From cbe094b56d257d22d0cfb842e49088dc075bac84 Mon Sep 17 00:00:00 2001 From: samuelmale Date: Thu, 19 Dec 2024 19:50:39 +0300 Subject: [PATCH] (feat) Add "Enable Feature Flags" config option to the app-shell --- .../src/module-config/module-config.ts | 1 - .../esm-routes/src/loaders/components.ts | 6 +-- .../shell/esm-app-shell/src/core-config.ts | 38 +++++++++++++++++++ packages/shell/esm-app-shell/src/run.ts | 2 + 4 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 packages/shell/esm-app-shell/src/core-config.ts diff --git a/packages/framework/esm-config/src/module-config/module-config.ts b/packages/framework/esm-config/src/module-config/module-config.ts index 4c7076279..f30da85b1 100644 --- a/packages/framework/esm-config/src/module-config/module-config.ts +++ b/packages/framework/esm-config/src/module-config/module-config.ts @@ -15,7 +15,6 @@ import { temporaryConfigStore, getExtensionSlotsConfigStore, } from './state'; -import type {} from '@openmrs/esm-globals'; import { type TemporaryConfigStore } from '..'; /** diff --git a/packages/framework/esm-routes/src/loaders/components.ts b/packages/framework/esm-routes/src/loaders/components.ts index 3027946b2..d772795eb 100644 --- a/packages/framework/esm-routes/src/loaders/components.ts +++ b/packages/framework/esm-routes/src/loaders/components.ts @@ -200,10 +200,10 @@ supported, so the workspace will not be loaded.`, } /** - * This function registers a workspace definition with the framework so that it can be launched. + * This function registers a feature flag definition with the framework. * - * @param appName The name of the app defining this workspace - * @param featureFlag An object that describes the workspace, derived from `routes.json` + * @param appName The name of the app defining this feature flag + * @param featureFlag An object that describes the feature flag, derived from `routes.json` */ export function tryRegisterFeatureFlag(appName: string, featureFlag: FeatureFlagDefinition) { const name = featureFlag.flagName; diff --git a/packages/shell/esm-app-shell/src/core-config.ts b/packages/shell/esm-app-shell/src/core-config.ts new file mode 100644 index 000000000..42cc89efa --- /dev/null +++ b/packages/shell/esm-app-shell/src/core-config.ts @@ -0,0 +1,38 @@ +import { defineConfigSchema, Type, getConfigStore } from '@openmrs/esm-framework'; +import { registerModuleLoad, featureFlagsStore } from '@openmrs/esm-framework/src/internal'; +import { appName } from './ui'; + +/** + * Sets up the app shell's configuration. + */ +export function setupCoreConfig() { + defineConfigSchema(appName, { + 'Enabled feature flags': { + _description: 'The feature flags that will be enabled', + _type: Type.Array, + _default: [], + _elements: { + _type: Type.String, + }, + }, + }); + registerModuleLoad(appName); + + // process feature flags + getConfigStore(appName).subscribe(({ config }) => { + const flagsToEnable = new Set((config?.['Enabled feature flags'] as Array) || []); + if (flagsToEnable.size) { + const newFlags = { ...featureFlagsStore.getState().flags }; + for (const flag of flagsToEnable) { + // validate the flag exists + if (!newFlags[flag]) { + console.error(`Feature flag "${flag}" does not exist. Please define the flag first.`); + } else { + newFlags[flag] = { ...newFlags[flag], enabled: true }; + } + } + + featureFlagsStore.setState({ flags: newFlags }); + } + }); +} diff --git a/packages/shell/esm-app-shell/src/run.ts b/packages/shell/esm-app-shell/src/run.ts index 2dc956f3f..d8d8fbc4d 100644 --- a/packages/shell/esm-app-shell/src/run.ts +++ b/packages/shell/esm-app-shell/src/run.ts @@ -43,6 +43,7 @@ import { import { setupI18n } from './locale'; import { registerOptionalDependencyHandler } from './optionaldeps'; import { appName, getCoreExtensions } from './ui'; +import { setupCoreConfig } from './core-config'; // @internal // used to track when the window.installedModules global is finalised @@ -408,6 +409,7 @@ export function run(configUrls: Array) { setupApiModule(); setupHistory(); registerCoreExtensions(); + setupCoreConfig(); return setupApps() .then(finishRegisteringAllApps)