From 45ee1570370c9e41fe503a12401ac5664081a832 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 11:24:37 +0100 Subject: [PATCH 01/34] Rename file --- packages/client/src/stores/index.js | 2 +- packages/client/src/stores/{notification.js => notification.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/client/src/stores/{notification.js => notification.ts} (100%) diff --git a/packages/client/src/stores/index.js b/packages/client/src/stores/index.js index f2b80ed732..e099434b3d 100644 --- a/packages/client/src/stores/index.js +++ b/packages/client/src/stores/index.js @@ -1,6 +1,6 @@ export { authStore } from "./auth" export { appStore } from "./app" -export { notificationStore } from "./notification" +export { notificationStore } from "./notification.ts" export { routeStore } from "./routes" export { screenStore } from "./screens" export { builderStore } from "./builder" diff --git a/packages/client/src/stores/notification.js b/packages/client/src/stores/notification.ts similarity index 100% rename from packages/client/src/stores/notification.js rename to packages/client/src/stores/notification.ts From 96cee21792413d638191e4a6872bf5e388d1786a Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 11:32:10 +0100 Subject: [PATCH 02/34] Type store --- packages/client/src/stores/notification.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/client/src/stores/notification.ts b/packages/client/src/stores/notification.ts index 054117aaba..6f5fcc9ef4 100644 --- a/packages/client/src/stores/notification.ts +++ b/packages/client/src/stores/notification.ts @@ -6,7 +6,7 @@ const DEFAULT_NOTIFICATION_TIMEOUT = 3000 const createNotificationStore = () => { let block = false - const store = writable([]) + const store = writable<{ id: string; message: string; count: number }[]>([]) const blockNotifications = (timeout = 1000) => { block = true @@ -14,17 +14,18 @@ const createNotificationStore = () => { } const send = ( - message, + message: string, type = "info", - icon, + icon: string, autoDismiss = true, - duration, + duration: number, count = 1 ) => { if (block) { return } + // @ts-expect-error if (get(routeStore).queryParams?.peek) { window.parent.postMessage({ type: "notification", @@ -66,7 +67,7 @@ const createNotificationStore = () => { } } - const dismiss = id => { + const dismiss = (id: string) => { store.update(state => { return state.filter(n => n.id !== id) }) @@ -76,13 +77,13 @@ const createNotificationStore = () => { subscribe: store.subscribe, actions: { send, - info: (msg, autoDismiss, duration) => + info: (msg: string, autoDismiss: boolean, duration: number) => send(msg, "info", "Info", autoDismiss ?? true, duration), - success: (msg, autoDismiss, duration) => + success: (msg: string, autoDismiss: boolean, duration: number) => send(msg, "success", "CheckmarkCircle", autoDismiss ?? true, duration), - warning: (msg, autoDismiss, duration) => + warning: (msg: string, autoDismiss: boolean, duration: number) => send(msg, "warning", "Alert", autoDismiss ?? true, duration), - error: (msg, autoDismiss, duration) => + error: (msg: string, autoDismiss: boolean, duration: number) => send(msg, "error", "Alert", autoDismiss ?? false, duration), blockNotifications, dismiss, From f938eb3297e5dd3de249d41c36ef7c0565f1996a Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 11:34:15 +0100 Subject: [PATCH 03/34] api to ts --- packages/client/src/api/{api.js => api.ts} | 6 +++++- packages/client/src/api/index.js | 2 +- packages/client/src/stores/notification.ts | 10 +++++----- 3 files changed, 11 insertions(+), 7 deletions(-) rename packages/client/src/api/{api.js => api.ts} (96%) diff --git a/packages/client/src/api/api.js b/packages/client/src/api/api.ts similarity index 96% rename from packages/client/src/api/api.js rename to packages/client/src/api/api.ts index d4c8faa4d2..59430e4ebd 100644 --- a/packages/client/src/api/api.js +++ b/packages/client/src/api/api.ts @@ -1,6 +1,10 @@ import { createAPIClient } from "@budibase/frontend-core" import { authStore } from "../stores/auth.js" -import { notificationStore, devToolsEnabled, devToolsStore } from "../stores/" +import { + notificationStore, + devToolsEnabled, + devToolsStore, +} from "../stores/index.js" import { get } from "svelte/store" export const API = createAPIClient({ diff --git a/packages/client/src/api/index.js b/packages/client/src/api/index.js index 5eb6b2b6f4..a63e19bfbb 100644 --- a/packages/client/src/api/index.js +++ b/packages/client/src/api/index.js @@ -1,4 +1,4 @@ -import { API } from "./api.js" +import { API } from "./api.ts" import { patchAPI } from "./patches.js" // Certain endpoints which return rows need patched so that they transform diff --git a/packages/client/src/stores/notification.ts b/packages/client/src/stores/notification.ts index 6f5fcc9ef4..5e1a4774c1 100644 --- a/packages/client/src/stores/notification.ts +++ b/packages/client/src/stores/notification.ts @@ -18,7 +18,7 @@ const createNotificationStore = () => { type = "info", icon: string, autoDismiss = true, - duration: number, + duration?: number, count = 1 ) => { if (block) { @@ -77,13 +77,13 @@ const createNotificationStore = () => { subscribe: store.subscribe, actions: { send, - info: (msg: string, autoDismiss: boolean, duration: number) => + info: (msg: string, autoDismiss?: boolean, duration?: number) => send(msg, "info", "Info", autoDismiss ?? true, duration), - success: (msg: string, autoDismiss: boolean, duration: number) => + success: (msg: string, autoDismiss?: boolean, duration?: number) => send(msg, "success", "CheckmarkCircle", autoDismiss ?? true, duration), - warning: (msg: string, autoDismiss: boolean, duration: number) => + warning: (msg: string, autoDismiss?: boolean, duration?: number) => send(msg, "warning", "Alert", autoDismiss ?? true, duration), - error: (msg: string, autoDismiss: boolean, duration: number) => + error: (msg: string, autoDismiss?: boolean, duration?: number) => send(msg, "error", "Alert", autoDismiss ?? false, duration), blockNotifications, dismiss, From a0950f15d9bb4d77dbdcc98d8f96fa93b78ef085 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 11:38:16 +0100 Subject: [PATCH 04/34] Add window typings --- packages/client/src/index.d.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/client/src/index.d.ts diff --git a/packages/client/src/index.d.ts b/packages/client/src/index.d.ts new file mode 100644 index 0000000000..7e13670b33 --- /dev/null +++ b/packages/client/src/index.d.ts @@ -0,0 +1,5 @@ +interface Window { + "##BUDIBASE_APP_ID##": string + "##BUDIBASE_IN_BUILDER##": string + MIGRATING_APP: boolean +} From 60c23ae021614dee53eb62a08e0ae9c4da974ff9 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 11:42:35 +0100 Subject: [PATCH 05/34] Type auth store --- packages/client/src/stores/{auth.js => auth.ts} | 4 +++- packages/types/src/api/web/global/self.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) rename packages/client/src/stores/{auth.js => auth.ts} (94%) diff --git a/packages/client/src/stores/auth.js b/packages/client/src/stores/auth.ts similarity index 94% rename from packages/client/src/stores/auth.js rename to packages/client/src/stores/auth.ts index 214cc7bce2..15f44e7c32 100644 --- a/packages/client/src/stores/auth.js +++ b/packages/client/src/stores/auth.ts @@ -2,7 +2,9 @@ import { API } from "api" import { writable } from "svelte/store" const createAuthStore = () => { - const store = writable(null) + const store = writable<{ + csrfToken?: string + } | null>(null) // Fetches the user object if someone is logged in and has reloaded the page const fetchUser = async () => { diff --git a/packages/types/src/api/web/global/self.ts b/packages/types/src/api/web/global/self.ts index 517559d1ca..9d99a1f1a5 100644 --- a/packages/types/src/api/web/global/self.ts +++ b/packages/types/src/api/web/global/self.ts @@ -15,5 +15,5 @@ export interface GetGlobalSelfResponse extends User { license: License budibaseAccess: boolean accountPortalAccess: boolean - csrfToken: boolean + csrfToken: string } From 6e816fb6a2ae3aa8ec13f8d5fc887bc88b3c25fe Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 11:51:27 +0100 Subject: [PATCH 06/34] Fixes --- packages/client/src/api/api.ts | 2 +- packages/client/src/stores/derived/currentRole.js | 2 +- packages/client/src/stores/notification.ts | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/client/src/api/api.ts b/packages/client/src/api/api.ts index 59430e4ebd..93f59f6e9a 100644 --- a/packages/client/src/api/api.ts +++ b/packages/client/src/api/api.ts @@ -1,5 +1,5 @@ import { createAPIClient } from "@budibase/frontend-core" -import { authStore } from "../stores/auth.js" +import { authStore } from "../stores/auth" import { notificationStore, devToolsEnabled, diff --git a/packages/client/src/stores/derived/currentRole.js b/packages/client/src/stores/derived/currentRole.js index 8bb4c5a25d..056a05f8ab 100644 --- a/packages/client/src/stores/derived/currentRole.js +++ b/packages/client/src/stores/derived/currentRole.js @@ -1,7 +1,7 @@ import { derived } from "svelte/store" import { Constants } from "@budibase/frontend-core" import { devToolsStore } from "../devTools.js" -import { authStore } from "../auth.js" +import { authStore } from "../auth" import { devToolsEnabled } from "./devToolsEnabled.js" // Derive the current role of the logged-in user diff --git a/packages/client/src/stores/notification.ts b/packages/client/src/stores/notification.ts index 5e1a4774c1..fa28b9f40a 100644 --- a/packages/client/src/stores/notification.ts +++ b/packages/client/src/stores/notification.ts @@ -25,7 +25,6 @@ const createNotificationStore = () => { return } - // @ts-expect-error if (get(routeStore).queryParams?.peek) { window.parent.postMessage({ type: "notification", From 1b6dc51f018c80938c8f45aaf2852734f3981076 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 11:51:38 +0100 Subject: [PATCH 07/34] Type routes --- .../src/stores/{routes.js => routes.ts} | 30 ++++++++++++++----- packages/types/src/documents/app/screen.ts | 1 + 2 files changed, 24 insertions(+), 7 deletions(-) rename packages/client/src/stores/{routes.js => routes.ts} (82%) diff --git a/packages/client/src/stores/routes.js b/packages/client/src/stores/routes.ts similarity index 82% rename from packages/client/src/stores/routes.js rename to packages/client/src/stores/routes.ts index 8e318af2e3..3f200a9c88 100644 --- a/packages/client/src/stores/routes.js +++ b/packages/client/src/stores/routes.ts @@ -4,8 +4,24 @@ import { API } from "api" import { peekStore } from "./peek" import { builderStore } from "./builder" +interface Route { + path: string + screenId: string +} + +interface StoreType { + routes: Route[] + routeParams: {} + activeRoute?: Route | null + routeSessionId: number + routerLoaded: boolean + queryParams?: { + peek?: boolean + } +} + const createRouteStore = () => { - const initialState = { + const initialState: StoreType = { routes: [], routeParams: {}, activeRoute: null, @@ -22,7 +38,7 @@ const createRouteStore = () => { } catch (error) { routeConfig = null } - let routes = [] + const routes: Route[] = [] Object.values(routeConfig?.routes || {}).forEach(route => { Object.entries(route.subpaths || {}).forEach(([path, config]) => { routes.push({ @@ -43,13 +59,13 @@ const createRouteStore = () => { return state }) } - const setRouteParams = routeParams => { + const setRouteParams = (routeParams: StoreType["routeParams"]) => { store.update(state => { state.routeParams = routeParams return state }) } - const setQueryParams = queryParams => { + const setQueryParams = (queryParams: { peek?: boolean }) => { store.update(state => { state.queryParams = { ...queryParams, @@ -60,13 +76,13 @@ const createRouteStore = () => { return state }) } - const setActiveRoute = route => { + const setActiveRoute = (route: string) => { store.update(state => { state.activeRoute = state.routes.find(x => x.path === route) return state }) } - const navigate = (url, peek, externalNewTab) => { + const navigate = (url: string, peek: boolean, externalNewTab: boolean) => { if (get(builderStore).inBuilder) { return } @@ -93,7 +109,7 @@ const createRouteStore = () => { const setRouterLoaded = () => { store.update(state => ({ ...state, routerLoaded: true })) } - const createFullURL = relativeURL => { + const createFullURL = (relativeURL: string) => { if (!relativeURL?.startsWith("/")) { return relativeURL } diff --git a/packages/types/src/documents/app/screen.ts b/packages/types/src/documents/app/screen.ts index b2cedf31a9..e85fd5953b 100644 --- a/packages/types/src/documents/app/screen.ts +++ b/packages/types/src/documents/app/screen.ts @@ -36,6 +36,7 @@ export type ScreenRoutingJson = Record< subpaths: Record< string, { + screenId: string screens: Record } > From 59bdd201585b90c1e87e6cfaa7b82becf2a3ef01 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 12:12:43 +0100 Subject: [PATCH 08/34] Type onError --- packages/frontend-core/src/api/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend-core/src/api/types.ts b/packages/frontend-core/src/api/types.ts index 0db1049591..940927f499 100644 --- a/packages/frontend-core/src/api/types.ts +++ b/packages/frontend-core/src/api/types.ts @@ -46,7 +46,7 @@ export type Headers = Record export type APIClientConfig = { enableCaching?: boolean attachHeaders?: (headers: Headers) => void - onError?: (error: any) => void + onError?: (error: APIError) => void onMigrationDetected?: (migration: string) => void } From e6c45d934b70ae496a8827b5f17d75cc5c8af5b8 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 12:39:44 +0100 Subject: [PATCH 09/34] Stringify api errors --- packages/frontend-core/src/api/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend-core/src/api/index.ts b/packages/frontend-core/src/api/index.ts index f7b05c338a..44e85e5a68 100644 --- a/packages/frontend-core/src/api/index.ts +++ b/packages/frontend-core/src/api/index.ts @@ -74,7 +74,7 @@ export const createAPIClient = (config: APIClientConfig = {}): APIClient => { if (json?.message) { message = json.message } else if (json?.error) { - message = json.error + message = JSON.stringify(json.error) } } catch (error) { // Do nothing From 2cbf7a47c16194741d49dc654d1d0ea059c3d54d Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 12:40:23 +0100 Subject: [PATCH 10/34] Type --- packages/frontend-core/src/api/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend-core/src/api/index.ts b/packages/frontend-core/src/api/index.ts index 44e85e5a68..b0e1970e6f 100644 --- a/packages/frontend-core/src/api/index.ts +++ b/packages/frontend-core/src/api/index.ts @@ -226,7 +226,7 @@ export const createAPIClient = (config: APIClientConfig = {}): APIClient => { return await handler(callConfig) } catch (error) { if (config?.onError) { - config.onError(error) + config.onError(error as APIError) } throw error } From 2b90d972b21325608f0f1e4f51d0d1a850be2e26 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 12:50:19 +0100 Subject: [PATCH 11/34] Clean code --- packages/frontend-core/src/api/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend-core/src/api/index.ts b/packages/frontend-core/src/api/index.ts index b0e1970e6f..92dc2d9ea3 100644 --- a/packages/frontend-core/src/api/index.ts +++ b/packages/frontend-core/src/api/index.ts @@ -68,7 +68,7 @@ export const createAPIClient = (config: APIClientConfig = {}): APIClient => { ): Promise => { // Try to read a message from the error let message = response.statusText - let json: any = null + let json = null try { json = await response.json() if (json?.message) { From 71c6480c1b3ea08cd69bc8a0cfe015aadbaa773b Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 13:00:02 +0100 Subject: [PATCH 12/34] Remove unused function --- packages/frontend-core/src/api/index.ts | 6 +----- packages/frontend-core/src/api/types.ts | 3 +-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/frontend-core/src/api/index.ts b/packages/frontend-core/src/api/index.ts index 92dc2d9ea3..6efc90023a 100644 --- a/packages/frontend-core/src/api/index.ts +++ b/packages/frontend-core/src/api/index.ts @@ -93,7 +93,7 @@ export const createAPIClient = (config: APIClientConfig = {}): APIClient => { // Generates an error object from a string const makeError = ( message: string, - url?: string, + url: string, method?: HTTPMethod ): APIError => { return { @@ -239,13 +239,9 @@ export const createAPIClient = (config: APIClientConfig = {}): APIClient => { patch: requestApiCall(HTTPMethod.PATCH), delete: requestApiCall(HTTPMethod.DELETE), put: requestApiCall(HTTPMethod.PUT), - error: (message: string) => { - throw makeError(message) - }, invalidateCache: () => { cache = {} }, - // Generic utility to extract the current app ID. Assumes that any client // that exists in an app context will be attaching our app ID header. getAppID: (): string => { diff --git a/packages/frontend-core/src/api/types.ts b/packages/frontend-core/src/api/types.ts index 940927f499..4819b4cd3b 100644 --- a/packages/frontend-core/src/api/types.ts +++ b/packages/frontend-core/src/api/types.ts @@ -86,14 +86,13 @@ export type BaseAPIClient = { patch: ( params: APICallParams ) => Promise - error: (message: string) => void invalidateCache: () => void getAppID: () => string } export type APIError = { message?: string - url?: string + url: string method?: HTTPMethod json: any status: number From 70a8b9e4688249211f5e9d56463e3524a97b2539 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 13:55:00 +0100 Subject: [PATCH 13/34] Remove screen id --- packages/types/src/documents/app/screen.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/types/src/documents/app/screen.ts b/packages/types/src/documents/app/screen.ts index e85fd5953b..b2cedf31a9 100644 --- a/packages/types/src/documents/app/screen.ts +++ b/packages/types/src/documents/app/screen.ts @@ -36,7 +36,6 @@ export type ScreenRoutingJson = Record< subpaths: Record< string, { - screenId: string screens: Record } > From 88e245a5bb7a97eedfc07ea6104e44c5d2dfbd2a Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 14:01:07 +0100 Subject: [PATCH 14/34] Fix typing --- packages/types/src/documents/app/screen.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/types/src/documents/app/screen.ts b/packages/types/src/documents/app/screen.ts index b2cedf31a9..a8c32118d3 100644 --- a/packages/types/src/documents/app/screen.ts +++ b/packages/types/src/documents/app/screen.ts @@ -33,11 +33,6 @@ export interface ScreenRoutesViewOutput extends Document { export type ScreenRoutingJson = Record< string, { - subpaths: Record< - string, - { - screens: Record - } - > + subpaths: Record } > From a5ec51028099325a288ab9fc4bca5e1978d634cb Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 15:58:59 +0100 Subject: [PATCH 15/34] Explicitly fetch the data from fetch --- packages/frontend-core/src/fetch/DataFetch.ts | 3 --- packages/frontend-core/src/fetch/index.ts | 7 ++++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/frontend-core/src/fetch/DataFetch.ts b/packages/frontend-core/src/fetch/DataFetch.ts index 9312c57637..0079fec057 100644 --- a/packages/frontend-core/src/fetch/DataFetch.ts +++ b/packages/frontend-core/src/fetch/DataFetch.ts @@ -179,9 +179,6 @@ export default abstract class DataFetch< this.store.update($store => ({ ...$store, loaded: true })) return } - - // Initially fetch data but don't bother waiting for the result - this.getInitialData() } /** diff --git a/packages/frontend-core/src/fetch/index.ts b/packages/frontend-core/src/fetch/index.ts index 4accb0b5ec..c1f35abef2 100644 --- a/packages/frontend-core/src/fetch/index.ts +++ b/packages/frontend-core/src/fetch/index.ts @@ -33,7 +33,12 @@ const DataFetchMap = { export const fetchData = ({ API, datasource, options }: any) => { const Fetch = DataFetchMap[datasource?.type as keyof typeof DataFetchMap] || TableFetch - return new Fetch({ API, datasource, ...options }) + const fetch = new Fetch({ API, datasource, ...options }) + + // Initially fetch data but don't bother waiting for the result + fetch.getInitialData() + + return fetch } // Creates an empty fetch instance with no datasource configured, so no data From 40192097d819564573343d47cd85a63b00d8be39 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 14:32:15 +0100 Subject: [PATCH 16/34] Pass datasource to instance --- packages/client/src/utils/schema.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/utils/schema.js b/packages/client/src/utils/schema.js index ffab142cf3..988c2e3316 100644 --- a/packages/client/src/utils/schema.js +++ b/packages/client/src/utils/schema.js @@ -31,7 +31,7 @@ const getDatasourceFetchInstance = datasource => { if (!handler) { return null } - return new handler({ API }) + return new handler({ API, datasource }) } /** From cbad9303d962f3b118186099aaf5c50f092b9668 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 14:24:59 +0100 Subject: [PATCH 17/34] Fix getSchema from forms --- packages/client/src/utils/schema.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/utils/schema.js b/packages/client/src/utils/schema.js index 988c2e3316..60800afc53 100644 --- a/packages/client/src/utils/schema.js +++ b/packages/client/src/utils/schema.js @@ -52,7 +52,7 @@ export const fetchDatasourceSchema = async ( // Get the normal schema as long as we aren't wanting a form schema let schema if (datasource?.type !== "query" || !options?.formSchema) { - schema = instance.getSchema(datasource, definition) + schema = instance.getSchema(definition) } else if (definition.parameters?.length) { schema = {} definition.parameters.forEach(param => { From aadc4da0b124cbdeaae04f85a008f41160dcb67e Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 10 Jan 2025 10:15:34 +0100 Subject: [PATCH 18/34] Remove duplicated utils --- .../src/components/grid/lib/utils.js | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 packages/frontend-core/src/components/grid/lib/utils.js diff --git a/packages/frontend-core/src/components/grid/lib/utils.js b/packages/frontend-core/src/components/grid/lib/utils.js deleted file mode 100644 index ee74a14bf0..0000000000 --- a/packages/frontend-core/src/components/grid/lib/utils.js +++ /dev/null @@ -1,32 +0,0 @@ -// TODO: remove when all stores are typed - -import { GeneratedIDPrefix, CellIDSeparator } from "./constants" -import { Helpers } from "@budibase/bbui" - -export const parseCellID = cellId => { - if (!cellId) { - return { rowId: undefined, field: undefined } - } - const parts = cellId.split(CellIDSeparator) - const field = parts.pop() - return { rowId: parts.join(CellIDSeparator), field } -} - -export const getCellID = (rowId, fieldName) => { - return `${rowId}${CellIDSeparator}${fieldName}` -} - -export const parseEventLocation = e => { - return { - x: e.clientX ?? e.touches?.[0]?.clientX, - y: e.clientY ?? e.touches?.[0]?.clientY, - } -} - -export const generateRowID = () => { - return `${GeneratedIDPrefix}${Helpers.uuid()}` -} - -export const isGeneratedRowID = id => { - return id?.startsWith(GeneratedIDPrefix) -} From 96052679cb5bbdda0b082ee6c471b6ce7cbaff06 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 10 Jan 2025 10:26:24 +0100 Subject: [PATCH 19/34] Convert constants.js --- .../src/components/grid/lib/{constants.js => constants.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/frontend-core/src/components/grid/lib/{constants.js => constants.ts} (100%) diff --git a/packages/frontend-core/src/components/grid/lib/constants.js b/packages/frontend-core/src/components/grid/lib/constants.ts similarity index 100% rename from packages/frontend-core/src/components/grid/lib/constants.js rename to packages/frontend-core/src/components/grid/lib/constants.ts From bb1811558570b1f29d3bd064640c6249df818e81 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 10 Jan 2025 10:26:56 +0100 Subject: [PATCH 20/34] Convert renderer --- .../grid/lib/{renderers.js => renderers.ts} | 18 ++++++++++++++---- packages/types/src/ui/stores/grid/columns.ts | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) rename packages/frontend-core/src/components/grid/lib/{renderers.js => renderers.ts} (82%) diff --git a/packages/frontend-core/src/components/grid/lib/renderers.js b/packages/frontend-core/src/components/grid/lib/renderers.ts similarity index 82% rename from packages/frontend-core/src/components/grid/lib/renderers.js rename to packages/frontend-core/src/components/grid/lib/renderers.ts index a860d01b53..b009806cc4 100644 --- a/packages/frontend-core/src/components/grid/lib/renderers.js +++ b/packages/frontend-core/src/components/grid/lib/renderers.ts @@ -1,4 +1,4 @@ -import { FieldType } from "@budibase/types" +import { FieldType, UIColumn } from "@budibase/types" import OptionsCell from "../cells/OptionsCell.svelte" import DateCell from "../cells/DateCell.svelte" @@ -40,13 +40,23 @@ const TypeComponentMap = { // Custom types for UI only role: RoleCell, } -export const getCellRenderer = column => { + +function getCellRendererByType(type: FieldType | "role" | undefined) { + if (!type) { + return + } + + return TypeComponentMap[type as keyof typeof TypeComponentMap] +} + +export const getCellRenderer = (column: UIColumn) => { if (column.calculationType) { return NumberCell } + return ( - TypeComponentMap[column?.schema?.cellRenderType] || - TypeComponentMap[column?.schema?.type] || + getCellRendererByType(column.schema?.cellRenderType) || + getCellRendererByType(column.schema?.type) || TextCell ) } diff --git a/packages/types/src/ui/stores/grid/columns.ts b/packages/types/src/ui/stores/grid/columns.ts index 7f20145246..2517d2a3e0 100644 --- a/packages/types/src/ui/stores/grid/columns.ts +++ b/packages/types/src/ui/stores/grid/columns.ts @@ -14,6 +14,7 @@ export type UIColumn = FieldSchema & { type: FieldType readonly: boolean autocolumn: boolean + cellRenderType?: FieldType | "role" } calculationType: CalculationType __idx: number From e23be5acb8ccb0d0425b39d14180817355bc7e6c Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 10 Jan 2025 10:30:19 +0100 Subject: [PATCH 21/34] Websocket to ts --- .../components/grid/lib/{websocket.js => websocket.ts} | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) rename packages/frontend-core/src/components/grid/lib/{websocket.js => websocket.ts} (89%) diff --git a/packages/frontend-core/src/components/grid/lib/websocket.js b/packages/frontend-core/src/components/grid/lib/websocket.ts similarity index 89% rename from packages/frontend-core/src/components/grid/lib/websocket.js rename to packages/frontend-core/src/components/grid/lib/websocket.ts index e7b89ff58a..437b93270d 100644 --- a/packages/frontend-core/src/components/grid/lib/websocket.js +++ b/packages/frontend-core/src/components/grid/lib/websocket.ts @@ -1,12 +1,14 @@ import { get } from "svelte/store" import { createWebsocket } from "../../../utils" import { SocketEvent, GridSocketEvent } from "@budibase/shared-core" +import { Store } from "../stores" +import { UIDatasource } from "@budibase/types" -export const createGridWebsocket = context => { +export const createGridWebsocket = (context: Store) => { const { rows, datasource, users, focusedCellId, definition, API } = context const socket = createWebsocket("/socket/grid") - const connectToDatasource = datasource => { + const connectToDatasource = (datasource: UIDatasource) => { if (!socket.connected) { return } @@ -65,7 +67,7 @@ export const createGridWebsocket = context => { GridSocketEvent.DatasourceChange, ({ datasource: newDatasource }) => { // Listen builder renames, as these aren't handled otherwise - if (newDatasource?.name !== get(definition).name) { + if (newDatasource?.name !== get(definition)?.name) { definition.set(newDatasource) } } From 535f2d68031efcb84f51493644e2d6c2fa8d7de7 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 10 Jan 2025 10:45:35 +0100 Subject: [PATCH 22/34] Type --- packages/frontend-core/src/components/grid/lib/websocket.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend-core/src/components/grid/lib/websocket.ts b/packages/frontend-core/src/components/grid/lib/websocket.ts index 437b93270d..bc41d594f4 100644 --- a/packages/frontend-core/src/components/grid/lib/websocket.ts +++ b/packages/frontend-core/src/components/grid/lib/websocket.ts @@ -2,7 +2,7 @@ import { get } from "svelte/store" import { createWebsocket } from "../../../utils" import { SocketEvent, GridSocketEvent } from "@budibase/shared-core" import { Store } from "../stores" -import { UIDatasource } from "@budibase/types" +import { UIDatasource, UIUser } from "@budibase/types" export const createGridWebsocket = (context: Store) => { const { rows, datasource, users, focusedCellId, definition, API } = context @@ -20,7 +20,7 @@ export const createGridWebsocket = (context: Store) => { datasource, appId, }, - ({ users: gridUsers }) => { + ({ users: gridUsers }: { users: UIUser[] }) => { users.set(gridUsers) } ) From 7d9debd3191668da83dac17c0f0b551a17cea0b5 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 14:49:07 +0100 Subject: [PATCH 23/34] Export DataFetchMap --- packages/frontend-core/src/fetch/index.ts | 14 +++++++------- packages/frontend-core/src/index.ts | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/frontend-core/src/fetch/index.ts b/packages/frontend-core/src/fetch/index.ts index c1f35abef2..e343b351bc 100644 --- a/packages/frontend-core/src/fetch/index.ts +++ b/packages/frontend-core/src/fetch/index.ts @@ -1,18 +1,18 @@ -import TableFetch from "./TableFetch.js" -import ViewFetch from "./ViewFetch.js" -import ViewV2Fetch from "./ViewV2Fetch.js" +import TableFetch from "./TableFetch" +import ViewFetch from "./ViewFetch" +import ViewV2Fetch from "./ViewV2Fetch" import QueryFetch from "./QueryFetch" import RelationshipFetch from "./RelationshipFetch" import NestedProviderFetch from "./NestedProviderFetch" import FieldFetch from "./FieldFetch" import JSONArrayFetch from "./JSONArrayFetch" -import UserFetch from "./UserFetch.js" +import UserFetch from "./UserFetch" import GroupUserFetch from "./GroupUserFetch" import CustomFetch from "./CustomFetch" -import QueryArrayFetch from "./QueryArrayFetch.js" -import { APIClient } from "../api/types.js" +import QueryArrayFetch from "./QueryArrayFetch" +import { APIClient } from "../api/types" -const DataFetchMap = { +export const DataFetchMap = { table: TableFetch, view: ViewFetch, viewV2: ViewV2Fetch, diff --git a/packages/frontend-core/src/index.ts b/packages/frontend-core/src/index.ts index 37951dc776..5b24a9ac50 100644 --- a/packages/frontend-core/src/index.ts +++ b/packages/frontend-core/src/index.ts @@ -1,5 +1,5 @@ export { createAPIClient } from "./api" -export { fetchData } from "./fetch" +export { fetchData, DataFetchMap } from "./fetch" export * as Constants from "./constants" export * from "./stores" export * from "./utils" From 7df69f154a594a5250b511ef62de29a2063870ad Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 14:50:21 +0100 Subject: [PATCH 24/34] Basic ts conversion --- packages/client/src/sdk.js | 2 +- .../client/src/utils/{schema.js => schema.ts} | 24 +++---------------- 2 files changed, 4 insertions(+), 22 deletions(-) rename packages/client/src/utils/{schema.js => schema.ts} (73%) diff --git a/packages/client/src/sdk.js b/packages/client/src/sdk.js index 40d066f2ee..40f35b2ba7 100644 --- a/packages/client/src/sdk.js +++ b/packages/client/src/sdk.js @@ -29,7 +29,7 @@ import { ActionTypes } from "./constants" import { fetchDatasourceSchema, fetchDatasourceDefinition, -} from "./utils/schema.js" +} from "./utils/schema.ts" import { getAPIKey } from "./utils/api.js" import { enrichButtonActions } from "./utils/buttonActions.js" import { processStringSync, makePropSafe } from "@budibase/string-templates" diff --git a/packages/client/src/utils/schema.js b/packages/client/src/utils/schema.ts similarity index 73% rename from packages/client/src/utils/schema.js rename to packages/client/src/utils/schema.ts index 60800afc53..53b31b5495 100644 --- a/packages/client/src/utils/schema.js +++ b/packages/client/src/utils/schema.ts @@ -1,13 +1,5 @@ import { API } from "api" -import TableFetch from "@budibase/frontend-core/src/fetch/TableFetch" -import ViewFetch from "@budibase/frontend-core/src/fetch/ViewFetch" -import QueryFetch from "@budibase/frontend-core/src/fetch/QueryFetch" -import RelationshipFetch from "@budibase/frontend-core/src/fetch/RelationshipFetch" -import NestedProviderFetch from "@budibase/frontend-core/src/fetch/NestedProviderFetch" -import FieldFetch from "@budibase/frontend-core/src/fetch/FieldFetch" -import JSONArrayFetch from "@budibase/frontend-core/src/fetch/JSONArrayFetch" -import ViewV2Fetch from "@budibase/frontend-core/src/fetch/ViewV2Fetch" -import QueryArrayFetch from "@budibase/frontend-core/src/fetch/QueryArrayFetch" +import { DataFetchMap } from "@budibase/frontend-core" /** * Constructs a fetch instance for a given datasource. @@ -16,18 +8,8 @@ import QueryArrayFetch from "@budibase/frontend-core/src/fetch/QueryArrayFetch" * @param datasource the datasource * @returns */ -const getDatasourceFetchInstance = datasource => { - const handler = { - table: TableFetch, - view: ViewFetch, - viewV2: ViewV2Fetch, - query: QueryFetch, - link: RelationshipFetch, - provider: NestedProviderFetch, - field: FieldFetch, - jsonarray: JSONArrayFetch, - queryarray: QueryArrayFetch, - }[datasource?.type] +const getDatasourceFetchInstance = (datasource: { type: string }) => { + const handler = DataFetchMap[datasource?.type] if (!handler) { return null } From e25f26d28d9d41bb2e46f7e0823e87b19c3c3986 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 15:04:56 +0100 Subject: [PATCH 25/34] Reuse type --- packages/frontend-core/src/fetch/index.ts | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/frontend-core/src/fetch/index.ts b/packages/frontend-core/src/fetch/index.ts index e343b351bc..21832e3ede 100644 --- a/packages/frontend-core/src/fetch/index.ts +++ b/packages/frontend-core/src/fetch/index.ts @@ -12,6 +12,8 @@ import CustomFetch from "./CustomFetch" import QueryArrayFetch from "./QueryArrayFetch" import { APIClient } from "../api/types" +export type DataFetchType = keyof typeof DataFetchMap + export const DataFetchMap = { table: TableFetch, view: ViewFetch, @@ -31,8 +33,7 @@ export const DataFetchMap = { // Constructs a new fetch model for a certain datasource export const fetchData = ({ API, datasource, options }: any) => { - const Fetch = - DataFetchMap[datasource?.type as keyof typeof DataFetchMap] || TableFetch + const Fetch = DataFetchMap[datasource?.type as DataFetchType] || TableFetch const fetch = new Fetch({ API, datasource, ...options }) // Initially fetch data but don't bother waiting for the result @@ -43,18 +44,14 @@ export const fetchData = ({ API, datasource, options }: any) => { // Creates an empty fetch instance with no datasource configured, so no data // will initially be loaded -const createEmptyFetchInstance = < - TDatasource extends { - type: keyof typeof DataFetchMap - } ->({ +const createEmptyFetchInstance = ({ API, datasource, }: { API: APIClient datasource: TDatasource }) => { - const handler = DataFetchMap[datasource?.type as keyof typeof DataFetchMap] + const handler = DataFetchMap[datasource?.type as DataFetchType] if (!handler) { return null } @@ -63,9 +60,7 @@ const createEmptyFetchInstance = < // Fetches the definition of any type of datasource export const getDatasourceDefinition = async < - TDatasource extends { - type: keyof typeof DataFetchMap - } + TDatasource extends { type: DataFetchType } >({ API, datasource, @@ -79,9 +74,7 @@ export const getDatasourceDefinition = async < // Fetches the schema of any type of datasource export const getDatasourceSchema = < - TDatasource extends { - type: keyof typeof DataFetchMap - } + TDatasource extends { type: DataFetchType } >({ API, datasource, From 4f06592685522e7d1d58af1a43e7549b24e9002a Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 15:23:20 +0100 Subject: [PATCH 26/34] Use trimmed and typed datasources --- packages/frontend-core/src/fetch/DataFetch.ts | 3 ++- packages/frontend-core/src/fetch/FieldFetch.ts | 9 ++++++--- packages/frontend-core/src/fetch/GroupUserFetch.ts | 2 ++ packages/frontend-core/src/fetch/JSONArrayFetch.ts | 2 +- .../frontend-core/src/fetch/NestedProviderFetch.ts | 1 + packages/frontend-core/src/fetch/QueryArrayFetch.ts | 2 +- packages/frontend-core/src/fetch/QueryFetch.ts | 1 + .../frontend-core/src/fetch/RelationshipFetch.ts | 1 + packages/frontend-core/src/fetch/TableFetch.ts | 9 +++++++-- packages/frontend-core/src/fetch/UserFetch.ts | 8 ++++++-- packages/frontend-core/src/fetch/ViewFetch.ts | 11 +++++++++-- packages/frontend-core/src/fetch/ViewV2Fetch.ts | 12 ++++++++++-- packages/frontend-core/src/fetch/index.ts | 8 ++++++-- packages/frontend-core/src/index.ts | 1 + 14 files changed, 54 insertions(+), 16 deletions(-) diff --git a/packages/frontend-core/src/fetch/DataFetch.ts b/packages/frontend-core/src/fetch/DataFetch.ts index 0079fec057..8f475339b4 100644 --- a/packages/frontend-core/src/fetch/DataFetch.ts +++ b/packages/frontend-core/src/fetch/DataFetch.ts @@ -13,6 +13,7 @@ import { UISearchFilter, } from "@budibase/types" import { APIClient } from "../api/types" +import { DataFetchType } from "." const { buildQuery, limit: queryLimit, runQuery, sort } = QueryUtils @@ -59,7 +60,7 @@ export interface DataFetchParams< * For other types of datasource, this class is overridden and extended. */ export default abstract class DataFetch< - TDatasource extends {}, + TDatasource extends { type: DataFetchType }, TDefinition extends { schema?: Record | null primaryDisplay?: string diff --git a/packages/frontend-core/src/fetch/FieldFetch.ts b/packages/frontend-core/src/fetch/FieldFetch.ts index ac1e683c51..694443a5dc 100644 --- a/packages/frontend-core/src/fetch/FieldFetch.ts +++ b/packages/frontend-core/src/fetch/FieldFetch.ts @@ -1,7 +1,10 @@ import { Row } from "@budibase/types" import DataFetch from "./DataFetch" -export interface FieldDatasource { +type Types = "field" | "queryarray" | "jsonarray" + +export interface FieldDatasource { + type: TType tableId: string fieldType: "attachment" | "array" value: string[] | Row[] @@ -15,8 +18,8 @@ function isArrayOfStrings(value: string[] | Row[]): value is string[] { return Array.isArray(value) && !!value[0] && typeof value[0] !== "object" } -export default class FieldFetch extends DataFetch< - FieldDatasource, +export default class FieldFetch extends DataFetch< + FieldDatasource, FieldDefinition > { async getDefinition(): Promise { diff --git a/packages/frontend-core/src/fetch/GroupUserFetch.ts b/packages/frontend-core/src/fetch/GroupUserFetch.ts index a14623bfb0..e07e5331d4 100644 --- a/packages/frontend-core/src/fetch/GroupUserFetch.ts +++ b/packages/frontend-core/src/fetch/GroupUserFetch.ts @@ -8,6 +8,7 @@ interface GroupUserQuery { } interface GroupUserDatasource { + type: "groupUser" tableId: TableNames.USERS } @@ -20,6 +21,7 @@ export default class GroupUserFetch extends DataFetch< super({ ...opts, datasource: { + type: "groupUser", tableId: TableNames.USERS, }, }) diff --git a/packages/frontend-core/src/fetch/JSONArrayFetch.ts b/packages/frontend-core/src/fetch/JSONArrayFetch.ts index cae9a1e521..d746c923f8 100644 --- a/packages/frontend-core/src/fetch/JSONArrayFetch.ts +++ b/packages/frontend-core/src/fetch/JSONArrayFetch.ts @@ -1,7 +1,7 @@ import FieldFetch from "./FieldFetch" import { getJSONArrayDatasourceSchema } from "../utils/json" -export default class JSONArrayFetch extends FieldFetch { +export default class JSONArrayFetch extends FieldFetch<"jsonarray"> { async getDefinition() { const { datasource } = this.options diff --git a/packages/frontend-core/src/fetch/NestedProviderFetch.ts b/packages/frontend-core/src/fetch/NestedProviderFetch.ts index 666340610f..af121fcef8 100644 --- a/packages/frontend-core/src/fetch/NestedProviderFetch.ts +++ b/packages/frontend-core/src/fetch/NestedProviderFetch.ts @@ -2,6 +2,7 @@ import { Row, TableSchema } from "@budibase/types" import DataFetch from "./DataFetch" interface NestedProviderDatasource { + type: "provider" value?: { schema: TableSchema primaryDisplay: string diff --git a/packages/frontend-core/src/fetch/QueryArrayFetch.ts b/packages/frontend-core/src/fetch/QueryArrayFetch.ts index 9142000fe6..7f4d34aaa6 100644 --- a/packages/frontend-core/src/fetch/QueryArrayFetch.ts +++ b/packages/frontend-core/src/fetch/QueryArrayFetch.ts @@ -4,7 +4,7 @@ import { generateQueryArraySchemas, } from "../utils/json" -export default class QueryArrayFetch extends FieldFetch { +export default class QueryArrayFetch extends FieldFetch<"queryarray"> { async getDefinition() { const { datasource } = this.options diff --git a/packages/frontend-core/src/fetch/QueryFetch.ts b/packages/frontend-core/src/fetch/QueryFetch.ts index 0754edd267..09dde86cbd 100644 --- a/packages/frontend-core/src/fetch/QueryFetch.ts +++ b/packages/frontend-core/src/fetch/QueryFetch.ts @@ -4,6 +4,7 @@ import { ExecuteQueryRequest, Query } from "@budibase/types" import { get } from "svelte/store" interface QueryDatasource { + type: "query" _id: string fields: Record & { pagination?: { diff --git a/packages/frontend-core/src/fetch/RelationshipFetch.ts b/packages/frontend-core/src/fetch/RelationshipFetch.ts index f853a753cd..89a85ab0e4 100644 --- a/packages/frontend-core/src/fetch/RelationshipFetch.ts +++ b/packages/frontend-core/src/fetch/RelationshipFetch.ts @@ -2,6 +2,7 @@ import { Table } from "@budibase/types" import DataFetch from "./DataFetch" interface RelationshipDatasource { + type: "link" tableId: string rowId: string rowTableId: string diff --git a/packages/frontend-core/src/fetch/TableFetch.ts b/packages/frontend-core/src/fetch/TableFetch.ts index f5927262cb..67cac6b6a7 100644 --- a/packages/frontend-core/src/fetch/TableFetch.ts +++ b/packages/frontend-core/src/fetch/TableFetch.ts @@ -1,8 +1,13 @@ import { get } from "svelte/store" import DataFetch from "./DataFetch" -import { SortOrder, Table, UITable } from "@budibase/types" +import { SortOrder, Table } from "@budibase/types" -export default class TableFetch extends DataFetch { +interface TableDatasource { + type: "table" + tableId: string +} + +export default class TableFetch extends DataFetch { async determineFeatureFlags() { return { supportsSearch: true, diff --git a/packages/frontend-core/src/fetch/UserFetch.ts b/packages/frontend-core/src/fetch/UserFetch.ts index 656cd840fe..54147fbccf 100644 --- a/packages/frontend-core/src/fetch/UserFetch.ts +++ b/packages/frontend-core/src/fetch/UserFetch.ts @@ -14,18 +14,22 @@ interface UserFetchQuery { } interface UserDatasource { - tableId: string + type: "user" + tableId: TableNames.USERS } +interface UserDefinition {} + export default class UserFetch extends DataFetch< UserDatasource, - {}, + UserDefinition, UserFetchQuery > { constructor(opts: DataFetchParams) { super({ ...opts, datasource: { + type: "user", tableId: TableNames.USERS, }, }) diff --git a/packages/frontend-core/src/fetch/ViewFetch.ts b/packages/frontend-core/src/fetch/ViewFetch.ts index b6830e7118..c075d80ce0 100644 --- a/packages/frontend-core/src/fetch/ViewFetch.ts +++ b/packages/frontend-core/src/fetch/ViewFetch.ts @@ -1,7 +1,14 @@ -import { Table, View } from "@budibase/types" +import { Table } from "@budibase/types" import DataFetch from "./DataFetch" -type ViewV1 = View & { name: string } +type ViewV1 = { + type: "view" + name: string + tableId: string + calculation: string + field: string + groupBy: string +} export default class ViewFetch extends DataFetch { async getDefinition() { diff --git a/packages/frontend-core/src/fetch/ViewV2Fetch.ts b/packages/frontend-core/src/fetch/ViewV2Fetch.ts index cdd3bab6ed..aa5fbd60a2 100644 --- a/packages/frontend-core/src/fetch/ViewV2Fetch.ts +++ b/packages/frontend-core/src/fetch/ViewV2Fetch.ts @@ -1,9 +1,17 @@ -import { SortOrder, UIView, ViewV2, ViewV2Type } from "@budibase/types" +import { SortOrder, ViewV2Enriched, ViewV2Type } from "@budibase/types" import DataFetch from "./DataFetch" import { get } from "svelte/store" import { helpers } from "@budibase/shared-core" -export default class ViewV2Fetch extends DataFetch { +interface ViewDatasource { + type: "viewV2" + id: string +} + +export default class ViewV2Fetch extends DataFetch< + ViewDatasource, + ViewV2Enriched +> { async determineFeatureFlags() { return { supportsSearch: true, diff --git a/packages/frontend-core/src/fetch/index.ts b/packages/frontend-core/src/fetch/index.ts index 21832e3ede..d80aa10df6 100644 --- a/packages/frontend-core/src/fetch/index.ts +++ b/packages/frontend-core/src/fetch/index.ts @@ -26,7 +26,7 @@ export const DataFetchMap = { // Client specific datasource types provider: NestedProviderFetch, - field: FieldFetch, + field: FieldFetch<"field">, jsonarray: JSONArrayFetch, queryarray: QueryArrayFetch, } @@ -55,7 +55,11 @@ const createEmptyFetchInstance = ({ if (!handler) { return null } - return new handler({ API, datasource: null as any, query: null as any }) + return new handler({ + API, + datasource: null as never, + query: null as any, + }) } // Fetches the definition of any type of datasource diff --git a/packages/frontend-core/src/index.ts b/packages/frontend-core/src/index.ts index 5b24a9ac50..c0baa63ab6 100644 --- a/packages/frontend-core/src/index.ts +++ b/packages/frontend-core/src/index.ts @@ -1,5 +1,6 @@ export { createAPIClient } from "./api" export { fetchData, DataFetchMap } from "./fetch" +export type { DataFetchType } from "./fetch" export * as Constants from "./constants" export * from "./stores" export * from "./utils" From eb73370460f9b3fb98303f086bf21e29a1ae9bc7 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 9 Jan 2025 15:35:16 +0100 Subject: [PATCH 27/34] Fix types --- packages/client/src/utils/schema.ts | 56 +++++++++++++------ packages/frontend-core/src/fetch/DataFetch.ts | 2 +- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/packages/client/src/utils/schema.ts b/packages/client/src/utils/schema.ts index 53b31b5495..5400d62087 100644 --- a/packages/client/src/utils/schema.ts +++ b/packages/client/src/utils/schema.ts @@ -1,5 +1,5 @@ import { API } from "api" -import { DataFetchMap } from "@budibase/frontend-core" +import { DataFetchMap, DataFetchType } from "@budibase/frontend-core" /** * Constructs a fetch instance for a given datasource. @@ -8,12 +8,20 @@ import { DataFetchMap } from "@budibase/frontend-core" * @param datasource the datasource * @returns */ -const getDatasourceFetchInstance = (datasource: { type: string }) => { +const getDatasourceFetchInstance = < + TDatasource extends { type: DataFetchType } +>( + datasource: TDatasource +) => { const handler = DataFetchMap[datasource?.type] if (!handler) { return null } - return new handler({ API, datasource }) + return new handler({ + API, + datasource: datasource as never, + query: null as any, + }) } /** @@ -21,21 +29,23 @@ const getDatasourceFetchInstance = (datasource: { type: string }) => { * @param datasource the datasource to fetch the schema for * @param options options for enriching the schema */ -export const fetchDatasourceSchema = async ( - datasource, +export const fetchDatasourceSchema = async < + TDatasource extends { type: DataFetchType } +>( + datasource: TDatasource, options = { enrichRelationships: false, formSchema: false } ) => { const instance = getDatasourceFetchInstance(datasource) - const definition = await instance?.getDefinition(datasource) - if (!definition) { + const definition = await instance?.getDefinition() + if (!instance || !definition) { return null } // Get the normal schema as long as we aren't wanting a form schema - let schema + let schema: any if (datasource?.type !== "query" || !options?.formSchema) { - schema = instance.getSchema(definition) - } else if (definition.parameters?.length) { + schema = instance.getSchema(definition as any) + } else if ("parameters" in definition && definition.parameters?.length) { schema = {} definition.parameters.forEach(param => { schema[param.name] = { ...param, type: "string" } @@ -55,7 +65,12 @@ export const fetchDatasourceSchema = async ( } // Enrich schema with relationships if required - if (definition?.sql && options?.enrichRelationships) { + if ( + definition && + "sql" in definition && + definition.sql && + options?.enrichRelationships + ) { const relationshipAdditions = await getRelationshipSchemaAdditions(schema) schema = { ...schema, @@ -71,20 +86,26 @@ export const fetchDatasourceSchema = async ( * Fetches the definition of any kind of datasource. * @param datasource the datasource to fetch the schema for */ -export const fetchDatasourceDefinition = async datasource => { +export const fetchDatasourceDefinition = async < + TDatasource extends { type: DataFetchType } +>( + datasource: TDatasource +) => { const instance = getDatasourceFetchInstance(datasource) - return await instance?.getDefinition(datasource) + return await instance?.getDefinition() } /** * Fetches the schema of relationship fields for a SQL table schema * @param schema the schema to enrich */ -export const getRelationshipSchemaAdditions = async schema => { +export const getRelationshipSchemaAdditions = async ( + schema: Record +) => { if (!schema) { return null } - let relationshipAdditions = {} + let relationshipAdditions: Record = {} for (let fieldKey of Object.keys(schema)) { const fieldSchema = schema[fieldKey] if (fieldSchema?.type === "link") { @@ -92,7 +113,10 @@ export const getRelationshipSchemaAdditions = async schema => { type: "table", tableId: fieldSchema?.tableId, }) - Object.keys(linkSchema || {}).forEach(linkKey => { + if (!linkSchema) { + continue + } + Object.keys(linkSchema).forEach(linkKey => { relationshipAdditions[`${fieldKey}.${linkKey}`] = { type: linkSchema[linkKey].type, externalType: linkSchema[linkKey].externalType, diff --git a/packages/frontend-core/src/fetch/DataFetch.ts b/packages/frontend-core/src/fetch/DataFetch.ts index 8f475339b4..b10a8b0a69 100644 --- a/packages/frontend-core/src/fetch/DataFetch.ts +++ b/packages/frontend-core/src/fetch/DataFetch.ts @@ -369,7 +369,7 @@ export default abstract class DataFetch< * @param schema the datasource schema * @return {object} the enriched datasource schema */ - private enrichSchema(schema: TableSchema): TableSchema { + enrichSchema(schema: TableSchema): TableSchema { // Check for any JSON fields so we can add any top level properties let jsonAdditions: Record = {} for (const fieldKey of Object.keys(schema)) { From be41a2ae6c2c087deea46c2d8b1861c7448afec2 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 10 Jan 2025 10:07:45 +0100 Subject: [PATCH 28/34] Add type to customDatasource --- packages/frontend-core/src/fetch/CustomFetch.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/frontend-core/src/fetch/CustomFetch.ts b/packages/frontend-core/src/fetch/CustomFetch.ts index afd3d18ba9..dfd29c4a02 100644 --- a/packages/frontend-core/src/fetch/CustomFetch.ts +++ b/packages/frontend-core/src/fetch/CustomFetch.ts @@ -1,6 +1,7 @@ import DataFetch from "./DataFetch" interface CustomDatasource { + type: "custom" data: any } From 616e89716c8ea89bcd1b34b8e16a72463b089924 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 10 Jan 2025 12:47:49 +0100 Subject: [PATCH 29/34] Remove unneeded extension --- packages/client/src/sdk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/sdk.js b/packages/client/src/sdk.js index 40f35b2ba7..68d75d2806 100644 --- a/packages/client/src/sdk.js +++ b/packages/client/src/sdk.js @@ -29,7 +29,7 @@ import { ActionTypes } from "./constants" import { fetchDatasourceSchema, fetchDatasourceDefinition, -} from "./utils/schema.ts" +} from "./utils/schema" import { getAPIKey } from "./utils/api.js" import { enrichButtonActions } from "./utils/buttonActions.js" import { processStringSync, makePropSafe } from "@budibase/string-templates" From b54eb876d81007c37b918e33f61ded9db8c4ef1f Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 10 Jan 2025 12:50:08 +0100 Subject: [PATCH 30/34] Renames --- packages/frontend-core/src/fetch/ViewFetch.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend-core/src/fetch/ViewFetch.ts b/packages/frontend-core/src/fetch/ViewFetch.ts index c075d80ce0..df00b9bbfc 100644 --- a/packages/frontend-core/src/fetch/ViewFetch.ts +++ b/packages/frontend-core/src/fetch/ViewFetch.ts @@ -1,7 +1,7 @@ import { Table } from "@budibase/types" import DataFetch from "./DataFetch" -type ViewV1 = { +type ViewV1Datasource = { type: "view" name: string tableId: string @@ -10,7 +10,7 @@ type ViewV1 = { groupBy: string } -export default class ViewFetch extends DataFetch { +export default class ViewFetch extends DataFetch { async getDefinition() { const { datasource } = this.options From ed6adbae08cb76f4278084b6d84fc9dcf0f65d45 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Fri, 10 Jan 2025 11:52:48 +0000 Subject: [PATCH 31/34] Bump version to 3.2.38 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 647c9f202d..ff69a18459 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.37", + "version": "3.2.38", "npmClient": "yarn", "concurrency": 20, "command": { From 6ecb01ae830d7ea94fe14b4e2696cfbb29f82cb1 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 10 Jan 2025 14:47:09 +0100 Subject: [PATCH 32/34] Fix close modal on grid+modal generation --- packages/frontend-core/src/utils/utils.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/frontend-core/src/utils/utils.js b/packages/frontend-core/src/utils/utils.js index c424aea5b2..55603b0129 100644 --- a/packages/frontend-core/src/utils/utils.js +++ b/packages/frontend-core/src/utils/utils.js @@ -209,6 +209,9 @@ export const buildFormBlockButtonConfig = props => { { "##eventHandlerType": "Close Side Panel", }, + { + "##eventHandlerType": "Close Modal", + }, ...(actionUrl ? [ From 23025f46396b828e27c356ae21c7bddb473c90c9 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 10 Jan 2025 15:19:55 +0100 Subject: [PATCH 33/34] Clean --- packages/client/src/api/api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/api/api.ts b/packages/client/src/api/api.ts index 93f59f6e9a..b944f7bd7c 100644 --- a/packages/client/src/api/api.ts +++ b/packages/client/src/api/api.ts @@ -4,7 +4,7 @@ import { notificationStore, devToolsEnabled, devToolsStore, -} from "../stores/index.js" +} from "../stores/index" import { get } from "svelte/store" export const API = createAPIClient({ From 9d0e3a17222f303e1f3a952e7c5e298d7187f070 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 10 Jan 2025 15:22:34 +0100 Subject: [PATCH 34/34] Remove unnecessary extensions --- packages/client/src/api/index.js | 4 ++-- packages/client/src/stores/index.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/src/api/index.js b/packages/client/src/api/index.js index a63e19bfbb..3c53045cfd 100644 --- a/packages/client/src/api/index.js +++ b/packages/client/src/api/index.js @@ -1,5 +1,5 @@ -import { API } from "./api.ts" -import { patchAPI } from "./patches.js" +import { API } from "./api" +import { patchAPI } from "./patches" // Certain endpoints which return rows need patched so that they transform // and enrich the row docs, so that they can be correctly handled by the diff --git a/packages/client/src/stores/index.js b/packages/client/src/stores/index.js index e099434b3d..f2b80ed732 100644 --- a/packages/client/src/stores/index.js +++ b/packages/client/src/stores/index.js @@ -1,6 +1,6 @@ export { authStore } from "./auth" export { appStore } from "./app" -export { notificationStore } from "./notification.ts" +export { notificationStore } from "./notification" export { routeStore } from "./routes" export { screenStore } from "./screens" export { builderStore } from "./builder"