@ai-matrx/records-ui 0.28.0 → 0.38.0

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 CHANGED
@@ -1,11 +1,12 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, ComponentType, RefObject } from 'react';
3
- import { PermissionLevel, Table, Uuid as Uuid$1, AggregateFilter, RecordsError, Field, RecordDocument, ReadRow, WriteConflict, ParityFieldType, NewFieldDeclaration, ValueEnvelope, WorkInboxKind, RuleExpression, FormSummary, PortalCard, PortalPrincipal, PortalPreviewRow, DashboardBlockKind, AggregateBucket, AggregateMeasure, DashboardBlock, DashboardSummary, DocTemplateRow, DocRenderRow, DashboardBlockResult, AnonTokenBinding, RecordsConfig, RecordsActor, RecordsDataSource, FieldTypeWord } from '@ai-matrx/records';
3
+ import * as _ai_matrx_records from '@ai-matrx/records';
4
+ import { PermissionLevel, Table, RecordScopeContext, EnrichCell, RecordsError, Uuid as Uuid$1, AggregateFilter, Field, RecordDocument, ReadRow, WriteConflict, ParityFieldType, NewFieldDeclaration, ValueEnvelope, WorkInboxKind, RuleExpression, FormSummary, PortalCard, PortalPrincipal, PortalPreviewRow, DashboardBlockKind, AggregateBucket, AggregateMeasure, DashboardBlock, DashboardSummary, DocTemplateRow, DocRenderRow, QuietHours, DashboardBlockResult, CaptureSheetFace, CaptureField, AnonTokenBinding, RecordsConfig, RecordsActor, RecordsDataSource, FieldTypeWord } from '@ai-matrx/records';
4
5
  import { Uuid, Field as Field$1, ReadRow as ReadRow$1 } from '@ai-matrx/records/react';
5
6
  import { RecordsClient } from '@ai-matrx/records/core';
6
7
  import { FieldFormatConfig } from '@ai-matrx/design-system/field-formats';
7
8
  import { MatrxColumnDef } from '@ai-matrx/design-system/data-table/types';
8
- import { TableStyle, ChoiceColorLookup } from '@ai-matrx/design-system/data-table';
9
+ import { TableStyle, GroupAggregateSpec, GroupOrder, ChoiceColorLookup } from '@ai-matrx/design-system/data-table';
9
10
 
10
11
  /** The six things a person does to a record or a table, as the screens offer them. */
11
12
  type Capability = "read" | "comment" | "write" | "remove" | "share" | "structure";
@@ -52,13 +53,34 @@ interface RecordChatEntry {
52
53
  label: string;
53
54
  /** `text` for a scalar, `json` for a structure. The host maps this to its own vocabulary. */
54
55
  type: "text" | "json";
56
+ /**
57
+ * DYN: a merge field resolves to a TRIPLE, not a string. The prompt gets the
58
+ * rendered value; the RUN gets this, and it is the only thing a "where did
59
+ * that come from" question can be answered from — so a host can turn a cited
60
+ * answer into a link to the record AND to the version it was read at.
61
+ */
62
+ cite?: {
63
+ record_id: Uuid;
64
+ field_id: Uuid;
65
+ value_version: number;
66
+ written_at: string | null;
67
+ };
55
68
  }
56
- /** A Field the STORE masked for this reader, named rather than silently dropped. */
69
+ /** A Field the agent was NOT given, named rather than silently dropped. */
57
70
  interface RecordChatWithheld {
58
71
  key: string;
59
72
  label: string;
60
73
  /** The store's own reason. */
61
74
  reason: string;
75
+ /**
76
+ * WHICH ABSENCE THIS IS. `masked` — the store kept it from THIS READER.
77
+ * `policy` — the organization keeps it out of conversations, and the same
78
+ * person can read it on the record two inches away. A screen that collapsed
79
+ * the two would tell somebody the wrong thing about their own access.
80
+ */
81
+ because?: "masked" | "policy";
82
+ /** The whole sentence, already written. A screen prints it; it composes nothing. */
83
+ says?: string;
62
84
  }
63
85
  /** Everything the host's chat surface needs, and nothing about how it should look. */
