@nivaro/react 0.3.41 → 0.3.43
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/dist/components/LayoutForm.js +100 -98
- package/dist/full.css +1 -1
- package/dist/hooks/useSessionRecorder.js +1 -1
- package/dist/index.d.ts +733 -15
- package/dist/index.js +820 -775
- package/dist/shared/components/ActivityEntry.js +154 -0
- package/dist/shared/components/AudienceConfirmPanel.js +98 -0
- package/dist/shared/components/BackgroundRunOffer.js +43 -31
- package/dist/shared/components/BroadcastView.js +225 -204
- package/dist/shared/components/CollectionBrowserView.js +3924 -3584
- package/dist/shared/components/ConfigHistory.js +153 -0
- package/dist/shared/components/ConfigReadBack.js +65 -0
- package/dist/shared/components/DataTable.js +379 -346
- package/dist/shared/components/ForceReloadBanner.js +47 -40
- package/dist/shared/components/IdleReloadWatcher.js +69 -0
- package/dist/shared/components/ItemEditForm.js +4041 -3853
- package/dist/shared/components/MyWorkView.js +278 -213
- package/dist/shared/components/NotificationBell.js +130 -121
- package/dist/shared/components/ProfileView.js +776 -1003
- package/dist/shared/components/RecentRecordsRail.js +34 -16
- package/dist/shared/components/RecordReadView.js +500 -477
- package/dist/shared/components/Skeletons.js +199 -0
- package/dist/shared/components/SlowNotice.js +63 -0
- package/dist/shared/components/Term.js +23 -0
- package/dist/shared/components/WidgetSlot.js +350 -353
- package/dist/shared/components/access/PermissionSummary.js +106 -0
- package/dist/shared/components/bulk/BulkActionButtons.js +76 -73
- package/dist/shared/components/chat/ChatPanel.js +902 -886
- package/dist/shared/components/chat/MemberPaging.js +70 -0
- package/dist/shared/components/chat/RoomParts.js +147 -117
- package/dist/shared/components/chat/ScreenClip.js +73 -69
- package/dist/shared/components/chat/chat-core.js +449 -396
- package/dist/shared/components/chat/huddle/huddle-store.js +48 -43
- package/dist/shared/components/help-videos/api.js +2 -5
- package/dist/shared/components/help-videos/viewer/HelpVideoMatchChip.js +79 -0
- package/dist/shared/components/help-videos/viewer/matchChip.js +50 -0
- package/dist/shared/components/imports/CollectionImportPanel.js +139 -133
- package/dist/shared/components/imports/RunDetailSheet.js +222 -227
- package/dist/shared/components/integrations/console/ErrorExplanation.js +121 -0
- package/dist/shared/components/integrations/console/PartnerDetail.js +175 -174
- package/dist/shared/components/integrations/console/SubmissionRow.js +36 -34
- package/dist/shared/components/integrations/console/drill/SubmissionDrill.js +50 -48
- package/dist/shared/components/item-edit/FieldComments.js +212 -0
- package/dist/shared/components/item-edit/FieldRow.js +340 -336
- package/dist/shared/components/item-edit/RecordHeaderActions.js +23 -22
- package/dist/shared/components/item-edit/RelationCombobox.js +231 -222
- package/dist/shared/components/item-edit/RuleHiddenNotes.js +55 -0
- package/dist/shared/components/item-edit/field-comments-context.js +6 -0
- package/dist/shared/components/item-edit/field-sources.js +33 -0
- package/dist/shared/components/item-edit/rule-hidden.js +30 -0
- package/dist/shared/components/layout-editor/HistoryPanel.js +113 -96
- package/dist/shared/components/layout-editor/editors/cascade-filters.js +170 -145
- package/dist/shared/components/layout-editor/inspector/Breadcrumb.js +22 -18
- package/dist/shared/components/layout-editor/inspector/GroupInspector.js +177 -159
- package/dist/shared/components/layout-editor/inspector/PickerTab.js +35 -34
- package/dist/shared/components/layout-editor/inspector/RulesTab.js +124 -111
- package/dist/shared/components/layout-editor/inspector/kit.js +292 -277
- package/dist/shared/components/layout-editor/parity-keys.json.js +1 -1
- package/dist/shared/components/list/CopyListLinkButton.js +41 -0
- package/dist/shared/components/list/InlineEdit.js +363 -0
- package/dist/shared/components/notifications/NotificationCenterView.js +213 -181
- package/dist/shared/components/notifications/NotificationDetailBits.js +205 -82
- package/dist/shared/components/notifications/NotificationRulesEditor.js +515 -0
- package/dist/shared/components/notifications/TestMyRules.js +137 -0
- package/dist/shared/components/notifications/changes-lines.js +24 -0
- package/dist/shared/components/notifications/why-lines.js +64 -0
- package/dist/shared/components/panels/CommentPanel.js +316 -281
- package/dist/shared/components/panels/LegalHoldBanner.js +38 -0
- package/dist/shared/components/panels/PipelinePanel.js +201 -196
- package/dist/shared/components/panels/RevisionsPanel.js +496 -479
- package/dist/shared/components/pipeline/PipelineEditorView.js +1587 -1560
- package/dist/shared/components/pipeline/PipelineStateOwners.js +116 -103
- package/dist/shared/components/profile/PersonDidPanel.js +188 -0
- package/dist/shared/components/profile/PersonProfile.js +57 -52
- package/dist/shared/components/queue/QueueWorklist.js +1526 -1365
- package/dist/shared/hooks/useSlowReason.js +39 -0
- package/dist/shared/lib/activity-sentence.js +670 -0
- package/dist/shared/lib/config-sentences.js +418 -0
- package/dist/shared/lib/core-glossary.js +229 -0
- package/dist/shared/lib/error-hints.js +159 -0
- package/dist/shared/lib/error-message.js +105 -0
- package/dist/shared/lib/error-toast.js +22 -0
- package/dist/shared/lib/field-comments.js +25 -0
- package/dist/shared/lib/filter-sentence.js +261 -0
- package/dist/shared/lib/glossary.js +55 -48
- package/dist/shared/lib/idle-reload.js +138 -0
- package/dist/shared/lib/layout-resolve.js +42 -29
- package/dist/shared/lib/list-inline-edit.js +190 -0
- package/dist/shared/lib/list-link.js +147 -0
- package/dist/shared/lib/nav-trail.js +107 -0
- package/dist/shared/lib/prefetch.js +259 -106
- package/dist/shared/lib/record-ref.js +72 -0
- package/dist/shared/lib/reload-holds.js +25 -0
- package/dist/shared/lib/safe-error.js +52 -24
- package/dist/shared/lib/skeleton-shapes.js +72 -0
- package/dist/shared/lib/slow-reason.js +63 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -120,6 +120,164 @@ declare interface ActiveLayoutData {
|
|
|
120
120
|
ungrouped_sort?: number | null;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
/** Who really did it (nivaro_activity.actor, migration 516; derived for older rows). */
|
|
124
|
+
declare interface ActivityActor {
|
|
125
|
+
kind: ActivityActorKind;
|
|
126
|
+
/** view_as: the admin; api_key: the key id; mcp: the connection; import: the definition
|
|
127
|
+
* key; flow: the flow id; cron: the job id. */
|
|
128
|
+
id?: string | null;
|
|
129
|
+
name?: string | null;
|
|
130
|
+
/** The person the actor acted for / as (view_as: the person being viewed as). */
|
|
131
|
+
on_behalf_of?: string | null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Activity sentences — one readable line per audit-trail entry.
|
|
136
|
+
*
|
|
137
|
+
* "Pat moved PO 4471 from Draft to Approved"
|
|
138
|
+
* "Sam deleted 3 invoices"
|
|
139
|
+
* "Rob as Pat changed Vendor on Workflow 85607"
|
|
140
|
+
* "Pat updated 40 workflows: Status → On Hold"
|
|
141
|
+
*
|
|
142
|
+
* Pure (no imports, no I/O): the Activity page, the activity detail page, the
|
|
143
|
+
* record history panels and the email digest all render through it. Labels
|
|
144
|
+
* come from POST /api/activity/labels (records read AS THE READER — a record
|
|
145
|
+
* the reader cannot see is "a record you can't see"; people by name;
|
|
146
|
+
* collection / field / choice labels); until they arrive the sentence falls
|
|
147
|
+
* back to the collection name and the stored id.
|
|
148
|
+
*
|
|
149
|
+
* TWIN FILE: packages/shared/src/lib/activity-sentence.ts and
|
|
150
|
+
* api/src/services/activity-sentence.ts must stay byte-identical (the API
|
|
151
|
+
* cannot import packages/shared; an API test compares the two files).
|
|
152
|
+
*/
|
|
153
|
+
declare type ActivityActorKind = 'person' | 'view_as' | 'api_key' | 'mcp' | 'import' | 'flow' | 'cron' | 'system';
|
|
154
|
+
|
|
155
|
+
/** A linked approval decision the read API joined onto the entry. */
|
|
156
|
+
declare interface ActivityApproval {
|
|
157
|
+
decision: string;
|
|
158
|
+
comment?: string | null;
|
|
159
|
+
chain?: string | null;
|
|
160
|
+
step?: string | number | null;
|
|
161
|
+
collection?: string | null;
|
|
162
|
+
item?: string | null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** A field change the read API summarised from the revision delta. */
|
|
166
|
+
declare interface ActivityChange {
|
|
167
|
+
field: string;
|
|
168
|
+
value?: unknown;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export declare function ActivityEntry({ entry, labels, group, onOpen, actions, showTime, className }: ActivityEntryProps): JSX.Element;
|
|
172
|
+
|
|
173
|
+
export declare interface ActivityEntryInput {
|
|
174
|
+
id?: number | string | null;
|
|
175
|
+
action: string | null;
|
|
176
|
+
/** The person (nivaro_activity.user); revisions call it user_id. */
|
|
177
|
+
user?: string | null;
|
|
178
|
+
user_id?: string | null;
|
|
179
|
+
first_name?: string | null;
|
|
180
|
+
last_name?: string | null;
|
|
181
|
+
user_email?: string | null;
|
|
182
|
+
collection?: string | null;
|
|
183
|
+
item?: string | number | null;
|
|
184
|
+
comment?: string | null;
|
|
185
|
+
timestamp?: string | Date | null;
|
|
186
|
+
origin?: string | null;
|
|
187
|
+
chain_parent?: string | null;
|
|
188
|
+
auth_method?: string | null;
|
|
189
|
+
api_key_id?: number | string | null;
|
|
190
|
+
api_key_name?: string | null;
|
|
191
|
+
mcp_conn?: string | null;
|
|
192
|
+
via_app?: string | null;
|
|
193
|
+
via_agent?: string | null;
|
|
194
|
+
group_key?: string | null;
|
|
195
|
+
/** Stored JSON (string) or the parsed object. */
|
|
196
|
+
actor?: ActivityActor | string | null;
|
|
197
|
+
changes?: ActivityChange[] | null;
|
|
198
|
+
changed_fields?: string[] | null;
|
|
199
|
+
delta?: Record<string, unknown> | null;
|
|
200
|
+
/** A pipeline event folded into a record's history (services/revisions.ts). */
|
|
201
|
+
event?: {
|
|
202
|
+
kind: 'transition' | 'start';
|
|
203
|
+
from_label?: string | null;
|
|
204
|
+
to_label?: string | null;
|
|
205
|
+
transition_label?: string | null;
|
|
206
|
+
source?: string | null;
|
|
207
|
+
on_behalf_of?: {
|
|
208
|
+
id: string;
|
|
209
|
+
name: string | null;
|
|
210
|
+
} | null;
|
|
211
|
+
addendum?: {
|
|
212
|
+
id: string;
|
|
213
|
+
title: string | null;
|
|
214
|
+
} | null;
|
|
215
|
+
} | null;
|
|
216
|
+
why?: ActivityWhy | null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* One audit-trail entry as a sentence ("Pat moved PO 4471 from Draft to Approved"), who
|
|
221
|
+
* really did it (View-as, API key, assistant, import, flow, scheduled job), why (change
|
|
222
|
+
* reason, transition note, linked approval) and when, in the reader's time zone. A burst
|
|
223
|
+
* (`group` with more than one entry: one bulk action, import run, flow run, MCP request…)
|
|
224
|
+
* reads as one line that expands to its entries.
|
|
225
|
+
*
|
|
226
|
+
* `actions` is a slot rendered at the row's end (Undo, Open…). Labels come from
|
|
227
|
+
* `useActivityLabels` (POST /api/activity/labels, read as the viewer).
|
|
228
|
+
*/
|
|
229
|
+
export declare interface ActivityEntryProps {
|
|
230
|
+
entry: ActivityEntryInput;
|
|
231
|
+
labels?: ActivityLabels | null;
|
|
232
|
+
/** The entry's whole burst, newest first (the entry itself included). */
|
|
233
|
+
group?: ActivityEntryInput[];
|
|
234
|
+
onOpen?: (entry: ActivityEntryInput) => void;
|
|
235
|
+
actions?: ReactNode;
|
|
236
|
+
/** Show the time at the row's end (default true). */
|
|
237
|
+
showTime?: boolean;
|
|
238
|
+
className?: string;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** A list of entries with bursts folded (groupActivity) — each group one ActivityEntry. */
|
|
242
|
+
export declare function ActivityFeed({ entries, labels, onOpen, actionsFor, empty, className }: {
|
|
243
|
+
entries: ActivityEntryInput[];
|
|
244
|
+
labels?: ActivityLabels | null;
|
|
245
|
+
onOpen?: (entry: ActivityEntryInput) => void;
|
|
246
|
+
/** The `actions` slot for a group's head entry. */
|
|
247
|
+
actionsFor?: (group: ActivityGroup) => ReactNode;
|
|
248
|
+
empty?: ReactNode;
|
|
249
|
+
className?: string;
|
|
250
|
+
}): JSX.Element;
|
|
251
|
+
|
|
252
|
+
declare interface ActivityGroup<T extends ActivityEntryInput = ActivityEntryInput> {
|
|
253
|
+
/** Stable React key. */
|
|
254
|
+
key: string;
|
|
255
|
+
/** Newest first, as given. */
|
|
256
|
+
entries: T[];
|
|
257
|
+
/** 'group_key' = written by one bulk action / import / flow / cron / batch / MCP request;
|
|
258
|
+
* 'time' = same actor + collection + action within the window (rows before 516). */
|
|
259
|
+
by: 'group_key' | 'time' | null;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** What POST /api/activity/labels answers (plus the reader's time zone, if any). */
|
|
263
|
+
export declare interface ActivityLabels {
|
|
264
|
+
/** Person id (any case) → display name. */
|
|
265
|
+
users?: Record<string, string>;
|
|
266
|
+
/** `collection:id` → label; null = the reader cannot see that record. */
|
|
267
|
+
records?: Record<string, string | null>;
|
|
268
|
+
/** Collection → names (or a bare display name). */
|
|
269
|
+
collections?: Record<string, CollectionNames | string>;
|
|
270
|
+
/** `collection.field` → field label. */
|
|
271
|
+
fields?: Record<string, string>;
|
|
272
|
+
/** `collection.field` → stored value → choice label. */
|
|
273
|
+
choices?: Record<string, Record<string, string>>;
|
|
274
|
+
/** `collection.field` → the collection a link field points at. Link values are ids, so a
|
|
275
|
+
* sentence names the field, never the raw value. */
|
|
276
|
+
links?: Record<string, string>;
|
|
277
|
+
/** IANA zone dates in values render in; unset = the runtime's own zone. */
|
|
278
|
+
timeZone?: string | null;
|
|
279
|
+
}
|
|
280
|
+
|
|
123
281
|
/** A stretch of the recording where the author was typing in a text field,
|
|
124
282
|
* or touched nothing at all (#1518). Never what was typed. */
|
|
125
283
|
declare type ActivitySpan = {
|
|
@@ -128,6 +286,25 @@ declare type ActivitySpan = {
|
|
|
128
286
|
end_ms: number;
|
|
129
287
|
};
|
|
130
288
|
|
|
289
|
+
/** The "why" the read API joins onto an entry (#5): reason, note, approval. */
|
|
290
|
+
declare interface ActivityWhy {
|
|
291
|
+
/** The change reason a person gave for a create / update / delete. */
|
|
292
|
+
reason?: string | null;
|
|
293
|
+
/** What a person wrote on a transition. */
|
|
294
|
+
note?: string | null;
|
|
295
|
+
approval?: ActivityApproval | null;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** The entry's "why" as short lines: change reason, transition note, approval. */
|
|
299
|
+
export declare function activityWhy(entry: ActivityEntryInput): {
|
|
300
|
+
reason: string | null;
|
|
301
|
+
note: string | null;
|
|
302
|
+
approval: string | null;
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
/** "Pat", "Rob as Pat", "API key “Partner sync”", "Claude for Pat", "Import “Vendors”". */
|
|
306
|
+
export declare function actorName(entry: ActivityEntryInput, labels?: ActivityLabels | null): string;
|
|
307
|
+
|
|
131
308
|
export declare function AddendumPanel({ collection, item, addendumLayoutId, canCreate, onActiveCountChange, onApplied, onCreated, defaultExpanded }: {
|
|
132
309
|
collection: string;
|
|
133
310
|
item: string;
|
|
@@ -786,6 +963,9 @@ export declare interface BackgroundRequest {
|
|
|
786
963
|
* then offers to hand the read to the server. While the server runs it, the strip shows elapsed
|
|
787
964
|
* time against the usual time; when the result is ready it fills the page's own query and the
|
|
788
965
|
* strip goes away. Every state is inline — no dialog.
|
|
966
|
+
*
|
|
967
|
+
* #3231 — from ~3 s it also says what the read is waiting on ("Waiting for a free slot — busy
|
|
968
|
+
* right now", "Running PUB health — not cached yet"), before and beside the offer.
|
|
789
969
|
*/
|
|
790
970
|
export declare function BackgroundRunOffer({ className, ...opts }: UseBackgroundRunOptions & {
|
|
791
971
|
className?: string;
|
|
@@ -1052,6 +1232,20 @@ export declare function captureMaskedScreenshot(opts?: {
|
|
|
1052
1232
|
|
|
1053
1233
|
export declare function captureReplayClip(kind?: ReplayClipKind, timeoutMs?: number): Promise<ReplayLink | null>;
|
|
1054
1234
|
|
|
1235
|
+
/**
|
|
1236
|
+
* A card placeholder: optional title row, a KPI figure, a chart block or text lines — the shape
|
|
1237
|
+
* of the card that is coming.
|
|
1238
|
+
*/
|
|
1239
|
+
export declare function CardSkeleton({ title, kpi, chart, lines, className, framed }: {
|
|
1240
|
+
title?: boolean;
|
|
1241
|
+
kpi?: boolean;
|
|
1242
|
+
chart?: boolean;
|
|
1243
|
+
lines?: number;
|
|
1244
|
+
className?: string;
|
|
1245
|
+
/** false = no border/background (the host already draws the card). */
|
|
1246
|
+
framed?: boolean;
|
|
1247
|
+
}): JSX.Element;
|
|
1248
|
+
|
|
1055
1249
|
export { CascadeFilterRule }
|
|
1056
1250
|
|
|
1057
1251
|
declare type CascadeRule = {
|
|
@@ -1111,6 +1305,17 @@ declare interface CellFilterLite {
|
|
|
1111
1305
|
id_value?: number | null;
|
|
1112
1306
|
}
|
|
1113
1307
|
|
|
1308
|
+
/**
|
|
1309
|
+
* Shape-matched loading placeholders (#3229) — the pure half.
|
|
1310
|
+
*
|
|
1311
|
+
* A placeholder takes the shape of what is coming: a list's real columns (a date column gets a
|
|
1312
|
+
* date-sized bar, a status column a pill, a number is right-aligned), a record form's real
|
|
1313
|
+
* sections and field widths when its layout is known before the record, a card's header and
|
|
1314
|
+
* lines. Widths are deterministic per (row, column) so a skeleton never flickers between renders.
|
|
1315
|
+
* The components live in components/Skeletons.tsx.
|
|
1316
|
+
*/
|
|
1317
|
+
declare type CellShape = 'text' | 'long' | 'short' | 'number' | 'date' | 'badge' | 'avatar' | 'bool';
|
|
1318
|
+
|
|
1114
1319
|
/** Shape of the 422 CHANGE_REASON_REQUIRED challenge from the items service. */
|
|
1115
1320
|
export declare interface ChangeReasonChallenge {
|
|
1116
1321
|
fields_changed: string[];
|
|
@@ -1890,6 +2095,11 @@ export declare function CollectionImportPanel({ initialJobId, onJobOpen }: {
|
|
|
1890
2095
|
onJobOpen?: (id: string | null) => void;
|
|
1891
2096
|
}): JSX.Element;
|
|
1892
2097
|
|
|
2098
|
+
declare interface CollectionNames {
|
|
2099
|
+
singular?: string | null;
|
|
2100
|
+
plural?: string | null;
|
|
2101
|
+
}
|
|
2102
|
+
|
|
1893
2103
|
/**
|
|
1894
2104
|
* Realtime sprint client contract. A HOST (admin, a portal app) owns the actual
|
|
1895
2105
|
* Socket.io connection and provides this to shared components; components
|
|
@@ -2044,6 +2254,9 @@ export declare function ConformanceView({ className }: {
|
|
|
2044
2254
|
className?: string;
|
|
2045
2255
|
}): JSX.Element;
|
|
2046
2256
|
|
|
2257
|
+
/** Pure: may this connection prefetch? Not when it asks to save data or is 2g-slow. */
|
|
2258
|
+
export declare function connectionAllowsPrefetch(c: NetInfo | null | undefined): boolean;
|
|
2259
|
+
|
|
2047
2260
|
/**
|
|
2048
2261
|
* "Copy as …" (#654): the request behind a list or a record, as a curl
|
|
2049
2262
|
* command, an SDK call and a GraphQL document, each ready to paste. The
|
|
@@ -2480,6 +2693,20 @@ declare interface DisplayPrefs {
|
|
|
2480
2693
|
|
|
2481
2694
|
export declare function DisplayPrefsCard(): JSX.Element;
|
|
2482
2695
|
|
|
2696
|
+
/**
|
|
2697
|
+
* The crumbs to show: walk back from the current page, newest first, skipping
|
|
2698
|
+
* the current page itself and repeats (the NEWEST visit of a page wins — the
|
|
2699
|
+
* fewest steps back), and stop after the first "root" page (a list or hub the
|
|
2700
|
+
* person started from) or `max` crumbs. Oldest first.
|
|
2701
|
+
*/
|
|
2702
|
+
export declare function displayTrail(chain: TrailEntry[], current: {
|
|
2703
|
+
idx: number;
|
|
2704
|
+
path: string;
|
|
2705
|
+
}, opts?: {
|
|
2706
|
+
isRoot?: (pathname: string) => boolean;
|
|
2707
|
+
max?: number;
|
|
2708
|
+
}): TrailCrumb[];
|
|
2709
|
+
|
|
2483
2710
|
declare type DmOpener = (userId: string, displayName?: string) => void;
|
|
2484
2711
|
|
|
2485
2712
|
export declare function dmPeer(room: string, self: string): string | null;
|
|
@@ -2782,6 +3009,8 @@ export declare interface ErpSubmission {
|
|
|
2782
3009
|
* A record page hosting its OWN External requests dialog already IS that
|
|
2783
3010
|
* record, so it never needs this badge and doesn't send it. */
|
|
2784
3011
|
record_label?: string;
|
|
3012
|
+
/** #18 — a failed push in plain words + Fix it target (null when it did not fail). */
|
|
3013
|
+
explanation?: IntegrationErrorExplanation | null;
|
|
2785
3014
|
}
|
|
2786
3015
|
|
|
2787
3016
|
export declare interface ErrorReplayLink {
|
|
@@ -3248,8 +3477,14 @@ export declare const FORCE_RELOAD_EVENT = "nvr:force-refresh";
|
|
|
3248
3477
|
* Unsaved work (lib/unsaved-work.ts) holds the reload: past the deadline the
|
|
3249
3478
|
* banner says a reload is waiting and reloads the moment the edits are saved
|
|
3250
3479
|
* or discarded — or when the person clicks Reload now.
|
|
3480
|
+
*
|
|
3481
|
+
* Reload old tabs when idle (#2937): the banner also mounts IdleReloadWatcher, so a tab left on an
|
|
3482
|
+
* older build after a release reloads by itself once idle (no countdown, no banner). Pass
|
|
3483
|
+
* `idleReload={false}` to leave that out.
|
|
3251
3484
|
*/
|
|
3252
|
-
export declare function ForceReloadBanner(
|
|
3485
|
+
export declare function ForceReloadBanner({ idleReload }?: {
|
|
3486
|
+
idleReload?: boolean;
|
|
3487
|
+
}): JSX.Element;
|
|
3253
3488
|
|
|
3254
3489
|
/**
|
|
3255
3490
|
* Sticky force refresh — the client half of api/src/services/sticky-refresh.ts.
|
|
@@ -3386,6 +3621,45 @@ export declare type FormSchema = {
|
|
|
3386
3621
|
slotAssignments: FormSlotAssignment[];
|
|
3387
3622
|
};
|
|
3388
3623
|
|
|
3624
|
+
/**
|
|
3625
|
+
* A record form placeholder. With a plan (formSkeletonFromLayout) it paints the form's own tabs,
|
|
3626
|
+
* section titles and field grid; without one, two generic sections.
|
|
3627
|
+
*/
|
|
3628
|
+
export declare function FormSkeleton({ plan, className }: {
|
|
3629
|
+
plan: FormSkeletonPlan | null;
|
|
3630
|
+
className?: string;
|
|
3631
|
+
}): JSX.Element;
|
|
3632
|
+
|
|
3633
|
+
declare interface FormSkeletonField {
|
|
3634
|
+
key: string;
|
|
3635
|
+
/** Grid span out of 12. */
|
|
3636
|
+
span: number;
|
|
3637
|
+
/** A grid, widget or slot block (taller than an input). */
|
|
3638
|
+
tall?: boolean;
|
|
3639
|
+
}
|
|
3640
|
+
|
|
3641
|
+
/**
|
|
3642
|
+
* The resolved layout (GET /collection-layouts/active) → the sections and field widths the form
|
|
3643
|
+
* will paint. Null when there is no layout (the caller shows a generic form placeholder).
|
|
3644
|
+
*/
|
|
3645
|
+
export declare function formSkeletonFromLayout(layout: LayoutLike | null | undefined, opts?: {
|
|
3646
|
+
isNew?: boolean;
|
|
3647
|
+
maxSections?: number;
|
|
3648
|
+
maxFields?: number;
|
|
3649
|
+
}): FormSkeletonPlan | null;
|
|
3650
|
+
|
|
3651
|
+
export declare interface FormSkeletonPlan {
|
|
3652
|
+
/** Tab labels, when the form opens on tabs (the first is the one that shows). */
|
|
3653
|
+
tabs: string[];
|
|
3654
|
+
sections: FormSkeletonSection[];
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3657
|
+
declare interface FormSkeletonSection {
|
|
3658
|
+
key: string;
|
|
3659
|
+
label: string | null;
|
|
3660
|
+
fields: FormSkeletonField[];
|
|
3661
|
+
}
|
|
3662
|
+
|
|
3389
3663
|
export declare type FormSlotAssignment = {
|
|
3390
3664
|
slot: string;
|
|
3391
3665
|
groupKey: string | null;
|
|
@@ -3591,6 +3865,16 @@ declare interface GridSumCapConfig {
|
|
|
3591
3865
|
message?: string;
|
|
3592
3866
|
}
|
|
3593
3867
|
|
|
3868
|
+
/**
|
|
3869
|
+
* Folds consecutive entries of one burst into one group. Entries sharing a
|
|
3870
|
+
* group_key always fold; entries without one fold when the same actor did the
|
|
3871
|
+
* same action on the same collection, each within `windowMs` of the previous
|
|
3872
|
+
* (rows from before migration 516). Order is kept; singles are groups of one.
|
|
3873
|
+
*/
|
|
3874
|
+
export declare function groupActivity<T extends ActivityEntryInput>(entries: T[], opts?: {
|
|
3875
|
+
windowMs?: number;
|
|
3876
|
+
}): ActivityGroup<T>[];
|
|
3877
|
+
|
|
3594
3878
|
/**
|
|
3595
3879
|
* Run one identity call through the gate: `blocked()` answers without a request while the tab
|
|
3596
3880
|
* is signed out (outside its probe window); a success opens the gate, a signed-out 401 closes it.
|
|
@@ -3891,6 +4175,13 @@ export declare interface HelpVideoDto {
|
|
|
3891
4175
|
* the page. Null when nothing was found or an author dismissed it;
|
|
3892
4176
|
* publishing clears it. Optional: older servers. */
|
|
3893
4177
|
stale?: HelpVideoStale | null;
|
|
4178
|
+
/** #18, GET /help-videos/for only: how the video matched the screen — tier
|
|
4179
|
+
* 0 step, 1 screen, 2 screens like it, 3 record type, 4 area, 5 a term on
|
|
4180
|
+
* the screen. Optional: older servers. */
|
|
4181
|
+
match?: {
|
|
4182
|
+
tier: number;
|
|
4183
|
+
reason: string;
|
|
4184
|
+
};
|
|
3894
4185
|
}
|
|
3895
4186
|
|
|
3896
4187
|
export declare function HelpVideoEditor({ videoId, onClose }: {
|
|
@@ -3935,6 +4226,28 @@ export declare function HelpVideoLibrary({ watchId, editId, onWatch, onEdit, hea
|
|
|
3935
4226
|
headerExtra?: React.ReactNode;
|
|
3936
4227
|
}): JSX.Element;
|
|
3937
4228
|
|
|
4229
|
+
/**
|
|
4230
|
+
* #18 — "Watch: How to submit an IR (2:10)": the screen's best help video,
|
|
4231
|
+
* when there is a strong match the person has not finished. Renders nothing
|
|
4232
|
+
* otherwise (no wrapper either), so a host can mount it in its header area
|
|
4233
|
+
* unconditionally. × hides that video's chip for good (this browser).
|
|
4234
|
+
*
|
|
4235
|
+
* Hosts pass the route (`path`) and, when they have one, their page key /
|
|
4236
|
+
* record context; the server ranks screen → screens like it → record type →
|
|
4237
|
+
* area → glossary terms (GET /help-videos/for).
|
|
4238
|
+
*/
|
|
4239
|
+
export declare function HelpVideoMatchChip({ path, app, page, collection, item, terms, className }: {
|
|
4240
|
+
path: string;
|
|
4241
|
+
app?: string;
|
|
4242
|
+
page?: string;
|
|
4243
|
+
collection?: string;
|
|
4244
|
+
item?: string | number;
|
|
4245
|
+
/** Glossary terms the screen shows. */
|
|
4246
|
+
terms?: string[];
|
|
4247
|
+
/** Classes for the wrapper, which only renders when a chip shows. */
|
|
4248
|
+
className?: string;
|
|
4249
|
+
}): JSX.Element;
|
|
4250
|
+
|
|
3938
4251
|
/** Keyed by video id: switching to another video starts a fresh player, so
|
|
3939
4252
|
* progress, the resume point and the one-retry flag never carry over. */
|
|
3940
4253
|
export declare function HelpVideoPlayer(props: HelpVideoPlayerProps): JSX.Element;
|
|
@@ -4147,6 +4460,16 @@ export declare function huddleHolds(prefs: Record<string, unknown> | null | unde
|
|
|
4147
4460
|
/** Time without real input before someone counts as idle. */
|
|
4148
4461
|
export declare const IDLE_AFTER_MS: number;
|
|
4149
4462
|
|
|
4463
|
+
/**
|
|
4464
|
+
* Reload old tabs when idle (#2937) — renders nothing. Mounted by ForceReloadBanner, so every
|
|
4465
|
+
* host that shows pushed reloads also gets this. The decision is lib/idle-reload.ts
|
|
4466
|
+
* `decideIdleReload` (pure, tested); this only feeds it and acts on it.
|
|
4467
|
+
*
|
|
4468
|
+
* Asks GET /realtime/build-status through the host's NivaroClient when there is one, else the
|
|
4469
|
+
* same-origin /api (admin mounts the banner outside its NivaroProvider).
|
|
4470
|
+
*/
|
|
4471
|
+
export declare function IdleReloadWatcher(): null;
|
|
4472
|
+
|
|
4150
4473
|
/** The fields a presence heartbeat should carry. */
|
|
4151
4474
|
export declare function idleState(): {
|
|
4152
4475
|
is_idle: boolean;
|
|
@@ -4634,8 +4957,9 @@ declare interface InputBinding {
|
|
|
4634
4957
|
export declare function installClientChaosFetch(): void;
|
|
4635
4958
|
|
|
4636
4959
|
/**
|
|
4637
|
-
* Document-level intent listener: resting on (or keyboard-focusing) a same-origin link
|
|
4638
|
-
*
|
|
4960
|
+
* Document-level intent listener: resting on (or keyboard-focusing) a same-origin link preloads
|
|
4961
|
+
* its screen's code; a record link also warms the record, a list link the list's metadata.
|
|
4962
|
+
* Leaving the link before pressing it cancels what it started. Returns the uninstaller.
|
|
4639
4963
|
*/
|
|
4640
4964
|
export declare function installIntentPrefetch(opts: IntentPrefetchOptions): () => void;
|
|
4641
4965
|
|
|
@@ -4661,6 +4985,17 @@ export declare interface IntegrationDotsProps {
|
|
|
4661
4985
|
className?: string;
|
|
4662
4986
|
}
|
|
4663
4987
|
|
|
4988
|
+
declare interface IntegrationErrorExplanation {
|
|
4989
|
+
sentence: string;
|
|
4990
|
+
cause: string;
|
|
4991
|
+
fix_label: string | null;
|
|
4992
|
+
fix: IntegrationFixTarget | null;
|
|
4993
|
+
fix_link: string | null;
|
|
4994
|
+
field: string | null;
|
|
4995
|
+
detail: string | null;
|
|
4996
|
+
rule: string;
|
|
4997
|
+
}
|
|
4998
|
+
|
|
4664
4999
|
/**
|
|
4665
5000
|
* One entry of the integration events feed. The cross-record feed carries
|
|
4666
5001
|
* `provider`; the per-record feed (GET /integration-events/record/...) carries
|
|
@@ -4718,6 +5053,25 @@ export declare type IntegrationEventPathTarget = {
|
|
|
4718
5053
|
chainId: string;
|
|
4719
5054
|
};
|
|
4720
5055
|
|
|
5056
|
+
/** GET answers' `explanation` (api services/integration-error-explain.ts). */
|
|
5057
|
+
declare type IntegrationFixTarget = {
|
|
5058
|
+
kind: 'record';
|
|
5059
|
+
collection: string;
|
|
5060
|
+
item: string;
|
|
5061
|
+
field?: string | null;
|
|
5062
|
+
} | {
|
|
5063
|
+
kind: 'external_api';
|
|
5064
|
+
id: number;
|
|
5065
|
+
section?: 'auth' | 'endpoints' | 'connection' | 'response' | null;
|
|
5066
|
+
} | {
|
|
5067
|
+
kind: 'partner';
|
|
5068
|
+
id: number;
|
|
5069
|
+
} | {
|
|
5070
|
+
kind: 'payload_template';
|
|
5071
|
+
api_id: number;
|
|
5072
|
+
key: string;
|
|
5073
|
+
};
|
|
5074
|
+
|
|
4721
5075
|
export declare function IntegrationObligationsView({ api, className }: IntegrationObligationsViewProps): JSX.Element;
|
|
4722
5076
|
|
|
4723
5077
|
export declare interface IntegrationObligationsViewProps {
|
|
@@ -4915,10 +5269,6 @@ export declare interface IntegrationsConsoleTab {
|
|
|
4915
5269
|
render: () => ReactNode;
|
|
4916
5270
|
}
|
|
4917
5271
|
|
|
4918
|
-
/**
|
|
4919
|
-
* HTTP shapes served by GET /integration-signals and /integration-partners —
|
|
4920
|
-
* copied from the core routes so the shared package never imports api code.
|
|
4921
|
-
*/
|
|
4922
5272
|
export declare interface IntegrationSignalAction {
|
|
4923
5273
|
kind: 'retry_submission' | 'resend' | 'open' | 'explain' | 'extension';
|
|
4924
5274
|
label: string;
|
|
@@ -4984,12 +5334,29 @@ declare interface IntentPrefetchOptions {
|
|
|
4984
5334
|
client: NivaroClient | null;
|
|
4985
5335
|
/** A link's same-origin path → the record it opens, or null. */
|
|
4986
5336
|
matchRecord?: (path: string) => RecordTarget | null;
|
|
5337
|
+
/** A link's same-origin path → the collection list it opens, or null (#3230). */
|
|
5338
|
+
matchList?: (path: string) => string | null;
|
|
4987
5339
|
/** Load the code for the screen a same-origin path opens. */
|
|
4988
5340
|
preloadRoute?: (path: string) => void;
|
|
4989
5341
|
/** Only links inside this element (default: the whole document). */
|
|
4990
5342
|
root?: HTMLElement | Document;
|
|
4991
5343
|
}
|
|
4992
5344
|
|
|
5345
|
+
export declare interface IntentProps {
|
|
5346
|
+
onPointerEnter: () => void;
|
|
5347
|
+
onPointerLeave: () => void;
|
|
5348
|
+
onPointerDown: () => void;
|
|
5349
|
+
onFocus: () => void;
|
|
5350
|
+
onBlur: () => void;
|
|
5351
|
+
}
|
|
5352
|
+
|
|
5353
|
+
/**
|
|
5354
|
+
* Handlers that turn resting on (or focusing) an element into `act()` after INTENT_DWELL_MS,
|
|
5355
|
+
* and leaving it into a cancel of what `act` started (unless it was pressed). `group` names the
|
|
5356
|
+
* intent (e.g. `record:projects:7`); `act` must start its prefetches under that group.
|
|
5357
|
+
*/
|
|
5358
|
+
export declare function intentProps(group: string, act: () => number | boolean | undefined): IntentProps;
|
|
5359
|
+
|
|
4993
5360
|
/** A title card before the recording (real extra edited time). Blank
|
|
4994
5361
|
* `title` / `subtitle` mean the video's title and the first line of its
|
|
4995
5362
|
* description. */
|
|
@@ -5283,6 +5650,12 @@ declare interface JsonMapEditorConfig {
|
|
|
5283
5650
|
};
|
|
5284
5651
|
}
|
|
5285
5652
|
|
|
5653
|
+
/**
|
|
5654
|
+
* A total the person has already seen for this list, from any cached page of it (search, sort
|
|
5655
|
+
* and filters aside) — so "Reading 48,000 invoices" never counts rows they cannot see.
|
|
5656
|
+
*/
|
|
5657
|
+
export declare function knownTotalFrom(entries: ReadonlyArray<readonly [unknown, unknown]>): number | null;
|
|
5658
|
+
|
|
5286
5659
|
declare interface LadderTier {
|
|
5287
5660
|
after_hours: number;
|
|
5288
5661
|
notify: string;
|
|
@@ -5311,6 +5684,15 @@ declare interface LayoutAssignment {
|
|
|
5311
5684
|
default_expanded?: boolean | number | null;
|
|
5312
5685
|
}
|
|
5313
5686
|
|
|
5687
|
+
declare interface LayoutAssignmentLike {
|
|
5688
|
+
field: string;
|
|
5689
|
+
sort?: number | null;
|
|
5690
|
+
group_key?: string | null;
|
|
5691
|
+
col_span?: number | null;
|
|
5692
|
+
is_visible?: boolean | number | null;
|
|
5693
|
+
widget_id?: number | null;
|
|
5694
|
+
}
|
|
5695
|
+
|
|
5314
5696
|
declare interface LayoutDesign {
|
|
5315
5697
|
selected: DesignTarget | null;
|
|
5316
5698
|
onSelect(t: DesignTarget, opts?: SelectOptions): void;
|
|
@@ -5382,10 +5764,15 @@ declare interface LayoutDesignProp {
|
|
|
5382
5764
|
*
|
|
5383
5765
|
* Zero CSS shipped — style via className props or data-* attributes.
|
|
5384
5766
|
*/
|
|
5385
|
-
export declare function LayoutForm({ form, components, className, style, sectionClassName, tabStripClassName, activeTabClassName, inactiveTabClassName, gridClassName, slotRenderers, itemId, stepperClassName, stepNavClassName, prevButtonClassName, nextButtonClassName, lastStepActions, layoutSlug: _layoutSlug }: LayoutFormProps): default_2.JSX.Element | null;
|
|
5767
|
+
export declare function LayoutForm({ form, components, className, style, sectionClassName, tabStripClassName, activeTabClassName, inactiveTabClassName, gridClassName, slotRenderers, itemId, stepperClassName, stepNavClassName, prevButtonClassName, nextButtonClassName, lastStepActions, layoutSlug: _layoutSlug, loadingFallback }: LayoutFormProps): string | number | bigint | boolean | default_2.JSX.Element | Iterable<default_2.ReactNode> | Promise<string | number | bigint | boolean | default_2.ReactPortal | default_2.ReactElement<unknown, string | default_2.JSXElementConstructor<any>> | Iterable<default_2.ReactNode> | null | undefined> | null;
|
|
5386
5768
|
|
|
5387
5769
|
declare type LayoutFormProps = {
|
|
5388
5770
|
form: UseNivaroFormReturn;
|
|
5771
|
+
/**
|
|
5772
|
+
* #3229 — shown while the schema or the record is still loading (default: nothing, the form
|
|
5773
|
+
* stays headless). Pass a shape-matched placeholder, e.g. `<FormSkeleton plan={…} />`.
|
|
5774
|
+
*/
|
|
5775
|
+
loadingFallback?: default_2.ReactNode;
|
|
5389
5776
|
components?: ComponentOverrides;
|
|
5390
5777
|
/** CSS class applied to the <form> element */
|
|
5391
5778
|
className?: string;
|
|
@@ -5453,8 +5840,24 @@ declare interface LayoutGroup {
|
|
|
5453
5840
|
summary_hide_empty?: boolean | number | null;
|
|
5454
5841
|
}
|
|
5455
5842
|
|
|
5843
|
+
declare interface LayoutGroupLike {
|
|
5844
|
+
id?: number | null;
|
|
5845
|
+
key: string;
|
|
5846
|
+
label?: string | null;
|
|
5847
|
+
type?: string | null;
|
|
5848
|
+
sort?: number | null;
|
|
5849
|
+
container_id?: number | null;
|
|
5850
|
+
visibility_mode?: string | null;
|
|
5851
|
+
}
|
|
5852
|
+
|
|
5456
5853
|
export declare type LayoutItem = FormGroupDescriptor | '__ungrouped__';
|
|
5457
5854
|
|
|
5855
|
+
declare interface LayoutLike {
|
|
5856
|
+
groups?: LayoutGroupLike[] | null;
|
|
5857
|
+
assignments?: LayoutAssignmentLike[] | null;
|
|
5858
|
+
ungrouped_sort?: number | null;
|
|
5859
|
+
}
|
|
5860
|
+
|
|
5458
5861
|
declare interface LayoutMeta {
|
|
5459
5862
|
id: number;
|
|
5460
5863
|
name: string;
|
|
@@ -5588,6 +5991,11 @@ export declare function ListLoadError({ error, onRetry, className }: {
|
|
|
5588
5991
|
*/
|
|
5589
5992
|
export declare function listLoadErrorText(err: unknown): string;
|
|
5590
5993
|
|
|
5994
|
+
/** The query key a collection list (CollectionBrowserView) reads its metadata under. */
|
|
5995
|
+
export declare function listQueryKeys(collection: string): {
|
|
5996
|
+
meta: QueryKey;
|
|
5997
|
+
};
|
|
5998
|
+
|
|
5591
5999
|
/**
|
|
5592
6000
|
* "Copy as …" (#654): the request a list or record view is making, rendered
|
|
5593
6001
|
* as a curl command, an SDK call and a GraphQL document. Pure — no client,
|
|
@@ -5606,6 +6014,22 @@ declare interface ListRequest {
|
|
|
5606
6014
|
page?: number;
|
|
5607
6015
|
}
|
|
5608
6016
|
|
|
6017
|
+
/**
|
|
6018
|
+
* A whole list placeholder for surfaces without a real header yet: a header strip (real labels
|
|
6019
|
+
* when given) and rows at the real row height, one bar per column.
|
|
6020
|
+
*/
|
|
6021
|
+
export declare function ListSkeleton({ columns, rows, header, rowClassName, className }: {
|
|
6022
|
+
columns: readonly (SkeletonColumn & {
|
|
6023
|
+
label?: ReactNode;
|
|
6024
|
+
grow?: number;
|
|
6025
|
+
})[];
|
|
6026
|
+
rows?: number;
|
|
6027
|
+
/** false = no header strip. */
|
|
6028
|
+
header?: boolean;
|
|
6029
|
+
rowClassName?: string;
|
|
6030
|
+
className?: string;
|
|
6031
|
+
}): JSX.Element;
|
|
6032
|
+
|
|
5609
6033
|
/**
|
|
5610
6034
|
* Query-key heads of surfaces that keep themselves live with their own socket handlers (record
|
|
5611
6035
|
* pages — RECORD_QUERY_HEADS in item-edit/RecordLiveSync — the collection browser's row reads,
|
|
@@ -5977,6 +6401,11 @@ declare interface MatrixEditorConfig {
|
|
|
5977
6401
|
};
|
|
5978
6402
|
}
|
|
5979
6403
|
|
|
6404
|
+
/** Prefetch requests one tab runs at once; the rest wait their turn. */
|
|
6405
|
+
export declare const MAX_PREFETCH_IN_FLIGHT = 2;
|
|
6406
|
+
|
|
6407
|
+
declare type MaybeIntent = IntentProps | Record<string, never>;
|
|
6408
|
+
|
|
5980
6409
|
/**
|
|
5981
6410
|
* The offset from a few samples: the server stamped its answer somewhere inside the round
|
|
5982
6411
|
* trip, so assume the midpoint, and trust the sample with the shortest round trip (the least
|
|
@@ -6137,6 +6566,11 @@ export declare type NavigationContextValue = {
|
|
|
6137
6566
|
helpVideosPath?: string;
|
|
6138
6567
|
};
|
|
6139
6568
|
|
|
6569
|
+
declare interface NetInfo {
|
|
6570
|
+
saveData?: boolean;
|
|
6571
|
+
effectiveType?: string;
|
|
6572
|
+
}
|
|
6573
|
+
|
|
6140
6574
|
export declare function networkdaysBetween(a: Date, b: Date): number;
|
|
6141
6575
|
|
|
6142
6576
|
export declare function NewImportDialog({ open, onOpenChange, definitions, runCounts, onQueued }: {
|
|
@@ -6284,7 +6718,7 @@ export declare function NotificationAnalyticsView({ className, compactHeader }:
|
|
|
6284
6718
|
* click-through routing via the shared notification-target resolver. Needs
|
|
6285
6719
|
* `<NivaroProvider>`.
|
|
6286
6720
|
*/
|
|
6287
|
-
export declare function NotificationBell({ routes, onNavigate, app, subscribe, buttonClassName, panelClassName, beforeList, extraBadge, mailLogUrl, renderTrigger, allPath, subscriptionsPath, onActionError, panelPlacement, tabBadge }: NotificationBellProps): JSX.Element;
|
|
6721
|
+
export declare function NotificationBell({ routes, onNavigate, app, subscribe, buttonClassName, panelClassName, beforeList, extraBadge, mailLogUrl, renderTrigger, allPath, subscriptionsPath, rulesPath, onActionError, panelPlacement, tabBadge }: NotificationBellProps): JSX.Element;
|
|
6288
6722
|
|
|
6289
6723
|
export declare interface NotificationBellProps {
|
|
6290
6724
|
/** Where each notification kind lands in the host app. */
|
|
@@ -6322,6 +6756,8 @@ export declare interface NotificationBellProps {
|
|
|
6322
6756
|
allPath?: string | null;
|
|
6323
6757
|
/** Path of the subscriptions page — a watch's "Why me?" offers a Manage link. */
|
|
6324
6758
|
subscriptionsPath?: string | null;
|
|
6759
|
+
/** Path of Profile → Notification rules — "Why?" offers a change link there (#3078). */
|
|
6760
|
+
rulesPath?: string | null;
|
|
6325
6761
|
/** Called with an error message when an inline action fails. */
|
|
6326
6762
|
onActionError?: (message: string) => void;
|
|
6327
6763
|
/** Where the panel opens relative to the trigger. 'below' (default) keeps
|
|
@@ -6360,7 +6796,7 @@ export declare interface NotificationBundle<R = unknown> {
|
|
|
6360
6796
|
rows: R[];
|
|
6361
6797
|
}
|
|
6362
6798
|
|
|
6363
|
-
export declare function NotificationCenterView({ routes, onNavigate, app, mailLogUrl, subscriptionsPath, onNotice, onError, className }: NotificationCenterViewProps): JSX.Element;
|
|
6799
|
+
export declare function NotificationCenterView({ routes, onNavigate, app, mailLogUrl, subscriptionsPath, rulesPath, changesId, onNotice, onError, className }: NotificationCenterViewProps): JSX.Element;
|
|
6364
6800
|
|
|
6365
6801
|
export declare interface NotificationCenterViewProps {
|
|
6366
6802
|
routes: NotificationRouteMap;
|
|
@@ -6369,6 +6805,11 @@ export declare interface NotificationCenterViewProps {
|
|
|
6369
6805
|
mailLogUrl?: (mailLogId: number) => string | null;
|
|
6370
6806
|
/** Host route of the subscriptions page (a watch's "Why me?" links there). */
|
|
6371
6807
|
subscriptionsPath?: string | null;
|
|
6808
|
+
/** Host route of Profile → Notification rules — "Why?" offers a change link there (#3078). */
|
|
6809
|
+
rulesPath?: string | null;
|
|
6810
|
+
/** #3079 — open on one notification's changes (the email's "See what changed" link lands
|
|
6811
|
+
* with ?changes=<id>). Undefined = read ?changes= from the address bar. */
|
|
6812
|
+
changesId?: number | null;
|
|
6372
6813
|
/** Toast hooks — hosts wire their own toaster. */
|
|
6373
6814
|
onNotice?: (message: string) => void;
|
|
6374
6815
|
onError?: (message: string) => void;
|
|
@@ -6837,6 +7278,8 @@ declare interface PartnerCall {
|
|
|
6837
7278
|
triggered_by: string | null;
|
|
6838
7279
|
has_body: boolean;
|
|
6839
7280
|
user: PartnerCallUser | null;
|
|
7281
|
+
/** #18 — a failed call in plain words + Fix it target (null when it did not fail). */
|
|
7282
|
+
explanation?: IntegrationErrorExplanation | null;
|
|
6840
7283
|
}
|
|
6841
7284
|
|
|
6842
7285
|
/** One user recorded on a call — via nivaro_users, batch-resolved server-side
|
|
@@ -7062,7 +7505,7 @@ export declare interface PersonProfileData {
|
|
|
7062
7505
|
} | null;
|
|
7063
7506
|
}
|
|
7064
7507
|
|
|
7065
|
-
export declare type PersonProfileTab = 'overview' | 'access' | 'activity' | 'tools';
|
|
7508
|
+
export declare type PersonProfileTab = 'overview' | 'access' | 'activity' | 'did' | 'tools';
|
|
7066
7509
|
|
|
7067
7510
|
/** Mirror of the server's PersonProfile (services/user-profile.ts). */
|
|
7068
7511
|
declare interface PersonRef {
|
|
@@ -7112,7 +7555,7 @@ declare type PipelineBinding = {
|
|
|
7112
7555
|
dimensions?: PipelineOwnerDimension[];
|
|
7113
7556
|
};
|
|
7114
7557
|
|
|
7115
|
-
export declare type PipelineEditorSection = 'states' | 'transitions' | 'branches' | 'bindings' | 'matrix' | 'simulator' | 'canvas' | 'flow-map' | 'replay' | 'cumulative-flow' | 'migration' | 'coverage' | 'lint' | 'skip-report' | 'ai-review' | 'versions' | 'matrix-versions';
|
|
7558
|
+
export declare type PipelineEditorSection = 'states' | 'transitions' | 'branches' | 'bindings' | 'matrix' | 'simulator' | 'canvas' | 'flow-map' | 'replay' | 'cumulative-flow' | 'migration' | 'coverage' | 'lint' | 'skip-report' | 'history' | 'ai-review' | 'versions' | 'matrix-versions';
|
|
7116
7559
|
|
|
7117
7560
|
export declare function PipelineEditorView({ templateId, onBack, onExport, hidden }: {
|
|
7118
7561
|
templateId: string;
|
|
@@ -7282,12 +7725,22 @@ export declare function precisionOf(options: unknown, fallback?: number): number
|
|
|
7282
7725
|
/** API prefetches one tab may make in any rolling minute. */
|
|
7283
7726
|
export declare const PREFETCH_PER_MINUTE = 30;
|
|
7284
7727
|
|
|
7728
|
+
/**
|
|
7729
|
+
* Warm a collection list: its metadata (fields, relations, browse config) — what the list waits
|
|
7730
|
+
* on before it can ask for rows, and what shapes its loading skeleton. The rows themselves
|
|
7731
|
+
* depend on the person's saved view, sort and filters, so they are not guessed.
|
|
7732
|
+
*/
|
|
7733
|
+
export declare function prefetchCollectionList(qc: QueryClient, client: NivaroClient, collection: string, opts?: {
|
|
7734
|
+
group?: string | null;
|
|
7735
|
+
}): number;
|
|
7736
|
+
|
|
7285
7737
|
/**
|
|
7286
7738
|
* Warm a record page: its readOne and the layout it will open with. Returns how many requests
|
|
7287
|
-
*
|
|
7739
|
+
* were queued (0 when both were fresh or the budget was spent).
|
|
7288
7740
|
*/
|
|
7289
7741
|
export declare function prefetchRecord(qc: QueryClient, client: NivaroClient, collection: string, id: string | number, opts?: {
|
|
7290
7742
|
layout?: boolean;
|
|
7743
|
+
group?: string | null;
|
|
7291
7744
|
}): number;
|
|
7292
7745
|
|
|
7293
7746
|
export declare interface PreparedReplayClip {
|
|
@@ -7396,7 +7849,7 @@ export declare function ProfileView({ userId, className, initialTab, extra, push
|
|
|
7396
7849
|
userId?: string | null;
|
|
7397
7850
|
className?: string;
|
|
7398
7851
|
/** Which tab an admin lands on for someone else's page. */
|
|
7399
|
-
initialTab?: 'overview' | 'access' | 'activity' | 'tools';
|
|
7852
|
+
initialTab?: 'overview' | 'access' | 'activity' | 'did' | 'tools';
|
|
7400
7853
|
/** Host-only cards for the OWN profile (a browser-push card, say), rendered in the right column. */
|
|
7401
7854
|
extra?: React.ReactNode;
|
|
7402
7855
|
/** Service worker the Browser notifications card registers (same origin); false hides the card. */
|
|
@@ -8321,6 +8774,9 @@ declare type RecordingHandoff = {
|
|
|
8321
8774
|
};
|
|
8322
8775
|
};
|
|
8323
8776
|
|
|
8777
|
+
/** Feed one location change. Returns the entry now current. */
|
|
8778
|
+
export declare function recordNavigation(ev: TrailEvent): TrailEntry | undefined;
|
|
8779
|
+
|
|
8324
8780
|
/**
|
|
8325
8781
|
* Mounted ONCE by a host (admin's AppLayout), inside a NivaroProvider and a
|
|
8326
8782
|
* QueryClientProvider: binds the outbox to the signed-in person so saves left
|
|
@@ -8514,6 +8970,18 @@ export declare function registerHelpVideoPage(key: string): () => void;
|
|
|
8514
8970
|
|
|
8515
8971
|
export declare function registerLayoutSlot(plugin: LayoutSlotPlugin): void;
|
|
8516
8972
|
|
|
8973
|
+
/**
|
|
8974
|
+
* "Is this tab in the middle of something live that a reload would cut off?" — a live huddle, a
|
|
8975
|
+
* screen clip being recorded. Not unsaved work (that is lib/unsaved-work.ts, the only source of
|
|
8976
|
+
* "unsaved changes"): nothing here is lost to a reload, it is interrupted. Read by the automatic
|
|
8977
|
+
* idle reload (lib/idle-reload.ts), which never reloads while any hold is on.
|
|
8978
|
+
*
|
|
8979
|
+
* Leaf module: the huddle store and the screen clip button report here, so the reload code never
|
|
8980
|
+
* imports the chat code.
|
|
8981
|
+
*/
|
|
8982
|
+
/** Report something live; the returned function removes it. `active` is read at decision time. */
|
|
8983
|
+
export declare function registerReloadHold(label: string, active?: () => boolean): () => void;
|
|
8984
|
+
|
|
8517
8985
|
/** Called by a host's recorder module. Returns an undo for tests / HMR. */
|
|
8518
8986
|
export declare function registerReplayCapture(fn: Capture, snap?: Snapshot): () => void;
|
|
8519
8987
|
|
|
@@ -8533,8 +9001,12 @@ export declare function RelatedRecordsPanel({ collection, itemId, title, default
|
|
|
8533
9001
|
defaultExpanded?: boolean;
|
|
8534
9002
|
}): JSX.Element;
|
|
8535
9003
|
|
|
8536
|
-
export declare function RelationCombobox({ collection, value, onChange, disabled, placeholder, extraFilter, autoSelectSingle, optionSort, requiredParent, facets, fieldKey, narrowedBy, pinned, missPlacement }: {
|
|
9004
|
+
export declare function RelationCombobox({ collection, value, onChange, disabled, placeholder, extraFilter, autoSelectSingle, optionSort, requiredParent, facets, fieldKey, narrowedBy, pinned, missPlacement, defaultOpen, onClose }: {
|
|
8537
9005
|
collection: string;
|
|
9006
|
+
/** Open the options panel on mount (a list cell's inline editor, #3224). */
|
|
9007
|
+
defaultOpen?: boolean;
|
|
9008
|
+
/** Called when the options panel closes (picked, clicked away or Escape). */
|
|
9009
|
+
onClose?: () => void;
|
|
8538
9010
|
/** The record-form placement this picker sits on: searches that find
|
|
8539
9011
|
* nothing are counted there (#2726). Absent = not reported. */
|
|
8540
9012
|
missPlacement?: PickerMissPlacement | null;
|
|
@@ -8622,6 +9094,12 @@ export declare function releaseGatedReadsOnSharedFetch(cache: QueryCacheLike): (
|
|
|
8622
9094
|
|
|
8623
9095
|
export declare function releaseHeld(): HeldItem[];
|
|
8624
9096
|
|
|
9097
|
+
/** "Pat updated 40 workflows: Status → On Hold"; a group of one reads as its entry. */
|
|
9098
|
+
export declare function renderActivityGroupSentence(entries: ActivityEntryInput[], labels?: ActivityLabels | null): string;
|
|
9099
|
+
|
|
9100
|
+
/** One readable sentence for one activity entry. */
|
|
9101
|
+
export declare function renderActivitySentence(entry: ActivityEntryInput, labels?: ActivityLabels | null): string;
|
|
9102
|
+
|
|
8625
9103
|
export declare type RenderFieldProps = {
|
|
8626
9104
|
field: any;
|
|
8627
9105
|
value: unknown;
|
|
@@ -9326,6 +9804,13 @@ export declare function setServerClockOffset(ms: number): void;
|
|
|
9326
9804
|
|
|
9327
9805
|
export declare function setTimeDisplay(mode: string | null | undefined): void;
|
|
9328
9806
|
|
|
9807
|
+
/**
|
|
9808
|
+
* Name a page in the trail (what later crumbs will show for it): the current
|
|
9809
|
+
* entry — and, when a key is given, only while that key is still current (a
|
|
9810
|
+
* label that lands after the person moved on is dropped, never misfiled).
|
|
9811
|
+
*/
|
|
9812
|
+
export declare function setTrailLabel(label: string | null | undefined, key?: string): void;
|
|
9813
|
+
|
|
9329
9814
|
/** True when this browser can share a socket between tabs. */
|
|
9330
9815
|
export declare function sharedWorkerSupported(): boolean;
|
|
9331
9816
|
|
|
@@ -9405,6 +9890,27 @@ declare type Size = {
|
|
|
9405
9890
|
h: number;
|
|
9406
9891
|
};
|
|
9407
9892
|
|
|
9893
|
+
export declare function SkeletonBar({ shape, width, className, style }: {
|
|
9894
|
+
shape?: CellShape;
|
|
9895
|
+
width?: string | number;
|
|
9896
|
+
className?: string;
|
|
9897
|
+
style?: CSSProperties;
|
|
9898
|
+
}): JSX.Element;
|
|
9899
|
+
|
|
9900
|
+
export declare interface SkeletonColumn {
|
|
9901
|
+
key: string;
|
|
9902
|
+
shape?: CellShape;
|
|
9903
|
+
/** Fixed column width in px (a resized column), when the list has one. */
|
|
9904
|
+
width?: number | null;
|
|
9905
|
+
}
|
|
9906
|
+
|
|
9907
|
+
/** Real list columns → skeleton columns (types decide the shapes). */
|
|
9908
|
+
export declare function skeletonColumnsFrom(keys: readonly string[], fields: ReadonlyArray<{
|
|
9909
|
+
field: string;
|
|
9910
|
+
type?: string | null;
|
|
9911
|
+
interface?: string | null;
|
|
9912
|
+
}>, widths?: Record<string, number | undefined>): SkeletonColumn[];
|
|
9913
|
+
|
|
9408
9914
|
declare type SkipCondition = {
|
|
9409
9915
|
type: 'no_owners';
|
|
9410
9916
|
} | {
|
|
@@ -9488,6 +9994,80 @@ export declare type SlotRendererProps = {
|
|
|
9488
9994
|
defaultExpanded: boolean;
|
|
9489
9995
|
};
|
|
9490
9996
|
|
|
9997
|
+
/**
|
|
9998
|
+
* "This is taking a while" with a reason (#3231). Renders nothing until the read has been
|
|
9999
|
+
* loading ~3 s, then says what it is waiting on in plain words ("Reading 48,000 invoices",
|
|
10000
|
+
* "Waiting for Fusion", "Waiting for a free slot — busy right now") with the elapsed time.
|
|
10001
|
+
*
|
|
10002
|
+
* variant 'inline' — a line inside a loading area (widgets, query results, forms)
|
|
10003
|
+
* variant 'pill' — a floating chip; the caller positions it (absolute) so nothing moves
|
|
10004
|
+
*
|
|
10005
|
+
* `children` ride beside the text (e.g. a Run in background button). Reads that can run in the
|
|
10006
|
+
* background use BackgroundRunOffer, which shows the same reason.
|
|
10007
|
+
*/
|
|
10008
|
+
export declare function SlowNotice({ variant, className, children, reason: given, ...opts }: UseSlowReasonOptions & {
|
|
10009
|
+
variant?: 'inline' | 'pill';
|
|
10010
|
+
className?: string;
|
|
10011
|
+
children?: ReactNode;
|
|
10012
|
+
/** A reason the host already computed with useSlowReason (skips the hook's own asking). */
|
|
10013
|
+
reason?: SlowReason;
|
|
10014
|
+
}): JSX.Element | null;
|
|
10015
|
+
|
|
10016
|
+
export declare function SlowNoticeView({ reason, variant, className, extra }: {
|
|
10017
|
+
reason: SlowReason;
|
|
10018
|
+
variant?: 'inline' | 'pill';
|
|
10019
|
+
className?: string;
|
|
10020
|
+
extra?: ReactNode;
|
|
10021
|
+
}): JSX.Element;
|
|
10022
|
+
|
|
10023
|
+
export declare interface SlowReadRequest {
|
|
10024
|
+
method: 'GET' | 'POST';
|
|
10025
|
+
/** API path (with or without /api); a query string is ignored. */
|
|
10026
|
+
url: string;
|
|
10027
|
+
}
|
|
10028
|
+
|
|
10029
|
+
/** The server's answer (api/src/services/wait-reasons.ts WaitAnswer). */
|
|
10030
|
+
export declare interface SlowReadWaitAnswer {
|
|
10031
|
+
found: boolean;
|
|
10032
|
+
kind?: WaitKind;
|
|
10033
|
+
subject?: string | null;
|
|
10034
|
+
shared?: boolean;
|
|
10035
|
+
position?: number | null;
|
|
10036
|
+
of?: number | null;
|
|
10037
|
+
age_ms?: number;
|
|
10038
|
+
statement_ms?: number;
|
|
10039
|
+
rows_so_far?: number;
|
|
10040
|
+
collection?: string | null;
|
|
10041
|
+
/** About how many rows the table holds — administrators only. */
|
|
10042
|
+
table_rows?: number | null;
|
|
10043
|
+
peer?: boolean;
|
|
10044
|
+
}
|
|
10045
|
+
|
|
10046
|
+
export declare interface SlowReason {
|
|
10047
|
+
/** Loading for at least `afterMs`. */
|
|
10048
|
+
slow: boolean;
|
|
10049
|
+
/** How long it has been loading, ms (0 while not slow). */
|
|
10050
|
+
elapsedMs: number;
|
|
10051
|
+
/** The plain sentence, or null when the server knows nothing useful. */
|
|
10052
|
+
text: string | null;
|
|
10053
|
+
answer: SlowReadWaitAnswer | null;
|
|
10054
|
+
}
|
|
10055
|
+
|
|
10056
|
+
declare interface SlowReasonContext {
|
|
10057
|
+
/** Plural noun for what a list reads, e.g. "invoices". */
|
|
10058
|
+
noun?: string | null;
|
|
10059
|
+
/** What the page calls this read, e.g. "PUB health" (a query or widget title). */
|
|
10060
|
+
label?: string | null;
|
|
10061
|
+
/** Rows the person can see, when the page already knows (a total from an earlier load). */
|
|
10062
|
+
knownRows?: number | null;
|
|
10063
|
+
}
|
|
10064
|
+
|
|
10065
|
+
/**
|
|
10066
|
+
* One plain sentence for what a slow read is waiting on, or null when the server knows nothing
|
|
10067
|
+
* useful (the request already finished, another replica not seen yet, cloud mode).
|
|
10068
|
+
*/
|
|
10069
|
+
export declare function slowReasonText(answer: SlowReadWaitAnswer | null | undefined, ctx?: SlowReasonContext): string | null;
|
|
10070
|
+
|
|
9491
10071
|
/**
|
|
9492
10072
|
* Two-phase capture: take the moment NOW (the clip's events, or the live
|
|
9493
10073
|
* recording's offset), upload later. A support dialog snapshots when it
|
|
@@ -9961,6 +10541,23 @@ export declare type SynonymGroups = ReadonlyArray<ReadonlyArray<string>>;
|
|
|
9961
10541
|
|
|
9962
10542
|
declare type TabKey = 'catalog' | 'rules' | 'subscriptions' | 'history' | 'widget_alerts' | 'widget_alert_history' | 'anomaly_rules' | 'anomaly_history';
|
|
9963
10543
|
|
|
10544
|
+
/**
|
|
10545
|
+
* Body rows for a real `<table>` whose header is already on screen: one cell per real column
|
|
10546
|
+
* (plus the table's own leading/trailing cells), with the row height and cell padding of the
|
|
10547
|
+
* real rows. Render inside `<tbody>`.
|
|
10548
|
+
*/
|
|
10549
|
+
export declare function TableSkeletonRows({ columns, rows, rowClassName, cellClassName, leadingCells, trailingCells, cellStyle, barClassName }: {
|
|
10550
|
+
columns: readonly SkeletonColumn[];
|
|
10551
|
+
rows?: number;
|
|
10552
|
+
rowClassName?: string;
|
|
10553
|
+
cellClassName?: string;
|
|
10554
|
+
leadingCells?: number;
|
|
10555
|
+
trailingCells?: number;
|
|
10556
|
+
/** Per-column style (pinned offsets, fixed widths) — the real cells' own. */
|
|
10557
|
+
cellStyle?: (key: string) => CSSProperties | undefined;
|
|
10558
|
+
barClassName?: string;
|
|
10559
|
+
}): JSX.Element;
|
|
10560
|
+
|
|
9964
10561
|
export declare type TabState = {
|
|
9965
10562
|
activeTab: string | null;
|
|
9966
10563
|
setActiveTab: (key: string) => void;
|
|
@@ -10141,6 +10738,68 @@ export declare function TrafficMiniMap({ window: win, tone, href, refreshMs, cla
|
|
|
10141
10738
|
className?: string;
|
|
10142
10739
|
}): JSX.Element | null;
|
|
10143
10740
|
|
|
10741
|
+
/**
|
|
10742
|
+
* #3225 — breadcrumbs that know the path. A per-TAB record of the history
|
|
10743
|
+
* entries this tab walked through (sessionStorage, so a reload keeps it and
|
|
10744
|
+
* another tab has its own), keyed by the router's history index. The page
|
|
10745
|
+
* header turns the entries before the current one into crumbs — how the
|
|
10746
|
+
* person actually got here (Queue "Pending approvals" → PO 4471 → Line 3) —
|
|
10747
|
+
* and a crumb click goes BACK that many history entries, so the page comes
|
|
10748
|
+
* back exactly as it was left: same URL (filters, tab), and the scroll
|
|
10749
|
+
* position the trail remembered.
|
|
10750
|
+
*
|
|
10751
|
+
* The host feeds it: call `recordNavigation()` on every location change with
|
|
10752
|
+
* the router's action ('PUSH' | 'REPLACE' | 'POP'), the location key and
|
|
10753
|
+
* `history.state.idx` (React Router keeps the index there across reloads).
|
|
10754
|
+
* Nothing here touches the router, so any host (admin, efp-new) can wire it.
|
|
10755
|
+
*
|
|
10756
|
+
* Pure parts (`reduceTrail`, `trailChain`, `displayTrail`) are tested on their own.
|
|
10757
|
+
*/
|
|
10758
|
+
declare type TrailAction = 'PUSH' | 'REPLACE' | 'POP';
|
|
10759
|
+
|
|
10760
|
+
/** The unbroken run of entries right before the current one, oldest first. */
|
|
10761
|
+
export declare function trailChain(state: TrailState): TrailEntry[];
|
|
10762
|
+
|
|
10763
|
+
declare interface TrailCrumb {
|
|
10764
|
+
key: string;
|
|
10765
|
+
path: string;
|
|
10766
|
+
label?: string;
|
|
10767
|
+
/** History steps to go back to reach it (negative). */
|
|
10768
|
+
delta: number;
|
|
10769
|
+
}
|
|
10770
|
+
|
|
10771
|
+
declare interface TrailEntry {
|
|
10772
|
+
key: string;
|
|
10773
|
+
idx: number;
|
|
10774
|
+
/** pathname + search + hash */
|
|
10775
|
+
path: string;
|
|
10776
|
+
label?: string;
|
|
10777
|
+
scroll?: TrailScroll[];
|
|
10778
|
+
at: number;
|
|
10779
|
+
}
|
|
10780
|
+
|
|
10781
|
+
declare interface TrailEvent {
|
|
10782
|
+
action: TrailAction;
|
|
10783
|
+
key: string;
|
|
10784
|
+
idx: number;
|
|
10785
|
+
path: string;
|
|
10786
|
+
at?: number;
|
|
10787
|
+
}
|
|
10788
|
+
|
|
10789
|
+
declare interface TrailScroll {
|
|
10790
|
+
/** '' = the page scroller itself; otherwise a child path from it (see scrollPathOf). */
|
|
10791
|
+
path: string;
|
|
10792
|
+
top: number;
|
|
10793
|
+
}
|
|
10794
|
+
|
|
10795
|
+
declare interface TrailState {
|
|
10796
|
+
entries: TrailEntry[];
|
|
10797
|
+
current: {
|
|
10798
|
+
key: string;
|
|
10799
|
+
idx: number;
|
|
10800
|
+
} | null;
|
|
10801
|
+
}
|
|
10802
|
+
|
|
10144
10803
|
/**
|
|
10145
10804
|
* Translate scope values (target-collection IDS) into a filter's value space.
|
|
10146
10805
|
* When the filter compares ids (valueField 'id'/undefined) this is identity;
|
|
@@ -10313,6 +10972,15 @@ declare type UploadRow = {
|
|
|
10313
10972
|
|
|
10314
10973
|
export declare function useActiveGamedays(enabled?: boolean): ActiveGameday[];
|
|
10315
10974
|
|
|
10975
|
+
/**
|
|
10976
|
+
* Labels for a page of entries, read AS THE VIEWER (POST /api/activity/labels): records they
|
|
10977
|
+
* cannot see come back null ("a record you can't see"), people by display name, collection /
|
|
10978
|
+
* field / choice labels. Adds the viewer's time zone. One request per distinct page.
|
|
10979
|
+
*/
|
|
10980
|
+
export declare function useActivityLabels(entries: ActivityEntryInput[], opts?: {
|
|
10981
|
+
enabled?: boolean;
|
|
10982
|
+
}): ActivityLabels | undefined;
|
|
10983
|
+
|
|
10316
10984
|
/**
|
|
10317
10985
|
* `useAfterIdle(ms)` — false on mount, true once the browser has had `ms` of
|
|
10318
10986
|
* settle time after the first paint. Gate secondary reads on it (freshness
|
|
@@ -10645,10 +11313,19 @@ export declare function useHelpVideosFor(ctx: {
|
|
|
10645
11313
|
item?: string | number;
|
|
10646
11314
|
state?: string;
|
|
10647
11315
|
page?: string;
|
|
11316
|
+
/** #18: the route (`/collections/purchase_orders/12`); the server derives
|
|
11317
|
+
* the screen, screens like it, the record type and the area from it. */
|
|
11318
|
+
path?: string;
|
|
11319
|
+
/** #18: which app `path` belongs to (default `admin`). */
|
|
11320
|
+
app?: string;
|
|
11321
|
+
/** #18: comma list of glossary terms the screen shows. */
|
|
11322
|
+
terms?: string;
|
|
10648
11323
|
}, enabled?: boolean): UseQueryResult<NoInfer<{
|
|
10649
11324
|
data: HelpVideoDto[];
|
|
10650
11325
|
can_author: boolean;
|
|
10651
11326
|
state: string | null;
|
|
11327
|
+
/** #18: the strong match this person has not finished. Older servers: absent. */
|
|
11328
|
+
best_id?: string | null;
|
|
10652
11329
|
}>, Error>;
|
|
10653
11330
|
|
|
10654
11331
|
/** "Show me on this page": the published version's labelled clicks. */
|
|
@@ -10786,6 +11463,9 @@ export declare function useMyScopes(): {
|
|
|
10786
11463
|
|
|
10787
11464
|
export declare function useNavigation(): NavigationContextValue;
|
|
10788
11465
|
|
|
11466
|
+
/** The tab's trail, re-rendering on every change. */
|
|
11467
|
+
export declare function useNavTrail(): TrailState;
|
|
11468
|
+
|
|
10789
11469
|
export declare function useNivaroClient(): NivaroClient;
|
|
10790
11470
|
|
|
10791
11471
|
/**
|
|
@@ -10911,6 +11591,16 @@ export declare function usePersonProfile(userId: string | null | undefined): Use
|
|
|
10911
11591
|
|
|
10912
11592
|
export declare function usePlanGridHost(): PlanGridHost | null;
|
|
10913
11593
|
|
|
11594
|
+
/**
|
|
11595
|
+
* `const intent = usePrefetchIntent()` → spread `{...intent.record(collection, id)}` on a row or
|
|
11596
|
+
* button that opens a record, `{...intent.list(collection)}` on one that opens a list. Inert
|
|
11597
|
+
* without a client (nothing to fetch with).
|
|
11598
|
+
*/
|
|
11599
|
+
export declare function usePrefetchIntent(): {
|
|
11600
|
+
record: (collection: string, id: string | number) => MaybeIntent;
|
|
11601
|
+
list: (collection: string) => MaybeIntent;
|
|
11602
|
+
};
|
|
11603
|
+
|
|
10914
11604
|
/** Who else is viewing one record (joins its room; names only). */
|
|
10915
11605
|
export declare function usePresence(collection: string | null | undefined, item: string | number | null | undefined): RecordPresence;
|
|
10916
11606
|
|
|
@@ -11121,6 +11811,23 @@ action: IntegrationSignalRow["actions"][number];
|
|
|
11121
11811
|
|
|
11122
11812
|
export declare function useSignals(tab?: string): UseQueryResult<NoInfer<IntegrationSignalsSnapshot>, Error>;
|
|
11123
11813
|
|
|
11814
|
+
/**
|
|
11815
|
+
* #3231 — after ~3 s of loading, ask the server what this read is waiting on and keep asking
|
|
11816
|
+
* every few seconds while it still loads (hidden tabs skip a beat). Nothing is asked for a read
|
|
11817
|
+
* that finishes in time, so a fast page makes no extra call.
|
|
11818
|
+
*/
|
|
11819
|
+
export declare function useSlowReason(opts: UseSlowReasonOptions): SlowReason;
|
|
11820
|
+
|
|
11821
|
+
declare interface UseSlowReasonOptions extends SlowReasonContext {
|
|
11822
|
+
/** True while the page's own read is still loading. */
|
|
11823
|
+
pending: boolean;
|
|
11824
|
+
/** The read the page is making; null = ask nothing (the notice still says it is slow). */
|
|
11825
|
+
request: SlowReadRequest | null;
|
|
11826
|
+
/** How long before the read counts as slow (default 3 s). */
|
|
11827
|
+
afterMs?: number;
|
|
11828
|
+
enabled?: boolean;
|
|
11829
|
+
}
|
|
11830
|
+
|
|
11124
11831
|
export declare function useSnooze(): {
|
|
11125
11832
|
add: UseMutationResult<unknown, Error, SnoozeInput, unknown>;
|
|
11126
11833
|
remove: UseMutationResult<unknown, Error, number, unknown>;
|
|
@@ -11327,6 +12034,17 @@ declare type Visibility = {
|
|
|
11327
12034
|
role_ids: string[];
|
|
11328
12035
|
};
|
|
11329
12036
|
|
|
12037
|
+
/**
|
|
12038
|
+
* "This is taking a while" with a reason (#3231) — the client half of
|
|
12039
|
+
* GET /api/background-runs/waiting.
|
|
12040
|
+
*
|
|
12041
|
+
* The server tells a page what ITS OWN unfinished read is waiting on (a free heavy-read slot and
|
|
12042
|
+
* where it stands in line, an external partner, an uncached query or widget, a statement still
|
|
12043
|
+
* running); this file turns that answer into one plain sentence. Pure — the hook and the notice
|
|
12044
|
+
* live in hooks/useSlowReason.ts and components/SlowNotice.tsx.
|
|
12045
|
+
*/
|
|
12046
|
+
declare type WaitKind = 'slot' | 'external' | 'query' | 'widget' | 'database' | 'auth' | 'working';
|
|
12047
|
+
|
|
11330
12048
|
/** One step of "Show me on this page" (GET /help-videos/:id/walk). */
|
|
11331
12049
|
export declare interface WalkStep {
|
|
11332
12050
|
label: string;
|