@jskit-ai/agent-docs 0.1.130 → 0.1.132
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/guide/agent/app-extras/assistant.md +29 -605
- package/guide/agent/app-extras/mobile-capacitor.md +29 -362
- package/guide/agent/app-extras/realtime.md +29 -277
- package/guide/agent/app-setup/a-more-interesting-shell.md +44 -815
- package/guide/agent/app-setup/authentication.md +43 -1073
- package/guide/agent/app-setup/console.md +26 -298
- package/guide/agent/app-setup/database-layer.md +110 -790
- package/guide/agent/app-setup/initial-scaffolding.md +50 -784
- package/guide/agent/app-setup/multi-homing.md +39 -712
- package/guide/agent/app-setup/quickstart.md +43 -179
- package/guide/agent/app-setup/users.md +34 -353
- package/guide/agent/index.md +16 -23
- package/package.json +2 -2
- package/patterns/INDEX.md +7 -7
- package/patterns/child-cruds.md +3 -3
- package/patterns/client-requests.md +6 -6
- package/patterns/crud-authoring.md +94 -0
- package/patterns/crud-links.md +1 -1
- package/patterns/feature-package/PATTERN.md +108 -0
- package/patterns/feature-package/example/booking-engine/package.json +48 -0
- package/patterns/feature-package/example/booking-engine/src/server/BookingEngineProvider.js +33 -0
- package/patterns/feature-package/example/booking-engine/src/server/actions.js +26 -0
- package/patterns/feature-package/example/booking-engine/src/server/inputSchemas.js +19 -0
- package/patterns/feature-package/example/variations/AvailabilityEngineProvider.js +31 -0
- package/patterns/feature-package/example/variations/InvoiceRollupProvider.js +36 -0
- package/patterns/feature-package/example/variations/customKnexRepository.js +34 -0
- package/patterns/feature-package/example/variations/orchestratorService.js +23 -0
- package/patterns/filters.md +8 -8
- package/patterns/live-actions.md +5 -18
- package/patterns/minimal-foundation/PATTERN.md +98 -0
- package/patterns/minimal-foundation/example/.nvmrc +1 -0
- package/patterns/minimal-foundation/example/AGENTS.md +17 -0
- package/patterns/minimal-foundation/example/Procfile +2 -0
- package/patterns/minimal-foundation/example/app.json +14 -0
- package/patterns/minimal-foundation/example/bin/develop.js +71 -0
- package/patterns/minimal-foundation/example/bin/server.js +8 -0
- package/patterns/minimal-foundation/example/config/public.js +40 -0
- package/patterns/minimal-foundation/example/config/server.js +1 -0
- package/patterns/minimal-foundation/example/config/surfaceAccessPolicies.js +3 -0
- package/patterns/minimal-foundation/example/eslint.config.mjs +19 -0
- package/patterns/minimal-foundation/example/favicon.svg +7 -0
- package/patterns/minimal-foundation/example/gitignore +9 -0
- package/patterns/minimal-foundation/example/index.html +13 -0
- package/patterns/minimal-foundation/example/jsconfig.json +8 -0
- package/patterns/minimal-foundation/example/package.json +57 -0
- package/patterns/minimal-foundation/example/packages/main/package.json +42 -0
- package/patterns/minimal-foundation/example/packages/main/src/shared/index.js +10 -0
- package/patterns/minimal-foundation/example/packages/main/src/shared/schemas/index.js +22 -0
- package/patterns/minimal-foundation/example/playwright.config.mjs +31 -0
- package/patterns/minimal-foundation/example/server/lib/runtimeEnv.js +45 -0
- package/patterns/minimal-foundation/example/server/lib/surfaceRuntime.js +10 -0
- package/patterns/minimal-foundation/example/server.js +195 -0
- package/patterns/minimal-foundation/example/src/App.vue +13 -0
- package/patterns/minimal-foundation/example/src/main.js +85 -0
- package/patterns/minimal-foundation/example/src/pages/home/index.vue +48 -0
- package/patterns/minimal-foundation/example/src/pages/home.vue +13 -0
- package/patterns/minimal-foundation/example/src/views/NotFound.vue +13 -0
- package/patterns/minimal-foundation/example/tests/client/smoke.vitest.js +7 -0
- package/patterns/minimal-foundation/example/tests/e2e/base-shell.spec.ts +23 -0
- package/patterns/minimal-foundation/example/tests/server/smoke.test.js +16 -0
- package/patterns/minimal-foundation/example/vite.config.mjs +81 -0
- package/patterns/page-scaffolding.md +20 -17
- package/patterns/placements.md +17 -15
- package/patterns/row-policies.md +4 -5
- package/patterns/server-search.md +3 -3
- package/patterns/shell-foundation/PATTERN.md +104 -0
- package/patterns/shell-foundation/example/.nvmrc +1 -0
- package/patterns/shell-foundation/example/AGENTS.md +17 -0
- package/patterns/shell-foundation/example/Procfile +2 -0
- package/patterns/shell-foundation/example/app.json +14 -0
- package/patterns/shell-foundation/example/bin/develop.js +71 -0
- package/patterns/shell-foundation/example/bin/server.js +8 -0
- package/patterns/shell-foundation/example/config/public.js +40 -0
- package/patterns/shell-foundation/example/config/server.js +1 -0
- package/patterns/shell-foundation/example/config/surfaceAccessPolicies.js +3 -0
- package/patterns/shell-foundation/example/eslint.config.mjs +19 -0
- package/patterns/shell-foundation/example/favicon.svg +7 -0
- package/patterns/shell-foundation/example/gitignore +9 -0
- package/patterns/shell-foundation/example/index.html +13 -0
- package/patterns/shell-foundation/example/jsconfig.json +8 -0
- package/patterns/shell-foundation/example/package.json +59 -0
- package/patterns/shell-foundation/example/packages/main/package.json +56 -0
- package/patterns/shell-foundation/example/packages/main/src/client/index.js +9 -0
- package/patterns/shell-foundation/example/packages/main/src/client/providers/MainClientProvider.js +18 -0
- package/patterns/shell-foundation/example/packages/main/src/shared/index.js +10 -0
- package/patterns/shell-foundation/example/packages/main/src/shared/schemas/index.js +22 -0
- package/patterns/shell-foundation/example/playwright.config.mjs +31 -0
- package/patterns/shell-foundation/example/server/lib/runtimeEnv.js +45 -0
- package/patterns/shell-foundation/example/server/lib/surfaceRuntime.js +10 -0
- package/patterns/shell-foundation/example/server.js +195 -0
- package/patterns/shell-foundation/example/src/App.vue +11 -0
- package/patterns/shell-foundation/example/src/components/ShellLayout.vue +12 -0
- package/patterns/shell-foundation/example/src/components/menus/MenuLinkItem.vue +30 -0
- package/patterns/shell-foundation/example/src/components/menus/SurfaceAwareMenuLinkItem.vue +42 -0
- package/patterns/shell-foundation/example/src/components/menus/TabLinkItem.vue +42 -0
- package/patterns/shell-foundation/example/src/error.js +19 -0
- package/patterns/shell-foundation/example/src/main.js +85 -0
- package/patterns/shell-foundation/example/src/pages/home/index.vue +116 -0
- package/patterns/shell-foundation/example/src/pages/home/settings/general/index.vue +40 -0
- package/patterns/shell-foundation/example/src/pages/home/settings/index.vue +7 -0
- package/patterns/shell-foundation/example/src/pages/home/settings.vue +109 -0
- package/patterns/shell-foundation/example/src/pages/home.vue +20 -0
- package/patterns/shell-foundation/example/src/placement.js +56 -0
- package/patterns/shell-foundation/example/src/placementTopology.js +149 -0
- package/patterns/shell-foundation/example/src/views/NotFound.vue +13 -0
- package/patterns/shell-foundation/example/tests/client/smoke.vitest.js +7 -0
- package/patterns/shell-foundation/example/tests/e2e/adaptive-shell.spec.ts +10 -0
- package/patterns/shell-foundation/example/tests/e2e/base-shell.spec.ts +23 -0
- package/patterns/shell-foundation/example/tests/server/smoke.test.js +16 -0
- package/patterns/shell-foundation/example/vite.config.mjs +81 -0
- package/patterns/ui-contract.md +56 -0
- package/patterns/ui-testing.md +10 -12
- package/reference/autogen/KERNEL_MAP.md +29 -107
- package/reference/autogen/PATTERN_INDEX.md +230 -0
- package/reference/autogen/README.md +4 -8
- package/reference/autogen/packages/agent-docs.md +259 -0
- package/reference/autogen/packages/assistant-core.md +3 -3
- package/reference/autogen/packages/assistant-runtime.md +32 -17
- package/reference/autogen/packages/auth-core.md +31 -33
- package/reference/autogen/packages/auth-provider-local-core.md +4 -12
- package/reference/autogen/packages/auth-provider-local-db-core.md +4 -4
- package/reference/autogen/packages/auth-provider-supabase-core.md +14 -18
- package/reference/autogen/packages/auth-web.md +42 -22
- package/reference/autogen/packages/console-core.md +8 -25
- package/reference/autogen/packages/console-web.md +5 -5
- package/reference/autogen/packages/crud-core.md +61 -17
- package/reference/autogen/packages/database-runtime-mysql.md +12 -2
- package/reference/autogen/packages/database-runtime-postgres.md +12 -2
- package/reference/autogen/packages/database-runtime.md +26 -25
- package/reference/autogen/packages/google-rewarded-core.md +19 -104
- package/reference/autogen/packages/http-runtime.md +4 -8
- package/reference/autogen/packages/http-web.md +32 -0
- package/reference/autogen/packages/json-rest-api-core.md +4 -6
- package/reference/autogen/packages/kernel.md +109 -390
- package/reference/autogen/packages/mobile-capacitor.md +2 -13
- package/reference/autogen/packages/realtime.md +29 -26
- package/reference/autogen/packages/resource-crud-core.md +6 -0
- package/reference/autogen/packages/shell-web.md +69 -54
- package/reference/autogen/packages/storage-runtime.md +3 -3
- package/reference/autogen/packages/uploads-image-web.md +0 -1
- package/reference/autogen/packages/uploads-runtime.md +3 -3
- package/reference/autogen/packages/users-core.md +45 -90
- package/reference/autogen/packages/users-web.md +5 -7
- package/reference/autogen/packages/workspaces-core.md +53 -74
- package/reference/autogen/packages/workspaces-web.md +15 -16
- package/reference/autogen/tooling/jskit-catalog.md +34 -0
- package/reference/autogen/tooling/testUtils.md +4 -4
- package/skills/jskit/SKILL.md +36 -28
- package/skills/jskit/agents/openai.yaml +2 -2
- package/skills/jskit/references/app-operations.md +68 -53
- package/skills/jskit/references/crud-operations.md +58 -106
- package/skills/jskit/references/material-3.md +105 -0
- package/skills/jskit/references/ui-operations.md +41 -44
- package/templates/app/AGENTS.md +7 -3
- package/guide/agent/app-setup/upgrade-beta-1-to-final.md +0 -252
- package/guide/agent/app-setup/working-with-the-jskit-cli.md +0 -325
- package/guide/agent/generators/advanced-cruds.md +0 -1935
- package/guide/agent/generators/crud-generators.md +0 -948
- package/guide/agent/generators/intro.md +0 -65
- package/guide/agent/generators/row-policies.md +0 -537
- package/guide/agent/generators/ui-generators.md +0 -690
- package/patterns/crud-scaffolding.md +0 -198
- package/patterns/generated-ui-contract-tracking.md +0 -66
- package/reference/autogen/packages/assistant.md +0 -68
- package/reference/autogen/packages/crud-server-generator.md +0 -215
- package/reference/autogen/packages/crud-ui-generator.md +0 -192
- package/reference/autogen/packages/feature-server-generator.md +0 -65
- package/reference/autogen/packages/ui-generator.md +0 -127
- package/reference/autogen/tooling/create-app.md +0 -317
- package/reference/autogen/tooling/jskit-cli.md +0 -933
- package/reference/autogen/tooling/test-support.md +0 -27
|
@@ -1,690 +0,0 @@
|
|
|
1
|
-
<!-- Generated by `npm run agent-docs:build` from `packages/agent-docs/site/guide/generators/ui-generators.md`. Do not edit manually. -->
|
|
2
|
-
|
|
3
|
-
# UI Generators
|
|
4
|
-
|
|
5
|
-
The earlier chapters already used `ui-generator` a little when we added:
|
|
6
|
-
|
|
7
|
-
- the `Alerts Widget`
|
|
8
|
-
- the `Profile` settings page
|
|
9
|
-
- the `Notifications` settings page
|
|
10
|
-
|
|
11
|
-
This chapter steps back and treats that tool as a subject in its own right.
|
|
12
|
-
|
|
13
|
-
Use `ui-generator` when you want app-owned UI that is **not** a CRUD route tree.
|
|
14
|
-
|
|
15
|
-
That usually means one of four jobs:
|
|
16
|
-
|
|
17
|
-
- create a route page
|
|
18
|
-
- create a small placed UI element
|
|
19
|
-
- turn an existing page into a host for child routes
|
|
20
|
-
- add a generic placement seam to an existing Vue file
|
|
21
|
-
|
|
22
|
-
## `ui-generator` `@jskit-ai/ui-generator` `(0.1.22)`
|
|
23
|
-
|
|
24
|
-
`ui-generator` has four subcommands:
|
|
25
|
-
|
|
26
|
-
- `page`
|
|
27
|
-
- `placed-element`
|
|
28
|
-
- `add-subpages`
|
|
29
|
-
- `outlet`
|
|
30
|
-
|
|
31
|
-
They are all about app-owned UI, but they solve different problems.
|
|
32
|
-
|
|
33
|
-
The easiest way to understand them is:
|
|
34
|
-
|
|
35
|
-
- `page` creates a route and the link that reaches it
|
|
36
|
-
- `placed-element` creates a reusable component and places it somewhere
|
|
37
|
-
- `add-subpages` upgrades a page into a routed child-page host
|
|
38
|
-
- `outlet` adds only a placement seam, without routed child-page behavior
|
|
39
|
-
|
|
40
|
-
## The simplest case: `page`
|
|
41
|
-
|
|
42
|
-
Start with the most common command:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
npx jskit generate ui-generator page \
|
|
46
|
-
home/reports/index.vue \
|
|
47
|
-
--name "Reports"
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
This command creates a page at:
|
|
51
|
-
|
|
52
|
-
```text
|
|
53
|
-
src/pages/home/reports/index.vue
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
and it also appends a matching link placement into:
|
|
57
|
-
|
|
58
|
-
```text
|
|
59
|
-
src/placement.js
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
That second part is important. `page` is not just a file generator. It also makes the new page reachable inside the shell.
|
|
63
|
-
|
|
64
|
-
In a fresh `home` surface app, the generated placement looks like a normal shell menu link. In the throwaway app used to verify this chapter, the command reported:
|
|
65
|
-
|
|
66
|
-
```text
|
|
67
|
-
Generated UI page "/reports" at src/pages/home/reports/index.vue.
|
|
68
|
-
Touched files (2):
|
|
69
|
-
- src/pages/home/reports/index.vue
|
|
70
|
-
- src/placement.js
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
That is the baseline behavior of `page`:
|
|
74
|
-
|
|
75
|
-
- one app-owned page file
|
|
76
|
-
- one app-owned placement entry
|
|
77
|
-
|
|
78
|
-
The important default is this:
|
|
79
|
-
|
|
80
|
-
- if JSKIT sees no nearer routed host, the new page gets a normal shell/menu placement
|
|
81
|
-
- if JSKIT does see a nearer routed host, the new page gets linked into that host instead
|
|
82
|
-
|
|
83
|
-
Open the app to see a real `/reports` page plus a real shell link for it.
|
|
84
|
-
|
|
85
|
-
### Customizing the generated menu link
|
|
86
|
-
|
|
87
|
-
The generated page command does not ask for an icon up front. That is deliberate. The command's job is to create the route and the matching placement entry, not to force every menu detail during generation.
|
|
88
|
-
|
|
89
|
-
If you want to customize the link afterwards, edit the placement entry that `page` wrote into `src/placement.js`.
|
|
90
|
-
|
|
91
|
-
That is where things such as:
|
|
92
|
-
|
|
93
|
-
- `label`
|
|
94
|
-
- `order`
|
|
95
|
-
- `icon`
|
|
96
|
-
- `owner`
|
|
97
|
-
- `surfaces`
|
|
98
|
-
|
|
99
|
-
normally get adjusted.
|
|
100
|
-
|
|
101
|
-
The important icon rule is this:
|
|
102
|
-
|
|
103
|
-
- inside `src/placement.js` menu metadata, import app-specific icons from `@mdi/js` and pass the path constant
|
|
104
|
-
- only use raw `mdi-*` strings for the small set of shell-web core icons that JSKIT normalizes
|
|
105
|
-
- inside normal Vue component props, use the same `@mdi/js` path constants or a Vuetify alias
|
|
106
|
-
|
|
107
|
-
So this is a valid menu-placement customization:
|
|
108
|
-
|
|
109
|
-
```js
|
|
110
|
-
import { mdiChartBoxOutline } from "@mdi/js";
|
|
111
|
-
|
|
112
|
-
props: {
|
|
113
|
-
label: "Reports",
|
|
114
|
-
to: "/reports",
|
|
115
|
-
icon: mdiChartBoxOutline
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
If you later open the generated page file itself and add a Vuetify icon to the template, use the same `@mdi/js` pattern:
|
|
120
|
-
|
|
121
|
-
```vue
|
|
122
|
-
<script setup>
|
|
123
|
-
import { mdiChartBoxOutline } from "@mdi/js";
|
|
124
|
-
</script>
|
|
125
|
-
|
|
126
|
-
<v-icon :icon="mdiChartBoxOutline" />
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
This keeps icon imports local and tree-shakeable. Do not import the whole `@mdi/js` namespace just to look up icon names dynamically.
|
|
130
|
-
|
|
131
|
-
## What `page` is really good at
|
|
132
|
-
|
|
133
|
-
The reason `page` is the primary subcommand is that it understands more than just "create this file".
|
|
134
|
-
|
|
135
|
-
It also understands shell topology.
|
|
136
|
-
|
|
137
|
-
If you create a page that lives under a parent page which has already been upgraded into a child-page host, `page` does **not** keep treating it as a top-level shell entry. It changes behavior and links the new page into the nearest host instead.
|
|
138
|
-
|
|
139
|
-
That is what makes it fit naturally with the rest of JSKIT.
|
|
140
|
-
|
|
141
|
-
### The important `page` overrides
|
|
142
|
-
|
|
143
|
-
The happy path is intentionally simple, but `page` also has a small set of override options that matter as soon as you stop accepting the defaults.
|
|
144
|
-
|
|
145
|
-
#### `--link-placement`
|
|
146
|
-
|
|
147
|
-
Use this when the generated page link should go somewhere other than the generator's inferred default.
|
|
148
|
-
|
|
149
|
-
Typical reasons:
|
|
150
|
-
|
|
151
|
-
- you want the page in a different shell menu
|
|
152
|
-
- you want the page link inside a specific existing semantic placement
|
|
153
|
-
- you do not want the link to land in the normal top-level menu
|
|
154
|
-
|
|
155
|
-
For example, if a page should appear in a settings menu rather than the shell drawer, `--link-placement` is the override that says so.
|
|
156
|
-
|
|
157
|
-
The value should normally be semantic, such as `shell.primary-nav`, `page.section-nav`, or another `area.slot` placement from `jskit list-placements`. Concrete `host:position` outlets remain an escape hatch, not the default authoring path.
|
|
158
|
-
|
|
159
|
-
#### `--link-to`
|
|
160
|
-
|
|
161
|
-
Use this when you want to override the generated `props.to` value.
|
|
162
|
-
|
|
163
|
-
This is especially useful for nested pages, because when JSKIT detects a parent subpages host it normally infers a relative link like:
|
|
164
|
-
|
|
165
|
-
```js
|
|
166
|
-
to: "./exports"
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
That default is usually correct. But if the host needs a different local target shape, or you are wiring a link into a custom outlet with different expectations, `--link-to` is the escape hatch.
|
|
170
|
-
|
|
171
|
-
So the rough rule is:
|
|
172
|
-
|
|
173
|
-
- if the link destination is obvious from the route tree, let JSKIT infer it
|
|
174
|
-
- if you need a very specific link destination, use `--link-to`
|
|
175
|
-
|
|
176
|
-
#### `--force`
|
|
177
|
-
|
|
178
|
-
Use this only when the target page file already exists and you intentionally want to overwrite it.
|
|
179
|
-
|
|
180
|
-
That is most common when:
|
|
181
|
-
|
|
182
|
-
- you are regenerating an experimental page
|
|
183
|
-
- you want to throw away the current file and replace it with fresh scaffold
|
|
184
|
-
|
|
185
|
-
It is not a routing option. It is simply an overwrite guard.
|
|
186
|
-
|
|
187
|
-
## Turning a page into a child-page host: `add-subpages`
|
|
188
|
-
|
|
189
|
-
Suppose `Reports` should stop being a single screen and start becoming a section with child routes under it.
|
|
190
|
-
|
|
191
|
-
Run:
|
|
192
|
-
|
|
193
|
-
```bash
|
|
194
|
-
npx jskit generate ui-generator add-subpages \
|
|
195
|
-
home/reports/index.vue \
|
|
196
|
-
--title "Reports" \
|
|
197
|
-
--subtitle "View and manage reporting modules."
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
This upgrades `src/pages/home/reports/index.vue` into a routed host page.
|
|
201
|
-
|
|
202
|
-
On the first use in a fresh app, it also installs the support shell component:
|
|
203
|
-
|
|
204
|
-
```text
|
|
205
|
-
src/components/SectionContainerShell.vue
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
In the verified throwaway app, the command reported:
|
|
209
|
-
|
|
210
|
-
```text
|
|
211
|
-
Enabled subpages in src/pages/home/reports/index.vue for "/reports" using outlet target "reports:sub-pages".
|
|
212
|
-
Touched files (2):
|
|
213
|
-
- src/components/SectionContainerShell.vue
|
|
214
|
-
- src/pages/home/reports/index.vue
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
After the command, the page gains three important pieces:
|
|
218
|
-
|
|
219
|
-
- `SectionContainerShell`
|
|
220
|
-
- a `ShellOutlet` for the child-page tabs
|
|
221
|
-
- `RouterView`
|
|
222
|
-
|
|
223
|
-
That lets the page keep rendering shared content while child routes render underneath it.
|
|
224
|
-
|
|
225
|
-
This is the first big distinction in this chapter:
|
|
226
|
-
|
|
227
|
-
- a plain page is just a page
|
|
228
|
-
- a subpages host is a page plus routed child-page structure
|
|
229
|
-
|
|
230
|
-
If what you need is routed children, `add-subpages` is the right tool.
|
|
231
|
-
|
|
232
|
-
### When `page` becomes a tab-like child instead of a top-level menu entry
|
|
233
|
-
|
|
234
|
-
This is the key transition to understand.
|
|
235
|
-
|
|
236
|
-
Before `add-subpages`, `page` usually creates:
|
|
237
|
-
|
|
238
|
-
- a page file
|
|
239
|
-
- a top-level shell link
|
|
240
|
-
|
|
241
|
-
After `add-subpages`, that same `page` command may create:
|
|
242
|
-
|
|
243
|
-
- a page file
|
|
244
|
-
- a child link inside the nearest parent host outlet
|
|
245
|
-
|
|
246
|
-
That is why nested pages often feel "tab-like" even though the generator command is still just `page`.
|
|
247
|
-
|
|
248
|
-
The route page is still a normal page file. What changes is the inferred placement target:
|
|
249
|
-
|
|
250
|
-
- no parent host found -> shell/menu entry
|
|
251
|
-
- nearest parent host found -> child link inside that host
|
|
252
|
-
|
|
253
|
-
So JSKIT is not switching to a different generator. The route tree has a routed host above the new page, so the inferred placement behavior follows that host.
|
|
254
|
-
|
|
255
|
-
### Making a child page the default landing route
|
|
256
|
-
|
|
257
|
-
This is important enough to state explicitly: if a routed host has child pages, and you want the bare parent URL to open one child immediately, use an explicit redirect.
|
|
258
|
-
|
|
259
|
-
Do **not** try to make the app "guess the first tab". Do **not** infer it from placement order. Keep the target explicit.
|
|
260
|
-
|
|
261
|
-
The standard pattern is:
|
|
262
|
-
|
|
263
|
-
```vue
|
|
264
|
-
<script setup>
|
|
265
|
-
import { redirectToChild } from "@jskit-ai/kernel/client/pageRedirects";
|
|
266
|
-
|
|
267
|
-
definePage({
|
|
268
|
-
redirect: redirectToChild("exports")
|
|
269
|
-
});
|
|
270
|
-
</script>
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
If this is placed on the host page, opening `/reports` lands on `/reports/exports`.
|
|
274
|
-
|
|
275
|
-
This is also the right pattern when the host page still renders shared content such as a title, tabs, summary panel, or `RouterView`. The parent route remains the host, and the child page simply becomes the default destination under it.
|
|
276
|
-
|
|
277
|
-
Why this is the recommended pattern:
|
|
278
|
-
|
|
279
|
-
- the destination is explicit and stable
|
|
280
|
-
- it survives later placement reordering
|
|
281
|
-
- it does not depend on which child link happens to render first
|
|
282
|
-
- it is easy to change later by editing one child segment
|
|
283
|
-
|
|
284
|
-
This is one of the most common things people want once they start using child-page hosts. Treat it as normal JSKIT routing, not a special hack.
|
|
285
|
-
|
|
286
|
-
## Nested pages under an `index.vue` host
|
|
287
|
-
|
|
288
|
-
Once `Reports` is a host, create a child page under it:
|
|
289
|
-
|
|
290
|
-
```bash
|
|
291
|
-
npx jskit generate ui-generator page \
|
|
292
|
-
home/reports/index/exports/index.vue \
|
|
293
|
-
--name "Exports"
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
This path shape matters.
|
|
297
|
-
|
|
298
|
-
Because the parent host is:
|
|
299
|
-
|
|
300
|
-
```text
|
|
301
|
-
src/pages/home/reports/index.vue
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
the child belongs under:
|
|
305
|
-
|
|
306
|
-
```text
|
|
307
|
-
src/pages/home/reports/index/exports/index.vue
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
That `index/...` folder segment is not an odd JSKIT convention. It is the real nesting rule for children of an `index.vue` route host.
|
|
311
|
-
|
|
312
|
-
And this is where `page` becomes interesting again.
|
|
313
|
-
|
|
314
|
-
In the throwaway app, the command reported:
|
|
315
|
-
|
|
316
|
-
```text
|
|
317
|
-
Generated UI page "/reports/exports" at src/pages/home/reports/index/exports/index.vue.
|
|
318
|
-
Touched files (2):
|
|
319
|
-
- src/pages/home/reports/index/exports/index.vue
|
|
320
|
-
- src/placement.js
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
But the placement it wrote was **not** another top-level shell link.
|
|
324
|
-
|
|
325
|
-
Instead, it targeted the host outlet:
|
|
326
|
-
|
|
327
|
-
```text
|
|
328
|
-
page.section-nav
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
with the host owner and relative route:
|
|
332
|
-
|
|
333
|
-
```js
|
|
334
|
-
owner: "reports",
|
|
335
|
-
to: "./exports"
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
That is exactly the behavior you want:
|
|
339
|
-
|
|
340
|
-
- `Reports` stays the host page
|
|
341
|
-
- `Exports` becomes a child tab under it
|
|
342
|
-
- the child route renders under the parent instead of becoming another top-level menu entry
|
|
343
|
-
|
|
344
|
-
This is also why `--link-placement` and `--link-to` are often unnecessary in the default nested case. Once the host exists, JSKIT already knows the likely semantic placement, owner, and relative `to` value. The link renderer comes from `src/placementTopology.js`.
|
|
345
|
-
|
|
346
|
-
## Nested pages under a file-route host
|
|
347
|
-
|
|
348
|
-
There is a second nesting shape that matters just as much.
|
|
349
|
-
|
|
350
|
-
Create a dynamic file-route page:
|
|
351
|
-
|
|
352
|
-
```bash
|
|
353
|
-
npx jskit generate ui-generator page \
|
|
354
|
-
home/contacts/[contactId].vue \
|
|
355
|
-
--name "Contact"
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
Then upgrade that page into a host:
|
|
359
|
-
|
|
360
|
-
```bash
|
|
361
|
-
npx jskit generate ui-generator add-subpages \
|
|
362
|
-
home/contacts/[contactId].vue \
|
|
363
|
-
--title "Contact" \
|
|
364
|
-
--subtitle "Contact activity and notes."
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
This time the parent is a file route, not an `index.vue` route.
|
|
368
|
-
|
|
369
|
-
So the child-page path is different:
|
|
370
|
-
|
|
371
|
-
```bash
|
|
372
|
-
npx jskit generate ui-generator page \
|
|
373
|
-
home/contacts/[contactId]/notes/index.vue \
|
|
374
|
-
--name "Notes"
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
That is the other important nesting rule:
|
|
378
|
-
|
|
379
|
-
- if the host is an `index.vue` page, children go under `index/...`
|
|
380
|
-
- if the host is a file-route page, children go under that page's directory
|
|
381
|
-
|
|
382
|
-
In the verified throwaway app, this command created:
|
|
383
|
-
|
|
384
|
-
```text
|
|
385
|
-
src/pages/home/contacts/[contactId]/notes/index.vue
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
and its link placement targeted:
|
|
389
|
-
|
|
390
|
-
```text
|
|
391
|
-
contacts-contact-id:sub-pages
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
So the exact host token changes, but the principle stays the same:
|
|
395
|
-
|
|
396
|
-
- a nearer routed host changes where `page` places the new link
|
|
397
|
-
- the child page becomes a tab or child link inside that host
|
|
398
|
-
|
|
399
|
-
This is one of the most important things to understand about `ui-generator`: nested pages are not a separate feature bolted on afterwards. The generator already knows how to attach them to the right place.
|
|
400
|
-
|
|
401
|
-
### A practical rule for child-page paths
|
|
402
|
-
|
|
403
|
-
Use these two rules when deciding where the child page file should go:
|
|
404
|
-
|
|
405
|
-
- host is `.../index.vue` -> child pages go under `.../index/...`
|
|
406
|
-
- host is `...[param].vue` or another file route -> child pages go under `.../[param]/...`
|
|
407
|
-
|
|
408
|
-
That is not only a file-layout preference. It is how the router keeps the parent host visible while the child page renders beneath it.
|
|
409
|
-
|
|
410
|
-
## Adding small placed UI: `placed-element`
|
|
411
|
-
|
|
412
|
-
Not everything should be a route.
|
|
413
|
-
|
|
414
|
-
If what you need is a small block of UI rendered into an existing placement target, use `placed-element` instead:
|
|
415
|
-
|
|
416
|
-
```bash
|
|
417
|
-
npx jskit generate ui-generator placed-element \
|
|
418
|
-
--name "Alerts Widget"
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
In the verified throwaway app, that command touched:
|
|
422
|
-
|
|
423
|
-
```text
|
|
424
|
-
- packages/main/src/client/providers/MainClientProvider.js
|
|
425
|
-
- src/components/AlertsWidgetElement.vue
|
|
426
|
-
- src/placement.js
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
Those three edits explain the feature:
|
|
430
|
-
|
|
431
|
-
- the component file is created in `src/components/`
|
|
432
|
-
- the app's local client provider registers a new local token for it
|
|
433
|
-
- `src/placement.js` adds a placement entry that renders that token
|
|
434
|
-
|
|
435
|
-
This is different from `page` in a very important way:
|
|
436
|
-
|
|
437
|
-
- `page` gives you a URL and a link
|
|
438
|
-
- `placed-element` gives you a component token and a placement entry
|
|
439
|
-
|
|
440
|
-
So if the thing you are adding should live *inside* an existing shell region, not at its own route, `placed-element` is the right command.
|
|
441
|
-
|
|
442
|
-
By default, the element targets the semantic status placement:
|
|
443
|
-
|
|
444
|
-
```text
|
|
445
|
-
shell.status
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
That is why this is such a good command for widgets, status panels, and compact shell extensions. The default shell topology maps `shell.status` to the concrete shell status outlet for each layout class.
|
|
449
|
-
|
|
450
|
-
### When `--surface` matters
|
|
451
|
-
|
|
452
|
-
`placed-element` only needs `--surface` when JSKIT cannot infer the target surface cleanly.
|
|
453
|
-
|
|
454
|
-
The easiest cases are:
|
|
455
|
-
|
|
456
|
-
- the app has only one enabled surface
|
|
457
|
-
- the chosen placement target clearly belongs to a page-owned outlet on one surface
|
|
458
|
-
|
|
459
|
-
In those cases, surface inference is straightforward.
|
|
460
|
-
|
|
461
|
-
The ambiguous cases are the ones to watch for:
|
|
462
|
-
|
|
463
|
-
- the app has several enabled surfaces
|
|
464
|
-
- the target placement is shared shell infrastructure rather than a page-owned outlet
|
|
465
|
-
- the placement itself does not tell JSKIT which surface you meant
|
|
466
|
-
|
|
467
|
-
That is exactly when `--surface` becomes important.
|
|
468
|
-
|
|
469
|
-
A practical example is:
|
|
470
|
-
|
|
471
|
-
```bash
|
|
472
|
-
npx jskit generate ui-generator placed-element \
|
|
473
|
-
--name "Ops Panel" \
|
|
474
|
-
--surface admin \
|
|
475
|
-
--placement shell.status
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
`shell.status` can be global across several surfaces. If your app has several enabled surfaces, `--surface admin` tells JSKIT which one this element is actually meant for.
|
|
479
|
-
|
|
480
|
-
So the rule of thumb is:
|
|
481
|
-
|
|
482
|
-
- page-owned semantic placement target -> surface is often inferable
|
|
483
|
-
- shared shell semantic placement in a multi-surface app -> pass `--surface`
|
|
484
|
-
|
|
485
|
-
### `--placement`
|
|
486
|
-
|
|
487
|
-
Use `--placement` when the default target `shell.status` is not what you want.
|
|
488
|
-
|
|
489
|
-
This is the option that answers:
|
|
490
|
-
|
|
491
|
-
- *where should this element render?*
|
|
492
|
-
|
|
493
|
-
In practice, it is the first override you will use for `placed-element`.
|
|
494
|
-
|
|
495
|
-
`--placement` expects a semantic placement id such as `shell.status`, `shell.global-actions`, or `settings.sections`. Concrete `host:position` outlets are exposed through topology, not used as normal placed-element authoring targets.
|
|
496
|
-
|
|
497
|
-
### `--path`
|
|
498
|
-
|
|
499
|
-
Use `--path` when the component file should live somewhere other than `src/components`.
|
|
500
|
-
|
|
501
|
-
This is not about placement in the UI. It is about placement in the source tree.
|
|
502
|
-
|
|
503
|
-
Typical reasons:
|
|
504
|
-
|
|
505
|
-
- you want widgets under `src/widgets`
|
|
506
|
-
- you want admin-specific pieces under a more specific component directory
|
|
507
|
-
- you want support scaffold grouped near a feature area instead of dumped into the default component folder
|
|
508
|
-
|
|
509
|
-
So `--path` changes where the new Vue file is written, not where it renders.
|
|
510
|
-
|
|
511
|
-
### `--force`
|
|
512
|
-
|
|
513
|
-
Use `--force` when the target component file already exists and you want to replace it with fresh generated scaffold.
|
|
514
|
-
|
|
515
|
-
That is most useful when:
|
|
516
|
-
|
|
517
|
-
- you are regenerating a throwaway prototype
|
|
518
|
-
- you intentionally want to reset the file to generator output
|
|
519
|
-
|
|
520
|
-
As with `page`, this is an overwrite guard, not a placement rule.
|
|
521
|
-
|
|
522
|
-
## Adding a plain placement seam: `outlet`
|
|
523
|
-
|
|
524
|
-
Now suppose you already have a component and you do **not** need routed child pages. You only need a named place where later UI can render.
|
|
525
|
-
|
|
526
|
-
That is what `outlet` is for.
|
|
527
|
-
|
|
528
|
-
In the verified throwaway app, after generating `Alerts Widget`, I ran:
|
|
529
|
-
|
|
530
|
-
```bash
|
|
531
|
-
npx jskit generate ui-generator outlet \
|
|
532
|
-
src/components/AlertsWidgetElement.vue \
|
|
533
|
-
--target alerts-widget:actions \
|
|
534
|
-
--placement page.actions
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
That command touched the Vue file and the topology file:
|
|
538
|
-
|
|
539
|
-
```text
|
|
540
|
-
src/components/AlertsWidgetElement.vue
|
|
541
|
-
src/placementTopology.js
|
|
542
|
-
```
|
|
543
|
-
|
|
544
|
-
and injected:
|
|
545
|
-
|
|
546
|
-
```vue
|
|
547
|
-
<ShellOutlet target="alerts-widget:actions" />
|
|
548
|
-
```
|
|
549
|
-
|
|
550
|
-
It did **not** add:
|
|
551
|
-
|
|
552
|
-
- `RouterView`
|
|
553
|
-
- `SectionContainerShell`
|
|
554
|
-
- child-page tab structure
|
|
555
|
-
|
|
556
|
-
That is the clean boundary between `outlet` and `add-subpages`.
|
|
557
|
-
|
|
558
|
-
Use `outlet` when you want:
|
|
559
|
-
|
|
560
|
-
- a placement seam inside an existing page or component
|
|
561
|
-
- later content to be targetable there
|
|
562
|
-
- no routed child-page behavior
|
|
563
|
-
|
|
564
|
-
After adding the outlet, `npx jskit list-placements` showed the new semantic placement immediately:
|
|
565
|
-
|
|
566
|
-
```text
|
|
567
|
-
- page.actions: ...
|
|
568
|
-
- compact -> alerts-widget:actions
|
|
569
|
-
- medium -> alerts-widget:actions
|
|
570
|
-
- expanded -> alerts-widget:actions
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
So `outlet` is the smallest possible way to add a concrete recipient and expose it through the public placement topology in the same change.
|
|
574
|
-
|
|
575
|
-
### When `outlet` is the smaller correct tool
|
|
576
|
-
|
|
577
|
-
This is the right command when you want to say:
|
|
578
|
-
|
|
579
|
-
- "other things should be able to render here later"
|
|
580
|
-
|
|
581
|
-
without also saying:
|
|
582
|
-
|
|
583
|
-
- "this file should become a routed host page"
|
|
584
|
-
|
|
585
|
-
That is why `outlet` is often the better choice for:
|
|
586
|
-
|
|
587
|
-
- summary cards
|
|
588
|
-
- header/action regions
|
|
589
|
-
- detail panes
|
|
590
|
-
- reusable components that need extension points
|
|
591
|
-
|
|
592
|
-
If you do **not** need `RouterView` and you do **not** need child routes, `outlet` is usually the cleaner tool.
|
|
593
|
-
|
|
594
|
-
### Choosing a good custom `--target` and `--placement`
|
|
595
|
-
|
|
596
|
-
`--target` should be meaningful to humans, not just syntactically valid.
|
|
597
|
-
|
|
598
|
-
A target like:
|
|
599
|
-
|
|
600
|
-
```text
|
|
601
|
-
customer-view:summary-actions
|
|
602
|
-
```
|
|
603
|
-
|
|
604
|
-
is good because it tells you:
|
|
605
|
-
|
|
606
|
-
- the host area: `customer-view`
|
|
607
|
-
- the position or outlet purpose: `summary-actions`
|
|
608
|
-
|
|
609
|
-
That is much better than something vague like:
|
|
610
|
-
|
|
611
|
-
```text
|
|
612
|
-
custom-area:slot1
|
|
613
|
-
```
|
|
614
|
-
|
|
615
|
-
because the meaningful target name will later show up in:
|
|
616
|
-
|
|
617
|
-
- `jskit list-placements --concrete`
|
|
618
|
-
- topology mappings
|
|
619
|
-
- future generator commands
|
|
620
|
-
|
|
621
|
-
So the target should describe the UI seam you are creating, not just satisfy the `host:position` format.
|
|
622
|
-
|
|
623
|
-
`--placement` is the public authoring target that other entries should use. It should be semantic, such as:
|
|
624
|
-
|
|
625
|
-
```text
|
|
626
|
-
page.actions
|
|
627
|
-
```
|
|
628
|
-
|
|
629
|
-
Adding an outlet without adding a semantic mapping would leave a low-level recipient that normal generators and humans will not discover by default.
|
|
630
|
-
|
|
631
|
-
## `add-subpages` versus `outlet`
|
|
632
|
-
|
|
633
|
-
This is the distinction that most often causes hesitation.
|
|
634
|
-
|
|
635
|
-
Use `add-subpages` when:
|
|
636
|
-
|
|
637
|
-
- the page should stay visible while child routes render underneath it
|
|
638
|
-
- you need a routed host page
|
|
639
|
-
- you want later generated child pages to attach there automatically
|
|
640
|
-
|
|
641
|
-
Use `outlet` when:
|
|
642
|
-
|
|
643
|
-
- you only want a placement seam
|
|
644
|
-
- the file already exists
|
|
645
|
-
- you do not want routed children
|
|
646
|
-
|
|
647
|
-
So:
|
|
648
|
-
|
|
649
|
-
- `add-subpages` changes the routing shape of the page
|
|
650
|
-
- `outlet` changes only the placement shape of the file
|
|
651
|
-
|
|
652
|
-
`add-subpages` also tends to be the right tool when the parent page is meant to stay visible while a series of related child pages render under it. `outlet` is the right tool when the file just needs extension points.
|
|
653
|
-
|
|
654
|
-
## Picking the right command
|
|
655
|
-
|
|
656
|
-
The short rule is:
|
|
657
|
-
|
|
658
|
-
- use `page` for new route pages
|
|
659
|
-
- use `placed-element` for reusable placed UI
|
|
660
|
-
- use `add-subpages` when the page should become a routed host
|
|
661
|
-
- use `outlet` when you only need a placement target inside an existing file
|
|
662
|
-
|
|
663
|
-
And the slightly longer rule is:
|
|
664
|
-
|
|
665
|
-
- if it needs a URL, start from `page`
|
|
666
|
-
- if it needs child routes, add `add-subpages`
|
|
667
|
-
- if it does not need a URL but should render somewhere, use `placed-element`
|
|
668
|
-
- if the file already exists and only needs a target for later UI, use `outlet`
|
|
669
|
-
|
|
670
|
-
## Summary
|
|
671
|
-
|
|
672
|
-
`ui-generator` is the non-CRUD side of JSKIT scaffolding.
|
|
673
|
-
|
|
674
|
-
It writes app-owned UI structure in four different shapes:
|
|
675
|
-
|
|
676
|
-
- route pages
|
|
677
|
-
- placed components
|
|
678
|
-
- routed host pages
|
|
679
|
-
- plain placement seams
|
|
680
|
-
|
|
681
|
-
The most important thing to remember is that nested pages are not a special afterthought. Once a page has been upgraded with `add-subpages`, later `page` generation automatically treats that host as the real placement target.
|
|
682
|
-
|
|
683
|
-
That is why the commands fit together cleanly:
|
|
684
|
-
|
|
685
|
-
- `page` creates routes
|
|
686
|
-
- `add-subpages` turns routes into hosts
|
|
687
|
-
- `page` can then create nested child routes under those hosts
|
|
688
|
-
- `placed-element` and `outlet` handle the non-routed side of the same UI system
|
|
689
|
-
|
|
690
|
-
Once the UI you want needs real database-backed list/view/new/edit behavior instead of only page structure, move to the CRUD generators chapter.
|