@firecms/collection_editor 3.3.0 → 3.4.0-canary.0ef7442

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/package.json CHANGED
@@ -1,18 +1,19 @@
1
1
  {
2
2
  "name": "@firecms/collection_editor",
3
3
  "type": "module",
4
- "version": "3.3.0",
4
+ "version": "3.4.0-canary.0ef7442",
5
5
  "main": "./dist/index.umd.js",
6
6
  "module": "./dist/index.es.js",
7
7
  "types": "./dist/index.d.ts",
8
8
  "source": "src/index.ts",
9
9
  "dependencies": {
10
- "@firecms/data_export": "^3.3.0",
11
- "@firecms/data_import": "^3.3.0",
12
- "@firecms/data_import_export": "^3.3.0",
13
- "@firecms/formex": "^3.3.0",
14
- "@firecms/schema_inference": "^3.3.0",
15
- "@firecms/ui": "^3.3.0",
10
+ "@firecms/core": "3.4.0-canary.0ef7442",
11
+ "@firecms/data_export": "3.4.0-canary.0ef7442",
12
+ "@firecms/data_import": "3.4.0-canary.0ef7442",
13
+ "@firecms/data_import_export": "3.4.0-canary.0ef7442",
14
+ "@firecms/formex": "3.4.0-canary.0ef7442",
15
+ "@firecms/schema_inference": "3.4.0-canary.0ef7442",
16
+ "@firecms/ui": "3.4.0-canary.0ef7442",
16
17
  "json5": "^2.2.3",
17
18
  "prism-react-renderer": "^2.4.1"
18
19
  },
@@ -503,7 +503,7 @@ export function CollectionPropertiesEditorForm({
503
503
  !isPropertyBuilder(selectedProperty) &&
504
504
  <PropertyForm
505
505
  inArray={false}
506
- key={`edit_view_${selectedPropertyIndex}_${generationCounter}`}
506
+ key={`edit_view_${selectedPropertyFullId}_${generationCounter}`}
507
507
  existingProperty={!isNewCollection}
508
508
  autoUpdateId={false}
509
509
  allowDataInference={!isNewCollection}
@@ -547,7 +547,7 @@ export function CollectionPropertiesEditorForm({
547
547
  {asDialog && <PropertyFormDialog
548
548
  inArray={false}
549
549
  open={selectedPropertyIndex !== undefined}
550
- key={`edit_view_${selectedPropertyIndex}_${generationCounter}`}
550
+ key={`edit_view_${selectedPropertyFullId}_${generationCounter}`}
551
551
  autoUpdateId={!selectedProperty}
552
552
  allowDataInference={!isNewCollection}
553
553
  existingProperty={true}
@@ -72,6 +72,34 @@ export function DisplaySettingsForm({
72
72
  return result;
73
73
  }, [resolvedCollection.properties]);
74
74
 
75
+ // Get image properties (for imageProperty), used as the thumbnail in Cards/Kanban views
76
+ const imageProperties = useMemo(() => {
77
+ const result: { key: string; label: string; property: Property; }[] = [];
78
+ if (!resolvedCollection.properties) return result;
79
+
80
+ const isImageProperty = (prop: any): boolean => {
81
+ if (!prop || !("dataType" in prop)) return false;
82
+ if (prop.dataType === "string") {
83
+ return Boolean(prop.storage?.acceptedFiles?.includes("image/*")) || prop.url === "image";
84
+ }
85
+ if (prop.dataType === "array" && prop.of) {
86
+ return isImageProperty(prop.of);
87
+ }
88
+ return false;
89
+ };
90
+
91
+ Object.entries(resolvedCollection.properties).forEach(([key, prop]) => {
92
+ if (isImageProperty(prop)) {
93
+ result.push({
94
+ key,
95
+ label: (prop as Property).name || key,
96
+ property: prop as Property
97
+ });
98
+ }
99
+ });
100
+ return result;
101
+ }, [resolvedCollection.properties]);
102
+
75
103
  const showErrors = submitCount > 0;
76
104
 
77
105
  // Document ID generation value
@@ -246,6 +274,83 @@ export function DisplaySettingsForm({
246
274
  })()}
247
275
  </div>
248
276
 
277
+ {/* Image Property (used as thumbnail in Cards/Kanban views) */}
278
+ <div className={"col-span-12 mt-4"}>
279
+ {(() => {
280
+ const imagePropertyMissing = Boolean(values.imageProperty) &&
281
+ !imageProperties.some(p => p.key === values.imageProperty);
282
+
283
+ return (
284
+ <>
285
+ <Typography variant={"label"} color={"secondary"} className={"ml-3.5"}>{t("image_property")}</Typography>
286
+ <Select
287
+ key={`image-select-${imageProperties.length}`}
288
+ name="imageProperty"
289
+ size={"large"}
290
+ fullWidth={true}
291
+ position={"item-aligned"}
292
+ disabled={imageProperties.length === 0}
293
+ error={imagePropertyMissing}
294
+ value={(values.imageProperty as string) ?? ""}
295
+ onValueChange={(v) => {
296
+ setFieldValue("imageProperty", v || undefined);
297
+ }}
298
+ renderValue={(value) => {
299
+ if (imagePropertyMissing) {
300
+ return <span className="text-red-500">{value} ({t("not_found_suffix")})</span>;
301
+ }
302
+ const prop = imageProperties.find(p => p.key === value);
303
+ if (!prop) return t("select_a_property");
304
+ const fieldConfig = getFieldConfig(prop.property, customizationController.propertyConfigs);
305
+ return (
306
+ <div className="flex items-center gap-2">
307
+ <PropertyConfigBadge propertyConfig={fieldConfig} />
308
+ <span>{prop.label}</span>
309
+ </div>
310
+ );
311
+ }}
312
+ endAdornment={values.imageProperty ? (
313
+ <IconButton
314
+ size="small"
315
+ onClick={(e) => {
316
+ e.stopPropagation();
317
+ setFieldValue("imageProperty", undefined);
318
+ }}
319
+ >
320
+ <CloseIcon size="small" />
321
+ </IconButton>
322
+ ) : undefined}
323
+ >
324
+ {imageProperties.map((prop) => {
325
+ const fieldConfig = getFieldConfig(prop.property, customizationController.propertyConfigs);
326
+ return (
327
+ <SelectItem key={prop.key} value={prop.key}>
328
+ <div className="flex items-center gap-3">
329
+ <PropertyConfigBadge propertyConfig={fieldConfig} />
330
+ <div>
331
+ <div>{prop.label}</div>
332
+ <Typography variant="caption" color="secondary">
333
+ {fieldConfig?.name || prop.label}
334
+ </Typography>
335
+ </div>
336
+ </div>
337
+ </SelectItem>
338
+ );
339
+ })}
340
+ </Select>
341
+ <FieldCaption error={imagePropertyMissing}>
342
+ {imagePropertyMissing
343
+ ? t("image_property_not_found", { property: values.imageProperty as string ?? "" })
344
+ : imageProperties.length === 0
345
+ ? t("no_image_properties")
346
+ : t("image_property_description")
347
+ }
348
+ </FieldCaption>
349
+ </>
350
+ );
351
+ })()}
352
+ </div>
353
+
249
354
  {/* Default row size */}
250
355
  <div className={"col-span-12"}>
251
356
  <Select