From c61cf5d583a78453fd7d3f2c7013c1442c2f3d6d Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 19 Dec 2024 16:53:51 +0100 Subject: [PATCH 1/4] Type table store --- .../stores/builder/{tables.js => tables.ts} | 137 +++++++++++------- 1 file changed, 81 insertions(+), 56 deletions(-) rename packages/builder/src/stores/builder/{tables.js => tables.ts} (63%) diff --git a/packages/builder/src/stores/builder/tables.js b/packages/builder/src/stores/builder/tables.ts similarity index 63% rename from packages/builder/src/stores/builder/tables.js rename to packages/builder/src/stores/builder/tables.ts index 8b3424f507..7a61d513ca 100644 --- a/packages/builder/src/stores/builder/tables.js +++ b/packages/builder/src/stores/builder/tables.ts @@ -1,30 +1,64 @@ -import { FieldType } from "@budibase/types" +import { + FieldSchema, + FieldType, + SaveTableRequest, + Table, +} from "@budibase/types" import { SWITCHABLE_TYPES } from "@budibase/shared-core" -import { get, writable, derived } from "svelte/store" +import { get, derived, Writable } from "svelte/store" import { cloneDeep } from "lodash/fp" import { API } from "api" +import { DerivedBudiStore } from "stores/BudiStore" -export function createTablesStore() { - const store = writable({ - list: [], - selectedTableId: null, - }) - const derivedStore = derived(store, $store => ({ - ...$store, - selected: $store.list?.find(table => table._id === $store.selectedTableId), - })) +interface BuilderTableStore { + list: Table[] + selectedTableId?: string +} - const fetch = async () => { +interface DerivedTableStore extends BuilderTableStore { + selected?: Table +} + +export class TableStore extends DerivedBudiStore< + BuilderTableStore, + DerivedTableStore +> { + constructor() { + const makeDerivedStore = (store: Writable) => { + return derived(store, $store => ({ + ...$store, + selected: $store.list?.find( + table => table._id === $store.selectedTableId + ), + })) + } + + super( + { + list: [], + selectedTableId: undefined, + }, + makeDerivedStore + ) + + this.select = this.select.bind(this) + } + + async init() { + return this.fetch() + } + + async fetch() { const tables = await API.getTables() - store.update(state => ({ + this.store.update(state => ({ ...state, list: tables, })) } - const singleFetch = async tableId => { + private async singleFetch(tableId: string) { const table = await API.getTable(tableId) - store.update(state => { + this.store.update(state => { const list = [] // update the list, keep order accurate for (let tbl of state.list) { @@ -39,16 +73,16 @@ export function createTablesStore() { }) } - const select = tableId => { - store.update(state => ({ + select(tableId: string | undefined) { + this.store.update(state => ({ ...state, selectedTableId: tableId, })) } - const save = async table => { - const updatedTable = cloneDeep(table) - const oldTable = get(store).list.filter(t => t._id === table._id)[0] + async save(table: Table) { + const updatedTable: SaveTableRequest = cloneDeep(table) + const oldTable = get(this.store).list.filter(t => t._id === table._id)[0] const fieldNames = [] // Update any renamed schema keys to reflect their names @@ -79,8 +113,8 @@ export function createTablesStore() { } const savedTable = await API.saveTable(updatedTable) - replaceTable(savedTable._id, savedTable) - select(savedTable._id) + this.replaceTable(savedTable._id, savedTable) + this.select(savedTable._id) // make sure tables up to date (related) let newTableIds = [] for (let column of Object.values(updatedTable?.schema || {})) { @@ -99,28 +133,33 @@ export function createTablesStore() { const tableIdsToFetch = [...new Set([...newTableIds, ...oldTableIds])] // too many tables to fetch, just get all if (tableIdsToFetch.length > 3) { - await fetch() + await this.fetch() } else { - await Promise.all(tableIdsToFetch.map(id => singleFetch(id))) + await Promise.all(tableIdsToFetch.map(id => this.singleFetch(id))) } return savedTable } - const deleteTable = async table => { + async delete(table: { _id: string; _rev: any }) { if (!table?._id) { return } await API.deleteTable(table._id, table._rev || "rev") - replaceTable(table._id, null) + this.replaceTable(table._id, null) } - const saveField = async ({ + async saveField({ originalName, field, primaryDisplay = false, indexes, - }) => { - let draft = cloneDeep(get(derivedStore).selected) + }: { + originalName: string + field: FieldSchema + primaryDisplay: boolean + indexes: Record + }) { + const draft: SaveTableRequest = cloneDeep(get(this.derivedStore).selected!) // delete the original if renaming // need to handle if the column had no name, empty string @@ -139,7 +178,7 @@ export function createTablesStore() { const fields = Object.keys(draft.schema) // pick another display column randomly if unselecting draft.primaryDisplay = fields.filter( - name => name !== originalName || name !== field + name => name !== originalName || name !== field.name )[0] } if (indexes) { @@ -150,24 +189,24 @@ export function createTablesStore() { [field.name]: cloneDeep(field), } - await save(draft) + await this.save(draft) } - const deleteField = async field => { - let draft = cloneDeep(get(derivedStore).selected) + async deleteField(field: { name: string | number }) { + let draft = cloneDeep(get(this.derivedStore).selected!) delete draft.schema[field.name] - await save(draft) + await this.save(draft) } // Handles external updates of tables - const replaceTable = (tableId, table) => { + replaceTable(tableId: string | undefined, table: Table | null) { if (!tableId) { return } // Handle deletion if (!table) { - store.update(state => ({ + this.store.update(state => ({ ...state, list: state.list.filter(x => x._id !== tableId), })) @@ -175,9 +214,9 @@ export function createTablesStore() { } // Add new table - const index = get(store).list.findIndex(x => x._id === table._id) + const index = get(this.store).list.findIndex(x => x._id === table._id) if (index === -1) { - store.update(state => ({ + this.store.update(state => ({ ...state, list: [...state.list, table], })) @@ -188,7 +227,7 @@ export function createTablesStore() { // This function has to merge state as there discrepancies with the table // API endpoints. The table list endpoint and get table endpoint use the // "type" property to mean different things. - store.update(state => { + this.store.update(state => { state.list[index] = { ...table, type: state.list[index].type, @@ -198,26 +237,12 @@ export function createTablesStore() { } } - const removeDatasourceTables = datasourceId => { - store.update(state => ({ + removeDatasourceTables(datasourceId: any) { + this.store.update(state => ({ ...state, list: state.list.filter(table => table.sourceId !== datasourceId), })) } - - return { - ...store, - subscribe: derivedStore.subscribe, - fetch, - init: fetch, - select, - save, - delete: deleteTable, - saveField, - deleteField, - replaceTable, - removeDatasourceTables, - } } -export const tables = createTablesStore() +export const tables = new TableStore() From 079aa769786a2e37421dad9e9a37888932183d55 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 19 Dec 2024 17:09:17 +0100 Subject: [PATCH 2/4] Types anys --- packages/builder/src/stores/builder/tables.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/stores/builder/tables.ts b/packages/builder/src/stores/builder/tables.ts index 7a61d513ca..d050a48b5e 100644 --- a/packages/builder/src/stores/builder/tables.ts +++ b/packages/builder/src/stores/builder/tables.ts @@ -140,7 +140,7 @@ export class TableStore extends DerivedBudiStore< return savedTable } - async delete(table: { _id: string; _rev: any }) { + async delete(table: { _id: string; _rev: string }) { if (!table?._id) { return } @@ -237,7 +237,7 @@ export class TableStore extends DerivedBudiStore< } } - removeDatasourceTables(datasourceId: any) { + removeDatasourceTables(datasourceId: string) { this.store.update(state => ({ ...state, list: state.list.filter(table => table.sourceId !== datasourceId), From ffab29cdeee3915f187410173fa738c7dd8ecba8 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 19 Dec 2024 17:11:50 +0100 Subject: [PATCH 3/4] Remove unnecessary null check --- packages/builder/src/stores/builder/tables.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/stores/builder/tables.ts b/packages/builder/src/stores/builder/tables.ts index d050a48b5e..31b3a64b5b 100644 --- a/packages/builder/src/stores/builder/tables.ts +++ b/packages/builder/src/stores/builder/tables.ts @@ -144,7 +144,7 @@ export class TableStore extends DerivedBudiStore< if (!table?._id) { return } - await API.deleteTable(table._id, table._rev || "rev") + await API.deleteTable(table._id, table._rev) this.replaceTable(table._id, null) } From 2ca4dec7005ba48daf4df6b50e8f7315c69516a5 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 19 Dec 2024 17:15:28 +0100 Subject: [PATCH 4/4] Clean code --- packages/builder/src/stores/builder/tables.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/builder/src/stores/builder/tables.ts b/packages/builder/src/stores/builder/tables.ts index 31b3a64b5b..d7eb7d89f2 100644 --- a/packages/builder/src/stores/builder/tables.ts +++ b/packages/builder/src/stores/builder/tables.ts @@ -141,9 +141,6 @@ export class TableStore extends DerivedBudiStore< } async delete(table: { _id: string; _rev: string }) { - if (!table?._id) { - return - } await API.deleteTable(table._id, table._rev) this.replaceTable(table._id, null) }