@firecms/core 3.0.0-canary.203 → 3.0.0-canary.205

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.
@@ -1,4 +1,4 @@
1
- import { EntityCollection, EntitySidePanelProps, NavigationController, SideDialogsController, SideEntityController } from "../types";
2
- export declare function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean): string;
1
+ import { CustomizationController, EntityCollection, EntitySidePanelProps, NavigationController, SideDialogsController, SideEntityController } from "../types";
2
+ export declare function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean, customizationController: CustomizationController): string;
3
3
  export declare const useBuildSideEntityController: (navigation: NavigationController, sideDialogsController: SideDialogsController) => SideEntityController;
4
4
  export declare function buildSidePanelsFromUrl(path: string, collections: EntityCollection[], newFlag: boolean): EntitySidePanelProps<any>[];
@@ -1,4 +1,4 @@
1
- import { ArrayProperty, CMSType, EntityCollection, EntityCustomView, EntityValues, EnumValueConfig, EnumValues, NumberProperty, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedArrayProperty, ResolvedEntityCollection, ResolvedNumberProperty, ResolvedProperties, ResolvedProperty, ResolvedStringProperty, StringProperty, UserConfigurationPersistence } from "../types";
1
+ import { ArrayProperty, CMSType, CustomizationController, EntityCollection, EntityCustomView, EntityValues, EnumValueConfig, EnumValues, NumberProperty, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedArrayProperty, ResolvedEntityCollection, ResolvedNumberProperty, ResolvedProperties, ResolvedProperty, ResolvedStringProperty, StringProperty, UserConfigurationPersistence } from "../types";
2
2
  export declare const resolveCollection: <M extends Record<string, any>>({ collection, path, entityId, values, previousValues, userConfigPersistence, propertyConfigs, ignoreMissingFields }: {
3
3
  collection: EntityCollection<M> | ResolvedEntityCollection<M>;
4
4
  path: string;
@@ -76,3 +76,8 @@ export declare function resolveProperties<M extends Record<string, any>>({ prope
76
76
  export declare function resolvePropertyEnum(property: StringProperty | NumberProperty, fromBuilder?: boolean): ResolvedStringProperty | ResolvedNumberProperty;
77
77
  export declare function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined;
78
78
  export declare function resolveEntityView(entityView: string | EntityCustomView<any>, contextEntityViews?: EntityCustomView<any>[]): EntityCustomView<any> | undefined;
79
+ export declare function resolvedSelectedEntityView<M extends Record<string, any>>(customViews: (string | EntityCustomView<M>)[] | undefined, customizationController: CustomizationController, selectedTab?: string): {
80
+ resolvedEntityViews: EntityCustomView[];
81
+ selectedEntityView: EntityCustomView | undefined;
82
+ selectedSecondaryForm: EntityCustomView | undefined;
83
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
3
  "type": "module",
4
- "version": "3.0.0-canary.203",
4
+ "version": "3.0.0-canary.205",
5
5
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/firecmsco"
@@ -50,9 +50,9 @@
50
50
  "./package.json": "./package.json"
51
51
  },
52
52
  "dependencies": {
53
- "@firecms/editor": "^3.0.0-canary.203",
54
- "@firecms/formex": "^3.0.0-canary.203",
55
- "@firecms/ui": "^3.0.0-canary.203",
53
+ "@firecms/editor": "^3.0.0-canary.205",
54
+ "@firecms/formex": "^3.0.0-canary.205",
55
+ "@firecms/ui": "^3.0.0-canary.205",
56
56
  "@hello-pangea/dnd": "^17.0.0",
57
57
  "@radix-ui/react-portal": "^1.1.3",
58
58
  "clsx": "^2.1.1",
@@ -104,7 +104,7 @@
104
104
  "dist",
105
105
  "src"
106
106
  ],
107
- "gitHead": "bad3e5f8069d21897795c6d5c42f843e9967b66d",
107
+ "gitHead": "b3a2a795ce5eb7edc68efea5caa69b8d477901be",
108
108
  "publishConfig": {
109
109
  "access": "public"
110
110
  },
@@ -1,8 +1,13 @@
1
1
  import React, { useEffect, useMemo, useState } from "react";
2
- import { Entity, EntityCollection, EntityCustomView, EntityStatus, FireCMSPlugin, FormContext, User } from "../types";
2
+ import { Entity, EntityCollection, EntityStatus, FireCMSPlugin, FormContext, User } from "../types";
3
3
 
4
4
  import { CircularProgressCenter, EntityCollectionView, EntityView, ErrorBoundary } from "../components";
5
- import { canEditEntity, removeInitialAndTrailingSlashes, resolveDefaultSelectedView, resolveEntityView } from "../util";
5
+ import {
6
+ canEditEntity,
7
+ removeInitialAndTrailingSlashes,
8
+ resolveDefaultSelectedView,
9
+ resolvedSelectedEntityView
10
+ } from "../util";
6
11
 
7
12
  import {
8
13
  useAuthController,
@@ -13,7 +18,7 @@ import {
13
18
  } from "../hooks";
14
19
  import { CircularProgress, cls, defaultBorderMixin, Tab, Tabs, Typography } from "@firecms/ui";
15
20
  import { getEntityFromCache } from "../util/entity_cache";
16
- import { EntityForm, EntityFormProps, FormLayoutInner } from "../form";
21
+ import { EntityForm, EntityFormProps } from "../form";
17
22
  import { EntityEditViewFormActions } from "./EntityEditViewFormActions";
18
23
 
19
24
  const MAIN_TAB_VALUE = "main_##Q$SC^#S6";
@@ -120,43 +125,6 @@ export function EntityEditView<M extends Record<string, any>, USER extends User>
120
125
  />;
121
126
  }
122
127
 
123
- function SecondaryForm<M extends object>({
124
- collection,
125
- className,
126
- customView,
127
- entity,
128
- formContext,
129
- forceActionsAtTheBottom,
130
- }: {
131
- className?: string,
132
- customView: EntityCustomView,
133
- formContext: FormContext<M>,
134
- collection: EntityCollection<M>,
135
- forceActionsAtTheBottom?: boolean,
136
- entity: Entity<M> | undefined,
137
- }) {
138
-
139
- if (!customView.Builder) {
140
- console.error("customView.Builder is not defined");
141
- return null;
142
- }
143
-
144
- return <FormLayoutInner
145
- className={className}
146
- forceActionsAtTheBottom={forceActionsAtTheBottom}
147
- formContext={formContext}
148
- EntityFormActionsComponent={EntityEditViewFormActions}>
149
- <ErrorBoundary>
150
- {formContext && <customView.Builder
151
- collection={collection}
152
- entity={entity}
153
- modifiedValues={formContext.formex.values ?? entity?.values}
154
- formContext={formContext}
155
- />}
156
- </ErrorBoundary>
157
- </FormLayoutInner>;
158
- }
159
-
160
128
  export function EntityEditViewInner<M extends Record<string, any>>({
161
129
  path,
162
130
  entityId,
@@ -214,42 +182,21 @@ export function EntityEditViewInner<M extends Record<string, any>>({
214
182
  }
215
183
  }, [selectedTabProp]);
216
184
 
217
- const mainViewVisible = selectedTab === MAIN_TAB_VALUE;
218
-
219
185
  const subcollections = (collection.subcollections ?? []).filter(c => !c.hideFromNavigation);
220
186
  const subcollectionsCount = subcollections?.length ?? 0;
221
187
  const customViews = collection.entityViews;
222
188
  const customViewsCount = customViews?.length ?? 0;
223
189
  const hasAdditionalViews = customViewsCount > 0 || subcollectionsCount > 0;
224
190
 
225
- const resolvedEntityViews = customViews ? customViews
226
- .map(e => resolveEntityView(e, customizationController.entityViews))
227
- .filter(Boolean) as EntityCustomView[]
228
- : [];
191
+ const {
192
+ resolvedEntityViews,
193
+ selectedEntityView,
194
+ selectedSecondaryForm
195
+ } = resolvedSelectedEntityView(customViews, customizationController, selectedTab);
229
196
 
230
- const selectedEntityView = resolvedEntityViews.find(e => e.key === selectedTab);
231
197
  const actionsAtTheBottom = !largeLayout || layout === "side_panel" || selectedEntityView?.includeActions === "bottom";
232
198
 
233
- const secondaryForms: React.ReactNode[] | undefined = formContext && customViews && resolvedEntityViews
234
- .filter(e => e.includeActions)
235
- .map((customView) => {
236
- if (!customView || !formContext)
237
- return null;
238
-
239
- if (!customView.Builder) {
240
- console.error("customView.Builder is not defined");
241
- return null;
242
- }
243
-
244
- return <SecondaryForm key={`custom_view_${customView.key}`}
245
- className={selectedTab !== customView.key ? "hidden" : ""}
246
- customView={customView}
247
- formContext={formContext}
248
- collection={collection}
249
- forceActionsAtTheBottom={!largeLayout || layout === "side_panel" || customView.includeActions === "bottom"}
250
- entity={usedEntity}/>;
251
-
252
- }).filter(Boolean);
199
+ const mainViewVisible = selectedTab === MAIN_TAB_VALUE || Boolean(selectedSecondaryForm);
253
200
 
254
201
  const customViewsView: React.ReactNode[] | undefined = customViews && resolvedEntityViews
255
202
  .filter(e => !e.includeActions)
@@ -322,7 +269,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
322
269
  path,
323
270
  entityId,
324
271
  selectedTab: value === MAIN_TAB_VALUE ? undefined : value,
325
- collection
272
+ collection,
326
273
  });
327
274
  }
328
275
  };
@@ -361,6 +308,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
361
308
  onSaved?.(res);
362
309
  formProps?.onSaved?.(res);
363
310
  }}
