@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
package/dist/model/queryKeys.js
CHANGED
|
@@ -13,6 +13,12 @@ export const workspacesQueryKeys = {
|
|
|
13
13
|
// The bare 3-tuple is a valid prefix of membersPage's 4-tuple, so
|
|
14
14
|
// invalidating `members(workspaceId)` (mutations.ts) drops every page.
|
|
15
15
|
members: (workspaceId) => [ROOT, "members", workspaceId],
|
|
16
|
+
/** The workspace's membership history (stapel-workspaces 0.24). Its own
|
|
17
|
+
* root, not a slice of `members`: history is append-only and a member
|
|
18
|
+
* mutation invalidates the ROSTER — the history it also appended to is
|
|
19
|
+
* invalidated deliberately, by naming this key, not as a side effect. */
|
|
20
|
+
audit: (workspaceId) => [ROOT, "audit", workspaceId],
|
|
21
|
+
auditPage: (workspaceId, params) => [ROOT, "audit", workspaceId, params],
|
|
16
22
|
// EVERY workspace's roster, not one. Not a read key — nothing fetches it —
|
|
17
23
|
// but the invalidation scope of a write that moves a name the whole fleet
|
|
18
24
|
// shares: `MemberResponse.display_name` is a live lookup in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../src/model/queryKeys.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../src/model/queryKeys.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,MAAM,IAAI,GAAG,YAAqB,CAAC;AAEnC,MAAM,CAAC,MAAM,mBAAmB,GAmC5B;IACF,GAAG,EAAE,CAAC,IAAI,CAAC;IACX,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC;IACtD,kEAAkE;IAClE,uEAAuE;IACvE,OAAO,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC;IACxD;;;6EAGyE;IACzE,KAAK,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC;IACpD,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC;IACxE,2EAA2E;IAC3E,0EAA0E;IAC1E,4DAA4D;IAC5D,wEAAwE;IACxE,sEAAsE;IACtE,mCAAmC;IACnC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC;IACnC,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC;IAC5E,0EAA0E;IAC1E,qEAAqE;IACrE,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,EAAE,WAAW,CAAC;IAChE,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC;QACxC,IAAI;QACJ,aAAa;QACb,WAAW;QACX,MAAM;KACP;IACD,2EAA2E;IAC3E,uEAAuE;IACvE,yDAAyD;IACzD,mBAAmB,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QAC7C,IAAI;QACJ,aAAa;QACb,WAAW;QACX,UAAU;QACV,OAAO;KACR;IACD,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC;IAClC,0EAA0E;IAC1E,yEAAyE;IACzE,2EAA2E;IAC3E,gBAAgB;IAChB,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,CAAC;CAClE,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactElement, ReactNode } from "react";
|
|
2
|
-
import type { Repository } from "@stapel/core";
|
|
2
|
+
import type { LoadState, Repository } from "@stapel/core";
|
|
3
3
|
import type { Workspace } from "../api/types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Which workspace am I in — the resolution the whole fleet was inventing
|
|
@@ -74,11 +74,26 @@ export interface WorkspaceSelectionUrlBinding {
|
|
|
74
74
|
}
|
|
75
75
|
/** What {@link useWorkspaceSelection} hands back. */
|
|
76
76
|
export interface WorkspaceSelection {
|
|
77
|
-
/** The caller's workspaces (empty before load, and for a guest). */
|
|
78
|
-
readonly workspaces: readonly Workspace[];
|
|
79
77
|
/**
|
|
80
|
-
* The
|
|
81
|
-
*
|
|
78
|
+
* The workspace list, as a state a host cannot flatten: `loading` / `ready`
|
|
79
|
+
* with the rows / `failed` with the error. Render it through core's
|
|
80
|
+
* `matchList`.
|
|
81
|
+
*
|
|
82
|
+
* THIS FIELD IS THE FIX FOR THE 2026-08-09 INCIDENT. What used to be here
|
|
83
|
+
* was `workspaces: readonly Workspace[]` beside `loading: boolean`, and NO
|
|
84
|
+
* error field at all — so when the list endpoint answered 404 (a route
|
|
85
|
+
* mounted one segment too deep), a host saw `loading: false`, `workspaces:
|
|
86
|
+
* []`, `current: null`, and had literally no way to tell that apart from a
|
|
87
|
+
* person who belongs to no workspace. Every screen in the product said "you
|
|
88
|
+
* have no workspaces" for hours. The distinction was not merely easy to
|
|
89
|
+
* miss; it was ABSENT from the type.
|
|
90
|
+
*/
|
|
91
|
+
readonly state: LoadState<readonly Workspace[]>;
|
|
92
|
+
/**
|
|
93
|
+
* The resolved workspace, once the list is `ready` and the chain has picked
|
|
94
|
+
* one. `null` while loading, when the load FAILED, and for a person who
|
|
95
|
+
* belongs to none — which is exactly why a screen must branch on
|
|
96
|
+
* {@link state} and not on this being null.
|
|
82
97
|
*
|
|
83
98
|
* Downstream fetching must gate on THIS, never on a raw id: an id that has
|
|
84
99
|
* not been checked against the fetched list is exactly how a client ends up
|
|
@@ -94,8 +109,6 @@ export interface WorkspaceSelection {
|
|
|
94
109
|
* this. The person has already been landed somewhere sane.
|
|
95
110
|
*/
|
|
96
111
|
readonly urlWorkspaceInvalid: boolean;
|
|
97
|
-
/** The workspace list is still loading. */
|
|
98
|
-
readonly loading: boolean;
|
|
99
112
|
/**
|
|
100
113
|
* An EXPLICIT choice by the person — the only entry point that persists.
|
|
101
114
|
* Writes the URL (push), local storage, and the backend preference.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../src/model/selection.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAW,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../src/model/selection.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAW,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAS9D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;6EAE6E;AAC7E,MAAM,MAAM,wBAAwB,GAChC,KAAK,GACL,OAAO,GACP,YAAY,GACZ,kBAAkB,GAClB,UAAU,GACV,YAAY,CAAC;AAEjB;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;;;;;;;;;OASG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAC9B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;QAAE,MAAM,EAAE,QAAQ,GAAG,aAAa,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,KACpE,IAAI,CAAC;CACX;AAED,qDAAqD;AACrD,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IAChD;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IACnC,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACjD;;;;;OAKG;IACH,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC;;;;OAIG;IACH,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,kCAAkC;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAuBD,oDAAoD;AACpD,MAAM,WAAW,+BACf,SAAQ,4BAA4B;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CACjD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,+BAA+B,GACrC,YAAY,CA8Nd;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,kBAAkB,CAQ1D"}
|
package/dist/model/selection.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
|
|
3
|
-
import { createRepository } from "@stapel/core";
|
|
3
|
+
import { bothLoaded, createRepository, loadLoading, loadReady, loadStateFromQuery, mapLoad, } from "@stapel/core";
|
|
4
4
|
import { useWorkspaces } from "./queries.js";
|
|
5
5
|
import { useSetPreferredWorkspace } from "./mutations.js";
|
|
6
|
+
/** Stable identity for the no-rows case — a fresh `[]` per render would
|
|
7
|
+
* re-run every consumer effect that depends on the memoised bag (#251). */
|
|
8
|
+
const EMPTY_WORKSPACES = [];
|
|
6
9
|
const SelectionContext = createContext(null);
|
|
7
10
|
/** The repository namespace and key holding the local-storage layer. */
|
|
8
11
|
const REPO_NAMESPACE = "workspaces";
|
|
@@ -84,14 +87,30 @@ export function WorkspaceSelectionProvider(props) {
|
|
|
84
87
|
cancelled = true;
|
|
85
88
|
};
|
|
86
89
|
}, [repo]);
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
// The list read and the local-storage read must BOTH land before the chain
|
|
91
|
+
// can answer, and a failure of either must not read as "still loading" —
|
|
92
|
+
// `bothLoaded` is exactly that rule, so it is not restated here.
|
|
93
|
+
// Memoised on the query's OWN fields, never on the query object: TanStack
|
|
94
|
+
// returns a new result object every render, so `[query]` here would hand
|
|
95
|
+
// every consumer a new `state` on every render — the #251 loop the bag
|
|
96
|
+
// memoisation below exists to prevent, reintroduced one level up.
|
|
97
|
+
const { status: queryStatus, data: queryData, error: queryError } = query;
|
|
98
|
+
const state = useMemo(() => mapLoad(bothLoaded(mapLoad(loadStateFromQuery({
|
|
99
|
+
status: queryStatus,
|
|
100
|
+
data: queryData,
|
|
101
|
+
error: queryError,
|
|
102
|
+
}), (list) => list.workspaces ?? []), localRead ? loadReady(null) : loadLoading()), ([rows]) => rows), [queryStatus, queryData, queryError, localRead]);
|
|
103
|
+
// The resolution chain below is a COMPUTATION over rows, not a rendering of
|
|
104
|
+
// them, so it reads the rows flat — and it runs only when the state is
|
|
105
|
+
// `ready`, which is what keeps a failed load from resolving to anything.
|
|
106
|
+
const workspaces = state.status === "ready" ? state.data : EMPTY_WORKSPACES;
|
|
107
|
+
const resolvable = state.status === "ready";
|
|
89
108
|
const memberOf = useCallback((id) => id ? (workspaces.find((w) => w.id === id) ?? null) : null, [workspaces]);
|
|
90
109
|
// The chain. Runs against the FETCHED list only — never against an
|
|
91
110
|
// unresolved one, or a raw stored id would be briefly authoritative and the
|
|
92
111
|
// app would fetch a workspace it has not verified the person can open.
|
|
93
112
|
const resolved = useMemo(() => {
|
|
94
|
-
if (
|
|
113
|
+
if (!resolvable || workspaces.length === 0) {
|
|
95
114
|
return { workspace: null, source: null };
|
|
96
115
|
}
|
|
97
116
|
const explicit = memberOf(chosenId);
|
|
@@ -115,13 +134,13 @@ export function WorkspaceSelectionProvider(props) {
|
|
|
115
134
|
// Last resort only — see this module's header for why it is last and why
|
|
116
135
|
// it is still here.
|
|
117
136
|
return { workspace: workspaces[0] ?? null, source: "positional" };
|
|
118
|
-
}, [
|
|
137
|
+
}, [resolvable, workspaces, memberOf, chosenId, urlWorkspaceId, localId, query.data]);
|
|
119
138
|
// The URL named something the person cannot open. Deliberately NOT an
|
|
120
139
|
// error state that blanks the screen, and deliberately NOT a silent
|
|
121
140
|
// substitution: they clicked a link expecting workspace X, and quietly
|
|
122
141
|
// showing workspace Y's data is the same misattribution class as #239.
|
|
123
142
|
// They land through the rest of the chain, and this flag drives the notice.
|
|
124
|
-
const urlWorkspaceInvalid =
|
|
143
|
+
const urlWorkspaceInvalid = resolvable &&
|
|
125
144
|
workspaces.length > 0 &&
|
|
126
145
|
chosenId === null &&
|
|
127
146
|
!!urlWorkspaceId &&
|
|
@@ -145,13 +164,16 @@ export function WorkspaceSelectionProvider(props) {
|
|
|
145
164
|
// later-corrected backend preference or instance default; deleting it just
|
|
146
165
|
// stops the next boot retrying a dead id.
|
|
147
166
|
useEffect(() => {
|
|
148
|
-
|
|
167
|
+
// Only a SUCCESSFUL load proves a stored id is dead. Deleting it because
|
|
168
|
+
// the request failed would punish an outage by forgetting the person's
|
|
169
|
+
// workspace on every affected boot.
|
|
170
|
+
if (!resolvable || !repo || localId === null)
|
|
149
171
|
return;
|
|
150
172
|
if (memberOf(localId))
|
|
151
173
|
return;
|
|
152
174
|
setLocalId(null);
|
|
153
175
|
void repo.del(REPO_KEY).catch(() => undefined);
|
|
154
|
-
}, [
|
|
176
|
+
}, [resolvable, repo, localId, memberOf]);
|
|
155
177
|
/**
|
|
156
178
|
* The only path that persists anything, and that is the whole write policy:
|
|
157
179
|
* a URL is per-tab CONTEXT, a picker click is a CHOICE.
|
|
@@ -193,19 +215,17 @@ export function WorkspaceSelectionProvider(props) {
|
|
|
193
215
|
// sets state, that is an unbounded render loop whose only symptom is a
|
|
194
216
|
// spinner that never resolves, with nothing in the console.
|
|
195
217
|
const value = useMemo(() => ({
|
|
196
|
-
|
|
218
|
+
state,
|
|
197
219
|
current: resolved.workspace,
|
|
198
220
|
source: resolved.source,
|
|
199
221
|
urlWorkspaceInvalid,
|
|
200
|
-
loading,
|
|
201
222
|
switchTo,
|
|
202
223
|
refetch,
|
|
203
224
|
}), [
|
|
204
|
-
|
|
225
|
+
state,
|
|
205
226
|
resolved.workspace,
|
|
206
227
|
resolved.source,
|
|
207
228
|
urlWorkspaceInvalid,
|
|
208
|
-
loading,
|
|
209
229
|
switchTo,
|
|
210
230
|
refetch,
|
|
211
231
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/model/selection.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,aAAa,EACb,WAAW,EACX,UAAU,EACV,SAAS,EACT,OAAO,EACP,MAAM,EACN,QAAQ,GACT,MAAM,OAAO,CAAC;AAEf,OAAO,
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/model/selection.tsx"],"names":[],"mappings":"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"}
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# @stapel/workspaces-react 0.
|
|
1
|
+
# @stapel/workspaces-react 0.15.0
|
|
2
2
|
|
|
3
|
-
Headless React flow pair for stapel-workspaces (contract >=0.
|
|
3
|
+
Headless React flow pair for stapel-workspaces (contract >=0.24 <0.25) — business + state, zero visual opinion.
|
|
4
4
|
Built on @stapel/core: typed client + StapelApiError envelope, auth token refresh,
|
|
5
5
|
verification-403 interception, i18n engine, analytics facade, TanStack Query layer.
|
|
6
6
|
|
|
@@ -24,6 +24,7 @@ api (typed client) · model (hooks, session) · flows (machines) · headless ·
|
|
|
24
24
|
## Operations (typed; use the named op, never a path string)
|
|
25
25
|
Request/response schema names are in manifest.json + the generated types.
|
|
26
26
|
Paths are relative to `/workspaces/api/v1/`.
|
|
27
|
+
- workspaces_api_v1_audit_list: GET /{workspace_id}/audit
|
|
27
28
|
- workspaces_api_v1_create: POST /
|
|
28
29
|
- workspaces_api_v1_destroy: DELETE /{workspace_id}
|
|
29
30
|
- workspaces_api_v1_instance_retrieve: GET /instance
|
|
@@ -53,6 +54,7 @@ Paths are relative to `/workspaces/api/v1/`.
|
|
|
53
54
|
|
|
54
55
|
## Query hooks (server state; keys come only from the key factory)
|
|
55
56
|
- useAcceptInvitation (mutation) → acceptInvitation
|
|
57
|
+
- useAudit (query) → listAudit
|
|
56
58
|
- useClaimInvitation (mutation) → claimInvitation
|
|
57
59
|
- useClearPreferredWorkspace (mutation) → clearPreferredWorkspace
|
|
58
60
|
- useCreateWorkspace (mutation) → createWorkspace
|
|
@@ -78,7 +80,7 @@ Paths are relative to `/workspaces/api/v1/`.
|
|
|
78
80
|
- useWorkspaces (query) → listWorkspaces
|
|
79
81
|
|
|
80
82
|
## Errors (render t(code, params); UX from remediation)
|
|
81
|
-
|
|
83
|
+
69 keys (full catalog: manifest.json §errors). By remediation: fix_input 33 · retry 12 · contact_support 9 · wait_and_retry 8 · verify 5 · reauthenticate 2.
|
|
82
84
|
Param-bearing keys (interpolation slots matter):
|
|
83
85
|
- error.400.field.blank [400] → fix_input {field}
|
|
84
86
|
- error.400.field.does_not_exist [400] → fix_input {field}
|
|
@@ -95,6 +97,7 @@ Param-bearing keys (interpolation slots matter):
|
|
|
95
97
|
- error.403.membership_suspended [403] → fix_input {reason}
|
|
96
98
|
- error.403.missing_capability [403] → contact_support {capability}
|
|
97
99
|
- error.403.role_exceeds_inviter_rank [403] → fix_input {role}
|
|
100
|
+
- error.429.invitation_resend_cooldown [429] → wait_and_retry {retry_after}
|
|
98
101
|
- error.429.rate_limit [429] → wait_and_retry {retry_after_minutes}
|
|
99
102
|
|
|
100
103
|
## Analytics events (typed; defineEvent → events.json, drift-gated)
|
package/manifest.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$generated": "by scripts/gen-manifest.mjs — do not edit; drift-gated (pnpm gen:manifest:check)",
|
|
3
3
|
"package": "@stapel/workspaces-react",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.15.0",
|
|
5
5
|
"backend": {
|
|
6
6
|
"module": "stapel-workspaces",
|
|
7
|
-
"contract": ">=0.
|
|
7
|
+
"contract": ">=0.24 <0.25"
|
|
8
8
|
},
|
|
9
9
|
"layers": [
|
|
10
10
|
"api",
|
|
@@ -18,6 +18,13 @@
|
|
|
18
18
|
"createInviteAcceptFlow"
|
|
19
19
|
],
|
|
20
20
|
"operations": {
|
|
21
|
+
"workspaces_api_v1_audit_list": {
|
|
22
|
+
"method": "GET",
|
|
23
|
+
"path": "/workspaces/api/v1/{workspace_id}/audit",
|
|
24
|
+
"tag": "Members",
|
|
25
|
+
"request": null,
|
|
26
|
+
"response": "PaginatedAuditEventResponseList"
|
|
27
|
+
},
|
|
21
28
|
"workspaces_api_v1_create": {
|
|
22
29
|
"method": "POST",
|
|
23
30
|
"path": "/workspaces/api/v1/",
|
|
@@ -217,6 +224,16 @@
|
|
|
217
224
|
]
|
|
218
225
|
]
|
|
219
226
|
},
|
|
227
|
+
"useAudit": {
|
|
228
|
+
"kind": "query",
|
|
229
|
+
"operation": "listAudit",
|
|
230
|
+
"queryKey": [
|
|
231
|
+
"workspaces",
|
|
232
|
+
"audit",
|
|
233
|
+
"{workspaceId}",
|
|
234
|
+
"{params}"
|
|
235
|
+
]
|
|
236
|
+
},
|
|
220
237
|
"useClaimInvitation": {
|
|
221
238
|
"kind": "mutation",
|
|
222
239
|
"operation": "claimInvitation"
|
|
@@ -725,6 +742,11 @@
|
|
|
725
742
|
"params": [],
|
|
726
743
|
"remediation": "verify"
|
|
727
744
|
},
|
|
745
|
+
"error.403.workspace_creation_closed": {
|
|
746
|
+
"status": 403,
|
|
747
|
+
"params": [],
|
|
748
|
+
"remediation": "contact_support"
|
|
749
|
+
},
|
|
728
750
|
"error.404.ad_not_found": {
|
|
729
751
|
"status": 404,
|
|
730
752
|
"params": [],
|
|
@@ -810,6 +832,13 @@
|
|
|
810
832
|
"params": [],
|
|
811
833
|
"remediation": "wait_and_retry"
|
|
812
834
|
},
|
|
835
|
+
"error.429.invitation_resend_cooldown": {
|
|
836
|
+
"status": 429,
|
|
837
|
+
"params": [
|
|
838
|
+
"retry_after"
|
|
839
|
+
],
|
|
840
|
+
"remediation": "wait_and_retry"
|
|
841
|
+
},
|
|
813
842
|
"error.429.rate_limit": {
|
|
814
843
|
"status": 429,
|
|
815
844
|
"params": [
|
|
@@ -893,7 +922,7 @@
|
|
|
893
922
|
{
|
|
894
923
|
"id": "workspaces.list",
|
|
895
924
|
"title": "Workspace list",
|
|
896
|
-
"description": "The headless WorkspaceList wraps the read of the caller's workspaces plus an owner-seeded create,
|
|
925
|
+
"description": "The headless WorkspaceList wraps the read of the caller's workspaces plus an owner-seeded create. The read arrives as a LoadState the skin renders through matchList, so 'no workspaces yet' and 'we could not load them' stay two different screens. Bring your own UI — the component is renderless.",
|
|
897
926
|
"component": "WorkspaceList",
|
|
898
927
|
"tokens": [
|
|
899
928
|
"card-bg",
|
|
@@ -991,6 +1020,7 @@
|
|
|
991
1020
|
"error.403.role_exceeds_inviter_rank",
|
|
992
1021
|
"error.403.verification_enrollment_required",
|
|
993
1022
|
"error.403.verification_required",
|
|
1023
|
+
"error.403.workspace_creation_closed",
|
|
994
1024
|
"error.404.ad_not_found",
|
|
995
1025
|
"error.404.invitation_not_found",
|
|
996
1026
|
"error.404.member_not_found",
|
|
@@ -1008,6 +1038,7 @@
|
|
|
1008
1038
|
"error.422.unprocessable_entity",
|
|
1009
1039
|
"error.423.locked",
|
|
1010
1040
|
"error.423.verification_locked",
|
|
1041
|
+
"error.429.invitation_resend_cooldown",
|
|
1011
1042
|
"error.429.rate_limit",
|
|
1012
1043
|
"error.429.too_many_requests",
|
|
1013
1044
|
"error.500.internal",
|
|
@@ -1045,13 +1076,16 @@
|
|
|
1045
1076
|
"workspaces.list.create",
|
|
1046
1077
|
"workspaces.list.creating",
|
|
1047
1078
|
"workspaces.list.empty",
|
|
1079
|
+
"workspaces.list.load_failed",
|
|
1048
1080
|
"workspaces.list.loading",
|
|
1081
|
+
"workspaces.members.empty",
|
|
1049
1082
|
"workspaces.members.invite",
|
|
1050
1083
|
"workspaces.members.invite_dialog.emails_label",
|
|
1051
1084
|
"workspaces.members.invite_dialog.emails_placeholder",
|
|
1052
1085
|
"workspaces.members.invite_dialog.role_label",
|
|
1053
1086
|
"workspaces.members.invite_dialog.title",
|
|
1054
1087
|
"workspaces.members.inviting",
|
|
1088
|
+
"workspaces.members.load_failed",
|
|
1055
1089
|
"workspaces.members.loading",
|
|
1056
1090
|
"workspaces.members.remove",
|
|
1057
1091
|
"workspaces.members.remove_confirm",
|
|
@@ -1062,10 +1096,14 @@
|
|
|
1062
1096
|
"workspaces.members.subtitle",
|
|
1063
1097
|
"workspaces.members.title",
|
|
1064
1098
|
"workspaces.members.update_role",
|
|
1099
|
+
"workspaces.retry",
|
|
1065
1100
|
"workspaces.role.admin",
|
|
1066
1101
|
"workspaces.role.member",
|
|
1067
1102
|
"workspaces.role.owner",
|
|
1068
1103
|
"workspaces.role.viewer",
|
|
1104
|
+
"workspaces.roles.load_failed",
|
|
1105
|
+
"workspaces.settings.blocked.name_required",
|
|
1106
|
+
"workspaces.settings.blocked.not_owner",
|
|
1069
1107
|
"workspaces.settings.danger_zone.delete",
|
|
1070
1108
|
"workspaces.settings.danger_zone.delete_confirm",
|
|
1071
1109
|
"workspaces.settings.danger_zone.title",
|
|
@@ -1110,6 +1148,8 @@
|
|
|
1110
1148
|
"registerWorkspacesI18n",
|
|
1111
1149
|
"toFlowError",
|
|
1112
1150
|
"useAcceptInvitation",
|
|
1151
|
+
"useAudit",
|
|
1152
|
+
"useCanCreateWorkspace",
|
|
1113
1153
|
"useCapabilities",
|
|
1114
1154
|
"useCapabilityGate",
|
|
1115
1155
|
"useClaimInvitation",
|
|
@@ -1147,6 +1187,9 @@
|
|
|
1147
1187
|
],
|
|
1148
1188
|
"types": [
|
|
1149
1189
|
"AcceptInvitationBag",
|
|
1190
|
+
"AuditEvent",
|
|
1191
|
+
"AuditPage",
|
|
1192
|
+
"AuditParams",
|
|
1150
1193
|
"CanBag",
|
|
1151
1194
|
"CapabilitiesResult",
|
|
1152
1195
|
"CapabilityGate",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stapel/workspaces-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Headless React flow pair for stapel-workspaces: typed API client, TanStack Query hooks, flow machines, headless components, and i18n keys. Zero visual opinion.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"size-limit": "^11.2.0",
|
|
92
92
|
"typescript": "^5.8.3",
|
|
93
93
|
"vitest": "^3.2.4",
|
|
94
|
-
"@stapel/core": "^0.
|
|
94
|
+
"@stapel/core": "^0.13.0",
|
|
95
95
|
"@stapel/showcase": "^0.2.0",
|
|
96
96
|
"@stapel/tokens": "^0.5.0"
|
|
97
97
|
},
|