@firecms/core 3.0.0-canary.186 → 3.0.0-canary.187

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.
@@ -68,24 +68,28 @@ export const NavigationRoutes = React.memo<NavigationRoutesProps>(
68
68
  });
69
69
  }
70
70
 
71
- const urlPath = navigation.buildUrlCollectionPath("");
72
- const collectionRoute = <Route path={urlPath + "/*"}
73
- key={`navigation_entity`}
74
- element={
75
- <ErrorBoundary>
76
- <FireCMSRoute/>
77
- </ErrorBoundary>
78
- }/>
71
+ const collectionUrlPath = navigation.buildUrlCollectionPath("");
72
+ const collectionRoute = (
73
+ <Route path={collectionUrlPath + "/*"}
74
+ key={`navigation_entity`}
75
+ element={
76
+ <ErrorBoundary>
77
+ <FireCMSRoute/>
78
+ </ErrorBoundary>
79
+ }/>
80
+ );
79
81
 
80
82
  const homeRoute = (
81
83
  <Route path={"/"}
82
84
  element={<HomePageRoute>{homePage}</HomePageRoute>}/>
83
85
  );
84
86
 
85
- const notFoundRoute = <Route path={"*"}
86
- element={
87
- <NotFoundPage/>
88
- }/>;
87
+ const notFoundRoute = (
88
+ <Route path={"*"}
89
+ element={
90
+ <NotFoundPage/>
91
+ }/>
92
+ );
89
93
 
