implement column edit api, except sort

pull/35/head
Ondřej Hruška 6 years ago
parent e3a8616c68
commit 1fbd3384ce
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 24
      app/Http/Controllers/TableEditController.php
  2. 109
      app/Tables/Changeset.php
  3. 21
      app/Tables/Column.php
  4. 8
      resources/assets/js/components/ColumnEditor.vue
  5. 2
      resources/assets/js/components/RowsEditor.vue

@ -128,9 +128,7 @@ class TableEditController extends Controller
switch ($input->action) {
case 'row.update':
$data = (object)$input->data;
$changeset->rowUpdate($data);
$resp = $changeset->fetchAndTransformRow($data->_id);
$resp = $changeset->rowUpdate($data);
break;
case 'row.remove':
@ -170,6 +168,26 @@ class TableEditController extends Controller
}
break;
case 'col.update':
$data = (object)$input->data;
$resp = $changeset->columnUpdate($data);
break;
case 'col.remove':
$isNew = $changeset->isNewColumn($input->id);
$changeset->columnRemove($input->id);
$resp = $isNew ? null : $changeset->fetchAndTransformColumn($input->id);
break;
case 'col.restore':
$changeset->columnRestore($input->id);
$resp = $changeset->fetchAndTransformColumn($input->id);
break;
case 'col.add':
$resp = $changeset->addBlankCol();
break;
default:
$resp = "Bad Action";
$code = 400;

@ -276,6 +276,41 @@ class Changeset
return $cachedColumns = $newOrder;
}
/**
* @param string $id
* @return Column
*/
public function fetchColumn(string $id)
{
if ($this->isNewColumn($id)) {
$c = new Column($this->newColumns[$id]);
$c->markAsNew();
return $c;
} else {
$columns = collect($this->revision->columns)->keyBy('id');
return new Column($columns[$id]);
}
}
/**
* @param string $id
* @return Column
*/
public function fetchAndTransformColumn(string $id)
{
$column = $this->fetchColumn($id);
if (isset($this->columnUpdates[$column->id])) {
$column->modifyByChangeset($this->columnUpdates[$column->id]);
}
if (in_array($column->id, $this->removedColumns)) {
$column->markForRemoval();
}
return $column;
}
public function rowRemove(int $id)
{
if ($this->isNewRow($id)) {
@ -296,6 +331,11 @@ class Changeset
return isset($this->newRows[$id]);
}
public function isNewColumn(string $id)
{
return isset($this->newColumns[$id]);
}
public function fetchAndTransformRow(int $id)
{
$r = $this->fetchRow($id);
@ -337,6 +377,7 @@ class Changeset
* if all differences were undone.
*
* @param array|object $newVals - values of the new row
* @return object - updated column
*/
public function rowUpdate($newVals)
{
@ -373,6 +414,56 @@ class Changeset
unset($this->rowUpdates[$_id]);
}
}
return $this->fetchAndTransformRow($_id);
}
/**
* @param $newVals
* @return Column
*/
public function columnUpdate($newVals)
{
$id = $newVals->id;
$col = $this->fetchColumn($id);
$updateObj = [];
foreach ($newVals as $field => $value) {
if (starts_with($field, '_')) continue; // internals
if ($value !== $col->$field) {
$updateObj[$field] = $value;
}
}
if ($this->isNewColumn($id)) {
$this->newColumns[$id] = array_merge($this->newColumns[$id], $updateObj);
}
else {
if (!empty($updateObj)) {
$this->columnUpdates[$id] = $updateObj;
} else {
// remove possible old update record for this row, if nothing changes now
unset($this->columnUpdates[$id]);
}
}
return $this->fetchAndTransformColumn($id);
}
public function columnRemove(string $id)
{
if ($this->isNewColumn($id)) {
unset($this->newColumns[$id]);
}
else {
$this->removedColumns[] = $id;
}
}
public function columnRestore(string $id)
{
$this->removedColumns = array_diff($this->removedColumns, [$id]);
}
/**
@ -464,4 +555,22 @@ class Changeset
$this->newRows = array_merge($this->newRows, $rows->all());
}
public function addBlankCol()
{
$cid = (new ColumnNumerator(1))->next();
$allCols = $this->fetchAndTransformColumns();
$num = count($allCols) + 1;
$col = [
'name' => "col_{$num}",
'type' => "string",
'title' => "Column {$num}",
'id' => $cid,
];
$this->newColumns[$cid] = $col;
return $col;
}
}

@ -71,7 +71,7 @@ class Column implements JsonSerializable, Arrayable
foreach ((array)$columnObject as $key => $value) {
if ($value != $this->$key) {
$this->modified_attribs[] = $key;
$this->orig_attribs[] = $this->$key;
$this->orig_attribs[$key] = $this->$key;
$this->$key = $value;
}
}
@ -123,16 +123,21 @@ class Column implements JsonSerializable, Arrayable
/**
* Create from object or array
*
* @param $obj
* @param object|array $obj
*/
public function __construct($obj)
public function __construct($obj, $allowEmptyName=false)
{
$b = objBag($obj);
if (!$b->has('name') || $b->name == '') throw new NotApplicableException('Missing name in column');
if (!$b->has('type')) throw new NotApplicableException('Missing type in column');
if (!$allowEmptyName && (!$b->has('name') || $b->name == '')) {
throw new NotApplicableException('Missing name in column');
}
if (!$b->has('type')) {
throw new NotApplicableException('Missing type in column');
}
if ($b->name[0] == '_') { // global row ID
if ($b->name[0] == '_') { // would cause problems with selects (see: _id / GRID)
throw new NotApplicableException("Column name can't start with underscore.");
}
@ -156,6 +161,10 @@ class Column implements JsonSerializable, Arrayable
'name' => $this->name,
'title' => $this->title,
'type' => $this->type,
'_new' => $this->isNew,
'_remove' => $this->toRemove,
'_changed' => $this->modified_attribs,
'_orig' => $this->orig_attribs,
];
}

@ -16,7 +16,7 @@ Complex animated column editor for the table edit page
</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}">
<tr v-for="(col, i) in columns" :key="col.id" :ref="`col${i}`" :class="{dragging: col._dragging, 'text-success': col._new}">
<td v-if="sortable">
<span class="btn-group">
<button type="button" class="btn btn-outline-secondary drag-btn"
@ -187,7 +187,7 @@ export default {
name: { type: String, required: true },
xColumns: { type: Array, required: true },
},
data: function () {
data () {
return {
newColNum: 0,
columns: this.xColumns,
@ -335,7 +335,7 @@ export default {
// 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)
this.$delete(this.columns, n)
}
else {
this.$set(this.columns, n, resp.data)
@ -369,7 +369,7 @@ export default {
},
tdWidthStyle(cell) {
let w = 100;
let w = 10;
if (cell == 'name') w = '14'
if (cell == 'type') w = '12'
if (cell == 'title') w = '14'

@ -73,7 +73,7 @@ Rows are identified by row._id, columns by col.id
xRows: Object, // key'd by _id
columns: Array,
},
data: function () {
data () {
return {
rows: this.xRows,
}

Loading…
Cancel
Save