@rebasepro/cms 0.22.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{CollectionEditorDialog-CUtfS_49.js → CollectionEditorDialog-p5-I-Apu.js} +181 -97
- package/dist/CollectionEditorDialog-p5-I-Apu.js.map +1 -0
- package/dist/{PropertyEditView-BpEbC0Q2.js → PropertyEditView-DDB_X-00.js} +55 -23
- package/dist/PropertyEditView-DDB_X-00.js.map +1 -0
- package/dist/{RouterCollectionsStudioView-EK8Knq5I.js → RouterCollectionsStudioView-SGBV4CMg.js} +34 -10
- package/dist/RouterCollectionsStudioView-SGBV4CMg.js.map +1 -0
- package/dist/{SchemaChangeDialog-BeP0A4MJ.js → SchemaChangeDialog-CcFSXvkK.js} +33 -12
- package/dist/SchemaChangeDialog-CcFSXvkK.js.map +1 -0
- package/dist/collection_editor/_cms_internals.d.ts +3 -1
- package/dist/collection_editor/liveSchemaClient.d.ts +38 -18
- package/dist/collection_editor/relation_kinds.d.ts +11 -0
- package/dist/collection_editor/serializable_types.d.ts +2 -0
- package/dist/collection_editor/types/config_controller.d.ts +11 -0
- package/dist/collection_editor/ui/collection_editor/CollectionStudioView.d.ts +8 -1
- package/dist/collection_editor/useLiveSchemaEditing.d.ts +5 -5
- package/dist/collection_editor/useLocalCollectionsConfigController.d.ts +7 -0
- package/dist/collection_editor_ui.js +5 -5
- package/dist/components/ClearFilterSortButton.d.ts +7 -1
- package/dist/components/CollectionTableBinding/fields/CompactEntityCellField.d.ts +12 -13
- package/dist/components/CollectionTableBinding/fields/TableMultipleRelationField.d.ts +6 -3
- package/dist/components/CollectionTableBinding/fields/TableReferenceField.d.ts +8 -1
- package/dist/components/CollectionTableBinding/fields/TableRelationField.d.ts +8 -1
- package/dist/components/CollectionTableBinding/fields/TableRelationSelectorField.d.ts +13 -3
- package/dist/components/CollectionTableBinding/fields/VirtualTableSelect.d.ts +10 -0
- package/dist/components/CollectionTableBinding/fields/VirtualTableUserSelect.d.ts +10 -0
- package/dist/components/CollectionTableBinding/internal/EntityTableCell.d.ts +21 -0
- package/dist/components/CollectionTableBinding/internal/TableCellOpener.d.ts +45 -0
- package/dist/components/CollectionTableBinding/table_bindings.d.ts +24 -0
- package/dist/components/CollectionViewBinding/CollectionViewActions.d.ts +6 -1
- package/dist/components/CollectionViewBinding/CollectionViewBinding.d.ts +12 -3
- package/dist/components/CollectionViewBinding/FiltersDialog.d.ts +5 -0
- package/dist/components/EditViewBinding.d.ts +7 -1
- package/dist/components/EntityIdentityBar.d.ts +29 -4
- package/dist/components/EntityPreviewBinding.d.ts +8 -1
- package/dist/components/EntityPreviewNesting.d.ts +15 -0
- package/dist/components/NavigationLoadingErrorView.d.ts +16 -0
- package/dist/components/PickerTrigger.d.ts +17 -0
- package/dist/components/ReferenceTable/SelectionTableBinding.d.ts +12 -0
- package/dist/components/RelationSelector.d.ts +24 -7
- package/dist/components/UserSelector.d.ts +8 -1
- package/dist/components/common/ActionMenuLabel.d.ts +15 -0
- package/dist/components/common/default_entity_actions.d.ts +37 -0
- package/dist/data_export/export/additional_fields.d.ts +13 -0
- package/dist/data_export/export/export.d.ts +6 -0
- package/dist/data_import/components/ImportConversionProblems.d.ts +11 -0
- package/dist/data_import/components/index.d.ts +1 -0
- package/dist/data_import/utils/csv.d.ts +3 -2
- package/dist/data_import/utils/data.d.ts +81 -4
- package/dist/data_import/utils/id_column.d.ts +16 -0
- package/dist/data_import/utils/import_columns.d.ts +48 -0
- package/dist/editor/editor.d.ts +7 -1
- package/dist/editor/extensions/Image.d.ts +22 -1
- package/dist/editor/hooks/useProseMirror.d.ts +4 -1
- package/dist/editor.js +69 -7
- package/dist/editor.js.map +1 -1
- package/dist/{export-LvIpE7sE.js → export-DCHuPD1a.js} +65 -211
- package/dist/export-DCHuPD1a.js.map +1 -0
- package/dist/form/form_utils.d.ts +37 -0
- package/dist/form/resolve_form_properties.d.ts +26 -0
- package/dist/form/validation.d.ts +13 -0
- package/dist/{history-DG6Ln7CV.js → history-CBd6SBRs.js} +3 -2
- package/dist/{history-DG6Ln7CV.js.map → history-CBd6SBRs.js.map} +1 -1
- package/dist/hooks/useEntityDisplay.d.ts +4 -5
- package/dist/hooks/useRecordActions.d.ts +28 -6
- package/dist/hooks/useReferencePaths.d.ts +21 -0
- package/dist/hooks/useStorageReferenceResolver.d.ts +23 -0
- package/dist/{import-Cxnmpyjl.js → import-DjQoRrIU.js} +35 -54
- package/dist/import-DjQoRrIU.js.map +1 -0
- package/dist/index.js +191 -117
- package/dist/index.js.map +1 -1
- package/dist/preview/components/StorageMarkdown.d.ts +10 -0
- package/dist/preview/util.d.ts +29 -0
- package/dist/util/caller_scopes.d.ts +15 -0
- package/dist/util/entity_actions.d.ts +37 -1
- package/dist/util/fit_inline_actions.d.ts +20 -0
- package/dist/util/navigation_utils.d.ts +14 -2
- package/dist/util/view_mode.d.ts +12 -18
- package/dist/{util-CyIcgnv2.js → util-BRvKFMLa.js} +5775 -3665
- package/dist/util-BRvKFMLa.js.map +1 -0
- package/dist/{util-DB31IoJE.js → util-D7ebttKT.js} +39 -2
- package/dist/util-D7ebttKT.js.map +1 -0
- package/package.json +9 -9
- package/dist/CollectionEditorDialog-CUtfS_49.js.map +0 -1
- package/dist/PropertyEditView-BpEbC0Q2.js.map +0 -1
- package/dist/RouterCollectionsStudioView-EK8Knq5I.js.map +0 -1
- package/dist/SchemaChangeDialog-BeP0A4MJ.js.map +0 -1
- package/dist/export-LvIpE7sE.js.map +0 -1
- package/dist/import-Cxnmpyjl.js.map +0 -1
- package/dist/util-CyIcgnv2.js.map +0 -1
- package/dist/util-DB31IoJE.js.map +0 -1
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { EntityRelation, FilterValues, Relation } from "@rebasepro/types";
|
|
3
|
-
import {
|
|
3
|
+
import { AdminCollection } from "@rebasepro/cms-types";
|
|
4
4
|
type TableMultipleRelationFieldProps = {
|
|
5
5
|
name: string;
|
|
6
6
|
disabled: boolean;
|
|
7
7
|
internalValue: EntityRelation[] | undefined | null;
|
|
8
8
|
updateValue: (newValue: EntityRelation[] | null) => void;
|
|
9
|
-
size: CollectionSize;
|
|
10
9
|
previewProperties?: string[];
|
|
11
|
-
title?: string;
|
|
12
10
|
relation: Relation;
|
|
13
11
|
fixedFilter?: FilterValues<string>;
|
|
14
12
|
includeId?: boolean;
|
|
15
13
|
includeEntityLink?: boolean;
|
|
14
|
+
/** The cell is selected. */
|
|
15
|
+
selected?: boolean;
|
|
16
|
+
/** See `TableRelationField`. */
|
|
17
|
+
open?: boolean;
|
|
18
|
+
onOpenChange?: (open: boolean) => void;
|
|
16
19
|
};
|
|
17
20
|
export declare function TableMultipleRelationField(props: TableMultipleRelationFieldProps): React.JSX.Element;
|
|
18
21
|
export declare const TableMultipleRelationFieldInternal: React.MemoExoticComponent<(props: TableMultipleRelationFieldProps & {
|
|
@@ -9,11 +9,18 @@ type TableReferenceFieldProps = {
|
|
|
9
9
|
size: CollectionSize;
|
|
10
10
|
multiselect: boolean;
|
|
11
11
|
previewProperties?: string[];
|
|
12
|
-
title?: string;
|
|
13
12
|
path: string;
|
|
14
13
|
fixedFilter?: FilterValues<string>;
|
|
15
14
|
includeId?: boolean;
|
|
16
15
|
includeEntityLink?: boolean;
|
|
16
|
+
/** The cell is selected. */
|
|
17
|
+
selected?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Set by the cell's opener: opens the selection dialog, and is handed
|
|
20
|
+
* back as closed at once — the dialog keeps its own state from there.
|
|
21
|
+
*/
|
|
22
|
+
open?: boolean;
|
|
23
|
+
onOpenChange?: (open: boolean) => void;
|
|
17
24
|
};
|
|
18
25
|
export declare function TableReferenceField(props: TableReferenceFieldProps): React.JSX.Element;
|
|
19
26
|
export declare const TableReferenceFieldInternal: React.MemoExoticComponent<(props: TableReferenceFieldProps & {
|
|
@@ -9,11 +9,18 @@ type TableRelationFieldProps = {
|
|
|
9
9
|
size: CollectionSize;
|
|
10
10
|
multiselect: boolean;
|
|
11
11
|
previewProperties?: string[];
|
|
12
|
-
title?: string;
|
|
13
12
|
relation: Relation;
|
|
14
13
|
fixedFilter?: FilterValues<string>;
|
|
15
14
|
includeId?: boolean;
|
|
16
15
|
includeEntityLink?: boolean;
|
|
16
|
+
/** The cell is selected. */
|
|
17
|
+
selected?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Set by the cell's opener: opens the selection dialog, and is handed
|
|
20
|
+
* back as closed at once — the dialog keeps its own state from there.
|
|
21
|
+
*/
|
|
22
|
+
open?: boolean;
|
|
23
|
+
onOpenChange?: (open: boolean) => void;
|
|
17
24
|
};
|
|
18
25
|
export declare function TableRelationField(props: TableRelationFieldProps): React.JSX.Element;
|
|
19
26
|
export declare const TableRelationFieldInternal: React.MemoExoticComponent<(props: TableRelationFieldProps & {
|
|
@@ -13,9 +13,19 @@ interface RelationSelectorFieldProps {
|
|
|
13
13
|
relation: Relation;
|
|
14
14
|
/** Force filter to be applied to the relation search */
|
|
15
15
|
fixedFilter?: FilterValues<string>;
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/** The cell is selected: the trigger takes the focus, so Enter opens the list. */
|
|
17
|
+
focused?: boolean;
|
|
18
|
+
/** Whether the list is open. Set by the cell's opener as well as the trigger. */
|
|
19
|
+
open?: boolean;
|
|
20
|
+
onOpenChange?: (open: boolean) => void;
|
|
21
|
+
/**
|
|
22
|
+
* What the cell shows at rest. The trigger shows the same node, so a
|
|
23
|
+
* selected cell looks like an unselected one.
|
|
24
|
+
*/
|
|
25
|
+
preview?: React.ReactNode;
|
|
26
|
+
/** The cell: the list opens against it rather than against the trigger. */
|
|
27
|
+
anchorRef?: React.RefObject<HTMLElement | null>;
|
|
18
28
|
}
|
|
19
29
|
/** Thin wrapper around RelationSelector for table cells */
|
|
20
|
-
export declare function TableRelationSelectorField({ disabled, internalValue, updateValue, relation, fixedFilter,
|
|
30
|
+
export declare function TableRelationSelectorField({ disabled, internalValue, updateValue, relation, fixedFilter, focused, open, onOpenChange, preview, anchorRef }: RelationSelectorFieldProps): React.JSX.Element;
|
|
21
31
|
export {};
|
|
@@ -11,5 +11,15 @@ export declare function VirtualTableSelect(props: {
|
|
|
11
11
|
valueType: "string" | "number";
|
|
12
12
|
updateValue: (newValue: (string | number | string[] | number[] | null)) => void;
|
|
13
13
|
focused: boolean;
|
|
14
|
+
/** Whether the list is open. Set by the cell's opener as well as the trigger. */
|
|
15
|
+
open?: boolean;
|
|
16
|
+
onOpenChange?: (open: boolean) => void;
|
|
17
|
+
/**
|
|
18
|
+
* What the cell shows at rest. The trigger shows the same node, so a
|
|
19
|
+
* selected cell looks like an unselected one; the chevron is the cell's.
|
|
20
|
+
*/
|
|
21
|
+
preview?: React.ReactNode;
|
|
22
|
+
/** The cell: the list opens against it rather than against the trigger. */
|
|
23
|
+
anchorRef?: React.RefObject<HTMLElement | null>;
|
|
14
24
|
onBlur?: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
|
|
15
25
|
}): React.JSX.Element;
|
|
@@ -8,5 +8,15 @@ export declare function VirtualTableUserSelect(props: {
|
|
|
8
8
|
internalValue: string | string[] | undefined;
|
|
9
9
|
updateValue: (newValue: (string | string[] | null)) => void;
|
|
10
10
|
focused: boolean;
|
|
11
|
+
/** Whether the list is open. Set by the cell's opener as well as the trigger. */
|
|
12
|
+
open?: boolean;
|
|
13
|
+
onOpenChange?: (open: boolean) => void;
|
|
14
|
+
/**
|
|
15
|
+
* What the cell shows at rest. The trigger shows the same node, so a
|
|
16
|
+
* selected cell looks like an unselected one.
|
|
17
|
+
*/
|
|
18
|
+
preview?: React.ReactNode;
|
|
19
|
+
/** The cell: the list opens against it rather than against the trigger. */
|
|
20
|
+
anchorRef?: React.RefObject<HTMLElement | null>;
|
|
11
21
|
onBlur?: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
|
|
12
22
|
}): React.JSX.Element;
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { TableSize } from "@rebasepro/app";
|
|
3
|
+
import { TableCellOpenerKind } from "./TableCellOpener.js";
|
|
4
|
+
export interface EntityTableCellOpener {
|
|
5
|
+
kind: TableCellOpenerKind;
|
|
6
|
+
open: boolean;
|
|
7
|
+
/** See {@link TableCellOpener}'s `focusOnSelect`. */
|
|
8
|
+
focusOnSelect: boolean;
|
|
9
|
+
label: string;
|
|
10
|
+
/**
|
|
11
|
+
* Whether the editor should now be open, and the cell's rect for editors
|
|
12
|
+
* positioned against it. The cell is selected before this is called.
|
|
13
|
+
*/
|
|
14
|
+
onToggle: (open: boolean, cellRect: DOMRect | undefined) => void;
|
|
15
|
+
}
|
|
3
16
|
interface EntityTableCellProps {
|
|
4
17
|
children: React.ReactNode;
|
|
5
18
|
actions?: React.ReactNode;
|
|
@@ -20,6 +33,14 @@ interface EntityTableCellProps {
|
|
|
20
33
|
fullHeight?: boolean;
|
|
21
34
|
selected?: boolean;
|
|
22
35
|
hideOverflow?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The control that opens the cell's editor, revealed on hover and kept
|
|
38
|
+
* shown while the cell is selected. The cell keeps a slot for it at its
|
|
39
|
+
* trailing edge either way, so it never moves the value.
|
|
40
|
+
*/
|
|
41
|
+
opener?: EntityTableCellOpener;
|
|
42
|
+
/** The cell's element, for editors that float and are positioned against it. */
|
|
43
|
+
cellRef?: React.RefObject<HTMLDivElement | null>;
|
|
23
44
|
onSelect?: (cellRect: DOMRect | undefined) => void;
|
|
24
45
|
sortableNodeRef?: (node: HTMLElement | null) => void;
|
|
25
46
|
sortableStyle?: React.CSSProperties;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* What a cell's opener opens.
|
|
4
|
+
*
|
|
5
|
+
* - `dropdown`: a list anchored to the cell — an enum, a user, an inline
|
|
6
|
+
* relation picker.
|
|
7
|
+
* - `dialog`: the selection dialog of a reference, or of a relation drawn with
|
|
8
|
+
* the dialog widget. Same chevron: to the person editing, both change which
|
|
9
|
+
* record the cell points at.
|
|
10
|
+
* - `calendar`: the date picker.
|
|
11
|
+
* - `expand`: the popup form, for values with no editor of their own in a
|
|
12
|
+
* cell (maps, arrays, custom fields).
|
|
13
|
+
*/
|
|
14
|
+
export type TableCellOpenerKind = "dropdown" | "dialog" | "calendar" | "expand";
|
|
15
|
+
export interface TableCellOpenerProps {
|
|
16
|
+
kind: TableCellOpenerKind;
|
|
17
|
+
/** The editor it opens is open: the chevron turns over and stays shown. */
|
|
18
|
+
open: boolean;
|
|
19
|
+
/** The cell is selected: the opener is shown whether or not it is hovered. */
|
|
20
|
+
selected: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Take the focus when the cell is selected, so Enter opens the editor.
|
|
23
|
+
* Off when the editor's own trigger takes it instead.
|
|
24
|
+
*/
|
|
25
|
+
focusOnSelect: boolean;
|
|
26
|
+
label: string;
|
|
27
|
+
/**
|
|
28
|
+
* Called on a click, with whether the editor should now be open. A click
|
|
29
|
+
* while it is open closes it rather than opening it a second time.
|
|
30
|
+
*/
|
|
31
|
+
onToggle: (open: boolean) => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The one control a cell reveals to open its editor.
|
|
35
|
+
*
|
|
36
|
+
* A cell looks the same at rest, hovered and selected: the value, in the same
|
|
37
|
+
* place. This is the only thing that appears — on hover, and for as long as
|
|
38
|
+
* the cell is selected — in a slot the cell keeps for it whether it is shown
|
|
39
|
+
* or not, so revealing it moves nothing.
|
|
40
|
+
*
|
|
41
|
+
* One click on it opens the editor, from rest: it selects the cell on the way.
|
|
42
|
+
* It never takes the focus on a mouse press, because the cell selects itself
|
|
43
|
+
* on focus and doing so first would re-render the cell under the pointer.
|
|
44
|
+
*/
|
|
45
|
+
export declare function TableCellOpener({ kind, open, selected, focusOnSelect, label, onToggle }: TableCellOpenerProps): React.JSX.Element;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Entity, Property } from "@rebasepro/types";
|
|
3
3
|
import { TableSize } from "@rebasepro/app";
|
|
4
|
+
import { TableCellOpenerKind } from "./internal/TableCellOpener.js";
|
|
4
5
|
export interface TableFieldBindingProps<T = unknown> {
|
|
5
6
|
propertyKey: string;
|
|
6
7
|
property: Property;
|
|
@@ -15,9 +16,32 @@ export interface TableFieldBindingProps<T = unknown> {
|
|
|
15
16
|
entity: Entity<Record<string, unknown>>;
|
|
16
17
|
path: string;
|
|
17
18
|
openPopup?: (cellRect: DOMRect | undefined) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Whether the cell's floating editor is open — its dropdown, its selection
|
|
21
|
+
* dialog, its date picker. The cell's opener sets it as well as the
|
|
22
|
+
* editor's own trigger, and it can be set before the editor has mounted.
|
|
23
|
+
*/
|
|
24
|
+
open?: boolean;
|
|
25
|
+
onOpenChange?: (open: boolean) => void;
|
|
26
|
+
/**
|
|
27
|
+
* What the cell shows at rest. An editor with a trigger shows this same
|
|
28
|
+
* node in it, so selecting the cell changes its frame and nothing else.
|
|
29
|
+
*/
|
|
30
|
+
preview?: React.ReactNode;
|
|
31
|
+
/**
|
|
32
|
+
* The cell's element. A floating editor opens against it rather than
|
|
33
|
+
* against its own trigger, which can be taller than the cell clipping it.
|
|
34
|
+
*/
|
|
35
|
+
anchorRef?: React.RefObject<HTMLElement | null>;
|
|
18
36
|
}
|
|
19
37
|
export interface TableFieldConfig {
|
|
20
38
|
Component: React.ComponentType<TableFieldBindingProps>;
|
|
39
|
+
/**
|
|
40
|
+
* The opener the cell reveals on hover, and keeps shown while selected,
|
|
41
|
+
* to open this editor in one click. None for editors that are the value
|
|
42
|
+
* itself (a text input, a switch) or that draw their own (storage).
|
|
43
|
+
*/
|
|
44
|
+
opener?: TableCellOpenerKind;
|
|
21
45
|
fullHeight?: boolean;
|
|
22
46
|
allowScroll?: boolean;
|
|
23
47
|
removePadding?: boolean;
|
|
@@ -14,6 +14,11 @@ export type CollectionViewActionsProps<M extends Record<string, unknown>> = {
|
|
|
14
14
|
*/
|
|
15
15
|
onAddExistingClick?: () => void;
|
|
16
16
|
onMultipleDeleteClick: () => void;
|
|
17
|
+
/**
|
|
18
|
+
* The rows are shared with other records through a junction, so removing
|
|
19
|
+
* them unlinks them from this record and deletes nothing. The bin says so.
|
|
20
|
+
*/
|
|
21
|
+
removeUnlinks?: boolean;
|
|
17
22
|
selectionController: SelectionController<M>;
|
|
18
23
|
tableController: EntityTableController<M>;
|
|
19
24
|
collectionEntitiesCount?: number;
|
|
@@ -21,4 +26,4 @@ export type CollectionViewActionsProps<M extends Record<string, unknown>> = {
|
|
|
21
26
|
children?: React.ReactNode;
|
|
22
27
|
openNewDocument: (defaultValues?: Record<string, unknown>) => void;
|
|
23
28
|
};
|
|
24
|
-
export declare function CollectionViewActions<M extends Record<string, unknown>>({ collection, relativePath, parentCollectionSlugs, parentEntityIds, onNewClick, onAddExistingClick, onMultipleDeleteClick, selectionEnabled, path, selectionController, tableController, collectionEntitiesCount, compact, children, openNewDocument }: CollectionViewActionsProps<M>): React.JSX.Element;
|
|
29
|
+
export declare function CollectionViewActions<M extends Record<string, unknown>>({ collection, relativePath, parentCollectionSlugs, parentEntityIds, onNewClick, onAddExistingClick, onMultipleDeleteClick, removeUnlinks, selectionEnabled, path, selectionController, tableController, collectionEntitiesCount, compact, children, openNewDocument }: CollectionViewActionsProps<M>): React.JSX.Element;
|
|
@@ -7,8 +7,11 @@ import React from "react";
|
|
|
7
7
|
*/
|
|
8
8
|
export type CollectionViewBindingProps<M extends Record<string, unknown>> = {
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* The path the collection is addressed by: its slug, or for a
|
|
11
|
+
* subcollection `parentSlug/{id}/slug`. Defaults to the collection's slug.
|
|
12
|
+
* Not the `path` a Firestore or MongoDB collection declares for its store:
|
|
13
|
+
* the data layer translates to that one, and another collection's slug may
|
|
14
|
+
* be spelled the same.
|
|
12
15
|
*/
|
|
13
16
|
path?: string;
|
|
14
17
|
/**
|
|
@@ -41,7 +44,7 @@ export type CollectionViewBindingProps<M extends Record<string, unknown>> = {
|
|
|
41
44
|
selectedTab?: string;
|
|
42
45
|
} & AdminCollection<M>;
|
|
43
46
|
export declare const CollectionViewBinding: React.FunctionComponent<CollectionViewBindingProps<any>>;
|
|
44
|
-
export declare function EntitiesCount({ path, collection, filter, sortBy, searchString, onCountChange }: {
|
|
47
|
+
export declare function EntitiesCount({ path, collection, filter, sortBy, searchString, onCountChange, refreshKey }: {
|
|
45
48
|
path: string;
|
|
46
49
|
collection: AdminCollection;
|
|
47
50
|
filter?: FilterValues<any>;
|
|
@@ -55,4 +58,10 @@ export declare function EntitiesCount({ path, collection, filter, sortBy, search
|
|
|
55
58
|
*/
|
|
56
59
|
searchString: string | undefined;
|
|
57
60
|
onCountChange?: (count: number | null | undefined) => void;
|
|
61
|
+
/**
|
|
62
|
+
* Counts again whenever this changes. The count is one read, not a
|
|
63
|
+
* subscription: after a delete the toolbar kept the old total, and "select
|
|
64
|
+
* all matching" offered it over the rows that were left.
|
|
65
|
+
*/
|
|
66
|
+
refreshKey?: number;
|
|
58
67
|
}): null;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { Property } from "@rebasepro/types";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { FilterValues } from "@rebasepro/types";
|
|
4
|
+
/**
|
|
5
|
+
* The properties the dialog lists, each with a filter field: every property
|
|
6
|
+
* that can be filtered, bar the collection's fixed-filter fields.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getFilterableProperties(properties: Record<string, Property>, fixedFilter?: FilterValues<string>, engine?: string): [string, Property][];
|
|
4
9
|
export interface FiltersDialogProps {
|
|
5
10
|
open: boolean;
|
|
6
11
|
onOpenChange: (open: boolean) => void;
|
|
@@ -82,11 +82,17 @@ export interface EditViewBindingProps<M extends Record<string, unknown> = Record
|
|
|
82
82
|
* a record is opened.
|
|
83
83
|
*/
|
|
84
84
|
export declare function EditViewBinding<M extends Record<string, unknown>>({ entityId, ...props }: EditViewBindingProps<M>): React.JSX.Element;
|
|
85
|
-
export declare function EditViewBindingInner<M extends Record<string, unknown>>({ path, entityId, selectedTab: selectedTabProp, collection, parentCollectionSlugs, parentEntityIds, onValuesModified, onSaved, onTabChange, navigateBack, onCloseRequest, entity, initialDirtyValues, dataLoading, layout, barActions, barActionsStart, onShowList, status, setStatus, formProps, canEdit }: EditViewBindingProps<M> & {
|
|
85
|
+
export declare function EditViewBindingInner<M extends Record<string, unknown>>({ path, entityId, selectedTab: selectedTabProp, collection, parentCollectionSlugs, parentEntityIds, onValuesModified, onSaved, onTabChange, navigateBack, onCloseRequest, entity, initialDirtyValues, dataLoading, layout, barActions, barActionsStart, onShowList, status, setStatus, formProps, canEdit, deletedElsewhere }: EditViewBindingProps<M> & {
|
|
86
86
|
entity?: Entity<M>;
|
|
87
87
|
initialDirtyValues?: Partial<M>;
|
|
88
88
|
dataLoading: boolean;
|
|
89
89
|
status: EntityStatus;
|
|
90
90
|
setStatus: (status: EntityStatus) => void;
|
|
91
91
|
canEdit?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* The record was deleted by someone else while this form had it open. The
|
|
94
|
+
* form keeps its values; saving them over the record is no longer
|
|
95
|
+
* possible, saving them as a new one is.
|
|
96
|
+
*/
|
|
97
|
+
deletedElsewhere?: boolean;
|
|
92
98
|
}): React.JSX.Element;
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import type { AdminCollection } from "@rebasepro/cms-types";
|
|
2
2
|
import type { EntityStatus } from "@rebasepro/types";
|
|
3
3
|
import React from "react";
|
|
4
|
+
import type { PlacedEntityActions } from "../util/entity_actions.js";
|
|
5
|
+
/**
|
|
6
|
+
* One of the record's own actions, resolved and ready to run — what the bar
|
|
7
|
+
* needs to draw it as a button or as a menu item.
|
|
8
|
+
*/
|
|
9
|
+
export interface RecordActionItem {
|
|
10
|
+
key: string;
|
|
11
|
+
name: string;
|
|
12
|
+
icon?: React.ReactNode;
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
/** Why it is disabled, when it is and its action says. */
|
|
15
|
+
disabledReason?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Runs the action, reporting its own failure. Returns a promise only when
|
|
18
|
+
* the action is asynchronous, which is what keeps a button's spinner up.
|
|
19
|
+
*/
|
|
20
|
+
run: () => Promise<void> | undefined;
|
|
21
|
+
}
|
|
4
22
|
export interface EntityIdentityBarProps {
|
|
5
23
|
/** Plural collection name, shown as the breadcrumb ahead of the title. */
|
|
6
24
|
collection: AdminCollection;
|
|
@@ -68,10 +86,17 @@ export interface EntityIdentityBarProps {
|
|
|
68
86
|
externalLink?: string;
|
|
69
87
|
/**
|
|
70
88
|
* Actions performed *on* the record — copy, delete, whatever the collection
|
|
71
|
-
* adds —
|
|
72
|
-
*
|
|
89
|
+
* adds — already placed: `inline` ones are buttons ahead of Save, folding
|
|
90
|
+
* into the overflow menu when the bar runs short of room, and the rest are
|
|
91
|
+
* menu groups. They live here rather than in a footer, which is what let
|
|
92
|
+
* the footer go away entirely.
|
|
93
|
+
*/
|
|
94
|
+
recordActions?: PlacedEntityActions<RecordActionItem>;
|
|
95
|
+
/**
|
|
96
|
+
* The read-only view's Edit: its main button, drawn where Save stands on
|
|
97
|
+
* the edit view — after the record's own buttons, ahead of the menu.
|
|
73
98
|
*/
|
|
74
|
-
|
|
99
|
+
primaryAction?: React.ReactNode;
|
|
75
100
|
/** Plugin-contributed actions, rendered inline before Save. */
|
|
76
101
|
pluginActions?: React.ReactNode;
|
|
77
102
|
/** Close / full-screen buttons supplied by the panel that owns this view. */
|
|
@@ -92,7 +117,7 @@ export interface EntityIdentityBarProps {
|
|
|
92
117
|
* editing. They live here instead, and the left half of a bar that was
|
|
93
118
|
* previously empty now does the work.
|
|
94
119
|
*/
|
|
95
|
-
export declare function EntityIdentityBar({ collection, collectionUrl, title, entityId, status, dirty, saving, onSave, onDiscard, saveDisabled, hasErrors, onSaveAndClose, saveAndClosePlacement, onClose, onBack, onInspect, onViewHistory, externalLink, recordActions, pluginActions, trailing, leading }: EntityIdentityBarProps): React.JSX.Element;
|
|
120
|
+
export declare function EntityIdentityBar({ collection, collectionUrl, title, entityId, status, dirty, saving, onSave, onDiscard, saveDisabled, hasErrors, onSaveAndClose, saveAndClosePlacement, onClose, onBack, onInspect, onViewHistory, externalLink, recordActions, primaryAction, pluginActions, trailing, leading }: EntityIdentityBarProps): React.JSX.Element;
|
|
96
121
|
export type EntitySaveActionsProps = Pick<EntityIdentityBarProps, "status" | "dirty" | "saving" | "onSave" | "onDiscard" | "saveDisabled" | "hasErrors" | "onSaveAndClose" | "saveAndClosePlacement">;
|
|
97
122
|
/**
|
|
98
123
|
* Save, "save and close", Discard, and the words saying where the edit stands.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { Entity } from "@rebasepro/types";
|
|
3
3
|
import type { PreviewSize } from "../types/components/PropertyPreviewProps.js";
|
|
4
|
+
import { EntityPreviewLayout } from "./EntityPreviewNesting.js";
|
|
4
5
|
import type { AdminCollection } from "@rebasepro/cms-types";
|
|
5
6
|
export type EntityPreviewBindingProps = {
|
|
6
7
|
size?: PreviewSize;
|
|
@@ -28,12 +29,18 @@ export type EntityPreviewBindingDataProps = {
|
|
|
28
29
|
includeTitle?: boolean;
|
|
29
30
|
includeEntityLink?: boolean;
|
|
30
31
|
includeImage?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* `row` draws the record as a line of a table row instead of a card: see
|
|
34
|
+
* {@link EntityPreviewLayout}. No id, no open button — the title opens the
|
|
35
|
+
* record — and only as many supporting lines as the row has room for.
|
|
36
|
+
*/
|
|
37
|
+
layout?: EntityPreviewLayout;
|
|
31
38
|
};
|
|
32
39
|
/**
|
|
33
40
|
* This component contains the main logic and content for displaying a entity preview,
|
|
34
41
|
* without any container wrapper. Used internally by EntityPreviewBinding.
|
|
35
42
|
*/
|
|
36
|
-
export declare function EntityPreviewBindingData({ actions, collection: collectionProp, previewKeys, size, includeId, onSidePanelClick, includeTitle, includeEntityLink, includeImage, entity }: EntityPreviewBindingDataProps): React.JSX.Element;
|
|
43
|
+
export declare function EntityPreviewBindingData({ actions, collection: collectionProp, previewKeys, size, includeId, onSidePanelClick, includeTitle, includeEntityLink, includeImage, layout, entity }: EntityPreviewBindingDataProps): React.JSX.Element;
|
|
37
44
|
export declare function EntityPreviewBindingWithId({ entityId, path, ...props }: Omit<EntityPreviewBindingProps, "entity"> & {
|
|
38
45
|
entityId: string | number;
|
|
39
46
|
path: string;
|
|
@@ -23,3 +23,18 @@ export declare function NestedEntityPreviewBoundary({ children }: {
|
|
|
23
23
|
export declare function RootEntityPreviewBoundary({ children }: {
|
|
24
24
|
children: React.ReactNode;
|
|
25
25
|
}): React.JSX.Element;
|
|
26
|
+
/**
|
|
27
|
+
* How a top-level reference or relation preview is laid out.
|
|
28
|
+
*
|
|
29
|
+
* `card` is the form's: a bordered box with the record's id, title, preview
|
|
30
|
+
* properties and a button to open it. `row` is a table cell's: the same
|
|
31
|
+
* record as a line of the row it sits in — image, a title that opens it, one
|
|
32
|
+
* supporting line — with no box of its own, because the cell is the box and
|
|
33
|
+
* a card is taller than a row.
|
|
34
|
+
*/
|
|
35
|
+
export type EntityPreviewLayout = "card" | "row";
|
|
36
|
+
export declare function useEntityPreviewLayout(): EntityPreviewLayout;
|
|
37
|
+
/** Lays out the previews below it as rows. See {@link EntityPreviewLayout}. */
|
|
38
|
+
export declare function RowEntityPreviewLayout({ children }: {
|
|
39
|
+
children: React.ReactNode;
|
|
40
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* The collections or views could not be resolved: a `collections` or `views`
|
|
4
|
+
* builder threw, or a plugin's `modifyCollections` did, or something either of
|
|
5
|
+
* them awaited failed.
|
|
6
|
+
*
|
|
7
|
+
* That failure used to be caught, logged and stored as
|
|
8
|
+
* `navigationLoadingError`, and then read by nothing: the home page rendered
|
|
9
|
+
* an empty search bar and a deep link to a collection spun for ever, or said
|
|
10
|
+
* the collection was not registered — the wrong cause. This says what failed
|
|
11
|
+
* and offers the retry the navigation controller already had.
|
|
12
|
+
*/
|
|
13
|
+
export declare function NavigationLoadingErrorView({ error, onRetry }: {
|
|
14
|
+
error: Error;
|
|
15
|
+
onRetry?: () => void;
|
|
16
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* The trigger of a picker's popover, or — given an anchor — a plain child
|
|
4
|
+
* beside a `Popover.Anchor` on that element.
|
|
5
|
+
*
|
|
6
|
+
* Both at once does not work: Radix's `Trigger` registers itself as the
|
|
7
|
+
* anchor through a ref callback, and a custom anchor through an effect that
|
|
8
|
+
* only reports a change. Under StrictMode the ref callback runs again after
|
|
9
|
+
* the effect, the effect sees nothing new, and the popover stays anchored to
|
|
10
|
+
* a trigger that the custom anchor then unmounts — it opened at the window's
|
|
11
|
+
* top-left corner. The pickers open and close themselves, so they lose
|
|
12
|
+
* nothing by leaving the `Trigger` out.
|
|
13
|
+
*/
|
|
14
|
+
export declare function PickerTrigger({ anchorRef, children }: {
|
|
15
|
+
anchorRef?: React.RefObject<HTMLElement | null>;
|
|
16
|
+
children: React.ReactElement;
|
|
17
|
+
}): React.JSX.Element;
|
|
@@ -38,6 +38,18 @@ export interface SelectionProps<M extends Record<string, unknown>> {
|
|
|
38
38
|
* @callback
|
|
39
39
|
*/
|
|
40
40
|
onMultipleEntitiesSelected?(entities: Entity<any>[]): void;
|
|
41
|
+
/**
|
|
42
|
+
* Called once, with the final selection, when the user presses Done.
|
|
43
|
+
*
|
|
44
|
+
* `onMultipleEntitiesSelected` reports every tick as it happens, which is
|
|
45
|
+
* right when the selection *is* the value (a reference field). Use this
|
|
46
|
+
* one instead when acting on the selection writes something — linking
|
|
47
|
+
* rows, say — so a row ticked and then unticked, or a selection cleared,
|
|
48
|
+
* is never acted on.
|
|
49
|
+
* @param entities
|
|
50
|
+
* @callback
|
|
51
|
+
*/
|
|
52
|
+
onSelectionDone?(entities: Entity<M>[]): void;
|
|
41
53
|
/**
|
|
42
54
|
* Allow selection of entities that pass the given filter only.
|
|
43
55
|
*/
|
|
@@ -20,13 +20,10 @@ export interface RelationSelectorProps {
|
|
|
20
20
|
* scale, so a relation picker lines up with the text field beside it.
|
|
21
21
|
*
|
|
22
22
|
* `small` and `medium` predate that scale (42 and 56) and are kept as they
|
|
23
|
-
*
|
|
24
|
-
* `
|
|
25
|
-
* the chosen records as inline lines (each opens its record), a chevron,
|
|
26
|
-
* nothing else.
|
|
27
|
-
* are because the table cells and the filter row are built around them.
|
|
23
|
+
* are because the filter row is built around them. A table cell passes
|
|
24
|
+
* `triggerContent` instead, and has no size of its own.
|
|
28
25
|
*/
|
|
29
|
-
size?: "
|
|
26
|
+
size?: "small" | "medium" | "large";
|
|
30
27
|
useChips?: boolean;
|
|
31
28
|
disabled?: boolean;
|
|
32
29
|
invisible?: boolean;
|
|
@@ -64,6 +61,26 @@ export interface RelationSelectorProps {
|
|
|
64
61
|
*/
|
|
65
62
|
emptyCollectionText?: string;
|
|
66
63
|
loadingText?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Whether the list is open, for a caller that opens it from outside the
|
|
66
|
+
* trigger — a table cell's opener. Every open and close the selector
|
|
67
|
+
* makes itself is reported through `onOpenChange`, controlled or not.
|
|
68
|
+
*/
|
|
69
|
+
open?: boolean;
|
|
70
|
+
onOpenChange?: (open: boolean) => void;
|
|
71
|
+
/**
|
|
72
|
+
* Replaces everything the trigger draws — the value, the box, its padding
|
|
73
|
+
* and the chevron — with this node. For a caller that frames the picker
|
|
74
|
+
* itself: a table cell passes the preview it shows at rest, so the cell
|
|
75
|
+
* looks the same whether the picker is mounted, closed or open.
|
|
76
|
+
*/
|
|
77
|
+
triggerContent?: React.ReactNode;
|
|
78
|
+
/**
|
|
79
|
+
* Positions the list against this element instead of the trigger. A
|
|
80
|
+
* table cell passes itself: the trigger inside it can be taller than the
|
|
81
|
+
* cell that clips it, and the list belongs under what can be seen.
|
|
82
|
+
*/
|
|
83
|
+
anchorRef?: React.RefObject<HTMLElement | null>;
|
|
67
84
|
/**
|
|
68
85
|
* Whether the open list offers to create a row in the target collection.
|
|
69
86
|
* Defaults to `true`. The offer is shown only when the user could actually
|
|
@@ -73,4 +90,4 @@ export interface RelationSelectorProps {
|
|
|
73
90
|
*/
|
|
74
91
|
allowCreate?: boolean;
|
|
75
92
|
}
|
|
76
|
-
export declare const RelationSelector: React.ForwardRefExoticComponent<RelationSelectorProps & React.RefAttributes<
|
|
93
|
+
export declare const RelationSelector: React.ForwardRefExoticComponent<RelationSelectorProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -21,5 +21,12 @@ export interface UserSelectorProps {
|
|
|
21
21
|
searchPlaceholder?: string;
|
|
22
22
|
noResultsText?: string;
|
|
23
23
|
loadingText?: string;
|
|
24
|
+
/** See `RelationSelector`'s `open`. */
|
|
25
|
+
open?: boolean;
|
|
26
|
+
onOpenChange?: (open: boolean) => void;
|
|
27
|
+
/** See `RelationSelector`'s `triggerContent`. */
|
|
28
|
+
triggerContent?: React.ReactNode;
|
|
29
|
+
/** See `RelationSelector`'s `anchorRef`. */
|
|
30
|
+
anchorRef?: React.RefObject<HTMLElement | null>;
|
|
24
31
|
}
|
|
25
|
-
export declare const UserSelector: React.ForwardRefExoticComponent<UserSelectorProps & React.RefAttributes<
|
|
32
|
+
export declare const UserSelector: React.ForwardRefExoticComponent<UserSelectorProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* An action's name in a menu and, when it is unavailable and says why, the
|
|
4
|
+
* reason on a line beneath it.
|
|
5
|
+
*
|
|
6
|
+
* In the text rather than a tooltip: a disabled menu item cannot be focused or
|
|
7
|
+
* hovered into anything, and on a touch screen there is no hover at all — the
|
|
8
|
+
* reason has to be readable where the item is. It is drawn in the label's own
|
|
9
|
+
* ink, a size down, because the item dims everything it holds: a muted colour
|
|
10
|
+
* under that dimming fell below legible.
|
|
11
|
+
*/
|
|
12
|
+
export declare function ActionMenuLabel({ name, disabledReason }: {
|
|
13
|
+
name: string;
|
|
14
|
+
disabledReason?: string;
|
|
15
|
+
}): React.JSX.Element;
|
|
@@ -15,3 +15,40 @@ export declare function ResetPasswordActionDialog({ user, open, onClose }: {
|
|
|
15
15
|
onClose: () => void;
|
|
16
16
|
}): React.JSX.Element;
|
|
17
17
|
export declare const resetPasswordAction: EntityAction;
|
|
18
|
+
/** A user, as the two dialogs below need one. */
|
|
19
|
+
interface AdminActionUser {
|
|
20
|
+
uid: string;
|
|
21
|
+
email: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Remove every second factor and recovery code an account has, and end its
|
|
25
|
+
* sessions — for someone who lost their authenticator and their codes.
|
|
26
|
+
*/
|
|
27
|
+
export declare function ResetMfaActionDialog({ user, open, onClose }: {
|
|
28
|
+
user: AdminActionUser;
|
|
29
|
+
open: boolean;
|
|
30
|
+
onClose: () => void;
|
|
31
|
+
}): React.JSX.Element;
|
|
32
|
+
/**
|
|
33
|
+
* Switch an account off, or back on. Off, it signs in nowhere and every session
|
|
34
|
+
* and token it holds ends; the switch reads the account's state first, because
|
|
35
|
+
* the users table does not carry it.
|
|
36
|
+
*/
|
|
37
|
+
export declare function AccountAccessDialog({ user, open, onClose }: {
|
|
38
|
+
user: AdminActionUser;
|
|
39
|
+
open: boolean;
|
|
40
|
+
onClose: () => void;
|
|
41
|
+
}): React.JSX.Element;
|
|
42
|
+
/**
|
|
43
|
+
* Reset a user's two-step verification. Offered to whoever holds
|
|
44
|
+
* `users:write`, as `DELETE /admin/users/:uid/mfa` is; the route also refuses
|
|
45
|
+
* an account that outranks the caller, and the dialog says so.
|
|
46
|
+
*/
|
|
47
|
+
export declare const resetMfaAction: EntityAction;
|
|
48
|
+
/**
|
|
49
|
+
* Switch an account off or on. Offered to whoever holds `users:write`, as
|
|
50
|
+
* `PUT /admin/users/:uid { disabled }` is, and never on the caller's own
|
|
51
|
+
* account, which the route refuses.
|
|
52
|
+
*/
|
|
53
|
+
export declare const accountAccessAction: EntityAction;
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Entity } from "@rebasepro/types";
|
|
2
|
+
import { AdditionalFieldDelegate, ExportMappingFunction, RebaseContext } from "@rebasepro/cms-types";
|
|
3
|
+
/**
|
|
4
|
+
* The values of the export's extra columns, one record per entity: the
|
|
5
|
+
* collection's `exportable.additionalFields` and its `additionalFields` that
|
|
6
|
+
* declare a `value`, both in the same record.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveAdditionalExportValues<M extends Record<string, unknown>>({ entities, exportFields, additionalFields, context }: {
|
|
9
|
+
entities: Entity<M>[];
|
|
10
|
+
exportFields: ExportMappingFunction[] | undefined;
|
|
11
|
+
additionalFields: AdditionalFieldDelegate<M>[] | undefined;
|
|
12
|
+
context: RebaseContext;
|
|
13
|
+
}): Promise<Record<string, unknown>[]>;
|
|
@@ -23,6 +23,12 @@ export declare function getEntityJsonExportableData(data: Entity<Record<string,
|
|
|
23
23
|
* the spreadsheet as "treat the rest as text", so the value reads back intact.
|
|
24
24
|
*/
|
|
25
25
|
export declare function escapeCsvFormula(value: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* The inverse of {@link escapeCsvFormula}, for a file read back in: a cell that
|
|
28
|
+
* is an apostrophe followed by a formula trigger loses the apostrophe, as it
|
|
29
|
+
* does when a spreadsheet reads it. Any other apostrophe is text.
|
|
30
|
+
*/
|
|
31
|
+
export declare function unescapeCsvFormula(value: string): string;
|
|
26
32
|
export declare function entryToCSVRow(entry: unknown[]): string;
|
|
27
33
|
export declare function downloadBlob(content: BlobPart[], filename: string, contentType: string): void;
|
|
28
34
|
export declare function downloadDataAsCsv(data: object[], name: string): void;
|