@firecms/collection_editor 3.0.1 → 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 +15260 -8173
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/index.umd.js +15257 -8170
  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 +23 -2
  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 +27 -2
  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 -267
  73. package/src/ui/collection_editor/CollectionEditorDialog.tsx +270 -198
  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 +5 -4
  104. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +47 -52
  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({
@@ -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}
@@ -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
 
@@ -73,6 +68,14 @@ export function StoragePropertyField({
73
68
  const fileTypesValue: string[] | undefined = Array.isArray(storedValue) ? storedValue : undefined;
74
69
  const allFileTypesSelected = !fileTypesValue || fileTypesValue.length === 0;
75
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
+
76
79
  const handleTypesChange = (value: string[]) => {
77
80
  if (!value) setFieldValue(acceptedFiles, undefined);
78
81
  else setFieldValue(acceptedFiles, value);
@@ -88,11 +91,11 @@ export function StoragePropertyField({
88
91
 
89
92
  <ExpandablePanel
90
93
  title={
91
- <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">
92
95
  <CloudUploadIcon/>
93
96
  <Typography variant={"subtitle2"}
94
97
  className="ml-4">
95
- File upload config
98
+ {t("file_upload_config")}
96
99
  </Typography>
97
100
  </div>
98
101
  }>
@@ -103,14 +106,14 @@ export function StoragePropertyField({
103
106
 
104
107
  <MultiSelect
105
108
  className={"w-full"}
106
- placeholder={"All file types allowed"}
109
+ placeholder={t("all_file_types_allowed")}
107
110
  disabled={disabled}
108
111
  name={acceptedFiles}
109
112
  value={fileTypesValue ?? []}
110
113
  onValueChange={handleTypesChange}
111
- label={allFileTypesSelected ? undefined : "Allowed file types"}
114
+ label={allFileTypesSelected ? undefined : t("allowed_file_types")}
112
115
  renderValues={(selected) => {
113
- if (!selected || selected.length === 0) return "All file types allowed";
116
+ if (!selected || selected.length === 0) return t("all_file_types_allowed");
114
117
  return selected.map((v: string) => fileTypes[v])
115
118
  .filter((v: string) => Boolean(v))
116
119
  .join(", ");
@@ -130,7 +133,7 @@ export function StoragePropertyField({
130
133
  e.stopPropagation();
131
134
  return setFieldValue(acceptedFiles, [value]);
132
135
  }}>
133
- Only
136
+ {t("only")}
134
137
  </Button>
135
138
  </MultiSelectItem>
136
139
  ))}
@@ -141,7 +144,7 @@ export function StoragePropertyField({
141
144
  <div className={"col-span-12"}>
142
145
  <Field name={fileName}
143
146
  as={DebouncedTextField}
144
- label={"File name"}
147
+ label={t("file_name_label")}
145
148
  size={"small"}
146
149
  disabled={hasFilenameCallback || disabled}
147
150
  value={hasFilenameCallback ? "-" : fileNameValue}
@@ -150,23 +153,21 @@ export function StoragePropertyField({
150
153
  <div className={"col-span-12"}>
151
154
  <Field name={storagePath}
152
155
  as={DebouncedTextField}
153
- label={"Storage path"}
156
+ label={t("storage_path_label")}
154
157
  disabled={hasStoragePathCallback || disabled}
155
158
  size={"small"}
156
159
  value={hasStoragePathCallback ? "-" : storagePathValue}
157
160
  />
158
161
  <Typography variant={"caption"} className={"ml-3.5 mt-1 mb-2"}>
159
- <p>You can use the following placeholders in
160
- the file name
161
- and storage path values:</p>
162
+ <p>{t("storage_placeholders_description")}</p>
162
163
  <ul>
163
- <li>{"{file} - Full name of the uploaded file"}</li>
164
- <li>{"{file.name} - Name of the uploaded file without extension"}</li>
165
- <li>{"{file.ext} - Extension of the uploaded file"}</li>
166
- <li>{"{entityId} - ID of the entity"}</li>
167
- <li>{"{propertyKey} - ID of this field"}</li>
168
- <li>{"{path} - Path of this entity"}</li>
169
- <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>
170
171
  </ul>
171
172
  </Typography>
172
173
 
@@ -177,7 +178,7 @@ export function StoragePropertyField({
177
178
  form
178
179
  }: FormexFieldProps) => {
179
180
  return <SwitchControl
180
- label={"Include bucket URL (gs://...) in saved value"}
181
+ label={t("include_bucket_url")}
181
182
  disabled={existing || disabled}
182
183
  form={form}
183
184
  field={field}/>;
@@ -185,9 +186,7 @@ export function StoragePropertyField({
185
186
  </Field>
186
187
 
187
188
  <Typography variant={"caption"} className={"ml-3.5 mt-1 mb-2"}>
188
- Turn this setting on if you want to save a fully-qualified storage URL
189
- (e.g. <code>gs://my-bucket/path/to/file</code>) instead of just the storage path.
190
- You can only change this prop upon creation.
189
+ {t("include_bucket_url_description")}
191
190
  </Typography>
192
191
 
193
192
  <Field name={storeUrl}
@@ -197,7 +196,7 @@ export function StoragePropertyField({
197
196
  form
198
197
  }: FormexFieldProps) => {
199
198
  return <SwitchControl
200
- label={"Save URL instead of storage path"}
199
+ label={t("save_url_instead_of_path")}
201
200
  disabled={existing || disabled}
202
201
  form={form}
203
202
  field={field}/>;
@@ -205,18 +204,14 @@ export function StoragePropertyField({
205
204
  </Field>
206
205
 
207
206
  <Typography variant={"caption"} className={"ml-3.5 mt-1 mb-2"}>
208
- Turn this setting on, if you prefer to save
209
- the download
210
- URL of the uploaded file instead of the
211
- storage path.
212
- You can only change this prop upon creation.
207
+ {t("save_url_description")}
213
208
  </Typography>
214
209
  </div>
215
210
 
216
211
  <div className={"col-span-12"}>
217
212
  <DebouncedTextField name={maxSize}
218
213
  type={"number"}
219
- label={"Max size (in bytes)"}
214
+ label={t("max_size_bytes")}
220
215
  size={"small"}
221
216
  value={maxSizeValue !== undefined && maxSizeValue !== null ? maxSizeValue.toString() : ""}
222
217
  onChange={(e) => {
@@ -231,10 +226,10 @@ export function StoragePropertyField({
231
226
  <Typography variant={"subtitle2"}
232
227
  color={"secondary"}
233
228
  className={"mb-2 block"}>
234
- Image Resize Configuration
229
+ {t("image_resize_configuration")}
235
230
  </Typography>
236
231
  <Typography variant={"caption"} className={"mb-2 block text-xs"}>
237
- Automatically resize and optimize images before upload (JPEG, PNG, WebP only)
232
+ {t("image_resize_description")}
238
233
  </Typography>
239
234
  </div>
240
235
 
@@ -242,7 +237,7 @@ export function StoragePropertyField({
242
237
  <DebouncedTextField
243
238
  name={imageResizeMaxWidth}
244
239
  type={"number"}
245
- label={"Max width (px)"}
240
+ label={t("max_width_px")}
246
241
  size={"small"}
247
242
  disabled={disabled}
248
243
  value={imageResizeMaxWidthValue !== undefined && imageResizeMaxWidthValue !== null ? imageResizeMaxWidthValue.toString() : ""}
@@ -258,7 +253,7 @@ export function StoragePropertyField({
258
253
  <DebouncedTextField
259
254
  name={imageResizeMaxHeight}
260
255
  type={"number"}
261
- label={"Max height (px)"}
256
+ label={t("max_height_px")}
262
257
  size={"small"}
263
258
  disabled={disabled}
264
259
  value={imageResizeMaxHeightValue !== undefined && imageResizeMaxHeightValue !== null ? imageResizeMaxHeightValue.toString() : ""}
@@ -278,16 +273,16 @@ export function StoragePropertyField({
278
273
  size={"medium"}
279
274
  value={imageResizeModeValue || "cover"}
280
275
  onValueChange={(value) => setFieldValue(imageResizeMode, value || "cover")}
281
- label={"Resize mode"}
276
+ label={t("resize_mode")}
282
277
  renderValue={(selected) => {
283
- if (!selected) return "Cover";
284
- 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");
285
280
  }}>
286
281
  <SelectItem value="contain">
287
- Contain (fit within bounds)
282
+ {t("resize_contain_description")}
288
283
  </SelectItem>
289
284
  <SelectItem value="cover">
290
- Cover (fill bounds, may crop)
285
+ {t("resize_cover_description")}
291
286
  </SelectItem>
292
287
  </Select>
293
288
  </div>
@@ -300,13 +295,13 @@ export function StoragePropertyField({
300
295
  name={imageResizeFormat}
301
296
  value={imageResizeFormatValue || "original"}
302
297
  onValueChange={(value) => setFieldValue(imageResizeFormat, value || "original")}
303
- label={"Output format"}
298
+ label={t("output_format")}
304
299
  renderValue={(selected) => {
305
- if (!selected) return "Original";
300
+ if (!selected) return t("format_original");
306
301
  return selected.charAt(0).toUpperCase() + selected.slice(1);
307
302
  }}>
308
303
  <SelectItem value="original">
309
- Original (keep same format)
304
+ {t("format_original_description")}
310
305
  </SelectItem>
311
306
  <SelectItem value="jpeg">
312
307
  JPEG
@@ -315,7 +310,7 @@ export function StoragePropertyField({
315
310
  PNG
316
311
  </SelectItem>
317
312
  <SelectItem value="webp">
318
- WebP (best compression)
313
+ {t("format_webp_description")}
319
314
  </SelectItem>
320
315
  </Select>
321
316
  </div>
@@ -324,7 +319,7 @@ export function StoragePropertyField({
324
319
  <DebouncedTextField
325
320
  name={imageResizeQuality}
326
321
  type={"number"}
327
- label={"Quality (0-100)"}
322
+ label={t("quality_label")}
328
323
  size={"small"}
329
324
  disabled={disabled}
330
325
  value={imageResizeQualityValue !== undefined && imageResizeQualityValue !== null ? imageResizeQualityValue.toString() : ""}
@@ -340,7 +335,7 @@ export function StoragePropertyField({
340
335
  }}
341
336
  />
342
337
  <Typography variant={"caption"} className={"ml-3.5 mt-1 mb-2"}>
343
- Higher quality = larger file size. Recommended: 80-90 for photos, 90-100 for graphics
338
+ {t("quality_hint")}
344
339
  </Typography>
345
340
  </div>
346
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
  }}