Enable creating and updating rows through views

This commit is contained in:
Andrew Kingston 2023-08-01 11:16:10 +01:00
parent a8c2cf8c08
commit 9d2b31af54
4 changed files with 71 additions and 23 deletions

View File

@ -33,4 +33,47 @@ export const buildViewV2Endpoints = API => ({
delete: async viewId => { delete: async viewId => {
return await API.delete({ url: `/api/v2/views/${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,
},
})
},
}) })

View File

@ -4,7 +4,7 @@
import { NewRowID } from "../lib/constants" import { NewRowID } from "../lib/constants"
const { const {
enrichedRows, rows,
focusedCellId, focusedCellId,
visibleColumns, visibleColumns,
focusedRow, focusedRow,
@ -142,7 +142,7 @@
// Focuses the first cell in the grid // Focuses the first cell in the grid
const focusFirstCell = () => { const focusFirstCell = () => {
const firstRow = $enrichedRows[0] const firstRow = $rows[0]
if (!firstRow) { if (!firstRow) {
return return
} }
@ -183,7 +183,7 @@
if (!$focusedRow) { if (!$focusedRow) {
return return
} }
const newRow = $enrichedRows[$focusedRow.__idx + delta] const newRow = $rows[$focusedRow.__idx + delta]
if (newRow) { if (newRow) {
const split = $focusedCellId.split("-") const split = $focusedCellId.split("-")
$focusedCellId = `${newRow._id}-${split[1]}` $focusedCellId = `${newRow._id}-${split[1]}`

View File

@ -31,9 +31,7 @@ export const deriveStores = context => {
if ($props.datasource?.type === "viewV2") { if ($props.datasource?.type === "viewV2") {
config.canEditPrimaryDisplay = false config.canEditPrimaryDisplay = false
config.canEditColumns = false config.canEditColumns = false
config.canEditRows = false
config.canDeleteRows = false config.canDeleteRows = false
config.canAddRows = false
} }
// Disable adding rows if we don't have any valid columns // Disable adding rows if we don't have any valid columns

View File

@ -16,17 +16,13 @@ export const createStores = () => {
const error = writable(null) const error = writable(null)
// Generate a lookup map to quick find a row by ID // Generate a lookup map to quick find a row by ID
const rowLookupMap = derived( const rowLookupMap = derived(rows, $rows => {
rows,
$rows => {
let map = {} let map = {}
for (let i = 0; i < $rows.length; i++) { for (let i = 0; i < $rows.length; i++) {
map[$rows[i]._id] = i map[$rows[i]._id] = i
} }
return map return map
}, })
{}
)
// Mark loaded as true if we've ever stopped loading // Mark loaded as true if we've ever stopped loading
let hasStartedLoading = false let hasStartedLoading = false
@ -47,8 +43,7 @@ export const createStores = () => {
...$rowChangeCache[row._id], ...$rowChangeCache[row._id],
__idx: idx, __idx: idx,
})) }))
}, }
[]
) )
return { return {
@ -262,13 +257,14 @@ export const createActions = context => {
let newRow = { ...row } let newRow = { ...row }
if ($datasource.type === "table") { if ($datasource.type === "table") {
newRow.tableId = $datasource.tableId newRow.tableId = $datasource.tableId
newRow = await API.saveRow(newRow, SuppressErrors)
} else if ($datasource.type === "viewV2") { } else if ($datasource.type === "viewV2") {
newRow.tableId = $datasource.tableId newRow.tableId = $datasource.tableId
newRow._viewId = $datasource.id newRow._viewId = $datasource.id
newRow = await API.viewV2.createRow(newRow)
} else { } else {
return return
} }
newRow = await API.saveRow(newRow, SuppressErrors)
// Update state // Update state
if (idx != null) { if (idx != null) {
@ -362,6 +358,7 @@ export const createActions = context => {
const updateRow = async (rowId, changes) => { const updateRow = async (rowId, changes) => {
const $rows = get(rows) const $rows = get(rows)
const $rowLookupMap = get(rowLookupMap) const $rowLookupMap = get(rowLookupMap)
const $datasource = get(datasource)
const index = $rowLookupMap[rowId] const index = $rowLookupMap[rowId]
const row = $rows[index] const row = $rows[index]
if (index == null || !Object.keys(changes || {}).length) { if (index == null || !Object.keys(changes || {}).length) {
@ -395,10 +392,20 @@ export const createActions = context => {
...state, ...state,
[rowId]: true, [rowId]: true,
})) }))
const saved = await API.saveRow(
let saved
if ($datasource.type === "table") {
saved = await API.saveRow(
{ ...row, ...get(rowChangeCache)[rowId] }, { ...row, ...get(rowChangeCache)[rowId] },
SuppressErrors 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 // Update state after a successful change
if (saved?._id) { if (saved?._id) {