@jskit-ai/users-web 0.1.53 → 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 (70) hide show
  1. package/package.descriptor.mjs +15 -53
  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 -11
  31. package/test/theme.test.js +0 -56
  32. package/src/client/components/MembersAdminClientElement.vue +0 -400
  33. package/src/client/components/UsersProfileSurfaceSwitchMenuItem.vue +0 -39
  34. package/src/client/components/UsersWorkspaceMembersMenuItem.vue +0 -36
  35. package/src/client/components/UsersWorkspacePermissionMenuItem.vue +0 -90
  36. package/src/client/components/UsersWorkspaceSelector.vue +0 -248
  37. package/src/client/components/UsersWorkspaceSettingsMenuItem.vue +0 -39
  38. package/src/client/components/UsersWorkspaceToolsWidget.vue +0 -12
  39. package/src/client/components/WorkspaceMembersClientElement.vue +0 -655
  40. package/src/client/components/WorkspaceProfileClientElement.vue +0 -116
  41. package/src/client/components/WorkspaceSettingsClientElement.vue +0 -102
  42. package/src/client/components/WorkspaceSettingsFieldsClientElement.vue +0 -265
  43. package/src/client/components/WorkspacesClientElement.vue +0 -509
  44. package/src/client/composables/account-settings/accountSettingsInvitesRuntime.js +0 -88
  45. package/src/client/composables/useBootstrapQuery.js +0 -52
  46. package/src/client/composables/useWorkspaceRouteContext.js +0 -28
  47. package/src/client/composables/useWorkspaceSurfaceId.js +0 -43
  48. package/src/client/lib/menuIcons.js +0 -201
  49. package/src/client/lib/profileSurfaceMenuLinks.js +0 -142
  50. package/src/client/lib/surfaceAccessPolicy.js +0 -350
  51. package/src/client/lib/workspaceLinkResolver.js +0 -207
  52. package/src/client/lib/workspaceSurfaceContext.js +0 -82
  53. package/src/client/lib/workspaceSurfacePaths.js +0 -163
  54. package/src/client/providers/UsersWorkspacesClientProvider.js +0 -24
  55. package/src/client/runtime/bootstrapPlacementRouteGuards.js +0 -371
  56. package/src/client/runtime/bootstrapPlacementRuntime.js +0 -463
  57. package/src/client/runtime/bootstrapPlacementRuntimeConstants.js +0 -28
  58. package/src/client/runtime/bootstrapPlacementRuntimeHelpers.js +0 -147
  59. package/src/client/support/menuLinkTarget.js +0 -93
  60. package/src/client/support/realtimeWorkspace.js +0 -21
  61. package/src/client/support/runtimeNormalization.js +0 -27
  62. package/src/client/support/workspaceQueryKeys.js +0 -15
  63. package/templates/src/components/account/settings/AccountSettingsInvitesSection.vue +0 -77
  64. package/test/bootstrapPlacementRuntime.test.js +0 -1095
  65. package/test/menuIcons.test.js +0 -34
  66. package/test/menuLinkTarget.test.js +0 -116
  67. package/test/profileSurfaceMenuLinks.test.js +0 -208
  68. package/test/surfaceAccessPolicy.test.js +0 -129
  69. package/test/workspaceLinkResolver.test.js +0 -61
  70. package/test/workspaceSurfacePaths.test.js +0 -39
