@ai-matrx/records-ui 0.16.1 → 0.30.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.cts CHANGED
@@ -1,9 +1,11 @@
1
1
  import * as react from 'react';
2
- import { ReactNode } from 'react';
3
- import { PermissionLevel, Table, Uuid as Uuid$1, RecordsError, Field, RecordDocument, ReadRow, WriteConflict, ParityFieldType, NewFieldDeclaration, ValueEnvelope, WorkInboxKind, RuleExpression, AggregateBucket, AggregateMeasure, DocTemplateRow, DocRenderRow, AnonTokenBinding, RecordsConfig, RecordsActor, RecordsDataSource } from '@ai-matrx/records';
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';
4
4
  import { Uuid, Field as Field$1, ReadRow as ReadRow$1 } from '@ai-matrx/records/react';
5
5
  import { RecordsClient } from '@ai-matrx/records/core';
6
+ import { FieldFormatConfig } from '@ai-matrx/design-system/field-formats';
6
7
  import { MatrxColumnDef } from '@ai-matrx/design-system/data-table/types';
8
+ import { TableStyle, GroupAggregateSpec, GroupOrder, ChoiceColorLookup } from '@ai-matrx/design-system/data-table';
7
9
 
8
10
  /** The six things a person does to a record or a table, as the screens offer them. */
9
11
  type Capability = "read" | "comment" | "write" | "remove" | "share" | "structure";
@@ -269,6 +271,54 @@ interface RecordsUiHost {
269
271
  * Never a Share button that opens nothing.
270
272
  */
271
273
  share?: (subject: ShareSubject) => ReactNode;
274
+ /**
275
+ * OPTIONAL. OPEN THE RECORDS BEHIND A NUMBER (SCR-16).
276
+ *
277
+ * Every number on a dashboard is a count of real records, and the whole
278
+ * product row is that a person can get from the number to them: click the
279
+ * "Awaiting parts" column and the grid opens on the twenty-eight jobs it
280
+ * counted, with the block's own filter still on. That is one navigation, and
281
+ * WHERE the grid lives is the host's routing — so it is a port, like
282
+ * `hrefForRecord`, rather than a route string this package invents.
283
+ *
284
+ * Unbound, the marks are NOT clickable and the canvas says so in one
285
+ * sentence naming this port. A chart whose bars looked pressable and did
286
+ * nothing is the dead control this package does not ship.
287
+ */
288
+ openRecords?: (ask: OpenRecordsAsk) => void;
289
+ /**
290
+ * OPTIONAL. ASK THE AGENT TO CHANGE THIS DASHBOARD (SCR-16).
291
+ *
292
+ * "break it down by owner" is how a dashboard is actually built — the agent
293
+ * calls `dashboard_propose` on the server's `records` tool with this
294
+ * dashboard's id and re-states it. Only the server can do that honestly (a
295
+ * browser stamping itself `agent` is a browser claiming to be one), which is
296
+ * the same reason `enrich` is a port, so this is one too.
297
+ *
298
+ * Unbound, the box is drawn DISABLED with one sentence naming this port —
299
+ * never a composer that goes nowhere and never silence.
300
+ */
301
+ onReask?: (question: string, context: ReaskContext) => Promise<void>;
302
+ }
303
+ /**
304
+ * WHAT A CLICK ON A NUMBER ASKS FOR. The filter is already merged: the block's
305
+ * own filter (which `custom.dashboard_run` echoes back with the canvas bar
306
+ * folded under it) with the clicked group's key and value over the top. A host
307
+ * that dropped a key would open the grid on more records than the number
308
+ * counted, which is the one way this control can lie.
309
+ */
310
+ interface OpenRecordsAsk {
311
+ tableId: Uuid$1;
312
+ filter: Record<string, AggregateFilter>;
313
+ /** What the person clicked, in words: "Jobs by stage this month · Awaiting parts". */
314
+ label: string;
315
+ }
316
+ /** Which dashboard a re-ask is about, so the agent re-states it rather than making a second one. */
317
+ interface ReaskContext {
318
+ tableId: Uuid$1;
319
+ /** Null while the canvas has no dashboard yet — the answer is the first one. */
320
+ dashboardId: Uuid$1 | null;
321
+ dashboardName: string | null;
272
322
  }
273
323
  /**
274
324
  * What a host's share dialog is being opened ON. A Table is a record in this
@@ -322,6 +372,10 @@ declare const NO_SAVED_VIEWS_REASON: string;
322
372
  declare const NO_MEMBERS_REASON: string;
323
373
  /** The sentence shown when no share dialog is bound. */
324
374
  declare const NO_SHARE_REASON: string;
375
+ /** The sentence a canvas shows when nothing is bound to open the records behind a number. */
376
+ declare const NO_OPEN_RECORDS_REASON: string;
377
+ /** The sentence the re-ask box shows when no agent is bound. */
378
+ declare const NO_REASK_REASON: string;
325
379
  /** The sentence an attachment question shows when no file store is bound. */
326
380
  declare const NO_UPLOAD_REASON: string;
