@jskit-ai/users-web 0.1.52 → 0.1.53
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/package.descriptor.mjs +7 -51
- package/package.json +7 -7
- package/src/client/lib/menuIcons.js +1 -10
- package/test/bootstrapPlacementRuntime.test.js +10 -10
- package/test/menuIcons.test.js +1 -2
- package/test/profileSurfaceMenuLinks.test.js +16 -15
- package/test/settingsPlacementContract.test.js +0 -38
- package/test/surfaceAccessPolicy.test.js +11 -11
- package/test/workspaceLinkResolver.test.js +2 -2
- package/test/workspaceSurfacePaths.test.js +2 -2
- package/src/client/components/ConsoleSettingsClientElement.vue +0 -24
- package/templates/src/pages/console/settings/index.vue +0 -8
- package/templates/src/pages/console/settings.vue +0 -32
package/package.descriptor.mjs
CHANGED
|
@@ -6,12 +6,11 @@ import {
|
|
|
6
6
|
export default Object.freeze({
|
|
7
7
|
packageVersion: 1,
|
|
8
8
|
packageId: "@jskit-ai/users-web",
|
|
9
|
-
version: "0.1.
|
|
9
|
+
version: "0.1.53",
|
|
10
10
|
kind: "runtime",
|
|
11
11
|
description: "Users web module: account/profile UI plus shared users web widgets.",
|
|
12
12
|
dependsOn: [
|
|
13
13
|
"@jskit-ai/auth-web",
|
|
14
|
-
"@jskit-ai/console-web",
|
|
15
14
|
"@jskit-ai/http-runtime",
|
|
16
15
|
"@jskit-ai/shell-web",
|
|
17
16
|
"@jskit-ai/uploads-image-web",
|
|
@@ -116,12 +115,6 @@ export default Object.freeze({
|
|
|
116
115
|
surfaces: ["admin"],
|
|
117
116
|
source: "src/client/components/UsersWorkspaceToolsWidget.vue"
|
|
118
117
|
},
|
|
119
|
-
{
|
|
120
|
-
target: "console-settings:primary-menu",
|
|
121
|
-
defaultLinkComponentToken: "local.main.ui.surface-aware-menu-link-item",
|
|
122
|
-
surfaces: ["console"],
|
|
123
|
-
source: "templates/src/pages/console/settings.vue"
|
|
124
|
-
}
|
|
125
118
|
],
|
|
126
119
|
contributions: [
|
|
127
120
|
{
|
|
@@ -142,15 +135,6 @@ export default Object.freeze({
|
|
|
142
135
|
when: "auth.authenticated === true",
|
|
143
136
|
source: "mutations.text#users-web-profile-settings-placement"
|
|
144
137
|
},
|
|
145
|
-
{
|
|
146
|
-
id: "users.console.menu.settings",
|
|
147
|
-
target: "shell-layout:primary-menu",
|
|
148
|
-
surfaces: ["console"],
|
|
149
|
-
order: 100,
|
|
150
|
-
componentToken: "local.main.ui.menu-link-item",
|
|
151
|
-
when: "auth.authenticated === true",
|
|
152
|
-
source: "mutations.text#users-web-console-settings-placement"
|
|
153
|
-
},
|
|
154
138
|
{
|
|
155
139
|
id: "users.home.tools.widget",
|
|
156
140
|
target: "shell-layout:top-right",
|
|
@@ -178,13 +162,12 @@ export default Object.freeze({
|
|
|
178
162
|
runtime: {
|
|
179
163
|
"@tanstack/vue-query": "5.92.12",
|
|
180
164
|
"@mdi/js": "^7.4.47",
|
|
181
|
-
"@jskit-ai/
|
|
182
|
-
"@jskit-ai/
|
|
183
|
-
"@jskit-ai/
|
|
184
|
-
"@jskit-ai/
|
|
185
|
-
"@jskit-ai/
|
|
186
|
-
"@jskit-ai/
|
|
187
|
-
"@jskit-ai/users-core": "0.1.47",
|
|
165
|
+
"@jskit-ai/http-runtime": "0.1.37",
|
|
166
|
+
"@jskit-ai/realtime": "0.1.37",
|
|
167
|
+
"@jskit-ai/kernel": "0.1.38",
|
|
168
|
+
"@jskit-ai/shell-web": "0.1.37",
|
|
169
|
+
"@jskit-ai/uploads-image-web": "0.1.16",
|
|
170
|
+
"@jskit-ai/users-core": "0.1.48",
|
|
188
171
|
vuetify: "^4.0.0"
|
|
189
172
|
},
|
|
190
173
|
dev: {}
|
|
@@ -239,22 +222,6 @@ export default Object.freeze({
|
|
|
239
222
|
reason: "Install app-owned account settings invites section scaffold.",
|
|
240
223
|
category: "users-web",
|
|
241
224
|
id: "users-web-component-account-settings-invites"
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
from: "templates/src/pages/console/settings.vue",
|
|
245
|
-
toSurface: "console",
|
|
246
|
-
toSurfacePath: "settings.vue",
|
|
247
|
-
reason: "Install console settings shell route scaffold for users-web console UI.",
|
|
248
|
-
category: "users-web",
|
|
249
|
-
id: "users-web-page-console-settings-shell"
|
|
250
|
-
},
|
|
251
|
-
{
|
|
252
|
-
from: "templates/src/pages/console/settings/index.vue",
|
|
253
|
-
toSurface: "console",
|
|
254
|
-
toSurfacePath: "settings/index.vue",
|
|
255
|
-
reason: "Install console settings index stub scaffold for app-owned landing or redirect behavior.",
|
|
256
|
-
category: "users-web",
|
|
257
|
-
id: "users-web-page-console-settings"
|
|
258
225
|
}
|
|
259
226
|
],
|
|
260
227
|
text: [
|
|
@@ -291,17 +258,6 @@ export default Object.freeze({
|
|
|
291
258
|
category: "users-web",
|
|
292
259
|
id: "users-web-profile-settings-placement"
|
|
293
260
|
},
|
|
294
|
-
{
|
|
295
|
-
op: "append-text",
|
|
296
|
-
file: "src/placement.js",
|
|
297
|
-
position: "bottom",
|
|
298
|
-
skipIfContains: "id: \"users.console.menu.settings\"",
|
|
299
|
-
value:
|
|
300
|
-
"\naddPlacement({\n id: \"users.console.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 }) => Boolean(auth?.authenticated)\n});\n",
|
|
301
|
-
reason: "Append users-web console settings menu placement into app-owned placement registry.",
|
|
302
|
-
category: "users-web",
|
|
303
|
-
id: "users-web-console-settings-placement"
|
|
304
|
-
},
|
|
305
261
|
{
|
|
306
262
|
op: "append-text",
|
|
307
263
|
file: "src/placement.js",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/users-web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.53",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@tanstack/vue-query": "5.92.12",
|
|
28
28
|
"@mdi/js": "^7.4.47",
|
|
29
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
30
|
-
"@jskit-ai/kernel": "0.1.
|
|
31
|
-
"@jskit-ai/realtime": "0.1.
|
|
32
|
-
"@jskit-ai/shell-web": "0.1.
|
|
33
|
-
"@jskit-ai/uploads-image-web": "0.1.
|
|
34
|
-
"@jskit-ai/users-core": "0.1.
|
|
29
|
+
"@jskit-ai/http-runtime": "0.1.37",
|
|
30
|
+
"@jskit-ai/kernel": "0.1.38",
|
|
31
|
+
"@jskit-ai/realtime": "0.1.37",
|
|
32
|
+
"@jskit-ai/shell-web": "0.1.37",
|
|
33
|
+
"@jskit-ai/uploads-image-web": "0.1.16",
|
|
34
|
+
"@jskit-ai/users-core": "0.1.48",
|
|
35
35
|
"vuetify": "^4.0.0"
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
mdiArrowRightCircleOutline,
|
|
7
7
|
mdiClipboardListOutline,
|
|
8
8
|
mdiCogOutline,
|
|
9
|
-
mdiConsoleNetworkOutline,
|
|
10
9
|
mdiFolderOutline,
|
|
11
10
|
mdiHomeVariantOutline,
|
|
12
11
|
mdiLogin,
|
|
@@ -23,8 +22,7 @@ import { normalizePathname as normalizeKernelPathname } from "@jskit-ai/kernel/s
|
|
|
23
22
|
const SURFACE_SWITCH_ICON_BY_ID = Object.freeze({
|
|
24
23
|
home: mdiHomeVariantOutline,
|
|
25
24
|
app: mdiViewDashboardOutline,
|
|
26
|
-
admin: mdiShieldCrownOutline
|
|
27
|
-
console: mdiConsoleNetworkOutline
|
|
25
|
+
admin: mdiShieldCrownOutline
|
|
28
26
|
});
|
|
29
27
|
|
|
30
28
|
function resolveExplicitIconValue(explicitIcon = "") {
|
|
@@ -157,13 +155,6 @@ function resolveMenuLinkIcon({ icon = "", label = "", to = "" } = {}) {
|
|
|
157
155
|
return mdiRobotOutline;
|
|
158
156
|
}
|
|
159
157
|
|
|
160
|
-
if (
|
|
161
|
-
normalizedLabel.includes("console") ||
|
|
162
|
-
normalizedPathname.startsWith("/console")
|
|
163
|
-
) {
|
|
164
|
-
return mdiConsoleNetworkOutline;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
158
|
if (
|
|
168
159
|
normalizedLabel.includes("admin") ||
|
|
169
160
|
normalizedPathname.includes("/admin")
|
|
@@ -993,15 +993,15 @@ test("bootstrap placement runtime enforces surface access policies after bootstr
|
|
|
993
993
|
},
|
|
994
994
|
surfaceAccessPolicies: {
|
|
995
995
|
public: {},
|
|
996
|
-
|
|
996
|
+
ops_owner: {
|
|
997
997
|
requireAuth: true,
|
|
998
|
-
requireFlagsAll: ["
|
|
998
|
+
requireFlagsAll: ["ops_owner"]
|
|
999
999
|
}
|
|
1000
1000
|
},
|
|
1001
1001
|
surfaceConfig: {
|
|
1002
1002
|
tenancyMode: "workspaces",
|
|
1003
1003
|
defaultSurfaceId: "home",
|
|
1004
|
-
enabledSurfaceIds: ["home", "
|
|
1004
|
+
enabledSurfaceIds: ["home", "ops"],
|
|
1005
1005
|
surfacesById: {
|
|
1006
1006
|
home: {
|
|
1007
1007
|
id: "home",
|
|
@@ -1011,18 +1011,18 @@ test("bootstrap placement runtime enforces surface access policies after bootstr
|
|
|
1011
1011
|
requiresWorkspace: false,
|
|
1012
1012
|
accessPolicyId: "public"
|
|
1013
1013
|
},
|
|
1014
|
-
|
|
1015
|
-
id: "
|
|
1014
|
+
ops: {
|
|
1015
|
+
id: "ops",
|
|
1016
1016
|
enabled: true,
|
|
1017
|
-
pagesRoot: "
|
|
1018
|
-
routeBase: "/
|
|
1017
|
+
pagesRoot: "ops",
|
|
1018
|
+
routeBase: "/ops",
|
|
1019
1019
|
requiresWorkspace: false,
|
|
1020
|
-
accessPolicyId: "
|
|
1020
|
+
accessPolicyId: "ops_owner"
|
|
1021
1021
|
}
|
|
1022
1022
|
}
|
|
1023
1023
|
}
|
|
1024
1024
|
});
|
|
1025
|
-
const router = createRouterStub("/
|
|
1025
|
+
const router = createRouterStub("/ops");
|
|
1026
1026
|
const runtime = createBootstrapPlacementRuntime({
|
|
1027
1027
|
app: createAppStub({
|
|
1028
1028
|
["runtime.web-placement.client"]: placementRuntime,
|
|
@@ -1037,7 +1037,7 @@ test("bootstrap placement runtime enforces surface access policies after bootstr
|
|
|
1037
1037
|
workspaces: [],
|
|
1038
1038
|
permissions: [],
|
|
1039
1039
|
surfaceAccess: {
|
|
1040
|
-
|
|
1040
|
+
opsowner: false
|
|
1041
1041
|
}
|
|
1042
1042
|
};
|
|
1043
1043
|
}
|
package/test/menuIcons.test.js
CHANGED
|
@@ -2,7 +2,6 @@ import assert from "node:assert/strict";
|
|
|
2
2
|
import test from "node:test";
|
|
3
3
|
import {
|
|
4
4
|
mdiAccountCogOutline,
|
|
5
|
-
mdiConsoleNetworkOutline,
|
|
6
5
|
mdiCogOutline,
|
|
7
6
|
mdiFolderOutline,
|
|
8
7
|
mdiLogin,
|
|
@@ -17,7 +16,7 @@ import {
|
|
|
17
16
|
|
|
18
17
|
test("resolveSurfaceSwitchIcon prefers explicit icon and maps known surfaces", () => {
|
|
19
18
|
assert.equal(resolveSurfaceSwitchIcon("admin"), mdiShieldCrownOutline);
|
|
20
|
-
assert.equal(resolveSurfaceSwitchIcon("
|
|
19
|
+
assert.equal(resolveSurfaceSwitchIcon("ops", "mdi-cog-outline"), mdiCogOutline);
|
|
21
20
|
assert.equal(resolveSurfaceSwitchIcon("admin", "custom-icon"), "custom-icon");
|
|
22
21
|
assert.equal(resolveSurfaceSwitchIcon("admin", "mdi-cog-outline"), mdiCogOutline);
|
|
23
22
|
});
|
|
@@ -11,7 +11,7 @@ function createPlacementContext({
|
|
|
11
11
|
workspace = null,
|
|
12
12
|
workspaces = [],
|
|
13
13
|
authenticated = true,
|
|
14
|
-
|
|
14
|
+
opsOwner = false
|
|
15
15
|
} = {}) {
|
|
16
16
|
return {
|
|
17
17
|
auth: {
|
|
@@ -21,7 +21,7 @@ function createPlacementContext({
|
|
|
21
21
|
workspaces,
|
|
22
22
|
permissions: [],
|
|
23
23
|
surfaceAccess: {
|
|
24
|
-
|
|
24
|
+
opsowner: opsOwner
|
|
25
25
|
},
|
|
26
26
|
surfaceAccessPolicies: {
|
|
27
27
|
public: {},
|
|
@@ -29,15 +29,15 @@ function createPlacementContext({
|
|
|
29
29
|
requireAuth: true,
|
|
30
30
|
requireWorkspaceMembership: true
|
|
31
31
|
},
|
|
32
|
-
|
|
32
|
+
ops_owner: {
|
|
33
33
|
requireAuth: true,
|
|
34
|
-
requireFlagsAll: ["
|
|
34
|
+
requireFlagsAll: ["ops_owner"]
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
surfaceConfig: {
|
|
38
38
|
tenancyMode: "workspaces",
|
|
39
39
|
defaultSurfaceId: "app",
|
|
40
|
-
enabledSurfaceIds: ["home", "app", "admin", "
|
|
40
|
+
enabledSurfaceIds: ["home", "app", "admin", "ops"],
|
|
41
41
|
surfacesById: {
|
|
42
42
|
home: {
|
|
43
43
|
id: "home",
|
|
@@ -66,14 +66,15 @@ function createPlacementContext({
|
|
|
66
66
|
requiresWorkspace: true,
|
|
67
67
|
accessPolicyId: "workspace_member"
|
|
68
68
|
},
|
|
69
|
-
|
|
70
|
-
id: "
|
|
69
|
+
ops: {
|
|
70
|
+
id: "ops",
|
|
71
71
|
enabled: true,
|
|
72
|
-
pagesRoot: "
|
|
73
|
-
routeBase: "/
|
|
72
|
+
pagesRoot: "ops",
|
|
73
|
+
routeBase: "/ops",
|
|
74
74
|
requiresAuth: true,
|
|
75
75
|
requiresWorkspace: false,
|
|
76
|
-
accessPolicyId: "
|
|
76
|
+
accessPolicyId: "ops_owner",
|
|
77
|
+
icon: "mdi-cog-outline"
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
}
|
|
@@ -165,7 +166,7 @@ test("resolvePrimarySurfaceSwitchLink hides workspace switch when slug is only i
|
|
|
165
166
|
assert.equal(link, null);
|
|
166
167
|
});
|
|
167
168
|
|
|
168
|
-
test("resolveProfileSurfaceMenuLinks includes
|
|
169
|
+
test("resolveProfileSurfaceMenuLinks includes gated non-workspace switches only for matching access flags", () => {
|
|
169
170
|
const nonOwnerContext = createPlacementContext({
|
|
170
171
|
workspace: {
|
|
171
172
|
id: 1,
|
|
@@ -177,7 +178,7 @@ test("resolveProfileSurfaceMenuLinks includes console switch only for console ow
|
|
|
177
178
|
slug: "acme"
|
|
178
179
|
}
|
|
179
180
|
],
|
|
180
|
-
|
|
181
|
+
opsOwner: false
|
|
181
182
|
});
|
|
182
183
|
const ownerContext = createPlacementContext({
|
|
183
184
|
workspace: {
|
|
@@ -190,7 +191,7 @@ test("resolveProfileSurfaceMenuLinks includes console switch only for console ow
|
|
|
190
191
|
slug: "acme"
|
|
191
192
|
}
|
|
192
193
|
],
|
|
193
|
-
|
|
194
|
+
opsOwner: true
|
|
194
195
|
});
|
|
195
196
|
|
|
196
197
|
const nonOwnerLinks = resolveProfileSurfaceMenuLinks({
|
|
@@ -202,6 +203,6 @@ test("resolveProfileSurfaceMenuLinks includes console switch only for console ow
|
|
|
202
203
|
surface: "app"
|
|
203
204
|
});
|
|
204
205
|
|
|
205
|
-
assert.equal(nonOwnerLinks.some((entry) => entry.id === "surface-switch.
|
|
206
|
-
assert.equal(ownerLinks.some((entry) => entry.id === "surface-switch.
|
|
206
|
+
assert.equal(nonOwnerLinks.some((entry) => entry.id === "surface-switch.ops"), false);
|
|
207
|
+
assert.equal(ownerLinks.some((entry) => entry.id === "surface-switch.ops"), true);
|
|
207
208
|
});
|
|
@@ -71,44 +71,6 @@ function expectTextMutation(id, { reason = "", category = "", skipIfContains = "
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
test("users-web console settings template exposes surface-derived settings outlets", async () => {
|
|
75
|
-
const source = await readFile(path.join(PACKAGE_DIR, "templates", "src", "pages", "console", "settings.vue"), "utf8");
|
|
76
|
-
|
|
77
|
-
assert.match(source, /target="console-settings:primary-menu"/);
|
|
78
|
-
assert.match(source, /default-link-component-token="local\.main\.ui\.surface-aware-menu-link-item"/);
|
|
79
|
-
assert.match(source, /<RouterView \/>/);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test("users-web console settings index template is a simple developer-owned stub", async () => {
|
|
83
|
-
const source = await readFile(path.join(PACKAGE_DIR, "templates", "src", "pages", "console", "settings", "index.vue"), "utf8");
|
|
84
|
-
|
|
85
|
-
assert.match(source, /definePage/);
|
|
86
|
-
assert.match(source, /your_child_segment/);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
test("users-web descriptor metadata advertises console settings outlets with standard positions", () => {
|
|
90
|
-
const outlets = readOutlets("console-settings:primary-menu");
|
|
91
|
-
assert.deepEqual(
|
|
92
|
-
outlets,
|
|
93
|
-
[
|
|
94
|
-
{
|
|
95
|
-
target: "console-settings:primary-menu",
|
|
96
|
-
defaultLinkComponentToken: "local.main.ui.surface-aware-menu-link-item",
|
|
97
|
-
surfaces: ["console"],
|
|
98
|
-
source: "templates/src/pages/console/settings.vue"
|
|
99
|
-
}
|
|
100
|
-
]
|
|
101
|
-
);
|
|
102
|
-
assert.deepEqual(findFileMutation("users-web-page-console-settings"), {
|
|
103
|
-
from: "templates/src/pages/console/settings/index.vue",
|
|
104
|
-
toSurface: "console",
|
|
105
|
-
toSurfacePath: "settings/index.vue",
|
|
106
|
-
reason: "Install console settings index stub scaffold for app-owned landing or redirect behavior.",
|
|
107
|
-
category: "users-web",
|
|
108
|
-
id: "users-web-page-console-settings"
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
74
|
test("users-web home tools widget exposes home-tools outlet", async () => {
|
|
113
75
|
const source = await readFile(path.join(PACKAGE_DIR, "src", "client", "components", "UsersHomeToolsWidget.vue"), "utf8");
|
|
114
76
|
|
|
@@ -15,7 +15,7 @@ function createContext(overrides = {}) {
|
|
|
15
15
|
],
|
|
16
16
|
permissions: [],
|
|
17
17
|
surfaceAccess: {
|
|
18
|
-
|
|
18
|
+
opsowner: false
|
|
19
19
|
},
|
|
20
20
|
surfaceAccessPolicies: {
|
|
21
21
|
public: {},
|
|
@@ -23,14 +23,14 @@ function createContext(overrides = {}) {
|
|
|
23
23
|
requireAuth: true,
|
|
24
24
|
requireWorkspaceMembership: true
|
|
25
25
|
},
|
|
26
|
-
|
|
26
|
+
ops_owner: {
|
|
27
27
|
requireAuth: true,
|
|
28
|
-
requireFlagsAll: ["
|
|
28
|
+
requireFlagsAll: ["ops_owner"]
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
surfaceConfig: {
|
|
32
32
|
defaultSurfaceId: "home",
|
|
33
|
-
enabledSurfaceIds: ["home", "app", "
|
|
33
|
+
enabledSurfaceIds: ["home", "app", "ops"],
|
|
34
34
|
surfacesById: {
|
|
35
35
|
home: {
|
|
36
36
|
id: "home",
|
|
@@ -46,12 +46,12 @@ function createContext(overrides = {}) {
|
|
|
46
46
|
requiresWorkspace: true,
|
|
47
47
|
accessPolicyId: "workspace_member"
|
|
48
48
|
},
|
|
49
|
-
|
|
50
|
-
id: "
|
|
49
|
+
ops: {
|
|
50
|
+
id: "ops",
|
|
51
51
|
enabled: true,
|
|
52
|
-
routeBase: "/
|
|
52
|
+
routeBase: "/ops",
|
|
53
53
|
requiresWorkspace: false,
|
|
54
|
-
accessPolicyId: "
|
|
54
|
+
accessPolicyId: "ops_owner"
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
},
|
|
@@ -98,17 +98,17 @@ test("evaluateSurfaceAccess allows unknown workspace membership when allowOnUnkn
|
|
|
98
98
|
test("evaluateSurfaceAccess enforces bootstrap surface access flags", () => {
|
|
99
99
|
const deniedDecision = evaluateSurfaceAccess({
|
|
100
100
|
context: createContext(),
|
|
101
|
-
surfaceId: "
|
|
101
|
+
surfaceId: "ops"
|
|
102
102
|
});
|
|
103
103
|
assert.equal(deniedDecision.allowed, false);
|
|
104
104
|
|
|
105
105
|
const allowedDecision = evaluateSurfaceAccess({
|
|
106
106
|
context: createContext({
|
|
107
107
|
surfaceAccess: {
|
|
108
|
-
|
|
108
|
+
opsowner: true
|
|
109
109
|
}
|
|
110
110
|
}),
|
|
111
|
-
surfaceId: "
|
|
111
|
+
surfaceId: "ops"
|
|
112
112
|
});
|
|
113
113
|
assert.equal(allowedDecision.allowed, true);
|
|
114
114
|
});
|
|
@@ -48,11 +48,11 @@ test("resolveWorkspaceShellLinkPath returns empty path for unknown non-default w
|
|
|
48
48
|
assert.equal(path, "");
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
test("resolveWorkspaceShellLinkPath returns empty path for unknown
|
|
51
|
+
test("resolveWorkspaceShellLinkPath returns empty path for unknown non-workspace surface ids", () => {
|
|
52
52
|
const context = createContext();
|
|
53
53
|
const path = resolveWorkspaceShellLinkPath({
|
|
54
54
|
context,
|
|
55
|
-
surface: "
|
|
55
|
+
surface: "ops",
|
|
56
56
|
mode: "workspace",
|
|
57
57
|
workspaceSlug: "acme"
|
|
58
58
|
});
|
|
@@ -10,12 +10,12 @@ test("resolveSurfaceWorkspacePathFromPlacementContext returns empty path without
|
|
|
10
10
|
const context = {
|
|
11
11
|
surfaceConfig: {
|
|
12
12
|
defaultSurfaceId: "home",
|
|
13
|
-
enabledSurfaceIds: ["home", "app", "admin", "
|
|
13
|
+
enabledSurfaceIds: ["home", "app", "admin", "ops"],
|
|
14
14
|
surfacesById: {
|
|
15
15
|
home: { id: "home", routeBase: "/home", requiresWorkspace: false },
|
|
16
16
|
app: { id: "app", routeBase: "/w/:workspaceSlug", requiresWorkspace: true },
|
|
17
17
|
admin: { id: "admin", routeBase: "/w/:workspaceSlug/admin", requiresWorkspace: true },
|
|
18
|
-
|
|
18
|
+
ops: { id: "ops", routeBase: "/ops", requiresWorkspace: false }
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-container fluid class="console-home pa-0">
|
|
3
|
-
<v-row class="ma-0" justify="center">
|
|
4
|
-
<v-col cols="12" sm="10" md="9" lg="7">
|
|
5
|
-
<v-sheet class="pa-6 pa-sm-8" rounded="lg" border>
|
|
6
|
-
<h1 class="text-h5 text-sm-h4 mb-3">Console settings</h1>
|
|
7
|
-
<p class="text-body-2 text-sm-body-1 mb-0">
|
|
8
|
-
No console settings sections are available yet. Install a module that adds a page and menu entry to
|
|
9
|
-
<code>console-settings:primary-menu</code>.
|
|
10
|
-
</p>
|
|
11
|
-
</v-sheet>
|
|
12
|
-
</v-col>
|
|
13
|
-
</v-row>
|
|
14
|
-
</v-container>
|
|
15
|
-
</template>
|
|
16
|
-
|
|
17
|
-
<style scoped>
|
|
18
|
-
.console-home {
|
|
19
|
-
min-height: min(100vh, 700px);
|
|
20
|
-
display: grid;
|
|
21
|
-
align-content: start;
|
|
22
|
-
padding-top: clamp(16px, 4vh, 48px);
|
|
23
|
-
}
|
|
24
|
-
</style>
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
import ShellOutlet from "@jskit-ai/shell-web/client/components/ShellOutlet";
|
|
3
|
-
import { RouterView } from "vue-router";
|
|
4
|
-
</script>
|
|
5
|
-
|
|
6
|
-
<template>
|
|
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>
|
|
31
|
-
</section>
|
|
32
|
-
</template>
|