@firecms/core 3.0.0-canary.3 → 3.0.0-canary.31

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.
Files changed (180) hide show
  1. package/README.md +2 -2
  2. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +1 -1
  3. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  4. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +2 -2
  5. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -2
  6. package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
  7. package/dist/components/EntityPreview.d.ts +25 -7
  8. package/dist/components/EntityView.d.ts +11 -0
  9. package/dist/components/FieldCaption.d.ts +5 -0
  10. package/dist/components/HomePage/NavigationCard.d.ts +8 -0
  11. package/dist/components/HomePage/{NavigationCollectionCard.d.ts → NavigationCardBinding.d.ts} +2 -2
  12. package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
  13. package/dist/components/HomePage/index.d.ts +3 -1
  14. package/dist/components/ReferenceWidget.d.ts +3 -3
  15. package/dist/components/VirtualTable/VirtualTableProps.d.ts +1 -1
  16. package/dist/components/index.d.ts +4 -3
  17. package/dist/contexts/AuthControllerContext.d.ts +1 -1
  18. package/dist/{internal/EntityView.d.ts → core/EntityEditView.d.ts} +2 -2
  19. package/dist/core/SideEntityView.d.ts +7 -0
  20. package/dist/core/index.d.ts +0 -2
  21. package/dist/form/EntityForm.d.ts +1 -1
  22. package/dist/form/components/StorageItemPreview.d.ts +3 -2
  23. package/dist/form/components/StorageUploadProgress.d.ts +1 -1
  24. package/dist/form/components/index.d.ts +1 -0
  25. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  26. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  27. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +4 -3
  28. package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
  29. package/dist/form/index.d.ts +1 -0
  30. package/dist/form/validation.d.ts +1 -1
  31. package/dist/hooks/data/delete.d.ts +2 -2
  32. package/dist/hooks/data/save.d.ts +1 -1
  33. package/dist/hooks/data/useDataSource.d.ts +2 -2
  34. package/dist/hooks/data/useEntityFetch.d.ts +3 -3
  35. package/dist/hooks/index.d.ts +3 -1
  36. package/dist/{core → hooks}/useBuildModeController.d.ts +1 -1
  37. package/dist/hooks/useBuildNavigationController.d.ts +6 -4
  38. package/dist/hooks/useProjectLog.d.ts +6 -2
  39. package/dist/hooks/useStorageSource.d.ts +2 -2
  40. package/dist/hooks/useValidateAuthenticator.d.ts +25 -0
  41. package/dist/index.es.js +8056 -7704
  42. package/dist/index.es.js.map +1 -1
  43. package/dist/index.umd.js +5 -5
  44. package/dist/index.umd.js.map +1 -1
  45. package/dist/internal/useBuildDataSource.d.ts +4 -0
  46. package/dist/preview/PropertyPreview.d.ts +1 -1
  47. package/dist/preview/PropertyPreviewProps.d.ts +1 -4
  48. package/dist/preview/components/BooleanPreview.d.ts +5 -1
  49. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  50. package/dist/preview/components/ReferencePreview.d.ts +1 -7
  51. package/dist/types/analytics.d.ts +1 -1
  52. package/dist/types/auth.d.ts +37 -1
  53. package/dist/types/collections.d.ts +17 -4
  54. package/dist/types/datasource.d.ts +1 -1
  55. package/dist/types/entities.d.ts +1 -0
  56. package/dist/types/entity_callbacks.d.ts +2 -2
  57. package/dist/types/entity_overrides.d.ts +6 -0
  58. package/dist/types/index.d.ts +2 -0
  59. package/dist/types/navigation.d.ts +14 -13
  60. package/dist/types/permissions.d.ts +5 -1
  61. package/dist/types/plugins.d.ts +17 -19
  62. package/dist/types/properties.d.ts +2 -2
  63. package/dist/types/property_config.d.ts +2 -2
  64. package/dist/types/roles.d.ts +31 -0
  65. package/dist/types/storage.d.ts +11 -3
  66. package/dist/types/user.d.ts +5 -0
  67. package/dist/util/collections.d.ts +9 -1
  68. package/dist/util/icons.d.ts +8 -2
  69. package/dist/util/permissions.d.ts +4 -4
  70. package/dist/util/references.d.ts +4 -2
  71. package/dist/util/resolutions.d.ts +1 -1
  72. package/dist/util/useTraceUpdate.d.ts +1 -0
  73. package/package.json +24 -24
  74. package/src/components/DeleteEntityDialog.tsx +4 -4
  75. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +2 -2
  76. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +273 -277
  77. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +1 -1
  78. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +13 -13
  79. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +10 -17
  80. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +3 -3
  81. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +1 -1
  82. package/src/components/EntityCollectionTable/internal/default_entity_actions.tsx +9 -5
  83. package/src/components/EntityCollectionView/EntityCollectionView.tsx +28 -49
  84. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -6
  85. package/src/components/EntityCollectionView/useSelectionController.tsx +30 -0
  86. package/src/components/EntityPreview.tsx +207 -70
  87. package/src/components/EntityView.tsx +84 -0
  88. package/src/components/FieldCaption.tsx +14 -0
  89. package/src/components/FireCMSAppBar.tsx +8 -0
  90. package/src/components/HomePage/DefaultHomePage.tsx +14 -10
  91. package/src/components/HomePage/NavigationCard.tsx +69 -0
  92. package/src/components/HomePage/NavigationCardBinding.tsx +116 -0
  93. package/src/components/HomePage/SmallNavigationCard.tsx +45 -0
  94. package/src/components/HomePage/index.tsx +3 -1
  95. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -4
  96. package/src/components/ReferenceWidget.tsx +8 -8
  97. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +1 -1
  98. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +11 -19
  99. package/src/components/VirtualTable/VirtualTableProps.tsx +1 -1
  100. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
  101. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +1 -1
  102. package/src/components/index.tsx +4 -3
  103. package/src/contexts/AuthControllerContext.tsx +1 -1
  104. package/src/core/Drawer.tsx +66 -39
  105. package/src/{internal/EntityView.tsx → core/EntityEditView.tsx} +22 -39
  106. package/src/core/EntitySidePanel.tsx +2 -2
  107. package/src/core/FireCMS.tsx +18 -2
  108. package/src/core/NavigationRoutes.tsx +8 -0
  109. package/src/core/SideEntityView.tsx +38 -0
  110. package/src/core/index.tsx +0 -2
  111. package/src/form/EntityForm.tsx +20 -12
  112. package/src/form/components/StorageItemPreview.tsx +5 -3
  113. package/src/form/components/StorageUploadProgress.tsx +6 -5
  114. package/src/form/components/index.tsx +1 -0
  115. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +2 -3
  116. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +12 -15
  117. package/src/form/field_bindings/BlockFieldBinding.tsx +2 -3
  118. package/src/form/field_bindings/DateTimeFieldBinding.tsx +4 -4
  119. package/src/form/field_bindings/KeyValueFieldBinding.tsx +18 -18
  120. package/src/form/field_bindings/MapFieldBinding.tsx +17 -17
  121. package/src/form/field_bindings/MarkdownFieldBinding.tsx +1 -2
  122. package/src/form/field_bindings/MultiSelectBinding.tsx +2 -3
  123. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +3 -3
  124. package/src/form/field_bindings/ReferenceFieldBinding.tsx +6 -4
  125. package/src/form/field_bindings/RepeatFieldBinding.tsx +3 -3
  126. package/src/form/field_bindings/SelectFieldBinding.tsx +2 -3
  127. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +15 -6
  128. package/src/form/field_bindings/SwitchFieldBinding.tsx +2 -3
  129. package/src/form/field_bindings/TextFieldBinding.tsx +10 -9
  130. package/src/form/index.tsx +1 -0
  131. package/src/form/validation.ts +3 -4
  132. package/src/hooks/data/delete.ts +3 -3
  133. package/src/hooks/data/save.ts +1 -1
  134. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  135. package/src/hooks/data/useDataSource.tsx +8 -3
  136. package/src/hooks/data/useEntityFetch.tsx +4 -4
  137. package/src/hooks/index.tsx +5 -1
  138. package/src/{core → hooks}/useBuildModeController.tsx +1 -1
  139. package/src/hooks/useBuildNavigationController.tsx +133 -72
  140. package/src/hooks/useProjectLog.tsx +16 -6
  141. package/src/hooks/useReferenceDialog.tsx +2 -2
  142. package/src/hooks/useStorageSource.tsx +7 -2
  143. package/src/hooks/useValidateAuthenticator.tsx +135 -0
  144. package/src/internal/useBuildDataSource.ts +7 -2
  145. package/src/internal/useBuildSideEntityController.tsx +3 -0
  146. package/src/preview/PropertyPreview.tsx +2 -2
  147. package/src/preview/PropertyPreviewProps.tsx +1 -11
  148. package/src/preview/components/BooleanPreview.tsx +19 -4
  149. package/src/preview/components/EnumValuesChip.tsx +1 -1
  150. package/src/preview/components/ReferencePreview.tsx +56 -148
  151. package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
  152. package/src/types/analytics.ts +1 -0
  153. package/src/types/auth.tsx +50 -1
  154. package/src/types/collections.ts +19 -4
  155. package/src/types/datasource.ts +1 -1
  156. package/src/types/entities.ts +4 -0
  157. package/src/types/entity_actions.tsx +4 -0
  158. package/src/types/entity_callbacks.ts +2 -2
  159. package/src/types/entity_overrides.tsx +7 -0
  160. package/src/types/firecms.tsx +0 -1
  161. package/src/types/index.ts +2 -0
  162. package/src/types/navigation.ts +17 -16
  163. package/src/types/permissions.ts +6 -1
  164. package/src/types/plugins.tsx +24 -27
  165. package/src/types/properties.ts +3 -2
  166. package/src/types/property_config.tsx +2 -2
  167. package/src/types/roles.ts +41 -0
  168. package/src/types/side_entity_controller.tsx +1 -0
  169. package/src/types/storage.ts +12 -3
  170. package/src/types/user.ts +7 -0
  171. package/src/util/collections.ts +22 -0
  172. package/src/util/icons.tsx +11 -3
  173. package/src/util/permissions.ts +11 -8
  174. package/src/util/references.ts +36 -5
  175. package/src/util/useTraceUpdate.tsx +2 -1
  176. package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
  177. /package/dist/{components → form/components}/LabelWithIcon.d.ts +0 -0
  178. /package/dist/{core → hooks}/useBuildLocalConfigurationPersistence.d.ts +0 -0
  179. /package/src/{components → form/components}/LabelWithIcon.tsx +0 -0
  180. /package/src/{core → hooks}/useBuildLocalConfigurationPersistence.tsx +0 -0
