@stapel/workspaces-react 0.10.0 → 0.11.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 +73 -0
- package/dist/api/generated/schema.d.ts +110 -0
- package/dist/api/generated/schema.d.ts.map +1 -1
- package/dist/api/types.d.ts +9 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/workspacesApi.d.ts +9 -1
- package/dist/api/workspacesApi.d.ts.map +1 -1
- package/dist/api/workspacesApi.js +2 -0
- package/dist/api/workspacesApi.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/model/mutations.d.ts +16 -1
- package/dist/model/mutations.d.ts.map +1 -1
- package/dist/model/mutations.js +39 -0
- package/dist/model/mutations.js.map +1 -1
- package/dist/model/selection.d.ts +146 -0
- package/dist/model/selection.d.ts.map +1 -0
- package/dist/model/selection.js +227 -0
- package/dist/model/selection.js.map +1 -0
- package/llms.txt +6 -2
- package/manifest.json +46 -2
- package/package.json +3 -3
- package/src/analytics/generated/events.json +1 -1
- package/src/api/generated/schema.ts +110 -0
- package/src/api/types.ts +9 -0
- package/src/api/workspacesApi.ts +21 -0
- package/src/index.ts +16 -0
- package/src/model/mutations.ts +59 -0
- package/src/model/selection.tsx +392 -0
package/dist/model/mutations.js
CHANGED
|
@@ -417,4 +417,43 @@ export function useDeclineInvitation() {
|
|
|
417
417
|
};
|
|
418
418
|
return useMutation(options);
|
|
419
419
|
}
|
|
420
|
+
/**
|
|
421
|
+
* Record the caller's home workspace (PUT /me/preferred-workspace).
|
|
422
|
+
*
|
|
423
|
+
* Invalidates the workspace list, because the list response is where the
|
|
424
|
+
* choice is READ back from (`preferred_workspace_id`) — one round trip, and
|
|
425
|
+
* no window in which the list has arrived but the answer has not.
|
|
426
|
+
*
|
|
427
|
+
* Callers should treat this as fire-and-forget: {@link useWorkspaceSelection}
|
|
428
|
+
* switches the tab locally and never blocks on the round trip. A switch that
|
|
429
|
+
* hangs on a flaky network is worse than a preference that lags one click.
|
|
430
|
+
*/
|
|
431
|
+
export function useSetPreferredWorkspace() {
|
|
432
|
+
const api = useWorkspacesApi();
|
|
433
|
+
const queryClient = useQueryClient();
|
|
434
|
+
const options = {
|
|
435
|
+
mutationFn: (body) => api.setPreferredWorkspace(body),
|
|
436
|
+
onSuccess: () => {
|
|
437
|
+
void queryClient.invalidateQueries({
|
|
438
|
+
queryKey: workspacesQueryKeys.list(),
|
|
439
|
+
});
|
|
440
|
+
},
|
|
441
|
+
};
|
|
442
|
+
return useMutation(options);
|
|
443
|
+
}
|
|
444
|
+
/** Clear the caller's home workspace (DELETE /me/preferred-workspace) — back
|
|
445
|
+
* to the instance default and the rest of the resolution chain. Idempotent. */
|
|
446
|
+
export function useClearPreferredWorkspace() {
|
|
447
|
+
const api = useWorkspacesApi();
|
|
448
|
+
const queryClient = useQueryClient();
|
|
449
|
+
const options = {
|
|
450
|
+
mutationFn: () => api.clearPreferredWorkspace(),
|
|
451
|
+
onSuccess: () => {
|
|
452
|
+
void queryClient.invalidateQueries({
|
|
453
|
+
queryKey: workspacesQueryKeys.list(),
|
|
454
|
+
});
|
|
455
|
+
},
|
|
456
|
+
};
|
|
457
|
+
return useMutation(options);
|
|
458
|
+
}
|
|
420
459
|
//# sourceMappingURL=mutations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutations.js","sourceRoot":"","sources":["../../src/model/mutations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"mutations.js","sourceRoot":"","sources":["../../src/model/mutations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from "react";
|
|
2
|
+
import type { Repository } from "@stapel/core";
|
|
3
|
+
import type { Workspace } from "../api/types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Which workspace am I in — the resolution the whole fleet was inventing
|
|
6
|
+
* separately, in one place.
|
|
7
|
+
*
|
|
8
|
+
* There are three places an answer can come from, and the design IS the order
|
|
9
|
+
* between them:
|
|
10
|
+
*
|
|
11
|
+
* 1. **the URL** — highest. This is what makes several browser tabs each work
|
|
12
|
+
* in a different workspace, and it only works because it is highest: a
|
|
13
|
+
* tab's identity must never be stolen by another tab writing shared
|
|
14
|
+
* storage.
|
|
15
|
+
* 2. **local storage** — the returning-user default on this device.
|
|
16
|
+
* 3. **the backend preference** (`preferred_workspace_id`, stapel-workspaces
|
|
17
|
+
* 0.20) — follows the person across devices and browsers.
|
|
18
|
+
*
|
|
19
|
+
* then the instance's `default_workspace_id`, then the personal workspace,
|
|
20
|
+
* then, and only then, the first row.
|
|
21
|
+
*
|
|
22
|
+
* `workspaces[0]` was the rule every client invented, and it is #239: the
|
|
23
|
+
* owner's pending invitations sat in the org workspace while his screen showed
|
|
24
|
+
* his personal one, because the list is ordered by `-last_accessed_at` and the
|
|
25
|
+
* first row is therefore "wherever you happened to be last", not a choice. It
|
|
26
|
+
* survives here only as step 6 — reached by someone with no URL, no local
|
|
27
|
+
* history, no recorded choice, no instance default and no personal workspace —
|
|
28
|
+
* because for the single-workspace majority it is trivially right, and
|
|
29
|
+
* refusing to pick would punish them with a chooser screen listing one option.
|
|
30
|
+
*/
|
|
31
|
+
/** Where {@link WorkspaceSelection.current} came from — the step of the chain
|
|
32
|
+
* that answered. Exposed because "why am I here" is otherwise unanswerable
|
|
33
|
+
* from the outside, and every previous version of this bug was invisible. */
|
|
34
|
+
export type WorkspaceSelectionSource = "url" | "local" | "preference" | "instance-default" | "personal" | "positional";
|
|
35
|
+
/**
|
|
36
|
+
* How a host binds the URL layer. Both halves are optional: omitted, the
|
|
37
|
+
* library runs on the remaining layers and multi-tab independence is simply
|
|
38
|
+
* not available — it is not an error, it is a host that has not wired it.
|
|
39
|
+
*
|
|
40
|
+
* Controlled props rather than the library reading `window.location` itself,
|
|
41
|
+
* and rather than an injected `{read, write}` adapter, for one mechanical
|
|
42
|
+
* reason: SPA routers navigate through `history.pushState`, which emits no
|
|
43
|
+
* observable event. A library reading `location` could not RE-RENDER when the
|
|
44
|
+
* URL changed, and a `read()` adapter has the same defect in disguise (a
|
|
45
|
+
* correct one would need `subscribe`, re-implementing what the host router's
|
|
46
|
+
* own re-render already gives us for free). Writing `history` directly would
|
|
47
|
+
* also desynchronise the host router's location state.
|
|
48
|
+
*/
|
|
49
|
+
export interface WorkspaceSelectionUrlBinding {
|
|
50
|
+
/**
|
|
51
|
+
* The workspace id the host read out of the URL — `?workspace=<uuid>` by
|
|
52
|
+
* convention. `null`/`undefined` means the URL names none.
|
|
53
|
+
*
|
|
54
|
+
* A query parameter, not a path segment, deliberately: a path parameter
|
|
55
|
+
* would force a `/w/:workspaceId/*` prefix into every host's route table,
|
|
56
|
+
* which is this pair dictating routing structure — the exact thing the seam
|
|
57
|
+
* exists to avoid.
|
|
58
|
+
*/
|
|
59
|
+
readonly urlWorkspaceId?: string | null;
|
|
60
|
+
/**
|
|
61
|
+
* The URL should now name `workspaceId`. The host navigates; this pair
|
|
62
|
+
* never touches history itself.
|
|
63
|
+
*
|
|
64
|
+
* `reason: "switch"` is an explicit picker action and wants a history
|
|
65
|
+
* PUSH — back should return the person to the workspace they came from.
|
|
66
|
+
* `reason: "invalid-url"` is the correction after a URL named a workspace
|
|
67
|
+
* the person cannot open, and wants a REPLACE — a URL that does not work
|
|
68
|
+
* must not stay reachable with the back button.
|
|
69
|
+
*/
|
|
70
|
+
readonly onUrlWorkspaceChange?: (workspaceId: string, meta: {
|
|
71
|
+
reason: "switch" | "invalid-url";
|
|
72
|
+
history: "push" | "replace";
|
|
73
|
+
}) => void;
|
|
74
|
+
}
|
|
75
|
+
/** What {@link useWorkspaceSelection} hands back. */
|
|
76
|
+
export interface WorkspaceSelection {
|
|
77
|
+
/** The caller's workspaces (empty before load, and for a guest). */
|
|
78
|
+
readonly workspaces: readonly Workspace[];
|
|
79
|
+
/**
|
|
80
|
+
* The resolved workspace — `null` while loading, and for a person who
|
|
81
|
+
* belongs to none.
|
|
82
|
+
*
|
|
83
|
+
* Downstream fetching must gate on THIS, never on a raw id: an id that has
|
|
84
|
+
* not been checked against the fetched list is exactly how a client ends up
|
|
85
|
+
* briefly rendering with a workspace the person cannot open.
|
|
86
|
+
*/
|
|
87
|
+
readonly current: Workspace | null;
|
|
88
|
+
/** Which step of the chain answered, or `null` before one has. */
|
|
89
|
+
readonly source: WorkspaceSelectionSource | null;
|
|
90
|
+
/**
|
|
91
|
+
* The URL named a workspace that is not in the caller's list — it does not
|
|
92
|
+
* exist, or they are not a member, or their membership is suspended (the
|
|
93
|
+
* backend deliberately does not say which). Drive a visible notice off
|
|
94
|
+
* this. The person has already been landed somewhere sane.
|
|
95
|
+
*/
|
|
96
|
+
readonly urlWorkspaceInvalid: boolean;
|
|
97
|
+
/** The workspace list is still loading. */
|
|
98
|
+
readonly loading: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* An EXPLICIT choice by the person — the only entry point that persists.
|
|
101
|
+
* Writes the URL (push), local storage, and the backend preference.
|
|
102
|
+
* Returns immediately; the backend write is fire-and-forget.
|
|
103
|
+
*/
|
|
104
|
+
switchTo: (workspaceId: string) => void;
|
|
105
|
+
/** Refetch the workspace list. */
|
|
106
|
+
refetch: () => Promise<void>;
|
|
107
|
+
}
|
|
108
|
+
/** Props for {@link WorkspaceSelectionProvider}. */
|
|
109
|
+
export interface WorkspaceSelectionProviderProps extends WorkspaceSelectionUrlBinding {
|
|
110
|
+
readonly children: ReactNode;
|
|
111
|
+
/**
|
|
112
|
+
* Override the local-storage layer. Injected for tests and for a host with
|
|
113
|
+
* its own persistence policy; the default is core's `createRepository`
|
|
114
|
+
* (`scope: "user"`). Pass `null` to run with NO local layer at all.
|
|
115
|
+
*/
|
|
116
|
+
readonly repository?: Repository<string> | null;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Resolves and holds the active workspace. Wrap the part of the app that
|
|
120
|
+
* needs one; read it with {@link useWorkspaceSelection}.
|
|
121
|
+
*
|
|
122
|
+
* ```tsx
|
|
123
|
+
* // react-router 7 host — the pair never imports the router
|
|
124
|
+
* const [params, setParams] = useSearchParams();
|
|
125
|
+
* <WorkspaceSelectionProvider
|
|
126
|
+
* urlWorkspaceId={params.get("workspace")}
|
|
127
|
+
* onUrlWorkspaceChange={(id, { history }) =>
|
|
128
|
+
* setParams((prev) => {
|
|
129
|
+
* const next = new URLSearchParams(prev);
|
|
130
|
+
* next.set("workspace", id);
|
|
131
|
+
* return next;
|
|
132
|
+
* }, { replace: history === "replace" })}
|
|
133
|
+
* >
|
|
134
|
+
* <App />
|
|
135
|
+
* </WorkspaceSelectionProvider>
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export declare function WorkspaceSelectionProvider(props: WorkspaceSelectionProviderProps): ReactElement;
|
|
139
|
+
/**
|
|
140
|
+
* The resolved active workspace. Throws outside
|
|
141
|
+
* {@link WorkspaceSelectionProvider} — a silent `null` here would be read as
|
|
142
|
+
* "no workspace yet" and produce exactly the blank screen this pair exists to
|
|
143
|
+
* prevent.
|
|
144
|
+
*/
|
|
145
|
+
export declare function useWorkspaceSelection(): WorkspaceSelection;
|
|
146
|
+
//# sourceMappingURL=selection.d.ts.map
|
|
@@ -0,0 +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;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,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,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;IAC1C;;;;;;;OAOG;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,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,kCAAkC;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAmBD,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,CAkMd;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,kBAAkB,CAQ1D"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
|
|
3
|
+
import { createRepository } from "@stapel/core";
|
|
4
|
+
import { useWorkspaces } from "./queries.js";
|
|
5
|
+
import { useSetPreferredWorkspace } from "./mutations.js";
|
|
6
|
+
const SelectionContext = createContext(null);
|
|
7
|
+
/** The repository namespace and key holding the local-storage layer. */
|
|
8
|
+
const REPO_NAMESPACE = "workspaces";
|
|
9
|
+
const REPO_KEY = "selected";
|
|
10
|
+
/**
|
|
11
|
+
* `scope: "user"` is deliberate on both counts it implies. It is encrypted at
|
|
12
|
+
* rest like the rest of the session's data, and — the part that matters — it
|
|
13
|
+
* is wiped at logout, so the next account signed in on a shared machine
|
|
14
|
+
* cannot inherit the previous account's workspace pointer.
|
|
15
|
+
*/
|
|
16
|
+
function defaultRepository() {
|
|
17
|
+
return createRepository(REPO_NAMESPACE, { scope: "user" });
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resolves and holds the active workspace. Wrap the part of the app that
|
|
21
|
+
* needs one; read it with {@link useWorkspaceSelection}.
|
|
22
|
+
*
|
|
23
|
+
* ```tsx
|
|
24
|
+
* // react-router 7 host — the pair never imports the router
|
|
25
|
+
* const [params, setParams] = useSearchParams();
|
|
26
|
+
* <WorkspaceSelectionProvider
|
|
27
|
+
* urlWorkspaceId={params.get("workspace")}
|
|
28
|
+
* onUrlWorkspaceChange={(id, { history }) =>
|
|
29
|
+
* setParams((prev) => {
|
|
30
|
+
* const next = new URLSearchParams(prev);
|
|
31
|
+
* next.set("workspace", id);
|
|
32
|
+
* return next;
|
|
33
|
+
* }, { replace: history === "replace" })}
|
|
34
|
+
* >
|
|
35
|
+
* <App />
|
|
36
|
+
* </WorkspaceSelectionProvider>
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function WorkspaceSelectionProvider(props) {
|
|
40
|
+
const { urlWorkspaceId, onUrlWorkspaceChange, children } = props;
|
|
41
|
+
const query = useWorkspaces();
|
|
42
|
+
// Same rule as `query.refetch` below: TanStack's mutation result is a new
|
|
43
|
+
// object every render, so the stable `mutate` handle is what `switchTo`
|
|
44
|
+
// closes over — depending on the result object would restore the very
|
|
45
|
+
// instability the memoisation exists to remove.
|
|
46
|
+
const savePreferred = useSetPreferredWorkspace().mutate;
|
|
47
|
+
// Built once. `createRepository` registers a logout wipe hook, so calling it
|
|
48
|
+
// per render would register one per render.
|
|
49
|
+
const repoRef = useRef(undefined);
|
|
50
|
+
if (repoRef.current === undefined) {
|
|
51
|
+
repoRef.current =
|
|
52
|
+
props.repository === undefined ? defaultRepository() : props.repository;
|
|
53
|
+
}
|
|
54
|
+
const repo = repoRef.current;
|
|
55
|
+
const [localId, setLocalId] = useState(null);
|
|
56
|
+
const [localRead, setLocalRead] = useState(!repo);
|
|
57
|
+
const [chosenId, setChosenId] = useState(null);
|
|
58
|
+
// The local layer is read EXACTLY ONCE, at mount, and never subscribed to.
|
|
59
|
+
//
|
|
60
|
+
// That is the multi-tab requirement, stated as code. The obvious "improvement"
|
|
61
|
+
// is a `storage` event listener to keep tabs in sync — and it is precisely
|
|
62
|
+
// what breaks the feature: `storage` fires in the OTHER tabs on every write,
|
|
63
|
+
// so switching in tab A would drag tab B onto A's workspace, which is the
|
|
64
|
+
// behaviour the URL layer exists to prevent. There is no listener here, and
|
|
65
|
+
// there must never be one.
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (!repo)
|
|
68
|
+
return;
|
|
69
|
+
let cancelled = false;
|
|
70
|
+
void repo
|
|
71
|
+
.get(REPO_KEY)
|
|
72
|
+
.then((value) => {
|
|
73
|
+
if (cancelled)
|
|
74
|
+
return;
|
|
75
|
+
if (typeof value === "string")
|
|
76
|
+
setLocalId(value);
|
|
77
|
+
})
|
|
78
|
+
.catch(() => undefined)
|
|
79
|
+
.finally(() => {
|
|
80
|
+
if (!cancelled)
|
|
81
|
+
setLocalRead(true);
|
|
82
|
+
});
|
|
83
|
+
return () => {
|
|
84
|
+
cancelled = true;
|
|
85
|
+
};
|
|
86
|
+
}, [repo]);
|
|
87
|
+
const workspaces = useMemo(() => query.data?.workspaces ?? [], [query.data]);
|
|
88
|
+
const loading = query.isLoading || !localRead;
|
|
89
|
+
const memberOf = useCallback((id) => id ? (workspaces.find((w) => w.id === id) ?? null) : null, [workspaces]);
|
|
90
|
+
// The chain. Runs against the FETCHED list only — never against an
|
|
91
|
+
// unresolved one, or a raw stored id would be briefly authoritative and the
|
|
92
|
+
// app would fetch a workspace it has not verified the person can open.
|
|
93
|
+
const resolved = useMemo(() => {
|
|
94
|
+
if (loading || workspaces.length === 0) {
|
|
95
|
+
return { workspace: null, source: null };
|
|
96
|
+
}
|
|
97
|
+
const explicit = memberOf(chosenId);
|
|
98
|
+
if (explicit)
|
|
99
|
+
return { workspace: explicit, source: "url" };
|
|
100
|
+
const fromUrl = memberOf(urlWorkspaceId);
|
|
101
|
+
if (fromUrl)
|
|
102
|
+
return { workspace: fromUrl, source: "url" };
|
|
103
|
+
const fromLocal = memberOf(localId);
|
|
104
|
+
if (fromLocal)
|
|
105
|
+
return { workspace: fromLocal, source: "local" };
|
|
106
|
+
const fromPreference = memberOf(query.data?.preferred_workspace_id);
|
|
107
|
+
if (fromPreference)
|
|
108
|
+
return { workspace: fromPreference, source: "preference" };
|
|
109
|
+
const fromInstance = memberOf(query.data?.default_workspace_id);
|
|
110
|
+
if (fromInstance)
|
|
111
|
+
return { workspace: fromInstance, source: "instance-default" };
|
|
112
|
+
const personal = workspaces.find((w) => w.type === "personal");
|
|
113
|
+
if (personal)
|
|
114
|
+
return { workspace: personal, source: "personal" };
|
|
115
|
+
// Last resort only — see this module's header for why it is last and why
|
|
116
|
+
// it is still here.
|
|
117
|
+
return { workspace: workspaces[0] ?? null, source: "positional" };
|
|
118
|
+
}, [loading, workspaces, memberOf, chosenId, urlWorkspaceId, localId, query.data]);
|
|
119
|
+
// The URL named something the person cannot open. Deliberately NOT an
|
|
120
|
+
// error state that blanks the screen, and deliberately NOT a silent
|
|
121
|
+
// substitution: they clicked a link expecting workspace X, and quietly
|
|
122
|
+
// showing workspace Y's data is the same misattribution class as #239.
|
|
123
|
+
// They land through the rest of the chain, and this flag drives the notice.
|
|
124
|
+
const urlWorkspaceInvalid = !loading &&
|
|
125
|
+
workspaces.length > 0 &&
|
|
126
|
+
chosenId === null &&
|
|
127
|
+
!!urlWorkspaceId &&
|
|
128
|
+
memberOf(urlWorkspaceId) === null;
|
|
129
|
+
// Correct the address bar once, with a REPLACE so the broken URL does not
|
|
130
|
+
// stay reachable with the back button.
|
|
131
|
+
const correctedFor = useRef(null);
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
if (!urlWorkspaceInvalid || !resolved.workspace)
|
|
134
|
+
return;
|
|
135
|
+
if (correctedFor.current === urlWorkspaceId)
|
|
136
|
+
return;
|
|
137
|
+
correctedFor.current = urlWorkspaceId ?? null;
|
|
138
|
+
onUrlWorkspaceChange?.(resolved.workspace.id, {
|
|
139
|
+
reason: "invalid-url",
|
|
140
|
+
history: "replace",
|
|
141
|
+
});
|
|
142
|
+
}, [urlWorkspaceInvalid, resolved.workspace, urlWorkspaceId, onUrlWorkspaceChange]);
|
|
143
|
+
// A stale local pointer is DELETED rather than rewritten to the fallback.
|
|
144
|
+
// Writing the fallback would ossify a guess into something that outranks a
|
|
145
|
+
// later-corrected backend preference or instance default; deleting it just
|
|
146
|
+
// stops the next boot retrying a dead id.
|
|
147
|
+
useEffect(() => {
|
|
148
|
+
if (loading || !repo || localId === null)
|
|
149
|
+
return;
|
|
150
|
+
if (memberOf(localId))
|
|
151
|
+
return;
|
|
152
|
+
setLocalId(null);
|
|
153
|
+
void repo.del(REPO_KEY).catch(() => undefined);
|
|
154
|
+
}, [loading, repo, localId, memberOf]);
|
|
155
|
+
/**
|
|
156
|
+
* The only path that persists anything, and that is the whole write policy:
|
|
157
|
+
* a URL is per-tab CONTEXT, a picker click is a CHOICE.
|
|
158
|
+
*
|
|
159
|
+
* If resolving from a shared link wrote the preference, one link pasted into
|
|
160
|
+
* a chat would permanently repoint its recipient's home — so a URL-driven
|
|
161
|
+
* resolution writes nothing at all, on either layer. A person who is in a
|
|
162
|
+
* URL-driven workspace and then picks it in the switcher is making a choice,
|
|
163
|
+
* and that goes through here.
|
|
164
|
+
*/
|
|
165
|
+
const switchTo = useCallback((workspaceId) => {
|
|
166
|
+
if (!workspaces.some((w) => w.id === workspaceId))
|
|
167
|
+
return;
|
|
168
|
+
setChosenId(workspaceId);
|
|
169
|
+
if (repo)
|
|
170
|
+
void repo.set(REPO_KEY, workspaceId).catch(() => undefined);
|
|
171
|
+
// Fire-and-forget: the tab has already switched. A switch that blocks on
|
|
172
|
+
// a flaky network is worse than a preference that lags one click.
|
|
173
|
+
savePreferred({ workspace_id: workspaceId });
|
|
174
|
+
onUrlWorkspaceChange?.(workspaceId, {
|
|
175
|
+
reason: "switch",
|
|
176
|
+
history: "push",
|
|
177
|
+
});
|
|
178
|
+
}, [workspaces, repo, savePreferred, onUrlWorkspaceChange]);
|
|
179
|
+
// `query.refetch`, NOT `query`: TanStack returns a NEW result object on every
|
|
180
|
+
// render, so depending on the whole query would make this callback — and
|
|
181
|
+
// therefore the memoised bag below — change identity every render, which is
|
|
182
|
+
// exactly the #251 render-loop this memoisation exists to prevent. The
|
|
183
|
+
// `refetch` handle itself is stable.
|
|
184
|
+
const refetchQuery = query.refetch;
|
|
185
|
+
const refetch = useCallback(async () => {
|
|
186
|
+
await refetchQuery();
|
|
187
|
+
}, [refetchQuery]);
|
|
188
|
+
// Memoised, and that is load-bearing rather than a performance nicety
|
|
189
|
+
// (ironmemo #251): consumers put `current` straight into `useEffect`
|
|
190
|
+
// dependency arrays to refetch when the workspace changes. A fresh object
|
|
191
|
+
// literal here would be a new value on every render of this provider, so
|
|
192
|
+
// every such effect would re-run on every render — and when the effect also
|
|
193
|
+
// sets state, that is an unbounded render loop whose only symptom is a
|
|
194
|
+
// spinner that never resolves, with nothing in the console.
|
|
195
|
+
const value = useMemo(() => ({
|
|
196
|
+
workspaces,
|
|
197
|
+
current: resolved.workspace,
|
|
198
|
+
source: resolved.source,
|
|
199
|
+
urlWorkspaceInvalid,
|
|
200
|
+
loading,
|
|
201
|
+
switchTo,
|
|
202
|
+
refetch,
|
|
203
|
+
}), [
|
|
204
|
+
workspaces,
|
|
205
|
+
resolved.workspace,
|
|
206
|
+
resolved.source,
|
|
207
|
+
urlWorkspaceInvalid,
|
|
208
|
+
loading,
|
|
209
|
+
switchTo,
|
|
210
|
+
refetch,
|
|
211
|
+
]);
|
|
212
|
+
return (_jsx(SelectionContext.Provider, { value: value, children: children }));
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* The resolved active workspace. Throws outside
|
|
216
|
+
* {@link WorkspaceSelectionProvider} — a silent `null` here would be read as
|
|
217
|
+
* "no workspace yet" and produce exactly the blank screen this pair exists to
|
|
218
|
+
* prevent.
|
|
219
|
+
*/
|
|
220
|
+
export function useWorkspaceSelection() {
|
|
221
|
+
const value = useContext(SelectionContext);
|
|
222
|
+
if (!value) {
|
|
223
|
+
throw new Error("useWorkspaceSelection must be used inside <WorkspaceSelectionProvider>");
|
|
224
|
+
}
|
|
225
|
+
return value;
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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.11.1
|
|
2
2
|
|
|
3
|
-
Headless React flow pair for stapel-workspaces (contract >=0.
|
|
3
|
+
Headless React flow pair for stapel-workspaces (contract >=0.20 <0.21) — 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
|
|
|
@@ -37,6 +37,8 @@ Paths are relative to `/workspaces/api/v1/`.
|
|
|
37
37
|
- workspaces_api_v1_invitations_resend_create: POST /{workspace_id}/invitations/{invitation_id}/resend
|
|
38
38
|
- workspaces_api_v1_invitations_retrieve: GET /invitations/{token}
|
|
39
39
|
- workspaces_api_v1_invitations_revoke_create: POST /{workspace_id}/invitations/{invitation_id}/revoke
|
|
40
|
+
- workspaces_api_v1_me_preferred_workspace_destroy: DELETE /me/preferred-workspace
|
|
41
|
+
- workspaces_api_v1_me_preferred_workspace_update: PUT /me/preferred-workspace
|
|
40
42
|
- workspaces_api_v1_members_destroy: DELETE /{workspace_id}/members/{user_id}
|
|
41
43
|
- workspaces_api_v1_members_invite_create: POST /{workspace_id}/members/invite
|
|
42
44
|
- workspaces_api_v1_members_list: GET /{workspace_id}/members
|
|
@@ -52,6 +54,7 @@ Paths are relative to `/workspaces/api/v1/`.
|
|
|
52
54
|
## Query hooks (server state; keys come only from the key factory)
|
|
53
55
|
- useAcceptInvitation (mutation) → acceptInvitation
|
|
54
56
|
- useClaimInvitation (mutation) → claimInvitation
|
|
57
|
+
- useClearPreferredWorkspace (mutation) → clearPreferredWorkspace
|
|
55
58
|
- useCreateWorkspace (mutation) → createWorkspace
|
|
56
59
|
- useDeclineInvitation (mutation) → declineInvitation
|
|
57
60
|
- useDeleteWorkspace (mutation) → deleteWorkspace
|
|
@@ -67,6 +70,7 @@ Paths are relative to `/workspaces/api/v1/`.
|
|
|
67
70
|
- useResetMemberPassword (mutation) → resetMemberPassword
|
|
68
71
|
- useRevokeInvitation (mutation) → revokeInvitation
|
|
69
72
|
- useRoles (query) → listRoles
|
|
73
|
+
- useSetPreferredWorkspace (mutation) → setPreferredWorkspace
|
|
70
74
|
- useUpdateMemberRole (mutation) → updateMemberRole
|
|
71
75
|
- useUpdateSecuritySettings (mutation) → getWorkspace+updateWorkspace
|
|
72
76
|
- useUpdateWorkspace (mutation) → updateWorkspace
|
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.11.1",
|
|
5
5
|
"backend": {
|
|
6
6
|
"module": "stapel-workspaces",
|
|
7
|
-
"contract": ">=0.
|
|
7
|
+
"contract": ">=0.20 <0.21"
|
|
8
8
|
},
|
|
9
9
|
"layers": [
|
|
10
10
|
"api",
|
|
@@ -109,6 +109,20 @@
|
|
|
109
109
|
"request": null,
|
|
110
110
|
"response": "InvitationResponse"
|
|
111
111
|
},
|
|
112
|
+
"workspaces_api_v1_me_preferred_workspace_destroy": {
|
|
113
|
+
"method": "DELETE",
|
|
114
|
+
"path": "/workspaces/api/v1/me/preferred-workspace",
|
|
115
|
+
"tag": "Workspaces",
|
|
116
|
+
"request": null,
|
|
117
|
+
"response": "PreferredWorkspaceResponse"
|
|
118
|
+
},
|
|
119
|
+
"workspaces_api_v1_me_preferred_workspace_update": {
|
|
120
|
+
"method": "PUT",
|
|
121
|
+
"path": "/workspaces/api/v1/me/preferred-workspace",
|
|
122
|
+
"tag": "Workspaces",
|
|
123
|
+
"request": "PreferredWorkspaceRequest",
|
|
124
|
+
"response": "PreferredWorkspaceResponse"
|
|
125
|
+
},
|
|
112
126
|
"workspaces_api_v1_members_destroy": {
|
|
113
127
|
"method": "DELETE",
|
|
114
128
|
"path": "/workspaces/api/v1/{workspace_id}/members/{user_id}",
|
|
@@ -207,6 +221,16 @@
|
|
|
207
221
|
"kind": "mutation",
|
|
208
222
|
"operation": "claimInvitation"
|
|
209
223
|
},
|
|
224
|
+
"useClearPreferredWorkspace": {
|
|
225
|
+
"kind": "mutation",
|
|
226
|
+
"operation": "clearPreferredWorkspace",
|
|
227
|
+
"invalidates": [
|
|
228
|
+
[
|
|
229
|
+
"workspaces",
|
|
230
|
+
"list"
|
|
231
|
+
]
|
|
232
|
+
]
|
|
233
|
+
},
|
|
210
234
|
"useCreateWorkspace": {
|
|
211
235
|
"kind": "mutation",
|
|
212
236
|
"operation": "createWorkspace",
|
|
@@ -369,6 +393,16 @@
|
|
|
369
393
|
"roles"
|
|
370
394
|
]
|
|
371
395
|
},
|
|
396
|
+
"useSetPreferredWorkspace": {
|
|
397
|
+
"kind": "mutation",
|
|
398
|
+
"operation": "setPreferredWorkspace",
|
|
399
|
+
"invalidates": [
|
|
400
|
+
[
|
|
401
|
+
"workspaces",
|
|
402
|
+
"list"
|
|
403
|
+
]
|
|
404
|
+
]
|
|
405
|
+
},
|
|
372
406
|
"useUpdateMemberRole": {
|
|
373
407
|
"kind": "mutation",
|
|
374
408
|
"operation": "updateMemberRole",
|
|
@@ -1051,6 +1085,7 @@
|
|
|
1051
1085
|
"WORKSPACES_FLOWS",
|
|
1052
1086
|
"WORKSPACES_I18N_KEYS",
|
|
1053
1087
|
"WorkspaceList",
|
|
1088
|
+
"WorkspaceSelectionProvider",
|
|
1054
1089
|
"WorkspacesProvider",
|
|
1055
1090
|
"WorkspacesRuntimeContext",
|
|
1056
1091
|
"capabilityLevel",
|
|
@@ -1072,6 +1107,7 @@
|
|
|
1072
1107
|
"useCapabilities",
|
|
1073
1108
|
"useCapabilityGate",
|
|
1074
1109
|
"useClaimInvitation",
|
|
1110
|
+
"useClearPreferredWorkspace",
|
|
1075
1111
|
"useCreateWorkspace",
|
|
1076
1112
|
"useDeclineInvitation",
|
|
1077
1113
|
"useDeleteWorkspace",
|
|
@@ -1089,10 +1125,12 @@
|
|
|
1089
1125
|
"useResetMemberPassword",
|
|
1090
1126
|
"useRevokeInvitation",
|
|
1091
1127
|
"useRoles",
|
|
1128
|
+
"useSetPreferredWorkspace",
|
|
1092
1129
|
"useUpdateMemberRole",
|
|
1093
1130
|
"useUpdateSecuritySettings",
|
|
1094
1131
|
"useUpdateWorkspace",
|
|
1095
1132
|
"useWorkspace",
|
|
1133
|
+
"useWorkspaceSelection",
|
|
1096
1134
|
"useWorkspaces",
|
|
1097
1135
|
"useWorkspacesAnalytics",
|
|
1098
1136
|
"useWorkspacesApi",
|
|
@@ -1139,6 +1177,8 @@
|
|
|
1139
1177
|
"MemberRoleUpdate",
|
|
1140
1178
|
"MembersBag",
|
|
1141
1179
|
"MembersParams",
|
|
1180
|
+
"PreferredWorkspace",
|
|
1181
|
+
"PreferredWorkspaceResult",
|
|
1142
1182
|
"ProvisionedUserPolicy",
|
|
1143
1183
|
"Remediation",
|
|
1144
1184
|
"RoleInfo",
|
|
@@ -1153,6 +1193,10 @@
|
|
|
1153
1193
|
"WorkspaceListData",
|
|
1154
1194
|
"WorkspaceRole",
|
|
1155
1195
|
"WorkspaceSecuritySettings",
|
|
1196
|
+
"WorkspaceSelection",
|
|
1197
|
+
"WorkspaceSelectionProviderProps",
|
|
1198
|
+
"WorkspaceSelectionSource",
|
|
1199
|
+
"WorkspaceSelectionUrlBinding",
|
|
1156
1200
|
"WorkspaceUpdate",
|
|
1157
1201
|
"WorkspacesApi",
|
|
1158
1202
|
"WorkspacesErrorCode",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stapel/workspaces-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
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": {
|
|
@@ -82,9 +82,9 @@
|
|
|
82
82
|
"size-limit": "^11.2.0",
|
|
83
83
|
"typescript": "^5.8.3",
|
|
84
84
|
"vitest": "^3.2.4",
|
|
85
|
+
"@stapel/core": "^0.10.0",
|
|
85
86
|
"@stapel/tokens": "^0.5.0",
|
|
86
|
-
"@stapel/showcase": "^0.2.0"
|
|
87
|
-
"@stapel/core": "^0.10.0"
|
|
87
|
+
"@stapel/showcase": "^0.2.0"
|
|
88
88
|
},
|
|
89
89
|
"engines": {
|
|
90
90
|
"node": ">=22"
|