Row edit and delete card working

This commit is contained in:
2018-08-05 17:07:34 +02:00
parent bb8bc459dc
commit a4103e7084
15 changed files with 393 additions and 209 deletions
+6
View File
@@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
@@ -55,6 +56,11 @@ class Controller extends BaseController
'mastodon', // mastodon fetching previews
];
protected function jsonResponse($data = [], $code=200)
{
return new JsonResponse($data, $code);
}
// Hacks to allow recursive nesting of validations in string and array format
public function makeValidator($data, $rules, $messages = array(), $customAttributes = array())
+58 -1
View File
@@ -3,10 +3,12 @@
namespace App\Http\Controllers;
use App\Models\Row;
use App\Models\Table;
use App\Models\User;
use App\Tables\Changeset;
use App\Tables\Column;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
@@ -35,6 +37,14 @@ class TableEditController extends Controller
});
}
private function storeChangeset(Changeset $chs)
{
$session_key = "proposal_{$chs->table->id}";
session()->put($session_key, $chs);
session()->save();
}
public function draft(User $user, string $table, $tab = null)
{
/** @var Table $tableModel */
@@ -47,13 +57,18 @@ class TableEditController extends Controller
$changeset = $this->getChangeset($tableModel);
if (Input::has('dump')) {
dd($changeset);
}
return $this->{camel_case($tab)}($changeset);
}
/** @noinspection PhpUnusedPrivateMethodInspection */
private function editRows(Changeset $changeset)
{
$revision = $changeset->revision;
$columns = $changeset->transformColumns();
$columns = $changeset->fetchAndTransformColumns();
$rows = $revision->rowsData($columns, true, false)->paginate(25, []);
return view('table.propose.edit-rows', [
@@ -63,4 +78,46 @@ class TableEditController extends Controller
'rows' => $rows,
]);
}
// TODO other tab handlers
public function draftUpdate(User $user, string $table, Request $request)
{
/** @var Table $tableModel */
$tableModel = $user->tables()->where('name', $table)->first();
if ($tableModel === null) abort(404, "No such table.");
$changeset = $this->getChangeset($tableModel);
$input = objBag($request->all(), false);
$code = 200;
switch ($input->action) {
case 'row.update':
$data = (object)$input->data;
$changeset->rowUpdate($data);
$resp = $changeset->fetchAndTransformRow($data->_id);
break;
case 'row.remove':
$changeset->rowRemove($input->id);
$resp = $changeset->fetchAndTransformRow($input->id);
break;
case 'row.restore':
$changeset->rowRestore($input->id);
$resp = $changeset->fetchAndTransformRow($input->id);
break;
default:
$resp = "Bad Action";
$code = 400;
break;
}
$this->storeChangeset($changeset);
return $this->jsonResponse($resp, $code);
}
}
+85 -14
View File
@@ -4,8 +4,11 @@
namespace App\Tables;
use App\Models\Revision;
use App\Models\Row;
use App\Models\Table;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;
use MightyPork\Exceptions\NotExistException;
use ReflectionClass;
/**
@@ -34,7 +37,7 @@ class Changeset
/**
* @var string - user's note attached to this changeset (future proposal)
*/
public $note;
public $note = '';
/**
* Rows whose content changed, identified by _id.
@@ -100,9 +103,6 @@ class Changeset
*/
public $removedColumns = [];
/** @var Column[] - loaded and transformed columns, cached from previous call to transformColumns() */
private $cachedColumns;
private function walkProps()
{
$properties = (new ReflectionClass($this))->getProperties();
@@ -147,7 +147,7 @@ class Changeset
$object = new \stdClass();
foreach ($this->walkProps() as $prop) {
$object->$prop = array_values($this->$prop);
$object->$prop = $this->$prop;
}
return $object;
@@ -178,6 +178,8 @@ class Changeset
*/
public function transformRow($row, $decorate)
{
if ($row instanceof Row) $row = (object)$row->getAttributes();
if ($decorate) {
$row->_remove = false;
$row->_changed = [];
@@ -222,16 +224,16 @@ class Changeset
*
* @return Column[]
*/
public function transformColumns()
public function fetchAndTransformColumns()
{
if ($this->cachedColumns) return $this->cachedColumns;
/** @var Column[] - loaded and transformed columns, cached from previous call to transformColumns() */
static $cachedColumns = [];
if ($cachedColumns) return $cachedColumns;
$columns = Column::columnsFromJson($this->revision->columns);
// Modify columns
$byId = [];
foreach ($columns as $column) {
$byId[$column->id] = $column;
if (isset($this->columnUpdates[$column->id])) {
$column->modifyByChangeset($this->columnUpdates[$column->id]);
}
@@ -248,16 +250,85 @@ class Changeset
}
// Reorder
$colsById = collect($columns)->keyBy('id')->all();
$newOrder = [];
foreach ($this->columnOrder as $id) {
$newOrder[] = $byId[$id];
$newOrder[] = $colsById[$id];
}
$leftover_keys = array_diff(array_keys($byId), $this->columnOrder);
$leftover_keys = array_diff(array_keys($colsById), $this->columnOrder);
foreach ($leftover_keys as $id) {
$newOrder[] = $byId[$id];
$newOrder[] = $colsById[$id];
}
return $this->cachedColumns = $newOrder;
return $cachedColumns = $newOrder;
}
public function rowRemove(int $id)
{
$this->removedRows[] = $id;
}
public function rowRestore(int $id)
{
$this->removedRows = array_diff($this->removedRows, [$id]);
}
public function fetchAndTransformRow(int $id)
{
$r = $this->fetchRow($id);
$transformed = $this->transformRow($r, true);
return $transformed;
}
public function fetchColumns()
{
return Column::columnsFromJson($this->revision->columns);
}
public function fetchRow($id)
{
$r = $this->revision->rowsData($this->fetchColumns(), true, false)
->whereRaw("data->>'_id' = ?", $id)->first();
if (! $r) throw new NotExistException("No such row _id = $id in this revision.");
// remove junk
unset($r->pivot_revision_id);
unset($r->pivot_row_id);
return (object)$r->getAttributes();
}
public function rowUpdate($newVals)
{
$_id = $newVals->_id;
$origRow = $this->fetchRow($_id);
/** @var Column[]|Collection $cols */
$cols = collect($this->fetchAndTransformColumns())->keyBy('id');
$updateObj = [];
\Debugbar::addMessage(json_encode($cols));
\Debugbar::addMessage(var_export($newVals, true));
foreach ($newVals as $colId => $value) {
if (starts_with($colId, '_')) continue; // internals
if (!isset($origRow->$colId) || $value != $origRow->$colId) {
$updateObj[$colId] = $cols[$colId]->cast($value);
}
}
\Debugbar::addMessage("New: ".json_encode($newVals));
\Debugbar::addMessage("Orig: ".json_encode($origRow));
\Debugbar::addMessage("UpdateObj: ".json_encode($updateObj));
if (!empty($updateObj)) {
$this->rowUpdates[$_id] = $updateObj;
} else {
// remove possible old update record for this row, if nothing changes now
unset($this->rowUpdates[$_id]);
}
}
}
+12 -17
View File
@@ -10,13 +10,6 @@ use MightyPork\Utils\Utils;
/**
* Helper class representing one column in a data table.
*
* @property-read string $id
* @property-read string $type
* @property-read string $name
* @property-read string $title
* @property-read bool $isNew
* @property-read bool $toRemove
*
* @property-read bool $id_modified
* @property-read bool $type_modified
* @property-read bool $name_modified
@@ -33,16 +26,18 @@ class Column implements JsonSerializable, Arrayable
'int', 'bool', 'float', 'string'
];
private $id;
private $type;
private $name;
private $title;
// marked public to make keyBy() work
public $id;
public $type;
public $name;
public $title;
/** @var bool - column is marked to be deleted by a changeset */
private $toRemove = false;
public $toRemove = false;
/** @var bool - column is new in this changeset */
private $isNew = false;
public $isNew = false;
/** @var array - original attrib values if edited in a changeset */
private $orig_attribs = [];
@@ -83,10 +78,6 @@ class Column implements JsonSerializable, Arrayable
public function __get($name)
{
if (property_exists($this, $name)) {
return $this->$name;
}
if (ends_with($name, '_modified')) {
$basename = str_replace('_modified', '', $name);
if (property_exists($this, $basename)) {
@@ -177,20 +168,24 @@ class Column implements JsonSerializable, Arrayable
{
switch ($this->type) {
case 'int':
if (is_null($value)) return 0;
if (is_int($value)) return $value;
if (is_float($value)) return round($value);
if (is_numeric($value)) return intval($value);
throw new NotApplicableException("Could not convert value \"$value\" to int!");
case 'float':
if (is_null($value)) return 0;
if (is_int($value) || is_float($value)) return (float)$value;
if (is_numeric($value)) return floatval($value);
throw new NotApplicableException("Could not convert value \"$value\" to float!");
case 'bool':
if (is_null($value)) return false;
return Utils::parseBool($value);
case 'string':
if (is_null($value)) return "";
return "$value";
default: