Skip to content

Commit ff096e4

Browse files
committed
Add new objects and enhance existing schemas for CRM application
1 parent b1814b5 commit ff096e4

8 files changed

Lines changed: 200 additions & 18 deletions

File tree

examples/crm/objectstack.config.ts

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,68 @@ import { App } from '@objectstack/spec/ui';
33
import { AccountObject } from './src/objects/account.object';
44
import { ContactObject } from './src/objects/contact.object';
55
import { OpportunityObject } from './src/objects/opportunity.object';
6+
import { ProductObject } from './src/objects/product.object';
7+
import { OrderObject } from './src/objects/order.object';
8+
import { UserObject } from './src/objects/user.object';
69

710
export default defineStack({
811
objects: [
912
AccountObject,
1013
ContactObject,
11-
OpportunityObject
14+
OpportunityObject,
15+
ProductObject,
16+
OrderObject,
17+
UserObject
1218
],
1319
apps: [
1420
App.create({
1521
name: 'crm_app',
1622
label: 'CRM',
1723
icon: 'users',
1824
navigation: [
25+
{
26+
id: 'nav_dashboard',
27+
type: 'page',
28+
pageName: 'dashboard',
29+
label: 'Dashboard',
30+
icon: 'layout-dashboard'
31+
},
1932
{
2033
id: 'nav_contacts',
2134
type: 'object',
2235
objectName: 'contact',
2336
label: 'Contacts'
2437
},
38+
{
39+
id: 'nav_accounts',
40+
type: 'object',
41+
objectName: 'account',
42+
label: 'Accounts'
43+
},
2544
{
2645
id: 'nav_opportunities',
2746
type: 'object',
2847
objectName: 'opportunity',
2948
label: 'Opportunities'
3049
},
3150
{
32-
id: 'nav_accounts',
33-
type: 'object',
34-
objectName: 'account',
35-
label: 'Accounts'
51+
id: 'nav_sales',
52+
type: 'group',
53+
label: 'Sales',
54+
children: [
55+
{
56+
id: 'nav_orders',
57+
type: 'object',
58+
objectName: 'order',
59+
label: 'Orders'
60+
},
61+
{
62+
id: 'nav_products',
63+
type: 'object',
64+
objectName: 'product',
65+
label: 'Products'
66+
}
67+
]
3668
}
3769
]
3870
})
@@ -97,6 +129,31 @@ export default defineStack({
97129
description: "Consulting services for Q2 implementation."
98130
}
99131
]
132+
},
133+
{
134+
object: 'user',
135+
mode: 'upsert',
136+
records: [
137+
{ _id: "1", name: 'John Doe', email: 'john@example.com', username: 'jdoe', role: 'admin', active: true },
138+
{ _id: "2", name: 'Jane Smith', email: 'jane@example.com', username: 'jsmith', role: 'user', active: true }
139+
]
140+
},
141+
{
142+
object: 'product',
143+
mode: 'upsert',
144+
records: [
145+
{ _id: "p1", sku: 'PROD-001', name: 'Laptop', category: 'Electronics', price: 1299.99, stock: 15 },
146+
{ _id: "p2", sku: 'PROD-002', name: 'Mouse', category: 'Electronics', price: 29.99, stock: 120 },
147+
{ _id: "p3", sku: 'PROD-003', name: 'Desk Chair', category: 'Furniture', price: 249.99, stock: 8 }
148+
]
149+
},
150+
{
151+
object: 'order',
152+
mode: 'upsert',
153+
records: [
154+
{ _id: "o1", name: 'ORD-1001', customer: "1", order_date: new Date('2024-01-15'), amount: 159.99, status: 'Draft' },
155+
{ _id: "o2", name: 'ORD-1002', customer: "2", order_date: new Date('2024-01-18'), amount: 89.50, status: 'Pending' }
156+
]
100157
}
101158
]
102159
}

examples/crm/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
export * from './objects/account.object';
22
export * from './objects/contact.object';
33
export * from './objects/opportunity.object';
4+
export * from './objects/product.object';
5+
export * from './objects/order.object';
6+
export * from './objects/user.object';
47
export { default as config } from '../objectstack.config';

