Skip to content

Commit 62563b3

Browse files
committed
2 parents 87fb927 + 7968b1f commit 62563b3

File tree

7 files changed

+856
-96
lines changed

7 files changed

+856
-96
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
- **Polished `examples/app-crm` dashboards** — Rewrote `executive`, `sales`, and `service` dashboards and added a new unified `crm` overview dashboard, modeled after the reference implementation at [objectstack-ai/objectui/examples/crm](https://github.com/objectstack-ai/objectui/tree/main/examples/crm/src/dashboards). The dashboards now use the framework's first-class metadata fields instead of ad-hoc hex strings stuffed into `options.color`:
12+
- Semantic `colorVariant` tokens (`success`/`warning`/`danger`/`blue`/`teal`/`purple`/`orange`) replace raw hex codes
13+
- Each widget carries a `description`, `chartConfig` (axes, color palette, annotations, interaction), and a header `actionUrl`/`actionType`/`actionIcon` for drill-down
14+
- Each dashboard declares a structured `header` with action buttons, a `dateRange` global time filter, `globalFilters` (owner / industry / priority lookups), and a `refreshInterval`
15+
- KPI metric widgets carry `icon`, `format`, and `trend` indicators (direction + delta + label) in `options`, mirroring the objectui reference visual style
16+
- Chart variety expanded: `area` (revenue trends), `donut` (lead source / industry), `funnel` (pipeline by stage), `gauge` (SLA compliance), `horizontal-bar` (rep ranking), with proper axis titles and value formatters
17+
- Table widgets use structured `columns: [{ header, accessorKey, format }]` instead of bare field-name arrays
18+
- New `examples/app-crm/test/dashboard.test.ts` validates every dashboard against `DashboardSchema` and enforces these conventions
19+
1020
### Added
1121
- **Release-readiness documentation pass (42 packages)** — Aligned every `@objectstack/*` package for the formal v4.x release:
1222
- Canonical README template and `package.json` publishing checklist committed at `docs/internal/PACKAGE_README_TEMPLATE.md`
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2+
3+
import type { Dashboard } from '@objectstack/spec/ui';
4+
5+
/**
6+
* CRM Overview Dashboard
7+
*
8+
* Single-page snapshot of revenue, pipeline, and customer activity. Designed
9+
* to mirror the polished CRM dashboard reference at
10+
* https://github.com/objectstack-ai/objectui/tree/main/examples/crm/src/dashboards
11+
* — KPI tiles with trend indicators and icons, an area-chart revenue trend, a
12+
* lead-source donut, a pipeline funnel, and a recent-deals table.
13+
*
14+
* This dashboard intentionally uses the framework's first-class metadata fields
15+
* (colorVariant, chartConfig, header, dateRange, descriptions, action buttons)
16+
* rather than ad-hoc hex strings stuffed into `options.color`.
17+
*/
18+
export const CrmOverviewDashboard: Dashboard = {
19+
name: 'crm_overview_dashboard',
20+
label: 'CRM Overview',
21+
description: 'Revenue metrics, pipeline analytics, and deal insights',
22+
23+
refreshInterval: 300,
24+
25+
header: {
26+
showTitle: true,
27+
showDescription: true,
28+
actions: [
29+
{ label: 'New Deal', icon: 'Plus', actionType: 'modal', actionUrl: 'create_opportunity' },
30+
{ label: 'New Lead', icon: 'Sparkles', actionType: 'modal', actionUrl: 'create_lead' },
31+
{ label: 'Reports', icon: 'BarChart3', actionType: 'url', actionUrl: '/reports' },
32+
],
33+
},
34+
35+
dateRange: {
36+
field: 'close_date',
37+
defaultRange: 'this_quarter',
38+
allowCustomRange: true,
39+
},
40+
41+
globalFilters: [
42+
{
43+
field: 'owner',
44+
label: 'Owner',
45+
type: 'lookup',
46+
scope: 'dashboard',
47+
optionsFrom: { object: 'user', valueField: 'id', labelField: 'name' },
48+
},
49+
],
50+
51+
widgets: [
52+
// ─── KPI Row ──────────────────────────────────────────────────────
53+
{
54+
id: 'total_revenue',
55+
title: 'Total Revenue',
56+
description: 'Closed-won revenue this period',
57+
type: 'metric',
58+
object: 'opportunity',
59+
filter: { stage: 'closed_won' },
60+
valueField: 'amount',
61+
aggregate: 'sum',
62+
colorVariant: 'success',
63+
actionUrl: '/reports/revenue',
64+
actionType: 'url',
65+
actionIcon: 'ArrowUpRight',
66+
layout: { x: 0, y: 0, w: 3, h: 2 },
67+
options: {
68+
icon: 'DollarSign',
69+
format: '$0,0',
70+
prefix: '$',
71+
trend: { value: 12.5, direction: 'up', label: 'vs last month' },
72+
},
73+
},
74+
{
75+
id: 'active_deals',
76+
title: 'Active Deals',
77+
description: 'Open opportunities in the pipeline',
78+
type: 'metric',
79+
object: 'opportunity',
80+
filter: { stage: { $nin: ['closed_won', 'closed_lost'] } },
81+
aggregate: 'count',
82+
colorVariant: 'blue',
83+
actionUrl: '/objects/opportunity?filter=open',
84+
actionType: 'url',
85+
actionIcon: 'ArrowUpRight',
86+
layout: { x: 3, y: 0, w: 3, h: 2 },
87+
options: {
88+
icon: 'Briefcase',
89+
format: '0,0',
90+
trend: { value: 2.1, direction: 'down', label: 'vs last month' },
91+
},
92+
},
93+
{
94+
id: 'win_rate',
95+
title: 'Win Rate',
96+
description: 'Closed-won share of resolved deals this period',
97+
type: 'metric',
98+
object: 'opportunity',
99+
filter: { stage: { $in: ['closed_won', 'closed_lost'] } },
100+
valueField: 'is_won',
101+
aggregate: 'avg',
102+
colorVariant: 'purple',
103+
actionUrl: '/reports/win-rate',
104+
actionType: 'url',
105+
actionIcon: 'ArrowUpRight',
106+
layout: { x: 6, y: 0, w: 3, h: 2 },
107+
options: {
108+
icon: 'Trophy',
109+
format: '0%',
110+
suffix: '%',
111+
trend: { value: 4.3, direction: 'up', label: 'vs last month' },
112+
},
113+
},
114+
{
115+
id: 'avg_deal_size',
116+
title: 'Avg Deal Size',
117+
description: 'Average value of closed-won deals',
118+
type: 'metric',
119+
object: 'opportunity',
120+
filter: { stage: 'closed_won' },
121+
valueField: 'amount',
122+
aggregate: 'avg',
123+
colorVariant: 'orange',
124+
actionUrl: '/reports/avg-deal-size',
125+
actionType: 'url',
126+
actionIcon: 'ArrowUpRight',
127+
layout: { x: 9, y: 0, w: 3, h: 2 },
128+
options: {
129+
icon: 'BarChart3',
130+
format: '$0,0',
131+
prefix: '$',
132+
trend: { value: 1.2, direction: 'up', label: 'vs last month' },
133+
},
134+
},
135+
136+
// ─── Charts Row 1 ─────────────────────────────────────────────────
137+
{
138+
id: 'revenue_trends',
139+
title: 'Revenue Trends',
140+
description: 'Closed-won revenue over the last 12 months',
141+
type: 'area',
142+
object: 'opportunity',
143+
filter: { stage: 'closed_won', close_date: { $gte: '{last_12_months}' } },
144+
categoryField: 'close_date',
145+
valueField: 'amount',
146+
aggregate: 'sum',
147+
colorVariant: 'success',
148+
layout: { x: 0, y: 2, w: 9, h: 4 },
149+
chartConfig: {
150+
type: 'area',
151+
showLegend: false,
152+
showDataLabels: false,
153+
colors: ['#10B981'],
154+
xAxis: { field: 'close_date', title: 'Month', showGridLines: false },
155+
yAxis: [{ field: 'amount', title: 'Revenue', format: '$0,0', showGridLines: true }],
156+
interaction: { tooltips: true, brush: true },
157+
},
158+
options: { dateGranularity: 'month' },
159+
},
160+
{
161+
id: 'lead_source',
162+
title: 'Lead Source',
163+
description: 'Pipeline value by acquisition channel',
164+
type: 'donut',
165+
object: 'opportunity',
166+
categoryField: 'lead_source',
167+
valueField: 'amount',
168+
aggregate: 'sum',
169+
colorVariant: 'purple',
170+
layout: { x: 9, y: 2, w: 3, h: 4 },
171+
chartConfig: {
172+
type: 'donut',
173+
showLegend: true,
174+
showDataLabels: true,
175+
colors: ['#4F46E5', '#06B6D4', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6'],
176+
},
177+
},
178+
179+
// ─── Charts Row 2 ─────────────────────────────────────────────────
180+
{
181+
id: 'pipeline_by_stage',
182+
title: 'Pipeline by Stage',
183+
description: 'Open opportunity value at each sales stage',
184+
type: 'funnel',
185+
object: 'opportunity',
186+
filter: { stage: { $nin: ['closed_won', 'closed_lost'] } },
187+
categoryField: 'stage',
188+
valueField: 'amount',
189+
aggregate: 'sum',
190+
colorVariant: 'teal',
191+
layout: { x: 0, y: 6, w: 6, h: 4 },
192+
chartConfig: {
193+
type: 'funnel',
194+
showLegend: false,
195+
showDataLabels: true,
196+
colors: ['#0EA5E9', '#06B6D4', '#14B8A6', '#10B981', '#22C55E'],
197+
},
198+
},
199+
{
200+
id: 'top_products',
201+
title: 'Top Products',
202+
description: 'Total list-price revenue by product category',
203+
type: 'bar',
204+
object: 'product',
205+
categoryField: 'category',
206+
valueField: 'price',
207+
aggregate: 'sum',
208+
colorVariant: 'blue',
209+
layout: { x: 6, y: 6, w: 6, h: 4 },
210+
chartConfig: {
211+
type: 'bar',
212+
showLegend: false,
213+
showDataLabels: true,
214+
colors: ['#4F46E5'],
215+
xAxis: { field: 'category', title: 'Category', showGridLines: false },
216+
yAxis: [{ field: 'price', title: 'Revenue', format: '$0,0', showGridLines: true }],
217+
},
218+
},
219+
220+
// ─── Recent Deals Table ───────────────────────────────────────────
221+
{
222+
id: 'recent_opportunities',
223+
title: 'Recent Opportunities',
224+
description: 'Most recently updated deals across the team',
225+
type: 'table',
226+
object: 'opportunity',
227+
aggregate: 'count',
228+
colorVariant: 'default',
229+
layout: { x: 0, y: 10, w: 12, h: 4 },
230+
options: {
231+
columns: [
232+
{ header: 'Opportunity', accessorKey: 'name' },
233+
{ header: 'Account', accessorKey: 'account' },
234+
{ header: 'Amount', accessorKey: 'amount', format: '$0,0' },
235+
{ header: 'Stage', accessorKey: 'stage' },
236+
{ header: 'Probability', accessorKey: 'probability', format: '0%' },
237+
{ header: 'Close Date', accessorKey: 'close_date', format: 'MMM D, YYYY' },
238+
{ header: 'Owner', accessorKey: 'owner' },
239+
],
240+
sortBy: 'last_modified_date',
241+
sortOrder: 'desc',
242+
limit: 10,
243+
striped: true,
244+
density: 'comfortable',
245+
},
246+
},
247+
],
248+
};

0 commit comments

Comments
 (0)