@rebasepro/admin 0.1.0 → 0.2.1
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/LICENSE +21 -6
- package/dist/{CollectionEditorDialog-MbvXGzEq.js → CollectionEditorDialog-BXIh2AXg.js} +40 -31
- package/dist/CollectionEditorDialog-BXIh2AXg.js.map +1 -0
- package/dist/{CollectionsStudioView-D9X6aiAr.js → CollectionsStudioView-jR8iz_ja.js} +6 -8
- package/dist/CollectionsStudioView-jR8iz_ja.js.map +1 -0
- package/dist/{ContentHomePage-CfVB1eUo.js → ContentHomePage-BQZWuOFb.js} +5 -7
- package/dist/ContentHomePage-BQZWuOFb.js.map +1 -0
- package/dist/{ExportCollectionAction-CUwJg4F9.js → ExportCollectionAction-CMdiiv1L.js} +36 -38
- package/dist/ExportCollectionAction-CMdiiv1L.js.map +1 -0
- package/dist/{ImportCollectionAction-DGa_SF_8.js → ImportCollectionAction-C05lE0IW.js} +5 -7
- package/dist/ImportCollectionAction-C05lE0IW.js.map +1 -0
- package/dist/{PropertyEditView-C4nlYmAc.js → PropertyEditView-BB5xjnhZ.js} +261 -165
- package/dist/PropertyEditView-BB5xjnhZ.js.map +1 -0
- package/dist/{RolesView-CNWxnR8e.js → RolesView-CULIHWZ9.js} +22 -11
- package/dist/RolesView-CULIHWZ9.js.map +1 -0
- package/dist/{UsersView-YiTIcXkA.js → UsersView-D7_AtJ44.js} +7 -71
- package/dist/UsersView-D7_AtJ44.js.map +1 -0
- package/dist/collection_editor/ui/collection_editor/LayoutModeSwitch.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/properties/VectorPropertyField.d.ts +3 -0
- package/dist/collection_editor_ui.js +5 -5
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +1 -1
- package/dist/components/EntityCollectionView/EntityCollectionListView.d.ts +18 -2
- package/dist/components/EntityCollectionView/FilterPresetsButton.d.ts +21 -0
- package/dist/components/EntityDetailView.d.ts +31 -0
- package/dist/components/EntityEditView.d.ts +3 -2
- package/dist/components/ReferenceTable/EntitySelectionTable.d.ts +1 -1
- package/dist/components/admin/CreationResultDialog.d.ts +5 -0
- package/dist/components/admin/RolesFilterSelect.d.ts +2 -0
- package/dist/components/admin/UserRolesSelectField.d.ts +2 -0
- package/dist/components/common/default_entity_actions.d.ts +7 -1
- package/dist/components/field_configs.d.ts +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/data_import/utils/data.d.ts +1 -1
- package/dist/data_import/utils/file_headers.d.ts +6 -1
- package/dist/data_import/utils/file_to_json.d.ts +1 -11
- package/dist/data_import/utils/transforms.d.ts +11 -0
- package/dist/editor.js +2 -4
- package/dist/editor.js.map +1 -1
- package/dist/form/EntityForm.d.ts +1 -1
- package/dist/form/field_bindings/RelationFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/VectorFieldBinding.d.ts +11 -0
- package/dist/form/index.d.ts +1 -0
- package/dist/hooks/navigation/useResolvedViews.d.ts +2 -1
- package/dist/{index-CtzpHzMQ.js → index-BAM9KCmM.js} +4 -6
- package/dist/index-BAM9KCmM.js.map +1 -0
- package/dist/{index-DKlrVD1m.js → index-CoSNm3e3.js} +3 -3
- package/dist/index-CoSNm3e3.js.map +1 -0
- package/dist/{index-kHJXfLNI.js → index-D5OQhv-T.js} +3 -3
- package/dist/index-D5OQhv-T.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +352 -148
- package/dist/index.js.map +1 -1
- package/dist/types/components/EntityFormActionsProps.d.ts +1 -1
- package/dist/types/components/EntityFormProps.d.ts +2 -1
- package/dist/types/fields.d.ts +3 -3
- package/dist/util/navigation_utils.d.ts +1 -1
- package/dist/{util-CwLmSpGp.js → util-DtbWD7LF.js} +5312 -2580
- package/dist/util-DtbWD7LF.js.map +1 -0
- package/package.json +45 -39
- package/src/collection_editor/ConfigControllerProvider.tsx +1 -1
- package/src/collection_editor/ui/AddKanbanColumnAction.tsx +12 -2
- package/src/collection_editor/ui/CollectionViewHeaderAction.tsx +1 -2
- package/src/collection_editor/ui/EditorCollectionAction.tsx +1 -2
- package/src/collection_editor/ui/EditorCollectionActionStart.tsx +1 -2
- package/src/collection_editor/ui/EditorEntityAction.tsx +1 -2
- package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +1 -2
- package/src/collection_editor/ui/NewCollectionButton.tsx +1 -2
- package/src/collection_editor/ui/NewCollectionCard.tsx +4 -6
- package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +1 -2
- package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +10 -2
- package/src/collection_editor/ui/collection_editor/CollectionDetailsForm.tsx +18 -2
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +22 -7
- package/src/collection_editor/ui/collection_editor/CollectionEditorWelcomeView.tsx +16 -2
- package/src/collection_editor/ui/collection_editor/CollectionJsonImportDialog.tsx +19 -9
- package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +13 -2
- package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +24 -2
- package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +22 -3
- package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +1 -2
- package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +11 -2
- package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +12 -2
- package/src/collection_editor/ui/collection_editor/EntityActionsEditTab.tsx +16 -3
- package/src/collection_editor/ui/collection_editor/EnumForm.tsx +17 -2
- package/src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx +18 -2
- package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +1 -2
- package/src/collection_editor/ui/collection_editor/KanbanConfigSection.tsx +1 -2
- package/src/collection_editor/ui/collection_editor/LayoutModeSwitch.tsx +17 -5
- package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +32 -6
- package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +7 -7
- package/src/collection_editor/ui/collection_editor/PropertyTree.tsx +14 -2
- package/src/collection_editor/ui/collection_editor/SubcollectionsEditTab.tsx +16 -2
- package/src/collection_editor/ui/collection_editor/ViewModeSwitch.tsx +9 -2
- package/src/collection_editor/ui/collection_editor/properties/BlockPropertyField.tsx +1 -2
- package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +1 -2
- package/src/collection_editor/ui/collection_editor/properties/MarkdownPropertyField.tsx +9 -2
- package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +11 -2
- package/src/collection_editor/ui/collection_editor/properties/VectorPropertyField.tsx +34 -0
- package/src/collection_editor/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +15 -7
- package/src/collection_editor/ui/collection_editor/properties/conditions/ConditionsPanel.tsx +1 -2
- package/src/collection_editor/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +15 -3
- package/src/collection_editor/ui/collection_editor/properties/conditions/property_paths.ts +1 -1
- package/src/collection_editor/ui/collection_editor/properties/validation/ValidationPanel.tsx +1 -2
- package/src/collection_editor/useLocalCollectionsConfigController.tsx +0 -2
- package/src/collection_editor/validateCollectionJson.ts +9 -9
- package/src/components/AdminModeSyncer.tsx +1 -1
- package/src/components/ArrayContainer.tsx +19 -15
- package/src/components/ClearFilterSortButton.tsx +1 -2
- package/src/components/CollectionEditorDialogs.tsx +1 -1
- package/src/components/DefaultAppBar.tsx +15 -3
- package/src/components/DefaultDrawer.tsx +3 -3
- package/src/components/DrawerNavigationGroup.tsx +1 -2
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +19 -9
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +2 -2
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +1 -1
- package/src/components/EntityCollectionTable/fields/TableMultipleRelationField.tsx +1 -2
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +1 -2
- package/src/components/EntityCollectionTable/fields/TableRelationField.tsx +1 -2
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +1 -2
- package/src/components/EntityCollectionTable/fields/VirtualTableSelect.tsx +0 -1
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +15 -27
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +3 -4
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -2
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -5
- package/src/components/EntityCollectionTable/table_bindings.tsx +51 -45
- package/src/components/EntityCollectionView/Board.tsx +1 -2
- package/src/components/EntityCollectionView/BoardColumn.tsx +9 -2
- package/src/components/EntityCollectionView/BoardColumnTitle.tsx +5 -4
- package/src/components/EntityCollectionView/EntityCard.tsx +2 -2
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +18 -16
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +16 -17
- package/src/components/EntityCollectionView/EntityCollectionListView.tsx +90 -21
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +20 -11
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +6 -7
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +14 -5
- package/src/components/EntityCollectionView/FilterPresetsButton.tsx +292 -0
- package/src/components/EntityCollectionView/FiltersDialog.tsx +1 -2
- package/src/components/EntityCollectionView/SplitListView.tsx +76 -25
- package/src/components/EntityCollectionView/ViewModeToggle.tsx +20 -7
- package/src/components/EntityCollectionView/hooks/useKanbanDragAndDrop.ts +1 -1
- package/src/components/EntityCollectionView/useBoardDataController.tsx +74 -6
- package/src/components/EntityCollectionView/useEntityPreviewSlots.ts +1 -1
- package/src/components/EntityDetailView.tsx +619 -0
- package/src/components/EntityEditView.tsx +29 -10
- package/src/components/EntityEditViewFormActions.tsx +20 -7
- package/src/components/EntityPreview.tsx +14 -5
- package/src/components/EntitySidePanel.tsx +116 -62
- package/src/components/EntityView.tsx +1 -2
- package/src/components/HomePage/ContentHomePage.tsx +1 -1
- package/src/components/HomePage/FavouritesView.tsx +1 -2
- package/src/components/HomePage/NavigationCard.tsx +1 -2
- package/src/components/HomePage/NavigationCardBinding.tsx +1 -2
- package/src/components/HomePage/NavigationGroup.tsx +1 -2
- package/src/components/HomePage/SmallNavigationCard.tsx +1 -2
- package/src/components/PropertyIdCopyTooltip.tsx +1 -2
- package/src/components/RebaseAuthGate.tsx +2 -2
- package/src/components/RebaseNavigation.tsx +9 -7
- package/src/components/ReferenceTable/EntitySelectionTable.tsx +12 -8
- package/src/components/RelationSelector.tsx +34 -6
- package/src/components/SearchIconsView.tsx +10 -2
- package/src/components/SelectableTable/SelectableTable.tsx +4 -4
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +1 -2
- package/src/components/SideDialogs.tsx +63 -38
- package/src/components/UserSelector.tsx +30 -6
- package/src/components/admin/CreationResultDialog.tsx +135 -0
- package/src/components/admin/RolesFilterSelect.tsx +45 -0
- package/src/components/admin/RolesView.tsx +53 -14
- package/src/components/admin/UserRolesSelectField.tsx +50 -0
- package/src/components/admin/UsersView.tsx +41 -124
- package/src/components/app/Scaffold.tsx +1 -2
- package/src/components/common/default_entity_actions.tsx +119 -12
- package/src/components/field_configs.tsx +39 -3
- package/src/components/history/EntityHistoryEntry.tsx +1 -2
- package/src/components/history/EntityHistoryView.tsx +1 -2
- package/src/components/index.ts +2 -0
- package/src/data_export/export/BasicExportAction.tsx +35 -38
- package/src/data_export/export/ExportCollectionAction.tsx +39 -40
- package/src/data_import/components/DataNewPropertiesMapping.tsx +15 -2
- package/src/data_import/components/ImportFileUpload.tsx +1 -2
- package/src/data_import/components/ImportNewPropertyFieldPreview.tsx +1 -2
- package/src/data_import/import/ImportCollectionAction.tsx +21 -8
- package/src/data_import/utils/data.ts +23 -5
- package/src/data_import/utils/file_headers.ts +13 -89
- package/src/data_import/utils/file_to_json.ts +43 -68
- package/src/data_import/utils/transforms.ts +47 -0
- package/src/editor/components/SlashCommandMenu.tsx +17 -2
- package/src/editor/components/editor-bubble-item.tsx +1 -1
- package/src/editor/extensions/Image/index.ts +1 -1
- package/src/editor/extensions/Image.ts +1 -1
- package/src/editor/selectors/color-selector.tsx +1 -2
- package/src/editor/selectors/link-selector.tsx +1 -2
- package/src/editor/selectors/node-selector.tsx +16 -2
- package/src/editor/selectors/text-buttons.tsx +1 -2
- package/src/editor/utils/prosemirror-utils.ts +1 -1
- package/src/form/EntityForm.tsx +16 -6
- package/src/form/EntityFormActions.tsx +11 -3
- package/src/form/PropertyFieldBinding.tsx +5 -12
- package/src/form/components/FieldHelperText.tsx +1 -2
- package/src/form/components/LocalChangesMenu.tsx +17 -2
- package/src/form/components/StorageItemPreview.tsx +1 -2
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +1 -2
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +17 -2
- package/src/form/field_bindings/MapFieldBinding.tsx +1 -1
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +10 -3
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +1 -2
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +1 -2
- package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +7 -7
- package/src/form/field_bindings/RelationFieldBinding.tsx +150 -147
- package/src/form/field_bindings/RepeatFieldBinding.tsx +1 -1
- package/src/form/field_bindings/SelectFieldBinding.tsx +1 -2
- package/src/form/field_bindings/TextFieldBinding.tsx +10 -2
- package/src/form/field_bindings/VectorFieldBinding.tsx +202 -0
- package/src/form/index.tsx +1 -0
- package/src/form/validation.ts +54 -2
- package/src/hooks/navigation/useBuildNavigationStateController.tsx +2 -1
- package/src/hooks/navigation/useResolvedViews.tsx +30 -15
- package/src/hooks/navigation/useTopLevelNavigation.ts +1 -1
- package/src/index.ts +6 -0
- package/src/preview/PropertyPreview.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +1 -1
- package/src/preview/components/UrlComponentPreview.tsx +1 -2
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +2 -2
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +23 -24
- package/src/routes/RebaseRoute.tsx +64 -35
- package/src/types/components/EntityFormActionsProps.tsx +1 -1
- package/src/types/components/EntityFormProps.tsx +3 -1
- package/src/types/fields.tsx +4 -3
- package/src/util/navigation_utils.ts +4 -3
- package/src/util/previews.ts +1 -1
- package/src/util/property_utils.tsx +22 -6
- package/src/util/resolutions.ts +2 -2
- package/dist/CollectionEditorDialog-MbvXGzEq.js.map +0 -1
- package/dist/CollectionsStudioView-D9X6aiAr.js.map +0 -1
- package/dist/ContentHomePage-CfVB1eUo.js.map +0 -1
- package/dist/ExportCollectionAction-CUwJg4F9.js.map +0 -1
- package/dist/ImportCollectionAction-DGa_SF_8.js.map +0 -1
- package/dist/PropertyEditView-C4nlYmAc.js.map +0 -1
- package/dist/RolesView-CNWxnR8e.js.map +0 -1
- package/dist/UsersView-YiTIcXkA.js.map +0 -1
- package/dist/index-CtzpHzMQ.js.map +0 -1
- package/dist/index-DKlrVD1m.js.map +0 -1
- package/dist/index-kHJXfLNI.js.map +0 -1
- package/dist/util-CwLmSpGp.js.map +0 -1
|
@@ -4,8 +4,15 @@ import { CSS } from "@dnd-kit/utilities";
|
|
|
4
4
|
import { BoardSortableList } from "./BoardSortableList";
|
|
5
5
|
import { BoardColumnTitle } from "./BoardColumnTitle";
|
|
6
6
|
import { BoardItem, BoardItemViewProps } from "./board_types";
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import {
|
|
8
|
+
ChipColorKey,
|
|
9
|
+
ChipColorScheme,
|
|
10
|
+
cls,
|
|
11
|
+
defaultBorderMixin,
|
|
12
|
+
IconButton,
|
|
13
|
+
iconSize,
|
|
14
|
+
PlusIcon
|
|
15
|
+
} from "@rebasepro/ui";
|
|
9
16
|
|
|
10
17
|
export interface BoardColumnProps<M extends Record<string, unknown>> {
|
|
11
18
|
id: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChipColorKey, ChipColorScheme, getColorSchemeForKey, cls } from "@rebasepro/ui";
|
|
1
|
+
import { ChipColorKey, ChipColorScheme, getColorSchemeForKey, cls, Typography } from "@rebasepro/ui";
|
|
2
2
|
import React, { useMemo } from "react";
|
|
3
3
|
|
|
4
4
|
export interface BoardColumnTitleProps {
|
|
@@ -23,10 +23,11 @@ export function BoardColumnTitle({
|
|
|
23
23
|
}, [color]);
|
|
24
24
|
|
|
25
25
|
return (
|
|
26
|
-
<
|
|
26
|
+
<Typography
|
|
27
|
+
variant="subtitle2"
|
|
28
|
+
component="h4"
|
|
27
29
|
className={
|
|
28
30
|
cls("py-3 px-3 transition-colors duration-200 flex-grow select-none relative outline-none focus:outline focus:outline-2 focus:outline-offset-2 flex items-center gap-3",
|
|
29
|
-
"text-sm font-semibold text-surface-900 dark:text-surface-200",
|
|
30
31
|
className)
|
|
31
32
|
}
|
|
32
33
|
{...props}
|
|
@@ -40,6 +41,6 @@ export function BoardColumnTitle({
|
|
|
40
41
|
/>
|
|
41
42
|
)}
|
|
42
43
|
{children}
|
|
43
|
-
</
|
|
44
|
+
</Typography>
|
|
44
45
|
);
|
|
45
46
|
}
|
|
@@ -94,8 +94,8 @@ export function EntityCard<M extends Record<string, unknown> = Record<string, un
|
|
|
94
94
|
"cursor-pointer overflow-hidden group relative",
|
|
95
95
|
"transition-all duration-200",
|
|
96
96
|
"hover:shadow-lg hover:-translate-y-0.5",
|
|
97
|
-
selected && "ring-2 ring-primary bg-surface-accent-50 dark:bg-surface-accent-
|
|
98
|
-
highlighted && !selected && "ring-2 ring-primary ring-opacity-50 bg-surface-accent-50/50 dark:bg-surface-accent-
|
|
97
|
+
selected && "ring-2 ring-primary bg-surface-accent-50 dark:bg-surface-accent-900",
|
|
98
|
+
highlighted && !selected && "ring-2 ring-primary ring-opacity-50 bg-surface-accent-50/50 dark:bg-surface-accent-900"
|
|
99
99
|
)}
|
|
100
100
|
onClick={handleClick}
|
|
101
101
|
>
|
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
|
|
2
2
|
import type { EntityCollection } from "@rebasepro/types";
|
|
3
|
-
import type { Property } from "@rebasepro/types";
|
|
4
3
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
-
import { Entity, EntityTableController, EnumValueConfig,
|
|
4
|
+
import { Entity, EntityTableController, EnumValueConfig, SaveEntityProps, SelectionController } from "@rebasepro/types";
|
|
6
5
|
import { Board } from "./Board";
|
|
7
6
|
import { BoardItem, BoardItemViewProps, ColumnLoadingState } from "./board_types";
|
|
8
7
|
import { EntityBoardCard } from "./EntityBoardCard";
|
|
9
|
-
import {
|
|
10
|
-
|
|
8
|
+
import {
|
|
9
|
+
Button,
|
|
10
|
+
ChipColorKey,
|
|
11
|
+
ChipColorScheme,
|
|
12
|
+
CircularProgress,
|
|
13
|
+
Dialog,
|
|
14
|
+
DialogActions,
|
|
15
|
+
DialogContent,
|
|
16
|
+
getColorSchemeForSeed,
|
|
17
|
+
IconButton,
|
|
18
|
+
iconSize,
|
|
19
|
+
RefreshCwIcon,
|
|
20
|
+
Tooltip,
|
|
21
|
+
Typography
|
|
22
|
+
} from "@rebasepro/ui";
|
|
11
23
|
import { resolveEnumValues } from "@rebasepro/common";
|
|
12
24
|
import { getPropertyInPath } from "../../util/property_utils";
|
|
13
25
|
import {
|
|
@@ -58,7 +70,6 @@ export function EntityCollectionBoardView<M extends Record<string, unknown> = Re
|
|
|
58
70
|
emptyComponent,
|
|
59
71
|
deletedEntities
|
|
60
72
|
}: EntityCollectionBoardViewProps<M>) {
|
|
61
|
-
const authController = useAuthController();
|
|
62
73
|
const customizationController = useCustomizationController();
|
|
63
74
|
const context = useRebaseContext();
|
|
64
75
|
const dataClient = useData();
|
|
@@ -245,7 +256,6 @@ export function EntityCollectionBoardView<M extends Record<string, unknown> = Re
|
|
|
245
256
|
|
|
246
257
|
useEffect(() => {
|
|
247
258
|
const currentDataClient = dataClientRef.current;
|
|
248
|
-
const currentCollection = collectionRef.current;
|
|
249
259
|
const accessor = currentDataClient.collection(fullPath);
|
|
250
260
|
|
|
251
261
|
if (!orderProperty || !accessor.count) {
|
|
@@ -351,9 +361,7 @@ export function EntityCollectionBoardView<M extends Record<string, unknown> = Re
|
|
|
351
361
|
|
|
352
362
|
// Backfill order values for all entities
|
|
353
363
|
const handleBackfill = useCallback(async () => {
|
|
354
|
-
console.log("handleBackfill called", { orderProperty });
|
|
355
364
|
if (!orderProperty) {
|
|
356
|
-
console.log("No orderProperty, returning");
|
|
357
365
|
return;
|
|
358
366
|
}
|
|
359
367
|
analyticsController.onAnalyticsEvent?.("kanban_backfill_order", {
|
|
@@ -363,19 +371,16 @@ export function EntityCollectionBoardView<M extends Record<string, unknown> = Re
|
|
|
363
371
|
|
|
364
372
|
try {
|
|
365
373
|
// Fetch ALL documents from collection (not relying on loaded entities)
|
|
366
|
-
console.log("Fetching all documents from collection...");
|
|
367
374
|
const allDocsRes = await dataClient.collection(fullPath).find({
|
|
368
375
|
limit: 10000 // Fetch all
|
|
369
376
|
});
|
|
370
377
|
const allDocs = allDocsRes.data as Entity<M>[];
|
|
371
|
-
console.log(`Fetched ${allDocs.length} documents`);
|
|
372
378
|
|
|
373
379
|
// Find entities missing order property
|
|
374
380
|
const entitiesToUpdate = allDocs.filter((entity: Entity<M>) => {
|
|
375
381
|
const orderValue = entity.values?.[orderProperty];
|
|
376
382
|
return orderValue === undefined || orderValue === null;
|
|
377
383
|
});
|
|
378
|
-
console.log(`${entitiesToUpdate.length} entities need order values`);
|
|
379
384
|
|
|
380
385
|
// Generate string fractional keys for all entities that need them
|
|
381
386
|
const keys = generateNKeysBetween(null, null, entitiesToUpdate.length);
|
|
@@ -404,9 +409,7 @@ export function EntityCollectionBoardView<M extends Record<string, unknown> = Re
|
|
|
404
409
|
);
|
|
405
410
|
});
|
|
406
411
|
|
|
407
|
-
console.log(`Total updates to run: ${updates.length}`);
|
|
408
412
|
await Promise.all(updates);
|
|
409
|
-
console.log("All updates complete");
|
|
410
413
|
setShowBackfillDialog(false);
|
|
411
414
|
|
|
412
415
|
// Reset missing count to hide banner
|
|
@@ -456,7 +459,6 @@ export function EntityCollectionBoardView<M extends Record<string, unknown> = Re
|
|
|
456
459
|
// Uses refs for ALL dynamic values so the component type never changes.
|
|
457
460
|
// When ItemComponent identity changes, React.memo'd SortableItem remounts
|
|
458
461
|
// the card → DOM is destroyed/recreated → CSS :hover state is lost → flicker.
|
|
459
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
460
462
|
const ItemComponent = useMemo(() => {
|
|
461
463
|
const Comp = (props: BoardItemViewProps<M>) => (
|
|
462
464
|
<EntityBoardCard
|
|
@@ -479,7 +481,7 @@ export function EntityCollectionBoardView<M extends Record<string, unknown> = Re
|
|
|
479
481
|
parentCollectionSlugs,
|
|
480
482
|
parentEntityIds
|
|
481
483
|
});
|
|
482
|
-
|
|
484
|
+
|
|
483
485
|
|
|
484
486
|
// Get AddKanbanColumnComponent from plugin slots
|
|
485
487
|
const addKanbanColumnSlots = useSlot("kanban.add-column", {
|
|
@@ -488,7 +490,7 @@ export function EntityCollectionBoardView<M extends Record<string, unknown> = Re
|
|
|
488
490
|
parentCollectionSlugs, parentEntityIds,
|
|
489
491
|
columnProperty
|
|
490
492
|
});
|
|
491
|
-
|
|
493
|
+
|
|
492
494
|
|
|
493
495
|
// Check for loading error
|
|
494
496
|
const hasError = Boolean(dataLoadingError);
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
CircularProgress,
|
|
8
8
|
Typography
|
|
9
9
|
} from "@rebasepro/ui";
|
|
10
|
-
import { useAuthController, useCustomizationController } from "@rebasepro/core";
|
|
11
10
|
|
|
12
11
|
export type EntityCollectionCardViewProps<M extends Record<string, unknown> = Record<string, unknown>> = {
|
|
13
12
|
collection: EntityCollection<M>;
|
|
@@ -77,8 +76,6 @@ export function EntityCollectionCardView<M extends Record<string, unknown> = Rec
|
|
|
77
76
|
initialScroll,
|
|
78
77
|
size = "m"
|
|
79
78
|
}: EntityCollectionCardViewProps<M>) {
|
|
80
|
-
const authController = useAuthController();
|
|
81
|
-
const customizationController = useCustomizationController();
|
|
82
79
|
|
|
83
80
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
84
81
|
const loadMoreRef = useRef<HTMLDivElement>(null);
|
|
@@ -98,28 +95,30 @@ export function EntityCollectionCardView<M extends Record<string, unknown> = Rec
|
|
|
98
95
|
// Track if we're currently loading to prevent multiple simultaneous load requests
|
|
99
96
|
const isLoadingMore = useRef(false);
|
|
100
97
|
|
|
101
|
-
//
|
|
98
|
+
// Keep mutable refs for values used in the IntersectionObserver callback
|
|
99
|
+
// to avoid re-creating the observer every time pagination state changes.
|
|
100
|
+
const paginationStateRef = useRef({ paginationEnabled, noMoreToLoad, dataLoading, itemCount, pageSize });
|
|
102
101
|
useEffect(() => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
102
|
+
paginationStateRef.current = { paginationEnabled, noMoreToLoad, dataLoading, itemCount, pageSize };
|
|
103
|
+
}, [paginationEnabled, noMoreToLoad, dataLoading, itemCount, pageSize]);
|
|
106
104
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
// Reset loading flag when new data arrives (separate effect, like list view)
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
if (!dataLoading) isLoadingMore.current = false;
|
|
108
|
+
}, [dataLoading]);
|
|
111
109
|
|
|
110
|
+
// Infinite scroll with Intersection Observer — stable deps only
|
|
111
|
+
useEffect(() => {
|
|
112
112
|
const observer = new IntersectionObserver(
|
|
113
113
|
(entries) => {
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
const { paginationEnabled: pe, noMoreToLoad: nm, dataLoading: dl, itemCount: ic, pageSize: ps } = paginationStateRef.current;
|
|
115
|
+
if (entries[0].isIntersecting && pe && !dl && !nm && !isLoadingMore.current) {
|
|
116
116
|
isLoadingMore.current = true;
|
|
117
|
-
|
|
118
|
-
setItemCount?.((itemCount ?? pageSize) + pageSize);
|
|
117
|
+
setItemCount?.((ic ?? ps) + ps);
|
|
119
118
|
}
|
|
120
119
|
},
|
|
121
120
|
{
|
|
122
|
-
root: containerRef.current,
|
|
121
|
+
root: containerRef.current,
|
|
123
122
|
rootMargin: "400px",
|
|
124
123
|
threshold: 0
|
|
125
124
|
}
|
|
@@ -130,7 +129,7 @@ export function EntityCollectionCardView<M extends Record<string, unknown> = Rec
|
|
|
130
129
|
}
|
|
131
130
|
|
|
132
131
|
return () => observer.disconnect();
|
|
133
|
-
}, [
|
|
132
|
+
}, [setItemCount]);
|
|
134
133
|
|
|
135
134
|
// Scroll restoration — deferred to after layout paint
|
|
136
135
|
useEffect(() => {
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
|
|
2
2
|
import type { EntityCollection, Property } from "@rebasepro/types";
|
|
3
3
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
-
import { CollectionSize, Entity, EntityTableController, SelectionController } from "@rebasepro/types";
|
|
5
|
-
import { getEntityImagePreviewPropertyKey } from "@rebasepro/common";
|
|
4
|
+
import { CollectionSize, Entity, EntityAction, EntityTableController, SelectionController } from "@rebasepro/types";
|
|
6
5
|
import {
|
|
7
6
|
Checkbox,
|
|
8
7
|
Chip,
|
|
9
8
|
CircularProgress,
|
|
10
9
|
cls,
|
|
11
10
|
defaultBorderMixin,
|
|
11
|
+
IconButton,
|
|
12
|
+
Tooltip,
|
|
12
13
|
Typography
|
|
13
14
|
} from "@rebasepro/ui";
|
|
14
15
|
import { PropertyPreview } from "../../preview";
|
|
@@ -17,10 +18,12 @@ import {
|
|
|
17
18
|
useCustomizationController
|
|
18
19
|
} from "@rebasepro/core";
|
|
19
20
|
import { useAnalyticsController } from "@rebasepro/core";
|
|
20
|
-
import {
|
|
21
|
+
import { getEntityPreviewKeys } from "../../util/previews";
|
|
21
22
|
import { IconForView } from "@rebasepro/core";
|
|
22
23
|
import { getValueInPath } from "@rebasepro/utils";
|
|
23
24
|
import { useCollectionSlotKeys, resolveEntitySlots, type CollectionSlotKeys } from "./useEntityPreviewSlots";
|
|
25
|
+
import { useCMSContext } from "../../hooks/useCMSContext";
|
|
26
|
+
import { resolveEntityAction } from "../../util/resolutions";
|
|
24
27
|
|
|
25
28
|
export type EntityCollectionListViewProps<M extends Record<string, unknown> = Record<string, unknown>> = {
|
|
26
29
|
collection: EntityCollection<M>;
|
|
@@ -45,6 +48,22 @@ export type EntityCollectionListViewProps<M extends Record<string, unknown> = Re
|
|
|
45
48
|
* row is visually highlighted with a primary accent.
|
|
46
49
|
*/
|
|
47
50
|
selectedEntityId?: string | number;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Callback to get entity actions for a given entity.
|
|
54
|
+
* Only actions with `showActionsInListView: true` will be rendered.
|
|
55
|
+
*/
|
|
56
|
+
getActionsForEntity?: (params: { entity?: Entity<M>, customEntityActions?: EntityAction[] }) => EntityAction[];
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Full path of the collection, used as context for action handlers.
|
|
60
|
+
*/
|
|
61
|
+
path?: string;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* How entities open when an action triggers navigation.
|
|
65
|
+
*/
|
|
66
|
+
openEntityMode?: "side_panel" | "full_screen" | "split" | "dialog";
|
|
48
67
|
};
|
|
49
68
|
|
|
50
69
|
type ListColumnDef = {
|
|
@@ -58,19 +77,6 @@ type ListColumnDef = {
|
|
|
58
77
|
width: string;
|
|
59
78
|
};
|
|
60
79
|
|
|
61
|
-
/**
|
|
62
|
-
* Get the number of preview property lines to show based on size
|
|
63
|
-
*/
|
|
64
|
-
function getPreviewCount(size: CollectionSize): number {
|
|
65
|
-
switch (size) {
|
|
66
|
-
case "xs": return 0;
|
|
67
|
-
case "s": return 1;
|
|
68
|
-
case "m": return 2;
|
|
69
|
-
case "l": return 3;
|
|
70
|
-
case "xl": return 4;
|
|
71
|
-
default: return 2;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
80
|
|
|
75
81
|
|
|
76
82
|
/**
|
|
@@ -107,6 +113,9 @@ const OVERSCAN_COUNT = 8;
|
|
|
107
113
|
/** Threshold in pixels from the bottom of the scroll area to trigger loading more. */
|
|
108
114
|
const LOAD_MORE_THRESHOLD = 400;
|
|
109
115
|
|
|
116
|
+
/** Stable empty array for when no list-view actions are available. */
|
|
117
|
+
const EMPTY_LIST_VIEW_ACTIONS: EntityAction[] = [];
|
|
118
|
+
|
|
110
119
|
/**
|
|
111
120
|
* Walk up the DOM from `element` to find the nearest scrollable ancestor.
|
|
112
121
|
*/
|
|
@@ -262,11 +271,15 @@ export function EntityCollectionListView<M extends Record<string, unknown> = Rec
|
|
|
262
271
|
emptyComponent,
|
|
263
272
|
|
|
264
273
|
size = "m",
|
|
265
|
-
selectedEntityId
|
|
274
|
+
selectedEntityId,
|
|
275
|
+
getActionsForEntity,
|
|
276
|
+
path,
|
|
277
|
+
openEntityMode
|
|
266
278
|
}: EntityCollectionListViewProps<M>) {
|
|
267
279
|
const authController = useAuthController();
|
|
268
280
|
const customizationController = useCustomizationController();
|
|
269
281
|
const analyticsController = useAnalyticsController();
|
|
282
|
+
const context = useCMSContext();
|
|
270
283
|
|
|
271
284
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
272
285
|
const [containerWidth, setContainerWidth] = useState(1200);
|
|
@@ -475,6 +488,15 @@ export function EntityCollectionListView<M extends Record<string, unknown> = Rec
|
|
|
475
488
|
return highlightedEntities?.some(e => e.id === entity.id && e.path === entity.path) ?? false;
|
|
476
489
|
}, [highlightedEntities]);
|
|
477
490
|
|
|
491
|
+
// ── Compute list-view-visible actions per entity ──
|
|
492
|
+
const getListViewActions = useCallback((entity: Entity<M>): EntityAction[] => {
|
|
493
|
+
if (!getActionsForEntity) return EMPTY_LIST_VIEW_ACTIONS;
|
|
494
|
+
const customEntityActions = (collection.entityActions ?? [])
|
|
495
|
+
.map(action => resolveEntityAction(action, customizationController.entityActions))
|
|
496
|
+
.filter(Boolean) as EntityAction<M>[];
|
|
497
|
+
const allActions = getActionsForEntity({ entity, customEntityActions });
|
|
498
|
+
return allActions.filter(a => a.showActionsInListView);
|
|
499
|
+
}, [getActionsForEntity, collection.entityActions, customizationController.entityActions]);
|
|
478
500
|
|
|
479
501
|
const rowClasses = getRowClasses(size);
|
|
480
502
|
|
|
@@ -615,6 +637,11 @@ export function EntityCollectionListView<M extends Record<string, unknown> = Rec
|
|
|
615
637
|
size={size}
|
|
616
638
|
isLast={isLast}
|
|
617
639
|
isActive={selectedEntityId !== undefined && entity.id === selectedEntityId}
|
|
640
|
+
listViewActions={getListViewActions(entity)}
|
|
641
|
+
context={context}
|
|
642
|
+
path={path}
|
|
643
|
+
selectionController={selectionController}
|
|
644
|
+
openEntityMode={openEntityMode}
|
|
618
645
|
/>
|
|
619
646
|
</div>
|
|
620
647
|
);
|
|
@@ -668,7 +695,12 @@ const ListRow = React.memo(function ListRow<M extends Record<string, unknown>>({
|
|
|
668
695
|
showImage,
|
|
669
696
|
size,
|
|
670
697
|
isLast,
|
|
671
|
-
isActive = false
|
|
698
|
+
isActive = false,
|
|
699
|
+
listViewActions = [],
|
|
700
|
+
context,
|
|
701
|
+
path,
|
|
702
|
+
selectionController,
|
|
703
|
+
openEntityMode
|
|
672
704
|
}: {
|
|
673
705
|
entity: Entity<M>;
|
|
674
706
|
collection: EntityCollection<M>;
|
|
@@ -684,6 +716,11 @@ const ListRow = React.memo(function ListRow<M extends Record<string, unknown>>({
|
|
|
684
716
|
size: CollectionSize;
|
|
685
717
|
isLast: boolean;
|
|
686
718
|
isActive?: boolean;
|
|
719
|
+
listViewActions?: EntityAction[];
|
|
720
|
+
context?: ReturnType<typeof useCMSContext>;
|
|
721
|
+
path?: string;
|
|
722
|
+
selectionController?: SelectionController<M>;
|
|
723
|
+
openEntityMode?: "side_panel" | "full_screen" | "split" | "dialog";
|
|
687
724
|
}) {
|
|
688
725
|
// ── Resolve slots (pure function, no hooks) ──
|
|
689
726
|
const slots = resolveEntitySlots(
|
|
@@ -720,11 +757,11 @@ const ListRow = React.memo(function ListRow<M extends Record<string, unknown>>({
|
|
|
720
757
|
"flex items-center gap-4 cursor-pointer group transition-colors duration-200 relative h-full",
|
|
721
758
|
rowClasses,
|
|
722
759
|
isActive
|
|
723
|
-
? "bg-surface-accent-100 dark:bg-surface-accent-950 hover:bg-surface-accent-200 dark:hover:bg-surface-accent-
|
|
760
|
+
? "bg-surface-accent-100 dark:bg-surface-accent-950 hover:bg-surface-accent-200 dark:hover:bg-surface-accent-950"
|
|
724
761
|
: selected
|
|
725
|
-
? "bg-surface-accent-50 dark:bg-surface-accent-
|
|
762
|
+
? "bg-surface-accent-50 dark:bg-surface-accent-900 hover:bg-surface-accent-100 dark:hover:bg-surface-accent-950"
|
|
726
763
|
: highlighted
|
|
727
|
-
? "bg-surface-accent-50 dark:bg-surface-accent-
|
|
764
|
+
? "bg-surface-accent-50 dark:bg-surface-accent-900 hover:bg-surface-50 dark:hover:bg-surface-800/40"
|
|
728
765
|
: "bg-white dark:bg-surface-900 hover:bg-surface-50 dark:hover:bg-surface-800/40"
|
|
729
766
|
)}
|
|
730
767
|
onClick={handleClick}
|
|
@@ -898,6 +935,33 @@ const ListRow = React.memo(function ListRow<M extends Record<string, unknown>>({
|
|
|
898
935
|
)}
|
|
899
936
|
</div>
|
|
900
937
|
)}
|
|
938
|
+
|
|
939
|
+
{/* LIST VIEW ACTIONS — always visible on each row */}
|
|
940
|
+
{listViewActions.length > 0 && (
|
|
941
|
+
<div className="flex items-center gap-0.5 flex-shrink-0 ml-auto" onClick={(e) => e.stopPropagation()}>
|
|
942
|
+
{listViewActions.map((action, index) => (
|
|
943
|
+
<Tooltip key={action.key ?? index} title={action.name} asChild>
|
|
944
|
+
<IconButton
|
|
945
|
+
size="small"
|
|
946
|
+
onClick={(e: React.MouseEvent) => {
|
|
947
|
+
e.stopPropagation();
|
|
948
|
+
action.onClick({
|
|
949
|
+
view: "collection",
|
|
950
|
+
entity,
|
|
951
|
+
path,
|
|
952
|
+
collection,
|
|
953
|
+
context: context!,
|
|
954
|
+
sideEntityController: context?.sideEntityController,
|
|
955
|
+
selectionController,
|
|
956
|
+
openEntityMode: openEntityMode ?? collection?.openEntityMode ?? "full_screen"
|
|
957
|
+
});
|
|
958
|
+
}}>
|
|
959
|
+
{action.icon}
|
|
960
|
+
</IconButton>
|
|
961
|
+
</Tooltip>
|
|
962
|
+
))}
|
|
963
|
+
</div>
|
|
964
|
+
)}
|
|
901
965
|
</div>
|
|
902
966
|
);
|
|
903
967
|
}) as <M extends Record<string, unknown>>(props: {
|
|
@@ -915,5 +979,10 @@ const ListRow = React.memo(function ListRow<M extends Record<string, unknown>>({
|
|
|
915
979
|
size: CollectionSize;
|
|
916
980
|
isLast: boolean;
|
|
917
981
|
isActive?: boolean;
|
|
982
|
+
listViewActions?: EntityAction[];
|
|
983
|
+
context?: ReturnType<typeof useCMSContext>;
|
|
984
|
+
path?: string;
|
|
985
|
+
selectionController?: SelectionController<M>;
|
|
986
|
+
openEntityMode?: "side_panel" | "full_screen" | "split" | "dialog";
|
|
918
987
|
}) => React.ReactElement;
|
|
919
988
|
|
|
@@ -5,10 +5,11 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
|
5
5
|
|
|
6
6
|
import { deepEqual as equal } from "fast-equals"
|
|
7
7
|
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- used as fallback for many array types
|
|
8
9
|
const EMPTY_ARRAY: any[] = [];
|
|
9
10
|
const DEFAULT_ENTITY_OPEN_MODE = "split";
|
|
10
11
|
|
|
11
|
-
import { CollectionSize, Entity, EntityReference, EntityTableController, FilterValues, PartialEntityCollection,
|
|
12
|
+
import { CollectionSize, Entity, EntityReference, EntityTableController, FilterValues, PartialEntityCollection, ViewMode } from "@rebasepro/types";
|
|
12
13
|
import {
|
|
13
14
|
EntityCollectionRowActions,
|
|
14
15
|
EntityCollectionTable
|
|
@@ -22,7 +23,6 @@ import { resolveEntityAction } from "../../util/resolutions";
|
|
|
22
23
|
import { getPropertyInPath } from "../../util/property_utils";
|
|
23
24
|
import { ReferencePreview } from "../../preview";
|
|
24
25
|
import {
|
|
25
|
-
saveEntityWithCallbacks,
|
|
26
26
|
useAuthController,
|
|
27
27
|
useCustomizationController,
|
|
28
28
|
useData,
|
|
@@ -41,7 +41,7 @@ import { SplitListView } from "./SplitListView";
|
|
|
41
41
|
import { EntityCollectionBoardView } from "./EntityCollectionBoardView";
|
|
42
42
|
import { ViewModeToggle, KanbanPropertyOption } from "./ViewModeToggle";
|
|
43
43
|
import { Button, cls, focusedDisabled, IconButton, Markdown, Popover, Skeleton, Tooltip, Typography, VirtualTableColumn , iconSize } from "@rebasepro/ui";
|
|
44
|
-
import {
|
|
44
|
+
import { ArrowRightToLineIcon, ErrorBoundary, PlusIcon, SearchIcon } from "@rebasepro/ui";
|
|
45
45
|
import { setIn } from "@rebasepro/formex";
|
|
46
46
|
import { getSubcollectionColumnId } from "../EntityCollectionTable/internal/common";
|
|
47
47
|
import {
|
|
@@ -59,15 +59,14 @@ import { useSelectionController } from "./useSelectionController";
|
|
|
59
59
|
import { EntityCollectionViewStartActions } from "./EntityCollectionViewStartActions";
|
|
60
60
|
import { addRecentId, getRecentIds } from "./utils";
|
|
61
61
|
import { useScrollRestoration } from "@rebasepro/core";
|
|
62
|
-
import { ErrorBoundary } from "@rebasepro/ui";
|
|
63
62
|
import { mergeDeep } from "@rebasepro/utils";
|
|
64
63
|
import { useCollectionRegistryController, useUrlController, useSideEntityController, useCMSContext } from "../../index";
|
|
65
64
|
import { useBreadcrumbsController } from "../../index";
|
|
66
65
|
|
|
67
66
|
function getOpenEntityMode(
|
|
68
67
|
viewMode: ViewMode,
|
|
69
|
-
configuredMode?: "side_panel" | "full_screen" | "split"
|
|
70
|
-
): "side_panel" | "full_screen" | "split" {
|
|
68
|
+
configuredMode?: "side_panel" | "full_screen" | "split" | "dialog"
|
|
69
|
+
): "side_panel" | "full_screen" | "split" | "dialog" {
|
|
71
70
|
if (configuredMode) return configuredMode;
|
|
72
71
|
if (viewMode === "kanban") return "side_panel";
|
|
73
72
|
if (viewMode === "table" || viewMode === "cards") return "full_screen";
|
|
@@ -671,10 +670,14 @@ export const EntityCollectionView = React.memo(
|
|
|
671
670
|
customEntityActions?: EntityAction[]
|
|
672
671
|
}): EntityAction[] => {
|
|
673
672
|
const deleteEnabled = entity ? canDelete(collection, path, entity) : true;
|
|
674
|
-
const
|
|
675
|
-
|
|
673
|
+
const disableActions = collection.disableDefaultActions ?? [];
|
|
674
|
+
const actions: EntityAction[] = [];
|
|
675
|
+
if (!disableActions.includes("edit")) {
|
|
676
|
+
actions.push(editEntityAction);
|
|
677
|
+
}
|
|
678
|
+
if (createEnabled && !disableActions.includes("copy"))
|
|
676
679
|
actions.push(copyEntityAction);
|
|
677
|
-
if (deleteEnabled)
|
|
680
|
+
if (deleteEnabled && !disableActions.includes("delete"))
|
|
678
681
|
actions.push(deleteEntityAction);
|
|
679
682
|
if (customEntityActions)
|
|
680
683
|
return mergeEntityActions(actions, customEntityActions);
|
|
@@ -771,8 +774,8 @@ export const EntityCollectionView = React.memo(
|
|
|
771
774
|
propertyKey,
|
|
772
775
|
onHover,
|
|
773
776
|
path,
|
|
774
|
-
collection: collection as
|
|
775
|
-
tableController: tableController as
|
|
777
|
+
collection: collection as EntityCollection,
|
|
778
|
+
tableController: tableController as EntityTableController,
|
|
776
779
|
parentCollectionSlugs: parentCollectionSlugs ?? EMPTY_ARRAY, parentEntityIds: parentEntityIds ?? EMPTY_ARRAY
|
|
777
780
|
};
|
|
778
781
|
return <>{headerActionContributions.map((s, i) => (
|
|
@@ -953,6 +956,9 @@ export const EntityCollectionView = React.memo(
|
|
|
953
956
|
highlightedEntities={highlightedEntity ? [highlightedEntity] : []}
|
|
954
957
|
size={listSize}
|
|
955
958
|
emptyComponent={emptyComponent}
|
|
959
|
+
getActionsForEntity={getActionsForEntity}
|
|
960
|
+
path={path}
|
|
961
|
+
openEntityMode={openEntityMode}
|
|
956
962
|
/>
|
|
957
963
|
) : (
|
|
958
964
|
<EntityCollectionTable
|
|
@@ -1074,6 +1080,9 @@ export const EntityCollectionView = React.memo(
|
|
|
1074
1080
|
size={listSize}
|
|
1075
1081
|
emptyComponent={emptyComponent}
|
|
1076
1082
|
selectedEntityId={selectedEntityIdProp}
|
|
1083
|
+
getActionsForEntity={getActionsForEntity}
|
|
1084
|
+
path={path}
|
|
1085
|
+
openEntityMode={openEntityMode}
|
|
1077
1086
|
/>
|
|
1078
1087
|
</div>
|
|
1079
1088
|
) : (
|
|
@@ -5,11 +5,10 @@ import React, { lazy, Suspense } from "react";
|
|
|
5
5
|
import { useLargeLayout, useTranslation, useSlot, resolveComponentRef } from "@rebasepro/core";
|
|
6
6
|
import { CollectionActionsProps, EntityTableController, SelectionController } from "@rebasepro/types";
|
|
7
7
|
import { Button, IconButton, Tooltip, Popover, iconSize } from "@rebasepro/ui";
|
|
8
|
-
import { PlusIcon, Trash2Icon
|
|
9
|
-
import { ErrorBoundary } from "@rebasepro/ui";
|
|
8
|
+
import { ErrorBoundary, MoreVerticalIcon, PlusIcon, Trash2Icon } from "@rebasepro/ui";
|
|
10
9
|
import { usePermissions } from "@rebasepro/core";
|
|
11
10
|
import { toArray } from "@rebasepro/utils";
|
|
12
|
-
// Lazy-load import/export — pulls in
|
|
11
|
+
// Lazy-load import/export — pulls in exceljs only on demand
|
|
13
12
|
const ImportCollectionAction = lazy(() => import("../../data_import/import").then(m => ({ default: m.ImportCollectionAction })));
|
|
14
13
|
const ExportCollectionAction = lazy(() => import("../../data_export/export").then(m => ({ default: m.ExportCollectionAction })));
|
|
15
14
|
import { EditorCollectionAction } from "../../collection_editor/ui/EditorCollectionAction";
|
|
@@ -135,7 +134,7 @@ export function EntityCollectionViewActions<M extends Record<string, unknown>>({
|
|
|
135
134
|
);
|
|
136
135
|
});
|
|
137
136
|
|
|
138
|
-
const pluginActions = useSlot("collection.actions", actionProps as
|
|
137
|
+
const pluginActions = useSlot("collection.actions", actionProps as CollectionActionsProps);
|
|
139
138
|
|
|
140
139
|
const secondaryActions = (
|
|
141
140
|
<>
|
|
@@ -146,17 +145,17 @@ export function EntityCollectionViewActions<M extends Record<string, unknown>>({
|
|
|
146
145
|
</ErrorBoundary>
|
|
147
146
|
<ErrorBoundary>
|
|
148
147
|
<Suspense fallback={null}>
|
|
149
|
-
<ImportCollectionAction {...(actionProps as
|
|
148
|
+
<ImportCollectionAction {...(actionProps as CollectionActionsProps)}/>
|
|
150
149
|
</Suspense>
|
|
151
150
|
</ErrorBoundary>
|
|
152
151
|
<ErrorBoundary>
|
|
153
152
|
<Suspense fallback={null}>
|
|
154
|
-
<ExportCollectionAction {...(actionProps as
|
|
153
|
+
<ExportCollectionAction {...(actionProps as CollectionActionsProps)}/>
|
|
155
154
|
</Suspense>
|
|
156
155
|
</ErrorBoundary>
|
|
157
156
|
{hasCollectionEditor && (
|
|
158
157
|
<ErrorBoundary>
|
|
159
|
-
<EditorCollectionAction {...(actionProps as
|
|
158
|
+
<EditorCollectionAction {...(actionProps as CollectionActionsProps)}/>
|
|
160
159
|
</ErrorBoundary>
|
|
161
160
|
)}
|
|
162
161
|
</>
|
|
@@ -4,10 +4,10 @@ import React, { useState, useCallback } from "react";
|
|
|
4
4
|
import { useAuthController, useLargeLayout, useTranslation, useSlot } from "@rebasepro/core";
|
|
5
5
|
import { CollectionActionsProps, EntityTableController, SelectionController } from "@rebasepro/types";
|
|
6
6
|
import { ErrorBoundary , iconSize } from "@rebasepro/ui";
|
|
7
|
-
import { ArrowLeftIcon, FilterIcon } from "
|
|
7
|
+
import { ArrowLeftIcon, Badge, Button, cls, FilterIcon, IconButton, Tooltip } from "@rebasepro/ui";
|
|
8
8
|
import { ClearFilterSortButton } from "../ClearFilterSortButton";
|
|
9
9
|
import { FiltersDialog } from "./FiltersDialog";
|
|
10
|
-
import {
|
|
10
|
+
import { FilterPresetsButton } from "./FilterPresetsButton";
|
|
11
11
|
import { toArray } from "@rebasepro/utils";
|
|
12
12
|
import { useNavigate } from "react-router-dom";
|
|
13
13
|
import { useUrlController, useCMSContext } from "../../index";
|
|
@@ -92,7 +92,6 @@ export function EntityCollectionViewStartActions<M extends Record<string, unknow
|
|
|
92
92
|
</Tooltip>
|
|
93
93
|
);
|
|
94
94
|
|
|
95
|
-
// Filters button
|
|
96
95
|
const filtersButton = resolvedProperties && tableController.setFilterValues && (
|
|
97
96
|
<Tooltip title={t("filters")}
|
|
98
97
|
key={"filters_tooltip"}>
|
|
@@ -108,7 +107,7 @@ export function EntityCollectionViewStartActions<M extends Record<string, unknow
|
|
|
108
107
|
startIcon={<FilterIcon size={iconSize.small}/>}
|
|
109
108
|
className={cls(activeFilterCount > 0 && "text-primary")}
|
|
110
109
|
>
|
|
111
|
-
{
|
|
110
|
+
{activeFilterCount > 0 ? `(${activeFilterCount})` : t("filters")}
|
|
112
111
|
</Button>
|
|
113
112
|
) : (
|
|
114
113
|
<Button
|
|
@@ -124,13 +123,23 @@ export function EntityCollectionViewStartActions<M extends Record<string, unknow
|
|
|
124
123
|
</Tooltip>
|
|
125
124
|
);
|
|
126
125
|
|
|
126
|
+
const filterPresetsButton = collection.filterPresets?.length ? (
|
|
127
|
+
<FilterPresetsButton
|
|
128
|
+
key={"filter_presets"}
|
|
129
|
+
filterPresets={collection.filterPresets}
|
|
130
|
+
tableController={tableController}
|
|
131
|
+
compact={compact}
|
|
132
|
+
/>
|
|
133
|
+
) : null;
|
|
134
|
+
|
|
127
135
|
const actions: React.ReactNode[] = [
|
|
128
136
|
backButton,
|
|
129
137
|
filtersButton,
|
|
130
138
|
<ClearFilterSortButton
|
|
131
139
|
key={"clear_filter"}
|
|
132
140
|
tableController={tableController}
|
|
133
|
-
enabled={!collection.fixedFilter}
|
|
141
|
+
enabled={!collection.fixedFilter}/>,
|
|
142
|
+
filterPresetsButton
|
|
134
143
|
];
|
|
135
144
|
|
|
136
145
|
const pluginActionsStart = useSlot("collection.actions.start", actionProps);
|