@rebasepro/cms 0.17.3 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/{CollectionEditorDialog-B-akreOU.js → CollectionEditorDialog-BeX4b92r.js} +13 -7
- package/dist/{CollectionEditorDialog-B-akreOU.js.map → CollectionEditorDialog-BeX4b92r.js.map} +1 -1
- package/dist/{PropertyEditView-CiY84wkR.js → PropertyEditView-C7thfj4L.js} +3 -3
- package/dist/{PropertyEditView-CiY84wkR.js.map → PropertyEditView-C7thfj4L.js.map} +1 -1
- package/dist/{RouterCollectionsStudioView-DkAWda4N.js → RouterCollectionsStudioView-BtjzvB6E.js} +4 -4
- package/dist/{RouterCollectionsStudioView-DkAWda4N.js.map → RouterCollectionsStudioView-BtjzvB6E.js.map} +1 -1
- package/dist/{SchemaChangeDialog-DceT8QFX.js → SchemaChangeDialog-CkqK6KOC.js} +4 -2
- package/dist/{SchemaChangeDialog-DceT8QFX.js.map → SchemaChangeDialog-CkqK6KOC.js.map} +1 -1
- package/dist/collection_editor/api/generateCollectionApi.d.ts +1 -2
- package/dist/collection_editor_ui.d.ts +2 -0
- package/dist/collection_editor_ui.js +6 -5
- package/dist/collection_editor_ui.js.map +1 -1
- package/dist/components/DeleteEntityDialog.d.ts +2 -3
- package/dist/components/RebaseLayout.d.ts +11 -4
- package/dist/components/field_configs.d.ts +1 -1
- package/dist/editor/sanitize-html.d.ts +15 -0
- package/dist/editor.js +195 -10
- package/dist/editor.js.map +1 -1
- package/dist/{export-Ben8E355.js → export--arni_VY.js} +2 -2
- package/dist/{export-Ben8E355.js.map → export--arni_VY.js.map} +1 -1
- package/dist/form/components/LabelWithIcon.d.ts +10 -0
- package/dist/{history-DIEVd26f.js → history-C2TpoQwi.js} +2 -2
- package/dist/{history-DIEVd26f.js.map → history-C2TpoQwi.js.map} +1 -1
- package/dist/hooks/navigation/useBuildNavigationStateController.d.ts +1 -1
- package/dist/hooks/navigation/useResolvedViews.d.ts +1 -1
- package/dist/hooks/navigation/useTopLevelNavigation.d.ts +1 -1
- package/dist/{import-D25x7ko-.js → import-DTkXNoBg.js} +2 -2
- package/dist/{import-D25x7ko-.js.map → import-DTkXNoBg.js.map} +1 -1
- package/dist/index.js +78 -33
- package/dist/index.js.map +1 -1
- package/dist/util/propertyConfigMapper.d.ts +1 -1
- package/dist/util-CfLFggP7.js +57 -0
- package/dist/util-CfLFggP7.js.map +1 -0
- package/dist/{util-DVqnqlLn.js → util-DE1WQW6h.js} +134 -112
- package/dist/util-DE1WQW6h.js.map +1 -0
- package/package.json +42 -34
- package/dist/util-DVqnqlLn.js.map +0 -1
- package/src/collection_editor/CollectionEditorDialogsContext.tsx +0 -25
- package/src/collection_editor/ConfigControllerProvider.tsx +0 -395
- package/src/collection_editor/_cms_internals.ts +0 -41
- package/src/collection_editor/api/generateCollectionApi.ts +0 -126
- package/src/collection_editor/api/index.ts +0 -1
- package/src/collection_editor/extensibility_types.ts +0 -168
- package/src/collection_editor/index.ts +0 -108
- package/src/collection_editor/liveSchemaClient.ts +0 -285
- package/src/collection_editor/relation_kinds.ts +0 -44
- package/src/collection_editor/serializable_types.ts +0 -535
- package/src/collection_editor/serializable_utils.ts +0 -729
- package/src/collection_editor/types/collection_editor_controller.tsx +0 -62
- package/src/collection_editor/types/collection_inference.ts +0 -18
- package/src/collection_editor/types/config_controller.tsx +0 -121
- package/src/collection_editor/ui/AddKanbanColumnAction.tsx +0 -199
- package/src/collection_editor/ui/CollectionViewHeaderAction.tsx +0 -51
- package/src/collection_editor/ui/EditorCollectionAction.tsx +0 -54
- package/src/collection_editor/ui/EditorCollectionActionStart.tsx +0 -90
- package/src/collection_editor/ui/EditorEntityAction.tsx +0 -50
- package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +0 -114
- package/src/collection_editor/ui/KanbanSetupAction.tsx +0 -43
- package/src/collection_editor/ui/MissingReferenceWidget.tsx +0 -35
- package/src/collection_editor/ui/NewCollectionButton.tsx +0 -27
- package/src/collection_editor/ui/NewCollectionCard.tsx +0 -48
- package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +0 -49
- package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +0 -260
- package/src/collection_editor/ui/collection_editor/AIModifiedPathsContext.tsx +0 -90
- package/src/collection_editor/ui/collection_editor/CollectionDetailsForm.tsx +0 -388
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +0 -1098
- package/src/collection_editor/ui/collection_editor/CollectionEditorWelcomeView.tsx +0 -301
- package/src/collection_editor/ui/collection_editor/CollectionJsonImportDialog.tsx +0 -172
- package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +0 -620
- package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +0 -530
- package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +0 -462
- package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +0 -104
- package/src/collection_editor/ui/collection_editor/CollectionYupValidation.tsx +0 -9
- package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +0 -199
- package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +0 -315
- package/src/collection_editor/ui/collection_editor/EntityActionsEditTab.tsx +0 -164
- package/src/collection_editor/ui/collection_editor/EntityActionsSelectDialog.tsx +0 -40
- package/src/collection_editor/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +0 -39
- package/src/collection_editor/ui/collection_editor/EnumForm.tsx +0 -373
- package/src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx +0 -288
- package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +0 -141
- package/src/collection_editor/ui/collection_editor/KanbanConfigSection.tsx +0 -194
- package/src/collection_editor/ui/collection_editor/LayoutModeSwitch.tsx +0 -53
- package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +0 -980
- package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +0 -164
- package/src/collection_editor/ui/collection_editor/PropertyTree.tsx +0 -364
- package/src/collection_editor/ui/collection_editor/RouterCollectionStudioView.tsx +0 -44
- package/src/collection_editor/ui/collection_editor/RouterCollectionsStudioView.tsx +0 -41
- package/src/collection_editor/ui/collection_editor/SchemaChangeDialog.tsx +0 -470
- package/src/collection_editor/ui/collection_editor/SubcollectionsEditTab.tsx +0 -256
- package/src/collection_editor/ui/collection_editor/SwitchControl.tsx +0 -39
- package/src/collection_editor/ui/collection_editor/ViewModeSwitch.tsx +0 -68
- package/src/collection_editor/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +0 -67
- package/src/collection_editor/ui/collection_editor/import/CollectionEditorImportMapping.tsx +0 -296
- package/src/collection_editor/ui/collection_editor/import/clean_import_data.ts +0 -57
- package/src/collection_editor/ui/collection_editor/properties/BlockPropertyField.tsx +0 -147
- package/src/collection_editor/ui/collection_editor/properties/BooleanPropertyField.tsx +0 -41
- package/src/collection_editor/ui/collection_editor/properties/CommonPropertyFields.tsx +0 -113
- package/src/collection_editor/ui/collection_editor/properties/DateTimePropertyField.tsx +0 -250
- package/src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx +0 -126
- package/src/collection_editor/ui/collection_editor/properties/KeyValuePropertyField.tsx +0 -20
- package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +0 -153
- package/src/collection_editor/ui/collection_editor/properties/MarkdownPropertyField.tsx +0 -217
- package/src/collection_editor/ui/collection_editor/properties/NumberPropertyField.tsx +0 -117
- package/src/collection_editor/ui/collection_editor/properties/ReferencePropertyField.tsx +0 -129
- package/src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx +0 -335
- package/src/collection_editor/ui/collection_editor/properties/RepeatPropertyField.tsx +0 -107
- package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +0 -403
- package/src/collection_editor/ui/collection_editor/properties/StringPropertyField.tsx +0 -148
- package/src/collection_editor/ui/collection_editor/properties/UrlPropertyField.tsx +0 -91
- package/src/collection_editor/ui/collection_editor/properties/VectorPropertyField.tsx +0 -34
- package/src/collection_editor/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +0 -49
- package/src/collection_editor/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +0 -925
- package/src/collection_editor/ui/collection_editor/properties/conditions/ConditionsPanel.tsx +0 -28
- package/src/collection_editor/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +0 -626
- package/src/collection_editor/ui/collection_editor/properties/conditions/index.ts +0 -6
- package/src/collection_editor/ui/collection_editor/properties/conditions/property_paths.ts +0 -93
- package/src/collection_editor/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +0 -52
- package/src/collection_editor/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +0 -63
- package/src/collection_editor/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +0 -114
- package/src/collection_editor/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +0 -154
- package/src/collection_editor/ui/collection_editor/properties/validation/ValidationPanel.tsx +0 -28
- package/src/collection_editor/ui/collection_editor/templates/blog_template.ts +0 -112
- package/src/collection_editor/ui/collection_editor/templates/pages_template.ts +0 -183
- package/src/collection_editor/ui/collection_editor/templates/products_template.ts +0 -88
- package/src/collection_editor/ui/collection_editor/templates/users_template.ts +0 -42
- package/src/collection_editor/ui/collection_editor/util.ts +0 -28
- package/src/collection_editor/ui/collection_editor/utils/strings.ts +0 -1
- package/src/collection_editor/ui/collection_editor/utils/supported_fields.tsx +0 -39
- package/src/collection_editor/ui/collection_editor/utils/update_property_for_widget.ts +0 -276
- package/src/collection_editor/useCollectionEditorController.tsx +0 -9
- package/src/collection_editor/useCollectionsConfigController.tsx +0 -9
- package/src/collection_editor/useJsonCollectionsConfigController.tsx +0 -297
- package/src/collection_editor/useLiveSchemaEditing.tsx +0 -315
- package/src/collection_editor/useLocalCollectionsConfigController.tsx +0 -341
- package/src/collection_editor/useSafeSnackbarController.ts +0 -9
- package/src/collection_editor/validateCollectionJson.ts +0 -440
- package/src/collection_editor_ui.ts +0 -21
- package/src/components/AdditionalFieldValue.tsx +0 -68
- package/src/components/AdminModeSyncer.tsx +0 -56
- package/src/components/ArrayContainer.tsx +0 -542
- package/src/components/ClearFilterSortButton.tsx +0 -56
- package/src/components/CollectionEditorDialogs.tsx +0 -69
- package/src/components/CollectionPanel.tsx +0 -179
- package/src/components/CollectionTableBinding/CollectionRowActions.tsx +0 -244
- package/src/components/CollectionTableBinding/CollectionTableBinding.tsx +0 -394
- package/src/components/CollectionTableBinding/CollectionTableBindingProps.tsx +0 -172
- package/src/components/CollectionTableBinding/PropertyTableCell.tsx +0 -350
- package/src/components/CollectionTableBinding/column_utils.tsx +0 -155
- package/src/components/CollectionTableBinding/fields/TableMultipleRelationField.tsx +0 -131
- package/src/components/CollectionTableBinding/fields/TableReferenceField.tsx +0 -193
- package/src/components/CollectionTableBinding/fields/TableRelationField.tsx +0 -192
- package/src/components/CollectionTableBinding/fields/TableRelationSelectorField.tsx +0 -42
- package/src/components/CollectionTableBinding/fields/TableStorageUpload.tsx +0 -324
- package/src/components/CollectionTableBinding/fields/VirtualTableSelect.tsx +0 -132
- package/src/components/CollectionTableBinding/fields/VirtualTableUserSelect.tsx +0 -41
- package/src/components/CollectionTableBinding/index.tsx +0 -14
- package/src/components/CollectionTableBinding/internal/CollectionTableToolbar.tsx +0 -96
- package/src/components/CollectionTableBinding/internal/EntityTableCell.tsx +0 -309
- package/src/components/CollectionTableBinding/internal/EntityTableCellActions.tsx +0 -80
- package/src/components/CollectionTableBinding/internal/common.tsx +0 -74
- package/src/components/CollectionTableBinding/internal/popup_field/PopupFormField.tsx +0 -422
- package/src/components/CollectionTableBinding/internal/popup_field/useDraggable.tsx +0 -99
- package/src/components/CollectionTableBinding/internal/popup_field/useWindowSize.tsx +0 -22
- package/src/components/CollectionTableBinding/table_bindings.tsx +0 -350
- package/src/components/CollectionViewBinding/BoardCardBinding.tsx +0 -263
- package/src/components/CollectionViewBinding/CollectionBoardViewBinding.tsx +0 -662
- package/src/components/CollectionViewBinding/CollectionCardViewBinding.tsx +0 -159
- package/src/components/CollectionViewBinding/CollectionListViewBinding.tsx +0 -1430
- package/src/components/CollectionViewBinding/CollectionViewActions.tsx +0 -227
- package/src/components/CollectionViewBinding/CollectionViewBinding.tsx +0 -1603
- package/src/components/CollectionViewBinding/CollectionViewStartActions.tsx +0 -240
- package/src/components/CollectionViewBinding/EntityCardBinding.tsx +0 -239
- package/src/components/CollectionViewBinding/FilterPresetsButton.tsx +0 -298
- package/src/components/CollectionViewBinding/FiltersDialog.tsx +0 -218
- package/src/components/CollectionViewBinding/SearchExplanation.tsx +0 -106
- package/src/components/CollectionViewBinding/SearchHighlight.tsx +0 -311
- package/src/components/CollectionViewBinding/SlotValue.tsx +0 -156
- package/src/components/CollectionViewBinding/SortButton.tsx +0 -354
- package/src/components/CollectionViewBinding/SplitListCloseButton.tsx +0 -49
- package/src/components/CollectionViewBinding/SplitListShowButton.tsx +0 -28
- package/src/components/CollectionViewBinding/SplitListView.tsx +0 -488
- package/src/components/CollectionViewBinding/SplitViewContext.tsx +0 -34
- package/src/components/CollectionViewBinding/ViewModeToggle.tsx +0 -250
- package/src/components/CollectionViewBinding/hooks/useCollectionInlineEditor.ts +0 -81
- package/src/components/CollectionViewBinding/hooks/useKanbanDragAndDrop.ts +0 -181
- package/src/components/CollectionViewBinding/useBoardDataController.tsx +0 -802
- package/src/components/CollectionViewBinding/usePreviewSlots.ts +0 -703
- package/src/components/CollectionViewBinding/useSelectionController.tsx +0 -40
- package/src/components/CollectionViewBinding/utils.ts +0 -22
- package/src/components/DefaultAppBar.tsx +0 -264
- package/src/components/DefaultDrawer.tsx +0 -593
- package/src/components/DeleteEntityDialog.tsx +0 -205
- package/src/components/DetailViewBinding.tsx +0 -731
- package/src/components/DrawerNavigationGroup.tsx +0 -141
- package/src/components/DrawerNavigationItem.tsx +0 -115
- package/src/components/EditFormActions.tsx +0 -303
- package/src/components/EditViewBinding.tsx +0 -1069
- package/src/components/EntityDisplayHeader.tsx +0 -170
- package/src/components/EntityIdentityBar.tsx +0 -428
- package/src/components/EntityInspector.tsx +0 -156
- package/src/components/EntityPreviewBinding.tsx +0 -432
- package/src/components/EntityPreviewNesting.tsx +0 -50
- package/src/components/EntityViewBinding.tsx +0 -374
- package/src/components/FieldCaption.tsx +0 -14
- package/src/components/HomePage/ContentHomePage.tsx +0 -586
- package/src/components/HomePage/FavouritesView.tsx +0 -60
- package/src/components/HomePage/HomePageDnD.tsx +0 -704
- package/src/components/HomePage/NavigationCard.tsx +0 -81
- package/src/components/HomePage/NavigationCardBinding.tsx +0 -107
- package/src/components/HomePage/NavigationGroup.tsx +0 -156
- package/src/components/HomePage/RenameGroupDialog.tsx +0 -123
- package/src/components/HomePage/SmallNavigationCard.tsx +0 -41
- package/src/components/HomePage/index.tsx +0 -5
- package/src/components/InlineEntityPreview.tsx +0 -149
- package/src/components/JsonPreviewBinding.tsx +0 -66
- package/src/components/PropertyCollectionView.tsx +0 -336
- package/src/components/PropertyConfigBadge.tsx +0 -28
- package/src/components/PropertyIdCopyTooltip.tsx +0 -47
- package/src/components/RebaseAuthGate.tsx +0 -44
- package/src/components/RebaseCMS.tsx +0 -30
- package/src/components/RebaseLayout.tsx +0 -80
- package/src/components/RebaseNavigation.tsx +0 -369
- package/src/components/RebaseRouteDefs.tsx +0 -127
- package/src/components/RebaseShell.tsx +0 -83
- package/src/components/ReferenceTable/SelectionTableBinding.tsx +0 -389
- package/src/components/ReferenceWidget.tsx +0 -156
- package/src/components/RelationSelector.tsx +0 -926
- package/src/components/SearchIconsView.tsx +0 -78
- package/src/components/SelectableTable/SelectableTable.tsx +0 -309
- package/src/components/SelectableTable/SelectableTableContext.tsx +0 -7
- package/src/components/SelectableTable/SelectionStore.ts +0 -43
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +0 -59
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +0 -146
- package/src/components/SelectableTable/filters/FilterFieldBinding.tsx +0 -190
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +0 -250
- package/src/components/SelectableTable/filters/RelationFilterField.tsx +0 -238
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +0 -282
- package/src/components/SelectableTable/filters/null_filter.ts +0 -63
- package/src/components/SideDialogs.tsx +0 -238
- package/src/components/SidePanelBinding.tsx +0 -361
- package/src/components/SidePanelProvider.tsx +0 -80
- package/src/components/UserSelector.tsx +0 -513
- package/src/components/admin/CreationResultDialog.tsx +0 -138
- package/src/components/admin/index.ts +0 -1
- package/src/components/app/AppBar.tsx +0 -17
- package/src/components/app/Drawer.tsx +0 -38
- package/src/components/app/Scaffold.tsx +0 -366
- package/src/components/app/index.ts +0 -4
- package/src/components/app/useApp.tsx +0 -36
- package/src/components/common/default_entity_actions.tsx +0 -440
- package/src/components/common/index.ts +0 -1
- package/src/components/field_configs.tsx +0 -506
- package/src/components/history/EntityHistoryEntry.tsx +0 -203
- package/src/components/history/EntityHistoryView.tsx +0 -206
- package/src/components/history/LastEditedByFormAction.tsx +0 -24
- package/src/components/history/LastEditedByIndicator.tsx +0 -95
- package/src/components/history/UserChip.tsx +0 -15
- package/src/components/history/index.tsx +0 -5
- package/src/components/index.ts +0 -63
- package/src/contexts/BreacrumbsContext.tsx +0 -45
- package/src/contexts/SideDialogsControllerContext.tsx +0 -5
- package/src/contexts/SidePanelControllerContext.tsx +0 -5
- package/src/data_export/export/BasicExportAction.tsx +0 -142
- package/src/data_export/export/ExportCollectionAction.tsx +0 -321
- package/src/data_export/export/export.ts +0 -295
- package/src/data_export/export/fetch_export_data.ts +0 -90
- package/src/data_export/export/index.ts +0 -4
- package/src/data_export/index.ts +0 -1
- package/src/data_import/components/DataNewPropertiesMapping.tsx +0 -261
- package/src/data_import/components/ImportFileUpload.tsx +0 -42
- package/src/data_import/components/ImportNewPropertyFieldPreview.tsx +0 -58
- package/src/data_import/components/ImportSaveInProgress.tsx +0 -121
- package/src/data_import/components/index.ts +0 -4
- package/src/data_import/hooks/index.ts +0 -1
- package/src/data_import/hooks/useImportConfig.tsx +0 -34
- package/src/data_import/import/ImportCollectionAction.tsx +0 -461
- package/src/data_import/import/index.ts +0 -1
- package/src/data_import/index.ts +0 -5
- package/src/data_import/types/column_mapping.ts +0 -32
- package/src/data_import/types/index.ts +0 -1
- package/src/data_import/utils/csv.ts +0 -153
- package/src/data_import/utils/data.ts +0 -181
- package/src/data_import/utils/file_headers.ts +0 -14
- package/src/data_import/utils/file_to_json.ts +0 -149
- package/src/data_import/utils/get_import_inference_type.ts +0 -33
- package/src/data_import/utils/get_properties_mapping.ts +0 -67
- package/src/data_import/utils/index.ts +0 -5
- package/src/data_import/utils/save_entities.ts +0 -138
- package/src/data_import/utils/transforms.ts +0 -70
- package/src/editor/components/SlashCommandMenu.tsx +0 -532
- package/src/editor/components/editor-bubble-item.tsx +0 -32
- package/src/editor/components/editor-bubble.tsx +0 -143
- package/src/editor/components/image-bubble.tsx +0 -183
- package/src/editor/components/index.ts +0 -14
- package/src/editor/components/table-bubble.tsx +0 -233
- package/src/editor/editor.tsx +0 -529
- package/src/editor/extensions/HighlightDecorationExtension.ts +0 -115
- package/src/editor/extensions/Image.ts +0 -159
- package/src/editor/extensions/TextLoadingDecorationExtension.tsx +0 -107
- package/src/editor/extensions/clipboard.ts +0 -72
- package/src/editor/extensions/custom-keymap.ts +0 -25
- package/src/editor/extensions/drag-and-drop.tsx +0 -508
- package/src/editor/hooks/useProseMirror.ts +0 -126
- package/src/editor/hooks/useProseMirrorContext.ts +0 -15
- package/src/editor/index.ts +0 -2
- package/src/editor/markdown-it-plugins.d.ts +0 -24
- package/src/editor/markdown.ts +0 -204
- package/src/editor/nodeViews/ImageComponent.tsx +0 -20
- package/src/editor/nodeViews/ReactNodeView.tsx +0 -89
- package/src/editor/nodeViews/TaskItemComponent.tsx +0 -30
- package/src/editor/nodeViews/index.ts +0 -35
- package/src/editor/plugins/index.ts +0 -58
- package/src/editor/plugins/inputrules.ts +0 -82
- package/src/editor/plugins/placeholderPlugin.ts +0 -55
- package/src/editor/plugins/slashCommandPlugin.ts +0 -65
- package/src/editor/schema.ts +0 -339
- package/src/editor/selectors/ai-selector.tsx +0 -110
- package/src/editor/selectors/color-selector.tsx +0 -199
- package/src/editor/selectors/link-selector.tsx +0 -122
- package/src/editor/selectors/node-selector.tsx +0 -159
- package/src/editor/selectors/text-buttons.tsx +0 -79
- package/src/editor/types.ts +0 -6
- package/src/editor/useProseMirror.ts +0 -125
- package/src/editor/utils/prosemirror-utils.ts +0 -113
- package/src/editor/utils/remove_classes.ts +0 -18
- package/src/editor/utils/useDebouncedCallback.ts +0 -25
- package/src/form/EntityForm.tsx +0 -761
- package/src/form/EntityFormActions.tsx +0 -160
- package/src/form/EntityFormBinding.tsx +0 -342
- package/src/form/PropertyFieldBinding.tsx +0 -348
- package/src/form/components/ErrorFocus.tsx +0 -44
- package/src/form/components/FieldBlock.tsx +0 -189
- package/src/form/components/FieldHelperText.tsx +0 -84
- package/src/form/components/FormRail.tsx +0 -153
- package/src/form/components/FormSections.tsx +0 -145
- package/src/form/components/LabelWithIcon.tsx +0 -43
- package/src/form/components/LabelWithIconAndTooltip.tsx +0 -28
- package/src/form/components/LocalChangesMenu.tsx +0 -147
- package/src/form/components/StorageItemPreview.tsx +0 -81
- package/src/form/components/StorageUploadProgress.tsx +0 -118
- package/src/form/components/index.tsx +0 -6
- package/src/form/components/useRailVisible.tsx +0 -47
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +0 -109
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +0 -172
- package/src/form/field_bindings/BinaryFieldBinding.tsx +0 -177
- package/src/form/field_bindings/BlockFieldBinding.tsx +0 -282
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +0 -78
- package/src/form/field_bindings/GeopointFieldBinding.tsx +0 -200
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +0 -574
- package/src/form/field_bindings/MapFieldBinding.tsx +0 -120
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +0 -259
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +0 -130
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +0 -168
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +0 -94
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +0 -146
- package/src/form/field_bindings/RelationFieldBinding.tsx +0 -202
- package/src/form/field_bindings/RepeatFieldBinding.tsx +0 -143
- package/src/form/field_bindings/SelectFieldBinding.tsx +0 -111
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +0 -521
- package/src/form/field_bindings/SwitchFieldBinding.tsx +0 -70
- package/src/form/field_bindings/TextFieldBinding.tsx +0 -189
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +0 -71
- package/src/form/field_bindings/VectorFieldBinding.tsx +0 -209
- package/src/form/form_utils.ts +0 -243
- package/src/form/index.tsx +0 -36
- package/src/form/useClearRestoreValue.tsx +0 -36
- package/src/form/useUndoableDiscard.ts +0 -39
- package/src/form/validation.ts +0 -583
- package/src/hooks/index.ts +0 -16
- package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +0 -22
- package/src/hooks/navigation/contexts/NavigationStateContext.tsx +0 -16
- package/src/hooks/navigation/contexts/UrlContext.tsx +0 -24
- package/src/hooks/navigation/contexts/index.ts +0 -14
- package/src/hooks/navigation/useAsyncResolver.ts +0 -100
- package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +0 -218
- package/src/hooks/navigation/useBuildNavigationStateController.tsx +0 -134
- package/src/hooks/navigation/useBuildUrlController.tsx +0 -66
- package/src/hooks/navigation/useNavigationResolution.ts +0 -271
- package/src/hooks/navigation/useResolvedCollections.ts +0 -102
- package/src/hooks/navigation/useResolvedViews.tsx +0 -139
- package/src/hooks/navigation/useTopLevelNavigation.ts +0 -273
- package/src/hooks/navigation/utils.ts +0 -200
- package/src/hooks/useAdminContext.tsx +0 -83
- package/src/hooks/useBreadcrumbsController.tsx +0 -17
- package/src/hooks/useBuildSideDialogsController.tsx +0 -145
- package/src/hooks/useBuildSidePanel.tsx +0 -315
- package/src/hooks/useChildViewSource.ts +0 -46
- package/src/hooks/useEntityDisplay.tsx +0 -262
- package/src/hooks/useEntityDisplayTitle.tsx +0 -49
- package/src/hooks/useHistory.ts +0 -178
- package/src/hooks/useRecordActions.tsx +0 -69
- package/src/hooks/useResolvedNavigationFrom.tsx +0 -167
- package/src/hooks/useResolvedUsers.ts +0 -148
- package/src/hooks/useSelectionDialog.tsx +0 -58
- package/src/hooks/useSideDialogsController.tsx +0 -25
- package/src/hooks/useSidePanel.tsx +0 -13
- package/src/index.ts +0 -124
- package/src/preview/PropertyPreview.tsx +0 -331
- package/src/preview/compact_text.ts +0 -68
- package/src/preview/components/ArrayEnumPreview.tsx +0 -39
- package/src/preview/components/BooleanPreview.tsx +0 -28
- package/src/preview/components/DatePreview.tsx +0 -106
- package/src/preview/components/EmptyValue.tsx +0 -10
- package/src/preview/components/EnumValuesChip.tsx +0 -39
- package/src/preview/components/ImagePreview.tsx +0 -144
- package/src/preview/components/InlineEntityListPreview.tsx +0 -42
- package/src/preview/components/ReferencePreview.tsx +0 -235
- package/src/preview/components/RelationPreview.tsx +0 -271
- package/src/preview/components/StorageThumbnail.tsx +0 -147
- package/src/preview/components/UrlComponentPreview.tsx +0 -116
- package/src/preview/components/UserPreview.tsx +0 -30
- package/src/preview/components/date_fns_locales.ts +0 -125
- package/src/preview/index.ts +0 -26
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -73
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +0 -67
- package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +0 -77
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +0 -49
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -70
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +0 -79
- package/src/preview/property_previews/ArrayPropertyEnumPreview.tsx +0 -35
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +0 -79
- package/src/preview/property_previews/MapPropertyPreview.tsx +0 -198
- package/src/preview/property_previews/NumberPropertyPreview.tsx +0 -39
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +0 -276
- package/src/preview/property_previews/StringPropertyPreview.tsx +0 -70
- package/src/preview/util.ts +0 -39
- package/src/routes/CustomViewRoute.tsx +0 -33
- package/src/routes/RebaseRoute.tsx +0 -467
- package/src/routes/index.ts +0 -2
- package/src/types/components/EntityFormActionsProps.tsx +0 -20
- package/src/types/components/EntityFormProps.tsx +0 -119
- package/src/types/components/PropertyPreviewProps.tsx +0 -85
- package/src/types/components/formex.tsx +0 -2
- package/src/types/components/index.ts +0 -3
- package/src/types/fields.tsx +0 -340
- package/src/types/index.ts +0 -4
- package/src/util/dataControllerAdapter.ts +0 -88
- package/src/util/entity_actions.ts +0 -28
- package/src/util/index.ts +0 -5
- package/src/util/navigation_utils.ts +0 -89
- package/src/util/number_format.ts +0 -46
- package/src/util/previews.ts +0 -131
- package/src/util/propertyConfigMapper.ts +0 -134
- package/src/util/property_utils.tsx +0 -236
- package/src/util/resolutions.ts +0 -96
- package/src/util/view_constants.ts +0 -33
- package/src/util/view_mode.ts +0 -176
|
@@ -1,662 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
-
import { Entity, EnumValueConfig, MAX_LIST_LIMIT } from "@rebasepro/types";
|
|
4
|
-
import { EntityTableController, SelectionController, AdminCollection } from "@rebasepro/cms-types";
|
|
5
|
-
import { BoardCardBinding } from "./BoardCardBinding";
|
|
6
|
-
import {
|
|
7
|
-
Button,
|
|
8
|
-
ChipColorKey,
|
|
9
|
-
ChipColorScheme,
|
|
10
|
-
CircularProgress,
|
|
11
|
-
Dialog,
|
|
12
|
-
DialogActions,
|
|
13
|
-
DialogContent,
|
|
14
|
-
DialogTitle,
|
|
15
|
-
getColorSchemeForSeed,
|
|
16
|
-
IconButton,
|
|
17
|
-
iconSize,
|
|
18
|
-
RefreshCwIcon,
|
|
19
|
-
Tooltip,
|
|
20
|
-
Typography,
|
|
21
|
-
KanbanView,
|
|
22
|
-
BoardItem,
|
|
23
|
-
BoardItemViewProps,
|
|
24
|
-
ColumnLoadingState
|
|
25
|
-
} from "@rebasepro/ui";
|
|
26
|
-
import { resolveEnumValues } from "@rebasepro/common";
|
|
27
|
-
import { getPropertyInPath } from "../../util/property_utils";
|
|
28
|
-
import {
|
|
29
|
-
saveEntityWithCallbacks,
|
|
30
|
-
SaveEntityWithCallbacksProps,
|
|
31
|
-
useAuthController,
|
|
32
|
-
useCustomizationController,
|
|
33
|
-
useData,
|
|
34
|
-
useRebaseContext,
|
|
35
|
-
useTranslation,
|
|
36
|
-
useSlot
|
|
37
|
-
} from "@rebasepro/app";
|
|
38
|
-
import { useAnalyticsController } from "@rebasepro/app";
|
|
39
|
-
import { setIn } from "@rebasepro/forms";
|
|
40
|
-
import { useBoardDataController } from "./useBoardDataController";
|
|
41
|
-
import { isValidOrderKey, ORDER_KEY_DIGITS, useKanbanDragAndDrop } from "./hooks/useKanbanDragAndDrop";
|
|
42
|
-
import { useSidePanel } from "../../hooks/useSidePanel";
|
|
43
|
-
import { generateNKeysBetween } from "fractional-indexing";
|
|
44
|
-
|
|
45
|
-
export type CollectionBoardViewBindingProps<M extends Record<string, unknown> = Record<string, unknown>> = {
|
|
46
|
-
collection: AdminCollection<M>;
|
|
47
|
-
tableController: EntityTableController<M>;
|
|
48
|
-
fullPath: string;
|
|
49
|
-
parentCollectionSlugs?: string[], parentEntityIds?: string[];
|
|
50
|
-
columnProperty: string;
|
|
51
|
-
onEntityClick?: (entity: Entity<M>) => void;
|
|
52
|
-
selectionController?: SelectionController<M>;
|
|
53
|
-
selectionEnabled?: boolean;
|
|
54
|
-
highlightedEntities?: Entity<M>[];
|
|
55
|
-
emptyComponent?: React.ReactNode;
|
|
56
|
-
/** Called when entities are deleted - used for optimistic count updates */
|
|
57
|
-
deletedEntities?: Entity<M>[];
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Kanban board view for displaying entities grouped by a string enum property.
|
|
62
|
-
*/
|
|
63
|
-
export function CollectionBoardViewBinding<M extends Record<string, unknown> = Record<string, unknown>>({
|
|
64
|
-
collection,
|
|
65
|
-
tableController,
|
|
66
|
-
fullPath,
|
|
67
|
-
parentCollectionSlugs = [],
|
|
68
|
-
parentEntityIds = [],
|
|
69
|
-
columnProperty,
|
|
70
|
-
onEntityClick,
|
|
71
|
-
selectionController,
|
|
72
|
-
selectionEnabled = true,
|
|
73
|
-
highlightedEntities,
|
|
74
|
-
emptyComponent,
|
|
75
|
-
deletedEntities
|
|
76
|
-
}: CollectionBoardViewBindingProps<M>) {
|
|
77
|
-
const customizationController = useCustomizationController();
|
|
78
|
-
const context = useRebaseContext();
|
|
79
|
-
const dataClient = useData();
|
|
80
|
-
const sidePanelController = useSidePanel();
|
|
81
|
-
const analyticsController = useAnalyticsController();
|
|
82
|
-
const { t } = useTranslation();
|
|
83
|
-
const plugins = customizationController.plugins ?? [];
|
|
84
|
-
|
|
85
|
-
// State for backfill dialog
|
|
86
|
-
const [showBackfillDialog, setShowBackfillDialog] = useState(false);
|
|
87
|
-
const [backfillLoading, setBackfillLoading] = useState(false);
|
|
88
|
-
|
|
89
|
-
// v4: use collection directly without resolving
|
|
90
|
-
|
|
91
|
-
// Get orderProperty from collection config, but validate it exists as a real property
|
|
92
|
-
const rawOrderProperty = collection.orderProperty;
|
|
93
|
-
const orderProperty = useMemo(() => {
|
|
94
|
-
if (!rawOrderProperty) return undefined;
|
|
95
|
-
// Check if the property actually exists in the collection
|
|
96
|
-
const property = getPropertyInPath(collection.properties, rawOrderProperty);
|
|
97
|
-
if (!property) {
|
|
98
|
-
console.warn(`orderProperty "${rawOrderProperty}" is defined but does not exist in the collection properties. Treating as unconfigured.`);
|
|
99
|
-
return undefined;
|
|
100
|
-
}
|
|
101
|
-
return rawOrderProperty;
|
|
102
|
-
}, [rawOrderProperty, collection.properties]);
|
|
103
|
-
|
|
104
|
-
// Get columns from the property's enumValues
|
|
105
|
-
const {
|
|
106
|
-
enumColumns,
|
|
107
|
-
columnLabels,
|
|
108
|
-
columnColors
|
|
109
|
-
} = useMemo(() => {
|
|
110
|
-
const property = getPropertyInPath(collection.properties, columnProperty);
|
|
111
|
-
if (!property || !("type" in property) || property.type !== "string") {
|
|
112
|
-
return {
|
|
113
|
-
enumColumns: [] as string[],
|
|
114
|
-
columnLabels: {} as Record<string, string>
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
const stringProperty = property;
|
|
118
|
-
if (!stringProperty.enum) {
|
|
119
|
-
return {
|
|
120
|
-
enumColumns: [] as string[],
|
|
121
|
-
columnLabels: {} as Record<string, string>
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
const enumValues = resolveEnumValues(stringProperty.enum);
|
|
125
|
-
if (!enumValues) {
|
|
126
|
-
return {
|
|
127
|
-
enumColumns: [] as string[],
|
|
128
|
-
columnLabels: {} as Record<string, string>
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
const cols = enumValues.map((ev: EnumValueConfig) => String(ev.id));
|
|
132
|
-
const labels = enumValues.reduce((acc: Record<string, string>, ev: EnumValueConfig) => {
|
|
133
|
-
acc[String(ev.id)] = ev.label;
|
|
134
|
-
return acc;
|
|
135
|
-
}, {});
|
|
136
|
-
const colors = enumValues.reduce((acc: Record<string, ChipColorKey | ChipColorScheme | undefined>, ev: EnumValueConfig) => {
|
|
137
|
-
acc[String(ev.id)] = ev.color ?? getColorSchemeForSeed(String(ev.id));
|
|
138
|
-
return acc;
|
|
139
|
-
}, {});
|
|
140
|
-
return {
|
|
141
|
-
enumColumns: cols,
|
|
142
|
-
columnLabels: labels,
|
|
143
|
-
columnColors: colors
|
|
144
|
-
};
|
|
145
|
-
}, [collection, columnProperty]);
|
|
146
|
-
|
|
147
|
-
// Track if user has manually reordered columns in this session
|
|
148
|
-
const [hasUserReordered, setHasUserReordered] = useState(false);
|
|
149
|
-
// Column order is derived from the property's enumValues order
|
|
150
|
-
// Local state tracks session reordering before it's persisted
|
|
151
|
-
const [localColumnsOrder, setLocalColumnsOrder] = useState<string[]>(enumColumns);
|
|
152
|
-
|
|
153
|
-
useEffect(() => {
|
|
154
|
-
if (!hasUserReordered) {
|
|
155
|
-
// Sync with enumColumns when property changes
|
|
156
|
-
setLocalColumnsOrder(enumColumns);
|
|
157
|
-
} else {
|
|
158
|
-
// User has reordered - only add any missing columns
|
|
159
|
-
const missingColumns = enumColumns.filter(c => !localColumnsOrder.includes(c));
|
|
160
|
-
if (missingColumns.length > 0) {
|
|
161
|
-
setLocalColumnsOrder(prev => [...prev, ...missingColumns]);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}, [enumColumns, hasUserReordered]);
|
|
165
|
-
|
|
166
|
-
const columns = localColumnsOrder;
|
|
167
|
-
|
|
168
|
-
// Use the new per-column data controller
|
|
169
|
-
const boardDataController = useBoardDataController<M>({
|
|
170
|
-
fullPath,
|
|
171
|
-
collection,
|
|
172
|
-
columnProperty,
|
|
173
|
-
columns,
|
|
174
|
-
orderProperty,
|
|
175
|
-
pageSize: 30,
|
|
176
|
-
searchString: tableController.searchString,
|
|
177
|
-
filterValues: tableController.filterValues
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
// Aggregate loading and error state
|
|
181
|
-
const dataLoading = boardDataController.loading;
|
|
182
|
-
const dataLoadingError = boardDataController.error;
|
|
183
|
-
|
|
184
|
-
// Track previously processed deleted entities to avoid double-counting
|
|
185
|
-
const processedDeletedRef = useRef<Set<string>>(new Set());
|
|
186
|
-
|
|
187
|
-
// Optimistic update for column counts when entities are deleted
|
|
188
|
-
useEffect(() => {
|
|
189
|
-
if (!deletedEntities || deletedEntities.length === 0) return;
|
|
190
|
-
|
|
191
|
-
// Calculate column deltas from deleted entities
|
|
192
|
-
const deltas: Record<string, number> = {};
|
|
193
|
-
deletedEntities.forEach(entity => {
|
|
194
|
-
// Skip if we've already processed this entity
|
|
195
|
-
if (processedDeletedRef.current.has(String(entity.id))) return;
|
|
196
|
-
processedDeletedRef.current.add(String(entity.id));
|
|
197
|
-
|
|
198
|
-
const col = entity.values?.[columnProperty];
|
|
199
|
-
if (col && typeof col === "string") {
|
|
200
|
-
deltas[col] = (deltas[col] ?? 0) + 1;
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
if (Object.keys(deltas).length > 0) {
|
|
205
|
-
boardDataController.decrementColumnCounts(deltas);
|
|
206
|
-
}
|
|
207
|
-
}, [deletedEntities, columnProperty, boardDataController]);
|
|
208
|
-
|
|
209
|
-
// Build all entities from all columns for operations that need the full list
|
|
210
|
-
const allEntities = useMemo(() => {
|
|
211
|
-
const entities: Entity<M>[] = [];
|
|
212
|
-
const seenIds = new Set<string>();
|
|
213
|
-
columns.forEach(col => {
|
|
214
|
-
const colData = boardDataController.columnData[col];
|
|
215
|
-
if (colData?.entities) {
|
|
216
|
-
colData.entities.forEach((entity: Entity<M>) => {
|
|
217
|
-
const idStr = String(entity.id);
|
|
218
|
-
if (!seenIds.has(idStr)) {
|
|
219
|
-
seenIds.add(idStr);
|
|
220
|
-
entities.push(entity);
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
return entities;
|
|
226
|
-
}, [boardDataController.columnData, columns]);
|
|
227
|
-
|
|
228
|
-
const allowColumnReorder = useMemo(() => {
|
|
229
|
-
return plugins.some(plugin => plugin.hooks?.onKanbanColumnsReorder);
|
|
230
|
-
}, [plugins]);
|
|
231
|
-
|
|
232
|
-
const handleColumnReorder = useCallback((newColumns: string[]) => {
|
|
233
|
-
analyticsController.onAnalyticsEvent?.("kanban_column_reorder", {
|
|
234
|
-
path: fullPath,
|
|
235
|
-
columnProperty
|
|
236
|
-
});
|
|
237
|
-
setHasUserReordered(true);
|
|
238
|
-
setLocalColumnsOrder(newColumns);
|
|
239
|
-
plugins
|
|
240
|
-
.filter(plugin => plugin.hooks?.onKanbanColumnsReorder)
|
|
241
|
-
.forEach(plugin => {
|
|
242
|
-
plugin.hooks!.onKanbanColumnsReorder!({
|
|
243
|
-
fullPath,
|
|
244
|
-
parentCollectionSlugs,
|
|
245
|
-
parentEntityIds,
|
|
246
|
-
collection,
|
|
247
|
-
kanbanColumnProperty: columnProperty,
|
|
248
|
-
newColumnsOrder: newColumns
|
|
249
|
-
});
|
|
250
|
-
});
|
|
251
|
-
}, [plugins, fullPath, parentCollectionSlugs, parentEntityIds, collection, columnProperty, analyticsController]);
|
|
252
|
-
|
|
253
|
-
// Collection-level count queries to detect missing order property
|
|
254
|
-
// Just TWO counts: total and ordered (for the entire collection, not per column)
|
|
255
|
-
const [missingOrderCount, setMissingOrderCount] = useState<number>(0);
|
|
256
|
-
|
|
257
|
-
const dataClientRef = useRef(dataClient);
|
|
258
|
-
const collectionRef = useRef(collection);
|
|
259
|
-
dataClientRef.current = dataClient;
|
|
260
|
-
collectionRef.current = collection;
|
|
261
|
-
|
|
262
|
-
useEffect(() => {
|
|
263
|
-
const currentDataClient = dataClientRef.current;
|
|
264
|
-
const accessor = currentDataClient.collection(fullPath);
|
|
265
|
-
|
|
266
|
-
if (!orderProperty || !accessor.count) {
|
|
267
|
-
setMissingOrderCount(0);
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Count 1: Total documents in collection
|
|
272
|
-
// Count 2: Documents with orderProperty != null
|
|
273
|
-
let totalCount = 0;
|
|
274
|
-
let orderedCount = 0;
|
|
275
|
-
let completed = 0;
|
|
276
|
-
|
|
277
|
-
accessor.count().then(count => {
|
|
278
|
-
totalCount = count;
|
|
279
|
-
completed++;
|
|
280
|
-
if (completed === 2) {
|
|
281
|
-
setMissingOrderCount(Math.max(0, totalCount - orderedCount));
|
|
282
|
-
}
|
|
283
|
-
}).catch(e => console.warn("Failed to get total count:", e));
|
|
284
|
-
|
|
285
|
-
accessor.count({
|
|
286
|
-
where: { [orderProperty]: ["!=", null] }
|
|
287
|
-
}).then(count => {
|
|
288
|
-
orderedCount = count;
|
|
289
|
-
completed++;
|
|
290
|
-
if (completed === 2) {
|
|
291
|
-
setMissingOrderCount(Math.max(0, totalCount - orderedCount));
|
|
292
|
-
}
|
|
293
|
-
}).catch(e => console.warn("Failed to get ordered count:", e));
|
|
294
|
-
}, [orderProperty, fullPath]); // Only re-run when these primitives change
|
|
295
|
-
|
|
296
|
-
// Check if items need backfill (have no orderProperty values)
|
|
297
|
-
const itemsNeedBackfill = useMemo(() => {
|
|
298
|
-
if (!orderProperty || dataLoading) return false;
|
|
299
|
-
// Use collection-level count detection
|
|
300
|
-
if (missingOrderCount > 0) return true;
|
|
301
|
-
// A value that is present but is not a fractional-indexing key is no
|
|
302
|
-
// more usable than a missing one — dropping a card next to it cannot
|
|
303
|
-
// produce a key between the two — so it earns the same offer to
|
|
304
|
-
// initialise the column.
|
|
305
|
-
return allEntities.some((entity: Entity<M>) => !isValidOrderKey(entity.values?.[orderProperty]));
|
|
306
|
-
}, [allEntities, orderProperty, dataLoading, missingOrderCount]);
|
|
307
|
-
|
|
308
|
-
// Create a lookup map of entity ID → column from boardDataController data
|
|
309
|
-
// This ensures items stay in the column they were fetched for, not re-evaluated from entity.values
|
|
310
|
-
const entityColumnMap = useMemo(() => {
|
|
311
|
-
const map: Record<string, string> = {};
|
|
312
|
-
columns.forEach(col => {
|
|
313
|
-
const colData = boardDataController.columnData[col];
|
|
314
|
-
if (colData?.entities) {
|
|
315
|
-
colData.entities.forEach((entity: Entity<M>) => {
|
|
316
|
-
map[String(entity.id)] = col;
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
|
-
return map;
|
|
321
|
-
}, [columns, boardDataController.columnData]);
|
|
322
|
-
|
|
323
|
-
// Convert entities to board items per column (data already sorted by orderProperty from controller)
|
|
324
|
-
const boardItems: BoardItem<Entity<M>>[] = useMemo(() => {
|
|
325
|
-
return allEntities.map((entity: Entity<M>) => ({
|
|
326
|
-
id: String(entity.id),
|
|
327
|
-
data: entity
|
|
328
|
-
}));
|
|
329
|
-
}, [allEntities]);
|
|
330
|
-
|
|
331
|
-
// Column loading state from the board data controller
|
|
332
|
-
const columnLoadingState: ColumnLoadingState = useMemo(() => {
|
|
333
|
-
const state: ColumnLoadingState = {};
|
|
334
|
-
columns.forEach(col => {
|
|
335
|
-
const colData = boardDataController.columnData[col];
|
|
336
|
-
state[col] = {
|
|
337
|
-
loading: colData?.loading ?? true,
|
|
338
|
-
hasMore: colData?.hasMore ?? false,
|
|
339
|
-
itemCount: colData?.entities?.length ?? 0,
|
|
340
|
-
totalCount: colData?.totalCount,
|
|
341
|
-
error: colData?.error
|
|
342
|
-
};
|
|
343
|
-
});
|
|
344
|
-
return state;
|
|
345
|
-
}, [columns, boardDataController.columnData]);
|
|
346
|
-
|
|
347
|
-
// Use the lookup map to assign columns - ensures items stay in the column they were fetched for
|
|
348
|
-
const assignColumn = useCallback((item: BoardItem<Entity<M>>): string => {
|
|
349
|
-
const column = entityColumnMap[item.id];
|
|
350
|
-
if (column) return column;
|
|
351
|
-
// Fallback: read from entity values (for newly created items or edge cases)
|
|
352
|
-
const value = item.data.values?.[columnProperty];
|
|
353
|
-
if (value && columns.includes(String(value))) return String(value);
|
|
354
|
-
return columns[0] || "";
|
|
355
|
-
}, [entityColumnMap, columnProperty, columns]);
|
|
356
|
-
|
|
357
|
-
const { handleItemsReorder } = useKanbanDragAndDrop({
|
|
358
|
-
collection,
|
|
359
|
-
fullPath,
|
|
360
|
-
columnProperty,
|
|
361
|
-
orderProperty,
|
|
362
|
-
dataClient,
|
|
363
|
-
context,
|
|
364
|
-
boardDataController,
|
|
365
|
-
analyticsController
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
// Backfill order values for all entities
|
|
369
|
-
const handleBackfill = useCallback(async () => {
|
|
370
|
-
if (!orderProperty) {
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
analyticsController.onAnalyticsEvent?.("kanban_backfill_order", {
|
|
374
|
-
path: fullPath
|
|
375
|
-
});
|
|
376
|
-
setBackfillLoading(true);
|
|
377
|
-
|
|
378
|
-
try {
|
|
379
|
-
// Fetch the documents to key (not relying on loaded entities). No
|
|
380
|
-
// `orderBy`: with no usable order key there is nothing to order by,
|
|
381
|
-
// and this is the same query the columns themselves run, so the
|
|
382
|
-
// keys are handed out in the order the board is showing — which is
|
|
383
|
-
// what the dialog promises.
|
|
384
|
-
//
|
|
385
|
-
// `MAX_LIST_LIMIT`, not a made-up 10 000: that is the most a single
|
|
386
|
-
// read serves, and asking for more is now refused outright rather
|
|
387
|
-
// than quietly answered with the first thousand. A board past the
|
|
388
|
-
// ceiling still gets only its first page backfilled — the same rows
|
|
389
|
-
// as before this became explicit — and wants a paged walk.
|
|
390
|
-
const allDocsRes = await dataClient.collection(fullPath).find({
|
|
391
|
-
limit: MAX_LIST_LIMIT
|
|
392
|
-
});
|
|
393
|
-
const allDocs = allDocsRes.data as Entity<M>[];
|
|
394
|
-
|
|
395
|
-
// Entities without a usable order key. Testing only for null here
|
|
396
|
-
// meant a column full of unusable values — `"12"`, `"6"` — offered
|
|
397
|
-
// an Initialize button that updated nothing and never went away.
|
|
398
|
-
const entitiesToUpdate = allDocs.filter((entity: Entity<M>) =>
|
|
399
|
-
!isValidOrderKey(entity.values?.[orderProperty]));
|
|
400
|
-
|
|
401
|
-
// Generate string fractional keys for all entities that need them
|
|
402
|
-
const keys = generateNKeysBetween(null, null, entitiesToUpdate.length, ORDER_KEY_DIGITS);
|
|
403
|
-
const updates: Promise<void>[] = [];
|
|
404
|
-
entitiesToUpdate.forEach((entity: Entity<M>, index: number) => {
|
|
405
|
-
const updatedValues = setIn({ ...entity.values }, orderProperty, keys[index]);
|
|
406
|
-
|
|
407
|
-
const saveProps: SaveEntityWithCallbacksProps<Record<string, unknown>> = {
|
|
408
|
-
path: entity.path,
|
|
409
|
-
entityId: entity.id,
|
|
410
|
-
values: updatedValues as M,
|
|
411
|
-
previousValues: entity.values,
|
|
412
|
-
collection,
|
|
413
|
-
status: "existing"
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
updates.push(
|
|
417
|
-
saveEntityWithCallbacks({
|
|
418
|
-
...saveProps,
|
|
419
|
-
collection,
|
|
420
|
-
data: dataClient,
|
|
421
|
-
context,
|
|
422
|
-
afterSave: () => {},
|
|
423
|
-
afterSaveError: (e) => console.error("Backfill save failed:", e)
|
|
424
|
-
}).then(() => {})
|
|
425
|
-
);
|
|
426
|
-
});
|
|
427
|
-
|
|
428
|
-
await Promise.all(updates);
|
|
429
|
-
setShowBackfillDialog(false);
|
|
430
|
-
|
|
431
|
-
// Reset missing count to hide banner
|
|
432
|
-
setMissingOrderCount(0);
|
|
433
|
-
|
|
434
|
-
// Refresh the board data
|
|
435
|
-
boardDataController.refreshAll();
|
|
436
|
-
} catch (e) {
|
|
437
|
-
console.error("Backfill error:", e);
|
|
438
|
-
} finally {
|
|
439
|
-
setBackfillLoading(false);
|
|
440
|
-
}
|
|
441
|
-
}, [orderProperty, fullPath, collection, dataClient, context, boardDataController, analyticsController]);
|
|
442
|
-
|
|
443
|
-
const handleEntityClick = useCallback((entity: Entity<M>) => {
|
|
444
|
-
onEntityClick?.(entity);
|
|
445
|
-
}, [onEntityClick]);
|
|
446
|
-
|
|
447
|
-
const handleSelectionChange = useCallback((entity: Entity<M>, selected: boolean) => {
|
|
448
|
-
selectionController?.toggleEntitySelection(entity, selected);
|
|
449
|
-
}, [selectionController]);
|
|
450
|
-
|
|
451
|
-
const isEntitySelected = useCallback((entity: Entity<M>) => {
|
|
452
|
-
return selectionController?.isEntitySelected(entity) ?? false;
|
|
453
|
-
}, [selectionController]);
|
|
454
|
-
|
|
455
|
-
// Store latest callbacks in refs so the stable ItemComponent always
|
|
456
|
-
// reads fresh values without changing its own identity.
|
|
457
|
-
const handleEntityClickRef = useRef(handleEntityClick);
|
|
458
|
-
handleEntityClickRef.current = handleEntityClick;
|
|
459
|
-
const isEntitySelectedRef = useRef(isEntitySelected);
|
|
460
|
-
isEntitySelectedRef.current = isEntitySelected;
|
|
461
|
-
const handleSelectionChangeRef = useRef(handleSelectionChange);
|
|
462
|
-
handleSelectionChangeRef.current = handleSelectionChange;
|
|
463
|
-
const selectionEnabledRef = useRef(selectionEnabled);
|
|
464
|
-
selectionEnabledRef.current = selectionEnabled;
|
|
465
|
-
|
|
466
|
-
// Stable callback wrappers — identity never changes, delegates to refs.
|
|
467
|
-
const stableOnClick = useCallback((entity: Entity<M>) => {
|
|
468
|
-
handleEntityClickRef.current(entity);
|
|
469
|
-
}, []);
|
|
470
|
-
const stableOnSelectionChange = useCallback((entity: Entity<M>, sel: boolean) => {
|
|
471
|
-
handleSelectionChangeRef.current(entity, sel);
|
|
472
|
-
}, []);
|
|
473
|
-
|
|
474
|
-
// Build a single, truly stable component reference.
|
|
475
|
-
// Uses refs for ALL dynamic values so the component type never changes.
|
|
476
|
-
// When ItemComponent identity changes, React.memo'd SortableItem remounts
|
|
477
|
-
// the card → DOM is destroyed/recreated → CSS :hover state is lost → flicker.
|
|
478
|
-
const ItemComponent = useMemo(() => {
|
|
479
|
-
const Comp = (props: BoardItemViewProps<Entity<M>>) => (
|
|
480
|
-
<BoardCardBinding
|
|
481
|
-
{...props}
|
|
482
|
-
collection={collectionRef.current as AdminCollection<M>}
|
|
483
|
-
onClick={stableOnClick}
|
|
484
|
-
selected={isEntitySelectedRef.current(props.item.data)}
|
|
485
|
-
onSelectionChange={stableOnSelectionChange}
|
|
486
|
-
selectionEnabled={selectionEnabledRef.current}
|
|
487
|
-
/>
|
|
488
|
-
);
|
|
489
|
-
Comp.displayName = "KanbanItemComponent";
|
|
490
|
-
return Comp;
|
|
491
|
-
}, []);
|
|
492
|
-
|
|
493
|
-
// Get KanbanSetupComponent from plugin slots
|
|
494
|
-
const kanbanSetupSlots = useSlot("kanban.setup", {
|
|
495
|
-
collection,
|
|
496
|
-
fullPath,
|
|
497
|
-
parentCollectionSlugs,
|
|
498
|
-
parentEntityIds
|
|
499
|
-
});
|
|
500
|
-
|
|
501
|
-
// Get AddKanbanColumnComponent from plugin slots
|
|
502
|
-
const addKanbanColumnSlots = useSlot("kanban.add-column", {
|
|
503
|
-
collection,
|
|
504
|
-
fullPath,
|
|
505
|
-
parentCollectionSlugs,
|
|
506
|
-
parentEntityIds,
|
|
507
|
-
columnProperty
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
// Check for loading error
|
|
511
|
-
const hasError = Boolean(dataLoadingError);
|
|
512
|
-
const errorMessage = dataLoadingError?.message || "";
|
|
513
|
-
const indexUrl = errorMessage.match(/https:\/\/console\.firebase\.google\.com[^\s]+/)?.[0];
|
|
514
|
-
|
|
515
|
-
// Error: no enum properties available for Kanban columns
|
|
516
|
-
if (!columnProperty || enumColumns.length === 0) {
|
|
517
|
-
return (
|
|
518
|
-
<div className="h-full flex flex-col items-center justify-center p-8 gap-4">
|
|
519
|
-
<Typography variant="h6">
|
|
520
|
-
{t("kanban_view_not_available")}
|
|
521
|
-
</Typography>
|
|
522
|
-
<Typography variant="body2" color="secondary" className="text-center max-w-md">
|
|
523
|
-
{t("kanban_view_requires_enum")}
|
|
524
|
-
</Typography>
|
|
525
|
-
{kanbanSetupSlots.length > 0 && kanbanSetupSlots[0]}
|
|
526
|
-
</div>
|
|
527
|
-
);
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
// Note: Empty state is not shown for Kanban view - we show the board with empty columns instead
|
|
531
|
-
// The emptyComponent is handled per-column in BoardColumn
|
|
532
|
-
|
|
533
|
-
// No columns
|
|
534
|
-
if (columns.length === 0) {
|
|
535
|
-
return (
|
|
536
|
-
<div className="h-full flex items-center justify-center p-8">
|
|
537
|
-
<Typography variant="label" color="secondary">
|
|
538
|
-
{t("no_enum_values_configured", { property: columnProperty })}
|
|
539
|
-
</Typography>
|
|
540
|
-
</div>
|
|
541
|
-
);
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
return (
|
|
545
|
-
<div className="flex-1 flex flex-col overflow-hidden">
|
|
546
|
-
{/* Error banner - only show when no data loaded */}
|
|
547
|
-
{hasError && allEntities.length === 0 && (
|
|
548
|
-
<div
|
|
549
|
-
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">
|
|
550
|
-
<Typography variant="body2" className="text-red-700 dark:text-red-300 flex-1">
|
|
551
|
-
<strong>Error:</strong>{" "}
|
|
552
|
-
{indexUrl
|
|
553
|
-
? "A Firestore index is required for this query."
|
|
554
|
-
: errorMessage}
|
|
555
|
-
</Typography>
|
|
556
|
-
<Tooltip title={t("refresh_data")}>
|
|
557
|
-
<IconButton
|
|
558
|
-
size="small"
|
|
559
|
-
onClick={() => boardDataController.refreshAll()}
|
|
560
|
-
>
|
|
561
|
-
<RefreshCwIcon size={iconSize.smallest}/>
|
|
562
|
-
</IconButton>
|
|
563
|
-
</Tooltip>
|
|
564
|
-
{indexUrl && (
|
|
565
|
-
<Button
|
|
566
|
-
size="small"
|
|
567
|
-
variant="filled"
|
|
568
|
-
color="error"
|
|
569
|
-
onClick={() => window.open(indexUrl, "_blank")}
|
|
570
|
-
>
|
|
571
|
-
{t("create_index")}
|
|
572
|
-
</Button>
|
|
573
|
-
)}
|
|
574
|
-
</div>
|
|
575
|
-
)}
|
|
576
|
-
|
|
577
|
-
{/* Warning: orderProperty not configured - drag reorder won't persist */}
|
|
578
|
-
{!orderProperty && !dataLoading && (
|
|
579
|
-
<div
|
|
580
|
-
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">
|
|
581
|
-
<Typography variant="body2" color="secondary">
|
|
582
|
-
{t("kanban_order_not_configured")}
|
|
583
|
-
</Typography>
|
|
584
|
-
{kanbanSetupSlots.length > 0 && kanbanSetupSlots[0]}
|
|
585
|
-
</div>
|
|
586
|
-
)}
|
|
587
|
-
|
|
588
|
-
{/* Backfill info bar - non-blocking */}
|
|
589
|
-
{itemsNeedBackfill && !dataLoading && (
|
|
590
|
-
<div
|
|
591
|
-
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">
|
|
592
|
-
<Typography variant="body2" color="secondary">
|
|
593
|
-
{t("items_need_backfill")}
|
|
594
|
-
</Typography>
|
|
595
|
-
<Button
|
|
596
|
-
size="small"
|
|
597
|
-
variant="text"
|
|
598
|
-
onClick={() => setShowBackfillDialog(true)}
|
|
599
|
-
>
|
|
600
|
-
{t("initialize")}
|
|
601
|
-
</Button>
|
|
602
|
-
</div>
|
|
603
|
-
)}
|
|
604
|
-
|
|
605
|
-
{/* Main board. It scrolls its own columns vertically and its own
|
|
606
|
-
row horizontally, so an `overflow-auto` here only added a second
|
|
607
|
-
scroll container around both. */}
|
|
608
|
-
<div className="flex-1 min-h-0 overflow-hidden">
|
|
609
|
-
<KanbanView
|
|
610
|
-
data={boardItems}
|
|
611
|
-
columns={columns}
|
|
612
|
-
columnLabels={columnLabels}
|
|
613
|
-
columnColors={columnColors}
|
|
614
|
-
assignColumn={assignColumn}
|
|
615
|
-
allowColumnReorder={allowColumnReorder}
|
|
616
|
-
onColumnReorder={handleColumnReorder}
|
|
617
|
-
onItemsReorder={handleItemsReorder}
|
|
618
|
-
ItemComponent={ItemComponent}
|
|
619
|
-
columnLoadingState={columnLoadingState}
|
|
620
|
-
onLoadMoreColumn={(column) => boardDataController.loadMoreColumn(column)}
|
|
621
|
-
onAddItemToColumn={(column) => {
|
|
622
|
-
analyticsController.onAnalyticsEvent?.("kanban_new_entity_in_column", {
|
|
623
|
-
path: fullPath,
|
|
624
|
-
column
|
|
625
|
-
});
|
|
626
|
-
sidePanelController.open({
|
|
627
|
-
path: fullPath,
|
|
628
|
-
collection,
|
|
629
|
-
entityId: undefined,
|
|
630
|
-
updateUrl: true,
|
|
631
|
-
formProps: {
|
|
632
|
-
initialDirtyValues: {
|
|
633
|
-
[columnProperty]: column
|
|
634
|
-
} as Partial<M>
|
|
635
|
-
}
|
|
636
|
-
});
|
|
637
|
-
}}
|
|
638
|
-
AddColumnComponent={addKanbanColumnSlots.length > 0 ? addKanbanColumnSlots[0] : undefined}
|
|
639
|
-
/>
|
|
640
|
-
</div>
|
|
641
|
-
|
|
642
|
-
{/* Backfill dialog */}
|
|
643
|
-
<Dialog open={showBackfillDialog} onOpenChange={setShowBackfillDialog}>
|
|
644
|
-
<DialogTitle hidden>{t("initialize_kanban_order")}</DialogTitle>
|
|
645
|
-
<DialogContent>
|
|
646
|
-
<Typography variant="h6" className="mb-4">{t("initialize_kanban_order")}</Typography>
|
|
647
|
-
<Typography variant="body2">
|
|
648
|
-
{t("initialize_kanban_order_desc")}
|
|
649
|
-
</Typography>
|
|
650
|
-
</DialogContent>
|
|
651
|
-
<DialogActions>
|
|
652
|
-
<Button variant="text" onClick={() => setShowBackfillDialog(false)} disabled={backfillLoading}>
|
|
653
|
-
{t("cancel")}
|
|
654
|
-
</Button>
|
|
655
|
-
<Button onClick={handleBackfill} disabled={backfillLoading}>
|
|
656
|
-
{backfillLoading ? <CircularProgress size="smallest"/> : t("initialize")}
|
|
657
|
-
</Button>
|
|
658
|
-
</DialogActions>
|
|
659
|
-
</Dialog>
|
|
660
|
-
</div>
|
|
661
|
-
);
|
|
662
|
-
}
|