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

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 (178) hide show
  1. package/README.md +1 -1
  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 +5 -2
  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 +8055 -7703
  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/ReferenceFilterField.tsx +11 -19
  98. package/src/components/VirtualTable/VirtualTableProps.tsx +1 -1
  99. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +1 -1
  100. package/src/components/index.tsx +4 -3
  101. package/src/contexts/AuthControllerContext.tsx +1 -1
  102. package/src/core/Drawer.tsx +66 -39
  103. package/src/{internal/EntityView.tsx → core/EntityEditView.tsx} +22 -39
  104. package/src/core/EntitySidePanel.tsx +2 -2
  105. package/src/core/FireCMS.tsx +18 -2
  106. package/src/core/NavigationRoutes.tsx +8 -0
  107. package/src/core/SideEntityView.tsx +38 -0
  108. package/src/core/index.tsx +0 -2
  109. package/src/form/EntityForm.tsx +20 -12
  110. package/src/form/components/StorageItemPreview.tsx +5 -3
  111. package/src/form/components/StorageUploadProgress.tsx +6 -5
  112. package/src/form/components/index.tsx +1 -0
  113. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +2 -3
  114. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +12 -15
  115. package/src/form/field_bindings/BlockFieldBinding.tsx +2 -3
  116. package/src/form/field_bindings/DateTimeFieldBinding.tsx +3 -3
  117. package/src/form/field_bindings/KeyValueFieldBinding.tsx +18 -18
  118. package/src/form/field_bindings/MapFieldBinding.tsx +17 -17
  119. package/src/form/field_bindings/MarkdownFieldBinding.tsx +1 -2
  120. package/src/form/field_bindings/MultiSelectBinding.tsx +2 -3
  121. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +3 -3
  122. package/src/form/field_bindings/ReferenceFieldBinding.tsx +6 -4
  123. package/src/form/field_bindings/RepeatFieldBinding.tsx +3 -3
  124. package/src/form/field_bindings/SelectFieldBinding.tsx +2 -3
  125. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +15 -6
  126. package/src/form/field_bindings/SwitchFieldBinding.tsx +2 -3
  127. package/src/form/field_bindings/TextFieldBinding.tsx +10 -9
  128. package/src/form/index.tsx +1 -0
  129. package/src/form/validation.ts +3 -4
  130. package/src/hooks/data/delete.ts +3 -3
  131. package/src/hooks/data/save.ts +1 -1
  132. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  133. package/src/hooks/data/useDataSource.tsx +8 -3
  134. package/src/hooks/data/useEntityFetch.tsx +4 -4
  135. package/src/hooks/index.tsx +5 -1
  136. package/src/{core → hooks}/useBuildModeController.tsx +1 -1
  137. package/src/hooks/useBuildNavigationController.tsx +132 -70
  138. package/src/hooks/useProjectLog.tsx +16 -6
  139. package/src/hooks/useReferenceDialog.tsx +2 -2
  140. package/src/hooks/useStorageSource.tsx +7 -2
  141. package/src/hooks/useValidateAuthenticator.tsx +135 -0
  142. package/src/internal/useBuildDataSource.ts +7 -2
  143. package/src/internal/useBuildSideEntityController.tsx +3 -0
  144. package/src/preview/PropertyPreview.tsx +2 -2
  145. package/src/preview/PropertyPreviewProps.tsx +1 -11
  146. package/src/preview/components/BooleanPreview.tsx +19 -4
  147. package/src/preview/components/EnumValuesChip.tsx +1 -1
  148. package/src/preview/components/ReferencePreview.tsx +56 -148
  149. package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
  150. package/src/types/analytics.ts +1 -0
  151. package/src/types/auth.tsx +50 -1
  152. package/src/types/collections.ts +19 -4
  153. package/src/types/datasource.ts +1 -1
  154. package/src/types/entities.ts +4 -0
  155. package/src/types/entity_actions.tsx +4 -0
  156. package/src/types/entity_callbacks.ts +2 -2
  157. package/src/types/entity_overrides.tsx +7 -0
  158. package/src/types/firecms.tsx +0 -1
  159. package/src/types/index.ts +2 -0
  160. package/src/types/navigation.ts +17 -16
  161. package/src/types/permissions.ts +6 -1
  162. package/src/types/plugins.tsx +24 -27
  163. package/src/types/properties.ts +3 -2
  164. package/src/types/property_config.tsx +2 -2
  165. package/src/types/roles.ts +41 -0
  166. package/src/types/side_entity_controller.tsx +1 -0
  167. package/src/types/storage.ts +12 -3
  168. package/src/types/user.ts +7 -0
  169. package/src/util/collections.ts +22 -0
  170. package/src/util/icons.tsx +11 -3
  171. package/src/util/permissions.ts +11 -8
  172. package/src/util/references.ts +36 -5
  173. package/src/util/useTraceUpdate.tsx +2 -1
  174. package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
  175. /package/dist/{components → form/components}/LabelWithIcon.d.ts +0 -0
  176. /package/dist/{core → hooks}/useBuildLocalConfigurationPersistence.d.ts +0 -0
  177. /package/src/{components → form/components}/LabelWithIcon.tsx +0 -0
  178. /package/src/{core → hooks}/useBuildLocalConfigurationPersistence.tsx +0 -0
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  import { EntityCollection } from "./collections";
2
3
  import { EntityReference } from "./entities";
