Skip to content

Commit 5d508fa

Browse files
Copilothotlong
andcommitted
Add example interfaces and modern app demonstrating new pattern
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 19f60a2 commit 5d508fa

7 files changed

Lines changed: 258 additions & 0 deletions

File tree

examples/app-crm/objectstack.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import * as agents from './src/agents';
1313
import * as ragPipelines from './src/rag';
1414
import * as profiles from './src/profiles';
1515
import * as apps from './src/apps';
16+
import * as interfaces from './src/interfaces';
1617
import * as translations from './src/translations';
1718
import { CrmSeedData } from './src/data';
1819

@@ -46,6 +47,7 @@ export default defineStack({
4647
ragPipelines: Object.values(ragPipelines),
4748
profiles: Object.values(profiles),
4849
apps: Object.values(apps),
50+
interfaces: Object.values(interfaces),
4951

5052
// Seed Data (top-level, registered as metadata)
5153
data: CrmSeedData,
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2+
3+
import { defineApp } from '@objectstack/spec/ui';
4+
5+
/**
6+
* Modern CRM App using the new Interface-driven navigation pattern
7+
*
8+
* Demonstrates:
9+
* - App.interfaces[] for main navigation (auto-generates Interface→Pages sidebar)
10+
* - App.defaultInterface for startup interface
11+
* - App.navigation[] repurposed for global utility entries only (Settings, Help)
12+
*/
13+
export const CrmAppModern = defineApp({
14+
name: 'crm_modern',
15+
label: 'CRM (Modern)',
16+
description: 'Enterprise CRM with Interface-driven navigation',
17+
icon: 'briefcase',
18+
19+
branding: {
20+
primaryColor: '#4169E1',
21+
logo: '/assets/crm-logo.png',
22+
favicon: '/assets/crm-favicon.ico',
23+
},
24+
25+
// NEW: Interface-driven navigation
26+
// The sidebar will auto-render a two-level menu:
27+
// - Sales Cloud (group)
28+
// - Sales Workspace (interface) → Pipeline, Accounts, Leads (pages)
29+
// - Lead Review (interface) → Review Queue, Qualified Leads (pages)
30+
// - Analytics (group)
31+
// - Sales Analytics (interface) → Overview, Pipeline Report (pages)
32+
interfaces: ['sales_workspace', 'lead_review', 'sales_analytics'],
33+
34+
// NEW: Default interface on app launch
35+
defaultInterface: 'sales_workspace',
36+
37+
// REPURPOSED: navigation[] is now for global utility entries only
38+
// These render at the bottom of the sidebar
39+
navigation: [
40+
{
41+
id: 'nav_settings',
42+
type: 'page',
43+
label: 'Settings',
44+
icon: 'settings',
45+
pageName: 'admin_settings',
46+
},
47+
{
48+
id: 'nav_help',
49+
type: 'url',
50+
label: 'Help Center',
51+
icon: 'help-circle',
52+
url: 'https://help.example.com',
53+
target: '_blank',
54+
},
55+
],
56+
57+
requiredPermissions: ['app.access.crm'],
58+
isDefault: true,
59+
});

examples/app-crm/src/apps/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
* App Definitions Barrel
55
*/
66
export { CrmApp } from './crm.app';
7+
export { CrmAppModern } from './crm_modern.app';
8+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2+
3+
export { SalesWorkspaceInterface } from './sales_workspace.interface';
4+
export { LeadReviewInterface } from './lead_review.interface';
5+
export { SalesAnalyticsInterface } from './sales_analytics.interface';
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2+
3+
import { defineInterface } from '@objectstack/spec/ui';
4+
5+
/**
6+
* Lead Review Interface
7+
* Sequential lead qualification and assignment workflow
8+
*/
9+
export const LeadReviewInterface = defineInterface({
10+
name: 'lead_review',
11+
label: 'Lead Review',
12+
description: 'Review and qualify incoming leads',
13+
icon: 'clipboard-check',
14+
group: 'Sales Cloud',
15+
object: 'lead',
16+
17+
pages: [
18+
{
19+
name: 'page_review_queue',
20+
label: 'Review Queue',
21+
type: 'record_review',
22+
icon: 'check-square',
23+
object: 'lead',
24+
recordReview: {
25+
object: 'lead',
26+
filter: { status: 'new' },
27+
sort: [{ field: 'created_at', order: 'desc' }],
28+
displayFields: ['company', 'title', 'email', 'phone', 'source'],
29+
actions: [
30+
{
31+
label: 'Qualify',
32+
type: 'approve',
33+
field: 'status',
34+
value: 'qualified',
35+
nextRecord: true,
36+
},
37+
{
38+
label: 'Disqualify',
39+
type: 'reject',
40+
field: 'status',
41+
value: 'disqualified',
42+
nextRecord: true,
43+
},
44+
{
45+
label: 'Skip',
46+
type: 'skip',
47+
nextRecord: true,
48+
},
49+
],
50+
navigation: 'sequential',
51+
showProgress: true,
52+
},
53+
regions: [],
54+
},
55+
{
56+
name: 'page_qualified',
57+
label: 'Qualified Leads',
58+
type: 'grid',
59+
icon: 'check-circle',
60+
object: 'lead',
61+
regions: [],
62+
},
63+
],
64+
65+
homePageName: 'page_review_queue',
66+
assignedRoles: ['sales_manager', 'lead_qualifier'],
67+
});
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2+
3+
import { defineInterface } from '@objectstack/spec/ui';
4+
5+
/**
6+
* Sales Analytics Interface
7+
* Dashboards and reports for sales metrics
8+
*/
9+
export const SalesAnalyticsInterface = defineInterface({
10+
name: 'sales_analytics',
11+
label: 'Sales Analytics',
12+
description: 'Sales performance dashboards and analytics',
13+
icon: 'chart-line',
14+
group: 'Analytics',
15+
object: 'opportunity',
16+
17+
pages: [
18+
{
19+
name: 'page_overview',
20+
label: 'Overview',
21+
type: 'dashboard',
22+
icon: 'gauge',
23+
regions: [
24+
{
25+
name: 'main',
26+
components: [
27+
{
28+
type: 'element:text',
29+
properties: {
30+
content: '# Sales Performance',
31+
variant: 'heading',
32+
},
33+
},
34+
{
35+
type: 'element:number',
36+
properties: {
37+
object: 'opportunity',
38+
aggregate: 'count',
39+
},
40+
dataSource: {
41+
object: 'opportunity',
42+
filter: { stage: 'closed_won' },
43+
},
44+
},
45+
{
46+
type: 'element:number',
47+
properties: {
48+
object: 'opportunity',
49+
field: 'amount',
50+
aggregate: 'sum',
51+
format: 'currency',
52+
prefix: '$',
53+
},
54+
dataSource: {
55+
object: 'opportunity',
56+
filter: { stage: 'closed_won' },
57+
},
58+
},
59+
],
60+
},
61+
],
62+
},
63+
{
64+
name: 'page_pipeline',
65+
label: 'Pipeline Report',
66+
type: 'dashboard',
67+
icon: 'chart-bar',
68+
regions: [],
69+
},
70+
],
71+
72+
homePageName: 'page_overview',
73+
assignedRoles: ['sales_manager', 'exec'],
74+
branding: {
75+
primaryColor: '#1A73E8',
76+
},
77+
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2+
3+
import { defineInterface } from '@objectstack/spec/ui';
4+
5+
/**
6+
* Sales Workspace Interface
7+
* Primary sales rep workspace with pipeline, accounts, and leads
8+
*/
9+
export const SalesWorkspaceInterface = defineInterface({
10+
name: 'sales_workspace',
11+
label: 'Sales Workspace',
12+
description: 'Primary workspace for sales representatives',
13+
icon: 'briefcase',
14+
group: 'Sales Cloud',
15+
object: 'opportunity',
16+
17+
pages: [
18+
{
19+
name: 'page_pipeline',
20+
label: 'Pipeline',
21+
type: 'kanban',
22+
icon: 'columns',
23+
object: 'opportunity',
24+
regions: [],
25+
},
26+
{
27+
name: 'page_accounts',
28+
label: 'Accounts',
29+
type: 'grid',
30+
icon: 'building',
31+
object: 'account',
32+
regions: [],
33+
},
34+
{
35+
name: 'page_leads',
36+
label: 'Leads',
37+
type: 'list',
38+
icon: 'user-plus',
39+
object: 'lead',
40+
regions: [],
41+
},
42+
],
43+
44+
homePageName: 'page_pipeline',
45+
assignedRoles: ['sales_rep', 'sales_manager'],
46+
});

0 commit comments

Comments
 (0)