@firecms/core 3.0.0-alpha.20 → 3.0.0-alpha.21

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,3 +1,4 @@
1
+ import React from "react";
1
2
  import { User } from "./user";
2
3
  import { AuthController } from "./auth";
3
4
  import { DataSource } from "./datasource";
@@ -108,11 +109,6 @@ export type FireCMSProps<UserType extends User> = {
108
109
  * Delegate for implementing your auth operations.
109
110
  */
110
111
  authController: AuthController<UserType>;
111
- /**
112
- * Optional link builder you can add to generate a button in your entity forms.
113
- * The function must return a URL that gets opened when the button is clicked
114
- */
115
- entityLinkBuilder?: EntityLinkBuilder;
116
112
  /**
117
113
  * Path under the navigation routes of the CMS will be created. Defaults to `/`.
118
114
  * Internally FireCMS uses `react-router` to create the routes, the base path is attached to the
@@ -139,4 +135,17 @@ export type FireCMSProps<UserType extends User> = {
139
135
  * Callback used to get analytics events from the CMS
140
136
  */
141
137
  onAnalyticsEvent?: (event: CMSAnalyticsEvent, data?: object) => void;
138
+ /**
139
+ * Optional link builder you can add to generate a button in your entity forms.
140
+ * The function must return a URL that gets opened when the button is clicked
141
+ */
142
+ entityLinkBuilder?: EntityLinkBuilder;
143
+ components?: {
144
+ /**
145
+ * Component to render when a reference is missing
146
+ */
147
+ missingReference?: React.ComponentType<{
148
+ path: string;
149
+ }>;
150
+ };
142
151
  };
@@ -92,4 +92,12 @@ export type FireCMSContext<UserType extends User = User, AuthControllerType exte
92
92
  * You can also define an entity view from the UI.
93
93
  */
94
94
  entityViews?: EntityCustomView[];
95
+ components?: {
96
+ /**
97
+ * Component to render when a reference is missing
98
+ */
99
+ missingReference?: React.ComponentType<{
100
+ path: string;
101
+ }>;
102
+ };
95
103
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
- "version": "3.0.0-alpha.20",
3
+ "version": "3.0.0-alpha.21",
4
4
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
5
5
  "funding": {
6
6
  "url": "https://github.com/sponsors/firecmsco"
@@ -132,7 +132,7 @@
132
132
  "dist",
133
133
  "src"
134
134
  ],
135
- "gitHead": "7b74c47b5ea9f490bd0ba3d2b479108484a19411",
135
+ "gitHead": "4a18047fa8fd4ddaa157ec2d415fcab89cf34d65",
136
136
  "publishConfig": {
137
137
  "access": "public"
138
138
  }
@@ -185,18 +185,6 @@ export function Select({
185
185
  </SelectPrimitive.Viewport>
186
186
  </SelectPrimitive.Content>
187
187
  </SelectPrimitive.Portal>
188
- {/*<SelectPrimitive.Portal>*/}
189
- {/* <SelectPrimitive.Content*/}
190
- {/* className={cn("z-50 relative border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-800 p-2 rounded-lg shadow-lg ",*/}
191
- {/* // "overflow-auto"*/}
192
- {/* )}*/}
193
- {/* position={position}*/}
194
- {/* align={"center"}>*/}
195
- {/* <SelectPrimitive.Viewport>*/}
196
- {/* {children}*/}
197
- {/* </SelectPrimitive.Viewport>*/}
198
- {/* </SelectPrimitive.Content>*/}
199
- {/*</SelectPrimitive.Portal>*/}
200
188
  </SelectPrimitive.Root>
201
189
  );
202
190
  }
@@ -53,7 +53,8 @@ export function FireCMS<UserType extends User>(props: FireCMSProps<UserType>) {
53
53
  plugins,
54
54
  onAnalyticsEvent,
55
55
  fields,
56
- entityViews
56
+ entityViews,
57
+ components
57
58
  } = props;
58
59
 
59
60
  useLocaleConfig(locale);
