Skip to content

Commit 9d65d48

Browse files
authored
Merge pull request #95 from GeneralUserModels/omar/feature-flags
Omar/feature flags
2 parents 51d6f8a + ec526a0 commit 9d65d48

33 files changed

Lines changed: 273 additions & 108 deletions

site/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type ReactNode, useEffect, useState } from "react";
1+
import React, { type ReactNode, useEffect, useState } from "react";
22

33
const REPO = "GeneralUserModels/tada";
44
const RELEASE_URL = `https://github.com/${REPO}/releases/latest`;

site/src/main.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { StrictMode } from "react";
1+
import React, { StrictMode } from "react";
22
import { createRoot } from "react-dom/client";
33
import { App } from "./App";
44
import "./App.css";

src/apps/moments/discovery.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from datetime import datetime
88
from pathlib import Path
99

10+
from server.feature_flags import is_enabled
11+
1012
logger = logging.getLogger(__name__)
1113

1214

@@ -100,7 +102,7 @@ async def run_moments_discovery(state) -> None:
100102
logger.info("Next discovery run at %s (in %.0fs)", next_run, delay)
101103
await asyncio.sleep(delay)
102104

103-
if not state.config.moments_enabled:
105+
if not (is_enabled(state.config, "moments") and state.config.moments_enabled):
104106
continue
105107

106108
cfg = state.config

src/apps/moments/scheduler.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from apps.moments.execute import run as execute_moment, _parse_frontmatter as parse_frontmatter
1414
from apps.moments.state import load_state
15+
from server.feature_flags import is_enabled
1516

1617
logger = logging.getLogger(__name__)
1718

@@ -138,7 +139,7 @@ async def run_moments_scheduler(state) -> None:
138139
try:
139140
await asyncio.sleep(SCAN_INTERVAL)
140141

141-
if not state.config.moments_enabled:
142+
if not (is_enabled(state.config, "moments") and state.config.moments_enabled):
142143
continue
143144

144145
cfg = state.config

src/client/renderer/App.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import React from "react";
12
import { useAppContext } from "./context/AppContext";
3+
import { useFeatureFlag } from "./featureFlags";
24
import { Sidebar } from "./components/Sidebar";
35
import { ConnectorsView } from "./components/views/ConnectorsView";
46
import { UserModelView } from "./components/views/UserModelView";
@@ -8,6 +10,7 @@ import { UpdateBanner } from "./components/UpdateBanner";
810

911
export function App() {
1012
const { state, dispatch } = useAppContext();
13+
const momentsEnabled = useFeatureFlag("moments");
1114

1215
const navigate = (view: typeof state.activeView) => {
1316
dispatch({ type: "NAVIGATE", view });
@@ -30,7 +33,7 @@ export function App() {
3033
/>
3134
)}
3235
{state.activeView === "connectors" && <ConnectorsView />}
33-
{state.activeView === "tada" && <TadaView />}
36+
{state.activeView === "tada" && momentsEnabled && <TadaView />}
3437
{state.activeView === "usermodel" && <UserModelView />}
3538
{state.activeView === "settings" && <SettingsView />}
3639
</main>

src/client/renderer/components/Sidebar.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import React from "react";
12
import { ActiveView } from "../context/AppContext";
3+
import { useFeatureFlags, getFlag } from "../featureFlags";
24

35
interface Props {
46
activeView: ActiveView;
@@ -48,7 +50,19 @@ const navItems: { view: ActiveView; label: string; icon: JSX.Element }[] = [
4850
},
4951
];
5052

53+
const FLAG_FOR_VIEW: Partial<Record<ActiveView, string>> = {
54+
tada: "moments",
55+
};
56+
5157
export function Sidebar({ activeView, connected, onNavigate }: Props) {
58+
const featureFlags = useFeatureFlags();
59+
60+
const visibleItems = navItems.filter(({ view }) => {
61+
const flag = FLAG_FOR_VIEW[view];
62+
if (flag && !getFlag(featureFlags, flag)) return false;
63+
return true;
64+
});
65+
5266
return (
5367
<nav id="sidebar">
5468
<div className="sidebar-brand">
@@ -72,7 +86,7 @@ export function Sidebar({ activeView, connected, onNavigate }: Props) {
7286
</div>
7387

7488
<div className="sidebar-nav">
75-
{navItems.map(({ view, label, icon }) => (
89+
{visibleItems.map(({ view, label, icon }) => (
7690
<button
7791
key={view}
7892
className={`nav-item${activeView === view ? " active" : ""}`}

src/client/renderer/components/UpdateBanner.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import React from "react";
2+
13
const DOWNLOAD_URL = "https://github.com/GeneralUserModels/tada-release/releases/latest";
24

35
interface Props {

src/client/renderer/components/connectors/ConnectorItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useState } from "react";
1+
import React, { useEffect, useState } from "react";
22

33
const CONNECTOR_ICONS: Record<string, JSX.Element> = {
44
monitor: (

src/client/renderer/components/dashboard/PipelineTile.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import React from "react";
12
import { TrainingState } from "../../hooks/useTraining";
23

34
const stateLabels: Record<TrainingState, string> = {

src/client/renderer/components/dashboard/PredictionCard.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import React from "react";
2+
13
interface Props {
24
prediction: { actions?: string; error?: string; timestamp?: string } | null;
35
}

0 commit comments

Comments
 (0)