@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,154 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* `<AuditTrailPane/>` — the workspace's membership history (GET
|
|
4
|
+
* `{ws}/audit`), the record nothing kept before stapel-workspaces 0.24: who
|
|
5
|
+
* let this person in, who took them out, and when.
|
|
6
|
+
*
|
|
7
|
+
* Three things this screen refuses to do, all of them things a log viewer
|
|
8
|
+
* does and a product must not:
|
|
9
|
+
*
|
|
10
|
+
* - **No raw enum.** `member_role_changed` is a vocabulary term, not a
|
|
11
|
+
* sentence. The closed `AuditAction` vocabulary has a label per value; a
|
|
12
|
+
* value from a newer backend falls back to the key title-cased, never to a
|
|
13
|
+
* dotted i18n key and never to the raw snake_case token.
|
|
14
|
+
* - **No ISO timestamps.** "3 days ago (23 Sept 2026, 09:00)" — the relative
|
|
15
|
+
* reading a person wants and the absolute one a support agent quotes, in
|
|
16
|
+
* the reader's own calendar.
|
|
17
|
+
* - **No ids on the glass.** An actor the journal has no name for is "the
|
|
18
|
+
* system", which is what an actorless line actually means (a sweep, an
|
|
19
|
+
* expiry), rather than a truncated UUID.
|
|
20
|
+
*
|
|
21
|
+
* The read is gated server-side on `members.view`: every role that may see
|
|
22
|
+
* who is in the room may see how they got there.
|
|
23
|
+
*/
|
|
24
|
+
import { useState } from "react";
|
|
25
|
+
import { Card, Flex, Select, Typography, theme as antdTheme } from "antd";
|
|
26
|
+
import { loadStateFromQuery, mapLoad, useI18n, useT } from "@stapel/core";
|
|
27
|
+
import { EmptyState, LoadList, SkinTheme, } from "@stapel/tokens-antd/skin";
|
|
28
|
+
import { spacing } from "@stapel/tokens";
|
|
29
|
+
import { useAudit } from "../model/queries.js";
|
|
30
|
+
import { titleCaseKey, useWorkspaceFormat } from "../model/format.js";
|
|
31
|
+
import { WORKSPACES_I18N_KEYS } from "../i18n/keys.js";
|
|
32
|
+
import { AnchorPager, Muted, PersonLine, StatusTag } from "./parts.js";
|
|
33
|
+
import { ActiveWorkspaceBoundary } from "./ActiveWorkspace.js";
|
|
34
|
+
import { useRoleLabel } from "./RoleSelectField.js";
|
|
35
|
+
/**
|
|
36
|
+
* The CLOSED action vocabulary (`models.AuditAction`), in lifecycle order —
|
|
37
|
+
* an invitation, then what became of it, then what became of the membership,
|
|
38
|
+
* then the end of the workspace. The filter offers exactly these because the
|
|
39
|
+
* server matches nothing for a value outside them, and a filter that silently
|
|
40
|
+
* does not apply is worse than an empty page.
|
|
41
|
+
*/
|
|
42
|
+
const ACTIONS = [
|
|
43
|
+
"invitation_created",
|
|
44
|
+
"invitation_accepted",
|
|
45
|
+
"invitation_declined",
|
|
46
|
+
"invitation_revoked",
|
|
47
|
+
"account_created_by_invitation",
|
|
48
|
+
"member_joined",
|
|
49
|
+
"member_provisioned",
|
|
50
|
+
"member_role_changed",
|
|
51
|
+
"member_suspended",
|
|
52
|
+
"member_unsuspended",
|
|
53
|
+
"member_removed",
|
|
54
|
+
"deleted",
|
|
55
|
+
];
|
|
56
|
+
const FIRST_PAGE = { anchor: undefined, direction: undefined, index: 1 };
|
|
57
|
+
/** The tone a line reads in: a removal is not the same news as a join. */
|
|
58
|
+
function toneFor(action) {
|
|
59
|
+
if (action === "member_removed" || action === "deleted")
|
|
60
|
+
return "danger";
|
|
61
|
+
if (action === "member_suspended" || action === "invitation_revoked")
|
|
62
|
+
return "warning";
|
|
63
|
+
if (action === "member_joined" ||
|
|
64
|
+
action === "invitation_accepted" ||
|
|
65
|
+
action === "member_unsuspended") {
|
|
66
|
+
return "success";
|
|
67
|
+
}
|
|
68
|
+
return "neutral";
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Consecutive events under the day they happened on.
|
|
72
|
+
*
|
|
73
|
+
* The wire returns the page already ordered, so grouping is a fold over
|
|
74
|
+
* neighbours — never a re-sort, which would put a client's opinion of the
|
|
75
|
+
* order above the server's cursor. An instant the formatter cannot read keeps
|
|
76
|
+
* its own group rather than being folded into the previous day.
|
|
77
|
+
*/
|
|
78
|
+
function groupByDay(events, dateOf) {
|
|
79
|
+
const groups = [];
|
|
80
|
+
for (const event of events) {
|
|
81
|
+
const label = dateOf(event.created_at) ?? "";
|
|
82
|
+
const current = groups[groups.length - 1];
|
|
83
|
+
if (current !== undefined && current.label === label)
|
|
84
|
+
current.events.push(event);
|
|
85
|
+
else
|
|
86
|
+
groups.push({ label, events: [event] });
|
|
87
|
+
}
|
|
88
|
+
return groups;
|
|
89
|
+
}
|
|
90
|
+
export function AuditTrailPane(props) {
|
|
91
|
+
return (_jsx(SkinTheme, { "data-testid": "audit-trail", children: _jsx(ActiveWorkspaceBoundary, { workspaceId: props.workspaceId, testId: "audit-trail-workspace", children: (workspaceId) => _jsx(AuditTrailBody, { workspaceId: workspaceId }) }) }));
|
|
92
|
+
}
|
|
93
|
+
function AuditTrailBody(props) {
|
|
94
|
+
const t = useT();
|
|
95
|
+
const i18n = useI18n();
|
|
96
|
+
const format = useWorkspaceFormat();
|
|
97
|
+
const [action, setAction] = useState(null);
|
|
98
|
+
const [walk, setWalk] = useState(FIRST_PAGE);
|
|
99
|
+
const params = {
|
|
100
|
+
...(action !== null ? { action } : {}),
|
|
101
|
+
...(walk.anchor !== undefined ? { anchor: walk.anchor } : {}),
|
|
102
|
+
...(walk.direction !== undefined ? { direction: walk.direction } : {}),
|
|
103
|
+
};
|
|
104
|
+
const query = useAudit(props.workspaceId, params);
|
|
105
|
+
const page = query.data ?? null;
|
|
106
|
+
// Raw bundle lookup, not `t()`: `t` falls back to the key itself, and a
|
|
107
|
+
// dotted i18n key is the one thing this must never print. Same contract as
|
|
108
|
+
// RoleSelect's `labelFor`.
|
|
109
|
+
const bundle = i18n.getBundle();
|
|
110
|
+
const labelForAction = (value) => bundle[`workspaces.audit.action.${value}`] ?? titleCaseKey(value);
|
|
111
|
+
return (_jsxs(Card, { children: [_jsxs(Flex, { vertical: true, gap: spacing["1"], children: [_jsx(Typography.Title, { level: 4, style: { marginTop: 0, marginBottom: 0 }, children: t(WORKSPACES_I18N_KEYS.auditTitle) }), _jsx(Typography.Text, { type: "secondary", children: t(WORKSPACES_I18N_KEYS.auditSubtitle) })] }), _jsxs(Flex, { gap: spacing["2"], align: "center", style: { marginTop: spacing["4"] }, wrap: true, children: [_jsx(Muted, { children: t(WORKSPACES_I18N_KEYS.auditFilterLabel) }), _jsx(Select, { value: action ?? "", onChange: (next) => {
|
|
112
|
+
// A new filter is a new walk: the anchor belongs to the old one.
|
|
113
|
+
setAction(next === "" ? null : next);
|
|
114
|
+
setWalk(FIRST_PAGE);
|
|
115
|
+
}, "aria-label": t(WORKSPACES_I18N_KEYS.auditFilterLabel), style: { flex: "1 1 14rem", maxWidth: "20rem" }, "data-testid": "audit-filter", options: [
|
|
116
|
+
{ value: "", label: t(WORKSPACES_I18N_KEYS.auditFilterAll) },
|
|
117
|
+
...ACTIONS.map((value) => ({ value, label: labelForAction(value) })),
|
|
118
|
+
] })] }), _jsx("div", { style: { marginTop: spacing["4"] }, children: _jsx(LoadList, { state: mapLoad(loadStateFromQuery(query), (loaded) => loaded.items), testId: "audit-list", onRetry: () => {
|
|
119
|
+
void query.refetch();
|
|
120
|
+
}, empty: _jsx(EmptyState, { title: t(WORKSPACES_I18N_KEYS.auditEmpty), testId: "audit-list-empty" }), children: (events) => (_jsx("div", { role: "list", "data-testid": "audit-rows", children: groupByDay(events, format.date).map((day) => (_jsxs("section", { "data-testid": `audit-day-${day.label}`, children: [_jsx("div", { style: { marginTop: spacing["4"], marginBottom: spacing["1"] }, children: _jsx(Typography.Text, { strong: true, children: day.label }) }), day.events.map((event) => (_jsx(AuditRow, { event: event, label: labelForAction(event.action) }, event.id)))] }, day.label))) })) }) }), page !== null && (_jsx(AnchorPager, { hasPrev: page.has_prev, hasNext: page.has_next, prevLabel: t(WORKSPACES_I18N_KEYS.pagerPrev), nextLabel: t(WORKSPACES_I18N_KEYS.pagerNext), position: t(WORKSPACES_I18N_KEYS.pagerPosition, { page: walk.index }), testId: "audit-pager", onPrev: () => setWalk({
|
|
121
|
+
anchor: page.prev_anchor ?? undefined,
|
|
122
|
+
direction: "prev",
|
|
123
|
+
index: Math.max(1, walk.index - 1),
|
|
124
|
+
}), onNext: () => setWalk({
|
|
125
|
+
anchor: page.next_anchor ?? undefined,
|
|
126
|
+
direction: "next",
|
|
127
|
+
index: walk.index + 1,
|
|
128
|
+
}) }))] }));
|
|
129
|
+
}
|
|
130
|
+
function AuditRow(props) {
|
|
131
|
+
const t = useT();
|
|
132
|
+
const format = useWorkspaceFormat();
|
|
133
|
+
const labelForRole = useRoleLabel();
|
|
134
|
+
const { token } = antdTheme.useToken();
|
|
135
|
+
const { event } = props;
|
|
136
|
+
const actor = event.actor_display_name?.trim();
|
|
137
|
+
return (_jsxs("div", { role: "listitem", "data-testid": `audit-row-${event.id}`, style: {
|
|
138
|
+
display: "flex",
|
|
139
|
+
flexWrap: "wrap",
|
|
140
|
+
alignItems: "flex-start",
|
|
141
|
+
justifyContent: "space-between",
|
|
142
|
+
gap: spacing["3"],
|
|
143
|
+
paddingTop: spacing["3"],
|
|
144
|
+
paddingBottom: spacing["3"],
|
|
145
|
+
borderBottom: `1px solid ${token.colorSplit}`,
|
|
146
|
+
}, children: [_jsx(PersonLine, { name: event.subject_display_name ?? null, email: event.subject_email ?? null, tags: _jsx(StatusTag, { tone: toneFor(event.action), testId: `audit-action-${event.id}`, children: props.label }), caption: _jsxs(_Fragment, { children: [t(WORKSPACES_I18N_KEYS.auditBy, {
|
|
147
|
+
actor: actor !== undefined && actor !== ""
|
|
148
|
+
? actor
|
|
149
|
+
: t(WORKSPACES_I18N_KEYS.auditActorUnknown),
|
|
150
|
+
}), event.role !== null && event.role !== undefined && event.role !== "" && (_jsxs(_Fragment, { children: [" · ", t(WORKSPACES_I18N_KEYS.auditRoleLine, {
|
|
151
|
+
role: labelForRole(event.role),
|
|
152
|
+
})] }))] }) }), _jsx(Muted, { testId: `audit-when-${event.id}`, children: format.time(event.created_at) })] }));
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=AuditTrailPane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuditTrailPane.js","sourceRoot":"","sources":["../../src/default/AuditTrailPane.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
export interface InvitationsPaneProps {
|
|
3
|
+
/**
|
|
4
|
+
* The workspace whose invitations these are. OPTIONAL: omitted (the way the
|
|
5
|
+
* nav contract mounts this screen), the active workspace comes from the
|
|
6
|
+
* runtime selection, and a screen with none renders the designed "choose a
|
|
7
|
+
* workspace" state.
|
|
8
|
+
*/
|
|
9
|
+
workspaceId?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Whether the caller may administer invitations (capability
|
|
12
|
+
* `members.invite`). The host knows its own verdict — pass `false` for a
|
|
13
|
+
* read-only view, which says so instead of silently dropping the controls.
|
|
14
|
+
* Default `true`.
|
|
15
|
+
*/
|
|
16
|
+
canManage?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function InvitationsPane(props: InvitationsPaneProps): ReactElement;
|
|
19
|
+
//# sourceMappingURL=InvitationsPane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvitationsPane.d.ts","sourceRoot":"","sources":["../../src/default/InvitationsPane.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAkC1C,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA2BD,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CAgBzE"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* `<InvitationsPane/>` — the admin's "who has not joined yet" console
|
|
4
|
+
* (stapel-workspaces #109). Four endpoints that had four hooks and zero
|
|
5
|
+
* pixels: list, revoke, resend, rename.
|
|
6
|
+
*
|
|
7
|
+
* ## Why each control is gated the way it is
|
|
8
|
+
*
|
|
9
|
+
* The three writes are refused by the backend on the invitation's own state,
|
|
10
|
+
* not on the caller's role, so the state is what the screen gates on and the
|
|
11
|
+
* reason is the one the endpoint would give:
|
|
12
|
+
*
|
|
13
|
+
* - **Revoke** and **rename** need a `pending` row. A terminal invitation
|
|
14
|
+
* answers `error.400.invitation_already_used` / `_revoked` / `_declined` /
|
|
15
|
+
* `_expired`; offering the control and letting the person discover that is
|
|
16
|
+
* the "button that leads to a refusal" defect.
|
|
17
|
+
* - **Resend** additionally accepts an `expired` row on purpose — a dead TTL
|
|
18
|
+
* is the commonest reason to resend — and it is NOT an idempotent poke: it
|
|
19
|
+
* rotates the token, so every earlier link (including the one in the
|
|
20
|
+
* invitee's inbox) stops working. The confirm says that, because an admin
|
|
21
|
+
* who does not know it will send two links and wonder which one works.
|
|
22
|
+
*
|
|
23
|
+
* Nothing here shows the invite TOKEN: it is a bearer credential that only
|
|
24
|
+
* ever leaves the backend inside the invitation email, and the response shape
|
|
25
|
+
* deliberately does not carry it.
|
|
26
|
+
*/
|
|
27
|
+
import { useState } from "react";
|
|
28
|
+
import { Card, Flex, Input, Segmented, Typography, theme as antdTheme } from "antd";
|
|
29
|
+
import { actionAvailable, actionBlocked, loadStateFromQuery, mapLoad, useT, useTPlural, } from "@stapel/core";
|
|
30
|
+
import { EmptyState, ErrorAlert, GatedButton, LoadList, SkinConfirm, SkinDialog, SkinTheme, } from "@stapel/tokens-antd/skin";
|
|
31
|
+
import { spacing } from "@stapel/tokens";
|
|
32
|
+
import { useInvitations } from "../model/queries.js";
|
|
33
|
+
import { useRenameInvitation, useResendInvitation, useRevokeInvitation, } from "../model/mutations.js";
|
|
34
|
+
import { useWorkspaceFormat } from "../model/format.js";
|
|
35
|
+
import { WORKSPACES_I18N_KEYS } from "../i18n/keys.js";
|
|
36
|
+
import { AnchorPager, Muted, PersonLine, RowActions, StatusTag } from "./parts.js";
|
|
37
|
+
import { ActiveWorkspaceBoundary } from "./ActiveWorkspace.js";
|
|
38
|
+
import { RoleLabel } from "./RoleSelectField.js";
|
|
39
|
+
/** The status a row is in, as the backend derives it. */
|
|
40
|
+
const STATUS_KEY = {
|
|
41
|
+
pending: WORKSPACES_I18N_KEYS.invitationsStatusPending,
|
|
42
|
+
accepted: WORKSPACES_I18N_KEYS.invitationsStatusAccepted,
|
|
43
|
+
declined: WORKSPACES_I18N_KEYS.invitationsStatusDeclined,
|
|
44
|
+
revoked: WORKSPACES_I18N_KEYS.invitationsStatusRevoked,
|
|
45
|
+
expired: WORKSPACES_I18N_KEYS.invitationsStatusExpired,
|
|
46
|
+
};
|
|
47
|
+
const STATUS_TONE = {
|
|
48
|
+
pending: "info",
|
|
49
|
+
accepted: "success",
|
|
50
|
+
declined: "neutral",
|
|
51
|
+
revoked: "neutral",
|
|
52
|
+
expired: "warning",
|
|
53
|
+
};
|
|
54
|
+
const FIRST_PAGE = { anchor: undefined, direction: undefined, index: 1 };
|
|
55
|
+
export function InvitationsPane(props) {
|
|
56
|
+
return (_jsx(SkinTheme, { "data-testid": "invitations-pane", children: _jsx(ActiveWorkspaceBoundary, { workspaceId: props.workspaceId, testId: "invitations-pane-workspace", children: (workspaceId) => (_jsx(InvitationsBody, { workspaceId: workspaceId, canManage: props.canManage ?? true })) }) }));
|
|
57
|
+
}
|
|
58
|
+
function InvitationsBody(props) {
|
|
59
|
+
const t = useT();
|
|
60
|
+
const tPlural = useTPlural();
|
|
61
|
+
const canManage = props.canManage;
|
|
62
|
+
const [status, setStatus] = useState("pending");
|
|
63
|
+
const [search, setSearch] = useState("");
|
|
64
|
+
const [walk, setWalk] = useState(FIRST_PAGE);
|
|
65
|
+
const [revoking, setRevoking] = useState(null);
|
|
66
|
+
const [resending, setResending] = useState(null);
|
|
67
|
+
const [renaming, setRenaming] = useState(null);
|
|
68
|
+
const params = {
|
|
69
|
+
status,
|
|
70
|
+
...(walk.anchor !== undefined ? { anchor: walk.anchor } : {}),
|
|
71
|
+
...(walk.direction !== undefined ? { direction: walk.direction } : {}),
|
|
72
|
+
...(search.trim() !== "" ? { search: search.trim() } : {}),
|
|
73
|
+
};
|
|
74
|
+
const query = useInvitations(props.workspaceId, params);
|
|
75
|
+
const revokeMutation = useRevokeInvitation(props.workspaceId);
|
|
76
|
+
const resendMutation = useResendInvitation(props.workspaceId);
|
|
77
|
+
const renameMutation = useRenameInvitation(props.workspaceId);
|
|
78
|
+
const page = query.data ?? null;
|
|
79
|
+
/** A new filter or a new search is a new walk — an anchor from the old one
|
|
80
|
+
* points into a list that no longer exists. */
|
|
81
|
+
function restart(apply) {
|
|
82
|
+
apply();
|
|
83
|
+
setWalk(FIRST_PAGE);
|
|
84
|
+
}
|
|
85
|
+
return (_jsxs(Card, { children: [_jsxs(Flex, { vertical: true, gap: spacing["1"], children: [_jsx(Typography.Title, { level: 4, style: { marginTop: 0, marginBottom: 0 }, children: t(WORKSPACES_I18N_KEYS.invitationsTitle) }), _jsx(Typography.Text, { type: "secondary", children: t(WORKSPACES_I18N_KEYS.invitationsSubtitle) }), page !== null && (_jsx(Muted, { testId: "invitations-count", children: tPlural(WORKSPACES_I18N_KEYS.invitationsCount, { count: page.count }) }))] }), _jsxs(Flex, { gap: spacing["3"], wrap: true, align: "center", style: { marginTop: spacing["4"] }, children: [_jsx(Segmented, { value: status, onChange: (next) => restart(() => setStatus(next)), "aria-label": t(WORKSPACES_I18N_KEYS.invitationsFilterLabel), "data-testid": "invitations-filter", options: [
|
|
86
|
+
{ value: "pending", label: t(WORKSPACES_I18N_KEYS.invitationsFilterPending) },
|
|
87
|
+
{
|
|
88
|
+
value: "never_accepted",
|
|
89
|
+
label: t(WORKSPACES_I18N_KEYS.invitationsFilterNeverAccepted),
|
|
90
|
+
},
|
|
91
|
+
{ value: "all", label: t(WORKSPACES_I18N_KEYS.invitationsFilterAll) },
|
|
92
|
+
] }), _jsx(Input, { value: search, onChange: (event) => restart(() => setSearch(event.target.value)), placeholder: t(WORKSPACES_I18N_KEYS.invitationsSearchPlaceholder), "aria-label": t(WORKSPACES_I18N_KEYS.invitationsSearchPlaceholder), allowClear: true, style: { flex: "1 1 12rem" }, "data-testid": "invitations-search" })] }), _jsx(ErrorAlert, { thrown: revokeMutation.error ?? resendMutation.error ?? renameMutation.error, style: { marginTop: spacing["3"] }, testId: "invitations-write-error" }), !canManage && (_jsx("div", { style: { marginTop: spacing["2"] }, children: _jsx(Muted, { testId: "invitations-read-only", children: t(WORKSPACES_I18N_KEYS.membersBlockedReadOnly) }) })), _jsx("div", { style: { marginTop: spacing["4"] }, children: _jsx(LoadList, { state: mapLoad(loadStateFromQuery(query), (loaded) => loaded.items), testId: "invitations-list", onRetry: () => {
|
|
93
|
+
void query.refetch();
|
|
94
|
+
}, empty: _jsx(EmptyState, { title: t(WORKSPACES_I18N_KEYS.invitationsEmpty), testId: "invitations-list-empty" }), children: (invitations) => (_jsx("div", { role: "list", "data-testid": "invitations-rows", children: invitations.map((invitation) => (_jsx(InvitationRow, { invitation: invitation, canManage: canManage, onRename: () => setRenaming(invitation), onResend: () => setResending(invitation), onRevoke: () => setRevoking(invitation) }, invitation.id))) })) }) }), page !== null && (_jsx(AnchorPager, { hasPrev: page.has_prev, hasNext: page.has_next, prevLabel: t(WORKSPACES_I18N_KEYS.pagerPrev), nextLabel: t(WORKSPACES_I18N_KEYS.pagerNext), position: t(WORKSPACES_I18N_KEYS.pagerPosition, { page: walk.index }), testId: "invitations-pager", onPrev: () => setWalk({
|
|
95
|
+
anchor: page.prev_anchor ?? undefined,
|
|
96
|
+
direction: "prev",
|
|
97
|
+
index: Math.max(1, walk.index - 1),
|
|
98
|
+
}), onNext: () => setWalk({
|
|
99
|
+
anchor: page.next_anchor ?? undefined,
|
|
100
|
+
direction: "next",
|
|
101
|
+
index: walk.index + 1,
|
|
102
|
+
}) })), _jsx(SkinConfirm, { open: revoking !== null, danger: true, title: t(WORKSPACES_I18N_KEYS.invitationsRevokeConfirm), body: t(WORKSPACES_I18N_KEYS.invitationsRevokeConfirmBody, {
|
|
103
|
+
email: revoking?.email ?? "",
|
|
104
|
+
}), confirmLabel: t(WORKSPACES_I18N_KEYS.invitationsRevoke), cancelLabel: t(WORKSPACES_I18N_KEYS.cancel), confirming: revokeMutation.isPending, onConfirm: () => {
|
|
105
|
+
if (revoking !== null)
|
|
106
|
+
revokeMutation.mutate(revoking.id);
|
|
107
|
+
setRevoking(null);
|
|
108
|
+
}, onCancel: () => setRevoking(null), "data-testid": "invitations-revoke-confirm" }), _jsx(SkinConfirm, { open: resending !== null, title: t(WORKSPACES_I18N_KEYS.invitationsResendConfirm), body: t(WORKSPACES_I18N_KEYS.invitationsResendConfirmBody, {
|
|
109
|
+
email: resending?.email ?? "",
|
|
110
|
+
}), confirmLabel: t(WORKSPACES_I18N_KEYS.invitationsResend), cancelLabel: t(WORKSPACES_I18N_KEYS.cancel), confirming: resendMutation.isPending, onConfirm: () => {
|
|
111
|
+
if (resending !== null)
|
|
112
|
+
resendMutation.mutate(resending.id);
|
|
113
|
+
setResending(null);
|
|
114
|
+
}, onCancel: () => setResending(null), "data-testid": "invitations-resend-confirm" }), _jsx(RenameInvitationDialog, { invitation: renaming, onClose: () => setRenaming(null), isRenaming: renameMutation.isPending, onRename: (displayName) => {
|
|
115
|
+
if (renaming !== null) {
|
|
116
|
+
renameMutation.mutate({ invitationId: renaming.id, displayName });
|
|
117
|
+
}
|
|
118
|
+
setRenaming(null);
|
|
119
|
+
} })] }));
|
|
120
|
+
}
|
|
121
|
+
/** Only a live invitation can be withdrawn or corrected. */
|
|
122
|
+
function pendingOnly(invitation) {
|
|
123
|
+
return invitation.status === "pending"
|
|
124
|
+
? actionAvailable()
|
|
125
|
+
: actionBlocked(WORKSPACES_I18N_KEYS.invitationsBlockedTerminal);
|
|
126
|
+
}
|
|
127
|
+
/** Resend also accepts an expired row — reviving a dead TTL is what it is
|
|
128
|
+
* mostly for — and refuses the three terminal states. */
|
|
129
|
+
function resendable(invitation) {
|
|
130
|
+
return invitation.status === "pending" || invitation.status === "expired"
|
|
131
|
+
? actionAvailable()
|
|
132
|
+
: actionBlocked(WORKSPACES_I18N_KEYS.invitationsBlockedResendTerminal);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The row's refusal as ONE sentence, or `null` when nothing on it is refused.
|
|
136
|
+
*
|
|
137
|
+
* Both gates above answer the same question — what became of this invitation —
|
|
138
|
+
* and the row's status tag has already named it. So a row states the
|
|
139
|
+
* consequence once, in the shape a person reads it ("nothing more can be done
|
|
140
|
+
* with it" / "only resending is left"), instead of repeating a four-way
|
|
141
|
+
* disjunction under every button.
|
|
142
|
+
*/
|
|
143
|
+
function rowReasonKey(invitation) {
|
|
144
|
+
const liveRefused = !pendingOnly(invitation).available;
|
|
145
|
+
const resendRefused = !resendable(invitation).available;
|
|
146
|
+
if (liveRefused && resendRefused) {
|
|
147
|
+
return WORKSPACES_I18N_KEYS.invitationsBlockedRowClosed;
|
|
148
|
+
}
|
|
149
|
+
if (liveRefused)
|
|
150
|
+
return WORKSPACES_I18N_KEYS.invitationsBlockedRowResendOnly;
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
function InvitationRow(props) {
|
|
154
|
+
const t = useT();
|
|
155
|
+
const format = useWorkspaceFormat();
|
|
156
|
+
const { token } = antdTheme.useToken();
|
|
157
|
+
const { invitation } = props;
|
|
158
|
+
const statusKey = STATUS_KEY[invitation.status];
|
|
159
|
+
const expires = format.relative(invitation.expires_at);
|
|
160
|
+
const lastSent = format.relative(invitation.last_sent_at);
|
|
161
|
+
const reasonKey = rowReasonKey(invitation);
|
|
162
|
+
return (_jsxs("div", { role: "listitem", "data-testid": `invitation-row-${invitation.id}`, style: {
|
|
163
|
+
display: "flex",
|
|
164
|
+
flexWrap: "wrap",
|
|
165
|
+
alignItems: "center",
|
|
166
|
+
justifyContent: "space-between",
|
|
167
|
+
gap: spacing["3"],
|
|
168
|
+
paddingTop: spacing["3"],
|
|
169
|
+
paddingBottom: spacing["3"],
|
|
170
|
+
borderBottom: `1px solid ${token.colorSplit}`,
|
|
171
|
+
}, children: [_jsx(PersonLine, { name: invitation.display_name ?? null, email: invitation.email, tags: _jsx(StatusTag, { tone: STATUS_TONE[invitation.status] ?? "neutral", testId: `invitation-status-${invitation.id}`, children: statusKey === undefined ? invitation.status : t(statusKey) }), caption: _jsxs(_Fragment, { children: [_jsx(RoleLabel, { role: invitation.role }), expires !== null && (_jsxs(_Fragment, { children: [" · ", t(WORKSPACES_I18N_KEYS.invitationsExpiresLabel), ": ", expires] })), " · ", lastSent === null
|
|
172
|
+
? t(WORKSPACES_I18N_KEYS.invitationsSentNever)
|
|
173
|
+
: `${t(WORKSPACES_I18N_KEYS.invitationsSentLabel)}: ${lastSent}`] }) }), props.canManage && (_jsx(RowActions, { testId: `invitation-blocked-${invitation.id}`, ...(reasonKey !== null ? { reason: t(reasonKey) } : {}), actions: [
|
|
174
|
+
{
|
|
175
|
+
key: "rename",
|
|
176
|
+
gate: pendingOnly(invitation),
|
|
177
|
+
label: t(WORKSPACES_I18N_KEYS.invitationsRename),
|
|
178
|
+
onClick: props.onRename,
|
|
179
|
+
testId: `invitation-rename-${invitation.id}`,
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
key: "resend",
|
|
183
|
+
gate: resendable(invitation),
|
|
184
|
+
label: t(WORKSPACES_I18N_KEYS.invitationsResend),
|
|
185
|
+
onClick: props.onResend,
|
|
186
|
+
testId: `invitation-resend-${invitation.id}`,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
key: "revoke",
|
|
190
|
+
gate: pendingOnly(invitation),
|
|
191
|
+
label: t(WORKSPACES_I18N_KEYS.invitationsRevoke),
|
|
192
|
+
onClick: props.onRevoke,
|
|
193
|
+
danger: true,
|
|
194
|
+
testId: `invitation-revoke-${invitation.id}`,
|
|
195
|
+
},
|
|
196
|
+
] }))] }));
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* The name correction one step before the member rename: the invitee has not
|
|
200
|
+
* accepted, so there is no profile to write and the hint lives on the
|
|
201
|
+
* invitation. `accept_invitation` copies it onto the membership.
|
|
202
|
+
*/
|
|
203
|
+
function RenameInvitationDialog(props) {
|
|
204
|
+
const t = useT();
|
|
205
|
+
const current = props.invitation?.display_name ?? "";
|
|
206
|
+
const [value, setValue] = useState(current);
|
|
207
|
+
const [editingId, setEditingId] = useState(null);
|
|
208
|
+
if (props.invitation !== null && editingId !== props.invitation.id) {
|
|
209
|
+
setEditingId(props.invitation.id);
|
|
210
|
+
setValue(props.invitation.display_name ?? "");
|
|
211
|
+
}
|
|
212
|
+
const gate = value.trim() === current.trim()
|
|
213
|
+
? actionBlocked(WORKSPACES_I18N_KEYS.membersRenameBlockedUnchanged)
|
|
214
|
+
: actionAvailable();
|
|
215
|
+
return (_jsx(SkinDialog, { open: props.invitation !== null, onClose: props.onClose, title: t(WORKSPACES_I18N_KEYS.invitationsRenameDialogTitle), dismissLabel: t(WORKSPACES_I18N_KEYS.dialogClose), "data-testid": "invitations-rename-dialog", footer: _jsx(GatedButton, { gate: gate, type: "primary", loading: props.isRenaming, onClick: () => props.onRename(value.trim() === "" ? null : value.trim()), testId: "invitations-rename-submit", "data-analytics": "none", "data-analytics-reason": "business action \u2014 host app wraps with its own tracked()", children: t(WORKSPACES_I18N_KEYS.membersRenameSubmit) }), children: _jsxs(Flex, { vertical: true, gap: spacing["2"], children: [_jsx(Typography.Text, { children: t(WORKSPACES_I18N_KEYS.membersRenameLabel) }), _jsx(Input, { value: value, onChange: (event) => setValue(event.target.value), placeholder: t(WORKSPACES_I18N_KEYS.membersRenamePlaceholder), "aria-label": t(WORKSPACES_I18N_KEYS.membersRenameLabel), "data-testid": "invitations-rename-input" })] }) }));
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=InvitationsPane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvitationsPane.js","sourceRoot":"","sources":["../../src/default/InvitationsPane.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AACpF,OAAO,EACL,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,OAAO,EACP,IAAI,EACJ,UAAU,GACX,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,UAAU,EACV,UAAU,EACV,WAAW,EACX,QAAQ,EACR,WAAW,EACX,UAAU,EACV,SAAS,GACV,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAmBjD,yDAAyD;AACzD,MAAM,UAAU,GAA2B;IACzC,OAAO,EAAE,oBAAoB,CAAC,wBAAwB;IACtD,QAAQ,EAAE,oBAAoB,CAAC,yBAAyB;IACxD,QAAQ,EAAE,oBAAoB,CAAC,yBAAyB;IACxD,OAAO,EAAE,oBAAoB,CAAC,wBAAwB;IACtD,OAAO,EAAE,oBAAoB,CAAC,wBAAwB;CACvD,CAAC;AAEF,MAAM,WAAW,GAA0E;IACzF,OAAO,EAAE,MAAM;IACf,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;CACnB,CAAC;AAQF,MAAM,UAAU,GAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAE/E,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,OAAO,CACL,KAAC,SAAS,mBAAa,kBAAkB,YACvC,KAAC,uBAAuB,IACtB,WAAW,EAAE,KAAK,CAAC,WAAW,EAC9B,MAAM,EAAC,4BAA4B,YAElC,CAAC,WAAW,EAAE,EAAE,CAAC,CAChB,KAAC,eAAe,IACd,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,GAClC,CACH,GACuB,GAChB,CACb,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAGxB;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAyB,SAAS,CAAC,CAAC;IACxE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAO,UAAU,CAAC,CAAC;IACnD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAoB,IAAI,CAAC,CAAC;IAClE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAoB,IAAI,CAAC,CAAC;IACpE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAoB,IAAI,CAAC,CAAC;IAElE,MAAM,MAAM,GAAsB;QAChC,MAAM;QACN,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3D,CAAC;IACF,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACxD,MAAM,cAAc,GAAG,mBAAmB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,mBAAmB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,mBAAmB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC;IAEhC;mDAC+C;IAC/C,SAAS,OAAO,CAAC,KAAiB;QAChC,KAAK,EAAE,CAAC;QACR,OAAO,CAAC,UAAU,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,CACL,MAAC,IAAI,eACH,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,aAC9B,KAAC,UAAU,CAAC,KAAK,IAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YACjE,CAAC,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,GACxB,EACnB,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,YAC9B,CAAC,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,GAC5B,EACjB,IAAI,KAAK,IAAI,IAAI,CAChB,KAAC,KAAK,IAAC,MAAM,EAAC,mBAAmB,YAC9B,OAAO,CAAC,oBAAoB,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,GAChE,CACT,IACI,EAEP,MAAC,IAAI,IAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,QAAC,KAAK,EAAC,QAAQ,EAAC,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,aAC7E,KAAC,SAAS,IACR,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,gBACtC,CAAC,CAAC,oBAAoB,CAAC,sBAAsB,CAAC,iBAC9C,oBAAoB,EAChC,OAAO,EAAE;4BACP,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,EAAE;4BAC7E;gCACE,KAAK,EAAE,gBAAgB;gCACvB,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,8BAA8B,CAAC;6BAC9D;4BACD,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,EAAE;yBACtE,GACD,EACF,KAAC,KAAK,IACJ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EACjE,WAAW,EAAE,CAAC,CAAC,oBAAoB,CAAC,4BAA4B,CAAC,gBACrD,CAAC,CAAC,oBAAoB,CAAC,4BAA4B,CAAC,EAChE,UAAU,QACV,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,iBAChB,oBAAoB,GAChC,IACG,EAEP,KAAC,UAAU,IACT,MAAM,EAAE,cAAc,CAAC,KAAK,IAAI,cAAc,CAAC,KAAK,IAAI,cAAc,CAAC,KAAK,EAC5E,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,EAClC,MAAM,EAAC,yBAAyB,GAChC,EAED,CAAC,SAAS,IAAI,CACb,cAAK,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,YACrC,KAAC,KAAK,IAAC,MAAM,EAAC,uBAAuB,YAClC,CAAC,CAAC,oBAAoB,CAAC,sBAAsB,CAAC,GACzC,GACJ,CACP,EAED,cAAK,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,YACrC,KAAC,QAAQ,IACP,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EACnE,MAAM,EAAC,kBAAkB,EACzB,OAAO,EAAE,GAAG,EAAE;wBACZ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;oBACvB,CAAC,EACD,KAAK,EACH,KAAC,UAAU,IACT,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,EAC/C,MAAM,EAAC,wBAAwB,GAC/B,YAGH,CAAC,WAAW,EAAE,EAAE,CAAC,CAChB,cAAK,IAAI,EAAC,MAAM,iBAAa,kBAAkB,YAC5C,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAC/B,KAAC,aAAa,IAEZ,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,EACvC,QAAQ,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,EACxC,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,IALlC,UAAU,CAAC,EAAE,CAMlB,CACH,CAAC,GACE,CACP,GACQ,GACP,EAEL,IAAI,KAAK,IAAI,IAAI,CAChB,KAAC,WAAW,IACV,OAAO,EAAE,IAAI,CAAC,QAAQ,EACtB,OAAO,EAAE,IAAI,CAAC,QAAQ,EACtB,SAAS,EAAE,CAAC,CAAC,oBAAoB,CAAC,SAAS,CAAC,EAC5C,SAAS,EAAE,CAAC,CAAC,oBAAoB,CAAC,SAAS,CAAC,EAC5C,QAAQ,EAAE,CAAC,CAAC,oBAAoB,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,EACrE,MAAM,EAAC,mBAAmB,EAC1B,MAAM,EAAE,GAAG,EAAE,CACX,OAAO,CAAC;oBACN,MAAM,EAAE,IAAI,CAAC,WAAW,IAAI,SAAS;oBACrC,SAAS,EAAE,MAAM;oBACjB,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;iBACnC,CAAC,EAEJ,MAAM,EAAE,GAAG,EAAE,CACX,OAAO,CAAC;oBACN,MAAM,EAAE,IAAI,CAAC,WAAW,IAAI,SAAS;oBACrC,SAAS,EAAE,MAAM;oBACjB,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC;iBACtB,CAAC,GAEJ,CACH,EAED,KAAC,WAAW,IACV,IAAI,EAAE,QAAQ,KAAK,IAAI,EACvB,MAAM,QACN,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,EACvD,IAAI,EAAE,CAAC,CAAC,oBAAoB,CAAC,4BAA4B,EAAE;oBACzD,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE;iBAC7B,CAAC,EACF,YAAY,EAAE,CAAC,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EACvD,WAAW,EAAE,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,EAC3C,UAAU,EAAE,cAAc,CAAC,SAAS,EACpC,SAAS,EAAE,GAAG,EAAE;oBACd,IAAI,QAAQ,KAAK,IAAI;wBAAE,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;oBAC1D,WAAW,CAAC,IAAI,CAAC,CAAC;gBACpB,CAAC,EACD,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,iBACrB,4BAA4B,GACxC,EAEF,KAAC,WAAW,IACV,IAAI,EAAE,SAAS,KAAK,IAAI,EACxB,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,EACvD,IAAI,EAAE,CAAC,CAAC,oBAAoB,CAAC,4BAA4B,EAAE;oBACzD,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,EAAE;iBAC9B,CAAC,EACF,YAAY,EAAE,CAAC,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EACvD,WAAW,EAAE,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,EAC3C,UAAU,EAAE,cAAc,CAAC,SAAS,EACpC,SAAS,EAAE,GAAG,EAAE;oBACd,IAAI,SAAS,KAAK,IAAI;wBAAE,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;oBAC5D,YAAY,CAAC,IAAI,CAAC,CAAC;gBACrB,CAAC,EACD,QAAQ,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,iBACtB,4BAA4B,GACxC,EAEF,KAAC,sBAAsB,IACrB,UAAU,EAAE,QAAQ,EACpB,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAChC,UAAU,EAAE,cAAc,CAAC,SAAS,EACpC,QAAQ,EAAE,CAAC,WAAW,EAAE,EAAE;oBACxB,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;wBACtB,cAAc,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;oBACpE,CAAC;oBACD,WAAW,CAAC,IAAI,CAAC,CAAC;gBACpB,CAAC,GACD,IACG,CACR,CAAC;AACJ,CAAC;AAED,4DAA4D;AAC5D,SAAS,WAAW,CAAC,UAAsB;IACzC,OAAO,UAAU,CAAC,MAAM,KAAK,SAAS;QACpC,CAAC,CAAC,eAAe,EAAE;QACnB,CAAC,CAAC,aAAa,CAAC,oBAAoB,CAAC,0BAA0B,CAAC,CAAC;AACrE,CAAC;AAED;yDACyD;AACzD,SAAS,UAAU,CAAC,UAAsB;IACxC,OAAO,UAAU,CAAC,MAAM,KAAK,SAAS,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS;QACvE,CAAC,CAAC,eAAe,EAAE;QACnB,CAAC,CAAC,aAAa,CAAC,oBAAoB,CAAC,gCAAgC,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,UAAsB;IAC1C,MAAM,WAAW,GAAG,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC;IACvD,MAAM,aAAa,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC;IACxD,IAAI,WAAW,IAAI,aAAa,EAAE,CAAC;QACjC,OAAO,oBAAoB,CAAC,2BAA2B,CAAC;IAC1D,CAAC;IACD,IAAI,WAAW;QAAE,OAAO,oBAAoB,CAAC,+BAA+B,CAAC;IAC7E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,KAMtB;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;IACvC,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAC7B,MAAM,SAAS,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IAE3C,OAAO,CACL,eACE,IAAI,EAAC,UAAU,iBACF,kBAAkB,UAAU,CAAC,EAAE,EAAE,EAC9C,KAAK,EAAE;YACL,OAAO,EAAE,MAAM;YACf,QAAQ,EAAE,MAAM;YAChB,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,eAAe;YAC/B,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;YACjB,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC;YACxB,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC;YAC3B,YAAY,EAAE,aAAa,KAAK,CAAC,UAAU,EAAE;SAC9C,aAED,KAAC,UAAU,IACT,IAAI,EAAE,UAAU,CAAC,YAAY,IAAI,IAAI,EACrC,KAAK,EAAE,UAAU,CAAC,KAAK,EACvB,IAAI,EACF,KAAC,SAAS,IACR,IAAI,EAAE,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,SAAS,EACjD,MAAM,EAAE,qBAAqB,UAAU,CAAC,EAAE,EAAE,YAE3C,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GACjD,EAEd,OAAO,EACL,8BACE,KAAC,SAAS,IAAC,IAAI,EAAE,UAAU,CAAC,IAAI,GAAI,EACnC,OAAO,KAAK,IAAI,IAAI,CACnB,8BACG,KAAK,EACL,CAAC,CAAC,oBAAoB,CAAC,uBAAuB,CAAC,QAAI,OAAO,IAC1D,CACJ,EACA,KAAK,EACL,QAAQ,KAAK,IAAI;4BAChB,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,oBAAoB,CAAC;4BAC9C,CAAC,CAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,KAAK,QAAQ,EAAE,IACjE,GAEL,EACD,KAAK,CAAC,SAAS,IAAI,CAClB,KAAC,UAAU,IACT,MAAM,EAAE,sBAAsB,UAAU,CAAC,EAAE,EAAE,KACzC,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACxD,OAAO,EAAE;oBACP;wBACE,GAAG,EAAE,QAAQ;wBACb,IAAI,EAAE,WAAW,CAAC,UAAU,CAAC;wBAC7B,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;wBAChD,OAAO,EAAE,KAAK,CAAC,QAAQ;wBACvB,MAAM,EAAE,qBAAqB,UAAU,CAAC,EAAE,EAAE;qBAC7C;oBACD;wBACE,GAAG,EAAE,QAAQ;wBACb,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC;wBAC5B,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;wBAChD,OAAO,EAAE,KAAK,CAAC,QAAQ;wBACvB,MAAM,EAAE,qBAAqB,UAAU,CAAC,EAAE,EAAE;qBAC7C;oBACD;wBACE,GAAG,EAAE,QAAQ;wBACb,IAAI,EAAE,WAAW,CAAC,UAAU,CAAC;wBAC7B,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;wBAChD,OAAO,EAAE,KAAK,CAAC,QAAQ;wBACvB,MAAM,EAAE,IAAI;wBACZ,MAAM,EAAE,qBAAqB,UAAU,CAAC,EAAE,EAAE;qBAC7C;iBACF,GACD,CACH,IACG,CACP,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAAC,KAK/B;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,EAAE,YAAY,IAAI,EAAE,CAAC;IACrD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAEhE,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,IAAI,SAAS,KAAK,KAAK,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;QACnE,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAClC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,IAAI,GACR,KAAK,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,EAAE;QAC7B,CAAC,CAAC,aAAa,CAAC,oBAAoB,CAAC,6BAA6B,CAAC;QACnE,CAAC,CAAC,eAAe,EAAE,CAAC;IAExB,OAAO,CACL,KAAC,UAAU,IACT,IAAI,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,EAC/B,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,4BAA4B,CAAC,EAC3D,YAAY,EAAE,CAAC,CAAC,oBAAoB,CAAC,WAAW,CAAC,iBACrC,2BAA2B,EACvC,MAAM,EACJ,KAAC,WAAW,IACV,IAAI,EAAE,IAAI,EACV,IAAI,EAAC,SAAS,EACd,OAAO,EAAE,KAAK,CAAC,UAAU,EACzB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EACxE,MAAM,EAAC,2BAA2B,oBACnB,MAAM,2BACC,8DAAyD,YAE9E,CAAC,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,GAChC,YAGhB,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,aAC9B,KAAC,UAAU,CAAC,IAAI,cAAE,CAAC,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,GAAmB,EAC/E,KAAC,KAAK,IACJ,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EACjD,WAAW,EAAE,CAAC,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,gBACjD,CAAC,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,iBAC1C,0BAA0B,GACtC,IACG,GACI,CACd,CAAC;AACJ,CAAC"}
|
|
@@ -21,6 +21,13 @@ export interface InviteAcceptPageProps {
|
|
|
21
21
|
}) => ReactNode;
|
|
22
22
|
/** Wrong-account CTA (sign out / switch). Omitted → CTA hidden. */
|
|
23
23
|
readonly onSwitchAccount?: () => void;
|
|
24
|
+
/**
|
|
25
|
+
* Leave the invitation page — the door out of a terminal state (expired,
|
|
26
|
+
* revoked, already used), where there is nothing left to do here. The pair
|
|
27
|
+
* owns no router, so omitting it draws no button and the page states the
|
|
28
|
+
* next step in words instead of offering one that goes nowhere.
|
|
29
|
+
*/
|
|
30
|
+
readonly onExit?: () => void;
|
|
24
31
|
readonly onAccepted?: (member: Member) => void;
|
|
25
32
|
readonly onDeclined?: () => void;
|
|
26
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InviteAcceptPage.d.ts","sourceRoot":"","sources":["../../src/default/InviteAcceptPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"InviteAcceptPage.d.ts","sourceRoot":"","sources":["../../src/default/InviteAcceptPage.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAkBrD,OAAO,KAAK,EAAqB,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIjE,MAAM,WAAW,qBAAqB;IACpC,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;0EACsE;IACtE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,uEAAuE;IACvE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE;QAChC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;KACrC,KAAK,SAAS,CAAC;IAChB,4EAA4E;IAC5E,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,SAAS,CAAC;IACzE,mEAAmE;IACnE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CAClC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CA+B3E"}
|