@jskit-ai/ui-generator 0.1.12 → 0.1.13

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/README.md CHANGED
@@ -31,7 +31,7 @@ npx jskit generate @jskit-ai/ui-generator page --name "Reports" --surface admin
31
31
  Generate an element at a specific outlet:
32
32
 
33
33
  ```bash
34
- npx jskit generate @jskit-ai/ui-generator element --name "Ops Panel" --surface admin --placement admin-settings:forms
34
+ npx jskit generate @jskit-ai/ui-generator element --name "Ops Panel" --surface admin --placement shell-layout:top-right
35
35
  ```
36
36
 
37
37
  Generate an element with custom component path:
@@ -93,6 +93,23 @@ npx jskit generate @jskit-ai/ui-generator outlet
93
93
  - `packages/main/src/client/providers/MainClientProvider.js` registration for `local.main.ui.tab-link-item`
94
94
  - `<route>.vue` as a thin wrapper around `SectionContainerShell` + `<RouterView />`, with route meta outlet declaration at `meta.jskit.placements.outlets`
95
95
  - no shell menu placement is added unless `--placement` is explicitly provided
96
+ - Child pages for a `container` go directly under the container route path, not under `(nestedChildren)`.
97
+ - Example container route: `src/pages/admin/practice.vue`
98
+ - Example child page path: `src/pages/admin/practice/notes/index.vue`
99
+ - Example URL: `/admin/practice/notes`
100
+ - Use `(nestedChildren)` for the `page + outlet` pattern when the parent page is an existing `index.vue` route that should render child routes inside its own `RouterView`.
101
+
102
+ Generate a child page inside a container:
103
+
104
+ ```bash
105
+ npx jskit generate @jskit-ai/ui-generator page \
106
+ --name "Notes" \
107
+ --surface admin \
108
+ --directory-prefix "practice" \
109
+ --placement practice:sub-pages \
110
+ --placement-component-token local.main.ui.tab-link-item
111
+ ```
112
+
96
113
  - Generate CRUD pages into that container using `@jskit-ai/crud-ui-generator` with:
97
114
  - `--container <route-slug>`
98
115
  - `--route-path <resource-slug>`
