Skip to content

Commit 429853f

Browse files
committed
feat: 更新导航结构,替换菜单项为结构化导航树
1 parent df89693 commit 429853f

File tree

8 files changed

+39
-113
lines changed

8 files changed

+39
-113
lines changed

.cursorrules

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ You define what a "Package" looks like in ObjectStack.
1313
* id: Unique identifier (e.g., com.example.crm).
1414
* type: app | plugin | driver | module.
1515
* permissions: Array of permission strings requested (e.g., ["system.user.read"]).
16-
* menus: Navigation structure injection.
16+
* navigation: Structured navigation menu tree (for apps).
1717
* entities: Glob patterns for ObjectQL files (e.g., ["./src/schema/*.gql"]).
1818
* extensions: Extension points (e.g., contributions to the UI).
1919
2. Directory Conventions (Law of Location)
@@ -50,11 +50,6 @@ export const ManifestSchema = z.object({
5050
id: z.string().describe("Unique package identifier (reverse domain style)"),
5151
version: z.string().regex(/^\d+\.\d+\.\d+$/),
5252
type: z.enum(['app', 'plugin', 'driver']),
53-
menus: z.array(z.object({
54-
label: z.string(),
55-
path: z.string(),
56-
icon: z.string().optional()
57-
})).optional()
5853
});
5954

6055
export type ObjectStackManifest = z.infer<typeof ManifestSchema>;

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Defines the "Shape of Data".
4040
Defines the "Shape of Interaction".
4141
- **Views:** Grids, Kanbans, Calendars.
4242
- **Pages:** FlexiPage layouts (Regions & Components).
43-
- **Navigation:** Apps, Menus.
43+
- **Navigation:** Apps, Navigation.
4444
- **Analytics:** Reports, Dashboards.
4545

4646
### 3. System Protocol (ObjectOS)

