@firecms/core 3.0.0-alpha.28 → 3.0.0-alpha.29

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 (57) hide show
  1. package/dist/core/FireCMS.d.ts +2 -2
  2. package/dist/core/builders.d.ts +2 -2
  3. package/dist/core/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +4 -2
  4. package/dist/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.d.ts +15 -11
  5. package/dist/core/components/EntityCollectionTable/internal/default_entity_actions.d.ts +5 -0
  6. package/dist/core/components/EntityCollectionTable/types.d.ts +1 -37
  7. package/dist/core/components/VirtualTable/VirtualTableProps.d.ts +1 -1
  8. package/dist/core/contexts/DialogsProvider.d.ts +4 -0
  9. package/dist/core/index.d.ts +1 -1
  10. package/dist/core/internal/useBuildNavigationContext.d.ts +3 -3
  11. package/dist/core/util/resolutions.d.ts +1 -1
  12. package/dist/hooks/useDialogsController.d.ts +11 -0
  13. package/dist/index.es.js +8400 -8230
  14. package/dist/index.es.js.map +1 -1
  15. package/dist/index.umd.js +67 -67
  16. package/dist/index.umd.js.map +1 -1
  17. package/dist/styles.d.ts +1 -1
  18. package/dist/types/collections.d.ts +36 -13
  19. package/dist/types/dialogs_controller.d.ts +30 -0
  20. package/dist/types/entity_actions.d.ts +33 -0
  21. package/dist/types/firecms.d.ts +5 -5
  22. package/dist/types/firecms_context.d.ts +7 -0
  23. package/dist/types/index.d.ts +1 -0
  24. package/dist/types/navigation.d.ts +3 -3
  25. package/dist/types/plugins.d.ts +11 -10
  26. package/package.json +3 -3
  27. package/src/components/Sheet.tsx +1 -0
  28. package/src/core/FireCMS.tsx +9 -6
  29. package/src/core/builders.ts +6 -6
  30. package/src/core/components/ArrayContainer.tsx +1 -1
  31. package/src/core/components/EntityCollectionTable/EntityCollectionTable.tsx +16 -9
  32. package/src/core/components/EntityCollectionTable/EntityCollectionTableProps.tsx +5 -2
  33. package/src/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.tsx +96 -79
  34. package/src/core/components/EntityCollectionTable/internal/default_entity_actions.tsx +107 -0
  35. package/src/core/components/EntityCollectionTable/types.tsx +1 -56
  36. package/src/core/components/EntityCollectionView/EntityCollectionView.tsx +66 -42
  37. package/src/core/components/ReferenceSelectionInner.tsx +2 -2
  38. package/src/core/components/VirtualTable/VirtualTable.tsx +4 -6
  39. package/src/core/components/VirtualTable/VirtualTableProps.tsx +1 -1
  40. package/src/core/contexts/DialogsProvider.tsx +50 -0
  41. package/src/core/index.tsx +1 -1
  42. package/src/core/internal/useBuildNavigationContext.tsx +13 -13
  43. package/src/core/internal/useBuildSideEntityController.tsx +9 -1
  44. package/src/form/EntityForm.tsx +63 -6
  45. package/src/hooks/useDialogsController.tsx +14 -0
  46. package/src/hooks/useFireCMSContext.tsx +5 -11
  47. package/src/styles.ts +1 -1
  48. package/src/types/collections.ts +36 -17
  49. package/src/types/dialogs_controller.tsx +31 -0
  50. package/src/types/entity_actions.tsx +36 -0
  51. package/src/types/firecms.tsx +5 -5
  52. package/src/types/firecms_context.tsx +8 -0
  53. package/src/types/index.ts +1 -0
  54. package/src/types/navigation.ts +3 -3
  55. package/src/types/plugins.tsx +11 -10
  56. /package/dist/core/contexts/{SnackbarContext.d.ts → SnackbarProvider.d.ts} +0 -0
  57. /package/src/core/contexts/{SnackbarContext.tsx → SnackbarProvider.tsx} +0 -0
