@elevasis/sdk 1.20.2 → 1.22.0
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.
- package/dist/cli.cjs +4220 -1583
- package/dist/index.d.ts +1035 -481
- package/dist/index.js +7381 -4187
- package/dist/node/index.d.ts +1 -3
- package/dist/node/index.js +40 -49
- package/dist/test-utils/index.d.ts +699 -123
- package/dist/test-utils/index.js +3826 -630
- package/dist/worker/index.js +3616 -442
- package/package.json +3 -3
- package/reference/_navigation.md +9 -7
- package/reference/_reference-manifest.json +1 -1
- package/reference/claude-config/hooks/post-edit-validate.mjs +98 -98
- package/reference/claude-config/hooks/scaffold-registry-reminder.mjs +188 -188
- package/reference/claude-config/hooks/tool-failure-recovery.mjs +73 -73
- package/reference/claude-config/registries/graph-skills.json +4 -4
- package/reference/claude-config/registries/knowledge-flags.json +0 -2
- package/reference/claude-config/rules/active-change-index.md +80 -80
- package/reference/claude-config/rules/agent-start-here.md +277 -273
- package/reference/claude-config/rules/deployment.md +57 -57
- package/reference/claude-config/rules/error-handling.md +56 -56
- package/reference/claude-config/rules/execution.md +40 -40
- package/reference/claude-config/rules/frontend.md +4 -4
- package/reference/claude-config/rules/observability.md +31 -31
- package/reference/claude-config/rules/operations.md +29 -17
- package/reference/claude-config/rules/organization-model.md +108 -40
- package/reference/claude-config/rules/organization-os.md +115 -113
- package/reference/claude-config/rules/package-taxonomy.md +33 -33
- package/reference/claude-config/rules/platform.md +42 -42
- package/reference/claude-config/rules/shared-types.md +49 -46
- package/reference/claude-config/rules/task-tracking.md +47 -47
- package/reference/claude-config/rules/ui.md +200 -200
- package/reference/claude-config/rules/vibe.md +235 -231
- package/reference/claude-config/scripts/statusline-command.js +18 -18
- package/reference/claude-config/settings.json +34 -34
- package/reference/claude-config/skills/deploy/{SKILL.md → skill.md} +156 -156
- package/reference/claude-config/skills/dsp/SKILL.md +66 -66
- package/reference/claude-config/skills/elevasis/SKILL.md +235 -235
- package/reference/claude-config/skills/explore/SKILL.md +6 -6
- package/reference/claude-config/skills/git-sync/SKILL.md +126 -126
- package/reference/claude-config/skills/knowledge/SKILL.md +330 -271
- package/reference/claude-config/skills/knowledge/operations/codify-level-a.md +100 -100
- package/reference/claude-config/skills/knowledge/operations/codify-level-b.md +159 -158
- package/reference/claude-config/skills/knowledge/operations/customers.md +109 -109
- package/reference/claude-config/skills/knowledge/operations/features.md +76 -113
- package/reference/claude-config/skills/knowledge/operations/goals.md +118 -118
- package/reference/claude-config/skills/knowledge/operations/identity.md +93 -93
- package/reference/claude-config/skills/knowledge/operations/labels.md +94 -89
- package/reference/claude-config/skills/knowledge/operations/offerings.md +109 -109
- package/reference/claude-config/skills/knowledge/operations/roles.md +99 -99
- package/reference/claude-config/skills/knowledge/operations/techStack.md +30 -30
- package/reference/claude-config/skills/project/SKILL.md +1088 -1088
- package/reference/claude-config/skills/run-ui/SKILL.md +73 -73
- package/reference/claude-config/skills/save/SKILL.md +3 -3
- package/reference/claude-config/skills/setup/SKILL.md +275 -275
- package/reference/claude-config/skills/status/SKILL.md +59 -59
- package/reference/claude-config/skills/submit-request/SKILL.md +180 -180
- package/reference/claude-config/skills/sync/SKILL.md +47 -47
- package/reference/claude-config/skills/tutorial/SKILL.md +259 -259
- package/reference/claude-config/skills/tutorial/progress-template.md +74 -74
- package/reference/claude-config/skills/tutorial/technical.md +1303 -1306
- package/reference/claude-config/skills/tutorial/vibe-coder.md +890 -890
- package/reference/claude-config/sync-notes/2026-04-22-git-sync-and-sync-notes.md +27 -27
- package/reference/claude-config/sync-notes/2026-04-22-lead-gen-deliverability-removal.md +30 -30
- package/reference/claude-config/sync-notes/2026-04-24-test-utils-and-template-tests.md +73 -73
- package/reference/claude-config/sync-notes/2026-04-24-ui-consolidation-and-sdk-cli-train.md +86 -86
- package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +55 -55
- package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +97 -97
- package/reference/claude-config/sync-notes/2026-04-27-lead-gen-substrate-train.md +112 -112
- package/reference/claude-config/sync-notes/2026-04-29-crm-state-and-lead-gen-processing-status.md +93 -93
- package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +58 -58
- package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +56 -56
- package/reference/claude-config/sync-notes/2026-05-04-elevasis-workspace.md +71 -71
- package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +83 -83
- package/reference/claude-config/sync-notes/2026-05-04-template-skills-run-ui-and-tutorial.md +59 -59
- package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +42 -42
- package/reference/claude-config/sync-notes/2026-05-06-crm-spine.md +60 -60
- package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +37 -37
- package/reference/claude-config/sync-notes/2026-05-07-sdk-changes-release-train.md +34 -34
- package/reference/claude-config/sync-notes/2026-05-08-resource-governance-scaffold-guidance.md +38 -38
- package/reference/claude-config/sync-notes/2026-05-09-clients-domain.md +32 -32
- package/reference/claude-config/sync-notes/2026-05-09-command-system.md +33 -33
- package/reference/claude-config/sync-notes/2026-05-09-resource-governance-and-misc.md +69 -69
- package/reference/claude-config/sync-notes/2026-05-12-sdk-ready-release-train.md +30 -0
- package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +42 -0
- package/reference/claude-config/sync-notes/README.md +43 -43
- package/reference/cli.mdx +808 -668
- package/reference/concepts.mdx +146 -146
- package/reference/deployment/api.mdx +297 -297
- package/reference/deployment/command-center.mdx +209 -209
- package/reference/deployment/index.mdx +195 -195
- package/reference/deployment/provided-features.mdx +107 -93
- package/reference/deployment/ui-execution.mdx +250 -250
- package/reference/examples/organization-model.ts +147 -84
- package/reference/framework/agent.mdx +156 -156
- package/reference/framework/index.mdx +195 -195
- package/reference/framework/interaction-guidance.mdx +182 -182
- package/reference/framework/memory.mdx +326 -326
- package/reference/framework/project-structure.mdx +282 -282
- package/reference/framework/tutorial-system.mdx +135 -135
- package/reference/getting-started.mdx +142 -142
- package/reference/index.mdx +106 -106
- package/reference/packages/core/src/README.md +14 -14
- package/reference/packages/core/src/business/README.md +2 -2
- package/reference/packages/core/src/knowledge/README.md +33 -32
- package/reference/packages/core/src/organization-model/README.md +149 -109
- package/reference/packages/core/src/test-utils/README.md +37 -37
- package/reference/packages/ui/src/api/README.md +18 -18
- package/reference/packages/ui/src/app/README.md +24 -24
- package/reference/packages/ui/src/auth/README.md +18 -18
- package/reference/packages/ui/src/components/README.md +24 -24
- package/reference/packages/ui/src/execution/README.md +16 -16
- package/reference/packages/ui/src/features/README.md +28 -28
- package/reference/packages/ui/src/graph/README.md +16 -16
- package/reference/packages/ui/src/hooks/README.md +23 -23
- package/reference/packages/ui/src/initialization/README.md +19 -19
- package/reference/packages/ui/src/knowledge/README.md +31 -31
- package/reference/packages/ui/src/organization/README.md +18 -18
- package/reference/packages/ui/src/profile/README.md +19 -19
- package/reference/packages/ui/src/provider/README.md +32 -32
- package/reference/packages/ui/src/router/README.md +18 -18
- package/reference/packages/ui/src/sse/README.md +13 -13
- package/reference/packages/ui/src/test-utils/README.md +7 -7
- package/reference/packages/ui/src/theme/README.md +23 -23
- package/reference/packages/ui/src/theme/presets/README.md +19 -19
- package/reference/packages/ui/src/types/README.md +16 -16
- package/reference/packages/ui/src/utils/README.md +18 -18
- package/reference/packages/ui/src/zustand/README.md +18 -18
- package/reference/platform-tools/adapters-integration.mdx +301 -301
- package/reference/platform-tools/adapters-platform.mdx +553 -553
- package/reference/platform-tools/index.mdx +217 -217
- package/reference/platform-tools/type-safety.mdx +82 -82
- package/reference/resources/index.mdx +349 -349
- package/reference/resources/patterns.mdx +449 -449
- package/reference/resources/types.mdx +116 -116
- package/reference/roadmap.mdx +165 -165
- package/reference/runtime.mdx +173 -173
- package/reference/scaffold/core/organization-graph.mdx +110 -89
- package/reference/scaffold/core/organization-model.mdx +226 -171
- package/reference/scaffold/index.mdx +67 -67
- package/reference/scaffold/operations/propagation-pipeline.md +77 -77
- package/reference/scaffold/operations/scaffold-maintenance.md +10 -10
- package/reference/scaffold/operations/workflow-recipes.md +138 -138
- package/reference/scaffold/recipes/add-a-feature.md +310 -88
- package/reference/scaffold/recipes/add-a-resource.md +137 -117
- package/reference/scaffold/recipes/customize-crm-actions.md +439 -439
- package/reference/scaffold/recipes/customize-knowledge-browser.md +384 -0
- package/reference/scaffold/recipes/customize-organization-model.md +281 -118
- package/reference/scaffold/recipes/extend-a-base-entity.md +8 -8
- package/reference/scaffold/recipes/extend-crm.md +40 -39
- package/reference/scaffold/recipes/extend-lead-gen.md +400 -401
- package/reference/scaffold/recipes/gate-by-feature-or-admin.md +118 -114
- package/reference/scaffold/recipes/index.md +47 -46
- package/reference/scaffold/recipes/query-the-knowledge-graph.md +227 -0
- package/reference/scaffold/reference/contracts.md +2389 -2121
- package/reference/scaffold/reference/feature-registry.md +9 -20
- package/reference/scaffold/reference/glossary.md +76 -76
- package/reference/scaffold/ui/composition-extensibility.mdx +233 -233
- package/reference/scaffold/ui/customization.md +243 -243
- package/reference/scaffold/ui/feature-flags-and-gating.md +46 -46
- package/reference/scaffold/ui/feature-shell.mdx +72 -72
- package/reference/scaffold/ui/recipes.md +221 -213
- package/reference/spine/spine-primer.md +96 -96
- package/reference/templates/index.mdx +47 -47
- package/reference/troubleshooting.mdx +223 -223
|
@@ -1,246 +1,246 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Customizing
|
|
3
|
-
description: One pattern for customizing
|
|
4
|
-
---
|
|
1
|
+
---
|
|
2
|
+
title: Customizing Systems
|
|
3
|
+
description: One pattern for customizing system sidebars and pages -- set manifest.sidebar to a component composing the system's published pieces. Decision tree + three worked examples.
|
|
4
|
+
---
|
|
5
5
|
<!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
|
|
6
6
|
<!-- Regenerate: pnpm scaffold:sync -->
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
# Customizing
|
|
10
|
-
|
|
11
|
-
**Status:** 🟢 Stable
|
|
12
|
-
|
|
13
|
-
> **Requires `@elevasis/ui` >= 2.8.1.**
|
|
14
|
-
|
|
15
|
-
There is one pattern for customizing a
|
|
16
|
-
|
|
17
|
-
## Decision Tree
|
|
18
|
-
|
|
19
|
-
**Adding or changing nav items?** Extend the exported item array and pass to `<*SidebarMiddle items={...}>`. This covers the vast majority of sidebar customization needs.
|
|
20
|
-
|
|
21
|
-
**Structural changes (injecting panels, reordering sections, wrapping sections)?** Compose `SidebarTop`, `SidebarMiddle`, and exported panels (`MyTasksPanel`, `QuickCreateActions`) directly into your own component and assign it to the manifest's `sidebar` field.
|
|
22
|
-
|
|
23
|
-
**Wrapping pages?** Import the
|
|
24
|
-
|
|
25
|
-
**Neither fits?** The missing export is a bug in `@elevasis/ui` -- file an issue. Copying source is physically possible but unsupported. You own upstream drift forever.
|
|
26
|
-
|
|
27
|
-
## Worked Example 1: Sidebar Nav Extension
|
|
28
|
-
|
|
29
|
-
Extend CRM's nav by spreading `CRM_ITEMS` and appending a Reports entry. Pass the extended array to `CrmSidebarMiddle`.
|
|
30
|
-
|
|
31
|
-
Wire the override in `ui/src/routes/__root.tsx`, where
|
|
32
|
-
|
|
33
|
-
```tsx
|
|
34
|
-
// ui/src/routes/__root.tsx (excerpt -- add after existing imports)
|
|
35
|
-
|
|
36
|
-
import { crmManifest, CrmSidebar, CrmSidebarMiddle, CRM_ITEMS } from '@elevasis/ui/features/crm'
|
|
37
|
-
import { IconFileText } from '@tabler/icons-react'
|
|
38
|
-
import type { NavItem } from '@elevasis/ui/layout'
|
|
39
|
-
|
|
40
|
-
// Extend the published CRM nav array with a project-specific Reports entry.
|
|
41
|
-
const customCrmItems: NavItem[] = [
|
|
42
|
-
...CRM_ITEMS,
|
|
43
|
-
{ label: 'Reports', to: '/crm/reports', icon: IconFileText, exact: false }
|
|
44
|
-
]
|
|
45
|
-
|
|
46
|
-
// Compose CrmSidebar (Top + Middle) with the extended item list.
|
|
47
|
-
const MyCrmSidebar = () => (
|
|
48
|
-
<CrmSidebar>
|
|
49
|
-
<CrmSidebarMiddle items={customCrmItems} />
|
|
50
|
-
</CrmSidebar>
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
// Override the manifest's sidebar, keeping every other field unchanged.
|
|
54
|
-
const customCrmManifest = { ...crmManifest, sidebar: MyCrmSidebar }
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Then swap `crmManifest` for `customCrmManifest` in the `
|
|
58
|
-
|
|
59
|
-
```tsx
|
|
60
|
-
// In the
|
|
61
|
-
const
|
|
62
|
-
leadGenManifest,
|
|
63
|
-
customCrmManifest, // <-- replaces crmManifest
|
|
64
|
-
deliveryManifest,
|
|
65
|
-
operationsManifest,
|
|
66
|
-
monitoringManifest,
|
|
67
|
-
settingsManifest
|
|
68
|
-
]
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Your new `/crm/reports` route file still needs to be created in `ui/src/routes/crm/` -- the nav item just controls the link.
|
|
72
|
-
|
|
73
|
-
## Worked Example 2: Sidebar with Injected Panel
|
|
74
|
-
|
|
75
|
-
Inject a custom panel between the nav list and the My Tasks section. Compose the parts explicitly rather than relying on `CrmSidebarMiddle`'s default layout.
|
|
76
|
-
|
|
77
|
-
```tsx
|
|
78
|
-
// ui/src/routes/__root.tsx (excerpt)
|
|
79
|
-
|
|
80
|
-
import {
|
|
81
|
-
crmManifest,
|
|
82
|
-
CrmSidebar,
|
|
83
|
-
CrmSidebarMiddle,
|
|
84
|
-
CrmSidebarTop,
|
|
85
|
-
MyTasksPanel,
|
|
86
|
-
QuickCreateActions,
|
|
87
|
-
CRM_ITEMS
|
|
88
|
-
} from '@elevasis/ui/features/crm'
|
|
89
|
-
import { SubshellNavList, SubshellSidebarSection } from '@elevasis/ui/layout'
|
|
90
|
-
import { Stack } from '@mantine/core'
|
|
91
|
-
import { IconChartBar } from '@tabler/icons-react'
|
|
92
|
-
|
|
93
|
-
// Custom middle that inserts a Pipeline Health panel between nav and My Tasks.
|
|
94
|
-
const MyCrmMiddle = () => (
|
|
95
|
-
<Stack gap={0} style={{ flex: 1, overflowY: 'auto' }}>
|
|
96
|
-
<Stack gap={0} p="sm">
|
|
97
|
-
<SubshellNavList items={CRM_ITEMS} />
|
|
98
|
-
</Stack>
|
|
99
|
-
{/* Inject custom panel here */}
|
|
100
|
-
<SubshellSidebarSection icon={IconChartBar} label="Pipeline Health" withTopBorder />
|
|
101
|
-
<Stack gap={0} p="sm">
|
|
102
|
-
<PipelineHealthWidget />
|
|
103
|
-
</Stack>
|
|
104
|
-
{/* Preserve the My Tasks section from the default middle */}
|
|
105
|
-
<MyTasksPanel footer={<QuickCreateActions showSectionLabel={false} />} showSectionLabel />
|
|
106
|
-
</Stack>
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
// Full sidebar: Top stays unchanged, Middle is replaced.
|
|
110
|
-
const MyCrmSidebar = () => (
|
|
111
|
-
<CrmSidebar>
|
|
112
|
-
<MyCrmMiddle />
|
|
113
|
-
</CrmSidebar>
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
const customCrmManifest = { ...crmManifest, sidebar: MyCrmSidebar }
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
`PipelineHealthWidget` is a component you define in `ui/src/features/crm/` or `ui/src/lib/components/`. Keep route files and `__root.tsx` thin -- push component logic into feature modules.
|
|
120
|
-
|
|
121
|
-
## Worked Example 3: Page Wrapping
|
|
122
|
-
|
|
123
|
-
Import a
|
|
124
|
-
|
|
125
|
-
The exported CRM page components are `DealsListPage` and `DealDetailPage`:
|
|
126
|
-
|
|
127
|
-
```tsx
|
|
128
|
-
// ui/src/routes/crm/deals.index.tsx
|
|
129
|
-
|
|
130
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
131
|
-
import { DealsListPage } from '@elevasis/ui/features/crm'
|
|
132
|
-
import { ProtectedRoute } from '@/features/auth'
|
|
133
|
-
import { ProjectAnnouncementBanner } from '@/lib/components/ProjectAnnouncementBanner'
|
|
134
|
-
import { Stack } from '@mantine/core'
|
|
135
|
-
|
|
136
|
-
export const Route = createFileRoute('/crm/deals/')({
|
|
137
|
-
component: DealsListPageGuarded
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
function DealsListPageGuarded() {
|
|
141
|
-
return (
|
|
142
|
-
<ProtectedRoute>
|
|
143
|
-
<Stack gap={0}>
|
|
144
|
-
<ProjectAnnouncementBanner context="crm-deals" />
|
|
145
|
-
<DealsListPage />
|
|
146
|
-
</Stack>
|
|
147
|
-
</ProtectedRoute>
|
|
148
|
-
)
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
The pattern is identical for `DealDetailPage`. Import the published component, wrap it in your chrome, export as the route component. No forking, no copying source.
|
|
153
|
-
|
|
154
|
-
## Delivery: Three-Section Sidebar
|
|
155
|
-
|
|
156
|
-
Delivery keeps three named sections (Projects, Work, Communication). It exports three separate arrays and `ProjectsSidebarMiddle` accepts three matching optional props -- one per section. There is no single `items` prop.
|
|
157
|
-
|
|
158
|
-
```tsx
|
|
159
|
-
// Adding items to an existing delivery section
|
|
160
|
-
import {
|
|
161
|
-
deliveryManifest,
|
|
162
|
-
ProjectsSidebar,
|
|
163
|
-
ProjectsSidebarMiddle,
|
|
164
|
-
DELIVERY_PROJECT_ITEMS,
|
|
165
|
-
DELIVERY_WORK_ITEMS,
|
|
166
|
-
DELIVERY_COMMUNICATION_ITEMS
|
|
167
|
-
} from '@elevasis/ui/features/delivery'
|
|
168
|
-
import type { NavItem } from '@elevasis/ui/layout'
|
|
169
|
-
import { IconChartBar } from '@tabler/icons-react'
|
|
170
|
-
|
|
171
|
-
const customProjectItems: NavItem[] = [
|
|
172
|
-
...DELIVERY_PROJECT_ITEMS,
|
|
173
|
-
{ label: 'Analytics', to: '/projects/analytics', icon: IconChartBar, exact: false }
|
|
174
|
-
]
|
|
175
|
-
|
|
176
|
-
const MyDeliverySidebar = () => (
|
|
177
|
-
<ProjectsSidebar>
|
|
178
|
-
<ProjectsSidebarMiddle
|
|
179
|
-
projectItems={customProjectItems}
|
|
180
|
-
workItems={DELIVERY_WORK_ITEMS}
|
|
181
|
-
communicationItems={DELIVERY_COMMUNICATION_ITEMS}
|
|
182
|
-
/>
|
|
183
|
-
</ProjectsSidebar>
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
const customDeliveryManifest = { ...deliveryManifest, sidebar: MyDeliverySidebar }
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**Adding a new section** (not extending an existing one) requires composing from primitives. Use `SubshellSidebarSection` as the section header and `SubshellNavList` to render items inside it:
|
|
190
|
-
|
|
191
|
-
```tsx
|
|
192
|
-
import {
|
|
193
|
-
ProjectsSidebar,
|
|
194
|
-
DELIVERY_PROJECT_ITEMS,
|
|
195
|
-
DELIVERY_WORK_ITEMS,
|
|
196
|
-
DELIVERY_COMMUNICATION_ITEMS
|
|
197
|
-
} from '@elevasis/ui/features/delivery'
|
|
198
|
-
import { SubshellSidebarSection, SubshellNavList } from '@elevasis/ui/layout'
|
|
199
|
-
import { Stack } from '@mantine/core'
|
|
200
|
-
import { IconChartBar, IconListCheck, IconMessageCircle, IconBriefcase } from '@tabler/icons-react'
|
|
201
|
-
import type { NavItem } from '@elevasis/ui/layout'
|
|
202
|
-
|
|
203
|
-
const ANALYTICS_ITEMS: NavItem[] = [
|
|
204
|
-
{ label: 'Dashboard', to: '/projects/analytics', icon: IconChartBar, exact: true }
|
|
205
|
-
]
|
|
206
|
-
|
|
207
|
-
const MyDeliveryMiddle = () => (
|
|
208
|
-
<Stack gap={0} style={{ flex: 1, overflowY: 'auto' }}>
|
|
209
|
-
<Stack gap={0} p="sm">
|
|
210
|
-
<SubshellNavList items={DELIVERY_PROJECT_ITEMS} />
|
|
211
|
-
</Stack>
|
|
212
|
-
<SubshellSidebarSection icon={IconListCheck} label="Work" withTopBorder />
|
|
213
|
-
<Stack gap={0} p="sm">
|
|
214
|
-
<SubshellNavList items={DELIVERY_WORK_ITEMS} />
|
|
215
|
-
</Stack>
|
|
216
|
-
<SubshellSidebarSection icon={IconMessageCircle} label="Communication" withTopBorder />
|
|
217
|
-
<Stack gap={0} p="sm">
|
|
218
|
-
<SubshellNavList items={DELIVERY_COMMUNICATION_ITEMS} />
|
|
219
|
-
</Stack>
|
|
220
|
-
<SubshellSidebarSection icon={IconChartBar} label="Analytics" withTopBorder />
|
|
221
|
-
<Stack gap={0} p="sm">
|
|
222
|
-
<SubshellNavList items={ANALYTICS_ITEMS} />
|
|
223
|
-
</Stack>
|
|
224
|
-
</Stack>
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
const MyDeliverySidebar = () => <ProjectsSidebar><MyDeliveryMiddle /></ProjectsSidebar>
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
This is the same compose-from-primitives path CRM consumers use for structural changes. No special API -- just `SubshellSidebarSection` + `SubshellNavList` from `@elevasis/ui/layout`.
|
|
231
|
-
|
|
232
|
-
For broader CRM extension work across pages, hooks, actions, workflows, and org-model boundaries, start with `node_modules/@elevasis/sdk/reference/scaffold/recipes/extend-crm.md`.
|
|
233
|
-
|
|
234
|
-
For broader lead-gen extension work across pages, hooks, list/member state, artifacts, workflows, and org-model boundaries, start with `node_modules/@elevasis/sdk/reference/scaffold/recipes/extend-lead-gen.md`.
|
|
235
|
-
|
|
236
|
-
## Imports Cheat Sheet
|
|
237
|
-
|
|
238
|
-
| What you need | Import from |
|
|
239
|
-
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
|
|
240
|
-
| `CRM_ITEMS`, `CrmSidebar`, `CrmSidebarTop`, `CrmSidebarMiddle`, `MyTasksPanel`, `QuickCreateActions`, `DealsListPage`, `DealDetailPage`, `crmManifest` | `@elevasis/ui/features/crm` |
|
|
241
|
-
| `LEAD_GEN_ITEMS`, `LeadGenSidebar`, `LeadGenSidebarTop`, `LeadGenSidebarMiddle`, `leadGenManifest` | `@elevasis/ui/features/lead-gen` |
|
|
242
|
-
| `DELIVERY_PROJECT_ITEMS`, `DELIVERY_WORK_ITEMS`, `DELIVERY_COMMUNICATION_ITEMS`, `ProjectsSidebar`, `ProjectsSidebarTop`, `ProjectsSidebarMiddle`, `deliveryManifest` | `@elevasis/ui/features/delivery` |
|
|
243
|
-
| `SubshellNavList`, `SubshellNavItem`, `SubshellSidebarSection`, `NavItem` | `@elevasis/ui/layout` |
|
|
244
|
-
| `
|
|
245
|
-
|
|
246
|
-
Operations, monitoring, and settings have no customizable sidebar items. Operations sidebar is route-aware dispatch and not extended via the `items` pattern.
|
|
8
|
+
|
|
9
|
+
# Customizing Systems
|
|
10
|
+
|
|
11
|
+
**Status:** 🟢 Stable
|
|
12
|
+
|
|
13
|
+
> **Requires `@elevasis/ui` >= 2.8.1.**
|
|
14
|
+
|
|
15
|
+
There is one pattern for customizing a system's sidebar or pages: set `sidebar` on your manifest override to a component that composes the system's published pieces. Pass custom `items` to swap the nav array, or compose `SidebarTop` + `SidebarMiddle` + exported panels directly for structural changes. Never fork a source file as a first resort -- if you copy source you own upstream drift forever.
|
|
16
|
+
|
|
17
|
+
## Decision Tree
|
|
18
|
+
|
|
19
|
+
**Adding or changing nav items?** Extend the exported item array and pass to `<*SidebarMiddle items={...}>`. This covers the vast majority of sidebar customization needs.
|
|
20
|
+
|
|
21
|
+
**Structural changes (injecting panels, reordering sections, wrapping sections)?** Compose `SidebarTop`, `SidebarMiddle`, and exported panels (`MyTasksPanel`, `QuickCreateActions`) directly into your own component and assign it to the manifest's `sidebar` field.
|
|
22
|
+
|
|
23
|
+
**Wrapping pages?** Import the system's page component and wrap with custom chrome in a route file.
|
|
24
|
+
|
|
25
|
+
**Neither fits?** The missing export is a bug in `@elevasis/ui` -- file an issue. Copying source is physically possible but unsupported. You own upstream drift forever.
|
|
26
|
+
|
|
27
|
+
## Worked Example 1: Sidebar Nav Extension
|
|
28
|
+
|
|
29
|
+
Extend CRM's nav by spreading `CRM_ITEMS` and appending a Reports entry. Pass the extended array to `CrmSidebarMiddle`.
|
|
30
|
+
|
|
31
|
+
Wire the override in `ui/src/routes/__root.tsx`, where system manifests are assembled before being passed to `ElevasisSystemsProvider`.
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
// ui/src/routes/__root.tsx (excerpt -- add after existing imports)
|
|
35
|
+
|
|
36
|
+
import { crmManifest, CrmSidebar, CrmSidebarMiddle, CRM_ITEMS } from '@elevasis/ui/features/crm'
|
|
37
|
+
import { IconFileText } from '@tabler/icons-react'
|
|
38
|
+
import type { NavItem } from '@elevasis/ui/layout'
|
|
39
|
+
|
|
40
|
+
// Extend the published CRM nav array with a project-specific Reports entry.
|
|
41
|
+
const customCrmItems: NavItem[] = [
|
|
42
|
+
...CRM_ITEMS,
|
|
43
|
+
{ label: 'Reports', to: '/crm/reports', icon: IconFileText, exact: false }
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
// Compose CrmSidebar (Top + Middle) with the extended item list.
|
|
47
|
+
const MyCrmSidebar = () => (
|
|
48
|
+
<CrmSidebar>
|
|
49
|
+
<CrmSidebarMiddle items={customCrmItems} />
|
|
50
|
+
</CrmSidebar>
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
// Override the manifest's sidebar, keeping every other field unchanged.
|
|
54
|
+
const customCrmManifest = { ...crmManifest, sidebar: MyCrmSidebar }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Then swap `crmManifest` for `customCrmManifest` in the `SYSTEM_MANIFESTS` array:
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
// In the SYSTEM_MANIFESTS array (same file)
|
|
61
|
+
const SYSTEM_MANIFESTS: SystemModule[] = [
|
|
62
|
+
leadGenManifest,
|
|
63
|
+
customCrmManifest, // <-- replaces crmManifest
|
|
64
|
+
deliveryManifest,
|
|
65
|
+
operationsManifest,
|
|
66
|
+
monitoringManifest,
|
|
67
|
+
settingsManifest
|
|
68
|
+
]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Your new `/crm/reports` route file still needs to be created in `ui/src/routes/crm/` -- the nav item just controls the link.
|
|
72
|
+
|
|
73
|
+
## Worked Example 2: Sidebar with Injected Panel
|
|
74
|
+
|
|
75
|
+
Inject a custom panel between the nav list and the My Tasks section. Compose the parts explicitly rather than relying on `CrmSidebarMiddle`'s default layout.
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
// ui/src/routes/__root.tsx (excerpt)
|
|
79
|
+
|
|
80
|
+
import {
|
|
81
|
+
crmManifest,
|
|
82
|
+
CrmSidebar,
|
|
83
|
+
CrmSidebarMiddle,
|
|
84
|
+
CrmSidebarTop,
|
|
85
|
+
MyTasksPanel,
|
|
86
|
+
QuickCreateActions,
|
|
87
|
+
CRM_ITEMS
|
|
88
|
+
} from '@elevasis/ui/features/crm'
|
|
89
|
+
import { SubshellNavList, SubshellSidebarSection } from '@elevasis/ui/layout'
|
|
90
|
+
import { Stack } from '@mantine/core'
|
|
91
|
+
import { IconChartBar } from '@tabler/icons-react'
|
|
92
|
+
|
|
93
|
+
// Custom middle that inserts a Pipeline Health panel between nav and My Tasks.
|
|
94
|
+
const MyCrmMiddle = () => (
|
|
95
|
+
<Stack gap={0} style={{ flex: 1, overflowY: 'auto' }}>
|
|
96
|
+
<Stack gap={0} p="sm">
|
|
97
|
+
<SubshellNavList items={CRM_ITEMS} />
|
|
98
|
+
</Stack>
|
|
99
|
+
{/* Inject custom panel here */}
|
|
100
|
+
<SubshellSidebarSection icon={IconChartBar} label="Pipeline Health" withTopBorder />
|
|
101
|
+
<Stack gap={0} p="sm">
|
|
102
|
+
<PipelineHealthWidget />
|
|
103
|
+
</Stack>
|
|
104
|
+
{/* Preserve the My Tasks section from the default middle */}
|
|
105
|
+
<MyTasksPanel footer={<QuickCreateActions showSectionLabel={false} />} showSectionLabel />
|
|
106
|
+
</Stack>
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
// Full sidebar: Top stays unchanged, Middle is replaced.
|
|
110
|
+
const MyCrmSidebar = () => (
|
|
111
|
+
<CrmSidebar>
|
|
112
|
+
<MyCrmMiddle />
|
|
113
|
+
</CrmSidebar>
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
const customCrmManifest = { ...crmManifest, sidebar: MyCrmSidebar }
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`PipelineHealthWidget` is a component you define in `ui/src/features/crm/` or `ui/src/lib/components/`. Keep route files and `__root.tsx` thin -- push component logic into feature modules.
|
|
120
|
+
|
|
121
|
+
## Worked Example 3: Page Wrapping
|
|
122
|
+
|
|
123
|
+
Import a system's page component and wrap it with custom chrome in a route file. This keeps the system's business logic intact while adding project-specific framing (banners, secondary nav, analytics context, etc.).
|
|
124
|
+
|
|
125
|
+
The exported CRM page components are `DealsListPage` and `DealDetailPage`:
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
// ui/src/routes/crm/deals.index.tsx
|
|
129
|
+
|
|
130
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
131
|
+
import { DealsListPage } from '@elevasis/ui/features/crm'
|
|
132
|
+
import { ProtectedRoute } from '@/features/auth'
|
|
133
|
+
import { ProjectAnnouncementBanner } from '@/lib/components/ProjectAnnouncementBanner'
|
|
134
|
+
import { Stack } from '@mantine/core'
|
|
135
|
+
|
|
136
|
+
export const Route = createFileRoute('/crm/deals/')({
|
|
137
|
+
component: DealsListPageGuarded
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
function DealsListPageGuarded() {
|
|
141
|
+
return (
|
|
142
|
+
<ProtectedRoute>
|
|
143
|
+
<Stack gap={0}>
|
|
144
|
+
<ProjectAnnouncementBanner context="crm-deals" />
|
|
145
|
+
<DealsListPage />
|
|
146
|
+
</Stack>
|
|
147
|
+
</ProtectedRoute>
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The pattern is identical for `DealDetailPage`. Import the published component, wrap it in your chrome, export as the route component. No forking, no copying source.
|
|
153
|
+
|
|
154
|
+
## Delivery: Three-Section Sidebar
|
|
155
|
+
|
|
156
|
+
Delivery keeps three named sections (Projects, Work, Communication). It exports three separate arrays and `ProjectsSidebarMiddle` accepts three matching optional props -- one per section. There is no single `items` prop.
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
// Adding items to an existing delivery section
|
|
160
|
+
import {
|
|
161
|
+
deliveryManifest,
|
|
162
|
+
ProjectsSidebar,
|
|
163
|
+
ProjectsSidebarMiddle,
|
|
164
|
+
DELIVERY_PROJECT_ITEMS,
|
|
165
|
+
DELIVERY_WORK_ITEMS,
|
|
166
|
+
DELIVERY_COMMUNICATION_ITEMS
|
|
167
|
+
} from '@elevasis/ui/features/delivery'
|
|
168
|
+
import type { NavItem } from '@elevasis/ui/layout'
|
|
169
|
+
import { IconChartBar } from '@tabler/icons-react'
|
|
170
|
+
|
|
171
|
+
const customProjectItems: NavItem[] = [
|
|
172
|
+
...DELIVERY_PROJECT_ITEMS,
|
|
173
|
+
{ label: 'Analytics', to: '/projects/analytics', icon: IconChartBar, exact: false }
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
const MyDeliverySidebar = () => (
|
|
177
|
+
<ProjectsSidebar>
|
|
178
|
+
<ProjectsSidebarMiddle
|
|
179
|
+
projectItems={customProjectItems}
|
|
180
|
+
workItems={DELIVERY_WORK_ITEMS}
|
|
181
|
+
communicationItems={DELIVERY_COMMUNICATION_ITEMS}
|
|
182
|
+
/>
|
|
183
|
+
</ProjectsSidebar>
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
const customDeliveryManifest = { ...deliveryManifest, sidebar: MyDeliverySidebar }
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Adding a new section** (not extending an existing one) requires composing from primitives. Use `SubshellSidebarSection` as the section header and `SubshellNavList` to render items inside it:
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
import {
|
|
193
|
+
ProjectsSidebar,
|
|
194
|
+
DELIVERY_PROJECT_ITEMS,
|
|
195
|
+
DELIVERY_WORK_ITEMS,
|
|
196
|
+
DELIVERY_COMMUNICATION_ITEMS
|
|
197
|
+
} from '@elevasis/ui/features/delivery'
|
|
198
|
+
import { SubshellSidebarSection, SubshellNavList } from '@elevasis/ui/layout'
|
|
199
|
+
import { Stack } from '@mantine/core'
|
|
200
|
+
import { IconChartBar, IconListCheck, IconMessageCircle, IconBriefcase } from '@tabler/icons-react'
|
|
201
|
+
import type { NavItem } from '@elevasis/ui/layout'
|
|
202
|
+
|
|
203
|
+
const ANALYTICS_ITEMS: NavItem[] = [
|
|
204
|
+
{ label: 'Dashboard', to: '/projects/analytics', icon: IconChartBar, exact: true }
|
|
205
|
+
]
|
|
206
|
+
|
|
207
|
+
const MyDeliveryMiddle = () => (
|
|
208
|
+
<Stack gap={0} style={{ flex: 1, overflowY: 'auto' }}>
|
|
209
|
+
<Stack gap={0} p="sm">
|
|
210
|
+
<SubshellNavList items={DELIVERY_PROJECT_ITEMS} />
|
|
211
|
+
</Stack>
|
|
212
|
+
<SubshellSidebarSection icon={IconListCheck} label="Work" withTopBorder />
|
|
213
|
+
<Stack gap={0} p="sm">
|
|
214
|
+
<SubshellNavList items={DELIVERY_WORK_ITEMS} />
|
|
215
|
+
</Stack>
|
|
216
|
+
<SubshellSidebarSection icon={IconMessageCircle} label="Communication" withTopBorder />
|
|
217
|
+
<Stack gap={0} p="sm">
|
|
218
|
+
<SubshellNavList items={DELIVERY_COMMUNICATION_ITEMS} />
|
|
219
|
+
</Stack>
|
|
220
|
+
<SubshellSidebarSection icon={IconChartBar} label="Analytics" withTopBorder />
|
|
221
|
+
<Stack gap={0} p="sm">
|
|
222
|
+
<SubshellNavList items={ANALYTICS_ITEMS} />
|
|
223
|
+
</Stack>
|
|
224
|
+
</Stack>
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
const MyDeliverySidebar = () => <ProjectsSidebar><MyDeliveryMiddle /></ProjectsSidebar>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
This is the same compose-from-primitives path CRM consumers use for structural changes. No special API -- just `SubshellSidebarSection` + `SubshellNavList` from `@elevasis/ui/layout`.
|
|
231
|
+
|
|
232
|
+
For broader CRM extension work across pages, hooks, actions, workflows, and org-model boundaries, start with `node_modules/@elevasis/sdk/reference/scaffold/recipes/extend-crm.md`.
|
|
233
|
+
|
|
234
|
+
For broader lead-gen extension work across pages, hooks, list/member state, artifacts, workflows, and org-model boundaries, start with `node_modules/@elevasis/sdk/reference/scaffold/recipes/extend-lead-gen.md`.
|
|
235
|
+
|
|
236
|
+
## Imports Cheat Sheet
|
|
237
|
+
|
|
238
|
+
| What you need | Import from |
|
|
239
|
+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
|
|
240
|
+
| `CRM_ITEMS`, `CrmSidebar`, `CrmSidebarTop`, `CrmSidebarMiddle`, `MyTasksPanel`, `QuickCreateActions`, `DealsListPage`, `DealDetailPage`, `crmManifest` | `@elevasis/ui/features/crm` |
|
|
241
|
+
| `LEAD_GEN_ITEMS`, `LeadGenSidebar`, `LeadGenSidebarTop`, `LeadGenSidebarMiddle`, `leadGenManifest` | `@elevasis/ui/features/lead-gen` |
|
|
242
|
+
| `DELIVERY_PROJECT_ITEMS`, `DELIVERY_WORK_ITEMS`, `DELIVERY_COMMUNICATION_ITEMS`, `ProjectsSidebar`, `ProjectsSidebarTop`, `ProjectsSidebarMiddle`, `deliveryManifest` | `@elevasis/ui/features/delivery` |
|
|
243
|
+
| `SubshellNavList`, `SubshellNavItem`, `SubshellSidebarSection`, `NavItem` | `@elevasis/ui/layout` |
|
|
244
|
+
| `SystemModule` | `@elevasis/ui/provider` |
|
|
245
|
+
|
|
246
|
+
Operations, monitoring, and settings have no customizable sidebar items. Operations sidebar is route-aware dispatch and not extended via the `items` pattern.
|
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
<!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
|
|
2
2
|
<!-- Regenerate: pnpm scaffold:sync -->
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## Where Visibility Comes From
|
|
9
|
-
|
|
10
|
-
- `
|
|
11
|
-
- Membership
|
|
12
|
-
- `requiresAdmin` hides sidebar entries from non-admins.
|
|
13
|
-
- `devOnly` hides sidebar entries outside development mode.
|
|
14
|
-
|
|
15
|
-
The shell derives visible sidebar entries from `shellModel.topLevel()` and `shellModel.childrenOf(id)`.
|
|
16
|
-
|
|
17
|
-
## Route Guards
|
|
18
|
-
|
|
19
|
-
Navigation visibility is cosmetic. Always guard routes directly:
|
|
20
|
-
|
|
21
|
-
```tsx
|
|
22
|
-
<ProtectedRoute>
|
|
23
|
-
<
|
|
24
|
-
<Outlet />
|
|
25
|
-
</
|
|
26
|
-
</ProtectedRoute>
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
For admin-only routes:
|
|
30
|
-
|
|
31
|
-
```tsx
|
|
32
|
-
<AdminGuard>
|
|
33
|
-
<SystemHealthPage />
|
|
34
|
-
</AdminGuard>
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Adding A Gated
|
|
38
|
-
|
|
39
|
-
```ts
|
|
40
|
-
{
|
|
41
|
-
id: 'analytics',
|
|
42
|
-
label: 'Analytics',
|
|
43
|
-
enabled: true,
|
|
44
|
-
path: '/analytics',
|
|
45
|
-
uiPosition: 'sidebar-primary'
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Use the same ID in `
|
|
4
|
+
# System Flags And Gating
|
|
5
|
+
|
|
6
|
+
System visibility is keyed by Organization Model system ID.
|
|
7
|
+
|
|
8
|
+
## Where Visibility Comes From
|
|
9
|
+
|
|
10
|
+
- `systems.systems[].enabled` in the organization model defines the baseline.
|
|
11
|
+
- Membership system config can override individual system IDs.
|
|
12
|
+
- `requiresAdmin` hides sidebar entries from non-admins.
|
|
13
|
+
- `devOnly` hides sidebar entries outside development mode.
|
|
14
|
+
|
|
15
|
+
The shell derives visible sidebar entries from `shellModel.topLevel()` and `shellModel.childrenOf(id)`.
|
|
16
|
+
|
|
17
|
+
## Route Guards
|
|
18
|
+
|
|
19
|
+
Navigation visibility is cosmetic. Always guard routes directly:
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
<ProtectedRoute>
|
|
23
|
+
<SystemGuard systemKey="sales.crm">
|
|
24
|
+
<Outlet />
|
|
25
|
+
</SystemGuard>
|
|
26
|
+
</ProtectedRoute>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For admin-only routes:
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
<AdminGuard>
|
|
33
|
+
<SystemHealthPage />
|
|
34
|
+
</AdminGuard>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Adding A Gated System
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
{
|
|
41
|
+
id: 'analytics',
|
|
42
|
+
label: 'Analytics',
|
|
43
|
+
enabled: true,
|
|
44
|
+
path: '/analytics',
|
|
45
|
+
uiPosition: 'sidebar-primary'
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Use the same ID in `SystemGuard systemKey` and `SystemModule.systemId`.
|