@jskit-ai/workspaces-web 0.1.41 → 0.1.43
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 +98 -20
- package/package.json +11 -10
- package/src/client/components/AccountSettingsInvitesSection.vue +36 -9
- package/src/client/components/UsersWorkspaceToolsWidget.vue +0 -1
- package/src/client/components/WorkspaceMembersClientElement.vue +62 -45
- package/src/client/components/WorkspaceProfileClientElement.vue +55 -12
- package/src/client/components/WorkspaceSettingsClientElement.vue +1 -1
- package/src/client/components/WorkspaceSettingsFieldsClientElement.vue +55 -12
- package/src/client/components/WorkspacesClientElement.vue +67 -17
- package/src/shared/toolsOutletContracts.js +1 -4
- package/templates/src/components/WorkspaceNotFoundCard.vue +32 -13
- package/templates/src/pages/admin/workspace/settings/index.vue +2 -6
- package/templates/src/pages/admin/workspace/settings.vue +61 -23
- package/templates/src/surfaces/admin/index.vue +62 -14
- package/templates/src/surfaces/app/index.vue +32 -13
- package/test/exportsContract.test.js +1 -0
- package/test/settingsPlacementContract.test.js +183 -14
package/package.descriptor.mjs
CHANGED
|
@@ -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.
|
|
4
|
+
version: "0.1.43",
|
|
5
5
|
kind: "runtime",
|
|
6
6
|
description: "Workspace web module: workspace selector, tools widget, workspace surfaces, and members/settings UI.",
|
|
7
7
|
dependsOn: [
|
|
@@ -41,6 +41,10 @@ export default Object.freeze({
|
|
|
41
41
|
subpath: "./client/components/AccountSettingsInvitesSection",
|
|
42
42
|
summary: "Exports the default account invites section component used by multihoming installs."
|
|
43
43
|
},
|
|
44
|
+
{
|
|
45
|
+
subpath: "./client/components/WorkspaceSettingsClientElement",
|
|
46
|
+
summary: "Exports the workspace settings client element used by the workspace admin settings starter page."
|
|
47
|
+
},
|
|
44
48
|
{
|
|
45
49
|
subpath: "./client/providers/WorkspacesWebClientProvider",
|
|
46
50
|
summary: "Exports workspaces-web client provider class."
|
|
@@ -69,39 +73,93 @@ export default Object.freeze({
|
|
|
69
73
|
outlets: [
|
|
70
74
|
{
|
|
71
75
|
target: "admin-settings:primary-menu",
|
|
72
|
-
defaultLinkComponentToken: "local.main.ui.surface-aware-menu-link-item",
|
|
73
76
|
surfaces: ["admin"],
|
|
74
77
|
source: "templates/src/pages/admin/workspace/settings.vue"
|
|
75
78
|
},
|
|
76
79
|
{
|
|
77
80
|
target: "admin-cog:primary-menu",
|
|
78
|
-
defaultLinkComponentToken: "local.main.ui.surface-aware-menu-link-item",
|
|
79
81
|
surfaces: ["admin"],
|
|
80
82
|
source: "src/client/components/UsersWorkspaceToolsWidget.vue"
|
|
81
83
|
}
|
|
82
84
|
],
|
|
85
|
+
topology: {
|
|
86
|
+
placements: [
|
|
87
|
+
{
|
|
88
|
+
id: "page.section-nav",
|
|
89
|
+
owner: "admin-settings",
|
|
90
|
+
description: "Navigation between workspace admin settings child pages.",
|
|
91
|
+
surfaces: ["admin"],
|
|
92
|
+
variants: {
|
|
93
|
+
compact: {
|
|
94
|
+
outlet: "admin-settings:primary-menu",
|
|
95
|
+
renderers: {
|
|
96
|
+
link: "local.main.ui.surface-aware-menu-link-item"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
medium: {
|
|
100
|
+
outlet: "admin-settings:primary-menu",
|
|
101
|
+
renderers: {
|
|
102
|
+
link: "local.main.ui.surface-aware-menu-link-item"
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
expanded: {
|
|
106
|
+
outlet: "admin-settings:primary-menu",
|
|
107
|
+
renderers: {
|
|
108
|
+
link: "local.main.ui.surface-aware-menu-link-item"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
id: "admin.tools-menu",
|
|
115
|
+
description: "Admin surface tools menu actions.",
|
|
116
|
+
surfaces: ["admin"],
|
|
117
|
+
variants: {
|
|
118
|
+
compact: {
|
|
119
|
+
outlet: "admin-cog:primary-menu",
|
|
120
|
+
renderers: {
|
|
121
|
+
link: "local.main.ui.surface-aware-menu-link-item"
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
medium: {
|
|
125
|
+
outlet: "admin-cog:primary-menu",
|
|
126
|
+
renderers: {
|
|
127
|
+
link: "local.main.ui.surface-aware-menu-link-item"
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
expanded: {
|
|
131
|
+
outlet: "admin-cog:primary-menu",
|
|
132
|
+
renderers: {
|
|
133
|
+
link: "local.main.ui.surface-aware-menu-link-item"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
},
|
|
83
140
|
contributions: [
|
|
84
141
|
{
|
|
85
142
|
id: "workspaces.workspace.menu.app",
|
|
86
|
-
target: "shell
|
|
143
|
+
target: "shell.primary-nav",
|
|
144
|
+
kind: "link",
|
|
87
145
|
surfaces: ["app"],
|
|
88
146
|
order: 50,
|
|
89
|
-
componentToken: "local.main.ui.surface-aware-menu-link-item",
|
|
90
147
|
when: "auth.authenticated === true",
|
|
91
148
|
source: "mutations.text#workspaces-web-placement-block"
|
|
92
149
|
},
|
|
93
150
|
{
|
|
94
151
|
id: "workspaces.workspace.menu.admin",
|
|
95
|
-
target: "shell
|
|
152
|
+
target: "shell.primary-nav",
|
|
153
|
+
kind: "link",
|
|
96
154
|
surfaces: ["admin"],
|
|
97
155
|
order: 60,
|
|
98
|
-
componentToken: "local.main.ui.surface-aware-menu-link-item",
|
|
99
156
|
when: "auth.authenticated === true",
|
|
100
157
|
source: "mutations.text#workspaces-web-placement-block"
|
|
101
158
|
},
|
|
102
159
|
{
|
|
103
160
|
id: "workspaces.profile.menu.surface-switch",
|
|
104
|
-
target: "auth
|
|
161
|
+
target: "auth.profile-menu",
|
|
162
|
+
kind: "component",
|
|
105
163
|
surfaces: ["*"],
|
|
106
164
|
order: 100,
|
|
107
165
|
componentToken: "workspaces.web.profile.menu.surface-switch-item",
|
|
@@ -110,7 +168,8 @@ export default Object.freeze({
|
|
|
110
168
|
},
|
|
111
169
|
{
|
|
112
170
|
id: "workspaces.workspace.selector",
|
|
113
|
-
target: "shell
|
|
171
|
+
target: "shell.identity",
|
|
172
|
+
kind: "component",
|
|
114
173
|
surfaces: ["*"],
|
|
115
174
|
order: 200,
|
|
116
175
|
componentToken: "workspaces.web.workspace.selector",
|
|
@@ -119,7 +178,8 @@ export default Object.freeze({
|
|
|
119
178
|
},
|
|
120
179
|
{
|
|
121
180
|
id: "workspaces.account.invites.cue",
|
|
122
|
-
target: "shell
|
|
181
|
+
target: "shell.status",
|
|
182
|
+
kind: "component",
|
|
123
183
|
surfaces: ["*"],
|
|
124
184
|
order: 850,
|
|
125
185
|
componentToken: "local.main.account.pending-invites.cue",
|
|
@@ -128,7 +188,9 @@ export default Object.freeze({
|
|
|
128
188
|
},
|
|
129
189
|
{
|
|
130
190
|
id: "workspaces.account.settings.invites",
|
|
131
|
-
target: "
|
|
191
|
+
target: "settings.sections",
|
|
192
|
+
owner: "account-settings",
|
|
193
|
+
kind: "component",
|
|
132
194
|
surfaces: ["account"],
|
|
133
195
|
order: 400,
|
|
134
196
|
componentToken: "local.main.account-settings.section.invites",
|
|
@@ -137,7 +199,8 @@ export default Object.freeze({
|
|
|
137
199
|
},
|
|
138
200
|
{
|
|
139
201
|
id: "workspaces.workspace.tools.widget",
|
|
140
|
-
target: "shell
|
|
202
|
+
target: "shell.status",
|
|
203
|
+
kind: "component",
|
|
141
204
|
surfaces: ["admin"],
|
|
142
205
|
order: 900,
|
|
143
206
|
componentToken: "workspaces.web.workspace.tools.widget",
|
|
@@ -145,7 +208,8 @@ export default Object.freeze({
|
|
|
145
208
|
},
|
|
146
209
|
{
|
|
147
210
|
id: "workspaces.workspace.menu.workspace-settings",
|
|
148
|
-
target: "admin-
|
|
211
|
+
target: "admin.tools-menu",
|
|
212
|
+
kind: "component",
|
|
149
213
|
surfaces: ["admin"],
|
|
150
214
|
order: 100,
|
|
151
215
|
componentToken: "workspaces.web.workspace-settings.menu-item",
|
|
@@ -153,7 +217,8 @@ export default Object.freeze({
|
|
|
153
217
|
},
|
|
154
218
|
{
|
|
155
219
|
id: "workspaces.workspace.menu.members",
|
|
156
|
-
target: "admin-
|
|
220
|
+
target: "admin.tools-menu",
|
|
221
|
+
kind: "component",
|
|
157
222
|
surfaces: ["admin"],
|
|
158
223
|
order: 200,
|
|
159
224
|
componentToken: "workspaces.web.workspace-members.menu-item",
|
|
@@ -166,9 +231,8 @@ export default Object.freeze({
|
|
|
166
231
|
mutations: {
|
|
167
232
|
dependencies: {
|
|
168
233
|
runtime: {
|
|
169
|
-
"@jskit-ai/workspaces-core": "0.1.
|
|
170
|
-
"@jskit-ai/users-web": "0.1.
|
|
171
|
-
"vuetify": "^4.0.0"
|
|
234
|
+
"@jskit-ai/workspaces-core": "0.1.43",
|
|
235
|
+
"@jskit-ai/users-web": "0.1.82"
|
|
172
236
|
},
|
|
173
237
|
dev: {}
|
|
174
238
|
},
|
|
@@ -310,7 +374,7 @@ export default Object.freeze({
|
|
|
310
374
|
position: "bottom",
|
|
311
375
|
skipIfContains: "id: \"workspaces.profile.menu.surface-switch\"",
|
|
312
376
|
value:
|
|
313
|
-
"\naddPlacement({\n id: \"workspaces.profile.menu.surface-switch\",\n target: \"auth
|
|
377
|
+
"\naddPlacement({\n id: \"workspaces.profile.menu.surface-switch\",\n target: \"auth.profile-menu\",\n kind: \"component\",\n surfaces: [\"*\"],\n order: 100,\n componentToken: \"workspaces.web.profile.menu.surface-switch-item\",\n when: ({ auth }) => auth?.authenticated === true\n});\n",
|
|
314
378
|
reason: "Append workspaces-web profile surface switch placement into app-owned placement registry.",
|
|
315
379
|
category: "workspaces-web",
|
|
316
380
|
id: "workspaces-web-profile-surface-switch-placement",
|
|
@@ -324,7 +388,7 @@ export default Object.freeze({
|
|
|
324
388
|
file: "src/placement.js",
|
|
325
389
|
position: "bottom",
|
|
326
390
|
skipIfContains: "id: \"workspaces.workspace.selector\"",
|
|
327
|
-
value: "\naddPlacement({\n id: \"workspaces.workspace.menu.app\",\n target: \"shell
|
|
391
|
+
value: "\naddPlacement({\n id: \"workspaces.workspace.menu.app\",\n target: \"shell.primary-nav\",\n kind: \"link\",\n surfaces: [\"app\"],\n order: 50,\n props: {\n label: \"Home\",\n surface: \"app\",\n scopedSuffix: \"/\",\n unscopedSuffix: \"/\",\n exact: true\n },\n when: ({ auth }) => auth?.authenticated === true\n});\n\naddPlacement({\n id: \"workspaces.workspace.menu.admin\",\n target: \"shell.primary-nav\",\n kind: \"link\",\n surfaces: [\"admin\"],\n order: 60,\n props: {\n label: \"Home\",\n surface: \"admin\",\n scopedSuffix: \"/\",\n unscopedSuffix: \"/\",\n exact: true\n },\n when: ({ auth }) => auth?.authenticated === true\n});\n\naddPlacement({\n id: \"workspaces.workspace.selector\",\n target: \"shell.identity\",\n kind: \"component\",\n surfaces: [\"*\"],\n order: 200,\n componentToken: \"workspaces.web.workspace.selector\",\n props: {\n allowOnNonWorkspaceSurface: true,\n targetSurfaceId: \"app\"\n },\n when: ({ auth }) => auth?.authenticated === true\n});\n\naddPlacement({\n id: \"workspaces.account.invites.cue\",\n target: \"shell.status\",\n kind: \"component\",\n surfaces: [\"*\"],\n order: 850,\n componentToken: \"local.main.account.pending-invites.cue\",\n when: ({ auth }) => auth?.authenticated === true\n});\n\naddPlacement({\n id: \"workspaces.workspace.tools.widget\",\n target: \"shell.status\",\n kind: \"component\",\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: \"admin.tools-menu\",\n kind: \"component\",\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: \"admin.tools-menu\",\n kind: \"component\",\n surfaces: [\"admin\"],\n order: 200,\n componentToken: \"workspaces.web.workspace-members.menu-item\"\n});\n",
|
|
328
392
|
reason: "Append workspace placement entries into app-owned placement registry.",
|
|
329
393
|
category: "workspaces-web",
|
|
330
394
|
id: "workspaces-web-placement-block",
|
|
@@ -333,13 +397,27 @@ export default Object.freeze({
|
|
|
333
397
|
in: ["personal", "workspaces"]
|
|
334
398
|
}
|
|
335
399
|
},
|
|
400
|
+
{
|
|
401
|
+
op: "append-text",
|
|
402
|
+
file: "src/placementTopology.js",
|
|
403
|
+
position: "bottom",
|
|
404
|
+
skipIfContains: "id: \"admin.tools-menu\"",
|
|
405
|
+
value: "\naddPlacementTopology({\n id: \"page.section-nav\",\n owner: \"admin-settings\",\n description: \"Navigation between workspace admin settings child pages.\",\n surfaces: [\"admin\"],\n variants: {\n compact: {\n outlet: \"admin-settings:primary-menu\",\n renderers: {\n link: \"local.main.ui.surface-aware-menu-link-item\"\n }\n },\n medium: {\n outlet: \"admin-settings:primary-menu\",\n renderers: {\n link: \"local.main.ui.surface-aware-menu-link-item\"\n }\n },\n expanded: {\n outlet: \"admin-settings:primary-menu\",\n renderers: {\n link: \"local.main.ui.surface-aware-menu-link-item\"\n }\n }\n }\n});\n\naddPlacementTopology({\n id: \"admin.tools-menu\",\n description: \"Admin surface tools menu actions.\",\n surfaces: [\"admin\"],\n variants: {\n compact: {\n outlet: \"admin-cog:primary-menu\",\n renderers: {\n link: \"local.main.ui.surface-aware-menu-link-item\"\n }\n },\n medium: {\n outlet: \"admin-cog:primary-menu\",\n renderers: {\n link: \"local.main.ui.surface-aware-menu-link-item\"\n }\n },\n expanded: {\n outlet: \"admin-cog:primary-menu\",\n renderers: {\n link: \"local.main.ui.surface-aware-menu-link-item\"\n }\n }\n }\n});\n",
|
|
406
|
+
reason: "Append workspaces-web admin semantic topology into app-owned placement topology.",
|
|
407
|
+
category: "workspaces-web",
|
|
408
|
+
id: "workspaces-web-admin-placement-topology",
|
|
409
|
+
when: {
|
|
410
|
+
config: "tenancyMode",
|
|
411
|
+
in: ["personal", "workspaces"]
|
|
412
|
+
}
|
|
413
|
+
},
|
|
336
414
|
{
|
|
337
415
|
op: "append-text",
|
|
338
416
|
file: "src/placement.js",
|
|
339
417
|
position: "bottom",
|
|
340
418
|
skipIfContains: "id: \"workspaces.account.settings.invites\"",
|
|
341
419
|
value:
|
|
342
|
-
"\naddPlacement({\n id: \"workspaces.account.settings.invites\",\n target: \"account-settings:
|
|
420
|
+
"\naddPlacement({\n id: \"workspaces.account.settings.invites\",\n target: \"settings.sections\",\n owner: \"account-settings\",\n kind: \"component\",\n surfaces: [\"account\"],\n order: 400,\n componentToken: \"local.main.account-settings.section.invites\",\n props: {\n title: \"Invites\",\n value: \"invites\",\n usesSharedRuntime: false\n },\n when: ({ auth, workspaceInvitesEnabled }) => auth?.authenticated === true && workspaceInvitesEnabled === true\n});\n",
|
|
343
421
|
reason: "Append workspaces-web account settings invites section placement into app-owned placement registry.",
|
|
344
422
|
category: "workspaces-web",
|
|
345
423
|
id: "workspaces-web-account-settings-placement",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/workspaces-web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.43",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -10,21 +10,22 @@
|
|
|
10
10
|
"./client/components/AccountSettingsInvitesSection": "./src/client/components/AccountSettingsInvitesSection.vue",
|
|
11
11
|
"./client/providers/WorkspacesWebClientProvider": "./src/client/providers/WorkspacesWebClientProvider.js",
|
|
12
12
|
"./client/components/WorkspaceMembersClientElement": "./src/client/components/WorkspaceMembersClientElement.vue",
|
|
13
|
+
"./client/components/WorkspaceSettingsClientElement": "./src/client/components/WorkspaceSettingsClientElement.vue",
|
|
13
14
|
"./client/composables/useWorkspaceRouteContext": "./src/client/composables/useWorkspaceRouteContext.js"
|
|
14
15
|
},
|
|
15
16
|
"dependencies": {
|
|
16
|
-
"@tanstack/vue-query": "5.92.12",
|
|
17
17
|
"@mdi/js": "^7.4.47",
|
|
18
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
19
|
-
"@jskit-ai/kernel": "0.1.
|
|
20
|
-
"@jskit-ai/shell-web": "0.1.
|
|
21
|
-
"@jskit-ai/users-core": "0.1.
|
|
22
|
-
"@jskit-ai/users-web": "0.1.
|
|
23
|
-
"@jskit-ai/workspaces-core": "0.1.
|
|
24
|
-
"vuetify": "^4.0.0"
|
|
18
|
+
"@jskit-ai/http-runtime": "0.1.66",
|
|
19
|
+
"@jskit-ai/kernel": "0.1.67",
|
|
20
|
+
"@jskit-ai/shell-web": "0.1.66",
|
|
21
|
+
"@jskit-ai/users-core": "0.1.77",
|
|
22
|
+
"@jskit-ai/users-web": "0.1.82",
|
|
23
|
+
"@jskit-ai/workspaces-core": "0.1.43"
|
|
25
24
|
},
|
|
26
25
|
"peerDependencies": {
|
|
26
|
+
"@tanstack/vue-query": "^5.90.5",
|
|
27
27
|
"vue": "^3.5.13",
|
|
28
|
-
"vue-router": "^5.0.4"
|
|
28
|
+
"vue-router": "^5.0.4",
|
|
29
|
+
"vuetify": "^4.0.0"
|
|
29
30
|
}
|
|
30
31
|
}
|
|
@@ -5,13 +5,13 @@ const invites = useAccountSettingsInvitesSectionRuntime();
|
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<template>
|
|
8
|
-
<v-
|
|
9
|
-
<
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
</
|
|
13
|
-
|
|
14
|
-
<
|
|
8
|
+
<v-sheet rounded="lg" border class="account-invites-section">
|
|
9
|
+
<header class="account-invites-section__header">
|
|
10
|
+
<h2 class="account-invites-section__title">Invitations</h2>
|
|
11
|
+
<p class="text-body-2 text-medium-emphasis mb-0">Accept or refuse workspace invitations.</p>
|
|
12
|
+
</header>
|
|
13
|
+
|
|
14
|
+
<div class="account-invites-section__body">
|
|
15
15
|
<template v-if="invites.isLoading.value">
|
|
16
16
|
<v-skeleton-loader type="text@2, list-item-two-line@3" />
|
|
17
17
|
</template>
|
|
@@ -67,6 +67,33 @@ const invites = useAccountSettingsInvitesSectionRuntime();
|
|
|
67
67
|
</v-list-item>
|
|
68
68
|
</v-list>
|
|
69
69
|
</template>
|
|
70
|
-
</
|
|
71
|
-
</v-
|
|
70
|
+
</div>
|
|
71
|
+
</v-sheet>
|
|
72
72
|
</template>
|
|
73
|
+
|
|
74
|
+
<style scoped>
|
|
75
|
+
.account-invites-section {
|
|
76
|
+
overflow: hidden;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.account-invites-section__header {
|
|
80
|
+
padding: 1rem 1rem 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.account-invites-section__title {
|
|
84
|
+
font-size: 1rem;
|
|
85
|
+
font-weight: 650;
|
|
86
|
+
line-height: 1.2;
|
|
87
|
+
margin: 0 0 0.25rem;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.account-invites-section__body {
|
|
91
|
+
padding: 1rem;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@media (max-width: 640px) {
|
|
95
|
+
.account-invites-section__body :deep(.v-btn) {
|
|
96
|
+
min-height: 48px;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
</style>
|
|
@@ -6,7 +6,6 @@ import { ADMIN_COG_OUTLET } from "../../shared/toolsOutletContracts.js";
|
|
|
6
6
|
<template>
|
|
7
7
|
<ShellOutletMenuWidget
|
|
8
8
|
:target="ADMIN_COG_OUTLET.target"
|
|
9
|
-
:default-link-component-token="ADMIN_COG_OUTLET.defaultLinkComponentToken"
|
|
10
9
|
:aria-label="ADMIN_COG_OUTLET.ariaLabel"
|
|
11
10
|
/>
|
|
12
11
|
</template>
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<section class="workspace-members-page">
|
|
3
|
-
<
|
|
4
|
-
{{ loadError }}
|
|
5
|
-
|
|
3
|
+
<div v-if="loadError" class="workspace-members-page__state">
|
|
4
|
+
<p class="text-body-2 text-medium-emphasis mb-4">{{ loadError }}</p>
|
|
5
|
+
<v-btn
|
|
6
|
+
v-if="canRetryLoad"
|
|
7
|
+
color="primary"
|
|
8
|
+
variant="tonal"
|
|
9
|
+
:loading="isRetryingLoad"
|
|
10
|
+
@click="refreshLoad"
|
|
11
|
+
>
|
|
12
|
+
Retry
|
|
13
|
+
</v-btn>
|
|
14
|
+
</div>
|
|
6
15
|
|
|
7
16
|
<MembersAdminClientElement
|
|
8
17
|
v-else
|
|
@@ -38,7 +47,6 @@ import { useView } from "@jskit-ai/users-web/client/composables/useView";
|
|
|
38
47
|
import { usePaths } from "@jskit-ai/users-web/client/composables/usePaths";
|
|
39
48
|
import { useAccess } from "@jskit-ai/users-web/client/composables/useAccess";
|
|
40
49
|
import { useUiFeedback } from "@jskit-ai/users-web/client/composables/runtime/useUiFeedback";
|
|
41
|
-
import { useShellWebErrorRuntime } from "@jskit-ai/shell-web/client/error";
|
|
42
50
|
import { useWorkspaceRouteContext } from "../composables/useWorkspaceRouteContext.js";
|
|
43
51
|
import { createWorkspaceRealtimeMatcher } from "../support/realtimeWorkspace.js";
|
|
44
52
|
import { buildWorkspaceQueryKey } from "../support/workspaceQueryKeys.js";
|
|
@@ -75,7 +83,6 @@ const removeMemberUserId = ref("");
|
|
|
75
83
|
|
|
76
84
|
const { route, currentSurfaceId, workspaceSlugFromRoute } = useWorkspaceRouteContext();
|
|
77
85
|
const usersPaths = usePaths();
|
|
78
|
-
const errorRuntime = useShellWebErrorRuntime();
|
|
79
86
|
const OWNERSHIP_WORKSPACE = ROUTE_VISIBILITY_WORKSPACE;
|
|
80
87
|
|
|
81
88
|
const hasRouteWorkspaceSlug = computed(() => Boolean(workspaceSlugFromRoute.value));
|
|
@@ -423,27 +430,44 @@ const loadError = computed(() => {
|
|
|
423
430
|
return "Workspace slug is required in the URL.";
|
|
424
431
|
}
|
|
425
432
|
|
|
426
|
-
return
|
|
433
|
+
return (
|
|
434
|
+
access.bootstrapError.value ||
|
|
435
|
+
workspaceSettingsView.loadError ||
|
|
436
|
+
workspaceRolesView.loadError ||
|
|
437
|
+
workspaceMembersList.loadError ||
|
|
438
|
+
workspaceInvitesList.loadError ||
|
|
439
|
+
""
|
|
440
|
+
);
|
|
427
441
|
});
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
source: "users-web.workspace-members-view",
|
|
437
|
-
severity: "error",
|
|
438
|
-
channel: "banner",
|
|
439
|
-
message: String(nextLoadError || "Unable to load workspace members."),
|
|
440
|
-
dedupeKey: `users-web.workspace-members-view:bootstrap:${nextLoadError}`,
|
|
441
|
-
dedupeWindowMs: 3000
|
|
442
|
-
});
|
|
443
|
-
},
|
|
444
|
-
{ immediate: true }
|
|
442
|
+
const canRetryLoad = computed(() => Boolean(hasRouteWorkspaceSlug.value && !access.bootstrapError.value));
|
|
443
|
+
const isRetryingLoad = computed(() =>
|
|
444
|
+
Boolean(
|
|
445
|
+
workspaceSettingsView.isFetching ||
|
|
446
|
+
workspaceRolesView.isFetching ||
|
|
447
|
+
workspaceMembersList.isFetching ||
|
|
448
|
+
workspaceInvitesList.isFetching
|
|
449
|
+
)
|
|
445
450
|
);
|
|
446
451
|
|
|
452
|
+
async function refreshLoad() {
|
|
453
|
+
if (!canRetryLoad.value) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
const jobs = [];
|
|
458
|
+
if (canInviteMembers.value) {
|
|
459
|
+
jobs.push(workspaceSettingsView.refresh());
|
|
460
|
+
}
|
|
461
|
+
if (canInviteMembers.value || canViewMembers.value) {
|
|
462
|
+
jobs.push(workspaceRolesView.refresh());
|
|
463
|
+
}
|
|
464
|
+
if (canViewMembers.value) {
|
|
465
|
+
jobs.push(workspaceMembersList.reload());
|
|
466
|
+
jobs.push(workspaceInvitesList.reload());
|
|
467
|
+
}
|
|
468
|
+
await Promise.all(jobs);
|
|
469
|
+
}
|
|
470
|
+
|
|
447
471
|
const actions = Object.freeze({
|
|
448
472
|
submitInvite,
|
|
449
473
|
submitRevokeInvite,
|
|
@@ -522,17 +546,6 @@ watch(
|
|
|
522
546
|
{ immediate: true }
|
|
523
547
|
);
|
|
524
548
|
|
|
525
|
-
watch(
|
|
526
|
-
() => workspaceMembersList.loadError,
|
|
527
|
-
(nextLoadError) => {
|
|
528
|
-
if (!nextLoadError) {
|
|
529
|
-
membersFeedback.clear();
|
|
530
|
-
return;
|
|
531
|
-
}
|
|
532
|
-
membersFeedback.error(null, nextLoadError);
|
|
533
|
-
}
|
|
534
|
-
);
|
|
535
|
-
|
|
536
549
|
watch(
|
|
537
550
|
() => workspaceInvitesList.items,
|
|
538
551
|
(nextInvites) => {
|
|
@@ -553,17 +566,6 @@ watch(
|
|
|
553
566
|
{ immediate: true }
|
|
554
567
|
);
|
|
555
568
|
|
|
556
|
-
watch(
|
|
557
|
-
() => workspaceInvitesList.loadError,
|
|
558
|
-
(nextLoadError) => {
|
|
559
|
-
if (!nextLoadError) {
|
|
560
|
-
teamFeedback.clear();
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
teamFeedback.error(null, nextLoadError);
|
|
564
|
-
}
|
|
565
|
-
);
|
|
566
|
-
|
|
567
569
|
watch(
|
|
568
570
|
() => route.fullPath,
|
|
569
571
|
() => {
|
|
@@ -671,3 +673,18 @@ async function submitRemoveMember(member) {
|
|
|
671
673
|
}
|
|
672
674
|
}
|
|
673
675
|
</script>
|
|
676
|
+
|
|
677
|
+
<style scoped>
|
|
678
|
+
.workspace-members-page__state {
|
|
679
|
+
margin-inline: auto;
|
|
680
|
+
max-width: 30rem;
|
|
681
|
+
padding: 2rem 1rem;
|
|
682
|
+
text-align: center;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
@media (max-width: 640px) {
|
|
686
|
+
.workspace-members-page__state :deep(.v-btn) {
|
|
687
|
+
min-height: 48px;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
</style>
|
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
</
|
|
7
|
-
|
|
8
|
-
<
|
|
2
|
+
<v-sheet rounded="lg" border class="workspace-profile-panel">
|
|
3
|
+
<header class="workspace-profile-panel__header">
|
|
4
|
+
<h2 class="workspace-profile-panel__title">Workspace profile</h2>
|
|
5
|
+
<p class="text-body-2 text-medium-emphasis mb-0">Name and avatar used across the workspace.</p>
|
|
6
|
+
</header>
|
|
7
|
+
|
|
8
|
+
<div class="workspace-profile-panel__body">
|
|
9
9
|
<template v-if="showSkeleton">
|
|
10
10
|
<v-skeleton-loader type="text@2, list-item-two-line@3, button" />
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
|
-
<
|
|
14
|
-
{{ addEdit.loadError }}
|
|
15
|
-
|
|
13
|
+
<div v-else-if="addEdit.loadError" class="workspace-profile-panel__state">
|
|
14
|
+
<p class="text-body-2 text-medium-emphasis mb-4">{{ addEdit.loadError }}</p>
|
|
15
|
+
<v-btn
|
|
16
|
+
v-if="addEdit.canRetryLoad"
|
|
17
|
+
color="primary"
|
|
18
|
+
variant="tonal"
|
|
19
|
+
:loading="addEdit.isFetching"
|
|
20
|
+
@click="addEdit.refresh"
|
|
21
|
+
>
|
|
22
|
+
Retry
|
|
23
|
+
</v-btn>
|
|
24
|
+
</div>
|
|
16
25
|
|
|
17
26
|
<p v-else-if="!addEdit.canView" class="text-body-2 text-medium-emphasis mb-4">
|
|
18
27
|
You do not have permission to view workspace profile.
|
|
@@ -62,8 +71,8 @@
|
|
|
62
71
|
</v-row>
|
|
63
72
|
</v-form>
|
|
64
73
|
</template>
|
|
65
|
-
</
|
|
66
|
-
</v-
|
|
74
|
+
</div>
|
|
75
|
+
</v-sheet>
|
|
67
76
|
</template>
|
|
68
77
|
|
|
69
78
|
<script setup>
|
|
@@ -110,3 +119,37 @@ const addEdit = useAddEdit({
|
|
|
110
119
|
|
|
111
120
|
const showSkeleton = computed(() => Boolean(addEdit.isInitialLoading));
|
|
112
121
|
</script>
|
|
122
|
+
|
|
123
|
+
<style scoped>
|
|
124
|
+
.workspace-profile-panel {
|
|
125
|
+
overflow: hidden;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.workspace-profile-panel__header {
|
|
129
|
+
padding: 1rem 1rem 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.workspace-profile-panel__title {
|
|
133
|
+
font-size: 1rem;
|
|
134
|
+
font-weight: 650;
|
|
135
|
+
line-height: 1.2;
|
|
136
|
+
margin: 0 0 0.25rem;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.workspace-profile-panel__body {
|
|
140
|
+
padding: 1rem;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.workspace-profile-panel__state {
|
|
144
|
+
margin-inline: auto;
|
|
145
|
+
max-width: 30rem;
|
|
146
|
+
padding: 1.5rem 1rem;
|
|
147
|
+
text-align: center;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@media (max-width: 640px) {
|
|
151
|
+
.workspace-profile-panel__body :deep(.v-btn) {
|
|
152
|
+
min-height: 48px;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<section class="workspace-settings-client-element">
|
|
2
|
+
<section class="workspace-settings-client-element d-flex flex-column ga-4">
|
|
3
3
|
<WorkspaceProfileClientElement @saved="handleFormSaved" />
|
|
4
4
|
<WorkspaceSettingsFieldsClientElement @saved="handleFormSaved" />
|
|
5
5
|
</section>
|