@schandlergarcia/sf-web-components 1.9.67 → 1.9.69

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.
@@ -1,125 +1 @@
1
- ## Core Conventions
2
-
3
- The following conventions apply to all dashboard development in this project.
4
-
5
- 1. **Write `.tsx` files** in `src/pages/` and update `CommandCenter.tsx` to import the dashboard. This is a TypeScript project — all React components use `.tsx` extension.
6
-
7
- 2. **Use ONLY library components** from `@/components/library` for all cards, charts, tables, lists, and feeds. The library has 30+ components — there is no reason to hand-roll HTML. See the component table below.
8
-
9
- 3. **No navigation inside the dashboard.** No `<nav>`, no header bar, no tab bar acting as page-level navigation. The app shell handles navigation. Your dashboard starts with content.
10
-
11
- 4. **Max 4 MetricCards per row.** Never 5. Split into two rows if needed.
12
-
13
- 5. **All charts use `ChartCard` + `D3Chart` or `GeoMap`.** No Recharts, no Chart.js, no custom SVG, no canvas, no hand-drawn paths. The only charting tools allowed are `D3Chart` (with `D3ChartTemplates` or a custom `renderChart` function) and `GeoMap`.
14
-
15
- 6. **Never `npm install` Salesforce packages.** The `@salesforce/*` packages are platform-provided via broken symlinks. They are stubbed in `src/stubs/` and aliased in `vite.config.ts`. Do not try to install them — they don't exist on npm. If you see a TypeScript error about `@salesforce/vite-plugin-webapp-experimental`, ignore it — the build still succeeds via `vite build` (the `tsc` error is in `vite.config.ts` which is handled separately by `tsconfig.node.json`).
16
-
17
- ## Use Library Components — Not Hand-Rolled HTML Cards
18
-
19
- The component library (`@/components/library`) provides pre-built, themed, dark-mode-ready cards for every common dashboard need. Use them instead of writing raw `<div>` cards with custom classes.
20
-
21
- ### Before writing ANY card-like UI, check this table:
22
-
23
- | Need | MUST use | NEVER do |
24
- |------|----------|----------|
25
- | KPI / stat | `MetricCard` | `<div className="bg-white border ..."><h3>Total Spend</h3><span>$4,903</span></div>` |
26
- | List of items | `ListCard` | `<div className="bg-white ..."><div className="space-y-3">` with custom item rows |
27
- | Activity feed | `ActivityCard` or `FeedPanel` | `<div>` with hand-rolled interaction rows |
28
- | Data table | `TableCard` | `<table>` or custom grid of rows |
29
- | Stats panel | `WidgetCard` or `SectionCard` | `<div className="bg-white ... p-6">` with label/value pairs |
30
- | Custom interactive content (expand/collapse, inline details) | `WidgetCard` (sections accept arbitrary JSX) or `ListCard` (with `onItemClick` + `itemActions`) | Hand-rolled `<div>` card with custom expand/collapse logic |
31
- | Status items | `StatusCard` | `<div>` with custom status badges |
32
- | Text summary | `NarrativeSummary` / `SectionCard` | `<div>` with headings and paragraphs |
33
- | Alert / callout | `CalloutCard` | Custom banner div |
34
-
35
- Every visible section of a dashboard should be a library component. If you're writing `<div className="bg-white border rounded-[10px] shadow-sm p-6">` with content inside, that's a hand-rolled card — use a library component instead.
36
-
37
- ### Correct example:
38
-
39
- ```jsx
40
- import { MetricCard, ListCard, ActivityCard, WidgetCard } from "@/components/library";
41
-
42
- // KPIs — use MetricCard
43
- <MetricCard title="Active Travelers" value={6} subtitle="Currently traveling" />
44
-
45
- // List — use ListCard with items array
46
- <ListCard title="Trip Activity" items={trips.map(t => ({
47
- id: t.id, title: t.hotel, description: `${t.city} · ${t.dates}`,
48
- status: t.status, avatar: t.travelerInitials
49
- }))} />
50
-
51
- // Activity feed — use ActivityCard
52
- <ActivityCard title="Eva — Recent Interactions" items={interactions.map(i => ({
53
- id: i.id, title: i.traveler, description: i.query,
54
- status: i.status, timestamp: i.time
55
- }))} />
56
-
57
- // Stats panel — use WidgetCard
58
- <WidgetCard title="Company Activity">
59
- {/* structured content */}
60
- </WidgetCard>
61
- ```
62
-
63
- ### Wrong example (hand-rolled HTML):
64
-
65
- ```jsx
66
- // ❌ NEVER DO THIS — this is a hand-rolled card
67
- <div className="bg-white border border-engine-border rounded-[10px] shadow-sm">
68
- <div className="p-6 border-b border-engine-border">
69
- <h2 className="text-lg font-semibold">Trip Activity</h2>
70
- </div>
71
- <div className="p-6 space-y-4">
72
- {trips.map(trip => (
73
- <div key={trip.id} className="flex gap-4 p-4 rounded-lg border ...">
74
- ...
75
- </div>
76
- ))}
77
- </div>
78
- </div>
79
- ```
80
-
81
- ## Images
82
-
83
- The only image allowed in dashboards is the **company logo**: `src/assets/images/engine_logo.png`. Import it as a module and use it where a logo is needed (nav header, branding, etc.).
84
-
85
- ```jsx
86
- import engineLogo from "@/assets/images/engine_logo.png";
87
-
88
- <img src={engineLogo} alt="Engine" className="h-8 w-auto" />
89
- ```
90
-
91
- - **Do not use external image URLs** (Unsplash, placeholder services, etc.) unless the user explicitly requests images.
92
- - **Do not use other asset images** (codey-*.png, etc.) unless the user asks for them.
93
- - **Preserve aspect ratio** — always use `w-auto` with a fixed height, or `h-auto` with a fixed width. Never set both `w-*` and `h-*` to fixed values on the logo or any image, as this distorts the aspect ratio.
94
-
95
- ```jsx
96
- // ✅ Correct — aspect ratio preserved
97
- <img src={engineLogo} alt="Engine" className="h-8 w-auto" />
98
- <img src={engineLogo} alt="Engine" className="w-24 h-auto" />
99
-
100
- // ❌ Wrong — aspect ratio distorted
101
- <img src={engineLogo} alt="Engine" className="w-8 h-8" />
102
- <div className="w-8 h-8 bg-black rounded" /> // placeholder box instead of logo
103
- ```
104
-
105
- ## No Dashboard-Level Navigation
106
-
107
- Dashboard pages must NOT include their own `<nav>`, header bar, or top navigation of any kind. Navigation is handled by `appLayout.tsx`. The dashboard renders inside the app shell — adding a nav inside the dashboard creates a duplicate header, which is the most visually obvious mistake.
108
-
109
- - ❌ `<nav className="bg-white border-b ...">` inside a dashboard page
110
- - ❌ A header bar with logo + nav links + user avatar inside the dashboard
111
- - ❌ Tab bars that act as top-level navigation (Overview, Travelers, Spend, etc.)
112
- - ❌ `useState("overview")` / `useState("travelers")` to toggle between views — this IS tab navigation even without a `<nav>` element
113
- - ❌ `{activeView === "overview" && (...)}` / `{activeView === "travelers" && (...)}` — content-swapping IS multi-tab navigation
114
- - ✅ Dashboard starts directly with content (metrics, then primary content)
115
- - ✅ If you need sub-sections, use the library `Tabs` component **inside a card** — not as a full-width page-level switcher
116
- - ✅ Build a single-page dashboard — all content visible by scrolling. Do NOT split into multiple tab "pages" that swap content.
117
-
118
- **Self-check:** If your dashboard has `useState` for an "active tab" or "active view" that conditionally renders different page sections, you are building multi-tab navigation. Delete it and put all content on one scrollable page.
119
-
120
- **Self-check:** If your dashboard JSX starts with `<nav>`, a sticky tab bar, or a `<div>` that spans the full width with nav links, you are violating this rule. Delete it.
121
-
122
- ### Why no multi-tab dashboards?
123
-
124
- Splitting a dashboard into 5 tab "pages" (Overview, Travelers, Spend, Policy, Eva) means each tab is a separate mini-app. This violates the single-page dashboard pattern. Instead, put **all sections on one scrollable page** using the vertical page structure (metrics → primary content → secondary content). If content is too long, prioritize the most important sections and use cards with `maxBodyHeight` to constrain tall sections.
125
-
1
+ See SKILL.md — Core Conventions, Library Components, Images, Navigation sections.
@@ -1,30 +1 @@
1
- # Dashboard Build Process
2
-
3
- ## 4-Phase Build
4
-
5
- Build dashboards in 4 distinct phases. Each phase has a dedicated instruction file with a code template in `.a4drules/phases/`:
6
-
7
- | Phase | File | Goal | Output |
8
- |-------|------|------|--------|
9
- | 1 | `phase-1-layout.md` | Layout & structure | Skeleton with placeholders |
10
- | 2 | `phase-2-components.md` | Components & sample data | Fully functional UI with mock data |
11
- | 3 | `phase-3-live-data.md` | Real data integration | Dashboard connected to Salesforce |
12
- | 4 | `phase-4-agent.md` | Agentforce integration | Eva agent + Salesforce signals |
13
-
14
- Each phase file is self-contained — it includes the code template, exact imports, and the 5 constraints that matter for that phase. No cross-references needed.
15
-
16
- ## Why This Works
17
-
18
- - Each phase has a single focus
19
- - Code templates mean less interpretation, faster builds
20
- - Self-contained files eliminate contradictions
21
- - Can stop after any phase (Phase 2 is a complete demo on its own)
22
-
23
- ## Build Prompts
24
-
25
- Each phase is triggered by a simple prompt:
26
-
27
- - Phase 1: "Scaffold the Engine Travel Command Center skeleton"
28
- - Phase 2: "Replace placeholders with library components and sample data"
29
- - Phase 3: "Connect the dashboard to live Salesforce data"
30
- - Phase 4: "Add Eva ChatBar and Salesforce signals"
1
+ See the PRD (engine-command-center-prd.md) section 13 for the 4-phase build process.
@@ -1,145 +1 @@
1
- ## Where Dashboards Live & How to Wire Them
2
-
3
- - Dashboard page files: `src/pages/` (e.g. `EngineDashboard.tsx`, `FleetDashboard.tsx`)
4
- - File format: `.tsx` (MUST be TypeScript) — this is a TypeScript project, all React components use `.tsx`.
5
- - `CommandCenter.tsx` wraps with `AppThemeProvider` + `DataModeProvider` + `Toaster`. **Never recreate these providers in dashboard pages.**
6
-
7
- ### Wiring a new dashboard (REQUIRED STEPS)
8
-
9
- You must do ALL of these or the dashboard will not render correctly:
10
-
11
- **Step 1:** Create the dashboard file in `src/pages/`:
12
- ```tsx
13
- // src/pages/MyDashboard.tsx
14
- import React from "react";
15
- import { MetricCard, ListCard, ChartCard, D3Chart } from "@/components/library";
16
-
17
- export default function MyDashboard() {
18
- return (
19
- <div className="space-y-6 p-6">
20
- {/* dashboard content using library components */}
21
- </div>
22
- );
23
- }
24
- ```
25
-
26
- **Step 2:** Update `CommandCenter.tsx` to import and render it:
27
- ```tsx
28
- // src/components/workspace/CommandCenter.tsx
29
- import AppThemeProvider from "@/components/library/theme/AppThemeProvider";
30
- import DataModeProvider from "@/components/library/data/DataModeProvider";
31
- import { Toaster } from "sonner";
32
- import MyDashboard from "../../pages/MyDashboard"; // ← change this import
33
-
34
- export default function CommandCenter() {
35
- return (
36
- <AppThemeProvider initialMode="light">
37
- <DataModeProvider initialMode="sample">
38
- <MyDashboard /> {/* ← change this */}
39
- <Toaster position="bottom-right" />
40
- </DataModeProvider>
41
- </AppThemeProvider>
42
- );
43
- }
44
- ```
45
-
46
- **Step 2.5:** Update `Home.tsx` to render `CommandCenter`:
47
- ```tsx
48
- // src/pages/Home.tsx
49
- import CommandCenter from "@/components/workspace/CommandCenter";
50
-
51
- export default function HomePage() {
52
- return <CommandCenter />;
53
- }
54
- ```
55
-
56
- **Step 3:** Update `src/routes.tsx` to make the dashboard the home page. Replace the Search page index route with the Home/CommandCenter route:
57
- ```tsx
58
- // src/routes.tsx — change the index route
59
- {
60
- index: true,
61
- element: <SuspenseWrap><Home /></SuspenseWrap>,
62
- handle: { showInNavigation: true, label: 'Dashboard' }
63
- },
64
- {
65
- path: "search",
66
- element: <SuspenseWrap><Search /></SuspenseWrap>,
67
- handle: { showInNavigation: true, label: 'Search' }
68
- },
69
- ```
70
-
71
- The `Home` page renders `CommandCenter`, which renders your dashboard. The Search page moves to `/search`.
72
-
73
- **Verify:** After writing all files, confirm:
74
- 1. Your dashboard `.tsx` file exists in `src/pages/`
75
- 2. `CommandCenter.tsx` (in `src/components/workspace/`) imports your dashboard (not `BlankDashboard`)
76
- 3. `Home.tsx` (in `src/pages/`) imports and renders `CommandCenter` (not search interface)
77
- 4. `src/routes.tsx` has `Home` as the index route and `Search` at `/search`
78
-
79
- ## Page Structure
80
-
81
- Every page follows this vertical order — never rearrange:
82
- 1. Context (NarrativeSummary or heading) — optional
83
- 2. KPI metrics (MetricsStrip or MetricCard grid) — required for dashboards
84
- 3. Primary content (tables, charts, status)
85
- 4. Secondary content (lists, logs, supporting data) — optional
86
- 5. Actions — optional
87
-
88
- Wrap all page content in `<div className="space-y-6">`. Do NOT use `mb-6` between sections — the wrapper handles spacing.
89
-
90
- ## Layout Grids
91
-
92
- Only these grid patterns — do not invent new ones:
93
-
94
- - **4 metrics (MAXIMUM per row — never 5 or more):** `grid grid-cols-2 gap-3 lg:grid-cols-4`
95
- - **3 metrics:** `grid grid-cols-1 gap-3 sm:grid-cols-3`
96
- - **Wide/narrow split:** `grid grid-cols-1 items-start gap-4 lg:grid-cols-3` with `lg:col-span-2` on the wide side
97
- - **3-col balanced:** `grid grid-cols-1 items-start gap-4 lg:grid-cols-3`
98
- - **Equal two-col:** `grid grid-cols-1 items-start gap-4 lg:grid-cols-2`
99
- - **Full-width:** `<div className="w-full">` — charts with 24+ data points
100
-
101
- `gap-4` for content grids, `gap-3` for metric rows. Start `grid-cols-1` (or `grid-cols-2` for metrics) for mobile. Only `sm:` and `lg:` breakpoints unless justified.
102
-
103
- **Max 4 KPIs per row — NEVER 5 or more.** If you have 5+ metrics, split into two rows (e.g. 4 + 1, or 3 + 2). Always `items-start` on grids pairing different-height cards. Use `maxBodyHeight={px}` for long card bodies. Actions go in card `actions` slot. Place `FilterBar` near the data it controls.
104
-
105
- ## Layout Differentiation
106
-
107
- Every dashboard needs a unique layout structure and at least one domain-specific "signature element" that couldn't exist in another dashboard. Vary section ordering, grid proportions, density, and visual rhythm.
108
-
109
- ## Map Layout
110
-
111
- **Default pattern:** GeoMap in a **wide/narrow grid** (`lg:grid-cols-3` with `lg:col-span-2`). This works well for dashboards where the map is one of several equal-weight sections.
112
-
113
- **If the PRD specifies a "visualization-hero" layout**, the map is full-width hero with glass overlays. The PRD always overrides this default pattern.
114
-
115
- **Default pattern: Map + sidebar at matched height**
116
-
117
- ```jsx
118
- <div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
119
- <div className="lg:col-span-2 relative overflow-hidden rounded-xl h-[300px]">
120
- <GeoMap
121
- markers={locations}
122
- arcs={arcs}
123
- overlays={overlays}
124
- initialBounds={{ sw: [-130, 24], ne: [-65, 50], padding: 30 }}
125
- theme="dark"
126
- width={960}
127
- height={480}
128
- zoomable
129
- className="h-full w-full"
130
- />
131
- </div>
132
- {/* Sidebar card — use maxBodyHeight to match map height */}
133
- {/* Map h-[300px] ≈ ListCard maxBodyHeight={236} + ~64px header */}
134
- <ListCard title="Activity" items={items} maxBodyHeight={236} showStatus />
135
- </div>
136
- ```
137
-
138
- Key rules:
139
- - **Do NOT wrap GeoMap in ChartCard** — GeoMap has its own background/borders
140
- - **Match heights** — set map `h-[Xpx]` and sidebar `maxBodyHeight` so they align. Account for ~64px card header padding.
141
- - **Use `initialBounds`** to auto-zoom to the region with data: `{ sw: [lonMin, latMin], ne: [lonMax, latMax], padding: 30 }`
142
- - **Always pass `arcs`** for flight routes and `overlays` for disruption zones — not just markers
143
- - **Use ListCard** (not ActivityCard) for the sidebar — ListCard supports `maxBodyHeight` for scroll, ActivityCard does not
144
- - Keep map height at 280–320px — not 400+
145
-
1
+ See SKILL.md Wiring, Page Structure, Layout Grids, Map Layout sections.
package/CHANGELOG.md CHANGED
@@ -5,7 +5,7 @@ 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.67] - 2026-04-01
8
+ ## [1.9.69] - 2026-04-01
9
9
 
