From 9d2b31af54232c03cca73c060c63642b53ba975d Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 1 Aug 2023 11:16:10 +0100 Subject: [PATCH] Enable creating and updating rows through views --- packages/frontend-core/src/api/viewsV2.js | 43 +++++++++++++++++++ .../grid/overlays/KeyboardManager.svelte | 6 +-- .../src/components/grid/stores/config.js | 2 - .../src/components/grid/stores/rows.js | 43 +++++++++++-------- 4 files changed, 71 insertions(+), 23 deletions(-) diff --git a/packages/frontend-core/src/api/viewsV2.js b/packages/frontend-core/src/api/viewsV2.js index 37bc78ae16..81fcfcf455 100644 --- a/packages/frontend-core/src/api/viewsV2.js +++ b/packages/frontend-core/src/api/viewsV2.js @@ -33,4 +33,47 @@ export const buildViewV2Endpoints = API => ({ delete: async viewId => { return await API.delete({ url: `/api/v2/views/${viewId}` }) }, + /** + * Creates a row from a view + * @param row the row to create + * @param suppressErrors whether or not to suppress error notifications + */ + createRow: async (row, suppressErrors = false) => { + if (!row?._viewId || !row?.tableId) { + return + } + return await API.post({ + url: `/api/v2/views/${row._viewId}/rows`, + body: row, + suppressErrors, + }) + }, + /** + * Updates an existing row through a view + * @param row the row to update + * @param suppressErrors whether or not to suppress error notifications + */ + updateRow: async (row, suppressErrors = false) => { + if (!row?._viewId || !row?.tableId || !row?._id) { + return + } + return await API.patch({ + url: `/api/v2/views/${row._viewId}/rows/${row._id}`, + body: row, + suppressErrors, + }) + }, + /** + * Deletes multiple rows from a table through a view + * @param viewId the table ID to delete the rows from + * @param rows the array of rows to delete + */ + deleteRows: async ({ viewId, rows }) => { + return await API.delete({ + url: `/api/v2/views/${viewId}/rows`, + body: { + rows, + }, + }) + }, }) diff --git a/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte b/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte index 721babd913..4f30c3c7db 100644 --- a/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte +++ b/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte @@ -4,7 +4,7 @@ import { NewRowID } from "../lib/constants" const { - enrichedRows, + rows, focusedCellId, visibleColumns, focusedRow, @@ -142,7 +142,7 @@ // Focuses the first cell in the grid const focusFirstCell = () => { - const firstRow = $enrichedRows[0] + const firstRow = $rows[0] if (!firstRow) { return } @@ -183,7 +183,7 @@ if (!$focusedRow) { return } - const newRow = $enrichedRows[$focusedRow.__idx + delta] + const newRow = $rows[$focusedRow.__idx + delta] if (newRow) { const split = $focusedCellId.split("-") $focusedCellId = `${newRow._id}-${split[1]}` diff --git a/packages/frontend-core/src/components/grid/stores/config.js b/packages/frontend-core/src/components/grid/stores/config.js index 0ed04bf741..9a72e781f7 100644 --- a/packages/frontend-core/src/components/grid/stores/config.js +++ b/packages/frontend-core/src/components/grid/stores/config.js @@ -31,9 +31,7 @@ export const deriveStores = context => { if ($props.datasource?.type === "viewV2") { config.canEditPrimaryDisplay = false config.canEditColumns = false - config.canEditRows = false config.canDeleteRows = false - config.canAddRows = false } // Disable adding rows if we don't have any valid columns diff --git a/packages/frontend-core/src/components/grid/stores/rows.js b/packages/frontend-core/src/components/grid/stores/rows.js index 35bacb786a..ac50672e07 100644 --- a/packages/frontend-core/src/components/grid/stores/rows.js +++ b/packages/frontend-core/src/components/grid/stores/rows.js @@ -16,17 +16,13 @@ export const createStores = () => { const error = writable(null) // Generate a lookup map to quick find a row by ID - const rowLookupMap = derived( - rows, - $rows => { - let map = {} - for (let i = 0; i < $rows.length; i++) { - map[$rows[i]._id] = i - } - return map - }, - {} - ) + const rowLookupMap = derived(rows, $rows => { + let map = {} + for (let i = 0; i < $rows.length; i++) { + map[$rows[i]._id] = i + } + return map + }) // Mark loaded as true if we've ever stopped loading let hasStartedLoading = false @@ -47,8 +43,7 @@ export const createStores = () => { ...$rowChangeCache[row._id], __idx: idx, })) - }, - [] + } ) return { @@ -262,13 +257,14 @@ export const createActions = context => { let newRow = { ...row } if ($datasource.type === "table") { newRow.tableId = $datasource.tableId + newRow = await API.saveRow(newRow, SuppressErrors) } else if ($datasource.type === "viewV2") { newRow.tableId = $datasource.tableId newRow._viewId = $datasource.id + newRow = await API.viewV2.createRow(newRow) } else { return } - newRow = await API.saveRow(newRow, SuppressErrors) // Update state if (idx != null) { @@ -362,6 +358,7 @@ export const createActions = context => { const updateRow = async (rowId, changes) => { const $rows = get(rows) const $rowLookupMap = get(rowLookupMap) + const $datasource = get(datasource) const index = $rowLookupMap[rowId] const row = $rows[index] if (index == null || !Object.keys(changes || {}).length) { @@ -395,10 +392,20 @@ export const createActions = context => { ...state, [rowId]: true, })) - const saved = await API.saveRow( - { ...row, ...get(rowChangeCache)[rowId] }, - SuppressErrors - ) + + let saved + if ($datasource.type === "table") { + saved = await API.saveRow( + { ...row, ...get(rowChangeCache)[rowId] }, + SuppressErrors + ) + } else if ($datasource.type === "viewV2") { + saved = await API.viewV2.updateRow( + { ...row, ...get(rowChangeCache)[rowId] }, + SuppressErrors + ) + saved._viewId = $datasource.id + } // Update state after a successful change if (saved?._id) {