@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
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
</
|
|
7
|
-
|
|
8
|
-
<
|
|
2
|
+
<v-sheet rounded="lg" border class="workspace-settings-panel">
|
|
3
|
+
<header class="workspace-settings-panel__header">
|
|
4
|
+
<h2 class="workspace-settings-panel__title">Workspace settings</h2>
|
|
5
|
+
<p class="text-body-2 text-medium-emphasis mb-0">These values apply to everyone in this workspace.</p>
|
|
6
|
+
</header>
|
|
7
|
+
|
|
8
|
+
<div class="workspace-settings-panel__body">
|
|
9
9
|
<template v-if="showSkeleton">
|
|
10
10
|
<v-skeleton-loader type="text@2, list-item-two-line@4, button" />
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
|
-
<
|
|
14
|
-
{{ addEdit.loadError }}
|
|
15
|
-
|
|
13
|
+
<div v-else-if="addEdit.loadError" class="workspace-settings-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 settings.
|
|
@@ -162,8 +171,8 @@
|
|
|
162
171
|
</v-row>
|
|
163
172
|
</v-form>
|
|
164
173
|
</template>
|
|
165
|
-
</
|
|
166
|
-
</v-
|
|
174
|
+
</div>
|
|
175
|
+
</v-sheet>
|
|
167
176
|
</template>
|
|
168
177
|
|
|
169
178
|
<script setup>
|
|
@@ -259,3 +268,37 @@ const addEdit = useAddEdit({
|
|
|
259
268
|
|
|
260
269
|
const showSkeleton = computed(() => Boolean(addEdit.isInitialLoading));
|
|
261
270
|
</script>
|
|
271
|
+
|
|
272
|
+
<style scoped>
|
|
273
|
+
.workspace-settings-panel {
|
|
274
|
+
overflow: hidden;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.workspace-settings-panel__header {
|
|
278
|
+
padding: 1rem 1rem 0;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.workspace-settings-panel__title {
|
|
282
|
+
font-size: 1rem;
|
|
283
|
+
font-weight: 650;
|
|
284
|
+
line-height: 1.2;
|
|
285
|
+
margin: 0 0 0.25rem;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.workspace-settings-panel__body {
|
|
289
|
+
padding: 1rem;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.workspace-settings-panel__state {
|
|
293
|
+
margin-inline: auto;
|
|
294
|
+
max-width: 30rem;
|
|
295
|
+
padding: 1.5rem 1rem;
|
|
296
|
+
text-align: center;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
@media (max-width: 640px) {
|
|
300
|
+
.workspace-settings-panel__body :deep(.v-btn) {
|
|
301
|
+
min-height: 48px;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
</style>
|
|
@@ -163,13 +163,14 @@ const workspaceInvitesEnabled = computed(() => bootstrapModel.workspaceInvitesEn
|
|
|
163
163
|
|
|
164
164
|
const isBootstrapping = computed(() => Boolean(bootstrapView.isLoading));
|
|
165
165
|
const isRefreshingBootstrap = computed(() => Boolean(bootstrapView.isRefetching));
|
|
166
|
+
const bootstrapLoadError = computed(() => String(bootstrapView.loadError || "").trim());
|
|
166
167
|
const canCreateWorkspace = computed(() => bootstrapModel.workspaceAllowSelfCreate === true);
|
|
167
168
|
const isCreatingWorkspace = computed(() => Boolean(createWorkspaceCommand.isRunning.value));
|
|
168
169
|
|
|
169
170
|
function reportFeedback({
|
|
170
171
|
message,
|
|
171
172
|
severity = "error",
|
|
172
|
-
channel = "
|
|
173
|
+
channel = "",
|
|
173
174
|
dedupeKey = ""
|
|
174
175
|
} = {}) {
|
|
175
176
|
const normalizedMessage = String(message || "").trim();
|
|
@@ -180,6 +181,7 @@ function reportFeedback({
|
|
|
180
181
|
errorRuntime.report({
|
|
181
182
|
source: "users-web.workspaces-view",
|
|
182
183
|
message: normalizedMessage,
|
|
184
|
+
intent: "action-feedback",
|
|
183
185
|
severity,
|
|
184
186
|
channel,
|
|
185
187
|
dedupeKey: dedupeKey || `users-web.workspaces-view:${severity}:${normalizedMessage}`,
|
|
@@ -233,7 +235,6 @@ async function openWorkspace(workspaceSlug) {
|
|
|
233
235
|
reportFeedback({
|
|
234
236
|
message: "Workspace surface is not configured.",
|
|
235
237
|
severity: "error",
|
|
236
|
-
channel: "banner",
|
|
237
238
|
dedupeKey: "users-web.workspaces-view:workspace-surface-missing"
|
|
238
239
|
});
|
|
239
240
|
return;
|
|
@@ -258,7 +259,6 @@ async function openWorkspace(workspaceSlug) {
|
|
|
258
259
|
reportFeedback({
|
|
259
260
|
message: String(error?.message || "Unable to open workspace."),
|
|
260
261
|
severity: "error",
|
|
261
|
-
channel: "banner",
|
|
262
262
|
dedupeKey: `users-web.workspaces-view:open-workspace:${normalizedSlug}`
|
|
263
263
|
});
|
|
264
264
|
} finally {
|
|
@@ -301,7 +301,6 @@ async function respondToInvite(invite, decision) {
|
|
|
301
301
|
reportFeedback({
|
|
302
302
|
message: "Invitation refused.",
|
|
303
303
|
severity: "success",
|
|
304
|
-
channel: "snackbar",
|
|
305
304
|
dedupeKey: `users-web.workspaces-view:invite-refused:${token}`
|
|
306
305
|
});
|
|
307
306
|
} catch (error) {
|
|
@@ -310,7 +309,6 @@ async function respondToInvite(invite, decision) {
|
|
|
310
309
|
error?.message || (normalizedDecision === "accept" ? "Unable to accept invite." : "Unable to refuse invite.")
|
|
311
310
|
),
|
|
312
311
|
severity: "error",
|
|
313
|
-
channel: "banner",
|
|
314
312
|
dedupeKey: `users-web.workspaces-view:invite-${normalizedDecision}:${token}`
|
|
315
313
|
});
|
|
316
314
|
} finally {
|
|
@@ -341,7 +339,6 @@ async function createWorkspace() {
|
|
|
341
339
|
reportFeedback({
|
|
342
340
|
message: "Workspace name is required.",
|
|
343
341
|
severity: "error",
|
|
344
|
-
channel: "banner",
|
|
345
342
|
dedupeKey: "users-web.workspaces-view:create-workspace-name-required"
|
|
346
343
|
});
|
|
347
344
|
return;
|
|
@@ -361,12 +358,15 @@ async function createWorkspace() {
|
|
|
361
358
|
reportFeedback({
|
|
362
359
|
message: String(error?.message || "Unable to create workspace."),
|
|
363
360
|
severity: "error",
|
|
364
|
-
channel: "banner",
|
|
365
361
|
dedupeKey: "users-web.workspaces-view:create-workspace-error"
|
|
366
362
|
});
|
|
367
363
|
}
|
|
368
364
|
}
|
|
369
365
|
|
|
366
|
+
async function refreshBootstrap() {
|
|
367
|
+
return bootstrapView.refresh();
|
|
368
|
+
}
|
|
369
|
+
|
|
370
370
|
watch(
|
|
371
371
|
() => bootstrapView.resource.data.value,
|
|
372
372
|
async (payload) => {
|
|
@@ -401,20 +401,31 @@ watch(
|
|
|
401
401
|
<template>
|
|
402
402
|
<section class="workspaces-view py-6">
|
|
403
403
|
<v-container class="mx-auto" max-width="860">
|
|
404
|
-
<v-
|
|
405
|
-
<
|
|
406
|
-
<
|
|
407
|
-
<
|
|
408
|
-
</
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
<v-card-text class="pt-4">
|
|
404
|
+
<v-sheet rounded="lg" border class="workspaces-view__panel">
|
|
405
|
+
<header class="workspaces-view__header">
|
|
406
|
+
<h1 class="workspaces-view__title">You are logged in</h1>
|
|
407
|
+
<p class="text-body-2 text-medium-emphasis mb-0">Select a workspace or respond to invitations.</p>
|
|
408
|
+
</header>
|
|
409
|
+
|
|
410
|
+
<div class="workspaces-view__body">
|
|
412
411
|
<v-progress-linear v-if="!isBootstrapping && isRefreshingBootstrap" indeterminate class="mb-4" />
|
|
413
412
|
<v-row>
|
|
414
413
|
<v-col cols="12" :md="workspaceInvitesEnabled ? 6 : 12">
|
|
415
414
|
<template v-if="isBootstrapping">
|
|
416
415
|
<v-skeleton-loader type="text, list-item-avatar-two-line@3" />
|
|
417
416
|
</template>
|
|
417
|
+
<div v-else-if="bootstrapLoadError" class="workspaces-view__state">
|
|
418
|
+
<h2 class="text-h6 mb-2">Unable to load workspaces</h2>
|
|
419
|
+
<p class="text-body-2 text-medium-emphasis mb-4">{{ bootstrapLoadError }}</p>
|
|
420
|
+
<v-btn
|
|
421
|
+
color="primary"
|
|
422
|
+
variant="tonal"
|
|
423
|
+
:loading="isRefreshingBootstrap"
|
|
424
|
+
@click="refreshBootstrap"
|
|
425
|
+
>
|
|
426
|
+
Retry
|
|
427
|
+
</v-btn>
|
|
428
|
+
</div>
|
|
418
429
|
<template v-else>
|
|
419
430
|
<div class="text-subtitle-2 mb-2">Your workspaces</div>
|
|
420
431
|
<template v-if="workspaceItems.length === 0">
|
|
@@ -539,8 +550,47 @@ watch(
|
|
|
539
550
|
</template>
|
|
540
551
|
</v-col>
|
|
541
552
|
</v-row>
|
|
542
|
-
</
|
|
543
|
-
</v-
|
|
553
|
+
</div>
|
|
554
|
+
</v-sheet>
|
|
544
555
|
</v-container>
|
|
545
556
|
</section>
|
|
546
557
|
</template>
|
|
558
|
+
|
|
559
|
+
<style scoped>
|
|
560
|
+
.workspaces-view__panel {
|
|
561
|
+
overflow: hidden;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
.workspaces-view__header {
|
|
565
|
+
padding: 1rem 1rem 0;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
.workspaces-view__title {
|
|
569
|
+
font-size: clamp(1.35rem, 2vw, 1.85rem);
|
|
570
|
+
font-weight: 650;
|
|
571
|
+
letter-spacing: -0.02em;
|
|
572
|
+
line-height: 1.15;
|
|
573
|
+
margin: 0 0 0.35rem;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
.workspaces-view__body {
|
|
577
|
+
padding: 1rem;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
.workspaces-view__state {
|
|
581
|
+
margin-inline: auto;
|
|
582
|
+
max-width: 30rem;
|
|
583
|
+
padding: 2rem 1rem;
|
|
584
|
+
text-align: center;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
@media (max-width: 640px) {
|
|
588
|
+
.workspaces-view {
|
|
589
|
+
padding-block: 0.75rem !important;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.workspaces-view__body :deep(.v-btn) {
|
|
593
|
+
min-height: 48px;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
</style>
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
const DEFAULT_COG_LINK_COMPONENT_TOKEN = "local.main.ui.surface-aware-menu-link-item";
|
|
2
|
-
|
|
3
1
|
const ADMIN_COG_OUTLET = Object.freeze({
|
|
4
2
|
target: "admin-cog:primary-menu",
|
|
5
|
-
defaultLinkComponentToken: DEFAULT_COG_LINK_COMPONENT_TOKEN,
|
|
6
3
|
ariaLabel: "Admin cog"
|
|
7
4
|
});
|
|
8
5
|
|
|
9
|
-
export {
|
|
6
|
+
export { ADMIN_COG_OUTLET };
|
|
@@ -18,17 +18,36 @@ const normalizedMessage = computed(() => String(props.message || "").trim() || "
|
|
|
18
18
|
</script>
|
|
19
19
|
|
|
20
20
|
<template>
|
|
21
|
-
<v-
|
|
22
|
-
<
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
</
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
<p class="text-medium-emphasis mb-0">{{ normalizedMessage }}</p>
|
|
32
|
-
</v-card-text>
|
|
33
|
-
</v-card>
|
|
21
|
+
<v-sheet rounded="lg" border class="workspace-unavailable-panel">
|
|
22
|
+
<div class="workspace-unavailable-panel__header">
|
|
23
|
+
<v-icon :icon="mdiAlertCircleOutline" color="error" />
|
|
24
|
+
<div>
|
|
25
|
+
<h1 class="workspace-unavailable-panel__title">Unavailable</h1>
|
|
26
|
+
<p class="text-body-2 text-medium-emphasis mb-0">{{ normalizedSurfaceLabel }} surface.</p>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
<p class="text-body-2 text-medium-emphasis mb-0">{{ normalizedMessage }}</p>
|
|
30
|
+
</v-sheet>
|
|
34
31
|
</template>
|
|
32
|
+
|
|
33
|
+
<style scoped>
|
|
34
|
+
.workspace-unavailable-panel {
|
|
35
|
+
display: grid;
|
|
36
|
+
gap: 1rem;
|
|
37
|
+
padding: 1rem;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.workspace-unavailable-panel__header {
|
|
41
|
+
align-items: flex-start;
|
|
42
|
+
display: flex;
|
|
43
|
+
gap: 0.75rem;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.workspace-unavailable-panel__title {
|
|
47
|
+
font-size: clamp(1.35rem, 2vw, 1.85rem);
|
|
48
|
+
font-weight: 650;
|
|
49
|
+
letter-spacing: -0.02em;
|
|
50
|
+
line-height: 1.15;
|
|
51
|
+
margin: 0 0 0.25rem;
|
|
52
|
+
}
|
|
53
|
+
</style>
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
|
|
3
|
-
// import { redirectToChild } from "@jskit-ai/kernel/client/pageRedirects";
|
|
4
|
-
// definePage({
|
|
5
|
-
// redirect: redirectToChild("your_child_segment")
|
|
6
|
-
// });
|
|
2
|
+
import WorkspaceSettingsClientElement from "@jskit-ai/workspaces-web/client/components/WorkspaceSettingsClientElement";
|
|
7
3
|
</script>
|
|
8
4
|
|
|
9
5
|
<template>
|
|
10
|
-
<
|
|
6
|
+
<WorkspaceSettingsClientElement />
|
|
11
7
|
</template>
|
|
@@ -5,28 +5,66 @@ import { RouterView } from "vue-router";
|
|
|
5
5
|
|
|
6
6
|
<template>
|
|
7
7
|
<section class="settings-shell d-flex flex-column ga-4">
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
<v-col cols="12" md="9" lg="10">
|
|
26
|
-
<RouterView />
|
|
27
|
-
</v-col>
|
|
28
|
-
</v-row>
|
|
29
|
-
</v-card-text>
|
|
30
|
-
</v-card>
|
|
8
|
+
<header>
|
|
9
|
+
<p class="text-overline text-medium-emphasis mb-1">Settings</p>
|
|
10
|
+
<h1 class="settings-shell__title">Workspace settings</h1>
|
|
11
|
+
<p class="text-body-2 text-medium-emphasis mb-0">Configure the current workspace and its members.</p>
|
|
12
|
+
</header>
|
|
13
|
+
|
|
14
|
+
<v-sheet rounded="lg" border class="settings-shell__panel">
|
|
15
|
+
<nav class="settings-shell__nav" aria-label="Workspace settings sections">
|
|
16
|
+
<v-list nav density="comfortable" class="settings-shell__nav-list">
|
|
17
|
+
<ShellOutlet target="admin-settings:primary-menu" />
|
|
18
|
+
</v-list>
|
|
19
|
+
</nav>
|
|
20
|
+
<main class="settings-shell__content">
|
|
21
|
+
<RouterView />
|
|
22
|
+
</main>
|
|
23
|
+
</v-sheet>
|
|
31
24
|
</section>
|
|
32
25
|
</template>
|
|
26
|
+
|
|
27
|
+
<style scoped>
|
|
28
|
+
.settings-shell__title {
|
|
29
|
+
font-size: clamp(1.35rem, 2vw, 1.85rem);
|
|
30
|
+
font-weight: 650;
|
|
31
|
+
letter-spacing: -0.02em;
|
|
32
|
+
line-height: 1.15;
|
|
33
|
+
margin: 0 0 0.35rem;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.settings-shell__panel {
|
|
37
|
+
display: grid;
|
|
38
|
+
gap: 1rem;
|
|
39
|
+
grid-template-columns: minmax(12rem, 16rem) minmax(0, 1fr);
|
|
40
|
+
padding: 1rem;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.settings-shell__nav-list {
|
|
44
|
+
padding: 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.settings-shell__content {
|
|
48
|
+
min-width: 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@media (max-width: 960px) {
|
|
52
|
+
.settings-shell__panel {
|
|
53
|
+
grid-template-columns: 1fr;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.settings-shell__nav {
|
|
57
|
+
overflow-x: auto;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.settings-shell__nav-list {
|
|
61
|
+
display: flex;
|
|
62
|
+
gap: 0.5rem;
|
|
63
|
+
min-width: max-content;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.settings-shell__nav-list :deep(.v-list-item) {
|
|
67
|
+
min-height: 48px;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
</style>
|
|
@@ -11,19 +11,67 @@ const { workspaceUnavailable, workspaceUnavailableMessage } = useWorkspaceNotFou
|
|
|
11
11
|
:message="workspaceUnavailableMessage"
|
|
12
12
|
surface-label="Admin"
|
|
13
13
|
/>
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
<
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
<section v-else class="workspace-admin-screen d-flex flex-column ga-4">
|
|
15
|
+
<header class="workspace-admin-screen__header">
|
|
16
|
+
<div>
|
|
17
|
+
<p class="text-overline text-medium-emphasis mb-1">Admin</p>
|
|
18
|
+
<h1 class="workspace-admin-screen__title">Workspace Admin</h1>
|
|
19
|
+
<p class="text-body-2 text-medium-emphasis mb-0">Manage members and workspace settings.</p>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="workspace-admin-screen__actions">
|
|
22
|
+
<v-btn color="primary" variant="flat" to="./members">Members</v-btn>
|
|
23
|
+
<v-btn color="primary" variant="tonal" to="./workspace/settings">Settings</v-btn>
|
|
24
|
+
</div>
|
|
25
|
+
</header>
|
|
26
|
+
|
|
27
|
+
<v-sheet rounded="lg" border class="workspace-admin-screen__panel">
|
|
28
|
+
<h2 class="text-h6 mb-2">Admin tasks</h2>
|
|
29
|
+
<p class="text-body-2 text-medium-emphasis mb-0">
|
|
30
|
+
Review workspace access, members, and operational settings from this surface.
|
|
26
31
|
</p>
|
|
27
|
-
</v-
|
|
28
|
-
</
|
|
32
|
+
</v-sheet>
|
|
33
|
+
</section>
|
|
29
34
|
</template>
|
|
35
|
+
|
|
36
|
+
<style scoped>
|
|
37
|
+
.workspace-admin-screen__header {
|
|
38
|
+
align-items: flex-start;
|
|
39
|
+
display: flex;
|
|
40
|
+
gap: 1rem;
|
|
41
|
+
justify-content: space-between;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.workspace-admin-screen__title {
|
|
45
|
+
font-size: clamp(1.5rem, 2.5vw, 2.25rem);
|
|
46
|
+
font-weight: 700;
|
|
47
|
+
letter-spacing: -0.03em;
|
|
48
|
+
line-height: 1.1;
|
|
49
|
+
margin: 0 0 0.4rem;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.workspace-admin-screen__actions {
|
|
53
|
+
display: flex;
|
|
54
|
+
flex-wrap: wrap;
|
|
55
|
+
gap: 0.5rem;
|
|
56
|
+
justify-content: flex-end;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.workspace-admin-screen__panel {
|
|
60
|
+
padding: 1rem;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@media (max-width: 640px) {
|
|
64
|
+
.workspace-admin-screen__header {
|
|
65
|
+
flex-direction: column;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.workspace-admin-screen__actions {
|
|
69
|
+
width: 100%;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.workspace-admin-screen__actions :deep(.v-btn) {
|
|
73
|
+
min-height: 48px;
|
|
74
|
+
flex: 1 1 10rem;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
</style>
|
|
@@ -11,17 +11,36 @@ const { workspaceUnavailable, workspaceUnavailableMessage } = useWorkspaceNotFou
|
|
|
11
11
|
:message="workspaceUnavailableMessage"
|
|
12
12
|
surface-label="App"
|
|
13
13
|
/>
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
14
|
+
<section v-else class="workspace-home-screen d-flex flex-column ga-4">
|
|
15
|
+
<header>
|
|
16
|
+
<p class="text-overline text-medium-emphasis mb-1">Workspace</p>
|
|
17
|
+
<h1 class="workspace-home-screen__title">Workspace Home</h1>
|
|
18
|
+
<p class="text-body-2 text-medium-emphasis mb-0">The current workspace is active.</p>
|
|
19
|
+
</header>
|
|
20
|
+
|
|
21
|
+
<v-sheet rounded="lg" border class="workspace-home-screen__panel">
|
|
22
|
+
<h2 class="text-h6 mb-2">No workspace activity yet</h2>
|
|
23
|
+
<p class="text-body-2 text-medium-emphasis mb-0">
|
|
24
|
+
Activity from workspace workflows will appear here.
|
|
25
|
+
</p>
|
|
26
|
+
</v-sheet>
|
|
27
|
+
</section>
|
|
27
28
|
</template>
|
|
29
|
+
|
|
30
|
+
<style scoped>
|
|
31
|
+
.workspace-home-screen__title {
|
|
32
|
+
font-size: clamp(1.5rem, 2.5vw, 2.25rem);
|
|
33
|
+
font-weight: 700;
|
|
34
|
+
letter-spacing: -0.03em;
|
|
35
|
+
line-height: 1.1;
|
|
36
|
+
margin: 0 0 0.4rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.workspace-home-screen__panel {
|
|
40
|
+
margin-inline: auto;
|
|
41
|
+
max-width: 34rem;
|
|
42
|
+
padding: 2rem 1.25rem;
|
|
43
|
+
text-align: center;
|
|
44
|
+
width: 100%;
|
|
45
|
+
}
|
|
46
|
+
</style>
|
|
@@ -16,6 +16,7 @@ test("workspaces-web exports are explicit and aligned with production usage", ()
|
|
|
16
16
|
requiredExports: [
|
|
17
17
|
"./client",
|
|
18
18
|
"./client/components/AccountSettingsInvitesSection",
|
|
19
|
+
"./client/components/WorkspaceSettingsClientElement",
|
|
19
20
|
"./client/providers/WorkspacesWebClientProvider",
|
|
20
21
|
"./client/composables/useWorkspaceRouteContext"
|
|
21
22
|
]
|