@firecms/core 3.1.0-canary.24c8270 → 3.1.0-canary.501d471
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/dist/components/EntityCollectionView/CollectionDataErrorBanner.d.ts +4 -0
- package/dist/components/ErrorBoundary.d.ts +3 -1
- package/dist/components/HomePage/DefaultHomePage.d.ts +0 -1
- package/dist/components/LanguageToggle.d.ts +1 -0
- package/dist/components/UnsavedChangesDialog.d.ts +1 -0
- package/dist/components/VirtualTable/VirtualTableHeader.d.ts +1 -0
- package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +6 -1
- package/dist/components/VirtualTable/types.d.ts +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/core/DrawerNavigationGroup.d.ts +2 -2
- 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/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useBuildNavigationController.d.ts +0 -1
- package/dist/hooks/useCollapsedGroups.d.ts +3 -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 +29889 -18645
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +29883 -18659
- package/dist/index.umd.js.map +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/types/collections.d.ts +38 -0
- package/dist/types/customization_controller.d.ts +2 -1
- 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 +7 -0
- package/dist/types/properties.d.ts +9 -8
- package/dist/types/storage.d.ts +1 -0
- package/dist/types/translations.d.ts +669 -0
- package/dist/util/index.d.ts +1 -0
- package/dist/util/lazy_eager.d.ts +7 -0
- package/dist/util/objects.d.ts +1 -0
- package/dist/util/useStorageUploadController.d.ts +10 -1
- package/package.json +45 -9
- package/src/app/Scaffold.tsx +7 -5
- package/src/components/AIIcon.tsx +3 -1
- package/src/components/ArrayContainer.tsx +6 -4
- package/src/components/ClearFilterSortButton.tsx +6 -3
- package/src/components/ConfirmationDialog.tsx +4 -2
- package/src/components/DeleteEntityDialog.tsx +10 -7
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +9 -3
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +6 -3
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -1
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -2
- package/src/components/EntityCollectionView/BoardSortableList.tsx +3 -1
- package/src/components/EntityCollectionView/CollectionDataErrorBanner.tsx +43 -0
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +16 -43
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +17 -25
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +24 -18
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -3
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -2
- package/src/components/EntityCollectionView/FiltersDialog.tsx +8 -5
- package/src/components/EntityCollectionView/ViewModeToggle.tsx +11 -8
- package/src/components/EntityJsonPreview.tsx +2 -1
- package/src/components/EntityView.tsx +3 -2
- package/src/components/ErrorBoundary.tsx +27 -15
- package/src/components/HomePage/DefaultHomePage.tsx +19 -13
- package/src/components/HomePage/HomePageDnD.tsx +3 -1
- package/src/components/HomePage/NavigationGroup.tsx +3 -1
- package/src/components/HomePage/RenameGroupDialog.tsx +15 -13
- package/src/components/LanguageToggle.tsx +66 -0
- package/src/components/NotFoundPage.tsx +5 -3
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +9 -7
- package/src/components/ReferenceWidget.tsx +3 -2
- package/src/components/SearchIconsView.tsx +3 -1
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +11 -0
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +15 -2
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +11 -0
- package/src/components/UnsavedChangesDialog.tsx +6 -4
- package/src/components/VirtualTable/VirtualTable.performance.test.tsx +1 -0
- package/src/components/VirtualTable/VirtualTable.tsx +5 -3
- package/src/components/VirtualTable/VirtualTableHeader.tsx +21 -18
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +8 -3
- package/src/components/VirtualTable/VirtualTableProps.tsx +7 -1
- package/src/components/VirtualTable/types.tsx +1 -0
- package/src/components/common/default_entity_actions.tsx +4 -0
- package/src/components/common/useDataSourceTableController.tsx +5 -14
- package/src/components/index.tsx +1 -0
- package/src/core/DefaultAppBar.tsx +14 -10
- package/src/core/DefaultDrawer.tsx +8 -2
- package/src/core/DrawerNavigationGroup.tsx +5 -3
- package/src/core/EntityEditView.tsx +53 -7
- package/src/core/EntityEditViewFormActions.tsx +24 -17
- package/src/core/EntitySidePanel.tsx +6 -4
- package/src/core/FireCMS.tsx +33 -6
- package/src/core/field_configs.tsx +4 -2
- 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 +80 -7
- package/src/form/EntityFormActions.tsx +19 -12
- package/src/form/PropertyFieldBinding.tsx +7 -5
- package/src/form/components/LocalChangesMenu.tsx +13 -13
- package/src/form/components/StorageItemPreview.tsx +3 -2
- package/src/form/components/StorageUploadProgress.tsx +18 -3
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +18 -5
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +22 -9
- package/src/form/field_bindings/BlockFieldBinding.tsx +26 -9
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +46 -24
- package/src/form/field_bindings/MapFieldBinding.tsx +27 -11
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +73 -36
- 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 +28 -10
- package/src/form/field_bindings/SwitchFieldBinding.tsx +31 -14
- package/src/form/field_bindings/TextFieldBinding.tsx +10 -7
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +7 -5
- package/src/hooks/index.tsx +1 -0
- package/src/hooks/useBuildNavigationController.tsx +20 -13
- package/src/hooks/useCollapsedGroups.ts +7 -6
- package/src/hooks/useTranslation.ts +31 -0
- package/src/i18n/FireCMSi18nProvider.tsx +160 -0
- package/src/index.ts +5 -0
- 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 +3 -2
- package/src/preview/components/ReferencePreview.tsx +2 -1
- package/src/preview/components/UrlComponentPreview.tsx +4 -2
- package/src/preview/components/UserPreview.tsx +3 -1
- package/src/preview/property_previews/MapPropertyPreview.tsx +49 -27
- package/src/routes/FireCMSRoute.tsx +63 -54
- package/src/types/collections.ts +40 -0
- package/src/types/customization_controller.tsx +2 -1
- 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 +8 -0
- package/src/types/properties.ts +12 -10
- package/src/types/storage.ts +2 -1
- package/src/types/translations.ts +752 -0
- package/src/util/index.ts +1 -0
- package/src/util/lazy_eager.tsx +33 -0
- package/src/util/objects.ts +15 -0
- package/src/util/useStorageUploadController.tsx +23 -29
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
defaultBorderMixin,
|
|
14
14
|
ExpandablePanel,
|
|
15
15
|
IconButton,
|
|
16
|
+
CloseIcon,
|
|
16
17
|
Menu,
|
|
17
18
|
MenuItem,
|
|
18
19
|
RemoveIcon,
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
import { getDefaultValueForDataType, getIconForProperty } from "../../util";
|
|
23
24
|
import { useCustomizationController } from "../../hooks";
|
|
24
25
|
import { getIn } from "@firecms/formex";
|
|
26
|
+
import { useTranslation } from "../../hooks/useTranslation";
|
|
25
27
|
|
|
26
28
|
type MapEditViewRowState = [number, {
|
|
27
29
|
key: string,
|
|
@@ -54,6 +56,7 @@ export function KeyValueFieldBinding({
|
|
|
54
56
|
throw Error(`Your property ${propertyKey} needs to have the 'keyValue' prop in order to use this field binding`);
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
const { t } = useTranslation();
|
|
57
60
|
const initialValues = getIn(context.formex.initialValues, propertyKey);
|
|
58
61
|
|
|
59
62
|
const mapFormView = <MapEditView value={value}
|
|
@@ -62,12 +65,28 @@ export function KeyValueFieldBinding({
|
|
|
62
65
|
initialValue={initialValues}
|
|
63
66
|
fieldName={property.name ?? propertyKey}/>;
|
|
64
67
|
|
|
65
|
-
const title =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
const title = (
|
|
69
|
+
<div className="flex items-center w-full">
|
|
70
|
+
<LabelWithIconAndTooltip
|
|
71
|
+
propertyKey={propertyKey}
|
|
72
|
+
icon={getIconForProperty(property, "small")}
|
|
73
|
+
required={property.validation?.required}
|
|
74
|
+
title={property.name}
|
|
75
|
+
className={"text-text-secondary dark:text-text-secondary-dark flex-grow"}/>
|
|
76
|
+
{(property.nullable || property.clearable) && !disabled && (
|
|
77
|
+
<IconButton
|
|
78
|
+
size="small"
|
|
79
|
+
onClick={(e) => {
|
|
80
|
+
e.stopPropagation();
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
setValue(null);
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
<CloseIcon size={"small"}/>
|
|
86
|
+
</IconButton>
|
|
87
|
+
)}
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
71
90
|
|
|
72
91
|
return (
|
|
73
92
|
<>
|
|
@@ -103,6 +122,7 @@ function MapEditView<T extends Record<string, any>>({
|
|
|
103
122
|
fieldName,
|
|
104
123
|
disabled
|
|
105
124
|
}: MapEditViewParams<T>) {
|
|
125
|
+
const { t } = useTranslation();
|
|
106
126
|
const [internalState, setInternalState] = React.useState<MapEditViewRowState[]>(
|
|
107
127
|
Object.keys(initialValue ?? {}).map((key) => [getRandomId(), {
|
|
108
128
|
key,
|
|
@@ -230,7 +250,7 @@ function MapEditView<T extends Record<string, any>>({
|
|
|
230
250
|
}]]);
|
|
231
251
|
}
|
|
232
252
|
}>
|
|
233
|
-
{fieldName ?
|
|
253
|
+
{fieldName ? t("add_to_field", { fieldName }) : t("add_entry")}
|
|
234
254
|
</Button>
|
|
235
255
|
|
|
236
256
|
</div>;
|
|
@@ -261,12 +281,13 @@ function MapKeyValueRow<T extends Record<string, any>>({
|
|
|
261
281
|
}) {
|
|
262
282
|
|
|
263
283
|
const { locale } = useCustomizationController();
|
|
284
|
+
const { t } = useTranslation();
|
|
264
285
|
|
|
265
286
|
function buildInput(entryValue: any, fieldKey: string, dataType: DataType) {
|
|
266
287
|
if (dataType === "string" || dataType === "number") {
|
|
267
288
|
return <TextField
|
|
268
289
|
key={dataType}
|
|
269
|
-
placeholder={"value"}
|
|
290
|
+
placeholder={t("value")}
|
|
270
291
|
value={entryValue}
|
|
271
292
|
type={dataType === "number" ? "number" : "text"}
|
|
272
293
|
size={"medium"}
|
|
@@ -325,7 +346,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
|
|
|
325
346
|
<ArrayContainer value={entryValue}
|
|
326
347
|
newDefaultEntry={""}
|
|
327
348
|
droppableId={rowId.toString()}
|
|
328
|
-
addLabel={fieldKey ?
|
|
349
|
+
addLabel={fieldKey ? t("add_to_field", { fieldName: fieldKey }) : t("add_entry")}
|
|
329
350
|
size={"small"}
|
|
330
351
|
disabled={disabled || !fieldKey}
|
|
331
352
|
canAddElements={true}
|
|
@@ -370,7 +391,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
|
|
|
370
391
|
} else {
|
|
371
392
|
return <Typography
|
|
372
393
|
variant={"caption"}>
|
|
373
|
-
{
|
|
394
|
+
{t("data_type_not_supported", { dataType })}
|
|
374
395
|
</Typography>;
|
|
375
396
|
}
|
|
376
397
|
}
|
|
@@ -386,7 +407,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
|
|
|
386
407
|
<div className="w-[300px] max-w-[30%]">
|
|
387
408
|
<TextField
|
|
388
409
|
value={fieldKey}
|
|
389
|
-
placeholder={"key"}
|
|
410
|
+
placeholder={t("key")}
|
|
390
411
|
disabled={disabled || (entryValue !== undefined && entryValue !== null && entryValue !== "")}
|
|
391
412
|
size={"medium"}
|
|
392
413
|
onChange={(event) => {
|
|
@@ -404,17 +425,17 @@ function MapKeyValueRow<T extends Record<string, any>>({
|
|
|
404
425
|
</IconButton>}
|
|
405
426
|
>
|
|
406
427
|
<MenuItem dense
|
|
407
|
-
onClick={() => doUpdateDataType("string")}>string</MenuItem>
|
|
428
|
+
onClick={() => doUpdateDataType("string")}>{t("string")}</MenuItem>
|
|
408
429
|
<MenuItem dense
|
|
409
|
-
onClick={() => doUpdateDataType("number")}>number</MenuItem>
|
|
430
|
+
onClick={() => doUpdateDataType("number")}>{t("number")}</MenuItem>
|
|
410
431
|
<MenuItem dense
|
|
411
|
-
onClick={() => doUpdateDataType("boolean")}>boolean</MenuItem>
|
|
432
|
+
onClick={() => doUpdateDataType("boolean")}>{t("boolean")}</MenuItem>
|
|
412
433
|
<MenuItem dense
|
|
413
|
-
onClick={() => doUpdateDataType("date")}>date</MenuItem>
|
|
434
|
+
onClick={() => doUpdateDataType("date")}>{t("date")}</MenuItem>
|
|
414
435
|
<MenuItem dense
|
|
415
|
-
onClick={() => doUpdateDataType("map")}>map</MenuItem>
|
|
436
|
+
onClick={() => doUpdateDataType("map")}>{t("map")}</MenuItem>
|
|
416
437
|
<MenuItem dense
|
|
417
|
-
onClick={() => doUpdateDataType("array")}>array</MenuItem>
|
|
438
|
+
onClick={() => doUpdateDataType("array")}>{t("array")}</MenuItem>
|
|
418
439
|
</Menu>
|
|
419
440
|
|
|
420
441
|
<IconButton aria-label="delete"
|
|
@@ -446,6 +467,7 @@ function ArrayKeyValueRow<T>({
|
|
|
446
467
|
}) {
|
|
447
468
|
|
|
448
469
|
const { locale } = useCustomizationController();
|
|
470
|
+
const { t } = useTranslation();
|
|
449
471
|
const [selectedDataType, setSelectedDataType] = useState<DataType>(getDataType(value) ?? "string");
|
|
450
472
|
|
|
451
473
|
function doUpdateDataType(dataType: DataType) {
|
|
@@ -487,7 +509,7 @@ function ArrayKeyValueRow<T>({
|
|
|
487
509
|
}}/>;
|
|
488
510
|
} else if (dataType === "array") {
|
|
489
511
|
return <Typography variant={"caption"}>
|
|
490
|
-
|
|
512
|
+
{t("arrays_of_arrays_not_supported")}
|
|
491
513
|
</Typography>;
|
|
492
514
|
} else if (dataType === "map") {
|
|
493
515
|
return <div className={cls(defaultBorderMixin, "ml-2 pl-2 border-l border-solid")}>
|
|
@@ -499,7 +521,7 @@ function ArrayKeyValueRow<T>({
|
|
|
499
521
|
} else {
|
|
500
522
|
return <Typography
|
|
501
523
|
variant={"caption"}>
|
|
502
|
-
{
|
|
524
|
+
{t("data_type_not_supported", { dataType })}
|
|
503
525
|
</Typography>;
|
|
504
526
|
}
|
|
505
527
|
}
|
|
@@ -519,15 +541,15 @@ function ArrayKeyValueRow<T>({
|
|
|
519
541
|
<ArrowDropDownIcon/>
|
|
520
542
|
</IconButton>}>
|
|
521
543
|
<MenuItem dense
|
|
522
|
-
onClick={() => doUpdateDataType("string")}>string</MenuItem>
|
|
544
|
+
onClick={() => doUpdateDataType("string")}>{t("string")}</MenuItem>
|
|
523
545
|
<MenuItem dense
|
|
524
|
-
onClick={() => doUpdateDataType("number")}>number</MenuItem>
|
|
546
|
+
onClick={() => doUpdateDataType("number")}>{t("number")}</MenuItem>
|
|
525
547
|
<MenuItem dense
|
|
526
|
-
onClick={() => doUpdateDataType("boolean")}>boolean</MenuItem>
|
|
548
|
+
onClick={() => doUpdateDataType("boolean")}>{t("boolean")}</MenuItem>
|
|
527
549
|
<MenuItem dense
|
|
528
|
-
onClick={() => doUpdateDataType("map")}>map</MenuItem>
|
|
550
|
+
onClick={() => doUpdateDataType("map")}>{t("map")}</MenuItem>
|
|
529
551
|
<MenuItem dense
|
|
530
|
-
onClick={() => doUpdateDataType("date")}>date</MenuItem>
|
|
552
|
+
onClick={() => doUpdateDataType("date")}>{t("date")}</MenuItem>
|
|
531
553
|
</Menu>
|
|
532
554
|
|
|
533
555
|
</Typography>
|
|
@@ -6,7 +6,8 @@ import { getIconForProperty, isHidden, isReadOnly, pick } from "../../util";
|
|
|
6
6
|
import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
|
|
7
7
|
import { FormEntry } from "../components/FormEntry";
|
|
8
8
|
import { PropertyFieldBinding } from "../PropertyFieldBinding";
|
|
9
|
-
import { cls, ExpandablePanel, InputLabel, Select, SelectItem } from "@firecms/ui";
|
|
9
|
+
import { cls, ExpandablePanel, InputLabel, Select, SelectItem, IconButton, CloseIcon } from "@firecms/ui";
|
|
10
|
+
import { useTranslation } from "../../hooks";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Field that renders the children property fields
|
|
@@ -27,7 +28,8 @@ export function MapFieldBinding({
|
|
|
27
28
|
includeDescription,
|
|
28
29
|
autoFocus,
|
|
29
30
|
context,
|
|
30
|
-
onPropertyChange
|
|
31
|
+
onPropertyChange,
|
|
32
|
+
setValue
|
|
31
33
|
}: FieldProps<Record<string, any>>) {
|
|
32
34
|
|
|
33
35
|
const pickOnlySomeKeys = property.pickOnlySomeKeys || false;
|
|
@@ -91,7 +93,7 @@ export function MapFieldBinding({
|
|
|
91
93
|
}
|
|
92
94
|
</div>
|
|
93
95
|
|
|
94
|
-
{/*{pickOnlySomeKeys && buildPickKeysSelect(disabled, property.properties, setValue, value)}*/}
|
|
96
|
+
{/*{pickOnlySomeKeys && buildPickKeysSelect(disabled, property.properties, setValue, value, t)}*/}
|
|
95
97
|
|
|
96
98
|
</>
|
|
97
99
|
;
|
|
@@ -107,12 +109,26 @@ export function MapFieldBinding({
|
|
|
107
109
|
}}
|
|
108
110
|
className={property.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
109
111
|
innerClassName={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2 bg-white dark:bg-surface-900"}
|
|
110
|
-
title={<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
title={<div className="flex items-center w-full">
|
|
113
|
+
<LabelWithIconAndTooltip
|
|
114
|
+
propertyKey={propertyKey}
|
|
115
|
+
icon={getIconForProperty(property, "small")}
|
|
116
|
+
required={property.validation?.required}
|
|
117
|
+
title={property.name}
|
|
118
|
+
className={"text-text-secondary dark:text-text-secondary-dark flex-grow"} />
|
|
119
|
+
{(property.nullable || property.clearable) && !disabled && (
|
|
120
|
+
<IconButton
|
|
121
|
+
size="small"
|
|
122
|
+
onClick={(e) => {
|
|
123
|
+
e.stopPropagation();
|
|
124
|
+
e.preventDefault();
|
|
125
|
+
setValue(null);
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
<CloseIcon size={"small"}/>
|
|
129
|
+
</IconButton>
|
|
130
|
+
)}
|
|
131
|
+
</div>}>
|
|
116
132
|
{mapFormView}
|
|
117
133
|
</ExpandablePanel>}
|
|
118
134
|
|
|
@@ -128,7 +144,7 @@ export function MapFieldBinding({
|
|
|
128
144
|
);
|
|
129
145
|
}
|
|
130
146
|
|
|
131
|
-
const buildPickKeysSelect = (disabled: boolean, properties: Properties, setValue: (value: any) => void, value: any) => {
|
|
147
|
+
const buildPickKeysSelect = (disabled: boolean, properties: Properties, setValue: (value: any) => void, value: any, t: any) => {
|
|
132
148
|
|
|
133
149
|
const keys = Object.keys(properties)
|
|
134
150
|
.filter((key) => !value || !(key in value));
|
|
@@ -143,7 +159,7 @@ const buildPickKeysSelect = (disabled: boolean, properties: Properties, setValue
|
|
|
143
159
|
if (!keys.length) return <></>;
|
|
144
160
|
|
|
145
161
|
return <div className={"m-4"}>
|
|
146
|
-
<InputLabel>
|
|
162
|
+
<InputLabel>{t("add_property")}</InputLabel>
|
|
147
163
|
<Select
|
|
148
164
|
value={""}
|
|
149
165
|
size={"large"}
|
|
@@ -11,9 +11,14 @@ import {
|
|
|
11
11
|
useAuthController,
|
|
12
12
|
useStorageSource
|
|
13
13
|
} from "../../index";
|
|
14
|
-
import { cls, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundMixin } from "@firecms/ui";
|
|
15
|
-
import {
|
|
14
|
+
import { cls, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundMixin, IconButton, CloseIcon } from "@firecms/ui";
|
|
15
|
+
import type { FireCMSEditorProps } from "../../editor";
|
|
16
16
|
import { resolveProperty, resolveStorageFilenameString, resolveStoragePathString } from "../../util";
|
|
17
|
+
import { isImageFile, resizeImage } from "../../util/useStorageUploadController";
|
|
18
|
+
import { lazyEager } from "../../util/lazy_eager";
|
|
19
|
+
import { CircularProgressCenter } from "../../components/CircularProgressCenter";
|
|
20
|
+
|
|
21
|
+
const FireCMSEditor = lazyEager<typeof import("../../editor/editor")["FireCMSEditor"]>(() => import("../../editor/editor"), "FireCMSEditor");
|
|
17
22
|
|
|
18
23
|
interface MarkdownEditorFieldProps {
|
|
19
24
|
highlight?: { from: number, to: number };
|
|
@@ -50,17 +55,17 @@ export function MarkdownEditorFieldBinding({
|
|
|
50
55
|
const internalValue = useRef<string | null>(value);
|
|
51
56
|
|
|
52
57
|
const onContentChange = useCallback((content: string) => {
|
|
53
|
-
if (content === value || (value === null && content === "")) {
|
|
58
|
+
if (content === value || ((value === null || value === undefined) && content === "")) {
|
|
54
59
|
return;
|
|
55
60
|
}
|
|
56
61
|
internalValue.current = content;
|
|
57
62
|
setValue(content);
|
|
58
|
-
}, [setValue]);
|
|
63
|
+
}, [setValue, value]);
|
|
59
64
|
|
|
60
65
|
useEffect(() => {
|
|
61
66
|
if (internalValue.current !== value) {
|
|
62
67
|
internalValue.current = value;
|
|
63
|
-
setFieldVersion(
|
|
68
|
+
setFieldVersion(v => v + 1);
|
|
64
69
|
}
|
|
65
70
|
}, [value]);
|
|
66
71
|
|
|
@@ -112,42 +117,74 @@ export function MarkdownEditorFieldBinding({
|
|
|
112
117
|
// Extract markdown config from property - can be boolean or object
|
|
113
118
|
const markdownConfig = typeof property.markdown === 'object' ? property.markdown : undefined;
|
|
114
119
|
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
120
|
+
const handleImageUpload = async (file: File) => {
|
|
121
|
+
const imageResize = storage?.imageResize;
|
|
122
|
+
const legacyCompression = storage?.imageCompression;
|
|
123
|
+
if ((imageResize || legacyCompression) && isImageFile(file)) {
|
|
124
|
+
file = await resizeImage(file, imageResize, legacyCompression);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const storagePath = storagePathBuilder(file);
|
|
128
|
+
const fileName = await fileNameBuilder(file);
|
|
129
|
+
const result = await storageSource.uploadFile({
|
|
130
|
+
file,
|
|
131
|
+
fileName,
|
|
132
|
+
path: storagePath,
|
|
133
|
+
});
|
|
134
|
+
const downloadConfig = await storageSource.getDownloadURL(result.path);
|
|
135
|
+
const url = downloadConfig.url;
|
|
136
|
+
if (!url) {
|
|
137
|
+
throw new Error("Error uploading image");
|
|
138
|
+
}
|
|
139
|
+
return url;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const editor = (
|
|
143
|
+
<React.Suspense fallback={<CircularProgressCenter />}>
|
|
144
|
+
<FireCMSEditor
|
|
145
|
+
key={context.formex.version + fieldVersion}
|
|
146
|
+
content={value}
|
|
147
|
+
onMarkdownContentChange={onContentChange}
|
|
148
|
+
version={context.formex.version + fieldVersion}
|
|
149
|
+
highlight={highlight}
|
|
150
|
+
disabled={disabled}
|
|
151
|
+
markdownConfig={markdownConfig}
|
|
152
|
+
handleImageUpload={handleImageUpload}
|
|
153
|
+
{...editorProps}
|
|
154
|
+
/>
|
|
155
|
+
</React.Suspense>
|
|
156
|
+
);
|
|
139
157
|
|
|
140
158
|
if (minimalistView)
|
|
141
|
-
return
|
|
159
|
+
return (
|
|
160
|
+
<>
|
|
161
|
+
{editor}
|
|
162
|
+
</>
|
|
163
|
+
);
|
|
142
164
|
|
|
143
165
|
return (
|
|
144
166
|
<>
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
167
|
+
<div className="flex items-center w-full">
|
|
168
|
+
<LabelWithIconAndTooltip
|
|
169
|
+
propertyKey={propertyKey}
|
|
170
|
+
icon={getIconForProperty(property, "small")}
|
|
171
|
+
required={property.validation?.required}
|
|
172
|
+
title={property.name}
|
|
173
|
+
className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"} />
|
|
174
|
+
<div className="flex-grow"/>
|
|
175
|
+
{(property.nullable || property.clearable) && !disabled && (
|
|
176
|
+
<IconButton
|
|
177
|
+
size="small"
|
|
178
|
+
onClick={(e) => {
|
|
179
|
+
e.stopPropagation();
|
|
180
|
+
e.preventDefault();
|
|
181
|
+
setValue(null);
|
|
182
|
+
}}
|
|
183
|
+
>
|
|
184
|
+
<CloseIcon size={"small"}/>
|
|
185
|
+
</IconButton>
|
|
186
|
+
)}
|
|
187
|
+
</div>
|
|
151
188
|
<div
|
|
152
189
|
className={cls("rounded-md", fieldBackgroundMixin, disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin)}>
|
|
153
190
|
{editor}
|
|
@@ -4,7 +4,7 @@ import { EnumType, FieldProps, ResolvedProperty } from "../../types";
|
|
|
4
4
|
import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
|
|
5
5
|
import { EnumValuesChip } from "../../preview";
|
|
6
6
|
import { enumToObjectEntries, getIconForProperty, getLabelOrConfigFrom } from "../../util";
|
|
7
|
-
import { CloseIcon, MultiSelect, MultiSelectItem } from "@firecms/ui";
|
|
7
|
+
import { CloseIcon, MultiSelect, MultiSelectItem, IconButton } from "@firecms/ui";
|
|
8
8
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -93,6 +93,20 @@ export function MultiSelectFieldBinding({
|
|
|
93
93
|
required={property.validation?.required}
|
|
94
94
|
title={property.name}
|
|
95
95
|
className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
|
|
96
|
+
endAdornment={
|
|
97
|
+
(property.nullable || property.clearable) && !disabled && value !== null && value !== undefined ? (
|
|
98
|
+
<IconButton
|
|
99
|
+
size="small"
|
|
100
|
+
onClick={(e) => {
|
|
101
|
+
e.stopPropagation();
|
|
102
|
+
e.preventDefault();
|
|
103
|
+
setValue(null);
|
|
104
|
+
}}
|
|
105
|
+
>
|
|
106
|
+
<CloseIcon size={"small"}/>
|
|
107
|
+
</IconButton>
|
|
108
|
+
) : undefined
|
|
109
|
+
}
|
|
96
110
|
onValueChange={(updatedValue: string[]) => {
|
|
97
111
|
let newValue: EnumType[] | null;
|
|
98
112
|
if (of && (of as ResolvedProperty)?.dataType === "number") {
|
|
@@ -8,7 +8,7 @@ import { ReferencePreview } from "../../preview";
|
|
|
8
8
|
import { getIconForProperty, IconForView } from "../../util";
|
|
9
9
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
10
10
|
import { EntityPreviewContainer } from "../../components/EntityPreview";
|
|
11
|
-
import { cls } from "@firecms/ui";
|
|
11
|
+
import { cls, IconButton, CloseIcon } from "@firecms/ui";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Field that opens a reference selection dialog and stores the entity ID as a string.
|
|
@@ -98,16 +98,30 @@ function ReferenceAsStringFieldBindingInternal({
|
|
|
98
98
|
|
|
99
99
|
{collection && <>
|
|
100
100
|
|
|
101
|
-
{referenceValue && <
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
101
|
+
{referenceValue && <div className="flex items-center gap-2">
|
|
102
|
+
<ReferencePreview
|
|
103
|
+
disabled={!path}
|
|
104
|
+
previewProperties={property.reference?.previewProperties}
|
|
105
|
+
hover={!disabled}
|
|
106
|
+
size={size}
|
|
107
|
+
onClick={disabled || isSubmitting ? undefined : onEntryClick}
|
|
108
|
+
reference={referenceValue}
|
|
109
|
+
includeEntityLink={property.reference?.includeEntityLink}
|
|
110
|
+
includeId={property.reference?.includeId}
|
|
111
|
+
/>
|
|
112
|
+
{(property.nullable || property.clearable) && !disabled && (
|
|
113
|
+
<IconButton
|
|
114
|
+
size="small"
|
|
115
|
+
onClick={(e) => {
|
|
116
|
+
e.stopPropagation();
|
|
117
|
+
e.preventDefault();
|
|
118
|
+
setValue(null);
|
|
119
|
+
}}
|
|
120
|
+
>
|
|
121
|
+
<CloseIcon size={"small"}/>
|
|
122
|
+
</IconButton>
|
|
123
|
+
)}
|
|
124
|
+
</div>}
|
|
111
125
|
|
|
112
126
|
{!value && <div className="justify-center text-left">
|
|
113
127
|
<EntityPreviewContainer
|
|
@@ -9,7 +9,7 @@ import { EmptyValue, ReferencePreview } from "../../preview";
|
|
|
9
9
|
import { getIconForProperty, getReferenceFrom, IconForView } from "../../util";
|
|
10
10
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
11
11
|
import { EntityPreviewContainer } from "../../components/EntityPreview";
|
|
12
|
-
import { cls } from "@firecms/ui";
|
|
12
|
+
import { cls, IconButton, CloseIcon } from "@firecms/ui";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Field that opens a reference selection dialog.
|
|
@@ -97,16 +97,30 @@ function ReferenceFieldBindingInternal({
|
|
|
97
97
|
|
|
98
98
|
{collection && <>
|
|
99
99
|
|
|
100
|
-
{value && <
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
100
|
+
{value && <div className="flex items-center gap-2">
|
|
101
|
+
<ReferencePreview
|
|
102
|
+
disabled={!property.path}
|
|
103
|
+
previewProperties={property.previewProperties}
|
|
104
|
+
hover={!disabled}
|
|
105
|
+
size={size}
|
|
106
|
+
onClick={disabled || isSubmitting ? undefined : onEntryClick}
|
|
107
|
+
reference={value}
|
|
108
|
+
includeEntityLink={property.includeEntityLink}
|
|
109
|
+
includeId={property.includeId}
|
|
110
|
+
/>
|
|
111
|
+
{(property.nullable || property.clearable) && !disabled && (
|
|
112
|
+
<IconButton
|
|
113
|
+
size="small"
|
|
114
|
+
onClick={(e) => {
|
|
115
|
+
e.stopPropagation();
|
|
116
|
+
e.preventDefault();
|
|
117
|
+
setValue(null);
|
|
118
|
+
}}
|
|
119
|
+
>
|
|
120
|
+
<CloseIcon size={"small"}/>
|
|
121
|
+
</IconButton>
|
|
122
|
+
)}
|
|
123
|
+
</div>}
|
|
110
124
|
|
|
111
125
|
{!value && <div className="justify-center text-left">
|
|
112
126
|
<EntityPreviewContainer className={cls("px-6 h-16 text-sm font-medium flex items-center gap-6",
|
|
@@ -4,9 +4,10 @@ import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
|
|
|
4
4
|
import { ArrayContainer, ArrayEntryParams, ErrorBoundary } from "../../components";
|
|
5
5
|
import { getArrayResolvedProperties, getDefaultValueFor, getIconForProperty, mergeDeep } from "../../util";
|
|
6
6
|
import { PropertyFieldBinding } from "../PropertyFieldBinding";
|
|
7
|
-
import { ExpandablePanel, Typography } from "@firecms/ui";
|
|
7
|
+
import { ExpandablePanel, Typography, IconButton, CloseIcon } from "@firecms/ui";
|
|
8
8
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
9
9
|
import { useAuthController } from "../../hooks";
|
|
10
|
+
import { useTranslation } from "../../hooks/useTranslation";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Generic array field that allows reordering and renders the child property
|
|
@@ -34,6 +35,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
|
|
|
34
35
|
|
|
35
36
|
const authController = useAuthController();
|
|
36
37
|
const minimalistView = minimalistViewProp || property.minimalistView;
|
|
38
|
+
const { t } = useTranslation();
|
|
37
39
|
|
|
38
40
|
if (!property.of)
|
|
39
41
|
throw Error("RepeatFieldBinding misconfiguration. Property `of` not set");
|
|
@@ -87,7 +89,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
|
|
|
87
89
|
const canAddElements = !property.disabled && !isSubmitting && !disabled && (property.canAddElements || property.canAddElements === undefined);
|
|
88
90
|
const sortable = property.sortable === undefined ? true : property.sortable;
|
|
89
91
|
const arrayContainer = <ArrayContainer droppableId={propertyKey}
|
|
90
|
-
addLabel={property.name ? "
|
|
92
|
+
addLabel={property.name ? t("add_to_field", { fieldName: property.name }) : t("add_entry")}
|
|
91
93
|
value={value}
|
|
92
94
|
buildEntry={buildEntry}
|
|
93
95
|
onInternalIdAdded={setLastAddedId}
|
|
@@ -99,15 +101,28 @@ export function RepeatFieldBinding<T extends Array<any>>({
|
|
|
99
101
|
className={property.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
100
102
|
/>;
|
|
101
103
|
|
|
102
|
-
const title = (
|
|
104
|
+
const title = (<div className="flex items-center w-full">
|
|
103
105
|
<LabelWithIconAndTooltip
|
|
104
106
|
propertyKey={propertyKey}
|
|
105
107
|
icon={getIconForProperty(property, "small")}
|
|
106
108
|
required={property.validation?.required}
|
|
107
109
|
title={property.name}
|
|
108
|
-
className={"
|
|
109
|
-
{Array.isArray(value) && <
|
|
110
|
-
|
|
110
|
+
className={"text-text-secondary dark:text-text-secondary-dark"}/>
|
|
111
|
+
{Array.isArray(value) && <span className={"text-sm text-text-secondary dark:text-text-secondary-dark ml-1"}>({value.length})</span>}
|
|
112
|
+
<div className="flex-grow"/>
|
|
113
|
+
{(property.nullable || property.clearable) && !disabled && (
|
|
114
|
+
<IconButton
|
|
115
|
+
size="small"
|
|
116
|
+
onClick={(e) => {
|
|
117
|
+
e.stopPropagation();
|
|
118
|
+
e.preventDefault();
|
|
119
|
+
setValue(null);
|
|
120
|
+
}}
|
|
121
|
+
>
|
|
122
|
+
<CloseIcon size={"small"}/>
|
|
123
|
+
</IconButton>
|
|
124
|
+
)}
|
|
125
|
+
</div>);
|
|
111
126
|
|
|
112
127
|
return (
|
|
113
128
|
|
|
@@ -66,11 +66,13 @@ export function SelectFieldBinding<T extends EnumType>({
|
|
|
66
66
|
/>
|
|
67
67
|
</PropertyIdCopyTooltip>}
|
|
68
68
|
endAdornment={
|
|
69
|
-
property.clearable && !disabled &&
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
(property.nullable || property.clearable) && !disabled && value !== null && value !== undefined ? (
|
|
70
|
+
<IconButton
|
|
71
|
+
size="small"
|
|
72
|
+
onClick={handleClearClick}>
|
|
73
|
+
<CloseIcon size={"small"}/>
|
|
74
|
+
</IconButton>
|
|
75
|
+
) : undefined
|
|
74
76
|
}
|
|
75
77
|
onValueChange={(updatedValue: string) => {
|
|
76
78
|
const newValue = updatedValue
|