@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/CHANGELOG.md +374 -0
- package/dist/index.cjs +2735 -1430
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +535 -57
- package/dist/index.d.ts +535 -57
- package/dist/index.js +2744 -1410
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
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
|
|
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
|
-
/**
|
|
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
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
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
|
-
/**
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
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
|
-
/**
|
|
1220
|
-
|
|
1221
|
-
|
|
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
|
|
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
|
-
/**
|
|
1241
|
-
filter?: Record<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
|
-
/**
|
|
1247
|
-
interface
|
|
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
|
|
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
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
/**
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
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
|
-
|
|
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({
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
/**
|
|
1680
|
-
|
|
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
|
-
/**
|
|
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,
|
|
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 };
|