@schandlergarcia/sf-web-components 1.9.50 → 1.9.54
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/features/command-center-dashboard-rule.md +20 -7
- package/.a4drules/features/engine-dashboard-rule.md +302 -0
- package/.a4drules/features/phase2-data-pattern.md +166 -0
- package/.a4drules/features/pre-code-checklist.md +72 -0
- package/.a4drules/skills/command-center-builder/SKILL.md +635 -29
- package/.a4drules/skills/command-center-project/SKILL.md +4 -4
- package/.a4drules/skills/component-library/SKILL.md +1000 -27
- package/.a4drules/troubleshooting/codegen-overwrites-types.md +181 -0
- package/.a4drules/troubleshooting/graphql-introspection-failure.md +286 -0
- package/.a4drules/validation-requirements.md +211 -0
- package/.a4drules/webapp-data.md +437 -0
- package/.a4drules/webapp-ui.md +16 -0
- package/CHANGELOG.md +350 -0
- package/data/README.md +95 -17
- package/data/engine-command-center-prd.md +438 -0
- package/data/schema.graphql +292 -0
- package/package.json +1 -1
- package/scripts/generate-schema-from-sample.mjs +370 -0
- package/scripts/postinstall.mjs +107 -3
- package/scripts/reset-command-center.sh +39 -2
- package/src/templates/config/vite.config.ts.template +108 -0
- package/src/templates/lib/dataStrategy.ts.template +42 -0
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
---
|
|
2
2
|
paths:
|
|
3
|
-
- "**/
|
|
4
|
-
- "**/
|
|
5
|
-
- "**/components/
|
|
3
|
+
- "**/pages/*.jsx"
|
|
4
|
+
- "**/pages/*.tsx"
|
|
5
|
+
- "**/components/workspace/CommandCenter.tsx"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Command Center Dashboard Rules (MANDATORY)
|
|
9
9
|
|
|
10
|
-
These rules are non-negotiable for all files in `src/components/
|
|
10
|
+
These rules are non-negotiable for all dashboard files in `src/pages/` and workspace files in `src/components/workspace/`.
|
|
11
|
+
|
|
12
|
+
**For the Engine Travel Command Center specifically:** Also read `.a4drules/features/engine-dashboard-rule.md` and `engine-command-center-prd.md` at the project root.
|
|
11
13
|
|
|
12
14
|
## Before writing ANY code, load these skills
|
|
13
15
|
|
|
14
16
|
You MUST load the **command-center-builder** and **component-library** skills before writing or editing dashboard pages. These skills contain the full component API reference and builder rules. Do not proceed without them.
|
|
15
17
|
|
|
18
|
+
**For Engine dashboard:** Also load **command-center-project** and **outer-app** skills, and read `engine-command-center-prd.md`.
|
|
19
|
+
|
|
20
|
+
**For Phase 2 (sample data):** Read `.a4drules/features/phase2-data-pattern.md`. The sample data file already exists at `src/data/engine-sample-data.js` — do NOT create it, just import from it.
|
|
21
|
+
|
|
16
22
|
## Critical constraints
|
|
17
23
|
|
|
18
|
-
1. **File extension
|
|
24
|
+
1. **File extension MUST be `.tsx`** — This is a TypeScript project. All React components MUST use `.tsx` extension, never `.jsx`. Dashboard files go in `src/pages/` (NOT `src/components/pages/`). All type definitions are available from the component library.
|
|
19
25
|
|
|
20
26
|
2. **Use ONLY library components** from `@/components/library` for cards, charts, tables, lists. Never hand-roll HTML cards (`<div className="bg-white border rounded...">`).
|
|
21
27
|
|
|
@@ -37,10 +43,17 @@ You MUST load the **command-center-builder** and **component-library** skills be
|
|
|
37
43
|
|
|
38
44
|
11. **`useDataSource`** is required — wire all data through `useDataSource({ sample, live })` for sample/live mode.
|
|
39
45
|
|
|
40
|
-
12. **Run `npm run validate:dashboard`** before reporting done — fix ALL errors, zero tolerance. Never dismiss errors as "justified".
|
|
46
|
+
12. **Run `npm run validate:dashboard`** before reporting done — fix ALL errors, zero tolerance. Never dismiss errors as "justified". The validator MUST show zero errors before the dashboard is considered complete.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cd force-app/main/default/webapplications/reactapp4
|
|
50
|
+
npm run validate:dashboard
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If errors are reported, you MUST fix them by switching to library components, correct colors, or proper imports. Do not proceed until the validator shows zero errors.
|
|
41
54
|
|
|
42
55
|
13. **Do NOT `npm install` any packages** for dashboard work. The component library and existing dependencies have everything needed.
|
|
43
56
|
|
|
44
57
|
14. **Heroicon names** — common correct names: `PaperAirplaneIcon` (not PlaneIcon), `BuildingOfficeIcon` (not HotelIcon), `BanknotesIcon` (not MoneyIcon), `ExclamationTriangleIcon` (not AlertIcon), `UserIcon` (not PersonIcon).
|
|
45
58
|
|
|
46
|
-
15. **Wire the dashboard as the home page.** After creating your dashboard and updating `CommandCenter.tsx`, also update `src/
|
|
59
|
+
15. **Wire the dashboard as the home page.** After creating your dashboard and updating `CommandCenter.tsx`, you MUST also update `src/pages/Home.tsx` to render `CommandCenter` (replace any search interface with `import CommandCenter from "@/components/workspace/CommandCenter"; export default function HomePage() { return <CommandCenter />; }`), and update `src/routes.tsx` to set `Home` as the index route and move `Search` to `/search`. The dashboard must be the first thing users see at `/`.
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/pages/EngineDashboard.tsx"
|
|
4
|
+
- "**/pages/Engine*.tsx"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Engine Travel Command Center Dashboard Rules
|
|
8
|
+
|
|
9
|
+
These rules apply ONLY when building the Engine Travel Command Center dashboard from `engine-command-center-prd.md`.
|
|
10
|
+
|
|
11
|
+
## Source of Truth
|
|
12
|
+
|
|
13
|
+
**The PRD is law:** `engine-command-center-prd.md` at the project root is the complete specification. Follow it exactly. If the PRD conflicts with your assumptions, the PRD wins.
|
|
14
|
+
|
|
15
|
+
## Phase Discipline (MANDATORY)
|
|
16
|
+
|
|
17
|
+
The Engine dashboard uses a **strict 4-phase build process.** You MUST complete each phase fully before starting the next:
|
|
18
|
+
|
|
19
|
+
1. **Phase 1: Layout** — Structure only, placeholders, no real components
|
|
20
|
+
2. **Phase 2: Components + Sample Data** — Full UI with hardcoded realistic data
|
|
21
|
+
- **CRITICAL:** Sample data file already exists at `src/data/engine-sample-data.js`
|
|
22
|
+
- **DO NOT create a new data file** — just import from the existing one
|
|
23
|
+
- Import dashboard-ready derivatives (MAP_MARKERS, TRAVELER_CARDS, etc.)
|
|
24
|
+
- DO NOT define sample data inline in the dashboard — causes file truncation
|
|
25
|
+
3. **Phase 3: Real Data** — Connect to Salesforce, keep UI identical to Phase 2
|
|
26
|
+
4. **Phase 4: Agent** — Add Eva ChatBar integration
|
|
27
|
+
|
|
28
|
+
### Phase 1 Placeholder Format
|
|
29
|
+
|
|
30
|
+
**Data panels** use `BaseCard` with centered placeholder text. NO titles on placeholders:
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
<BaseCard>
|
|
34
|
+
<div className="h-48 flex items-center justify-center text-slate-400">
|
|
35
|
+
Disruptions Panel
|
|
36
|
+
</div>
|
|
37
|
+
</BaseCard>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Hero map** renders the actual GeoMap component (empty, no data):
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { GeoMap, useAppTheme } from "@/components/library";
|
|
44
|
+
|
|
45
|
+
export default function EngineDashboard() {
|
|
46
|
+
const { mode } = useAppTheme();
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div className="relative" style={{ flex: "1.15 1 0", minHeight: 0 }}>
|
|
50
|
+
<GeoMap
|
|
51
|
+
width={960}
|
|
52
|
+
height={520}
|
|
53
|
+
theme={mode === "dark" ? "dark" : "light"}
|
|
54
|
+
className="h-full w-full"
|
|
55
|
+
/>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
All data panel placeholders: BaseCard, no title, centered text, `h-48`, `text-slate-400`.
|
|
62
|
+
|
|
63
|
+
Hero map in Phase 1: actual GeoMap component (no markers/arcs/overlays yet), NOT wrapped in BaseCard.
|
|
64
|
+
|
|
65
|
+
**DO NOT:**
|
|
66
|
+
- Mix phases (don't add sample data in Phase 1, don't add Eva in Phase 2, etc.)
|
|
67
|
+
- Skip validation between phases
|
|
68
|
+
- Proceed to the next phase with validator errors
|
|
69
|
+
- Use BaseCard titles in Phase 1 placeholders (causes text to run together)
|
|
70
|
+
|
|
71
|
+
### Phase 3: Real Data Integration
|
|
72
|
+
|
|
73
|
+
**CRITICAL:** You MUST explicitly use the Salesforce GraphQL skills by name. Declarative listing doesn't work - use imperative commands.
|
|
74
|
+
|
|
75
|
+
**Goal:** Connect dashboard to live Salesforce data. No toggle needed - dashboard shows live data only.
|
|
76
|
+
|
|
77
|
+
**Key insight:** The sample data file (`src/data/engine-sample-data.js`) already uses real Salesforce field names (Trip__c, Flight__c, Contact, etc.). Read the file header comment to understand the object schema.
|
|
78
|
+
|
|
79
|
+
**Custom objects used:**
|
|
80
|
+
- Contact (travelers, with custom fields: Home_Airport__c, Travel_Policy_Tier__c, etc.)
|
|
81
|
+
- Trip__c (origin, destination, dates, cost, policy status)
|
|
82
|
+
- Flight__c (flight number, airports, status, delay, traveler lookup)
|
|
83
|
+
- Booking__c (upcoming reservations)
|
|
84
|
+
- Disruption__c (delays, cancellations, severity)
|
|
85
|
+
- Rebooking_Action__c (Eva activity log)
|
|
86
|
+
- Travel_Policy__c (policy rules and status)
|
|
87
|
+
|
|
88
|
+
**Implementation steps (FOLLOW EXACTLY):**
|
|
89
|
+
|
|
90
|
+
1. **Read sample data file** (`src/data/engine-sample-data.js`) to understand which Salesforce fields are needed (e.g., Trip__c has Origin_City__c, Contact has FirstName, etc.)
|
|
91
|
+
|
|
92
|
+
2. **Use the Salesforce GraphQL skills** to implement queries and hooks:
|
|
93
|
+
|
|
94
|
+
- Use `exploring-webapp-graphql-schema` skill to look up each object
|
|
95
|
+
- Say: "Use the exploring-webapp-graphql-schema skill to look up Trip__c"
|
|
96
|
+
- The skill reads from schema.graphql (already checked into the repo)
|
|
97
|
+
|
|
98
|
+
- Use `generating-webapp-graphql-read-query` skill to create queries
|
|
99
|
+
- Say: "Use the generating-webapp-graphql-read-query skill to create a query for Trip__c"
|
|
100
|
+
- The skill generates properly typed GraphQL code with @optional directives
|
|
101
|
+
|
|
102
|
+
- Use `using-webapp-graphql` skill to implement hooks
|
|
103
|
+
- Say: "Use the using-webapp-graphql skill to create a useTravelers hook"
|
|
104
|
+
- The skill creates hooks that return { data, loading, error }
|
|
105
|
+
|
|
106
|
+
3. **Update useDataSource calls** to use live data:
|
|
107
|
+
- Change: `useDataSource({ sample: TRAVELER_CARDS })`
|
|
108
|
+
- To: `useDataSource({ sample: TRAVELER_CARDS, live: liveTravelers ?? [] })`
|
|
109
|
+
|
|
110
|
+
4. **No data mode toggle** - dashboard always shows live data (or falls back to sample on error)
|
|
111
|
+
|
|
112
|
+
**Key insight:** The schema.graphql file is pre-built and checked into the repo. GraphQL skills and tooling work out of the box without any schema generation.
|
|
113
|
+
|
|
114
|
+
**Example pattern:**
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
// Phase 2 (sample data only)
|
|
118
|
+
const travelers = useDataSource({ sample: TRAVELER_CARDS, live: [] });
|
|
119
|
+
|
|
120
|
+
// Phase 3 (live data with sample fallback on error)
|
|
121
|
+
const { data: liveTravelers, loading, error } = useTravelers();
|
|
122
|
+
const travelers = useDataSource({
|
|
123
|
+
sample: TRAVELER_CARDS, // Used as fallback if live data fails
|
|
124
|
+
live: liveTravelers ?? [] // Primary data source
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The `useDataSource` hook automatically uses `live` data when available, falling back to `sample` only on error. No toggle UI needed.
|
|
129
|
+
|
|
130
|
+
**DO NOT:**
|
|
131
|
+
- Ask the user about object names - they're in the sample data file
|
|
132
|
+
- Create object metadata - objects already exist in org
|
|
133
|
+
- Change field names in queries - use exact names from sample data
|
|
134
|
+
- Modify UI components - only change data sources
|
|
135
|
+
- Add DataModeToggle - Phase 3 uses live data only (sample data is fallback for errors)
|
|
136
|
+
- Panic if schema introspection fails - queries still work fine (see troubleshooting guide below)
|
|
137
|
+
- List skills declaratively - use imperative commands ("Use the X skill to...")
|
|
138
|
+
|
|
139
|
+
**Troubleshooting:** If you encounter GraphQL schema introspection failures, see `.a4drules/troubleshooting/graphql-introspection-failure.md` for the complete workaround pattern.
|
|
140
|
+
|
|
141
|
+
## Validation Checkpoints (ZERO ERRORS REQUIRED)
|
|
142
|
+
|
|
143
|
+
After EVERY change, run the validator from the webapp directory:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
cd force-app/main/default/webapplications/reactapp4
|
|
147
|
+
npm run validate:dashboard
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Zero errors required.** If the validator reports ANY errors:
|
|
151
|
+
1. Read the error message carefully
|
|
152
|
+
2. Identify which rule was violated
|
|
153
|
+
3. Fix it by switching to the correct library component
|
|
154
|
+
4. Re-run the validator
|
|
155
|
+
5. Repeat until zero errors
|
|
156
|
+
|
|
157
|
+
**Common fixes:**
|
|
158
|
+
- "Hand-rolled card detected" → Wrap in `WidgetCard`, `ListCard`, `BaseCard`, etc.
|
|
159
|
+
- "Forbidden color: text-white" → Change to `text-slate-50` or `text-slate-900`
|
|
160
|
+
- "shadcn import detected" → Replace with library equivalent from `@/components/library`
|
|
161
|
+
- "Missing useDataSource" → Add `useDataSource({ sample, live })` pattern
|
|
162
|
+
|
|
163
|
+
Do NOT report the phase as complete until the validator shows zero errors.
|
|
164
|
+
|
|
165
|
+
## File Requirements
|
|
166
|
+
|
|
167
|
+
- **Extension:** `.tsx` (TypeScript) — NEVER `.jsx`
|
|
168
|
+
- **Location:** `src/pages/EngineDashboard.tsx` (NOT `src/components/pages/`)
|
|
169
|
+
- **Imports:** ONLY from `@/components/library` — never shadcn, never Lucide, never Recharts
|
|
170
|
+
|
|
171
|
+
## Layout Pattern: Visualization-Hero
|
|
172
|
+
|
|
173
|
+
The Engine dashboard uses the **visualization-hero** layout (see PRD section 5). This means:
|
|
174
|
+
|
|
175
|
+
1. **Hero map:** Full-width, large (`flex: 1.15 1 0`), GeoMap with glass overlays and flight status strip
|
|
176
|
+
2. **Data panels below:** Standard grid sections (`flex: 1 1 0`)
|
|
177
|
+
|
|
178
|
+
**DO NOT:**
|
|
179
|
+
- Put the map in a 1/3 or 1/2 grid column (it's hero, not sidebar)
|
|
180
|
+
- Wrap GeoMap in ChartCard (render directly)
|
|
181
|
+
- Skip the glass KPI overlays or flight status strip
|
|
182
|
+
- Make the map too small (minimum 400px height)
|
|
183
|
+
|
|
184
|
+
## Component Selection
|
|
185
|
+
|
|
186
|
+
Every section of the dashboard MUST use a library component. No hand-rolled HTML cards:
|
|
187
|
+
|
|
188
|
+
| Content | Use | NOT |
|
|
189
|
+
|---------|-----|-----|
|
|
190
|
+
| KPI number | `MetricCard` | `<div className="bg-white ...">` |
|
|
191
|
+
| Data table | `TableCard` | `<table>` HTML |
|
|
192
|
+
| Item list | `ListCard` | Custom `.map()` divs |
|
|
193
|
+
| Activity log | `ActivityCard` | Custom feed markup |
|
|
194
|
+
| Chart | `ChartCard` + `D3Chart` | Recharts/Chart.js/custom SVG |
|
|
195
|
+
| Map | `GeoMap` (direct) | react-simple-maps |
|
|
196
|
+
| Status items | `StatusCard` | Custom status badges |
|
|
197
|
+
| Multi-section panel | `WidgetCard` | Nested divs |
|
|
198
|
+
| Expandable content | `WidgetCard` (single section) | Hand-rolled collapse logic |
|
|
199
|
+
|
|
200
|
+
## Engine Brand Colors
|
|
201
|
+
|
|
202
|
+
Update `src/styles/global.css` with Engine teal palette (PRD section 3). Use `engine-*` and `brand-*` Tailwind classes, never hardcoded hex values.
|
|
203
|
+
|
|
204
|
+
## Dark Mode (MANDATORY)
|
|
205
|
+
|
|
206
|
+
Every visible element MUST work in both light and dark mode. Test both before reporting complete.
|
|
207
|
+
|
|
208
|
+
- GeoMap: pass `theme={mode === "dark" ? "dark" : "light"}`
|
|
209
|
+
- Glass overlays: `bg-black/40 backdrop-blur-md` (works in both modes)
|
|
210
|
+
- Text: use slate scale, never `text-black` or `text-white`
|
|
211
|
+
- All custom elements: add `dark:` variants
|
|
212
|
+
|
|
213
|
+
## Eva Integration (Phase 4 Only)
|
|
214
|
+
|
|
215
|
+
Eva is a `ChatBar` in the header. NOT a FAB. NOT a ChatPanel in the grid. NOT a sliding panel.
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
<ChatBar
|
|
219
|
+
title="Eva"
|
|
220
|
+
placeholder="Ask Eva..."
|
|
221
|
+
suggestions={CHAT_SUGGESTIONS}
|
|
222
|
+
onSend={handleChat}
|
|
223
|
+
/>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Data Mode (Sample vs Live)
|
|
227
|
+
|
|
228
|
+
Every component must work in both data modes:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
// ✅ Correct
|
|
232
|
+
const SAMPLE_TRAVELERS = [...]; // module scope
|
|
233
|
+
const travelers = useDataSource({ sample: SAMPLE_TRAVELERS, live: liveTravelers });
|
|
234
|
+
|
|
235
|
+
// ❌ Wrong — no mode switching
|
|
236
|
+
const travelers = [...]; // always uses same data
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Wiring Steps (REQUIRED)
|
|
240
|
+
|
|
241
|
+
After creating `EngineDashboard.tsx`, you MUST:
|
|
242
|
+
|
|
243
|
+
1. Update `src/components/workspace/CommandCenter.tsx`:
|
|
244
|
+
```tsx
|
|
245
|
+
import EngineDashboard from "../../pages/EngineDashboard";
|
|
246
|
+
// ... render <EngineDashboard />
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
2. Update `src/pages/Home.tsx`:
|
|
250
|
+
```tsx
|
|
251
|
+
import CommandCenter from "@/components/workspace/CommandCenter";
|
|
252
|
+
export default function HomePage() { return <CommandCenter />; }
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
3. Update `src/routes.tsx`:
|
|
256
|
+
```tsx
|
|
257
|
+
{ index: true, element: <Home />, handle: { showInNavigation: true, label: 'Dashboard' } }
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Verify all three files are updated before reporting complete.
|
|
261
|
+
|
|
262
|
+
## Pre-Completion Checklist
|
|
263
|
+
|
|
264
|
+
Before reporting ANY phase complete, verify ALL of these:
|
|
265
|
+
|
|
266
|
+
- [ ] Validator shows zero errors (`npm run validate:dashboard`)
|
|
267
|
+
- [ ] File is `.tsx` not `.jsx`
|
|
268
|
+
- [ ] All cards are library components (MetricCard, ListCard, etc.)
|
|
269
|
+
- [ ] No hand-rolled HTML cards (`<div className="bg-white border ...">`)
|
|
270
|
+
- [ ] No shadcn imports (`@/components/ui/`)
|
|
271
|
+
- [ ] No Lucide icons (use Heroicons)
|
|
272
|
+
- [ ] No chart libraries (use D3Chart/GeoMap)
|
|
273
|
+
- [ ] GeoMap rendered directly, not wrapped in ChartCard
|
|
274
|
+
- [ ] Dark mode works on all elements
|
|
275
|
+
- [ ] `useDataSource` used for all data
|
|
276
|
+
- [ ] Sample data is module-scope constants
|
|
277
|
+
- [ ] CommandCenter.tsx, Home.tsx, and routes.tsx are updated
|
|
278
|
+
- [ ] Dev server starts without errors (`npm run dev`)
|
|
279
|
+
|
|
280
|
+
## What Makes This Dashboard Unique
|
|
281
|
+
|
|
282
|
+
The Engine dashboard's signature elements (must be present):
|
|
283
|
+
|
|
284
|
+
1. **Hero map** — Full-width GeoMap with animated flight arcs, weather overlays, glass KPI pills, and flight status strip
|
|
285
|
+
2. **Glass overlays** — Floating KPIs and flight chips with `bg-black/40 backdrop-blur-md`
|
|
286
|
+
3. **Engine brand** — Teal color palette throughout
|
|
287
|
+
4. **Eva integration** — ChatBar in header for AI queries
|
|
288
|
+
5. **Disruptions panel** — Custom inline component showing severity dots and Eva actions
|
|
289
|
+
|
|
290
|
+
These elements distinguish the Engine dashboard from generic dashboards. They must all be present and functional.
|
|
291
|
+
|
|
292
|
+
## Anti-Patterns (NEVER DO THESE)
|
|
293
|
+
|
|
294
|
+
- Creating BlankDashboard.tsx or GenericDashboard.tsx (name is EngineDashboard.tsx)
|
|
295
|
+
- Multi-tab layout with content swapping (build one scrollable page)
|
|
296
|
+
- `<nav>` or header bar inside the dashboard (AppLayout handles navigation)
|
|
297
|
+
- Map in a sidebar grid (it's hero — full width)
|
|
298
|
+
- More than 4 KPIs in a row
|
|
299
|
+
- Using `Math.random()` in sample data
|
|
300
|
+
- Skipping validator errors
|
|
301
|
+
- Reporting phase complete before wiring the dashboard into the app
|
|
302
|
+
- Mixing phases (adding sample data in Phase 1, adding Eva in Phase 2, etc.)
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/pages/*.tsx"
|
|
4
|
+
- "**/data/*.ts"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Phase 2: Sample Data Pattern (MANDATORY)
|
|
8
|
+
|
|
9
|
+
When building Phase 2 (Components & Sample Data), you MUST use the pre-existing sample data file to avoid file truncation.
|
|
10
|
+
|
|
11
|
+
**Important:** The sample data file uses real Salesforce field names (Trip__c, Flight__c, Contact, etc.) so Phase 3 can connect to live data without field name changes.
|
|
12
|
+
|
|
13
|
+
## The Problem
|
|
14
|
+
|
|
15
|
+
**❌ WRONG:** Defining all sample data inline in the dashboard file causes:
|
|
16
|
+
- Dashboard file becomes 500+ lines
|
|
17
|
+
- File gets truncated during writing
|
|
18
|
+
- Unclosed JSX tags and syntax errors
|
|
19
|
+
- Agent has to retry multiple times
|
|
20
|
+
|
|
21
|
+
## The Solution
|
|
22
|
+
|
|
23
|
+
**✅ CORRECT:** The sample data file already exists at `src/data/engine-sample-data.js` — just import and use it.
|
|
24
|
+
|
|
25
|
+
### Data File Already Exists
|
|
26
|
+
|
|
27
|
+
The file `src/data/engine-sample-data.js` contains all sample data as exported constants:
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
// src/data/engine-sample-data.js
|
|
31
|
+
// THIS FILE ALREADY EXISTS - DO NOT CREATE IT
|
|
32
|
+
|
|
33
|
+
// Sample data exports (already defined):
|
|
34
|
+
export const TRAVELERS = [...]; // 8 travelers with Contact fields
|
|
35
|
+
export const TRIPS = [...]; // 8 trips with Trip__c fields
|
|
36
|
+
export const FLIGHTS = [...]; // 8 flights with Flight__c fields
|
|
37
|
+
export const HOTELS = [...]; // 8 hotels with Reservation fields
|
|
38
|
+
export const DISRUPTIONS = [...]; // 4 disruptions
|
|
39
|
+
export const BOOKINGS = [...]; // 8 upcoming bookings
|
|
40
|
+
export const REBOOKING_ACTIONS = [...]; // 8 Eva actions
|
|
41
|
+
export const TRAVEL_POLICIES = [...]; // 5 policy items
|
|
42
|
+
export const MONTHLY_SPEND = [...]; // 6 months of spend
|
|
43
|
+
export const ACCOUNT = {...}; // Account stats
|
|
44
|
+
|
|
45
|
+
// Dashboard-ready derivatives (already computed):
|
|
46
|
+
export const MAP_MARKERS = [...]; // For GeoMap markers prop
|
|
47
|
+
export const MAP_ARCS = [...]; // For GeoMap arcs prop
|
|
48
|
+
export const MAP_OVERLAYS = [...]; // For GeoMap overlays prop
|
|
49
|
+
export const FLIGHT_STATUS_LIST = [...]; // For flight status strip
|
|
50
|
+
export const TRAVELER_CARDS = [...]; // For traveler ListCard
|
|
51
|
+
export const DISRUPTION_CARDS = [...]; // For disruptions panel
|
|
52
|
+
export const EVA_ACTIONS = [...]; // For ActivityCard
|
|
53
|
+
export const BOOKING_ROWS = [...]; // For TableCard
|
|
54
|
+
export const POLICY_ITEMS = [...]; // For StatusCard
|
|
55
|
+
export const DESTINATION_CHART_DATA = [...]; // For destination chart
|
|
56
|
+
export const SPEND_CHART_DATA = [...]; // For spend chart
|
|
57
|
+
export const METRICS = {...}; // Computed KPIs
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
This file is ~370 lines and contains all sample data you need.
|
|
61
|
+
|
|
62
|
+
### Import Into Dashboard
|
|
63
|
+
|
|
64
|
+
In `src/pages/EngineDashboard.tsx`, import the pre-existing data:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// src/pages/EngineDashboard.tsx
|
|
68
|
+
import React from "react";
|
|
69
|
+
import { BaseCard, ListCard, ActivityCard, ChartCard, TableCard, StatusCard, D3Chart, GeoMap } from "@/components/library";
|
|
70
|
+
import {
|
|
71
|
+
MAP_MARKERS,
|
|
72
|
+
MAP_ARCS,
|
|
73
|
+
MAP_OVERLAYS,
|
|
74
|
+
FLIGHT_STATUS_LIST,
|
|
75
|
+
TRAVELER_CARDS,
|
|
76
|
+
DISRUPTION_CARDS,
|
|
77
|
+
EVA_ACTIONS,
|
|
78
|
+
BOOKING_ROWS,
|
|
79
|
+
POLICY_ITEMS,
|
|
80
|
+
DESTINATION_CHART_DATA,
|
|
81
|
+
SPEND_CHART_DATA,
|
|
82
|
+
METRICS
|
|
83
|
+
} from "@/data/engine-sample-data";
|
|
84
|
+
|
|
85
|
+
export default function EngineDashboard() {
|
|
86
|
+
return (
|
|
87
|
+
<div className="flex h-screen flex-col bg-slate-50 dark:bg-slate-950">
|
|
88
|
+
{/* Header - use METRICS for KPIs */}
|
|
89
|
+
|
|
90
|
+
{/* Hero Map - use MAP_MARKERS, MAP_ARCS, MAP_OVERLAYS */}
|
|
91
|
+
<GeoMap markers={MAP_MARKERS} arcs={MAP_ARCS} overlays={MAP_OVERLAYS} />
|
|
92
|
+
|
|
93
|
+
{/* Data Panels */}
|
|
94
|
+
<div className="px-4 py-5 space-y-6">
|
|
95
|
+
{/* Disruptions - use DISRUPTION_CARDS */}
|
|
96
|
+
{/* Active Travelers - use TRAVELER_CARDS */}
|
|
97
|
+
{/* Eva Activity - use EVA_ACTIONS */}
|
|
98
|
+
<ActivityCard title="Eva Activity" actions={EVA_ACTIONS} />
|
|
99
|
+
|
|
100
|
+
{/* Charts - use DESTINATION_CHART_DATA, SPEND_CHART_DATA */}
|
|
101
|
+
{/* Bookings - use BOOKING_ROWS */}
|
|
102
|
+
<TableCard items={BOOKING_ROWS} />
|
|
103
|
+
|
|
104
|
+
{/* Policy - use POLICY_ITEMS */}
|
|
105
|
+
<StatusCard items={POLICY_ITEMS} />
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Dashboard file stays ~150-200 lines because data is imported.
|
|
113
|
+
|
|
114
|
+
## Phase 2 Workflow
|
|
115
|
+
|
|
116
|
+
**DO NOT create the data file** — it already exists. Just:
|
|
117
|
+
|
|
118
|
+
1. Read `src/data/engine-sample-data.js` to understand available exports
|
|
119
|
+
2. Import the dashboard-ready derivatives into `src/pages/EngineDashboard.tsx`
|
|
120
|
+
3. Replace BaseCard placeholders with library components using imported data
|
|
121
|
+
|
|
122
|
+
## Benefits
|
|
123
|
+
|
|
124
|
+
- ✅ Dashboard file stays small (no truncation)
|
|
125
|
+
- ✅ Data file already prepared and tested
|
|
126
|
+
- ✅ Clean separation of concerns
|
|
127
|
+
- ✅ Easy to switch to live data in Phase 3 (just change imports)
|
|
128
|
+
- ✅ Faster Phase 2 completion (no data creation needed)
|
|
129
|
+
|
|
130
|
+
## Common Mistakes
|
|
131
|
+
|
|
132
|
+
❌ **Creating a new data file:**
|
|
133
|
+
```bash
|
|
134
|
+
# WRONG - file already exists
|
|
135
|
+
Write src/data/engine-sample-data.ts
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
❌ **Defining data inline in dashboard:**
|
|
139
|
+
```typescript
|
|
140
|
+
export default function EngineDashboard() {
|
|
141
|
+
const travelers = [
|
|
142
|
+
{ id: "1", name: "Maya Rodriguez", ... }, // 500 more lines
|
|
143
|
+
];
|
|
144
|
+
// File gets truncated here!
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
✅ **Importing from existing file:**
|
|
148
|
+
```typescript
|
|
149
|
+
import { TRAVELER_CARDS, EVA_ACTIONS } from "@/data/engine-sample-data";
|
|
150
|
+
|
|
151
|
+
export default function EngineDashboard() {
|
|
152
|
+
// Use imported data
|
|
153
|
+
<ListCard items={TRAVELER_CARDS} />
|
|
154
|
+
<ActivityCard actions={EVA_ACTIONS} />
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Complete Phase 2 Workflow
|
|
159
|
+
|
|
160
|
+
1. **Read** `src/data/engine-sample-data.js` (understand exports)
|
|
161
|
+
2. **Import** dashboard-ready derivatives into `src/pages/EngineDashboard.tsx`
|
|
162
|
+
3. **Replace** BaseCard placeholders with library components using imported data
|
|
163
|
+
4. **Run** validator (`npm run validate:dashboard`)
|
|
164
|
+
5. **Test** in browser
|
|
165
|
+
|
|
166
|
+
This pattern prevents truncation and keeps code clean.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/pages/*.tsx"
|
|
4
|
+
- "**/components/pages/*.tsx"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Pre-Code Checklist (MANDATORY)
|
|
8
|
+
|
|
9
|
+
Before writing any code for command center dashboards, verify these requirements from the PRD and skills.
|
|
10
|
+
|
|
11
|
+
## File Creation Checklist
|
|
12
|
+
|
|
13
|
+
When creating a new dashboard file, confirm:
|
|
14
|
+
|
|
15
|
+
1. **File path:** `src/pages/DashboardName.tsx` (NOT `src/components/pages/`)
|
|
16
|
+
2. **File extension:** `.tsx` (NOT `.jsx`) — this is a TypeScript project
|
|
17
|
+
3. **Imports:** `@/components/library` ONLY (NOT `@/components/ui/`, NOT `lucide-react`, NOT `recharts`)
|
|
18
|
+
4. **Colors:** Slate scale ONLY (NOT `text-white`, NOT `text-black`, NOT `bg-black`)
|
|
19
|
+
|
|
20
|
+
## During Code Generation Checklist
|
|
21
|
+
|
|
22
|
+
As you write the dashboard code:
|
|
23
|
+
|
|
24
|
+
1. **Every card** is a library component (MetricCard, ListCard, WidgetCard, etc.) — NO hand-rolled `<div className="bg-white border rounded...">`
|
|
25
|
+
2. **Every chart** uses `ChartCard` + `D3Chart` or `GeoMap` — NO Recharts, NO Chart.js, NO custom SVG
|
|
26
|
+
3. **Every color** uses semantic classes or slate scale — NO `text-white`, NO `bg-black`, NO hardcoded hex
|
|
27
|
+
4. **Dark mode** on every element — `dark:` variants on all custom styling
|
|
28
|
+
5. **Phase 1 placeholders:**
|
|
29
|
+
- Data panels: use BaseCard with NO title prop, centered text
|
|
30
|
+
- Hero map: render actual GeoMap component (empty, no markers/arcs/overlays), NOT wrapped in BaseCard
|
|
31
|
+
|
|
32
|
+
## After Code Generation Checklist
|
|
33
|
+
|
|
34
|
+
After writing the dashboard code:
|
|
35
|
+
|
|
36
|
+
1. **Wiring:**
|
|
37
|
+
- [ ] `CommandCenter.tsx` imports your dashboard
|
|
38
|
+
- [ ] `Home.tsx` renders `CommandCenter`
|
|
39
|
+
- [ ] `routes.tsx` has correct routes
|
|
40
|
+
|
|
41
|
+
2. **Validation:**
|
|
42
|
+
```bash
|
|
43
|
+
cd force-app/main/default/webapplications/reactapp4
|
|
44
|
+
npm run validate:dashboard
|
|
45
|
+
```
|
|
46
|
+
- [ ] Zero errors required
|
|
47
|
+
- [ ] Fix all errors before proceeding
|
|
48
|
+
|
|
49
|
+
## Quick Reference
|
|
50
|
+
|
|
51
|
+
| Question | Answer |
|
|
52
|
+
|----------|--------|
|
|
53
|
+
| File path? | `src/pages/EngineDashboard.tsx` |
|
|
54
|
+
| Extension? | `.tsx` (TypeScript) |
|
|
55
|
+
| Import from? | `@/components/library` |
|
|
56
|
+
| Colors? | Slate scale (`text-slate-50`, `bg-slate-900`) |
|
|
57
|
+
| Cards? | Library components (MetricCard, ListCard, etc.) |
|
|
58
|
+
| Charts? | `ChartCard` + `D3Chart` or `GeoMap` |
|
|
59
|
+
| Validate? | `npm run validate:dashboard` → zero errors |
|
|
60
|
+
|
|
61
|
+
## Common Mistakes to Avoid
|
|
62
|
+
|
|
63
|
+
❌ `src/pages/EngineDashboard.tsx` → ✅ `src/pages/EngineDashboard.tsx`
|
|
64
|
+
❌ `EngineDashboard.jsx` → ✅ `EngineDashboard.tsx`
|
|
65
|
+
❌ `text-white` → ✅ `text-slate-50`
|
|
66
|
+
❌ `bg-black` → ✅ `bg-slate-900`
|
|
67
|
+
❌ `<div className="bg-white border rounded-lg p-4">` → ✅ `<BaseCard>` or `<WidgetCard>`
|
|
68
|
+
❌ `import { Button } from '@/components/ui/button'` → ✅ `import { UIButton } from '@/components/library'`
|
|
69
|
+
|
|
70
|
+
## Enforcement
|
|
71
|
+
|
|
72
|
+
This checklist is MANDATORY. Do not skip any step. Verify each item before moving to the next phase.
|