Skip to content

Commit

Permalink
feat(feature-flags): create basic support for feature flags
Browse files Browse the repository at this point in the history
  • Loading branch information
nimdanitro committed Oct 28, 2024
1 parent bc60be9 commit 926b571
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 85 deletions.
2 changes: 1 addition & 1 deletion ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; style-src-attr 'self'; child-src 'none'; worker-src 'self' blob:; script-src-elem 'self' https://api.mapbox.com; connect-src 'self' ws://* wss://* https://*;"
content="default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; style-src-attr 'self'; child-src 'none'; worker-src 'self' blob:; script-src 'self' 'wasm-unsafe-eval'; script-src-elem 'self' https://api.mapbox.com; connect-src 'self' ws://* wss://* https://*;"
/>
<meta name="description" content="SitRep" />
<link rel="icon" href="/favicon-48x48.ico" sizes="48x48" />
Expand Down
4 changes: 4 additions & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@fortawesome/react-fontawesome": "^0.2.2",
"@mapbox/mapbox-gl-draw": "~1.4.3",
"@openfeature/core": "^1.4.0",
"@openfeature/flipt-web-provider": "^0.1.0",
"@openfeature/react-sdk": "^0.4.6",
"@openfeature/web-sdk": "^1.2.4",
"@turf/bearing": "^7.1.0",
"@turf/center": "^7.1.0",
"@turf/helpers": "^7.1.0",
Expand Down
167 changes: 85 additions & 82 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import { UserState } from "types";
import { UserContext } from "utils";
import MessageSheet from "views/journal/MessageSheet";
import { Layout, LayoutMarginLess } from "views/Layout";
import { default as client } from "./client";
import { default as client } from "client";
import { Provider as FeatureFlagProvider } from "FeatureFlags";

const Map = lazy(() => import("views/map"));

Expand Down Expand Up @@ -65,126 +66,128 @@ function App() {
return (
<UserContext.Provider value={userState}>
<ApolloProvider client={client}>
<Router>
<Routes>
<Route path="/incident">
<Route
path="list"
element={
<Layout>
<IncidentList />
</Layout>
}
/>
<Route
path="new"
element={
<Layout>
<IncidentNew />
</Layout>
}
/>

<Route path=":incidentId">
<FeatureFlagProvider>
<Router>
<Routes>
<Route path="/incident">
<Route
path="edit"
path="list"
element={
<Layout>
<IncidentEditor />
<IncidentList />
</Layout>
}
/>
<Route
path="new"
element={
<Layout>
<IncidentNew />
</Layout>
}
/>

<Route path="journal">
<Route path=":incidentId">
<Route
path="view"
path="edit"
element={
<Layout>
<JournalOverview />
<IncidentEditor />
</Layout>
}
/>

<Route path="journal">
<Route
path="view"
element={
<Layout>
<JournalOverview />
</Layout>
}
/>
<Route
path="new"
element={
<Layout>
<JournalNew />
</Layout>
}
/>
<Route
path=":journalId/edit"
element={
<Layout>
<JournalEditor />
</Layout>
}
/>
<Route
path=":journalId"
element={
<Layout>
<JournalMessageList showControls={false} autoScroll={true} />
</Layout>
}
/>
<Route
path=":journalId/messages/:messageId"
element={
<Layout>
<MessageSheet />
</Layout>
}
/>
</Route>

<Route
path="new"
path="resources"
element={
<Layout>
<JournalNew />
<ResourcesList />
</Layout>
}
/>
<Route
path=":journalId/edit"
path="map"
element={
<LayoutMarginLess>
<Suspense fallback={<Spinner />}>
<Map />
</Suspense>
</LayoutMarginLess>
}
/>
<Route
path="tasks"
element={
<Layout>
<JournalEditor />
<TaskList />
</Layout>
}
/>
<Route
path=":journalId"
path="requests"
element={
<Layout>
<JournalMessageList showControls={false} autoScroll={true} />
<RequestList />
</Layout>
}
/>
<Route
path=":journalId/messages/:messageId"
path="soma"
element={
<Layout>
<MessageSheet />
<ImmediateMeasuresList />
</Layout>
}
/>
</Route>

<Route
path="resources"
element={
<Layout>
<ResourcesList />
</Layout>
}
/>
<Route
path="map"
element={
<LayoutMarginLess>
<Suspense fallback={<Spinner />}>
<Map />
</Suspense>
</LayoutMarginLess>
}
/>
<Route
path="tasks"
element={
<Layout>
<TaskList />
</Layout>
}
/>
<Route
path="requests"
element={
<Layout>
<RequestList />
</Layout>
}
/>
<Route
path="soma"
element={
<Layout>
<ImmediateMeasuresList />
</Layout>
}
/>
</Route>
</Route>
<Route path="/" element={<Navigate to="/incident/list" />} />
</Routes>
</Router>
<Route path="/" element={<Navigate to="/incident/list" />} />
</Routes>
</Router>
</FeatureFlagProvider>
</ApolloProvider>
</UserContext.Provider>
);
Expand Down
36 changes: 36 additions & 0 deletions ui/src/FeatureFlags.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { EvaluationContext, OpenFeatureProvider, OpenFeature, InMemoryProvider } from "@openfeature/react-sdk";
import { FliptWebProvider } from "@openfeature/flipt-web-provider";

import { PropsWithChildren, useEffect } from "react";

const localFlagConfig = {
"new-message": {
disabled: false,
variants: {
on: true,
off: false,
},
defaultVariant: "on",
contextEvaluator: (context: EvaluationContext) => {
if (context.silly) {
return "on";
}
return "off";
},
},
};

const Provider = (props: PropsWithChildren) => {
const { children } = props;
useEffect(() => {
const fliptProvider = new FliptWebProvider("sitrep-ui", { url: "https://flipt.sitrep.ch" });
OpenFeature.setLogger(console);
OpenFeature.setProvider("local", new InMemoryProvider(localFlagConfig));
console.log("setting origin", document.location.host);
OpenFeature.setProvider(fliptProvider, { domain: document.location.host.split(":")[0] });
}, []);

return <OpenFeatureProvider>{children}</OpenFeatureProvider>;
};

export { Provider };
8 changes: 6 additions & 2 deletions ui/src/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import classNames from "classnames";
import { FunctionComponent, useContext, useEffect, useState } from "react";
import { useBooleanFlagValue } from "@openfeature/react-sdk";

import { faCalendar, faClock } from "@fortawesome/free-regular-svg-icons";
import logo from "assets/logo.svg";
Expand All @@ -39,6 +40,9 @@ const Navbar: FunctionComponent<{ isActive?: boolean }> = ({ isActive = false })
"is-active": isMenuActive,
});

