@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,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This pair's contribution to the scripted-fullstack nav contract
|
|
3
|
+
* (`@stapel/core`'s `NavEntry`/`PackageNavManifest`). `scripts/gen-nav-
|
|
4
|
+
* manifest.mjs` reads `navEntries` below, stamps `package`/`version` from THIS
|
|
5
|
+
* package's own `package.json` (never hand-copied here — a version bump must
|
|
6
|
+
* not require touching this file), and emits
|
|
7
|
+
* `packages/workspaces-react/nav-manifest.json` plus this package's slice of
|
|
8
|
+
* the root aggregate.
|
|
9
|
+
*
|
|
10
|
+
* ## The six doors
|
|
11
|
+
*
|
|
12
|
+
* - `workspaces.list` — the workspace roster (`<WorkspacesPage/>`), under the
|
|
13
|
+
* container-synthesised `account.root` submenu, next to privacy and
|
|
14
|
+
* billing. Everything it shows is the caller's own.
|
|
15
|
+
* - `workspaces.settings` / `.members` / `.invitations` / `.audit` — the four
|
|
16
|
+
* workspace-scoped admin screens, siblings of the roster under the same
|
|
17
|
+
* account section, on paths RELATIVE to it (`workspaces/members`, …).
|
|
18
|
+
* - `workspaces.invite` — the public `/invite/:token` route
|
|
19
|
+
* (`<InviteAcceptPage/>`). `surface: "public"` and `requiresAuth: false`
|
|
20
|
+
* because the invitee usually has no account here at all — that is the
|
|
21
|
+
* entire reason `claim` exists — and the token in the URL is the bearer
|
|
22
|
+
* secret. `menuVisibleDefault: false`: it is an address a letter sends
|
|
23
|
+
* somebody to, never a menu item.
|
|
24
|
+
*
|
|
25
|
+
* ## Where the four scoped screens get their workspace (architecture verdict)
|
|
26
|
+
*
|
|
27
|
+
* They do NOT get it from the route. The active workspace is RUNTIME state —
|
|
28
|
+
* the same state the container writes when a person switches workspaces
|
|
29
|
+
* (`WorkspaceSelection.switchTo`) — not a path param of a settings URL, so
|
|
30
|
+
* these entries declare no `:workspaceId` segment and the screens read the
|
|
31
|
+
* selection themselves (`useOptionalWorkspaceSelection`, see
|
|
32
|
+
* `src/default/ActiveWorkspace.tsx`). A host that mounts the same components
|
|
33
|
+
* outside the shell keeps passing `workspaceId` explicitly; the prop stayed,
|
|
34
|
+
* it only became optional.
|
|
35
|
+
*
|
|
36
|
+
* The failure mode that made this a question at all — four doors opening on a
|
|
37
|
+
* screen with no workspace — is answered by the screens rather than by the
|
|
38
|
+
* contract: with no active workspace they render a designed "choose a
|
|
39
|
+
* workspace" state (and "you are not in a workspace yet" for a person who
|
|
40
|
+
* belongs to none), never a blank page and never a crash from a selection
|
|
41
|
+
* provider a shell forgot to wire.
|
|
42
|
+
*/
|
|
43
|
+
import type { NavEntry } from "@stapel/core";
|
|
44
|
+
|
|
45
|
+
export const navEntries: readonly NavEntry[] = [
|
|
46
|
+
{
|
|
47
|
+
id: "workspaces.list",
|
|
48
|
+
labelKey: "workspaces.nav.workspaces",
|
|
49
|
+
icon: "AppstoreOutlined",
|
|
50
|
+
route: { path: "workspaces" },
|
|
51
|
+
component: { export: "WorkspacesPage", subpath: "default" },
|
|
52
|
+
placement: { level: "submenu", parentId: "account.root" },
|
|
53
|
+
menuVisibleDefault: true,
|
|
54
|
+
requiresAuth: true,
|
|
55
|
+
surface: "member",
|
|
56
|
+
order: 10,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "workspaces.settings",
|
|
60
|
+
labelKey: "workspaces.nav.settings",
|
|
61
|
+
icon: "ProfileOutlined",
|
|
62
|
+
route: { path: "workspaces/settings" },
|
|
63
|
+
component: { export: "WorkspaceSettings", subpath: "default" },
|
|
64
|
+
placement: { level: "submenu", parentId: "account.root" },
|
|
65
|
+
menuVisibleDefault: true,
|
|
66
|
+
requiresAuth: true,
|
|
67
|
+
surface: "member",
|
|
68
|
+
order: 11,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: "workspaces.members",
|
|
72
|
+
labelKey: "workspaces.nav.members",
|
|
73
|
+
icon: "UserOutlined",
|
|
74
|
+
route: { path: "workspaces/members" },
|
|
75
|
+
component: { export: "MembersManager", subpath: "default" },
|
|
76
|
+
placement: { level: "submenu", parentId: "account.root" },
|
|
77
|
+
menuVisibleDefault: true,
|
|
78
|
+
requiresAuth: true,
|
|
79
|
+
surface: "member",
|
|
80
|
+
order: 12,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: "workspaces.invitations",
|
|
84
|
+
labelKey: "workspaces.nav.invitations",
|
|
85
|
+
icon: "MessageOutlined",
|
|
86
|
+
route: { path: "workspaces/invitations" },
|
|
87
|
+
component: { export: "InvitationsPane", subpath: "default" },
|
|
88
|
+
placement: { level: "submenu", parentId: "account.root" },
|
|
89
|
+
menuVisibleDefault: true,
|
|
90
|
+
requiresAuth: true,
|
|
91
|
+
surface: "member",
|
|
92
|
+
order: 13,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "workspaces.audit",
|
|
96
|
+
labelKey: "workspaces.nav.audit",
|
|
97
|
+
icon: "AuditOutlined",
|
|
98
|
+
route: { path: "workspaces/audit" },
|
|
99
|
+
component: { export: "AuditTrailPane", subpath: "default" },
|
|
100
|
+
placement: { level: "submenu", parentId: "account.root" },
|
|
101
|
+
menuVisibleDefault: true,
|
|
102
|
+
requiresAuth: true,
|
|
103
|
+
surface: "member",
|
|
104
|
+
order: 14,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: "workspaces.invite",
|
|
108
|
+
labelKey: "workspaces.nav.invite",
|
|
109
|
+
icon: "MessageOutlined",
|
|
110
|
+
route: { path: "/invite/:token" },
|
|
111
|
+
component: { export: "InviteAcceptPage", subpath: "default" },
|
|
112
|
+
placement: { level: "top" },
|
|
113
|
+
menuVisibleDefault: false,
|
|
114
|
+
// A session is NOT needed: the whole point of the claim path is that the
|
|
115
|
+
// invitee has no account yet, and decline went `AllowAny` in 0.27.0.
|
|
116
|
+
requiresAuth: false,
|
|
117
|
+
surface: "public",
|
|
118
|
+
order: 0,
|
|
119
|
+
},
|
|
120
|
+
];
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { CSSProperties, ReactElement } from "react";
|
|
2
|
-
import type { FlowErrorDisplay } from "@stapel/core";
|
|
3
|
-
export declare function ErrorAlert(props: {
|
|
4
|
-
error: FlowErrorDisplay | undefined;
|
|
5
|
-
style?: CSSProperties | undefined;
|
|
6
|
-
testId?: string | undefined;
|
|
7
|
-
}): ReactElement | null;
|
|
8
|
-
//# sourceMappingURL=ErrorAlert.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorAlert.d.ts","sourceRoot":"","sources":["../../src/default/ErrorAlert.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,KAAK,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACpC,KAAK,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,YAAY,GAAG,IAAI,CAqBtB"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* The one error surface this pair's default skins render, so the split copy
|
|
4
|
-
* core produces reaches a screen the same way everywhere.
|
|
5
|
-
*
|
|
6
|
-
* Core's `describeFlowError` splits a failure into the sentence a person
|
|
7
|
-
* reads and the technical detail a support agent quotes (owner report
|
|
8
|
-
* 2026-08-09: the status used to be spliced into the sentence, which ended
|
|
9
|
-
* in a bare `" (500)"` — and a product does not read a protocol number out to
|
|
10
|
-
* a person). The split is only worth anything if a
|
|
11
|
-
* skin actually renders both halves at their own weights: `message` at
|
|
12
|
-
* normal weight, `detail` muted and small, where an eye skips it and a
|
|
13
|
-
* support agent finds it.
|
|
14
|
-
*
|
|
15
|
-
* `undefined` in — including a `detail` that core left `undefined` because
|
|
16
|
-
* there was nothing worth quoting — renders nothing rather than an empty
|
|
17
|
-
* muted line.
|
|
18
|
-
*/
|
|
19
|
-
import { Alert, Typography } from "antd";
|
|
20
|
-
export function ErrorAlert(props) {
|
|
21
|
-
const { error } = props;
|
|
22
|
-
if (!error)
|
|
23
|
-
return null;
|
|
24
|
-
return (_jsx(Alert, { type: "error", showIcon: true, ...(props.style ? { style: props.style } : {}), ...(props.testId ? { "data-testid": props.testId } : {}), message: error.message, ...(error.detail
|
|
25
|
-
? {
|
|
26
|
-
description: (_jsx(Typography.Text, { type: "secondary", style: { fontSize: 12 }, children: error.detail })),
|
|
27
|
-
}
|
|
28
|
-
: {}) }));
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=ErrorAlert.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorAlert.js","sourceRoot":"","sources":["../../src/default/ErrorAlert.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAIzC,MAAM,UAAU,UAAU,CAAC,KAI1B;IACC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACxB,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,CACL,KAAC,KAAK,IACJ,IAAI,EAAC,OAAO,EACZ,QAAQ,WACJ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAC3C,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACzD,OAAO,EAAE,KAAK,CAAC,OAAO,KAClB,CAAC,KAAK,CAAC,MAAM;YACf,CAAC,CAAC;gBACE,WAAW,EAAE,CACX,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,EAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,YACtD,KAAK,CAAC,MAAM,GACG,CACnB;aACF;YACH,CAAC,CAAC,EAAE,CAAC,GACP,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The one error surface this pair's default skins render, so the split copy
|
|
3
|
-
* core produces reaches a screen the same way everywhere.
|
|
4
|
-
*
|
|
5
|
-
* Core's `describeFlowError` splits a failure into the sentence a person
|
|
6
|
-
* reads and the technical detail a support agent quotes (owner report
|
|
7
|
-
* 2026-08-09: the status used to be spliced into the sentence, which ended
|
|
8
|
-
* in a bare `" (500)"` — and a product does not read a protocol number out to
|
|
9
|
-
* a person). The split is only worth anything if a
|
|
10
|
-
* skin actually renders both halves at their own weights: `message` at
|
|
11
|
-
* normal weight, `detail` muted and small, where an eye skips it and a
|
|
12
|
-
* support agent finds it.
|
|
13
|
-
*
|
|
14
|
-
* `undefined` in — including a `detail` that core left `undefined` because
|
|
15
|
-
* there was nothing worth quoting — renders nothing rather than an empty
|
|
16
|
-
* muted line.
|
|
17
|
-
*/
|
|
18
|
-
import { Alert, Typography } from "antd";
|
|
19
|
-
import type { CSSProperties, ReactElement } from "react";
|
|
20
|
-
import type { FlowErrorDisplay } from "@stapel/core";
|
|
21
|
-
|
|
22
|
-
export function ErrorAlert(props: {
|
|
23
|
-
error: FlowErrorDisplay | undefined;
|
|
24
|
-
style?: CSSProperties | undefined;
|
|
25
|
-
testId?: string | undefined;
|
|
26
|
-
}): ReactElement | null {
|
|
27
|
-
const { error } = props;
|
|
28
|
-
if (!error) return null;
|
|
29
|
-
return (
|
|
30
|
-
<Alert
|
|
31
|
-
type="error"
|
|
32
|
-
showIcon
|
|
33
|
-
{...(props.style ? { style: props.style } : {})}
|
|
34
|
-
{...(props.testId ? { "data-testid": props.testId } : {})}
|
|
35
|
-
message={error.message}
|
|
36
|
-
{...(error.detail
|
|
37
|
-
? {
|
|
38
|
-
description: (
|
|
39
|
-
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
|
|
40
|
-
{error.detail}
|
|
41
|
-
</Typography.Text>
|
|
42
|
-
),
|
|
43
|
-
}
|
|
44
|
-
: {})}
|
|
45
|
-
/>
|
|
46
|
-
);
|
|
47
|
-
}
|