@firecms/core 3.0.0-canary.5 → 3.0.0-canary.51
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 +2 -2
- package/dist/components/ClearFilterSortButton.d.ts +5 -0
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +11 -11
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +5 -3
- package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +3 -2
- package/dist/components/EntityCollectionTable/column_utils.d.ts +1 -2
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -4
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +12 -3
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
- package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
- package/dist/components/EntityPreview.d.ts +25 -7
- package/dist/components/EntityView.d.ts +11 -0
- package/dist/components/FieldCaption.d.ts +5 -0
- package/dist/components/FireCMSAppBar.d.ts +3 -2
- package/dist/components/HomePage/NavigationCard.d.ts +8 -0
- package/dist/components/HomePage/{NavigationCollectionCard.d.ts → NavigationCardBinding.d.ts} +2 -2
- package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
- package/dist/components/HomePage/index.d.ts +3 -1
- package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +1 -1
- package/dist/components/common/types.d.ts +4 -6
- package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +3 -0
- package/dist/components/index.d.ts +4 -2
- package/dist/contexts/AuthControllerContext.d.ts +1 -1
- package/dist/core/Drawer.d.ts +5 -12
- package/dist/core/DrawerNavigationItem.d.ts +9 -0
- package/dist/core/{EntityView.d.ts → EntityEditView.d.ts} +2 -2
- package/dist/core/NavigationRoutes.d.ts +1 -1
- package/dist/core/Scaffold.d.ts +7 -10
- package/dist/core/index.d.ts +3 -4
- package/dist/form/EntityForm.d.ts +1 -1
- package/dist/form/components/ErrorFocus.d.ts +1 -1
- package/dist/form/components/StorageItemPreview.d.ts +3 -2
- package/dist/form/components/StorageUploadProgress.d.ts +1 -1
- package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +4 -3
- package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
- package/dist/form/validation.d.ts +1 -1
- package/dist/hooks/data/delete.d.ts +2 -2
- package/dist/hooks/data/save.d.ts +2 -3
- package/dist/hooks/data/useDataSource.d.ts +2 -2
- package/dist/hooks/data/useEntityFetch.d.ts +3 -3
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/useBuildNavigationController.d.ts +6 -4
- package/dist/hooks/useProjectLog.d.ts +6 -2
- package/dist/hooks/useStorageSource.d.ts +2 -2
- package/dist/hooks/useValidateAuthenticator.d.ts +21 -0
- package/dist/index.es.js +9644 -9122
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +5 -5
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useBuildDataSource.d.ts +1 -12
- package/dist/preview/PropertyPreview.d.ts +1 -1
- package/dist/preview/PropertyPreviewProps.d.ts +1 -4
- package/dist/preview/components/BooleanPreview.d.ts +5 -1
- package/dist/preview/components/EnumValuesChip.d.ts +1 -1
- package/dist/preview/components/ReferencePreview.d.ts +1 -7
- package/dist/types/analytics.d.ts +1 -1
- package/dist/types/auth.d.ts +37 -1
- package/dist/types/collections.d.ts +29 -5
- package/dist/types/datasource.d.ts +3 -6
- package/dist/types/entities.d.ts +5 -1
- package/dist/types/entity_actions.d.ts +14 -0
- package/dist/types/entity_callbacks.d.ts +2 -2
- package/dist/types/entity_overrides.d.ts +6 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/navigation.d.ts +14 -13
- package/dist/types/permissions.d.ts +5 -1
- package/dist/types/plugins.d.ts +20 -20
- package/dist/types/properties.d.ts +4 -4
- package/dist/types/property_config.d.ts +2 -2
- package/dist/types/roles.d.ts +31 -0
- package/dist/types/storage.d.ts +11 -3
- package/dist/types/user.d.ts +5 -0
- package/dist/util/collections.d.ts +9 -1
- package/dist/util/entities.d.ts +1 -1
- package/dist/util/icon_synonyms.d.ts +2 -4
- package/dist/util/icons.d.ts +8 -2
- package/dist/util/navigation_utils.d.ts +2 -2
- package/dist/util/permissions.d.ts +4 -4
- package/dist/util/references.d.ts +4 -2
- package/dist/util/resolutions.d.ts +9 -13
- package/dist/util/useTraceUpdate.d.ts +1 -0
- package/package.json +139 -119
- package/src/components/ClearFilterSortButton.tsx +41 -0
- package/src/components/DeleteEntityDialog.tsx +4 -4
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +2 -2
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +275 -278
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +9 -5
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +44 -44
- package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +9 -16
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +3 -3
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +27 -32
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +11 -6
- package/src/components/EntityCollectionTable/internal/default_entity_actions.tsx +9 -5
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +2 -4
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +560 -554
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -6
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
- package/src/components/EntityCollectionView/useSelectionController.tsx +30 -0
- package/src/components/EntityPreview.tsx +207 -70
- package/src/components/EntityView.tsx +84 -0
- package/src/components/FieldCaption.tsx +14 -0
- package/src/components/FireCMSAppBar.tsx +33 -11
- package/src/components/HomePage/DefaultHomePage.tsx +15 -11
- package/src/components/HomePage/NavigationCard.tsx +69 -0
- package/src/components/HomePage/NavigationCardBinding.tsx +116 -0
- package/src/components/HomePage/SmallNavigationCard.tsx +45 -0
- package/src/components/HomePage/index.tsx +3 -1
- package/src/components/PropertyIdCopyTooltipContent.tsx +2 -3
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +4 -4
- package/src/components/ReferenceWidget.tsx +5 -5
- package/src/components/SearchIconsView.tsx +4 -4
- package/src/components/SelectableTable/SelectableTable.tsx +1 -1
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +23 -8
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +35 -24
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +35 -15
- package/src/components/VirtualTable/VirtualTable.tsx +28 -20
- package/src/components/VirtualTable/VirtualTableProps.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
- package/src/components/common/types.tsx +4 -6
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -1
- package/src/components/index.tsx +4 -2
- package/src/contexts/AuthControllerContext.tsx +1 -1
- package/src/core/Drawer.tsx +78 -103
- package/src/core/DrawerNavigationItem.tsx +62 -0
- package/src/core/{EntityView.tsx → EntityEditView.tsx} +21 -40
- package/src/core/EntitySidePanel.tsx +2 -2
- package/src/core/FireCMS.tsx +22 -7
- package/src/core/NavigationRoutes.tsx +11 -4
- package/src/core/Scaffold.tsx +76 -61
- package/src/core/field_configs.tsx +1 -2
- package/src/core/index.tsx +3 -4
- package/src/form/EntityForm.tsx +42 -22
- package/src/form/PropertyFieldBinding.tsx +0 -2
- package/src/form/components/StorageItemPreview.tsx +5 -3
- package/src/form/components/StorageUploadProgress.tsx +7 -6
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +8 -12
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +15 -15
- package/src/form/field_bindings/MapFieldBinding.tsx +15 -15
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -0
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +14 -5
- package/src/form/field_bindings/TextFieldBinding.tsx +7 -5
- package/src/form/validation.ts +3 -4
- package/src/hooks/data/delete.ts +3 -3
- package/src/hooks/data/save.ts +2 -2
- package/src/hooks/data/useCollectionFetch.tsx +1 -1
- package/src/hooks/data/useDataSource.tsx +8 -3
- package/src/hooks/data/useEntityFetch.tsx +4 -4
- package/src/hooks/index.tsx +3 -0
- package/src/hooks/useBuildLocalConfigurationPersistence.tsx +9 -10
- package/src/hooks/useBuildModeController.tsx +11 -5
- package/src/hooks/useBuildNavigationController.tsx +199 -81
- package/src/hooks/useProjectLog.tsx +17 -7
- package/src/hooks/useReferenceDialog.tsx +2 -2
- package/src/hooks/useStorageSource.tsx +7 -2
- package/src/hooks/useValidateAuthenticator.tsx +115 -0
- package/src/internal/useBuildDataSource.ts +42 -44
- package/src/internal/useBuildSideEntityController.tsx +86 -20
- package/src/preview/PropertyPreview.tsx +3 -14
- package/src/preview/PropertyPreviewProps.tsx +1 -11
- package/src/preview/components/BooleanPreview.tsx +19 -4
- package/src/preview/components/EnumValuesChip.tsx +1 -1
- package/src/preview/components/ReferencePreview.tsx +55 -147
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +0 -1
- package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
- package/src/types/analytics.ts +1 -0
- package/src/types/auth.tsx +50 -1
- package/src/types/collections.ts +33 -5
- package/src/types/datasource.ts +8 -5
- package/src/types/entities.ts +9 -1
- package/src/types/entity_actions.tsx +17 -0
- package/src/types/entity_callbacks.ts +2 -2
- package/src/types/entity_overrides.tsx +7 -0
- package/src/types/firecms.tsx +0 -1
- package/src/types/index.ts +2 -1
- package/src/types/navigation.ts +17 -16
- package/src/types/permissions.ts +6 -1
- package/src/types/plugins.tsx +26 -28
- package/src/types/properties.ts +8 -6
- package/src/types/property_config.tsx +2 -2
- package/src/types/roles.ts +41 -0
- package/src/types/side_entity_controller.tsx +1 -0
- package/src/types/storage.ts +12 -3
- package/src/types/user.ts +7 -0
- package/src/util/collections.ts +22 -0
- package/src/util/entities.ts +1 -1
- package/src/util/icon_list.ts +2 -2
- package/src/util/icon_synonyms.ts +4 -6
- package/src/util/icons.tsx +11 -3
- package/src/util/navigation_utils.ts +6 -6
- package/src/util/objects.ts +0 -14
- package/src/util/permissions.ts +11 -8
- package/src/util/references.ts +36 -5
- package/src/util/resolutions.ts +6 -24
- package/src/util/strings.ts +2 -2
- package/src/util/useTraceUpdate.tsx +2 -1
- package/dist/core/SideEntityView.d.ts +0 -7
- package/dist/internal/useBuildCustomizationController.d.ts +0 -2
- package/dist/internal/useLocaleConfig.d.ts +0 -1
- package/dist/types/appcheck.d.ts +0 -26
- package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
- package/src/core/SideEntityView.tsx +0 -38
- package/src/internal/useBuildCustomizationController.tsx +0 -5
- package/src/internal/useLocaleConfig.tsx +0 -18
- package/src/types/appcheck.ts +0 -29
package/src/form/EntityForm.tsx
CHANGED
|
@@ -19,8 +19,9 @@ import equal from "react-fast-compare"
|
|
|
19
19
|
import {
|
|
20
20
|
canCreateEntity,
|
|
21
21
|
canDeleteEntity,
|
|
22
|
-
fullPathToCollectionSegments,
|
|
23
22
|
getDefaultValuesFor,
|
|
23
|
+
getEntityTitlePropertyKey,
|
|
24
|
+
getValueInPath,
|
|
24
25
|
isHidden,
|
|
25
26
|
isReadOnly,
|
|
26
27
|
resolveCollection
|
|
@@ -134,12 +135,13 @@ export type EntityFormSaveParams<M extends Record<string, any>> = {
|
|
|
134
135
|
* @constructor
|
|
135
136
|
* @group Components
|
|
136
137
|
*/
|
|
137
|
-
export const EntityForm =
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
export const EntityForm = EntityFormInternal;
|
|
139
|
+
// export const EntityForm = React.memo<EntityFormProps<any>>(EntityFormInternal,
|
|
140
|
+
// (a: EntityFormProps<any>, b: EntityFormProps<any>) => {
|
|
141
|
+
// return a.status === b.status &&
|
|
142
|
+
// a.path === b.path &&
|
|
143
|
+
// equal(a.entity?.values, b.entity?.values);
|
|
144
|
+
// }) as typeof EntityFormInternal;
|
|
143
145
|
|
|
144
146
|
function getDataSourceEntityValues<M extends object>(initialResolvedCollection: ResolvedEntityCollection,
|
|
145
147
|
status: "new" | "existing" | "copy",
|
|
@@ -171,15 +173,16 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
171
173
|
onFormContextChange,
|
|
172
174
|
hideId,
|
|
173
175
|
autoSave,
|
|
174
|
-
onIdUpdateError
|
|
176
|
+
onIdUpdateError,
|
|
175
177
|
}: EntityFormProps<M>) {
|
|
176
178
|
|
|
177
179
|
const analyticsController = useAnalyticsController();
|
|
178
180
|
|
|
179
181
|
const customizationController = useCustomizationController();
|
|
182
|
+
console.log("EntityFormInternal propertyConfigs", customizationController.propertyConfigs);
|
|
180
183
|
|
|
181
184
|
const context = useFireCMSContext();
|
|
182
|
-
const dataSource = useDataSource();
|
|
185
|
+
const dataSource = useDataSource(inputCollection);
|
|
183
186
|
const plugins = customizationController.plugins;
|
|
184
187
|
|
|
185
188
|
const initialResolvedCollection = useMemo(() => resolveCollection({
|
|
@@ -187,7 +190,7 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
187
190
|
path,
|
|
188
191
|
values: entity?.values,
|
|
189
192
|
fields: customizationController.propertyConfigs
|
|
190
|
-
}), [entity?.values, path]);
|
|
193
|
+
}), [entity?.values, path, customizationController.propertyConfigs]);
|
|
191
194
|
|
|
192
195
|
const mustSetCustomId: boolean = (status === "new" || status === "copy") &&
|
|
193
196
|
(Boolean(initialResolvedCollection.customId) && initialResolvedCollection.customId !== "optional");
|
|
@@ -344,6 +347,9 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
344
347
|
fields: customizationController.propertyConfigs
|
|
345
348
|
});
|
|
346
349
|
|
|
350
|
+
const titlePropertyKey = getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs);
|
|
351
|
+
const title = internalValues && titlePropertyKey ? getValueInPath(internalValues, titlePropertyKey) : undefined;
|
|
352
|
+
|
|
347
353
|
const onIdUpdate = inputCollection.callbacks?.onIdUpdate;
|
|
348
354
|
|
|
349
355
|
const doOnIdUpdate = useCallback(async () => {
|
|
@@ -389,12 +395,15 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
389
395
|
|
|
390
396
|
const authController = useAuthController();
|
|
391
397
|
|
|
392
|
-
const getActionsForEntity = useCallback(({
|
|
398
|
+
const getActionsForEntity = useCallback(({
|
|
399
|
+
entity,
|
|
400
|
+
customEntityActions
|
|
401
|
+
}: {
|
|
393
402
|
entity?: Entity<M>,
|
|
394
403
|
customEntityActions?: EntityAction[]
|
|
395
404
|
}): EntityAction[] => {
|
|
396
|
-
const createEnabled = canCreateEntity(inputCollection, authController,
|
|
397
|
-
const deleteEnabled = entity ? canDeleteEntity(inputCollection, authController,
|
|
405
|
+
const createEnabled = canCreateEntity(inputCollection, authController, path, null);
|
|
406
|
+
const deleteEnabled = entity ? canDeleteEntity(inputCollection, authController, path, entity) : true;
|
|
398
407
|
const actions: EntityAction[] = [];
|
|
399
408
|
if (createEnabled)
|
|
400
409
|
actions.push(copyEntityAction);
|
|
@@ -408,7 +417,8 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
408
417
|
const pluginActions: React.ReactNode[] = [];
|
|
409
418
|
|
|
410
419
|
const formContext: FormContext<M> = {
|
|
411
|
-
|
|
420
|
+
// @ts-ignore
|
|
421
|
+
setFieldValue: useCallback(formex.setFieldValue, []),
|
|
412
422
|
values: formex.values,
|
|
413
423
|
collection: resolvedCollection,
|
|
414
424
|
entityId,
|
|
@@ -416,12 +426,14 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
416
426
|
save
|
|
417
427
|
};
|
|
418
428
|
|
|
429
|
+
const submittedFormContext = useRef<FormContext<M> | null>(null);
|
|
419
430
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
420
431
|
useEffect(() => {
|
|
421
|
-
if (onFormContextChange) {
|
|
432
|
+
if (onFormContextChange && !formContextsEqual(submittedFormContext.current ?? undefined, formContext)) {
|
|
422
433
|
onFormContextChange(formContext);
|
|
434
|
+
submittedFormContext.current = formContext;
|
|
423
435
|
}
|
|
424
|
-
}, [
|
|
436
|
+
}, [formContext, onFormContextChange]);
|
|
425
437
|
|
|
426
438
|
if (plugins && inputCollection) {
|
|
427
439
|
const actionProps: PluginFormActionProps = {
|
|
@@ -436,7 +448,7 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
436
448
|
pluginActions.push(...plugins.map((plugin, i) => (
|
|
437
449
|
plugin.form?.Actions
|
|
438
450
|
? <plugin.form.Actions
|
|
439
|
-
key={`actions_${plugin.
|
|
451
|
+
key={`actions_${plugin.key}`} {...actionProps}/>
|
|
440
452
|
: null
|
|
441
453
|
)).filter(Boolean));
|
|
442
454
|
}
|
|
@@ -454,8 +466,8 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
454
466
|
className={`w-full py-2 flex flex-col items-start mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>
|
|
455
467
|
|
|
456
468
|
<Typography
|
|
457
|
-
className={"mt-4 flex-grow " + inputCollection.hideIdFromForm ? "mb-2" : "mb-0"}
|
|
458
|
-
variant={"h4"}>{inputCollection.singularName ?? inputCollection.name}
|
|
469
|
+
className={"mt-4 flex-grow line-clamp-1 " + inputCollection.hideIdFromForm ? "mb-2" : "mb-0"}
|
|
470
|
+
variant={"h4"}>{title ?? inputCollection.singularName ?? inputCollection.name}
|
|
459
471
|
</Typography>
|
|
460
472
|
<Alert color={"base"} className={"w-full"} size={"small"}>
|
|
461
473
|
<code className={"text-xs select-all"}>{path}/{entityId}</code>
|
|
@@ -508,7 +520,7 @@ function InnerForm<M extends Record<string, any>>(props: FormexController<M> & {
|
|
|
508
520
|
savingError?: Error,
|
|
509
521
|
closeAfterSaveRef: MutableRefObject<boolean>,
|
|
510
522
|
autoSave?: boolean,
|
|
511
|
-
entityActions: EntityAction[]
|
|
523
|
+
entityActions: EntityAction[],
|
|
512
524
|
}) {
|
|
513
525
|
|
|
514
526
|
const {
|
|
@@ -530,7 +542,7 @@ function InnerForm<M extends Record<string, any>>(props: FormexController<M> & {
|
|
|
530
542
|
dirty,
|
|
531
543
|
closeAfterSaveRef,
|
|
532
544
|
autoSave,
|
|
533
|
-
entityActions
|
|
545
|
+
entityActions,
|
|
534
546
|
} = props;
|
|
535
547
|
|
|
536
548
|
const context = useFireCMSContext();
|
|
@@ -598,6 +610,7 @@ function InnerForm<M extends Record<string, any>>(props: FormexController<M> & {
|
|
|
598
610
|
<Tooltip title={<PropertyIdCopyTooltipContent propertyId={key}/>}
|
|
599
611
|
delayDuration={800}
|
|
600
612
|
side={"left"}
|
|
613
|
+
align={"start"}
|
|
601
614
|
sideOffset={16}>
|
|
602
615
|
<PropertyFieldBinding {...cmsFormFieldProps}/>
|
|
603
616
|
</Tooltip>
|
|
@@ -655,7 +668,7 @@ function InnerForm<M extends Record<string, any>>(props: FormexController<M> & {
|
|
|
655
668
|
fullPath: resolvedCollection.path,
|
|
656
669
|
collection: resolvedCollection,
|
|
657
670
|
context,
|
|
658
|
-
sideEntityController
|
|
671
|
+
sideEntityController,
|
|
659
672
|
});
|
|
660
673
|
}}>
|
|
661
674
|
{action.icon}
|
|
@@ -718,3 +731,10 @@ export function yupToFormErrors(yupError: ValidationError): Record<string, any>
|
|
|
718
731
|
}
|
|
719
732
|
return errors;
|
|
720
733
|
}
|
|
734
|
+
|
|
735
|
+
function formContextsEqual(a: FormContext<any> | undefined, b: FormContext<any> | undefined): boolean {
|
|
736
|
+
return a?.path === b?.path &&
|
|
737
|
+
a?.entityId === b?.entityId &&
|
|
738
|
+
equal(a?.values, b?.values) &&
|
|
739
|
+
equal(a?.collection, b?.collection);
|
|
740
|
+
}
|
|
@@ -92,7 +92,6 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
92
92
|
let Component: ComponentType<FieldProps<T>> | undefined;
|
|
93
93
|
const resolvedProperty: ResolvedProperty<T> | null = resolveProperty({
|
|
94
94
|
propertyKey,
|
|
95
|
-
propertyValue: fieldProps.field.value,
|
|
96
95
|
propertyOrBuilder: property,
|
|
97
96
|
values: fieldProps.form.values,
|
|
98
97
|
path: context.path,
|
|
@@ -116,7 +115,6 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
116
115
|
}
|
|
117
116
|
const configProperty = resolveProperty({
|
|
118
117
|
propertyOrBuilder: propertyConfig.property,
|
|
119
|
-
propertyValue: fieldProps.field.value,
|
|
120
118
|
values: fieldProps.form.values,
|
|
121
119
|
path: context.path,
|
|
122
120
|
entityId: context.entityId,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import { Entity, ResolvedStringProperty } from "../../types";
|
|
3
|
+
import { Entity, EntityCollection, ResolvedStringProperty } from "../../types";
|
|
4
4
|
import { PreviewSize, PropertyPreview } from "../../preview";
|
|
5
5
|
|
|
6
6
|
import { cn, IconButton, paperMixin, RemoveIcon, Tooltip } from "@firecms/ui";
|
|
@@ -14,6 +14,7 @@ interface StorageItemPreviewProps {
|
|
|
14
14
|
onRemove: (value: string) => void;
|
|
15
15
|
size: PreviewSize;
|
|
16
16
|
disabled: boolean;
|
|
17
|
+
collection: EntityCollection;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export function StorageItemPreview({
|
|
@@ -23,7 +24,8 @@ export function StorageItemPreview({
|
|
|
23
24
|
entity,
|
|
24
25
|
onRemove,
|
|
25
26
|
disabled,
|
|
26
|
-
size
|
|
27
|
+
size,
|
|
28
|
+
collection
|
|
27
29
|
}: StorageItemPreviewProps) {
|
|
28
30
|
|
|
29
31
|
return (
|
|
@@ -54,7 +56,7 @@ export function StorageItemPreview({
|
|
|
54
56
|
<PropertyPreview propertyKey={name}
|
|
55
57
|
value={value}
|
|
56
58
|
property={property}
|
|
57
|
-
|
|
59
|
+
// entity={entity}
|
|
58
60
|
size={size}/>
|
|
59
61
|
</ErrorBoundary>
|
|
60
62
|
}
|
|
@@ -4,6 +4,7 @@ import { useSnackbarController, useStorageSource } from "../../hooks";
|
|
|
4
4
|
import { StorageFieldItem } from "../../util/useStorageUploadController";
|
|
5
5
|
import { ErrorView } from "../../components";
|
|
6
6
|
import { cn, paperMixin, Skeleton } from "@firecms/ui";
|
|
7
|
+
import { EntityCollection, StorageSource } from "../../types";
|
|
7
8
|
|
|
8
9
|
export interface StorageUploadItemProps {
|
|
9
10
|
storagePath: string;
|
|
@@ -22,10 +23,10 @@ export function StorageUploadProgress({
|
|
|
22
23
|
metadata,
|
|
23
24
|
onFileUploadComplete,
|
|
24
25
|
imageSize,
|
|
25
|
-
simple
|
|
26
|
+
simple,
|
|
26
27
|
}: StorageUploadItemProps) {
|
|
27
28
|
|
|
28
|
-
const
|
|
29
|
+
const storageSource = useStorageSource();
|
|
29
30
|
|
|
30
31
|
const snackbarController = useSnackbarController();
|
|
31
32
|
|
|
@@ -41,14 +42,14 @@ export function StorageUploadProgress({
|
|
|
41
42
|
setError(undefined);
|
|
42
43
|
setLoading(true);
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
storageSource.uploadFile({
|
|
45
46
|
file,
|
|
46
47
|
fileName,
|
|
47
48
|
path: storagePath,
|
|
48
49
|
metadata
|
|
49
50
|
})
|
|
50
51
|
.then(async ({ path }) => {
|
|
51
|
-
console.debug("Upload successful");
|
|
52
|
+
console.debug("Upload successful", path);
|
|
52
53
|
await onFileUploadComplete(path, entry, metadata);
|
|
53
54
|
if (mounted.current)
|
|
54
55
|
setLoading(false);
|
|
@@ -67,7 +68,7 @@ export function StorageUploadProgress({
|
|
|
67
68
|
.finally(() => {
|
|
68
69
|
uploading.current = false;
|
|
69
70
|
});
|
|
70
|
-
}, [entry, metadata, onFileUploadComplete,
|
|
71
|
+
}, [entry, metadata, onFileUploadComplete, storageSource, storagePath]);
|
|
71
72
|
|
|
72
73
|
React.useEffect(() => {
|
|
73
74
|
mounted.current = true;
|
|
@@ -89,7 +90,7 @@ export function StorageUploadProgress({
|
|
|
89
90
|
|
|
90
91
|
<div className={cn(paperMixin,
|
|
91
92
|
"relative m-4 border-box flex items-center justify-center",
|
|
92
|
-
|
|
93
|
+
`min-w-[${imageSize}px] min-h-[${imageSize}px]`)}>
|
|
93
94
|
|
|
94
95
|
{loading &&
|
|
95
96
|
<Skeleton className="w-full h-full"/>}
|
|
@@ -6,7 +6,7 @@ import { ErrorView } from "../../components";
|
|
|
6
6
|
import { getIconForProperty, getReferenceFrom } from "../../util";
|
|
7
7
|
|
|
8
8
|
import { useNavigationController, useReferenceDialog } from "../../hooks";
|
|
9
|
-
import { Button, ExpandablePanel } from "@firecms/ui";
|
|
9
|
+
import { Button, cn, ExpandablePanel, fieldBackgroundMixin } from "@firecms/ui";
|
|
10
10
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
11
11
|
|
|
12
12
|
type ArrayOfReferencesFieldProps = FieldProps<EntityReference[]>;
|
|
@@ -38,7 +38,6 @@ export function ArrayOfReferencesFieldBinding({
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
const expanded = property.expanded === undefined ? true : property.expanded;
|
|
41
|
-
const [onHover, setOnHover] = React.useState(false);
|
|
42
41
|
const selectedEntityIds = value && Array.isArray(value) ? value.map((ref) => ref.id) : [];
|
|
43
42
|
|
|
44
43
|
useClearRestoreValue({
|
|
@@ -81,21 +80,17 @@ export function ArrayOfReferencesFieldBinding({
|
|
|
81
80
|
if (!entryValue)
|
|
82
81
|
return <div>Internal ERROR</div>;
|
|
83
82
|
return (
|
|
84
|
-
<div
|
|
85
|
-
onMouseEnter={() => setOnHover(true)}
|
|
86
|
-
onMouseMove={() => setOnHover(true)}
|
|
87
|
-
onMouseLeave={() => setOnHover(false)}>
|
|
88
83
|
<ReferencePreview
|
|
84
|
+
key={internalId}
|
|
89
85
|
disabled={!ofProperty.path}
|
|
90
86
|
previewProperties={ofProperty.previewProperties}
|
|
91
87
|
size={"medium"}
|
|
92
88
|
onClick={onEntryClick}
|
|
89
|
+
hover={!disabled}
|
|
93
90
|
reference={entryValue}
|
|
94
|
-
onHover={onHover}
|
|
95
91
|
/>
|
|
96
|
-
</div>
|
|
97
92
|
);
|
|
98
|
-
}, [ofProperty.path, ofProperty.previewProperties,
|
|
93
|
+
}, [ofProperty.path, ofProperty.previewProperties, value]);
|
|
99
94
|
|
|
100
95
|
const title = (
|
|
101
96
|
<LabelWithIcon icon={getIconForProperty(property, "small")}
|
|
@@ -108,7 +103,7 @@ export function ArrayOfReferencesFieldBinding({
|
|
|
108
103
|
{!collection && <ErrorView
|
|
109
104
|
error={"The specified collection does not exist. Check console"}/>}
|
|
110
105
|
|
|
111
|
-
{collection &&
|
|
106
|
+
{collection && <div className={"group"}>
|
|
112
107
|
|
|
113
108
|
<FormikArrayContainer value={value}
|
|
114
109
|
addLabel={property.name ? "Add reference to " + property.name : "Add reference"}
|
|
@@ -126,7 +121,7 @@ export function ArrayOfReferencesFieldBinding({
|
|
|
126
121
|
onClick={onEntryClick}>
|
|
127
122
|
Edit {property.name}
|
|
128
123
|
</Button>
|
|
129
|
-
|
|
124
|
+
</div>}
|
|
130
125
|
</>;
|
|
131
126
|
|
|
132
127
|
return (
|
|
@@ -134,7 +129,8 @@ export function ArrayOfReferencesFieldBinding({
|
|
|
134
129
|
|
|
135
130
|
{!tableMode &&
|
|
136
131
|
<ExpandablePanel
|
|
137
|
-
|
|
132
|
+
titleClassName={fieldBackgroundMixin}
|
|
133
|
+
className={cn("px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2", fieldBackgroundMixin)}
|
|
138
134
|
initiallyExpanded={expanded}
|
|
139
135
|
title={title}>
|
|
140
136
|
{body}
|
|
@@ -43,7 +43,7 @@ export function DateTimeFieldBinding({
|
|
|
43
43
|
<>
|
|
44
44
|
<DateTimeField
|
|
45
45
|
value={internalValue}
|
|
46
|
-
onChange={(dateValue) => setValue(dateValue)}
|
|
46
|
+
onChange={(dateValue) => setValue(dateValue ?? null)}
|
|
47
47
|
size={"medium"}
|
|
48
48
|
mode={property.mode}
|
|
49
49
|
clearable={property.clearable}
|
|
@@ -32,20 +32,20 @@ type MapEditViewRowState = [number, {
|
|
|
32
32
|
*
|
|
33
33
|
* @group Form fields
|
|
34
34
|
*/
|
|
35
|
-
export function KeyValueFieldBinding
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
export function KeyValueFieldBinding({
|
|
36
|
+
propertyKey,
|
|
37
|
+
value,
|
|
38
|
+
showError,
|
|
39
|
+
error,
|
|
40
|
+
disabled,
|
|
41
|
+
property,
|
|
42
|
+
setValue,
|
|
43
|
+
tableMode,
|
|
44
|
+
includeDescription,
|
|
45
|
+
underlyingValueHasChanged,
|
|
46
|
+
autoFocus,
|
|
47
|
+
context
|
|
48
|
+
}: FieldProps<Record<string, any>>) {
|
|
49
49
|
|
|
50
50
|
const expanded = (property.expanded === undefined ? true : property.expanded) || autoFocus;
|
|
51
51
|
|
|
@@ -546,7 +546,7 @@ function getDataType(value: any): DataType | undefined {
|
|
|
546
546
|
return "array";
|
|
547
547
|
} else if (value instanceof Date) {
|
|
548
548
|
return "date";
|
|
549
|
-
} else if (value
|
|
549
|
+
} else if (value?.isEntityReference && value?.isEntityReference()) {
|
|
550
550
|
return "reference";
|
|
551
551
|
} else if (value instanceof GeoPoint) {
|
|
552
552
|
return "geopoint";
|
|
@@ -14,21 +14,21 @@ import { ExpandablePanel, InputLabel, Select, SelectItem } from "@firecms/ui";
|
|
|
14
14
|
* and tables to the specified properties.
|
|
15
15
|
* @group Form fields
|
|
16
16
|
*/
|
|
17
|
-
export function MapFieldBinding
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
export function MapFieldBinding({
|
|
18
|
+
propertyKey,
|
|
19
|
+
value,
|
|
20
|
+
showError,
|
|
21
|
+
error,
|
|
22
|
+
disabled,
|
|
23
|
+
property,
|
|
24
|
+
setValue,
|
|
25
|
+
partOfBlock,
|
|
26
|
+
tableMode,
|
|
27
|
+
includeDescription,
|
|
28
|
+
underlyingValueHasChanged,
|
|
29
|
+
autoFocus,
|
|
30
|
+
context
|
|
31
|
+
}: FieldProps<Record<string, any>>) {
|
|
32
32
|
|
|
33
33
|
const pickOnlySomeKeys = property.pickOnlySomeKeys || false;
|
|
34
34
|
const expanded = (property.expanded === undefined ? true : property.expanded) || autoFocus;
|
|
@@ -95,6 +95,7 @@ function ReferenceFieldBindingInternal<M extends Record<string, any>>({
|
|
|
95
95
|
{value && <ReferencePreview
|
|
96
96
|
disabled={!property.path}
|
|
97
97
|
previewProperties={property.previewProperties}
|
|
98
|
+
hover={!disabled}
|
|
98
99
|
size={"medium"}
|
|
99
100
|
onClick={disabled || isSubmitting ? undefined : onEntryClick}
|
|
100
101
|
reference={value}
|
|
@@ -3,6 +3,7 @@ import React, { useCallback } from "react";
|
|
|
3
3
|
import {
|
|
4
4
|
ArrayProperty,
|
|
5
5
|
Entity,
|
|
6
|
+
EntityCollection,
|
|
6
7
|
FieldProps,
|
|
7
8
|
ResolvedArrayProperty,
|
|
8
9
|
ResolvedStringProperty,
|
|
@@ -10,10 +11,10 @@ import {
|
|
|
10
11
|
} from "../../types";
|
|
11
12
|
import { useDropzone } from "react-dropzone";
|
|
12
13
|
import { PreviewSize } from "../../preview";
|
|
13
|
-
import { FieldHelperText,LabelWithIcon } from "../components";
|
|
14
|
+
import { FieldHelperText, LabelWithIcon } from "../components";
|
|
14
15
|
|
|
15
16
|
import { getIconForProperty, isReadOnly } from "../../util";
|
|
16
|
-
import {
|
|
17
|
+
import { useSnackbarController, useStorageSource } from "../../hooks";
|
|
17
18
|
import { DragDropContext, Draggable, Droppable } from "@hello-pangea/dnd";
|
|
18
19
|
import { StorageFieldItem, useStorageUploadController } from "../../util/useStorageUploadController";
|
|
19
20
|
import { StorageUploadProgress } from "../components/StorageUploadProgress";
|
|
@@ -55,13 +56,13 @@ export function StorageUploadFieldBinding({
|
|
|
55
56
|
property,
|
|
56
57
|
includeDescription,
|
|
57
58
|
context,
|
|
58
|
-
isSubmitting
|
|
59
|
+
isSubmitting,
|
|
59
60
|
}: StorageUploadFieldProps) {
|
|
60
61
|
|
|
61
62
|
if (!context.entityId)
|
|
62
63
|
throw new Error("StorageUploadFieldBinding: Entity id is null");
|
|
63
64
|
|
|
64
|
-
const storageSource = useStorageSource();
|
|
65
|
+
const storageSource = useStorageSource(context.collection);
|
|
65
66
|
const disabled = isReadOnly(property) || !!property.disabled || isSubmitting;
|
|
66
67
|
|
|
67
68
|
const {
|
|
@@ -108,6 +109,7 @@ export function StorageUploadFieldBinding({
|
|
|
108
109
|
|
|
109
110
|
<StorageUpload
|
|
110
111
|
value={internalValue}
|
|
112
|
+
collection={context.collection}
|
|
111
113
|
name={propertyKey}
|
|
112
114
|
disabled={disabled}
|
|
113
115
|
autoFocus={autoFocus}
|
|
@@ -133,6 +135,7 @@ export function StorageUploadFieldBinding({
|
|
|
133
135
|
|
|
134
136
|
function FileDropComponent({
|
|
135
137
|
storage,
|
|
138
|
+
collection,
|
|
136
139
|
disabled,
|
|
137
140
|
isDraggingOver,
|
|
138
141
|
onFilesAdded,
|
|
@@ -151,6 +154,7 @@ function FileDropComponent({
|
|
|
151
154
|
helpText
|
|
152
155
|
}: {
|
|
153
156
|
storage: StorageConfig,
|
|
157
|
+
collection: EntityCollection,
|
|
154
158
|
disabled: boolean,
|
|
155
159
|
isDraggingOver: boolean,
|
|
156
160
|
droppableProvided: any,
|
|
@@ -231,6 +235,7 @@ function FileDropComponent({
|
|
|
231
235
|
if (entry.storagePathOrDownloadUrl) {
|
|
232
236
|
child = (
|
|
233
237
|
<StorageItemPreview
|
|
238
|
+
collection={collection}
|
|
234
239
|
name={`storage_preview_${entry.storagePathOrDownloadUrl}`}
|
|
235
240
|
property={property}
|
|
236
241
|
disabled={disabled}
|
|
@@ -294,6 +299,7 @@ function FileDropComponent({
|
|
|
294
299
|
|
|
295
300
|
export interface StorageUploadProps {
|
|
296
301
|
value: StorageFieldItem[];
|
|
302
|
+
collection: EntityCollection;
|
|
297
303
|
setInternalValue: (v: StorageFieldItem[]) => void;
|
|
298
304
|
name: string;
|
|
299
305
|
property: ResolvedStringProperty | ResolvedArrayProperty<string[]>;
|
|
@@ -309,6 +315,7 @@ export interface StorageUploadProps {
|
|
|
309
315
|
}
|
|
310
316
|
|
|
311
317
|
export function StorageUpload({
|
|
318
|
+
collection,
|
|
312
319
|
property,
|
|
313
320
|
name,
|
|
314
321
|
value,
|
|
@@ -321,7 +328,7 @@ export function StorageUpload({
|
|
|
321
328
|
autoFocus,
|
|
322
329
|
storage,
|
|
323
330
|
entity,
|
|
324
|
-
storagePathBuilder
|
|
331
|
+
storagePathBuilder,
|
|
325
332
|
}: StorageUploadProps) {
|
|
326
333
|
|
|
327
334
|
if (multipleFilesSupported) {
|
|
@@ -401,6 +408,7 @@ export function StorageUpload({
|
|
|
401
408
|
className="rounded"
|
|
402
409
|
>
|
|
403
410
|
<StorageItemPreview
|
|
411
|
+
collection={collection}
|
|
404
412
|
name={`storage_preview_${entry.storagePathOrDownloadUrl}`}
|
|
405
413
|
property={renderProperty}
|
|
406
414
|
disabled={true}
|
|
@@ -414,6 +422,7 @@ export function StorageUpload({
|
|
|
414
422
|
>
|
|
415
423
|
{(provided, snapshot) => {
|
|
416
424
|
return <FileDropComponent storage={storage}
|
|
425
|
+
collection={collection}
|
|
417
426
|
disabled={disabled}
|
|
418
427
|
isDraggingOver={snapshot.isDraggingOver}
|
|
419
428
|
droppableProvided={provided}
|
|
@@ -7,7 +7,7 @@ import { getIconForProperty } from "../../util";
|
|
|
7
7
|
import { PropertyPreview } from "../../preview";
|
|
8
8
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
9
9
|
|
|
10
|
-
interface
|
|
10
|
+
interface TextFieldBindingProps<T extends string | number> extends FieldProps<T> {
|
|
11
11
|
allowInfinity?: boolean
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -18,6 +18,7 @@ interface TextFieldProps<T extends string | number> extends FieldProps<T> {
|
|
|
18
18
|
* @group Form fields
|
|
19
19
|
*/
|
|
20
20
|
export function TextFieldBinding<T extends string | number>({
|
|
21
|
+
context,
|
|
21
22
|
propertyKey,
|
|
22
23
|
value,
|
|
23
24
|
setValue,
|
|
@@ -27,7 +28,7 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
27
28
|
autoFocus,
|
|
28
29
|
property,
|
|
29
30
|
includeDescription,
|
|
30
|
-
}:
|
|
31
|
+
}: TextFieldBindingProps<T>) {
|
|
31
32
|
|
|
32
33
|
let multiline: boolean | undefined;
|
|
33
34
|
let url: boolean | PreviewType | undefined;
|
|
@@ -96,9 +97,10 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
96
97
|
{url && <Collapse
|
|
97
98
|
className="mt-1 ml-1"
|
|
98
99
|
in={Boolean(value)}>
|
|
99
|
-
<PropertyPreview
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
<PropertyPreview
|
|
101
|
+
value={value}
|
|
102
|
+
property={property}
|
|
103
|
+
size={"medium"}/>
|
|
102
104
|
</Collapse>}
|
|
103
105
|
|
|
104
106
|
</>
|
package/src/form/validation.ts
CHANGED
|
@@ -9,8 +9,7 @@ import {
|
|
|
9
9
|
} from "../types";
|
|
10
10
|
import * as yup from "yup";
|
|
11
11
|
import { AnySchema, ArraySchema, BooleanSchema, DateSchema, NumberSchema, ObjectSchema, StringSchema } from "yup";
|
|
12
|
-
import { enumToObjectEntries } from "../util
|
|
13
|
-
import { getValueInPath, hydrateRegExp, isPropertyBuilder } from "../util";
|
|
12
|
+
import { enumToObjectEntries, getValueInPath, hydrateRegExp, isPropertyBuilder } from "../util";
|
|
14
13
|
|
|
15
14
|
// Add custom unique function for array values
|
|
16
15
|
declare module "yup" {
|
|
@@ -90,12 +89,12 @@ export function mapPropertyToYup<T extends CMSType>(propertyContext: PropertyCon
|
|
|
90
89
|
throw Error("Unsupported data type in yup mapping");
|
|
91
90
|
}
|
|
92
91
|
|
|
93
|
-
export function getYupMapObjectSchema
|
|
92
|
+
export function getYupMapObjectSchema({
|
|
94
93
|
property,
|
|
95
94
|
entityId,
|
|
96
95
|
customFieldValidator,
|
|
97
96
|
name
|
|
98
|
-
}: PropertyContext<
|
|
97
|
+
}: PropertyContext<Record<string, any>>): ObjectSchema<any> {
|
|
99
98
|
const objectSchema: any = {};
|
|
100
99
|
const validation = property.validation;
|
|
101
100
|
if (property.properties)
|