@nivaro/react 0.1.4
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/full.css +125 -0
- package/dist/index.d.ts +1608 -0
- package/dist/index.js +38391 -0
- package/package.json +104 -0
- package/styles.css +124 -0
- package/tailwind-preset.cjs +97 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1608 @@
|
|
|
1
|
+
import { CascadeFilterRule } from '@nivaro/sdk';
|
|
2
|
+
import { default as default_2 } from 'react';
|
|
3
|
+
import { FieldDependencyConfig } from '@nivaro/sdk';
|
|
4
|
+
import type { ImportParseResponse } from '@nivaro/sdk';
|
|
5
|
+
import { JSX } from 'react';
|
|
6
|
+
import { JSXElementConstructor } from 'react';
|
|
7
|
+
import { NivaroClient } from '@nivaro/sdk';
|
|
8
|
+
import { default as React_2 } from 'react';
|
|
9
|
+
import { ReactElement } from 'react';
|
|
10
|
+
import { ReactNode } from 'react';
|
|
11
|
+
import { ReactPortal } from 'react';
|
|
12
|
+
import { ReportDateRange } from '@nivaro/sdk';
|
|
13
|
+
import { ReportEntityFilter } from '@nivaro/sdk';
|
|
14
|
+
import { ReportQueryWidgetConfig } from '@nivaro/sdk';
|
|
15
|
+
import { UseMutationResult } from '@tanstack/react-query';
|
|
16
|
+
import { UserScopesInfo } from '@nivaro/sdk';
|
|
17
|
+
|
|
18
|
+
export declare function AlertManagerView({ defaultTab, hiddenTabs, onOpenReport, className }: AlertManagerViewProps): JSX.Element;
|
|
19
|
+
|
|
20
|
+
export declare interface AlertManagerViewProps {
|
|
21
|
+
/** Tab shown on first render. */
|
|
22
|
+
defaultTab?: TabKey;
|
|
23
|
+
/** Hide specific tabs (e.g. widget tabs when Report Studio is unused). */
|
|
24
|
+
hiddenTabs?: TabKey[];
|
|
25
|
+
/** Called when a widget alert's report name is clicked (host navigation). */
|
|
26
|
+
onOpenReport?: (reportId: string) => void;
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export declare function BooleanField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
|
|
31
|
+
|
|
32
|
+
export declare function canOpenDm(): boolean;
|
|
33
|
+
|
|
34
|
+
export { CascadeFilterRule }
|
|
35
|
+
|
|
36
|
+
declare interface ChannelMeta {
|
|
37
|
+
id: number;
|
|
38
|
+
visibility: 'open' | 'role' | 'private';
|
|
39
|
+
role: string | null;
|
|
40
|
+
topic: string | null;
|
|
41
|
+
created_by: string | null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export declare function chatAvatarColor(id: string): string;
|
|
45
|
+
|
|
46
|
+
export declare interface ChatConfig {
|
|
47
|
+
collections: {
|
|
48
|
+
messages: string;
|
|
49
|
+
reads: string;
|
|
50
|
+
presence: string;
|
|
51
|
+
};
|
|
52
|
+
globalRoom: string;
|
|
53
|
+
globalLabel: string;
|
|
54
|
+
/** Entity-id pattern rendered as record links (RegExp source, global flags applied). */
|
|
55
|
+
entityPattern: string;
|
|
56
|
+
/** URL for an entity token (null = plain text). */
|
|
57
|
+
entityUrl: (token: string) => string | null;
|
|
58
|
+
/** Label for a non-global, non-dm room key (null = uppercased key). */
|
|
59
|
+
roomLabel?: (room: string) => string | null;
|
|
60
|
+
/** Host route for a resolved record (entity rooms' "Open record" action) —
|
|
61
|
+
* admin passes /collections/:c/:id, efp-new /records/:c/:id. Absent = the
|
|
62
|
+
* admin shape; return null = hide the action. */
|
|
63
|
+
recordUrl?: (collection: string, id: string | number) => string | null;
|
|
64
|
+
/** Live updates: subscribe to a collection's change feed; return unsubscribe.
|
|
65
|
+
* Still used for presence/typing, which remain plain /items collections. */
|
|
66
|
+
realtime?: (collection: string, cb: () => void) => () => void;
|
|
67
|
+
/**
|
|
68
|
+
* Live chat delivery: join the given rooms' socket rooms and call back on a
|
|
69
|
+
* `chat:message` event. Replaces invalidating on every chat_messages write
|
|
70
|
+
* anywhere — at channel scale that fan-out is a broadcast storm, and the
|
|
71
|
+
* server only emits to `chat:<room>` now. Without it the queries still poll.
|
|
72
|
+
*/
|
|
73
|
+
subscribeRooms?: (rooms: string[], cb: (msg: ChatMessage) => void) => () => void;
|
|
74
|
+
me: {
|
|
75
|
+
id: string;
|
|
76
|
+
name: string;
|
|
77
|
+
} | null;
|
|
78
|
+
/** Online users (presence) — drives the Online tab + mention autocomplete. */
|
|
79
|
+
onlineUsers: ChatOnlineUser[];
|
|
80
|
+
/** Presence typing setter (userId, room|null). */
|
|
81
|
+
setTypingRoom?: (userId: string, room: string | null) => void | Promise<void>;
|
|
82
|
+
navigate?: (url: string) => void;
|
|
83
|
+
sound: boolean;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export declare function chatInitials(name: string | null): string;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Nivaro chat — data layer.
|
|
90
|
+
*
|
|
91
|
+
* Messages, rooms and watermarks go through /api/chat, NOT plain /items: room
|
|
92
|
+
* visibility (your DMs, the channels you belong to, entity rooms for records
|
|
93
|
+
* you can read) cannot be expressed as a table-level policy, and the items API
|
|
94
|
+
* now refuses these collections outright. Presence/typing stay on /items,
|
|
95
|
+
* which is per-user by nature. Live delivery comes from a host-provided
|
|
96
|
+
* realtime adapter, with polling fallbacks baked into every query.
|
|
97
|
+
*
|
|
98
|
+
* Ported from the EFP implementation with its semantics preserved:
|
|
99
|
+
* - DM room keys are 'dm:<A>:<B>' with UPPERCASED sorted uuids (MSSQL returns
|
|
100
|
+
* uuids uppercased — a casing mismatch forks a second room).
|
|
101
|
+
* - Read watermarks are serialized per room (markInFlight) because the reads
|
|
102
|
+
* table has UNIQUE(user, room) and the room view marks on entry AND on each
|
|
103
|
+
* new message — concurrent select-then-insert would 500 on duplicate key.
|
|
104
|
+
* - Mentions store '@[Display Name]' with no id; notifications fire only for
|
|
105
|
+
* users picked from the autocomplete.
|
|
106
|
+
*/
|
|
107
|
+
export declare interface ChatMessage {
|
|
108
|
+
id: number;
|
|
109
|
+
sender: string;
|
|
110
|
+
sender_name: string | null;
|
|
111
|
+
room: string;
|
|
112
|
+
message: string;
|
|
113
|
+
date_created: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export declare interface ChatOnlineUser {
|
|
117
|
+
user_id: string;
|
|
118
|
+
display_name: string | null;
|
|
119
|
+
role_name?: string | null;
|
|
120
|
+
current_path?: string | null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export declare function ChatPanel({ open, onClose, renderMessageBody, requestedDm }: {
|
|
124
|
+
open: boolean;
|
|
125
|
+
onClose: () => void;
|
|
126
|
+
renderMessageBody?: (m: ChatMessage, ctx: {
|
|
127
|
+
mine: boolean;
|
|
128
|
+
}) => React.ReactNode;
|
|
129
|
+
/** External DM request (UserChip "Send message" via registerDmOpener) —
|
|
130
|
+
* nonce bumps re-trigger even for the same user. */
|
|
131
|
+
requestedDm?: {
|
|
132
|
+
userId: string;
|
|
133
|
+
name?: string;
|
|
134
|
+
nonce: number;
|
|
135
|
+
} | null;
|
|
136
|
+
}): JSX.Element | null;
|
|
137
|
+
|
|
138
|
+
export declare function ChatProvider({ children, me, onlineUsers, collections, globalRoom, globalLabel, entityPattern, entityUrl, roomLabel, recordUrl, realtime, subscribeRooms, setTypingRoom, navigate, sound, theme }: ChatProviderProps): JSX.Element;
|
|
139
|
+
|
|
140
|
+
declare interface ChatProviderProps {
|
|
141
|
+
children: React.ReactNode;
|
|
142
|
+
me: ChatConfig['me'];
|
|
143
|
+
onlineUsers?: ChatOnlineUser[];
|
|
144
|
+
collections?: Partial<ChatConfig['collections']>;
|
|
145
|
+
globalRoom?: string;
|
|
146
|
+
globalLabel?: string;
|
|
147
|
+
entityPattern?: string;
|
|
148
|
+
entityUrl?: ChatConfig['entityUrl'];
|
|
149
|
+
roomLabel?: ChatConfig['roomLabel'];
|
|
150
|
+
recordUrl?: ChatConfig['recordUrl'];
|
|
151
|
+
realtime?: ChatConfig['realtime'];
|
|
152
|
+
subscribeRooms?: ChatConfig['subscribeRooms'];
|
|
153
|
+
setTypingRoom?: ChatConfig['setTypingRoom'];
|
|
154
|
+
navigate?: ChatConfig['navigate'];
|
|
155
|
+
sound?: boolean;
|
|
156
|
+
theme?: Partial<ChatTheme>;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export declare function ChatRoomList({ rooms, onOpen }: {
|
|
160
|
+
rooms: RoomInfo[];
|
|
161
|
+
onOpen: (room: RoomInfo) => void;
|
|
162
|
+
}): JSX.Element;
|
|
163
|
+
|
|
164
|
+
export declare function ChatRoomView({ room, label, onBack, onOpenSettings, renderMessageBody }: {
|
|
165
|
+
room: string;
|
|
166
|
+
label: string;
|
|
167
|
+
onBack: () => void;
|
|
168
|
+
/** Channel rooms only — opens members/visibility settings. */
|
|
169
|
+
onOpenSettings?: () => void;
|
|
170
|
+
renderMessageBody?: (m: ChatMessage, ctx: {
|
|
171
|
+
mine: boolean;
|
|
172
|
+
}) => React.ReactNode;
|
|
173
|
+
}): JSX.Element;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Nivaro chat UI — a complete team panel (Online tab, grouped rooms, live
|
|
177
|
+
* conversations with mentions, typing, receipts, search).
|
|
178
|
+
*
|
|
179
|
+
* Theming: every visual slot reads from `ChatTheme` (className strings) with
|
|
180
|
+
* nvr-cyan defaults — pass `theme` overrides on ChatProvider to restyle
|
|
181
|
+
* without forking. Structural hooks: `data-chat-*` attributes on every major
|
|
182
|
+
* element, `renderMessageBody` to override message rendering entirely.
|
|
183
|
+
*/
|
|
184
|
+
export declare interface ChatTheme {
|
|
185
|
+
/** My message bubble. */
|
|
186
|
+
bubbleMine: string;
|
|
187
|
+
/** Others' message bubble. */
|
|
188
|
+
bubbleOther: string;
|
|
189
|
+
/** Accent text (links, read receipt, active states). */
|
|
190
|
+
accentText: string;
|
|
191
|
+
/** Soft accent fill (active tab, selected candidate, mention highlight). */
|
|
192
|
+
accentSoft: string;
|
|
193
|
+
/** Unread pill. */
|
|
194
|
+
pill: string;
|
|
195
|
+
/** Primary action (send button). */
|
|
196
|
+
action: string;
|
|
197
|
+
/** Panel/popover surface. */
|
|
198
|
+
surface: string;
|
|
199
|
+
/** Input fields. */
|
|
200
|
+
input: string;
|
|
201
|
+
/** Divider borders. */
|
|
202
|
+
divider: string;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Clear the schema cache (e.g. after a schema change). */
|
|
206
|
+
export declare function clearFormSchemaCache(collection?: string): void;
|
|
207
|
+
|
|
208
|
+
/** @deprecated Column model changed to plain field keys — kept for source
|
|
209
|
+
* compatibility with early adopters; maps `path` to a field key. */
|
|
210
|
+
export declare interface CollectionBrowserColumn {
|
|
211
|
+
path: string;
|
|
212
|
+
label?: string;
|
|
213
|
+
format?: 'currency' | 'date' | 'datetime' | 'text';
|
|
214
|
+
filterable?: boolean;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export declare function CollectionBrowserView({ collection, quickFilters, initialColumns, initialSort, pageSize, initialSearch, initialConditions, onOpenItem, showCreate, className }: CollectionBrowserViewProps): React_2.JSX.Element;
|
|
218
|
+
|
|
219
|
+
export declare interface CollectionBrowserViewProps {
|
|
220
|
+
collection: string;
|
|
221
|
+
/** Persistent facet dropdowns above the table (multi-select + Apply/Clear);
|
|
222
|
+
* selections filter server-side over the entire record set. */
|
|
223
|
+
quickFilters?: QuickFilterDef[];
|
|
224
|
+
/** Initial visible columns (plain field keys). Defaults to the first 7
|
|
225
|
+
* non-hidden fields. */
|
|
226
|
+
initialColumns?: string[];
|
|
227
|
+
/** Default sort until a header is clicked (e.g. '-created'). */
|
|
228
|
+
initialSort?: string;
|
|
229
|
+
pageSize?: number;
|
|
230
|
+
/** Initial quick-search value (deep links). */
|
|
231
|
+
initialSearch?: string;
|
|
232
|
+
/** Contextual deep-link conditions (e.g. a dashboard tile linking to "my
|
|
233
|
+
* drafts"): ANDed into every fetch until the user clears the context chip.
|
|
234
|
+
* `label` is what the chip displays for that condition. */
|
|
235
|
+
initialConditions?: Array<{
|
|
236
|
+
path: string[];
|
|
237
|
+
op: string;
|
|
238
|
+
value: unknown;
|
|
239
|
+
label?: string;
|
|
240
|
+
}>;
|
|
241
|
+
/** Override row-open behavior; defaults to NavigationContext itemUrl. */
|
|
242
|
+
onOpenItem?: (id: string | number) => void;
|
|
243
|
+
showCreate?: boolean;
|
|
244
|
+
className?: string;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export declare function CollectionImportPanel({ initialJobId, onJobOpen }: {
|
|
248
|
+
/** Deep link: open this job's detail on mount. */
|
|
249
|
+
initialJobId?: string | null;
|
|
250
|
+
onJobOpen?: (id: string | null) => void;
|
|
251
|
+
}): JSX.Element;
|
|
252
|
+
|
|
253
|
+
declare interface Column<T = Record<string, unknown>> {
|
|
254
|
+
key: string;
|
|
255
|
+
header: React_2.ReactNode;
|
|
256
|
+
sortable?: boolean;
|
|
257
|
+
className?: string;
|
|
258
|
+
headerClassName?: string;
|
|
259
|
+
render?: (row: T, index: number) => React_2.ReactNode;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
declare type ColumnFormatConfig = {
|
|
263
|
+
type: 'datetime';
|
|
264
|
+
template: string;
|
|
265
|
+
} | {
|
|
266
|
+
type: 'number';
|
|
267
|
+
decimals?: number;
|
|
268
|
+
thousands?: boolean;
|
|
269
|
+
prefix?: string;
|
|
270
|
+
suffix?: string;
|
|
271
|
+
} | {
|
|
272
|
+
type: 'boolean';
|
|
273
|
+
true_label: string;
|
|
274
|
+
false_label: string;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
export declare function CommentPanel({ collection, item, title, defaultExpanded, queuedComments, onQueueComment }: {
|
|
278
|
+
collection: string;
|
|
279
|
+
item: string | number;
|
|
280
|
+
title?: string;
|
|
281
|
+
defaultExpanded?: boolean;
|
|
282
|
+
queuedComments?: string[];
|
|
283
|
+
onQueueComment?: (text: string) => void;
|
|
284
|
+
}): React_2.JSX.Element;
|
|
285
|
+
|
|
286
|
+
export declare type ComponentOverrides = {
|
|
287
|
+
text?: default_2.ComponentType<FieldComponentProps>;
|
|
288
|
+
textarea?: default_2.ComponentType<FieldComponentProps>;
|
|
289
|
+
integer?: default_2.ComponentType<FieldComponentProps>;
|
|
290
|
+
float?: default_2.ComponentType<FieldComponentProps>;
|
|
291
|
+
decimal?: default_2.ComponentType<FieldComponentProps>;
|
|
292
|
+
boolean?: default_2.ComponentType<FieldComponentProps>;
|
|
293
|
+
date?: default_2.ComponentType<FieldComponentProps>;
|
|
294
|
+
datetime?: default_2.ComponentType<FieldComponentProps>;
|
|
295
|
+
select?: default_2.ComponentType<FieldComponentProps>;
|
|
296
|
+
radio?: default_2.ComponentType<FieldComponentProps>;
|
|
297
|
+
'checkbox-group'?: default_2.ComponentType<FieldComponentProps>;
|
|
298
|
+
'relation-m2o'?: default_2.ComponentType<FieldComponentProps>;
|
|
299
|
+
'relation-o2m'?: default_2.ComponentType<FieldComponentProps>;
|
|
300
|
+
'relation-m2m'?: default_2.ComponentType<FieldComponentProps>;
|
|
301
|
+
wysiwyg?: default_2.ComponentType<FieldComponentProps>;
|
|
302
|
+
file?: default_2.ComponentType<FieldComponentProps>;
|
|
303
|
+
json?: default_2.ComponentType<FieldComponentProps>;
|
|
304
|
+
uuid?: default_2.ComponentType<FieldComponentProps>;
|
|
305
|
+
fallback?: default_2.ComponentType<FieldComponentProps>;
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
export declare function DataTable<T = Record<string, unknown>>({ columns, rows, rowKey, total, page, limit, isLoading, isError, errorMessage, sort, onSortChange, onPageChange, onRowClick, searchValue, onSearchChange, searchPlaceholder, filterDefs, filterValues, onFilterChange, toolbarRight, emptyMessage, minBodyHeight, fillHeight, hideFilterRow, nowrapCells, pinFirstColumn, columnPins, onColumnPinChange, columnFilterRow, hScrollProxy, selectedIds, onSelectionChange, rowClassName, rowGroups, collapsedGroups, onToggleGroup }: DataTableProps<T>): React_2.JSX.Element;
|
|
309
|
+
|
|
310
|
+
declare interface DataTableProps<T = Record<string, unknown>> {
|
|
311
|
+
columns: Column<T>[];
|
|
312
|
+
rows: T[];
|
|
313
|
+
rowKey?: (row: T, i: number) => string;
|
|
314
|
+
total: number;
|
|
315
|
+
page: number;
|
|
316
|
+
limit?: number;
|
|
317
|
+
isLoading?: boolean;
|
|
318
|
+
isError?: boolean;
|
|
319
|
+
errorMessage?: string;
|
|
320
|
+
sort?: string;
|
|
321
|
+
onSortChange?: (sort: string) => void;
|
|
322
|
+
onPageChange: (page: number) => void;
|
|
323
|
+
onRowClick?: (row: T) => void;
|
|
324
|
+
searchValue?: string;
|
|
325
|
+
onSearchChange?: (val: string) => void;
|
|
326
|
+
searchPlaceholder?: string;
|
|
327
|
+
filterDefs?: FilterDef[];
|
|
328
|
+
filterValues?: Record<string, string | string[]>;
|
|
329
|
+
onFilterChange?: (key: string, value: string | string[]) => void;
|
|
330
|
+
toolbarRight?: React_2.ReactNode;
|
|
331
|
+
emptyMessage?: string;
|
|
332
|
+
/** Suppress the inline filter-control row while keeping filterDefs available
|
|
333
|
+
* to the host (e.g. a page rendering its own filter rail). */
|
|
334
|
+
hideFilterRow?: boolean;
|
|
335
|
+
/** Force single-line cells (whitespace-nowrap on every body cell) — hosts
|
|
336
|
+
* pair this with per-column truncation for dense, scannable tables. */
|
|
337
|
+
nowrapCells?: boolean;
|
|
338
|
+
/** Pin the selection checkbox (when present) and the first data column so
|
|
339
|
+
* they stay visible while the table scrolls horizontally. */
|
|
340
|
+
pinFirstColumn?: boolean;
|
|
341
|
+
/** Per-column pinning (CollectionBrowserView parity). When provided (even
|
|
342
|
+
* empty), replaces `pinFirstColumn`: left-pinned columns render first,
|
|
343
|
+
* right-pinned last, sticky offsets come from live header-cell width
|
|
344
|
+
* measurement, and (with `onColumnPinChange`) every header grows a
|
|
345
|
+
* hover-revealed pin button cycling none → left → right → none. */
|
|
346
|
+
columnPins?: Record<string, 'left' | 'right'>;
|
|
347
|
+
onColumnPinChange?: (key: string, pin: 'left' | 'right' | null) => void;
|
|
348
|
+
/** Render a compact per-column filter row under the headers — each column
|
|
349
|
+
* whose key matches a FilterDef gets that def's control inline (the
|
|
350
|
+
* CollectionBrowserView column-filter pattern). Independent of the
|
|
351
|
+
* toolbar/rail rendering controlled by `hideFilterRow`. */
|
|
352
|
+
columnFilterRow?: boolean;
|
|
353
|
+
/** Always-visible draggable horizontal scrollbar under the table (the
|
|
354
|
+
* CollectionBrowserView HScrollProxy) — the native x-scrollbar is hidden
|
|
355
|
+
* and trackpad panning is translated by the proxy. */
|
|
356
|
+
hScrollProxy?: boolean;
|
|
357
|
+
/** Minimum height for the table body region — keeps empty/short tables from
|
|
358
|
+
* collapsing to a sliver (empty message centers in the space). */
|
|
359
|
+
minBodyHeight?: number;
|
|
360
|
+
/** Fill the parent's (bounded) height: rows scroll INSIDE the card under a
|
|
361
|
+
* sticky header, so the h-scroll proxy and pagination stay pinned in view
|
|
362
|
+
* instead of sitting below a page-tall table. Parent must give the card a
|
|
363
|
+
* definite height (flex chain with min-h-0). */
|
|
364
|
+
fillHeight?: boolean;
|
|
365
|
+
selectedIds?: string[];
|
|
366
|
+
onSelectionChange?: (ids: string[]) => void;
|
|
367
|
+
/** Optional per-row class — e.g. at-risk background tinting. */
|
|
368
|
+
rowClassName?: (row: T) => string | undefined;
|
|
369
|
+
/** Grouped rendering: when set, `rows` is ignored for the body; each group renders
|
|
370
|
+
* a full-width header row followed by its rows (unless collapsed). Pagination hides. */
|
|
371
|
+
rowGroups?: Array<{
|
|
372
|
+
key: string;
|
|
373
|
+
header: React_2.ReactNode;
|
|
374
|
+
rows: T[];
|
|
375
|
+
}>;
|
|
376
|
+
collapsedGroups?: Set<string>;
|
|
377
|
+
onToggleGroup?: (key: string) => void;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export declare function DateField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
|
|
381
|
+
|
|
382
|
+
/** The admin's route shape — the default when the host supplies no itemUrl. */
|
|
383
|
+
export declare function defaultItemUrl(t: ItemLinkTarget): string;
|
|
384
|
+
|
|
385
|
+
declare type DmOpener = (userId: string, displayName?: string) => void;
|
|
386
|
+
|
|
387
|
+
export declare function dmPeer(room: string, self: string): string | null;
|
|
388
|
+
|
|
389
|
+
export declare function dmRoom(a: string, b: string): string;
|
|
390
|
+
|
|
391
|
+
export declare const DrilldownContext: React_2.Context<DrilldownContextValue | null>;
|
|
392
|
+
|
|
393
|
+
declare interface DrilldownContextValue {
|
|
394
|
+
open: (target: DrilldownTarget) => void;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export declare interface DrilldownTarget {
|
|
398
|
+
collection: string;
|
|
399
|
+
itemId: string;
|
|
400
|
+
layoutId?: number | null;
|
|
401
|
+
width?: number | string | null;
|
|
402
|
+
title?: string;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* The ids a filter surface should PRE-SELECT for a dimension. Restrictions are
|
|
407
|
+
* server-enforced regardless, so the seeded selection must reflect them:
|
|
408
|
+
* defaults ∩ restricted when both are set; ALL restricted values when defaults
|
|
409
|
+
* are empty or entirely outside the restriction; plain defaults otherwise.
|
|
410
|
+
*/
|
|
411
|
+
export declare function effectiveScopeSeedIds(scopes: {
|
|
412
|
+
defaults: Record<string, Array<string | number>>;
|
|
413
|
+
restricted: Record<string, Array<string | number>>;
|
|
414
|
+
}, dimName: string): Array<string | number>;
|
|
415
|
+
|
|
416
|
+
export declare function fetchSchema(client: NivaroClient, collection: string, includeHidden: boolean, layoutId?: number, layoutSlug?: string): Promise<FormSchema>;
|
|
417
|
+
|
|
418
|
+
export declare type FieldArrayReturn = {
|
|
419
|
+
items: unknown[];
|
|
420
|
+
append: (item?: unknown) => void;
|
|
421
|
+
remove: (index: number) => void;
|
|
422
|
+
move: (from: number, to: number) => void;
|
|
423
|
+
update: (index: number, value: unknown) => void;
|
|
424
|
+
replace: (items: unknown[]) => void;
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
export declare type FieldComponentProps = {
|
|
428
|
+
field: FormFieldDescriptor;
|
|
429
|
+
value: unknown;
|
|
430
|
+
onChange: (value: unknown) => void;
|
|
431
|
+
error: string[] | undefined;
|
|
432
|
+
disabled: boolean;
|
|
433
|
+
readOnly: boolean;
|
|
434
|
+
/**
|
|
435
|
+
* Unique DOM id for the input element — generated by NivaroField via useId().
|
|
436
|
+
* Falls back to `field.field` when not provided (may collide if two forms
|
|
437
|
+
* with the same collection are mounted simultaneously).
|
|
438
|
+
*/
|
|
439
|
+
inputId?: string;
|
|
440
|
+
/** id of the error container element, for aria-describedby wiring */
|
|
441
|
+
errorId?: string;
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
export { FieldDependencyConfig }
|
|
445
|
+
|
|
446
|
+
export declare type FieldState = {
|
|
447
|
+
value: unknown;
|
|
448
|
+
error: string[] | undefined;
|
|
449
|
+
visible: boolean;
|
|
450
|
+
locked: boolean;
|
|
451
|
+
required: boolean;
|
|
452
|
+
colSpan: number;
|
|
453
|
+
descriptor: FormFieldDescriptor | null;
|
|
454
|
+
onChange: (v: unknown) => void;
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Unstyled file input. On selection it uploads via client.upload() (POST /files)
|
|
459
|
+
* and calls onChange with the returned file id. Renders the current id/url as text.
|
|
460
|
+
*
|
|
461
|
+
* On upload error the file input is reset via a key increment so the browser
|
|
462
|
+
* doesn't show the failed filename as if the upload succeeded.
|
|
463
|
+
*/
|
|
464
|
+
export declare function FileField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
|
|
465
|
+
|
|
466
|
+
declare interface FilterDef {
|
|
467
|
+
key: string;
|
|
468
|
+
placeholder: string;
|
|
469
|
+
/** Defaults to 'select' — every existing FilterDef without this field keeps its current dropdown behavior unchanged. */
|
|
470
|
+
type?: 'select' | 'text' | 'range' | 'combobox';
|
|
471
|
+
/** Required when type is 'select' or omitted; static options for 'combobox'; ignored for 'text'/'range'. */
|
|
472
|
+
options?: {
|
|
473
|
+
label: string;
|
|
474
|
+
value: string;
|
|
475
|
+
}[];
|
|
476
|
+
/** 'combobox' only: server-backed autocomplete. Called (debounced) with the search
|
|
477
|
+
* text; overrides `options` when provided. */
|
|
478
|
+
loadOptions?: (search: string) => Promise<{
|
|
479
|
+
label: string;
|
|
480
|
+
value: string;
|
|
481
|
+
}[]>;
|
|
482
|
+
/** 'combobox' only: allow selecting multiple values (filter matches ANY of them). */
|
|
483
|
+
multi?: boolean;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
export declare type FormDirtyState = {
|
|
487
|
+
isDirty: boolean;
|
|
488
|
+
dirtyFields: string[];
|
|
489
|
+
isFieldDirty: (field: string) => boolean;
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
export declare type FormErrors = Record<string, string[]>;
|
|
493
|
+
|
|
494
|
+
export declare type FormFieldDescriptor = {
|
|
495
|
+
field: string;
|
|
496
|
+
/** raw DB type (string, integer, boolean, uuid, json, …) */
|
|
497
|
+
type: string;
|
|
498
|
+
/** normalized type used to pick the rendering component */
|
|
499
|
+
fieldType: FormFieldType;
|
|
500
|
+
/** CMS interface string (input, select-dropdown, many-to-one, …) */
|
|
501
|
+
interface: string | null;
|
|
502
|
+
label: string;
|
|
503
|
+
note: string | null;
|
|
504
|
+
required: boolean;
|
|
505
|
+
readonly: boolean;
|
|
506
|
+
hidden: boolean;
|
|
507
|
+
sort: number | null;
|
|
508
|
+
/** field group key (null = ungrouped) */
|
|
509
|
+
group: string | null;
|
|
510
|
+
/** interface options (e.g. { choices: [{text, value}] } for selects) */
|
|
511
|
+
options: Record<string, unknown> | null;
|
|
512
|
+
validationRules: FormValidationRule[] | null;
|
|
513
|
+
visibilityRules: FormVisibilityRule[] | null;
|
|
514
|
+
lockCondition: FormLockCondition | null;
|
|
515
|
+
relation?: {
|
|
516
|
+
type: 'o2m' | 'm2o' | 'm2m' | 'm2a';
|
|
517
|
+
relatedCollection: string;
|
|
518
|
+
/** For M2M: the junction/pivot table (e.g. workflows_divisions). relatedCollection is the far-end. */
|
|
519
|
+
junctionCollection?: string | null;
|
|
520
|
+
displayTemplate: string | null;
|
|
521
|
+
manyField?: string | null;
|
|
522
|
+
junctionField?: string | null;
|
|
523
|
+
} | null;
|
|
524
|
+
defaultValue?: unknown;
|
|
525
|
+
/** cascade_filters from dependency_config — each rule links a parent field to a filter column */
|
|
526
|
+
cascadeFilters?: Array<{
|
|
527
|
+
parent_field: string;
|
|
528
|
+
filter_column: string;
|
|
529
|
+
clear_on_parent_change?: boolean;
|
|
530
|
+
}> | null;
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Normalized field type used by the form renderer to pick a component.
|
|
535
|
+
* Derived from the raw DB type + CMS interface string in `useFormSchema`.
|
|
536
|
+
*/
|
|
537
|
+
export declare type FormFieldType = 'text' | 'textarea' | 'integer' | 'float' | 'decimal' | 'boolean' | 'date' | 'datetime' | 'select' | 'radio' | 'checkbox-group' | 'relation-m2o' | 'relation-o2m' | 'relation-m2m' | 'wysiwyg' | 'file' | 'json' | 'uuid' | 'unknown';
|
|
538
|
+
|
|
539
|
+
export declare type FormGroupDescriptor = {
|
|
540
|
+
key: string;
|
|
541
|
+
label: string;
|
|
542
|
+
type: 'section' | 'tab';
|
|
543
|
+
icon: string | null;
|
|
544
|
+
sort: number;
|
|
545
|
+
isCollapsed: boolean;
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
/** A client-evaluable lock condition. */
|
|
549
|
+
export declare type FormLockCondition = {
|
|
550
|
+
when: string;
|
|
551
|
+
op: string;
|
|
552
|
+
value?: unknown;
|
|
553
|
+
};
|
|
554
|
+
|
|
555
|
+
export declare type FormSchema = {
|
|
556
|
+
collection: string;
|
|
557
|
+
displayName: string | null;
|
|
558
|
+
singleton: boolean;
|
|
559
|
+
draftPublishEnabled: boolean;
|
|
560
|
+
fields: FormFieldDescriptor[];
|
|
561
|
+
groups: FormGroupDescriptor[];
|
|
562
|
+
/** index of the Ungrouped zone among groups (null = after all groups) */
|
|
563
|
+
ungroupedSort: number | null;
|
|
564
|
+
/** 'steps' for step-wizard mode, 'tabs' or null for standard tabs */
|
|
565
|
+
tabMode: 'tabs' | 'steps' | null;
|
|
566
|
+
aiEnabled: boolean;
|
|
567
|
+
summaryEnabled: boolean;
|
|
568
|
+
validateBeforeNext: boolean;
|
|
569
|
+
/** Slot assignments from the active layout (__pipeline__, __comments__, __tasks__) */
|
|
570
|
+
slotAssignments: FormSlotAssignment[];
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
export declare type FormSlotAssignment = {
|
|
574
|
+
slot: string;
|
|
575
|
+
groupKey: string | null;
|
|
576
|
+
sort: number;
|
|
577
|
+
labelOverride: string | null;
|
|
578
|
+
isVisible: boolean;
|
|
579
|
+
defaultExpanded: boolean;
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
export declare type FormStatus = {
|
|
583
|
+
isDirty: boolean;
|
|
584
|
+
isValid: boolean;
|
|
585
|
+
isSubmitting: boolean;
|
|
586
|
+
isLoading: boolean;
|
|
587
|
+
canSubmit: boolean;
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
/** A single validation rule attached to a field. */
|
|
591
|
+
export declare type FormValidationRule = {
|
|
592
|
+
type: string;
|
|
593
|
+
value?: unknown;
|
|
594
|
+
message?: string;
|
|
595
|
+
/** soft = warning only, hard (default) = blocks save */
|
|
596
|
+
soft?: boolean;
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
/** A client-evaluable visibility rule. */
|
|
600
|
+
export declare type FormVisibilityRule = {
|
|
601
|
+
/** key of the field this rule observes */
|
|
602
|
+
when: string;
|
|
603
|
+
/** eq | neq | null | nnull | in | contains */
|
|
604
|
+
op: string;
|
|
605
|
+
value?: unknown;
|
|
606
|
+
action: 'show' | 'hide';
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
export declare function getMentionQuery(text: string, cursorPos: number): string | null;
|
|
610
|
+
|
|
611
|
+
export declare const GridFlushContext: React_2.Context<GridFlushContextValue | null>;
|
|
612
|
+
|
|
613
|
+
declare type GridFlushContextValue = {
|
|
614
|
+
register: (key: string, fn: () => Promise<void>) => void;
|
|
615
|
+
unregister: (key: string) => void;
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
declare interface HeaderWidgetInfo {
|
|
619
|
+
field: string;
|
|
620
|
+
widgetId: number;
|
|
621
|
+
label: string | null;
|
|
622
|
+
inputBindings: InputBinding[];
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
export declare function ImportConsole({ realtime, defaultTab, initialJobId, onJobOpen }: ImportConsoleProps): JSX.Element;
|
|
626
|
+
|
|
627
|
+
export declare interface ImportConsoleProps {
|
|
628
|
+
/**
|
|
629
|
+
* Live `import:progress` events. Hosts own the socket; without an adapter the
|
|
630
|
+
* console still tracks state on its poll, just up to 5s later.
|
|
631
|
+
*/
|
|
632
|
+
realtime?: ImportRealtimeAdapter;
|
|
633
|
+
/** Which section to open on. `definitions` is admin-only. */
|
|
634
|
+
defaultTab?: ImportConsoleTab;
|
|
635
|
+
/** Deep link into a collection-import job's detail (admin /imports/:id). */
|
|
636
|
+
initialJobId?: string | null;
|
|
637
|
+
/** Fires when a collection-import job's detail opens or closes, so a host
|
|
638
|
+
* can keep its own URL in step. */
|
|
639
|
+
onJobOpen?: (id: string | null) => void;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
export declare type ImportConsoleTab = 'runs' | 'collection' | 'definitions';
|
|
643
|
+
|
|
644
|
+
export declare interface ImportDefinition {
|
|
645
|
+
id: number;
|
|
646
|
+
key: string;
|
|
647
|
+
label: string | null;
|
|
648
|
+
description: string | null;
|
|
649
|
+
staging_table: string | null;
|
|
650
|
+
procedure: string | null;
|
|
651
|
+
loader: 'bulk' | 'insert' | null;
|
|
652
|
+
file_types: string | null;
|
|
653
|
+
is_active: boolean;
|
|
654
|
+
sort: number;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
export declare interface ImportJob {
|
|
658
|
+
id: string;
|
|
659
|
+
collection: string;
|
|
660
|
+
file_name: string;
|
|
661
|
+
column_map: Record<string, string> | null;
|
|
662
|
+
duplicate_strategy: string;
|
|
663
|
+
id_field: string | null;
|
|
664
|
+
status: ImportJobStatus;
|
|
665
|
+
total_rows: number | null;
|
|
666
|
+
processed_rows: number | null;
|
|
667
|
+
created_rows: number | null;
|
|
668
|
+
updated_rows: number | null;
|
|
669
|
+
skipped_rows: number | null;
|
|
670
|
+
error_rows: number | null;
|
|
671
|
+
errors: Array<{
|
|
672
|
+
row: number;
|
|
673
|
+
error: string;
|
|
674
|
+
}> | null;
|
|
675
|
+
created_by: string | null;
|
|
676
|
+
created_at: string;
|
|
677
|
+
started_at: string | null;
|
|
678
|
+
completed_at: string | null;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
export declare type ImportJobStatus = 'pending' | 'processing' | 'complete' | 'failed';
|
|
682
|
+
|
|
683
|
+
/** Result of `POST /staged-imports/preview` — the worker's own parse, run
|
|
684
|
+
* against the file before anything is queued. */
|
|
685
|
+
export declare interface ImportPreview {
|
|
686
|
+
row_count: number;
|
|
687
|
+
columns: string[];
|
|
688
|
+
rows: Array<Record<string, string>>;
|
|
689
|
+
file_name: string;
|
|
690
|
+
staging_table: string | null;
|
|
691
|
+
staging_columns: string[] | null;
|
|
692
|
+
unknown_columns: string[];
|
|
693
|
+
missing_columns: string[];
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/** Emitted by the worker on the `import:progress` socket event. */
|
|
697
|
+
export declare interface ImportProgressEvent {
|
|
698
|
+
id: number;
|
|
699
|
+
stage: 'row_count' | 'preparing' | 'importing' | 'completed' | 'error';
|
|
700
|
+
row_count?: number;
|
|
701
|
+
duration?: number;
|
|
702
|
+
error?: string;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Hosts own the socket (the shared package has no transport of its own — the
|
|
707
|
+
* same contract `QueueWorklist` uses for `collection:update`). Without an
|
|
708
|
+
* adapter the console still stays current on its 5s poll.
|
|
709
|
+
*/
|
|
710
|
+
export declare interface ImportRealtimeAdapter {
|
|
711
|
+
subscribe: (onProgress: (event: ImportProgressEvent) => void) => () => void;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
/** A row of `nivaro_import_queue`, joined with its definition, file and queuer. */
|
|
715
|
+
export declare interface ImportRun {
|
|
716
|
+
id: number;
|
|
717
|
+
definition: number | null;
|
|
718
|
+
import_key: string;
|
|
719
|
+
status: ImportRunStatus;
|
|
720
|
+
sort: number;
|
|
721
|
+
file: string | null;
|
|
722
|
+
row_count: number | null;
|
|
723
|
+
duration: number | null;
|
|
724
|
+
logs: string | null;
|
|
725
|
+
started_at: string | null;
|
|
726
|
+
finished_at: string | null;
|
|
727
|
+
created_by: string | null;
|
|
728
|
+
created_at: string | null;
|
|
729
|
+
updated_at: string | null;
|
|
730
|
+
legacy_id: number | null;
|
|
731
|
+
definition_label: string | null;
|
|
732
|
+
staging_table: string | null;
|
|
733
|
+
procedure: string | null;
|
|
734
|
+
loader: 'bulk' | 'insert' | null;
|
|
735
|
+
definition_active: boolean | null;
|
|
736
|
+
file_name: string | null;
|
|
737
|
+
file_size: string | number | null;
|
|
738
|
+
created_by_first_name: string | null;
|
|
739
|
+
created_by_last_name: string | null;
|
|
740
|
+
created_by_email: string | null;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/** Shared types for the Import Console (`/api/staged-imports`). */
|
|
744
|
+
export declare type ImportRunStatus = 'queued' | 'running' | 'completed' | 'error' | 'canceled';
|
|
745
|
+
|
|
746
|
+
/** Live queue depth is never windowed; the rest respects `window_days`. */
|
|
747
|
+
export declare interface ImportStats {
|
|
748
|
+
window_days: number;
|
|
749
|
+
by_status: Partial<Record<ImportRunStatus, number>>;
|
|
750
|
+
total: number;
|
|
751
|
+
/** Unwindowed — distinguishes "nothing has ever run" from "nothing recently". */
|
|
752
|
+
all_time_total: number;
|
|
753
|
+
/** Unwindowed run count per import key — a property of the definition. */
|
|
754
|
+
by_key: Record<string, number>;
|
|
755
|
+
rows_imported: number;
|
|
756
|
+
median_duration: number | null;
|
|
757
|
+
success_rate: number | null;
|
|
758
|
+
runs_today: number;
|
|
759
|
+
active: Array<{
|
|
760
|
+
id: number;
|
|
761
|
+
import_key: string;
|
|
762
|
+
status: 'queued' | 'running';
|
|
763
|
+
started_at: string | null;
|
|
764
|
+
created_at: string | null;
|
|
765
|
+
row_count: number | null;
|
|
766
|
+
}>;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
declare interface InputBinding {
|
|
770
|
+
key: string;
|
|
771
|
+
binding_type: 'item_field' | 'static' | 'url_param';
|
|
772
|
+
binding_value: string;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
export declare const ItemEditAuthContext: React_2.Context<ItemEditAuthContextValue>;
|
|
776
|
+
|
|
777
|
+
declare type ItemEditAuthContextValue = {
|
|
778
|
+
isAdmin: boolean;
|
|
779
|
+
userId: string;
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
export declare function ItemEditForm({ collection, itemId: itemIdProp, layoutSlug, onBack, onSaved, onDeleted, showHeader, showItemActions, showRevisions, showClone, showPipeline, showWorkflow, showComments, showTasks, showLockBanner, className, headerClassName, renderField, extraTopContent, extraBottomContent, onHeaderWidgets, initialImportResult, initialValues }: ItemEditFormProps): JSX.Element;
|
|
783
|
+
|
|
784
|
+
export declare interface ItemEditFormProps {
|
|
785
|
+
collection: string;
|
|
786
|
+
itemId?: string;
|
|
787
|
+
layoutSlug?: string;
|
|
788
|
+
onBack?: () => void;
|
|
789
|
+
onSaved?: (id: string) => void;
|
|
790
|
+
onDeleted?: () => void;
|
|
791
|
+
showHeader?: boolean;
|
|
792
|
+
/** Render extension-registered item actions (Push to Fusion etc.) in the
|
|
793
|
+
* header toolbar. Off by default — the admin's ItemEdit page renders its
|
|
794
|
+
* own copy in the page header; headless hosts opt in. */
|
|
795
|
+
showItemActions?: boolean;
|
|
796
|
+
showRevisions?: boolean;
|
|
797
|
+
showClone?: boolean;
|
|
798
|
+
showPipeline?: boolean;
|
|
799
|
+
showWorkflow?: boolean;
|
|
800
|
+
showComments?: boolean;
|
|
801
|
+
showTasks?: boolean;
|
|
802
|
+
showLockBanner?: boolean;
|
|
803
|
+
className?: string;
|
|
804
|
+
headerClassName?: string;
|
|
805
|
+
renderField?: (props: RenderFieldProps) => ReactNode;
|
|
806
|
+
extraTopContent?: ReactNode;
|
|
807
|
+
extraBottomContent?: ReactNode;
|
|
808
|
+
onHeaderWidgets?: (widgets: HeaderWidgetInfo[]) => void;
|
|
809
|
+
/** Consumed once, on mount, when `isNew` — prefills the draft + stages O2M
|
|
810
|
+
* lines from an already-parsed import result (e.g. handed off by a caller
|
|
811
|
+
* that ran the file picker before this form existed). */
|
|
812
|
+
initialImportResult?: ImportParseResponse;
|
|
813
|
+
/** Consumed once, on mount, when `isNew` — seeds the draft with plain field
|
|
814
|
+
* values (deep-link prefill, "create from common values", AI hand-offs).
|
|
815
|
+
* User edits made before the seed applies win over seeded keys. */
|
|
816
|
+
initialValues?: Record<string, unknown>;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/** A record the UI wants to link to / open the edit page for. */
|
|
820
|
+
export declare type ItemLinkTarget = {
|
|
821
|
+
collection: string;
|
|
822
|
+
itemId: string;
|
|
823
|
+
/** Grouped-layout slug to pin (queue item_layout etc.); null/absent = default. */
|
|
824
|
+
layoutSlug?: string | null;
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
export declare function ItemLockBanner({ lockHolder, onTakeOver, takingOver, isAdmin }: {
|
|
828
|
+
lockHolder: LockHolder | null;
|
|
829
|
+
onTakeOver: () => void;
|
|
830
|
+
takingOver: boolean;
|
|
831
|
+
isAdmin?: boolean;
|
|
832
|
+
}): JSX.Element | null;
|
|
833
|
+
|
|
834
|
+
/**
|
|
835
|
+
* Full layout-aware form renderer.
|
|
836
|
+
*
|
|
837
|
+
* Renders the form exactly as configured in the Layout tab:
|
|
838
|
+
* - Tab-type groups become clickable tabs (or step wizards when tabMode='steps')
|
|
839
|
+
* - Section-type groups become collapsible sections
|
|
840
|
+
* - Ungrouped fields appear at the position set in the Layout tab
|
|
841
|
+
* - Fields honour their col_span width inside a 12-column grid
|
|
842
|
+
* - Page slots (__pipeline__, __comments__, __tasks__) rendered via slotRenderers
|
|
843
|
+
*
|
|
844
|
+
* Zero CSS shipped — style via className props or data-* attributes.
|
|
845
|
+
*/
|
|
846
|
+
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;
|
|
847
|
+
|
|
848
|
+
declare type LayoutFormProps = {
|
|
849
|
+
form: UseNivaroFormReturn;
|
|
850
|
+
components?: ComponentOverrides;
|
|
851
|
+
/** CSS class applied to the <form> element */
|
|
852
|
+
className?: string;
|
|
853
|
+
style?: default_2.CSSProperties;
|
|
854
|
+
/** CSS class for a section group wrapper */
|
|
855
|
+
sectionClassName?: string;
|
|
856
|
+
/** CSS class for a tab strip wrapper */
|
|
857
|
+
tabStripClassName?: string;
|
|
858
|
+
/** CSS class for the active tab button */
|
|
859
|
+
activeTabClassName?: string;
|
|
860
|
+
/** CSS class for inactive tab buttons */
|
|
861
|
+
inactiveTabClassName?: string;
|
|
862
|
+
/** CSS class for the 12-col grid row (col_span chips snap to this) */
|
|
863
|
+
gridClassName?: string;
|
|
864
|
+
/**
|
|
865
|
+
* Slot renderers — keyed by slot name (__pipeline__, __comments__, __tasks__).
|
|
866
|
+
* Called with { slot, collection, itemId, labelOverride, defaultExpanded }.
|
|
867
|
+
* If omitted, slots are silently skipped.
|
|
868
|
+
*/
|
|
869
|
+
slotRenderers?: Record<string, (props: SlotRendererProps) => default_2.ReactNode>;
|
|
870
|
+
/**
|
|
871
|
+
* itemId of the currently-loaded item — needed for slot renderers.
|
|
872
|
+
* For edit mode: pass the item id. For create mode: leave undefined.
|
|
873
|
+
*/
|
|
874
|
+
itemId?: string | number | null;
|
|
875
|
+
/** CSS class for the stepper strip wrapper (steps mode) */
|
|
876
|
+
stepperClassName?: string;
|
|
877
|
+
/** CSS class for the prev/next button bar (steps mode) */
|
|
878
|
+
stepNavClassName?: string;
|
|
879
|
+
/** CSS class for the Prev button */
|
|
880
|
+
prevButtonClassName?: string;
|
|
881
|
+
/** CSS class for the Next/Save button */
|
|
882
|
+
nextButtonClassName?: string;
|
|
883
|
+
/** Extra content rendered before the Save button on the last step (steps mode only) */
|
|
884
|
+
lastStepActions?: default_2.ReactNode;
|
|
885
|
+
/**
|
|
886
|
+
* Layout slug that was used to load this form's schema.
|
|
887
|
+
* Informational only — schema resolution happens in useNivaroForm.
|
|
888
|
+
*/
|
|
889
|
+
layoutSlug?: string;
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
export declare type LayoutItem = FormGroupDescriptor | '__ungrouped__';
|
|
893
|
+
|
|
894
|
+
declare interface LockHolder {
|
|
895
|
+
locked_by: string;
|
|
896
|
+
locked_by_name: string | null;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
/** Match a filter surface (by its own key and/or its options collection) to a
|
|
900
|
+
* scope dimension. Convention: key === dimension name wins, else the filter's
|
|
901
|
+
* options collection === the dimension's target collection. */
|
|
902
|
+
export declare function matchScopeDimension(scopes: UserScopesInfo | null, probe: {
|
|
903
|
+
key?: string;
|
|
904
|
+
collection?: string;
|
|
905
|
+
}): UserScopesInfo['dimensions'][number] | null;
|
|
906
|
+
|
|
907
|
+
declare interface MessageToken {
|
|
908
|
+
text: string;
|
|
909
|
+
entity?: string;
|
|
910
|
+
mention?: string;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
export declare const NavigationContext: React_2.Context<NavigationContextValue>;
|
|
914
|
+
|
|
915
|
+
declare type NavigationContextValue = {
|
|
916
|
+
/** `options.state` rides along for hosts whose router supports it (e.g. react-router's
|
|
917
|
+
* useNavigate) — hosts that ignore the second argument still navigate correctly. */
|
|
918
|
+
navigate: (path: string, options?: {
|
|
919
|
+
state?: unknown;
|
|
920
|
+
}) => void;
|
|
921
|
+
/** Map item links onto the host app's own routes. Components fall back to
|
|
922
|
+
* the admin shape (/collections/:collection/:id?layout=…) when absent —
|
|
923
|
+
* external embeds supply one function and every open path follows. */
|
|
924
|
+
itemUrl?: (target: ItemLinkTarget) => string;
|
|
925
|
+
/** Full interception of item-opening: return true = handled (components
|
|
926
|
+
* skip navigation entirely — open your own modal/drawer instead). Checked
|
|
927
|
+
* before itemUrl/navigate. */
|
|
928
|
+
openItem?: (target: ItemLinkTarget) => boolean | undefined;
|
|
929
|
+
/** Route for a user's profile page (UserChip "View profile"). Absent = the
|
|
930
|
+
* admin shape `/users/:id`; return null = host has no such page, the
|
|
931
|
+
* action is hidden instead of navigating into the host's 404 fallback. */
|
|
932
|
+
userUrl?: (userId: string) => string | null;
|
|
933
|
+
};
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* Selects and renders the correct field component for a single field based on
|
|
937
|
+
* its normalized fieldType. Override any type via `components`; falls back to
|
|
938
|
+
* `components.fallback` or a basic text input for unknown types.
|
|
939
|
+
*
|
|
940
|
+
* Uses React 18's useId() to generate a unique DOM id per field instance so
|
|
941
|
+
* two forms with the same collection mounted simultaneously don't collide.
|
|
942
|
+
*/
|
|
943
|
+
export declare function NivaroField({ field, value, onChange, error, disabled, readOnly, components, className, itemId }: NivaroFieldProps): default_2.JSX.Element;
|
|
944
|
+
|
|
945
|
+
declare type NivaroFieldProps = {
|
|
946
|
+
field: FormFieldDescriptor;
|
|
947
|
+
value: unknown;
|
|
948
|
+
onChange: (value: unknown) => void;
|
|
949
|
+
error?: string[];
|
|
950
|
+
disabled?: boolean;
|
|
951
|
+
readOnly?: boolean;
|
|
952
|
+
components?: ComponentOverrides;
|
|
953
|
+
className?: string;
|
|
954
|
+
/** Parent item id — passed through to inline-grid fields */
|
|
955
|
+
itemId?: string | number | null;
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* Optional convenience wrapper that renders a <form> driven by useNivaroForm.
|
|
960
|
+
* Provide `children` to fully control layout, or omit them to auto-render every
|
|
961
|
+
* group and its fields via NivaroField.
|
|
962
|
+
*/
|
|
963
|
+
export declare function NivaroForm({ form, children, components, renderField, renderGroup, className, style }: NivaroFormProps): default_2.JSX.Element;
|
|
964
|
+
|
|
965
|
+
declare type NivaroFormProps = {
|
|
966
|
+
/** the object returned by useNivaroForm */
|
|
967
|
+
form: UseNivaroFormReturn;
|
|
968
|
+
/** custom render children; if omitted the form auto-renders all fields/groups */
|
|
969
|
+
children?: default_2.ReactNode;
|
|
970
|
+
/** override specific field-type renderers */
|
|
971
|
+
components?: ComponentOverrides;
|
|
972
|
+
/** wrap/replace the rendering of a single field */
|
|
973
|
+
renderField?: (field: FormFieldDescriptor, defaultRender: () => default_2.ReactNode) => default_2.ReactNode;
|
|
974
|
+
/** wrap/replace the rendering of a group + its fields */
|
|
975
|
+
renderGroup?: (group: FormGroupDescriptor | null, fields: default_2.ReactNode) => default_2.ReactNode;
|
|
976
|
+
className?: string;
|
|
977
|
+
style?: default_2.CSSProperties;
|
|
978
|
+
};
|
|
979
|
+
|
|
980
|
+
export declare function NivaroProvider({ client, children }: {
|
|
981
|
+
client: NivaroClient;
|
|
982
|
+
children: React_2.ReactNode;
|
|
983
|
+
}): React_2.JSX.Element;
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* Map a raw DB type + CMS interface string to the normalized FormFieldType
|
|
987
|
+
* the renderer uses to choose a component.
|
|
988
|
+
*/
|
|
989
|
+
export declare function normalizeFieldType(rawType: string, iface: string | null, relation: FormFieldDescriptor['relation']): FormFieldType;
|
|
990
|
+
|
|
991
|
+
export declare function NumberField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
|
|
992
|
+
|
|
993
|
+
declare interface O2MFieldInfo {
|
|
994
|
+
field: string;
|
|
995
|
+
label: string;
|
|
996
|
+
relatedCollection: string;
|
|
997
|
+
manyField: string;
|
|
998
|
+
parentId: string;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
export declare function openDmWith(userId: string, displayName?: string): void;
|
|
1002
|
+
|
|
1003
|
+
export declare function OwnerAvatars({ owners, max, emptyLabel }: {
|
|
1004
|
+
owners: OwnerLike[];
|
|
1005
|
+
max?: number;
|
|
1006
|
+
emptyLabel?: string;
|
|
1007
|
+
}): JSX.Element;
|
|
1008
|
+
|
|
1009
|
+
declare interface OwnerLike {
|
|
1010
|
+
id: string;
|
|
1011
|
+
name: string;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
export declare function PageRenderer({ slug, hideHeader, className }: PageRendererProps): JSX.Element;
|
|
1015
|
+
|
|
1016
|
+
export declare interface PageRendererPage {
|
|
1017
|
+
slug: string;
|
|
1018
|
+
name: string;
|
|
1019
|
+
layout?: {
|
|
1020
|
+
columns?: number;
|
|
1021
|
+
widgets?: PageRendererWidget[];
|
|
1022
|
+
} | null;
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
export declare interface PageRendererProps {
|
|
1026
|
+
/** nivaro_pages slug to render. */
|
|
1027
|
+
slug: string;
|
|
1028
|
+
/** Hide the page-name header row (host renders its own chrome). */
|
|
1029
|
+
hideHeader?: boolean;
|
|
1030
|
+
className?: string;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
export declare interface PageRendererWidget {
|
|
1034
|
+
id: string;
|
|
1035
|
+
type: string;
|
|
1036
|
+
x: number;
|
|
1037
|
+
y: number;
|
|
1038
|
+
w: number;
|
|
1039
|
+
h: number;
|
|
1040
|
+
config?: Record<string, unknown>;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
declare interface PendingTask {
|
|
1044
|
+
title: string;
|
|
1045
|
+
assignee: string | null;
|
|
1046
|
+
due_date: string;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
export declare function PipelinePanel({ collection, item, defaultExpanded, title, showApprovalChain, onBeforeTransition, addendumPending }: {
|
|
1050
|
+
collection: string;
|
|
1051
|
+
item: string;
|
|
1052
|
+
defaultExpanded?: boolean;
|
|
1053
|
+
title?: string;
|
|
1054
|
+
showApprovalChain?: boolean;
|
|
1055
|
+
onBeforeTransition?: () => boolean;
|
|
1056
|
+
addendumPending?: boolean;
|
|
1057
|
+
}): JSX.Element | null;
|
|
1058
|
+
|
|
1059
|
+
export declare function PipelineTransitionButtons({ collection, item, onBeforeTransition }: {
|
|
1060
|
+
collection: string;
|
|
1061
|
+
item: string;
|
|
1062
|
+
onBeforeTransition?: () => boolean;
|
|
1063
|
+
}): JSX.Element | null;
|
|
1064
|
+
|
|
1065
|
+
export declare function ProfileView({ userId, className }: {
|
|
1066
|
+
userId?: string | null;
|
|
1067
|
+
className?: string;
|
|
1068
|
+
}): JSX.Element;
|
|
1069
|
+
|
|
1070
|
+
export declare function QueryWidgetBody({ cfg, dateRange, entityFilters, refetchInterval, onStatus, onDrill }: {
|
|
1071
|
+
cfg: ReportQueryWidgetConfig;
|
|
1072
|
+
dateRange: ReportDateRange | null;
|
|
1073
|
+
entityFilters: ReportEntityFilter[];
|
|
1074
|
+
refetchInterval?: number;
|
|
1075
|
+
onStatus?: (s: {
|
|
1076
|
+
isFetching: boolean;
|
|
1077
|
+
refetch: () => void;
|
|
1078
|
+
}) => void;
|
|
1079
|
+
onDrill?: (t: {
|
|
1080
|
+
collection: string;
|
|
1081
|
+
itemId: string;
|
|
1082
|
+
title?: string;
|
|
1083
|
+
}) => void;
|
|
1084
|
+
}): JSX.Element;
|
|
1085
|
+
|
|
1086
|
+
export declare function QueueBulkBar({ count, states, busy, claimsEnabled, onClaim, onRelease, onTransition, onClear }: {
|
|
1087
|
+
count: number;
|
|
1088
|
+
states: Array<{
|
|
1089
|
+
value: string;
|
|
1090
|
+
label: string;
|
|
1091
|
+
}>;
|
|
1092
|
+
busy: boolean;
|
|
1093
|
+
claimsEnabled?: boolean;
|
|
1094
|
+
onClaim: () => void;
|
|
1095
|
+
onRelease: () => void;
|
|
1096
|
+
onTransition: (state: string) => void;
|
|
1097
|
+
onClear: () => void;
|
|
1098
|
+
}): JSX.Element | null;
|
|
1099
|
+
|
|
1100
|
+
declare interface QueueItemRow {
|
|
1101
|
+
collection: string;
|
|
1102
|
+
item_id: string;
|
|
1103
|
+
label: string;
|
|
1104
|
+
state: string | null;
|
|
1105
|
+
state_color: string | null;
|
|
1106
|
+
owners: QueueOwner_2[];
|
|
1107
|
+
sla_status: 'ok' | 'warning' | 'breached' | null;
|
|
1108
|
+
at_risk: boolean;
|
|
1109
|
+
aging_hours: number | null;
|
|
1110
|
+
claimed_by: QueueOwner_2 | null;
|
|
1111
|
+
url: string;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
export declare function QueueItemSheet({ item, onOpenChange, onClaim, onRelease, workNextActive, onNext, refetchItems, stateLabels, collectionLabel, claimsEnabled, columnFormats, width, itemLayout }: {
|
|
1115
|
+
item: SheetItem | null;
|
|
1116
|
+
onOpenChange: (open: boolean) => void;
|
|
1117
|
+
onClaim: (item: SheetItem) => void;
|
|
1118
|
+
onRelease: (item: SheetItem) => void;
|
|
1119
|
+
workNextActive?: boolean;
|
|
1120
|
+
onNext?: () => void;
|
|
1121
|
+
refetchItems: () => void;
|
|
1122
|
+
/** State key → display label (falls back to the raw key). */
|
|
1123
|
+
stateLabels?: Record<string, string>;
|
|
1124
|
+
/** Collection name → display name. */
|
|
1125
|
+
collectionLabel?: (name: string) => string;
|
|
1126
|
+
/** When false the claim/release button is hidden. */
|
|
1127
|
+
claimsEnabled?: boolean;
|
|
1128
|
+
/** Extra-field path → display format config (display-only). */
|
|
1129
|
+
columnFormats?: Record<string, ColumnFormatConfig>;
|
|
1130
|
+
/** Sidebar width: px number or 'NN%' of viewport; default 480. */
|
|
1131
|
+
width?: number | string | null;
|
|
1132
|
+
/** Layout slug the Open button pins on the full item; null = default. */
|
|
1133
|
+
itemLayout?: string | null;
|
|
1134
|
+
}): JSX.Element;
|
|
1135
|
+
|
|
1136
|
+
export declare function QueueKanbanBoard({ items, onDrop, onCardClick, onClaim, onRelease, swimlaneBy, stateLabels, laneLabel, claimsEnabled }: {
|
|
1137
|
+
items: QueueItemRow[];
|
|
1138
|
+
onDrop: (item: QueueItemRow, targetState: string) => void;
|
|
1139
|
+
onCardClick: (item: QueueItemRow) => void;
|
|
1140
|
+
onClaim: (item: QueueItemRow) => void;
|
|
1141
|
+
onRelease: (item: QueueItemRow) => void;
|
|
1142
|
+
/** Optional horizontal lanes crossed with the state columns. */
|
|
1143
|
+
swimlaneBy?: 'collection' | 'owners' | null;
|
|
1144
|
+
/** State key → display label (falls back to the raw key). */
|
|
1145
|
+
stateLabels?: Record<string, string>;
|
|
1146
|
+
/** Formats lane keys (e.g. collection names → display names). */
|
|
1147
|
+
laneLabel?: (key: string) => string;
|
|
1148
|
+
/** When false the per-card Claim/Release button is hidden. */
|
|
1149
|
+
claimsEnabled?: boolean;
|
|
1150
|
+
}): JSX.Element;
|
|
1151
|
+
|
|
1152
|
+
declare interface QueueOwner {
|
|
1153
|
+
id: string;
|
|
1154
|
+
name: string;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
declare interface QueueOwner_2 {
|
|
1158
|
+
id: string;
|
|
1159
|
+
name: string;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
export declare interface QueueRealtimeAdapter {
|
|
1163
|
+
/** Subscribe to update events for these collections; call onUpdate per event; return unsubscribe. */
|
|
1164
|
+
subscribe: (collections: string[], onUpdate: () => void) => () => void;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
export declare function QueueWorklist({ queueId, realtime, renderError }: QueueWorklistProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | ReactPortal | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | JSX.Element | null;
|
|
1168
|
+
|
|
1169
|
+
export declare interface QueueWorklistProps {
|
|
1170
|
+
queueId: string;
|
|
1171
|
+
realtime?: QueueRealtimeAdapter;
|
|
1172
|
+
renderError?: (status: number) => React.ReactNode;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
export declare function QueueWorkloadView({ queueId }: {
|
|
1176
|
+
queueId: string;
|
|
1177
|
+
}): JSX.Element;
|
|
1178
|
+
|
|
1179
|
+
declare interface QuickFilterDef {
|
|
1180
|
+
/** Unique key for this filter's selection state. */
|
|
1181
|
+
key: string;
|
|
1182
|
+
label: string;
|
|
1183
|
+
/** Server condition path — supports M2O chains and O2M/M2M alias hops
|
|
1184
|
+
* (e.g. ['funding_years'], ['project', 'project_type']). */
|
|
1185
|
+
path: string[];
|
|
1186
|
+
/** When set, the selection matches if ANY of these paths hits (server _or
|
|
1187
|
+
* group) — e.g. project.project_type OR car_project_type. Overrides path. */
|
|
1188
|
+
or_paths?: string[][];
|
|
1189
|
+
/** Collection the options list loads from. */
|
|
1190
|
+
collection: string;
|
|
1191
|
+
/** Option value column (default 'id'). */
|
|
1192
|
+
value_field?: string;
|
|
1193
|
+
/** Option label column. */
|
|
1194
|
+
label_field: string;
|
|
1195
|
+
sort?: string;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
export declare function RecordDrilldownSheet({ collection, itemId, layoutId, rootLayoutSlug, width, title, onClose }: {
|
|
1199
|
+
collection: string;
|
|
1200
|
+
itemId: string;
|
|
1201
|
+
layoutId?: number | null;
|
|
1202
|
+
/** Render the ROOT record with this exact layout slug (a queue's configured
|
|
1203
|
+
* grouped item_layout), bypassing detail-layout resolution. Nested drills
|
|
1204
|
+
* still use detail layouts. */
|
|
1205
|
+
rootLayoutSlug?: string | null;
|
|
1206
|
+
/** Panel width per config: px number or 'NN%' of the viewport; default 640. */
|
|
1207
|
+
width?: number | string | null;
|
|
1208
|
+
title?: string;
|
|
1209
|
+
onClose: () => void;
|
|
1210
|
+
}): JSX.Element;
|
|
1211
|
+
|
|
1212
|
+
/** Register the host's DM opener. Returns an unregister function. */
|
|
1213
|
+
export declare function registerDmOpener(fn: DmOpener): () => void;
|
|
1214
|
+
|
|
1215
|
+
/**
|
|
1216
|
+
* Unstyled relation picker.
|
|
1217
|
+
* - m2o: single <select> of related items
|
|
1218
|
+
* - o2m / m2m: multi <select> of related item ids
|
|
1219
|
+
*
|
|
1220
|
+
* Options are fetched from the related collection via useRelationOptions and
|
|
1221
|
+
* labelled with the relation's display template.
|
|
1222
|
+
*
|
|
1223
|
+
* If no NivaroClient is available (neither via NivaroProvider nor passed
|
|
1224
|
+
* directly to the field consumer), a visible error is shown instead of a
|
|
1225
|
+
* silently-empty picker.
|
|
1226
|
+
*/
|
|
1227
|
+
export declare function RelationField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
|
|
1228
|
+
|
|
1229
|
+
export declare type RelationOption = {
|
|
1230
|
+
id: string | number;
|
|
1231
|
+
label: string;
|
|
1232
|
+
raw: Record<string, unknown>;
|
|
1233
|
+
};
|
|
1234
|
+
|
|
1235
|
+
declare type RenderFieldProps = {
|
|
1236
|
+
field: any;
|
|
1237
|
+
value: unknown;
|
|
1238
|
+
onChange: (v: unknown) => void;
|
|
1239
|
+
disabled: boolean;
|
|
1240
|
+
collection: string;
|
|
1241
|
+
itemId: string;
|
|
1242
|
+
relations: any[];
|
|
1243
|
+
cascadeFilter?: Record<string, unknown>;
|
|
1244
|
+
unsatisfiedParentLabel?: string | null;
|
|
1245
|
+
requiredParentLabel?: string | null;
|
|
1246
|
+
};
|
|
1247
|
+
|
|
1248
|
+
export declare function ReportView({ reportId, showFilterBar, dateRange, initialEntityFilters, refetchInterval, className, emptyState }: ReportViewProps): JSX.Element;
|
|
1249
|
+
|
|
1250
|
+
/**
|
|
1251
|
+
* ReportView — the full, styled, interactive Report Studio renderer for
|
|
1252
|
+
* headless frontends, matching how QueueWorklist / ItemEditForm ship.
|
|
1253
|
+
*
|
|
1254
|
+
* Fully Tailwind-styled (bring the styles via `@nivaro/react/full.css` or the
|
|
1255
|
+
* Tailwind preset, exactly like the other shared components) and interactive:
|
|
1256
|
+
* a global filter bar (date-range switcher + live entity-filter chips), and
|
|
1257
|
+
* per-widget freshness + one-click refresh. Every widget resolves as the
|
|
1258
|
+
* client identity — collection read permissions apply server-side. Charts use
|
|
1259
|
+
* recharts (bundled into the react package). Read-only: no drag/resize edit
|
|
1260
|
+
* surface (that lives in the admin builder).
|
|
1261
|
+
*/
|
|
1262
|
+
export declare interface ReportViewProps {
|
|
1263
|
+
reportId: string;
|
|
1264
|
+
/** Show the global filter bar (date range + entity chips). Default true. */
|
|
1265
|
+
showFilterBar?: boolean;
|
|
1266
|
+
/** Override the report's saved date range at view time. */
|
|
1267
|
+
dateRange?: ReportDateRange | null;
|
|
1268
|
+
/** Initial report-level entity filters. */
|
|
1269
|
+
initialEntityFilters?: ReportEntityFilter[];
|
|
1270
|
+
/** Poll interval (ms) for live refresh; omit for one-shot. */
|
|
1271
|
+
refetchInterval?: number;
|
|
1272
|
+
className?: string;
|
|
1273
|
+
emptyState?: React.ReactNode;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
export declare function RevisionsPanel({ collection, item, onRollback, triggerClassName, inlineTableFields, open, onOpenChange }: {
|
|
1277
|
+
collection: string;
|
|
1278
|
+
item: string;
|
|
1279
|
+
onRollback?: () => void;
|
|
1280
|
+
triggerClassName?: string;
|
|
1281
|
+
inlineTableFields?: O2MFieldInfo[];
|
|
1282
|
+
/** Controlled mode (no trigger button) — open the sheet programmatically,
|
|
1283
|
+
* e.g. from a row Actions menu. */
|
|
1284
|
+
open?: boolean;
|
|
1285
|
+
onOpenChange?: (open: boolean) => void;
|
|
1286
|
+
}): JSX.Element;
|
|
1287
|
+
|
|
1288
|
+
export declare interface RoomInfo {
|
|
1289
|
+
room: string;
|
|
1290
|
+
label: string;
|
|
1291
|
+
kind: 'global' | 'dm' | 'channel' | 'entity';
|
|
1292
|
+
lastMessage: ChatMessage | null;
|
|
1293
|
+
unread: number;
|
|
1294
|
+
muted: boolean;
|
|
1295
|
+
joined: boolean;
|
|
1296
|
+
channel: ChannelMeta | null;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
export declare type SectionState = {
|
|
1300
|
+
isCollapsed: (key: string) => boolean;
|
|
1301
|
+
toggle: (key: string) => void;
|
|
1302
|
+
collapseAll: () => void;
|
|
1303
|
+
expandAll: () => void;
|
|
1304
|
+
};
|
|
1305
|
+
|
|
1306
|
+
export declare function SelectField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
|
|
1307
|
+
|
|
1308
|
+
/**
|
|
1309
|
+
* rrweb session recorder for headless frontends.
|
|
1310
|
+
*
|
|
1311
|
+
* Drop `useSessionRecorder({ app: 'customer-portal' })` anywhere inside a
|
|
1312
|
+
* NivaroProvider (or pass a client explicitly) and the app records itself —
|
|
1313
|
+
* ONLY when the Nivaro instance has session recording enabled in Settings,
|
|
1314
|
+
* and ONLY if the host app has `rrweb` installed (optional peer dependency;
|
|
1315
|
+
* without it the hook warns once and no-ops).
|
|
1316
|
+
*
|
|
1317
|
+
* Privacy defaults match the admin recorder: every input masked before
|
|
1318
|
+
* events leave the browser, elements with the `nvr-no-record` class blocked.
|
|
1319
|
+
* Events flush every 10s (or 150 events); the server enforces size caps and
|
|
1320
|
+
* a 7-day retention. Recordings attribute to the authenticated SDK identity
|
|
1321
|
+
* (usually your service token's user) with the `app` label telling replays
|
|
1322
|
+
* apart per frontend.
|
|
1323
|
+
*/
|
|
1324
|
+
export declare interface SessionRecorderOptions {
|
|
1325
|
+
/** Label shown in the admin replay list — which frontend this is. */
|
|
1326
|
+
app?: string;
|
|
1327
|
+
/** Explicit client; defaults to the NivaroProvider context client. */
|
|
1328
|
+
client?: NivaroClient;
|
|
1329
|
+
/** Force-disable locally regardless of the instance setting. */
|
|
1330
|
+
disabled?: boolean;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
declare interface SheetItem {
|
|
1334
|
+
collection: string;
|
|
1335
|
+
item_id: string;
|
|
1336
|
+
label: string;
|
|
1337
|
+
state: string | null;
|
|
1338
|
+
state_color: string | null;
|
|
1339
|
+
owners: QueueOwner[];
|
|
1340
|
+
sla_status: 'ok' | 'warning' | 'breached' | null;
|
|
1341
|
+
at_risk: boolean;
|
|
1342
|
+
aging_hours: number | null;
|
|
1343
|
+
claimed_by: QueueOwner | null;
|
|
1344
|
+
extra?: Record<string, unknown>;
|
|
1345
|
+
url: string;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
export declare type SlotRendererProps = {
|
|
1349
|
+
slot: string;
|
|
1350
|
+
collection: string;
|
|
1351
|
+
itemId: string | number | null | undefined;
|
|
1352
|
+
labelOverride: string | null;
|
|
1353
|
+
defaultExpanded: boolean;
|
|
1354
|
+
};
|
|
1355
|
+
|
|
1356
|
+
export declare function splitMessageTokens(text: string, entityPattern: string): MessageToken[];
|
|
1357
|
+
|
|
1358
|
+
declare type TabKey = 'catalog' | 'rules' | 'subscriptions' | 'history' | 'widget_alerts' | 'widget_alert_history' | 'anomaly_rules' | 'anomaly_history';
|
|
1359
|
+
|
|
1360
|
+
export declare type TabState = {
|
|
1361
|
+
activeTab: string | null;
|
|
1362
|
+
setActiveTab: (key: string) => void;
|
|
1363
|
+
tabs: FormGroupDescriptor[];
|
|
1364
|
+
hasTabs: boolean;
|
|
1365
|
+
};
|
|
1366
|
+
|
|
1367
|
+
export declare function TaskPanel({ collection, item, title, defaultExpanded, queuedTasks, onQueueTask }: {
|
|
1368
|
+
collection: string;
|
|
1369
|
+
item: string;
|
|
1370
|
+
title?: string;
|
|
1371
|
+
defaultExpanded?: boolean;
|
|
1372
|
+
queuedTasks?: PendingTask[];
|
|
1373
|
+
onQueueTask?: (task: PendingTask) => void;
|
|
1374
|
+
}): JSX.Element | null;
|
|
1375
|
+
|
|
1376
|
+
export declare function TextareaField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
|
|
1377
|
+
|
|
1378
|
+
export declare function TextField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
|
|
1379
|
+
|
|
1380
|
+
/**
|
|
1381
|
+
* Translate scope values (target-collection IDS) into a filter's value space.
|
|
1382
|
+
* When the filter compares ids (valueField 'id'/undefined) this is identity;
|
|
1383
|
+
* otherwise the target collection is fetched once to map id → valueField.
|
|
1384
|
+
*/
|
|
1385
|
+
export declare function translateScopeValues(client: {
|
|
1386
|
+
request: (c: unknown) => Promise<unknown>;
|
|
1387
|
+
}, dimension: {
|
|
1388
|
+
target_collection: string;
|
|
1389
|
+
}, ids: Array<string | number>, valueField?: string): Promise<Array<string | number>>;
|
|
1390
|
+
|
|
1391
|
+
export declare function useChatConfig(): ChatConfig;
|
|
1392
|
+
|
|
1393
|
+
export declare function useChatMessages(room: string | null): {
|
|
1394
|
+
messages: NoInfer<ChatMessage[]>;
|
|
1395
|
+
loading: boolean;
|
|
1396
|
+
};
|
|
1397
|
+
|
|
1398
|
+
/**
|
|
1399
|
+
* The sidebar. The server decides WHICH rooms (visibility) and computes unread
|
|
1400
|
+
* in SQL against the watermark; the client only labels them. The old version
|
|
1401
|
+
* pulled the last 500 messages globally and grouped them here, which both
|
|
1402
|
+
* leaked other people's rooms and silently dropped quiet ones once a busy room
|
|
1403
|
+
* filled the window.
|
|
1404
|
+
*/
|
|
1405
|
+
export declare function useChatRooms(): {
|
|
1406
|
+
rooms: RoomInfo[];
|
|
1407
|
+
totalUnread: number;
|
|
1408
|
+
loading: boolean;
|
|
1409
|
+
};
|
|
1410
|
+
|
|
1411
|
+
export declare function useDrilldown(): DrilldownContextValue | null;
|
|
1412
|
+
|
|
1413
|
+
export declare function useFieldArray(form: UseNivaroFormReturn, field: string): FieldArrayReturn;
|
|
1414
|
+
|
|
1415
|
+
export declare function useFieldState(form: UseNivaroFormReturn, field: string): FieldState;
|
|
1416
|
+
|
|
1417
|
+
export declare function useFormDirty(form: UseNivaroFormReturn, initialValuesOverride?: Record<string, unknown>): FormDirtyState;
|
|
1418
|
+
|
|
1419
|
+
/**
|
|
1420
|
+
* Fetch + cache a collection's form schema. Caches by client URL + collection +
|
|
1421
|
+
* includeHidden flag so re-mounts and sibling forms share one request.
|
|
1422
|
+
*
|
|
1423
|
+
* NOTE: Pass a stable `client` reference. A new object on every render resets
|
|
1424
|
+
* the cache key and re-fetches. Use `useMemo` or define the client outside the
|
|
1425
|
+
* component tree.
|
|
1426
|
+
*/
|
|
1427
|
+
export declare function useFormSchema(client: NivaroClient | null, collection: string, includeHidden?: boolean, layoutId?: number, layoutSlug?: string): {
|
|
1428
|
+
schema: FormSchema | null;
|
|
1429
|
+
loading: boolean;
|
|
1430
|
+
error: Error | null;
|
|
1431
|
+
};
|
|
1432
|
+
|
|
1433
|
+
export declare function useFormStatus(form: UseNivaroFormReturn): FormStatus;
|
|
1434
|
+
|
|
1435
|
+
export declare function useGridFlush(): GridFlushContextValue | null;
|
|
1436
|
+
|
|
1437
|
+
export declare function useItemEditAuth(): ItemEditAuthContextValue;
|
|
1438
|
+
|
|
1439
|
+
export declare function useItemLock(collection: string | undefined, item: string | undefined, enabled: boolean): {
|
|
1440
|
+
lockHolder: LockHolder | null;
|
|
1441
|
+
acquired: boolean;
|
|
1442
|
+
isReadOnly: boolean;
|
|
1443
|
+
takeOver: () => Promise<void>;
|
|
1444
|
+
takingOver: boolean;
|
|
1445
|
+
isAdmin: boolean;
|
|
1446
|
+
};
|
|
1447
|
+
|
|
1448
|
+
/** Resolved item-link helpers honoring the host's itemUrl/openItem overrides. */
|
|
1449
|
+
export declare function useItemNavigation(): {
|
|
1450
|
+
urlFor: (target: ItemLinkTarget) => string;
|
|
1451
|
+
open: (target: ItemLinkTarget) => void;
|
|
1452
|
+
};
|
|
1453
|
+
|
|
1454
|
+
/**
|
|
1455
|
+
* Mark read. The server upserts against UNIQUE(user, room), so the old
|
|
1456
|
+
* select-then-insert dance (and the per-room promise chain that stopped it
|
|
1457
|
+
* 500ing on duplicate key) is gone.
|
|
1458
|
+
*/
|
|
1459
|
+
export declare function useMarkRoomRead(): UseMutationResult<unknown, Error, string, unknown>;
|
|
1460
|
+
|
|
1461
|
+
/**
|
|
1462
|
+
* The signed-in user's scope dimensions + default/restricted value sets
|
|
1463
|
+
* (User Scopes feature). Filter surfaces use this to SEED initial selections
|
|
1464
|
+
* from defaults and NARROW visible options to restricted values — narrowing
|
|
1465
|
+
* is curation; the items service enforces restrictions server-side regardless.
|
|
1466
|
+
*/
|
|
1467
|
+
export declare function useMyScopes(): {
|
|
1468
|
+
scopes: UserScopesInfo | null;
|
|
1469
|
+
ready: boolean;
|
|
1470
|
+
};
|
|
1471
|
+
|
|
1472
|
+
export declare function useNavigation(): NavigationContextValue;
|
|
1473
|
+
|
|
1474
|
+
export declare function useNivaroClient(): NivaroClient;
|
|
1475
|
+
|
|
1476
|
+
/**
|
|
1477
|
+
* Primary form hook for Nivaro CMS.
|
|
1478
|
+
*
|
|
1479
|
+
* IMPORTANT: Pass a stable `client` reference (defined outside the component
|
|
1480
|
+
* or wrapped in useMemo). A new object on every render triggers schema
|
|
1481
|
+
* re-fetches and item reloads on every render cycle.
|
|
1482
|
+
*/
|
|
1483
|
+
export declare function useNivaroForm(collection: string, options: UseNivaroFormOptions, client?: NivaroClient): UseNivaroFormReturn;
|
|
1484
|
+
|
|
1485
|
+
export declare type UseNivaroFormOptions = {
|
|
1486
|
+
mode: 'create' | 'edit';
|
|
1487
|
+
/** required when mode='edit' */
|
|
1488
|
+
itemId?: string | number;
|
|
1489
|
+
defaultValues?: Record<string, unknown>;
|
|
1490
|
+
onSuccess?: (item: Record<string, unknown>) => void;
|
|
1491
|
+
onError?: (error: Error) => void;
|
|
1492
|
+
/** custom synchronous validators; return an error string or null when valid */
|
|
1493
|
+
validate?: Record<string, (value: unknown, values: Record<string, unknown>) => string | null>;
|
|
1494
|
+
/** include hidden fields in the schema (default false) */
|
|
1495
|
+
includeHidden?: boolean;
|
|
1496
|
+
/**
|
|
1497
|
+
* Specific layout id to use for group/field ordering.
|
|
1498
|
+
* When omitted, the collection's active layout is used automatically.
|
|
1499
|
+
*/
|
|
1500
|
+
layoutId?: number;
|
|
1501
|
+
/**
|
|
1502
|
+
* Layout slug to resolve a specific named layout variant.
|
|
1503
|
+
* When set, overrides `layoutId` and fetches the layout by its machine name.
|
|
1504
|
+
*/
|
|
1505
|
+
layoutSlug?: string;
|
|
1506
|
+
/**
|
|
1507
|
+
* Debounce delay in ms for server-side field-rules evaluation (default 300).
|
|
1508
|
+
* Pass 0 to disable server evaluation entirely.
|
|
1509
|
+
*/
|
|
1510
|
+
fieldRulesDebounce?: number;
|
|
1511
|
+
};
|
|
1512
|
+
|
|
1513
|
+
export declare type UseNivaroFormReturn = {
|
|
1514
|
+
schema: FormSchema | null;
|
|
1515
|
+
schemaLoading: boolean;
|
|
1516
|
+
schemaError: Error | null;
|
|
1517
|
+
values: Record<string, unknown>;
|
|
1518
|
+
/** Snapshot of values as last confirmed by the server (or seeded defaults). */
|
|
1519
|
+
initialValues: Record<string, unknown>;
|
|
1520
|
+
errors: FormErrors;
|
|
1521
|
+
isDirty: boolean;
|
|
1522
|
+
isSubmitting: boolean;
|
|
1523
|
+
/** true while loading schema or the item being edited */
|
|
1524
|
+
isLoading: boolean;
|
|
1525
|
+
isVisible: (field: string) => boolean;
|
|
1526
|
+
isLocked: (field: string) => boolean;
|
|
1527
|
+
setValue: (field: string, value: unknown) => void;
|
|
1528
|
+
setValues: (patch: Record<string, unknown>) => void;
|
|
1529
|
+
reset: (values?: Record<string, unknown>) => void;
|
|
1530
|
+
handleSubmit: (e?: default_2.FormEvent) => Promise<void>;
|
|
1531
|
+
fieldsByGroup: Map<string | null, FormFieldDescriptor[]>;
|
|
1532
|
+
visibleGroups: FormGroupDescriptor[];
|
|
1533
|
+
gridFlushersRef: default_2.MutableRefObject<Map<string, () => Promise<void>>>;
|
|
1534
|
+
};
|
|
1535
|
+
|
|
1536
|
+
export declare function useOrderedLayout(form: UseNivaroFormReturn): {
|
|
1537
|
+
items: LayoutItem[];
|
|
1538
|
+
hasTabs: boolean;
|
|
1539
|
+
tabGroups: FormGroupDescriptor[];
|
|
1540
|
+
sectionGroups: FormGroupDescriptor[];
|
|
1541
|
+
ungroupedFields: FormFieldDescriptor[];
|
|
1542
|
+
};
|
|
1543
|
+
|
|
1544
|
+
export declare function usePeerReadAt(room: string | null): string | null;
|
|
1545
|
+
|
|
1546
|
+
export declare function UserChip({ userId, size }: {
|
|
1547
|
+
userId: string;
|
|
1548
|
+
size?: 'default' | 'compact';
|
|
1549
|
+
}): React_2.JSX.Element;
|
|
1550
|
+
|
|
1551
|
+
/**
|
|
1552
|
+
* Fetch selectable options for a relation field's related collection.
|
|
1553
|
+
* Re-fetches when `search` changes. Pass `enabled: false` to skip fetching
|
|
1554
|
+
* (e.g. while the related collection name is still unknown).
|
|
1555
|
+
*
|
|
1556
|
+
* When `enabled` transitions to false, previously-loaded options are retained
|
|
1557
|
+
* so cascading pickers don't flash blank while a parent field is being cleared.
|
|
1558
|
+
*/
|
|
1559
|
+
export declare function useRelationOptions(client: NivaroClient | null, relatedCollection: string, options?: {
|
|
1560
|
+
search?: string;
|
|
1561
|
+
limit?: number;
|
|
1562
|
+
displayTemplate?: string | null;
|
|
1563
|
+
enabled?: boolean;
|
|
1564
|
+
filter?: Record<string, unknown>;
|
|
1565
|
+
}): {
|
|
1566
|
+
options: RelationOption[];
|
|
1567
|
+
loading: boolean;
|
|
1568
|
+
error: Error | null;
|
|
1569
|
+
};
|
|
1570
|
+
|
|
1571
|
+
/** Stacked avatar cluster (+N) with a hover/pinnable portal roster whose rows
|
|
1572
|
+
* are UserChips — the single user-display primitive for owners/user lists.
|
|
1573
|
+
* Reused by the item-header Owners chip and the collection browser. */
|
|
1574
|
+
export declare function UserRosterCluster({ users, showSingleName }: {
|
|
1575
|
+
users: Array<{
|
|
1576
|
+
id: string;
|
|
1577
|
+
name: string;
|
|
1578
|
+
}>;
|
|
1579
|
+
showSingleName?: boolean;
|
|
1580
|
+
}): React_2.JSX.Element;
|
|
1581
|
+
|
|
1582
|
+
export declare function useSectionState(form: UseNivaroFormReturn, defaultCollapsed?: string[]): SectionState;
|
|
1583
|
+
|
|
1584
|
+
export declare function useSendChatMessage(room: string): UseMutationResult<void, Error, string | {
|
|
1585
|
+
text: string;
|
|
1586
|
+
mentions?: string[];
|
|
1587
|
+
}, unknown>;
|
|
1588
|
+
|
|
1589
|
+
export declare function useSessionRecorder(options?: SessionRecorderOptions): void;
|
|
1590
|
+
|
|
1591
|
+
export declare function useTabState(form: UseNivaroFormReturn): TabState;
|
|
1592
|
+
|
|
1593
|
+
export declare function useTypingIndicator(room: string | null): {
|
|
1594
|
+
onType: () => void;
|
|
1595
|
+
clearTyping: () => void;
|
|
1596
|
+
typingText: string | null;
|
|
1597
|
+
};
|
|
1598
|
+
|
|
1599
|
+
export declare function useUnreadChirp(totalUnread: number): void;
|
|
1600
|
+
|
|
1601
|
+
export declare function useWatchFields(form: UseNivaroFormReturn, fields: string[]): Record<string, unknown>;
|
|
1602
|
+
|
|
1603
|
+
export declare function WorkflowPanel({ collection, item }: {
|
|
1604
|
+
collection: string;
|
|
1605
|
+
item: string;
|
|
1606
|
+
}): JSX.Element | null;
|
|
1607
|
+
|
|
1608
|
+
export { }
|