@firecms/core 3.0.1 → 3.1.0-canary.7d91b7c

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 (185) 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 +5266 -1578
  42. package/dist/index.es.js.map +1 -1
  43. package/dist/index.umd.js +5260 -1573
  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/index.tsx +4 -0
  123. package/src/contexts/BreacrumbsContext.tsx +15 -8
  124. package/src/contexts/index.ts +10 -0
  125. package/src/core/DefaultAppBar.tsx +40 -27
  126. package/src/core/DefaultDrawer.tsx +42 -56
  127. package/src/core/DrawerNavigationGroup.tsx +118 -0
  128. package/src/core/DrawerNavigationItem.tsx +4 -3
  129. package/src/core/EntityEditView.tsx +41 -43
  130. package/src/core/EntitySidePanel.tsx +28 -26
  131. package/src/core/SideDialogs.tsx +4 -2
  132. package/src/core/field_configs.tsx +14 -9
  133. package/src/core/index.tsx +1 -0
  134. package/src/form/EntityForm.tsx +69 -60
  135. package/src/form/PropertyFieldBinding.tsx +61 -46
  136. package/src/form/components/ErrorFocus.tsx +3 -3
  137. package/src/form/components/StorageItemPreview.tsx +2 -1
  138. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +0 -1
  139. package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -16
  140. package/src/form/field_bindings/KeyValueFieldBinding.tsx +0 -1
  141. package/src/form/field_bindings/MapFieldBinding.tsx +69 -67
  142. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +22 -18
  143. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +83 -83
  144. package/src/form/field_bindings/TextFieldBinding.tsx +71 -35
  145. package/src/form/validation.ts +245 -160
  146. package/src/hooks/useBreadcrumbsController.tsx +18 -0
  147. package/src/hooks/useBuildNavigationController.tsx +46 -23
  148. package/src/hooks/useCollapsedGroups.ts +12 -4
  149. package/src/hooks/useValidateAuthenticator.tsx +1 -1
  150. package/src/internal/useBuildDataSource.ts +68 -34
  151. package/src/internal/useBuildSideDialogsController.tsx +11 -8
  152. package/src/internal/useBuildSideEntityController.tsx +2 -4
  153. package/src/internal/useRestoreScroll.tsx +26 -14
  154. package/src/preview/PropertyPreview.tsx +41 -32
  155. package/src/preview/PropertyPreviewProps.tsx +6 -0
  156. package/src/preview/components/DatePreview.tsx +72 -4
  157. package/src/preview/components/EmptyValue.tsx +1 -1
  158. package/src/preview/components/ImagePreview.tsx +37 -21
  159. package/src/preview/components/StorageThumbnail.tsx +16 -12
  160. package/src/preview/components/UrlComponentPreview.tsx +28 -25
  161. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +9 -7
  162. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +11 -9
  163. package/src/preview/property_previews/ArrayPropertyPreview.tsx +26 -24
  164. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +61 -56
  165. package/src/routes/CustomCMSRoute.tsx +1 -0
  166. package/src/routes/FireCMSRoute.tsx +26 -13
  167. package/src/types/analytics.ts +10 -0
  168. package/src/types/collections.ts +57 -3
  169. package/src/types/datasource.ts +54 -56
  170. package/src/types/plugins.tsx +69 -1
  171. package/src/types/properties.ts +347 -27
  172. package/src/util/__tests__/conditions.test.ts +506 -0
  173. package/src/util/__tests__/objects.test.ts +196 -0
  174. package/src/util/callbacks.ts +6 -3
  175. package/src/util/collections.ts +51 -6
  176. package/src/util/conditions.ts +339 -0
  177. package/src/util/entities.ts +29 -30
  178. package/src/util/entity_cache.ts +2 -1
  179. package/src/util/index.ts +2 -1
  180. package/src/util/join_collections.ts +10 -8
  181. package/src/util/objects.ts +31 -13
  182. package/src/util/{references.ts → previews.ts} +16 -2
  183. package/src/util/property_utils.tsx +37 -11
  184. package/src/util/resolutions.ts +62 -58
  185. /package/dist/util/{references.d.ts → previews.d.ts} +0 -0
@@ -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-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",
37
+ "hover:bg-surface-accent-300 hover:bg-opacity-75 hover:bg-surface-accent-300/75 dark:hover:bg-surface-accent-800 dark:hover:bg-opacity-75 dark:hover:bg-surface-accent-800/75 text-text-primary dark:text-surface-200 hover:text-surface-900 hover:dark:text-white hover:bg-surface-accent-300/75 dark:hover:bg-surface-accent-800/75",
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-10" : "pl-4 h-9",
42
42
  "font-semibold text-xs",