3
4
 
@@ -6,7 +7,7 @@ import { EntityReference } from "./entities";
6
7
  * attributes.
7
8
  * @group Models
8
9
  */
9
- export type NavigationController = {
10
+ export type NavigationController<EC extends EntityCollection = EntityCollection<any>> = {
10
11
 
11
12
  /**
12
13
  * List of the mapped collections in the CMS.
@@ -22,6 +23,12 @@ export type NavigationController = {
22
23
  */
23
24
  views?: CMSView[];
24
25
 
26
+ /**
27
+ * Custom additional views created by the developer, added to the admin
28
+ * navigation
29
+ */
30
+ adminViews?: CMSView[];
31
+
25
32
  /**
26
33
  * Configuration for the views that should be displayed at the top
27
34
  * level of the navigation (e.g. in the home page or the navigation
@@ -49,18 +56,18 @@ export type NavigationController = {
49
56
  * Get the collection configuration for a given path.
50
57
  * The collection is resolved from the given path or alias.
51
58
  */
52
- getCollection: <EC extends EntityCollection = EntityCollection<any>>(pathOrAlias: string,
53
- entityId?: string,
54
- includeUserOverride?: boolean) => EC | undefined;
59
+ getCollection: (pathOrAlias: string,
60
+ entityId?: string,
61
+ includeUserOverride?: boolean) => EC | undefined;
55
62
  /**
56
63
  * Get the collection configuration from its parent path segments.
57
64
  */
58
- getCollectionFromIds: <EC extends EntityCollection = EntityCollection<any>>(ids: string[]) => EC | undefined;
65
+ getCollectionFromIds: (ids: string[]) => EC | undefined;
59
66
 
60
67
  /**
61
68
  * Get the collection configuration from its parent path segments.
62
69
  */
63
- getCollectionFromPaths: <EC extends EntityCollection = EntityCollection<any>>(pathSegments: string[]) => EC | undefined;
70
+ getCollectionFromPaths: (pathSegments: string[]) => EC | undefined;
64
71
 
65
72
  /**
66
73
  * Default path under the navigation routes of the CMS will be created
@@ -116,13 +123,6 @@ export type NavigationController = {
116
123
  */
117
124
  resolveAliasesFrom: (pathWithAliases: string) => string;
118
125
 
119
- /**
120
- * Location used as the base for routes.
121
- * This is the location that will be used underneath, when the url changes while
122
- * opening a side dialog
123
- */
124
- baseLocation: string;
125
-
126
126
  /**
127
127
  * Call this method to recalculate the navigation
128
128
  */
@@ -192,6 +192,7 @@ export interface CMSView {
192
192
  /**
193
193
  * Optional field used to group top level navigation entries under a
194
194
  * navigation view.
195
+ * This prop is ignored for admin views.
195
196
  */
196
197
  group?: string;
197
198
 
@@ -201,11 +202,11 @@ export interface TopNavigationEntry {
201
202
  url: string;
202
203
  name: string;
203
204
  path: string;
204
- type: "collection" | "view";
205
+ type: "collection" | "view" | "admin";
205
206
  collection?: EntityCollection;
206
- view: CMSView;
207
+ view?: CMSView;
207
208
  description?: string;
208
- group?: string;
209
+ group: string;
209
210
  }
210
211
 
211
212
  export type TopNavigationResult = {
@@ -41,6 +41,11 @@ export interface PermissionsBuilderProps<EC extends EntityCollection = EntityCol
41
41
  */
42
42
  entity: Entity<M> | null;
43
43
 
44
+ /**
45
+ * Path of the collection e.g. 'products/12345/locales'
46
+ */
47
+ path: string;
48
+
44
49
  /**
45
50
  * Path segments of the collection e.g. ['products', 'locales']
46
51
  */
@@ -73,4 +78,4 @@ export type PermissionsBuilder<EC extends EntityCollection = EntityCollection, U
73
78
  user,
74
79
  collection,
75
80
  authController
76
- }: PermissionsBuilderProps<EC, UserType, M>) => Permissions);
81
+ }: PermissionsBuilderProps<EC, UserType, M>) => Permissions | undefined);
@@ -7,6 +7,7 @@ import { FieldProps, FormContext } from "./fields";
7
7
  import { CMSType, Property } from "./properties";