examples/crm/src/objects/account.object.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,26 @@ import { ObjectSchema, Field } from '@objectstack/spec/data';
33
export const AccountObject = ObjectSchema.create({
44
name: 'account',
55
label: 'Account',
6+
icon: 'building',
67
fields: {
7-
name: Field.text({ label: 'Account Name', required: true }),
8-
industry: Field.text({ label: 'Industry' })
8+
name: Field.text({ label: 'Account Name', required: true, searchable: true }),
9+
industry: Field.select(['Technology', 'Finance', 'Healthcare', 'Retail', 'Manufacturing'], { label: 'Industry', filterable: true }),
10+
rating: Field.select(['Hot', 'Warm', 'Cold'], { label: 'Rating' }),
11+
type: Field.select(['Customer', 'Partner', 'Reseller', 'Vendor'], { label: 'Type' }),
12+
annual_revenue: Field.currency({ label: 'Annual Revenue' }),
13+
website: Field.url({ label: 'Website' }),
14+
phone: Field.text({ label: 'Phone' }),
15+
owner: Field.lookup('user', { label: 'Owner' })
16+
},
17+
list_views: {
18+
all: {
19+
label: 'All Accounts',
20+
columns: ['name', 'industry', 'type', 'phone', 'website']
21+
},
22+
customers: {
23+
label: 'Customers',
24+
columns: ['name', 'industry', 'annual_revenue'],
25+
filter: [['type', '=', 'Customer']]
26+
}
927
}
1028
});

examples/crm/src/objects/contact.object.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,27 @@ import { ObjectSchema, Field } from '@objectstack/spec/data';
33
export const ContactObject = ObjectSchema.create({
44
name: 'contact',
55
label: 'Contact',
6+
icon: 'user',
67
fields: {
7-
name: Field.text({ label: 'Name', required: true }),
8-
email: Field.email({ label: 'Email' }),
8+
name: Field.text({ label: 'Name', required: true, searchable: true }),
9+
email: Field.email({ label: 'Email', searchable: true }),
910
phone: Field.text({ label: 'Phone' }),
1011
title: Field.text({ label: 'Title' }),
11-
company: Field.text({ label: 'Company' }),
12-
status: Field.select(['Active', 'Lead', 'Customer'], { label: 'Status' }),
13-
priority: Field.number({ label: 'Priority', defaultValue: 5 }),
12+
account: Field.lookup('account', { label: 'Account' }),
13+
status: Field.select(['Active', 'Lead', 'Customer'], { label: 'Status', filterable: true }),
14+
priority: Field.select(['High', 'Medium', 'Low'], { label: 'Priority', defaultValue: 'Medium' }),
1415
is_active: Field.boolean({ label: 'Active', defaultValue: true }),
1516
notes: Field.textarea({ label: 'Notes' })
17+
},
18+
list_views: {
19+
all: {
20+
label: 'All Contacts',
21+
columns: ['name', 'account', 'email', 'phone', 'title', 'status']
22+
},
23+
mypending: {
24+
label: 'My Pending Contacts',
25+
columns: ['name', 'account', 'status', 'priority'],
26+
filter: [['status', '!=', 'Active']]
27+
}
1628
}
1729
});

