From f2440f3727a76e81f0ad534d852309b4a559aa0d Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jan 2025 10:34:57 +0000 Subject: [PATCH 1/5] convert roles stores to typescript --- packages/builder/src/stores/builder/roles.js | 88 ---------------- packages/builder/src/stores/builder/roles.ts | 104 +++++++++++++++++++ 2 files changed, 104 insertions(+), 88 deletions(-) delete mode 100644 packages/builder/src/stores/builder/roles.js create mode 100644 packages/builder/src/stores/builder/roles.ts diff --git a/packages/builder/src/stores/builder/roles.js b/packages/builder/src/stores/builder/roles.js deleted file mode 100644 index e718545f14..0000000000 --- a/packages/builder/src/stores/builder/roles.js +++ /dev/null @@ -1,88 +0,0 @@ -import { derived, writable, get } from "svelte/store" -import { API } from "@/api" -import { RoleUtils } from "@budibase/frontend-core" - -export function createRolesStore() { - const store = writable([]) - const enriched = derived(store, $store => { - return $store.map(role => ({ - ...role, - - // Ensure we have new metadata for all roles - uiMetadata: { - displayName: role.uiMetadata?.displayName || role.name, - color: - role.uiMetadata?.color || "var(--spectrum-global-color-magenta-400)", - description: role.uiMetadata?.description || "Custom role", - }, - })) - }) - - function setRoles(roles) { - store.set( - roles.sort((a, b) => { - const priorityA = RoleUtils.getRolePriority(a._id) - const priorityB = RoleUtils.getRolePriority(b._id) - if (priorityA !== priorityB) { - return priorityA > priorityB ? -1 : 1 - } - const nameA = a.uiMetadata?.displayName || a.name - const nameB = b.uiMetadata?.displayName || b.name - return nameA < nameB ? -1 : 1 - }) - ) - } - - const actions = { - fetch: async () => { - const roles = await API.getRoles() - setRoles(roles) - }, - fetchByAppId: async appId => { - const { roles } = await API.getRolesForApp(appId) - setRoles(roles) - }, - delete: async role => { - await API.deleteRole(role._id, role._rev) - await actions.fetch() - }, - save: async role => { - const savedRole = await API.saveRole(role) - await actions.fetch() - return savedRole - }, - replace: (roleId, role) => { - // Handles external updates of roles - if (!roleId) { - return - } - - // Handle deletion - if (!role) { - store.update(state => state.filter(x => x._id !== roleId)) - return - } - - // Add new role - const index = get(store).findIndex(x => x._id === role._id) - if (index === -1) { - store.update(state => [...state, role]) - } - - // Update existing role - else if (role) { - store.update(state => { - state[index] = role - return [...state] - }) - } - }, - } - - return { - subscribe: enriched.subscribe, - ...actions, - } -} - -export const roles = createRolesStore() diff --git a/packages/builder/src/stores/builder/roles.ts b/packages/builder/src/stores/builder/roles.ts new file mode 100644 index 0000000000..ea34fdef53 --- /dev/null +++ b/packages/builder/src/stores/builder/roles.ts @@ -0,0 +1,104 @@ +import { derived, get } from "svelte/store" +import { API } from "@/api" +import { RoleUtils } from "@budibase/frontend-core" +import { BudiStore } from "../BudiStore" +import { Role } from "@budibase/types" + +interface RoleWithMetadata extends Role { + uiMetadata?: { + displayName?: string + color?: string + description?: string + } +} + +export class RoleStore extends BudiStore { + constructor() { + super([]) + } + + enriched = derived(this, $store => { + return $store.map(role => ({ + ...role, + // Ensure we have new metadata for all roles + uiMetadata: { + displayName: role.uiMetadata?.displayName || role.name, + color: + role.uiMetadata?.color || "var(--spectrum-global-color-magenta-400)", + description: role.uiMetadata?.description || "Custom role", + }, + })) + }) + + private setRoles = (roles: RoleWithMetadata[]) => { + this.set( + roles.sort((a, b) => { + // Ensure we have valid IDs for priority comparison + const priorityA = RoleUtils.getRolePriority(a._id) + const priorityB = RoleUtils.getRolePriority(b._id) + if (priorityA !== priorityB) { + return priorityA > priorityB ? -1 : 1 + } + const nameA = a.uiMetadata?.displayName || a.name + const nameB = b.uiMetadata?.displayName || b.name + return nameA < nameB ? -1 : 1 + }) + ) + } + + fetch = async () => { + const roles = await API.getRoles() + this.setRoles(roles) + } + + fetchByAppId = async (appId: string) => { + const { roles } = await API.getRolesForApp(appId) + this.setRoles(roles) + } + + delete = async (role: RoleWithMetadata) => { + if (!role._id || !role._rev) { + return + } + await API.deleteRole(role._id, role._rev) + await this.fetch() + } + + save = async (role: RoleWithMetadata) => { + const savedRole = await API.saveRole(role) + await this.fetch() + return savedRole + } + + replace = (roleId: string, role?: RoleWithMetadata) => { + // Handles external updates of roles + if (!roleId) { + return + } + + // Handle deletion + if (!role) { + this.update(state => state.filter(x => x._id !== roleId)) + return + } + + // Add new role + const index = get(this).findIndex(x => x._id === role._id) + if (index === -1) { + this.update(state => [...state, role]) + } + // Update existing role + else if (role) { + this.update(state => { + state[index] = role + return [...state] + }) + } + } +} + +const store = new RoleStore() +export const roles = { + ...store, + subscribe: store.enriched.subscribe, +} From 1248e55bc2e2969a9075b3e94f3341da7382e3ee Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jan 2025 11:35:46 +0000 Subject: [PATCH 2/5] use correct type --- packages/builder/src/stores/builder/roles.ts | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/packages/builder/src/stores/builder/roles.ts b/packages/builder/src/stores/builder/roles.ts index ea34fdef53..95ea63a997 100644 --- a/packages/builder/src/stores/builder/roles.ts +++ b/packages/builder/src/stores/builder/roles.ts @@ -4,15 +4,7 @@ import { RoleUtils } from "@budibase/frontend-core" import { BudiStore } from "../BudiStore" import { Role } from "@budibase/types" -interface RoleWithMetadata extends Role { - uiMetadata?: { - displayName?: string - color?: string - description?: string - } -} - -export class RoleStore extends BudiStore { +export class RoleStore extends BudiStore { constructor() { super([]) } @@ -30,7 +22,7 @@ export class RoleStore extends BudiStore { })) }) - private setRoles = (roles: RoleWithMetadata[]) => { + private setRoles = (roles: Role[]) => { this.set( roles.sort((a, b) => { // Ensure we have valid IDs for priority comparison @@ -56,7 +48,7 @@ export class RoleStore extends BudiStore { this.setRoles(roles) } - delete = async (role: RoleWithMetadata) => { + delete = async (role: Role) => { if (!role._id || !role._rev) { return } @@ -64,13 +56,13 @@ export class RoleStore extends BudiStore { await this.fetch() } - save = async (role: RoleWithMetadata) => { + save = async (role: Role) => { const savedRole = await API.saveRole(role) await this.fetch() return savedRole } - replace = (roleId: string, role?: RoleWithMetadata) => { + replace = (roleId: string, role?: Role) => { // Handles external updates of roles if (!roleId) { return From 867d162751d9fa75745cde7f317572d3857f376e Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jan 2025 12:34:38 +0000 Subject: [PATCH 3/5] convert published store to ts --- .../src/stores/builder/{published.js => published.ts} | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) rename packages/builder/src/stores/builder/{published.js => published.ts} (53%) diff --git a/packages/builder/src/stores/builder/published.js b/packages/builder/src/stores/builder/published.ts similarity index 53% rename from packages/builder/src/stores/builder/published.js rename to packages/builder/src/stores/builder/published.ts index a59352fb22..c38f3bb718 100644 --- a/packages/builder/src/stores/builder/published.js +++ b/packages/builder/src/stores/builder/published.ts @@ -1,13 +1,16 @@ import { appStore } from "./app" import { appsStore } from "@/stores/portal/apps" import { deploymentStore } from "./deployments" -import { derived } from "svelte/store" +import { derived, type Readable } from "svelte/store" +import { DeploymentProgressResponse, DeploymentStatus } from "@budibase/types" -export const appPublished = derived( +export const appPublished: Readable = derived( [appStore, appsStore, deploymentStore], ([$appStore, $appsStore, $deploymentStore]) => { const app = $appsStore.apps.find(app => app.devId === $appStore.appId) - const deployments = $deploymentStore.filter(x => x.status === "SUCCESS") + const deployments = $deploymentStore.filter( + (x: DeploymentProgressResponse) => x.status === DeploymentStatus.SUCCESS + ) return app?.status === "published" && deployments.length > 0 } ) From 17bb67f6252de70c8679a2852005f6d6647adc54 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 6 Jan 2025 12:41:40 +0000 Subject: [PATCH 4/5] type theme correctly in app document --- packages/builder/src/stores/builder/theme.ts | 15 +++------------ packages/types/src/documents/app/app.ts | 4 ++-- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/packages/builder/src/stores/builder/theme.ts b/packages/builder/src/stores/builder/theme.ts index b3ac202a5d..f2675fe06b 100644 --- a/packages/builder/src/stores/builder/theme.ts +++ b/packages/builder/src/stores/builder/theme.ts @@ -19,10 +19,7 @@ export class ThemeStore extends BudiStore { syncAppTheme = (app: App) => { this.update(state => { - const theme = ensureValidTheme( - app.theme as Theme | undefined, - DefaultAppTheme - ) as Theme + const theme = ensureValidTheme(app.theme, DefaultAppTheme) return { ...state, theme, @@ -35,10 +32,7 @@ export class ThemeStore extends BudiStore { const app = await API.saveAppMetadata(appId, { theme }) this.update(state => ({ ...state, - theme: ensureValidTheme( - app.theme as Theme | undefined, - DefaultAppTheme - ) as Theme, + theme: ensureValidTheme(app.theme, DefaultAppTheme), })) } @@ -55,10 +49,7 @@ export class ThemeStore extends BudiStore { const { theme, customTheme } = metadata this.update(state => ({ ...state, - theme: ensureValidTheme( - theme as Theme | undefined, - DefaultAppTheme - ) as Theme, + theme: ensureValidTheme(theme, DefaultAppTheme), customTheme: customTheme || {}, })) } diff --git a/packages/types/src/documents/app/app.ts b/packages/types/src/documents/app/app.ts index e31dd1e9ac..7486a3fa7e 100644 --- a/packages/types/src/documents/app/app.ts +++ b/packages/types/src/documents/app/app.ts @@ -1,4 +1,4 @@ -import { User, Document, Plugin, Snippet } from "../" +import { User, Document, Plugin, Snippet, Theme } from "../" import { SocketSession } from "../../sdk" export type AppMetadataErrors = { [key: string]: string[] } @@ -14,7 +14,7 @@ export interface App extends Document { instance: AppInstance tenantId: string status: string - theme?: string + theme?: Theme customTheme?: AppCustomTheme revertableVersion?: string lockedBy?: User From 62873dedf480be50e3d70aa5daef7ad1b2ed160e Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 7 Jan 2025 10:35:07 +0000 Subject: [PATCH 5/5] make roles derived store --- packages/builder/src/stores/builder/roles.ts | 44 ++++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/packages/builder/src/stores/builder/roles.ts b/packages/builder/src/stores/builder/roles.ts index 95ea63a997..732f50d6be 100644 --- a/packages/builder/src/stores/builder/roles.ts +++ b/packages/builder/src/stores/builder/roles.ts @@ -1,28 +1,30 @@ -import { derived, get } from "svelte/store" +import { derived, get, type Writable } from "svelte/store" import { API } from "@/api" import { RoleUtils } from "@budibase/frontend-core" -import { BudiStore } from "../BudiStore" +import { DerivedBudiStore } from "../BudiStore" import { Role } from "@budibase/types" -export class RoleStore extends BudiStore { +export class RoleStore extends DerivedBudiStore { constructor() { - super([]) + const makeDerivedStore = (store: Writable) => + derived(store, $store => { + return $store.map((role: Role) => ({ + ...role, + // Ensure we have new metadata for all roles + uiMetadata: { + displayName: role.uiMetadata?.displayName || role.name, + color: + role.uiMetadata?.color || + "var(--spectrum-global-color-magenta-400)", + description: role.uiMetadata?.description || "Custom role", + }, + })) + }) + + super([], makeDerivedStore) } - enriched = derived(this, $store => { - return $store.map(role => ({ - ...role, - // Ensure we have new metadata for all roles - uiMetadata: { - displayName: role.uiMetadata?.displayName || role.name, - color: - role.uiMetadata?.color || "var(--spectrum-global-color-magenta-400)", - description: role.uiMetadata?.description || "Custom role", - }, - })) - }) - - private setRoles = (roles: Role[]) => { + setRoles = (roles: Role[]) => { this.set( roles.sort((a, b) => { // Ensure we have valid IDs for priority comparison @@ -89,8 +91,4 @@ export class RoleStore extends BudiStore { } } -const store = new RoleStore() -export const roles = { - ...store, - subscribe: store.enriched.subscribe, -} +export const roles = new RoleStore()