@jskit-ai/console-web 0.1.33 → 0.1.35

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.
@@ -1,7 +1,7 @@
1
1
  export default Object.freeze({
2
2
  packageVersion: 1,
3
3
  packageId: "@jskit-ai/console-web",
4
- version: "0.1.33",
4
+ version: "0.1.35",
5
5
  kind: "runtime",
6
6
  description: "Authenticated console surface scaffold and surface policy wiring.",
7
7
  dependsOn: [
@@ -43,27 +43,56 @@ export default Object.freeze({
43
43
  outlets: [
44
44
  {
45
45
  target: "console-settings:primary-menu",
46
- defaultLinkComponentToken: "local.main.ui.surface-aware-menu-link-item",
47
46
  surfaces: ["console"],
48
47
  source: "templates/src/pages/console/settings.vue"
49
48
  }
50
49
  ],
50
+ topology: {
51
+ placements: [
52
+ {
53
+ id: "page.section-nav",
54
+ owner: "console-settings",
55
+ description: "Navigation between console settings child pages.",
56
+ surfaces: ["console"],
57
+ variants: {
58
+ compact: {
59
+ outlet: "console-settings:primary-menu",
60
+ renderers: {
61
+ link: "local.main.ui.surface-aware-menu-link-item"
62
+ }
63
+ },
64
+ medium: {
65
+ outlet: "console-settings:primary-menu",
66
+ renderers: {
67
+ link: "local.main.ui.surface-aware-menu-link-item"
68
+ }
69
+ },
70
+ expanded: {
71
+ outlet: "console-settings:primary-menu",
72
+ renderers: {
73
+ link: "local.main.ui.surface-aware-menu-link-item"
74
+ }
75
+ }
76
+ }
77
+ }
78
+ ]
79
+ },
51
80
  contributions: [
52
81
  {
53
82
  id: "console.web.profile.menu.console",
54
- target: "auth-profile-menu:primary-menu",
83
+ target: "auth.profile-menu",
84
+ kind: "link",
55
85
  surfaces: ["*"],
56
86
  order: 600,
57
- componentToken: "auth.web.profile.menu.link-item",
58
87
  when: "auth.authenticated === true && surfaceAccess.consoleowner === true && surface !== \"console\"",
59
88
  source: "mutations.text#console-web-profile-menu-console-placement"
60
89
  },
61
90
  {
62
91
  id: "console.web.menu.settings",
63
- target: "shell-layout:primary-menu",
92
+ target: "shell.primary-nav",
93
+ kind: "link",
64
94
  surfaces: ["console"],
65
95
  order: 100,
66
- componentToken: "local.main.ui.menu-link-item",
67
96
  when: "auth.authenticated === true",
68
97
  source: "mutations.text#console-web-console-settings-placement"
69
98
  }
@@ -74,9 +103,9 @@ export default Object.freeze({
74
103
  mutations: {
75
104
  dependencies: {
76
105
  runtime: {
77
- "@jskit-ai/auth-web": "0.1.66",
78
- "@jskit-ai/console-core": "0.1.28",
79
- "@jskit-ai/shell-web": "0.1.64",
106
+ "@jskit-ai/auth-web": "0.1.68",
107
+ "@jskit-ai/console-core": "0.1.30",
108
+ "@jskit-ai/shell-web": "0.1.66",
80
109
  },
81
110
  dev: {}
82
111
  },
@@ -154,7 +183,7 @@ export default Object.freeze({
154
183
  position: "bottom",
155
184
  skipIfContains: "id: \"console.web.profile.menu.console\"",
156
185
  value:
157
- "\naddPlacement({\n id: \"console.web.profile.menu.console\",\n target: \"auth-profile-menu:primary-menu\",\n surfaces: [\"*\"],\n order: 600,\n componentToken: \"auth.web.profile.menu.link-item\",\n props: {\n label: \"Go to console\",\n to: \"/console\",\n icon: \"mdi-console-network-outline\"\n },\n when: ({ auth, surfaceAccess, surface }) => {\n return auth?.authenticated === true && surfaceAccess?.consoleowner === true && surface !== \"console\";\n }\n});\n",
186
+ "\naddPlacement({\n id: \"console.web.profile.menu.console\",\n target: \"auth.profile-menu\",\n kind: \"link\",\n surfaces: [\"*\"],\n order: 600,\n props: {\n label: \"Go to console\",\n to: \"/console\",\n icon: \"mdi-console-network-outline\"\n },\n when: ({ auth, surfaceAccess, surface }) => {\n return auth?.authenticated === true && surfaceAccess?.consoleowner === true && surface !== \"console\";\n }\n});\n",
158
187
  reason: "Append owner-only console navigation entry into the authenticated profile menu outside the console surface.",
159
188
  category: "console-web",
160
189
  id: "console-web-profile-menu-console-placement"
@@ -165,10 +194,21 @@ export default Object.freeze({
165
194
  position: "bottom",
166
195
  skipIfContains: "id: \"console.web.menu.settings\"",
167
196
  value:
168
- "\naddPlacement({\n id: \"console.web.menu.settings\",\n target: \"shell-layout:primary-menu\",\n surfaces: [\"console\"],\n order: 100,\n componentToken: \"local.main.ui.menu-link-item\",\n props: {\n label: \"Settings\",\n to: \"/console/settings\",\n icon: \"mdi-cog-outline\"\n },\n when: ({ auth }) => auth?.authenticated === true\n});\n",
197
+ "\naddPlacement({\n id: \"console.web.menu.settings\",\n target: \"shell.primary-nav\",\n kind: \"link\",\n surfaces: [\"console\"],\n order: 100,\n props: {\n label: \"Settings\",\n to: \"/console/settings\",\n icon: \"mdi-cog-outline\"\n },\n when: ({ auth }) => auth?.authenticated === true\n});\n",
169
198
  reason: "Append console-web settings menu placement into app-owned placement registry.",
170
199
  category: "console-web",
171
200
  id: "console-web-console-settings-placement"
201
+ },
202
+ {
203
+ op: "append-text",
204
+ file: "src/placementTopology.js",
205
+ position: "bottom",
206
+ skipIfContains: "owner: \"console-settings\"",
207
+ value:
208
+ "\naddPlacementTopology({\n id: \"page.section-nav\",\n owner: \"console-settings\",\n description: \"Navigation between console settings child pages.\",\n surfaces: [\"console\"],\n variants: {\n compact: {\n outlet: \"console-settings:primary-menu\",\n renderers: {\n link: \"local.main.ui.surface-aware-menu-link-item\"\n }\n },\n medium: {\n outlet: \"console-settings:primary-menu\",\n renderers: {\n link: \"local.main.ui.surface-aware-menu-link-item\"\n }\n },\n expanded: {\n outlet: \"console-settings:primary-menu\",\n renderers: {\n link: \"local.main.ui.surface-aware-menu-link-item\"\n }\n }\n }\n});\n",
209
+ reason: "Append console settings semantic topology into app-owned placement topology.",
210
+ category: "console-web",
211
+ id: "console-web-settings-placement-topology"
172
212
  }
173
213
  ]
174
214
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@jskit-ai/console-web",
3
- "version": "0.1.33",
3
+ "version": "0.1.35",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
7
7
  },
8
8
  "dependencies": {
9
- "@jskit-ai/auth-web": "0.1.66",
10
- "@jskit-ai/console-core": "0.1.28",
11
- "@jskit-ai/shell-web": "0.1.64"
9
+ "@jskit-ai/auth-web": "0.1.68",
10
+ "@jskit-ai/console-core": "0.1.30",
11
+ "@jskit-ai/shell-web": "0.1.66"
12
12
  }
13
13
  }
@@ -1,24 +1,62 @@
1
1
  <template>
2
- <v-card rounded="lg" elevation="1" border>
3
- <v-card-item>
4
- <template #prepend>
5
- <v-chip color="primary" size="small" label>Console</v-chip>
6
- </template>
7
- <v-card-title class="text-h5">Operations Console</v-card-title>
8
- <v-card-subtitle>Operator tools, scripts, and diagnostics.</v-card-subtitle>
9
- </v-card-item>
10
- <v-divider />
11
- <v-card-text class="d-flex flex-column ga-4">
12
- <div class="d-flex flex-wrap ga-3">
2
+ <section class="console-home-screen d-flex flex-column ga-4">
3
+ <header class="console-home-screen__header">
4
+ <div>
5
+ <p class="text-overline text-medium-emphasis mb-1">Console</p>
6
+ <h1 class="console-home-screen__title">Operations Console</h1>
7
+ <p class="text-body-2 text-medium-emphasis mb-0">Operator tools, scripts, and diagnostics.</p>
8
+ </div>
9
+ <v-btn color="primary" variant="flat" to="/home">Back to home</v-btn>
10
+ </header>
11
+
12
+ <v-sheet rounded="lg" border class="console-home-screen__panel">
13
+ <div class="console-home-screen__status-row">
13
14
  <v-chip color="secondary" variant="tonal" label>Route: /console</v-chip>
14
15
  <v-chip color="info" variant="tonal" label>Surface status: enabled</v-chip>
15
16
  </div>
16
- <p class="text-medium-emphasis mb-0">
17
- Ideal for operator actions, scripts, and technical insights not meant for end users.
17
+ <p class="text-body-2 text-medium-emphasis mb-0">
18
+ Use this surface for operator actions and technical insights that should stay out of the end-user app.
18
19
  </p>
19
- <div>
20
- <v-btn color="primary" variant="flat" to="/home">Back to home</v-btn>
21
- </div>
22
- </v-card-text>
23
- </v-card>
20
+ </v-sheet>
21
+ </section>
24
22
  </template>
23
+
24
+ <style scoped>
25
+ .console-home-screen__header {
26
+ align-items: flex-start;
27
+ display: flex;
28
+ gap: 1rem;
29
+ justify-content: space-between;
30
+ }
31
+
32
+ .console-home-screen__title {
33
+ font-size: clamp(1.5rem, 2.5vw, 2.25rem);
34
+ font-weight: 700;
35
+ letter-spacing: -0.03em;
36
+ line-height: 1.1;
37
+ margin: 0 0 0.4rem;
38
+ }
39
+
40
+ .console-home-screen__panel {
41
+ display: grid;
42
+ gap: 1rem;
43
+ padding: 1rem;
44
+ }
45
+
46
+ .console-home-screen__status-row {
47
+ display: flex;
48
+ flex-wrap: wrap;
49
+ gap: 0.5rem;
50
+ }
51
+
52
+ @media (max-width: 640px) {
53
+ .console-home-screen__header {
54
+ flex-direction: column;
55
+ }
56
+
57
+ .console-home-screen__header :deep(.v-btn) {
58
+ min-height: 48px;
59
+ width: 100%;
60
+ }
61
+ }
62
+ </style>
@@ -1,11 +1,17 @@
1
- <script setup>
2
- // To redirect this settings shell to a child page, uncomment and edit the example below.
3
- // import { redirectToChild } from "@jskit-ai/kernel/client/pageRedirects";
4
- // definePage({
5
- // redirect: redirectToChild("your_child_segment")
6
- // });
7
- </script>
8
-
9
1
  <template>
10
- <div />
2
+ <section class="console-settings-empty">
3
+ <h2 class="text-h6 mb-2">No console settings yet</h2>
4
+ <p class="text-body-2 text-medium-emphasis mb-0">
5
+ Console settings sections will appear here when installed.
6
+ </p>
7
+ </section>
11
8
  </template>
9
+
10
+ <style scoped>
11
+ .console-settings-empty {
12
+ margin-inline: auto;
13
+ max-width: 34rem;
14
+ padding: 2rem 1.25rem;
15
+ text-align: center;
16
+ }
17
+ </style>
@@ -5,28 +5,66 @@ import { RouterView } from "vue-router";
5
5
 
6
6
  <template>
7
7
  <section class="settings-shell d-flex flex-column ga-4">
8
- <v-card rounded="lg" elevation="1" border>
9
- <v-card-item>
10
- <v-card-title>Console settings</v-card-title>
11
- <v-card-subtitle>Global configuration and reference data for the whole app.</v-card-subtitle>
12
- </v-card-item>
13
- <v-divider />
14
- <v-card-text class="pt-4">
15
- <v-row no-gutters>
16
- <v-col cols="12" md="3" lg="2" class="pr-md-4 mb-4 mb-md-0">
17
- <v-list nav density="comfortable" rounded="lg" border>
18
- <ShellOutlet
19
- target="console-settings:primary-menu"
20
- default-link-component-token="local.main.ui.surface-aware-menu-link-item"
21
- />
22
- </v-list>
23
- </v-col>
24
-
25
- <v-col cols="12" md="9" lg="10">
26
- <RouterView />
27
- </v-col>
28
- </v-row>
29
- </v-card-text>
30
- </v-card>
8
+ <header>
9
+ <p class="text-overline text-medium-emphasis mb-1">Console</p>
10
+ <h1 class="settings-shell__title">Console settings</h1>
11
+ <p class="text-body-2 text-medium-emphasis mb-0">Global configuration and reference data for the whole app.</p>
12
+ </header>
13
+
14
+ <v-sheet rounded="lg" border class="settings-shell__panel">
15
+ <nav class="settings-shell__nav" aria-label="Console settings sections">
16
+ <v-list nav density="comfortable" class="settings-shell__nav-list">
17
+ <ShellOutlet target="console-settings:primary-menu" />
18
+ </v-list>
19
+ </nav>
20
+ <main class="settings-shell__content">
21
+ <RouterView />
22
+ </main>
23
+ </v-sheet>
31
24
  </section>
32
25
  </template>
26
+
27
+ <style scoped>
28
+ .settings-shell__title {
29
+ font-size: clamp(1.35rem, 2vw, 1.85rem);
30
+ font-weight: 650;
31
+ letter-spacing: -0.02em;
32
+ line-height: 1.15;
33
+ margin: 0 0 0.35rem;
34
+ }
35
+
36
+ .settings-shell__panel {
37
+ display: grid;
38
+ gap: 1rem;
39
+ grid-template-columns: minmax(12rem, 16rem) minmax(0, 1fr);
40
+ padding: 1rem;
41
+ }
42
+
43
+ .settings-shell__nav-list {
44
+ padding: 0;
45
+ }
46
+
47
+ .settings-shell__content {
48
+ min-width: 0;
49
+ }
50
+
51
+ @media (max-width: 960px) {
52
+ .settings-shell__panel {
53
+ grid-template-columns: 1fr;
54
+ }
55
+
56
+ .settings-shell__nav {
57
+ overflow-x: auto;
58
+ }
59
+
60
+ .settings-shell__nav-list {
61
+ display: flex;
62
+ gap: 0.5rem;
63
+ min-width: max-content;
64
+ }
65
+
66
+ .settings-shell__nav-list :deep(.v-list-item) {
67
+ min-height: 48px;
68
+ }
69
+ }
70
+ </style>
@@ -22,6 +22,34 @@ function findTextMutation(id) {
22
22
  : null;
23
23
  }
24
24
 
25
+ function readOutlets(target = "") {
26
+ const outlets = descriptor?.metadata?.ui?.placements?.outlets;
27
+ const normalizedTarget = String(target || "").trim();
28
+ return Array.isArray(outlets)
29
+ ? outlets.filter((entry) => String(entry?.target || "").trim() === normalizedTarget)
30
+ : [];
31
+ }
32
+
33
+ function findTopology(id, owner = "") {
34
+ const placements = descriptor?.metadata?.ui?.placements?.topology?.placements;
35
+ const normalizedId = String(id || "").trim();
36
+ const normalizedOwner = String(owner || "").trim();
37
+ return Array.isArray(placements)
38
+ ? placements.find((entry) => {
39
+ const entryId = String(entry?.id || "").trim();
40
+ const entryOwner = String(entry?.owner || "").trim();
41
+ return entryId === normalizedId && entryOwner === normalizedOwner;
42
+ }) || null
43
+ : null;
44
+ }
45
+
46
+ function findContribution(id) {
47
+ const contributions = descriptor?.metadata?.ui?.placements?.contributions;
48
+ return Array.isArray(contributions)
49
+ ? contributions.find((entry) => String(entry?.id || "").trim() === id) || null
50
+ : null;
51
+ }
52
+
25
53
  test("console-web installs console surface scripts and files", () => {
26
54
  assert.deepEqual(descriptor?.mutations?.packageJson?.scripts, {
27
55
  "server:console": "SERVER_SURFACE=console node ./bin/server.js",
@@ -82,6 +110,49 @@ test("console-web wires console surface policy into app config", () => {
82
110
  /surfaceAccess\?\.consoleowner === true && surface !== "console"/
83
111
  );
84
112
  assert.equal(findTextMutation("console-web-console-settings-placement")?.file, "src/placement.js");
113
+ assert.equal(findTextMutation("console-web-settings-placement-topology")?.file, "src/placementTopology.js");
114
+ assert.deepEqual(readOutlets("console-settings:primary-menu"), [
115
+ {
116
+ target: "console-settings:primary-menu",
117
+ surfaces: ["console"],
118
+ source: "templates/src/pages/console/settings.vue"
119
+ }
120
+ ]);
121
+ assert.deepEqual(findTopology("page.section-nav", "console-settings"), {
122
+ id: "page.section-nav",
123
+ owner: "console-settings",
124
+ description: "Navigation between console settings child pages.",
125
+ surfaces: ["console"],
126
+ variants: {
127
+ compact: {
128
+ outlet: "console-settings:primary-menu",
129
+ renderers: {
130
+ link: "local.main.ui.surface-aware-menu-link-item"
131
+ }
132
+ },
133
+ medium: {
134
+ outlet: "console-settings:primary-menu",
135
+ renderers: {
136
+ link: "local.main.ui.surface-aware-menu-link-item"
137
+ }
138
+ },
139
+ expanded: {
140
+ outlet: "console-settings:primary-menu",
141
+ renderers: {
142
+ link: "local.main.ui.surface-aware-menu-link-item"
143
+ }
144
+ }
145
+ }
146
+ });
147
+ assert.deepEqual(findContribution("console.web.menu.settings"), {
148
+ id: "console.web.menu.settings",
149
+ target: "shell.primary-nav",
150
+ kind: "link",
151
+ surfaces: ["console"],
152
+ order: 100,
153
+ when: "auth.authenticated === true",
154
+ source: "mutations.text#console-web-console-settings-placement"
155
+ });
85
156
  });
86
157
 
87
158
  test("console-web console templates stay shell-driven", async () => {
@@ -93,9 +164,12 @@ test("console-web console templates stay shell-driven", async () => {
93
164
  assert.match(wrapperSource, /ShellLayout/);
94
165
  assert.match(wrapperSource, /"surface": "console"/);
95
166
  assert.match(indexSource, /Operations Console/);
167
+ assert.match(indexSource, /console-home-screen__panel/);
168
+ assert.doesNotMatch(indexSource, /<v-card\b|v-card-title|v-card-subtitle/);
96
169
  assert.match(settingsSource, /target="console-settings:primary-menu"/);
97
- assert.match(settingsSource, /default-link-component-token="local\.main\.ui\.surface-aware-menu-link-item"/);
170
+ assert.doesNotMatch(settingsSource, /default-link-component-token/);
171
+ assert.doesNotMatch(settingsSource, /<v-card\b/);
98
172
  assert.match(settingsSource, /<RouterView \/>/);
99
- assert.match(settingsIndexSource, /definePage/);
100
- assert.match(settingsIndexSource, /your_child_segment/);
173
+ assert.match(settingsIndexSource, /No console settings yet/);
174
+ assert.doesNotMatch(settingsIndexSource, /your_child_segment|To redirect this settings shell/);
101
175
  });