90
94
  return (
91
95
  <Routes location={baseLocation}>
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { ErrorBoundary } from "../../components";
3
+
4
+ export function FormEntry({
5
+ propertyKey,
6
+ widthPercentage = 100,
7
+ children
8
+ }: {
9
+ propertyKey: string;
10
+ widthPercentage?: number;
11
+ children: React.ReactNode;
12
+ }) {
13
+ return (
14
+ <div id={`form_field_${propertyKey}`}
15
+ className={"relative"}
16
+ style={{ width: widthPercentage === 100 ? "100%" : `calc(${widthPercentage}% - 8px)` }}>
17
+ <ErrorBoundary>
18
+ {children}
19
+ </ErrorBoundary>
20
+ </div>
21
+ );
22
+ }
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { cls } from "@firecms/ui";
3
+
4
+ export function FormLayout({
5
+ children,
6
+ className
7
+ }: {
8
+ children: React.ReactNode;
9
+ className?: string;
10
+ }) {
11
+ return (
12
+ <div className={cls("flex flex-wrap gap-x-4 w-full space-y-8", className)}>
13
+ {children}
14
+ </div>
15
+ );
16
+ }
@@ -1,3 +1,5 @@
1
1
  export * from "./FieldHelperText";
2
2
  export * from "./LabelWithIcon";
3
3
  export * from "./LabelWithIconAndTooltip";
4
+ export * from "./FormEntry";
5
+ export * from "./FormLayout";
@@ -23,7 +23,6 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
23
23
  minimalistView: minimalistViewProp,
24
24
  property,
25
25
  includeDescription,
26
- underlyingValueHasChanged,
27
26
  context,
28
27
  disabled
29
28
  }: FieldProps<T, any, any>) {
@@ -65,7 +64,6 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
65
64
  disabled: disabled || thisDisabled,
66
65
  property: childProperty,
67
66
  includeDescription,
68
- underlyingValueHasChanged,
69
67
  context,
70
68
  partOfArray: true,
71
69
  minimalistView: false,
@@ -23,7 +23,6 @@ export function MapFieldBinding({
23
23
  property,
24
24
  minimalistView: minimalistViewProp,
25
25
  includeDescription,
26
- underlyingValueHasChanged,
27
26
  autoFocus,
28
27
  context,
29
28
  onPropertyChange
@@ -62,7 +61,6 @@ export function MapFieldBinding({
62
61
  disabled: disabled || thisDisabled,
63
62
  property: childProperty,
64
63
  includeDescription,
65
- underlyingValueHasChanged,
66
64
  context,
67
65
  partOfArray: false,
68
66
  minimalistView: false,
@@ -190,10 +190,15 @@ function EntityFullScreenRoute({
190
190
  onValuesModified={(modified) => blocked.current = modified}
191
191
  onSaved={(params) => {
192
192
  console.log("Entity saved", params);
193
- navigate(`${basePath}/${params.entityId}`, { replace: true });
193
+ const newSelectedTab = params.selectedTab;
194
+ const newEntityId = params.entityId;
195
+ if (newSelectedTab) {
196
+ navigate(`${basePath}/${newEntityId}/${newSelectedTab}`, { replace: true });
197
+ } else {
198
+ navigate(`${basePath}/${newEntityId}`, { replace: true });
199
+ }
194
200
  }}
195
201
  onTabChange={(params) => {
196
- // updateUrl(params.entityId, params.selectedTab, !isNew, params.path, isNew);
197
202
  setSelectedTab(params.selectedTab);
198
203
  if (isNew) {
199
204
  return;
@@ -1,6 +1,7 @@
1
1
  import { CMSType, Property, PropertyOrBuilder } from "./properties";
2
2
  import { ResolvedEntityCollection, ResolvedProperty } from "./resolved_entities";
3
3
  import { FormexController } from "@firecms/formex";
4
+ import { Entity } from "./entities";
4
5
 
5
6
  /**
6
7
  * When building a custom field you need to create a React component that takes
@@ -161,6 +162,21 @@ export interface FormContext<M extends Record<string, any> = any> {
161
162
  */
162
163
  path?: string;
163
164
 
165
+ status: "new" | "existing" | "copy";
166
+
167
+ entity?: Entity<M>;
168
+
169
+ savingError?: Error;
170
+
171
+ openEntityMode: "side_panel" | "full_screen";
172
+
173
+ /**
174
+ * If pending close is set to true, the form will close when the user
175
+ * saves the entity
176
+ * @param pendingClose
177
+ */
178
+ setPendingClose?: (pendingClose: boolean) => void;
179
+
164
180
  /**
165
181
  * This is the underlying formex controller that powers the form
166
182
  */
@@ -5,6 +5,7 @@ import { EntityReference } from "./entities";
5
5
  /**
6
6
  * Controller that includes the resolved navigation and utility methods and
7
7
  * attributes.
8
+ * This controller holds the state of the navigation including the collections.
8
9
  * @group Models
9
10
  */
10
11
  export type NavigationController<EC extends EntityCollection = EntityCollection<any>> = {
@@ -195,7 +195,7 @@ export interface PluginFormActionProps<USER extends User = User, EC extends Enti
195
195
  formContext?: FormContext<any>;
196
196
  context: FireCMSContext<USER>;
197
197
  currentEntityId?: string;
198
- layout: "side_panel" | "full_screen";
198
+ openEntityMode: "side_panel" | "full_screen";
199
199
  }
200
200
 
201
201
  export type PluginFieldBuilderParams<T extends CMSType = CMSType, M extends Record<string, any> = any, EC extends EntityCollection<M> = EntityCollection<M>> = {
@@ -377,7 +377,7 @@ export interface StringProperty extends BaseProperty<string> {
377
377
 
378
378
  /**
379
379
  * You can specify a `Storage` configuration. It is used to
380
- * indicate that this string refers to a path in Google Cloud Storage.
380
+ * indicate that this string refers to a path in your storage provider.
381
381
  */
382
382
  storage?: StorageConfig;
383
383
 
@@ -10,23 +10,31 @@ const entityCache: Map<string, object> = new Map();
10
10
  const isLocalStorageAvailable = typeof localStorage !== "undefined";
11
11
 
12
12
  // Define custom replacer for JSON.stringify
13
- function customReplacer(key: string, value: any): any {
13
+ function customReplacer(key: string): any {
14
+
15
+ // @ts-ignore
16
+ const value = this[key];
17
+
14
18
  // Handle Date objects
19
+ // @ts-ignore
15
20
  if (value instanceof Date) {
16
21
  return { __type: "Date", value: value.toISOString() };
17
22
  }
18
23
 
19
24
  // Handle EntityReference
25
+ // @ts-ignore
20
26
  if (value instanceof EntityReference) {
21
27
  return { __type: "EntityReference", id: value.id, path: value.path };
22
28
  }
23
29
 
24
30
  // Handle GeoPoint
31
+ // @ts-ignore
25
32
  if (value instanceof GeoPoint) {
26
33
  return { __type: "GeoPoint", latitude: value.latitude, longitude: value.longitude };
27
34
  }
28
35
 
29
36
  // Handle Vector
37
+ // @ts-ignore
30
38
  if (value instanceof Vector) {
31
39
  return { __type: "Vector", value: value.value };
32
40
  }
@@ -93,6 +101,7 @@ export function saveEntityToCache(path: string, data: object): void {
93
101
  if (isLocalStorageAvailable) {
94
102
  try {
95
103
  const key = LOCAL_STORAGE_PREFIX + path;
104
+ console.log("Saving entity to cache", key, data);
96
105
  const entityString = JSON.stringify(data, customReplacer);
97
106
  localStorage.setItem(key, entityString);
98
107
  } catch (error) {