@firecms/collection_editor 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.
Files changed (119) hide show
  1. package/dist/ConfigControllerProvider.d.ts +6 -0
  2. package/dist/api/generateCollectionApi.d.ts +71 -0
  3. package/dist/api/index.d.ts +1 -0
  4. package/dist/index.d.ts +5 -1
  5. package/dist/index.es.js +15234 -8138
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/index.umd.js +15199 -8103
  8. package/dist/index.umd.js.map +1 -1
  9. package/dist/locales/de.d.ts +120 -0
  10. package/dist/locales/en.d.ts +120 -0
  11. package/dist/locales/es.d.ts +120 -0
  12. package/dist/locales/fr.d.ts +120 -0
  13. package/dist/locales/hi.d.ts +120 -0
  14. package/dist/locales/it.d.ts +120 -0
  15. package/dist/locales/pt.d.ts +120 -0
  16. package/dist/types/collection_editor_controller.d.ts +14 -0
  17. package/dist/types/collection_inference.d.ts +8 -2
  18. package/dist/types/config_controller.d.ts +31 -1
  19. package/dist/ui/AddKanbanColumnAction.d.ts +11 -0
  20. package/dist/ui/KanbanSetupAction.d.ts +10 -0
  21. package/dist/ui/collection_editor/AICollectionGeneratorPopover.d.ts +37 -0
  22. package/dist/ui/collection_editor/AIModifiedPathsContext.d.ts +20 -0
  23. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +2 -3
  24. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +24 -0
  25. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +4 -1
  26. package/dist/ui/collection_editor/CollectionJsonImportDialog.d.ts +7 -0
  27. package/dist/ui/collection_editor/CollectionYupValidation.d.ts +9 -13
  28. package/dist/ui/collection_editor/DisplaySettingsForm.d.ts +3 -0
  29. package/dist/ui/collection_editor/EntityActionsEditTab.d.ts +2 -1
  30. package/dist/ui/collection_editor/ExtendSettingsForm.d.ts +14 -0
  31. package/dist/ui/collection_editor/GeneralSettingsForm.d.ts +7 -0
  32. package/dist/ui/collection_editor/KanbanConfigSection.d.ts +4 -0
  33. package/dist/ui/collection_editor/PropertyEditView.d.ts +6 -1
  34. package/dist/ui/collection_editor/PropertyTree.d.ts +2 -1
  35. package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +2 -1
  36. package/dist/ui/collection_editor/ViewModeSwitch.d.ts +6 -0
  37. package/dist/ui/collection_editor/properties/EnumPropertyField.d.ts +2 -1
  38. package/dist/ui/collection_editor/properties/conditions/ConditionsEditor.d.ts +10 -0
  39. package/dist/ui/collection_editor/properties/conditions/ConditionsPanel.d.ts +2 -0
  40. package/dist/ui/collection_editor/properties/conditions/EnumConditionsEditor.d.ts +6 -0
  41. package/dist/ui/collection_editor/properties/conditions/index.d.ts +6 -0
  42. package/dist/ui/collection_editor/properties/conditions/property_paths.d.ts +19 -0
  43. package/dist/useCollectionEditorPlugin.d.ts +7 -1
  44. package/dist/utils/validateCollectionJson.d.ts +22 -0
  45. package/package.json +15 -15
  46. package/src/ConfigControllerProvider.tsx +82 -47
  47. package/src/api/generateCollectionApi.ts +119 -0
  48. package/src/api/index.ts +1 -0
  49. package/src/index.ts +28 -1
  50. package/src/locales/de.ts +125 -0
  51. package/src/locales/en.ts +145 -0
  52. package/src/locales/es.ts +125 -0
  53. package/src/locales/fr.ts +125 -0
  54. package/src/locales/hi.ts +125 -0
  55. package/src/locales/it.ts +125 -0
  56. package/src/locales/pt.ts +125 -0
  57. package/src/types/collection_editor_controller.tsx +16 -3
  58. package/src/types/collection_inference.ts +15 -2
  59. package/src/types/config_controller.tsx +37 -1
  60. package/src/ui/AddKanbanColumnAction.tsx +203 -0
  61. package/src/ui/EditorCollectionAction.tsx +3 -3
  62. package/src/ui/EditorCollectionActionStart.tsx +1 -2
  63. package/src/ui/EditorEntityAction.tsx +3 -2
  64. package/src/ui/HomePageEditorCollectionAction.tsx +41 -13
  65. package/src/ui/KanbanSetupAction.tsx +38 -0
  66. package/src/ui/MissingReferenceWidget.tsx +1 -1
  67. package/src/ui/NewCollectionButton.tsx +4 -2
  68. package/src/ui/NewCollectionCard.tsx +7 -4
  69. package/src/ui/PropertyAddColumnComponent.tsx +4 -3
  70. package/src/ui/collection_editor/AICollectionGeneratorPopover.tsx +243 -0
  71. package/src/ui/collection_editor/AIModifiedPathsContext.tsx +88 -0
  72. package/src/ui/collection_editor/CollectionDetailsForm.tsx +222 -268
  73. package/src/ui/collection_editor/CollectionEditorDialog.tsx +270 -204
  74. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +138 -71
  75. package/src/ui/collection_editor/CollectionJsonImportDialog.tsx +171 -0
  76. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +202 -101
  77. package/src/ui/collection_editor/DisplaySettingsForm.tsx +335 -0
  78. package/src/ui/collection_editor/EntityActionsEditTab.tsx +106 -97
  79. package/src/ui/collection_editor/EntityActionsSelectDialog.tsx +8 -10
  80. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +5 -7
  81. package/src/ui/collection_editor/EnumForm.tsx +153 -102
  82. package/src/ui/collection_editor/ExtendSettingsForm.tsx +94 -0
  83. package/src/ui/collection_editor/GeneralSettingsForm.tsx +335 -0
  84. package/src/ui/collection_editor/GetCodeDialog.tsx +63 -41
  85. package/src/ui/collection_editor/KanbanConfigSection.tsx +209 -0
  86. package/src/ui/collection_editor/LayoutModeSwitch.tsx +27 -43
  87. package/src/ui/collection_editor/PropertyEditView.tsx +272 -199
  88. package/src/ui/collection_editor/PropertyFieldPreview.tsx +1 -1
  89. package/src/ui/collection_editor/PropertyTree.tsx +130 -58
  90. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +169 -163
  91. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +0 -2
  92. package/src/ui/collection_editor/ViewModeSwitch.tsx +43 -0
  93. package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +6 -3
  94. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +5 -2
  95. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +0 -2
  96. package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +4 -1
  97. package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +6 -4
  98. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +126 -42
  99. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +32 -24
  100. package/src/ui/collection_editor/properties/MapPropertyField.tsx +8 -9
  101. package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +128 -53
  102. package/src/ui/collection_editor/properties/NumberPropertyField.tsx +3 -1
  103. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +6 -9
  104. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +65 -49
  105. package/src/ui/collection_editor/properties/StringPropertyField.tsx +3 -1
  106. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +12 -10
  107. package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +23 -4
  108. package/src/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +866 -0
  109. package/src/ui/collection_editor/properties/conditions/ConditionsPanel.tsx +28 -0
  110. package/src/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +599 -0
  111. package/src/ui/collection_editor/properties/conditions/index.ts +6 -0
  112. package/src/ui/collection_editor/properties/conditions/property_paths.ts +92 -0
  113. package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +5 -2
  114. package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +7 -5
  115. package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +10 -7
  116. package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +11 -9
  117. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +5 -2
  118. package/src/useCollectionEditorPlugin.tsx +53 -22
  119. package/src/utils/validateCollectionJson.ts +380 -0