43
- isActive ? "bg-surface-accent-200 bg-opacity-60 dark:bg-surface-800 dark:bg-opacity-50" : ""
43
+ isActive ? "bg-surface-accent-200 bg-opacity-60 dark:bg-surface-800 dark:bg-opacity-50 bg-surface-accent-200/60 dark:bg-surface-800/50" : ""
44
44
  )}
45
45
  to={url}
46
46
  >
@@ -49,8 +49,9 @@ export function DrawerNavigationItem({
49
49
 
50
50
  <div
51
51
  className={cls(
52
+ "text-text-primary dark:text-surface-200",
52
53
  drawerOpen ? "opacity-100" : "opacity-0 hidden",
53
- "ml-4 font-inherit text-inherit"
54
+ "ml-4 font-inherit"
54
55
  )}>
55
56
  {name.toUpperCase()}
56
57
  </div>
@@ -75,7 +75,7 @@ export interface EntityEditViewProps<M extends Record<string, any>> {
75
75
  copy?: boolean;
76
76
  selectedTab?: string;
77
77
  parentCollectionIds: string[];
78
- onValuesModified?: (modified: boolean, values:M) => void;
78
+ onValuesModified?: (modified: boolean, values: M) => void;
79
79
  onSaved?: (params: OnUpdateParams) => void;
80
80
  onTabChange?: (props: OnTabChangeParams<M>) => void;
81
81
  layout?: "side_panel" | "full_screen";
@@ -88,9 +88,9 @@ export interface EntityEditViewProps<M extends Record<string, any>> {
88
88
  * an entity is opened.
89
89
  */
90
90
  export function EntityEditView<M extends Record<string, any>, USER extends User>({
91
- entityId,
92
- ...props
93
- }: EntityEditViewProps<M>) {
91
+ entityId,
92
+ ...props
93
+ }: EntityEditViewProps<M>) {
94
94
 
95
95
  const {
96
96
  entity,
@@ -123,7 +123,7 @@ export function EntityEditView<M extends Record<string, any>, USER extends User>
123
123
  }, [authController, entity, status]);
124
124
 
125
125
  if ((dataLoading && !initialDirtyValues) || (!entity || canEdit === undefined) && (status === "existing" || status === "copy")) {
126
- return <CircularProgressCenter/>;
126
+ return <CircularProgressCenter />;
127
127
  }
128
128
 
129
129
  if (entityId && !entity && !initialDirtyValues) {
@@ -131,36 +131,36 @@ export function EntityEditView<M extends Record<string, any>, USER extends User>
131
131
  }
132
132
 
133
133
  return <EntityEditViewInner<M> {...props}
134
- entityId={entityId}
135
- entity={entity}
136
- initialDirtyValues={initialDirtyValues as Partial<M>}
137
- dataLoading={dataLoading}
138
- status={status}
139
- setStatus={setStatus}
140
- canEdit={canEdit}
134
+ entityId={entityId}
135
+ entity={entity}
136
+ initialDirtyValues={initialDirtyValues as Partial<M>}
137
+ dataLoading={dataLoading}
138
+ status={status}
139
+ setStatus={setStatus}
140
+ canEdit={canEdit}
141
141
  />;
142
142
  }
143
143
 
144
144
  export function EntityEditViewInner<M extends Record<string, any>>({
145
- path,
146
- fullIdPath,
147
- entityId,
148
- selectedTab: selectedTabProp,
149
- collection,
150
- parentCollectionIds,
151
- onValuesModified,
152
- onSaved,
153
- onTabChange,
154
- entity,
155
- initialDirtyValues,
156
- dataLoading,
157
- layout = "side_panel",
158
- barActions,
159
- status,
160
- setStatus,
161
- formProps,
162
- canEdit
163
- }: EntityEditViewProps<M> & {
145
+ path,
146
+ fullIdPath,
147
+ entityId,
148
+ selectedTab: selectedTabProp,
149
+ collection,
150
+ parentCollectionIds,
151
+ onValuesModified,
152
+ onSaved,
153
+ onTabChange,
154
+ entity,
155
+ initialDirtyValues,
156
+ dataLoading,
157
+ layout = "side_panel",
158
+ barActions,
159
+ status,
160
+ setStatus,
161
+ formProps,
162
+ canEdit
163
+ }: EntityEditViewProps<M> & {
164
164
  entity?: Entity<M>,
165
165
  initialDirtyValues?: Partial<M>, // dirty cached entity in memory
166
166
  dataLoading: boolean,
@@ -312,7 +312,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
312
312
  role="tabpanel">
313
313
  <ErrorBoundary>
314
314
  <EntityJsonPreview
315
- values={formContext?.values ?? entity?.values ?? {}}/>
315
+ values={formContext?.values ?? entity?.values ?? {}} />
316
316
  </ErrorBoundary>
317
317
  </div>;
318
318
 
@@ -328,7 +328,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
328
328
  key={`subcol_${subcollectionId}`}
329
329
  role="tabpanel">
330
330
 
331
- {globalLoading && <CircularProgressCenter/>}
331
+ {globalLoading && <CircularProgressCenter />}
332
332
 
333
333
  {!globalLoading &&
334
334
  (usedEntity && newFullPath
@@ -339,7 +339,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
339
339
  isSubCollection={true}
340
340
  updateUrl={false}
341
341
  {...subcollection}
342
- openEntityMode={layout}/>
342
+ openEntityMode={layout} />
343
343
  : <div className="flex items-center justify-center w-full h-full p-3">
344
344
  <Typography variant={"label"}>
345
345
  You need to save your entity before
@@ -375,8 +375,8 @@ export function EntityEditViewInner<M extends Record<string, any>>({
375
375
  className={"px-8 h-full overflow-auto"}
376
376
  entity={entity}
377
377
  path={path}
378
- collection={collection}/>
379
- <div className="h-16"/>
378
+ collection={collection} />
379
+ <div className="h-16" />
380
380
  </div>
381
381
  </div> : null;
382
382
 
@@ -396,7 +396,6 @@ export function EntityEditViewInner<M extends Record<string, any>>({
396
396
  disabled={!canEdit}
397
397
  {...formProps}
398
398
  onEntityChange={(entity) => {
399
- console.log("333 EntityEditView onEntityChange:", entity);
400
399
  setUsedEntity(entity);
401
400
  formProps?.onEntityChange?.(entity);
402
401
  }}
@@ -452,7 +451,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
452
451
  let result = <div className="relative flex flex-col h-full w-full bg-white dark:bg-surface-900">
453
452
 
454
453
  {shouldShowTopBar && <div
455
- className={cls("h-14 items-center flex overflow-visible overflow-x-scroll w-full no-scrollbar h-14 border-b pl-2 pr-2 pt-1 flex bg-surface-50 dark:bg-surface-900", defaultBorderMixin)}>
454
+ className={cls("h-14 items-center overflow-visible overflow-x-scroll w-full no-scrollbar border-b pl-2 pr-2 flex gap-2 bg-surface-50 dark:bg-surface-900", defaultBorderMixin)}>
456
455
 
457
456
  {barActions?.({
458
457
  path: fullIdPath ?? path,
@@ -461,16 +460,15 @@ export function EntityEditViewInner<M extends Record<string, any>>({
461
460
  status
462
461
  })}
463
462
 
464
- <div className={"flex-grow"}/>
463
+ <div className={"flex-grow"} />
465
464
 
466
465
  {pluginActionsTop}
467
466
 
468
467
  {globalLoading && <div className="self-center">
469
- <CircularProgress size={"small"}/>
468
+ <CircularProgress size={"small"} />
470
469
  </div>}
471
470
 
472
471
  {hasAdditionalViews && <Tabs
473
- className={"self-end"}
474
472
  value={selectedTab}
475
473
  onValueChange={(value) => {
476
474
  onSideTabClick(value);
@@ -480,7 +478,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
480
478
  disabled={!hasAdditionalViews}
481
479
  value={JSON_TAB_VALUE}
482
480
  className={"text-sm"}>
483
- <CodeIcon size={"small"}/>
481
+ <CodeIcon size={"small"} />
484
482
  </Tab>}
485
483
 
486
484
  {customViewTabsStart}
@@ -501,7 +499,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
501
499
 
502
500
  {globalLoading
503
501
  ? <div className="w-full pt-12 pb-16 px-4 sm:px-8 md:px-10">
504
- <CircularProgressCenter/>
502
+ <CircularProgressCenter />
505
503
  </div>
506
504
  : <>
507
505
  {entityReadOnlyView}
@@ -105,7 +105,7 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
105
105
  }, [collection?.name, setBlocked, setBlockedNavigationMessage]);
106
106
 
107
107
  if (!props || !collection) {
108
- return <div className={"w-full"}/>;
108
+ return <div className={"w-full"} />;
109
109
  }
110
110
 
111
111
  return (
@@ -120,32 +120,34 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
120
120
  onValuesModified={onValuesModified}
121
121
  onSaved={onUpdate}
122
122
  barActions={({
123
- status,
124
- values
125
- }) => <>
126
- <IconButton
127
- className="self-center"
128
- onClick={onClose}>
129
- <CloseIcon size={"small"}/>
130
- </IconButton>
131
- {allowFullScreen && <IconButton
132
- className="self-center"
133
- onClick={() => {
134
- const key = (status === "new" || status === "copy") ? path + "#new" : path + "/" + entityId;
135
- saveEntityToMemoryCache(key, values);
136
- if (entityId)
137
- navigate(location.pathname);
138
- else
139
- navigate(location.pathname + "#new");
140
- }}>
141
- <OpenInFullIcon size={"small"}/>
142
- </IconButton>}
143
- </>}
123
+ status,
124
+ values
125
+ }) => <>
126
+ <IconButton
127
+ className="self-center"
128
+ size={"smallest"}
129
+ onClick={onClose}>
130
+ <CloseIcon size={"smallest"} />
131
+ </IconButton>
132
+ {allowFullScreen && <IconButton
133
+ className="self-center"
134
+ size={"smallest"}
135
+ onClick={() => {
136
+ const key = (status === "new" || status === "copy") ? path + "#new" : path + "/" + entityId;
137
+ saveEntityToMemoryCache(key, values);
138
+ if (entityId)
139
+ navigate(location.pathname);
140
+ else
141
+ navigate(location.pathname + "#new");
142
+ }}>
143
+ <OpenInFullIcon size={"smallest"} />
144
+ </IconButton>}
145
+ </>}
144
146
  onTabChange={({
145
- entityId,
146
- selectedTab,
147
- collection,
148
- }) => {
147
+ entityId,
148
+ selectedTab,
149
+ collection,
150
+ }) => {
149
151
  sideEntityController.replace({
150
152
  path,
151
153
  entityId,
@@ -1,10 +1,11 @@
1
1
  import React, { useContext, useEffect, useState } from "react";
2
2
  import { useSideDialogsController } from "../hooks";
3
- import { SideDialogPanelProps } from "../types";
3
+ import { EntitySidePanelProps, SideDialogPanelProps } from "../types";
4
4
  import { Sheet } from "@firecms/ui";
5
5
  import { useNavigationUnsavedChangesDialog } from "../internal/useUnsavedChangesDialog";
6
6
  import { ErrorBoundary } from "../components";
7
7
  import { UnsavedChangesDialog } from "../components/UnsavedChangesDialog";
8
+ import { EntitySidePanel } from "./EntitySidePanel";
8
9
 
9
10
  export type SideDialogController = {
10
11
  blocked: boolean,
@@ -157,7 +158,8 @@ function SideDialogView({
157
158
  }}
158
159
  >
159
160
  <ErrorBoundary>
160
- {panel.component}
161
+ {/* Lazy render EntitySidePanel from props for better performance */}
162
+ {panel.component ?? (panel.additional ? <EntitySidePanel {...(panel.additional as EntitySidePanelProps)} /> : null)}
161
163
  </ErrorBoundary>
162
164
  </div>}
163
165
 
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { ArrayProperty, FieldProps, Property, PropertyConfig, ResolvedProperty } from "../types";
3
+ import { ArrayProperty, FieldProps, NumberProperty, Property, PropertyConfig, ResolvedProperty, StringProperty } from "../types";
4
4
  import {
5
5
  ArrayCustomShapedFieldBinding,
6
6
  ArrayOfReferencesFieldBinding,
@@ -397,14 +397,19 @@ export function getDefaultFieldId(property: Property | ResolvedProperty) {
397
397
  return "custom_array";
398
398
  } else if (isPropertyBuilder(of)) {
399
399
  return "repeat";
400
- } else if (of?.dataType === "string" && of.enumValues) {
401
- return "multi_select";
402
- } else if (of?.dataType === "number" && of.enumValues) {
403
- return "multi_number_select";
404
- } else if (of?.dataType === "string" && of.storage) {
405
- return "multi_file_upload";
406
- } else if (of?.dataType === "reference") {
407
- return "multi_references";
400
+ } else if (of) {
401
+ const ofProperty = of as Property;
402
+ if (ofProperty.dataType === "string" && (ofProperty as StringProperty).enumValues) {
403
+ return "multi_select";
404
+ } else if (ofProperty.dataType === "number" && (ofProperty as NumberProperty).enumValues) {
405
+ return "multi_number_select";
406
+ } else if (ofProperty.dataType === "string" && (ofProperty as StringProperty).storage) {
407
+ return "multi_file_upload";
408
+ } else if (ofProperty.dataType === "reference") {
409
+ return "multi_references";
410
+ } else {
411
+ return "repeat";
412
+ }
408
413
  } else {
409
414
  return "repeat";
410
415
  }
@@ -2,6 +2,7 @@ export * from "./FireCMS";
2
2
 
3
3
  export * from "./DefaultDrawer";
4
4
  export * from "./DrawerNavigationItem";
5
+ export * from "./DrawerNavigationGroup";
5
6
 
6
7
  export * from "./field_configs";
7
8
 
@@ -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>