@stapel/workspaces-react 0.13.0 → 0.15.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 +65 -0
- package/dist/api/generated/schema.d.ts +165 -3
- package/dist/api/generated/schema.d.ts.map +1 -1
- package/dist/api/types.d.ts +22 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/workspacesApi.d.ts +5 -1
- package/dist/api/workspacesApi.d.ts.map +1 -1
- package/dist/api/workspacesApi.js +16 -0
- package/dist/api/workspacesApi.js.map +1 -1
- package/dist/default/MembersManager.d.ts.map +1 -1
- package/dist/default/MembersManager.js +20 -6
- package/dist/default/MembersManager.js.map +1 -1
- package/dist/default/WorkspaceSettings.d.ts.map +1 -1
- package/dist/default/WorkspaceSettings.js +7 -3
- package/dist/default/WorkspaceSettings.js.map +1 -1
- package/dist/headless/Can.d.ts +8 -0
- package/dist/headless/Can.d.ts.map +1 -1
- package/dist/headless/Can.js +5 -1
- package/dist/headless/Can.js.map +1 -1
- package/dist/headless/Members.d.ts +14 -13
- package/dist/headless/Members.d.ts.map +1 -1
- package/dist/headless/Members.js +4 -12
- package/dist/headless/Members.js.map +1 -1
- package/dist/headless/RoleSelect.d.ts +15 -9
- package/dist/headless/RoleSelect.d.ts.map +1 -1
- package/dist/headless/RoleSelect.js +12 -8
- package/dist/headless/RoleSelect.js.map +1 -1
- package/dist/headless/WorkspaceList.d.ts +25 -10
- package/dist/headless/WorkspaceList.d.ts.map +1 -1
- package/dist/headless/WorkspaceList.js +14 -5
- package/dist/headless/WorkspaceList.js.map +1 -1
- package/dist/i18n/generated/errors.es.gen.d.ts.map +1 -1
- package/dist/i18n/generated/errors.es.gen.js +2 -0
- package/dist/i18n/generated/errors.es.gen.js.map +1 -1
- package/dist/i18n/generated/errors.gen.d.ts +12 -0
- package/dist/i18n/generated/errors.gen.d.ts.map +1 -1
- package/dist/i18n/generated/errors.gen.js +6 -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 +2 -0
- package/dist/i18n/generated/errors.ru.gen.js.map +1 -1
- package/dist/i18n/keys.d.ts +13 -0
- package/dist/i18n/keys.d.ts.map +1 -1
- package/dist/i18n/keys.js +23 -0
- package/dist/i18n/keys.js.map +1 -1
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +7 -0
- package/dist/i18n/ru.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/model/queries.d.ts +46 -8
- package/dist/model/queries.d.ts.map +1 -1
- package/dist/model/queries.js +53 -9
- package/dist/model/queries.js.map +1 -1
- package/dist/model/queryKeys.d.ts +3 -1
- package/dist/model/queryKeys.d.ts.map +1 -1
- package/dist/model/queryKeys.js +6 -0
- package/dist/model/queryKeys.js.map +1 -1
- package/dist/model/selection.d.ts +20 -7
- package/dist/model/selection.d.ts.map +1 -1
- package/dist/model/selection.js +32 -12
- package/dist/model/selection.js.map +1 -1
- package/llms.txt +6 -3
- package/manifest.json +46 -3
- package/package.json +2 -2
- package/src/analytics/generated/events.json +1 -1
- package/src/api/generated/schema.ts +165 -3
- package/src/api/types.ts +23 -0
- package/src/api/workspacesApi.ts +22 -0
- package/src/default/MembersManager.tsx +69 -16
- package/src/default/WorkspaceSettings.tsx +41 -5
- package/src/headless/Can.tsx +13 -1
- package/src/headless/Members.tsx +18 -26
- package/src/headless/RoleSelect.tsx +17 -14
- package/src/headless/WorkspaceList.tsx +31 -14
- package/src/i18n/generated/errors.es.gen.ts +2 -0
- package/src/i18n/generated/errors.gen.ts +6 -0
- package/src/i18n/generated/errors.json +16 -0
- package/src/i18n/generated/errors.ru.gen.ts +2 -0
- package/src/i18n/keys.ts +26 -0
- package/src/i18n/ru.ts +10 -0
- package/src/index.ts +5 -0
- package/src/model/queries.ts +77 -16
- package/src/model/queryKeys.ts +16 -1
- package/src/model/selection.tsx +73 -21
|
@@ -15,8 +15,8 @@ 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 { Button, Card, Input, Modal, Popconfirm, Select, Table, Typography } from "antd";
|
|
19
|
-
import { useErrorDisplay, useT } from "@stapel/core";
|
|
18
|
+
import { Button, Card, Empty, Input, Modal, Popconfirm, Select, Table, Typography } from "antd";
|
|
19
|
+
import { loadedRowsOrEmpty, matchList, 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";
|
|
@@ -32,9 +32,15 @@ export function MembersManager(props) {
|
|
|
32
32
|
const [inviteOpen, setInviteOpen] = useState(false);
|
|
33
33
|
const [emailsText, setEmailsText] = useState("");
|
|
34
34
|
const [inviteRole, setInviteRole] = useState(DEFAULT_INVITE_ROLE);
|
|
35
|
-
return (_jsx(RoleSelect, { children: (rolesBag) => (_jsx(Members, { workspaceId: props.workspaceId, children: ({
|
|
35
|
+
return (_jsx(RoleSelect, { children: (rolesBag) => (_jsx(Members, { workspaceId: props.workspaceId, children: ({ state, writeError, invite, isInviting, updateRole, remove, refetch }) => {
|
|
36
36
|
const { labelFor } = rolesBag;
|
|
37
|
-
|
|
37
|
+
// The registry read is a SEPARATE load from the roster's, and it
|
|
38
|
+
// gets its own sentence below rather than silently producing an
|
|
39
|
+
// empty picker — a role menu with nothing in it and a role menu
|
|
40
|
+
// that could not be fetched look identical to a person.
|
|
41
|
+
const rolesFailed = rolesBag.state.status === "failed";
|
|
42
|
+
const rolesLoading = rolesBag.state.status === "loading";
|
|
43
|
+
const roleOptions = loadedRowsOrEmpty(rolesBag.state).map((r) => ({
|
|
38
44
|
value: r.role,
|
|
39
45
|
label: labelFor(r.role),
|
|
40
46
|
}));
|
|
@@ -64,7 +70,7 @@ export function MembersManager(props) {
|
|
|
64
70
|
{
|
|
65
71
|
title: t(WORKSPACES_I18N_KEYS.membersInviteRoleLabel),
|
|
66
72
|
key: "role",
|
|
67
|
-
render: (_, member) => canManage ? (_jsx(Select, { value: member.role, style: { width: 160 }, loading:
|
|
73
|
+
render: (_, member) => canManage ? (_jsx(Select, { value: member.role, style: { width: 160 }, loading: rolesLoading, onChange: (next) => updateRole({ userId: member.user_id, role: next }),
|
|
68
74
|
// A member's CURRENT role may be missing from the
|
|
69
75
|
// registry options (a deployment removed an overlay
|
|
70
76
|
// role) — antd shows the raw value then, which matches
|
|
@@ -81,7 +87,15 @@ export function MembersManager(props) {
|
|
|
81
87
|
]
|
|
82
88
|
: []),
|
|
83
89
|
];
|
|
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) }))] }),
|
|
90
|
+
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) }))] }), writeError !== null && (_jsx(ErrorAlert, { error: errorDisplay(writeError), style: { marginTop: 12 } })), rolesFailed && (_jsx(ErrorAlert, { testId: "members-roles-error", error: { message: t(WORKSPACES_I18N_KEYS.rolesLoadFailed), detail: undefined }, style: { marginTop: 12 } })), matchList(state, {
|
|
91
|
+
loading: () => (_jsx(Table, { style: { marginTop: 16 }, size: "small", loading: true, rowKey: (member) => member.id, dataSource: [], columns: columns, pagination: false })),
|
|
92
|
+
// An antd Table with no rows renders "No data". On a failed
|
|
93
|
+
// read that is the empty-state lie with a built-in
|
|
94
|
+
// illustration, so the table does not get rendered at all.
|
|
95
|
+
failed: (error) => (_jsxs("div", { style: { marginTop: 16 }, "data-testid": "members-list-error", children: [_jsx(ErrorAlert, { error: errorDisplay(error) }), _jsx(Button, { style: { marginTop: 12 }, onClick: refetch, "data-analytics": "none", "data-analytics-reason": "local-ui-refetch-after-a-stated-read-failure", children: t(WORKSPACES_I18N_KEYS.retry) })] })),
|
|
96
|
+
empty: () => (_jsx(Empty, { style: { marginTop: 16 }, "data-testid": "members-list-empty", description: t(WORKSPACES_I18N_KEYS.membersEmpty) })),
|
|
97
|
+
ready: (members) => (_jsx(Table, { style: { marginTop: 16 }, size: "small", rowKey: (member) => member.id, dataSource: [...members], columns: columns, pagination: false })),
|
|
98
|
+
}), _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: rolesLoading, options: inviteRoleOptions })] })] }) })] }));
|
|
85
99
|
} })) }));
|
|
86
100
|
}
|
|
87
101
|
//# 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,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;
|
|
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;AAe1C,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,CAqI7E"}
|
|
@@ -9,7 +9,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
9
9
|
*/
|
|
10
10
|
import { useEffect, useState } from "react";
|
|
11
11
|
import { Badge, Button, Card, Input, Popconfirm, Spin, Typography } from "antd";
|
|
12
|
-
import { useErrorDisplay, useT } from "@stapel/core";
|
|
12
|
+
import { actionAvailable, actionBlocked, firstBlock, useActionGate, 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";
|
|
@@ -25,6 +25,11 @@ export function WorkspaceSettings(props) {
|
|
|
25
25
|
const deleteMutation = useDeleteWorkspace();
|
|
26
26
|
const workspace = query.data;
|
|
27
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)));
|
|
28
33
|
useEffect(() => {
|
|
29
34
|
if (workspace)
|
|
30
35
|
setName(workspace.name);
|
|
@@ -46,7 +51,6 @@ export function WorkspaceSettings(props) {
|
|
|
46
51
|
detail: undefined,
|
|
47
52
|
} }));
|
|
48
53
|
}
|
|
49
|
-
|
|
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) }) })] }))] }));
|
|
54
|
+
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 }), !isOwner && (_jsx("div", { children: _jsx(Typography.Text, { type: "secondary", "data-testid": "workspace-name-blocked", children: t(WORKSPACES_I18N_KEYS.blockedNotOwner) }) }))] }), _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: saveGate.disabled, 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) }), saveGate.reason !== undefined && (_jsx("div", { style: { marginTop: 8 }, children: _jsx(Typography.Text, { type: "secondary", "data-testid": "workspace-save-blocked", children: saveGate.reason }) }))] }), 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) }) })] }))] }));
|
|
51
55
|
}
|
|
52
56
|
//# 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,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAChF,OAAO,
|
|
1
|
+
{"version":3,"file":"WorkspaceSettings.js","sourceRoot":"","sources":["../../src/default/WorkspaceSettings.tsx"],"names":[],"mappings":"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"}
|
package/dist/headless/Can.d.ts
CHANGED
|
@@ -6,6 +6,14 @@ export interface CanBag {
|
|
|
6
6
|
/** The underlying read is still in flight (verdict is `false` meanwhile —
|
|
7
7
|
* deny-by-default; render a skeleton off this if flicker matters). */
|
|
8
8
|
readonly isLoading: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* The read FAILED, so `allowed: false` means "we could not find out",
|
|
11
|
+
* not "you may not". Deny-by-default still holds — a capability check that
|
|
12
|
+
* opened up on an outage would be a security hole — but a skin with
|
|
13
|
+
* somewhere to put a sentence should say which of the two it is rather than
|
|
14
|
+
* silently withholding the control.
|
|
15
|
+
*/
|
|
16
|
+
readonly isUnknown: boolean;
|
|
9
17
|
}
|
|
10
18
|
/**
|
|
11
19
|
* Capability gate (org-program §A2) — the mandate model's UI affordance:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Can.d.ts","sourceRoot":"","sources":["../../src/headless/Can.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,mEAAmE;AACnE,MAAM,WAAW,MAAM;IACrB,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;0EACsE;IACtE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE;IACzB,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB;uCACmC;IACnC,QAAQ,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC;IACnD,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"Can.d.ts","sourceRoot":"","sources":["../../src/headless/Can.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,mEAAmE;AACnE,MAAM,WAAW,MAAM;IACrB,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;0EACsE;IACtE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE;IACzB,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB;uCACmC;IACnC,QAAQ,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC;IACnD,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,GAAG,SAAS,CAWZ"}
|
package/dist/headless/Can.js
CHANGED
|
@@ -23,7 +23,11 @@ export function Can(props) {
|
|
|
23
23
|
const caps = useCapabilities(props.workspaceId);
|
|
24
24
|
const allowed = caps.can(props.capability);
|
|
25
25
|
if (typeof props.children === "function") {
|
|
26
|
-
return props.children({
|
|
26
|
+
return props.children({
|
|
27
|
+
allowed,
|
|
28
|
+
isLoading: caps.state.status === "loading",
|
|
29
|
+
isUnknown: caps.state.status === "failed",
|
|
30
|
+
});
|
|
27
31
|
}
|
|
28
32
|
return allowed ? props.children : (props.fallback ?? null);
|
|
29
33
|
}
|
package/dist/headless/Can.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Can.js","sourceRoot":"","sources":["../../src/headless/Can.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"Can.js","sourceRoot":"","sources":["../../src/headless/Can.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAmBtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,GAAG,CAAC,KASnB;IACC,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC,QAAQ,CAAC;YACpB,OAAO;YACP,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS;YAC1C,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ;SAC1C,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import type { StapelApiError } from "@stapel/core";
|
|
2
|
+
import type { LoadState, StapelApiError } from "@stapel/core";
|
|
3
3
|
import type { Member, MemberInvite } from "../api/types.js";
|
|
4
4
|
import type { MemberRoleChange } from "../model/mutations.js";
|
|
5
5
|
/** Render-prop bag for {@link Members}. */
|
|
6
6
|
export interface MembersBag {
|
|
7
7
|
/**
|
|
8
|
-
* The
|
|
9
|
-
* (default 100)
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* The roster read, as a state a skin cannot flatten — render it with core's
|
|
9
|
+
* `matchList`. This is one page (default 100); a full pager is out of scope
|
|
10
|
+
* for this renderless view (bring your own via `useMembers`' `params` for
|
|
11
|
+
* anchor pagination).
|
|
12
|
+
*
|
|
13
|
+
* Separate from {@link writeError} on purpose: "the roster could not be
|
|
14
|
+
* loaded" and "your invite was rejected" are different sentences, and the
|
|
15
|
+
* old merged `isError` could only produce one of them.
|
|
12
16
|
*/
|
|
13
|
-
readonly
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
readonly isError: boolean;
|
|
18
|
-
/** The error, when `isError` (a localizable `StapelApiError`), else null. */
|
|
19
|
-
readonly error: StapelApiError | null;
|
|
17
|
+
readonly state: LoadState<readonly Member[]>;
|
|
18
|
+
/** An invite, a role change, or a removal failed. Never the read — that is
|
|
19
|
+
* {@link state}. */
|
|
20
|
+
readonly writeError: StapelApiError | null;
|
|
20
21
|
/** Invite one or more emails at a role. */
|
|
21
22
|
invite(body: MemberInvite): void;
|
|
22
23
|
/** An invite call is in flight. */
|
|
@@ -41,7 +42,7 @@ export interface MembersBag {
|
|
|
41
42
|
*
|
|
42
43
|
* ```tsx
|
|
43
44
|
* <Members workspaceId={id}>
|
|
44
|
-
* {({
|
|
45
|
+
* {({ state, invite, updateRole, remove }) => ( ... )}
|
|
45
46
|
* </Members>
|
|
46
47
|
* ```
|
|
47
48
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Members.d.ts","sourceRoot":"","sources":["../../src/headless/Members.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Members.d.ts","sourceRoot":"","sources":["../../src/headless/Members.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAO5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB;;;;;;;;;OASG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAC7C;wBACoB;IACpB,QAAQ,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI,CAAC;IAC3C,2CAA2C;IAC3C,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IACjC,mCAAmC;IACnC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,8BAA8B;IAC9B,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC3C,uCAAuC;IACvC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,mCAAmC;IACnC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mCAAmC;IACnC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,+CAA+C;IAC/C,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,SAAS,CAAC;CAC1C,GAAG,SAAS,CAyBZ"}
|
package/dist/headless/Members.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { loadStateFromQuery, mapLoad } from "@stapel/core";
|
|
1
2
|
import { useMembers } from "../model/queries.js";
|
|
2
3
|
import { useInviteMembers, useRemoveMember, useUpdateMemberRole, } from "../model/mutations.js";
|
|
3
4
|
/**
|
|
@@ -9,7 +10,7 @@ import { useInviteMembers, useRemoveMember, useUpdateMemberRole, } from "../mode
|
|
|
9
10
|
*
|
|
10
11
|
* ```tsx
|
|
11
12
|
* <Members workspaceId={id}>
|
|
12
|
-
* {({
|
|
13
|
+
* {({ state, invite, updateRole, remove }) => ( ... )}
|
|
13
14
|
* </Members>
|
|
14
15
|
* ```
|
|
15
16
|
*/
|
|
@@ -19,17 +20,8 @@ export function Members(props) {
|
|
|
19
20
|
const roleMutation = useUpdateMemberRole(props.workspaceId);
|
|
20
21
|
const removeMutation = useRemoveMember(props.workspaceId);
|
|
21
22
|
return props.children({
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
isError: query.isError ||
|
|
25
|
-
inviteMutation.isError ||
|
|
26
|
-
roleMutation.isError ||
|
|
27
|
-
removeMutation.isError,
|
|
28
|
-
error: query.error ??
|
|
29
|
-
inviteMutation.error ??
|
|
30
|
-
roleMutation.error ??
|
|
31
|
-
removeMutation.error ??
|
|
32
|
-
null,
|
|
23
|
+
state: mapLoad(loadStateFromQuery(query), (page) => page.items),
|
|
24
|
+
writeError: inviteMutation.error ?? roleMutation.error ?? removeMutation.error ?? null,
|
|
33
25
|
invite: (body) => {
|
|
34
26
|
inviteMutation.mutate(body);
|
|
35
27
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Members.js","sourceRoot":"","sources":["../../src/headless/Members.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Members.js","sourceRoot":"","sources":["../../src/headless/Members.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG3D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAmC/B;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,OAAO,CAAC,KAGvB;IACC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,cAAc,GAAG,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,mBAAmB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC5D,MAAM,cAAc,GAAG,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC1D,OAAO,KAAK,CAAC,QAAQ,CAAC;QACpB,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;QAC/D,UAAU,EACR,cAAc,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,IAAI,cAAc,CAAC,KAAK,IAAI,IAAI;QAC5E,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACf,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QACD,UAAU,EAAE,cAAc,CAAC,SAAS;QACpC,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE;YACrB,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QACD,cAAc,EAAE,YAAY,CAAC,SAAS;QACtC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YACjB,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QACD,UAAU,EAAE,cAAc,CAAC,SAAS;QACpC,OAAO,EAAE,GAAG,EAAE;YACZ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import type {
|
|
2
|
+
import type { LoadState } from "@stapel/core";
|
|
3
3
|
import type { RoleInfo } from "../api/types.js";
|
|
4
4
|
/** Render-prop bag for {@link RoleSelect}. */
|
|
5
5
|
export interface RoleSelectBag {
|
|
6
6
|
/** The effective registry (GET /roles): builtin four + the deployment's
|
|
7
|
-
* overlay, rank-descending.
|
|
8
|
-
|
|
7
|
+
* overlay, rank-descending. A state rather than an array: a role picker
|
|
8
|
+
* built from `[]` because the registry read FAILED offers no roles at all
|
|
9
|
+
* and looks exactly like a deployment that defined none. */
|
|
10
|
+
readonly state: LoadState<readonly RoleInfo[]>;
|
|
9
11
|
/**
|
|
10
12
|
* Display label for a role key: the i18n key `workspaces.role.<key>` when
|
|
11
13
|
* the current locale's merged bundle carries it (the pair ships the builtin
|
|
@@ -15,9 +17,6 @@ export interface RoleSelectBag {
|
|
|
15
17
|
* never render as a dotted i18n key.
|
|
16
18
|
*/
|
|
17
19
|
labelFor(role: string): string;
|
|
18
|
-
readonly isLoading: boolean;
|
|
19
|
-
readonly isError: boolean;
|
|
20
|
-
readonly error: StapelApiError | null;
|
|
21
20
|
}
|
|
22
21
|
/**
|
|
23
22
|
* Headless role picker over the effective role registry (org-program §A2) —
|
|
@@ -26,9 +25,16 @@ export interface RoleSelectBag {
|
|
|
26
25
|
*
|
|
27
26
|
* ```tsx
|
|
28
27
|
* <RoleSelect>
|
|
29
|
-
* {({
|
|
30
|
-
*
|
|
31
|
-
*
|
|
28
|
+
* {({ state, labelFor }) =>
|
|
29
|
+
* matchList(state, {
|
|
30
|
+
* loading: () => <Select loading options={[]} />,
|
|
31
|
+
* failed: (error) => <RoleLoadFailed error={error} />,
|
|
32
|
+
* empty: () => <Select disabled options={[]} />,
|
|
33
|
+
* ready: (roles) => (
|
|
34
|
+
* <Select options={roles.map((r) => ({ value: r.role, label: labelFor(r.role) }))} />
|
|
35
|
+
* ),
|
|
36
|
+
* })
|
|
37
|
+
* }
|
|
32
38
|
* </RoleSelect>
|
|
33
39
|
* ```
|
|
34
40
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoleSelect.d.ts","sourceRoot":"","sources":["../../src/headless/RoleSelect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"RoleSelect.d.ts","sourceRoot":"","sources":["../../src/headless/RoleSelect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGhD,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B;;;gEAG4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,QAAQ,EAAE,CAAC,CAAC;IAC/C;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,QAAQ,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,SAAS,CAAC;CAC7C,GAAG,SAAS,CAWZ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useI18n } from "@stapel/core";
|
|
1
|
+
import { loadStateFromQuery, useI18n } from "@stapel/core";
|
|
2
2
|
import { useRoles } from "../model/queries.js";
|
|
3
3
|
/**
|
|
4
4
|
* Headless role picker over the effective role registry (org-program §A2) —
|
|
@@ -7,9 +7,16 @@ import { useRoles } from "../model/queries.js";
|
|
|
7
7
|
*
|
|
8
8
|
* ```tsx
|
|
9
9
|
* <RoleSelect>
|
|
10
|
-
* {({
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* {({ state, labelFor }) =>
|
|
11
|
+
* matchList(state, {
|
|
12
|
+
* loading: () => <Select loading options={[]} />,
|
|
13
|
+
* failed: (error) => <RoleLoadFailed error={error} />,
|
|
14
|
+
* empty: () => <Select disabled options={[]} />,
|
|
15
|
+
* ready: (roles) => (
|
|
16
|
+
* <Select options={roles.map((r) => ({ value: r.role, label: labelFor(r.role) }))} />
|
|
17
|
+
* ),
|
|
18
|
+
* })
|
|
19
|
+
* }
|
|
13
20
|
* </RoleSelect>
|
|
14
21
|
* ```
|
|
15
22
|
*
|
|
@@ -24,11 +31,8 @@ export function RoleSelect(props) {
|
|
|
24
31
|
// must show its raw name, not `workspaces.role.secretary`).
|
|
25
32
|
const bundle = i18n.getBundle();
|
|
26
33
|
return props.children({
|
|
27
|
-
|
|
34
|
+
state: loadStateFromQuery(query),
|
|
28
35
|
labelFor: (role) => bundle[`workspaces.role.${role}`] ?? role,
|
|
29
|
-
isLoading: query.isLoading,
|
|
30
|
-
isError: query.isError,
|
|
31
|
-
error: query.error ?? null,
|
|
32
36
|
});
|
|
33
37
|
}
|
|
34
38
|
//# sourceMappingURL=RoleSelect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoleSelect.js","sourceRoot":"","sources":["../../src/headless/RoleSelect.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"RoleSelect.js","sourceRoot":"","sources":["../../src/headless/RoleSelect.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG3D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAoB/C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,UAAU,CAAC,KAE1B;IACC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,2EAA2E;IAC3E,2EAA2E;IAC3E,4DAA4D;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IAChC,OAAO,KAAK,CAAC,QAAQ,CAAC;QACpB,KAAK,EAAE,kBAAkB,CAAC,KAAK,CAAC;QAChC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,mBAAmB,IAAI,EAAE,CAAC,IAAI,IAAI;KAC9D,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import type { StapelApiError } from "@stapel/core";
|
|
2
|
+
import type { LoadState, StapelApiError } from "@stapel/core";
|
|
3
3
|
import type { Workspace, WorkspaceCreate } from "../api/types.js";
|
|
4
4
|
/** Render-prop bag for {@link WorkspaceList}. */
|
|
5
5
|
export interface WorkspaceListBag {
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The read, as a state a skin cannot flatten: `loading` / `ready` with the
|
|
8
|
+
* rows / `failed` with the error. Render it with core's `matchList`, whose
|
|
9
|
+
* four arms are all required, so "you have no workspaces" can only be said
|
|
10
|
+
* about a load that actually succeeded.
|
|
11
|
+
*
|
|
12
|
+
* This replaced a `workspaces: readonly Workspace[]` field that was `[]` in
|
|
13
|
+
* all three cases. On 2026-08-09 the list endpoint answered 404 for hours
|
|
14
|
+
* and every screen built on that field said the person had no workspaces.
|
|
15
|
+
* The bag carried `isError` beside it the whole time; nothing forced a skin
|
|
16
|
+
* to look, so nothing did.
|
|
17
|
+
*/
|
|
18
|
+
readonly state: LoadState<readonly Workspace[]>;
|
|
14
19
|
/** Create a workspace (owner-seeded). */
|
|
15
20
|
create(body: WorkspaceCreate): void;
|
|
16
21
|
/** A create call is in flight. */
|
|
17
22
|
readonly isCreating: boolean;
|
|
18
23
|
/** The workspace created by the last `create`, else null. */
|
|
19
24
|
readonly created: Workspace | null;
|
|
25
|
+
/** The CREATE's failure — a write, and therefore a different question from
|
|
26
|
+
* {@link state}, which is about the read. */
|
|
27
|
+
readonly createError: StapelApiError | null;
|
|
20
28
|
/** Refetch the list from the server. */
|
|
21
29
|
refetch(): void;
|
|
22
30
|
}
|
|
@@ -28,7 +36,14 @@ export interface WorkspaceListBag {
|
|
|
28
36
|
*
|
|
29
37
|
* ```tsx
|
|
30
38
|
* <WorkspaceList>
|
|
31
|
-
* {({
|
|
39
|
+
* {({ state, create }) =>
|
|
40
|
+
* matchList(state, {
|
|
41
|
+
* loading: () => <Spinner />,
|
|
42
|
+
* failed: (error) => <ErrorPanel error={error} onRetry={refetch} />,
|
|
43
|
+
* empty: () => <FirstWorkspacePrompt onCreate={create} />,
|
|
44
|
+
* ready: (workspaces) => <List items={workspaces} />,
|
|
45
|
+
* })
|
|
46
|
+
* }
|
|
32
47
|
* </WorkspaceList>
|
|
33
48
|
* ```
|
|
34
49
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceList.d.ts","sourceRoot":"","sources":["../../src/headless/WorkspaceList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"WorkspaceList.d.ts","sourceRoot":"","sources":["../../src/headless/WorkspaceList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIlE,iDAAiD;AACjD,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IAChD,yCAAyC;IACzC,MAAM,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,kCAAkC;IAClC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IACnC;iDAC6C;IAC7C,QAAQ,CAAC,WAAW,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5C,wCAAwC;IACxC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,QAAQ,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,SAAS,CAAC;CAChD,GAAG,SAAS,CAkBZ"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { loadStateFromQuery, mapLoad } from "@stapel/core";
|
|
1
2
|
import { useWorkspaces } from "../model/queries.js";
|
|
2
3
|
import { useCreateWorkspace } from "../model/mutations.js";
|
|
3
4
|
/**
|
|
@@ -8,7 +9,14 @@ import { useCreateWorkspace } from "../model/mutations.js";
|
|
|
8
9
|
*
|
|
9
10
|
* ```tsx
|
|
10
11
|
* <WorkspaceList>
|
|
11
|
-
* {({
|
|
12
|
+
* {({ state, create }) =>
|
|
13
|
+
* matchList(state, {
|
|
14
|
+
* loading: () => <Spinner />,
|
|
15
|
+
* failed: (error) => <ErrorPanel error={error} onRetry={refetch} />,
|
|
16
|
+
* empty: () => <FirstWorkspacePrompt onCreate={create} />,
|
|
17
|
+
* ready: (workspaces) => <List items={workspaces} />,
|
|
18
|
+
* })
|
|
19
|
+
* }
|
|
12
20
|
* </WorkspaceList>
|
|
13
21
|
* ```
|
|
14
22
|
*/
|
|
@@ -16,15 +24,16 @@ export function WorkspaceList(props) {
|
|
|
16
24
|
const query = useWorkspaces();
|
|
17
25
|
const mutation = useCreateWorkspace();
|
|
18
26
|
return props.children({
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
// `workspaces` is optional in the wire schema, so a SUCCESSFUL response
|
|
28
|
+
// may legitimately carry none. That is an empty list, not a failed load —
|
|
29
|
+
// the distinction this whole field exists for is already made above it.
|
|
30
|
+
state: mapLoad(loadStateFromQuery(query), (list) => list.workspaces ?? []),
|
|
23
31
|
create: (body) => {
|
|
24
32
|
mutation.mutate(body);
|
|
25
33
|
},
|
|
26
34
|
isCreating: mutation.isPending,
|
|
27
35
|
created: mutation.data ?? null,
|
|
36
|
+
createError: mutation.error ?? null,
|
|
28
37
|
refetch: () => {
|
|
29
38
|
void query.refetch();
|
|
30
39
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceList.js","sourceRoot":"","sources":["../../src/headless/WorkspaceList.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WorkspaceList.js","sourceRoot":"","sources":["../../src/headless/WorkspaceList.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG3D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AA8B3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAAC,KAE7B;IACC,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;IACtC,OAAO,KAAK,CAAC,QAAQ,CAAC;QACpB,wEAAwE;QACxE,0EAA0E;QAC1E,wEAAwE;QACxE,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;QAC1E,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACf,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QACD,UAAU,EAAE,QAAQ,CAAC,SAAS;QAC9B,OAAO,EAAE,QAAQ,CAAC,IAAI,IAAI,IAAI;QAC9B,WAAW,EAAE,QAAQ,CAAC,KAAK,IAAI,IAAI;QACnC,OAAO,EAAE,GAAG,EAAE;YACZ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.es.gen.d.ts","sourceRoot":"","sources":["../../../src/i18n/generated/errors.es.gen.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"errors.es.gen.d.ts","sourceRoot":"","sources":["../../../src/i18n/generated/errors.es.gen.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAsEvE,CAAC"}
|
|
@@ -49,6 +49,7 @@ export const workspacesErrorBundleEs = {
|
|
|
49
49
|
"error.403.role_exceeds_inviter_rank": "No puedes conceder un rol superior al tuyo ({role})",
|
|
50
50
|
"error.403.verification_enrollment_required": "Es necesario registrar un factor de verificación.",
|
|
51
51
|
"error.403.verification_required": "Se requiere verificación adicional",
|
|
52
|
+
"error.403.workspace_creation_closed": "Esta instancia no te permite crear espacios de trabajo",
|
|
52
53
|
"error.404.ad_not_found": "Anuncio no encontrado",
|
|
53
54
|
"error.404.invitation_not_found": "Invitación no encontrada",
|
|
54
55
|
"error.404.member_not_found": "Miembro no encontrado en este espacio de trabajo",
|
|
@@ -66,6 +67,7 @@ export const workspacesErrorBundleEs = {
|
|
|
66
67
|
"error.422.unprocessable_entity": "Entidad no procesable",
|
|
67
68
|
"error.423.locked": "El recurso está bloqueado",
|
|
68
69
|
"error.423.verification_locked": "Demasiados intentos fallidos — verificación bloqueada",
|
|
70
|
+
"error.429.invitation_resend_cooldown": "Esta invitación se envió por correo hace poco; puedes volver a enviarla en {retry_after} segundos",
|
|
69
71
|
"error.429.rate_limit": "Demasiados intentos. Inténtalo de nuevo en {retry_after_minutes} minutos.",
|
|
70
72
|
"error.429.too_many_requests": "Demasiadas solicitudes. Inténtalo de nuevo más tarde.",
|
|
71
73
|
"error.500.internal": "Algo salió mal",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.es.gen.js","sourceRoot":"","sources":["../../../src/i18n/generated/errors.es.gen.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAwC;IAC1E,oCAAoC,EAAE,qDAAqD;IAC3F,uBAAuB,EAAE,sBAAsB;IAC/C,2BAA2B,EAAE,6DAA6D;IAC1F,4BAA4B,EAAE,mCAAmC;IACjE,8BAA8B,EAAE,iDAAiD;IACjF,wCAAwC,EAAE,0DAA0D;IACpG,wCAAwC,EAAE,uDAAuD;IACjG,kCAAkC,EAAE,yDAAyD;IAC7F,yBAAyB,EAAE,oCAAoC;IAC/D,uBAAuB,EAAE,8BAA8B;IACvD,gCAAgC,EAAE,mBAAmB;IACrD,yBAAyB,EAAE,sBAAsB;IACjD,gCAAgC,EAAE,iCAAiC;IACnE,4BAA4B,EAAE,wDAAwD;IACtF,2BAA2B,EAAE,0CAA0C;IACvE,4BAA4B,EAAE,qDAAqD;IACnF,2BAA2B,EAAE,0CAA0C;IACvE,sBAAsB,EAAE,2BAA2B;IACnD,0BAA0B,EAAE,wBAAwB;IACpD,wBAAwB,EAAE,wBAAwB;IAClD,yBAAyB,EAAE,yBAAyB;IACpD,sCAAsC,EAAE,2DAA2D;IACnG,wBAAwB,EAAE,eAAe;IACzC,mCAAmC,EAAE,kCAAkC;IACvE,+BAA+B,EAAE,iCAAiC;IAClE,8BAA8B,EAAE,2BAA2B;IAC3D,8BAA8B,EAAE,gCAAgC;IAChE,4BAA4B,EAAE,qBAAqB;IACnD,+BAA+B,EAAE,4BAA4B;IAC7D,uCAAuC,EAAE,gDAAgD;IACzF,gCAAgC,EAAE,+CAA+C;IACjF,wBAAwB,EAAE,2BAA2B;IACrD,gCAAgC,EAAE,wEAAwE;IAC1G,gCAAgC,EAAE,wEAAwE;IAC1G,4BAA4B,EAAE,kBAAkB;IAChD,qBAAqB,EAAE,6CAA6C;IACpE,+BAA+B,EAAE,4CAA4C;IAC7E,wCAAwC,EAAE,6EAA6E;IACvH,gCAAgC,EAAE,qEAAqE;IACvG,8BAA8B,EAAE,wEAAwE;IACxG,2BAA2B,EAAE,4CAA4C;IACzE,qCAAqC,EAAE,qDAAqD;IAC5F,4CAA4C,EAAE,mDAAmD;IACjG,iCAAiC,EAAE,oCAAoC;IACvE,wBAAwB,EAAE,uBAAuB;IACjD,gCAAgC,EAAE,0BAA0B;IAC5D,4BAA4B,EAAE,kDAAkD;IAChF,qBAAqB,EAAE,kCAAkC;IACzD,4CAA4C,EAAE,kDAAkD;IAChG,+BAA+B,EAAE,kCAAkC;IACnE,8BAA8B,EAAE,qBAAqB;IACrD,0BAA0B,EAAE,cAAc;IAC1C,2BAA2B,EAAE,0CAA0C;IACvE,oBAAoB,EAAE,sBAAsB;IAC5C,oCAAoC,EAAE,6EAA6E;IACnH,gBAAgB,EAAE,4CAA4C;IAC9D,6BAA6B,EAAE,+CAA+C;IAC9E,kCAAkC,EAAE,iCAAiC;IACrE,gCAAgC,EAAE,uBAAuB;IACzD,kBAAkB,EAAE,2BAA2B;IAC/C,+BAA+B,EAAE,uDAAuD;IACxF,sBAAsB,EAAE,2EAA2E;IACnG,6BAA6B,EAAE,uDAAuD;IACtF,oBAAoB,EAAE,gBAAgB;IACtC,4BAA4B,EAAE,+EAA+E;IAC7G,mCAAmC,EAAE,2HAA2H;IAChK,gCAAgC,EAAE,0EAA0E;CAC7G,CAAC"}
|
|
1
|
+
{"version":3,"file":"errors.es.gen.js","sourceRoot":"","sources":["../../../src/i18n/generated/errors.es.gen.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAwC;IAC1E,oCAAoC,EAAE,qDAAqD;IAC3F,uBAAuB,EAAE,sBAAsB;IAC/C,2BAA2B,EAAE,6DAA6D;IAC1F,4BAA4B,EAAE,mCAAmC;IACjE,8BAA8B,EAAE,iDAAiD;IACjF,wCAAwC,EAAE,0DAA0D;IACpG,wCAAwC,EAAE,uDAAuD;IACjG,kCAAkC,EAAE,yDAAyD;IAC7F,yBAAyB,EAAE,oCAAoC;IAC/D,uBAAuB,EAAE,8BAA8B;IACvD,gCAAgC,EAAE,mBAAmB;IACrD,yBAAyB,EAAE,sBAAsB;IACjD,gCAAgC,EAAE,iCAAiC;IACnE,4BAA4B,EAAE,wDAAwD;IACtF,2BAA2B,EAAE,0CAA0C;IACvE,4BAA4B,EAAE,qDAAqD;IACnF,2BAA2B,EAAE,0CAA0C;IACvE,sBAAsB,EAAE,2BAA2B;IACnD,0BAA0B,EAAE,wBAAwB;IACpD,wBAAwB,EAAE,wBAAwB;IAClD,yBAAyB,EAAE,yBAAyB;IACpD,sCAAsC,EAAE,2DAA2D;IACnG,wBAAwB,EAAE,eAAe;IACzC,mCAAmC,EAAE,kCAAkC;IACvE,+BAA+B,EAAE,iCAAiC;IAClE,8BAA8B,EAAE,2BAA2B;IAC3D,8BAA8B,EAAE,gCAAgC;IAChE,4BAA4B,EAAE,qBAAqB;IACnD,+BAA+B,EAAE,4BAA4B;IAC7D,uCAAuC,EAAE,gDAAgD;IACzF,gCAAgC,EAAE,+CAA+C;IACjF,wBAAwB,EAAE,2BAA2B;IACrD,gCAAgC,EAAE,wEAAwE;IAC1G,gCAAgC,EAAE,wEAAwE;IAC1G,4BAA4B,EAAE,kBAAkB;IAChD,qBAAqB,EAAE,6CAA6C;IACpE,+BAA+B,EAAE,4CAA4C;IAC7E,wCAAwC,EAAE,6EAA6E;IACvH,gCAAgC,EAAE,qEAAqE;IACvG,8BAA8B,EAAE,wEAAwE;IACxG,2BAA2B,EAAE,4CAA4C;IACzE,qCAAqC,EAAE,qDAAqD;IAC5F,4CAA4C,EAAE,mDAAmD;IACjG,iCAAiC,EAAE,oCAAoC;IACvE,qCAAqC,EAAE,wDAAwD;IAC/F,wBAAwB,EAAE,uBAAuB;IACjD,gCAAgC,EAAE,0BAA0B;IAC5D,4BAA4B,EAAE,kDAAkD;IAChF,qBAAqB,EAAE,kCAAkC;IACzD,4CAA4C,EAAE,kDAAkD;IAChG,+BAA+B,EAAE,kCAAkC;IACnE,8BAA8B,EAAE,qBAAqB;IACrD,0BAA0B,EAAE,cAAc;IAC1C,2BAA2B,EAAE,0CAA0C;IACvE,oBAAoB,EAAE,sBAAsB;IAC5C,oCAAoC,EAAE,6EAA6E;IACnH,gBAAgB,EAAE,4CAA4C;IAC9D,6BAA6B,EAAE,+CAA+C;IAC9E,kCAAkC,EAAE,iCAAiC;IACrE,gCAAgC,EAAE,uBAAuB;IACzD,kBAAkB,EAAE,2BAA2B;IAC/C,+BAA+B,EAAE,uDAAuD;IACxF,sCAAsC,EAAE,mGAAmG;IAC3I,sBAAsB,EAAE,2EAA2E;IACnG,6BAA6B,EAAE,uDAAuD;IACtF,oBAAoB,EAAE,gBAAgB;IACtC,4BAA4B,EAAE,+EAA+E;IAC7G,mCAAmC,EAAE,2HAA2H;IAChK,gCAAgC,EAAE,0EAA0E;CAC7G,CAAC"}
|
|
@@ -286,6 +286,12 @@ export declare const WORKSPACES_ERRORS: {
|
|
|
286
286
|
readonly remediation: "verify";
|
|
287
287
|
readonly en: "Additional verification required";
|
|
288
288
|
};
|
|
289
|
+
readonly "error.403.workspace_creation_closed": {
|
|
290
|
+
readonly status: 403;
|
|
291
|
+
readonly params: readonly [];
|
|
292
|
+
readonly remediation: "contact_support";
|
|
293
|
+
readonly en: "This instance does not allow you to create workspaces";
|
|
294
|
+
};
|
|
289
295
|
readonly "error.404.ad_not_found": {
|
|
290
296
|
readonly status: 404;
|
|
291
297
|
readonly params: readonly [];
|
|
@@ -388,6 +394,12 @@ export declare const WORKSPACES_ERRORS: {
|
|
|
388
394
|
readonly remediation: "wait_and_retry";
|
|
389
395
|
readonly en: "Too many failed attempts — verification locked";
|
|
390
396
|
};
|
|
397
|
+
readonly "error.429.invitation_resend_cooldown": {
|
|
398
|
+
readonly status: 429;
|
|
399
|
+
readonly params: readonly ["retry_after"];
|
|
400
|
+
readonly remediation: "wait_and_retry";
|
|
401
|
+
readonly en: "This invitation was emailed recently; you can send it again in {retry_after} seconds";
|
|
402
|
+
};
|
|
391
403
|
readonly "error.429.rate_limit": {
|
|
392
404
|
readonly status: 429;
|
|
393
405
|
readonly params: readonly ["retry_after_minutes"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.gen.d.ts","sourceRoot":"","sources":["../../../src/i18n/generated/errors.gen.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,gBAAgB,GAChB,gBAAgB,GAChB,QAAQ,GACR,WAAW,GACX,iBAAiB,GACjB,KAAK,CAAC;AAEV,MAAM,WAAW,mBAAmB;IAClC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"errors.gen.d.ts","sourceRoot":"","sources":["../../../src/i18n/generated/errors.gen.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,gBAAgB,GAChB,gBAAgB,GAChB,QAAQ,GACR,WAAW,GACX,iBAAiB,GACjB,KAAK,CAAC;AAEV,MAAM,WAAW,mBAAmB;IAClC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsEpB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,iBAAiB,CAAC;AAEjE,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,EAAE,SAAS,mBAAmB,EAsEhE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAsEvE,CAAC"}
|