@@ -3,12 +3,14 @@ import { NumberPropertyValidation } from "./validation/NumberPropertyValidation"
3
3
  import { ValidationPanel } from "./validation/ValidationPanel";
4
4
  import { TextField } from "@firecms/ui";
5
5
  import { getIn, useFormex } from "@firecms/formex";
6
+ import { useTranslation } from "@firecms/core";
6
7
 
7
8
  export function NumberPropertyField({ disabled }: {
8
9
  disabled: boolean;
9
10
  }) {
10
11
 
11
12
  const { values, setFieldValue } = useFormex();
13
+ const { t } = useTranslation();
12
14
 
13
15
  return (
14
16
  <>
@@ -29,7 +31,7 @@ export function NumberPropertyField({ disabled }: {
29
31
  onChange={(e: any) => {
30
32
  setFieldValue("defaultValue", e.target.value === "" ? undefined : parseFloat(e.target.value));
31
33
  }}
32
- label={"Default value"}
34
+ label={t("default_value")}
33
35
  value={getIn(values, "defaultValue") ?? ""}/>
34
36
 
35
37
  </div>
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { Field, getIn, useFormex } from "@firecms/formex";
3
- import { FieldCaption, IconForView, NumberProperty, StringProperty, useNavigationController } from "@firecms/core";
3
+ import { FieldCaption, IconForView, NumberProperty, StringProperty, useNavigationController, useTranslation } from "@firecms/core";
4
4
  import { CircularProgress, Select, SelectGroup, SelectItem, Typography, } from "@firecms/ui";
5
5
 
6
6
  export function ReferencePropertyField({
@@ -41,7 +41,7 @@ export function ReferencePropertyField({
41
41
  <Field name={pathPath}
42
42
  pathPath={pathPath}
43
43
  type="select"
44
- disabled={(existing && Boolean(pathValue)) || disabled}
44
+ disabled={disabled}
45
45
  value={pathValue}
46
46
  error={pathError}
47
47
  handleChange={handleChange}
@@ -69,6 +69,7 @@ export function CollectionsSelect({
69
69
  }) {
70
70
 
71
71
  const navigation = useNavigationController();
72
+ const { t } = useTranslation();
72
73
 
73
74
  if (!navigation)
74
75
  return <div className={"col-span-12"}>
@@ -94,7 +95,7 @@ export function CollectionsSelect({
94
95
  size={"large"}
95
96
  fullWidth={true}
96
97
  onChange={handleChange}
97
- label={"Target collection"}
98
+ label={t("target_collection")}
98
99
  renderValue={(selected) => {
99
100
  const selectedCollection = collections.find(collection => collection.id === selected || collection.path === selected);
100
101
  if (!selectedCollection) return null;
@@ -111,7 +112,7 @@ export function CollectionsSelect({
111
112
  {...props}>
112
113
 
113
114
  {groups.flatMap((group) => (
114
- <SelectGroup label={group || "Views"}
115
+ <SelectGroup label={group || t("views_group")}
115
116
  key={`group_${group}`}>
116
117
  {
117
118
  collections.filter(collection => collection.group === group)
@@ -134,7 +135,7 @@ export function CollectionsSelect({
134
135
  </SelectGroup>
135
136
  ))}
136
137
 
137
- {ungroupedCollections && <SelectGroup label={"Views"}>
138
+ {ungroupedCollections && <SelectGroup label={t("views_group")}>
138
139
  {ungroupedCollections
139
140
  .map((collection) => {
140
141
  return <SelectItem key={collection.id ?? collection.path}
@@ -155,10 +156,6 @@ export function CollectionsSelect({
155
156
 
156
157
  </Select>
157
158
 
158
- <FieldCaption>
159
- You can only edit the reference collection upon field
160
- creation.
161
- </FieldCaption>
162
159
  </>
163
160
  );
164
161
  }
@@ -16,14 +16,7 @@ import { GeneralPropertyValidation } from "./validation/GeneralPropertyValidatio
16
16
  import { ArrayPropertyValidation } from "./validation/ArrayPropertyValidation";
17
17
  import { ValidationPanel } from "./validation/ValidationPanel";
18
18
  import { SwitchControl } from "../SwitchControl";
19
-
20
- const fileTypes: Record<string, string> = {
21
- "image/*": "Images",
22
- "video/*": "Videos",
23
- "audio/*": "Audio files",
24
- "application/*": "Files (pdf, zip, csv, excel...)",
25
- "text/*": "Text files"
26
- }
19
+ import { useTranslation } from "@firecms/core";
27
20
 
28
21
  export function StoragePropertyField({
29
22
  multiple,
@@ -40,6 +33,8 @@ export function StoragePropertyField({
40
33
  setFieldValue
41
34
  } = useFormex();
42
35
 
36
+ const { t } = useTranslation();
37
+
43
38
  const baseStoragePath = multiple ? "of.storage" : "storage";
44
39
  const acceptedFiles = `${baseStoragePath}.acceptedFiles`;
45
40
 
@@ -48,6 +43,7 @@ export function StoragePropertyField({
48
43
  const maxSize = `${baseStoragePath}.maxSize`;
49
44
  const storagePath = `${baseStoragePath}.storagePath`;
50
45
  const storeUrl = `${baseStoragePath}.storeUrl`;
46
+ const includeBucketUrl = `${baseStoragePath}.includeBucketUrl`;
51
47
 
52
48
  // Image resize config paths
53
49
  const imageResize = `${baseStoragePath}.imageResize`;
@@ -72,6 +68,14 @@ export function StoragePropertyField({
72
68
  const fileTypesValue: string[] | undefined = Array.isArray(storedValue) ? storedValue : undefined;
73
69
  const allFileTypesSelected = !fileTypesValue || fileTypesValue.length === 0;
74
70
 
71
+ const fileTypes: Record<string, string> = {
72
+ "image/*": t("file_type_images"),
73
+ "video/*": t("file_type_videos"),
74
+ "audio/*": t("file_type_audio"),
75
+ "application/*": t("file_type_applications"),
76
+ "text/*": t("file_type_text")
77
+ };
78
+
75
79
  const handleTypesChange = (value: string[]) => {
76
80
  if (!value) setFieldValue(acceptedFiles, undefined);
77
81
  else setFieldValue(acceptedFiles, value);
@@ -87,11 +91,11 @@ export function StoragePropertyField({
87
91
 
88
92
  <ExpandablePanel
89
93
  title={
90
- <div className="flex flex-row text-surface-500">
94
+ <div className="flex flex-row text-surface-500 text-text-secondary dark:text-text-secondary-dark">
91
95
  <CloudUploadIcon/>
92
96
  <Typography variant={"subtitle2"}
93
97
  className="ml-4">
94
- File upload config
98
+ {t("file_upload_config")}
95
99
  </Typography>
96
100
  </div>
97
101
  }>
@@ -102,14 +106,14 @@ export function StoragePropertyField({
102
106
 
103
107
  <MultiSelect
104
108
  className={"w-full"}
105
- placeholder={"All file types allowed"}
109
+ placeholder={t("all_file_types_allowed")}
106
110
  disabled={disabled}
107
111
  name={acceptedFiles}
108
112
  value={fileTypesValue ?? []}
109
113
  onValueChange={handleTypesChange}
110
- label={allFileTypesSelected ? undefined : "Allowed file types"}
114
+ label={allFileTypesSelected ? undefined : t("allowed_file_types")}
111
115
  renderValues={(selected) => {
112
- if (!selected || selected.length === 0) return "All file types allowed";
116
+ if (!selected || selected.length === 0) return t("all_file_types_allowed");
113
117
  return selected.map((v: string) => fileTypes[v])
114
118
  .filter((v: string) => Boolean(v))
115
119
  .join(", ");
@@ -129,7 +133,7 @@ export function StoragePropertyField({
129
133
  e.stopPropagation();
130
134
  return setFieldValue(acceptedFiles, [value]);
131
135
  }}>
132
- Only
136
+ {t("only")}
133
137
  </Button>
134
138
  </MultiSelectItem>
135
139
  ))}
@@ -140,7 +144,7 @@ export function StoragePropertyField({
140
144
  <div className={"col-span-12"}>
141
145
  <Field name={fileName}
142
146
  as={DebouncedTextField}
143
- label={"File name"}
147
+ label={t("file_name_label")}
144
148
  size={"small"}
145
149
  disabled={hasFilenameCallback || disabled}
146
150
  value={hasFilenameCallback ? "-" : fileNameValue}
@@ -149,26 +153,42 @@ export function StoragePropertyField({
149
153
  <div className={"col-span-12"}>
150
154
  <Field name={storagePath}
151
155
  as={DebouncedTextField}
152
- label={"Storage path"}
156
+ label={t("storage_path_label")}
153
157
  disabled={hasStoragePathCallback || disabled}
154
158
  size={"small"}
155
159
  value={hasStoragePathCallback ? "-" : storagePathValue}
156
160
  />
157
161
  <Typography variant={"caption"} className={"ml-3.5 mt-1 mb-2"}>
158
- <p>You can use the following placeholders in
159
- the file name
160
- and storage path values:</p>
162
+ <p>{t("storage_placeholders_description")}</p>
161
163
  <ul>
162
- <li>{"{file} - Full name of the uploaded file"}</li>
163
- <li>{"{file.name} - Name of the uploaded file without extension"}</li>
164
- <li>{"{file.ext} - Extension of the uploaded file"}</li>
165
- <li>{"{entityId} - ID of the entity"}</li>
166
- <li>{"{propertyKey} - ID of this field"}</li>
167
- <li>{"{path} - Path of this entity"}</li>
168
- <li>{"{rand} - Random value used to avoid name collisions"}</li>
164
+ <li>{t("storage_placeholder_file")}</li>
165
+ <li>{t("storage_placeholder_file_name")}</li>
166
+ <li>{t("storage_placeholder_file_ext")}</li>
167
+ <li>{t("storage_placeholder_entity_id")}</li>
168
+ <li>{t("storage_placeholder_property_key")}</li>
169
+ <li>{t("storage_placeholder_path")}</li>
170
+ <li>{t("storage_placeholder_rand")}</li>
169
171
  </ul>
170
172
  </Typography>
171
173
 
174
+ <Field name={includeBucketUrl}
175
+ type="checkbox">
176
+ {({
177
+ field,
178
+ form
179
+ }: FormexFieldProps) => {
180
+ return <SwitchControl
181
+ label={t("include_bucket_url")}
182
+ disabled={existing || disabled}
183
+ form={form}
184
+ field={field}/>;
185
+ }}
186
+ </Field>
187
+
188
+ <Typography variant={"caption"} className={"ml-3.5 mt-1 mb-2"}>
189
+ {t("include_bucket_url_description")}
190
+ </Typography>
191
+
172
192
  <Field name={storeUrl}
173
193
  type="checkbox">
174
194
  {({
@@ -176,26 +196,22 @@ export function StoragePropertyField({
176
196
  form
177
197
  }: FormexFieldProps) => {
178
198
  return <SwitchControl
179
- label={"Save URL instead of storage path"}
199
+ label={t("save_url_instead_of_path")}
180
200
  disabled={existing || disabled}
181
201
  form={form}
182
- field={field}/>
202
+ field={field}/>;
183
203
  }}
184
204
  </Field>
185
205
 
186
206
  <Typography variant={"caption"} className={"ml-3.5 mt-1 mb-2"}>
187
- Turn this setting on, if you prefer to save
188
- the download
189
- URL of the uploaded file instead of the
190
- storage path.
191
- You can only change this prop upon creation.
207
+ {t("save_url_description")}
192
208
  </Typography>
193
209
  </div>
194
210
 
195
211
  <div className={"col-span-12"}>
196
212
  <DebouncedTextField name={maxSize}
197
213
  type={"number"}
198
- label={"Max size (in bytes)"}
214
+ label={t("max_size_bytes")}
199
215
  size={"small"}
200
216
  value={maxSizeValue !== undefined && maxSizeValue !== null ? maxSizeValue.toString() : ""}
201
217
  onChange={(e) => {
@@ -210,10 +226,10 @@ export function StoragePropertyField({
210
226
  <Typography variant={"subtitle2"}
211
227
  color={"secondary"}
212
228
  className={"mb-2 block"}>
213
- Image Resize Configuration
229
+ {t("image_resize_configuration")}
214
230
  </Typography>
215
231
  <Typography variant={"caption"} className={"mb-2 block text-xs"}>
216
- Automatically resize and optimize images before upload (JPEG, PNG, WebP only)
232
+ {t("image_resize_description")}
217
233
  </Typography>
218
234
  </div>
219
235
 
@@ -221,7 +237,7 @@ export function StoragePropertyField({
221
237
  <DebouncedTextField
222
238
  name={imageResizeMaxWidth}
223
239
  type={"number"}
224
- label={"Max width (px)"}
240
+ label={t("max_width_px")}
225
241
  size={"small"}
226
242
  disabled={disabled}
227
243
  value={imageResizeMaxWidthValue !== undefined && imageResizeMaxWidthValue !== null ? imageResizeMaxWidthValue.toString() : ""}
@@ -237,7 +253,7 @@ export function StoragePropertyField({
237
253
  <DebouncedTextField
238
254
  name={imageResizeMaxHeight}
239
255
  type={"number"}
240
- label={"Max height (px)"}
256
+ label={t("max_height_px")}
241
257
  size={"small"}
242
258
  disabled={disabled}
243
259
  value={imageResizeMaxHeightValue !== undefined && imageResizeMaxHeightValue !== null ? imageResizeMaxHeightValue.toString() : ""}
@@ -257,16 +273,16 @@ export function StoragePropertyField({
257
273
  size={"medium"}
258
274
  value={imageResizeModeValue || "cover"}
259
275
  onValueChange={(value) => setFieldValue(imageResizeMode, value || "cover")}
260
- label={"Resize mode"}
276
+ label={t("resize_mode")}
261
277
  renderValue={(selected) => {
262
- if (!selected) return "Cover";
263
- return selected === "contain" ? "Contain (fit within bounds)" : "Cover (fill bounds, may crop)";
278
+ if (!selected) return t("resize_cover");
279
+ return selected === "contain" ? t("resize_contain_description") : t("resize_cover_description");
264
280
  }}>
265
281
  <SelectItem value="contain">
266
- Contain (fit within bounds)
282
+ {t("resize_contain_description")}
267
283
  </SelectItem>
268
284
  <SelectItem value="cover">
269
- Cover (fill bounds, may crop)
285
+ {t("resize_cover_description")}
270
286
  </SelectItem>
271
287
  </Select>
272
288
  </div>
@@ -279,13 +295,13 @@ export function StoragePropertyField({
279
295
  name={imageResizeFormat}
280
296
  value={imageResizeFormatValue || "original"}
281
297
  onValueChange={(value) => setFieldValue(imageResizeFormat, value || "original")}
282
- label={"Output format"}
298
+ label={t("output_format")}
283
299
  renderValue={(selected) => {
284
- if (!selected) return "Original";
300
+ if (!selected) return t("format_original");
285
301
  return selected.charAt(0).toUpperCase() + selected.slice(1);
286
302
  }}>
287
303
  <SelectItem value="original">
288
- Original (keep same format)
304
+ {t("format_original_description")}
289
305
  </SelectItem>
290
306
  <SelectItem value="jpeg">
291
307
  JPEG
@@ -294,7 +310,7 @@ export function StoragePropertyField({
294
310
  PNG
295
311
  </SelectItem>
296
312
  <SelectItem value="webp">
297
- WebP (best compression)
313
+ {t("format_webp_description")}
298
314
  </SelectItem>
299
315
  </Select>
300
316
  </div>
@@ -303,7 +319,7 @@ export function StoragePropertyField({
303
319
  <DebouncedTextField
304
320
  name={imageResizeQuality}
305
321
  type={"number"}
306
- label={"Quality (0-100)"}
322
+ label={t("quality_label")}
307
323
  size={"small"}
308
324
  disabled={disabled}
309
325
  value={imageResizeQualityValue !== undefined && imageResizeQualityValue !== null ? imageResizeQualityValue.toString() : ""}
@@ -319,7 +335,7 @@ export function StoragePropertyField({
319
335
  }}
320
336
  />
321
337
  <Typography variant={"caption"} className={"ml-3.5 mt-1 mb-2"}>
322
- Higher quality = larger file size. Recommended: 80-90 for photos, 90-100 for graphics
338
+ {t("quality_hint")}
323
339
  </Typography>
324
340
  </div>
325
341
 
@@ -4,6 +4,7 @@ import { ValidationPanel } from "./validation/ValidationPanel";
4
4
  import { getIn, useFormex } from "@firecms/formex";
5
5
 
6
6
  import { TextField } from "@firecms/ui";
7
+ import { useTranslation } from "@firecms/core";
7
8
 
8
9
  export function StringPropertyField({
9
10
  widgetId,
@@ -16,6 +17,7 @@ export function StringPropertyField({
16
17
  }) {
17
18
 
18
19
  const { values, setFieldValue } = useFormex();
20
+ const { t } = useTranslation();
19
21
 
20
22
  return (
21
23
  <>
@@ -65,7 +67,7 @@ export function StringPropertyField({
65
67
  onChange={(e: any) => {
66
68
  setFieldValue("defaultValue", e.target.value === "" ? undefined : e.target.value);
67
69
  }}
68
- label={"Default value"}
70
+ label={t("default_value")}
69
71
  value={getIn(values, "defaultValue") ?? ""}/>
70
72
 
71
73
  </div>
@@ -4,6 +4,7 @@ import { ValidationPanel } from "./validation/ValidationPanel";
4
4
  import { getIn, useFormex } from "@firecms/formex";
5
5
 
6
6
  import { Select, SelectItem, TextField } from "@firecms/ui";
7
+ import { useTranslation } from "@firecms/core";
7
8
 
8
9
  export function UrlPropertyField({
9
10
  disabled,
@@ -14,6 +15,7 @@ export function UrlPropertyField({
14
15
  }) {
15
16
 
16
17
  const { values, setFieldValue } = useFormex();
18
+ const { t } = useTranslation();
17
19
 
18
20
  const urlValue = getIn(values, "url");
19
21
 
@@ -31,31 +33,31 @@ export function UrlPropertyField({
31
33
  else
32
34
  setFieldValue("url", value);
33
35
  }}
34
- label={"Preview type"}
36
+ label={t("preview_type")}
35
37
  renderValue={(value: string) => {
36
38
  switch (value) {
37
39
  case "image":
38
- return "Image";
40
+ return t("preview_image");
39
41
  case "video":
40
- return "Video";
42
+ return t("preview_video");
41
43
  case "audio":
42
- return "Audio";
44
+ return t("preview_audio");
43
45
  default:
44
- return "Display URL";
46
+ return t("display_url");
45
47
  }
46
48
  }}
47
49
  value={urlValue ?? "[NONE]"}>
48
50
  <SelectItem value={"[NONE]"}>
49
- Display URL
51
+ {t("display_url")}
50
52
  </SelectItem>
51
53
  <SelectItem value={"image"}>
52
- Image
54
+ {t("preview_image")}
53
55
  </SelectItem>
54
56
  <SelectItem value={"video"}>
55
- Video
57
+ {t("preview_video")}
56
58
  </SelectItem>
57
59
  <SelectItem value={"audio"}>
58
- Audio
60
+ {t("preview_audio")}
59
61
  </SelectItem>
60
62
  </Select>
61
63
  </div>
@@ -81,7 +83,7 @@ export function UrlPropertyField({
81
83
  onChange={(e: any) => {
82
84
  setFieldValue("defaultValue", e.target.value === "" ? undefined : e.target.value);
83
85
  }}
84
- label={"Default value"}
86
+ label={t("default_value")}
85
87
  value={getIn(values, "defaultValue") ?? ""}/>
86
88
 
87
89
  </div>
@@ -2,14 +2,18 @@ import React from "react";
2
2
 
3
3
  import { Field, FormexFieldProps } from "@firecms/formex";
4
4
  import { SwitchControl } from "../../SwitchControl";
5
+ import { useTranslation } from "@firecms/core";
5
6
 
6
7
  export function AdvancedPropertyValidation({ disabled }: {
7
8
  disabled: boolean
8
9
  }) {
9
10
 
11
+ const { t } = useTranslation();
12
+
10
13
  const columnWidth = "columnWidth";
11
14
  const hideFromCollection = "hideFromCollection";
12
15
  const readOnly = "readOnly";
16
+ const nullable = "nullable";
13
17
 
14
18
  return (
15
19
 
@@ -18,11 +22,11 @@ export function AdvancedPropertyValidation({ disabled }: {
18
22
  <Field type="checkbox" name={hideFromCollection}>
19
23
  {({ field, form }: FormexFieldProps) => {
20
24
  return <SwitchControl
21
- label={"Hide from collection"}
25
+ label={t("hide_from_collection")}
22
26
  size={"medium"}
23
27
  disabled={disabled}
24
28
  form={form}
25
- tooltip={"Hide this field from the collection view. It will still be visible in the form view"}
29
+ tooltip={t("hide_from_collection_tooltip")}
26
30
  field={field}/>
27
31
  }}
28
32
  </Field>
@@ -33,10 +37,25 @@ export function AdvancedPropertyValidation({ disabled }: {
33
37
  type="checkbox">
34
38
  {({ field, form }: FormexFieldProps) => {
35
39
  return <SwitchControl
36
- label={"Read only"}
40
+ label={t("read_only")}
41
+ size={"medium"}
42
+ disabled={disabled}
43
+ tooltip={t("read_only_tooltip")}
44
+ form={form}
45
+ field={field}/>
46
+ }}
47
+ </Field>
48
+ </div>
49
+
50
+ <div className={"col-span-12"}>
51
+ <Field name={nullable}
52
+ type="checkbox">
53
+ {({ field, form }: FormexFieldProps) => {
54
+ return <SwitchControl
55
+ label={t("nullable")}
37
56
  size={"medium"}
38
57
  disabled={disabled}
39
- tooltip={"Is this a read only field. Display only as a preview"}
58
+ tooltip={t("nullable_tooltip")}
40
59
  form={form}
41
60
  field={field}/>
42
61
  }}