@firecms/core 3.0.0-beta.10 → 3.0.0-beta.11

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 (166) hide show
  1. package/dist/components/ArrayContainer.d.ts +17 -5
  2. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
  3. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +2 -2
  4. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +6 -3
  5. package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +1 -1
  6. package/dist/core/EntityEditView.d.ts +1 -1
  7. package/dist/core/FireCMS.d.ts +1 -1
  8. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  9. package/dist/form/components/index.d.ts +0 -1
  10. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  11. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
  12. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
  13. package/dist/hooks/data/delete.d.ts +4 -4
  14. package/dist/hooks/data/save.d.ts +3 -3
  15. package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
  16. package/dist/hooks/data/useEntityFetch.d.ts +3 -3
  17. package/dist/hooks/useAuthController.d.ts +1 -1
  18. package/dist/hooks/useBuildNavigationController.d.ts +3 -3
  19. package/dist/hooks/useFireCMSContext.d.ts +1 -1
  20. package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
  21. package/dist/hooks/useValidateAuthenticator.d.ts +3 -3
  22. package/dist/index.es.js +17515 -14786
  23. package/dist/index.es.js.map +1 -1
  24. package/dist/index.umd.js +17912 -15184
  25. package/dist/index.umd.js.map +1 -1
  26. package/dist/preview/PropertyPreviewProps.d.ts +1 -1
  27. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  28. package/dist/preview/util.d.ts +3 -3
  29. package/dist/types/auth.d.ts +7 -9
  30. package/dist/types/collections.d.ts +14 -13
  31. package/dist/types/datasource.d.ts +0 -4
  32. package/dist/types/entity_actions.d.ts +4 -4
  33. package/dist/types/entity_callbacks.d.ts +16 -16
  34. package/dist/types/export_import.d.ts +4 -4
  35. package/dist/types/fields.d.ts +18 -2
  36. package/dist/types/firecms.d.ts +2 -2
  37. package/dist/types/firecms_context.d.ts +1 -1
  38. package/dist/types/permissions.d.ts +4 -4
  39. package/dist/types/plugins.d.ts +8 -8
  40. package/dist/types/property_config.d.ts +0 -2
  41. package/dist/types/user.d.ts +1 -0
  42. package/dist/util/builders.d.ts +2 -2
  43. package/dist/util/entities.d.ts +1 -1
  44. package/dist/util/icon_synonyms.d.ts +0 -1
  45. package/dist/util/icons.d.ts +3 -1
  46. package/dist/util/objects.d.ts +1 -0
  47. package/dist/util/permissions.d.ts +4 -4
  48. package/dist/util/property_utils.d.ts +2 -2
  49. package/dist/util/resolutions.d.ts +6 -6
  50. package/package.json +131 -125
  51. package/src/app/Scaffold.tsx +4 -4
  52. package/src/components/ArrayContainer.tsx +79 -17
  53. package/src/components/CircularProgressCenter.tsx +1 -1
  54. package/src/components/ConfirmationDialog.tsx +2 -2
  55. package/src/components/DeleteEntityDialog.tsx +9 -18
  56. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +4 -1
  57. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +14 -14
  58. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +2 -2
  59. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +6 -4
  60. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +8 -9
  61. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -11
  62. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +2 -2
  63. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +5 -5
  64. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +2 -2
  65. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +79 -69
  66. package/src/components/EntityCollectionView/EntityCollectionView.tsx +9 -10
  67. package/src/components/EntityCollectionView/useSelectionController.tsx +5 -4
  68. package/src/components/EntityPreview.tsx +39 -30
  69. package/src/components/EntityView.tsx +5 -5
  70. package/src/components/ErrorView.tsx +3 -3
  71. package/src/components/HomePage/DefaultHomePage.tsx +1 -0
  72. package/src/components/HomePage/FavouritesView.tsx +6 -11
  73. package/src/components/HomePage/NavigationCard.tsx +1 -1
  74. package/src/components/HomePage/NavigationCardBinding.tsx +4 -9
  75. package/src/components/HomePage/NavigationGroup.tsx +1 -1
  76. package/src/components/PropertyConfigBadge.tsx +1 -1
  77. package/src/components/PropertyIdCopyTooltip.tsx +1 -1
  78. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +2 -2
  79. package/src/components/SelectableTable/SelectableTable.tsx +2 -2
  80. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +4 -2
  81. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +3 -1
  82. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +7 -5
  83. package/src/components/VirtualTable/VirtualTableHeader.tsx +8 -8
  84. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
  85. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  86. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
  87. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +2 -0
  88. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +2 -2
  89. package/src/contexts/SnackbarProvider.tsx +2 -0
  90. package/src/core/DefaultAppBar.tsx +12 -11
  91. package/src/core/DefaultDrawer.tsx +11 -9
  92. package/src/core/DrawerNavigationItem.tsx +4 -4
  93. package/src/core/EntityEditView.tsx +50 -52
  94. package/src/core/FireCMS.tsx +5 -5
  95. package/src/core/SideDialogs.tsx +1 -1
  96. package/src/core/field_configs.tsx +4 -4
  97. package/src/form/PropertyFieldBinding.tsx +27 -20
  98. package/src/form/components/CustomIdField.tsx +2 -0
  99. package/src/form/components/StorageItemPreview.tsx +3 -3
  100. package/src/form/components/index.tsx +0 -1
  101. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +3 -2
  102. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +16 -10
  103. package/src/form/field_bindings/BlockFieldBinding.tsx +41 -23
  104. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
  105. package/src/form/field_bindings/KeyValueFieldBinding.tsx +10 -7
  106. package/src/form/field_bindings/MapFieldBinding.tsx +58 -39
  107. package/src/form/field_bindings/ReferenceFieldBinding.tsx +4 -4
  108. package/src/form/field_bindings/RepeatFieldBinding.tsx +25 -20
  109. package/src/form/field_bindings/SelectFieldBinding.tsx +5 -4
  110. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +1 -1
  111. package/src/form/field_bindings/SwitchFieldBinding.tsx +25 -25
  112. package/src/form/field_bindings/TextFieldBinding.tsx +3 -3
  113. package/src/hooks/data/delete.ts +4 -4
  114. package/src/hooks/data/save.ts +7 -8
  115. package/src/hooks/data/useCollectionFetch.tsx +2 -2
  116. package/src/hooks/data/useEntityFetch.tsx +5 -5
  117. package/src/hooks/useAuthController.tsx +1 -1
  118. package/src/hooks/useBuildNavigationController.tsx +5 -6
  119. package/src/hooks/useFireCMSContext.tsx +5 -5
  120. package/src/hooks/useResolvedNavigationFrom.tsx +5 -5
  121. package/src/hooks/useValidateAuthenticator.tsx +3 -3
  122. package/src/internal/useBuildDataSource.ts +1 -1
  123. package/src/internal/useUnsavedChangesDialog.tsx +2 -2
  124. package/src/preview/PropertyPreview.tsx +3 -3
  125. package/src/preview/PropertyPreviewProps.tsx +1 -1
  126. package/src/preview/components/BooleanPreview.tsx +1 -1
  127. package/src/preview/components/EmptyValue.tsx +1 -1
  128. package/src/preview/components/EnumValuesChip.tsx +1 -1
  129. package/src/preview/components/ImagePreview.tsx +5 -6
  130. package/src/preview/components/UrlComponentPreview.tsx +4 -4
  131. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  132. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -2
  133. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +2 -2
  134. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +1 -1
  135. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
  136. package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -2
  137. package/src/preview/property_previews/MapPropertyPreview.tsx +4 -4
  138. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +12 -12
  139. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  140. package/src/preview/util.ts +10 -10
  141. package/src/types/auth.tsx +8 -12
  142. package/src/types/collections.ts +14 -13
  143. package/src/types/datasource.ts +0 -5
  144. package/src/types/entity_actions.tsx +4 -4
  145. package/src/types/entity_callbacks.ts +18 -18
  146. package/src/types/export_import.ts +4 -4
  147. package/src/types/fields.tsx +20 -2
  148. package/src/types/firecms.tsx +2 -2
  149. package/src/types/firecms_context.tsx +1 -1
  150. package/src/types/permissions.ts +5 -5
  151. package/src/types/plugins.tsx +8 -8
  152. package/src/types/property_config.tsx +0 -2
  153. package/src/types/user.ts +2 -0
  154. package/src/util/builders.ts +6 -6
  155. package/src/util/entities.ts +3 -1
  156. package/src/util/icon_list.ts +1 -0
  157. package/src/util/icon_synonyms.ts +0 -1
  158. package/src/util/icons.tsx +12 -8
  159. package/src/util/objects.ts +20 -0
  160. package/src/util/permissions.ts +8 -8
  161. package/src/util/property_utils.tsx +10 -3
  162. package/src/util/references.ts +8 -2
  163. package/src/util/resolutions.ts +8 -8
  164. package/src/util/useStorageUploadController.tsx +1 -1
  165. package/dist/form/components/FormikArrayContainer.d.ts +0 -19
  166. package/src/form/components/FormikArrayContainer.tsx +0 -47
