@stapel/workspaces-react 0.11.2 → 0.12.0
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 +9 -0
- package/dist/default/ErrorAlert.d.ts +8 -0
- package/dist/default/ErrorAlert.d.ts.map +1 -0
- package/dist/default/ErrorAlert.js +30 -0
- package/dist/default/ErrorAlert.js.map +1 -0
- package/dist/default/MembersManager.d.ts.map +1 -1
- package/dist/default/MembersManager.js +5 -4
- package/dist/default/MembersManager.js.map +1 -1
- package/dist/default/WorkspaceSettings.d.ts.map +1 -1
- package/dist/default/WorkspaceSettings.js +9 -5
- package/dist/default/WorkspaceSettings.js.map +1 -1
- package/llms.txt +1 -1
- package/manifest.json +1 -1
- package/package.json +3 -3
- package/src/analytics/generated/events.json +1 -1
- package/src/default/ErrorAlert.tsx +47 -0
- package/src/default/MembersManager.tsx +5 -6
- package/src/default/WorkspaceSettings.tsx +13 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @stapel/workspaces-react
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c5c0a11: Default skins render the error surface through core's split copy: the human
|
|
8
|
+
sentence as the alert's message, and the technical detail (`HTTP 500`) as a
|
|
9
|
+
muted, small description beside it instead of a protocol number spliced into
|
|
10
|
+
the sentence. Requires `@stapel/core >= 0.12.0`.
|
|
11
|
+
|
|
3
12
|
## 0.11.2
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement } from "react";
|
|
2
|
+
import type { FlowErrorDisplay } from "@stapel/core";
|
|
3
|
+
export declare function ErrorAlert(props: {
|
|
4
|
+
error: FlowErrorDisplay | undefined;
|
|
5
|
+
style?: CSSProperties | undefined;
|
|
6
|
+
testId?: string | undefined;
|
|
7
|
+
}): ReactElement | null;
|
|
8
|
+
//# sourceMappingURL=ErrorAlert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorAlert.d.ts","sourceRoot":"","sources":["../../src/default/ErrorAlert.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,KAAK,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACpC,KAAK,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,YAAY,GAAG,IAAI,CAqBtB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* The one error surface this pair's default skins render, so the split copy
|
|
4
|
+
* core produces reaches a screen the same way everywhere.
|
|
5
|
+
*
|
|
6
|
+
* Core's `describeFlowError` splits a failure into the sentence a person
|
|
7
|
+
* reads and the technical detail a support agent quotes (owner report
|
|
8
|
+
* 2026-08-09: the status used to be spliced into the sentence, which ended
|
|
9
|
+
* in a bare `" (500)"` — and a product does not read a protocol number out to
|
|
10
|
+
* a person). The split is only worth anything if a
|
|
11
|
+
* skin actually renders both halves at their own weights: `message` at
|
|
12
|
+
* normal weight, `detail` muted and small, where an eye skips it and a
|
|
13
|
+
* support agent finds it.
|
|
14
|
+
*
|
|
15
|
+
* `undefined` in — including a `detail` that core left `undefined` because
|
|
16
|
+
* there was nothing worth quoting — renders nothing rather than an empty
|
|
17
|
+
* muted line.
|
|
18
|
+
*/
|
|
19
|
+
import { Alert, Typography } from "antd";
|
|
20
|
+
export function ErrorAlert(props) {
|
|
21
|
+
const { error } = props;
|
|
22
|
+
if (!error)
|
|
23
|
+
return null;
|
|
24
|
+
return (_jsx(Alert, { type: "error", showIcon: true, ...(props.style ? { style: props.style } : {}), ...(props.testId ? { "data-testid": props.testId } : {}), message: error.message, ...(error.detail
|
|
25
|
+
? {
|
|
26
|
+
description: (_jsx(Typography.Text, { type: "secondary", style: { fontSize: 12 }, children: error.detail })),
|
|
27
|
+
}
|
|
28
|
+
: {}) }));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=ErrorAlert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorAlert.js","sourceRoot":"","sources":["../../src/default/ErrorAlert.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAIzC,MAAM,UAAU,UAAU,CAAC,KAI1B;IACC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACxB,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,CACL,KAAC,KAAK,IACJ,IAAI,EAAC,OAAO,EACZ,QAAQ,WACJ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAC3C,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACzD,OAAO,EAAE,KAAK,CAAC,OAAO,KAClB,CAAC,KAAK,CAAC,MAAM;YACf,CAAC,CAAC;gBACE,WAAW,EAAE,CACX,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,EAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,YACtD,KAAK,CAAC,MAAM,GACG,CACnB;aACF;YACH,CAAC,CAAC,EAAE,CAAC,GACP,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MembersManager.d.ts","sourceRoot":"","sources":["../../src/default/MembersManager.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MembersManager.d.ts","sourceRoot":"","sources":["../../src/default/MembersManager.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAW1C,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAID,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CA4JvE"}
|
|
@@ -15,18 +15,19 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
15
15
|
* the invite dialog filters it out, as before.
|
|
16
16
|
*/
|
|
17
17
|
import { useState } from "react";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
18
|
+
import { Button, Card, Input, Modal, Popconfirm, Select, Table, Typography } from "antd";
|
|
19
|
+
import { useErrorDisplay, useT } from "@stapel/core";
|
|
20
20
|
import { Members } from "../headless/Members.js";
|
|
21
21
|
import { RoleSelect } from "../headless/RoleSelect.js";
|
|
22
22
|
import { WORKSPACES_I18N_KEYS } from "../i18n/keys.js";
|
|
23
|
+
import { ErrorAlert } from "./ErrorAlert.js";
|
|
23
24
|
const DEFAULT_INVITE_ROLE = "member";
|
|
24
25
|
export function MembersManager(props) {
|
|
25
26
|
const t = useT();
|
|
26
27
|
// Never the raw `.message` — for a response with no error envelope that
|
|
27
28
|
// is the transport's own "Request failed with status 500" (owner report
|
|
28
29
|
// 2026-08-09). `useErrorText` folds any thrown value into the one dialect.
|
|
29
|
-
const
|
|
30
|
+
const errorDisplay = useErrorDisplay(WORKSPACES_I18N_KEYS.unknownError);
|
|
30
31
|
const canManage = props.canManage ?? true;
|
|
31
32
|
const [inviteOpen, setInviteOpen] = useState(false);
|
|
32
33
|
const [emailsText, setEmailsText] = useState("");
|
|
@@ -80,7 +81,7 @@ export function MembersManager(props) {
|
|
|
80
81
|
]
|
|
81
82
|
: []),
|
|
82
83
|
];
|
|
83
|
-
return (_jsxs(Card, { "data-testid": "members-manager", children: [_jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 16 }, children: [_jsxs("div", { children: [_jsx(Typography.Title, { level: 4, style: { marginTop: 0 }, children: t(WORKSPACES_I18N_KEYS.membersTitle) }), _jsx(Typography.Text, { type: "secondary", children: t(WORKSPACES_I18N_KEYS.membersSubtitle) })] }), canManage && (_jsx(Button, { type: "primary", onClick: openInvite, "data-analytics": "none", "data-analytics-reason": "local-ui-open-invite-dialog", children: t(WORKSPACES_I18N_KEYS.membersInvite) }))] }), isError &&
|
|
84
|
+
return (_jsxs(Card, { "data-testid": "members-manager", children: [_jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 16 }, children: [_jsxs("div", { children: [_jsx(Typography.Title, { level: 4, style: { marginTop: 0 }, children: t(WORKSPACES_I18N_KEYS.membersTitle) }), _jsx(Typography.Text, { type: "secondary", children: t(WORKSPACES_I18N_KEYS.membersSubtitle) })] }), canManage && (_jsx(Button, { type: "primary", onClick: openInvite, "data-analytics": "none", "data-analytics-reason": "local-ui-open-invite-dialog", children: t(WORKSPACES_I18N_KEYS.membersInvite) }))] }), isError && _jsx(ErrorAlert, { error: errorDisplay(error), style: { marginTop: 12 } }), _jsx(Table, { style: { marginTop: 16 }, size: "small", loading: isLoading, rowKey: (member) => member.id, dataSource: members, columns: columns, pagination: false }), _jsx(Modal, { title: t(WORKSPACES_I18N_KEYS.membersInviteDialogTitle), open: inviteOpen, onCancel: () => setInviteOpen(false), onOk: submitInvite, okButtonProps: { loading: isInviting, disabled: emailsText.trim().length === 0 }, children: _jsxs("div", { style: { display: "grid", gap: 12 }, children: [_jsxs("div", { children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.membersInviteEmailsLabel) }), _jsx(Input, { value: emailsText, onChange: (e) => setEmailsText(e.target.value), placeholder: t(WORKSPACES_I18N_KEYS.membersInviteEmailsPlaceholder) })] }), _jsxs("div", { children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.membersInviteRoleLabel) }), _jsx(Select, { value: inviteRole, onChange: setInviteRole, style: { width: "100%" }, loading: rolesBag.isLoading, options: inviteRoleOptions })] })] }) })] }));
|
|
84
85
|
} })) }));
|
|
85
86
|
}
|
|
86
87
|
//# sourceMappingURL=MembersManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MembersManager.js","sourceRoot":"","sources":["../../src/default/MembersManager.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"MembersManager.js","sourceRoot":"","sources":["../../src/default/MembersManager.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceSettings.d.ts","sourceRoot":"","sources":["../../src/default/WorkspaceSettings.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"WorkspaceSettings.d.ts","sourceRoot":"","sources":["../../src/default/WorkspaceSettings.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAQ1C,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB;gEAC4D;IAC5D,SAAS,CAAC,IAAI,IAAI,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,CAwG7E"}
|
|
@@ -8,17 +8,18 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
* `<MembersManager/>` (a workspace's settings page composes both).
|
|
9
9
|
*/
|
|
10
10
|
import { useEffect, useState } from "react";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { Badge, Button, Card, Input, Popconfirm, Spin, Typography } from "antd";
|
|
12
|
+
import { useErrorDisplay, useT } from "@stapel/core";
|
|
13
13
|
import { useWorkspace } from "../model/queries.js";
|
|
14
14
|
import { useUpdateWorkspace, useDeleteWorkspace } from "../model/mutations.js";
|
|
15
15
|
import { WORKSPACES_I18N_KEYS } from "../i18n/keys.js";
|
|
16
|
+
import { ErrorAlert } from "./ErrorAlert.js";
|
|
16
17
|
export function WorkspaceSettings(props) {
|
|
17
18
|
const t = useT();
|
|
18
19
|
// Never the raw `.message` — for a response with no error envelope that
|
|
19
20
|
// is the transport's own "Request failed with status 500" (owner report
|
|
20
21
|
// 2026-08-09). `useErrorText` folds any thrown value into the one dialect.
|
|
21
|
-
const
|
|
22
|
+
const errorDisplay = useErrorDisplay(WORKSPACES_I18N_KEYS.unknownError);
|
|
22
23
|
const query = useWorkspace(props.workspaceId);
|
|
23
24
|
const updateMutation = useUpdateWorkspace(props.workspaceId);
|
|
24
25
|
const deleteMutation = useDeleteWorkspace();
|
|
@@ -40,9 +41,12 @@ export function WorkspaceSettings(props) {
|
|
|
40
41
|
return _jsx(Spin, { "data-testid": "workspace-settings-loading" });
|
|
41
42
|
}
|
|
42
43
|
if (!workspace) {
|
|
43
|
-
return (_jsx(
|
|
44
|
+
return (_jsx(ErrorAlert, { testId: "workspace-settings-error", error: errorDisplay(query.error) ?? {
|
|
45
|
+
message: t(WORKSPACES_I18N_KEYS.unknownError),
|
|
46
|
+
detail: undefined,
|
|
47
|
+
} }));
|
|
44
48
|
}
|
|
45
49
|
const isOwner = workspace.my_role === "owner";
|
|
46
|
-
return (_jsxs("div", { "data-testid": "workspace-settings", style: { display: "grid", gap: 16 }, children: [_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: { display: "grid", gap: 12, maxWidth: 480, marginTop: 16 }, children: [_jsxs("div", { children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.fieldName) }), _jsx(Input, { value: name, onChange: (e) => setName(e.target.value), disabled: !isOwner })] }), _jsxs("div", { children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.fieldSlug) }), _jsx("div", { children: _jsx(Typography.Text, { code: true, children: workspace.slug }) })] }), _jsxs("div", { children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.fieldType) }), _jsx("div", { children: _jsx(Badge, { status: "default", text: workspace.type }) })] })] }),
|
|
50
|
+
return (_jsxs("div", { "data-testid": "workspace-settings", style: { display: "grid", gap: 16 }, children: [_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: { display: "grid", gap: 12, maxWidth: 480, marginTop: 16 }, children: [_jsxs("div", { children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.fieldName) }), _jsx(Input, { value: name, onChange: (e) => setName(e.target.value), disabled: !isOwner })] }), _jsxs("div", { children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.fieldSlug) }), _jsx("div", { children: _jsx(Typography.Text, { code: true, children: workspace.slug }) })] }), _jsxs("div", { children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.fieldType) }), _jsx("div", { children: _jsx(Badge, { status: "default", text: workspace.type }) })] })] }), _jsx(ErrorAlert, { error: errorDisplay(updateMutation.error), style: { marginTop: 12 } }), _jsx(Button, { type: "primary", style: { marginTop: 16 }, loading: updateMutation.isPending, disabled: !isOwner || !name.trim(), onClick: handleSave, "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 ? t(WORKSPACES_I18N_KEYS.saving) : t(WORKSPACES_I18N_KEYS.save) })] }), isOwner && (_jsxs(Card, { children: [_jsx(Typography.Title, { level: 5, type: "danger", style: { marginTop: 0 }, children: t(WORKSPACES_I18N_KEYS.dangerZoneTitle) }), _jsx(Popconfirm, { title: t(WORKSPACES_I18N_KEYS.deleteWorkspaceConfirm), onConfirm: handleDelete, okButtonProps: { loading: deleteMutation.isPending, danger: true }, children: _jsx(Button, { danger: true, children: t(WORKSPACES_I18N_KEYS.deleteWorkspace) }) })] }))] }));
|
|
47
51
|
}
|
|
48
52
|
//# sourceMappingURL=WorkspaceSettings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceSettings.js","sourceRoot":"","sources":["../../src/default/WorkspaceSettings.tsx"],"names":[],"mappings":";AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"WorkspaceSettings.js","sourceRoot":"","sources":["../../src/default/WorkspaceSettings.tsx"],"names":[],"mappings":"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"}
|
package/llms.txt
CHANGED
package/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stapel/workspaces-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Headless React flow pair for stapel-workspaces: typed API client, TanStack Query hooks, flow machines, headless components, and i18n keys. Zero visual opinion.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
}
|
|
59
59
|
],
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"@stapel/core": ">=0.
|
|
61
|
+
"@stapel/core": ">=0.12.0 <1.0.0",
|
|
62
62
|
"@tanstack/react-query": "^5.0.0",
|
|
63
63
|
"antd": ">=5.20.0 <7",
|
|
64
64
|
"react": ">=19"
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"size-limit": "^11.2.0",
|
|
83
83
|
"typescript": "^5.8.3",
|
|
84
84
|
"vitest": "^3.2.4",
|
|
85
|
-
"@stapel/core": "^0.
|
|
85
|
+
"@stapel/core": "^0.12.0",
|
|
86
86
|
"@stapel/showcase": "^0.2.0",
|
|
87
87
|
"@stapel/tokens": "^0.5.0"
|
|
88
88
|
},
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one error surface this pair's default skins render, so the split copy
|
|
3
|
+
* core produces reaches a screen the same way everywhere.
|
|
4
|
+
*
|
|
5
|
+
* Core's `describeFlowError` splits a failure into the sentence a person
|
|
6
|
+
* reads and the technical detail a support agent quotes (owner report
|
|
7
|
+
* 2026-08-09: the status used to be spliced into the sentence, which ended
|
|
8
|
+
* in a bare `" (500)"` — and a product does not read a protocol number out to
|
|
9
|
+
* a person). The split is only worth anything if a
|
|
10
|
+
* skin actually renders both halves at their own weights: `message` at
|
|
11
|
+
* normal weight, `detail` muted and small, where an eye skips it and a
|
|
12
|
+
* support agent finds it.
|
|
13
|
+
*
|
|
14
|
+
* `undefined` in — including a `detail` that core left `undefined` because
|
|
15
|
+
* there was nothing worth quoting — renders nothing rather than an empty
|
|
16
|
+
* muted line.
|
|
17
|
+
*/
|
|
18
|
+
import { Alert, Typography } from "antd";
|
|
19
|
+
import type { CSSProperties, ReactElement } from "react";
|
|
20
|
+
import type { FlowErrorDisplay } from "@stapel/core";
|
|
21
|
+
|
|
22
|
+
export function ErrorAlert(props: {
|
|
23
|
+
error: FlowErrorDisplay | undefined;
|
|
24
|
+
style?: CSSProperties | undefined;
|
|
25
|
+
testId?: string | undefined;
|
|
26
|
+
}): ReactElement | null {
|
|
27
|
+
const { error } = props;
|
|
28
|
+
if (!error) return null;
|
|
29
|
+
return (
|
|
30
|
+
<Alert
|
|
31
|
+
type="error"
|
|
32
|
+
showIcon
|
|
33
|
+
{...(props.style ? { style: props.style } : {})}
|
|
34
|
+
{...(props.testId ? { "data-testid": props.testId } : {})}
|
|
35
|
+
message={error.message}
|
|
36
|
+
{...(error.detail
|
|
37
|
+
? {
|
|
38
|
+
description: (
|
|
39
|
+
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
|
|
40
|
+
{error.detail}
|
|
41
|
+
</Typography.Text>
|
|
42
|
+
),
|
|
43
|
+
}
|
|
44
|
+
: {})}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -15,14 +15,15 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { useState } from "react";
|
|
17
17
|
import type { ReactElement } from "react";
|
|
18
|
-
import {
|
|
18
|
+
import { Button, Card, Input, Modal, Popconfirm, Select, Table, Typography } from "antd";
|
|
19
19
|
import type { TableProps } from "antd";
|
|
20
|
-
import {
|
|
20
|
+
import { useErrorDisplay, useT } from "@stapel/core";
|
|
21
21
|
import { Members } from "../headless/Members.js";
|
|
22
22
|
import { RoleSelect } from "../headless/RoleSelect.js";
|
|
23
23
|
import type { RoleSelectBag } from "../headless/RoleSelect.js";
|
|
24
24
|
import type { Member } from "../api/types.js";
|
|
25
25
|
import { WORKSPACES_I18N_KEYS } from "../i18n/keys.js";
|
|
26
|
+
import { ErrorAlert } from "./ErrorAlert.js";
|
|
26
27
|
|
|
27
28
|
export interface MembersManagerProps {
|
|
28
29
|
workspaceId: string;
|
|
@@ -43,7 +44,7 @@ export function MembersManager(props: MembersManagerProps): ReactElement {
|
|
|
43
44
|
// Never the raw `.message` — for a response with no error envelope that
|
|
44
45
|
// is the transport's own "Request failed with status 500" (owner report
|
|
45
46
|
// 2026-08-09). `useErrorText` folds any thrown value into the one dialect.
|
|
46
|
-
const
|
|
47
|
+
const errorDisplay = useErrorDisplay(WORKSPACES_I18N_KEYS.unknownError);
|
|
47
48
|
const canManage = props.canManage ?? true;
|
|
48
49
|
const [inviteOpen, setInviteOpen] = useState(false);
|
|
49
50
|
const [emailsText, setEmailsText] = useState("");
|
|
@@ -147,9 +148,7 @@ export function MembersManager(props: MembersManagerProps): ReactElement {
|
|
|
147
148
|
)}
|
|
148
149
|
</div>
|
|
149
150
|
|
|
150
|
-
{isError && error
|
|
151
|
-
<Alert style={{ marginTop: 12 }} type="error" showIcon message={errorText(error)} />
|
|
152
|
-
)}
|
|
151
|
+
{isError && <ErrorAlert error={errorDisplay(error)} style={{ marginTop: 12 }} />}
|
|
153
152
|
|
|
154
153
|
<Table<Member>
|
|
155
154
|
style={{ marginTop: 16 }}
|
|
@@ -8,11 +8,12 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { useEffect, useState } from "react";
|
|
10
10
|
import type { ReactElement } from "react";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { Badge, Button, Card, Input, Popconfirm, Spin, Typography } from "antd";
|
|
12
|
+
import { useErrorDisplay, useT } from "@stapel/core";
|
|
13
13
|
import { useWorkspace } from "../model/queries.js";
|
|
14
14
|
import { useUpdateWorkspace, useDeleteWorkspace } from "../model/mutations.js";
|
|
15
15
|
import { WORKSPACES_I18N_KEYS } from "../i18n/keys.js";
|
|
16
|
+
import { ErrorAlert } from "./ErrorAlert.js";
|
|
16
17
|
|
|
17
18
|
export interface WorkspaceSettingsProps {
|
|
18
19
|
workspaceId: string;
|
|
@@ -26,7 +27,7 @@ export function WorkspaceSettings(props: WorkspaceSettingsProps): ReactElement {
|
|
|
26
27
|
// Never the raw `.message` — for a response with no error envelope that
|
|
27
28
|
// is the transport's own "Request failed with status 500" (owner report
|
|
28
29
|
// 2026-08-09). `useErrorText` folds any thrown value into the one dialect.
|
|
29
|
-
const
|
|
30
|
+
const errorDisplay = useErrorDisplay(WORKSPACES_I18N_KEYS.unknownError);
|
|
30
31
|
const query = useWorkspace(props.workspaceId);
|
|
31
32
|
const updateMutation = useUpdateWorkspace(props.workspaceId);
|
|
32
33
|
const deleteMutation = useDeleteWorkspace();
|
|
@@ -53,11 +54,14 @@ export function WorkspaceSettings(props: WorkspaceSettingsProps): ReactElement {
|
|
|
53
54
|
}
|
|
54
55
|
if (!workspace) {
|
|
55
56
|
return (
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
<ErrorAlert
|
|
58
|
+
testId="workspace-settings-error"
|
|
59
|
+
error={
|
|
60
|
+
errorDisplay(query.error) ?? {
|
|
61
|
+
message: t(WORKSPACES_I18N_KEYS.unknownError),
|
|
62
|
+
detail: undefined,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
61
65
|
/>
|
|
62
66
|
);
|
|
63
67
|
}
|
|
@@ -91,14 +95,7 @@ export function WorkspaceSettings(props: WorkspaceSettingsProps): ReactElement {
|
|
|
91
95
|
</div>
|
|
92
96
|
</div>
|
|
93
97
|
|
|
94
|
-
{updateMutation.error
|
|
95
|
-
<Alert
|
|
96
|
-
style={{ marginTop: 12 }}
|
|
97
|
-
type="error"
|
|
98
|
-
showIcon
|
|
99
|
-
message={errorText(updateMutation.error)}
|
|
100
|
-
/>
|
|
101
|
-
)}
|
|
98
|
+
<ErrorAlert error={errorDisplay(updateMutation.error)} style={{ marginTop: 12 }} />
|
|
102
99
|
|
|
103
100
|
<Button
|
|
104
101
|
type="primary"
|