@rebasepro/core 0.0.1-canary.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 +174 -0
- package/dist/app/AppBar.d.ts +12 -0
- package/dist/app/Drawer.d.ts +19 -0
- package/dist/app/Scaffold.d.ts +34 -0
- package/dist/app/index.d.ts +4 -0
- package/dist/app/useApp.d.ts +17 -0
- package/dist/components/AIIcon.d.ts +16 -0
- package/dist/components/AdminModeSyncer.d.ts +17 -0
- package/dist/components/ArrayContainer.d.ts +59 -0
- package/dist/components/CircularProgressCenter.d.ts +11 -0
- package/dist/components/ClearFilterSortButton.d.ts +5 -0
- package/dist/components/ConfirmationDialog.d.ts +9 -0
- package/dist/components/Debug/UIReferenceView.d.ts +1 -0
- package/dist/components/Debug/UIStyleGuide.d.ts +1 -0
- package/dist/components/DeleteEntityDialog.d.ts +12 -0
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +37 -0
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +27 -0
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +128 -0
- package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +25 -0
- package/dist/components/EntityCollectionTable/column_utils.d.ts +15 -0
- package/dist/components/EntityCollectionTable/fields/TableMultipleRelationField.d.ts +20 -0
- package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +21 -0
- package/dist/components/EntityCollectionTable/fields/TableRelationField.d.ts +21 -0
- package/dist/components/EntityCollectionTable/fields/TableRelationSelectorField.d.ts +20 -0
- package/dist/components/EntityCollectionTable/fields/TableStorageUpload.d.ts +32 -0
- package/dist/components/EntityCollectionTable/index.d.ts +6 -0
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +16 -0
- package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +32 -0
- package/dist/components/EntityCollectionTable/internal/EntityTableCellActions.d.ts +9 -0
- package/dist/components/EntityCollectionTable/internal/common.d.ts +4 -0
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +26 -0
- package/dist/components/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +13 -0
- package/dist/components/EntityCollectionTable/internal/popup_field/useWindowSize.d.ts +6 -0
- package/dist/components/EntityCollectionView/Board.d.ts +2 -0
- package/dist/components/EntityCollectionView/BoardColumn.d.ts +42 -0
- package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +9 -0
- package/dist/components/EntityCollectionView/BoardSortableList.d.ts +14 -0
- package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +26 -0
- package/dist/components/EntityCollectionView/EntityCard.d.ts +19 -0
- package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +20 -0
- package/dist/components/EntityCollectionView/EntityCollectionCardView.d.ts +31 -0
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +54 -0
- package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +14 -0
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +15 -0
- package/dist/components/EntityCollectionView/FiltersDialog.d.ts +14 -0
- package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +44 -0
- package/dist/components/EntityCollectionView/board_types.d.ts +105 -0
- package/dist/components/EntityCollectionView/useBoardDataController.d.ts +60 -0
- package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
- package/dist/components/EntityCollectionView/utils.d.ts +3 -0
- package/dist/components/EntityJsonPreview.d.ts +3 -0
- package/dist/components/EntityPreview.d.ts +54 -0
- package/dist/components/EntityView.d.ts +11 -0
- package/dist/components/ErrorBoundary.d.ts +11 -0
- package/dist/components/ErrorTooltip.d.ts +2 -0
- package/dist/components/ErrorView.d.ts +21 -0
- package/dist/components/FieldCaption.d.ts +5 -0
- package/dist/components/HomePage/ContentHomePage.d.ts +11 -0
- package/dist/components/HomePage/FavouritesView.d.ts +3 -0
- package/dist/components/HomePage/HomePageDnD.d.ts +77 -0
- package/dist/components/HomePage/NavigationCard.d.ts +10 -0
- package/dist/components/HomePage/NavigationCardBinding.d.ts +18 -0
- package/dist/components/HomePage/NavigationGroup.d.ts +11 -0
- package/dist/components/HomePage/RenameGroupDialog.d.ts +9 -0
- package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
- package/dist/components/HomePage/StudioHomePage.d.ts +9 -0
- package/dist/components/HomePage/index.d.ts +5 -0
- package/dist/components/NotFoundPage.d.ts +1 -0
- package/dist/components/PropertyCollectionView.d.ts +22 -0
- package/dist/components/PropertyConfigBadge.d.ts +6 -0
- package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
- package/dist/components/RebaseLogo.d.ts +7 -0
- package/dist/components/ReferenceTable/EntitySelectionTable.d.ts +58 -0
- package/dist/components/ReferenceWidget.d.ts +29 -0
- package/dist/components/RelationSelector.d.ts +32 -0
- package/dist/components/SearchIconsView.d.ts +5 -0
- package/dist/components/SelectableTable/SelectableTable.d.ts +89 -0
- package/dist/components/SelectableTable/SelectableTableContext.d.ts +4 -0
- package/dist/components/SelectableTable/filters/BooleanFilterField.d.ts +9 -0
- package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +12 -0
- package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +15 -0
- package/dist/components/SelectableTable/filters/RelationFilterField.d.ts +12 -0
- package/dist/components/SelectableTable/filters/StringNumberFilterField.d.ts +13 -0
- package/dist/components/UnsavedChangesDialog.d.ts +9 -0
- package/dist/components/UserDisplay.d.ts +7 -0
- package/dist/components/UserSettingsView.d.ts +1 -0
- package/dist/components/VirtualTable/VirtualTable.d.ts +11 -0
- package/dist/components/VirtualTable/VirtualTableCell.d.ts +20 -0
- package/dist/components/VirtualTable/VirtualTableHeader.d.ts +29 -0
- package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +2 -0
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +239 -0
- package/dist/components/VirtualTable/VirtualTableRow.d.ts +3 -0
- package/dist/components/VirtualTable/fields/VirtualTableDateField.d.ts +12 -0
- package/dist/components/VirtualTable/fields/VirtualTableInput.d.ts +9 -0
- package/dist/components/VirtualTable/fields/VirtualTableNumberInput.d.ts +8 -0
- package/dist/components/VirtualTable/fields/VirtualTableSelect.d.ts +15 -0
- package/dist/components/VirtualTable/fields/VirtualTableSwitch.d.ts +7 -0
- package/dist/components/VirtualTable/fields/VirtualTableUserSelect.d.ts +12 -0
- package/dist/components/VirtualTable/index.d.ts +3 -0
- package/dist/components/VirtualTable/types.d.ts +37 -0
- package/dist/components/admin/RoleChip.d.ts +4 -0
- package/dist/components/admin/RolesView.d.ts +4 -0
- package/dist/components/admin/UsersView.d.ts +4 -0
- package/dist/components/admin/index.d.ts +3 -0
- package/dist/components/common/default_entity_actions.d.ts +4 -0
- package/dist/components/common/index.d.ts +6 -0
- package/dist/components/common/table_height.d.ts +5 -0
- package/dist/components/common/types.d.ts +58 -0
- package/dist/components/common/useColumnsIds.d.ts +6 -0
- package/dist/components/common/useDataSourceTableController.d.ts +44 -0
- package/dist/components/common/useDebouncedCallback.d.ts +1 -0
- package/dist/components/common/useDebouncedData.d.ts +9 -0
- package/dist/components/common/useScrollRestoration.d.ts +14 -0
- package/dist/components/common/useTableSearchHelper.d.ts +11 -0
- package/dist/components/index.d.ts +35 -0
- package/dist/contexts/AdminModeController.d.ts +4 -0
- package/dist/contexts/AnalyticsContext.d.ts +3 -0
- package/dist/contexts/AuthControllerContext.d.ts +3 -0
- package/dist/contexts/BreacrumbsContext.d.ts +8 -0
- package/dist/contexts/CustomizationControllerContext.d.ts +3 -0
- package/dist/contexts/DataSourceContext.d.ts +3 -0
- package/dist/contexts/DialogsProvider.d.ts +4 -0
- package/dist/contexts/EffectiveRoleController.d.ts +4 -0
- package/dist/contexts/InternalUserManagementContext.d.ts +3 -0
- package/dist/contexts/ModeController.d.ts +4 -0
- package/dist/contexts/NavigationContext.d.ts +3 -0
- package/dist/contexts/SideDialogsControllerContext.d.ts +3 -0
- package/dist/contexts/SideEntityControllerContext.d.ts +3 -0
- package/dist/contexts/SnackbarProvider.d.ts +2 -0
- package/dist/contexts/StorageSourceContext.d.ts +3 -0
- package/dist/contexts/UserConfigurationPersistenceContext.d.ts +3 -0
- package/dist/contexts/index.d.ts +15 -0
- package/dist/core/DefaultAppBar.d.ts +29 -0
- package/dist/core/DefaultDrawer.d.ts +29 -0
- package/dist/core/DrawerNavigationGroup.d.ts +45 -0
- package/dist/core/DrawerNavigationItem.d.ts +10 -0
- package/dist/core/EntityEditView.d.ts +47 -0
- package/dist/core/EntityEditViewFormActions.d.ts +2 -0
- package/dist/core/EntitySidePanel.d.ts +10 -0
- package/dist/core/Rebase.d.ts +13 -0
- package/dist/core/RebaseRouter.d.ts +4 -0
- package/dist/core/RebaseRoutes.d.ts +17 -0
- package/dist/core/SideDialogs.d.ts +25 -0
- package/dist/core/field_configs.d.ts +6 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/form/EntityForm.d.ts +7 -0
- package/dist/form/EntityFormActions.d.ts +2 -0
- package/dist/form/PropertyFieldBinding.d.ts +30 -0
- package/dist/form/components/ErrorFocus.d.ts +4 -0
- package/dist/form/components/FieldHelperText.d.ts +12 -0
- package/dist/form/components/FormEntry.d.ts +6 -0
- package/dist/form/components/FormLayout.d.ts +5 -0
- package/dist/form/components/LabelWithIcon.d.ts +14 -0
- package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
- package/dist/form/components/LocalChangesMenu.d.ts +11 -0
- package/dist/form/components/StorageItemPreview.d.ts +13 -0
- package/dist/form/components/StorageUploadProgress.d.ts +10 -0
- package/dist/form/components/index.d.ts +5 -0
- package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +9 -0
- package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +11 -0
- package/dist/form/field_bindings/BlockFieldBinding.d.ts +10 -0
- package/dist/form/field_bindings/DateTimeFieldBinding.d.ts +11 -0
- package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +7 -0
- package/dist/form/field_bindings/MapFieldBinding.d.ts +9 -0
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
- package/dist/form/field_bindings/MultiSelectFieldBinding.d.ts +9 -0
- package/dist/form/field_bindings/MultipleRelationFieldBinding.d.ts +9 -0
- package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +10 -0
- package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +9 -0
- package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +9 -0
- package/dist/form/field_bindings/RelationFieldBinding.d.ts +2 -0
- package/dist/form/field_bindings/RepeatFieldBinding.d.ts +10 -0
- package/dist/form/field_bindings/SelectFieldBinding.d.ts +10 -0
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +19 -0
- package/dist/form/field_bindings/SwitchFieldBinding.d.ts +9 -0
- package/dist/form/field_bindings/TextFieldBinding.d.ts +8 -0
- package/dist/form/field_bindings/UserSelectFieldBinding.d.ts +12 -0
- package/dist/form/index.d.ts +20 -0
- package/dist/form/useClearRestoreValue.d.ts +13 -0
- package/dist/form/validation.d.ts +26 -0
- package/dist/hooks/ApiConfigContext.d.ts +24 -0
- package/dist/hooks/data/delete.d.ts +33 -0
- package/dist/hooks/data/save.d.ts +37 -0
- package/dist/hooks/data/useCollectionFetch.d.ts +50 -0
- package/dist/hooks/data/useDataOrder.d.ts +12 -0
- package/dist/hooks/data/useDataSource.d.ts +6 -0
- package/dist/hooks/data/useEntityFetch.d.ts +29 -0
- package/dist/hooks/data/useRelationSelector.d.ts +45 -0
- package/dist/hooks/index.d.ts +41 -0
- package/dist/hooks/navigation/contexts/CMSUrlContext.d.ts +4 -0
- package/dist/hooks/navigation/contexts/CollectionRegistryContext.d.ts +4 -0
- package/dist/hooks/navigation/contexts/NavigationStateContext.d.ts +4 -0
- package/dist/hooks/navigation/contexts/index.d.ts +3 -0
- package/dist/hooks/navigation/useBuildCMSUrlController.d.ts +6 -0
- package/dist/hooks/navigation/useBuildCollectionRegistryController.d.ts +7 -0
- package/dist/hooks/navigation/useBuildNavigationStateController.d.ts +32 -0
- package/dist/hooks/navigation/useNavigationRegistry.d.ts +10 -0
- package/dist/hooks/navigation/useNavigationResolution.d.ts +5 -0
- package/dist/hooks/navigation/useNavigationURLs.d.ts +11 -0
- package/dist/hooks/navigation/useResolvedCollections.d.ts +26 -0
- package/dist/hooks/navigation/useResolvedViews.d.ts +28 -0
- package/dist/hooks/navigation/useTopLevelNavigation.d.ts +26 -0
- package/dist/hooks/navigation/utils.d.ts +12 -0
- package/dist/hooks/useAdminModeController.d.ts +19 -0
- package/dist/hooks/useAnalyticsController.d.ts +5 -0
- package/dist/hooks/useAuthController.d.ts +11 -0
- package/dist/hooks/useBackendStorageSource.d.ts +30 -0
- package/dist/hooks/useBreadcrumbsController.d.ts +42 -0
- package/dist/hooks/useBrowserTitleAndIcon.d.ts +6 -0
- package/dist/hooks/useBuildAdminModeController.d.ts +6 -0
- package/dist/hooks/useBuildEffectiveRoleController.d.ts +8 -0
- package/dist/hooks/useBuildLocalConfigurationPersistence.d.ts +2 -0
- package/dist/hooks/useBuildModeController.d.ts +6 -0
- package/dist/hooks/useBuildNavigationController.d.ts +16 -0
- package/dist/hooks/useClipboard.d.ts +57 -0
- package/dist/hooks/useCollapsedGroups.d.ts +12 -0
- package/dist/hooks/useCustomizationController.d.ts +11 -0
- package/dist/hooks/useDialogsController.d.ts +11 -0
- package/dist/hooks/useEffectiveRoleController.d.ts +7 -0
- package/dist/hooks/useEntitySelectionDialog.d.ts +18 -0
- package/dist/hooks/useInternalUserManagementController.d.ts +12 -0
- package/dist/hooks/useLargeLayout.d.ts +1 -0
- package/dist/hooks/useModeController.d.ts +19 -0
- package/dist/hooks/usePermissions.d.ts +11 -0
- package/dist/hooks/useRebaseContext.d.ts +11 -0
- package/dist/hooks/useResolvedNavigationFrom.d.ts +72 -0
- package/dist/hooks/useSideDialogsController.d.ts +18 -0
- package/dist/hooks/useSideEntityController.d.ts +12 -0
- package/dist/hooks/useSnackbarController.d.ts +20 -0
- package/dist/hooks/useStorageSource.d.ts +6 -0
- package/dist/hooks/useUnsavedChangesDialog.d.ts +12 -0
- package/dist/hooks/useUserConfigurationPersistence.d.ts +8 -0
- package/dist/hooks/useValidateAuthenticator.d.ts +21 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.es.js +34745 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +34751 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/internal/common.d.ts +3 -0
- package/dist/internal/useBuildDataSource.d.ts +12 -0
- package/dist/internal/useBuildSideDialogsController.d.ts +2 -0
- package/dist/internal/useBuildSideEntityController.d.ts +4 -0
- package/dist/internal/useRestoreScroll.d.ts +6 -0
- package/dist/preview/PropertyPreview.d.ts +6 -0
- package/dist/preview/components/ArrayEnumPreview.d.ts +10 -0
- package/dist/preview/components/AsyncPreviewComponent.d.ts +11 -0
- package/dist/preview/components/BooleanPreview.d.ts +10 -0
- package/dist/preview/components/DatePreview.d.ts +17 -0
- package/dist/preview/components/EmptyValue.d.ts +6 -0
- package/dist/preview/components/EnumValuesChip.d.ts +13 -0
- package/dist/preview/components/ImagePreview.d.ts +16 -0
- package/dist/preview/components/ReferencePreview.d.ts +16 -0
- package/dist/preview/components/RelationPreview.d.ts +16 -0
- package/dist/preview/components/StorageThumbnail.d.ts +15 -0
- package/dist/preview/components/UrlComponentPreview.d.ts +13 -0
- package/dist/preview/components/UserPreview.d.ts +8 -0
- package/dist/preview/index.d.ts +24 -0
- package/dist/preview/property_previews/ArrayOfMapsPreview.d.ts +5 -0
- package/dist/preview/property_previews/ArrayOfReferencesPreview.d.ts +5 -0
- package/dist/preview/property_previews/ArrayOfRelationsPreview.d.ts +5 -0
- package/dist/preview/property_previews/ArrayOfStorageComponentsPreview.d.ts +5 -0
- package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +5 -0
- package/dist/preview/property_previews/ArrayOneOfPreview.d.ts +5 -0
- package/dist/preview/property_previews/ArrayPropertyEnumPreview.d.ts +5 -0
- package/dist/preview/property_previews/ArrayPropertyPreview.d.ts +5 -0
- package/dist/preview/property_previews/MapPropertyPreview.d.ts +8 -0
- package/dist/preview/property_previews/NumberPropertyPreview.d.ts +6 -0
- package/dist/preview/property_previews/SkeletonPropertyComponent.d.ts +13 -0
- package/dist/preview/property_previews/StringPropertyPreview.d.ts +6 -0
- package/dist/preview/util.d.ts +6 -0
- package/dist/routes/CustomCMSRoute.d.ts +4 -0
- package/dist/routes/RebaseRoute.d.ts +1 -0
- package/dist/routes/index.d.ts +2 -0
- package/dist/util/createFormexStub.d.ts +2 -0
- package/dist/util/entity_cache.d.ts +27 -0
- package/dist/util/enums.d.ts +5 -0
- package/dist/util/icon_list.d.ts +5 -0
- package/dist/util/icon_synonyms.d.ts +1853 -0
- package/dist/util/icons.d.ts +16 -0
- package/dist/util/index.d.ts +11 -0
- package/dist/util/previews.d.ts +3 -0
- package/dist/util/property_utils.d.ts +23 -0
- package/dist/util/useDebouncedCallback.d.ts +1 -0
- package/dist/util/useStorageUploadController.d.ts +36 -0
- package/dist/util/useTraceUpdate.d.ts +2 -0
- package/dist/vitePlugin.d.ts +16 -0
- package/package.json +165 -0
- package/src/app/AppBar.tsx +18 -0
- package/src/app/Drawer.tsx +30 -0
- package/src/app/Scaffold.tsx +238 -0
- package/src/app/index.ts +4 -0
- package/src/app/useApp.tsx +36 -0
- package/src/components/AIIcon.tsx +39 -0
- package/src/components/AdminModeSyncer.tsx +47 -0
- package/src/components/ArrayContainer.tsx +549 -0
- package/src/components/CircularProgressCenter.tsx +26 -0
- package/src/components/ClearFilterSortButton.tsx +44 -0
- package/src/components/ConfirmationDialog.tsx +46 -0
- package/src/components/Debug/UIReferenceView.tsx +710 -0
- package/src/components/Debug/UIStyleGuide.tsx +164 -0
- package/src/components/DeleteEntityDialog.tsx +181 -0
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +225 -0
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +383 -0
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +180 -0
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +561 -0
- package/src/components/EntityCollectionTable/column_utils.tsx +74 -0
- package/src/components/EntityCollectionTable/fields/TableMultipleRelationField.tsx +122 -0
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +169 -0
- package/src/components/EntityCollectionTable/fields/TableRelationField.tsx +177 -0
- package/src/components/EntityCollectionTable/fields/TableRelationSelectorField.tsx +42 -0
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +315 -0
- package/src/components/EntityCollectionTable/index.tsx +12 -0
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +90 -0
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +311 -0
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +82 -0
- package/src/components/EntityCollectionTable/internal/common.tsx +72 -0
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +425 -0
- package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +96 -0
- package/src/components/EntityCollectionTable/internal/popup_field/useWindowSize.tsx +20 -0
- package/src/components/EntityCollectionView/Board.tsx +324 -0
- package/src/components/EntityCollectionView/BoardColumn.tsx +158 -0
- package/src/components/EntityCollectionView/BoardColumnTitle.tsx +45 -0
- package/src/components/EntityCollectionView/BoardSortableList.tsx +172 -0
- package/src/components/EntityCollectionView/EntityBoardCard.tsx +200 -0
- package/src/components/EntityCollectionView/EntityCard.tsx +225 -0
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +746 -0
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +254 -0
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +1220 -0
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +142 -0
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +131 -0
- package/src/components/EntityCollectionView/FiltersDialog.tsx +249 -0
- package/src/components/EntityCollectionView/ViewModeToggle.tsx +194 -0
- package/src/components/EntityCollectionView/board_types.ts +113 -0
- package/src/components/EntityCollectionView/useBoardDataController.tsx +490 -0
- package/src/components/EntityCollectionView/useSelectionController.tsx +43 -0
- package/src/components/EntityCollectionView/utils.ts +19 -0
- package/src/components/EntityJsonPreview.tsx +66 -0
- package/src/components/EntityPreview.tsx +367 -0
- package/src/components/EntityView.tsx +66 -0
- package/src/components/ErrorBoundary.tsx +40 -0
- package/src/components/ErrorTooltip.tsx +12 -0
- package/src/components/ErrorView.tsx +69 -0
- package/src/components/FieldCaption.tsx +14 -0
- package/src/components/HomePage/ContentHomePage.tsx +634 -0
- package/src/components/HomePage/FavouritesView.tsx +59 -0
- package/src/components/HomePage/HomePageDnD.tsx +702 -0
- package/src/components/HomePage/NavigationCard.tsx +80 -0
- package/src/components/HomePage/NavigationCardBinding.tsx +111 -0
- package/src/components/HomePage/NavigationGroup.tsx +154 -0
- package/src/components/HomePage/RenameGroupDialog.tsx +121 -0
- package/src/components/HomePage/SmallNavigationCard.tsx +45 -0
- package/src/components/HomePage/StudioHomePage.tsx +231 -0
- package/src/components/HomePage/index.tsx +6 -0
- package/src/components/NotFoundPage.tsx +25 -0
- package/src/components/PropertyCollectionView.tsx +333 -0
- package/src/components/PropertyConfigBadge.tsx +27 -0
- package/src/components/PropertyIdCopyTooltip.tsx +47 -0
- package/src/components/RebaseLogo.tsx +29 -0
- package/src/components/ReferenceTable/EntitySelectionTable.tsx +371 -0
- package/src/components/ReferenceWidget.tsx +152 -0
- package/src/components/RelationSelector.tsx +518 -0
- package/src/components/SearchIconsView.tsx +78 -0
- package/src/components/SelectableTable/SelectableTable.tsx +344 -0
- package/src/components/SelectableTable/SelectableTableContext.tsx +6 -0
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +49 -0
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +126 -0
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +203 -0
- package/src/components/SelectableTable/filters/RelationFilterField.tsx +138 -0
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +217 -0
- package/src/components/UnsavedChangesDialog.tsx +45 -0
- package/src/components/UserDisplay.tsx +55 -0
- package/src/components/UserSettingsView.tsx +220 -0
- package/src/components/VirtualTable/VirtualTable.performance.test.tsx +386 -0
- package/src/components/VirtualTable/VirtualTable.tsx +625 -0
- package/src/components/VirtualTable/VirtualTableCell.tsx +58 -0
- package/src/components/VirtualTable/VirtualTableHeader.tsx +275 -0
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +249 -0
- package/src/components/VirtualTable/VirtualTableProps.tsx +298 -0
- package/src/components/VirtualTable/VirtualTableRow.tsx +52 -0
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +39 -0
- package/src/components/VirtualTable/fields/VirtualTableInput.tsx +93 -0
- package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +83 -0
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +133 -0
- package/src/components/VirtualTable/fields/VirtualTableSwitch.tsx +32 -0
- package/src/components/VirtualTable/fields/VirtualTableUserSelect.tsx +111 -0
- package/src/components/VirtualTable/index.tsx +3 -0
- package/src/components/VirtualTable/types.tsx +46 -0
- package/src/components/admin/RoleChip.tsx +23 -0
- package/src/components/admin/RolesView.tsx +408 -0
- package/src/components/admin/UsersView.tsx +353 -0
- package/src/components/admin/index.ts +3 -0
- package/src/components/common/default_entity_actions.tsx +144 -0
- package/src/components/common/index.ts +6 -0
- package/src/components/common/table_height.tsx +21 -0
- package/src/components/common/types.tsx +61 -0
- package/src/components/common/useColumnsIds.tsx +210 -0
- package/src/components/common/useDataSourceTableController.tsx +480 -0
- package/src/components/common/useDebouncedCallback.tsx +20 -0
- package/src/components/common/useDebouncedData.ts +49 -0
- package/src/components/common/useScrollRestoration.tsx +68 -0
- package/src/components/common/useTableSearchHelper.ts +75 -0
- package/src/components/index.tsx +49 -0
- package/src/contexts/AdminModeController.tsx +11 -0
- package/src/contexts/AnalyticsContext.tsx +4 -0
- package/src/contexts/AuthControllerContext.tsx +4 -0
- package/src/contexts/BreacrumbsContext.tsx +45 -0
- package/src/contexts/CustomizationControllerContext.tsx +4 -0
- package/src/contexts/DataSourceContext.tsx +4 -0
- package/src/contexts/DialogsProvider.tsx +53 -0
- package/src/contexts/EffectiveRoleController.tsx +11 -0
- package/src/contexts/InternalUserManagementContext.tsx +4 -0
- package/src/contexts/ModeController.tsx +11 -0
- package/src/contexts/NavigationContext.tsx +4 -0
- package/src/contexts/SideDialogsControllerContext.tsx +4 -0
- package/src/contexts/SideEntityControllerContext.tsx +4 -0
- package/src/contexts/SnackbarProvider.tsx +14 -0
- package/src/contexts/StorageSourceContext.tsx +4 -0
- package/src/contexts/UserConfigurationPersistenceContext.tsx +4 -0
- package/src/contexts/index.ts +15 -0
- package/src/core/DefaultAppBar.tsx +274 -0
- package/src/core/DefaultDrawer.tsx +267 -0
- package/src/core/DrawerNavigationGroup.tsx +117 -0
- package/src/core/DrawerNavigationItem.tsx +65 -0
- package/src/core/EntityEditView.tsx +590 -0
- package/src/core/EntityEditViewFormActions.tsx +343 -0
- package/src/core/EntitySidePanel.tsx +173 -0
- package/src/core/Rebase.tsx +229 -0
- package/src/core/RebaseRouter.tsx +17 -0
- package/src/core/RebaseRoutes.tsx +47 -0
- package/src/core/SideDialogs.tsx +200 -0
- package/src/core/field_configs.tsx +443 -0
- package/src/core/index.tsx +14 -0
- package/src/form/EntityForm.tsx +820 -0
- package/src/form/EntityFormActions.tsx +201 -0
- package/src/form/PropertyFieldBinding.tsx +348 -0
- package/src/form/components/ErrorFocus.tsx +44 -0
- package/src/form/components/FieldHelperText.tsx +45 -0
- package/src/form/components/FormEntry.tsx +22 -0
- package/src/form/components/FormLayout.tsx +16 -0
- package/src/form/components/LabelWithIcon.tsx +43 -0
- package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
- package/src/form/components/LocalChangesMenu.tsx +144 -0
- package/src/form/components/StorageItemPreview.tsx +79 -0
- package/src/form/components/StorageUploadProgress.tsx +105 -0
- package/src/form/components/index.tsx +5 -0
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +105 -0
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +163 -0
- package/src/form/field_bindings/BlockFieldBinding.tsx +268 -0
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +70 -0
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +567 -0
- package/src/form/field_bindings/MapFieldBinding.tsx +156 -0
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +146 -0
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +120 -0
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +151 -0
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +64 -0
- package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +135 -0
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +134 -0
- package/src/form/field_bindings/RelationFieldBinding.tsx +176 -0
- package/src/form/field_bindings/RepeatFieldBinding.tsx +136 -0
- package/src/form/field_bindings/SelectFieldBinding.tsx +107 -0
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +490 -0
- package/src/form/field_bindings/SwitchFieldBinding.tsx +64 -0
- package/src/form/field_bindings/TextFieldBinding.tsx +153 -0
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +96 -0
- package/src/form/index.tsx +27 -0
- package/src/form/useClearRestoreValue.tsx +35 -0
- package/src/form/validation.ts +532 -0
- package/src/hooks/ApiConfigContext.tsx +40 -0
- package/src/hooks/data/delete.ts +77 -0
- package/src/hooks/data/save.ts +75 -0
- package/src/hooks/data/useCollectionFetch.tsx +148 -0
- package/src/hooks/data/useDataOrder.ts +26 -0
- package/src/hooks/data/useDataSource.tsx +22 -0
- package/src/hooks/data/useEntityFetch.tsx +121 -0
- package/src/hooks/data/useRelationSelector.tsx +205 -0
- package/src/hooks/index.tsx +51 -0
- package/src/hooks/navigation/contexts/CMSUrlContext.tsx +24 -0
- package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +19 -0
- package/src/hooks/navigation/contexts/NavigationStateContext.tsx +15 -0
- package/src/hooks/navigation/contexts/index.ts +14 -0
- package/src/hooks/navigation/useBuildCMSUrlController.tsx +68 -0
- package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +150 -0
- package/src/hooks/navigation/useBuildNavigationStateController.tsx +135 -0
- package/src/hooks/navigation/useNavigationRegistry.ts +142 -0
- package/src/hooks/navigation/useNavigationResolution.ts +98 -0
- package/src/hooks/navigation/useNavigationURLs.ts +56 -0
- package/src/hooks/navigation/useResolvedCollections.ts +139 -0
- package/src/hooks/navigation/useResolvedViews.tsx +204 -0
- package/src/hooks/navigation/useTopLevelNavigation.ts +265 -0
- package/src/hooks/navigation/utils.ts +177 -0
- package/src/hooks/useAdminModeController.tsx +23 -0
- package/src/hooks/useAnalyticsController.tsx +8 -0
- package/src/hooks/useAuthController.tsx +14 -0
- package/src/hooks/useBackendStorageSource.ts +276 -0
- package/src/hooks/useBreadcrumbsController.tsx +49 -0
- package/src/hooks/useBrowserTitleAndIcon.tsx +25 -0
- package/src/hooks/useBuildAdminModeController.tsx +24 -0
- package/src/hooks/useBuildEffectiveRoleController.tsx +30 -0
- package/src/hooks/useBuildLocalConfigurationPersistence.tsx +65 -0
- package/src/hooks/useBuildModeController.tsx +71 -0
- package/src/hooks/useBuildNavigationController.tsx +341 -0
- package/src/hooks/useClipboard.tsx +158 -0
- package/src/hooks/useCollapsedGroups.ts +72 -0
- package/src/hooks/useCustomizationController.tsx +14 -0
- package/src/hooks/useDialogsController.tsx +14 -0
- package/src/hooks/useEffectiveRoleController.tsx +10 -0
- package/src/hooks/useEntitySelectionDialog.tsx +56 -0
- package/src/hooks/useInternalUserManagementController.tsx +17 -0
- package/src/hooks/useLargeLayout.tsx +65 -0
- package/src/hooks/useModeController.tsx +23 -0
- package/src/hooks/usePermissions.ts +43 -0
- package/src/hooks/useRebaseContext.tsx +86 -0
- package/src/hooks/useResolvedNavigationFrom.tsx +158 -0
- package/src/hooks/useSideDialogsController.tsx +21 -0
- package/src/hooks/useSideEntityController.tsx +15 -0
- package/src/hooks/useSnackbarController.tsx +52 -0
- package/src/hooks/useStorageSource.tsx +14 -0
- package/src/hooks/useUnsavedChangesDialog.tsx +62 -0
- package/src/hooks/useUserConfigurationPersistence.tsx +11 -0
- package/src/hooks/useValidateAuthenticator.tsx +115 -0
- package/src/index.ts +17 -0
- package/src/internal/common.tsx +5 -0
- package/src/internal/useBuildDataSource.ts +380 -0
- package/src/internal/useBuildSideDialogsController.tsx +135 -0
- package/src/internal/useBuildSideEntityController.tsx +309 -0
- package/src/internal/useRestoreScroll.tsx +60 -0
- package/src/preview/PropertyPreview.tsx +308 -0
- package/src/preview/components/ArrayEnumPreview.tsx +38 -0
- package/src/preview/components/AsyncPreviewComponent.tsx +47 -0
- package/src/preview/components/BooleanPreview.tsx +25 -0
- package/src/preview/components/DatePreview.tsx +94 -0
- package/src/preview/components/EmptyValue.tsx +10 -0
- package/src/preview/components/EnumValuesChip.tsx +39 -0
- package/src/preview/components/ImagePreview.tsx +111 -0
- package/src/preview/components/ReferencePreview.tsx +162 -0
- package/src/preview/components/RelationPreview.tsx +153 -0
- package/src/preview/components/StorageThumbnail.tsx +91 -0
- package/src/preview/components/UrlComponentPreview.tsx +113 -0
- package/src/preview/components/UserPreview.tsx +27 -0
- package/src/preview/index.ts +26 -0
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +72 -0
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +43 -0
- package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +52 -0
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +49 -0
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +44 -0
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +67 -0
- package/src/preview/property_previews/ArrayPropertyEnumPreview.tsx +34 -0
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +69 -0
- package/src/preview/property_previews/MapPropertyPreview.tsx +145 -0
- package/src/preview/property_previews/NumberPropertyPreview.tsx +28 -0
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +275 -0
- package/src/preview/property_previews/StringPropertyPreview.tsx +57 -0
- package/src/preview/util.ts +30 -0
- package/src/routes/CustomCMSRoute.tsx +21 -0
- package/src/routes/RebaseRoute.tsx +255 -0
- package/src/routes/index.ts +2 -0
- package/src/util/createFormexStub.tsx +66 -0
- package/src/util/entity_cache.ts +267 -0
- package/src/util/enums.ts +32 -0
- package/src/util/icon_list.ts +23 -0
- package/src/util/icon_synonyms.ts +1853 -0
- package/src/util/icons.tsx +87 -0
- package/src/util/index.ts +11 -0
- package/src/util/previews.ts +50 -0
- package/src/util/property_utils.tsx +152 -0
- package/src/util/useDebouncedCallback.ts +25 -0
- package/src/util/useStorageUploadController.tsx +342 -0
- package/src/util/useTraceUpdate.tsx +24 -0
- package/src/vitePlugin.ts +47 -0
|
@@ -0,0 +1,746 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Entity,
|
|
4
|
+
EntityCollection,
|
|
5
|
+
EntityTableController,
|
|
6
|
+
EnumValueConfig,
|
|
7
|
+
FilterValues,
|
|
8
|
+
Property,
|
|
9
|
+
SaveEntityProps,
|
|
10
|
+
SelectionController
|
|
11
|
+
} from "@rebasepro/types";
|
|
12
|
+
import { Board } from "./Board";
|
|
13
|
+
import { BoardItem, BoardItemViewProps, ColumnLoadingState } from "./board_types";
|
|
14
|
+
import { EntityBoardCard } from "./EntityBoardCard";
|
|
15
|
+
import {
|
|
16
|
+
Button,
|
|
17
|
+
ChipColorKey,
|
|
18
|
+
ChipColorScheme,
|
|
19
|
+
CircularProgress,
|
|
20
|
+
Dialog,
|
|
21
|
+
DialogActions,
|
|
22
|
+
DialogContent,
|
|
23
|
+
getColorSchemeForSeed,
|
|
24
|
+
IconButton,
|
|
25
|
+
RefreshIcon,
|
|
26
|
+
Tooltip,
|
|
27
|
+
Typography
|
|
28
|
+
} from "@rebasepro/ui";
|
|
29
|
+
import { resolveEnumValues } from "@rebasepro/common";
|
|
30
|
+
import { getPropertyInPath } from "../../util";
|
|
31
|
+
import {
|
|
32
|
+
saveEntityWithCallbacks,
|
|
33
|
+
useAuthController,
|
|
34
|
+
useCustomizationController,
|
|
35
|
+
useDataSource,
|
|
36
|
+
useRebaseContext,
|
|
37
|
+
useSideEntityController
|
|
38
|
+
} from "../../hooks";
|
|
39
|
+
import { useAnalyticsController } from "../../hooks/useAnalyticsController";
|
|
40
|
+
import { setIn } from "@rebasepro/formex";
|
|
41
|
+
import { useBoardDataController } from "./useBoardDataController";
|
|
42
|
+
|
|
43
|
+
export type EntityCollectionBoardViewProps<M extends Record<string, any> = any> = {
|
|
44
|
+
collection: EntityCollection<M>;
|
|
45
|
+
tableController: EntityTableController<M>;
|
|
46
|
+
fullPath: string;
|
|
47
|
+
parentCollectionIds?: string[];
|
|
48
|
+
columnProperty: string;
|
|
49
|
+
onEntityClick?: (entity: Entity<M>) => void;
|
|
50
|
+
selectionController?: SelectionController<M>;
|
|
51
|
+
selectionEnabled?: boolean;
|
|
52
|
+
highlightedEntities?: Entity<M>[];
|
|
53
|
+
emptyComponent?: React.ReactNode;
|
|
54
|
+
/** Called when entities are deleted - used for optimistic count updates */
|
|
55
|
+
deletedEntities?: Entity<M>[];
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Kanban board view for displaying entities grouped by a string enum property.
|
|
60
|
+
*/
|
|
61
|
+
export function EntityCollectionBoardView<M extends Record<string, any> = any>({
|
|
62
|
+
collection,
|
|
63
|
+
tableController,
|
|
64
|
+
fullPath,
|
|
65
|
+
parentCollectionIds = [],
|
|
66
|
+
columnProperty,
|
|
67
|
+
onEntityClick,
|
|
68
|
+
selectionController,
|
|
69
|
+
selectionEnabled = true,
|
|
70
|
+
highlightedEntities,
|
|
71
|
+
emptyComponent,
|
|
72
|
+
deletedEntities
|
|
73
|
+
}: EntityCollectionBoardViewProps<M>) {
|
|
74
|
+
const authController = useAuthController();
|
|
75
|
+
const customizationController = useCustomizationController();
|
|
76
|
+
const context = useRebaseContext();
|
|
77
|
+
const dataSource = useDataSource(collection);
|
|
78
|
+
const sideEntityController = useSideEntityController();
|
|
79
|
+
const analyticsController = useAnalyticsController();
|
|
80
|
+
const plugins = customizationController.plugins ?? [];
|
|
81
|
+
|
|
82
|
+
// State for backfill dialog
|
|
83
|
+
const [showBackfillDialog, setShowBackfillDialog] = useState(false);
|
|
84
|
+
const [backfillLoading, setBackfillLoading] = useState(false);
|
|
85
|
+
|
|
86
|
+
// v4: use collection directly without resolving
|
|
87
|
+
|
|
88
|
+
// Get orderProperty from collection config, but validate it exists as a real property
|
|
89
|
+
const rawOrderProperty = collection.orderProperty;
|
|
90
|
+
const orderProperty = useMemo(() => {
|
|
91
|
+
if (!rawOrderProperty) return undefined;
|
|
92
|
+
// Check if the property actually exists in the collection
|
|
93
|
+
const property = getPropertyInPath(collection.properties, rawOrderProperty);
|
|
94
|
+
if (!property) {
|
|
95
|
+
console.warn(`orderProperty "${rawOrderProperty}" is defined but does not exist in the collection properties. Treating as unconfigured.`);
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
return rawOrderProperty;
|
|
99
|
+
}, [rawOrderProperty, collection.properties]);
|
|
100
|
+
|
|
101
|
+
// Get columns from the property's enumValues
|
|
102
|
+
const {
|
|
103
|
+
enumColumns,
|
|
104
|
+
columnLabels,
|
|
105
|
+
columnColors
|
|
106
|
+
} = useMemo(() => {
|
|
107
|
+
const property = getPropertyInPath(collection.properties, columnProperty);
|
|
108
|
+
if (!property || !("type" in property) || (property as any).type !== "string") {
|
|
109
|
+
return {
|
|
110
|
+
enumColumns: [] as string[],
|
|
111
|
+
columnLabels: {} as Record<string, string>
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
const stringProperty = property as any;
|
|
115
|
+
if (!stringProperty.enum) {
|
|
116
|
+
return {
|
|
117
|
+
enumColumns: [] as string[],
|
|
118
|
+
columnLabels: {} as Record<string, string>
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const enumValues = resolveEnumValues(stringProperty.enum);
|
|
122
|
+
if (!enumValues) {
|
|
123
|
+
return {
|
|
124
|
+
enumColumns: [] as string[],
|
|
125
|
+
columnLabels: {} as Record<string, string>
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const cols = enumValues.map((ev: EnumValueConfig) => String(ev.id));
|
|
129
|
+
const labels = enumValues.reduce((acc: Record<string, string>, ev: EnumValueConfig) => {
|
|
130
|
+
acc[String(ev.id)] = ev.label;
|
|
131
|
+
return acc;
|
|
132
|
+
}, {});
|
|
133
|
+
const colors = enumValues.reduce((acc: Record<string, ChipColorKey | ChipColorScheme | undefined>, ev: EnumValueConfig) => {
|
|
134
|
+
acc[String(ev.id)] = ev.color ?? getColorSchemeForSeed(String(ev.id));
|
|
135
|
+
return acc;
|
|
136
|
+
}, {});
|
|
137
|
+
return {
|
|
138
|
+
enumColumns: cols,
|
|
139
|
+
columnLabels: labels,
|
|
140
|
+
columnColors: colors
|
|
141
|
+
};
|
|
142
|
+
}, [collection, columnProperty]);
|
|
143
|
+
|
|
144
|
+
// Track if user has manually reordered columns in this session
|
|
145
|
+
const [hasUserReordered, setHasUserReordered] = useState(false);
|
|
146
|
+
// Column order is derived from the property's enumValues order
|
|
147
|
+
// Local state tracks session reordering before it's persisted
|
|
148
|
+
const [localColumnsOrder, setLocalColumnsOrder] = useState<string[]>(enumColumns);
|
|
149
|
+
|
|
150
|
+
useEffect(() => {
|
|
151
|
+
if (!hasUserReordered) {
|
|
152
|
+
// Sync with enumColumns when property changes
|
|
153
|
+
setLocalColumnsOrder(enumColumns);
|
|
154
|
+
} else {
|
|
155
|
+
// User has reordered - only add any missing columns
|
|
156
|
+
const missingColumns = enumColumns.filter(c => !localColumnsOrder.includes(c));
|
|
157
|
+
if (missingColumns.length > 0) {
|
|
158
|
+
setLocalColumnsOrder(prev => [...prev, ...missingColumns]);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}, [enumColumns, hasUserReordered]);
|
|
162
|
+
|
|
163
|
+
const columns = localColumnsOrder;
|
|
164
|
+
|
|
165
|
+
// Use the new per-column data controller
|
|
166
|
+
const boardDataController = useBoardDataController<M>({
|
|
167
|
+
fullPath,
|
|
168
|
+
collection,
|
|
169
|
+
columnProperty,
|
|
170
|
+
columns,
|
|
171
|
+
orderProperty,
|
|
172
|
+
pageSize: 30,
|
|
173
|
+
searchString: tableController.searchString,
|
|
174
|
+
filterValues: tableController.filterValues
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// Aggregate loading and error state
|
|
178
|
+
const dataLoading = boardDataController.loading;
|
|
179
|
+
const dataLoadingError = boardDataController.error;
|
|
180
|
+
|
|
181
|
+
// Track previously processed deleted entities to avoid double-counting
|
|
182
|
+
const processedDeletedRef = useRef<Set<string>>(new Set());
|
|
183
|
+
|
|
184
|
+
// Optimistic update for column counts when entities are deleted
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
if (!deletedEntities || deletedEntities.length === 0) return;
|
|
187
|
+
|
|
188
|
+
// Calculate column deltas from deleted entities
|
|
189
|
+
const deltas: Record<string, number> = {};
|
|
190
|
+
deletedEntities.forEach(entity => {
|
|
191
|
+
// Skip if we've already processed this entity
|
|
192
|
+
if (processedDeletedRef.current.has(String(entity.id))) return;
|
|
193
|
+
processedDeletedRef.current.add(String(entity.id));
|
|
194
|
+
|
|
195
|
+
const col = entity.values?.[columnProperty];
|
|
196
|
+
if (col && typeof col === "string") {
|
|
197
|
+
deltas[col] = (deltas[col] ?? 0) + 1;
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
if (Object.keys(deltas).length > 0) {
|
|
202
|
+
boardDataController.decrementColumnCounts(deltas);
|
|
203
|
+
}
|
|
204
|
+
}, [deletedEntities, columnProperty, boardDataController]);
|
|
205
|
+
|
|
206
|
+
// Build all entities from all columns for operations that need the full list
|
|
207
|
+
const allEntities = useMemo(() => {
|
|
208
|
+
const entities: Entity<M>[] = [];
|
|
209
|
+
columns.forEach(col => {
|
|
210
|
+
const colData = boardDataController.columnData[col];
|
|
211
|
+
if (colData?.entities) {
|
|
212
|
+
entities.push(...colData.entities);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
return entities;
|
|
216
|
+
}, [boardDataController.columnData, columns]);
|
|
217
|
+
|
|
218
|
+
const allowColumnReorder = useMemo(() => {
|
|
219
|
+
return plugins.some(plugin => plugin.collectionView?.onKanbanColumnsReorder);
|
|
220
|
+
}, [plugins]);
|
|
221
|
+
|
|
222
|
+
const handleColumnReorder = useCallback((newColumns: string[]) => {
|
|
223
|
+
analyticsController.onAnalyticsEvent?.("kanban_column_reorder", {
|
|
224
|
+
path: fullPath,
|
|
225
|
+
columnProperty
|
|
226
|
+
});
|
|
227
|
+
setHasUserReordered(true);
|
|
228
|
+
setLocalColumnsOrder(newColumns);
|
|
229
|
+
plugins
|
|
230
|
+
.filter(plugin => plugin.collectionView?.onKanbanColumnsReorder)
|
|
231
|
+
.forEach(plugin => {
|
|
232
|
+
plugin.collectionView!.onKanbanColumnsReorder!({
|
|
233
|
+
fullPath,
|
|
234
|
+
parentCollectionIds,
|
|
235
|
+
collection,
|
|
236
|
+
kanbanColumnProperty: columnProperty,
|
|
237
|
+
newColumnsOrder: newColumns
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
}, [plugins, fullPath, parentCollectionIds, collection, columnProperty, analyticsController]);
|
|
241
|
+
|
|
242
|
+
// Collection-level count queries to detect missing order property
|
|
243
|
+
// Just TWO counts: total and ordered (for the entire collection, not per column)
|
|
244
|
+
const [missingOrderCount, setMissingOrderCount] = useState<number>(0);
|
|
245
|
+
|
|
246
|
+
// Use refs for objects that shouldn't trigger re-runs
|
|
247
|
+
const dataSourceRef = useRef(dataSource);
|
|
248
|
+
const collectionRef = useRef(collection);
|
|
249
|
+
dataSourceRef.current = dataSource;
|
|
250
|
+
collectionRef.current = collection;
|
|
251
|
+
|
|
252
|
+
useEffect(() => {
|
|
253
|
+
const currentDataSource = dataSourceRef.current;
|
|
254
|
+
const currentCollection = collectionRef.current;
|
|
255
|
+
|
|
256
|
+
if (!orderProperty || !currentDataSource.countEntities) {
|
|
257
|
+
setMissingOrderCount(0);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Count 1: Total documents in collection
|
|
262
|
+
// Count 2: Documents with orderProperty != null
|
|
263
|
+
let totalCount = 0;
|
|
264
|
+
let orderedCount = 0;
|
|
265
|
+
let completed = 0;
|
|
266
|
+
|
|
267
|
+
currentDataSource.countEntities({
|
|
268
|
+
path: fullPath,
|
|
269
|
+
collection: currentCollection
|
|
270
|
+
}).then(count => {
|
|
271
|
+
totalCount = count;
|
|
272
|
+
completed++;
|
|
273
|
+
if (completed === 2) {
|
|
274
|
+
setMissingOrderCount(Math.max(0, totalCount - orderedCount));
|
|
275
|
+
}
|
|
276
|
+
}).catch(e => console.warn("Failed to get total count:", e));
|
|
277
|
+
|
|
278
|
+
currentDataSource.countEntities({
|
|
279
|
+
path: fullPath,
|
|
280
|
+
collection: currentCollection,
|
|
281
|
+
filter: { [orderProperty]: ["!=", null] } as FilterValues<string>
|
|
282
|
+
}).then(count => {
|
|
283
|
+
orderedCount = count;
|
|
284
|
+
completed++;
|
|
285
|
+
if (completed === 2) {
|
|
286
|
+
setMissingOrderCount(Math.max(0, totalCount - orderedCount));
|
|
287
|
+
}
|
|
288
|
+
}).catch(e => console.warn("Failed to get ordered count:", e));
|
|
289
|
+
}, [orderProperty, fullPath]); // Only re-run when these primitives change
|
|
290
|
+
|
|
291
|
+
// Check if items need backfill (have no orderProperty values)
|
|
292
|
+
const itemsNeedBackfill = useMemo(() => {
|
|
293
|
+
if (!orderProperty || dataLoading) return false;
|
|
294
|
+
// Use collection-level count detection
|
|
295
|
+
if (missingOrderCount > 0) return true;
|
|
296
|
+
// Fallback to checking loaded entities
|
|
297
|
+
return allEntities.some((entity: Entity<M>) => {
|
|
298
|
+
const orderValue = entity.values?.[orderProperty];
|
|
299
|
+
return orderValue === undefined || orderValue === null;
|
|
300
|
+
});
|
|
301
|
+
}, [allEntities, orderProperty, dataLoading, missingOrderCount]);
|
|
302
|
+
|
|
303
|
+
// Create a lookup map of entity ID → column from boardDataController data
|
|
304
|
+
// This ensures items stay in the column they were fetched for, not re-evaluated from entity.values
|
|
305
|
+
const entityColumnMap = useMemo(() => {
|
|
306
|
+
const map: Record<string, string> = {};
|
|
307
|
+
columns.forEach(col => {
|
|
308
|
+
const colData = boardDataController.columnData[col];
|
|
309
|
+
if (colData?.entities) {
|
|
310
|
+
colData.entities.forEach((entity: Entity<M>) => {
|
|
311
|
+
map[String(entity.id)] = col;
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
return map;
|
|
316
|
+
}, [columns, boardDataController.columnData]);
|
|
317
|
+
|
|
318
|
+
// Convert entities to board items per column (data already sorted by orderProperty from controller)
|
|
319
|
+
const boardItems: BoardItem<M>[] = useMemo(() => {
|
|
320
|
+
return allEntities.map((entity: Entity<M>) => ({
|
|
321
|
+
id: String(entity.id),
|
|
322
|
+
entity
|
|
323
|
+
}));
|
|
324
|
+
}, [allEntities]);
|
|
325
|
+
|
|
326
|
+
// Column loading state from the board data controller
|
|
327
|
+
const columnLoadingState: ColumnLoadingState = useMemo(() => {
|
|
328
|
+
const state: ColumnLoadingState = {};
|
|
329
|
+
columns.forEach(col => {
|
|
330
|
+
const colData = boardDataController.columnData[col];
|
|
331
|
+
state[col] = {
|
|
332
|
+
loading: colData?.loading ?? true,
|
|
333
|
+
hasMore: colData?.hasMore ?? false,
|
|
334
|
+
itemCount: colData?.entities?.length ?? 0,
|
|
335
|
+
totalCount: colData?.totalCount
|
|
336
|
+
};
|
|
337
|
+
});
|
|
338
|
+
return state;
|
|
339
|
+
}, [columns, boardDataController.columnData]);
|
|
340
|
+
|
|
341
|
+
// Use the lookup map to assign columns - ensures items stay in the column they were fetched for
|
|
342
|
+
const assignColumn = useCallback((item: BoardItem<M>): string => {
|
|
343
|
+
const column = entityColumnMap[item.id];
|
|
344
|
+
if (column) return column;
|
|
345
|
+
// Fallback: read from entity values (for newly created items or edge cases)
|
|
346
|
+
const value = item.entity.values?.[columnProperty];
|
|
347
|
+
if (value && columns.includes(String(value))) return String(value);
|
|
348
|
+
return columns[0] || "";
|
|
349
|
+
}, [entityColumnMap, columnProperty, columns]);
|
|
350
|
+
|
|
351
|
+
// Calculate new order value using fractional indexing
|
|
352
|
+
const calculateNewOrder = useCallback((
|
|
353
|
+
items: BoardItem<M>[],
|
|
354
|
+
movedItemId: string,
|
|
355
|
+
targetColumn: string
|
|
356
|
+
): number => {
|
|
357
|
+
// Get items in target column (sorted by order)
|
|
358
|
+
const columnItems = items
|
|
359
|
+
.filter(item => {
|
|
360
|
+
const col = item.entity.values?.[columnProperty];
|
|
361
|
+
return col === targetColumn || (item.id === movedItemId);
|
|
362
|
+
})
|
|
363
|
+
.filter(item => item.id !== movedItemId)
|
|
364
|
+
.sort((a, b) => {
|
|
365
|
+
const orderA = a.entity.values?.[orderProperty!] ?? 0;
|
|
366
|
+
const orderB = b.entity.values?.[orderProperty!] ?? 0;
|
|
367
|
+
return orderA - orderB;
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
// Find the moved item's new position in the column
|
|
371
|
+
const movedItemIndex = items.findIndex(item => item.id === movedItemId);
|
|
372
|
+
const movedItem = items[movedItemIndex];
|
|
373
|
+
|
|
374
|
+
if (!movedItem) return 0;
|
|
375
|
+
|
|
376
|
+
// Find items before and after in the target column
|
|
377
|
+
let prevOrder: number | null = null;
|
|
378
|
+
let nextOrder: number | null = null;
|
|
379
|
+
|
|
380
|
+
// Simple approach: find the item at the new position
|
|
381
|
+
const newColumnItems = items.filter(item => {
|
|
382
|
+
if (item.id === movedItemId) return true;
|
|
383
|
+
const col = item.entity.values?.[columnProperty];
|
|
384
|
+
return col === targetColumn;
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
const newIndex = newColumnItems.findIndex(item => item.id === movedItemId);
|
|
388
|
+
|
|
389
|
+
if (newIndex > 0) {
|
|
390
|
+
const prevItem = newColumnItems[newIndex - 1];
|
|
391
|
+
prevOrder = prevItem?.entity.values?.[orderProperty!] ?? null;
|
|
392
|
+
}
|
|
393
|
+
if (newIndex < newColumnItems.length - 1) {
|
|
394
|
+
const nextItem = newColumnItems[newIndex + 1];
|
|
395
|
+
nextOrder = nextItem?.entity.values?.[orderProperty!] ?? null;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Calculate new order using fractional indexing
|
|
399
|
+
if (prevOrder !== null && nextOrder !== null) {
|
|
400
|
+
return (prevOrder + nextOrder) / 2;
|
|
401
|
+
} else if (prevOrder !== null) {
|
|
402
|
+
return prevOrder + 1;
|
|
403
|
+
} else if (nextOrder !== null) {
|
|
404
|
+
return nextOrder - 1;
|
|
405
|
+
}
|
|
406
|
+
return 0;
|
|
407
|
+
}, [columnProperty, orderProperty]);
|
|
408
|
+
|
|
409
|
+
// Handle item reorder and column changes
|
|
410
|
+
const handleItemsReorder = useCallback(async (
|
|
411
|
+
items: BoardItem<M>[],
|
|
412
|
+
moveInfo?: { itemId: string; sourceColumn: string; targetColumn: string; }
|
|
413
|
+
) => {
|
|
414
|
+
const entity = items.find(item => item.id === moveInfo?.itemId)?.entity;
|
|
415
|
+
if (!entity) return;
|
|
416
|
+
|
|
417
|
+
analyticsController.onAnalyticsEvent?.("kanban_card_moved", {
|
|
418
|
+
path: fullPath,
|
|
419
|
+
entityId: entity.id,
|
|
420
|
+
sourceColumn: moveInfo?.sourceColumn,
|
|
421
|
+
targetColumn: moveInfo?.targetColumn
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
const isColumnChange = moveInfo && moveInfo.sourceColumn !== moveInfo.targetColumn;
|
|
425
|
+
|
|
426
|
+
// If no orderProperty and not a column change, nothing to do
|
|
427
|
+
if (!orderProperty && !isColumnChange) return;
|
|
428
|
+
|
|
429
|
+
// Optimistic update: update column counts immediately when moving between columns
|
|
430
|
+
if (isColumnChange) {
|
|
431
|
+
boardDataController.updateColumnCounts(moveInfo.sourceColumn, moveInfo.targetColumn);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Build updated values
|
|
435
|
+
let updatedValues = { ...entity.values };
|
|
436
|
+
|
|
437
|
+
// Calculate and set new order value (only if orderProperty is configured)
|
|
438
|
+
if (orderProperty) {
|
|
439
|
+
const newOrder = calculateNewOrder(items, moveInfo?.itemId ?? "", moveInfo?.targetColumn ?? "");
|
|
440
|
+
updatedValues = setIn(updatedValues, orderProperty, newOrder);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Update column if it changed
|
|
444
|
+
if (isColumnChange) {
|
|
445
|
+
updatedValues = setIn(updatedValues, columnProperty, moveInfo.targetColumn);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const saveProps: SaveEntityProps = {
|
|
449
|
+
path: entity.path,
|
|
450
|
+
entityId: entity.id,
|
|
451
|
+
values: updatedValues as M,
|
|
452
|
+
previousValues: entity.values,
|
|
453
|
+
collection,
|
|
454
|
+
status: "existing"
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
try {
|
|
458
|
+
await saveEntityWithCallbacks({
|
|
459
|
+
...saveProps,
|
|
460
|
+
collection,
|
|
461
|
+
dataSource,
|
|
462
|
+
context,
|
|
463
|
+
afterSave: () => {
|
|
464
|
+
},
|
|
465
|
+
afterSaveError: (e: Error) => console.error("Failed to save entity after reorder:", e)
|
|
466
|
+
});
|
|
467
|
+
} catch (e) {
|
|
468
|
+
console.error("Error saving entity:", e);
|
|
469
|
+
}
|
|
470
|
+
}, [collection, columnProperty, orderProperty, context, dataSource, calculateNewOrder, boardDataController, analyticsController, fullPath]);
|
|
471
|
+
|
|
472
|
+
// Backfill order values for all entities
|
|
473
|
+
const handleBackfill = useCallback(async () => {
|
|
474
|
+
console.log("handleBackfill called", { orderProperty });
|
|
475
|
+
if (!orderProperty) {
|
|
476
|
+
console.log("No orderProperty, returning");
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
analyticsController.onAnalyticsEvent?.("kanban_backfill_order", {
|
|
480
|
+
path: fullPath
|
|
481
|
+
});
|
|
482
|
+
setBackfillLoading(true);
|
|
483
|
+
|
|
484
|
+
try {
|
|
485
|
+
// Fetch ALL documents from collection (not relying on loaded entities)
|
|
486
|
+
console.log("Fetching all documents from collection...");
|
|
487
|
+
const allDocs = await dataSource.fetchCollection<M>({
|
|
488
|
+
path: fullPath,
|
|
489
|
+
collection,
|
|
490
|
+
limit: 10000 // Fetch all
|
|
491
|
+
});
|
|
492
|
+
console.log(`Fetched ${allDocs.length} documents`);
|
|
493
|
+
|
|
494
|
+
// Find entities missing order property
|
|
495
|
+
const entitiesToUpdate = allDocs.filter((entity: Entity<M>) => {
|
|
496
|
+
const orderValue = entity.values?.[orderProperty];
|
|
497
|
+
return orderValue === undefined || orderValue === null;
|
|
498
|
+
});
|
|
499
|
+
console.log(`${entitiesToUpdate.length} entities need order values`);
|
|
500
|
+
|
|
501
|
+
// Assign sequential order values
|
|
502
|
+
const updates: Promise<void>[] = [];
|
|
503
|
+
entitiesToUpdate.forEach((entity: Entity<M>, index: number) => {
|
|
504
|
+
console.log(`Updating entity ${entity.id} with order ${index}`);
|
|
505
|
+
const updatedValues = setIn({ ...entity.values }, orderProperty, index);
|
|
506
|
+
|
|
507
|
+
const saveProps: SaveEntityProps = {
|
|
508
|
+
path: entity.path,
|
|
509
|
+
entityId: entity.id,
|
|
510
|
+
values: updatedValues as M,
|
|
511
|
+
previousValues: entity.values,
|
|
512
|
+
collection,
|
|
513
|
+
status: "existing"
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
updates.push(
|
|
517
|
+
saveEntityWithCallbacks({
|
|
518
|
+
...saveProps,
|
|
519
|
+
collection,
|
|
520
|
+
dataSource,
|
|
521
|
+
context,
|
|
522
|
+
afterSave: () => {
|
|
523
|
+
console.log(`Saved entity ${entity.id}`);
|
|
524
|
+
},
|
|
525
|
+
afterSaveError: (e) => console.error("Backfill save failed:", e)
|
|
526
|
+
}).then(() => {
|
|
527
|
+
})
|
|
528
|
+
);
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
console.log(`Total updates to run: ${updates.length}`);
|
|
532
|
+
await Promise.all(updates);
|
|
533
|
+
console.log("All updates complete");
|
|
534
|
+
setShowBackfillDialog(false);
|
|
535
|
+
|
|
536
|
+
// Reset missing count to hide banner
|
|
537
|
+
setMissingOrderCount(0);
|
|
538
|
+
|
|
539
|
+
// Refresh the board data
|
|
540
|
+
boardDataController.refreshAll();
|
|
541
|
+
} catch (e) {
|
|
542
|
+
console.error("Backfill error:", e);
|
|
543
|
+
} finally {
|
|
544
|
+
setBackfillLoading(false);
|
|
545
|
+
}
|
|
546
|
+
}, [orderProperty, fullPath, collection, dataSource, context, boardDataController, analyticsController]);
|
|
547
|
+
|
|
548
|
+
const handleEntityClick = useCallback((entity: Entity<M>) => {
|
|
549
|
+
onEntityClick?.(entity);
|
|
550
|
+
}, [onEntityClick]);
|
|
551
|
+
|
|
552
|
+
const handleSelectionChange = useCallback((entity: Entity<M>, selected: boolean) => {
|
|
553
|
+
selectionController?.toggleEntitySelection(entity, selected);
|
|
554
|
+
}, [selectionController]);
|
|
555
|
+
|
|
556
|
+
const isEntitySelected = useCallback((entity: Entity<M>) => {
|
|
557
|
+
return selectionController?.isEntitySelected(entity) ?? false;
|
|
558
|
+
}, [selectionController]);
|
|
559
|
+
|
|
560
|
+
const ItemComponent = useCallback((props: BoardItemViewProps<M>) => {
|
|
561
|
+
return (
|
|
562
|
+
<EntityBoardCard
|
|
563
|
+
{...props}
|
|
564
|
+
collection={collection}
|
|
565
|
+
onClick={handleEntityClick}
|
|
566
|
+
selected={isEntitySelected(props.item.entity)}
|
|
567
|
+
onSelectionChange={handleSelectionChange}
|
|
568
|
+
selectionEnabled={selectionEnabled}
|
|
569
|
+
/>
|
|
570
|
+
);
|
|
571
|
+
}, [collection, handleEntityClick, isEntitySelected, handleSelectionChange, selectionEnabled]);
|
|
572
|
+
|
|
573
|
+
// Get KanbanSetupComponent from plugins
|
|
574
|
+
const KanbanSetupComponent = useMemo(() => {
|
|
575
|
+
for (const plugin of plugins) {
|
|
576
|
+
if (plugin.collectionView?.KanbanSetupComponent) {
|
|
577
|
+
return plugin.collectionView.KanbanSetupComponent;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return null;
|
|
581
|
+
}, [plugins]);
|
|
582
|
+
|
|
583
|
+
// Get AddKanbanColumnComponent from plugins
|
|
584
|
+
const AddKanbanColumnComponent = useMemo(() => {
|
|
585
|
+
for (const plugin of plugins) {
|
|
586
|
+
if (plugin.collectionView?.AddKanbanColumnComponent) {
|
|
587
|
+
return plugin.collectionView.AddKanbanColumnComponent;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return null;
|
|
591
|
+
}, [plugins]);
|
|
592
|
+
|
|
593
|
+
// Check for loading error
|
|
594
|
+
const hasError = Boolean(dataLoadingError);
|
|
595
|
+
const errorMessage = dataLoadingError?.message || "";
|
|
596
|
+
const indexUrl = errorMessage.match(/https:\/\/console\.firebase\.google\.com[^\s]+/)?.[0];
|
|
597
|
+
|
|
598
|
+
// Error: no enum properties available for Kanban columns
|
|
599
|
+
if (!columnProperty || enumColumns.length === 0) {
|
|
600
|
+
return (
|
|
601
|
+
<div className="flex-1 flex flex-col items-center justify-center p-8 gap-4">
|
|
602
|
+
<Typography variant="h6">
|
|
603
|
+
Kanban view is not available
|
|
604
|
+
</Typography>
|
|
605
|
+
<Typography variant="body2" color="secondary" className="text-center max-w-md">
|
|
606
|
+
Kanban view requires a string property with enum values to group entities into columns.
|
|
607
|
+
Please add an enum property to your collection schema to use this view.
|
|
608
|
+
</Typography>
|
|
609
|
+
{KanbanSetupComponent && (
|
|
610
|
+
<KanbanSetupComponent
|
|
611
|
+
collection={collection}
|
|
612
|
+
fullPath={fullPath}
|
|
613
|
+
parentCollectionIds={parentCollectionIds}
|
|
614
|
+
/>
|
|
615
|
+
)}
|
|
616
|
+
</div>
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// Note: Empty state is not shown for Kanban view - we show the board with empty columns instead
|
|
621
|
+
// The emptyComponent is handled per-column in BoardColumn
|
|
622
|
+
|
|
623
|
+
// No columns
|
|
624
|
+
if (columns.length === 0) {
|
|
625
|
+
return (
|
|
626
|
+
<div className="flex-1 flex items-center justify-center p-8">
|
|
627
|
+
<Typography variant="label" color="secondary">
|
|
628
|
+
No enum values configured for property "{columnProperty}"
|
|
629
|
+
</Typography>
|
|
630
|
+
</div>
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
return (
|
|
635
|
+
<div className="flex-1 flex flex-col overflow-hidden">
|
|
636
|
+
{/* Error banner - only show when no data loaded */}
|
|
637
|
+
{hasError && allEntities.length === 0 && (
|
|
638
|
+
<div
|
|
639
|
+
className="flex items-center gap-4 px-4 py-3 bg-red-50 dark:bg-red-900/20 border-b border-red-200 dark:border-red-800">
|
|
640
|
+
<Typography variant="body2" className="text-red-700 dark:text-red-300 flex-1">
|
|
641
|
+
<strong>Error:</strong>{" "}
|
|
642
|
+
{indexUrl
|
|
643
|
+
? "A Firestore index is required for this query."
|
|
644
|
+
: errorMessage}
|
|
645
|
+
</Typography>
|
|
646
|
+
<Tooltip title="Refresh data">
|
|
647
|
+
<IconButton
|
|
648
|
+
size="small"
|
|
649
|
+
onClick={() => boardDataController.refreshAll()}
|
|
650
|
+
>
|
|
651
|
+
<RefreshIcon size="small" />
|
|
652
|
+
</IconButton>
|
|
653
|
+
</Tooltip>
|
|
654
|
+
{indexUrl && (
|
|
655
|
+
<Button
|
|
656
|
+
size="small"
|
|
657
|
+
variant="filled"
|
|
658
|
+
color="error"
|
|
659
|
+
onClick={() => window.open(indexUrl, "_blank")}
|
|
660
|
+
>
|
|
661
|
+
Create Index
|
|
662
|
+
</Button>
|
|
663
|
+
)}
|
|
664
|
+
</div>
|
|
665
|
+
)}
|
|
666
|
+
|
|
667
|
+
{/* Backfill info bar - non-blocking */}
|
|
668
|
+
{itemsNeedBackfill && !dataLoading && (
|
|
669
|
+
<div
|
|
670
|
+
className="flex items-center justify-between gap-4 px-4 py-2 bg-amber-50 dark:bg-amber-900/20 border-b border-amber-200 dark:border-amber-800">
|
|
671
|
+
<Typography variant="body2" color="secondary">
|
|
672
|
+
Some items don't have order values. Initialize to enable drag-and-drop reordering.
|
|
673
|
+
</Typography>
|
|
674
|
+
<Button
|
|
675
|
+
size="small"
|
|
676
|
+
variant="text"
|
|
677
|
+
onClick={() => setShowBackfillDialog(true)}
|
|
678
|
+
>
|
|
679
|
+
Initialize Order
|
|
680
|
+
</Button>
|
|
681
|
+
</div>
|
|
682
|
+
)}
|
|
683
|
+
|
|
684
|
+
{/* Main board */}
|
|
685
|
+
<div className="flex-1 overflow-auto no-scrollbar">
|
|
686
|
+
<Board
|
|
687
|
+
data={boardItems}
|
|
688
|
+
columns={columns}
|
|
689
|
+
columnLabels={columnLabels}
|
|
690
|
+
columnColors={columnColors}
|
|
691
|
+
assignColumn={assignColumn}
|
|
692
|
+
allowColumnReorder={allowColumnReorder}
|
|
693
|
+
onColumnReorder={handleColumnReorder}
|
|
694
|
+
onItemsReorder={handleItemsReorder}
|
|
695
|
+
ItemComponent={ItemComponent}
|
|
696
|
+
columnLoadingState={columnLoadingState}
|
|
697
|
+
onLoadMoreColumn={(column) => boardDataController.loadMoreColumn(column)}
|
|
698
|
+
onAddItemToColumn={(column) => {
|
|
699
|
+
analyticsController.onAnalyticsEvent?.("kanban_new_entity_in_column", {
|
|
700
|
+
path: fullPath,
|
|
701
|
+
column
|
|
702
|
+
});
|
|
703
|
+
sideEntityController.open({
|
|
704
|
+
path: fullPath,
|
|
705
|
+
collection,
|
|
706
|
+
entityId: undefined,
|
|
707
|
+
updateUrl: true,
|
|
708
|
+
formProps: {
|
|
709
|
+
initialDirtyValues: {
|
|
710
|
+
[columnProperty]: column
|
|
711
|
+
} as Partial<M>
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
}}
|
|
715
|
+
AddColumnComponent={AddKanbanColumnComponent && (
|
|
716
|
+
<AddKanbanColumnComponent
|
|
717
|
+
collection={collection}
|
|
718
|
+
fullPath={fullPath}
|
|
719
|
+
parentCollectionIds={parentCollectionIds}
|
|
720
|
+
columnProperty={columnProperty}
|
|
721
|
+
/>
|
|
722
|
+
)}
|
|
723
|
+
/>
|
|
724
|
+
</div>
|
|
725
|
+
|
|
726
|
+
{/* Backfill dialog */}
|
|
727
|
+
<Dialog open={showBackfillDialog} onOpenChange={setShowBackfillDialog}>
|
|
728
|
+
<DialogContent>
|
|
729
|
+
<Typography variant="h6" className="mb-4">Initialize Kanban Order</Typography>
|
|
730
|
+
<Typography variant="body2">
|
|
731
|
+
This will assign sequential order values to all items that don't have one.
|
|
732
|
+
Items will maintain their current order within each column.
|
|
733
|
+
</Typography>
|
|
734
|
+
</DialogContent>
|
|
735
|
+
<DialogActions>
|
|
736
|
+
<Button variant="text" onClick={() => setShowBackfillDialog(false)} disabled={backfillLoading}>
|
|
737
|
+
Cancel
|
|
738
|
+
</Button>
|
|
739
|
+
<Button onClick={handleBackfill} disabled={backfillLoading}>
|
|
740
|
+
{backfillLoading ? <CircularProgress size="smallest" /> : "Initialize"}
|
|
741
|
+
</Button>
|
|
742
|
+
</DialogActions>
|
|
743
|
+
</Dialog>
|
|
744
|
+
</div>
|
|
745
|
+
);
|
|
746
|
+
}
|