@jskit-ai/workspaces-web 0.1.18 → 0.1.19

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/workspaces-web",
4
- version: "0.1.18",
4
+ version: "0.1.19",
5
5
  kind: "runtime",
6
6
  description: "Workspace web module: workspace selector, tools widget, workspace surfaces, and members/settings UI.",
7
7
  dependsOn: [
@@ -71,6 +71,24 @@ export default Object.freeze({
71
71
  }
72
72
  ],
73
73
  contributions: [
74
+ {
75
+ id: "workspaces.workspace.menu.app",
76
+ target: "shell-layout:primary-menu",
77
+ surfaces: ["app"],
78
+ order: 50,
79
+ componentToken: "local.main.ui.surface-aware-menu-link-item",
80
+ when: "auth.authenticated === true",
81
+ source: "mutations.text#workspaces-web-placement-block"
82
+ },
83
+ {
84
+ id: "workspaces.workspace.menu.admin",
85
+ target: "shell-layout:primary-menu",
86
+ surfaces: ["admin"],
87
+ order: 60,
88
+ componentToken: "local.main.ui.surface-aware-menu-link-item",
89
+ when: "auth.authenticated === true",
90
+ source: "mutations.text#workspaces-web-placement-block"
91
+ },
74
92
  {
75
93
  id: "workspaces.profile.menu.surface-switch",
76
94
  target: "auth-profile-menu:primary-menu",
@@ -129,8 +147,8 @@ export default Object.freeze({
129
147
  mutations: {
130
148
  dependencies: {
131
149
  runtime: {
132
- "@jskit-ai/workspaces-core": "0.1.18",
133
- "@jskit-ai/users-web": "0.1.57",
150
+ "@jskit-ai/workspaces-core": "0.1.19",
151
+ "@jskit-ai/users-web": "0.1.58",
134
152
  "vuetify": "^4.0.0"
135
153
  },
136
154
  dev: {}
@@ -280,7 +298,7 @@ export default Object.freeze({
280
298
  file: "src/placement.js",
281
299
  position: "bottom",
282
300
  skipIfContains: "id: \"workspaces.workspace.selector\"",
283
- value: "\naddPlacement({\n id: \"workspaces.workspace.selector\",\n target: \"shell-layout:top-left\",\n surfaces: [\"*\"],\n order: 200,\n componentToken: \"workspaces.web.workspace.selector\",\n props: {\n allowOnNonWorkspaceSurface: true,\n targetSurfaceId: \"app\"\n },\n when: ({ auth }) => {\n return Boolean(auth?.authenticated);\n }\n});\n\naddPlacement({\n id: \"workspaces.account.invites.cue\",\n target: \"shell-layout:top-right\",\n surfaces: [\"*\"],\n order: 850,\n componentToken: \"local.main.account.pending-invites.cue\",\n when: ({ auth }) => Boolean(auth?.authenticated)\n});\n\naddPlacement({\n id: \"workspaces.workspace.tools.widget\",\n target: \"shell-layout:top-right\",\n surfaces: [\"admin\"],\n order: 900,\n componentToken: \"workspaces.web.workspace.tools.widget\"\n});\n\naddPlacement({\n id: \"workspaces.workspace.menu.workspace-settings\",\n target: \"workspace-tools:primary-menu\",\n surfaces: [\"admin\"],\n order: 100,\n componentToken: \"workspaces.web.workspace-settings.menu-item\"\n});\n\naddPlacement({\n id: \"workspaces.workspace.menu.members\",\n target: \"workspace-tools:primary-menu\",\n surfaces: [\"admin\"],\n order: 200,\n componentToken: \"workspaces.web.workspace-members.menu-item\"\n});\n",
301
+ value: "\naddPlacement({\n id: \"workspaces.workspace.menu.app\",\n target: \"shell-layout:primary-menu\",\n surfaces: [\"app\"],\n order: 50,\n componentToken: \"local.main.ui.surface-aware-menu-link-item\",\n props: {\n label: \"Home\",\n surface: \"app\",\n scopedSuffix: \"/\",\n unscopedSuffix: \"/\",\n exact: true\n },\n when: ({ auth }) => Boolean(auth?.authenticated)\n});\n\naddPlacement({\n id: \"workspaces.workspace.menu.admin\",\n target: \"shell-layout:primary-menu\",\n surfaces: [\"admin\"],\n order: 60,\n componentToken: \"local.main.ui.surface-aware-menu-link-item\",\n props: {\n label: \"Home\",\n surface: \"admin\",\n scopedSuffix: \"/\",\n unscopedSuffix: \"/\",\n exact: true\n },\n when: ({ auth }) => Boolean(auth?.authenticated)\n});\n\naddPlacement({\n id: \"workspaces.workspace.selector\",\n target: \"shell-layout:top-left\",\n surfaces: [\"*\"],\n order: 200,\n componentToken: \"workspaces.web.workspace.selector\",\n props: {\n allowOnNonWorkspaceSurface: true,\n targetSurfaceId: \"app\"\n },\n when: ({ auth }) => {\n return Boolean(auth?.authenticated);\n }\n});\n\naddPlacement({\n id: \"workspaces.account.invites.cue\",\n target: \"shell-layout:top-right\",\n surfaces: [\"*\"],\n order: 850,\n componentToken: \"local.main.account.pending-invites.cue\",\n when: ({ auth }) => Boolean(auth?.authenticated)\n});\n\naddPlacement({\n id: \"workspaces.workspace.tools.widget\",\n target: \"shell-layout:top-right\",\n surfaces: [\"admin\"],\n order: 900,\n componentToken: \"workspaces.web.workspace.tools.widget\"\n});\n\naddPlacement({\n id: \"workspaces.workspace.menu.workspace-settings\",\n target: \"workspace-tools:primary-menu\",\n surfaces: [\"admin\"],\n order: 100,\n componentToken: \"workspaces.web.workspace-settings.menu-item\"\n});\n\naddPlacement({\n id: \"workspaces.workspace.menu.members\",\n target: \"workspace-tools:primary-menu\",\n surfaces: [\"admin\"],\n order: 200,\n componentToken: \"workspaces.web.workspace-members.menu-item\"\n});\n",
284
302
  reason: "Append workspace placement entries into app-owned placement registry.",
285
303
  category: "workspaces-web",
286
304
  id: "workspaces-web-placement-block",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/workspaces-web",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -14,12 +14,12 @@
14
14
  "dependencies": {
15
15
  "@tanstack/vue-query": "5.92.12",
16
16
  "@mdi/js": "^7.4.47",
17
- "@jskit-ai/http-runtime": "0.1.41",
18
- "@jskit-ai/kernel": "0.1.42",
19
- "@jskit-ai/shell-web": "0.1.41",
20
- "@jskit-ai/users-core": "0.1.52",
21
- "@jskit-ai/users-web": "0.1.57",
22
- "@jskit-ai/workspaces-core": "0.1.18",
17
+ "@jskit-ai/http-runtime": "0.1.42",
18
+ "@jskit-ai/kernel": "0.1.43",
19
+ "@jskit-ai/shell-web": "0.1.42",
20
+ "@jskit-ai/users-core": "0.1.53",
21
+ "@jskit-ai/users-web": "0.1.58",
22
+ "@jskit-ai/workspaces-core": "0.1.19",
23
23
  "vuetify": "^4.0.0"
24
24
  }
25
25
  }
@@ -117,8 +117,9 @@ async function navigateToWorkspace(slug) {
117
117
 
118
118
  const targetPath = paths.page("/", {
119
119
  surface: workspaceSwitchSurfaceId.value,
120
- workspaceSlug: normalizedSlug,
121
- mode: "workspace"
120
+ params: {
121
+ workspaceSlug: normalizedSlug
122
+ }
122
123
  });
123
124
  if (!targetPath) {
124
125
  errorMessage.value = "Workspace selector target surface is not configured.";
@@ -22,6 +22,13 @@ function findContribution(id) {
22
22
  : null;
23
23
  }
24
24
 
25
+ function findTextMutation(id) {
26
+ const textMutations = descriptor?.mutations?.text;
27
+ return Array.isArray(textMutations)
28
+ ? textMutations.find((entry) => String(entry?.id || "").trim() === id) || null
29
+ : null;
30
+ }
31
+
25
32
  function findFileMutation(id) {
26
33
  const fileMutations = descriptor?.mutations?.files;
27
34
  return Array.isArray(fileMutations)
@@ -63,6 +70,26 @@ test("workspaces-web descriptor metadata advertises admin settings outlets", ()
63
70
  ]
64
71
  );
65
72
  assert.equal(findContribution("workspaces.workspace.settings.general"), null);
73
+ assert.deepEqual(findContribution("workspaces.workspace.menu.app"), {
74
+ id: "workspaces.workspace.menu.app",
75
+ target: "shell-layout:primary-menu",
76
+ surfaces: ["app"],
77
+ order: 50,
78
+ componentToken: "local.main.ui.surface-aware-menu-link-item",
79
+ when: "auth.authenticated === true",
80
+ source: "mutations.text#workspaces-web-placement-block"
81
+ });
82
+ assert.deepEqual(findContribution("workspaces.workspace.menu.admin"), {
83
+ id: "workspaces.workspace.menu.admin",
84
+ target: "shell-layout:primary-menu",
85
+ surfaces: ["admin"],
86
+ order: 60,
87
+ componentToken: "local.main.ui.surface-aware-menu-link-item",
88
+ when: "auth.authenticated === true",
89
+ source: "mutations.text#workspaces-web-placement-block"
90
+ });
91
+ assert.match(findTextMutation("workspaces-web-placement-block")?.value || "", /id: "workspaces\.workspace\.menu\.app"[\s\S]*surfaces: \["app"\][\s\S]*label: "Home"/);
92
+ assert.match(findTextMutation("workspaces-web-placement-block")?.value || "", /id: "workspaces\.workspace\.menu\.admin"[\s\S]*surfaces: \["admin"\][\s\S]*label: "Home"/);
66
93
  assert.deepEqual(findContribution("workspaces.profile.menu.surface-switch"), {
67
94
  id: "workspaces.profile.menu.surface-switch",
68
95
  target: "auth-profile-menu:primary-menu",
@@ -0,0 +1,19 @@
1
+ import assert from "node:assert/strict";
2
+ import path from "node:path";
3
+ import test from "node:test";
4
+ import { fileURLToPath } from "node:url";
5
+ import { readFile } from "node:fs/promises";
6
+
7
+ const TEST_DIRECTORY = path.dirname(fileURLToPath(import.meta.url));
8
+ const PACKAGE_DIR = path.resolve(TEST_DIRECTORY, "..");
9
+ const COMPONENT_PATH = path.join(PACKAGE_DIR, "src", "client", "components", "UsersWorkspaceSelector.vue");
10
+
11
+ test("UsersWorkspaceSelector passes workspaceSlug through generic page params", async () => {
12
+ const source = await readFile(COMPONENT_PATH, "utf8");
13
+
14
+ assert.match(
15
+ source,
16
+ /paths\.page\("\/",\s*\{\s*surface:\s*workspaceSwitchSurfaceId\.value,\s*params:\s*\{\s*workspaceSlug:\s*normalizedSlug\s*\}/s
17
+ );
18
+ assert.doesNotMatch(source, /workspaceSlug:\s*normalizedSlug,\s*mode:\s*"workspace"/s);
19
+ });