Skip to content

Commit

Permalink
Implement Feature Flags
Browse files Browse the repository at this point in the history
  • Loading branch information
brandones committed Jul 13, 2023
1 parent 31afb71 commit 357be5d
Show file tree
Hide file tree
Showing 28 changed files with 544 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ The following common libraries have been developed. They may also be used indepe
- [@openmrs/esm-config](packages/framework/esm-config): validation and storage of frontend configuration
- [@openmrs/esm-error-handling](packages/framework/esm-error-handling): handling of errors
- [@openmrs/esm-extensions](packages/framework/esm-extensions): implementation of a frontend component extension system
- [@openmrs/esm-feature-flags](packages/framework/esm-feature-flags): hide features that are in progress
- [@openmrs/esm-globals](packages/framework/esm-globals): useful global variables and types
- [@openmrs/esm-offline](packages/framework/esm-offline): provides offline functionality
- [@openmrs/esm-react-utils](packages/framework/esm-react-utils): utilities for React components
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import React, { Fragment, useMemo } from "react";
import { useTranslation } from "react-i18next";
import {
DataTable,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableHeader,
TableRow,
Toggle,
} from "@carbon/react";
import styles from "./frontend-modules.scss";
import { registerFeatureFlag, useStore } from "@openmrs/esm-framework";
import {
featureFlagsStore,
setFeatureFlag,
} from "@openmrs/esm-framework/src/internal";

