@schandlergarcia/sf-web-components 1.9.67 → 1.9.68

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.68] - 2026-04-01
9
9
 
10
10
  ### Fixed
11
11
  - **6 data bugs in engine-sample-data.js**:
@@ -17,27 +17,44 @@ 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)**:
20
+ - **PRD (engine-command-center-prd.md)** - Major rewrite (481 → 290 lines, -39%):
21
+ - Applied Option A layout: Escalations + Disruptions in Row 1 (above fold), Active Travelers + Spend in Row 2
22
+ - Both rows now use `lg:grid-cols-3` with left panel at 2/3 width
23
+ - Removed all "TDX26" and "demo" references
24
+ - Cut Section 14 "What NOT to Do" entirely (covered by builder rules)
25
+ - Cut all "Why" explanations and duplicate wrong/right examples
26
+ - Condensed Phase 1 placeholder rules from 75 lines to 8
27
+ - Sharpened every code example to be copy-ready
21
28
  - Fixed "Sarah Chen" → "Priya Patel" in section 8c escalation example
22
- - Rewrote section 13 build prompts to sound natural (removed AI coaching language)
23
29
  - Removed "Required skills:" line from header
30
+
31
+ - **Builder skill sub-files** - Replaced with single-line redirects (100% duplicates):
32
+ - `skills/command-center-builder/getting-started.md` - 125 → 1 line
33
+ - `skills/command-center-builder/page-layout.md` - 145 → 1 line
34
+ - `skills/command-center-builder/components-styling.md` - 98 → 1 line
35
+ - `skills/command-center-builder/charts-visualization.md` - 136 → 1 line
36
+ - `skills/command-center-builder/completion-checklist.md` - 62 → 1 line
37
+ - `skills/command-center-builder/data-forms-ai.md` - 44 → 1 line
38
+ - `skills/command-center-builder/improved-build-process.md` - 20 → 1 line
39
+
40
+ - **Builder skill main file** - Trimmed (629 → 505 lines, -20%):
41
+ - `skills/command-center-builder/SKILL.md` - Removed wrong-example code blocks, condensed navigation section from 40 to 2 lines, trimmed map layout section, removed custom renderChart examples, cut anti-patterns list from 33 to 12 items
42
+
24
43
  - **Simplified .a4drules documentation** - Removed redundancy, contradictions, and AI coaching language:
25
44
  - `features/engine-dashboard-rule.md` - Rewritten as "Project Conventions" (reduced from 310 to ~65 lines)
26
45
  - `features/command-center-dashboard-rule.md` - Rewritten as slim conventions (~30 lines)
27
46
  - `features/pre-code-checklist.md` - Rewritten as "Quick Reference" (~25 lines, removed auto-load)
28
47
  - `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
48
  - `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
49
  - `skills/command-center-guide/SKILL.md` - Reduced from 270 to ~45 lines (simplified routing guide). Description improved for better matching
38
50
  - `skills/component-library/SKILL.md` - Description now lists all key component names (MetricCard, ChartCard, GeoMap, etc.) for better matching
39
51
 
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.
52
+ **Context:** Major documentation consolidation. PRD is now 39% shorter with copy-ready code. Builder skill sub-files eliminated duplication by redirecting to SKILL.md. Overall .a4drules reduced from ~2000 to ~800 lines while improving clarity.
53
+
54
+ ## [1.9.67] - 2026-04-01
55
+
56
+ ### Updated
57
+ - **Skill descriptions** - Improved for better discoverability and matching
41
58
 
42
59
  ## [1.9.66] - 2026-04-01
43
60