examples/crm/src/objects/opportunity.object.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,31 @@ import { ObjectSchema, Field } from '@objectstack/spec/data';
33
export const OpportunityObject = ObjectSchema.create({
44
name: 'opportunity',
55
label: 'Opportunity',
6+
icon: 'trending-up',
67
fields: {
7-
name: Field.text({ label: 'Opportunity Name', required: true }),
8-
amount: Field.currency({ label: 'Amount' }),
9-
stage: Field.select(["Prospecting", "Proposal", "Negotiation", "Closed Won", "Closed Lost"], { label: 'Stage' }),
10-
close_date: Field.date({ label: 'Close Date' }),
11-
account_id: Field.lookup('account', { label: 'Account' }),
12-
contact_ids: Field.lookup('contact', { label: 'Contacts', multiple: true }),
8+
name: Field.text({ label: 'Opportunity Name', required: true, searchable: true }),
9+
amount: Field.currency({ label: 'Amount', sortable: true }),
10+
stage: Field.select(["Prospecting", "Proposal", "Negotiation", "Closed Won", "Closed Lost"], { label: 'Stage', filterable: true }),
11+
close_date: Field.date({ label: 'Close Date', sortable: true }),
12+
account: Field.lookup('account', { label: 'Account' }),
13+
contacts: Field.lookup('contact', { label: 'Contacts', multiple: true }),
14+
probability: Field.percent({ label: 'Probability' }),
1315
description: Field.textarea({ label: 'Description' })
16+
},
17+
list_views: {
18+
all: {
19+
label: 'All Opportunities',
20+
columns: ['name', 'account', 'amount', 'stage', 'close_date']
21+
},
22+
closing_soon: {
23+
label: 'Closing Soon',
24+
columns: ['name', 'amount', 'stage', 'close_date'],
25+
sort: [['close_date', 'asc']]
26+
},
27+
won: {
28+
label: 'Won',
29+
columns: ['name', 'amount', 'account', 'close_date'],
30+
filter: [['stage', '=', 'Closed Won']]
31+
}
1432
}
1533
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { ObjectSchema, Field } from '@objectstack/spec/data';
2+
3+
export const OrderObject = ObjectSchema.create({
4+
name: 'order',
5+
label: 'Order',
6+
icon: 'shopping-cart',
7+
fields: {
8+
name: Field.text({ label: 'Order Number', required: true, searchable: true }),
9+
customer: Field.lookup('contact', { label: 'Customer', required: true }),
10+
amount: Field.currency({ label: 'Total Amount', sortable: true }),
11+
status: Field.select(['Draft', 'Pending', 'Paid', 'Shipped', 'Delivered', 'Cancelled'], { label: 'Status', defaultValue: 'Draft', filterable: true }),
12+
order_date: Field.date({ label: 'Order Date', defaultValue: 'now' })
13+
},
14+
list_views: {
15+
all: {
16+
label: 'All Orders',
17+
columns: ['name', 'customer', 'amount', 'status', 'order_date'],
18+
sort: [['order_date', 'desc']]
19+
},
20+
pending: {
21+
label: 'Pending Orders',
22+
columns: ['name', 'customer', 'amount', 'order_date'],
23+
filter: [['status', '=', 'Pending']]
24+
}
25+
}
26+
});
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { ObjectSchema, Field } from '@objectstack/spec/data';
2+
3+
export const ProductObject = ObjectSchema.create({
4+
name: 'product',
5+
label: 'Product',
6+
icon: 'package',
7+
fields: {
8+
name: Field.text({ label: 'Product Name', required: true, searchable: true }),
9+
sku: Field.text({ label: 'SKU', required: true, searchable: true }),
10+
category: Field.select(['Electronics', 'Furniture', 'Clothing', 'Services'], { label: 'Category', filterable: true }),
11+
price: Field.currency({ label: 'Price', sortable: true }),
12+
stock: Field.number({ label: 'Stock', sortable: true }),
13+
description: Field.textarea({ label: 'Description' }),
14+
image: Field.url({ label: 'Image URL' })
15+
},
16+
list_views: {
17+
all: {
18+
label: 'All Products',
19+
columns: ['name', 'sku', 'category', 'price', 'stock']
20+
},
21+
low_stock: {
22+
label: 'Low Stock',
23+
columns: ['name', 'stock', 'price'],
24+
filter: [['stock', '<', 10]]
25+
}
26+
}
27+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { ObjectSchema, Field } from '@objectstack/spec/data';
2+
3+
export const UserObject = ObjectSchema.create({
4+
name: 'user',
5+
label: 'User',
6+
icon: 'user-check',
7+
fields: {
8+
name: Field.text({ label: 'Full Name', required: true, searchable: true }),
9+
email: Field.email({ label: 'Email', required: true, searchable: true }),
10+
username: Field.text({ label: 'Username', required: true }),
11+
role: Field.select(['admin', 'user', 'guest'], { label: 'Role' }),
12+
avatar: Field.url({ label: 'Avatar URL' }),
13+
active: Field.boolean({ label: 'Active', defaultValue: true })
14+
},
15+
list_views: {
16+
all: {
17+
label: 'All Users',
18+
columns: ['name', 'username', 'email', 'role', 'active']
19+
}
20+
}
21+
});

0 commit comments

Comments
 (0)