Split out more datasource specific logic

This commit is contained in:
Andrew Kingston 2023-08-03 13:18:58 +01:00
parent b00f3d2418
commit d443bf3616
8 changed files with 142 additions and 78 deletions

View File

@ -1,2 +1 @@
export { default as Grid } from "./layout/Grid.svelte"
export { DatasourceType } from "./lib/constants"

View File

@ -1,7 +1,3 @@
export const DatasourceType = {
Table: "table",
ViewV2: "viewV2",
}
export const Padding = 246
export const MaxCellRenderHeight = 222
export const ScrollBarSize = 8

View File

@ -1,6 +1,5 @@
import { derivedMemo } from "../../../utils"
import { derived } from "svelte/store"
import { DatasourceType } from "../lib/constants"
export const deriveStores = context => {
const { props, hasNonAutoColumn } = context
@ -29,7 +28,7 @@ export const deriveStores = context => {
}
// Disable some features if we're editing a view
if ($props.datasource?.type === DatasourceType.ViewV2) {
if ($props.datasource?.type === "viewV2") {
config.canEditColumns = false
}

View File

@ -19,18 +19,6 @@ export const deriveStores = context => {
}
let newSchema = { ...$definition?.schema }
// Edge case to temporarily allow deletion of duplicated user
// fields that were saved with the "disabled" flag set.
// By overriding the saved schema we ensure only overrides can
// set the disabled flag.
// TODO: remove in future
Object.keys(newSchema).forEach(field => {
newSchema[field] = {
...newSchema[field],
disabled: false,
}
})
// Apply schema overrides
Object.keys($schemaOverrides || {}).forEach(field => {
if (newSchema[field]) {
@ -60,34 +48,34 @@ export const deriveStores = context => {
}
export const createActions = context => {
const { datasource, definition, API, config, dispatch } = context
const { datasource, definition, config, dispatch, table, viewV2 } = context
// Gets the appropriate API for the configured datasource type
const getAPI = () => {
const $datasource = get(datasource)
switch ($datasource?.type) {
case "table":
return table
case "viewV2":
return viewV2
default:
return null
}
}
// Refreshes the datasource definition
const refreshDefinition = async () => {
const $datasource = get(datasource)
if ($datasource.type === "table") {
definition.set(await API.fetchTableDefinition($datasource.tableId))
} else if ($datasource.type === "viewV2") {
// const definition = await API.viewsV2.(get(tableId))
// table.set(definition)
}
return await getAPI()?.actions.refreshDefinition()
}
// Saves the datasource definition
const saveDefinition = async newDefinition => {
const $config = get(config)
const $datasource = get(datasource)
// Update local state
definition.set(newDefinition)
// Update server
if ($config.canSaveSchema) {
if ($datasource.type === "table") {
await API.saveTable(newDefinition)
} else if ($datasource.type === "viewV2") {
await API.viewV2.update(newDefinition)
}
if (get(config).canSaveSchema) {
await getAPI()?.actions.saveDefinition(newDefinition)
}
// Broadcast change to external state can be updated, as this change
@ -95,12 +83,30 @@ export const createActions = context => {
dispatch("updatedefinition", newDefinition)
}
// Adds a row to the datasource
const addRow = async row => {
return await getAPI()?.actions.addRow(row)
}
// Updates an existing row in the datasource
const updateRow = async row => {
return await getAPI()?.actions.updateRow(row)
}
// Deletes rows from the datasource
const deleteRows = async rows => {
return await getAPI()?.actions.deleteRows(rows)
}
return {
datasource: {
...datasource,
actions: {
refreshDefinition,
saveDefinition,
addRow,
updateRow,
deleteRows,
},
},
}

View File

@ -20,12 +20,13 @@ import * as ViewV2 from "./viewV2"
import * as Datasource from "./datasource"
const DependencyOrderedStores = [
// Common stores
Notifications,
Sort,
Filter,
Bounds,
Scroll,
Table,
ViewV2,
Datasource,
Columns,
Rows,
@ -39,10 +40,6 @@ const DependencyOrderedStores = [
Pagination,
Clipboard,
Config,
// Datasource specific stores
Table,
ViewV2,
]
export const attachStores = context => {

View File

@ -240,19 +240,9 @@ export const createActions = context => {
// Adds a new row
const addRow = async (row, idx, bubble = false) => {
try {
// Create row
const $datasource = get(datasource)
// Create row. Spread row so we can mutate and enrich safely.
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 datasource.actions.addRow(newRow)
// Update state
if (idx != null) {
@ -381,19 +371,11 @@ export const createActions = context => {
[rowId]: true,
}))
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 row
const saved = await datasource.actions.updateRow({
...row,
...get(rowChangeCache)[rowId],
})
// Update state after a successful change
if (saved?._id) {
@ -428,23 +410,12 @@ export const createActions = context => {
if (!rowsToDelete?.length) {
return
}
const $datasource = get(datasource)
// Actually delete rows
rowsToDelete.forEach(row => {
delete row.__idx
})
if ($datasource.type === "table") {
await API.deleteRows({
tableId: $datasource.tableId,
rows: rowsToDelete,
})
} else if ($datasource.type === "viewV2") {
await API.viewV2.deleteRows({
viewId: $datasource.id,
rows: rowsToDelete,
})
}
await datasource.actions.deleteRows(rowsToDelete)
// Update state
handleRemoveRows(rowsToDelete)

View File

@ -1,5 +1,43 @@
import { get } from "svelte/store"
const SuppressErrors = true
export const createActions = context => {
const { definition, API, datasource } = context
const refreshDefinition = async () => {
definition.set(await API.fetchTableDefinition(get(datasource).tableId))
}
const saveDefinition = async newDefinition => {
await API.saveTable(newDefinition)
}
const saveRow = async row => {
row.tableId = get(datasource)?.tableId
return await API.saveRow(row, SuppressErrors)
}
const deleteRows = async rows => {
await API.deleteRows({
tableId: get(datasource).tableId,
rows,
})
}
return {
table: {
actions: {
refreshDefinition,
saveDefinition,
addRow: saveRow,
updateRow: saveRow,
deleteRows,
},
},
}
}
export const initialise = context => {
const { datasource, fetch, filter, sort } = context

View File

@ -1,5 +1,63 @@
import { get } from "svelte/store"
const SuppressErrors = true
export const createActions = context => {
const { definition, API, datasource } = context
const refreshDefinition = async () => {
const $datasource = get(datasource)
if (!$datasource) {
definition.set(null)
return
}
const table = await API.fetchTableDefinition($datasource.tableId)
const view = Object.values(table?.views || {}).find(
view => view.id === $datasource.id
)
definition.set(view)
}
const saveDefinition = async newDefinition => {
await API.viewV2.update(newDefinition)
}
const addRow = async row => {
const $datasource = get(datasource)
row.tableId = $datasource?.tableId
row._viewId = $datasource?.id
return await API.viewV2.createRow(row, SuppressErrors)
}
const updateRow = async row => {
const $datasource = get(datasource)
const savedRow = await API.viewV2.updateRow(row, SuppressErrors)
return {
...savedRow,
_viewId: $datasource.id,
}
}
const deleteRows = async rows => {
await API.viewV2.deleteRows({
viewId: get(datasource).id,
rows,
})
}
return {
viewV2: {
actions: {
refreshDefinition,
saveDefinition,
addRow,
updateRow,
deleteRows,
},
},
}
}
export const initialise = context => {
const { definition, datasource, sort, rows } = context