diff --git a/app/Http/Controllers/TableEditController.php b/app/Http/Controllers/TableEditController.php
index db17c66..a37ca85 100644
--- a/app/Http/Controllers/TableEditController.php
+++ b/app/Http/Controllers/TableEditController.php
@@ -123,20 +123,36 @@ class TableEditController extends Controller
$input = objBag($request->all(), false);
+ $resp = null;
+ $code = 200;
+
try {
- $code = 200;
switch ($input->action) {
case 'row.update':
$data = (object)$input->data;
$resp = $changeset->rowUpdate($data);
break;
+ case 'row.update-many':
+ $newVals = $input->data;
+ $updated = [];
+ foreach ($newVals as $rowUpdate) {
+ $r = $changeset->rowUpdate($rowUpdate);
+ $updated[$r->_id] = $r;
+ }
+ $resp = $updated;
+ 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':
+ $changeset->removeEmptyNewRows();
+ break;
+
case 'row.restore':
$changeset->rowRestore($input->id);
$resp = $changeset->fetchAndTransformRow($input->id);
@@ -144,13 +160,6 @@ class TableEditController extends Controller
case 'rows.add':
$changeset->addBlankRows($input->count);
-
- // rows.add is sent via a form
- if ($input->has('redirect')) {
- return redirect($input->redirect);
- } else {
- $resp = null;
- }
break;
case 'rows.add-csv':
@@ -159,13 +168,6 @@ class TableEditController extends Controller
} catch (\Exception $e) {
return $this->backWithErrors(['data' => $e->getMessage()]);
}
-
- // rows.add-csv is sent via a form
- if ($input->has('redirect')) {
- return redirect($input->redirect);
- } else {
- $resp = null;
- }
break;
case 'col.update':
@@ -190,7 +192,6 @@ class TableEditController extends Controller
case 'col.sort':
$changeset->setColOrder($input->order);
- $resp = null;
break;
default:
@@ -204,6 +205,11 @@ class TableEditController extends Controller
$this->storeChangeset($changeset);
+ // Redirect requested via form
+ if ($code == 200 && $input->has('redirect')) {
+ return redirect($input->redirect);
+ }
+
return $this->jsonResponse($resp, $code);
}
}
diff --git a/app/Tables/Changeset.php b/app/Tables/Changeset.php
index 8e260dc..391d057 100644
--- a/app/Tables/Changeset.php
+++ b/app/Tables/Changeset.php
@@ -191,6 +191,13 @@ class Changeset
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;
}
@@ -359,7 +366,9 @@ class Changeset
public function fetchRow(int $id)
{
if ($this->isNewRow($id)) {
- return (object)$this->newRows[$id];
+ $nr = (object)$this->newRows[$id];
+ $nr->_new = true;
+ return $nr;
}
$r = $this->revision->rowsData($this->fetchColumns(), true, false)
@@ -557,7 +566,8 @@ class Changeset
$rows = self::csvToRowsArray($columns, $csvArray, false)
->keyBy('_id');
- $this->newRows = array_merge($this->newRows, $rows->all());
+ // using '+' to avoid renumbering
+ $this->newRows = $this->newRows + $rows->toArray();
}
public function addBlankCol()
@@ -587,4 +597,17 @@ class Changeset
$this->columnOrder = array_merge($order, $missing);
}
+
+ public function removeEmptyNewRows()
+ {
+ $cols = $this->fetchColumns();
+ $emptyTpl = collect($cols)->keyBy('id')->map(function(Column $c) {
+ return $c->cast(null);
+ })->all();
+
+ $this->newRows = array_filter($this->newRows, function ($r) use ($emptyTpl) {
+ $emptyTpl['_id'] = $r['_id'];
+ return $emptyTpl != $r;
+ });
+ }
}
diff --git a/app/helpers.php b/app/helpers.php
index eb39c42..bd3796a 100644
--- a/app/helpers.php
+++ b/app/helpers.php
@@ -126,6 +126,11 @@ function collection_paginate($items, $per_page, $mapFn = null)
$page = Request::get('page', 1);
$pageItems = $items->forPage($page, $per_page)->values();
+ if (count($pageItems) == 0 && $page > 1) {
+ $page = 1;
+ Request::replace(['page' => $page]);
+ $pageItems = $items->forPage($page, $per_page)->values();
+ }
return new Illuminate\Pagination\LengthAwarePaginator(
$mapFn ? $pageItems->map($mapFn) : $pageItems,
diff --git a/public/fonts/fa-dtbl-1-preview.html b/public/fonts/fa-dtbl-1-preview.html
index 79196f5..dc7a923 100644
--- a/public/fonts/fa-dtbl-1-preview.html
+++ b/public/fonts/fa-dtbl-1-preview.html
@@ -162,6 +162,7 @@
[data-icon]:before,
.fa-address-card-o:before,
+.fa-arrow-left:before,
.fa-bars:before,
.fa-calendar:before,
.fa-chevron-down:before,
@@ -172,13 +173,13 @@
.fa-exclamation-triangle:before,
.fa-eye:before,
.fa-facebook-square:before,
+.fa-file-excel-o:before,
.fa-floppy-o:before,
.fa-github:before,
.fa-globe:before,
.fa-google:before,
.fa-history:before,
.fa-home:before,
-.fa-hourglass:before,
.fa-inbox:before,
.fa-key-modern:before,
.fa-link:before,
@@ -186,14 +187,15 @@
.fa-pencil:before,
.fa-plus:before,
.fa-question-circle:before,
+.fa-reply:before,
.fa-sign-in:before,
.fa-sign-out:before,
+.fa-spinner:before,
.fa-star:before,
.fa-star-o:before,
.fa-sun-o:before,
.fa-table:before,
.fa-th-list:before,
-.fa-times:before,
.fa-trash-o:before,
.fa-undo:before,
.fa-user:before,
@@ -216,45 +218,47 @@
}
.fa-address-card-o:before { content: "\f100"; }
-.fa-bars:before { content: "\f101"; }
-.fa-calendar:before { content: "\f102"; }
-.fa-chevron-down:before { content: "\f103"; }
-.fa-chevron-up:before { content: "\f104"; }
-.fa-code-fork:before { content: "\f105"; }
-.fa-comment:before { content: "\f106"; }
-.fa-download:before { content: "\f107"; }
-.fa-exclamation-triangle:before { content: "\f108"; }
-.fa-eye:before { content: "\f109"; }
-.fa-facebook-square:before { content: "\f10a"; }
-.fa-floppy-o:before { content: "\f10b"; }
-.fa-github:before { content: "\f10c"; }
-.fa-globe:before { content: "\f10d"; }
-.fa-google:before { content: "\f10e"; }
-.fa-history:before { content: "\f10f"; }
-.fa-home:before { content: "\f110"; }
-.fa-hourglass:before { content: "\f111"; }
-.fa-inbox:before { content: "\f112"; }
-.fa-key-modern:before { content: "\f113"; }
-.fa-link:before { content: "\f114"; }
-.fa-moon-o:before { content: "\f115"; }
-.fa-pencil:before { content: "\f116"; }
-.fa-plus:before { content: "\f117"; }
-.fa-question-circle:before { content: "\f118"; }
-.fa-sign-in:before { content: "\f119"; }
-.fa-sign-out:before { content: "\f11a"; }
-.fa-star:before { content: "\f11b"; }
-.fa-star-o:before { content: "\f11c"; }
-.fa-sun-o:before { content: "\f11d"; }
-.fa-table:before { content: "\f11e"; }
-.fa-th-list:before { content: "\f11f"; }
-.fa-times:before { content: "\f120"; }
-.fa-trash-o:before { content: "\f121"; }
-.fa-undo:before { content: "\f122"; }
-.fa-user:before { content: "\f123"; }
-.fa-user-circle-o:before { content: "\f124"; }
-.fa-user-plus:before { content: "\f125"; }
-.fa-users:before { content: "\f126"; }
-.fa-wrench:before { content: "\f127"; }
+.fa-arrow-left:before { content: "\f101"; }
+.fa-bars:before { content: "\f102"; }
+.fa-calendar:before { content: "\f103"; }
+.fa-chevron-down:before { content: "\f104"; }
+.fa-chevron-up:before { content: "\f105"; }
+.fa-code-fork:before { content: "\f106"; }
+.fa-comment:before { content: "\f107"; }
+.fa-download:before { content: "\f108"; }
+.fa-exclamation-triangle:before { content: "\f109"; }
+.fa-eye:before { content: "\f10a"; }
+.fa-facebook-square:before { content: "\f10b"; }
+.fa-file-excel-o:before { content: "\f10c"; }
+.fa-floppy-o:before { content: "\f10d"; }
+.fa-github:before { content: "\f10e"; }
+.fa-globe:before { content: "\f10f"; }
+.fa-google:before { content: "\f110"; }
+.fa-history:before { content: "\f111"; }
+.fa-home:before { content: "\f112"; }
+.fa-inbox:before { content: "\f113"; }
+.fa-key-modern:before { content: "\f114"; }
+.fa-link:before { content: "\f115"; }
+.fa-moon-o:before { content: "\f116"; }
+.fa-pencil:before { content: "\f117"; }
+.fa-plus:before { content: "\f118"; }
+.fa-question-circle:before { content: "\f119"; }
+.fa-reply:before { content: "\f11a"; }
+.fa-sign-in:before { content: "\f11b"; }
+.fa-sign-out:before { content: "\f11c"; }
+.fa-spinner:before { content: "\f11d"; }
+.fa-star:before { content: "\f11e"; }
+.fa-star-o:before { content: "\f11f"; }
+.fa-sun-o:before { content: "\f120"; }
+.fa-table:before { content: "\f121"; }
+.fa-th-list:before { content: "\f122"; }
+.fa-trash-o:before { content: "\f123"; }
+.fa-undo:before { content: "\f124"; }
+.fa-user:before { content: "\f125"; }
+.fa-user-circle-o:before { content: "\f126"; }
+.fa-user-plus:before { content: "\f127"; }
+.fa-users:before { content: "\f128"; }
+.fa-wrench:before { content: "\f129"; }
@@ -270,7 +274,7 @@
+
+
+ PpPpPpPpPpPpPpPpPpPp
+
+
+ 12141618212436486072
+
+
+
+
+
+
+
@@ -311,7 +328,7 @@
-
+
@@ -324,7 +341,7 @@
-
+
@@ -337,7 +354,7 @@
-
+
@@ -350,7 +367,7 @@
-
+
@@ -363,7 +380,7 @@
-
+
@@ -376,7 +393,7 @@
-
+
@@ -390,7 +407,7 @@
-
+
@@ -403,7 +420,7 @@
-
+
@@ -416,7 +433,20 @@
-
+
+
+
+
+
+
+ PpPpPpPpPpPpPpPpPpPp
+
+
+ 12141618212436486072
+
+
+
+
@@ -430,7 +460,7 @@
-
+
@@ -443,7 +473,7 @@
-
+
@@ -456,7 +486,7 @@
-
+
@@ -469,7 +499,7 @@
-
+
@@ -482,7 +512,7 @@
-
+
@@ -495,20 +525,7 @@
-
-
-
-
-
@@ -521,7 +538,7 @@
-
+
@@ -534,7 +551,7 @@
-
+
@@ -547,7 +564,7 @@
-
+
@@ -560,7 +577,7 @@
-
+
@@ -573,7 +590,7 @@
-
+
@@ -586,7 +603,7 @@
-
+
@@ -599,7 +616,20 @@
-
+
+
+
+
+
+
+ PpPpPpPpPpPpPpPpPpPp
+
+
+ 12141618212436486072
+
+
+
+
@@ -612,7 +642,7 @@
-
+
@@ -625,86 +655,85 @@
-
+
@@ -717,7 +746,7 @@
-
+
@@ -730,7 +759,7 @@
-
+
@@ -743,7 +772,7 @@
-
+
@@ -756,7 +785,7 @@
-
+
@@ -769,7 +798,7 @@
-
+
@@ -782,7 +811,7 @@
-
+
@@ -795,7 +824,7 @@
-
+
diff --git a/public/fonts/fa-dtbl-1.css b/public/fonts/fa-dtbl-1.css
index 8ceda4a..85efae6 100644
--- a/public/fonts/fa-dtbl-1.css
+++ b/public/fonts/fa-dtbl-1.css
@@ -7,7 +7,6 @@
src: url('./fa-dtbl-1.eot?v=1.1.0');
src: url('./fa-dtbl-1.eot?#iefix&v=1.1.0') format('embedded-opentype'),
url('./fa-dtbl-1.woff2?v=1.1.0') format('woff2'),
- url('./fa-dtbl-1.woff?v=1.1.0') format('woff'),
url('./fa-dtbl-1.ttf?v=1.1.0') format('truetype'),
url('./fa-dtbl-1.svg?v=1.1.0#fa-dtbl-1') format('svg');
font-weight: normal;
@@ -40,42 +39,44 @@
}
.fa-address-card-o::before, .fa-vcard-o::before { content: "\f100"; }
-.fa-bars::before { content: "\f101"; }
-.fa-calendar::before { content: "\f102"; }
-.fa-chevron-down::before { content: "\f103"; }
-.fa-chevron-up::before { content: "\f104"; }
-.fa-code-fork::before { content: "\f105"; }
-.fa-comment::before { content: "\f106"; }
-.fa-download::before { content: "\f107"; }
-.fa-exclamation-triangle::before, .fa-warning::before { content: "\f108"; }
-.fa-eye::before { content: "\f109"; }
-.fa-facebook-square::before { content: "\f10a"; }
-.fa-floppy-o::before, .fa-save::before { content: "\f10b"; }
-.fa-github::before { content: "\f10c"; }
-.fa-globe::before { content: "\f10d"; }
-.fa-google::before { content: "\f10e"; }
-.fa-history::before { content: "\f10f"; }
-.fa-home::before { content: "\f110"; }
-.fa-hourglass::before { content: "\f111"; }
-.fa-inbox::before { content: "\f112"; }
-.fa-key-modern::before { content: "\f113"; }
-.fa-link::before { content: "\f114"; }
-.fa-moon-o::before { content: "\f115"; }
-.fa-pencil::before { content: "\f116"; }
-.fa-plus::before { content: "\f117"; }
-.fa-question-circle::before { content: "\f118"; }
-.fa-sign-in::before { content: "\f119"; }
-.fa-sign-out::before { content: "\f11a"; }
-.fa-star::before { content: "\f11b"; }
-.fa-star-o::before { content: "\f11c"; }
-.fa-sun-o::before { content: "\f11d"; }
-.fa-table::before { content: "\f11e"; }
-.fa-th-list::before { content: "\f11f"; }
-.fa-times::before, .fa-close::before { content: "\f120"; }
-.fa-trash-o::before { content: "\f121"; }
-.fa-undo::before { content: "\f122"; }
-.fa-user::before { content: "\f123"; }
-.fa-user-circle-o::before { content: "\f124"; }
-.fa-user-plus::before { content: "\f125"; }
-.fa-users::before { content: "\f126"; }
-.fa-wrench::before { content: "\f127"; }
+.fa-arrow-left::before { content: "\f101"; }
+.fa-bars::before { content: "\f102"; }
+.fa-calendar::before { content: "\f103"; }
+.fa-chevron-down::before { content: "\f104"; }
+.fa-chevron-up::before { content: "\f105"; }
+.fa-code-fork::before { content: "\f106"; }
+.fa-comment::before { content: "\f107"; }
+.fa-download::before { content: "\f108"; }
+.fa-exclamation-triangle::before, .fa-warning::before { content: "\f109"; }
+.fa-eye::before { content: "\f10a"; }
+.fa-facebook-square::before { content: "\f10b"; }
+.fa-file-excel-o::before { content: "\f10c"; }
+.fa-floppy-o::before, .fa-save::before { content: "\f10d"; }
+.fa-github::before { content: "\f10e"; }
+.fa-globe::before { content: "\f10f"; }
+.fa-google::before { content: "\f110"; }
+.fa-history::before { content: "\f111"; }
+.fa-home::before { content: "\f112"; }
+.fa-inbox::before { content: "\f113"; }
+.fa-key-modern::before { content: "\f114"; }
+.fa-link::before { content: "\f115"; }
+.fa-moon-o::before { content: "\f116"; }
+.fa-pencil::before { content: "\f117"; }
+.fa-plus::before { content: "\f118"; }
+.fa-question-circle::before { content: "\f119"; }
+.fa-reply::before { content: "\f11a"; }
+.fa-sign-in::before { content: "\f11b"; }
+.fa-sign-out::before { content: "\f11c"; }
+.fa-spinner::before { content: "\f11d"; }
+.fa-star::before { content: "\f11e"; }
+.fa-star-o::before { content: "\f11f"; }
+.fa-sun-o::before { content: "\f120"; }
+.fa-table::before { content: "\f121"; }
+.fa-th-list::before { content: "\f122"; }
+.fa-trash-o::before { content: "\f123"; }
+.fa-undo::before { content: "\f124"; }
+.fa-user::before { content: "\f125"; }
+.fa-user-circle-o::before { content: "\f126"; }
+.fa-user-plus::before { content: "\f127"; }
+.fa-users::before { content: "\f128"; }
+.fa-wrench::before { content: "\f129"; }
diff --git a/public/fonts/fa-dtbl-1.eot b/public/fonts/fa-dtbl-1.eot
index ba9c715..f7fcd1f 100644
Binary files a/public/fonts/fa-dtbl-1.eot and b/public/fonts/fa-dtbl-1.eot differ
diff --git a/public/fonts/fa-dtbl-1.svg b/public/fonts/fa-dtbl-1.svg
index 6f84d1b..44eae9d 100644
--- a/public/fonts/fa-dtbl-1.svg
+++ b/public/fonts/fa-dtbl-1.svg
@@ -1,12 +1,12 @@
diff --git a/public/fonts/fa-dtbl-1.ttf b/public/fonts/fa-dtbl-1.ttf
index 0bf2e9c..36204ac 100644
Binary files a/public/fonts/fa-dtbl-1.ttf and b/public/fonts/fa-dtbl-1.ttf differ
diff --git a/public/fonts/fa-dtbl-1.woff b/public/fonts/fa-dtbl-1.woff
deleted file mode 100644
index b2f914a..0000000
Binary files a/public/fonts/fa-dtbl-1.woff and /dev/null differ
diff --git a/public/fonts/fa-dtbl-1.woff2 b/public/fonts/fa-dtbl-1.woff2
index 40a9397..4956c12 100644
Binary files a/public/fonts/fa-dtbl-1.woff2 and b/public/fonts/fa-dtbl-1.woff2 differ
diff --git a/resources/assets/fa-config/wanted.ini b/resources/assets/fa-config/wanted.ini
index 7fda533..e4820ed 100644
--- a/resources/assets/fa-config/wanted.ini
+++ b/resources/assets/fa-config/wanted.ini
@@ -38,20 +38,26 @@ download # export buttons
wrench # Table options
trash-o
-plus
-warning
-undo
+plus # Add column in table editor
+warning # validation fail icon
+undo # Used in table editor
-close
-hourglass
+spinner
+paper-plane-o # save proposal
+# dark mode
sun-o
moon-o
+# manual sort buttons
chevron-up
chevron-down
-bars
+bars # sort icon
+file-excel-o # CSV button
+
+reply # reply, or back
+arrow-left # back
# Unused
; sliders
diff --git a/resources/assets/js/components/ColumnEditor.vue b/resources/assets/js/components/ColumnEditor.vue
index a54647a..64143da 100644
--- a/resources/assets/js/components/ColumnEditor.vue
+++ b/resources/assets/js/components/ColumnEditor.vue
@@ -5,7 +5,7 @@ Complex animated column editor for the table edit page
-
+
|
diff --git a/resources/assets/js/components/RowsEditor.vue b/resources/assets/js/components/RowsEditor.vue
index e623f5d..c30b457 100644
--- a/resources/assets/js/components/RowsEditor.vue
+++ b/resources/assets/js/components/RowsEditor.vue
@@ -10,49 +10,95 @@ Rows are identified by row._id, columns by col.id
-->
-
+
+
+
+
+
+
+
+
+
+ CSV
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/views/table/propose/edit-rows.blade.php b/resources/views/table/propose/edit-rows.blade.php
index 794aa13..3d00656 100644
--- a/resources/views/table/propose/edit-rows.blade.php
+++ b/resources/views/table/propose/edit-rows.blade.php
@@ -23,6 +23,11 @@