@jskit-ai/users-web 0.1.52 → 0.1.54

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.
Files changed (73) hide show
  1. package/package.descriptor.mjs +14 -96
  2. package/package.json +16 -11
  3. package/src/client/account-settings/sections.js +74 -0
  4. package/src/client/composables/account-settings/accountSettingsRuntimeHelpers.js +2 -38
  5. package/src/client/composables/crud/crudLookupFieldRuntime.js +2 -2
  6. package/src/client/composables/internal/crudListParentTitleSupport.js +1 -1
  7. package/src/client/composables/internal/useOperationScope.js +12 -12
  8. package/src/client/composables/records/useAddEdit.js +2 -2
  9. package/src/client/composables/records/useList.js +3 -3
  10. package/src/client/composables/records/useView.js +2 -2
  11. package/src/client/composables/support/scopeHelpers.js +19 -19
  12. package/src/client/composables/useAccess.js +3 -3
  13. package/src/client/composables/useAccountSettingsRuntime.js +8 -156
  14. package/src/client/composables/useCommand.js +2 -2
  15. package/src/client/composables/useCrudListParentTitle.js +2 -2
  16. package/src/client/composables/usePaths.js +50 -38
  17. package/src/client/composables/useScopeRuntime.js +55 -27
  18. package/src/client/composables/useSurfaceRouteContext.js +1 -7
  19. package/src/client/index.js +0 -1
  20. package/src/client/lib/bootstrap.js +0 -63
  21. package/src/client/lib/httpClient.js +2 -59
  22. package/src/client/lib/theme.js +12 -189
  23. package/src/client/providers/UsersWebClientProvider.js +2 -25
  24. package/src/client/providers/bootUsersWebClientProvider.js +28 -0
  25. package/src/shared/toolsOutletContracts.js +1 -8
  26. package/templates/src/components/account/settings/AccountSettingsClientElement.vue +33 -21
  27. package/test/accountSettingsSections.test.js +79 -0
  28. package/test/exportsContract.test.js +2 -2
  29. package/test/scopeHelpers.test.js +6 -6
  30. package/test/settingsPlacementContract.test.js +4 -49
  31. package/test/theme.test.js +0 -56
  32. package/src/client/components/ConsoleSettingsClientElement.vue +0 -24
  33. package/src/client/components/MembersAdminClientElement.vue +0 -400
  34. package/src/client/components/UsersProfileSurfaceSwitchMenuItem.vue +0 -39
  35. package/src/client/components/UsersWorkspaceMembersMenuItem.vue +0 -36
  36. package/src/client/components/UsersWorkspacePermissionMenuItem.vue +0 -90
  37. package/src/client/components/UsersWorkspaceSelector.vue +0 -248
  38. package/src/client/components/UsersWorkspaceSettingsMenuItem.vue +0 -39
  39. package/src/client/components/UsersWorkspaceToolsWidget.vue +0 -12
  40. package/src/client/components/WorkspaceMembersClientElement.vue +0 -655
  41. package/src/client/components/WorkspaceProfileClientElement.vue +0 -116
  42. package/src/client/components/WorkspaceSettingsClientElement.vue +0 -102
  43. package/src/client/components/WorkspaceSettingsFieldsClientElement.vue +0 -265
  44. package/src/client/components/WorkspacesClientElement.vue +0 -509
  45. package/src/client/composables/account-settings/accountSettingsInvitesRuntime.js +0 -88
  46. package/src/client/composables/useBootstrapQuery.js +0 -52
  47. package/src/client/composables/useWorkspaceRouteContext.js +0 -28
  48. package/src/client/composables/useWorkspaceSurfaceId.js +0 -43
  49. package/src/client/lib/menuIcons.js +0 -210
  50. package/src/client/lib/profileSurfaceMenuLinks.js +0 -142
  51. package/src/client/lib/surfaceAccessPolicy.js +0 -350
  52. package/src/client/lib/workspaceLinkResolver.js +0 -207
  53. package/src/client/lib/workspaceSurfaceContext.js +0 -82
  54. package/src/client/lib/workspaceSurfacePaths.js +0 -163
  55. package/src/client/providers/UsersWorkspacesClientProvider.js +0 -24
  56. package/src/client/runtime/bootstrapPlacementRouteGuards.js +0 -371
  57. package/src/client/runtime/bootstrapPlacementRuntime.js +0 -463
  58. package/src/client/runtime/bootstrapPlacementRuntimeConstants.js +0 -28
  59. package/src/client/runtime/bootstrapPlacementRuntimeHelpers.js +0 -147
  60. package/src/client/support/menuLinkTarget.js +0 -93
  61. package/src/client/support/realtimeWorkspace.js +0 -21
  62. package/src/client/support/runtimeNormalization.js +0 -27
  63. package/src/client/support/workspaceQueryKeys.js +0 -15
  64. package/templates/src/components/account/settings/AccountSettingsInvitesSection.vue +0 -77
  65. package/templates/src/pages/console/settings/index.vue +0 -8
  66. package/templates/src/pages/console/settings.vue +0 -32
  67. package/test/bootstrapPlacementRuntime.test.js +0 -1095
  68. package/test/menuIcons.test.js +0 -35
  69. package/test/menuLinkTarget.test.js +0 -116
  70. package/test/profileSurfaceMenuLinks.test.js +0 -207
  71. package/test/surfaceAccessPolicy.test.js +0 -129
  72. package/test/workspaceLinkResolver.test.js +0 -61
  73. package/test/workspaceSurfacePaths.test.js +0 -39
