From 342503700a563cd12364c477d84d88f78e050803 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 30 Dec 2024 09:06:12 +0000 Subject: [PATCH 1/4] convert more stores to ts --- .../src/stores/builder/{app.js => app.ts} | 73 ++++++++++++++++--- 1 file changed, 62 insertions(+), 11 deletions(-) rename packages/builder/src/stores/builder/{app.js => app.ts} (55%) diff --git a/packages/builder/src/stores/builder/app.js b/packages/builder/src/stores/builder/app.ts similarity index 55% rename from packages/builder/src/stores/builder/app.js rename to packages/builder/src/stores/builder/app.ts index 3b9e4e0b3c..f98e79eff1 100644 --- a/packages/builder/src/stores/builder/app.js +++ b/packages/builder/src/stores/builder/app.ts @@ -1,7 +1,54 @@ import { API } from "api" import { BudiStore } from "../BudiStore" +import { + App, + AppFeatures, + AppIcon, + AutomationSettings, + Plugin, +} from "@budibase/types" -export const INITIAL_APP_META_STATE = { +interface ClientFeatures { + spectrumThemes: boolean + intelligentLoading: boolean + deviceAwareness: boolean + state: boolean + rowSelection: boolean + customThemes: boolean + devicePreview: boolean + messagePassing: boolean + continueIfAction: boolean + showNotificationAction: boolean + sidePanel: boolean +} + +interface TypeSupportPresets { + [key: string]: any +} + +interface AppMetaState { + appId: string + name: string + url: string + libraries: string[] + clientFeatures: ClientFeatures + typeSupportPresets: TypeSupportPresets + features: AppFeatures + clientLibPath: string + hasLock: boolean + appInstance: { _id: string } | null + initialised: boolean + hasAppPackage: boolean + usedPlugins: Plugin[] | null + automations: AutomationSettings + routes: { [key: string]: any } + version?: string + revertableVersion?: string + upgradableVersion?: string + icon?: AppIcon +} + +export const INITIAL_APP_META_STATE: AppMetaState = { appId: "", name: "", url: "", @@ -34,23 +81,27 @@ export const INITIAL_APP_META_STATE = { routes: {}, } -export class AppMetaStore extends BudiStore { +export class AppMetaStore extends BudiStore { constructor() { super(INITIAL_APP_META_STATE) } - reset() { + reset(): void { this.store.set({ ...INITIAL_APP_META_STATE }) } - syncAppPackage(pkg) { + syncAppPackage(pkg: { + application: App + clientLibPath: string + hasLock: boolean + }): void { const { application: app, clientLibPath, hasLock } = pkg this.update(state => ({ ...state, name: app.name, appId: app.appId, - url: app.url, + url: app.url || "", hasLock, clientLibPath, libraries: app.componentLibraries, @@ -58,8 +109,8 @@ export class AppMetaStore extends BudiStore { appInstance: app.instance, revertableVersion: app.revertableVersion, upgradableVersion: app.upgradableVersion, - usedPlugins: app.usedPlugins, - icon: app.icon || {}, + usedPlugins: app.usedPlugins || null, + icon: app.icon, features: { ...INITIAL_APP_META_STATE.features, ...app.features, @@ -70,7 +121,7 @@ export class AppMetaStore extends BudiStore { })) } - syncClientFeatures(features) { + syncClientFeatures(features: Partial): void { this.update(state => ({ ...state, clientFeatures: { @@ -80,14 +131,14 @@ export class AppMetaStore extends BudiStore { })) } - syncClientTypeSupportPresets(typeSupportPresets) { + syncClientTypeSupportPresets(typeSupportPresets: TypeSupportPresets): void { this.update(state => ({ ...state, typeSupportPresets, })) } - async syncAppRoutes() { + async syncAppRoutes(): Promise { const resp = await API.fetchAppRoutes() this.update(state => ({ ...state, @@ -96,7 +147,7 @@ export class AppMetaStore extends BudiStore { } // Returned from socket - syncMetadata(metadata) { + syncMetadata(metadata: { name: string; url: string; icon?: AppIcon }): void { const { name, url, icon } = metadata this.update(state => ({ ...state, From 6e6c25e15e988dc9d574158aeaf5e3e1dba45676 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 30 Dec 2024 09:08:51 +0000 Subject: [PATCH 2/4] migrate builder.js to ts --- .../stores/builder/{builder.js => builder.ts} | 62 ++++++++++++------- 1 file changed, 40 insertions(+), 22 deletions(-) rename packages/builder/src/stores/builder/{builder.js => builder.ts} (67%) diff --git a/packages/builder/src/stores/builder/builder.js b/packages/builder/src/stores/builder/builder.ts similarity index 67% rename from packages/builder/src/stores/builder/builder.js rename to packages/builder/src/stores/builder/builder.ts index 9b5a847680..472abe7c66 100644 --- a/packages/builder/src/stores/builder/builder.js +++ b/packages/builder/src/stores/builder/builder.ts @@ -3,8 +3,25 @@ import { createBuilderWebsocket } from "./websocket.js" import { BuilderSocketEvent } from "@budibase/shared-core" import { BudiStore } from "../BudiStore.js" import { TOUR_KEYS } from "components/portal/onboarding/tours.js" +import { App } from "@budibase/types" -export const INITIAL_BUILDER_STATE = { +interface BuilderState { + previousTopNavPath: Record + highlightedSetting: { + key: string + type: "info" | string + } | null + propertyFocus: string | null + builderSidePanel: boolean + onboarding: boolean + tourNodes: Record | null + tourKey: string | null + tourStepKey: string | null + hoveredComponentId: string | null + websocket?: ReturnType +} + +export const INITIAL_BUILDER_STATE: BuilderState = { previousTopNavPath: {}, highlightedSetting: null, propertyFocus: null, @@ -16,7 +33,9 @@ export const INITIAL_BUILDER_STATE = { hoveredComponentId: null, } -export class BuilderStore extends BudiStore { +export class BuilderStore extends BudiStore { + websocket?: ReturnType + constructor() { super({ ...INITIAL_BUILDER_STATE }) @@ -32,11 +51,9 @@ export class BuilderStore extends BudiStore { this.registerTourNode = this.registerTourNode.bind(this) this.destroyTourNode = this.destroyTourNode.bind(this) this.startBuilderOnboarding = this.startBuilderOnboarding.bind(this) - - this.websocket } - init(app) { + init(app: App): void { if (!app?.appId) { console.error("BuilderStore: No appId supplied for websocket") return @@ -46,45 +63,46 @@ export class BuilderStore extends BudiStore { } } - refresh() { - this.store.set(this.store.get()) + refresh(): void { + const currentState = get(this.store) + this.store.set(currentState) } - reset() { + reset(): void { this.store.set({ ...INITIAL_BUILDER_STATE }) this.websocket?.disconnect() - this.websocket = null + this.websocket = undefined } - highlightSetting(key, type) { + highlightSetting(key?: string, type?: string): void { this.update(state => ({ ...state, highlightedSetting: key ? { key, type: type || "info" } : null, })) } - propertyFocus(key) { + propertyFocus(key: string | null): void { this.update(state => ({ ...state, propertyFocus: key, })) } - showBuilderSidePanel() { + showBuilderSidePanel(): void { this.update(state => ({ ...state, builderSidePanel: true, })) } - hideBuilderSidePanel() { + hideBuilderSidePanel(): void { this.update(state => ({ ...state, builderSidePanel: false, })) } - setPreviousTopNavPath(route, url) { + setPreviousTopNavPath(route: string, url: string): void { this.update(state => ({ ...state, previousTopNavPath: { @@ -94,13 +112,13 @@ export class BuilderStore extends BudiStore { })) } - selectResource(id) { - this.websocket.emit(BuilderSocketEvent.SelectResource, { + selectResource(id: string): void { + this.websocket?.emit(BuilderSocketEvent.SelectResource, { resourceId: id, }) } - registerTourNode(tourStepKey, node) { + registerTourNode(tourStepKey: string, node: HTMLElement): void { this.update(state => { const update = { ...state, @@ -113,7 +131,7 @@ export class BuilderStore extends BudiStore { }) } - destroyTourNode(tourStepKey) { + destroyTourNode(tourStepKey: string): void { const store = get(this.store) if (store.tourNodes?.[tourStepKey]) { const nodes = { ...store.tourNodes } @@ -125,7 +143,7 @@ export class BuilderStore extends BudiStore { } } - startBuilderOnboarding() { + startBuilderOnboarding(): void { this.update(state => ({ ...state, onboarding: true, @@ -133,19 +151,19 @@ export class BuilderStore extends BudiStore { })) } - endBuilderOnboarding() { + endBuilderOnboarding(): void { this.update(state => ({ ...state, onboarding: false, })) } - setTour(tourKey) { + setTour(tourKey?: string | null): void { this.update(state => ({ ...state, tourStepKey: null, tourNodes: null, - tourKey: tourKey, + tourKey: tourKey || null, })) } } From a94adced72589e1f66249b6afb9d0416613bd674 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 30 Dec 2024 09:27:22 +0000 Subject: [PATCH 3/4] contextmenu and deployment --- .../builder/src/stores/builder/contextMenu.js | 28 ----------- .../builder/src/stores/builder/contextMenu.ts | 46 +++++++++++++++++++ .../{deployments.js => deployments.ts} | 7 +-- 3 files changed, 50 insertions(+), 31 deletions(-) delete mode 100644 packages/builder/src/stores/builder/contextMenu.js create mode 100644 packages/builder/src/stores/builder/contextMenu.ts rename packages/builder/src/stores/builder/{deployments.js => deployments.ts} (62%) diff --git a/packages/builder/src/stores/builder/contextMenu.js b/packages/builder/src/stores/builder/contextMenu.js deleted file mode 100644 index 2b8808570e..0000000000 --- a/packages/builder/src/stores/builder/contextMenu.js +++ /dev/null @@ -1,28 +0,0 @@ -import { writable } from "svelte/store" - -export const INITIAL_CONTEXT_MENU_STATE = { - id: null, - items: [], - position: { x: 0, y: 0 }, - visible: false, -} - -export function createViewsStore() { - const store = writable({ ...INITIAL_CONTEXT_MENU_STATE }) - - const open = (id, items, position) => { - store.set({ id, items, position, visible: true }) - } - - const close = () => { - store.set({ ...INITIAL_CONTEXT_MENU_STATE }) - } - - return { - subscribe: store.subscribe, - open, - close, - } -} - -export const contextMenuStore = createViewsStore() diff --git a/packages/builder/src/stores/builder/contextMenu.ts b/packages/builder/src/stores/builder/contextMenu.ts new file mode 100644 index 0000000000..dc205c7fea --- /dev/null +++ b/packages/builder/src/stores/builder/contextMenu.ts @@ -0,0 +1,46 @@ +import { writable } from "svelte/store" + +interface Position { + x: number + y: number +} + +interface MenuItem { + label: string + icon?: string + action: () => void +} + +interface ContextMenuState { + id: string | null + items: MenuItem[] + position: Position + visible: boolean +} + +export const INITIAL_CONTEXT_MENU_STATE: ContextMenuState = { + id: null, + items: [], + position: { x: 0, y: 0 }, + visible: false, +} + +export function createViewsStore() { + const store = writable({ ...INITIAL_CONTEXT_MENU_STATE }) + + const open = (id: string, items: MenuItem[], position: Position): void => { + store.set({ id, items, position, visible: true }) + } + + const close = (): void => { + store.set({ ...INITIAL_CONTEXT_MENU_STATE }) + } + + return { + subscribe: store.subscribe, + open, + close, + } +} + +export const contextMenuStore = createViewsStore() diff --git a/packages/builder/src/stores/builder/deployments.js b/packages/builder/src/stores/builder/deployments.ts similarity index 62% rename from packages/builder/src/stores/builder/deployments.js rename to packages/builder/src/stores/builder/deployments.ts index dafdb1dabc..130e52bc91 100644 --- a/packages/builder/src/stores/builder/deployments.js +++ b/packages/builder/src/stores/builder/deployments.ts @@ -1,11 +1,12 @@ -import { writable } from "svelte/store" +import { writable, type Writable } from "svelte/store" import { API } from "api" import { notifications } from "@budibase/bbui" +import { DeploymentProgressResponse } from "@budibase/types" export const createDeploymentStore = () => { - let store = writable([]) + let store: Writable = writable([]) - const load = async () => { + const load = async (): Promise => { try { store.set(await API.getAppDeployments()) } catch (err) { From c30c68c289e324d3c111ba60753b07db8013e388 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 30 Dec 2024 12:16:02 +0000 Subject: [PATCH 4/4] socket expects undefined instead of null --- packages/builder/src/stores/builder/builder.ts | 5 +++-- packages/builder/src/stores/builder/tests/builder.test.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/builder/src/stores/builder/builder.ts b/packages/builder/src/stores/builder/builder.ts index 472abe7c66..00f6c5fce7 100644 --- a/packages/builder/src/stores/builder/builder.ts +++ b/packages/builder/src/stores/builder/builder.ts @@ -1,5 +1,6 @@ import { get } from "svelte/store" import { createBuilderWebsocket } from "./websocket.js" +import { Socket } from "socket.io-client" import { BuilderSocketEvent } from "@budibase/shared-core" import { BudiStore } from "../BudiStore.js" import { TOUR_KEYS } from "components/portal/onboarding/tours.js" @@ -18,7 +19,7 @@ interface BuilderState { tourKey: string | null tourStepKey: string | null hoveredComponentId: string | null - websocket?: ReturnType + websocket?: Socket } export const INITIAL_BUILDER_STATE: BuilderState = { @@ -34,7 +35,7 @@ export const INITIAL_BUILDER_STATE: BuilderState = { } export class BuilderStore extends BudiStore { - websocket?: ReturnType + websocket?: Socket constructor() { super({ ...INITIAL_BUILDER_STATE }) diff --git a/packages/builder/src/stores/builder/tests/builder.test.js b/packages/builder/src/stores/builder/tests/builder.test.js index e6f52689aa..f3c42dae72 100644 --- a/packages/builder/src/stores/builder/tests/builder.test.js +++ b/packages/builder/src/stores/builder/tests/builder.test.js @@ -65,7 +65,7 @@ describe("Builder store", () => { ctx.test.builderStore.reset() expect(disconnected).toBe(true) expect(ctx.test.store).toStrictEqual(INITIAL_BUILDER_STATE) - expect(ctx.test.builderStore.websocket).toBeNull() + expect(ctx.test.builderStore.websocket).toBeUndefined() }) it("Attempt to emit a resource select event to the websocket on select", ctx => {