Skip to content

Commit

Permalink
fix: Form dialog hidden fixed feature flags (#4675)
Browse files Browse the repository at this point in the history
* Form dialog hidden fixed feature flags

* remove temp lint directive

* Removed debugging vars
  • Loading branch information
GeoffCoxMSFT authored Nov 4, 2020
1 parent 5bed4ba commit e98e52c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 57 deletions.
2 changes: 1 addition & 1 deletion Composer/packages/lib/shared/src/featureFlagUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const getDefaultFeatureFlags = (): FeatureFlagMap => ({
FORM_DIALOG: {
displayName: formatMessage('Show Form Dialog'),
description: formatMessage('Show form dialog editor in the canvas'),
isHidden: false,
isHidden: true,
enabled: false,
},
});
107 changes: 51 additions & 56 deletions Composer/packages/server/src/services/featureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,69 +21,64 @@ export class FeatureFlagService {
private static updateFeatureFlags = () => {
const currentFeatureFlagKeys = Object.keys(FeatureFlagService.currentFeatureFlagMap);
const defaultFeatureFlagKeys = Object.keys(FeatureFlagService.defaultFeatureFlags);
const keysToAdd: string[] = [];
const keysToUpdateHidden: string[] = [];

defaultFeatureFlagKeys.forEach((key: string) => {
if (!currentFeatureFlagKeys.includes(key)) {
keysToAdd.push(key);
} else if (
currentFeatureFlagKeys.includes(key) &&
FeatureFlagService.currentFeatureFlagMap[key as FeatureFlagKey].isHidden !==
FeatureFlagService.defaultFeatureFlags[key as FeatureFlagKey].isHidden
) {
keysToUpdateHidden.push(key);
}
});

const keysToRemove = currentFeatureFlagKeys.filter((key: string) => {
if (!defaultFeatureFlagKeys.includes(key)) {
return key;
}
});

keysToAdd.forEach((key: string) => {
FeatureFlagService.currentFeatureFlagMap[key] = FeatureFlagService.defaultFeatureFlags[key];
// apply defaults to the loaded feature flags
Object.keys(FeatureFlagService.currentFeatureFlagMap).forEach((key) => {
FeatureFlagService.currentFeatureFlagMap[key] = {
...FeatureFlagService.defaultFeatureFlags[key],
...FeatureFlagService.currentFeatureFlagMap[key],
};
});

keysToRemove.forEach((key: string) => {
delete FeatureFlagService.currentFeatureFlagMap[key];
});

keysToUpdateHidden.forEach((key: string) => {
FeatureFlagService.currentFeatureFlagMap[key as FeatureFlagKey].isHidden =
FeatureFlagService.defaultFeatureFlags[key as FeatureFlagKey].isHidden;
});

const hiddenFeatureFlagUpdated = FeatureFlagService.updateHiddenFeatureFlags();

if (
keysToRemove?.length > 0 ||
keysToAdd?.length > 0 ||
keysToUpdateHidden?.length > 0 ||
hiddenFeatureFlagUpdated
) {
Store.set(storeKey, FeatureFlagService.currentFeatureFlagMap);
let saveNeeded = false;

// add any new keys defined in the defaults that aren't in current
defaultFeatureFlagKeys
.filter((key: string) => !currentFeatureFlagKeys.includes(key))
.forEach((key: string) => {
FeatureFlagService.currentFeatureFlagMap[key] = FeatureFlagService.defaultFeatureFlags[key];
saveNeeded = true;
});

// remove any keys no longer in default that are in current
currentFeatureFlagKeys
.filter((key: string) => !defaultFeatureFlagKeys.includes(key))
.forEach((key: string) => {
delete FeatureFlagService.currentFeatureFlagMap[key];
saveNeeded = true;
});

// set any hidden feature flags from the process
// process should override value for hidden features flags
Object.keys(FeatureFlagService.currentFeatureFlagMap)
.filter((key) => FeatureFlagService.currentFeatureFlagMap[key as FeatureFlagKey].isHidden)
.forEach((key) => {
const enabled = FeatureFlagService.currentFeatureFlagMap[key as FeatureFlagKey].enabled;
const processEnvEnabled = key in process.env;

if (enabled !== processEnvEnabled) {
FeatureFlagService.currentFeatureFlagMap[key as FeatureFlagKey].enabled = processEnvEnabled;
saveNeeded = true;
}
});

if (saveNeeded) {
FeatureFlagService.saveFeatureFlags();
}
};

private static updateHiddenFeatureFlags = (): boolean => {
const hiddenFeatureFlagKeys = Object.keys(FeatureFlagService.currentFeatureFlagMap).filter((key: string) => {
if (FeatureFlagService.currentFeatureFlagMap[key as FeatureFlagKey].isHidden) {
return key;
}
});
private static saveFeatureFlags() {
const saveFeatureFlagMap: FeatureFlagMap = {} as FeatureFlagMap;

let result = false;
hiddenFeatureFlagKeys.forEach((key: string) => {
if (process.env[key] && process.env[key] !== FeatureFlagService.currentFeatureFlagMap[key]) {
FeatureFlagService.currentFeatureFlagMap[key as FeatureFlagKey].enabled =
process.env[key]?.toLowerCase() === 'true';
result = true;
}
// only save user data to avoid replacing values from defaults like displayName
Object.keys(FeatureFlagService.currentFeatureFlagMap).forEach((key) => {
saveFeatureFlagMap[key] = {
enabled: FeatureFlagService.currentFeatureFlagMap[key].enabled,
isHidden: FeatureFlagService.currentFeatureFlagMap[key].isHidden,
};
});
return result;
};
Store.set(storeKey, saveFeatureFlagMap);
}

public static getFeatureFlags(): FeatureFlagMap {
FeatureFlagService.initialize();
Expand All @@ -92,7 +87,7 @@ export class FeatureFlagService {

public static updateFeatureFlag(newFeatureFlags: FeatureFlagMap) {
FeatureFlagService.currentFeatureFlagMap = newFeatureFlags;
Store.set(storeKey, newFeatureFlags);
FeatureFlagService.saveFeatureFlags();
}

public static getFeatureFlagValue(featureFlagKey: FeatureFlagKey): boolean {
Expand Down

0 comments on commit e98e52c

Please sign in to comment.