pi-mega-compact 0.20.59 → 0.20.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/vector-cortex-dash-0c.js +23 -0
- package/dist/config/vector-cortex-dash-0d.js +26 -0
- package/dist/config/vector-cortex.js +4 -0
- package/dist/config.js +1 -1
- package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +2 -0
- package/dist/src/config/vector-cortex-dash-0c.js +23 -0
- package/dist/src/config/vector-cortex-dash-0d.js +26 -0
- package/dist/src/config/vector-cortex.js +4 -0
- package/dist/src/config.js +1 -1
- package/extensions/dashboard-client/dist/assets/AdminTab-DEjVnlwe.js +2 -0
- package/extensions/dashboard-client/dist/assets/AdminTab-DEjVnlwe.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{AreaChart-GTwQxOAm.js → AreaChart-B1PoTqKJ.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AreaChart-GTwQxOAm.js.map → AreaChart-B1PoTqKJ.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{BarChart-BFqUD5L4.js → BarChart-DaoONT_V.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{BarChart-BFqUD5L4.js.map → BarChart-DaoONT_V.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/CacheTab-rD5sjlkW.js +2 -0
- package/extensions/dashboard-client/dist/assets/CacheTab-rD5sjlkW.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/ConfigTab-BQkufK7t.js +2 -0
- package/extensions/dashboard-client/dist/assets/ConfigTab-BQkufK7t.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{EventsTab-BYLh6cud.js → EventsTab-DGlQzJaT.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-BYLh6cud.js.map → EventsTab-DGlQzJaT.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-CkJXEbjn.js → HealthTab-DW7kt4qm.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-CkJXEbjn.js.map → HealthTab-DW7kt4qm.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/MaintenanceTab-CGiZ0OQ6.js +2 -0
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-Lm3v0nJO.js.map → MaintenanceTab-CGiZ0OQ6.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/MemoryMapTab-BwyrxjuW.js +2 -0
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-C8AeBIQi.js.map → MemoryMapTab-BwyrxjuW.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsTab-m410T4vk.js → MetricsCards-IZaCOOXU.js} +2 -2
- package/extensions/dashboard-client/dist/assets/MetricsCards-IZaCOOXU.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/MetricsTab-wCxVpHlC.js +2 -0
- package/extensions/dashboard-client/dist/assets/MetricsTab-wCxVpHlC.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{OverviewTab-BfDfMFXx.js → OverviewTab-DsH08Wr0.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-BfDfMFXx.js.map → OverviewTab-DsH08Wr0.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-CsFxxqJ6.js → ReposTab-Dpb7sXWB.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-CsFxxqJ6.js.map → ReposTab-Dpb7sXWB.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/SessionsTab-DFMo7tKA.js +2 -0
- package/extensions/dashboard-client/dist/assets/SessionsTab-DFMo7tKA.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/SetupTab-D2IEBt1u.js +3 -0
- package/extensions/dashboard-client/dist/assets/SetupTab-D2IEBt1u.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-BkRzjyRm.js → TimeSavedCard-BGPvmVFG.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-BkRzjyRm.js.map → TimeSavedCard-BGPvmVFG.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/TurnMemoryView-BZo09Jri.js +5 -0
- package/extensions/dashboard-client/dist/assets/TurnMemoryView-BZo09Jri.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/TurnsTab-CosKNvMp.js +2 -0
- package/extensions/dashboard-client/dist/assets/TurnsTab-CosKNvMp.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-B8B8RStV.js → VcStatusBadge-UEZLL6Zj.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-B8B8RStV.js.map → VcStatusBadge-UEZLL6Zj.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-CrGANNd_.js → VectorCortexTab-fDAgD2pN.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-CrGANNd_.js.map → VectorCortexTab-fDAgD2pN.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{WikiTab-DyD0yGzI.js → WikiTab-7TIe2MkS.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{WikiTab-DyD0yGzI.js.map → WikiTab-7TIe2MkS.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/button-C9qrZYdn.js +2 -0
- package/extensions/dashboard-client/dist/assets/{button-Bynl3ONj.js.map → button-C9qrZYdn.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{card-Daf3pQIu.js → card-DxZRNC4E.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{card-Daf3pQIu.js.map → card-DxZRNC4E.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/client-extra-Dj7wJs6Z.js +2 -0
- package/extensions/dashboard-client/dist/assets/{client-extra-DqAYZBW1.js.map → client-extra-Dj7wJs6Z.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-B-fe5jjr.js → generateCategoricalChart-Dj-DYUgL.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-B-fe5jjr.js.map → generateCategoricalChart-Dj-DYUgL.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{index-Bjvv23bp.js → index-Bq2n15a4.js} +31 -31
- package/extensions/dashboard-client/dist/assets/index-Bq2n15a4.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/switch-1sEgLPHu.js +2 -0
- package/extensions/dashboard-client/dist/assets/{switch-CivyERPS.js.map → switch-1sEgLPHu.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/toggle-jMzQoJ2C.js +2 -0
- package/extensions/dashboard-client/dist/assets/{toggle-qmdkrAgF.js.map → toggle-jMzQoJ2C.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{useSSE-uNuduyGe.js → useSSE-Dxy616R1.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-uNuduyGe.js.map → useSSE-Dxy616R1.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-client/src/App.tsx +150 -17
- package/extensions/dashboard-client/src/tabs/AdminTab.tsx +81 -0
- package/extensions/dashboard-client/src/tabs/CacheTab/MetricsCards.tsx +66 -0
- package/extensions/dashboard-client/src/tabs/CacheTab.tsx +46 -0
- package/extensions/dashboard-client/src/tabs/MetricsTab.tsx +10 -51
- package/extensions/dashboard-client/src/tabs/SetupTab.tsx +33 -4
- package/extensions/dashboard-client/src/tabs/TurnsTab.tsx +9 -366
- package/extensions/dashboard-client/src/tabs/dashHashRouter.ts +76 -0
- package/extensions/dashboard-client/src/tabs/index.ts +7 -6
- package/extensions/dashboard-client/src/tabs/registry.ts +26 -1
- package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +12 -0
- package/package.json +1 -1
- package/src/config/vector-cortex-dash-0c.ts +25 -0
- package/src/config/vector-cortex-dash-0d.ts +28 -0
- package/src/config/vector-cortex.ts +4 -0
- package/src/config.ts +2 -0
- package/extensions/dashboard-client/dist/assets/CacheTab-BLM6_PQQ.js +0 -2
- package/extensions/dashboard-client/dist/assets/CacheTab-BLM6_PQQ.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/HydeDetailPanel-Dt9T7kc5.js +0 -5
- package/extensions/dashboard-client/dist/assets/HydeDetailPanel-Dt9T7kc5.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/MaintenanceTab-Lm3v0nJO.js +0 -2
- package/extensions/dashboard-client/dist/assets/MemoryMapTab-C8AeBIQi.js +0 -2
- package/extensions/dashboard-client/dist/assets/MetricsTab-m410T4vk.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/SessionsTab-DstDOzwu.js +0 -2
- package/extensions/dashboard-client/dist/assets/SessionsTab-DstDOzwu.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/SetupTab-DVT4PrH0.js +0 -3
- package/extensions/dashboard-client/dist/assets/SetupTab-DVT4PrH0.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/TurnsTab-D5QTnv52.js +0 -2
- package/extensions/dashboard-client/dist/assets/TurnsTab-D5QTnv52.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/button-Bynl3ONj.js +0 -2
- package/extensions/dashboard-client/dist/assets/client-extra-DqAYZBW1.js +0 -2
- package/extensions/dashboard-client/dist/assets/index-Bjvv23bp.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/switch-CivyERPS.js +0 -2
- package/extensions/dashboard-client/dist/assets/toggle-qmdkrAgF.js +0 -2
|
@@ -4,39 +4,53 @@
|
|
|
4
4
|
* SPRINT-B1: React scaffold with tab routing, header, error boundary.
|
|
5
5
|
* SPRINT-C1+: tabs wired progressively with real content.
|
|
6
6
|
* SPRINT-V2: NEW_UI flag splits OldDashboard (legacy) from NewDashboard (AppShell).
|
|
7
|
+
* DASH-0d: the `TabContent` lazy list + switch consolidate onto the 7 fixed
|
|
8
|
+
* navigational surfaces (Overview, Sessions, Cache+Performance, Memory Graph,
|
|
9
|
+
* Diagnostics, Setup, Admin) behind MEGACOMPACT_DASH_0D. An additive hash router
|
|
10
|
+
* maps every legacy #deep-link to a live consolidated surface. Flag-OFF
|
|
11
|
+
* reproduces the pre-rollup 13-tab surface list byte-identically (the
|
|
12
|
+
* DASH-0D-LEGACY region). The consolidated rendering is the DASH-0D-CONSOLIDATED
|
|
13
|
+
* region — both are parsed by scripts/dash-tab-count.mjs.
|
|
7
14
|
*/
|
|
8
15
|
|
|
9
|
-
import React, { useState, useCallback } from "react";
|
|
16
|
+
import React, { useState, useEffect, useCallback } from "react";
|
|
10
17
|
import { ErrorBoundary } from "./components/ErrorBoundary";
|
|
11
18
|
import { TabBar } from "./components/TabBar";
|
|
12
19
|
import { LoadingSpinner } from "./components/LoadingSpinner";
|
|
13
20
|
import { useApi } from "./hooks/useApi";
|
|
14
|
-
import { fetchSnapshot } from "./api/client";
|
|
15
|
-
import type { SnapshotResponse } from "@contracts";
|
|
21
|
+
import { fetchSnapshot, fetchSettings } from "./api/client";
|
|
22
|
+
import type { SnapshotResponse, SettingsResponse } from "@contracts";
|
|
16
23
|
import { NEW_UI } from "./config";
|
|
17
24
|
import { AppShell } from "./components/layout/AppShell";
|
|
18
25
|
import {
|
|
19
26
|
PRIMARY_TABS,
|
|
20
27
|
ADVANCED_TABS,
|
|
21
28
|
ADVANCED_TAB_IDS as advancedTabIds,
|
|
29
|
+
DASH_SURFACE_IDS,
|
|
30
|
+
DASH_SURFACE_LABELS,
|
|
22
31
|
type TabId,
|
|
32
|
+
type DashTabId,
|
|
23
33
|
} from "./tabs/registry";
|
|
34
|
+
import { useHashTab } from "./tabs/dashHashRouter";
|
|
24
35
|
export type { TabId };
|
|
25
36
|
|
|
26
|
-
// Tab components — lazy-loaded.
|
|
37
|
+
// Tab components — lazy-loaded. DASH-0d: the consolidated 7 host components come
|
|
38
|
+
// from the merged barrel homes; the 13 legacy-only components stay for flag-off.
|
|
27
39
|
const OverviewTab = React.lazy(() => import("./tabs/OverviewTab"));
|
|
40
|
+
const SessionsTab = React.lazy(() => import("./tabs/SessionsTab"));
|
|
41
|
+
const CacheTab = React.lazy(() => import("./tabs/CacheTab"));
|
|
42
|
+
const MemoryMapTab = React.lazy(() => import("./tabs/MemoryMapTab"));
|
|
43
|
+
const VectorCortexTab = React.lazy(() => import("./tabs/VectorCortexTab"));
|
|
44
|
+
const SetupTab = React.lazy(() => import("./tabs/SetupTab"));
|
|
45
|
+
const AdminTab = React.lazy(() => import("./tabs/AdminTab"));
|
|
46
|
+
// Legacy-only host components (flag-off pre-rollup surface set).
|
|
28
47
|
const ReposTab = React.lazy(() => import("./tabs/ReposTab"));
|
|
29
48
|
const EventsTab = React.lazy(() => import("./tabs/EventsTab"));
|
|
30
|
-
const SetupTab = React.lazy(() => import("./tabs/SetupTab"));
|
|
31
49
|
const MetricsTab = React.lazy(() => import("./tabs/MetricsTab"));
|
|
32
|
-
const CacheTab = React.lazy(() => import("./tabs/CacheTab"));
|
|
33
|
-
const SessionsTab = React.lazy(() => import("./tabs/SessionsTab"));
|
|
34
50
|
const WikiTab = React.lazy(() => import("./tabs/WikiTab"));
|
|
35
51
|
const TurnsTab = React.lazy(() => import("./tabs/TurnsTab"));
|
|
36
52
|
const MaintenanceTab = React.lazy(() => import("./tabs/MaintenanceTab"));
|
|
37
|
-
const MemoryMapTab = React.lazy(() => import("./tabs/MemoryMapTab"));
|
|
38
53
|
const HealthTab = React.lazy(() => import("./tabs/HealthTab"));
|
|
39
|
-
const VectorCortexTab = React.lazy(() => import("./tabs/VectorCortexTab"));
|
|
40
54
|
|
|
41
55
|
interface AppState {
|
|
42
56
|
snapshot: SnapshotResponse | null;
|
|
@@ -44,7 +58,52 @@ interface AppState {
|
|
|
44
58
|
error: Error | null;
|
|
45
59
|
}
|
|
46
60
|
|
|
47
|
-
|
|
61
|
+
const DASH_0D_KEY = "MEGACOMPACT_DASH_0D";
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Resolve the DASH-0d consolidation flag from the server-authoritative
|
|
65
|
+
* `/api/rag-settings` state (the dashboard client has no `process` global).
|
|
66
|
+
* Absent/not-yet-loaded => true (default ON), matching the server default.
|
|
67
|
+
*/
|
|
68
|
+
function dash0dEnabled(settings: SettingsResponse | null): boolean {
|
|
69
|
+
if (!settings) return true;
|
|
70
|
+
for (const cat of settings.categories) {
|
|
71
|
+
for (const s of cat.settings) {
|
|
72
|
+
if (s.key === DASH_0D_KEY && s.type === "boolean") return s.value === true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** The unified active-tab state: a legacy 13-tab TabId OR a consolidated surface. */
|
|
79
|
+
type ActiveTab = TabId | DashTabId;
|
|
80
|
+
|
|
81
|
+
/** Consolidated 7-surface content (DASH-0d). Parsed by scripts/dash-tab-count.mjs. */
|
|
82
|
+
function ConsolidatedContent({
|
|
83
|
+
activeTab,
|
|
84
|
+
snapshot,
|
|
85
|
+
loading,
|
|
86
|
+
error,
|
|
87
|
+
}: AppState & { activeTab: DashTabId }): React.ReactElement {
|
|
88
|
+
return (
|
|
89
|
+
<React.Suspense fallback={<LoadingSpinner />}>
|
|
90
|
+
{/* DASH-0D-CONSOLIDATED */}
|
|
91
|
+
{activeTab === "overview" && (
|
|
92
|
+
<OverviewTab snapshot={snapshot} loading={loading} error={error} />
|
|
93
|
+
)}
|
|
94
|
+
{activeTab === "sessions" && <SessionsTab />}
|
|
95
|
+
{activeTab === "cache-perf" && <CacheTab />}
|
|
96
|
+
{activeTab === "memory-graph" && <MemoryMapTab />}
|
|
97
|
+
{activeTab === "diagnostics" && <VectorCortexTab />}
|
|
98
|
+
{activeTab === "setup" && <SetupTab />}
|
|
99
|
+
{activeTab === "admin" && <AdminTab />}
|
|
100
|
+
{/* DASH-0D-CONSOLIDATED-END */}
|
|
101
|
+
</React.Suspense>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Pre-rollup 13-tab content (flag-off). Parsed by scripts/dash-tab-count.mjs. */
|
|
106
|
+
function LegacyContent({
|
|
48
107
|
activeTab,
|
|
49
108
|
snapshot,
|
|
50
109
|
loading,
|
|
@@ -52,6 +111,7 @@ function TabContent({
|
|
|
52
111
|
}: AppState & { activeTab: TabId }): React.ReactElement {
|
|
53
112
|
return (
|
|
54
113
|
<React.Suspense fallback={<LoadingSpinner />}>
|
|
114
|
+
{/* DASH-0D-LEGACY */}
|
|
55
115
|
{activeTab === "overview" && (
|
|
56
116
|
<OverviewTab snapshot={snapshot} loading={loading} error={error} />
|
|
57
117
|
)}
|
|
@@ -67,6 +127,7 @@ function TabContent({
|
|
|
67
127
|
{activeTab === "memory-map" && <MemoryMapTab />}
|
|
68
128
|
{activeTab === "health" && <HealthTab />}
|
|
69
129
|
{activeTab === "vector-cortex" && <VectorCortexTab />}
|
|
130
|
+
{/* DASH-0D-LEGACY-END */}
|
|
70
131
|
</React.Suspense>
|
|
71
132
|
);
|
|
72
133
|
}
|
|
@@ -102,7 +163,7 @@ function OldDashboard({
|
|
|
102
163
|
onTabChange={setActiveTab}
|
|
103
164
|
/>
|
|
104
165
|
<main className="dashboard-content">
|
|
105
|
-
<
|
|
166
|
+
<LegacyContent activeTab={activeTab} snapshot={snapshot} loading={loading} error={error} />
|
|
106
167
|
</main>
|
|
107
168
|
</div>
|
|
108
169
|
</ErrorBoundary>
|
|
@@ -122,14 +183,40 @@ function NewDashboard({
|
|
|
122
183
|
return (
|
|
123
184
|
<ErrorBoundary>
|
|
124
185
|
<AppShell active={activeTab} onTabChange={setActiveTab} snapshot={snapshot}>
|
|
125
|
-
<
|
|
186
|
+
<LegacyContent activeTab={activeTab} snapshot={snapshot} loading={loading} error={error} />
|
|
126
187
|
</AppShell>
|
|
127
188
|
</ErrorBoundary>
|
|
128
189
|
);
|
|
129
190
|
}
|
|
130
191
|
|
|
192
|
+
/** DASH-0d consolidated 7-surface navigation rail (flag-ON New UI path). */
|
|
193
|
+
function ConsolidatedNav({
|
|
194
|
+
active,
|
|
195
|
+
onSelect,
|
|
196
|
+
}: {
|
|
197
|
+
active: DashTabId;
|
|
198
|
+
onSelect: (id: DashTabId) => void;
|
|
199
|
+
}): React.ReactElement {
|
|
200
|
+
return (
|
|
201
|
+
<nav className="consolidated-nav" role="tablist" aria-label="Dashboard surfaces">
|
|
202
|
+
{DASH_SURFACE_IDS.map((id) => (
|
|
203
|
+
<button
|
|
204
|
+
key={id}
|
|
205
|
+
type="button"
|
|
206
|
+
role="tab"
|
|
207
|
+
aria-selected={active === id}
|
|
208
|
+
className={active === id ? "active" : ""}
|
|
209
|
+
onClick={() => onSelect(id)}
|
|
210
|
+
>
|
|
211
|
+
{DASH_SURFACE_LABELS[id] ?? id}
|
|
212
|
+
</button>
|
|
213
|
+
))}
|
|
214
|
+
</nav>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
131
218
|
export default function App(): React.ReactElement {
|
|
132
|
-
const [activeTab, setActiveTab] = useState<
|
|
219
|
+
const [activeTab, setActiveTab] = useState<ActiveTab>("overview");
|
|
133
220
|
const {
|
|
134
221
|
data: snapshot,
|
|
135
222
|
loading,
|
|
@@ -142,11 +229,57 @@ export default function App(): React.ReactElement {
|
|
|
142
229
|
},
|
|
143
230
|
);
|
|
144
231
|
|
|
232
|
+
// Server-resolved DASH-0d flag (default ON when settings absent).
|
|
233
|
+
const { data: settingsData } = useApi<SettingsResponse>(
|
|
234
|
+
useCallback(() => fetchSettings(), []),
|
|
235
|
+
{ pollInterval: 0, maxRetries: 0 },
|
|
236
|
+
);
|
|
237
|
+
const dash0dOn = dash0dEnabled(settingsData);
|
|
238
|
+
|
|
239
|
+
// Additive hash→surface deep-link router: every legacy #hash maps to a live
|
|
240
|
+
// consolidated surface; empty hash keeps current behavior (default overview).
|
|
241
|
+
// Only active under the DASH-0d 7-surface rendering — flag-off keeps the
|
|
242
|
+
// pre-rollup 13-tab behavior unchanged (hash ignored).
|
|
243
|
+
const hashSurface = useHashTab();
|
|
244
|
+
useEffect(() => {
|
|
245
|
+
if (dash0dOn && hashSurface != null) setActiveTab(hashSurface);
|
|
246
|
+
}, [dash0dOn, hashSurface]);
|
|
247
|
+
|
|
248
|
+
// Flag-ON consolidated New-UI surface: a 7-surface rail + the consolidated
|
|
249
|
+
// content. Flag-OFF (or legacy NEW_UI false) renders the 13-tab path as today.
|
|
250
|
+
if (NEW_UI() && dash0dOn) {
|
|
251
|
+
const current = DASH_SURFACE_IDS.includes(activeTab as DashTabId)
|
|
252
|
+
? (activeTab as DashTabId)
|
|
253
|
+
: "overview";
|
|
254
|
+
return (
|
|
255
|
+
<ErrorBoundary>
|
|
256
|
+
<div className="dashboard-app">
|
|
257
|
+
<header className="dashboard-header">
|
|
258
|
+
<h1>mega-compact dashboard <span className="tier">{snapshot?.tier ?? "unknown"}</span></h1>
|
|
259
|
+
</header>
|
|
260
|
+
<ConsolidatedNav active={current} onSelect={(id: DashTabId) => setActiveTab(id)} />
|
|
261
|
+
<main className="dashboard-content">
|
|
262
|
+
<ConsolidatedContent
|
|
263
|
+
activeTab={current}
|
|
264
|
+
snapshot={snapshot}
|
|
265
|
+
loading={loading}
|
|
266
|
+
error={error}
|
|
267
|
+
/>
|
|
268
|
+
</main>
|
|
269
|
+
</div>
|
|
270
|
+
</ErrorBoundary>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Flag-off (or legacy NEW_UI): always a legacy TabId (hash routing is gated
|
|
275
|
+
// on dash0dOn above, so activeTab stays a 13-tab id here).
|
|
276
|
+
const legacyTab = (activeTab as TabId) ?? "overview";
|
|
277
|
+
|
|
145
278
|
if (NEW_UI()) {
|
|
146
279
|
return (
|
|
147
280
|
<NewDashboard
|
|
148
|
-
activeTab={
|
|
149
|
-
setActiveTab={setActiveTab}
|
|
281
|
+
activeTab={legacyTab}
|
|
282
|
+
setActiveTab={(id: TabId) => setActiveTab(id)}
|
|
150
283
|
snapshot={snapshot}
|
|
151
284
|
loading={loading}
|
|
152
285
|
error={error}
|
|
@@ -156,8 +289,8 @@ export default function App(): React.ReactElement {
|
|
|
156
289
|
|
|
157
290
|
return (
|
|
158
291
|
<OldDashboard
|
|
159
|
-
activeTab={
|
|
160
|
-
setActiveTab={setActiveTab}
|
|
292
|
+
activeTab={legacyTab}
|
|
293
|
+
setActiveTab={(id: TabId) => setActiveTab(id)}
|
|
161
294
|
snapshot={snapshot}
|
|
162
295
|
loading={loading}
|
|
163
296
|
error={error}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dashboard-client/src/tabs/AdminTab.tsx — Admin tab (DASH-0c delegate-shell).
|
|
3
|
+
*
|
|
4
|
+
* DASH-0c: the Admin surface combines the maintenance actions with the config
|
|
5
|
+
* editor. A `AdminViews` toggle ("maintenance" / "config") switches between
|
|
6
|
+
* `MaintenanceTab` (the maintenance shell over MaintenanceTab/*) and `ConfigTab`
|
|
7
|
+
* (the config editor). Both bodies are UNCHANGED — only their hosting changes to
|
|
8
|
+
* this new delegate-shell. `MaintenanceTab.tsx` and `ConfigTab.tsx` stay importable
|
|
9
|
+
* from their original hosts (`ConfigTab` also stays wired into SetupTab per the
|
|
10
|
+
* dual-host note). Flag-ON renders the toggle + both views; flag-OFF renders only
|
|
11
|
+
* the maintenance view (the predecessor's `admin → MaintenanceTab` mapping),
|
|
12
|
+
* and App.tsx keeps its current TabId routing this sprint (DASH-0d rewires).
|
|
13
|
+
*
|
|
14
|
+
* Flag: `MEGACOMPACT_DASH_0C` default ON. The dashboard client is a browser
|
|
15
|
+
* bundle with NO `process` global, so the positive sprint flag cannot be read
|
|
16
|
+
* server-side-style (`process.env`) inside the client. Instead the flag is read
|
|
17
|
+
* from the server-authoritative `/api/rag-settings` state: the server resolves
|
|
18
|
+
* `process.env["MEGACOMPACT_DASH_0C"] ?? default` into the `SettingState.value`
|
|
19
|
+
* boolean.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type React from "react";
|
|
23
|
+
import { useCallback, useState } from "react";
|
|
24
|
+
import type { SettingsResponse } from "@contracts";
|
|
25
|
+
import { useApi } from "../hooks/useApi";
|
|
26
|
+
import { fetchSettings } from "../api/client";
|
|
27
|
+
import { Toggle } from "../components/ui/toggle";
|
|
28
|
+
import MaintenanceTab from "./MaintenanceTab";
|
|
29
|
+
import ConfigTab from "./ConfigTab";
|
|
30
|
+
|
|
31
|
+
const DASH_0C_KEY = "MEGACOMPACT_DASH_0C";
|
|
32
|
+
|
|
33
|
+
/** Resolve the DASH-0c consolidation flag from the server settings state.
|
|
34
|
+
* Absent/not-yet-loaded => false (flag-off posture), so flag-off users never
|
|
35
|
+
* see the toggle flash; the toggle appears only once settings confirm it is ON. */
|
|
36
|
+
function dash0cEnabled(settings: SettingsResponse | null): boolean {
|
|
37
|
+
if (!settings) return false;
|
|
38
|
+
for (const cat of settings.categories) {
|
|
39
|
+
for (const s of cat.settings) {
|
|
40
|
+
if (s.key === DASH_0C_KEY && s.type === "boolean") return s.value === true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type AdminViews = "maintenance" | "config";
|
|
47
|
+
|
|
48
|
+
export default function AdminTab(): React.ReactElement {
|
|
49
|
+
const [view, setView] = useState<AdminViews>("maintenance");
|
|
50
|
+
|
|
51
|
+
const { data: settingsData } = useApi<SettingsResponse>(
|
|
52
|
+
useCallback(() => fetchSettings(), []),
|
|
53
|
+
{ pollInterval: 0, maxRetries: 0 },
|
|
54
|
+
);
|
|
55
|
+
const dash0cOn = dash0cEnabled(settingsData);
|
|
56
|
+
|
|
57
|
+
if (!dash0cOn) {
|
|
58
|
+
return <MaintenanceTab />;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<div className="flex flex-col gap-4">
|
|
63
|
+
<div
|
|
64
|
+
className="flex items-center gap-2"
|
|
65
|
+
role="tablist"
|
|
66
|
+
aria-label="Admin views"
|
|
67
|
+
>
|
|
68
|
+
<Toggle
|
|
69
|
+
pressed={view === "maintenance"}
|
|
70
|
+
onClick={() => setView("maintenance")}
|
|
71
|
+
>
|
|
72
|
+
Maintenance
|
|
73
|
+
</Toggle>
|
|
74
|
+
<Toggle pressed={view === "config"} onClick={() => setView("config")}>
|
|
75
|
+
Config
|
|
76
|
+
</Toggle>
|
|
77
|
+
</div>
|
|
78
|
+
{view === "maintenance" ? <MaintenanceTab /> : <ConfigTab />}
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dashboard-client/src/tabs/CacheTab/MetricsCards.tsx — Performance cards (C2),
|
|
3
|
+
* moved VERBATIM from the top-level MetricsTab.tsx.
|
|
4
|
+
*
|
|
5
|
+
* DASH-0c: the Cache+Performance surface absorbs MetricsTab as a Performance
|
|
6
|
+
* section. This file holds the byte-preserved metrics body (the `MetricsCards`
|
|
7
|
+
* component). The standalone `tabs/MetricsTab.tsx` is reduced to a shell that
|
|
8
|
+
* re-exports it (kept for the #metrics deep-link + rollback symmetry). Only the
|
|
9
|
+
* export name changed (MetricsTab → MetricsCards); the render body is otherwise
|
|
10
|
+
* identical.
|
|
11
|
+
*
|
|
12
|
+
* Fetches /api/perf (rolling-window aggregates) + /api/snapshot (for model).
|
|
13
|
+
* Renders ModelBadge + PerfChart + 5 perf cards (latency, throughput, process,
|
|
14
|
+
* snapshot cost, TUI lag proxy). Polls every 10s.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type React from "react";
|
|
18
|
+
import { useCallback } from "react";
|
|
19
|
+
import { useApi } from "../../hooks/useApi";
|
|
20
|
+
import { fetchPerf, fetchSnapshot } from "../../api/client";
|
|
21
|
+
import type { PerfResponse, SnapshotResponse } from "@contracts";
|
|
22
|
+
import { NEW_UI } from "../../config";
|
|
23
|
+
import { PerfChart } from "../../components/PerfChart";
|
|
24
|
+
import { PerfCards } from "../../components/PerfCards";
|
|
25
|
+
import { ModelBadge } from "../../components/ModelBadge";
|
|
26
|
+
import { RagDashboard } from "../../components/RagDashboard";
|
|
27
|
+
|
|
28
|
+
export function MetricsCards(): React.ReactElement {
|
|
29
|
+
const { data: perf, error: perfErr } = useApi<PerfResponse>(
|
|
30
|
+
useCallback(() => fetchPerf({ minutes: 30 }), []),
|
|
31
|
+
{ pollInterval: 10_000 },
|
|
32
|
+
);
|
|
33
|
+
const { data: snapshot } = useApi<SnapshotResponse>(
|
|
34
|
+
useCallback(() => fetchSnapshot(), []),
|
|
35
|
+
{ pollInterval: 10_000 },
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
if (perfErr && !perf) {
|
|
39
|
+
return (
|
|
40
|
+
<div className="tab-stub">Error loading perf: {perfErr.message}</div>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
if (!perf) {
|
|
44
|
+
return <div className="tab-stub">Loading perf…</div>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div className="flex flex-col gap-4">
|
|
49
|
+
{snapshot?.model && (
|
|
50
|
+
<ModelBadge
|
|
51
|
+
name={snapshot.model.name}
|
|
52
|
+
providerName={snapshot.model.providerName}
|
|
53
|
+
provider={snapshot.model.provider}
|
|
54
|
+
inputRate={snapshot.model.inputRate}
|
|
55
|
+
outputRate={snapshot.model.outputRate}
|
|
56
|
+
/>
|
|
57
|
+
)}
|
|
58
|
+
<PerfChart perf={perf} />
|
|
59
|
+
<PerfCards perf={perf} />
|
|
60
|
+
<div className="text-xs text-muted-foreground">
|
|
61
|
+
{perf.sampleCount} samples · updated {perf.updatedAt}
|
|
62
|
+
</div>
|
|
63
|
+
{NEW_UI() && <RagDashboard />}
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
@@ -18,6 +18,7 @@ import type {
|
|
|
18
18
|
CacheStripesResponse,
|
|
19
19
|
PerfResponse,
|
|
20
20
|
PrefixStabilityResponse,
|
|
21
|
+
SettingsResponse,
|
|
21
22
|
} from "@contracts";
|
|
22
23
|
import { useApi } from "../hooks/useApi";
|
|
23
24
|
import {
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
fetchCacheStripes,
|
|
27
28
|
fetchPrefixStability,
|
|
28
29
|
fetchPerf,
|
|
30
|
+
fetchSettings,
|
|
29
31
|
} from "../api/client";
|
|
30
32
|
import { CacheHitsCard } from "../components/CacheHitsCard";
|
|
31
33
|
import { TimeSavedCard } from "../components/TimeSavedCard";
|
|
@@ -35,6 +37,25 @@ import { CacheHitRateTrendCard } from "../components/CacheHitRateTrendCard";
|
|
|
35
37
|
import { PrefixStabilityCard } from "../components/PrefixStabilityCard";
|
|
36
38
|
import { Button } from "../components/ui/button";
|
|
37
39
|
import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card";
|
|
40
|
+
import { MetricsCards } from "./CacheTab/MetricsCards";
|
|
41
|
+
|
|
42
|
+
const DASH_0C_KEY = "MEGACOMPACT_DASH_0C";
|
|
43
|
+
|
|
44
|
+
/** Resolve the DASH-0c consolidation flag from the server settings state.
|
|
45
|
+
* The dashboard client is a browser bundle with NO `process` global, so the
|
|
46
|
+
* positive sprint flag is read from the server-authoritative /api/rag-settings
|
|
47
|
+
* state (the server resolves MEGACOMPACT_DASH_0C into a SettingState boolean).
|
|
48
|
+
* Absent/not-yet-loaded => false (flag-off posture), so flag-off users never
|
|
49
|
+
* see the Performance section flash; it mounts only once settings confirm ON. */
|
|
50
|
+
function dash0cEnabled(settings: SettingsResponse | null): boolean {
|
|
51
|
+
if (!settings) return false;
|
|
52
|
+
for (const cat of settings.categories) {
|
|
53
|
+
for (const s of cat.settings) {
|
|
54
|
+
if (s.key === DASH_0C_KEY && s.type === "boolean") return s.value === true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
38
59
|
|
|
39
60
|
export default function CacheTab(): React.ReactElement {
|
|
40
61
|
const [infoExpanded, setInfoExpanded] = useState(false);
|
|
@@ -87,6 +108,13 @@ export default function CacheTab(): React.ReactElement {
|
|
|
87
108
|
{ pollInterval: 5000 },
|
|
88
109
|
);
|
|
89
110
|
|
|
111
|
+
/* --- DASH-0c: server-resolved settings state for the flag gate --- */
|
|
112
|
+
const { data: settingsData } = useApi<SettingsResponse>(
|
|
113
|
+
useCallback(() => fetchSettings(), []),
|
|
114
|
+
{ pollInterval: 0, maxRetries: 0 },
|
|
115
|
+
);
|
|
116
|
+
const dash0cOn = dash0cEnabled(settingsData);
|
|
117
|
+
|
|
90
118
|
return (
|
|
91
119
|
<div className="flex flex-col gap-4">
|
|
92
120
|
<div>
|
|
@@ -223,6 +251,24 @@ export default function CacheTab(): React.ReactElement {
|
|
|
223
251
|
);
|
|
224
252
|
})()
|
|
225
253
|
)}
|
|
254
|
+
{/* ==============================================================
|
|
255
|
+
Section 5 -- Performance (DASH-0c)
|
|
256
|
+
The metrics body (ModelBadge + PerfChart + PerfCards + RagDashboard)
|
|
257
|
+
absorbed from MetricsTab as a Performance section. Moved VERBATIM to
|
|
258
|
+
./CacheTab/MetricsCards.tsx. Omitted entirely when flag-off so the
|
|
259
|
+
cache-only body is byte-identical to the predecessor.
|
|
260
|
+
============================================================== */}
|
|
261
|
+
{dash0cOn && (
|
|
262
|
+
<section aria-labelledby="cache-perf-cards">
|
|
263
|
+
<h2
|
|
264
|
+
id="cache-perf-cards"
|
|
265
|
+
className="font-heading text-lg font-semibold"
|
|
266
|
+
>
|
|
267
|
+
Performance
|
|
268
|
+
</h2>
|
|
269
|
+
<MetricsCards />
|
|
270
|
+
</section>
|
|
271
|
+
)}
|
|
226
272
|
</div>
|
|
227
273
|
);
|
|
228
274
|
}
|
|
@@ -1,58 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* dashboard-client/src/tabs/MetricsTab.tsx — Metrics tab (C2).
|
|
2
|
+
* dashboard-client/src/tabs/MetricsTab.tsx — Metrics tab (C2) shell.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* DASH-0c: the Cache+Performance surface absorbs the metrics body as a
|
|
5
|
+
* Performance section; this file is reduced to a shell that re-exports
|
|
6
|
+
* `MetricsCards` (the byte-preserved body moved to ./CacheTab/MetricsCards.tsx).
|
|
7
|
+
* Kept as a deep-link anchor for #metrics and for rollback symmetry (flag-off
|
|
8
|
+
* renders MetricsTab as a standalone top-level surface). A DASH-0d cleanup deletes
|
|
9
|
+
* this standalone copy after a deep-link audit proves no live consumer points
|
|
10
|
+
* at it. The render body is otherwise identical to the pre-DASH-0c MetricsTab.
|
|
7
11
|
*/
|
|
8
12
|
|
|
9
|
-
import
|
|
10
|
-
import { useCallback } from "react";
|
|
11
|
-
import { useApi } from "../hooks/useApi";
|
|
12
|
-
import { fetchPerf, fetchSnapshot } from "../api/client";
|
|
13
|
-
import type { PerfResponse, SnapshotResponse } from "@contracts";
|
|
14
|
-
import { NEW_UI } from "../config";
|
|
15
|
-
import { PerfChart } from "../components/PerfChart";
|
|
16
|
-
import { PerfCards } from "../components/PerfCards";
|
|
17
|
-
import { ModelBadge } from "../components/ModelBadge";
|
|
18
|
-
import { RagDashboard } from "../components/RagDashboard";
|
|
13
|
+
import { MetricsCards } from "./CacheTab/MetricsCards";
|
|
19
14
|
|
|
20
15
|
export default function MetricsTab(): React.ReactElement {
|
|
21
|
-
|
|
22
|
-
useCallback(() => fetchPerf({ minutes: 30 }), []),
|
|
23
|
-
{ pollInterval: 10_000 },
|
|
24
|
-
);
|
|
25
|
-
const { data: snapshot } = useApi<SnapshotResponse>(
|
|
26
|
-
useCallback(() => fetchSnapshot(), []),
|
|
27
|
-
{ pollInterval: 10_000 },
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
if (perfErr && !perf) {
|
|
31
|
-
return (
|
|
32
|
-
<div className="tab-stub">Error loading perf: {perfErr.message}</div>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
if (!perf) {
|
|
36
|
-
return <div className="tab-stub">Loading perf…</div>;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<div className="flex flex-col gap-4">
|
|
41
|
-
{snapshot?.model && (
|
|
42
|
-
<ModelBadge
|
|
43
|
-
name={snapshot.model.name}
|
|
44
|
-
providerName={snapshot.model.providerName}
|
|
45
|
-
provider={snapshot.model.provider}
|
|
46
|
-
inputRate={snapshot.model.inputRate}
|
|
47
|
-
outputRate={snapshot.model.outputRate}
|
|
48
|
-
/>
|
|
49
|
-
)}
|
|
50
|
-
<PerfChart perf={perf} />
|
|
51
|
-
<PerfCards perf={perf} />
|
|
52
|
-
<div className="text-xs text-muted-foreground">
|
|
53
|
-
{perf.sampleCount} samples · updated {perf.updatedAt}
|
|
54
|
-
</div>
|
|
55
|
-
{NEW_UI() && <RagDashboard />}
|
|
56
|
-
</div>
|
|
57
|
-
);
|
|
16
|
+
return <MetricsCards />;
|
|
58
17
|
}
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* no external network calls.
|
|
11
11
|
*/
|
|
12
12
|
import type React from "react";
|
|
13
|
-
import { useState, useMemo } from "react";
|
|
13
|
+
import { useState, useMemo, useCallback } from "react";
|
|
14
|
+
import type { SettingsResponse } from "@contracts";
|
|
14
15
|
import GameTab from "./GameTab";
|
|
15
16
|
import AchievementsTab from "./AchievementsTab";
|
|
16
17
|
import ConfigTab from "./ConfigTab";
|
|
@@ -18,8 +19,26 @@ import EmbedderSetup from "./SetupTab/EmbedderSetup";
|
|
|
18
19
|
import ThresholdsPanel from "./SetupTab/ThresholdsPanel";
|
|
19
20
|
import CortexSetup from "./SetupTab/CortexSetup";
|
|
20
21
|
import { Toggle } from "../components/ui/toggle";
|
|
22
|
+
import { useApi } from "../hooks/useApi";
|
|
23
|
+
import { fetchSettings } from "../api/client";
|
|
21
24
|
import { useSetupCortexPoll, isCortexSubTabVisible } from "./useSetupCortexPoll";
|
|
22
25
|
|
|
26
|
+
const DASH_0C_KEY = "MEGACOMPACT_DASH_0C";
|
|
27
|
+
|
|
28
|
+
/** Resolve the DASH-0c consolidation flag from the server settings state.
|
|
29
|
+
* Absent/not-yet-loaded => false (flag-off posture), so flag-off users keep the
|
|
30
|
+
* Config sub-tab; it is hidden only once settings confirm the flag is ON (the
|
|
31
|
+
* config editor then lives solely on the Admin surface). */
|
|
32
|
+
function dash0cEnabled(settings: SettingsResponse | null): boolean {
|
|
33
|
+
if (!settings) return false;
|
|
34
|
+
for (const cat of settings.categories) {
|
|
35
|
+
for (const s of cat.settings) {
|
|
36
|
+
if (s.key === DASH_0C_KEY && s.type === "boolean") return s.value === true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
23
42
|
type SetupSubTab =
|
|
24
43
|
| "embedder"
|
|
25
44
|
| "thresholds"
|
|
@@ -43,11 +62,21 @@ export default function SetupTab(): React.ReactElement {
|
|
|
43
62
|
const [subTab, setSubTab] = useState<SetupSubTab>("embedder");
|
|
44
63
|
const [cortex] = useSetupCortexPoll();
|
|
45
64
|
|
|
65
|
+
/* DASH-0c: flag-ON hides the config sub-tab member (the config editor is then
|
|
66
|
+
* reachable only via the Admin surface). Flag-OFF renders config as today. */
|
|
67
|
+
const { data: settingsData } = useApi<SettingsResponse>(
|
|
68
|
+
useCallback(() => fetchSettings(), []),
|
|
69
|
+
{ pollInterval: 0, maxRetries: 0 },
|
|
70
|
+
);
|
|
71
|
+
const dash0cOn = dash0cEnabled(settingsData);
|
|
72
|
+
|
|
46
73
|
const subTabs = useMemo(() => {
|
|
47
|
-
const tabs =
|
|
74
|
+
const tabs = dash0cOn
|
|
75
|
+
? BASE_SUB_TABS.filter((t) => t.id !== "config")
|
|
76
|
+
: [...BASE_SUB_TABS];
|
|
48
77
|
if (isCortexSubTabVisible(cortex.data)) tabs.push(CORTEX_TAB);
|
|
49
78
|
return tabs;
|
|
50
|
-
}, [cortex.data]);
|
|
79
|
+
}, [cortex.data, dash0cOn]);
|
|
51
80
|
|
|
52
81
|
return (
|
|
53
82
|
<div className="mx-auto flex max-w-3xl flex-col gap-4 p-4">
|
|
@@ -68,7 +97,7 @@ export default function SetupTab(): React.ReactElement {
|
|
|
68
97
|
|
|
69
98
|
{subTab === "embedder" && <EmbedderSetup />}
|
|
70
99
|
{subTab === "thresholds" && <ThresholdsPanel />}
|
|
71
|
-
{subTab === "config" && <ConfigTab />}
|
|
100
|
+
{subTab === "config" && !dash0cOn && <ConfigTab />}
|
|
72
101
|
{subTab === "game" && <GameTab />}
|
|
73
102
|
{subTab === "achievements" && <AchievementsTab />}
|
|
74
103
|
{subTab === "cortex" && <CortexSetup />}
|