row undos
This commit is contained in:
@@ -79,7 +79,19 @@ class TableEditController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO other tab handlers
|
/** @noinspection PhpUnusedPrivateMethodInspection */
|
||||||
|
private function addRows(Changeset $changeset)
|
||||||
|
{
|
||||||
|
$columns = $changeset->fetchAndTransformColumns();
|
||||||
|
$rows = $changeset->getAddedRows(25);
|
||||||
|
|
||||||
|
return view('table.propose.add-rows', [
|
||||||
|
'changeset' => $changeset,
|
||||||
|
'table' => $changeset->table,
|
||||||
|
'columns' => collect($columns),
|
||||||
|
'rows' => $rows,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function draftUpdate(User $user, string $table, Request $request)
|
public function draftUpdate(User $user, string $table, Request $request)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace App\Tables;
|
|||||||
use App\Models\Revision;
|
use App\Models\Revision;
|
||||||
use App\Models\Row;
|
use App\Models\Row;
|
||||||
use App\Models\Table;
|
use App\Models\Table;
|
||||||
|
use Illuminate\Pagination\Paginator;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use MightyPork\Exceptions\NotExistException;
|
use MightyPork\Exceptions\NotExistException;
|
||||||
@@ -186,7 +187,7 @@ class Changeset
|
|||||||
$row->_orig = [];
|
$row->_orig = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removed rows
|
// Removed rows - return as null
|
||||||
if (in_array($row->_id, $this->removedRows)) {
|
if (in_array($row->_id, $this->removedRows)) {
|
||||||
if ($decorate) {
|
if ($decorate) {
|
||||||
$row->_remove = true;
|
$row->_remove = true;
|
||||||
@@ -195,6 +196,8 @@ class Changeset
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if marked for removal, hide changes
|
||||||
|
if (!$row->_remove) {
|
||||||
// Changed values
|
// Changed values
|
||||||
if (isset($this->rowUpdates[$row->_id])) {
|
if (isset($this->rowUpdates[$row->_id])) {
|
||||||
$newVals = $this->rowUpdates[$row->_id];
|
$newVals = $this->rowUpdates[$row->_id];
|
||||||
@@ -206,6 +209,7 @@ class Changeset
|
|||||||
|
|
||||||
$row = (object)array_merge((array)$row, $newVals);
|
$row = (object)array_merge((array)$row, $newVals);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Drop deleted columns
|
// Drop deleted columns
|
||||||
if (!$decorate) {
|
if (!$decorate) {
|
||||||
@@ -300,8 +304,16 @@ class Changeset
|
|||||||
return (object)$r->getAttributes();
|
return (object)$r->getAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply a row update, adding the row to the list of changes, or removing it
|
||||||
|
* if all differences were undone.
|
||||||
|
*
|
||||||
|
* @param array|object $newVals
|
||||||
|
*/
|
||||||
public function rowUpdate($newVals)
|
public function rowUpdate($newVals)
|
||||||
{
|
{
|
||||||
|
$newVals = (object)$newVals;
|
||||||
|
|
||||||
$_id = $newVals->_id;
|
$_id = $newVals->_id;
|
||||||
$origRow = $this->fetchRow($_id);
|
$origRow = $this->fetchRow($_id);
|
||||||
|
|
||||||
@@ -309,8 +321,6 @@ class Changeset
|
|||||||
$cols = collect($this->fetchAndTransformColumns())->keyBy('id');
|
$cols = collect($this->fetchAndTransformColumns())->keyBy('id');
|
||||||
|
|
||||||
$updateObj = [];
|
$updateObj = [];
|
||||||
\Debugbar::addMessage(json_encode($cols));
|
|
||||||
\Debugbar::addMessage(var_export($newVals, true));
|
|
||||||
|
|
||||||
foreach ($newVals as $colId => $value) {
|
foreach ($newVals as $colId => $value) {
|
||||||
if (starts_with($colId, '_')) continue; // internals
|
if (starts_with($colId, '_')) continue; // internals
|
||||||
@@ -320,10 +330,6 @@ class Changeset
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
\Debugbar::addMessage("New: ".json_encode($newVals));
|
|
||||||
\Debugbar::addMessage("Orig: ".json_encode($origRow));
|
|
||||||
\Debugbar::addMessage("UpdateObj: ".json_encode($updateObj));
|
|
||||||
|
|
||||||
if (!empty($updateObj)) {
|
if (!empty($updateObj)) {
|
||||||
$this->rowUpdates[$_id] = $updateObj;
|
$this->rowUpdates[$_id] = $updateObj;
|
||||||
} else {
|
} else {
|
||||||
@@ -331,4 +337,15 @@ class Changeset
|
|||||||
unset($this->rowUpdates[$_id]);
|
unset($this->rowUpdates[$_id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a page of added rows for display in the editor
|
||||||
|
*
|
||||||
|
* @param int $perPage
|
||||||
|
* @return \Illuminate\Pagination\LengthAwarePaginator|Collection|array
|
||||||
|
*/
|
||||||
|
public function getAddedRows(int $perPage = 25)
|
||||||
|
{
|
||||||
|
return collection_paginate($this->newRows, $perPage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,3 +95,28 @@ function toJSON($object) {
|
|||||||
function fromJSON($object, $assoc=false) {
|
function fromJSON($object, $assoc=false) {
|
||||||
return \GuzzleHttp\json_decode($object, $assoc);
|
return \GuzzleHttp\json_decode($object, $assoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Illuminate\Support\Collection|array $items
|
||||||
|
* @param int $per_page
|
||||||
|
* @param null|\Closure $mapFn
|
||||||
|
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||||
|
*/
|
||||||
|
function collection_paginate($items, $per_page, $mapFn = null)
|
||||||
|
{
|
||||||
|
if (!$items instanceof \Illuminate\Support\Collection) {
|
||||||
|
$items = collect($items);
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = Request::get('page', 1);
|
||||||
|
|
||||||
|
$pageItems = $items->forPage($page, $per_page)->values();
|
||||||
|
|
||||||
|
return new Illuminate\Pagination\LengthAwarePaginator(
|
||||||
|
$mapFn ? $pageItems->map($mapFn) : $pageItems,
|
||||||
|
$items->count(),
|
||||||
|
$per_page,
|
||||||
|
Illuminate\Pagination\Paginator::resolveCurrentPage(),
|
||||||
|
['path' => Illuminate\Pagination\Paginator::resolveCurrentPath()]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// window._ = require('lodash');
|
//window._ = require('lodash');
|
||||||
window.Popper = require('popper.js').default
|
window.Popper = require('popper.js').default
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<i :title="tooltipText">
|
<i :title="tooltipText" @click="$emit('click')">
|
||||||
<span class="sr-only" v-html=srHtml></span>
|
<span class="sr-only" v-html=srHtml></span>
|
||||||
</i>
|
</i>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
inheritAttrs: false,
|
|
||||||
props: {
|
props: {
|
||||||
alt: String,
|
alt: String,
|
||||||
srOnly: Boolean
|
srOnly: Boolean
|
||||||
|
|||||||
@@ -32,7 +32,12 @@
|
|||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<td v-for="col in columns">
|
<td v-for="col in columns">
|
||||||
{{ row[col.id] || '' }}
|
<span class="text-danger strike" title="Original value" v-if="isChanged(row, col.id)">{{row._orig[col.id]}}</span>
|
||||||
|
<span>{{ row[col.id] || '' }}</span>
|
||||||
|
<v-icon v-if="isChanged(row, col.id)"
|
||||||
|
@click="revertCell(row, col.id)"
|
||||||
|
class="fa-undo text-danger pointer"
|
||||||
|
alt="Revert Change" />
|
||||||
</td>
|
</td>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -47,6 +52,8 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { merge } from 'lodash';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
route: String,
|
route: String,
|
||||||
@@ -72,27 +79,30 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
toggleRowDelete(_id) {
|
toggleRowDelete(_id) {
|
||||||
let remove = !this.rows[_id]._remove;
|
let remove = !this.rows[_id]._remove
|
||||||
|
|
||||||
this.query({
|
this.query({
|
||||||
action: remove ? 'row.remove' : 'row.restore',
|
action: remove ? 'row.remove' : 'row.restore',
|
||||||
id: _id
|
id: _id
|
||||||
}, (resp) => {
|
}, (resp) => {
|
||||||
this.$set(this.rows, _id, resp.data);
|
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);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
toggleRowEditing(_id) {
|
toggleRowEditing(_id) {
|
||||||
if (this.rows[_id]._remove) return false; // can't edit row marked for removal
|
if (this.rows[_id]._remove) return false; // can't edit row marked for removal
|
||||||
|
|
||||||
let editing = !this.rows[_id]._editing;
|
let editing = !this.rows[_id]._editing
|
||||||
|
|
||||||
if (!editing) {
|
if (!editing) {
|
||||||
this.query({
|
this.submitRowChange(this.rows[_id])
|
||||||
action: 'row.update',
|
|
||||||
data: this.rows[_id]
|
|
||||||
}, (resp) => {
|
|
||||||
this.$set(this.rows, _id, resp.data);
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
this.$set(this.rows[_id], '_editing', true);
|
this.$set(this.rows[_id], '_editing', true);
|
||||||
}
|
}
|
||||||
@@ -113,6 +123,12 @@ export default {
|
|||||||
backgroundColor: row._remove? '#FFC4CC': 'transparent'
|
backgroundColor: row._remove? '#FFC4CC': 'transparent'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
isChanged (row, colId) {
|
||||||
|
return row._changed.indexOf(colId) > -1
|
||||||
|
},
|
||||||
|
revertCell(row, colId) {
|
||||||
|
this.submitRowChange(merge({}, row, { [colId]: row._orig[colId] }))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Vendored
+4
@@ -25,3 +25,7 @@
|
|||||||
.opacity-fade {
|
.opacity-fade {
|
||||||
transition: opacity .3s ease-in-out;
|
transition: opacity .3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user