@ai-matrx/records-ui 0.6.0 → 0.7.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 +43 -0
- package/dist/index.cjs +80 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -2
- package/dist/index.d.ts +44 -2
- package/dist/index.js +96 -34
- package/dist/index.js.map +1 -1
- package/package.json +8 -6
package/dist/index.d.cts
CHANGED
|
@@ -463,9 +463,14 @@ interface TableSettingsProps {
|
|
|
463
463
|
proposals?: FieldProposalRow[] | undefined;
|
|
464
464
|
onAcceptProposal?: ((proposal: FieldProposalRow) => void) | undefined;
|
|
465
465
|
onRejectProposal?: ((proposal: FieldProposalRow) => void) | undefined;
|
|
466
|
+
/**
|
|
467
|
+
* SCR-3's fourth verb. Called after the store has accepted the delete, so the
|
|
468
|
+
* host can leave a page that is now about a table nobody can open.
|
|
469
|
+
*/
|
|
470
|
+
onDeleted?: (() => void) | undefined;
|
|
466
471
|
className?: string | undefined;
|
|
467
472
|
}
|
|
468
|
-
declare function TableSettings({ tableId, proposals, onAcceptProposal, onRejectProposal, className, }: TableSettingsProps): react.JSX.Element;
|
|
473
|
+
declare function TableSettings({ tableId, proposals, onAcceptProposal, onRejectProposal, onDeleted, className, }: TableSettingsProps): react.JSX.Element;
|
|
469
474
|
|
|
470
475
|
interface PeekProps {
|
|
471
476
|
tableId: Uuid;
|
|
@@ -579,6 +584,31 @@ interface UseSystemTableState {
|
|
|
579
584
|
}
|
|
580
585
|
/** The hook every package-owned component opens with. */
|
|
581
586
|
declare function useSystemTable(spec: SystemTableSpec): UseSystemTableState;
|
|
587
|
+
/**
|
|
588
|
+
* THE VERSION OF THE ONE RECORD BEING EDITED.
|
|
589
|
+
*
|
|
590
|
+
* The read door (`custom.read_records`) answers documents, never versions —
|
|
591
|
+
* deliberately, because a version is a fact about the row and not about what
|
|
592
|
+
* this reader may see. A screen that saves optimistically still needs the
|
|
593
|
+
* version it LOADED, so it reads it here, for the one record it is editing and
|
|
594
|
+
* never for a list, through `custom.io_revisions`.
|
|
595
|
+
*
|
|
596
|
+
* `null` is an honest answer: the save then carries no expected version and is
|
|
597
|
+
* the store's ordinary last-writer-wins write. It is never a guess.
|
|
598
|
+
*/
|
|
599
|
+
/** What `useRecordVersion` hands a screen that writes the record more than once. */
|
|
600
|
+
interface TrackedVersion {
|
|
601
|
+
/** The version this screen is writing against, or `null` when none was read. */
|
|
602
|
+
version: number | null;
|
|
603
|
+
/**
|
|
604
|
+
* TELL IT THE STORE MOVED. Every successful write answers the record's NEW
|
|
605
|
+
* version; a screen that does not hand it back here will write against the
|
|
606
|
+
* old one next time and the store will — correctly — refuse it as a conflict
|
|
607
|
+
* with somebody who turns out to be the same person. Measured 2026-09-19:
|
|
608
|
+
* switching a saved view's layout twice in a row did exactly that.
|
|
609
|
+
*/
|
|
610
|
+
note: (version: number) => void;
|
|
611
|
+
}
|
|
582
612
|
|
|
583
613
|
/** The four ways one saved view can be looked at (SCR-6). */
|
|
584
614
|
declare const VIEW_LAYOUTS: readonly ["grid", "kanban", "calendar", "gallery"];
|
|
@@ -1369,6 +1399,18 @@ type DeclareResult = {
|
|
|
1369
1399
|
/** `My Sales Pipeline` → `my_sales_pipeline`. A token, never a sentence. */
|
|
1370
1400
|
declare function tokenFor(name: string): string;
|
|
1371
1401
|
/** The one Field a Table cannot be declared without: something to call a record. */
|
|
1402
|
+
/**
|
|
1403
|
+
* WHY THE FIRST FIELD IS NOT REQUIRED.
|
|
1404
|
+
*
|
|
1405
|
+
* It was, and the cost showed up the moment the grid could add a row: "New
|
|
1406
|
+
* record" writes an empty record and puts you in the first cell, and the store
|
|
1407
|
+
* correctly refused every one of them — `REC-51: Title is required` — so the
|
|
1408
|
+
* one gesture that makes a grid feel like a grid never worked on a table a
|
|
1409
|
+
* person had just made. A title is what makes a record a CHIP (REC-2), which is
|
|
1410
|
+
* a fact about how it is shown, not a promise it can never be written without;
|
|
1411
|
+
* an organization that wants it demanded says so in the field editor, and the
|
|
1412
|
+
* store then enforces it for everyone.
|
|
1413
|
+
*/
|
|
1372
1414
|
declare const DEFAULT_FIELDS: NewFieldSpec[];
|
|
1373
1415
|
declare function declareTable(client: RecordsClient, spec: NewTableSpec): Promise<DeclareResult>;
|
|
1374
1416
|
/** Write Field records for an existing Table. Used by the create path and by import. */
|
|
@@ -1380,4 +1422,4 @@ declare function addFields(client: RecordsClient, tableId: Uuid$1, fields: NewFi
|
|
|
1380
1422
|
error: RecordsError;
|
|
1381
1423
|
}>;
|
|
1382
1424
|
|
|
1383
|
-
export { ACTION_KINDS, ACTION_TABLE, ActionInbox, type ActionInboxProps, type ActionKind, BookingSlots, type BookingSlotsProps, CAPTURE_MODES, CHART_KINDS, CHART_KIND_LABEL, CHART_NEEDS, CHECKLIST_TABLE, COMMENT_TABLE, 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, FORM_FLOWS, FORM_TABLE, FieldControl, FieldEditor, type FieldEditorControlProps, type FieldEditorProps, FieldLabel, type FieldProposalRow, FormBuilder, type FormBuilderProps, type FormFlow, type FormQuestionSpec, FormRunner, type FormRunnerProps, type FormSpec, type FormTheme, 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, NO_CHAT_REASON, NO_ENRICH_REASON, NO_MEMBERS_REASON, NO_RIGHTS, NO_SAVED_VIEWS_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, PortalShell, type PortalShellProps, type ProposalOutcome, ProposalRow, type ProposalRowProps, type ProposedChange, ProvenanceBadge, PublicViewPage, type PublicViewPageProps, type QueuedAction, type QueuedActionSpec, RecordChat, type RecordChatContext, type RecordChatEntry, type RecordChatProps, type RecordChatWithheld, RecordChip, RecordForm, type RecordFormProps, RecordsMount, type RecordsMountProps, type RecordsUiHost, RecordsUiProvider, RefusalLine, RefusalNotice, RelationPicker, type RelationPickerProps, SERIES_COLORS, STORE_DECIDES_REASON, type SavedDashboard, type SavedForm, type SavedView, type SavedViewSpec, 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 UseSystemTableState, VIEW_LAYOUTS, VIEW_TABLE, ViewBar, type ViewBarProps, type ViewLayout, type ViewSort, ViewSwitcher, type ViewSwitcherProps, actionDocument, addFields, bodyForReading, bodyFromKeys, columnForField, dashboardDocument, dashboardFromRecord, declareTable, editorKindFor, ensureSystemTable, envelopeFor, fieldIsEditable, fieldName, fieldToken, fieldTypeLabel, formDocument, formFromRecord, groupLabel, humanize, isSignatureField, laneFor, memberName, personActor, personRecordForMember, recordName, recordsDataSource, renderValue, rowName, scalarText, storeDecidesRights, submissionStamp, tableName, tokenFor, useEmbedHandshake, useGridEditing, useRecordsUi, useSystemTable, useTableRights, useViewRecords, viewDocument, viewFromRecord, viewPatchDocument };
|
|
1425
|
+
export { ACTION_KINDS, ACTION_TABLE, ActionInbox, type ActionInboxProps, type ActionKind, BookingSlots, type BookingSlotsProps, CAPTURE_MODES, CHART_KINDS, CHART_KIND_LABEL, CHART_NEEDS, CHECKLIST_TABLE, COMMENT_TABLE, 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, FORM_FLOWS, FORM_TABLE, FieldControl, FieldEditor, type FieldEditorControlProps, type FieldEditorProps, FieldLabel, type FieldProposalRow, FormBuilder, type FormBuilderProps, type FormFlow, type FormQuestionSpec, FormRunner, type FormRunnerProps, type FormSpec, type FormTheme, 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, NO_CHAT_REASON, NO_ENRICH_REASON, NO_MEMBERS_REASON, NO_RIGHTS, NO_SAVED_VIEWS_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, PortalShell, type PortalShellProps, type ProposalOutcome, ProposalRow, type ProposalRowProps, type ProposedChange, ProvenanceBadge, PublicViewPage, type PublicViewPageProps, type QueuedAction, type QueuedActionSpec, RecordChat, type RecordChatContext, type RecordChatEntry, type RecordChatProps, type RecordChatWithheld, RecordChip, RecordForm, type RecordFormProps, RecordsMount, type RecordsMountProps, type RecordsUiHost, RecordsUiProvider, RefusalLine, RefusalNotice, RelationPicker, type RelationPickerProps, SERIES_COLORS, STORE_DECIDES_REASON, type SavedDashboard, type SavedForm, type SavedView, type SavedViewSpec, 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, actionDocument, addFields, bodyForReading, bodyFromKeys, columnForField, dashboardDocument, dashboardFromRecord, declareTable, editorKindFor, ensureSystemTable, envelopeFor, fieldIsEditable, fieldName, fieldToken, fieldTypeLabel, formDocument, formFromRecord, groupLabel, humanize, isSignatureField, laneFor, memberName, personActor, personRecordForMember, recordName, recordsDataSource, renderValue, rowName, scalarText, storeDecidesRights, submissionStamp, tableName, tokenFor, useEmbedHandshake, useGridEditing, useRecordsUi, useSystemTable, useTableRights, useViewRecords, viewDocument, viewFromRecord, viewPatchDocument };
|
package/dist/index.d.ts
CHANGED
|
@@ -463,9 +463,14 @@ interface TableSettingsProps {
|
|
|
463
463
|
proposals?: FieldProposalRow[] | undefined;
|
|
464
464
|
onAcceptProposal?: ((proposal: FieldProposalRow) => void) | undefined;
|
|
465
465
|
onRejectProposal?: ((proposal: FieldProposalRow) => void) | undefined;
|
|
466
|
+
/**
|
|
467
|
+
* SCR-3's fourth verb. Called after the store has accepted the delete, so the
|
|
468
|
+
* host can leave a page that is now about a table nobody can open.
|
|
469
|
+
*/
|
|
470
|
+
onDeleted?: (() => void) | undefined;
|
|
466
471
|
className?: string | undefined;
|
|
467
472
|
}
|
|
468
|
-
declare function TableSettings({ tableId, proposals, onAcceptProposal, onRejectProposal, className, }: TableSettingsProps): react.JSX.Element;
|
|
473
|
+
declare function TableSettings({ tableId, proposals, onAcceptProposal, onRejectProposal, onDeleted, className, }: TableSettingsProps): react.JSX.Element;
|
|
469
474
|
|
|
470
475
|
interface PeekProps {
|
|
471
476
|
tableId: Uuid;
|
|
@@ -579,6 +584,31 @@ interface UseSystemTableState {
|
|
|
579
584
|
}
|
|
580
585
|
/** The hook every package-owned component opens with. */
|
|
581
586
|
declare function useSystemTable(spec: SystemTableSpec): UseSystemTableState;
|
|
587
|
+
/**
|
|
588
|
+
* THE VERSION OF THE ONE RECORD BEING EDITED.
|
|
589
|
+
*
|
|
590
|
+
* The read door (`custom.read_records`) answers documents, never versions —
|
|
591
|
+
* deliberately, because a version is a fact about the row and not about what
|
|
592
|
+
* this reader may see. A screen that saves optimistically still needs the
|
|
593
|
+
* version it LOADED, so it reads it here, for the one record it is editing and
|
|
594
|
+
* never for a list, through `custom.io_revisions`.
|
|
595
|
+
*
|
|
596
|
+
* `null` is an honest answer: the save then carries no expected version and is
|
|
597
|
+
* the store's ordinary last-writer-wins write. It is never a guess.
|
|
598
|
+
*/
|
|
599
|
+
/** What `useRecordVersion` hands a screen that writes the record more than once. */
|
|
600
|
+
interface TrackedVersion {
|
|
601
|
+
/** The version this screen is writing against, or `null` when none was read. */
|
|
602
|
+
version: number | null;
|
|
603
|
+
/**
|
|
604
|
+
* TELL IT THE STORE MOVED. Every successful write answers the record's NEW
|
|
605
|
+
* version; a screen that does not hand it back here will write against the
|
|
606
|
+
* old one next time and the store will — correctly — refuse it as a conflict
|
|
607
|
+
* with somebody who turns out to be the same person. Measured 2026-09-19:
|
|
608
|
+
* switching a saved view's layout twice in a row did exactly that.
|
|
609
|
+
*/
|
|
610
|
+
note: (version: number) => void;
|
|
611
|
+
}
|
|
582
612
|
|
|
583
613
|
/** The four ways one saved view can be looked at (SCR-6). */
|
|
584
614
|
declare const VIEW_LAYOUTS: readonly ["grid", "kanban", "calendar", "gallery"];
|
|
@@ -1369,6 +1399,18 @@ type DeclareResult = {
|
|
|
1369
1399
|
/** `My Sales Pipeline` → `my_sales_pipeline`. A token, never a sentence. */
|
|
1370
1400
|
declare function tokenFor(name: string): string;
|
|
1371
1401
|
/** The one Field a Table cannot be declared without: something to call a record. */
|
|
1402
|
+
/**
|
|
1403
|
+
* WHY THE FIRST FIELD IS NOT REQUIRED.
|
|
1404
|
+
*
|
|
1405
|
+
* It was, and the cost showed up the moment the grid could add a row: "New
|
|
1406
|
+
* record" writes an empty record and puts you in the first cell, and the store
|
|
1407
|
+
* correctly refused every one of them — `REC-51: Title is required` — so the
|
|
1408
|
+
* one gesture that makes a grid feel like a grid never worked on a table a
|
|
1409
|
+
* person had just made. A title is what makes a record a CHIP (REC-2), which is
|
|
1410
|
+
* a fact about how it is shown, not a promise it can never be written without;
|
|
1411
|
+
* an organization that wants it demanded says so in the field editor, and the
|
|
1412
|
+
* store then enforces it for everyone.
|
|
1413
|
+
*/
|
|
1372
1414
|
declare const DEFAULT_FIELDS: NewFieldSpec[];
|
|
1373
1415
|
declare function declareTable(client: RecordsClient, spec: NewTableSpec): Promise<DeclareResult>;
|
|
1374
1416
|
/** Write Field records for an existing Table. Used by the create path and by import. */
|
|
@@ -1380,4 +1422,4 @@ declare function addFields(client: RecordsClient, tableId: Uuid$1, fields: NewFi
|
|
|
1380
1422
|
error: RecordsError;
|
|
1381
1423
|
}>;
|
|
1382
1424
|
|
|
1383
|
-
export { ACTION_KINDS, ACTION_TABLE, ActionInbox, type ActionInboxProps, type ActionKind, BookingSlots, type BookingSlotsProps, CAPTURE_MODES, CHART_KINDS, CHART_KIND_LABEL, CHART_NEEDS, CHECKLIST_TABLE, COMMENT_TABLE, 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, FORM_FLOWS, FORM_TABLE, FieldControl, FieldEditor, type FieldEditorControlProps, type FieldEditorProps, FieldLabel, type FieldProposalRow, FormBuilder, type FormBuilderProps, type FormFlow, type FormQuestionSpec, FormRunner, type FormRunnerProps, type FormSpec, type FormTheme, 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, NO_CHAT_REASON, NO_ENRICH_REASON, NO_MEMBERS_REASON, NO_RIGHTS, NO_SAVED_VIEWS_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, PortalShell, type PortalShellProps, type ProposalOutcome, ProposalRow, type ProposalRowProps, type ProposedChange, ProvenanceBadge, PublicViewPage, type PublicViewPageProps, type QueuedAction, type QueuedActionSpec, RecordChat, type RecordChatContext, type RecordChatEntry, type RecordChatProps, type RecordChatWithheld, RecordChip, RecordForm, type RecordFormProps, RecordsMount, type RecordsMountProps, type RecordsUiHost, RecordsUiProvider, RefusalLine, RefusalNotice, RelationPicker, type RelationPickerProps, SERIES_COLORS, STORE_DECIDES_REASON, type SavedDashboard, type SavedForm, type SavedView, type SavedViewSpec, 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 UseSystemTableState, VIEW_LAYOUTS, VIEW_TABLE, ViewBar, type ViewBarProps, type ViewLayout, type ViewSort, ViewSwitcher, type ViewSwitcherProps, actionDocument, addFields, bodyForReading, bodyFromKeys, columnForField, dashboardDocument, dashboardFromRecord, declareTable, editorKindFor, ensureSystemTable, envelopeFor, fieldIsEditable, fieldName, fieldToken, fieldTypeLabel, formDocument, formFromRecord, groupLabel, humanize, isSignatureField, laneFor, memberName, personActor, personRecordForMember, recordName, recordsDataSource, renderValue, rowName, scalarText, storeDecidesRights, submissionStamp, tableName, tokenFor, useEmbedHandshake, useGridEditing, useRecordsUi, useSystemTable, useTableRights, useViewRecords, viewDocument, viewFromRecord, viewPatchDocument };
|
|
1425
|
+
export { ACTION_KINDS, ACTION_TABLE, ActionInbox, type ActionInboxProps, type ActionKind, BookingSlots, type BookingSlotsProps, CAPTURE_MODES, CHART_KINDS, CHART_KIND_LABEL, CHART_NEEDS, CHECKLIST_TABLE, COMMENT_TABLE, 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, FORM_FLOWS, FORM_TABLE, FieldControl, FieldEditor, type FieldEditorControlProps, type FieldEditorProps, FieldLabel, type FieldProposalRow, FormBuilder, type FormBuilderProps, type FormFlow, type FormQuestionSpec, FormRunner, type FormRunnerProps, type FormSpec, type FormTheme, 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, NO_CHAT_REASON, NO_ENRICH_REASON, NO_MEMBERS_REASON, NO_RIGHTS, NO_SAVED_VIEWS_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, PortalShell, type PortalShellProps, type ProposalOutcome, ProposalRow, type ProposalRowProps, type ProposedChange, ProvenanceBadge, PublicViewPage, type PublicViewPageProps, type QueuedAction, type QueuedActionSpec, RecordChat, type RecordChatContext, type RecordChatEntry, type RecordChatProps, type RecordChatWithheld, RecordChip, RecordForm, type RecordFormProps, RecordsMount, type RecordsMountProps, type RecordsUiHost, RecordsUiProvider, RefusalLine, RefusalNotice, RelationPicker, type RelationPickerProps, SERIES_COLORS, STORE_DECIDES_REASON, type SavedDashboard, type SavedForm, type SavedView, type SavedViewSpec, 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, actionDocument, addFields, bodyForReading, bodyFromKeys, columnForField, dashboardDocument, dashboardFromRecord, declareTable, editorKindFor, ensureSystemTable, envelopeFor, fieldIsEditable, fieldName, fieldToken, fieldTypeLabel, formDocument, formFromRecord, groupLabel, humanize, isSignatureField, laneFor, memberName, personActor, personRecordForMember, recordName, recordsDataSource, renderValue, rowName, scalarText, storeDecidesRights, submissionStamp, tableName, tokenFor, useEmbedHandshake, useGridEditing, useRecordsUi, useSystemTable, useTableRights, useViewRecords, viewDocument, viewFromRecord, viewPatchDocument };
|
package/dist/index.js
CHANGED
|
@@ -812,6 +812,7 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite }) {
|
|
|
812
812
|
const [rowError, setRowError] = useState4(null);
|
|
813
813
|
const [busy, setBusy] = useState4(false);
|
|
814
814
|
const versions = useRef(/* @__PURE__ */ new Map());
|
|
815
|
+
const queues = useRef(/* @__PURE__ */ new Map());
|
|
815
816
|
const editable = useMemo4(() => fields.filter(fieldIsEditable), [fields]);
|
|
816
817
|
const order = useMemo4(() => editable.map((f) => f.key), [editable]);
|
|
817
818
|
const rowIds = useMemo4(() => rows.map((r) => r.id), [rows]);
|
|
@@ -845,7 +846,7 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite }) {
|
|
|
845
846
|
[canWrite, client]
|
|
846
847
|
);
|
|
847
848
|
const cancel = useCallback2(() => setEditing(null), []);
|
|
848
|
-
const
|
|
849
|
+
const writeCellNow = useCallback2(
|
|
849
850
|
async (rowId, key, value2) => {
|
|
850
851
|
const id = cellKey(rowId, key);
|
|
851
852
|
setOptimistic((held) => ({ ...held, [id]: value2 }));
|
|
@@ -889,6 +890,22 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite }) {
|
|
|
889
890
|
},
|
|
890
891
|
[client, reload]
|
|
891
892
|
);
|
|
893
|
+
const writeCell = useCallback2(
|
|
894
|
+
(rowId, key, value2) => {
|
|
895
|
+
const behind = queues.current.get(rowId) ?? Promise.resolve();
|
|
896
|
+
const next = behind.then(() => writeCellNow(rowId, key, value2));
|
|
897
|
+
queues.current.set(
|
|
898
|
+
rowId,
|
|
899
|
+
next.then(
|
|
900
|
+
() => void 0,
|
|
901
|
+
() => void 0
|
|
902
|
+
)
|
|
903
|
+
);
|
|
904
|
+
return next;
|
|
905
|
+
},
|
|
906
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
907
|
+
[client, reload]
|
|
908
|
+
);
|
|
892
909
|
const commit = useCallback2(
|
|
893
910
|
(value2, move = null) => {
|
|
894
911
|
const open = editing;
|
|
@@ -1097,10 +1114,16 @@ function OpenCell({
|
|
|
1097
1114
|
const [draft, setDraft] = useState4(value2);
|
|
1098
1115
|
const multiline = editorKindFor(field) === "long_text";
|
|
1099
1116
|
const blurCommits = closesOnBlur(field);
|
|
1117
|
+
const done = useRef(false);
|
|
1118
|
+
const once = (run) => {
|
|
1119
|
+
if (done.current) return;
|
|
1120
|
+
done.current = true;
|
|
1121
|
+
run();
|
|
1122
|
+
};
|
|
1100
1123
|
const blur = blurCommits ? {
|
|
1101
1124
|
onBlur: (event) => {
|
|
1102
1125
|
if (event.currentTarget.contains(event.relatedTarget)) return;
|
|
1103
|
-
onCommit(draft, null);
|
|
1126
|
+
once(() => onCommit(draft, null));
|
|
1104
1127
|
}
|
|
1105
1128
|
} : {};
|
|
1106
1129
|
return /* @__PURE__ */ jsxs5(
|
|
@@ -1117,27 +1140,27 @@ function OpenCell({
|
|
|
1117
1140
|
if (event.key === "Escape") {
|
|
1118
1141
|
event.preventDefault();
|
|
1119
1142
|
event.stopPropagation();
|
|
1120
|
-
onCancel
|
|
1143
|
+
once(onCancel);
|
|
1121
1144
|
return;
|
|
1122
1145
|
}
|
|
1123
1146
|
if (event.key === "Tab") {
|
|
1124
1147
|
event.preventDefault();
|
|
1125
1148
|
event.stopPropagation();
|
|
1126
|
-
onCommit(draft, event.shiftKey ? "previous" : "next");
|
|
1149
|
+
once(() => onCommit(draft, event.shiftKey ? "previous" : "next"));
|
|
1127
1150
|
return;
|
|
1128
1151
|
}
|
|
1129
1152
|
if (event.key === "Enter" && (!multiline || event.metaKey || event.ctrlKey)) {
|
|
1130
1153
|
event.preventDefault();
|
|
1131
1154
|
event.stopPropagation();
|
|
1132
|
-
onCommit(draft, null);
|
|
1155
|
+
once(() => onCommit(draft, null));
|
|
1133
1156
|
}
|
|
1134
1157
|
},
|
|
1135
1158
|
...blur,
|
|
1136
1159
|
children: [
|
|
1137
1160
|
/* @__PURE__ */ jsx7(FieldControl, { field, value: draft, onChange: setDraft, id: `cell-${field.id}` }),
|
|
1138
1161
|
blurCommits ? /* @__PURE__ */ jsx7("span", { className: "text-[10px] text-muted-foreground", children: multiline ? "\u2318\u23CE saves \xB7 Esc cancels \xB7 Tab next" : "\u23CE saves \xB7 Esc cancels \xB7 Tab next" }) : /* @__PURE__ */ jsxs5("span", { className: "flex items-center gap-1", children: [
|
|
1139
|
-
/* @__PURE__ */ jsx7(Button4, { size: "sm", onClick: () => onCommit(draft, null), children: "Save" }),
|
|
1140
|
-
/* @__PURE__ */ jsx7(Button4, { size: "sm", variant: "ghost", onClick: onCancel, children: "Cancel" })
|
|
1162
|
+
/* @__PURE__ */ jsx7(Button4, { size: "sm", onClick: () => once(() => onCommit(draft, null)), children: "Save" }),
|
|
1163
|
+
/* @__PURE__ */ jsx7(Button4, { size: "sm", variant: "ghost", onClick: () => once(onCancel), children: "Cancel" })
|
|
1141
1164
|
] })
|
|
1142
1165
|
]
|
|
1143
1166
|
}
|
|
@@ -1755,7 +1778,7 @@ function useRecordVersion(recordId) {
|
|
|
1755
1778
|
cancelled = true;
|
|
1756
1779
|
};
|
|
1757
1780
|
}, [client, recordId]);
|
|
1758
|
-
return version;
|
|
1781
|
+
return { version, note: setVersion };
|
|
1759
1782
|
}
|
|
1760
1783
|
|
|
1761
1784
|
// src/RecordForm.tsx
|
|
@@ -1774,7 +1797,8 @@ function RecordForm({
|
|
|
1774
1797
|
const mutation = useRecordMutation2();
|
|
1775
1798
|
const [draft, setDraft] = useState9({});
|
|
1776
1799
|
const [touched, setTouched] = useState9(false);
|
|
1777
|
-
const
|
|
1800
|
+
const loaded = useRecordVersion(recordId ?? null);
|
|
1801
|
+
const loadedVersion = loaded.version;
|
|
1778
1802
|
useEffect5(() => {
|
|
1779
1803
|
const document3 = existing.data?.document;
|
|
1780
1804
|
if (document3) setDraft({ ...document3 });
|
|
@@ -1803,6 +1827,7 @@ function RecordForm({
|
|
|
1803
1827
|
...version === null ? {} : { expectedVersion: version }
|
|
1804
1828
|
});
|
|
1805
1829
|
if (moved !== null) {
|
|
1830
|
+
loaded.note(moved);
|
|
1806
1831
|
host.notify?.success("Saved");
|
|
1807
1832
|
existing.reload();
|
|
1808
1833
|
onSaved?.(recordId);
|
|
@@ -2169,12 +2194,13 @@ var FIELD_KERNEL = KERNEL_TABLES2.find((t) => t.name === "Field").id;
|
|
|
2169
2194
|
import { useState as useState12 } from "react";
|
|
2170
2195
|
import { useFields as useFields6, useRecordMutation as useRecordMutation4, useTable as useTable5 } from "@ai-matrx/records/react";
|
|
2171
2196
|
import { Badge as Badge4, Button as Button11, Separator as Separator5, cn as cn13 } from "@ai-matrx/design-system";
|
|
2172
|
-
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2197
|
+
import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2173
2198
|
function TableSettings({
|
|
2174
2199
|
tableId,
|
|
2175
2200
|
proposals,
|
|
2176
2201
|
onAcceptProposal,
|
|
2177
2202
|
onRejectProposal,
|
|
2203
|
+
onDeleted,
|
|
2178
2204
|
className
|
|
2179
2205
|
}) {
|
|
2180
2206
|
const table = useTable5(tableId);
|
|
@@ -2182,6 +2208,7 @@ function TableSettings({
|
|
|
2182
2208
|
const rights = useTableRights(table.data);
|
|
2183
2209
|
const mutation = useRecordMutation4();
|
|
2184
2210
|
const [editing, setEditing] = useState12(null);
|
|
2211
|
+
const [askingToDelete, setAskingToDelete] = useState12(false);
|
|
2185
2212
|
if (table.error) return /* @__PURE__ */ jsx14(RefusalNotice, { error: table.error, className });
|
|
2186
2213
|
if (fields.error) return /* @__PURE__ */ jsx14(RefusalNotice, { error: fields.error, className });
|
|
2187
2214
|
if (!rights.admin) return /* @__PURE__ */ jsx14("p", { className: cn13("text-xs text-muted-foreground", className), children: rights.reason });
|
|
@@ -2198,6 +2225,11 @@ function TableSettings({
|
|
|
2198
2225
|
await mutation.remove({ record_id: field.id });
|
|
2199
2226
|
fields.reload();
|
|
2200
2227
|
};
|
|
2228
|
+
const deleteTable = async () => {
|
|
2229
|
+
const gone = await mutation.remove({ record_id: tableId });
|
|
2230
|
+
setAskingToDelete(false);
|
|
2231
|
+
if (gone !== null) onDeleted?.();
|
|
2232
|
+
};
|
|
2201
2233
|
if (editing) {
|
|
2202
2234
|
return /* @__PURE__ */ jsx14(
|
|
2203
2235
|
FieldEditor,
|
|
@@ -2273,7 +2305,28 @@ function TableSettings({
|
|
|
2273
2305
|
/* @__PURE__ */ jsx14(Badge4, { variant: "secondary", className: "text-[10px] font-normal", children: proposal.proposed_by }),
|
|
2274
2306
|
/* @__PURE__ */ jsx14(Button11, { size: "sm", variant: "outline", onClick: () => onAcceptProposal?.(proposal), children: "Accept" }),
|
|
2275
2307
|
/* @__PURE__ */ jsx14(Button11, { size: "sm", variant: "ghost", onClick: () => onRejectProposal?.(proposal), children: "Reject" })
|
|
2276
|
-
] }, proposal.id)) })
|
|
2308
|
+
] }, proposal.id)) }),
|
|
2309
|
+
/* @__PURE__ */ jsx14(Separator5, {}),
|
|
2310
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-1", children: [
|
|
2311
|
+
/* @__PURE__ */ jsx14("span", { className: "font-medium", children: "This table" }),
|
|
2312
|
+
askingToDelete ? /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
2313
|
+
/* @__PURE__ */ jsxs12("p", { className: "text-muted-foreground", children: [
|
|
2314
|
+
"Deleting ",
|
|
2315
|
+
table.data ? tableName(table.data) : "this table",
|
|
2316
|
+
" takes it out of everyone's list, with its ",
|
|
2317
|
+
rows.length,
|
|
2318
|
+
" field",
|
|
2319
|
+
rows.length === 1 ? "" : "s",
|
|
2320
|
+
" and every record in it.",
|
|
2321
|
+
table.data?.retention_days ? ` The store keeps them for ${table.data.retention_days} days, so it can still be restored.` : " The store keeps them, so it can still be restored."
|
|
2322
|
+
] }),
|
|
2323
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex gap-1", children: [
|
|
2324
|
+
/* @__PURE__ */ jsx14(Button11, { size: "sm", variant: "destructive", disabled: mutation.saving, onClick: () => void deleteTable(), children: mutation.saving ? "Deleting\u2026" : "Delete this table" }),
|
|
2325
|
+
/* @__PURE__ */ jsx14(Button11, { size: "sm", variant: "ghost", onClick: () => setAskingToDelete(false), children: "Keep it" })
|
|
2326
|
+
] })
|
|
2327
|
+
] }) : /* @__PURE__ */ jsx14("div", { children: /* @__PURE__ */ jsx14(Button11, { size: "sm", variant: "outline", onClick: () => setAskingToDelete(true), children: "Delete this table" }) }),
|
|
2328
|
+
mutation.error ? /* @__PURE__ */ jsx14(RefusalNotice, { error: mutation.error }) : null
|
|
2329
|
+
] })
|
|
2277
2330
|
] });
|
|
2278
2331
|
}
|
|
2279
2332
|
|
|
@@ -2282,7 +2335,7 @@ import { useState as useState13 } from "react";
|
|
|
2282
2335
|
import { useFields as useFields7, useRecord as useRecord3, useTable as useTable6 } from "@ai-matrx/records/react";
|
|
2283
2336
|
import { AlchemyMenu as AlchemyMenu2 } from "@ai-matrx/alchemy/react";
|
|
2284
2337
|
import { Button as Button12, Separator as Separator6, Skeleton as Skeleton2, cn as cn14 } from "@ai-matrx/design-system";
|
|
2285
|
-
import { Fragment as
|
|
2338
|
+
import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2286
2339
|
function Peek({ tableId, recordId, onClose, className }) {
|
|
2287
2340
|
const table = useTable6(tableId);
|
|
2288
2341
|
const fields = useFields7(tableId);
|
|
@@ -2331,7 +2384,7 @@ function Peek({ tableId, recordId, onClose, className }) {
|
|
|
2331
2384
|
] }),
|
|
2332
2385
|
/* @__PURE__ */ jsx15("dd", { className: "min-w-0", children: renderValue(field, document2?.[field.key], document2) })
|
|
2333
2386
|
] }, field.id)) }),
|
|
2334
|
-
record.data?.computed?.length ? /* @__PURE__ */ jsxs13(
|
|
2387
|
+
record.data?.computed?.length ? /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
2335
2388
|
/* @__PURE__ */ jsx15(Separator6, {}),
|
|
2336
2389
|
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1", children: [
|
|
2337
2390
|
/* @__PURE__ */ jsx15("span", { className: "font-medium", children: "Worked out by the system" }),
|
|
@@ -3553,7 +3606,7 @@ import { useCallback as useCallback8, useEffect as useEffect11, useMemo as useMe
|
|
|
3553
3606
|
import { useFields as useFields10, useRecordsClient as useRecordsClient12 } from "@ai-matrx/records/react";
|
|
3554
3607
|
import { doorExists, DOORS } from "@ai-matrx/records/core";
|
|
3555
3608
|
import { Button as Button19, Progress, Skeleton as Skeleton8, cn as cn21 } from "@ai-matrx/design-system";
|
|
3556
|
-
import { Fragment as
|
|
3609
|
+
import { Fragment as Fragment5, jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3557
3610
|
function FormRunner({ form, preview = false, onSubmitted, className }) {
|
|
3558
3611
|
const client = useRecordsClient12();
|
|
3559
3612
|
const host = useRecordsUi();
|
|
@@ -3741,7 +3794,7 @@ function Question({
|
|
|
3741
3794
|
return /* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-1.5", children: [
|
|
3742
3795
|
/* @__PURE__ */ jsx22(FieldLabel, { field: { ...field, label: question.ask, required: question.required }, htmlFor: id }),
|
|
3743
3796
|
question.help ? /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: question.help }) : null,
|
|
3744
|
-
isAttachment && !upload ? /* @__PURE__ */ jsx22("p", { className: "rounded border border-dashed px-2 py-1 text-xs text-muted-foreground", children: NO_UPLOAD_REASON }) : isAttachment ? /* @__PURE__ */ jsxs20(
|
|
3797
|
+
isAttachment && !upload ? /* @__PURE__ */ jsx22("p", { className: "rounded border border-dashed px-2 py-1 text-xs text-muted-foreground", children: NO_UPLOAD_REASON }) : isAttachment ? /* @__PURE__ */ jsxs20(Fragment5, { children: [
|
|
3745
3798
|
/* @__PURE__ */ jsx22(
|
|
3746
3799
|
"input",
|
|
3747
3800
|
{
|
|
@@ -3766,7 +3819,7 @@ function Question({
|
|
|
3766
3819
|
}
|
|
3767
3820
|
|
|
3768
3821
|
// src/FormBuilder.tsx
|
|
3769
|
-
import { Fragment as
|
|
3822
|
+
import { Fragment as Fragment6, jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3770
3823
|
var CONDITION_OPS = [
|
|
3771
3824
|
{ op: "eq", label: "is" },
|
|
3772
3825
|
{ op: "ne", label: "is not" },
|
|
@@ -3787,7 +3840,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
|
|
|
3787
3840
|
const [draft, setDraft] = useState21(null);
|
|
3788
3841
|
const [saving, setSaving] = useState21(false);
|
|
3789
3842
|
const [saved, setSaved] = useState21(null);
|
|
3790
|
-
const
|
|
3843
|
+
const loaded = useRecordVersion(activeId);
|
|
3791
3844
|
const formTableId = home.tableId;
|
|
3792
3845
|
const load = useCallback9(async () => {
|
|
3793
3846
|
if (!formTableId) return;
|
|
@@ -3851,13 +3904,14 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
|
|
|
3851
3904
|
record_id: draft.id,
|
|
3852
3905
|
patch: document2,
|
|
3853
3906
|
// The form record's own version: two people editing one form are TOLD.
|
|
3854
|
-
...
|
|
3907
|
+
...loaded.version === null ? {} : { expectedVersion: loaded.version }
|
|
3855
3908
|
});
|
|
3856
3909
|
setSaving(false);
|
|
3857
3910
|
if (!written.ok) {
|
|
3858
3911
|
setError(written.error);
|
|
3859
3912
|
return;
|
|
3860
3913
|
}
|
|
3914
|
+
loaded.note(written.data);
|
|
3861
3915
|
setSaved("Saved.");
|
|
3862
3916
|
await load();
|
|
3863
3917
|
}
|
|
@@ -3913,7 +3967,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
|
|
|
3913
3967
|
/* @__PURE__ */ jsx23(Button20, { size: "sm", disabled: saving || !draft, onClick: () => void save(), children: saving ? "Saving\u2026" : "Save" })
|
|
3914
3968
|
] })
|
|
3915
3969
|
] }),
|
|
3916
|
-
!draft ? /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: 'No form collects into this table yet. "New form" makes one, or an agent writes a whole one with a single record.' }) : /* @__PURE__ */ jsxs21(
|
|
3970
|
+
!draft ? /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: 'No form collects into this table yet. "New form" makes one, or an agent writes a whole one with a single record.' }) : /* @__PURE__ */ jsxs21(Fragment6, { children: [
|
|
3917
3971
|
/* @__PURE__ */ jsxs21("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
3918
3972
|
/* @__PURE__ */ jsxs21("label", { className: "flex flex-col gap-1", children: [
|
|
3919
3973
|
/* @__PURE__ */ jsx23(Label3, { className: "text-xs font-medium", children: "Name" }),
|
|
@@ -4076,7 +4130,7 @@ function Condition({
|
|
|
4076
4130
|
]
|
|
4077
4131
|
}
|
|
4078
4132
|
),
|
|
4079
|
-
onField ? /* @__PURE__ */ jsxs21(
|
|
4133
|
+
onField ? /* @__PURE__ */ jsxs21(Fragment6, { children: [
|
|
4080
4134
|
/* @__PURE__ */ jsx23(
|
|
4081
4135
|
"select",
|
|
4082
4136
|
{
|
|
@@ -4960,7 +5014,7 @@ function DashboardCanvas({ tableId, seed, activeDashboardId, className }) {
|
|
|
4960
5014
|
const [boards, setBoards] = useState27(null);
|
|
4961
5015
|
const [error, setError] = useState27(null);
|
|
4962
5016
|
const [activeId, setActiveId] = useState27(activeDashboardId ?? null);
|
|
4963
|
-
const
|
|
5017
|
+
const loaded = useRecordVersion(activeId);
|
|
4964
5018
|
const boardTableId = home.tableId;
|
|
4965
5019
|
const load = useCallback14(async () => {
|
|
4966
5020
|
if (!boardTableId) return;
|
|
@@ -5006,12 +5060,13 @@ function DashboardCanvas({ tableId, seed, activeDashboardId, className }) {
|
|
|
5006
5060
|
record_id: board2.id,
|
|
5007
5061
|
patch: dashboardDocument({ ...board2, blocks }),
|
|
5008
5062
|
// The dashboard record's own version: two tabs editing one board are TOLD.
|
|
5009
|
-
...
|
|
5063
|
+
...loaded.version === null ? {} : { expectedVersion: loaded.version }
|
|
5010
5064
|
});
|
|
5011
5065
|
if (!updated.ok) {
|
|
5012
5066
|
setError(updated.error);
|
|
5013
5067
|
return;
|
|
5014
5068
|
}
|
|
5069
|
+
loaded.note(updated.data);
|
|
5015
5070
|
await load();
|
|
5016
5071
|
}
|
|
5017
5072
|
async function create() {
|
|
@@ -5876,7 +5931,7 @@ function whenText(at) {
|
|
|
5876
5931
|
import { useCallback as useCallback18, useEffect as useEffect23, useRef as useRef5, useState as useState32 } from "react";
|
|
5877
5932
|
import { useFields as useFields17, useRecordsClient as useRecordsClient24, useTable as useTable19 } from "@ai-matrx/records/react";
|
|
5878
5933
|
import { Button as Button29, Input as Input2, Skeleton as Skeleton20, Textarea as Textarea2, cn as cn33 } from "@ai-matrx/design-system";
|
|
5879
|
-
import { Fragment as
|
|
5934
|
+
import { Fragment as Fragment7, jsx as jsx34, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
5880
5935
|
var CAPTURE_MODES = ["reading", "photo", "voice"];
|
|
5881
5936
|
var IN_MEMORY_QUEUE_REASON = "No capture queue is bound, so anything that cannot be sent right now is held in this page's memory and is lost if the page closes. Bind `captureQueue` on <RecordsUiProvider> with your host's own durable store (IndexedDB in a browser) and a queued capture survives the tab, the reload and the flight. It is said here rather than discovered later.";
|
|
5882
5937
|
function mintClientKey() {
|
|
@@ -6033,7 +6088,7 @@ function CaptureSheet({
|
|
|
6033
6088
|
" ",
|
|
6034
6089
|
/* @__PURE__ */ jsx34("code", { children: "attachmentField" }),
|
|
6035
6090
|
"."
|
|
6036
|
-
] }) : /* @__PURE__ */ jsxs32(
|
|
6091
|
+
] }) : /* @__PURE__ */ jsxs32(Fragment7, { children: [
|
|
6037
6092
|
/* @__PURE__ */ jsx34(
|
|
6038
6093
|
"input",
|
|
6039
6094
|
{
|
|
@@ -6287,7 +6342,7 @@ import { useCallback as useCallback21, useEffect as useEffect26, useState as use
|
|
|
6287
6342
|
import { useRecordsClient as useRecordsClient27 } from "@ai-matrx/records/react";
|
|
6288
6343
|
import { Button as Button31, Input as Input3, Skeleton as Skeleton23, Textarea as Textarea3, cn as cn36 } from "@ai-matrx/design-system";
|
|
6289
6344
|
import { useTable as useTable20 } from "@ai-matrx/records/react";
|
|
6290
|
-
import { Fragment as
|
|
6345
|
+
import { Fragment as Fragment8, jsx as jsx37, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
6291
6346
|
function EmbedFrame({
|
|
6292
6347
|
tableId,
|
|
6293
6348
|
formId,
|
|
@@ -6371,7 +6426,7 @@ function EmbedFrame({
|
|
|
6371
6426
|
" will not pass."
|
|
6372
6427
|
] })
|
|
6373
6428
|
] }),
|
|
6374
|
-
!secret ? /* @__PURE__ */ jsx37(Button31, { size: "sm", className: "self-start", disabled: busy || parsed.length === 0, onClick: () => void issue(), children: busy ? "Issuing\u2026" : "Issue embed" }) : /* @__PURE__ */ jsxs35(
|
|
6429
|
+
!secret ? /* @__PURE__ */ jsx37(Button31, { size: "sm", className: "self-start", disabled: busy || parsed.length === 0, onClick: () => void issue(), children: busy ? "Issuing\u2026" : "Issue embed" }) : /* @__PURE__ */ jsxs35(Fragment8, { children: [
|
|
6375
6430
|
/* @__PURE__ */ jsx37("p", { className: "rounded border px-2 py-1 text-xs text-muted-foreground", children: "Copy this now. Only its digest is stored, so nobody \u2014 including us \u2014 can show it to you again; if it is lost, issue a new one and replace the old." }),
|
|
6376
6431
|
/* @__PURE__ */ jsx37(Textarea3, { "aria-label": "Embed snippet", readOnly: true, rows: 3, className: "font-mono text-[11px]", value: snippet ?? "" }),
|
|
6377
6432
|
/* @__PURE__ */ jsxs35("div", { className: "flex gap-2", children: [
|
|
@@ -6466,7 +6521,7 @@ function tokenFor(name) {
|
|
|
6466
6521
|
return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 48) || "table";
|
|
6467
6522
|
}
|
|
6468
6523
|
var DEFAULT_FIELDS = [
|
|
6469
|
-
{ key: "title", label: "Title", type: "text", sort: 10, required:
|
|
6524
|
+
{ key: "title", label: "Title", type: "text", sort: 10, required: false }
|
|
6470
6525
|
];
|
|
6471
6526
|
async function declareTable(client, spec) {
|
|
6472
6527
|
const fields = spec.fields && spec.fields.length > 0 ? spec.fields : DEFAULT_FIELDS;
|
|
@@ -6536,7 +6591,7 @@ async function addFields(client, tableId, fields) {
|
|
|
6536
6591
|
}
|
|
6537
6592
|
|
|
6538
6593
|
// src/TablesHome.tsx
|
|
6539
|
-
import { Fragment as
|
|
6594
|
+
import { Fragment as Fragment9, jsx as jsx39, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
6540
6595
|
var TABLE_LANES = ["mine", "organization", "system", "community", "app"];
|
|
6541
6596
|
var LANE_TITLE = {
|
|
6542
6597
|
mine: "Mine",
|
|
@@ -6589,7 +6644,7 @@ function TablesHome({ onOpenTable, className }) {
|
|
|
6589
6644
|
[client, name, onOpenTable, tables]
|
|
6590
6645
|
);
|
|
6591
6646
|
return /* @__PURE__ */ jsxs36("div", { className: cn37("flex min-h-0 flex-col gap-4", className), children: [
|
|
6592
|
-
/* @__PURE__ */ jsx39("div", { className: "flex items-center gap-2", children: creating ? /* @__PURE__ */ jsxs36(
|
|
6647
|
+
/* @__PURE__ */ jsx39("div", { className: "flex items-center gap-2", children: creating ? /* @__PURE__ */ jsxs36(Fragment9, { children: [
|
|
6593
6648
|
/* @__PURE__ */ jsx39(
|
|
6594
6649
|
BasicInput8,
|
|
6595
6650
|
{
|
|
@@ -6663,7 +6718,7 @@ function TablesHome({ onOpenTable, className }) {
|
|
|
6663
6718
|
import { useCallback as useCallback23, useState as useState37 } from "react";
|
|
6664
6719
|
import { useRecordsClient as useRecordsClient29, useTable as useTable21 } from "@ai-matrx/records/react";
|
|
6665
6720
|
import { Button as Button33, Separator as Separator7, Skeleton as Skeleton25, cn as cn38 } from "@ai-matrx/design-system";
|
|
6666
|
-
import { Fragment as
|
|
6721
|
+
import { Fragment as Fragment10, jsx as jsx40, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
6667
6722
|
var TABLE_NOT_REACHABLE = "This table is not in the organization you are working in, so there is nothing here to show. Switch to the organization that owns it and open it again \u2014 or it may have been deleted.";
|
|
6668
6723
|
var DEFAULT_VIEW_NAME = "All records";
|
|
6669
6724
|
function defaultView(tableId) {
|
|
@@ -6692,11 +6747,12 @@ function TablePage({
|
|
|
6692
6747
|
setView({ ...current, ...patch });
|
|
6693
6748
|
const document2 = viewPatchDocument(patch);
|
|
6694
6749
|
if (Object.keys(document2).length === 0) return;
|
|
6695
|
-
await client.recordUpdate({
|
|
6750
|
+
const written = await client.recordUpdate({
|
|
6696
6751
|
record_id: current.id,
|
|
6697
6752
|
patch: document2,
|
|
6698
|
-
...viewVersion === null ? {} : { expectedVersion: viewVersion }
|
|
6753
|
+
...viewVersion.version === null ? {} : { expectedVersion: viewVersion.version }
|
|
6699
6754
|
});
|
|
6755
|
+
if (written.ok) viewVersion.note(written.data);
|
|
6700
6756
|
},
|
|
6701
6757
|
[client, view, viewVersion]
|
|
6702
6758
|
);
|
|
@@ -6722,7 +6778,7 @@ function TablePage({
|
|
|
6722
6778
|
}
|
|
6723
6779
|
),
|
|
6724
6780
|
rights.write && view && view.layout !== "grid" ? /* @__PURE__ */ jsx40(Button33, { size: "sm", onClick: () => show("new-record"), children: "New record" }) : null,
|
|
6725
|
-
rights.admin ? /* @__PURE__ */ jsxs37(
|
|
6781
|
+
rights.admin ? /* @__PURE__ */ jsxs37(Fragment10, { children: [
|
|
6726
6782
|
/* @__PURE__ */ jsx40(Button33, { size: "sm", variant: "outline", onClick: () => show("field"), children: "Add field" }),
|
|
6727
6783
|
/* @__PURE__ */ jsx40(Button33, { size: "sm", variant: "ghost", onClick: () => show("settings"), children: "Settings" }),
|
|
6728
6784
|
/* @__PURE__ */ jsx40(Button33, { size: "sm", variant: "ghost", onClick: () => show("import"), children: "Import" })
|
|
@@ -6749,7 +6805,13 @@ function TablePage({
|
|
|
6749
6805
|
] })
|
|
6750
6806
|
] }),
|
|
6751
6807
|
rail === "none" ? null : /* @__PURE__ */ jsxs37("aside", { className: "w-[26rem] shrink-0 overflow-y-auto rounded-md border p-3", children: [
|
|
6752
|
-
rail === "settings" ? /* @__PURE__ */ jsx40(
|
|
6808
|
+
rail === "settings" ? /* @__PURE__ */ jsx40(
|
|
6809
|
+
TableSettings,
|
|
6810
|
+
{
|
|
6811
|
+
tableId,
|
|
6812
|
+
...onLeave ? { onDeleted: onLeave } : {}
|
|
6813
|
+
}
|
|
6814
|
+
) : null,
|
|
6753
6815
|
rail === "inbox" ? /* @__PURE__ */ jsx40(
|
|
6754
6816
|
ActionInbox,
|
|
6755
6817
|
{
|