@schandlergarcia/sf-web-components 1.9.78 → 1.9.80
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/.a4drules/skills/command-center-builder/SKILL.md +2 -1
- package/.a4drules/skills/command-center-builder/getting-started.md +20 -8
- package/.a4drules/skills/command-center-builder/improved-build-process.md +3 -2
- package/CHANGELOG.md +25 -0
- package/data/engine-command-center-prd.md +5 -4
- package/data/useEngineLiveData.ts +6 -11
- package/dist/components/library/data/useDataSource.js +6 -9
- package/dist/components/library/data/useDataSource.js.map +1 -1
- package/package.json +1 -1
- package/scripts/reset-command-center.sh +81 -15
- package/src/components/library/data/useDataSource.jsx +9 -10
- package/src/templates/lib/dataStrategy.ts.template +12 -30
- package/src/templates/workspace/CommandCenter.tsx.template +2 -1
|
@@ -43,6 +43,7 @@ export default function HomePage() {
|
|
|
43
43
|
// src/components/workspace/CommandCenter.tsx
|
|
44
44
|
import AppThemeProvider from "@/components/library/theme/AppThemeProvider";
|
|
45
45
|
import DataModeProvider from "@/components/library/data/DataModeProvider";
|
|
46
|
+
import { ENABLE_SAMPLE_DATA_CACHE } from "@/lib/dataStrategy";
|
|
46
47
|
import { Toast } from "@heroui/react";
|
|
47
48
|
import MyDashboard from "../../pages/MyDashboard"; // ← change ONLY this import
|
|
48
49
|
|
|
@@ -50,7 +51,7 @@ export default function CommandCenter() {
|
|
|
50
51
|
return (
|
|
51
52
|
<div className="heroui-scope">
|
|
52
53
|
<AppThemeProvider initialMode="light">
|
|
53
|
-
<DataModeProvider initialMode="sample">
|
|
54
|
+
<DataModeProvider initialMode={ENABLE_SAMPLE_DATA_CACHE ? "sample" : "live"}>
|
|
54
55
|
<MyDashboard />
|
|
55
56
|
<Toast.Provider placement="bottom end" />
|
|
56
57
|
</DataModeProvider>
|
|
@@ -45,19 +45,23 @@ The dashboard is built in **3 phases**, one per user prompt. Each phase adds a l
|
|
|
45
45
|
|
|
46
46
|
## Phase 2 — Connect to Live Data
|
|
47
47
|
|
|
48
|
+
**The point of Phase 2:** The dashboard switches from sample data (8 US travelers: Sarah Chen, Marcus Johnson…) to a completely different live dataset (12 global travelers: Raj Kapoor, Sofia Reyes… with a Midwest storm scenario). The user should see different names, different cities, different metrics, and different disruptions.
|
|
49
|
+
|
|
50
|
+
**How the switch works:** `ENABLE_SAMPLE_DATA_CACHE` in `src/lib/dataStrategy.ts` controls which data `useDataSource` returns. `CommandCenter.tsx` reads this flag and passes it to `DataModeProvider`. When the flag is `true` (default), mode is "sample." When `false`, mode is "live" and every `useDataSource` call returns its `live` prop instead.
|
|
51
|
+
|
|
48
52
|
**How to work:** Make surgical edits to the existing `EngineDashboard.tsx`. Do NOT rewrite the file.
|
|
49
53
|
|
|
50
54
|
**Files to read first (only these):**
|
|
51
55
|
1. `src/pages/EngineDashboard.tsx` — the Phase 1 dashboard you're editing
|
|
52
|
-
2. `src/
|
|
56
|
+
2. `src/hooks/useEngineLiveData.ts` — to see the live data shape
|
|
53
57
|
|
|
54
|
-
**Do NOT read:** `useDataSource.
|
|
58
|
+
**Do NOT read:** `useDataSource.jsx`, `DataModeProvider.jsx`, `dataStrategy.ts`, or any library component source. The patterns are right here.
|
|
55
59
|
|
|
56
60
|
**Edits to make (in order):**
|
|
57
61
|
|
|
58
62
|
1. **Add import** at the top of EngineDashboard.tsx:
|
|
59
63
|
```tsx
|
|
60
|
-
import useEngineLiveData from "@/hooks/useEngineLiveData";
|
|
64
|
+
import { useEngineLiveData } from "@/hooks/useEngineLiveData";
|
|
61
65
|
```
|
|
62
66
|
|
|
63
67
|
2. **Add hook call** inside the component, near the top:
|
|
@@ -80,9 +84,15 @@ The dashboard is built in **3 phases**, one per user prompt. Each phase adds a l
|
|
|
80
84
|
```
|
|
81
85
|
Then use `activeMetrics` in KPI overlays instead of hardcoded sample constants.
|
|
82
86
|
|
|
83
|
-
|
|
87
|
+
5. **Flip the backend switch** — change `src/lib/dataStrategy.ts`:
|
|
88
|
+
```tsx
|
|
89
|
+
export const ENABLE_SAMPLE_DATA_CACHE = false;
|
|
90
|
+
```
|
|
91
|
+
This causes `CommandCenter.tsx` to pass `initialMode="live"` to `DataModeProvider`, and every `useDataSource` call now returns the live prop. The dashboard instantly shows the live dataset on next load.
|
|
92
|
+
|
|
93
|
+
That's 5 targeted edits. Not a full rewrite.
|
|
84
94
|
|
|
85
|
-
**No UI toggle.**
|
|
95
|
+
**No UI toggle.** There is no `DataModeToggle` in the dashboard. The switch is `ENABLE_SAMPLE_DATA_CACHE` in `dataStrategy.ts`.
|
|
86
96
|
|
|
87
97
|
**After wiring — STOP and suggest (do not create yet):**
|
|
88
98
|
|
|
@@ -94,6 +104,7 @@ Only create `Flight__c.Weather_Impact__c` (PRD section 14a) AFTER the user confi
|
|
|
94
104
|
- No ChatBar or Eva — that's Phase 3
|
|
95
105
|
- No platform events or Apex — that's Phase 3
|
|
96
106
|
- Do NOT rewrite EngineDashboard.tsx from scratch
|
|
107
|
+
- Do NOT add `DataModeToggle` to the UI
|
|
97
108
|
- Do NOT read library component source files
|
|
98
109
|
- Do NOT run `npm run build` between edits
|
|
99
110
|
|
|
@@ -166,12 +177,13 @@ Only create `TravelDisruptionEventService` (PRD section 14c) AFTER the user conf
|
|
|
166
177
|
| | Phase 1 | Phase 2 | Phase 3 |
|
|
167
178
|
|---|---------|---------|---------|
|
|
168
179
|
| Dashboard layout & panels | Write new file | — | — |
|
|
169
|
-
| Sample data | Wire | — | — |
|
|
170
|
-
| Live data | Skip | Surgical edits | — |
|
|
180
|
+
| Sample data | Wire (`live: []`) | — | — |
|
|
181
|
+
| Live data wiring | Skip | Surgical edits | — |
|
|
182
|
+
| Flip `dataStrategy.ts` to `false` | Skip | Edit | — |
|
|
171
183
|
| Custom field metadata | Skip | Suggest → wait | — |
|
|
172
184
|
| ChatBar (Eva) | Skip | Skip | Surgical edit |
|
|
173
185
|
| AgentforceConversationClient | Skip | Skip | Surgical edit |
|
|
174
186
|
| Platform event | Skip | Skip | Suggest → wait |
|
|
175
187
|
| Apex service | Skip | Skip | Suggest → wait |
|
|
176
188
|
|
|
177
|
-
**
|
|
189
|
+
**Data mode control:** `ENABLE_SAMPLE_DATA_CACHE` in `src/lib/dataStrategy.ts` is the backend switch. `CommandCenter.tsx` reads this flag and passes `initialMode` to `DataModeProvider`. Phase 1 leaves it `true` (sample data). Phase 2 flips it to `false` (live data — different travelers, cities, and metrics). There is no UI toggle.
|
|
@@ -34,14 +34,15 @@ Rewriting a 400+ line file from scratch takes 60 seconds, risks losing prior wor
|
|
|
34
34
|
## Phase 2 Edit Order
|
|
35
35
|
|
|
36
36
|
```
|
|
37
|
-
1. Add useEngineLiveData import
|
|
37
|
+
1. Add useEngineLiveData import to EngineDashboard.tsx
|
|
38
38
|
2. Add const live = useEngineLiveData() hook call
|
|
39
39
|
3. Update each useDataSource({ sample, live: [] }) → live: live.xxx
|
|
40
40
|
4. Update KPI derivations to use activeMetrics
|
|
41
|
+
5. Flip ENABLE_SAMPLE_DATA_CACHE to false in src/lib/dataStrategy.ts
|
|
41
42
|
→ STOP — suggest Weather_Impact__c, wait for confirmation
|
|
42
43
|
```
|
|
43
44
|
|
|
44
|
-
No
|
|
45
|
+
No UI toggle. The switch is `ENABLE_SAMPLE_DATA_CACHE` in `dataStrategy.ts`. When `false`, `CommandCenter.tsx` passes `initialMode="live"` and every `useDataSource` returns its live prop.
|
|
45
46
|
|
|
46
47
|
## Phase 3 Edit Order
|
|
47
48
|
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.9.80] - 2026-04-04
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Reset script cleans Salesforce metadata** — `reset-command-center.sh` now removes all Apex classes (`.cls` + `.cls-meta.xml`), custom field XML, and platform event directories from `force-app/main/default/`. Walks up from the webapp root to find the SFDX project structure automatically.
|
|
12
|
+
|
|
13
|
+
**Context:** Demo phases create Apex classes (Agent*, TCC_*), custom fields (Weather_Impact__c), and platform events (Travel_Disruption_Alert__e) that need to be cleaned up when resetting for a fresh demo run.
|
|
14
|
+
|
|
15
|
+
## [1.9.79] - 2026-04-04
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- **Data mode switching was broken** — `ENABLE_SAMPLE_DATA_CACHE` in `dataStrategy.ts` was dead code (nothing read it). `useEngineLiveData` was auto-calling `setMode("live")` after 2 seconds via React context, which was fragile and confusing
|
|
19
|
+
- **No visible data change between phases** — Phase 2 should produce visibly different data (12 global travelers vs 8 US travelers, Midwest storm scenario) but the switching mechanism wasn't wired to `dataStrategy.ts`
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- **`useEngineLiveData.ts`** — Removed `setMode("sample"/"live")` calls. Hook now just provides the live data; it no longer controls the data mode
|
|
23
|
+
- **`useDataSource.jsx`** — Updated to fall back to sample when live is null/empty, reads mode from `DataModeProvider` context which is now properly controlled by `dataStrategy.ts`
|
|
24
|
+
- **`CommandCenter.tsx` template** — Now imports `ENABLE_SAMPLE_DATA_CACHE` from `@/lib/dataStrategy` and passes `initialMode={ENABLE_SAMPLE_DATA_CACHE ? "sample" : "live"}` to `DataModeProvider`
|
|
25
|
+
- **`dataStrategy.ts` template** — Rewritten comments to explain the Phase 1/Phase 2 connection and how flipping the flag changes the dashboard data
|
|
26
|
+
- **Build guide Phase 2** — Added step 5: "Flip `ENABLE_SAMPLE_DATA_CACHE` to `false`". Added explanation of what changes visually (different names, cities, metrics)
|
|
27
|
+
- **PRD Phase 2** — Added `dataStrategy.ts` flip as step 6 with explanation of the visual change
|
|
28
|
+
- **Efficient build process** — Updated Phase 2 edit order to include the flag flip
|
|
29
|
+
- **SKILL.md** — Updated `CommandCenter.tsx` wiring example to include `ENABLE_SAMPLE_DATA_CACHE` import
|
|
30
|
+
|
|
31
|
+
**Context:** The data mode switch was supposed to be a backend config (`dataStrategy.ts`) but the flag was disconnected. The actual switching was done by `useEngineLiveData` auto-calling `setMode("live")` after a 2-second delay, which meant the hook controlled both data AND mode — not clean. Now: `dataStrategy.ts` is the single control point, `CommandCenter.tsx` reads it, `DataModeProvider` respects it, and `useDataSource` returns the right data. Phase 2 just flips the flag.
|
|
32
|
+
|
|
8
33
|
## [1.9.78] - 2026-04-04
|
|
9
34
|
|
|
10
35
|
### Fixed
|
|
@@ -352,17 +352,18 @@ Build incrementally in 3 prompts. Each prompt builds on the previous result. The
|
|
|
352
352
|
|
|
353
353
|
**What the agent must do:**
|
|
354
354
|
|
|
355
|
-
1. Read only `EngineDashboard.tsx` and
|
|
355
|
+
1. Read only `EngineDashboard.tsx` and `src/hooks/useEngineLiveData.ts` — don't read `useDataSource.jsx`, `DataModeProvider.jsx`, or other library source files (the patterns are in the build guide)
|
|
356
356
|
2. Make **surgical edits** to the existing `EngineDashboard.tsx` — do NOT rewrite the entire file
|
|
357
357
|
3. Add `useEngineLiveData` import and hook call
|
|
358
358
|
4. Update every `useDataSource({ sample, live })` call to pass live data
|
|
359
359
|
5. Update KPI overlays to derive from whichever metrics are active
|
|
360
|
-
6.
|
|
360
|
+
6. **Flip the backend switch:** change `ENABLE_SAMPLE_DATA_CACHE` from `true` to `false` in `src/lib/dataStrategy.ts` — this makes `CommandCenter.tsx` pass `initialMode="live"` to `DataModeProvider`, so every `useDataSource` call now returns the live prop. The dashboard will show completely different data: 12 global travelers (Raj Kapoor, Sofia Reyes…) instead of 8 US travelers, a Midwest storm scenario, and different metrics.
|
|
361
|
+
7. After wiring is complete, **STOP and suggest** the `Weather_Impact__c` custom field — do NOT create it until the user confirms
|
|
361
362
|
|
|
362
363
|
**What the agent must NOT do in this prompt:**
|
|
363
364
|
- Do NOT rewrite `EngineDashboard.tsx` from scratch — make targeted edits to the existing Phase 1 file
|
|
364
|
-
- Do NOT read library component source files (`useDataSource.
|
|
365
|
-
- Do NOT add `DataModeToggle` to the UI —
|
|
365
|
+
- Do NOT read library component source files (`useDataSource.jsx`, `DataModeProvider.jsx`, `dataStrategy.ts`) — the wiring patterns are in the build guide
|
|
366
|
+
- Do NOT add `DataModeToggle` to the UI — there is no UI toggle, the switch is `dataStrategy.ts`
|
|
366
367
|
- Do NOT create the custom field without asking first — suggest it, then wait for "yes"
|
|
367
368
|
- Do NOT add ChatBar, Eva, or any Agentforce integration — that's Prompt 3
|
|
368
369
|
- Do NOT run `npm run build` between edits
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { useState, useEffect } from "react";
|
|
2
|
-
import { useDataMode } from "@/components/library/data/DataModeProvider";
|
|
3
2
|
import * as live from "@/data/engine-live-data";
|
|
4
3
|
|
|
5
4
|
const SIMULATED_LOAD_MS = 2000;
|
|
@@ -18,26 +17,22 @@ export interface EngineLiveData {
|
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
|
-
*
|
|
20
|
+
* Provides the live dataset for the Engine Travel Command Center.
|
|
22
21
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* live prop instead of
|
|
27
|
-
* simultaneously with new data.
|
|
22
|
+
* Simulates a 2-second network fetch, then resolves with all live data.
|
|
23
|
+
* Does NOT control the data mode — that's handled by ENABLE_SAMPLE_DATA_CACHE
|
|
24
|
+
* in src/lib/dataStrategy.ts. When the flag is false, every useDataSource call
|
|
25
|
+
* returns its live prop (which this hook provides) instead of its sample prop.
|
|
28
26
|
*/
|
|
29
27
|
export function useEngineLiveData(): EngineLiveData {
|
|
30
28
|
const [loading, setLoading] = useState(true);
|
|
31
|
-
const { setMode } = useDataMode();
|
|
32
29
|
|
|
33
30
|
useEffect(() => {
|
|
34
|
-
setMode("sample");
|
|
35
31
|
const timer = setTimeout(() => {
|
|
36
32
|
setLoading(false);
|
|
37
|
-
setMode("live");
|
|
38
33
|
}, SIMULATED_LOAD_MS);
|
|
39
34
|
return () => clearTimeout(timer);
|
|
40
|
-
}, [
|
|
35
|
+
}, []);
|
|
41
36
|
|
|
42
37
|
return {
|
|
43
38
|
loading,
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { useMemo as
|
|
2
|
-
import { useDataMode as
|
|
3
|
-
function
|
|
4
|
-
const { mode:
|
|
5
|
-
return
|
|
6
|
-
const o = r === "sample" ? t : e;
|
|
7
|
-
return typeof o == "function" ? o() : o;
|
|
8
|
-
}, [r, t, e]);
|
|
1
|
+
import { useMemo as n } from "react";
|
|
2
|
+
import { useDataMode as u } from "./DataModeProvider.js";
|
|
3
|
+
function a({ sample: t, live: r }) {
|
|
4
|
+
const { mode: o } = u();
|
|
5
|
+
return n(() => o === "live" && r != null && !(Array.isArray(r) && r.length === 0) ? typeof r == "function" ? r() : r : typeof t == "function" ? t() : t, [o, t, r]);
|
|
9
6
|
}
|
|
10
7
|
export {
|
|
11
|
-
|
|
8
|
+
a as default
|
|
12
9
|
};
|
|
13
10
|
//# sourceMappingURL=useDataSource.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDataSource.js","sources":["../../../../src/components/library/data/useDataSource.jsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useDataMode } from \"./DataModeProvider\";\n\n/**\n * Select between sample and live data based on the global data mode.\n *\n * Values can be plain data or functions (lazy-evaluated only when active).\n *\n * @param {{ sample: any | () => any, live: any | () => any }} sources\n * @returns {any} the resolved value for the active mode\n *\n * @example\n *
|
|
1
|
+
{"version":3,"file":"useDataSource.js","sources":["../../../../src/components/library/data/useDataSource.jsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useDataMode } from \"./DataModeProvider\";\n\n/**\n * Select between sample and live data based on the global data mode.\n *\n * The mode is controlled by ENABLE_SAMPLE_DATA_CACHE in src/lib/dataStrategy.ts,\n * which CommandCenter.tsx passes to DataModeProvider as initialMode.\n * When the flag is true, mode is \"sample\" and this hook returns the sample prop.\n * When false, mode is \"live\" and this hook returns the live prop.\n *\n * Values can be plain data or functions (lazy-evaluated only when active).\n *\n * @param {{ sample: any | () => any, live: any | () => any }} sources\n * @returns {any} the resolved value for the active mode\n *\n * @example\n * const incidents = useDataSource({\n * sample: sampleIncidents,\n * live: fetchedIncidents,\n * });\n */\nexport default function useDataSource({ sample, live }) {\n const { mode } = useDataMode();\n\n return useMemo(() => {\n if (mode === \"live\" && live != null && !(Array.isArray(live) && live.length === 0)) {\n return typeof live === \"function\" ? live() : live;\n }\n return typeof sample === \"function\" ? sample() : sample;\n }, [mode, sample, live]);\n}\n"],"names":["useDataSource","sample","live","mode","useDataMode","useMemo"],"mappings":";;AAsBA,SAAwBA,EAAc,EAAE,QAAAC,GAAQ,MAAAC,KAAQ;AACtD,QAAM,EAAE,MAAAC,EAAA,IAASC,EAAA;AAEjB,SAAOC,EAAQ,MACTF,MAAS,UAAUD,KAAQ,QAAQ,EAAE,MAAM,QAAQA,CAAI,KAAKA,EAAK,WAAW,KACvE,OAAOA,KAAS,aAAaA,EAAA,IAASA,IAExC,OAAOD,KAAW,aAAaA,EAAA,IAAWA,GAChD,CAACE,GAAMF,GAAQC,CAAI,CAAC;AACzB;"}
|
package/package.json
CHANGED
|
@@ -755,7 +755,79 @@ else
|
|
|
755
755
|
echo " ⚠ Skipped logo (package logo not found)"
|
|
756
756
|
fi
|
|
757
757
|
|
|
758
|
-
|
|
758
|
+
# ── Clean Salesforce metadata created during the demo ────────────────────────
|
|
759
|
+
|
|
760
|
+
SFDX_DEFAULT=""
|
|
761
|
+
|
|
762
|
+
# Walk up from webapp root to find force-app/main/default
|
|
763
|
+
check="$ROOT"
|
|
764
|
+
for i in 1 2 3 4 5; do
|
|
765
|
+
if [ -d "$check/force-app/main/default" ]; then
|
|
766
|
+
SFDX_DEFAULT="$check/force-app/main/default"
|
|
767
|
+
break
|
|
768
|
+
fi
|
|
769
|
+
parent="$(dirname "$check")"
|
|
770
|
+
# Check if we're already inside force-app/main/default
|
|
771
|
+
if [[ "$check" == */force-app/main/default/* ]]; then
|
|
772
|
+
SFDX_DEFAULT="${check%%/force-app/main/default/*}/force-app/main/default"
|
|
773
|
+
break
|
|
774
|
+
fi
|
|
775
|
+
check="$parent"
|
|
776
|
+
done
|
|
777
|
+
|
|
778
|
+
if [ -n "$SFDX_DEFAULT" ]; then
|
|
779
|
+
echo "→ Cleaning Salesforce metadata…"
|
|
780
|
+
|
|
781
|
+
# Remove all Apex classes (.cls and .cls-meta.xml)
|
|
782
|
+
CLASSES_DIR="$SFDX_DEFAULT/classes"
|
|
783
|
+
if [ -d "$CLASSES_DIR" ]; then
|
|
784
|
+
cls_count=$(find "$CLASSES_DIR" -maxdepth 1 -name "*.cls" -o -name "*.cls-meta.xml" 2>/dev/null | wc -l | tr -d ' ')
|
|
785
|
+
if [ "$cls_count" -gt 0 ]; then
|
|
786
|
+
rm -f "$CLASSES_DIR"/*.cls "$CLASSES_DIR"/*.cls-meta.xml
|
|
787
|
+
echo " ✓ Removed $cls_count Apex class files from classes/"
|
|
788
|
+
else
|
|
789
|
+
echo " ℹ No Apex classes to remove"
|
|
790
|
+
fi
|
|
791
|
+
fi
|
|
792
|
+
|
|
793
|
+
# Remove custom fields created during the demo (e.g., Weather_Impact__c)
|
|
794
|
+
OBJECTS_DIR="$SFDX_DEFAULT/objects"
|
|
795
|
+
if [ -d "$OBJECTS_DIR" ]; then
|
|
796
|
+
fields_removed=0
|
|
797
|
+
for fields_dir in "$OBJECTS_DIR"/*/fields; do
|
|
798
|
+
if [ -d "$fields_dir" ]; then
|
|
799
|
+
for f in "$fields_dir"/*.field-meta.xml; do
|
|
800
|
+
if [ -f "$f" ]; then
|
|
801
|
+
rm "$f"
|
|
802
|
+
echo " ✓ Removed $(basename "$f")"
|
|
803
|
+
fields_removed=$((fields_removed + 1))
|
|
804
|
+
fi
|
|
805
|
+
done
|
|
806
|
+
fi
|
|
807
|
+
done
|
|
808
|
+
if [ "$fields_removed" -eq 0 ]; then
|
|
809
|
+
echo " ℹ No custom fields to remove"
|
|
810
|
+
fi
|
|
811
|
+
|
|
812
|
+
# Remove platform event directories (e.g., Travel_Disruption_Alert__e/)
|
|
813
|
+
events_removed=0
|
|
814
|
+
for evt_dir in "$OBJECTS_DIR"/*__e; do
|
|
815
|
+
if [ -d "$evt_dir" ]; then
|
|
816
|
+
rm -rf "$evt_dir"
|
|
817
|
+
echo " ✓ Removed platform event $(basename "$evt_dir")"
|
|
818
|
+
events_removed=$((events_removed + 1))
|
|
819
|
+
fi
|
|
820
|
+
done
|
|
821
|
+
if [ "$events_removed" -eq 0 ]; then
|
|
822
|
+
echo " ℹ No platform events to remove"
|
|
823
|
+
fi
|
|
824
|
+
fi
|
|
825
|
+
|
|
826
|
+
echo ""
|
|
827
|
+
else
|
|
828
|
+
echo "→ Skipping metadata cleanup (no force-app directory found)"
|
|
829
|
+
echo ""
|
|
830
|
+
fi
|
|
759
831
|
|
|
760
832
|
# ── Done ─────────────────────────────────────────────────────────────────────
|
|
761
833
|
|
|
@@ -764,18 +836,15 @@ echo "║ ✓ Reset complete! ║"
|
|
|
764
836
|
echo "║ ║"
|
|
765
837
|
echo "║ Restored: ║"
|
|
766
838
|
echo "║ • Engine brand theme (global.css) ║"
|
|
767
|
-
echo "║
|
|
768
|
-
echo "║ - Inter font stack ║"
|
|
769
|
-
echo "║ - HeroUI Engine theme overrides ║"
|
|
770
|
-
echo "║ • Engine sample data (engine-sample-data.js)║"
|
|
771
|
-
echo "║ • Engine live data (engine-live-data.js) ║"
|
|
839
|
+
echo "║ • Engine sample data + live data ║"
|
|
772
840
|
echo "║ • Live data hook (useEngineLiveData.ts) ║"
|
|
773
|
-
echo "║ • GraphQL schema
|
|
774
|
-
echo "║ •
|
|
775
|
-
echo "║
|
|
776
|
-
echo "║
|
|
777
|
-
echo "║ •
|
|
778
|
-
echo "║ •
|
|
841
|
+
echo "║ • GraphQL schema + PRD + logo ║"
|
|
842
|
+
echo "║ • Component library + theme providers ║"
|
|
843
|
+
echo "║ ║"
|
|
844
|
+
echo "║ Cleaned: ║"
|
|
845
|
+
echo "║ • Apex classes (force-app classes/) ║"
|
|
846
|
+
echo "║ • Custom fields (force-app objects/) ║"
|
|
847
|
+
echo "║ • Platform events (force-app *__e/) ║"
|
|
779
848
|
echo "║ ║"
|
|
780
849
|
echo "║ Layout: ║"
|
|
781
850
|
echo "║ / → Home (search page) ║"
|
|
@@ -783,9 +852,6 @@ echo "║ /search → Search (search page) ║"
|
|
|
783
852
|
echo "║ Nav bar on Home + Search pages only ║"
|
|
784
853
|
echo "║ ║"
|
|
785
854
|
echo "║ Start building: ║"
|
|
786
|
-
echo "║ • For dashboards: Edit BlankDashboard.tsx ║"
|
|
787
|
-
echo "║ then wire into routes or CommandCenter ║"
|
|
788
|
-
echo "║ • For search app: Ready to go! ║"
|
|
789
855
|
echo "║ npm run dev ║"
|
|
790
856
|
echo "╚════════════════════════════════════════════════╝"
|
|
791
857
|
echo ""
|
|
@@ -4,30 +4,29 @@ import { useDataMode } from "./DataModeProvider";
|
|
|
4
4
|
/**
|
|
5
5
|
* Select between sample and live data based on the global data mode.
|
|
6
6
|
*
|
|
7
|
+
* The mode is controlled by ENABLE_SAMPLE_DATA_CACHE in src/lib/dataStrategy.ts,
|
|
8
|
+
* which CommandCenter.tsx passes to DataModeProvider as initialMode.
|
|
9
|
+
* When the flag is true, mode is "sample" and this hook returns the sample prop.
|
|
10
|
+
* When false, mode is "live" and this hook returns the live prop.
|
|
11
|
+
*
|
|
7
12
|
* Values can be plain data or functions (lazy-evaluated only when active).
|
|
8
13
|
*
|
|
9
14
|
* @param {{ sample: any | () => any, live: any | () => any }} sources
|
|
10
15
|
* @returns {any} the resolved value for the active mode
|
|
11
16
|
*
|
|
12
17
|
* @example
|
|
13
|
-
* // Static data
|
|
14
18
|
* const incidents = useDataSource({
|
|
15
19
|
* sample: sampleIncidents,
|
|
16
20
|
* live: fetchedIncidents,
|
|
17
21
|
* });
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* // Lazy — factory only runs when that mode is active
|
|
21
|
-
* const metrics = useDataSource({
|
|
22
|
-
* sample: () => generateSampleMetrics(),
|
|
23
|
-
* live: () => computeFromAPI(apiData),
|
|
24
|
-
* });
|
|
25
22
|
*/
|
|
26
23
|
export default function useDataSource({ sample, live }) {
|
|
27
24
|
const { mode } = useDataMode();
|
|
28
25
|
|
|
29
26
|
return useMemo(() => {
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
if (mode === "live" && live != null && !(Array.isArray(live) && live.length === 0)) {
|
|
28
|
+
return typeof live === "function" ? live() : live;
|
|
29
|
+
}
|
|
30
|
+
return typeof sample === "function" ? sample() : sample;
|
|
32
31
|
}, [mode, sample, live]);
|
|
33
32
|
}
|
|
@@ -1,42 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Data Strategy Configuration
|
|
3
3
|
*
|
|
4
|
-
* Controls
|
|
4
|
+
* Controls which dataset the dashboard displays.
|
|
5
5
|
*
|
|
6
6
|
* ENABLE_SAMPLE_DATA_CACHE:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* - Faster load times during development
|
|
10
|
-
* - Consistent data for testing and presentations
|
|
11
|
-
* - Reduced API load
|
|
12
|
-
* - Offline-first capability
|
|
7
|
+
* - true → Dashboard shows sample data (default after install)
|
|
8
|
+
* - false → Dashboard shows live data (different travelers, cities, metrics)
|
|
13
9
|
*
|
|
14
10
|
* HOW IT WORKS:
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* seamless switching between data sources without code changes.
|
|
11
|
+
* CommandCenter.tsx reads this flag and passes initialMode to DataModeProvider:
|
|
12
|
+
* initialMode={ENABLE_SAMPLE_DATA_CACHE ? "sample" : "live"}
|
|
18
13
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
14
|
+
* Every useDataSource({ sample, live }) call returns whichever prop matches
|
|
15
|
+
* the active mode. When you flip this flag to false, the dashboard instantly
|
|
16
|
+
* shows the live dataset on next load — no code changes needed.
|
|
22
17
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
18
|
+
* USAGE:
|
|
19
|
+
* Phase 1 (Build the Dashboard): Leave as true — sample data.
|
|
20
|
+
* Phase 2 (Connect to Live Data): Flip to false — live data with different
|
|
21
|
+
* travelers, cities, disruptions, and metrics.
|
|
25
22
|
*/
|
|
26
23
|
|
|
27
24
|
export const ENABLE_SAMPLE_DATA_CACHE = true;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Sample data cache is currently ENABLED
|
|
31
|
-
*
|
|
32
|
-
* Benefits:
|
|
33
|
-
* ✓ Instant data loading (no network latency)
|
|
34
|
-
* ✓ No API rate limiting concerns
|
|
35
|
-
* ✓ Consistent data for demos and testing
|
|
36
|
-
* ✓ Works offline
|
|
37
|
-
* ✓ Reduced backend load
|
|
38
|
-
*
|
|
39
|
-
* To enable live API data:
|
|
40
|
-
* 1. Set ENABLE_SAMPLE_DATA_CACHE to false
|
|
41
|
-
* 2. Restart the development server
|
|
42
|
-
*/
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import AppThemeProvider from "@/components/library/theme/AppThemeProvider";
|
|
2
2
|
import DataModeProvider from "@/components/library/data/DataModeProvider";
|
|
3
|
+
import { ENABLE_SAMPLE_DATA_CACHE } from "@/lib/dataStrategy";
|
|
3
4
|
import { Toaster } from "sonner";
|
|
4
5
|
import BlankDashboard from "../pages/BlankDashboard";
|
|
5
6
|
|
|
6
7
|
export default function CommandCenter() {
|
|
7
8
|
return (
|
|
8
9
|
<AppThemeProvider initialMode="light">
|
|
9
|
-
<DataModeProvider initialMode="sample">
|
|
10
|
+
<DataModeProvider initialMode={ENABLE_SAMPLE_DATA_CACHE ? "sample" : "live"}>
|
|
10
11
|
<BlankDashboard />
|
|
11
12
|
<Toaster position="bottom-right" />
|
|
12
13
|
</DataModeProvider>
|