311
+ Builder={selectedSecondaryForm?.Builder}
364
312
  />;
365
313
 
366
314
  const subcollectionTabs = subcollections && subcollections.map((subcollection) =>
@@ -421,7 +369,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
421
369
  </div>
422
370
  : entityView}
423
371
 
424
- {secondaryForms}
372
+ {/*{secondaryForms}*/}
425
373
 
426
374
  {customViewsView}
427
375
 
@@ -141,14 +141,14 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
141
141
  path,
142
142
  entityId,
143
143
  selectedTab,
144
- collection
144
+ collection,
145
145
  }) => {
146
146
  sideEntityController.replace({
147
147
  path,
148
148
  entityId,
149
149
  selectedTab,
150
150
  updateUrl: true,
151
- collection
151
+ collection,
152
152
  });
153
153
  }}
154
154
  formProps={props.formProps}
@@ -3,6 +3,7 @@ import {
3
3
  CMSAnalyticsEvent,
4
4
  Entity,
5
5
  EntityCollection,
6
+ EntityCustomViewParams,
6
7
  EntityStatus,
7
8
  EntityValues,
8
9
  FormContext,
@@ -82,6 +83,8 @@ export type EntityFormProps<M extends Record<string, any>> = {
82
83
 
83
84
  EntityFormActionsComponent?: React.FC<EntityFormActionsProps>;
84
85
 
86
+ Builder?: React.ComponentType<EntityCustomViewParams<M>>;
87
+
85
88
  children?: React.ReactNode;
86
89
  };
87
90
 
@@ -102,6 +105,7 @@ export function EntityForm<M extends Record<string, any>>({
102
105
  onEntityChange,
103
106
  openEntityMode = "full_screen",
104
107
  formex: formexProp,
108
+ Builder,
105
109
  EntityFormActionsComponent = EntityFormActions,
106
110
  showDefaultActions = true,
107
111
  showEntityPath = true,
@@ -498,83 +502,94 @@ export function EntityForm<M extends Record<string, any>>({
498
502
 
499
503
  const formFieldKeys = getFormFieldKeys(resolvedCollection);
500
504
 
501
- const formFields = () => (
502
- <FormLayout>
503
- {formFieldKeys.map((key) => {
504
- const property = resolvedCollection.properties[key];
505
- if (property) {
506
- const underlyingValueHasChanged: boolean =
507
- !!underlyingChanges &&
508
- Object.keys(underlyingChanges).includes(key) &&
509
- formex.touched[key];
510
- const disabled = (!autoSave && formex.isSubmitting) || isReadOnly(property) || Boolean(property.disabled);
511
- const hidden = isHidden(property);
512
- if (hidden) return null;
513
- const widthPercentage = property.widthPercentage ?? 100;
514
- const cmsFormFieldProps: PropertyFieldBindingProps<any, M> = {
515
- propertyKey: key,
516
- disabled,
517
- property,
518
- includeDescription: property.description || property.longDescription,
519
- underlyingValueHasChanged: underlyingValueHasChanged && !autoSave,
520
- context: formContext,
521
- partOfArray: false,
522
- minimalistView: false,
523
- autoFocus: false
524
- };
525
-
526
- return (
527
- <FormEntry propertyKey={key}
528
- widthPercentage={widthPercentage}
529
- key={`field_${key}`}>
530
- <PropertyFieldBinding {...cmsFormFieldProps} />
531
- </FormEntry>
532
- );
533
- }
505
+ const formFields = () => {
534
506
 
535
- const additionalField = resolvedCollection.additionalFields?.find(f => f.key === key);
536
- if (additionalField && entity) {
537
- const Builder = additionalField.Builder;
538
- if (!Builder && !additionalField.value) {
539
- throw new Error("When using additional fields you need to provide a Builder or a value");
507
+ if (Builder) {
508
+ return <Builder
509
+ collection={collection}
510
+ entity={entity}
511
+ modifiedValues={formex.values}
512
+ formContext={formContext}
513
+ />;
514
+ }
515
+ return (
516
+ <FormLayout>
517
+ {formFieldKeys.map((key) => {
518
+ const property = resolvedCollection.properties[key];
519
+ if (property) {
520
+ const underlyingValueHasChanged: boolean =
521
+ !!underlyingChanges &&
522
+ Object.keys(underlyingChanges).includes(key) &&
523
+ formex.touched[key];
524
+ const disabled = (!autoSave && formex.isSubmitting) || isReadOnly(property) || Boolean(property.disabled);
525
+ const hidden = isHidden(property);
526
+ if (hidden) return null;
527
+ const widthPercentage = property.widthPercentage ?? 100;
528
+ const cmsFormFieldProps: PropertyFieldBindingProps<any, M> = {
529
+ propertyKey: key,
530
+ disabled,
531
+ property,
532
+ includeDescription: property.description || property.longDescription,
533
+ underlyingValueHasChanged: underlyingValueHasChanged && !autoSave,
534
+ context: formContext,
535
+ partOfArray: false,
536
+ minimalistView: false,
537
+ autoFocus: false
538
+ };
539
+
540
+ return (
541
+ <FormEntry propertyKey={key}
542
+ widthPercentage={widthPercentage}
543
+ key={`field_${key}`}>
544
+ <PropertyFieldBinding {...cmsFormFieldProps} />
545
+ </FormEntry>
546
+ );
540
547
  }
541
- const child = Builder
542
- ? <Builder entity={entity} context={context}/>
543
- : <div className={"w-full"}>
544
- {additionalField.value?.({
545
- entity,
546
- context
547
- })?.toString()}
548
- </div>;
549
-
550
- return (
551
- <div key={`additional_${key}`} className={"w-full"}>
552
- <LabelWithIconAndTooltip
553
- propertyKey={key}
554
- icon={<NotesIcon size={"small"}/>}
555
- title={additionalField.name}
556
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
557
- <div
558
- className={cls(paperMixin, "w-full min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
559
- <ErrorBoundary>
560
- {child}
561
- </ErrorBoundary>
548
+
549
+ const additionalField = resolvedCollection.additionalFields?.find(f => f.key === key);
550
+ if (additionalField && entity) {
551
+ const Builder = additionalField.Builder;
552
+ if (!Builder && !additionalField.value) {
553
+ throw new Error("When using additional fields you need to provide a Builder or a value");
554
+ }
555
+ const child = Builder
556
+ ? <Builder entity={entity} context={context}/>
557
+ : <div className={"w-full"}>
558
+ {additionalField.value?.({
559
+ entity,
560
+ context
561
+ })?.toString()}
562
+ </div>;
563
+
564
+ return (
565
+ <div key={`additional_${key}`} className={"w-full"}>
566
+ <LabelWithIconAndTooltip
567
+ propertyKey={key}
568
+ icon={<NotesIcon size={"small"}/>}
569
+ title={additionalField.name}
570
+ className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
571
+ <div
572
+ className={cls(paperMixin, "w-full min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
573
+ <ErrorBoundary>
574
+ {child}
575
+ </ErrorBoundary>
576
+ </div>
562
577
  </div>
563
- </div>
564
- );
565
- }
578
+ );
579
+ }
566
580
 
567
- console.warn(`Property ${key} not found in collection ${resolvedCollection.name} in properties or additional fields. Skipping.`);
568
- return null;
569
- }).filter(Boolean)}
570
- </FormLayout>
571
- );
581
+ console.warn(`Property ${key} not found in collection ${resolvedCollection.name} in properties or additional fields. Skipping.`);
582
+ return null;
583
+ }).filter(Boolean)}
584
+ </FormLayout>
585
+ );
586
+ };
572
587
 
573
588
  const formRef = useRef<HTMLDivElement>(null);
574
589
 
575
590
  const formView = <ErrorBoundary>
576
591
  <>
577
- <div className={"w-full py-2 flex flex-col items-start my-4 lg:my-6"}>
592
+ {!Builder && <div className={"w-full py-2 flex flex-col items-start my-4 lg:my-6"}>
578
593
  <Typography
579
594
  className={"py-4 flex-grow line-clamp-1 " + (collection.hideIdFromForm ? "mb-2" : "mb-0")}
580
595
  variant={"h4"}>
@@ -586,11 +601,11 @@ export function EntityForm<M extends Record<string, any>>({
586
601
  {entity?.path ?? path}/{entityId}
587
602
  </code>
588
603
  </Alert>}
589
- </div>
604
+ </div>}
590
605
 
591
606
  {children}
592
607
 
593
- {!collection.hideIdFromForm &&
608
+ {!Builder && !collection.hideIdFromForm &&
594
609
  <CustomIdField customId={collection.customId}
595
610
  entityId={entityId}
596
611
  status={status}
@@ -616,104 +631,14 @@ export function EntityForm<M extends Record<string, any>>({
616
631
  onIdChange(entityId);
617
632
  }, [entityId, onIdChange]);
618
633
 
619
- return (
620
- <FormLayoutInner
621
- className={className}
622
- id={`form_${path}`}
623
- pluginActions={pluginActions}
624
- forceActionsAtTheBottom={forceActionsAtTheBottom}
625
- EntityFormActionsComponent={EntityFormActionsComponent}
626
- formContext={formContext}
627
- showDefaultActions={showDefaultActions}>
628
- {formView}
629
- </FormLayoutInner>
630
- );
631
- }
632
-
633
- function getInitialEntityValues<M extends object>(
634
- collection: EntityCollection,
635
- path: string,
636
- status: "new" | "existing" | "copy",
637
- entity: Entity<M> | undefined,
638
- propertyConfigs?: Record<string, PropertyConfig>
639
- ): Partial<EntityValues<M>> {
640
- const resolvedCollection = resolveCollection({
641
- collection,
642
- path,
643
- values: entity?.values,
644
- propertyConfigs
645
- });
646
- const properties = resolvedCollection.properties;
647
- if ((status === "existing" || status === "copy") && entity) {
648
- if (!collection.alwaysApplyDefaultValues) {
649
- return entity.values ?? getDefaultValuesFor(properties);
650
- } else {
651
- const defaultValues = getDefaultValuesFor(properties);
652
- return mergeDeep(defaultValues, entity.values ?? {});
653
- }
654
- } else if (status === "new") {
655
- return getDefaultValuesFor(properties);
656
- } else {
657
- console.error({
658
- status,
659
- entity
660
- });
661
- throw new Error("Form has not been initialised with the correct parameters");
662
- }
663
- }
664
-
665
- export function yupToFormErrors(yupError: ValidationError): Record<string, any> {
666
- let errors: Record<string, any> = {};
667
- if (yupError.inner) {
668
- if (yupError.inner.length === 0) {
669
- return setIn(errors, yupError.path!, yupError.message);
670
- }
671
- for (const err of yupError.inner) {
672
- if (!getIn(errors, err.path!)) {
673
- errors = setIn(errors, err.path!, err.message);
674
- }
675
- }
676
- }
677
- return errors;
678
- }
679
-
680
- export function FormLayoutInner({
681
- id,
682
- formContext,
683
- children,
684
- className,
685
- forceActionsAtTheBottom,
686
- pluginActions,
687
- EntityFormActionsComponent,
688
- showDefaultActions,
689
- }: {
690
- id?: string,
691
- formContext: FormContext,
692
- children: React.ReactNode,
693
- className?: string,
694
- forceActionsAtTheBottom?: boolean,
695
- pluginActions?: React.ReactNode[],
696
- EntityFormActionsComponent: React.FC<EntityFormActionsProps>;
697
- showDefaultActions?: boolean;
698
- }) {
699
-
700
- const formex = formContext.formex;
701
- const collection = formContext.collection;
702
- const path = formContext.path;
703
- const entity = formContext.entity;
704
- const savingError = formContext.savingError;
705
- const status = formContext.status;
706
- const openEntityMode = formContext.openEntityMode;
707
634
  const disabled = formex.isSubmitting || (!formex.dirty && status === "existing");
708
635
 
709
- const customizationController = useCustomizationController();
710
-
711
- if (!collection || !path) {
636
+ if (!resolvedCollection || !path) {
712
637
  throw Error("INTERNAL: Collection and path must be defined in form context");
713
638
  }
714
639
 
715
640
  const dialogActions = <EntityFormActionsComponent
716
- collection={collection}
641
+ collection={resolvedCollection}
717
642
  path={path}
718
643
  entity={entity}
719
644
  layout={forceActionsAtTheBottom ? "bottom" : "side"}
@@ -731,12 +656,12 @@ export function FormLayoutInner({
731
656
  <form
732
657
  onSubmit={formContext.formex.handleSubmit}
733
658
  onReset={() => formex.resetForm({
734
- values: getInitialEntityValues(collection, path, status, entity, customizationController.propertyConfigs),
659
+ values: getInitialEntityValues(collection, path, status, entity, customizationController.propertyConfigs) as M,
735
660
  })}
736
661
  noValidate
737
662
  className={cls("flex-1 flex flex-row w-full overflow-y-auto justify-center", className)}>
738
663
  <div
739
- id={id}
664
+ id={`form_${path}`}
740
665
  className={cls("relative flex flex-row max-w-4xl lg:max-w-3xl xl:max-w-4xl 2xl:max-w-6xl w-full h-fit")}>
741
666
 
742
667
  <div className={cls("flex flex-col w-full pt-12 pb-16 px-4 sm:px-8 md:px-10")}>
@@ -754,7 +679,8 @@ export function FormLayoutInner({
754
679
  <CheckIcon size={"smallest"}/>
755
680
  </Chip>
756
681
  </Tooltip>}
757
- {children}
682
+
683
+ {formView}
758
684
 
759
685
  </div>
760
686
 
@@ -766,6 +692,53 @@ export function FormLayoutInner({
766
692
  );
767
693
  }
768
694
 
695
+ function getInitialEntityValues<M extends object>(
696
+ collection: EntityCollection,
697
+ path: string,
698
+ status: "new" | "existing" | "copy",
699
+ entity: Entity<M> | undefined,
700
+ propertyConfigs?: Record<string, PropertyConfig>
701
+ ): Partial<EntityValues<M>> {
702
+ const resolvedCollection = resolveCollection({
703
+ collection,
704
+ path,
705
+ values: entity?.values,
706
+ propertyConfigs
707
+ });
708
+ const properties = resolvedCollection.properties;
709
+ if ((status === "existing" || status === "copy") && entity) {
710
+ if (!collection.alwaysApplyDefaultValues) {
711
+ return entity.values ?? getDefaultValuesFor(properties);
712
+ } else {
713
+ const defaultValues = getDefaultValuesFor(properties);
714
+ return mergeDeep(defaultValues, entity.values ?? {});
715
+ }
716
+ } else if (status === "new") {
717
+ return getDefaultValuesFor(properties);
718
+ } else {
719
+ console.error({
720
+ status,
721
+ entity
722
+ });
723
+ throw new Error("Form has not been initialised with the correct parameters");
724
+ }
725
+ }
726
+
727
+ export function yupToFormErrors(yupError: ValidationError): Record<string, any> {
728
+ let errors: Record<string, any> = {};
729
+ if (yupError.inner) {
730
+ if (yupError.inner.length === 0) {
731
+ return setIn(errors, yupError.path!, yupError.message);
732
+ }
733
+ for (const err of yupError.inner) {
734
+ if (!getIn(errors, err.path!)) {
735
+ errors = setIn(errors, err.path!, err.message);
736
+ }
737
+ }
738
+ }
739
+ return errors;
740
+ }
741
+
769
742
  function useOnAutoSave(autoSave: undefined | boolean, formex: FormexController<any>, lastSavedValues: any, save: (values: EntityValues<any>) => Promise<void>) {
770
743
  if (!autoSave) return;
771
744
  useEffect(() => {