@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.
- package/README.md +1 -1
- package/dist/components/AIIcon.d.ts +16 -0
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +7 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +14 -0
- package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +6 -0
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +5 -4
- package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +6 -0
- package/dist/components/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +2 -2
- package/dist/components/EntityCollectionView/Board.d.ts +2 -0
- package/dist/components/EntityCollectionView/BoardColumn.d.ts +42 -0
- package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +9 -0
- package/dist/components/EntityCollectionView/BoardSortableList.d.ts +14 -0
- package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +26 -0
- package/dist/components/EntityCollectionView/EntityCard.d.ts +19 -0
- package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +20 -0
- package/dist/components/EntityCollectionView/EntityCollectionCardView.d.ts +31 -0
- package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +2 -2
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +7 -3
- package/dist/components/EntityCollectionView/FiltersDialog.d.ts +14 -0
- package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +44 -0
- package/dist/components/EntityCollectionView/board_types.d.ts +105 -0
- package/dist/components/EntityCollectionView/useBoardDataController.d.ts +60 -0
- package/dist/components/ErrorBoundary.d.ts +1 -1
- package/dist/components/SelectableTable/SelectableTable.d.ts +5 -1
- package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +2 -1
- package/dist/components/VirtualTable/VirtualTableCell.d.ts +6 -0
- package/dist/components/VirtualTable/VirtualTableHeader.d.ts +3 -1
- package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +11 -0
- package/dist/components/VirtualTable/fields/VirtualTableDateField.d.ts +1 -0
- package/dist/components/VirtualTable/types.d.ts +2 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/contexts/index.d.ts +10 -0
- package/dist/core/DrawerNavigationGroup.d.ts +45 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/form/components/ErrorFocus.d.ts +1 -1
- package/dist/form/validation.d.ts +3 -2
- package/dist/hooks/useBreadcrumbsController.d.ts +16 -0
- package/dist/hooks/useCollapsedGroups.d.ts +4 -1
- package/dist/index.es.js +5266 -1578
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +5260 -1573
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useRestoreScroll.d.ts +1 -1
- package/dist/preview/PropertyPreviewProps.d.ts +5 -0
- package/dist/preview/components/DatePreview.d.ts +13 -3
- package/dist/preview/components/ImagePreview.d.ts +5 -1
- package/dist/preview/components/StorageThumbnail.d.ts +2 -1
- package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
- package/dist/preview/property_previews/ArrayOfStorageComponentsPreview.d.ts +1 -1
- package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +1 -1
- package/dist/preview/property_previews/SkeletonPropertyComponent.d.ts +1 -1
- package/dist/types/analytics.d.ts +1 -1
- package/dist/types/collections.d.ts +50 -2
- package/dist/types/datasource.d.ts +0 -1
- package/dist/types/plugins.d.ts +62 -1
- package/dist/types/properties.d.ts +259 -4
- package/dist/util/__tests__/conditions.test.d.ts +1 -0
- package/dist/util/__tests__/objects.test.d.ts +1 -0
- package/dist/util/conditions.d.ts +26 -0
- package/dist/util/entities.d.ts +2 -3
- package/dist/util/index.d.ts +2 -1
- package/dist/util/property_utils.d.ts +2 -1
- package/dist/util/resolutions.d.ts +3 -3
- package/package.json +14 -11
- package/src/app/Scaffold.tsx +14 -15
- package/src/components/AIIcon.tsx +39 -0
- package/src/components/ArrayContainer.tsx +1 -4
- package/src/components/ClearFilterSortButton.tsx +19 -16
- package/src/components/ConfirmationDialog.tsx +0 -2
- package/src/components/DeleteEntityDialog.tsx +2 -4
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +74 -41
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +130 -79
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +121 -104
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +132 -103
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +20 -42
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +90 -49
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
- package/src/components/EntityCollectionView/Board.tsx +324 -0
- package/src/components/EntityCollectionView/BoardColumn.tsx +158 -0
- package/src/components/EntityCollectionView/BoardColumnTitle.tsx +45 -0
- package/src/components/EntityCollectionView/BoardSortableList.tsx +172 -0
- package/src/components/EntityCollectionView/EntityBoardCard.tsx +212 -0
- package/src/components/EntityCollectionView/EntityCard.tsx +235 -0
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +733 -0
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +244 -0
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +519 -203
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +31 -19
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +84 -15
- package/src/components/EntityCollectionView/FiltersDialog.tsx +249 -0
- package/src/components/EntityCollectionView/ViewModeToggle.tsx +199 -0
- package/src/components/EntityCollectionView/board_types.ts +113 -0
- package/src/components/EntityCollectionView/useBoardDataController.tsx +490 -0
- package/src/components/ErrorTooltip.tsx +2 -1
- package/src/components/HomePage/DefaultHomePage.tsx +47 -10
- package/src/components/HomePage/HomePageDnD.tsx +56 -41
- package/src/components/HomePage/NavigationCard.tsx +20 -18
- package/src/components/HomePage/NavigationGroup.tsx +17 -16
- package/src/components/HomePage/RenameGroupDialog.tsx +0 -2
- package/src/components/HomePage/SmallNavigationCard.tsx +10 -9
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -10
- package/src/components/ReferenceWidget.tsx +2 -4
- package/src/components/SelectableTable/SelectableTable.tsx +75 -67
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +7 -6
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +39 -40
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +38 -38
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +49 -58
- package/src/components/UnsavedChangesDialog.tsx +0 -2
- package/src/components/UserDisplay.tsx +4 -4
- package/src/components/VirtualTable/VirtualTable.tsx +272 -118
- package/src/components/VirtualTable/VirtualTableCell.tsx +18 -2
- package/src/components/VirtualTable/VirtualTableHeader.tsx +59 -50
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +158 -42
- package/src/components/VirtualTable/VirtualTableProps.tsx +14 -1
- package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -0
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +19 -6
- package/src/components/VirtualTable/types.tsx +2 -0
- package/src/components/common/useColumnsIds.tsx +95 -3
- package/src/components/index.tsx +4 -0
- package/src/contexts/BreacrumbsContext.tsx +15 -8
- package/src/contexts/index.ts +10 -0
- package/src/core/DefaultAppBar.tsx +40 -27
- package/src/core/DefaultDrawer.tsx +42 -56
- package/src/core/DrawerNavigationGroup.tsx +118 -0
- package/src/core/DrawerNavigationItem.tsx +4 -3
- package/src/core/EntityEditView.tsx +41 -43
- package/src/core/EntitySidePanel.tsx +28 -26
- package/src/core/SideDialogs.tsx +4 -2
- package/src/core/field_configs.tsx +14 -9
- package/src/core/index.tsx +1 -0
- package/src/form/EntityForm.tsx +69 -60
- package/src/form/PropertyFieldBinding.tsx +61 -46
- package/src/form/components/ErrorFocus.tsx +3 -3
- package/src/form/components/StorageItemPreview.tsx +2 -1
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +0 -1
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -16
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +0 -1
- package/src/form/field_bindings/MapFieldBinding.tsx +69 -67
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +22 -18
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +83 -83
- package/src/form/field_bindings/TextFieldBinding.tsx +71 -35
- package/src/form/validation.ts +245 -160
- package/src/hooks/useBreadcrumbsController.tsx +18 -0
- package/src/hooks/useBuildNavigationController.tsx +46 -23
- package/src/hooks/useCollapsedGroups.ts +12 -4
- package/src/hooks/useValidateAuthenticator.tsx +1 -1
- package/src/internal/useBuildDataSource.ts +68 -34
- package/src/internal/useBuildSideDialogsController.tsx +11 -8
- package/src/internal/useBuildSideEntityController.tsx +2 -4
- package/src/internal/useRestoreScroll.tsx +26 -14
- package/src/preview/PropertyPreview.tsx +41 -32
- package/src/preview/PropertyPreviewProps.tsx +6 -0
- package/src/preview/components/DatePreview.tsx +72 -4
- package/src/preview/components/EmptyValue.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +37 -21
- package/src/preview/components/StorageThumbnail.tsx +16 -12
- package/src/preview/components/UrlComponentPreview.tsx +28 -25
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +9 -7
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +11 -9
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +26 -24
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +61 -56
- package/src/routes/CustomCMSRoute.tsx +1 -0
- package/src/routes/FireCMSRoute.tsx +26 -13
- package/src/types/analytics.ts +10 -0
- package/src/types/collections.ts +57 -3
- package/src/types/datasource.ts +54 -56
- package/src/types/plugins.tsx +69 -1
- package/src/types/properties.ts +347 -27
- package/src/util/__tests__/conditions.test.ts +506 -0
- package/src/util/__tests__/objects.test.ts +196 -0
- package/src/util/callbacks.ts +6 -3
- package/src/util/collections.ts +51 -6
- package/src/util/conditions.ts +339 -0
- package/src/util/entities.ts +29 -30
- package/src/util/entity_cache.ts +2 -1
- package/src/util/index.ts +2 -1
- package/src/util/join_collections.ts +10 -8
- package/src/util/objects.ts +31 -13
- package/src/util/{references.ts → previews.ts} +16 -2
- package/src/util/property_utils.tsx +37 -11
- package/src/util/resolutions.ts +62 -58
- /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
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
|
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
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
entityId,
|
|
148
|
+
selectedTab,
|
|
149
|
+
collection,
|
|
150
|
+
}) => {
|
|
149
151
|
sideEntityController.replace({
|
|
150
152
|
path,
|
|
151
153
|
entityId,
|
package/src/core/SideDialogs.tsx
CHANGED
|
@@ -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
|
-
{
|
|
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
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
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
|
}
|
package/src/core/index.tsx
CHANGED
package/src/form/EntityForm.tsx
CHANGED
|
@@ -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
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
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
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
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
|
-
|
|
635
|
-
|
|
636
|
-
|
|
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
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
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
|
-
|
|
703
|
-
|
|
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
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
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>
|