@@ -1,116 +0,0 @@
1
- <template>
2
- <v-card class="mb-4" rounded="lg" elevation="1" border>
3
- <v-card-item>
4
- <v-card-title class="text-h6">Workspace profile</v-card-title>
5
- <v-card-subtitle>Name and avatar used across the workspace.</v-card-subtitle>
6
- </v-card-item>
7
- <v-divider />
8
- <v-card-text class="pt-4">
9
- <template v-if="showSkeleton">
10
- <v-skeleton-loader type="text@2, list-item-two-line@3, button" />
11
- </template>
12
-
13
- <p v-else-if="addEdit.loadError" class="text-body-2 text-medium-emphasis mb-4">
14
- {{ addEdit.loadError }}
15
- </p>
16
-
17
- <p v-else-if="!addEdit.canView" class="text-body-2 text-medium-emphasis mb-4">
18
- You do not have permission to view workspace profile.
19
- </p>
20
-
21
- <template v-else>
22
- <v-form @submit.prevent="addEdit.submit" novalidate>
23
- <v-progress-linear v-if="addEdit.isRefetching" indeterminate class="mb-4" />
24
- <v-row>
25
- <v-col cols="12" md="6">
26
- <v-text-field
27
- v-model="workspaceProfileForm.name"
28
- label="Workspace name"
29
- variant="outlined"
30
- density="comfortable"
31
- :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
32
- :error-messages="addEdit.fieldErrors.name ? [addEdit.fieldErrors.name] : []"
33
- />
34
- </v-col>
35
-
36
- <v-col cols="12" md="6">
37
- <v-text-field
38
- v-model="workspaceProfileForm.avatarUrl"
39
- label="Workspace avatar URL"
40
- variant="outlined"
41
- density="comfortable"
42
- :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
43
- placeholder="https://..."
44
- hint="Optional"
45
- persistent-hint
46
- :error-messages="addEdit.fieldErrors.avatarUrl ? [addEdit.fieldErrors.avatarUrl] : []"
47
- />
48
- </v-col>
49
-
50
- <v-col cols="12" class="d-flex align-center justify-end ga-3">
51
- <v-btn
52
- v-if="addEdit.canSave"
53
- type="submit"
54
- color="primary"
55
- :loading="addEdit.isSaving"
56
- :disabled="addEdit.isInitialLoading || addEdit.isRefetching"
57
- >
58
- Save workspace profile
59
- </v-btn>
60
- <v-chip v-else color="secondary" label>Read-only</v-chip>
61
- </v-col>
62
- </v-row>
63
- </v-form>
64
- </template>
65
- </v-card-text>
66
- </v-card>
67
- </template>
68
-
69
- <script setup>
70
- import { computed, reactive } from "vue";
71
- import { validateOperationSection } from "@jskit-ai/http-runtime/shared/validators/operationValidation";
72
- import { workspaceResource } from "@jskit-ai/users-core/shared/resources/workspaceResource";
73
- import { USERS_ROUTE_VISIBILITY_WORKSPACE } from "@jskit-ai/users-core/shared/support/usersVisibility";
74
- import { useAddEdit } from "../composables/records/useAddEdit.js";
75
- import { buildWorkspaceQueryKey } from "../support/workspaceQueryKeys.js";
76
-
77
- const emit = defineEmits(["saved"]);
78
-
79
- const workspaceProfileForm = reactive({
80
- name: "",
81
- avatarUrl: ""
82
- });
83
-
84
- const addEdit = useAddEdit({
85
- ownershipFilter: USERS_ROUTE_VISIBILITY_WORKSPACE,
86
- resource: workspaceResource,
87
- apiSuffix: "/",
88
- queryKeyFactory: (surfaceId = "", workspaceSlug = "") =>
89
- buildWorkspaceQueryKey("profile", surfaceId, workspaceSlug),
90
- viewPermissions: ["workspace.settings.view", "workspace.settings.update"],
91
- savePermissions: ["workspace.settings.update"],
92
- placementSource: "users-web.workspace-profile-view",
93
- fallbackLoadError: "Unable to load workspace profile.",
94
- fieldErrorKeys: ["name", "avatarUrl"],
95
- model: workspaceProfileForm,
96
- parseInput: (rawPayload) =>
97
- validateOperationSection({
98
- operation: workspaceResource.operations.patch,
99
- section: "bodyValidator",
100
- value: rawPayload
101
- }),
102
- mapLoadedToModel: (model, payload = {}) => {
103
- model.name = String(payload?.name || "");
104
- model.avatarUrl = String(payload?.avatarUrl || "");
105
- },
106
- buildRawPayload: (model) => ({
107
- name: model.name,
108
- avatarUrl: model.avatarUrl
109
- }),
110
- onSaveSuccess: async () => {
111
- emit("saved");
112
- }
113
- });
114
-
115
- const showSkeleton = computed(() => Boolean(addEdit.isInitialLoading));
116
- </script>
@@ -1,102 +0,0 @@
1
- <template>
2
- <section class="workspace-settings-client-element">
3
- <WorkspaceProfileClientElement @saved="handleFormSaved" />
4
- <WorkspaceSettingsFieldsClientElement @saved="handleFormSaved" />
5
- </section>
6
- </template>
7
-
8
- <script setup>
9
- import { computed, watch } from "vue";
10
- import { useWebPlacementContext } from "@jskit-ai/shell-web/client/placement";
11
- import { useBootstrapQuery } from "../composables/useBootstrapQuery.js";
12
- import { useWorkspaceRouteContext } from "../composables/useWorkspaceRouteContext.js";
13
- import { findWorkspaceBySlug, normalizeWorkspaceList } from "../lib/bootstrap.js";
14
- import { arePermissionListsEqual, normalizePermissionList } from "../lib/permissions.js";
15
- import WorkspaceProfileClientElement from "./WorkspaceProfileClientElement.vue";
16
- import WorkspaceSettingsFieldsClientElement from "./WorkspaceSettingsFieldsClientElement.vue";
17
-
18
- const routeContext = useWorkspaceRouteContext();
19
- const { context: placementContext, mergeContext: mergePlacementContext } = useWebPlacementContext();
20
- const bootstrapQuery = useBootstrapQuery({
21
- workspaceSlug: routeContext.workspaceSlugFromRoute,
22
- enabled: computed(() => Boolean(routeContext.workspaceSlugFromRoute.value))
23
- });
24
-
25
- function toWorkspaceEntrySnapshot(entry = null) {
26
- if (!entry || typeof entry !== "object") {
27
- return "";
28
- }
29
-
30
- const normalizedEntry = normalizeWorkspaceList([entry])[0] || null;
31
- if (!normalizedEntry) {
32
- return "";
33
- }
34
-
35
- return JSON.stringify(normalizedEntry);
36
- }
37
-
38
- function toWorkspaceListSnapshot(list = []) {
39
- return JSON.stringify(normalizeWorkspaceList(list));
40
- }
41
-
42
- function toWorkspaceSettingsSnapshot(settings = null) {
43
- if (!settings || typeof settings !== "object") {
44
- return "";
45
- }
46
-
47
- return JSON.stringify(settings);
48
- }
49
-
50
- function applyShellWorkspaceContext(payload = {}) {
51
- const availableWorkspaces = normalizeWorkspaceList(payload?.workspaces);
52
- const currentWorkspace = findWorkspaceBySlug(
53
- availableWorkspaces,
54
- routeContext.workspaceSlugFromRoute.value
55
- );
56
- const permissions = normalizePermissionList(payload?.permissions);
57
- const currentContext =
58
- placementContext.value && typeof placementContext.value === "object"
59
- ? placementContext.value
60
- : {};
61
- const currentPermissions = normalizePermissionList(currentContext.permissions);
62
- const samePermissions = arePermissionListsEqual(permissions, currentPermissions);
63
- const sameWorkspace = toWorkspaceEntrySnapshot(currentContext.workspace) === toWorkspaceEntrySnapshot(currentWorkspace);
64
- const sameWorkspaces =
65
- toWorkspaceListSnapshot(currentContext.workspaces) === toWorkspaceListSnapshot(availableWorkspaces);
66
- const sameWorkspaceSettings =
67
- toWorkspaceSettingsSnapshot(currentContext.workspaceSettings) ===
68
- toWorkspaceSettingsSnapshot(payload?.workspaceSettings);
69
-
70
- if (samePermissions && sameWorkspace && sameWorkspaces && sameWorkspaceSettings) {
71
- return;
72
- }
73
-
74
- mergePlacementContext(
75
- {
76
- workspace: currentWorkspace,
77
- workspaceSettings:
78
- payload?.workspaceSettings && typeof payload.workspaceSettings === "object"
79
- ? payload.workspaceSettings
80
- : null,
81
- workspaces: availableWorkspaces,
82
- permissions
83
- },
84
- "users-web.workspace-settings-view"
85
- );
86
- }
87
-
88
- watch(
89
- () => bootstrapQuery.query.data.value,
90
- (payload) => {
91
- if (!payload || typeof payload !== "object") {
92
- return;
93
- }
94
- applyShellWorkspaceContext(payload);
95
- },
96
- { immediate: true }
97
- );
98
-
99
- async function handleFormSaved() {
100
- await bootstrapQuery.query.refetch();
101
- }
102
- </script>
@@ -1,265 +0,0 @@
1
- <template>
2
- <v-card rounded="lg" elevation="1" border>
3
- <v-card-item>
4
- <v-card-title class="text-h6">Workspace settings</v-card-title>
5
- <v-card-subtitle>These values apply to everyone in this workspace.</v-card-subtitle>
6
- </v-card-item>
7
- <v-divider />
8
- <v-card-text class="pt-4">
9
- <template v-if="showSkeleton">
10
- <v-skeleton-loader type="text@2, list-item-two-line@4, button" />
11
- </template>
12
-
13
- <p v-else-if="addEdit.loadError" class="text-body-2 text-medium-emphasis mb-4">
14
- {{ addEdit.loadError }}
15
- </p>
16
-
17
- <p v-else-if="!addEdit.canView" class="text-body-2 text-medium-emphasis mb-4">
18
- You do not have permission to view workspace settings.
19
- </p>
20
-
21
- <template v-else>
22
- <v-form @submit.prevent="addEdit.submit" novalidate>
23
- <v-progress-linear v-if="addEdit.isRefetching" indeterminate class="mb-4" />
24
- <v-row>
25
- <v-col cols="12">
26
- <div class="text-subtitle-2 mb-2">Theme colors</div>
27
- <v-row dense class="mb-2">
28
- <v-col cols="12">
29
- <div class="text-caption text-medium-emphasis mb-2">Light palette</div>
30
- </v-col>
31
- <v-col cols="12" md="3">
32
- <v-text-field
33
- v-model="workspaceSettingsForm.lightPrimaryColor"
34
- label="Primary"
35
- type="color"
36
- variant="outlined"
37
- density="comfortable"
38
- :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
39
- :error-messages="addEdit.fieldErrors.lightPrimaryColor ? [addEdit.fieldErrors.lightPrimaryColor] : []"
40
- />
41
- </v-col>
42
-
43
- <v-col cols="12" md="3">
44
- <v-text-field
45
- v-model="workspaceSettingsForm.lightSecondaryColor"
46
- label="Secondary"
47
- type="color"
48
- variant="outlined"
49
- density="comfortable"
50
- :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
51
- :error-messages="
52
- addEdit.fieldErrors.lightSecondaryColor ? [addEdit.fieldErrors.lightSecondaryColor] : []
53
- "
54
- />
55
- </v-col>
56
-
57
- <v-col cols="12" md="3">
58
- <v-text-field
59
- v-model="workspaceSettingsForm.lightSurfaceColor"
60
- label="Surface"
61
- type="color"
62
- variant="outlined"
63
- density="comfortable"
64
- :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
65
- :error-messages="addEdit.fieldErrors.lightSurfaceColor ? [addEdit.fieldErrors.lightSurfaceColor] : []"
66
- />
67
- </v-col>
68
-
69
- <v-col cols="12" md="3">
70
- <v-text-field
71
- v-model="workspaceSettingsForm.lightSurfaceVariantColor"
72
- label="Surface variant"
73
- type="color"
74
- variant="outlined"
75
- density="comfortable"
76
- :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
77
- :error-messages="
78
- addEdit.fieldErrors.lightSurfaceVariantColor ? [addEdit.fieldErrors.lightSurfaceVariantColor] : []
79
- "
80
- />
81
- </v-col>
82
- </v-row>
83
-
84
- <v-row dense>
85
- <v-col cols="12">
86
- <div class="text-caption text-medium-emphasis mb-2">Dark palette</div>
87
- </v-col>
88
- <v-col cols="12" md="3">
89
- <v-text-field
90
- v-model="workspaceSettingsForm.darkPrimaryColor"
91
- label="Primary"
92
- type="color"
93
- variant="outlined"
94
- density="comfortable"
95
- :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
96
- :error-messages="addEdit.fieldErrors.darkPrimaryColor ? [addEdit.fieldErrors.darkPrimaryColor] : []"
97
- />
98
- </v-col>
99
-
100
- <v-col cols="12" md="3">
101
- <v-text-field
102
- v-model="workspaceSettingsForm.darkSecondaryColor"
103
- label="Secondary"
104
- type="color"
105
- variant="outlined"
106
- density="comfortable"
107
- :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
108
- :error-messages="addEdit.fieldErrors.darkSecondaryColor ? [addEdit.fieldErrors.darkSecondaryColor] : []"
109
- />
110
- </v-col>
111
-
112
- <v-col cols="12" md="3">
113
- <v-text-field
114
- v-model="workspaceSettingsForm.darkSurfaceColor"
115
- label="Surface"
116
- type="color"
117
- variant="outlined"
118
- density="comfortable"
119
- :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
120
- :error-messages="addEdit.fieldErrors.darkSurfaceColor ? [addEdit.fieldErrors.darkSurfaceColor] : []"
121
- />
122
- </v-col>
123
-
124
- <v-col cols="12" md="3">
125
- <v-text-field
126
- v-model="workspaceSettingsForm.darkSurfaceVariantColor"
127
- label="Surface variant"
128
- type="color"
129
- variant="outlined"
130
- density="comfortable"
131
- :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
132
- :error-messages="
133
- addEdit.fieldErrors.darkSurfaceVariantColor ? [addEdit.fieldErrors.darkSurfaceVariantColor] : []
134
- "
135
- />
136
- </v-col>
137
- </v-row>
138
- </v-col>
139
-
140
- <v-col cols="12" md="6" class="d-flex align-center">
141
- <v-switch
142
- v-model="workspaceSettingsForm.invitesEnabled"
143
- color="primary"
144
- hide-details
145
- label="Enable invites"
146
- :disabled="!addEdit.canSave || !workspaceSettingsForm.invitesAvailable || addEdit.isSaving || addEdit.isRefetching"
147
- />
148
- </v-col>
149
-
150
- <v-col cols="12" class="d-flex align-center justify-end ga-3">
151
- <v-btn
152
- v-if="addEdit.canSave"
153
- type="submit"
154
- color="primary"
155
- :loading="addEdit.isSaving"
156
- :disabled="addEdit.isInitialLoading || addEdit.isRefetching"
157
- >
158
- Save workspace settings
159
- </v-btn>
160
- <v-chip v-else color="secondary" label>Read-only</v-chip>
161
- </v-col>
162
- </v-row>
163
- </v-form>
164
- </template>
165
- </v-card-text>
166
- </v-card>
167
- </template>
168
-
169
- <script setup>
170
- import { computed, reactive } from "vue";
171
- import { validateOperationSection } from "@jskit-ai/http-runtime/shared/validators/operationValidation";
172
- import { workspaceSettingsResource } from "@jskit-ai/users-core/shared/resources/workspaceSettingsResource";
173
- import { USERS_ROUTE_VISIBILITY_WORKSPACE } from "@jskit-ai/users-core/shared/support/usersVisibility";
174
- import {
175
- DEFAULT_WORKSPACE_DARK_PALETTE,
176
- DEFAULT_WORKSPACE_LIGHT_PALETTE,
177
- resolveWorkspaceThemePalettes
178
- } from "@jskit-ai/users-core/shared/settings";
179
- import { useAddEdit } from "../composables/records/useAddEdit.js";
180
- import { useWorkspaceRouteContext } from "../composables/useWorkspaceRouteContext.js";
181
- import { createWorkspaceRealtimeMatcher } from "../support/realtimeWorkspace.js";
182
- import { buildWorkspaceQueryKey } from "../support/workspaceQueryKeys.js";
183
-
184
- const emit = defineEmits(["saved"]);
185
-
186
- const workspaceSettingsForm = reactive({
187
- lightPrimaryColor: DEFAULT_WORKSPACE_LIGHT_PALETTE.color,
188
- lightSecondaryColor: DEFAULT_WORKSPACE_LIGHT_PALETTE.secondaryColor,
189
- lightSurfaceColor: DEFAULT_WORKSPACE_LIGHT_PALETTE.surfaceColor,
190
- lightSurfaceVariantColor: DEFAULT_WORKSPACE_LIGHT_PALETTE.surfaceVariantColor,
191
- darkPrimaryColor: DEFAULT_WORKSPACE_DARK_PALETTE.color,
192
- darkSecondaryColor: DEFAULT_WORKSPACE_DARK_PALETTE.secondaryColor,
193
- darkSurfaceColor: DEFAULT_WORKSPACE_DARK_PALETTE.surfaceColor,
194
- darkSurfaceVariantColor: DEFAULT_WORKSPACE_DARK_PALETTE.surfaceVariantColor,
195
- invitesEnabled: false,
196
- invitesAvailable: false
197
- });
198
-
199
- const routeContext = useWorkspaceRouteContext();
200
- const matchesWorkspaceRealtime = createWorkspaceRealtimeMatcher(routeContext.workspaceSlugFromRoute);
201
-
202
- const addEdit = useAddEdit({
203
- ownershipFilter: USERS_ROUTE_VISIBILITY_WORKSPACE,
204
- resource: workspaceSettingsResource,
205
- apiSuffix: "/settings",
206
- queryKeyFactory: (surfaceId = "", workspaceSlug = "") =>
207
- buildWorkspaceQueryKey("settings", surfaceId, workspaceSlug),
208
- viewPermissions: ["workspace.settings.view", "workspace.settings.update"],
209
- savePermissions: ["workspace.settings.update"],
210
- placementSource: "users-web.workspace-settings-view",
211
- fallbackLoadError: "Unable to load workspace settings.",
212
- fieldErrorKeys: [
213
- "lightPrimaryColor",
214
- "lightSecondaryColor",
215
- "lightSurfaceColor",
216
- "lightSurfaceVariantColor",
217
- "darkPrimaryColor",
218
- "darkSecondaryColor",
219
- "darkSurfaceColor",
220
- "darkSurfaceVariantColor"
221
- ],
222
- realtime: {
223
- event: "workspace.settings.changed",
224
- matches: matchesWorkspaceRealtime
225
- },
226
- model: workspaceSettingsForm,
227
- parseInput: (rawPayload) =>
228
- validateOperationSection({
229
- operation: workspaceSettingsResource.operations.patch,
230
- section: "bodyValidator",
231
- value: rawPayload
232
- }),
233
- mapLoadedToModel: (model, payload = {}) => {
234
- const settings = payload?.settings && typeof payload.settings === "object" ? payload.settings : {};
235
- const normalizedTheme = resolveWorkspaceThemePalettes(settings);
236
-
237
- model.lightPrimaryColor = normalizedTheme.light.color;
238
- model.lightSecondaryColor = normalizedTheme.light.secondaryColor;
239
- model.lightSurfaceColor = normalizedTheme.light.surfaceColor;
240
- model.lightSurfaceVariantColor = normalizedTheme.light.surfaceVariantColor;
241
- model.darkPrimaryColor = normalizedTheme.dark.color;
242
- model.darkSecondaryColor = normalizedTheme.dark.secondaryColor;
243
- model.darkSurfaceColor = normalizedTheme.dark.surfaceColor;
244
- model.darkSurfaceVariantColor = normalizedTheme.dark.surfaceVariantColor;
245
- model.invitesEnabled = settings.invitesEnabled !== false;
246
- model.invitesAvailable = settings.invitesAvailable !== false;
247
- },
248
- buildRawPayload: (model) => ({
249
- lightPrimaryColor: model.lightPrimaryColor,
250
- lightSecondaryColor: model.lightSecondaryColor,
251
- lightSurfaceColor: model.lightSurfaceColor,
252
- lightSurfaceVariantColor: model.lightSurfaceVariantColor,
253
- darkPrimaryColor: model.darkPrimaryColor,
254
- darkSecondaryColor: model.darkSecondaryColor,
255
- darkSurfaceColor: model.darkSurfaceColor,
256
- darkSurfaceVariantColor: model.darkSurfaceVariantColor,
257
- invitesEnabled: model.invitesEnabled
258
- }),
259
- onSaveSuccess: async () => {
260
- emit("saved");
261
- }
262
- });
263
-
264
- const showSkeleton = computed(() => Boolean(addEdit.isInitialLoading));
265
- </script>