@firecms/core 3.0.1 → 3.1.0-canary.24c8270

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 (186) hide show
  1. package/README.md +1 -1
  2. package/dist/components/AIIcon.d.ts +16 -0
  3. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +7 -1
  4. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
  5. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +14 -0
  6. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +6 -0
  7. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +5 -4
  8. package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +6 -0
  9. package/dist/components/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +2 -2
  10. package/dist/components/EntityCollectionView/Board.d.ts +2 -0
  11. package/dist/components/EntityCollectionView/BoardColumn.d.ts +42 -0
  12. package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +9 -0
  13. package/dist/components/EntityCollectionView/BoardSortableList.d.ts +14 -0
  14. package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +26 -0
  15. package/dist/components/EntityCollectionView/EntityCard.d.ts +19 -0
  16. package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +20 -0
  17. package/dist/components/EntityCollectionView/EntityCollectionCardView.d.ts +31 -0
  18. package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +2 -2
  19. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +7 -3
  20. package/dist/components/EntityCollectionView/FiltersDialog.d.ts +14 -0
  21. package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +44 -0
  22. package/dist/components/EntityCollectionView/board_types.d.ts +105 -0
  23. package/dist/components/EntityCollectionView/useBoardDataController.d.ts +60 -0
  24. package/dist/components/ErrorBoundary.d.ts +1 -1
  25. package/dist/components/SelectableTable/SelectableTable.d.ts +5 -1
  26. package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +2 -1
  27. package/dist/components/VirtualTable/VirtualTableCell.d.ts +6 -0
  28. package/dist/components/VirtualTable/VirtualTableHeader.d.ts +3 -1
  29. package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
  30. package/dist/components/VirtualTable/VirtualTableProps.d.ts +11 -0
  31. package/dist/components/VirtualTable/fields/VirtualTableDateField.d.ts +1 -0
  32. package/dist/components/VirtualTable/types.d.ts +2 -0
  33. package/dist/components/index.d.ts +3 -0
  34. package/dist/contexts/index.d.ts +10 -0
  35. package/dist/core/DrawerNavigationGroup.d.ts +45 -0
  36. package/dist/core/index.d.ts +1 -0
  37. package/dist/form/components/ErrorFocus.d.ts +1 -1
  38. package/dist/form/validation.d.ts +3 -2
  39. package/dist/hooks/useBreadcrumbsController.d.ts +16 -0
  40. package/dist/hooks/useCollapsedGroups.d.ts +4 -1
  41. package/dist/index.es.js +5316 -1592
  42. package/dist/index.es.js.map +1 -1
  43. package/dist/index.umd.js +5309 -1586
  44. package/dist/index.umd.js.map +1 -1
  45. package/dist/internal/useRestoreScroll.d.ts +1 -1
  46. package/dist/preview/PropertyPreviewProps.d.ts +5 -0
  47. package/dist/preview/components/DatePreview.d.ts +13 -3
  48. package/dist/preview/components/ImagePreview.d.ts +5 -1
  49. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  50. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  51. package/dist/preview/property_previews/ArrayOfStorageComponentsPreview.d.ts +1 -1
  52. package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +1 -1
  53. package/dist/preview/property_previews/SkeletonPropertyComponent.d.ts +1 -1
  54. package/dist/types/analytics.d.ts +1 -1
  55. package/dist/types/collections.d.ts +50 -2
  56. package/dist/types/datasource.d.ts +0 -1
  57. package/dist/types/plugins.d.ts +62 -1
  58. package/dist/types/properties.d.ts +259 -4
  59. package/dist/util/__tests__/conditions.test.d.ts +1 -0
  60. package/dist/util/__tests__/objects.test.d.ts +1 -0
  61. package/dist/util/conditions.d.ts +26 -0
  62. package/dist/util/entities.d.ts +2 -3
  63. package/dist/util/index.d.ts +2 -1
  64. package/dist/util/property_utils.d.ts +2 -1
  65. package/dist/util/resolutions.d.ts +3 -3
  66. package/package.json +14 -11
  67. package/src/app/Scaffold.tsx +14 -15
  68. package/src/components/AIIcon.tsx +39 -0
  69. package/src/components/ArrayContainer.tsx +1 -4
  70. package/src/components/ClearFilterSortButton.tsx +19 -16
  71. package/src/components/ConfirmationDialog.tsx +0 -2
  72. package/src/components/DeleteEntityDialog.tsx +2 -4
  73. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +74 -41
  74. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +130 -79
  75. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +121 -104
  76. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +132 -103
  77. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +20 -42
  78. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +90 -49
  79. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
  80. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
  81. package/src/components/EntityCollectionView/Board.tsx +324 -0
  82. package/src/components/EntityCollectionView/BoardColumn.tsx +158 -0
  83. package/src/components/EntityCollectionView/BoardColumnTitle.tsx +45 -0
  84. package/src/components/EntityCollectionView/BoardSortableList.tsx +172 -0
  85. package/src/components/EntityCollectionView/EntityBoardCard.tsx +212 -0
  86. package/src/components/EntityCollectionView/EntityCard.tsx +235 -0
  87. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +733 -0
  88. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +244 -0
  89. package/src/components/EntityCollectionView/EntityCollectionView.tsx +519 -203
  90. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +31 -19
  91. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +84 -15
  92. package/src/components/EntityCollectionView/FiltersDialog.tsx +249 -0
  93. package/src/components/EntityCollectionView/ViewModeToggle.tsx +199 -0
  94. package/src/components/EntityCollectionView/board_types.ts +113 -0
  95. package/src/components/EntityCollectionView/useBoardDataController.tsx +490 -0
  96. package/src/components/ErrorTooltip.tsx +2 -1
  97. package/src/components/HomePage/DefaultHomePage.tsx +47 -10
  98. package/src/components/HomePage/HomePageDnD.tsx +56 -41
  99. package/src/components/HomePage/NavigationCard.tsx +20 -18
  100. package/src/components/HomePage/NavigationGroup.tsx +17 -16
  101. package/src/components/HomePage/RenameGroupDialog.tsx +0 -2
  102. package/src/components/HomePage/SmallNavigationCard.tsx +10 -9
  103. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -10
  104. package/src/components/ReferenceWidget.tsx +2 -4
  105. package/src/components/SelectableTable/SelectableTable.tsx +75 -67
  106. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +7 -6
  107. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +39 -40
  108. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +38 -38
  109. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +49 -58
  110. package/src/components/UnsavedChangesDialog.tsx +0 -2
  111. package/src/components/UserDisplay.tsx +4 -4
  112. package/src/components/VirtualTable/VirtualTable.tsx +272 -118
  113. package/src/components/VirtualTable/VirtualTableCell.tsx +18 -2
  114. package/src/components/VirtualTable/VirtualTableHeader.tsx +59 -50
  115. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +158 -42
  116. package/src/components/VirtualTable/VirtualTableProps.tsx +14 -1
  117. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  118. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -0
  119. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +19 -6
  120. package/src/components/VirtualTable/types.tsx +2 -0
  121. package/src/components/common/useColumnsIds.tsx +95 -3
  122. package/src/components/common/useDataSourceTableController.tsx +21 -4
  123. package/src/components/index.tsx +4 -0
  124. package/src/contexts/BreacrumbsContext.tsx +15 -8
  125. package/src/contexts/index.ts +10 -0
  126. package/src/core/DefaultAppBar.tsx +40 -27
  127. package/src/core/DefaultDrawer.tsx +42 -56
  128. package/src/core/DrawerNavigationGroup.tsx +118 -0
  129. package/src/core/DrawerNavigationItem.tsx +4 -3
  130. package/src/core/EntityEditView.tsx +41 -43
  131. package/src/core/EntitySidePanel.tsx +28 -26
  132. package/src/core/SideDialogs.tsx +4 -2
  133. package/src/core/field_configs.tsx +14 -9
  134. package/src/core/index.tsx +1 -0
  135. package/src/form/EntityForm.tsx +69 -60
  136. package/src/form/PropertyFieldBinding.tsx +61 -46
  137. package/src/form/components/ErrorFocus.tsx +3 -3
  138. package/src/form/components/StorageItemPreview.tsx +2 -1
  139. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +0 -1
  140. package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -16
  141. package/src/form/field_bindings/KeyValueFieldBinding.tsx +0 -1
  142. package/src/form/field_bindings/MapFieldBinding.tsx +69 -67
  143. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +22 -18
  144. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +83 -83
  145. package/src/form/field_bindings/TextFieldBinding.tsx +71 -35
  146. package/src/form/validation.ts +245 -160
  147. package/src/hooks/useBreadcrumbsController.tsx +18 -0
  148. package/src/hooks/useBuildNavigationController.tsx +71 -28
  149. package/src/hooks/useCollapsedGroups.ts +12 -4
  150. package/src/hooks/useValidateAuthenticator.tsx +1 -1
  151. package/src/internal/useBuildDataSource.ts +68 -34
  152. package/src/internal/useBuildSideDialogsController.tsx +11 -8
  153. package/src/internal/useBuildSideEntityController.tsx +24 -24
  154. package/src/internal/useRestoreScroll.tsx +26 -14
  155. package/src/preview/PropertyPreview.tsx +41 -32
  156. package/src/preview/PropertyPreviewProps.tsx +6 -0
  157. package/src/preview/components/DatePreview.tsx +72 -4
  158. package/src/preview/components/EmptyValue.tsx +1 -1
  159. package/src/preview/components/ImagePreview.tsx +37 -21
  160. package/src/preview/components/StorageThumbnail.tsx +16 -12
  161. package/src/preview/components/UrlComponentPreview.tsx +28 -25
  162. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +9 -7
  163. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +11 -9
  164. package/src/preview/property_previews/ArrayPropertyPreview.tsx +26 -24
  165. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +61 -56
  166. package/src/routes/CustomCMSRoute.tsx +1 -0
  167. package/src/routes/FireCMSRoute.tsx +26 -13
  168. package/src/types/analytics.ts +10 -0
  169. package/src/types/collections.ts +57 -3
  170. package/src/types/datasource.ts +54 -56
  171. package/src/types/plugins.tsx +69 -1
  172. package/src/types/properties.ts +347 -27
  173. package/src/util/__tests__/conditions.test.ts +506 -0
  174. package/src/util/__tests__/objects.test.ts +196 -0
  175. package/src/util/callbacks.ts +6 -3
  176. package/src/util/collections.ts +51 -6
  177. package/src/util/conditions.ts +339 -0
  178. package/src/util/entities.ts +29 -30
  179. package/src/util/entity_cache.ts +2 -1
  180. package/src/util/index.ts +2 -1
  181. package/src/util/join_collections.ts +10 -8
  182. package/src/util/objects.ts +31 -13
  183. package/src/util/{references.ts → previews.ts} +16 -2
  184. package/src/util/property_utils.tsx +37 -11
  185. package/src/util/resolutions.ts +62 -58
  186. /package/dist/util/{references.d.ts → previews.d.ts} +0 -0
