@firecms/core 3.0.0-canary.202 → 3.0.0-canary.204

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
3
  "type": "module",
4
- "version": "3.0.0-canary.202",
4
+ "version": "3.0.0-canary.204",
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.202",
54
- "@firecms/formex": "^3.0.0-canary.202",
55
- "@firecms/ui": "^3.0.0-canary.202",
53
+ "@firecms/editor": "^3.0.0-canary.204",
54
+ "@firecms/formex": "^3.0.0-canary.204",
55
+ "@firecms/ui": "^3.0.0-canary.204",
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": "6e21f87de35d34c8c4fcb15d1e5f1d07b0f69488",
107
+ "gitHead": "2fb107e78d8fc3ade463adaf00908e3a8c812a0f",
108
108
  "publishConfig": {
109
109
  "access": "public"
110
110
  },
@@ -289,7 +289,7 @@ export function ArrayContainerItem({
289
289
  ref={provided.innerRef}
290
290
  {...provided.draggableProps}
291
291
  style={provided.draggableProps.style}
292
- className={`${
292
+ className={`relative ${
293
293
  !isDragging ? "hover:bg-surface-accent-50 dark:hover:bg-surface-800 dark:hover:bg-opacity-20" : ""
294
294
  } rounded-md opacity-100`}
295
295
  >
@@ -214,8 +214,6 @@ export function EntityEditViewInner<M extends Record<string, any>>({
214
214
  }
215
215
  }, [selectedTabProp]);
216
216
 
217
- const mainViewVisible = selectedTab === MAIN_TAB_VALUE;
218
-
219
217
  const subcollections = (collection.subcollections ?? []).filter(c => !c.hideFromNavigation);
220
218
  const subcollectionsCount = subcollections?.length ?? 0;
221
219
  const customViews = collection.entityViews;
@@ -228,28 +226,13 @@ export function EntityEditViewInner<M extends Record<string, any>>({
228
226
  : [];
229
227
 
230
228
  const selectedEntityView = resolvedEntityViews.find(e => e.key === selectedTab);
231
- const actionsAtTheBottom = !largeLayout || layout === "side_panel" || selectedEntityView?.includeActions === "bottom";
232
-
233
- const secondaryForms: React.ReactNode[] | undefined = formContext && customViews && resolvedEntityViews
234
- .filter(e => e.includeActions)
235
- .map((customView) => {
236
- if (!customView || !formContext)
237
- return null;
229
+ const selectedSecondaryForm = formContext
230
+ && customViews
231
+ && resolvedEntityViews.filter(e => e.includeActions).find(e => e.key === selectedTab);
238
232
 
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}/>;
233
+ const actionsAtTheBottom = !largeLayout || layout === "side_panel" || selectedEntityView?.includeActions === "bottom";
251
234
 
252
- }).filter(Boolean);
235
+ const mainViewVisible = selectedTab === MAIN_TAB_VALUE || Boolean(selectedSecondaryForm);
253
236
 
254
237
  const customViewsView: React.ReactNode[] | undefined = customViews && resolvedEntityViews
255
238
  .filter(e => !e.includeActions)
@@ -361,6 +344,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
361
344
  onSaved?.(res);
362
345
  formProps?.onSaved?.(res);
363
346
  }}
347
+ Builder={selectedSecondaryForm?.Builder}
364
348
  />;
365
349
 
366
350
  const subcollectionTabs = subcollections && subcollections.map((subcollection) =>
@@ -421,7 +405,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
421
405
  </div>
422
406
  : entityView}
423
407
 
424
- {secondaryForms}
408
+ {/*{secondaryForms}*/}
425
409
 
426
410
  {customViewsView}
427
411
 
@@ -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,
@@ -81,6 +82,10 @@ export type EntityFormProps<M extends Record<string, any>> = {
81
82
  showEntityPath?: boolean;
82
83
 
83
84
  EntityFormActionsComponent?: React.FC<EntityFormActionsProps>;
85
+
86
+ Builder?: React.ComponentType<EntityCustomViewParams<M>>;
87
+
88
+ children?: React.ReactNode;
84
89
  };
85
90
 
86
91
  export function EntityForm<M extends Record<string, any>>({
@@ -100,9 +105,11 @@ export function EntityForm<M extends Record<string, any>>({
100
105
  onEntityChange,
101
106
  openEntityMode = "full_screen",
102
107
  formex: formexProp,
108
+ Builder,
103
109
  EntityFormActionsComponent = EntityFormActions,
104
110
  showDefaultActions = true,
105
- showEntityPath = true
111
+ showEntityPath = true,
112
+ children
106
113
  }: EntityFormProps<M>) {
107
114
 
108
115
  if (collection.customId && collection.formAutoSave) {
@@ -495,83 +502,94 @@ export function EntityForm<M extends Record<string, any>>({
495
502
 
496
503
  const formFieldKeys = getFormFieldKeys(resolvedCollection);
497
504
 
498
- const formFields = () => (
499
- <FormLayout>
500
- {formFieldKeys.map((key) => {
501
- const property = resolvedCollection.properties[key];
502
- if (property) {
503
- const underlyingValueHasChanged: boolean =
504
- !!underlyingChanges &&
505
- Object.keys(underlyingChanges).includes(key) &&
506
- formex.touched[key];
507
- const disabled = (!autoSave && formex.isSubmitting) || isReadOnly(property) || Boolean(property.disabled);
508
- const hidden = isHidden(property);
509
- if (hidden) return null;
510
- const widthPercentage = property.widthPercentage ?? 100;
511
- const cmsFormFieldProps: PropertyFieldBindingProps<any, M> = {
512
- propertyKey: key,
513
- disabled,
514
- property,
515
- includeDescription: property.description || property.longDescription,
516
- underlyingValueHasChanged: underlyingValueHasChanged && !autoSave,
517
- context: formContext,
518
- partOfArray: false,
519
- minimalistView: false,
520
- autoFocus: false
521
- };
522
-
523
- return (
524
- <FormEntry propertyKey={key}
525
- widthPercentage={widthPercentage}
526
- key={`field_${key}`}>
527
- <PropertyFieldBinding {...cmsFormFieldProps} />
528
- </FormEntry>
529
- );
530
- }
505
+ const formFields = () => {
531
506
 
532
- const additionalField = resolvedCollection.additionalFields?.find(f => f.key === key);
533
- if (additionalField && entity) {
534
- const Builder = additionalField.Builder;
535
- if (!Builder && !additionalField.value) {
536
- 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
+ );
537
547
  }
538
- const child = Builder
539
- ? <Builder entity={entity} context={context}/>
540
- : <div className={"w-full"}>
541
- {additionalField.value?.({
542
- entity,
543
- context
544
- })?.toString()}
545
- </div>;
546
-
547
- return (
548
- <div key={`additional_${key}`} className={"w-full"}>
549
- <LabelWithIconAndTooltip
550
- propertyKey={key}
551
- icon={<NotesIcon size={"small"}/>}
552
- title={additionalField.name}
553
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
554
- <div
555
- className={cls(paperMixin, "w-full min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
556
- <ErrorBoundary>
557
- {child}
558
- </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>
559
577
  </div>
560
- </div>
561
- );
562
- }
578
+ );
579
+ }
563
580
 
564
- console.warn(`Property ${key} not found in collection ${resolvedCollection.name} in properties or additional fields. Skipping.`);
565
- return null;
566
- }).filter(Boolean)}
567
- </FormLayout>
568
- );
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
+ };
569
587
 
570
588
  const formRef = useRef<HTMLDivElement>(null);
571
589
 
572
590
  const formView = <ErrorBoundary>
573
591
  <>
574
- <div className={"w-full py-2 flex flex-col items-start mt-4 lg:mt-8 mb-8"}>
592
+ <div className={"w-full py-2 flex flex-col items-start my-4 lg:my-6"}>
575
593
  <Typography
576
594
  className={"py-4 flex-grow line-clamp-1 " + (collection.hideIdFromForm ? "mb-2" : "mb-0")}
577
595
  variant={"h4"}>
@@ -585,6 +603,8 @@ export function EntityForm<M extends Record<string, any>>({
585
603
  </Alert>}
586
604
  </div>
587
605
 
606
+ {children}
607
+
588
608
  {!collection.hideIdFromForm &&
589
609
  <CustomIdField customId={collection.customId}
590
610
  entityId={entityId}
@@ -75,7 +75,7 @@ export function MapFieldBinding({
75
75
  };
76
76
 
77
77
  return (
78
- <div key={`map-${propertyKey}-${index}`}>
78
+ <div key={`map-${propertyKey}-${index}`} className={"relative"}>
79
79
  <ErrorBoundary>
80
80
  <PropertyFieldBinding
81
81
  {...fieldBindingProps}/>