@@ -1,43 +0,0 @@
1
- import { computed, unref } from "vue";
2
- import { resolveSurfaceIdFromPlacementPathname } from "@jskit-ai/shell-web/client/placement";
3
- import {
4
- resolveSurfaceSwitchTargetsFromPlacementContext,
5
- surfaceRequiresWorkspaceFromPlacementContext
6
- } from "../lib/workspaceSurfaceContext.js";
7
-
8
- function resolveCurrentPathname(route = null) {
9
- const routePath = String(route?.path || "").trim();
10
- if (routePath) {
11
- return routePath;
12
- }
13
-
14
- if (typeof window === "object" && window?.location?.pathname) {
15
- return String(window.location.pathname);
16
- }
17
-
18
- return "/";
19
- }
20
-
21
- function useWorkspaceSurfaceId({ route = null, placementContext = null } = {}) {
22
- const currentSurfaceId = computed(() =>
23
- resolveSurfaceIdFromPlacementPathname(unref(placementContext), resolveCurrentPathname(route))
24
- );
25
-
26
- const workspaceSurfaceId = computed(() => {
27
- const contextValue = unref(placementContext);
28
- const surfaceId = String(currentSurfaceId.value || "").trim().toLowerCase();
29
- if (surfaceId && surfaceRequiresWorkspaceFromPlacementContext(contextValue, surfaceId)) {
30
- return surfaceId;
31
- }
32
-
33
- const targets = resolveSurfaceSwitchTargetsFromPlacementContext(contextValue, surfaceId);
34
- return String(targets.workspaceSurfaceId || "").trim().toLowerCase();
35
- });
36
-
37
- return Object.freeze({
38
- currentSurfaceId,
39
- workspaceSurfaceId
40
- });
41
- }
42
-
43
- export { useWorkspaceSurfaceId };
@@ -1,210 +0,0 @@
1
- import * as mdiIcons from "@mdi/js";
2
- import {
3
- mdiAccountCircleOutline,
4
- mdiAccountCogOutline,
5
- mdiAccountGroupOutline,
6
- mdiArrowRightCircleOutline,
7
- mdiClipboardListOutline,
8
- mdiCogOutline,
9
- mdiConsoleNetworkOutline,
10
- mdiFolderOutline,
11
- mdiHomeVariantOutline,
12
- mdiLogin,
13
- mdiLogout,
14
- mdiRobotOutline,
15
- mdiShieldCrownOutline,
16
- mdiViewDashboardOutline,
17
- mdiViewListOutline
18
- } from "@mdi/js";
19
- import { isExternalLinkTarget, splitPathQueryHash } from "@jskit-ai/kernel/shared/support/linkPath";
20
- import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
21
- import { normalizePathname as normalizeKernelPathname } from "@jskit-ai/kernel/shared/surface/paths";
22
-
23
- const SURFACE_SWITCH_ICON_BY_ID = Object.freeze({
24
- home: mdiHomeVariantOutline,
25
- app: mdiViewDashboardOutline,
26
- admin: mdiShieldCrownOutline,
27
- console: mdiConsoleNetworkOutline
28
- });
29
-
30
- function resolveExplicitIconValue(explicitIcon = "") {
31
- const normalizedExplicitIcon = normalizeText(explicitIcon);
32
- if (!normalizedExplicitIcon) {
33
- return "";
34
- }
35
-
36
- if (!normalizedExplicitIcon.startsWith("mdi-")) {
37
- return normalizedExplicitIcon;
38
- }
39
-
40
- const iconKey = normalizedExplicitIcon
41
- .slice("mdi-".length)
42
- .split("-")
43
- .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
44
- .join("");
45
- const exportName = `mdi${iconKey}`;
46
- const resolvedIcon = mdiIcons[exportName];
47
- return typeof resolvedIcon === "string" && resolvedIcon ? resolvedIcon : normalizedExplicitIcon;
48
- }
49
-
50
- function normalizePathname(value) {
51
- const normalizedValue = normalizeText(value);
52
- if (!normalizedValue) {
53
- return "";
54
- }
55
-
56
- if (isExternalLinkTarget(normalizedValue)) {
57
- const isHttpTarget = normalizedValue.startsWith("http://") || normalizedValue.startsWith("https://");
58
- if (!isHttpTarget) {
59
- return "";
60
- }
61
-
62
- let parsedPathname = "";
63
- try {
64
- parsedPathname = String(new URL(normalizedValue).pathname || "");
65
- } catch {
66
- return "";
67
- }
68
-
69
- const normalizedPathname = normalizeText(parsedPathname);
70
- if (!normalizedPathname) {
71
- return "";
72
- }
73
- return normalizeKernelPathname(normalizedPathname).toLowerCase();
74
- }
75
-
76
- const { pathname } = splitPathQueryHash(normalizedValue);
77
- const normalizedPathname = normalizeText(pathname);
78
- if (!normalizedPathname) {
79
- return "";
80
- }
81
-
82
- return normalizeKernelPathname(normalizedPathname).toLowerCase();
83
- }
84
-
85
- function resolveSurfaceSwitchIdFromLabel(label = "") {
86
- const normalizedLabel = normalizeText(label).toLowerCase();
87
- if (!normalizedLabel.startsWith("go to ")) {
88
- return "";
89
- }
90
- return normalizeText(normalizedLabel.slice("go to ".length));
91
- }
92
-
93
- function resolveSurfaceSwitchIcon(surfaceId = "", explicitIcon = "") {
94
- const resolvedExplicitIcon = resolveExplicitIconValue(explicitIcon);
95
- if (resolvedExplicitIcon) {
96
- return resolvedExplicitIcon;
97
- }
98
-
99
- const normalizedSurfaceId = normalizeText(surfaceId).toLowerCase();
100
- return SURFACE_SWITCH_ICON_BY_ID[normalizedSurfaceId] || mdiArrowRightCircleOutline;
101
- }
102
-
103
- function resolveMenuLinkIcon({ icon = "", label = "", to = "" } = {}) {
104
- const resolvedExplicitIcon = resolveExplicitIconValue(icon);
105
- if (resolvedExplicitIcon) {
106
- return resolvedExplicitIcon;
107
- }
108
-
109
- const normalizedLabel = normalizeText(label).toLowerCase();
110
- const normalizedPathname = normalizePathname(to);
111
- if (!normalizedLabel && !normalizedPathname) {
112
- return "";
113
- }
114
-
115
- const surfaceSwitchSurfaceId = resolveSurfaceSwitchIdFromLabel(normalizedLabel);
116
- if (surfaceSwitchSurfaceId) {
117
- return resolveSurfaceSwitchIcon(surfaceSwitchSurfaceId);
118
- }
119
-
120
- if (
121
- normalizedLabel.includes("sign in") ||
122
- normalizedPathname.includes("/auth/login")
123
- ) {
124
- return mdiLogin;
125
- }
126
-
127
- if (
128
- normalizedLabel.includes("sign out") ||
129
- normalizedPathname.includes("/auth/signout")
130
- ) {
131
- return mdiLogout;
132
- }
133
-
134
- if (
135
- normalizedLabel.includes("account") ||
136
- normalizedPathname.includes("/account")
137
- ) {
138
- if (
139
- normalizedLabel.includes("settings") ||
140
- normalizedPathname.includes("/settings") ||
141
- normalizedPathname === "/account"
142
- ) {
143
- return mdiAccountCogOutline;
144
- }
145
- return mdiAccountCircleOutline;
146
- }
147
-
148
- if (
149
- normalizedLabel.includes("members") ||
150
- normalizedLabel.includes("team") ||
151
- normalizedPathname.includes("/members")
152
- ) {
153
- return mdiAccountGroupOutline;
154
- }
155
-
156
- if (normalizedLabel.includes("assistant") || normalizedPathname.includes("/assistant")) {
157
- return mdiRobotOutline;
158
- }
159
-
160
- if (
161
- normalizedLabel.includes("console") ||
162
- normalizedPathname.startsWith("/console")
163
- ) {
164
- return mdiConsoleNetworkOutline;
165
- }
166
-
167
- if (
168
- normalizedLabel.includes("admin") ||
169
- normalizedPathname.includes("/admin")
170
- ) {
171
- return mdiShieldCrownOutline;
172
- }
173
-
174
- if (normalizedLabel.includes("settings") || normalizedPathname.includes("/settings")) {
175
- return mdiCogOutline;
176
- }
177
-
178
- if (
179
- normalizedLabel.includes("home") ||
180
- normalizedPathname === "/"
181
- ) {
182
- return mdiHomeVariantOutline;
183
- }
184
-
185
- if (
186
- normalizedLabel.includes("workspace") ||
187
- normalizedLabel.includes("dashboard") ||
188
- normalizedPathname.includes("/w/")
189
- ) {
190
- return mdiViewDashboardOutline;
191
- }
192
-
193
- if (normalizedPathname) {
194
- const segments = normalizedPathname.split("/").filter(Boolean);
195
- if (segments.length === 1) {
196
- return mdiFolderOutline;
197
- }
198
- }
199
-
200
- if (normalizedLabel.includes("list")) {
201
- return mdiClipboardListOutline;
202
- }
203
-
204
- return mdiViewListOutline;
205
- }
206
-
207
- export {
208
- resolveMenuLinkIcon,
209
- resolveSurfaceSwitchIcon
210
- };
@@ -1,142 +0,0 @@
1
- import {
2
- resolveSurfaceIdFromPlacementPathname
3
- } from "@jskit-ai/shell-web/client/placement";
4
- import { resolveWorkspaceShellLinkPath } from "./workspaceLinkResolver.js";
5
- import { resolveSurfaceSwitchTargetsFromPlacementContext } from "./workspaceSurfaceContext.js";
6
- import { evaluateSurfaceAccess, hasWorkspaceMembership } from "./surfaceAccessPolicy.js";
7
- import {
8
- resolveWorkspaceSurfaceIdFromPlacementPathname,
9
- extractWorkspaceSlugFromSurfacePathname
10
- } from "./workspaceSurfacePaths.js";
11
- import { resolveSurfaceSwitchIcon } from "./menuIcons.js";
12
-
13
- function resolveCurrentWorkspaceSlug(contextValue, surfaceId) {
14
- const context = contextValue && typeof contextValue === "object" ? contextValue : {};
15
- const workspaceSlugFromContext = String(context?.workspace?.slug || "").trim();
16
- if (workspaceSlugFromContext) {
17
- return workspaceSlugFromContext;
18
- }
19
-
20
- if (typeof window !== "object" || !window?.location?.pathname) {
21
- return "";
22
- }
23
-
24
- const pathname = String(window.location.pathname || "").trim();
25
- const currentSurfaceId =
26
- resolveWorkspaceSurfaceIdFromPlacementPathname(context, pathname) ||
27
- resolveSurfaceIdFromPlacementPathname(context, pathname) ||
28
- surfaceId;
29
- return String(extractWorkspaceSlugFromSurfacePathname(context, currentSurfaceId, pathname) || "").trim();
30
- }
31
-
32
- function shouldIncludeSurfaceSwitchTarget(surfaceDefinition = null) {
33
- if (!surfaceDefinition || typeof surfaceDefinition !== "object") {
34
- return false;
35
- }
36
-
37
- if (surfaceDefinition.enabled === false) {
38
- return false;
39
- }
40
-
41
- if (surfaceDefinition.showInSurfaceSwitchMenu === true) {
42
- return true;
43
- }
44
- if (surfaceDefinition.showInSurfaceSwitchMenu === false) {
45
- return false;
46
- }
47
-
48
- return surfaceDefinition.requiresWorkspace === true || surfaceDefinition.requiresAuth === true;
49
- }
50
-
51
- function resolveSurfaceSwitchLinkLabel(surfaceDefinition = null, surfaceId = "") {
52
- const normalizedSurfaceId = String(surfaceId || "").trim();
53
- const configuredLabel = String(surfaceDefinition?.label || "").trim();
54
- const label = configuredLabel || normalizedSurfaceId;
55
- if (!label) {
56
- return "Go to surface";
57
- }
58
- return `Go to ${label.toLowerCase()}`;
59
- }
60
-
61
- function resolveSurfaceSwitchLinks({ context, surface } = {}) {
62
- const source = context && typeof context === "object" ? context : {};
63
- const targets = resolveSurfaceSwitchTargetsFromPlacementContext(source, surface);
64
- const currentSurfaceId = String(targets.currentSurfaceId || "").trim().toLowerCase();
65
- const resolvedWorkspaceSlug = resolveCurrentWorkspaceSlug(source, currentSurfaceId || surface);
66
- const workspaceSlug = hasWorkspaceMembership(source, resolvedWorkspaceSlug) ? resolvedWorkspaceSlug : "";
67
- const enabledSurfaceIds = Array.isArray(targets?.surfaceConfig?.enabledSurfaceIds)
68
- ? targets.surfaceConfig.enabledSurfaceIds
69
- : [];
70
- const links = [];
71
-
72
- for (const targetSurfaceIdCandidate of enabledSurfaceIds) {
73
- const targetSurfaceId = String(targetSurfaceIdCandidate || "").trim().toLowerCase();
74
- if (!targetSurfaceId) {
75
- continue;
76
- }
77
- if (targetSurfaceId === currentSurfaceId) {
78
- continue;
79
- }
80
-
81
- const targetSurface = targets.surfaceConfig.surfacesById[targetSurfaceId] || null;
82
- if (!shouldIncludeSurfaceSwitchTarget(targetSurface)) {
83
- continue;
84
- }
85
-
86
- const targetWorkspaceSlug = targetSurface?.requiresWorkspace === true ? workspaceSlug : "";
87
- if (targetSurface?.requiresWorkspace === true && !targetWorkspaceSlug) {
88
- continue;
89
- }
90
-
91
- const accessDecision = evaluateSurfaceAccess({
92
- context: source,
93
- surfaceId: targetSurfaceId,
94
- workspaceSlug: targetWorkspaceSlug
95
- });
96
- if (!accessDecision.allowed) {
97
- continue;
98
- }
99
-
100
- links.push({
101
- id: `surface-switch.${targetSurfaceId}`,
102
- label: resolveSurfaceSwitchLinkLabel(targetSurface, targetSurfaceId),
103
- icon: resolveSurfaceSwitchIcon(targetSurfaceId, targetSurface?.icon),
104
- to: resolveWorkspaceShellLinkPath({
105
- context: source,
106
- surface: targetSurfaceId,
107
- workspaceSlug: targetWorkspaceSlug,
108
- mode: targetSurface?.requiresWorkspace === true ? "workspace" : "surface",
109
- relativePath: "/"
110
- })
111
- });
112
- }
113
-
114
- return links;
115
- }
116
-
117
- function resolvePrimarySurfaceSwitchLink({ context, surface } = {}) {
118
- const links = resolveSurfaceSwitchLinks({
119
- context,
120
- surface
121
- });
122
- return links[0] || null;
123
- }
124
-
125
- function resolveProfileSurfaceMenuLinks({ context, surface } = {}) {
126
- const source = context && typeof context === "object" ? context : {};
127
- const authenticated = Boolean(source?.auth?.authenticated);
128
- if (!authenticated) {
129
- return [];
130
- }
131
- return resolveSurfaceSwitchLinks({
132
- context: source,
133
- surface
134
- });
135
- }
136
-
137
- export {
138
- resolveProfileSurfaceMenuLinks,
139
- resolvePrimarySurfaceSwitchLink,
140
- resolveSurfaceSwitchLinks,
141
- hasWorkspaceMembership
142
- };