64
86
  interface RecordChatContext {
@@ -73,10 +95,18 @@ interface RecordChatContext {
73
95
  tableName: string;
74
96
  /** The record's own title, for the panel's one-row header and the chip. */
75
97
  title: string;
98
+ /** What the scope chip says: `About: Acme Industrial`. */
99
+ chip: string;
76
100
  /** The grounding, already read through the read door. */
77
101
  entries: RecordChatEntry[];
78
102
  /** What this reader is NOT being given, with the store's reason for each. */
79
103
  withheld: RecordChatWithheld[];
104
+ /** Questions derived from THIS record's shape. Never a fixed list. */
105
+ suggested: string[];
106
+ /** One sentence naming what is not in the conversation. Printed verbatim. */
107
+ says: string;
108
+ /** The whole door answer, for a host that wants the history or the relations. */
109
+ scope: RecordScopeContext;
80
110
  }
81
111
  declare const NO_CHAT_REASON: string;
82
112
  interface RecordChatProps {
@@ -86,29 +116,73 @@ interface RecordChatProps {
86
116
  }
87
117
  declare function RecordChat({ tableId, recordId, className }: RecordChatProps): react.JSX.Element;
88
118
 
89
- /** What the host is asked to have the server's `records` tool do. */
119
+ /** What the host is asked to have the SERVER's `records` tool do. */
90
120
  interface EnrichAsk {
91
121
  tableId: Uuid;
92
- recordId: Uuid;
93
- /** The agent Fields to refill, each with why this panel thinks it is due. */
94
- fields: Array<{
95
- key: string;
96
- label: string;
97
- because: string;
98
- }>;
122
+ fieldId: Uuid;
123
+ fieldKey: string;
124
+ /** How many records this run covers. */
125
+ rows: number;
126
+ /** True: ask the model and report what it WOULD write, writing nothing. */
127
+ previewOnly: boolean;
99
128
  }
100
129
  interface EnrichOutcome {
101
130
  ok: boolean;
102
131
  /** What happened, in a sentence — the server's own words when it has some. */
103
132
  message: string;
133
+ /** For a preview: what would go in each cell. */
134
+ wouldWrite?: Array<{
135
+ record_id: string;
136
+ value?: unknown;
137
+ absent?: string;
138
+ says?: string;
139
+ }>;
104
140
  }
105
141
  declare const NO_ENRICH_REASON: string;
142
+ /** Which of the four things this cell is. One place, so nothing can disagree. */
143
+ declare function cellState(cell: EnrichCell | undefined): "none" | "agent" | "yours" | "unsure";
144
+ interface EnrichBadgeProps {
145
+ cell: EnrichCell | undefined;
146
+ /** Bound when this person may change the record; absent, no pin control is drawn. */
147
+ onPin?: ((pinned: boolean) => void | Promise<void>) | undefined;
148
+ className?: string | undefined;
149
+ }
150
+ /**
151
+ * THE BADGE. Drawn beside every agent-owned value, always.
152
+ *
153
+ * The word on it is the state; `stale` rides along as a second, smaller word rather than a
154
+ * colour, because "this is six weeks old" is a sentence and not a hue — a person reading a
155
+ * red cell has to be told what red means, and then told again next week.
156
+ */
157
+ declare function EnrichBadge({ cell, onPin, className }: EnrichBadgeProps): react.JSX.Element | null;
158
+ /**
159
+ * Every badge on a page of a grid, in ONE round trip.
160
+ *
161
+ * A badge asked per cell is one round trip per badge — fifty round trips to draw fifty
162
+ * badges, which is why the store answers the whole page at once. The hook is keyed by the
163
+ * record ids the grid is actually drawing, so paging re-asks and scrolling does not.
164
+ */
165
+ declare function useEnrichCells(tableId: Uuid | undefined, recordIds: Uuid[] | undefined): {
166
+ cells: Map<string, EnrichCell>;
167
+ refresh: () => Promise<void>;
168
+ error: RecordsError | null;
169
+ };
106
170
  interface EnrichPanelProps {
107
171
  tableId: Uuid;
108
- recordId: Uuid;
172
+ /** Open straight onto one column. Absent, the panel lists every agent-owned column. */
173
+ fieldId?: Uuid | undefined;
109
174
  className?: string | undefined;
110
175
  }
111
- declare function EnrichPanel({ tableId, recordId, className }: EnrichPanelProps): react.JSX.Element;
176
+ /**
177
+ * THE PANEL — the whole of an enrichment in one screen, in a person's own words.
178
+ *
179
+ * It is deliberately NOT a settings form with a Save button at the bottom. The order is the
180
+ * order somebody actually thinks in: what should go in this column · what it may look at ·
181
+ * how often to check it again · what it has cost so far · SEE IT ON FIVE ROWS · and only
182
+ * then, turn it on. The preview is not a nicety: it is the only honest way to find out what
183
+ * a model will write into other people's data before it writes it.
184
+ */
185
+ declare function EnrichPanel({ tableId, fieldId, className }: EnrichPanelProps): react.JSX.Element;
112
186
 
113
187
  /**
114
188
  * What a person may do to one table. The four words and the ladder are the
@@ -229,6 +303,26 @@ interface RecordsUiHost {
229
303
  * nowhere.
230
304
  */
231
305
  chat?: (context: RecordChatContext) => ReactNode;
306
+ /**
307
+ * OPTIONAL. "TALK TO THIS RECORD" — the HOST opens its own one chat surface
308
+ * (AGT-N-9, PRODUCTS row 11).
309
+ *
310
+ * `chat` is the port that RENDERS a chat inside a panel this package draws.
311
+ * This one is the other direction: a menu entry in the grid, the cell menu or
312
+ * the record header says "the person wants to talk about this record", and the
313
+ * host opens the chat where the host puts chats — full height, the platform's
314
+ * own pattern — and binds the conversation to the record through
315
+ * `conversationScopeBind`. Drawing a chat next to a grid row from inside this
316
+ * package would be the parallel layer the canvas ruling forbids.
317
+ *
318
+ * ABSENT, NEVER DEAD: where neither this nor `chat` is bound, the entries do
319
+ * not render at all.
320
+ */
321
+ talkToRecord?: (target: {
322
+ tableId: Uuid$1;
323
+ recordId: Uuid$1;
324
+ title: string;
325
+ }) => void;
232
326
  /**
233
327
  * OPTIONAL. THE SERVER'S `records` TOOL (SCR-27).
234
328
  *
@@ -592,10 +686,20 @@ declare function useGridEditing({ tableId, fields, rows, reload, canWrite, mayWr
592
686
  * `data-matrx-cell-control` is the data table's own opt-out from whole-row
593
687
  * click, so opening a cell never also opens the record panel behind it.
594
688
  */
595
- declare function GridCell({ field, row, editing, canWrite, whyNot, format, }: {
689
+ declare function GridCell({ field, row, editing, canWrite, whyNot, format, onAskWhoChanged, }: {
596
690
  field: Field;
597
691
  row: ReadRow;
598
- editing: GridEditing;
692
+ /**
693
+ * The edit session, or NULL on a cell nobody may edit.
694
+ *
695
+ * 🚨 Null is not "do not render me". "Who changed this?" is a READING
696
+ * question — the person who may not edit a cell is exactly the person who
697
+ * wants to know who did — and the cell used to disappear entirely the moment
698
+ * editing was off, taking the control with it while this file's own comments
699
+ * claimed it was offered at viewer. A null session means no editor, nothing
700
+ * else.
701
+ */
702
+ editing: GridEditing | null;
599
703
  /** Whether this person may write THIS row. Asked before the cell is drawn. */
600
704
  canWrite: boolean;
601
705
  /**
@@ -606,6 +710,12 @@ declare function GridCell({ field, row, editing, canWrite, whyNot, format, }: {
606
710
  whyNot?: string | undefined;
607
711
  /** The column's declared format, so the read view reads like its header. */
608
712
  format?: FieldFormatConfig | undefined;
713
+ /**
714
+ * "WHO CHANGED THIS?" — the question a person asks of the CELL they are
715
+ * looking at. Bound by the host; absent, no control is drawn at all, because
716
+ * a control that opens nothing is the thing this package exists to prevent.
717
+ */
718
+ onAskWhoChanged?: ((fieldKey: string, recordId: Uuid$1) => void) | undefined;
609
719
  }): react.JSX.Element;
610
720
 
611
721
  /**
@@ -649,6 +759,33 @@ declare function RefusalLine({ error, className }: {
649
759
  * has ever styled still shows `$1,250.50` and `45%`.
650
760
  */
651
761
 
762
+ /**
763
+ * SECTIONS BY A FIELD — the view's own grouping.
764
+ *
765
+ * `field` is a Field KEY, exactly like `frozen` and the keys of `formats`,
766
+ * because a view is written against the Table's declaration and never against
767
+ * whatever id a screen happened to build its columns with.
768
+ *
769
+ * `aggregates` is keyed by Field key too, and `collapsed` holds the data
770
+ * table's own group keys (`s:Blocked`, `n:3`, `empty`), which is what the
771
+ * primitive emits and the only thing that survives a value rendering the same
772
+ * text as another.
773
+ *
774
+ * NOTHING HERE IS EVER CALLED `valueOf`, `toString` or `hasOwnProperty`: every
775
+ * object in JavaScript already has all three, so an optional field by one of
776
+ * those names is NEVER absent and a `config.valueOf ? … : …` check silently
777
+ * reads `Object.prototype`. It cost the primitive a whole grouping once.
778
+ */
779
+ type GridGrouping = {
780
+ /** The Field key whose value makes the sections. */
781
+ field: string;
782
+ /** Per-Field-key subtotal on every section header. */
783
+ aggregates?: Record<string, GroupAggregateSpec>;
784
+ /** Section order. The primitive's default is `value-asc`; blanks sort last. */
785
+ order?: GroupOrder;
786
+ /** The sections this view keeps shut, by the primitive's own group key. */
787
+ collapsed?: string[];
788
+ };
652
789
  /** Everything a view says about how its table LOOKS. */
653
790
  type GridPresentation = {
654
791
  /** Color-by-a-column, rules and manual highlights. */
@@ -662,10 +799,29 @@ type GridPresentation = {
662
799
  * guessed offset.
663
800
  */
664
801
  frozen?: string[];
802
+ /** Collapsible sections by one Field, with subtotals on each header. */
803
+ grouping?: GridGrouping;
804
+ /**
805
+ * The width a person dragged a column to, by Field key. SPARSE on purpose —
806
+ * a view saved before widths existed carries none and still parses, and a
807
+ * column nobody resized is left to the table's own measurement.
808
+ */
809
+ widths?: Record<string, number>;
810
+ /** The body row height this view remembers, in px. */
811
+ rowHeight?: number;
665
812
  };
666
813
  declare const EMPTY_PRESENTATION: GridPresentation;
667
814
  /** A frozen column needs a known width, or the table declines to freeze at all. */
668
815
  declare const FROZEN_COLUMN_WIDTH = 200;
816
+ /**
817
+ * WHAT A ROW HEIGHT IS ALLOWED TO BE. Below the floor the text is clipped and
818
+ * no editor fits; above the ceiling one record fills the screen. A view asking
819
+ * for anything outside it is DROPPED rather than obeyed, because a saved look
820
+ * must not be able to make a table unreadable — and the Fields' own heights
821
+ * still draw, which is the tolerant half.
822
+ */
823
+ declare const MIN_ROW_HEIGHT = 24;
824
+ declare const MAX_ROW_HEIGHT = 96;
669
825
  /**
670
826
  * Read a presentation out of whatever the view record holds — an object, or the
671
827
  * JSON string a text field stores.
@@ -716,6 +872,15 @@ interface GridProps {
716
872
  onOpenRecord?: ((recordId: Uuid) => void) | undefined;
717
873
  /** SCR-2. Called when an admin clicks the "+" at the end of the headers. */
718
874
  onAddField?: (() => void) | undefined;
875
+ /**
876
+ * "WHO CHANGED THIS?" — from the cell, about that column, on that record.
877
+ *
878
+ * The question people actually ask is about a CELL they are looking at, not
879
+ * about a record they then have to open. The store answers it
880
+ * (`custom.field_history`), and the host decides where the answer appears —
881
+ * a side panel, a window, a route. Unbound, the control is ABSENT, not dead.
882
+ */
883
+ onAskWhoChanged?: ((fieldKey: string, recordId: Uuid) => void) | undefined;
719
884
  /**
720
885
  * The host's whole-record form. Offered BY NAME when the store refuses an
721
886
  * empty record — a Table with a required Field cannot be added to one cell at
@@ -737,9 +902,26 @@ interface GridProps {
737
902
  * override, never the only thing that makes a column readable.
738
903
  */
739
904
  presentation?: GridPresentation | undefined;
905
+ /**
906
+ * THE LOOK, WRITTEN BACK. Called with the WHOLE next look when the person
907
+ * changes one on the table itself — picks a column to group by, shuts a
908
+ * section, drags a column wider.
909
+ *
910
+ * It is the same door every other view change already uses: `ViewSwitcher`
911
+ * folds it into its `onViewChange` patch and `TablePage` writes that patch
912
+ * onto the view record with `client.recordUpdate`, carrying the version it
913
+ * read. The Grid has no view id and must not grow one — a component that
914
+ * wrote to a record it was never told about would be a second, parallel way
915
+ * to save a view.
916
+ *
917
+ * UNBOUND, NOTHING IS DEAD. A host that binds no door still gets grouping,
918
+ * collapsing and resizing for this visit — they are held in the grid's own
919
+ * state — they are simply not remembered.
920
+ */
921
+ onPresentationChange?: ((next: GridPresentation) => void) | undefined;
740
922
  className?: string | undefined;
741
923
  }
742
- declare function Grid({ tableId, pageSize, onOpenRecord, onAddField, onNewRecordForm, toolbarActions, editable, presentation, className, }: GridProps): react.JSX.Element;
924
+ declare function Grid({ tableId, pageSize, onOpenRecord, onAddField, onNewRecordForm, toolbarActions, editable, presentation, onPresentationChange, className, onAskWhoChanged, }: GridProps): react.JSX.Element;
743
925
  /**
744
926
  * One Field becomes one column. The header is the Field's own NAME — never its
745
927
  * key (`names.ts`) — and the cell is the value, rendered by its parity type and
@@ -748,6 +930,18 @@ declare function Grid({ tableId, pageSize, onOpenRecord, onAddField, onNewRecord
748
930
  declare function columnForField(field: Field$1, editing?: GridEditing | null, mayWriteRow?: (rowId: Uuid) => boolean, whyNotRow?: (rowId: Uuid) => string, look?: {
749
931
  format?: FieldFormatConfig;
750
932
  frozen?: boolean;
933
+ },
934
+ /** "Who changed this?" from the cell's own menu. Absent, no control is drawn. */
935
+ onAskWhoChanged?: ((fieldKey: string, recordId: Uuid) => void) | undefined,
936
+ /**
937
+ * PRODUCTS row 10 — the provenance of a cell a MODEL owns. `cellFor` answers the page's
938
+ * already-fetched badge data for one row; `onPin` is bound only where this person may
939
+ * change the record, so a viewer reads every badge and is offered no control they do not
940
+ * have. Absent entirely, no badge is drawn and the column looks exactly as it did.
941
+ */
942
+ enrich?: {
943
+ cellFor: (recordId: Uuid) => _ai_matrx_records.EnrichCell | undefined;
944
+ onPin?: ((recordId: Uuid, fieldKey: string, pinned: boolean) => void | Promise<void>) | undefined;
751
945
  }): MatrxColumnDef<ReadRow$1>;
752
946
 
753
947
  interface ExportMenuProps {
@@ -762,12 +956,10 @@ declare function ExportMenu({ tableId, rows, label, className }: ExportMenuProps
762
956
 
763
957
  interface ImportWizardProps {
764
958
  tableId: Uuid;
765
- /** SCR-N-7: what "add this as a field" does. Absent means the offer is not made. */
766
- onProposeField?: ((header: string) => void) | undefined;
767
959
  onDone?: ((written: number) => void) | undefined;
768
960
  className?: string | undefined;
769
961
  }
770
- declare function ImportWizard({ tableId, onProposeField, onDone, className }: ImportWizardProps): react.JSX.Element;
962
+ declare function ImportWizard({ tableId, onDone, className }: ImportWizardProps): react.JSX.Element;
771
963
 
772
964
  interface CustomFieldsSectionProps {
773
965
  /** The standard table's registered token (REC-33), e.g. `party`, `crm_deal`. */
@@ -1189,6 +1381,8 @@ interface ViewSwitcherProps {
1189
1381
  onOpenRecord?: ((recordId: Uuid) => void) | undefined;
1190
1382
  /** The host's whole-record form, offered by the grid when an empty record is refused. */
1191
1383
  onNewRecordForm?: (() => void) | undefined;
1384
+ /** "Who changed this?" from a grid cell — the host opens that column's timeline. */
1385
+ onAskWhoChanged?: ((fieldKey: string, recordId: Uuid) => void) | undefined;
1192
1386
  pageSize?: number | undefined;
1193
1387
  className?: string | undefined;
1194
1388
  }
@@ -1200,7 +1394,7 @@ declare function useViewRecords(view: SavedViewSpec, pageSize?: number): {
1200
1394
  /** Where membership came from, in a sentence. A screen that hides this is hiding the view's meaning. */
1201
1395
  membership: string;
1202
1396
  };
1203
- declare function ViewSwitcher({ view, onLayoutChange, onViewChange, onOpenRecord, onNewRecordForm, pageSize, className, }: ViewSwitcherProps): react.JSX.Element;
1397
+ declare function ViewSwitcher({ view, onLayoutChange, onViewChange, onOpenRecord, onNewRecordForm, onAskWhoChanged, pageSize, className, }: ViewSwitcherProps): react.JSX.Element;
1204
1398
 
1205
1399
  interface ViewBarProps {
1206
1400
  /** The Table whose views these are. */
@@ -1290,20 +1484,39 @@ declare function ActionInbox({ tableId, includeSettled, onOpenRecord, className
1290
1484
  interface HistoryPanelProps {
1291
1485
  tableId: Uuid;
1292
1486
  recordId: Uuid;
1487
+ /**
1488
+ * "Who changed THIS column?" — the host opens that field's own timeline. Left
1489
+ * out, the per-field control is absent rather than dead.
1490
+ */
1491
+ onAskAboutField?: ((fieldKey: string) => void) | undefined;
1293
1492
  className?: string | undefined;
1294
1493
  }
1295
- declare function HistoryPanel({ tableId, recordId, className }: HistoryPanelProps): react.JSX.Element;
1494
+ declare function HistoryPanel({ tableId, recordId, onAskAboutField, className }: HistoryPanelProps): react.JSX.Element;
1296
1495
 
1297
- /** The package-owned Table every comment is a record of. */
1298
- declare const COMMENT_TABLE: SystemTableSpec;
1299
1496
  interface CommentThreadProps {
1300
- /** The Table the commented-on record belongs to — its rights decide the composer. */
1497
+ /** The Table the commented-on record belongs to — its Fields name an anchor. */
1301
1498
  tableId: Uuid;
1302
1499
  /** The record being discussed. */
1303
1500
  recordId: Uuid;
1501
+ /** Open on the thread about ONE column, and post there by default. */
1502
+ fieldKey?: string | undefined;
1503
+ className?: string | undefined;
1504
+ }
1505
+ declare function CommentThread({ tableId, recordId, fieldKey, className }: CommentThreadProps): react.JSX.Element;
1506
+
1507
+ interface FieldHistoryPanelProps {
1508
+ tableId: Uuid;
1509
+ /** The column being asked about, by its key. */
1510
+ fieldKey: string;
1511
+ /** Scoped to ONE record when present; the whole Table when absent. */
1512
+ recordId?: Uuid | undefined;
1513
+ /** The host's way back — a cell menu opens this, so it closes too. */
1514
+ onClose?: (() => void) | undefined;
1515
+ /** Open a record from one of its rows. Absent, the row is not a link. */
1516
+ onOpenRecord?: ((recordId: Uuid) => void) | undefined;
1304
1517
  className?: string | undefined;
1305
1518
  }
1306
- declare function CommentThread({ tableId, recordId, className }: CommentThreadProps): react.JSX.Element;
1519
+ declare function FieldHistoryPanel({ tableId, fieldKey, recordId, onClose, onOpenRecord, className, }: FieldHistoryPanelProps): react.JSX.Element;
1307
1520
 
1308
1521
  /** How a form is put in front of a person. */
1309
1522
  declare const FORM_FLOWS: readonly ["one-at-a-time", "single-page"];
@@ -1685,11 +1898,13 @@ declare function SignBlock({ tableId, recordId, render, className }: SignBlockPr
1685
1898
  interface NotifyRuleSpec {
1686
1899
  name: string;
1687
1900
  savedViewId: Uuid;
1688
- /** `immediate` fires on the change; `digest` is collected and sent on a schedule. */
1901
+ /** `instant` fires the moment a record enters the view; the rest are summaries. */
1689
1902
  cadence?: string;
1690
- /** The digest's schedule, in the store's own words. Meaningless for `immediate`. */
1903
+ /** The summary's schedule "monday 08:00". Meaningless for `instant`. */
1691
1904
  schedule?: string | null;
1692
1905
  channel?: string;
1906
+ /** The hours not to be told in. A send inside them is MOVED, never dropped. */
1907
+ quietHours?: QuietHours | null;
1693
1908
  /** Who is told. Left out, the person setting it up — "tell ME". */
1694
1909
  recipientUserId?: Uuid | null;
1695
1910
  eventKey?: string;
@@ -1824,7 +2039,18 @@ declare const CAPTURE_MODES: readonly ["reading", "photo", "voice"];
1824
2039
  type CaptureMode = (typeof CAPTURE_MODES)[number];
1825
2040
  declare const IN_MEMORY_QUEUE_REASON: string;
1826
2041
  interface CaptureSheetProps {
1827
- /** The Table a capture becomes a record in. */
2042
+ /**
2043
+ * A DECLARED capture sheet. Given one, this component runs THAT sheet — its
2044
+ * questions, in its order, with its required ones, one at a time, through
2045
+ * `custom.capture_open` and `custom.capture_submit`, with the durable queue. That is
2046
+ * the crew case (PRODUCTS row 15) and it is what twelve people doing the same round
2047
+ * need: somebody has SAID what the questions are.
2048
+ *
2049
+ * Without one this stays the ad-hoc capture below, which guesses which Field a
2050
+ * reading goes in — right for a quick one-off, wrong for a crew.
2051
+ */
2052
+ sheetId?: Uuid | undefined;
2053
+ /** The Table a capture becomes a record in. Not needed when `sheetId` is given. */
1828
2054
  tableId: Uuid;
1829
2055
  /** Which Field a reading's number goes in. Defaults to the first range Field. */
1830
2056
  readingField?: string | undefined;
@@ -1834,7 +2060,20 @@ interface CaptureSheetProps {
1834
2060
  attachmentField?: string | undefined;
1835
2061
  className?: string | undefined;
1836
2062
  }
1837
- declare function CaptureSheet({ tableId, readingField, noteField, attachmentField, className, }: CaptureSheetProps): react.JSX.Element;
2063
+ declare function CaptureSheet({ sheetId, tableId, readingField, noteField, attachmentField, className, }: CaptureSheetProps): react.JSX.Element;
2064
+
2065
+ interface CaptureRunProps {
2066
+ sheetId: Uuid$1;
2067
+ /**
2068
+ * The sheet, already loaded — by a server render, or from the phone's own copy. Given
2069
+ * one, this component makes NO network call before the first question is on screen.
2070
+ */
2071
+ face?: CaptureSheetFace | null | undefined;
2072
+ className?: string | undefined;
2073
+ }
2074
+ /** What control one question gets. `attachment` is why a phone opens its camera. */
2075
+ declare function controlFor(field: CaptureField | undefined): "photo" | "voice" | "number" | "text";
2076
+ declare function CaptureRun({ sheetId, face: given, className }: CaptureRunProps): react.JSX.Element;
1838
2077
 
1839
2078
  interface PortalShellProps {
1840
2079
  /** The Table the outsider's records belong to. */
@@ -2165,4 +2404,4 @@ declare function useCanShare(): boolean;
2165
2404
  declare function shareUnavailableReason(): string;
2166
2405
  declare function ShareControl({ kind, organizationId, subjectId, name, may, size, variant, className, }: ShareControlProps): ReactNode;
2167
2406
 
2168
- export { ACTION_KINDS, ActionInbox, type ActionInboxProps, type ActionKind, BookingSlots, type BookingSlotsProps, CAPTURE_MODES, CHART_KINDS, CHART_KIND_LABEL, CHART_NEEDS, CHECKLIST_TABLE, COMMENT_TABLE, type Capability, type CaptureMode, type CaptureQueuePort, CaptureSheet, type CaptureSheetProps, type CellAddress, type CellRefusal, type CellState, ChartBlock, type ChartBlockProps, type ChartConfig, ChartFrame, type ChartKind, ChartLegendContent, type ChartSpec, ChartTooltipContent, ChecklistRunner, type ChecklistRunnerProps, type ChecklistSpec, type ChecklistStepSpec, CommentThread, type CommentThreadProps, CustomFieldsSection, type CustomFieldsSectionProps, DEFAULT_FIELDS, DEFAULT_VIEW_NAME, DashboardCanvas, type DashboardCanvasProps, type DeclareResult, DocRender, type DocRenderProps, DocTemplate, type DocTemplateProps, type DocTemplateSpec, EMPTY_PRESENTATION, type EditorKind, EmbedFrame, type EmbedFrameProps, type EnrichAsk, type EnrichOutcome, EnrichPanel, type EnrichPanelProps, ExportMenu, type ExportMenuProps, FIELD_TYPE_CHOICES, FIELD_TYPE_GROUPS, FORM_FLOWS, FROZEN_COLUMN_WIDTH, FieldControl, FieldEditor, type FieldEditorControlProps, type FieldEditorProps, FieldLabel, type FieldProposalRow, type FieldTypeChoice, FormBuilder, type FormBuilderProps, type FormFlow, type FormQuestionSpec, FormRunner, type FormRunnerProps, type FormSpec, type FormSubmitOutcome, type FormTheme, FormsPanel, type FormsPanelProps, Grid, GridCell, type GridEditing, type GridPresentation, type GridProps, HistoryPanel, type HistoryPanelProps, IN_MEMORY_QUEUE_REASON, ImportWizard, type ImportWizardProps, KERNEL_REASON, LANE_EMPTY, LANE_TITLE, LAYOUT_FIELD_KIND, LAYOUT_LABEL, LAYOUT_NEEDS, LAYOUT_NO_FIELD, LEVEL_WORD, type LabelLookup, MACHINE_IDENTITY, NOT_ANSWERED_YET, NO_CHAT_REASON, NO_COLUMNS_WHY, NO_COLUMNS_YET, NO_ENRICH_REASON, NO_MEMBERS_REASON, NO_OPEN_RECORDS_REASON, NO_REASK_REASON, NO_RIGHTS, NO_SAVED_VIEWS_REASON, NO_SHARE_REASON, NO_UPLOAD_REASON, type NewFieldSpec, type NewTableSpec, NotifyRuleEditor, type NotifyRuleEditorProps, type NotifyRuleSpec, type OpenRecordsAsk, type OrganizationMember, PARITY_LABEL, PARITY_MADE_OF, Peek, type PeekProps, type PendingCapture, PersonPicker, type PersonPickerProps, type PickableFieldType, type PlainFieldType, type PlainRefusal, type PortalAnswer, PortalCardView, type PortalCardViewProps, PortalShell, type PortalShellProps, PortalsPanel, type PortalsPanelProps, type ProposalOutcome, ProposalRow, type ProposalRowProps, type ProposedChange, ProvenanceBadge, PublicViewPage, type PublicViewPageProps, type ReaskContext, RecordChat, type RecordChatContext, type RecordChatEntry, type RecordChatProps, type RecordChatWithheld, RecordChip, RecordForm, type RecordFormProps, RecordLabelProvider, RecordValue, RecordsMount, type RecordsMountProps, type RecordsUiHost, RecordsUiProvider, RefusalLine, RefusalNotice, RelationPicker, type RelationPickerProps, SERIES_COLORS, STORE_DECIDES_REASON, type SavedDashboard, type SavedForm, type SavedView, type SavedViewSpec, ShareControl, type ShareControlProps, type ShareSubject, SignBlock, type SignBlockProps, SubscriptionsPanel, type SubscriptionsPanelProps, type SystemFieldSpec, type SystemTableSpec, TABLE_LANES, TABLE_NOT_REACHABLE, type TableLane, TablePage, type TablePageProps, type TableRights, TableSettings, type TableSettingsProps, TablesHome, type TablesHomeProps, type TrackedVersion, type UseSystemTableState, VIEW_LAYOUTS, VIEW_NOT_SAVED_YET, VIEW_TABLE, ViewBar, type ViewBarProps, type ViewLayout, type ViewSort, ViewSwitcher, type ViewSwitcherProps, type WhatYouMayDo, addFields, blockFromSpec, bodyForReading, bodyFromKeys, colorFromTheValue, columnForField, currencyCodeFor, dashboardDeclareArgs, dashboardFromSummary, declareTable, editorKindFor, ensureSystemTable, envelopeFor, fieldDeclarationFor, fieldIsEditable, fieldName, fieldToken, fieldTypeChoice, fieldTypeLabel, formDeclareArgs, formFromSummary, formPresentation, formatForField, groupLabel, hintForAPerson, hintIsMachineIdentity, humanize, idsOf, isId, isMachineIdentity, isPlainFieldType, isSignatureField, keyFor, laneFor, machineIdentityIn, memberName, parityTypesWithNoExplanation, parseGridPresentation, personActor, personRecordForMember, pointsAtRecords, presentationDocument, presentationIsEmpty, previewLine, recordName, recordsDataSource, refusalForAPerson, refusalLineForAPerson, renderValue, revokeConsequence, rowName, scalarText, shareUnavailableReason, specFromBlock, storeDecidesRights, submissionStamp, tableName, tableRightsAt, tokenFor, useCanShare, useEmbedHandshake, useGridEditing, useMeasuredWidth, useRecordLabels, useRecordRights, useRecordsUi, useRowRights, useSystemTable, useTableRights, useViewRecords, viewDocument, viewFromRecord, viewPatchDocument, whatIsMissing, whatYouMayDo, whatYouMayDoWithTable };
2407
+ export { ACTION_KINDS, ActionInbox, type ActionInboxProps, type ActionKind, BookingSlots, type BookingSlotsProps, CAPTURE_MODES, CHART_KINDS, CHART_KIND_LABEL, CHART_NEEDS, CHECKLIST_TABLE, type Capability, type CaptureMode, type CaptureQueuePort, CaptureRun, type CaptureRunProps, CaptureSheet, type CaptureSheetProps, type CellAddress, type CellRefusal, type CellState, ChartBlock, type ChartBlockProps, type ChartConfig, ChartFrame, type ChartKind, ChartLegendContent, type ChartSpec, ChartTooltipContent, ChecklistRunner, type ChecklistRunnerProps, type ChecklistSpec, type ChecklistStepSpec, CommentThread, type CommentThreadProps, CustomFieldsSection, type CustomFieldsSectionProps, DEFAULT_FIELDS, DEFAULT_VIEW_NAME, DashboardCanvas, type DashboardCanvasProps, type DeclareResult, DocRender, type DocRenderProps, DocTemplate, type DocTemplateProps, type DocTemplateSpec, EMPTY_PRESENTATION, type EditorKind, EmbedFrame, type EmbedFrameProps, type EnrichAsk, EnrichBadge, type EnrichBadgeProps, type EnrichOutcome, EnrichPanel, type EnrichPanelProps, ExportMenu, type ExportMenuProps, FIELD_TYPE_CHOICES, FIELD_TYPE_GROUPS, FORM_FLOWS, FROZEN_COLUMN_WIDTH, FieldControl, FieldEditor, type FieldEditorControlProps, type FieldEditorProps, FieldHistoryPanel, type FieldHistoryPanelProps, FieldLabel, type FieldProposalRow, type FieldTypeChoice, FormBuilder, type FormBuilderProps, type FormFlow, type FormQuestionSpec, FormRunner, type FormRunnerProps, type FormSpec, type FormSubmitOutcome, type FormTheme, FormsPanel, type FormsPanelProps, Grid, GridCell, type GridEditing, type GridGrouping, type GridPresentation, type GridProps, HistoryPanel, type HistoryPanelProps, IN_MEMORY_QUEUE_REASON, ImportWizard, type ImportWizardProps, KERNEL_REASON, LANE_EMPTY, LANE_TITLE, LAYOUT_FIELD_KIND, LAYOUT_LABEL, LAYOUT_NEEDS, LAYOUT_NO_FIELD, LEVEL_WORD, type LabelLookup, MACHINE_IDENTITY, MAX_ROW_HEIGHT, MIN_ROW_HEIGHT, NOT_ANSWERED_YET, NO_CHAT_REASON, NO_COLUMNS_WHY, NO_COLUMNS_YET, NO_ENRICH_REASON, NO_MEMBERS_REASON, NO_OPEN_RECORDS_REASON, NO_REASK_REASON, NO_RIGHTS, NO_SAVED_VIEWS_REASON, NO_SHARE_REASON, NO_UPLOAD_REASON, type NewFieldSpec, type NewTableSpec, NotifyRuleEditor, type NotifyRuleEditorProps, type NotifyRuleSpec, type OpenRecordsAsk, type OrganizationMember, PARITY_LABEL, PARITY_MADE_OF, Peek, type PeekProps, type PendingCapture, PersonPicker, type PersonPickerProps, type PickableFieldType, type PlainFieldType, type PlainRefusal, type PortalAnswer, PortalCardView, type PortalCardViewProps, PortalShell, type PortalShellProps, PortalsPanel, type PortalsPanelProps, type ProposalOutcome, ProposalRow, type ProposalRowProps, type ProposedChange, ProvenanceBadge, PublicViewPage, type PublicViewPageProps, type ReaskContext, RecordChat, type RecordChatContext, type RecordChatEntry, type RecordChatProps, type RecordChatWithheld, RecordChip, RecordForm, type RecordFormProps, RecordLabelProvider, RecordValue, RecordsMount, type RecordsMountProps, type RecordsUiHost, RecordsUiProvider, RefusalLine, RefusalNotice, RelationPicker, type RelationPickerProps, SERIES_COLORS, STORE_DECIDES_REASON, type SavedDashboard, type SavedForm, type SavedView, type SavedViewSpec, ShareControl, type ShareControlProps, type ShareSubject, SignBlock, type SignBlockProps, SubscriptionsPanel, type SubscriptionsPanelProps, type SystemFieldSpec, type SystemTableSpec, TABLE_LANES, TABLE_NOT_REACHABLE, type TableLane, TablePage, type TablePageProps, type TableRights, TableSettings, type TableSettingsProps, TablesHome, type TablesHomeProps, type TrackedVersion, type UseSystemTableState, VIEW_LAYOUTS, VIEW_NOT_SAVED_YET, VIEW_TABLE, ViewBar, type ViewBarProps, type ViewLayout, type ViewSort, ViewSwitcher, type ViewSwitcherProps, type WhatYouMayDo, addFields, blockFromSpec, bodyForReading, bodyFromKeys, cellState, colorFromTheValue, columnForField, controlFor, currencyCodeFor, dashboardDeclareArgs, dashboardFromSummary, declareTable, editorKindFor, ensureSystemTable, envelopeFor, fieldDeclarationFor, fieldIsEditable, fieldName, fieldToken, fieldTypeChoice, fieldTypeLabel, formDeclareArgs, formFromSummary, formPresentation, formatForField, groupLabel, hintForAPerson, hintIsMachineIdentity, humanize, idsOf, isId, isMachineIdentity, isPlainFieldType, isSignatureField, keyFor, laneFor, machineIdentityIn, memberName, parityTypesWithNoExplanation, parseGridPresentation, personActor, personRecordForMember, pointsAtRecords, presentationDocument, presentationIsEmpty, previewLine, recordName, recordsDataSource, refusalForAPerson, refusalLineForAPerson, renderValue, revokeConsequence, rowName, scalarText, shareUnavailableReason, specFromBlock, storeDecidesRights, submissionStamp, tableName, tableRightsAt, tokenFor, useCanShare, useEmbedHandshake, useEnrichCells, useGridEditing, useMeasuredWidth, useRecordLabels, useRecordRights, useRecordsUi, useRowRights, useSystemTable, useTableRights, useViewRecords, viewDocument, viewFromRecord, viewPatchDocument, whatIsMissing, whatYouMayDo, whatYouMayDoWithTable };