10
10
  ### Fixed
11
11
  - **6 data bugs in engine-sample-data.js**:
@@ -17,27 +17,55 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
17
17
  6. Updated TXL → BER throughout (Berlin airport code change)
18
18
 
19
19
  ### Updated
20
- - **PRD (engine-command-center-prd.md)**:
21
- - Fixed "Sarah Chen" → "Priya Patel" in section 8c escalation example
22
- - Rewrote section 13 build prompts to sound natural (removed AI coaching language)
23
- - Removed "Required skills:" line from header
20
+ - **Global styles** - Added `src/styles/global.css` with Engine brand tokens and command center styling
21
+
22
+ - **PRD (engine-command-center-prd.md)** - Updated to match actual built dashboard:
23
+ - Layout diagram now shows 4-section structure: Header Hero Map → Eva ChatBar → Data Panels (was missing ChatBar section)
24
+ - Layout classes added Eva: `<div className="px-4 pt-4">` as distinct section
25
+ - Section 6 (Header): Explicitly says "No ChatBar in the header — Eva lives below the map." Added "Powered by Agentforce" badge description
26
+ - Section 7 (Hero Map): Added explicit KPI label styling (`text-[10px] font-medium uppercase tracking-wide text-slate-300`) and value/pill/icon specs
27
+ - Section 8a (Escalations): Replaced ActivityCard with custom inline panel in BaseCard. Added full code example with status icons (CheckCircleIcon/ArrowPathIcon/ClockIcon), conditional "Assign to Agent" buttons, and toast.success
28
+ - Section 8c (Active Travelers): Added "View in Salesforce" link in expanded detail
29
+ - Section 9 (Eva): Completely rewritten - ChatBar is now between map and data panels, full-width, with phasing notes (Phase 1 = skip, Phase 4 = add)
30
+ - Section 10 (Signals): Added "Assigned to Eva" toast row for Assign to Agent button
31
+ - Phase 4 build prompt: Updated to say "Add Eva below the map as a ChatBar" and mention "Assign to Agent" buttons on open escalations
32
+ - Applied Option A layout: Escalations + Disruptions in Row 1 (above fold), Active Travelers + Spend in Row 2
33
+ - Both rows use `lg:grid-cols-3` with left panel at 2/3 width
34
+ - Removed all "TDX26" and "demo" references
35
+ - Cut Section 14 "What NOT to Do" entirely
36
+ - Condensed Phase 1 placeholder rules from 75 to 8 lines
37
+
38
+ - **Builder skill (SKILL.md)** - Fixed 4 contradictions:
39
+ - Component table: Split "Activity feed" into two rows: "display only" → ActivityCard, "with per-item actions" → custom markup in BaseCard
40
+ - Component selection table: Same split applied
41
+ - AI Chat & Agent section: Added bullet: "Place ChatBar between the hero map and data panels, NOT in the header"
42
+ - Pre-Completion Checklist: Added exception: panels needing per-item action buttons can use custom markup inside BaseCard
43
+ - General library component rule: Added exception note for per-item action buttons
44
+ - Removed wrong-example code blocks, condensed navigation (40 → 2 lines), removed custom renderChart examples, cut anti-patterns (33 → 12 items)
45
+
46
+ - **Builder skill sub-files** - Replaced with single-line redirects:
47
+ - 7 files reduced from 630 total lines to 7 lines (100% duplicates eliminated)
48
+
24
49
  - **Simplified .a4drules documentation** - Removed redundancy, contradictions, and AI coaching language:
