@nivaro/react 0.1.66 → 0.1.67
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/index.d.ts +1301 -111
- package/dist/index.js +41382 -41171
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { CascadeFilterRule } from '@nivaro/sdk';
|
|
2
2
|
import { default as default_2 } from 'react';
|
|
3
3
|
import { FieldDependencyConfig } from '@nivaro/sdk';
|
|
4
|
-
import
|
|
4
|
+
import { ImportParseResponse } from '@nivaro/sdk';
|
|
5
|
+
import { ImportTemplateSummary } from '@nivaro/sdk';
|
|
5
6
|
import { JSX } from 'react';
|
|
6
7
|
import { JSXElementConstructor } from 'react';
|
|
7
8
|
import { NivaroClient } from '@nivaro/sdk';
|
|
@@ -15,6 +16,56 @@ import { ReportQueryWidgetConfig } from '@nivaro/sdk';
|
|
|
15
16
|
import { UseMutationResult } from '@tanstack/react-query';
|
|
16
17
|
import { UserScopesInfo } from '@nivaro/sdk';
|
|
17
18
|
|
|
19
|
+
export declare function AccessDeniedPanel({ collection, itemId, onBack }: {
|
|
20
|
+
collection: string;
|
|
21
|
+
itemId: string;
|
|
22
|
+
/** Host-provided back action (e.g. navigate(-1)); renders a button when set. */
|
|
23
|
+
onBack?: () => void;
|
|
24
|
+
}): JSX.Element;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Options filter for every nivaro_users picker: mirrors listUsers() — redacted
|
|
28
|
+
* accounts never appear, and suspended users cannot be PICKED (existing values
|
|
29
|
+
* still display, since current-value lookups fetch by id with no filter).
|
|
30
|
+
* Null-safe on status so a fresh install with unset statuses keeps working.
|
|
31
|
+
*/
|
|
32
|
+
export declare const ACTIVE_USER_OPTION_FILTER: {
|
|
33
|
+
_and: ({
|
|
34
|
+
is_redacted: {
|
|
35
|
+
_eq: boolean;
|
|
36
|
+
};
|
|
37
|
+
_or?: undefined;
|
|
38
|
+
} | {
|
|
39
|
+
_or: ({
|
|
40
|
+
status: {
|
|
41
|
+
_neq: string;
|
|
42
|
+
_null?: undefined;
|
|
43
|
+
};
|
|
44
|
+
} | {
|
|
45
|
+
status: {
|
|
46
|
+
_null: boolean;
|
|
47
|
+
_neq?: undefined;
|
|
48
|
+
};
|
|
49
|
+
})[];
|
|
50
|
+
is_redacted?: undefined;
|
|
51
|
+
})[];
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export declare function AddendumPanel({ collection, item, addendumLayoutId, canCreate, onActiveCountChange, onApplied, defaultExpanded, }: {
|
|
55
|
+
collection: string;
|
|
56
|
+
item: string;
|
|
57
|
+
addendumLayoutId?: number | null;
|
|
58
|
+
canCreate?: boolean;
|
|
59
|
+
onActiveCountChange?: (count: number) => void;
|
|
60
|
+
/** Fired after an addendum is approved/rejected/submitted — i.e. whenever the
|
|
61
|
+
* parent record may now read differently. ItemEditForm uses it to refresh a
|
|
62
|
+
* generated PDF so the attached document matches the amended record. */
|
|
63
|
+
onApplied?: () => void;
|
|
64
|
+
defaultExpanded?: boolean;
|
|
65
|
+
}): JSX.Element | null;
|
|
66
|
+
|
|
67
|
+
export declare function agingBucket(hours: number | null): string;
|
|
68
|
+
|
|
18
69
|
export declare function AlertManagerView({ defaultTab, hiddenTabs, onOpenReport, className }: AlertManagerViewProps): JSX.Element;
|
|
19
70
|
|
|
20
71
|
export declare interface AlertManagerViewProps {
|
|
@@ -27,6 +78,91 @@ export declare interface AlertManagerViewProps {
|
|
|
27
78
|
className?: string;
|
|
28
79
|
}
|
|
29
80
|
|
|
81
|
+
declare type AlertOperator = 'gt' | 'gte' | 'lt' | 'lte' | 'eq' | 'change_pct';
|
|
82
|
+
|
|
83
|
+
export declare function AlertRuleDrawer({ open, definitions, editRule, preselectedDefinitionId, scopeSeeds, onClose, onSave, saving }: {
|
|
84
|
+
open: boolean;
|
|
85
|
+
definitions: MetricDefinition[];
|
|
86
|
+
editRule: MetricAlertRule | null;
|
|
87
|
+
preselectedDefinitionId?: number | null;
|
|
88
|
+
/** Pre-seeded filter values (e.g. from the user's scope restrictions), keyed by filter key. */
|
|
89
|
+
scopeSeeds?: Record<string, Array<string | number>>;
|
|
90
|
+
onClose: () => void;
|
|
91
|
+
onSave: (values: Record<string, unknown>) => void;
|
|
92
|
+
saving: boolean;
|
|
93
|
+
}): JSX.Element;
|
|
94
|
+
|
|
95
|
+
declare type AlertUnit = 'percent' | 'dollar' | 'count' | 'days';
|
|
96
|
+
|
|
97
|
+
declare type AllocateDrawerConfig = {
|
|
98
|
+
/** Option collection browsed in the drawer (e.g. workflow_line_items). */
|
|
99
|
+
collection: string;
|
|
100
|
+
/** Grid FK column that receives the picked option's id. */
|
|
101
|
+
target_field: string;
|
|
102
|
+
/** Grid column that receives the entered amount. */
|
|
103
|
+
value_field: string;
|
|
104
|
+
title?: string;
|
|
105
|
+
value_label?: string;
|
|
106
|
+
/** Option filter — same '$parent.<field>' token semantics as option_filter. */
|
|
107
|
+
filter?: Record<string, unknown>;
|
|
108
|
+
/** Display columns over the option rows: dotted paths resolve via nested
|
|
109
|
+
* field expansion; formula entries compute from the option row's values. */
|
|
110
|
+
columns?: Array<string | {
|
|
111
|
+
path?: string;
|
|
112
|
+
label?: string;
|
|
113
|
+
format?: string;
|
|
114
|
+
formula?: string;
|
|
115
|
+
width?: number;
|
|
116
|
+
}>;
|
|
117
|
+
/** Group option rows under collapsible headers by this (dotted) path —
|
|
118
|
+
* EFP grouped allocation lines by workflow. Groups start collapsed;
|
|
119
|
+
* groups containing an existing allocation start expanded. */
|
|
120
|
+
group_by?: string;
|
|
121
|
+
/** Per-row allocation ceiling formula (same tokens as column formulas incl.
|
|
122
|
+
* {{__saved__}} = this row's saved amount): inputs clamp to it on commit
|
|
123
|
+
* and show invalid state while exceeding it. */
|
|
124
|
+
value_max?: string;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
declare interface AnomalyDefinition {
|
|
128
|
+
id: number;
|
|
129
|
+
key: string;
|
|
130
|
+
name: string;
|
|
131
|
+
description: string | null;
|
|
132
|
+
category: string;
|
|
133
|
+
status: string;
|
|
134
|
+
scope_options: FilterOptionSpec[] | null;
|
|
135
|
+
sensitivity_hints: Record<string, string> | null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
declare interface AnomalyRule {
|
|
139
|
+
id: number;
|
|
140
|
+
name: string;
|
|
141
|
+
definition_id: number;
|
|
142
|
+
sensitivity: 'low' | 'medium' | 'high' | string;
|
|
143
|
+
scopes: Record<string, Array<string | number>> | null;
|
|
144
|
+
check_frequency: 'daily' | 'weekly' | string;
|
|
145
|
+
delivery_in_app: boolean;
|
|
146
|
+
delivery_email: boolean;
|
|
147
|
+
status: string;
|
|
148
|
+
created_by: string | null;
|
|
149
|
+
definition?: {
|
|
150
|
+
id: number;
|
|
151
|
+
key: string;
|
|
152
|
+
name: string;
|
|
153
|
+
description: string | null;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export declare function AnomalyRuleDrawer({ open, definitions, editRule, onClose, onSave, saving }: {
|
|
158
|
+
open: boolean;
|
|
159
|
+
definitions: AnomalyDefinition[];
|
|
160
|
+
editRule: AnomalyRule | null;
|
|
161
|
+
onClose: () => void;
|
|
162
|
+
onSave: (values: Record<string, unknown>) => void;
|
|
163
|
+
saving: boolean;
|
|
164
|
+
}): JSX.Element;
|
|
165
|
+
|
|
30
166
|
/**
|
|
31
167
|
* "The API was redeployed since you loaded this page" bar.
|
|
32
168
|
*
|
|
@@ -58,10 +194,41 @@ export declare interface ApiVersionInfo {
|
|
|
58
194
|
environment?: string;
|
|
59
195
|
}
|
|
60
196
|
|
|
197
|
+
/** Evaluate one field validation rule against a value. Returns an error message
|
|
198
|
+
* or null. Shared by useNivaroForm (headless) and ItemEditForm (admin). */
|
|
199
|
+
export declare function applyValidationRule(rule: FormValidationRule_2, value: unknown, label: string): string | null;
|
|
200
|
+
|
|
201
|
+
declare type AutoAllocateConfig = {
|
|
202
|
+
/** Button label; defaults to 'Auto allocate'. */
|
|
203
|
+
label?: string;
|
|
204
|
+
/** drawer_relations entry (by field name) whose `match` supplies the
|
|
205
|
+
* existing-allocation query + create defaults for this grid's rows. */
|
|
206
|
+
relation: string;
|
|
207
|
+
/** Grid row column holding the required quantity. */
|
|
208
|
+
row_qty_field: string;
|
|
209
|
+
/** Quantity column on the allocation rows. */
|
|
210
|
+
alloc_qty_field: string;
|
|
211
|
+
/** FK column on allocation rows pointing at a candidate record. */
|
|
212
|
+
fk_field: string;
|
|
213
|
+
candidates: {
|
|
214
|
+
collection: string;
|
|
215
|
+
/** Same '$parent.*' / '$row.*' token semantics as matched drawer filters. */
|
|
216
|
+
filters: Record<string, unknown>;
|
|
217
|
+
/** Server sort, e.g. 'date' for FIFO. */
|
|
218
|
+
sort?: string;
|
|
219
|
+
/** Gross capacity per candidate row, e.g. '0 - {{quantity}}'. */
|
|
220
|
+
capacity_formula: string;
|
|
221
|
+
/** Candidates with net capacity below this are skipped (default 1). */
|
|
222
|
+
min_capacity?: number;
|
|
223
|
+
};
|
|
224
|
+
};
|
|
225
|
+
|
|
61
226
|
declare type BinaryOp = '+' | '-' | '*' | '/' | '==' | '!=' | '<' | '<=' | '>' | '>=' | '&&' | '||';
|
|
62
227
|
|
|
63
228
|
export declare function BooleanField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
|
|
64
229
|
|
|
230
|
+
export declare function buildGroups<T extends QueueGroupingRow>(rows: T[], attribute: string): QueueGroup<T>[];
|
|
231
|
+
|
|
65
232
|
export declare function canOpenChatRoom(): boolean;
|
|
66
233
|
|
|
67
234
|
export declare function canOpenDm(): boolean;
|
|
@@ -70,6 +237,21 @@ export declare function canPreviewFile(type: string | null | undefined): boolean
|
|
|
70
237
|
|
|
71
238
|
export { CascadeFilterRule }
|
|
72
239
|
|
|
240
|
+
declare type CascadeRule = {
|
|
241
|
+
parent_field: string;
|
|
242
|
+
child_field: string;
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
export declare function CellCopyLayer(): ReactPortal | null;
|
|
246
|
+
|
|
247
|
+
declare interface ChannelMember {
|
|
248
|
+
user: string;
|
|
249
|
+
first_name: string | null;
|
|
250
|
+
last_name: string | null;
|
|
251
|
+
email: string | null;
|
|
252
|
+
joined_at: string;
|
|
253
|
+
}
|
|
254
|
+
|
|
73
255
|
declare interface ChannelMeta {
|
|
74
256
|
id: number;
|
|
75
257
|
visibility: 'open' | 'role' | 'private';
|
|
@@ -81,6 +263,26 @@ declare interface ChannelMeta {
|
|
|
81
263
|
|
|
82
264
|
export declare function chatAvatarColor(id: string): string;
|
|
83
265
|
|
|
266
|
+
/**
|
|
267
|
+
* Browse and join channels. The sidebar only lists rooms you belong to, so at
|
|
268
|
+
* hundreds of channels this is how you find the rest — the old list rendered
|
|
269
|
+
* every room anyone had ever posted in.
|
|
270
|
+
*/
|
|
271
|
+
export declare function ChatChannelBrowser({ onOpen }: {
|
|
272
|
+
onOpen: (room: string, label: string, channel: ChannelMeta) => void;
|
|
273
|
+
}): JSX.Element;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Channel settings. Owner or admin edits name/topic/visibility, manages members
|
|
277
|
+
* and archives; everyone else gets the read-only summary, so a member can still
|
|
278
|
+
* see what kind of room they are in and who else is here.
|
|
279
|
+
*/
|
|
280
|
+
export declare function ChatChannelSettings({ channel, label, onBack }: {
|
|
281
|
+
channel: ChannelMeta;
|
|
282
|
+
label: string;
|
|
283
|
+
onBack: () => void;
|
|
284
|
+
}): JSX.Element;
|
|
285
|
+
|
|
84
286
|
export declare interface ChatConfig {
|
|
85
287
|
collections: {
|
|
86
288
|
messages: string;
|
|
@@ -174,7 +376,7 @@ export declare function ChatPanel({ open, onClose, renderMessageBody, requestedD
|
|
|
174
376
|
|
|
175
377
|
export declare function ChatProvider({ children, me, onlineUsers, collections, globalRoom, globalLabel, entityPattern, entityUrl, roomLabel, recordUrl, sessionUrl, realtime, subscribeRooms, setTypingRoom, navigate, sound, theme }: ChatProviderProps): JSX.Element;
|
|
176
378
|
|
|
177
|
-
declare interface ChatProviderProps {
|
|
379
|
+
export declare interface ChatProviderProps {
|
|
178
380
|
children: React.ReactNode;
|
|
179
381
|
me: ChatConfig['me'];
|
|
180
382
|
onlineUsers?: ChatOnlineUser[];
|
|
@@ -239,6 +441,15 @@ export declare function ChatRoomView({ room, label, onBack, onOpenSettings, rend
|
|
|
239
441
|
initialUnread?: number;
|
|
240
442
|
}): JSX.Element;
|
|
241
443
|
|
|
444
|
+
declare interface ChatSearchHit {
|
|
445
|
+
id: number;
|
|
446
|
+
room: string;
|
|
447
|
+
sender: string | null;
|
|
448
|
+
sender_name: string | null;
|
|
449
|
+
message: string;
|
|
450
|
+
date_created: string;
|
|
451
|
+
}
|
|
452
|
+
|
|
242
453
|
/**
|
|
243
454
|
* Nivaro chat UI — a complete team panel (Online tab, grouped rooms, live
|
|
244
455
|
* conversations with mentions, typing, receipts, search).
|
|
@@ -269,9 +480,80 @@ export declare interface ChatTheme {
|
|
|
269
480
|
divider: string;
|
|
270
481
|
}
|
|
271
482
|
|
|
483
|
+
declare type CheckFrequency = 'hourly' | 'daily' | 'weekly';
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Select-choice display text. Legacy Directus schema imports store choice
|
|
487
|
+
* labels as i18n keys ('$t:published') that Directus resolved through its own
|
|
488
|
+
* translation bundle — Nivaro has no such bundle, so the raw key leaked into
|
|
489
|
+
* dropdowns and read views. Strip the marker and humanize; plain labels pass
|
|
490
|
+
* through untouched.
|
|
491
|
+
*/
|
|
492
|
+
export declare function choiceLabel(text: string | null | undefined): string;
|
|
493
|
+
|
|
272
494
|
/** Clear the schema cache (e.g. after a schema change). */
|
|
273
495
|
export declare function clearFormSchemaCache(collection?: string): void;
|
|
274
496
|
|
|
497
|
+
declare interface ClientAction {
|
|
498
|
+
type: 'open-sidebar';
|
|
499
|
+
collection: string;
|
|
500
|
+
itemId: string;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
export declare function CloneDialog({ collection, itemId, fields, relations, currentValues, onSuccess }: CloneDialogProps): JSX.Element;
|
|
504
|
+
|
|
505
|
+
declare interface CloneDialogProps {
|
|
506
|
+
collection: string;
|
|
507
|
+
itemId: string;
|
|
508
|
+
fields: CMSField[];
|
|
509
|
+
relations: CMSRelation[];
|
|
510
|
+
currentValues: Record<string, unknown>;
|
|
511
|
+
onSuccess: (newId: string | number) => void;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
declare interface CMSField {
|
|
515
|
+
field: string;
|
|
516
|
+
type: string;
|
|
517
|
+
interface: string | null;
|
|
518
|
+
label: string | null;
|
|
519
|
+
required: boolean;
|
|
520
|
+
hidden: boolean;
|
|
521
|
+
readonly: boolean;
|
|
522
|
+
sort: number;
|
|
523
|
+
group_key: string | null;
|
|
524
|
+
options: Record<string, unknown> | string | null;
|
|
525
|
+
computed_formula: string | null;
|
|
526
|
+
computed_type: string | null;
|
|
527
|
+
note: string | null;
|
|
528
|
+
placeholder: string | null;
|
|
529
|
+
repeater_schema: Record<string, unknown>[] | string | null;
|
|
530
|
+
dependency_config: Record<string, unknown> | string | null;
|
|
531
|
+
/** {source_collection, source_fk_field?, field_map:{target:source}} — live copy from a related record when the FK changes. */
|
|
532
|
+
cross_record_defaults?: Record<string, unknown> | string | null;
|
|
533
|
+
validation_rules?: Array<{
|
|
534
|
+
type: string;
|
|
535
|
+
value?: unknown;
|
|
536
|
+
message?: string;
|
|
537
|
+
soft?: boolean;
|
|
538
|
+
}> | string | null;
|
|
539
|
+
layout_assigned?: boolean;
|
|
540
|
+
/** Raw layout-assignment overrides (label, readonly, drilldown, ...) — passed through by field-config. */
|
|
541
|
+
_overrides?: Record<string, unknown> | null;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
declare interface CMSRelation {
|
|
545
|
+
id: number;
|
|
546
|
+
one_collection: string | null;
|
|
547
|
+
one_field: string | null;
|
|
548
|
+
many_collection: string | null;
|
|
549
|
+
many_field: string | null;
|
|
550
|
+
junction_field: string | null;
|
|
551
|
+
/** M2A only — the junction column naming which collection each row's `item` id
|
|
552
|
+
* belongs to (usually 'collection'); one_collection is null on those rows. */
|
|
553
|
+
one_collection_field?: string | null;
|
|
554
|
+
one_allowed_collections?: string | null;
|
|
555
|
+
}
|
|
556
|
+
|
|
275
557
|
/** @deprecated Column model changed to plain field keys — kept for source
|
|
276
558
|
* compatibility with early adopters; maps `path` to a field key. */
|
|
277
559
|
export declare interface CollectionBrowserColumn {
|
|
@@ -317,7 +599,7 @@ export declare function CollectionImportPanel({ initialJobId, onJobOpen }: {
|
|
|
317
599
|
onJobOpen?: (id: string | null) => void;
|
|
318
600
|
}): JSX.Element;
|
|
319
601
|
|
|
320
|
-
declare interface Column<T = Record<string, unknown>> {
|
|
602
|
+
export declare interface Column<T = Record<string, unknown>> {
|
|
321
603
|
key: string;
|
|
322
604
|
header: React_2.ReactNode;
|
|
323
605
|
sortable?: boolean;
|
|
@@ -326,7 +608,7 @@ declare interface Column<T = Record<string, unknown>> {
|
|
|
326
608
|
render?: (row: T, index: number) => React_2.ReactNode;
|
|
327
609
|
}
|
|
328
610
|
|
|
329
|
-
declare type ColumnFormatConfig = {
|
|
611
|
+
export declare type ColumnFormatConfig = {
|
|
330
612
|
type: 'datetime';
|
|
331
613
|
template: string;
|
|
332
614
|
} | {
|
|
@@ -341,6 +623,11 @@ declare type ColumnFormatConfig = {
|
|
|
341
623
|
false_label: string;
|
|
342
624
|
};
|
|
343
625
|
|
|
626
|
+
declare interface ColumnPreset {
|
|
627
|
+
name: string;
|
|
628
|
+
columns: string[];
|
|
629
|
+
}
|
|
630
|
+
|
|
344
631
|
export declare function CommentPanel({ collection, item, title, defaultExpanded, queuedComments, onQueueComment }: {
|
|
345
632
|
collection: string;
|
|
346
633
|
item: string | number;
|
|
@@ -374,7 +661,7 @@ export declare type ComponentOverrides = {
|
|
|
374
661
|
|
|
375
662
|
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, density, pinFirstColumn, columnPins, onColumnPinChange, columnFilterRow, hScrollProxy, selectedIds, onSelectionChange, rowClassName, rowGroups, collapsedGroups, onToggleGroup }: DataTableProps<T>): React_2.JSX.Element;
|
|
376
663
|
|
|
377
|
-
declare interface DataTableProps<T = Record<string, unknown>> {
|
|
664
|
+
export declare interface DataTableProps<T = Record<string, unknown>> {
|
|
378
665
|
columns: Column<T>[];
|
|
379
666
|
rows: T[];
|
|
380
667
|
rowKey?: (row: T, i: number) => string;
|
|
@@ -451,15 +738,37 @@ export declare function DateField({ field, value, onChange, error, disabled, rea
|
|
|
451
738
|
/** The admin's route shape — the default when the host supplies no itemUrl. */
|
|
452
739
|
export declare function defaultItemUrl(t: ItemLinkTarget): string;
|
|
453
740
|
|
|
741
|
+
export declare function deriveGroupKey<T extends QueueGroupingRow>(row: T, attribute: string): string;
|
|
742
|
+
|
|
743
|
+
declare interface DirectoryChannel {
|
|
744
|
+
id: number;
|
|
745
|
+
key: string;
|
|
746
|
+
name: string;
|
|
747
|
+
topic: string | null;
|
|
748
|
+
visibility: 'open' | 'role' | 'private';
|
|
749
|
+
role: string | null;
|
|
750
|
+
joined: boolean;
|
|
751
|
+
members: number;
|
|
752
|
+
}
|
|
753
|
+
|
|
454
754
|
declare type DmOpener = (userId: string, displayName?: string) => void;
|
|
455
755
|
|
|
456
756
|
export declare function dmPeer(room: string, self: string): string | null;
|
|
457
757
|
|
|
458
758
|
export declare function dmRoom(a: string, b: string): string;
|
|
459
759
|
|
|
760
|
+
declare type DrawerRelationConfig = string | {
|
|
761
|
+
field: string;
|
|
762
|
+
hint?: {
|
|
763
|
+
sum_field: string;
|
|
764
|
+
cap_field: string;
|
|
765
|
+
};
|
|
766
|
+
match?: MatchedDrawerConfig;
|
|
767
|
+
};
|
|
768
|
+
|
|
460
769
|
export declare const DrilldownContext: React_2.Context<DrilldownContextValue | null>;
|
|
461
770
|
|
|
462
|
-
declare interface DrilldownContextValue {
|
|
771
|
+
export declare interface DrilldownContextValue {
|
|
463
772
|
open: (target: DrilldownTarget) => void;
|
|
464
773
|
}
|
|
465
774
|
|
|
@@ -482,6 +791,11 @@ export declare function effectiveScopeSeedIds(scopes: {
|
|
|
482
791
|
restricted: Record<string, Array<string | number>>;
|
|
483
792
|
}, dimName: string): Array<string | number>;
|
|
484
793
|
|
|
794
|
+
export declare function ErpFailureBanner({ collection, itemId }: {
|
|
795
|
+
collection: string;
|
|
796
|
+
itemId: string;
|
|
797
|
+
}): JSX.Element | null;
|
|
798
|
+
|
|
485
799
|
/** Boolean convenience — for guards and conditions. */
|
|
486
800
|
export declare function evaluateBoolean(src: string, row: TokenResolver | Record<string, unknown>, opts?: EvaluateOptions): boolean;
|
|
487
801
|
|
|
@@ -491,7 +805,7 @@ export declare function evaluateExpression(src: string, resolve: TokenResolver |
|
|
|
491
805
|
/** Numeric convenience — the shape every existing call site wants. */
|
|
492
806
|
export declare function evaluateNumeric(src: string, row: TokenResolver | Record<string, unknown>, opts?: EvaluateOptions): number | null;
|
|
493
807
|
|
|
494
|
-
declare interface EvaluateOptions {
|
|
808
|
+
export declare interface EvaluateOptions {
|
|
495
809
|
/**
|
|
496
810
|
* What an unresolvable or non-numeric token means in arithmetic.
|
|
497
811
|
* 'zero' (default) matches every existing dialect. 'null' propagates, so a
|
|
@@ -500,7 +814,7 @@ declare interface EvaluateOptions {
|
|
|
500
814
|
missing?: 'zero' | 'null';
|
|
501
815
|
}
|
|
502
816
|
|
|
503
|
-
declare type ExprNode = {
|
|
817
|
+
export declare type ExprNode = {
|
|
504
818
|
kind: 'number';
|
|
505
819
|
value: number;
|
|
506
820
|
} | {
|
|
@@ -561,6 +875,18 @@ declare type ExprNode = {
|
|
|
561
875
|
*/
|
|
562
876
|
export declare type ExprValue = number | string | boolean | null;
|
|
563
877
|
|
|
878
|
+
/**
|
|
879
|
+
* Item-header chip summarizing every external (ERP) request this record has
|
|
880
|
+
* sent — badge counts by outcome, click for the full request/response log.
|
|
881
|
+
* Renders nothing when the record has no submissions. Shares the
|
|
882
|
+
* ['erp-submissions', collection, item] cache with ErpFailureBanner, so
|
|
883
|
+
* transition writebacks refresh both.
|
|
884
|
+
*/
|
|
885
|
+
export declare function ExternalRequestsChip({ collection, itemId }: {
|
|
886
|
+
collection: string;
|
|
887
|
+
itemId: string;
|
|
888
|
+
}): JSX.Element | null;
|
|
889
|
+
|
|
564
890
|
/** Field paths an expression reads, without evaluating it. */
|
|
565
891
|
export declare function extractExpressionTokens(src: string): string[];
|
|
566
892
|
|
|
@@ -596,6 +922,31 @@ export declare type FieldComponentProps = {
|
|
|
596
922
|
|
|
597
923
|
export { FieldDependencyConfig }
|
|
598
924
|
|
|
925
|
+
export declare interface FieldDrilldownConfig {
|
|
926
|
+
enabled?: boolean;
|
|
927
|
+
layout_id?: number | null;
|
|
928
|
+
width?: number | string | null;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
export declare function fieldDrilldownConfig(field: {
|
|
932
|
+
interface?: string | null;
|
|
933
|
+
_overrides?: Record<string, unknown> | null;
|
|
934
|
+
}): FieldDrilldownConfig | null;
|
|
935
|
+
|
|
936
|
+
export declare function FieldRenderer({ field, value, onChange, relations, collection, itemId, cascadeFilter, requiredParentLabel, onCountChange, displayOnly, prefillParentId }: {
|
|
937
|
+
field: CMSField;
|
|
938
|
+
value: unknown;
|
|
939
|
+
onChange: (v: unknown) => void;
|
|
940
|
+
relations: CMSRelation[];
|
|
941
|
+
collection: string;
|
|
942
|
+
itemId: string;
|
|
943
|
+
cascadeFilter?: Record<string, unknown>;
|
|
944
|
+
requiredParentLabel?: string | null;
|
|
945
|
+
onCountChange?: (count: number) => void;
|
|
946
|
+
displayOnly?: boolean;
|
|
947
|
+
prefillParentId?: string;
|
|
948
|
+
}): JSX.Element;
|
|
949
|
+
|
|
599
950
|
export declare type FieldState = {
|
|
600
951
|
value: unknown;
|
|
601
952
|
error: string[] | undefined;
|
|
@@ -621,7 +972,14 @@ export declare function FilePreviewLightbox({ file, onClose }: {
|
|
|
621
972
|
onClose: () => void;
|
|
622
973
|
}): ReactPortal;
|
|
623
974
|
|
|
624
|
-
declare
|
|
975
|
+
export declare function FilterControl({ def, value, onChange, layout }: {
|
|
976
|
+
def: FilterDef;
|
|
977
|
+
value: string | string[];
|
|
978
|
+
onChange: (value: string | string[]) => void;
|
|
979
|
+
layout?: 'inline' | 'stacked' | 'cell';
|
|
980
|
+
}): React_2.JSX.Element;
|
|
981
|
+
|
|
982
|
+
export declare interface FilterDef {
|
|
625
983
|
key: string;
|
|
626
984
|
placeholder: string;
|
|
627
985
|
/** Defaults to 'select' — every existing FilterDef without this field keeps its current dropdown behavior unchanged. */
|
|
@@ -643,6 +1001,35 @@ declare interface FilterDef {
|
|
|
643
1001
|
restricted?: boolean;
|
|
644
1002
|
}
|
|
645
1003
|
|
|
1004
|
+
export declare function filterDefLabel(def: FilterDef): string;
|
|
1005
|
+
|
|
1006
|
+
declare interface FilterOptionSpec {
|
|
1007
|
+
key: string;
|
|
1008
|
+
label?: string;
|
|
1009
|
+
collection?: string;
|
|
1010
|
+
value_field?: string;
|
|
1011
|
+
label_field?: string;
|
|
1012
|
+
sort?: string;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
/** Human display for an applied filter value — option labels for comboboxes
|
|
1016
|
+
* (ids → names), ≥/≤ for ranges, first two entries + count for multiselects. */
|
|
1017
|
+
export declare function filterValueDisplay(def: FilterDef, value: string | string[]): string;
|
|
1018
|
+
|
|
1019
|
+
export declare function formatDate(date: string | Date, opts?: Intl.DateTimeFormatOptions): string;
|
|
1020
|
+
|
|
1021
|
+
export declare function formatDateTime(date: string | Date): string;
|
|
1022
|
+
|
|
1023
|
+
export declare function formatFileSize(bytes: number | null | undefined): string;
|
|
1024
|
+
|
|
1025
|
+
export declare function formatMultiValue(raw: string, cfg: ColumnFormatConfig): string;
|
|
1026
|
+
|
|
1027
|
+
export declare function formatNumber(n: number | null | undefined): string;
|
|
1028
|
+
|
|
1029
|
+
export declare function formatRelative(date: string | Date): string;
|
|
1030
|
+
|
|
1031
|
+
export declare function formatValue(raw: string, cfg: ColumnFormatConfig): string;
|
|
1032
|
+
|
|
646
1033
|
export declare type FormDirtyState = {
|
|
647
1034
|
isDirty: boolean;
|
|
648
1035
|
dirtyFields: string[];
|
|
@@ -699,7 +1086,7 @@ export declare type FormFieldType = 'text' | 'textarea' | 'integer' | 'float' |
|
|
|
699
1086
|
export declare type FormGroupDescriptor = {
|
|
700
1087
|
key: string;
|
|
701
1088
|
label: string;
|
|
702
|
-
type: 'section' | 'tab';
|
|
1089
|
+
type: 'section' | 'tab' | 'metadata' | 'container';
|
|
703
1090
|
icon: string | null;
|
|
704
1091
|
sort: number;
|
|
705
1092
|
isCollapsed: boolean;
|
|
@@ -800,6 +1187,13 @@ export declare type FormValidationRule = {
|
|
|
800
1187
|
soft?: boolean;
|
|
801
1188
|
};
|
|
802
1189
|
|
|
1190
|
+
declare type FormValidationRule_2 = {
|
|
1191
|
+
type: string;
|
|
1192
|
+
value?: unknown;
|
|
1193
|
+
message?: string;
|
|
1194
|
+
soft?: boolean;
|
|
1195
|
+
};
|
|
1196
|
+
|
|
803
1197
|
/** A client-evaluable visibility rule. */
|
|
804
1198
|
export declare type FormVisibilityRule = {
|
|
805
1199
|
/** key of the field this rule observes */
|
|
@@ -817,18 +1211,25 @@ export declare function getMentionQuery(text: string, cursorPos: number): string
|
|
|
817
1211
|
|
|
818
1212
|
export declare const GridFlushContext: React_2.Context<GridFlushContextValue | null>;
|
|
819
1213
|
|
|
820
|
-
declare type GridFlushContextValue = {
|
|
1214
|
+
export declare type GridFlushContextValue = {
|
|
821
1215
|
register: (key: string, fn: () => Promise<void>) => void;
|
|
822
1216
|
unregister: (key: string) => void;
|
|
823
1217
|
};
|
|
824
1218
|
|
|
825
|
-
declare interface HeaderWidgetInfo {
|
|
1219
|
+
export declare interface HeaderWidgetInfo {
|
|
826
1220
|
field: string;
|
|
827
1221
|
widgetId: number;
|
|
828
1222
|
label: string | null;
|
|
829
1223
|
inputBindings: InputBinding[];
|
|
830
1224
|
}
|
|
831
1225
|
|
|
1226
|
+
/** Always-visible horizontal scrollbar proxy for the table scroller —
|
|
1227
|
+
* overlay-OS scrollbars hide, so wide tables get a persistent draggable
|
|
1228
|
+
* track pinned above the pagination footer. */
|
|
1229
|
+
export declare function HScrollProxy({ scrollerRef }: {
|
|
1230
|
+
scrollerRef: React_2.RefObject<HTMLDivElement | null>;
|
|
1231
|
+
}): React_2.JSX.Element | null;
|
|
1232
|
+
|
|
832
1233
|
/** Time without real input before someone counts as idle. */
|
|
833
1234
|
export declare const IDLE_AFTER_MS: number;
|
|
834
1235
|
|
|
@@ -878,6 +1279,23 @@ export declare interface ImportDefinition {
|
|
|
878
1279
|
validation?: string | null;
|
|
879
1280
|
}
|
|
880
1281
|
|
|
1282
|
+
export declare function ImportFromFileButton({ collection, templateFilter, getLabel, onParsed, compact }: {
|
|
1283
|
+
collection: string;
|
|
1284
|
+
templateFilter?: (t: ImportTemplateSummary) => boolean;
|
|
1285
|
+
/** Per-template label source; defaults to the template's button_label. */
|
|
1286
|
+
getLabel?: (t: ImportTemplateSummary) => string | null | undefined;
|
|
1287
|
+
onParsed: (result: ImportParseResponse, template: ImportTemplateSummary) => void;
|
|
1288
|
+
/** Grid-toolbar sizing (h-6, 11px) matching other inline-table buttons. */
|
|
1289
|
+
compact?: boolean;
|
|
1290
|
+
}): JSX.Element | null;
|
|
1291
|
+
|
|
1292
|
+
declare type ImportIssue = ImportParseResponse['issues'][number];
|
|
1293
|
+
|
|
1294
|
+
export declare function ImportIssuesPanel({ issues, onDismiss }: {
|
|
1295
|
+
issues: ImportIssue[];
|
|
1296
|
+
onDismiss?: () => void;
|
|
1297
|
+
}): JSX.Element | null;
|
|
1298
|
+
|
|
881
1299
|
export declare interface ImportJob {
|
|
882
1300
|
id: string;
|
|
883
1301
|
collection: string;
|
|
@@ -1006,15 +1424,76 @@ declare interface ImportValidationReport {
|
|
|
1006
1424
|
truncated: boolean;
|
|
1007
1425
|
}
|
|
1008
1426
|
|
|
1427
|
+
export declare function InlineTableField({ relatedCollection, manyField, parentId, parentCollection, layoutId, showRowRevisions, allowRevisionRestore, saveMode, showLineNumbers, enableReorder, parentCascades, rowRules, columnPresets, defaultPreset, drawerRelations, parentContextFields, uniqueBy, sortField, sortDir, sectionGroupBy, rowFilter, rowDefaults, allocateDrawer, autoAllocate, rowBulkActions, uploadTemplate, submissionErrors, prefillParentId, parentFieldKey, readOnly }: {
|
|
1428
|
+
relatedCollection: string;
|
|
1429
|
+
manyField: string;
|
|
1430
|
+
parentId: string;
|
|
1431
|
+
/** Same table display, but no editing: hides the Add toolbar, + Add row,
|
|
1432
|
+
* row delete/undo, and blocks cell edit entry. */
|
|
1433
|
+
readOnly?: boolean;
|
|
1434
|
+
parentCollection?: string;
|
|
1435
|
+
layoutId?: number | null;
|
|
1436
|
+
showRowRevisions?: boolean;
|
|
1437
|
+
allowRevisionRestore?: boolean;
|
|
1438
|
+
saveMode?: 'immediate' | 'pending';
|
|
1439
|
+
showLineNumbers?: boolean;
|
|
1440
|
+
enableReorder?: boolean;
|
|
1441
|
+
parentCascades?: CascadeRule[];
|
|
1442
|
+
rowRules?: RowRule[];
|
|
1443
|
+
columnPresets?: ColumnPreset[];
|
|
1444
|
+
/** Initial view before the user picks one: a preset name or '__all__'. */
|
|
1445
|
+
defaultPreset?: string;
|
|
1446
|
+
drawerRelations?: DrawerRelationConfig[];
|
|
1447
|
+
parentContextFields?: string[];
|
|
1448
|
+
uniqueBy?: string[];
|
|
1449
|
+
sortField?: string;
|
|
1450
|
+
sortDir?: 'asc' | 'desc';
|
|
1451
|
+
/** Dotted relation path on the child collection (e.g. 'item.category.name'):
|
|
1452
|
+
* saved rows render grouped into collapsible sections by the resolved value. */
|
|
1453
|
+
sectionGroupBy?: string;
|
|
1454
|
+
/** Static filter narrowing which child rows this grid shows — flat {col: value}
|
|
1455
|
+
* entries become _eq, object values pass through as filter operators. Lets two
|
|
1456
|
+
* grids on the same relation show disjoint views (e.g. is_osp split). */
|
|
1457
|
+
rowFilter?: Record<string, unknown>;
|
|
1458
|
+
/** Values seeded onto every NEW row created from this grid (e.g. {is_osp: true}). */
|
|
1459
|
+
rowDefaults?: Record<string, unknown>;
|
|
1460
|
+
/** EFP-style allocate drawer: browse all eligible options, type amounts. */
|
|
1461
|
+
allocateDrawer?: AllocateDrawerConfig;
|
|
1462
|
+
autoAllocate?: AutoAllocateConfig;
|
|
1463
|
+
/** Toolbar buttons that rewrite EVERY row in one go from an aggregate of a
|
|
1464
|
+
* related collection — the generic form of EFP's "Close Out Lines" (reduce
|
|
1465
|
+
* each REQ line by the open unbilled amount across its PO lines). */
|
|
1466
|
+
rowBulkActions?: RowBulkActionConfig[];
|
|
1467
|
+
/** Import template NAME — renders that template's upload button in this
|
|
1468
|
+
* grid's toolbar (existing records; wired to ItemEditForm's reimport flow). */
|
|
1469
|
+
uploadTemplate?: string;
|
|
1470
|
+
/** Flag rows a failed ERP push rejected (options.submission_errors) — the
|
|
1471
|
+
* latest failed nivaro_erp_submissions row for the PARENT record is parsed
|
|
1472
|
+
* for "LineNumber N: reason" entries and matching rows tint red with the
|
|
1473
|
+
* reason beneath. `line_field` = the row column holding the pushed line
|
|
1474
|
+
* number (default 'line_number'). Mirrors CatalogPickerField's
|
|
1475
|
+
* submission_errors for catalog grids. */
|
|
1476
|
+
submissionErrors?: {
|
|
1477
|
+
line_field?: string;
|
|
1478
|
+
};
|
|
1479
|
+
prefillParentId?: string;
|
|
1480
|
+
parentFieldKey?: string;
|
|
1481
|
+
}): JSX.Element;
|
|
1482
|
+
|
|
1009
1483
|
declare interface InputBinding {
|
|
1010
1484
|
key: string;
|
|
1011
1485
|
binding_type: 'item_field' | 'static' | 'url_param';
|
|
1012
1486
|
binding_value: string;
|
|
1013
1487
|
}
|
|
1014
1488
|
|
|
1489
|
+
export declare function ItemActionButtons({ collection, itemId }: {
|
|
1490
|
+
collection: string;
|
|
1491
|
+
itemId: string;
|
|
1492
|
+
}): JSX.Element | null;
|
|
1493
|
+
|
|
1015
1494
|
export declare const ItemEditAuthContext: React_2.Context<ItemEditAuthContextValue>;
|
|
1016
1495
|
|
|
1017
|
-
declare type ItemEditAuthContextValue = {
|
|
1496
|
+
export declare type ItemEditAuthContextValue = {
|
|
1018
1497
|
isAdmin: boolean;
|
|
1019
1498
|
userId: string;
|
|
1020
1499
|
};
|
|
@@ -1095,6 +1574,73 @@ export declare function ItemLockBanner({ lockHolder, onTakeOver, takingOver, isA
|
|
|
1095
1574
|
isAdmin?: boolean;
|
|
1096
1575
|
}): JSX.Element | null;
|
|
1097
1576
|
|
|
1577
|
+
export declare function JsonMapEditor({ config, scope }: {
|
|
1578
|
+
config: JsonMapEditorConfig;
|
|
1579
|
+
scope: Record<string, unknown>;
|
|
1580
|
+
}): JSX.Element;
|
|
1581
|
+
|
|
1582
|
+
declare interface JsonMapEditorConfig {
|
|
1583
|
+
collection: string;
|
|
1584
|
+
title?: string;
|
|
1585
|
+
/** Record picker label field (also the required name on create). */
|
|
1586
|
+
label_field?: string;
|
|
1587
|
+
/** Filter for the record picker; '$scope.<field>' tokens resolve from the
|
|
1588
|
+
* host-provided scope. Scope values are also seeded onto created records. */
|
|
1589
|
+
record_filter?: Record<string, unknown>;
|
|
1590
|
+
/** Plain record fields edited beside the picker (small option sets). */
|
|
1591
|
+
fields?: Array<{
|
|
1592
|
+
field: string;
|
|
1593
|
+
label?: string;
|
|
1594
|
+
options: string[];
|
|
1595
|
+
}>;
|
|
1596
|
+
/** JSON-dict columns; each stored under `json_field` on the record. */
|
|
1597
|
+
map_columns: Array<{
|
|
1598
|
+
json_field: string;
|
|
1599
|
+
label: string;
|
|
1600
|
+
min?: number;
|
|
1601
|
+
max?: number;
|
|
1602
|
+
}>;
|
|
1603
|
+
/** Key rows: records of other collections. Template supports one-hop dotted
|
|
1604
|
+
* refs ('{{core_category.name}}'); filter supports '$scope' tokens. */
|
|
1605
|
+
sections: Array<{
|
|
1606
|
+
collection: string;
|
|
1607
|
+
label_template: string;
|
|
1608
|
+
filter?: Record<string, unknown>;
|
|
1609
|
+
section_label?: string;
|
|
1610
|
+
}>;
|
|
1611
|
+
/** Static sentinel keys appended after the sections (bg = row tint). */
|
|
1612
|
+
extra_rows?: Array<{
|
|
1613
|
+
key: string;
|
|
1614
|
+
label: string;
|
|
1615
|
+
bg?: string;
|
|
1616
|
+
}>;
|
|
1617
|
+
/** 'Left to allocate' style hint: shown when record[when_field] ===
|
|
1618
|
+
* when_value; remaining = total − Σ json_field values. */
|
|
1619
|
+
remaining_hint?: {
|
|
1620
|
+
when_field: string;
|
|
1621
|
+
when_value: string;
|
|
1622
|
+
total: number;
|
|
1623
|
+
json_field: string;
|
|
1624
|
+
label?: string;
|
|
1625
|
+
};
|
|
1626
|
+
/** Extra fields seeded onto created records from scope values. */
|
|
1627
|
+
seed_fields?: string[];
|
|
1628
|
+
/** Custom query run after save (recompute hooks); '$scope' tokens. */
|
|
1629
|
+
after_save?: {
|
|
1630
|
+
query_slug: string;
|
|
1631
|
+
params?: Record<string, unknown>;
|
|
1632
|
+
};
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
declare interface LayoutAssignment {
|
|
1636
|
+
field: string;
|
|
1637
|
+
group_key: string | null;
|
|
1638
|
+
sort: number;
|
|
1639
|
+
label_override: string | null;
|
|
1640
|
+
is_visible: boolean | number;
|
|
1641
|
+
overrides?: string | Record<string, unknown> | null;
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1098
1644
|
/**
|
|
1099
1645
|
* Full layout-aware form renderer.
|
|
1100
1646
|
*
|
|
@@ -1153,6 +1699,13 @@ declare type LayoutFormProps = {
|
|
|
1153
1699
|
layoutSlug?: string;
|
|
1154
1700
|
};
|
|
1155
1701
|
|
|
1702
|
+
declare interface LayoutGroup {
|
|
1703
|
+
key: string;
|
|
1704
|
+
label: string;
|
|
1705
|
+
type: string | null;
|
|
1706
|
+
sort: number;
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1156
1709
|
export declare type LayoutItem = FormGroupDescriptor | '__ungrouped__';
|
|
1157
1710
|
|
|
1158
1711
|
declare interface LockHolder {
|
|
@@ -1160,6 +1713,25 @@ declare interface LockHolder {
|
|
|
1160
1713
|
locked_by_name: string | null;
|
|
1161
1714
|
}
|
|
1162
1715
|
|
|
1716
|
+
export declare interface M2MStagingCtx {
|
|
1717
|
+
getStagedLinks: (key: string) => unknown[];
|
|
1718
|
+
getStagedUnlinks: (key: string) => Set<unknown>;
|
|
1719
|
+
stageLink: (key: string, relatedId: unknown) => void;
|
|
1720
|
+
stageUnlink: (key: string, junctionId: unknown) => void;
|
|
1721
|
+
unstageLink: (key: string, relatedId: unknown) => void;
|
|
1722
|
+
unstageUnlink: (key: string, junctionId: unknown) => void;
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
declare type MatchedDrawerConfig = {
|
|
1726
|
+
/** Rows selected by filter instead of an FK to the child row — values may be
|
|
1727
|
+
* '$parent.id', '$parent.<field>', '$row.<field>', or literals; dotted keys
|
|
1728
|
+
* become nested relation filters. Creates are seeded with `defaults`
|
|
1729
|
+
* (same token resolution, plain columns only). */
|
|
1730
|
+
collection: string;
|
|
1731
|
+
filters: Record<string, unknown>;
|
|
1732
|
+
defaults?: Record<string, unknown>;
|
|
1733
|
+
};
|
|
1734
|
+
|
|
1163
1735
|
/** Match a filter surface (by its own key and/or its options collection) to a
|
|
1164
1736
|
* scope dimension. Convention: key === dimension name wins, else the filter's
|
|
1165
1737
|
* options collection === the dimension's target collection. */
|
|
@@ -1168,22 +1740,147 @@ export declare function matchScopeDimension(scopes: UserScopesInfo | null, probe
|
|
|
1168
1740
|
collection?: string;
|
|
1169
1741
|
}): UserScopesInfo['dimensions'][number] | null;
|
|
1170
1742
|
|
|
1743
|
+
export declare function MatrixEditor({ config, initialScope }: {
|
|
1744
|
+
config: MatrixEditorConfig;
|
|
1745
|
+
/** Pre-seed scope pickers (drill-down hosts scope the matrix to a record). */
|
|
1746
|
+
initialScope?: Record<string, unknown>;
|
|
1747
|
+
}): JSX.Element;
|
|
1748
|
+
|
|
1749
|
+
declare interface MatrixEditorConfig {
|
|
1750
|
+
title?: string;
|
|
1751
|
+
target_collection: string;
|
|
1752
|
+
option_collection: string;
|
|
1753
|
+
/** Plain display column (default 'name') — or use option_label_template. */
|
|
1754
|
+
option_label?: string;
|
|
1755
|
+
/** Dotted display template, e.g. '{{core_category.name}} - {{sub_category.name}}'. */
|
|
1756
|
+
option_label_template?: string;
|
|
1757
|
+
/** Filter for the option fetch. '$scope.<field>' tokens resolve from scope. */
|
|
1758
|
+
option_filter?: Record<string, unknown>;
|
|
1759
|
+
key_field: string;
|
|
1760
|
+
value_field: string;
|
|
1761
|
+
value_label?: string;
|
|
1762
|
+
value_format?: 'currency' | 'number';
|
|
1763
|
+
/** Scope pickers. `filter` narrows a picker's options; '$scope.<field>'
|
|
1764
|
+
* tokens resolve from the other scope values (EFP: sub types limited to the
|
|
1765
|
+
* chosen project's linked sub types) — unresolved tokens drop the filter. */
|
|
1766
|
+
scope_fields: Array<{
|
|
1767
|
+
field: string;
|
|
1768
|
+
collection: string;
|
|
1769
|
+
label?: string;
|
|
1770
|
+
filter?: Record<string, unknown>;
|
|
1771
|
+
}>;
|
|
1772
|
+
/** Third level: sub-group options WITHIN a group section by a template over
|
|
1773
|
+
* the option record (EFP region → core category → Labor/Materials/Equipment:
|
|
1774
|
+
* label_template '{{core_category.name}}', row_label_template
|
|
1775
|
+
* '{{sub_category.name}}'). Sub-headers aggregate their children and
|
|
1776
|
+
* collapse independently. */
|
|
1777
|
+
option_section?: {
|
|
1778
|
+
label_template: string;
|
|
1779
|
+
/** Leaf row label; defaults to the full option label. */
|
|
1780
|
+
row_label_template?: string;
|
|
1781
|
+
};
|
|
1782
|
+
/** Second axis: sections per group record; target rows keyed (key, group, scope). */
|
|
1783
|
+
group?: {
|
|
1784
|
+
field: string;
|
|
1785
|
+
collection: string;
|
|
1786
|
+
label_field?: string;
|
|
1787
|
+
filter?: Record<string, unknown>;
|
|
1788
|
+
};
|
|
1789
|
+
/** Extra seeds on created rows, '$<scopeField>.<path>' — path may be dotted
|
|
1790
|
+
* and use [n] (e.g. '$project.funding_years[0].funding_year'). */
|
|
1791
|
+
scope_seeds?: Record<string, string>;
|
|
1792
|
+
/** Auto-fill a scope picker from another scope record when empty, e.g.
|
|
1793
|
+
* {project_sub_type: '$project.default_sub_type'} (EFP default sub type). */
|
|
1794
|
+
scope_defaults?: Record<string, string>;
|
|
1795
|
+
/** Seeds copied from the GROUP record onto rows created in that section,
|
|
1796
|
+
* {targetField: groupField} — e.g. {division: 'division'} (allocation rows
|
|
1797
|
+
* carry the region's division, not one picked from the project). */
|
|
1798
|
+
group_seeds?: Record<string, string>;
|
|
1799
|
+
/** Cap strip: cap value read from a scope record's field; total of all cells
|
|
1800
|
+
* is clamped so it never exceeds the cap (server sum_cap should back this). */
|
|
1801
|
+
cap?: {
|
|
1802
|
+
scope_field: string;
|
|
1803
|
+
field: string;
|
|
1804
|
+
label?: string;
|
|
1805
|
+
};
|
|
1806
|
+
/** Synthetic rows per group for target rows with a NULL key (Uncategorized)
|
|
1807
|
+
* and/or a boolean bucket flag (Inventory: rows with flag true, key null). */
|
|
1808
|
+
specials?: {
|
|
1809
|
+
uncategorized?: {
|
|
1810
|
+
label?: string;
|
|
1811
|
+
metric_value?: number | null;
|
|
1812
|
+
};
|
|
1813
|
+
bucket?: {
|
|
1814
|
+
flag_field: string;
|
|
1815
|
+
label?: string;
|
|
1816
|
+
metric_value?: number | null;
|
|
1817
|
+
};
|
|
1818
|
+
};
|
|
1819
|
+
/** Per-cell read-only metric columns from a custom query. */
|
|
1820
|
+
metrics?: {
|
|
1821
|
+
query_slug: string;
|
|
1822
|
+
params?: Record<string, unknown>;
|
|
1823
|
+
match_option_field: string;
|
|
1824
|
+
match_group_field?: string;
|
|
1825
|
+
columns: Array<{
|
|
1826
|
+
field: string;
|
|
1827
|
+
label?: string;
|
|
1828
|
+
format?: 'currency' | 'number';
|
|
1829
|
+
}>;
|
|
1830
|
+
};
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1171
1833
|
declare interface MessageToken {
|
|
1172
1834
|
text: string;
|
|
1173
1835
|
entity?: string;
|
|
1174
1836
|
mention?: string;
|
|
1175
1837
|
}
|
|
1176
1838
|
|
|
1839
|
+
declare interface MetricAlertRule {
|
|
1840
|
+
id: number;
|
|
1841
|
+
name: string;
|
|
1842
|
+
definition_id: number;
|
|
1843
|
+
operator: string;
|
|
1844
|
+
threshold_value: number;
|
|
1845
|
+
filters: Record<string, Array<string | number>> | null;
|
|
1846
|
+
check_frequency: CheckFrequency | string;
|
|
1847
|
+
is_shared: boolean;
|
|
1848
|
+
status: string;
|
|
1849
|
+
created_by: string | null;
|
|
1850
|
+
created_at: string | null;
|
|
1851
|
+
definition?: {
|
|
1852
|
+
id: number;
|
|
1853
|
+
name: string;
|
|
1854
|
+
description: string | null;
|
|
1855
|
+
category: string;
|
|
1856
|
+
unit: string;
|
|
1857
|
+
};
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
declare interface MetricDefinition {
|
|
1861
|
+
id: number;
|
|
1862
|
+
name: string;
|
|
1863
|
+
description: string | null;
|
|
1864
|
+
metric_key: string;
|
|
1865
|
+
category: string;
|
|
1866
|
+
unit: AlertUnit | string;
|
|
1867
|
+
default_operator: AlertOperator | string;
|
|
1868
|
+
default_threshold: number | null;
|
|
1869
|
+
supported_filters: FilterOptionSpec[] | null;
|
|
1870
|
+
status: string;
|
|
1871
|
+
sort: number | null;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1177
1874
|
export declare function MyWorkView({ notificationRoutes, onOpenPath }?: {
|
|
1178
1875
|
/** Host page map so notification clicks land on real pages (reports, queues,
|
|
1179
1876
|
* alerts…); without it only record targets are clickable. */
|
|
1180
|
-
notificationRoutes?:
|
|
1877
|
+
notificationRoutes?: NotificationRouteMap;
|
|
1181
1878
|
onOpenPath?: (path: string) => void;
|
|
1182
1879
|
}): JSX.Element;
|
|
1183
1880
|
|
|
1184
1881
|
export declare const NavigationContext: React_2.Context<NavigationContextValue>;
|
|
1185
1882
|
|
|
1186
|
-
declare type NavigationContextValue = {
|
|
1883
|
+
export declare type NavigationContextValue = {
|
|
1187
1884
|
/** `options.state` rides along for hosts whose router supports it (e.g. react-router's
|
|
1188
1885
|
* useNavigate) — hosts that ignore the second argument still navigate correctly. */
|
|
1189
1886
|
navigate: (path: string, options?: {
|
|
@@ -1271,34 +1968,7 @@ export declare function normalizeFieldType(rawType: string, iface: string | null
|
|
|
1271
1968
|
* system collections map to their owning pages, and the pseudo-collection
|
|
1272
1969
|
* `__chat__` carries a chat room key.
|
|
1273
1970
|
*/
|
|
1274
|
-
|
|
1275
1971
|
export declare interface NotificationRouteMap {
|
|
1276
|
-
/** Record route for a business collection — return null when the host has none. */
|
|
1277
|
-
record: (collection: string, item: string) => string | null
|
|
1278
|
-
/** Collection listing (item-less business notifications, e.g. view digests). */
|
|
1279
|
-
list?: (collection: string) => string | null
|
|
1280
|
-
report?: (id: string) => string | null
|
|
1281
|
-
queue?: (id: string) => string | null
|
|
1282
|
-
dashboard?: (id: string) => string | null
|
|
1283
|
-
/** Alert-manager page (metric/anomaly/per-record alert notifications). */
|
|
1284
|
-
alerts?: () => string | null
|
|
1285
|
-
imports?: () => string | null
|
|
1286
|
-
issues?: () => string | null
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
/**
|
|
1290
|
-
* Every in-app notification must land somewhere meaningful — this is the ONE
|
|
1291
|
-
* resolver both bells, the notifications page, and My Work use to decide what
|
|
1292
|
-
* a click does. A row that resolves to null renders as plain text (no hover,
|
|
1293
|
-
* no cursor), which is the honest state for broadcast-style messages; it must
|
|
1294
|
-
* never render as a link that goes nowhere.
|
|
1295
|
-
*
|
|
1296
|
-
* Server writers use `collection` + `item` as the target: business collections
|
|
1297
|
-
* point at records (or the collection list when item is null), a handful of
|
|
1298
|
-
* system collections map to their owning pages, and the pseudo-collection
|
|
1299
|
-
* `__chat__` carries a chat room key.
|
|
1300
|
-
*/
|
|
1301
|
-
declare interface NotificationRouteMap_2 {
|
|
1302
1972
|
/** Record route for a business collection — return null when the host has none. */
|
|
1303
1973
|
record: (collection: string, item: string) => string | null;
|
|
1304
1974
|
/** Collection listing (item-less business notifications, e.g. view digests). */
|
|
@@ -1312,13 +1982,19 @@ declare interface NotificationRouteMap_2 {
|
|
|
1312
1982
|
issues?: () => string | null;
|
|
1313
1983
|
}
|
|
1314
1984
|
|
|
1315
|
-
export declare type NotificationTarget =
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
|
1985
|
+
export declare type NotificationTarget = {
|
|
1986
|
+
type: 'path';
|
|
1987
|
+
path: string;
|
|
1988
|
+
} | {
|
|
1989
|
+
type: 'chat';
|
|
1990
|
+
room: string;
|
|
1991
|
+
} | null;
|
|
1319
1992
|
|
|
1320
1993
|
export declare function NumberField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
|
|
1321
1994
|
|
|
1995
|
+
/** Intl options for a numeric field, honoring its configured precision. */
|
|
1996
|
+
export declare function numericIntlOptions(options: unknown, format?: string): Intl.NumberFormatOptions;
|
|
1997
|
+
|
|
1322
1998
|
declare interface O2MFieldInfo {
|
|
1323
1999
|
field: string;
|
|
1324
2000
|
label: string;
|
|
@@ -1375,6 +2051,13 @@ declare interface OwnerLike {
|
|
|
1375
2051
|
name: string;
|
|
1376
2052
|
}
|
|
1377
2053
|
|
|
2054
|
+
export declare function OwnersSlot({ collection, item, title, defaultExpanded }: {
|
|
2055
|
+
collection: string;
|
|
2056
|
+
item: string;
|
|
2057
|
+
title?: string;
|
|
2058
|
+
defaultExpanded?: boolean;
|
|
2059
|
+
}): JSX.Element | null;
|
|
2060
|
+
|
|
1378
2061
|
export declare function PageRenderer({ slug, hideHeader, className }: PageRendererProps): JSX.Element;
|
|
1379
2062
|
|
|
1380
2063
|
export declare interface PageRendererPage {
|
|
@@ -1413,7 +2096,7 @@ declare interface ParseFailure {
|
|
|
1413
2096
|
position: number;
|
|
1414
2097
|
}
|
|
1415
2098
|
|
|
1416
|
-
declare type ParseResult = ParseSuccess | ParseFailure;
|
|
2099
|
+
export declare type ParseResult = ParseSuccess | ParseFailure;
|
|
1417
2100
|
|
|
1418
2101
|
declare interface ParseSuccess {
|
|
1419
2102
|
ok: true;
|
|
@@ -1428,6 +2111,14 @@ declare interface PendingTask {
|
|
|
1428
2111
|
due_date: string;
|
|
1429
2112
|
}
|
|
1430
2113
|
|
|
2114
|
+
declare interface PinnedMessage {
|
|
2115
|
+
pin_id: number;
|
|
2116
|
+
id: number;
|
|
2117
|
+
sender_name: string | null;
|
|
2118
|
+
message: string;
|
|
2119
|
+
date_created: string;
|
|
2120
|
+
}
|
|
2121
|
+
|
|
1431
2122
|
export declare function PipelinePanel({ collection, item, defaultExpanded, title, showApprovalChain, onBeforeTransition, addendumPending, addendumView }: {
|
|
1432
2123
|
collection: string;
|
|
1433
2124
|
item: string;
|
|
@@ -1445,6 +2136,17 @@ export declare function PipelineTransitionButtons({ collection, item, onBeforeTr
|
|
|
1445
2136
|
onBeforeTransition?: () => boolean | Promise<boolean>;
|
|
1446
2137
|
}): JSX.Element | null;
|
|
1447
2138
|
|
|
2139
|
+
/**
|
|
2140
|
+
* How many decimal places a numeric field wants, from its `precision` option.
|
|
2141
|
+
*
|
|
2142
|
+
* One helper because the answer was hardcoded to 2 in five places — the field
|
|
2143
|
+
* input, the inline grid's cells, its formula and aggregate columns, and the
|
|
2144
|
+
* read-only display — so a field configured for 4 showed 4 in one of them and
|
|
2145
|
+
* 2 everywhere else. Out-of-range or missing values fall back rather than
|
|
2146
|
+
* throwing at Intl, which rejects anything outside 0–20.
|
|
2147
|
+
*/
|
|
2148
|
+
export declare function precisionOf(options: unknown, fallback?: number): number;
|
|
2149
|
+
|
|
1448
2150
|
/**
|
|
1449
2151
|
* Inline attachment preview — click a file, see it, without a download round
|
|
1450
2152
|
* trip. Images, PDFs, video and audio render in an overlay; anything else
|
|
@@ -1467,6 +2169,136 @@ export declare function ProfileView({ userId, className }: {
|
|
|
1467
2169
|
className?: string;
|
|
1468
2170
|
}): JSX.Element;
|
|
1469
2171
|
|
|
2172
|
+
export declare function QueryStatStrip({ stats, rows, effectiveParams, loading }: {
|
|
2173
|
+
stats: QueryWidgetStat[];
|
|
2174
|
+
rows: Array<Record<string, unknown>>;
|
|
2175
|
+
effectiveParams: Record<string, unknown>;
|
|
2176
|
+
loading: boolean;
|
|
2177
|
+
}): JSX.Element | null;
|
|
2178
|
+
|
|
2179
|
+
export declare function QueryTable({ rows, config, onRowClick, pivotYear, rowActions }: {
|
|
2180
|
+
rows: Array<Record<string, unknown>>;
|
|
2181
|
+
config?: QueryTableConfig;
|
|
2182
|
+
/** Makes rows clickable (hover highlight); receives the (post-grouping) row. */
|
|
2183
|
+
onRowClick?: (row: Record<string, unknown>) => void;
|
|
2184
|
+
/** Resolved pivot year (from the widget's params) — overrides config.pivot.year. */
|
|
2185
|
+
pivotYear?: number;
|
|
2186
|
+
/** Trailing action buttons per row (and on the totals row, receiving null). */
|
|
2187
|
+
rowActions?: Array<{
|
|
2188
|
+
label: string;
|
|
2189
|
+
onClick: (row: Record<string, unknown> | null) => void;
|
|
2190
|
+
}>;
|
|
2191
|
+
}): JSX.Element;
|
|
2192
|
+
|
|
2193
|
+
declare interface QueryTableColumn {
|
|
2194
|
+
/** Row key. Omit for pure formula columns. */
|
|
2195
|
+
field?: string;
|
|
2196
|
+
label?: string;
|
|
2197
|
+
format?: 'currency' | 'number' | 'percent' | 'text';
|
|
2198
|
+
/** Arithmetic over {{col}} refs, e.g. '{{carAmount}} - {{allocated}}' or
|
|
2199
|
+
* '{{allocated}} / {{carAmount}} * 100'. Evaluated per row (and over the
|
|
2200
|
+
* totals row for the footer). */
|
|
2201
|
+
formula?: string;
|
|
2202
|
+
/** Include in the totals footer (plain fields sum; formula columns re-run
|
|
2203
|
+
* the formula over the summed values — weighted, not averaged). */
|
|
2204
|
+
sum?: boolean;
|
|
2205
|
+
/** 'progress' renders the value with a bar underneath, filled to
|
|
2206
|
+
* value / progress_max (EFP PUB'd-vs-budget style). Over 100% turns red. */
|
|
2207
|
+
display?: 'progress';
|
|
2208
|
+
/** Denominator for display 'progress': a row field name or a {{col}} formula. */
|
|
2209
|
+
progress_max?: string;
|
|
2210
|
+
/** Column group label. When any column has one, the header renders two
|
|
2211
|
+
* rows — group cells spanning their children ('Jan' over Fcst/Act) — and
|
|
2212
|
+
* alternating groups get a faint band so wide grids stay scannable. */
|
|
2213
|
+
group?: string;
|
|
2214
|
+
/** Cell text color (any CSS color) — EFP forecast/actual column tinting.
|
|
2215
|
+
* color_dark overrides in dark mode (defaults to color). */
|
|
2216
|
+
color?: string;
|
|
2217
|
+
color_dark?: string;
|
|
2218
|
+
/** Second field rendered as a stacked line under the main value in the SAME
|
|
2219
|
+
* cell (EFP month cells: Fcst over Act — halves the column count). Toggles
|
|
2220
|
+
* hide individual lines; the column collapses when both lines hide. */
|
|
2221
|
+
stack?: string;
|
|
2222
|
+
stack_color?: string;
|
|
2223
|
+
stack_color_dark?: string;
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
declare interface QueryTableConfig {
|
|
2227
|
+
columns?: QueryTableColumn[];
|
|
2228
|
+
/** Group rows by this field, summing every numeric column per group. */
|
|
2229
|
+
group_by?: string;
|
|
2230
|
+
/** Render the totals footer row. */
|
|
2231
|
+
totals?: boolean;
|
|
2232
|
+
/** Collapsible section rows: one header row per distinct value of this
|
|
2233
|
+
* field (per-column sums on the header), child rows listed under it.
|
|
2234
|
+
* Unlike group_by (which REPLACES rows with aggregates), children stay. */
|
|
2235
|
+
tree_group_by?: string;
|
|
2236
|
+
/** Sections start collapsed (default false = expanded). */
|
|
2237
|
+
tree_collapsed?: boolean;
|
|
2238
|
+
/** SECOND tree level inside each section, derived by splitting `field` on
|
|
2239
|
+
* its LAST `separator` (default ' - '): left side = collapsible summed
|
|
2240
|
+
* sub-section (category), right side = the leaf's label (Labor/Materials).
|
|
2241
|
+
* Rows without the separator stay directly under the section. */
|
|
2242
|
+
tree_sub_split?: {
|
|
2243
|
+
field: string;
|
|
2244
|
+
separator?: string;
|
|
2245
|
+
};
|
|
2246
|
+
/** Sub-sections start collapsed (default true). */
|
|
2247
|
+
tree_sub_collapsed?: boolean;
|
|
2248
|
+
/** Leaf rows strip a leading '<section name> - ' from the first column —
|
|
2249
|
+
* de-duplicates labels when the section field is the label's prefix. */
|
|
2250
|
+
tree_strip_section_prefix?: boolean;
|
|
2251
|
+
/** Per-row numeric format override: name of a row field holding
|
|
2252
|
+
* 'currency' | 'number' — lets unit-count rows sit alongside dollar rows
|
|
2253
|
+
* (EFP forecasting grid). Falls back to the column format. */
|
|
2254
|
+
row_format_field?: string;
|
|
2255
|
+
/** Pin the first column and the header row while the grid scrolls — wide
|
|
2256
|
+
* month grids keep their row labels in view. */
|
|
2257
|
+
sticky?: boolean;
|
|
2258
|
+
/** Render zeroes as an em dash — de-noises mostly-empty month grids. */
|
|
2259
|
+
zero_dash?: boolean;
|
|
2260
|
+
/** Column show/hide toggle pills above the table (EFP Actuals / Forecasts /
|
|
2261
|
+
* Calendar Year). A toggle turned OFF hides columns matched by exact
|
|
2262
|
+
* `fields` or a field-name `suffix` — unless `hide_when_on` inverts it
|
|
2263
|
+
* (Calendar Year ON hides the Prior/Carryover columns). */
|
|
2264
|
+
toggles?: Array<{
|
|
2265
|
+
label: string;
|
|
2266
|
+
fields?: string[];
|
|
2267
|
+
suffix?: string;
|
|
2268
|
+
default_on?: boolean;
|
|
2269
|
+
hide_when_on?: boolean;
|
|
2270
|
+
}>;
|
|
2271
|
+
/** Tint every column of this group (header + cells + totals). The sentinel
|
|
2272
|
+
* '$current_month' resolves to the current month's short label (Jan…Dec).
|
|
2273
|
+
* Pair with highlight_year_param so it only applies on the current year. */
|
|
2274
|
+
highlight_group?: string;
|
|
2275
|
+
/** Widget-layer guard: name of the effective param holding the selected
|
|
2276
|
+
* year — highlight_group is dropped unless it equals the current year. */
|
|
2277
|
+
highlight_year_param?: string;
|
|
2278
|
+
/** Tiny colored line-name legend under stacked-column headers, e.g.
|
|
2279
|
+
* ['Fcst', 'Act'] (EFP listHeaderSubLabel). */
|
|
2280
|
+
stack_legend?: [string, string];
|
|
2281
|
+
/** Pivot long rows into month columns BEFORE rendering. Rows sharing the
|
|
2282
|
+
* same key fields merge into one row with Jan…Dec (+ optional
|
|
2283
|
+
* prior/later-year buckets and a total) from `value_field`, driven by a
|
|
2284
|
+
* 'yyyy-MM' `date_field` and the `year` param/prop. */
|
|
2285
|
+
pivot?: {
|
|
2286
|
+
date_field: string;
|
|
2287
|
+
value_field: string;
|
|
2288
|
+
/** Fields that identify a row (everything else is dropped). */
|
|
2289
|
+
key_fields: string[];
|
|
2290
|
+
/** Which year's months to expand; other years fold into per-year columns.
|
|
2291
|
+
* Resolved from the widget's effective params when `year_param` set. */
|
|
2292
|
+
year?: number;
|
|
2293
|
+
year_param?: string;
|
|
2294
|
+
/** Add a Total column summing every pivoted cell. */
|
|
2295
|
+
total?: boolean;
|
|
2296
|
+
/** Render a Months/Quarters toggle above the table (EFP quarterly view).
|
|
2297
|
+
* Quarter columns sum their three months — same drill/total math. */
|
|
2298
|
+
quarter_toggle?: boolean;
|
|
2299
|
+
};
|
|
2300
|
+
}
|
|
2301
|
+
|
|
1470
2302
|
export declare function QueryWidgetBody({ cfg, dateRange, entityFilters, refetchInterval, onStatus, onDrill }: {
|
|
1471
2303
|
cfg: ReportQueryWidgetConfig;
|
|
1472
2304
|
dateRange: ReportDateRange | null;
|
|
@@ -1483,6 +2315,42 @@ export declare function QueryWidgetBody({ cfg, dateRange, entityFilters, refetch
|
|
|
1483
2315
|
}) => void;
|
|
1484
2316
|
}): JSX.Element;
|
|
1485
2317
|
|
|
2318
|
+
declare interface QueryWidgetStat {
|
|
2319
|
+
label: string;
|
|
2320
|
+
/** Sum this field over the main query's rows. */
|
|
2321
|
+
field?: string;
|
|
2322
|
+
format?: 'currency' | 'number';
|
|
2323
|
+
/** Hover breakdown: each entry summed over the same rows. */
|
|
2324
|
+
details?: Array<{
|
|
2325
|
+
label: string;
|
|
2326
|
+
field: string;
|
|
2327
|
+
}>;
|
|
2328
|
+
/** Independent source: own custom query. Value = sum of value_field over its
|
|
2329
|
+
* rows; when label_field set, rows also list in the hover breakdown.
|
|
2330
|
+
* param_from copies values from the main widget's effective params
|
|
2331
|
+
* {statQueryParam: widgetParam}. */
|
|
2332
|
+
query?: {
|
|
2333
|
+
slug: string;
|
|
2334
|
+
params?: Record<string, unknown>;
|
|
2335
|
+
param_from?: Record<string, string>;
|
|
2336
|
+
value_field: string;
|
|
2337
|
+
label_field?: string;
|
|
2338
|
+
};
|
|
2339
|
+
/** Card tint (any CSS color, e.g. '#f9fbd1'). */
|
|
2340
|
+
bg?: string;
|
|
2341
|
+
/** Only sum rows matching these field values (equality AND) — EFP
|
|
2342
|
+
* forecasting stats scope to the Workflow Forecast section. */
|
|
2343
|
+
row_match?: Record<string, unknown>;
|
|
2344
|
+
/** Delta stat: value = sum(field) − sum(field_subtract); positive values
|
|
2345
|
+
* render with a leading '+'. */
|
|
2346
|
+
field_subtract?: string;
|
|
2347
|
+
/** EFP stat-card accent: colored top border + value (accent_dark in dark
|
|
2348
|
+
* mode; accent_negative when a delta goes negative). */
|
|
2349
|
+
accent?: string;
|
|
2350
|
+
accent_dark?: string;
|
|
2351
|
+
accent_negative?: string;
|
|
2352
|
+
}
|
|
2353
|
+
|
|
1486
2354
|
export declare function QueueBulkBar({ count, states, busy, claimsEnabled, onClaim, onRelease, onTransition, onClear }: {
|
|
1487
2355
|
count: number;
|
|
1488
2356
|
states: Array<{
|
|
@@ -1497,6 +2365,25 @@ export declare function QueueBulkBar({ count, states, busy, claimsEnabled, onCla
|
|
|
1497
2365
|
onClear: () => void;
|
|
1498
2366
|
}): JSX.Element | null;
|
|
1499
2367
|
|
|
2368
|
+
export declare interface QueueGroup<T extends QueueGroupingRow = QueueGroupingRow> {
|
|
2369
|
+
key: string;
|
|
2370
|
+
rows: T[];
|
|
2371
|
+
breached: number;
|
|
2372
|
+
atRisk: number;
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2375
|
+
declare interface QueueGroupingRow {
|
|
2376
|
+
collection: string;
|
|
2377
|
+
state: string | null;
|
|
2378
|
+
sla_status: 'ok' | 'warning' | 'breached' | null;
|
|
2379
|
+
at_risk: boolean;
|
|
2380
|
+
owners: {
|
|
2381
|
+
name: string;
|
|
2382
|
+
}[];
|
|
2383
|
+
aging_hours: number | null;
|
|
2384
|
+
extra?: Record<string, unknown>;
|
|
2385
|
+
}
|
|
2386
|
+
|
|
1500
2387
|
declare interface QueueItemRow {
|
|
1501
2388
|
collection: string;
|
|
1502
2389
|
item_id: string;
|
|
@@ -1595,6 +2482,23 @@ declare interface QuickFilterDef {
|
|
|
1595
2482
|
sort?: string;
|
|
1596
2483
|
}
|
|
1597
2484
|
|
|
2485
|
+
/** The reaction palette — mirrored server-side; anything else is rejected. */
|
|
2486
|
+
export declare const REACTION_EMOJI: readonly ["👍", "✅", "👀", "🎉", "❤️", "😂"];
|
|
2487
|
+
|
|
2488
|
+
export declare interface ReadViewLayout {
|
|
2489
|
+
layout: {
|
|
2490
|
+
id: number;
|
|
2491
|
+
name: string;
|
|
2492
|
+
};
|
|
2493
|
+
groups: LayoutGroup[];
|
|
2494
|
+
assignments: LayoutAssignment[];
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
export declare function RecordChatActions({ collection, itemDraft }: {
|
|
2498
|
+
collection: string;
|
|
2499
|
+
itemDraft: Record<string, unknown>;
|
|
2500
|
+
}): JSX.Element | null;
|
|
2501
|
+
|
|
1598
2502
|
export declare function RecordDrilldownSheet({ collection, itemId, layoutId, rootLayoutSlug, width, title, stack: controlledStack, onPush, onPop, onClose }: {
|
|
1599
2503
|
collection: string;
|
|
1600
2504
|
itemId: string;
|
|
@@ -1616,11 +2520,150 @@ export declare function RecordDrilldownSheet({ collection, itemId, layoutId, roo
|
|
|
1616
2520
|
onClose: () => void;
|
|
1617
2521
|
}): JSX.Element;
|
|
1618
2522
|
|
|
2523
|
+
export declare function RecordGridEditor({ config }: {
|
|
2524
|
+
config: RecordGridEditorConfig;
|
|
2525
|
+
}): JSX.Element;
|
|
2526
|
+
|
|
2527
|
+
declare interface RecordGridEditorConfig {
|
|
2528
|
+
collection: string;
|
|
2529
|
+
title?: string;
|
|
2530
|
+
/** Scope pickers: every field must be chosen before rows load; values filter
|
|
2531
|
+
* loaded rows and seed created rows. `filter` supports '$scope.<field>'
|
|
2532
|
+
* tokens off the other scope values. */
|
|
2533
|
+
scope?: Array<{
|
|
2534
|
+
field: string;
|
|
2535
|
+
collection: string;
|
|
2536
|
+
label?: string;
|
|
2537
|
+
filter?: Record<string, unknown>;
|
|
2538
|
+
}>;
|
|
2539
|
+
/** Free-form identity pickers on each row (year / division / …) — part of
|
|
2540
|
+
* what makes a row unique; rendered as comboboxes on NEW rows, read-only
|
|
2541
|
+
* labels on existing ones. */
|
|
2542
|
+
key_columns?: Array<{
|
|
2543
|
+
field: string;
|
|
2544
|
+
label?: string;
|
|
2545
|
+
collection: string;
|
|
2546
|
+
}>;
|
|
2547
|
+
/** One editable row per record of this collection; existing target rows are
|
|
2548
|
+
* matched via fk_field. `filter` supports '$scope.<field>' tokens. */
|
|
2549
|
+
row_source?: {
|
|
2550
|
+
collection: string;
|
|
2551
|
+
label_field: string;
|
|
2552
|
+
fk_field: string;
|
|
2553
|
+
filter?: Record<string, unknown>;
|
|
2554
|
+
sort?: string;
|
|
2555
|
+
};
|
|
2556
|
+
/** Plain editable numeric columns. */
|
|
2557
|
+
columns?: Array<{
|
|
2558
|
+
field: string;
|
|
2559
|
+
label?: string;
|
|
2560
|
+
readonly?: boolean;
|
|
2561
|
+
}>;
|
|
2562
|
+
/** Generates january…december editable columns per set (field =
|
|
2563
|
+
* '<month><suffix>'). */
|
|
2564
|
+
month_sets?: Array<{
|
|
2565
|
+
suffix: string;
|
|
2566
|
+
label: string;
|
|
2567
|
+
}>;
|
|
2568
|
+
allow_add?: boolean;
|
|
2569
|
+
allow_delete?: boolean;
|
|
2570
|
+
/** Written on save as the sum of the FIRST month set's values. */
|
|
2571
|
+
computed_total_field?: string;
|
|
2572
|
+
/** Custom query run after a successful save — params support '$scope.<f>'. */
|
|
2573
|
+
after_save?: {
|
|
2574
|
+
query_slug: string;
|
|
2575
|
+
params?: Record<string, unknown>;
|
|
2576
|
+
};
|
|
2577
|
+
/** Nested map editors opened from toolbar buttons (EFP Manage Cost Tables) —
|
|
2578
|
+
* receive the current scope; enabled once `require_scope` fields are set. */
|
|
2579
|
+
toolbar_editors?: Array<{
|
|
2580
|
+
button_label: string;
|
|
2581
|
+
sheet_width?: number | string;
|
|
2582
|
+
require_scope?: string[];
|
|
2583
|
+
json_map: JsonMapEditorConfig;
|
|
2584
|
+
}>;
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2587
|
+
export declare function RecordReadView({ collection, itemId, layoutData }: {
|
|
2588
|
+
collection: string;
|
|
2589
|
+
itemId: string;
|
|
2590
|
+
layoutData: ReadViewLayout;
|
|
2591
|
+
}): JSX.Element;
|
|
2592
|
+
|
|
2593
|
+
/**
|
|
2594
|
+
* "Since you last looked" — opening a saved record touches the per-user view
|
|
2595
|
+
* watermark and, when other people changed the record in between, renders a
|
|
2596
|
+
* one-line recap above the form. The server owns the session semantics (a
|
|
2597
|
+
* refresh within 30 minutes keeps the same baseline), the strip just shows
|
|
2598
|
+
* whatever the touch returned. Dismiss is per-mount — the next genuine visit
|
|
2599
|
+
* recomputes against the new baseline anyway.
|
|
2600
|
+
*/
|
|
2601
|
+
export declare function RecordRecapStrip({ collection, itemId }: {
|
|
2602
|
+
collection: string;
|
|
2603
|
+
itemId: string;
|
|
2604
|
+
}): JSX.Element | null;
|
|
2605
|
+
|
|
2606
|
+
/**
|
|
2607
|
+
* Per-record notification subscription — a bell in the item header that lets
|
|
2608
|
+
* any user watch this specific record. Backed entirely by the existing
|
|
2609
|
+
* nivaro_notification_subscriptions engine:
|
|
2610
|
+
*
|
|
2611
|
+
* State changes only → one event_type='workflow_transition' row scoped to
|
|
2612
|
+
* the record via filters [{field:'id', op:'eq', value:<id>}] (filter_field
|
|
2613
|
+
* stays null — on transition subs it means "to_state").
|
|
2614
|
+
* All changes → that row PLUS an event_type='all' row scoped via
|
|
2615
|
+
* filter_field='id' / filter_value (the create/update/delete path reads
|
|
2616
|
+
* only the flat filter pair, never the filters JSON).
|
|
2617
|
+
*
|
|
2618
|
+
* Transitions never fire the items-service update hook (state mirrors are raw
|
|
2619
|
+
* writes), so the two rows can't double-notify.
|
|
2620
|
+
*/
|
|
2621
|
+
export declare function RecordSubscribeButton({ collection, itemId, recordLabel }: {
|
|
2622
|
+
collection: string;
|
|
2623
|
+
itemId: string;
|
|
2624
|
+
recordLabel?: string;
|
|
2625
|
+
}): JSX.Element;
|
|
2626
|
+
|
|
1619
2627
|
/** Register the host's DM opener. Returns an unregister function. */
|
|
1620
2628
|
export declare function registerDmOpener(fn: DmOpener): () => void;
|
|
1621
2629
|
|
|
1622
2630
|
export declare function registerRoomOpener(fn: RoomOpener): () => void;
|
|
1623
2631
|
|
|
2632
|
+
export declare function RelatedRecordsPanel({ collection, itemId, defaultExpanded }: {
|
|
2633
|
+
collection: string;
|
|
2634
|
+
itemId: string;
|
|
2635
|
+
defaultExpanded?: boolean;
|
|
2636
|
+
}): JSX.Element;
|
|
2637
|
+
|
|
2638
|
+
export declare function RelationCombobox({ collection, value, onChange, disabled, placeholder, extraFilter, autoSelectSingle, optionSort, requiredParent, facets, fieldKey }: {
|
|
2639
|
+
collection: string;
|
|
2640
|
+
value: unknown;
|
|
2641
|
+
onChange: (v: unknown) => void;
|
|
2642
|
+
disabled?: boolean;
|
|
2643
|
+
placeholder?: string;
|
|
2644
|
+
extraFilter?: Record<string, unknown>;
|
|
2645
|
+
/** When the filtered option set has EXACTLY one option and the field is
|
|
2646
|
+
* empty, pick it automatically (options.auto_select_single). Two or more
|
|
2647
|
+
* options — or zero — leave the field blank; an existing value is never
|
|
2648
|
+
* overridden. Re-evaluates when the effective filter changes (e.g. a
|
|
2649
|
+
* cascade parent narrowing the list). */
|
|
2650
|
+
autoSelectSingle?: boolean;
|
|
2651
|
+
/** Option ordering: 'column' | '-column' (server sort) | 'label' | '-label' (display-label sort). Default: label ascending. */
|
|
2652
|
+
optionSort?: string;
|
|
2653
|
+
requiredParent?: string;
|
|
2654
|
+
/** Field name, so staleness can be reported to the form by name. */
|
|
2655
|
+
fieldKey?: string;
|
|
2656
|
+
/** In-picker filter facets: M2O fields ON THE TARGET COLLECTION rendered as
|
|
2657
|
+
* small pickers inside the dropdown. Ephemeral — they only narrow the
|
|
2658
|
+
* option list, nothing is written to the form. */
|
|
2659
|
+
facets?: Array<{
|
|
2660
|
+
field: string;
|
|
2661
|
+
label?: string;
|
|
2662
|
+
sort?: string;
|
|
2663
|
+
filter?: Record<string, unknown>;
|
|
2664
|
+
}>;
|
|
2665
|
+
}): JSX.Element;
|
|
2666
|
+
|
|
1624
2667
|
/**
|
|
1625
2668
|
* Unstyled relation picker.
|
|
1626
2669
|
* - m2o: single <select> of related items
|
|
@@ -1641,7 +2684,7 @@ export declare type RelationOption = {
|
|
|
1641
2684
|
raw: Record<string, unknown>;
|
|
1642
2685
|
};
|
|
1643
2686
|
|
|
1644
|
-
declare type RenderFieldProps = {
|
|
2687
|
+
export declare type RenderFieldProps = {
|
|
1645
2688
|
field: any;
|
|
1646
2689
|
value: unknown;
|
|
1647
2690
|
onChange: (v: unknown) => void;
|
|
@@ -1684,56 +2727,9 @@ export declare interface ReportViewProps {
|
|
|
1684
2727
|
emptyState?: React.ReactNode;
|
|
1685
2728
|
}
|
|
1686
2729
|
|
|
1687
|
-
export declare function
|
|
1688
|
-
|
|
1689
|
-
item: string | null | undefined,
|
|
1690
|
-
routes: NotificationRouteMap
|
|
1691
|
-
): NotificationTarget {
|
|
1692
|
-
const c = collection?.trim()
|
|
1693
|
-
if (!c) return null
|
|
1694
|
-
const i = item != null && String(item).trim() !== '' ? String(item) : null
|
|
1695
|
-
|
|
1696
|
-
if (c === '__chat__') {
|
|
1697
|
-
// Opening a room needs a registered chat dock — without one there is no
|
|
1698
|
-
// chat surface to open, so the row stays plain.
|
|
1699
|
-
return i && canOpenChatRoom() ? { type: 'chat', room: i } : null
|
|
1700
|
-
}
|
|
1701
|
-
|
|
1702
|
-
if (c === 'nivaro_report_defs') {
|
|
1703
|
-
const p = i ? routes.report?.(i) : null
|
|
1704
|
-
return p ? { type: 'path', path: p } : null
|
|
1705
|
-
}
|
|
1706
|
-
if (c === 'nivaro_queues') {
|
|
1707
|
-
const p = i ? routes.queue?.(i) : null
|
|
1708
|
-
return p ? { type: 'path', path: p } : null
|
|
1709
|
-
}
|
|
1710
|
-
if (c === 'nivaro_dashboards') {
|
|
1711
|
-
const p = i ? routes.dashboard?.(i) : null
|
|
1712
|
-
return p ? { type: 'path', path: p } : null
|
|
1713
|
-
}
|
|
1714
|
-
if (ALERT_COLLECTIONS.has(c)) {
|
|
1715
|
-
const p = routes.alerts?.()
|
|
1716
|
-
return p ? { type: 'path', path: p } : null
|
|
1717
|
-
}
|
|
1718
|
-
if (IMPORT_COLLECTIONS.has(c)) {
|
|
1719
|
-
const p = routes.imports?.()
|
|
1720
|
-
return p ? { type: 'path', path: p } : null
|
|
1721
|
-
}
|
|
1722
|
-
if (c === 'nivaro_issues') {
|
|
1723
|
-
const p = routes.issues?.()
|
|
1724
|
-
return p ? { type: 'path', path: p } : null
|
|
1725
|
-
}
|
|
1726
|
-
// Any other system collection has no user-facing page — plain row, never a
|
|
1727
|
-
// /collections/nivaro_* route that would 404 or 403.
|
|
1728
|
-
if (/^nivaro_/i.test(c) || /^directus_/i.test(c)) return null
|
|
1729
|
-
|
|
1730
|
-
if (i) {
|
|
1731
|
-
const p = routes.record(c, i)
|
|
1732
|
-
return p ? { type: 'path', path: p } : null
|
|
1733
|
-
}
|
|
1734
|
-
const p = routes.list?.(c)
|
|
1735
|
-
return p ? { type: 'path', path: p } : null
|
|
1736
|
-
}
|
|
2730
|
+
export declare function resolveCollectionIcon(iconName: string | null | undefined): React.ElementType | null;
|
|
2731
|
+
|
|
2732
|
+
export declare function resolveNotificationTarget(collection: string | null | undefined, item: string | null | undefined, routes: NotificationRouteMap): NotificationTarget;
|
|
1737
2733
|
|
|
1738
2734
|
export declare function RevisionsPanel({ collection, item, onRollback, triggerClassName, inlineTableFields, open, onOpenChange }: {
|
|
1739
2735
|
collection: string;
|
|
@@ -1767,20 +2763,67 @@ export declare interface RoomInfo {
|
|
|
1767
2763
|
*/
|
|
1768
2764
|
declare type RoomOpener = (room: string, label?: string) => void;
|
|
1769
2765
|
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
2766
|
+
export declare const ROW_HIGHLIGHT_TINTS: Record<string, {
|
|
2767
|
+
row: string;
|
|
2768
|
+
text: string;
|
|
2769
|
+
}>;
|
|
2770
|
+
|
|
2771
|
+
/**
|
|
2772
|
+
* A one-click rewrite of every row in the grid, driven by an aggregate of a
|
|
2773
|
+
* related collection.
|
|
2774
|
+
*
|
|
2775
|
+
* EFP's "Close Out Lines" is one instance of this shape: for each REQ line,
|
|
2776
|
+
* sum `open_unbilled_amount` across the PO lines pointing at it and, where the
|
|
2777
|
+
* line covers that remainder, subtract it. Expressed as config rather than
|
|
2778
|
+
* EFP code so any collection can do the same:
|
|
2779
|
+
*
|
|
2780
|
+
* {label:'Close Out Lines', relation:'po_line_items',
|
|
2781
|
+
* aggregate:{field:'open_unbilled_amount', op:'sum'},
|
|
2782
|
+
* guard:'{{amount}} >= {{__agg__}}',
|
|
2783
|
+
* set:{amount:'{{amount}} - {{__agg__}}'}}
|
|
2784
|
+
*
|
|
2785
|
+
* `{{__agg__}}` is the aggregate for that row (same token match-agg-column
|
|
2786
|
+
* uses); every other `{{field}}` reads the row's current value. Rows failing
|
|
2787
|
+
* the guard are left exactly as they are.
|
|
2788
|
+
*
|
|
2789
|
+
* Writes go through the SAME paths a manual cell edit uses, so a staged grid
|
|
2790
|
+
* (new record, addendum, save_mode 'pending') stages the change and an
|
|
2791
|
+
* immediate grid PATCHes it — the action never invents its own persistence.
|
|
2792
|
+
*/
|
|
2793
|
+
declare interface RowBulkActionConfig {
|
|
2794
|
+
label: string;
|
|
2795
|
+
/** O2M alias on the ROW's collection pointing at the rows to aggregate. */
|
|
2796
|
+
relation: string;
|
|
2797
|
+
aggregate: {
|
|
2798
|
+
field: string;
|
|
2799
|
+
op?: 'sum' | 'count' | 'min' | 'max';
|
|
2800
|
+
};
|
|
2801
|
+
/** Optional per-row condition; rows that fail are skipped untouched. */
|
|
2802
|
+
guard?: string;
|
|
2803
|
+
/** field → formula. */
|
|
2804
|
+
set: Record<string, string>;
|
|
2805
|
+
confirm?: string;
|
|
2806
|
+
variant?: 'default' | 'danger';
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
export declare function rowHighlightClass(color?: string | null): string | undefined;
|
|
2810
|
+
|
|
2811
|
+
export declare function rowHighlightTextClass(color?: string | null): string;
|
|
2812
|
+
|
|
2813
|
+
declare interface RowRule {
|
|
2814
|
+
trigger_field?: string | null;
|
|
2815
|
+
trigger_op?: string;
|
|
2816
|
+
trigger_value?: string | null;
|
|
2817
|
+
target_field: string;
|
|
2818
|
+
target_type: 'set' | 'clear' | 'relation_field';
|
|
2819
|
+
target_value?: string | null;
|
|
2820
|
+
only_if_empty?: boolean;
|
|
2821
|
+
sort?: number;
|
|
1782
2822
|
}
|
|
1783
2823
|
|
|
2824
|
+
/** Convenience: run a resolved target (navigate or open the chat room). */
|
|
2825
|
+
export declare function runNotificationTarget(target: NotificationTarget, navigate: (path: string) => void): boolean;
|
|
2826
|
+
|
|
1784
2827
|
export declare type SectionState = {
|
|
1785
2828
|
isCollapsed: (key: string) => boolean;
|
|
1786
2829
|
toggle: (key: string) => void;
|
|
@@ -1870,7 +2913,9 @@ export declare function TextField({ field, value, onChange, error, disabled, rea
|
|
|
1870
2913
|
|
|
1871
2914
|
export declare function TipLayer(): ReactPortal | null;
|
|
1872
2915
|
|
|
1873
|
-
declare
|
|
2916
|
+
export declare function titleCase(str: string): string;
|
|
2917
|
+
|
|
2918
|
+
export declare type TokenResolver = (path: string) => unknown;
|
|
1874
2919
|
|
|
1875
2920
|
/** Install the listeners. Safe to call more than once. */
|
|
1876
2921
|
export declare function trackActivity(): void;
|
|
@@ -1886,8 +2931,45 @@ export declare function translateScopeValues(client: {
|
|
|
1886
2931
|
target_collection: string;
|
|
1887
2932
|
}, ids: Array<string | number>, valueField?: string): Promise<Array<string | number>>;
|
|
1888
2933
|
|
|
2934
|
+
/**
|
|
2935
|
+
* Base URL + auth for the few raw `fetch` calls (widgets, PDF blobs) that
|
|
2936
|
+
* can't go through `client.request`. Derives everything from the ambient
|
|
2937
|
+
* Nivaro client so external hosts (different origin, token auth) work the
|
|
2938
|
+
* same as the same-origin admin; falls back to relative '/api' + cookies
|
|
2939
|
+
* when no provider is mounted.
|
|
2940
|
+
*/
|
|
2941
|
+
export declare function useApiFetchConfig(): {
|
|
2942
|
+
apiBase: string;
|
|
2943
|
+
authHeaders: Record<string, string>;
|
|
2944
|
+
credentials: RequestCredentials;
|
|
2945
|
+
};
|
|
2946
|
+
|
|
1889
2947
|
export declare function useApiUpdate(): ApiVersionInfo | null;
|
|
1890
2948
|
|
|
2949
|
+
export declare function useChannelAdmin(channelId: number | null): {
|
|
2950
|
+
update: UseMutationResult<unknown, Error, {
|
|
2951
|
+
name?: string;
|
|
2952
|
+
topic?: string | null;
|
|
2953
|
+
visibility?: "open" | "role" | "private";
|
|
2954
|
+
role?: string | null;
|
|
2955
|
+
is_archived?: boolean;
|
|
2956
|
+
}, unknown>;
|
|
2957
|
+
addMember: UseMutationResult<unknown, Error, string, unknown>;
|
|
2958
|
+
removeMember: UseMutationResult<unknown, Error, string, unknown>;
|
|
2959
|
+
};
|
|
2960
|
+
|
|
2961
|
+
/** Browsable channels — what keeps the sidebar to joined rooms only. */
|
|
2962
|
+
export declare function useChannelDirectory(search: string): {
|
|
2963
|
+
channels: NoInfer<DirectoryChannel[]>;
|
|
2964
|
+
loading: boolean;
|
|
2965
|
+
};
|
|
2966
|
+
|
|
2967
|
+
/** Members of a channel — the owner-facing list for private channels. */
|
|
2968
|
+
export declare function useChannelMembers(channelId: number | null): {
|
|
2969
|
+
members: NoInfer<ChannelMember[]>;
|
|
2970
|
+
loading: boolean;
|
|
2971
|
+
};
|
|
2972
|
+
|
|
1891
2973
|
export declare function useChatConfig(): ChatConfig;
|
|
1892
2974
|
|
|
1893
2975
|
export declare function useChatMessages(room: string | null): {
|
|
@@ -1895,6 +2977,13 @@ export declare function useChatMessages(room: string | null): {
|
|
|
1895
2977
|
loading: boolean;
|
|
1896
2978
|
};
|
|
1897
2979
|
|
|
2980
|
+
/** Id + name only — /api/roles is admin-gated, so the channel picker reads the
|
|
2981
|
+
* chat route's own lightweight list. */
|
|
2982
|
+
export declare function useChatRoles(): NoInfer<{
|
|
2983
|
+
id: string;
|
|
2984
|
+
name: string;
|
|
2985
|
+
}[]>;
|
|
2986
|
+
|
|
1898
2987
|
/**
|
|
1899
2988
|
* The sidebar. The server decides WHICH rooms (visibility) and computes unread
|
|
1900
2989
|
* in SQL against the watermark; the client only labels them. The old version
|
|
@@ -1908,8 +2997,48 @@ export declare function useChatRooms(): {
|
|
|
1908
2997
|
loading: boolean;
|
|
1909
2998
|
};
|
|
1910
2999
|
|
|
3000
|
+
/** Search every room in MY sidebar (server enforces visibility by
|
|
3001
|
+
* construction — the room set is the user's own). */
|
|
3002
|
+
export declare function useChatSearch(q: string): {
|
|
3003
|
+
hits: NoInfer<ChatSearchHit[]>;
|
|
3004
|
+
loading: boolean;
|
|
3005
|
+
};
|
|
3006
|
+
|
|
3007
|
+
export declare function useCreateChannel(): UseMutationResult<unknown, Error, {
|
|
3008
|
+
name: string;
|
|
3009
|
+
key?: string;
|
|
3010
|
+
topic?: string;
|
|
3011
|
+
visibility?: "open" | "role" | "private";
|
|
3012
|
+
role?: string | null;
|
|
3013
|
+
}, unknown>;
|
|
3014
|
+
|
|
3015
|
+
export declare function useCreateGroupDm(): UseMutationResult< {
|
|
3016
|
+
room: string;
|
|
3017
|
+
name: string;
|
|
3018
|
+
}, Error, {
|
|
3019
|
+
user_ids: string[];
|
|
3020
|
+
name?: string;
|
|
3021
|
+
}, unknown>;
|
|
3022
|
+
|
|
3023
|
+
export declare function useDeleteMessage(room: string): UseMutationResult<unknown, Error, number, unknown>;
|
|
3024
|
+
|
|
1911
3025
|
export declare function useDrilldown(): DrilldownContextValue | null;
|
|
1912
3026
|
|
|
3027
|
+
export declare function useEditMessage(room: string): UseMutationResult<unknown, Error, {
|
|
3028
|
+
messageId: number;
|
|
3029
|
+
text: string;
|
|
3030
|
+
}, unknown>;
|
|
3031
|
+
|
|
3032
|
+
/**
|
|
3033
|
+
* Resolves an entity room ('wf:CR26-76773') to the record's URL, host-routed
|
|
3034
|
+
* via cfg.recordUrl. The room-type registry maps the prefix to a collection +
|
|
3035
|
+
* match field; when the match field isn't the PK the record is looked up by
|
|
3036
|
+
* it (readable by construction — room visibility already required record
|
|
3037
|
+
* read). Null for non-entity rooms, unregistered prefixes, or when the record
|
|
3038
|
+
* doesn't resolve.
|
|
3039
|
+
*/
|
|
3040
|
+
export declare function useEntityRoomLink(room: string | null): string | null;
|
|
3041
|
+
|
|
1913
3042
|
export declare function useFieldArray(form: UseNivaroFormReturn, field: string): FieldArrayReturn;
|
|
1914
3043
|
|
|
1915
3044
|
export declare function useFieldState(form: UseNivaroFormReturn, field: string): FieldState;
|
|
@@ -2033,6 +3162,8 @@ export declare type UseNivaroFormReturn = {
|
|
|
2033
3162
|
gridFlushersRef: default_2.MutableRefObject<Map<string, () => Promise<void>>>;
|
|
2034
3163
|
};
|
|
2035
3164
|
|
|
3165
|
+
export declare function useOptionalNivaroClient(): NivaroClient | null;
|
|
3166
|
+
|
|
2036
3167
|
export declare function useOrderedLayout(form: UseNivaroFormReturn): {
|
|
2037
3168
|
items: LayoutItem[];
|
|
2038
3169
|
hasTabs: boolean;
|
|
@@ -2099,6 +3230,21 @@ export declare function useRelationOptions(client: NivaroClient | null, relatedC
|
|
|
2099
3230
|
error: Error | null;
|
|
2100
3231
|
};
|
|
2101
3232
|
|
|
3233
|
+
export declare function useRoomMembership(): {
|
|
3234
|
+
join: UseMutationResult<unknown, Error, string, unknown>;
|
|
3235
|
+
leave: UseMutationResult<unknown, Error, string, unknown>;
|
|
3236
|
+
setMuted: UseMutationResult<unknown, Error, {
|
|
3237
|
+
room: string;
|
|
3238
|
+
muted: boolean;
|
|
3239
|
+
}, unknown>;
|
|
3240
|
+
setNotifyMode: UseMutationResult<unknown, Error, {
|
|
3241
|
+
room: string;
|
|
3242
|
+
mode: "all" | "mentions";
|
|
3243
|
+
}, unknown>;
|
|
3244
|
+
};
|
|
3245
|
+
|
|
3246
|
+
export declare function useRoomPins(room: string | null): NoInfer<PinnedMessage[]>;
|
|
3247
|
+
|
|
2102
3248
|
/** Stacked avatar cluster (+N) with a hover/pinnable portal roster whose rows
|
|
2103
3249
|
* are UserChips — the single user-display primitive for owners/user lists.
|
|
2104
3250
|
* Reused by the item-header Owners chip and the collection browser. */
|
|
@@ -2122,6 +3268,13 @@ export declare function useSessionRecorder(options?: SessionRecorderOptions): vo
|
|
|
2122
3268
|
|
|
2123
3269
|
export declare function useTabState(form: UseNivaroFormReturn): TabState;
|
|
2124
3270
|
|
|
3271
|
+
export declare function useTogglePin(room: string): UseMutationResult<unknown, Error, number, unknown>;
|
|
3272
|
+
|
|
3273
|
+
export declare function useToggleReaction(room: string): UseMutationResult<unknown, Error, {
|
|
3274
|
+
messageId: number;
|
|
3275
|
+
emoji: string;
|
|
3276
|
+
}, unknown>;
|
|
3277
|
+
|
|
2125
3278
|
export declare function useTypingIndicator(room: string | null): {
|
|
2126
3279
|
onType: () => void;
|
|
2127
3280
|
clearTyping: () => void;
|
|
@@ -2130,6 +3283,17 @@ export declare function useTypingIndicator(room: string | null): {
|
|
|
2130
3283
|
|
|
2131
3284
|
export declare function useUnreadChirp(totalUnread: number, rooms?: RoomInfo[]): void;
|
|
2132
3285
|
|
|
3286
|
+
/** Directory of users to add to a private channel. */
|
|
3287
|
+
export declare function useUserSearch(search: string, enabled: boolean): {
|
|
3288
|
+
users: NoInfer<{
|
|
3289
|
+
id: string;
|
|
3290
|
+
first_name: string | null;
|
|
3291
|
+
last_name: string | null;
|
|
3292
|
+
email: string | null;
|
|
3293
|
+
}[]>;
|
|
3294
|
+
loading: boolean;
|
|
3295
|
+
};
|
|
3296
|
+
|
|
2133
3297
|
export declare function useWatchFields(form: UseNivaroFormReturn, fields: string[]): Record<string, unknown>;
|
|
2134
3298
|
|
|
2135
3299
|
/**
|
|
@@ -2149,6 +3313,32 @@ declare interface ValidationResult {
|
|
|
2149
3313
|
unknownTokens: string[];
|
|
2150
3314
|
}
|
|
2151
3315
|
|
|
3316
|
+
export declare function WidgetSlot({ widgetId, inputBindings, itemDraft, itemCollection, ready, label, defaultExpanded, frameless, apiBase: apiBaseProp, compact, strip, onClientAction, onWidgetType, onContentChange }: WidgetSlotProps): JSX.Element | null;
|
|
3317
|
+
|
|
3318
|
+
declare interface WidgetSlotProps {
|
|
3319
|
+
widgetId: number;
|
|
3320
|
+
inputBindings?: InputBinding[];
|
|
3321
|
+
itemDraft?: Record<string, unknown>;
|
|
3322
|
+
itemCollection?: string;
|
|
3323
|
+
ready?: boolean;
|
|
3324
|
+
label?: string;
|
|
3325
|
+
defaultExpanded?: boolean;
|
|
3326
|
+
/** Render body only — no card border/header/collapse (host provides chrome). */
|
|
3327
|
+
frameless?: boolean;
|
|
3328
|
+
apiBase?: string;
|
|
3329
|
+
compact?: boolean;
|
|
3330
|
+
strip?: boolean;
|
|
3331
|
+
onClientAction?: (action: ClientAction) => void;
|
|
3332
|
+
onWidgetType?: (type: string) => void;
|
|
3333
|
+
/**
|
|
3334
|
+
* Reports whether the widget has anything to show (review_list: any rows;
|
|
3335
|
+
* other types: any successful render; errors count as content so failures
|
|
3336
|
+
* stay visible). Lets a host section's hide_when_empty consider widget
|
|
3337
|
+
* content, not just field values.
|
|
3338
|
+
*/
|
|
3339
|
+
onContentChange?: (hasContent: boolean) => void;
|
|
3340
|
+
}
|
|
3341
|
+
|
|
2152
3342
|
export declare function WorkflowPanel({ collection, item }: {
|
|
2153
3343
|
collection: string;
|
|
2154
3344
|
item: string;
|