content/prompts/objectstack.prompt.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ File: objectstack.config.ts (or strict JSON inside package.json)
5353
Schema Location: packages/protocol/schemas/manifest.schema.json
5454
Key Fields:
5555
* type: app | plugin | driver
56-
* menus: Array of navigation items to inject into the OS sidebar.
56+
* navigation: Structured navigation menu tree.
5757
* permissions: Array of requested capabilities (e.g., finance.read).
5858
* entities: Path patterns to auto-load Schema files (e.g., ./src/schemas/*.gql).
5959
* lifecycle: Hooks for onInstall, onEnable.

examples/crm/objectstack.config.ts

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,47 +34,44 @@ export default App.create({
3434
],
3535

3636
// Navigation menu structure
37-
menus: [
37+
navigation: [
3838
{
39+
id: 'group_sales',
40+
type: 'group',
3941
label: 'Sales',
40-
items: [
41-
{ type: 'object', object: 'lead', label: 'Leads' },
42-
{ type: 'object', object: 'account', label: 'Accounts' },
43-
{ type: 'object', object: 'contact', label: 'Contacts' },
44-
{ type: 'object', object: 'opportunity', label: 'Opportunities' },
45-
{ type: 'divider' },
46-
{ type: 'dashboard', dashboard: 'sales_dashboard', label: 'Sales Dashboard' },
47-
{ type: 'report', report: 'opportunities_by_stage', label: 'Pipeline Report' },
42+
children: [
43+
{ id: 'nav_lead', type: 'object', objectName: 'lead', label: 'Leads' },
44+
{ id: 'nav_account', type: 'object', objectName: 'account', label: 'Accounts' },
45+
{ id: 'nav_contact', type: 'object', objectName: 'contact', label: 'Contacts' },
46+
{ id: 'nav_opportunity', type: 'object', objectName: 'opportunity', label: 'Opportunities' },
47+
{ id: 'nav_sales_dashboard', type: 'dashboard', dashboardName: 'sales_dashboard', label: 'Sales Dashboard' },
4848
]
4949
},
5050
{
51+
id: 'group_service',
52+
type: 'group',
5153
label: 'Service',
52-
items: [
53-
{ type: 'object', object: 'case', label: 'Cases' },
54-
{ type: 'divider' },
55-
{ type: 'dashboard', dashboard: 'service_dashboard', label: 'Service Dashboard' },
56-
{ type: 'report', report: 'cases_by_status_priority', label: 'Case Report' },
54+
children: [
55+
{ id: 'nav_case', type: 'object', objectName: 'case', label: 'Cases' },
56+
{ id: 'nav_service_dashboard', type: 'dashboard', dashboardName: 'service_dashboard', label: 'Service Dashboard' },
5757
]
5858
},
5959
{
60+
id: 'group_activities',
61+
type: 'group',
6062
label: 'Activities',
61-
items: [
62-
{ type: 'object', object: 'task', label: 'Tasks' },
63+
children: [
64+
{ id: 'nav_task', type: 'object', objectName: 'task', label: 'Tasks' },
6365
]
6466
},
6567
{
68+
id: 'group_analytics',
69+
type: 'group',
6670
label: 'Analytics',
67-
items: [
68-
{ type: 'dashboard', dashboard: 'executive_dashboard', label: 'Executive Dashboard' },
69-
{ type: 'dashboard', dashboard: 'sales_dashboard', label: 'Sales Dashboard' },
70-
{ type: 'dashboard', dashboard: 'service_dashboard', label: 'Service Dashboard' },
71-
{ type: 'divider' },
72-
{ type: 'report', report: 'opportunities_by_stage', label: 'Opportunities by Stage' },
73-
{ type: 'report', report: 'won_opportunities_by_owner', label: 'Won Opportunities' },
74-
{ type: 'report', report: 'accounts_by_industry_type', label: 'Accounts Matrix' },
75-
{ type: 'report', report: 'cases_by_status_priority', label: 'Cases by Status' },
76-
{ type: 'report', report: 'sla_performance', label: 'SLA Performance' },
77-
{ type: 'report', report: 'leads_by_source', label: 'Leads by Source' },
71+
children: [
72+
{ id: 'nav_exec_dashboard', type: 'dashboard', dashboardName: 'executive_dashboard', label: 'Executive Dashboard' },
73+
{ id: 'nav_analytics_sales_db', type: 'dashboard', dashboardName: 'sales_dashboard', label: 'Sales Dashboard' },
74+
{ id: 'nav_analytics_service_db', type: 'dashboard', dashboardName: 'service_dashboard', label: 'Service Dashboard' },
7875
]
7976
}
8077
],

examples/todo/objectstack.config.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,19 @@ export default App.create({
99
objects: [
1010
TodoTask
1111
],
12-
menus: [
12+
navigation: [
1313
{
14-
label: 'Tasks',
15-
items: [
16-
{ type: 'object', object: 'todo_task' }
17-
]
14+
id: 'group_tasks',
15+
type: 'group',
16+
label: 'Tasks',
17+
children: [
18+
{
19+
id: 'nav_todo_task',
20+
type: 'object',
21+
objectName: 'todo_task',
22+
label: 'My Tasks'
23+
}
24+
]
1825
}
1926
]
2027
});

packages/spec/src/system/manifest.test.ts

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -109,29 +109,6 @@ describe('ManifestSchema', () => {
109109
expect(() => ManifestSchema.parse(manifest)).not.toThrow();
110110
});
111111

112-
it('should accept manifest with menus', () => {
113-
const manifest: ObjectStackManifest = {
114-
id: 'com.example.reports',
115-
version: '1.5.2',
116-
type: 'app',
117-
name: 'Reports App',
118-
menus: [
119-
{
120-
label: 'Reports',
121-
path: '/reports',
122-
icon: 'chart-bar',
123-
},
124-
{
125-
label: 'Analytics',
126-
path: '/analytics',
127-
icon: 'trending-up',
128-
},
129-
],
130-
};
131-
132-
expect(() => ManifestSchema.parse(manifest)).not.toThrow();
133-
});
134-
135112
it('should accept manifest with object patterns', () => {
136113
const manifest: ObjectStackManifest = {
137114
id: 'com.example.sales',
@@ -189,33 +166,6 @@ describe('ManifestSchema', () => {
189166
'crm.contact.read',
190167
'crm.contact.write',
191168
],
192-
menus: [
193-
{
194-
label: 'Home',
195-
path: '/crm/home',
196-
icon: 'home',
197-
},
198-
{
199-
label: 'Leads',
200-
path: '/crm/leads',
201-
icon: 'users',
202-
},
203-
{
204-
label: 'Opportunities',
205-
path: '/crm/opportunities',
206-
icon: 'target',
207-
},
208-
{
209-
label: 'Accounts',
210-
path: '/crm/accounts',
211-
icon: 'building-2',
212-
},
213-
{
214-
label: 'Contacts',
215-
path: '/crm/contacts',
216-
icon: 'user',
217-
},
218-
],
219169
objects: [
220170
'./objects/lead.object.ts',
221171
'./objects/opportunity.object.ts',

packages/spec/src/system/manifest.zod.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,5 @@
11
import { z } from 'zod';
22

3-
/**
4-
* Schema for menu items in ObjectStack packages.
5-
* Defines navigation structure that can be injected into the UI.
6-
*/
7-
export const MenuItemSchema = z.object({
8-
/** Display label for the menu item */
9-
label: z.string().describe('Display label for the menu item'),
10-
/** Navigation path (route) for the menu item */
11-
path: z.string().describe('Navigation path (route) for the menu item'),
12-
/** Optional icon identifier for the menu item */
13-
icon: z.string().optional().describe('Optional icon identifier for the menu item'),
14-
});
15-
163
/**
174
* Schema for the ObjectStack Manifest.
185
* This defines the structure of a package configuration in the ObjectStack ecosystem.
@@ -56,11 +43,6 @@ export const ManifestSchema = z.object({
5643
*/
5744
permissions: z.array(z.string()).optional().describe('Array of required permission strings'),
5845

59-
/**
60-
* Navigation menu structure that the package contributes to the UI.
61-
*/
62-
menus: z.array(MenuItemSchema).optional().describe('Navigation menu structure'),
63-
6446
/**
6547
* Glob patterns specifying ObjectQL schemas files (typically *.object.yml or *.object.ts).
6648
* Example: `["./src/objects/*.object.yml"]`

packages/spec/src/ui/app.zod.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,6 @@ export const AppSchema = z.object({
133133
*/
134134
navigation: z.array(NavigationItemSchema).optional().describe('Structured navigation menu tree'),
135135

136-
/**
137-
* Deprecated: Use navigation instead.
138-
*/
139-
menus: z.array(z.any()).optional().describe('Deprecated: Use navigation instead'),
140-
141136
/**
142137
* App-level Home Page Override
143138
* ID of the navigation item to act as the landing page.

0 commit comments

Comments
 (0)