@jskit-ai/ui-generator 0.1.3

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 ADDED
@@ -0,0 +1,73 @@
1
+ # @jskit-ai/ui-generator
2
+
3
+ Generate non-CRUD UI pages and outlet elements for JSKIT apps.
4
+
5
+ ## Quick Start
6
+
7
+ List available placement targets in the current app:
8
+
9
+ ```bash
10
+ npx jskit list placements
11
+ ```
12
+
13
+ Generate a page (default placement target):
14
+
15
+ ```bash
16
+ npx jskit generate @jskit-ai/ui-generator page --name "Reports Dashboard" --surface admin
17
+ ```
18
+
19
+ Generate a page in a subdirectory:
20
+
21
+ ```bash
22
+ npx jskit generate @jskit-ai/ui-generator page --name "Reports Dashboard" --surface admin --directory-prefix ops
23
+ ```
24
+
25
+ Generate a page and place its menu entry in the workspace cog dropdown:
26
+
27
+ ```bash
28
+ npx jskit generate @jskit-ai/ui-generator page --name "Reports" --surface admin --placement workspace-tools:primary-menu
29
+ ```
30
+
31
+ Generate an element at a specific outlet:
32
+
33
+ ```bash
34
+ npx jskit generate @jskit-ai/ui-generator element --name "Ops Panel" --surface admin --placement workspace-settings:forms
35
+ ```
36
+
37
+ Generate an element with custom component path:
38
+
39
+ ```bash
40
+ npx jskit generate @jskit-ai/ui-generator element --name "Alerts Widget" --surface admin --path src/widgets --placement shell-layout:top-right
41
+ ```
42
+
43
+ Generate a route container page with nested outlet (for embedded sub-pages):
44
+
45
+ ```bash
46
+ npx jskit generate @jskit-ai/ui-generator container --name "Practice" --surface admin
47
+ ```
48
+
49
+ ## Commands
50
+
51
+ - `page`: `--name --surface [--directory-prefix] [--placement]`
52
+ - `element`: `--name --surface [--path] [--placement]`
53
+ - `container`: `--name --surface [--directory-prefix] [--placement]`
54
+
55
+ ## Container Workflow
56
+
57
+ - `container` creates app-owned scaffolding:
58
+ - `src/components/SectionContainerShell.vue` (shared container shell with responsive tab row)
59
+ - `src/components/SectionShellTabLinkItem.vue` (tab link item token component)
60
+ - `packages/main/src/client/providers/MainClientProvider.js` registration for `local.main.ui.section-shell.tab-link-item`
61
+ - `<route>.vue` as a thin wrapper around `SectionContainerShell` + `<RouterView />`
62
+ - Generate CRUD pages into that container using `@jskit-ai/crud-ui-generator` with:
63
+ - `--container <route-slug>`
64
+ - `--route-path <resource-slug>`
65
+ - optional `--placement` override (default becomes `<container>:sub-pages` for list pages)
66
+
67
+ ## Placement Notes
68
+
69
+ - `--placement` expects `host:position`.
70
+ - Targets come from:
71
+ - app-declared `<ShellOutlet host="..." position="..." />` in `src/**/*.vue`
72
+ - installed package metadata `metadata.ui.placements.outlets`
73
+ - If `--placement` is omitted, the app default outlet is used.
@@ -0,0 +1,121 @@
1
+ export default Object.freeze({
2
+ packageVersion: 1,
3
+ packageId: "@jskit-ai/ui-generator",
4
+ version: "0.1.3",
5
+ kind: "generator",
6
+ description: "Generate app-local non-CRUD UI pages and outlet elements.",
7
+ options: {
8
+ name: {
9
+ required: true,
10
+ inputType: "text",
11
+ defaultValue: "",
12
+ promptLabel: "Element name",
13
+ promptHint: "Display name and route slug source (example: Reports Dashboard)."
14
+ },
15
+ surface: {
16
+ required: true,
17
+ inputType: "text",
18
+ defaultFromConfig: "surfaceDefaultId",
19
+ promptLabel: "Target surface",
20
+ promptHint: "Defaults to config.public.surfaceDefaultId. Must match an enabled surface id."
21
+ },
22
+ path: {
23
+ required: false,
24
+ inputType: "text",
25
+ defaultValue: "src/components",
26
+ promptLabel: "Component path",
27
+ promptHint: "Component directory relative to app root (used by element subcommand)."
28
+ },
29
+ "directory-prefix": {
30
+ required: false,
31
+ inputType: "text",
32
+ defaultValue: "",
33
+ promptLabel: "Page directory prefix",
34
+ promptHint: "Optional subpath under the selected surface pages root (example: crm or ops/team-a)."
35
+ },
36
+ placement: {
37
+ required: false,
38
+ inputType: "text",
39
+ defaultValue: "",
40
+ promptLabel: "Placement target",
41
+ promptHint: "Optional host:position target (defaults to app ShellOutlet default target)."
42
+ }
43
+ },
44
+ dependsOn: [],
45
+ capabilities: {
46
+ provides: ["ui-generator"],
47
+ requires: []
48
+ },
49
+ runtime: {
50
+ server: {
51
+ providers: []
52
+ },
53
+ client: {
54
+ providers: []
55
+ }
56
+ },
57
+ metadata: {
58
+ generatorPrimarySubcommand: "page",
59
+ generatorSubcommands: {
60
+ element: {
61
+ entrypoint: "src/server/subcommands/element.js",
62
+ export: "runGeneratorSubcommand"
63
+ },
64
+ container: {
65
+ entrypoint: "src/server/subcommands/container.js",
66
+ export: "runGeneratorSubcommand"
67
+ }
68
+ },
69
+ apiSummary: {
70
+ surfaces: [
71
+ {
72
+ subpath: "./server/buildTemplateContext",
73
+ summary: "Builds deterministic page menu placement template context values."
74
+ }
75
+ ],
76
+ containerTokens: {
77
+ server: [],
78
+ client: []
79
+ }
80
+ }
81
+ },
82
+ mutations: {
83
+ dependencies: {
84
+ runtime: {
85
+ "@jskit-ai/users-web": "0.1.34"
86
+ },
87
+ dev: {}
88
+ },
89
+ packageJson: {
90
+ scripts: {}
91
+ },
92
+ procfile: {},
93
+ files: [
94
+ {
95
+ from: "templates/src/pages/admin/ui-generator/Page.vue",
96
+ toSurface: "${option:surface|lower}",
97
+ toSurfacePath: "${option:directory-prefix|pathprefix}${option:name|path}/index.vue",
98
+ reason: "Install generated UI page scaffold.",
99
+ category: "ui-generator",
100
+ id: "ui-generator-page-${option:name|snake}"
101
+ }
102
+ ],
103
+ text: [
104
+ {
105
+ op: "append-text",
106
+ file: "src/placement.js",
107
+ position: "bottom",
108
+ skipIfContains: "jskit:ui-generator.page.menu:${option:surface|lower}:${option:directory-prefix|path}:${option:name|path}",
109
+ value:
110
+ "\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: \"users.web.shell.surface-aware-menu-link-item\",\n props: {\n label: \"${option:name|trim}\",\n surface: \"${option:surface|lower}\",\n workspaceSuffix: \"/${option:directory-prefix|pathprefix}${option:name|path}\",\n nonWorkspaceSuffix: \"/${option:directory-prefix|pathprefix}${option:name|path}\"\n },\n when: ({ auth }) => Boolean(auth?.authenticated)\n });\n}\n",
111
+ reason: "Append generated UI page menu placement.",
112
+ category: "ui-generator",
113
+ id: "ui-generator-page-placement-menu-${option:name|snake}",
114
+ templateContext: {
115
+ entrypoint: "src/server/buildTemplateContext.js",
116
+ export: "buildUiPageTemplateContext"
117
+ }
118
+ }
119
+ ]
120
+ }
121
+ });
package/package.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "@jskit-ai/ui-generator",
3
+ "version": "0.1.3",
4
+ "type": "module",
5
+ "scripts": {
6
+ "test": "node --test"
7
+ },
8
+ "dependencies": {
9
+ "@jskit-ai/kernel": "0.1.20"
10
+ },
11
+ "exports": {
12
+ "./server/buildTemplateContext": "./src/server/buildTemplateContext.js"
13
+ }
14
+ }
@@ -0,0 +1,17 @@
1
+ import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
2
+ import { resolveShellOutletPlacementTargetFromApp } from "@jskit-ai/kernel/server/support";
3
+
4
+ async function buildUiPageTemplateContext({ appRoot, options } = {}) {
5
+ const placementTarget = await resolveShellOutletPlacementTargetFromApp({
6
+ appRoot,
7
+ context: "ui-generator",
8
+ placement: options?.placement
9
+ });
10
+
11
+ return {
12
+ __JSKIT_UI_MENU_PLACEMENT_HOST__: normalizeText(placementTarget?.host),
13
+ __JSKIT_UI_MENU_PLACEMENT_POSITION__: normalizeText(placementTarget?.position)
14
+ };
15
+ }
16
+
17
+ export { buildUiPageTemplateContext };