@firecms/core 3.0.0-canary.117 → 3.0.0-canary.119

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.
@@ -177,6 +177,10 @@ export interface DataSourceDelegate {
177
177
  * If the data source has been initialised
178
178
  */
179
179
  initialised?: boolean;
180
+ /**
181
+ * If the user is authenticated to use the data source
182
+ */
183
+ authenticated?: boolean;
180
184
  /**
181
185
  * Fetch data from a collection
182
186
  * @param path
@@ -8,7 +8,7 @@ import { ChipColorKey, ChipColorScheme } from "@firecms/ui";
8
8
  /**
9
9
  * @group Entity properties
10
10
  */
11
- export type DataType<T extends CMSType = CMSType> = T extends string ? "string" : T extends number ? "number" : T extends boolean ? "boolean" : T extends Date ? "date" : T extends GeoPoint ? "geopoint" : T extends Vector ? "vector" : T extends EntityReference ? "reference" : T extends Array<CMSType> ? "array" : T extends Record<string, any> ? "map" : never;
11
+ export type DataType<T extends CMSType = CMSType> = T extends string ? "string" : T extends number ? "number" : T extends boolean ? "boolean" : T extends Date ? "date" : T extends GeoPoint ? "geopoint" : T extends Vector ? "vector" : T extends EntityReference ? "reference" : T extends Array<CMSType> ? "array" : T extends Record<string, CMSType> ? "map" : never;
12
12
  /**
13
13
  * @group Entity properties
14
14
  */
@@ -26,6 +26,19 @@ export declare function resolveProperty<T extends CMSType = CMSType, M extends R
26
26
  fields?: Record<string, PropertyConfig<any>>;
27
27
  ignoreMissingFields?: boolean;
28
28
  }): ResolvedProperty<T> | null;