@@ -77,19 +77,21 @@ export const DefaultAppBar = function DefaultAppBar({
77
77
 
78
78
  const user = userProp ?? authController.user;
79
79
 
80
- let avatarComponent: JSX.Element;
81
- if (user && user.photoURL) {
82
- avatarComponent = <Avatar
83
- src={user.photoURL}/>;
80
+ let avatarComponent: JSX.Element | null;
81
+
82
+ if (user) {
83
+ const initial = user?.displayName
84
+ ? user.displayName[0].toUpperCase()
85
+ : (user?.email ? user.email[0].toUpperCase() : "A");
86
+ avatarComponent = <Avatar src={user.photoURL ?? undefined}>
87
+ {initial}
88
+ </Avatar>;
84
89
  } else if (user === undefined || authController.initialLoading) {
85
90
  avatarComponent = <div className={"p-1 flex justify-center"}>
86
91
  <Skeleton className={"w-10 h-10 rounded-full"}/>
87
92
  </div>;
88
93
  } else {
89
- const initial = user?.displayName
90
- ? user.displayName[0].toUpperCase()
91
- : (user?.email ? user.email[0].toUpperCase() : "A");
92
- avatarComponent = <Avatar>{initial}</Avatar>;
94
+ avatarComponent = null;
93
95
  }
94
96
 
95
97
  return (
@@ -108,7 +110,7 @@ export const DefaultAppBar = function DefaultAppBar({
108
110
 
109
111
  {navigation && <div className="mr-8 hidden lg:block">
110
112
  <ReactLink
111
- className="visited:text-inherit visited:dark:text-inherit"
113
+ className="visited:text-inherit visited:dark:text-inherit block"
112
114
  to={navigation?.basePath ?? "/"}
113
115
  >
114
116
  <div className={"flex flex-row gap-4"}>
@@ -120,8 +122,7 @@ export const DefaultAppBar = function DefaultAppBar({
120
122
 
121
123
  {typeof title === "string"
122
124
  ? <Typography variant="subtitle1"
123
- noWrap
124
- className={cls("transition-all", drawerOpen ? "ml-2" : "")}>
125
+ noWrap>
125
126
  {title}
126
127
  </Typography>
127
128
  : title}
@@ -79,13 +79,13 @@ export function DefaultDrawer({
79
79
  <DrawerLogo logo={logo}/>
80
80
 
81
81
  <div className={"mt-4 flex-grow overflow-scroll no-scrollbar"}
82
- style={{
83
- maskImage: "linear-gradient(to bottom, transparent 0, black 20px, black calc(100% - 20px), transparent 100%)",
84
- }}>
82
+ style={{
83
+ maskImage: "linear-gradient(to bottom, transparent 0, black 20px, black calc(100% - 20px), transparent 100%)",
84
+ }}>
85
85
 
86
86
  {groupsWithoutAdmin.map((group) => (
87
87
  <div
88
- className={"bg-gray-50 dark:bg-gray-800 dark:bg-opacity-30 my-4 rounded-lg ml-4"}
88
+ className={"bg-surface-50 dark:bg-surface-800 dark:bg-opacity-30 my-4 rounded-lg ml-3 mr-1"}
89
89
  key={`drawer_group_${group}`}>
90
90
  {buildGroupHeader(group)}
91
91
  {Object.values(navigationEntries)
@@ -93,7 +93,8 @@ export function DefaultDrawer({
93
93
  .map((view, index) =>
94
94
  <DrawerNavigationItem
95
95
  key={`navigation_${index}`}
96
- icon={<IconForView collectionOrView={view.collection ?? view.view} size={"small"}/>}
96
+ icon={<IconForView collectionOrView={view.collection ?? view.view}
97
+ size={"small"}/>}
97
98
  tooltipsOpen={tooltipsOpen}
98
99
  adminMenuOpen={adminMenuOpen}
99
100
  drawerOpen={drawerOpen}
@@ -112,7 +113,7 @@ export function DefaultDrawer({
112
113
  trigger={
113
114
  <IconButton
114
115
  shape={"square"}
115
- className={"m-4 text-gray-900 dark:text-white w-fit"}>
116
+ className={"m-4 text-surface-900 dark:text-white w-fit"}>
116
117
  <Tooltip title={"Admin"}
117
118
  open={tooltipsOpen}
118
119
  side={"right"} sideOffset={28}>
@@ -163,18 +164,19 @@ export function DrawerLogo({ logo }: {
163
164
  transition: "padding 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms",
164
165
  padding: drawerOpen ? "32px 144px 0px 24px" : "72px 12px 0px 12px"
165
166
  }}
166
- className={cls("cursor-pointer ml-4")}>
167
+ className={cls("cursor-pointer rounded ml-3 mr-1")}>
167
168
 
168
169
  <Tooltip title={"Home"}
169
170
  sideOffset={20}
170
171
  side="right">
171
172
  <Link
173
+ className={"block"}
172
174
  to={navigation.basePath}>
173
175
  {logo
174
176
  ? <img src={logo}
175
177
  alt="Logo"
176
- className={cls("max-w-full max-h-full",
177
- drawerOpen ?? "w-[112px] h-[112px]")}/>
178
+ className={cls("max-w-full max-h-full transition-all",
179
+ drawerOpen ? "w-[96px] h-[96px]" : "w-[32px] h-[32px]")}/>
178
180
  : <FireCMSLogo/>}
179
181
 
180
182
  </Link>
@@ -22,7 +22,7 @@ export function DrawerNavigationItem({
22
22
  }) {
23
23
 
24
24
  const iconWrap = <div
25
- className={"text-gray-600 dark:text-gray-500"}>
25
+ className={"text-text-secondary dark:text-text-secondary-dark"}>
26
26
  {icon}
27
27
  </div>;
28
28
 
@@ -34,13 +34,13 @@ export function DrawerNavigationItem({
34
34
  transition: drawerOpen ? "width 150ms ease-in" : undefined
35
35
  }}
36
36
  className={({ isActive }: any) => cls("rounded-lg truncate",
37
- "hover:bg-slate-300 hover:bg-opacity-75 dark:hover:bg-slate-800 dark:hover:bg-opacity-75 text-gray-800 dark:text-gray-200 hover:text-gray-900 hover:dark:text-white",
37
+ "hover:bg-surface-accent-300 hover:bg-opacity-75 dark:hover:bg-surface-accent-800 dark:hover:bg-opacity-75 text-text-primary dark:text-surface-200 hover:text-surface-900 hover:dark:text-white",
38
38
  "flex flex-row items-center mr-8",
39
39
  // "transition-all ease-in-out delay-100 duration-300",
40
40
  // drawerOpen ? "w-full" : "w-18",
41
41
  drawerOpen ? "pl-4 h-12" : "pl-4 h-11",
42
- "font-medium text-sm",
43
- isActive ? "bg-slate-200 bg-opacity-60 dark:bg-gray-800 dark:bg-opacity-50" : ""
42
+ "font-semibold text-xs",
43
+ isActive ? "bg-surface-accent-200 bg-opacity-60 dark:bg-surface-800 dark:bg-opacity-50" : ""
44
44
  )}
45
45
  to={url}
46
46
  >
@@ -95,16 +95,16 @@ export interface EntityEditViewProps<M extends Record<string, any>> {
95
95
  * You probably don't want to use this view directly since it is bound to the
96
96
  * side panel.
97
97
  */
98
- export function EntityEditView<M extends Record<string, any>, UserType extends User>({
99
- entityId,
100
- ...props
101
- }: EntityEditViewProps<M>) {
98
+ export function EntityEditView<M extends Record<string, any>, USER extends User>({
99
+ entityId,
100
+ ...props
101
+ }: EntityEditViewProps<M>) {
102
102
  const {
103
103
  entity,
104
104
  dataLoading,
105
105
  // eslint-disable-next-line no-unused-vars
106
106
  dataLoadingError
107
- } = useEntityFetch<M, UserType>({
107
+ } = useEntityFetch<M, USER>({
108
108
  path: props.path,
109
109
  entityId: entityId,
110
110
  collection: props.collection,
@@ -185,7 +185,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
185
185
  collection: inputCollection,
186
186
  path,
187
187
  values: entity?.values,
188
- fields: customizationController.propertyConfigs
188
+ propertyConfigs: customizationController.propertyConfigs
189
189
  }), [entity?.values, path, customizationController.propertyConfigs]);
190
190
 
191
191
  const initialStatus = copy ? "copy" : (entityIdProp ? "existing" : "new");
@@ -431,10 +431,10 @@ export function EntityEditViewInner<M extends Record<string, any>>({
431
431
  return {};
432
432
  })
433
433
  .catch((e: any) => {
434
- const errors: Record<string, string> = {};
435
- e.inner.forEach((error: any) => {
436
- errors[error.path] = error.message;
437
- });
434
+ // const errors: Record<string, string> = {};
435
+ // e.inner.forEach((error: any) => {
436
+ // errors[error.path] = error.message;
437
+ // });
438
438
  return yupToFormErrors(e);
439
439
  });
440
440
  }
@@ -446,7 +446,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
446
446
  entityId,
447
447
  values: formex.values,
448
448
  previousValues: formex.initialValues,
449
- fields: customizationController.propertyConfigs
449
+ propertyConfigs: customizationController.propertyConfigs
450
450
  });
451
451
 
452
452
  const lastSavedValues = useRef<EntityValues<M> | undefined>(entity?.values);
@@ -778,12 +778,14 @@ export function EntityEditViewInner<M extends Record<string, any>>({
778
778
 
779
779
  const child = Builder
780
780
  ? <Builder entity={entity} context={context}/>
781
- : <>{additionalField.value?.({
782
- entity,
783
- context
784
- })}</>;
781
+ : <>
782
+ {additionalField.value?.({
783
+ entity,
784
+ context
785
+ })?.toString()}
786
+ </>;
785
787
  return (
786
- <div>
788
+ <div key={`additional_${key}`}>
787
789
  <LabelWithIconAndTooltip
788
790
  propertyKey={key}
789
791
  icon={<NotesIcon size={"small"}/>}
@@ -806,8 +808,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
806
808
  })
807
809
  .filter(Boolean)}
808
810
 
809
- </>
810
- );
811
+ </>);
811
812
 
812
813
  const disabled = formex.isSubmitting || (!modified && status === "existing");
813
814
  const formRef = React.useRef<HTMLDivElement>(null);
@@ -888,49 +889,46 @@ export function EntityEditViewInner<M extends Record<string, any>>({
888
889
  let form = <>
889
890
 
890
891
  {pluginActions.length > 0 && <div
891
- className={cls("w-full flex justify-end items-center sticky top-0 right-0 left-0 z-10 bg-opacity-60 bg-slate-200 dark:bg-opacity-60 dark:bg-slate-800 backdrop-blur-md")}>
892
+ className={cls("w-full flex justify-end items-center sticky top-0 right-0 left-0 z-10 bg-opacity-60 bg-surface-accent-200 dark:bg-opacity-60 dark:bg-surface-accent-800 backdrop-blur-md")}>
892
893
  {pluginActions}
893
894
  </div>}
894
895
 
895
- <div className="h-full overflow-auto">
896
+ <div className="pt-12 pb-16 pl-4 sm:px-8 md:px-10">
897
+ <div
898
+ className={`w-full py-2 flex flex-col items-start mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>
896
899
 
897
- <div className="pt-12 pb-16 pl-4 sm:px-8 md:px-10">
898
- <div
899
- className={`w-full py-2 flex flex-col items-start mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>
900
-
901
- <Typography
902
- className={"mt-4 flex-grow line-clamp-1 " + inputCollection.hideIdFromForm ? "mb-2" : "mb-0"}
903
- variant={"h4"}>{title ?? inputCollection.singularName ?? inputCollection.name}
904
- </Typography>
905
- <Alert color={"base"} className={"w-full"} size={"small"}>
906
- <code className={"text-xs select-all"}>{path}/{entityId}</code>
907
- </Alert>
908
- </div>
900
+ <Typography
901
+ className={"mt-4 flex-grow line-clamp-1 " + inputCollection.hideIdFromForm ? "mb-2" : "mb-0"}
902
+ variant={"h4"}>{title ?? inputCollection.singularName ?? inputCollection.name}
903
+ </Typography>
904
+ <Alert color={"base"} className={"w-full"} size={"small"}>
905
+ <code className={"text-xs select-all"}>{path}/{entityId}</code>
906
+ </Alert>
907
+ </div>
909
908
 
910
- {!collection.hideIdFromForm &&
911
- <CustomIdField customId={inputCollection.customId}
912
- entityId={entityId}
913
- status={status}
914
- onChange={setEntityId}
915
- error={entityIdError}
916
- loading={customIdLoading}
917
- entity={entity}/>}
909
+ {!collection.hideIdFromForm &&
910
+ <CustomIdField customId={inputCollection.customId}
911
+ entityId={entityId}
912
+ status={status}
913
+ onChange={setEntityId}
914
+ error={entityIdError}
915
+ loading={customIdLoading}
916
+ entity={entity}/>}
918
917
 
919
- {entityId && formContext && <>
920
- <div className="mt-12 flex flex-col gap-8"
921
- ref={formRef}>
918
+ {entityId && formContext && <>
919
+ <div className="mt-12 flex flex-col gap-8"
920
+ ref={formRef}>
922
921
 
923
- {formFields}
922
+ {formFields}
924
923
 
925
- <ErrorFocus containerRef={formRef}/>
924
+ <ErrorFocus containerRef={formRef}/>
926
925
 
927
- </div>
926
+ </div>
928
927
 
929
- <div className="h-14"/>
928
+ <div className="h-14"/>
930
929
 
931
- </>}
930
+ </>}
932
931
 
933
- </div>
934
932
  </div>
935
933
  </>;
936
934
 
@@ -1004,10 +1002,10 @@ export function EntityEditViewInner<M extends Record<string, any>>({
1004
1002
  return (
1005
1003
  <Formex value={formex}>
1006
1004
 
1007
- <div className="flex flex-col h-full w-full transition-width duration-250 ease-in-out">
1005
+ <div className="flex flex-col h-full w-full">
1008
1006
 
1009
1007
  <div
1010
- className={cls(defaultBorderMixin, "no-scrollbar border-b pl-2 pr-2 pt-1 flex items-end overflow-scroll bg-gray-50 dark:bg-gray-950")}>
1008
+ className={cls(defaultBorderMixin, "no-scrollbar h-16 border-b pl-2 pr-2 pt-1 flex items-end overflow-scroll bg-surface-50 dark:bg-surface-950")}>
1011
1009
 
1012
1010
  <div
1013
1011
  className="pb-1 self-center">
@@ -1032,7 +1030,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
1032
1030
  onValueChange={(value) => {
1033
1031
  onSideTabClick(value);
1034
1032
  }}
1035
- className="pl-4 pr-4 pt-0">
1033
+ innerClassName="pl-4 pr-4 pt-0">
1036
1034
 
1037
1035
  <Tab
1038
1036
  disabled={!hasAdditionalViews}
@@ -1,5 +1,7 @@
1
- import React, { useMemo } from "react";
1
+ "use client";
2
2
 
3
+ import React, { useMemo } from "react";
4
+ import { CenteredView, Typography } from "@firecms/ui";
3
5
  import { CustomizationController, EntityCollection, FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
4
6
  import { AuthControllerContext } from "../contexts";
5
7
  import { useBuildSideEntityController } from "../internal/useBuildSideEntityController";
@@ -12,7 +14,6 @@ import { DataSourceContext } from "../contexts/DataSourceContext";
12
14
  import { SideEntityControllerContext } from "../contexts/SideEntityControllerContext";
13
15
  import { NavigationContext } from "../contexts/NavigationContext";
14
16
  import { SideDialogsControllerContext } from "../contexts/SideDialogsControllerContext";
15
- import { CenteredView, Typography, useLocaleConfig } from "@firecms/ui";
16
17
  import { DialogsProvider } from "../contexts/DialogsProvider";
17
18
  import { useBuildDataSource } from "../internal/useBuildDataSource";
18
19
  import { CustomizationControllerContext } from "../contexts/CustomizationControllerContext";
@@ -31,7 +32,7 @@ import { useProjectLog } from "../hooks/useProjectLog";
31
32
 
32
33
  * @group Core
33
34
  */
34
- export function FireCMS<UserType extends User, EC extends EntityCollection>(props: FireCMSProps<UserType, EC>) {
35
+ export function FireCMS<USER extends User, EC extends EntityCollection>(props: FireCMSProps<USER, EC>) {
35
36
 
36
37
  const {
37
38
  children,
@@ -51,8 +52,6 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
51
52
  apiKey
52
53
  } = props;
53
54
 
54
- useLocaleConfig(locale);
55
-
56
55
  /**
57
56
  * Controller in charge of fetching and persisting data
58
57
  */
@@ -89,6 +88,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
89
88
  dataSourceDelegate,
90
89
  plugins
91
90
  });
91
+
92
92
  if (accessResponse?.message) {
93
93
  console.warn(accessResponse.message);
94
94
  }
@@ -130,7 +130,7 @@ function SideDialogView({
130
130
  >
131
131
  {panel &&
132
132
  <div
133
- className={"transform max-w-[100vw] lg:max-w-[95vw] flex flex-col h-full transition-all duration-250 ease-in-out bg-white dark:bg-gray-900 "}
133
+ className={"transform max-w-[100vw] lg:max-w-[95vw] flex flex-col h-full transition-all duration-250 ease-in-out bg-white dark:bg-surface-900 "}
134
134
  style={{
135
135
  width: panel.width,
136
136
  transform: `translateX(-${offsetPosition * 200}px)`
@@ -23,7 +23,6 @@ import {
23
23
  AddLinkIcon,
24
24
  BallotIcon,
25
25
  DriveFolderUploadIcon,
26
- EmailIcon,
27
26
  FlagIcon,
28
27
  FormatListNumberedIcon,
29
28
  FormatQuoteIcon,
@@ -31,6 +30,7 @@ import {
31
30
  LinkIcon,
32
31
  ListAltIcon,
33
32
  ListIcon,
33
+ MailIcon,
34
34
  NumbersIcon,
35
35
  RepeatIcon,
36
36
  ScheduleIcon,
@@ -96,7 +96,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
96
96
  key: "email",
97
97
  name: "Email",
98
98
  description: "Text with email validation",
99
- Icon: EmailIcon,
99
+ Icon: MailIcon,
100
100
  color: "#154fb3",
101
101
  property: {
102
102
  dataType: "string",
@@ -129,7 +129,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
129
129
  },
130
130
  multi_select: {
131
131
  key: "multi_select",
132
- name: "Multi select",
132
+ name: "Multi select (enum)",
133
133
  description: "Select multiple text values from within an enumeration",
134
134
  Icon: ListAltIcon,
135
135
  color: "#4223c9",
@@ -300,7 +300,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
300
300
  block: {
301
301
  key: "block",
302
302
  name: "Block",
303
- description: "A complex field that allows the user to compose different fields together, with a key->value format",
303
+ description: "A complex field that allows the user to compose different fields together, with a key/value format",
304
304
  Icon: ViewStreamIcon,
305
305
  color: "#ff9408",
306
306
  property: {
@@ -81,12 +81,13 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
81
81
  context,
82
82
  includeDescription,
83
83
  underlyingValueHasChanged,
84
- disabled,
84
+ disabled: disabledProp,
85
85
  partOfArray,
86
86
  minimalistView,
87
87
  autoFocus,
88
88
  index,
89
- size
89
+ size,
90
+ onPropertyChange
90
91
  }: PropertyFieldBindingProps<T, M>): ReactElement<PropertyFieldBindingProps<T, M>> {
91
92
 
92
93
  const customizationController = useCustomizationController();
@@ -105,10 +106,12 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
105
106
  values: fieldProps.form.values,
106
107
  path: context.path,
107
108
  entityId: context.entityId,
108
- fields: customizationController.propertyConfigs,
109
+ propertyConfigs: customizationController.propertyConfigs,
109
110
  index
110
111
  });
111
112
 
113
+ const disabled = disabledProp || isReadOnly(resolvedProperty) || Boolean(resolvedProperty?.disabled);
114
+
112
115
  if (resolvedProperty === null || isHidden(resolvedProperty)) {
113
116
  return <></>;
114
117
  } else if (isReadOnly(resolvedProperty)) {
@@ -122,6 +125,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
122
125
  if (!propertyConfig) {
123
126
  console.log("INTERNAL: Could not find field config for property", {
124
127
  propertyKey,
128
+ property,
125
129
  resolvedProperty,
126
130
  fields: customizationController.propertyConfigs,
127
131
  propertyConfig
@@ -134,7 +138,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
134
138
  values: fieldProps.form.values,
135
139
  path: context.path,
136
140
  entityId: context.entityId,
137
- fields: customizationController.propertyConfigs,
141
+ propertyConfigs: customizationController.propertyConfigs,
138
142
  index
139
143
  });
140
144
  Component = configProperty.Field as ComponentType<FieldProps<T>>;
@@ -157,13 +161,14 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
157
161
  partOfArray,
158
162
  minimalistView,
159
163
  autoFocus,
160
- size
164
+ size,
165
+ onPropertyChange
161
166
  };
162
167
 
163
168
  return <FieldInternal
164
169
  Component={Component as ComponentType<FieldProps>}
165
170
  componentProps={componentProps}
166
- fieldProps={fieldProps}/>;
171
+ formexFieldProps={fieldProps}/>;
167
172
  }}
168
173
  </Field>
169
174
  );
@@ -189,26 +194,27 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
189
194
  autoFocus,
190
195
  context,
191
196
  disabled,
192
- size
197
+ size,
198
+ onPropertyChange
193
199
  },
194
- fieldProps
200
+ formexFieldProps
195
201
  }:
196
202
  {
197
203
  Component: ComponentType<FieldProps<T, any, M>>,
198
204
  componentProps: ResolvedPropertyFieldBindingProps<T, M>,
199
- fieldProps: FormexFieldProps<T, any>
205
+ formexFieldProps: FormexFieldProps<T, any>
200
206
  }) {
201
207
 
202
208
  const { plugins } = useCustomizationController();
203
209
 
204
210
  const customFieldProps: any = property.customProps;
205
- const value = fieldProps.field.value;
206
- // const initialValue = fieldProps.meta.initialValue;
207
- const error = getIn(fieldProps.form.errors, propertyKey);
208
- const touched = getIn(fieldProps.form.touched, propertyKey);
211
+ const value = formexFieldProps.field.value;
212
+ // const initialValue = formexFieldProps.meta.initialValue;
213
+ const error = getIn(formexFieldProps.form.errors, propertyKey);
214
+ const touched = getIn(formexFieldProps.form.touched, propertyKey);
209
215
 
210
216
  const showError: boolean = error &&
211
- (fieldProps.form.submitCount > 0 || property.validation?.unique) &&
217
+ (formexFieldProps.form.submitCount > 0 || property.validation?.unique) &&
212
218
  (!Array.isArray(error) || !!error.filter((e: any) => !!e).length);
213
219
 
214
220
  const WrappedComponent: ComponentType<FieldProps<T, any, M>> | null = useWrappedComponent({
@@ -221,16 +227,16 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
221
227
  });
222
228
  const UsedComponent: ComponentType<FieldProps<T>> = WrappedComponent ?? Component;
223
229
 
224
- const isSubmitting = fieldProps.form.isSubmitting;
230
+ const isSubmitting = formexFieldProps.form.isSubmitting;
225
231
 
226
232
  const setValue = useCallback((value: T | null, shouldValidate?: boolean) => {
227
- fieldProps.form.setFieldTouched(propertyKey, true, false);
228
- fieldProps.form.setFieldValue(propertyKey, value, shouldValidate);
233
+ formexFieldProps.form.setFieldTouched(propertyKey, true, false);
234
+ formexFieldProps.form.setFieldValue(propertyKey, value, shouldValidate);
229
235
  }, []);
230
236
 
231
237
  const setFieldValue = useCallback((otherPropertyKey: string, value: CMSType | null, shouldValidate?: boolean) => {
232
- fieldProps.form.setFieldTouched(propertyKey, true, false);
233
- fieldProps.form.setFieldValue(otherPropertyKey, value, shouldValidate);
238
+ formexFieldProps.form.setFieldTouched(propertyKey, true, false);
239
+ formexFieldProps.form.setFieldValue(otherPropertyKey, value, shouldValidate);
234
240
  }, []);
235
241
 
236
242
  const cmsFieldProps: FieldProps<T, CustomProps, M> = {
@@ -251,7 +257,8 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
251
257
  autoFocus: autoFocus ?? false,
252
258
  customProps: customFieldProps,
253
259
  context,
254
- size
260
+ size,
261
+ onPropertyChange
255
262
  };
256
263
 
257
264
  return (
@@ -100,7 +100,9 @@ export function CustomIdField<M extends Record<string, any>>({
100
100
 
101
101
  {enumValues &&
102
102
  <Select
103
+ size={"large"}
103
104
  error={error}
105
+ fullWidth={true}
104
106
  onValueChange={(v) => onChange(v as string)}
105
107
  {...fieldProps}
106
108
  renderValue={(option) => {
@@ -31,12 +31,12 @@ export function StorageItemPreview({
31
31
  return (
32
32
  <div className={cls(paperMixin,
33
33
  "relative m-4 border-box flex items-center justify-center",
34
- size === "medium" ? "min-w-[220px] min-h-[220px] max-w-[220px]" : "min-w-[118px] min-h-[118px] max-w-[118px]",
34
+ size === "large" ? "min-w-[220px] min-h-[220px] max-w-[220px]" : "min-w-[118px] min-h-[118px] max-w-[118px]",
35
35
  className)}>
36
36
 
37
37
  {!placeholder && !disabled &&
38
38
  <div
39
- className="absolute rounded-full -top-2 -right-2 z-10 bg-white dark:bg-gray-900">
39
+ className="absolute rounded-full -top-2 -right-2 z-10 bg-white dark:bg-surface-900">
40
40
 
41
41
  <Tooltip
42
42
  asChild={true}
@@ -67,7 +67,7 @@ export function StorageItemPreview({
67
67
  <div
68
68
  onClick={(e) => e.stopPropagation()}
69
69
  className="flex flex-col items-center justify-center w-full h-full">
70
- <DescriptionIcon className="text-gray-700 dark:text-gray-300"/>
70
+ <DescriptionIcon className="text-surface-700 dark:text-surface-300"/>
71
71
  </div>
72
72
  }
73
73
 
@@ -1,4 +1,3 @@
1
- export * from "./FormikArrayContainer";
2
1
  export * from "./FieldHelperText";
3
2
  export * from "./LabelWithIcon";
4
3
  export * from "./LabelWithIconAndTooltip";
@@ -3,7 +3,7 @@ import { FieldProps } from "../../types";
3
3
  import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
4
4
  import { PropertyFieldBinding } from "../PropertyFieldBinding";
5
5
  import { ExpandablePanel, Typography } from "@firecms/ui";
6
- import { getArrayResolvedProperties, getIconForProperty } from "../../util";
6
+ import { getArrayResolvedProperties, getIconForProperty, isReadOnly } from "../../util";
7
7
  import { useClearRestoreValue } from "../useClearRestoreValue";
8
8
 
9
9
  /**
@@ -57,9 +57,10 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
57
57
  </>);
58
58
 
59
59
  const body = resolvedProperties.map((childProperty, index) => {
60
+ const thisDisabled = isReadOnly(childProperty) || Boolean(childProperty.disabled);
60
61
  const fieldProps = {
61
62
  propertyKey: `${propertyKey}[${index}]`,
62
- disabled,
63
+ disabled: disabled || thisDisabled,
63
64
  property: childProperty,
64
65
  includeDescription,
65
66
  underlyingValueHasChanged,