@firecms/core 3.0.0-beta.7 → 3.0.0-beta.9

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 (216) hide show
  1. package/dist/app/AppBar.d.ts +12 -0
  2. package/dist/app/Drawer.d.ts +17 -0
  3. package/dist/app/Scaffold.d.ts +30 -0
  4. package/dist/app/index.d.ts +4 -0
  5. package/dist/app/useApp.d.ts +16 -0
  6. package/dist/components/ArrayContainer.d.ts +2 -1
  7. package/dist/components/CircularProgressCenter.d.ts +1 -1
  8. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +0 -1
  9. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
  10. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
  11. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -1
  12. package/dist/components/EntityPreview.d.ts +1 -1
  13. package/dist/components/ErrorView.d.ts +1 -1
  14. package/dist/components/HomePage/DefaultHomePage.d.ts +1 -1
  15. package/dist/components/HomePage/NavigationCardBinding.d.ts +1 -1
  16. package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
  17. package/dist/components/VirtualTable/VirtualTableProps.d.ts +14 -6
  18. package/dist/components/common/useColumnsIds.d.ts +2 -1
  19. package/dist/components/index.d.ts +2 -1
  20. package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +3 -8
  21. package/dist/core/DefaultDrawer.d.ts +19 -0
  22. package/dist/core/DrawerNavigationItem.d.ts +2 -1
  23. package/dist/core/EntityEditView.d.ts +18 -4
  24. package/dist/core/FireCMS.d.ts +1 -1
  25. package/dist/core/NavigationRoutes.d.ts +2 -2
  26. package/dist/core/index.d.ts +2 -2
  27. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  28. package/dist/form/components/FieldHelperText.d.ts +3 -3
  29. package/dist/form/components/FormikArrayContainer.d.ts +2 -1
  30. package/dist/form/components/LabelWithIcon.d.ts +1 -1
  31. package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
  32. package/dist/form/components/StorageItemPreview.d.ts +4 -4
  33. package/dist/form/components/index.d.ts +1 -0
  34. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  35. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  36. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  37. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  38. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  39. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
  40. package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
  41. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  42. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  43. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  44. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -5
  45. package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
  46. package/dist/form/index.d.ts +3 -5
  47. package/dist/form/useClearRestoreValue.d.ts +2 -2
  48. package/dist/hooks/useProjectLog.d.ts +2 -2
  49. package/dist/index.d.ts +1 -0
  50. package/dist/index.es.js +14434 -11300
  51. package/dist/index.es.js.map +1 -1
  52. package/dist/index.umd.js +19987 -587
  53. package/dist/index.umd.js.map +1 -1
  54. package/dist/preview/PropertyPreviewProps.d.ts +6 -1
  55. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  56. package/dist/preview/components/ReferencePreview.d.ts +1 -1
  57. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  58. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  59. package/dist/types/auth.d.ts +2 -2
  60. package/dist/types/collections.d.ts +26 -3
  61. package/dist/types/datasource.d.ts +53 -30
  62. package/dist/types/entities.d.ts +1 -0
  63. package/dist/types/entity_overrides.d.ts +2 -2
  64. package/dist/types/fields.d.ts +47 -41
  65. package/dist/types/navigation.d.ts +1 -0
  66. package/dist/types/plugins.d.ts +11 -3
  67. package/dist/types/properties.d.ts +25 -20
  68. package/dist/types/side_dialogs_controller.d.ts +10 -0
  69. package/dist/types/storage.d.ts +75 -0
  70. package/dist/util/entities.d.ts +1 -1
  71. package/dist/util/icon_list.d.ts +5 -1
  72. package/dist/util/icons.d.ts +3 -2
  73. package/dist/util/index.d.ts +1 -0
  74. package/dist/util/plurals.d.ts +0 -2
  75. package/dist/util/property_utils.d.ts +1 -1
  76. package/dist/util/resolutions.d.ts +15 -1
  77. package/dist/util/storage.d.ts +23 -2
  78. package/dist/util/useStorageUploadController.d.ts +3 -3
  79. package/package.json +18 -29
  80. package/src/app/AppBar.tsx +18 -0
  81. package/src/app/Drawer.tsx +25 -0
  82. package/src/{core → app}/Scaffold.tsx +71 -122
  83. package/src/app/index.ts +4 -0
  84. package/src/app/useApp.tsx +32 -0
  85. package/src/components/ArrayContainer.tsx +15 -10
  86. package/src/components/CircularProgressCenter.tsx +1 -1
  87. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +11 -18
  88. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +2 -2
  89. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +4 -2
  90. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +21 -14
  91. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +12 -4
  92. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +17 -19
  93. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +19 -7
  94. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +5 -6
  95. package/src/components/EntityCollectionView/EntityCollectionView.tsx +33 -29
  96. package/src/components/EntityCollectionView/useSelectionController.tsx +19 -7
  97. package/src/components/EntityPreview.tsx +30 -31
  98. package/src/components/ErrorView.tsx +1 -1
  99. package/src/components/HomePage/DefaultHomePage.tsx +24 -18
  100. package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
  101. package/src/components/HomePage/SmallNavigationCard.tsx +1 -2
  102. package/src/components/PropertyIdCopyTooltip.tsx +48 -0
  103. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +7 -6
  104. package/src/components/SearchIconsView.tsx +5 -2
  105. package/src/components/SelectableTable/SelectableTable.tsx +2 -4
  106. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +1 -1
  107. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +54 -7
  108. package/src/components/VirtualTable/VirtualTable.tsx +36 -10
  109. package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
  110. package/src/components/VirtualTable/VirtualTableProps.tsx +17 -8
  111. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -3
  112. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -1
  113. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
  114. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +14 -28
  115. package/src/components/common/useColumnsIds.tsx +13 -0
  116. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -12
  117. package/src/components/common/useTableSearchHelper.ts +53 -12
  118. package/src/components/index.tsx +2 -1
  119. package/src/contexts/DialogsProvider.tsx +2 -2
  120. package/src/{components/FireCMSAppBar.tsx → core/DefaultAppBar.tsx} +28 -30
  121. package/src/core/DefaultDrawer.tsx +183 -0
  122. package/src/core/DrawerNavigationItem.tsx +31 -27
  123. package/src/core/EntityEditView.tsx +712 -145
  124. package/src/core/EntitySidePanel.tsx +0 -1
  125. package/src/core/FireCMS.tsx +2 -2
  126. package/src/core/NavigationRoutes.tsx +4 -4
  127. package/src/core/SideDialogs.tsx +1 -0
  128. package/src/core/field_configs.tsx +5 -5
  129. package/src/core/index.tsx +2 -2
  130. package/src/form/PropertyFieldBinding.tsx +53 -19
  131. package/src/form/components/CustomIdField.tsx +4 -2
  132. package/src/form/components/FieldHelperText.tsx +4 -4
  133. package/src/form/components/FormikArrayContainer.tsx +4 -1
  134. package/src/form/components/LabelWithIcon.tsx +27 -19
  135. package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
  136. package/src/form/components/StorageItemPreview.tsx +20 -10
  137. package/src/form/components/StorageUploadProgress.tsx +0 -1
  138. package/src/form/components/index.tsx +1 -0
  139. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +26 -15
  140. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +28 -25
  141. package/src/form/field_bindings/BlockFieldBinding.tsx +13 -11
  142. package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -14
  143. package/src/form/field_bindings/KeyValueFieldBinding.tsx +48 -42
  144. package/src/form/field_bindings/MapFieldBinding.tsx +17 -17
  145. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +150 -0
  146. package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +25 -20
  147. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +9 -14
  148. package/src/form/field_bindings/ReferenceFieldBinding.tsx +27 -18
  149. package/src/form/field_bindings/RepeatFieldBinding.tsx +32 -19
  150. package/src/form/field_bindings/SelectFieldBinding.tsx +17 -10
  151. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +33 -43
  152. package/src/form/field_bindings/SwitchFieldBinding.tsx +9 -5
  153. package/src/form/field_bindings/TextFieldBinding.tsx +26 -23
  154. package/src/form/index.tsx +4 -9
  155. package/src/form/useClearRestoreValue.tsx +2 -2
  156. package/src/form/validation.ts +1 -17
  157. package/src/hooks/data/delete.ts +2 -1
  158. package/src/hooks/data/save.ts +5 -2
  159. package/src/hooks/data/useDataSource.tsx +11 -3
  160. package/src/hooks/useBuildNavigationController.tsx +10 -3
  161. package/src/hooks/useProjectLog.tsx +18 -7
  162. package/src/index.ts +1 -0
  163. package/src/internal/useBuildDataSource.ts +69 -74
  164. package/src/internal/useBuildSideDialogsController.tsx +1 -0
  165. package/src/internal/useBuildSideEntityController.tsx +17 -4
  166. package/src/internal/useUnsavedChangesDialog.tsx +3 -1
  167. package/src/preview/PropertyPreview.tsx +7 -4
  168. package/src/preview/PropertyPreviewProps.tsx +7 -1
  169. package/src/preview/components/BooleanPreview.tsx +1 -1
  170. package/src/preview/components/EnumValuesChip.tsx +1 -1
  171. package/src/preview/components/ImagePreview.tsx +24 -34
  172. package/src/preview/components/ReferencePreview.tsx +2 -12
  173. package/src/preview/components/StorageThumbnail.tsx +5 -1
  174. package/src/preview/components/UrlComponentPreview.tsx +44 -11
  175. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  176. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +1 -1
  177. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +1 -1
  178. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
  179. package/src/preview/property_previews/ArrayPropertyPreview.tsx +1 -1
  180. package/src/preview/property_previews/MapPropertyPreview.tsx +1 -1
  181. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +2 -2
  182. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  183. package/src/preview/util.ts +2 -2
  184. package/src/types/auth.tsx +2 -2
  185. package/src/types/collections.ts +29 -4
  186. package/src/types/customization_controller.tsx +0 -1
  187. package/src/types/datasource.ts +62 -43
  188. package/src/types/entities.ts +2 -0
  189. package/src/types/entity_overrides.tsx +2 -2
  190. package/src/types/fields.tsx +51 -45
  191. package/src/types/navigation.ts +1 -0
  192. package/src/types/plugins.tsx +12 -3
  193. package/src/types/properties.ts +25 -19
  194. package/src/types/side_dialogs_controller.tsx +13 -0
  195. package/src/types/storage.ts +82 -0
  196. package/src/util/entities.ts +5 -4
  197. package/src/util/icon_list.ts +14 -9
  198. package/src/util/icons.tsx +8 -2
  199. package/src/util/index.ts +1 -0
  200. package/src/util/objects.ts +17 -7
  201. package/src/util/permissions.ts +1 -0
  202. package/src/util/plurals.ts +0 -2
  203. package/src/util/property_utils.tsx +1 -1
  204. package/src/util/references.ts +3 -0
  205. package/src/util/resolutions.ts +43 -11
  206. package/src/util/storage.ts +79 -21
  207. package/src/util/useStorageUploadController.tsx +33 -7
  208. package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
  209. package/dist/core/Drawer.d.ts +0 -16
  210. package/dist/core/Scaffold.d.ts +0 -51
  211. package/dist/form/EntityForm.d.ts +0 -77
  212. package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
  213. package/src/components/PropertyIdCopyTooltipContent.tsx +0 -27
  214. package/src/core/Drawer.tsx +0 -139
  215. package/src/form/EntityForm.tsx +0 -736
  216. package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
