@rebasepro/app 0.24.0 → 0.24.1-canary.gcb918fc
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/README.md +2 -2
- package/dist/components/common/useColumnsIds.d.ts +2 -2
- package/dist/components/common/useDataTableController.d.ts +15 -1
- package/dist/components/common/useScrollRestoration.d.ts +16 -7
- package/dist/contexts/CollectionResolverContext.d.ts +8 -1
- package/dist/contexts/StorageSourcesContext.d.ts +6 -0
- package/dist/core/RebaseProps.d.ts +21 -0
- package/dist/core/deprecated_plugin_keys.d.ts +10 -0
- package/dist/de-BcBo287O.js +1434 -0
- package/dist/de-BcBo287O.js.map +1 -0
- package/dist/debug/ui-reference/ComponentSections.d.ts +16 -0
- package/dist/debug.js +867 -484
- package/dist/es-D-JXBvsW.js +1442 -0
- package/dist/es-D-JXBvsW.js.map +1 -0
- package/dist/fr-BKGBSaZM.js +1434 -0
- package/dist/fr-BKGBSaZM.js.map +1 -0
- package/dist/hi-D1jEYlQ1.js +1434 -0
- package/dist/hi-D1jEYlQ1.js.map +1 -0
- package/dist/hooks/data/collectionWindow.d.ts +146 -13
- package/dist/hooks/data/save.d.ts +11 -2
- package/dist/hooks/data/useBatchedFetch.d.ts +21 -0
- package/dist/hooks/data/useDataOrder.d.ts +6 -0
- package/dist/hooks/data/useFetch.d.ts +12 -4
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/useBuildModeController.d.ts +22 -2
- package/dist/hooks/useComponentOverride.d.ts +10 -7
- package/dist/hooks/useNavigationBlocker.d.ts +17 -9
- package/dist/index.d.ts +0 -1
- package/dist/index.es.js +1558 -8659
- package/dist/index.es.js.map +1 -1
- package/dist/it-DLXLsP1j.js +1434 -0
- package/dist/it-DLXLsP1j.js.map +1 -0
- package/dist/pt-Dd3JWvUZ.js +1439 -0
- package/dist/pt-Dd3JWvUZ.js.map +1 -0
- package/dist/util/previews.d.ts +22 -5
- package/dist/util/useStorageUploadController.d.ts +6 -2
- package/dist/vitePlugin.js +2 -0
- package/package.json +11 -7
- package/dist/hooks/useBackendStorageSource.d.ts +0 -35
|
@@ -17,6 +17,15 @@ export interface CollectionWindowState<M extends Record<string, unknown> = Recor
|
|
|
17
17
|
* flashing a partial list.
|
|
18
18
|
*/
|
|
19
19
|
rows: Entity<M>[] | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* The same rows by position, with `undefined` where a row exists but has
|
|
22
|
+
* not been read — the rows above a scroll position the window was
|
|
23
|
+
* restored to ({@link CollectionWindowOptions.seed}), until the view
|
|
24
|
+
* scrolls to them. Absent when nothing is missing, which is always the
|
|
25
|
+
* case for a window no view reports a range to: `rows` is then complete
|
|
26
|
+
* from the first row.
|
|
27
|
+
*/
|
|
28
|
+
sparse?: (Entity<M> | undefined)[];
|
|
20
29
|
/** Rows not yet on screen are being read: the first page, or the next one. */
|
|
21
30
|
loading: boolean;
|
|
22
31
|
error: Error | undefined;
|
|
@@ -47,8 +56,38 @@ export interface CollectionWindowOptions<M extends Record<string, unknown>> {
|
|
|
47
56
|
* The subscription still wins whenever it does answer.
|
|
48
57
|
*/
|
|
49
58
|
firstPaintTimeoutMs?: number;
|
|
59
|
+
/**
|
|
60
|
+
* The quiet time kept between the end of one re-read of the rows past the
|
|
61
|
+
* first page and the start of the next. Defaults to
|
|
62
|
+
* {@link REREAD_INTERVAL_MS}. A push after a quiet spell is re-read at
|
|
63
|
+
* once; pushes inside this window fold into one re-read at its end.
|
|
64
|
+
*/
|
|
65
|
+
rereadIntervalMs?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Rows already known, from a view this window replaces (a scroll position
|
|
68
|
+
* kept while a record was open full screen): `rows` sit at `offset` and
|
|
69
|
+
* on. They are shown at once and read again only when a view reports
|
|
70
|
+
* them in range ({@link CollectionWindow.setVisibleRange}); the rows
|
|
71
|
+
* between the first page and `offset` are not read until a view scrolls
|
|
72
|
+
* to them. `target` should cover them.
|
|
73
|
+
*/
|
|
74
|
+
seed?: {
|
|
75
|
+
offset: number;
|
|
76
|
+
rows: Entity<M>[];
|
|
77
|
+
};
|
|
50
78
|
onChange: (state: CollectionWindowState<M>) => void;
|
|
51
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* The quiet time between two re-reads of the rows held past the first page.
|
|
82
|
+
*
|
|
83
|
+
* The server pushes at most once per ~300 ms of quiet per subscription, and at
|
|
84
|
+
* least once a second under a steady stream of writes; each push used to start
|
|
85
|
+
* a re-read of every held row past the first page as soon as the last one
|
|
86
|
+
* ended, so a table scrolled to 10,000 rows ran ten 1,000-row reads back to
|
|
87
|
+
* back for as long as the writes went on. This keeps the duty cycle bounded:
|
|
88
|
+
* at most one re-read per re-read time plus this.
|
|
89
|
+
*/
|
|
90
|
+
export declare const REREAD_INTERVAL_MS = 2000;
|
|
52
91
|
/**
|
|
53
92
|
* A scrolled collection view's rows, read one page at a time.
|
|
54
93
|
*
|
|
@@ -72,14 +111,34 @@ export interface CollectionWindowOptions<M extends Record<string, unknown>> {
|
|
|
72
111
|
* view offers can express — a relevance-ordered search has no cursor — and
|
|
73
112
|
* because the server breaks ties on the id, so pages neither repeat nor skip
|
|
74
113
|
* rows under a sort with duplicates.
|
|
75
|
-
* - **Realtime
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* read again
|
|
79
|
-
*
|
|
114
|
+
* - **Realtime.** The server re-runs a subscription on every write to its
|
|
115
|
+
* collection, so each push after the first says "something changed", and
|
|
116
|
+
* every row held past the first page is stale from then on. Which of them
|
|
117
|
+
* are read again depends on whether a view says what it shows:
|
|
118
|
+
* - A view that reports the rows it draws ({@link setVisibleRange}) has the
|
|
119
|
+
* rows on screen read again, plus a page either side — one read, however
|
|
120
|
+
* far it was scrolled. Rows further out stay stale and are read when they
|
|
121
|
+
* come within half a page of the screen, before they are on it.
|
|
122
|
+
* - Without a report, every row held is read again, in reads of at most
|
|
123
|
+
* `MAX_LIST_LIMIT`, and replaced in one step — the only way a view that
|
|
124
|
+
* cannot say what it shows never shows a stale row.
|
|
125
|
+
* Either way a push after a quiet spell is re-read at once; pushes that
|
|
126
|
+
* arrive while a re-read runs, or within `rereadIntervalMs` of the last one
|
|
127
|
+
* ending, fold into one re-read at the end of that interval — at once if the
|
|
128
|
+
* view asks for more rows or scrolls to rows not read since. The first page
|
|
129
|
+
* itself is applied the moment it is pushed, as always.
|
|
80
130
|
*
|
|
81
|
-
* Rows are de-duplicated by id
|
|
82
|
-
*
|
|
131
|
+
* Rows are de-duplicated by id, keeping the copy read last: an insert or a
|
|
132
|
+
* delete above shifts every offset by one, so between a push and the re-read
|
|
133
|
+
* of the rows it moved, a row can sit in two places — on the first page and in
|
|
134
|
+
* the stale row below it, or in the rows just re-read and the stale ones next
|
|
135
|
+
* to them.
|
|
136
|
+
*
|
|
137
|
+
* A window can hold **gaps**: a restored scroll position ({@link
|
|
138
|
+
* CollectionWindowOptions.seed}) shows the rows that were on screen without
|
|
139
|
+
* reading every row above them. A gap is read when a view scrolls to it; a
|
|
140
|
+
* window no view reports a range to reads its gaps at once and shows nothing
|
|
141
|
+
* until they are filled, as it would have read them all before.
|
|
83
142
|
*/
|
|
84
143
|
export declare class CollectionWindow<M extends Record<string, unknown>> {
|
|
85
144
|
private readonly accessor;
|
|
@@ -92,13 +151,26 @@ export declare class CollectionWindow<M extends Record<string, unknown>> {
|
|
|
92
151
|
private head;
|
|
93
152
|
/** The first page came back full, so there may be more past it. */
|
|
94
153
|
private headFull;
|
|
95
|
-
/**
|
|
96
|
-
|
|
97
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Rows past the first page: `slots[i]` is the row at offset
|
|
156
|
+
* `pageSize + i`, `undefined` where it has not been read (a gap).
|
|
157
|
+
*/
|
|
158
|
+
private slots;
|
|
159
|
+
/** The last read reaching the end of the held rows came back short. */
|
|
98
160
|
private tailEnded;
|
|
99
|
-
/**
|
|
100
|
-
private
|
|
161
|
+
/** Moves on with every push after the first: rows read before it are stale. */
|
|
162
|
+
private version;
|
|
163
|
+
/**
|
|
164
|
+
* The offsets a view says it draws, end exclusive. `undefined` until one
|
|
165
|
+
* says so, and again when it goes: every held row is then kept current.
|
|
166
|
+
*/
|
|
167
|
+
private range;
|
|
168
|
+
/** The view moved to rows not read since: read them without waiting. */
|
|
169
|
+
private rangeMoved;
|
|
170
|
+
/** Offset of each row (or gap) of the last state reported, by position. */
|
|
171
|
+
private emittedOffsets;
|
|
101
172
|
private pumping;
|
|
173
|
+
private pumpQueued;
|
|
102
174
|
private loadingMore;
|
|
103
175
|
private headError;
|
|
104
176
|
private tailError;
|
|
@@ -108,26 +180,87 @@ export declare class CollectionWindow<M extends Record<string, unknown>> {
|
|
|
108
180
|
private liveAnswered;
|
|
109
181
|
private unsubscribe;
|
|
110
182
|
private firstPaintTimer;
|
|
183
|
+
/** When the last re-read of the rows past the first page finished. */
|
|
184
|
+
private lastRereadEndedAt;
|
|
185
|
+
/** A re-read waiting out {@link REREAD_INTERVAL_MS}. */
|
|
186
|
+
private rereadTimer;
|
|
111
187
|
constructor(options: CollectionWindowOptions<M>);
|
|
112
188
|
start(): void;
|
|
113
189
|
/** Hold this many rows. Fewer than are held drops the rows past it. */
|
|
114
190
|
setTarget(target: number): void;
|
|
191
|
+
/**
|
|
192
|
+
* The rows a view draws, by position in the last `rows` (or `sparse`) it
|
|
193
|
+
* was given, end exclusive; `undefined` when it stops drawing them. Rows
|
|
194
|
+
* near the range are kept current and gaps near it are read; see the
|
|
195
|
+
* class comment.
|
|
196
|
+
*/
|
|
197
|
+
setVisibleRange(range: {
|
|
198
|
+
start: number;
|
|
199
|
+
end: number;
|
|
200
|
+
} | undefined): void;
|
|
201
|
+
/**
|
|
202
|
+
* What to keep of this window to show it again later: the rows read
|
|
203
|
+
* around the range a view last reported — or, with none reported, every
|
|
204
|
+
* row from the first — the offset of the first of them, and how many
|
|
205
|
+
* rows the window holds in all. See {@link CollectionWindowOptions.seed}.
|
|
206
|
+
*/
|
|
207
|
+
snapshot(): {
|
|
208
|
+
offset: number;
|
|
209
|
+
rows: Entity<M>[];
|
|
210
|
+
held: number;
|
|
211
|
+
};
|
|
115
212
|
dispose(): void;
|
|
116
213
|
private readHeadOnce;
|
|
117
214
|
private receiveLiveError;
|
|
118
215
|
private receiveHead;
|
|
119
216
|
/** Rows still wanted past the ones held. */
|
|
120
217
|
private wanted;
|
|
218
|
+
private needsRead;
|
|
219
|
+
/**
|
|
220
|
+
* The held rows to read again now, by slot, or `undefined` if none.
|
|
221
|
+
*
|
|
222
|
+
* With a range: the stale rows and gaps within a page of it, once any of
|
|
223
|
+
* them is within half a page — so scrolling into stale rows reads a
|
|
224
|
+
* stretch of them ahead of the screen rather than one row per frame.
|
|
225
|
+
* Without: every stale row and gap, as one span.
|
|
226
|
+
*/
|
|
227
|
+
private nextRefresh;
|
|
228
|
+
private schedulePump;
|
|
121
229
|
/**
|
|
122
230
|
* The one loop that reads past the first page, so a re-read and a next page
|
|
123
231
|
* never run at the same time and interleave their offsets.
|
|
124
232
|
*/
|
|
125
233
|
private pump;
|
|
234
|
+
/** How long a re-read due now still has to wait. 0 after a quiet spell. */
|
|
235
|
+
private rereadWait;
|
|
236
|
+
private armReread;
|
|
126
237
|
private readNext;
|
|
127
|
-
/**
|
|
238
|
+
/**
|
|
239
|
+
* Read the held rows in slots `[from, to)` again, and swap them in at once.
|
|
240
|
+
* A read that comes back short says where the collection ends now: the
|
|
241
|
+
* rows held past that are dropped.
|
|
242
|
+
*/
|
|
128
243
|
private reread;
|
|
244
|
+
/**
|
|
245
|
+
* Every one-shot read the window makes: its query, never counted.
|
|
246
|
+
*
|
|
247
|
+
* Nothing here reads `meta.total` — a page ends the window by coming back
|
|
248
|
+
* short — and the `COUNT(*)` beside each page read every matching row to
|
|
249
|
+
* report a number that was thrown away: scrolling a table to 10,000 rows
|
|
250
|
+
* ran 199 of them. The first page's subscription is the accessor's and is
|
|
251
|
+
* left as it is.
|
|
252
|
+
*/
|
|
253
|
+
private oneShot;
|
|
129
254
|
private process;
|
|
130
255
|
private complete;
|
|
256
|
+
private hasGaps;
|
|
131
257
|
private emit;
|
|
258
|
+
/**
|
|
259
|
+
* The rows to show, in order, each id once — the copy read last wins, the
|
|
260
|
+
* first page counting as read now — with gaps kept as positions in
|
|
261
|
+
* `sparse`, and the offset each position stands for.
|
|
262
|
+
*/
|
|
132
263
|
private rows;
|
|
264
|
+
/** Positions in the last state reported, as offsets in the collection. */
|
|
265
|
+
private toOffsets;
|
|
133
266
|
}
|
|
@@ -11,6 +11,13 @@ export type SaveEntityWithCallbacksProps<M extends Record<string, unknown>> = {
|
|
|
11
11
|
previousValues?: Partial<EntityValues<M>>;
|
|
12
12
|
collection?: AdminCollection<M>;
|
|
13
13
|
status: EntityStatus;
|
|
14
|
+
/**
|
|
15
|
+
* The version the edit was made against — the edited entity's
|
|
16
|
+
* {@link Entity.etag}. An update is then refused with `412
|
|
17
|
+
* PRECONDITION_FAILED` if the record has changed since, rather than
|
|
18
|
+
* writing over the change. Ignored for a create.
|
|
19
|
+
*/
|
|
20
|
+
ifMatch?: string;
|
|
14
21
|
afterSave?: (updatedEntity: Entity<M>) => void;
|
|
15
22
|
afterSaveError?: (e: Error) => void;
|
|
16
23
|
};
|
|
@@ -33,7 +40,9 @@ export type SaveEntityWithCallbacksProps<M extends Record<string, unknown>> = {
|
|
|
33
40
|
*
|
|
34
41
|
* `afterSave`/`afterSaveError` below are the *caller's* UI callbacks — the
|
|
35
42
|
* form's "close the dialog", the table's "clear the editing state" — and are
|
|
36
|
-
* unrelated to the collection's. Both run: the collection's first.
|
|
43
|
+
* unrelated to the collection's. Both run: the collection's first. A
|
|
44
|
+
* collection `afterSave` that throws does not undo the save: the write has
|
|
45
|
+
* committed, so it is reported as a warning and the caller's `afterSave` runs.
|
|
37
46
|
*
|
|
38
47
|
* @param collection
|
|
39
48
|
* @param path
|
|
@@ -47,7 +56,7 @@ export type SaveEntityWithCallbacksProps<M extends Record<string, unknown>> = {
|
|
|
47
56
|
* @param afterSaveError
|
|
48
57
|
* @group Hooks and utilities
|
|
49
58
|
*/
|
|
50
|
-
export declare function saveEntityWithCallbacks<M extends Record<string, unknown>>({ collection, path, entityId, values, previousValues, status, data, context, afterSave, afterSaveError }: Omit<SaveEntityWithCallbacksProps<M>, "collection"> & {
|
|
59
|
+
export declare function saveEntityWithCallbacks<M extends Record<string, unknown>>({ collection, path, entityId, values, previousValues, status, ifMatch, data, context, afterSave, afterSaveError }: Omit<SaveEntityWithCallbacksProps<M>, "collection"> & {
|
|
51
60
|
collection: AdminCollection<M>;
|
|
52
61
|
data: RebaseData;
|
|
53
62
|
context: RebaseContext;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AdminCollection } from "@rebasepro/cms-types";
|
|
2
|
+
import type { FetchResult } from "./useFetch.js";
|
|
3
|
+
/**
|
|
4
|
+
* {@link useFetch} for a record many previews on one screen ask for at once —
|
|
5
|
+
* the target of a reference in a table cell, a card, an array of references.
|
|
6
|
+
*
|
|
7
|
+
* The ids every preview asks for in one tick are read together: one query and
|
|
8
|
+
* one live subscription per batch, not one `listenById` per record. Updates
|
|
9
|
+
* reach a preview per batch — a write to any record of the batch refetches the
|
|
10
|
+
* batch — which is what a preview needs.
|
|
11
|
+
*
|
|
12
|
+
* For one record a view edits, use {@link useFetch}: it follows that record
|
|
13
|
+
* alone and seeds from the record cache.
|
|
14
|
+
*
|
|
15
|
+
* @group Hooks and utilities
|
|
16
|
+
*/
|
|
17
|
+
export declare function useBatchedFetch<M extends Record<string, any>>({ path, entityId, collection }: {
|
|
18
|
+
path: string;
|
|
19
|
+
entityId?: string | number;
|
|
20
|
+
collection: AdminCollection<M>;
|
|
21
|
+
}): FetchResult<M>;
|
|
@@ -5,6 +5,12 @@ export interface DataOrderProps<M extends Record<string, any>> {
|
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* This hook is used to have some entities at the beginning of data.
|
|
8
|
+
*
|
|
9
|
+
* The result is the same array until `data` or `entitiesDisplayedFirst`
|
|
10
|
+
* changes. It used to be rebuilt on every call whenever rows were pinned, so
|
|
11
|
+
* the table controller around it — and everything rendering from that — was
|
|
12
|
+
* new on every render.
|
|
13
|
+
*
|
|
8
14
|
* @param path
|
|
9
15
|
* @param entitiesDisplayedFirst
|
|
10
16
|
* @group Hooks and utilities
|
|
@@ -9,6 +9,14 @@ export interface FetchProps<M extends Record<string, any>, USER extends User = U
|
|
|
9
9
|
databaseId?: string;
|
|
10
10
|
collection: AdminCollection<M, USER>;
|
|
11
11
|
useCache?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Load the collection's relation properties into the record, as a list
|
|
14
|
+
* read loads them into each row. The record views ask for it: a form built
|
|
15
|
+
* on a record without them shows a many-to-many field empty, and saving it
|
|
16
|
+
* sets that empty membership. A preview leaves it off, since it would load
|
|
17
|
+
* every related row of the record it previews.
|
|
18
|
+
*/
|
|
19
|
+
relations?: boolean;
|
|
12
20
|
}
|
|
13
21
|
/**
|
|
14
22
|
* @group Hooks and utilities
|
|
@@ -19,9 +27,9 @@ export interface FetchResult<M extends Record<string, any>> {
|
|
|
19
27
|
dataLoadingError?: Error;
|
|
20
28
|
}
|
|
21
29
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
30
|
+
* Put records in the entity fetch cache, so a view that opens one renders it at
|
|
31
|
+
* once while the background fetch/listener brings in fresh data. The cache
|
|
32
|
+
* keeps the 2,000 records written or read most recently.
|
|
25
33
|
* @param path - The collection path (e.g. "products")
|
|
26
34
|
* @param entities - Array of entities to cache
|
|
27
35
|
*/
|
|
@@ -40,4 +48,4 @@ export declare function clearFetchCache(): void;
|
|
|
40
48
|
* @param useCache
|
|
41
49
|
* @group Hooks and utilities
|
|
42
50
|
*/
|
|
43
|
-
export declare function useFetch<M extends Record<string, any>, USER extends User = User>({ path, entityId, collection, databaseId, useCache }: FetchProps<M, USER>): FetchResult<M>;
|
|
51
|
+
export declare function useFetch<M extends Record<string, any>, USER extends User = User>({ path, entityId, collection, databaseId, useCache, relations }: FetchProps<M, USER>): FetchResult<M>;
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./data/useData.js";
|
|
|
2
2
|
export * from "./data/useCollection.js";
|
|
3
3
|
export * from "./data/collectionWindow.js";
|
|
4
4
|
export * from "./data/useFetch.js";
|
|
5
|
+
export * from "./data/useBatchedFetch.js";
|
|
5
6
|
export * from "./data/useRelationSelector.js";
|
|
6
7
|
export * from "./data/save.js";
|
|
7
8
|
export * from "./data/delete.js";
|
|
@@ -26,7 +27,6 @@ export * from "./useCustomizationController.js";
|
|
|
26
27
|
export * from "./useBuildLocalConfigurationPersistence.js";
|
|
27
28
|
export * from "./useBuildModeController.js";
|
|
28
29
|
export * from "./useRebaseRegistry.js";
|
|
29
|
-
export * from "./useBackendStorageSource.js";
|
|
30
30
|
export * from "./usePermissions.js";
|
|
31
31
|
export * from "./ApiConfigContext.js";
|
|
32
32
|
export * from "./useTranslation.js";
|
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
import type { ModeController } from "./useModeController.js";
|
|
2
|
+
/**
|
|
3
|
+
* @group Hooks and utilities
|
|
4
|
+
*/
|
|
5
|
+
export interface BuildModeControllerOptions {
|
|
6
|
+
/**
|
|
7
|
+
* `false` builds a controller that touches nothing outside React: no `dark`
|
|
8
|
+
* class on `<html>`, no `prefers-color-scheme` listener, no localStorage.
|
|
9
|
+
* `<Rebase>` passes it when the host app hands over its own
|
|
10
|
+
* `modeController`. Defaults to `true`.
|
|
11
|
+
*/
|
|
12
|
+
enabled?: boolean;
|
|
13
|
+
}
|
|
2
14
|
/**
|
|
3
15
|
* Use this hook to build a color mode controller that determines
|
|
4
|
-
* the theme of the admin
|
|
16
|
+
* the theme of the admin.
|
|
17
|
+
*
|
|
18
|
+
* While enabled it owns the page's theme: it puts the `dark` class on
|
|
19
|
+
* `document.documentElement`, follows `prefers-color-scheme` until the user
|
|
20
|
+
* picks a mode, and remembers that pick in localStorage. When the component
|
|
21
|
+
* using it unmounts, it takes away the `dark` class if it was the one that
|
|
22
|
+
* added it.
|
|
23
|
+
*
|
|
24
|
+
* @group Hooks and utilities
|
|
5
25
|
*/
|
|
6
|
-
export declare function useBuildModeController(): ModeController;
|
|
26
|
+
export declare function useBuildModeController(options?: BuildModeControllerOptions): ModeController;
|
|
@@ -3,15 +3,18 @@ import type { OverridableComponentName } from "@rebasepro/cms-types";
|
|
|
3
3
|
/**
|
|
4
4
|
* Resolves a potentially overridden component.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* 1.
|
|
8
|
-
* 2. Global override
|
|
9
|
-
* 3.
|
|
6
|
+
* The two scopes compose, innermost first:
|
|
7
|
+
* 1. Default component
|
|
8
|
+
* 2. Global override (`<Rebase components>`), applied to the default
|
|
9
|
+
* 3. Collection-scoped override (`admin.components`), applied to the result
|
|
10
|
+
* of 2
|
|
10
11
|
*
|
|
11
12
|
* Supports two override modes:
|
|
12
|
-
* - **Eject** (default): The override component fully replaces
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* - **Eject** (default): The override component fully replaces what it is
|
|
14
|
+
* applied to.
|
|
15
|
+
* - **Wrap** (`wrap: true`): The override component wraps what it is applied
|
|
16
|
+
* to, passed as `OriginalComponent` in props — so a collection's wrapper
|
|
17
|
+
* wraps the global override when there is one, not the built-in default.
|
|
15
18
|
*
|
|
16
19
|
* @param name - The overridable component name (e.g. `"Entity.Form"`)
|
|
17
20
|
* @param DefaultComponent - The built-in default component
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Blocker, BlockerFunction } from "react-router";
|
|
3
3
|
/**
|
|
4
|
-
* Owns the single
|
|
4
|
+
* Owns the single navigation guard for the whole app.
|
|
5
5
|
*
|
|
6
|
-
* React Router
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Under a React Router **data router** (`createBrowserRouter` +
|
|
7
|
+
* `<RouterProvider>`) it holds the one `useBlocker` in the tree. React Router
|
|
8
|
+
* only honours one blocker at a time: `shouldBlockNavigation` picks the
|
|
9
|
+
* last-registered blocker function and silently ignores every other one (it
|
|
10
|
+
* only logs a dev warning). Because blockers register in a `useEffect`, the
|
|
11
|
+
* winner is whichever surface mounted most recently — so an unsaved-changes
|
|
12
|
+
* guard could be disabled by an unrelated component mounting after it. This
|
|
13
|
+
* provider registers the only one and multiplexes it, so every surface that
|
|
14
|
+
* guards navigation gets a say regardless of mount order.
|
|
11
15
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
16
|
+
* Under any **other** router (a plain `<BrowserRouter>`, a `<MemoryRouter>`)
|
|
17
|
+
* there is no `useBlocker` to call — it throws outside a data router — and no
|
|
18
|
+
* way to intercept an in-app navigation. The guards then degrade to the
|
|
19
|
+
* browser's own: leaving the page (reload, tab close, typing a URL) asks for
|
|
20
|
+
* confirmation while any registered guard would block leaving.
|
|
21
|
+
*
|
|
22
|
+
* Surfaces register through {@link useNavigationBlocker}.
|
|
15
23
|
*/
|
|
16
24
|
export declare function NavigationBlockerProvider({ children }: {
|
|
17
25
|
children: React.ReactNode;
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,6 @@ export type { RebaseStorageSource } from "./core/RebaseProps.js";
|
|
|
13
13
|
export { UnsavedChangesDialog } from "./components/UnsavedChangesDialog.js";
|
|
14
14
|
export * from "./i18n/RebaseI18nProvider.js";
|
|
15
15
|
export * from "./locales/en.js";
|
|
16
|
-
export * from "./locales/es.js";
|
|
17
16
|
export * from "./hooks/useStudioBridge.js";
|
|
18
17
|
export { useBridgeRegistration } from "./hooks/useBridgeRegistration.js";
|
|
19
18
|
export * from "./collections/index.js";
|