@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.
- package/dist/app/AppBar.d.ts +12 -0
- package/dist/app/Drawer.d.ts +17 -0
- package/dist/app/Scaffold.d.ts +30 -0
- package/dist/app/index.d.ts +4 -0
- package/dist/app/useApp.d.ts +16 -0
- package/dist/components/ArrayContainer.d.ts +2 -1
- package/dist/components/CircularProgressCenter.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +0 -1
- package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -1
- package/dist/components/EntityPreview.d.ts +1 -1
- package/dist/components/ErrorView.d.ts +1 -1
- package/dist/components/HomePage/DefaultHomePage.d.ts +1 -1
- package/dist/components/HomePage/NavigationCardBinding.d.ts +1 -1
- package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +14 -6
- package/dist/components/common/useColumnsIds.d.ts +2 -1
- package/dist/components/index.d.ts +2 -1
- package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +3 -8
- package/dist/core/DefaultDrawer.d.ts +19 -0
- package/dist/core/DrawerNavigationItem.d.ts +2 -1
- package/dist/core/EntityEditView.d.ts +18 -4
- package/dist/core/FireCMS.d.ts +1 -1
- package/dist/core/NavigationRoutes.d.ts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/form/components/FieldHelperText.d.ts +3 -3
- package/dist/form/components/FormikArrayContainer.d.ts +2 -1
- package/dist/form/components/LabelWithIcon.d.ts +1 -1
- package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
- package/dist/form/components/StorageItemPreview.d.ts +4 -4
- package/dist/form/components/index.d.ts +1 -0
- package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
- package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
- package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -5
- package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
- package/dist/form/index.d.ts +3 -5
- package/dist/form/useClearRestoreValue.d.ts +2 -2
- package/dist/hooks/useProjectLog.d.ts +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +14434 -11300
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +19987 -587
- package/dist/index.umd.js.map +1 -1
- package/dist/preview/PropertyPreviewProps.d.ts +6 -1
- package/dist/preview/components/EnumValuesChip.d.ts +1 -1
- package/dist/preview/components/ReferencePreview.d.ts +1 -1
- package/dist/preview/components/StorageThumbnail.d.ts +2 -1
- package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
- package/dist/types/auth.d.ts +2 -2
- package/dist/types/collections.d.ts +26 -3
- package/dist/types/datasource.d.ts +53 -30
- package/dist/types/entities.d.ts +1 -0
- package/dist/types/entity_overrides.d.ts +2 -2
- package/dist/types/fields.d.ts +47 -41
- package/dist/types/navigation.d.ts +1 -0
- package/dist/types/plugins.d.ts +11 -3
- package/dist/types/properties.d.ts +25 -20
- package/dist/types/side_dialogs_controller.d.ts +10 -0
- package/dist/types/storage.d.ts +75 -0
- package/dist/util/entities.d.ts +1 -1
- package/dist/util/icon_list.d.ts +5 -1
- package/dist/util/icons.d.ts +3 -2
- package/dist/util/index.d.ts +1 -0
- package/dist/util/plurals.d.ts +0 -2
- package/dist/util/property_utils.d.ts +1 -1
- package/dist/util/resolutions.d.ts +15 -1
- package/dist/util/storage.d.ts +23 -2
- package/dist/util/useStorageUploadController.d.ts +3 -3
- package/package.json +18 -29
- package/src/app/AppBar.tsx +18 -0
- package/src/app/Drawer.tsx +25 -0
- package/src/{core → app}/Scaffold.tsx +71 -122
- package/src/app/index.ts +4 -0
- package/src/app/useApp.tsx +32 -0
- package/src/components/ArrayContainer.tsx +15 -10
- package/src/components/CircularProgressCenter.tsx +1 -1
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +11 -18
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +2 -2
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +4 -2
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +21 -14
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +12 -4
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +17 -19
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +19 -7
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +5 -6
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +33 -29
- package/src/components/EntityCollectionView/useSelectionController.tsx +19 -7
- package/src/components/EntityPreview.tsx +30 -31
- package/src/components/ErrorView.tsx +1 -1
- package/src/components/HomePage/DefaultHomePage.tsx +24 -18
- package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
- package/src/components/HomePage/SmallNavigationCard.tsx +1 -2
- package/src/components/PropertyIdCopyTooltip.tsx +48 -0
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +7 -6
- package/src/components/SearchIconsView.tsx +5 -2
- package/src/components/SelectableTable/SelectableTable.tsx +2 -4
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +1 -1
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +54 -7
- package/src/components/VirtualTable/VirtualTable.tsx +36 -10
- package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
- package/src/components/VirtualTable/VirtualTableProps.tsx +17 -8
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -3
- package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -1
- package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +14 -28
- package/src/components/common/useColumnsIds.tsx +13 -0
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -12
- package/src/components/common/useTableSearchHelper.ts +53 -12
- package/src/components/index.tsx +2 -1
- package/src/contexts/DialogsProvider.tsx +2 -2
- package/src/{components/FireCMSAppBar.tsx → core/DefaultAppBar.tsx} +28 -30
- package/src/core/DefaultDrawer.tsx +183 -0
- package/src/core/DrawerNavigationItem.tsx +31 -27
- package/src/core/EntityEditView.tsx +712 -145
- package/src/core/EntitySidePanel.tsx +0 -1
- package/src/core/FireCMS.tsx +2 -2
- package/src/core/NavigationRoutes.tsx +4 -4
- package/src/core/SideDialogs.tsx +1 -0
- package/src/core/field_configs.tsx +5 -5
- package/src/core/index.tsx +2 -2
- package/src/form/PropertyFieldBinding.tsx +53 -19
- package/src/form/components/CustomIdField.tsx +4 -2
- package/src/form/components/FieldHelperText.tsx +4 -4
- package/src/form/components/FormikArrayContainer.tsx +4 -1
- package/src/form/components/LabelWithIcon.tsx +27 -19
- package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
- package/src/form/components/StorageItemPreview.tsx +20 -10
- package/src/form/components/StorageUploadProgress.tsx +0 -1
- package/src/form/components/index.tsx +1 -0
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +26 -15
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +28 -25
- package/src/form/field_bindings/BlockFieldBinding.tsx +13 -11
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -14
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +48 -42
- package/src/form/field_bindings/MapFieldBinding.tsx +17 -17
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +150 -0
- package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +25 -20
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +9 -14
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +27 -18
- package/src/form/field_bindings/RepeatFieldBinding.tsx +32 -19
- package/src/form/field_bindings/SelectFieldBinding.tsx +17 -10
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +33 -43
- package/src/form/field_bindings/SwitchFieldBinding.tsx +9 -5
- package/src/form/field_bindings/TextFieldBinding.tsx +26 -23
- package/src/form/index.tsx +4 -9
- package/src/form/useClearRestoreValue.tsx +2 -2
- package/src/form/validation.ts +1 -17
- package/src/hooks/data/delete.ts +2 -1
- package/src/hooks/data/save.ts +5 -2
- package/src/hooks/data/useDataSource.tsx +11 -3
- package/src/hooks/useBuildNavigationController.tsx +10 -3
- package/src/hooks/useProjectLog.tsx +18 -7
- package/src/index.ts +1 -0
- package/src/internal/useBuildDataSource.ts +69 -74
- package/src/internal/useBuildSideDialogsController.tsx +1 -0
- package/src/internal/useBuildSideEntityController.tsx +17 -4
- package/src/internal/useUnsavedChangesDialog.tsx +3 -1
- package/src/preview/PropertyPreview.tsx +7 -4
- package/src/preview/PropertyPreviewProps.tsx +7 -1
- package/src/preview/components/BooleanPreview.tsx +1 -1
- package/src/preview/components/EnumValuesChip.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +24 -34
- package/src/preview/components/ReferencePreview.tsx +2 -12
- package/src/preview/components/StorageThumbnail.tsx +5 -1
- package/src/preview/components/UrlComponentPreview.tsx +44 -11
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +1 -1
- package/src/preview/property_previews/MapPropertyPreview.tsx +1 -1
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +2 -2
- package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
- package/src/preview/util.ts +2 -2
- package/src/types/auth.tsx +2 -2
- package/src/types/collections.ts +29 -4
- package/src/types/customization_controller.tsx +0 -1
- package/src/types/datasource.ts +62 -43
- package/src/types/entities.ts +2 -0
- package/src/types/entity_overrides.tsx +2 -2
- package/src/types/fields.tsx +51 -45
- package/src/types/navigation.ts +1 -0
- package/src/types/plugins.tsx +12 -3
- package/src/types/properties.ts +25 -19
- package/src/types/side_dialogs_controller.tsx +13 -0
- package/src/types/storage.ts +82 -0
- package/src/util/entities.ts +5 -4
- package/src/util/icon_list.ts +14 -9
- package/src/util/icons.tsx +8 -2
- package/src/util/index.ts +1 -0
- package/src/util/objects.ts +17 -7
- package/src/util/permissions.ts +1 -0
- package/src/util/plurals.ts +0 -2
- package/src/util/property_utils.tsx +1 -1
- package/src/util/references.ts +3 -0
- package/src/util/resolutions.ts +43 -11
- package/src/util/storage.ts +79 -21
- package/src/util/useStorageUploadController.tsx +33 -7
- package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
- package/dist/core/Drawer.d.ts +0 -16
- package/dist/core/Scaffold.d.ts +0 -51
- package/dist/form/EntityForm.d.ts +0 -77
- package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
- package/src/components/PropertyIdCopyTooltipContent.tsx +0 -27
- package/src/core/Drawer.tsx +0 -139
- package/src/form/EntityForm.tsx +0 -736
- 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
|
|
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
|
-
|
|
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
|
|
109
|
-
|
|
110
|
+
const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
|
|
111
|
+
|
|
112
|
+
if (!usedDelegate.listenCollection)
|
|
110
113
|
throw Error("useBuildDataSource delegate not initialised");
|
|
111
114
|
|
|
112
|
-
return
|
|
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
|
-
|
|
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> =>
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
170
|
+
const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
|
|
171
|
+
|
|
172
|
+
if (!usedDelegate.listenEntity)
|
|
165
173
|
throw Error("useBuildDataSource delegate not initialised");
|
|
166
174
|
|
|
167
|
-
return
|
|
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 =
|
|
218
|
+
const firestoreValues = usedDelegate.cmsToDelegateModel(
|
|
209
219
|
values,
|
|
210
220
|
);
|
|
211
221
|
|
|
212
|
-
const
|
|
222
|
+
const updatedValues: EntityValues<M> = properties
|
|
213
223
|
? updateDateAutoValues(
|
|
214
224
|
{
|
|
215
225
|
inputValues: firestoreValues,
|
|
216
226
|
properties,
|
|
217
227
|
status,
|
|
218
|
-
timestampNowValue:
|
|
219
|
-
setDateToMidnight:
|
|
228
|
+
timestampNowValue: usedDelegate.currentTime?.() ?? new Date(),
|
|
229
|
+
setDateToMidnight: usedDelegate.setDateToMidnight
|
|
220
230
|
})
|
|
221
231
|
: firestoreValues;
|
|
222
232
|
|
|
223
|
-
return
|
|
233
|
+
return usedDelegate.saveEntity({
|
|
224
234
|
path,
|
|
235
|
+
collection,
|
|
225
236
|
entityId,
|
|
226
|
-
values:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
306
|
+
const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
|
|
307
|
+
return usedDelegate.countEntities!({
|
|
288
308
|
path,
|
|
289
309
|
filter,
|
|
290
310
|
orderBy,
|
|
291
311
|
order,
|
|
292
|
-
|
|
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
|
-
// }
|
|
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef } from "react";
|
|
|
2
2
|
import {
|
|
3
3
|
EntityCollection,
|
|
4
4
|
EntitySidePanelProps,
|
|
5
|
-
NavigationController,
|
|
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
|
|
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:
|
|
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
|
-
|
|
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={
|
|
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" | "
|
|
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 === "
|
|
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: "
|
|
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
|
|
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 === "
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
</
|
|
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-
|
|
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 =
|
|
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
|
-
}
|
|
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);
|