package/dist/styles.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const focusedMixin = "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent";
1
+ export declare const focusedMixin = "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent";
2
2
  export declare const focusedInvisibleMixin = "focus:bg-opacity-70 focus:bg-gray-100 focus:dark:bg-gray-800 focus:dark:bg-opacity-60";
3
3
  export declare const focusedClasses = "z-30 outline-none ring-2 ring-primary ring-opacity-75 ring-offset-2 ring-offset-transparent ";
4
4
  export declare const fieldBackgroundMixin = "bg-opacity-70 bg-gray-100 dark:bg-gray-800 dark:bg-opacity-60 transition duration-150 ease-in-out";
@@ -6,6 +6,7 @@ import { EntityCallbacks } from "./entity_callbacks";
6
6
  import { Permissions, PermissionsBuilder } from "./permissions";
7
7
  import { EnumValues, PropertiesOrBuilders } from "./properties";
8
8
  import { FormContext } from "./fields";
9
+ import { EntityAction } from "./entity_actions";
9
10
  /**
10
11
  * This interface represents a view that includes a collection of entities.
11
12
  * It can be in the root level of the configuration, defining the main
@@ -13,7 +14,7 @@ import { FormContext } from "./fields";
13
14
  *
14
15
  * @category Models
15
16
  */