8
8
  import { EntityStatus } from "./entities";
9
9
  import { ResolvedProperty } from "./resolved_entities";
10
+ import { CMSView } from "./navigation";
10
11
 
11
12
  /**
12
13
  * Interface used to define plugins for FireCMS.
@@ -16,9 +17,9 @@ import { ResolvedProperty } from "./resolved_entities";
16
17
  export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollection = EntityCollection, COL_ACTIONS_PROPS = any> = {
17
18
 
18
19
  /**
19
- * Name of the plugin
20
+ * Key of the plugin. This is used to identify the plugin in the CMS.
20
21
  */
21
- name: string;
22
+ key: string;
22
23
 
23
24
  /**
24
25
  * If this flag is set to true, no content will be shown in the CMS
@@ -26,31 +27,6 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
26
27
  */
27
28
  loading?: boolean;
28
29
 
29
- collections?: {
30
-
31
- /**
32
- * Use this component to add custom actions to the entity collections
33
- * toolbar.
34
- */
35
- CollectionActions?: React.ComponentType<CollectionActionsProps<any, any, EC> & COL_ACTIONS_PROPS> | React.ComponentType<CollectionActionsProps<any, any, EC> & COL_ACTIONS_PROPS>[];
36
-
37
- collectionActionsProps?: COL_ACTIONS_PROPS;
38
-
39
- }
40
-
41
- form?: {
42
- provider?: {
43
- Component: React.ComponentType<PropsWithChildren<FORM_PROPS & PluginFormActionProps<any, EC>>>;
44
- props?: FORM_PROPS;
45
- }
46
-
47
- Actions?: React.ComponentType<PluginFormActionProps<any, EC>>;
48
-
49
- fieldBuilder?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T, any, EC>) => React.ComponentType<FieldProps<T>> | null;
50
-
51
- fieldBuilderEnabled?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T>) => boolean;
52
- }
53
-
54
30
  /**
55
31
  * You can use this prop to add higher order components to the CMS.
56
32
  * The components will be added to the root of the CMS, so any component
@@ -113,6 +89,14 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
113
89
 
114
90
  collectionView?: {
115
91
 
92
+ /**
93
+ * Use this component to add custom actions to the entity collections
94
+ * toolbar.
95
+ */
96
+ CollectionActions?: React.ComponentType<CollectionActionsProps<any, any, EC> & COL_ACTIONS_PROPS> | React.ComponentType<CollectionActionsProps<any, any, EC> & COL_ACTIONS_PROPS>[];
97
+
98
+ collectionActionsProps?: COL_ACTIONS_PROPS;
99
+
116
100
  showTextSearchBar?: (props: {
117
101
  context: FireCMSContext,
118
102
  path: string,
@@ -151,6 +135,19 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
151
135
  }>;
152
136
  }