29
+ export declare function getArrayResolvedProperties<M>({ propertyKey, propertyValue, property, ...props }: {
30
+ propertyValue: any;
31
+ propertyKey?: string;
32
+ property: ArrayProperty<any> | ResolvedArrayProperty<any>;
33
+ ignoreMissingFields: boolean;
34
+ values?: Partial<M>;
35
+ previousValues?: Partial<M>;
36
+ path?: string;
37
+ entityId?: string;
38
+ index?: number;
39
+ fromBuilder?: boolean;
40
+ fields?: Record<string, PropertyConfig>;
41
+ }): ResolvedProperty[];
29
42
  export declare function resolveArrayProperty<T extends any[], M>({ propertyKey, property, ignoreMissingFields, ...props }: {
30
43
  propertyKey?: string;
31
44
  property: ArrayProperty<T> | ResolvedArrayProperty<T>;
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.117",
4
+ "version": "3.0.0-canary.119",
5
5
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/firecmsco"
@@ -46,9 +46,9 @@
46
46
  "./package.json": "./package.json"
47
47
  },
48
48
  "dependencies": {
49
- "@firecms/editor": "^3.0.0-canary.117",
50
- "@firecms/formex": "^3.0.0-canary.117",
51
- "@firecms/ui": "^3.0.0-canary.117",
49
+ "@firecms/editor": "^3.0.0-canary.119",
50
+ "@firecms/formex": "^3.0.0-canary.119",
51
+ "@firecms/ui": "^3.0.0-canary.119",
52
52
  "@hello-pangea/dnd": "^16.6.0",
53
53
  "@radix-ui/react-portal": "^1.1.1",
54
54
  "clsx": "^2.1.1",
@@ -100,7 +100,7 @@
100
100
  "dist",
101
101
  "src"
102
102
  ],
103
- "gitHead": "cac002cef9ec7263a6e40cc80b15b861cee12aef",
103
+ "gitHead": "22e1ffb78b12816a576df70e3aa7df1ee29e26ad",
104
104
  "publishConfig": {
105
105
  "access": "public"
106
106
  },
@@ -82,8 +82,6 @@ export function VirtualTableSelect(props: {
82
82
  className="w-full h-full p-0 bg-transparent"
83
83
  position={"item-aligned"}
84
84
  disabled={disabled}
85
- padding={false}
86
- includeFocusOutline={false}
87
85
  value={validValue
88
86
  ? ((internalValue as any[]).map(v => v.toString()))
89
87
  : ([])}
@@ -30,15 +30,15 @@ export function DefaultDrawer({
30
30
  logo
31
31
  } = useApp();
32
32
 
33
+ const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
34
+
33
35
  const analyticsController = useAnalyticsController();
34
36
  const navigation = useNavigationController();
35
37
 
36
- const tooltipsOpen = drawerHovered && !drawerOpen;
38
+ const tooltipsOpen = drawerHovered && !drawerOpen && !adminMenuOpen;
37
39
  const largeLayout = useLargeLayout();
38
40
  const navigate = useNavigate();
39
41
 
40
- const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
41
-
42
42
  if (!navigation.topLevelNavigation)
43
43
  throw Error("Navigation not ready in Drawer");
44
44
 
@@ -91,6 +91,7 @@ export function DefaultDrawer({
91
91
  key={`navigation_${index}`}
92
92
  icon={<IconForView collectionOrView={view.collection ?? view.view}/>}
93
93
  tooltipsOpen={tooltipsOpen}
94
+ adminMenuOpen={adminMenuOpen}
94
95
  drawerOpen={drawerOpen}
95
96
  onClick={() => onClick(view)}
96
97
  url={view.url}
@@ -101,6 +102,7 @@ export function DefaultDrawer({
101
102
  </div>
102
103
 
103
104
  {adminViews.length > 0 && <Menu
105
+ side={"right"}
104
106
  open={adminMenuOpen}
105
107
  onOpenChange={setAdminMenuOpen}
106
108
  trigger={
@@ -7,6 +7,7 @@ export function DrawerNavigationItem({
7
7
  name,
8
8
  icon,
9
9
  drawerOpen,
10
+ adminMenuOpen,
10
11
  tooltipsOpen,
11
12
  url,
12
13
  onClick
@@ -15,6 +16,7 @@ export function DrawerNavigationItem({
15
16
  name: string,
16
17
  tooltipsOpen: boolean,
17
18
  drawerOpen: boolean,
19
+ adminMenuOpen?: boolean,
18
20
  url: string,
19
21
  onClick?: () => void,
20
22
  }) {
@@ -56,7 +58,7 @@ export function DrawerNavigationItem({
56
58
  </div>;
57
59
 
58
60
  return <Tooltip
59
- open={drawerOpen ? false : tooltipsOpen}
61
+ open={drawerOpen || adminMenuOpen ? false : tooltipsOpen}
60
62
  side="right"
61
63
  title={name}>
62
64
  {listItem}
@@ -54,7 +54,7 @@ export function MapFieldBinding({
54
54
  {Object.entries(mapProperties)
55
55
  .filter(([_, property]) => !isHidden(property))
56
56
  .map(([entryKey, childProperty], index) => {
57
- const fieldProps = {
57
+ const fieldBindingProps = {
58
58
  propertyKey: `${propertyKey}.${entryKey}`,
59
59
  disabled,
60
60
  property: childProperty,
@@ -70,7 +70,7 @@ export function MapFieldBinding({
70
70
  <div key={`map-${propertyKey}-${index}`}>
71
71
  <ErrorBoundary>
72
72
  <PropertyFieldBinding
73
- {...fieldProps}/>
73
+ {...fieldBindingProps}/>
74
74
  </ErrorBoundary>
75
75
  </div>
76
76
  );
@@ -2,7 +2,7 @@ import React, { useState } from "react";
2
2
  import { CMSType, FieldProps, ResolvedProperty } from "../../types";
3
3
  import { FieldHelperText, FormikArrayContainer, LabelWithIconAndTooltip } from "../components";
4
4
  import { ErrorBoundary } from "../../components";
5
- import { getDefaultValueFor, getIconForProperty } from "../../util";
5
+ import { getArrayResolvedProperties, getDefaultValueFor, getIconForProperty } from "../../util";
6
6
  import { PropertyFieldBinding } from "../PropertyFieldBinding";
7
7
  import { ExpandablePanel, Typography } from "@firecms/ui";
8
8
  import { useClearRestoreValue } from "../useClearRestoreValue";
@@ -34,8 +34,17 @@ export function RepeatFieldBinding<T extends Array<any>>({
34
34
  if (!property.of)
35
35
  throw Error("RepeatFieldBinding misconfiguration. Property `of` not set");
36
36
 
37
- if (!property.resolvedProperties || !Array.isArray(property.resolvedProperties))
38
- throw Error("RepeatFieldBinding - Internal error: Expected array in 'property.resolvedProperties'");
37
+ let resolvedProperties = property.resolvedProperties;
38
+ if (!resolvedProperties) {
39
+ resolvedProperties = getArrayResolvedProperties({
40
+ propertyValue: value,
41
+ propertyKey,
42
+ property,
43
+ ignoreMissingFields: false
44
+ })
45
+ }
46
+ // if (!resolvedProperties || !Array.isArray(resolvedProperties))
47
+ // throw Error("RepeatFieldBinding - Internal error: Expected array in 'property.resolvedProperties'");
39
48
 
40
49
  const expanded = property.expanded === undefined ? true : property.expanded;
41
50
  const ofProperty: ResolvedProperty<CMSType[]> = property.of as ResolvedProperty<CMSType[]>;
@@ -49,7 +58,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
49
58
  });
50
59
 
51
60
  const buildEntry = (index: number, internalId: number) => {
52
- const childProperty = property.resolvedProperties[index] ?? ofProperty;
61
+ const childProperty = resolvedProperties[index] ?? ofProperty;
53
62
  const fieldProps = {
54
63
  propertyKey: `${propertyKey}.${index}`,
55
64
  disabled,
@@ -49,50 +49,51 @@ export function SelectFieldBinding<T extends EnumType>({
49
49
  return (
50
50
  <>
51
51
 
52
- <PropertyIdCopyTooltip propertyKey={propertyKey}>
53
- <Select
54
- size={size === "medium" ? "medium" : "small"}
55
- value={value !== undefined && value != null ? value.toString() : ""}
56
- disabled={disabled}
57
- position="item-aligned"
58
- inputClassName={cls("w-full")}
59
- label={<LabelWithIcon
60
- icon={getIconForProperty(property, "small")}
61
- required={property.validation?.required}
62
- title={property.name}
63
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}
64
- />}
65
- endAdornment={
66
- property.clearable && <IconButton
67
- onClick={handleClearClick}>
68
- <ClearIcon/>
69
- </IconButton>
70
- }
71
- onValueChange={(updatedValue: string) => {
72
- const newValue = updatedValue
73
- ? (property.dataType === "number" ? parseFloat(updatedValue) : updatedValue)
74
- : null;
75
- return setValue(newValue as T);
76
- }}
77
- renderValue={(enumKey: any) => {
78
- return <EnumValuesChip
79
- enumKey={enumKey}
52
+ <Select
53
+ size={size === "medium" ? "medium" : "small"}
54
+ value={value !== undefined && value != null ? value.toString() : ""}
55
+ disabled={disabled}
56
+ position="item-aligned"
57
+ inputClassName={cls("w-full")}
58
+ label={
59
+ <PropertyIdCopyTooltip propertyKey={propertyKey}>
60
+ <LabelWithIcon
61
+ icon={getIconForProperty(property, "small")}
62
+ required={property.validation?.required}
63
+ title={property.name}
64
+ className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}
65
+ />
66
+ </PropertyIdCopyTooltip>}
67
+ endAdornment={
68
+ property.clearable && <IconButton
69
+ onClick={handleClearClick}>
70
+ <ClearIcon/>
71
+ </IconButton>
72
+ }
73
+ onValueChange={(updatedValue: string) => {
74
+ const newValue = updatedValue
75
+ ? (property.dataType === "number" ? parseFloat(updatedValue) : updatedValue)
76
+ : null;
77
+ return setValue(newValue as T);
78
+ }}
79
+ renderValue={(enumKey: any) => {
80
+ return <EnumValuesChip
81
+ enumKey={enumKey}
82
+ enumValues={enumValues}
83
+ size={size}/>;
84
+ }}
85
+ >
86
+ {enumValues && enumValues.map((option) => {
87
+ return <SelectItem
88
+ key={option.id}
89
+ value={String(option.id)}>
90
+ <EnumValuesChip
91
+ enumKey={String(option.id)}
80
92
  enumValues={enumValues}
81
- size={size}/>;
82
- }}
83
- >
84
- {enumValues && enumValues.map((option) => {
85
- return <SelectItem
86
- key={option.id}
87
- value={String(option.id)}>
88
- <EnumValuesChip
89
- enumKey={String(option.id)}
90
- enumValues={enumValues}
91
- size={size}/>
92
- </SelectItem>
93
- })}
94
- </Select>
95
- </PropertyIdCopyTooltip>
93
+ size={size}/>
94
+ </SelectItem>
95
+ })}
96
+ </Select>
96
97
 
97
98
  <FieldHelperText includeDescription={includeDescription}
98
99
  showError={showError}
@@ -19,7 +19,6 @@ interface TextFieldBindingProps<T extends string | number> extends FieldProps<T>
19
19
  * @group Form fields
20
20
  */
21
21
  export function TextFieldBinding<T extends string | number>({
22
- context,
23
22
  propertyKey,
24
23
  value,
25
24
  setValue,
@@ -34,10 +34,5 @@ export {
34
34
 
35
35
  export * from "./components";
36
36
 
37
- // export type { EntityFormProps } from "./EntityForm";
38
- // export {
39
- // EntityForm
40
- // } from "./EntityForm";
41
-
42
37
  export { PropertyFieldBinding } from "./PropertyFieldBinding";
43
38
  export * from "./useClearRestoreValue";
@@ -54,7 +54,7 @@ export function ArrayOfMapsPreview({
54
54
  values.map((v, index) => {
55
55
  return (
56
56
  <div key={`table_${v}_${index}`}
57
- className="border-b last:border-b-0">
57
+ className="border-b last:border-b-0 py-2">
58
58
  {mapProperties && mapProperties.map(
59
59
  (key) => (
60
60
  <div
@@ -49,7 +49,7 @@ export function ArrayOneOfPreview({
49
49
  values.map((value, index) =>
50
50
  <React.Fragment
51
51
  key={"preview_array_" + value + "_" + index}>
52
- <div className={cls(defaultBorderMixin, "m-1 border-b last:border-b-0")}>
52
+ <div className={cls(defaultBorderMixin, "m-1 border-b last:border-b-0 py-2")}>
53
53
  <ErrorBoundary>
54
54
  {value && <PropertyPreview
55
55
  propertyKey={propertyKey}
@@ -260,6 +260,11 @@ export interface DataSourceDelegate {
260
260
  */
261
261
  initialised?: boolean;
262
262
 
263
+ /**
264
+ * If the user is authenticated to use the data source
265
+ */
266
+ authenticated?: boolean;
267
+
263
268
  /**
264
269
  * Fetch data from a collection
265
270
  * @param path
@@ -18,7 +18,7 @@ export type DataType<T extends CMSType = CMSType> =
18
18
  T extends Vector ? "vector" :
19
19
  T extends EntityReference ? "reference" :
20
20
  T extends Array<CMSType> ? "array" :
21
- T extends Record<string, any> ? "map" : never;
21
+ T extends Record<string, CMSType> ? "map" : never;
22
22
 
23
23
  /**
24
24
  * @group Entity properties
@@ -217,6 +217,38 @@ export function resolveProperty<T extends CMSType = CMSType, M extends Record<st
217
217
  : null;
218
218
  }
219
219
 
220
+ export function getArrayResolvedProperties<M>({
221
+ propertyKey,
222
+ propertyValue,
223
+ property,
224
+ ...props
225
+ }: {
226
+ propertyValue: any,
227
+ propertyKey?: string,
228
+ property: ArrayProperty<any> | ResolvedArrayProperty<any>,
229
+ ignoreMissingFields: boolean,
230
+ values?: Partial<M>;
231
+ previousValues?: Partial<M>;
232
+ path?: string;
233
+ entityId?: string;
234
+ index?: number;
235
+ fromBuilder?: boolean;
236
+ fields?: Record<string, PropertyConfig>
237
+ }) {
238
+
239
+ const of = property.of;
240
+ return Array.isArray(propertyValue)
241
+ ? propertyValue.map((v: any, index: number) => {
242
+ return resolveProperty({
243
+ propertyKey: `${propertyKey}.${index}`,
244
+ propertyOrBuilder: of,
245
+ ...props,
246
+ index
247
+ });
248
+ }).filter(e => Boolean(e)) as ResolvedProperty[]
249
+ : [];
250
+ }
251
+
220
252
  export function resolveArrayProperty<T extends any[], M>({
221
253
  propertyKey,
222
254
  property,
@@ -254,17 +286,13 @@ export function resolveArrayProperty<T extends any[], M>({
254
286
  } as ResolvedArrayProperty;
255
287
  } else {
256
288
  const of = property.of;
257
- const resolvedProperties: ResolvedProperty[] = Array.isArray(propertyValue)
258
- ? propertyValue.map((v: any, index: number) => {
259
- return resolveProperty({
260
- propertyKey: `${propertyKey}.${index}`,
261
- propertyOrBuilder: of,
262
- ignoreMissingFields,
263
- ...props,
264
- index
265
- });
266
- }).filter(e => Boolean(e)) as ResolvedProperty[]
267
- : [];
289
+ const resolvedProperties = getArrayResolvedProperties({
290
+ propertyValue,
291
+ propertyKey,
292
+ property,
293
+ ignoreMissingFields,
294
+ ...props
295
+ });
268
296
  const ofProperty = resolveProperty({
269
297
  propertyOrBuilder: of,
270
298
  ignoreMissingFields,