@ai-matrx/records-ui 0.16.0 → 0.28.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, 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,88 @@ 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
+ /** Everything a view says about how its table LOOKS. */
653
+ type GridPresentation = {
654
+ /** Color-by-a-column, rules and manual highlights. */
655
+ style?: TableStyle;
656
+ /** Per-column format overrides, by the Field's key. */
657
+ formats?: Record<string, FieldFormatConfig>;
658
+ /**
659
+ * The columns that stay in place while the table scrolls sideways, by Field
660
+ * key. Only the LEADING run of the view's column order can actually freeze —
661
+ * the data table decides that, and declines rather than pinning a column at a
662
+ * guessed offset.
663
+ */
664
+ frozen?: string[];
665
+ };
666
+ declare const EMPTY_PRESENTATION: GridPresentation;
667
+ /** A frozen column needs a known width, or the table declines to freeze at all. */
668
+ declare const FROZEN_COLUMN_WIDTH = 200;
669
+ /**
670
+ * Read a presentation out of whatever the view record holds — an object, or the
671
+ * JSON string a text field stores.
672
+ *
673
+ * Tolerant in exactly the way `parseTableStyle` is: an unreadable half is
674
+ * dropped and the rest still applies, because a table must keep drawing when
675
+ * one piece of its styling goes out of date.
676
+ */
677
+ declare function parseGridPresentation(raw: unknown): GridPresentation;
678
+ /** True when nothing here would change how anything looks. */
679
+ declare function presentationIsEmpty(p: GridPresentation): boolean;
680
+ /** The string a view record stores. Empty string for "this view styles nothing". */
681
+ declare function presentationDocument(p: GridPresentation): string;
682
+ /**
683
+ * The format a Field's OWN declaration implies, before any view says anything.
684
+ *
685
+ * Returns `undefined` for a Field whose value the record renderer already draws
686
+ * better than a formatter could — a relation chip, a person, an attachment, a
687
+ * choice — because handing those to a text formatter would REPLACE a working
688
+ * control with a string.
689
+ */
690
+ declare function formatForField(field: Field): FieldFormatConfig | undefined;
691
+ declare function currencyCodeFor(unit: string | null | undefined): string;
692
+ /**
693
+ * The color a value paints with when a view colors BY a column.
694
+ *
695
+ * NOTHING FAILS SILENTLY, so this never returns "no color" for a value that
696
+ * exists. The store keeps a list column's choices as records of another Table,
697
+ * and this grid has not read that Table's option colors, so the color is
698
+ * derived from the value's own text: the same word always gets the same color,
699
+ * different words get different ones, and `true` is green the way every
700
+ * checklist reads. When those option colors do land, this is the ONE function
701
+ * that changes and every screen follows.
702
+ */
703
+ declare const colorFromTheValue: ChoiceColorLookup;
704
+
705
+ /**
706
+ * WHAT A TABLE WITH NO COLUMNS SAYS. Named here because the gate asserts on it:
707
+ * the state it describes is what a first-time person met for two days.
708
+ */
709
+ declare const NO_COLUMNS_YET = "This table has no columns yet";
710
+ declare const NO_COLUMNS_WHY: string;
573
711
  interface GridProps {
574
712
  tableId: Uuid;
575
713
  /** Rows per page. The table's own pagination handles the rest. */
@@ -588,15 +726,29 @@ interface GridProps {
588
726
  toolbarActions?: ReactNode | undefined;
589
727
  /** Editing in place is on by default; a read-only surface (a portal) turns it off. */
590
728
  editable?: boolean | undefined;
729
+ /**
730
+ * HOW THIS TABLE LOOKS — the active saved view's colors, per-column formats
731
+ * and frozen columns (`presentation.ts`).
732
+ *
733
+ * It is a prop and not a read of its own because the VIEW owns it and the
734
+ * host already knows which view is open; a second read here would draw one
735
+ * view's colors over another's. Omitted, the table still formats every money
736
+ * and date column correctly from the Fields' own declarations — a look is an
737
+ * override, never the only thing that makes a column readable.
738
+ */
739
+ presentation?: GridPresentation | undefined;
591
740
  className?: string | undefined;
592
741
  }
593
- declare function Grid({ tableId, pageSize, onOpenRecord, onAddField, onNewRecordForm, toolbarActions, editable, className, }: GridProps): react.JSX.Element;
742
+ declare function Grid({ tableId, pageSize, onOpenRecord, onAddField, onNewRecordForm, toolbarActions, editable, presentation, className, }: GridProps): react.JSX.Element;
594
743
  /**
595
744
  * One Field becomes one column. The header is the Field's own NAME — never its
596
745
  * key (`names.ts`) — and the cell is the value, rendered by its parity type and
597
746
  * editable in place when an editing session is passed.
598
747
  */
599
- declare function columnForField(field: Field$1, editing?: GridEditing | null, mayWriteRow?: (rowId: Uuid) => boolean, whyNotRow?: (rowId: Uuid) => string): MatrxColumnDef<ReadRow$1>;
748
+ declare function columnForField(field: Field$1, editing?: GridEditing | null, mayWriteRow?: (rowId: Uuid) => boolean, whyNotRow?: (rowId: Uuid) => string, look?: {
749
+ format?: FieldFormatConfig;
750
+ frozen?: boolean;
751
+ }): MatrxColumnDef<ReadRow$1>;
600
752
 
601
753
  interface ExportMenuProps {
602
754
  tableId: Uuid;
@@ -820,10 +972,23 @@ declare function ProvenanceBadge({ document, fieldKey }: {
820
972
  * export, a chat line) keeps calling `renderValue` with no resolver and says
821
973
  * "Loading…" rather than printing an id.
822
974
  */
823
- declare function RecordValue({ field, value, document, }: {
975
+ declare function RecordValue({ field, value, document, format, }: {
824
976
  field: Field;
825
977
  value: unknown;
826
978
  document?: RecordDocument | undefined;
979
+ /**
980
+ * The column's DECLARED format (`presentation.ts`), when it has one.
981
+ *
982
+ * A cell renderer beats `MatrxColumnDef.format` — the table hands the cell to
983
+ * the consumer and steps back — so a store column that declared `currency`
984
+ * and then drew itself here would have shown a raw `1250.5` while its own
985
+ * header was right-aligned for money. The primitive's formatter is asked for
986
+ * the text instead of a second one being written beside it, so the read view
987
+ * and the table can never disagree about what a number means. THE FALLBACK
988
+ * LAW rides along: a value that does not fit is amber with the reason, never
989
+ * blank.
990
+ */
991
+ format?: FieldFormatConfig | undefined;
827
992
  }): react.JSX.Element;
828
993
 
829
994
  declare const PARITY_LABEL: Record<ParityFieldType, string>;
@@ -855,6 +1020,16 @@ interface SystemFieldSpec {
855
1020
  required?: boolean;
856
1021
  multi?: boolean;
857
1022
  config?: Record<string, unknown>;
1023
+ /**
1024
+ * WHAT THE BEHAVIOUR ALONE CANNOT SAY, and what the declaring door refuses a
1025
+ * column without. A `list` has to name its choices (FLD-5/FLD-6) and a
1026
+ * `relation` has to name the Table it points at (FLD-11) — a package table
1027
+ * that grew one of those without saying so here would be refused by name on
1028
+ * every organization's first load, which is the class this file just cost us.
1029
+ */
1030
+ options?: string[];
1031
+ relationTarget?: Uuid$1;
1032
+ expr?: Record<string, unknown>;
858
1033
  }
859
1034
  interface SystemTableSpec {
860
1035
  /** The token this Table is addressed by. Every package table starts `records_ui_`. */
@@ -943,6 +1118,16 @@ interface SavedViewSpec {
943
1118
  */
944
1119
  ruleId?: Uuid$1 | null;
945
1120
  isDefault?: boolean;
1121
+ /**
1122
+ * HOW THIS VIEW LOOKS — its colors, its per-column formats and its frozen
1123
+ * column (`presentation.ts`).
1124
+ *
1125
+ * It lives on the VIEW and not on the Fields because two people read one
1126
+ * table two ways and neither reading is a fact about the records; it lives on
1127
+ * a RECORD, not a new column, because that is what makes it something an
1128
+ * agent writes with the same `records` tool as everything else.
1129
+ */
1130
+ presentation?: GridPresentation;
946
1131
  }
947
1132
  /** A saved view as it comes back out of the store, with its record's own id. */
948
1133
  interface SavedView extends SavedViewSpec {
@@ -1169,23 +1354,52 @@ interface FormSpec {
1169
1354
  */
1170
1355
  isPublic?: boolean;
1171
1356
  }
1172
- /** A form as it comes back out of the store, with its record's own id and version. */
1357
+ /**
1358
+ * A form as `custom.forms` reports it — the spec a screen renders, plus the
1359
+ * things only the STORE knows about it.
1360
+ *
1361
+ * The four store-side ids are carried on purpose. `custom.form_declare` is a
1362
+ * RE-STATEMENT of the whole form, so a save that left `notifyRuleId` out would
1363
+ * set it to null and the owner would quietly stop being told when somebody
1364
+ * answers — the exact silent failure the notify Rule exists to prevent. They are
1365
+ * read here and handed straight back by `formDeclareArgs`.
1366
+ */
1173
1367
  interface SavedForm extends FormSpec {
1174
1368
  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;
1369
+ /** draft · open · closed · full — the store's own word, never derived on a screen. */
1370
+ state: FormSummary["state"];
1371
+ /** The form's readable name in the store. `form_declare` keeps it across saves. */
1372
+ slug: string;
1373
+ /** Stops taking answers at this many. Null is no ceiling. */
1374
+ submissionCap: number | null;
1375
+ /** The accept Rule: what counts as a complete answer. Null holds every answer for a person. */
1376
+ quarantineRuleId: Uuid$1 | null;
1377
+ /** The subscription Rule that tells somebody an answer arrived. */
1378
+ notifyRuleId: Uuid$1 | null;
1182
1379
  }
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;
1380
+ /**
1381
+ * The spec as `custom.anon_form.presentation` holds it.
1382
+ *
1383
+ * `questions` is deliberately NOT here: the door writes it itself from the
1384
+ * argument it validated (`presentation || {"questions": p_questions}`), so the
1385
+ * words a form is asked in and the keys it is allowed to accept can never be two
1386
+ * different lists.
1387
+ */
1388
+ declare function formPresentation(spec: FormSpec): Record<string, unknown>;
1389
+ /** The exact arguments `custom.form_declare` is called with, for a new form or a re-statement. */
1390
+ declare function formDeclareArgs(form: FormSpec | SavedForm): {
1391
+ table_id: Uuid$1;
1392
+ title: string;
1393
+ questions: FormQuestionSpec[];
1394
+ presentation: Record<string, unknown>;
1395
+ submission_cap: number | null;
1396
+ quarantine_rule_id: Uuid$1 | null;
1397
+ notify_rule_id: Uuid$1 | null;
1398
+ form_id: Uuid$1 | null;
1399
+ slug: string | null;
1400
+ };
1401
+ /** One row of `custom.forms` back into the spec a screen and an agent both read. */
1402
+ declare function formFromSummary(summary: FormSummary): SavedForm;
1189
1403
  /**
1190
1404
  * THE SOURCE STAMP every submission carries. A record that arrived through a
1191
1405
  * form is not indistinguishable from one somebody typed into the grid: it says
@@ -1200,6 +1414,65 @@ declare function submissionStamp(args: {
1200
1414
  onBehalfOf?: string | null;
1201
1415
  }): Record<string, unknown>;
1202
1416
 
1417
+ interface PortalsPanelProps {
1418
+ /**
1419
+ * OPTIONAL. The Table whose page this rail is on. It is used for ONE thing:
1420
+ * saying, on an opened portal, whether this table is among the ones that
1421
+ * portal shows. It never filters the list — a portal belongs to the
1422
+ * organization, and hiding the others would answer a question nobody asked.
1423
+ */
1424
+ tableId?: Uuid | undefined;
1425
+ className?: string | undefined;
1426
+ }
1427
+ /** What a door answered, for a view that never holds a client of its own. */
1428
+ type PortalAnswer<T> = {
1429
+ ok: true;
1430
+ data: T;
1431
+ } | {
1432
+ ok: false;
1433
+ error: RecordsError;
1434
+ };
1435
+ /**
1436
+ * THE SENTENCE SAID BEFORE A REVOKE, and it is deliberately not generic.
1437
+ *
1438
+ * "Are you sure?" tells somebody nothing they did not already know. What they
1439
+ * need is the two things that actually change: this person stops being able to
1440
+ * sign in at all, and the records that named their client stop reaching them.
1441
+ * The store says the same thing back in the past tense once it is done
1442
+ * (`custom.portal_revoke`'s own `say`), and that sentence is shown too.
1443
+ */
1444
+ declare function revokeConsequence(person: PortalPrincipal, portalTitle: string): string;
1445
+ /**
1446
+ * THE LINE ABOVE A PREVIEW, and why it is not decoration.
1447
+ *
1448
+ * A preview a screen assembled for itself would be a second implementation of
1449
+ * visibility, and the first time the two disagreed nobody would know which one
1450
+ * was lying. This one is the store's own answer to the store's own question, so
1451
+ * the screen can say whose eyes these are and be right.
1452
+ */
1453
+ declare function previewLine(person: PortalPrincipal): string;
1454
+ declare function PortalsPanel({ tableId, className }: PortalsPanelProps): react.JSX.Element;
1455
+ interface PortalCardViewProps {
1456
+ /** Exactly what `custom.portal_card` answered. */
1457
+ card: PortalCard;
1458
+ /** The Table whose page this is on, if any — marked among the ones shown. */
1459
+ tableId?: Uuid | undefined;
1460
+ /** Take one person's way in away. Answers the door's own past-tense sentence. */
1461
+ onRevoke: (person: PortalPrincipal) => Promise<PortalAnswer<string>>;
1462
+ /** What this person sees on one Table — `custom.portal_preview`'s answer. */
1463
+ onPreview: (person: PortalPrincipal, tableId: Uuid) => Promise<PortalAnswer<PortalPreviewRow[]>>;
1464
+ /** The invite control, which needs a client of its own. Absent means none is offered. */
1465
+ invite?: ReactNode;
1466
+ className?: string | undefined;
1467
+ }
1468
+ declare function PortalCardView({ card, tableId, onRevoke, onPreview, invite, className, }: PortalCardViewProps): react.JSX.Element;
1469
+
1470
+ interface SubscriptionsPanelProps {
1471
+ tableId: Uuid;
1472
+ className?: string | undefined;
1473
+ }
1474
+ declare function SubscriptionsPanel({ tableId, className }: SubscriptionsPanelProps): react.JSX.Element;
1475
+
1203
1476
  interface FormBuilderProps {
1204
1477
  /** The Table this form collects into. A form is a view on a real Table. */
1205
1478
  tableId: Uuid;
@@ -1216,13 +1489,23 @@ interface FormBuilderProps {
1216
1489
  }
1217
1490
  declare function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }: FormBuilderProps): react.JSX.Element;
1218
1491
 
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];
1492
+ /**
1493
+ * The shapes a block can take. There is exactly ONE closed set and it is the
1494
+ * store's — `custom.dashboard_kinds()` answers it and `@ai-matrx/records`
1495
+ * carries it. A second copy here would be a list that can disagree with the
1496
+ * door, which is how a screen comes to offer a shape the store refuses.
1497
+ */
1498
+ type ChartKind = DashboardBlockKind;
1222
1499
  declare const CHART_KIND_LABEL: Record<ChartKind, string>;
1500
+ /**
1501
+ * The shapes in the order a person reads them, derived from the labels above —
1502
+ * which TypeScript keys exhaustively by the store's own type, so this list can
1503
+ * never drift from the closed set.
1504
+ */
1505
+ declare const CHART_KINDS: ChartKind[];
1223
1506
  /** What each shape needs before it can draw, in one sentence a block prints. */
1224
1507
  declare const CHART_NEEDS: Record<ChartKind, string | null>;
1225
- /** ONE BLOCK: the question and the shape, in one declarative object. */
1508
+ /** ONE BLOCK, in the words a screen edits. */
1226
1509
  interface ChartSpec {
1227
1510
  title: string;
1228
1511
  /** The Table this block asks about. */
@@ -1237,33 +1520,50 @@ interface ChartSpec {
1237
1520
  } | null;
1238
1521
  /** `count` needs no key; every other measure reads one Field. */
1239
1522
  measures?: AggregateMeasure[];
1240
- /** Equality only, and the store puts it in the SAME WHERE as visibility. */
1241
- filter?: Record<string, string>;
1523
+ /** A scalar is an equality; an object is a half-open moment window. */
1524
+ filter?: Record<string, AggregateFilter>;
1242
1525
  limit?: number;
1243
1526
  /** How wide this block sits on the canvas, in twelfths. */
1244
1527
  span?: number;
1528
+ /** `stuck` only: the Field whose value is watched for a change. */
1529
+ stateKey?: string;
1530
+ /** `stuck` only: how long a record may sit on the same value. */
1531
+ days?: number;
1245
1532
  }
1246
- /** THE WHOLE DASHBOARD, as one object an agent writes in one call. */
1247
- interface DashboardSpec {
1533
+ /** A dashboard as `custom.dashboards` reports it, in the screen's own words. */
1534
+ interface SavedDashboard {
1535
+ id: Uuid$1;
1248
1536
  name: string;
1249
- /** The Table most of its blocks are about. A block may name another. */
1250
- subject: Uuid$1;
1537
+ /** The subject Table: the one a block that names no table of its own reads. */
1538
+ subject: Uuid$1 | null;
1251
1539
  blocks: ChartSpec[];
1540
+ presentation: Record<string, unknown>;
1541
+ /** The store's own version. A save re-states the whole dashboard. */
1542
+ version: number;
1252
1543
  }
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;
1544
+ /** One saved block back into the shape a screen edits. */
1545
+ declare function specFromBlock(block: DashboardBlock, subject: Uuid$1): ChartSpec;
1546
+ /**
1547
+ * One block back into the door's own argument. `custom.dashboard_declare` judges
1548
+ * every block on the way IN — a block naming a Field this Table does not have is
1549
+ * refused BY NAME — so a canvas cannot be saved broken.
1550
+ */
1551
+ declare function blockFromSpec(spec: ChartSpec, subject: Uuid$1): DashboardBlock;
1552
+ /** One row of `custom.dashboards` into the shape a screen and an agent both read. */
1553
+ declare function dashboardFromSummary(summary: DashboardSummary): SavedDashboard;
1554
+ /**
1555
+ * The exact arguments `custom.dashboard_declare` is called with. A save is a
1556
+ * RE-STATEMENT of the whole dashboard, so the presentation goes straight back:
1557
+ * a save that dropped it would quietly lose the question the person asked the
1558
+ * agent, which is what the canvas is FOR.
1559
+ */
1560
+ declare function dashboardDeclareArgs(board: SavedDashboard, subject: Uuid$1): {
1561
+ table_id: Uuid$1;
1562
+ name: string;
1563
+ blocks: DashboardBlock[];
1564
+ presentation: Record<string, unknown>;
1565
+ dashboard_id: Uuid$1 | null;
1566
+ };
1267
1567
  /**
1268
1568
  * The series palette. Six SEMANTIC tokens the design system already flips for
1269
1569
  * dark mode, so a chart is correct in both themes without a second palette and
@@ -1273,6 +1573,60 @@ declare const SERIES_COLORS: readonly ["hsl(var(--primary))", "hsl(var(--info))"
1273
1573
  /** The label one aggregate row carries — its groups, joined the way a person reads them. */
1274
1574
  declare function groupLabel(groups: Record<string, string | null>): string;
1275
1575
 
1576
+ /** The same shape `components/ui/chart.tsx` takes: one entry per series key. */
1577
+ type ChartConfig = Record<string, {
1578
+ label?: ReactNode;
1579
+ icon?: ComponentType;
1580
+ color?: string;
1581
+ }>;
1582
+ /**
1583
+ * MEASURE THE BOX, DO NOT ASK RECHARTS TO. Returns the ref to put on the
1584
+ * wrapper and the width to hand the chart. `ResizeObserver` being absent is not
1585
+ * an error: the fallback stands and the chart still draws.
1586
+ */
1587
+ declare function useMeasuredWidth(fallback?: number): [RefObject<HTMLDivElement | null>, number];
1588
+ /**
1589
+ * The box a chart lives in. It carries the app's own Recharts class overrides —
1590
+ * axis ticks in `muted-foreground`, the grid and the cursor in `border`, no
1591
+ * focus outline on a layer — so the chart sits in the page's own palette.
1592
+ */
1593
+ declare function ChartFrame({ config, height, className, children, }: {
1594
+ config: ChartConfig;
1595
+ height: number;
1596
+ className?: string | undefined;
1597
+ children: (width: number) => ReactNode;
1598
+ }): react.JSX.Element;
1599
+ /** One payload entry as Recharts injects it into a tooltip's `content` element. */
1600
+ interface TooltipEntry {
1601
+ name?: string | number;
1602
+ dataKey?: string | number;
1603
+ value?: number | string;
1604
+ color?: string;
1605
+ payload?: Record<string, unknown>;
1606
+ }
1607
+ /**
1608
+ * The app's tooltip, with its markup and its classes. Recharts 3 injects
1609
+ * `active` / `payload` / `label` into the element it clones, so they are
1610
+ * declared optional here exactly as the app declares them.
1611
+ */
1612
+ declare function ChartTooltipContent({ active, payload, label, config, className, }: {
1613
+ active?: boolean;
1614
+ payload?: ReadonlyArray<TooltipEntry>;
1615
+ label?: ReactNode;
1616
+ config: ChartConfig;
1617
+ className?: string | undefined;
1618
+ }): react.JSX.Element | null;
1619
+ /** The app's legend, with its markup and its classes. */
1620
+ declare function ChartLegendContent({ payload, config, className, }: {
1621
+ payload?: ReadonlyArray<{
1622
+ value?: string | number;
1623
+ color?: string;
1624
+ dataKey?: string | number;
1625
+ }>;
1626
+ config: ChartConfig;
1627
+ className?: string | undefined;
1628
+ }): react.JSX.Element | null;
1629
+
1276
1630
  /** The one token form, written the way the store's own pattern reads it. */
1277
1631
  declare function fieldToken(fieldId: Uuid$1): string;
1278
1632
  /** THE DECLARATIVE SPEC an agent writes. One template, whole, in one object. */
@@ -1350,20 +1704,23 @@ interface NotifyRuleEditorProps {
1350
1704
  declare function NotifyRuleEditor({ tableId, seed, className }: NotifyRuleEditorProps): react.JSX.Element;
1351
1705
 
1352
1706
  interface ChartBlockProps {
1353
- spec: ChartSpec;
1707
+ /** One block out of the canvas's single run — answered, or refused. */
1708
+ block: DashboardBlockResult;
1709
+ /** The dashboard's subject Table, for a block that names none of its own. */
1710
+ subject: Uuid$1;
1354
1711
  className?: string | undefined;
1355
1712
  }
1356
- declare function ChartBlock({ spec, className }: ChartBlockProps): react.JSX.Element;
1713
+ declare function ChartBlock({ block, subject, className }: ChartBlockProps): react.JSX.Element;
1357
1714
 
1358
1715
  interface DashboardCanvasProps {
1359
1716
  /** The Table these blocks are about. */
1360
1717
  tableId: Uuid;
1361
- /** COMPLETE declarative dashboards an agent wrote. Saved once, never overwritten. */
1362
- seed?: DashboardSpec[] | undefined;
1363
1718
  activeDashboardId?: Uuid | null | undefined;
1719
+ /** The one filter bar across the canvas. Merged UNDER each block's own filter. */
1720
+ filter?: Record<string, AggregateFilter> | undefined;
1364
1721
  className?: string | undefined;
1365
1722
  }
1366
- declare function DashboardCanvas({ tableId, seed, activeDashboardId, className }: DashboardCanvasProps): react.JSX.Element;
1723
+ declare function DashboardCanvas({ tableId, activeDashboardId, filter, className }: DashboardCanvasProps): react.JSX.Element;
1367
1724
 
1368
1725
  interface FormsPanelProps {
1369
1726
  tableId: Uuid;
@@ -1610,7 +1967,13 @@ declare const LANE_EMPTY: Record<TableLane, string>;
1610
1967
  declare function laneFor(table: Table): TableLane;
1611
1968
  interface TablesHomeProps {
1612
1969
  /** Where a table opens. Absent and the card is a plain row with no pretend link. */
1613
- onOpenTable?: ((tableId: Uuid$1) => void) | undefined;
1970
+ /**
1971
+ * Opening a Table, and — with a second argument — opening it ON one of its
1972
+ * dashboards. The second argument is optional so every existing caller is
1973
+ * unchanged; a host that ignores it lands on the records, which is what it
1974
+ * did before, rather than on a screen it does not know how to address.
1975
+ */
1976
+ onOpenTable?: ((tableId: Uuid$1, dashboardId?: Uuid$1) => void) | undefined;
1614
1977
  className?: string | undefined;
1615
1978
  }
1616
1979
  declare function TablesHome({ onOpenTable, className }: TablesHomeProps): react.JSX.Element;
@@ -1635,6 +1998,17 @@ interface TablePageProps {
1635
1998
  onLeave?: (() => void) | undefined;
1636
1999
  /** The word on that button. Defaults to "Back to your tables". */
1637
2000
  leaveLabel?: string | undefined;
2001
+ /**
2002
+ * OPEN ON ONE DASHBOARD, because an agent's answer ends in a LINK.
2003
+ *
2004
+ * `dashboard_propose` makes the whole canvas in one call and hands back an
2005
+ * address. A link that landed on the records and left the person to find the
2006
+ * Dashboards button, and then the right dashboard among several, is a link
2007
+ * that did not finish the sentence the agent started. Present, this opens the
2008
+ * canvas on that dashboard; absent, the page opens on the records exactly as
2009
+ * it always has.
2010
+ */
2011
+ activeDashboardId?: Uuid$1 | null | undefined;
1638
2012
  className?: string | undefined;
1639
2013
  }
1640
2014
  /**
@@ -1670,18 +2044,36 @@ declare const TABLE_NOT_REACHABLE: string;
1670
2044
  * second kind of view that every feature after it has to know about.
1671
2045
  */
1672
2046
  declare const DEFAULT_VIEW_NAME = "All records";
1673
- declare function TablePage({ tableId, pageSize, seedViews, onLeave, leaveLabel, className, }: TablePageProps): react.JSX.Element;
2047
+ /**
2048
+ * What the page says while it is running on the unsaved default. It is a
2049
+ * STAND-IN and it announces itself, with the one thing a person can do about
2050
+ * it: the bar above saves a view, and from then on the layout is remembered.
2051
+ */
2052
+ declare const VIEW_NOT_SAVED_YET: string;
2053
+ declare function TablePage({ tableId, pageSize, seedViews, onLeave, leaveLabel, activeDashboardId, className, }: TablePageProps): react.JSX.Element;
1674
2054
 
1675
- /** One Field a person asked for, in the store's own behaviour words (FLD-1). */
2055
+ /** One Field a person asked for, in the words a person uses (FLD-1 / FLD-11). */
1676
2056
  interface NewFieldSpec {
1677
2057
  key: string;
1678
2058
  label: string;
1679
- /** A parity type — the thirteen come from the store, see `PARITY_FIELD_TYPES`. */
1680
- type: string;
2059
+ /**
2060
+ * The word for what this column holds. One of the thirteen parity types, one
2061
+ * of the five behaviours, or a plain synonym (`text`, `long_text`, `number`)
2062
+ * — `custom._field_document_for` resolves all three and refuses a word that
2063
+ * means nothing, by name, with the list.
2064
+ */
2065
+ type: FieldTypeWord;
1681
2066
  sort?: number;
1682
2067
  required?: boolean;
1683
2068
  multi?: boolean;
1684
2069
  config?: Record<string, unknown>;
2070
+ /** A choice list's choices, as words. The store keeps them as a Table (FLD-5). */
2071
+ options?: string[];
2072
+ /** A column that points at another Table of this organization (FLD-11 / REL-8). */
2073
+ relationTarget?: Uuid$1;
2074
+ /** A currency column's symbol; a date column's day-or-day-and-time. */
2075
+ unit?: string;
2076
+ kind?: "date" | "datetime";
1685
2077
  }
1686
2078
  interface NewTableSpec {
1687
2079
  name: string;
@@ -1693,9 +2085,16 @@ interface NewTableSpec {
1693
2085
  titleField?: string;
1694
2086
  fields?: NewFieldSpec[];
1695
2087
  }
1696
- type DeclareResult = {
2088
+ type DeclareResult =
2089
+ /**
2090
+ * The Table's id — and its HOME's, because REC-14 gives the Table exactly one
2091
+ * and the caller that made it is the only one that can tidy it up again. A
2092
+ * caller reading `data` alone is unaffected.
2093
+ */
2094
+ {
1697
2095
  ok: true;
1698
2096
  data: Uuid$1;
2097
+ homeId: Uuid$1;
1699
2098
  } | {
1700
2099
  ok: false;
1701
2100
  error: RecordsError;
@@ -1716,8 +2115,24 @@ declare function tokenFor(name: string): string;
1716
2115
  * store then enforces it for everyone.
1717
2116
  */
1718
2117
  declare const DEFAULT_FIELDS: NewFieldSpec[];
2118
+ /**
2119
+ * One column, in the shape `custom.field_declare` takes — and EVERYTHING a
2120
+ * person said about it. The keys after the type are not decoration: without
2121
+ * `options` the door refuses a choice list outright ("A list of choices needs
2122
+ * its choices"), without `unit` a money column is dollars whatever the person
2123
+ * picked, and without `relation_target` a column that points at another of this
2124
+ * organization's own tables cannot be declared at all.
2125
+ */
2126
+ declare function fieldDeclarationFor(field: NewFieldSpec): NewFieldDeclaration;
1719
2127
  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. */
2128
+ /**
2129
+ * Columns for an existing Table, through the door that declares one. Used by
2130
+ * the create path and by import.
2131
+ *
2132
+ * A column the store refused STOPS the sequence and hands back the store's own
2133
+ * sentence: a Table that quietly lost a column is the silent failure this
2134
+ * package exists to prevent.
2135
+ */
1721
2136
  declare function addFields(client: RecordsClient, tableId: Uuid$1, fields: NewFieldSpec[]): Promise<{
1722
2137
  ok: true;
1723
2138
  data: Uuid$1;
@@ -1750,4 +2165,4 @@ declare function useCanShare(): boolean;
1750
2165
  declare function shareUnavailableReason(): string;
1751
2166
  declare function ShareControl({ kind, organizationId, subjectId, name, may, size, variant, className, }: ShareControlProps): ReactNode;
1752
2167
 
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 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 };
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 };