16
- export interface EntityCollection<M extends Record<string, any> = any, AdditionalKey extends string = string, UserType extends User = User> {
17
+ export interface EntityCollection<M extends Record<string, any> = any, UserType extends User = User> {
17
18
  /**
18
19
  * Name of the collection, typically plural.
19
20
  * E.g. `Products`, `Blog`
@@ -48,9 +49,9 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
48
49
  alias?: string;
49
50
  /**
50
51
  * Icon key to use in this collection.
51
- * You can use any of the icons in the MUI specs:
52
- * https://mui.com/material-ui/material-icons/
53
- * e.g. 'AccountTree' or 'Person'
52
+ * You can use any of the icons in the Material specs:
53
+ * https://fonts.google.com/icons
54
+ * e.g. 'account_tree' or 'person'
54
55
  */
55
56
  icon?: string;
56
57
  /**
@@ -80,7 +81,7 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
80
81
  * - If you are using a collection group, you will also have an
81
82
  * additional `collectionGroupParent` column.
82
83
  */
83
- propertiesOrder?: Extract<keyof M | AdditionalKey, string>[];
84
+ propertiesOrder?: Extract<keyof M, string>[];
84
85
  /**
85
86
  * If enabled, content is loaded in batches. If `false` all entities in the
86
87
  * collection are loaded.
@@ -97,7 +98,7 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
97
98
  * Permissions the logged-in user can perform on this collection.
98
99
  * If not specified everything defaults to `true`.
99
100
  */
100
- permissions?: Permissions | PermissionsBuilder<EntityCollection<M>, UserType, M>;
101
+ permissions?: Permissions | PermissionsBuilder<any, UserType, M>;
101
102
  /**
102
103
  * Are the entities in this collection selectable. Defaults to `true`
103
104
  */
@@ -119,6 +120,30 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
119
120
  * collection toolbar
120
121
  */
121
122
  Actions?: React.ComponentType<CollectionActionsProps> | React.ComponentType<CollectionActionsProps>[];
123
+ /**
124
+ * You can define additional actions that can be performed on the entities
125
+ * in this collection. These actions can be displayed in the collection
126
+ * view or in the entity view.
127
+ *
128
+ * You can use the `onClick` method to implement your own logic.
129
+ * In the `context` prop you can access all the controllers of FireCMS.
130
+ *
131
+ * ```
132
+ * const archiveEntityAction: EntityAction = {
133
+ * icon: <ArchiveIcon/>,
134
+ * name: "Archive",
135
+ * onClick({
136
+ * entity,
137
+ * collection,
138
+ * context,
139
+ * }): Promise<void> {
140
+ * // Add your code here
141
+ * return Promise.resolve(undefined);
142
+ * }
143
+ * }
144
+ * ```
145
+ */
146
+ entityActions?: EntityAction<M, UserType>[];
122
147
  /**
123
148
  * Pass your own selection controller if you want to control selected
124
149
  * entities externally.
@@ -163,7 +188,7 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
163
188
  * You can add additional fields to the collection view by implementing
164
189
  * an additional field delegate.
165
190
  */
166
- additionalFields?: AdditionalFieldDelegate<M, AdditionalKey, UserType>[];
191
+ additionalFields?: AdditionalFieldDelegate<M, UserType>[];
167
192
  /**
168
193
  * Default size of the rendered collection
169
194
  */
@@ -208,10 +233,8 @@ export interface EntityCollection<M extends Record<string, any> = any, Additiona
208
233
  }
209
234
  /**
210
235
  * Parameter passed to the `Actions` prop in the collection configuration.
211
- * Note that actions are rendered in the collection toolbar, as well
212
- * as in the home page card.
213
- * If you don't want to render the actions in the home page card, you can
214
- * return `null` if mode is `home`.
236
+ * The component will receive this prop when it is rendered in the collection
237
+ * toolbar.
215
238
  *
216
239
  * @category Models
217
240
  */
@@ -296,12 +319,12 @@ export type AdditionalFieldDelegateProps<M extends Record<string, any> = any, Us
296
319
  * If you need to do some async loading you can use {@link AsyncPreviewComponent}
297
320
  * @category Models
298
321
  */
299
- export interface AdditionalFieldDelegate<M extends Record<string, any> = any, AdditionalKey extends string = string, UserType extends User = User> {
322
+ export interface AdditionalFieldDelegate<M extends Record<string, any> = any, UserType extends User = User> {
300
323
  /**
301
324
  * ID of this column. You can use this id in the `properties` field of the
302
325
  * collection in any order you want
303
326
  */
304
- id: AdditionalKey;
327
+ id: string;
305
328
  /**
306
329
  * Header of this column
307
330
  */
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Controller to open the side dialog
3
+ * @category Hooks and utilities
4
+ */
5
+ export interface DialogsController {
6
+ /**
7
+ * Close the last dialog
8
+ */
9
+ close: () => void;
10
+ /**
11
+ * Open a dialog
12
+ * @param props
13
+ */
14
+ open: (props: DialogControllerEntryProps) => {
15
+ closeDialog: () => void;
16
+ };
17
+ }
18
+ /**
19
+ * Props used to open a side dialog
20
+ * @category Hooks and utilities
21
+ */
22
+ export interface DialogControllerEntryProps {
23
+ key: string;
24
+ /**
25
+ * The component type that will be rendered
26
+ */
27
+ Component: React.ComponentType<{
28
+ open: boolean;
29
+ }>;
30
+ }
@@ -0,0 +1,33 @@
1
+ import React from "react";
2
+ import { FireCMSContext } from "./firecms_context";
3
+ import { Entity } from "./entities";
4
+ import { EntityCollection, SelectionController } from "./collections";
5
+ import { User } from "./user";
6
+ import { SideEntityController } from "./side_entity_controller";
7
+ export type EntityAction<M extends object = any, UserType extends User = User> = {
8
+ name: string;
9
+ icon?: React.ReactElement;
10
+ onClick: (props: EntityActionClickProps<M, UserType>) => Promise<void>;
11
+ /**
12
+ * Show this action in the menu, defaults to true
13
+ */
14
+ collapsed?: boolean;
15
+ /**
16
+ * Show this action in the form, defaults to true
17
+ */
18
+ includeInForm?: boolean;
19
+ };
20
+ export type EntityActionClickProps<M extends object, UserType extends User = User> = {
21
+ entity: Entity<M>;
22
+ context: FireCMSContext<UserType>;
23
+ fullPath?: string;
24
+ collection?: EntityCollection<M>;
25
+ selectionController?: SelectionController;
26
+ highlightEntity?: (entity: Entity<any>) => void;
27
+ unhighlightEntity?: (entity: Entity<any>) => void;
28
+ onCollectionChange?: () => void;
29
+ /**
30
+ * If this actions is being called from a side dialog
31
+ */
32
+ sideEntityController?: SideEntityController;
33
+ };
@@ -22,11 +22,11 @@ import { CMSAnalyticsEvent } from "./analytics";
22
22
  * APIs directly, or a REST API.
23
23
  * @category Models
24
24
  */
25
- export type EntityCollectionsBuilder = (params: {
25
+ export type EntityCollectionsBuilder<EC extends EntityCollection> = (params: {
26
26
  user: User | null;
27
27
  authController: AuthController;
28
28
  dataSource: DataSource;
29
- }) => EntityCollection[] | Promise<EntityCollection[]>;
29
+ }) => EC[] | Promise<EC[]>;
30
30
  /**
31
31
  * Use this callback to build custom views dynamically.
32
32
  * You can use the user to decide which views to show.
@@ -44,7 +44,7 @@ export type CMSViewsBuilder = (params: {
44
44
  /**
45
45
  * @category Models
46
46
  */
47
- export type FireCMSProps<UserType extends User> = {
47
+ export type FireCMSProps<UserType extends User, EC extends EntityCollection> = {
48
48
  /**
49
49
  * Use this function to return the components you want to render under
50
50
  * FireCMS
@@ -68,7 +68,7 @@ export type FireCMSProps<UserType extends User> = {
68
68
  * Each of the navigation entries in this field
69
69
  * generates an entry in the main menu.
70
70
  */
71
- collections?: EntityCollection[] | EntityCollectionsBuilder;
71
+ collections?: EC[] | EntityCollectionsBuilder<EC>;
72
72
  /**
73
73
  * Custom additional views created by the developer, added to the main
74
74
  * navigation
@@ -130,7 +130,7 @@ export type FireCMSProps<UserType extends User> = {
130
130
  * Use plugins to modify the behaviour of the CMS.
131
131
  * Currently, in ALPHA, and likely subject to change.
132
132
  */
133
- plugins?: FireCMSPlugin[];
133
+ plugins?: FireCMSPlugin<any, any, any>[];
134
134
  /**
135
135
  * Callback used to get analytics events from the CMS
136
136
  */
@@ -13,6 +13,7 @@ import { FireCMSPlugin } from "./plugins";
13
13
  import { CMSAnalyticsEvent } from "./analytics";
14
14
  import { PropertyConfig } from "./property_config";
15
15
  import { EntityCustomView } from "./collections";
16
+ import { DialogsController } from "./dialogs_controller";
16
17
  /**
17
18
  * Context that includes the internal controllers and contexts used by the app.
18
19
  * Some controllers and context included in this context can be accessed
@@ -51,8 +52,14 @@ export type FireCMSContext<UserType extends User = User, AuthControllerType exte
51
52
  sideEntityController: SideEntityController;
52
53
  /**
53
54
  * Controller used to open side dialogs
55
+ * This is the controller used internally by side entity dialogs
56
+ * or reference dialogs.
54
57
  */
55
58
  sideDialogsController: SideDialogsController;
59
+ /**
60
+ * Controller used to open regular dialogs
61
+ */
62
+ dialogsController: DialogsController;
56
63
  /**
57
64
  * Used auth controller
58
65
  */
@@ -1,5 +1,6 @@
1
1
  export * from "./auth";
2
2
  export * from "./entities";
3
+ export * from "./entity_actions";
3
4
  export * from "./resolved_entities";
4
5
  export * from "./properties";
5
6
  export * from "./collections";
@@ -127,9 +127,9 @@ export interface CMSView {
127
127
  description?: string;
128
128
  /**
129
129
  * Icon key to use in this view.
130
- * You can use any of the icons in the MUI specs:
131
- * https://mui.com/material-ui/material-icons/
132
- * e.g. 'AccountTree' or 'Person'
130
+ * You can use any of the icons in the Material specs:
131
+ * https://fonts.google.com/icons
132
+ * e.g. 'account_tree' or 'person'
133
133
  */
134
134
  icon?: string;
135
135
  /**
@@ -11,7 +11,7 @@ import { ResolvedProperty } from "./resolved_entities";
11
11
  * NOTE: This is a work in progress and the API is not stable yet.
12
12
  * @category Core
13
13
  */
14
- export type FireCMSPlugin<PROPS = any, FORM_PROPS = any> = {
14
+ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollection = EntityCollection> = {
15
15
  /**
16
16
  * Name of the plugin
17
17
  */
@@ -34,15 +34,15 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any> = {
34
34
  * Use this component to add custom actions to the entity collections
35
35
  * toolbar.
36
36
  */
37
- CollectionActions?: React.ComponentType<CollectionActionsProps> | React.ComponentType<CollectionActionsProps>[];
37
+ CollectionActions?: React.ComponentType<CollectionActionsProps<any, any, EC>> | React.ComponentType<CollectionActionsProps<any, any, EC>>[];
38
38
  };
39
39
  form?: {
40
40
  provider?: {
41
- Component: React.ComponentType<PropsWithChildren<FORM_PROPS & PluginFormActionProps<any>>>;
41
+ Component: React.ComponentType<PropsWithChildren<FORM_PROPS & PluginFormActionProps<any, EC>>>;
42
42
  props?: FORM_PROPS;
43
43
  };
44
- Actions?: React.ComponentType<PluginFormActionProps>;
45
- fieldBuilder?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T>) => React.ComponentType<FieldProps<T>> | null;
44
+ Actions?: React.ComponentType<PluginFormActionProps<any, EC>>;
45
+ fieldBuilder?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T, any, EC>) => React.ComponentType<FieldProps<T>> | null;
46
46
  fieldBuilderEnabled?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T>) => boolean;
47
47
  };
48
48
  /**
@@ -95,6 +95,7 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any> = {
95
95
  fullPath: string;
96
96
  parentPathSegments: string[];
97
97
  onHover: boolean;
98
+ collection: EC;
98
99
  }>;
99
100
  /**
100
101
  * If you add this callback to your plugin, an add button will be added to the collection table.
@@ -103,7 +104,7 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any> = {
103
104
  AddColumnComponent?: React.ComponentType<{
104
105
  fullPath: string;
105
106
  parentPathSegments: string[];
106
- collection: EntityCollection;
107
+ collection: EC;
107
108
  }>;
108
109
  };
109
110
  };
@@ -129,23 +130,23 @@ export interface PluginHomePageActionsProps<EP extends object = object, M extend
129
130
  context: FireCMSContext<UserType>;
130
131
  extraProps?: EP;
131
132
  }
132
- export interface PluginFormActionProps<UserType extends User = User> {
133
+ export interface PluginFormActionProps<UserType extends User = User, EC extends EntityCollection = EntityCollection> {
133
134
  entityId?: string;
134
135
  path: string;
135
136
  status: EntityStatus;
136
- collection: EntityCollection;
137
+ collection: EC;
137
138
  formContext?: FormContext<any>;
138
139
  context: FireCMSContext<UserType>;
139
140
  currentEntityId?: string;
140
141
  }
141
- export type PluginFieldBuilderParams<T extends CMSType = CMSType, M extends Record<string, any> = any> = {
142
+ export type PluginFieldBuilderParams<T extends CMSType = CMSType, M extends Record<string, any> = any, EC extends EntityCollection<M> = EntityCollection<M>> = {
142
143
  fieldConfigId: string;
143
144
  propertyKey: string;
144
145
  property: Property<T> | ResolvedProperty<T>;
145
146
  Field: React.ComponentType<FieldProps<T, any, M>>;
146
147
  plugin: FireCMSPlugin;
147
148
  path: string;
148
- collection: EntityCollection<M>;
149
+ collection: EC;
149
150
  };
150
151
  export interface PluginGenericProps<UserType extends User = User> {
151
152
  context: FireCMSContext<UserType>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
- "version": "3.0.0-alpha.28",
3
+ "version": "3.0.0-alpha.29",
4
4
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
5
5
  "funding": {
6
6
  "url": "https://github.com/sponsors/firecmsco"
@@ -101,7 +101,7 @@
101
101
  "@testing-library/react": "^14.0.0",
102
102
  "@testing-library/user-event": "^14.5.1",
103
103
  "@types/jest": "^29.5.6",
104
- "@types/node": "^18.18.7",
104
+ "@types/node": "^20.8.9",
105
105
  "@types/object-hash": "^3.0.5",
106
106
  "@types/react": "^18.2.33",
107
107
  "@types/react-dom": "^18.2.14",
@@ -133,7 +133,7 @@
133
133
  "dist",
134
134
  "src"
135
135
  ],
136
- "gitHead": "aba9501b45cf2dc84dc172084510b90e417b42f1",
136
+ "gitHead": "65c1ea189696ea89b29b2416680a1dc541da0b36",
137
137
  "publishConfig": {
138
138
  "access": "public"
139
139
  }
@@ -61,6 +61,7 @@ export const Sheet: React.FC<SheetProps> = ({
61
61
  {...props}
62
62
  className={cn(
63
63
  // "transform-gpu",
64
+ "will-change-transform",
64
65
  "text-gray-900 dark:text-white",
65
66
  "fixed transform z-20 transition-all duration-[240ms] ease-in-out",
66
67
  "outline-none focus:outline-none",
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from "react";
2
2
 
3
- import { FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
3
+ import { EntityCollection, FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
4
4
  import { BreadcrumbsProvider } from "./contexts/BreacrumbsContext";
5
5
  import { ModeControllerContext } from "./contexts/ModeController";
6
6
  import { useBuildSideEntityController } from "./internal/useBuildSideEntityController";
@@ -17,6 +17,7 @@ import { AuthControllerContext } from "./contexts/AuthControllerContext";
17
17
  import { SideDialogsControllerContext } from "./contexts/SideDialogsControllerContext";
18
18
  import { useLocaleConfig } from "./internal/useLocaleConfig";
19
19
  import { CenteredView } from "../components";
20
+ import { DialogsProvider } from "./contexts/DialogsProvider";
20
21
 
21
22
  const DEFAULT_BASE_PATH = "/";
22
23
  const DEFAULT_COLLECTION_PATH = "/c";
@@ -34,7 +35,7 @@ const DEFAULT_COLLECTION_PATH = "/c";
34
35
  * @constructor
35
36
  * @category Core
36
37
  */
37
- export function FireCMS<UserType extends User>(props: FireCMSProps<UserType>) {
38
+ export function FireCMS<UserType extends User, EC extends EntityCollection>(props: FireCMSProps<UserType, EC>) {
38
39
 
39
40
  const modeController = useModeController();
40
41
  const {
@@ -124,10 +125,12 @@ export function FireCMS<UserType extends User>(props: FireCMSProps<UserType>) {
124
125
  <NavigationContextInstance.Provider
125
126
  value={navigation}>
126
127
  <BreadcrumbsProvider>
127
- <FireCMSInternal
128
- loading={loading}>
129
- {children}
130
- </FireCMSInternal>
128
+ <DialogsProvider>
129
+ <FireCMSInternal
130
+ loading={loading}>
131
+ {children}
132
+ </FireCMSInternal>
133
+ </DialogsProvider>
131
134
  </BreadcrumbsProvider>
132
135
  </NavigationContextInstance.Provider>
133
136
  </SideEntityControllerContext.Provider>
@@ -27,10 +27,10 @@ import {
27
27
  * @category Builder
28
28
  */
29
29
  export function buildCollection<M extends Record<string, any> = any,
30
- AdditionalKey extends string = string,
30
+
31
31
  UserType extends User = User>(
32
- collection: EntityCollection<M, AdditionalKey, UserType>
33
- ): EntityCollection<M, AdditionalKey, UserType> {
32
+ collection: EntityCollection<M, UserType>
33
+ ): EntityCollection<M, UserType> {
34
34
  return collection;
35
35
  }
36
36
 
@@ -121,9 +121,9 @@ export function buildEntityCallbacks<M extends Record<string, any> = any>(
121
121
  * @param additionalFieldDelegate
122
122
  * @category Builder
123
123
  */
124
- export function buildAdditionalFieldDelegate<M extends Record<string, any>, AdditionalKey extends string = string, UserType extends User = User>(
125
- additionalFieldDelegate: AdditionalFieldDelegate<M, AdditionalKey, UserType>
126
- ): AdditionalFieldDelegate<M, AdditionalKey, UserType> {
124
+ export function buildAdditionalFieldDelegate<M extends Record<string, any>, UserType extends User = User>(
125
+ additionalFieldDelegate: AdditionalFieldDelegate<M, UserType>
126
+ ): AdditionalFieldDelegate<M, UserType> {
127
127
  return additionalFieldDelegate;
128
128
  }
129
129
 
@@ -175,7 +175,7 @@ export function ArrayContainer<T>({
175
175
 
176
176
  {droppableProvided.placeholder}
177
177
 
178
- {includeAddButton && <div className="p-4 justify-center text-left">
178
+ {includeAddButton && <div className="py-4 justify-center text-left">
179
179
  <Button
180
180
  variant={size === "small" ? "text" : "outlined"}
181
181
  size={size === "small" ? "small" : "medium"}
@@ -63,7 +63,7 @@ export const useEntityCollectionTableController = () => useContext<EntityCollect
63
63
  * @category Components
64
64
  */
65
65
  export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>(
66
- function EntityCollectionTable<M extends Record<string, any>, AdditionalKey extends string, UserType extends User>
66
+ function EntityCollectionTable<M extends Record<string, any>, UserType extends User>
67
67
  ({
68
68
  forceFilter,
69
69
  actionsStart,
@@ -110,7 +110,9 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
110
110
  endAdornment,
111
111
  AddColumnComponent,
112
112
  AdditionalHeaderWidget,
113
- additionalIDHeaderWidget
113
+ additionalIDHeaderWidget,
114
+ emptyComponent,
115
+ getIdColumnWidth
114
116
  }: EntityCollectionTableProps<M>) {
115
117
 
116
118
  const largeLayout = useLargeLayout();
@@ -154,12 +156,12 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
154
156
 
155
157
  const onTextSearch = useCallback((newSearchString?: string) => setSearchString?.(newSearchString), []);
156
158
 
157
- const additionalFieldsMap: Record<string, AdditionalFieldDelegate<M, string, UserType>> = useMemo(() => {
159
+ const additionalFieldsMap: Record<string, AdditionalFieldDelegate<M, UserType>> = useMemo(() => {
158
160
  return (additionalFields
159
161
  ? additionalFields
160
- .map((aC) => ({ [aC.id]: aC as AdditionalFieldDelegate<M, string, any> }))
162
+ .map((aC) => ({ [aC.id]: aC as AdditionalFieldDelegate<M, any> }))
161
163
  .reduce((a, b) => ({ ...a, ...b }), {})
162
- : {}) as Record<string, AdditionalFieldDelegate<M, string, UserType>>;
164
+ : {}) as Record<string, AdditionalFieldDelegate<M, UserType>>;
163
165
  }, [additionalFields]);
164
166
 
165
167
  // on ESC key press
@@ -198,7 +200,11 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
198
200
 
199
201
  let disabled = column.custom?.disabled;
200
202
  const propertyValue = entity.values ? getValueInPath(entity.values, propertyKey) : undefined;
201
- const property = getPropertyFor?.({ propertyKey, propertyValue, entity }) ?? column.custom.resolvedProperty;
203
+ const property = getPropertyFor?.({
204
+ propertyKey,
205
+ propertyValue,
206
+ entity
207
+ }) ?? column.custom.resolvedProperty;
202
208
  if (!property?.disabled) {
203
209
  disabled = false;
204
210
  }
@@ -238,7 +244,7 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
238
244
 
239
245
  const entity: Entity<M> = rowData;
240
246
 
241
- const additionalField = additionalFieldsMap[column.key as AdditionalKey];
247
+ const additionalField = additionalFieldsMap[column.key as string];
242
248
  const value = additionalField.dependencies
243
249
  ? Object.entries(entity.values)
244
250
  .filter(([key, value]) => additionalField.dependencies!.includes(key as Extract<keyof M, string>))
@@ -318,14 +324,14 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
318
324
 
319
325
  const idColumn: VirtualTableColumn = useMemo(() => ({
320
326
  key: "id_ewcfedcswdf3",
321
- width: largeLayout ? 160 : 130,
327
+ width: getIdColumnWidth?.() ?? (largeLayout ? 160 : 130),
322
328
  title: "ID",
323
329
  resizable: false,
324
330
  frozen: largeLayout,
325
331
  headerAlign: "center",
326
332
  align: "center",
327
333
  AdditionalHeaderWidget: () => additionalIDHeaderWidget
328
- }), [largeLayout])
334
+ }), [getIdColumnWidth, largeLayout])
329
335
 
330
336
  const columns: VirtualTableColumn[] = useMemo(() => [
331
337
  idColumn,
@@ -410,6 +416,7 @@ export const EntityCollectionTable = React.memo<EntityCollectionTableProps<any>>
410
416
  sortBy={sortBy}
411
417
  onSortByUpdate={setSortBy as ((sortBy?: [string, "asc" | "desc"]) => void)}
412
418
  hoverRow={hoverRow}
419
+ emptyComponent={emptyComponent}
413
420
  checkFilterCombination={checkFilterCombination}
414
421
  createFilterField={filterable ? createFilterField : undefined}
415
422
  rowClassName={useCallback((entity: Entity<M>) => {
@@ -21,7 +21,7 @@ export type OnColumnResizeParams = { width: number, key: string };
21
21
  * @category Collection components
22
22
  */
23
23
  export type EntityCollectionTableProps<M extends Record<string, any>,
24
- AdditionalKey extends string = string,
24
+
25
25
  UserType extends User = User> = {
26
26
 
27
27
  /**
@@ -105,7 +105,7 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
105
105
 
106
106
  inlineEditing?: boolean | ((entity: Entity<M>) => boolean);
107
107
 
108
- additionalFields?: AdditionalFieldDelegate<M, AdditionalKey, UserType>[];
108
+ additionalFields?: AdditionalFieldDelegate<M, UserType>[];
109
109
 
110
110
  defaultSize?: CollectionSize;
111
111
 
@@ -129,6 +129,9 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
129
129
 
130
130
  additionalIDHeaderWidget?: React.ReactNode;
131
131
 
132
+ emptyComponent?: React.ReactNode;
133
+
134
+ getIdColumnWidth?: () => number;
132
135
  }
133
136
 
134
137
  export type GetPropertyForProps<M extends Record<string, any>> = {