@firecms/core 3.0.0-canary.7 → 3.0.0-canary.9

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 (132) hide show
  1. package/README.md +1 -1
  2. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +1 -1
  3. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  4. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +2 -2
  5. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -2
  6. package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
  7. package/dist/components/EntityPreview.d.ts +25 -7
  8. package/dist/components/EntityView.d.ts +11 -0
  9. package/dist/components/FieldCaption.d.ts +5 -0
  10. package/dist/components/HomePage/NavigationCard.d.ts +8 -0
  11. package/dist/components/HomePage/{NavigationCollectionCard.d.ts → NavigationCardBinding.d.ts} +2 -2
  12. package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
  13. package/dist/components/HomePage/index.d.ts +3 -1
  14. package/dist/components/VirtualTable/VirtualTableProps.d.ts +1 -1
  15. package/dist/components/index.d.ts +4 -2
  16. package/dist/core/{EntityView.d.ts → EntityEditView.d.ts} +2 -2
  17. package/dist/core/SideEntityView.d.ts +2 -2
  18. package/dist/form/EntityForm.d.ts +1 -1
  19. package/dist/form/components/StorageItemPreview.d.ts +3 -2
  20. package/dist/form/components/StorageUploadProgress.d.ts +1 -1
  21. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  22. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  23. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +4 -3
  24. package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
  25. package/dist/form/validation.d.ts +1 -1
  26. package/dist/hooks/data/useDataSource.d.ts +2 -2
  27. package/dist/hooks/useBuildNavigationController.d.ts +5 -2
  28. package/dist/hooks/useProjectLog.d.ts +5 -1
  29. package/dist/hooks/useStorageSource.d.ts +2 -2
  30. package/dist/index.es.js +8333 -8060
  31. package/dist/index.es.js.map +1 -1
  32. package/dist/index.umd.js +5 -5
  33. package/dist/index.umd.js.map +1 -1
  34. package/dist/internal/useRestoreScroll.d.ts +1 -1
  35. package/dist/preview/PropertyPreview.d.ts +1 -1
  36. package/dist/preview/components/BooleanPreview.d.ts +5 -1
  37. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  38. package/dist/preview/components/ReferencePreview.d.ts +1 -7
  39. package/dist/types/analytics.d.ts +1 -1
  40. package/dist/types/auth.d.ts +13 -1
  41. package/dist/types/collections.d.ts +14 -1
  42. package/dist/types/entity_overrides.d.ts +6 -0
  43. package/dist/types/index.d.ts +2 -0
  44. package/dist/types/navigation.d.ts +10 -9
  45. package/dist/types/permissions.d.ts +5 -1
  46. package/dist/types/plugins.d.ts +15 -17
  47. package/dist/types/properties.d.ts +2 -2
  48. package/dist/types/property_config.d.ts +2 -2
  49. package/dist/types/roles.d.ts +31 -0
  50. package/dist/types/user.d.ts +5 -0
  51. package/dist/util/collections.d.ts +9 -1
  52. package/dist/util/icons.d.ts +8 -2
  53. package/dist/util/permissions.d.ts +4 -4
  54. package/dist/util/references.d.ts +4 -2
  55. package/dist/util/resolutions.d.ts +1 -1
  56. package/package.json +23 -23
  57. package/src/components/DeleteEntityDialog.tsx +4 -4
  58. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +2 -2
  59. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +273 -277
  60. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +1 -1
  61. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +12 -13
  62. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +8 -15
  63. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +3 -3
  64. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +1 -1
  65. package/src/components/EntityCollectionTable/internal/default_entity_actions.tsx +9 -5
  66. package/src/components/EntityCollectionView/EntityCollectionView.tsx +28 -49
  67. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -6
  68. package/src/components/EntityCollectionView/useSelectionController.tsx +30 -0
  69. package/src/components/EntityPreview.tsx +204 -70
  70. package/src/components/EntityView.tsx +84 -0
  71. package/src/components/FieldCaption.tsx +14 -0
  72. package/src/components/FireCMSAppBar.tsx +8 -0
  73. package/src/components/HomePage/DefaultHomePage.tsx +13 -9
  74. package/src/components/HomePage/NavigationCard.tsx +69 -0
  75. package/src/components/HomePage/NavigationCardBinding.tsx +116 -0
  76. package/src/components/HomePage/SmallNavigationCard.tsx +45 -0
  77. package/src/components/HomePage/index.tsx +3 -1
  78. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -4
  79. package/src/components/ReferenceWidget.tsx +3 -3
  80. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +11 -19
  81. package/src/components/VirtualTable/VirtualTableProps.tsx +1 -1
  82. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +1 -1
  83. package/src/components/index.tsx +4 -2
  84. package/src/core/Drawer.tsx +66 -39
  85. package/src/core/{EntityView.tsx → EntityEditView.tsx} +20 -37
  86. package/src/core/EntitySidePanel.tsx +2 -2
  87. package/src/core/FireCMS.tsx +18 -2
  88. package/src/core/NavigationRoutes.tsx +8 -0
  89. package/src/core/SideEntityView.tsx +2 -2
  90. package/src/form/EntityForm.tsx +19 -11
  91. package/src/form/components/StorageItemPreview.tsx +5 -3
  92. package/src/form/components/StorageUploadProgress.tsx +6 -5
  93. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +8 -12
  94. package/src/form/field_bindings/KeyValueFieldBinding.tsx +15 -15
  95. package/src/form/field_bindings/MapFieldBinding.tsx +15 -15
  96. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +1 -1
  97. package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -0
  98. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +14 -5
  99. package/src/form/field_bindings/TextFieldBinding.tsx +7 -5
  100. package/src/form/validation.ts +3 -4
  101. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  102. package/src/hooks/data/useDataSource.tsx +8 -3
  103. package/src/hooks/data/useEntityFetch.tsx +1 -1
  104. package/src/hooks/useBuildNavigationController.tsx +79 -38
  105. package/src/hooks/useProjectLog.tsx +11 -3
  106. package/src/hooks/useReferenceDialog.tsx +2 -2
  107. package/src/hooks/useStorageSource.tsx +7 -2
  108. package/src/preview/PropertyPreview.tsx +1 -1
  109. package/src/preview/components/BooleanPreview.tsx +16 -3
  110. package/src/preview/components/EnumValuesChip.tsx +1 -1
  111. package/src/preview/components/ReferencePreview.tsx +54 -146
  112. package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
  113. package/src/types/analytics.ts +1 -0
  114. package/src/types/auth.tsx +17 -1
  115. package/src/types/collections.ts +16 -1
  116. package/src/types/entity_actions.tsx +4 -0
  117. package/src/types/entity_overrides.tsx +7 -0
  118. package/src/types/firecms.tsx +0 -1
  119. package/src/types/index.ts +2 -0
  120. package/src/types/navigation.ts +11 -10
  121. package/src/types/permissions.ts +6 -1
  122. package/src/types/plugins.tsx +22 -25
  123. package/src/types/properties.ts +3 -2
  124. package/src/types/property_config.tsx +2 -2
  125. package/src/types/roles.ts +41 -0
  126. package/src/types/side_entity_controller.tsx +1 -0
  127. package/src/types/user.ts +7 -0
  128. package/src/util/collections.ts +22 -0
  129. package/src/util/icons.tsx +11 -3
  130. package/src/util/permissions.ts +11 -8
  131. package/src/util/references.ts +36 -5
  132. package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
