From 150961fcf26e642a38b590e21e036c6002fe2a7c Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 26 Jul 2023 13:23:31 +0100 Subject: [PATCH] WIP: split views into separate stores, fix datasource list, use unique data table for views V2 --- ...DataTable.svelte => TableDataTable.svelte} | 6 +- .../backend/DataTable/ViewV2DataTable.svelte | 50 +++++++++++ .../DatasourceNavigator.svelte | 30 +++++-- .../TableNavigator/TableNavigator.svelte | 8 +- packages/builder/src/helpers/urlStateSync.js | 2 +- .../data/table/[tableId]/index.svelte | 2 +- .../data/view/[viewName]/_layout.svelte | 4 +- .../data/view/v2/[id]/_layout.svelte | 15 ++-- .../data/view/v2/[id]/index.svelte | 27 +----- packages/builder/src/stores/backend/index.js | 1 + packages/builder/src/stores/backend/views.js | 26 ++---- .../builder/src/stores/backend/viewsV2.js | 85 +++++++++++++++++++ .../src/components/grid/layout/Grid.svelte | 6 +- .../components/grid/layout/HeaderRow.svelte | 4 +- .../src/components/grid/layout/NewRow.svelte | 4 +- .../src/components/grid/lib/websocket.js | 12 +-- .../src/components/grid/stores/config.js | 4 +- .../src/components/grid/stores/rows.js | 21 +---- 18 files changed, 206 insertions(+), 101 deletions(-) rename packages/builder/src/components/backend/DataTable/{DataTable.svelte => TableDataTable.svelte} (97%) create mode 100644 packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte create mode 100644 packages/builder/src/stores/backend/viewsV2.js diff --git a/packages/builder/src/components/backend/DataTable/DataTable.svelte b/packages/builder/src/components/backend/DataTable/TableDataTable.svelte similarity index 97% rename from packages/builder/src/components/backend/DataTable/DataTable.svelte rename to packages/builder/src/components/backend/DataTable/TableDataTable.svelte index 33db9b60e3..7a03564ba1 100644 --- a/packages/builder/src/components/backend/DataTable/DataTable.svelte +++ b/packages/builder/src/components/backend/DataTable/TableDataTable.svelte @@ -26,6 +26,10 @@ $: id = $tables.selected?._id $: isUsersTable = id === TableNames.USERS $: isInternal = $tables.selected?.type !== "external" + $: datasource = { + type: "table", + tableId: id, + } const handleGridTableUpdate = async e => { tables.replaceTable(id, e.detail) @@ -43,7 +47,7 @@
+ import { datasources, viewsV2 } from "stores/backend" + import { Grid } from "@budibase/frontend-core" + import { API } from "api" + import GridCreateEditRowModal from "components/backend/DataTable/modals/grid/GridCreateEditRowModal.svelte" + import GridFilterButton from "components/backend/DataTable/buttons/grid/GridFilterButton.svelte" + import GridManageAccessButton from "components/backend/DataTable/buttons/grid/GridManageAccessButton.svelte" + + $: id = $viewsV2.selected?.id + $: datasource = { + type: "viewV2", + id, + tableId: id?.split("_").slice(0, -1).join("_"), + } + $: console.log(datasource) + + const handleGridViewUpdate = async e => { + viewsV2.replace(id, e.detail) + } + + +
+ + + + + + + + + +
+ + diff --git a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte index f7b6f61a10..8f5a35ea1f 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte @@ -1,7 +1,14 @@ diff --git a/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte b/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte index e641bd99a5..caa9de222a 100644 --- a/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte +++ b/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte @@ -1,5 +1,5 @@ -
- -
- - + diff --git a/packages/builder/src/stores/backend/index.js b/packages/builder/src/stores/backend/index.js index 6fbc9f82c7..278e43c1ed 100644 --- a/packages/builder/src/stores/backend/index.js +++ b/packages/builder/src/stores/backend/index.js @@ -1,6 +1,7 @@ export { database } from "./database" export { tables } from "./tables" export { views } from "./views" +export { viewsV2 } from "./viewsV2" export { permissions } from "./permissions" export { roles } from "./roles" export { datasources, ImportTableError } from "./datasources" diff --git a/packages/builder/src/stores/backend/views.js b/packages/builder/src/stores/backend/views.js index 8df337a299..603b0830fc 100644 --- a/packages/builder/src/stores/backend/views.js +++ b/packages/builder/src/stores/backend/views.js @@ -9,7 +9,10 @@ export function createViewsStore() { const derivedStore = derived([store, tables], ([$store, $tables]) => { let list = [] $tables.list?.forEach(table => { - list = list.concat(Object.values(table?.views || {})) + const views = Object.values(table?.views || {}).filter(view => { + return view.version !== 2 + }) + list = list.concat(views) }) return { ...$store, @@ -26,11 +29,7 @@ export function createViewsStore() { } const deleteView = async view => { - if (view.version === 2) { - await API.viewV2.delete(view.id) - } else { - await API.deleteView(view.name) - } + await API.deleteView(view.name) // Update tables tables.update(state => { @@ -40,20 +39,6 @@ export function createViewsStore() { }) } - const create = async view => { - const savedViewResponse = await API.viewV2.create(view) - const savedView = savedViewResponse.data - - // Update tables - tables.update(state => { - const table = state.list.find(table => table._id === view.tableId) - table.views[view.name] = savedView - return { ...state } - }) - - return savedView - } - const save = async view => { const savedView = await API.saveView(view) @@ -74,7 +59,6 @@ export function createViewsStore() { subscribe: derivedStore.subscribe, select, delete: deleteView, - create, save, } } diff --git a/packages/builder/src/stores/backend/viewsV2.js b/packages/builder/src/stores/backend/viewsV2.js new file mode 100644 index 0000000000..8b7b1d876c --- /dev/null +++ b/packages/builder/src/stores/backend/viewsV2.js @@ -0,0 +1,85 @@ +import { writable, derived } from "svelte/store" +import { tables } from "./" +import { API } from "api" + +export function createViewsV2Store() { + const store = writable({ + selectedViewId: null, + }) + const derivedStore = derived([store, tables], ([$store, $tables]) => { + let list = [] + $tables.list?.forEach(table => { + const views = Object.values(table?.views || {}).filter(view => { + return view.version === 2 + }) + list = list.concat(views) + }) + return { + ...$store, + list, + selected: list.find(view => view.id === $store.selectedViewId), + } + }) + + const select = id => { + store.update(state => ({ + ...state, + selectedViewId: id, + })) + } + + const deleteView = async view => { + await API.viewV2.delete(view.id) + + // Update tables + tables.update(state => { + const table = state.list.find(table => table._id === view.tableId) + delete table.views[view.name] + return { ...state } + }) + } + + const create = async view => { + const savedViewResponse = await API.viewV2.create(view) + const savedView = savedViewResponse.data + + // Update tables + tables.update(state => { + const table = state.list.find(table => table._id === view.tableId) + table.views[view.name] = savedView + return { ...state } + }) + + return savedView + } + + const save = async view => { + // No dedicated save endpoint at this time + // const savedView = await API.saveView(view) + // + // // Update tables + // tables.update(state => { + // const table = state.list.find(table => table._id === view.tableId) + // if (table) { + // if (view.originalName) { + // delete table.views[view.originalName] + // } + // table.views[view.name] = savedView + // } + // return { ...state } + // }) + } + + const replace = (id, view) => {} + + return { + subscribe: derivedStore.subscribe, + select, + delete: deleteView, + create, + save, + replace, + } +} + +export const viewsV2 = createViewsV2Store() diff --git a/packages/frontend-core/src/components/grid/layout/Grid.svelte b/packages/frontend-core/src/components/grid/layout/Grid.svelte index d92851719f..556e6ca16e 100644 --- a/packages/frontend-core/src/components/grid/layout/Grid.svelte +++ b/packages/frontend-core/src/components/grid/layout/Grid.svelte @@ -28,8 +28,7 @@ } from "../lib/constants" export let API = null - export let tableId = null - export let datasourceType = null + export let datasource = null export let schemaOverrides = null export let columnWhitelist = null export let allowAddRows = true @@ -77,8 +76,7 @@ // Keep config store up to date with props $: config.set({ - tableId, - datasourceType, + datasource, schemaOverrides, columnWhitelist, allowAddRows, diff --git a/packages/frontend-core/src/components/grid/layout/HeaderRow.svelte b/packages/frontend-core/src/components/grid/layout/HeaderRow.svelte index f39e679da4..d964931682 100644 --- a/packages/frontend-core/src/components/grid/layout/HeaderRow.svelte +++ b/packages/frontend-core/src/components/grid/layout/HeaderRow.svelte @@ -12,7 +12,7 @@ width, config, hasNonAutoColumn, - tableId, + datasource, loading, } = getContext("grid") @@ -33,7 +33,7 @@
{#if $config.allowSchemaChanges} - {#key $tableId} + {#key $datasource} { - const { rows, tableId, users, focusedCellId, table, API } = context + const { rows, datasource, users, focusedCellId, table, API } = context const socket = createWebsocket("/socket/grid") - const connectToTable = tableId => { + const connectToDatasource = datasource => { if (!socket.connected) { return } // Identify which table we are editing const appId = API.getAppID() socket.emit( - GridSocketEvent.SelectTable, - { tableId, appId }, + GridSocketEvent.SelectDatasource, + { datasource, appId }, ({ users: gridUsers }) => { users.set(gridUsers) } @@ -23,7 +23,7 @@ export const createGridWebsocket = context => { // Built-in events socket.on("connect", () => { - connectToTable(get(tableId)) + connectToDatasource(get(datasource)) }) socket.on("connect_error", err => { console.log("Failed to connect to grid websocket:", err.message) @@ -57,7 +57,7 @@ export const createGridWebsocket = context => { }) // Change websocket connection when table changes - tableId.subscribe(connectToTable) + datasource.subscribe(connectToDatasource) // Notify selected cell changes focusedCellId.subscribe($focusedCellId => { diff --git a/packages/frontend-core/src/components/grid/stores/config.js b/packages/frontend-core/src/components/grid/stores/config.js index fc9decc1ef..8aa6b818e2 100644 --- a/packages/frontend-core/src/components/grid/stores/config.js +++ b/packages/frontend-core/src/components/grid/stores/config.js @@ -6,7 +6,7 @@ export const createStores = context => { const getProp = prop => derivedMemo(config, $config => $config[prop]) // Derive and memoize some props so that we can react to them in isolation - const tableId = getProp("tableId") + const datasource = getProp("datasource") const initialSortColumn = getProp("initialSortColumn") const initialSortOrder = getProp("initialSortOrder") const initialFilter = getProp("initialFilter") @@ -18,7 +18,7 @@ export const createStores = context => { return { config, - tableId, + datasource, initialSortColumn, initialSortOrder, initialFilter, diff --git a/packages/frontend-core/src/components/grid/stores/rows.js b/packages/frontend-core/src/components/grid/stores/rows.js index dccbc774a4..1346d7c8b2 100644 --- a/packages/frontend-core/src/components/grid/stores/rows.js +++ b/packages/frontend-core/src/components/grid/stores/rows.js @@ -59,7 +59,7 @@ export const deriveStores = context => { filter, loading, sort, - tableId, + datasource, API, scroll, validation, @@ -71,7 +71,7 @@ export const deriveStores = context => { hasNextPage, error, notifications, - props, + config, } = context const instanceLoaded = writable(false) const fetch = writable(null) @@ -95,7 +95,7 @@ export const deriveStores = context => { // Reset everything when table ID changes let unsubscribe = null let lastResetKey = null - tableId.subscribe(async $tableId => { + datasource.subscribe(async $datasource => { // Unsub from previous fetch if one exists unsubscribe?.() fetch.set(null) @@ -108,21 +108,6 @@ export const deriveStores = context => { const $filter = get(filter) const $sort = get(sort) - let datasource - if (props.datasourceType === "viewV2") { - const tableId = $tableId - datasource = { - type: props.datasourceType, - id: $tableId, - tableId: tableId.split("_").slice(0, -1).join("_"), - } - } else { - datasource = { - type: props.datasourceType, - tableId: $tableId, - } - } - // Create new fetch model const newFetch = fetchData({ API,