153
137
 
138
+ form?: {
139
+ provider?: {
140
+ Component: React.ComponentType<PropsWithChildren<FORM_PROPS & PluginFormActionProps<any, EC>>>;
141
+ props?: FORM_PROPS;
142
+ }
143
+
144
+ Actions?: React.ComponentType<PluginFormActionProps<any, EC>>;
145
+
146
+ fieldBuilder?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T, any, EC>) => React.ComponentType<FieldProps<T>> | null;
147
+
148
+ fieldBuilderEnabled?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T>) => boolean;
149
+ }
150
+
154
151
  }
155
152
 
156
153
  /**
@@ -695,7 +695,7 @@ export interface ArrayPropertyValidationSchema extends PropertyValidationSchema
695
695
  * Additional configuration related to Storage related fields
696
696
  * @group Entity properties
697
697
  */
698
- export interface StorageConfig {
698
+ export type StorageConfig = {
699
699
 
700
700
  /**
701
701
  * File MIME types that can be uploaded to this reference. Don't specify for
@@ -770,7 +770,8 @@ export interface StorageConfig {
770
770
  * Postprocess the saved value (storage path or URL)
771
771
  * after it has been resolved.
772
772
  */
773
- postProcess?: (pathOrUrl: string) => Promise<string>
773
+ postProcess?: (pathOrUrl: string) => Promise<string>;
774
+
774
775
  }
775
776
 
776
777
  /**
@@ -11,7 +11,7 @@ export type PropertyConfig<T extends CMSType = any> = {
11
11
  /**
12
12
  * Key used to identify this property config.
13
13
  */
14
- key: string,
14
+ key: PropertyConfigId | string;
15
15
 
16
16
  /**
17
17
  * Name of this field type.
@@ -48,7 +48,7 @@ export type PropertyConfig<T extends CMSType = any> = {
48
48
 
49
49
  }
50
50
 
51
- export type FieldConfigId =
51
+ export type PropertyConfigId =
52
52
  "text_field" |
53
53
  "multiline" |
54
54
  "markdown" |
@@ -0,0 +1,41 @@
1
+ import { Permissions } from "../index";
2
+
3
+ export type Role = {
4
+
5
+ /**
6
+ * ID of the role
7
+ */
8
+ id: string;
9
+
10
+ /**
11
+ * Name of the role
12
+ */
13
+ name: string;
14
+
15
+ /**
16
+ * If this flag is true, the user can perform any action
17
+ */
18
+ isAdmin?: boolean;
19
+
20
+ /**
21
+ * Default permissions for all collections for this role.
22
+ * You can override this values at the collection level using
23
+ * {@link collectionPermissions}
24
+ */
25
+ defaultPermissions?: Permissions;
26
+
27
+ /**
28
+ * Record of stripped collection ids to their permissions.
29
+ * @see stripCollectionPath
30
+ */
31
+ collectionPermissions?: Record<string, Permissions>;
32
+
33
+ config?: {
34
+
35
+ createCollections?: boolean;
36
+
37
+ editCollections?: boolean | "own";
38
+
39
+ deleteCollections?: boolean | "own";
40
+ }
41
+ }
@@ -1,6 +1,7 @@
1
1
  import { EntityCollection } from "./collections";
2
2
  import { ResolvedEntityCollection } from "./resolved_entities";
