@firecms/core 3.0.0-canary.198 → 3.0.0-canary.199

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.
@@ -18,6 +18,7 @@ export interface NavigationViewEntityCustomInternal<M extends Record<string, any
18
18
  type: "custom_view";
19
19
  path: string;
20
20
  fullPath: string;
21
+ entityId: string;
21
22
  view: EntityCustomView<M>;
22
23
  }
23
24
  export declare function getNavigationEntriesFromPath(props: {
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.198",
4
+ "version": "3.0.0-canary.199",
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.198",
54
- "@firecms/formex": "^3.0.0-canary.198",
55
- "@firecms/ui": "^3.0.0-canary.198",
53
+ "@firecms/editor": "^3.0.0-canary.199",
54
+ "@firecms/formex": "^3.0.0-canary.199",
55
+ "@firecms/ui": "^3.0.0-canary.199",
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": "c246dc2774f7ef1a91df3da792a217decbda700b",
107
+ "gitHead": "c61e0a8c9aaf3e671612490547db2254b4729b50",
108
108
  "publishConfig": {
109
109
  "access": "public"
110
110
  },
@@ -348,7 +348,7 @@ export const EntityCollectionView = React.memo(
348
348
  const updatedValues = setIn({ ...entity.values }, propertyKey, value);
349
349
 
350
350
  const saveProps: SaveEntityProps = {
351
- path: fullPath,
351
+ path: entity.path ?? fullPath,
352
352
  entityId: entity.id,
353
353
  values: updatedValues,
354
354
  previousValues: entity.values,
@@ -494,77 +494,76 @@ export function EntityForm<M extends Record<string, any>>({
494
494
  const formFieldKeys = getFormFieldKeys(resolvedCollection);
495
495
 
496
496
  const formFields = () => (
497
- <FormLayout>
498
- {formFieldKeys.map((key) => {
499
- const property = resolvedCollection.properties[key];
500
- if (property) {
501
- const underlyingValueHasChanged: boolean =
502
- !!underlyingChanges &&
503
- Object.keys(underlyingChanges).includes(key) &&
504
- formex.touched[key];
505
- const disabled = (!autoSave && formex.isSubmitting) || isReadOnly(property) || Boolean(property.disabled);
506
- const hidden = isHidden(property);
507
- if (hidden) return null;
508
- const widthPercentage = property.widthPercentage ?? 100;
509
- const cmsFormFieldProps: PropertyFieldBindingProps<any, M> = {
510
- propertyKey: key,
511
- disabled,
512
- property,
513
- includeDescription: property.description || property.longDescription,
514
- underlyingValueHasChanged: underlyingValueHasChanged && !autoSave,
515
- context: formContext,
516
- partOfArray: false,
517
- minimalistView: false,
518
- autoFocus: false
519
- };
520
-
521
- return (
522
- <FormEntry propertyKey={key}
523
- widthPercentage={widthPercentage}
524
- key={`field_${key}`}>
525
- <PropertyFieldBinding {...cmsFormFieldProps} />
526
- </FormEntry>
527
- );
528
- }
497
+ <FormLayout>
498
+ {formFieldKeys.map((key) => {
499
+ const property = resolvedCollection.properties[key];
500
+ if (property) {
501
+ const underlyingValueHasChanged: boolean =
502
+ !!underlyingChanges &&
503
+ Object.keys(underlyingChanges).includes(key) &&
504
+ formex.touched[key];
505
+ const disabled = (!autoSave && formex.isSubmitting) || isReadOnly(property) || Boolean(property.disabled);
506
+ const hidden = isHidden(property);
507
+ if (hidden) return null;
508
+ const widthPercentage = property.widthPercentage ?? 100;
509
+ const cmsFormFieldProps: PropertyFieldBindingProps<any, M> = {
510
+ propertyKey: key,
511
+ disabled,
512
+ property,
513
+ includeDescription: property.description || property.longDescription,
514
+ underlyingValueHasChanged: underlyingValueHasChanged && !autoSave,
515
+ context: formContext,
516
+ partOfArray: false,
517
+ minimalistView: false,
518
+ autoFocus: false
519
+ };
520
+
521
+ return (
522
+ <FormEntry propertyKey={key}
523
+ widthPercentage={widthPercentage}
524
+ key={`field_${key}`}>
525
+ <PropertyFieldBinding {...cmsFormFieldProps} />
526
+ </FormEntry>
527
+ );
528
+ }
529
529
 
530
- const additionalField = resolvedCollection.additionalFields?.find(f => f.key === key);
531
- if (additionalField && entity) {
532
- const Builder = additionalField.Builder;
533
- if (!Builder && !additionalField.value) {
534
- throw new Error("When using additional fields you need to provide a Builder or a value");
535
- }
536
- const child = Builder
537
- ? <Builder entity={entity} context={context}/>
538
- : <div className={"w-full"}>
539
- {additionalField.value?.({
540
- entity,
541
- context
542
- })?.toString()}
543
- </div>;
544
-
545
- return (
546
- <div key={`additional_${key}`} className={"w-full"}>
547
- <LabelWithIconAndTooltip
548
- propertyKey={key}
549
- icon={<NotesIcon size={"small"}/>}
550
- title={additionalField.name}
551
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
552
- <div
553
- className={cls(paperMixin, "w-full min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
554
- <ErrorBoundary>
555
- {child}
556
- </ErrorBoundary>
557
- </div>
558
- </div>
559
- );
530
+ const additionalField = resolvedCollection.additionalFields?.find(f => f.key === key);
531
+ if (additionalField && entity) {
532
+ const Builder = additionalField.Builder;
533
+ if (!Builder && !additionalField.value) {
534
+ throw new Error("When using additional fields you need to provide a Builder or a value");
560
535
  }
536
+ const child = Builder
537
+ ? <Builder entity={entity} context={context}/>
538
+ : <div className={"w-full"}>
539
+ {additionalField.value?.({
540
+ entity,
541
+ context
542
+ })?.toString()}
543
+ </div>;
544
+
545
+ return (
546
+ <div key={`additional_${key}`} className={"w-full"}>
547
+ <LabelWithIconAndTooltip
548
+ propertyKey={key}
549
+ icon={<NotesIcon size={"small"}/>}
550
+ title={additionalField.name}
551
+ className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
552
+ <div
553
+ className={cls(paperMixin, "w-full min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
554
+ <ErrorBoundary>
555
+ {child}
556
+ </ErrorBoundary>
557
+ </div>
558
+ </div>
559
+ );
560
+ }
561
561
 
562
- console.warn(`Property ${key} not found in collection ${resolvedCollection.name} in properties or additional fields. Skipping.`);
563
- return null;
564
- }).filter(Boolean)}
565
- </FormLayout>
566
- )
567
- ;
562
+ console.warn(`Property ${key} not found in collection ${resolvedCollection.name} in properties or additional fields. Skipping.`);
563
+ return null;
564
+ }).filter(Boolean)}
565
+ </FormLayout>
566
+ );
568
567
 
569
568
  const formRef = useRef<HTMLDivElement>(null);
570
569
 
@@ -104,12 +104,10 @@ export const useBuildSideEntityController = (navigation: NavigationController,
104
104
  const panelsFromUrl = buildSidePanelsFromUrl(entityOrCollectionPath, navigation.collections ?? [], newFlag);
105
105
  for (let i = 0; i < panelsFromUrl.length; i++) {
106
106
  const props = panelsFromUrl[i];
107
- // setTimeout(() => {
108
107
  if (i === 0)
109
108
  sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout));
110
109
  else
111
110
  sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout))
112
- // }, 1);
113
111
  }
114
112
  }
115
113
  initialised.current = true;
@@ -107,6 +107,19 @@ export function FireCMSRoute() {
107
107
 
108
108
  }
109
109
 
110
+ function getSelectedTabFromUrl(isNew: boolean, lastCustomView: NavigationViewCollectionInternal<any> | NavigationViewEntityCustomInternal<any> | undefined) {
111
+ if (isNew) {
112
+ return undefined;
113
+ } else if (lastCustomView) {
114
+ if (lastCustomView.type === "custom_view") {
115
+ return lastCustomView.view.key;
116
+ } else if (lastCustomView.type === "collection") {
117
+ return lastCustomView.id ?? lastCustomView.path;
118
+ }
119
+ }
120
+ return undefined;
121
+ }
122
+
110
123
  function EntityFullScreenRoute({
111
124
  pathname,
112
125
  navigationEntries,
@@ -136,7 +149,7 @@ function EntityFullScreenRoute({
136
149
 
137
150
  const entityId = lastEntityEntry?.entityId;
138
151
 
139
- const urlTab = isNew ? undefined : (lastCustomView && "id" in lastCustomView ? lastCustomView?.id : undefined) ?? lastCustomView?.path;
152
+ const urlTab = getSelectedTabFromUrl(isNew, lastCustomView);
140
153
  const [selectedTab, setSelectedTab] = useState<string | undefined>(urlTab);
141
154
 
142
155
  const parentCollectionIds = navigation.getParentCollectionIds(navigationPath);
@@ -27,6 +27,7 @@ export interface NavigationViewEntityCustomInternal<M extends Record<string, any
27
27
  type: "custom_view";
28
28
  path: string;
29
29
  fullPath: string;
30
+ entityId: string;
30
31
  view: EntityCustomView<M>;
31
32
  }
32
33
 
@@ -88,13 +89,11 @@ export function getNavigationEntriesFromPath(props: {
88
89
  .filter(Boolean)
89
90
  .find((entry) => entry!.key === newPath);
90
91
  if (customView) {
91
- const path = currentFullPath && currentFullPath.length > 0
92
- ? (currentFullPath + "/" + customView.key)
93
- : customView.key;
94
92
  result.push({
95
93
  type: "custom_view",
96
- path,
97
- fullPath: fullPath + "/" + path,
94
+ path: collectionPath,
95
+ entityId: entityId,
96
+ fullPath: fullPath + "/" + customView.key,
98
97
  view: customView
99
98
  });
100
99
  } else if (collection.subcollections) {