@@ -1,7 +1,7 @@
1
1
  export default Object.freeze({
2
2
  packageVersion: 1,
3
3
  packageId: "@jskit-ai/ui-generator",
4
- version: "0.1.12",
4
+ version: "0.1.13",
5
5
  kind: "generator",
6
6
  description: "Generate app-local non-CRUD UI pages and outlet elements.",
7
7
  options: {
@@ -149,7 +149,7 @@ export default Object.freeze({
149
149
  mutations: {
150
150
  dependencies: {
151
151
  runtime: {
152
- "@jskit-ai/users-web": "0.1.44"
152
+ "@jskit-ai/users-web": "0.1.45"
153
153
  },
154
154
  dev: {}
155
155
  },
@@ -174,7 +174,7 @@ export default Object.freeze({
174
174
  position: "bottom",
175
175
  skipIfContains: "jskit:ui-generator.page.menu:${option:surface|lower}:${option:directory-prefix|path}:${option:name|path}",
176
176
  value:
177
- "\n// jskit:ui-generator.page.menu:${option:surface|lower}:${option:directory-prefix|path}:${option:name|path}\n{\n addPlacement({\n id: \"ui-generator.page.${option:name|kebab}.menu\",\n host: \"__JSKIT_UI_MENU_PLACEMENT_HOST__\",\n position: \"__JSKIT_UI_MENU_PLACEMENT_POSITION__\",\n surfaces: [\"${option:surface|lower}\"],\n order: 155,\n componentToken: \"__JSKIT_UI_MENU_COMPONENT_TOKEN__\",\n props: {\n label: \"${option:name|trim}\",\n surface: \"${option:surface|lower}\",\n workspaceSuffix: \"__JSKIT_UI_MENU_WORKSPACE_SUFFIX__\",\n nonWorkspaceSuffix: \"__JSKIT_UI_MENU_NON_WORKSPACE_SUFFIX__\",\n__JSKIT_UI_MENU_TO_PROP_LINE__ },\n when: ({ auth }) => Boolean(auth?.authenticated)\n });\n}\n",
177
+ "\n// jskit:ui-generator.page.menu:${option:surface|lower}:${option:directory-prefix|path}:${option:name|path}\n{\n addPlacement({\n id: \"__JSKIT_UI_MENU_PLACEMENT_ID__\",\n host: \"__JSKIT_UI_MENU_PLACEMENT_HOST__\",\n position: \"__JSKIT_UI_MENU_PLACEMENT_POSITION__\",\n surfaces: [\"${option:surface|lower}\"],\n order: 155,\n componentToken: \"__JSKIT_UI_MENU_COMPONENT_TOKEN__\",\n props: {\n label: \"${option:name|trim}\",\n surface: \"${option:surface|lower}\",\n workspaceSuffix: \"__JSKIT_UI_MENU_WORKSPACE_SUFFIX__\",\n nonWorkspaceSuffix: \"__JSKIT_UI_MENU_NON_WORKSPACE_SUFFIX__\",\n__JSKIT_UI_MENU_TO_PROP_LINE__ },\n when: ({ auth }) => Boolean(auth?.authenticated)\n });\n}\n",
178
178
  reason: "Append generated UI page menu placement.",
179
179
  category: "ui-generator",
180
180
  id: "ui-generator-page-placement-menu-${option:name|snake}",
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@jskit-ai/ui-generator",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
7
7
  },
8
8
  "dependencies": {
9
- "@jskit-ai/kernel": "0.1.29"
9
+ "@jskit-ai/kernel": "0.1.30"
10
10
  },
11
11
  "exports": {
12
12
  "./server/buildTemplateContext": "./src/server/buildTemplateContext.js"
@@ -113,6 +113,21 @@ function resolveMenuToPropLine(options = {}) {
113
113
  return ` to: ${JSON.stringify(placementTo)},\n`;
114
114
  }
115
115
 
116
+ function normalizePlacementIdSegment(value = "") {
117
+ return wordsToKebab(splitTextIntoWords(value));
118
+ }
119
+
120
+ function resolveMenuPlacementId(options = {}) {
121
+ const idSegments = [
122
+ ...splitPathSegments(options?.["directory-prefix"]),
123
+ ...splitPathSegments(options?.name)
124
+ ]
125
+ .map((segment) => normalizePlacementIdSegment(segment))
126
+ .filter(Boolean);
127
+
128
+ return `ui-generator.page.${idSegments.join(".")}.menu`;
129
+ }
130
+
116
131
  async function buildUiPageTemplateContext({ appRoot, options } = {}) {
117
132
  const placementTarget = await resolveShellOutletPlacementTargetFromApp({
118
133
  appRoot,
@@ -121,6 +136,7 @@ async function buildUiPageTemplateContext({ appRoot, options } = {}) {
121
136
  });
122
137
 
123
138
  return {
139
+ __JSKIT_UI_MENU_PLACEMENT_ID__: resolveMenuPlacementId(options),
124
140
  __JSKIT_UI_MENU_PLACEMENT_HOST__: normalizeText(placementTarget?.host),
125
141
  __JSKIT_UI_MENU_PLACEMENT_POSITION__: normalizeText(placementTarget?.position),
126
142
  __JSKIT_UI_MENU_COMPONENT_TOKEN__: resolveMenuComponentToken(options),
@@ -86,7 +86,7 @@ test("ui-generator element subcommand creates component and outlet placement", a
86
86
  options: {
87
87
  name: "Ops Panel",
88
88
  surface: "admin",
89
- placement: "admin-settings:forms"
89
+ placement: "shell-layout:top-right"
90
90
  }
91
91
  });
92
92
 
@@ -105,8 +105,8 @@ test("ui-generator element subcommand creates component and outlet placement", a
105
105
 
106
106
  const placementSource = await readFile(path.join(appRoot, "src", "placement.js"), "utf8");
107
107
  assert.match(placementSource, /id: "ui-generator\.element\.ops-panel"/);
108
- assert.match(placementSource, /host: "admin-settings"/);
109
- assert.match(placementSource, /position: "forms"/);
108
+ assert.match(placementSource, /host: "shell-layout"/);
109
+ assert.match(placementSource, /position: "top-right"/);
110
110
  assert.match(placementSource, /componentToken: "local\.main\.ui\.element\.ops-panel"/);
111
111
  });
112
112
  });