@rebasepro/cms 0.17.3 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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,295 +0,0 @@
|
|
|
1
|
-
import { Entity, EntityReference, Properties, Property } from "@rebasepro/types";
|
|
2
|
-
import { type ArrayValuesCount, getArrayValuesCount, getValueInPath } from "@rebasepro/utils";
|
|
3
|
-
|
|
4
|
-
interface Header {
|
|
5
|
-
key: string;
|
|
6
|
-
label: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface DownloadEntitiesExportParams<M extends Record<string, unknown>> {
|
|
10
|
-
data: Entity<M>[];
|
|
11
|
-
additionalData: Record<string, unknown>[] | undefined;
|
|
12
|
-
properties: Properties;
|
|
13
|
-
propertiesOrder: string[] | undefined;
|
|
14
|
-
name: string;
|
|
15
|
-
flattenArrays: boolean;
|
|
16
|
-
additionalHeaders: string[] | undefined;
|
|
17
|
-
exportType: "csv" | "json";
|
|
18
|
-
dateExportType: "timestamp" | "string";
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function downloadEntitiesExport<M extends Record<string, unknown>>({
|
|
22
|
-
data,
|
|
23
|
-
additionalData,
|
|
24
|
-
properties,
|
|
25
|
-
propertiesOrder,
|
|
26
|
-
name,
|
|
27
|
-
flattenArrays,
|
|
28
|
-
additionalHeaders,
|
|
29
|
-
exportType,
|
|
30
|
-
dateExportType
|
|
31
|
-
}: DownloadEntitiesExportParams<M>
|
|
32
|
-
) {
|
|
33
|
-
|
|
34
|
-
console.debug("Downloading export", {
|
|
35
|
-
dataLength: data.length,
|
|
36
|
-
properties,
|
|
37
|
-
exportType,
|
|
38
|
-
dateExportType
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
if (exportType === "csv") {
|
|
42
|
-
const arrayValuesCount = flattenArrays ? getArrayValuesCount(data.map(d => d.values)) : {};
|
|
43
|
-
const headers = getExportHeaders(properties, propertiesOrder, additionalHeaders, arrayValuesCount);
|
|
44
|
-
const exportableData = getEntityCSVExportableData(data, additionalData, properties, headers, dateExportType);
|
|
45
|
-
const headersData = entryToCSVRow(headers.map(h => h.label));
|
|
46
|
-
const csvData = exportableData.map(entry => entryToCSVRow(entry));
|
|
47
|
-
downloadBlob([headersData, ...csvData], `${name}.csv`, "text/csv");
|
|
48
|
-
} else {
|
|
49
|
-
const exportableData = getEntityJsonExportableData(data, additionalData, properties, dateExportType);
|
|
50
|
-
const json = JSON.stringify(exportableData, null, 2);
|
|
51
|
-
downloadBlob([json], `${name}.json`, "application/json");
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function getEntityCSVExportableData(data: Entity<Record<string, unknown>>[],
|
|
56
|
-
additionalData: Record<string, unknown>[] | undefined,
|
|
57
|
-
properties: Properties,
|
|
58
|
-
headers: Header[],
|
|
59
|
-
dateExportType: "timestamp" | "string"
|
|
60
|
-
) {
|
|
61
|
-
|
|
62
|
-
const mergedData: Record<string, unknown>[] = data.map(e => ({
|
|
63
|
-
id: e.id,
|
|
64
|
-
...processValuesForExport(e.values, properties, "csv", dateExportType)
|
|
65
|
-
}));
|
|
66
|
-
|
|
67
|
-
if (additionalData) {
|
|
68
|
-
additionalData.forEach((additional, index) => {
|
|
69
|
-
mergedData[index] = { ...mergedData[index],
|
|
70
|
-
...additional };
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return mergedData && mergedData.map((entry) => {
|
|
75
|
-
return headers.map((header) => getValueInPath(entry, header.key));
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function getEntityJsonExportableData(data: Entity<Record<string, unknown>>[],
|
|
80
|
-
additionalData: Record<string, unknown>[] | undefined,
|
|
81
|
-
properties: Properties,
|
|
82
|
-
dateExportType: "timestamp" | "string"
|
|
83
|
-
) {
|
|
84
|
-
|
|
85
|
-
const mergedData: Record<string, unknown>[] = data.map(e => ({
|
|
86
|
-
id: e.id,
|
|
87
|
-
...processValuesForExport(e.values, properties, "json", dateExportType)
|
|
88
|
-
}));
|
|
89
|
-
|
|
90
|
-
if (additionalData) {
|
|
91
|
-
additionalData.forEach((additional, index) => {
|
|
92
|
-
mergedData[index] = { ...mergedData[index],
|
|
93
|
-
...additional };
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return mergedData;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function getExportHeaders<M extends Record<string, unknown>>(properties: Properties,
|
|
101
|
-
propertiesOrder: string[] | undefined,
|
|
102
|
-
additionalHeaders: string[] | undefined,
|
|
103
|
-
arrayValuesCount?: ArrayValuesCount): Header[] {
|
|
104
|
-
|
|
105
|
-
const headers: Header[] = [
|
|
106
|
-
{
|
|
107
|
-
label: "id",
|
|
108
|
-
key: "id"
|
|
109
|
-
},
|
|
110
|
-
...(propertiesOrder ?? Object.keys(properties))
|
|
111
|
-
.flatMap((childKey) => {
|
|
112
|
-
const property = properties[childKey];
|
|
113
|
-
if (!property) {
|
|
114
|
-
console.warn("Property not found", childKey, properties);
|
|
115
|
-
return [];
|
|
116
|
-
}
|
|
117
|
-
if (arrayValuesCount && arrayValuesCount[childKey] > 1) {
|
|
118
|
-
return Array.from({ length: arrayValuesCount[childKey] },
|
|
119
|
-
(_, i) => getHeaders(property as Property, `${childKey}[${i}]`, ""))
|
|
120
|
-
.flat();
|
|
121
|
-
} else {
|
|
122
|
-
return getHeaders(property as Property, childKey, "");
|
|
123
|
-
}
|
|
124
|
-
})
|
|
125
|
-
];
|
|
126
|
-
|
|
127
|
-
if (additionalHeaders) {
|
|
128
|
-
headers.push(...additionalHeaders.map(h => ({
|
|
129
|
-
label: h,
|
|
130
|
-
key: h
|
|
131
|
-
})));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return headers;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Get headers for property. There could be more than one header per property
|
|
139
|
-
* @param property
|
|
140
|
-
* @param propertyKey
|
|
141
|
-
* @param prefix
|
|
142
|
-
*/
|
|
143
|
-
function getHeaders(property: Property, propertyKey: string, prefix = ""): Header[] {
|
|
144
|
-
const currentKey = prefix ? `${prefix}.${propertyKey}` : propertyKey;
|
|
145
|
-
if (property.type === "map" && property.properties) {
|
|
146
|
-
return Object.entries(property.properties)
|
|
147
|
-
.map(([childKey, p]) => getHeaders(p, childKey, currentKey))
|
|
148
|
-
.flat();
|
|
149
|
-
} else {
|
|
150
|
-
return [{
|
|
151
|
-
label: currentKey,
|
|
152
|
-
key: currentKey
|
|
153
|
-
}];
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Read whatever a `date` column actually arrived as into a `Date`.
|
|
159
|
-
*
|
|
160
|
-
* The driver/WebSocket path revives `{ __type: "date" }` into a `Date`; the REST
|
|
161
|
-
* path — which is the one the admin is on — leaves an ISO string, and an epoch
|
|
162
|
-
* number is what a re-imported export carries. Returns `undefined` for anything
|
|
163
|
-
* that is not a date, so the caller can pass the raw value through.
|
|
164
|
-
*/
|
|
165
|
-
function toExportableDate(inputValue: unknown): Date | undefined {
|
|
166
|
-
if (inputValue instanceof Date) return Number.isNaN(inputValue.getTime()) ? undefined : inputValue;
|
|
167
|
-
if (typeof inputValue === "number" && Number.isFinite(inputValue)) return new Date(inputValue);
|
|
168
|
-
if (typeof inputValue === "string" && inputValue.trim() !== "") {
|
|
169
|
-
const parsed = new Date(inputValue);
|
|
170
|
-
return Number.isNaN(parsed.getTime()) ? undefined : parsed;
|
|
171
|
-
}
|
|
172
|
-
return undefined;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function processValueForExport(inputValue: unknown,
|
|
176
|
-
property: Property,
|
|
177
|
-
exportType: "csv" | "json",
|
|
178
|
-
dateExportType: "timestamp" | "string"
|
|
179
|
-
): unknown {
|
|
180
|
-
|
|
181
|
-
let value: unknown;
|
|
182
|
-
if (property.type === "map" && property.properties) {
|
|
183
|
-
value = processValuesForExport(inputValue as Record<string, unknown>, property.properties as Properties, exportType, dateExportType);
|
|
184
|
-
} else if (property.type === "array") {
|
|
185
|
-
if (property.of && Array.isArray(inputValue)) {
|
|
186
|
-
if (Array.isArray(property.of)) {
|
|
187
|
-
value = property.of.map((p, i) => processValueForExport(inputValue[i], p, exportType, dateExportType));
|
|
188
|
-
} else if (property.of.type === "map") {
|
|
189
|
-
value = exportType === "csv"
|
|
190
|
-
? inputValue.map((e) => JSON.stringify(e))
|
|
191
|
-
: inputValue.map((e) => processValueForExport(e, property.of as Property, exportType, dateExportType));
|
|
192
|
-
;
|
|
193
|
-
} else {
|
|
194
|
-
value = inputValue.map((e) => processValueForExport(e, property.of as Property, exportType, dateExportType));
|
|
195
|
-
}
|
|
196
|
-
} else {
|
|
197
|
-
value = inputValue;
|
|
198
|
-
}
|
|
199
|
-
} else if (property.type === "reference" && inputValue && typeof inputValue === "object" && "isEntityReference" in inputValue && typeof (inputValue as EntityReference).isEntityReference === "function" && (inputValue as EntityReference).isEntityReference()) {
|
|
200
|
-
const ref = inputValue ? inputValue as EntityReference : undefined;
|
|
201
|
-
value = ref ? ref.fullPath : null;
|
|
202
|
-
} else if (property.type === "date") {
|
|
203
|
-
// Not `instanceof Date`: the admin reads over REST, and the REST row
|
|
204
|
-
// pipeline hands dates back as the database wrote them — a string. That
|
|
205
|
-
// made this branch dead on every live export, so both radio options
|
|
206
|
-
// produced identical files. Normalise here, where the declared type says
|
|
207
|
-
// the column is a date, and leave anything unparseable untouched rather
|
|
208
|
-
// than exporting an invalid date as `null`.
|
|
209
|
-
const date = toExportableDate(inputValue);
|
|
210
|
-
value = date
|
|
211
|
-
? (dateExportType === "timestamp" ? date.getTime() : date.toISOString())
|
|
212
|
-
: inputValue;
|
|
213
|
-
} else {
|
|
214
|
-
value = inputValue;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return value;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function processValuesForExport<M extends Record<string, unknown>>
|
|
221
|
-
(inputValues: Record<string, unknown>,
|
|
222
|
-
properties: Properties,
|
|
223
|
-
exportType: "csv" | "json",
|
|
224
|
-
dateExportType: "timestamp" | "string"
|
|
225
|
-
): Record<string, unknown> {
|
|
226
|
-
const updatedValues = Object.entries(properties)
|
|
227
|
-
.map(([key, property]) => {
|
|
228
|
-
const inputValue = inputValues && (inputValues)[key];
|
|
229
|
-
const updatedValue = processValueForExport(inputValue, property as Property, exportType, dateExportType);
|
|
230
|
-
if (updatedValue === undefined) return {};
|
|
231
|
-
return ({ [key]: updatedValue });
|
|
232
|
-
})
|
|
233
|
-
.reduce((a, b) => ({ ...a,
|
|
234
|
-
...b }), {}) as Record<string, unknown>;
|
|
235
|
-
return { ...inputValues,
|
|
236
|
-
...updatedValues };
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Characters that make a spreadsheet read a cell as a formula rather than text.
|
|
241
|
-
*
|
|
242
|
-
* Quoting is CSV *escaping* and is not enough: Excel, LibreOffice Calc and
|
|
243
|
-
* Sheets strip the CSV quoting at parse time and then evaluate a cell whose
|
|
244
|
-
* first character is one of these — `=HYPERLINK(…)` exfiltrates neighbouring
|
|
245
|
-
* cells on click, `=cmd|'…'!A0` is worse.
|
|
246
|
-
*/
|
|
247
|
-
const FORMULA_TRIGGERS = ["=", "+", "-", "@", "\t", "\r"];
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Neutralise a cell that a spreadsheet would otherwise evaluate, by prefixing a
|
|
251
|
-
* single quote — the standard OWASP mitigation. The apostrophe is consumed by
|
|
252
|
-
* the spreadsheet as "treat the rest as text", so the value reads back intact.
|
|
253
|
-
*/
|
|
254
|
-
export function escapeCsvFormula(value: string): string {
|
|
255
|
-
const first = value.charAt(0);
|
|
256
|
-
if (!FORMULA_TRIGGERS.includes(first)) return value;
|
|
257
|
-
// A signed number is not a formula, and prefixing it would turn every
|
|
258
|
-
// negative amount in the file into text. `-1+1` is still neutralised,
|
|
259
|
-
// because it is not a number.
|
|
260
|
-
if ((first === "-" || first === "+") && value.trim() !== "" && Number.isFinite(Number(value))) return value;
|
|
261
|
-
return "'" + value;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function toCSVCell(v: unknown): string {
|
|
265
|
-
if (v === null || v === undefined) return "";
|
|
266
|
-
const s = Array.isArray(v) ? JSON.stringify(v) : String(v);
|
|
267
|
-
return "\"" + escapeCsvFormula(s).replaceAll("\"", "\"\"") + "\"";
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
export function entryToCSVRow(entry: unknown[]) {
|
|
271
|
-
return entry
|
|
272
|
-
.map(toCSVCell)
|
|
273
|
-
.join(",") + "\r\n";
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
export function downloadBlob(content: BlobPart[], filename: string, contentType: string) {
|
|
277
|
-
const blob = new Blob(content, { type: contentType });
|
|
278
|
-
const url = URL.createObjectURL(blob);
|
|
279
|
-
const pom = document.createElement("a");
|
|
280
|
-
pom.href = url;
|
|
281
|
-
pom.setAttribute("download", filename);
|
|
282
|
-
pom.click();
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
export function downloadDataAsCsv(data: object[], name: string) {
|
|
286
|
-
if (data.length === 0) return;
|
|
287
|
-
|
|
288
|
-
const headers = Object.keys(data[0]);
|
|
289
|
-
const csvContent = [
|
|
290
|
-
headers.join(","),
|
|
291
|
-
...data.map(row => headers.map(header => toCSVCell((row as Record<string, unknown>)[header])).join(","))
|
|
292
|
-
].join("\r\n");
|
|
293
|
-
|
|
294
|
-
downloadBlob([csvContent], `${name}.csv`, "text/csv");
|
|
295
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { Entity, FindParams, FindResponse } from "@rebasepro/types";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Rows asked for per request.
|
|
5
|
-
*
|
|
6
|
-
* Kept at or below the server's `MAX_LIST_LIMIT`, which is now the largest page
|
|
7
|
-
* a read will serve *and refuses* anything larger — it used to clamp silently,
|
|
8
|
-
* and asking for 100 000 while receiving 1 000 looked exactly like a collection
|
|
9
|
-
* with 1 000 rows in it. The walk still never trusts the page size it asked for:
|
|
10
|
-
* it advances by the rows it was actually handed.
|
|
11
|
-
*/
|
|
12
|
-
export const EXPORT_PAGE_SIZE = 500;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Most rows one browser-side export will materialise.
|
|
16
|
-
*
|
|
17
|
-
* Everything here is built in memory and handed to a Blob, so there is a
|
|
18
|
-
* ceiling whether or not it is named. Naming it means going over it **throws**
|
|
19
|
-
* instead of writing a short file that reads like the whole collection.
|
|
20
|
-
*/
|
|
21
|
-
export const MAX_EXPORT_ROWS = 100_000;
|
|
22
|
-
|
|
23
|
-
export interface FetchAllForExportParams<M extends Record<string, unknown>> {
|
|
24
|
-
/** The collection accessor to read through — `dataClient.collection(path)`. */
|
|
25
|
-
accessor: { find(params?: FindParams<M>): Promise<FindResponse<M>> };
|
|
26
|
-
/** Query to export. The window (`limit` / `offset` / `page`) is owned by the walk. */
|
|
27
|
-
params?: Omit<FindParams<M>, "limit" | "offset" | "page">;
|
|
28
|
-
pageSize?: number;
|
|
29
|
-
maxRows?: number;
|
|
30
|
-
/** Called after every page with the rows so far, and the total when the server reports one. */
|
|
31
|
-
onProgress?: (loaded: number, total: number | undefined) => void;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Read **every** row matching a query, one page at a time.
|
|
36
|
-
*
|
|
37
|
-
* `find({})` sends no `limit`, and an absent limit is resolved server-side to
|
|
38
|
-
* `DEFAULT_LIST_LIMIT` — 50 rows. The export used to hand those 50 rows back as
|
|
39
|
-
* `<collection>.csv` with nothing saying it was a sample, next to a dialog
|
|
40
|
-
* warning that the collection had 100 000 documents.
|
|
41
|
-
*
|
|
42
|
-
* Termination is driven by the server's `meta.hasMore` where it is reported and
|
|
43
|
-
* by an empty page otherwise — never by comparing a page's length against the
|
|
44
|
-
* requested limit, since a final page that happens to be exactly full is
|
|
45
|
-
* indistinguishable that way and a walk that stops there drops rows.
|
|
46
|
-
*
|
|
47
|
-
* @throws When more than `maxRows` rows match. A truncated export is worse than
|
|
48
|
-
* no export: it is indistinguishable from a complete one.
|
|
49
|
-
*/
|
|
50
|
-
export async function fetchAllEntitiesForExport<M extends Record<string, unknown>>({
|
|
51
|
-
accessor,
|
|
52
|
-
params,
|
|
53
|
-
pageSize = EXPORT_PAGE_SIZE,
|
|
54
|
-
maxRows = MAX_EXPORT_ROWS,
|
|
55
|
-
onProgress
|
|
56
|
-
}: FetchAllForExportParams<M>): Promise<Entity<M>[]> {
|
|
57
|
-
|
|
58
|
-
const rows: Entity<M>[] = [];
|
|
59
|
-
let offset = 0;
|
|
60
|
-
|
|
61
|
-
for (;;) {
|
|
62
|
-
const res = await accessor.find({
|
|
63
|
-
...params,
|
|
64
|
-
limit: pageSize,
|
|
65
|
-
offset
|
|
66
|
-
} as FindParams<M>);
|
|
67
|
-
|
|
68
|
-
const page = res?.data ?? [];
|
|
69
|
-
rows.push(...page);
|
|
70
|
-
onProgress?.(rows.length, res?.meta?.total);
|
|
71
|
-
|
|
72
|
-
if (rows.length > maxRows) {
|
|
73
|
-
throw new Error(
|
|
74
|
-
`This export would contain more than ${maxRows.toLocaleString()} rows, which is more than the ` +
|
|
75
|
-
"browser can build in one file. Filter the collection down, or export it from the server."
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// An empty page ends the walk whatever the metadata says, so a server
|
|
80
|
-
// that keeps answering `hasMore` cannot spin forever.
|
|
81
|
-
if (page.length === 0) break;
|
|
82
|
-
if (res?.meta && !res.meta.hasMore) break;
|
|
83
|
-
|
|
84
|
-
// By rows received, not by `pageSize`: a server whose ceiling is lower
|
|
85
|
-
// than the page we asked for would otherwise skip everything it clamped.
|
|
86
|
-
offset += page.length;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return rows;
|
|
90
|
-
}
|
package/src/data_export/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./export";
|
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { getPropertyInPath } from "../../util";
|
|
3
|
-
import { Properties, Property } from "@rebasepro/types";
|
|
4
|
-
import {
|
|
5
|
-
BooleanSwitchWithLabel,
|
|
6
|
-
ChevronRightIcon,
|
|
7
|
-
DateTimeField,
|
|
8
|
-
ExpandablePanel,
|
|
9
|
-
Select,
|
|
10
|
-
SelectItem,
|
|
11
|
-
Table,
|
|
12
|
-
TableBody,
|
|
13
|
-
TableCell,
|
|
14
|
-
TableHeader,
|
|
15
|
-
TableRow,
|
|
16
|
-
TextField,
|
|
17
|
-
Typography
|
|
18
|
-
} from "@rebasepro/ui";
|
|
19
|
-
import { getIn, setIn } from "@rebasepro/forms";
|
|
20
|
-
import { useTranslation } from "@rebasepro/app";
|
|
21
|
-
import { ImportConfig } from "../types";
|
|
22
|
-
|
|
23
|
-
export interface DataPropertyMappingProps {
|
|
24
|
-
importConfig: ImportConfig;
|
|
25
|
-
destinationProperties: Record<string, Property>;
|
|
26
|
-
buildPropertyView?: (props: {
|
|
27
|
-
isIdColumn: boolean,
|
|
28
|
-
property: Property | null,
|
|
29
|
-
propertyKey: string | null,
|
|
30
|
-
importKey: string
|
|
31
|
-
}) => any;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function DataNewPropertiesMapping({
|
|
35
|
-
importConfig,
|
|
36
|
-
destinationProperties,
|
|
37
|
-
buildPropertyView
|
|
38
|
-
}: DataPropertyMappingProps) {
|
|
39
|
-
|
|
40
|
-
const { t } = useTranslation();
|
|
41
|
-
const headersMapping = importConfig.headersMapping;
|
|
42
|
-
const headingsOrder = importConfig.headingsOrder;
|
|
43
|
-
const idColumn = importConfig.idColumn;
|
|
44
|
-
const originProperties = importConfig.originProperties;
|
|
45
|
-
|
|
46
|
-
return (
|
|
47
|
-
<>
|
|
48
|
-
|
|
49
|
-
<IdSelectField idColumn={idColumn}
|
|
50
|
-
headersMapping={headersMapping}
|
|
51
|
-
onChange={(value) => importConfig.setIdColumn(value ?? undefined)}/>
|
|
52
|
-
|
|
53
|
-
<div className={"h-4"}/>
|
|
54
|
-
|
|
55
|
-
<Table style={{
|
|
56
|
-
tableLayout: "fixed"
|
|
57
|
-
}}>
|
|
58
|
-
<TableHeader>
|
|
59
|
-
<TableCell header={true} style={{ width: "20%" }}>
|
|
60
|
-
Column in file
|
|
61
|
-
</TableCell>
|
|
62
|
-
<TableCell header={true}>
|
|
63
|
-
</TableCell>
|
|
64
|
-
<TableCell header={true} style={{ width: "75%" }}>
|
|
65
|
-
Map to Property
|
|
66
|
-
</TableCell>
|
|
67
|
-
</TableHeader>
|
|
68
|
-
<TableBody>
|
|
69
|
-
{destinationProperties &&
|
|
70
|
-
headingsOrder.map((importKey) => {
|
|
71
|
-
const mappedKey = headersMapping[importKey];
|
|
72
|
-
const propertyKey = headersMapping[importKey];
|
|
73
|
-
const property = mappedKey ? getPropertyInPath(destinationProperties, mappedKey) as Property : null;
|
|
74
|
-
|
|
75
|
-
const originProperty = getPropertyInPath(originProperties, importKey) as Property | undefined;
|
|
76
|
-
const origintype = originProperty
|
|
77
|
-
? (originProperty.type === "array" && typeof originProperty.of === "object"
|
|
78
|
-
? `${originProperty.type} - ${(originProperty.of as Property).type}`
|
|
79
|
-
: originProperty.type)
|
|
80
|
-
: undefined;
|
|
81
|
-
return <TableRow key={importKey} style={{ height: "90px" }}>
|
|
82
|
-
<TableCell style={{ width: "20%" }}>
|
|
83
|
-
<Typography variant={"body2"}>{importKey}</Typography>
|
|
84
|
-
{originProperty && <Typography
|
|
85
|
-
variant={"caption"}
|
|
86
|
-
color={"secondary"}
|
|
87
|
-
>{origintype}</Typography>}
|
|
88
|
-
</TableCell>
|
|
89
|
-
<TableCell>
|
|
90
|
-
<ChevronRightIcon/>
|
|
91
|
-
</TableCell>
|
|
92
|
-
<TableCell className={importKey === idColumn ? "text-center" : undefined}
|
|
93
|
-
style={{ width: "75%" }}>
|
|
94
|
-
{buildPropertyView?.({
|
|
95
|
-
isIdColumn: importKey === idColumn,
|
|
96
|
-
property,
|
|
97
|
-
propertyKey,
|
|
98
|
-
importKey
|
|
99
|
-
})}
|
|
100
|
-
</TableCell>
|
|
101
|
-
</TableRow>;
|
|
102
|
-
}
|
|
103
|
-
)}
|
|
104
|
-
</TableBody>
|
|
105
|
-
</Table>
|
|
106
|
-
|
|
107
|
-
<ExpandablePanel title="Default values" initiallyExpanded={false} innerClassName={"p-4 mt-4"}>
|
|
108
|
-
|
|
109
|
-
<div className={"text-sm text-surface-accent-500 dark:text-surface-accent-300 font-medium ml-3.5 mb-1"}>
|
|
110
|
-
You can select a default value for unmapped columns and empty values:
|
|
111
|
-
</div>
|
|
112
|
-
<Table style={{
|
|
113
|
-
tableLayout: "fixed"
|
|
114
|
-
}}>
|
|
115
|
-
<TableHeader>
|
|
116
|
-
<TableCell header={true} style={{ width: "30%" }}>
|
|
117
|
-
Property
|
|
118
|
-
</TableCell>
|
|
119
|
-
<TableCell header={true}>
|
|
120
|
-
</TableCell>
|
|
121
|
-
<TableCell header={true} style={{ width: "65%" }}>
|
|
122
|
-
{t("default_value")}
|
|
123
|
-
</TableCell>
|
|
124
|
-
</TableHeader>
|
|
125
|
-
<TableBody>
|
|
126
|
-
{destinationProperties &&
|
|
127
|
-
getAllPropertyKeys(destinationProperties).map((key) => {
|
|
128
|
-
const property = getPropertyInPath(destinationProperties, key);
|
|
129
|
-
if (typeof property !== "object" || property === null) {
|
|
130
|
-
return null;
|
|
131
|
-
}
|
|
132
|
-
if (!["number", "string", "boolean", "map"].includes(property.type)) {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
return <TableRow key={key} style={{ height: "70px" }}>
|
|
136
|
-
<TableCell style={{ width: "20%" }}>
|
|
137
|
-
<Typography variant={"body2"}>{key}</Typography>
|
|
138
|
-
</TableCell>
|
|
139
|
-
<TableCell>
|
|
140
|
-
<ChevronRightIcon/>
|
|
141
|
-
</TableCell>
|
|
142
|
-
<TableCell className={key === idColumn ? "text-center" : undefined}
|
|
143
|
-
style={{ width: "75%" }}>
|
|
144
|
-
<DefaultValuesField property={property}
|
|
145
|
-
defaultValue={getIn(importConfig.defaultValues, key)}
|
|
146
|
-
onValueChange={(value) => {
|
|
147
|
-
const newValues = setIn(importConfig.defaultValues, key, value);
|
|
148
|
-
importConfig.setDefaultValues(newValues as Record<string, any>);
|
|
149
|
-
}}/>
|
|
150
|
-
</TableCell>
|
|
151
|
-
</TableRow>;
|
|
152
|
-
}
|
|
153
|
-
)}
|
|
154
|
-
</TableBody>
|
|
155
|
-
</Table>
|
|
156
|
-
</ExpandablePanel>
|
|
157
|
-
</>
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function getAllPropertyKeys(properties: Properties, currentKey?: string): string[] {
|
|
162
|
-
return Object.entries(properties).reduce((acc, [key, property]) => {
|
|
163
|
-
const accumulatedKey = currentKey ? `${currentKey}.${key}` : key;
|
|
164
|
-
if (typeof property !== "function" && property.type === "map" && property.properties) {
|
|
165
|
-
const childProperties = getAllPropertyKeys(property.properties, accumulatedKey);
|
|
166
|
-
return [...acc, ...childProperties];
|
|
167
|
-
}
|
|
168
|
-
return [...acc, accumulatedKey];
|
|
169
|
-
}, [] as string[]);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function IdSelectField({
|
|
173
|
-
idColumn,
|
|
174
|
-
headersMapping,
|
|
175
|
-
onChange
|
|
176
|
-
}: {
|
|
177
|
-
idColumn?: string,
|
|
178
|
-
headersMapping: Record<string, string | null>;
|
|
179
|
-
onChange: (value: string | null) => void
|
|
180
|
-
}) {
|
|
181
|
-
return <div>
|
|
182
|
-
<Select
|
|
183
|
-
size={"medium"}
|
|
184
|
-
value={idColumn ?? ""}
|
|
185
|
-
fullWidth={true}
|
|
186
|
-
onChange={(event) => {
|
|
187
|
-
const value = event.target.value;
|
|
188
|
-
onChange(value === "__none__" ? null : value);
|
|
189
|
-
}}
|
|
190
|
-
placeholder={"Autogenerate ID"}
|
|
191
|
-
renderValue={(value) => {
|
|
192
|
-
return <Typography variant={"body2"}>
|
|
193
|
-
{value !== "__none__" ? value : "Autogenerate ID"}
|
|
194
|
-
</Typography>;
|
|
195
|
-
}}
|
|
196
|
-
label={"Column that will be used as ID for each document"}>
|
|
197
|
-
<SelectItem value={"__none__"}>Autogenerate ID</SelectItem>
|
|
198
|
-
{Object.entries(headersMapping).map(([key, value]) => {
|
|
199
|
-
return <SelectItem key={key} value={key}>{key}</SelectItem>;
|
|
200
|
-
})}
|
|
201
|
-
</Select>
|
|
202
|
-
</div>;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function DefaultValuesField({
|
|
206
|
-
property,
|
|
207
|
-
onValueChange,
|
|
208
|
-
defaultValue
|
|
209
|
-
}: { property: Property, onValueChange: (value: any) => void, defaultValue?: any }) {
|
|
210
|
-
const { t } = useTranslation();
|
|
211
|
-
const defaultValueLabel = t("default_value");
|
|
212
|
-
// Named fields stay distinguishable from each other — several of these sit
|
|
213
|
-
// in one table, and an aria-label repeated verbatim tells a screen reader
|
|
214
|
-
// nothing about which row it is on.
|
|
215
|
-
//
|
|
216
|
-
// Composed with a separator rather than a phrase: there is no key for the
|
|
217
|
-
// possessive form, and `t` returns the key itself for one that does not
|
|
218
|
-
// exist, so inventing `default_value_for` here would read out the literal
|
|
219
|
-
// string "default_value_for" in every locale, English included.
|
|
220
|
-
const ariaLabel = property.name
|
|
221
|
-
? `${defaultValueLabel}: ${property.name}`
|
|
222
|
-
: defaultValueLabel;
|
|
223
|
-
if (property.type === "string") {
|
|
224
|
-
return <TextField size={"medium"}
|
|
225
|
-
aria-label={ariaLabel}
|
|
226
|
-
placeholder={defaultValueLabel}
|
|
227
|
-
value={defaultValue ?? ""}
|
|
228
|
-
onChange={(event) => onValueChange(event.target.value)}/>;
|
|
229
|
-
} else if (property.type === "number") {
|
|
230
|
-
return <TextField size={"medium"}
|
|
231
|
-
type={"number"}
|
|
232
|
-
aria-label={ariaLabel}
|
|
233
|
-
value={defaultValue ?? ""}
|
|
234
|
-
placeholder={defaultValueLabel}
|
|
235
|
-
onChange={(event) => onValueChange(event.target.value)}/>;
|
|
236
|
-
} else if (property.type === "boolean") {
|
|
237
|
-
return <BooleanSwitchWithLabel
|
|
238
|
-
value={defaultValue ?? null}
|
|
239
|
-
allowIndeterminate={true}
|
|
240
|
-
size={"small"}
|
|
241
|
-
onValueChange={(v: boolean | null) => onValueChange(v === null ? undefined : v)}
|
|
242
|
-
label={defaultValue === undefined
|
|
243
|
-
? "Do not set value"
|
|
244
|
-
: defaultValue === true
|
|
245
|
-
? "Set value to true"
|
|
246
|
-
: "Set value to false"}
|
|
247
|
-
/>
|
|
248
|
-
} else if (property.type === "date") {
|
|
249
|
-
return <DateTimeField
|
|
250
|
-
mode={property.mode ?? "date"}
|
|
251
|
-
size={"medium"}
|
|
252
|
-
value={defaultValue ?? undefined}
|
|
253
|
-
onChange={(dateValue: Date | null) => {
|
|
254
|
-
onValueChange(dateValue);
|
|
255
|
-
}}
|
|
256
|
-
clearable={true}
|
|
257
|
-
/>
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
return null;
|
|
261
|
-
}
|