From 6b03db235b73391fa430a07296701f0e8db1130b Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 26 Jan 2022 17:43:48 +0000 Subject: [PATCH] Use frontend-core implementation of data fetching in backend UI --- .../backend/DataTable/DataTable.svelte | 51 +++-- .../builder/src/helpers/fetchTableData.js | 209 ------------------ 2 files changed, 28 insertions(+), 232 deletions(-) delete mode 100644 packages/builder/src/helpers/fetchTableData.js diff --git a/packages/builder/src/components/backend/DataTable/DataTable.svelte b/packages/builder/src/components/backend/DataTable/DataTable.svelte index 27b1b54373..abcde0c25e 100644 --- a/packages/builder/src/components/backend/DataTable/DataTable.svelte +++ b/packages/builder/src/components/backend/DataTable/DataTable.svelte @@ -14,18 +14,19 @@ import Table from "./Table.svelte" import { TableNames } from "constants" import CreateEditRow from "./modals/CreateEditRow.svelte" - import { fetchTableData } from "helpers/fetchTableData" import { Pagination } from "@budibase/bbui" + import { fetchData } from "@budibase/frontend-core" + import { API } from "api" let hideAutocolumns = true + $: isUsersTable = $tables.selected?._id === TableNames.USERS $: type = $tables.selected?.type $: isInternal = type !== "external" $: schema = $tables.selected?.schema $: enrichedSchema = enrichSchema($tables.selected?.schema) $: id = $tables.selected?._id - $: search = searchTable(id) - $: columnOptions = Object.keys($search.schema || {}) + $: fetch = createFetch(id) const enrichSchema = schema => { let tempSchema = { ...schema } @@ -47,18 +48,24 @@ return tempSchema } // Fetches new data whenever the table changes - const searchTable = tableId => { - return fetchTableData({ - tableId, - schema, - limit: 10, - paginate: true, + const createFetch = tableId => { + return fetchData({ + API, + datasource: { + tableId, + type: "table", + }, + options: { + schema, + limit: 10, + paginate: true, + }, }) } // Fetch data whenever sorting option changes const onSort = e => { - search.update({ + fetch.update({ sortColumn: e.detail.column, sortOrder: e.detail.order, }) @@ -66,22 +73,20 @@ // Fetch data whenever filters change const onFilter = e => { - search.update({ - filters: e.detail, + fetch.update({ + filter: e.detail, }) } // Fetch data whenever schema changes const onUpdateColumns = () => { - search.update({ - schema, - }) + fetch.refresh() } // Fetch data whenever rows are modified. Unfortunately we have to lose // our pagination place, as our bookmarks will have shifted. const onUpdateRows = () => { - search.update() + fetch.update() } @@ -91,9 +96,9 @@ schema={enrichedSchema} {type} tableId={id} - data={$search.rows} + data={$fetch.rows} bind:hideAutocolumns - loading={$search.loading} + loading={$fetch.loading} on:sort={onSort} allowEditing disableSorting @@ -138,11 +143,11 @@
diff --git a/packages/builder/src/helpers/fetchTableData.js b/packages/builder/src/helpers/fetchTableData.js deleted file mode 100644 index 375b018039..0000000000 --- a/packages/builder/src/helpers/fetchTableData.js +++ /dev/null @@ -1,209 +0,0 @@ -// Do not use any aliased imports in common files, as these will be bundled -// by multiple bundlers which may not be able to resolve them. -// This will eventually be replaced by the new client implementation when we -// add a core package. -import { writable, derived, get } from "svelte/store" -import { API } from "api" -import { LuceneUtils } from "@budibase/frontend-core" - -const defaultOptions = { - tableId: null, - filters: null, - limit: 10, - sortColumn: null, - sortOrder: "ascending", - paginate: true, - schema: null, -} - -export const fetchTableData = opts => { - // Save option set so we can override it later rather than relying on params - let options = { - ...defaultOptions, - ...opts, - } - - // Local non-observable state - let query - let sortType - let lastBookmark - - // Local observable state - const store = writable({ - rows: [], - schema: null, - loading: false, - loaded: false, - bookmarks: [], - pageNumber: 0, - }) - - // Derive certain properties to return - const derivedStore = derived(store, $store => { - return { - ...$store, - hasNextPage: $store.bookmarks[$store.pageNumber + 1] != null, - hasPrevPage: $store.pageNumber > 0, - } - }) - - const fetchPage = async bookmark => { - lastBookmark = bookmark - const { tableId, limit, sortColumn, sortOrder, paginate } = options - return await API.searchTable({ - tableId, - query, - limit, - sort: sortColumn, - sortOrder: sortOrder?.toLowerCase() ?? "ascending", - sortType, - paginate, - bookmark, - }) - } - - // Fetches a fresh set of results from the server - const fetchData = async () => { - const { tableId, schema, sortColumn, filters } = options - - // Ensure table ID exists - if (!tableId) { - return - } - - // Get and enrich schema. - // Ensure there are "name" properties for all fields and that field schema - // are objects - let enrichedSchema = schema - if (!enrichedSchema) { - const definition = await API.fetchTableDefinition(tableId) - enrichedSchema = definition?.schema ?? null - } - if (enrichedSchema) { - Object.entries(schema).forEach(([fieldName, fieldSchema]) => { - if (typeof fieldSchema === "string") { - enrichedSchema[fieldName] = { - type: fieldSchema, - name: fieldName, - } - } else { - enrichedSchema[fieldName] = { - ...fieldSchema, - name: fieldName, - } - } - }) - - // Save fixed schema so we can provide it later - options.schema = enrichedSchema - } - - // Ensure schema exists - if (!schema) { - return - } - store.update($store => ({ ...$store, schema, loading: true })) - - // Work out what sort type to use - if (!sortColumn || !schema[sortColumn]) { - sortType = "string" - } - const type = schema?.[sortColumn]?.type - sortType = type === "number" ? "number" : "string" - - // Build the lucene query - query = LuceneUtils.buildLuceneQuery(filters) - - // Actually fetch data - const page = await fetchPage() - store.update($store => ({ - ...$store, - loading: false, - loaded: true, - pageNumber: 0, - rows: page.rows, - bookmarks: page.hasNextPage ? [null, page.bookmark] : [null], - })) - } - - // Fetches the next page of data - const nextPage = async () => { - const state = get(derivedStore) - if (state.loading || !options.paginate || !state.hasNextPage) { - return - } - - // Fetch next page - store.update($store => ({ ...$store, loading: true })) - const page = await fetchPage(state.bookmarks[state.pageNumber + 1]) - - // Update state - store.update($store => { - let { bookmarks, pageNumber } = $store - if (page.hasNextPage) { - bookmarks[pageNumber + 2] = page.bookmark - } - return { - ...$store, - pageNumber: pageNumber + 1, - rows: page.rows, - bookmarks, - loading: false, - } - }) - } - - // Fetches the previous page of data - const prevPage = async () => { - const state = get(derivedStore) - if (state.loading || !options.paginate || !state.hasPrevPage) { - return - } - - // Fetch previous page - store.update($store => ({ ...$store, loading: true })) - const page = await fetchPage(state.bookmarks[state.pageNumber - 1]) - - // Update state - store.update($store => { - return { - ...$store, - pageNumber: $store.pageNumber - 1, - rows: page.rows, - loading: false, - } - }) - } - - // Resets the data set and updates options - const update = async newOptions => { - if (newOptions) { - options = { - ...options, - ...newOptions, - } - } - await fetchData() - } - - // Loads the same page again - const refresh = async () => { - if (get(store).loading) { - return - } - const page = await fetchPage(lastBookmark) - store.update($store => ({ ...$store, rows: page.rows })) - } - - // Initially fetch data but don't bother waiting for the result - fetchData() - - // Return our derived store which will be updated over time - return { - subscribe: derivedStore.subscribe, - nextPage, - prevPage, - update, - refresh, - } -}