@jskit-ai/agent-docs 0.1.26 → 0.1.28
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/DISTR_AGENT.md +1 -0
- package/guide/agent/app-extras/assistant.md +9 -20
- package/guide/agent/app-extras/mobile-capacitor.md +381 -0
- package/guide/agent/app-extras/realtime.md +13 -12
- package/guide/agent/app-setup/a-more-interesting-shell.md +102 -87
- package/guide/agent/app-setup/authentication.md +50 -31
- package/guide/agent/app-setup/console.md +8 -8
- package/guide/agent/app-setup/database-layer.md +15 -15
- package/guide/agent/app-setup/initial-scaffolding.md +37 -5
- package/guide/agent/app-setup/multi-homing.md +50 -47
- package/guide/agent/app-setup/quickstart.md +11 -14
- package/guide/agent/app-setup/users.md +24 -24
- package/guide/agent/app-setup/working-with-the-jskit-cli.md +18 -10
- package/guide/agent/generators/advanced-cruds.md +111 -68
- package/guide/agent/generators/crud-generators.md +5 -5
- package/guide/agent/generators/ui-generators.md +44 -36
- package/guide/agent/index.md +3 -2
- package/package.json +1 -1
- package/patterns/INDEX.md +4 -1
- package/patterns/client-requests.md +23 -6
- package/patterns/crud-repository-mapping.md +1 -1
- package/patterns/crud-scaffolding.md +10 -1
- package/patterns/filters.md +28 -10
- package/patterns/generated-ui-contract-tracking.md +62 -0
- package/patterns/page-scaffolding.md +20 -2
- package/patterns/placements.md +67 -1
- package/patterns/surfaces.md +5 -1
- package/patterns/ui-testing.md +3 -0
- package/reference/autogen/KERNEL_MAP.md +46 -1
- package/reference/autogen/README.md +3 -0
- package/reference/autogen/packages/assistant.md +2 -1
- package/reference/autogen/packages/auth-web.md +20 -1
- package/reference/autogen/packages/crud-ui-generator.md +20 -8
- package/reference/autogen/packages/google-rewarded-core.md +222 -0
- package/reference/autogen/packages/google-rewarded-web.md +71 -0
- package/reference/autogen/packages/kernel.md +94 -10
- package/reference/autogen/packages/mobile-capacitor.md +76 -0
- package/reference/autogen/packages/realtime.md +1 -0
- package/reference/autogen/packages/shell-web.md +48 -3
- package/reference/autogen/packages/ui-generator.md +34 -2
- package/reference/autogen/packages/users-core.md +2 -0
- package/reference/autogen/packages/users-web.md +92 -4
- package/reference/autogen/packages/workspaces-web.md +3 -2
- package/reference/autogen/tooling/jskit-cli.md +114 -9
- package/templates/app/AGENTS.md +1 -0
- package/workflow/bootstrap.md +1 -0
|
@@ -6,7 +6,7 @@ Use when:
|
|
|
6
6
|
- custom endpoint reads or writes
|
|
7
7
|
- AJAX questions
|
|
8
8
|
- replacing raw `fetch(...)` calls
|
|
9
|
-
- choosing between `useCommand()`, `useList()`, `useView()`, `useAddEdit()`, and `useEndpointResource()`
|
|
9
|
+
- choosing between shared CRUD screens, `useCommand()`, `useList()`, `useView()`, `useAddEdit()`, and `useEndpointResource()`
|
|
10
10
|
|
|
11
11
|
Rules:
|
|
12
12
|
|
|
@@ -19,22 +19,31 @@ Rules:
|
|
|
19
19
|
Choose the function like this:
|
|
20
20
|
|
|
21
21
|
```js
|
|
22
|
-
// 1.
|
|
22
|
+
// 1. Generated CRUD route screen
|
|
23
|
+
const screen = useCrudListScreen({ ... });
|
|
24
|
+
|
|
25
|
+
// 2. Button/toggle/small mutation
|
|
23
26
|
const command = useCommand({ ... });
|
|
24
27
|
|
|
25
|
-
//
|
|
28
|
+
// 3. List endpoint
|
|
26
29
|
const list = useList({ ... });
|
|
27
30
|
|
|
28
|
-
//
|
|
31
|
+
// 4. Single-record endpoint
|
|
29
32
|
const view = useView({ ... });
|
|
30
33
|
|
|
31
|
-
//
|
|
34
|
+
// 5. Form save flow
|
|
32
35
|
const form = useAddEdit({ ... });
|
|
33
36
|
|
|
34
|
-
//
|
|
37
|
+
// 6. Truly custom endpoint
|
|
35
38
|
const resource = useEndpointResource({ ... });
|
|
36
39
|
```
|
|
37
40
|
|
|
41
|
+
Use the shared CRUD screen wrappers when the route is a generated CRUD page:
|
|
42
|
+
|
|
43
|
+
- `useCrudListScreen()` plus `CrudListScreen` for list route pages
|
|
44
|
+
- `useCrudViewScreen()` plus `CrudViewScreen` for record view route pages
|
|
45
|
+
- `useCrudAddEditScreen()` plus `CrudAddEditScreen` for generated new/edit route pages
|
|
46
|
+
|
|
38
47
|
Use the CRUD wrappers when they fit:
|
|
39
48
|
|
|
40
49
|
- `useCrudList()` for routed CRUD lists
|
|
@@ -55,6 +64,13 @@ Why this is the standard JSKIT shape:
|
|
|
55
64
|
- Use `requestQueryParams` for endpoint query strings on list, view, and add/edit runtimes.
|
|
56
65
|
- Keep `apiUrlTemplate` path-only. Do not put `?include=...` or other query strings in URL templates.
|
|
57
66
|
|
|
67
|
+
Error presentation rules:
|
|
68
|
+
|
|
69
|
+
- Resource load failures should stay local to the screen with the runtime's `loadError` state and a retry action.
|
|
70
|
+
- Do not force global banners for ordinary list/view/add-edit load failures; the shell error policy treats `resource-load` as `silent` by default.
|
|
71
|
+
- Use `useUiFeedback()` or `useCommand()` for user-triggered action feedback. Those flows report `action-feedback`, and the app-owned shell error policy decides the channel.
|
|
72
|
+
- Use explicit shell error intents only for exceptional app-level cases: `app-recoverable` for recoverable shell/runtime failures and `blocking` for failures that require user attention.
|
|
73
|
+
|
|
58
74
|
Avoid:
|
|
59
75
|
|
|
60
76
|
- raw `fetch(...)` for standard page or component work
|
|
@@ -62,3 +78,4 @@ Avoid:
|
|
|
62
78
|
- manually concatenating scoped route params into API URLs
|
|
63
79
|
- using a lower-level seam when a higher-level routed CRUD or command runtime already fits
|
|
64
80
|
- smuggling query params into `apiUrlTemplate`
|
|
81
|
+
- reporting routine resource load errors through hand-written global snackbar/banner calls
|
|
@@ -80,7 +80,7 @@ const repositoryRuntime = createCrudResourceRuntime(resource, {
|
|
|
80
80
|
});
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
What CRUD core
|
|
83
|
+
What CRUD core does for you:
|
|
84
84
|
- default select columns include only column-backed output fields
|
|
85
85
|
- create/update write payloads serialize standard writable `date-time` fields centrally
|
|
86
86
|
- create/update write payloads also apply any explicit field write serializers centrally
|
|
@@ -19,12 +19,20 @@ Rules:
|
|
|
19
19
|
- For a CRUD-backed entity, start with `jskit generate crud-server-generator scaffold ...`.
|
|
20
20
|
- Unless the table is already owned by a JSKIT baseline package or is an explicit narrow exception recorded in `.jskit/table-ownership.json`, every persisted app-owned table must go through that server CRUD step first.
|
|
21
21
|
- That server scaffold is the crucial first step even if no CRUD UI will be created yet.
|
|
22
|
-
- If the table should be CRUD-owned
|
|
22
|
+
- If the table should already be CRUD-owned but should not expose public CRUD HTTP routes yet, scaffold it with `jskit generate crud-server-generator scaffold ... --internal` instead of dropping to direct knex or a hand-built pseudo-repository.
|
|
23
23
|
- Create the real table directly in the database before scaffolding. `crud-server-generator` reads the live table shape.
|
|
24
24
|
- If `crud-server-generator` is going to own the CRUD, do not hand-write a separate CRUD migration for that table. The generator installs and manages the CRUD migration scaffold itself.
|
|
25
25
|
- Do not scaffold CRUD UI, hand-build CRUD routes, or hand-build CRUD endpoints before the server CRUD package and shared resource file exist.
|
|
26
26
|
- Treat the generated shared resource file as the canonical CRUD contract for later UI scaffolding and CRUD behavior changes.
|
|
27
27
|
- `feature-server-generator` is not the default lane for ordinary persisted entities. Use it for workflows or orchestration that sit on top of CRUD-owned tables, or for rare explicit non-CRUD exceptions.
|
|
28
|
+
- Generated CRUD UI must be compact-first. Lists need searchable cards on compact widths and tables only for medium/expanded layouts.
|
|
29
|
+
- Generated CRUD list screens need real loading, empty, and error states. Empty copy should name the resource, such as "No customers yet", and offer the create action when available.
|
|
30
|
+
- Generated CRUD view/new/edit screens should use page headers plus direct sheet panels. Do not use generic card shells as the page architecture.
|
|
31
|
+
- Compact CRUD actions should be reachable without a drawer. Use a mobile-visible primary action or FAB for create flows.
|
|
32
|
+
- Row actions should collapse into an overflow/action menu on compact widths and can be inline on wider layouts.
|
|
33
|
+
- Bulk actions should be declared in the generated page-local `listBulkActions.js`. The generated list owns selection state, keeps selection controls hidden until actions exist, and exposes selected ids/records to action handlers.
|
|
34
|
+
- Structured filters should use shared filter definitions and collapse to compact filter controls/sheets when they outgrow simple search. Do not stack dense desktop filter bars on phone widths.
|
|
35
|
+
- Use `--navigation-role` for CRUD list placement intent. Main resources can stay `primary`; nested/detail/workflow CRUD routes should usually be `secondary`, `workflow`, or `none`.
|
|
28
36
|
|
|
29
37
|
Meaning of `--internal`:
|
|
30
38
|
|
|
@@ -38,3 +46,4 @@ Avoid:
|
|
|
38
46
|
- starting with `crud-ui-generator` before the server scaffold exists
|
|
39
47
|
- hand-building CRUD routes or validators that duplicate the generated server resource contract
|
|
40
48
|
- letting a new app-owned table exist in the live database without either generated CRUD ownership or a documented `.jskit/table-ownership.json` exception
|
|
49
|
+
- accepting table-only CRUD UI as "done" when the route is visible on phone widths
|
package/patterns/filters.md
CHANGED
|
@@ -17,21 +17,35 @@ Ask first:
|
|
|
17
17
|
- whether lookup filters need remote autocomplete search
|
|
18
18
|
- whether there are presets such as "Today", "Last 7 Days", or "Only Archived"
|
|
19
19
|
|
|
20
|
-
Default JSKIT pattern:
|
|
21
|
-
1.
|
|
20
|
+
Default JSKIT client pattern:
|
|
21
|
+
1. Generated CRUD list pages include a page-local `listFilters.js` file next to `index.vue`.
|
|
22
|
+
2. Put client filter definitions in that file with `defineCrudListFilters(...)`.
|
|
23
|
+
3. The generated `index.vue` passes `listFilters` into `useCrudListScreen(...)`; the shared list screen builds `useCrudListFilters(listFilters)`, passes `filterRuntime.queryParams` into the list request, and renders `CrudListFilterSurface`.
|
|
24
|
+
4. If `listFilters` is empty, the filter surface renders nothing and the page behaves like a normal searchable list.
|
|
25
|
+
5. The AI/app author is responsible for ensuring the server accepts and applies the query params declared in `listFilters.js`.
|
|
26
|
+
6. For lookup-backed filters, use `useCrudListFilterLookups(...)` when the page needs remote options or readable chip labels.
|
|
27
|
+
|
|
28
|
+
Generated client shape:
|
|
29
|
+
- `src/pages/<surface>/<resource>/listFilters.js`
|
|
30
|
+
- `const listFilters = defineCrudListFilters({ ... })`
|
|
31
|
+
- `useCrudListScreen({ ..., listFilters })`
|
|
32
|
+
- shared screen runtime owns:
|
|
33
|
+
- `const filterRuntime = useCrudListFilters(listFilters)`
|
|
34
|
+
- `queryParams: filterRuntime.queryParams`
|
|
35
|
+
- `<CrudListFilterSurface :filters="listFilters" :runtime="filterRuntime" />`
|
|
36
|
+
|
|
37
|
+
Server-side pattern, only when implementing real backend filter semantics:
|
|
38
|
+
1. Put reusable server-aware filter definitions in the CRUD package if the filter contract needs to be shared outside one generated page.
|
|
22
39
|
Example path: `packages/<crud>/src/shared/<crud>ListFilters.js`
|
|
23
40
|
2. Build the server runtime from that module with `createCrudListFilters(...)`.
|
|
24
41
|
3. Build route/action validators explicitly with `createCrudListFilterQueryField(...)` plus `createCrudListFilterQuerySchema(...)`, and use `applyQuery(...)` in the repository. There is no default validator mode or route-runtime alias.
|
|
25
|
-
4. Build the client runtime from the same shared definitions with `useCrudListFilters(...)`. Presets can use static `values` or dynamic `resolveValues({ values, filters, presetKey, preset })`.
|
|
26
|
-
5. Pass `listFilters.queryParams` into `useCrudList(...)`.
|
|
27
|
-
6. For lookup-backed filters, use `useCrudListFilterLookups(...)` instead of hand-rolling `useList()` in each page.
|
|
28
42
|
|
|
29
43
|
Exact file checklist:
|
|
30
44
|
- create `packages/<crud>/src/shared/<crud>ListFilters.js`
|
|
31
45
|
- update `packages/<crud>/src/server/registerRoutes.js` and `packages/<crud>/src/server/actions.js` so the list query validator lists structured filter params explicitly with `createCrudListFilterQueryField(...)` inside `createCrudListFilterQuerySchema(...)`, or update `packages/<crud>/src/server/listQueryValidators.js` if that package already extracts list-query composition there
|
|
32
46
|
- update `packages/<crud>/src/server/repository.js` so list queries call the runtime's `applyQuery(...)`
|
|
33
|
-
- update the
|
|
34
|
-
- for lookup-backed filters,
|
|
47
|
+
- update the generated page-local `listFilters.js` first; only edit `index.vue` if a specialist lookup label/runtime integration is needed
|
|
48
|
+
- for lookup-backed filters, wire `useCrudListFilterLookups(...)` beside the existing generated filter runtime instead of replacing `CrudListFilterSurface`
|
|
35
49
|
|
|
36
50
|
Validation mode is part of the contract:
|
|
37
51
|
- there is no default mode and no fallback alias, so every explicit structured filter field must choose `invalidValues: "reject"` or `invalidValues: "discard"` deliberately
|
|
@@ -72,11 +86,15 @@ Avoid:
|
|
|
72
86
|
- hiding accepted structured filter params behind whole-query validator generation when the route/action contract can list them directly
|
|
73
87
|
- hand-rolled preset apply/reset/active-state helpers when `useCrudListFilters(..., { presets })`, `applyPreset(...)`, and `matchesPreset(...)` fit
|
|
74
88
|
- per-screen `useList()` wrappers for lookup-backed filters when `useCrudListFilterLookups(...)` fits
|
|
75
|
-
-
|
|
89
|
+
- editing generated `.vue` files just to add basic filter controls; use the page-local `listFilters.js` seam first
|
|
76
90
|
- overloading `q` with structured filter meaning
|
|
77
|
-
-
|
|
91
|
+
- inline filter-definition objects passed into `useCrudListFilters(...)` or `createCrudListFilters(...)`; keep definitions in a named module
|
|
78
92
|
|
|
79
93
|
Good shape:
|
|
94
|
+
- `src/pages/home/customers/listFilters.js`
|
|
95
|
+
- `const listFilters = defineCrudListFilters({ status: { type: "enum", ... } })`
|
|
96
|
+
- generated page passes `listFilters` into `useCrudListScreen(...)`
|
|
97
|
+
- shared screen runtime passes `filterRuntime.queryParams` into the list request
|
|
80
98
|
- `packages/receivals/src/shared/receivalListFilters.js`
|
|
81
99
|
- `createCrudListFilters(RECEIVAL_LIST_FILTER_DEFINITIONS, ...)`
|
|
82
100
|
- `const listFilters = useCrudListFilters(RECEIVAL_LIST_FILTER_DEFINITIONS, { presets: [...] })`
|
|
@@ -89,7 +107,7 @@ Preset contract notes:
|
|
|
89
107
|
- if the URL contains `status=archived&status=bogus`, a preset for only `archived` should not render as active while the `bogus` chip is still visible
|
|
90
108
|
|
|
91
109
|
Review checks:
|
|
92
|
-
- one
|
|
110
|
+
- one filter definition source of truth: generated page-local `listFilters.js` for client-only filters, or a shared CRUD-package module when server code imports the same definitions
|
|
93
111
|
- server validator/repository logic derived from that source, with route/action query params still listed explicitly
|
|
94
112
|
- client query params/chips/reset logic derived from that source
|
|
95
113
|
- lookup-backed filters use the shared lookup helper, not a page-local mini-framework
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Generated UI Contract Tracking
|
|
2
|
+
|
|
3
|
+
Use this file to track the generator-level UI contract work. Keep entries concrete and update the checklist as each slice lands.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Generated JSKIT apps should feel like real adaptive apps by default, not framework demos. The contract must be enforced in generators, descriptors, docs, and tests so it does not drift.
|
|
8
|
+
|
|
9
|
+
## Current Scope
|
|
10
|
+
|
|
11
|
+
- [x] Centralize navigation role behavior beyond per-generator helpers.
|
|
12
|
+
- [x] Improve product-aware navigation inference and CLI prompting.
|
|
13
|
+
- [x] Audit generated/package UI templates for placeholder or instructional live-page copy.
|
|
14
|
+
- [x] Formalize surface density rules for app, admin, console, and settings screens.
|
|
15
|
+
- [x] Add shared typography/density primitives or generator support helpers where they reduce duplication.
|
|
16
|
+
- [x] Enforce "no cards inside cards" for generated page architecture while preserving intentional tool/dialog cards.
|
|
17
|
+
- [x] Expand UI verification from shell smoke coverage to generator-pattern smoke coverage for current page, CRUD, and shell outputs.
|
|
18
|
+
- [x] Centralize the JSKIT design contract and make tests consume it.
|
|
19
|
+
|
|
20
|
+
## Work Slices
|
|
21
|
+
|
|
22
|
+
- [x] Slice 1: create the central contract/support seam and move navigation-role constants into it.
|
|
23
|
+
- [x] Slice 2: wire `ui-generator` and `crud-ui-generator` to the shared contract.
|
|
24
|
+
- [x] Slice 3: add template/content contract scans for placeholder copy, card-shell misuse, and missing responsive hooks.
|
|
25
|
+
- [x] Slice 4: audit package templates that ship live UI and classify intentional cards.
|
|
26
|
+
- [x] Slice 5a: extend generated app Playwright smoke coverage to assert the generated screen contract.
|
|
27
|
+
- [x] Slice 5b: enforce page, CRUD, and shell generator-pattern verification through shared source contracts plus responsive smoke checks.
|
|
28
|
+
- [x] Slice 6: update distributed agent docs and regenerated references/catalog outputs.
|
|
29
|
+
|
|
30
|
+
## Verification Checklist
|
|
31
|
+
|
|
32
|
+
- [x] `npm run lint`
|
|
33
|
+
- [x] `npm run check:runtime-deps`
|
|
34
|
+
- [x] `npm run jskit -- lint-descriptors`
|
|
35
|
+
- [x] `npm run catalog:build`
|
|
36
|
+
- [x] `npm run agent-docs:build`
|
|
37
|
+
- [x] `npm test --workspace @jskit-ai/kernel`
|
|
38
|
+
- [x] `npm test --workspace @jskit-ai/ui-generator`
|
|
39
|
+
- [x] `npm test --workspace @jskit-ai/crud-ui-generator`
|
|
40
|
+
- [x] `npm test --workspace @jskit-ai/shell-web`
|
|
41
|
+
- [x] `npm test --workspace @jskit-ai/users-web`
|
|
42
|
+
- [x] `npm test --workspace @jskit-ai/workspaces-web`
|
|
43
|
+
- [x] `npm test --workspace @jskit-ai/jskit-cli`
|
|
44
|
+
- [x] `npm test --workspace @jskit-ai/create-app`
|
|
45
|
+
- [x] `npm test --workspace @jskit-ai/agent-docs`
|
|
46
|
+
- [x] `git diff --check`
|
|
47
|
+
|
|
48
|
+
## Notes
|
|
49
|
+
|
|
50
|
+
- Do not weaken semantic placement defaults while adding navigation inference.
|
|
51
|
+
- Do not turn the contract into runtime business logic; it is generator and template policy.
|
|
52
|
+
- Do not remove intentional cards from specialist UI components just to satisfy a broad scan.
|
|
53
|
+
- Keep generated files deterministic and update catalog/agent-doc outputs when descriptors or exported symbols change.
|
|
54
|
+
- Kernel shared UI contract must stay surface-id agnostic. Concrete mappings like admin/console to operator profile belong in generators or package templates.
|
|
55
|
+
- Item 3 is complete for current generated surfaces: page, CRUD, shell, and starter outputs require compact/medium/expanded coverage, horizontal overflow checks, generated screen checks, and 48px tap target checks. Calendar/grid/bottom-sheet specialist generators remain future scope until those generators exist.
|
|
56
|
+
- Item 5 is complete for current generators: `primary`, `secondary`, `utility`, `detail`, `workflow`, and `none` are centralized in the generated UI contract, generators consume that contract, and `utility` resolves to seeded `shell.global-actions` topology.
|
|
57
|
+
- Item 6 is complete for the default shell: compact app bars use compact density and bounded top-left/top-right regions, while primary navigation remains in semantic bottom navigation instead of app-bar chrome.
|
|
58
|
+
- CRUD filters are client-side by default: generated list pages create a page-local `listFilters.js` and pass it into `useCrudListScreen(...)`; the shared list screen wires `filterRuntime.queryParams` into the list request and renders `CrudListFilterSurface`. Server filter behavior remains explicit app/package work.
|
|
59
|
+
- CRUD bulk actions are client-side by default: generated list pages create a page-local `listBulkActions.js` and pass it into `useCrudListScreen(...)`; the shared list screen wires `useCrudListBulkActions(...)` and keeps selection controls hidden until actions are declared.
|
|
60
|
+
- Generated CRUD page templates delegate their screen chrome to shared `users-web` screen components (`CrudListScreen`, `CrudViewScreen`, and `CrudAddEditScreen`) so list/view/form load states, retry actions, responsive shell layout, filters, and bulk actions do not drift across generated pages.
|
|
61
|
+
- Routine resource-load errors stay local to the generated screen and retry affordance. Action feedback uses the shell error policy through `action-feedback`.
|
|
62
|
+
- `page.supporting-content` is a semantic supporting region in the default shell. Compact layout renders it as a closed bottom sheet; medium/expanded layouts render it as a closed side panel.
|
|
@@ -18,13 +18,31 @@ Rules:
|
|
|
18
18
|
|
|
19
19
|
- Default to `jskit generate ui-generator page ...` for a new app-owned non-CRUD route page.
|
|
20
20
|
- Let the generator create both the page file and the matching `src/placement.js` entry, then adapt the generated output if needed.
|
|
21
|
-
-
|
|
22
|
-
- If the page
|
|
21
|
+
- Choose the generated page's product navigation role deliberately. Use `--navigation-role primary` for main destinations, `secondary` for lower-priority shell links, and `detail`, `workflow`, or `none` when the page should not appear in navigation.
|
|
22
|
+
- If the page link belongs in a non-default semantic slot, discover the public placement first with `jskit list-placements` and pass `--link-placement`.
|
|
23
|
+
- If you need the concrete outlet inventory, use `jskit list-placements --concrete`; do not target concrete outlets by default.
|
|
24
|
+
- If the page sits under an existing routed host, check whether `ui-generator page` can infer the correct `page.section-nav` owner before writing a custom link by hand.
|
|
23
25
|
- If you do not use `ui-generator page`, state exactly why the generator does not fit before editing code.
|
|
24
26
|
- For a small placeholder route inside an existing route family, update the workboard rather than rewriting the blueprint unless the durable route or surface plan changed.
|
|
27
|
+
- Generated live pages must be usable screens, not instructional scaffolds. Do not ship copy such as "replace this", "use this area", or "this page is ready".
|
|
28
|
+
- Prefer a page header plus a direct `v-sheet` working region. Do not wrap every generated page in a generic `v-card`.
|
|
29
|
+
- If the screen is not implemented yet, use a product-shaped empty state with one clear next action or status, not developer instructions.
|
|
30
|
+
- Primary navigation links belong in semantic placements such as `shell.primary-nav` or `page.section-nav`; do not place every generated route into one drawer by default.
|
|
31
|
+
- Compact layouts must be checked first: no horizontal overflow, no unreachable primary action, and tap targets should be at least 48 px.
|
|
32
|
+
|
|
33
|
+
Generated UI contract:
|
|
34
|
+
|
|
35
|
+
- App-facing screens are phone-first and task-first; admin/console screens may be denser but still need responsive controls.
|
|
36
|
+
- Navigation uses semantic placements by default. Raw `host:position` outlets are advanced infrastructure.
|
|
37
|
+
- Page architecture is header plus direct work region, normally `v-sheet`; do not use generic page-level `v-card` shells.
|
|
38
|
+
- Empty/loading/error states are product-shaped and resource-named.
|
|
39
|
+
- Detail and workflow routes are not primary navigation by default.
|
|
40
|
+
- Generated UI must have compact, medium, and expanded browser checks when it changes user-facing behavior.
|
|
25
41
|
|
|
26
42
|
Avoid:
|
|
27
43
|
|
|
28
44
|
- hand-writing both `src/pages/...` and `src/placement.js` for a normal non-CRUD page before checking `ui-generator`
|
|
29
45
|
- treating a small page stub as permission to rewrite marketing copy, route architecture, or blueprint scope
|
|
30
46
|
- claiming that no generator exists without checking the actual `jskit` generator inventory first
|
|
47
|
+
- adding cards inside cards or repeating the page title inside a card title
|
|
48
|
+
- treating Vuetify component defaults as the product architecture
|
package/patterns/placements.md
CHANGED
|
@@ -11,18 +11,84 @@ Use when:
|
|
|
11
11
|
Check first:
|
|
12
12
|
|
|
13
13
|
- app `src/placement.js`
|
|
14
|
+
- app `src/placementTopology.js`
|
|
14
15
|
- package placement contributions
|
|
16
|
+
- package placement topology
|
|
15
17
|
- linked component token props
|
|
16
18
|
|
|
19
|
+
Mental model:
|
|
20
|
+
|
|
21
|
+
- `src/placement.js` answers "what is being placed?"
|
|
22
|
+
- `src/placementTopology.js` answers "where does this semantic placement render for compact, medium, and expanded layouts?"
|
|
23
|
+
- `<ShellOutlet target="host:position" />` is the concrete recipient rendered by Vue.
|
|
24
|
+
- Semantic ids use dot notation, for example `shell.primary-nav`, `shell.status`, `page.section-nav`, `page.supporting-content`, `settings.sections`.
|
|
25
|
+
- Concrete outlet ids use colon notation, for example `shell-layout:primary-menu`, `shell-layout:top-right`, `home-settings:primary-menu`.
|
|
26
|
+
- Authoring should target semantic placements by default. Concrete outlets are an advanced escape hatch.
|
|
27
|
+
|
|
28
|
+
Placement entries:
|
|
29
|
+
|
|
30
|
+
- Add entries with `addPlacement(...)` in `src/placement.js`.
|
|
31
|
+
- Use `target: "area.slot"` for normal entries.
|
|
32
|
+
- Use `owner` when the semantic placement is scoped to a specific host, for example `target: "page.section-nav", owner: "home-settings"`.
|
|
33
|
+
- Use `kind: "link"` for navigation/menu/tab links. Do not add a link renderer token to the entry unless there is a deliberate override.
|
|
34
|
+
- Use `kind: "component"` for widgets/sections/elements. These entries require `componentToken`.
|
|
35
|
+
- Use `surfaces` to say where the entry is eligible. Missing or `["*"]` means any surface.
|
|
36
|
+
- Use `order` for ordering. Equal order preserves source order.
|
|
37
|
+
- Use `props` for the rendered component props, including labels, icons, `surface`, `scopedSuffix`, `unscopedSuffix`, or explicit `to`.
|
|
38
|
+
- Use `when(context)` only for auth, permissions, feature flags, and runtime state. Do not use `when()` for layout adaptation.
|
|
39
|
+
- Direct concrete placement must use `target: "host:position"` plus `internal: true`. Treat this as low-level infrastructure, not normal app authoring.
|
|
40
|
+
|
|
41
|
+
Placement topology:
|
|
42
|
+
|
|
43
|
+
- `src/placementTopology.js` should be append-friendly: keep a `placements` array, export `addPlacementTopology(value)`, and append `addPlacementTopology(...)` blocks at the bottom.
|
|
44
|
+
- Every semantic placement topology entry needs `id`, optional `owner`, optional `description`, `surfaces`, and all three variants: `compact`, `medium`, and `expanded`.
|
|
45
|
+
- Every variant needs an `outlet: "host:position"`.
|
|
46
|
+
- Variant `renderers` maps semantic `kind` values to component tokens, for example `renderers: { link: "local.main.ui.surface-aware-menu-link-item" }`.
|
|
47
|
+
- Renderer choice for semantic `kind: "link"` placements belongs in topology, not in each placement entry.
|
|
48
|
+
- `default: true` marks the fallback semantic placement that page generators use when no nearer host applies.
|
|
49
|
+
- Package topology is discovered too, but app topology with the same `id` and `owner` overrides package topology in CLI discovery.
|
|
50
|
+
|
|
51
|
+
Runtime behavior:
|
|
52
|
+
|
|
53
|
+
- The shell runtime loads `/src/placementTopology.js` and `/src/placement.js`.
|
|
54
|
+
- Each `ShellOutlet` asks for placements by concrete `target`, current `surface`, and current layout class.
|
|
55
|
+
- Layout classes are `compact`, `medium`, and `expanded`.
|
|
56
|
+
- For semantic entries, runtime matches topology by `target`, `owner`, and `surface`, then chooses the current layout variant.
|
|
57
|
+
- A semantic entry renders only when the selected variant's `outlet` equals the concrete `ShellOutlet target`.
|
|
58
|
+
- Runtime resolves the component token as `entry.componentToken || variant.renderers[entry.kind]`.
|
|
59
|
+
- Entries without a resolvable component token do not render.
|
|
60
|
+
- `when()` receives placement context including `app`, `surface`, `target`, `layoutClass`, runtime context, local outlet context, and context contributors.
|
|
61
|
+
|
|
62
|
+
CLI and generators:
|
|
63
|
+
|
|
64
|
+
- `jskit list-placements` shows semantic placements by default.
|
|
65
|
+
- `jskit list-placements --concrete` shows concrete `ShellOutlet` recipients.
|
|
66
|
+
- `jskit list-placements --all` shows both.
|
|
67
|
+
- `jskit list-placements --json` returns structured semantic and concrete placement data.
|
|
68
|
+
- `ui-generator page`, CRUD UI list generation, and assistant page generation target semantic placements.
|
|
69
|
+
- `--link-placement` for generated pages is a semantic placement id, not a concrete outlet id.
|
|
70
|
+
- If a generated page is under a parent host with a mapped `ShellOutlet`, the generator infers the semantic placement and owner from topology.
|
|
71
|
+
- `ui-generator add-subpages` upgrades a page into a routed child-page host and appends a `page.section-nav` topology entry for the generated concrete outlet.
|
|
72
|
+
- `ui-generator outlet` injects a plain concrete `ShellOutlet` and appends the semantic topology mapping in the same command.
|
|
73
|
+
- `ui-generator page` and `crud-ui-generator crud` accept `--navigation-role` so detail, workflow, and utility routes do not accidentally become primary navigation.
|
|
74
|
+
- `page.supporting-content` is the default semantic place for supporting detail/content overlays. The default shell maps it to a closed compact bottom sheet and a closed medium/expanded side panel.
|
|
75
|
+
- When adding a public concrete outlet by hand, add its semantic topology mapping in the same change.
|
|
76
|
+
- If `jskit list-placements` reports unmapped concrete outlets, either add semantic topology for them or keep those outlets private/internal.
|
|
77
|
+
|
|
17
78
|
Rules:
|
|
18
79
|
|
|
19
80
|
- In JSKIT, tab-like links and shell/menu entries are often placement-owned, not page-owned.
|
|
20
81
|
- When asked to change a tab or menu icon, inspect placement metadata before editing page components.
|
|
21
82
|
- Look at placement `props`, especially fields such as `icon`, `prependIcon`, `appendIcon`, or props passed into the linked component token.
|
|
22
83
|
- If the visible entry is contributed by a package, update the owning package placement contribution instead of patching a local page component.
|
|
23
|
-
- If the request is really about where a link appears, check the placement `target`, `surfaces`, `order`, and `when` fields before changing UI markup.
|
|
84
|
+
- If the request is really about where a link appears, check the placement `target`, `owner`, `surfaces`, `order`, and `when` fields before changing UI markup.
|
|
85
|
+
- Placement targets should be semantic by default, such as `shell.primary-nav` or `page.section-nav`; concrete `host:position` outlets are the advanced escape hatch.
|
|
86
|
+
- Renderer choice for semantic `kind: "link"` placements belongs in topology, not in each placement entry.
|
|
87
|
+
- Supporting detail content should target `page.supporting-content` rather than generating per-page bottom-sheet markup.
|
|
88
|
+
- Adding a public concrete `ShellOutlet` should happen with a matching semantic topology entry in the same change.
|
|
24
89
|
|
|
25
90
|
Avoid:
|
|
26
91
|
|
|
27
92
|
- editing the routed page just to change a shell/tab/menu icon that is actually placement-owned
|
|
28
93
|
- assuming a rendered tab label/icon lives in the page component
|
|
94
|
+
- adding a public `ShellOutlet` without also exposing a semantic placement that maps to it
|
package/patterns/surfaces.md
CHANGED
|
@@ -19,12 +19,16 @@ Rules:
|
|
|
19
19
|
- Do not silently default new functionality to `app`.
|
|
20
20
|
- Surface choice is architectural, not cosmetic. It controls routes, access, placement visibility, and often data ownership expectations.
|
|
21
21
|
- When a link or widget should only appear on certain surfaces, use placement `surfaces` first and keep runtime `when` conditions for behavior-specific gating.
|
|
22
|
+
- App surfaces should be phone-first and task-first: lower chrome, bottom primary navigation on compact layouts, and prominent task actions.
|
|
23
|
+
- Admin and console surfaces can be denser and more utilitarian, but they still need responsive controls and must not become generic drawer-only mobile UIs.
|
|
24
|
+
- Settings surfaces should expose section navigation, direct controls, and real saved state. Avoid fake overview cards and instructional placeholder copy.
|
|
25
|
+
- Utility/status widgets belong in semantic status/action placements such as `shell.status` or `shell.global-actions`, not primary navigation.
|
|
22
26
|
|
|
23
27
|
Ask explicitly about:
|
|
24
28
|
|
|
25
29
|
- route pages
|
|
26
30
|
- menu entries
|
|
27
|
-
-
|
|
31
|
+
- semantic shell widgets such as `shell.identity`, `shell.status`, and `shell.global-actions`
|
|
28
32
|
- settings pages
|
|
29
33
|
- CRUD screens
|
|
30
34
|
- helper components that only make sense on one surface
|
package/patterns/ui-testing.md
CHANGED
|
@@ -10,6 +10,9 @@ Use when:
|
|
|
10
10
|
Rules:
|
|
11
11
|
|
|
12
12
|
- Any chunk that adds or changes user-facing UI must include a Playwright flow that exercises the changed behavior before the chunk is done.
|
|
13
|
+
- Generator or package template UI changes must be checked at compact phone, tablet-ish medium, and expanded desktop widths.
|
|
14
|
+
- For generated UI, the browser checks should cover horizontal overflow, clipped text, invisible text, duplicate navigation, broken route placement, and tap targets under 48 px.
|
|
15
|
+
- Apps with `shell-web` installed should start from the generated `tests/e2e/adaptive-shell.spec.ts` smoke and extend it for feature-specific assertions.
|
|
13
16
|
- Record that Playwright run with `jskit app verify-ui --command "<playwright command>" --feature "<label>" --auth-mode <mode>`.
|
|
14
17
|
- `jskit doctor` expects `.jskit/verification/ui.json` to match the current dirty UI file set when UI files are changed.
|
|
15
18
|
- For local pre-merge review, follow the recorded Playwright run with `jskit doctor --against <base-ref>` so `doctor` compares against the branch delta instead of only the local dirty worktree.
|
|
@@ -124,6 +124,35 @@ Exports
|
|
|
124
124
|
Exports
|
|
125
125
|
- `formatDateTime(value, { fallback = "unknown" } = {})`
|
|
126
126
|
|
|
127
|
+
### `support/generatedUiContract.js`
|
|
128
|
+
Exports
|
|
129
|
+
- `GENERATED_UI_FORBIDDEN_CARD_SHELL_PATTERNS`
|
|
130
|
+
- `GENERATED_UI_FORBIDDEN_LIVE_COPY_PATTERNS`
|
|
131
|
+
- `GENERATED_UI_NAVIGATION_ROLE_DEFAULT`
|
|
132
|
+
- `GENERATED_UI_NAVIGATION_ROLE_LINK_PLACEMENTS`
|
|
133
|
+
- `GENERATED_UI_NAVIGATION_ROLE_OPTION`
|
|
134
|
+
- `GENERATED_UI_NAVIGATION_ROLE_VALUES`
|
|
135
|
+
- `GENERATED_UI_NO_LINK_NAVIGATION_ROLES`
|
|
136
|
+
- `GENERATED_UI_SOURCE_CONTRACT_PROFILES`
|
|
137
|
+
- `GENERATED_UI_SURFACE_PROFILES`
|
|
138
|
+
- `assertGeneratedUiSourceContract(source = "", options = {})`
|
|
139
|
+
- `buildGeneratedUiScreenClassName(baseClassName = "", { surfaceProfile = "" } = {})`
|
|
140
|
+
- `collectGeneratedUiSourceContractIssues(source = "", { profile = "", forbidLiveCopy = undefined, forbidCardShell = undefined, forbiddenPatterns = [], requiredPatterns = [] } = {})`
|
|
141
|
+
- `inferGeneratedUiNavigationRole(options = {}, { dynamicRoutePolicy = "leaf", routePath = "" } = {})`
|
|
142
|
+
- `isGeneratedUiNoLinkNavigationRole(value = "")`
|
|
143
|
+
- `normalizeGeneratedUiNavigationRole(value = "")`
|
|
144
|
+
- `resolveGeneratedUiSurfaceProfile(surfaceProfile = "")`
|
|
145
|
+
- `resolveGeneratedUiNavigationRoleLinkPlacement(options = {}, inferenceContext = {})`
|
|
146
|
+
- `shouldCreateGeneratedUiNavigationLink(options = {}, { allowLinkTo = false, dynamicRoutePolicy = "leaf", routePath = "" } = {})`
|
|
147
|
+
Local functions
|
|
148
|
+
- `matchesGeneratedUiContractPattern(source = "", pattern)`
|
|
149
|
+
- `normalizeGeneratedUiContractPattern(patternEntry = {}, fallbackMessage = "")`
|
|
150
|
+
- `normalizeGeneratedUiContractPatternList(patternEntries = [], fallbackMessage = "")`
|
|
151
|
+
- `resolveGeneratedUiSourceContractProfile(profile = "")`
|
|
152
|
+
- `hasExplicitGeneratedUiNavigationRole(options = {})`
|
|
153
|
+
- `normalizeGeneratedUiRouteSegments(routePath = "")`
|
|
154
|
+
- `isGeneratedUiDynamicRouteSegment(routeSegment = "")`
|
|
155
|
+
|
|
127
156
|
### `support/index.js`
|
|
128
157
|
Exports
|
|
129
158
|
- `isRecord`
|
|
@@ -174,6 +203,10 @@ Exports
|
|
|
174
203
|
- `normalizeRecordId(value, { fallback = null } = {})`
|
|
175
204
|
- `normalizeOpaqueId(value, { fallback = null } = {})`
|
|
176
205
|
- `normalizeOneOf(value, allowedValues = [], fallback = "")`
|
|
206
|
+
- `normalizeMobileAssetMode(value = "", { fallback = "bundled" } = {})`
|
|
207
|
+
- `normalizeMobileCallbackPath(value = "", { fallback = "/auth/login" } = {})`
|
|
208
|
+
- `normalizeMobileConfig(source = {})`
|
|
209
|
+
- `normalizeMobileStrategy(value = "", { fallback = "" } = {})`
|
|
177
210
|
- `ensureNonEmptyText(value, label = "value")`
|
|
178
211
|
|
|
179
212
|
### `support/permissions.js`
|
|
@@ -229,14 +262,26 @@ Local functions
|
|
|
229
262
|
|
|
230
263
|
### `support/shellLayoutTargets.js`
|
|
231
264
|
Exports
|
|
265
|
+
- `PLACEMENT_LAYOUT_CLASSES`
|
|
232
266
|
- `describeShellOutletTargets(targets = [])`
|
|
233
|
-
- `discoverShellOutletTargetsFromVueSource(source = "", { context = "shell layout" } = {})`
|
|
267
|
+
- `discoverShellOutletTargetsFromVueSource(source = "", { context = "shell layout", enforceSingleDefault = true } = {})`
|
|
234
268
|
- `findShellOutletTargetById(targets = [], targetId = "")`
|
|
269
|
+
- `normalizePlacementKind(value = "")`
|
|
270
|
+
- `normalizePlacementLayoutClass(value = "")`
|
|
271
|
+
- `normalizePlacementOwnerId(value = "")`
|
|
272
|
+
- `normalizePlacementSurfaceId(value = "")`
|
|
273
|
+
- `normalizePlacementSurfaces(value)`
|
|
274
|
+
- `normalizePlacementTopologyDefinition(value = {}, { context = "placement topology" } = {})`
|
|
275
|
+
- `normalizePlacementTopologyEntry(value = {}, { context = "placement topology" } = {})`
|
|
276
|
+
- `normalizePlacementTopologyVariant(value = {}, { context = "placement topology variant" } = {})`
|
|
277
|
+
- `normalizeSemanticPlacementId(value = "")`
|
|
235
278
|
- `normalizeShellOutletTargetId(value = "")`
|
|
236
279
|
- `normalizeShellOutletTargetRecord(value = {}, { context = "shell layout" } = {})`
|
|
280
|
+
- `resolvePlacementTargetReference(value = "")`
|
|
237
281
|
- `resolveShellOutletTargetParts({ target = "" } = {})`
|
|
238
282
|
Local functions
|
|
239
283
|
- `parseTagAttributes(attributesSource = "")`
|
|
284
|
+
- `normalizePlacementRenderers(value = {})`
|
|
240
285
|
- `isDefaultAttributeEnabled(value)`
|
|
241
286
|
|
|
242
287
|
### `support/sorting.js`
|
|
@@ -23,9 +23,12 @@ Startup navigation stays in `KERNEL_MAP.md`.
|
|
|
23
23
|
- [database-runtime-mysql](/packages/agent-docs/reference/autogen/packages/database-runtime-mysql.md)
|
|
24
24
|
- [database-runtime-postgres](/packages/agent-docs/reference/autogen/packages/database-runtime-postgres.md)
|
|
25
25
|
- [feature-server-generator](/packages/agent-docs/reference/autogen/packages/feature-server-generator.md)
|
|
26
|
+
- [google-rewarded-core](/packages/agent-docs/reference/autogen/packages/google-rewarded-core.md)
|
|
27
|
+
- [google-rewarded-web](/packages/agent-docs/reference/autogen/packages/google-rewarded-web.md)
|
|
26
28
|
- [http-runtime](/packages/agent-docs/reference/autogen/packages/http-runtime.md)
|
|
27
29
|
- [json-rest-api-core](/packages/agent-docs/reference/autogen/packages/json-rest-api-core.md)
|
|
28
30
|
- [kernel](/packages/agent-docs/reference/autogen/packages/kernel.md)
|
|
31
|
+
- [mobile-capacitor](/packages/agent-docs/reference/autogen/packages/mobile-capacitor.md)
|
|
29
32
|
- [realtime](/packages/agent-docs/reference/autogen/packages/realtime.md)
|
|
30
33
|
- [resource-core](/packages/agent-docs/reference/autogen/packages/resource-core.md)
|
|
31
34
|
- [resource-crud-core](/packages/agent-docs/reference/autogen/packages/resource-crud-core.md)
|
|
@@ -27,6 +27,7 @@ Exports
|
|
|
27
27
|
- `renderAssistantPageSummary(pageTarget = {}, { pageAlreadyExisted = false, pageOverwritten = false } = {})`
|
|
28
28
|
Local functions
|
|
29
29
|
- `resolveLinkToPropLine(linkTo = "")`
|
|
30
|
+
- `resolveOwnerLine(owner = "")`
|
|
30
31
|
- `resolveTemplateFilePath(relativePath = "")`
|
|
31
32
|
|
|
32
33
|
### `src/server/subcommands/page.js`
|
|
@@ -53,7 +54,7 @@ Exports
|
|
|
53
54
|
- `normalizeConfigScope(value = "")`
|
|
54
55
|
- `loadAppConfig(appRoot = "")`
|
|
55
56
|
- `resolveSurfaceDefinition(appConfig = {}, surfaceId = "", optionName = "surface")`
|
|
56
|
-
- `assertAssistantSurfaceIsAvailable(appConfig = {}, surfaceId = "")`
|
|
57
|
+
- `assertAssistantSurfaceIsAvailable(appConfig = {}, surfaceId = "", expected = {})`
|
|
57
58
|
- `resolveAiConfigPrefix(surfaceId = "", explicitPrefix = "")`
|
|
58
59
|
|
|
59
60
|
### templates
|
|
@@ -51,7 +51,7 @@ Local functions
|
|
|
51
51
|
|
|
52
52
|
### `src/client/composables/loginView/useLoginViewActions.js`
|
|
53
53
|
Exports
|
|
54
|
-
- `useLoginViewActions({ state, validation, queryClient, errorRuntime } = {})`
|
|
54
|
+
- `useLoginViewActions({ state, validation, queryClient, errorRuntime, oauthLaunchClient = null } = {})`
|
|
55
55
|
|
|
56
56
|
### `src/client/composables/loginView/useLoginViewState.js`
|
|
57
57
|
Exports
|
|
@@ -84,6 +84,9 @@ Exports
|
|
|
84
84
|
- `AuthProfileMenuLinkItem`
|
|
85
85
|
- `useAuthStore`
|
|
86
86
|
- `useAuthGuardRuntime`
|
|
87
|
+
- `completeOAuthCallbackFromCurrentLocation`
|
|
88
|
+
- `completeOAuthCallbackFromUrl`
|
|
89
|
+
- `readOAuthCallbackParamsFromUrl`
|
|
87
90
|
- `routeComponents`
|
|
88
91
|
- `clientProviders`
|
|
89
92
|
|
|
@@ -152,9 +155,25 @@ Exports
|
|
|
152
155
|
### `src/client/runtime/inject.js`
|
|
153
156
|
Exports
|
|
154
157
|
- `AUTH_GUARD_RUNTIME_INJECTION_KEY`
|
|
158
|
+
- `AUTH_OAUTH_LAUNCH_CLIENT_INJECTION_KEY`
|
|
155
159
|
- `EMPTY_AUTH_GUARD_STATE`
|
|
156
160
|
- `EMPTY_AUTH_GUARD_RUNTIME`
|
|
157
161
|
- `useAuthGuardRuntime({ required = false } = {})`
|
|
162
|
+
- `useAuthOAuthLaunchClient({ required = false } = {})`
|
|
163
|
+
|
|
164
|
+
### `src/client/runtime/oauthCallbackRuntime.js`
|
|
165
|
+
Exports
|
|
166
|
+
- `completeOAuthCallbackFromCurrentLocation(options = {})`
|
|
167
|
+
- `completeOAuthCallbackFromUrl({ url = "", fallbackReturnTo = "/", allowedReturnToOrigins = [], defaultProvider = "", request = authHttpRequest, refreshSession = async () => null } = {})`
|
|
168
|
+
- `readOAuthCallbackParamsFromUrl(url = "")`
|
|
169
|
+
Local functions
|
|
170
|
+
- `parseCallbackUrl(url = "")`
|
|
171
|
+
- `buildOAuthCompletePayload({ callbackParams = null, provider = "", hasSessionPair = false } = {})`
|
|
172
|
+
|
|
173
|
+
### `src/client/runtime/oauthLaunchClient.js`
|
|
174
|
+
Exports
|
|
175
|
+
- `createBrowserOAuthLaunchClient({ location = null } = {})`
|
|
176
|
+
- `isAuthOAuthLaunchClient(value = null)`
|
|
158
177
|
|
|
159
178
|
### `src/client/runtime/useLoginView.js`
|
|
160
179
|
Exports
|
|
@@ -25,19 +25,26 @@ Local functions
|
|
|
25
25
|
- `toSingularKebab(value = "")`
|
|
26
26
|
- `toPluralKebab(value = "")`
|
|
27
27
|
- `toTitleFromKebab(value = "", fallback = "")`
|
|
28
|
+
- `buildCrudListCopy(resourceLabels = {})`
|
|
28
29
|
- `normalizeRelativeAppPath(value = "")`
|
|
29
30
|
- `requireTargetRootOption(options = {})`
|
|
30
31
|
- `resolveListTargetFile(targetRoot = "")`
|
|
31
32
|
- `parseOperationsOption(options)`
|
|
32
33
|
- `parseDisplayFieldsOption(options)`
|
|
33
34
|
- `parseParentTitleOption(options)`
|
|
35
|
+
- `shouldCreateNavigationLink(options = {}, inferenceContext = {})`
|
|
36
|
+
- `resolveNavigationRoleLinkPlacement(options = {}, inferenceContext = {})`
|
|
34
37
|
- `validateDisplayFieldsForOperation(selectedFieldKeys, fields, operationName)`
|
|
35
38
|
- `filterDisplayFields(selectedFieldKeys, fields)`
|
|
36
39
|
- `rewriteGeneratedBlockIndent(source = "", { trimPrefix = "", addPrefix = "" } = {})`
|
|
37
40
|
- `hasLookupFormFields(fields = [])`
|
|
41
|
+
- `hasLookupDisplayFields(fields = [])`
|
|
42
|
+
- `buildListCardSlotProps(fields = [])`
|
|
43
|
+
- `buildListRowSlotProps(fields = [])`
|
|
44
|
+
- `buildCrudFieldsSlotProps(fields = [], { includeMode = false } = {})`
|
|
38
45
|
- `buildLookupImportLine(fields = [])`
|
|
39
46
|
- `buildLookupRuntimeSetup(fields = [], { formFieldsVariable = "", resourceNamespace = "", mode = "" } = {})`
|
|
40
|
-
- `buildLookupFormProps(fields = [])`
|
|
47
|
+
- `buildLookupFormProps(fields = [], { sourcePrefix = "" } = {})`
|
|
41
48
|
- `buildLookupFormPropDefinitions({ createFields = [], editFields = [] } = {})`
|
|
42
49
|
- `filterDefaultHiddenListFields(selectedFieldKeys, fields, { recordIdFieldKey = "" } = {})`
|
|
43
50
|
- `ensureFields(fields, fallbackFields = createFieldDefinitions({}))`
|
|
@@ -45,7 +52,10 @@ Local functions
|
|
|
45
52
|
- `resolveResourceNamespace(resource = {}, pageTarget = {}, options = {})`
|
|
46
53
|
- `resolveResourceLabels(namespace = "", pageTarget = {})`
|
|
47
54
|
- `resolveTargetRootRelativeRoutePath(pageTarget = {})`
|
|
55
|
+
- `resolveNavigationInferenceRoutePath(pageTarget = {})`
|
|
48
56
|
- `resolveMenuToPropLine(linkTo = "")`
|
|
57
|
+
- `resolveMenuOwnerLine(owner = "")`
|
|
58
|
+
- `buildMenuAppendBlock({ hasListOperation = false, menuMarker = "", pageLinkTarget = null, pageTarget = {} } = {})`
|
|
49
59
|
- `resolveCrudRelativePath(namespace = "")`
|
|
50
60
|
- `buildListParentTitleImportLine(parentTitleMode = "contextual")`
|
|
51
61
|
- `buildListHeadingTitleSetup({ parentTitleMode = "contextual", resourceNamespace = "", routeTitle = "Records" } = {})`
|
|
@@ -69,6 +79,7 @@ Exports
|
|
|
69
79
|
- `resolveNearestParentRouteParamKey(routePath = "", { recordIdParam = "recordId" } = {})`
|
|
70
80
|
- `buildListHeaderColumns(fields = [])`
|
|
71
81
|
- `buildListRowColumns(fields = [])`
|
|
82
|
+
- `buildListCardFields(fields = [])`
|
|
72
83
|
- `buildViewColumns(fields = [])`
|
|
73
84
|
- `buildFormColumns(fields = [])`
|
|
74
85
|
- `resolveRecordIdFieldKey(fields = [])`
|
|
@@ -131,9 +142,6 @@ Local functions
|
|
|
131
142
|
### `templates/src/pages/admin/ui-generator/AddEditForm.vue`
|
|
132
143
|
Exports
|
|
133
144
|
- None
|
|
134
|
-
Local functions
|
|
135
|
-
- `resolveFieldErrors(fieldKey)`
|
|
136
|
-
- `resolveCancelTo(target)`
|
|
137
145
|
|
|
138
146
|
### `templates/src/pages/admin/ui-generator/AddEditFormFields.js`
|
|
139
147
|
Exports
|
|
@@ -143,22 +151,26 @@ Exports
|
|
|
143
151
|
### `templates/src/pages/admin/ui-generator/EditElement.vue`
|
|
144
152
|
Exports
|
|
145
153
|
- None
|
|
146
|
-
Local functions
|
|
147
|
-
- `resolveFieldErrors(fieldKey)`
|
|
148
154
|
|
|
149
155
|
### `templates/src/pages/admin/ui-generator/EditWrapperElement.vue`
|
|
150
156
|
Exports
|
|
151
157
|
- None
|
|
152
158
|
|
|
159
|
+
### `templates/src/pages/admin/ui-generator/listBulkActions.js`
|
|
160
|
+
Exports
|
|
161
|
+
- `listBulkActions`
|
|
162
|
+
|
|
153
163
|
### `templates/src/pages/admin/ui-generator/ListElement.vue`
|
|
154
164
|
Exports
|
|
155
165
|
- None
|
|
156
166
|
|
|
167
|
+
### `templates/src/pages/admin/ui-generator/listFilters.js`
|
|
168
|
+
Exports
|
|
169
|
+
- `listFilters`
|
|
170
|
+
|
|
157
171
|
### `templates/src/pages/admin/ui-generator/NewElement.vue`
|
|
158
172
|
Exports
|
|
159
173
|
- None
|
|
160
|
-
Local functions
|
|
161
|
-
- `resolveFieldErrors(fieldKey)`
|
|
162
174
|
|
|
163
175
|
### `templates/src/pages/admin/ui-generator/NewWrapperElement.vue`
|
|
164
176
|
Exports
|