CSV import, also from file, and more UX improvements
This commit is contained in:
@@ -60,8 +60,9 @@ class TableEditController extends Controller
|
||||
if ($tableModel === null) abort(404, "No such table.");
|
||||
|
||||
if ($tab == null) $tab = 'edit-rows';
|
||||
$tabs = ['edit-rows', 'add-rows', 'manage-columns', 'review'];
|
||||
if (!in_array($tab, $tabs)) abort(404, "No such tab: $tab");
|
||||
|
||||
$method = camel_case($tab);
|
||||
if (!method_exists($this, $method)) abort(404, "No such tab: $tab");
|
||||
|
||||
$changeset = $this->getChangeset($tableModel);
|
||||
|
||||
@@ -69,7 +70,7 @@ class TableEditController extends Controller
|
||||
dd($changeset);
|
||||
}
|
||||
|
||||
return $this->{camel_case($tab)}($changeset);
|
||||
return $this->$method($changeset);
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnusedPrivateMethodInspection */
|
||||
@@ -101,6 +102,18 @@ class TableEditController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnusedPrivateMethodInspection */
|
||||
private function addRowsCsv(Changeset $changeset)
|
||||
{
|
||||
$columns = $changeset->fetchAndTransformColumns();
|
||||
|
||||
return view('table.propose.add-rows-csv', [
|
||||
'changeset' => $changeset,
|
||||
'table' => $changeset->table,
|
||||
'columns' => collect($columns),
|
||||
]);
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnusedPrivateMethodInspection */
|
||||
private function manageColumns(Changeset $changeset)
|
||||
{
|
||||
@@ -143,13 +156,43 @@ class TableEditController extends Controller
|
||||
$resp = $updated;
|
||||
break;
|
||||
|
||||
case 'row.add-csv':
|
||||
$fname = 'csv-file';
|
||||
if ($request->hasFile($fname)) {
|
||||
try {
|
||||
$file = $request->file($fname);
|
||||
if ($file->isValid() && $file->isReadable()) {
|
||||
$handle = $file->openFile();
|
||||
$csv = Utils::csvToArray($handle);
|
||||
if (empty($csv)) throw new \Exception("Failed to parse CSV file.");
|
||||
|
||||
$changeset->addFilledRows($csv);
|
||||
$handle = null;
|
||||
} else {
|
||||
throw new \Exception("File not valid.");
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->backWithErrors(['csv-file' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$text = trim($input->data);
|
||||
if (empty($text)) throw new \Exception("Empty CSV field and no file uploaded.");
|
||||
$changeset->addFilledRows(Utils::csvToArray($text));
|
||||
} catch (\Exception $e) {
|
||||
return $this->backWithErrors(['data' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'row.remove':
|
||||
$isNew = $changeset->isNewRow($input->id);
|
||||
$changeset->rowRemove($input->id);
|
||||
$resp = $isNew ? null : $changeset->fetchAndTransformRow($input->id);
|
||||
break;
|
||||
|
||||
case 'rows.remove-empty-new':
|
||||
case 'row.remove-empty-new':
|
||||
$changeset->removeEmptyNewRows();
|
||||
break;
|
||||
|
||||
@@ -162,14 +205,6 @@ class TableEditController extends Controller
|
||||
$changeset->addBlankRows($input->count);
|
||||
break;
|
||||
|
||||
case 'rows.add-csv':
|
||||
try {
|
||||
$changeset->addFilledRows(Utils::csvToArray($input->data));
|
||||
} catch (\Exception $e) {
|
||||
return $this->backWithErrors(['data' => $e->getMessage()]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'col.update':
|
||||
$data = (object)$input->data;
|
||||
$resp = $changeset->columnUpdate($data);
|
||||
|
||||
@@ -188,16 +188,19 @@ class Changeset
|
||||
$row->_orig = [];
|
||||
}
|
||||
|
||||
if ($decorate) {
|
||||
$row->_orig = array_diff((array)$row, []);
|
||||
// remove junk
|
||||
unset($row->_orig['_id']);
|
||||
unset($row->_orig['_new']);
|
||||
unset($row->_orig['_remove']);
|
||||
unset($row->_orig['_changed']);
|
||||
unset($row->_orig['_orig']);
|
||||
}
|
||||
|
||||
if ($this->isNewRow($row->_id)) {
|
||||
if ($decorate) {
|
||||
$row->_new = true;
|
||||
$row->_orig = array_diff((array)$row, []);
|
||||
// remove junk
|
||||
unset($row->_orig['_id']);
|
||||
unset($row->_orig['_new']);
|
||||
unset($row->_orig['_remove']);
|
||||
unset($row->_orig['_changed']);
|
||||
unset($row->_orig['_orig']);
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
@@ -235,6 +238,16 @@ class Changeset
|
||||
|
||||
unset($row->_row_pivot);
|
||||
|
||||
if ($decorate) {
|
||||
$row->_loadvals = array_diff((array)$row, []);
|
||||
// remove junk
|
||||
unset($row->_loadvals['_id']);
|
||||
unset($row->_loadvals['_new']);
|
||||
unset($row->_loadvals['_remove']);
|
||||
unset($row->_loadvals['_changed']);
|
||||
unset($row->_loadvals['_orig']);
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
@@ -582,6 +595,7 @@ class Changeset
|
||||
'type' => "string",
|
||||
'title' => "Column {$num}",
|
||||
'id' => $cid,
|
||||
'_new' => true,
|
||||
];
|
||||
|
||||
$this->newColumns[$cid] = $col;
|
||||
|
||||
@@ -38,6 +38,19 @@ class WidgetFactory
|
||||
"</div>";
|
||||
}
|
||||
|
||||
public function labeledPar($label, $text, $extraClasses='', $escape=true)
|
||||
{
|
||||
if (false === strpos($extraClasses, 'mb-')) $extraClasses .= ' mb-2';
|
||||
|
||||
return
|
||||
"<div class=\"row\">".
|
||||
"<label class=\"text-md-right col-form-label col-md-$this->labelCols\">".e($label)."</label>".
|
||||
"<p class=\"form-control-plaintext col-md-$this->fieldCols".e($extraClasses)."\">".
|
||||
($escape ? e($text) : $text) .
|
||||
"</p>".
|
||||
"</div>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given string to a-href if it is a link.
|
||||
*
|
||||
@@ -85,6 +98,11 @@ class WidgetFactory
|
||||
return $this->baseWidget('input', $name, $label)->type('email');
|
||||
}
|
||||
|
||||
public function file($name, $label)
|
||||
{
|
||||
return $this->baseWidget('input', $name, $label)->type('file');
|
||||
}
|
||||
|
||||
public function checkbox($name, $label)
|
||||
{
|
||||
return (new CheckboxWidget('checkbox', $name, $label))
|
||||
|
||||
Reference in New Issue
Block a user