@@ -9,6 +9,7 @@ import {
9
9
  FetchCollectionProps,
10
10
  FetchEntityProps,
11
11
  FilterValues,
12
+ FireCMSContext,
12
13
  ListenCollectionProps,
13
14
  ListenEntityProps,
14
15
  NavigationController,
@@ -51,23 +52,25 @@ export function useBuildDataSource({
51
52
  */
52
53
  fetchCollection: useCallback(<M extends Record<string, any>>({
53
54
  path,
54
- collection: collectionProp,
55
+ collection,
55
56
  filter,
56
57
  limit,
57
58
  startAfter,
58
59
  searchString,
59
60
  orderBy,
60
- order
61
+ order,
61
62
  }: FetchCollectionProps<M>
62
63
  ): Promise<Entity<M>[]> => {
63
- return delegate.fetchCollection<M>({
64
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
65
+ return usedDelegate.fetchCollection<M>({
64
66
  path,
65
67
  filter,
66
68
  limit,
67
69
  startAfter,
68
70
  searchString,
69
71
  orderBy,
70
- order
72
+ order,
73
+ collection
71
74
  });
72
75
  }, [delegate]),
73
76
 
@@ -88,7 +91,6 @@ export function useBuildDataSource({
88
91
  * @group Firestore
89
92
  */
90
93
  listenCollection: delegate.listenCollection
91
- // eslint-disable-next-line react-hooks/rules-of-hooks
92
94
  ? useCallback(<M extends Record<string, any>>(
93
95
  {
94
96
  path,
@@ -105,11 +107,12 @@ export function useBuildDataSource({
105
107
  ): () => void => {
106
108
 
107
109
  const collection = collectionProp ?? navigationController.getCollection(path);
108
- const isCollectionGroup = Boolean(collection?.collectionGroup) ?? false;
109
- if (!delegate.listenCollection)
110
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
111
+
112
+ if (!usedDelegate.listenCollection)
110
113
  throw Error("useBuildDataSource delegate not initialised");
111
114
 
112
- return delegate.listenCollection<M>({
115
+ return usedDelegate.listenCollection<M>({
113
116
  path,
114
117
  filter,
115
118
  limit,
@@ -119,8 +122,7 @@ export function useBuildDataSource({
119
122
  order,
120
123
  onUpdate,
121
124
  onError,
122
- isCollectionGroup,
123
- collection
125
+ collection,
124
126
  });
125
127
  }, [delegate, navigationController.getCollection])
126
128
  : undefined,
@@ -134,12 +136,17 @@ export function useBuildDataSource({
134
136
  */
135
137
  fetchEntity: useCallback(<M extends Record<string, any>>({
136
138
  path,
137
- entityId
139
+ entityId,
140
+ collection
138
141
  }: FetchEntityProps<M>
139
- ): Promise<Entity<M> | undefined> => delegate.fetchEntity({
140
- path,
141
- entityId
142
- }), [delegate]),
142
+ ): Promise<Entity<M> | undefined> => {
143
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
144
+ return usedDelegate.fetchEntity({
145
+ path,
146
+ entityId,
147
+ collection
148
+ });
149
+ }, [delegate.fetchEntity]),
143
150
 
144
151
  /**
145
152
  *
@@ -152,7 +159,6 @@ export function useBuildDataSource({
152
159
  * @group Firestore
153
160
  */
154
161
  listenEntity: delegate.listenEntity
155
- // eslint-disable-next-line react-hooks/rules-of-hooks
156
162
  ? useCallback(<M extends Record<string, any>>(
157
163
  {
158
164
  path,
@@ -161,14 +167,17 @@ export function useBuildDataSource({
161
167
  onUpdate,
162
168
  onError
163
169
  }: ListenEntityProps<M>): () => void => {
164
- if (!delegate.listenEntity)
170
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
171
+
172
+ if (!usedDelegate.listenEntity)
165
173
  throw Error("useBuildDataSource delegate not initialised");
166
174
 
167
- return delegate.listenEntity<M>({
175
+ return usedDelegate.listenEntity<M>({
168
176
  path,
169
177
  entityId,
170
178
  onUpdate,
171
- onError
179
+ onError,
180
+ collection
172
181
  })
173
182
  }, [delegate.listenEntity]) : undefined,
174
183
 
@@ -193,6 +202,7 @@ export function useBuildDataSource({
193
202
  }: SaveEntityProps<M>): Promise<Entity<M>> => {
194
203
 
195
204
  const collection = collectionProp ?? navigationController.getCollection(path);
205
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
196
206
 
197
207
  const resolvedCollection = collection
198
208
  ? resolveCollection<M>({
@@ -205,31 +215,32 @@ export function useBuildDataSource({
205
215
 
206
216
  const properties: ResolvedProperties<M> | undefined = resolvedCollection?.properties;
207
217
 
208
- const firestoreValues = delegate.cmsToDelegateModel(
218
+ const firestoreValues = usedDelegate.cmsToDelegateModel(
209
219
  values,
210
220
  );
211
221
 
212
- const updatedFirestoreValues: EntityValues<M> = properties
222
+ const updatedValues: EntityValues<M> = properties
213
223
  ? updateDateAutoValues(
214
224
  {
215
225
  inputValues: firestoreValues,
216
226
  properties,
217
227
  status,
218
- timestampNowValue: delegate.currentTime(),
219
- setDateToMidnight: delegate.setDateToMidnight
228
+ timestampNowValue: usedDelegate.currentTime?.() ?? new Date(),
229
+ setDateToMidnight: usedDelegate.setDateToMidnight
220
230
  })
221
231
  : firestoreValues;
222
232
 
223
- return delegate.saveEntity({
233
+ return usedDelegate.saveEntity({
224
234
  path,
235
+ collection,
225
236
  entityId,
226
- values: updatedFirestoreValues,
237
+ values: updatedValues,
227
238
  status
228
239
  }).then((res) => {
229
240
  return {
230
241
  id: res.id,
231
242
  path: res.path,
232
- values: delegate.delegateToCMSModel(updatedFirestoreValues)
243
+ values: usedDelegate.delegateToCMSModel(updatedValues)
233
244
  } as Entity<M>;
234
245
  });
235
246
  }, [delegate.saveEntity, navigationController.getCollection]),
@@ -242,10 +253,15 @@ export function useBuildDataSource({
242
253
  */
243
254
  deleteEntity: useCallback(<M extends Record<string, any>>(
244
255
  {
245
- entity
256
+ entity,
257
+ collection
246
258
  }: DeleteEntityProps<M>
247
259
  ): Promise<void> => {
248
- return delegate.deleteEntity({ entity });
260
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
261
+ return usedDelegate.deleteEntity({
262
+ entity,
263
+ collection
264
+ });
249
265
  }, [delegate.deleteEntity]),
250
266
 
251
267
  /**
@@ -262,13 +278,16 @@ export function useBuildDataSource({
262
278
  path: string,
263
279
  name: string,
264
280
  value: any,
265
- entityId?: string
281
+ entityId?: string,
282
+ collection?: EntityCollection
266
283
  ): Promise<boolean> => {
267
- return delegate.checkUniqueField(path, name, value, entityId);
284
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
285
+ return usedDelegate.checkUniqueField(path, name, value, entityId, collection);
268
286
  }, [delegate.checkUniqueField]),
269
287
 
270
- generateEntityId: useCallback((path: string): string => {
271
- return delegate.generateEntityId(path,);
288
+ generateEntityId: useCallback((path: string, collection: EntityCollection): string => {
289
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
290
+ return usedDelegate.generateEntityId(path, collection);
272
291
  }, [delegate.generateEntityId]),
273
292
 
274
293
  countEntities: delegate.countEntities ? async ({
@@ -284,21 +303,24 @@ export function useBuildDataSource({
284
303
  orderBy?: string,
285
304
  order?: "desc" | "asc",
286
305
  }): Promise<number> => {
287
- return delegate.countEntities!({
306
+ const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
307
+ return usedDelegate.countEntities!({
288
308
  path,
289
309
  filter,
290
310
  orderBy,
291
311
  order,
292
- isCollectionGroup: Boolean(collection.collectionGroup) ?? false
312
+ collection
293
313
  });
294
314
  } : undefined,
295
315
 
296
316
  isFilterCombinationValid: useCallback(({
297
317
  path,
318
+ databaseId,
298
319
  filterValues,
299
320
  sortBy
300
321
  }: {
301
322
  path: string,
323
+ databaseId?: string,
302
324
  filterValues: FilterValues<any>,
303
325
  sortBy?: [string, "asc" | "desc"]
304
326
  }): boolean => {
@@ -307,52 +329,25 @@ export function useBuildDataSource({
307
329
  return delegate.isFilterCombinationValid(
308
330
  {
309
331
  path,
332
+ databaseId,
310
333
  filterValues,
311
334
  sortBy
312
335
  }
313
336
  )
314
337
  }, [delegate.isFilterCombinationValid]),
315
338
 
339
+ initTextSearch: useCallback(async (props: {
340
+ context: FireCMSContext,
341
+ path: string,
342
+ collection: EntityCollection,
343
+ parentCollectionIds?: string[]
344
+ }): Promise<boolean> => {
345
+ const usedDelegate = props.collection?.overrides?.dataSourceDelegate ?? delegate;
346
+ if (!usedDelegate.initTextSearch)
347
+ return false;
348
+ return usedDelegate.initTextSearch(props)
349
+ }, [delegate.initTextSearch]),
350
+
316
351
  };
317
352
 
318
353
  }
319
-
320
- // /**
321
- // * Recursive function that converts Firestore data types into CMS or plain
322
- // * JS types.
323
- // * FireCMS uses Javascript dates internally instead of Firestore timestamps.
324
- // * This makes it easier to interact with the rest of the libraries and
325
- // * bindings.
326
- // * Also, Firestore references are replaced with {@link EntityReference}
327
- // * @param data
328
- // * @param buildReference
329
- // * @param buildGeoPoint
330
- // * @param buildDate
331
- // * @param buildDelete
332
- // * @group Firestore
333
- // */
334
- // export function cmsToDelegateModel(data: any,
335
- // buildReference: (reference: EntityReference) => any,
336
- // buildGeoPoint: (geoPoint: GeoPoint) => any,
337
- // buildDate: (date: Date) => any,
338
- // buildDelete: () => any
339
- // ): any {
340
- // if (data === undefined) {
341
- // return buildDelete();
342
- // } else if (data === null) {
343
- // return null;
344
- // } else if (Array.isArray(data)) {
345
- // return data.map(v => cmsToDelegateModel(v, buildReference, buildGeoPoint, buildDate, buildDelete));
346
- // } else if (data.isEntityReference && data.isEntityReference()) {
347
- // return buildReference(data);
348
- // } else if (data instanceof GeoPoint) {
349
- // return buildGeoPoint(data);
350
- // } else if (data instanceof Date) {
351
- // return buildDate(data);
352
- // } else if (data && typeof data === "object") {
353
- // return Object.entries(data)
354
- // .map(([key, v]) => ({ [key]: cmsToDelegateModel(v, buildReference, buildGeoPoint, buildDate, buildDelete) }))
355
- // .reduce((a, b) => ({ ...a, ...b }), {});
356
- // }
357
- // return data;
358
- // }
@@ -118,6 +118,7 @@ export function useBuildSideDialogsController(): SideDialogsController {
118
118
 
119
119
  return {
120
120
  sidePanels,
121
+ setSidePanels: updateSidePanels,
121
122
  close,
122
123
  open,
123
124
  replace
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef } from "react";
2
2
  import {
3
3
  EntityCollection,
4
4
  EntitySidePanelProps,
5
- NavigationController, PropertyConfig,
5
+ NavigationController,
6
6
  ResolvedProperty,
7
7
  SideDialogPanelProps,
8
8
  SideDialogsController,
@@ -115,6 +115,16 @@ export const useBuildSideEntityController = (navigation: NavigationController,
115
115
  }
116
116
  }, [location, navigation.loading, navigation.isUrlCollectionPath, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, sideDialogsController, smallLayout, navigation]);
117
117
 
118
+ useEffect(() => {
119
+ const updatedSidePanels = sideDialogsController.sidePanels.map(sidePanelProps => {
120
+ if (sidePanelProps.additional) {
121
+ return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout);
122
+ }
123
+ return sidePanelProps;
124
+ });
125
+ sideDialogsController.setSidePanels(updatedSidePanels);
126
+ }, [smallLayout]);
127
+
118
128
  const close = useCallback(() => {
119
129
  sideDialogsController.close();
120
130
  }, [sideDialogsController]);
@@ -210,7 +220,7 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
210
220
  return sidePanels;
211
221
  }
212
222
 
213
- const propsToSidePanel = (props: EntitySidePanelProps<any>,
223
+ const propsToSidePanel = (props: EntitySidePanelProps,
214
224
  buildUrlCollectionPath: (path: string) => string,
215
225
  resolveAliasesFrom: (pathWithAliases: string) => string,
216
226
  smallLayout: boolean): SideDialogPanelProps => {
@@ -227,13 +237,16 @@ const propsToSidePanel = (props: EntitySidePanelProps<any>,
227
237
  path: resolvedPath,
228
238
  };
229
239
 
240
+ const entityViewWidth = getEntityViewWidth(props, smallLayout);
241
+
230
242
  return {
231
243
  key: `${props.path}/${props.entityId}`,
232
244
  component: <EntitySidePanel {...resolvedPanelProps}/>,
233
245
  urlPath: newPath,
234
246
  parentUrlPath: buildUrlCollectionPath(collectionPath),
235
- width: getEntityViewWidth(props, smallLayout),
236
- onClose: props.onClose
247
+ width: entityViewWidth,
248
+ onClose: props.onClose,
249
+ additional: props
237
250
  };
238
251
  }
239
252
  ;
@@ -84,8 +84,10 @@ export function UnsavedChangesDialog({
84
84
 
85
85
  return (
86
86
  <Dialog
87
+ onEscapeKeyDown={() => {
88
+ handleCancel();
89
+ }}
87
90
  open={open}
88
- onOpenChange={(open) => open ? handleCancel() : handleOk()}
89
91
  >
90
92
  <DialogContent>
91
93
  <Typography variant={"h6"}>{title}</Typography>
@@ -47,7 +47,7 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
47
47
  size,
48
48
  height,
49
49
  width,
50
- // entity
50
+ interactive
51
51
  } = props;
52
52
 
53
53
  const property = resolveProperty({
@@ -84,14 +84,17 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
84
84
  content =
85
85
  <UrlComponentPreview size={props.size}
86
86
  url={value}
87
+ interactive={interactive}
87
88
  previewType={stringProperty.url}/>;
89
+ } else if (stringProperty.markdown) {
90
+ content = <Markdown source={value} size={"small"}/>;
88
91
  } else if (stringProperty.storage) {
92
+ const filePath = stringProperty.storage.previewUrl ? stringProperty.storage.previewUrl(value) : value;
89
93
  content = <StorageThumbnail
94
+ interactive={interactive}
90
95
  storeUrl={property.storage?.storeUrl ?? false}
91
96
  size={props.size}
92
- storagePathOrDownloadUrl={value}/>;
93
- } else if (stringProperty.markdown) {
94
- content = <Markdown source={value} size={"small"}/>;
97
+ storagePathOrDownloadUrl={filePath}/>;
95
98
  } else {
96
99
  content = <StringPropertyPreview {...props}
97
100
  property={stringProperty}
@@ -3,7 +3,7 @@ import { CMSType, Property, ResolvedProperty } from "../types";
3
3
  /**
4
4
  * @group Preview components
5
5
  */
6
- export type PreviewSize = "medium" | "small" | "tiny";
6
+ export type PreviewSize = "medium" | "small" | "smallest";
7
7
 
8
8
  /**
9
9
  * @group Preview components
@@ -46,4 +46,10 @@ export interface PropertyPreviewProps<T extends CMSType = any, CustomProps = any
46
46
  */
47
47
  customProps?: CustomProps;
48
48
 
49
+ /**
50
+ * If the preview should be interactive or not.
51
+ * This applies only to videos.
52
+ */
53
+ interactive?: boolean;
54
+
49
55
  }
@@ -21,6 +21,6 @@ export function BooleanPreview({
21
21
  size={size}
22
22
  color={"secondary"}/>
23
23
  {property.name && <span
24
- className={cls("text-text-secondary dark:text-text-secondary-dark", size === "tiny" ? "text-sm" : "")}>{property.name}</span>}
24
+ className={cls("text-text-secondary dark:text-text-secondary-dark", size === "smallest" ? "text-sm" : "")}>{property.name}</span>}
25
25
  </div>;
26
26
  }
@@ -6,7 +6,7 @@ import { buildEnumLabel, enumToObjectEntries, getColorScheme, getLabelOrConfigFr
6
6
  export interface EnumValuesChipProps {
7
7
  enumValues?: EnumValues;
8
8
  enumKey: string | number;
9
- size: "tiny" | "small" | "medium";
9
+ size: "smallest" | "small" | "medium";
10
10
  className?: string;
11
11
  children?: React.ReactNode;
12
12
  }
@@ -1,4 +1,4 @@
1
- import React, { CSSProperties, useMemo, useState } from "react";
1
+ import React, { CSSProperties, useMemo } from "react";
2
2
 
3
3
  import { getThumbnailMeasure } from "../util";
4
4
  import { PreviewSize } from "../PropertyPreviewProps";
@@ -20,11 +20,9 @@ export function ImagePreview({
20
20
  url
21
21
  }: ImagePreviewProps) {
22
22
 
23
- const [onHover, setOnHover] = useState(false);
24
-
25
23
  const imageSize = useMemo(() => getThumbnailMeasure(size), [size]);
26
24
 
27
- if (size === "tiny") {
25
+ if (size === "smallest") {
28
26
  return (
29
27
  <img src={url}
30
28
  className={"rounded-md"}
@@ -47,60 +45,52 @@ export function ImagePreview({
47
45
 
48
46
  return (
49
47
  <div
50
- className="relative flex items-center justify-center max-w-full max-h-full"
48
+ className="relative flex items-center justify-center max-w-full max-h-full group"
51
49
  style={{
52
50
  width: imageSize,
53
51
  height: imageSize
54
52
  }}
55
- key={"image_preview_" + url}
56
- onMouseEnter={() => setOnHover(true)}
57
- onMouseMove={() => setOnHover(true)}
58
- onMouseLeave={() => setOnHover(false)}>
53
+ key={"image_preview_" + url}>
59
54
 
60
55
  <img src={url}
61
56
  className={"rounded-md"}
62
57
  style={imageStyle}/>
63
58
 
64
- {onHover && <>
65
59
 
66
- {navigator && <Tooltip title="Copy url to clipboard">
67
- <div
68
- className="rounded-full absolute bottom-[-4px] right-8">
69
- <IconButton
70
- variant={"filled"}
71
- size={"small"}
72
- onClick={(e) => {
73
- e.stopPropagation();
74
- e.preventDefault();
75
- return navigator.clipboard.writeText(url);
76
- }}>
77
- <ContentCopyIcon className={"text-gray-500"}
78
- size={"small"}/>
79
- </IconButton>
80
- </div>
60
+ <div className={"flex flex-row gap-2 absolute bottom-[-4px] right-[-4px] invisible group-hover:visible"}>
61
+ {navigator && <Tooltip
62
+ asChild={true}
63
+ title="Copy url to clipboard" side={"bottom"}>
64
+ <IconButton
65
+ variant={"filled"}
66
+ size={"small"}
67
+ onClick={(e) => {
68
+ e.stopPropagation();
69
+ e.preventDefault();
70
+ return navigator.clipboard.writeText(url);
71
+ }}>
72
+ <ContentCopyIcon className={"text-gray-700 dark:text-gray-300"}
73
+ size={"small"}/>
74
+ </IconButton>
81
75
  </Tooltip>}
82
76
 
83
- <Tooltip title="Open image in new tab">
77
+ <Tooltip title="Open image in new tab" side={"bottom"}>
84
78
  <IconButton
79
+ className="invisible group-hover:visible"
85
80
  variant={"filled"}
86
81
  component={"a" as React.ElementType}
87
- style={{
88
- position: "absolute",
89
- bottom: -4,
90
- right: -4
91
- }}
92
82
  href={url}
93
83
  rel="noopener noreferrer"
94
84
  target="_blank"
95
85
  size={"small"}
96
86
  onClick={(e: any) => e.stopPropagation()}
97
87
  >
98
- <OpenInNewIcon className={"text-gray-500"}
88
+ <OpenInNewIcon className={"text-gray-700 dark:text-gray-300"}
99
89
  size={"small"}/>
100
90
  </IconButton>
101
91
  </Tooltip>
102
- </>
103
- }
92
+ </div>
93
+
104
94
  </div>
105
95
  );
106
96
  }
@@ -21,7 +21,7 @@ export type ReferencePreviewProps = {
21
21
  /**
22
22
  * @group Preview components
23
23
  */
24
- export const ReferencePreview = React.memo<ReferencePreviewProps>(function ReferencePreview(props: ReferencePreviewProps) {
24
+ export const ReferencePreview = function ReferencePreview(props: ReferencePreviewProps) {
25
25
  const reference = props.reference;
26
26
  if (!(typeof reference === "object" && "isEntityReference" in reference && reference.isEntityReference())) {
27
27
  console.warn("Reference preview received value of type", typeof reference);
@@ -33,17 +33,7 @@ export const ReferencePreview = React.memo<ReferencePreviewProps>(function Refer
33
33
  </EntityPreviewContainer>;
34
34
  }
35
35
  return <ReferencePreviewInternal {...props} />;
36
- }, areEqual) as React.FunctionComponent<ReferencePreviewProps>;
37
-
38
- function areEqual(prevProps: ReferencePreviewProps, nextProps: ReferencePreviewProps) {
39
- return prevProps.disabled === nextProps.disabled &&
40
- prevProps.size === nextProps.size &&
41
- prevProps.hover === nextProps.hover &&
42
- prevProps.reference?.id === nextProps.reference?.id &&
43
- prevProps.reference?.path === nextProps.reference?.path &&
44
- prevProps.includeEntityLink === nextProps.includeEntityLink
45
- ;
46
- }
36
+ };
47
37
 
48
38
  function ReferencePreviewInternal({
49
39
  disabled,
@@ -11,6 +11,7 @@ type StorageThumbnailProps = {
11
11
  storagePathOrDownloadUrl: string;
12
12
  storeUrl: boolean;
13
13
  size: PreviewSize;
14
+ interactive?: boolean;
14
15
  };
15
16
 
16
17
  /**
@@ -21,13 +22,15 @@ export const StorageThumbnail = React.memo<StorageThumbnailProps>(StorageThumbna
21
22
  function areEqual(prevProps: StorageThumbnailProps, nextProps: StorageThumbnailProps) {
22
23
  return prevProps.size === nextProps.size &&
23
24
  prevProps.storagePathOrDownloadUrl === nextProps.storagePathOrDownloadUrl &&
24
- prevProps.storeUrl === nextProps.storeUrl;
25
+ prevProps.storeUrl === nextProps.storeUrl&&
26
+ prevProps.interactive === nextProps.interactive;
25
27
  }
26
28
 
27
29
  const URL_CACHE: Record<string, DownloadConfig> = {};
28
30
 
29
31
  export function StorageThumbnailInternal({
30
32
  storeUrl,
33
+ interactive,
31
34
  storagePathOrDownloadUrl,
32
35
  size
33
36
  }: StorageThumbnailProps) {
@@ -68,6 +71,7 @@ export function StorageThumbnailInternal({
68
71
  return downloadConfig?.url
69
72
  ? <UrlComponentPreview previewType={previewType}
70
73
  url={downloadConfig.url}
74
+ interactive={interactive}
71
75
  size={size}
72
76
  hint={storagePathOrDownloadUrl}/>
73
77
  : renderSkeletonImageThumbnail(size);