25
- - `features/engine-dashboard-rule.md` - Rewritten as "Project Conventions" (reduced from 310 to ~65 lines)
50
+ - `features/engine-dashboard-rule.md` - Rewritten as "Project Conventions" (~65 lines)
26
51
  - `features/command-center-dashboard-rule.md` - Rewritten as slim conventions (~30 lines)
27
- - `features/pre-code-checklist.md` - Rewritten as "Quick Reference" (~25 lines, removed auto-load)
52
+ - `features/pre-code-checklist.md` - Rewritten as "Quick Reference" (~25 lines)
28
53
  - `features/phase2-data-pattern.md` - Rewritten as "Sample Data" documentation (~20 lines)
29
- - `skills/command-center-builder/SKILL.md` - Fixed map contradiction, removed validator contradiction, removed AI coaching language. Description now includes "Engine Travel Command Center", "scaffold", component names for better matching
30
- - `skills/command-center-builder/page-layout.md` - Fixed map contradiction, softened wiring language
31
- - `skills/command-center-builder/completion-checklist.md` - Removed validator contradiction
32
- - `skills/command-center-builder/improved-build-process.md` - Rewritten as methodology description (~30 lines)
33
- - `skills/command-center-builder/getting-started.md` - Removed AI coaching language
34
- - `skills/command-center-builder/components-styling.md` - Removed (MANDATORY) header
35
- - `skills/command-center-builder/charts-visualization.md` - Removed (MANDATORY) header
36
- - `skills/command-center-project/SKILL.md` - Fixed file path contradiction (src/components/pages/ → src/pages/). Description now includes "Engine Travel Command Center", tech stack keywords
37
- - `skills/command-center-guide/SKILL.md` - Reduced from 270 to ~45 lines (simplified routing guide). Description improved for better matching
38
- - `skills/component-library/SKILL.md` - Description now lists all key component names (MetricCard, ChartCard, GeoMap, etc.) for better matching
39
-
40
- **Context:** Complete documentation overhaul to eliminate confusion from scattered, contradictory guidance. Removed prescriptive AI coaching language in favor of clear technical conventions. Improved skill descriptions for better discoverability.
54
+ - `skills/command-center-project/SKILL.md` - Fixed file path contradiction
55
+ - `skills/command-center-guide/SKILL.md` - Reduced from 270 to ~45 lines
56
+ - `skills/component-library/SKILL.md` - Description now lists all key component names
57
+
58
+ **Context:** PRD now accurately reflects the actual built dashboard with Eva ChatBar between map and data panels. Eliminated contradictions about ActivityCard vs custom markup for action buttons.
59
+
60
+ ## [1.9.68] - 2026-04-01
61
+
62
+ ### Updated
63
+ - **Major documentation consolidation** - PRD reduced 39%, builder skill sub-files eliminated duplication, overall .a4drules reduced from ~2000 to ~800 lines
64
+
65
+ ## [1.9.67] - 2026-04-01
66
+
67
+ ### Updated
68
+ - **Skill descriptions** - Improved for better discoverability and matching
41
69
 
42
70
  ## [1.9.66] - 2026-04-01
43
71