@@ -81,8 +82,9 @@ export function FireCMS<UserType extends User>(props: FireCMSProps<UserType>) {
81
82
  plugins,
82
83
  onAnalyticsEvent,
83
84
  entityViews: entityViews ?? [],
84
- fields: fields ?? {}
85
- }), [dateTimeFormat, locale, plugins, entityViews, fields]);
85
+ fields: fields ?? {},
86
+ components
87
+ }), [dateTimeFormat, locale, plugins, entityViews, fields, components]);
86
88
 
87
89
  if (navigation.navigationLoadingError) {
88
90
  return (
@@ -1,14 +1,14 @@
1
1
  import React, { useCallback, useState } from "react";
2
2
  import { ReferencePreview, ReferencePreviewContainer } from "../../../../preview";
3
- import { CollectionSize, Entity, EntityReference, FilterValues } from "../../../../types";
3
+ import { CollectionSize, Entity, EntityCollection, EntityReference, FilterValues } from "../../../../types";
4
4
 
5
5
  import { getPreviewSizeFrom } from "../../../../preview/util";
6
6
  import { getReferenceFrom } from "../../../util";
7
- import { useNavigationContext, useReferenceDialog } from "../../../../hooks";
7
+ import { useFireCMSContext, useNavigationContext, useReferenceDialog } from "../../../../hooks";
8
8
  import { ErrorView } from "../../ErrorView";
9
9
  import { Button } from "../../../../components/Button";
10
10
 
11
- export function TableReferenceField(props: {
11
+ type TableReferenceFieldProps = {
12
12
  name: string;
13
13
  disabled: boolean;
14
14
  internalValue: EntityReference | EntityReference[] | undefined | null;
@@ -19,8 +19,27 @@ export function TableReferenceField(props: {
19
19
  title?: string;
20
20
  path: string;
21
21
  forceFilter?: FilterValues<string>;
22
- }) {
22
+ };
23
+
24
+ export function TableReferenceField(props: TableReferenceFieldProps) {
25
+
26
+ const context = useFireCMSContext();
27
+ const navigationContext = useNavigationContext();
28
+ const { path } = props;
29
+ const collection = navigationContext.getCollection<EntityCollection>(path);
30
+ if (!collection) {
31
+ if (context.components?.missingReference) {
32
+ return <context.components.missingReference path={path}/>;
33
+ } else {
34
+ throw Error(`Couldn't find the corresponding collection view for the path: ${path}`);
35
+ }
36
+ }
37
+ return <TableReferenceFieldSuccess {...props} collection={collection}/>;
38
+ }
23
39
 
40
+ function TableReferenceFieldSuccess(props: TableReferenceFieldProps & {
41
+ collection: EntityCollection;
42
+ }) {
24
43
  const {
25
44
  name,
26
45
  internalValue,
@@ -31,7 +50,8 @@ export function TableReferenceField(props: {
31
50
  previewProperties,
32
51
  title,
33
52
  disabled,
34
- forceFilter
53
+ forceFilter,
54
+ collection
35
55
  } = props;
36
56
 
37
57
  const [onHover, setOnHover] = useState(false);
@@ -39,13 +59,6 @@ export function TableReferenceField(props: {
39
59
  const hoverTrue = useCallback(() => setOnHover(true), []);
40
60
  const hoverFalse = useCallback(() => setOnHover(false), []);
41
61
 
42
- const navigationContext = useNavigationContext();
43
-
44
- const collection = navigationContext.getCollection(path);
45
- if (!collection) {
46
- throw Error(`Couldn't find the corresponding collection view for the path: ${path}`);
47
- }
48
-
49
62
  const onSingleEntitySelected = useCallback((entity: Entity<any>) => {
50
63
  updateValue(entity ? getReferenceFrom(entity) : null);
51
64
  }, [updateValue]);
@@ -17,3 +17,4 @@ export * from "./plurals";
17
17
  export * from "./references";
18
18
  export * from "./debounce";
19
19
  export * from "./flatten_object";
20
+ export * from "./make_properties_editable";
@@ -0,0 +1,11 @@
1
+ import { Properties } from "../../types";
2
+
3
+ export function makePropertiesEditable(properties: Properties) {
4
+ Object.keys(properties).forEach((key) => {
5
+ const property = properties[key];
6
+ property.editable = true;
7
+ if (property.dataType === "map" && property.properties) {
8
+ makePropertiesEditable(property.properties as Properties);
9
+ }
10
+ });
11
+ }
@@ -61,15 +61,35 @@ function ReferencePreviewInternal<M extends Record<string, any>>({
61
61
  }: ReferencePreviewProps) {
62
62
 
63
63
  const context = useFireCMSContext();
64
-
65
64
  const navigationContext = useNavigationContext();
66
- const sideEntityController = useSideEntityController();
67
65
 
68
66
  const collection = navigationContext.getCollection<EntityCollection<M>>(reference.path);
69
67
  if (!collection) {
70
- throw Error(`Couldn't find the corresponding collection view for the path: ${reference.path}`);
68
+ if (context.components?.missingReference) {
69
+ return <context.components.missingReference path={reference.path}/>;
70
+ } else {
71
+ throw Error(`Couldn't find the corresponding collection view for the path: ${reference.path}`);
72
+ }
71
73
  }
72
74
 
75
+ return <ReferencePreviewExisting
76
+ reference={reference}
77
+ collection={collection}
78
+ previewProperties={previewProperties}
79
+ size={size}
80
+ disabled={disabled}
81
+ allowEntityNavigation={allowEntityNavigation}
82
+ onClick={onClick}
83
+ onHover={onHover}/>
84
+ }
85
+
86
+ function ReferencePreviewExisting<M extends Record<string, any> = any>({ reference, collection, previewProperties, size, disabled, allowEntityNavigation, onClick, onHover }: ReferencePreviewProps & {
87
+ collection: EntityCollection<M>
88
+ }) {
89
+
90
+ const context = useFireCMSContext();
91
+ const sideEntityController = useSideEntityController();
92
+
73
93
  const {
74
94
  entity,
75
95
  dataLoading,
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  import { User } from "./user";
2
3
  import { AuthController } from "./auth";
3
4
  import { DataSource } from "./datasource";
@@ -123,12 +124,6 @@ export type FireCMSProps<UserType extends User> = {
123
124
  */
124
125
  authController: AuthController<UserType>;
125
126
 
126
- /**
127
- * Optional link builder you can add to generate a button in your entity forms.
128
- * The function must return a URL that gets opened when the button is clicked
129
- */
130
- entityLinkBuilder?: EntityLinkBuilder;
131
-
132
127
  /**
133
128
  * Path under the navigation routes of the CMS will be created. Defaults to `/`.
134
129
  * Internally FireCMS uses `react-router` to create the routes, the base path is attached to the
@@ -160,4 +155,21 @@ export type FireCMSProps<UserType extends User> = {
160
155
  */
161
156
  onAnalyticsEvent?: (event: CMSAnalyticsEvent, data?: object) => void;
162
157
 
158
+ /**
159
+ * Optional link builder you can add to generate a button in your entity forms.
160
+ * The function must return a URL that gets opened when the button is clicked
161
+ */
162
+ entityLinkBuilder?: EntityLinkBuilder;
163
+
164
+ components?: {
165
+
166
+ /**
167
+ * Component to render when a reference is missing
168
+ */
169
+ missingReference?: React.ComponentType<{
170
+ path: string,
171
+ }>;
172
+
173
+ }
174
+
163
175
  };
@@ -108,4 +108,13 @@ export type FireCMSContext<UserType extends User = User, AuthControllerType exte
108
108
  * You can also define an entity view from the UI.
109
109
  */
110
110
  entityViews?: EntityCustomView[];
111
+
112
+ components?: {
113
+
114
+ /**
115
+ * Component to render when a reference is missing
116
+ */
117
+ missingReference?: React.ComponentType<{ path: string }>;
118
+
119
+ }
111
120
  };