@cxtms/cx-schema 1.0.0 → 1.1.1
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/.claude/skills/cx-core/SKILL.md +93 -0
- package/.claude/skills/cx-core/ref-entity-accounting.md +173 -0
- package/.claude/skills/cx-core/ref-entity-commodity.md +205 -0
- package/.claude/skills/cx-core/ref-entity-contact.md +153 -0
- package/.claude/skills/cx-core/ref-entity-geography.md +119 -0
- package/.claude/skills/cx-core/ref-entity-job.md +77 -0
- package/.claude/skills/cx-core/ref-entity-order-sub.md +140 -0
- package/.claude/skills/cx-core/ref-entity-order.md +168 -0
- package/.claude/skills/cx-core/ref-entity-rate.md +174 -0
- package/.claude/skills/cx-core/ref-entity-shared.md +147 -0
- package/.claude/skills/cx-core/ref-entity-warehouse.md +110 -0
- package/.claude/skills/cx-module/SKILL.md +402 -0
- package/.claude/skills/cx-module/ref-components-data.md +286 -0
- package/.claude/skills/cx-module/ref-components-display.md +394 -0
- package/.claude/skills/cx-module/ref-components-forms.md +362 -0
- package/.claude/skills/cx-module/ref-components-interactive.md +306 -0
- package/.claude/skills/cx-module/ref-components-layout.md +295 -0
- package/.claude/skills/cx-module/ref-components-specialized.md +427 -0
- package/.claude/skills/cx-workflow/SKILL.md +330 -0
- package/.claude/skills/cx-workflow/ref-accounting.md +66 -0
- package/.claude/skills/cx-workflow/ref-communication.md +161 -0
- package/.claude/skills/cx-workflow/ref-entity.md +162 -0
- package/.claude/skills/cx-workflow/ref-expressions.md +239 -0
- package/.claude/skills/cx-workflow/ref-filetransfer.md +80 -0
- package/.claude/skills/cx-workflow/ref-flow.md +180 -0
- package/.claude/skills/cx-workflow/ref-other.md +120 -0
- package/.claude/skills/cx-workflow/ref-query.md +85 -0
- package/.claude/skills/cx-workflow/ref-utilities.md +171 -0
- package/README.md +34 -34
- package/dist/cli.js +545 -35
- package/dist/cli.js.map +1 -1
- package/dist/types.d.ts +17 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/workflowValidator.d.ts +31 -0
- package/dist/workflowValidator.d.ts.map +1 -1
- package/dist/workflowValidator.js +299 -9
- package/dist/workflowValidator.js.map +1 -1
- package/package.json +4 -3
- package/schemas/schema.graphql +2077 -321
- package/schemas/workflows/flow/aggregation.json +44 -0
- package/schemas/workflows/flow/entity.json +110 -0
- package/schemas/workflows/flow/state.json +105 -0
- package/schemas/workflows/flow/transition.json +143 -0
- package/schemas/workflows/input.json +53 -7
- package/schemas/workflows/output.json +20 -0
- package/schemas/workflows/trigger.json +4 -0
- package/schemas/workflows/variable.json +2 -6
- package/schemas/workflows/workflow.json +179 -21
- package/scripts/postinstall.js +30 -1
- package/templates/module-configuration.yaml +110 -0
- package/templates/module-form.yaml +152 -0
- package/templates/module-grid.yaml +229 -0
- package/templates/module-select.yaml +139 -0
- package/templates/module.yaml +3 -3
- package/templates/workflow-api-tracking.yaml +189 -0
- package/templates/workflow-basic.yaml +76 -0
- package/templates/workflow-document.yaml +155 -0
- package/templates/workflow-entity-trigger.yaml +90 -0
- package/templates/workflow-ftp-edi.yaml +158 -0
- package/templates/workflow-ftp-tracking.yaml +161 -0
- package/templates/workflow-mcp-tool.yaml +112 -0
- package/templates/workflow-public-api.yaml +135 -0
- package/templates/workflow-scheduled.yaml +125 -0
- package/templates/workflow-utility.yaml +96 -0
- package/templates/workflow-webhook.yaml +128 -0
- package/templates/workflow.yaml +52 -12
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# Layout & Structure Components
|
|
2
|
+
|
|
3
|
+
## layout
|
|
4
|
+
|
|
5
|
+
General-purpose container. Renders MUI Grid or Box with flexbox.
|
|
6
|
+
|
|
7
|
+
**Props:**
|
|
8
|
+
| Prop | Type | Default | Description |
|
|
9
|
+
|------|------|---------|-------------|
|
|
10
|
+
| `orientation` | `horizontal \| vertical \| flex` | — | Grid direction |
|
|
11
|
+
| `cols` | `number` | — | Equal-width columns (`12/cols` per child) |
|
|
12
|
+
| `columns` | `number \| {xs,sm,md,lg,xl}` | — | Responsive column count |
|
|
13
|
+
| `spacing` | `number` | `3` | Grid gap spacing |
|
|
14
|
+
| `containerTag` | `grid \| box` | `grid` | Grid container vs flexbox Box |
|
|
15
|
+
| `containerSx` | `SxProps` | — | MUI sx styles on container |
|
|
16
|
+
| `className` | `string` | — | CSS class (template-parsed) |
|
|
17
|
+
| `id` | `string` | — | Element ID (template-parsed) |
|
|
18
|
+
| `direction` | `row \| column` | — | Explicit flex direction |
|
|
19
|
+
| `justifyContent` | `string` | — | Flexbox main-axis alignment |
|
|
20
|
+
| `alignItems` | `string` | — | Flexbox cross-axis alignment |
|
|
21
|
+
| `refreshHandler` | `string` | — | Remounts on refresh event |
|
|
22
|
+
| `permission` | `string` | — | Permission gate |
|
|
23
|
+
| `title` | `ILocalizeString` | — | Layout title |
|
|
24
|
+
| `icon` | `string` | — | Layout icon |
|
|
25
|
+
| `toolbar` | `component[]` | — | Toolbar components |
|
|
26
|
+
| `itemDefaults` | `{size?,offset?,order?,sx?}` | — | Default Grid item props for all children |
|
|
27
|
+
|
|
28
|
+
**Events:** `onClick`
|
|
29
|
+
|
|
30
|
+
**Children:** Yes — each child rendered via ComponentRender, wrapped in Grid item.
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
# Basic 2-column layout
|
|
34
|
+
component: layout
|
|
35
|
+
name: detailLayout
|
|
36
|
+
props:
|
|
37
|
+
cols: 2
|
|
38
|
+
spacing: 2
|
|
39
|
+
title:
|
|
40
|
+
en-US: "Detail View"
|
|
41
|
+
icon: file-text
|
|
42
|
+
permission: "Module/Read"
|
|
43
|
+
children:
|
|
44
|
+
- component: field
|
|
45
|
+
name: firstName
|
|
46
|
+
props: { type: text, label: { en-US: "First Name" } }
|
|
47
|
+
- component: field
|
|
48
|
+
name: lastName
|
|
49
|
+
props: { type: text, label: { en-US: "Last Name" } }
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```yaml
|
|
53
|
+
# Horizontal flex layout with toolbar
|
|
54
|
+
component: layout
|
|
55
|
+
name: pageLayout
|
|
56
|
+
props:
|
|
57
|
+
orientation: vertical
|
|
58
|
+
toolbar:
|
|
59
|
+
- component: button
|
|
60
|
+
name: saveBtn
|
|
61
|
+
props:
|
|
62
|
+
label: { en-US: "Save" }
|
|
63
|
+
icon: check
|
|
64
|
+
options: { type: submit, variant: primary }
|
|
65
|
+
children:
|
|
66
|
+
- component: form
|
|
67
|
+
name: myForm
|
|
68
|
+
# ...
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## row
|
|
74
|
+
|
|
75
|
+
Horizontal MUI Grid row. Simpler alternative to layout for single rows.
|
|
76
|
+
|
|
77
|
+
**Props:**
|
|
78
|
+
| Prop | Type | Default | Description |
|
|
79
|
+
|------|------|---------|-------------|
|
|
80
|
+
| `spacing` | `number` | `3` | Grid spacing |
|
|
81
|
+
| `columns` | `number` | — | Grid columns |
|
|
82
|
+
| `direction` | `row \| column` | `row` | Grid direction |
|
|
83
|
+
| `sx` | `SxProps` | — | MUI sx styles |
|
|
84
|
+
| `className` | `string` | — | CSS class |
|
|
85
|
+
| `alignItems` | `string` | — | Cross-axis alignment |
|
|
86
|
+
| `justifyContent` | `string` | — | Main-axis alignment |
|
|
87
|
+
|
|
88
|
+
**Children:** Yes — rendered without Grid item wrapper (use `col` children).
|
|
89
|
+
|
|
90
|
+
```yaml
|
|
91
|
+
component: row
|
|
92
|
+
name: headerRow
|
|
93
|
+
props:
|
|
94
|
+
spacing: 2
|
|
95
|
+
alignItems: center
|
|
96
|
+
children:
|
|
97
|
+
- component: col
|
|
98
|
+
name: leftCol
|
|
99
|
+
props: { size: 6 }
|
|
100
|
+
children:
|
|
101
|
+
- component: text
|
|
102
|
+
name: title
|
|
103
|
+
props: { value: "Header", type: h3 }
|
|
104
|
+
- component: col
|
|
105
|
+
name: rightCol
|
|
106
|
+
props: { size: 6 }
|
|
107
|
+
children:
|
|
108
|
+
- component: button
|
|
109
|
+
name: actionBtn
|
|
110
|
+
props: { label: { en-US: "Action" } }
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## col
|
|
116
|
+
|
|
117
|
+
Grid column item. Child of `row` or `layout`.
|
|
118
|
+
|
|
119
|
+
**Props:**
|
|
120
|
+
| Prop | Type | Description |
|
|
121
|
+
|------|------|-------------|
|
|
122
|
+
| `size` | `number \| {xs,sm,md,lg,xl}` | Responsive column width (plain number = xs) |
|
|
123
|
+
| `offset` | `number \| {xs,sm,md,lg,xl}` | Responsive column offset |
|
|
124
|
+
| `order` | `number \| {xs,sm,md,lg,xl}` | CSS order for reordering |
|
|
125
|
+
| `sx` | `SxProps` | MUI sx styles |
|
|
126
|
+
| `className` | `string` | CSS class |
|
|
127
|
+
| `alignSelf` | `string` | CSS align-self |
|
|
128
|
+
|
|
129
|
+
**Children:** Yes.
|
|
130
|
+
|
|
131
|
+
```yaml
|
|
132
|
+
component: col
|
|
133
|
+
name: mainContent
|
|
134
|
+
props:
|
|
135
|
+
size: { xs: 12, md: 8 }
|
|
136
|
+
offset: { md: 2 }
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## header
|
|
142
|
+
|
|
143
|
+
Section header with title and optional subtitle.
|
|
144
|
+
|
|
145
|
+
**Props:**
|
|
146
|
+
| Prop | Type | Description |
|
|
147
|
+
|------|------|-------------|
|
|
148
|
+
| `title` | `string` | Rendered as `<h3>` |
|
|
149
|
+
| `subtitle` | `string` | Rendered as `<h4>` with divider |
|
|
150
|
+
| `className` | `string` | Additional CSS class |
|
|
151
|
+
|
|
152
|
+
**Children:** Yes.
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
component: header
|
|
156
|
+
name: sectionHeader
|
|
157
|
+
props:
|
|
158
|
+
title: "Contact Information"
|
|
159
|
+
subtitle: "Primary contact details"
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## tabs
|
|
165
|
+
|
|
166
|
+
Tabbed interface with MUI TabContext. Tab state stored in URL params.
|
|
167
|
+
|
|
168
|
+
**Props:**
|
|
169
|
+
| Prop | Type | Description |
|
|
170
|
+
|------|------|-------------|
|
|
171
|
+
| `options` | `object` | Additional props spread to Tab elements |
|
|
172
|
+
| `toolbar` | `component[]` | Action components next to tab list |
|
|
173
|
+
| `useNavigationForTabs` | `boolean` | Push to history instead of replace |
|
|
174
|
+
|
|
175
|
+
**Tab children props:**
|
|
176
|
+
| Prop | Type | Description |
|
|
177
|
+
|------|------|-------------|
|
|
178
|
+
| `label` | `ILocalizeString` | Tab label (localized, template-parsed) |
|
|
179
|
+
| `isVisible` | `string` | Template expression — show when truthy |
|
|
180
|
+
| `isHidden` | `string` | Template expression — hide when truthy |
|
|
181
|
+
| `options` | `object` | Additional Tab element props |
|
|
182
|
+
|
|
183
|
+
**Children:** Each child = one tab. Content rendered inside TabPanel via LayoutComponent.
|
|
184
|
+
|
|
185
|
+
```yaml
|
|
186
|
+
component: tabs
|
|
187
|
+
name: detailTabs
|
|
188
|
+
props:
|
|
189
|
+
toolbar:
|
|
190
|
+
- component: button
|
|
191
|
+
name: refreshBtn
|
|
192
|
+
props: { label: { en-US: "Refresh" }, icon: refresh-cw }
|
|
193
|
+
children:
|
|
194
|
+
- name: general
|
|
195
|
+
props:
|
|
196
|
+
label: { en-US: "General" }
|
|
197
|
+
children:
|
|
198
|
+
- component: field
|
|
199
|
+
name: name
|
|
200
|
+
props: { type: text, label: { en-US: "Name" } }
|
|
201
|
+
- name: advanced
|
|
202
|
+
props:
|
|
203
|
+
label: { en-US: "Advanced" }
|
|
204
|
+
isHidden: "{{ eval !isAdmin }}"
|
|
205
|
+
children:
|
|
206
|
+
- component: field
|
|
207
|
+
name: config
|
|
208
|
+
props: { type: textarea, label: { en-US: "Config" } }
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## toolbar
|
|
214
|
+
|
|
215
|
+
Nav-style toolbar with title and action buttons.
|
|
216
|
+
|
|
217
|
+
**Props:**
|
|
218
|
+
| Prop | Type | Description |
|
|
219
|
+
|------|------|-------------|
|
|
220
|
+
| `title` | `ILocalizeString` | Toolbar title (navbar brand) |
|
|
221
|
+
| `buttons` | `component[]` | Action components (right-aligned) |
|
|
222
|
+
|
|
223
|
+
**Children:** No — uses `buttons` prop.
|
|
224
|
+
|
|
225
|
+
```yaml
|
|
226
|
+
component: toolbar
|
|
227
|
+
name: pageToolbar
|
|
228
|
+
props:
|
|
229
|
+
title: { en-US: "Order Management" }
|
|
230
|
+
buttons:
|
|
231
|
+
- component: button
|
|
232
|
+
name: exportBtn
|
|
233
|
+
props: { label: { en-US: "Export" }, icon: download }
|
|
234
|
+
- component: button
|
|
235
|
+
name: createBtn
|
|
236
|
+
props: { label: { en-US: "Create" }, icon: plus, options: { variant: primary } }
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## card
|
|
242
|
+
|
|
243
|
+
MUI Card container with optional header, content, and actions.
|
|
244
|
+
|
|
245
|
+
**Props (under `options`):**
|
|
246
|
+
| Prop | Type | Default | Description |
|
|
247
|
+
|------|------|---------|-------------|
|
|
248
|
+
| `variant` | `elevation \| outlined` | — | MUI Card variant |
|
|
249
|
+
| `elevation` | `number` | — | Shadow depth |
|
|
250
|
+
| `sx` | `SxProps` | — | Card sx styles |
|
|
251
|
+
| `className` | `string` | — | Additional CSS class |
|
|
252
|
+
| `bgcolor` | `string` | — | Background color |
|
|
253
|
+
| `color` | `string` | — | Text color |
|
|
254
|
+
| `header` | `{title?, subheader?, sx?}` | — | Renders MUI CardHeader |
|
|
255
|
+
| `disableContentWrapper` | `boolean` | `false` | Skip CardContent wrapper |
|
|
256
|
+
| `contentSx` | `SxProps` | — | CardContent styles |
|
|
257
|
+
| `contentClassName` | `string` | `card-content` | CardContent CSS class |
|
|
258
|
+
|
|
259
|
+
**Children:** Yes — wrapped in CardContent (unless `disableContentWrapper`).
|
|
260
|
+
|
|
261
|
+
```yaml
|
|
262
|
+
component: card
|
|
263
|
+
name: summaryCard
|
|
264
|
+
props:
|
|
265
|
+
options:
|
|
266
|
+
variant: outlined
|
|
267
|
+
header:
|
|
268
|
+
title: "Summary"
|
|
269
|
+
subheader: "Last updated today"
|
|
270
|
+
contentSx:
|
|
271
|
+
padding: 2
|
|
272
|
+
children:
|
|
273
|
+
- component: text
|
|
274
|
+
name: total
|
|
275
|
+
props: { value: "Total: {{ totalAmount }}", type: h4 }
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## line
|
|
281
|
+
|
|
282
|
+
Simple `<hr>` horizontal divider.
|
|
283
|
+
|
|
284
|
+
**Props:**
|
|
285
|
+
| Prop | Type | Default | Description |
|
|
286
|
+
|------|------|---------|-------------|
|
|
287
|
+
| `options.style` | `CSSProperties` | `margin: 0.5rem 0` | Inline styles |
|
|
288
|
+
|
|
289
|
+
```yaml
|
|
290
|
+
component: line
|
|
291
|
+
name: divider
|
|
292
|
+
props:
|
|
293
|
+
options:
|
|
294
|
+
style: { margin: "1rem 0" }
|
|
295
|
+
```
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
# Specialized Components
|
|
2
|
+
|
|
3
|
+
## calendar
|
|
4
|
+
|
|
5
|
+
FullCalendar integration with GraphQL event sources, timezone support, and programmatic control.
|
|
6
|
+
|
|
7
|
+
**Props:**
|
|
8
|
+
| Prop | Type | Default | Description |
|
|
9
|
+
|------|------|---------|-------------|
|
|
10
|
+
| `calendarId` | `string` | — | Calendar ID (template-parsed), used for timezone fetch |
|
|
11
|
+
| `initialView` | `string` | `dayGridMonth` | View: `dayGridMonth`, `timeGridWeek`, `timeGridDay`, `listMonth` |
|
|
12
|
+
| `height` | `number` | `600` | Calendar height |
|
|
13
|
+
| `aspectRatio` | `number` | `1.35` | Calendar aspect ratio |
|
|
14
|
+
| `options.headerToolbar` | `object` | — | FullCalendar header toolbar config |
|
|
15
|
+
| `options.selectable` | `boolean` | — | Enable date selection |
|
|
16
|
+
| `options.editable` | `boolean` | — | Enable drag/resize events |
|
|
17
|
+
| `options.weekends` | `boolean` | — | Show weekends |
|
|
18
|
+
| `options.nowIndicator` | `boolean` | — | Show current time line |
|
|
19
|
+
| `options.eventDisplay` | `string` | — | Event display style |
|
|
20
|
+
| `options.eventSources` | `EventSource[]` | — | Event data sources |
|
|
21
|
+
|
|
22
|
+
**EventSource definition:**
|
|
23
|
+
| Prop | Type | Description |
|
|
24
|
+
|------|------|-------------|
|
|
25
|
+
| `query.command` | `string` | GraphQL query |
|
|
26
|
+
| `query.variables` | `object` | Query variables |
|
|
27
|
+
| `query.path` | `string` | Path to events in response |
|
|
28
|
+
| `query.mapping` | `object` | Field mapping for events |
|
|
29
|
+
| `color` | `string` | Event background color |
|
|
30
|
+
| `textColor` | `string` | Event text color |
|
|
31
|
+
|
|
32
|
+
**Events:**
|
|
33
|
+
| Event | Data | Description |
|
|
34
|
+
|-------|------|-------------|
|
|
35
|
+
| `onDateClick` | `date, dateStr, allDay, view` | Date cell clicked |
|
|
36
|
+
| `onEventClick` | `event{id,title,start,end,allDay,extendedProps}, view` | Event clicked |
|
|
37
|
+
| `onSelect` | `start, end, startStr, endStr, allDay, view` | Date range selected |
|
|
38
|
+
| `onEventDrop` | `event, oldEvent, delta, revert` | Event drag-dropped |
|
|
39
|
+
| `onEventResize` | `event, oldEvent, revert` | Event resized |
|
|
40
|
+
| `onDatesSet` | `start, end, startStr, endStr, view` | Visible range changed |
|
|
41
|
+
|
|
42
|
+
**Store API:** Stores `calendar_{calendarId}` in context store with: `refresh()`, `changeView()`, `gotoDate()`, `prev()`, `next()`, `today()`.
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
component: calendar
|
|
46
|
+
name: shipmentCalendar
|
|
47
|
+
props:
|
|
48
|
+
calendarId: "{{ calendarId }}"
|
|
49
|
+
initialView: dayGridMonth
|
|
50
|
+
height: 700
|
|
51
|
+
options:
|
|
52
|
+
selectable: true
|
|
53
|
+
editable: true
|
|
54
|
+
weekends: true
|
|
55
|
+
nowIndicator: true
|
|
56
|
+
headerToolbar:
|
|
57
|
+
left: prev,next,today
|
|
58
|
+
center: title
|
|
59
|
+
right: dayGridMonth,timeGridWeek,timeGridDay
|
|
60
|
+
eventSources:
|
|
61
|
+
- query:
|
|
62
|
+
command: |
|
|
63
|
+
query($start: DateTime!, $end: DateTime!) {
|
|
64
|
+
shipments(startDate: $start, endDate: $end) {
|
|
65
|
+
id title startDate endDate status
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
variables:
|
|
69
|
+
start: "{{ startStr }}"
|
|
70
|
+
end: "{{ endStr }}"
|
|
71
|
+
path: shipments
|
|
72
|
+
mapping:
|
|
73
|
+
id: id
|
|
74
|
+
title: title
|
|
75
|
+
start: startDate
|
|
76
|
+
end: endDate
|
|
77
|
+
color: "#1976d2"
|
|
78
|
+
events:
|
|
79
|
+
onEventClick:
|
|
80
|
+
- navigate: "shipments/{{ event.id }}"
|
|
81
|
+
onDateClick:
|
|
82
|
+
- dialog:
|
|
83
|
+
component: Shipments/CreateShipment
|
|
84
|
+
props:
|
|
85
|
+
date: "{{ dateStr }}"
|
|
86
|
+
onSelect:
|
|
87
|
+
- dialog:
|
|
88
|
+
component: Shipments/CreateShipment
|
|
89
|
+
props:
|
|
90
|
+
startDate: "{{ startStr }}"
|
|
91
|
+
endDate: "{{ endStr }}"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## notes
|
|
97
|
+
|
|
98
|
+
Rich-text notes/comments component with TipTap editor, message threading, and pagination.
|
|
99
|
+
|
|
100
|
+
**Props:**
|
|
101
|
+
| Prop | Type | Default | Description |
|
|
102
|
+
|------|------|---------|-------------|
|
|
103
|
+
| `threadName` | `string` | — | Thread identifier (template-parsed) |
|
|
104
|
+
| `title` | `ILocalizeString` | `Notes` | Card title |
|
|
105
|
+
| `height` | `number` | `400` | Card max height |
|
|
106
|
+
| `placeholder` | `string` | — | Editor placeholder |
|
|
107
|
+
| `readonly` | `boolean \| string` | — | Hide input area |
|
|
108
|
+
| `options.allowAttachments` | `boolean` | `true` | Show attach button |
|
|
109
|
+
| `options.showTimestamps` | `boolean` | `true` | Show relative times |
|
|
110
|
+
| `options.showAuthor` | `boolean` | `true` | Show author info |
|
|
111
|
+
| `options.inputPosition` | `top \| bottom` | `top` | Input placement |
|
|
112
|
+
| `options.autoScroll` | `boolean` | `true` | Auto-scroll to latest |
|
|
113
|
+
| `pagination.pageSize` | `number` | `20` | Notes per page |
|
|
114
|
+
| `pagination.orderBy` | `string` | `created` | Sort field |
|
|
115
|
+
| `pagination.orderDirection` | `ASC \| DESC` | `DESC` | Sort direction |
|
|
116
|
+
| `pagination.loadMoreMode` | `button \| auto \| disabled` | `button` | Load more behavior |
|
|
117
|
+
| `permissions.create` | `string` | — | Create permission |
|
|
118
|
+
| `permissions.edit` | `string` | — | Edit permission |
|
|
119
|
+
| `permissions.delete` | `string` | — | Delete permission |
|
|
120
|
+
|
|
121
|
+
**Events:**
|
|
122
|
+
| Event | Description |
|
|
123
|
+
|-------|-------------|
|
|
124
|
+
| `onNoteCreated` | After note created |
|
|
125
|
+
| `onNoteUpdated` | After note updated |
|
|
126
|
+
| `onNoteDeleted` | After note deleted |
|
|
127
|
+
|
|
128
|
+
**Features:** Enter to send, Shift+Enter for newline. Message grouping (5 min window). Date separators. Long message collapse (>500 chars). Edit/delete on hover.
|
|
129
|
+
|
|
130
|
+
```yaml
|
|
131
|
+
component: notes
|
|
132
|
+
name: orderNotes
|
|
133
|
+
props:
|
|
134
|
+
threadName: "order-{{ orderId }}"
|
|
135
|
+
title: { en-US: "Order Notes" }
|
|
136
|
+
height: 500
|
|
137
|
+
placeholder: "Add a note..."
|
|
138
|
+
options:
|
|
139
|
+
allowAttachments: true
|
|
140
|
+
inputPosition: top
|
|
141
|
+
autoScroll: true
|
|
142
|
+
pagination:
|
|
143
|
+
pageSize: 30
|
|
144
|
+
orderDirection: DESC
|
|
145
|
+
loadMoreMode: button
|
|
146
|
+
permissions:
|
|
147
|
+
create: "Orders/CreateNote"
|
|
148
|
+
edit: "Orders/EditNote"
|
|
149
|
+
delete: "Orders/DeleteNote"
|
|
150
|
+
events:
|
|
151
|
+
onNoteCreated:
|
|
152
|
+
- refresh: orderActivity
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## dashboard
|
|
158
|
+
|
|
159
|
+
CSS Grid-based dashboard with draggable/resizable widgets.
|
|
160
|
+
|
|
161
|
+
**Props:**
|
|
162
|
+
| Prop | Type | Default | Description |
|
|
163
|
+
|------|------|---------|-------------|
|
|
164
|
+
| `toolbar` | `component[]` | — | Filter/form fields in header |
|
|
165
|
+
| `options.rows` | `number` | `12` | Grid rows |
|
|
166
|
+
| `options.columns` | `number` | `12` | Grid columns |
|
|
167
|
+
| `options.gridGap` | `number` | `16` | Gap between cells (px) |
|
|
168
|
+
| `options.allowEdit` | `boolean` | `false` | Enable edit mode (drag/resize/add/remove) |
|
|
169
|
+
| `options.showGridLines` | `boolean` | `true` | Grid background in edit mode |
|
|
170
|
+
| `options.autoSave` | `boolean` | `false` | Auto-save layout |
|
|
171
|
+
| `options.title` | `string` | — | Dashboard title |
|
|
172
|
+
| `options.height` | `string` | — | Container height |
|
|
173
|
+
|
|
174
|
+
**Children:** `dashboard-widget` components only.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## dashboard-widget
|
|
179
|
+
|
|
180
|
+
Positioned widget card inside a dashboard. Supports drag-to-move and resize in edit mode.
|
|
181
|
+
|
|
182
|
+
**Props (under `options`):**
|
|
183
|
+
| Prop | Type | Default | Description |
|
|
184
|
+
|------|------|---------|-------------|
|
|
185
|
+
| `row` | `number` | `1` | Grid row start |
|
|
186
|
+
| `col` | `number` | `1` | Grid column start |
|
|
187
|
+
| `rowSpan` | `number` | `1` | Rows spanned |
|
|
188
|
+
| `colSpan` | `number` | `1` | Columns spanned |
|
|
189
|
+
| `title` | `string` | — | Widget header title |
|
|
190
|
+
| `showHeader` | `boolean` | `true` | Show card header |
|
|
191
|
+
| `minRowSpan` / `maxRowSpan` | `number` | — | Size constraints |
|
|
192
|
+
| `minColSpan` / `maxColSpan` | `number` | — | Size constraints |
|
|
193
|
+
| `allowScroll` | `boolean` | `false` | Allow content scroll |
|
|
194
|
+
|
|
195
|
+
**Children:** Yes — any components.
|
|
196
|
+
|
|
197
|
+
```yaml
|
|
198
|
+
# Dashboard with widgets
|
|
199
|
+
component: dashboard
|
|
200
|
+
name: operationsDashboard
|
|
201
|
+
props:
|
|
202
|
+
options:
|
|
203
|
+
rows: 8
|
|
204
|
+
columns: 12
|
|
205
|
+
gridGap: 16
|
|
206
|
+
allowEdit: true
|
|
207
|
+
title: "Operations Dashboard"
|
|
208
|
+
toolbar:
|
|
209
|
+
- component: field
|
|
210
|
+
name: dateRange
|
|
211
|
+
props: { type: rangedatetime, label: { en-US: "Date Range" } }
|
|
212
|
+
children:
|
|
213
|
+
- component: dashboard-widget
|
|
214
|
+
name: revenueWidget
|
|
215
|
+
props:
|
|
216
|
+
options:
|
|
217
|
+
row: 1
|
|
218
|
+
col: 1
|
|
219
|
+
rowSpan: 3
|
|
220
|
+
colSpan: 6
|
|
221
|
+
title: "Revenue"
|
|
222
|
+
children:
|
|
223
|
+
- component: widget
|
|
224
|
+
name: revenueChart
|
|
225
|
+
props:
|
|
226
|
+
type: chart
|
|
227
|
+
queries:
|
|
228
|
+
- name: getRevenue
|
|
229
|
+
query:
|
|
230
|
+
command: "query { monthlyRevenue { month amount } }"
|
|
231
|
+
|
|
232
|
+
- component: dashboard-widget
|
|
233
|
+
name: statsWidget
|
|
234
|
+
props:
|
|
235
|
+
options:
|
|
236
|
+
row: 1
|
|
237
|
+
col: 7
|
|
238
|
+
rowSpan: 3
|
|
239
|
+
colSpan: 6
|
|
240
|
+
title: "Quick Stats"
|
|
241
|
+
children:
|
|
242
|
+
- component: widget
|
|
243
|
+
name: orderStats
|
|
244
|
+
props:
|
|
245
|
+
type: stats
|
|
246
|
+
queries:
|
|
247
|
+
- name: getStats
|
|
248
|
+
query:
|
|
249
|
+
command: "query { orderStats { total pending completed } }"
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## widget
|
|
255
|
+
|
|
256
|
+
Data-driven widget that delegates to sub-components by type.
|
|
257
|
+
|
|
258
|
+
**Props:**
|
|
259
|
+
| Prop | Type | Description |
|
|
260
|
+
|------|------|-------------|
|
|
261
|
+
| `type` | `stats \| chart \| kpi \| metric \| table` | **Required.** Widget type |
|
|
262
|
+
| `initialValues` | `object` | Data loading config (like form) |
|
|
263
|
+
| `queries` | `object` | Named GraphQL queries |
|
|
264
|
+
| `data` | `object` | Static data |
|
|
265
|
+
| `refreshHandler` | `string` | Refresh handler |
|
|
266
|
+
|
|
267
|
+
**Events:** `onLoading`, `onSuccess` (data: `loadedData`), `onError` (data: `error`)
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## timeline
|
|
272
|
+
|
|
273
|
+
MUI Lab Timeline for displaying events chronologically. Horizontal or vertical orientation.
|
|
274
|
+
|
|
275
|
+
**Props:**
|
|
276
|
+
| Prop | Type | Default | Description |
|
|
277
|
+
|------|------|---------|-------------|
|
|
278
|
+
| `orientation` | `horizontal \| vertical` | `horizontal` | Layout mode |
|
|
279
|
+
| `view` | `day \| week \| month \| year` | `week` | Time view |
|
|
280
|
+
| `startDate` / `endDate` | `string` | — | Initial date range |
|
|
281
|
+
| `eventSources` | `EventSource[]` | — | Same pattern as calendar |
|
|
282
|
+
| `eventTemplate` | `ComponentProps` | — | Custom event template |
|
|
283
|
+
| `options.height` | `string \| number` | `400` | Component height |
|
|
284
|
+
| `options.showTodayMarker` | `boolean` | `true` | Today marker |
|
|
285
|
+
| `options.enableZoom` | `boolean` | `true` | View switcher |
|
|
286
|
+
| `options.enableNavigation` | `boolean` | `true` | Prev/next/today buttons |
|
|
287
|
+
| `options.alternating` | `boolean` | `true` | Alternate sides (vertical) |
|
|
288
|
+
| `options.dateFormat` | `string` | `MMM DD` | Date format |
|
|
289
|
+
|
|
290
|
+
**Events:** `onEventClick` (data: `event`)
|
|
291
|
+
|
|
292
|
+
```yaml
|
|
293
|
+
component: timeline
|
|
294
|
+
name: orderTimeline
|
|
295
|
+
props:
|
|
296
|
+
orientation: vertical
|
|
297
|
+
view: month
|
|
298
|
+
options:
|
|
299
|
+
enableNavigation: true
|
|
300
|
+
alternating: true
|
|
301
|
+
eventSources:
|
|
302
|
+
- query:
|
|
303
|
+
command: "query($id: Int!) { orderHistory(orderId: $id) { id title date type } }"
|
|
304
|
+
variables: { id: "{{ number orderId }}" }
|
|
305
|
+
path: orderHistory
|
|
306
|
+
eventTemplate:
|
|
307
|
+
component: card
|
|
308
|
+
name: eventCard
|
|
309
|
+
props:
|
|
310
|
+
options:
|
|
311
|
+
variant: outlined
|
|
312
|
+
header:
|
|
313
|
+
title: "{{ item.title }}"
|
|
314
|
+
subheader: "{{ format item.date LLL }}"
|
|
315
|
+
events:
|
|
316
|
+
onEventClick:
|
|
317
|
+
- dialog:
|
|
318
|
+
component: Orders/EventDetail
|
|
319
|
+
props: { eventId: "{{ event.id }}" }
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## timeline-grid
|
|
325
|
+
|
|
326
|
+
CSS Grid-based timeline with swim lanes, drill-down, and virtual scrolling.
|
|
327
|
+
|
|
328
|
+
**Props:**
|
|
329
|
+
| Prop | Type | Default | Description |
|
|
330
|
+
|------|------|---------|-------------|
|
|
331
|
+
| `view` | `day \| week \| month \| year` | `week` | Time view |
|
|
332
|
+
| `startDate` / `endDate` | `string` | — | Date range |
|
|
333
|
+
| `eventSources` | `EventSource[]` | — | Event data sources |
|
|
334
|
+
| `eventTemplate` | `ComponentProps` | — | Custom event template |
|
|
335
|
+
| `options.height` | `string \| number` | `600` | Container height |
|
|
336
|
+
| `options.cellHeight` | `number` | `60/100` | Cell height (px) |
|
|
337
|
+
| `options.groupBy` | `string` | — | Field for swim lane grouping |
|
|
338
|
+
| `options.showTodayMarker` | `boolean` | `true` | Today marker |
|
|
339
|
+
| `options.enableNavigation` | `boolean` | `true` | Nav controls |
|
|
340
|
+
| `options.virtualScroll` | `boolean` | `true` | Virtual scrolling |
|
|
341
|
+
| `options.hourInterval` | `15 \| 30 \| 60` | `60` | Time intervals (day/week) |
|
|
342
|
+
| `options.showWeekends` | `boolean` | `true` | Show weekends |
|
|
343
|
+
| `options.showTotalCount` | `boolean` | `false` | Show event totals |
|
|
344
|
+
|
|
345
|
+
**Events:**
|
|
346
|
+
| Event | Data | Description |
|
|
347
|
+
|-------|------|-------------|
|
|
348
|
+
| `onEventClick` | `item, view` | Event clicked |
|
|
349
|
+
| `onCellClick` | `column, row, date, view` | Empty cell clicked |
|
|
350
|
+
| `onViewChange` | `previousView, newView, startDate, endDate` | View changed |
|
|
351
|
+
| `onNavigate` | `direction, view, startDate, endDate` | Navigation |
|
|
352
|
+
| `onEventsLoaded` | `events, eventCount, view, dataRange` | Data loaded |
|
|
353
|
+
| `onLoad` | `view, startDate, endDate, options` | Initial mount |
|
|
354
|
+
|
|
355
|
+
**Column drill-down:** Click column header: year->month, month->week, week->day.
|
|
356
|
+
|
|
357
|
+
```yaml
|
|
358
|
+
component: timeline-grid
|
|
359
|
+
name: scheduleGrid
|
|
360
|
+
props:
|
|
361
|
+
view: week
|
|
362
|
+
options:
|
|
363
|
+
height: 700
|
|
364
|
+
cellHeight: 80
|
|
365
|
+
groupBy: assignee
|
|
366
|
+
showWeekends: false
|
|
367
|
+
hourInterval: 30
|
|
368
|
+
showTotalCount: true
|
|
369
|
+
enableNavigation: true
|
|
370
|
+
eventSources:
|
|
371
|
+
- query:
|
|
372
|
+
command: |
|
|
373
|
+
query($start: DateTime!, $end: DateTime!) {
|
|
374
|
+
scheduleEvents(start: $start, end: $end) {
|
|
375
|
+
id title startDate endDate assignee status
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
path: scheduleEvents
|
|
379
|
+
events:
|
|
380
|
+
onEventClick:
|
|
381
|
+
- dialog:
|
|
382
|
+
component: Schedule/EventDetail
|
|
383
|
+
props: { eventId: "{{ item.id }}" }
|
|
384
|
+
onCellClick:
|
|
385
|
+
- dialog:
|
|
386
|
+
component: Schedule/CreateEvent
|
|
387
|
+
props: { date: "{{ date }}", assignee: "{{ row }}" }
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## oauth2
|
|
393
|
+
|
|
394
|
+
OAuth2 authorization flow button. Opens popup for auth, exchanges code for token.
|
|
395
|
+
|
|
396
|
+
**Props:**
|
|
397
|
+
| Prop | Type | Description |
|
|
398
|
+
|------|------|-------------|
|
|
399
|
+
| `clientId` | `string` | OAuth2 client ID (template-parsed) |
|
|
400
|
+
| `clientSecret` | `string` | OAuth2 client secret (template-parsed) |
|
|
401
|
+
| `authorizationUrl` | `string` | Authorization endpoint |
|
|
402
|
+
| `tokenUrl` | `string` | Token exchange endpoint |
|
|
403
|
+
| `scopes` | `string[]` | Requested scopes |
|
|
404
|
+
| `additionalParams` | `Record<string, string>` | Extra auth URL params |
|
|
405
|
+
| `additionalHeaders` | `object` | Extra token request headers |
|
|
406
|
+
| `label` | `ILocalizeString` | Button label (default: `Authorize`) |
|
|
407
|
+
| `className` | `string` | Button CSS class |
|
|
408
|
+
|
|
409
|
+
**Events:** `onToken` — fires with `{ token }` when OAuth completes.
|
|
410
|
+
|
|
411
|
+
```yaml
|
|
412
|
+
component: oauth2
|
|
413
|
+
name: intuitAuth
|
|
414
|
+
props:
|
|
415
|
+
label: { en-US: "Connect QuickBooks" }
|
|
416
|
+
clientId: "{{ quickbooksClientId }}"
|
|
417
|
+
clientSecret: "{{ quickbooksClientSecret }}"
|
|
418
|
+
authorizationUrl: "https://appcenter.intuit.com/connect/oauth2"
|
|
419
|
+
tokenUrl: "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer"
|
|
420
|
+
scopes:
|
|
421
|
+
- com.intuit.quickbooks.accounting
|
|
422
|
+
onToken:
|
|
423
|
+
- mutation:
|
|
424
|
+
command: "mutation($token: String!) { saveOAuthToken(token: $token) { success } }"
|
|
425
|
+
variables: { token: "{{ token }}" }
|
|
426
|
+
- notification: { message: { en-US: "Connected!" }, type: success }
|
|
427
|
+
```
|