diff --git a/site/src/App.tsx b/site/src/App.tsx
index 521d28f..a6aeea9 100644
--- a/site/src/App.tsx
+++ b/site/src/App.tsx
@@ -1,4 +1,4 @@
-import { type ReactNode, useEffect, useState } from "react";
+import React, { type ReactNode, useEffect, useState } from "react";
const REPO = "GeneralUserModels/tada";
const RELEASE_URL = `https://github.com/${REPO}/releases/latest`;
diff --git a/site/src/main.tsx b/site/src/main.tsx
index bd4d570..423ec24 100644
--- a/site/src/main.tsx
+++ b/site/src/main.tsx
@@ -1,4 +1,4 @@
-import { StrictMode } from "react";
+import React, { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { App } from "./App";
import "./App.css";
diff --git a/src/apps/moments/discovery.py b/src/apps/moments/discovery.py
index 671120f..9075ee8 100644
--- a/src/apps/moments/discovery.py
+++ b/src/apps/moments/discovery.py
@@ -7,6 +7,8 @@
from datetime import datetime
from pathlib import Path
+from server.feature_flags import is_enabled
+
logger = logging.getLogger(__name__)
@@ -100,7 +102,7 @@ async def run_moments_discovery(state) -> None:
logger.info("Next discovery run at %s (in %.0fs)", next_run, delay)
await asyncio.sleep(delay)
- if not state.config.moments_enabled:
+ if not (is_enabled(state.config, "moments") and state.config.moments_enabled):
continue
cfg = state.config
diff --git a/src/apps/moments/scheduler.py b/src/apps/moments/scheduler.py
index 4284331..da921d3 100644
--- a/src/apps/moments/scheduler.py
+++ b/src/apps/moments/scheduler.py
@@ -12,6 +12,7 @@
from apps.moments.execute import run as execute_moment, _parse_frontmatter as parse_frontmatter
from apps.moments.state import load_state
+from server.feature_flags import is_enabled
logger = logging.getLogger(__name__)
@@ -138,7 +139,7 @@ async def run_moments_scheduler(state) -> None:
try:
await asyncio.sleep(SCAN_INTERVAL)
- if not state.config.moments_enabled:
+ if not (is_enabled(state.config, "moments") and state.config.moments_enabled):
continue
cfg = state.config
diff --git a/src/client/renderer/App.tsx b/src/client/renderer/App.tsx
index 0046904..31020ca 100644
--- a/src/client/renderer/App.tsx
+++ b/src/client/renderer/App.tsx
@@ -1,4 +1,6 @@
+import React from "react";
import { useAppContext } from "./context/AppContext";
+import { useFeatureFlag } from "./featureFlags";
import { Sidebar } from "./components/Sidebar";
import { ConnectorsView } from "./components/views/ConnectorsView";
import { UserModelView } from "./components/views/UserModelView";
@@ -8,6 +10,7 @@ import { UpdateBanner } from "./components/UpdateBanner";
export function App() {
const { state, dispatch } = useAppContext();
+ const momentsEnabled = useFeatureFlag("moments");
const navigate = (view: typeof state.activeView) => {
dispatch({ type: "NAVIGATE", view });
@@ -30,7 +33,7 @@ export function App() {
/>
)}
{state.activeView === "connectors" && }
- {state.activeView === "tada" && }
+ {state.activeView === "tada" && momentsEnabled && }
{state.activeView === "usermodel" && }
{state.activeView === "settings" && }
diff --git a/src/client/renderer/components/Sidebar.tsx b/src/client/renderer/components/Sidebar.tsx
index dbfe03a..d18e222 100644
--- a/src/client/renderer/components/Sidebar.tsx
+++ b/src/client/renderer/components/Sidebar.tsx
@@ -1,4 +1,6 @@
+import React from "react";
import { ActiveView } from "../context/AppContext";
+import { useFeatureFlags, getFlag } from "../featureFlags";
interface Props {
activeView: ActiveView;
@@ -48,7 +50,19 @@ const navItems: { view: ActiveView; label: string; icon: JSX.Element }[] = [
},
];
+const FLAG_FOR_VIEW: Partial> = {
+ tada: "moments",
+};
+
export function Sidebar({ activeView, connected, onNavigate }: Props) {
+ const featureFlags = useFeatureFlags();
+
+ const visibleItems = navItems.filter(({ view }) => {
+ const flag = FLAG_FOR_VIEW[view];
+ if (flag && !getFlag(featureFlags, flag)) return false;
+ return true;
+ });
+
return (