export function FeatureFlags() {
const { flags } = useStore(featureFlagsStore);
const { t } = useTranslation();

const headers = useMemo(
() => [
{
key: "label",
header: t("featureFlag", "Feature Flag"),
},
{
key: "description",
header: t("description", "Description"),
},
{
key: "enabled",
header: t("enabled", "Enabled"),
},
],
[t]
);

const rows = useMemo(() => {
return Object.entries(flags)
.sort(([ka, va], [kb, vb]) => {
return (va.label ?? ka).localeCompare(vb.label || kb);
})
.map(([name, { enabled, label, description }]) => ({
name,
enabled,
label,
description,
}));
}, [flags]);

return (
<div className={styles.container}>
<DataTable rows={[]} headers={headers}>
{({ headers, getTableProps, getHeaderProps }) => (
<TableContainer title="">
<Table {...getTableProps()}>
<TableHead>
<TableRow>
{headers.map((header) => (
<TableHeader {...getHeaderProps({ header })}>
{header.header}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((flag) => (
<Fragment key={flag.name}>
<TableRow>
<TableCell>
<div
id={`flag-label-${flag.name}`}
className={styles.header}
>
{flag.label}
</div>
<div className={styles.helper}>{flag.name}</div>
</TableCell>
<TableCell>
<span>{flag.description}</span>
</TableCell>
<TableCell>
<Toggle
id={`feature-flag-${flag.name}-toggle`}
aria-labelledby={`flag-label-${flag.name}`}
labelText="" // using aria-labelledby instead
hideLabel={true}
toggled={flag.enabled}
onToggle={() =>
setFeatureFlag(flag.name, !flag.enabled)
}
/>
</TableCell>
</TableRow>
</Fragment>
))}
</TableBody>
</Table>
</TableContainer>
)}
</DataTable>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@use "@carbon/styles/scss/type";

.container {
height: 50vh;
overflow-y: auto;

:global(.cds--data-table-container) {
padding-top: 0;
}
}

.header {
@include type.type-style("heading-compact-02");
}

.helper {
@include type.type-style("helper-text-01");
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { FrontendModules } from "../frontend-modules/frontend-modules.component"
import { BackendDependencies } from "../backend-dependencies/backend-dependencies.component";
import type { ResolvedDependenciesModule } from "../backend-dependencies/openmrs-backend-dependencies";
import styles from "./popup.styles.scss";
import { FeatureFlags } from "../feature-flags/feature-flags.component";
import { useFeatureFlag } from "@openmrs/esm-framework/src/internal";
import { registerFeatureFlag } from "@openmrs/esm-framework";
import ImplementerTools from "../implementer-tools.component";

interface DevToolsPopupProps {
close(): void;
Expand All @@ -28,10 +32,13 @@ export default function Popup({
return <Configuration />;
} else if (activeTab == 1) {
return <FrontendModules frontendModules={frontendModules} />;
} else {
} else if (activeTab == 2) {
return <BackendDependencies backendDependencies={backendDependencies} />;
} else {
return <FeatureFlags />;
}
}, [activeTab, backendDependencies, frontendModules]);
const testFlag = useFeatureFlag("test-flag");

return (
<div className={styles.popup}>
Expand All @@ -54,8 +61,13 @@ export default function Popup({
name="backend-modules-tab"
text={t("backendModules", "Backend Modules")}
/>
<Switch
name="feature-flags-tab"
text={t("featureFlags", "Feature Flags")}
/>
</ContentSwitcher>
</div>
{testFlag && <div>testFlag is on!</div>}
<div>
<Button
kind="secondary"
Expand All @@ -71,3 +83,10 @@ export default function Popup({
</div>
);
}

registerFeatureFlag(
"test-flag",
"Test Flag",
"Adds a message to the Implementer Tools"
);
registerFeatureFlag("test-flag-2", "Test Flag 2", "Does nothing");
4 changes: 4 additions & 0 deletions packages/apps/esm-implementer-tools-app/translations/am.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
"backendModules": "Backend Modules",
"clearConfig": "Clear Local Config",
"configuration": "Configuration",
"description": "Description",
"downloadConfig": "Download Config",
"edit": "Edit",
"editValueButtonText": "Edit",
"enabled": "Enabled",
"extensions": "Extensions",
"featureFlag": "Feature Flag",
"featureFlags": "Feature Flags",
"frontendModules": "Frontend Modules",
"installedVersion": "Installed Version",
"itemDescriptionSourceDefaultText": "The current value is the default.",
Expand Down
4 changes: 4 additions & 0 deletions packages/apps/esm-implementer-tools-app/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
"backendModules": "Backend Modules",
"clearConfig": "Clear Local Config",
"configuration": "Configuration",
"description": "Description",
"downloadConfig": "Download Config",
"edit": "Edit",
"editValueButtonText": "Edit",
"enabled": "Enabled",
"extensions": "Extensions",
"featureFlag": "Feature Flag",
"featureFlags": "Feature Flags",
"frontendModules": "Frontend Modules",
"installedVersion": "Installed Version",
"itemDescriptionSourceDefaultText": "The current value is the default.",
Expand Down
4 changes: 4 additions & 0 deletions packages/apps/esm-implementer-tools-app/translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
"backendModules": "Modulos backend",
"clearConfig": "Borrar config",
"configuration": "Configuración",
"description": "Description",
"downloadConfig": "Descargar config",
"edit": "Editar",
"editValueButtonText": "Editar",
"enabled": "Enabled",
"extensions": "Extensions",
"featureFlag": "Feature Flag",
"featureFlags": "Feature Flags",
"frontendModules": "Frontend Modules",
"installedVersion": "Versión instalada",
"itemDescriptionSourceDefaultText": "El valor coriente es lo predeterminado.",
Expand Down
4 changes: 4 additions & 0 deletions packages/apps/esm-implementer-tools-app/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
"backendModules": "Backend Modules",
"clearConfig": "Clear Local Config",
"configuration": "Configuration",
"description": "Description",
"downloadConfig": "Download Config",
"edit": "Edit",
"editValueButtonText": "Edit",
"enabled": "Enabled",
"extensions": "Extensions",
"featureFlag": "Feature Flag",
"featureFlags": "Feature Flags",
"frontendModules": "Frontend Modules",
"installedVersion": "Installed Version",
"itemDescriptionSourceDefaultText": "The current value is the default.",
Expand Down
4 changes: 4 additions & 0 deletions packages/apps/esm-implementer-tools-app/translations/he.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
"backendModules": "מודולים בצד השרת",
"clearConfig": "נקה תצורה מקומית",
"configuration": "תצורה",
"description": "Description",
"downloadConfig": "הורד תצורה",
"edit": "ערוך",
"editValueButtonText": "ערוך",
"enabled": "Enabled",
"extensions": "Extensions",
"featureFlag": "Feature Flag",
"featureFlags": "Feature Flags",
"frontendModules": "מודולים בצד הלקוח",
"installedVersion": "גרסה מותקנת",
"itemDescriptionSourceDefaultText": "הערך הנוכחי הוא הערך המוגדר כברירת מחדל.",
Expand Down
4 changes: 4 additions & 0 deletions packages/apps/esm-implementer-tools-app/translations/km.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
"backendModules": "Backend Modules",
"clearConfig": "Clear Local Config",
"configuration": "Configuration",
"description": "Description",
"downloadConfig": "Download Config",
"edit": "Edit",
"editValueButtonText": "Edit",
"enabled": "Enabled",
"extensions": "Extensions",
"featureFlag": "Feature Flag",
"featureFlags": "Feature Flags",
"frontendModules": "Frontend Modules",
"installedVersion": "Installed Version",
"itemDescriptionSourceDefaultText": "The current value is the default.",
Expand Down
1 change: 0 additions & 1 deletion packages/framework/esm-config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,3 @@ PRs welcome! See
[OpenMRS Frontend RFC-20](https://github.com/openmrs/openmrs-rfc-frontend/blob/master/text/0020-contributing-guidelines.md#contributing-guidelines)
for guidelines about contributing.

Maintainer: Brandon Istenes ([email protected])
16 changes: 16 additions & 0 deletions packages/framework/esm-feature-flags/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# openmrs-esm-feature-flags

[![npm: openmrs/esm-feature-flags](https://img.shields.io/npm/v/@openmrs/esm-feature-flags)](https://www.npmjs.com/package/@openmrs/esm-feature-flags)

## What is this?

This is the feature flags library for [OpenMRS Frontend 3.0](https://wiki.openmrs.org/display/projects/OpenMRS+3.0%3A+A+Frontend+Framework+that+enables+collaboration+and+better+User+Experience).

Please see the [Developer Documentation](https://openmrs.github.io/openmrs-esm-core/#/main/config)
for information about how to use it.

## Contributing & Development

PRs welcome! See
[OpenMRS Frontend RFC-20](https://github.com/openmrs/openmrs-rfc-frontend/blob/master/text/0020-contributing-guidelines.md#contributing-guidelines)
for guidelines about contributing.
9 changes: 9 additions & 0 deletions packages/framework/esm-feature-flags/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
transform: {
"^.+\\.tsx?$": ["@swc/jest"],
},
testEnvironment: "jsdom",
testEnvironmentOptions: {
url: "http://localhost/",
},
};
51 changes: 51 additions & 0 deletions packages/framework/esm-feature-flags/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "@openmrs/esm-feature-flags",
"version": "5.0.2",
"license": "MPL-2.0",
"description": "A feature flag system for the OpenMRS Single-Spa framework.",
"browser": "dist/openmrs-esm-feature-flags.js",
"main": "src/index.ts",
"source": true,
"scripts": {
"test": "jest --config jest.config.js --passWithNoTests",
"build": "webpack --mode=production",
"build:development": "webpack --mode development",
"analyze": "webpack --mode=production --env analyze=true",
"typescript": "tsc",
"lint": "eslint src --ext ts,tsx"
},
"keywords": [
"openmrs",
"microfrontends"
],
"directories": {
"lib": "dist",
"src": "src"
},
"browserslist": [
"extends browserslist-config-openmrs"
],
"repository": {
"type": "git",
"url": "git+https://github.com/openmrs/openmrs-esm-core.git"
},
"bugs": {
"url": "https://github.com/openmrs/openmrs-esm-core/issues"
},
"homepage": "https://github.com/openmrs/openmrs-esm-core#readme",
"publishConfig": {
"access": "public"
},
"dependencies": {
"ramda": "^0.26.1"
},
"peerDependencies": {
"@openmrs/esm-globals": "4.x",
"@openmrs/esm-state": "4.x",
"single-spa": "5.x"
},
"devDependencies": {
"@openmrs/esm-globals": "^5.0.2",
"@openmrs/esm-state": "^5.0.2"
}
}
Loading

0 comments on commit 357be5d

Please sign in to comment.