From c2fbdf505ede3f5f0cac579f8d28703116cf2006 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 3 Jan 2025 10:42:44 +0000 Subject: [PATCH] Convert portal feature store to TS --- packages/builder/src/stores/BudiStore.ts | 13 +++-- .../builder/src/stores/portal/features.js | 54 ------------------- .../builder/src/stores/portal/features.ts | 35 ++++++++++++ packages/types/src/documents/global/config.ts | 3 ++ 4 files changed, 48 insertions(+), 57 deletions(-) delete mode 100644 packages/builder/src/stores/portal/features.js create mode 100644 packages/builder/src/stores/portal/features.ts diff --git a/packages/builder/src/stores/BudiStore.ts b/packages/builder/src/stores/BudiStore.ts index d5bbc99328..d537847a4d 100644 --- a/packages/builder/src/stores/BudiStore.ts +++ b/packages/builder/src/stores/BudiStore.ts @@ -20,7 +20,7 @@ interface BudiStoreOpts { export class BudiStore { store: Writable - subscribe: Writable["subscribe"] + subscribe: Readable["subscribe"] update: Writable["update"] set: Writable["set"] @@ -53,17 +53,24 @@ export class BudiStore { } } -export class DerivedBudiStore extends BudiStore { +// This deliberately does not extend a BudiStore as doing so imposes a requirement that +// DerivedT must extend T, which is not desirable, due to the type of the subscribe property. +export class DerivedBudiStore { + store: BudiStore derivedStore: Readable subscribe: Readable["subscribe"] + update: Writable["update"] + set: Writable["set"] constructor( init: T, makeDerivedStore: (store: Writable) => Readable, opts?: BudiStoreOpts ) { - super(init, opts) + this.store = new BudiStore(init, opts) this.derivedStore = makeDerivedStore(this.store) this.subscribe = this.derivedStore.subscribe + this.update = this.store.update + this.set = this.store.set } } diff --git a/packages/builder/src/stores/portal/features.js b/packages/builder/src/stores/portal/features.js deleted file mode 100644 index 747052aa6c..0000000000 --- a/packages/builder/src/stores/portal/features.js +++ /dev/null @@ -1,54 +0,0 @@ -import { writable } from "svelte/store" -import { API } from "@/api" -import { licensing } from "./licensing" -import { ConfigType } from "@budibase/types" - -export const createFeatureStore = () => { - const internalStore = writable({ - scim: { - isFeatureFlagEnabled: false, - isConfigFlagEnabled: false, - }, - }) - - const store = writable({ - isScimEnabled: false, - }) - - internalStore.subscribe(s => { - store.update(state => ({ - ...state, - isScimEnabled: s.scim.isFeatureFlagEnabled && s.scim.isConfigFlagEnabled, - })) - }) - - licensing.subscribe(v => { - internalStore.update(state => ({ - ...state, - scim: { - ...state.scim, - isFeatureFlagEnabled: v.scimEnabled, - }, - })) - }) - - const actions = { - init: async () => { - const scimConfig = await API.getConfig(ConfigType.SCIM) - internalStore.update(state => ({ - ...state, - scim: { - ...state.scim, - isConfigFlagEnabled: scimConfig?.config?.enabled, - }, - })) - }, - } - - return { - subscribe: store.subscribe, - ...actions, - } -} - -export const features = createFeatureStore() diff --git a/packages/builder/src/stores/portal/features.ts b/packages/builder/src/stores/portal/features.ts new file mode 100644 index 0000000000..049c7485a6 --- /dev/null +++ b/packages/builder/src/stores/portal/features.ts @@ -0,0 +1,35 @@ +import { derived, Writable } from "svelte/store" +import { API } from "@/api" +import { licensing } from "./licensing" +import { ConfigType, isConfig, isSCIMConfig } from "@budibase/types" +import { DerivedBudiStore } from "../BudiStore" + +interface FeatureState { + scimConfigEnabled: Boolean +} + +interface DerivedFeatureState { + isScimEnabled: Boolean +} + +class FeatureStore extends DerivedBudiStore { + constructor() { + const makeDerivedStore = (store: Writable) => { + return derived([store, licensing], ([$state, $licensing]) => ({ + isScimEnabled: $state.scimConfigEnabled && $licensing.scimEnabled, + })) + } + super({ scimConfigEnabled: false }, makeDerivedStore) + } + + async init() { + const config = await API.getConfig(ConfigType.SCIM) + this.update(state => ({ + ...state, + scimConfigEnabled: + isConfig(config) && isSCIMConfig(config) && config.config.enabled, + })) + } +} + +export const features = new FeatureStore() diff --git a/packages/types/src/documents/global/config.ts b/packages/types/src/documents/global/config.ts index 33f7e10584..d51ca9d54d 100644 --- a/packages/types/src/documents/global/config.ts +++ b/packages/types/src/documents/global/config.ts @@ -127,6 +127,9 @@ export interface AIInnerConfig { export interface AIConfig extends Config {} +export const isConfig = (config: Object): config is Config => + "type" in config && "config" in config + export const isSettingsConfig = (config: Config): config is SettingsConfig => config.type === ConfigType.SETTINGS