@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,298 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useMemo } from "react";
|
|
2
|
-
import { CheckIcon, ChevronsUpDownIcon, cls, FilterChip, Menu, MenuItem, Tooltip } from "@rebasepro/ui";
|
|
3
|
-
import type { FilterValues, FilterPreset, OrderByTuple } from "@rebasepro/types";
|
|
4
|
-
import { normalizeOrderBy } from "@rebasepro/common";
|
|
5
|
-
import type { EntityTableController, PropertyPath } from "@rebasepro/cms-types";
|
|
6
|
-
|
|
7
|
-
export interface FilterPresetsButtonProps<M extends Record<string, unknown>> {
|
|
8
|
-
// Matches `admin.filterPresets`, which is keyed by property path — the
|
|
9
|
-
// component is fed straight from the collection.
|
|
10
|
-
filterPresets: FilterPreset<PropertyPath<M>>[];
|
|
11
|
-
tableController: EntityTableController<M>;
|
|
12
|
-
compact?: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Maximum number of presets shown as inline toggle chips before the
|
|
17
|
-
* rest are collapsed into an overflow menu.
|
|
18
|
-
*/
|
|
19
|
-
const MAX_VISIBLE_PRESETS = 4;
|
|
20
|
-
|
|
21
|
-
/** Max characters for a chip label before truncation. */
|
|
22
|
-
const MAX_LABEL_LENGTH = 22;
|
|
23
|
-
|
|
24
|
-
// ─── Helpers ────────────────────────────────────────────────────────
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Deep equality without JSON.stringify.
|
|
28
|
-
* Handles primitives, arrays, Dates, and plain objects recursively.
|
|
29
|
-
*/
|
|
30
|
-
function deepEqual(a: unknown, b: unknown): boolean {
|
|
31
|
-
if (a === b) return true;
|
|
32
|
-
if (a == null || b == null) return false;
|
|
33
|
-
if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
|
|
34
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
35
|
-
if (a.length !== b.length) return false;
|
|
36
|
-
return a.every((v, i) => deepEqual(v, b[i]));
|
|
37
|
-
}
|
|
38
|
-
if (typeof a === "object" && typeof b === "object") {
|
|
39
|
-
const aKeys = Object.keys(a as Record<string, unknown>);
|
|
40
|
-
const bKeys = Object.keys(b as Record<string, unknown>);
|
|
41
|
-
if (aKeys.length !== bKeys.length) return false;
|
|
42
|
-
return aKeys.every(k =>
|
|
43
|
-
deepEqual(
|
|
44
|
-
(a as Record<string, unknown>)[k],
|
|
45
|
-
(b as Record<string, unknown>)[k]
|
|
46
|
-
)
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Check if a preset's filters are a subset of the controller's
|
|
54
|
-
* current filter values (key-by-key deep comparison on the tuples).
|
|
55
|
-
*/
|
|
56
|
-
function isPresetActive(
|
|
57
|
-
preset: FilterPreset<string>,
|
|
58
|
-
controllerFilters: Record<string, unknown> | undefined
|
|
59
|
-
): boolean {
|
|
60
|
-
if (!controllerFilters) return false;
|
|
61
|
-
const entries = Object.entries(preset.filterValues);
|
|
62
|
-
if (entries.length === 0) return false;
|
|
63
|
-
for (const [key, presetTuple] of entries) {
|
|
64
|
-
const controllerTuple = controllerFilters[key];
|
|
65
|
-
if (!controllerTuple || !presetTuple) return false;
|
|
66
|
-
if (!deepEqual(presetTuple, controllerTuple)) return false;
|
|
67
|
-
}
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Generate a human-readable label from filter keys when no explicit label is provided.
|
|
73
|
-
*/
|
|
74
|
-
function generateLabel(filterValues: FilterValues<string>): string {
|
|
75
|
-
const keys = Object.keys(filterValues);
|
|
76
|
-
if (keys.length === 0) return "Filter";
|
|
77
|
-
if (keys.length === 1) return keys[0].replace(/_/g, " ");
|
|
78
|
-
if (keys.length === 2) return keys.map(k => k.replace(/_/g, " ")).join(" + ");
|
|
79
|
-
return `${keys[0].replace(/_/g, " ")} +${keys.length - 1}`;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Truncate a label if it exceeds MAX_LABEL_LENGTH.
|
|
84
|
-
*/
|
|
85
|
-
function truncateLabel(label: string): { display: string; truncated: boolean } {
|
|
86
|
-
if (label.length <= MAX_LABEL_LENGTH) return { display: label,
|
|
87
|
-
truncated: false };
|
|
88
|
-
return { display: label.slice(0, MAX_LABEL_LENGTH - 1) + "…",
|
|
89
|
-
truncated: true };
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// ─── Overflow Menu ──────────────────────────────────────────────────
|
|
93
|
-
|
|
94
|
-
interface OverflowMenuProps {
|
|
95
|
-
presets: { preset: FilterPreset<string>; originalIndex: number }[];
|
|
96
|
-
activeSet: Set<number>;
|
|
97
|
-
onToggle: (index: number) => void;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function OverflowMenu({ presets, activeSet, onToggle }: OverflowMenuProps) {
|
|
101
|
-
const activeCount = presets.filter(p => activeSet.has(p.originalIndex)).length;
|
|
102
|
-
|
|
103
|
-
const trigger = (
|
|
104
|
-
<FilterChip
|
|
105
|
-
active={activeCount > 0}
|
|
106
|
-
icon={<ChevronsUpDownIcon size={12} />}
|
|
107
|
-
>
|
|
108
|
-
+{presets.length}
|
|
109
|
-
</FilterChip>
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
return (
|
|
113
|
-
<Menu trigger={trigger} side="bottom" align="start">
|
|
114
|
-
<div className="min-w-[180px] max-w-[300px] max-h-[320px] overflow-y-auto">
|
|
115
|
-
{presets.map(({ preset, originalIndex }) => {
|
|
116
|
-
const rawLabel = preset.label ?? generateLabel(preset.filterValues as FilterValues<string>);
|
|
117
|
-
const active = activeSet.has(originalIndex);
|
|
118
|
-
|
|
119
|
-
return (
|
|
120
|
-
<MenuItem
|
|
121
|
-
key={originalIndex}
|
|
122
|
-
dense
|
|
123
|
-
onClick={() => onToggle(originalIndex)}
|
|
124
|
-
className={cls(active && "bg-primary/10 dark:bg-primary/20")}
|
|
125
|
-
>
|
|
126
|
-
<span className="flex items-center gap-2 w-full min-w-0">
|
|
127
|
-
{active && <CheckIcon size={14} className="text-primary shrink-0" />}
|
|
128
|
-
<span className={cls("truncate", active ? "text-primary font-medium" : "")}>
|
|
129
|
-
{rawLabel}
|
|
130
|
-
</span>
|
|
131
|
-
</span>
|
|
132
|
-
</MenuItem>
|
|
133
|
-
);
|
|
134
|
-
})}
|
|
135
|
-
</div>
|
|
136
|
-
</Menu>
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// ─── Main Component ─────────────────────────────────────────────────
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Filter Presets — displayed as inline toggle chips in the collection toolbar.
|
|
144
|
-
*
|
|
145
|
-
* Active state is **derived** from the controller's actual filter values,
|
|
146
|
-
* not tracked locally. A chip is "active" when ALL of its filter entries
|
|
147
|
-
* match the current controller state (deep value comparison, no JSON.stringify).
|
|
148
|
-
*
|
|
149
|
-
* This means:
|
|
150
|
-
* - Toggling a preset on adds its filters to the controller.
|
|
151
|
-
* - Toggling it off removes its filter keys.
|
|
152
|
-
* - Changing filters via the dialog automatically deactivates unmatched chips.
|
|
153
|
-
* - Clearing all filters deactivates all chips.
|
|
154
|
-
* - Multiple presets can be active simultaneously.
|
|
155
|
-
*/
|
|
156
|
-
export function FilterPresetsButton<M extends Record<string, unknown>>({
|
|
157
|
-
filterPresets,
|
|
158
|
-
tableController,
|
|
159
|
-
compact
|
|
160
|
-
}: FilterPresetsButtonProps<M>) {
|
|
161
|
-
|
|
162
|
-
// ── Derive active state from controller ─────────────────────────
|
|
163
|
-
const activeSet = useMemo(() => {
|
|
164
|
-
const set = new Set<number>();
|
|
165
|
-
if (!filterPresets.length || !tableController.setFilterValues) return set;
|
|
166
|
-
for (let i = 0; i < filterPresets.length; i++) {
|
|
167
|
-
if (isPresetActive(
|
|
168
|
-
filterPresets[i] as FilterPreset<string>,
|
|
169
|
-
tableController.filterValues as Record<string, unknown> | undefined
|
|
170
|
-
)) {
|
|
171
|
-
set.add(i);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return set;
|
|
175
|
-
}, [filterPresets, tableController.filterValues, tableController.setFilterValues]);
|
|
176
|
-
|
|
177
|
-
// ── Toggle handler ──────────────────────────────────────────────
|
|
178
|
-
const handleToggle = useCallback((index: number) => {
|
|
179
|
-
const preset = filterPresets[index] as FilterPreset<string>;
|
|
180
|
-
const currentFilters = { ...(tableController.filterValues ?? {}) } as Record<string, [string, unknown]>;
|
|
181
|
-
const wasActive = isPresetActive(preset, currentFilters);
|
|
182
|
-
|
|
183
|
-
if (wasActive) {
|
|
184
|
-
// Toggle OFF: remove this preset's filter keys
|
|
185
|
-
for (const key of Object.keys(preset.filterValues)) {
|
|
186
|
-
delete currentFilters[key];
|
|
187
|
-
}
|
|
188
|
-
// Re-apply overlapping keys from other still-active presets
|
|
189
|
-
for (let i = 0; i < filterPresets.length; i++) {
|
|
190
|
-
if (i === index) continue;
|
|
191
|
-
const other = filterPresets[i] as FilterPreset<string>;
|
|
192
|
-
if (isPresetActive(other, currentFilters)) {
|
|
193
|
-
Object.assign(currentFilters, other.filterValues);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
} else {
|
|
197
|
-
// Toggle ON: merge this preset's filters on top
|
|
198
|
-
Object.assign(currentFilters, preset.filterValues);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Apply
|
|
202
|
-
if (Object.keys(currentFilters).length === 0) {
|
|
203
|
-
if (tableController.clearFilter) {
|
|
204
|
-
tableController.clearFilter();
|
|
205
|
-
} else {
|
|
206
|
-
tableController.setFilterValues?.(
|
|
207
|
-
{} as FilterValues<Extract<keyof M, string> | (string & {})>
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
tableController.setSortBy?.(undefined);
|
|
211
|
-
} else {
|
|
212
|
-
tableController.setFilterValues?.(
|
|
213
|
-
currentFilters as FilterValues<Extract<keyof M, string> | (string & {})>
|
|
214
|
-
);
|
|
215
|
-
|
|
216
|
-
// Resolve sort: use the toggled preset's sort if toggling on,
|
|
217
|
-
// otherwise find sort from remaining active presets
|
|
218
|
-
if (!wasActive && preset.sort) {
|
|
219
|
-
tableController.setSortBy?.(
|
|
220
|
-
normalizeOrderBy(preset.sort) as OrderByTuple<Extract<keyof M, string> | (string & {})>[]
|
|
221
|
-
);
|
|
222
|
-
} else if (wasActive) {
|
|
223
|
-
let remainingSort: OrderByTuple[] | undefined;
|
|
224
|
-
for (let i = 0; i < filterPresets.length; i++) {
|
|
225
|
-
if (i === index) continue;
|
|
226
|
-
const other = filterPresets[i] as FilterPreset<string>;
|
|
227
|
-
if (isPresetActive(other, currentFilters) && other.sort) {
|
|
228
|
-
remainingSort = normalizeOrderBy(other.sort);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
tableController.setSortBy?.(
|
|
232
|
-
remainingSort as OrderByTuple<Extract<keyof M, string> | (string & {})>[] | undefined
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}, [filterPresets, tableController]);
|
|
237
|
-
|
|
238
|
-
// ── Guard (after hooks to preserve Rules of Hooks) ──────────────
|
|
239
|
-
if (!filterPresets.length || !tableController.setFilterValues) return null;
|
|
240
|
-
|
|
241
|
-
// ── Split visible vs overflow ───────────────────────────────────
|
|
242
|
-
const maxVisible = compact ? 2 : MAX_VISIBLE_PRESETS;
|
|
243
|
-
const needsOverflow = filterPresets.length > maxVisible;
|
|
244
|
-
const visibleCount = needsOverflow ? maxVisible - 1 : filterPresets.length;
|
|
245
|
-
|
|
246
|
-
const visiblePresets = filterPresets.slice(0, visibleCount);
|
|
247
|
-
const overflowPresets = needsOverflow
|
|
248
|
-
? filterPresets.slice(visibleCount).map((preset, i) => ({
|
|
249
|
-
preset: preset as FilterPreset<string>,
|
|
250
|
-
originalIndex: visibleCount + i
|
|
251
|
-
}))
|
|
252
|
-
: [];
|
|
253
|
-
|
|
254
|
-
const hasOverflow = overflowPresets.length > 0;
|
|
255
|
-
|
|
256
|
-
return (
|
|
257
|
-
<div className="flex items-center gap-1 min-w-0 overflow-hidden">
|
|
258
|
-
{/* Scrollable chip area — on narrow screens chips scroll,
|
|
259
|
-
on desktop there's enough space so no scroll occurs.
|
|
260
|
-
py-0.5 gives the inset shadow breathing room inside the clip area. */}
|
|
261
|
-
<div
|
|
262
|
-
className="flex items-center gap-1 min-w-0 overflow-x-auto py-0.5"
|
|
263
|
-
style={{ scrollbarWidth: "none" }}
|
|
264
|
-
>
|
|
265
|
-
{visiblePresets.map((preset, index) => {
|
|
266
|
-
const rawLabel = preset.label ?? generateLabel(preset.filterValues as FilterValues<string>);
|
|
267
|
-
const { display, truncated } = truncateLabel(rawLabel);
|
|
268
|
-
const active = activeSet.has(index);
|
|
269
|
-
|
|
270
|
-
const chip = (
|
|
271
|
-
<FilterChip
|
|
272
|
-
key={index}
|
|
273
|
-
active={active}
|
|
274
|
-
onClick={() => handleToggle(index)}
|
|
275
|
-
size="small"
|
|
276
|
-
>
|
|
277
|
-
{display}
|
|
278
|
-
</FilterChip>
|
|
279
|
-
);
|
|
280
|
-
|
|
281
|
-
if (truncated) {
|
|
282
|
-
return <Tooltip key={index} title={rawLabel}>{chip}</Tooltip>;
|
|
283
|
-
}
|
|
284
|
-
return chip;
|
|
285
|
-
})}
|
|
286
|
-
</div>
|
|
287
|
-
|
|
288
|
-
{/* Overflow button — always pinned outside the scroll area */}
|
|
289
|
-
{hasOverflow && (
|
|
290
|
-
<OverflowMenu
|
|
291
|
-
presets={overflowPresets}
|
|
292
|
-
activeSet={activeSet}
|
|
293
|
-
onToggle={handleToggle}
|
|
294
|
-
/>
|
|
295
|
-
)}
|
|
296
|
-
</div>
|
|
297
|
-
);
|
|
298
|
-
}
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import type { Property } from "@rebasepro/types";
|
|
3
|
-
import React, { useCallback, useMemo, useState } from "react";
|
|
4
|
-
import { FilterValues, WhereFilterOp } from "@rebasepro/types";
|
|
5
|
-
import { Button, cls, defaultBorderMixin, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@rebasepro/ui";
|
|
6
|
-
import { FilterIcon, VirtualTableWhereFilterOp } from "@rebasepro/ui";
|
|
7
|
-
import { resolveFilterOperators } from "@rebasepro/app";
|
|
8
|
-
import { useCollectionScope, useTranslation } from "@rebasepro/app";
|
|
9
|
-
import { FilterFieldBinding } from "../SelectableTable/filters/FilterFieldBinding";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* `WhereFilterOp` is declared twice: once in `@rebasepro/types` as the canonical
|
|
13
|
-
* operator set every driver translates, and once in `@rebasepro/ui` for the
|
|
14
|
-
* table's own props. That is deliberate — `ui` is a standalone design system and
|
|
15
|
-
* depends on no Rebase package, so it cannot import the canonical one (and a
|
|
16
|
-
* type-only import would not help: `ui` emits declarations with `tsc`, which
|
|
17
|
-
* references external types rather than inlining them, so its published `.d.ts`
|
|
18
|
-
* would demand `@rebasepro/types` from every consumer).
|
|
19
|
-
*
|
|
20
|
-
* This file is where the two meet and get cast into each other, so it is where
|
|
21
|
-
* their agreement is checked. Adding an operator to one and not the other stops
|
|
22
|
-
* this line compiling instead of silently producing a filter the table can build
|
|
23
|
-
* and no driver can run — or one a driver supports and the table cannot offer.
|
|
24
|
-
*/
|
|
25
|
-
type MutuallyAssignable<A, B> = [A] extends [B] ? ([B] extends [A] ? true : never) : never;
|
|
26
|
-
const _whereFilterOpDefinitionsAgree: MutuallyAssignable<WhereFilterOp, VirtualTableWhereFilterOp> = true;
|
|
27
|
-
void _whereFilterOpDefinitionsAgree;
|
|
28
|
-
|
|
29
|
-
export interface FiltersDialogProps {
|
|
30
|
-
open: boolean;
|
|
31
|
-
onOpenChange: (open: boolean) => void;
|
|
32
|
-
properties: Record<string, Property>;
|
|
33
|
-
filterValues: FilterValues<any> | undefined;
|
|
34
|
-
setFilterValues: (filterValues?: FilterValues<any>) => void;
|
|
35
|
-
fixedFilter?: FilterValues<any>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Dialog that displays all filterable properties from a collection
|
|
40
|
-
* and allows setting filter values for each.
|
|
41
|
-
*/
|
|
42
|
-
export function FiltersDialog({
|
|
43
|
-
open,
|
|
44
|
-
onOpenChange,
|
|
45
|
-
properties,
|
|
46
|
-
filterValues,
|
|
47
|
-
setFilterValues,
|
|
48
|
-
fixedFilter
|
|
49
|
-
}: FiltersDialogProps) {
|
|
50
|
-
const { t } = useTranslation();
|
|
51
|
-
// Engine of the collection this dialog filters — read from the
|
|
52
|
-
// surrounding CollectionScopeProvider mounted by the collection view.
|
|
53
|
-
const engine = useCollectionScope()?.engine;
|
|
54
|
-
// Local state for filters being edited
|
|
55
|
-
const [localFilters, setLocalFilters] = useState<FilterValues<any>>(filterValues ?? {});
|
|
56
|
-
|
|
57
|
-
// Track hidden state for reference fields (when reference dialog is open)
|
|
58
|
-
const [hiddenFields, setHiddenFields] = useState<Record<string, boolean>>({});
|
|
59
|
-
|
|
60
|
-
// Reset local state when dialog opens
|
|
61
|
-
React.useEffect(() => {
|
|
62
|
-
if (open) {
|
|
63
|
-
setLocalFilters(filterValues ?? {});
|
|
64
|
-
}
|
|
65
|
-
}, [open, filterValues]);
|
|
66
|
-
|
|
67
|
-
// Get list of filterable properties
|
|
68
|
-
const filterableProperties = useMemo(() => {
|
|
69
|
-
return Object.entries(properties).filter(([key, property]) => {
|
|
70
|
-
if (!property) return false;
|
|
71
|
-
// Force filter properties should not be editable
|
|
72
|
-
if (fixedFilter && key in fixedFilter) return false;
|
|
73
|
-
const isArray = property.type === "array";
|
|
74
|
-
const ofProp = isArray && "of" in property ? property.of : undefined;
|
|
75
|
-
const baseProperty = isArray ? (Array.isArray(ofProp) ? ofProp[0] : ofProp) as Property | undefined : property;
|
|
76
|
-
if (!baseProperty) return false;
|
|
77
|
-
// A property is filterable when it has a custom filter field, or
|
|
78
|
-
// when at least one operator survives the engine ∩ type ∩
|
|
79
|
-
// property-narrowing resolution.
|
|
80
|
-
if (baseProperty.admin?.Filter) return true;
|
|
81
|
-
return resolveFilterOperators({ property: baseProperty, isArray, engine }).length > 0;
|
|
82
|
-
});
|
|
83
|
-
}, [properties, fixedFilter, engine]);
|
|
84
|
-
|
|
85
|
-
const handleFilterChange = useCallback((propertyKey: string, value?: [VirtualTableWhereFilterOp, any]) => {
|
|
86
|
-
setLocalFilters(prev => {
|
|
87
|
-
const newFilters = { ...prev };
|
|
88
|
-
if (value) {
|
|
89
|
-
newFilters[propertyKey] = value as [WhereFilterOp, any];
|
|
90
|
-
} else {
|
|
91
|
-
delete newFilters[propertyKey];
|
|
92
|
-
}
|
|
93
|
-
return newFilters;
|
|
94
|
-
});
|
|
95
|
-
}, []);
|
|
96
|
-
|
|
97
|
-
const handleApply = useCallback(() => {
|
|
98
|
-
const hasFilters = Object.keys(localFilters).length > 0;
|
|
99
|
-
setFilterValues(hasFilters ? { ...localFilters,
|
|
100
|
-
...fixedFilter } : (fixedFilter || undefined));
|
|
101
|
-
onOpenChange(false);
|
|
102
|
-
}, [localFilters, setFilterValues, fixedFilter, onOpenChange]);
|
|
103
|
-
|
|
104
|
-
const handleClearAll = useCallback(() => {
|
|
105
|
-
setLocalFilters({});
|
|
106
|
-
}, []);
|
|
107
|
-
|
|
108
|
-
const setHiddenForField = useCallback((propertyKey: string, hidden: boolean) => {
|
|
109
|
-
setHiddenFields(prev => ({
|
|
110
|
-
...prev,
|
|
111
|
-
[propertyKey]: hidden
|
|
112
|
-
}));
|
|
113
|
-
}, []);
|
|
114
|
-
|
|
115
|
-
// Check if any reference field's dialog is currently open (should hide this dialog)
|
|
116
|
-
const isAnyFieldHidden = Object.values(hiddenFields).some(hidden => hidden);
|
|
117
|
-
const activeFilterCount = Object.keys(localFilters).length;
|
|
118
|
-
|
|
119
|
-
const renderFilterField = useCallback((propertyKey: string, property: Property) => {
|
|
120
|
-
const filterValue = localFilters[propertyKey] as [WhereFilterOp, any] | undefined;
|
|
121
|
-
const setValue = (value?: [WhereFilterOp, any]) => handleFilterChange(propertyKey, value as [VirtualTableWhereFilterOp, any] | undefined);
|
|
122
|
-
|
|
123
|
-
return (
|
|
124
|
-
<FilterFieldBinding
|
|
125
|
-
propertyKey={propertyKey}
|
|
126
|
-
property={property}
|
|
127
|
-
engine={engine}
|
|
128
|
-
value={filterValue}
|
|
129
|
-
setValue={setValue}
|
|
130
|
-
hidden={hiddenFields[propertyKey] ?? false}
|
|
131
|
-
setHidden={(hidden) => setHiddenForField(propertyKey, hidden)}
|
|
132
|
-
/>
|
|
133
|
-
);
|
|
134
|
-
}, [localFilters, handleFilterChange, hiddenFields, setHiddenForField, engine]);
|
|
135
|
-
|
|
136
|
-
return (
|
|
137
|
-
<Dialog
|
|
138
|
-
open={open}
|
|
139
|
-
onOpenChange={onOpenChange}
|
|
140
|
-
maxWidth="3xl"
|
|
141
|
-
fullWidth
|
|
142
|
-
containerClassName={isAnyFieldHidden ? "hidden" : undefined}
|
|
143
|
-
>
|
|
144
|
-
<DialogTitle className="flex items-center gap-2" variant="h6">
|
|
145
|
-
{t("filters")}
|
|
146
|
-
{activeFilterCount > 0 && (
|
|
147
|
-
<span className="ml-2 px-2 py-0.5 text-xs rounded-full bg-primary text-white">
|
|
148
|
-
{activeFilterCount}
|
|
149
|
-
</span>
|
|
150
|
-
)}
|
|
151
|
-
</DialogTitle>
|
|
152
|
-
|
|
153
|
-
<DialogContent >
|
|
154
|
-
{filterableProperties.length === 0 ? (
|
|
155
|
-
<Typography color="secondary" className="py-8 text-center">
|
|
156
|
-
{t("no_filterable_properties")}
|
|
157
|
-
</Typography>
|
|
158
|
-
) : (
|
|
159
|
-
<table className="w-full border-collapse">
|
|
160
|
-
<tbody>
|
|
161
|
-
{filterableProperties.map(([propertyKey, property], index) => {
|
|
162
|
-
const hasFilter = propertyKey in localFilters;
|
|
163
|
-
|
|
164
|
-
return (
|
|
165
|
-
<tr key={propertyKey} className={cls(
|
|
166
|
-
index > 0 && "border-t",
|
|
167
|
-
defaultBorderMixin
|
|
168
|
-
)}>
|
|
169
|
-
{/* Property name on the left */}
|
|
170
|
-
<td className="py-3 pr-4 align-middle w-[160px]">
|
|
171
|
-
<Typography
|
|
172
|
-
variant="body2"
|
|
173
|
-
className={cls(
|
|
174
|
-
"font-medium",
|
|
175
|
-
hasFilter && "text-primary"
|
|
176
|
-
)}
|
|
177
|
-
>
|
|
178
|
-
{property.name || propertyKey}
|
|
179
|
-
</Typography>
|
|
180
|
-
</td>
|
|
181
|
-
|
|
182
|
-
{/* FilterIcon field on the right */}
|
|
183
|
-
<td className="py-3">
|
|
184
|
-
{renderFilterField(propertyKey, property)}
|
|
185
|
-
</td>
|
|
186
|
-
</tr>
|
|
187
|
-
);
|
|
188
|
-
})}
|
|
189
|
-
</tbody>
|
|
190
|
-
</table>
|
|
191
|
-
)}
|
|
192
|
-
</DialogContent>
|
|
193
|
-
|
|
194
|
-
<DialogActions>
|
|
195
|
-
<Button
|
|
196
|
-
variant="text"
|
|
197
|
-
onClick={handleClearAll}
|
|
198
|
-
disabled={activeFilterCount === 0}
|
|
199
|
-
>
|
|
200
|
-
{t("clear_all")}
|
|
201
|
-
</Button>
|
|
202
|
-
<div className="flex-grow"/>
|
|
203
|
-
<Button
|
|
204
|
-
variant="text"
|
|
205
|
-
onClick={() => onOpenChange(false)}
|
|
206
|
-
>
|
|
207
|
-
{t("cancel")}
|
|
208
|
-
</Button>
|
|
209
|
-
<Button
|
|
210
|
-
variant="filled"
|
|
211
|
-
onClick={handleApply}
|
|
212
|
-
>
|
|
213
|
-
{t("apply_filters")}
|
|
214
|
-
</Button>
|
|
215
|
-
</DialogActions>
|
|
216
|
-
</Dialog>
|
|
217
|
-
);
|
|
218
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import React, { useMemo } from "react";
|
|
2
|
-
import type { SearchMatch } from "@rebasepro/types";
|
|
3
|
-
import { Snippet, searchTerms, offSlotMatch, localRowMatch } from "./SearchHighlight";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The one place a view asks "why is this row here?" and gets something to draw.
|
|
7
|
-
*
|
|
8
|
-
* List, cards and board all render the same title-and-subtitle slots over the
|
|
9
|
-
* same machinery. An explanation that shows up in one of them and not the others
|
|
10
|
-
* reads as randomness rather than as a feature, so the decision and the markup
|
|
11
|
-
* live here and each view calls them.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Terms to mark inside values the row already shows, plus the single match
|
|
16
|
-
* worth putting where the subtitle would go — or nothing, when the row is not
|
|
17
|
-
* the product of a search or the hit is already visible.
|
|
18
|
-
*
|
|
19
|
-
* Prefers the server's `_matches`, which knows the stemming the index used, and
|
|
20
|
-
* falls back to reading the row directly. That fallback is not belt-and-braces:
|
|
21
|
-
* rows reach the panel over REST, the realtime socket and the offline cache,
|
|
22
|
-
* and only one of those carries query metadata.
|
|
23
|
-
*/
|
|
24
|
-
export function useSearchExplanation(
|
|
25
|
-
entity: { values?: Record<string, unknown>; searchMatches?: SearchMatch[] },
|
|
26
|
-
properties: Record<string, unknown> | undefined,
|
|
27
|
-
shownKeys: (string | undefined)[],
|
|
28
|
-
searchString: string | undefined
|
|
29
|
-
): { terms: string[]; offSlot: SearchMatch | undefined } {
|
|
30
|
-
const terms = useMemo(() => searchTerms(searchString), [searchString]);
|
|
31
|
-
|
|
32
|
-
// Joined so the memo compares by value: the caller builds this array inline,
|
|
33
|
-
// so its identity changes every render and would defeat the memo entirely.
|
|
34
|
-
//
|
|
35
|
-
// `|` is the separator because a property path is identifiers and dots — it
|
|
36
|
-
// cannot contain one, so the round trip is lossless. (A NUL would also be
|
|
37
|
-
// unambiguous and is what this first used; a raw control byte in a source
|
|
38
|
-
// file makes grep treat the whole file as binary, and the repo rejects it.)
|
|
39
|
-
const shownKey = shownKeys.map(k => k ?? "").join("|");
|
|
40
|
-
|
|
41
|
-
const offSlot = useMemo(
|
|
42
|
-
() => {
|
|
43
|
-
if (terms.length === 0) return undefined;
|
|
44
|
-
const shown = shownKey.split("|").map(k => k || undefined);
|
|
45
|
-
return offSlotMatch(entity.searchMatches, shown)
|
|
46
|
-
?? localRowMatch(entity.values, properties, terms, shown);
|
|
47
|
-
},
|
|
48
|
-
[entity.searchMatches, entity.values, properties, shownKey, terms]
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
return { terms, offSlot };
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Which field the hit was in, and the text around it.
|
|
56
|
-
*
|
|
57
|
-
* Sits where the subtitle would have gone. Deliberately quiet — a small amber
|
|
58
|
-
* caption and one line — because it is context for a result, not the result. It
|
|
59
|
-
* has to survive a narrow column, so it truncates rather than wraps.
|
|
60
|
-
*/
|
|
61
|
-
export function MatchExplanation({ match, label }: { match: SearchMatch; label: string }) {
|
|
62
|
-
return (
|
|
63
|
-
<div className="mt-0.5 flex items-baseline gap-1.5 min-w-0">
|
|
64
|
-
<span
|
|
65
|
-
className="shrink-0 text-[10px] uppercase tracking-wide font-semibold text-amber-700 dark:text-amber-500/90"
|
|
66
|
-
title={match.field}
|
|
67
|
-
>
|
|
68
|
-
{label}
|
|
69
|
-
</span>
|
|
70
|
-
<span className="truncate text-xs text-surface-500 dark:text-surface-400 min-w-0">
|
|
71
|
-
<Snippet text={match.snippet}/>
|
|
72
|
-
</span>
|
|
73
|
-
</div>
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* What to call a matched field on screen.
|
|
79
|
-
*
|
|
80
|
-
* The path is what the config and the server speak — `questionnaire.
|
|
81
|
-
* certifications` — and is unreadable in a list. Resolve it to the property's
|
|
82
|
-
* declared `name`, walking into `map` properties for a dotted path, and fall
|
|
83
|
-
* back to the last segment humanised, so an unnamed field still reads as words
|
|
84
|
-
* rather than as a path.
|
|
85
|
-
*/
|
|
86
|
-
export function fieldLabel(properties: Record<string, unknown> | undefined, path: string): string {
|
|
87
|
-
const segments = path.split(".");
|
|
88
|
-
let node = properties;
|
|
89
|
-
let named: string | undefined;
|
|
90
|
-
|
|
91
|
-
for (const segment of segments) {
|
|
92
|
-
const property = node?.[segment] as { name?: string; properties?: Record<string, unknown> } | undefined;
|
|
93
|
-
// A path can run deeper than the schema describes — `content.value`,
|
|
94
|
-
// where `content` is an array of blocks whose shape is not declared
|
|
95
|
-
// property-by-property. Keep the last name that *was* declared rather
|
|
96
|
-
// than discarding it: "Content" is the answer a reader wants, and
|
|
97
|
-
// resetting to undefined here labelled that field "Value".
|
|
98
|
-
if (!property) break;
|
|
99
|
-
named = property.name ?? named;
|
|
100
|
-
node = property.properties;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (named) return named;
|
|
104
|
-
const last = segments[segments.length - 1] ?? path;
|
|
105
|
-
return last.replace(/[_-]+/g, " ").replace(/^./, c => c.toUpperCase());
|
|
106
|
-
}
|