cabloy 5.1.159 → 5.1.161
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/.cabloy-version +1 -1
- package/CHANGELOG.md +22 -0
- package/package.json +1 -1
- package/repo-docs/.vitepress/config.mjs +11 -0
- package/repo-docs/backend/department-management.md +98 -0
- package/repo-docs/backend/menu-authorization.md +124 -0
- package/repo-docs/backend/rbac-authorization.md +117 -0
- package/repo-docs/backend/resource-field-update.md +2 -2
- package/repo-docs/backend/role-management.md +92 -0
- package/repo-docs/backend/shared-rbac-architecture.md +339 -0
- package/repo-docs/backend/user-management.md +92 -0
- package/repo-docs/frontend/model-resource-owner-pattern.md +2 -0
- package/repo-docs/frontend/permission-formscene-action-visibility-guide.md +5 -3
- package/repo-docs/frontend/table-action-visibility-permission-flow-guide.md +2 -0
- package/repo-docs/frontend/table-guide.md +75 -22
- package/repo-docs/frontend/table-resource-crud-cookbook.md +25 -4
- package/repo-docs/frontend/zova-table-source-reading-map.md +54 -19
- package/repo-docs/frontend/zova-table-under-the-hood.md +70 -39
- package/repo-e2e/specs/cabloy-basic.spec.ts +16 -16
- package/vona/packages-cli/cli/package.json +1 -1
- package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/entity/{{resourceName}}.tsx_ +1 -1
- package/vona/packages-cli/cli-set-api/package.json +1 -1
- package/vona/pnpm-lock.yaml +80 -84
- package/zova/pnpm-lock.yaml +16 -16
|
@@ -47,7 +47,7 @@ If you only remember one idea, remember this one:
|
|
|
47
47
|
That leads to three common authoring surfaces:
|
|
48
48
|
|
|
49
49
|
- `ZTable` — the root table component
|
|
50
|
-
- schema `
|
|
50
|
+
- schema metadata — `ZovaRender.column(...)` supplies table-column layout/capability metadata, while shared/table-scene overlays supply effective visibility, order, and render metadata
|
|
51
51
|
- `tableCell` beans — the main extension surface for reusable cell rendering
|
|
52
52
|
|
|
53
53
|
## One running example through this guide: Student list page
|
|
@@ -123,17 +123,12 @@ A practical reading takeaway is:
|
|
|
123
123
|
|
|
124
124
|
In the default path, `ZTable` reads table-scene metadata from the row schema.
|
|
125
125
|
|
|
126
|
-
The
|
|
127
|
-
|
|
128
|
-
- `order`
|
|
129
|
-
- `visible`
|
|
130
|
-
- `render`
|
|
131
|
-
- `columnProps`
|
|
126
|
+
The table sees the **effective table metadata**, not only one literal source object. It combines shared field `rest` metadata with the table-scene `rest.table` overlay, then orders the resulting properties by effective `rest.order`.
|
|
132
127
|
|
|
133
128
|
A simplified mental model is:
|
|
134
129
|
|
|
135
130
|
```text
|
|
136
|
-
schema row ->
|
|
131
|
+
schema row -> merge table metadata -> sort by order -> filter by visible -> build columns -> render cells
|
|
137
132
|
```
|
|
138
133
|
|
|
139
134
|
That means the default list-page question becomes less:
|
|
@@ -146,6 +141,58 @@ and more:
|
|
|
146
141
|
|
|
147
142
|
This is why table work often belongs in the broader contract loop when the real source of truth is backend field metadata.
|
|
148
143
|
|
|
144
|
+
## Step 4: Configure physical columns with `ZovaRender.column(...)`
|
|
145
|
+
|
|
146
|
+
`ZovaRender.column(...)` is a shared Cabloy/Zova schema-metadata API available in both Cabloy Basic and Cabloy Start. It returns a schema transformer that writes column options under `rest.table`; it does **not** register a frontend column or render a cell by itself.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
@Api.field(
|
|
150
|
+
v.title($locale('Name')),
|
|
151
|
+
ZovaRender.column({
|
|
152
|
+
align: 'left',
|
|
153
|
+
width: 240,
|
|
154
|
+
fixed: 'left',
|
|
155
|
+
enableSorting: true,
|
|
156
|
+
sortDescFirst: true,
|
|
157
|
+
}),
|
|
158
|
+
v.string(),
|
|
159
|
+
)
|
|
160
|
+
name: string;
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The current options are:
|
|
164
|
+
|
|
165
|
+
| Option | Meaning in the table runtime |
|
|
166
|
+
| --------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
167
|
+
| `order` | Orders this property among the effective table properties. For shared field order, `ZovaRender.order(...)` is usually clearer. |
|
|
168
|
+
| `align` | Applies `left`, `center`, or `right` text alignment to the header and cells. |
|
|
169
|
+
| `width` | Supplies the TanStack column size and current renderers apply it as pixel width and minimum width. |
|
|
170
|
+
| `fixed` | Pins the column to the `left` or `right`; the table runtime calculates pinning and renderers apply sticky offsets. |
|
|
171
|
+
| `enableSorting` | Requests a sortable header, subject to the order-schema capability described below. |
|
|
172
|
+
| `sortDescFirst` | Makes the first header toggle descend; it does not change backend order syntax. |
|
|
173
|
+
|
|
174
|
+
`ZovaRender.column(...)` configures the physical column. `ZovaRender.cell(...)` independently selects the cell renderer and its options. For example, a virtual Operations field can be right-pinned and centered while its content comes from a reusable `tableCell` resource:
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
@Api.field(
|
|
178
|
+
v.title($locale('Operations')),
|
|
179
|
+
ZovaRender.order(1, 'max'),
|
|
180
|
+
ZovaRender.column({ align: 'center', width: 360, fixed: 'right' }),
|
|
181
|
+
ZovaRender.cell('basic-table:actionOperationsRow', { actions }),
|
|
182
|
+
)
|
|
183
|
+
_operationsRow?: unknown;
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
The `basic-table:*` renderer key in this example is Cabloy Basic-specific. The `ZovaRender.column(...)` contract itself is shared; use the active edition's renderer keys when selecting a cell resource.
|
|
187
|
+
|
|
188
|
+
### Enable server-backed sorting
|
|
189
|
+
|
|
190
|
+
`enableSorting: true` is necessary but not sufficient. The same field, canonical key, or schema alias must also exist in `schemaOrder`; otherwise the table deliberately creates a non-sortable column.
|
|
191
|
+
|
|
192
|
+
A direct `ZTable` consumer owns and passes `schemaOrder`, controlled `sorting`, and `onSortingChange`. In the standard Cabloy Basic resource-page path, `basic-page:blockTable` passes those values from `basic-page:blockPage`; the page translates one manual table sort into backend `orders` and reloads the resource query. The loaded page is not client-side sorted by TanStack.
|
|
193
|
+
|
|
194
|
+
For relation-order rewriting, see [Existing Resource Field Update](/backend/resource-field-update#filter-and-sort-a-relation-by-its-display-field). For the resource-page bridge, see [Table + Resource CRUD Cookbook](/frontend/table-resource-crud-cookbook).
|
|
195
|
+
|
|
149
196
|
A practical expression example is a schema-driven cell display that formats the current row value through CEL:
|
|
150
197
|
|
|
151
198
|
```text
|
|
@@ -156,7 +203,7 @@ In the shared table CEL scope, `getValue(name)` reads the current row value and
|
|
|
156
203
|
|
|
157
204
|
For the schema side of that contract, also see [API Schema Guide](/frontend/api-schema-guide).
|
|
158
205
|
|
|
159
|
-
## Step
|
|
206
|
+
## Step 5: Use built-in or custom `tableCell` render resources
|
|
160
207
|
|
|
161
208
|
A column render is usually chosen through schema metadata such as:
|
|
162
209
|
|
|
@@ -184,7 +231,7 @@ A practical rule is:
|
|
|
184
231
|
- use built-in `tableCell` resources first
|
|
185
232
|
- add a custom `tableCell` bean only when the business UI really needs module-owned rendering behavior
|
|
186
233
|
|
|
187
|
-
## Step
|
|
234
|
+
## Step 6: Create a custom `tableCell` bean
|
|
188
235
|
|
|
189
236
|
When a built-in renderer is not enough, use the existing CLI-backed scene workflow.
|
|
190
237
|
|
|
@@ -230,7 +277,7 @@ That scaffold is useful because it starts from the correct Zova scene contract:
|
|
|
230
277
|
|
|
231
278
|
For the broader scene system behind this decorator, see [Bean Scene Authoring](/frontend/bean-scene-authoring).
|
|
232
279
|
|
|
233
|
-
## Step
|
|
280
|
+
## Step 7: Add page-local custom columns with `getColumns(...)`
|
|
234
281
|
|
|
235
282
|
When most columns should stay schema-driven but one column should be page-local, use `getColumns(...)`.
|
|
236
283
|
|
|
@@ -275,7 +322,7 @@ A practical caveat is:
|
|
|
275
322
|
|
|
276
323
|
So a mixed table does **not** mean bypassing Zova. It means extending the existing runtime through its own hooks.
|
|
277
324
|
|
|
278
|
-
## Step
|
|
325
|
+
## Step 8: Use resource-driven page blocks for CRUD list pages
|
|
279
326
|
|
|
280
327
|
For standard resource pages, the more common public surface is not direct `ZTable` usage. It is the block-based page runtime:
|
|
281
328
|
|
|
@@ -299,7 +346,7 @@ This gives you a cohesive CRUD path where:
|
|
|
299
346
|
|
|
300
347
|
For the resource ownership side of that page shape, see [Model Resource Owner Pattern](/frontend/model-resource-owner-pattern).
|
|
301
348
|
|
|
302
|
-
## Step
|
|
349
|
+
## Step 9: Know when to use `BeanControllerPageTableBase`
|
|
303
350
|
|
|
304
351
|
If your table belongs directly to a page controller rather than a reusable component controller, the page-oriented base class already exists:
|
|
305
352
|
|
|
@@ -322,15 +369,19 @@ TanStack Table is still important, but the business-facing runtime is controller
|
|
|
322
369
|
|
|
323
370
|
For many resource pages, the faster path is to let `rest.table` metadata describe the default columns first.
|
|
324
371
|
|
|
325
|
-
### Mistake 3:
|
|
372
|
+
### Mistake 3: Treating `ZovaRender.column(...)` as a cell renderer
|
|
373
|
+
|
|
374
|
+
`ZovaRender.column(...)` supplies column layout and sorting metadata. Use `ZovaRender.cell(...)` to name the cell render target, and use a `tableCell` bean when that reusable renderer needs module-owned behavior.
|
|
375
|
+
|
|
376
|
+
### Mistake 4: Bypassing `tableCell` beans for reusable cell behavior
|
|
326
377
|
|
|
327
378
|
If a renderer should be shared across pages or modules, prefer a `tableCell` resource over repeated page-local callbacks.
|
|
328
379
|
|
|
329
|
-
### Mistake
|
|
380
|
+
### Mistake 5: Treating `controllerRef` like a generic Vue DOM ref
|
|
330
381
|
|
|
331
382
|
`controllerRef` gives you the table controller instance, not a plain DOM element.
|
|
332
383
|
|
|
333
|
-
### Mistake
|
|
384
|
+
### Mistake 6: Rebuilding CRUD list wiring manually when `basic-page` already owns it
|
|
334
385
|
|
|
335
386
|
For standard resource pages, prefer the existing block/page runtime before hand-building a custom table flow.
|
|
336
387
|
|
|
@@ -340,12 +391,12 @@ If you want the shortest accurate path to a real business table, use this order:
|
|
|
340
391
|
|
|
341
392
|
1. make sure the backend row schema is already the right contract truth
|
|
342
393
|
2. start with a resource page or direct `ZTable`
|
|
343
|
-
3. let schema metadata drive the default columns
|
|
344
|
-
4.
|
|
394
|
+
3. let schema metadata drive the default columns; add `ZovaRender.column(...)` only where layout, pinning, or sorting metadata is needed
|
|
395
|
+
4. use `ZovaRender.cell(...)` and built-in `tableCell` renderers for cell content first
|
|
345
396
|
5. add page-local `getColumns(...)` only where needed
|
|
346
397
|
6. create custom `tableCell` beans only where the UI becomes business-specific
|
|
347
398
|
7. continue with [TableCell Authoring Cookbook](/frontend/table-cell-cookbook) when you want concrete patterns for custom cell beans and row actions
|
|
348
|
-
8. continue with [Table + Resource CRUD Cookbook](/frontend/table-resource-crud-cookbook) when you want the standard resource-page integration path for filter, bulk actions, table, and
|
|
399
|
+
8. continue with [Table + Resource CRUD Cookbook](/frontend/table-resource-crud-cookbook) when you want the standard resource-page integration path for filter, bulk actions, table, pager, and server sorting
|
|
349
400
|
9. continue with [Zova Table Under the Hood](/frontend/zova-table-under-the-hood) when you want the runtime explanation behind the public authoring surface
|
|
350
401
|
10. continue with [Zova Table Source Reading Map](/frontend/zova-table-source-reading-map) when you need framework-level source details and targeted file-order guidance
|
|
351
402
|
|
|
@@ -359,9 +410,11 @@ When documenting or changing a table workflow, verify in this order:
|
|
|
359
410
|
npm run zova :create:bean --help
|
|
360
411
|
```
|
|
361
412
|
|
|
362
|
-
2. confirm the `
|
|
363
|
-
3. confirm the
|
|
364
|
-
4.
|
|
413
|
+
2. confirm the `ZovaRender.column(...)` option contract and table-scene metadata merge still match current source
|
|
414
|
+
3. confirm the `tableCell` scene metadata still exists in the current `a-table` module
|
|
415
|
+
4. for sortable resource columns, verify header state, fixed-column layout/overflow where relevant, and the backend `orders` request
|
|
416
|
+
5. confirm the runtime claims against the current `a-table`, `basic-table`, and `basic-page` source
|
|
417
|
+
6. if you changed docs, build the docs site:
|
|
365
418
|
|
|
366
419
|
```bash
|
|
367
420
|
npm run docs:build
|
|
@@ -269,6 +269,8 @@ Its bridge role is very clear:
|
|
|
269
269
|
- render `ZTable`
|
|
270
270
|
- pass page data into `data`
|
|
271
271
|
- pass row schema into `schema`
|
|
272
|
+
- pass the resource order schema into `schemaOrder`
|
|
273
|
+
- pass controlled `sorting` and `onSortingChange`
|
|
272
274
|
- pass page CEL scope into `tableScope`
|
|
273
275
|
- capture the table controller through `controllerRef`
|
|
274
276
|
|
|
@@ -329,10 +331,13 @@ _operationsRow?: unknown;
|
|
|
329
331
|
|
|
330
332
|
This is the practical reverse-sharing model:
|
|
331
333
|
|
|
332
|
-
-
|
|
334
|
+
- `ZovaRender.column(...)` configures physical-column behavior such as alignment, width, pinning, and sorting eligibility
|
|
335
|
+
- `ZovaRender.cell(...)` chooses the table-cell resource identity and its options
|
|
333
336
|
- the frontend table runtime resolves that resource
|
|
334
337
|
- the page block and table block do not need page-local hard-coded row-action wiring
|
|
335
338
|
|
|
339
|
+
For example, an Operations field can add `ZovaRender.column({ align: 'center', width: 360, fixed: 'right' })` beside the existing `ZovaRender.cell(...)`. `ZovaRender.column(...)` is a shared Basic/Start capability; the `basic-table:*` cell key remains a Cabloy Basic choice.
|
|
340
|
+
|
|
336
341
|
For the built-in metadata-sharing teaching path, see [Tutorial 3: Frontend Metadata Sharing](/fullstack/tutorial-3-frontend-metadata-sharing).
|
|
337
342
|
|
|
338
343
|
For the forward-chain row-action teaching path, see [Tutorial 5: Backend Contract Sharing](/fullstack/tutorial-5-backend-contract-sharing).
|
|
@@ -346,10 +351,24 @@ For standard CRUD list pages, most customization should happen in one of these p
|
|
|
346
351
|
Use this when:
|
|
347
352
|
|
|
348
353
|
- a field should change order
|
|
354
|
+
- a column should change alignment, width, or left/right pinning
|
|
355
|
+
- a server-authorized field should expose a sortable header
|
|
349
356
|
- a column should be visible or hidden
|
|
350
357
|
- a field should use a different built-in or custom `tableCell`
|
|
351
358
|
|
|
352
|
-
This is usually the first and best extension point.
|
|
359
|
+
This is usually the first and best extension point. Use `ZovaRender.column(...)` for the column metadata and `ZovaRender.cell(...)` for the cell renderer; do not treat either helper as a replacement for the other.
|
|
360
|
+
|
|
361
|
+
### Enable standard resource-page sorting
|
|
362
|
+
|
|
363
|
+
For a normal Cabloy Basic resource list, backend field metadata can request a sortable column with:
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
ZovaRender.column({ enableSorting: true });
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
The field must also be present in the resource `schemaOrder`; that order schema remains the authority for whether the header is actually sortable. `blockTable` forwards the order schema plus controlled sorting state into `ZTable`, and `blockPage` turns one header selection into backend `orders` before reloading the resource query. This is server sorting, not local reordering of the current page.
|
|
370
|
+
|
|
371
|
+
For the full shared `ZovaRender.column(...)` contract, see [Table Guide](/frontend/table-guide#configure-physical-columns-with-zovarendercolumn). For relation-backed order rewriting, see [Existing Resource Field Update](/backend/resource-field-update#filter-and-sort-a-relation-by-its-display-field).
|
|
353
372
|
|
|
354
373
|
### Extension point B: backend block composition metadata
|
|
355
374
|
|
|
@@ -505,8 +524,8 @@ If you want the shortest path to a real CRUD list page, use this order:
|
|
|
505
524
|
1. generate or confirm the backend CRUD contract thread
|
|
506
525
|
2. confirm the resource-owner model already exposes the required schemas and permissions
|
|
507
526
|
3. keep the standard `blockPage -> blockFilter -> blockToolbarBulk -> blockTable -> blockPager` chain
|
|
508
|
-
4. refine backend row metadata for visible columns and row actions
|
|
509
|
-
5. reuse built-in `tableCell` resources first
|
|
527
|
+
4. refine backend row metadata for visible columns, layout/pinning/sort capability through `ZovaRender.column(...)`, and row actions
|
|
528
|
+
5. reuse `ZovaRender.cell(...)` with built-in `tableCell` resources first
|
|
510
529
|
6. add custom `tableCell` resources only where the UI becomes business-specific
|
|
511
530
|
7. change block controllers only when the existing runtime is structurally insufficient
|
|
512
531
|
8. continue with [Table Guide](/frontend/table-guide) for the public `ZTable` surface
|
|
@@ -533,6 +552,8 @@ When authoring or documenting a resource CRUD list page, verify in this order:
|
|
|
533
552
|
- filter works
|
|
534
553
|
- bulk actions render correctly
|
|
535
554
|
- table columns and row actions match metadata
|
|
555
|
+
- fixed columns, widths, and overflow behave as intended when configured
|
|
556
|
+
- sortable headers expose the expected state and reload with the intended backend `orders`
|
|
536
557
|
- pager updates the list correctly
|
|
537
558
|
7. if you changed docs, build the docs site:
|
|
538
559
|
|
|
@@ -120,7 +120,8 @@ Use this path when you are asking questions like:
|
|
|
120
120
|
Use this path when you are asking questions like:
|
|
121
121
|
|
|
122
122
|
- how does a row schema become visible columns?
|
|
123
|
-
- where do `
|
|
123
|
+
- where do `order`, `align`, `width`, `fixed`, `enableSorting`, and `sortDescFirst` come from?
|
|
124
|
+
- where do `visible`, `render`, and `columnProps` come from?
|
|
124
125
|
- how does the table scene differ from form or filter scenes?
|
|
125
126
|
|
|
126
127
|
### Read the docs first
|
|
@@ -130,17 +131,51 @@ Use this path when you are asking questions like:
|
|
|
130
131
|
|
|
131
132
|
### Then read source in this order
|
|
132
133
|
|
|
134
|
+
1. `zova/packages-cli/cli-set-front/cli/templates/rest/rest.ts`
|
|
135
|
+
2. `zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/rest.ts`
|
|
136
|
+
3. `zova/src/suite-vendor/a-zova/modules/a-openapi/src/lib/schema.ts`
|
|
137
|
+
4. `zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx`
|
|
138
|
+
5. `zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/render.tsx`
|
|
139
|
+
|
|
140
|
+
### What each file clarifies
|
|
141
|
+
|
|
142
|
+
- `cli/templates/rest/rest.ts` shows that `ZovaRender.column(...)` writes `ITableColumnOptions` under `rest.table`
|
|
143
|
+
- `types/rest.ts` defines `order`, `align`, `width`, `fixed`, `enableSorting`, and `sortDescFirst`
|
|
144
|
+
- `schema.ts` shows `loadSchemaProperties(...)`, `$ref` resolution, and the merge of shared `rest` metadata with table-scene overlays
|
|
145
|
+
- `controller.tsx` shows `_createProperties()`, `_createTableMeta()`, `_createColumnsMiddle()`, order-schema sorting eligibility, and pinning
|
|
146
|
+
- `render.tsx` shows how effective metadata becomes alignment, dimensions, fixed-column styles, and sortable header DOM
|
|
147
|
+
|
|
148
|
+
## 4. Column metadata, sortable headers, and resource orders
|
|
149
|
+
|
|
150
|
+
Use this path when you are asking questions like:
|
|
151
|
+
|
|
152
|
+
- why did `ZovaRender.column({ enableSorting: true })` not make a header sortable?
|
|
153
|
+
- how do fixed columns become sticky left/right columns?
|
|
154
|
+
- how does one header click become a resource request `orders` value?
|
|
155
|
+
|
|
156
|
+
### Read the docs first
|
|
157
|
+
|
|
158
|
+
- [Table Guide](/frontend/table-guide)
|
|
159
|
+
- [Table + Resource CRUD Cookbook](/frontend/table-resource-crud-cookbook)
|
|
160
|
+
- [Existing Resource Field Update](/backend/resource-field-update#filter-and-sort-a-relation-by-its-display-field)
|
|
161
|
+
|
|
162
|
+
### Then read source in this order
|
|
163
|
+
|
|
133
164
|
1. `zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx`
|
|
134
|
-
2. `zova/src/suite-vendor/a-zova/modules/a-
|
|
135
|
-
3. `zova/src/suite
|
|
165
|
+
2. `zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/render.tsx`
|
|
166
|
+
3. `zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockTable/controller.tsx`
|
|
167
|
+
4. `zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx`
|
|
136
168
|
|
|
137
169
|
### What each file clarifies
|
|
138
170
|
|
|
139
|
-
- `controller.tsx` shows `
|
|
140
|
-
- `
|
|
141
|
-
- `
|
|
171
|
+
- `controller.tsx` shows that `enableSorting` also requires the property key or aliases to exist in `schemaOrder`, and shows left/right pinning construction
|
|
172
|
+
- `render.tsx` shows the header toggle, `aria-sort`, indicators, and sticky styles
|
|
173
|
+
- `blockTable/controller.tsx` shows the handoff of `schemaOrder`, controlled sorting, and `onSortingChange`
|
|
174
|
+
- `blockPage/controller.tsx` shows conversion of the single current sort into backend `orders` and query reload
|
|
175
|
+
|
|
176
|
+
The result is a controlled, manual server-sorting path: the standard resource page does not client-side sort rows that have already been fetched. The `basic-page` files are Cabloy Basic specimens; the metadata API and base Zova Table behavior are shared with Cabloy Start, whose page module paths must be resolved in that edition.
|
|
142
177
|
|
|
143
|
-
##
|
|
178
|
+
## 5. `tableCell` bean-scene contract and decorator surface
|
|
144
179
|
|
|
145
180
|
Use this path when you are asking questions like:
|
|
146
181
|
|
|
@@ -168,7 +203,7 @@ Use this path when you are asking questions like:
|
|
|
168
203
|
- `package.json` shows `zovaModule.onions.tableCell` and boilerplate metadata
|
|
169
204
|
- the boilerplate files show the intended scaffold shape for normal cells and row-action cells
|
|
170
205
|
|
|
171
|
-
##
|
|
206
|
+
## 6. Cell render pipeline and CEL/JSX scope
|
|
172
207
|
|
|
173
208
|
Use this path when you are asking questions like:
|
|
174
209
|
|
|
@@ -193,7 +228,7 @@ Use this path when you are asking questions like:
|
|
|
193
228
|
- `tableColumn.ts` shows column scope, cell scope, and table column render types
|
|
194
229
|
- `tableCell.ts` shows the render-context contract received by a `tableCell` bean
|
|
195
230
|
|
|
196
|
-
##
|
|
231
|
+
## 7. Representative built-in cell renderers
|
|
197
232
|
|
|
198
233
|
Use this path when you are asking questions like:
|
|
199
234
|
|
|
@@ -220,7 +255,7 @@ Use this path when you are asking questions like:
|
|
|
220
255
|
- `tableCell.select.tsx` shows value-to-item mapping
|
|
221
256
|
- `actionOperationsRow.tsx` shows advanced visibility checks, nested action rendering, and permission-aware orchestration
|
|
222
257
|
|
|
223
|
-
##
|
|
258
|
+
## 8. Custom columns through `getColumns(...)`
|
|
224
259
|
|
|
225
260
|
Use this path when you are asking questions like:
|
|
226
261
|
|
|
@@ -243,15 +278,15 @@ Use this path when you are asking questions like:
|
|
|
243
278
|
|
|
244
279
|
- `types/table.ts` shows `TypeTableGetColumns` and `TypeTableCreateColumnRender`
|
|
245
280
|
- `controller.tsx` shows how custom columns are given `next(...)`, `createColumnRender(...)`, and the table controller itself
|
|
246
|
-
- `basic-table/render.tsx`
|
|
281
|
+
- `basic-table/render.tsx` is a Cabloy Basic forwarding wrapper around `ZTable`; it preserves the custom-column hook rather than serving as an executable custom-column specimen
|
|
247
282
|
|
|
248
|
-
##
|
|
283
|
+
## 9. Resource-page integration
|
|
249
284
|
|
|
250
285
|
Use this path when you are asking questions like:
|
|
251
286
|
|
|
252
287
|
- how does a resource list page feed schema and data into `ZTable`?
|
|
253
|
-
- where do `data`, `schemaRow`, and `tableScope` come from?
|
|
254
|
-
- where should permission-sensitive table refresh be debugged?
|
|
288
|
+
- where do `data`, `schemaRow`, `schemaOrder`, and `tableScope` come from?
|
|
289
|
+
- where should permission-sensitive table refresh or resource sorting be debugged?
|
|
255
290
|
|
|
256
291
|
### Read the docs first
|
|
257
292
|
|
|
@@ -266,11 +301,11 @@ Use this path when you are asking questions like:
|
|
|
266
301
|
|
|
267
302
|
### What each file clarifies
|
|
268
303
|
|
|
269
|
-
- `blockPage/controller.tsx` shows resource ownership, query state, page CEL scope, permissions,
|
|
270
|
-
- `blockTable/controller.tsx` shows the direct bridge from page block to `ZTable
|
|
304
|
+
- `blockPage/controller.tsx` shows resource ownership, query state, page CEL scope, permissions, table refresh integration, and `orders` mapping
|
|
305
|
+
- `blockTable/controller.tsx` shows the direct bridge from page block to `ZTable`, including order schema and controlled sorting props
|
|
271
306
|
- the Vona DTO specimen shows the block-based page composition consumed from backend-owned metadata
|
|
272
307
|
|
|
273
|
-
##
|
|
308
|
+
## 10. Representative specimens to read before editing the framework
|
|
274
309
|
|
|
275
310
|
Use this section when you want one small example before reading framework internals.
|
|
276
311
|
|
|
@@ -288,7 +323,7 @@ Use this section when you want one small example before reading framework intern
|
|
|
288
323
|
|
|
289
324
|
Together they give you the public integration, the advanced cell path, and the minimal cell path before you descend into the whole table runtime.
|
|
290
325
|
|
|
291
|
-
##
|
|
326
|
+
## 11. A compact reading strategy
|
|
292
327
|
|
|
293
328
|
When in doubt, use this order:
|
|
294
329
|
|
|
@@ -301,7 +336,7 @@ When in doubt, use this order:
|
|
|
301
336
|
|
|
302
337
|
That order usually gets you to the answer faster than starting from the deepest runtime files first.
|
|
303
338
|
|
|
304
|
-
##
|
|
339
|
+
## 12. Final takeaway
|
|
305
340
|
|
|
306
341
|
The fastest way to read Zova Table accurately is not to memorize every file in `a-table`.
|
|
307
342
|
|
|
@@ -58,13 +58,14 @@ This page is that bridge.
|
|
|
58
58
|
|
|
59
59
|
For a typical Zova table, the shortest accurate model is:
|
|
60
60
|
|
|
61
|
-
1.
|
|
62
|
-
2. the
|
|
63
|
-
3. the controller
|
|
64
|
-
4. the controller
|
|
65
|
-
5.
|
|
66
|
-
6.
|
|
67
|
-
7.
|
|
61
|
+
1. backend schema helpers such as `ZovaRender.column(...)` attach table-column metadata to the field contract
|
|
62
|
+
2. the `ZTable` wrapper creates a table controller bean through the normal Zova controller path
|
|
63
|
+
3. the table controller loads effective table-scene schema properties from the row schema
|
|
64
|
+
4. the controller builds table metadata with visible properties and per-column render functions
|
|
65
|
+
5. the controller creates TanStack table options through Zova’s `$useTable(...)` wrapper
|
|
66
|
+
6. each cell render resolves either to text fallback, a general JSX render target, or a `tableCell` bean
|
|
67
|
+
7. the cell runtime evaluates JSX/CEL props with table-aware column and cell scope
|
|
68
|
+
8. resource pages feed schema, data, permissions, and page scope into the same table runtime through `basic-page:blockTable`
|
|
68
69
|
|
|
69
70
|
That is why Zova Table is not only a thin wrapper around TanStack Table. The business-facing runtime surface is still Zova-native.
|
|
70
71
|
|
|
@@ -98,25 +99,27 @@ These three files already show the core architecture:
|
|
|
98
99
|
|
|
99
100
|
When you want to trace the full mechanism, read these files in order:
|
|
100
101
|
|
|
101
|
-
1. `zova/
|
|
102
|
-
2. `zova/src/suite-vendor/a-zova/modules/a-table/src/component/table
|
|
103
|
-
3. `zova/src/suite-vendor/a-zova/modules/a-table/src/
|
|
104
|
-
4. `zova/src/suite-vendor/a-zova/modules/a-table/src/
|
|
105
|
-
5. `zova/src/suite-vendor/a-zova/modules/a-
|
|
106
|
-
6. `zova/src/suite-vendor/a-zova/modules/a-
|
|
107
|
-
7. `zova/src/suite/
|
|
108
|
-
8. `zova/src/suite/cabloy-basic/modules/basic-page/src/component/
|
|
102
|
+
1. `zova/packages-cli/cli-set-front/cli/templates/rest/rest.ts`
|
|
103
|
+
2. `zova/src/suite-vendor/a-zova/modules/a-table/src/.metadata/component/table.ts`
|
|
104
|
+
3. `zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx`
|
|
105
|
+
4. `zova/src/suite-vendor/a-zova/modules/a-table/src/lib/beanControllerTableBase.ts`
|
|
106
|
+
5. `zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/render.tsx`
|
|
107
|
+
6. `zova/src/suite-vendor/a-zova/modules/a-openapi/src/lib/schema.ts`
|
|
108
|
+
7. `zova/src/suite-vendor/a-zova/modules/a-table/src/types/tableCell.ts`
|
|
109
|
+
8. `zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockTable/controller.tsx`
|
|
110
|
+
9. `zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx`
|
|
109
111
|
|
|
110
112
|
A compact role map is:
|
|
111
113
|
|
|
114
|
+
- `cli/templates/rest/rest.ts` shows that `ZovaRender.column(...)` stores its options under `rest.table`
|
|
112
115
|
- `table.ts` shows how the public wrapper enters `useController(...)`
|
|
113
|
-
- `component/table/controller.tsx` owns schema properties, metadata refresh, TanStack bridge, and cell rendering
|
|
116
|
+
- `component/table/controller.tsx` owns schema properties, metadata refresh, TanStack bridge, pinning, sorting eligibility, and cell rendering
|
|
114
117
|
- `beanControllerTableBase.ts` shows the Zova wrapper around `useVueTable(...)`
|
|
115
|
-
- `component/table/render.tsx` shows the default table DOM render path
|
|
116
|
-
- `schema.ts` shows how table-scene
|
|
118
|
+
- `component/table/render.tsx` shows the default table DOM render path, layout metadata, sortable headers, and `FlexRender`
|
|
119
|
+
- `schema.ts` shows how top-level and table-scene metadata are merged and ordered
|
|
117
120
|
- `types/tableCell.ts` shows the `tableCell` scene contract
|
|
118
|
-
- `blockTable/controller.tsx` shows how page blocks feed
|
|
119
|
-
- `blockPage/controller.tsx` shows where resource data, permissions,
|
|
121
|
+
- `blockTable/controller.tsx` shows how Basic page blocks feed data, schemas, scope, and sorting state into `ZTable`
|
|
122
|
+
- `blockPage/controller.tsx` shows where resource data, permissions, page scope, and backend `orders` mapping come from
|
|
120
123
|
|
|
121
124
|
## Step-by-step runtime path
|
|
122
125
|
|
|
@@ -205,16 +208,19 @@ zova/src/suite-vendor/a-zova/modules/a-openapi/src/lib/schema.ts
|
|
|
205
208
|
|
|
206
209
|
The important runtime path is:
|
|
207
210
|
|
|
208
|
-
1. the
|
|
209
|
-
2.
|
|
210
|
-
3. `
|
|
211
|
-
4. `
|
|
212
|
-
5. `
|
|
211
|
+
1. `ZovaRender.column(options)` stores the field's column options under `rest.table`
|
|
212
|
+
2. the table receives `schema`
|
|
213
|
+
3. `_createProperties()` computes `this.$sdk.loadSchemaProperties(this.schema, 'table')`
|
|
214
|
+
4. `loadSchemaProperties(...)` resolves `$ref`, merges shared `rest` metadata with the `rest.table` overlay, and sorts by effective `rest.order`
|
|
215
|
+
5. `_createTableMeta()` iterates those properties and decides visibility and render behavior
|
|
216
|
+
6. `_createColumnsMiddle()` converts the surviving properties into TanStack column definitions
|
|
217
|
+
|
|
218
|
+
`ZovaRender.column(...)` is a shared Zova API available in both Cabloy Basic and Cabloy Start. It supplies metadata only; it neither registers a frontend column nor selects a cell renderer. `ZovaRender.cell(...)` supplies the render target, and `tableCell` beans implement reusable cell behavior.
|
|
213
219
|
|
|
214
220
|
A practical reading takeaway is:
|
|
215
221
|
|
|
216
222
|
- **schema is not only validation truth**
|
|
217
|
-
- **schema also drives table order, visibility, and cell render metadata**
|
|
223
|
+
- **schema also drives table order, physical-column behavior, visibility, and cell render metadata**
|
|
218
224
|
|
|
219
225
|
## 5. How table metadata is built
|
|
220
226
|
|
|
@@ -257,6 +263,21 @@ A practical reading takeaway is:
|
|
|
257
263
|
- **TanStack owns the row-model mechanics**
|
|
258
264
|
- **the controller still owns which data and columns TanStack sees**
|
|
259
265
|
|
|
266
|
+
### Column metadata becomes TanStack and DOM behavior
|
|
267
|
+
|
|
268
|
+
When `_createColumnsMiddle()` creates each surviving property column, it maps effective table metadata as follows:
|
|
269
|
+
|
|
270
|
+
| Metadata | Controller and render behavior |
|
|
271
|
+
| -------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
272
|
+
| `rest.order` | Orders properties during schema-property loading. |
|
|
273
|
+
| `rest.width` | Becomes the TanStack `size`; render beans apply pixel `width` and `min-width`. |
|
|
274
|
+
| `rest.align` | Remains in column metadata; render beans apply header/cell text alignment. |
|
|
275
|
+
| `rest.fixed` | Builds left/right TanStack pinning arrays; render beans use sticky positions and calculated offsets. |
|
|
276
|
+
| `rest.enableSorting` | Enables sorting only when the field's key or aliases are also present in `schemaOrder`. |
|
|
277
|
+
| `rest.sortDescFirst` | Becomes TanStack's first-toggle direction. |
|
|
278
|
+
|
|
279
|
+
The sorting gate is intentional: metadata can request sorting, but the order schema remains the contract that authorizes the field. The standard resource-page table is controlled and `manualSorting`; it does not locally reorder the fetched data.
|
|
280
|
+
|
|
260
281
|
## 7. Column and cell render context are explicitly separated
|
|
261
282
|
|
|
262
283
|
The controller creates two related but distinct runtime contexts.
|
|
@@ -392,12 +413,12 @@ That contract defines:
|
|
|
392
413
|
The decorator itself is:
|
|
393
414
|
|
|
394
415
|
```typescript
|
|
395
|
-
createBeanDecorator('tableCell', '
|
|
416
|
+
createBeanDecorator('tableCell', 'app', true, options);
|
|
396
417
|
```
|
|
397
418
|
|
|
398
|
-
That means `tableCell` is not only a naming convention. It is
|
|
419
|
+
That means `tableCell` is not only a naming convention. It is an app-scoped frontend bean scene with:
|
|
399
420
|
|
|
400
|
-
-
|
|
421
|
+
- app-scoped reusable bean resolution
|
|
401
422
|
- scene-level typing
|
|
402
423
|
- CLI boilerplate support
|
|
403
424
|
- metadata-driven resource identity
|
|
@@ -437,9 +458,12 @@ The default render bean lives in:
|
|
|
437
458
|
zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/render.tsx
|
|
438
459
|
```
|
|
439
460
|
|
|
440
|
-
It does
|
|
461
|
+
It does more than delegate vnode creation:
|
|
441
462
|
|
|
442
463
|
- render the outer table markup with `<table class="table">`
|
|
464
|
+
- apply effective column alignment, pixel width/minimum width, and fixed-column sticky positioning
|
|
465
|
+
- calculate and apply left/right pinned-column offsets
|
|
466
|
+
- render accessible sortable header buttons, `aria-sort`, and sort-state indicators when the controller exposes a sortable column
|
|
443
467
|
- delegate header and cell vnode creation to TanStack `FlexRender`
|
|
444
468
|
|
|
445
469
|
If `slotDefault` is supplied, the render bean yields to that slot instead of the built-in table DOM.
|
|
@@ -470,7 +494,8 @@ zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockTable/controll
|
|
|
470
494
|
- loads `ModelResource`
|
|
471
495
|
- creates page-level JSX/CEL environment
|
|
472
496
|
- computes resource query state
|
|
473
|
-
- exposes `data`, `schemaRow`, and `permissions`
|
|
497
|
+
- exposes `data`, `schemaRow`, `schemaOrder`, and `permissions`
|
|
498
|
+
- owns controlled table sorting and converts its single current sorting entry into backend `orders`
|
|
474
499
|
- refreshes table metadata when permissions change
|
|
475
500
|
|
|
476
501
|
### Table block path
|
|
@@ -480,6 +505,8 @@ zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockTable/controll
|
|
|
480
505
|
- renders `ZTable`
|
|
481
506
|
- passes `data={$$page.data}`
|
|
482
507
|
- passes `schema={$$page.schemaRow}`
|
|
508
|
+
- passes `schemaOrder={$$page.schemaOrder}`
|
|
509
|
+
- passes controlled `sorting` and `onSortingChange`
|
|
483
510
|
- passes `tableScope={$$page.jsxCelScope}`
|
|
484
511
|
- captures `controllerRef` and stores `tableRef` back onto the page controller
|
|
485
512
|
|
|
@@ -487,18 +514,22 @@ This is one of the most important integration facts about the module.
|
|
|
487
514
|
|
|
488
515
|
The resource page does not manually rebuild the table runtime. It feeds page-owned resource state into the same reusable table controller.
|
|
489
516
|
|
|
517
|
+
This section uses Cabloy Basic `basic-page` paths as the concrete resource-page specimen. The core `ZovaRender.column(...)` metadata contract and the base Zova Table controller behavior are shared by Cabloy Basic and Cabloy Start; resolve Start-specific page modules and renderer keys from the active Start repository.
|
|
518
|
+
|
|
490
519
|
## 14. Compact call-flow sketch
|
|
491
520
|
|
|
492
521
|
When in doubt, use this short call flow:
|
|
493
522
|
|
|
494
|
-
1. `
|
|
495
|
-
2. `
|
|
496
|
-
3. `
|
|
497
|
-
4. `
|
|
498
|
-
5. `
|
|
499
|
-
6.
|
|
500
|
-
7.
|
|
501
|
-
8.
|
|
523
|
+
1. `ZovaRender.column(...)` contributes `rest.table` metadata to the backend/OpenAPI field contract
|
|
524
|
+
2. `ZTable` wrapper enters the normal Zova controller path
|
|
525
|
+
3. `ControllerTable.__init__()` creates CEL/JSX support and schema-driven properties
|
|
526
|
+
4. `refreshMeta()` computes visible table properties, column pinning, and per-column render functions
|
|
527
|
+
5. `_createTable()` creates the TanStack bridge through `$useTable(...)`
|
|
528
|
+
6. `RenderTable` applies column metadata and renders headers and rows through `FlexRender`
|
|
529
|
+
7. each cell render resolves to text fallback, a general render target, or a `tableCell` bean
|
|
530
|
+
8. `tableCell` beans receive controller-prepared options, scope, and `next()`
|
|
531
|
+
9. resource pages prepare `data`, `schemaRow`, `schemaOrder`, sorting state, permissions, and `tableScope` before entering the same runtime
|
|
532
|
+
10. a resource-page sort becomes backend `orders`; TanStack does not locally sort the fetched page
|
|
502
533
|
|
|
503
534
|
That is the shortest end-to-end explanation of how the module cooperates.
|
|
504
535
|
|