cabloy 5.1.59 → 5.1.61
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/hooks/contract-loop-gate.ts +296 -0
- package/.claude/settings.json +16 -0
- package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +1 -0
- package/.claude/skills/cabloy-contract-loop/SKILL.md +103 -14
- package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +126 -12
- package/.claude/skills/cabloy-contract-loop/references/resource-custom-state-pattern.md +148 -0
- package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +49 -13
- package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +11 -0
- package/.claude/skills/cabloy-frontend-scaffold/references/follow-up-checklist.md +2 -0
- package/.claude/skills/cabloy-module-removal/SKILL.md +144 -0
- package/.claude/skills/cabloy-resource-field-update/SKILL.md +274 -0
- package/.claude/skills/cabloy-resource-field-update/evals/evals.json +53 -0
- package/.claude/skills/cabloy-resource-field-update/references/custom-renderer-demo-checklist.md +102 -0
- package/.claude/skills/cabloy-resource-field-update/references/field-update-decision-tree.md +120 -0
- package/.claude/skills/cabloy-resource-field-update/references/follow-up-checklist.md +80 -0
- package/.claude/skills/cabloy-resource-field-update/references/verification-checklist.md +97 -0
- package/.claude/skills/cabloy-zova-source-reading/SKILL.md +221 -0
- package/.claude/skills/cabloy-zova-source-reading/references/analysis-modes.md +91 -0
- package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +117 -0
- package/.github/workflows/docs-pages.yml +2 -0
- package/.github/workflows/vona-cov-pg.yml +2 -0
- package/.github/workflows/vona-test-crud.yml +4 -2
- package/.github/workflows/vona-test-mysql.yml +2 -0
- package/.github/workflows/vona-test-pg.yml +2 -0
- package/.github/workflows/vona-test-sqlite3.yml +2 -0
- package/.github/workflows/vona-tsc.yml +2 -0
- package/.github/workflows/zova-ui.yml +2 -0
- package/.gitignore +0 -4
- package/CHANGELOG.md +52 -0
- package/CLAUDE.md +12 -0
- package/README.md +15 -0
- package/cabloy-docs/.vitepress/config.mjs +89 -0
- package/cabloy-docs/ai/class-placement-rule.md +2 -0
- package/cabloy-docs/ai/cli-to-skill-map.md +14 -0
- package/cabloy-docs/ai/docs-skills-rules-mapping.md +14 -0
- package/cabloy-docs/ai/future-skill-roadmap.md +27 -9
- package/cabloy-docs/ai/introduction.md +1 -0
- package/cabloy-docs/ai/playbook-backend-module.md +6 -0
- package/cabloy-docs/ai/playbook-module-removal.md +164 -0
- package/cabloy-docs/ai/skills.md +11 -0
- package/cabloy-docs/backend/bean-scene-authoring.md +350 -0
- package/cabloy-docs/backend/cli.md +26 -1
- package/cabloy-docs/backend/dto-guide.md +6 -0
- package/cabloy-docs/backend/entity-guide.md +18 -0
- package/cabloy-docs/backend/foundation.md +28 -3
- package/cabloy-docs/backend/introduction.md +10 -0
- package/cabloy-docs/backend/serialization-guide.md +10 -0
- package/cabloy-docs/backend/service-guide.md +2 -0
- package/cabloy-docs/backend/status-guide.md +271 -0
- package/cabloy-docs/backend/websocket-call-flow.md +435 -0
- package/cabloy-docs/backend/websocket-guide.md +455 -0
- package/cabloy-docs/backend/websocket-protocol-guide.md +381 -0
- package/cabloy-docs/backend/websocket-usage-guide.md +356 -0
- package/cabloy-docs/frontend/api-guide.md +2 -0
- package/cabloy-docs/frontend/bean-scene-authoring.md +374 -0
- package/cabloy-docs/frontend/behavior-guide.md +449 -0
- package/cabloy-docs/frontend/cli.md +24 -0
- package/cabloy-docs/frontend/command-scene-authoring.md +495 -0
- package/cabloy-docs/frontend/design-principles.md +6 -0
- package/cabloy-docs/frontend/fetch-interceptor-guide.md +440 -0
- package/cabloy-docs/frontend/form-guide.md +795 -0
- package/cabloy-docs/frontend/foundation.md +29 -0
- package/cabloy-docs/frontend/introduction.md +17 -1
- package/cabloy-docs/frontend/ioc-and-beans.md +16 -9
- package/cabloy-docs/frontend/mock-guide.md +1 -0
- package/cabloy-docs/frontend/model-architecture.md +252 -39
- package/cabloy-docs/frontend/model-resource-best-practices.md +379 -0
- package/cabloy-docs/frontend/model-resource-cookbook.md +505 -0
- package/cabloy-docs/frontend/model-resource-owner-pattern.md +382 -0
- package/cabloy-docs/frontend/model-resource-usage-guide.md +318 -0
- package/cabloy-docs/frontend/model-state-guide.md +366 -13
- package/cabloy-docs/frontend/openapi-sdk-guide.md +5 -2
- package/cabloy-docs/frontend/page-guide.md +6 -0
- package/cabloy-docs/frontend/quickstart.md +4 -0
- package/cabloy-docs/frontend/reading-zova-for-vue-developers.md +266 -0
- package/cabloy-docs/frontend/router-tabs-admin-web-comparison.md +206 -0
- package/cabloy-docs/frontend/router-tabs-introduction.md +106 -0
- package/cabloy-docs/frontend/router-tabs-mechanism.md +469 -0
- package/cabloy-docs/frontend/router-tabs-overview.md +227 -0
- package/cabloy-docs/frontend/router-tabs-route-meta-cookbook.md +343 -0
- package/cabloy-docs/frontend/server-data.md +2 -0
- package/cabloy-docs/frontend/ssr-architecture-overview.md +211 -0
- package/cabloy-docs/frontend/ssr-build-deploy-guide.md +308 -0
- package/cabloy-docs/frontend/ssr-review-checklist.md +184 -0
- package/cabloy-docs/frontend/ssr-troubleshooting-guide.md +301 -0
- package/cabloy-docs/frontend/zova-form-source-reading-map.md +295 -0
- package/cabloy-docs/frontend/zova-form-under-the-hood.md +556 -0
- package/cabloy-docs/frontend/zova-reactivity-under-the-hood.md +320 -0
- package/cabloy-docs/frontend/zova-source-reading-map.md +327 -0
- package/cabloy-docs/frontend/zova-vs-vue3-comparison.md +308 -0
- package/cabloy-docs/fullstack/contract-loop-playbook.md +350 -0
- package/cabloy-docs/fullstack/framework-performance.md +3 -3
- package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +44 -1
- package/cabloy-docs/fullstack/introduction.md +40 -0
- package/cabloy-docs/fullstack/openapi-to-sdk.md +19 -9
- package/cabloy-docs/fullstack/quickstart.md +7 -1
- package/cabloy-docs/fullstack/tutorial-1-first-module.md +111 -0
- package/cabloy-docs/fullstack/tutorial-2-first-crud.md +122 -0
- package/cabloy-docs/fullstack/tutorial-3-frontend-metadata-sharing.md +131 -0
- package/cabloy-docs/fullstack/tutorial-4-custom-level-renderers.md +144 -0
- package/cabloy-docs/fullstack/tutorial-5-backend-contract-sharing.md +146 -0
- package/cabloy-docs/fullstack/tutorial-6-one-contract-four-uses.md +170 -0
- package/cabloy-docs/fullstack/tutorials-overview.md +192 -0
- package/cabloy-docs/index.md +4 -3
- package/cabloy-docs/reference/bean-scene-boilerplates.md +75 -0
- package/cabloy-docs/reference/cli-reference.md +2 -0
- package/package.json +7 -2
- package/scripts/initTestData.ts +25 -0
- package/scripts/upgrade.ts +17 -2
- package/vona/packages-cli/cabloy-cli/package.json +2 -2
- package/vona/packages-cli/cli/package.json +1 -1
- package/vona/packages-cli/cli-set-api/package.json +1 -1
- package/vona/packages-cli/cli-set-api/src/lib/bean/cli.create.module.ts +4 -0
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/pnpm-lock.yaml +226 -1091
- package/vona/pnpm-workspace.yaml +0 -1
- package/vona/src/suite-vendor/a-vona/modules/a-core/assets/static/img/vona.svg +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-upload/package.json +2 -2
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/package.original.json +1 -1
- package/zova/packages-cli/cli/package.json +3 -3
- package/zova/packages-cli/cli-set-front/cli/templates/init/icon/boilerplate/icons/default/zova.svg +1 -1
- package/zova/packages-cli/cli-set-front/cli/templates/openapi/config/boilerplate/module/openapi.config.ts +6 -1
- package/zova/packages-cli/cli-set-front/package.json +3 -3
- package/zova/packages-cli/cli-set-front/src/lib/bean/cli.create.module.ts +4 -0
- package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +34 -4
- package/zova/packages-cli/cli-set-front/src/lib/command/create.bean.ts +5 -1
- package/zova/packages-utils/zova-vite/package.json +2 -2
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +282 -1311
- package/zova/pnpm-workspace.yaml +0 -1
- package/zova/src/suite/a-home/modules/home-icon/icons/social/cabloy.svg +1 -1
- package/zova/src/suite/a-home/modules/home-icon/icons/social/vona.svg +1 -1
- package/zova/src/suite/a-home/modules/home-icon/icons/social/zova.svg +1 -1
- package/zova/src/suite/a-home/modules/home-icon/src/.metadata/icons/groups/social.svg +3 -3
- package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/formFieldSelect/controller.tsx +9 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +66 -16
- package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-routertabs/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts +60 -18
- package/zova/src/suite-vendor/a-zova/modules/a-table/cli/tableActionRow/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
- package/zova/src/suite-vendor/a-zova/modules/a-table/cli/tableCell/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
- package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/package.json +4 -4
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Reading Zova for Vue Developers
|
|
2
|
+
|
|
3
|
+
This guide is for readers who already know Vue 3 and want the shortest accurate path to reading Zova source code without forcing generic Vue assumptions onto it.
|
|
4
|
+
|
|
5
|
+
## Why this page exists
|
|
6
|
+
|
|
7
|
+
When Vue developers first open Zova code, several things can feel unfamiliar at the same time:
|
|
8
|
+
|
|
9
|
+
- page and component logic lives in controller classes
|
|
10
|
+
- plain class fields behave reactively
|
|
11
|
+
- derived state is often wired in `__init__`
|
|
12
|
+
- render logic is written in TSX and can live in a controller or a dedicated render bean
|
|
13
|
+
- state sharing is organized through IoC containers and bean scopes rather than a pile of unrelated patterns
|
|
14
|
+
|
|
15
|
+
If you read Zova as "Vue with unusual syntax," you will miss the architectural point.
|
|
16
|
+
|
|
17
|
+
A better starting point is:
|
|
18
|
+
|
|
19
|
+
- **Vue still provides the reactive foundation**
|
|
20
|
+
- **Zova changes the preferred programming model built on top of that foundation**
|
|
21
|
+
|
|
22
|
+
## The shortest accurate mental model
|
|
23
|
+
|
|
24
|
+
If you only remember one paragraph, remember this one:
|
|
25
|
+
|
|
26
|
+
> Zova keeps Vue 3 reactivity underneath, but moves the main authoring surface from `setup()` locals and explicit `ref/reactive` values toward IoC-managed reactive bean instances such as page controllers, component controllers, service beans, and model beans.
|
|
27
|
+
|
|
28
|
+
That is why Zova code often reads more like controller-oriented application code than like a typical Vue single-file-component or composable-first codebase.
|
|
29
|
+
|
|
30
|
+
## Quick translation table
|
|
31
|
+
|
|
32
|
+
| If you usually think in Vue terms | Read Zova like this instead |
|
|
33
|
+
| --- | --- |
|
|
34
|
+
| `setup()` is the main wiring point | `__init__` and bean lifecycle are major wiring points |
|
|
35
|
+
| `ref` / `reactive` are the visible state hosts | controller and bean instances are the visible state hosts |
|
|
36
|
+
| `computed()` creates local derived refs | `$computed()` usually creates instance-level derived state |
|
|
37
|
+
| `useRoute()` pulls route state into the component | page controllers expose `$route`, `$params`, and `$query` as part of the controller surface |
|
|
38
|
+
| `provide/inject`, composables, props, and stores are separate sharing tools | bean scopes and IoC are used to unify more sharing patterns under one model |
|
|
39
|
+
| template or component render is the obvious center | controller-oriented architecture is the center; render can stay in the controller or move into render beans |
|
|
40
|
+
|
|
41
|
+
## Start from the right assumptions
|
|
42
|
+
|
|
43
|
+
### 1. Do not assume Zova wants to end at `ref.value`
|
|
44
|
+
|
|
45
|
+
Zova intentionally aims for code that feels closer to direct variable usage than `ref/reactive`-heavy business code.
|
|
46
|
+
|
|
47
|
+
That does **not** mean Zova rejects Vue reactivity. It means Zova tries to hide more of the reactive primitive management behind a different framework surface.
|
|
48
|
+
|
|
49
|
+
Read together with:
|
|
50
|
+
|
|
51
|
+
- [Design Principles](/frontend/design-principles)
|
|
52
|
+
- [Foundation](/frontend/foundation)
|
|
53
|
+
|
|
54
|
+
### 2. Do not treat IoC as a small convenience layer
|
|
55
|
+
|
|
56
|
+
In Zova, IoC is not only about injecting a helper or two.
|
|
57
|
+
|
|
58
|
+
It is part of the larger architectural answer for:
|
|
59
|
+
|
|
60
|
+
- state ownership
|
|
61
|
+
- state sharing
|
|
62
|
+
- cross-module composition
|
|
63
|
+
- lifecycle structure
|
|
64
|
+
- extensibility
|
|
65
|
+
|
|
66
|
+
Read together with:
|
|
67
|
+
|
|
68
|
+
- [IoC and Beans](/frontend/ioc-and-beans)
|
|
69
|
+
- [Module Scope](/frontend/module-scope)
|
|
70
|
+
- [Modules and Suites](/frontend/modules-and-suites)
|
|
71
|
+
|
|
72
|
+
### 3. Do not collapse page, component, service, and model code into one generic Vue component mental model
|
|
73
|
+
|
|
74
|
+
Zova gives different bean types different architectural jobs.
|
|
75
|
+
|
|
76
|
+
For example:
|
|
77
|
+
|
|
78
|
+
- page controllers organize page-local state and route-aware behavior
|
|
79
|
+
- component controllers organize reusable UI units
|
|
80
|
+
- service beans can own extracted business state or behavior
|
|
81
|
+
- model beans organize broader state categories such as async, local-storage, cookie, or in-memory data
|
|
82
|
+
|
|
83
|
+
Read together with:
|
|
84
|
+
|
|
85
|
+
- [Page Guide](/frontend/page-guide)
|
|
86
|
+
- [Component Guide](/frontend/component-guide)
|
|
87
|
+
- [Model Architecture](/frontend/model-architecture)
|
|
88
|
+
- [Model State Guide](/frontend/model-state-guide)
|
|
89
|
+
|
|
90
|
+
## A concrete specimen to read first
|
|
91
|
+
|
|
92
|
+
If you want one small example that shows the Zova coding style clearly, start with the demo page controller in the public source tree:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
zova/src/suite/a-demo/modules/demo-basic/src/page/state/controller.tsx
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The important things to notice in that file are:
|
|
99
|
+
|
|
100
|
+
- `count` is a plain class field
|
|
101
|
+
- `count2` is wired in `__init__` through `$computed`
|
|
102
|
+
- actions are plain class methods such as `increment()` and `decrement()`
|
|
103
|
+
- `render()` reads the instance fields directly
|
|
104
|
+
|
|
105
|
+
A Vue-first reader often expects this kind of code to be rewritten into `setup()` plus `ref` plus `computed`. That is exactly the instinct you should suspend while reading Zova.
|
|
106
|
+
|
|
107
|
+
## How to read the reactive path under the surface
|
|
108
|
+
|
|
109
|
+
For the example above, a practical source-reading path is:
|
|
110
|
+
|
|
111
|
+
1. the example controller in `zova/src/suite/a-demo/modules/demo-basic/src/page/state/controller.tsx`
|
|
112
|
+
2. `zova/packages-zova/zova-core/src/composables/useController.ts`
|
|
113
|
+
3. `zova/packages-zova/zova-core/src/bean/beanContainer.ts`
|
|
114
|
+
4. `zova/packages-zova/zova-core/src/bean/beanBase.ts`
|
|
115
|
+
5. `zova/packages-zova/zova-core/src/core/context/component.ts`
|
|
116
|
+
6. `zova/src/suite-vendor/a-zova/modules/a-router/src/monkey.ts`
|
|
117
|
+
|
|
118
|
+
A compact interpretation of those files is:
|
|
119
|
+
|
|
120
|
+
- `useController.ts` creates and loads the controller bean
|
|
121
|
+
- `beanContainer.ts` is where bean instances become reactive and container-managed
|
|
122
|
+
- `beanBase.ts` exposes helpers such as `$computed`, `$watch`, and `$toRef`
|
|
123
|
+
- `component.ts` patches the component render flow so controller-driven render logic participates in normal frontend updates
|
|
124
|
+
- `a-router/src/monkey.ts` pushes page route state onto page controllers
|
|
125
|
+
|
|
126
|
+
This is the main reason Zova can feel so different while still standing on top of Vue runtime behavior.
|
|
127
|
+
|
|
128
|
+
If you want the next layer down, continue with [Zova Reactivity Under the Hood](/frontend/zova-reactivity-under-the-hood).
|
|
129
|
+
|
|
130
|
+
## Six practical differences Vue developers usually feel first
|
|
131
|
+
|
|
132
|
+
### 1. The visible state host is the controller instance
|
|
133
|
+
|
|
134
|
+
A Vue developer often expects to see:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
const count = ref(0);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
A Zova reader will more often see:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
count: number = 0;
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The important idea is not only less syntax. The important idea is that the framework is making the bean instance itself the main business-facing state surface.
|
|
147
|
+
|
|
148
|
+
### 2. Derived state is written as instance wiring
|
|
149
|
+
|
|
150
|
+
Instead of thinking:
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const count2 = computed(() => `=== ${count.value} ===`);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Zova often reads more like:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
protected async __init__() {
|
|
160
|
+
this.count2 = this.$computed(() => {
|
|
161
|
+
return `=== ${this.count} ===`;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
That makes derived state feel like part of object initialization rather than only part of a local `setup()` assembly.
|
|
167
|
+
|
|
168
|
+
### 3. Actions are ordinary methods
|
|
169
|
+
|
|
170
|
+
Instead of scattering behavior through closures returned from `setup()`, Zova often keeps page or component actions as plain methods on the controller instance.
|
|
171
|
+
|
|
172
|
+
That is one reason Zova business code can read more like application controller code.
|
|
173
|
+
|
|
174
|
+
### 4. Route state is part of the page-controller surface
|
|
175
|
+
|
|
176
|
+
A Vue reader often looks for `useRoute()` first.
|
|
177
|
+
|
|
178
|
+
In Zova, a page controller often expects route-aware behavior through members such as:
|
|
179
|
+
|
|
180
|
+
- `$route`
|
|
181
|
+
- `$params`
|
|
182
|
+
- `$query`
|
|
183
|
+
|
|
184
|
+
For the route-oriented mental model, also see [Page Route Guide](/frontend/page-route-guide).
|
|
185
|
+
|
|
186
|
+
### 5. State sharing is more architecture-driven
|
|
187
|
+
|
|
188
|
+
Vue projects often combine several independent techniques:
|
|
189
|
+
|
|
190
|
+
- props and emits
|
|
191
|
+
- composables
|
|
192
|
+
- `provide/inject`
|
|
193
|
+
- store layers
|
|
194
|
+
|
|
195
|
+
Zova tries to keep more of that within the bean and scope architecture, so the first question becomes less "which unrelated mechanism should I use?" and more "which bean owns this state and which scope should that bean live in?"
|
|
196
|
+
|
|
197
|
+
### 6. Render is controller-oriented, not only component-file-oriented
|
|
198
|
+
|
|
199
|
+
A Vue reader might assume that moving code out of a large page means immediately creating more composables or child components.
|
|
200
|
+
|
|
201
|
+
In Zova, a common growth path is:
|
|
202
|
+
|
|
203
|
+
- start with a single page controller
|
|
204
|
+
- split render into a render bean when the page grows
|
|
205
|
+
- split style into a style bean when needed
|
|
206
|
+
- extract business state or logic into service beans when that becomes clearer
|
|
207
|
+
|
|
208
|
+
That growth path is one of the main reasons you should read Zova pages through the page/controller architecture instead of through a generic component-file lens.
|
|
209
|
+
|
|
210
|
+
## A practical reading order for Vue developers
|
|
211
|
+
|
|
212
|
+
If you want the shortest path from Vue familiarity to Zova fluency, use this order:
|
|
213
|
+
|
|
214
|
+
1. [Foundation](/frontend/foundation)
|
|
215
|
+
2. [Design Principles](/frontend/design-principles)
|
|
216
|
+
3. [IoC and Beans](/frontend/ioc-and-beans)
|
|
217
|
+
4. [Page Guide](/frontend/page-guide)
|
|
218
|
+
5. [Component Guide](/frontend/component-guide)
|
|
219
|
+
6. [Model Architecture](/frontend/model-architecture)
|
|
220
|
+
7. [Page Route Guide](/frontend/page-route-guide)
|
|
221
|
+
8. [Behavior Guide](/frontend/behavior-guide)
|
|
222
|
+
|
|
223
|
+
Use this order when:
|
|
224
|
+
|
|
225
|
+
- you already know Vue
|
|
226
|
+
- you want to read Zova source code accurately
|
|
227
|
+
- you want to avoid rewriting framework-specific code back toward generic Vue habits
|
|
228
|
+
|
|
229
|
+
## Common mistakes to avoid
|
|
230
|
+
|
|
231
|
+
### Mistake 1: "This should become a normal Vue SFC"
|
|
232
|
+
|
|
233
|
+
Usually the better question is whether the existing controller, render bean, style bean, or service/model bean boundaries are already the intended Zova architecture.
|
|
234
|
+
|
|
235
|
+
### Mistake 2: "If I do not see `ref`, there is no real reactivity"
|
|
236
|
+
|
|
237
|
+
The reactive foundation is still there. The framework is simply exposing a different authoring surface.
|
|
238
|
+
|
|
239
|
+
### Mistake 3: "IoC only matters for dependency injection"
|
|
240
|
+
|
|
241
|
+
In Zova, IoC is tied to structure, sharing scope, extensibility, and long-term maintainability.
|
|
242
|
+
|
|
243
|
+
### Mistake 4: "Route state should always be pulled locally by composables"
|
|
244
|
+
|
|
245
|
+
For page controllers, route-aware behavior is deliberately pushed into the controller surface so the page model stays cohesive.
|
|
246
|
+
|
|
247
|
+
### Mistake 5: "Model state is just another local store choice"
|
|
248
|
+
|
|
249
|
+
The model layer is one of Zova’s larger architectural answers for unified state categories, SSR-aware state handling, caching, and persistence-oriented behavior.
|
|
250
|
+
|
|
251
|
+
## Edition note
|
|
252
|
+
|
|
253
|
+
This reading guide is about the shared Zova frontend architecture, not about one UI library.
|
|
254
|
+
|
|
255
|
+
That means the architectural reading model applies across Cabloy Basic and Cabloy Start. However, UI-sensitive examples can still diverge:
|
|
256
|
+
|
|
257
|
+
- Cabloy Basic public examples currently align with DaisyUI + Tailwind CSS
|
|
258
|
+
- Cabloy Start aligns with Vuetify-oriented UI workflows and may differ in modules, SSR site baselines, and project assets
|
|
259
|
+
|
|
260
|
+
So when your task becomes UI-specific rather than architecture-specific, detect the active edition before assuming a component or theme workflow.
|
|
261
|
+
|
|
262
|
+
## Final takeaway
|
|
263
|
+
|
|
264
|
+
If Vue teaches you to think in terms of reactive primitives and local composition, Zova asks you to think in terms of reactive framework-managed objects with explicit architectural roles.
|
|
265
|
+
|
|
266
|
+
That is the mental shift that makes the rest of the source tree much easier to read.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Router Tabs Admin and Web Comparison
|
|
2
|
+
|
|
3
|
+
This guide compares how the router-tabs mechanism appears in the Admin and Web layouts in Zova within the Cabloy monorepo.
|
|
4
|
+
|
|
5
|
+
Read this together with:
|
|
6
|
+
|
|
7
|
+
- [Router Tabs Introduction](/frontend/router-tabs-introduction)
|
|
8
|
+
- [Router Tabs Overview](/frontend/router-tabs-overview)
|
|
9
|
+
- [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
|
|
10
|
+
- [Router Tabs Route Meta Cookbook](/frontend/router-tabs-route-meta-cookbook)
|
|
11
|
+
|
|
12
|
+
## Why this comparison matters
|
|
13
|
+
|
|
14
|
+
The current Cabloy Basic frontend source uses one shared router-tabs state model in more than one layout.
|
|
15
|
+
|
|
16
|
+
That means future contributors should not assume that the mechanism is identical to one specific tab-row UI.
|
|
17
|
+
|
|
18
|
+
The shared contract is the workbench-state and route-grouping model. The visible layout expression can vary.
|
|
19
|
+
|
|
20
|
+
## The shared foundation
|
|
21
|
+
|
|
22
|
+
Both layouts reuse the same router-tabs model.
|
|
23
|
+
|
|
24
|
+
They both depend on the same ideas:
|
|
25
|
+
|
|
26
|
+
- `tabKey` as the level-1 workspace grouping identity
|
|
27
|
+
- `componentKey` as the page-instance identity
|
|
28
|
+
- tab activation through router navigation
|
|
29
|
+
- keep-alive integration through the router-tabs controller
|
|
30
|
+
- cache, pruning, and item-state behavior in the shared model
|
|
31
|
+
|
|
32
|
+
Representative shared implementation:
|
|
33
|
+
|
|
34
|
+
- `zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts`
|
|
35
|
+
- `zova/src/suite-vendor/a-zova/modules/a-routertabs/src/component/routerViewTabs/controller.tsx`
|
|
36
|
+
|
|
37
|
+
## The main difference in one sentence
|
|
38
|
+
|
|
39
|
+
The Admin layout shows the workbench model as an explicit two-level tab UI, while the Web layout uses the same underlying state model but presents the top-level workspaces through a horizontal menu-like surface.
|
|
40
|
+
|
|
41
|
+
## Admin layout view
|
|
42
|
+
|
|
43
|
+
Representative sources:
|
|
44
|
+
|
|
45
|
+
- `zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/controller.tsx`
|
|
46
|
+
- `zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.tabs.tsx`
|
|
47
|
+
|
|
48
|
+
### What users see
|
|
49
|
+
|
|
50
|
+
In the Admin layout, users can see the two levels directly:
|
|
51
|
+
|
|
52
|
+
- a first row for workspace-level tabs
|
|
53
|
+
- a second row for task-level items inside the current workspace
|
|
54
|
+
|
|
55
|
+
This is the clearest visual expression of the router-tabs workbench model.
|
|
56
|
+
|
|
57
|
+
### How level-1 behaves
|
|
58
|
+
|
|
59
|
+
In Admin, level-1 tabs are rendered from `RouteTab` records.
|
|
60
|
+
|
|
61
|
+
The visible title and icon are usually derived from menu-backed tab info rather than from the active inner page title.
|
|
62
|
+
|
|
63
|
+
That means the first row behaves like a business workspace selector.
|
|
64
|
+
|
|
65
|
+
### How level-2 behaves
|
|
66
|
+
|
|
67
|
+
In Admin, level-2 items are rendered from `tabCurrent.items`.
|
|
68
|
+
|
|
69
|
+
The second row shows task-level state such as:
|
|
70
|
+
|
|
71
|
+
- page title
|
|
72
|
+
- dirty state
|
|
73
|
+
- create/edit form state
|
|
74
|
+
- close actions for inner work items
|
|
75
|
+
|
|
76
|
+
The Admin layout also deliberately skips the anchor item when rendering the second row. That keeps the second level focused on additional work items rather than on the workspace anchor itself.
|
|
77
|
+
|
|
78
|
+
### When Admin is the best mental model
|
|
79
|
+
|
|
80
|
+
Use the Admin layout as the primary mental model when explaining:
|
|
81
|
+
|
|
82
|
+
- why router tabs are two-level in business meaning
|
|
83
|
+
- how one workspace can hold several work items
|
|
84
|
+
- how page metadata affects task-level presentation
|
|
85
|
+
|
|
86
|
+
## Web layout view
|
|
87
|
+
|
|
88
|
+
Representative sources:
|
|
89
|
+
|
|
90
|
+
- `zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/controller.tsx`
|
|
91
|
+
- `zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.tabs.tsx`
|
|
92
|
+
|
|
93
|
+
### What users see
|
|
94
|
+
|
|
95
|
+
In the Web layout, the same router-tabs model is presented differently.
|
|
96
|
+
|
|
97
|
+
The top-level workspace surface is rendered more like a horizontal menu, with support for folders, leaves, and separators.
|
|
98
|
+
|
|
99
|
+
This means the visual experience is less like an IDE-style double tab bar and more like a menu-driven workspace shell.
|
|
100
|
+
|
|
101
|
+
### How top-level behavior works
|
|
102
|
+
|
|
103
|
+
The Web layout still uses `$$modelTabs.tabs` as the current workspace list.
|
|
104
|
+
|
|
105
|
+
However, instead of rendering a lifted tab row plus a bordered second row, it renders menu items that can:
|
|
106
|
+
|
|
107
|
+
- behave as top-level workspace entries
|
|
108
|
+
- expand folders
|
|
109
|
+
- navigate through menu leaf links
|
|
110
|
+
- highlight the active workspace
|
|
111
|
+
|
|
112
|
+
This is an important reminder that router tabs are not only a cosmetic tab component. They are a route-grouping and workbench-state mechanism that a layout can present in different ways.
|
|
113
|
+
|
|
114
|
+
### How grouping differs visually
|
|
115
|
+
|
|
116
|
+
In the Web layout, the grouping meaning can still be present even when the UI does not emphasize the second level in the same direct way as Admin.
|
|
117
|
+
|
|
118
|
+
That means the mechanism is still doing grouping and workspace-state management, but the visual expression is tuned for a different frontend shell style.
|
|
119
|
+
|
|
120
|
+
### When Web is the better mental model
|
|
121
|
+
|
|
122
|
+
Use the Web layout as the primary mental model when explaining:
|
|
123
|
+
|
|
124
|
+
- that the router-tabs model is reusable beyond one tab-row UI
|
|
125
|
+
- that top-level workspaces can be expressed through a menu-like shell
|
|
126
|
+
- that the framework contract is broader than the Admin visual treatment
|
|
127
|
+
|
|
128
|
+
## Comparison table
|
|
129
|
+
|
|
130
|
+
| Topic | Admin layout | Web layout |
|
|
131
|
+
| ------------------------- | -------------------------------------- | ------------------------------------------------------ |
|
|
132
|
+
| Shared model | router-tabs model | router-tabs model |
|
|
133
|
+
| Top-level presentation | explicit lifted tab row | horizontal menu-like workspace surface |
|
|
134
|
+
| Second-level presentation | explicit bordered task row | not emphasized in the same direct double-row way |
|
|
135
|
+
| Primary user signal | workbench tabs | menu-oriented workspace navigation |
|
|
136
|
+
| Best use as explanation | business meaning of two levels | portability of the shared mechanism |
|
|
137
|
+
| Risk if misread | assuming Admin UI is the only contract | assuming menu presentation means tabs are not involved |
|
|
138
|
+
|
|
139
|
+
## What is shared and should stay shared
|
|
140
|
+
|
|
141
|
+
Future contributors should preserve these shared behaviors across layouts unless there is an intentional framework change:
|
|
142
|
+
|
|
143
|
+
- route-to-workspace mapping
|
|
144
|
+
- `tabKey` and `componentKey` semantics
|
|
145
|
+
- activation through router navigation
|
|
146
|
+
- keep-alive integration
|
|
147
|
+
- cache and pruning behavior in the shared model
|
|
148
|
+
|
|
149
|
+
If one layout needs different visuals, it should change the presentation layer first rather than casually rewriting the shared state semantics.
|
|
150
|
+
|
|
151
|
+
## What may differ safely by layout
|
|
152
|
+
|
|
153
|
+
These areas are more naturally layout-specific:
|
|
154
|
+
|
|
155
|
+
- how top-level workspaces are styled
|
|
156
|
+
- whether the second level is displayed explicitly
|
|
157
|
+
- icon placement and density
|
|
158
|
+
- close-button visibility
|
|
159
|
+
- whether the shell feels tab-centric or menu-centric
|
|
160
|
+
|
|
161
|
+
The key rule is:
|
|
162
|
+
|
|
163
|
+
- layout-specific UI may vary
|
|
164
|
+
- workbench-state semantics should stay intentional
|
|
165
|
+
|
|
166
|
+
## Common mistakes to avoid
|
|
167
|
+
|
|
168
|
+
Avoid these assumptions:
|
|
169
|
+
|
|
170
|
+
### Mistake 1: Admin rendering is the whole contract
|
|
171
|
+
|
|
172
|
+
This can lead contributors to hard-code two-row visual assumptions into framework-level decisions.
|
|
173
|
+
|
|
174
|
+
### Mistake 2: Web rendering means router tabs are not involved
|
|
175
|
+
|
|
176
|
+
This can lead contributors to ignore the shared state model and accidentally break workspace continuity.
|
|
177
|
+
|
|
178
|
+
### Mistake 3: layout differences justify changing `tabKey` or `componentKey` semantics
|
|
179
|
+
|
|
180
|
+
Usually they do not.
|
|
181
|
+
|
|
182
|
+
Those keys belong to the shared routing and state model, not only to one specific layout theme.
|
|
183
|
+
|
|
184
|
+
## Recommended guidance for future docs and implementation work
|
|
185
|
+
|
|
186
|
+
When documenting or extending this area:
|
|
187
|
+
|
|
188
|
+
1. explain the shared mechanism first
|
|
189
|
+
2. use Admin as the clearest business-meaning example
|
|
190
|
+
3. use Web as the proof that the mechanism is presentation-independent
|
|
191
|
+
4. keep route-meta guidance layout-neutral unless a real layout-specific exception exists
|
|
192
|
+
|
|
193
|
+
## Summary
|
|
194
|
+
|
|
195
|
+
The Admin and Web layouts do not represent two different router-tabs mechanisms.
|
|
196
|
+
|
|
197
|
+
They represent two different UI expressions of the same underlying workbench-state model.
|
|
198
|
+
|
|
199
|
+
Admin is the clearest example of explicit two-level tabs. Web is the clearest example that the same grouping and state model can power a different shell style without changing the core semantics.
|
|
200
|
+
|
|
201
|
+
## See also
|
|
202
|
+
|
|
203
|
+
- [Router Tabs Introduction](/frontend/router-tabs-introduction)
|
|
204
|
+
- [Router Tabs Overview](/frontend/router-tabs-overview)
|
|
205
|
+
- [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
|
|
206
|
+
- [Router Tabs Route Meta Cookbook](/frontend/router-tabs-route-meta-cookbook)
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Router Tabs Introduction
|
|
2
|
+
|
|
3
|
+
This guide is the landing page for the router-tabs documentation set in Zova within the Cabloy monorepo.
|
|
4
|
+
|
|
5
|
+
Use it to understand what the router-tabs mechanism is, which questions each companion document answers, and what order to read them in.
|
|
6
|
+
|
|
7
|
+
## What router tabs are
|
|
8
|
+
|
|
9
|
+
Router tabs provide a workbench-style navigation model for frontend layouts that need more than a simple route-transition model.
|
|
10
|
+
|
|
11
|
+
In the current Cabloy Basic source, the mechanism supports:
|
|
12
|
+
|
|
13
|
+
- stable workspace-level grouping
|
|
14
|
+
- task-level page-instance switching inside a workspace
|
|
15
|
+
- keep-alive integration for routed work items
|
|
16
|
+
- optional cache restoration for workbench state
|
|
17
|
+
- more than one layout presentation on top of the same shared model
|
|
18
|
+
|
|
19
|
+
That means router tabs are not only a visual tab bar. They are a route-grouping and workbench-state mechanism.
|
|
20
|
+
|
|
21
|
+
## Start here when you need to answer these questions
|
|
22
|
+
|
|
23
|
+
### What business problem does this solve?
|
|
24
|
+
|
|
25
|
+
Read [Router Tabs Overview](/frontend/router-tabs-overview).
|
|
26
|
+
|
|
27
|
+
This document explains:
|
|
28
|
+
|
|
29
|
+
- why admin-style applications need more than a simple menu transition model
|
|
30
|
+
- why workspace identity and task identity should stay separate
|
|
31
|
+
- how the mechanism supports parallel work and workbench continuity
|
|
32
|
+
|
|
33
|
+
### How does the mechanism work in code?
|
|
34
|
+
|
|
35
|
+
Read [Router Tabs Mechanism](/frontend/router-tabs-mechanism).
|
|
36
|
+
|
|
37
|
+
This document explains:
|
|
38
|
+
|
|
39
|
+
- the shared state model
|
|
40
|
+
- `tabKey` and `componentKey`
|
|
41
|
+
- page metadata, keep-alive, cache, and pruning behavior
|
|
42
|
+
- the relationship between the shared model and concrete layouts
|
|
43
|
+
|
|
44
|
+
### How should I author route meta for this?
|
|
45
|
+
|
|
46
|
+
Read [Router Tabs Route Meta Cookbook](/frontend/router-tabs-route-meta-cookbook).
|
|
47
|
+
|
|
48
|
+
This document explains:
|
|
49
|
+
|
|
50
|
+
- practical recipes for `tabKey`
|
|
51
|
+
- when to use `componentKeyMode`
|
|
52
|
+
- when to define explicit `componentKey`
|
|
53
|
+
- when to disable keep-alive
|
|
54
|
+
- common authoring mistakes to avoid
|
|
55
|
+
|
|
56
|
+
### How do Admin and Web layouts differ?
|
|
57
|
+
|
|
58
|
+
Read [Router Tabs Admin and Web Comparison](/frontend/router-tabs-admin-web-comparison).
|
|
59
|
+
|
|
60
|
+
This document explains:
|
|
61
|
+
|
|
62
|
+
- what both layouts share
|
|
63
|
+
- how Admin exposes the two-level model directly
|
|
64
|
+
- how Web reuses the same model with a different shell style
|
|
65
|
+
- why layout-specific UI should not be confused with shared mechanism semantics
|
|
66
|
+
|
|
67
|
+
## Recommended reading paths
|
|
68
|
+
|
|
69
|
+
### Product or architecture perspective
|
|
70
|
+
|
|
71
|
+
Recommended order:
|
|
72
|
+
|
|
73
|
+
1. [Router Tabs Overview](/frontend/router-tabs-overview)
|
|
74
|
+
2. [Router Tabs Admin and Web Comparison](/frontend/router-tabs-admin-web-comparison)
|
|
75
|
+
3. [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
|
|
76
|
+
|
|
77
|
+
### Frontend implementation perspective
|
|
78
|
+
|
|
79
|
+
Recommended order:
|
|
80
|
+
|
|
81
|
+
1. [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
|
|
82
|
+
2. [Router Tabs Route Meta Cookbook](/frontend/router-tabs-route-meta-cookbook)
|
|
83
|
+
3. [Router Tabs Admin and Web Comparison](/frontend/router-tabs-admin-web-comparison)
|
|
84
|
+
|
|
85
|
+
### Maintenance and refactor perspective
|
|
86
|
+
|
|
87
|
+
Recommended order:
|
|
88
|
+
|
|
89
|
+
1. [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
|
|
90
|
+
2. [Router Tabs Admin and Web Comparison](/frontend/router-tabs-admin-web-comparison)
|
|
91
|
+
3. `.docs-internal/architecture/router-tabs-design-boundaries.md`
|
|
92
|
+
|
|
93
|
+
## Scope boundary
|
|
94
|
+
|
|
95
|
+
The public router-tabs docs explain the shared frontend mechanism and how to use it.
|
|
96
|
+
|
|
97
|
+
For internal design boundaries, maintenance invariants, and refactor safety rules, see:
|
|
98
|
+
|
|
99
|
+
- `.docs-internal/architecture/router-tabs-design-boundaries.md`
|
|
100
|
+
|
|
101
|
+
## See also
|
|
102
|
+
|
|
103
|
+
- [Router Tabs Overview](/frontend/router-tabs-overview)
|
|
104
|
+
- [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
|
|
105
|
+
- [Router Tabs Route Meta Cookbook](/frontend/router-tabs-route-meta-cookbook)
|
|
106
|
+
- [Router Tabs Admin and Web Comparison](/frontend/router-tabs-admin-web-comparison)
|