@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
package/src/form/EntityForm.tsx
DELETED
|
@@ -1,761 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import type { AdditionalFieldDelegateProps } from "@rebasepro/cms-types";
|
|
3
|
-
import type { FormContext, PropertyFieldBindingProps } from "../types/fields";
|
|
4
|
-
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
-
import { Entity, EntityStatus, EntityValues } from "@rebasepro/types";
|
|
6
|
-
import type { EntityFormProps } from "../types/components/EntityFormProps";
|
|
7
|
-
import { deepEqual as equal } from "fast-equals";
|
|
8
|
-
|
|
9
|
-
import { ErrorBoundary } from "@rebasepro/ui";
|
|
10
|
-
import { AlignLeftIcon, useDebouncedCallback } from "@rebasepro/ui";
|
|
11
|
-
import { getDefaultValuesFor } from "@rebasepro/common";
|
|
12
|
-
import { isDisabled, isReadOnly } from "@rebasepro/app";
|
|
13
|
-
|
|
14
|
-
import { getFormFieldKeys, resolveFormLayout } from "@rebasepro/app";
|
|
15
|
-
import type { ResolvedFormField } from "@rebasepro/app";
|
|
16
|
-
import { Alert, Button, cls, defaultBorderMixin, Dialog, DialogActions, DialogContent, DialogTitle, paperMixin, Typography } from "@rebasepro/ui";
|
|
17
|
-
import { Formex, FormexController, useCreateFormex } from "@rebasepro/forms";
|
|
18
|
-
|
|
19
|
-
import { FieldBlock, isSelfLabellingProperty, LABEL_ICON_SIZE, spanClass } from "./components/FieldBlock";
|
|
20
|
-
import { AdditionalFieldValue } from "../components/AdditionalFieldValue";
|
|
21
|
-
import { FormRail, RecordMeta } from "./components/FormRail";
|
|
22
|
-
import { FormSections } from "./components/FormSections";
|
|
23
|
-
import { useRailVisible } from "./components/useRailVisible";
|
|
24
|
-
import { PropertyFieldBinding } from "./PropertyFieldBinding";
|
|
25
|
-
import { flattenKeys } from "@rebasepro/app";
|
|
26
|
-
import { ErrorFocus } from "./components/ErrorFocus";
|
|
27
|
-
import { CustomFieldValidator, getEntitySchema } from "./validation";
|
|
28
|
-
import { EntityFormActions } from "./EntityFormActions";
|
|
29
|
-
import type { EntityFormActionsProps } from "../types/components/EntityFormActionsProps";
|
|
30
|
-
import { LocalChangesMenu } from "./components/LocalChangesMenu";
|
|
31
|
-
import { useUndoableDiscard } from "./useUndoableDiscard";
|
|
32
|
-
|
|
33
|
-
import { mergeDeep } from "@rebasepro/utils";
|
|
34
|
-
import {
|
|
35
|
-
getChanges,
|
|
36
|
-
zodToFormErrors
|
|
37
|
-
} from "./form_utils";
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Headless entity form component.
|
|
41
|
-
*
|
|
42
|
-
* Renders a form for a entity collection without any admin or backend dependencies.
|
|
43
|
-
* All backend concerns (save, caching, analytics, plugin slots) are provided via
|
|
44
|
-
* callback props. For admin-connected usage, use {@link EntityFormBinding} instead.
|
|
45
|
-
*
|
|
46
|
-
* @group Components
|
|
47
|
-
*/
|
|
48
|
-
export function EntityForm<M extends Record<string, unknown>>({
|
|
49
|
-
path,
|
|
50
|
-
entityId: entityIdProp,
|
|
51
|
-
collection,
|
|
52
|
-
onValuesModified,
|
|
53
|
-
onIdChange,
|
|
54
|
-
onSaved,
|
|
55
|
-
entity,
|
|
56
|
-
initialDirtyValues,
|
|
57
|
-
onFormContextReady,
|
|
58
|
-
initialStatus,
|
|
59
|
-
className,
|
|
60
|
-
onStatusChange,
|
|
61
|
-
onEntityChange,
|
|
62
|
-
openEntityMode = "full_screen",
|
|
63
|
-
formex: formexProp,
|
|
64
|
-
disabled: disabledProp,
|
|
65
|
-
Builder,
|
|
66
|
-
EntityFormActionsComponent = EntityFormActions,
|
|
67
|
-
showDefaultActions = true,
|
|
68
|
-
navigateBack: navigateBackProp,
|
|
69
|
-
children,
|
|
70
|
-
// Headless callback props
|
|
71
|
-
onSubmit: onSubmitProp,
|
|
72
|
-
onValuesChangeDeferred: onValuesChangeDeferredProp,
|
|
73
|
-
onReset: onResetProp,
|
|
74
|
-
uniqueFieldValidator: uniqueFieldValidatorProp,
|
|
75
|
-
// Slots
|
|
76
|
-
beforeFields,
|
|
77
|
-
afterFields,
|
|
78
|
-
pluginActions: pluginActionsProp,
|
|
79
|
-
// Local changes (managed externally)
|
|
80
|
-
computedInitialValues,
|
|
81
|
-
hasLocalChanges: hasLocalChangesProp,
|
|
82
|
-
localChangesData,
|
|
83
|
-
manualApplyLocalChanges,
|
|
84
|
-
localChangesCacheKey,
|
|
85
|
-
onClearLocalChanges
|
|
86
|
-
}: EntityFormProps<M>) {
|
|
87
|
-
|
|
88
|
-
const navigateBack = useCallback(() => {
|
|
89
|
-
if (navigateBackProp) {
|
|
90
|
-
navigateBackProp();
|
|
91
|
-
}
|
|
92
|
-
}, [navigateBackProp]);
|
|
93
|
-
|
|
94
|
-
const [status, setStatus] = useState<EntityStatus>(initialStatus);
|
|
95
|
-
|
|
96
|
-
const updateStatus = (status: EntityStatus) => {
|
|
97
|
-
setStatus(status);
|
|
98
|
-
onStatusChange?.(status);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
const [valuesToBeSaved, setValuesToBeSaved] = useState<EntityValues<M> | undefined>(undefined);
|
|
102
|
-
useDebouncedCallback(valuesToBeSaved, () => {
|
|
103
|
-
if (valuesToBeSaved && onSubmitProp) {
|
|
104
|
-
setIsSavingAutoSave(true);
|
|
105
|
-
Promise.resolve(onSubmitProp(valuesToBeSaved, formex))
|
|
106
|
-
.finally(() => setIsSavingAutoSave(false));
|
|
107
|
-
}
|
|
108
|
-
}, false, 2000);
|
|
109
|
-
|
|
110
|
-
const [underlyingChanges] = useState<Partial<EntityValues<M>>>({});
|
|
111
|
-
|
|
112
|
-
const initialEntityId: string | number | undefined = useMemo(() => {
|
|
113
|
-
if (status === "new" || status === "copy") {
|
|
114
|
-
return undefined;
|
|
115
|
-
} else {
|
|
116
|
-
return entityIdProp;
|
|
117
|
-
}
|
|
118
|
-
}, [entityIdProp, status]);
|
|
119
|
-
|
|
120
|
-
const [entityId, setEntityId] = useState<string | number | undefined>(initialEntityId);
|
|
121
|
-
const [savingError, setSavingError] = useState<Error | undefined>();
|
|
122
|
-
const [isSavingAutoSave, setIsSavingAutoSave] = useState<boolean>(false);
|
|
123
|
-
const [discardDialogOpen, setDiscardDialogOpen] = useState<boolean>(false);
|
|
124
|
-
|
|
125
|
-
const discard = useUndoableDiscard();
|
|
126
|
-
|
|
127
|
-
const autoSave = collection.formAutoSave;
|
|
128
|
-
|
|
129
|
-
// Use externally computed initial values if provided, otherwise compute from entity + collection
|
|
130
|
-
const baseInitialValues = useMemo(() => {
|
|
131
|
-
if (computedInitialValues !== undefined) {
|
|
132
|
-
return computedInitialValues;
|
|
133
|
-
}
|
|
134
|
-
// Fallback: compute from entity/collection (requires authController from context)
|
|
135
|
-
// In headless mode without computedInitialValues, use entity values or defaults
|
|
136
|
-
if ((status === "existing" || status === "copy") && entity) {
|
|
137
|
-
return entity.values ?? getDefaultValuesFor(collection.properties);
|
|
138
|
-
}
|
|
139
|
-
return getDefaultValuesFor(collection.properties);
|
|
140
|
-
}, [computedInitialValues, collection.properties, status, entity]);
|
|
141
|
-
|
|
142
|
-
const [localChangesCleared, setLocalChangesCleared] = useState<boolean>(false);
|
|
143
|
-
|
|
144
|
-
const hasLocalChanges = hasLocalChangesProp !== undefined
|
|
145
|
-
? (hasLocalChangesProp && !localChangesCleared)
|
|
146
|
-
: false;
|
|
147
|
-
|
|
148
|
-
const onSubmit = (values: EntityValues<M>, formexController: FormexController<EntityValues<M>>) => {
|
|
149
|
-
|
|
150
|
-
setSavingError(undefined);
|
|
151
|
-
|
|
152
|
-
if (status === "existing") {
|
|
153
|
-
if (!entity?.id) throw Error("Form misconfiguration when saving, no id for existing entity");
|
|
154
|
-
} else if (status !== "new" && status !== "copy") {
|
|
155
|
-
throw Error("New FormType added, check EntityForm");
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (!onSubmitProp) {
|
|
159
|
-
console.warn("EntityForm: no onSubmit callback provided. Form submission has no effect.");
|
|
160
|
-
formexController.setSubmitting(false);
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return Promise.resolve(save(values))
|
|
165
|
-
?.then((savedEntity) => {
|
|
166
|
-
if (savedEntity) {
|
|
167
|
-
formexController.resetForm({
|
|
168
|
-
values: savedEntity.values || values,
|
|
169
|
-
submitCount: 0,
|
|
170
|
-
touched: {}
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
})
|
|
174
|
-
.finally(() => {
|
|
175
|
-
formexController.setSubmitting(false);
|
|
176
|
-
});
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* What the form opens showing, when that is not what is stored — an edit
|
|
181
|
-
* carried over from the side panel's "open full screen", or a draft
|
|
182
|
-
* restored from the local-changes backup.
|
|
183
|
-
*
|
|
184
|
-
* The merge is deliberately *not* folded into the baseline. `mergeDeep`
|
|
185
|
-
* used to produce a single `initialValues` that served as both, with a
|
|
186
|
-
* `initialDirty: true` bolted on beside it to say what the baseline could
|
|
187
|
-
* no longer show — and that flag survived exactly one render, because the
|
|
188
|
-
* record's data arriving replaced the baseline and the form recomputed
|
|
189
|
-
* dirty as false against a baseline that already contained the edit.
|
|
190
|
-
*
|
|
191
|
-
* Read once, at mount: this is a handoff, and re-reading it every render
|
|
192
|
-
* tied the form to a cache that is cleared as soon as it has been consumed.
|
|
193
|
-
*/
|
|
194
|
-
const initialModifiedValues = useRef(
|
|
195
|
-
initialDirtyValues && Object.keys(initialDirtyValues).length > 0
|
|
196
|
-
? mergeDeep(baseInitialValues, initialDirtyValues)
|
|
197
|
-
: undefined
|
|
198
|
-
).current;
|
|
199
|
-
|
|
200
|
-
const internalFormex = useCreateFormex<M>({
|
|
201
|
-
initialValues: baseInitialValues as M,
|
|
202
|
-
initialModifiedValues: initialModifiedValues as M | undefined,
|
|
203
|
-
debugId: `EntityForm:${path}/${entityIdProp}`,
|
|
204
|
-
initialTouched: initialDirtyValues ?
|
|
205
|
-
flattenKeys(initialDirtyValues!)
|
|
206
|
-
.reduce((previousValue, currentValue) => ({
|
|
207
|
-
...previousValue,
|
|
208
|
-
[currentValue]: true
|
|
209
|
-
}), {})
|
|
210
|
-
: {},
|
|
211
|
-
onSubmit,
|
|
212
|
-
onReset: () => {
|
|
213
|
-
onResetProp?.();
|
|
214
|
-
// The stored values — a reset returns the form to them, and by now
|
|
215
|
-
// that is the baseline whether or not it was at mount.
|
|
216
|
-
onValuesModified?.(false, baseInitialValues as M);
|
|
217
|
-
},
|
|
218
|
-
onValuesChangeDeferred: onValuesChangeDeferredProp,
|
|
219
|
-
validation: async (values): Promise<Record<string, string>> => {
|
|
220
|
-
if (!validationSchema) return {};
|
|
221
|
-
const result = await validationSchema.safeParseAsync(values);
|
|
222
|
-
if (result.success) return {};
|
|
223
|
-
return zodToFormErrors(result.error);
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
const formex: FormexController<M> = formexProp ?? internalFormex;
|
|
227
|
-
|
|
228
|
-
useEffect(() => {
|
|
229
|
-
|
|
230
|
-
const handleKeyDown = (e: KeyboardEvent) => {
|
|
231
|
-
const isUndo = (e.metaKey || e.ctrlKey) && !e.shiftKey && e.key.toLowerCase() === "z";
|
|
232
|
-
const isRedo =
|
|
233
|
-
((e.metaKey || e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === "z") ||
|
|
234
|
-
((e.metaKey || e.ctrlKey) && !e.shiftKey && e.key.toLowerCase() === "y");
|
|
235
|
-
const isSave = (e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "s";
|
|
236
|
-
|
|
237
|
-
if (isSave && !disabled && formex.dirty) {
|
|
238
|
-
e.preventDefault();
|
|
239
|
-
formex.handleSubmit();
|
|
240
|
-
} else if (isUndo && formex.canUndo) {
|
|
241
|
-
e.preventDefault();
|
|
242
|
-
formex.undo();
|
|
243
|
-
} else if (isRedo && formex.canRedo) {
|
|
244
|
-
e.preventDefault();
|
|
245
|
-
formex.redo();
|
|
246
|
-
}
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
250
|
-
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
251
|
-
|
|
252
|
-
}, [formex]);
|
|
253
|
-
|
|
254
|
-
const afterSave = (updatedEntity: Entity<M>) => {
|
|
255
|
-
onResetProp?.();
|
|
256
|
-
onValuesModified?.(false, updatedEntity.values);
|
|
257
|
-
onEntityChange?.(updatedEntity);
|
|
258
|
-
updateStatus("existing");
|
|
259
|
-
setEntityId(updatedEntity.id);
|
|
260
|
-
|
|
261
|
-
if (onSaved) {
|
|
262
|
-
onSaved({
|
|
263
|
-
entity: updatedEntity,
|
|
264
|
-
status,
|
|
265
|
-
path,
|
|
266
|
-
entityId: updatedEntity.id,
|
|
267
|
-
collection
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
const lastSavedValues = useRef<EntityValues<M> | undefined>(entity?.values);
|
|
273
|
-
const save = async (values: EntityValues<M>): Promise<Entity<M> | void> => {
|
|
274
|
-
const valuesToSave = status === "existing"
|
|
275
|
-
? getChanges(values, entity?.values || {}) as EntityValues<M>
|
|
276
|
-
: values;
|
|
277
|
-
|
|
278
|
-
if (status === "existing" && Object.keys(valuesToSave).length === 0 && entity) {
|
|
279
|
-
return Promise.resolve(entity);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
lastSavedValues.current = values;
|
|
283
|
-
|
|
284
|
-
if (!onSubmitProp) {
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const autoSaveEnabled = autoSave ?? false;
|
|
289
|
-
|
|
290
|
-
if (autoSaveEnabled) {
|
|
291
|
-
setValuesToBeSaved(values);
|
|
292
|
-
return Promise.resolve();
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return Promise.resolve(onSubmitProp(valuesToSave as M, formex))
|
|
296
|
-
.then((result) => {
|
|
297
|
-
if (result) {
|
|
298
|
-
afterSave(result as Entity<M>);
|
|
299
|
-
}
|
|
300
|
-
return result as Entity<M> | void;
|
|
301
|
-
})
|
|
302
|
-
.catch(e => {
|
|
303
|
-
console.error(e);
|
|
304
|
-
setSavingError(e);
|
|
305
|
-
});
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
const disabled = formex.isSubmitting || Boolean(disabledProp);
|
|
309
|
-
|
|
310
|
-
const formContext: FormContext<M> = {
|
|
311
|
-
setFieldValue: useCallback((key: string, value: unknown) => formex.setFieldValue(key, value), []),
|
|
312
|
-
values: formex.values,
|
|
313
|
-
collection,
|
|
314
|
-
entityId: entityId as string,
|
|
315
|
-
path,
|
|
316
|
-
save,
|
|
317
|
-
submit: formex.handleSubmit,
|
|
318
|
-
formex,
|
|
319
|
-
entity,
|
|
320
|
-
savingError,
|
|
321
|
-
status,
|
|
322
|
-
openEntityMode,
|
|
323
|
-
disabled,
|
|
324
|
-
isSaving: formex.isSubmitting || isSavingAutoSave
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
useEffect(() => {
|
|
328
|
-
onFormContextReady?.(formContext);
|
|
329
|
-
// `formex.version` only moves on `resetForm`, so these deps used to hand
|
|
330
|
-
// the container one snapshot at mount and never another. That was
|
|
331
|
-
// invisible while Save lived inside the form and read `formex` directly;
|
|
332
|
-
// once the identity bar owned Save, its `dirty` was frozen false and the
|
|
333
|
-
// button never enabled — for any field, not just the one that exposed
|
|
334
|
-
// it. Custom entity views read `formContext.values` through the same
|
|
335
|
-
// channel and were reading a stale copy too.
|
|
336
|
-
//
|
|
337
|
-
// Deps are the state *transitions* a container cares about, not
|
|
338
|
-
// `formex.values`: re-publishing on every keystroke would re-render the
|
|
339
|
-
// whole entity view per character.
|
|
340
|
-
}, [
|
|
341
|
-
formex.version, collection, entityId, path,
|
|
342
|
-
formex.dirty, formex.isSubmitting, formex.submitCount, isSavingAutoSave
|
|
343
|
-
]);
|
|
344
|
-
|
|
345
|
-
const actionsDisabled = disabled || formex.isSubmitting || (status === "existing" && !formex.dirty) || Boolean(disabledProp);
|
|
346
|
-
|
|
347
|
-
// The record's title is resolved by the container that renders the identity
|
|
348
|
-
// bar (see `useEntityDisplayTitle`), not here — the form no longer draws a
|
|
349
|
-
// heading of its own.
|
|
350
|
-
|
|
351
|
-
const modified = formex.dirty;
|
|
352
|
-
|
|
353
|
-
useEffect(() => {
|
|
354
|
-
if (!autoSave) {
|
|
355
|
-
onValuesModified?.(modified, formex.values);
|
|
356
|
-
}
|
|
357
|
-
}, [formex.dirty]);
|
|
358
|
-
|
|
359
|
-
// Default no-op unique field validator — always passes
|
|
360
|
-
const defaultUniqueFieldValidator: CustomFieldValidator = useCallback(async () => true, []);
|
|
361
|
-
|
|
362
|
-
const uniqueFieldValidator: CustomFieldValidator = useMemo(() => {
|
|
363
|
-
if (uniqueFieldValidatorProp) {
|
|
364
|
-
return uniqueFieldValidatorProp as CustomFieldValidator;
|
|
365
|
-
}
|
|
366
|
-
return defaultUniqueFieldValidator;
|
|
367
|
-
}, [uniqueFieldValidatorProp, defaultUniqueFieldValidator]);
|
|
368
|
-
|
|
369
|
-
const validationSchema = useMemo(() => getEntitySchema(
|
|
370
|
-
entityId,
|
|
371
|
-
collection.properties,
|
|
372
|
-
uniqueFieldValidator),
|
|
373
|
-
[entityId, collection.properties, uniqueFieldValidator]);
|
|
374
|
-
|
|
375
|
-
useOnAutoSave(autoSave, formex, lastSavedValues, save);
|
|
376
|
-
|
|
377
|
-
useEffect(() => {
|
|
378
|
-
if (!autoSave && !formex.isSubmitting && underlyingChanges && entity) {
|
|
379
|
-
// we update the form fields from the driver data
|
|
380
|
-
// if they were not touched
|
|
381
|
-
Object.entries(underlyingChanges).forEach(([key, value]) => {
|
|
382
|
-
const formValue = formex.values[key];
|
|
383
|
-
if (!equal(value, formValue) && !formex.touched[key]) {
|
|
384
|
-
console.debug("Updated value from the driver:", key, value);
|
|
385
|
-
formex.setFieldValue(key, value !== undefined ? value : null);
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
}, [formex.isSubmitting, autoSave, underlyingChanges, entity, formex.values, formex.touched, formex.setFieldValue]);
|
|
390
|
-
|
|
391
|
-
const formFieldKeys = getFormFieldKeys(collection);
|
|
392
|
-
|
|
393
|
-
const layout = useMemo(() => resolveFormLayout({
|
|
394
|
-
collection,
|
|
395
|
-
fieldKeys: formFieldKeys,
|
|
396
|
-
status
|
|
397
|
-
}), [collection, formFieldKeys.join(","), status]);
|
|
398
|
-
|
|
399
|
-
const formElementRef = useRef<HTMLFormElement>(null);
|
|
400
|
-
// Measured, not a breakpoint: the rail holds fields the resolver moved
|
|
401
|
-
// out of the column, so when it cannot be shown they have to come back.
|
|
402
|
-
const railVisible = useRailVisible(formElementRef);
|
|
403
|
-
const showRail = !Builder && layout.hasRail && railVisible;
|
|
404
|
-
|
|
405
|
-
// Collapsed sections are per-section-key so a renamed title keeps its state,
|
|
406
|
-
// and initial state comes from the config rather than being forced open.
|
|
407
|
-
const [collapsedSections, setCollapsedSections] = useState<Set<string>>(
|
|
408
|
-
() => new Set(layout.sections.filter(s => s.collapsed).map(s => s.key))
|
|
409
|
-
);
|
|
410
|
-
const toggleSection = useCallback((key: string) => {
|
|
411
|
-
setCollapsedSections(prev => {
|
|
412
|
-
const next = new Set(prev);
|
|
413
|
-
if (next.has(key)) next.delete(key); else next.add(key);
|
|
414
|
-
return next;
|
|
415
|
-
});
|
|
416
|
-
}, []);
|
|
417
|
-
|
|
418
|
-
const errorKeys = useMemo(
|
|
419
|
-
() => new Set(formex.submitCount > 0 ? Object.keys(formex.errors) : []),
|
|
420
|
-
[formex.errors, formex.submitCount]
|
|
421
|
-
);
|
|
422
|
-
|
|
423
|
-
// Autofocus lands on the first field the user can actually type into. Tracked
|
|
424
|
-
// across the whole layout rather than per section, so a collapsed leading
|
|
425
|
-
// group does not steal it.
|
|
426
|
-
const autoFocusKey = useMemo(() => {
|
|
427
|
-
if (status !== "new" && status !== "copy") return undefined;
|
|
428
|
-
const ordered = [...layout.sections.flatMap(s => s.fields), ...layout.sidebar];
|
|
429
|
-
return ordered.find(field => {
|
|
430
|
-
const property = collection.properties?.[field.key];
|
|
431
|
-
return property ? !isFieldDisabled(property) : false;
|
|
432
|
-
})?.key;
|
|
433
|
-
}, [layout, collection, status, disabledProp]);
|
|
434
|
-
|
|
435
|
-
function isFieldDisabled(property: NonNullable<typeof collection.properties[string]>): boolean {
|
|
436
|
-
const isNew = status === "new" || status === "copy";
|
|
437
|
-
const isStringOrNumber = property.type === "string" || property.type === "number";
|
|
438
|
-
const isIdAndAuto = isStringOrNumber && "isId" in property && typeof property.isId === "string" && property.isId !== "manual";
|
|
439
|
-
return Boolean(
|
|
440
|
-
disabledProp
|
|
441
|
-
|| (!autoSave && formex.isSubmitting)
|
|
442
|
-
|| isReadOnly(property)
|
|
443
|
-
|| isDisabled(property)
|
|
444
|
-
|| (!isNew && "isId" in property && Boolean(property.isId))
|
|
445
|
-
|| (isNew && isIdAndAuto)
|
|
446
|
-
);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
const renderField = (field: ResolvedFormField): React.ReactNode => {
|
|
450
|
-
|
|
451
|
-
if (field.additional) {
|
|
452
|
-
const additionalField = collection.additionalFields?.find(f => f.key === field.key);
|
|
453
|
-
if (!additionalField || !entity) return null;
|
|
454
|
-
|
|
455
|
-
const AdditionalFieldBuilder = additionalField.Builder;
|
|
456
|
-
if (!AdditionalFieldBuilder && !additionalField.value) {
|
|
457
|
-
throw new Error("When using additional fields you need to provide a Builder or a value");
|
|
458
|
-
}
|
|
459
|
-
const additionalFieldContext = formContext as unknown as AdditionalFieldDelegateProps["context"];
|
|
460
|
-
const child = AdditionalFieldBuilder
|
|
461
|
-
? <AdditionalFieldBuilder entity={entity} context={additionalFieldContext}/>
|
|
462
|
-
: <div className={"w-full"}>
|
|
463
|
-
<AdditionalFieldValue
|
|
464
|
-
field={additionalField}
|
|
465
|
-
entity={entity}
|
|
466
|
-
context={additionalFieldContext}/>
|
|
467
|
-
</div>;
|
|
468
|
-
|
|
469
|
-
return (
|
|
470
|
-
// Through FieldBlock like every other cell, so a computed
|
|
471
|
-
// column is labelled at the same size, with the same gap to its
|
|
472
|
-
// box, as the property next to it on the grid.
|
|
473
|
-
<div key={`additional_${field.key}`}
|
|
474
|
-
className={spanClass(field.span)}>
|
|
475
|
-
<FieldBlock propertyKey={field.key}
|
|
476
|
-
showLabel={true}
|
|
477
|
-
label={additionalField.name}
|
|
478
|
-
icon={<AlignLeftIcon size={LABEL_ICON_SIZE}/>}>
|
|
479
|
-
<div className={cls(paperMixin, "w-full min-h-12 p-4 md:p-6 overflow-x-auto no-scrollbar")}>
|
|
480
|
-
{child}
|
|
481
|
-
</div>
|
|
482
|
-
</FieldBlock>
|
|
483
|
-
</div>
|
|
484
|
-
);
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
const property = collection.properties?.[field.key];
|
|
488
|
-
if (!property) {
|
|
489
|
-
console.warn(`Property ${field.key} not found in collection ${collection.name} in properties or additional fields. Skipping.`);
|
|
490
|
-
return null;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
const underlyingValueHasChanged: boolean =
|
|
494
|
-
!!underlyingChanges &&
|
|
495
|
-
Object.keys(underlyingChanges).includes(field.key) &&
|
|
496
|
-
formex.touched[field.key];
|
|
497
|
-
|
|
498
|
-
const disabled = isFieldDisabled(property);
|
|
499
|
-
// The panel-style editors carry their own header; everything else is
|
|
500
|
-
// labelled by FieldBlock, which is what puts every label in one place.
|
|
501
|
-
const selfLabelling = isSelfLabellingProperty(property);
|
|
502
|
-
|
|
503
|
-
const cmsFormFieldProps: PropertyFieldBindingProps<M> = {
|
|
504
|
-
propertyKey: field.key,
|
|
505
|
-
disabled,
|
|
506
|
-
property,
|
|
507
|
-
// FieldBlock owns the description now, so the binding must not
|
|
508
|
-
// repeat it — it still renders validation errors, which belong
|
|
509
|
-
// against the control rather than under the label.
|
|
510
|
-
includeDescription: false,
|
|
511
|
-
hideLabel: !selfLabelling,
|
|
512
|
-
underlyingValueHasChanged: underlyingValueHasChanged && !autoSave,
|
|
513
|
-
context: formContext,
|
|
514
|
-
partOfArray: false,
|
|
515
|
-
minimalistView: false,
|
|
516
|
-
// One height for every control in the form. Left to their own
|
|
517
|
-
// defaults, a text field came out 48px, a select 44 and a switch 64.
|
|
518
|
-
size: "large",
|
|
519
|
-
autoFocus: autoFocusKey === field.key
|
|
520
|
-
};
|
|
521
|
-
|
|
522
|
-
return (
|
|
523
|
-
<div key={`field_${field.key}`} className={spanClass(field.span)}>
|
|
524
|
-
<FieldBlock propertyKey={field.key}
|
|
525
|
-
property={property}
|
|
526
|
-
showLabel={!selfLabelling}>
|
|
527
|
-
<PropertyFieldBinding {...cmsFormFieldProps}/>
|
|
528
|
-
</FieldBlock>
|
|
529
|
-
</div>
|
|
530
|
-
);
|
|
531
|
-
};
|
|
532
|
-
|
|
533
|
-
const formFields = () => {
|
|
534
|
-
|
|
535
|
-
if (Builder) {
|
|
536
|
-
return <Builder
|
|
537
|
-
collection={collection}
|
|
538
|
-
entity={entity}
|
|
539
|
-
modifiedValues={formex.values}
|
|
540
|
-
formContext={formContext}
|
|
541
|
-
/>;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
const sections = showRail || !layout.sidebar.length
|
|
545
|
-
? layout.sections
|
|
546
|
-
: [
|
|
547
|
-
...layout.sections,
|
|
548
|
-
// Trailing, not leading. Beside the column these read as
|
|
549
|
-
// peripheral; stacked above it they pushed the record's own name
|
|
550
|
-
// below its status, which is the wrong thing to meet first.
|
|
551
|
-
// Settings come after the content they apply to.
|
|
552
|
-
{
|
|
553
|
-
key: "__rail",
|
|
554
|
-
title: "Settings",
|
|
555
|
-
collapsible: false,
|
|
556
|
-
collapsed: false,
|
|
557
|
-
fields: layout.sidebar
|
|
558
|
-
}
|
|
559
|
-
];
|
|
560
|
-
|
|
561
|
-
return <>
|
|
562
|
-
<FormSections
|
|
563
|
-
sections={sections}
|
|
564
|
-
collapsed={collapsedSections}
|
|
565
|
-
onToggle={toggleSection}
|
|
566
|
-
errorKeys={errorKeys}
|
|
567
|
-
renderField={renderField}/>
|
|
568
|
-
|
|
569
|
-
{/* Folded back with the rail's fields, and for the same reason. The
|
|
570
|
-
rail renders only where it has been measured to fit, so on the
|
|
571
|
-
split pane, the side panel and the dialog this block was dropped
|
|
572
|
-
outright and the record's id was nowhere on screen but the
|
|
573
|
-
truncated chip in the bar. */}
|
|
574
|
-
{!showRail && layout.showRecordMeta && status === "existing" && entity && (
|
|
575
|
-
<div className={cls("mt-8 pt-5 border-t max-w-sm", defaultBorderMixin)}>
|
|
576
|
-
<RecordMeta entity={entity as Entity<Record<string, unknown>>}/>
|
|
577
|
-
</div>
|
|
578
|
-
)}
|
|
579
|
-
</>;
|
|
580
|
-
};
|
|
581
|
-
|
|
582
|
-
const formRef = useRef<HTMLDivElement>(null);
|
|
583
|
-
|
|
584
|
-
const hasFormErrors = Object.keys(formex.errors).length > 0 && formex.submitCount > 0;
|
|
585
|
-
|
|
586
|
-
const formView = <ErrorBoundary>
|
|
587
|
-
<>
|
|
588
|
-
{beforeFields}
|
|
589
|
-
|
|
590
|
-
{/* The title, the `path/id` chip and the 72px gap under them used to
|
|
591
|
-
live here — 219px above the first field, carrying nothing, and
|
|
592
|
-
scrolling the record's identity away on the first wheel click.
|
|
593
|
-
It is now in the persistent bar, where it stays put. */}
|
|
594
|
-
|
|
595
|
-
{!entity?.values && initialStatus === "existing" &&
|
|
596
|
-
<Alert color={"warning"} size={"small"} outerClassName={"w-full mb-4 text-xs"}>
|
|
597
|
-
This entity does not exist yet
|
|
598
|
-
</Alert>}
|
|
599
|
-
|
|
600
|
-
{children}
|
|
601
|
-
|
|
602
|
-
{initialEntityId && !entity && initialStatus !== "new" && <Alert color={"info"} size={"small"}>
|
|
603
|
-
This entity does not exist yet
|
|
604
|
-
</Alert>}
|
|
605
|
-
|
|
606
|
-
{hasFormErrors && <Alert color={"error"} size={"small"} outerClassName={"w-full mt-2"}>
|
|
607
|
-
Please fix the highlighted errors before saving.
|
|
608
|
-
</Alert>}
|
|
609
|
-
|
|
610
|
-
{formContext && <>
|
|
611
|
-
<div ref={formRef}>
|
|
612
|
-
{formFields()}
|
|
613
|
-
<ErrorFocus containerRef={formRef}/>
|
|
614
|
-
</div>
|
|
615
|
-
</>}
|
|
616
|
-
|
|
617
|
-
{afterFields}
|
|
618
|
-
|
|
619
|
-
<Dialog open={discardDialogOpen} onOpenChange={setDiscardDialogOpen} maxWidth={"sm"}>
|
|
620
|
-
<DialogTitle>{status === "existing" ? "Discard changes?" : "Clear form?"}</DialogTitle>
|
|
621
|
-
<DialogContent>
|
|
622
|
-
<Typography>
|
|
623
|
-
{status === "existing"
|
|
624
|
-
? "All unsaved changes will be lost. "
|
|
625
|
-
: "All entered values will be cleared. "}
|
|
626
|
-
You can bring them back with Undo (⌘Z / Ctrl+Z), or from
|
|
627
|
-
the notification, for as long as this form stays open.
|
|
628
|
-
</Typography>
|
|
629
|
-
</DialogContent>
|
|
630
|
-
<DialogActions>
|
|
631
|
-
<Button variant={"text"} onClick={() => setDiscardDialogOpen(false)}>
|
|
632
|
-
Cancel
|
|
633
|
-
</Button>
|
|
634
|
-
<Button variant={"filled"} color={"error"} onClick={() => {
|
|
635
|
-
setDiscardDialogOpen(false);
|
|
636
|
-
discard(formex, status, baseInitialValues);
|
|
637
|
-
}}>
|
|
638
|
-
{status === "existing" ? "Discard" : "Clear"}
|
|
639
|
-
</Button>
|
|
640
|
-
</DialogActions>
|
|
641
|
-
</Dialog>
|
|
642
|
-
</>
|
|
643
|
-
</ErrorBoundary>;
|
|
644
|
-
|
|
645
|
-
useEffect(() => {
|
|
646
|
-
if (entityId && onIdChange)
|
|
647
|
-
onIdChange(entityId);
|
|
648
|
-
}, [entityId, onIdChange]);
|
|
649
|
-
|
|
650
|
-
if (!collection || !path) {
|
|
651
|
-
throw Error("INTERNAL: Collection and path must be defined in form context");
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
const EntityFormActionsRender = EntityFormActionsComponent as React.FC<EntityFormActionsProps>;
|
|
655
|
-
|
|
656
|
-
const dialogActions = <EntityFormActionsRender
|
|
657
|
-
collection={collection}
|
|
658
|
-
path={path}
|
|
659
|
-
entity={entity}
|
|
660
|
-
savingError={savingError}
|
|
661
|
-
formex={formex as FormexController<Record<string, unknown>>}
|
|
662
|
-
disabled={actionsDisabled}
|
|
663
|
-
status={status}
|
|
664
|
-
pluginActions={pluginActionsProp ?? []}
|
|
665
|
-
openEntityMode={openEntityMode}
|
|
666
|
-
showDefaultActions={showDefaultActions}
|
|
667
|
-
navigateBack={navigateBack}
|
|
668
|
-
formContext={formContext as FormContext<Record<string, unknown>>}
|
|
669
|
-
/>;
|
|
670
|
-
|
|
671
|
-
return (
|
|
672
|
-
<Formex value={formex}>
|
|
673
|
-
<form
|
|
674
|
-
ref={formElementRef}
|
|
675
|
-
onSubmit={formex.handleSubmit}
|
|
676
|
-
onReset={(e) => {
|
|
677
|
-
e.preventDefault();
|
|
678
|
-
if (formex.dirty) {
|
|
679
|
-
setDiscardDialogOpen(true);
|
|
680
|
-
} else {
|
|
681
|
-
formex.resetForm({ values: baseInitialValues as M });
|
|
682
|
-
}
|
|
683
|
-
}}
|
|
684
|
-
noValidate
|
|
685
|
-
className={cls("@container/form flex-1 flex flex-col w-full min-h-0", className)}>
|
|
686
|
-
|
|
687
|
-
{/* The actions bar is a sibling of this row rather than absolutely
|
|
688
|
-
positioned over it, so the scroll area ends where the bar
|
|
689
|
-
begins. As an overlay it hid the last field, and the bottom
|
|
690
|
-
padding that compensated was a guess at its height. */}
|
|
691
|
-
<div className={"flex-1 min-h-0 flex flex-row w-full"}>
|
|
692
|
-
|
|
693
|
-
{/* Main column. Its own container scope, so a field's span
|
|
694
|
-
answers to the column it sits in rather than to the window —
|
|
695
|
-
the same form renders at four very different widths. */}
|
|
696
|
-
{/* `items-start`: the column is a flex item, so without it the cross-axis
|
|
697
|
-
default stretches it to the scroller's height. Its content then
|
|
698
|
-
overflows its own box and the bottom padding sits at the bottom of
|
|
699
|
-
the *viewport* instead of after the last field — which is why the
|
|
700
|
-
form appeared to have no padding however large `pb-*` grew. */}
|
|
701
|
-
<div className={"flex-1 min-w-0 overflow-y-auto flex justify-center items-start"}>
|
|
702
|
-
<div
|
|
703
|
-
id={`form_${path}`}
|
|
704
|
-
className={cls(
|
|
705
|
-
// Two rules widen the column, and they answer to
|
|
706
|
-
// different things on purpose. `@7xl/form` measures
|
|
707
|
-
// the form itself: full screen on a laptop is ~1400px
|
|
708
|
-
// of form, which after the 304px rail leaves room for
|
|
709
|
-
// the wider column with real gutters either side — and
|
|
710
|
-
// it stays 768 in the split pane and the side panel,
|
|
711
|
-
// which never get that wide. `2xl` is the older
|
|
712
|
-
// viewport rule, kept so a panel on a large monitor
|
|
713
|
-
// does not get *narrower* than it is today.
|
|
714
|
-
"@container/col w-full max-w-3xl @7xl/form:max-w-4xl 2xl:max-w-4xl flex flex-col",
|
|
715
|
-
openEntityMode === "dialog"
|
|
716
|
-
? "pt-5 pb-8 px-6 sm:px-8"
|
|
717
|
-
: "pt-6 pb-12 px-5 sm:px-8"
|
|
718
|
-
)}>
|
|
719
|
-
|
|
720
|
-
{manualApplyLocalChanges && hasLocalChanges && localChangesCacheKey &&
|
|
721
|
-
<div className={"flex justify-end mb-3"}>
|
|
722
|
-
<LocalChangesMenu<M>
|
|
723
|
-
cacheKey={localChangesCacheKey}
|
|
724
|
-
properties={collection.properties}
|
|
725
|
-
cachedData={localChangesData as Partial<M>}
|
|
726
|
-
formex={formex}
|
|
727
|
-
onClearLocalChanges={() => {
|
|
728
|
-
setLocalChangesCleared(true);
|
|
729
|
-
onClearLocalChanges?.();
|
|
730
|
-
}}
|
|
731
|
-
/>
|
|
732
|
-
</div>}
|
|
733
|
-
|
|
734
|
-
{formView}
|
|
735
|
-
|
|
736
|
-
</div>
|
|
737
|
-
</div>
|
|
738
|
-
|
|
739
|
-
{showRail && <FormRail
|
|
740
|
-
fields={layout.sidebar}
|
|
741
|
-
showRecordMeta={layout.showRecordMeta && status === "existing"}
|
|
742
|
-
entity={entity as Entity<Record<string, unknown>> | undefined}
|
|
743
|
-
renderField={renderField}/>}
|
|
744
|
-
</div>
|
|
745
|
-
|
|
746
|
-
{dialogActions}
|
|
747
|
-
|
|
748
|
-
</form>
|
|
749
|
-
|
|
750
|
-
</Formex>
|
|
751
|
-
);
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
function useOnAutoSave<M extends Record<string, unknown>>(autoSave: undefined | boolean, formex: FormexController<M>, lastSavedValues: React.MutableRefObject<EntityValues<M> | undefined>, save: (values: EntityValues<M>) => Promise<Entity<M> | void>) {
|
|
755
|
-
useEffect(() => {
|
|
756
|
-
if (!autoSave) return;
|
|
757
|
-
if (formex.values && !equal(formex.values, lastSavedValues.current)) {
|
|
758
|
-
save(formex.values);
|
|
759
|
-
}
|
|
760
|
-
}, [autoSave, formex.values]);
|
|
761
|
-
}
|