@@ -19,8 +19,9 @@ import equal from "react-fast-compare"
19
19
  import {
20
20
  canCreateEntity,
21
21
  canDeleteEntity,
22
- fullPathToCollectionSegments,
23
22
  getDefaultValuesFor,
23
+ getEntityTitlePropertyKey,
24
+ getValueInPath,
24
25
  isHidden,
25
26
  isReadOnly,
26
27
  resolveCollection
@@ -171,7 +172,7 @@ function EntityFormInternal<M extends Record<string, any>>({
171
172
  onFormContextChange,
172
173
  hideId,
173
174
  autoSave,
174
- onIdUpdateError
175
+ onIdUpdateError,
175
176
  }: EntityFormProps<M>) {
176
177
 
177
178
  const analyticsController = useAnalyticsController();
@@ -179,7 +180,7 @@ function EntityFormInternal<M extends Record<string, any>>({
179
180
  const customizationController = useCustomizationController();
180
181
 
181
182
  const context = useFireCMSContext();
182
- const dataSource = useDataSource();
183
+ const dataSource = useDataSource(inputCollection);
183
184
  const plugins = customizationController.plugins;
184
185
 
185
186
  const initialResolvedCollection = useMemo(() => resolveCollection({
@@ -344,6 +345,9 @@ function EntityFormInternal<M extends Record<string, any>>({
344
345
  fields: customizationController.propertyConfigs
345
346
  });
346
347
 
348
+ const titlePropertyKey = getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs);
349
+ const title = internalValues && titlePropertyKey ? getValueInPath(internalValues, titlePropertyKey) : undefined;
350
+
347
351
  const onIdUpdate = inputCollection.callbacks?.onIdUpdate;
348
352
 
349
353
  const doOnIdUpdate = useCallback(async () => {
@@ -389,12 +393,15 @@ function EntityFormInternal<M extends Record<string, any>>({
389
393
 
390
394
  const authController = useAuthController();
391
395
 
392
- const getActionsForEntity = useCallback(({ entity, customEntityActions }: {
396
+ const getActionsForEntity = useCallback(({
397
+ entity,
398
+ customEntityActions
399
+ }: {
393
400
  entity?: Entity<M>,
394
401
  customEntityActions?: EntityAction[]
395
402
  }): EntityAction[] => {
396
- const createEnabled = canCreateEntity(inputCollection, authController, fullPathToCollectionSegments(path), null);
397
- const deleteEnabled = entity ? canDeleteEntity(inputCollection, authController, fullPathToCollectionSegments(path), entity) : true;
403
+ const createEnabled = canCreateEntity(inputCollection, authController, path, null);
404
+ const deleteEnabled = entity ? canDeleteEntity(inputCollection, authController, path, entity) : true;
398
405
  const actions: EntityAction[] = [];
399
406
  if (createEnabled)
400
407
  actions.push(copyEntityAction);
@@ -454,8 +461,8 @@ function EntityFormInternal<M extends Record<string, any>>({
454
461
  className={`w-full py-2 flex flex-col items-start mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>
455
462
 
456
463
  <Typography
457
- className={"mt-4 flex-grow " + inputCollection.hideIdFromForm ? "mb-2" : "mb-0"}
458
- variant={"h4"}>{inputCollection.singularName ?? inputCollection.name}
464
+ className={"mt-4 flex-grow line-clamp-1 " + inputCollection.hideIdFromForm ? "mb-2" : "mb-0"}
465
+ variant={"h4"}>{title ?? inputCollection.singularName ?? inputCollection.name}
459
466
  </Typography>
460
467
  <Alert color={"base"} className={"w-full"} size={"small"}>
461
468
  <code className={"text-xs select-all"}>{path}/{entityId}</code>
@@ -508,7 +515,7 @@ function InnerForm<M extends Record<string, any>>(props: FormexController<M> & {
508
515
  savingError?: Error,
509
516
  closeAfterSaveRef: MutableRefObject<boolean>,
510
517
  autoSave?: boolean,
511
- entityActions: EntityAction[]
518
+ entityActions: EntityAction[],
512
519
  }) {
513
520
 
514
521
  const {
@@ -530,7 +537,7 @@ function InnerForm<M extends Record<string, any>>(props: FormexController<M> & {
530
537
  dirty,
531
538
  closeAfterSaveRef,
532
539
  autoSave,
533
- entityActions
540
+ entityActions,
534
541
  } = props;
535
542
 
536
543
  const context = useFireCMSContext();
@@ -598,6 +605,7 @@ function InnerForm<M extends Record<string, any>>(props: FormexController<M> & {
598
605
  <Tooltip title={<PropertyIdCopyTooltipContent propertyId={key}/>}
599
606
  delayDuration={800}
600
607
  side={"left"}
608
+ align={"start"}
601
609
  sideOffset={16}>
602
610
  <PropertyFieldBinding {...cmsFormFieldProps}/>
603
611
  </Tooltip>
@@ -655,7 +663,7 @@ function InnerForm<M extends Record<string, any>>(props: FormexController<M> & {
655
663
  fullPath: resolvedCollection.path,
656
664
  collection: resolvedCollection,
657
665
  context,
658
- sideEntityController
666
+ sideEntityController,
659
667
  });
660
668
  }}>
661
669
  {action.icon}
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Entity, ResolvedStringProperty } from "../../types";
3
+ import { Entity, EntityCollection, ResolvedStringProperty } from "../../types";
4
4
  import { PreviewSize, PropertyPreview } from "../../preview";
5
5
 
6
6
  import { cn, IconButton, paperMixin, RemoveIcon, Tooltip } from "@firecms/ui";
@@ -14,6 +14,7 @@ interface StorageItemPreviewProps {
14
14
  onRemove: (value: string) => void;
15
15
  size: PreviewSize;
16
16
  disabled: boolean;
17
+ collection: EntityCollection;
17
18
  }
18
19
 
19
20
  export function StorageItemPreview({
@@ -23,7 +24,8 @@ export function StorageItemPreview({
23
24
  entity,
24
25
  onRemove,
25
26
  disabled,
26
- size
27
+ size,
28
+ collection
27
29
  }: StorageItemPreviewProps) {
28
30
 
29
31
  return (
@@ -54,7 +56,7 @@ export function StorageItemPreview({
54
56
  <PropertyPreview propertyKey={name}
55
57
  value={value}
56
58
  property={property}
57
- // entity={entity}
59
+ // entity={entity}
58
60
  size={size}/>
59
61
  </ErrorBoundary>
60
62
  }
@@ -4,6 +4,7 @@ import { useSnackbarController, useStorageSource } from "../../hooks";
4
4
  import { StorageFieldItem } from "../../util/useStorageUploadController";
5
5
  import { ErrorView } from "../../components";
6
6
  import { cn, paperMixin, Skeleton } from "@firecms/ui";
7
+ import { EntityCollection, StorageSource } from "../../types";
7
8
 
8
9
  export interface StorageUploadItemProps {
9
10
  storagePath: string;
@@ -22,10 +23,10 @@ export function StorageUploadProgress({
22
23
  metadata,
23
24
  onFileUploadComplete,
24
25
  imageSize,
25
- simple
26
+ simple,
26
27
  }: StorageUploadItemProps) {
27
28
 
28
- const storage = useStorageSource();
29
+ const storageSource = useStorageSource();
29
30
 
30
31
  const snackbarController = useSnackbarController();
31
32
 
@@ -41,7 +42,7 @@ export function StorageUploadProgress({
41
42
  setError(undefined);
42
43
  setLoading(true);
43
44
 
44
- storage.uploadFile({
45
+ storageSource.uploadFile({
45
46
  file,
46
47
  fileName,
47
48
  path: storagePath,
@@ -67,7 +68,7 @@ export function StorageUploadProgress({
67
68
  .finally(() => {
68
69
  uploading.current = false;
69
70
  });
70
- }, [entry, metadata, onFileUploadComplete, storage, storagePath]);
71
+ }, [entry, metadata, onFileUploadComplete, storageSource, storagePath]);
71
72
 
72
73
  React.useEffect(() => {
73
74
  mounted.current = true;
@@ -89,7 +90,7 @@ export function StorageUploadProgress({
89
90
 
90
91
  <div className={cn(paperMixin,
91
92
  "relative m-4 border-box flex items-center justify-center",
92
- `min-w-[${imageSize}px] min-h-[${imageSize}px]`)}>
93
+ `min-w-[${imageSize}px] min-h-[${imageSize}px]`)}>
93
94
 
94
95
  {loading &&
95
96
  <Skeleton className="w-full h-full"/>}
@@ -6,7 +6,7 @@ import { ErrorView } from "../../components";
6
6
  import { getIconForProperty, getReferenceFrom } from "../../util";
7
7
 
8
8
  import { useNavigationController, useReferenceDialog } from "../../hooks";
9
- import { Button, ExpandablePanel } from "@firecms/ui";
9
+ import { Button, cn, ExpandablePanel, fieldBackgroundMixin } from "@firecms/ui";
10
10
  import { useClearRestoreValue } from "../useClearRestoreValue";
11
11
 
12
12
  type ArrayOfReferencesFieldProps = FieldProps<EntityReference[]>;
@@ -38,7 +38,6 @@ export function ArrayOfReferencesFieldBinding({
38
38
  }
39
39
 
40
40
  const expanded = property.expanded === undefined ? true : property.expanded;
41
- const [onHover, setOnHover] = React.useState(false);
42
41
  const selectedEntityIds = value && Array.isArray(value) ? value.map((ref) => ref.id) : [];
43
42
 
44
43
  useClearRestoreValue({
@@ -81,21 +80,17 @@ export function ArrayOfReferencesFieldBinding({
81
80
  if (!entryValue)
82
81
  return <div>Internal ERROR</div>;
83
82
  return (
84
- <div
85
- onMouseEnter={() => setOnHover(true)}
86
- onMouseMove={() => setOnHover(true)}
87
- onMouseLeave={() => setOnHover(false)}>
88
83
  <ReferencePreview
84
+ key={internalId}
89
85
  disabled={!ofProperty.path}
90
86
  previewProperties={ofProperty.previewProperties}
91
87
  size={"medium"}
92
88
  onClick={onEntryClick}
89
+ hover={!disabled}
93
90
  reference={entryValue}
94
- onHover={onHover}
95
91
  />
96
- </div>
97
92
  );
98
- }, [ofProperty.path, ofProperty.previewProperties, onHover, value]);
93
+ }, [ofProperty.path, ofProperty.previewProperties, value]);
99
94
 
100
95
  const title = (
101
96
  <LabelWithIcon icon={getIconForProperty(property, "small")}
@@ -108,7 +103,7 @@ export function ArrayOfReferencesFieldBinding({
108
103
  {!collection && <ErrorView
109
104
  error={"The specified collection does not exist. Check console"}/>}
110
105
 
111
- {collection && <>
106
+ {collection && <div className={"group"}>
112
107
 
113
108
  <FormikArrayContainer value={value}
114
109
  addLabel={property.name ? "Add reference to " + property.name : "Add reference"}
@@ -126,7 +121,7 @@ export function ArrayOfReferencesFieldBinding({
126
121
  onClick={onEntryClick}>
127
122
  Edit {property.name}
128
123
  </Button>
129
- </>}
124
+ </div>}
130
125
  </>;
131
126
 
132
127
  return (
@@ -134,7 +129,8 @@ export function ArrayOfReferencesFieldBinding({
134
129
 
135
130
  {!tableMode &&
136
131
  <ExpandablePanel
137
- className={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2"}
132
+ titleClassName={fieldBackgroundMixin}
133
+ className={cn("px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2", fieldBackgroundMixin)}
138
134
  initiallyExpanded={expanded}
139
135
  title={title}>
140
136
  {body}
@@ -32,20 +32,20 @@ type MapEditViewRowState = [number, {
32
32
  *
33
33
  * @group Form fields
34
34
  */
35
- export function KeyValueFieldBinding<T extends Record<string, any>>({
36
- propertyKey,
37
- value,
38
- showError,
39
- error,
40
- disabled,
41
- property,
42
- setValue,
43
- tableMode,
44
- includeDescription,
45
- underlyingValueHasChanged,
46
- autoFocus,
47
- context
48
- }: FieldProps<T>) {
35
+ export function KeyValueFieldBinding({
36
+ propertyKey,
37
+ value,
38
+ showError,
39
+ error,
40
+ disabled,
41
+ property,
42
+ setValue,
43
+ tableMode,
44
+ includeDescription,
45
+ underlyingValueHasChanged,
46
+ autoFocus,
47
+ context
48
+ }: FieldProps<Record<string, any>>) {
49
49
 
50
50
  const expanded = (property.expanded === undefined ? true : property.expanded) || autoFocus;
51
51
 
@@ -546,7 +546,7 @@ function getDataType(value: any): DataType | undefined {
546
546
  return "array";
547
547
  } else if (value instanceof Date) {
548
548
  return "date";
549
- } else if (value.isEntityReference && value.isEntityReference()) {
549
+ } else if (value?.isEntityReference && value?.isEntityReference()) {
550
550
  return "reference";
551
551
  } else if (value instanceof GeoPoint) {
552
552
  return "geopoint";
@@ -14,21 +14,21 @@ import { ExpandablePanel, InputLabel, Select, SelectItem } from "@firecms/ui";
14
14
  * and tables to the specified properties.
15
15
  * @group Form fields
16
16
  */
17
- export function MapFieldBinding<T extends Record<string, any>>({
18
- propertyKey,
19
- value,
20
- showError,
21
- error,
22
- disabled,
23
- property,
24
- setValue,
25
- partOfBlock,
26
- tableMode,
27
- includeDescription,
28
- underlyingValueHasChanged,
29
- autoFocus,
30
- context
31
- }: FieldProps<T>) {
17
+ export function MapFieldBinding({
18
+ propertyKey,
19
+ value,
20
+ showError,
21
+ error,
22
+ disabled,
23
+ property,
24
+ setValue,
25
+ partOfBlock,
26
+ tableMode,
27
+ includeDescription,
28
+ underlyingValueHasChanged,
29
+ autoFocus,
30
+ context
31
+ }: FieldProps<Record<string, any>>) {
32
32
 
33
33
  const pickOnlySomeKeys = property.pickOnlySomeKeys || false;
34
34
  const expanded = (property.expanded === undefined ? true : property.expanded) || autoFocus;
@@ -53,7 +53,7 @@ export function ReadOnlyFieldBinding({
53
53
  <PropertyPreview propertyKey={propertyKey}
54
54
  value={value}
55
55
  property={property}
56
- // entity={entity}
56
+ // entity={entity}
57
57
  size={"medium"}/>
58
58
  </ErrorBoundary>
59
59
 
@@ -95,6 +95,7 @@ function ReferenceFieldBindingInternal<M extends Record<string, any>>({
95
95
  {value && <ReferencePreview
96
96
  disabled={!property.path}
97
97
  previewProperties={property.previewProperties}
98
+ hover={!disabled}
98
99
  size={"medium"}
99
100
  onClick={disabled || isSubmitting ? undefined : onEntryClick}
100
101
  reference={value}
@@ -3,6 +3,7 @@ import React, { useCallback } from "react";
3
3
  import {
4
4
  ArrayProperty,
5
5
  Entity,
6
+ EntityCollection,
6
7
  FieldProps,
7
8
  ResolvedArrayProperty,
8
9
  ResolvedStringProperty,
@@ -10,10 +11,10 @@ import {
10
11
  } from "../../types";
11
12
  import { useDropzone } from "react-dropzone";
12
13
  import { PreviewSize } from "../../preview";
13
- import { FieldHelperText,LabelWithIcon } from "../components";
14
+ import { FieldHelperText, LabelWithIcon } from "../components";
14
15
 
15
16
  import { getIconForProperty, isReadOnly } from "../../util";
16
- import { useSnackbarController, useStorageSource } from "../../hooks";
17
+ import { useSnackbarController, useStorageSource } from "../../hooks";
17
18
  import { DragDropContext, Draggable, Droppable } from "@hello-pangea/dnd";
18
19
  import { StorageFieldItem, useStorageUploadController } from "../../util/useStorageUploadController";
19
20
  import { StorageUploadProgress } from "../components/StorageUploadProgress";
@@ -55,13 +56,13 @@ export function StorageUploadFieldBinding({
55
56
  property,
56
57
  includeDescription,
57
58
  context,
58
- isSubmitting
59
+ isSubmitting,
59
60
  }: StorageUploadFieldProps) {
60
61
 
61
62
  if (!context.entityId)
62
63
  throw new Error("StorageUploadFieldBinding: Entity id is null");
63
64
 
64
- const storageSource = useStorageSource();
65
+ const storageSource = useStorageSource(context.collection);
65
66
  const disabled = isReadOnly(property) || !!property.disabled || isSubmitting;
66
67
 
67
68
  const {
@@ -108,6 +109,7 @@ export function StorageUploadFieldBinding({
108
109
 
109
110
  <StorageUpload
110
111
  value={internalValue}
112
+ collection={context.collection}
111
113
  name={propertyKey}
112
114
  disabled={disabled}
113
115
  autoFocus={autoFocus}
@@ -133,6 +135,7 @@ export function StorageUploadFieldBinding({
133
135
 
134
136
  function FileDropComponent({
135
137
  storage,
138
+ collection,
136
139
  disabled,
137
140
  isDraggingOver,
138
141
  onFilesAdded,
@@ -151,6 +154,7 @@ function FileDropComponent({
151
154
  helpText
152
155
  }: {
153
156
  storage: StorageConfig,
157
+ collection: EntityCollection,
154
158
  disabled: boolean,
155
159
  isDraggingOver: boolean,
156
160
  droppableProvided: any,
@@ -231,6 +235,7 @@ function FileDropComponent({
231
235
  if (entry.storagePathOrDownloadUrl) {
232
236
  child = (
233
237
  <StorageItemPreview
238
+ collection={collection}
234
239
  name={`storage_preview_${entry.storagePathOrDownloadUrl}`}
235
240
  property={property}
236
241
  disabled={disabled}
@@ -294,6 +299,7 @@ function FileDropComponent({
294
299
 
295
300
  export interface StorageUploadProps {
296
301
  value: StorageFieldItem[];
302
+ collection: EntityCollection;
297
303
  setInternalValue: (v: StorageFieldItem[]) => void;
298
304
  name: string;
299
305
  property: ResolvedStringProperty | ResolvedArrayProperty<string[]>;
@@ -309,6 +315,7 @@ export interface StorageUploadProps {
309
315
  }
310
316
 
311
317
  export function StorageUpload({
318
+ collection,
312
319
  property,
313
320
  name,
314
321
  value,
@@ -321,7 +328,7 @@ export function StorageUpload({
321
328
  autoFocus,
322
329
  storage,
323
330
  entity,
324
- storagePathBuilder
331
+ storagePathBuilder,
325
332
  }: StorageUploadProps) {
326
333
 
327
334
  if (multipleFilesSupported) {
@@ -401,6 +408,7 @@ export function StorageUpload({
401
408
  className="rounded"
402
409
  >
403
410
  <StorageItemPreview
411
+ collection={collection}
404
412
  name={`storage_preview_${entry.storagePathOrDownloadUrl}`}
405
413
  property={renderProperty}
406
414
  disabled={true}
@@ -414,6 +422,7 @@ export function StorageUpload({
414
422
  >
415
423
  {(provided, snapshot) => {
416
424
  return <FileDropComponent storage={storage}
425
+ collection={collection}
417
426
  disabled={disabled}
418
427
  isDraggingOver={snapshot.isDraggingOver}
419
428
  droppableProvided={provided}
@@ -7,7 +7,7 @@ import { getIconForProperty } from "../../util";
7
7
  import { PropertyPreview } from "../../preview";
8
8
  import { useClearRestoreValue } from "../useClearRestoreValue";
9
9
 
10
- interface TextFieldProps<T extends string | number> extends FieldProps<T> {
10
+ interface TextFieldBindingProps<T extends string | number> extends FieldProps<T> {
11
11
  allowInfinity?: boolean
12
12
  }
13
13
 
@@ -18,6 +18,7 @@ interface TextFieldProps<T extends string | number> extends FieldProps<T> {
18
18
  * @group Form fields
19
19
  */
20
20
  export function TextFieldBinding<T extends string | number>({
21
+ context,
21
22
  propertyKey,
22
23
  value,
23
24
  setValue,
@@ -27,7 +28,7 @@ export function TextFieldBinding<T extends string | number>({
27
28
  autoFocus,
28
29
  property,
29
30
  includeDescription,
30
- }: TextFieldProps<T>) {
31
+ }: TextFieldBindingProps<T>) {
31
32
 
32
33
  let multiline: boolean | undefined;
33
34
  let url: boolean | PreviewType | undefined;
@@ -96,9 +97,10 @@ export function TextFieldBinding<T extends string | number>({
96
97
  {url && <Collapse
97
98
  className="mt-1 ml-1"
98
99
  in={Boolean(value)}>
99
- <PropertyPreview value={value}
100
- property={property}
101
- size={"medium"}/>
100
+ <PropertyPreview
101
+ value={value}
102
+ property={property}
103
+ size={"medium"}/>
102
104
  </Collapse>}
103
105
 
104
106
  </>
@@ -9,8 +9,7 @@ import {
9
9
  } from "../types";
10
10
  import * as yup from "yup";
11
11
  import { AnySchema, ArraySchema, BooleanSchema, DateSchema, NumberSchema, ObjectSchema, StringSchema } from "yup";
12
- import { enumToObjectEntries } from "../util/enums";
13
- import { getValueInPath, hydrateRegExp, isPropertyBuilder } from "../util";
12
+ import { enumToObjectEntries, getValueInPath, hydrateRegExp, isPropertyBuilder } from "../util";
14
13
 
15
14
  // Add custom unique function for array values
16
15
  declare module "yup" {
@@ -90,12 +89,12 @@ export function mapPropertyToYup<T extends CMSType>(propertyContext: PropertyCon
90
89
  throw Error("Unsupported data type in yup mapping");
91
90
  }
92
91
 
93
- export function getYupMapObjectSchema<M extends Record<string, any>>({
92
+ export function getYupMapObjectSchema({
94
93
  property,
95
94
  entityId,
96
95
  customFieldValidator,
97
96
  name
98
- }: PropertyContext<M>): ObjectSchema<any> {
97
+ }: PropertyContext<Record<string, any>>): ObjectSchema<any> {
99
98
  const objectSchema: any = {};
100
99
  const validation = property.validation;
101
100
  if (property.properties)
@@ -70,7 +70,7 @@ export function useCollectionFetch<M extends Record<string, any>, UserType exten
70
70
  searchString
71
71
  }: CollectionFetchProps<M>): CollectionFetchResult<M> {
72
72
 
73
- const dataSource = useDataSource();
73
+ const dataSource = useDataSource(collection);
74
74
  const navigationController = useNavigationController();
75
75
 
76
76
  const path = navigationController.resolveAliasesFrom(inputPath);
@@ -1,9 +1,14 @@
1
- import { useContext } from "react";
2
- import { DataSource } from "../../types";
1
+ import { useContext, useMemo } from "react";
2
+ import { DataSource, EntityCollection } from "../../types";
3
3
  import { DataSourceContext } from "../../contexts/DataSourceContext";
4
4
 
5
5
  /**
6
6
  * Use this hook to get the datasource being used
7
7
  * @group Hooks and utilities
8
8
  */
9
- export const useDataSource = (): DataSource => useContext(DataSourceContext);
9
+ export const useDataSource = (collection?: EntityCollection): DataSource => {
10
+ const defaultDataSource = useContext(DataSourceContext);
11
+ if (collection?.overrides?.dataSource)
12
+ return collection?.overrides.dataSource;
13
+ return defaultDataSource;
14
+ };
@@ -43,7 +43,7 @@ export function useEntityFetch<M extends Record<string, any>, UserType extends U
43
43
  useCache = false
44
44
  }: EntityFetchProps<M>): EntityFetchResult<M> {
45
45
 
46
- const dataSource = useDataSource();
46
+ const dataSource = useDataSource(collection);
47
47
  const navigationController = useNavigationController();
48
48
 
49
49
  const path = navigationController.resolveAliasesFrom(inputPath);