@rebasepro/admin 0.7.0 → 0.9.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/LICENSE +21 -0
- package/README.md +20 -20
- package/dist/{CollectionEditorDialog-iGgS4rLX.js → CollectionEditorDialog-B-7uW3iJ.js} +15 -15
- package/dist/CollectionEditorDialog-B-7uW3iJ.js.map +1 -0
- package/dist/{PropertyEditView-C9yhLyja.js → PropertyEditView-7KMTcrqi.js} +140 -106
- package/dist/PropertyEditView-7KMTcrqi.js.map +1 -0
- package/dist/{RouterCollectionsStudioView-Dqx27GD8.js → RouterCollectionsStudioView-epqIbZrJ.js} +4 -4
- package/dist/{RouterCollectionsStudioView-Dqx27GD8.js.map → RouterCollectionsStudioView-epqIbZrJ.js.map} +1 -1
- package/dist/collection_editor/_cms_internals.d.ts +4 -4
- package/dist/collection_editor/api/generateCollectionApi.d.ts +7 -6
- package/dist/collection_editor/extensibility_types.d.ts +3 -3
- package/dist/collection_editor/index.d.ts +2 -2
- package/dist/collection_editor/pgColumnToProperty.d.ts +3 -3
- package/dist/collection_editor/serializable_types.d.ts +12 -16
- package/dist/collection_editor/serializable_utils.d.ts +8 -8
- package/dist/collection_editor/types/collection_editor_controller.d.ts +5 -5
- package/dist/collection_editor/types/collection_inference.d.ts +2 -2
- package/dist/collection_editor/types/config_controller.d.ts +7 -7
- package/dist/collection_editor/ui/AddKanbanColumnAction.d.ts +2 -2
- package/dist/collection_editor/ui/CollectionViewHeaderAction.d.ts +2 -2
- package/dist/collection_editor/ui/KanbanSetupAction.d.ts +2 -2
- package/dist/collection_editor/ui/PropertyAddColumnComponent.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.d.ts +3 -3
- package/dist/collection_editor/ui/collection_editor/CollectionDetailsForm.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +4 -5
- package/dist/collection_editor/ui/collection_editor/CollectionEditorWelcomeView.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/CollectionJsonImportDialog.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +4 -4
- package/dist/collection_editor/ui/collection_editor/CollectionStudioView.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/CollectionsStudioView.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/EntityActionsEditTab.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/GeneralSettingsForm.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/GetCodeDialog.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/PropertyEditView.d.ts +4 -4
- package/dist/collection_editor/ui/collection_editor/SubcollectionsEditTab.d.ts +3 -3
- package/dist/collection_editor/ui/collection_editor/templates/blog_template.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/templates/pages_template.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/templates/products_template.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/templates/users_template.d.ts +2 -2
- package/dist/collection_editor/useLocalCollectionsConfigController.d.ts +2 -2
- package/dist/collection_editor/validateCollectionJson.d.ts +2 -2
- package/dist/collection_editor_ui.js +4 -4
- package/dist/components/CollectionPanel.d.ts +4 -4
- package/dist/components/{EntityCollectionTable/EntityCollectionRowActions.d.ts → CollectionTableBinding/CollectionRowActions.d.ts} +3 -3
- package/dist/components/CollectionTableBinding/CollectionTableBinding.d.ts +28 -0
- package/dist/components/{EntityCollectionTable/EntityCollectionTableProps.d.ts → CollectionTableBinding/CollectionTableBindingProps.d.ts} +1 -1
- package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableMultipleRelationField.d.ts +2 -2
- package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableReferenceField.d.ts +2 -2
- package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableRelationField.d.ts +2 -2
- package/dist/components/CollectionTableBinding/index.d.ts +6 -0
- package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/common.d.ts +2 -2
- package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/PopupFormField.d.ts +2 -2
- package/dist/components/{EntityCollectionView/EntityBoardCard.d.ts → CollectionViewBinding/BoardCardBinding.d.ts} +8 -8
- package/dist/components/{EntityCollectionView/EntityCollectionBoardView.d.ts → CollectionViewBinding/CollectionBoardViewBinding.d.ts} +4 -4
- package/dist/components/{EntityCollectionView/EntityCollectionCardView.d.ts → CollectionViewBinding/CollectionCardViewBinding.d.ts} +5 -5
- package/dist/components/{EntityCollectionView/EntityCollectionListView.d.ts → CollectionViewBinding/CollectionListViewBinding.d.ts} +4 -4
- package/dist/components/{EntityCollectionView/EntityCollectionViewActions.d.ts → CollectionViewBinding/CollectionViewActions.d.ts} +4 -4
- package/dist/components/{EntityCollectionView/EntityCollectionView.d.ts → CollectionViewBinding/CollectionViewBinding.d.ts} +4 -4
- package/dist/components/{EntityCollectionView/EntityCollectionViewStartActions.d.ts → CollectionViewBinding/CollectionViewStartActions.d.ts} +4 -4
- package/dist/components/CollectionViewBinding/EntityCardBinding.d.ts +21 -0
- package/dist/components/{EntityCollectionView → CollectionViewBinding}/SplitListView.d.ts +3 -3
- package/dist/components/{EntityCollectionView → CollectionViewBinding}/hooks/useCollectionInlineEditor.d.ts +2 -2
- package/dist/components/{EntityCollectionView → CollectionViewBinding}/hooks/useKanbanDragAndDrop.d.ts +2 -2
- package/dist/components/{EntityCollectionView → CollectionViewBinding}/useBoardDataController.d.ts +2 -2
- package/dist/components/{EntityCollectionView/useEntityPreviewSlots.d.ts → CollectionViewBinding/usePreviewSlots.d.ts} +5 -5
- package/dist/components/DeleteEntityDialog.d.ts +4 -4
- package/dist/components/{EntityDetailView.d.ts → DetailViewBinding.d.ts} +5 -5
- package/dist/components/EditFormActions.d.ts +3 -0
- package/dist/components/{EntityEditView.d.ts → EditViewBinding.d.ts} +9 -9
- package/dist/components/{EntityPreview.d.ts → EntityPreviewBinding.d.ts} +13 -13
- package/dist/components/EntityViewBinding.d.ts +13 -0
- package/dist/components/{EntityJsonPreview.d.ts → JsonPreviewBinding.d.ts} +1 -1
- package/dist/components/RebaseCMS.d.ts +1 -1
- package/dist/components/RebaseNavigation.d.ts +1 -1
- package/dist/components/ReferenceTable/{EntitySelectionTable.d.ts → SelectionTableBinding.d.ts} +5 -5
- package/dist/components/SelectableTable/SelectableTable.d.ts +5 -5
- package/dist/components/SelectableTable/SelectableTableContext.d.ts +3 -3
- package/dist/components/SelectableTable/SelectionStore.d.ts +13 -22
- package/dist/components/SelectableTable/filters/BooleanFilterField.d.ts +6 -1
- package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +7 -1
- package/dist/components/SelectableTable/filters/FilterFieldBinding.d.ts +40 -0
- package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +7 -1
- package/dist/components/SelectableTable/filters/RelationFilterField.d.ts +7 -1
- package/dist/components/SelectableTable/filters/StringNumberFilterField.d.ts +7 -1
- package/dist/components/SideDialogs.d.ts +1 -1
- package/dist/components/SidePanelBinding.d.ts +11 -0
- package/dist/components/{SideEntityProvider.d.ts → SidePanelProvider.d.ts} +7 -7
- package/dist/components/field_configs.d.ts +1 -1
- package/dist/components/history/EntityHistoryEntry.d.ts +2 -2
- package/dist/components/history/LastEditedByIndicator.d.ts +2 -2
- package/dist/components/index.d.ts +14 -13
- package/dist/contexts/SidePanelControllerContext.d.ts +3 -0
- package/dist/data_export/export/ExportCollectionAction.d.ts +3 -3
- package/dist/data_import/components/ImportSaveInProgress.d.ts +2 -2
- 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 +1 -1
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/form/components/StorageUploadProgress.d.ts +6 -1
- package/dist/form/form_utils.d.ts +2 -2
- package/dist/form/index.d.ts +0 -1
- package/dist/{history-ChHgyyvM.js → history-7X5bON_n.js} +4 -4
- package/dist/history-7X5bON_n.js.map +1 -0
- package/dist/hooks/index.d.ts +4 -4
- package/dist/hooks/navigation/contexts/CollectionRegistryContext.d.ts +2 -2
- package/dist/hooks/navigation/useBuildNavigationStateController.d.ts +5 -5
- package/dist/hooks/navigation/useNavigationResolution.d.ts +4 -4
- package/dist/hooks/navigation/useResolvedCollections.d.ts +7 -7
- package/dist/hooks/navigation/useTopLevelNavigation.d.ts +2 -2
- package/dist/hooks/navigation/utils.d.ts +5 -5
- package/dist/hooks/useBuildSidePanel.d.ts +6 -0
- package/dist/hooks/useCMSContext.d.ts +2 -2
- package/dist/hooks/{useEntityHistory.d.ts → useHistory.d.ts} +1 -1
- package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
- package/dist/hooks/{useEntitySelectionDialog.d.ts → useSelectionDialog.d.ts} +2 -2
- package/dist/hooks/useSideDialogsController.d.ts +1 -1
- package/dist/hooks/useSidePanel.d.ts +11 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/preview/components/StorageThumbnail.d.ts +3 -1
- package/dist/{src-DOX2nOyh.js → src-sUZfe29F.js} +904 -1096
- package/dist/src-sUZfe29F.js.map +1 -0
- package/dist/types/components/EntityFormActionsProps.d.ts +2 -2
- package/dist/types/components/EntityFormProps.d.ts +3 -3
- package/dist/types/components/PropertyPreviewProps.d.ts +2 -1
- package/dist/types/fields.d.ts +6 -8
- package/dist/util/dataControllerAdapter.d.ts +2 -5
- package/dist/util/navigation_utils.d.ts +6 -6
- package/dist/util/previews.d.ts +3 -3
- package/dist/util/property_utils.d.ts +2 -2
- package/dist/util/{entity_view_constants.d.ts → view_constants.d.ts} +1 -1
- package/package.json +18 -18
- package/src/collection_editor/ConfigControllerProvider.tsx +10 -10
- package/src/collection_editor/_cms_internals.ts +4 -4
- package/src/collection_editor/api/generateCollectionApi.ts +7 -6
- package/src/collection_editor/extensibility_types.ts +3 -3
- package/src/collection_editor/index.ts +3 -3
- package/src/collection_editor/pgColumnToProperty.ts +4 -4
- package/src/collection_editor/serializable_types.ts +22 -35
- package/src/collection_editor/serializable_utils.ts +40 -52
- package/src/collection_editor/types/collection_editor_controller.tsx +5 -5
- package/src/collection_editor/types/collection_inference.ts +2 -2
- package/src/collection_editor/types/config_controller.tsx +7 -7
- package/src/collection_editor/ui/AddKanbanColumnAction.tsx +2 -2
- package/src/collection_editor/ui/CollectionViewHeaderAction.tsx +2 -2
- package/src/collection_editor/ui/EditorCollectionAction.tsx +2 -2
- package/src/collection_editor/ui/EditorCollectionActionStart.tsx +2 -2
- package/src/collection_editor/ui/EditorEntityAction.tsx +2 -2
- package/src/collection_editor/ui/KanbanSetupAction.tsx +2 -2
- package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +5 -5
- package/src/collection_editor/ui/collection_editor/CollectionDetailsForm.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +63 -46
- package/src/collection_editor/ui/collection_editor/CollectionEditorWelcomeView.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/CollectionJsonImportDialog.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +8 -8
- package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/EntityActionsEditTab.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx +5 -5
- package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +4 -4
- package/src/collection_editor/ui/collection_editor/KanbanConfigSection.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +7 -16
- package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +45 -36
- package/src/collection_editor/ui/collection_editor/PropertyTree.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/SubcollectionsEditTab.tsx +5 -5
- package/src/collection_editor/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/import/CollectionEditorImportMapping.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +35 -1
- package/src/collection_editor/ui/collection_editor/templates/blog_template.ts +3 -3
- package/src/collection_editor/ui/collection_editor/templates/pages_template.ts +2 -2
- package/src/collection_editor/ui/collection_editor/templates/products_template.ts +2 -2
- package/src/collection_editor/ui/collection_editor/templates/users_template.ts +2 -2
- 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 +14 -14
- package/src/collection_editor/useLocalCollectionsConfigController.tsx +4 -4
- package/src/collection_editor/validateCollectionJson.ts +3 -3
- package/src/components/CollectionPanel.tsx +14 -17
- package/src/components/{EntityCollectionTable/EntityCollectionRowActions.tsx → CollectionTableBinding/CollectionRowActions.tsx} +6 -6
- package/src/components/{EntityCollectionTable/EntityCollectionTable.tsx → CollectionTableBinding/CollectionTableBinding.tsx} +19 -17
- package/src/components/{EntityCollectionTable/EntityCollectionTableProps.tsx → CollectionTableBinding/CollectionTableBindingProps.tsx} +1 -1
- package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableMultipleRelationField.tsx +7 -6
- package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableReferenceField.tsx +10 -10
- package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableRelationField.tsx +7 -6
- package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableStorageUpload.tsx +23 -20
- package/src/components/CollectionTableBinding/index.tsx +14 -0
- package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/common.tsx +2 -2
- package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/PopupFormField.tsx +2 -2
- package/src/components/{EntityCollectionTable → CollectionTableBinding}/table_bindings.tsx +24 -44
- package/src/components/{EntityCollectionView/EntityBoardCard.tsx → CollectionViewBinding/BoardCardBinding.tsx} +15 -15
- package/src/components/{EntityCollectionView/EntityCollectionBoardView.tsx → CollectionViewBinding/CollectionBoardViewBinding.tsx} +15 -14
- package/src/components/{EntityCollectionView/EntityCollectionCardView.tsx → CollectionViewBinding/CollectionCardViewBinding.tsx} +8 -8
- package/src/components/{EntityCollectionView/EntityCollectionListView.tsx → CollectionViewBinding/CollectionListViewBinding.tsx} +24 -13
- package/src/components/{EntityCollectionView/EntityCollectionViewActions.tsx → CollectionViewBinding/CollectionViewActions.tsx} +5 -5
- package/src/components/{EntityCollectionView/EntityCollectionView.tsx → CollectionViewBinding/CollectionViewBinding.tsx} +112 -114
- package/src/components/{EntityCollectionView/EntityCollectionViewStartActions.tsx → CollectionViewBinding/CollectionViewStartActions.tsx} +5 -5
- package/src/components/{EntityCollectionView/EntityCard.tsx → CollectionViewBinding/EntityCardBinding.tsx} +9 -9
- package/src/components/{EntityCollectionView → CollectionViewBinding}/FiltersDialog.tsx +31 -72
- package/src/components/{EntityCollectionView → CollectionViewBinding}/SplitListView.tsx +9 -9
- package/src/components/{EntityCollectionView → CollectionViewBinding}/hooks/useCollectionInlineEditor.ts +6 -6
- package/src/components/{EntityCollectionView → CollectionViewBinding}/hooks/useKanbanDragAndDrop.ts +4 -4
- package/src/components/{EntityCollectionView → CollectionViewBinding}/useBoardDataController.tsx +28 -50
- package/src/components/{EntityCollectionView/useEntityPreviewSlots.ts → CollectionViewBinding/usePreviewSlots.ts} +11 -11
- package/src/components/DefaultDrawer.tsx +1 -1
- package/src/components/DeleteEntityDialog.tsx +6 -6
- package/src/components/{EntityDetailView.tsx → DetailViewBinding.tsx} +28 -31
- package/src/components/{EntityEditViewFormActions.tsx → EditFormActions.tsx} +15 -15
- package/src/components/{EntityEditView.tsx → EditViewBinding.tsx} +31 -34
- package/src/components/{EntityPreview.tsx → EntityPreviewBinding.tsx} +27 -27
- package/src/components/{EntityView.tsx → EntityViewBinding.tsx} +5 -5
- package/src/components/HomePage/ContentHomePage.tsx +1 -1
- package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
- package/src/components/{EntityJsonPreview.tsx → JsonPreviewBinding.tsx} +1 -1
- package/src/components/RebaseCMS.tsx +4 -4
- package/src/components/RebaseNavigation.tsx +20 -10
- package/src/components/ReferenceTable/{EntitySelectionTable.tsx → SelectionTableBinding.tsx} +22 -19
- package/src/components/ReferenceWidget.tsx +4 -4
- package/src/components/RelationSelector.tsx +16 -14
- package/src/components/SelectableTable/SelectableTable.tsx +44 -89
- package/src/components/SelectableTable/SelectableTableContext.tsx +3 -3
- package/src/components/SelectableTable/SelectionStore.ts +22 -52
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +9 -1
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +33 -12
- package/src/components/SelectableTable/filters/FilterFieldBinding.tsx +187 -0
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +21 -7
- package/src/components/SelectableTable/filters/RelationFilterField.tsx +17 -3
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +66 -12
- package/src/components/SideDialogs.tsx +3 -3
- package/src/components/{EntitySidePanel.tsx → SidePanelBinding.tsx} +19 -19
- package/src/components/{SideEntityProvider.tsx → SidePanelProvider.tsx} +16 -16
- package/src/components/common/default_entity_actions.tsx +24 -13
- package/src/components/field_configs.tsx +0 -14
- package/src/components/history/EntityHistoryEntry.tsx +2 -2
- package/src/components/history/EntityHistoryView.tsx +3 -3
- package/src/components/history/LastEditedByIndicator.tsx +2 -2
- package/src/components/index.ts +15 -14
- package/src/contexts/SidePanelControllerContext.tsx +5 -0
- package/src/data_export/export/ExportCollectionAction.tsx +4 -4
- package/src/data_import/components/ImportSaveInProgress.tsx +3 -3
- package/src/data_import/import/ImportCollectionAction.tsx +4 -4
- package/src/data_import/utils/data.ts +2 -2
- package/src/editor/editor.tsx +4 -7
- package/src/form/EntityForm.tsx +2 -2
- package/src/form/EntityFormActions.tsx +4 -4
- package/src/form/EntityFormBinding.tsx +7 -7
- package/src/form/PropertyFieldBinding.tsx +4 -4
- package/src/form/components/StorageUploadProgress.tsx +9 -2
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +4 -4
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +19 -19
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +12 -1
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +6 -6
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +5 -5
- package/src/form/field_bindings/RelationFieldBinding.tsx +8 -10
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +19 -15
- package/src/form/form_utils.ts +2 -2
- package/src/form/index.tsx +0 -1
- package/src/hooks/index.ts +4 -4
- package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +2 -2
- package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +11 -11
- package/src/hooks/navigation/useBuildNavigationStateController.tsx +5 -5
- package/src/hooks/navigation/useNavigationResolution.ts +10 -10
- package/src/hooks/navigation/useResolvedCollections.ts +8 -8
- package/src/hooks/navigation/useTopLevelNavigation.ts +2 -2
- package/src/hooks/navigation/utils.ts +5 -5
- package/src/hooks/{useBuildSideEntityController.tsx → useBuildSidePanel.tsx} +28 -28
- package/src/hooks/useCMSContext.tsx +6 -6
- package/src/hooks/{useEntityHistory.ts → useHistory.ts} +1 -1
- package/src/hooks/useResolvedNavigationFrom.tsx +8 -5
- package/src/hooks/{useEntitySelectionDialog.tsx → useSelectionDialog.tsx} +7 -7
- package/src/hooks/useSideDialogsController.tsx +1 -1
- package/src/hooks/useSidePanel.tsx +13 -0
- package/src/index.ts +13 -13
- package/src/preview/PropertyPreview.tsx +1 -16
- package/src/preview/components/ReferencePreview.tsx +10 -10
- package/src/preview/components/RelationPreview.tsx +13 -12
- package/src/preview/components/StorageThumbnail.tsx +24 -7
- package/src/routes/RebaseRoute.tsx +10 -10
- package/src/types/components/EntityFormActionsProps.tsx +2 -2
- package/src/types/components/EntityFormProps.tsx +3 -3
- package/src/types/components/PropertyPreviewProps.tsx +1 -1
- package/src/types/fields.tsx +4 -9
- package/src/util/dataControllerAdapter.ts +9 -15
- package/src/util/navigation_utils.ts +7 -7
- package/src/util/previews.ts +23 -3
- package/src/util/propertyConfigMapper.ts +3 -3
- package/src/util/property_utils.tsx +2 -3
- package/src/util/{entity_view_constants.ts → view_constants.ts} +1 -1
- package/dist/CollectionEditorDialog-iGgS4rLX.js.map +0 -1
- package/dist/PropertyEditView-C9yhLyja.js.map +0 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +0 -28
- 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/EntityCollectionTable/index.d.ts +0 -6
- package/dist/components/EntityCollectionView/EntityCard.d.ts +0 -21
- package/dist/components/EntityEditViewFormActions.d.ts +0 -3
- package/dist/components/EntitySidePanel.d.ts +0 -11
- package/dist/components/EntityView.d.ts +0 -13
- package/dist/contexts/SideEntityControllerContext.d.ts +0 -3
- package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +0 -11
- package/dist/history-ChHgyyvM.js.map +0 -1
- package/dist/hooks/useBuildSideEntityController.d.ts +0 -6
- package/dist/hooks/useSideEntityController.d.ts +0 -11
- package/dist/src-DOX2nOyh.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/EntityCollectionTable/index.tsx +0 -14
- package/src/contexts/SideEntityControllerContext.tsx +0 -5
- package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +0 -141
- package/src/hooks/useSideEntityController.tsx +0 -13
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/PropertyTableCell.d.ts +0 -0
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/column_utils.d.ts +0 -0
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableRelationSelectorField.d.ts +0 -0
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableStorageUpload.d.ts +0 -0
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/VirtualTableSelect.d.ts +0 -0
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/VirtualTableUserSelect.d.ts +0 -0
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/CollectionTableToolbar.d.ts +0 -0
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/EntityTableCell.d.ts +0 -0
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/EntityTableCellActions.d.ts +0 -0
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/useDraggable.d.ts +0 -0
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/useWindowSize.d.ts +0 -0
- /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/table_bindings.d.ts +0 -0
- /package/dist/components/{EntityCollectionView → CollectionViewBinding}/FilterPresetsButton.d.ts +0 -0
- /package/dist/components/{EntityCollectionView → CollectionViewBinding}/FiltersDialog.d.ts +0 -0
- /package/dist/components/{EntityCollectionView → CollectionViewBinding}/ViewModeToggle.d.ts +0 -0
- /package/dist/components/{EntityCollectionView → CollectionViewBinding}/useSelectionController.d.ts +0 -0
- /package/dist/components/{EntityCollectionView → CollectionViewBinding}/utils.d.ts +0 -0
- /package/src/components/{EntityCollectionTable → CollectionTableBinding}/PropertyTableCell.tsx +0 -0
- /package/src/components/{EntityCollectionTable → CollectionTableBinding}/column_utils.tsx +0 -0
- /package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableRelationSelectorField.tsx +0 -0
- /package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/VirtualTableSelect.tsx +0 -0
- /package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/VirtualTableUserSelect.tsx +0 -0
- /package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/CollectionTableToolbar.tsx +0 -0
- /package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/EntityTableCell.tsx +0 -0
- /package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/EntityTableCellActions.tsx +0 -0
- /package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/useDraggable.tsx +0 -0
- /package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/useWindowSize.tsx +0 -0
- /package/src/components/{EntityCollectionView → CollectionViewBinding}/FilterPresetsButton.tsx +0 -0
- /package/src/components/{EntityCollectionView → CollectionViewBinding}/ViewModeToggle.tsx +0 -0
- /package/src/components/{EntityCollectionView → CollectionViewBinding}/useSelectionController.tsx +0 -0
- /package/src/components/{EntityCollectionView → CollectionViewBinding}/utils.ts +0 -0
|
@@ -2,14 +2,14 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
|
2
2
|
import * as React$1 from "react";
|
|
3
3
|
import React, { Suspense, createContext, createElement, forwardRef, lazy, memo, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
4
4
|
import { deepEqual } from "fast-equals";
|
|
5
|
-
import { Alert, AlertCircleIcon, AlertTriangleIcon, AlignLeftIcon, ArrowLeftIcon, ArrowRightToLineIcon, Avatar, Badge,
|
|
6
|
-
import { CollectionRegistry, DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE, addInitialSlash, buildRoutedRebaseData, canReadCollection, enumToObjectEntries, getArrayResolvedProperties, getCollectionBySlugWithin, getCollectionPathsCombinations, getDefaultValueFor, getDefaultValueFortype, getDefaultValuesFor, getEntityImagePreviewPropertyKey, getLabelOrConfigFrom, getLastSegment, getLastSegment as getLastSegment$1, getLocalChangesBackup, getNavigationEntriesFromPath, getParentReferencesFromPath, getReferenceFrom, getRelationFrom, getSubcollections, getTableName, isHidden, isPropertyBuilder, isReadOnly, normalizeToEntityRelation, removeInitialAndTrailingSlashes, removeInitialAndTrailingSlashes as removeInitialAndTrailingSlashes$1, removeInitialSlash, removeTrailingSlash, resolveArrayProperties, resolveCollectionPathIds, resolveCollectionPathIds as resolveCollectionPathIds$1, resolveDataSource, resolveDefaultSelectedView, resolveEnumValues, resolveProperty, resolveRelationProperty, resolveStorageFilenameString, resolveStoragePathString } from "@rebasepro/common";
|
|
7
|
-
import { ADDITIONAL_TAB_WIDTH, CONTAINER_FULL_WIDTH,
|
|
5
|
+
import { Alert, AlertCircleIcon, AlertTriangleIcon, AlignLeftIcon, ArrowLeftIcon, ArrowRightToLineIcon, Avatar, Badge, BooleanSwitchWithLabel, Button, CHIP_COLORS, CalendarIcon, Card, CardView, CenteredView, CheckCircleIcon, CheckIcon, Checkbox, ChevronDownIcon, ChevronRightIcon, ChevronUpIcon, ChevronsLeftIcon, ChevronsRightIcon, ChevronsUpDownIcon, Chip, CircleIcon, CircularProgress, CircularProgressCenter, CodeIcon, Collapse, ColumnsIcon, Container, CopyIcon, DateTimeField, Dialog, DialogActions, DialogContent, DialogTitle, DownloadIcon, ErrorBoundary, ExpandablePanel, ExternalLinkIcon, EyeIcon, EyeOffIcon, FileTextIcon, FileUpload, FilterChip, FilterIcon, FilterXIcon, FlagIcon, FolderUpIcon, FunctionSquareIcon, GlobeIcon, HandleIcon, HashIcon, HistoryIcon, IconButton, ImageOffIcon, KanbanIcon, KanbanView, KeyRoundIcon, Label, LayoutGridIcon, LinkIcon, ListIcon, ListOrderedIcon, ListView, LoaderIcon, LoadingButton, LogOutIcon, MailIcon, Markdown, Maximize2Icon, Menu, MenuIcon, MenuItem, MinusIcon, MoonIcon, MoreVerticalIcon, MultiSelect, MultiSelectItem, PencilIcon, PlusIcon, Popover, PopoverPrimitive, Portal, QuoteIcon, RadioGroup, RadioGroupItem, RefreshCwIcon, RepeatIcon, ResizablePanels, Rows3Icon, SearchBar, SearchIcon, Select, SelectItem, Separator, SettingsIcon, Sheet, Skeleton, StarIcon, SunIcon, SunMoonIcon, Tab, Table, TableBody, TableCell, TableHeader, TableIcon, TableRow, TableView, Tabs, TextField, TextIcon, TextareaAutosize, ToggleButtonGroup, Tooltip, Trash2Icon, Typography, UploadIcon, UserIcon, VirtualTableDateField, VirtualTableInput, VirtualTableInput as VirtualTableInput$1, VirtualTableNumberInput, VirtualTableSwitch, VoteIcon, XCircleIcon, XIcon, cls, coolIconKeys, createVirtualTableSelectionStore, debounce, defaultBorderMixin, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundInvisibleMixin, fieldBackgroundMixin, focusedDisabled, getColorSchemeForSeed, iconSize, lucideIcons, paperMixin, useDebouncedCallback, useInjectStyles, useOutsideAlerter } from "@rebasepro/ui";
|
|
6
|
+
import { CollectionRegistry, DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE, addInitialSlash, buildRoutedRebaseData, canReadCollection, enumToObjectEntries, getArrayResolvedProperties, getCollectionBySlugWithin, getCollectionPathsCombinations, getDefaultValueFor, getDefaultValueFortype, getDefaultValuesFor, getEntityImagePreviewPropertyKey, getLabelOrConfigFrom, getLastSegment, getLastSegment as getLastSegment$1, getLocalChangesBackup, getNavigationEntriesFromPath, getParentReferencesFromPath, getReferenceFrom, getRelationFrom, getSubcollections, getTableName, isHidden, isPropertyBuilder, isReadOnly, normalizeToEntityRelation, removeInitialAndTrailingSlashes, removeInitialAndTrailingSlashes as removeInitialAndTrailingSlashes$1, removeInitialSlash, removeTrailingSlash, resolveArrayProperties, resolveCollectionPathIds, resolveCollectionPathIds as resolveCollectionPathIds$1, resolveDataSource, resolveDefaultSelectedView, resolveEnumValues, resolveFilterOperators, resolveProperty, resolveRelationProperty, resolveStorageFilenameString, resolveStoragePathString, resolveStorageSource } from "@rebasepro/common";
|
|
7
|
+
import { ADDITIONAL_TAB_WIDTH, CONTAINER_FULL_WIDTH, CollectionScopeProvider, ConfirmationDialog, CustomizationControllerContext, DEFAULT_PAGE_SIZE, ErrorTooltip, ErrorView, FORM_CONTAINER_WIDTH, IconForView, LanguageToggle, LoginView, NotFoundPage, PluginProviderStack, RebaseDataContext, RebaseLogo, RebaseRoutes, SchemaDriftBanner, StorageSourceContext, StudioBridgeRegistryProvider, UIReferenceView, UnsavedChangesDialog, UserDisplay, UserSettingsView, buildCollapsedDefaults, buildEnumLabel, createFormexStub, deleteEntityWithCallbacks, flattenKeys, getColorScheme, getColumnKeysForProperty, getEntityFromCache, getEntityFromMemoryCache, getFormFieldKeys, getIcon, getRowHeight, iconsSearch, removeEntityFromCache, removeEntityFromMemoryCache, resolveComponentRef, saveEntityToCache, saveEntityToMemoryCache, saveEntityWithCallbacks, useAdminModeController, useAnalyticsController, useApiConfig, useAuthController, useBridgeRegistration, useBuildLocalConfigurationPersistence, useCollapsedGroups, useCollectionScope, useColumnIds, useComponentOverride, useCustomizationController, useData, useDataSources, useDataTableController, useFetch, useLargeLayout, useModeController, usePermissions, useRebaseClient, useRebaseContext, useRebaseRegistry, useRebaseRegistryDispatch, useRelationSelector, useResolvedComponent, useRestoreScroll, useScrollRestoration, useSlot, useSnackbarController, useStorageSource, useStorageSources, useStorageUploadController, useTranslation, useUnsavedChangesDialog, useUserConfigurationPersistence } from "@rebasepro/core";
|
|
8
8
|
import { Field, Formex, getIn, setIn, useCreateFormex, useFormex } from "@rebasepro/formex";
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import { defaultDateFormat, getArrayValuesCount, getHashValue, getValueInPath, hydrateRegExp, isObject, mergeDeep, prettifyIdentifier, randomString, slugify, toArray } from "@rebasepro/utils";
|
|
11
|
+
import { EntityReference, EntityRelation, GeoPoint, Vector, getCollectionDataPath, getDataSourceCapabilities } from "@rebasepro/types";
|
|
11
12
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
-
import { EntityReference, EntityRelation, GeoPoint, Vector, getDataSourceCapabilities } from "@rebasepro/types";
|
|
13
13
|
import { Link, NavLink, Outlet, Route, useBlocker, useLocation, useNavigate, useSearchParams } from "react-router-dom";
|
|
14
14
|
import { Highlight, themes } from "prism-react-renderer";
|
|
15
15
|
import { Command } from "cmdk";
|
|
@@ -347,10 +347,10 @@ function buildBottomActions$1({ savingError, entity, path, formActions, collecti
|
|
|
347
347
|
if (entity) action.onClick({
|
|
348
348
|
view: "form",
|
|
349
349
|
entity,
|
|
350
|
-
path: path ?? collection
|
|
350
|
+
path: path ?? getCollectionDataPath(collection),
|
|
351
351
|
collection,
|
|
352
352
|
context: void 0,
|
|
353
|
-
|
|
353
|
+
sidePanelController: void 0,
|
|
354
354
|
openEntityMode,
|
|
355
355
|
navigateBack,
|
|
356
356
|
formContext
|
|
@@ -784,26 +784,32 @@ function renderSkeletonIcon() {
|
|
|
784
784
|
*/
|
|
785
785
|
var StorageThumbnail = React.memo(StorageThumbnailInternal, areEqual$1);
|
|
786
786
|
function areEqual$1(prevProps, nextProps) {
|
|
787
|
-
return prevProps.size === nextProps.size && prevProps.storagePathOrDownloadUrl === nextProps.storagePathOrDownloadUrl && prevProps.storeUrl === nextProps.storeUrl && prevProps.interactive === nextProps.interactive && prevProps.fill === nextProps.fill;
|
|
787
|
+
return prevProps.size === nextProps.size && prevProps.storagePathOrDownloadUrl === nextProps.storagePathOrDownloadUrl && prevProps.storeUrl === nextProps.storeUrl && prevProps.interactive === nextProps.interactive && prevProps.fill === nextProps.fill && prevProps.storageSourceKey === nextProps.storageSourceKey;
|
|
788
788
|
}
|
|
789
789
|
var URL_CACHE = {};
|
|
790
|
-
function StorageThumbnailInternal({ storeUrl, interactive, storagePathOrDownloadUrl, size, fill }) {
|
|
790
|
+
function StorageThumbnailInternal({ storeUrl, interactive, storagePathOrDownloadUrl, size, fill, storageSourceKey }) {
|
|
791
791
|
const [error, setError] = React.useState(void 0);
|
|
792
|
-
const
|
|
793
|
-
const
|
|
792
|
+
const defaultStorage = useStorageSource();
|
|
793
|
+
const storage = resolveStorageSource({
|
|
794
|
+
sourceKey: storageSourceKey,
|
|
795
|
+
sources: useStorageSources().sources,
|
|
796
|
+
defaultSource: defaultStorage
|
|
797
|
+
});
|
|
798
|
+
const cacheKey = `${storageSourceKey ?? ""}::${storagePathOrDownloadUrl}`;
|
|
799
|
+
const [downloadConfig, setDownloadConfig] = React.useState(URL_CACHE[cacheKey]);
|
|
794
800
|
useEffect(() => {
|
|
795
801
|
if (!storagePathOrDownloadUrl) return;
|
|
796
802
|
let unmounted = false;
|
|
797
803
|
storage.getSignedUrl(storagePathOrDownloadUrl).then(function(downloadConfig) {
|
|
798
804
|
if (!unmounted) {
|
|
799
805
|
setDownloadConfig(downloadConfig);
|
|
800
|
-
URL_CACHE[
|
|
806
|
+
URL_CACHE[cacheKey] = downloadConfig;
|
|
801
807
|
}
|
|
802
808
|
}).catch(setError);
|
|
803
809
|
return () => {
|
|
804
810
|
unmounted = true;
|
|
805
811
|
};
|
|
806
|
-
}, [storagePathOrDownloadUrl]);
|
|
812
|
+
}, [storagePathOrDownloadUrl, cacheKey]);
|
|
807
813
|
if (!storagePathOrDownloadUrl) return null;
|
|
808
814
|
const filetype = downloadConfig?.metadata ? getFiletype(downloadConfig?.metadata.contentType) : void 0;
|
|
809
815
|
const previewType = filetype?.startsWith("image") ? "image" : filetype?.startsWith("video") ? "video" : filetype?.startsWith("audio") ? "audio" : "file";
|
|
@@ -951,7 +957,6 @@ function getDefaultIconForProperty(property) {
|
|
|
951
957
|
if (property.ui?.url) return GlobeIcon;
|
|
952
958
|
if (property.email) return MailIcon;
|
|
953
959
|
if (property.ui?.multiline || property.ui?.markdown) return AlignLeftIcon;
|
|
954
|
-
if (property.reference) return LinkIcon;
|
|
955
960
|
return TextIcon;
|
|
956
961
|
case "number": return HashIcon;
|
|
957
962
|
case "boolean": return FlagIcon;
|
|
@@ -1054,6 +1059,21 @@ function isHiddenProperty(property) {
|
|
|
1054
1059
|
if (!property) return false;
|
|
1055
1060
|
return Boolean(property.ui?.hideFromCollection);
|
|
1056
1061
|
}
|
|
1062
|
+
/**
|
|
1063
|
+
* Returns true when the property holds file-storage content (single image,
|
|
1064
|
+
* array of images, generic upload, …). These properties are rendered by the
|
|
1065
|
+
* dedicated image-slot and should NOT appear as regular preview columns.
|
|
1066
|
+
*/
|
|
1067
|
+
function isStorageProperty$1(property) {
|
|
1068
|
+
if (!property) return false;
|
|
1069
|
+
if (property.type === "string" && property.storage) return true;
|
|
1070
|
+
if (property.type === "string" && property.ui?.url === "image") return true;
|
|
1071
|
+
if (property.type === "array" && property.of && !Array.isArray(property.of)) {
|
|
1072
|
+
const inner = property.of;
|
|
1073
|
+
if (inner.type === "string" && (inner.storage || inner.ui?.url === "image")) return true;
|
|
1074
|
+
}
|
|
1075
|
+
return false;
|
|
1076
|
+
}
|
|
1057
1077
|
function getEntityPreviewKeys(authController, targetCollection, fields, previewProperties, limit = 3) {
|
|
1058
1078
|
const allProperties = Object.keys(targetCollection.properties);
|
|
1059
1079
|
let listProperties = previewProperties?.filter((p) => allProperties.includes(p));
|
|
@@ -1067,7 +1087,7 @@ function getEntityPreviewKeys(authController, targetCollection, fields, previewP
|
|
|
1067
1087
|
return !(prop && typeof prop === "object" && "isId" in prop && Boolean(prop.isId)) && key !== "id";
|
|
1068
1088
|
}).filter((key) => {
|
|
1069
1089
|
const property = targetCollection.properties[key];
|
|
1070
|
-
return property && !isPropertyBuilder(property) && !isReferenceProperty(property) && !isHiddenProperty(property) && (hasExplicitOrder || !isRelationProperty(property));
|
|
1090
|
+
return property && !isPropertyBuilder(property) && !isReferenceProperty(property) && !isHiddenProperty(property) && !isStorageProperty$1(property) && (hasExplicitOrder || !isRelationProperty(property));
|
|
1071
1091
|
}).slice(0, limit);
|
|
1072
1092
|
}
|
|
1073
1093
|
}
|
|
@@ -1140,15 +1160,15 @@ function resolveTitleToString(title) {
|
|
|
1140
1160
|
}
|
|
1141
1161
|
}
|
|
1142
1162
|
//#endregion
|
|
1143
|
-
//#region src/components/
|
|
1163
|
+
//#region src/components/EntityPreviewBinding.tsx
|
|
1144
1164
|
/**
|
|
1145
|
-
* This component contains the main logic and content for displaying
|
|
1146
|
-
* without any container wrapper. Used internally by
|
|
1165
|
+
* This component contains the main logic and content for displaying a entity preview,
|
|
1166
|
+
* without any container wrapper. Used internally by EntityPreviewBinding.
|
|
1147
1167
|
*/
|
|
1148
|
-
function
|
|
1168
|
+
function EntityPreviewBindingData({ actions, collection: collectionProp, previewKeys, size = "medium", includeId = true, onSidePanelClick, includeTitle = true, includeEntityLink = true, includeImage = true, entity }) {
|
|
1149
1169
|
const authController = useAuthController();
|
|
1150
1170
|
const analyticsController = useAnalyticsController();
|
|
1151
|
-
const
|
|
1171
|
+
const sidePanelController = useSidePanel();
|
|
1152
1172
|
const customizationController = useCustomizationController();
|
|
1153
1173
|
const collectionRegistryController = useCollectionRegistryController();
|
|
1154
1174
|
const collection = collectionProp ?? collectionRegistryController.getCollection(entity.path);
|
|
@@ -1245,12 +1265,12 @@ function EntityPreviewData({ actions, collection: collectionProp, previewKeys, s
|
|
|
1245
1265
|
onClick: (e) => {
|
|
1246
1266
|
e.stopPropagation();
|
|
1247
1267
|
e.preventDefault();
|
|
1248
|
-
|
|
1268
|
+
onSidePanelClick?.(entity);
|
|
1249
1269
|
analyticsController.onAnalyticsEvent?.("entity_click_from_reference", {
|
|
1250
1270
|
path: entity.path,
|
|
1251
1271
|
entityId: entity.id
|
|
1252
1272
|
});
|
|
1253
|
-
|
|
1273
|
+
sidePanelController.open({
|
|
1254
1274
|
entityId: entity.id,
|
|
1255
1275
|
path: entity.path,
|
|
1256
1276
|
collection,
|
|
@@ -1268,15 +1288,15 @@ function EntityPreviewData({ actions, collection: collectionProp, previewKeys, s
|
|
|
1268
1288
|
] });
|
|
1269
1289
|
}
|
|
1270
1290
|
/**
|
|
1271
|
-
* This view is used to display a preview of
|
|
1291
|
+
* This view is used to display a preview of a entity.
|
|
1272
1292
|
* It is used by default in reference fields and whenever a reference is displayed.
|
|
1273
1293
|
*/
|
|
1274
|
-
function
|
|
1294
|
+
function EntityPreviewBinding({ actions, disabled, hover, collection, previewKeys, onClick, size = "medium", includeId = true, includeTitle = true, includeEntityLink = true, includeImage = true, onSidePanelClick, entity }) {
|
|
1275
1295
|
return /* @__PURE__ */ jsx(EntityPreviewContainer, {
|
|
1276
1296
|
onClick: disabled ? void 0 : onClick,
|
|
1277
1297
|
hover: disabled ? void 0 : hover,
|
|
1278
1298
|
size,
|
|
1279
|
-
children: /* @__PURE__ */ jsx(
|
|
1299
|
+
children: /* @__PURE__ */ jsx(EntityPreviewBindingData, {
|
|
1280
1300
|
actions,
|
|
1281
1301
|
collection,
|
|
1282
1302
|
previewKeys,
|
|
@@ -1285,7 +1305,7 @@ function EntityPreview({ actions, disabled, hover, collection, previewKeys, onCl
|
|
|
1285
1305
|
includeTitle,
|
|
1286
1306
|
includeEntityLink,
|
|
1287
1307
|
includeImage,
|
|
1288
|
-
|
|
1308
|
+
onSidePanelClick,
|
|
1289
1309
|
entity
|
|
1290
1310
|
})
|
|
1291
1311
|
});
|
|
@@ -1369,16 +1389,16 @@ function ReferencePreviewInternal(props) {
|
|
|
1369
1389
|
...props,
|
|
1370
1390
|
collection
|
|
1371
1391
|
});
|
|
1372
|
-
if (collection
|
|
1373
|
-
|
|
1392
|
+
if (collection) return /* @__PURE__ */ jsx(CollectionScopeProvider, {
|
|
1393
|
+
collection,
|
|
1374
1394
|
children: content
|
|
1375
1395
|
});
|
|
1376
1396
|
return content;
|
|
1377
1397
|
}
|
|
1378
1398
|
function ReferencePreviewExisting({ reference, collection, previewProperties, size, disabled, includeEntityLink, includeId, onClick, hover, textOnly }) {
|
|
1379
|
-
const ResolvedEntityPreview = useComponentOverride("
|
|
1399
|
+
const ResolvedEntityPreview = useComponentOverride("EntityPreview", EntityPreviewBinding);
|
|
1380
1400
|
const customizationController = useCustomizationController();
|
|
1381
|
-
const { entity, dataLoading, dataLoadingError } =
|
|
1401
|
+
const { entity, dataLoading, dataLoadingError } = useFetch({
|
|
1382
1402
|
path: reference.path,
|
|
1383
1403
|
entityId: reference.id,
|
|
1384
1404
|
collection,
|
|
@@ -1468,8 +1488,8 @@ function ArrayOfReferencesPreview({ propertyKey, value, property, size }) {
|
|
|
1468
1488
|
});
|
|
1469
1489
|
}
|
|
1470
1490
|
//#endregion
|
|
1471
|
-
//#region src/components/
|
|
1472
|
-
function
|
|
1491
|
+
//#region src/components/EntityViewBinding.tsx
|
|
1492
|
+
function EntityViewBinding({ entity, collection, path, className }) {
|
|
1473
1493
|
const customizationController = useCustomizationController();
|
|
1474
1494
|
const properties = collection.properties;
|
|
1475
1495
|
return /* @__PURE__ */ jsx("div", {
|
|
@@ -1540,8 +1560,8 @@ function resolvedSelectedEntityView(customViews, customizationController, select
|
|
|
1540
1560
|
};
|
|
1541
1561
|
}
|
|
1542
1562
|
//#endregion
|
|
1543
|
-
//#region src/components/
|
|
1544
|
-
function
|
|
1563
|
+
//#region src/components/JsonPreviewBinding.tsx
|
|
1564
|
+
function JsonPreviewBinding({ values }) {
|
|
1545
1565
|
const code = JSON.stringify(values, null, " ");
|
|
1546
1566
|
const { mode } = useModeController();
|
|
1547
1567
|
const preRef = useRef(null);
|
|
@@ -1568,17 +1588,17 @@ function EntityJsonPreview({ values }) {
|
|
|
1568
1588
|
});
|
|
1569
1589
|
}
|
|
1570
1590
|
//#endregion
|
|
1571
|
-
//#region src/util/
|
|
1591
|
+
//#region src/util/view_constants.ts
|
|
1572
1592
|
/**
|
|
1573
|
-
* Shared tab value constants used by
|
|
1593
|
+
* Shared tab value constants used by EditViewBinding and DetailViewBinding.
|
|
1574
1594
|
*/
|
|
1575
1595
|
var MAIN_TAB_VALUE = "__main_##Q$SC^#S6";
|
|
1576
1596
|
var JSON_TAB_VALUE = "__json";
|
|
1577
1597
|
//#endregion
|
|
1578
|
-
//#region src/components/
|
|
1579
|
-
var EntityHistoryView$1 = lazy(() => import("./history-
|
|
1580
|
-
function
|
|
1581
|
-
const { entity, dataLoading, dataLoadingError } =
|
|
1598
|
+
//#region src/components/DetailViewBinding.tsx
|
|
1599
|
+
var EntityHistoryView$1 = lazy(() => import("./history-7X5bON_n.js").then((m) => ({ default: m.EntityHistoryView })));
|
|
1600
|
+
function DetailViewBinding({ entityId, ...props }) {
|
|
1601
|
+
const { entity, dataLoading, dataLoadingError } = useFetch({
|
|
1582
1602
|
path: props.path,
|
|
1583
1603
|
entityId,
|
|
1584
1604
|
collection: props.collection,
|
|
@@ -1589,20 +1609,19 @@ function EntityDetailView({ entityId, ...props }) {
|
|
|
1589
1609
|
variant: "label",
|
|
1590
1610
|
children: "Entity not found"
|
|
1591
1611
|
}) });
|
|
1592
|
-
const content = /* @__PURE__ */ jsx(
|
|
1612
|
+
const content = /* @__PURE__ */ jsx(DetailViewBindingInner, {
|
|
1593
1613
|
...props,
|
|
1594
1614
|
entityId,
|
|
1595
1615
|
entity,
|
|
1596
1616
|
dataLoading
|
|
1597
1617
|
});
|
|
1598
|
-
|
|
1599
|
-
|
|
1618
|
+
return /* @__PURE__ */ jsx(CollectionScopeProvider, {
|
|
1619
|
+
collection: props.collection,
|
|
1600
1620
|
children: content
|
|
1601
1621
|
});
|
|
1602
|
-
return content;
|
|
1603
1622
|
}
|
|
1604
|
-
function
|
|
1605
|
-
const ResolvedCollectionView = useComponentOverride("Collection.View",
|
|
1623
|
+
function DetailViewBindingInner({ path, entityId, selectedTab: selectedTabProp, collection, parentCollectionSlugs, parentEntityIds, onTabChange, onEditClick, entity, dataLoading, layout = "full_screen", barActions }) {
|
|
1624
|
+
const ResolvedCollectionView = useComponentOverride("Collection.View", CollectionViewBinding);
|
|
1606
1625
|
const { t } = useTranslation();
|
|
1607
1626
|
const context = useRebaseContext();
|
|
1608
1627
|
const urlController = useUrlController();
|
|
@@ -1751,7 +1770,7 @@ function EntityDetailViewInner({ path, entityId, selectedTab: selectedTabProp, c
|
|
|
1751
1770
|
const jsonView = activeTab === "__json" || jsonTabMounted ? /* @__PURE__ */ jsx("div", {
|
|
1752
1771
|
className: cls("relative flex-1 h-full overflow-auto w-full", { "hidden": activeTab !== JSON_TAB_VALUE }),
|
|
1753
1772
|
role: "tabpanel",
|
|
1754
|
-
children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(
|
|
1773
|
+
children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(JsonPreviewBinding, { values: usedEntity?.values ?? {} }) })
|
|
1755
1774
|
}, "json_view") : null;
|
|
1756
1775
|
const historyView = includeHistoryView && activeTab === "__rebase_history" ? /* @__PURE__ */ jsx("div", {
|
|
1757
1776
|
className: "relative flex-1 h-full overflow-auto w-full",
|
|
@@ -1768,7 +1787,7 @@ function EntityDetailViewInner({ path, entityId, selectedTab: selectedTabProp, c
|
|
|
1768
1787
|
}, "history_view") : null;
|
|
1769
1788
|
const subCollectionsViews = subcollections && subcollections.map((subcollection) => {
|
|
1770
1789
|
const subcollectionId = subcollection.slug;
|
|
1771
|
-
const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollection
|
|
1790
|
+
const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(getCollectionDataPath(subcollection))}` : void 0;
|
|
1772
1791
|
if (activeTab !== subcollectionId) return null;
|
|
1773
1792
|
return /* @__PURE__ */ jsxs("div", {
|
|
1774
1793
|
className: "relative flex-1 h-full overflow-auto w-full",
|
|
@@ -1816,7 +1835,7 @@ function EntityDetailViewInner({ path, entityId, selectedTab: selectedTabProp, c
|
|
|
1816
1835
|
formContext: readOnlyFormContext
|
|
1817
1836
|
})
|
|
1818
1837
|
}) });
|
|
1819
|
-
return /* @__PURE__ */ jsx(Fragment, { children: usedEntity && /* @__PURE__ */ jsx(
|
|
1838
|
+
return /* @__PURE__ */ jsx(Fragment, { children: usedEntity && /* @__PURE__ */ jsx(EntityViewBinding, {
|
|
1820
1839
|
entity: usedEntity,
|
|
1821
1840
|
collection,
|
|
1822
1841
|
path
|
|
@@ -2058,44 +2077,9 @@ function DetailViewSkeleton({ collection }) {
|
|
|
2058
2077
|
}
|
|
2059
2078
|
//#endregion
|
|
2060
2079
|
//#region src/components/SelectableTable/SelectionStore.ts
|
|
2061
|
-
/**
|
|
2062
|
-
* A ref-based selection store that avoids React context re-renders.
|
|
2063
|
-
*
|
|
2064
|
-
* The problem with putting `selectedCell` in a React context value is that
|
|
2065
|
-
* ANY cell selection change triggers a context value change, which forces
|
|
2066
|
-
* ALL consumers (every PropertyTableCell in the table) to re-render.
|
|
2067
|
-
* This causes the DOM to be replaced between mousedown and click events,
|
|
2068
|
-
* breaking `alwaysInteractive` cells (like relation selectors) where the
|
|
2069
|
-
* user needs to click a button on the very first interaction.
|
|
2070
|
-
*
|
|
2071
|
-
* This store uses `useSyncExternalStore` so only cells whose `selected`
|
|
2072
|
-
* derivation actually changed will re-render.
|
|
2073
|
-
*/
|
|
2074
2080
|
function createSelectionStore() {
|
|
2075
|
-
|
|
2076
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
2077
|
-
function getSnapshot() {
|
|
2078
|
-
return selectedCell;
|
|
2079
|
-
}
|
|
2080
|
-
function subscribe(listener) {
|
|
2081
|
-
listeners.add(listener);
|
|
2082
|
-
return () => listeners.delete(listener);
|
|
2083
|
-
}
|
|
2084
|
-
function select(cell) {
|
|
2085
|
-
selectedCell = cell;
|
|
2086
|
-
listeners.forEach((l) => l());
|
|
2087
|
-
}
|
|
2088
|
-
return {
|
|
2089
|
-
getSnapshot,
|
|
2090
|
-
subscribe,
|
|
2091
|
-
select
|
|
2092
|
-
};
|
|
2081
|
+
return createVirtualTableSelectionStore();
|
|
2093
2082
|
}
|
|
2094
|
-
/**
|
|
2095
|
-
* Hook that subscribes a cell to the selection store and returns
|
|
2096
|
-
* whether THIS cell is selected. Only re-renders when the cell's
|
|
2097
|
-
* `selected` boolean actually changes (not on every store update).
|
|
2098
|
-
*/
|
|
2099
2083
|
function useCellSelected(store, propertyKey, entityPath, entityId) {
|
|
2100
2084
|
const selectorRef = useRef({
|
|
2101
2085
|
propertyKey,
|
|
@@ -2107,79 +2091,16 @@ function useCellSelected(store, propertyKey, entityPath, entityId) {
|
|
|
2107
2091
|
entityPath,
|
|
2108
2092
|
entityId
|
|
2109
2093
|
};
|
|
2110
|
-
const
|
|
2111
|
-
const cell = store.
|
|
2094
|
+
const getEntity = useCallback(() => {
|
|
2095
|
+
const cell = store.getEntity();
|
|
2112
2096
|
if (!cell) return false;
|
|
2113
2097
|
const s = selectorRef.current;
|
|
2114
2098
|
return cell.propertyKey === s.propertyKey && cell.entityPath === s.entityPath && cell.entityId === s.entityId;
|
|
2115
2099
|
}, [store]);
|
|
2116
|
-
return useSyncExternalStore(store.subscribe,
|
|
2100
|
+
return useSyncExternalStore(store.subscribe, getEntity, getEntity);
|
|
2117
2101
|
}
|
|
2118
2102
|
//#endregion
|
|
2119
|
-
//#region src/components/
|
|
2120
|
-
function VirtualTableInput(props) {
|
|
2121
|
-
const ref = React.useRef(null);
|
|
2122
|
-
const { disabled, value, multiline, updateValue, focused } = props;
|
|
2123
|
-
const prevValue = useRef(value);
|
|
2124
|
-
const [internalValue, setInternalValue] = useState(value);
|
|
2125
|
-
const focusedState = useRef(false);
|
|
2126
|
-
useEffect(() => {
|
|
2127
|
-
if (prevValue.current !== value && value !== internalValue) setInternalValue(value);
|
|
2128
|
-
prevValue.current = value;
|
|
2129
|
-
}, [value]);
|
|
2130
|
-
const doUpdate = React.useCallback(() => {
|
|
2131
|
-
if (!value && !internalValue) return;
|
|
2132
|
-
if (internalValue !== value && internalValue !== prevValue.current) {
|
|
2133
|
-
prevValue.current = internalValue;
|
|
2134
|
-
updateValue(internalValue);
|
|
2135
|
-
}
|
|
2136
|
-
}, [
|
|
2137
|
-
internalValue,
|
|
2138
|
-
updateValue,
|
|
2139
|
-
value
|
|
2140
|
-
]);
|
|
2141
|
-
useDebouncedCallback(internalValue, doUpdate, !focused, 400);
|
|
2142
|
-
useEffect(() => {
|
|
2143
|
-
if (ref.current && focused && !focusedState.current) {
|
|
2144
|
-
focusedState.current = true;
|
|
2145
|
-
ref.current.focus({ preventScroll: true });
|
|
2146
|
-
ref.current.selectionStart = ref.current.value.length;
|
|
2147
|
-
ref.current.selectionEnd = ref.current.value.length;
|
|
2148
|
-
} else focusedState.current = focused;
|
|
2149
|
-
}, [focused, ref]);
|
|
2150
|
-
return /* @__PURE__ */ jsx(TextareaAutosize, {
|
|
2151
|
-
className: focusedDisabled,
|
|
2152
|
-
ref,
|
|
2153
|
-
style: {
|
|
2154
|
-
padding: 0,
|
|
2155
|
-
margin: 0,
|
|
2156
|
-
width: "100%",
|
|
2157
|
-
color: "unset",
|
|
2158
|
-
fontWeight: "unset",
|
|
2159
|
-
fontSize: "unset",
|
|
2160
|
-
fontFamily: "unset",
|
|
2161
|
-
background: "unset",
|
|
2162
|
-
border: "unset",
|
|
2163
|
-
resize: "none",
|
|
2164
|
-
outline: "none"
|
|
2165
|
-
},
|
|
2166
|
-
value: internalValue ?? "",
|
|
2167
|
-
onChange: (evt) => {
|
|
2168
|
-
const newValue = evt.target.value;
|
|
2169
|
-
if (multiline || !newValue.endsWith("\n")) setInternalValue(newValue);
|
|
2170
|
-
},
|
|
2171
|
-
onFocus: () => {
|
|
2172
|
-
focusedState.current = true;
|
|
2173
|
-
},
|
|
2174
|
-
onBlur: () => {
|
|
2175
|
-
focusedState.current = false;
|
|
2176
|
-
doUpdate();
|
|
2177
|
-
if (props.onBlur) props.onBlur();
|
|
2178
|
-
}
|
|
2179
|
-
});
|
|
2180
|
-
}
|
|
2181
|
-
//#endregion
|
|
2182
|
-
//#region src/components/EntityCollectionTable/fields/VirtualTableSelect.tsx
|
|
2103
|
+
//#region src/components/CollectionTableBinding/fields/VirtualTableSelect.tsx
|
|
2183
2104
|
function VirtualTableSelect(props) {
|
|
2184
2105
|
const { enumValues, internalValue, disabled, small, focused, updateValue, multiple, valueType } = props;
|
|
2185
2106
|
const validValue = Array.isArray(internalValue) && multiple || !Array.isArray(internalValue) && !multiple;
|
|
@@ -2252,78 +2173,6 @@ function VirtualTableSelect(props) {
|
|
|
2252
2173
|
});
|
|
2253
2174
|
}
|
|
2254
2175
|
//#endregion
|
|
2255
|
-
//#region src/components/EntityCollectionTable/fields/VirtualTableNumberInput.tsx
|
|
2256
|
-
function VirtualTableNumberInput(props) {
|
|
2257
|
-
const { align, value, updateValue, focused } = props;
|
|
2258
|
-
const propStringValue = value && typeof value === "number" ? value.toString() : "";
|
|
2259
|
-
const [internalValue, setInternalValue] = useState(propStringValue);
|
|
2260
|
-
const prevValue = useRef(value);
|
|
2261
|
-
useEffect(() => {
|
|
2262
|
-
if (prevValue.current !== value && String(value) !== internalValue) setInternalValue(value ? value.toString() : null);
|
|
2263
|
-
prevValue.current = value;
|
|
2264
|
-
}, [value]);
|
|
2265
|
-
useDebouncedCallback(internalValue, React.useCallback(() => {
|
|
2266
|
-
if (internalValue !== propStringValue) if (internalValue !== void 0 && internalValue !== null) {
|
|
2267
|
-
const numberValue = parseFloat(internalValue);
|
|
2268
|
-
if (isNaN(numberValue)) return;
|
|
2269
|
-
if (numberValue !== void 0 && numberValue !== null) updateValue(numberValue);
|
|
2270
|
-
} else updateValue(null);
|
|
2271
|
-
}, [internalValue, value]), !focused, 400);
|
|
2272
|
-
useEffect(() => {
|
|
2273
|
-
if (!focused && propStringValue !== internalValue) setInternalValue(value !== void 0 && value !== null ? value.toString() : null);
|
|
2274
|
-
}, [value, focused]);
|
|
2275
|
-
const inputRef = React.useRef(null);
|
|
2276
|
-
useEffect(() => {
|
|
2277
|
-
if (inputRef.current && focused) inputRef.current.focus({ preventScroll: true });
|
|
2278
|
-
}, [focused, inputRef]);
|
|
2279
|
-
const regexp = /^-?[0-9]+[,.]?[0-9]*$/;
|
|
2280
|
-
return /* @__PURE__ */ jsx(TextField, {
|
|
2281
|
-
inputRef,
|
|
2282
|
-
invisible: true,
|
|
2283
|
-
size: "small",
|
|
2284
|
-
className: "w-full",
|
|
2285
|
-
inputClassName: cls("p-0 m-0 bg-transparent border-none outline-hidden font-normal leading-normal text-unset", focusedDisabled),
|
|
2286
|
-
inputStyle: { textAlign: align },
|
|
2287
|
-
value: internalValue ?? "",
|
|
2288
|
-
onChange: (evt) => {
|
|
2289
|
-
const newValue = evt.target.value.replace(",", ".");
|
|
2290
|
-
if (newValue.length === 0) setInternalValue(null);
|
|
2291
|
-
if (regexp.test(newValue) || newValue.startsWith("-")) setInternalValue(newValue);
|
|
2292
|
-
}
|
|
2293
|
-
});
|
|
2294
|
-
}
|
|
2295
|
-
//#endregion
|
|
2296
|
-
//#region src/components/EntityCollectionTable/fields/VirtualTableSwitch.tsx
|
|
2297
|
-
function VirtualTableSwitch(props) {
|
|
2298
|
-
const { internalValue, updateValue, focused } = props;
|
|
2299
|
-
const ref = React.useRef(null);
|
|
2300
|
-
useEffect(() => {
|
|
2301
|
-
if (ref.current && focused) ref.current.focus({ preventScroll: true });
|
|
2302
|
-
}, [focused, ref]);
|
|
2303
|
-
return /* @__PURE__ */ jsx(BooleanSwitch, {
|
|
2304
|
-
ref,
|
|
2305
|
-
size: "small",
|
|
2306
|
-
value: Boolean(internalValue),
|
|
2307
|
-
onValueChange: updateValue
|
|
2308
|
-
});
|
|
2309
|
-
}
|
|
2310
|
-
//#endregion
|
|
2311
|
-
//#region src/components/EntityCollectionTable/fields/VirtualTableDateField.tsx
|
|
2312
|
-
function VirtualTableDateField(props) {
|
|
2313
|
-
const { locale } = useCustomizationController();
|
|
2314
|
-
const { disabled, error, mode, timezone, internalValue, updateValue } = props;
|
|
2315
|
-
return /* @__PURE__ */ jsx(DateTimeField, {
|
|
2316
|
-
value: internalValue ?? void 0,
|
|
2317
|
-
onChange: (dateValue) => updateValue(dateValue ?? null),
|
|
2318
|
-
invisible: true,
|
|
2319
|
-
inputClassName: cls("w-full h-full", focusedDisabled),
|
|
2320
|
-
className: cls("w-full h-full", focusedDisabled),
|
|
2321
|
-
mode,
|
|
2322
|
-
timezone,
|
|
2323
|
-
locale
|
|
2324
|
-
});
|
|
2325
|
-
}
|
|
2326
|
-
//#endregion
|
|
2327
2176
|
//#region src/components/UserSelector.tsx
|
|
2328
2177
|
var DEFAULT_PAGE_SIZE$2 = 10;
|
|
2329
2178
|
/**
|
|
@@ -2639,7 +2488,7 @@ var UserSelector = React$1.forwardRef(({ value, size = "medium", onValueChange,
|
|
|
2639
2488
|
});
|
|
2640
2489
|
UserSelector.displayName = "UserSelector";
|
|
2641
2490
|
//#endregion
|
|
2642
|
-
//#region src/components/
|
|
2491
|
+
//#region src/components/CollectionTableBinding/fields/VirtualTableUserSelect.tsx
|
|
2643
2492
|
function VirtualTableUserSelect(props) {
|
|
2644
2493
|
const { internalValue, disabled, small, focused, updateValue, multiple } = props;
|
|
2645
2494
|
return /* @__PURE__ */ jsx(UserSelector, {
|
|
@@ -2655,8 +2504,9 @@ function VirtualTableUserSelect(props) {
|
|
|
2655
2504
|
}
|
|
2656
2505
|
//#endregion
|
|
2657
2506
|
//#region src/form/components/StorageUploadProgress.tsx
|
|
2658
|
-
function StorageUploadProgress({ storagePath, entry, metadata, onFileUploadComplete, imageSize, simple }) {
|
|
2659
|
-
const
|
|
2507
|
+
function StorageUploadProgress({ storagePath, entry, metadata, onFileUploadComplete, imageSize, simple, storageSource: storageSourceProp }) {
|
|
2508
|
+
const defaultStorageSource = useStorageSource();
|
|
2509
|
+
const storageSource = storageSourceProp ?? defaultStorageSource;
|
|
2660
2510
|
const snackbarController = useSnackbarController();
|
|
2661
2511
|
const [error, setError] = React.useState();
|
|
2662
2512
|
const [loading, setLoading] = React.useState(false);
|
|
@@ -2720,7 +2570,7 @@ function StorageUploadProgress({ storagePath, entry, metadata, onFileUploadCompl
|
|
|
2720
2570
|
});
|
|
2721
2571
|
}
|
|
2722
2572
|
//#endregion
|
|
2723
|
-
//#region src/components/
|
|
2573
|
+
//#region src/components/CollectionTableBinding/internal/EntityTableCellActions.tsx
|
|
2724
2574
|
function EntityTableCellActions({ showError, disabled, showExpandIcon, selected, openPopup, children }) {
|
|
2725
2575
|
const ref = useRef(null);
|
|
2726
2576
|
const doOpenPopup = useCallback(() => {
|
|
@@ -2770,7 +2620,7 @@ function EntityTableCellActions({ showError, disabled, showExpandIcon, selected,
|
|
|
2770
2620
|
}) });
|
|
2771
2621
|
}
|
|
2772
2622
|
//#endregion
|
|
2773
|
-
//#region src/components/
|
|
2623
|
+
//#region src/components/CollectionTableBinding/fields/TableStorageUpload.tsx
|
|
2774
2624
|
var dropZoneClasses$1 = "max-w-full box-border relative pt-[2px] items-center border border-transparent outline-hidden rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid";
|
|
2775
2625
|
var activeDropClasses$1 = "pt-0 border-2 border-solid";
|
|
2776
2626
|
var acceptDropClasses$1 = "transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-green-500 bg-green-50 dark:bg-green-900";
|
|
@@ -2785,7 +2635,7 @@ var rejectDropClasses$1 = "transition-colors duration-200 ease-[cubic-bezier(0,0
|
|
|
2785
2635
|
function TableStorageUpload(props) {
|
|
2786
2636
|
const { propertyKey, error, selected, openPopup, value, disabled, property, entity, path, previewSize, updateValue } = props;
|
|
2787
2637
|
const storageSource = useStorageSource();
|
|
2788
|
-
const { internalValue, setInternalValue, onFilesAdded, storage, onFileUploadComplete, storagePathBuilder, multipleFilesSupported } = useStorageUploadController({
|
|
2638
|
+
const { internalValue, setInternalValue, onFilesAdded, storage, onFileUploadComplete, storagePathBuilder, multipleFilesSupported, resolvedStorageSource } = useStorageUploadController({
|
|
2789
2639
|
entityValues: entity.values,
|
|
2790
2640
|
entityId: entity.id,
|
|
2791
2641
|
path,
|
|
@@ -2796,24 +2646,27 @@ function TableStorageUpload(props) {
|
|
|
2796
2646
|
value,
|
|
2797
2647
|
disabled
|
|
2798
2648
|
});
|
|
2799
|
-
return /* @__PURE__ */ jsx(
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2649
|
+
return /* @__PURE__ */ jsx(StorageSourceContext.Provider, {
|
|
2650
|
+
value: resolvedStorageSource,
|
|
2651
|
+
children: /* @__PURE__ */ jsx(StorageUpload$1, {
|
|
2652
|
+
internalValue,
|
|
2653
|
+
setInternalValue,
|
|
2654
|
+
name: propertyKey,
|
|
2655
|
+
disabled,
|
|
2656
|
+
autoFocus: false,
|
|
2657
|
+
openPopup,
|
|
2658
|
+
error,
|
|
2659
|
+
selected,
|
|
2660
|
+
property,
|
|
2661
|
+
onChange: updateValue,
|
|
2662
|
+
entity,
|
|
2663
|
+
storagePathBuilder,
|
|
2664
|
+
storage,
|
|
2665
|
+
multipleFilesSupported,
|
|
2666
|
+
onFilesAdded,
|
|
2667
|
+
onFileUploadComplete,
|
|
2668
|
+
previewSize
|
|
2669
|
+
})
|
|
2817
2670
|
});
|
|
2818
2671
|
}
|
|
2819
2672
|
function StorageUpload$1({ property, name, internalValue, setInternalValue, openPopup, entity, selected, error, onChange, multipleFilesSupported, previewSize: previewSizeInput, disabled, autoFocus, storage, onFilesAdded, onFileUploadComplete, storagePathBuilder }) {
|
|
@@ -2923,7 +2776,7 @@ function TableStorageItemPreview({ propertyKey, property, value, size, entity })
|
|
|
2923
2776
|
});
|
|
2924
2777
|
}
|
|
2925
2778
|
//#endregion
|
|
2926
|
-
//#region src/hooks/
|
|
2779
|
+
//#region src/hooks/useSelectionDialog.tsx
|
|
2927
2780
|
/**
|
|
2928
2781
|
* This hook is used to open a side dialog that allows the selection
|
|
2929
2782
|
* of entities under a given path.
|
|
@@ -2934,17 +2787,17 @@ function TableStorageItemPreview({ propertyKey, property, value, size, entity })
|
|
|
2934
2787
|
* This is the same hook used internally when a reference property is defined.
|
|
2935
2788
|
* @group Hooks and utilities
|
|
2936
2789
|
*/
|
|
2937
|
-
function
|
|
2790
|
+
function useSelectionDialog(referenceDialogProps) {
|
|
2938
2791
|
const navigation = useCollectionRegistryController();
|
|
2939
2792
|
const sideDialogsController = useSideDialogsController();
|
|
2940
2793
|
const open = useCallback(() => {
|
|
2941
2794
|
if (referenceDialogProps.path) {
|
|
2942
2795
|
let usedCollection = referenceDialogProps.collection;
|
|
2943
2796
|
if (!usedCollection) usedCollection = navigation.getCollection(referenceDialogProps.path);
|
|
2944
|
-
if (!usedCollection) throw Error("Not able to resolve the collection in
|
|
2797
|
+
if (!usedCollection) throw Error("Not able to resolve the collection in useSelectionDialog. Make sure a collection is registered in path " + referenceDialogProps.path);
|
|
2945
2798
|
sideDialogsController.open({
|
|
2946
2799
|
key: `reference_${referenceDialogProps.path}`,
|
|
2947
|
-
component: /* @__PURE__ */ jsx(
|
|
2800
|
+
component: /* @__PURE__ */ jsx(SelectionTableBinding, {
|
|
2948
2801
|
collection: usedCollection,
|
|
2949
2802
|
...referenceDialogProps
|
|
2950
2803
|
}),
|
|
@@ -2968,7 +2821,7 @@ function useEntitySelectionDialog(referenceDialogProps) {
|
|
|
2968
2821
|
}), [open, close]);
|
|
2969
2822
|
}
|
|
2970
2823
|
//#endregion
|
|
2971
|
-
//#region src/components/
|
|
2824
|
+
//#region src/components/CollectionTableBinding/fields/TableReferenceField.tsx
|
|
2972
2825
|
var DefaultMissingReference$1 = () => null;
|
|
2973
2826
|
function TableReferenceFieldResolver(props) {
|
|
2974
2827
|
const ResolvedMissingReference = useComponentOverride("Entity.MissingReference", DefaultMissingReference$1);
|
|
@@ -2988,8 +2841,8 @@ function TableReferenceField(props) {
|
|
|
2988
2841
|
...props,
|
|
2989
2842
|
collection
|
|
2990
2843
|
});
|
|
2991
|
-
if (collection
|
|
2992
|
-
|
|
2844
|
+
if (collection) return /* @__PURE__ */ jsx(CollectionScopeProvider, {
|
|
2845
|
+
collection,
|
|
2993
2846
|
children: content
|
|
2994
2847
|
});
|
|
2995
2848
|
return content;
|
|
@@ -2999,7 +2852,7 @@ var TableReferenceFieldInternal = React.memo(function TableReferenceFieldInterna
|
|
|
2999
2852
|
const onSingleEntitySelected = useCallback((entity) => {
|
|
3000
2853
|
updateValue(entity ? getReferenceFrom(entity) : null);
|
|
3001
2854
|
}, [updateValue]);
|
|
3002
|
-
const referenceDialogController =
|
|
2855
|
+
const referenceDialogController = useSelectionDialog({
|
|
3003
2856
|
multiselect,
|
|
3004
2857
|
path,
|
|
3005
2858
|
collection,
|
|
@@ -3067,7 +2920,7 @@ var TableReferenceFieldInternal = React.memo(function TableReferenceFieldInterna
|
|
|
3067
2920
|
});
|
|
3068
2921
|
}, deepEqual);
|
|
3069
2922
|
//#endregion
|
|
3070
|
-
//#region src/components/
|
|
2923
|
+
//#region src/components/CollectionTableBinding/fields/TableMultipleRelationField.tsx
|
|
3071
2924
|
function TableMultipleRelationField(props) {
|
|
3072
2925
|
const collection = props.relation.target();
|
|
3073
2926
|
return /* @__PURE__ */ jsx(TableMultipleRelationFieldInternal, {
|
|
@@ -3082,9 +2935,9 @@ var TableMultipleRelationFieldInternal = React.memo(function TableMultipleRelati
|
|
|
3082
2935
|
updateValue(entities.map((e) => getRelationFrom(e)));
|
|
3083
2936
|
}, [updateValue]);
|
|
3084
2937
|
const selectedEntityIds = value.map((ref) => ref.id);
|
|
3085
|
-
const relationDialogController =
|
|
2938
|
+
const relationDialogController = useSelectionDialog({
|
|
3086
2939
|
multiselect: true,
|
|
3087
|
-
path: collection
|
|
2940
|
+
path: getCollectionDataPath(collection),
|
|
3088
2941
|
collection,
|
|
3089
2942
|
onMultipleEntitiesSelected,
|
|
3090
2943
|
selectedEntityIds,
|
|
@@ -3126,7 +2979,7 @@ var TableMultipleRelationFieldInternal = React.memo(function TableMultipleRelati
|
|
|
3126
2979
|
});
|
|
3127
2980
|
}, deepEqual);
|
|
3128
2981
|
//#endregion
|
|
3129
|
-
//#region src/components/
|
|
2982
|
+
//#region src/components/CollectionTableBinding/fields/TableRelationField.tsx
|
|
3130
2983
|
function TableRelationField(props) {
|
|
3131
2984
|
const collection = props.relation.target();
|
|
3132
2985
|
if (props.relation?.cardinality === "many") return /* @__PURE__ */ jsx(TableMultipleRelationField, {
|
|
@@ -3156,9 +3009,9 @@ var TableRelationFieldInternal = React.memo(function TableRelationFieldInternal(
|
|
|
3156
3009
|
updateValue(entities.map((e) => getRelationFrom(e)));
|
|
3157
3010
|
}, [updateValue]);
|
|
3158
3011
|
const selectedEntityIds = internalValue ? Array.isArray(internalValue) ? internalValue.map((ref) => ref.id) : internalValue.id ? [internalValue.id] : [] : [];
|
|
3159
|
-
const relationDialogController =
|
|
3012
|
+
const relationDialogController = useSelectionDialog({
|
|
3160
3013
|
multiselect,
|
|
3161
|
-
path: collection
|
|
3014
|
+
path: getCollectionDataPath(collection),
|
|
3162
3015
|
collection,
|
|
3163
3016
|
onMultipleEntitiesSelected,
|
|
3164
3017
|
onSingleEntitySelected,
|
|
@@ -3221,22 +3074,22 @@ var TableRelationFieldInternal = React.memo(function TableRelationFieldInternal(
|
|
|
3221
3074
|
});
|
|
3222
3075
|
}, deepEqual);
|
|
3223
3076
|
//#endregion
|
|
3224
|
-
//#region src/hooks/
|
|
3225
|
-
var
|
|
3077
|
+
//#region src/hooks/useSidePanel.tsx
|
|
3078
|
+
var SidePanelControllerContext = React.createContext({});
|
|
3226
3079
|
/**
|
|
3227
|
-
* Use this hook to retrieve
|
|
3228
|
-
* a side dialog to edit
|
|
3080
|
+
* Use this hook to retrieve a entity controller that allows you to open
|
|
3081
|
+
* a side dialog to edit a entity.
|
|
3229
3082
|
*
|
|
3230
|
-
* @see
|
|
3083
|
+
* @see SidePanelController
|
|
3231
3084
|
* @group Hooks and utilities
|
|
3232
3085
|
*/
|
|
3233
|
-
var
|
|
3086
|
+
var useSidePanel = () => useContext(SidePanelControllerContext);
|
|
3234
3087
|
//#endregion
|
|
3235
3088
|
//#region src/components/RelationSelector.tsx
|
|
3236
3089
|
var RelationSelector = React$1.forwardRef(({ value, size = "medium", onValueChange, invisible, disabled, placeholder, useChips = true, className, relation, fixedFilter, pageSize, emptyPlaceholder, searchPlaceholder = "Search...", noResultsText = "No relations found.", loadingText = "Loading..." }, ref) => {
|
|
3237
3090
|
const collection = relation.target();
|
|
3238
3091
|
const dataClient = useData();
|
|
3239
|
-
const
|
|
3092
|
+
const sidePanelController = useSidePanel();
|
|
3240
3093
|
const multiple = relation.cardinality === "many";
|
|
3241
3094
|
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
|
|
3242
3095
|
const isPopoverOpenRef = useRef(false);
|
|
@@ -3246,7 +3099,7 @@ var RelationSelector = React$1.forwardRef(({ value, size = "medium", onValueChan
|
|
|
3246
3099
|
const localSelectionIdsRef = useRef(null);
|
|
3247
3100
|
const pinnedIdsRef = useRef(null);
|
|
3248
3101
|
const { items: availableItems, isLoading, hasMore, search, loadMore, entityToRelationItem } = useRelationSelector({
|
|
3249
|
-
path: collection
|
|
3102
|
+
path: getCollectionDataPath(collection),
|
|
3250
3103
|
collection,
|
|
3251
3104
|
fixedFilter,
|
|
3252
3105
|
pageSize
|
|
@@ -3520,12 +3373,12 @@ var RelationSelector = React$1.forwardRef(({ value, size = "medium", onValueChan
|
|
|
3520
3373
|
children: selectedItems.map((item) => {
|
|
3521
3374
|
if (!useChips || !multiple) return /* @__PURE__ */ jsx("div", {
|
|
3522
3375
|
className: "flex flex-row items-center gap-1 truncate",
|
|
3523
|
-
children: item.data ? /* @__PURE__ */ jsx(
|
|
3376
|
+
children: item.data ? /* @__PURE__ */ jsx(EntityPreviewBindingData, {
|
|
3524
3377
|
size: "medium",
|
|
3525
3378
|
entity: item.data,
|
|
3526
3379
|
includeEntityLink: false,
|
|
3527
3380
|
includeId: false,
|
|
3528
|
-
|
|
3381
|
+
onSidePanelClick: closePopover
|
|
3529
3382
|
}) : /* @__PURE__ */ jsx("span", {
|
|
3530
3383
|
className: "text-sm truncate",
|
|
3531
3384
|
children: item.label
|
|
@@ -3534,7 +3387,7 @@ var RelationSelector = React$1.forwardRef(({ value, size = "medium", onValueChan
|
|
|
3534
3387
|
return /* @__PURE__ */ jsxs(Chip, {
|
|
3535
3388
|
size: "small",
|
|
3536
3389
|
className: cls("flex flex-row items-center gap-1 truncate"),
|
|
3537
|
-
children: [item.data ? /* @__PURE__ */ jsx(
|
|
3390
|
+
children: [item.data ? /* @__PURE__ */ jsx(EntityPreviewBindingData, {
|
|
3538
3391
|
size: "smallest",
|
|
3539
3392
|
entity: item.data,
|
|
3540
3393
|
includeEntityLink: false,
|
|
@@ -3568,7 +3421,7 @@ var RelationSelector = React$1.forwardRef(({ value, size = "medium", onValueChan
|
|
|
3568
3421
|
e.preventDefault();
|
|
3569
3422
|
const entity = selectedItems[0].data;
|
|
3570
3423
|
setIsPopoverOpen(false);
|
|
3571
|
-
|
|
3424
|
+
sidePanelController.open({
|
|
3572
3425
|
entityId: entity.id,
|
|
3573
3426
|
path: entity.path,
|
|
3574
3427
|
collection,
|
|
@@ -3670,7 +3523,7 @@ var RelationSelector = React$1.forwardRef(({ value, size = "medium", onValueChan
|
|
|
3670
3523
|
className: cls("flex flex-row items-center gap-1.5 m-1 p-1 rounded-xs cursor-pointer ring-offset-transparent", isSelected && "bg-surface-accent-200 dark:bg-surface-accent-950", "aria-selected:outline-hidden aria-selected:ring-2 aria-selected:ring-primary/75 aria-selected:ring-offset-2 aria-selected:bg-surface-accent-100 dark:aria-selected:bg-surface-accent-900"),
|
|
3671
3524
|
children: [multiple && /* @__PURE__ */ jsx(InnerCheckBox, { checked: isSelected }), item.data ? /* @__PURE__ */ jsx("div", {
|
|
3672
3525
|
className: "flex flex-row items-center gap-2 min-w-0 w-full",
|
|
3673
|
-
children: /* @__PURE__ */ jsx(
|
|
3526
|
+
children: /* @__PURE__ */ jsx(EntityPreviewBindingData, {
|
|
3674
3527
|
size: multiple ? "smallest" : "medium",
|
|
3675
3528
|
entity: item.data,
|
|
3676
3529
|
includeId: false,
|
|
@@ -3720,7 +3573,7 @@ function InnerCheckBox({ checked }) {
|
|
|
3720
3573
|
});
|
|
3721
3574
|
}
|
|
3722
3575
|
//#endregion
|
|
3723
|
-
//#region src/components/
|
|
3576
|
+
//#region src/components/CollectionTableBinding/fields/TableRelationSelectorField.tsx
|
|
3724
3577
|
/** Thin wrapper around RelationSelector for table cells */
|
|
3725
3578
|
function TableRelationSelectorField({ disabled = false, internalValue, updateValue, relation, fixedFilter, size = "medium" }) {
|
|
3726
3579
|
return /* @__PURE__ */ jsx(RelationSelector, {
|
|
@@ -3733,7 +3586,7 @@ function TableRelationSelectorField({ disabled = false, internalValue, updateVal
|
|
|
3733
3586
|
});
|
|
3734
3587
|
}
|
|
3735
3588
|
//#endregion
|
|
3736
|
-
//#region src/components/
|
|
3589
|
+
//#region src/components/CollectionTableBinding/table_bindings.tsx
|
|
3737
3590
|
function isStorageProperty(property) {
|
|
3738
3591
|
if (property.type === "string" && property.ui?.markdown) return false;
|
|
3739
3592
|
if (property.type === "string" && property.storage) return true;
|
|
@@ -3742,32 +3595,7 @@ function isStorageProperty(property) {
|
|
|
3742
3595
|
return false;
|
|
3743
3596
|
}
|
|
3744
3597
|
function getTableBindingForProperty(property, selected) {
|
|
3745
|
-
|
|
3746
|
-
if (property.type === "string" && property.reference?.path) return {
|
|
3747
|
-
Component: ({ propertyKey, property, internalValue, updateValue, disabled, size, path }) => {
|
|
3748
|
-
const referenceProperty = property.reference;
|
|
3749
|
-
if (!referenceProperty) return null;
|
|
3750
|
-
return /* @__PURE__ */ jsx(TableReferenceField, {
|
|
3751
|
-
name: propertyKey,
|
|
3752
|
-
internalValue: internalValue ? new EntityReference({
|
|
3753
|
-
id: internalValue,
|
|
3754
|
-
path: referenceProperty.path
|
|
3755
|
-
}) : void 0,
|
|
3756
|
-
updateValue: (v) => updateValue(v ? v.id : null),
|
|
3757
|
-
disabled,
|
|
3758
|
-
size,
|
|
3759
|
-
path: referenceProperty.path,
|
|
3760
|
-
multiselect: false,
|
|
3761
|
-
previewProperties: referenceProperty.ui?.previewProperties,
|
|
3762
|
-
includeId: referenceProperty.includeId,
|
|
3763
|
-
includeEntityLink: referenceProperty.includeEntityLink,
|
|
3764
|
-
title: property.name,
|
|
3765
|
-
fixedFilter: referenceProperty.fixedFilter
|
|
3766
|
-
});
|
|
3767
|
-
},
|
|
3768
|
-
allowScroll: false
|
|
3769
|
-
};
|
|
3770
|
-
else if (isAStorageProperty) return {
|
|
3598
|
+
if (isStorageProperty(property)) return {
|
|
3771
3599
|
Component: ({ validationError, error, disabled, selected, openPopup, property, entity, path, internalValue, size, updateValue, propertyKey }) => /* @__PURE__ */ jsx(TableStorageUpload, {
|
|
3772
3600
|
error: validationError ?? error,
|
|
3773
3601
|
disabled,
|
|
@@ -3845,7 +3673,7 @@ function getTableBindingForProperty(property, selected) {
|
|
|
3845
3673
|
}),
|
|
3846
3674
|
fullHeight: true
|
|
3847
3675
|
};
|
|
3848
|
-
else if (stringProperty.ui?.markdown || !stringProperty.storage
|
|
3676
|
+
else if (stringProperty.ui?.markdown || !stringProperty.storage) {
|
|
3849
3677
|
const multiline = Boolean(stringProperty.ui?.multiline) || Boolean(stringProperty.ui?.markdown);
|
|
3850
3678
|
return {
|
|
3851
3679
|
Component: ({ error, validationError, disabled, selected, internalValue, updateValue }) => /* @__PURE__ */ jsx(VirtualTableInput, {
|
|
@@ -3867,15 +3695,19 @@ function getTableBindingForProperty(property, selected) {
|
|
|
3867
3695
|
updateValue
|
|
3868
3696
|
}) };
|
|
3869
3697
|
else if (property.type === "date") return {
|
|
3870
|
-
Component: ({ propertyKey, error, validationError, disabled, selected, property, internalValue, updateValue }) =>
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3698
|
+
Component: ({ propertyKey, error, validationError, disabled, selected, property, internalValue, updateValue }) => {
|
|
3699
|
+
const { locale } = useCustomizationController();
|
|
3700
|
+
return /* @__PURE__ */ jsx(VirtualTableDateField, {
|
|
3701
|
+
name: propertyKey,
|
|
3702
|
+
error: validationError ?? error,
|
|
3703
|
+
disabled,
|
|
3704
|
+
mode: property.mode,
|
|
3705
|
+
focused: selected,
|
|
3706
|
+
internalValue,
|
|
3707
|
+
updateValue,
|
|
3708
|
+
locale
|
|
3709
|
+
});
|
|
3710
|
+
},
|
|
3879
3711
|
fullHeight: true,
|
|
3880
3712
|
hideOverflow: false,
|
|
3881
3713
|
allowScroll: false
|
|
@@ -3987,7 +3819,7 @@ function RelationSelectorBindingComponent({ propertyKey, internalValue, updateVa
|
|
|
3987
3819
|
});
|
|
3988
3820
|
}
|
|
3989
3821
|
//#endregion
|
|
3990
|
-
//#region src/components/
|
|
3822
|
+
//#region src/components/CollectionTableBinding/internal/EntityTableCell.tsx
|
|
3991
3823
|
var TableCellInner = ({ justifyContent, scrollable, faded, fullHeight, children }) => {
|
|
3992
3824
|
return /* @__PURE__ */ jsx("div", {
|
|
3993
3825
|
className: cls("flex flex-col max-h-full w-full", { "items-start": faded || scrollable }),
|
|
@@ -4148,7 +3980,7 @@ function useClearRestoreValue({ property, value, setValue }) {
|
|
|
4148
3980
|
}, [property]);
|
|
4149
3981
|
}
|
|
4150
3982
|
//#endregion
|
|
4151
|
-
//#region src/components/
|
|
3983
|
+
//#region src/components/CollectionTableBinding/PropertyTableCell.tsx
|
|
4152
3984
|
var PropertyTableCell = React.memo(function PropertyTableCell({ propertyKey, customFieldValidator, value, property, align, width, height, path, entity, readonly, disabled: disabledProp, enablePopupIcon = true, sortableNodeRef, sortableStyle, sortableAttributes, isDragging, isDraggable, frozen }) {
|
|
4153
3985
|
const { onValueChange, size, selectionStore, select, setPopupCell } = useSelectableTableController();
|
|
4154
3986
|
const dummySelectionStore = useMemo(() => createSelectionStore(), []);
|
|
@@ -4364,7 +4196,7 @@ function areEqual(prevProps, nextProps) {
|
|
|
4364
4196
|
return prevProps.height === nextProps.height && prevProps.propertyKey === nextProps.propertyKey && prevProps.align === nextProps.align && prevProps.width === nextProps.width && deepEqual(prevProps.property, nextProps.property) && deepEqual(prevProps.value, nextProps.value) && prevProps.entity.id === nextProps.entity.id && prevProps.entity.path === nextProps.entity.path && prevProps.isDragging === nextProps.isDragging && prevProps.isDraggable === nextProps.isDraggable && prevProps.frozen === nextProps.frozen;
|
|
4365
4197
|
}
|
|
4366
4198
|
//#endregion
|
|
4367
|
-
//#region src/components/
|
|
4199
|
+
//#region src/components/CollectionTableBinding/CollectionRowActions.tsx
|
|
4368
4200
|
/**
|
|
4369
4201
|
*
|
|
4370
4202
|
* @param entity
|
|
@@ -4378,9 +4210,9 @@ function areEqual(prevProps, nextProps) {
|
|
|
4378
4210
|
*
|
|
4379
4211
|
* @group Collection components
|
|
4380
4212
|
*/
|
|
4381
|
-
var
|
|
4213
|
+
var CollectionRowActions = function CollectionRowActions({ entity, collection, path, width, frozen, isSelected, selectionEnabled, size, highlightEntity, onCollectionChange, unhighlightEntity, actions = [], hideId, selectionController, openEntityMode, sortableNodeRef, sortableStyle, sortableAttributes, isDragging, isDraggable }) {
|
|
4382
4214
|
const context = useCMSContext();
|
|
4383
|
-
const
|
|
4215
|
+
const sidePanelCtrl = context.sidePanelController;
|
|
4384
4216
|
const { t } = useTranslation();
|
|
4385
4217
|
const onCheckedChange = useCallback((checked) => {
|
|
4386
4218
|
selectionController?.toggleEntitySelection(entity, checked);
|
|
@@ -4417,7 +4249,7 @@ var EntityCollectionRowActions = function EntityCollectionRowActions({ entity, c
|
|
|
4417
4249
|
path,
|
|
4418
4250
|
collection,
|
|
4419
4251
|
context,
|
|
4420
|
-
|
|
4252
|
+
sidePanelController: sidePanelCtrl,
|
|
4421
4253
|
selectionController,
|
|
4422
4254
|
highlightEntity,
|
|
4423
4255
|
unhighlightEntity,
|
|
@@ -4452,7 +4284,7 @@ var EntityCollectionRowActions = function EntityCollectionRowActions({ entity, c
|
|
|
4452
4284
|
path,
|
|
4453
4285
|
collection,
|
|
4454
4286
|
context,
|
|
4455
|
-
|
|
4287
|
+
sidePanelController: sidePanelCtrl,
|
|
4456
4288
|
selectionController,
|
|
4457
4289
|
highlightEntity,
|
|
4458
4290
|
unhighlightEntity,
|
|
@@ -4496,7 +4328,7 @@ var EntityCollectionRowActions = function EntityCollectionRowActions({ entity, c
|
|
|
4496
4328
|
return content;
|
|
4497
4329
|
};
|
|
4498
4330
|
//#endregion
|
|
4499
|
-
//#region src/components/
|
|
4331
|
+
//#region src/components/CollectionTableBinding/internal/CollectionTableToolbar.tsx
|
|
4500
4332
|
function CollectionTableToolbar({ actions, actionsStart, loading, onTextSearch, title, viewModeToggle, initialSearchText, compact = false }) {
|
|
4501
4333
|
const largeLayout = useLargeLayout();
|
|
4502
4334
|
const { t } = useTranslation();
|
|
@@ -4539,7 +4371,7 @@ function CollectionTableToolbar({ actions, actionsStart, loading, onTextSearch,
|
|
|
4539
4371
|
});
|
|
4540
4372
|
}
|
|
4541
4373
|
//#endregion
|
|
4542
|
-
//#region src/components/
|
|
4374
|
+
//#region src/components/CollectionTableBinding/internal/common.tsx
|
|
4543
4375
|
function getTableCellAlignment(property) {
|
|
4544
4376
|
if (property.type === "boolean") return "center";
|
|
4545
4377
|
else if (property.type === "number") {
|
|
@@ -4576,7 +4408,7 @@ function getSubcollectionColumnId(collection) {
|
|
|
4576
4408
|
return `subcollection:${collection.slug}`;
|
|
4577
4409
|
}
|
|
4578
4410
|
//#endregion
|
|
4579
|
-
//#region src/components/
|
|
4411
|
+
//#region src/components/CollectionTableBinding/column_utils.tsx
|
|
4580
4412
|
function propertiesToColumns({ properties, sortable, fixedFilter, AdditionalHeaderWidget }) {
|
|
4581
4413
|
const disabledFilter = Boolean(fixedFilter);
|
|
4582
4414
|
return Object.entries(properties).flatMap(([key, property]) => getColumnKeysForProperty(property, key)).map(({ key, disabled }) => {
|
|
@@ -4625,140 +4457,8 @@ function filterableProperty(property, partOfArray = false) {
|
|
|
4625
4457
|
].includes(property.type);
|
|
4626
4458
|
}
|
|
4627
4459
|
//#endregion
|
|
4628
|
-
//#region src/components/SelectableTable/filters/ReferenceFilterField.tsx
|
|
4629
|
-
var operationLabels$3 = {
|
|
4630
|
-
"==": "==",
|
|
4631
|
-
"!=": "!=",
|
|
4632
|
-
">": ">",
|
|
4633
|
-
"<": "<",
|
|
4634
|
-
">=": ">=",
|
|
4635
|
-
"<=": "<=",
|
|
4636
|
-
in: "In",
|
|
4637
|
-
"not-in": "Not in",
|
|
4638
|
-
"array-contains": "Contains",
|
|
4639
|
-
"array-contains-any": "Contains Any"
|
|
4640
|
-
};
|
|
4641
|
-
var multipleSelectOperations$3 = [
|
|
4642
|
-
"array-contains-any",
|
|
4643
|
-
"in",
|
|
4644
|
-
"not-in"
|
|
4645
|
-
];
|
|
4646
|
-
function ReferenceFilterField({ value, setValue, isArray, path, includeId = true, previewProperties, setHidden }) {
|
|
4647
|
-
const { t } = useTranslation();
|
|
4648
|
-
const possibleOperations = isArray ? ["array-contains"] : [
|
|
4649
|
-
"==",
|
|
4650
|
-
"!=",
|
|
4651
|
-
">",
|
|
4652
|
-
"<",
|
|
4653
|
-
">=",
|
|
4654
|
-
"<="
|
|
4655
|
-
];
|
|
4656
|
-
if (isArray) possibleOperations.push("array-contains-any");
|
|
4657
|
-
else possibleOperations.push("in", "not-in");
|
|
4658
|
-
const [fieldOperation, fieldValue] = value || [possibleOperations[0], void 0];
|
|
4659
|
-
const [operation, setOperation] = useState(fieldOperation);
|
|
4660
|
-
const [internalValue, setInternalValue] = useState(fieldValue);
|
|
4661
|
-
const selectedEntityIds = internalValue ? Array.isArray(internalValue) ? internalValue.map((ref) => {
|
|
4662
|
-
if (!(ref?.isEntityReference && ref?.isEntityReference())) return null;
|
|
4663
|
-
return ref.id;
|
|
4664
|
-
}).filter(Boolean) : [internalValue.id] : [];
|
|
4665
|
-
function updateFilter(op, val) {
|
|
4666
|
-
const prevOpIsArray = multipleSelectOperations$3.includes(operation);
|
|
4667
|
-
const newOpIsArray = multipleSelectOperations$3.includes(op);
|
|
4668
|
-
let newValue = val;
|
|
4669
|
-
if (prevOpIsArray !== newOpIsArray) newValue = newOpIsArray ? newValue && !Array.isArray(newValue) && newValue.isEntityReference?.() ? [newValue] : [] : void 0;
|
|
4670
|
-
setOperation(op);
|
|
4671
|
-
setInternalValue(newValue);
|
|
4672
|
-
const hasNewValue = newValue !== null && Array.isArray(newValue) ? newValue.length > 0 : newValue !== void 0;
|
|
4673
|
-
if (op && hasNewValue) setValue([op, newValue]);
|
|
4674
|
-
else setValue(void 0);
|
|
4675
|
-
}
|
|
4676
|
-
const collectionRegistryController = useCollectionRegistryController();
|
|
4677
|
-
const collection = useMemo(() => {
|
|
4678
|
-
return path ? collectionRegistryController.getCollection(path) : void 0;
|
|
4679
|
-
}, [path]);
|
|
4680
|
-
const onSingleEntitySelected = (entity) => {
|
|
4681
|
-
updateFilter(operation, getReferenceFrom(entity));
|
|
4682
|
-
};
|
|
4683
|
-
const onMultipleEntitiesSelected = (entities) => {
|
|
4684
|
-
updateFilter(operation, entities.map((e) => getReferenceFrom(e)));
|
|
4685
|
-
};
|
|
4686
|
-
const multiple = multipleSelectOperations$3.includes(operation);
|
|
4687
|
-
const referenceDialogController = useEntitySelectionDialog({
|
|
4688
|
-
multiselect: multiple,
|
|
4689
|
-
path,
|
|
4690
|
-
collection,
|
|
4691
|
-
onSingleEntitySelected,
|
|
4692
|
-
onMultipleEntitiesSelected,
|
|
4693
|
-
selectedEntityIds,
|
|
4694
|
-
onClose: () => {
|
|
4695
|
-
setHidden(false);
|
|
4696
|
-
}
|
|
4697
|
-
});
|
|
4698
|
-
const doOpenDialog = () => {
|
|
4699
|
-
setHidden(true);
|
|
4700
|
-
referenceDialogController.open();
|
|
4701
|
-
};
|
|
4702
|
-
const buildEntry = (reference) => {
|
|
4703
|
-
return /* @__PURE__ */ jsx(ReferencePreview, {
|
|
4704
|
-
disabled: !path,
|
|
4705
|
-
previewProperties,
|
|
4706
|
-
size: "medium",
|
|
4707
|
-
onClick: doOpenDialog,
|
|
4708
|
-
reference,
|
|
4709
|
-
hover: true,
|
|
4710
|
-
includeId,
|
|
4711
|
-
includeEntityLink: false
|
|
4712
|
-
});
|
|
4713
|
-
};
|
|
4714
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
4715
|
-
className: "flex w-full flex-row",
|
|
4716
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
4717
|
-
className: "w-[100px]",
|
|
4718
|
-
children: /* @__PURE__ */ jsx(Select, {
|
|
4719
|
-
value: operation,
|
|
4720
|
-
size: "medium",
|
|
4721
|
-
fullWidth: true,
|
|
4722
|
-
onValueChange: (value) => {
|
|
4723
|
-
updateFilter(value, internalValue);
|
|
4724
|
-
},
|
|
4725
|
-
renderValue: (op) => operationLabels$3[op],
|
|
4726
|
-
children: possibleOperations.map((op) => /* @__PURE__ */ jsx(SelectItem, {
|
|
4727
|
-
value: op,
|
|
4728
|
-
children: operationLabels$3[op]
|
|
4729
|
-
}, op))
|
|
4730
|
-
})
|
|
4731
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
4732
|
-
className: "grow ml-2 h-full gap-2 flex flex-col",
|
|
4733
|
-
children: [
|
|
4734
|
-
internalValue && Array.isArray(internalValue) && /* @__PURE__ */ jsx("div", { children: internalValue.map((ref, index) => buildEntry(ref)) }),
|
|
4735
|
-
internalValue && !Array.isArray(internalValue) && /* @__PURE__ */ jsx("div", { children: buildEntry(internalValue) }),
|
|
4736
|
-
(!internalValue || Array.isArray(internalValue) && internalValue.length === 0) && /* @__PURE__ */ jsx(Button, {
|
|
4737
|
-
onClick: doOpenDialog,
|
|
4738
|
-
size: "medium",
|
|
4739
|
-
className: "h-full w-full",
|
|
4740
|
-
children: multiple ? t("select_references") : t("select_reference")
|
|
4741
|
-
}),
|
|
4742
|
-
!isArray && /* @__PURE__ */ jsxs(Label, {
|
|
4743
|
-
className: "border cursor-pointer rounded-md p-2 flex items-center gap-2 bg-surface-50 dark:bg-surface-900 hover:bg-surface-100 dark:hover:bg-surface-800",
|
|
4744
|
-
htmlFor: "null-filter",
|
|
4745
|
-
children: [/* @__PURE__ */ jsx(Checkbox, {
|
|
4746
|
-
id: "null-filter",
|
|
4747
|
-
checked: internalValue === null,
|
|
4748
|
-
size: "small",
|
|
4749
|
-
onCheckedChange: (checked) => {
|
|
4750
|
-
if (internalValue !== null) updateFilter(operation, null);
|
|
4751
|
-
else updateFilter(operation, void 0);
|
|
4752
|
-
}
|
|
4753
|
-
}), t("filter_for_null_values")]
|
|
4754
|
-
})
|
|
4755
|
-
]
|
|
4756
|
-
})]
|
|
4757
|
-
});
|
|
4758
|
-
}
|
|
4759
|
-
//#endregion
|
|
4760
4460
|
//#region src/components/SelectableTable/filters/StringNumberFilterField.tsx
|
|
4761
|
-
var operationLabels$
|
|
4461
|
+
var operationLabels$3 = {
|
|
4762
4462
|
"==": "==",
|
|
4763
4463
|
"!=": "!=",
|
|
4764
4464
|
">": ">",
|
|
@@ -4769,40 +4469,62 @@ var operationLabels$2 = {
|
|
|
4769
4469
|
"not-in": "Not in",
|
|
4770
4470
|
"array-contains": "Contains",
|
|
4771
4471
|
"array-contains-any": "Any",
|
|
4772
|
-
"
|
|
4472
|
+
"ilike": "Contains",
|
|
4473
|
+
"not-ilike": "Not contains",
|
|
4474
|
+
"is-null": "Is null",
|
|
4475
|
+
"is-not-null": "Is not null"
|
|
4773
4476
|
};
|
|
4774
|
-
var multipleSelectOperations$
|
|
4477
|
+
var multipleSelectOperations$3 = [
|
|
4775
4478
|
"array-contains-any",
|
|
4776
4479
|
"in",
|
|
4777
4480
|
"not-in"
|
|
4778
4481
|
];
|
|
4779
|
-
|
|
4482
|
+
/** Operators that match a substring, wrapped in SQL wildcards (`%value%`). */
|
|
4483
|
+
var containsOperations = ["ilike", "not-ilike"];
|
|
4484
|
+
/** Strip the surrounding `%` wildcards a contains-filter adds, for display. */
|
|
4485
|
+
function unwrapContains(value) {
|
|
4486
|
+
if (typeof value !== "string") return "";
|
|
4487
|
+
return value.replace(/^%/, "").replace(/%$/, "");
|
|
4488
|
+
}
|
|
4489
|
+
function StringNumberFilterField({ name, value, setValue, type, isArray, enumValues, title, operators }) {
|
|
4780
4490
|
const { t } = useTranslation();
|
|
4781
|
-
|
|
4491
|
+
let possibleOperations = isArray ? ["array-contains"] : [
|
|
4782
4492
|
"==",
|
|
4783
4493
|
"!=",
|
|
4784
4494
|
">",
|
|
4785
4495
|
"<",
|
|
4786
4496
|
">=",
|
|
4787
4497
|
"<=",
|
|
4788
|
-
"is-null"
|
|
4498
|
+
"is-null",
|
|
4499
|
+
"is-not-null"
|
|
4789
4500
|
];
|
|
4501
|
+
if (!isArray && !enumValues && type === "string") possibleOperations.push("ilike", "not-ilike");
|
|
4790
4502
|
if (enumValues) if (isArray) possibleOperations.push("array-contains-any");
|
|
4791
4503
|
else possibleOperations.push("in", "not-in");
|
|
4504
|
+
if (operators) possibleOperations = possibleOperations.filter((op) => operators.includes(op));
|
|
4792
4505
|
const [fieldOperation, fieldValue] = value || [possibleOperations[0], void 0];
|
|
4793
|
-
const [operation, setOperation] = useState(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation);
|
|
4794
|
-
const [internalValue, setInternalValue] = useState(fieldValue);
|
|
4795
|
-
const isNullOperation = operation === "is-null";
|
|
4506
|
+
const [operation, setOperation] = useState(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation === "!=" && fieldValue === null ? "is-not-null" : fieldOperation);
|
|
4507
|
+
const [internalValue, setInternalValue] = useState(containsOperations.includes(fieldOperation) ? unwrapContains(fieldValue) : fieldValue);
|
|
4508
|
+
const isNullOperation = operation === "is-null" || operation === "is-not-null";
|
|
4509
|
+
if (possibleOperations.length === 0) return null;
|
|
4796
4510
|
function updateFilter(op, val) {
|
|
4797
|
-
if (op === "is-null") {
|
|
4511
|
+
if (op === "is-null" || op === "is-not-null") {
|
|
4798
4512
|
setOperation(op);
|
|
4799
4513
|
setInternalValue(null);
|
|
4800
|
-
setValue([
|
|
4514
|
+
setValue([op, null]);
|
|
4515
|
+
return;
|
|
4516
|
+
}
|
|
4517
|
+
if (op === "ilike" || op === "not-ilike") {
|
|
4518
|
+
const raw = typeof val === "string" ? val : "";
|
|
4519
|
+
setOperation(op);
|
|
4520
|
+
setInternalValue(raw);
|
|
4521
|
+
if (raw.length > 0) setValue([op, `%${raw}%`]);
|
|
4522
|
+
else setValue(void 0);
|
|
4801
4523
|
return;
|
|
4802
4524
|
}
|
|
4803
4525
|
let newValue = val;
|
|
4804
|
-
const prevOpIsArray = multipleSelectOperations$
|
|
4805
|
-
const newOpIsArray = multipleSelectOperations$
|
|
4526
|
+
const prevOpIsArray = multipleSelectOperations$3.includes(operation);
|
|
4527
|
+
const newOpIsArray = multipleSelectOperations$3.includes(op);
|
|
4806
4528
|
if (prevOpIsArray !== newOpIsArray) if (newOpIsArray) if (typeof val === "string") newValue = [val];
|
|
4807
4529
|
else if (typeof val === "number") newValue = [val];
|
|
4808
4530
|
else newValue = [];
|
|
@@ -4814,7 +4536,7 @@ function StringNumberFilterField({ name, value, setValue, type, isArray, enumVal
|
|
|
4814
4536
|
if (op && hasNewValue) setValue([op, newValue]);
|
|
4815
4537
|
else setValue(void 0);
|
|
4816
4538
|
}
|
|
4817
|
-
const multiple = multipleSelectOperations$
|
|
4539
|
+
const multiple = multipleSelectOperations$3.includes(operation);
|
|
4818
4540
|
return /* @__PURE__ */ jsxs("div", {
|
|
4819
4541
|
className: "flex w-full",
|
|
4820
4542
|
children: [/* @__PURE__ */ jsx("div", {
|
|
@@ -4827,10 +4549,10 @@ function StringNumberFilterField({ name, value, setValue, type, isArray, enumVal
|
|
|
4827
4549
|
onValueChange: (value) => {
|
|
4828
4550
|
updateFilter(value, internalValue);
|
|
4829
4551
|
},
|
|
4830
|
-
renderValue: (op) => operationLabels$
|
|
4552
|
+
renderValue: (op) => operationLabels$3[op],
|
|
4831
4553
|
children: possibleOperations.map((op) => /* @__PURE__ */ jsx(SelectItem, {
|
|
4832
4554
|
value: op,
|
|
4833
|
-
children: operationLabels$
|
|
4555
|
+
children: operationLabels$3[op]
|
|
4834
4556
|
}, op))
|
|
4835
4557
|
})
|
|
4836
4558
|
}), /* @__PURE__ */ jsxs("div", {
|
|
@@ -4910,8 +4632,9 @@ function StringNumberFilterField({ name, value, setValue, type, isArray, enumVal
|
|
|
4910
4632
|
}
|
|
4911
4633
|
//#endregion
|
|
4912
4634
|
//#region src/components/SelectableTable/filters/BooleanFilterField.tsx
|
|
4913
|
-
function BooleanFilterField({ name, title, value, setValue }) {
|
|
4635
|
+
function BooleanFilterField({ name, title, value, setValue, operators }) {
|
|
4914
4636
|
const { t } = useTranslation();
|
|
4637
|
+
if (operators && !operators.includes("==")) return null;
|
|
4915
4638
|
function updateFilter(val) {
|
|
4916
4639
|
if (val !== void 0) setValue(["==", val]);
|
|
4917
4640
|
else setValue(void 0);
|
|
@@ -4930,7 +4653,7 @@ function BooleanFilterField({ name, title, value, setValue }) {
|
|
|
4930
4653
|
}
|
|
4931
4654
|
//#endregion
|
|
4932
4655
|
//#region src/components/SelectableTable/filters/DateTimeFilterField.tsx
|
|
4933
|
-
var operationLabels$
|
|
4656
|
+
var operationLabels$2 = {
|
|
4934
4657
|
"==": "==",
|
|
4935
4658
|
"!=": "!=",
|
|
4936
4659
|
">": ">",
|
|
@@ -4941,34 +4664,38 @@ var operationLabels$1 = {
|
|
|
4941
4664
|
in: "in",
|
|
4942
4665
|
"array-contains": "Contains",
|
|
4943
4666
|
"array-contains-any": "Any",
|
|
4944
|
-
"is-null": "Is null"
|
|
4667
|
+
"is-null": "Is null",
|
|
4668
|
+
"is-not-null": "Is not null"
|
|
4945
4669
|
};
|
|
4946
|
-
var multipleSelectOperations$
|
|
4947
|
-
function DateTimeFilterField({ name, isArray, mode, value, setValue, title, timezone }) {
|
|
4670
|
+
var multipleSelectOperations$2 = ["array-contains-any", "in"];
|
|
4671
|
+
function DateTimeFilterField({ name, isArray, mode, value, setValue, title, timezone, operators }) {
|
|
4948
4672
|
const { locale } = useCustomizationController();
|
|
4949
|
-
|
|
4673
|
+
let possibleOperations = isArray ? ["array-contains"] : [
|
|
4950
4674
|
"==",
|
|
4951
4675
|
"!=",
|
|
4952
4676
|
">",
|
|
4953
4677
|
"<",
|
|
4954
4678
|
">=",
|
|
4955
4679
|
"<=",
|
|
4956
|
-
"is-null"
|
|
4680
|
+
"is-null",
|
|
4681
|
+
"is-not-null"
|
|
4957
4682
|
];
|
|
4683
|
+
if (operators) possibleOperations = possibleOperations.filter((op) => operators.includes(op));
|
|
4958
4684
|
const [fieldOperation, fieldValue] = value || [possibleOperations[0], void 0];
|
|
4959
|
-
const [operation, setOperation] = useState(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation);
|
|
4685
|
+
const [operation, setOperation] = useState(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation === "!=" && fieldValue === null ? "is-not-null" : fieldOperation);
|
|
4960
4686
|
const [internalValue, setInternalValue] = useState(fieldValue);
|
|
4961
|
-
const isNullOperation = operation === "is-null";
|
|
4687
|
+
const isNullOperation = operation === "is-null" || operation === "is-not-null";
|
|
4688
|
+
if (possibleOperations.length === 0) return null;
|
|
4962
4689
|
function updateFilter(op, val) {
|
|
4963
|
-
if (op === "is-null") {
|
|
4690
|
+
if (op === "is-null" || op === "is-not-null") {
|
|
4964
4691
|
setOperation(op);
|
|
4965
4692
|
setInternalValue(null);
|
|
4966
|
-
setValue([
|
|
4693
|
+
setValue([op, null]);
|
|
4967
4694
|
return;
|
|
4968
4695
|
}
|
|
4969
4696
|
let newValue = val;
|
|
4970
|
-
const prevOpIsArray = multipleSelectOperations$
|
|
4971
|
-
const newOpIsArray = multipleSelectOperations$
|
|
4697
|
+
const prevOpIsArray = multipleSelectOperations$2.includes(operation);
|
|
4698
|
+
const newOpIsArray = multipleSelectOperations$2.includes(op);
|
|
4972
4699
|
if (prevOpIsArray !== newOpIsArray) newValue = newOpIsArray ? val ? [val] : [] : void 0;
|
|
4973
4700
|
setOperation(op);
|
|
4974
4701
|
setInternalValue(Array.isArray(newValue) ? newValue[0] ?? null : newValue);
|
|
@@ -4987,10 +4714,10 @@ function DateTimeFilterField({ name, isArray, mode, value, setValue, title, time
|
|
|
4987
4714
|
onValueChange: (value) => {
|
|
4988
4715
|
updateFilter(value, internalValue);
|
|
4989
4716
|
},
|
|
4990
|
-
renderValue: (op) => operationLabels$
|
|
4717
|
+
renderValue: (op) => operationLabels$2[op],
|
|
4991
4718
|
children: possibleOperations.map((op) => /* @__PURE__ */ jsx(SelectItem, {
|
|
4992
4719
|
value: op,
|
|
4993
|
-
children: operationLabels$
|
|
4720
|
+
children: operationLabels$2[op]
|
|
4994
4721
|
}, op))
|
|
4995
4722
|
})
|
|
4996
4723
|
}), /* @__PURE__ */ jsx("div", {
|
|
@@ -5011,6 +4738,140 @@ function DateTimeFilterField({ name, isArray, mode, value, setValue, title, time
|
|
|
5011
4738
|
});
|
|
5012
4739
|
}
|
|
5013
4740
|
//#endregion
|
|
4741
|
+
//#region src/components/SelectableTable/filters/ReferenceFilterField.tsx
|
|
4742
|
+
var operationLabels$1 = {
|
|
4743
|
+
"==": "==",
|
|
4744
|
+
"!=": "!=",
|
|
4745
|
+
">": ">",
|
|
4746
|
+
"<": "<",
|
|
4747
|
+
">=": ">=",
|
|
4748
|
+
"<=": "<=",
|
|
4749
|
+
in: "In",
|
|
4750
|
+
"not-in": "Not in",
|
|
4751
|
+
"array-contains": "Contains",
|
|
4752
|
+
"array-contains-any": "Contains Any"
|
|
4753
|
+
};
|
|
4754
|
+
var multipleSelectOperations$1 = [
|
|
4755
|
+
"array-contains-any",
|
|
4756
|
+
"in",
|
|
4757
|
+
"not-in"
|
|
4758
|
+
];
|
|
4759
|
+
function ReferenceFilterField({ value, setValue, isArray, path, includeId = true, previewProperties, setHidden, operators }) {
|
|
4760
|
+
const { t } = useTranslation();
|
|
4761
|
+
let possibleOperations = isArray ? ["array-contains"] : [
|
|
4762
|
+
"==",
|
|
4763
|
+
"!=",
|
|
4764
|
+
">",
|
|
4765
|
+
"<",
|
|
4766
|
+
">=",
|
|
4767
|
+
"<="
|
|
4768
|
+
];
|
|
4769
|
+
if (isArray) possibleOperations.push("array-contains-any");
|
|
4770
|
+
else possibleOperations.push("in", "not-in");
|
|
4771
|
+
if (operators) possibleOperations = possibleOperations.filter((op) => operators.includes(op));
|
|
4772
|
+
const [fieldOperation, fieldValue] = value || [possibleOperations[0], void 0];
|
|
4773
|
+
const [operation, setOperation] = useState(fieldOperation);
|
|
4774
|
+
const [internalValue, setInternalValue] = useState(fieldValue);
|
|
4775
|
+
const selectedEntityIds = internalValue ? Array.isArray(internalValue) ? internalValue.map((ref) => {
|
|
4776
|
+
if (!(ref?.isEntityReference && ref?.isEntityReference())) return null;
|
|
4777
|
+
return ref.id;
|
|
4778
|
+
}).filter(Boolean) : [internalValue.id] : [];
|
|
4779
|
+
function updateFilter(op, val) {
|
|
4780
|
+
const prevOpIsArray = multipleSelectOperations$1.includes(operation);
|
|
4781
|
+
const newOpIsArray = multipleSelectOperations$1.includes(op);
|
|
4782
|
+
let newValue = val;
|
|
4783
|
+
if (prevOpIsArray !== newOpIsArray) newValue = newOpIsArray ? newValue && !Array.isArray(newValue) && newValue.isEntityReference?.() ? [newValue] : [] : void 0;
|
|
4784
|
+
setOperation(op);
|
|
4785
|
+
setInternalValue(newValue);
|
|
4786
|
+
const hasNewValue = newValue !== null && Array.isArray(newValue) ? newValue.length > 0 : newValue !== void 0;
|
|
4787
|
+
if (op && hasNewValue) setValue([op, newValue]);
|
|
4788
|
+
else setValue(void 0);
|
|
4789
|
+
}
|
|
4790
|
+
const collectionRegistryController = useCollectionRegistryController();
|
|
4791
|
+
const collection = useMemo(() => {
|
|
4792
|
+
return path ? collectionRegistryController.getCollection(path) : void 0;
|
|
4793
|
+
}, [path]);
|
|
4794
|
+
const onSingleEntitySelected = (entity) => {
|
|
4795
|
+
updateFilter(operation, getReferenceFrom(entity));
|
|
4796
|
+
};
|
|
4797
|
+
const onMultipleEntitiesSelected = (entities) => {
|
|
4798
|
+
updateFilter(operation, entities.map((e) => getReferenceFrom(e)));
|
|
4799
|
+
};
|
|
4800
|
+
const multiple = multipleSelectOperations$1.includes(operation);
|
|
4801
|
+
const referenceDialogController = useSelectionDialog({
|
|
4802
|
+
multiselect: multiple,
|
|
4803
|
+
path,
|
|
4804
|
+
collection,
|
|
4805
|
+
onSingleEntitySelected,
|
|
4806
|
+
onMultipleEntitiesSelected,
|
|
4807
|
+
selectedEntityIds,
|
|
4808
|
+
onClose: () => {
|
|
4809
|
+
setHidden(false);
|
|
4810
|
+
}
|
|
4811
|
+
});
|
|
4812
|
+
const doOpenDialog = () => {
|
|
4813
|
+
setHidden(true);
|
|
4814
|
+
referenceDialogController.open();
|
|
4815
|
+
};
|
|
4816
|
+
const buildEntry = (reference) => {
|
|
4817
|
+
return /* @__PURE__ */ jsx(ReferencePreview, {
|
|
4818
|
+
disabled: !path,
|
|
4819
|
+
previewProperties,
|
|
4820
|
+
size: "medium",
|
|
4821
|
+
onClick: doOpenDialog,
|
|
4822
|
+
reference,
|
|
4823
|
+
hover: true,
|
|
4824
|
+
includeId,
|
|
4825
|
+
includeEntityLink: false
|
|
4826
|
+
});
|
|
4827
|
+
};
|
|
4828
|
+
if (possibleOperations.length === 0) return null;
|
|
4829
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
4830
|
+
className: "flex w-full flex-row",
|
|
4831
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
4832
|
+
className: "w-[100px]",
|
|
4833
|
+
children: /* @__PURE__ */ jsx(Select, {
|
|
4834
|
+
value: operation,
|
|
4835
|
+
size: "medium",
|
|
4836
|
+
fullWidth: true,
|
|
4837
|
+
onValueChange: (value) => {
|
|
4838
|
+
updateFilter(value, internalValue);
|
|
4839
|
+
},
|
|
4840
|
+
renderValue: (op) => operationLabels$1[op],
|
|
4841
|
+
children: possibleOperations.map((op) => /* @__PURE__ */ jsx(SelectItem, {
|
|
4842
|
+
value: op,
|
|
4843
|
+
children: operationLabels$1[op]
|
|
4844
|
+
}, op))
|
|
4845
|
+
})
|
|
4846
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
4847
|
+
className: "grow ml-2 h-full gap-2 flex flex-col",
|
|
4848
|
+
children: [
|
|
4849
|
+
internalValue && Array.isArray(internalValue) && /* @__PURE__ */ jsx("div", { children: internalValue.map((ref, index) => buildEntry(ref)) }),
|
|
4850
|
+
internalValue && !Array.isArray(internalValue) && /* @__PURE__ */ jsx("div", { children: buildEntry(internalValue) }),
|
|
4851
|
+
(!internalValue || Array.isArray(internalValue) && internalValue.length === 0) && /* @__PURE__ */ jsx(Button, {
|
|
4852
|
+
onClick: doOpenDialog,
|
|
4853
|
+
size: "medium",
|
|
4854
|
+
className: "h-full w-full",
|
|
4855
|
+
children: multiple ? t("select_references") : t("select_reference")
|
|
4856
|
+
}),
|
|
4857
|
+
!isArray && /* @__PURE__ */ jsxs(Label, {
|
|
4858
|
+
className: "border cursor-pointer rounded-md p-2 flex items-center gap-2 bg-surface-50 dark:bg-surface-900 hover:bg-surface-100 dark:hover:bg-surface-800",
|
|
4859
|
+
htmlFor: "null-filter",
|
|
4860
|
+
children: [/* @__PURE__ */ jsx(Checkbox, {
|
|
4861
|
+
id: "null-filter",
|
|
4862
|
+
checked: internalValue === null,
|
|
4863
|
+
size: "small",
|
|
4864
|
+
onCheckedChange: (checked) => {
|
|
4865
|
+
if (internalValue !== null) updateFilter(operation, null);
|
|
4866
|
+
else updateFilter(operation, void 0);
|
|
4867
|
+
}
|
|
4868
|
+
}), t("filter_for_null_values")]
|
|
4869
|
+
})
|
|
4870
|
+
]
|
|
4871
|
+
})]
|
|
4872
|
+
});
|
|
4873
|
+
}
|
|
4874
|
+
//#endregion
|
|
5014
4875
|
//#region src/components/SelectableTable/filters/RelationFilterField.tsx
|
|
5015
4876
|
var operationLabels = {
|
|
5016
4877
|
"==": "==",
|
|
@@ -5029,9 +4890,9 @@ var multipleSelectOperations = [
|
|
|
5029
4890
|
"in",
|
|
5030
4891
|
"not-in"
|
|
5031
4892
|
];
|
|
5032
|
-
function RelationFilterField({ value, setValue, relation, name: _name, hidden: _hidden, setHidden: _setHidden }) {
|
|
4893
|
+
function RelationFilterField({ value, setValue, relation, name: _name, hidden: _hidden, setHidden: _setHidden, operators }) {
|
|
5033
4894
|
const manyRelation = relation.cardinality === "many";
|
|
5034
|
-
|
|
4895
|
+
let possibleOperations = manyRelation ? ["array-contains", "array-contains-any"] : [
|
|
5035
4896
|
"==",
|
|
5036
4897
|
"!=",
|
|
5037
4898
|
">",
|
|
@@ -5041,6 +4902,7 @@ function RelationFilterField({ value, setValue, relation, name: _name, hidden: _
|
|
|
5041
4902
|
"in",
|
|
5042
4903
|
"not-in"
|
|
5043
4904
|
];
|
|
4905
|
+
if (operators) possibleOperations = possibleOperations.filter((op) => operators.includes(op));
|
|
5044
4906
|
const [fieldOperation, fieldValue] = value || [possibleOperations[0], void 0];
|
|
5045
4907
|
const [operation, setOperation] = useState(fieldOperation);
|
|
5046
4908
|
const [internalValue, setInternalValue] = useState(fieldValue);
|
|
@@ -5072,6 +4934,7 @@ function RelationFilterField({ value, setValue, relation, name: _name, hidden: _
|
|
|
5072
4934
|
}
|
|
5073
4935
|
updateFilter(operation, newVal);
|
|
5074
4936
|
};
|
|
4937
|
+
if (possibleOperations.length === 0) return null;
|
|
5075
4938
|
return /* @__PURE__ */ jsxs("div", {
|
|
5076
4939
|
className: "flex flex-row",
|
|
5077
4940
|
children: [/* @__PURE__ */ jsx("div", {
|
|
@@ -5113,28 +4976,146 @@ function RelationFilterField({ value, setValue, relation, name: _name, hidden: _
|
|
|
5113
4976
|
});
|
|
5114
4977
|
}
|
|
5115
4978
|
//#endregion
|
|
4979
|
+
//#region src/components/SelectableTable/filters/FilterFieldBinding.tsx
|
|
4980
|
+
/**
|
|
4981
|
+
* The single entry point for rendering a collection filter field.
|
|
4982
|
+
* Used by both the table header filters ({@link SelectableTable}) and the
|
|
4983
|
+
* Filters dialog.
|
|
4984
|
+
*
|
|
4985
|
+
* Resolution order:
|
|
4986
|
+
* 1. `property.ui.Filter` — per-property replacement (rendered even when the
|
|
4987
|
+
* resolved operator list is empty; the component owns filterability).
|
|
4988
|
+
* 2. `components["Collection.FilterField"]` — collection-level or app-level
|
|
4989
|
+
* override (wrap mode supported via `OriginalComponent`).
|
|
4990
|
+
* 3. Built-in field dispatched by property type.
|
|
4991
|
+
*
|
|
4992
|
+
* The operators handed to the field are the intersection of the engine's
|
|
4993
|
+
* capabilities, the property-type defaults, and `property.ui.filterOperators`
|
|
4994
|
+
* (see `resolveFilterOperators`). When that intersection is empty and no
|
|
4995
|
+
* per-property `Filter` is set, nothing is rendered.
|
|
4996
|
+
*
|
|
4997
|
+
* @group Components
|
|
4998
|
+
*/
|
|
4999
|
+
function FilterFieldBinding({ propertyKey, property, engine, value, setValue, hidden, setHidden }) {
|
|
5000
|
+
const isArray = property.type === "array";
|
|
5001
|
+
const ofVal = isArray ? property.of : void 0;
|
|
5002
|
+
const baseProperty = isArray ? Array.isArray(ofVal) ? ofVal[0] : ofVal : property;
|
|
5003
|
+
const scopeCollection = useCollectionScope();
|
|
5004
|
+
const ResolvedFilterField = useComponentOverride("Collection.FilterField", DefaultFilterField);
|
|
5005
|
+
const PropertyFilter = useResolvedComponent(baseProperty?.ui?.Filter);
|
|
5006
|
+
if (!baseProperty) return null;
|
|
5007
|
+
const operators = resolveFilterOperators({
|
|
5008
|
+
property: baseProperty,
|
|
5009
|
+
isArray,
|
|
5010
|
+
engine: engine ?? scopeCollection?.engine
|
|
5011
|
+
});
|
|
5012
|
+
const bindingProps = {
|
|
5013
|
+
propertyKey,
|
|
5014
|
+
property: baseProperty,
|
|
5015
|
+
isArray,
|
|
5016
|
+
operators,
|
|
5017
|
+
value,
|
|
5018
|
+
setValue,
|
|
5019
|
+
title: property.name,
|
|
5020
|
+
hidden,
|
|
5021
|
+
setHidden
|
|
5022
|
+
};
|
|
5023
|
+
if (PropertyFilter) return /* @__PURE__ */ jsx(Suspense, {
|
|
5024
|
+
fallback: null,
|
|
5025
|
+
children: /* @__PURE__ */ jsx(PropertyFilter, { ...bindingProps })
|
|
5026
|
+
});
|
|
5027
|
+
if (operators.length === 0) return null;
|
|
5028
|
+
return /* @__PURE__ */ jsx(ResolvedFilterField, { ...bindingProps });
|
|
5029
|
+
}
|
|
5030
|
+
/**
|
|
5031
|
+
* Built-in filter field dispatch by property type. This is the
|
|
5032
|
+
* `OriginalComponent` received by `"Collection.FilterField"` overrides in
|
|
5033
|
+
* wrap mode.
|
|
5034
|
+
*/
|
|
5035
|
+
function DefaultFilterField({ propertyKey, property, isArray, operators, value, setValue, title, hidden, setHidden }) {
|
|
5036
|
+
if (property.type === "reference") {
|
|
5037
|
+
const referenceProperty = property;
|
|
5038
|
+
return /* @__PURE__ */ jsx(ReferenceFilterField, {
|
|
5039
|
+
value,
|
|
5040
|
+
setValue,
|
|
5041
|
+
name: propertyKey,
|
|
5042
|
+
isArray,
|
|
5043
|
+
operators,
|
|
5044
|
+
path: referenceProperty.path,
|
|
5045
|
+
title,
|
|
5046
|
+
includeId: referenceProperty.includeId,
|
|
5047
|
+
previewProperties: referenceProperty.ui?.previewProperties,
|
|
5048
|
+
hidden: hidden ?? false,
|
|
5049
|
+
setHidden: setHidden ?? (() => void 0)
|
|
5050
|
+
});
|
|
5051
|
+
}
|
|
5052
|
+
if (property.type === "relation") {
|
|
5053
|
+
const relation = property.relation;
|
|
5054
|
+
if (!relation) return null;
|
|
5055
|
+
return /* @__PURE__ */ jsx(RelationFilterField, {
|
|
5056
|
+
value,
|
|
5057
|
+
setValue,
|
|
5058
|
+
name: propertyKey,
|
|
5059
|
+
operators,
|
|
5060
|
+
relation,
|
|
5061
|
+
hidden: hidden ?? false,
|
|
5062
|
+
setHidden: setHidden ?? (() => void 0)
|
|
5063
|
+
});
|
|
5064
|
+
}
|
|
5065
|
+
if (property.type === "number" || property.type === "string") {
|
|
5066
|
+
const enumValues = property.enum ? enumToObjectEntries(property.enum) : void 0;
|
|
5067
|
+
return /* @__PURE__ */ jsx(StringNumberFilterField, {
|
|
5068
|
+
value,
|
|
5069
|
+
setValue,
|
|
5070
|
+
name: propertyKey,
|
|
5071
|
+
type: property.type,
|
|
5072
|
+
isArray,
|
|
5073
|
+
operators,
|
|
5074
|
+
enumValues,
|
|
5075
|
+
title
|
|
5076
|
+
});
|
|
5077
|
+
}
|
|
5078
|
+
if (property.type === "boolean") return /* @__PURE__ */ jsx(BooleanFilterField, {
|
|
5079
|
+
value,
|
|
5080
|
+
setValue,
|
|
5081
|
+
name: propertyKey,
|
|
5082
|
+
operators,
|
|
5083
|
+
title
|
|
5084
|
+
});
|
|
5085
|
+
if (property.type === "date") return /* @__PURE__ */ jsx(DateTimeFilterField, {
|
|
5086
|
+
value,
|
|
5087
|
+
setValue,
|
|
5088
|
+
name: propertyKey,
|
|
5089
|
+
mode: property.mode,
|
|
5090
|
+
isArray,
|
|
5091
|
+
operators,
|
|
5092
|
+
title
|
|
5093
|
+
});
|
|
5094
|
+
return null;
|
|
5095
|
+
}
|
|
5096
|
+
//#endregion
|
|
5116
5097
|
//#region src/components/SelectableTable/SelectableTable.tsx
|
|
5117
5098
|
/**
|
|
5118
5099
|
* This component is in charge of rendering a collection table with a high
|
|
5119
5100
|
* degree of customization.
|
|
5120
5101
|
*
|
|
5121
|
-
* This component is used internally by {@link
|
|
5102
|
+
* This component is used internally by {@link CollectionViewBinding} and
|
|
5122
5103
|
* {@link useReferenceDialog}
|
|
5123
5104
|
*
|
|
5124
5105
|
* Please note that you only need to use this component if you are building
|
|
5125
5106
|
* a custom view. If you just need to create a default view you can do it
|
|
5126
5107
|
* exclusively with config options.
|
|
5127
5108
|
*
|
|
5128
|
-
* If you want to bind a {@link
|
|
5109
|
+
* If you want to bind a {@link CollectionConfig} to a table with the default
|
|
5129
5110
|
* options you see in collections in the top level navigation, you can
|
|
5130
|
-
* check {@link
|
|
5111
|
+
* check {@link CollectionViewBinding}.
|
|
5131
5112
|
*
|
|
5132
5113
|
* The data displayed in the table is managed by a {@link EntityTableController}.
|
|
5133
5114
|
* You can build the default, bound to a path in the driver, by using the hook
|
|
5134
5115
|
* {@link useDataTableController}
|
|
5135
5116
|
*
|
|
5136
|
-
* @see
|
|
5137
|
-
* @see
|
|
5117
|
+
* @see CollectionTableBindingProps
|
|
5118
|
+
* @see CollectionViewBinding
|
|
5138
5119
|
* @see VirtualTable
|
|
5139
5120
|
* @group Components
|
|
5140
5121
|
*/
|
|
@@ -5162,7 +5143,12 @@ var SelectableTable = function SelectableTable({ onValueChange, cellRenderer, on
|
|
|
5162
5143
|
}, [onEntityClick, inlineEditing]);
|
|
5163
5144
|
const select = useCallback((cell) => {
|
|
5164
5145
|
setLocalSelectedCell(cell);
|
|
5165
|
-
selectionStore.select(
|
|
5146
|
+
if (cell) selectionStore.select({
|
|
5147
|
+
...cell,
|
|
5148
|
+
columnKey: cell.propertyKey,
|
|
5149
|
+
id: cell.entityId
|
|
5150
|
+
});
|
|
5151
|
+
else selectionStore.select(void 0);
|
|
5166
5152
|
}, [selectionStore]);
|
|
5167
5153
|
const unselect = useCallback(() => {
|
|
5168
5154
|
setLocalSelectedCell(void 0);
|
|
@@ -5199,6 +5185,19 @@ var SelectableTable = function SelectableTable({ onValueChange, cellRenderer, on
|
|
|
5199
5185
|
size,
|
|
5200
5186
|
selectionStore
|
|
5201
5187
|
]);
|
|
5188
|
+
const createFilterField = useCallback(({ id, filterValue, setFilterValue, column, hidden, setHidden }) => {
|
|
5189
|
+
if (!column.custom) return null;
|
|
5190
|
+
const { resolvedProperty } = column.custom;
|
|
5191
|
+
if (!resolvedProperty) return null;
|
|
5192
|
+
return /* @__PURE__ */ jsx(FilterFieldBinding, {
|
|
5193
|
+
propertyKey: id,
|
|
5194
|
+
property: resolvedProperty,
|
|
5195
|
+
value: filterValue,
|
|
5196
|
+
setValue: setFilterValue,
|
|
5197
|
+
hidden,
|
|
5198
|
+
setHidden
|
|
5199
|
+
});
|
|
5200
|
+
}, []);
|
|
5202
5201
|
return /* @__PURE__ */ jsx(SelectableTableContext.Provider, {
|
|
5203
5202
|
value: contextValue,
|
|
5204
5203
|
children: /* @__PURE__ */ jsx("div", {
|
|
@@ -5237,93 +5236,33 @@ var SelectableTable = function SelectableTable({ onValueChange, cellRenderer, on
|
|
|
5237
5236
|
})
|
|
5238
5237
|
});
|
|
5239
5238
|
};
|
|
5240
|
-
function createFilterField({ id, filterValue, setFilterValue, column, hidden, setHidden }) {
|
|
5241
|
-
if (!column.custom) return null;
|
|
5242
|
-
const { resolvedProperty } = column.custom;
|
|
5243
|
-
const isArray = resolvedProperty?.type === "array";
|
|
5244
|
-
const ofVal = isArray && resolvedProperty ? resolvedProperty.of : void 0;
|
|
5245
|
-
const baseProperty = isArray ? Array.isArray(ofVal) ? ofVal[0] : ofVal : resolvedProperty;
|
|
5246
|
-
if (!baseProperty) return null;
|
|
5247
|
-
if (baseProperty.type === "reference") return /* @__PURE__ */ jsx(ReferenceFilterField, {
|
|
5248
|
-
value: filterValue,
|
|
5249
|
-
setValue: setFilterValue,
|
|
5250
|
-
name: id,
|
|
5251
|
-
isArray,
|
|
5252
|
-
path: baseProperty.path,
|
|
5253
|
-
title: resolvedProperty?.name,
|
|
5254
|
-
includeId: baseProperty.includeId,
|
|
5255
|
-
previewProperties: baseProperty?.ui?.previewProperties,
|
|
5256
|
-
hidden,
|
|
5257
|
-
setHidden
|
|
5258
|
-
});
|
|
5259
|
-
else if (baseProperty.type === "relation" && baseProperty.relation) return /* @__PURE__ */ jsx(RelationFilterField, {
|
|
5260
|
-
value: filterValue,
|
|
5261
|
-
setValue: setFilterValue,
|
|
5262
|
-
name: id,
|
|
5263
|
-
relation: baseProperty.relation,
|
|
5264
|
-
hidden,
|
|
5265
|
-
setHidden
|
|
5266
|
-
});
|
|
5267
|
-
else if (baseProperty.type === "number" || baseProperty.type === "string") {
|
|
5268
|
-
const name = baseProperty.name;
|
|
5269
|
-
const enumValues = baseProperty.enum ? enumToObjectEntries(baseProperty.enum) : void 0;
|
|
5270
|
-
return /* @__PURE__ */ jsx(StringNumberFilterField, {
|
|
5271
|
-
value: filterValue,
|
|
5272
|
-
setValue: setFilterValue,
|
|
5273
|
-
name: id,
|
|
5274
|
-
type: baseProperty.type,
|
|
5275
|
-
isArray,
|
|
5276
|
-
enumValues,
|
|
5277
|
-
title: name
|
|
5278
|
-
});
|
|
5279
|
-
} else if (baseProperty.type === "boolean") {
|
|
5280
|
-
const name = baseProperty.name;
|
|
5281
|
-
return /* @__PURE__ */ jsx(BooleanFilterField, {
|
|
5282
|
-
value: filterValue,
|
|
5283
|
-
setValue: setFilterValue,
|
|
5284
|
-
name: id,
|
|
5285
|
-
title: name
|
|
5286
|
-
});
|
|
5287
|
-
} else if (baseProperty.type === "date") {
|
|
5288
|
-
const title = baseProperty.name;
|
|
5289
|
-
return /* @__PURE__ */ jsx(DateTimeFilterField, {
|
|
5290
|
-
value: filterValue,
|
|
5291
|
-
setValue: setFilterValue,
|
|
5292
|
-
name: id,
|
|
5293
|
-
mode: baseProperty.mode,
|
|
5294
|
-
isArray,
|
|
5295
|
-
title
|
|
5296
|
-
});
|
|
5297
|
-
}
|
|
5298
|
-
return /* @__PURE__ */ jsx("div", { children: `Currently the filter field ${resolvedProperty?.type} is not supported` });
|
|
5299
|
-
}
|
|
5300
5239
|
//#endregion
|
|
5301
|
-
//#region src/components/
|
|
5240
|
+
//#region src/components/CollectionTableBinding/CollectionTableBinding.tsx
|
|
5302
5241
|
/**
|
|
5303
5242
|
* This component is in charge of rendering a collection table with a high
|
|
5304
5243
|
* degree of customization.
|
|
5305
5244
|
*
|
|
5306
|
-
* This component is used internally by {@link
|
|
5245
|
+
* This component is used internally by {@link CollectionViewBinding} and
|
|
5307
5246
|
* {@link useReferenceDialog}
|
|
5308
5247
|
*
|
|
5309
5248
|
* Please note that you only need to use this component if you are building
|
|
5310
5249
|
* a custom view. If you just need to create a default view you can do it
|
|
5311
5250
|
* exclusively with config options.
|
|
5312
5251
|
*
|
|
5313
|
-
* If you want to bind a {@link
|
|
5252
|
+
* If you want to bind a {@link CollectionConfig} to a table with the default
|
|
5314
5253
|
* options you see in collections in the top level navigation, you can
|
|
5315
|
-
* check {@link
|
|
5254
|
+
* check {@link CollectionViewBinding}.
|
|
5316
5255
|
*
|
|
5317
5256
|
* The data displayed in the table is managed by a {@link EntityTableController}.
|
|
5318
5257
|
* You can build the default, bound to a path in the driver, by using the hook
|
|
5319
5258
|
* {@link useDataTableController}
|
|
5320
5259
|
*
|
|
5321
|
-
* @see
|
|
5322
|
-
* @see
|
|
5260
|
+
* @see CollectionTableBindingProps
|
|
5261
|
+
* @see CollectionViewBinding
|
|
5323
5262
|
* @see VirtualTable
|
|
5324
5263
|
* @group Components
|
|
5325
5264
|
*/
|
|
5326
|
-
var
|
|
5265
|
+
var CollectionTableBinding = function CollectionTableBinding({ className, style, fixedFilter, actionsStart, actions, viewModeToggle, title, tableRowActionsBuilder, uniqueFieldValidator, getPropertyFor, onValueChange, selectionController, highlightedEntities, onEntityClick, onColumnResize, initialScroll, onScroll, onSizeChanged, hoverRow = true, inlineEditing = false, additionalFields, displayedColumnIds, defaultSize, properties, tableController, filterable = true, sortable = true, endAdornment, AddColumnComponent, AdditionalHeaderWidget, additionalIDHeaderWidget, emptyComponent, getIdColumnWidth, enablePopupIcon, openEntityMode = "side_panel", onColumnsOrderChange, hideToolbar = false }) {
|
|
5327
5266
|
const ref = useRef(null);
|
|
5328
5267
|
const largeLayout = useLargeLayout();
|
|
5329
5268
|
const selectedEntities = useMemo(() => {
|
|
@@ -5348,6 +5287,7 @@ var EntityCollectionTable = function EntityCollectionTable({ className, style, f
|
|
|
5348
5287
|
const customFieldValidator = uniqueFieldValidator;
|
|
5349
5288
|
const propertyCellRenderer = useCallback(({ column, columnIndex, rowData, rowIndex, sortableNodeRef, sortableStyle, sortableAttributes, isDragging, isDraggable, frozen }) => {
|
|
5350
5289
|
const entity = rowData;
|
|
5290
|
+
if (!entity) return null;
|
|
5351
5291
|
const propertyKey = column.key;
|
|
5352
5292
|
const columnCustom = column.custom;
|
|
5353
5293
|
let disabled = columnCustom?.disabled ?? false;
|
|
@@ -5387,6 +5327,7 @@ var EntityCollectionTable = function EntityCollectionTable({ className, style, f
|
|
|
5387
5327
|
]);
|
|
5388
5328
|
const additionalCellRenderer = useCallback(({ column, rowData, width, sortableNodeRef, sortableStyle, sortableAttributes, isDragging, isDraggable, frozen }) => {
|
|
5389
5329
|
const entity = rowData;
|
|
5330
|
+
if (!entity) return null;
|
|
5390
5331
|
const additionalField = additionalFieldsMap[column.key];
|
|
5391
5332
|
const value = additionalField.dependencies ? Object.entries(entity.values).filter(([key, value]) => additionalField.dependencies.includes(key)).reduce((a, b) => ({
|
|
5392
5333
|
...a,
|
|
@@ -5474,7 +5415,7 @@ var EntityCollectionTable = function EntityCollectionTable({ className, style, f
|
|
|
5474
5415
|
width: column.width,
|
|
5475
5416
|
frozen: column.frozen
|
|
5476
5417
|
});
|
|
5477
|
-
else return /* @__PURE__ */ jsx(
|
|
5418
|
+
else return /* @__PURE__ */ jsx(CollectionRowActions, {
|
|
5478
5419
|
entity: props.rowData,
|
|
5479
5420
|
width: column.width,
|
|
5480
5421
|
frozen: column.frozen,
|
|
@@ -5549,7 +5490,7 @@ var EntityCollectionTable = function EntityCollectionTable({ className, style, f
|
|
|
5549
5490
|
});
|
|
5550
5491
|
};
|
|
5551
5492
|
//#endregion
|
|
5552
|
-
//#region src/components/
|
|
5493
|
+
//#region src/components/CollectionViewBinding/useSelectionController.tsx
|
|
5553
5494
|
function useSelectionController(onSelectionChange) {
|
|
5554
5495
|
const [selectedEntities, setSelectedEntities] = useState([]);
|
|
5555
5496
|
const onSelectionChangeRef = useRef(onSelectionChange);
|
|
@@ -5608,11 +5549,11 @@ function mergeEntityActions(currentActions, newActions) {
|
|
|
5608
5549
|
return updatedActions;
|
|
5609
5550
|
}
|
|
5610
5551
|
//#endregion
|
|
5611
|
-
//#region src/components/
|
|
5612
|
-
function
|
|
5552
|
+
//#region src/components/EditFormActions.tsx
|
|
5553
|
+
function EditFormActions({ collection, path, entity, layout, savingError, formex, disabled, status, pluginActions, openEntityMode, showDefaultActions = true, navigateBack, formContext }) {
|
|
5613
5554
|
const { canCreate, canDelete } = usePermissions();
|
|
5614
5555
|
const context = useCMSContext();
|
|
5615
|
-
const
|
|
5556
|
+
const sidePanelController = context.sidePanelController;
|
|
5616
5557
|
const sideDialogContext = useSideDialogContext();
|
|
5617
5558
|
const customizationController = useCustomizationController();
|
|
5618
5559
|
const { t } = useTranslation();
|
|
@@ -5642,7 +5583,7 @@ function EntityEditViewFormActions({ collection, path, entity, layout, savingErr
|
|
|
5642
5583
|
formActions,
|
|
5643
5584
|
collection,
|
|
5644
5585
|
context,
|
|
5645
|
-
|
|
5586
|
+
sidePanelController,
|
|
5646
5587
|
disabled,
|
|
5647
5588
|
status,
|
|
5648
5589
|
sideDialogContext,
|
|
@@ -5660,7 +5601,7 @@ function EntityEditViewFormActions({ collection, path, entity, layout, savingErr
|
|
|
5660
5601
|
formActions,
|
|
5661
5602
|
collection,
|
|
5662
5603
|
context,
|
|
5663
|
-
|
|
5604
|
+
sidePanelController,
|
|
5664
5605
|
sideDialogContext,
|
|
5665
5606
|
disabled,
|
|
5666
5607
|
status,
|
|
@@ -5675,7 +5616,7 @@ function EntityEditViewFormActions({ collection, path, entity, layout, savingErr
|
|
|
5675
5616
|
if (layout === "responsive") return /* @__PURE__ */ jsxs(Fragment, { children: [bottomActions, sideActions] });
|
|
5676
5617
|
return layout === "bottom" ? bottomActions : sideActions;
|
|
5677
5618
|
}
|
|
5678
|
-
function buildBottomActions({ savingError, entity, formActions, collection, context,
|
|
5619
|
+
function buildBottomActions({ savingError, entity, formActions, collection, context, sidePanelController, disabled, status, sideDialogContext, pluginActions, openEntityMode, navigateBack, formContext, formex, t, className }) {
|
|
5679
5620
|
const hasErrors = Object.keys(formex.errors).length > 0 && formex.submitCount > 0;
|
|
5680
5621
|
const canClose = openEntityMode === "side_panel" || openEntityMode === "dialog";
|
|
5681
5622
|
return /* @__PURE__ */ jsxs(DialogActions, {
|
|
@@ -5695,10 +5636,10 @@ function buildBottomActions({ savingError, entity, formActions, collection, cont
|
|
|
5695
5636
|
const props = {
|
|
5696
5637
|
view: "form",
|
|
5697
5638
|
entity,
|
|
5698
|
-
path: collection
|
|
5639
|
+
path: getCollectionDataPath(collection),
|
|
5699
5640
|
collection,
|
|
5700
5641
|
context,
|
|
5701
|
-
|
|
5642
|
+
sidePanelController,
|
|
5702
5643
|
openEntityMode,
|
|
5703
5644
|
navigateBack,
|
|
5704
5645
|
formContext
|
|
@@ -5767,7 +5708,7 @@ function buildBottomActions({ savingError, entity, formActions, collection, cont
|
|
|
5767
5708
|
]
|
|
5768
5709
|
});
|
|
5769
5710
|
}
|
|
5770
|
-
function buildSideActions({ savingError, entity, formActions, collection, context,
|
|
5711
|
+
function buildSideActions({ savingError, entity, formActions, collection, context, sidePanelController, disabled, status, sideDialogContext, pluginActions, openEntityMode, navigateBack, formContext, formex, t, className }) {
|
|
5771
5712
|
const hasErrors = Object.keys(formex.errors).length > 0 && formex.submitCount > 0;
|
|
5772
5713
|
return /* @__PURE__ */ jsxs("div", {
|
|
5773
5714
|
className: cls("overflow-auto h-full flex flex-col gap-2 w-80 2xl:w-96 px-4 py-16 sticky top-0 border-l", defaultBorderMixin, className),
|
|
@@ -5813,10 +5754,10 @@ function buildSideActions({ savingError, entity, formActions, collection, contex
|
|
|
5813
5754
|
const props = {
|
|
5814
5755
|
view: "form",
|
|
5815
5756
|
entity,
|
|
5816
|
-
path: collection
|
|
5757
|
+
path: getCollectionDataPath(collection),
|
|
5817
5758
|
collection,
|
|
5818
5759
|
context,
|
|
5819
|
-
|
|
5760
|
+
sidePanelController,
|
|
5820
5761
|
openEntityMode,
|
|
5821
5762
|
navigateBack,
|
|
5822
5763
|
formContext
|
|
@@ -5879,14 +5820,14 @@ function EntityActionButton({ action, enabled, props }) {
|
|
|
5879
5820
|
});
|
|
5880
5821
|
}
|
|
5881
5822
|
//#endregion
|
|
5882
|
-
//#region src/components/
|
|
5883
|
-
var EntityHistoryView = lazy(() => import("./history-
|
|
5823
|
+
//#region src/components/EditViewBinding.tsx
|
|
5824
|
+
var EntityHistoryView = lazy(() => import("./history-7X5bON_n.js").then((m) => ({ default: m.EntityHistoryView })));
|
|
5884
5825
|
/**
|
|
5885
5826
|
* This is the default view that is used as the content of a side panel when
|
|
5886
|
-
*
|
|
5827
|
+
* a record is opened.
|
|
5887
5828
|
*/
|
|
5888
|
-
function
|
|
5889
|
-
const { entity, dataLoading, dataLoadingError } =
|
|
5829
|
+
function EditViewBinding({ entityId, ...props }) {
|
|
5830
|
+
const { entity, dataLoading, dataLoadingError } = useFetch({
|
|
5890
5831
|
path: props.path,
|
|
5891
5832
|
entityId,
|
|
5892
5833
|
collection: props.collection,
|
|
@@ -5914,7 +5855,7 @@ function EntityEditView({ entityId, ...props }) {
|
|
|
5914
5855
|
children: "Entity not found"
|
|
5915
5856
|
}) });
|
|
5916
5857
|
}
|
|
5917
|
-
const content = /* @__PURE__ */ jsx(
|
|
5858
|
+
const content = /* @__PURE__ */ jsx(EditViewBindingInner, {
|
|
5918
5859
|
...props,
|
|
5919
5860
|
entityId,
|
|
5920
5861
|
entity,
|
|
@@ -5924,16 +5865,15 @@ function EntityEditView({ entityId, ...props }) {
|
|
|
5924
5865
|
setStatus,
|
|
5925
5866
|
canEdit
|
|
5926
5867
|
});
|
|
5927
|
-
|
|
5928
|
-
|
|
5868
|
+
return /* @__PURE__ */ jsx(CollectionScopeProvider, {
|
|
5869
|
+
collection: props.collection,
|
|
5929
5870
|
children: content
|
|
5930
5871
|
});
|
|
5931
|
-
return content;
|
|
5932
5872
|
}
|
|
5933
|
-
function
|
|
5934
|
-
const ResolvedFormActions = useComponentOverride("
|
|
5873
|
+
function EditViewBindingInner({ path, entityId, selectedTab: selectedTabProp, collection, parentCollectionSlugs, parentEntityIds, onValuesModified, onSaved, onTabChange, navigateBack, entity, initialDirtyValues, dataLoading, layout = "side_panel", barActions, status, setStatus, formProps, canEdit }) {
|
|
5874
|
+
const ResolvedFormActions = useComponentOverride("EditView.FormActions", EditFormActions);
|
|
5935
5875
|
const ResolvedEntityForm = useComponentOverride("Entity.Form", EntityFormBinding);
|
|
5936
|
-
const ResolvedCollectionView = useComponentOverride("Collection.View",
|
|
5876
|
+
const ResolvedCollectionView = useComponentOverride("Collection.View", CollectionViewBinding);
|
|
5937
5877
|
const context = useRebaseContext();
|
|
5938
5878
|
const urlController = useUrlController();
|
|
5939
5879
|
const navigate = useNavigate();
|
|
@@ -6081,7 +6021,7 @@ function EntityEditViewInner({ path, entityId, selectedTab: selectedTabProp, col
|
|
|
6081
6021
|
const jsonView = activeTab === "__json" || jsonTabMounted ? /* @__PURE__ */ jsx("div", {
|
|
6082
6022
|
className: cls("relative flex-1 h-full overflow-auto w-full", { "hidden": activeTab !== JSON_TAB_VALUE }),
|
|
6083
6023
|
role: "tabpanel",
|
|
6084
|
-
children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(
|
|
6024
|
+
children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(JsonPreviewBinding, { values: formContext?.values ?? entity?.values ?? {} }) })
|
|
6085
6025
|
}, "json_view") : null;
|
|
6086
6026
|
const historyView = includeHistoryView && activeTab === "__rebase_history" ? /* @__PURE__ */ jsx("div", {
|
|
6087
6027
|
className: "relative flex-1 h-full overflow-auto w-full",
|
|
@@ -6098,7 +6038,7 @@ function EntityEditViewInner({ path, entityId, selectedTab: selectedTabProp, col
|
|
|
6098
6038
|
}, "history_view") : null;
|
|
6099
6039
|
const subCollectionsViews = subcollections && subcollections.map((subcollection) => {
|
|
6100
6040
|
const subcollectionId = subcollection.slug;
|
|
6101
|
-
const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollection
|
|
6041
|
+
const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(getCollectionDataPath(subcollection))}` : void 0;
|
|
6102
6042
|
if (activeTab !== subcollectionId) return null;
|
|
6103
6043
|
return /* @__PURE__ */ jsxs("div", {
|
|
6104
6044
|
className: "relative flex-1 h-full overflow-auto w-full",
|
|
@@ -6158,7 +6098,7 @@ function EntityEditViewInner({ path, entityId, selectedTab: selectedTabProp, col
|
|
|
6158
6098
|
modifiedValues: usedEntity?.values,
|
|
6159
6099
|
formContext: readOnlyFormContext
|
|
6160
6100
|
})
|
|
6161
|
-
}) }) : /* @__PURE__ */ jsx(
|
|
6101
|
+
}) }) : /* @__PURE__ */ jsx(EntityViewBinding, {
|
|
6162
6102
|
className: "px-8 h-full overflow-auto",
|
|
6163
6103
|
entity,
|
|
6164
6104
|
path,
|
|
@@ -6407,21 +6347,21 @@ function EntityFormSkeleton({ collection }) {
|
|
|
6407
6347
|
});
|
|
6408
6348
|
}
|
|
6409
6349
|
//#endregion
|
|
6410
|
-
//#region src/components/
|
|
6350
|
+
//#region src/components/SidePanelBinding.tsx
|
|
6411
6351
|
/**
|
|
6412
6352
|
* This is the component in charge of rendering the side dialog used
|
|
6413
|
-
* for editing entities. Use the {@link
|
|
6353
|
+
* for editing entities. Use the {@link useSidePanel} to open
|
|
6414
6354
|
* and control the dialogs.
|
|
6415
6355
|
* This component needs a parent {@link Rebase}
|
|
6416
|
-
* {@link
|
|
6356
|
+
* {@link useSidePanel}
|
|
6417
6357
|
* @group Components
|
|
6418
6358
|
*/
|
|
6419
|
-
function
|
|
6359
|
+
function SidePanelBinding(props) {
|
|
6420
6360
|
const { allowFullScreen = true, path, entityId, selectedTab, formProps } = props;
|
|
6421
|
-
const ResolvedDetailView = useComponentOverride("
|
|
6361
|
+
const ResolvedDetailView = useComponentOverride("DetailView", DetailViewBinding);
|
|
6422
6362
|
const { blocked, setBlocked, setBlockedNavigationMessage, close } = useSideDialogContext();
|
|
6423
6363
|
const navigate = useNavigate();
|
|
6424
|
-
const
|
|
6364
|
+
const sidePanelController = useSidePanel();
|
|
6425
6365
|
const collectionRegistryController = useCollectionRegistryController();
|
|
6426
6366
|
const sideDialogsController = useSideDialogContext();
|
|
6427
6367
|
const urlController = useUrlController();
|
|
@@ -6433,7 +6373,7 @@ function EntitySidePanel(props) {
|
|
|
6433
6373
|
const onUpdate = (params) => {
|
|
6434
6374
|
if (props.onUpdate) props.onUpdate(params);
|
|
6435
6375
|
setShowEditInPanel(false);
|
|
6436
|
-
if (params.status !== "existing")
|
|
6376
|
+
if (params.status !== "existing") sidePanelController.replace({
|
|
6437
6377
|
path: params.path,
|
|
6438
6378
|
entityId: params.entityId,
|
|
6439
6379
|
selectedTab: params.selectedTab,
|
|
@@ -6471,7 +6411,7 @@ function EntitySidePanel(props) {
|
|
|
6471
6411
|
});
|
|
6472
6412
|
if (effectiveDefault && effectiveDefault !== "edit") {
|
|
6473
6413
|
hasCorrectedDefaultView.current = true;
|
|
6474
|
-
|
|
6414
|
+
sidePanelController.replace({
|
|
6475
6415
|
path,
|
|
6476
6416
|
entityId,
|
|
6477
6417
|
selectedTab: effectiveDefault,
|
|
@@ -6484,7 +6424,7 @@ function EntitySidePanel(props) {
|
|
|
6484
6424
|
entityId,
|
|
6485
6425
|
collection,
|
|
6486
6426
|
path,
|
|
6487
|
-
|
|
6427
|
+
sidePanelController
|
|
6488
6428
|
]);
|
|
6489
6429
|
const onValuesModified = useCallback((modified) => {
|
|
6490
6430
|
setBlockedNavigationMessage(modified ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -6525,7 +6465,7 @@ function EntitySidePanel(props) {
|
|
|
6525
6465
|
}),
|
|
6526
6466
|
onTabChange: ({ entityId: tabEntityId, selectedTab, collection: paramCollection }) => {
|
|
6527
6467
|
if (collection?.openEntityMode === "dialog" || paramCollection?.openEntityMode === "dialog") return;
|
|
6528
|
-
if (tabEntityId)
|
|
6468
|
+
if (tabEntityId) sidePanelController.replace({
|
|
6529
6469
|
path,
|
|
6530
6470
|
entityId: tabEntityId,
|
|
6531
6471
|
selectedTab,
|
|
@@ -6533,7 +6473,7 @@ function EntitySidePanel(props) {
|
|
|
6533
6473
|
collection: paramCollection ?? collection
|
|
6534
6474
|
});
|
|
6535
6475
|
}
|
|
6536
|
-
}) : /* @__PURE__ */ jsx(
|
|
6476
|
+
}) : /* @__PURE__ */ jsx(EditViewBinding, {
|
|
6537
6477
|
...props,
|
|
6538
6478
|
layout: collection?.openEntityMode === "dialog" ? "dialog" : "side_panel",
|
|
6539
6479
|
collection,
|
|
@@ -6564,7 +6504,7 @@ function EntitySidePanel(props) {
|
|
|
6564
6504
|
}),
|
|
6565
6505
|
onTabChange: ({ entityId: tabEntityId, selectedTab, collection: paramCollection }) => {
|
|
6566
6506
|
if (collection?.openEntityMode === "dialog" || paramCollection?.openEntityMode === "dialog") return;
|
|
6567
|
-
if (tabEntityId)
|
|
6507
|
+
if (tabEntityId) sidePanelController.replace({
|
|
6568
6508
|
path,
|
|
6569
6509
|
entityId: tabEntityId,
|
|
6570
6510
|
selectedTab,
|
|
@@ -6576,22 +6516,22 @@ function EntitySidePanel(props) {
|
|
|
6576
6516
|
}) }) });
|
|
6577
6517
|
}
|
|
6578
6518
|
//#endregion
|
|
6579
|
-
//#region src/hooks/
|
|
6519
|
+
//#region src/hooks/useBuildSidePanel.tsx
|
|
6580
6520
|
/**
|
|
6581
6521
|
* Thin wrapper that resolves the Entity.SidePanel component override.
|
|
6582
6522
|
* Because the JSX is created inside `propsToSidePanel` (a plain function,
|
|
6583
6523
|
* not a React component), we need this wrapper so the hook is called at the
|
|
6584
6524
|
* top level of a React component per the Rules of Hooks.
|
|
6585
6525
|
*/
|
|
6586
|
-
function
|
|
6587
|
-
return /* @__PURE__ */ jsx(useComponentOverride("Entity.SidePanel",
|
|
6526
|
+
function ResolvedSidePanelBindingInner(props) {
|
|
6527
|
+
return /* @__PURE__ */ jsx(useComponentOverride("Entity.SidePanel", SidePanelBinding), { ...props });
|
|
6588
6528
|
}
|
|
6589
|
-
function
|
|
6590
|
-
if (props.collection
|
|
6591
|
-
|
|
6592
|
-
children: /* @__PURE__ */ jsx(
|
|
6529
|
+
function ResolvedSidePanelBinding(props) {
|
|
6530
|
+
if (props.collection) return /* @__PURE__ */ jsx(CollectionScopeProvider, {
|
|
6531
|
+
collection: props.collection,
|
|
6532
|
+
children: /* @__PURE__ */ jsx(ResolvedSidePanelBindingInner, { ...props })
|
|
6593
6533
|
});
|
|
6594
|
-
return /* @__PURE__ */ jsx(
|
|
6534
|
+
return /* @__PURE__ */ jsx(ResolvedSidePanelBindingInner, { ...props });
|
|
6595
6535
|
}
|
|
6596
6536
|
var NEW_URL_HASH = "new_side";
|
|
6597
6537
|
var SIDE_URL_HASH = "side";
|
|
@@ -6629,7 +6569,7 @@ function getNestedPropertiesDepth(property, accumulator = 0) {
|
|
|
6629
6569
|
else return getNestedPropertiesDepth(property.of, accumulator + 1);
|
|
6630
6570
|
else return accumulator + 1;
|
|
6631
6571
|
}
|
|
6632
|
-
var
|
|
6572
|
+
var useBuildSidePanel = (collectionRegistryController, urlController, navigationStateController, sideDialogsController, authController) => {
|
|
6633
6573
|
const location = useLocation();
|
|
6634
6574
|
const initialised = useRef(false);
|
|
6635
6575
|
const currentPanelKeysRef = useRef([]);
|
|
@@ -6682,7 +6622,7 @@ var useBuildSideEntityController = (collectionRegistryController, urlController,
|
|
|
6682
6622
|
sideDialogsController.close();
|
|
6683
6623
|
}, [sideDialogsController]);
|
|
6684
6624
|
const open = useCallback((props) => {
|
|
6685
|
-
if (props.copy && !props.entityId) throw Error("If you want to copy
|
|
6625
|
+
if (props.copy && !props.entityId) throw Error("If you want to copy a entity you need to provide a entityId");
|
|
6686
6626
|
const defaultSelectedView = resolveDefaultSelectedView(props.collection ? props.collection.defaultSelectedView : void 0, {
|
|
6687
6627
|
status: props.copy ? "copy" : props.entityId ? "existing" : "new",
|
|
6688
6628
|
entityId: props.entityId
|
|
@@ -6700,7 +6640,7 @@ var useBuildSideEntityController = (collectionRegistryController, urlController,
|
|
|
6700
6640
|
location.search
|
|
6701
6641
|
]);
|
|
6702
6642
|
const replace = useCallback((props) => {
|
|
6703
|
-
if (props.copy && !props.entityId) throw Error("If you want to copy
|
|
6643
|
+
if (props.copy && !props.entityId) throw Error("If you want to copy a entity you need to provide a entityId");
|
|
6704
6644
|
sideDialogsController.replace(propsToSidePanel(props, urlController.buildUrlCollectionPath, urlController.resolveDatabasePathsFrom, smallLayout, customizationController, authController, location.search));
|
|
6705
6645
|
}, [
|
|
6706
6646
|
urlController.buildUrlCollectionPath,
|
|
@@ -6776,7 +6716,7 @@ var propsToSidePanel = (props, buildUrlCollectionPath, resolveIdsFrom, smallLayo
|
|
|
6776
6716
|
const entityViewWidth = getEntityViewWidth(props, smallLayout, customizationController);
|
|
6777
6717
|
return {
|
|
6778
6718
|
key: `${props.path}/${props.entityId}`,
|
|
6779
|
-
component: /* @__PURE__ */ jsx(
|
|
6719
|
+
component: /* @__PURE__ */ jsx(ResolvedSidePanelBinding, { ...resolvedPanelProps }),
|
|
6780
6720
|
urlPath,
|
|
6781
6721
|
parentUrlPath,
|
|
6782
6722
|
width: entityViewWidth,
|
|
@@ -6849,21 +6789,21 @@ function useUrlController() {
|
|
|
6849
6789
|
*/
|
|
6850
6790
|
function useCMSContext() {
|
|
6851
6791
|
const baseContext = useRebaseContext();
|
|
6852
|
-
const
|
|
6792
|
+
const sidePanelController = useSidePanel();
|
|
6853
6793
|
const sideDialogsController = useSideDialogsController();
|
|
6854
6794
|
const urlController = useUrlController();
|
|
6855
6795
|
const navigationStateController = useNavigationStateController();
|
|
6856
6796
|
const collectionRegistryController = useCollectionRegistryController();
|
|
6857
6797
|
return useMemo(() => ({
|
|
6858
6798
|
...baseContext,
|
|
6859
|
-
|
|
6799
|
+
sidePanelController,
|
|
6860
6800
|
sideDialogsController,
|
|
6861
6801
|
urlController,
|
|
6862
6802
|
navigationStateController,
|
|
6863
6803
|
collectionRegistryController
|
|
6864
6804
|
}), [
|
|
6865
6805
|
baseContext,
|
|
6866
|
-
|
|
6806
|
+
sidePanelController,
|
|
6867
6807
|
sideDialogsController,
|
|
6868
6808
|
urlController,
|
|
6869
6809
|
navigationStateController,
|
|
@@ -6894,8 +6834,13 @@ function resolveNavigationFrom({ path, context }) {
|
|
|
6894
6834
|
if (entry.type === "collection") return Promise.resolve(entry);
|
|
6895
6835
|
else if (entry.type === "entity") {
|
|
6896
6836
|
if (!collectionRegistryController.getCollection(entry.slug)) throw Error(`No collection defined in the navigation for the entity with path ${entry.slug}`);
|
|
6897
|
-
return data.collection(entry.slug).findById(entry.entityId).then((
|
|
6898
|
-
if (!
|
|
6837
|
+
return data.collection(entry.slug).findById(entry.entityId).then((row) => {
|
|
6838
|
+
if (!row) return void 0;
|
|
6839
|
+
const entity = {
|
|
6840
|
+
id: row.id,
|
|
6841
|
+
path: entry.slug,
|
|
6842
|
+
values: row
|
|
6843
|
+
};
|
|
6899
6844
|
return {
|
|
6900
6845
|
...entry,
|
|
6901
6846
|
entity
|
|
@@ -6943,12 +6888,12 @@ function useResolvedNavigationFrom({ path }) {
|
|
|
6943
6888
|
]);
|
|
6944
6889
|
}
|
|
6945
6890
|
//#endregion
|
|
6946
|
-
//#region src/hooks/
|
|
6891
|
+
//#region src/hooks/useHistory.ts
|
|
6947
6892
|
/**
|
|
6948
6893
|
* Hook to fetch entity history from the backend REST API.
|
|
6949
6894
|
* Replaces the old subcollection-based approach with a proper API call.
|
|
6950
6895
|
*/
|
|
6951
|
-
function
|
|
6896
|
+
function useHistory(params) {
|
|
6952
6897
|
const { slug, entityId, enabled = true, pageSize = 10 } = params;
|
|
6953
6898
|
const apiConfig = useApiConfig();
|
|
6954
6899
|
const [entries, setEntries] = useState([]);
|
|
@@ -7283,7 +7228,7 @@ function DeleteEntityDialog({ entityOrEntitiesToDelete, collection, onClose, ope
|
|
|
7283
7228
|
if (entityOrEntities && multipleEntities) content = /* @__PURE__ */ jsx(Fragment, { children: t("multiple_entities") });
|
|
7284
7229
|
else {
|
|
7285
7230
|
const entity = entityOrEntities;
|
|
7286
|
-
content = entity ? /* @__PURE__ */ jsx(
|
|
7231
|
+
content = entity ? /* @__PURE__ */ jsx(EntityViewBinding, {
|
|
7287
7232
|
entity,
|
|
7288
7233
|
collection,
|
|
7289
7234
|
path
|
|
@@ -7331,7 +7276,7 @@ function DeleteEntityDialog({ entityOrEntitiesToDelete, collection, onClose, ope
|
|
|
7331
7276
|
});
|
|
7332
7277
|
}
|
|
7333
7278
|
//#endregion
|
|
7334
|
-
//#region src/components/
|
|
7279
|
+
//#region src/components/CollectionViewBinding/utils.ts
|
|
7335
7280
|
function addRecentId(collectionId, id) {
|
|
7336
7281
|
const newRecentIds = [id, ...getRecentIds(collectionId).filter((i) => i !== id)];
|
|
7337
7282
|
if (newRecentIds.length > 5) newRecentIds.pop();
|
|
@@ -7349,11 +7294,11 @@ function getRecentIds(collectionId) {
|
|
|
7349
7294
|
//#endregion
|
|
7350
7295
|
//#region src/util/navigation_utils.ts
|
|
7351
7296
|
/**
|
|
7352
|
-
* Navigate to
|
|
7297
|
+
* Navigate to a entity using either a side panel or full-screen mode.
|
|
7353
7298
|
* This is an admin-specific UI concern and lives here (not in common).
|
|
7354
7299
|
*/
|
|
7355
|
-
function navigateToEntity({ openEntityMode, collection, entityId, copy, path, selectedTab, defaultValues,
|
|
7356
|
-
if (openEntityMode === "side_panel" || openEntityMode === "dialog")
|
|
7300
|
+
function navigateToEntity({ openEntityMode, collection, entityId, copy, path, selectedTab, defaultValues, sidePanelController, onClose, navigation, replace }) {
|
|
7301
|
+
if (openEntityMode === "side_panel" || openEntityMode === "dialog") sidePanelController.open({
|
|
7357
7302
|
entityId,
|
|
7358
7303
|
path,
|
|
7359
7304
|
copy,
|
|
@@ -7495,9 +7440,9 @@ var editEntityAction = {
|
|
|
7495
7440
|
name: "Edit",
|
|
7496
7441
|
collapsed: false,
|
|
7497
7442
|
isEnabled: ({ entity }) => Boolean(entity),
|
|
7498
|
-
onClick({ entity, collection, path, context,
|
|
7443
|
+
onClick({ entity, collection, path, context, sidePanelController, highlightEntity, unhighlightEntity, openEntityMode }) {
|
|
7499
7444
|
if (!entity) throw new Error("INTERNAL: editEntityAction: Entity is undefined");
|
|
7500
|
-
if (!
|
|
7445
|
+
if (!sidePanelController) throw new Error("INTERNAL: editEntityAction: sidePanelController is undefined");
|
|
7501
7446
|
highlightEntity?.(entity);
|
|
7502
7447
|
context?.analyticsController?.onAnalyticsEvent?.("entity_click", {
|
|
7503
7448
|
path: entity.path,
|
|
@@ -7509,14 +7454,15 @@ var editEntityAction = {
|
|
|
7509
7454
|
status: "existing",
|
|
7510
7455
|
entityId: entity.id
|
|
7511
7456
|
});
|
|
7457
|
+
if (!context?.urlController) throw new Error("INTERNAL: editEntityAction: urlController is undefined");
|
|
7512
7458
|
navigateToEntity({
|
|
7513
7459
|
openEntityMode,
|
|
7514
7460
|
collection,
|
|
7515
7461
|
entityId: entity.id,
|
|
7516
7462
|
path: newFullIdPath,
|
|
7517
|
-
|
|
7463
|
+
sidePanelController,
|
|
7518
7464
|
onClose: () => unhighlightEntity?.(entity),
|
|
7519
|
-
navigation: context
|
|
7465
|
+
navigation: context.urlController,
|
|
7520
7466
|
selectedTab: defaultSelectedView
|
|
7521
7467
|
});
|
|
7522
7468
|
return Promise.resolve(void 0);
|
|
@@ -7527,24 +7473,25 @@ var copyEntityAction = {
|
|
|
7527
7473
|
name: "Copy",
|
|
7528
7474
|
key: "copy",
|
|
7529
7475
|
isEnabled: ({ entity }) => Boolean(entity),
|
|
7530
|
-
onClick({ entity, collection, context, path,
|
|
7476
|
+
onClick({ entity, collection, context, path, sidePanelController, highlightEntity, unhighlightEntity, openEntityMode }) {
|
|
7531
7477
|
if (!entity) throw new Error("INTERNAL: copyEntityAction: Entity is undefined");
|
|
7532
|
-
if (!
|
|
7478
|
+
if (!sidePanelController) throw new Error("INTERNAL: copyEntityAction: sidePanelController is undefined");
|
|
7533
7479
|
highlightEntity?.(entity);
|
|
7534
7480
|
context?.analyticsController?.onAnalyticsEvent?.("copy_entity_click", {
|
|
7535
7481
|
path: entity.path,
|
|
7536
7482
|
entityId: entity.id
|
|
7537
7483
|
});
|
|
7538
7484
|
const usedPath = path ?? collection?.slug ?? entity.path;
|
|
7485
|
+
if (!context?.urlController) throw new Error("INTERNAL: copyEntityAction: urlController is undefined");
|
|
7539
7486
|
navigateToEntity({
|
|
7540
7487
|
openEntityMode,
|
|
7541
7488
|
collection,
|
|
7542
7489
|
entityId: entity.id,
|
|
7543
7490
|
path: usedPath,
|
|
7544
7491
|
copy: true,
|
|
7545
|
-
|
|
7492
|
+
sidePanelController,
|
|
7546
7493
|
onClose: () => unhighlightEntity?.(entity),
|
|
7547
|
-
navigation: context
|
|
7494
|
+
navigation: context.urlController
|
|
7548
7495
|
});
|
|
7549
7496
|
return Promise.resolve(void 0);
|
|
7550
7497
|
}
|
|
@@ -7744,7 +7691,7 @@ function injectAuthCollectionConfig(collections) {
|
|
|
7744
7691
|
const { dialogsController } = context;
|
|
7745
7692
|
const creationResult = {
|
|
7746
7693
|
user: {
|
|
7747
|
-
uid: String(props.
|
|
7694
|
+
uid: String(props.id),
|
|
7748
7695
|
email: typeof values.email === "string" ? values.email : "",
|
|
7749
7696
|
displayName: typeof values.displayName === "string" ? values.displayName : "",
|
|
7750
7697
|
roles: Array.isArray(values.roles) ? values.roles : [],
|
|
@@ -7989,7 +7936,7 @@ function useAsyncResolver({ resolver, initialValue, isEqual, deps, disabled }) {
|
|
|
7989
7936
|
//#region src/hooks/navigation/useResolvedCollections.ts
|
|
7990
7937
|
/**
|
|
7991
7938
|
* Hook that resolves collection props (which may be async builders or arrays)
|
|
7992
|
-
* into concrete
|
|
7939
|
+
* into concrete CollectionConfig[], and registers them with the CollectionRegistry.
|
|
7993
7940
|
*
|
|
7994
7941
|
* When userManagement is provided, the default users collection is always
|
|
7995
7942
|
* prepended. Developer collections override via generic slug-based dedup
|
|
@@ -8472,7 +8419,7 @@ var SideDialogContext = React.createContext({
|
|
|
8472
8419
|
var useSideDialogContext = () => useContext(SideDialogContext);
|
|
8473
8420
|
/**
|
|
8474
8421
|
* This is the component in charge of rendering the side dialogs used
|
|
8475
|
-
* for editing entities. Use the {@link
|
|
8422
|
+
* for editing entities. Use the {@link useSidePanel} to open
|
|
8476
8423
|
* and control the dialogs.
|
|
8477
8424
|
* This component needs a parent {@link Rebase}
|
|
8478
8425
|
* {@link useSideDialogsController}
|
|
@@ -8590,22 +8537,22 @@ function SideDialogView({ offsetPosition, panel, panelIndex, isTopPanel }) {
|
|
|
8590
8537
|
});
|
|
8591
8538
|
}
|
|
8592
8539
|
//#endregion
|
|
8593
|
-
//#region src/components/ReferenceTable/
|
|
8540
|
+
//#region src/components/ReferenceTable/SelectionTableBinding.tsx
|
|
8594
8541
|
/**
|
|
8595
8542
|
* This component allows to select entities from a given collection.
|
|
8596
|
-
* You probably want to open this dialog as a side view using {@link
|
|
8543
|
+
* You probably want to open this dialog as a side view using {@link useSelectionTableBinding}
|
|
8597
8544
|
* @group Components
|
|
8598
8545
|
*/
|
|
8599
|
-
function
|
|
8546
|
+
function SelectionTableBinding(props) {
|
|
8600
8547
|
if (!props.collection) return /* @__PURE__ */ jsx(ErrorView, { error: "Could not find collection" });
|
|
8601
|
-
return /* @__PURE__ */ jsx(
|
|
8548
|
+
return /* @__PURE__ */ jsx(SelectionTableBindingInternal, {
|
|
8602
8549
|
...props,
|
|
8603
8550
|
collection: props.collection
|
|
8604
8551
|
});
|
|
8605
8552
|
}
|
|
8606
|
-
function
|
|
8553
|
+
function SelectionTableBindingInternal({ onSingleEntitySelected, onMultipleEntitiesSelected, multiselect, collection, path: pathInput, selectedEntityIds: selectedEntityIdsProp, description, fixedFilter, maxSelection }) {
|
|
8607
8554
|
const sideDialogContext = useSideDialogContext();
|
|
8608
|
-
const
|
|
8555
|
+
const sidePanelController = useSidePanel();
|
|
8609
8556
|
const urlController = useUrlController();
|
|
8610
8557
|
const analyticsController = useAnalyticsController();
|
|
8611
8558
|
const path = urlController.resolveDatabasePathsFrom(pathInput);
|
|
@@ -8682,7 +8629,7 @@ function EntitySelectionTableInternal({ onSingleEntitySelected, onMultipleEntiti
|
|
|
8682
8629
|
]);
|
|
8683
8630
|
const onNewClick = () => {
|
|
8684
8631
|
analyticsController.onAnalyticsEvent?.("reference_selection_new_entity", { path });
|
|
8685
|
-
|
|
8632
|
+
sidePanelController.open({
|
|
8686
8633
|
path,
|
|
8687
8634
|
collection,
|
|
8688
8635
|
updateUrl: true,
|
|
@@ -8695,7 +8642,7 @@ function EntitySelectionTableInternal({ onSingleEntitySelected, onMultipleEntiti
|
|
|
8695
8642
|
};
|
|
8696
8643
|
const tableRowActionsBuilder = ({ entity, size, width, frozen }) => {
|
|
8697
8644
|
const selectedEntities = selectionController.selectedEntities;
|
|
8698
|
-
return /* @__PURE__ */ jsx(
|
|
8645
|
+
return /* @__PURE__ */ jsx(CollectionRowActions, {
|
|
8699
8646
|
width,
|
|
8700
8647
|
frozen,
|
|
8701
8648
|
entity,
|
|
@@ -8720,51 +8667,54 @@ function EntitySelectionTableInternal({ onSingleEntitySelected, onMultipleEntiti
|
|
|
8720
8667
|
fixedFilter,
|
|
8721
8668
|
updateUrl: false
|
|
8722
8669
|
});
|
|
8723
|
-
return /* @__PURE__ */
|
|
8724
|
-
|
|
8725
|
-
children:
|
|
8726
|
-
className: "
|
|
8727
|
-
children:
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
|
|
8742
|
-
|
|
8743
|
-
|
|
8744
|
-
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
|
|
8670
|
+
return /* @__PURE__ */ jsx(CollectionScopeProvider, {
|
|
8671
|
+
collection,
|
|
8672
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
8673
|
+
className: "flex flex-col h-full",
|
|
8674
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
8675
|
+
className: "grow",
|
|
8676
|
+
children: entitiesDisplayedFirst && /* @__PURE__ */ jsx(CollectionTableBinding, {
|
|
8677
|
+
additionalFields: collection.additionalFields,
|
|
8678
|
+
displayedColumnIds,
|
|
8679
|
+
onEntityClick,
|
|
8680
|
+
tableController,
|
|
8681
|
+
enablePopupIcon: false,
|
|
8682
|
+
tableRowActionsBuilder,
|
|
8683
|
+
openEntityMode: "side_panel",
|
|
8684
|
+
title: /* @__PURE__ */ jsxs(Typography, {
|
|
8685
|
+
variant: "subtitle2",
|
|
8686
|
+
className: "flex flex-row gap-2",
|
|
8687
|
+
children: [/* @__PURE__ */ jsx(IconForView, {
|
|
8688
|
+
size: "small",
|
|
8689
|
+
collectionOrView: collection,
|
|
8690
|
+
className: "text-surface-300 dark:text-surface-600"
|
|
8691
|
+
}), collection.singularName ? `Select ${collection.singularName}` : `Select from ${collection.name}`]
|
|
8692
|
+
}),
|
|
8693
|
+
defaultSize: collection.defaultSize,
|
|
8694
|
+
properties: collection.properties,
|
|
8695
|
+
fixedFilter,
|
|
8696
|
+
inlineEditing: false,
|
|
8697
|
+
selectionController,
|
|
8698
|
+
actions: /* @__PURE__ */ jsx(EntitySelectionDialogActions, {
|
|
8699
|
+
collection,
|
|
8700
|
+
path,
|
|
8701
|
+
onNewClick,
|
|
8702
|
+
onClear
|
|
8703
|
+
})
|
|
8754
8704
|
})
|
|
8755
|
-
})
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
|
|
8765
|
-
|
|
8705
|
+
}), /* @__PURE__ */ jsxs(DialogActions, {
|
|
8706
|
+
translucent: false,
|
|
8707
|
+
children: [description && /* @__PURE__ */ jsx(Typography, {
|
|
8708
|
+
variant: "body2",
|
|
8709
|
+
className: "grow text-left",
|
|
8710
|
+
children: description
|
|
8711
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
8712
|
+
onClick: onDone,
|
|
8713
|
+
variant: "filled",
|
|
8714
|
+
children: "Done"
|
|
8715
|
+
})]
|
|
8766
8716
|
})]
|
|
8767
|
-
})
|
|
8717
|
+
})
|
|
8768
8718
|
});
|
|
8769
8719
|
}
|
|
8770
8720
|
function EntitySelectionDialogActions({ collection, path, onClear, onNewClick }) {
|
|
@@ -8789,10 +8739,10 @@ function EntitySelectionDialogActions({ collection, path, onClear, onNewClick })
|
|
|
8789
8739
|
}), addButton] });
|
|
8790
8740
|
}
|
|
8791
8741
|
//#endregion
|
|
8792
|
-
//#region src/components/
|
|
8742
|
+
//#region src/components/CollectionViewBinding/hooks/useCollectionInlineEditor.ts
|
|
8793
8743
|
function useCollectionInlineEditor({ path, collection, dataClient, context }) {
|
|
8794
8744
|
const uniqueFieldValidator = useCallback(async ({ name, value, property, entityId }) => {
|
|
8795
|
-
const conflictingEntities = (await dataClient.collection(path).find({ where: { [name]: "
|
|
8745
|
+
const conflictingEntities = (await dataClient.collection(path).find({ where: { [name]: ["==", value] } })).data;
|
|
8796
8746
|
return conflictingEntities.length === 0 || conflictingEntities.length === 1 && conflictingEntities[0].id === entityId;
|
|
8797
8747
|
}, [path, dataClient]);
|
|
8798
8748
|
const onValueChange = useCallback(({ value, propertyKey, onValueUpdated, setError, data: entity }) => {
|
|
@@ -9080,7 +9030,7 @@ function ReadOnlyFieldBinding({ propertyKey, value, error, showError, minimalist
|
|
|
9080
9030
|
*
|
|
9081
9031
|
* Please note that if you build a custom field in a component, the
|
|
9082
9032
|
* **validation** passed in the property will have no effect. You need to set
|
|
9083
|
-
* the validation in the `
|
|
9033
|
+
* the validation in the `CollectionConfig` definition.
|
|
9084
9034
|
*
|
|
9085
9035
|
* @param propertyKey You can use nested names such as `address.street` or `friends[2]`
|
|
9086
9036
|
* @param property
|
|
@@ -9663,7 +9613,7 @@ function ArrayOfReferencesFieldBinding({ propertyKey, value, error, showError, d
|
|
|
9663
9613
|
const onMultipleEntitiesSelected = useCallback((entities) => {
|
|
9664
9614
|
setValue(entities.map((e) => getReferenceFrom(e)));
|
|
9665
9615
|
}, [setValue]);
|
|
9666
|
-
const referenceDialogController =
|
|
9616
|
+
const referenceDialogController = useSelectionDialog({
|
|
9667
9617
|
multiselect: true,
|
|
9668
9618
|
path: ofProperty.path,
|
|
9669
9619
|
collection,
|
|
@@ -10012,13 +9962,13 @@ function MapEditView({ value, initialValue, setValue, fieldName, disabled }) {
|
|
|
10012
9962
|
});
|
|
10013
9963
|
setInternalState(newRowIds);
|
|
10014
9964
|
}, [value]);
|
|
10015
|
-
const updatetype = (
|
|
10016
|
-
if (!
|
|
9965
|
+
const updatetype = (id, type) => {
|
|
9966
|
+
if (!id) {
|
|
10017
9967
|
console.warn("No key selected for data type update");
|
|
10018
9968
|
return;
|
|
10019
9969
|
}
|
|
10020
9970
|
setInternalState(internalState.map((row) => {
|
|
10021
|
-
if (row[0] ===
|
|
9971
|
+
if (row[0] === id) return [row[0], {
|
|
10022
9972
|
key: row[1].key,
|
|
10023
9973
|
type
|
|
10024
9974
|
}];
|
|
@@ -10026,20 +9976,20 @@ function MapEditView({ value, initialValue, setValue, fieldName, disabled }) {
|
|
|
10026
9976
|
}));
|
|
10027
9977
|
setValue({
|
|
10028
9978
|
...value ?? {},
|
|
10029
|
-
[internalState.find((row) => row[0] ===
|
|
9979
|
+
[internalState.find((row) => row[0] === id)?.[1].key ?? ""]: getDefaultValueFortype(type)
|
|
10030
9980
|
});
|
|
10031
9981
|
};
|
|
10032
9982
|
return /* @__PURE__ */ jsxs("div", {
|
|
10033
9983
|
className: "py-1 flex flex-col gap-1",
|
|
10034
|
-
children: [internalState.map(([
|
|
9984
|
+
children: [internalState.map(([id, { key: fieldKey, type }], index) => {
|
|
10035
9985
|
const entryValue = fieldKey ? value?.[fieldKey] : "";
|
|
10036
9986
|
const onFieldKeyChange = (newKey) => {
|
|
10037
|
-
setInternalState(internalState.map((
|
|
10038
|
-
if (
|
|
9987
|
+
setInternalState(internalState.map((currentId) => {
|
|
9988
|
+
if (currentId[0] === id) return [id, {
|
|
10039
9989
|
key: newKey ?? "",
|
|
10040
|
-
type:
|
|
9990
|
+
type: currentId[1].type
|
|
10041
9991
|
}];
|
|
10042
|
-
return
|
|
9992
|
+
return currentId;
|
|
10043
9993
|
}));
|
|
10044
9994
|
if (typeof value === "object" && newKey in value) return;
|
|
10045
9995
|
const newValue = { ...value ?? {} };
|
|
@@ -10051,14 +10001,14 @@ function MapEditView({ value, initialValue, setValue, fieldName, disabled }) {
|
|
|
10051
10001
|
});
|
|
10052
10002
|
};
|
|
10053
10003
|
return /* @__PURE__ */ jsx(MapKeyValueRow, {
|
|
10054
|
-
|
|
10004
|
+
id,
|
|
10055
10005
|
fieldKey,
|
|
10056
10006
|
value: value ?? {},
|
|
10057
10007
|
onDeleteClick: () => {
|
|
10058
10008
|
const newValue = { ...value ?? {} };
|
|
10059
10009
|
if (initialValue && fieldKey in initialValue) newValue[fieldKey] = void 0;
|
|
10060
10010
|
else delete newValue[fieldKey];
|
|
10061
|
-
setInternalState(internalState.filter((
|
|
10011
|
+
setInternalState(internalState.filter((currentId) => currentId[0] !== id));
|
|
10062
10012
|
setValue({ ...newValue });
|
|
10063
10013
|
},
|
|
10064
10014
|
onFieldKeyChange,
|
|
@@ -10067,7 +10017,7 @@ function MapEditView({ value, initialValue, setValue, fieldName, disabled }) {
|
|
|
10067
10017
|
type,
|
|
10068
10018
|
disabled,
|
|
10069
10019
|
updatetype
|
|
10070
|
-
},
|
|
10020
|
+
}, id);
|
|
10071
10021
|
}), /* @__PURE__ */ jsx(Button, {
|
|
10072
10022
|
variant: "text",
|
|
10073
10023
|
size: "small",
|
|
@@ -10089,7 +10039,7 @@ function MapEditView({ value, initialValue, setValue, fieldName, disabled }) {
|
|
|
10089
10039
|
})]
|
|
10090
10040
|
});
|
|
10091
10041
|
}
|
|
10092
|
-
function MapKeyValueRow({
|
|
10042
|
+
function MapKeyValueRow({ id, fieldKey, value, onFieldKeyChange, onDeleteClick, setValue, entryValue, type, updatetype, disabled }) {
|
|
10093
10043
|
const { locale } = useCustomizationController();
|
|
10094
10044
|
const { t } = useTranslation();
|
|
10095
10045
|
function buildInput(entryValue, fieldKey, type) {
|
|
@@ -10151,7 +10101,7 @@ function MapKeyValueRow({ rowId, fieldKey, value, onFieldKeyChange, onDeleteClic
|
|
|
10151
10101
|
children: /* @__PURE__ */ jsx(ArrayContainer, {
|
|
10152
10102
|
value: arrayValue,
|
|
10153
10103
|
newDefaultEntry: "",
|
|
10154
|
-
droppableId:
|
|
10104
|
+
droppableId: id.toString(),
|
|
10155
10105
|
addLabel: fieldKey ? t("add_to_field", { fieldName: fieldKey }) : t("add"),
|
|
10156
10106
|
size: "small",
|
|
10157
10107
|
disabled: disabled || !fieldKey,
|
|
@@ -10199,7 +10149,7 @@ function MapKeyValueRow({ rowId, fieldKey, value, onFieldKeyChange, onDeleteClic
|
|
|
10199
10149
|
});
|
|
10200
10150
|
}
|
|
10201
10151
|
function doUpdatetype(type) {
|
|
10202
|
-
updatetype(
|
|
10152
|
+
updatetype(id, type);
|
|
10203
10153
|
}
|
|
10204
10154
|
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Typography, {
|
|
10205
10155
|
component: "div",
|
|
@@ -10268,7 +10218,7 @@ function MapKeyValueRow({ rowId, fieldKey, value, onFieldKeyChange, onDeleteClic
|
|
|
10268
10218
|
})]
|
|
10269
10219
|
})
|
|
10270
10220
|
]
|
|
10271
|
-
},
|
|
10221
|
+
}, id.toString()), (type === "map" || type === "array") && buildInput(entryValue, fieldKey, type)] });
|
|
10272
10222
|
}
|
|
10273
10223
|
function ArrayKeyValueRow({ id, index, value, setValue }) {
|
|
10274
10224
|
const { locale } = useCustomizationController();
|
|
@@ -10489,8 +10439,18 @@ function MarkdownEditorFieldBinding({ property, propertyKey, value, setValue, in
|
|
|
10489
10439
|
const disabled = disabledProp || isSubmitting;
|
|
10490
10440
|
const highlight = customProps?.highlight;
|
|
10491
10441
|
const editorProps = customProps?.editorProps;
|
|
10492
|
-
const
|
|
10442
|
+
const defaultStorageSource = useStorageSource();
|
|
10493
10443
|
const storage = property.storage;
|
|
10444
|
+
const storageSources = useStorageSources();
|
|
10445
|
+
const storageSource = useMemo(() => resolveStorageSource({
|
|
10446
|
+
sourceKey: storage?.storageSource,
|
|
10447
|
+
sources: storageSources.sources,
|
|
10448
|
+
defaultSource: defaultStorageSource
|
|
10449
|
+
}), [
|
|
10450
|
+
storage?.storageSource,
|
|
10451
|
+
storageSources.sources,
|
|
10452
|
+
defaultStorageSource
|
|
10453
|
+
]);
|
|
10494
10454
|
const entityValues = context.values;
|
|
10495
10455
|
const entityId = context.entityId;
|
|
10496
10456
|
const path = context.path;
|
|
@@ -10701,91 +10661,6 @@ function MultiSelectFieldBinding({ propertyKey, value, setValue, error, showErro
|
|
|
10701
10661
|
})] });
|
|
10702
10662
|
}
|
|
10703
10663
|
//#endregion
|
|
10704
|
-
//#region src/form/field_bindings/ReferenceAsStringFieldBinding.tsx
|
|
10705
|
-
/**
|
|
10706
|
-
* Field that opens a reference selection dialog and stores the entity ID as a string.
|
|
10707
|
-
*
|
|
10708
|
-
* This is one of the internal components that get mapped natively inside forms
|
|
10709
|
-
* and tables to the specified properties.
|
|
10710
|
-
* @group Form fields
|
|
10711
|
-
*/
|
|
10712
|
-
function ReferenceAsStringFieldBinding(props) {
|
|
10713
|
-
if (typeof props.property.reference?.path !== "string") return /* @__PURE__ */ jsx(ReadOnlyFieldBinding, { ...props });
|
|
10714
|
-
return /* @__PURE__ */ jsx(ReferenceAsStringFieldBindingInternal, { ...props });
|
|
10715
|
-
}
|
|
10716
|
-
function ReferenceAsStringFieldBindingInternal({ propertyKey, value, setValue, error, showError, isSubmitting, disabled, minimalistView, property, includeDescription, size = "medium" }) {
|
|
10717
|
-
if (!property.reference?.path) throw new Error("Property path is required for ReferenceAsStringFieldBinding");
|
|
10718
|
-
useClearRestoreValue({
|
|
10719
|
-
property,
|
|
10720
|
-
value,
|
|
10721
|
-
setValue
|
|
10722
|
-
});
|
|
10723
|
-
const collectionRegistryController = useCollectionRegistryController();
|
|
10724
|
-
const path = property.reference.path;
|
|
10725
|
-
const collection = useMemo(() => {
|
|
10726
|
-
return path ? collectionRegistryController.getCollection(path) : void 0;
|
|
10727
|
-
}, [path]);
|
|
10728
|
-
const referenceValue = useMemo(() => {
|
|
10729
|
-
if (value && path) return new EntityReference({
|
|
10730
|
-
id: value,
|
|
10731
|
-
path
|
|
10732
|
-
});
|
|
10733
|
-
}, [value, path]);
|
|
10734
|
-
if (!collection) throw Error(`Couldn't find the corresponding collection for the path: ${path}`);
|
|
10735
|
-
const referenceDialogController = useEntitySelectionDialog({
|
|
10736
|
-
multiselect: false,
|
|
10737
|
-
path,
|
|
10738
|
-
collection,
|
|
10739
|
-
onSingleEntitySelected: useCallback((e) => {
|
|
10740
|
-
setValue(e ? String(e.id) : null);
|
|
10741
|
-
}, [setValue]),
|
|
10742
|
-
selectedEntityIds: value ? [value] : void 0,
|
|
10743
|
-
fixedFilter: property.reference?.fixedFilter
|
|
10744
|
-
});
|
|
10745
|
-
const onEntryClick = (e) => {
|
|
10746
|
-
e.preventDefault();
|
|
10747
|
-
referenceDialogController.open();
|
|
10748
|
-
};
|
|
10749
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10750
|
-
!minimalistView && /* @__PURE__ */ jsx(LabelWithIconAndTooltip, {
|
|
10751
|
-
propertyKey,
|
|
10752
|
-
icon: getIconForProperty(property, "small"),
|
|
10753
|
-
required: property.validation?.required,
|
|
10754
|
-
title: property.name ?? propertyKey,
|
|
10755
|
-
className: "h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"
|
|
10756
|
-
}),
|
|
10757
|
-
!collection && /* @__PURE__ */ jsx(ErrorView, { error: "The specified collection does not exist. Check console" }),
|
|
10758
|
-
collection && /* @__PURE__ */ jsxs(Fragment, { children: [referenceValue && /* @__PURE__ */ jsx(ReferencePreview, {
|
|
10759
|
-
disabled: !path,
|
|
10760
|
-
previewProperties: property.reference?.ui?.previewProperties,
|
|
10761
|
-
hover: !disabled,
|
|
10762
|
-
size,
|
|
10763
|
-
onClick: disabled || isSubmitting ? void 0 : onEntryClick,
|
|
10764
|
-
reference: referenceValue,
|
|
10765
|
-
includeEntityLink: property.reference?.includeEntityLink,
|
|
10766
|
-
includeId: property.reference?.includeId
|
|
10767
|
-
}), !value && /* @__PURE__ */ jsx("div", {
|
|
10768
|
-
className: "justify-center text-left",
|
|
10769
|
-
children: /* @__PURE__ */ jsxs(EntityPreviewContainer, {
|
|
10770
|
-
className: cls("px-6 h-16 text-sm font-medium flex items-center gap-6", disabled || isSubmitting ? "text-surface-accent-500" : "cursor-pointer text-surface-accent-700 dark:text-surface-accent-300 hover:bg-surface-accent-50 dark:hover:bg-surface-800 group-hover:bg-surface-accent-50 dark:group-hover:bg-surface-800"),
|
|
10771
|
-
onClick: onEntryClick,
|
|
10772
|
-
size: "medium",
|
|
10773
|
-
children: [/* @__PURE__ */ jsx(IconForView, {
|
|
10774
|
-
collectionOrView: collection,
|
|
10775
|
-
className: "text-surface-300 dark:text-surface-600"
|
|
10776
|
-
}), `Edit ${property.name}`.toUpperCase()]
|
|
10777
|
-
})
|
|
10778
|
-
})] }),
|
|
10779
|
-
/* @__PURE__ */ jsx(FieldHelperText, {
|
|
10780
|
-
includeDescription,
|
|
10781
|
-
showError,
|
|
10782
|
-
error,
|
|
10783
|
-
disabled,
|
|
10784
|
-
property
|
|
10785
|
-
})
|
|
10786
|
-
] });
|
|
10787
|
-
}
|
|
10788
|
-
//#endregion
|
|
10789
10664
|
//#region src/form/field_bindings/ReferenceFieldBinding.tsx
|
|
10790
10665
|
/**
|
|
10791
10666
|
* Field that opens a reference selection dialog.
|
|
@@ -10815,7 +10690,7 @@ function ReferenceFieldBindingInternal({ propertyKey, value, setValue, error, sh
|
|
|
10815
10690
|
const onSingleEntitySelected = useCallback((e) => {
|
|
10816
10691
|
setValue(e ? getReferenceFrom(e) : null);
|
|
10817
10692
|
}, [setValue, propertyKey]);
|
|
10818
|
-
const referenceDialogController =
|
|
10693
|
+
const referenceDialogController = useSelectionDialog({
|
|
10819
10694
|
multiselect: false,
|
|
10820
10695
|
path: property.path,
|
|
10821
10696
|
collection,
|
|
@@ -11078,9 +10953,9 @@ var acceptDropClasses = "transition-colors duration-200 ease-[cubic-bezier(0,0,0
|
|
|
11078
10953
|
var rejectDropClasses = "transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-red-500";
|
|
11079
10954
|
function StorageUploadFieldBinding({ propertyKey, value, setValue, error, showError, autoFocus, minimalistView, property, includeDescription, context, isSubmitting }) {
|
|
11080
10955
|
useAuthController();
|
|
11081
|
-
const storageSource = useStorageSource(
|
|
10956
|
+
const storageSource = useStorageSource();
|
|
11082
10957
|
const disabled = isReadOnly(property) || !!property.ui?.disabled || isSubmitting || context.disabled;
|
|
11083
|
-
const { internalValue, setInternalValue, onFilesAdded, storage, onFileUploadComplete, storagePathBuilder, multipleFilesSupported } = useStorageUploadController({
|
|
10958
|
+
const { internalValue, setInternalValue, onFilesAdded, storage, onFileUploadComplete, storagePathBuilder, multipleFilesSupported, resolvedStorageSource } = useStorageUploadController({
|
|
11084
10959
|
entityValues: context.values,
|
|
11085
10960
|
entityId: context.entityId,
|
|
11086
10961
|
path: context.path,
|
|
@@ -11104,19 +10979,22 @@ function StorageUploadFieldBinding({ propertyKey, value, setValue, error, showEr
|
|
|
11104
10979
|
title: property.name ?? propertyKey,
|
|
11105
10980
|
className: "h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"
|
|
11106
10981
|
}),
|
|
11107
|
-
/* @__PURE__ */ jsx(
|
|
11108
|
-
value:
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
|
|
11114
|
-
|
|
11115
|
-
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
10982
|
+
/* @__PURE__ */ jsx(StorageSourceContext.Provider, {
|
|
10983
|
+
value: resolvedStorageSource,
|
|
10984
|
+
children: /* @__PURE__ */ jsx(StorageUpload, {
|
|
10985
|
+
value: internalValue,
|
|
10986
|
+
name: propertyKey,
|
|
10987
|
+
disabled: disabled ?? false,
|
|
10988
|
+
autoFocus: autoFocus ?? false,
|
|
10989
|
+
property,
|
|
10990
|
+
onChange: setValue,
|
|
10991
|
+
setInternalValue,
|
|
10992
|
+
onFilesAdded,
|
|
10993
|
+
onFileUploadComplete,
|
|
10994
|
+
storagePathBuilder,
|
|
10995
|
+
storage,
|
|
10996
|
+
multipleFilesSupported
|
|
10997
|
+
})
|
|
11120
10998
|
}),
|
|
11121
10999
|
/* @__PURE__ */ jsx(FieldHelperText, {
|
|
11122
11000
|
includeDescription,
|
|
@@ -11623,7 +11501,7 @@ function MultipleRelationFieldBinding({ propertyKey, value: valueProp, error, sh
|
|
|
11623
11501
|
const { t } = useTranslation();
|
|
11624
11502
|
if (property.type !== "relation") throw Error("RelationFieldBinding expected a property containing a relation");
|
|
11625
11503
|
const parentCollection = context.collection;
|
|
11626
|
-
const capabilities = parentCollection ? getDataSourceCapabilities(parentCollection.
|
|
11504
|
+
const capabilities = parentCollection ? getDataSourceCapabilities(parentCollection.engine) : void 0;
|
|
11627
11505
|
if (!parentCollection || !capabilities?.supportsRelations || !("relations" in parentCollection) || !parentCollection.relations) throw Error("RelationFieldBinding expected a collection with relations support");
|
|
11628
11506
|
const relation = resolveRelationProperty(property, parentCollection.relations, propertyKey).relation;
|
|
11629
11507
|
if (!relation) throw Error("Property relation is required for MultipleRelationFieldBinding");
|
|
@@ -11632,9 +11510,9 @@ function MultipleRelationFieldBinding({ propertyKey, value: valueProp, error, sh
|
|
|
11632
11510
|
const onMultipleEntitiesSelected = useCallback((entities) => {
|
|
11633
11511
|
setValue(entities.map((e) => getRelationFrom(e)));
|
|
11634
11512
|
}, [setValue]);
|
|
11635
|
-
const referenceDialogController =
|
|
11513
|
+
const referenceDialogController = useSelectionDialog({
|
|
11636
11514
|
multiselect: true,
|
|
11637
|
-
path: collection
|
|
11515
|
+
path: getCollectionDataPath(collection),
|
|
11638
11516
|
collection,
|
|
11639
11517
|
onMultipleEntitiesSelected,
|
|
11640
11518
|
selectedEntityIds,
|
|
@@ -11720,7 +11598,7 @@ function RelationFieldBinding(props) {
|
|
|
11720
11598
|
const { property, propertyKey, context } = props;
|
|
11721
11599
|
if (property.type !== "relation") throw Error("RelationFieldBinding expected a property containing a relation");
|
|
11722
11600
|
const collection = context.collection;
|
|
11723
|
-
const capabilities = collection ? getDataSourceCapabilities(collection.
|
|
11601
|
+
const capabilities = collection ? getDataSourceCapabilities(collection.engine) : void 0;
|
|
11724
11602
|
if (!collection || !capabilities?.supportsRelations || !("relations" in collection) || !collection.relations) throw Error("RelationFieldBinding expected a collection with relations support");
|
|
11725
11603
|
const relation = resolveRelationProperty(property, collection.relations, propertyKey).relation;
|
|
11726
11604
|
const manyRelation = relation?.cardinality === "many";
|
|
@@ -11778,9 +11656,9 @@ function SingleRelationFieldBinding({ propertyKey, value, size, error, showError
|
|
|
11778
11656
|
const onSingleEntitySelected = useCallback((e) => {
|
|
11779
11657
|
setValue(e ? getRelationFrom(e) : null);
|
|
11780
11658
|
}, [setValue]);
|
|
11781
|
-
const referenceDialogController =
|
|
11659
|
+
const referenceDialogController = useSelectionDialog({
|
|
11782
11660
|
multiselect: false,
|
|
11783
|
-
path: collection
|
|
11661
|
+
path: getCollectionDataPath(collection),
|
|
11784
11662
|
collection,
|
|
11785
11663
|
onSingleEntitySelected,
|
|
11786
11664
|
selectedEntityIds: validValue && normalizedValue ? [normalizedValue.id] : void 0,
|
|
@@ -12052,17 +11930,6 @@ var DEFAULT_FIELD_CONFIGS = {
|
|
|
12052
11930
|
ui: { Field: StorageUploadFieldBinding }
|
|
12053
11931
|
}
|
|
12054
11932
|
},
|
|
12055
|
-
reference_as_string: {
|
|
12056
|
-
key: "reference_as_string",
|
|
12057
|
-
name: "Reference (as string)",
|
|
12058
|
-
description: "The value refers to a different collection (it is saved as a string)",
|
|
12059
|
-
Icon: LinkIcon,
|
|
12060
|
-
color: "#154fb3",
|
|
12061
|
-
property: {
|
|
12062
|
-
type: "string",
|
|
12063
|
-
ui: { Field: ReferenceAsStringFieldBinding }
|
|
12064
|
-
}
|
|
12065
|
-
},
|
|
12066
11933
|
reference: {
|
|
12067
11934
|
key: "reference",
|
|
12068
11935
|
name: "Reference",
|
|
@@ -12208,7 +12075,6 @@ function getDefaultFieldId(property) {
|
|
|
12208
12075
|
else if (property.email) return "email";
|
|
12209
12076
|
else if (property.enum) return "select";
|
|
12210
12077
|
else if (property.userSelect) return "user_select";
|
|
12211
|
-
else if (property.reference) return "reference_as_string";
|
|
12212
12078
|
else return "text_field";
|
|
12213
12079
|
else if (property.type === "number") {
|
|
12214
12080
|
if (property.enum) return "number_select";
|
|
@@ -13119,10 +12985,10 @@ function EditorCollectionAction({ path, parentCollectionSlugs, parentEntityIds,
|
|
|
13119
12985
|
}) });
|
|
13120
12986
|
}
|
|
13121
12987
|
//#endregion
|
|
13122
|
-
//#region src/components/
|
|
12988
|
+
//#region src/components/CollectionViewBinding/CollectionViewActions.tsx
|
|
13123
12989
|
var ImportCollectionAction$1 = lazy(() => Promise.resolve().then(() => import_exports).then((m) => ({ default: m.ImportCollectionAction })));
|
|
13124
12990
|
var ExportCollectionAction$1 = lazy(() => Promise.resolve().then(() => export_exports).then((m) => ({ default: m.ExportCollectionAction })));
|
|
13125
|
-
function
|
|
12991
|
+
function CollectionViewActions({ collection, relativePath, parentCollectionSlugs, parentEntityIds, onNewClick, onMultipleDeleteClick, selectionEnabled, path, selectionController, tableController, collectionEntitiesCount, compact, children, openNewDocument }) {
|
|
13126
12992
|
const context = useCMSContext();
|
|
13127
12993
|
const { canCreate, canDelete } = usePermissions();
|
|
13128
12994
|
const largeLayout = useLargeLayout();
|
|
@@ -13227,7 +13093,7 @@ function EntityCollectionViewActions({ collection, relativePath, parentCollectio
|
|
|
13227
13093
|
});
|
|
13228
13094
|
}
|
|
13229
13095
|
//#endregion
|
|
13230
|
-
//#region src/components/
|
|
13096
|
+
//#region src/components/CollectionViewBinding/usePreviewSlots.ts
|
|
13231
13097
|
/**
|
|
13232
13098
|
* Resolve which property key fills each slot for a given collection.
|
|
13233
13099
|
* Pure function — call inside `useMemo`.
|
|
@@ -13293,8 +13159,8 @@ function resolveCollectionSlotKeys(collection, authController, propertyConfigs)
|
|
|
13293
13159
|
const sortedPreviewKeys = hasExplicitOrder ? previewKeys : [...previewKeys].sort((a, b) => {
|
|
13294
13160
|
const propA = collection.properties[a];
|
|
13295
13161
|
const propB = collection.properties[b];
|
|
13296
|
-
const scoreA = propA?.type === "string" ? propA.multiline ? 2 : 1 : 0;
|
|
13297
|
-
return (propB?.type === "string" ? propB.multiline ? 2 : 1 : 0) - scoreA;
|
|
13162
|
+
const scoreA = propA?.type === "string" ? propA.ui?.multiline ? 2 : 1 : 0;
|
|
13163
|
+
return (propB?.type === "string" ? propB.ui?.multiline ? 2 : 1 : 0) - scoreA;
|
|
13298
13164
|
});
|
|
13299
13165
|
return {
|
|
13300
13166
|
titleKey,
|
|
@@ -13487,7 +13353,7 @@ function resolveRelationDisplayName(relation, prop) {
|
|
|
13487
13353
|
return false;
|
|
13488
13354
|
};
|
|
13489
13355
|
const isDisplayCandidate = (p) => {
|
|
13490
|
-
return p.type === "string" && !p.multiline && !p.markdown && !p.storage && !("isId" in p && p.isId) && !isHiddenProp(p);
|
|
13356
|
+
return p.type === "string" && !p.ui?.multiline && !p.ui?.markdown && !p.storage && !("isId" in p && p.isId) && !isHiddenProp(p);
|
|
13491
13357
|
};
|
|
13492
13358
|
for (const pk of [
|
|
13493
13359
|
"name",
|
|
@@ -13522,12 +13388,12 @@ function resolveRelationDisplayName(relation, prop) {
|
|
|
13522
13388
|
return id !== void 0 ? String(id) : void 0;
|
|
13523
13389
|
}
|
|
13524
13390
|
//#endregion
|
|
13525
|
-
//#region src/components/
|
|
13391
|
+
//#region src/components/CollectionViewBinding/EntityCardBinding.tsx
|
|
13526
13392
|
/**
|
|
13527
|
-
* Card component for displaying
|
|
13393
|
+
* Card component for displaying a entity in a grid view.
|
|
13528
13394
|
* Shows thumbnail, title, and preview properties via the shared slot system.
|
|
13529
13395
|
*/
|
|
13530
|
-
function
|
|
13396
|
+
function EntityCardBinding({ entity, collection, onClick, selected, highlighted, onSelectionChange, selectionEnabled, size = "m" }) {
|
|
13531
13397
|
const authController = useAuthController();
|
|
13532
13398
|
const analyticsController = useAnalyticsController();
|
|
13533
13399
|
const slotKeys = useCollectionSlotKeys(collection, authController, useCustomizationController().propertyConfigs);
|
|
@@ -13646,13 +13512,13 @@ function EntityCard({ entity, collection, onClick, selected, highlighted, onSele
|
|
|
13646
13512
|
});
|
|
13647
13513
|
}
|
|
13648
13514
|
//#endregion
|
|
13649
|
-
//#region src/components/
|
|
13515
|
+
//#region src/components/CollectionViewBinding/CollectionCardViewBinding.tsx
|
|
13650
13516
|
/**
|
|
13651
13517
|
* Card grid view for displaying entities with infinite scroll.
|
|
13652
|
-
* Alternative to the
|
|
13518
|
+
* Alternative to the CollectionTableBinding for visual browsing.
|
|
13653
13519
|
*/
|
|
13654
|
-
function
|
|
13655
|
-
const ResolvedEntityCard = useComponentOverride("Collection.Card",
|
|
13520
|
+
function CollectionCardViewBinding({ collection, tableController, onEntityClick, selectionController, selectionEnabled = true, highlightedEntities, emptyComponent, onScroll, initialScroll, size = "m" }) {
|
|
13521
|
+
const ResolvedEntityCard = useComponentOverride("Collection.Card", EntityCardBinding);
|
|
13656
13522
|
const { data, dataLoading, noMoreToLoad, dataLoadingError, itemCount, setItemCount, pageSize = 50, paginationEnabled } = tableController;
|
|
13657
13523
|
const handleEntityClick = useCallback((entity) => {
|
|
13658
13524
|
onEntityClick?.(entity);
|
|
@@ -13702,7 +13568,7 @@ function EntityCollectionCardView({ collection, tableController, onEntityClick,
|
|
|
13702
13568
|
});
|
|
13703
13569
|
}
|
|
13704
13570
|
//#endregion
|
|
13705
|
-
//#region src/components/
|
|
13571
|
+
//#region src/components/CollectionViewBinding/CollectionListViewBinding.tsx
|
|
13706
13572
|
/**
|
|
13707
13573
|
* Get row padding/spacing classes based on size
|
|
13708
13574
|
*/
|
|
@@ -13823,7 +13689,7 @@ function formatDateValue(value) {
|
|
|
13823
13689
|
* - Column-sortable headers
|
|
13824
13690
|
* - Infinite scroll
|
|
13825
13691
|
*/
|
|
13826
|
-
function
|
|
13692
|
+
function CollectionListViewBinding({ collection, tableController, onEntityClick, selectionController, selectionEnabled = true, highlightedEntities, emptyComponent, size = "m", selectedEntityId, getActionsForEntity, path, openEntityMode }) {
|
|
13827
13693
|
const authController = useAuthController();
|
|
13828
13694
|
const customizationController = useCustomizationController();
|
|
13829
13695
|
const analyticsController = useAnalyticsController();
|
|
@@ -13903,7 +13769,17 @@ function EntityCollectionListView({ collection, tableController, onEntityClick,
|
|
|
13903
13769
|
subtitleKey,
|
|
13904
13770
|
"id"
|
|
13905
13771
|
]);
|
|
13906
|
-
allKeys.filter((k) =>
|
|
13772
|
+
allKeys.filter((k) => {
|
|
13773
|
+
if (usedKeys.has(k)) return false;
|
|
13774
|
+
const prop = resolvedCollection.properties[k];
|
|
13775
|
+
if (!prop) return false;
|
|
13776
|
+
if (prop.type === "string" && (prop.storage || prop.ui?.url === "image")) return false;
|
|
13777
|
+
if (prop.type === "array" && prop.of && !Array.isArray(prop.of)) {
|
|
13778
|
+
const inner = prop.of;
|
|
13779
|
+
if (inner.type === "string" && (inner.storage || inner.ui?.url === "image")) return false;
|
|
13780
|
+
}
|
|
13781
|
+
return true;
|
|
13782
|
+
}).forEach((key) => {
|
|
13907
13783
|
const prop = resolvedCollection.properties[key];
|
|
13908
13784
|
cols.push({
|
|
13909
13785
|
key,
|
|
@@ -14256,7 +14132,7 @@ var ListRow = React.memo(function ListRow({ entity, collection, onClick, selecte
|
|
|
14256
14132
|
path,
|
|
14257
14133
|
collection,
|
|
14258
14134
|
context,
|
|
14259
|
-
|
|
14135
|
+
sidePanelController: context?.sidePanelController,
|
|
14260
14136
|
selectionController,
|
|
14261
14137
|
openEntityMode: openEntityMode ?? collection?.openEntityMode ?? "full_screen"
|
|
14262
14138
|
});
|
|
@@ -14269,7 +14145,7 @@ var ListRow = React.memo(function ListRow({ entity, collection, onClick, selecte
|
|
|
14269
14145
|
});
|
|
14270
14146
|
});
|
|
14271
14147
|
//#endregion
|
|
14272
|
-
//#region src/components/
|
|
14148
|
+
//#region src/components/CollectionViewBinding/SplitListView.tsx
|
|
14273
14149
|
var PANEL_SIZE_KEY = "rebase_split_list_panel_size";
|
|
14274
14150
|
function getSavedPanelSize(path) {
|
|
14275
14151
|
try {
|
|
@@ -14298,7 +14174,7 @@ function savePanelSize(path, size) {
|
|
|
14298
14174
|
* State management:
|
|
14299
14175
|
* - The selected entity is driven by the URL path (e.g. /c/authors/14).
|
|
14300
14176
|
* `selectedEntityId` comes from props via RebaseRoute, NOT from internal state.
|
|
14301
|
-
* - Clicking
|
|
14177
|
+
* - Clicking a entity navigates to /c/authors/{id} via the standard onEntityClick handler.
|
|
14302
14178
|
* - Closing the detail navigates back to /c/authors.
|
|
14303
14179
|
*/
|
|
14304
14180
|
function SplitListView({ collection, tableController, onEntityClick: externalOnEntityClick, onNewClick: externalOnNewClick, selectionController, selectionEnabled = true, highlightedEntities, emptyComponent, onScroll, initialScroll, size = "m", path, parentCollectionSlugs, parentEntityIds, selectedEntityId, selectedTab, toolbar, children }) {
|
|
@@ -14428,7 +14304,7 @@ function SplitListView({ collection, tableController, onEntityClick: externalOnE
|
|
|
14428
14304
|
const detailPanel = renderedEntityId !== void 0 ? /* @__PURE__ */ jsx("div", {
|
|
14429
14305
|
className: cls("flex-1 flex flex-col min-w-0 h-full transition-all ease-out w-full", animationPhase === "entered" ? "opacity-100 translate-x-0" : largeLayout ? "opacity-0 translate-x-8" : "opacity-0 translate-x-1/3"),
|
|
14430
14306
|
style: { transitionDuration: `${TRANSITION_DURATION}ms` },
|
|
14431
|
-
children: /* @__PURE__ */ jsx(ErrorBoundary, { children: collection.defaultEntityAction === "view" && !isEditMode ? /* @__PURE__ */ jsx(
|
|
14307
|
+
children: /* @__PURE__ */ jsx(ErrorBoundary, { children: collection.defaultEntityAction === "view" && !isEditMode ? /* @__PURE__ */ jsx(DetailViewBinding, {
|
|
14432
14308
|
path,
|
|
14433
14309
|
collection,
|
|
14434
14310
|
entityId: renderedEntityId,
|
|
@@ -14449,7 +14325,7 @@ function SplitListView({ collection, tableController, onEntityClick: externalOnE
|
|
|
14449
14325
|
if (currentViewParam) entityUrl += `${entityUrl.includes("?") ? "&" : "?"}__view=${currentViewParam}`;
|
|
14450
14326
|
navigate(entityUrl);
|
|
14451
14327
|
}
|
|
14452
|
-
}, String(renderedEntityId)) : /* @__PURE__ */ jsx(
|
|
14328
|
+
}, String(renderedEntityId)) : /* @__PURE__ */ jsx(EditViewBinding, {
|
|
14453
14329
|
path,
|
|
14454
14330
|
collection,
|
|
14455
14331
|
entityId: renderedEntityId,
|
|
@@ -14489,16 +14365,16 @@ function SplitListView({ collection, tableController, onEntityClick: externalOnE
|
|
|
14489
14365
|
});
|
|
14490
14366
|
}
|
|
14491
14367
|
//#endregion
|
|
14492
|
-
//#region src/components/
|
|
14368
|
+
//#region src/components/CollectionViewBinding/BoardCardBinding.tsx
|
|
14493
14369
|
/**
|
|
14494
|
-
* Compact card component for displaying
|
|
14370
|
+
* Compact card component for displaying a entity in a Kanban board.
|
|
14495
14371
|
* Uses the shared slot system for consistent preview rendering.
|
|
14496
14372
|
*
|
|
14497
14373
|
* Selection UX: The checkbox overlays on top of the image/icon thumbnail area,
|
|
14498
14374
|
* revealed on card hover or when the card is selected. This keeps the card
|
|
14499
14375
|
* layout clean while providing intuitive selection affordance.
|
|
14500
14376
|
*/
|
|
14501
|
-
function
|
|
14377
|
+
function BoardCardBindingInner({ item, isDragging, isGroupedOver, style, collection, onClick, selected, onSelectionChange, selectionEnabled = false }) {
|
|
14502
14378
|
const entity = item.data;
|
|
14503
14379
|
const slotKeys = useCollectionSlotKeys(collection, useAuthController(), useCustomizationController().propertyConfigs);
|
|
14504
14380
|
const slots = useMemo(() => resolveEntitySlots(entity, collection, slotKeys), [
|
|
@@ -14635,9 +14511,9 @@ function EntityBoardCardInner({ item, isDragging, isGroupedOver, style, collecti
|
|
|
14635
14511
|
})
|
|
14636
14512
|
});
|
|
14637
14513
|
}
|
|
14638
|
-
var
|
|
14514
|
+
var BoardCardBinding = memo(BoardCardBindingInner);
|
|
14639
14515
|
//#endregion
|
|
14640
|
-
//#region src/components/
|
|
14516
|
+
//#region src/components/CollectionViewBinding/useBoardDataController.tsx
|
|
14641
14517
|
var DEFAULT_PAGE_SIZE$1 = 20;
|
|
14642
14518
|
/**
|
|
14643
14519
|
* Shallow equality for entity value records.
|
|
@@ -14761,19 +14637,11 @@ function useBoardDataController({ fullPath, collection, columnProperty, columns,
|
|
|
14761
14637
|
}));
|
|
14762
14638
|
return;
|
|
14763
14639
|
}
|
|
14764
|
-
const
|
|
14765
|
-
|
|
14766
|
-
|
|
14767
|
-
|
|
14768
|
-
|
|
14769
|
-
let stringVal;
|
|
14770
|
-
if (Array.isArray(val)) stringVal = `(${val.join(",")})`;
|
|
14771
|
-
else stringVal = String(val);
|
|
14772
|
-
whereMap[key] = `${postgrestOp}.${stringVal}`;
|
|
14773
|
-
}
|
|
14774
|
-
});
|
|
14775
|
-
whereMap[currentColumnProperty] = `eq.${column}`;
|
|
14776
|
-
const orderByParam = currentOrderProperty ? `${currentOrderProperty}:asc` : void 0;
|
|
14640
|
+
const whereFilter = {
|
|
14641
|
+
...currentFilterValues ?? {},
|
|
14642
|
+
[currentColumnProperty]: ["==", column]
|
|
14643
|
+
};
|
|
14644
|
+
const orderByParam = currentOrderProperty ? [currentOrderProperty, "asc"] : void 0;
|
|
14777
14645
|
setColumnData((prev) => ({
|
|
14778
14646
|
...prev,
|
|
14779
14647
|
[column]: {
|
|
@@ -14824,12 +14692,21 @@ function useBoardDataController({ fullPath, collection, columnProperty, columns,
|
|
|
14824
14692
|
return valA < valB ? -1 : valA > valB ? 1 : 0;
|
|
14825
14693
|
});
|
|
14826
14694
|
if (currentCollection.callbacks?.afterRead) try {
|
|
14827
|
-
processed = await Promise.all(processed.map((entity) =>
|
|
14828
|
-
|
|
14829
|
-
|
|
14830
|
-
|
|
14831
|
-
|
|
14832
|
-
|
|
14695
|
+
processed = await Promise.all(processed.map(async (entity) => {
|
|
14696
|
+
const processedRow = await currentCollection.callbacks.afterRead({
|
|
14697
|
+
collection: currentCollection,
|
|
14698
|
+
path: currentResolvedPath,
|
|
14699
|
+
row: {
|
|
14700
|
+
id: entity.id,
|
|
14701
|
+
...entity.values
|
|
14702
|
+
},
|
|
14703
|
+
context: currentContext
|
|
14704
|
+
});
|
|
14705
|
+
return {
|
|
14706
|
+
...entity,
|
|
14707
|
+
values: processedRow
|
|
14708
|
+
};
|
|
14709
|
+
}));
|
|
14833
14710
|
} catch (e) {
|
|
14834
14711
|
console.error("Error in afterRead callback:", e);
|
|
14835
14712
|
}
|
|
@@ -14881,13 +14758,13 @@ function useBoardDataController({ fullPath, collection, columnProperty, columns,
|
|
|
14881
14758
|
const accessor = currentDataClient.collection(currentResolvedPath);
|
|
14882
14759
|
if (accessor.listen) {
|
|
14883
14760
|
const unsubscribe = accessor.listen({
|
|
14884
|
-
where:
|
|
14761
|
+
where: whereFilter,
|
|
14885
14762
|
limit: itemCount,
|
|
14886
14763
|
orderBy: orderByParam
|
|
14887
14764
|
}, (res) => onUpdate(res.data), onError);
|
|
14888
14765
|
unsubscribersRef.current[column] = unsubscribe;
|
|
14889
14766
|
} else accessor.find({
|
|
14890
|
-
where:
|
|
14767
|
+
where: whereFilter,
|
|
14891
14768
|
limit: itemCount,
|
|
14892
14769
|
orderBy: orderByParam
|
|
14893
14770
|
}).then((res) => onUpdate(res.data)).catch(onError);
|
|
@@ -14916,19 +14793,11 @@ function useBoardDataController({ fullPath, collection, columnProperty, columns,
|
|
|
14916
14793
|
if (isColumnExcludedByFilter(column, currentFilterValues, currentColumnProperty)) return;
|
|
14917
14794
|
const accessor = currentDataClient.collection(currentResolvedPath);
|
|
14918
14795
|
if (accessor.count) {
|
|
14919
|
-
const
|
|
14920
|
-
|
|
14921
|
-
|
|
14922
|
-
|
|
14923
|
-
|
|
14924
|
-
let stringVal;
|
|
14925
|
-
if (Array.isArray(val)) stringVal = `(${val.join(",")})`;
|
|
14926
|
-
else stringVal = String(val);
|
|
14927
|
-
whereMap[key] = `${postgrestOp}.${stringVal}`;
|
|
14928
|
-
}
|
|
14929
|
-
});
|
|
14930
|
-
whereMap[currentColumnProperty] = `eq.${column}`;
|
|
14931
|
-
accessor.count({ where: whereMap }).then((count) => {
|
|
14796
|
+
const whereFilter = {
|
|
14797
|
+
...currentFilterValues ?? {},
|
|
14798
|
+
[currentColumnProperty]: ["==", column]
|
|
14799
|
+
};
|
|
14800
|
+
accessor.count({ where: whereFilter }).then((count) => {
|
|
14932
14801
|
if (isCleaningUpRef.current) return;
|
|
14933
14802
|
setColumnData((prev) => ({
|
|
14934
14803
|
...prev,
|
|
@@ -15111,7 +14980,7 @@ function useBoardDataController({ fullPath, collection, columnProperty, columns,
|
|
|
15111
14980
|
]);
|
|
15112
14981
|
}
|
|
15113
14982
|
//#endregion
|
|
15114
|
-
//#region src/components/
|
|
14983
|
+
//#region src/components/CollectionViewBinding/hooks/useKanbanDragAndDrop.ts
|
|
15115
14984
|
function useKanbanDragAndDrop({ collection, fullPath, columnProperty, orderProperty, dataClient, context, boardDataController, analyticsController }) {
|
|
15116
14985
|
const handleItemsReorder = useCallback(async (items, moveInfo) => {
|
|
15117
14986
|
const entity = items.find((item) => item.id === moveInfo?.itemId)?.data;
|
|
@@ -15184,15 +15053,15 @@ function useKanbanDragAndDrop({ collection, fullPath, columnProperty, orderPrope
|
|
|
15184
15053
|
return useMemo(() => ({ handleItemsReorder }), [handleItemsReorder]);
|
|
15185
15054
|
}
|
|
15186
15055
|
//#endregion
|
|
15187
|
-
//#region src/components/
|
|
15056
|
+
//#region src/components/CollectionViewBinding/CollectionBoardViewBinding.tsx
|
|
15188
15057
|
/**
|
|
15189
15058
|
* Kanban board view for displaying entities grouped by a string enum property.
|
|
15190
15059
|
*/
|
|
15191
|
-
function
|
|
15060
|
+
function CollectionBoardViewBinding({ collection, tableController, fullPath, parentCollectionSlugs = [], parentEntityIds = [], columnProperty, onEntityClick, selectionController, selectionEnabled = true, highlightedEntities, emptyComponent, deletedEntities }) {
|
|
15192
15061
|
const customizationController = useCustomizationController();
|
|
15193
15062
|
const context = useRebaseContext();
|
|
15194
15063
|
const dataClient = useData();
|
|
15195
|
-
const
|
|
15064
|
+
const sidePanelController = useSidePanel();
|
|
15196
15065
|
const analyticsController = useAnalyticsController();
|
|
15197
15066
|
const { t } = useTranslation();
|
|
15198
15067
|
const plugins = customizationController.plugins ?? [];
|
|
@@ -15336,7 +15205,7 @@ function EntityCollectionBoardView({ collection, tableController, fullPath, pare
|
|
|
15336
15205
|
completed++;
|
|
15337
15206
|
if (completed === 2) setMissingOrderCount(Math.max(0, totalCount - orderedCount));
|
|
15338
15207
|
}).catch((e) => console.warn("Failed to get total count:", e));
|
|
15339
|
-
accessor.count({ where: { [orderProperty]: "
|
|
15208
|
+
accessor.count({ where: { [orderProperty]: ["!=", null] } }).then((count) => {
|
|
15340
15209
|
orderedCount = count;
|
|
15341
15210
|
completed++;
|
|
15342
15211
|
if (completed === 2) setMissingOrderCount(Math.max(0, totalCount - orderedCount));
|
|
@@ -15477,7 +15346,7 @@ function EntityCollectionBoardView({ collection, tableController, fullPath, pare
|
|
|
15477
15346
|
handleSelectionChangeRef.current(entity, sel);
|
|
15478
15347
|
}, []);
|
|
15479
15348
|
const ItemComponent = useMemo(() => {
|
|
15480
|
-
const Comp = (props) => /* @__PURE__ */ jsx(
|
|
15349
|
+
const Comp = (props) => /* @__PURE__ */ jsx(BoardCardBinding, {
|
|
15481
15350
|
...props,
|
|
15482
15351
|
collection: collectionRef.current,
|
|
15483
15352
|
onClick: stableOnClick,
|
|
@@ -15600,7 +15469,7 @@ function EntityCollectionBoardView({ collection, tableController, fullPath, pare
|
|
|
15600
15469
|
path: fullPath,
|
|
15601
15470
|
column
|
|
15602
15471
|
});
|
|
15603
|
-
|
|
15472
|
+
sidePanelController.open({
|
|
15604
15473
|
path: fullPath,
|
|
15605
15474
|
collection,
|
|
15606
15475
|
entityId: void 0,
|
|
@@ -15643,7 +15512,7 @@ function EntityCollectionBoardView({ collection, tableController, fullPath, pare
|
|
|
15643
15512
|
});
|
|
15644
15513
|
}
|
|
15645
15514
|
//#endregion
|
|
15646
|
-
//#region src/components/
|
|
15515
|
+
//#region src/components/CollectionViewBinding/ViewModeToggle.tsx
|
|
15647
15516
|
var ALL_VIEW_MODES = [
|
|
15648
15517
|
"list",
|
|
15649
15518
|
"table",
|
|
@@ -15768,7 +15637,7 @@ function ViewModeToggle({ viewMode = "table", onViewModeChange, enabledViews = A
|
|
|
15768
15637
|
});
|
|
15769
15638
|
}
|
|
15770
15639
|
//#endregion
|
|
15771
|
-
//#region src/components/
|
|
15640
|
+
//#region src/components/CollectionTableBinding/internal/popup_field/useDraggable.tsx
|
|
15772
15641
|
/** Tracks events originating inside the inner (non-draggable) area. */
|
|
15773
15642
|
var innerClicked = /* @__PURE__ */ new WeakSet();
|
|
15774
15643
|
function useDraggable({ containerRef, innerRef, x, y, onMove }) {
|
|
@@ -15832,7 +15701,7 @@ function useDraggable({ containerRef, innerRef, x, y, onMove }) {
|
|
|
15832
15701
|
]);
|
|
15833
15702
|
}
|
|
15834
15703
|
//#endregion
|
|
15835
|
-
//#region src/components/
|
|
15704
|
+
//#region src/components/CollectionTableBinding/internal/popup_field/useWindowSize.tsx
|
|
15836
15705
|
function useWindowSize() {
|
|
15837
15706
|
const [size, setSize] = useState({
|
|
15838
15707
|
width: 0,
|
|
@@ -15852,7 +15721,7 @@ function useWindowSize() {
|
|
|
15852
15721
|
return size;
|
|
15853
15722
|
}
|
|
15854
15723
|
//#endregion
|
|
15855
|
-
//#region src/components/
|
|
15724
|
+
//#region src/components/CollectionTableBinding/internal/popup_field/PopupFormField.tsx
|
|
15856
15725
|
function PopupFormField(props) {
|
|
15857
15726
|
if (!props.open) return null;
|
|
15858
15727
|
return /* @__PURE__ */ jsx(PopupFormFieldLoading, { ...props });
|
|
@@ -16132,13 +16001,14 @@ function ClearFilterSortButton({ tableController, enabled }) {
|
|
|
16132
16001
|
return null;
|
|
16133
16002
|
}
|
|
16134
16003
|
//#endregion
|
|
16135
|
-
//#region src/components/
|
|
16004
|
+
//#region src/components/CollectionViewBinding/FiltersDialog.tsx
|
|
16136
16005
|
/**
|
|
16137
16006
|
* Dialog that displays all filterable properties from a collection
|
|
16138
16007
|
* and allows setting filter values for each.
|
|
16139
16008
|
*/
|
|
16140
16009
|
function FiltersDialog({ open, onOpenChange, properties, filterValues, setFilterValues, fixedFilter }) {
|
|
16141
16010
|
const { t } = useTranslation();
|
|
16011
|
+
const engine = useCollectionScope()?.engine;
|
|
16142
16012
|
const [localFilters, setLocalFilters] = useState(filterValues ?? {});
|
|
16143
16013
|
const [hiddenFields, setHiddenFields] = useState({});
|
|
16144
16014
|
React.useEffect(() => {
|
|
@@ -16148,17 +16018,22 @@ function FiltersDialog({ open, onOpenChange, properties, filterValues, setFilter
|
|
|
16148
16018
|
return Object.entries(properties).filter(([key, property]) => {
|
|
16149
16019
|
if (!property) return false;
|
|
16150
16020
|
if (fixedFilter && key in fixedFilter) return false;
|
|
16151
|
-
const
|
|
16152
|
-
|
|
16153
|
-
|
|
16154
|
-
|
|
16155
|
-
|
|
16156
|
-
|
|
16157
|
-
|
|
16158
|
-
|
|
16159
|
-
|
|
16021
|
+
const isArray = property.type === "array";
|
|
16022
|
+
const ofProp = isArray && "of" in property ? property.of : void 0;
|
|
16023
|
+
const baseProperty = isArray ? Array.isArray(ofProp) ? ofProp[0] : ofProp : property;
|
|
16024
|
+
if (!baseProperty) return false;
|
|
16025
|
+
if (baseProperty.ui?.Filter) return true;
|
|
16026
|
+
return resolveFilterOperators({
|
|
16027
|
+
property: baseProperty,
|
|
16028
|
+
isArray,
|
|
16029
|
+
engine
|
|
16030
|
+
}).length > 0;
|
|
16160
16031
|
});
|
|
16161
|
-
}, [
|
|
16032
|
+
}, [
|
|
16033
|
+
properties,
|
|
16034
|
+
fixedFilter,
|
|
16035
|
+
engine
|
|
16036
|
+
]);
|
|
16162
16037
|
const handleFilterChange = useCallback((propertyKey, value) => {
|
|
16163
16038
|
setLocalFilters((prev) => {
|
|
16164
16039
|
const newFilters = { ...prev };
|
|
@@ -16191,55 +16066,23 @@ function FiltersDialog({ open, onOpenChange, properties, filterValues, setFilter
|
|
|
16191
16066
|
const isAnyFieldHidden = Object.values(hiddenFields).some((hidden) => hidden);
|
|
16192
16067
|
const activeFilterCount = Object.keys(localFilters).length;
|
|
16193
16068
|
const renderFilterField = useCallback((propertyKey, property) => {
|
|
16194
|
-
const isArray = property.type === "array";
|
|
16195
|
-
const ofProp = isArray && "of" in property ? property.of : void 0;
|
|
16196
|
-
const baseProperty = isArray ? Array.isArray(ofProp) ? ofProp[0] : ofProp : property;
|
|
16197
|
-
if (!baseProperty) return null;
|
|
16198
16069
|
const filterValue = localFilters[propertyKey];
|
|
16199
16070
|
const setValue = (value) => handleFilterChange(propertyKey, value);
|
|
16200
|
-
|
|
16071
|
+
return /* @__PURE__ */ jsx(FilterFieldBinding, {
|
|
16072
|
+
propertyKey,
|
|
16073
|
+
property,
|
|
16074
|
+
engine,
|
|
16201
16075
|
value: filterValue,
|
|
16202
16076
|
setValue,
|
|
16203
|
-
name: propertyKey,
|
|
16204
|
-
isArray,
|
|
16205
|
-
path: baseProperty.path,
|
|
16206
|
-
title: property.name,
|
|
16207
|
-
includeId: baseProperty.includeId,
|
|
16208
|
-
previewProperties: baseProperty.ui?.previewProperties,
|
|
16209
16077
|
hidden: hiddenFields[propertyKey] ?? false,
|
|
16210
16078
|
setHidden: (hidden) => setHiddenForField(propertyKey, hidden)
|
|
16211
16079
|
});
|
|
16212
|
-
else if (baseProperty.type === "number" || baseProperty.type === "string") {
|
|
16213
|
-
const enumValues = baseProperty.enum ? enumToObjectEntries(baseProperty.enum) : void 0;
|
|
16214
|
-
return /* @__PURE__ */ jsx(StringNumberFilterField, {
|
|
16215
|
-
value: filterValue,
|
|
16216
|
-
setValue,
|
|
16217
|
-
name: propertyKey,
|
|
16218
|
-
type: baseProperty.type,
|
|
16219
|
-
isArray,
|
|
16220
|
-
enumValues,
|
|
16221
|
-
title: property.name
|
|
16222
|
-
});
|
|
16223
|
-
} else if (baseProperty.type === "boolean") return /* @__PURE__ */ jsx(BooleanFilterField, {
|
|
16224
|
-
value: filterValue,
|
|
16225
|
-
setValue,
|
|
16226
|
-
name: propertyKey,
|
|
16227
|
-
title: property.name
|
|
16228
|
-
});
|
|
16229
|
-
else if (baseProperty.type === "date") return /* @__PURE__ */ jsx(DateTimeFilterField, {
|
|
16230
|
-
value: filterValue,
|
|
16231
|
-
setValue,
|
|
16232
|
-
name: propertyKey,
|
|
16233
|
-
mode: baseProperty.mode,
|
|
16234
|
-
isArray,
|
|
16235
|
-
title: property.name
|
|
16236
|
-
});
|
|
16237
|
-
return null;
|
|
16238
16080
|
}, [
|
|
16239
16081
|
localFilters,
|
|
16240
16082
|
handleFilterChange,
|
|
16241
16083
|
hiddenFields,
|
|
16242
|
-
setHiddenForField
|
|
16084
|
+
setHiddenForField,
|
|
16085
|
+
engine
|
|
16243
16086
|
]);
|
|
16244
16087
|
return /* @__PURE__ */ jsxs(Dialog, {
|
|
16245
16088
|
open,
|
|
@@ -16303,7 +16146,7 @@ function FiltersDialog({ open, onOpenChange, properties, filterValues, setFilter
|
|
|
16303
16146
|
});
|
|
16304
16147
|
}
|
|
16305
16148
|
//#endregion
|
|
16306
|
-
//#region src/components/
|
|
16149
|
+
//#region src/components/CollectionViewBinding/FilterPresetsButton.tsx
|
|
16307
16150
|
/**
|
|
16308
16151
|
* Maximum number of presets shown as inline toggle chips before the
|
|
16309
16152
|
* rest are collapsed into an overflow menu.
|
|
@@ -16496,8 +16339,8 @@ function FilterPresetsButton({ filterPresets, tableController, compact }) {
|
|
|
16496
16339
|
});
|
|
16497
16340
|
}
|
|
16498
16341
|
//#endregion
|
|
16499
|
-
//#region src/components/
|
|
16500
|
-
function
|
|
16342
|
+
//#region src/components/CollectionViewBinding/CollectionViewStartActions.tsx
|
|
16343
|
+
function CollectionViewStartActions({ collection, relativePath, parentCollectionSlugs, parentEntityIds, path, selectionController, tableController, collectionEntitiesCount, resolvedProperties, compact, openNewDocument }) {
|
|
16501
16344
|
const context = useCMSContext();
|
|
16502
16345
|
const largeLayout = useLargeLayout();
|
|
16503
16346
|
const { t } = useTranslation();
|
|
@@ -16586,7 +16429,7 @@ function EntityCollectionViewStartActions({ collection, relativePath, parentColl
|
|
|
16586
16429
|
] });
|
|
16587
16430
|
}
|
|
16588
16431
|
//#endregion
|
|
16589
|
-
//#region src/components/
|
|
16432
|
+
//#region src/components/CollectionViewBinding/CollectionViewBinding.tsx
|
|
16590
16433
|
var EMPTY_ARRAY = [];
|
|
16591
16434
|
var DEFAULT_ENTITY_OPEN_MODE = "split";
|
|
16592
16435
|
function getOpenEntityMode(viewMode, configuredMode) {
|
|
@@ -16596,20 +16439,20 @@ function getOpenEntityMode(viewMode, configuredMode) {
|
|
|
16596
16439
|
return "split";
|
|
16597
16440
|
}
|
|
16598
16441
|
/**
|
|
16599
|
-
* This component is in charge of binding a driver path with an {@link
|
|
16442
|
+
* This component is in charge of binding a driver path with an {@link CollectionConfig}
|
|
16600
16443
|
* where it's configuration is defined. It includes an infinite scrolling table
|
|
16601
16444
|
* and a 'Add' new entities button,
|
|
16602
16445
|
*
|
|
16603
16446
|
* This component is the default one used for displaying entity collections
|
|
16604
16447
|
* and is in charge of generating all the specific actions and customization
|
|
16605
|
-
* of the lower level {@link
|
|
16448
|
+
* of the lower level {@link CollectionTableBinding}
|
|
16606
16449
|
*
|
|
16607
16450
|
* Please **note** that you only need to use this component if you are building
|
|
16608
16451
|
* a custom view. If you just need to create a default view you can do it
|
|
16609
16452
|
* exclusively with config options.
|
|
16610
16453
|
*
|
|
16611
16454
|
* If you need a lower level implementation with more granular options, you
|
|
16612
|
-
* can use {@link
|
|
16455
|
+
* can use {@link CollectionTableBinding}.
|
|
16613
16456
|
*
|
|
16614
16457
|
* If you need a generic table that is not bound to the driver or entities and
|
|
16615
16458
|
* properties at all, you can check {@link VirtualTable}
|
|
@@ -16619,15 +16462,15 @@ function getOpenEntityMode(viewMode, configuredMode) {
|
|
|
16619
16462
|
|
|
16620
16463
|
* @group Components
|
|
16621
16464
|
*/
|
|
16622
|
-
var
|
|
16465
|
+
var CollectionViewBindingInner = React.memo(function CollectionViewBindingInner({ path: pathProp, parentCollectionSlugs, parentEntityIds, isSubCollection, className, updateUrl, selectedEntityId: selectedEntityIdProp, selectedTab: selectedTabProp, ...collectionProp }) {
|
|
16623
16466
|
const { t } = useTranslation();
|
|
16624
16467
|
const context = useCMSContext();
|
|
16625
16468
|
const collectionRegistry = useCollectionRegistryController();
|
|
16626
16469
|
const urlController = useUrlController();
|
|
16627
16470
|
const breadcrumbs = useBreadcrumbsController();
|
|
16628
|
-
const path = pathProp ?? collectionProp
|
|
16471
|
+
const path = pathProp ?? getCollectionDataPath(collectionProp);
|
|
16629
16472
|
const dataClient = useData();
|
|
16630
|
-
const
|
|
16473
|
+
const sidePanelController = useSidePanel();
|
|
16631
16474
|
useAuthController();
|
|
16632
16475
|
const userConfigPersistence = useUserConfigurationPersistence();
|
|
16633
16476
|
const analyticsController = useAnalyticsController();
|
|
@@ -16748,14 +16591,14 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
16748
16591
|
navigateToEntity({
|
|
16749
16592
|
navigation: urlController,
|
|
16750
16593
|
path: path ?? clickedEntity.path,
|
|
16751
|
-
|
|
16594
|
+
sidePanelController,
|
|
16752
16595
|
openEntityMode,
|
|
16753
16596
|
collection,
|
|
16754
16597
|
entityId: clickedEntity.id,
|
|
16755
16598
|
replace: openEntityMode === "split" && selectedEntityIdProp !== void 0
|
|
16756
16599
|
});
|
|
16757
16600
|
}, [
|
|
16758
|
-
|
|
16601
|
+
sidePanelController,
|
|
16759
16602
|
openEntityMode,
|
|
16760
16603
|
selectedEntityIdProp,
|
|
16761
16604
|
path,
|
|
@@ -16770,11 +16613,11 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
16770
16613
|
collection,
|
|
16771
16614
|
entityId: void 0,
|
|
16772
16615
|
path,
|
|
16773
|
-
|
|
16616
|
+
sidePanelController,
|
|
16774
16617
|
navigation: urlController,
|
|
16775
16618
|
onClose: unselectNavigatedEntity
|
|
16776
16619
|
});
|
|
16777
|
-
}, [path,
|
|
16620
|
+
}, [path, sidePanelController]);
|
|
16778
16621
|
const openNewDocument = useCallback((defaultValues) => {
|
|
16779
16622
|
const collection = collectionRef.current;
|
|
16780
16623
|
analyticsController.onAnalyticsEvent?.("new_entity_click", { path });
|
|
@@ -16784,13 +16627,13 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
16784
16627
|
entityId: void 0,
|
|
16785
16628
|
defaultValues,
|
|
16786
16629
|
path,
|
|
16787
|
-
|
|
16630
|
+
sidePanelController,
|
|
16788
16631
|
navigation: urlController,
|
|
16789
16632
|
onClose: unselectNavigatedEntity
|
|
16790
16633
|
});
|
|
16791
16634
|
}, [
|
|
16792
16635
|
path,
|
|
16793
|
-
|
|
16636
|
+
sidePanelController,
|
|
16794
16637
|
openEntityMode,
|
|
16795
16638
|
urlController,
|
|
16796
16639
|
unselectNavigatedEntity
|
|
@@ -16989,7 +16832,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
16989
16832
|
selectedTab: subcollection.slug,
|
|
16990
16833
|
path,
|
|
16991
16834
|
navigation: urlController,
|
|
16992
|
-
|
|
16835
|
+
sidePanelController
|
|
16993
16836
|
});
|
|
16994
16837
|
},
|
|
16995
16838
|
children: subcollection.name
|
|
@@ -17000,7 +16843,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
17000
16843
|
}, [
|
|
17001
16844
|
collection,
|
|
17002
16845
|
path,
|
|
17003
|
-
|
|
16846
|
+
sidePanelController
|
|
17004
16847
|
]);
|
|
17005
16848
|
const updateLastDeleteTimestamp = useCallback(() => {
|
|
17006
16849
|
setLastDeleteTimestamp(Date.now());
|
|
@@ -17031,7 +16874,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
17031
16874
|
return (largeLayout ? 80 + actionsWidth : 70 + actionsWidth) + (collapsedActions.length > 0 ? largeLayout ? 40 : 30 : 0);
|
|
17032
16875
|
}, [getActionsForEntity, largeLayout]);
|
|
17033
16876
|
const tableRowActionsBuilder = useCallback(({ entity, size, width, frozen }) => {
|
|
17034
|
-
return /* @__PURE__ */ jsx(
|
|
16877
|
+
return /* @__PURE__ */ jsx(CollectionRowActions, {
|
|
17035
16878
|
entity,
|
|
17036
16879
|
width,
|
|
17037
16880
|
frozen,
|
|
@@ -17144,8 +16987,8 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
17144
16987
|
const isSearching = !!tableController.searchString;
|
|
17145
16988
|
const isFilteredOrSorted = tableController.filterValues !== void 0 || tableController.sortBy !== void 0 || isSearching;
|
|
17146
16989
|
const ResolvedEmptyState = useComponentOverride("Collection.EmptyState", DefaultCollectionEmptyState);
|
|
17147
|
-
const ResolvedCollectionActions = useComponentOverride("Collection.Actions",
|
|
17148
|
-
const ResolvedCollectionTable = useComponentOverride("Collection.Table",
|
|
16990
|
+
const ResolvedCollectionActions = useComponentOverride("Collection.Actions", CollectionViewActions);
|
|
16991
|
+
const ResolvedCollectionTable = useComponentOverride("Collection.Table", CollectionTableBinding);
|
|
17149
16992
|
const emptyComponent = pluginEmptyStates.length > 0 ? /* @__PURE__ */ jsx(Fragment, { children: pluginEmptyStates }) : /* @__PURE__ */ jsx(ResolvedEmptyState, {
|
|
17150
16993
|
canCreate: canCreateEntities && !isFilteredOrSorted,
|
|
17151
16994
|
onNewClick,
|
|
@@ -17158,13 +17001,13 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
17158
17001
|
onTextSearch: tableController.setSearchString,
|
|
17159
17002
|
initialSearchText: tableController.searchString,
|
|
17160
17003
|
viewModeToggle: viewModeToggleElement,
|
|
17161
|
-
actionsStart: /* @__PURE__ */ jsx(
|
|
17004
|
+
actionsStart: /* @__PURE__ */ jsx(CollectionViewStartActions, {
|
|
17162
17005
|
parentCollectionSlugs: parentCollectionSlugs ?? EMPTY_ARRAY,
|
|
17163
17006
|
parentEntityIds: parentEntityIds ?? EMPTY_ARRAY,
|
|
17164
17007
|
collection,
|
|
17165
17008
|
tableController,
|
|
17166
17009
|
path,
|
|
17167
|
-
relativePath: collection
|
|
17010
|
+
relativePath: getCollectionDataPath(collection),
|
|
17168
17011
|
selectionController: usedSelectionController,
|
|
17169
17012
|
collectionEntitiesCount: docsCount ?? void 0,
|
|
17170
17013
|
resolvedProperties: resolvedCollection.properties,
|
|
@@ -17180,7 +17023,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
17180
17023
|
onNewClick,
|
|
17181
17024
|
openNewDocument,
|
|
17182
17025
|
path,
|
|
17183
|
-
relativePath: collection
|
|
17026
|
+
relativePath: getCollectionDataPath(collection),
|
|
17184
17027
|
selectionController: usedSelectionController,
|
|
17185
17028
|
selectionEnabled: activeSelectionEnabled,
|
|
17186
17029
|
collectionEntitiesCount: docsCount ?? void 0,
|
|
@@ -17188,7 +17031,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
17188
17031
|
children: pluginToolbarWidgets
|
|
17189
17032
|
})
|
|
17190
17033
|
});
|
|
17191
|
-
const innerView = viewMode === "kanban" ? /* @__PURE__ */ jsx(
|
|
17034
|
+
const innerView = viewMode === "kanban" ? /* @__PURE__ */ jsx(CollectionBoardViewBinding, {
|
|
17192
17035
|
collection,
|
|
17193
17036
|
tableController,
|
|
17194
17037
|
fullPath: path,
|
|
@@ -17201,7 +17044,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
17201
17044
|
highlightedEntities: highlightedEntity ? [highlightedEntity] : [],
|
|
17202
17045
|
deletedEntities,
|
|
17203
17046
|
emptyComponent
|
|
17204
|
-
}, `kanban-view-${path}-${selectedKanbanProperty}`) : viewMode === "cards" ? /* @__PURE__ */ jsx(
|
|
17047
|
+
}, `kanban-view-${path}-${selectedKanbanProperty}`) : viewMode === "cards" ? /* @__PURE__ */ jsx(CollectionCardViewBinding, {
|
|
17205
17048
|
collection,
|
|
17206
17049
|
tableController,
|
|
17207
17050
|
onEntityClick,
|
|
@@ -17212,7 +17055,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
17212
17055
|
initialScroll: tableController.initialScroll,
|
|
17213
17056
|
size: cardSize,
|
|
17214
17057
|
emptyComponent
|
|
17215
|
-
}, `cards-view-${path}`) : viewMode === "list" ? /* @__PURE__ */ jsx(
|
|
17058
|
+
}, `cards-view-${path}`) : viewMode === "list" ? /* @__PURE__ */ jsx(CollectionListViewBinding, {
|
|
17216
17059
|
collection,
|
|
17217
17060
|
tableController,
|
|
17218
17061
|
onEntityClick,
|
|
@@ -17315,7 +17158,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
17315
17158
|
children: pluginInsights
|
|
17316
17159
|
})
|
|
17317
17160
|
}),
|
|
17318
|
-
/* @__PURE__ */ jsx(
|
|
17161
|
+
/* @__PURE__ */ jsx(CollectionListViewBinding, {
|
|
17319
17162
|
collection,
|
|
17320
17163
|
tableController,
|
|
17321
17164
|
onEntityClick,
|
|
@@ -17388,13 +17231,13 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
|
|
|
17388
17231
|
}, (a, b) => {
|
|
17389
17232
|
return deepEqual(a.path, b.path) && deepEqual(a.parentCollectionSlugs, b.parentCollectionSlugs) && deepEqual(a.parentEntityIds, b.parentEntityIds) && deepEqual(a.isSubCollection, b.isSubCollection) && deepEqual(a.className, b.className) && deepEqual(a.properties, b.properties) && deepEqual(a.propertiesOrder, b.propertiesOrder) && deepEqual(a.hideIdFromCollection, b.hideIdFromCollection) && deepEqual(a.inlineEditing, b.inlineEditing) && deepEqual(a.selectionEnabled, b.selectionEnabled) && deepEqual(a.selectionController, b.selectionController) && deepEqual(a.Actions, b.Actions) && deepEqual(a.defaultSize, b.defaultSize) && deepEqual(a.includeJsonView, b.includeJsonView) && deepEqual(a.additionalFields, b.additionalFields) && deepEqual(a.sideDialogWidth, b.sideDialogWidth) && deepEqual(a.openEntityMode, b.openEntityMode) && deepEqual(a.exportable, b.exportable) && deepEqual(a.history, b.history) && deepEqual(a.fixedFilter, b.fixedFilter) && deepEqual(a.selectedEntityId, b.selectedEntityId) && deepEqual(a.selectedTab, b.selectedTab);
|
|
17390
17233
|
});
|
|
17391
|
-
var
|
|
17234
|
+
var CollectionViewBinding = React.memo(function CollectionViewBinding(props) {
|
|
17392
17235
|
const collectionRegistry = useCollectionRegistryController();
|
|
17393
17236
|
const path = props.path ?? props.slug;
|
|
17394
17237
|
const collection = collectionRegistry.getCollection(path) ?? props;
|
|
17395
|
-
const content = /* @__PURE__ */ jsx(
|
|
17396
|
-
if (collection
|
|
17397
|
-
|
|
17238
|
+
const content = /* @__PURE__ */ jsx(CollectionViewBindingInner, { ...props });
|
|
17239
|
+
if (collection) return /* @__PURE__ */ jsx(CollectionScopeProvider, {
|
|
17240
|
+
collection,
|
|
17398
17241
|
children: content
|
|
17399
17242
|
});
|
|
17400
17243
|
return content;
|
|
@@ -17445,19 +17288,8 @@ function EntitiesCount({ path, collection, filter, sortBy, onCountChange }) {
|
|
|
17445
17288
|
return;
|
|
17446
17289
|
}
|
|
17447
17290
|
let cancelled = false;
|
|
17448
|
-
const
|
|
17449
|
-
|
|
17450
|
-
if (value && Array.isArray(value)) {
|
|
17451
|
-
const [op, val] = value;
|
|
17452
|
-
const postgrestOp = op === "==" ? "eq" : op === "!=" ? "neq" : op === ">" ? "gt" : op === ">=" ? "gte" : op === "<" ? "lt" : op === "<=" ? "lte" : op === "in" ? "in" : op === "not-in" ? "nin" : op === "array-contains" ? "cs" : op === "array-contains-any" ? "csa" : "eq";
|
|
17453
|
-
let stringVal;
|
|
17454
|
-
if (Array.isArray(val)) stringVal = `(${val.join(",")})`;
|
|
17455
|
-
else stringVal = String(val);
|
|
17456
|
-
whereMap[key] = `${postgrestOp}.${stringVal}`;
|
|
17457
|
-
}
|
|
17458
|
-
});
|
|
17459
|
-
const whereParams = Object.keys(whereMap).length > 0 ? whereMap : void 0;
|
|
17460
|
-
const orderByParams = sortByProperty ? `${String(sortByProperty)}:${currentSort}` : void 0;
|
|
17291
|
+
const whereParams = filter && Object.keys(filter).length > 0 ? filter : void 0;
|
|
17292
|
+
const orderByParams = sortByProperty && currentSort ? [String(sortByProperty), currentSort] : void 0;
|
|
17461
17293
|
const cacheKey = `${path}|${filterKey}|${sortByProperty ?? ""}|${currentSort ?? ""}`;
|
|
17462
17294
|
let countPromise = inflightCountRequests.get(cacheKey);
|
|
17463
17295
|
if (!countPromise) {
|
|
@@ -17498,7 +17330,7 @@ function EntityIdHeaderWidget({ collection, path, idPath }) {
|
|
|
17498
17330
|
const [openPopup, setOpenPopup] = React.useState(false);
|
|
17499
17331
|
const [searchString, setSearchString] = React.useState("");
|
|
17500
17332
|
const [recentIds, setRecentIds] = React.useState(getRecentIds(collection.slug).map(String));
|
|
17501
|
-
const
|
|
17333
|
+
const sidePanelController = useSidePanel();
|
|
17502
17334
|
const openEntityMode = collection?.openEntityMode ?? DEFAULT_ENTITY_OPEN_MODE;
|
|
17503
17335
|
return /* @__PURE__ */ jsx(Tooltip, {
|
|
17504
17336
|
title: !openPopup ? t("find_by_id") : void 0,
|
|
@@ -17528,7 +17360,7 @@ function EntityIdHeaderWidget({ collection, path, idPath }) {
|
|
|
17528
17360
|
collection,
|
|
17529
17361
|
entityId,
|
|
17530
17362
|
path,
|
|
17531
|
-
|
|
17363
|
+
sidePanelController,
|
|
17532
17364
|
navigation: urlController
|
|
17533
17365
|
});
|
|
17534
17366
|
},
|
|
@@ -17567,7 +17399,7 @@ function EntityIdHeaderWidget({ collection, path, idPath }) {
|
|
|
17567
17399
|
collection,
|
|
17568
17400
|
entityId: id,
|
|
17569
17401
|
path,
|
|
17570
|
-
|
|
17402
|
+
sidePanelController,
|
|
17571
17403
|
navigation: urlController
|
|
17572
17404
|
});
|
|
17573
17405
|
},
|
|
@@ -17606,7 +17438,7 @@ function ReferenceWidget({ name, multiselect = false, path, disabled, value, onR
|
|
|
17606
17438
|
entities
|
|
17607
17439
|
});
|
|
17608
17440
|
}, [disabled, onReferenceSelected]);
|
|
17609
|
-
const referenceDialogController =
|
|
17441
|
+
const referenceDialogController = useSelectionDialog({
|
|
17610
17442
|
multiselect,
|
|
17611
17443
|
path,
|
|
17612
17444
|
collection,
|
|
@@ -17750,15 +17582,15 @@ function useBuildSideDialogsController() {
|
|
|
17750
17582
|
]);
|
|
17751
17583
|
}
|
|
17752
17584
|
//#endregion
|
|
17753
|
-
//#region src/components/
|
|
17585
|
+
//#region src/components/SidePanelProvider.tsx
|
|
17754
17586
|
/**
|
|
17755
|
-
* Provider that builds the
|
|
17756
|
-
* via the
|
|
17587
|
+
* Provider that builds the SidePanelController and makes it available
|
|
17588
|
+
* via the SidePanelControllerContext from @rebasepro/core.
|
|
17757
17589
|
*
|
|
17758
|
-
* After the CMS extraction refactor, `
|
|
17590
|
+
* After the CMS extraction refactor, `useBuildSidePanel` lives
|
|
17759
17591
|
* in the CMS package while the context it feeds into lives in core.
|
|
17760
17592
|
* This provider bridges the two: place it inside the `<Rebase>` tree and
|
|
17761
|
-
* above any component that calls `
|
|
17593
|
+
* above any component that calls `useSidePanel()`.
|
|
17762
17594
|
*
|
|
17763
17595
|
* Also auto-registers the side entity controller and breadcrumbs into the
|
|
17764
17596
|
* self-assembling Studio bridge (when a StudioBridgeRegistryProvider is
|
|
@@ -17768,28 +17600,28 @@ function useBuildSideDialogsController() {
|
|
|
17768
17600
|
* ```tsx
|
|
17769
17601
|
* <Rebase ...>
|
|
17770
17602
|
* {({ loading }) => (
|
|
17771
|
-
* <
|
|
17603
|
+
* <SidePanelProvider>
|
|
17772
17604
|
* <RebaseRoutes>
|
|
17773
17605
|
* ...
|
|
17774
17606
|
* </RebaseRoutes>
|
|
17775
|
-
* </
|
|
17607
|
+
* </SidePanelProvider>
|
|
17776
17608
|
* )}
|
|
17777
17609
|
* </Rebase>
|
|
17778
17610
|
* ```
|
|
17779
17611
|
*
|
|
17780
17612
|
* @group Components
|
|
17781
17613
|
*/
|
|
17782
|
-
function
|
|
17614
|
+
function SidePanelProvider({ children }) {
|
|
17783
17615
|
const collectionRegistryController = useCollectionRegistryController();
|
|
17784
17616
|
const urlController = useUrlController();
|
|
17785
17617
|
const navigationStateController = useNavigationStateController();
|
|
17786
17618
|
const sideDialogsController = useBuildSideDialogsController();
|
|
17787
|
-
const
|
|
17619
|
+
const sidePanelController = useBuildSidePanel(collectionRegistryController, urlController, navigationStateController, sideDialogsController, useAuthController());
|
|
17788
17620
|
return /* @__PURE__ */ jsx(BreadcrumbsProvider, { children: /* @__PURE__ */ jsx(SideDialogsControllerContext.Provider, {
|
|
17789
17621
|
value: sideDialogsController,
|
|
17790
|
-
children: /* @__PURE__ */ jsxs(
|
|
17791
|
-
value:
|
|
17792
|
-
children: [/* @__PURE__ */ jsx(BridgeAutoRegistrar$1, {
|
|
17622
|
+
children: /* @__PURE__ */ jsxs(SidePanelControllerContext.Provider, {
|
|
17623
|
+
value: sidePanelController,
|
|
17624
|
+
children: [/* @__PURE__ */ jsx(BridgeAutoRegistrar$1, { sidePanelController }), children]
|
|
17793
17625
|
})
|
|
17794
17626
|
}) });
|
|
17795
17627
|
}
|
|
@@ -17797,9 +17629,9 @@ function SideEntityProvider({ children }) {
|
|
|
17797
17629
|
* Internal component that auto-registers side entity and breadcrumbs
|
|
17798
17630
|
* into the Studio bridge. Must be a child of BreadcrumbsProvider.
|
|
17799
17631
|
*/
|
|
17800
|
-
function BridgeAutoRegistrar$1({
|
|
17632
|
+
function BridgeAutoRegistrar$1({ sidePanelController }) {
|
|
17801
17633
|
const breadcrumbs = useBreadcrumbsController();
|
|
17802
|
-
useBridgeRegistration("
|
|
17634
|
+
useBridgeRegistration("sidePanelController", sidePanelController);
|
|
17803
17635
|
useBridgeRegistration("breadcrumbs", breadcrumbs);
|
|
17804
17636
|
return null;
|
|
17805
17637
|
}
|
|
@@ -18185,7 +18017,7 @@ function CMSNavigationContent() {
|
|
|
18185
18017
|
if (registry.studioConfig && registry.cmsConfig?.collectionEditor) slugs.add("schema");
|
|
18186
18018
|
return slugs;
|
|
18187
18019
|
}, [registry.studioConfig, registry.cmsConfig?.collectionEditor]);
|
|
18188
|
-
const filteredEntries = adminModeController.mode === "studio" ? allNavigationEntries.filter((e) => e.type === "view" || e.type === "admin") : allNavigationEntries.filter((e) => e.type !== "view" || !studioViewSlugs.has(e.slug));
|
|
18020
|
+
const filteredEntries = adminModeController.mode === "studio" ? allNavigationEntries.filter((e) => e.type === "view" && studioViewSlugs.has(e.slug) || e.type === "admin") : allNavigationEntries.filter((e) => e.type !== "view" || !studioViewSlugs.has(e.slug));
|
|
18189
18021
|
const entryGroups = new Set(filteredEntries.map((e) => e.group).filter(Boolean));
|
|
18190
18022
|
const orderedGroups = navigationState.topLevelNavigation?.groups ?? [];
|
|
18191
18023
|
const groupsToRender = [...orderedGroups.filter((g) => entryGroups.has(g)), ...[...entryGroups].filter((g) => !orderedGroups.includes(g))];
|
|
@@ -18623,7 +18455,7 @@ function DrawerWrapper(props) {
|
|
|
18623
18455
|
* is auto-wired as a native feature (slots, provider, Studio view) without
|
|
18624
18456
|
* needing any external plugin.
|
|
18625
18457
|
*/
|
|
18626
|
-
function RebaseCMS({ collections, views, homePage, entityViews, entityActions,
|
|
18458
|
+
function RebaseCMS({ collections, views, homePage, entityViews, entityActions, collectionEditor, navigationGroupMappings, basePath }) {
|
|
18627
18459
|
const dispatch = useRebaseRegistryDispatch();
|
|
18628
18460
|
useLayoutEffect(() => {
|
|
18629
18461
|
dispatch.registerCMS({
|
|
@@ -18632,9 +18464,9 @@ function RebaseCMS({ collections, views, homePage, entityViews, entityActions, p
|
|
|
18632
18464
|
homePage,
|
|
18633
18465
|
entityViews,
|
|
18634
18466
|
entityActions,
|
|
18635
|
-
plugins,
|
|
18636
18467
|
collectionEditor,
|
|
18637
|
-
navigationGroupMappings
|
|
18468
|
+
navigationGroupMappings,
|
|
18469
|
+
basePath
|
|
18638
18470
|
});
|
|
18639
18471
|
return () => dispatch.unregisterCMS();
|
|
18640
18472
|
}, [
|
|
@@ -18644,9 +18476,9 @@ function RebaseCMS({ collections, views, homePage, entityViews, entityActions, p
|
|
|
18644
18476
|
homePage,
|
|
18645
18477
|
entityViews,
|
|
18646
18478
|
entityActions,
|
|
18647
|
-
plugins,
|
|
18648
18479
|
collectionEditor,
|
|
18649
|
-
navigationGroupMappings
|
|
18480
|
+
navigationGroupMappings,
|
|
18481
|
+
basePath
|
|
18650
18482
|
]);
|
|
18651
18483
|
return null;
|
|
18652
18484
|
}
|
|
@@ -18780,7 +18612,7 @@ function useLocalCollectionsConfigController(clientOrUrl, baseCollections = [],
|
|
|
18780
18612
|
//#region src/components/RebaseNavigation.tsx
|
|
18781
18613
|
var EMPTY_PLUGINS = [];
|
|
18782
18614
|
var EMPTY_COLLECTIONS = [];
|
|
18783
|
-
var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-
|
|
18615
|
+
var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-epqIbZrJ.js").then((n) => n.n).then((m) => ({ default: m.RouterCollectionsStudioView })));
|
|
18784
18616
|
/**
|
|
18785
18617
|
* Navigation layer — builds and provides all CMS navigation controllers:
|
|
18786
18618
|
* collection registry, URL controller, navigation state, side entity,
|
|
@@ -18795,7 +18627,7 @@ var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-Dqx
|
|
|
18795
18627
|
* ```tsx
|
|
18796
18628
|
* <RebaseNavigation>
|
|
18797
18629
|
* <MyCustomLayout>
|
|
18798
|
-
* <
|
|
18630
|
+
* <CollectionViewBinding ... />
|
|
18799
18631
|
* </MyCustomLayout>
|
|
18800
18632
|
* </RebaseNavigation>
|
|
18801
18633
|
* ```
|
|
@@ -18827,7 +18659,12 @@ function RebaseNavigation({ children }) {
|
|
|
18827
18659
|
resolveKey: (slugOrPath) => resolveDataSource(getCollectionRef.current(slugOrPath), dataSources.registry).key
|
|
18828
18660
|
}), [defaultData, dataSources]);
|
|
18829
18661
|
const urlController = useBuildUrlController({
|
|
18830
|
-
basePath:
|
|
18662
|
+
basePath: useMemo(() => {
|
|
18663
|
+
const raw = registry.cmsConfig?.basePath;
|
|
18664
|
+
if (!raw || raw === "/") return "/";
|
|
18665
|
+
const trimmed = raw.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
18666
|
+
return trimmed ? `/${trimmed}` : "/";
|
|
18667
|
+
}, [registry.cmsConfig?.basePath]),
|
|
18831
18668
|
baseCollectionPath: "/c",
|
|
18832
18669
|
collectionRegistryController
|
|
18833
18670
|
});
|
|
@@ -18884,8 +18721,9 @@ function RebaseNavigation({ children }) {
|
|
|
18884
18721
|
};
|
|
18885
18722
|
return [...cmsViews, ...devViews];
|
|
18886
18723
|
}, [cmsViews, devViews]);
|
|
18724
|
+
const parentCustomizationController = useCustomizationController();
|
|
18887
18725
|
const navigationStateController = useBuildNavigationStateController({
|
|
18888
|
-
plugins:
|
|
18726
|
+
plugins: parentCustomizationController.plugins ?? EMPTY_PLUGINS,
|
|
18889
18727
|
collections: collectionsBuilder,
|
|
18890
18728
|
views: mergedViews,
|
|
18891
18729
|
navigationGroupMappings: registry.cmsConfig?.navigationGroupMappings,
|
|
@@ -18895,7 +18733,6 @@ function RebaseNavigation({ children }) {
|
|
|
18895
18733
|
urlController,
|
|
18896
18734
|
adminMode: adminModeController?.mode
|
|
18897
18735
|
});
|
|
18898
|
-
const parentCustomizationController = useCustomizationController();
|
|
18899
18736
|
const enrichedCustomizationController = useMemo(() => {
|
|
18900
18737
|
const cmsEntityViews = registry.cmsConfig?.entityViews ?? [];
|
|
18901
18738
|
const cmsEntityActions = registry.cmsConfig?.entityActions ?? [];
|
|
@@ -18920,7 +18757,7 @@ function RebaseNavigation({ children }) {
|
|
|
18920
18757
|
value: urlController,
|
|
18921
18758
|
children: /* @__PURE__ */ jsx(NavigationStateContext.Provider, {
|
|
18922
18759
|
value: navigationStateController,
|
|
18923
|
-
children: /* @__PURE__ */ jsxs(
|
|
18760
|
+
children: /* @__PURE__ */ jsxs(SidePanelProvider, { children: [/* @__PURE__ */ jsx(BridgeAutoRegistrar, {
|
|
18924
18761
|
collectionRegistryController,
|
|
18925
18762
|
urlController,
|
|
18926
18763
|
navigationStateController
|
|
@@ -19720,7 +19557,7 @@ function ContentHomePage({ additionalActions, additionalChildrenStart, additiona
|
|
|
19720
19557
|
return slugs;
|
|
19721
19558
|
}, [registry.studioConfig, registry.cmsConfig?.collectionEditor]);
|
|
19722
19559
|
const rawNavigationEntries = useMemo(() => {
|
|
19723
|
-
if (adminModeController.mode === "studio") return unFilteredNavigationEntries.filter((e) => e.type === "view" || e.type === "admin");
|
|
19560
|
+
if (adminModeController.mode === "studio") return unFilteredNavigationEntries.filter((e) => e.type === "view" && studioViewSlugs.has(e.slug) || e.type === "admin");
|
|
19724
19561
|
return unFilteredNavigationEntries.filter((e) => e.type !== "view" || !studioViewSlugs.has(e.slug));
|
|
19725
19562
|
}, [
|
|
19726
19563
|
unFilteredNavigationEntries,
|
|
@@ -20003,7 +19840,7 @@ function RebaseRoute() {
|
|
|
20003
19840
|
const urlController = useUrlController();
|
|
20004
19841
|
const breadcrumbs = useBreadcrumbsController();
|
|
20005
19842
|
const userConfigPersistence = useUserConfigurationPersistence();
|
|
20006
|
-
const ResolvedCollectionView = useComponentOverride("Collection.View",
|
|
19843
|
+
const ResolvedCollectionView = useComponentOverride("Collection.View", CollectionViewBinding);
|
|
20007
19844
|
const hash = location.hash;
|
|
20008
19845
|
const isSidePanel = hash.includes("#side");
|
|
20009
19846
|
const isNew = hash.includes("#new") || hash.includes("#new_side");
|
|
@@ -20198,7 +20035,7 @@ function EntityFullScreenRoute({ pathname, navigationEntries, isNew, isCopy }) {
|
|
|
20198
20035
|
const fullIdPath = isNew ? lastCollectionEntry.slug : lastEntityEntry.slug;
|
|
20199
20036
|
const collectionPath = urlController.resolveDatabasePathsFrom(fullIdPath);
|
|
20200
20037
|
const isEditRoute = pathname.endsWith("/edit") || pathname.split("/").pop() === "edit";
|
|
20201
|
-
if (collection.defaultEntityAction === "view" && !isNew && !isCopy && entityId && !isEditRoute) return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
20038
|
+
if (collection.defaultEntityAction === "view" && !isNew && !isCopy && entityId && !isEditRoute) return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(DetailViewBinding, {
|
|
20202
20039
|
entityId,
|
|
20203
20040
|
collection,
|
|
20204
20041
|
layout: "full_screen",
|
|
@@ -20216,7 +20053,7 @@ function EntityFullScreenRoute({ pathname, navigationEntries, isNew, isCopy }) {
|
|
|
20216
20053
|
parentCollectionSlugs,
|
|
20217
20054
|
parentEntityIds
|
|
20218
20055
|
}, collection.slug + "_view_" + entityId) });
|
|
20219
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(
|
|
20056
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(EditViewBinding, {
|
|
20220
20057
|
entityId: isNew ? void 0 : entityId,
|
|
20221
20058
|
collection,
|
|
20222
20059
|
layout: "full_screen",
|
|
@@ -20272,8 +20109,8 @@ function CustomViewRoute({ view }) {
|
|
|
20272
20109
|
}
|
|
20273
20110
|
//#endregion
|
|
20274
20111
|
//#region src/components/CollectionEditorDialogs.tsx
|
|
20275
|
-
var CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-
|
|
20276
|
-
var PropertyFormDialog = lazy(() => import("./PropertyEditView-
|
|
20112
|
+
var CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-B-7uW3iJ.js").then((n) => n.r).then((m) => ({ default: m.CollectionEditorDialog })));
|
|
20113
|
+
var PropertyFormDialog = lazy(() => import("./PropertyEditView-7KMTcrqi.js").then((n) => n.t).then((m) => ({ default: m.PropertyFormDialog })));
|
|
20277
20114
|
/**
|
|
20278
20115
|
* Renders the CollectionEditorDialog and PropertyFormDialog inside
|
|
20279
20116
|
* the RebaseShell tree where CMS-internal contexts
|
|
@@ -20467,7 +20304,7 @@ function RebaseShell(props) {
|
|
|
20467
20304
|
* @group Components
|
|
20468
20305
|
*/
|
|
20469
20306
|
function CollectionPanelInner({ mergedCollection, path, title, updateUrl, className }) {
|
|
20470
|
-
const ResolvedCollectionView = useComponentOverride("Collection.View",
|
|
20307
|
+
const ResolvedCollectionView = useComponentOverride("Collection.View", CollectionViewBinding);
|
|
20471
20308
|
return /* @__PURE__ */ jsxs("div", {
|
|
20472
20309
|
className,
|
|
20473
20310
|
children: [title !== false && /* @__PURE__ */ jsx(Typography, {
|
|
@@ -20516,15 +20353,13 @@ function CollectionPanel(props) {
|
|
|
20516
20353
|
]
|
|
20517
20354
|
})
|
|
20518
20355
|
});
|
|
20519
|
-
|
|
20520
|
-
|
|
20521
|
-
|
|
20522
|
-
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
children: content
|
|
20356
|
+
return /* @__PURE__ */ jsx(CollectionScopeProvider, {
|
|
20357
|
+
collection: mergedCollection,
|
|
20358
|
+
children: /* @__PURE__ */ jsx(CollectionPanelInner, {
|
|
20359
|
+
...props,
|
|
20360
|
+
mergedCollection
|
|
20361
|
+
})
|
|
20526
20362
|
});
|
|
20527
|
-
return content;
|
|
20528
20363
|
}
|
|
20529
20364
|
//#endregion
|
|
20530
20365
|
//#region src/preview/components/RelationPreview.tsx
|
|
@@ -20619,17 +20454,17 @@ function RelationPreviewInternal(props) {
|
|
|
20619
20454
|
...props,
|
|
20620
20455
|
collection
|
|
20621
20456
|
});
|
|
20622
|
-
if (collection
|
|
20623
|
-
|
|
20457
|
+
if (collection) return /* @__PURE__ */ jsx(CollectionScopeProvider, {
|
|
20458
|
+
collection,
|
|
20624
20459
|
children: content
|
|
20625
20460
|
});
|
|
20626
20461
|
return content;
|
|
20627
20462
|
}
|
|
20628
20463
|
function RelationPreviewExisting({ relation, collection, previewProperties, size, disabled, includeEntityLink, includeId, onClick, hover, textOnly }) {
|
|
20629
20464
|
const passedEntity = relation.data;
|
|
20630
|
-
const ResolvedEntityPreview = useComponentOverride("
|
|
20465
|
+
const ResolvedEntityPreview = useComponentOverride("EntityPreview", EntityPreviewBinding);
|
|
20631
20466
|
const customizationController = useCustomizationController();
|
|
20632
|
-
const { entity, dataLoading, dataLoadingError } =
|
|
20467
|
+
const { entity, dataLoading, dataLoadingError } = useFetch({
|
|
20633
20468
|
path: relation.path,
|
|
20634
20469
|
entityId: passedEntity ? void 0 : relation.id,
|
|
20635
20470
|
collection,
|
|
@@ -21062,6 +20897,7 @@ var PropertyPreview = React.memo(function PropertyPreview(props) {
|
|
|
21062
20897
|
content = /* @__PURE__ */ jsx(StorageThumbnail, {
|
|
21063
20898
|
interactive,
|
|
21064
20899
|
storeUrl: property.storage?.storeUrl ?? false,
|
|
20900
|
+
storageSourceKey: stringProperty.storage.storageSource,
|
|
21065
20901
|
size: props.size,
|
|
21066
20902
|
fill,
|
|
21067
20903
|
storagePathOrDownloadUrl: filePath
|
|
@@ -21089,19 +20925,6 @@ var PropertyPreview = React.memo(function PropertyPreview(props) {
|
|
|
21089
20925
|
propertyKey,
|
|
21090
20926
|
size: props.size
|
|
21091
20927
|
});
|
|
21092
|
-
else if (stringProperty.reference) if (typeof stringProperty.reference.path === "string") content = /* @__PURE__ */ jsx(ReferencePreview, {
|
|
21093
|
-
disabled: !stringProperty.reference.path,
|
|
21094
|
-
previewProperties: stringProperty.reference?.ui?.previewProperties,
|
|
21095
|
-
includeId: stringProperty.reference.includeId,
|
|
21096
|
-
includeEntityLink: stringProperty.reference.includeEntityLink,
|
|
21097
|
-
size: props.size,
|
|
21098
|
-
reference: new EntityReference({
|
|
21099
|
-
id: value,
|
|
21100
|
-
path: stringProperty.reference.path
|
|
21101
|
-
}),
|
|
21102
|
-
textOnly: props.textOnly
|
|
21103
|
-
});
|
|
21104
|
-
else content = /* @__PURE__ */ jsx(EmptyValue, {});
|
|
21105
20928
|
else content = /* @__PURE__ */ jsx(StringPropertyPreview, {
|
|
21106
20929
|
...props,
|
|
21107
20930
|
property: stringProperty,
|
|
@@ -21691,7 +21514,7 @@ function zodToFormErrors(zodError) {
|
|
|
21691
21514
|
/**
|
|
21692
21515
|
* Headless entity form component.
|
|
21693
21516
|
*
|
|
21694
|
-
* Renders a form for
|
|
21517
|
+
* Renders a form for a entity collection without any CMS or backend dependencies.
|
|
21695
21518
|
* All backend concerns (save, caching, analytics, plugin slots) are provided via
|
|
21696
21519
|
* callback props. For CMS-connected usage, use {@link EntityFormBinding} instead.
|
|
21697
21520
|
*
|
|
@@ -22143,7 +21966,7 @@ function useOnAutoSave(autoSave, formex, lastSavedValues, save) {
|
|
|
22143
21966
|
*/
|
|
22144
21967
|
function EntityFormBinding({ path, entityId: entityIdProp, collection, entity, initialStatus, onSaved, onValuesModified, onEntityChange, onStatusChange, openEntityMode = "full_screen", navigateBack: navigateBackProp, initialDirtyValues, ...restProps }) {
|
|
22145
21968
|
const { t } = useTranslation();
|
|
22146
|
-
const
|
|
21969
|
+
const sidePanelController = useSidePanel();
|
|
22147
21970
|
const collectionRegistryController = useCollectionRegistryController();
|
|
22148
21971
|
const authController = useAuthController();
|
|
22149
21972
|
const dataClient = useData();
|
|
@@ -22197,12 +22020,12 @@ function EntityFormBinding({ path, entityId: entityIdProp, collection, entity, i
|
|
|
22197
22020
|
navigateBackProp();
|
|
22198
22021
|
return;
|
|
22199
22022
|
}
|
|
22200
|
-
if (openEntityMode === "side_panel" || openEntityMode === "dialog")
|
|
22023
|
+
if (openEntityMode === "side_panel" || openEntityMode === "dialog") sidePanelController.close();
|
|
22201
22024
|
else window.history.back();
|
|
22202
22025
|
}, [
|
|
22203
22026
|
navigateBackProp,
|
|
22204
22027
|
openEntityMode,
|
|
22205
|
-
|
|
22028
|
+
sidePanelController
|
|
22206
22029
|
]);
|
|
22207
22030
|
const clearDirtyCache = useCallback(() => {
|
|
22208
22031
|
if (status === "new" || status === "copy") {
|
|
@@ -22298,7 +22121,7 @@ function EntityFormBinding({ path, entityId: entityIdProp, collection, entity, i
|
|
|
22298
22121
|
const uniqueFieldValidator = useCallback(async ({ name, value }) => {
|
|
22299
22122
|
try {
|
|
22300
22123
|
const { data } = await dataClient.collection(path).find({
|
|
22301
|
-
where: { [name]:
|
|
22124
|
+
where: { [name]: ["==", value] },
|
|
22302
22125
|
limit: 2
|
|
22303
22126
|
});
|
|
22304
22127
|
return (entityId ? data.filter((e) => e.id !== entityId) : data).length === 0;
|
|
@@ -22398,10 +22221,10 @@ function mapPropertyToConfig(property) {
|
|
|
22398
22221
|
};
|
|
22399
22222
|
if (property.type === "string") {
|
|
22400
22223
|
if (property.enum) base.enum = mapEnumValues(property.enum);
|
|
22401
|
-
if (property.multiline) base.multiline = true;
|
|
22224
|
+
if (property.ui?.multiline) base.multiline = true;
|
|
22402
22225
|
if (property.ui?.previewAsTag) base.previewAsTag = true;
|
|
22403
|
-
if (property.
|
|
22404
|
-
if (property.ui?.markdown
|
|
22226
|
+
if (property.ui?.url) base.url = property.ui.url;
|
|
22227
|
+
if (property.ui?.markdown) base.markdown = true;
|
|
22405
22228
|
if (property.storage) base.storage = true;
|
|
22406
22229
|
if (property.email) base.email = true;
|
|
22407
22230
|
}
|
|
@@ -22453,22 +22276,16 @@ function normalizeEnumValueConfig(config) {
|
|
|
22453
22276
|
* entity-aware data layer to the headless collection view.
|
|
22454
22277
|
*/
|
|
22455
22278
|
/**
|
|
22456
|
-
*
|
|
22457
|
-
* The
|
|
22458
|
-
*
|
|
22459
|
-
*
|
|
22460
|
-
* The flattened row includes `id` and `path` at the top level,
|
|
22461
|
-
* plus all values spread.
|
|
22279
|
+
* Unwrap `Entity<M>` objects to flat rows for the headless view.
|
|
22280
|
+
* The entity system uses `{ id, path, values: M }`; `values` is already the
|
|
22281
|
+
* flat row `M` carrying its real primary key, so unwrapping is just `.values` —
|
|
22282
|
+
* no `id`/`path` merge (those are view-model metadata, not row columns).
|
|
22462
22283
|
*/
|
|
22463
22284
|
function flattenEntities(entities) {
|
|
22464
|
-
return entities.map((entity) =>
|
|
22465
|
-
id: entity.id,
|
|
22466
|
-
path: entity.path,
|
|
22467
|
-
...entity.values
|
|
22468
|
-
}));
|
|
22285
|
+
return entities.map((entity) => entity.values);
|
|
22469
22286
|
}
|
|
22470
22287
|
/**
|
|
22471
|
-
* React hook that adapts
|
|
22288
|
+
* React hook that adapts a EntityTableController to a CollectionDataController.
|
|
22472
22289
|
*
|
|
22473
22290
|
* Usage:
|
|
22474
22291
|
* ```tsx
|
|
@@ -22776,7 +22593,7 @@ function ImportDataPreview({ importConfig, properties, propertiesOrder }) {
|
|
|
22776
22593
|
importConfig.setEntities(mappedData);
|
|
22777
22594
|
}, []);
|
|
22778
22595
|
const selectionController = useSelectionController();
|
|
22779
|
-
return /* @__PURE__ */ jsx(
|
|
22596
|
+
return /* @__PURE__ */ jsx(CollectionTableBinding, {
|
|
22780
22597
|
title: /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Typography, {
|
|
22781
22598
|
variant: "subtitle2",
|
|
22782
22599
|
children: "Imported data preview"
|
|
@@ -23372,6 +23189,7 @@ function toSerializableStorageConfig(storage) {
|
|
|
23372
23189
|
if (storage.includeBucketUrl !== void 0) result.includeBucketUrl = storage.includeBucketUrl;
|
|
23373
23190
|
if (storage.storeUrl !== void 0) result.storeUrl = storage.storeUrl;
|
|
23374
23191
|
if (storage.maxSize !== void 0) result.maxSize = storage.maxSize;
|
|
23192
|
+
if (storage.storageSource !== void 0) result.storageSource = storage.storageSource;
|
|
23375
23193
|
return result;
|
|
23376
23194
|
}
|
|
23377
23195
|
/**
|
|
@@ -23384,7 +23202,7 @@ function serializeMatches(matches) {
|
|
|
23384
23202
|
}
|
|
23385
23203
|
/**
|
|
23386
23204
|
* Resolve a relation target to a string slug.
|
|
23387
|
-
* Functions are called to extract the target;
|
|
23205
|
+
* Functions are called to extract the target; CollectionConfig objects
|
|
23388
23206
|
* use their slug.
|
|
23389
23207
|
*/
|
|
23390
23208
|
function resolveRelationTarget(target) {
|
|
@@ -23429,12 +23247,8 @@ function toSerializableProperty(property) {
|
|
|
23429
23247
|
if (sp.columnType) result.columnType = sp.columnType;
|
|
23430
23248
|
if (sp.isId !== void 0) result.isId = sp.isId;
|
|
23431
23249
|
if (sp.enum) result.enum = sp.enum;
|
|
23432
|
-
if (sp.multiline) result.multiline = sp.multiline;
|
|
23433
|
-
if (sp.markdown) result.markdown = sp.markdown;
|
|
23434
23250
|
if (sp.userSelect) result.userSelect = sp.userSelect;
|
|
23435
|
-
if (sp.url) result.url = sp.url;
|
|
23436
23251
|
if (sp.email) result.email = sp.email;
|
|
23437
|
-
if (sp.previewAsTag) result.previewAsTag = sp.previewAsTag;
|
|
23438
23252
|
if (sp.validation) {
|
|
23439
23253
|
const { matches, ...restValidation } = sp.validation;
|
|
23440
23254
|
const serializedValidation = { ...restValidation };
|
|
@@ -23444,7 +23258,6 @@ function toSerializableProperty(property) {
|
|
|
23444
23258
|
}
|
|
23445
23259
|
const storage = toSerializableStorageConfig(sp.storage);
|
|
23446
23260
|
if (storage) result.storage = storage;
|
|
23447
|
-
if (sp.reference) result.reference = toSerializableProperty(sp.reference);
|
|
23448
23261
|
return result;
|
|
23449
23262
|
}
|
|
23450
23263
|
case "number": {
|
|
@@ -23478,7 +23291,6 @@ function toSerializableProperty(property) {
|
|
|
23478
23291
|
if (dp.mode) result.mode = dp.mode;
|
|
23479
23292
|
if (dp.timezone) result.timezone = dp.timezone;
|
|
23480
23293
|
if (dp.autoValue) result.autoValue = dp.autoValue;
|
|
23481
|
-
if (dp.clearable) result.clearable = dp.clearable;
|
|
23482
23294
|
if (dp.validation) {
|
|
23483
23295
|
const serializedValidation = {};
|
|
23484
23296
|
if (dp.validation.required !== void 0) serializedValidation.required = dp.validation.required;
|
|
@@ -23605,14 +23417,14 @@ function toSerializableProperties(properties) {
|
|
|
23605
23417
|
return result;
|
|
23606
23418
|
}
|
|
23607
23419
|
/**
|
|
23608
|
-
* Convert an `
|
|
23420
|
+
* Convert an `CollectionConfig` to its JSON-serializable form.
|
|
23609
23421
|
*
|
|
23610
23422
|
* Strips all non-serializable fields (functions, React nodes, class instances)
|
|
23611
23423
|
* while preserving the structural schema that the collection editor works with.
|
|
23612
23424
|
*
|
|
23613
23425
|
* The result is safe for `JSON.stringify()` and database storage.
|
|
23614
23426
|
*/
|
|
23615
|
-
function
|
|
23427
|
+
function toSerializableCollectionConfig(collection) {
|
|
23616
23428
|
const result = {
|
|
23617
23429
|
slug: collection.slug,
|
|
23618
23430
|
name: collection.name,
|
|
@@ -23621,7 +23433,8 @@ function toSerializableCollection(collection) {
|
|
|
23621
23433
|
if (collection.singularName) result.singularName = collection.singularName;
|
|
23622
23434
|
if (collection.description) result.description = collection.description;
|
|
23623
23435
|
if (collection.group) result.group = collection.group;
|
|
23624
|
-
if (collection.
|
|
23436
|
+
if (collection.engine) result.engine = collection.engine;
|
|
23437
|
+
if (collection.dataSource) result.dataSource = collection.dataSource;
|
|
23625
23438
|
if (collection.databaseId) result.databaseId = collection.databaseId;
|
|
23626
23439
|
if (collection.titleProperty) result.titleProperty = collection.titleProperty;
|
|
23627
23440
|
if (collection.ownerId) result.ownerId = collection.ownerId;
|
|
@@ -23703,12 +23516,7 @@ function fromSerializableProperty(serialized) {
|
|
|
23703
23516
|
if (sp.properties) result.properties = fromSerializableProperties(sp.properties);
|
|
23704
23517
|
return result;
|
|
23705
23518
|
}
|
|
23706
|
-
case "string": {
|
|
23707
|
-
const sp = serialized;
|
|
23708
|
-
const result = { ...sp };
|
|
23709
|
-
if (sp.reference) result.reference = fromSerializableProperty(sp.reference);
|
|
23710
|
-
return result;
|
|
23711
|
-
}
|
|
23519
|
+
case "string": return { ...serialized };
|
|
23712
23520
|
default: return serialized;
|
|
23713
23521
|
}
|
|
23714
23522
|
}
|
|
@@ -23721,13 +23529,13 @@ function fromSerializableProperties(serialized) {
|
|
|
23721
23529
|
return result;
|
|
23722
23530
|
}
|
|
23723
23531
|
/**
|
|
23724
|
-
* Convert a `
|
|
23532
|
+
* Convert a `SerializableCollectionConfig` back to an `CollectionConfig`.
|
|
23725
23533
|
*
|
|
23726
23534
|
* The result will NOT contain any of the non-serializable fields
|
|
23727
23535
|
* (callbacks, entityActions, etc.) — those must be re-attached by the
|
|
23728
23536
|
* consumer if needed.
|
|
23729
23537
|
*/
|
|
23730
|
-
function
|
|
23538
|
+
function fromSerializableCollectionConfig(serialized) {
|
|
23731
23539
|
const { properties, ...rest } = serialized;
|
|
23732
23540
|
return {
|
|
23733
23541
|
...rest,
|
|
@@ -23768,7 +23576,7 @@ function useJsonCollectionsConfigController({ store, readOnly = false, autoLoad
|
|
|
23768
23576
|
try {
|
|
23769
23577
|
const [serialized, navEntries] = await Promise.all([storeRef.current.load(), storeRef.current.loadNavigationEntries?.() ?? Promise.resolve([])]);
|
|
23770
23578
|
if (cancelled) return;
|
|
23771
|
-
setCollections(serialized.map(
|
|
23579
|
+
setCollections(serialized.map(fromSerializableCollectionConfig));
|
|
23772
23580
|
setNavigationEntries(navEntries);
|
|
23773
23581
|
} catch (e) {
|
|
23774
23582
|
console.error("useJsonCollectionsConfigController: failed to load collections", e);
|
|
@@ -23784,7 +23592,7 @@ function useJsonCollectionsConfigController({ store, readOnly = false, autoLoad
|
|
|
23784
23592
|
* Update local state and persist a collection to the store.
|
|
23785
23593
|
*/
|
|
23786
23594
|
const persistCollection = useCallback(async (collection) => {
|
|
23787
|
-
const serializable =
|
|
23595
|
+
const serializable = toSerializableCollectionConfig(collection);
|
|
23788
23596
|
await storeRef.current.save(collection.slug, serializable);
|
|
23789
23597
|
}, []);
|
|
23790
23598
|
/**
|
|
@@ -24309,6 +24117,6 @@ function getFullIdPath(propertyKey, propertyNamespace) {
|
|
|
24309
24117
|
return idToPropertiesPath(propertyNamespace ? `${propertyNamespace}.${propertyKey}` : propertyKey);
|
|
24310
24118
|
}
|
|
24311
24119
|
//#endregion
|
|
24312
|
-
export { RelationPreview as $, SelectableTable as $n,
|
|
24120
|
+
export { RelationPreview as $, SelectableTable as $n, BlockFieldBinding as $t, useCollectionDataController as A, removeInitialAndTrailingSlashes$1 as An, renderSkeletonIcon as Ar, useImportConfig as At, ArrayOfMapsPreview as B, useUrlController as Bn, getFieldId as Bt, downloadEntitiesExport as C, editEntityAction as Cn, ArrayPropertyPreview as Cr, useCollectionEditorController as Ct, ImportDataPreview as D, getCollectionBySlugWithin as Dn, StorageThumbnailInternal as Dr, flattenEntry as Dt, ImportCollectionAction as E, addInitialSlash as En, StorageThumbnail as Er, convertDataToEntity as Et, extractTouchedValues as F, useHistory as Fn, ImagePreview as Fr, PropertyConfigBadge as Ft, DatePreview as G, useSideDialogsController as Gn, SelectFieldBinding as Gt, UserPreview as H, useNavigationStateController as Hn, TextFieldBinding as Ht, getChanges as I, resolveNavigationFrom as In, EmptyValue as Ir, DEFAULT_FIELD_CONFIGS as It, ArrayOneOfPreview as J, useBuildSidePanel as Jn, MultiSelectFieldBinding as Jt, KeyValuePreview as K, buildSidePanelsFromUrl as Kn, RepeatFieldBinding as Kt, getInitialEntityValues as L, useResolvedNavigationFrom as Ln, getDefaultFieldConfig as Lt, mapPropertyToConfig as M, removeTrailingSlash as Mn, renderSkeletonText as Mr, ImportFileUpload as Mt, EntityFormBinding as N, resolveCollectionPathIds$1 as Nn, UrlComponentPreview as Nr, convertFileToJson as Nt, PropertySelectEntry as O, getCollectionPathsCombinations as On, SkeletonPropertyComponent as Or, processValueMapping as Ot, EntityForm as P, useBuildCollectionRegistryController as Pn, sanitizeUrl as Pr, unflattenObject as Pt, ArrayOfStorageComponentsPreview as Q, CollectionTableBinding as Qn, DateTimeFieldBinding as Qt, removeEmptyContainers as R, useCMSContext as Rn, getDefaultFieldId as Rt, downloadDataAsCsv as S, deleteEntityAction as Sn, isRelationProperty as Sr, CollectionViewActions as St, getEntityJsonExportableData as T, CreationResultDialog as Tn, EnumValuesChip as Tr, DataNewPropertiesMapping as Tt, NumberPropertyPreview as U, CollectionRegistryContext as Un, SwitchFieldBinding as Ut, PropertyPreview as V, NavigationStateContext as Vn, VectorFieldBinding as Vt, BooleanPreview as W, useCollectionRegistryController as Wn, StorageUploadFieldBinding as Wt, ArrayPropertyEnumPreview as X, useSelectionController as Xn, MapFieldBinding as Xt, ArrayOfStringsPreview as Y, mergeEntityActions as Yn, MarkdownEditorFieldBinding as Yt, ArrayEnumPreview as Z, VirtualTableInput$1 as Zn, KeyValueFieldBinding as Zt, toSerializableProperty as _, useBuildNavigationStateController as _n, getIconForWidget as _r, SidePanelProvider as _t, namespaceToPropertiesPath as a, FormLayout as an, useSelectionDialog as ar, RebaseLayout as at, BasicExportAction as b, useResolvedCollections as bn, getResolvedPropertyInPath as br, CollectionCardViewBinding as bt, DEFAULT_COLLECTION_GENERATION_ENDPOINT as c, PropertyIdCopyTooltip as cn, EntityViewBinding as cr, RebaseAuthGate as ct, useJsonCollectionsConfigController as d, SearchIconsView as dn, EntityPreviewBinding as dr, Drawer as dt, ArrayOfReferencesFieldBinding as en, CollectionRowActions as er, CollectionPanel as et, fromSerializableCollectionConfig as f, FieldCaption as fn, getEntityPreviewKeys as fr, DefaultDrawer as ft, toSerializableProperties as g, useBuildUrlController as gn, getIconForProperty as gr, AdminModeSyncer as gt, toSerializableCollectionConfig as h, useBreadcrumbsController as hn, getDefaultPropertiesOrder as hr, useApp as ht, namespaceToPropertiesOrderPath as i, ReadOnlyFieldBinding as in, useSidePanel as ir, RebaseRoute as it, mapPropertiesToConfigs as j, removeInitialSlash as jn, renderSkeletonImageThumbnail as jr, ImportSaveInProgress as jt, createStaticDataController as k, getLastSegment$1 as kn, renderSkeletonCaptionText as kr, getInferenceType as kt, buildCollectionGenerationCallback as l, LabelWithIcon as ln, ArrayOfReferencesPreview as lr, RebaseCMS as lt, fromSerializableProperty as m, SideDialogs as mn, getBracketNotation as mr, AppBar as mt, getFullIdPath as n, ArrayCustomShapedFieldBinding as nn, SelectableTableContext as nr, RebaseRouteDefs as nt, MissingReferenceWidget as o, FormEntry as on, resolveEntityAction as or, RebaseNavigation as ot, fromSerializableProperties as p, SelectionTableBinding as pn, getEntityTitlePropertyKey as pr, DrawerFooterActions as pt, MapPropertyPreview as q, getEntityViewWidth as qn, ReferenceFieldBinding as qt, idToPropertiesPath as r, PropertyFieldBinding as rn, SidePanelControllerContext as rr, CustomViewRoute as rt, CollectionGenerationApiError as s, LabelWithIconAndTooltip as sn, resolveEntityView as sr, useLocalCollectionsConfigController as st, getFullId as t, ArrayContainer as tn, useClearRestoreValue as tr, RebaseShell as tt, validateCollectionJson as u, FieldHelperText as un, ReferencePreview as ur, Scaffold as ut, useCollectionsConfigController as v, useTopLevelNavigation as vn, getPropertiesWithPropertiesOrder as vr, ReferenceWidget as vt, getEntityCSVExportableData as w, resetPasswordAction as wn, StringPropertyPreview as wr, ImportNewPropertyFieldPreview as wt, downloadBlob as x, copyEntityAction as xn, isReferenceProperty as xr, EntityCardBinding as xt, ExportCollectionAction as y, useResolvedViews as yn, getPropertyInPath as yr, CollectionViewBinding as yt, zodToFormErrors as z, UrlContext as zn, getFieldConfig as zt };
|
|
24313
24121
|
|
|
24314
|
-
//# sourceMappingURL=src-
|
|
24122
|
+
//# sourceMappingURL=src-sUZfe29F.js.map
|