@stapel/workspaces-react 0.17.0 → 0.19.1
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/CHANGELOG.md +218 -0
- package/README.md +39 -8
- package/dist/api/generated/schema.d.ts +187 -60
- package/dist/api/generated/schema.d.ts.map +1 -1
- package/dist/default/ActiveWorkspace.d.ts +43 -0
- package/dist/default/ActiveWorkspace.d.ts.map +1 -0
- package/dist/default/ActiveWorkspace.js +33 -0
- package/dist/default/ActiveWorkspace.js.map +1 -0
- package/dist/default/AuditTrailPane.d.ts +12 -0
- package/dist/default/AuditTrailPane.d.ts.map +1 -0
- package/dist/default/AuditTrailPane.js +154 -0
- package/dist/default/AuditTrailPane.js.map +1 -0
- package/dist/default/InvitationsPane.d.ts +19 -0
- package/dist/default/InvitationsPane.d.ts.map +1 -0
- package/dist/default/InvitationsPane.js +217 -0
- package/dist/default/InvitationsPane.js.map +1 -0
- package/dist/default/InviteAcceptPage.d.ts +7 -0
- package/dist/default/InviteAcceptPage.d.ts.map +1 -1
- package/dist/default/InviteAcceptPage.js +74 -38
- package/dist/default/InviteAcceptPage.js.map +1 -1
- package/dist/default/MembersManager.d.ts +12 -4
- package/dist/default/MembersManager.d.ts.map +1 -1
- package/dist/default/MembersManager.js +320 -84
- package/dist/default/MembersManager.js.map +1 -1
- package/dist/default/RoleSelectField.d.ts +64 -0
- package/dist/default/RoleSelectField.d.ts.map +1 -0
- package/dist/default/RoleSelectField.js +78 -0
- package/dist/default/RoleSelectField.js.map +1 -0
- package/dist/default/WorkspaceSettings.d.ts +7 -1
- package/dist/default/WorkspaceSettings.d.ts.map +1 -1
- package/dist/default/WorkspaceSettings.js +203 -45
- package/dist/default/WorkspaceSettings.js.map +1 -1
- package/dist/default/WorkspacesPage.d.ts +13 -0
- package/dist/default/WorkspacesPage.d.ts.map +1 -0
- package/dist/default/WorkspacesPage.js +109 -0
- package/dist/default/WorkspacesPage.js.map +1 -0
- package/dist/default/index.d.ts +28 -7
- package/dist/default/index.d.ts.map +1 -1
- package/dist/default/index.js +24 -7
- package/dist/default/index.js.map +1 -1
- package/dist/default/parts.d.ts +104 -0
- package/dist/default/parts.d.ts.map +1 -0
- package/dist/default/parts.js +143 -0
- package/dist/default/parts.js.map +1 -0
- package/dist/headless/Members.d.ts +59 -14
- package/dist/headless/Members.d.ts.map +1 -1
- package/dist/headless/Members.js +35 -10
- package/dist/headless/Members.js.map +1 -1
- package/dist/headless/RoleSelect.d.ts +9 -3
- package/dist/headless/RoleSelect.d.ts.map +1 -1
- package/dist/headless/RoleSelect.js +3 -2
- package/dist/headless/RoleSelect.js.map +1 -1
- package/dist/i18n/es.d.ts +11 -12
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +267 -14
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/generated/errors.es.gen.d.ts.map +1 -1
- package/dist/i18n/generated/errors.es.gen.js +5 -0
- package/dist/i18n/generated/errors.es.gen.js.map +1 -1
- package/dist/i18n/generated/errors.gen.d.ts +30 -0
- package/dist/i18n/generated/errors.gen.d.ts.map +1 -1
- package/dist/i18n/generated/errors.gen.js +15 -0
- package/dist/i18n/generated/errors.gen.js.map +1 -1
- package/dist/i18n/generated/errors.ru.gen.d.ts.map +1 -1
- package/dist/i18n/generated/errors.ru.gen.js +5 -0
- package/dist/i18n/generated/errors.ru.gen.js.map +1 -1
- package/dist/i18n/keys.d.ts +209 -1
- package/dist/i18n/keys.d.ts.map +1 -1
- package/dist/i18n/keys.js +410 -4
- package/dist/i18n/keys.js.map +1 -1
- package/dist/i18n/ru.d.ts +7 -2
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +209 -4
- package/dist/i18n/ru.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/model/format.d.ts +56 -0
- package/dist/model/format.d.ts.map +1 -0
- package/dist/model/format.js +125 -0
- package/dist/model/format.js.map +1 -0
- package/dist/model/selection.d.ts +15 -0
- package/dist/model/selection.d.ts.map +1 -1
- package/dist/model/selection.js +18 -1
- package/dist/model/selection.js.map +1 -1
- package/dist/nav/manifest.d.ts +45 -0
- package/dist/nav/manifest.d.ts.map +1 -0
- package/dist/nav/manifest.js +77 -0
- package/dist/nav/manifest.js.map +1 -0
- package/llms.txt +11 -10
- package/manifest.json +281 -69
- package/package.json +18 -12
- package/src/analytics/generated/events.json +1 -1
- package/src/api/generated/schema.ts +187 -60
- package/src/default/ActiveWorkspace.tsx +97 -0
- package/src/default/AuditTrailPane.tsx +309 -0
- package/src/default/InvitationsPane.tsx +501 -0
- package/src/default/InviteAcceptPage.tsx +187 -90
- package/src/default/MembersManager.tsx +832 -222
- package/src/default/RoleSelectField.tsx +187 -0
- package/src/default/WorkspaceSettings.tsx +540 -125
- package/src/default/WorkspacesPage.tsx +394 -0
- package/src/default/index.ts +28 -7
- package/src/default/parts.tsx +315 -0
- package/src/headless/Members.tsx +84 -16
- package/src/headless/RoleSelect.tsx +12 -5
- package/src/i18n/es.ts +326 -14
- package/src/i18n/generated/errors.es.gen.ts +5 -0
- package/src/i18n/generated/errors.gen.ts +15 -0
- package/src/i18n/generated/errors.json +37 -0
- package/src/i18n/generated/errors.ru.gen.ts +5 -0
- package/src/i18n/keys.ts +462 -5
- package/src/i18n/ru.ts +259 -5
- package/src/index.ts +1 -0
- package/src/model/format.ts +158 -0
- package/src/model/selection.tsx +19 -1
- package/src/nav/manifest.ts +120 -0
- package/dist/default/ErrorAlert.d.ts +0 -8
- package/dist/default/ErrorAlert.d.ts.map +0 -1
- package/dist/default/ErrorAlert.js +0 -30
- package/dist/default/ErrorAlert.js.map +0 -1
- package/src/default/ErrorAlert.tsx +0 -47
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Flex, Select, Typography } from "antd";
|
|
3
|
+
import { matchList, useI18n, useT } from "@stapel/core";
|
|
4
|
+
import { spacing, fontSize } from "@stapel/tokens";
|
|
5
|
+
import { RoleSelect } from "../headless/RoleSelect.js";
|
|
6
|
+
import { titleCaseKey } from "../model/format.js";
|
|
7
|
+
import { WORKSPACES_I18N_KEYS } from "../i18n/keys.js";
|
|
8
|
+
import { Muted } from "./parts.js";
|
|
9
|
+
/** The system-protected role only an owner may grant. */
|
|
10
|
+
const OWNER_ROLE = "owner";
|
|
11
|
+
/**
|
|
12
|
+
* Role key → the word for it, with no registry read behind it.
|
|
13
|
+
*
|
|
14
|
+
* `RoleSelect`'s own `labelFor` is a bundle lookup that never touches the
|
|
15
|
+
* query, but mounting `<RoleSelect>` to reach it also fires GET /roles — which
|
|
16
|
+
* on the PUBLIC invitation page is a call an anonymous reader cannot make.
|
|
17
|
+
* A caption that only needs a word asks for a word.
|
|
18
|
+
*/
|
|
19
|
+
export function useRoleLabel() {
|
|
20
|
+
const i18n = useI18n();
|
|
21
|
+
// Raw bundle lookup, NOT `t()`: `t` falls back to the key itself, and
|
|
22
|
+
// `workspaces.role.secretary` is the one thing this must never print.
|
|
23
|
+
const bundle = i18n.getBundle();
|
|
24
|
+
return (role) => bundle[`workspaces.role.${role}`] ?? titleCaseKey(role);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A role as a WORD, where there is nothing to pick — an invitation's granted
|
|
28
|
+
* role, a read-only roster. The same label resolution as the field, so one
|
|
29
|
+
* screen never calls `admin` "Admin" while its neighbour prints `admin`.
|
|
30
|
+
*/
|
|
31
|
+
export function RoleLabel(props) {
|
|
32
|
+
const labelFor = useRoleLabel();
|
|
33
|
+
return _jsx(_Fragment, { children: labelFor(props.role) });
|
|
34
|
+
}
|
|
35
|
+
export function RoleSelectField(props) {
|
|
36
|
+
const t = useT();
|
|
37
|
+
return (_jsx(RoleSelect, { children: ({ state, labelFor }) => {
|
|
38
|
+
const control = matchList(state, {
|
|
39
|
+
loading: () => (_jsx(Select, { value: props.value, loading: true, open: false, size: props.size ?? "middle", style: { width: "100%" }, "aria-label": props.label, options: [{ value: props.value, label: labelFor(props.value) }], onChange: props.onChange, disabled: true, "data-disabled-reason": "the role registry is still loading; the current role is shown meanwhile", ...(props.testId !== undefined ? { "data-testid": props.testId } : {}) })),
|
|
40
|
+
// A failed registry read is not an empty registry, and neither is a
|
|
41
|
+
// picker. The role still READS; only the choice is withdrawn.
|
|
42
|
+
failed: () => (_jsxs(Flex, { vertical: true, gap: spacing["1"], align: "flex-start", children: [_jsx(Typography.Text, { children: labelFor(props.value) }), _jsx(Muted, { testId: props.testId !== undefined ? `${props.testId}-blocked` : undefined, children: t(WORKSPACES_I18N_KEYS.rolesLoadFailed) })] })),
|
|
43
|
+
// A registry that came back EMPTY is not a registry that failed —
|
|
44
|
+
// saying "we could not load the role list" about a successful read
|
|
45
|
+
// is the same class of lie as an empty state over a failed one.
|
|
46
|
+
empty: () => (_jsxs(Flex, { vertical: true, gap: spacing["1"], align: "flex-start", children: [_jsx(Typography.Text, { children: labelFor(props.value) }), _jsx(Muted, { children: t(WORKSPACES_I18N_KEYS.rolesEmpty) })] })),
|
|
47
|
+
ready: (roles) => {
|
|
48
|
+
const offered = props.excludeOwner === true
|
|
49
|
+
? roles.filter((role) => role.role !== OWNER_ROLE)
|
|
50
|
+
: roles;
|
|
51
|
+
const rankOf = new Map(offered.map((role) => [role.role, role.rank]));
|
|
52
|
+
const options = offered.map((role) => ({
|
|
53
|
+
value: role.role,
|
|
54
|
+
label: labelFor(role.role),
|
|
55
|
+
}));
|
|
56
|
+
// The member's CURRENT role may be missing from the offered set
|
|
57
|
+
// (an overlay role a deployment removed, or `owner` on the invite
|
|
58
|
+
// path). Antd would render the bare key for it; the registry's
|
|
59
|
+
// own label is better, and the row must keep showing what the
|
|
60
|
+
// person actually holds.
|
|
61
|
+
const hasCurrent = options.some((option) => option.value === props.value);
|
|
62
|
+
const allOptions = hasCurrent
|
|
63
|
+
? options
|
|
64
|
+
: [{ value: props.value, label: labelFor(props.value) }, ...options];
|
|
65
|
+
return (_jsx(Select, { value: props.value, onChange: props.onChange, size: props.size ?? "middle", style: { width: "100%" }, "aria-label": props.label, ...(props["aria-describedby"] !== undefined
|
|
66
|
+
? { "aria-describedby": props["aria-describedby"] }
|
|
67
|
+
: {}), ...(props.disabled !== undefined ? { disabled: props.disabled } : {}), options: allOptions, optionRender: (option) => {
|
|
68
|
+
const rank = rankOf.get(String(option.value));
|
|
69
|
+
return (_jsxs(Flex, { vertical: true, gap: spacing["0"], children: [_jsx("span", { children: option.label }), rank !== undefined && (_jsx(Typography.Text, { type: "secondary", style: { fontSize: fontSize.xs.fontSize }, children: t(WORKSPACES_I18N_KEYS.roleRankCaption, { rank }) }))] }));
|
|
70
|
+
}, ...(props.testId !== undefined ? { "data-testid": props.testId } : {}) }));
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
if (props.showLabel !== true)
|
|
74
|
+
return control;
|
|
75
|
+
return (_jsxs(Flex, { vertical: true, gap: spacing["1"], style: { width: "100%" }, children: [_jsx(Typography.Text, { children: props.label }), control] }));
|
|
76
|
+
} }));
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=RoleSelectField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoleSelectField.js","sourceRoot":"","sources":["../../src/default/RoleSelectField.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
export interface WorkspaceSettingsProps {
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The workspace being configured. OPTIONAL: omitted (the way the nav
|
|
5
|
+
* contract mounts this screen — a route, never an ambient scope), the
|
|
6
|
+
* active workspace comes from the runtime selection, and a screen with none
|
|
7
|
+
* renders the designed "choose a workspace" state rather than a blank.
|
|
8
|
+
*/
|
|
9
|
+
workspaceId?: string;
|
|
4
10
|
/** Called after a successful delete — the host navigates away / switches
|
|
5
11
|
* to another workspace. Not called on cancel or failure. */
|
|
6
12
|
onDeleted?(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceSettings.d.ts","sourceRoot":"","sources":["../../src/default/WorkspaceSettings.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WorkspaceSettings.d.ts","sourceRoot":"","sources":["../../src/default/WorkspaceSettings.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAqC1C,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;gEAC4D;IAC5D,SAAS,CAAC,IAAI,IAAI,CAAC;CACpB;AA8CD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,CAgB7E"}
|
|
@@ -1,56 +1,214 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* `<WorkspaceSettings/>` — default skin for
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
3
|
+
* `<WorkspaceSettings/>` — the default skin for a workspace's own settings:
|
|
4
|
+
* its name, the security policy everyone in it has to meet, and the one
|
|
5
|
+
* irreversible act (deletion). Participants and roles live in the sibling
|
|
6
|
+
* `<MembersManager/>`; invitations in `<InvitationsPane/>`.
|
|
7
|
+
*
|
|
8
|
+
* ## Two rules this screen exists to state
|
|
9
|
+
*
|
|
10
|
+
* **A control never claims what the endpoint would refuse.** The delete
|
|
11
|
+
* button used to be drawn from `my_role === "owner"`. That derivation is
|
|
12
|
+
* wrong on exactly two workspaces — the instance's default one, and a
|
|
13
|
+
* personal one the next sign-in re-mints — and the backend added
|
|
14
|
+
* `WorkspaceResponse.can_delete` + `delete_blocked_reason` (0.26.0) because
|
|
15
|
+
* of it: the verdict comes from the SAME `deletion_block_reason()` the DELETE
|
|
16
|
+
* raises from, so a screen built on it cannot promise what the endpoint
|
|
17
|
+
* denies. `delete_blocked_reason` is an error CODE (`error.409.workspace_is_
|
|
18
|
+
* personal`), which is already a key in this pair's generated bundle, so the
|
|
19
|
+
* refusal renders in the reader's language beside the switched-off control.
|
|
20
|
+
* The same rule applies to the name field, which is gated on the capability
|
|
21
|
+
* `workspace.update` rather than on a role name — a deployment role can hold
|
|
22
|
+
* the capability without being called owner.
|
|
23
|
+
*
|
|
24
|
+
* **A policy says what HOLDS, not what was asked for.** `settings.security.
|
|
25
|
+
* require_mfa` is a flag somebody set; `mfa_enforcement` is how far the
|
|
26
|
+
* sweep actually got (WORK-01, 0.25.0). An administrator who switched MFA on
|
|
27
|
+
* and was told "saved" while half the organization was never checked is the
|
|
28
|
+
* defect the status block answers, and `unverified_members` is the number
|
|
29
|
+
* they have to get to zero.
|
|
9
30
|
*/
|
|
10
|
-
import { useEffect, useState } from "react";
|
|
11
|
-
import {
|
|
12
|
-
import { actionAvailable, actionBlocked, firstBlock,
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
31
|
+
import { useEffect, useMemo, useState } from "react";
|
|
32
|
+
import { Card, Checkbox, Flex, Input, Switch, Typography } from "antd";
|
|
33
|
+
import { actionAvailable, actionBlocked, firstBlock, loadStateFromQuery, useT, useTPlural, } from "@stapel/core";
|
|
34
|
+
import { ErrorAlert, GatedButton, GatedControl, LoadBoundary, SkinConfirm, SkinTheme, } from "@stapel/tokens-antd/skin";
|
|
35
|
+
import { spacing } from "@stapel/tokens";
|
|
36
|
+
import { hasCapability } from "../model/capabilities.js";
|
|
37
|
+
import { useCapabilityGate, useWorkspace } from "../model/queries.js";
|
|
38
|
+
import { useDeleteWorkspace, useUpdateSecuritySettings, useUpdateWorkspace, } from "../model/mutations.js";
|
|
39
|
+
import { useWorkspaceFormat } from "../model/format.js";
|
|
15
40
|
import { WORKSPACES_I18N_KEYS } from "../i18n/keys.js";
|
|
16
|
-
import {
|
|
41
|
+
import { ActiveWorkspaceBoundary } from "./ActiveWorkspace.js";
|
|
42
|
+
import { Muted, StatusTag, SCREEN_STACK, FIELD_STACK } from "./parts.js";
|
|
43
|
+
/** The two first-login demands an organization may raise, in the order the
|
|
44
|
+
* backend documents them. Independent checkboxes, never alternatives. */
|
|
45
|
+
const POLICIES = [
|
|
46
|
+
{
|
|
47
|
+
value: "password_change",
|
|
48
|
+
labelKey: WORKSPACES_I18N_KEYS.securityPolicyPasswordChange,
|
|
49
|
+
},
|
|
50
|
+
{ value: "mfa_enroll", labelKey: WORKSPACES_I18N_KEYS.securityPolicyMfaEnroll },
|
|
51
|
+
];
|
|
52
|
+
/** `settings.security`, typed. The block lives inside the free-form settings
|
|
53
|
+
* JSON, so the generated types say `object` and this is the read side of the
|
|
54
|
+
* documented correction in `api/types.ts`. */
|
|
55
|
+
function securityOf(workspace) {
|
|
56
|
+
const settings = (workspace.settings ?? {});
|
|
57
|
+
return (settings["security"] ?? {});
|
|
58
|
+
}
|
|
59
|
+
function sameStringSet(a, b) {
|
|
60
|
+
return a.length === b.length && a.every((value) => b.includes(value));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* May this caller exercise `capability` in this workspace?
|
|
64
|
+
*
|
|
65
|
+
* `my_capabilities` is the mandate the server granted, and it is what the
|
|
66
|
+
* server re-checks — so it is what the screen reads. It is also ADDITIVE
|
|
67
|
+
* (stapel-workspaces ≥0.6.0): a deployment on an older backend sends the
|
|
68
|
+
* field not at all, and treating that silence as "no" would switch the whole
|
|
69
|
+
* settings screen off for its owner. So the absence — and only the absence —
|
|
70
|
+
* falls back to the pre-0.6 rule this pair used to apply everywhere. Where
|
|
71
|
+
* the field IS present, `my_role` is never consulted: a deployment role can
|
|
72
|
+
* hold `workspace.update` without being called owner, and the endpoint would
|
|
73
|
+
* accept it.
|
|
74
|
+
*/
|
|
75
|
+
function mayUse(workspace, capability) {
|
|
76
|
+
const granted = workspace.my_capabilities;
|
|
77
|
+
if (granted === undefined)
|
|
78
|
+
return workspace.my_role === "owner";
|
|
79
|
+
return hasCapability(granted, capability);
|
|
80
|
+
}
|
|
17
81
|
export function WorkspaceSettings(props) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// 2026-08-09). `useErrorText` folds any thrown value into the one dialect.
|
|
22
|
-
const errorDisplay = useErrorDisplay(WORKSPACES_I18N_KEYS.unknownError);
|
|
82
|
+
return (_jsx(SkinTheme, { surface: "base", "data-testid": "workspace-settings", children: _jsx(ActiveWorkspaceBoundary, { workspaceId: props.workspaceId, testId: "workspace-settings-workspace", children: (workspaceId) => (_jsx(SettingsBody, { workspaceId: workspaceId, ...(props.onDeleted !== undefined ? { onDeleted: props.onDeleted } : {}) })) }) }));
|
|
83
|
+
}
|
|
84
|
+
function SettingsBody(props) {
|
|
23
85
|
const query = useWorkspace(props.workspaceId);
|
|
86
|
+
return (_jsx(LoadBoundary, { state: loadStateFromQuery(query), testId: "workspace-settings-load", onRetry: () => {
|
|
87
|
+
void query.refetch();
|
|
88
|
+
}, children: (workspace) => (_jsxs("div", { style: SCREEN_STACK, children: [_jsx(GeneralCard, { workspace: workspace, workspaceId: props.workspaceId }), _jsx(SecurityCard, { workspace: workspace, workspaceId: props.workspaceId }), _jsx(DangerZone, { workspace: workspace, workspaceId: props.workspaceId, ...(props.onDeleted !== undefined ? { onDeleted: props.onDeleted } : {}) })] })) }));
|
|
89
|
+
}
|
|
90
|
+
/** Name, slug, type — the parts of a workspace a person renames. */
|
|
91
|
+
function GeneralCard(props) {
|
|
92
|
+
const t = useT();
|
|
24
93
|
const updateMutation = useUpdateWorkspace(props.workspaceId);
|
|
25
|
-
const
|
|
26
|
-
const workspace = query.data;
|
|
27
|
-
const [name, setName] = useState("");
|
|
28
|
-
// Two unrelated situations used to share one `disabled={!isOwner ||
|
|
29
|
-
// !name.trim()}` bit, and a person facing either of them saw the same dead
|
|
30
|
-
// button. `firstBlock` keeps them two, in the order you would explain them.
|
|
31
|
-
const isOwner = workspace?.my_role === "owner";
|
|
32
|
-
const saveGate = useActionGate(firstBlock(isOwner ? actionAvailable() : actionBlocked(WORKSPACES_I18N_KEYS.blockedNotOwner), name.trim() ? actionAvailable() : actionBlocked(WORKSPACES_I18N_KEYS.blockedNameRequired)));
|
|
94
|
+
const [name, setName] = useState(props.workspace.name);
|
|
33
95
|
useEffect(() => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
96
|
+
setName(props.workspace.name);
|
|
97
|
+
}, [props.workspace.name]);
|
|
98
|
+
// Ordered the way it would be explained out loud: what you may do first,
|
|
99
|
+
// then what you have not done yet.
|
|
100
|
+
const canManage = mayUse(props.workspace, "workspace.update")
|
|
101
|
+
? actionAvailable()
|
|
102
|
+
: actionBlocked(WORKSPACES_I18N_KEYS.blockedCannotManage);
|
|
103
|
+
const saveGate = firstBlock(canManage, name.trim() === ""
|
|
104
|
+
? actionBlocked(WORKSPACES_I18N_KEYS.blockedNameRequired)
|
|
105
|
+
: actionAvailable(), name.trim() === props.workspace.name
|
|
106
|
+
? actionBlocked(WORKSPACES_I18N_KEYS.blockedUnchanged)
|
|
107
|
+
: actionAvailable());
|
|
108
|
+
const typeKey = props.workspace.type === "personal"
|
|
109
|
+
? WORKSPACES_I18N_KEYS.typePersonal
|
|
110
|
+
: WORKSPACES_I18N_KEYS.typeWork;
|
|
111
|
+
return (_jsxs(Card, { children: [_jsx(Typography.Title, { level: 4, style: { marginTop: 0 }, children: t(WORKSPACES_I18N_KEYS.settingsTitle) }), _jsx(Typography.Text, { type: "secondary", children: t(WORKSPACES_I18N_KEYS.settingsSubtitle) }), _jsxs("div", { style: { ...FIELD_STACK, marginTop: spacing["4"] }, children: [_jsx(GatedControl, { gate: canManage, testId: "workspace-name-field", children: (bind) => (_jsxs(Flex, { vertical: true, gap: spacing["1"], style: { width: "100%" }, children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.fieldName) }), _jsx(Input, { value: name, onChange: (event) => setName(event.target.value), "aria-label": t(WORKSPACES_I18N_KEYS.fieldName), ...bind })] })) }), _jsxs(Flex, { vertical: true, gap: spacing["1"], children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.fieldSlug) }), _jsx(Typography.Text, { code: true, children: props.workspace.slug })] }), _jsxs(Flex, { vertical: true, gap: spacing["1"], align: "flex-start", children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.fieldType) }), _jsx(StatusTag, { tone: "neutral", testId: "workspace-type", children: t(typeKey) })] })] }), _jsx(ErrorAlert, { thrown: updateMutation.error, style: { marginTop: spacing["3"] }, testId: "workspace-settings-write-error" }), _jsx("div", { style: { marginTop: spacing["4"] }, children: _jsx(GatedButton, { gate: saveGate, type: "primary", loading: updateMutation.isPending, onClick: () => {
|
|
112
|
+
updateMutation.mutate({ name: name.trim() });
|
|
113
|
+
}, testId: "workspace-save", "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked(); pairs carry no @stapel/analytics runtime dependency by architecture", children: updateMutation.isPending
|
|
114
|
+
? t(WORKSPACES_I18N_KEYS.saving)
|
|
115
|
+
: t(WORKSPACES_I18N_KEYS.save) }) })] }));
|
|
116
|
+
}
|
|
117
|
+
/** The `require_mfa` policy: what was asked for, and what actually holds. */
|
|
118
|
+
function SecurityCard(props) {
|
|
119
|
+
const t = useT();
|
|
120
|
+
const tPlural = useTPlural();
|
|
121
|
+
const format = useWorkspaceFormat();
|
|
122
|
+
const mutation = useUpdateSecuritySettings(props.workspaceId);
|
|
123
|
+
const gate = useCapabilityGate(props.workspaceId, "workspace.security.manage");
|
|
124
|
+
const stored = useMemo(() => securityOf(props.workspace), [props.workspace]);
|
|
125
|
+
const storedPolicies = useMemo(() => stored.provisioned_user_policies ?? [], [stored]);
|
|
126
|
+
/** What is SAVED, not what the person has just toggled: the enforcement
|
|
127
|
+
* block describes the policy the server is acting on. */
|
|
128
|
+
const storedRequireMfa = stored.require_mfa === true;
|
|
129
|
+
const [requireMfa, setRequireMfa] = useState(stored.require_mfa === true);
|
|
130
|
+
const [policies, setPolicies] = useState(storedPolicies);
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
setRequireMfa(stored.require_mfa === true);
|
|
133
|
+
setPolicies(storedPolicies);
|
|
134
|
+
}, [stored, storedPolicies]);
|
|
135
|
+
const allowed = mayUse(props.workspace, "workspace.security.manage");
|
|
136
|
+
const canManage = allowed
|
|
137
|
+
? actionAvailable()
|
|
138
|
+
: actionBlocked(WORKSPACES_I18N_KEYS.securityBlockedCapability);
|
|
139
|
+
const unchanged = requireMfa === (stored.require_mfa === true) &&
|
|
140
|
+
sameStringSet(policies, storedPolicies);
|
|
141
|
+
const saveGate = firstBlock(canManage, unchanged ? actionBlocked(WORKSPACES_I18N_KEYS.blockedUnchanged) : actionAvailable());
|
|
142
|
+
const enforcement = props.workspace.mfa_enforcement ?? null;
|
|
143
|
+
return (_jsxs(Card, { "data-testid": "workspace-security", children: [_jsx(Typography.Title, { level: 5, style: { marginTop: 0 }, children: t(WORKSPACES_I18N_KEYS.securityTitle) }), _jsx(Typography.Text, { type: "secondary", children: t(WORKSPACES_I18N_KEYS.securitySubtitle) }), _jsxs("div", { style: { ...FIELD_STACK, marginTop: spacing["4"] }, children: [_jsx(GatedControl, { gate: canManage, testId: "workspace-require-mfa-field", children: (bind) => (_jsxs(Flex, { gap: spacing["3"], align: "flex-start", children: [_jsx(Switch, { checked: requireMfa, onChange: setRequireMfa, "aria-label": t(WORKSPACES_I18N_KEYS.securityRequireMfa), "data-testid": "workspace-require-mfa", ...bind }), _jsxs(Flex, { vertical: true, gap: spacing["0"], children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.securityRequireMfa) }), _jsx(Muted, { children: t(WORKSPACES_I18N_KEYS.securityRequireMfaHint) })] })] })) }), _jsx(GatedControl, { gate: canManage, testId: "workspace-policies-field", children: (bind) => (_jsxs(Flex, { vertical: true, gap: spacing["2"], align: "flex-start", children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.securityPoliciesLabel) }), _jsx(Muted, { children: t(WORKSPACES_I18N_KEYS.securityPoliciesHint) }), POLICIES.map((policy) => (_jsx(Checkbox, { checked: policies.includes(policy.value), onChange: (event) => {
|
|
144
|
+
setPolicies((current) => event.target.checked
|
|
145
|
+
? [...current, policy.value]
|
|
146
|
+
: current.filter((value) => value !== policy.value));
|
|
147
|
+
}, "data-testid": `workspace-policy-${policy.value}`, ...bind, children: t(policy.labelKey) }, policy.value)))] })) })] }), allowed && gate.requiresStepUp && (_jsx("div", { style: { marginTop: spacing["3"] }, children: _jsx(Muted, { testId: "workspace-security-stepup", children: t(WORKSPACES_I18N_KEYS.securityStepUpNotice) }) })), _jsx(ErrorAlert, { thrown: mutation.error, style: { marginTop: spacing["3"] }, testId: "workspace-security-error" }), _jsx("div", { style: { marginTop: spacing["4"] }, children: _jsx(GatedButton, { gate: saveGate, type: "primary", loading: mutation.isPending, onClick: () => {
|
|
148
|
+
mutation.mutate({
|
|
149
|
+
require_mfa: requireMfa,
|
|
150
|
+
provisioned_user_policies: policies,
|
|
151
|
+
});
|
|
152
|
+
}, testId: "workspace-security-save", "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", children: mutation.isPending
|
|
153
|
+
? t(WORKSPACES_I18N_KEYS.securitySaving)
|
|
154
|
+
: t(WORKSPACES_I18N_KEYS.securitySave) }) }), _jsxs("div", { style: { marginTop: spacing["5"] }, children: [_jsx(Typography.Text, { strong: true, children: t(WORKSPACES_I18N_KEYS.mfaStatusTitle) }), enforcement === null ? (_jsx("div", { style: { marginTop: spacing["2"] }, children: _jsx(Muted, { testId: "workspace-mfa-off", children: t(storedRequireMfa
|
|
155
|
+
? WORKSPACES_I18N_KEYS.mfaNoStatusYet
|
|
156
|
+
: WORKSPACES_I18N_KEYS.mfaOffNotice) }) })) : (_jsxs(Flex, { vertical: true, gap: spacing["2"], align: "flex-start", style: { marginTop: spacing["2"] }, "data-testid": "workspace-mfa-status", children: [_jsxs(Flex, { gap: spacing["2"], align: "center", wrap: true, children: [_jsx(Muted, { children: t(WORKSPACES_I18N_KEYS.mfaStateLabel) }), _jsx(StatusTag, { tone: enforcement.state === "enforced"
|
|
157
|
+
? "success"
|
|
158
|
+
: enforcement.state === "failed"
|
|
159
|
+
? "danger"
|
|
160
|
+
: "warning", testId: "workspace-mfa-state", children: mfaStateLabel(t, enforcement.state) })] }), _jsx(Muted, { children: tPlural(WORKSPACES_I18N_KEYS.mfaCheckedCount, {
|
|
161
|
+
count: enforcement.checked_members ?? 0,
|
|
162
|
+
}) }), _jsx(Muted, { children: tPlural(WORKSPACES_I18N_KEYS.mfaNoncompliantCount, {
|
|
163
|
+
count: enforcement.noncompliant_members ?? 0,
|
|
164
|
+
}) }), _jsx(Typography.Text, { type: (enforcement.unverified_members ?? 0) > 0 ? "warning" : "secondary", "data-testid": "workspace-mfa-unverified", children: tPlural(WORKSPACES_I18N_KEYS.mfaUnverifiedCount, {
|
|
165
|
+
count: enforcement.unverified_members ?? 0,
|
|
166
|
+
}) }), (enforcement.unverified_members ?? 0) > 0 && (_jsx(Muted, { children: t(WORKSPACES_I18N_KEYS.mfaUnverifiedHint) })), _jsx(Muted, { children: tPlural(WORKSPACES_I18N_KEYS.mfaAttemptsCount, {
|
|
167
|
+
count: enforcement.attempts ?? 0,
|
|
168
|
+
}) }), format.timestamp(enforcement.last_attempt_at) !== null && (_jsx(Muted, { children: t(WORKSPACES_I18N_KEYS.mfaLastAttempt, {
|
|
169
|
+
date: format.timestamp(enforcement.last_attempt_at),
|
|
170
|
+
}) })), format.timestamp(enforcement.completed_at) !== null && (_jsx(Muted, { children: t(WORKSPACES_I18N_KEYS.mfaCompletedAt, {
|
|
171
|
+
date: format.timestamp(enforcement.completed_at),
|
|
172
|
+
}) })), enforcement.last_error !== undefined && enforcement.last_error !== "" && (_jsx(Muted, { testId: "workspace-mfa-error", children: t(WORKSPACES_I18N_KEYS.mfaLastError, { error: enforcement.last_error }) }))] }))] })] }));
|
|
173
|
+
}
|
|
174
|
+
/** The four states the backend names, plus an honest line for a fifth this
|
|
175
|
+
* build has never heard of. */
|
|
176
|
+
function mfaStateLabel(t, state) {
|
|
177
|
+
switch (state) {
|
|
178
|
+
case "pending":
|
|
179
|
+
return t(WORKSPACES_I18N_KEYS.mfaStatePending);
|
|
180
|
+
case "enforcing":
|
|
181
|
+
return t(WORKSPACES_I18N_KEYS.mfaStateEnforcing);
|
|
182
|
+
case "enforced":
|
|
183
|
+
return t(WORKSPACES_I18N_KEYS.mfaStateEnforced);
|
|
184
|
+
case "failed":
|
|
185
|
+
return t(WORKSPACES_I18N_KEYS.mfaStateFailed);
|
|
186
|
+
default:
|
|
187
|
+
return t(WORKSPACES_I18N_KEYS.mfaStateOther, { state });
|
|
53
188
|
}
|
|
54
|
-
|
|
189
|
+
}
|
|
190
|
+
/** Deletion — the one act on this screen nobody can take back. */
|
|
191
|
+
function DangerZone(props) {
|
|
192
|
+
const t = useT();
|
|
193
|
+
const mutation = useDeleteWorkspace();
|
|
194
|
+
const [confirming, setConfirming] = useState(false);
|
|
195
|
+
// THE SERVER'S ANSWER, not a rule re-derived from `my_role`. `can_delete`
|
|
196
|
+
// is additive on the wire, so a backend that predates it sends neither
|
|
197
|
+
// field; treating "absent" as "allowed" keeps such a deployment working
|
|
198
|
+
// exactly as it did, and the refusal it might answer is a translated 409
|
|
199
|
+
// rather than a promise this screen made.
|
|
200
|
+
const canDelete = props.workspace.can_delete ?? true;
|
|
201
|
+
const blockedReason = props.workspace.delete_blocked_reason;
|
|
202
|
+
const deleteGate = canDelete
|
|
203
|
+
? actionAvailable()
|
|
204
|
+
: actionBlocked(blockedReason !== undefined && blockedReason !== ""
|
|
205
|
+
? blockedReason
|
|
206
|
+
: WORKSPACES_I18N_KEYS.deleteBlockedFallback);
|
|
207
|
+
return (_jsxs(Card, { "data-testid": "workspace-danger-zone", children: [_jsx(Typography.Title, { level: 5, type: "danger", style: { marginTop: 0 }, children: t(WORKSPACES_I18N_KEYS.dangerZoneTitle) }), _jsx(ErrorAlert, { thrown: mutation.error, style: { marginBottom: spacing["3"] }, testId: "workspace-delete-error" }), _jsx(GatedButton, { gate: deleteGate, danger: true, onClick: () => setConfirming(true), testId: "workspace-delete", "data-analytics": "none", "data-analytics-reason": "opens the confirm; the delete itself is the tracked point", children: t(WORKSPACES_I18N_KEYS.deleteWorkspace) }), _jsx(SkinConfirm, { open: confirming, danger: true, title: t(WORKSPACES_I18N_KEYS.deleteWorkspaceConfirm), body: t(WORKSPACES_I18N_KEYS.deleteWorkspaceConfirmBody), confirmLabel: t(WORKSPACES_I18N_KEYS.deleteWorkspace), cancelLabel: t(WORKSPACES_I18N_KEYS.cancel), confirming: mutation.isPending, onConfirm: () => {
|
|
208
|
+
mutation.mutate(props.workspaceId, {
|
|
209
|
+
onSuccess: () => props.onDeleted?.(),
|
|
210
|
+
onSettled: () => setConfirming(false),
|
|
211
|
+
});
|
|
212
|
+
}, onCancel: () => setConfirming(false), "data-testid": "workspace-delete-confirm" })] }));
|
|
55
213
|
}
|
|
56
214
|
//# sourceMappingURL=WorkspaceSettings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceSettings.js","sourceRoot":"","sources":["../../src/default/WorkspaceSettings.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WorkspaceSettings.js","sourceRoot":"","sources":["../../src/default/WorkspaceSettings.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { Workspace } from "../api/types.js";
|
|
3
|
+
export interface WorkspacesPageProps {
|
|
4
|
+
/**
|
|
5
|
+
* Open a workspace. The pair owns no router (there are several, and a
|
|
6
|
+
* library that picks one picks it for every host), so the door is the
|
|
7
|
+
* host's: omit it and no "Open" control is drawn, because a button that
|
|
8
|
+
* goes nowhere is worse than no button.
|
|
9
|
+
*/
|
|
10
|
+
onOpen?(workspace: Workspace): void;
|
|
11
|
+
}
|
|
12
|
+
export declare function WorkspacesPage(props: WorkspacesPageProps): ReactElement;
|
|
13
|
+
//# sourceMappingURL=WorkspacesPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspacesPage.d.ts","sourceRoot":"","sources":["../../src/default/WorkspacesPage.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AA2B1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAKjD,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,MAAM,CAAC,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;CACrC;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CAavE"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* `<WorkspacesPage/>` — the default skin for {@link WorkspaceList}: the
|
|
4
|
+
* roster of workspaces a person belongs to, the door into each one, the
|
|
5
|
+
* "open this one by default" choice, and the create control.
|
|
6
|
+
*
|
|
7
|
+
* §54 said every headless primitive gets an AntD default; this was the one
|
|
8
|
+
* missing, and it is the one every app needs on day one — the audit found
|
|
9
|
+
* `useCanCreateWorkspace` existing only to feed a create button nobody had
|
|
10
|
+
* drawn.
|
|
11
|
+
*
|
|
12
|
+
* Three answers come from the SERVER and are never re-derived here:
|
|
13
|
+
*
|
|
14
|
+
* - `can_create_workspace` — the instance's `WORKSPACE_CREATE_POLICY`, over
|
|
15
|
+
* the same helper the POST gate uses, so a drawn button always opens.
|
|
16
|
+
* - `preferred_workspace_id` — the person's explicit home, which the
|
|
17
|
+
* instance default documents itself as yielding to. Never `workspaces[0]`
|
|
18
|
+
* (that guess was tracker #239) and never `last_accessed_at`, which is
|
|
19
|
+
* telemetry.
|
|
20
|
+
* - `is_guest` — someone here on a link rather than a membership. An empty
|
|
21
|
+
* list means something different to them, and the screen says which.
|
|
22
|
+
*/
|
|
23
|
+
import { useId, useState } from "react";
|
|
24
|
+
import { Button, Card, Flex, Input, Typography, theme as antdTheme } from "antd";
|
|
25
|
+
import { actionAvailable, actionBlocked, loadStateFromQuery, requireLoaded, useT, useTPlural, } from "@stapel/core";
|
|
26
|
+
import { EmptyState, ErrorAlert, GatedButton, LoadList, SkinDialog, SkinTheme, useBlockedButtonClassName, } from "@stapel/tokens-antd/skin";
|
|
27
|
+
import { spacing } from "@stapel/tokens";
|
|
28
|
+
import { WorkspaceList } from "../headless/WorkspaceList.js";
|
|
29
|
+
import { useWorkspaces } from "../model/queries.js";
|
|
30
|
+
import { useClearPreferredWorkspace, useSetPreferredWorkspace, } from "../model/mutations.js";
|
|
31
|
+
import { WORKSPACES_I18N_KEYS } from "../i18n/keys.js";
|
|
32
|
+
import { LoadFailure, Muted, StatusTag, SCREEN_STACK } from "./parts.js";
|
|
33
|
+
import { RoleLabel } from "./RoleSelectField.js";
|
|
34
|
+
export function WorkspacesPage(props) {
|
|
35
|
+
return (_jsx(SkinTheme, { surface: "base", "data-testid": "workspaces-page", children: _jsx(WorkspaceList, { children: (bag) => (_jsx(PageBody, { bag: bag, ...(props.onOpen !== undefined ? { onOpen: props.onOpen } : {}) })) }) }));
|
|
36
|
+
}
|
|
37
|
+
function PageBody(props) {
|
|
38
|
+
const t = useT();
|
|
39
|
+
const tPlural = useTPlural();
|
|
40
|
+
const { bag } = props;
|
|
41
|
+
const listQuery = useWorkspaces();
|
|
42
|
+
const [creating, setCreating] = useState(false);
|
|
43
|
+
const list = listQuery.data ?? null;
|
|
44
|
+
const failureId = useId();
|
|
45
|
+
// The create verdict is a property of the LIST response, so it is blocked
|
|
46
|
+
// while the list is loading — with core's own sentence — and by the policy
|
|
47
|
+
// when the list arrived and says no.
|
|
48
|
+
//
|
|
49
|
+
// A FAILED read is deliberately not routed through the gate. `requireLoaded`
|
|
50
|
+
// would hand the button its own copy of the outage ("We could not load what
|
|
51
|
+
// this needs…" plus `HTTP 503`) directly above the alert that states the
|
|
52
|
+
// same outage with the retry — the same bad news twice, in two wordings,
|
|
53
|
+
// with two different recoveries. The read has exactly one failure surface on
|
|
54
|
+
// this screen, and the button points at it.
|
|
55
|
+
const listState = loadStateFromQuery(listQuery);
|
|
56
|
+
const listFailed = listState.status === "failed";
|
|
57
|
+
const blockedLook = useBlockedButtonClassName();
|
|
58
|
+
const createGate = requireLoaded(listState, (loaded) => loaded.can_create_workspace === true
|
|
59
|
+
? actionAvailable()
|
|
60
|
+
: actionBlocked(WORKSPACES_I18N_KEYS.listCreateBlockedPolicy));
|
|
61
|
+
const rows = bag.state.status === "ready" ? bag.state.data : [];
|
|
62
|
+
return (_jsxs("div", { style: SCREEN_STACK, children: [_jsxs(Card, { children: [_jsxs(Flex, { justify: "space-between", align: "flex-start", gap: spacing["4"], wrap: true, children: [_jsxs(Flex, { vertical: true, gap: spacing["1"], children: [_jsx(Typography.Title, { level: 4, style: { marginTop: 0, marginBottom: 0 }, children: t(WORKSPACES_I18N_KEYS.pageTitle) }), _jsx(Typography.Text, { type: "secondary", children: t(WORKSPACES_I18N_KEYS.pageSubtitle) }), bag.state.status === "ready" && (_jsx(Muted, { testId: "workspaces-count", children: tPlural(WORKSPACES_I18N_KEYS.listCount, { count: rows.length }) }))] }), listFailed ? (_jsx(Button, { type: "primary", "aria-disabled": true, className: blockedLook, "aria-describedby": failureId, "data-disabled-reason": "the roster read failed; the alert below says so once and carries the retry", "data-analytics": "none", "data-analytics-reason": "local-ui-open-create-dialog", "data-testid": "workspaces-create-open", children: t(WORKSPACES_I18N_KEYS.listCreate) })) : (_jsx(GatedButton, { gate: createGate, type: "primary", onClick: () => setCreating(true), testId: "workspaces-create-open", "data-analytics": "none", "data-analytics-reason": "local-ui-open-create-dialog", children: t(WORKSPACES_I18N_KEYS.listCreate) }))] }), list?.is_guest === true && (_jsx("div", { style: { marginTop: spacing["3"] }, children: _jsx(Muted, { testId: "workspaces-guest", children: t(WORKSPACES_I18N_KEYS.listGuestNotice) }) })), _jsx(ErrorAlert, { thrown: bag.createError, style: { marginTop: spacing["3"] }, testId: "workspaces-create-error" }), _jsx("div", { style: { marginTop: spacing["4"] }, children: _jsx(LoadList, { state: bag.state, testId: "workspaces-list", onRetry: bag.refetch, failed: (error) => (_jsx("div", { id: failureId, children: _jsx(LoadFailure, { error: error, onRetry: bag.refetch, testId: "workspaces-list-failed" }) })), empty: _jsx(EmptyState, { title: t(WORKSPACES_I18N_KEYS.listEmpty), testId: "workspaces-list-empty",
|
|
63
|
+
// The RESTRICTION is stated once, beside the switched-off
|
|
64
|
+
// control above; this line is the other half — what the person
|
|
65
|
+
// can actually do about it. Saying "this installation does not
|
|
66
|
+
// hand out workspaces" here as well was the same fact twice in
|
|
67
|
+
// two wordings on one 390px screen.
|
|
68
|
+
hint: createGate.available === true
|
|
69
|
+
? t(WORKSPACES_I18N_KEYS.listEmptyHint)
|
|
70
|
+
: t(WORKSPACES_I18N_KEYS.listInstanceClosed), ...(createGate.available === true
|
|
71
|
+
? {
|
|
72
|
+
action: (_jsx(Button, { type: "primary", onClick: () => setCreating(true), "data-analytics": "none", "data-analytics-reason": "local-ui-open-create-dialog", children: t(WORKSPACES_I18N_KEYS.listCreate) })),
|
|
73
|
+
}
|
|
74
|
+
: {}) }), children: (workspaces) => (_jsx("div", { role: "list", "data-testid": "workspaces-rows", children: workspaces.map((workspace) => (_jsx(WorkspaceRow, { workspace: workspace, isPreferred: list?.preferred_workspace_id === workspace.id, ...(props.onOpen !== undefined ? { onOpen: props.onOpen } : {}) }, workspace.id))) })) }) })] }), _jsx(CreateDialog, { open: creating, onClose: () => setCreating(false), isCreating: bag.isCreating, onCreate: (name) => {
|
|
75
|
+
bag.create({ name });
|
|
76
|
+
setCreating(false);
|
|
77
|
+
} })] }));
|
|
78
|
+
}
|
|
79
|
+
function WorkspaceRow(props) {
|
|
80
|
+
const t = useT();
|
|
81
|
+
const tPlural = useTPlural();
|
|
82
|
+
const { token } = antdTheme.useToken();
|
|
83
|
+
const setPreferred = useSetPreferredWorkspace();
|
|
84
|
+
const clearPreferred = useClearPreferredWorkspace();
|
|
85
|
+
const { workspace } = props;
|
|
86
|
+
const owner = workspace.owner_display_name?.trim();
|
|
87
|
+
return (_jsxs("div", { role: "listitem", "data-testid": `workspace-row-${workspace.id}`, style: {
|
|
88
|
+
display: "flex",
|
|
89
|
+
flexWrap: "wrap",
|
|
90
|
+
alignItems: "center",
|
|
91
|
+
justifyContent: "space-between",
|
|
92
|
+
gap: spacing["3"],
|
|
93
|
+
paddingTop: spacing["3"],
|
|
94
|
+
paddingBottom: spacing["3"],
|
|
95
|
+
borderBottom: `1px solid ${token.colorSplit}`,
|
|
96
|
+
}, children: [_jsxs(Flex, { vertical: true, gap: spacing["1"], style: { minWidth: 0 }, children: [_jsxs(Flex, { gap: spacing["2"], align: "center", wrap: true, children: [_jsx(Typography.Text, { strong: true, children: workspace.name }), props.isPreferred && (_jsx(StatusTag, { tone: "info", testId: `workspace-preferred-${workspace.id}`, children: t(WORKSPACES_I18N_KEYS.listPreferredTag) }))] }), owner !== undefined && owner !== "" && (_jsx(Muted, { children: t(WORKSPACES_I18N_KEYS.listOwnerLine, { owner }) })), _jsxs(Muted, { children: [tPlural(WORKSPACES_I18N_KEYS.listMemberCount, { count: workspace.member_count }), workspace.my_role !== null && (_jsxs(_Fragment, { children: [" · ", t(WORKSPACES_I18N_KEYS.listYourRole), ":", " ", _jsx(RoleLabel, { role: workspace.my_role })] }))] })] }), _jsxs(Flex, { gap: spacing["2"], align: "center", wrap: true, children: [props.isPreferred ? (_jsx(Button, { type: "link", size: "small", loading: clearPreferred.isPending, onClick: () => clearPreferred.mutate(), "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", "data-testid": `workspace-clear-home-${workspace.id}`, children: t(WORKSPACES_I18N_KEYS.listClearPreferred) })) : (_jsx(Button, { type: "link", size: "small", loading: setPreferred.isPending, onClick: () => setPreferred.mutate({ workspace_id: workspace.id }), "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", "data-testid": `workspace-set-home-${workspace.id}`, children: t(WORKSPACES_I18N_KEYS.listSetPreferred) })), props.onOpen !== undefined && (_jsx(Button, { onClick: () => props.onOpen?.(workspace), "data-analytics": "none", "data-analytics-reason": "navigation \u2014 the host owns the router", "data-testid": `workspace-open-${workspace.id}`, children: t(WORKSPACES_I18N_KEYS.listOpen) }))] })] }));
|
|
97
|
+
}
|
|
98
|
+
function CreateDialog(props) {
|
|
99
|
+
const t = useT();
|
|
100
|
+
const [name, setName] = useState("");
|
|
101
|
+
const gate = name.trim() === ""
|
|
102
|
+
? actionBlocked(WORKSPACES_I18N_KEYS.listCreateBlockedNoName)
|
|
103
|
+
: actionAvailable();
|
|
104
|
+
return (_jsx(SkinDialog, { open: props.open, onClose: props.onClose, title: t(WORKSPACES_I18N_KEYS.listCreateDialogTitle), dismissLabel: t(WORKSPACES_I18N_KEYS.dialogClose), "data-testid": "workspaces-create-dialog", footer: _jsx(GatedButton, { gate: gate, type: "primary", loading: props.isCreating, onClick: () => {
|
|
105
|
+
props.onCreate(name.trim());
|
|
106
|
+
setName("");
|
|
107
|
+
}, testId: "workspaces-create-submit", "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", children: t(WORKSPACES_I18N_KEYS.listCreateSubmit) }), children: _jsxs(Flex, { vertical: true, gap: spacing["2"], children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.listCreateNameLabel) }), _jsx(Input, { value: name, onChange: (event) => setName(event.target.value), placeholder: t(WORKSPACES_I18N_KEYS.listCreateNamePlaceholder), "aria-label": t(WORKSPACES_I18N_KEYS.listCreateNameLabel), "data-testid": "workspaces-create-name" })] }) }));
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=WorkspacesPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspacesPage.js","sourceRoot":"","sources":["../../src/default/WorkspacesPage.tsx"],"names":[],"mappings":"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"}
|