3
3
  import { Entity } from "./entities";
4
+ import { EntityOverrides } from "./entity_overrides";
4
5
 
5
6
  /**
6
7
  * Props used to open a side dialog
@@ -6,6 +6,7 @@ export interface UploadFileProps {
6
6
  fileName?: string,
7
7
  path?: string,
8
8
  metadata?: any,
9
+ bucket?: string
9
10
  }
10
11
 
11
12
  /**
@@ -16,6 +17,10 @@ export interface UploadFileResult {
16
17
  * Storage path including the file name where the file was uploaded.
17
18
  */
18
19
  path: string;
20
+ /**
21
+ * Bucket where the file was uploaded
22
+ */
23
+ bucket: string;
19
24
  }
20
25
 
21
26
  /**
@@ -73,24 +78,28 @@ export interface StorageSource {
73
78
  * @param fileName
74
79
  * @param path
75
80
  * @param metadata
81
+ * @param bucket
76
82
  */
77
83
  uploadFile: ({
78
84
  file,
79
85
  fileName,
80
86
  path,
81
- metadata
87
+ metadata,
88
+ bucket
82
89
  }: UploadFileProps) => Promise<UploadFileResult>;
83
90
 
84
91
  /**
85
92
  * Convert a storage path or URL into a download configuration
86
93
  * @param path
94
+ * @param bucket
87
95
  */
88
- getDownloadURL: (pathOrUrl: string) => Promise<DownloadConfig>;
96
+ getDownloadURL: (pathOrUrl: string, bucket?: string) => Promise<DownloadConfig>;
89
97
 
90
98
  /**
91
99
  * Get a file from a storage path.
92
100
  * It returns null if the file does not exist.
93
101
  * @param props
102
+ * @param bucket
94
103
  */
95
- getFile: (path:string) => Promise<File | null>;
104
+ getFile: (path:string, bucket?: string) => Promise<File | null>;
96
105
  }
package/src/types/user.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { Role } from "./roles";
2
+
1
3
  /**
2
4
  * This interface represents a user.
3
5
  * It has some of the same fields as a Firebase User.
@@ -34,4 +36,9 @@ export type User = {
34
36
  */
35
37
  readonly isAnonymous: boolean;
36
38
 
39
+ /**
40
+ *
41
+ */
42
+ roles?: Role[];
43
+
37
44
  };
@@ -1,6 +1,8 @@
1
1
  import {
2
2
  DefaultSelectedViewBuilder,
3
3
  DefaultSelectedViewParams,
4
+ EntityCollection,
5
+ PermissionsBuilder,
4
6
  PropertiesOrBuilders,
5
7
  PropertyOrBuilder
6
8
  } from "../types";
@@ -48,3 +50,23 @@ export function resolveDefaultSelectedView(
48
50
  return defaultSelectedView(params);
49
51
  }
50
52
  }
53
+
54
+ /**
55
+ * If a collection is not applying permissions, we apply the given permissionsBuilder.
56
+ * This is used to apply the role permissions to the collections, unless they are already
57
+ * applying permissions.
58
+ * @param collections
59
+ * @param permissionsBuilder
60
+ */
61
+ export const applyPermissionsFunctionIfEmpty = (collections: EntityCollection[], permissionsBuilder?: PermissionsBuilder<any, any>): EntityCollection[] => {
62
+
63
+ return collections.map(collection => {
64
+ if (collection.permissions) {
65
+ return collection;
66
+ }
67
+ return ({
68
+ ...collection,
69
+ permissions: permissionsBuilder
70
+ });
71
+ });
72
+ }
@@ -1,5 +1,4 @@
1
1
  import React from "react";
2
- import { CMSView, EntityCollection } from "../types";
3
2
  import { hashString } from "./hash";
4
3
  import { coolIconKeys, Icon, iconKeys } from "@firecms/ui";
5
4
  import { slugify } from "./strings";
