@firecms/core 3.0.0 → 3.1.0-canary.02232f4
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 +1 -1
- package/dist/components/AIIcon.d.ts +16 -0
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +7 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +14 -0
- package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +6 -0
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +5 -4
- package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +6 -0
- package/dist/components/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +2 -2
- package/dist/components/EntityCollectionView/Board.d.ts +2 -0
- package/dist/components/EntityCollectionView/BoardColumn.d.ts +42 -0
- package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +9 -0
- package/dist/components/EntityCollectionView/BoardSortableList.d.ts +14 -0
- package/dist/components/EntityCollectionView/CollectionDataErrorBanner.d.ts +4 -0
- package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +26 -0
- package/dist/components/EntityCollectionView/EntityCard.d.ts +19 -0
- package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +20 -0
- package/dist/components/EntityCollectionView/EntityCollectionCardView.d.ts +31 -0
- package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +2 -2
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +7 -3
- package/dist/components/EntityCollectionView/FiltersDialog.d.ts +14 -0
- package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +44 -0
- package/dist/components/EntityCollectionView/board_types.d.ts +105 -0
- package/dist/components/EntityCollectionView/useBoardDataController.d.ts +60 -0
- package/dist/components/ErrorBoundary.d.ts +4 -2
- package/dist/components/HomePage/DefaultHomePage.d.ts +0 -1
- package/dist/components/LanguageToggle.d.ts +1 -0
- package/dist/components/SelectableTable/SelectableTable.d.ts +5 -1
- package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +2 -1
- package/dist/components/UnsavedChangesDialog.d.ts +1 -0
- package/dist/components/VirtualTable/VirtualTable.performance.test.d.ts +1 -0
- package/dist/components/VirtualTable/VirtualTableCell.d.ts +6 -0
- package/dist/components/VirtualTable/VirtualTableHeader.d.ts +4 -1
- package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +17 -1
- package/dist/components/VirtualTable/fields/VirtualTableDateField.d.ts +1 -0
- package/dist/components/VirtualTable/types.d.ts +3 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/contexts/index.d.ts +10 -0
- package/dist/core/DrawerNavigationGroup.d.ts +45 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/editor/components/SlashCommandMenu.d.ts +6 -0
- package/dist/editor/components/editor-bubble-item.d.ts +8 -0
- package/dist/editor/components/editor-bubble.d.ts +8 -0
- package/dist/editor/components/image-bubble.d.ts +5 -0
- package/dist/editor/components/index.d.ts +16 -0
- package/dist/editor/components/table-bubble.d.ts +5 -0
- package/dist/editor/editor.d.ts +30 -0
- package/dist/editor/extensions/HighlightDecorationExtension.d.ts +24 -0
- package/dist/editor/extensions/Image/index.d.ts +6 -0
- package/dist/editor/extensions/Image.d.ts +6 -0
- package/dist/editor/extensions/TextLoadingDecorationExtension.d.ts +16 -0
- package/dist/editor/extensions/clipboard.d.ts +7 -0
- package/dist/editor/extensions/custom-keymap.d.ts +1 -0
- package/dist/editor/extensions/drag-and-drop.d.ts +9 -0
- package/dist/editor/hooks/useProseMirror.d.ts +13 -0
- package/dist/editor/hooks/useProseMirrorContext.d.ts +9 -0
- package/dist/editor/index.d.ts +2 -0
- package/dist/editor/markdown.d.ts +5 -0
- package/dist/editor/nodeViews/ImageComponent.d.ts +3 -0
- package/dist/editor/nodeViews/ReactNodeView.d.ts +29 -0
- package/dist/editor/nodeViews/TaskItemComponent.d.ts +3 -0
- package/dist/editor/nodeViews/index.d.ts +6 -0
- package/dist/editor/plugins/index.d.ts +2 -0
- package/dist/editor/plugins/inputrules.d.ts +6 -0
- package/dist/editor/plugins/placeholderPlugin.d.ts +3 -0
- package/dist/editor/plugins/slashCommandPlugin.d.ts +12 -0
- package/dist/editor/schema.d.ts +2 -0
- package/dist/editor/selectors/ai-selector.d.ts +0 -0
- package/dist/editor/selectors/color-selector.d.ts +10 -0
- package/dist/editor/selectors/link-selector.d.ts +8 -0
- package/dist/editor/selectors/node-selector.d.ts +15 -0
- package/dist/editor/selectors/text-buttons.d.ts +1 -0
- package/dist/editor/types.d.ts +5 -0
- package/dist/editor/useProseMirror.d.ts +16 -0
- package/dist/editor/utils/prosemirror-utils.d.ts +6 -0
- package/dist/editor/utils/remove_classes.d.ts +1 -0
- package/dist/editor/utils/useDebouncedCallback.d.ts +1 -0
- package/dist/form/components/ErrorFocus.d.ts +1 -1
- package/dist/form/components/LocalChangesMenu.d.ts +2 -2
- package/dist/form/components/StorageUploadProgress.d.ts +1 -1
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
- package/dist/form/validation.d.ts +3 -2
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useBreadcrumbsController.d.ts +16 -0
- package/dist/hooks/useBuildNavigationController.d.ts +0 -1
- package/dist/hooks/useCollapsedGroups.d.ts +6 -3
- package/dist/hooks/useTranslation.d.ts +17 -0
- package/dist/i18n/FireCMSi18nProvider.d.ts +33 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.es.js +31028 -16080
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +29955 -15028
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useRestoreScroll.d.ts +1 -1
- package/dist/locales/de.d.ts +2 -0
- package/dist/locales/en.d.ts +10 -0
- package/dist/locales/es.d.ts +10 -0
- package/dist/locales/fr.d.ts +2 -0
- package/dist/locales/hi.d.ts +2 -0
- package/dist/locales/it.d.ts +2 -0
- package/dist/locales/pt.d.ts +7 -0
- package/dist/preview/PropertyPreviewProps.d.ts +5 -0
- package/dist/preview/components/DatePreview.d.ts +13 -3
- package/dist/preview/components/ImagePreview.d.ts +5 -1
- package/dist/preview/components/StorageThumbnail.d.ts +2 -1
- package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
- package/dist/preview/property_previews/ArrayOfStorageComponentsPreview.d.ts +1 -1
- package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +1 -1
- package/dist/preview/property_previews/SkeletonPropertyComponent.d.ts +1 -1
- package/dist/types/analytics.d.ts +1 -1
- package/dist/types/collections.d.ts +88 -2
- package/dist/types/customization_controller.d.ts +2 -1
- package/dist/types/datasource.d.ts +0 -1
- package/dist/types/entities.d.ts +1 -0
- package/dist/types/firecms.d.ts +2 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/navigation.d.ts +2 -2
- package/dist/types/plugins.d.ts +69 -1
- package/dist/types/properties.d.ts +277 -12
- package/dist/types/storage.d.ts +9 -0
- package/dist/types/translations.d.ts +669 -0
- package/dist/util/__tests__/conditions.test.d.ts +1 -0
- package/dist/util/__tests__/objects.test.d.ts +1 -0
- package/dist/util/conditions.d.ts +26 -0
- package/dist/util/entities.d.ts +2 -3
- package/dist/util/index.d.ts +3 -1
- package/dist/util/lazy_eager.d.ts +7 -0
- package/dist/util/objects.d.ts +1 -0
- package/dist/util/property_utils.d.ts +2 -1
- package/dist/util/resolutions.d.ts +3 -3
- package/dist/util/useStorageUploadController.d.ts +11 -2
- package/package.json +52 -12
- package/src/app/Scaffold.tsx +20 -19
- package/src/components/AIIcon.tsx +41 -0
- package/src/components/ArrayContainer.tsx +7 -8
- package/src/components/ClearFilterSortButton.tsx +25 -19
- package/src/components/ConfirmationDialog.tsx +4 -4
- package/src/components/DeleteEntityDialog.tsx +12 -11
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +82 -43
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +130 -79
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +121 -104
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +132 -103
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +6 -3
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +24 -44
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +90 -49
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -2
- package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
- package/src/components/EntityCollectionView/Board.tsx +324 -0
- package/src/components/EntityCollectionView/BoardColumn.tsx +158 -0
- package/src/components/EntityCollectionView/BoardColumnTitle.tsx +45 -0
- package/src/components/EntityCollectionView/BoardSortableList.tsx +174 -0
- package/src/components/EntityCollectionView/CollectionDataErrorBanner.tsx +43 -0
- package/src/components/EntityCollectionView/EntityBoardCard.tsx +212 -0
- package/src/components/EntityCollectionView/EntityCard.tsx +235 -0
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +706 -0
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +236 -0
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +531 -209
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +35 -22
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +86 -15
- package/src/components/EntityCollectionView/FiltersDialog.tsx +252 -0
- package/src/components/EntityCollectionView/ViewModeToggle.tsx +202 -0
- package/src/components/EntityCollectionView/board_types.ts +113 -0
- package/src/components/EntityCollectionView/useBoardDataController.tsx +490 -0
- package/src/components/EntityJsonPreview.tsx +2 -1
- package/src/components/EntityPreview.tsx +1 -1
- package/src/components/EntityView.tsx +3 -2
- package/src/components/ErrorBoundary.tsx +27 -15
- package/src/components/ErrorTooltip.tsx +2 -1
- package/src/components/HomePage/DefaultHomePage.tsx +65 -22
- package/src/components/HomePage/HomePageDnD.tsx +59 -42
- package/src/components/HomePage/NavigationCard.tsx +20 -18
- package/src/components/HomePage/NavigationGroup.tsx +20 -17
- package/src/components/HomePage/RenameGroupDialog.tsx +15 -15
- package/src/components/HomePage/SmallNavigationCard.tsx +10 -9
- package/src/components/LanguageToggle.tsx +66 -0
- package/src/components/NotFoundPage.tsx +5 -3
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +12 -17
- package/src/components/ReferenceWidget.tsx +5 -6
- package/src/components/SearchIconsView.tsx +3 -1
- package/src/components/SelectableTable/SelectableTable.tsx +75 -67
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +7 -6
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +50 -40
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +53 -40
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +60 -58
- package/src/components/UnsavedChangesDialog.tsx +6 -6
- package/src/components/UserDisplay.tsx +4 -4
- package/src/components/VirtualTable/VirtualTable.performance.test.tsx +387 -0
- package/src/components/VirtualTable/VirtualTable.tsx +277 -121
- package/src/components/VirtualTable/VirtualTableCell.tsx +18 -2
- package/src/components/VirtualTable/VirtualTableHeader.tsx +76 -64
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +163 -42
- package/src/components/VirtualTable/VirtualTableProps.tsx +21 -2
- package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -0
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +19 -6
- package/src/components/VirtualTable/types.tsx +3 -0
- package/src/components/common/default_entity_actions.tsx +4 -0
- package/src/components/common/useColumnsIds.tsx +95 -3
- package/src/components/common/useDataSourceTableController.tsx +12 -4
- package/src/components/index.tsx +5 -0
- package/src/contexts/BreacrumbsContext.tsx +15 -8
- package/src/contexts/index.ts +10 -0
- package/src/core/DefaultAppBar.tsx +49 -32
- package/src/core/DefaultDrawer.tsx +49 -57
- package/src/core/DrawerNavigationGroup.tsx +120 -0
- package/src/core/DrawerNavigationItem.tsx +4 -3
- package/src/core/EntityEditView.tsx +94 -50
- package/src/core/EntityEditViewFormActions.tsx +24 -17
- package/src/core/EntitySidePanel.tsx +34 -30
- package/src/core/FireCMS.tsx +33 -6
- package/src/core/SideDialogs.tsx +4 -2
- package/src/core/field_configs.tsx +18 -11
- package/src/core/index.tsx +1 -0
- package/src/editor/components/SlashCommandMenu.tsx +516 -0
- package/src/editor/components/editor-bubble-item.tsx +32 -0
- package/src/editor/components/editor-bubble.tsx +118 -0
- package/src/editor/components/image-bubble.tsx +156 -0
- package/src/editor/components/index.ts +14 -0
- package/src/editor/components/table-bubble.tsx +165 -0
- package/src/editor/editor.tsx +455 -0
- package/src/editor/extensions/HighlightDecorationExtension.ts +114 -0
- package/src/editor/extensions/Image/index.ts +133 -0
- package/src/editor/extensions/Image.ts +159 -0
- package/src/editor/extensions/TextLoadingDecorationExtension.tsx +107 -0
- package/src/editor/extensions/clipboard.ts +72 -0
- package/src/editor/extensions/custom-keymap.ts +24 -0
- package/src/editor/extensions/drag-and-drop.tsx +480 -0
- package/src/editor/hooks/useProseMirror.ts +124 -0
- package/src/editor/hooks/useProseMirrorContext.ts +15 -0
- package/src/editor/index.ts +2 -0
- package/src/editor/markdown.ts +172 -0
- package/src/editor/nodeViews/ImageComponent.tsx +20 -0
- package/src/editor/nodeViews/ReactNodeView.tsx +89 -0
- package/src/editor/nodeViews/TaskItemComponent.tsx +29 -0
- package/src/editor/nodeViews/index.ts +35 -0
- package/src/editor/plugins/index.ts +58 -0
- package/src/editor/plugins/inputrules.ts +82 -0
- package/src/editor/plugins/placeholderPlugin.ts +55 -0
- package/src/editor/plugins/slashCommandPlugin.ts +61 -0
- package/src/editor/schema.ts +240 -0
- package/src/editor/selectors/ai-selector.tsx +111 -0
- package/src/editor/selectors/color-selector.tsx +200 -0
- package/src/editor/selectors/link-selector.tsx +118 -0
- package/src/editor/selectors/node-selector.tsx +157 -0
- package/src/editor/selectors/text-buttons.tsx +86 -0
- package/src/editor/types.ts +6 -0
- package/src/editor/useProseMirror.ts +126 -0
- package/src/editor/utils/prosemirror-utils.ts +108 -0
- package/src/editor/utils/remove_classes.ts +17 -0
- package/src/editor/utils/useDebouncedCallback.ts +25 -0
- package/src/form/EntityForm.tsx +150 -75
- package/src/form/EntityFormActions.tsx +19 -12
- package/src/form/PropertyFieldBinding.tsx +68 -51
- package/src/form/components/ErrorFocus.tsx +3 -3
- package/src/form/components/LocalChangesMenu.tsx +19 -19
- package/src/form/components/StorageItemPreview.tsx +5 -3
- package/src/form/components/StorageUploadProgress.tsx +22 -6
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +18 -5
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +22 -10
- package/src/form/field_bindings/BlockFieldBinding.tsx +26 -9
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +18 -17
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +46 -25
- package/src/form/field_bindings/MapFieldBinding.tsx +88 -70
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +93 -52
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +15 -1
- package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +25 -11
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +25 -11
- package/src/form/field_bindings/RepeatFieldBinding.tsx +21 -6
- package/src/form/field_bindings/SelectFieldBinding.tsx +7 -5
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +110 -92
- package/src/form/field_bindings/SwitchFieldBinding.tsx +31 -14
- package/src/form/field_bindings/TextFieldBinding.tsx +77 -38
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +7 -5
- package/src/form/validation.ts +245 -160
- package/src/hooks/index.tsx +1 -0
- package/src/hooks/useBreadcrumbsController.tsx +18 -0
- package/src/hooks/useBuildNavigationController.tsx +91 -41
- package/src/hooks/useCollapsedGroups.ts +18 -9
- package/src/hooks/useTranslation.ts +31 -0
- package/src/hooks/useValidateAuthenticator.tsx +1 -1
- package/src/i18n/FireCMSi18nProvider.tsx +160 -0
- package/src/index.ts +5 -0
- package/src/internal/useBuildDataSource.ts +68 -34
- package/src/internal/useBuildSideDialogsController.tsx +11 -8
- package/src/internal/useBuildSideEntityController.tsx +24 -24
- package/src/internal/useRestoreScroll.tsx +26 -14
- package/src/locales/de.ts +718 -0
- package/src/locales/en.ts +730 -0
- package/src/locales/es.ts +730 -0
- package/src/locales/fr.ts +718 -0
- package/src/locales/hi.ts +718 -0
- package/src/locales/it.ts +718 -0
- package/src/locales/pt.ts +727 -0
- package/src/preview/PropertyPreview.tsx +43 -33
- package/src/preview/PropertyPreviewProps.tsx +6 -0
- package/src/preview/components/DatePreview.tsx +72 -4
- package/src/preview/components/EmptyValue.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +37 -21
- package/src/preview/components/ReferencePreview.tsx +8 -2
- package/src/preview/components/StorageThumbnail.tsx +16 -12
- package/src/preview/components/UrlComponentPreview.tsx +32 -27
- package/src/preview/components/UserPreview.tsx +3 -1
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +9 -7
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +11 -9
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +26 -24
- package/src/preview/property_previews/MapPropertyPreview.tsx +49 -27
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +61 -56
- package/src/routes/CustomCMSRoute.tsx +1 -0
- package/src/routes/FireCMSRoute.tsx +87 -65
- package/src/types/analytics.ts +10 -0
- package/src/types/collections.ts +97 -3
- package/src/types/customization_controller.tsx +2 -1
- package/src/types/datasource.ts +54 -56
- package/src/types/entities.ts +10 -0
- package/src/types/firecms.tsx +2 -1
- package/src/types/index.ts +1 -0
- package/src/types/navigation.ts +2 -2
- package/src/types/plugins.tsx +77 -1
- package/src/types/properties.ts +369 -37
- package/src/types/storage.ts +11 -1
- package/src/types/translations.ts +752 -0
- package/src/util/__tests__/conditions.test.ts +506 -0
- package/src/util/__tests__/objects.test.ts +196 -0
- package/src/util/callbacks.ts +6 -3
- package/src/util/collections.ts +51 -6
- package/src/util/conditions.ts +339 -0
- package/src/util/entities.ts +29 -30
- package/src/util/entity_cache.ts +2 -1
- package/src/util/index.ts +3 -1
- package/src/util/join_collections.ts +10 -8
- package/src/util/lazy_eager.tsx +33 -0
- package/src/util/objects.ts +46 -13
- package/src/util/{references.ts → previews.ts} +16 -2
- package/src/util/property_utils.tsx +37 -11
- package/src/util/resolutions.ts +62 -58
- package/src/util/useStorageUploadController.tsx +34 -30
- /package/dist/util/{references.d.ts → previews.d.ts} +0 -0
package/src/form/EntityForm.tsx
CHANGED
|
@@ -40,7 +40,10 @@ import {
|
|
|
40
40
|
useSnackbarController
|
|
41
41
|
} from "../hooks";
|
|
42
42
|
import { Alert, CheckIcon, Chip, cls, EditIcon, NotesIcon, paperMixin, Tooltip, Typography } from "@firecms/ui";
|
|
43
|
-
import { Formex, FormexController, getIn, setIn, useCreateFormex
|
|
43
|
+
import { Formex, FormexController, getIn, setIn, useCreateFormex,
|
|
44
|
+
useFormex
|
|
45
|
+
} from "@firecms/formex";
|
|
46
|
+
import { useTranslation } from "../hooks";
|
|
44
47
|
import { useAnalyticsController } from "../hooks/useAnalyticsController";
|
|
45
48
|
import { FormEntry, FormLayout, LabelWithIconAndTooltip, PropertyFieldBinding } from "../form";
|
|
46
49
|
import { ValidationError } from "yup";
|
|
@@ -122,6 +125,35 @@ export function extractTouchedValues(values: any, touched: Record<string, boolea
|
|
|
122
125
|
return acc;
|
|
123
126
|
}
|
|
124
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Recursively removes empty plain objects `{}` and empty arrays `[]` from a value tree.
|
|
130
|
+
* This prevents ghost containers created by `setIn` intermediate path construction
|
|
131
|
+
* (e.g. `{ address: {} }` when only `address.city` was touched but value is undefined)
|
|
132
|
+
* from falsely triggering the unsaved local changes indicator.
|
|
133
|
+
*/
|
|
134
|
+
function removeEmptyContainers(obj: any): any {
|
|
135
|
+
if (Array.isArray(obj)) {
|
|
136
|
+
const cleaned = obj.map(removeEmptyContainers);
|
|
137
|
+
// Keep arrays even if they contain only nulls/undefined — that's intentional data
|
|
138
|
+
return cleaned;
|
|
139
|
+
}
|
|
140
|
+
if (obj && typeof obj === "object" && Object.getPrototypeOf(obj) === Object.prototype) {
|
|
141
|
+
const result: Record<string, any> = {};
|
|
142
|
+
for (const key of Object.keys(obj)) {
|
|
143
|
+
const cleaned = removeEmptyContainers(obj[key]);
|
|
144
|
+
// Skip empty plain objects
|
|
145
|
+
if (cleaned && typeof cleaned === "object" && !Array.isArray(cleaned)
|
|
146
|
+
&& Object.getPrototypeOf(cleaned) === Object.prototype
|
|
147
|
+
&& Object.keys(cleaned).length === 0) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
result[key] = cleaned;
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
return obj;
|
|
155
|
+
}
|
|
156
|
+
|
|
125
157
|
export function getChanges<T extends object>(source: Partial<T>, comparison: Partial<T>): Partial<T> {
|
|
126
158
|
const changes: Partial<T> = {};
|
|
127
159
|
|
|
@@ -181,30 +213,30 @@ export function getChanges<T extends object>(source: Partial<T>, comparison: Par
|
|
|
181
213
|
}
|
|
182
214
|
|
|
183
215
|
export function EntityForm<M extends Record<string, any>>({
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
216
|
+
path,
|
|
217
|
+
fullIdPath,
|
|
218
|
+
entityId: entityIdProp,
|
|
219
|
+
collection,
|
|
220
|
+
onValuesModified,
|
|
221
|
+
onIdChange,
|
|
222
|
+
onSaved,
|
|
223
|
+
entity,
|
|
224
|
+
initialDirtyValues,
|
|
225
|
+
onFormContextReady,
|
|
226
|
+
forceActionsAtTheBottom,
|
|
227
|
+
initialStatus,
|
|
228
|
+
className,
|
|
229
|
+
onStatusChange,
|
|
230
|
+
onEntityChange,
|
|
231
|
+
openEntityMode = "full_screen",
|
|
232
|
+
formex: formexProp,
|
|
233
|
+
disabled: disabledProp,
|
|
234
|
+
Builder,
|
|
235
|
+
EntityFormActionsComponent = EntityFormActions,
|
|
236
|
+
showDefaultActions = true,
|
|
237
|
+
showEntityPath = true,
|
|
238
|
+
children
|
|
239
|
+
}: EntityFormProps<M>) {
|
|
208
240
|
|
|
209
241
|
if (collection.customId && collection.formAutoSave) {
|
|
210
242
|
console.warn(`The collection ${collection.path} has customId and formAutoSave enabled. This is not supported and formAutoSave will be ignored`);
|
|
@@ -212,6 +244,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
212
244
|
|
|
213
245
|
const sideEntityController = useSideEntityController();
|
|
214
246
|
const navigationController = useNavigationController();
|
|
247
|
+
const { t } = useTranslation();
|
|
215
248
|
|
|
216
249
|
const navigateBack = useCallback(() => {
|
|
217
250
|
if (openEntityMode === "side_panel") {
|
|
@@ -247,7 +280,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
247
280
|
const context = useFireCMSContext();
|
|
248
281
|
const analyticsController = useAnalyticsController();
|
|
249
282
|
|
|
250
|
-
const [underlyingChanges] = useState<Partial<EntityValues<M>>>({});
|
|
283
|
+
const [underlyingChanges, setUnderlyingChanges] = useState<Partial<EntityValues<M>>>({});
|
|
251
284
|
|
|
252
285
|
const [customIdLoading, setCustomIdLoading] = useState<boolean>(false);
|
|
253
286
|
|
|
@@ -328,14 +361,15 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
328
361
|
return [initialValues, initialDirty];
|
|
329
362
|
}, [autoApplyLocalChanges, localChangesDataRaw, baseInitialValues, initialDirtyValues]);
|
|
330
363
|
|
|
331
|
-
const
|
|
332
|
-
if (!localChangesDataRaw) {
|
|
333
|
-
return
|
|
364
|
+
const hasLocalChanges = useMemo(() => {
|
|
365
|
+
if (localChangesCleared || !localChangesDataRaw || Object.keys(localChangesDataRaw).length === 0) {
|
|
366
|
+
return false;
|
|
334
367
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
368
|
+
// Compare cached values against entity values to check for real differences
|
|
369
|
+
const entityValues = entity?.values ?? {};
|
|
370
|
+
const realChanges = getChanges(localChangesDataRaw as Partial<M>, entityValues as Partial<M>);
|
|
371
|
+
return Object.keys(realChanges).length > 0;
|
|
372
|
+
}, [localChangesCleared, localChangesDataRaw, entity?.values]);
|
|
339
373
|
|
|
340
374
|
const formex: FormexController<M> = formexProp ?? useCreateFormex<M>({
|
|
341
375
|
initialValues: initialValues as M,
|
|
@@ -355,8 +389,10 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
355
389
|
onValuesChangeDeferred: (values: M, controller: FormexController<M>) => {
|
|
356
390
|
const key = (status === "new" || status === "copy") ? path + "#new" : path + "/" + entityId;
|
|
357
391
|
if (controller.dirty) {
|
|
358
|
-
const touchedValues = extractTouchedValues(values, controller.touched);
|
|
359
|
-
|
|
392
|
+
const touchedValues = removeEmptyContainers(extractTouchedValues(values, controller.touched));
|
|
393
|
+
if (touchedValues && Object.keys(touchedValues).length > 0) {
|
|
394
|
+
saveEntityToCache(key, touchedValues);
|
|
395
|
+
}
|
|
360
396
|
}
|
|
361
397
|
},
|
|
362
398
|
validation: (values) => {
|
|
@@ -373,6 +409,15 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
373
409
|
useEffect(() => {
|
|
374
410
|
|
|
375
411
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
412
|
+
if (e.defaultPrevented) return;
|
|
413
|
+
const activeElement = document.activeElement as HTMLElement;
|
|
414
|
+
const isInput = activeElement && (
|
|
415
|
+
activeElement.tagName === "INPUT" ||
|
|
416
|
+
activeElement.tagName === "TEXTAREA" ||
|
|
417
|
+
activeElement.isContentEditable
|
|
418
|
+
);
|
|
419
|
+
if (isInput) return;
|
|
420
|
+
|
|
376
421
|
const isUndo = (e.metaKey || e.ctrlKey) && !e.shiftKey && e.key.toLowerCase() === "z";
|
|
377
422
|
const isRedo =
|
|
378
423
|
((e.metaKey || e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === "z") ||
|
|
@@ -462,12 +507,12 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
462
507
|
}, [entityId, path, snackbarController]);
|
|
463
508
|
|
|
464
509
|
const saveEntity = ({
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
510
|
+
values,
|
|
511
|
+
previousValues,
|
|
512
|
+
entityId,
|
|
513
|
+
collection,
|
|
514
|
+
path
|
|
515
|
+
}: {
|
|
471
516
|
collection: EntityCollection<M>,
|
|
472
517
|
path: string,
|
|
473
518
|
entityId: string | undefined,
|
|
@@ -500,13 +545,13 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
500
545
|
};
|
|
501
546
|
|
|
502
547
|
const onSaveEntityRequest = async ({
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
548
|
+
collection,
|
|
549
|
+
path,
|
|
550
|
+
entityId,
|
|
551
|
+
values,
|
|
552
|
+
previousValues,
|
|
553
|
+
autoSave
|
|
554
|
+
}: EntityFormSaveParams<M>): Promise<void> => {
|
|
510
555
|
if (!status)
|
|
511
556
|
return;
|
|
512
557
|
if (autoSave) {
|
|
@@ -574,6 +619,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
574
619
|
}, [snackbarController]);
|
|
575
620
|
|
|
576
621
|
const pluginActions: React.ReactNode[] = [];
|
|
622
|
+
const pluginBeforeTitle: React.ReactNode[] = [];
|
|
577
623
|
const plugins = customizationController.plugins;
|
|
578
624
|
|
|
579
625
|
const actionsDisabled = disabled || formex.isSubmitting || (status === "existing" && !formex.dirty) || Boolean(disabledProp);
|
|
@@ -597,6 +643,12 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
597
643
|
key={`actions_${plugin.key}`} {...actionProps} />
|
|
598
644
|
: null
|
|
599
645
|
)).filter(Boolean));
|
|
646
|
+
pluginBeforeTitle.push(...plugins.map((plugin) => (
|
|
647
|
+
plugin.form?.BeforeTitle
|
|
648
|
+
? <plugin.form.BeforeTitle
|
|
649
|
+
key={`before_title_${plugin.key}`} {...actionProps} />
|
|
650
|
+
: null
|
|
651
|
+
)).filter(Boolean));
|
|
600
652
|
}
|
|
601
653
|
|
|
602
654
|
const titlePropertyKey = getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs);
|
|
@@ -638,21 +690,42 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
638
690
|
const modified = formex.dirty;
|
|
639
691
|
|
|
640
692
|
const uniqueFieldValidator: CustomFieldValidator = useCallback(({
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
693
|
+
name,
|
|
694
|
+
value
|
|
695
|
+
}) => dataSource.checkUniqueField(path, name, value, entityId, collection),
|
|
644
696
|
[dataSource, path, entityId]);
|
|
645
697
|
|
|
646
698
|
const validationSchema = useMemo(() => entityId
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
699
|
+
? getYupEntitySchema(
|
|
700
|
+
entityId,
|
|
701
|
+
resolvedCollection.properties,
|
|
702
|
+
uniqueFieldValidator)
|
|
703
|
+
: undefined,
|
|
652
704
|
[entityId, resolvedCollection.properties, uniqueFieldValidator]);
|
|
653
705
|
|
|
654
706
|
useOnAutoSave(autoSave, formex, lastSavedValues, save);
|
|
655
707
|
|
|
708
|
+
// Detect external changes to the entity (e.g. from onSnapshot after Admin SDK writes)
|
|
709
|
+
const prevEntityValuesRef = useRef<EntityValues<M> | undefined>(entity?.values);
|
|
710
|
+
useEffect(() => {
|
|
711
|
+
if (!entity?.values || status !== "existing") return;
|
|
712
|
+
const prev = prevEntityValuesRef.current;
|
|
713
|
+
prevEntityValuesRef.current = entity.values;
|
|
714
|
+
if (prev && !equal(prev, entity.values)) {
|
|
715
|
+
// Compute the diff between the old and new entity values
|
|
716
|
+
const changes: Partial<EntityValues<M>> = {};
|
|
717
|
+
const allKeys = new Set([...Object.keys(prev), ...Object.keys(entity.values)]);
|
|
718
|
+
for (const key of allKeys) {
|
|
719
|
+
if (!equal((prev as any)[key], (entity.values as any)[key])) {
|
|
720
|
+
(changes as any)[key] = (entity.values as any)[key];
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
if (Object.keys(changes).length > 0) {
|
|
724
|
+
setUnderlyingChanges(changes);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}, [entity?.values, status]);
|
|
728
|
+
|
|
656
729
|
useEffect(() => {
|
|
657
730
|
if (!autoSave && !formex.isSubmitting && underlyingChanges && entity) {
|
|
658
731
|
// we update the form fields from the Firestore data
|
|
@@ -706,8 +779,8 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
706
779
|
|
|
707
780
|
return (
|
|
708
781
|
<FormEntry propertyKey={key}
|
|
709
|
-
|
|
710
|
-
|
|
782
|
+
widthPercentage={widthPercentage}
|
|
783
|
+
key={`field_${key}`}>
|
|
711
784
|
<PropertyFieldBinding {...cmsFormFieldProps} />
|
|
712
785
|
</FormEntry>
|
|
713
786
|
);
|
|
@@ -720,7 +793,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
720
793
|
throw new Error("When using additional fields you need to provide a Builder or a value");
|
|
721
794
|
}
|
|
722
795
|
const child = Builder
|
|
723
|
-
? <Builder entity={entity} context={context}/>
|
|
796
|
+
? <Builder entity={entity} context={context} />
|
|
724
797
|
: <div className={"w-full"}>
|
|
725
798
|
{additionalField.value?.({
|
|
726
799
|
entity,
|
|
@@ -732,9 +805,9 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
732
805
|
<div key={`additional_${key}`} className={"w-full"}>
|
|
733
806
|
<LabelWithIconAndTooltip
|
|
734
807
|
propertyKey={key}
|
|
735
|
-
icon={<NotesIcon size={"small"}/>}
|
|
808
|
+
icon={<NotesIcon size={"small"} />}
|
|
736
809
|
title={additionalField.name}
|
|
737
|
-
className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
|
|
810
|
+
className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"} />
|
|
738
811
|
<div
|
|
739
812
|
className={cls(paperMixin, "w-full min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
|
|
740
813
|
<ErrorBoundary>
|
|
@@ -756,6 +829,8 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
756
829
|
|
|
757
830
|
const formView = <ErrorBoundary>
|
|
758
831
|
<>
|
|
832
|
+
{pluginBeforeTitle}
|
|
833
|
+
|
|
759
834
|
{!Builder && <div className={"w-full py-2 flex flex-col items-start my-4 lg:my-6"}>
|
|
760
835
|
<Typography
|
|
761
836
|
className={"my-4 flex-grow line-clamp-1 " + (collection.hideIdFromForm ? "mb-6" : "")}
|
|
@@ -765,7 +840,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
765
840
|
|
|
766
841
|
{!entity?.values && initialStatus === "existing" &&
|
|
767
842
|
<Alert color={"warning"} size={"small"} outerClassName={"w-full mb-4 text-xs"}>
|
|
768
|
-
|
|
843
|
+
{t("this_entity_not_exist")}
|
|
769
844
|
</Alert>}
|
|
770
845
|
|
|
771
846
|
{showEntityPath && <Alert color={"base"} outerClassName={"w-full"} size={"small"}>
|
|
@@ -779,27 +854,27 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
779
854
|
{children}
|
|
780
855
|
|
|
781
856
|
{initialEntityId && !entity && initialStatus !== "new" && <Alert color={"info"} size={"small"}>
|
|
782
|
-
|
|
857
|
+
{t("this_entity_not_exist")}
|
|
783
858
|
</Alert>}
|
|
784
859
|
|
|
785
860
|
{!Builder && !collection.hideIdFromForm &&
|
|
786
861
|
<CustomIdField customId={collection.customId}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
862
|
+
entityId={entityId}
|
|
863
|
+
status={status}
|
|
864
|
+
onChange={setEntityId}
|
|
865
|
+
error={entityIdError}
|
|
866
|
+
loading={customIdLoading}
|
|
867
|
+
entity={entity} />
|
|
793
868
|
}
|
|
794
869
|
|
|
795
870
|
{entityId && formContext && <>
|
|
796
871
|
<div className="mt-12 flex flex-col gap-8" ref={formRef}>
|
|
797
872
|
{formFields()}
|
|
798
|
-
<ErrorFocus containerRef={formRef}/>
|
|
873
|
+
<ErrorFocus containerRef={formRef} />
|
|
799
874
|
</div>
|
|
800
875
|
</>}
|
|
801
876
|
|
|
802
|
-
{forceActionsAtTheBottom && <div className="h-16"/>}
|
|
877
|
+
{forceActionsAtTheBottom && <div className="h-16" />}
|
|
803
878
|
</>
|
|
804
879
|
</ErrorBoundary>;
|
|
805
880
|
|
|
@@ -851,7 +926,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
851
926
|
<LocalChangesMenu
|
|
852
927
|
cacheKey={status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId}
|
|
853
928
|
properties={resolvedCollection.properties}
|
|
854
|
-
|
|
929
|
+
cachedData={localChangesDataRaw as Partial<M>}
|
|
855
930
|
formex={formex}
|
|
856
931
|
onClearLocalChanges={() => setLocalChangesCleared(true)}
|
|
857
932
|
/>}
|
|
@@ -859,12 +934,12 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
859
934
|
{formex.dirty
|
|
860
935
|
? <Tooltip title={"This form has been modified"}>
|
|
861
936
|
<Chip size={"small"} className={"py-1"} colorScheme={"orangeDarker"}>
|
|
862
|
-
<EditIcon size={"smallest"}/>
|
|
937
|
+
<EditIcon size={"smallest"} />
|
|
863
938
|
</Chip>
|
|
864
939
|
</Tooltip>
|
|
865
940
|
: <Tooltip title={"The current form is in sync with the database"}>
|
|
866
|
-
<Chip size={"small"} className={"py-1"}
|
|
867
|
-
<CheckIcon size={"smallest"}/>
|
|
941
|
+
<Chip size={"small"} className={"py-1"}>
|
|
942
|
+
<CheckIcon size={"smallest"} />
|
|
868
943
|
</Chip>
|
|
869
944
|
</Tooltip>}
|
|
870
945
|
</div>
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from "@firecms/ui";
|
|
20
20
|
import { FormexController } from "@firecms/formex";
|
|
21
21
|
import { useFireCMSContext, useSideEntityController } from "../hooks";
|
|
22
|
+
import { useTranslation } from "../hooks/useTranslation";
|
|
22
23
|
|
|
23
24
|
export interface EntityFormActionsProps {
|
|
24
25
|
fullPath: string;
|
|
@@ -56,6 +57,7 @@ export function EntityFormActions({
|
|
|
56
57
|
|
|
57
58
|
const context = useFireCMSContext();
|
|
58
59
|
const sideEntityController = useSideEntityController();
|
|
60
|
+
const { t } = useTranslation();
|
|
59
61
|
|
|
60
62
|
return layout === "bottom"
|
|
61
63
|
? buildBottomActions({
|
|
@@ -72,7 +74,8 @@ export function EntityFormActions({
|
|
|
72
74
|
openEntityMode,
|
|
73
75
|
navigateBack,
|
|
74
76
|
formContext,
|
|
75
|
-
formex
|
|
77
|
+
formex,
|
|
78
|
+
t
|
|
76
79
|
})
|
|
77
80
|
: buildSideActions({
|
|
78
81
|
fullPath,
|
|
@@ -88,7 +91,8 @@ export function EntityFormActions({
|
|
|
88
91
|
openEntityMode,
|
|
89
92
|
navigateBack,
|
|
90
93
|
formContext,
|
|
91
|
-
formex
|
|
94
|
+
formex,
|
|
95
|
+
t
|
|
92
96
|
});
|
|
93
97
|
}
|
|
94
98
|
|
|
@@ -108,6 +112,7 @@ type ActionsViewProps<M extends object> = {
|
|
|
108
112
|
navigateBack: () => void;
|
|
109
113
|
formContext: FormContext,
|
|
110
114
|
formex: FormexController<any>;
|
|
115
|
+
t: (key: any, vars?: Record<string, string>) => string;
|
|
111
116
|
};
|
|
112
117
|
|
|
113
118
|
function buildBottomActions<M extends object>({
|
|
@@ -125,7 +130,8 @@ function buildBottomActions<M extends object>({
|
|
|
125
130
|
openEntityMode,
|
|
126
131
|
navigateBack,
|
|
127
132
|
formContext,
|
|
128
|
-
formex
|
|
133
|
+
formex,
|
|
134
|
+
t
|
|
129
135
|
}: ActionsViewProps<M>) {
|
|
130
136
|
|
|
131
137
|
const hasErrors = Object.keys(formex.errors).length > 0 && formex.submitCount > 0;
|
|
@@ -165,16 +171,16 @@ function buildBottomActions<M extends object>({
|
|
|
165
171
|
<Button variant="text" disabled={disabled || formex.isSubmitting}
|
|
166
172
|
color={"primary"}
|
|
167
173
|
type="reset">
|
|
168
|
-
{status === "existing" ? "
|
|
174
|
+
{status === "existing" ? t("discard") : t("clear")}
|
|
169
175
|
</Button>
|
|
170
176
|
<Button variant={"filled"}
|
|
171
177
|
color="primary"
|
|
172
178
|
type="submit"
|
|
173
179
|
disabled={disabled || formex.isSubmitting}
|
|
174
180
|
startIcon={hasErrors ? <ErrorIcon/> : undefined}>
|
|
175
|
-
{status === "existing" && "
|
|
176
|
-
{status === "copy" && "
|
|
177
|
-
{status === "new" && "
|
|
181
|
+
{status === "existing" && t("save")}
|
|
182
|
+
{status === "copy" && t("create_copy")}
|
|
183
|
+
{status === "new" && t("create")}
|
|
178
184
|
</Button>
|
|
179
185
|
|
|
180
186
|
</DialogActions>;
|
|
@@ -193,7 +199,8 @@ function buildSideActions<M extends object>({
|
|
|
193
199
|
disabled,
|
|
194
200
|
status,
|
|
195
201
|
pluginActions,
|
|
196
|
-
formex
|
|
202
|
+
formex,
|
|
203
|
+
t
|
|
197
204
|
}: ActionsViewProps<M>) {
|
|
198
205
|
|
|
199
206
|
const hasErrors = Object.keys(formex.errors).length > 0 && formex.submitCount > 0;
|
|
@@ -207,12 +214,12 @@ function buildSideActions<M extends object>({
|
|
|
207
214
|
size={"large"}
|
|
208
215
|
startIcon={hasErrors ? <ErrorIcon/> : undefined}
|
|
209
216
|
disabled={disabled || formex.isSubmitting}>
|
|
210
|
-
{status === "existing" && "
|
|
211
|
-
{status === "copy" && "
|
|
212
|
-
{status === "new" && "
|
|
217
|
+
{status === "existing" && t("save")}
|
|
218
|
+
{status === "copy" && t("create_copy")}
|
|
219
|
+
{status === "new" && t("create")}
|
|
213
220
|
</LoadingButton>
|
|
214
221
|
<Button fullWidth={true} variant="text" disabled={disabled || formex.isSubmitting} type="reset">
|
|
215
|
-
{status === "existing" ? "
|
|
222
|
+
{status === "existing" ? t("discard") : t("clear")}
|
|
216
223
|
</Button>
|
|
217
224
|
|
|
218
225
|
{pluginActions}
|