@rebasepro/admin 0.6.1 → 0.8.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-HNXGxXdO.js → CollectionEditorDialog-BO_aQ-Z4.js} +236 -155
- package/dist/CollectionEditorDialog-BO_aQ-Z4.js.map +1 -0
- package/dist/{PropertyEditView-C2wp8kQ9.js → PropertyEditView-DKzOpMjR.js} +190 -50
- package/dist/PropertyEditView-DKzOpMjR.js.map +1 -0
- package/dist/{CollectionsStudioView-B1mN33GB.js → RouterCollectionsStudioView-BQTIExjA.js} +61 -39
- package/dist/RouterCollectionsStudioView-BQTIExjA.js.map +1 -0
- package/dist/collection_editor/_cms_internals.d.ts +1 -1
- package/dist/collection_editor/api/generateCollectionApi.d.ts +3 -2
- package/dist/collection_editor/extensibility_types.d.ts +135 -0
- package/dist/collection_editor/index.d.ts +6 -0
- package/dist/collection_editor/serializable_types.d.ts +370 -0
- package/dist/collection_editor/serializable_utils.d.ts +50 -0
- package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +3 -3
- package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +12 -1
- package/dist/collection_editor/ui/collection_editor/CollectionStudioView.d.ts +13 -1
- package/dist/collection_editor/ui/collection_editor/CollectionsStudioView.d.ts +24 -2
- package/dist/collection_editor/ui/collection_editor/DisplaySettingsForm.d.ts +2 -1
- package/dist/collection_editor/ui/collection_editor/GeneralSettingsForm.d.ts +4 -1
- package/dist/collection_editor/ui/collection_editor/PropertyEditView.d.ts +12 -1
- package/dist/collection_editor/ui/collection_editor/RouterCollectionStudioView.d.ts +15 -0
- package/dist/collection_editor/ui/collection_editor/RouterCollectionsStudioView.d.ts +14 -0
- package/dist/collection_editor/useJsonCollectionsConfigController.d.ts +37 -0
- package/dist/collection_editor/useSafeSnackbarController.d.ts +2 -0
- package/dist/collection_editor_ui.d.ts +4 -0
- package/dist/collection_editor_ui.js +33 -4
- package/dist/collection_editor_ui.js.map +1 -0
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/index.d.ts +1 -1
- package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +3 -3
- package/dist/components/EntityCollectionView/hooks/useKanbanDragAndDrop.d.ts +3 -3
- package/dist/components/EntityEditView.d.ts +3 -2
- package/dist/components/RebaseCMS.d.ts +1 -1
- package/dist/components/SelectableTable/SelectionStore.d.ts +12 -21
- package/dist/components/field_configs.d.ts +1 -1
- package/dist/editor/editor.d.ts +0 -6
- package/dist/editor.js +1 -3
- package/dist/editor.js.map +1 -1
- package/dist/form/EntityForm.d.ts +10 -9
- package/dist/form/EntityFormBinding.d.ts +27 -0
- package/dist/form/components/StorageUploadProgress.d.ts +6 -1
- package/dist/form/form_utils.d.ts +8 -0
- package/dist/form/index.d.ts +5 -2
- package/dist/{history-BO6VT85a.js → history-B3cqBzEV.js} +2 -2
- package/dist/{history-BO6VT85a.js.map → history-B3cqBzEV.js.map} +1 -1
- package/dist/hooks/navigation/contexts/CollectionRegistryContext.d.ts +1 -1
- package/dist/hooks/navigation/useAsyncResolver.d.ts +26 -0
- package/dist/hooks/navigation/useBuildCollectionRegistryController.d.ts +2 -0
- package/dist/hooks/navigation/useTopLevelNavigation.d.ts +1 -1
- package/dist/hooks/navigation/utils.d.ts +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -2
- package/dist/preview/components/StorageThumbnail.d.ts +3 -1
- package/dist/routes/CustomViewRoute.d.ts +2 -1
- package/dist/{src-BYniefVu.js → src-cxV1ODRG.js} +1731 -1710
- package/dist/src-cxV1ODRG.js.map +1 -0
- package/dist/types/components/EntityFormActionsProps.d.ts +1 -1
- package/dist/types/components/EntityFormProps.d.ts +59 -0
- package/dist/types/components/PropertyPreviewProps.d.ts +2 -1
- package/dist/types/fields.d.ts +10 -7
- package/dist/util/dataControllerAdapter.d.ts +30 -0
- package/dist/util/navigation_utils.d.ts +1 -1
- package/dist/util/propertyConfigMapper.d.ts +17 -0
- package/package.json +8 -8
- package/src/collection_editor/_cms_internals.ts +1 -1
- package/src/collection_editor/api/generateCollectionApi.ts +3 -2
- package/src/collection_editor/extensibility_types.ts +168 -0
- package/src/collection_editor/index.ts +46 -0
- package/src/collection_editor/pgColumnToProperty.ts +2 -2
- package/src/collection_editor/serializable_types.ts +474 -0
- package/src/collection_editor/serializable_utils.ts +576 -0
- package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +6 -6
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +170 -89
- package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +95 -78
- package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +23 -20
- package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +79 -27
- package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +9 -7
- package/src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx +22 -5
- package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +154 -18
- package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +6 -6
- package/src/collection_editor/ui/collection_editor/PropertyTree.tsx +1 -0
- package/src/collection_editor/ui/collection_editor/RouterCollectionStudioView.tsx +44 -0
- package/src/collection_editor/ui/collection_editor/RouterCollectionsStudioView.tsx +41 -0
- package/src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx +4 -3
- package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +35 -1
- package/src/collection_editor/ui/collection_editor/templates/blog_template.ts +1 -1
- package/src/collection_editor/ui/collection_editor/utils/supported_fields.tsx +0 -1
- package/src/collection_editor/ui/collection_editor/utils/update_property_for_widget.ts +7 -29
- package/src/collection_editor/useJsonCollectionsConfigController.tsx +286 -0
- package/src/collection_editor/useSafeSnackbarController.ts +9 -0
- package/src/collection_editor_ui.ts +6 -0
- package/src/components/DefaultDrawer.tsx +14 -4
- package/src/components/DrawerNavigationGroup.tsx +2 -2
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +11 -9
- package/src/components/EntityCollectionTable/fields/TableMultipleRelationField.tsx +2 -1
- package/src/components/EntityCollectionTable/fields/TableRelationField.tsx +2 -1
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +23 -20
- package/src/components/EntityCollectionTable/index.tsx +1 -1
- package/src/components/EntityCollectionTable/table_bindings.tsx +24 -44
- package/src/components/EntityCollectionView/EntityBoardCard.tsx +6 -6
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +13 -12
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +40 -190
- package/src/components/EntityCollectionView/EntityCollectionListView.tsx +66 -184
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +8 -25
- package/src/components/EntityCollectionView/hooks/useCollectionInlineEditor.ts +1 -1
- package/src/components/EntityCollectionView/hooks/useKanbanDragAndDrop.ts +6 -6
- package/src/components/EntityCollectionView/useBoardDataController.tsx +12 -40
- package/src/components/EntityCollectionView/useEntityPreviewSlots.ts +3 -3
- package/src/components/EntityDetailView.tsx +2 -2
- package/src/components/EntityEditView.tsx +7 -6
- package/src/components/EntityEditViewFormActions.tsx +35 -29
- package/src/components/HomePage/ContentHomePage.tsx +14 -5
- package/src/components/RebaseCMS.tsx +3 -3
- package/src/components/RebaseNavigation.tsx +74 -9
- package/src/components/RelationSelector.tsx +2 -2
- package/src/components/SelectableTable/SelectableTable.tsx +13 -5
- package/src/components/SelectableTable/SelectionStore.ts +18 -48
- package/src/components/SideDialogs.tsx +0 -7
- package/src/components/common/default_entity_actions.tsx +22 -11
- package/src/components/field_configs.tsx +0 -14
- package/src/contexts/BreacrumbsContext.tsx +15 -6
- package/src/editor/editor.tsx +4 -7
- package/src/editor/selectors/ai-selector.tsx +0 -1
- package/src/form/EntityForm.tsx +191 -428
- package/src/form/EntityFormActions.tsx +35 -49
- package/src/form/EntityFormBinding.tsx +323 -0
- package/src/form/components/FormLayout.tsx +1 -1
- package/src/form/components/StorageUploadProgress.tsx +9 -2
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +12 -1
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +4 -4
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +7 -2
- package/src/form/field_bindings/RelationFieldBinding.tsx +5 -7
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +19 -15
- package/src/form/form_utils.ts +163 -0
- package/src/form/index.tsx +14 -6
- package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +2 -2
- package/src/hooks/navigation/contexts/NavigationStateContext.tsx +2 -2
- package/src/hooks/navigation/contexts/UrlContext.tsx +1 -2
- package/src/hooks/navigation/useAsyncResolver.ts +100 -0
- package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +15 -8
- package/src/hooks/navigation/useBuildNavigationStateController.tsx +12 -8
- package/src/hooks/navigation/useNavigationResolution.ts +33 -0
- package/src/hooks/navigation/useResolvedCollections.ts +29 -71
- package/src/hooks/navigation/useResolvedViews.tsx +40 -70
- package/src/hooks/navigation/useTopLevelNavigation.ts +20 -16
- package/src/hooks/navigation/utils.ts +7 -4
- package/src/index.ts +6 -1
- package/src/preview/PropertyPreview.tsx +1 -16
- package/src/preview/components/StorageThumbnail.tsx +24 -7
- package/src/routes/CustomViewRoute.tsx +14 -6
- package/src/types/components/EntityFormActionsProps.tsx +1 -1
- package/src/types/components/EntityFormProps.tsx +68 -0
- package/src/types/components/PropertyPreviewProps.tsx +1 -1
- package/src/types/fields.tsx +9 -8
- package/src/util/dataControllerAdapter.ts +93 -0
- package/src/util/navigation_utils.ts +1 -1
- package/src/util/previews.ts +20 -0
- package/src/util/propertyConfigMapper.ts +134 -0
- package/src/util/property_utils.tsx +1 -2
- package/dist/CollectionEditorDialog-HNXGxXdO.js.map +0 -1
- package/dist/CollectionsStudioView-B1mN33GB.js.map +0 -1
- package/dist/PropertyEditView-C2wp8kQ9.js.map +0 -1
- package/dist/components/EntityCollectionTable/fields/VirtualTableDateField.d.ts +0 -12
- package/dist/components/EntityCollectionTable/fields/VirtualTableInput.d.ts +0 -10
- package/dist/components/EntityCollectionTable/fields/VirtualTableNumberInput.d.ts +0 -9
- package/dist/components/EntityCollectionTable/fields/VirtualTableSwitch.d.ts +0 -8
- package/dist/components/EntityCollectionView/Board.d.ts +0 -3
- package/dist/components/EntityCollectionView/BoardColumn.d.ts +0 -42
- package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +0 -9
- package/dist/components/EntityCollectionView/BoardSortableList.d.ts +0 -14
- package/dist/components/EntityCollectionView/board_types.d.ts +0 -105
- package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +0 -11
- package/dist/hooks/navigation/useNavigationRegistry.d.ts +0 -12
- package/dist/hooks/navigation/useNavigationURLs.d.ts +0 -11
- package/dist/src-BYniefVu.js.map +0 -1
- package/src/components/EntityCollectionTable/fields/VirtualTableDateField.tsx +0 -39
- package/src/components/EntityCollectionTable/fields/VirtualTableInput.tsx +0 -90
- package/src/components/EntityCollectionTable/fields/VirtualTableNumberInput.tsx +0 -83
- package/src/components/EntityCollectionTable/fields/VirtualTableSwitch.tsx +0 -32
- package/src/components/EntityCollectionView/Board.tsx +0 -475
- package/src/components/EntityCollectionView/BoardColumn.tsx +0 -165
- package/src/components/EntityCollectionView/BoardColumnTitle.tsx +0 -46
- package/src/components/EntityCollectionView/BoardSortableList.tsx +0 -177
- package/src/components/EntityCollectionView/board_types.ts +0 -113
- package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +0 -141
- package/src/hooks/navigation/useNavigationRegistry.ts +0 -164
- package/src/hooks/navigation/useNavigationURLs.ts +0 -56
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { ArrayProperty, DateProperty, Entity, EntityReference, EntityRelation, NumberProperty, Property, ReferenceProperty, RelationProperty, StringProperty } from "@rebasepro/types";
|
|
3
|
-
import { TableSize } from "@rebasepro/core";
|
|
3
|
+
import { TableSize, useCustomizationController } from "@rebasepro/core";
|
|
4
|
+
import {
|
|
5
|
+
VirtualTableInput,
|
|
6
|
+
VirtualTableNumberInput,
|
|
7
|
+
VirtualTableSwitch,
|
|
8
|
+
VirtualTableDateField
|
|
9
|
+
} from "@rebasepro/ui";
|
|
4
10
|
|
|
5
|
-
import { VirtualTableInput } from "./fields/VirtualTableInput";
|
|
6
11
|
import { VirtualTableSelect } from "./fields/VirtualTableSelect";
|
|
7
|
-
import { VirtualTableNumberInput } from "./fields/VirtualTableNumberInput";
|
|
8
|
-
import { VirtualTableSwitch } from "./fields/VirtualTableSwitch";
|
|
9
|
-
import { VirtualTableDateField } from "./fields/VirtualTableDateField";
|
|
10
12
|
import { VirtualTableUserSelect } from "./fields/VirtualTableUserSelect";
|
|
11
13
|
import { TableStorageUpload } from "./fields/TableStorageUpload";
|
|
12
14
|
import { TableReferenceField } from "./fields/TableReferenceField";
|
|
@@ -63,33 +65,7 @@ export function getTableBindingForProperty(
|
|
|
63
65
|
): TableFieldConfig | undefined {
|
|
64
66
|
const isAStorageProperty = isStorageProperty(property);
|
|
65
67
|
|
|
66
|
-
if (
|
|
67
|
-
return {
|
|
68
|
-
Component: ({ propertyKey, property, internalValue, updateValue, disabled, size, path }: TableFieldBindingProps) => {
|
|
69
|
-
const referenceProperty = (property as StringProperty).reference;
|
|
70
|
-
if (!referenceProperty) return null;
|
|
71
|
-
const referenceValue = internalValue ? new EntityReference({ id: internalValue as string,
|
|
72
|
-
path: referenceProperty.path as string }) : undefined;
|
|
73
|
-
return (
|
|
74
|
-
<TableReferenceField
|
|
75
|
-
name={propertyKey}
|
|
76
|
-
internalValue={referenceValue}
|
|
77
|
-
updateValue={(v) => updateValue(v ? (v as EntityReference).id : null)}
|
|
78
|
-
disabled={disabled}
|
|
79
|
-
size={size}
|
|
80
|
-
path={referenceProperty.path as string}
|
|
81
|
-
multiselect={false}
|
|
82
|
-
previewProperties={referenceProperty.ui?.previewProperties}
|
|
83
|
-
includeId={referenceProperty.includeId}
|
|
84
|
-
includeEntityLink={referenceProperty.includeEntityLink}
|
|
85
|
-
title={property.name}
|
|
86
|
-
fixedFilter={referenceProperty.fixedFilter}
|
|
87
|
-
/>
|
|
88
|
-
);
|
|
89
|
-
},
|
|
90
|
-
allowScroll: false
|
|
91
|
-
};
|
|
92
|
-
} else if (isAStorageProperty) {
|
|
68
|
+
if (isAStorageProperty) {
|
|
93
69
|
return {
|
|
94
70
|
Component: ({ validationError, error, disabled, selected, openPopup, property, entity, path, internalValue, size, updateValue, propertyKey }: TableFieldBindingProps) => (
|
|
95
71
|
<TableStorageUpload
|
|
@@ -183,7 +159,7 @@ export function getTableBindingForProperty(
|
|
|
183
159
|
),
|
|
184
160
|
fullHeight: true
|
|
185
161
|
};
|
|
186
|
-
} else if (stringProperty.ui?.markdown || !stringProperty.storage
|
|
162
|
+
} else if (stringProperty.ui?.markdown || !stringProperty.storage) {
|
|
187
163
|
const multiline = Boolean(stringProperty.ui?.multiline) || Boolean(stringProperty.ui?.markdown);
|
|
188
164
|
return {
|
|
189
165
|
Component: ({ error, validationError, disabled, selected, internalValue, updateValue }: TableFieldBindingProps) => (
|
|
@@ -213,17 +189,21 @@ export function getTableBindingForProperty(
|
|
|
213
189
|
};
|
|
214
190
|
} else if (property.type === "date") {
|
|
215
191
|
return {
|
|
216
|
-
Component: ({ propertyKey, error, validationError, disabled, selected, property, internalValue, updateValue }: TableFieldBindingProps) =>
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
192
|
+
Component: ({ propertyKey, error, validationError, disabled, selected, property, internalValue, updateValue }: TableFieldBindingProps) => {
|
|
193
|
+
const { locale } = useCustomizationController();
|
|
194
|
+
return (
|
|
195
|
+
<VirtualTableDateField
|
|
196
|
+
name={propertyKey}
|
|
197
|
+
error={validationError ?? error}
|
|
198
|
+
disabled={disabled}
|
|
199
|
+
mode={(property as DateProperty).mode}
|
|
200
|
+
focused={selected}
|
|
201
|
+
internalValue={internalValue as Date}
|
|
202
|
+
updateValue={updateValue}
|
|
203
|
+
locale={locale}
|
|
204
|
+
/>
|
|
205
|
+
);
|
|
206
|
+
},
|
|
227
207
|
fullHeight: true,
|
|
228
208
|
hideOverflow: false,
|
|
229
209
|
allowScroll: false
|
|
@@ -5,10 +5,10 @@ import { Checkbox, Chip, cls, defaultBorderMixin, Markdown } from "@rebasepro/ui
|
|
|
5
5
|
import { PropertyPreview } from "../../preview";
|
|
6
6
|
import { useAuthController, useCustomizationController } from "@rebasepro/core";
|
|
7
7
|
import { IconForView } from "@rebasepro/core";
|
|
8
|
-
import { BoardItemViewProps } from "
|
|
8
|
+
import { BoardItemViewProps } from "@rebasepro/ui";
|
|
9
9
|
import { useCollectionSlotKeys, resolveEntitySlots } from "./useEntityPreviewSlots";
|
|
10
10
|
|
|
11
|
-
export type EntityBoardCardProps<M extends Record<string, unknown> = Record<string, unknown>> = BoardItemViewProps<M
|
|
11
|
+
export type EntityBoardCardProps<M extends Record<string, unknown> = Record<string, unknown>> = BoardItemViewProps<Entity<M>> & {
|
|
12
12
|
collection: EntityCollection<M>;
|
|
13
13
|
onClick?: (entity: Entity<M>) => void;
|
|
14
14
|
selected?: boolean;
|
|
@@ -35,7 +35,7 @@ function EntityBoardCardInner<M extends Record<string, unknown> = Record<string,
|
|
|
35
35
|
onSelectionChange,
|
|
36
36
|
selectionEnabled = false
|
|
37
37
|
}: EntityBoardCardProps<M>) {
|
|
38
|
-
const entity = item.
|
|
38
|
+
const entity = item.data;
|
|
39
39
|
const authController = useAuthController();
|
|
40
40
|
const customizationController = useCustomizationController();
|
|
41
41
|
|
|
@@ -247,14 +247,14 @@ export function createEntityBoardCardComponent<M extends Record<string, unknown>
|
|
|
247
247
|
onSelectionChange?: (entity: Entity<M>, selected: boolean) => void;
|
|
248
248
|
selectionEnabled?: boolean;
|
|
249
249
|
}
|
|
250
|
-
): React.ComponentType<BoardItemViewProps<M
|
|
251
|
-
return function EntityBoardCardWrapper(props: BoardItemViewProps<M
|
|
250
|
+
): React.ComponentType<BoardItemViewProps<Entity<M>>> {
|
|
251
|
+
return function EntityBoardCardWrapper(props: BoardItemViewProps<Entity<M>>) {
|
|
252
252
|
return (
|
|
253
253
|
<EntityBoardCard
|
|
254
254
|
{...props}
|
|
255
255
|
collection={collection}
|
|
256
256
|
onClick={options.onClick}
|
|
257
|
-
selected={options.isEntitySelected?.(props.item.
|
|
257
|
+
selected={options.isEntitySelected?.(props.item.data)}
|
|
258
258
|
onSelectionChange={options.onSelectionChange}
|
|
259
259
|
selectionEnabled={options.selectionEnabled}
|
|
260
260
|
/>
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
1
|
import type { EntityCollection } from "@rebasepro/types";
|
|
3
2
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
3
|
import { Entity, EntityTableController, EnumValueConfig, SaveEntityProps, SelectionController } from "@rebasepro/types";
|
|
5
|
-
import { Board } from "./Board";
|
|
6
|
-
import { BoardItem, BoardItemViewProps, ColumnLoadingState } from "./board_types";
|
|
7
4
|
import { EntityBoardCard } from "./EntityBoardCard";
|
|
8
5
|
import {
|
|
9
6
|
Button,
|
|
@@ -19,7 +16,11 @@ import {
|
|
|
19
16
|
iconSize,
|
|
20
17
|
RefreshCwIcon,
|
|
21
18
|
Tooltip,
|
|
22
|
-
Typography
|
|
19
|
+
Typography,
|
|
20
|
+
KanbanView,
|
|
21
|
+
BoardItem,
|
|
22
|
+
BoardItemViewProps,
|
|
23
|
+
ColumnLoadingState
|
|
23
24
|
} from "@rebasepro/ui";
|
|
24
25
|
import { resolveEnumValues } from "@rebasepro/common";
|
|
25
26
|
import { getPropertyInPath } from "../../util/property_utils";
|
|
@@ -280,7 +281,7 @@ parentEntityIds,
|
|
|
280
281
|
}).catch(e => console.warn("Failed to get total count:", e));
|
|
281
282
|
|
|
282
283
|
accessor.count({
|
|
283
|
-
where: { [orderProperty]: "
|
|
284
|
+
where: { [orderProperty]: ["!=", null] }
|
|
284
285
|
}).then(count => {
|
|
285
286
|
orderedCount = count;
|
|
286
287
|
completed++;
|
|
@@ -318,10 +319,10 @@ parentEntityIds,
|
|
|
318
319
|
}, [columns, boardDataController.columnData]);
|
|
319
320
|
|
|
320
321
|
// Convert entities to board items per column (data already sorted by orderProperty from controller)
|
|
321
|
-
const boardItems: BoardItem<M
|
|
322
|
+
const boardItems: BoardItem<Entity<M>>[] = useMemo(() => {
|
|
322
323
|
return allEntities.map((entity: Entity<M>) => ({
|
|
323
324
|
id: String(entity.id),
|
|
324
|
-
entity
|
|
325
|
+
data: entity
|
|
325
326
|
}));
|
|
326
327
|
}, [allEntities]);
|
|
327
328
|
|
|
@@ -341,11 +342,11 @@ parentEntityIds,
|
|
|
341
342
|
}, [columns, boardDataController.columnData]);
|
|
342
343
|
|
|
343
344
|
// Use the lookup map to assign columns - ensures items stay in the column they were fetched for
|
|
344
|
-
const assignColumn = useCallback((item: BoardItem<M
|
|
345
|
+
const assignColumn = useCallback((item: BoardItem<Entity<M>>): string => {
|
|
345
346
|
const column = entityColumnMap[item.id];
|
|
346
347
|
if (column) return column;
|
|
347
348
|
// Fallback: read from entity values (for newly created items or edge cases)
|
|
348
|
-
const value = item.
|
|
349
|
+
const value = item.data.values?.[columnProperty];
|
|
349
350
|
if (value && columns.includes(String(value))) return String(value);
|
|
350
351
|
return columns[0] || "";
|
|
351
352
|
}, [entityColumnMap, columnProperty, columns]);
|
|
@@ -462,12 +463,12 @@ parentEntityIds,
|
|
|
462
463
|
// When ItemComponent identity changes, React.memo'd SortableItem remounts
|
|
463
464
|
// the card → DOM is destroyed/recreated → CSS :hover state is lost → flicker.
|
|
464
465
|
const ItemComponent = useMemo(() => {
|
|
465
|
-
const Comp = (props: BoardItemViewProps<M
|
|
466
|
+
const Comp = (props: BoardItemViewProps<Entity<M>>) => (
|
|
466
467
|
<EntityBoardCard
|
|
467
468
|
{...props}
|
|
468
469
|
collection={collectionRef.current as EntityCollection<M>}
|
|
469
470
|
onClick={stableOnClick}
|
|
470
|
-
selected={isEntitySelectedRef.current(props.item.
|
|
471
|
+
selected={isEntitySelectedRef.current(props.item.data)}
|
|
471
472
|
onSelectionChange={stableOnSelectionChange}
|
|
472
473
|
selectionEnabled={selectionEnabledRef.current}
|
|
473
474
|
/>
|
|
@@ -592,7 +593,7 @@ parentEntityIds,
|
|
|
592
593
|
|
|
593
594
|
{/* Main board */}
|
|
594
595
|
<div className="flex-1 overflow-auto no-scrollbar">
|
|
595
|
-
<
|
|
596
|
+
<KanbanView
|
|
596
597
|
data={boardItems}
|
|
597
598
|
columns={columns}
|
|
598
599
|
columnLabels={columnLabels}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { EntityCollection } from "@rebasepro/types";
|
|
2
|
-
import React, { useCallback, useEffect, useRef } from "react";
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
|
3
3
|
import { CollectionSize, Entity, EntityTableController, SelectionController } from "@rebasepro/types";
|
|
4
4
|
import { EntityCard } from "./EntityCard";
|
|
5
5
|
import {
|
|
6
6
|
cls,
|
|
7
7
|
CircularProgress,
|
|
8
|
-
Typography
|
|
8
|
+
Typography,
|
|
9
|
+
CardView
|
|
9
10
|
} from "@rebasepro/ui";
|
|
10
11
|
import { useComponentOverride } from "@rebasepro/core";
|
|
11
12
|
|
|
@@ -92,8 +93,6 @@ export function EntityCollectionCardView<M extends Record<string, unknown> = Rec
|
|
|
92
93
|
}: EntityCollectionCardViewProps<M>) {
|
|
93
94
|
|
|
94
95
|
const ResolvedEntityCard = useComponentOverride("Collection.Card", EntityCard) as typeof EntityCard;
|
|
95
|
-
const containerRef = useRef<HTMLDivElement>(null);
|
|
96
|
-
const hasRestoredScroll = useRef(false);
|
|
97
96
|
|
|
98
97
|
const {
|
|
99
98
|
data,
|
|
@@ -106,116 +105,6 @@ export function EntityCollectionCardView<M extends Record<string, unknown> = Rec
|
|
|
106
105
|
paginationEnabled
|
|
107
106
|
} = tableController;
|
|
108
107
|
|
|
109
|
-
// Track if we're currently loading to prevent multiple simultaneous load requests
|
|
110
|
-
const isLoadingMore = useRef(false);
|
|
111
|
-
|
|
112
|
-
// Keep mutable refs for values used in the scroll listener callback
|
|
113
|
-
// to avoid re-attaching the listener every time pagination state changes.
|
|
114
|
-
const paginationStateRef = useRef({ paginationEnabled,
|
|
115
|
-
noMoreToLoad,
|
|
116
|
-
dataLoading,
|
|
117
|
-
itemCount,
|
|
118
|
-
pageSize });
|
|
119
|
-
useEffect(() => {
|
|
120
|
-
paginationStateRef.current = { paginationEnabled,
|
|
121
|
-
noMoreToLoad,
|
|
122
|
-
dataLoading,
|
|
123
|
-
itemCount,
|
|
124
|
-
pageSize };
|
|
125
|
-
}, [paginationEnabled, noMoreToLoad, dataLoading, itemCount, pageSize]);
|
|
126
|
-
|
|
127
|
-
// Reset loading flag when new data arrives (separate effect, like list view)
|
|
128
|
-
useEffect(() => {
|
|
129
|
-
if (!dataLoading) isLoadingMore.current = false;
|
|
130
|
-
}, [dataLoading]);
|
|
131
|
-
|
|
132
|
-
// Infinite scroll and resize observer
|
|
133
|
-
useEffect(() => {
|
|
134
|
-
const el = containerRef.current;
|
|
135
|
-
if (!el) return;
|
|
136
|
-
const scrollEl = getScrollParent(el);
|
|
137
|
-
if (!scrollEl) return;
|
|
138
|
-
|
|
139
|
-
let rafId: number | null = null;
|
|
140
|
-
|
|
141
|
-
const update = () => {
|
|
142
|
-
rafId = null;
|
|
143
|
-
|
|
144
|
-
// Infinite scroll: trigger load-more when near the bottom
|
|
145
|
-
const { paginationEnabled: pe, noMoreToLoad: nm, itemCount: ic, pageSize: ps } = paginationStateRef.current;
|
|
146
|
-
if (
|
|
147
|
-
pe &&
|
|
148
|
-
!nm &&
|
|
149
|
-
!isLoadingMore.current &&
|
|
150
|
-
scrollEl.scrollHeight - scrollEl.scrollTop - scrollEl.clientHeight < 400
|
|
151
|
-
) {
|
|
152
|
-
isLoadingMore.current = true;
|
|
153
|
-
setItemCount?.((ic ?? ps) + ps);
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
const onScrollEvent = () => {
|
|
158
|
-
if (rafId === null) rafId = requestAnimationFrame(update);
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
scrollEl.addEventListener("scroll", onScrollEvent, { passive: true });
|
|
162
|
-
const ro = new ResizeObserver(() => update());
|
|
163
|
-
ro.observe(scrollEl);
|
|
164
|
-
update(); // initial measurement
|
|
165
|
-
|
|
166
|
-
return () => {
|
|
167
|
-
scrollEl.removeEventListener("scroll", onScrollEvent);
|
|
168
|
-
ro.disconnect();
|
|
169
|
-
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
170
|
-
};
|
|
171
|
-
}, [setItemCount]);
|
|
172
|
-
|
|
173
|
-
// Scroll restoration — deferred to after layout paint
|
|
174
|
-
useEffect(() => {
|
|
175
|
-
if (!containerRef.current || !initialScroll || hasRestoredScroll.current || data.length === 0) return;
|
|
176
|
-
|
|
177
|
-
const scrollEl = getScrollParent(containerRef.current);
|
|
178
|
-
if (!scrollEl) return;
|
|
179
|
-
|
|
180
|
-
let attempts = 0;
|
|
181
|
-
const maxAttempts = 5;
|
|
182
|
-
|
|
183
|
-
const tryRestore = () => {
|
|
184
|
-
if (scrollEl.scrollHeight >= initialScroll || attempts >= maxAttempts) {
|
|
185
|
-
scrollEl.scrollTop = initialScroll;
|
|
186
|
-
hasRestoredScroll.current = true;
|
|
187
|
-
} else {
|
|
188
|
-
attempts++;
|
|
189
|
-
requestAnimationFrame(tryRestore);
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
requestAnimationFrame(tryRestore);
|
|
194
|
-
}, [initialScroll, data.length]);
|
|
195
|
-
|
|
196
|
-
// Scroll tracking: call onScroll when user scrolls
|
|
197
|
-
const lastScrollOffset = useRef(0);
|
|
198
|
-
useEffect(() => {
|
|
199
|
-
const el = containerRef.current;
|
|
200
|
-
if (!el || !onScroll) return;
|
|
201
|
-
const scrollEl = getScrollParent(el);
|
|
202
|
-
if (!scrollEl) return;
|
|
203
|
-
|
|
204
|
-
const handleScroll = () => {
|
|
205
|
-
const currentOffset = scrollEl.scrollTop;
|
|
206
|
-
const direction = currentOffset > lastScrollOffset.current ? "forward" : "backward";
|
|
207
|
-
lastScrollOffset.current = currentOffset;
|
|
208
|
-
onScroll({
|
|
209
|
-
scrollDirection: direction,
|
|
210
|
-
scrollOffset: currentOffset,
|
|
211
|
-
scrollUpdateWasRequested: false
|
|
212
|
-
});
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
scrollEl.addEventListener("scroll", handleScroll, { passive: true });
|
|
216
|
-
return () => scrollEl.removeEventListener("scroll", handleScroll);
|
|
217
|
-
}, [onScroll]);
|
|
218
|
-
|
|
219
108
|
const handleEntityClick = useCallback((entity: Entity<M>) => {
|
|
220
109
|
onEntityClick?.(entity);
|
|
221
110
|
}, [onEntityClick]);
|
|
@@ -224,84 +113,45 @@ pageSize };
|
|
|
224
113
|
selectionController?.toggleEntitySelection(entity, selected);
|
|
225
114
|
}, [selectionController]);
|
|
226
115
|
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
}, [selectionController]);
|
|
230
|
-
|
|
231
|
-
const isEntityHighlighted = useCallback((entity: Entity<M>) => {
|
|
232
|
-
return highlightedEntities?.some(e => e.id === entity.id && e.path === entity.path) ?? false;
|
|
233
|
-
}, [highlightedEntities]);
|
|
116
|
+
const selectedIds = useMemo(() => new Set(selectionController?.selectedEntities.map(e => e.id)), [selectionController?.selectedEntities]);
|
|
117
|
+
const highlightedIds = useMemo(() => new Set(highlightedEntities?.map(e => e.id)), [highlightedEntities]);
|
|
234
118
|
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const isInitialLoading = dataLoading && data.length === 0 && !dataLoadingError;
|
|
239
|
-
// Empty state
|
|
240
|
-
const isEmpty = !dataLoading && data.length === 0 && !dataLoadingError;
|
|
119
|
+
const handleRowSelectionChange = useCallback((entity: Entity<M>, selected: boolean) => {
|
|
120
|
+
handleSelectionChange(entity, selected);
|
|
121
|
+
}, [handleSelectionChange]);
|
|
241
122
|
|
|
242
123
|
return (
|
|
243
|
-
<
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
{
|
|
248
|
-
{
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
{
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
<ResolvedEntityCard
|
|
276
|
-
key={`${entity.path}_${entity.id}`}
|
|
277
|
-
entity={entity}
|
|
278
|
-
collection={collection}
|
|
279
|
-
onClick={handleEntityClick}
|
|
280
|
-
selected={isEntitySelected(entity)}
|
|
281
|
-
highlighted={isEntityHighlighted(entity)}
|
|
282
|
-
onSelectionChange={handleSelectionChange}
|
|
283
|
-
selectionEnabled={selectionEnabled}
|
|
284
|
-
size={size}
|
|
285
|
-
/>
|
|
286
|
-
))}
|
|
287
|
-
</div>
|
|
288
|
-
|
|
289
|
-
{/* Load more trigger / Loading indicator */}
|
|
290
|
-
<div
|
|
291
|
-
className="flex items-center justify-center py-8"
|
|
292
|
-
>
|
|
293
|
-
{dataLoading && (
|
|
294
|
-
<CircularProgress size="small"/>
|
|
295
|
-
)}
|
|
296
|
-
{!dataLoading && noMoreToLoad && data.length > 0 && (
|
|
297
|
-
<Typography variant="caption" color="secondary">
|
|
298
|
-
All {data.length} entries loaded
|
|
299
|
-
</Typography>
|
|
300
|
-
)}
|
|
301
|
-
</div>
|
|
302
|
-
</div>
|
|
303
|
-
</>
|
|
304
|
-
)}
|
|
305
|
-
</div>
|
|
124
|
+
<CardView<Entity<M>>
|
|
125
|
+
data={data}
|
|
126
|
+
dataLoading={dataLoading}
|
|
127
|
+
noMoreToLoad={noMoreToLoad}
|
|
128
|
+
dataLoadingError={dataLoadingError}
|
|
129
|
+
itemCount={itemCount}
|
|
130
|
+
setItemCount={setItemCount}
|
|
131
|
+
pageSize={pageSize}
|
|
132
|
+
paginationEnabled={paginationEnabled}
|
|
133
|
+
onItemClick={handleEntityClick}
|
|
134
|
+
selectedIds={selectedIds}
|
|
135
|
+
highlightedIds={highlightedIds}
|
|
136
|
+
selectionEnabled={selectionEnabled}
|
|
137
|
+
onSelectionChange={handleRowSelectionChange}
|
|
138
|
+
onScroll={onScroll}
|
|
139
|
+
initialScroll={initialScroll}
|
|
140
|
+
size={size}
|
|
141
|
+
emptyComponent={emptyComponent}
|
|
142
|
+
renderCard={useCallback((entity, { selected, highlighted, onClick }) => (
|
|
143
|
+
<ResolvedEntityCard
|
|
144
|
+
key={`${entity.path}_${entity.id}`}
|
|
145
|
+
entity={entity}
|
|
146
|
+
collection={collection}
|
|
147
|
+
onClick={onClick as any}
|
|
148
|
+
selected={selected}
|
|
149
|
+
highlighted={highlighted}
|
|
150
|
+
onSelectionChange={handleRowSelectionChange}
|
|
151
|
+
selectionEnabled={selectionEnabled}
|
|
152
|
+
size={size}
|
|
153
|
+
/>
|
|
154
|
+
), [collection, selectionEnabled, size, handleRowSelectionChange, ResolvedEntityCard])}
|
|
155
|
+
/>
|
|
306
156
|
);
|
|
307
157
|
}
|