@firecms/core 3.0.0-canary.102 → 3.0.0-canary.104

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 (59) hide show
  1. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
  2. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  3. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  4. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  5. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  6. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  7. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  8. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +9 -0
  9. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  10. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  11. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +1 -1
  12. package/dist/form/index.d.ts +2 -2
  13. package/dist/index.es.js +269 -817
  14. package/dist/index.es.js.map +1 -1
  15. package/dist/index.umd.js +268 -815
  16. package/dist/index.umd.js.map +1 -1
  17. package/dist/types/collections.d.ts +11 -1
  18. package/dist/types/datasource.d.ts +12 -12
  19. package/dist/types/entities.d.ts +1 -0
  20. package/dist/types/fields.d.ts +5 -13
  21. package/dist/types/navigation.d.ts +1 -0
  22. package/dist/util/index.d.ts +1 -0
  23. package/dist/util/storage.d.ts +1 -1
  24. package/package.json +5 -5
  25. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +4 -2
  26. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -5
  27. package/src/components/EntityCollectionView/EntityCollectionView.tsx +4 -4
  28. package/src/components/common/useTableSearchHelper.ts +1 -0
  29. package/src/core/DefaultDrawer.tsx +1 -1
  30. package/src/core/EntityEditView.tsx +3 -4
  31. package/src/core/field_configs.tsx +2 -2
  32. package/src/form/PropertyFieldBinding.tsx +4 -8
  33. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +4 -5
  34. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +3 -3
  35. package/src/form/field_bindings/BlockFieldBinding.tsx +5 -6
  36. package/src/form/field_bindings/KeyValueFieldBinding.tsx +5 -5
  37. package/src/form/field_bindings/MapFieldBinding.tsx +6 -8
  38. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +133 -0
  39. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +5 -5
  40. package/src/form/field_bindings/ReferenceFieldBinding.tsx +5 -4
  41. package/src/form/field_bindings/RepeatFieldBinding.tsx +6 -7
  42. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +2 -2
  43. package/src/form/index.tsx +2 -2
  44. package/src/hooks/data/save.ts +5 -1
  45. package/src/internal/useBuildDataSource.ts +29 -14
  46. package/src/preview/PropertyPreview.tsx +2 -2
  47. package/src/types/collections.ts +13 -1
  48. package/src/types/datasource.ts +13 -16
  49. package/src/types/entities.ts +2 -0
  50. package/src/types/fields.tsx +5 -15
  51. package/src/types/navigation.ts +1 -0
  52. package/src/util/index.ts +1 -0
  53. package/src/util/references.ts +3 -0
  54. package/src/util/storage.ts +1 -1
  55. package/src/util/useStorageUploadController.tsx +2 -2
  56. package/dist/form/PropertiesForm.d.ts +0 -8
  57. package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
  58. package/src/form/PropertiesForm.tsx +0 -81
  59. package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
