@jskit-ai/users-web 0.1.4
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 +507 -0
- package/package.json +31 -0
- package/src/client/components/ConsoleSettingsClientElement.vue +24 -0
- package/src/client/components/MembersAdminClientElement.vue +404 -0
- package/src/client/components/ProfileClientElement.vue +242 -0
- package/src/client/components/UsersProfileSurfaceSwitchMenuItem.vue +39 -0
- package/src/client/components/UsersShellMenuLinkItem.vue +140 -0
- package/src/client/components/UsersSurfaceAwareMenuLinkItem.vue +87 -0
- package/src/client/components/UsersWorkspaceMembersMenuItem.vue +36 -0
- package/src/client/components/UsersWorkspacePermissionMenuItem.vue +90 -0
- package/src/client/components/UsersWorkspaceSelector.vue +237 -0
- package/src/client/components/UsersWorkspaceSettingsMenuItem.vue +39 -0
- package/src/client/components/UsersWorkspaceToolsWidget.vue +23 -0
- package/src/client/components/WorkspaceMembersClientElement.vue +663 -0
- package/src/client/components/WorkspaceSettingsClientElement.vue +230 -0
- package/src/client/components/WorkspacesClientElement.vue +514 -0
- package/src/client/composables/accountSettingsAvatarUploadRuntime.js +241 -0
- package/src/client/composables/accountSettingsInvitesRuntime.js +88 -0
- package/src/client/composables/accountSettingsRuntimeConstants.js +77 -0
- package/src/client/composables/accountSettingsRuntimeHelpers.js +75 -0
- package/src/client/composables/errorMessageHelpers.js +66 -0
- package/src/client/composables/internal/useOperationScope.js +144 -0
- package/src/client/composables/modelStateHelpers.js +49 -0
- package/src/client/composables/operationUiHelpers.js +121 -0
- package/src/client/composables/operationValidationHelpers.js +52 -0
- package/src/client/composables/refValueHelpers.js +19 -0
- package/src/client/composables/scopeHelpers.js +145 -0
- package/src/client/composables/useAccess.js +109 -0
- package/src/client/composables/useAccountSettingsRuntime.js +533 -0
- package/src/client/composables/useAddEdit.js +135 -0
- package/src/client/composables/useAddEditCore.js +137 -0
- package/src/client/composables/useBootstrapQuery.js +52 -0
- package/src/client/composables/useCommand.js +112 -0
- package/src/client/composables/useCommandCore.js +130 -0
- package/src/client/composables/useEndpointResource.js +104 -0
- package/src/client/composables/useFieldErrorBag.js +61 -0
- package/src/client/composables/useList.js +85 -0
- package/src/client/composables/useListCore.js +65 -0
- package/src/client/composables/usePagedCollection.js +125 -0
- package/src/client/composables/usePaths.js +108 -0
- package/src/client/composables/useRealtimeQueryInvalidation.js +105 -0
- package/src/client/composables/useScopeRuntime.js +107 -0
- package/src/client/composables/useSurfaceRouteContext.js +31 -0
- package/src/client/composables/useUiFeedback.js +96 -0
- package/src/client/composables/useView.js +89 -0
- package/src/client/composables/useViewCore.js +104 -0
- package/src/client/composables/useWorkspaceRouteContext.js +28 -0
- package/src/client/composables/useWorkspaceSurfaceId.js +43 -0
- package/src/client/index.js +7 -0
- package/src/client/lib/bootstrap.js +95 -0
- package/src/client/lib/httpClient.js +67 -0
- package/src/client/lib/menuIcons.js +192 -0
- package/src/client/lib/permissions.js +34 -0
- package/src/client/lib/profileSurfaceMenuLinks.js +142 -0
- package/src/client/lib/surfaceAccessPolicy.js +350 -0
- package/src/client/lib/theme.js +99 -0
- package/src/client/lib/workspaceLinkResolver.js +207 -0
- package/src/client/lib/workspaceSurfaceContext.js +82 -0
- package/src/client/lib/workspaceSurfacePaths.js +163 -0
- package/src/client/providers/UsersWebClientProvider.js +85 -0
- package/src/client/runtime/bootstrapPlacementRouteGuards.js +371 -0
- package/src/client/runtime/bootstrapPlacementRuntime.js +413 -0
- package/src/client/runtime/bootstrapPlacementRuntimeConstants.js +32 -0
- package/src/client/runtime/bootstrapPlacementRuntimeHelpers.js +157 -0
- package/src/client/support/contractGuards.js +34 -0
- package/src/client/support/realtimeWorkspace.js +12 -0
- package/src/client/support/runtimeNormalization.js +27 -0
- package/src/client/support/workspaceQueryKeys.js +15 -0
- package/templates/packages/main/src/client/components/AccountPendingInvitesCue.vue +162 -0
- package/templates/src/components/WorkspaceNotFoundCard.vue +33 -0
- package/templates/src/components/account/settings/AccountSettingsClientElement.vue +153 -0
- package/templates/src/components/account/settings/AccountSettingsInvitesSection.vue +77 -0
- package/templates/src/components/account/settings/AccountSettingsNotificationsSection.vue +55 -0
- package/templates/src/components/account/settings/AccountSettingsPreferencesSection.vue +125 -0
- package/templates/src/components/account/settings/AccountSettingsProfileSection.vue +94 -0
- package/templates/src/composables/useWorkspaceNotFoundState.js +48 -0
- package/templates/src/pages/account/index.vue +17 -0
- package/templates/src/pages/admin/members/index.vue +7 -0
- package/templates/src/pages/admin/workspace/settings/index.vue +16 -0
- package/templates/src/pages/console/settings/index.vue +16 -0
- package/templates/src/surfaces/admin/index.vue +29 -0
- package/templates/src/surfaces/admin/root.vue +20 -0
- package/templates/src/surfaces/app/index.vue +27 -0
- package/templates/src/surfaces/app/root.vue +20 -0
- package/test/bootstrap.test.js +38 -0
- package/test/bootstrapPlacementRuntime.test.js +991 -0
- package/test/errorMessageHelpers.test.js +28 -0
- package/test/exportsContract.test.js +39 -0
- package/test/menuIcons.test.js +33 -0
- package/test/permissions.test.js +35 -0
- package/test/profileSurfaceMenuLinks.test.js +207 -0
- package/test/refValueHelpers.test.js +14 -0
- package/test/scopeHelpers.test.js +57 -0
- package/test/surfaceAccessPolicy.test.js +129 -0
- package/test/theme.test.js +95 -0
- package/test/workspaceLinkResolver.test.js +61 -0
- package/test/workspaceSurfacePaths.test.js +39 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { unref } from "vue";
|
|
2
|
+
import { resolveLinkPath } from "@jskit-ai/kernel/shared";
|
|
3
|
+
import { normalizeSurfaceId } from "@jskit-ai/kernel/shared/surface/registry";
|
|
4
|
+
import {
|
|
5
|
+
useWebPlacementContext,
|
|
6
|
+
resolveRuntimePathname,
|
|
7
|
+
resolveSurfaceDefinitionFromPlacementContext,
|
|
8
|
+
resolveSurfaceIdFromPlacementPathname,
|
|
9
|
+
resolveSurfaceRootPathFromPlacementContext
|
|
10
|
+
} from "@jskit-ai/shell-web/client/placement";
|
|
11
|
+
import {
|
|
12
|
+
resolveWorkspaceSurfaceIdFromPlacementPathname,
|
|
13
|
+
resolveSurfaceWorkspacePathFromPlacementContext,
|
|
14
|
+
extractWorkspaceSlugFromSurfacePathname
|
|
15
|
+
} from "./workspaceSurfacePaths.js";
|
|
16
|
+
import { surfaceRequiresWorkspaceFromPlacementContext } from "./workspaceSurfaceContext.js";
|
|
17
|
+
import { parseWorkspacePathname } from "@jskit-ai/users-core/shared/support/workspacePathModel";
|
|
18
|
+
|
|
19
|
+
function resolveSurfaceBasePath(context = null, surface = "") {
|
|
20
|
+
const normalizedSurface = normalizeSurfaceId(surface);
|
|
21
|
+
if (!normalizedSurface) {
|
|
22
|
+
return "";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!resolveSurfaceDefinitionFromPlacementContext(context, normalizedSurface)) {
|
|
26
|
+
return "";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return resolveSurfaceRootPathFromPlacementContext(context, normalizedSurface);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function resolveWorkspaceSlugFromContextOrPath({
|
|
33
|
+
context = null,
|
|
34
|
+
surface = "",
|
|
35
|
+
workspaceSlug = "",
|
|
36
|
+
pathname = ""
|
|
37
|
+
} = {}) {
|
|
38
|
+
const explicitWorkspaceSlug = String(workspaceSlug || "").trim();
|
|
39
|
+
if (explicitWorkspaceSlug) {
|
|
40
|
+
return explicitWorkspaceSlug;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const workspaceSlugFromContext = String(context?.workspace?.slug || "").trim();
|
|
44
|
+
if (workspaceSlugFromContext) {
|
|
45
|
+
return workspaceSlugFromContext;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const currentPathname = resolveRuntimePathname(pathname);
|
|
49
|
+
const workspaceSlugFromPath = String(parseWorkspacePathname(currentPathname)?.workspaceSlug || "").trim();
|
|
50
|
+
if (workspaceSlugFromPath) {
|
|
51
|
+
return workspaceSlugFromPath;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const normalizedSurface = normalizeSurfaceId(surface);
|
|
55
|
+
const workspaceSurfaceId = resolveWorkspaceSurfaceIdFromPlacementPathname(context, currentPathname);
|
|
56
|
+
const surfaceIdFromPath = workspaceSurfaceId || resolveSurfaceIdFromPlacementPathname(context, currentPathname);
|
|
57
|
+
const activeSurfaceId = normalizeSurfaceId(surfaceIdFromPath || normalizedSurface);
|
|
58
|
+
if (!activeSurfaceId) {
|
|
59
|
+
return "";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return String(extractWorkspaceSlugFromSurfacePathname(context, activeSurfaceId, currentPathname) || "").trim();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function resolveWorkspaceBasePath(context = null, surface = "", workspaceSlug = "") {
|
|
66
|
+
const normalizedSurface = normalizeSurfaceId(surface);
|
|
67
|
+
const normalizedWorkspaceSlug = String(workspaceSlug || "").trim();
|
|
68
|
+
if (!normalizedSurface || !normalizedWorkspaceSlug) {
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!resolveSurfaceDefinitionFromPlacementContext(context, normalizedSurface)) {
|
|
73
|
+
return "";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!surfaceRequiresWorkspaceFromPlacementContext(context, normalizedSurface)) {
|
|
77
|
+
return resolveSurfaceBasePath(context, normalizedSurface);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return resolveSurfaceWorkspacePathFromPlacementContext(context, normalizedSurface, normalizedWorkspaceSlug, "/");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function resolveWorkspaceShellLinkPath({
|
|
84
|
+
context = null,
|
|
85
|
+
surface = "",
|
|
86
|
+
mode = "auto",
|
|
87
|
+
explicitTo = "",
|
|
88
|
+
relativePath = "/",
|
|
89
|
+
workspaceRelativePath = "",
|
|
90
|
+
surfaceRelativePath = "",
|
|
91
|
+
workspaceSlug = "",
|
|
92
|
+
pathname = ""
|
|
93
|
+
} = {}) {
|
|
94
|
+
const explicitTarget = String(explicitTo || "").trim();
|
|
95
|
+
if (explicitTarget) {
|
|
96
|
+
return explicitTarget;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const normalizedSurface = normalizeSurfaceId(surface);
|
|
100
|
+
const normalizedMode = String(mode || "auto").trim().toLowerCase();
|
|
101
|
+
const hasSurfaceDefinition = Boolean(
|
|
102
|
+
normalizedSurface && resolveSurfaceDefinitionFromPlacementContext(context, normalizedSurface)
|
|
103
|
+
);
|
|
104
|
+
if (!hasSurfaceDefinition) {
|
|
105
|
+
return "";
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const resolvedWorkspaceSlug = resolveWorkspaceSlugFromContextOrPath({
|
|
109
|
+
context,
|
|
110
|
+
surface: normalizedSurface,
|
|
111
|
+
workspaceSlug,
|
|
112
|
+
pathname
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const nextWorkspaceRelativePath = String(workspaceRelativePath || "").trim() || String(relativePath || "").trim() || "/";
|
|
116
|
+
const nextSurfaceRelativePath = String(surfaceRelativePath || "").trim() || String(relativePath || "").trim() || "/";
|
|
117
|
+
const nextSurfaceBasePath = resolveSurfaceBasePath(context, normalizedSurface);
|
|
118
|
+
|
|
119
|
+
if (normalizedMode === "surface") {
|
|
120
|
+
return resolveLinkPath(nextSurfaceBasePath, nextSurfaceRelativePath);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (normalizedMode === "workspace") {
|
|
124
|
+
if (!surfaceRequiresWorkspaceFromPlacementContext(context, normalizedSurface)) {
|
|
125
|
+
return resolveLinkPath(nextSurfaceBasePath, nextSurfaceRelativePath);
|
|
126
|
+
}
|
|
127
|
+
if (!resolvedWorkspaceSlug) {
|
|
128
|
+
return "";
|
|
129
|
+
}
|
|
130
|
+
const workspaceBasePath = resolveWorkspaceBasePath(context, normalizedSurface, resolvedWorkspaceSlug);
|
|
131
|
+
if (!workspaceBasePath) {
|
|
132
|
+
return "";
|
|
133
|
+
}
|
|
134
|
+
return resolveLinkPath(
|
|
135
|
+
workspaceBasePath,
|
|
136
|
+
nextWorkspaceRelativePath
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (surfaceRequiresWorkspaceFromPlacementContext(context, normalizedSurface)) {
|
|
141
|
+
if (!resolvedWorkspaceSlug) {
|
|
142
|
+
return "";
|
|
143
|
+
}
|
|
144
|
+
const workspaceBasePath = resolveWorkspaceBasePath(context, normalizedSurface, resolvedWorkspaceSlug);
|
|
145
|
+
if (!workspaceBasePath) {
|
|
146
|
+
return "";
|
|
147
|
+
}
|
|
148
|
+
return resolveLinkPath(
|
|
149
|
+
workspaceBasePath,
|
|
150
|
+
nextWorkspaceRelativePath
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return resolveLinkPath(nextSurfaceBasePath, nextSurfaceRelativePath);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function useWorkspaceLinkResolver({ surface = "", workspaceSlug = "", pathname = "" } = {}) {
|
|
158
|
+
const { context: placementContext } = useWebPlacementContext();
|
|
159
|
+
|
|
160
|
+
function resolve(relativePath = "/", options = {}) {
|
|
161
|
+
return resolveWorkspaceShellLinkPath({
|
|
162
|
+
context: placementContext.value,
|
|
163
|
+
surface: String(unref(options.surface ?? surface) || ""),
|
|
164
|
+
workspaceSlug: String(unref(options.workspaceSlug ?? workspaceSlug) || ""),
|
|
165
|
+
pathname: String(unref(options.pathname ?? pathname) || ""),
|
|
166
|
+
mode: String(options.mode || "auto"),
|
|
167
|
+
explicitTo: options.explicitTo,
|
|
168
|
+
relativePath,
|
|
169
|
+
workspaceRelativePath: options.workspaceRelativePath,
|
|
170
|
+
surfaceRelativePath: options.surfaceRelativePath
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function toSurface(relativePath = "/", options = {}) {
|
|
175
|
+
return resolve(relativePath, {
|
|
176
|
+
...options,
|
|
177
|
+
mode: "surface"
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function toWorkspace(relativePath = "/", options = {}) {
|
|
182
|
+
return resolve(relativePath, {
|
|
183
|
+
...options,
|
|
184
|
+
mode: "workspace"
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function toAuto(relativePath = "/", options = {}) {
|
|
189
|
+
return resolve(relativePath, {
|
|
190
|
+
...options,
|
|
191
|
+
mode: "auto"
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return Object.freeze({
|
|
196
|
+
resolve,
|
|
197
|
+
toSurface,
|
|
198
|
+
toWorkspace,
|
|
199
|
+
toAuto
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export {
|
|
204
|
+
resolveWorkspaceSlugFromContextOrPath,
|
|
205
|
+
resolveWorkspaceShellLinkPath,
|
|
206
|
+
useWorkspaceLinkResolver
|
|
207
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { normalizeSurfaceId } from "@jskit-ai/kernel/shared/surface";
|
|
2
|
+
import {
|
|
3
|
+
readPlacementSurfaceConfig,
|
|
4
|
+
resolveSurfaceDefinitionFromPlacementContext
|
|
5
|
+
} from "@jskit-ai/shell-web/client/placement";
|
|
6
|
+
|
|
7
|
+
function listWorkspaceSurfaceIdsFromSurfaceConfig(surfaceConfig = null) {
|
|
8
|
+
return listSurfaceIdsFromSurfaceConfig(surfaceConfig, {
|
|
9
|
+
requiresWorkspace: true
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function listNonWorkspaceSurfaceIdsFromSurfaceConfig(surfaceConfig = null) {
|
|
14
|
+
return listSurfaceIdsFromSurfaceConfig(surfaceConfig, {
|
|
15
|
+
requiresWorkspace: false
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function listSurfaceIdsFromSurfaceConfig(surfaceConfig = null, { requiresWorkspace = null } = {}) {
|
|
20
|
+
const source = surfaceConfig && typeof surfaceConfig === "object" ? surfaceConfig : {};
|
|
21
|
+
const enabledSurfaceIds = Array.isArray(source.enabledSurfaceIds) ? source.enabledSurfaceIds : [];
|
|
22
|
+
const surfacesById = source.surfacesById && typeof source.surfacesById === "object" ? source.surfacesById : {};
|
|
23
|
+
|
|
24
|
+
const result = [];
|
|
25
|
+
for (const candidate of enabledSurfaceIds) {
|
|
26
|
+
const surfaceId = normalizeSurfaceId(candidate);
|
|
27
|
+
if (!surfaceId) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const surfaceRequiresWorkspace = surfacesById[surfaceId]?.requiresWorkspace === true;
|
|
31
|
+
if (requiresWorkspace === true && !surfaceRequiresWorkspace) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (requiresWorkspace === false && surfaceRequiresWorkspace) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
result.push(surfaceId);
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function surfaceRequiresWorkspaceFromPlacementContext(contextValue = null, surfaceId = "") {
|
|
43
|
+
return Boolean(resolveSurfaceDefinitionFromPlacementContext(contextValue, surfaceId)?.requiresWorkspace);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function firstAlternativeSurfaceId(surfaceIds = [], excludeSurfaceId = "") {
|
|
47
|
+
const normalizedExcludeSurfaceId = normalizeSurfaceId(excludeSurfaceId);
|
|
48
|
+
for (const candidate of Array.isArray(surfaceIds) ? surfaceIds : []) {
|
|
49
|
+
const surfaceId = normalizeSurfaceId(candidate);
|
|
50
|
+
if (!surfaceId || surfaceId === normalizedExcludeSurfaceId) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
return surfaceId;
|
|
54
|
+
}
|
|
55
|
+
return "";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function resolveSurfaceSwitchTargetsFromPlacementContext(contextValue = null, surfaceId = "") {
|
|
59
|
+
const surfaceConfig = readPlacementSurfaceConfig(contextValue);
|
|
60
|
+
const currentSurface = resolveSurfaceDefinitionFromPlacementContext(contextValue, surfaceId);
|
|
61
|
+
const currentSurfaceId = normalizeSurfaceId(currentSurface?.id);
|
|
62
|
+
const defaultSurfaceId = normalizeSurfaceId(surfaceConfig.defaultSurfaceId);
|
|
63
|
+
const defaultSurface = defaultSurfaceId ? surfaceConfig.surfacesById[defaultSurfaceId] || null : null;
|
|
64
|
+
const workspaceSurfaceIds = listWorkspaceSurfaceIdsFromSurfaceConfig(surfaceConfig);
|
|
65
|
+
const nonWorkspaceSurfaceIds = listNonWorkspaceSurfaceIdsFromSurfaceConfig(surfaceConfig);
|
|
66
|
+
|
|
67
|
+
return Object.freeze({
|
|
68
|
+
surfaceConfig,
|
|
69
|
+
currentSurfaceId,
|
|
70
|
+
currentSurface,
|
|
71
|
+
defaultSurfaceId,
|
|
72
|
+
defaultSurface,
|
|
73
|
+
workspaceSurfaceId: firstAlternativeSurfaceId(workspaceSurfaceIds, currentSurfaceId),
|
|
74
|
+
nonWorkspaceSurfaceId: firstAlternativeSurfaceId(nonWorkspaceSurfaceIds, currentSurfaceId)
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
listWorkspaceSurfaceIdsFromSurfaceConfig,
|
|
80
|
+
surfaceRequiresWorkspaceFromPlacementContext,
|
|
81
|
+
resolveSurfaceSwitchTargetsFromPlacementContext
|
|
82
|
+
};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeSurfaceId
|
|
3
|
+
} from "@jskit-ai/kernel/shared/surface";
|
|
4
|
+
import {
|
|
5
|
+
normalizePathname,
|
|
6
|
+
normalizeSurfaceSegmentFromRouteBase,
|
|
7
|
+
parseWorkspacePathname,
|
|
8
|
+
resolveDefaultWorkspaceSurfaceId,
|
|
9
|
+
resolveWorkspaceSurfaceIdFromSuffixSegments
|
|
10
|
+
} from "@jskit-ai/users-core/shared/support/workspacePathModel";
|
|
11
|
+
import {
|
|
12
|
+
readPlacementSurfaceConfig,
|
|
13
|
+
resolveSurfaceDefinitionFromPlacementContext,
|
|
14
|
+
resolveSurfacePathFromPlacementContext,
|
|
15
|
+
resolveSurfaceRootPathFromPlacementContext
|
|
16
|
+
} from "@jskit-ai/shell-web/client/placement";
|
|
17
|
+
import {
|
|
18
|
+
listWorkspaceSurfaceIdsFromSurfaceConfig,
|
|
19
|
+
surfaceRequiresWorkspaceFromPlacementContext
|
|
20
|
+
} from "./workspaceSurfaceContext.js";
|
|
21
|
+
|
|
22
|
+
const ACCOUNT_SURFACE_ID = "account";
|
|
23
|
+
const ACCOUNT_SETTINGS_SUFFIX = "/";
|
|
24
|
+
const ACCOUNT_SETTINGS_FALLBACK_PATH = "/account";
|
|
25
|
+
|
|
26
|
+
function normalizeWorkspaceSuffix(suffix) {
|
|
27
|
+
const rawSuffix = String(suffix || "/").trim();
|
|
28
|
+
if (!rawSuffix || rawSuffix === "/") {
|
|
29
|
+
return "/";
|
|
30
|
+
}
|
|
31
|
+
return rawSuffix.startsWith("/") ? rawSuffix : `/${rawSuffix}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function resolveWorkspaceSurfaceIdFromSurfaceConfig(surfaceConfig, pathname = "") {
|
|
35
|
+
const parsedWorkspacePath = parseWorkspacePathname(pathname, {
|
|
36
|
+
workspaceBasePath: "/w"
|
|
37
|
+
});
|
|
38
|
+
if (!parsedWorkspacePath) {
|
|
39
|
+
return "";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const workspaceSurfaceIds = listWorkspaceSurfaceIdsFromSurfaceConfig(surfaceConfig);
|
|
43
|
+
const defaultWorkspaceSurfaceId = resolveDefaultWorkspaceSurfaceId({
|
|
44
|
+
defaultSurfaceId: surfaceConfig?.defaultSurfaceId,
|
|
45
|
+
workspaceSurfaceIds,
|
|
46
|
+
surfaceRequiresWorkspace: (surfaceId) => Boolean(surfaceConfig?.surfacesById?.[surfaceId]?.requiresWorkspace)
|
|
47
|
+
});
|
|
48
|
+
if (parsedWorkspacePath.suffixSegments.length < 1) {
|
|
49
|
+
return defaultWorkspaceSurfaceId || normalizeSurfaceId(surfaceConfig?.defaultSurfaceId);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const workspaceSurfaces = workspaceSurfaceIds
|
|
53
|
+
.map((surfaceId) => normalizeSurfaceId(surfaceId))
|
|
54
|
+
.map((surfaceId) => {
|
|
55
|
+
if (!surfaceId) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const definition = surfaceConfig.surfacesById?.[surfaceId];
|
|
59
|
+
return {
|
|
60
|
+
id: surfaceId,
|
|
61
|
+
routeBase: definition?.routeBase
|
|
62
|
+
};
|
|
63
|
+
})
|
|
64
|
+
.filter(Boolean);
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
resolveWorkspaceSurfaceIdFromSuffixSegments({
|
|
68
|
+
suffixSegments: parsedWorkspacePath.suffixSegments,
|
|
69
|
+
defaultWorkspaceSurfaceId,
|
|
70
|
+
workspaceSurfaces
|
|
71
|
+
}) ||
|
|
72
|
+
defaultWorkspaceSurfaceId ||
|
|
73
|
+
normalizeSurfaceId(surfaceConfig?.defaultSurfaceId)
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function resolveWorkspaceSurfaceIdFromPlacementPathname(contextValue = null, pathname = "") {
|
|
78
|
+
const surfaceConfig = readPlacementSurfaceConfig(contextValue);
|
|
79
|
+
const normalizedPathname =
|
|
80
|
+
normalizePathname(pathname) ||
|
|
81
|
+
(typeof window === "object" && window?.location?.pathname ? normalizePathname(window.location.pathname) : "/");
|
|
82
|
+
|
|
83
|
+
return resolveWorkspaceSurfaceIdFromSurfaceConfig(surfaceConfig, normalizedPathname);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function resolveAccountSettingsPathFromPlacementContext(contextValue = null) {
|
|
87
|
+
const accountSurfaceDefinition = resolveSurfaceDefinitionFromPlacementContext(contextValue, ACCOUNT_SURFACE_ID);
|
|
88
|
+
if (!accountSurfaceDefinition) {
|
|
89
|
+
return ACCOUNT_SETTINGS_FALLBACK_PATH;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return resolveSurfacePathFromPlacementContext(contextValue, ACCOUNT_SURFACE_ID, ACCOUNT_SETTINGS_SUFFIX);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function resolveSurfaceWorkspacePathFromPlacementContext(contextValue = null, surfaceId = "", workspaceSlug = "", suffix = "/") {
|
|
96
|
+
const normalizedWorkspaceSlug = String(workspaceSlug || "").trim();
|
|
97
|
+
const normalizedSurfaceId = normalizeSurfaceId(surfaceId);
|
|
98
|
+
if (!normalizedWorkspaceSlug) {
|
|
99
|
+
return "";
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const surfaceConfig = readPlacementSurfaceConfig(contextValue);
|
|
103
|
+
const surfaceDefinition = surfaceConfig.surfacesById[normalizedSurfaceId] || null;
|
|
104
|
+
const normalizedSuffix = normalizeWorkspaceSuffix(suffix);
|
|
105
|
+
|
|
106
|
+
if (surfaceDefinition && !surfaceDefinition.requiresWorkspace) {
|
|
107
|
+
if (normalizedSuffix === "/") {
|
|
108
|
+
return resolveSurfaceRootPathFromPlacementContext(contextValue, normalizedSurfaceId);
|
|
109
|
+
}
|
|
110
|
+
return resolveSurfacePathFromPlacementContext(contextValue, normalizedSurfaceId, normalizedSuffix);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let workspaceRootPath = `/w/${normalizedWorkspaceSlug}`;
|
|
114
|
+
const workspaceSurfaceIds = listWorkspaceSurfaceIdsFromSurfaceConfig(surfaceConfig);
|
|
115
|
+
const defaultWorkspaceSurfaceId = resolveDefaultWorkspaceSurfaceId({
|
|
116
|
+
defaultSurfaceId: surfaceConfig?.defaultSurfaceId,
|
|
117
|
+
workspaceSurfaceIds,
|
|
118
|
+
surfaceRequiresWorkspace: (candidateSurfaceId) => Boolean(surfaceConfig?.surfacesById?.[candidateSurfaceId]?.requiresWorkspace)
|
|
119
|
+
});
|
|
120
|
+
if (normalizedSurfaceId && normalizedSurfaceId !== defaultWorkspaceSurfaceId) {
|
|
121
|
+
const surfaceSegment = normalizeSurfaceSegmentFromRouteBase(surfaceDefinition?.routeBase) || normalizedSurfaceId;
|
|
122
|
+
if (surfaceSegment) {
|
|
123
|
+
workspaceRootPath = `${workspaceRootPath}/${surfaceSegment}`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (normalizedSuffix === "/") {
|
|
128
|
+
return normalizePathname(workspaceRootPath);
|
|
129
|
+
}
|
|
130
|
+
return normalizePathname(`${workspaceRootPath}${normalizedSuffix}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function extractWorkspaceSlugFromSurfacePathname(contextValue = null, surfaceId = "", pathname = "") {
|
|
134
|
+
const normalizedPathname = normalizePathname(
|
|
135
|
+
pathname || (typeof window === "object" && window?.location?.pathname ? window.location.pathname : "/")
|
|
136
|
+
);
|
|
137
|
+
const normalizedSurfaceId = normalizeSurfaceId(surfaceId);
|
|
138
|
+
if (!normalizedSurfaceId) {
|
|
139
|
+
return "";
|
|
140
|
+
}
|
|
141
|
+
if (!surfaceRequiresWorkspaceFromPlacementContext(contextValue, normalizedSurfaceId)) {
|
|
142
|
+
return "";
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const parsedWorkspacePath = parseWorkspacePathname(normalizedPathname);
|
|
146
|
+
if (!parsedWorkspacePath) {
|
|
147
|
+
return "";
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const resolvedSurfaceId = resolveWorkspaceSurfaceIdFromPlacementPathname(contextValue, normalizedPathname);
|
|
151
|
+
if (resolvedSurfaceId !== normalizedSurfaceId) {
|
|
152
|
+
return "";
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return parsedWorkspacePath.workspaceSlug;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export {
|
|
159
|
+
resolveAccountSettingsPathFromPlacementContext,
|
|
160
|
+
resolveWorkspaceSurfaceIdFromPlacementPathname,
|
|
161
|
+
resolveSurfaceWorkspacePathFromPlacementContext,
|
|
162
|
+
extractWorkspaceSlugFromSurfacePathname
|
|
163
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import UsersWorkspaceSelector from "../components/UsersWorkspaceSelector.vue";
|
|
2
|
+
import UsersWorkspaceToolsWidget from "../components/UsersWorkspaceToolsWidget.vue";
|
|
3
|
+
import UsersShellMenuLinkItem from "../components/UsersShellMenuLinkItem.vue";
|
|
4
|
+
import UsersSurfaceAwareMenuLinkItem from "../components/UsersSurfaceAwareMenuLinkItem.vue";
|
|
5
|
+
import UsersProfileSurfaceSwitchMenuItem from "../components/UsersProfileSurfaceSwitchMenuItem.vue";
|
|
6
|
+
import UsersWorkspaceSettingsMenuItem from "../components/UsersWorkspaceSettingsMenuItem.vue";
|
|
7
|
+
import UsersWorkspaceMembersMenuItem from "../components/UsersWorkspaceMembersMenuItem.vue";
|
|
8
|
+
import ProfileClientElement from "../components/ProfileClientElement.vue";
|
|
9
|
+
import MembersAdminClientElement from "../components/MembersAdminClientElement.vue";
|
|
10
|
+
import WorkspaceSettingsClientElement from "../components/WorkspaceSettingsClientElement.vue";
|
|
11
|
+
import {
|
|
12
|
+
USERS_WEB_BOOTSTRAP_PLACEMENT_RUNTIME_TOKEN,
|
|
13
|
+
createBootstrapPlacementRuntime
|
|
14
|
+
} from "../runtime/bootstrapPlacementRuntime.js";
|
|
15
|
+
|
|
16
|
+
const USERS_WEB_WORKSPACE_SELECTOR_TOKEN = "users.web.workspace.selector";
|
|
17
|
+
const USERS_WEB_WORKSPACE_TOOLS_WIDGET_TOKEN = "users.web.workspace.tools.widget";
|
|
18
|
+
const USERS_WEB_SHELL_MENU_LINK_ITEM_TOKEN = "users.web.shell.menu-link-item";
|
|
19
|
+
const USERS_WEB_SURFACE_AWARE_MENU_LINK_ITEM_TOKEN = "users.web.shell.surface-aware-menu-link-item";
|
|
20
|
+
const USERS_WEB_PROFILE_SURFACE_SWITCH_MENU_ITEM_TOKEN = "users.web.profile.menu.surface-switch-item";
|
|
21
|
+
const USERS_WEB_WORKSPACE_SETTINGS_MENU_ITEM_TOKEN = "users.web.workspace-settings.menu-item";
|
|
22
|
+
const USERS_WEB_WORKSPACE_MEMBERS_MENU_ITEM_TOKEN = "users.web.workspace-members.menu-item";
|
|
23
|
+
const USERS_WEB_PROFILE_ELEMENT_TOKEN = "users.web.profile.element";
|
|
24
|
+
const USERS_WEB_MEMBERS_ADMIN_ELEMENT_TOKEN = "users.web.members-admin.element";
|
|
25
|
+
const USERS_WEB_WORKSPACE_SETTINGS_ELEMENT_TOKEN = "users.web.workspace-settings.element";
|
|
26
|
+
|
|
27
|
+
class UsersWebClientProvider {
|
|
28
|
+
static id = "users.web.client";
|
|
29
|
+
static dependsOn = ["shell.web.client"];
|
|
30
|
+
|
|
31
|
+
register(app) {
|
|
32
|
+
if (!app || typeof app.singleton !== "function") {
|
|
33
|
+
throw new Error("UsersWebClientProvider requires application singleton().");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
app.singleton(USERS_WEB_WORKSPACE_SELECTOR_TOKEN, () => UsersWorkspaceSelector);
|
|
37
|
+
app.singleton(USERS_WEB_WORKSPACE_TOOLS_WIDGET_TOKEN, () => UsersWorkspaceToolsWidget);
|
|
38
|
+
app.singleton(USERS_WEB_SHELL_MENU_LINK_ITEM_TOKEN, () => UsersShellMenuLinkItem);
|
|
39
|
+
app.singleton(USERS_WEB_SURFACE_AWARE_MENU_LINK_ITEM_TOKEN, () => UsersSurfaceAwareMenuLinkItem);
|
|
40
|
+
app.singleton(USERS_WEB_PROFILE_SURFACE_SWITCH_MENU_ITEM_TOKEN, () => UsersProfileSurfaceSwitchMenuItem);
|
|
41
|
+
app.singleton(USERS_WEB_WORKSPACE_SETTINGS_MENU_ITEM_TOKEN, () => UsersWorkspaceSettingsMenuItem);
|
|
42
|
+
app.singleton(USERS_WEB_WORKSPACE_MEMBERS_MENU_ITEM_TOKEN, () => UsersWorkspaceMembersMenuItem);
|
|
43
|
+
app.singleton(USERS_WEB_PROFILE_ELEMENT_TOKEN, () => ProfileClientElement);
|
|
44
|
+
app.singleton(USERS_WEB_MEMBERS_ADMIN_ELEMENT_TOKEN, () => MembersAdminClientElement);
|
|
45
|
+
app.singleton(USERS_WEB_WORKSPACE_SETTINGS_ELEMENT_TOKEN, () => WorkspaceSettingsClientElement);
|
|
46
|
+
app.singleton(USERS_WEB_BOOTSTRAP_PLACEMENT_RUNTIME_TOKEN, (scope) => createBootstrapPlacementRuntime({ app: scope }));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async boot(app) {
|
|
50
|
+
if (!app || typeof app.make !== "function") {
|
|
51
|
+
throw new Error("UsersWebClientProvider requires application make().");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const runtime = app.make(USERS_WEB_BOOTSTRAP_PLACEMENT_RUNTIME_TOKEN);
|
|
55
|
+
if (runtime && typeof runtime.initialize === "function") {
|
|
56
|
+
await runtime.initialize();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
shutdown(app) {
|
|
61
|
+
if (!app || typeof app.make !== "function") {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const runtime = app.make(USERS_WEB_BOOTSTRAP_PLACEMENT_RUNTIME_TOKEN);
|
|
66
|
+
if (runtime && typeof runtime.shutdown === "function") {
|
|
67
|
+
runtime.shutdown();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export {
|
|
73
|
+
UsersWebClientProvider,
|
|
74
|
+
USERS_WEB_WORKSPACE_SELECTOR_TOKEN,
|
|
75
|
+
USERS_WEB_WORKSPACE_TOOLS_WIDGET_TOKEN,
|
|
76
|
+
USERS_WEB_SHELL_MENU_LINK_ITEM_TOKEN,
|
|
77
|
+
USERS_WEB_SURFACE_AWARE_MENU_LINK_ITEM_TOKEN,
|
|
78
|
+
USERS_WEB_PROFILE_SURFACE_SWITCH_MENU_ITEM_TOKEN,
|
|
79
|
+
USERS_WEB_WORKSPACE_SETTINGS_MENU_ITEM_TOKEN,
|
|
80
|
+
USERS_WEB_WORKSPACE_MEMBERS_MENU_ITEM_TOKEN,
|
|
81
|
+
USERS_WEB_PROFILE_ELEMENT_TOKEN,
|
|
82
|
+
USERS_WEB_MEMBERS_ADMIN_ELEMENT_TOKEN,
|
|
83
|
+
USERS_WEB_WORKSPACE_SETTINGS_ELEMENT_TOKEN,
|
|
84
|
+
USERS_WEB_BOOTSTRAP_PLACEMENT_RUNTIME_TOKEN
|
|
85
|
+
};
|