@@ -14,8 +13,17 @@ export function getIcon(iconKey?: string, className?: string): React.ReactElemen
14
13
  return iconKey in iconKeysMap ? <Icon iconKey={iconKey} size={"medium"} className={className}/> : undefined;
15
14
  }
16
15
 
16
+ export type IconViewProps = {
17
+ path: string;
18
+ name: string;
19
+ singularName?: string;
20
+ group?: string;
21
+ icon?: string;
22
+ }
23
+
17
24
  export const IconForView = React.memo(
18
- function IconForView({ collectionOrView, className }: { collectionOrView: EntityCollection | CMSView, className?: string }): React.ReactElement {
25
+ function IconForView({ collectionOrView, className }: { collectionOrView?: IconViewProps, className?: string }): React.ReactElement {
26
+ if (!collectionOrView) return <></>;
19
27
  const icon = getIcon(collectionOrView.icon, className);
20
28
  if (collectionOrView?.icon && icon)
21
29
  return icon;
@@ -39,7 +47,7 @@ export const IconForView = React.memo(
39
47
 
40
48
  return <Icon iconKey={key} size={"medium"} className={className}/>;
41
49
  }, (prevProps, nextProps) => {
42
- return equal(prevProps.collectionOrView.icon, nextProps.collectionOrView.icon);
50
+ return equal(prevProps.collectionOrView?.icon, nextProps.collectionOrView?.icon);
43
51
  });
44
52
 
45
53
  const iconKeysMap: Record<string, string> = iconKeys.reduce((acc: Record<string, string>, key) => {
@@ -1,4 +1,5 @@
1
1
  import { AuthController, Entity, EntityCollection, Permissions, User } from "../types";
2
+ import { fullPathToCollectionSegments } from "./paths";
2
3
 
3
4
  const DEFAULT_PERMISSIONS = {
4
5
  read: true,
@@ -10,8 +11,8 @@ const DEFAULT_PERMISSIONS = {
10
11
  export function resolvePermissions<M extends Record<string, any>, UserType extends User>
11
12
  (collection: EntityCollection<M>,
12
13
  authController: AuthController<UserType>,
13
- pathSegments: string[],
14
- entity: Entity<M> | null): Permissions {
14
+ path: string,
15
+ entity: Entity<M> | null): Permissions | undefined {
15
16
 
16
17
  const permission = collection.permissions;
17
18
  if (permission === undefined) {
@@ -19,8 +20,10 @@ export function resolvePermissions<M extends Record<string, any>, UserType exten
19
20
  } else if (typeof permission === "object") {
20
21
  return permission as Permissions;
21
22
  } else if (typeof permission === "function") {
23
+ const pathSegments = fullPathToCollectionSegments(path);
22
24
  return permission({
23
25
  entity,
26
+ path,
24
27
  user: authController.user,
25
28
  authController,
26
29
  collection,
@@ -35,27 +38,27 @@ export function canEditEntity<M extends Record<string, any>, UserType extends Us
35
38
  (
36
39
  collection: EntityCollection<M>,
37
40
  authController: AuthController<UserType>,
38
- paths: string[],
41
+ path: string,
39
42
  entity: Entity<M> | null): boolean {
40
- return resolvePermissions(collection, authController, paths, entity).edit ?? DEFAULT_PERMISSIONS.edit;
43
+ return resolvePermissions(collection, authController, path, entity)?.edit ?? DEFAULT_PERMISSIONS.edit;
41
44
  }
42
45
 
43
46
  export function canCreateEntity<M extends Record<string, any>, UserType extends User>
44
47
  (
45
48
  collection: EntityCollection<M>,
46
49
  authController: AuthController<UserType>,
47
- paths: string[],
50
+ path: string,
48
51
  entity: Entity<M> | null): boolean {
49
- return resolvePermissions(collection, authController, paths, entity).create ?? DEFAULT_PERMISSIONS.create;
52
+ return resolvePermissions(collection, authController, path, entity)?.create ?? DEFAULT_PERMISSIONS.create;
50
53
  }
51
54
 
52
55
  export function canDeleteEntity<M extends Record<string, any>, UserType extends User>
53
56
  (
54
57
  collection: EntityCollection<M>,
55
58
  authController: AuthController<UserType>,
56
- paths: string[],
59
+ path: string,
57
60
  entity: Entity<M> | null): boolean {
58
- return resolvePermissions(collection, authController, paths, entity).delete ?? DEFAULT_PERMISSIONS.delete;
61
+ return resolvePermissions(collection, authController, path, entity)?.delete ?? DEFAULT_PERMISSIONS.delete;
59
62
  }
60
63
 
61
64
  // export function resolveCollectionsPermissions(roles: Role[]): Record<string, Permissions> {
@@ -1,11 +1,12 @@
1
- import { EntityCollection, PropertyConfig } from "../types";
1
+ import { EntityCollection, PropertyConfig, ResolvedEntityCollection } from "../types";
2
2
  import { isReferenceProperty } from "./property_utils";
3
3
  import { isPropertyBuilder } from "./entities";
4
+ import { getFieldConfig } from "../core";
4
5
 
5
- export function getReferencePreviewKeys(targetCollection: EntityCollection<any>,
6
- fields: Record<string, PropertyConfig>,
7
- previewProperties?: string[],
8
- limit = 3) {
6
+ export function getEntityPreviewKeys(targetCollection: EntityCollection<any>,
7
+ fields: Record<string, PropertyConfig>,
8
+ previewProperties?: string[],
9
+ limit = 3) {
9
10
  const allProperties = Object.keys(targetCollection.properties);
10
11
  let listProperties = previewProperties?.filter(p => allProperties.includes(p as string));
11
12
  if (listProperties && listProperties.length > 0) {
@@ -18,3 +19,33 @@ export function getReferencePreviewKeys(targetCollection: EntityCollection<any>,
18
19
  }).slice(0, limit);
19
20
  }
20
21
  }
22
+
23
+ export function getEntityTitlePropertyKey<M extends Record<string, any>>(collection: EntityCollection<M>, propertyConfigs: Record<string, PropertyConfig<any>>): string | undefined {
24
+ if (collection.titleProperty) {
25
+ return collection.titleProperty as string;
26
+ }
27
+ // find first text field property
28
+ for (const key in collection.properties) {
29
+ const property = collection.properties[key];
30
+ if (!isPropertyBuilder(property)) {
31
+ const field = getFieldConfig(property, propertyConfigs);
32
+ if (field?.key === "text_field") {
33
+ return key;
34
+ }
35
+ }
36
+ }
37
+ return undefined;
38
+ }
39
+
40
+ export function getEntityImagePreviewPropertyKey<M extends object>(collection: ResolvedEntityCollection<M>): string | undefined {
41
+
42
+ // find first text field property
43
+ for (const key in collection.properties) {
44
+ const property = collection.properties[key];
45
+ if (property.dataType === "string" && property.storage?.acceptedFiles?.includes("image/*")) {
46
+ return key;
47
+ }
48
+
49
+ }
50
+ return undefined;
51
+ }
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useRef } from "react";
2
2
 
3
- function printChanged(props: any, prev: any, path = "", depth = 0, maxDepth: number) {
3
+ export function printChanged(props: any, prev: any, path: string | undefined = "", depth: number | undefined = 0, maxDepth: number | undefined = 10) {
4
4
  if (depth > maxDepth) {
5
5
  return;
6
6
  }
@@ -17,6 +17,7 @@ function printChanged(props: any, prev: any, path = "", depth = 0, maxDepth: num
17
17
  export function useTraceUpdate(props: any, maxDepth = 3) {
18
18
  const prev = useRef(props);
19
19
  useEffect(() => {
20
+ console.log("Changed props:");
20
21
  printChanged(props, prev.current, "", 0, maxDepth);
21
22
  prev.current = props;
22
23
  });