@firecms/core 3.0.0-canary.50 → 3.0.0-canary.51
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/core/Drawer.d.ts +5 -12
- package/dist/core/DrawerNavigationItem.d.ts +9 -0
- package/dist/core/Scaffold.d.ts +6 -9
- package/dist/core/index.d.ts +3 -4
- package/dist/hooks/index.d.ts +1 -0
- package/dist/index.es.js +708 -690
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +5 -5
- package/dist/index.umd.js.map +1 -1
- package/dist/util/icon_synonyms.d.ts +1 -0
- package/package.json +4 -4
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +526 -525
- package/src/components/EntityView.tsx +1 -1
- package/src/components/PropertyIdCopyTooltipContent.tsx +2 -3
- package/src/components/ReferenceWidget.tsx +1 -1
- package/src/components/common/types.tsx +1 -1
- package/src/core/Drawer.tsx +14 -66
- package/src/core/DrawerNavigationItem.tsx +62 -0
- package/src/core/FireCMS.tsx +4 -4
- package/src/core/Scaffold.tsx +75 -61
- package/src/core/index.tsx +3 -4
- package/src/form/EntityForm.tsx +2 -1
- package/src/hooks/index.tsx +1 -0
- package/src/types/storage.ts +1 -1
- package/src/util/icon_synonyms.ts +3 -2
- package/dist/internal/useBuildCustomizationController.d.ts +0 -2
- package/src/internal/useBuildCustomizationController.tsx +0 -5
|
@@ -134,559 +134,560 @@ export const EntityCollectionView = React.memo(
|
|
|
134
134
|
}: EntityCollectionViewProps<M>
|
|
135
135
|
) {
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const containerRef = React.useRef<HTMLDivElement>(null);
|
|
148
|
-
|
|
149
|
-
const collection = useMemo(() => {
|
|
150
|
-
const userOverride = userConfigPersistence?.getCollectionConfig<M>(fullPath);
|
|
151
|
-
return (userOverride ? mergeDeep(collectionProp, userOverride) : collectionProp) as EntityCollection<M>;
|
|
152
|
-
}, [collectionProp, fullPath, userConfigPersistence?.getCollectionConfig]);
|
|
153
|
-
|
|
154
|
-
const collectionRef = React.useRef(collection);
|
|
155
|
-
useEffect(() => {
|
|
156
|
-
collectionRef.current = collection;
|
|
157
|
-
}, [collection]);
|
|
158
|
-
|
|
159
|
-
const canCreateEntities = canCreateEntity(collection, authController, fullPath, null);
|
|
160
|
-
const [selectedNavigationEntity, setSelectedNavigationEntity] = useState<Entity<M> | undefined>(undefined);
|
|
161
|
-
const [deleteEntityClicked, setDeleteEntityClicked] = React.useState<Entity<M> | Entity<M>[] | undefined>(undefined);
|
|
162
|
-
|
|
163
|
-
const [lastDeleteTimestamp, setLastDeleteTimestamp] = React.useState<number>(0);
|
|
164
|
-
|
|
165
|
-
// number of entities in the collection
|
|
166
|
-
const [docsCount, setDocsCount] = useState<number>(0);
|
|
167
|
-
|
|
168
|
-
const unselectNavigatedEntity = useCallback(() => {
|
|
169
|
-
const currentSelection = selectedNavigationEntity;
|
|
170
|
-
setTimeout(() => {
|
|
171
|
-
if (currentSelection === selectedNavigationEntity)
|
|
172
|
-
setSelectedNavigationEntity(undefined);
|
|
173
|
-
}, 2400);
|
|
174
|
-
}, [selectedNavigationEntity]);
|
|
175
|
-
|
|
176
|
-
const checkInlineEditing = useCallback((entity?: Entity<any>): boolean => {
|
|
177
|
-
const collection = collectionRef.current;
|
|
178
|
-
if (!canEditEntity(collection, authController, fullPath, entity ?? null)) {
|
|
179
|
-
return false;
|
|
180
|
-
}
|
|
181
|
-
return collection.inlineEditing === undefined || collection.inlineEditing;
|
|
182
|
-
}, [authController, fullPath]);
|
|
137
|
+
const context = useFireCMSContext();
|
|
138
|
+
console.debug("EntityCollectionView context", context.customizationController.propertyConfigs);
|
|
139
|
+
const fullPath = fullPathProp ?? collectionProp.path;
|
|
140
|
+
const dataSource = useDataSource(collectionProp);
|
|
141
|
+
const navigation = useNavigationController();
|
|
142
|
+
const sideEntityController = useSideEntityController();
|
|
143
|
+
const authController = useAuthController();
|
|
144
|
+
const userConfigPersistence = useUserConfigurationPersistence();
|
|
145
|
+
const analyticsController = useAnalyticsController();
|
|
146
|
+
const customizationController = useCustomizationController();
|
|
183
147
|
|
|
184
|
-
|
|
185
|
-
const hoverRow = !checkInlineEditing();
|
|
148
|
+
const containerRef = React.useRef<HTMLDivElement>(null);
|
|
186
149
|
|
|
187
|
-
|
|
150
|
+
const collection = useMemo(() => {
|
|
151
|
+
const userOverride = userConfigPersistence?.getCollectionConfig<M>(fullPath);
|
|
152
|
+
return (userOverride ? mergeDeep(collectionProp, userOverride) : collectionProp) as EntityCollection<M>;
|
|
153
|
+
}, [collectionProp, fullPath, userConfigPersistence?.getCollectionConfig]);
|
|
188
154
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
155
|
+
const collectionRef = React.useRef(collection);
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
collectionRef.current = collection;
|
|
158
|
+
}, [collection]);
|
|
159
|
+
|
|
160
|
+
const canCreateEntities = canCreateEntity(collection, authController, fullPath, null);
|
|
161
|
+
const [selectedNavigationEntity, setSelectedNavigationEntity] = useState<Entity<M> | undefined>(undefined);
|
|
162
|
+
const [deleteEntityClicked, setDeleteEntityClicked] = React.useState<Entity<M> | Entity<M>[] | undefined>(undefined);
|
|
163
|
+
|
|
164
|
+
const [lastDeleteTimestamp, setLastDeleteTimestamp] = React.useState<number>(0);
|
|
165
|
+
|
|
166
|
+
// number of entities in the collection
|
|
167
|
+
const [docsCount, setDocsCount] = useState<number>(0);
|
|
168
|
+
|
|
169
|
+
const unselectNavigatedEntity = useCallback(() => {
|
|
170
|
+
const currentSelection = selectedNavigationEntity;
|
|
171
|
+
setTimeout(() => {
|
|
172
|
+
if (currentSelection === selectedNavigationEntity)
|
|
173
|
+
setSelectedNavigationEntity(undefined);
|
|
174
|
+
}, 2400);
|
|
175
|
+
}, [selectedNavigationEntity]);
|
|
176
|
+
|
|
177
|
+
const checkInlineEditing = useCallback((entity?: Entity<any>): boolean => {
|
|
178
|
+
const collection = collectionRef.current;
|
|
179
|
+
if (!canEditEntity(collection, authController, fullPath, entity ?? null)) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
return collection.inlineEditing === undefined || collection.inlineEditing;
|
|
183
|
+
}, [authController, fullPath]);
|
|
196
184
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}, [selectedEntities]);
|
|
185
|
+
const selectionEnabled = collection.selectionEnabled === undefined || collection.selectionEnabled;
|
|
186
|
+
const hoverRow = !checkInlineEditing();
|
|
200
187
|
|
|
201
|
-
|
|
202
|
-
|
|
188
|
+
const [popOverOpen, setPopOverOpen] = useState(false);
|
|
189
|
+
|
|
190
|
+
const selectionController = useSelectionController<M>();
|
|
191
|
+
const usedSelectionController = collection.selectionController ?? selectionController;
|
|
192
|
+
const {
|
|
193
|
+
selectedEntities,
|
|
194
|
+
isEntitySelected,
|
|
195
|
+
setSelectedEntities
|
|
196
|
+
} = usedSelectionController;
|
|
197
|
+
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
setDeleteEntityClicked(undefined);
|
|
200
|
+
}, [selectedEntities]);
|
|
201
|
+
|
|
202
|
+
const tableController = useDataSourceEntityCollectionTableController<M>({
|
|
203
|
+
fullPath,
|
|
204
|
+
collection,
|
|
205
|
+
lastDeleteTimestamp
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
const tableKey = React.useRef<string>(Math.random().toString(36));
|
|
209
|
+
const popupCell = tableController.popupCell;
|
|
210
|
+
|
|
211
|
+
const onPopupClose = useCallback(() => {
|
|
212
|
+
tableController.setPopupCell?.(undefined);
|
|
213
|
+
}, [tableController.setPopupCell]);
|
|
214
|
+
|
|
215
|
+
const onEntityClick = useCallback((clickedEntity: Entity<M>) => {
|
|
216
|
+
console.log("Entity clicked", clickedEntity)
|
|
217
|
+
const collection = collectionRef.current;
|
|
218
|
+
setSelectedNavigationEntity(clickedEntity);
|
|
219
|
+
analyticsController.onAnalyticsEvent?.("edit_entity_clicked", {
|
|
220
|
+
path: clickedEntity.path,
|
|
221
|
+
entityId: clickedEntity.id
|
|
222
|
+
});
|
|
223
|
+
return sideEntityController.open({
|
|
224
|
+
entityId: clickedEntity.id,
|
|
225
|
+
path: clickedEntity.path,
|
|
203
226
|
collection,
|
|
204
|
-
|
|
227
|
+
updateUrl: true,
|
|
228
|
+
onClose: unselectNavigatedEntity,
|
|
205
229
|
});
|
|
230
|
+
}, [unselectNavigatedEntity, sideEntityController]);
|
|
206
231
|
|
|
207
|
-
|
|
208
|
-
const popupCell = tableController.popupCell;
|
|
209
|
-
|
|
210
|
-
const onPopupClose = useCallback(() => {
|
|
211
|
-
tableController.setPopupCell?.(undefined);
|
|
212
|
-
}, [tableController.setPopupCell]);
|
|
213
|
-
|
|
214
|
-
const onEntityClick = useCallback((clickedEntity: Entity<M>) => {
|
|
215
|
-
console.log("Entity clicked", clickedEntity)
|
|
216
|
-
const collection = collectionRef.current;
|
|
217
|
-
setSelectedNavigationEntity(clickedEntity);
|
|
218
|
-
analyticsController.onAnalyticsEvent?.("edit_entity_clicked", {
|
|
219
|
-
path: clickedEntity.path,
|
|
220
|
-
entityId: clickedEntity.id
|
|
221
|
-
});
|
|
222
|
-
return sideEntityController.open({
|
|
223
|
-
entityId: clickedEntity.id,
|
|
224
|
-
path: clickedEntity.path,
|
|
225
|
-
collection,
|
|
226
|
-
updateUrl: true,
|
|
227
|
-
onClose: unselectNavigatedEntity,
|
|
228
|
-
});
|
|
229
|
-
}, [unselectNavigatedEntity, sideEntityController]);
|
|
230
|
-
|
|
231
|
-
const onNewClick = useCallback(() => {
|
|
232
|
-
|
|
233
|
-
const collection = collectionRef.current;
|
|
234
|
-
analyticsController.onAnalyticsEvent?.("new_entity_click", {
|
|
235
|
-
path: fullPath
|
|
236
|
-
});
|
|
237
|
-
sideEntityController.open({
|
|
238
|
-
path: fullPath,
|
|
239
|
-
collection,
|
|
240
|
-
updateUrl: true,
|
|
241
|
-
onClose: unselectNavigatedEntity,
|
|
242
|
-
});
|
|
243
|
-
}, [fullPath, sideEntityController]);
|
|
244
|
-
|
|
245
|
-
const onMultipleDeleteClick = () => {
|
|
246
|
-
analyticsController.onAnalyticsEvent?.("multiple_delete_dialog_open", {
|
|
247
|
-
path: fullPath
|
|
248
|
-
});
|
|
249
|
-
setDeleteEntityClicked(selectedEntities);
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
const internalOnEntityDelete = (_path: string, entity: Entity<M>) => {
|
|
253
|
-
analyticsController.onAnalyticsEvent?.("single_entity_deleted", {
|
|
254
|
-
path: fullPath
|
|
255
|
-
});
|
|
256
|
-
setSelectedEntities((selectedEntities) => selectedEntities.filter((e) => e.id !== entity.id));
|
|
257
|
-
setLastDeleteTimestamp(Date.now());
|
|
258
|
-
};
|
|
232
|
+
const onNewClick = useCallback(() => {
|
|
259
233
|
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
234
|
+
const collection = collectionRef.current;
|
|
235
|
+
analyticsController.onAnalyticsEvent?.("new_entity_click", {
|
|
236
|
+
path: fullPath
|
|
237
|
+
});
|
|
238
|
+
sideEntityController.open({
|
|
239
|
+
path: fullPath,
|
|
240
|
+
collection,
|
|
241
|
+
updateUrl: true,
|
|
242
|
+
onClose: unselectNavigatedEntity,
|
|
243
|
+
});
|
|
244
|
+
}, [fullPath, sideEntityController]);
|
|
268
245
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
246
|
+
const onMultipleDeleteClick = () => {
|
|
247
|
+
analyticsController.onAnalyticsEvent?.("multiple_delete_dialog_open", {
|
|
248
|
+
path: fullPath
|
|
249
|
+
});
|
|
250
|
+
setDeleteEntityClicked(selectedEntities);
|
|
251
|
+
};
|
|
274
252
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
253
|
+
const internalOnEntityDelete = (_path: string, entity: Entity<M>) => {
|
|
254
|
+
analyticsController.onAnalyticsEvent?.("single_entity_deleted", {
|
|
255
|
+
path: fullPath
|
|
256
|
+
});
|
|
257
|
+
setSelectedEntities((selectedEntities) => selectedEntities.filter((e) => e.id !== entity.id));
|
|
258
|
+
setLastDeleteTimestamp(Date.now());
|
|
259
|
+
};
|
|
279
260
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const onSizeChanged = useCallback((size: CollectionSize) => {
|
|
301
|
-
if (userConfigPersistence)
|
|
302
|
-
onCollectionModifiedForUser(fullPath, { defaultSize: size })
|
|
303
|
-
}, [onCollectionModifiedForUser, fullPath, userConfigPersistence]);
|
|
304
|
-
|
|
305
|
-
const createEnabled = canCreateEntity(collection, authController, fullPath, null);
|
|
306
|
-
|
|
307
|
-
const uniqueFieldValidator: UniqueFieldValidator = useCallback(
|
|
308
|
-
({
|
|
309
|
-
name,
|
|
310
|
-
value,
|
|
311
|
-
property,
|
|
312
|
-
entityId
|
|
313
|
-
}) => dataSource.checkUniqueField(fullPath, name, value, entityId),
|
|
314
|
-
[fullPath]);
|
|
315
|
-
|
|
316
|
-
const onValueChange: OnCellValueChange<any, any> = ({
|
|
317
|
-
value,
|
|
318
|
-
propertyKey,
|
|
319
|
-
onValueUpdated,
|
|
320
|
-
setError,
|
|
321
|
-
data: entity,
|
|
322
|
-
}) => {
|
|
323
|
-
|
|
324
|
-
const updatedValues = setIn({ ...entity.values }, propertyKey, value);
|
|
325
|
-
|
|
326
|
-
const saveProps: SaveEntityProps = {
|
|
327
|
-
path: fullPath,
|
|
328
|
-
entityId: entity.id,
|
|
329
|
-
values: updatedValues,
|
|
330
|
-
previousValues: entity.values,
|
|
331
|
-
collection,
|
|
332
|
-
status: "existing"
|
|
333
|
-
};
|
|
261
|
+
const internalOnMultipleEntitiesDelete = (_path: string, entities: Entity<M>[]) => {
|
|
262
|
+
analyticsController.onAnalyticsEvent?.("multiple_entities_deleted", {
|
|
263
|
+
path: fullPath
|
|
264
|
+
});
|
|
265
|
+
setSelectedEntities([]);
|
|
266
|
+
setDeleteEntityClicked(undefined);
|
|
267
|
+
setLastDeleteTimestamp(Date.now());
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
let AddColumnComponent: React.ComponentType<{
|
|
271
|
+
fullPath: string,
|
|
272
|
+
parentCollectionIds: string[],
|
|
273
|
+
collection: EntityCollection;
|
|
274
|
+
}> | undefined
|
|
275
|
+
|
|
276
|
+
// we are only using the first plugin that implements this
|
|
277
|
+
if (customizationController?.plugins) {
|
|
278
|
+
AddColumnComponent = customizationController.plugins.find(plugin => plugin.collectionView?.AddColumnComponent)?.collectionView?.AddColumnComponent;
|
|
279
|
+
}
|
|
334
280
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
onValueUpdated();
|
|
343
|
-
},
|
|
344
|
-
onSaveFailure: (e: Error) => {
|
|
345
|
-
console.error("Save failure");
|
|
346
|
-
console.error(e);
|
|
347
|
-
setError(e);
|
|
348
|
-
}
|
|
349
|
-
});
|
|
281
|
+
const onCollectionModifiedForUser = useCallback((path: string, partialCollection: PartialEntityCollection<M>) => {
|
|
282
|
+
if (userConfigPersistence) {
|
|
283
|
+
const currentStoredConfig = userConfigPersistence.getCollectionConfig(path);
|
|
284
|
+
const updatedConfig = mergeDeep(currentStoredConfig, partialCollection);
|
|
285
|
+
userConfigPersistence.onCollectionModified(path, updatedConfig);
|
|
286
|
+
}
|
|
287
|
+
}, [userConfigPersistence]);
|
|
350
288
|
|
|
289
|
+
const onColumnResize = useCallback(({
|
|
290
|
+
width,
|
|
291
|
+
key
|
|
292
|
+
}: OnColumnResizeParams) => {
|
|
293
|
+
|
|
294
|
+
const collection = collectionRef.current;
|
|
295
|
+
// Only for property columns
|
|
296
|
+
if (!getPropertyInPath(collection.properties, key)) return;
|
|
297
|
+
const localCollection = buildPropertyWidthOverwrite(key, width);
|
|
298
|
+
onCollectionModifiedForUser(fullPath, localCollection);
|
|
299
|
+
}, [onCollectionModifiedForUser, fullPath]);
|
|
300
|
+
|
|
301
|
+
const onSizeChanged = useCallback((size: CollectionSize) => {
|
|
302
|
+
if (userConfigPersistence)
|
|
303
|
+
onCollectionModifiedForUser(fullPath, { defaultSize: size })
|
|
304
|
+
}, [onCollectionModifiedForUser, fullPath, userConfigPersistence]);
|
|
305
|
+
|
|
306
|
+
const createEnabled = canCreateEntity(collection, authController, fullPath, null);
|
|
307
|
+
|
|
308
|
+
const uniqueFieldValidator: UniqueFieldValidator = useCallback(
|
|
309
|
+
({
|
|
310
|
+
name,
|
|
311
|
+
value,
|
|
312
|
+
property,
|
|
313
|
+
entityId
|
|
314
|
+
}) => dataSource.checkUniqueField(fullPath, name, value, entityId),
|
|
315
|
+
[fullPath]);
|
|
316
|
+
|
|
317
|
+
const onValueChange: OnCellValueChange<any, any> = ({
|
|
318
|
+
value,
|
|
319
|
+
propertyKey,
|
|
320
|
+
onValueUpdated,
|
|
321
|
+
setError,
|
|
322
|
+
data: entity,
|
|
323
|
+
}) => {
|
|
324
|
+
|
|
325
|
+
const updatedValues = setIn({ ...entity.values }, propertyKey, value);
|
|
326
|
+
|
|
327
|
+
const saveProps: SaveEntityProps = {
|
|
328
|
+
path: fullPath,
|
|
329
|
+
entityId: entity.id,
|
|
330
|
+
values: updatedValues,
|
|
331
|
+
previousValues: entity.values,
|
|
332
|
+
collection,
|
|
333
|
+
status: "existing"
|
|
351
334
|
};
|
|
352
335
|
|
|
353
|
-
|
|
354
|
-
|
|
336
|
+
return saveEntityWithCallbacks({
|
|
337
|
+
...saveProps,
|
|
355
338
|
collection,
|
|
339
|
+
dataSource,
|
|
340
|
+
context,
|
|
341
|
+
onSaveSuccess: () => {
|
|
342
|
+
setError(undefined);
|
|
343
|
+
onValueUpdated();
|
|
344
|
+
},
|
|
345
|
+
onSaveFailure: (e: Error) => {
|
|
346
|
+
console.error("Save failure");
|
|
347
|
+
console.error(e);
|
|
348
|
+
setError(e);
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
const resolvedFullPath = navigation.resolveAliasesFrom(fullPath);
|
|
355
|
+
const resolvedCollection = useMemo(() => resolveCollection<M>({
|
|
356
|
+
collection,
|
|
357
|
+
path: fullPath,
|
|
358
|
+
fields: customizationController.propertyConfigs
|
|
359
|
+
}), [collection, fullPath]);
|
|
360
|
+
|
|
361
|
+
const getPropertyFor = useCallback(({
|
|
362
|
+
propertyKey,
|
|
363
|
+
entity
|
|
364
|
+
}: GetPropertyForProps<M>) => {
|
|
365
|
+
let propertyOrBuilder: PropertyOrBuilder<any, M> | undefined = getPropertyInPath<M>(collection.properties, propertyKey);
|
|
366
|
+
|
|
367
|
+
// we might not find the property in the collection if combining property builders and map spread
|
|
368
|
+
if (!propertyOrBuilder) {
|
|
369
|
+
// these 2 properties are coming from the resolved collection with default values
|
|
370
|
+
propertyOrBuilder = getPropertyInPath<M>(resolvedCollection.properties, propertyKey);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return resolveProperty({
|
|
374
|
+
propertyKey,
|
|
375
|
+
propertyOrBuilder,
|
|
356
376
|
path: fullPath,
|
|
377
|
+
values: entity.values,
|
|
378
|
+
entityId: entity.id,
|
|
357
379
|
fields: customizationController.propertyConfigs
|
|
358
|
-
})
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
380
|
+
});
|
|
381
|
+
}, [collection.properties, customizationController.propertyConfigs, fullPath, resolvedCollection.properties]);
|
|
382
|
+
|
|
383
|
+
const displayedColumnIds = useColumnIds(resolvedCollection, true);
|
|
384
|
+
|
|
385
|
+
const additionalFields = useMemo(() => {
|
|
386
|
+
const subcollectionColumns: AdditionalFieldDelegate<M, any>[] = collection.subcollections?.map((subcollection) => {
|
|
387
|
+
return {
|
|
388
|
+
key: getSubcollectionColumnId(subcollection),
|
|
389
|
+
name: subcollection.name,
|
|
390
|
+
width: 200,
|
|
391
|
+
dependencies: [],
|
|
392
|
+
Builder: ({ entity }) => (
|
|
393
|
+
<Button color={"primary"}
|
|
394
|
+
variant={"outlined"}
|
|
395
|
+
startIcon={<KeyboardTabIcon size={"small"}/>}
|
|
396
|
+
onClick={(event: any) => {
|
|
397
|
+
event.stopPropagation();
|
|
398
|
+
sideEntityController.open({
|
|
399
|
+
path: fullPath,
|
|
400
|
+
entityId: entity.id,
|
|
401
|
+
selectedSubPath: subcollection.id ?? subcollection.path,
|
|
402
|
+
collection,
|
|
403
|
+
updateUrl: true,
|
|
404
|
+
});
|
|
405
|
+
}}>
|
|
406
|
+
{subcollection.name}
|
|
407
|
+
</Button>
|
|
408
|
+
)
|
|
409
|
+
};
|
|
410
|
+
}) ?? [];
|
|
411
|
+
|
|
412
|
+
const collectionGroupParentCollections: AdditionalFieldDelegate<M, any>[] = collection.collectionGroup
|
|
413
|
+
? [{
|
|
414
|
+
key: COLLECTION_GROUP_PARENT_ID,
|
|
415
|
+
name: "Parent entities",
|
|
416
|
+
width: 260,
|
|
417
|
+
dependencies: [],
|
|
418
|
+
Builder: ({ entity }) => {
|
|
419
|
+
const collectionsWithPath = navigation.getParentReferencesFromPath(entity.path);
|
|
420
|
+
return (
|
|
421
|
+
<>
|
|
422
|
+
{collectionsWithPath.map((reference) => {
|
|
423
|
+
return (
|
|
424
|
+
<ReferencePreview
|
|
425
|
+
key={reference.path + "/" + reference.id}
|
|
426
|
+
reference={reference}
|
|
427
|
+
size={"tiny"}/>
|
|
428
|
+
);
|
|
429
|
+
})}
|
|
430
|
+
</>
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
}]
|
|
434
|
+
: [];
|
|
435
|
+
|
|
436
|
+
return [
|
|
437
|
+
...(collection.additionalFields ?? []),
|
|
438
|
+
...subcollectionColumns,
|
|
439
|
+
...collectionGroupParentCollections
|
|
440
|
+
];
|
|
441
|
+
}, [collection, fullPath, sideEntityController]);
|
|
442
|
+
|
|
443
|
+
const updateLastDeleteTimestamp = useCallback(() => {
|
|
444
|
+
setLastDeleteTimestamp(Date.now());
|
|
445
|
+
}, []);
|
|
446
|
+
|
|
447
|
+
const largeLayout = useLargeLayout();
|
|
448
|
+
|
|
449
|
+
const getActionsForEntity = ({
|
|
450
|
+
entity,
|
|
451
|
+
customEntityActions
|
|
452
|
+
}: {
|
|
453
|
+
entity?: Entity<M>,
|
|
454
|
+
customEntityActions?: EntityAction[]
|
|
455
|
+
}): EntityAction[] => {
|
|
456
|
+
const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPath, entity) : true;
|
|
457
|
+
const actions: EntityAction[] = [editEntityAction];
|
|
458
|
+
if (createEnabled)
|
|
459
|
+
actions.push(copyEntityAction);
|
|
460
|
+
if (deleteEnabled)
|
|
461
|
+
actions.push(deleteEntityAction);
|
|
462
|
+
if (customEntityActions)
|
|
463
|
+
actions.push(...customEntityActions);
|
|
464
|
+
return actions;
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
const getIdColumnWidth = () => {
|
|
468
|
+
const entityActions = getActionsForEntity({});
|
|
469
|
+
const collapsedActions = entityActions.filter(a => a.collapsed !== false);
|
|
470
|
+
const uncollapsedActions = entityActions.filter(a => a.collapsed === false);
|
|
471
|
+
const actionsWidth = uncollapsedActions.length * (largeLayout ? 40 : 30);
|
|
472
|
+
return (largeLayout ? (80 + actionsWidth) : (70 + actionsWidth)) + (collapsedActions.length > 0 ? (largeLayout ? 40 : 30) : 0);
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
const tableRowActionsBuilder = ({
|
|
476
|
+
entity,
|
|
477
|
+
size,
|
|
478
|
+
width,
|
|
479
|
+
frozen
|
|
480
|
+
}: {
|
|
481
|
+
entity: Entity<any>,
|
|
482
|
+
size: CollectionSize,
|
|
483
|
+
width: number,
|
|
484
|
+
frozen?: boolean
|
|
485
|
+
}) => {
|
|
486
|
+
|
|
487
|
+
const isSelected = isEntitySelected(entity);
|
|
488
|
+
|
|
489
|
+
const actions = getActionsForEntity({
|
|
490
|
+
entity,
|
|
491
|
+
customEntityActions: collection.entityActions
|
|
492
|
+
});
|
|
371
493
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
dependencies: [],
|
|
391
|
-
Builder: ({ entity }) => (
|
|
392
|
-
<Button color={"primary"}
|
|
393
|
-
variant={"outlined"}
|
|
394
|
-
startIcon={<KeyboardTabIcon size={"small"}/>}
|
|
395
|
-
onClick={(event: any) => {
|
|
396
|
-
event.stopPropagation();
|
|
397
|
-
sideEntityController.open({
|
|
398
|
-
path: fullPath,
|
|
399
|
-
entityId: entity.id,
|
|
400
|
-
selectedSubPath: subcollection.id ?? subcollection.path,
|
|
401
|
-
collection,
|
|
402
|
-
updateUrl: true,
|
|
403
|
-
});
|
|
404
|
-
}}>
|
|
405
|
-
{subcollection.name}
|
|
406
|
-
</Button>
|
|
407
|
-
)
|
|
408
|
-
};
|
|
409
|
-
}) ?? [];
|
|
410
|
-
|
|
411
|
-
const collectionGroupParentCollections: AdditionalFieldDelegate<M, any>[] = collection.collectionGroup
|
|
412
|
-
? [{
|
|
413
|
-
key: COLLECTION_GROUP_PARENT_ID,
|
|
414
|
-
name: "Parent entities",
|
|
415
|
-
width: 260,
|
|
416
|
-
dependencies: [],
|
|
417
|
-
Builder: ({ entity }) => {
|
|
418
|
-
const collectionsWithPath = navigation.getParentReferencesFromPath(entity.path);
|
|
419
|
-
return (
|
|
420
|
-
<>
|
|
421
|
-
{collectionsWithPath.map((reference) => {
|
|
422
|
-
return (
|
|
423
|
-
<ReferencePreview
|
|
424
|
-
key={reference.path + "/" + reference.id}
|
|
425
|
-
reference={reference}
|
|
426
|
-
size={"tiny"}/>
|
|
427
|
-
);
|
|
428
|
-
})}
|
|
429
|
-
</>
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
}]
|
|
433
|
-
: [];
|
|
434
|
-
|
|
435
|
-
return [
|
|
436
|
-
...(collection.additionalFields ?? []),
|
|
437
|
-
...subcollectionColumns,
|
|
438
|
-
...collectionGroupParentCollections
|
|
439
|
-
];
|
|
440
|
-
}, [collection, fullPath, sideEntityController]);
|
|
441
|
-
|
|
442
|
-
const updateLastDeleteTimestamp = useCallback(() => {
|
|
443
|
-
setLastDeleteTimestamp(Date.now());
|
|
444
|
-
}, []);
|
|
445
|
-
|
|
446
|
-
const largeLayout = useLargeLayout();
|
|
447
|
-
|
|
448
|
-
const getActionsForEntity = ({
|
|
449
|
-
entity,
|
|
450
|
-
customEntityActions
|
|
451
|
-
}: {
|
|
452
|
-
entity?: Entity<M>,
|
|
453
|
-
customEntityActions?: EntityAction[]
|
|
454
|
-
}): EntityAction[] => {
|
|
455
|
-
const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPath, entity) : true;
|
|
456
|
-
const actions: EntityAction[] = [editEntityAction];
|
|
457
|
-
if (createEnabled)
|
|
458
|
-
actions.push(copyEntityAction);
|
|
459
|
-
if (deleteEnabled)
|
|
460
|
-
actions.push(deleteEntityAction);
|
|
461
|
-
if (customEntityActions)
|
|
462
|
-
actions.push(...customEntityActions);
|
|
463
|
-
return actions;
|
|
464
|
-
};
|
|
494
|
+
return (
|
|
495
|
+
<EntityCollectionRowActions
|
|
496
|
+
entity={entity}
|
|
497
|
+
width={width}
|
|
498
|
+
frozen={frozen}
|
|
499
|
+
isSelected={isSelected}
|
|
500
|
+
selectionEnabled={selectionEnabled}
|
|
501
|
+
size={size}
|
|
502
|
+
highlightEntity={setSelectedNavigationEntity}
|
|
503
|
+
unhighlightEntity={unselectNavigatedEntity}
|
|
504
|
+
collection={collection}
|
|
505
|
+
fullPath={fullPath}
|
|
506
|
+
actions={actions}
|
|
507
|
+
hideId={collection?.hideIdFromCollection}
|
|
508
|
+
onCollectionChange={updateLastDeleteTimestamp}
|
|
509
|
+
selectionController={usedSelectionController}
|
|
510
|
+
/>
|
|
511
|
+
);
|
|
465
512
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
const title = <Popover
|
|
516
|
+
open={popOverOpen}
|
|
517
|
+
onOpenChange={setPopOverOpen}
|
|
518
|
+
enabled={Boolean(collection.description)}
|
|
519
|
+
trigger={<div className="flex flex-col items-start">
|
|
520
|
+
<Typography
|
|
521
|
+
variant={"subtitle1"}
|
|
522
|
+
className={`leading-none truncate max-w-[160px] lg:max-w-[240px] ${collection.description ? "cursor-pointer" : "cursor-auto"}`}
|
|
523
|
+
onClick={collection.description
|
|
524
|
+
? (e) => {
|
|
525
|
+
setPopOverOpen(true);
|
|
526
|
+
e.stopPropagation();
|
|
527
|
+
}
|
|
528
|
+
: undefined}>
|
|
529
|
+
{`${collection.name}`}
|
|
530
|
+
</Typography>
|
|
531
|
+
|
|
532
|
+
<EntitiesCount
|
|
533
|
+
fullPath={fullPath}
|
|
534
|
+
collection={collection}
|
|
535
|
+
filter={tableController.filterValues}
|
|
536
|
+
sortBy={tableController.sortBy}
|
|
537
|
+
onCountChange={setDocsCount}
|
|
538
|
+
/>
|
|
539
|
+
|
|
540
|
+
</div>}
|
|
541
|
+
>
|
|
542
|
+
|
|
543
|
+
{collection.description && <div className="m-4 text-gray-900 dark:text-white">
|
|
544
|
+
<Markdown source={collection.description}/>
|
|
545
|
+
</div>}
|
|
546
|
+
|
|
547
|
+
</Popover>;
|
|
548
|
+
|
|
549
|
+
const buildAdditionalHeaderWidget = useCallback(({
|
|
550
|
+
property,
|
|
551
|
+
propertyKey,
|
|
552
|
+
onHover
|
|
553
|
+
}: {
|
|
554
|
+
property: ResolvedProperty,
|
|
555
|
+
propertyKey: string,
|
|
556
|
+
onHover: boolean
|
|
557
|
+
}) => {
|
|
558
|
+
const collection = collectionRef.current;
|
|
559
|
+
if (!customizationController.plugins)
|
|
560
|
+
return null;
|
|
561
|
+
return <>
|
|
562
|
+
{customizationController.plugins.filter(plugin => plugin.collectionView?.HeaderAction)
|
|
563
|
+
.map((plugin, i) => {
|
|
564
|
+
const HeaderAction = plugin.collectionView!.HeaderAction!;
|
|
565
|
+
return <HeaderAction
|
|
566
|
+
onHover={onHover}
|
|
567
|
+
key={`plugin_header_action_${i}`}
|
|
568
|
+
propertyKey={propertyKey}
|
|
569
|
+
property={property}
|
|
570
|
+
fullPath={fullPath}
|
|
571
|
+
collection={collection}
|
|
572
|
+
parentCollectionIds={parentCollectionIds ?? []}/>;
|
|
573
|
+
})}
|
|
574
|
+
</>;
|
|
575
|
+
}, [customizationController.plugins, fullPath, parentCollectionIds]);
|
|
576
|
+
|
|
577
|
+
const addColumnComponentInternal = AddColumnComponent
|
|
578
|
+
? function () {
|
|
579
|
+
if (typeof AddColumnComponent === "function")
|
|
580
|
+
return <AddColumnComponent fullPath={fullPath}
|
|
581
|
+
parentCollectionIds={parentCollectionIds ?? []}
|
|
582
|
+
collection={collection}/>;
|
|
583
|
+
return null;
|
|
584
|
+
}
|
|
585
|
+
: undefined;
|
|
586
|
+
|
|
587
|
+
const {
|
|
588
|
+
textSearchLoading,
|
|
589
|
+
textSearchInitialised,
|
|
590
|
+
onTextSearchClick,
|
|
591
|
+
textSearchEnabled
|
|
592
|
+
} = useTableSearchHelper({
|
|
593
|
+
collection,
|
|
594
|
+
fullPath: resolvedFullPath,
|
|
595
|
+
parentCollectionIds
|
|
596
|
+
});
|
|
473
597
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
size={size}
|
|
501
|
-
highlightEntity={setSelectedNavigationEntity}
|
|
502
|
-
unhighlightEntity={unselectNavigatedEntity}
|
|
598
|
+
return (
|
|
599
|
+
<div className={cn("overflow-hidden h-full w-full rounded-md", className)}
|
|
600
|
+
ref={containerRef}>
|
|
601
|
+
<EntityCollectionTable
|
|
602
|
+
key={`collection_table_${fullPath}`}
|
|
603
|
+
additionalFields={additionalFields}
|
|
604
|
+
tableController={tableController}
|
|
605
|
+
enablePopupIcon={true}
|
|
606
|
+
displayedColumnIds={displayedColumnIds}
|
|
607
|
+
onSizeChanged={onSizeChanged}
|
|
608
|
+
onEntityClick={onEntityClick}
|
|
609
|
+
onColumnResize={onColumnResize}
|
|
610
|
+
onValueChange={onValueChange}
|
|
611
|
+
tableRowActionsBuilder={tableRowActionsBuilder}
|
|
612
|
+
uniqueFieldValidator={uniqueFieldValidator}
|
|
613
|
+
title={title}
|
|
614
|
+
selectionController={usedSelectionController}
|
|
615
|
+
highlightedEntities={selectedNavigationEntity ? [selectedNavigationEntity] : []}
|
|
616
|
+
defaultSize={collection.defaultSize}
|
|
617
|
+
properties={resolvedCollection.properties}
|
|
618
|
+
getPropertyFor={getPropertyFor}
|
|
619
|
+
onTextSearchClick={textSearchInitialised ? undefined : onTextSearchClick}
|
|
620
|
+
textSearchLoading={textSearchLoading}
|
|
621
|
+
textSearchEnabled={textSearchEnabled}
|
|
622
|
+
actionsStart={<EntityCollectionViewStartActions
|
|
623
|
+
parentCollectionIds={parentCollectionIds ?? []}
|
|
503
624
|
collection={collection}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
onCollectionChange={updateLastDeleteTimestamp}
|
|
625
|
+
tableController={tableController}
|
|
626
|
+
path={fullPath}
|
|
627
|
+
relativePath={collection.path}
|
|
508
628
|
selectionController={usedSelectionController}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
};
|
|
513
|
-
|
|
514
|
-
const title = <Popover
|
|
515
|
-
open={popOverOpen}
|
|
516
|
-
onOpenChange={setPopOverOpen}
|
|
517
|
-
enabled={Boolean(collection.description)}
|
|
518
|
-
trigger={<div className="flex flex-col items-start">
|
|
519
|
-
<Typography
|
|
520
|
-
variant={"subtitle1"}
|
|
521
|
-
className={`leading-none truncate max-w-[160px] lg:max-w-[240px] ${collection.description ? "cursor-pointer" : "cursor-auto"}`}
|
|
522
|
-
onClick={collection.description
|
|
523
|
-
? (e) => {
|
|
524
|
-
setPopOverOpen(true);
|
|
525
|
-
e.stopPropagation();
|
|
526
|
-
}
|
|
527
|
-
: undefined}>
|
|
528
|
-
{`${collection.name}`}
|
|
529
|
-
</Typography>
|
|
530
|
-
|
|
531
|
-
<EntitiesCount
|
|
532
|
-
fullPath={fullPath}
|
|
629
|
+
collectionEntitiesCount={docsCount}/>}
|
|
630
|
+
actions={<EntityCollectionViewActions
|
|
631
|
+
parentCollectionIds={parentCollectionIds ?? []}
|
|
533
632
|
collection={collection}
|
|
534
|
-
filter={tableController.filterValues}
|
|
535
|
-
sortBy={tableController.sortBy}
|
|
536
|
-
onCountChange={setDocsCount}
|
|
537
|
-
/>
|
|
538
|
-
|
|
539
|
-
</div>}
|
|
540
|
-
>
|
|
541
|
-
|
|
542
|
-
{collection.description && <div className="m-4 text-gray-900 dark:text-white">
|
|
543
|
-
<Markdown source={collection.description}/>
|
|
544
|
-
</div>}
|
|
545
|
-
|
|
546
|
-
</Popover>;
|
|
547
|
-
|
|
548
|
-
const buildAdditionalHeaderWidget = useCallback(({
|
|
549
|
-
property,
|
|
550
|
-
propertyKey,
|
|
551
|
-
onHover
|
|
552
|
-
}: {
|
|
553
|
-
property: ResolvedProperty,
|
|
554
|
-
propertyKey: string,
|
|
555
|
-
onHover: boolean
|
|
556
|
-
}) => {
|
|
557
|
-
const collection = collectionRef.current;
|
|
558
|
-
if (!customizationController.plugins)
|
|
559
|
-
return null;
|
|
560
|
-
return <>
|
|
561
|
-
{customizationController.plugins.filter(plugin => plugin.collectionView?.HeaderAction)
|
|
562
|
-
.map((plugin, i) => {
|
|
563
|
-
const HeaderAction = plugin.collectionView!.HeaderAction!;
|
|
564
|
-
return <HeaderAction
|
|
565
|
-
onHover={onHover}
|
|
566
|
-
key={`plugin_header_action_${i}`}
|
|
567
|
-
propertyKey={propertyKey}
|
|
568
|
-
property={property}
|
|
569
|
-
fullPath={fullPath}
|
|
570
|
-
collection={collection}
|
|
571
|
-
parentCollectionIds={parentCollectionIds ?? []}/>;
|
|
572
|
-
})}
|
|
573
|
-
</>;
|
|
574
|
-
}, [customizationController.plugins, fullPath, parentCollectionIds]);
|
|
575
|
-
|
|
576
|
-
const addColumnComponentInternal = AddColumnComponent
|
|
577
|
-
? function () {
|
|
578
|
-
if (typeof AddColumnComponent === "function")
|
|
579
|
-
return <AddColumnComponent fullPath={fullPath}
|
|
580
|
-
parentCollectionIds={parentCollectionIds ?? []}
|
|
581
|
-
collection={collection}/>;
|
|
582
|
-
return null;
|
|
583
|
-
}
|
|
584
|
-
: undefined;
|
|
585
|
-
|
|
586
|
-
const {
|
|
587
|
-
textSearchLoading,
|
|
588
|
-
textSearchInitialised,
|
|
589
|
-
onTextSearchClick,
|
|
590
|
-
textSearchEnabled
|
|
591
|
-
} = useTableSearchHelper({
|
|
592
|
-
collection,
|
|
593
|
-
fullPath: resolvedFullPath,
|
|
594
|
-
parentCollectionIds
|
|
595
|
-
});
|
|
596
|
-
|
|
597
|
-
return (
|
|
598
|
-
<div className={cn("overflow-hidden h-full w-full rounded-md", className)}
|
|
599
|
-
ref={containerRef}>
|
|
600
|
-
<EntityCollectionTable
|
|
601
|
-
key={`collection_table_${fullPath}`}
|
|
602
|
-
additionalFields={additionalFields}
|
|
603
633
|
tableController={tableController}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
onColumnResize={onColumnResize}
|
|
609
|
-
onValueChange={onValueChange}
|
|
610
|
-
tableRowActionsBuilder={tableRowActionsBuilder}
|
|
611
|
-
uniqueFieldValidator={uniqueFieldValidator}
|
|
612
|
-
title={title}
|
|
634
|
+
onMultipleDeleteClick={onMultipleDeleteClick}
|
|
635
|
+
onNewClick={onNewClick}
|
|
636
|
+
path={fullPath}
|
|
637
|
+
relativePath={collection.path}
|
|
613
638
|
selectionController={usedSelectionController}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
getIdColumnWidth={getIdColumnWidth}
|
|
661
|
-
additionalIDHeaderWidget={<EntityIdHeaderWidget
|
|
662
|
-
path={fullPath}
|
|
663
|
-
collection={collection}/>}
|
|
664
|
-
/>
|
|
665
|
-
|
|
666
|
-
<PopupFormField
|
|
667
|
-
key={`popup_form_${popupCell?.propertyKey}_${popupCell?.entity?.id}`}
|
|
668
|
-
open={Boolean(popupCell)}
|
|
669
|
-
onClose={onPopupClose}
|
|
670
|
-
cellRect={popupCell?.cellRect}
|
|
671
|
-
propertyKey={popupCell?.propertyKey}
|
|
639
|
+
selectionEnabled={selectionEnabled}
|
|
640
|
+
collectionEntitiesCount={docsCount}
|
|
641
|
+
/>}
|
|
642
|
+
emptyComponent={canCreateEntities && tableController.filterValues === undefined && tableController.sortBy === undefined
|
|
643
|
+
? <div className="flex flex-col items-center justify-center">
|
|
644
|
+
<Typography variant={"subtitle2"}>So empty...</Typography>
|
|
645
|
+
<Button
|
|
646
|
+
color={"primary"}
|
|
647
|
+
variant={"outlined"}
|
|
648
|
+
onClick={onNewClick}
|
|
649
|
+
className="mt-4"
|
|
650
|
+
>
|
|
651
|
+
<AddIcon/>
|
|
652
|
+
Create your first entity
|
|
653
|
+
</Button>
|
|
654
|
+
</div>
|
|
655
|
+
: <Typography variant={"label"}>No results with the applied filter/sort</Typography>
|
|
656
|
+
}
|
|
657
|
+
hoverRow={hoverRow}
|
|
658
|
+
inlineEditing={checkInlineEditing()}
|
|
659
|
+
AdditionalHeaderWidget={buildAdditionalHeaderWidget}
|
|
660
|
+
AddColumnComponent={addColumnComponentInternal}
|
|
661
|
+
getIdColumnWidth={getIdColumnWidth}
|
|
662
|
+
additionalIDHeaderWidget={<EntityIdHeaderWidget
|
|
663
|
+
path={fullPath}
|
|
664
|
+
collection={collection}/>}
|
|
665
|
+
/>
|
|
666
|
+
|
|
667
|
+
<PopupFormField
|
|
668
|
+
key={`popup_form_${popupCell?.propertyKey}_${popupCell?.entity?.id}`}
|
|
669
|
+
open={Boolean(popupCell)}
|
|
670
|
+
onClose={onPopupClose}
|
|
671
|
+
cellRect={popupCell?.cellRect}
|
|
672
|
+
propertyKey={popupCell?.propertyKey}
|
|
673
|
+
collection={collection}
|
|
674
|
+
entity={popupCell?.entity}
|
|
675
|
+
tableKey={tableKey.current}
|
|
676
|
+
customFieldValidator={uniqueFieldValidator}
|
|
677
|
+
path={resolvedFullPath}
|
|
678
|
+
onCellValueChange={onValueChange}
|
|
679
|
+
container={containerRef.current}/>
|
|
680
|
+
|
|
681
|
+
{deleteEntityClicked &&
|
|
682
|
+
<DeleteEntityDialog
|
|
683
|
+
entityOrEntitiesToDelete={deleteEntityClicked}
|
|
684
|
+
path={fullPath}
|
|
672
685
|
collection={collection}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
container={containerRef.current}/>
|
|
679
|
-
|
|
680
|
-
{deleteEntityClicked &&
|
|
681
|
-
<DeleteEntityDialog
|
|
682
|
-
entityOrEntitiesToDelete={deleteEntityClicked}
|
|
683
|
-
path={fullPath}
|
|
684
|
-
collection={collection}
|
|
685
|
-
callbacks={collection.callbacks}
|
|
686
|
-
open={Boolean(deleteEntityClicked)}
|
|
687
|
-
onEntityDelete={internalOnEntityDelete}
|
|
688
|
-
onMultipleEntitiesDelete={internalOnMultipleEntitiesDelete}
|
|
689
|
-
onClose={() => setDeleteEntityClicked(undefined)}/>}
|
|
686
|
+
callbacks={collection.callbacks}
|
|
687
|
+
open={Boolean(deleteEntityClicked)}
|
|
688
|
+
onEntityDelete={internalOnEntityDelete}
|
|
689
|
+
onMultipleEntitiesDelete={internalOnMultipleEntitiesDelete}
|
|
690
|
+
onClose={() => setDeleteEntityClicked(undefined)}/>}
|
|
690
691
|
|
|
691
692
|
</div>
|
|
692
693
|
);
|