@@ -181,30 +181,30 @@ export function getChanges<T extends object>(source: Partial<T>, comparison: Par
181
181
  }
182
182
 
183
183
  export function EntityForm<M extends Record<string, any>>({
184
- path,
185
- fullIdPath,
186
- entityId: entityIdProp,
187
- collection,
188
- onValuesModified,
189
- onIdChange,
190
- onSaved,
191
- entity,
192
- initialDirtyValues,
193
- onFormContextReady,
194
- forceActionsAtTheBottom,
195
- initialStatus,
196
- className,
197
- onStatusChange,
198
- onEntityChange,
199
- openEntityMode = "full_screen",
200
- formex: formexProp,
201
- disabled: disabledProp,
202
- Builder,
203
- EntityFormActionsComponent = EntityFormActions,
204
- showDefaultActions = true,
205
- showEntityPath = true,
206
- children
207
- }: EntityFormProps<M>) {
184
+ path,
185
+ fullIdPath,
186
+ entityId: entityIdProp,
187
+ collection,
188
+ onValuesModified,
189
+ onIdChange,
190
+ onSaved,
191
+ entity,
192
+ initialDirtyValues,
193
+ onFormContextReady,
194
+ forceActionsAtTheBottom,
195
+ initialStatus,
196
+ className,
197
+ onStatusChange,
198
+ onEntityChange,
199
+ openEntityMode = "full_screen",
200
+ formex: formexProp,
201
+ disabled: disabledProp,
202
+ Builder,
203
+ EntityFormActionsComponent = EntityFormActions,
204
+ showDefaultActions = true,
205
+ showEntityPath = true,
206
+ children
207
+ }: EntityFormProps<M>) {
208
208
 
209
209
  if (collection.customId && collection.formAutoSave) {
210
210
  console.warn(`The collection ${collection.path} has customId and formAutoSave enabled. This is not supported and formAutoSave will be ignored`);
@@ -455,12 +455,12 @@ export function EntityForm<M extends Record<string, any>>({
455
455
  }, [entityId, path, snackbarController]);
456
456
 
457
457
  const saveEntity = ({
458
- values,
459
- previousValues,
460
- entityId,
461
- collection,
462
- path
463
- }: {
458
+ values,
459
+ previousValues,
460
+ entityId,
461
+ collection,
462
+ path
463
+ }: {
464
464
  collection: EntityCollection<M>,
465
465
  path: string,
466
466
  entityId: string | undefined,
@@ -493,13 +493,13 @@ export function EntityForm<M extends Record<string, any>>({
493
493
  };
494
494
 
495
495
  const onSaveEntityRequest = async ({
496
- collection,
497
- path,
498
- entityId,
499
- values,
500
- previousValues,
501
- autoSave
502
- }: EntityFormSaveParams<M>): Promise<void> => {
496
+ collection,
497
+ path,
498
+ entityId,
499
+ values,
500
+ previousValues,
501
+ autoSave
502
+ }: EntityFormSaveParams<M>): Promise<void> => {
503
503
  if (!status)
504
504
  return;
505
505
  if (autoSave) {
@@ -567,6 +567,7 @@ export function EntityForm<M extends Record<string, any>>({
567
567
  }, [snackbarController]);
568
568
 
569
569
  const pluginActions: React.ReactNode[] = [];
570
+ const pluginBeforeTitle: React.ReactNode[] = [];
570
571
  const plugins = customizationController.plugins;
571
572
 
572
573
  const actionsDisabled = disabled || formex.isSubmitting || (status === "existing" && !formex.dirty) || Boolean(disabledProp);
@@ -590,6 +591,12 @@ export function EntityForm<M extends Record<string, any>>({
590
591
  key={`actions_${plugin.key}`} {...actionProps} />
591
592
  : null
592
593
  )).filter(Boolean));
594
+ pluginBeforeTitle.push(...plugins.map((plugin) => (
595
+ plugin.form?.BeforeTitle
596
+ ? <plugin.form.BeforeTitle
597
+ key={`before_title_${plugin.key}`} {...actionProps} />
598
+ : null
599
+ )).filter(Boolean));
593
600
  }
594
601
 
595
602
  const titlePropertyKey = getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs);
@@ -631,17 +638,17 @@ export function EntityForm<M extends Record<string, any>>({
631
638
  const modified = formex.dirty;
632
639
 
633
640
  const uniqueFieldValidator: CustomFieldValidator = useCallback(({
634
- name,
635
- value
636
- }) => dataSource.checkUniqueField(path, name, value, entityId, collection),
641
+ name,
642
+ value
643
+ }) => dataSource.checkUniqueField(path, name, value, entityId, collection),
637
644
  [dataSource, path, entityId]);
638
645
 
639
646
  const validationSchema = useMemo(() => entityId
640
- ? getYupEntitySchema(
641
- entityId,
642
- resolvedCollection.properties,
643
- uniqueFieldValidator)
644
- : undefined,
647
+ ? getYupEntitySchema(
648
+ entityId,
649
+ resolvedCollection.properties,
650
+ uniqueFieldValidator)
651
+ : undefined,
645
652
  [entityId, resolvedCollection.properties, uniqueFieldValidator]);
646
653
 
647
654
  useOnAutoSave(autoSave, formex, lastSavedValues, save);
@@ -699,8 +706,8 @@ export function EntityForm<M extends Record<string, any>>({
699
706
 
700
707
  return (
701
708
  <FormEntry propertyKey={key}
702
- widthPercentage={widthPercentage}
703
- key={`field_${key}`}>
709
+ widthPercentage={widthPercentage}
710
+ key={`field_${key}`}>
704
711
  <PropertyFieldBinding {...cmsFormFieldProps} />
705
712
  </FormEntry>
706
713
  );
@@ -713,7 +720,7 @@ export function EntityForm<M extends Record<string, any>>({
713
720
  throw new Error("When using additional fields you need to provide a Builder or a value");
714
721
  }
715
722
  const child = Builder
716
- ? <Builder entity={entity} context={context}/>
723
+ ? <Builder entity={entity} context={context} />
717
724
  : <div className={"w-full"}>
718
725
  {additionalField.value?.({
719
726
  entity,
@@ -725,9 +732,9 @@ export function EntityForm<M extends Record<string, any>>({
725
732
  <div key={`additional_${key}`} className={"w-full"}>
726
733
  <LabelWithIconAndTooltip
727
734
  propertyKey={key}
728
- icon={<NotesIcon size={"small"}/>}
735
+ icon={<NotesIcon size={"small"} />}
729
736
  title={additionalField.name}
730
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
737
+ className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"} />
731
738
  <div
732
739
  className={cls(paperMixin, "w-full min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
733
740
  <ErrorBoundary>
@@ -749,6 +756,8 @@ export function EntityForm<M extends Record<string, any>>({
749
756
 
750
757
  const formView = <ErrorBoundary>
751
758
  <>
759
+ {pluginBeforeTitle}
760
+
752
761
  {!Builder && <div className={"w-full py-2 flex flex-col items-start my-4 lg:my-6"}>
753
762
  <Typography
754
763
  className={"my-4 flex-grow line-clamp-1 " + (collection.hideIdFromForm ? "mb-6" : "")}
@@ -777,22 +786,22 @@ export function EntityForm<M extends Record<string, any>>({
777
786
 
778
787
  {!Builder && !collection.hideIdFromForm &&
779
788
  <CustomIdField customId={collection.customId}
780
- entityId={entityId}
781
- status={status}
782
- onChange={setEntityId}
783
- error={entityIdError}
784
- loading={customIdLoading}
785
- entity={entity}/>
789
+ entityId={entityId}
790
+ status={status}
791
+ onChange={setEntityId}
792
+ error={entityIdError}
793
+ loading={customIdLoading}
794
+ entity={entity} />
786
795
  }
787
796
 
788
797
  {entityId && formContext && <>
789
798
  <div className="mt-12 flex flex-col gap-8" ref={formRef}>
790
799
  {formFields()}
791
- <ErrorFocus containerRef={formRef}/>
800
+ <ErrorFocus containerRef={formRef} />
792
801
  </div>
793
802
  </>}
794
803
 
795
- {forceActionsAtTheBottom && <div className="h-16"/>}
804
+ {forceActionsAtTheBottom && <div className="h-16" />}
796
805
  </>
797
806
  </ErrorBoundary>;
798
807
 
@@ -852,12 +861,12 @@ export function EntityForm<M extends Record<string, any>>({
852
861
  {formex.dirty
853
862
  ? <Tooltip title={"This form has been modified"}>
854
863
  <Chip size={"small"} className={"py-1"} colorScheme={"orangeDarker"}>
855
- <EditIcon size={"smallest"}/>
864
+ <EditIcon size={"smallest"} />
856
865
  </Chip>
857
866
  </Tooltip>
858
867
  : <Tooltip title={"The current form is in sync with the database"}>
859
868
  <Chip size={"small"} className={"py-1"}>
860
- <CheckIcon size={"smallest"}/>
869
+ <CheckIcon size={"smallest"} />
861
870
  </Chip>
862
871
  </Tooltip>}
863
872
  </div>
@@ -75,21 +75,21 @@ export const PropertyFieldBinding = React.memo(PropertyFieldBindingInternal, (a:
75
75
  }) as typeof PropertyFieldBindingInternal;
76
76
 
77
77
  function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Record<string, any> = any>
78
- ({
79
- propertyKey,
80
- property,
81
- context,
82
- includeDescription,
83
- underlyingValueHasChanged,
84
- disabled: disabledProp,
85
- partOfArray,
86
- partOfBlock,
87
- minimalistView,
88
- autoFocus,
89
- index,
90
- size,
91
- onPropertyChange,
92
- }: PropertyFieldBindingProps<T, M>): ReactElement<PropertyFieldBindingProps<T, M>> {
78
+ ({
79
+ propertyKey,
80
+ property,
81
+ context,
82
+ includeDescription,
83
+ underlyingValueHasChanged,
84
+ disabled: disabledProp,
85
+ partOfArray,
86
+ partOfBlock,
87
+ minimalistView,
88
+ autoFocus,
89
+ index,
90
+ size,
91
+ onPropertyChange,
92
+ }: PropertyFieldBindingProps<T, M>): ReactElement<PropertyFieldBindingProps<T, M>> {
93
93
 
94
94
  const authController = useAuthController();
95
95
  const customizationController = useCustomizationController();
@@ -137,7 +137,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
137
137
  }
138
138
  const configProperty = resolveProperty({
139
139
  propertyKey,
140
- propertyOrBuilder: propertyConfig.property,
140
+ propertyOrBuilder: propertyConfig.property as any,
141
141
  values: fieldProps.form.values,
142
142
  path: context.path,
143
143
  entityId: context.entityId,
@@ -145,7 +145,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
145
145
  index,
146
146
  authController
147
147
  });
148
- Component = configProperty.Field as ComponentType<FieldProps<T>>;
148
+ Component = configProperty?.Field as ComponentType<FieldProps<T>> | undefined;
149
149
  }
150
150
  if (!Component) {
151
151
  console.warn(`No field component found for property ${propertyKey}`);
@@ -175,7 +175,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
175
175
  return <FieldInternal
176
176
  Component={Component as ComponentType<FieldProps>}
177
177
  componentProps={componentProps}
178
- formexFieldProps={fieldProps}/>;
178
+ formexFieldProps={fieldProps} />;
179
179
  }}
180
180
  </Field>
181
181
  );
@@ -185,39 +185,54 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
185
185
  type ResolvedPropertyFieldBindingProps<T extends CMSType = CMSType, M extends Record<string, any> = any> =
186
186
  Omit<PropertyFieldBindingProps<T, M>, "property">
187
187
  & {
188
- property: ResolvedProperty<T>
189
- };
188
+ property: ResolvedProperty<T>
189
+ };
190
190
 
191
191
  function FieldInternal<T extends CMSType, CustomProps, M extends Record<string, any>>
192
- ({
193
- Component,
194
- componentProps: {
195
- propertyKey,
196
- property,
197
- includeDescription,
198
- underlyingValueHasChanged,
199
- partOfArray,
200
- partOfBlock,
201
- minimalistView,
202
- autoFocus,
203
- context,
204
- disabled,
205
- size,
206
- onPropertyChange
207
- },
208
- formexFieldProps
209
- }:
210
- {
211
- Component: ComponentType<FieldProps<T, any, M>>,
212
- componentProps: ResolvedPropertyFieldBindingProps<T, M>,
213
- formexFieldProps: FormexFieldProps<T, any>
214
- }) {
192
+ ({
193
+ Component,
194
+ componentProps: {
195
+ propertyKey,
196
+ property,
197
+ includeDescription,
198
+ underlyingValueHasChanged,
199
+ partOfArray,
200
+ partOfBlock,
201
+ minimalistView,
202
+ autoFocus,
203
+ context,
204
+ disabled,
205
+ size,
206
+ onPropertyChange
207
+ },
208
+ formexFieldProps
209
+ }:
210
+ {
211
+ Component: ComponentType<FieldProps<T, any, M>>,
212
+ componentProps: ResolvedPropertyFieldBindingProps<T, M>,
213
+ formexFieldProps: FormexFieldProps<T, any>
214
+ }) {
215
215
 
216
216
  const { plugins } = useCustomizationController();
217
217
 
218
218
  const customFieldProps: any = property.customProps;
219
219
  const value = formexFieldProps.field.value;
220
- const error = getIn(formexFieldProps.form.errors, propertyKey);
220
+
221
+ // Get error for this field path, but avoid string indexing issues
222
+ // When an array has a string error like "Tags should have unique values",
223
+ // accessing errors["tags"]["0"] returns "T" (string indexing).
224
+ // We traverse the path manually and stop if we hit a string.
225
+ let error: any = formexFieldProps.form.errors;
226
+ for (const part of propertyKey.split(".")) {
227
+ if (error === undefined || error === null) break;
228
+ if (typeof error === "string") {
229
+ // Parent is a string error, children shouldn't inherit individual characters
230
+ error = undefined;
231
+ break;
232
+ }
233
+ error = error[part];
234
+ }
235
+
221
236
  const touched = getIn(formexFieldProps.form.touched, propertyKey);
222
237
 
223
238
  const showError: boolean = error &&
@@ -272,7 +287,7 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
272
287
  return (
273
288
  <ErrorBoundary>
274
289
 
275
- <UsedComponent {...cmsFieldProps}/>
290
+ <UsedComponent {...cmsFieldProps} />
276
291
 
277
292
  {underlyingValueHasChanged && !isSubmitting &&
278
293
  <Typography variant={"caption"} className={"ml-3.5"}>
@@ -287,7 +302,7 @@ const shouldPropertyReRender = (property: PropertyOrBuilder | ResolvedProperty,
287
302
  if (plugins?.some((plugin) => plugin.form?.fieldBuilder)) {
288
303
  return true;
289
304
  }
290
- if (isPropertyBuilder(property)) {
305
+ if (isPropertyBuilder(property as any)) {
291
306
  return true;
292
307
  }
293
308
  const defAProperty = property as Property | ResolvedProperty;
@@ -2,9 +2,9 @@ import React, { useEffect, useRef } from "react";
2
2
  import { useFormex } from "@firecms/formex";
3
3
 
4
4
  export const ErrorFocus = ({ containerRef }:
5
- {
6
- containerRef?: React.RefObject<HTMLDivElement>
7
- }) => {
5
+ {
6
+ containerRef?: React.RefObject<HTMLDivElement | null>
7
+ }) => {
8
8
  const {
9
9
  isValidating,
10
10
  errors,
@@ -29,9 +29,10 @@ export function StorageItemPreview({
29
29
  }: StorageItemPreviewProps) {
30
30
 
31
31
  return (
32
- <div className={cls(paperMixin,
32
+ <div className={cls(
33
33
  "relative border-box flex items-center justify-center",
34
34
  size === "large" ? "min-w-[220px] min-h-[220px] max-w-[220px]" : "min-w-[118px] min-h-[118px] max-w-[118px]",
35
+ paperMixin,
35
36
  className)}>
36
37
 
37
38
  {!placeholder && !disabled &&
@@ -129,7 +129,6 @@ export function ArrayOfReferencesFieldBinding({
129
129
  <Button
130
130
  className="ml-3.5 my-4 justify-center text-left"
131
131
  variant="text"
132
- color="primary"
133
132
  disabled={isSubmitting}
134
133
  onClick={onEntryClick}>
135
134
  <EditIcon size={"small"}/>
@@ -19,17 +19,17 @@ type DateTimeFieldProps = FieldProps<Date>;
19
19
  * @group Form fields
20
20
  */
21
21
  export function DateTimeFieldBinding({
22
- propertyKey,
23
- value,
24
- setValue,
25
- autoFocus,
26
- error,
27
- showError,
28
- disabled,
29
- touched,
30
- property,
31
- includeDescription
32
- }: DateTimeFieldProps) {
22
+ propertyKey,
23
+ value,
24
+ setValue,
25
+ autoFocus,
26
+ error,
27
+ showError,
28
+ disabled,
29
+ touched,
30
+ property,
31
+ includeDescription
32
+ }: DateTimeFieldProps) {
33
33
 
34
34
  const { locale } = useCustomizationController();
35
35
  const internalValue = value || null;
@@ -50,21 +50,22 @@ export function DateTimeFieldBinding({
50
50
  mode={property.mode}
51
51
  clearable={property.clearable}
52
52
  locale={locale}
53
+ timezone={property.timezone}
53
54
  error={showError}
54
55
  disabled={disabled}
55
56
  label={<LabelWithIcon
56
57
  icon={getIconForProperty(property, "small")}
57
58
  required={property.validation?.required}
58
59
  className={showError ? "text-red-500 dark:text-red-500" : "text-text-secondary dark:text-text-secondary-dark"}
59
- title={property.name}/>}
60
+ title={property.name} />}
60
61
  />
61
62
  </PropertyIdCopyTooltip>
62
63
 
63
64
  <FieldHelperText includeDescription={includeDescription}
64
- showError={showError}
65
- error={error}
66
- disabled={disabled}
67
- property={property}/>
65
+ showError={showError}
66
+ error={error}
67
+ disabled={disabled}
68
+ property={property} />
68
69
 
69
70
  </>
70
71
  );
@@ -215,7 +215,6 @@ function MapEditView<T extends Record<string, any>>({
215
215
 
216
216
  <Button variant={"text"}
217
217
  size={"small"}
218
- color="primary"
219
218
  className="w-full"
220
219
  disabled={disabled}
221
220
  startIcon={<AddIcon/>}