Preparing column editor for backend requests, remove simple col editor and reuse one for both cases
This commit is contained in:
@@ -1,42 +1,86 @@
|
||||
<!--
|
||||
Complex animated column editor for the table edit page
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<input type="hidden" :name="name" :value="JSON.stringify(columns)">
|
||||
<input type="hidden" :name="name" :value="JSON.stringify(columns)" v-if="newTable">
|
||||
<table class="editor-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-if="doSort"></th>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Title</th>
|
||||
<th v-if="!newTable"></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(col, i) in columns">
|
||||
<td>
|
||||
<input v-model="col.name" class="form-control" type="text" style="width: 140px">
|
||||
<transition-group name="col-list" tag="tbody" ref="col-list">
|
||||
<tr v-for="(col, i) in columns" :key="col.id" :ref="'col' + i" :class="{dragging: col._dragging}">
|
||||
<td class="btn-group" v-if="doSort">
|
||||
<button class="btn btn-outline-secondary drag-btn" @mousedown="beginDrag(i, $event)">
|
||||
<v-icon class="fa-bars" alt="Drag" />
|
||||
</button>
|
||||
<a href="" :class="['btn', 'btn-outline-secondary', {disabled: i==0}]"
|
||||
@click.prevent="move(i, -1)">
|
||||
<v-icon class="fa-chevron-up" alt="Move Up" />
|
||||
</a><a href="" :class="['btn', 'btn-outline-secondary', {disabled: i == (columns.length-1)}]"
|
||||
@click.prevent="move(i, 1)">
|
||||
<v-icon class="fa-chevron-down" alt="Move Down" />
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<select v-model="col.type" class="form-control custom-select" style="width: 110px">
|
||||
<input v-model="col.name"
|
||||
@input="markColNeedSave(i)"
|
||||
class="form-control"
|
||||
type="text"
|
||||
style="width: 140px">
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<select v-model="col.type"
|
||||
@input="markColNeedSave(i)"
|
||||
class="form-control custom-select"
|
||||
style="width: 110px">
|
||||
<option v-for="t in colTypes" :value="t">{{t}}</option>
|
||||
</select>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<input v-model="col.title" class="form-control" type="text" style="width: 170px">
|
||||
<input v-model="col.title"
|
||||
@input="markColNeedSave(i)"
|
||||
class="form-control"
|
||||
type="text"
|
||||
style="width: 170px">
|
||||
</td>
|
||||
|
||||
<td class="text-nowrap">
|
||||
<a href="" :class="['btn', 'btn-outline-secondary', {disabled: i==0}]" @click.prevent="delCol(i)">
|
||||
<v-icon class="fa-trash-o" alt="Delete column" />
|
||||
</a><!--
|
||||
--><a href="" class="btn btn-outline-secondary" v-if="i === columns.length - 1"
|
||||
@click.prevent="addCol()">
|
||||
<td v-if="!newTable">
|
||||
<a href="" :class="['btn', col._dirty ? 'btn-info' : 'btn-outline-secondary']"
|
||||
@click.prevent="saveCol(i)">
|
||||
<v-icon class="fa-save" alt="Save" />
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="" :class="delBtnClass(col)"
|
||||
@click.prevent="toggleColDelete(i)">
|
||||
<v-icon :class="col._remove ? 'fa-undo' : 'fa-trash-o'"
|
||||
:alt="col._remove ? 'Undo Remove' : 'Remove'" />
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="" :class="['btn', 'btn-outline-secondary']"
|
||||
v-if="i === columns.length - 1"
|
||||
@click.prevent="addCol()">
|
||||
<v-icon class="fa-plus" alt="Add Column" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</transition-group>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
@@ -53,36 +97,199 @@
|
||||
@include py(1);
|
||||
}
|
||||
|
||||
td .btn {
|
||||
@include mr(1);
|
||||
tr.dragging {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
background-color: $body-bg;
|
||||
}
|
||||
tr.dragging .drag-btn {
|
||||
// fake hover
|
||||
background-color: $secondary;
|
||||
color: color-yiq($secondary);
|
||||
}
|
||||
|
||||
.col-list-enter-active {
|
||||
transition: all .3s cubic-bezier(.2, .3, 0, 1);
|
||||
}
|
||||
|
||||
.col-list-enter {
|
||||
opacity: 0;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
.col-list-leave {
|
||||
// approximate position of delete button
|
||||
clip-path: circle(calc(100% + 5em) at calc(100% - 4em) 50%);
|
||||
}
|
||||
.col-list-leave-active .delete-btn {
|
||||
animation: col-list-leave-delete-btn .3s forwards;
|
||||
}
|
||||
.col-list-leave-active {
|
||||
transition: all .3s cubic-bezier(.4, .1, .6, .9);
|
||||
}
|
||||
.col-list-leave-to {
|
||||
clip-path: circle(0 at calc(100% - 4em) 50%);
|
||||
}
|
||||
|
||||
@keyframes col-list-leave-delete-btn {
|
||||
0% {
|
||||
transition-timing-function: cubic-bezier(.2, .4, .6, .9);
|
||||
}
|
||||
50% {
|
||||
transition-timing-function: cubic-bezier(.5, 0, .8, .5);
|
||||
transform: scale(1.1);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(0);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.col-list-move {
|
||||
transition: transform .3s cubic-bezier(.2, .3, 0, 1);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import { query } from './table-editor-utils'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
name: String,
|
||||
initialColumns: Array,
|
||||
route: { type: String, default: null },
|
||||
doSort: { type: Boolean, default: true },
|
||||
newTable: { type: Boolean, default: false },
|
||||
name: { type: String, required: true },
|
||||
xColumns: { type: Array, required: true },
|
||||
},
|
||||
data: function() {
|
||||
data: function () {
|
||||
return {
|
||||
columns: this.initialColumns,
|
||||
columns: this.xColumns,
|
||||
colTypes: ['string', 'int', 'float', 'bool'],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
delCol(n) {
|
||||
if (n == 0) return
|
||||
|
||||
this.columns.splice(n, 1)
|
||||
query (data, sucfn, erfn) {
|
||||
query(this.route, data, sucfn, erfn)
|
||||
},
|
||||
addCol() {
|
||||
this.columns.push({
|
||||
name: '',
|
||||
type: 'string',
|
||||
title: '',
|
||||
|
||||
addCol () {
|
||||
if (this.newTable) {
|
||||
this.columns.push({
|
||||
id: Math.random().toString(),
|
||||
name: '',
|
||||
type: 'string',
|
||||
title: '',
|
||||
})
|
||||
} else {
|
||||
this.query({
|
||||
action: 'col.add',
|
||||
}, (resp) => {
|
||||
this.columns.push(resp.data)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
move (i, dir) {
|
||||
let cur = this.columns[i]
|
||||
let next = this.columns[i + dir]
|
||||
this.$set(this.columns, i, next)
|
||||
this.$set(this.columns, i + dir, cur)
|
||||
},
|
||||
|
||||
markColNeedSave(i) {
|
||||
this.$set(this.columns[i], '_dirty', true)
|
||||
},
|
||||
|
||||
beginDrag (i, evt) {
|
||||
const column = this.columns[i]
|
||||
column._dragging = true
|
||||
this.$set(this.columns, i, column) // notify vue
|
||||
|
||||
let currentIndex = i
|
||||
|
||||
const dragMoveListener = e => {
|
||||
let cursorIndex = 0
|
||||
|
||||
// find cursor index by going through the list and adding the li
|
||||
// heights (can’t use their positions because they may be animating at
|
||||
// that moment)
|
||||
let accumY = this.$refs['col-list'].$el.getBoundingClientRect().top
|
||||
for (let i = 0; i < this.columns.length; i++) {
|
||||
if (e.clientY > accumY) {
|
||||
cursorIndex = i
|
||||
}
|
||||
accumY += $(this.$refs['col' + i]).outerHeight(true)
|
||||
}
|
||||
|
||||
if (cursorIndex !== currentIndex) {
|
||||
this.move(currentIndex, cursorIndex - currentIndex)
|
||||
currentIndex = cursorIndex
|
||||
}
|
||||
}
|
||||
|
||||
const dragEndListener = e => {
|
||||
column._dragging = false
|
||||
this.$set(this.columns, currentIndex, column) // notify vue
|
||||
|
||||
$(window).off('mousemove', dragMoveListener)
|
||||
$(window).off('mouseup', dragEndListener)
|
||||
}
|
||||
|
||||
$(window).on('mousemove', dragMoveListener)
|
||||
$(window).on('mouseup', dragEndListener)
|
||||
},
|
||||
|
||||
delBtnClass(col) {
|
||||
return [
|
||||
'btn',
|
||||
'btn-outline-danger',
|
||||
'delete-btn',
|
||||
{'active': col._remove},
|
||||
{disabled: this.newTable && this.columns.length === 1}
|
||||
]
|
||||
},
|
||||
|
||||
saveCol(n) {
|
||||
let col = this.columns[n]
|
||||
if (_.isUndefined(col)) return
|
||||
|
||||
this.query({
|
||||
action: 'col.update',
|
||||
data: col
|
||||
}, (resp) => {
|
||||
this.$set(this.columns, n, resp.data)
|
||||
}, (er) => {
|
||||
if (!_.isUndefined(er.errors)) {
|
||||
this.$set(this.columns[n], '_errors', er.errors)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
toggleColDelete(n) {
|
||||
let col = this.columns[n]
|
||||
if (_.isUndefined(col)) return
|
||||
|
||||
if (this.newTable) {
|
||||
// hard delete
|
||||
this.columns.splice(n, 1)
|
||||
} else {
|
||||
let remove = !col._remove
|
||||
|
||||
this.query({
|
||||
action: remove ? 'col.remove' : 'col.restore',
|
||||
id: col.id
|
||||
}, (resp) => {
|
||||
// if response is null, this was a New col
|
||||
// and it was discarded without a way back - hard drop
|
||||
if (_.isEmpty(resp.data)) {
|
||||
this.$delete(this.col, n)
|
||||
}
|
||||
else {
|
||||
this.$set(this.columns, n, resp.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<input type="hidden" :name="name" :value="JSON.stringify(columns)">
|
||||
<table class="editor-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Title</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<transition-group name="col-list" tag="tbody" ref="col-list">
|
||||
<tr v-for="(col, i) in columns" :key="col.id" :ref="'col' + i" :class="{dragging: col._dragging}">
|
||||
<td class="btn-group">
|
||||
<button class="btn btn-outline-secondary drag-btn" @mousedown="beginDrag(i, $event)">
|
||||
<v-icon class="fa-bars" alt="Drag" />
|
||||
</button>
|
||||
<a href="" :class="['btn', 'btn-outline-secondary', {disabled: i==0}]" @click.prevent="move(i, -1)">
|
||||
<v-icon class="fa-chevron-up" alt="Move Up" />
|
||||
</a><a href="" :class="['btn', 'btn-outline-secondary', {disabled: i == (columns.length-1)}]" @click.prevent="move(i, 1)">
|
||||
<v-icon class="fa-chevron-down" alt="Move Down" />
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<input v-model="col.name" class="form-control" type="text" style="width: 140px">
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<select v-model="col.type" class="form-control custom-select" style="width: 110px">
|
||||
<option v-for="t in colTypes" :value="t">{{t}}</option>
|
||||
</select>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<input v-model="col.title" class="form-control" type="text" style="width: 170px">
|
||||
</td>
|
||||
|
||||
<td class="text-nowrap">
|
||||
<a href="" :class="['mr-1', 'btn', 'btn-outline-secondary', 'delete-btn', {disabled: i==0}]" @click.prevent="delCol(i)">
|
||||
<v-icon class="fa-trash-o" alt="Delete column" />
|
||||
</a><!--
|
||||
--><a href="" class="btn btn-outline-secondary" v-if="i === columns.length - 1"
|
||||
@click.prevent="addCol()">
|
||||
<v-icon class="fa-plus" alt="Add Column" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</transition-group>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "base";
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
td, th {
|
||||
@include pr(1);
|
||||
@include py(1);
|
||||
}
|
||||
|
||||
tr.dragging {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
background-color: $body-bg;
|
||||
}
|
||||
tr.dragging .drag-btn {
|
||||
// fake hover
|
||||
background-color: $secondary;
|
||||
color: color-yiq($secondary);
|
||||
}
|
||||
|
||||
.col-list-enter-active {
|
||||
transition: all .3s cubic-bezier(.2, .3, 0, 1);
|
||||
}
|
||||
|
||||
.col-list-enter {
|
||||
opacity: 0;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
.col-list-leave {
|
||||
// approximate position of delete button
|
||||
clip-path: circle(calc(100% + 5em) at calc(100% - 4em) 50%);
|
||||
}
|
||||
.col-list-leave-active .delete-btn {
|
||||
animation: col-list-leave-delete-btn .3s forwards;
|
||||
}
|
||||
.col-list-leave-active {
|
||||
transition: all .3s cubic-bezier(.4, .1, .6, .9);
|
||||
}
|
||||
.col-list-leave-to {
|
||||
clip-path: circle(0 at calc(100% - 4em) 50%);
|
||||
}
|
||||
|
||||
@keyframes col-list-leave-delete-btn {
|
||||
0% {
|
||||
transition-timing-function: cubic-bezier(.2, .4, .6, .9);
|
||||
}
|
||||
50% {
|
||||
transition-timing-function: cubic-bezier(.5, 0, .8, .5);
|
||||
transform: scale(1.1);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(0);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.col-list-move {
|
||||
transition: transform .3s cubic-bezier(.2, .3, 0, 1);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
name: String,
|
||||
initialColumns: Array,
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
columns: this.initialColumns,
|
||||
colTypes: ['string', 'int', 'float', 'bool'],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
delCol(n) {
|
||||
if (n == 0) return
|
||||
|
||||
this.columns.splice(n, 1)
|
||||
},
|
||||
addCol() {
|
||||
this.columns.push({
|
||||
id: Math.random().toString(),
|
||||
name: '',
|
||||
type: 'string',
|
||||
title: '',
|
||||
})
|
||||
},
|
||||
move(i, dir) {
|
||||
let cur = this.columns[i];
|
||||
let next = this.columns[i+dir];
|
||||
this.$set(this.columns, i, next);
|
||||
this.$set(this.columns, i+dir, cur);
|
||||
},
|
||||
beginDrag(i, evt) {
|
||||
const column = this.columns[i];
|
||||
column._dragging = true;
|
||||
this.$set(this.columns, i, column); // notify vue
|
||||
|
||||
let currentIndex = i;
|
||||
|
||||
const dragMoveListener = e => {
|
||||
let cursorIndex = 0;
|
||||
|
||||
// find cursor index by going through the list and adding the li
|
||||
// heights (can’t use their positions because they may be animating at
|
||||
// that moment)
|
||||
let accumY = this.$refs['col-list'].$el.getBoundingClientRect().top;
|
||||
for (let i = 0; i < this.columns.length; i++) {
|
||||
if (e.clientY > accumY) {
|
||||
cursorIndex = i;
|
||||
}
|
||||
accumY += $(this.$refs['col' + i]).outerHeight(true);
|
||||
}
|
||||
|
||||
if (cursorIndex !== currentIndex) {
|
||||
this.move(currentIndex, cursorIndex - currentIndex);
|
||||
currentIndex = cursorIndex;
|
||||
}
|
||||
}
|
||||
|
||||
const dragEndListener = e => {
|
||||
column._dragging = false;
|
||||
this.$set(this.columns, currentIndex, column); // notify vue
|
||||
|
||||
$(window).off('mousemove', dragMoveListener);
|
||||
$(window).off('mouseup', dragEndListener);
|
||||
};
|
||||
|
||||
$(window).on('mousemove', dragMoveListener);
|
||||
$(window).on('mouseup', dragEndListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,3 +1,14 @@
|
||||
<!--
|
||||
Row editor for the edit-rows or add-rows card of table editor
|
||||
|
||||
Rows and columns marked for removal have x._remove=true
|
||||
New columns have col._new=true
|
||||
Changed rows have r._changed = [ids of changed fields]
|
||||
and r._orig = [previous values]
|
||||
|
||||
Rows are identified by row._id, columns by col.id
|
||||
-->
|
||||
|
||||
<template>
|
||||
<table class="table table-hover table-sm table-fixed td-va-middle">
|
||||
<thead>
|
||||
@@ -54,107 +65,95 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
route: String,
|
||||
xRows: Object, // key'd by _id
|
||||
columns: Array,
|
||||
lastPage: Boolean,
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
rows: this.xRows,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
busy (yes) {
|
||||
$('#draft-busy').css('opacity', yes ? 1 : 0)
|
||||
import { query } from './table-editor-utils'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
route: String,
|
||||
xRows: Object, // key'd by _id
|
||||
columns: Array,
|
||||
},
|
||||
|
||||
query (data, sucfn, erfn) {
|
||||
this.busy(true)
|
||||
if (!sucfn) sucfn = ()=>{}
|
||||
if (!sucfn) erfn = ()=>{}
|
||||
window.axios.post(this.route, data).then(sucfn).catch((error) => {
|
||||
console.error(error.message)
|
||||
erfn(error.response.data)
|
||||
}).then(() => {
|
||||
this.busy(false)
|
||||
})
|
||||
},
|
||||
|
||||
toggleRowDelete(_id) {
|
||||
if (!_.isDefined(this.rows[_id])) return;
|
||||
|
||||
let remove = !this.rows[_id]._remove
|
||||
|
||||
this.query({
|
||||
action: remove ? 'row.remove' : 'row.restore',
|
||||
id: _id
|
||||
}, (resp) => {
|
||||
// if response is null, this was a New row
|
||||
// and it was discarded without a way back - hard drop
|
||||
if (_.isEmpty(resp.data)) {
|
||||
this.$delete(this.rows, _id)
|
||||
}
|
||||
else {
|
||||
this.$set(this.rows, _id, resp.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
submitRowChange(row) {
|
||||
this.query({
|
||||
action: 'row.update',
|
||||
data: row
|
||||
}, (resp) => {
|
||||
this.$set(this.rows, resp.data._id, resp.data);
|
||||
}, (er) => {
|
||||
if (!_.isUndefined(er.errors)) {
|
||||
this.$set(this.rows[row._id], '_errors', er.errors);
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toggleRowEditing(_id) {
|
||||
if (this.rows[_id]._remove) return false; // can't edit row marked for removal
|
||||
|
||||
let editing = !this.rows[_id]._editing
|
||||
|
||||
if (!editing) {
|
||||
this.submitRowChange(this.rows[_id])
|
||||
} else {
|
||||
this.$set(this.rows[_id], '_editing', true);
|
||||
}
|
||||
},
|
||||
|
||||
colClasses(col) {
|
||||
return [
|
||||
'border-top-0',
|
||||
{
|
||||
'text-danger': col._remove,
|
||||
'strike': col._remove,
|
||||
'text-success': col._new
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
rowStyle(row) {
|
||||
data: function () {
|
||||
return {
|
||||
opacity: row._remove ? .8 : 1,
|
||||
backgroundColor:
|
||||
row._remove ? '#FFC4CC':
|
||||
'transparent'
|
||||
rows: this.xRows,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
query (data, sucfn, erfn) {
|
||||
query(this.route, data, sucfn, erfn)
|
||||
},
|
||||
|
||||
isChanged (row, colId) {
|
||||
return row._changed && row._changed.indexOf(colId) > -1
|
||||
},
|
||||
toggleRowDelete (_id) {
|
||||
if (!_.isDefined(this.rows[_id])) return
|
||||
|
||||
revertCell(row, colId) {
|
||||
this.submitRowChange(_.merge({}, row, { [colId]: row._orig[colId] }))
|
||||
let remove = !this.rows[_id]._remove
|
||||
|
||||
this.query({
|
||||
action: remove ? 'row.remove' : 'row.restore',
|
||||
id: _id
|
||||
}, (resp) => {
|
||||
// if response is null, this was a New row
|
||||
// and it was discarded without a way back - hard drop
|
||||
if (_.isEmpty(resp.data)) {
|
||||
this.$delete(this.rows, _id)
|
||||
}
|
||||
else {
|
||||
this.$set(this.rows, _id, resp.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
submitRowChange (row) {
|
||||
this.query({
|
||||
action: 'row.update',
|
||||
data: row
|
||||
}, (resp) => {
|
||||
this.$set(this.rows, row._id, resp.data)
|
||||
}, (er) => {
|
||||
if (!_.isUndefined(er.errors)) {
|
||||
this.$set(this.rows[row._id], '_errors', er.errors)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toggleRowEditing (_id) {
|
||||
if (this.rows[_id]._remove) return false // can't edit row marked for removal
|
||||
let editing = !this.rows[_id]._editing
|
||||
|
||||
if (!editing) {
|
||||
this.submitRowChange(this.rows[_id])
|
||||
} else {
|
||||
this.$set(this.rows[_id], '_editing', true)
|
||||
}
|
||||
},
|
||||
|
||||
colClasses (col) {
|
||||
return [
|
||||
'border-top-0',
|
||||
{
|
||||
'text-danger': col._remove,
|
||||
'strike': col._remove,
|
||||
'text-success': col._new
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
rowStyle (row) {
|
||||
return {
|
||||
opacity: row._remove ? .8 : 1,
|
||||
backgroundColor:
|
||||
row._remove ? '#FFC4CC' :
|
||||
'transparent'
|
||||
}
|
||||
},
|
||||
|
||||
isChanged (row, colId) {
|
||||
return row._changed && row._changed.indexOf(colId) > -1
|
||||
},
|
||||
|
||||
revertCell (row, colId) {
|
||||
this.submitRowChange(_.merge({}, row, {[colId]: row._orig[colId]}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
function busy (yes) {
|
||||
$('#draft-busy').css('opacity', yes ? 1 : 0)
|
||||
}
|
||||
|
||||
function query (route, data, sucfn, erfn) {
|
||||
busy(true)
|
||||
if (!sucfn) sucfn = () => {}
|
||||
if (!sucfn) erfn = () => {}
|
||||
window.axios.post(route, data).then(sucfn).catch((error) => {
|
||||
console.error(error.message)
|
||||
erfn(error.response.data)
|
||||
}).then(() => {
|
||||
busy(false)
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
busy,
|
||||
query
|
||||
}
|
||||
Vendored
-4
@@ -1,7 +1,6 @@
|
||||
window.Vue = require('vue')
|
||||
|
||||
const ColumnEditor = Vue.component('column-editor', require('./components/ColumnEditor.vue'))
|
||||
const ColumnEditorAdvanced = Vue.component('column-editor', require('./components/ColumnEditorAdvanced.vue'))
|
||||
const RowsEditor = Vue.component('rows-editor', require('./components/RowsEditor.vue'))
|
||||
const Icon = Vue.component('v-icon', require('./components/Icon.vue'))
|
||||
|
||||
@@ -13,9 +12,6 @@ window.app = {
|
||||
ColumnEditor: function (selector, data) {
|
||||
new ColumnEditor({ propsData: data }).$mount(selector)
|
||||
},
|
||||
ColumnEditorAdvanced: function (selector, data) {
|
||||
new ColumnEditorAdvanced({ propsData: data }).$mount(selector)
|
||||
},
|
||||
RowsEditor: function (selector, data) {
|
||||
new RowsEditor({ propsData: data }).$mount(selector)
|
||||
},
|
||||
|
||||
@@ -79,7 +79,9 @@
|
||||
ready(function() {
|
||||
app.ColumnEditor('#column-editor', {
|
||||
name: 'columns',
|
||||
initialColumns: {!! old('columns', toJSON($columns)) !!},
|
||||
xColumns: {!! old('columns', toJSON($columns)) !!},
|
||||
newTable: true,
|
||||
doSort: false,
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -14,11 +14,10 @@
|
||||
@push('scripts')
|
||||
<script>
|
||||
ready(function() {
|
||||
// TODO we need a better editor with ajax for adding, also with ordering
|
||||
app.ColumnEditorAdvanced('#column-editor', {
|
||||
app.ColumnEditor('#column-editor', {
|
||||
name: 'columns',
|
||||
route: {!! toJSON($table->draftUpdateRoute) !!},
|
||||
initialColumns: {!! toJSON($columns) !!},
|
||||
xColumns: {!! toJSON($columns) !!},
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user