327
381
  declare function RecordsUiProvider({ value, children }: {
@@ -538,7 +592,7 @@ declare function useGridEditing({ tableId, fields, rows, reload, canWrite, mayWr
538
592
  * `data-matrx-cell-control` is the data table's own opt-out from whole-row
539
593
  * click, so opening a cell never also opens the record panel behind it.
540
594
  */
541
- declare function GridCell({ field, row, editing, canWrite, whyNot, }: {
595
+ declare function GridCell({ field, row, editing, canWrite, whyNot, format, }: {
542
596
  field: Field;
543
597
  row: ReadRow;
544
598
  editing: GridEditing;
@@ -550,6 +604,8 @@ declare function GridCell({ field, row, editing, canWrite, whyNot, }: {
550
604
  * is the silent half of the same defect this file closes.
551
605
  */
552
606
  whyNot?: string | undefined;
607
+ /** The column's declared format, so the read view reads like its header. */
608
+ format?: FieldFormatConfig | undefined;
553
609
  }): react.JSX.Element;
554
610
 
555
611
  /**
@@ -570,6 +626,134 @@ declare function RefusalLine({ error, className }: {
570
626
  className?: string | undefined;
571
627
  }): react.JSX.Element;
572
628
 
629
+ /**
630
+ * HOW A TABLE LOOKS — colors, formats and the frozen column.
631
+ *
632
+ * THE SPLIT, AND WHY IT IS THIS ONE. A Field declares WHAT it holds: a
633
+ * currency, a percent, a date, a person. A VIEW declares HOW that reads and
634
+ * what it is worth looking at: two decimal places or none, tint the row when
635
+ * Status is Blocked, keep Name in place while the rest scrolls. Airtable draws
636
+ * the line in exactly this place, and it has to be here: two people read one
637
+ * table two different ways, and neither reading is a fact about the records.
638
+ *
639
+ * So nothing in this module is a new column on a Field and nothing here needed
640
+ * a migration. A presentation lives on the saved-view record (`views.ts`), which
641
+ * is an ordinary record of an ordinary Table — which means an agent sets it
642
+ * through the same `records` tool it uses for everything else, and it travels
643
+ * with the table the way every other record does.
644
+ *
645
+ * A FIELD STILL GETS ITS MONEY RIGHT WITH NO CONFIGURATION. `formatForField`
646
+ * reads the Field's OWN declaration — a `currency` parity type with unit `$`, a
647
+ * `percent`, a `datetime` with `config.kind` — and returns the format that
648
+ * follows from it. The view's `formats` map only OVERRIDES that. A table nobody
649
+ * has ever styled still shows `$1,250.50` and `45%`.
650
+ */
651
+
652
+ /**
653
+ * SECTIONS BY A FIELD — the view's own grouping.
654
+ *
655
+ * `field` is a Field KEY, exactly like `frozen` and the keys of `formats`,
656
+ * because a view is written against the Table's declaration and never against
657
+ * whatever id a screen happened to build its columns with.
658
+ *
659
+ * `aggregates` is keyed by Field key too, and `collapsed` holds the data
660
+ * table's own group keys (`s:Blocked`, `n:3`, `empty`), which is what the
661
+ * primitive emits and the only thing that survives a value rendering the same
662
+ * text as another.
663
+ *
664
+ * NOTHING HERE IS EVER CALLED `valueOf`, `toString` or `hasOwnProperty`: every
665
+ * object in JavaScript already has all three, so an optional field by one of
666
+ * those names is NEVER absent and a `config.valueOf ? … : …` check silently
667
+ * reads `Object.prototype`. It cost the primitive a whole grouping once.
668
+ */
669
+ type GridGrouping = {
670
+ /** The Field key whose value makes the sections. */
671
+ field: string;
672
+ /** Per-Field-key subtotal on every section header. */
673
+ aggregates?: Record<string, GroupAggregateSpec>;
674
+ /** Section order. The primitive's default is `value-asc`; blanks sort last. */
675
+ order?: GroupOrder;
676
+ /** The sections this view keeps shut, by the primitive's own group key. */
677
+ collapsed?: string[];
678
+ };
679
+ /** Everything a view says about how its table LOOKS. */
680
+ type GridPresentation = {
681
+ /** Color-by-a-column, rules and manual highlights. */
682
+ style?: TableStyle;
683
+ /** Per-column format overrides, by the Field's key. */
684
+ formats?: Record<string, FieldFormatConfig>;
685
+ /**
686
+ * The columns that stay in place while the table scrolls sideways, by Field
687
+ * key. Only the LEADING run of the view's column order can actually freeze —
688
+ * the data table decides that, and declines rather than pinning a column at a
689
+ * guessed offset.
690
+ */
691
+ frozen?: string[];
692
+ /** Collapsible sections by one Field, with subtotals on each header. */
693
+ grouping?: GridGrouping;
694
+ /**
695
+ * The width a person dragged a column to, by Field key. SPARSE on purpose —
696
+ * a view saved before widths existed carries none and still parses, and a
697
+ * column nobody resized is left to the table's own measurement.
698
+ */
699
+ widths?: Record<string, number>;
700
+ /** The body row height this view remembers, in px. */
701
+ rowHeight?: number;
702
+ };
703
+ declare const EMPTY_PRESENTATION: GridPresentation;
704
+ /** A frozen column needs a known width, or the table declines to freeze at all. */
705
+ declare const FROZEN_COLUMN_WIDTH = 200;
706
+ /**
707
+ * WHAT A ROW HEIGHT IS ALLOWED TO BE. Below the floor the text is clipped and
708
+ * no editor fits; above the ceiling one record fills the screen. A view asking
709
+ * for anything outside it is DROPPED rather than obeyed, because a saved look
710
+ * must not be able to make a table unreadable — and the Fields' own heights
711
+ * still draw, which is the tolerant half.
712
+ */
713
+ declare const MIN_ROW_HEIGHT = 24;
714
+ declare const MAX_ROW_HEIGHT = 96;
715
+ /**
716
+ * Read a presentation out of whatever the view record holds — an object, or the
717
+ * JSON string a text field stores.
718
+ *
719
+ * Tolerant in exactly the way `parseTableStyle` is: an unreadable half is
720
+ * dropped and the rest still applies, because a table must keep drawing when
721
+ * one piece of its styling goes out of date.
722
+ */
723
+ declare function parseGridPresentation(raw: unknown): GridPresentation;
724
+ /** True when nothing here would change how anything looks. */
725
+ declare function presentationIsEmpty(p: GridPresentation): boolean;
726
+ /** The string a view record stores. Empty string for "this view styles nothing". */
727
+ declare function presentationDocument(p: GridPresentation): string;
728
+ /**
729
+ * The format a Field's OWN declaration implies, before any view says anything.
730
+ *
731
+ * Returns `undefined` for a Field whose value the record renderer already draws
732
+ * better than a formatter could — a relation chip, a person, an attachment, a
733
+ * choice — because handing those to a text formatter would REPLACE a working
734
+ * control with a string.
735
+ */
736
+ declare function formatForField(field: Field): FieldFormatConfig | undefined;
737
+ declare function currencyCodeFor(unit: string | null | undefined): string;
738
+ /**
739
+ * The color a value paints with when a view colors BY a column.
740
+ *
741
+ * NOTHING FAILS SILENTLY, so this never returns "no color" for a value that
742
+ * exists. The store keeps a list column's choices as records of another Table,
743
+ * and this grid has not read that Table's option colors, so the color is
744
+ * derived from the value's own text: the same word always gets the same color,
745
+ * different words get different ones, and `true` is green the way every
746
+ * checklist reads. When those option colors do land, this is the ONE function
747
+ * that changes and every screen follows.
748
+ */
749
+ declare const colorFromTheValue: ChoiceColorLookup;
750
+
751
+ /**
752
+ * WHAT A TABLE WITH NO COLUMNS SAYS. Named here because the gate asserts on it:
753
+ * the state it describes is what a first-time person met for two days.
754
+ */
755
+ declare const NO_COLUMNS_YET = "This table has no columns yet";
756
+ declare const NO_COLUMNS_WHY: string;
573
757
  interface GridProps {
574
758
  tableId: Uuid;
575
759
  /** Rows per page. The table's own pagination handles the rest. */
@@ -588,15 +772,46 @@ interface GridProps {
588
772
  toolbarActions?: ReactNode | undefined;
589
773
  /** Editing in place is on by default; a read-only surface (a portal) turns it off. */
590
774
  editable?: boolean | undefined;
775
+ /**
776
+ * HOW THIS TABLE LOOKS — the active saved view's colors, per-column formats
777
+ * and frozen columns (`presentation.ts`).
778
+ *
779
+ * It is a prop and not a read of its own because the VIEW owns it and the
780
+ * host already knows which view is open; a second read here would draw one
781
+ * view's colors over another's. Omitted, the table still formats every money
782
+ * and date column correctly from the Fields' own declarations — a look is an
783
+ * override, never the only thing that makes a column readable.
784
+ */
785
+ presentation?: GridPresentation | undefined;
786
+ /**
787
+ * THE LOOK, WRITTEN BACK. Called with the WHOLE next look when the person
788
+ * changes one on the table itself — picks a column to group by, shuts a
789
+ * section, drags a column wider.
790
+ *
791
+ * It is the same door every other view change already uses: `ViewSwitcher`
792
+ * folds it into its `onViewChange` patch and `TablePage` writes that patch
793
+ * onto the view record with `client.recordUpdate`, carrying the version it
794
+ * read. The Grid has no view id and must not grow one — a component that
795
+ * wrote to a record it was never told about would be a second, parallel way
796
+ * to save a view.
797
+ *
798
+ * UNBOUND, NOTHING IS DEAD. A host that binds no door still gets grouping,
799
+ * collapsing and resizing for this visit — they are held in the grid's own
800
+ * state — they are simply not remembered.
801
+ */
802
+ onPresentationChange?: ((next: GridPresentation) => void) | undefined;
591
803
  className?: string | undefined;
592
804
  }
593
- declare function Grid({ tableId, pageSize, onOpenRecord, onAddField, onNewRecordForm, toolbarActions, editable, className, }: GridProps): react.JSX.Element;
805
+ declare function Grid({ tableId, pageSize, onOpenRecord, onAddField, onNewRecordForm, toolbarActions, editable, presentation, onPresentationChange, className, }: GridProps): react.JSX.Element;
594
806
  /**
595
807
  * One Field becomes one column. The header is the Field's own NAME — never its
596
808
  * key (`names.ts`) — and the cell is the value, rendered by its parity type and
597
809
  * editable in place when an editing session is passed.
598
810
  */
599
- declare function columnForField(field: Field$1, editing?: GridEditing | null, mayWriteRow?: (rowId: Uuid) => boolean, whyNotRow?: (rowId: Uuid) => string): MatrxColumnDef<ReadRow$1>;
811
+ declare function columnForField(field: Field$1, editing?: GridEditing | null, mayWriteRow?: (rowId: Uuid) => boolean, whyNotRow?: (rowId: Uuid) => string, look?: {
812
+ format?: FieldFormatConfig;
813
+ frozen?: boolean;
814
+ }): MatrxColumnDef<ReadRow$1>;
600
815
 
601
816
  interface ExportMenuProps {
602
817
  tableId: Uuid;
@@ -820,10 +1035,23 @@ declare function ProvenanceBadge({ document, fieldKey }: {
820
1035
  * export, a chat line) keeps calling `renderValue` with no resolver and says
821
1036
  * "Loading…" rather than printing an id.
822
1037
  */
823
- declare function RecordValue({ field, value, document, }: {
1038
+ declare function RecordValue({ field, value, document, format, }: {
824
1039
  field: Field;
825
1040
  value: unknown;
826
1041
  document?: RecordDocument | undefined;
1042
+ /**
1043
+ * The column's DECLARED format (`presentation.ts`), when it has one.
1044
+ *
1045
+ * A cell renderer beats `MatrxColumnDef.format` — the table hands the cell to
1046
+ * the consumer and steps back — so a store column that declared `currency`
1047
+ * and then drew itself here would have shown a raw `1250.5` while its own
1048
+ * header was right-aligned for money. The primitive's formatter is asked for
1049
+ * the text instead of a second one being written beside it, so the read view
1050
+ * and the table can never disagree about what a number means. THE FALLBACK
1051
+ * LAW rides along: a value that does not fit is amber with the reason, never
1052
+ * blank.
1053
+ */
1054
+ format?: FieldFormatConfig | undefined;
827
1055
  }): react.JSX.Element;
828
1056
 
829
1057
  declare const PARITY_LABEL: Record<ParityFieldType, string>;
@@ -855,6 +1083,16 @@ interface SystemFieldSpec {
855
1083
  required?: boolean;
856
1084
  multi?: boolean;
857
1085
  config?: Record<string, unknown>;
1086
+ /**
1087
+ * WHAT THE BEHAVIOUR ALONE CANNOT SAY, and what the declaring door refuses a
1088
+ * column without. A `list` has to name its choices (FLD-5/FLD-6) and a
1089
+ * `relation` has to name the Table it points at (FLD-11) — a package table
1090
+ * that grew one of those without saying so here would be refused by name on
1091
+ * every organization's first load, which is the class this file just cost us.
1092
+ */
1093
+ options?: string[];
1094
+ relationTarget?: Uuid$1;
1095
+ expr?: Record<string, unknown>;
858
1096
  }
859
1097
  interface SystemTableSpec {
860
1098
  /** The token this Table is addressed by. Every package table starts `records_ui_`. */
@@ -943,6 +1181,16 @@ interface SavedViewSpec {
943
1181
  */
944
1182
  ruleId?: Uuid$1 | null;
945
1183
  isDefault?: boolean;
1184
+ /**
1185
+ * HOW THIS VIEW LOOKS — its colors, its per-column formats and its frozen
1186
+ * column (`presentation.ts`).
1187
+ *
1188
+ * It lives on the VIEW and not on the Fields because two people read one
1189
+ * table two ways and neither reading is a fact about the records; it lives on
1190
+ * a RECORD, not a new column, because that is what makes it something an
1191
+ * agent writes with the same `records` tool as everything else.
1192
+ */
1193
+ presentation?: GridPresentation;
946
1194
  }
947
1195
  /** A saved view as it comes back out of the store, with its record's own id. */
948
1196
  interface SavedView extends SavedViewSpec {
@@ -1169,23 +1417,52 @@ interface FormSpec {
1169
1417
  */
1170
1418
  isPublic?: boolean;
1171
1419
  }
1172
- /** A form as it comes back out of the store, with its record's own id and version. */
1420
+ /**
1421
+ * A form as `custom.forms` reports it — the spec a screen renders, plus the
1422
+ * things only the STORE knows about it.
1423
+ *
1424
+ * The four store-side ids are carried on purpose. `custom.form_declare` is a
1425
+ * RE-STATEMENT of the whole form, so a save that left `notifyRuleId` out would
1426
+ * set it to null and the owner would quietly stop being told when somebody
1427
+ * answers — the exact silent failure the notify Rule exists to prevent. They are
1428
+ * read here and handed straight back by `formDeclareArgs`.
1429
+ */
1173
1430
  interface SavedForm extends FormSpec {
1174
1431
  id: Uuid$1;
1175
- /**
1176
- * The record's version AT LOAD, read from `custom.io_revisions` for the one
1177
- * record being edited. The read door answers documents and not versions, so
1178
- * this is null until it has been read — and a save with a null version is an
1179
- * ordinary last-writer-wins write, exactly as the store defines it.
1180
- */
1181
- version: number | null;
1432
+ /** draft · open · closed · full — the store's own word, never derived on a screen. */
1433
+ state: FormSummary["state"];
1434
+ /** The form's readable name in the store. `form_declare` keeps it across saves. */
1435
+ slug: string;
1436
+ /** Stops taking answers at this many. Null is no ceiling. */
1437
+ submissionCap: number | null;
1438
+ /** The accept Rule: what counts as a complete answer. Null holds every answer for a person. */
1439
+ quarantineRuleId: Uuid$1 | null;
1440
+ /** The subscription Rule that tells somebody an answer arrived. */
1441
+ notifyRuleId: Uuid$1 | null;
1182
1442
  }
1183
- /** The package-owned Table every form is a record of. */
1184
- declare const FORM_TABLE: SystemTableSpec;
1185
- /** The spec as the one document the store holds. */
1186
- declare function formDocument(spec: FormSpec): Record<string, unknown>;
1187
- /** One stored record back into the spec a screen and an agent both read. */
1188
- declare function formFromRecord(row: ReadRow): SavedForm;
1443
+ /**
1444
+ * The spec as `custom.anon_form.presentation` holds it.
1445
+ *
1446
+ * `questions` is deliberately NOT here: the door writes it itself from the
1447
+ * argument it validated (`presentation || {"questions": p_questions}`), so the
1448
+ * words a form is asked in and the keys it is allowed to accept can never be two
1449
+ * different lists.
1450
+ */
1451
+ declare function formPresentation(spec: FormSpec): Record<string, unknown>;
1452
+ /** The exact arguments `custom.form_declare` is called with, for a new form or a re-statement. */
1453
+ declare function formDeclareArgs(form: FormSpec | SavedForm): {
1454
+ table_id: Uuid$1;
1455
+ title: string;
1456
+ questions: FormQuestionSpec[];
1457
+ presentation: Record<string, unknown>;
1458
+ submission_cap: number | null;
1459
+ quarantine_rule_id: Uuid$1 | null;
1460
+ notify_rule_id: Uuid$1 | null;
1461
+ form_id: Uuid$1 | null;
1462
+ slug: string | null;
1463
+ };
1464
+ /** One row of `custom.forms` back into the spec a screen and an agent both read. */
1465
+ declare function formFromSummary(summary: FormSummary): SavedForm;
1189
1466
  /**
1190
1467
  * THE SOURCE STAMP every submission carries. A record that arrived through a
1191
1468
  * form is not indistinguishable from one somebody typed into the grid: it says
@@ -1200,6 +1477,65 @@ declare function submissionStamp(args: {
1200
1477
  onBehalfOf?: string | null;
1201
1478
  }): Record<string, unknown>;
1202
1479
 
1480
+ interface PortalsPanelProps {
1481
+ /**
1482
+ * OPTIONAL. The Table whose page this rail is on. It is used for ONE thing:
1483
+ * saying, on an opened portal, whether this table is among the ones that
1484
+ * portal shows. It never filters the list — a portal belongs to the
1485
+ * organization, and hiding the others would answer a question nobody asked.
1486
+ */
1487
+ tableId?: Uuid | undefined;
1488
+ className?: string | undefined;
1489
+ }
1490
+ /** What a door answered, for a view that never holds a client of its own. */
1491
+ type PortalAnswer<T> = {
1492
+ ok: true;
1493
+ data: T;
1494
+ } | {
1495
+ ok: false;
1496
+ error: RecordsError;
1497
+ };
1498
+ /**
1499
+ * THE SENTENCE SAID BEFORE A REVOKE, and it is deliberately not generic.
1500
+ *
1501
+ * "Are you sure?" tells somebody nothing they did not already know. What they
1502
+ * need is the two things that actually change: this person stops being able to
1503
+ * sign in at all, and the records that named their client stop reaching them.
1504
+ * The store says the same thing back in the past tense once it is done
1505
+ * (`custom.portal_revoke`'s own `say`), and that sentence is shown too.
1506
+ */
1507
+ declare function revokeConsequence(person: PortalPrincipal, portalTitle: string): string;
1508
+ /**
1509
+ * THE LINE ABOVE A PREVIEW, and why it is not decoration.
1510
+ *
1511
+ * A preview a screen assembled for itself would be a second implementation of
1512
+ * visibility, and the first time the two disagreed nobody would know which one
1513
+ * was lying. This one is the store's own answer to the store's own question, so
1514
+ * the screen can say whose eyes these are and be right.
1515
+ */
1516
+ declare function previewLine(person: PortalPrincipal): string;
1517
+ declare function PortalsPanel({ tableId, className }: PortalsPanelProps): react.JSX.Element;
1518
+ interface PortalCardViewProps {
1519
+ /** Exactly what `custom.portal_card` answered. */
1520
+ card: PortalCard;
1521
+ /** The Table whose page this is on, if any — marked among the ones shown. */
1522
+ tableId?: Uuid | undefined;
1523
+ /** Take one person's way in away. Answers the door's own past-tense sentence. */
1524
+ onRevoke: (person: PortalPrincipal) => Promise<PortalAnswer<string>>;
1525
+ /** What this person sees on one Table — `custom.portal_preview`'s answer. */
1526
+ onPreview: (person: PortalPrincipal, tableId: Uuid) => Promise<PortalAnswer<PortalPreviewRow[]>>;
1527
+ /** The invite control, which needs a client of its own. Absent means none is offered. */
1528
+ invite?: ReactNode;
1529
+ className?: string | undefined;
1530
+ }
1531
+ declare function PortalCardView({ card, tableId, onRevoke, onPreview, invite, className, }: PortalCardViewProps): react.JSX.Element;
1532
+
1533
+ interface SubscriptionsPanelProps {
1534
+ tableId: Uuid;
1535
+ className?: string | undefined;
1536
+ }
1537
+ declare function SubscriptionsPanel({ tableId, className }: SubscriptionsPanelProps): react.JSX.Element;
1538
+
1203
1539
  interface FormBuilderProps {
1204
1540
  /** The Table this form collects into. A form is a view on a real Table. */
1205
1541
  tableId: Uuid;
@@ -1216,13 +1552,23 @@ interface FormBuilderProps {
1216
1552
  }
1217
1553
  declare function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }: FormBuilderProps): react.JSX.Element;
1218
1554
 
1219
- /** The shapes a block can take. Closed: a shape nobody drew is not offered. */
1220
- declare const CHART_KINDS: readonly ["bar", "column", "line", "donut", "number", "table"];
1221
- type ChartKind = (typeof CHART_KINDS)[number];
1555
+ /**
1556
+ * The shapes a block can take. There is exactly ONE closed set and it is the
1557
+ * store's — `custom.dashboard_kinds()` answers it and `@ai-matrx/records`
1558
+ * carries it. A second copy here would be a list that can disagree with the
1559
+ * door, which is how a screen comes to offer a shape the store refuses.
1560
+ */
1561
+ type ChartKind = DashboardBlockKind;
1222
1562
  declare const CHART_KIND_LABEL: Record<ChartKind, string>;
1563
+ /**
1564
+ * The shapes in the order a person reads them, derived from the labels above —
1565
+ * which TypeScript keys exhaustively by the store's own type, so this list can
1566
+ * never drift from the closed set.
1567
+ */
1568
+ declare const CHART_KINDS: ChartKind[];
1223
1569
  /** What each shape needs before it can draw, in one sentence a block prints. */
1224
1570
  declare const CHART_NEEDS: Record<ChartKind, string | null>;
1225
- /** ONE BLOCK: the question and the shape, in one declarative object. */
1571
+ /** ONE BLOCK, in the words a screen edits. */
1226
1572
  interface ChartSpec {
1227
1573
  title: string;
1228
1574
  /** The Table this block asks about. */
@@ -1237,33 +1583,50 @@ interface ChartSpec {
1237
1583
  } | null;
1238
1584
  /** `count` needs no key; every other measure reads one Field. */
1239
1585
  measures?: AggregateMeasure[];
1240
- /** Equality only, and the store puts it in the SAME WHERE as visibility. */
1241
- filter?: Record<string, string>;
1586
+ /** A scalar is an equality; an object is a half-open moment window. */
1587
+ filter?: Record<string, AggregateFilter>;
1242
1588
  limit?: number;
1243
1589
  /** How wide this block sits on the canvas, in twelfths. */
1244
1590
  span?: number;
1591
+ /** `stuck` only: the Field whose value is watched for a change. */
1592
+ stateKey?: string;
1593
+ /** `stuck` only: how long a record may sit on the same value. */
1594
+ days?: number;
1245
1595
  }
1246
- /** THE WHOLE DASHBOARD, as one object an agent writes in one call. */
1247
- interface DashboardSpec {
1596
+ /** A dashboard as `custom.dashboards` reports it, in the screen's own words. */
1597
+ interface SavedDashboard {
1598
+ id: Uuid$1;
1248
1599
  name: string;
1249
- /** The Table most of its blocks are about. A block may name another. */
1250
- subject: Uuid$1;
1600
+ /** The subject Table: the one a block that names no table of its own reads. */
1601
+ subject: Uuid$1 | null;
1251
1602
  blocks: ChartSpec[];
1603
+ presentation: Record<string, unknown>;
1604
+ /** The store's own version. A save re-states the whole dashboard. */
1605
+ version: number;
1252
1606
  }
1253
- interface SavedDashboard extends DashboardSpec {
1254
- id: Uuid$1;
1255
- /**
1256
- * The record's version AT LOAD, read from `custom.io_revisions` for the one
1257
- * record being edited. The read door answers documents and not versions, so
1258
- * this is null until it has been read — and a save with a null version is an
1259
- * ordinary last-writer-wins write, exactly as the store defines it.
1260
- */
1261
- version: number | null;
1262
- }
1263
- /** The package-owned Table every dashboard is a record of. */
1264
- declare const DASHBOARD_TABLE: SystemTableSpec;
1265
- declare function dashboardDocument(spec: DashboardSpec): Record<string, unknown>;
1266
- declare function dashboardFromRecord(row: ReadRow): SavedDashboard;
1607
+ /** One saved block back into the shape a screen edits. */
1608
+ declare function specFromBlock(block: DashboardBlock, subject: Uuid$1): ChartSpec;
1609
+ /**
1610
+ * One block back into the door's own argument. `custom.dashboard_declare` judges
1611
+ * every block on the way IN — a block naming a Field this Table does not have is
1612
+ * refused BY NAME — so a canvas cannot be saved broken.
1613
+ */
1614
+ declare function blockFromSpec(spec: ChartSpec, subject: Uuid$1): DashboardBlock;
1615
+ /** One row of `custom.dashboards` into the shape a screen and an agent both read. */
1616
+ declare function dashboardFromSummary(summary: DashboardSummary): SavedDashboard;
1617
+ /**
1618
+ * The exact arguments `custom.dashboard_declare` is called with. A save is a
1619
+ * RE-STATEMENT of the whole dashboard, so the presentation goes straight back:
1620
+ * a save that dropped it would quietly lose the question the person asked the
1621
+ * agent, which is what the canvas is FOR.
1622
+ */
1623
+ declare function dashboardDeclareArgs(board: SavedDashboard, subject: Uuid$1): {
1624
+ table_id: Uuid$1;
1625
+ name: string;
1626
+ blocks: DashboardBlock[];
1627
+ presentation: Record<string, unknown>;
1628
+ dashboard_id: Uuid$1 | null;
1629
+ };
1267
1630
  /**
1268
1631
  * The series palette. Six SEMANTIC tokens the design system already flips for
1269
1632
  * dark mode, so a chart is correct in both themes without a second palette and
@@ -1273,6 +1636,60 @@ declare const SERIES_COLORS: readonly ["hsl(var(--primary))", "hsl(var(--info))"
1273
1636
  /** The label one aggregate row carries — its groups, joined the way a person reads them. */
1274
1637
  declare function groupLabel(groups: Record<string, string | null>): string;
1275
1638
 
1639
+ /** The same shape `components/ui/chart.tsx` takes: one entry per series key. */
1640
+ type ChartConfig = Record<string, {
1641
+ label?: ReactNode;
1642
+ icon?: ComponentType;
1643
+ color?: string;
1644
+ }>;
1645
+ /**
1646
+ * MEASURE THE BOX, DO NOT ASK RECHARTS TO. Returns the ref to put on the
1647
+ * wrapper and the width to hand the chart. `ResizeObserver` being absent is not
1648
+ * an error: the fallback stands and the chart still draws.
1649
+ */
1650
+ declare function useMeasuredWidth(fallback?: number): [RefObject<HTMLDivElement | null>, number];
1651
+ /**
1652
+ * The box a chart lives in. It carries the app's own Recharts class overrides —
1653
+ * axis ticks in `muted-foreground`, the grid and the cursor in `border`, no
1654
+ * focus outline on a layer — so the chart sits in the page's own palette.
1655
+ */
1656
+ declare function ChartFrame({ config, height, className, children, }: {
1657
+ config: ChartConfig;
1658
+ height: number;
1659
+ className?: string | undefined;
1660
+ children: (width: number) => ReactNode;
1661
+ }): react.JSX.Element;
1662
+ /** One payload entry as Recharts injects it into a tooltip's `content` element. */
1663
+ interface TooltipEntry {
1664
+ name?: string | number;
1665
+ dataKey?: string | number;
1666
+ value?: number | string;
1667
+ color?: string;
1668
+ payload?: Record<string, unknown>;
1669
+ }
1670
+ /**
1671
+ * The app's tooltip, with its markup and its classes. Recharts 3 injects
1672
+ * `active` / `payload` / `label` into the element it clones, so they are
1673
+ * declared optional here exactly as the app declares them.
1674
+ */
1675
+ declare function ChartTooltipContent({ active, payload, label, config, className, }: {
1676
+ active?: boolean;
1677
+ payload?: ReadonlyArray<TooltipEntry>;
1678
+ label?: ReactNode;
1679
+ config: ChartConfig;
1680
+ className?: string | undefined;
1681
+ }): react.JSX.Element | null;
1682
+ /** The app's legend, with its markup and its classes. */
1683
+ declare function ChartLegendContent({ payload, config, className, }: {
1684
+ payload?: ReadonlyArray<{
1685
+ value?: string | number;
1686
+ color?: string;
1687
+ dataKey?: string | number;
1688
+ }>;
1689
+ config: ChartConfig;
1690
+ className?: string | undefined;
1691
+ }): react.JSX.Element | null;
1692
+
1276
1693
  /** The one token form, written the way the store's own pattern reads it. */
1277
1694
  declare function fieldToken(fieldId: Uuid$1): string;
1278
1695
  /** THE DECLARATIVE SPEC an agent writes. One template, whole, in one object. */
@@ -1350,20 +1767,23 @@ interface NotifyRuleEditorProps {
1350
1767
  declare function NotifyRuleEditor({ tableId, seed, className }: NotifyRuleEditorProps): react.JSX.Element;
1351
1768
 
1352
1769
  interface ChartBlockProps {
1353
- spec: ChartSpec;
1770
+ /** One block out of the canvas's single run — answered, or refused. */
1771
+ block: DashboardBlockResult;
1772
+ /** The dashboard's subject Table, for a block that names none of its own. */
1773
+ subject: Uuid$1;
1354
1774
  className?: string | undefined;
1355
1775
  }
1356
- declare function ChartBlock({ spec, className }: ChartBlockProps): react.JSX.Element;
1776
+ declare function ChartBlock({ block, subject, className }: ChartBlockProps): react.JSX.Element;
1357
1777
 
1358
1778
  interface DashboardCanvasProps {
1359
1779
  /** The Table these blocks are about. */
1360
1780
  tableId: Uuid;
1361
- /** COMPLETE declarative dashboards an agent wrote. Saved once, never overwritten. */
1362
- seed?: DashboardSpec[] | undefined;
1363
1781
  activeDashboardId?: Uuid | null | undefined;
1782
+ /** The one filter bar across the canvas. Merged UNDER each block's own filter. */
1783
+ filter?: Record<string, AggregateFilter> | undefined;
1364
1784
  className?: string | undefined;
1365
1785
  }
1366
- declare function DashboardCanvas({ tableId, seed, activeDashboardId, className }: DashboardCanvasProps): react.JSX.Element;
1786
+ declare function DashboardCanvas({ tableId, activeDashboardId, filter, className }: DashboardCanvasProps): react.JSX.Element;
1367
1787
 
1368
1788
  interface FormsPanelProps {
1369
1789
  tableId: Uuid;
@@ -1610,7 +2030,13 @@ declare const LANE_EMPTY: Record<TableLane, string>;
1610
2030
  declare function laneFor(table: Table): TableLane;
1611
2031
  interface TablesHomeProps {
1612
2032
  /** Where a table opens. Absent and the card is a plain row with no pretend link. */
1613
- onOpenTable?: ((tableId: Uuid$1) => void) | undefined;
2033
+ /**
2034
+ * Opening a Table, and — with a second argument — opening it ON one of its
2035
+ * dashboards. The second argument is optional so every existing caller is
2036
+ * unchanged; a host that ignores it lands on the records, which is what it
2037
+ * did before, rather than on a screen it does not know how to address.
2038
+ */
2039
+ onOpenTable?: ((tableId: Uuid$1, dashboardId?: Uuid$1) => void) | undefined;
1614
2040
  className?: string | undefined;
1615
2041
  }
1616
2042
  declare function TablesHome({ onOpenTable, className }: TablesHomeProps): react.JSX.Element;
@@ -1635,6 +2061,17 @@ interface TablePageProps {
1635
2061
  onLeave?: (() => void) | undefined;
1636
2062
  /** The word on that button. Defaults to "Back to your tables". */
1637
2063
  leaveLabel?: string | undefined;
2064
+ /**
2065
+ * OPEN ON ONE DASHBOARD, because an agent's answer ends in a LINK.
2066
+ *
2067
+ * `dashboard_propose` makes the whole canvas in one call and hands back an
2068
+ * address. A link that landed on the records and left the person to find the
2069
+ * Dashboards button, and then the right dashboard among several, is a link
2070
+ * that did not finish the sentence the agent started. Present, this opens the
2071
+ * canvas on that dashboard; absent, the page opens on the records exactly as
2072
+ * it always has.
2073
+ */
2074
+ activeDashboardId?: Uuid$1 | null | undefined;
1638
2075
  className?: string | undefined;
1639
2076
  }
1640
2077
  /**
@@ -1670,18 +2107,36 @@ declare const TABLE_NOT_REACHABLE: string;
1670
2107
  * second kind of view that every feature after it has to know about.
1671
2108
  */
1672
2109
  declare const DEFAULT_VIEW_NAME = "All records";
1673
- declare function TablePage({ tableId, pageSize, seedViews, onLeave, leaveLabel, className, }: TablePageProps): react.JSX.Element;
2110
+ /**
2111
+ * What the page says while it is running on the unsaved default. It is a
2112
+ * STAND-IN and it announces itself, with the one thing a person can do about
2113
+ * it: the bar above saves a view, and from then on the layout is remembered.
2114
+ */
2115
+ declare const VIEW_NOT_SAVED_YET: string;
2116
+ declare function TablePage({ tableId, pageSize, seedViews, onLeave, leaveLabel, activeDashboardId, className, }: TablePageProps): react.JSX.Element;
1674
2117
 
1675
- /** One Field a person asked for, in the store's own behaviour words (FLD-1). */
2118
+ /** One Field a person asked for, in the words a person uses (FLD-1 / FLD-11). */
1676
2119
  interface NewFieldSpec {
1677
2120
  key: string;
1678
2121
  label: string;
1679
- /** A parity type — the thirteen come from the store, see `PARITY_FIELD_TYPES`. */
1680
- type: string;
2122
+ /**
2123
+ * The word for what this column holds. One of the thirteen parity types, one
2124
+ * of the five behaviours, or a plain synonym (`text`, `long_text`, `number`)
2125
+ * — `custom._field_document_for` resolves all three and refuses a word that
2126
+ * means nothing, by name, with the list.
2127
+ */
2128
+ type: FieldTypeWord;
1681
2129
  sort?: number;
1682
2130
  required?: boolean;
1683
2131
  multi?: boolean;
1684
2132
  config?: Record<string, unknown>;
2133
+ /** A choice list's choices, as words. The store keeps them as a Table (FLD-5). */
2134
+ options?: string[];
2135
+ /** A column that points at another Table of this organization (FLD-11 / REL-8). */
2136
+ relationTarget?: Uuid$1;
2137
+ /** A currency column's symbol; a date column's day-or-day-and-time. */
2138
+ unit?: string;
2139
+ kind?: "date" | "datetime";
1685
2140
  }
1686
2141
  interface NewTableSpec {
1687
2142
  name: string;
@@ -1693,9 +2148,16 @@ interface NewTableSpec {
1693
2148
  titleField?: string;
1694
2149
  fields?: NewFieldSpec[];
1695
2150
  }
1696
- type DeclareResult = {
2151
+ type DeclareResult =
2152
+ /**
2153
+ * The Table's id — and its HOME's, because REC-14 gives the Table exactly one
2154
+ * and the caller that made it is the only one that can tidy it up again. A
2155
+ * caller reading `data` alone is unaffected.
2156
+ */
2157
+ {
1697
2158
  ok: true;
1698
2159
  data: Uuid$1;
2160
+ homeId: Uuid$1;
1699
2161
  } | {
1700
2162
  ok: false;
1701
2163
  error: RecordsError;
@@ -1716,8 +2178,24 @@ declare function tokenFor(name: string): string;
1716
2178
  * store then enforces it for everyone.
1717
2179
  */
1718
2180
  declare const DEFAULT_FIELDS: NewFieldSpec[];
2181
+ /**
2182
+ * One column, in the shape `custom.field_declare` takes — and EVERYTHING a
2183
+ * person said about it. The keys after the type are not decoration: without
2184
+ * `options` the door refuses a choice list outright ("A list of choices needs
2185
+ * its choices"), without `unit` a money column is dollars whatever the person
2186
+ * picked, and without `relation_target` a column that points at another of this
2187
+ * organization's own tables cannot be declared at all.
2188
+ */
2189
+ declare function fieldDeclarationFor(field: NewFieldSpec): NewFieldDeclaration;
1719
2190
  declare function declareTable(client: RecordsClient, spec: NewTableSpec): Promise<DeclareResult>;
1720
- /** Write Field records for an existing Table. Used by the create path and by import. */
2191
+ /**
2192
+ * Columns for an existing Table, through the door that declares one. Used by
2193
+ * the create path and by import.
2194
+ *
2195
+ * A column the store refused STOPS the sequence and hands back the store's own
2196
+ * sentence: a Table that quietly lost a column is the silent failure this
2197
+ * package exists to prevent.
2198
+ */
1721
2199
  declare function addFields(client: RecordsClient, tableId: Uuid$1, fields: NewFieldSpec[]): Promise<{
1722
2200
  ok: true;
1723
2201
  data: Uuid$1;
@@ -1750,4 +2228,4 @@ declare function useCanShare(): boolean;
1750
2228
  declare function shareUnavailableReason(): string;
1751
2229
  declare function ShareControl({ kind, organizationId, subjectId, name, may, size, variant, className, }: ShareControlProps): ReactNode;
1752
2230
 
1753
- 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 ChartKind, type ChartSpec, ChecklistRunner, type ChecklistRunnerProps, type ChecklistSpec, type ChecklistStepSpec, CommentThread, type CommentThreadProps, CustomFieldsSection, type CustomFieldsSectionProps, DASHBOARD_TABLE, DEFAULT_FIELDS, DEFAULT_VIEW_NAME, DashboardCanvas, type DashboardCanvasProps, type DashboardSpec, type DeclareResult, DocRender, type DocRenderProps, DocTemplate, type DocTemplateProps, type DocTemplateSpec, type EditorKind, EmbedFrame, type EmbedFrameProps, type EnrichAsk, type EnrichOutcome, EnrichPanel, type EnrichPanelProps, ExportMenu, type ExportMenuProps, FIELD_TYPE_CHOICES, FIELD_TYPE_GROUPS, FORM_FLOWS, FORM_TABLE, 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 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_ENRICH_REASON, NO_MEMBERS_REASON, NO_RIGHTS, NO_SAVED_VIEWS_REASON, NO_SHARE_REASON, NO_UPLOAD_REASON, type NewFieldSpec, type NewTableSpec, NotifyRuleEditor, type NotifyRuleEditorProps, type NotifyRuleSpec, type OrganizationMember, PARITY_LABEL, PARITY_MADE_OF, Peek, type PeekProps, type PendingCapture, PersonPicker, type PersonPickerProps, type PickableFieldType, type PlainFieldType, type PlainRefusal, PortalShell, type PortalShellProps, type ProposalOutcome, ProposalRow, type ProposalRowProps, type ProposedChange, ProvenanceBadge, PublicViewPage, type PublicViewPageProps, 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, 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_TABLE, ViewBar, type ViewBarProps, type ViewLayout, type ViewSort, ViewSwitcher, type ViewSwitcherProps, type WhatYouMayDo, addFields, bodyForReading, bodyFromKeys, columnForField, dashboardDocument, dashboardFromRecord, declareTable, editorKindFor, ensureSystemTable, envelopeFor, fieldIsEditable, fieldName, fieldToken, fieldTypeChoice, fieldTypeLabel, formDocument, formFromRecord, groupLabel, hintForAPerson, hintIsMachineIdentity, humanize, idsOf, isId, isMachineIdentity, isPlainFieldType, isSignatureField, keyFor, laneFor, machineIdentityIn, memberName, parityTypesWithNoExplanation, personActor, personRecordForMember, pointsAtRecords, recordName, recordsDataSource, refusalForAPerson, refusalLineForAPerson, renderValue, rowName, scalarText, shareUnavailableReason, storeDecidesRights, submissionStamp, tableName, tableRightsAt, tokenFor, useCanShare, useEmbedHandshake, useGridEditing, useRecordLabels, useRecordRights, useRecordsUi, useRowRights, useSystemTable, useTableRights, useViewRecords, viewDocument, viewFromRecord, viewPatchDocument, whatIsMissing, whatYouMayDo, whatYouMayDoWithTable };
2231
+ 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 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, 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 };