@@ -0,0 +1,133 @@
1
+ import {
2
+ FieldHelperText,
3
+ FieldProps,
4
+ getIconForProperty,
5
+ LabelWithIcon,
6
+ randomString,
7
+ useStorageSource
8
+ } from "../../index";
9
+ import { Paper } from "@firecms/ui";
10
+ import { FireCMSEditor } from "@firecms/editor";
11
+ import React, { useCallback, useEffect, useRef, useState } from "react";
12
+ import { resolveStorageFilenameString, resolveStoragePathString } from "../../util/storage";
13
+
14
+ interface MarkdownEditorFieldProps {
15
+ highlight?: { from: number, to: number };
16
+ }
17
+
18
+ export function MarkdownEditorFieldBinding({
19
+ property,
20
+ propertyKey,
21
+ value,
22
+ setValue,
23
+ includeDescription,
24
+ showError,
25
+ error,
26
+ minimalistView,
27
+ isSubmitting,
28
+ context,
29
+ customProps,
30
+ ...props
31
+ }: FieldProps<string, MarkdownEditorFieldProps>) {
32
+
33
+ const highlight = customProps?.highlight;
34
+ const storageSource = useStorageSource();
35
+ const storage = property.storage;
36
+
37
+ const entityValues = context.values;
38
+ const entityId = context.entityId;
39
+ const path = context.path;
40
+
41
+ // const fieldVersion = useRef(0);
42
+ const [fieldVersion, setFieldVersion] = useState(0);
43
+ const internalValue = useRef(value);
44
+
45
+ const onContentChange = useCallback((content: string) => {
46
+ internalValue.current = content;
47
+ setValue(content);
48
+ }, [setValue]);
49
+
50
+ useEffect(() => {
51
+ if (internalValue.current !== value) {
52
+ internalValue.current = value;
53
+ setFieldVersion(fieldVersion + 1);
54
+ // fieldVersion.current = fieldVersion.current + 1;
55
+ }
56
+ }, [value]);
57
+
58
+ const fileNameBuilder = useCallback(async (file: File) => {
59
+ if (storage?.fileName) {
60
+ const fileName = await resolveStorageFilenameString({
61
+ input: storage.fileName,
62
+ storage,
63
+ values: entityValues,
64
+ entityId,
65
+ path,
66
+ property,
67
+ file,
68
+ propertyKey
69
+ });
70
+ if (!fileName || fileName.length === 0) {
71
+ throw Error("You need to return a valid filename");
72
+ }
73
+ return fileName;
74
+ }
75
+ return randomString() + "_" + file.name;
76
+ }, [entityId, entityValues, path, property, propertyKey, storage]);
77
+
78
+ const storagePathBuilder = useCallback((file: File) => {
79
+ if (!storage) return "/";
80
+ return resolveStoragePathString({
81
+ input: storage.storagePath,
82
+ storage,
83
+ values: entityValues,
84
+ entityId,
85
+ path,
86
+ property,
87
+ file,
88
+ propertyKey
89
+ }) ?? "/";
90
+ }, [entityId, entityValues, path, property, propertyKey, storage]);
91
+
92
+ const editor = <FireCMSEditor
93
+ content={value}
94
+ onMarkdownContentChange={onContentChange}
95
+ version={context.formex.version + fieldVersion}
96
+ highlight={highlight}
97
+ handleImageUpload={async (file: File) => {
98
+ const storagePath = storagePathBuilder(file);
99
+ const fileName = await fileNameBuilder(file);
100
+ const result = await storageSource.uploadFile({
101
+ file,
102
+ fileName,
103
+ path: storagePath,
104
+ });
105
+ const downloadConfig = await storageSource.getDownloadURL(result.path);
106
+ const url = downloadConfig.url;
107
+ if (!url) {
108
+ throw new Error("Error uploading image");
109
+ }
110
+ return url;
111
+ }}/>;
112
+
113
+ if (minimalistView)
114
+ return editor;
115
+
116
+ return (
117
+ <>
118
+ <LabelWithIcon icon={getIconForProperty(property, "small")}
119
+ required={property.validation?.required}
120
+ title={property.name}
121
+ className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
122
+ <Paper>
123
+ {editor}
124
+ </Paper>
125
+ <FieldHelperText includeDescription={includeDescription}
126
+ showError={showError}
127
+ error={error}
128
+ property={property}/>
129
+ </>
130
+
131
+ );
132
+
133
+ }
@@ -21,7 +21,7 @@ export function ReadOnlyFieldBinding({
21
21
  value,
22
22
  error,
23
23
  showError,
24
- tableMode,
24
+ minimalistView,
25
25
  property,
26
26
  includeDescription,
27
27
  context
@@ -34,10 +34,10 @@ export function ReadOnlyFieldBinding({
34
34
 
35
35
  <>
36
36
 
37
- {!tableMode && <LabelWithIcon icon={getIconForProperty(property, "small")}
38
- required={property.validation?.required}
39
- title={property.name}
40
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
37
+ {!minimalistView && <LabelWithIcon icon={getIconForProperty(property, "small")}
38
+ required={property.validation?.required}
39
+ title={property.name}
40
+ className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
41
41
  }
42
42
 
43
43
  <div
@@ -34,6 +34,7 @@ function ReferenceFieldBindingInternal({
34
34
  showError,
35
35
  isSubmitting,
36
36
  disabled,
37
+ minimalistView,
37
38
  touched,
38
39
  autoFocus,
39
40
  property,
@@ -82,10 +83,10 @@ function ReferenceFieldBindingInternal({
82
83
 
83
84
  return (
84
85
  <>
85
- <LabelWithIcon icon={getIconForProperty(property, "small")}
86
- required={property.validation?.required}
87
- title={property.name}
88
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
86
+ {!minimalistView && <LabelWithIcon icon={getIconForProperty(property, "small")}
87
+ required={property.validation?.required}
88
+ title={property.name}
89
+ className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
89
90
 
90
91
  {!collection && <ErrorView
91
92
  error={"The specified collection does not exist. Check console"}/>}
@@ -23,7 +23,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
23
23
  isSubmitting,
24
24
  setValue,
25
25
  setFieldValue,
26
- tableMode,
26
+ minimalistView,
27
27
  property,
28
28
  includeDescription,
29
29
  underlyingValueHasChanged,
@@ -57,9 +57,8 @@ export function RepeatFieldBinding<T extends Array<any>>({
57
57
  includeDescription,
58
58
  underlyingValueHasChanged,
59
59
  context,
60
- tableMode: false,
61
60
  partOfArray: true,
62
- partOfBlock: false,
61
+ minimalistView: false,
63
62
  autoFocus: internalId === lastAddedId
64
63
  };
65
64
  return <ErrorBoundary>
@@ -89,13 +88,13 @@ export function RepeatFieldBinding<T extends Array<any>>({
89
88
 
90
89
  <>
91
90
 
92
- {!tableMode && <ExpandablePanel initiallyExpanded={expanded}
93
- className={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2"}
94
- title={title}>
91
+ {!minimalistView && <ExpandablePanel initiallyExpanded={expanded}
92
+ className={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2"}
93
+ title={title}>
95
94
  {arrayContainer}
96
95
  </ExpandablePanel>}
97
96
 
98
- {tableMode && arrayContainer}
97
+ {minimalistView && arrayContainer}
99
98
 
100
99
  <FieldHelperText includeDescription={includeDescription}
101
100
  showError={showError}
@@ -44,7 +44,7 @@ export function StorageUploadFieldBinding({
44
44
  error,
45
45
  showError,
46
46
  autoFocus,
47
- tableMode,
47
+ minimalistView,
48
48
  property,
49
49
  includeDescription,
50
50
  context,
@@ -87,7 +87,7 @@ export function StorageUploadFieldBinding({
87
87
 
88
88
  <>
89
89
 
90
- {!tableMode &&
90
+ {!minimalistView &&
91
91
  <LabelWithIcon icon={getIconForProperty(property, "small")}
92
92
  required={property.validation?.required}
93
93
  title={property.name}
@@ -11,7 +11,7 @@ import { KeyValueFieldBinding } from "./field_bindings/KeyValueFieldBinding";
11
11
  import { RepeatFieldBinding } from "./field_bindings/RepeatFieldBinding";
12
12
  import { BlockFieldBinding } from "./field_bindings/BlockFieldBinding";
13
13
  import { ReadOnlyFieldBinding } from "./field_bindings/ReadOnlyFieldBinding";
14
- import { MarkdownFieldBinding } from "./field_bindings/MarkdownFieldBinding";
14
+ import { MarkdownEditorFieldBinding } from "./field_bindings/MarkdownEditorFieldBinding";
15
15
  import { ArrayCustomShapedFieldBinding } from "./field_bindings/ArrayCustomShapedFieldBinding";
16
16
 
17
17
  export {
@@ -28,7 +28,7 @@ export {
28
28
  SelectFieldBinding,
29
29
  StorageUploadFieldBinding,
30
30
  SwitchFieldBinding,
31
- MarkdownFieldBinding,
31
+ MarkdownEditorFieldBinding,
32
32
  TextFieldBinding
33
33
  };
34
34
 
@@ -108,7 +108,11 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, Use
108
108
  updatedValues = values;
109
109
  }
110
110
 
111
- console.log("Saving entity", entityId, updatedValues);
111
+ console.log("Saving entity", {
112
+ entityId,
113
+ updatedValues,
114
+ collection
115
+ });
112
116
  return dataSource.saveEntity({
113
117
  collection,
114
118
  path: resolvedPath,
@@ -52,13 +52,13 @@ export function useBuildDataSource({
52
52
  */
53
53
  fetchCollection: useCallback(<M extends Record<string, any>>({
54
54
  path,
55
- collection: collectionProp,
55
+ collection,
56
56
  filter,
57
57
  limit,
58
58
  startAfter,
59
59
  searchString,
60
60
  orderBy,
61
- order
61
+ order,
62
62
  }: FetchCollectionProps<M>
63
63
  ): Promise<Entity<M>[]> => {
64
64
  return delegate.fetchCollection<M>({
@@ -68,7 +68,8 @@ export function useBuildDataSource({
68
68
  startAfter,
69
69
  searchString,
70
70
  orderBy,
71
- order
71
+ order,
72
+ collection
72
73
  });
73
74
  }, [delegate]),
74
75
 
@@ -89,7 +90,6 @@ export function useBuildDataSource({
89
90
  * @group Firestore
90
91
  */
91
92
  listenCollection: delegate.listenCollection
92
- // eslint-disable-next-line react-hooks/rules-of-hooks
93
93
  ? useCallback(<M extends Record<string, any>>(
94
94
  {
95
95
  path,
@@ -106,7 +106,7 @@ export function useBuildDataSource({
106
106
  ): () => void => {
107
107
 
108
108
  const collection = collectionProp ?? navigationController.getCollection(path);
109
- const isCollectionGroup = Boolean(collection?.collectionGroup) ?? false;
109
+ const isCollectionGroup = Boolean(collection?.collectionGroup);
110
110
  if (!delegate.listenCollection)
111
111
  throw Error("useBuildDataSource delegate not initialised");
112
112
 
@@ -120,8 +120,7 @@ export function useBuildDataSource({
120
120
  order,
121
121
  onUpdate,
122
122
  onError,
123
- isCollectionGroup,
124
- collection
123
+ collection,
125
124
  });
126
125
  }, [delegate, navigationController.getCollection])
127
126
  : undefined,
@@ -135,11 +134,13 @@ export function useBuildDataSource({
135
134
  */
136
135
  fetchEntity: useCallback(<M extends Record<string, any>>({
137
136
  path,
138
- entityId
137
+ entityId,
138
+ collection
139
139
  }: FetchEntityProps<M>
140
140
  ): Promise<Entity<M> | undefined> => delegate.fetchEntity({
141
141
  path,
142
- entityId
142
+ entityId,
143
+ collection
143
144
  }), [delegate]),
144
145
 
145
146
  /**
@@ -153,7 +154,6 @@ export function useBuildDataSource({
153
154
  * @group Firestore
154
155
  */
155
156
  listenEntity: delegate.listenEntity
156
- // eslint-disable-next-line react-hooks/rules-of-hooks
157
157
  ? useCallback(<M extends Record<string, any>>(
158
158
  {
159
159
  path,
@@ -169,7 +169,8 @@ export function useBuildDataSource({
169
169
  path,
170
170
  entityId,
171
171
  onUpdate,
172
- onError
172
+ onError,
173
+ collection
173
174
  })
174
175
  }, [delegate.listenEntity]) : undefined,
175
176
 
@@ -195,6 +196,15 @@ export function useBuildDataSource({
195
196
 
196
197
  const collection = collectionProp ?? navigationController.getCollection(path);
197
198
 
199
+ console.log("useBuildDatasource save", {
200
+ path,
201
+ entityId,
202
+ values,
203
+ collectionProp,
204
+ collection,
205
+ status
206
+ });
207
+
198
208
  const resolvedCollection = collection
199
209
  ? resolveCollection<M>({
200
210
  collection,
@@ -223,6 +233,7 @@ export function useBuildDataSource({
223
233
 
224
234
  return delegate.saveEntity({
225
235
  path,
236
+ collection,
226
237
  entityId,
227
238
  values: updatedFirestoreValues,
228
239
  status
@@ -263,9 +274,10 @@ export function useBuildDataSource({
263
274
  path: string,
264
275
  name: string,
265
276
  value: any,
266
- entityId?: string
277
+ entityId?: string,
278
+ databaseId?: string
267
279
  ): Promise<boolean> => {
268
- return delegate.checkUniqueField(path, name, value, entityId);
280
+ return delegate.checkUniqueField(path, name, value, entityId, databaseId);
269
281
  }, [delegate.checkUniqueField]),
270
282
 
271
283
  generateEntityId: useCallback((path: string): string => {
@@ -290,16 +302,18 @@ export function useBuildDataSource({
290
302
  filter,
291
303
  orderBy,
292
304
  order,
293
- isCollectionGroup: Boolean(collection.collectionGroup)
305
+ collection
294
306
  });
295
307
  } : undefined,
296
308
 
297
309
  isFilterCombinationValid: useCallback(({
298
310
  path,
311
+ databaseId,
299
312
  filterValues,
300
313
  sortBy
301
314
  }: {
302
315
  path: string,
316
+ databaseId?: string,
303
317
  filterValues: FilterValues<any>,
304
318
  sortBy?: [string, "asc" | "desc"]
305
319
  }): boolean => {
@@ -308,6 +322,7 @@ export function useBuildDataSource({
308
322
  return delegate.isFilterCombinationValid(
309
323
  {
310
324
  path,
325
+ databaseId,
311
326
  filterValues,
312
327
  sortBy
313
328
  }
@@ -86,6 +86,8 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
86
86
  url={value}
87
87
  interactive={interactive}
88
88
  previewType={stringProperty.url}/>;
89
+ } else if (stringProperty.markdown) {
90
+ content = <Markdown source={value} size={"small"}/>;
89
91
  } else if (stringProperty.storage) {
90
92
  const filePath = stringProperty.storage.previewUrl ? stringProperty.storage.previewUrl(value) : value;
91
93
  content = <StorageThumbnail
@@ -93,8 +95,6 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
93
95
  storeUrl={property.storage?.storeUrl ?? false}
94
96
  size={props.size}
95
97
  storagePathOrDownloadUrl={filePath}/>;
96
- } else if (stringProperty.markdown) {
97
- content = <Markdown source={value} size={"small"}/>;
98
98
  } else {
99
99
  content = <StringPropertyPreview {...props}
100
100
  property={stringProperty}
@@ -51,6 +51,12 @@ export interface EntityCollection<M extends Record<string, any> = any, UserType
51
51
  */
52
52
  path: string;
53
53
 
54
+ /**
55
+ * Optional database id of this collection. If not specified, the default
56
+ * database id will be used.
57
+ */
58
+ databaseId?: string;
59
+
54
60
  /**
55
61
  * If this collection is a top level navigation entry, you can set this
56
62
  * property to `true` to indicate that this collection is a collection group.
@@ -61,7 +67,8 @@ export interface EntityCollection<M extends Record<string, any> = any, UserType
61
67
  * Icon key to use in this collection.
62
68
  * You can use any of the icons in the Material specs:
63
69
  * https://fonts.google.com/icons
64
- * e.g. 'account_tree' or 'person'
70
+ * e.g. 'account_tree' or 'person'.
71
+ * Find all the icons in https://firecms.co/docs/icons
65
72
  */
66
73
  icon?: string;
67
74
 
@@ -304,6 +311,11 @@ export interface EntityCollection<M extends Record<string, any> = any, UserType
304
311
  * Width of the side dialog (in pixels) when opening an entity in this collection.
305
312
  */
306
313
  sideDialogWidth?: number | string;
314
+
315
+ /**
316
+ * Default preview properties displayed when this collection is referenced to.
317
+ */
318
+ previewProperties?: string[];
307
319
  }
308
320
 
309
321
  /**
@@ -18,6 +18,7 @@ export interface FetchEntityProps<M extends Record<string, any> = any> {
18
18
  export type ListenEntityProps<M extends Record<string, any> = any> =
19
19
  FetchEntityProps<M>
20
20
  & {
21
+ databaseId?: string;
21
22
  onUpdate: (entity: Entity<M>) => void,
22
23
  onError?: (error: Error) => void,
23
24
  }
@@ -198,7 +199,8 @@ export interface DataSource {
198
199
  path: string,
199
200
  name: string,
200
201
  value: any,
201
- entityId?: string
202
+ entityId?: string,
203
+ databaseId?: string
202
204
  ): Promise<boolean>;
203
205
 
204
206
  /**
@@ -238,19 +240,11 @@ export type FilterCombinationValidProps = {
238
240
  sortBy?: [string, "asc" | "desc"];
239
241
  };
240
242
 
241
- export type SaveEntityDelegateProps<M extends Record<string, any> = any> = Omit<SaveEntityProps<M>, "collection">;
243
+ export type SaveEntityDelegateProps<M extends Record<string, any> = any> = SaveEntityProps<M>;
242
244
 
243
- export type FetchCollectionDelegateProps<M extends Record<string, any> = any> =
244
- Omit<FetchCollectionProps<M>, "collection">
245
- & {
246
- isCollectionGroup?: boolean
247
- };
245
+ export type FetchCollectionDelegateProps<M extends Record<string, any> = any> = FetchCollectionProps<M>;
248
246
 
249
- export type ListenCollectionDelegateProps<M extends Record<string, any> = any> =
250
- ListenCollectionProps<M>
251
- & {
252
- isCollectionGroup?: boolean;
253
- };
247
+ export type ListenCollectionDelegateProps<M extends Record<string, any> = any> = ListenCollectionProps<M>;
254
248
 
255
249
  export interface DataSourceDelegate {
256
250
 
@@ -321,7 +315,7 @@ export interface DataSourceDelegate {
321
315
  fetchEntity<M extends Record<string, any> = any>({
322
316
  path,
323
317
  entityId,
324
- }: Omit<FetchEntityProps<M>, "collection">): Promise<Entity<M> | undefined>;
318
+ }: FetchEntityProps<M>): Promise<Entity<M> | undefined>;
325
319
 
326
320
  /**
327
321
  * Get realtime updates on one entity.
@@ -337,7 +331,7 @@ export interface DataSourceDelegate {
337
331
  entityId,
338
332
  onUpdate,
339
333
  onError
340
- }: Omit<ListenEntityProps<M>, "collection">): () => void;
334
+ }: ListenEntityProps<M>): () => void;
341
335
 
342
336
  /**
343
337
  * Save entity to the specified path
@@ -368,7 +362,7 @@ export interface DataSourceDelegate {
368
362
  * @param entityId
369
363
  * @return `true` if there are no other fields besides the given entity
370
364
  */
371
- checkUniqueField(path: string, name: string, value: any, entityId?: string): Promise<boolean>;
365
+ checkUniqueField(path: string, name: string, value: any, entityId?: string, databaseId?: string): Promise<boolean>;
372
366
 
373
367
  /**
374
368
  * Generate an id for a new entity
@@ -384,7 +378,9 @@ export interface DataSourceDelegate {
384
378
  * Check if the given filter combination is valid
385
379
  * @param props
386
380
  */
387
- isFilterCombinationValid?(props: Omit<FilterCombinationValidProps, "collection">): boolean;
381
+ isFilterCombinationValid?(props: Omit<FilterCombinationValidProps, "collection"> & {
382
+ databaseId?: string
383
+ }): boolean;
388
384
 
389
385
  /**
390
386
  * Get the object to generate the current time in the datasource
@@ -400,6 +396,7 @@ export interface DataSourceDelegate {
400
396
  initTextSearch?: (props: {
401
397
  context: FireCMSContext,
402
398
  path: string,
399
+ databaseId?: string,
403
400
  collection: EntityCollection,
404
401
  parentCollectionIds?: string[]
405
402
  }) => Promise<boolean>;
@@ -25,6 +25,8 @@ export interface Entity<M extends object> {
25
25
  * Current values
26
26
  */
27
27
  values: EntityValues<M>;
28
+
29
+ databaseId?: string;
28
30
  }
29
31
 
30
32
  /**
@@ -81,14 +81,9 @@ export interface FieldProps<T extends CMSType = any, CustomProps = any, M extend
81
81
  partOfArray?: boolean;
82
82
 
83
83
  /**
84
- * Is this field part of a block (oneOf array)
85
- */
86
- partOfBlock?: boolean;
87
-
88
- /**
89
- * Is this field being rendered in the entity table popup
84
+ * Should this field render with the minimal amount of UI elements
90
85
  */
91
- tableMode?: boolean;
86
+ minimalistView?: boolean;
92
87
 
93
88
  /**
94
89
  * Should this field autofocus on mount
@@ -98,7 +93,7 @@ export interface FieldProps<T extends CMSType = any, CustomProps = any, M extend
98
93
  /**
99
94
  * Additional properties set by the developer
100
95
  */
101
- customProps?: CustomProps
96
+ customProps: CustomProps
102
97
 
103
98
  /**
104
99
  * Additional values related to the state of the form or the entity
@@ -144,7 +139,7 @@ export interface FormContext<M extends Record<string, any> = any> {
144
139
  /**
145
140
  * Entity id, it can be null if it's a new entity
146
141
  */
147
- entityId?: string;
142
+ entityId: string;
148
143
 
149
144
  /**
150
145
  * Path this entity is located at
@@ -192,11 +187,6 @@ export interface PropertyFieldBindingProps<T extends CMSType, M extends Record<s
192
187
  */
193
188
  underlyingValueHasChanged?: boolean;
194
189
 
195
- /**
196
- * Is this field being rendered in a table
197
- */
198
- tableMode?: boolean;
199
-
200
190
  /**
201
191
  * Is this field part of an array
202
192
  */
@@ -205,7 +195,7 @@ export interface PropertyFieldBindingProps<T extends CMSType, M extends Record<s
205
195
  /**
206
196
  * Is this field part of a block (oneOf array)
207
197
  */
208
- partOfBlock?: boolean;
198
+ minimalistView?: boolean;
209
199
 
210
200
  /**
211
201
  * Should the field take focus when rendered. When opening the popup view
@@ -173,6 +173,7 @@ export interface CMSView {
173
173
  * You can use any of the icons in the Material specs:
174
174
  * https://fonts.google.com/icons
175
175
  * e.g. 'account_tree' or 'person'
176
+ * Find all the icons in https://firecms.co/docs/icons
176
177
  */
177
178
  icon?: string;
178
179
 
package/src/util/index.ts CHANGED
@@ -21,3 +21,4 @@ export * from "./make_properties_editable";
21
21
  export * from "./join_collections";
22
22
  export * from "./builders";
23
23
  export * from "./useTraceUpdate";
24
+ export * from "./storage";
@@ -9,6 +9,9 @@ export function getEntityPreviewKeys(targetCollection: EntityCollection<any>,
9
9
  limit = 3) {
10
10
  const allProperties = Object.keys(targetCollection.properties);
11
11
  let listProperties = previewProperties?.filter(p => allProperties.includes(p as string));
12
+ if (!listProperties && targetCollection.previewProperties) {
13
+ listProperties = targetCollection.previewProperties?.filter(p => allProperties.includes(p as string));
14
+ }
12
15
  if (listProperties && listProperties.length > 0) {
13
16
  return listProperties;
14
17
  } else {
@@ -18,7 +18,7 @@ interface ResolveFilenameStringParams<M extends object> {
18
18
  propertyKey: string;
19
19
  }
20
20
 
21
- export async function resolveFilenameString<M extends object>(
21
+ export async function resolveStorageFilenameString<M extends object>(
22
22
  {
23
23
  input,
24
24
  storage,