@jskit-ai/users-web 0.1.67 → 0.1.69
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 +18 -13
- package/package.json +7 -7
- package/src/client/account-settings/sections.js +57 -9
- package/src/client/components/UsersHomeToolsWidget.vue +4 -4
- package/src/client/providers/UsersWebClientProvider.js +0 -5
- package/src/shared/toolsOutletContracts.js +7 -7
- package/templates/src/components/account/settings/AccountSettingsClientElement.vue +1 -1
- package/test/accountSettingsSections.test.js +68 -55
- package/test/settingsPlacementContract.test.js +19 -9
- package/src/client/providers/bootUsersWebClientProvider.js +0 -28
package/package.descriptor.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HOME_COG_OUTLET } from "./src/shared/toolsOutletContracts.js";
|
|
2
2
|
|
|
3
3
|
export default Object.freeze({
|
|
4
4
|
packageVersion: 1,
|
|
5
5
|
packageId: "@jskit-ai/users-web",
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.69",
|
|
7
7
|
kind: "runtime",
|
|
8
8
|
description: "Users web module: account/profile UI plus shared users web widgets.",
|
|
9
9
|
dependsOn: [
|
|
@@ -96,7 +96,7 @@ export default Object.freeze({
|
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
subpath: "./client/account-settings/sections",
|
|
99
|
-
summary: "Exports account settings section
|
|
99
|
+
summary: "Exports placement-backed account settings section helpers."
|
|
100
100
|
}
|
|
101
101
|
],
|
|
102
102
|
containerTokens: {
|
|
@@ -111,10 +111,15 @@ export default Object.freeze({
|
|
|
111
111
|
placements: {
|
|
112
112
|
outlets: [
|
|
113
113
|
{
|
|
114
|
-
target:
|
|
115
|
-
defaultLinkComponentToken:
|
|
114
|
+
target: HOME_COG_OUTLET.target,
|
|
115
|
+
defaultLinkComponentToken: HOME_COG_OUTLET.defaultLinkComponentToken,
|
|
116
116
|
surfaces: ["home"],
|
|
117
117
|
source: "src/client/components/UsersHomeToolsWidget.vue"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
target: "account-settings:sections",
|
|
121
|
+
surfaces: ["account"],
|
|
122
|
+
source: "templates/src/components/account/settings/AccountSettingsClientElement.vue"
|
|
118
123
|
}
|
|
119
124
|
],
|
|
120
125
|
contributions: [
|
|
@@ -138,7 +143,7 @@ export default Object.freeze({
|
|
|
138
143
|
},
|
|
139
144
|
{
|
|
140
145
|
id: "users.home.menu.settings",
|
|
141
|
-
target: "home-
|
|
146
|
+
target: "home-cog:primary-menu",
|
|
142
147
|
surfaces: ["home"],
|
|
143
148
|
order: 100,
|
|
144
149
|
componentToken: "local.main.ui.surface-aware-menu-link-item",
|
|
@@ -154,12 +159,12 @@ export default Object.freeze({
|
|
|
154
159
|
runtime: {
|
|
155
160
|
"@tanstack/vue-query": "5.92.12",
|
|
156
161
|
"@mdi/js": "^7.4.47",
|
|
157
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
158
|
-
"@jskit-ai/realtime": "0.1.
|
|
159
|
-
"@jskit-ai/kernel": "0.1.
|
|
160
|
-
"@jskit-ai/shell-web": "0.1.
|
|
161
|
-
"@jskit-ai/uploads-image-web": "0.1.
|
|
162
|
-
"@jskit-ai/users-core": "0.1.
|
|
162
|
+
"@jskit-ai/http-runtime": "0.1.53",
|
|
163
|
+
"@jskit-ai/realtime": "0.1.53",
|
|
164
|
+
"@jskit-ai/kernel": "0.1.54",
|
|
165
|
+
"@jskit-ai/shell-web": "0.1.53",
|
|
166
|
+
"@jskit-ai/uploads-image-web": "0.1.32",
|
|
167
|
+
"@jskit-ai/users-core": "0.1.64",
|
|
163
168
|
vuetify: "^4.0.0"
|
|
164
169
|
},
|
|
165
170
|
dev: {}
|
|
@@ -238,7 +243,7 @@ export default Object.freeze({
|
|
|
238
243
|
position: "bottom",
|
|
239
244
|
skipIfContains: "id: \"users.home.tools.widget\"",
|
|
240
245
|
value:
|
|
241
|
-
"\naddPlacement({\n id: \"users.home.tools.widget\",\n target: \"shell-layout:top-right\",\n surfaces: [\"home\"],\n order: 900,\n componentToken: \"users.web.home.tools.widget\",\n when: ({ auth }) => auth?.authenticated === true\n});\n\naddPlacement({\n id: \"users.home.menu.settings\",\n target: \"home-
|
|
246
|
+
"\naddPlacement({\n id: \"users.home.tools.widget\",\n target: \"shell-layout:top-right\",\n surfaces: [\"home\"],\n order: 900,\n componentToken: \"users.web.home.tools.widget\",\n when: ({ auth }) => auth?.authenticated === true\n});\n\naddPlacement({\n id: \"users.home.menu.settings\",\n target: \"home-cog:primary-menu\",\n surfaces: [\"home\"],\n order: 100,\n componentToken: \"local.main.ui.surface-aware-menu-link-item\",\n props: {\n label: \"Settings\",\n surface: \"home\",\n scopedSuffix: \"/settings\",\n unscopedSuffix: \"/settings\"\n },\n when: ({ auth }) => auth?.authenticated === true\n});\n",
|
|
242
247
|
reason: "Append users-web home tools widget and settings menu placements into app-owned placement registry.",
|
|
243
248
|
category: "users-web",
|
|
244
249
|
id: "users-web-home-tools-placement"
|
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.69",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@tanstack/vue-query": "5.92.12",
|
|
37
37
|
"@mdi/js": "^7.4.47",
|
|
38
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
39
|
-
"@jskit-ai/kernel": "0.1.
|
|
40
|
-
"@jskit-ai/realtime": "0.1.
|
|
41
|
-
"@jskit-ai/shell-web": "0.1.
|
|
42
|
-
"@jskit-ai/uploads-image-web": "0.1.
|
|
43
|
-
"@jskit-ai/users-core": "0.1.
|
|
38
|
+
"@jskit-ai/http-runtime": "0.1.53",
|
|
39
|
+
"@jskit-ai/kernel": "0.1.54",
|
|
40
|
+
"@jskit-ai/realtime": "0.1.53",
|
|
41
|
+
"@jskit-ai/shell-web": "0.1.53",
|
|
42
|
+
"@jskit-ai/uploads-image-web": "0.1.32",
|
|
43
|
+
"@jskit-ai/users-core": "0.1.64",
|
|
44
44
|
"vuetify": "^4.0.0"
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -1,21 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
computed,
|
|
3
|
+
inject,
|
|
4
|
+
onBeforeUnmount,
|
|
5
|
+
onMounted,
|
|
6
|
+
ref
|
|
7
|
+
} from "vue";
|
|
8
|
+
import { useWebPlacementContext } from "@jskit-ai/shell-web/client/placement";
|
|
2
9
|
|
|
3
|
-
const
|
|
4
|
-
const ACCOUNT_SETTINGS_SECTION_REGISTRY_TAG = "users.web.account-settings.sections";
|
|
10
|
+
const ACCOUNT_SETTINGS_SECTION_TARGET = "account-settings:sections";
|
|
5
11
|
const EMPTY_ACCOUNT_SETTINGS_SECTIONS = Object.freeze([]);
|
|
6
12
|
const RESERVED_ACCOUNT_SETTINGS_SECTION_VALUES = Object.freeze([
|
|
7
13
|
"profile",
|
|
8
14
|
"preferences",
|
|
9
15
|
"notifications"
|
|
10
16
|
]);
|
|
17
|
+
const WEB_PLACEMENT_RUNTIME_INJECTION_KEY = "jskit.shell-web.runtime.web-placement.client";
|
|
11
18
|
|
|
12
19
|
function normalizeAccountSettingsSectionEntry(entry = null) {
|
|
13
20
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
14
21
|
return null;
|
|
15
22
|
}
|
|
16
23
|
|
|
17
|
-
const
|
|
18
|
-
|
|
24
|
+
const props = entry?.props && typeof entry.props === "object" && !Array.isArray(entry.props)
|
|
25
|
+
? entry.props
|
|
26
|
+
: {};
|
|
27
|
+
const value = String(props.value || entry.value || "").trim().toLowerCase();
|
|
28
|
+
const title = String(props.title || entry.title || "").trim();
|
|
19
29
|
const component = entry.component;
|
|
20
30
|
if (!value || !title || !component) {
|
|
21
31
|
return null;
|
|
@@ -26,7 +36,7 @@ function normalizeAccountSettingsSectionEntry(entry = null) {
|
|
|
26
36
|
title,
|
|
27
37
|
component,
|
|
28
38
|
order: Number.isFinite(Number(entry.order)) ? Number(entry.order) : 500,
|
|
29
|
-
usesSharedRuntime: entry.usesSharedRuntime === true
|
|
39
|
+
usesSharedRuntime: props.usesSharedRuntime === true || entry.usesSharedRuntime === true
|
|
30
40
|
});
|
|
31
41
|
}
|
|
32
42
|
|
|
@@ -51,6 +61,7 @@ function resolveAccountSettingsSections(entries = []) {
|
|
|
51
61
|
if (!resolved || seen.has(resolved.value)) {
|
|
52
62
|
continue;
|
|
53
63
|
}
|
|
64
|
+
|
|
54
65
|
seen.add(resolved.value);
|
|
55
66
|
normalized.push(resolved);
|
|
56
67
|
}
|
|
@@ -59,12 +70,49 @@ function resolveAccountSettingsSections(entries = []) {
|
|
|
59
70
|
}
|
|
60
71
|
|
|
61
72
|
function useAccountSettingsSections() {
|
|
62
|
-
|
|
73
|
+
const placementRuntime = inject(WEB_PLACEMENT_RUNTIME_INJECTION_KEY, null);
|
|
74
|
+
const { context: placementContext } = useWebPlacementContext();
|
|
75
|
+
const revision = ref(
|
|
76
|
+
placementRuntime && typeof placementRuntime.getRevision === "function"
|
|
77
|
+
? placementRuntime.getRevision()
|
|
78
|
+
: 0
|
|
79
|
+
);
|
|
80
|
+
let unsubscribe = null;
|
|
81
|
+
|
|
82
|
+
onMounted(() => {
|
|
83
|
+
if (!placementRuntime || typeof placementRuntime.subscribe !== "function") {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
unsubscribe = placementRuntime.subscribe((event = {}) => {
|
|
87
|
+
const nextRevision = Number(event.revision);
|
|
88
|
+
revision.value = Number.isInteger(nextRevision) ? nextRevision : revision.value + 1;
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
onBeforeUnmount(() => {
|
|
93
|
+
if (typeof unsubscribe === "function") {
|
|
94
|
+
unsubscribe();
|
|
95
|
+
unsubscribe = null;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return computed(() => {
|
|
100
|
+
void revision.value;
|
|
101
|
+
if (!placementRuntime || typeof placementRuntime.getPlacements !== "function") {
|
|
102
|
+
return EMPTY_ACCOUNT_SETTINGS_SECTIONS;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const placements = placementRuntime.getPlacements({
|
|
106
|
+
surface: "account",
|
|
107
|
+
target: ACCOUNT_SETTINGS_SECTION_TARGET,
|
|
108
|
+
context: placementContext.value
|
|
109
|
+
});
|
|
110
|
+
return resolveAccountSettingsSections(placements);
|
|
111
|
+
});
|
|
63
112
|
}
|
|
64
113
|
|
|
65
114
|
export {
|
|
66
|
-
|
|
67
|
-
ACCOUNT_SETTINGS_SECTION_REGISTRY_TAG,
|
|
115
|
+
ACCOUNT_SETTINGS_SECTION_TARGET,
|
|
68
116
|
EMPTY_ACCOUNT_SETTINGS_SECTIONS,
|
|
69
117
|
RESERVED_ACCOUNT_SETTINGS_SECTION_VALUES,
|
|
70
118
|
normalizeAccountSettingsSectionEntry,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import ShellOutletMenuWidget from "@jskit-ai/shell-web/client/components/ShellOutletMenuWidget";
|
|
3
|
-
import {
|
|
3
|
+
import { HOME_COG_OUTLET } from "../../shared/toolsOutletContracts.js";
|
|
4
4
|
</script>
|
|
5
5
|
|
|
6
6
|
<template>
|
|
7
7
|
<ShellOutletMenuWidget
|
|
8
|
-
:target="
|
|
9
|
-
:default-link-component-token="
|
|
10
|
-
:aria-label="
|
|
8
|
+
:target="HOME_COG_OUTLET.target"
|
|
9
|
+
:default-link-component-token="HOME_COG_OUTLET.defaultLinkComponentToken"
|
|
10
|
+
:aria-label="HOME_COG_OUTLET.ariaLabel"
|
|
11
11
|
/>
|
|
12
12
|
</template>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import UsersHomeToolsWidget from "../components/UsersHomeToolsWidget.vue";
|
|
2
2
|
import ProfileClientElement from "../components/ProfileClientElement.vue";
|
|
3
|
-
import { bootUsersWebClientProvider } from "./bootUsersWebClientProvider.js";
|
|
4
3
|
|
|
5
4
|
class UsersWebClientProvider {
|
|
6
5
|
static id = "users.web.client";
|
|
@@ -14,10 +13,6 @@ class UsersWebClientProvider {
|
|
|
14
13
|
app.singleton("users.web.home.tools.widget", () => UsersHomeToolsWidget);
|
|
15
14
|
app.singleton("users.web.profile.element", () => ProfileClientElement);
|
|
16
15
|
}
|
|
17
|
-
|
|
18
|
-
async boot(app) {
|
|
19
|
-
await bootUsersWebClientProvider(app);
|
|
20
|
-
}
|
|
21
16
|
}
|
|
22
17
|
|
|
23
18
|
export { UsersWebClientProvider };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
const
|
|
1
|
+
const DEFAULT_COG_LINK_COMPONENT_TOKEN = "local.main.ui.surface-aware-menu-link-item";
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
target: "home-
|
|
5
|
-
defaultLinkComponentToken:
|
|
6
|
-
ariaLabel: "Home
|
|
3
|
+
const HOME_COG_OUTLET = Object.freeze({
|
|
4
|
+
target: "home-cog:primary-menu",
|
|
5
|
+
defaultLinkComponentToken: DEFAULT_COG_LINK_COMPONENT_TOKEN,
|
|
6
|
+
ariaLabel: "Home cog"
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
export {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
DEFAULT_COG_LINK_COMPONENT_TOKEN,
|
|
11
|
+
HOME_COG_OUTLET
|
|
12
12
|
};
|
|
@@ -1,79 +1,92 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import test from "node:test";
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
ACCOUNT_SETTINGS_SECTION_TARGET,
|
|
5
|
+
normalizeAccountSettingsSectionEntry,
|
|
5
6
|
resolveAccountSettingsSections
|
|
6
7
|
} from "../src/client/account-settings/sections.js";
|
|
7
|
-
import { bootUsersWebClientProvider } from "../src/client/providers/bootUsersWebClientProvider.js";
|
|
8
8
|
|
|
9
|
-
test("
|
|
9
|
+
test("account settings sections use the standard placement target", () => {
|
|
10
|
+
assert.equal(ACCOUNT_SETTINGS_SECTION_TARGET, "account-settings:sections");
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test("resolveAccountSettingsSections normalizes, deduplicates, and sorts placement-backed account section entries", () => {
|
|
10
14
|
const SectionA = {};
|
|
11
15
|
const SectionB = {};
|
|
12
16
|
|
|
13
17
|
const resolved = resolveAccountSettingsSections([
|
|
14
|
-
{
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
test("bootUsersWebClientProvider provides normalized account section extensions", async () => {
|
|
31
|
-
const SectionComponent = {};
|
|
32
|
-
const provided = new Map();
|
|
33
|
-
let resolvedTagName = "";
|
|
34
|
-
|
|
35
|
-
await bootUsersWebClientProvider({
|
|
36
|
-
make(token) {
|
|
37
|
-
if (token === "jskit.client.vue.app") {
|
|
38
|
-
return {
|
|
39
|
-
provide(key, value) {
|
|
40
|
-
provided.set(key, value);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
18
|
+
{
|
|
19
|
+
id: "users.notifications.duplicate",
|
|
20
|
+
order: 999,
|
|
21
|
+
component: SectionA,
|
|
22
|
+
props: {
|
|
23
|
+
value: "notifications",
|
|
24
|
+
title: "Ignore duplicate"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "workspaces.invites",
|
|
29
|
+
order: 400,
|
|
30
|
+
component: SectionA,
|
|
31
|
+
props: {
|
|
32
|
+
value: "invites",
|
|
33
|
+
title: "Invites"
|
|
43
34
|
}
|
|
44
|
-
throw new Error(`Unexpected token: ${token}`);
|
|
45
35
|
},
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
36
|
+
{
|
|
37
|
+
id: "invalid.missing-component",
|
|
38
|
+
order: 250,
|
|
39
|
+
props: {
|
|
40
|
+
value: "profile",
|
|
41
|
+
title: "Broken missing component"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "security.section",
|
|
46
|
+
order: 350,
|
|
47
|
+
component: SectionB,
|
|
48
|
+
props: {
|
|
49
|
+
value: "security",
|
|
50
|
+
title: "Security",
|
|
51
|
+
usesSharedRuntime: true
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "workspaces.invites.duplicate",
|
|
56
|
+
order: 100,
|
|
57
|
+
component: SectionB,
|
|
58
|
+
props: {
|
|
59
|
+
value: "invites",
|
|
60
|
+
title: "Second duplicate"
|
|
61
|
+
}
|
|
57
62
|
}
|
|
58
|
-
|
|
63
|
+
]);
|
|
59
64
|
|
|
60
|
-
assert.equal(resolvedTagName, ACCOUNT_SETTINGS_SECTION_REGISTRY_TAG);
|
|
61
|
-
const [providedSections] = [...provided.values()];
|
|
62
|
-
assert.equal(Array.isArray(providedSections), true);
|
|
63
65
|
assert.deepEqual(
|
|
64
|
-
|
|
66
|
+
resolved.map((entry) => ({
|
|
65
67
|
value: entry.value,
|
|
66
68
|
title: entry.title,
|
|
67
69
|
order: entry.order,
|
|
68
70
|
usesSharedRuntime: entry.usesSharedRuntime
|
|
69
71
|
})),
|
|
70
72
|
[
|
|
71
|
-
{
|
|
72
|
-
|
|
73
|
-
title: "Invites",
|
|
74
|
-
order: 400,
|
|
75
|
-
usesSharedRuntime: false
|
|
76
|
-
}
|
|
73
|
+
{ value: "security", title: "Security", order: 350, usesSharedRuntime: true },
|
|
74
|
+
{ value: "invites", title: "Invites", order: 400, usesSharedRuntime: false }
|
|
77
75
|
]
|
|
78
76
|
);
|
|
79
77
|
});
|
|
78
|
+
|
|
79
|
+
test("normalizeAccountSettingsSectionEntry rejects malformed placement entries", () => {
|
|
80
|
+
assert.equal(normalizeAccountSettingsSectionEntry(null), null);
|
|
81
|
+
assert.equal(normalizeAccountSettingsSectionEntry({}), null);
|
|
82
|
+
assert.equal(
|
|
83
|
+
normalizeAccountSettingsSectionEntry({
|
|
84
|
+
component: {},
|
|
85
|
+
props: {
|
|
86
|
+
value: "",
|
|
87
|
+
title: "Broken"
|
|
88
|
+
}
|
|
89
|
+
}),
|
|
90
|
+
null
|
|
91
|
+
);
|
|
92
|
+
});
|
|
@@ -71,27 +71,37 @@ function expectTextMutation(id, { reason = "", category = "", skipIfContains = "
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
test("users-web home tools widget exposes home-
|
|
74
|
+
test("users-web home tools widget exposes home-cog outlet", async () => {
|
|
75
75
|
const source = await readFile(path.join(PACKAGE_DIR, "src", "client", "components", "UsersHomeToolsWidget.vue"), "utf8");
|
|
76
76
|
|
|
77
|
-
assert.match(source, /import \{
|
|
77
|
+
assert.match(source, /import \{ HOME_COG_OUTLET \} from "\.\.\/\.\.\/shared\/toolsOutletContracts\.js";/);
|
|
78
78
|
assert.match(source, /<ShellOutletMenuWidget/);
|
|
79
|
-
assert.match(source, /:target="
|
|
80
|
-
assert.match(source, /:default-link-component-token="
|
|
79
|
+
assert.match(source, /:target="HOME_COG_OUTLET\.target"/);
|
|
80
|
+
assert.match(source, /:default-link-component-token="HOME_COG_OUTLET\.defaultLinkComponentToken"/);
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
-
test("users-web descriptor metadata advertises home
|
|
83
|
+
test("users-web descriptor metadata advertises home cog outlet and standard home settings placements", () => {
|
|
84
84
|
assert.deepEqual(
|
|
85
|
-
readOutlets("home-
|
|
85
|
+
readOutlets("home-cog:primary-menu"),
|
|
86
86
|
[
|
|
87
87
|
{
|
|
88
|
-
target: "home-
|
|
88
|
+
target: "home-cog:primary-menu",
|
|
89
89
|
defaultLinkComponentToken: "local.main.ui.surface-aware-menu-link-item",
|
|
90
90
|
surfaces: ["home"],
|
|
91
91
|
source: "src/client/components/UsersHomeToolsWidget.vue"
|
|
92
92
|
}
|
|
93
93
|
]
|
|
94
94
|
);
|
|
95
|
+
assert.deepEqual(
|
|
96
|
+
readOutlets("account-settings:sections"),
|
|
97
|
+
[
|
|
98
|
+
{
|
|
99
|
+
target: "account-settings:sections",
|
|
100
|
+
surfaces: ["account"],
|
|
101
|
+
source: "templates/src/components/account/settings/AccountSettingsClientElement.vue"
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
);
|
|
95
105
|
|
|
96
106
|
expectContribution("users.profile.menu.settings", {
|
|
97
107
|
target: "auth-profile-menu:primary-menu",
|
|
@@ -112,7 +122,7 @@ test("users-web descriptor metadata advertises home tools outlet and standard ho
|
|
|
112
122
|
});
|
|
113
123
|
|
|
114
124
|
expectContribution("users.home.menu.settings", {
|
|
115
|
-
target: "home-
|
|
125
|
+
target: "home-cog:primary-menu",
|
|
116
126
|
surfaces: ["home"],
|
|
117
127
|
order: 100,
|
|
118
128
|
componentToken: "local.main.ui.surface-aware-menu-link-item",
|
|
@@ -129,7 +139,7 @@ test("users-web descriptor metadata advertises home tools outlet and standard ho
|
|
|
129
139
|
'id: "users.home.tools.widget"',
|
|
130
140
|
'componentToken: "users.web.home.tools.widget"',
|
|
131
141
|
'id: "users.home.menu.settings"',
|
|
132
|
-
'target: "home-
|
|
142
|
+
'target: "home-cog:primary-menu"',
|
|
133
143
|
'componentToken: "local.main.ui.surface-aware-menu-link-item"',
|
|
134
144
|
'scopedSuffix: "/settings"',
|
|
135
145
|
'unscopedSuffix: "/settings"'
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ACCOUNT_SETTINGS_SECTIONS_INJECTION_KEY,
|
|
3
|
-
ACCOUNT_SETTINGS_SECTION_REGISTRY_TAG,
|
|
4
|
-
resolveAccountSettingsSections
|
|
5
|
-
} from "../account-settings/sections.js";
|
|
6
|
-
|
|
7
|
-
async function bootUsersWebClientProvider(app) {
|
|
8
|
-
if (!app || typeof app.make !== "function") {
|
|
9
|
-
throw new Error("bootUsersWebClientProvider requires application make().");
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const vueApp = app.make("jskit.client.vue.app");
|
|
13
|
-
if (!vueApp || typeof vueApp.provide !== "function") {
|
|
14
|
-
throw new Error("bootUsersWebClientProvider requires jskit.client.vue.app provide().");
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const extensionSections =
|
|
18
|
-
typeof app.resolveTag === "function"
|
|
19
|
-
? app.resolveTag(ACCOUNT_SETTINGS_SECTION_REGISTRY_TAG)
|
|
20
|
-
: [];
|
|
21
|
-
|
|
22
|
-
vueApp.provide(
|
|
23
|
-
ACCOUNT_SETTINGS_SECTIONS_INJECTION_KEY,
|
|
24
|
-
resolveAccountSettingsSections(extensionSections)
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export { bootUsersWebClientProvider };
|