@@ -8,7 +8,7 @@ export type PreviewSize = "medium" | "small" | "tiny";
8
8
  /**
9
9
  * @group Preview components
10
10
  */
11
- export interface PropertyPreviewProps<T extends CMSType = any, CustomProps = any, M extends Record<string, any> = Record<string, any>> {
11
+ export interface PropertyPreviewProps<T extends CMSType = any, CustomProps = any> {
12
12
  /**
13
13
  * Name of the property
14
14
  */
@@ -24,11 +24,6 @@ export interface PropertyPreviewProps<T extends CMSType = any, CustomProps = any
24
24
  */
25
25
  property: Property<T> | ResolvedProperty<T>;
26
26
 
27
- /**
28
- * Click handler
29
- */
30
- // onClick?: () => void;
31
-
32
27
  /**
33
28
  * Desired size of the preview, depending on the context.
34
29
  */
@@ -51,9 +46,4 @@ export interface PropertyPreviewProps<T extends CMSType = any, CustomProps = any
51
46
  */
52
47
  customProps?: CustomProps;
53
48
 
54
- /**
55
- * Entity this property refers to
56
- */
57
- // entity?: Entity<M>;
58
-
59
49
  }
@@ -1,11 +1,26 @@
1
1
  import React from "react";
2
- import { Checkbox } from "@firecms/ui";
2
+ import { Checkbox, cn } from "@firecms/ui";
3
+ import { PreviewSize } from "../PropertyPreviewProps";
4
+ import { Property } from "../../types";
3
5
 
4
6
  /**
5
7
  * @group Preview components
6
8
  */
7
- export function BooleanPreview({ value }: {
8
- value: boolean
9
+ export function BooleanPreview({
10
+ value,
11
+ size,
12
+ property
13
+ }: {
14
+ value: boolean,
15
+ size: PreviewSize,
16
+ property: Property,
9
17
  }): React.ReactElement {
10
- return <Checkbox checked={value} color={"secondary"}/>;
18
+ return <div className={"flex flex-row gap-2 items-center"}>
19
+ <Checkbox checked={value}
20
+ padding={false}
21
+ size={size}
22
+ color={"secondary"}/>
23
+ {property.name && <span
24
+ className={cn("text-text-secondary dark:text-text-secondary-dark", size === "tiny" ? "text-sm" : "")}>{property.name}</span>}
25
+ </div>;
11
26
  }
@@ -6,7 +6,7 @@ import { Chip } from "@firecms/ui";
6
6
  export interface EnumValuesChipProps {
7
7
  enumValues?: EnumValues;
8
8
  enumKey: string | number;
9
- size: "small" | "medium";
9
+ size: "tiny" | "small" | "medium";
10
10
  className?: string;
11
11
  children?: React.ReactNode;
12
12
  }
@@ -1,21 +1,17 @@
1
1
  import * as React from "react";
2
- import { useMemo } from "react";
3
2
 
4
- import { Entity, EntityCollection, EntityReference, ResolvedProperty } from "../../types";
5
-
6
- import { getReferencePreviewKeys, getValueInPath, resolveCollection } from "../../util";
3
+ import { Entity, EntityCollection, EntityReference } from "../../types";
7
4
  import {
8
5
  useCustomizationController,
9
6
  useEntityFetch,
10
7
  useNavigationController,
11
8
  useSideEntityController
12
9
  } from "../../hooks";
13
- import { PropertyPreview } from "../PropertyPreview";
14
10
  import { PreviewSize } from "../PropertyPreviewProps";
15
- import { SkeletonPropertyComponent } from "../property_previews/SkeletonPropertyComponent";
16
- import { cn, IconButton, KeyboardTabIcon, Skeleton, Tooltip, Typography } from "@firecms/ui";
11
+ import { IconButton, KeyboardTabIcon, Skeleton, Tooltip } from "@firecms/ui";
17
12
  import { ErrorView } from "../../components";
18
13
  import { useAnalyticsController } from "../../hooks/useAnalyticsController";
14
+ import { EntityPreview, EntityPreviewContainer } from "../../components/EntityPreview";
19
15
 
20
16
  export type ReferencePreviewProps = {
21
17
  disabled?: boolean;
@@ -23,7 +19,7 @@ export type ReferencePreviewProps = {
23
19
  size: PreviewSize;
24
20
  previewProperties?: string[];
25
21
  onClick?: (e: React.SyntheticEvent) => void;
26
- onHover?: boolean;
22
+ hover?: boolean;
27
23
  allowEntityNavigation?: boolean;
28
24
  };
29
25
 
@@ -32,14 +28,14 @@ export type ReferencePreviewProps = {
32
28
  */
33
29
  export const ReferencePreview = React.memo<ReferencePreviewProps>(function ReferencePreview(props: ReferencePreviewProps) {
34
30
  const reference = props.reference;
35
- if (!((reference as unknown) instanceof EntityReference)) {
31
+ if (!(typeof reference === "object" && "isEntityReference" in reference && reference.isEntityReference())) {
36
32
  console.warn("Reference preview received value of type", typeof reference);
37
- return <ReferencePreviewContainer
33
+ return <EntityPreviewContainer
38
34
  onClick={props.onClick}
39
35
  size={props.size}>
40
36
  <ErrorView error={"Unexpected value. Click to edit"}
41
37
  tooltip={JSON.stringify(reference)}/>
42
- </ReferencePreviewContainer>;
38
+ </EntityPreviewContainer>;
43
39
  }
44
40
  return <ReferencePreviewInternal {...props} />;
45
41
  }, areEqual) as React.FunctionComponent<ReferencePreviewProps>;
@@ -47,7 +43,7 @@ export const ReferencePreview = React.memo<ReferencePreviewProps>(function Refer
47
43
  function areEqual(prevProps: ReferencePreviewProps, nextProps: ReferencePreviewProps) {
48
44
  return prevProps.disabled === nextProps.disabled &&
49
45
  prevProps.size === nextProps.size &&
50
- prevProps.onHover === nextProps.onHover &&
46
+ prevProps.hover === nextProps.hover &&
51
47
  prevProps.reference?.id === nextProps.reference?.id &&
52
48
  prevProps.reference?.path === nextProps.reference?.path &&
53
49
  prevProps.allowEntityNavigation === nextProps.allowEntityNavigation
@@ -59,7 +55,7 @@ function ReferencePreviewInternal<M extends Record<string, any>>({
59
55
  reference,
60
56
  previewProperties,
61
57
  size,
62
- onHover,
58
+ hover,
63
59
  onClick,
64
60
  allowEntityNavigation = true
65
61
  }: ReferencePreviewProps) {
@@ -68,7 +64,7 @@ function ReferencePreviewInternal<M extends Record<string, any>>({
68
64
 
69
65
  const navigationController = useNavigationController();
70
66
 
71
- const collection = navigationController.getCollection<EntityCollection<M>>(reference.path);
67
+ const collection = navigationController.getCollection(reference.path);
72
68
  if (!collection) {
73
69
  if (customizationController.components?.missingReference) {
74
70
  return <customizationController.components.missingReference path={reference.path}/>;
@@ -85,18 +81,22 @@ function ReferencePreviewInternal<M extends Record<string, any>>({
85
81
  disabled={disabled}
86
82
  allowEntityNavigation={allowEntityNavigation}
87
83
  onClick={onClick}
88
- onHover={onHover}/>
84
+ hover={hover}/>
89
85
  }
90
86
 
91
- function ReferencePreviewExisting<M extends Record<string, any> = any>({ reference, collection, previewProperties, size, disabled, allowEntityNavigation, onClick, onHover }: ReferencePreviewProps & {
87
+ function ReferencePreviewExisting<M extends Record<string, any> = any>({
88
+ reference,
89
+ collection,
90
+ previewProperties,
91
+ size,
92
+ disabled,
93
+ allowEntityNavigation,
94
+ onClick,
95
+ hover
96
+ }: ReferencePreviewProps & {
92
97
  collection: EntityCollection<M>
93
98
  }) {
94
99
 
95
- const customizationController = useCustomizationController();
96
-
97
- const analyticsController = useAnalyticsController();
98
- const sideEntityController = useSideEntityController();
99
-
100
100
  const {
101
101
  entity,
102
102
  dataLoading,
@@ -114,145 +114,53 @@ function ReferencePreviewExisting<M extends Record<string, any> = any>({ referen
114
114
 
115
115
  const usedEntity = entity ?? referencesCache.get(reference.pathWithId);
116
116
 
117
- const resolvedCollection = useMemo(() => resolveCollection({
118
- collection,
119
- path: reference.path,
120
- values: usedEntity?.values,
121
- fields: customizationController.propertyConfigs
122
- }), [collection]);
123
-
124
- const listProperties = useMemo(() => getReferencePreviewKeys(resolvedCollection, customizationController.propertyConfigs, previewProperties, size === "small" || size === "medium" ? 3 : 1),
125
- [previewProperties, resolvedCollection, size]);
126
-
127
117
  let body: React.ReactNode;
128
118
 
129
- if (!resolvedCollection) {
130
- return <ErrorView
131
- error={"Could not find collection with id " + resolvedCollection}/>
132
- }
133
-
134
119
  if (!reference) {
135
120
  body = <ErrorView error={"Reference not set"}/>;
136
121
  } else if (usedEntity && !usedEntity.values) {
137
122
  body = <ErrorView error={"Reference does not exist"}
138
123
  tooltip={reference.path}/>;
139
- } else {
140
- body = (
141
- <>
142
- <div
143
- className="flex flex-col flex-grow w-full max-w-[calc(100%-52px)] m-1">
144
-
145
- {size !== "tiny" && (
146
- reference
147
- ? <div className={`${
148
- size !== "medium"
149
- ? "block whitespace-nowrap overflow-hidden truncate"
150
- : ""
151
- }`}>
152
- <Typography variant={"caption"}
153
- className={"font-mono"}>
154
- {reference.id}
155
- </Typography>
156
- </div>
157
- : <Skeleton/>)}
158
-
159
- {listProperties && listProperties.map((key) => {
160
- const childProperty = resolvedCollection.properties[key as string];
161
- if (!childProperty) return null;
162
-
163
- return (
164
- <div key={"ref_prev_" + (key as string)}
165
- className={listProperties.length > 1 ? "my-0.5" : "my-0"}>
166
- {
167
- usedEntity
168
- ? <PropertyPreview
169
- propertyKey={key as string}
170
- value={getValueInPath(usedEntity.values, key)}
171
- property={childProperty as ResolvedProperty}
172
- // entity={usedEntity}
173
- size={"tiny"}/>
174
- : <SkeletonPropertyComponent
175
- property={childProperty as ResolvedProperty}
176
- size={"tiny"}/>
177
- }
178
- </div>
179
- );
180
- })}
181
-
182
- </div>
183
- <div className={`my-${size === "tiny" ? 2 : 4}`}>
184
- {!disabled && usedEntity && allowEntityNavigation &&
185
- <Tooltip title={`See details for ${usedEntity.id}`}>
186
- <IconButton
187
- color={"inherit"}
188
- size={"small"}
189
- onClick={(e) => {
190
- e.stopPropagation();
191
- analyticsController.onAnalyticsEvent?.("entity_click_from_reference", {
192
- path: usedEntity.path,
193
- entityId: usedEntity.id
194
- });
195
- sideEntityController.open({
196
- entityId: usedEntity.id,
197
- path: usedEntity.path,
198
- collection: resolvedCollection,
199
- updateUrl: true
200
- });
201
- }}>
202
- <KeyboardTabIcon size={"small"}/>
203
- </IconButton>
204
- </Tooltip>}
205
- </div>
206
- </>
124
+ }
125
+ if (body) {
126
+
127
+ return (
128
+ <EntityPreviewContainer onClick={disabled ? undefined : onClick}
129
+ hover={disabled ? undefined : hover}
130
+ size={size}>
131
+ {body}
132
+ </EntityPreviewContainer>
207
133
  );
208
134
  }
209
135
 
210
- return (
211
- <ReferencePreviewContainer onClick={disabled ? undefined : onClick}
212
- onHover={disabled ? undefined : onHover}
213
- size={size}>
214
- {body}
215
- </ReferencePreviewContainer>
216
- );
217
- }
218
-
219
- export function ReferencePreviewContainer({
220
- children,
221
- onHover,
222
- size,
223
- onClick
224
- }: {
225
- children: React.ReactNode;
226
- onHover?: boolean;
227
- size: PreviewSize;
228
- onClick?: (e: React.SyntheticEvent) => void;
229
- }) {
230
- return <Typography variant={"label"}
231
- className={cn("bg-opacity-70 bg-gray-100 dark:bg-gray-800 dark:bg-opacity-60",
232
- "w-full",
233
- "flex",
234
- "rounded-md",
235
- "overflow-hidden",
236
- onHover ? "hover:bg-opacity-90 dark:hover:bg-opacity-90" : "",
237
- size === "medium" ? "p-2" : "p-1",
238
- size === "tiny" ? "items-center" : "",
239
- "transition-colors duration-300 ease-in-out ",
240
- // onHover ? "shadow-outline" : "",
241
- onClick ? "cursor-pointer" : "")}
242
- style={{
243
- // @ts-ignore
244
- tabindex: 0
245
- }}
246
- onClick={(event) => {
247
- if (onClick) {
248
- event.preventDefault();
249
- onClick(event);
250
- }
251
- }}>
136
+ if (dataLoading && !usedEntity) {
137
+ return (
138
+ <EntityPreviewContainer onClick={disabled ? undefined : onClick}
139
+ hover={disabled ? undefined : hover}
140
+ size={size}>
141
+ <Skeleton/>
142
+ </EntityPreviewContainer>
143
+ );
144
+ }
252
145
 
253
- {children}
146
+ if (!usedEntity) {
147
+ return (
148
+ <EntityPreviewContainer onClick={disabled ? undefined : onClick}
149
+ hover={disabled ? undefined : hover}
150
+ size={size}>
151
+ <ErrorView error={"Entity not found"}/>
152
+ </EntityPreviewContainer>
153
+ );
154
+ }
155
+ return <EntityPreview size={size}
156
+ previewProperties={previewProperties}
157
+ disabled={disabled}
158
+ entity={usedEntity}
159
+ collection={collection}
160
+ onClick={onClick}
161
+ includeEntityNavigation={allowEntityNavigation}
162
+ hover={hover}/>;
254
163
 
255
- </Typography>
256
164
  }
257
165
 
258
166
  const referencesCache = new Map<string, Entity<any>>();
@@ -6,7 +6,7 @@ import { PreviewType } from "../../types";
6
6
  import { UrlComponentPreview } from "../components/UrlComponentPreview";
7
7
  import { PropertyPreviewProps } from "../PropertyPreviewProps";
8
8
  import { ErrorBoundary } from "../../components";
9
- import { Chip, getColorSchemeForSeed } from "@firecms/ui";
9
+ import { Chip, cn, getColorSchemeForSeed } from "@firecms/ui";
10
10
 
11
11
  /**
12
12
  * @group Preview components
@@ -24,14 +24,14 @@ export function StringPropertyPreview({
24
24
  return <EnumValuesChip
25
25
  enumKey={enumKey}
26
26
  enumValues={resolvedProperty.enumValues}
27
- size={size !== "medium" ? "small" : "medium"}/>;
27
+ size={size}/>;
28
28
  } else if (property.previewAsTag) {
29
29
  const colorScheme = getColorSchemeForSeed(propertyKey ?? "");
30
30
  return (
31
31
  <ErrorBoundary>
32
32
  <Chip
33
33
  colorScheme={colorScheme}
34
- size={size !== "medium" ? "small" : "medium"}>
34
+ size={size}>
35
35
  {value}
36
36
  </Chip>
37
37
  </ErrorBoundary>);
@@ -45,15 +45,16 @@ export function StringPropertyPreview({
45
45
  if (!value) return <></>;
46
46
  const lines = value.split("\n");
47
47
  return value && value.includes("\n")
48
- ? <div className={"overflow-x-scroll"}>
48
+ ? <div className={cn("overflow-x-scroll", size === "tiny" ? "text-sm" : "")}>
49
49
  {lines.map((str, index) =>
50
50
  <React.Fragment key={`string_preview_${index}`}>
51
51
  <span>{str}</span>
52
52
  {index !== lines.length - 1 && <br/>}
53
53
  </React.Fragment>)}
54
54
  </div>
55
- : <>
56
- {value}
57
- </>;
55
+ : (size === "tiny"
56
+ ? <span className={"text-sm"}>{value}</span>
57
+ : <>{value}</>
58
+ );
58
59
  }
59
60
  }
@@ -26,6 +26,7 @@ export type CMSAnalyticsEvent =
26
26
  | "home_navigate_to_collection"
27
27
  | "home_favorite_navigate_to_collection"
28
28
  | "home_navigate_to_view"
29
+ | "home_navigate_to_admin_view"
29
30
  | "home_favorite_navigate_to_view"
30
31
 
31
32
  | "collection_inline_editing"
@@ -1,4 +1,7 @@
1
1
  import { User } from "./user";
2
+ import { Role } from "./roles";
3
+ import { DataSourceDelegate } from "./datasource";
4
+ import { StorageSource } from "./storage";
2
5
 
3
6
  /**
4
7
  * Controller for retrieving the logged user or performing auth related operations.
@@ -6,7 +9,7 @@ import { User } from "./user";
6
9
  * to do it as the result of a hook.
7
10
  * @group Hooks and utilities
8
11
  */
9
- export type AuthController<UserType extends User = User> = {
12
+ export type AuthController<UserType extends User = any, ExtraData extends any = any> = {
10
13
 
11
14
  /**
12
15
  * The user currently logged in
@@ -14,6 +17,11 @@ export type AuthController<UserType extends User = User> = {
14
17
  */
15
18
  user: UserType | null;
16
19
 
20
+ /**
21
+ * Roles related to the logged user
22
+ */
23
+ roles?: Role[];
24
+
17
25
  /**
18
26
  * Initial loading flag. It is used not to display the login screen
19
27
  * when the app first loads, and it has not been checked whether the user
@@ -21,6 +29,12 @@ export type AuthController<UserType extends User = User> = {
21
29
  */
22
30
  initialLoading?: boolean;
23
31
 
32
+ /**
33
+ * Loading flag. It is used to display a loading screen when the user is
34
+ * logging in or out.
35
+ */
36
+ authLoading: boolean;
37
+
24
38
  /**
25
39
  * Sign out
26
40
  */
@@ -46,4 +60,39 @@ export type AuthController<UserType extends User = User> = {
46
60
  */
47
61
  loginSkipped: boolean;
48
62
 
63
+ extra: ExtraData;
64
+
65
+ setExtra: (extra: ExtraData) => void;
66
+
67
+ // setUser?: (user: UserType | null) => void;
68
+
69
+ // setRoles?: (roles: Role[]) => void;
49
70
  };
71
+
72
+ /**
73
+ * Implement this function to allow access to specific users.
74
+ * @group Hooks and utilities
75
+ */
76
+ export type Authenticator<UserType extends User = User, Controller extends AuthController<UserType> = AuthController<UserType>> = (props: {
77
+
78
+ /**
79
+ * Logged-in user or null
80
+ */
81
+ user: UserType | null;
82
+
83
+ /**
84
+ * AuthController
85
+ */
86
+ authController: Controller;
87
+
88
+ /**
89
+ * Connector to your database, e.g. your Firestore database
90
+ */
91
+ dataSourceDelegate: DataSourceDelegate;
92
+
93
+ /**
94
+ * Used storage implementation
95
+ */
96
+ storageSource: StorageSource;
97
+
98
+ }) => boolean | Promise<boolean>;
@@ -8,6 +8,7 @@ import { EnumValues, PropertiesOrBuilders } from "./properties";
8
8
  import { FormContext } from "./fields";
9
9
  import { EntityAction } from "./entity_actions";
10
10
  import { ExportConfig } from "./export_import";
11
+ import { EntityOverrides } from "./entity_overrides";
11
12
 
12
13
  /**
13
14
  * This interface represents a view that includes a collection of entities.
@@ -16,7 +17,7 @@ import { ExportConfig } from "./export_import";
16
17
  *
17
18
  * @group Models
18
19
  */
19
- export interface EntityCollection<M extends Record<string, any> = any, UserType extends User = User> {
20
+ export interface EntityCollection<M extends Record<string, any> = any, UserType extends User = any> {
20
21
 
21
22
  /**
22
23
  * You can set an alias that will be used internally instead of the `path`.
@@ -76,6 +77,13 @@ export interface EntityCollection<M extends Record<string, any> = any, UserType
76
77
  */
77
78
  properties: PropertiesOrBuilders<M>;
78
79
 
80
+ /**
81
+ * Title property of the entity. This is the property that will be used
82
+ * as the title in entity related views and references.
83
+ * If not specified, the first property simple text property will be used.
84
+ */
85
+ titleProperty?: keyof M,
86
+
79
87
  /**
80
88
  * Can this collection be edited by the end user.
81
89
  * Defaults to `true`.
@@ -139,7 +147,7 @@ export interface EntityCollection<M extends Record<string, any> = any, UserType
139
147
  * is being created, updated or deleted.
140
148
  * Useful for adding your own logic or blocking the execution of the operation.
141
149
  */
142
- callbacks?: EntityCallbacks<M>;
150
+ callbacks?: EntityCallbacks<M, UserType>;
143
151
 
144
152
  /**
145
153
  * Builder for rendering additional components such as buttons in the
@@ -276,6 +284,13 @@ export interface EntityCollection<M extends Record<string, any> = any, UserType
276
284
  *
277
285
  */
278
286
  exportable?: boolean | ExportConfig<UserType>;
287
+
288
+ /**
289
+ * User id of the owner of this collection. This is used only by plugins, or if you
290
+ * are writing custom code
291
+ */
292
+ ownerId?: string;
293
+ overrides?: EntityOverrides;
279
294
  }
280
295
 
281
296
  /**
@@ -346,7 +361,7 @@ export type SelectionController<M extends Record<string, any> = any> = {
346
361
 
347
362
  /**
348
363
  * Filter conditions in a `Query.where()` clause are specified using the
349
- * strings '<', '<=', '==', '>=', '>', 'array-contains', 'in', and 'array-contains-any'.
364
+ * strings `<`, `<=`, `==`, `>=`, `>`, `array-contains`, `in`, and `array-contains-any`.
350
365
  * @group Models
351
366
  */
352
367
  export type WhereFilterOp =
@@ -436,7 +451,7 @@ export interface AdditionalFieldDelegate<M extends Record<string, any> = any,
436
451
  * view.
437
452
  * @param entity
438
453
  */
439
- value?: (props: { entity: Entity<M>, context: FireCMSContext }) => string | number | Promise<string | number> | undefined;
454
+ value?: (props: { entity: Entity<M>, context: FireCMSContext<any> }) => string | number | Promise<string | number> | undefined;
440
455
  }
441
456
 
442
457
  /**
@@ -8,7 +8,7 @@ import { ResolvedEntityCollection } from "./resolved_entities";
8
8
  export interface FetchEntityProps<M extends Record<string, any> = any> {
9
9
  path: string;
10
10
  entityId: string;
11
- collection?: EntityCollection<M>
11
+ collection?: EntityCollection<M, any>
12
12
  }
13
13
 
14
14
  /**
@@ -56,6 +56,10 @@ export class EntityReference<M extends Record<string, any> = any> {
56
56
  get pathWithId() {
57
57
  return `${this.path}/${this.id}`;
58
58
  }
59
+
60
+ isEntityReference() {
61
+ return true;
62
+ }
59
63
  }
60
64
 
61
65
  export class GeoPoint {
@@ -4,6 +4,7 @@ import { Entity } from "./entities";
4
4
  import { EntityCollection, SelectionController } from "./collections";
5
5
  import { User } from "./user";
6
6
  import { SideEntityController } from "./side_entity_controller";
7
+ import { EntityOverrides } from "./entity_overrides";
7
8
 
8
9
  export type EntityAction<M extends object = any, UserType extends User = User> = {
9
10
  name: string;
@@ -21,8 +22,11 @@ export type EntityAction<M extends object = any, UserType extends User = User> =
21
22
  * Show this action in the form, defaults to true
22
23
  */
23
24
  includeInForm?: boolean;
25
+
24
26
  }
25
27
 
28
+
29
+
26
30
  export type EntityActionClickProps<M extends object, UserType extends User = User> = {
27
31
  entity: Entity<M>;
28
32
  context: FireCMSContext<UserType>;
@@ -78,7 +78,7 @@ export interface EntityOnFetchProps<M extends Record<string, any> = any, UserTyp
78
78
  /**
79
79
  * Collection of the entity
80
80
  */
81
- collection: EntityCollection<M>;
81
+ collection: EntityCollection<M, UserType>;
82
82
 
83
83
  /**
84
84
  * Full path of the CMS where this collection is being fetched.
@@ -193,7 +193,7 @@ export interface EntityOnDeleteProps<M extends Record<string, any> = any, UserTy
193
193
  /**
194
194
  * Context of the app status
195
195
  */
196
- context: FireCMSContext;
196
+ context: FireCMSContext<UserType>;
197
197
  }
198
198
 
199
199
  /**
@@ -0,0 +1,7 @@
1
+ import { DataSource } from "./datasource";
2
+ import { StorageSource } from "./storage";
3
+
4
+ export type EntityOverrides = {
5
+ dataSource?: DataSource;
6
+ storageSource?: StorageSource;
7
+ };
@@ -67,7 +67,6 @@ export type FireCMSProps<UserType extends User, EC extends EntityCollection> = {
67
67
  loading: boolean;
68
68
  }) => React.ReactNode;
69
69
 
70
-
71
70
  /**
72
71
  * Record of custom form fields to be used in the CMS.
73
72
  * You can use the key to reference the custom field in
@@ -17,10 +17,12 @@ export * from "./side_entity_controller";
17
17
  export * from "./side_dialogs_controller";
18
18
  export * from "./firecms_context";
19
19
  export * from "./entity_callbacks";
20
+ export * from "./entity_overrides";
20
21
  export * from "./local_config_persistence";
21
22
  export * from "./plugins";
22
23
  export * from "./analytics";
23
24
  export * from "./firecms";
25
+ export * from "./roles";
24
26
  export * from "./appcheck";
25
27
  export * from "./export_import";
26
28
  export * from "./modify_collections";