const showResources = useBooleanFlagValue("show-resources", false);
const showTasks = useBooleanFlagValue("show-tasks", false);

return (
<nav className="navbar is-fixed-top is-hidden-print">
<div className="navbar-brand">
Expand Down Expand Up @@ -90,8 +94,8 @@ const Navbar: FunctionComponent<{ isActive?: boolean }> = ({ isActive = false })
</div>
</div>
<JournalNavBar />
{/* <ResourcesNavBar />
<TasksNavBar /> */}
{showResources ? <ResourcesNavBar /> : <></>}
{showTasks ? <TasksNavBar /> : <></>}
<MapNavBar />
</div>
<div className="navbar-end">
Expand Down
49 changes: 49 additions & 0 deletions ui/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2281,6 +2281,13 @@ __metadata:
languageName: node
linkType: hard

"@flipt-io/flipt-client-browser@npm:^0.0.17":
version: 0.0.17
resolution: "@flipt-io/flipt-client-browser@npm:0.0.17"
checksum: 10/284e5924b3756efd63ae5a3902d54534cd1266463557015b13b00822cf6fc10ee058d6634966519982326ec13e7423f08e65bdd61ed9a009a3bff75eef208d83
languageName: node
linkType: hard

"@fortawesome/fontawesome-common-types@npm:6.6.0":
version: 6.6.0
resolution: "@fortawesome/fontawesome-common-types@npm:6.6.0"
Expand Down Expand Up @@ -3236,6 +3243,44 @@ __metadata:
languageName: node
linkType: hard

"@openfeature/core@npm:^1.4.0":
version: 1.4.0
resolution: "@openfeature/core@npm:1.4.0"
checksum: 10/7a253920b05659e4590c4b1c07f6fced25f5ff08ff9092ad6608f5c7f42075e44d0add94f95690414a1405e54c73e511db2963bfcc2e78f26f3f7861f755993d
languageName: node
linkType: hard

"@openfeature/flipt-web-provider@npm:^0.1.0":
version: 0.1.0
resolution: "@openfeature/flipt-web-provider@npm:0.1.0"
dependencies:
"@flipt-io/flipt-client-browser": "npm:^0.0.17"
tslib: "npm:^2.3.0"
peerDependencies:
"@openfeature/web-sdk": ^1.0.0
checksum: 10/d9d80e2e343f77898639b29aee6bdcf2e65ef82cb4b7d350122481b31e30c668cb175e779edbcf51d70b78add960eb7399c976b52584bebf904e0e5863eb7fe1
languageName: node
linkType: hard

"@openfeature/react-sdk@npm:^0.4.6":
version: 0.4.6
resolution: "@openfeature/react-sdk@npm:0.4.6"
peerDependencies:
"@openfeature/web-sdk": ^1.2.2
react: ">=16.8.0"
checksum: 10/bac78bc4e201739ae2903f7790195629566d5ace054cc30404d691838d4806b474ae98ae8bb8b87bbfdd015efa1ef6f9e8ffdeee9160b197d278536da3ffe7c1
languageName: node
linkType: hard

"@openfeature/web-sdk@npm:^1.2.4":
version: 1.2.4
resolution: "@openfeature/web-sdk@npm:1.2.4"
peerDependencies:
"@openfeature/core": 1.4.0
checksum: 10/3dcef55af73050638c8c15fccbb23fb20d5efd9619b822d86b926c11b2c042191e0e3a98b5412fc0fe66ef9506941d6dbf2a28caa29847e54b683386fc7d0dc0
languageName: node
linkType: hard

"@parcel/watcher-android-arm64@npm:2.4.1":
version: 2.4.1
resolution: "@parcel/watcher-android-arm64@npm:2.4.1"
Expand Down Expand Up @@ -12623,6 +12668,10 @@ __metadata:
"@fortawesome/free-solid-svg-icons": "npm:^6.6.0"
"@fortawesome/react-fontawesome": "npm:^0.2.2"
"@mapbox/mapbox-gl-draw": "npm:~1.4.3"
"@openfeature/core": "npm:^1.4.0"
"@openfeature/flipt-web-provider": "npm:^0.1.0"
"@openfeature/react-sdk": "npm:^0.4.6"
"@openfeature/web-sdk": "npm:^1.2.4"
"@testing-library/dom": "npm:^10.4.0"
"@testing-library/jest-dom": "npm:^6.6.2"
"@testing-library/react": "npm:^16.0.1"
Expand Down

0 comments on commit 926b571

Please sign in to comment.