@firecms/core 3.0.0-alpha.81 → 3.0.0-alpha.82

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 (81) hide show
  1. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +3 -3
  2. package/dist/components/EntityCollectionTable/column_utils.d.ts +2 -2
  3. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +5 -1
  4. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -1
  5. package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +1 -1
  6. package/dist/components/VirtualTable/VirtualTableProps.d.ts +1 -1
  7. package/dist/contexts/AnalyticsContext.d.ts +3 -0
  8. package/dist/contexts/CustomizationControllerContext.d.ts +3 -0
  9. package/dist/core/field_configs.d.ts +1 -1
  10. package/dist/hooks/index.d.ts +1 -0
  11. package/dist/hooks/useAnalyticsController.d.ts +5 -0
  12. package/dist/hooks/useCustomizationController.d.ts +11 -0
  13. package/dist/hooks/useFireCMSContext.d.ts +0 -1
  14. package/dist/index.es.js +4614 -4592
  15. package/dist/index.es.js.map +1 -1
  16. package/dist/index.umd.js +5 -5
  17. package/dist/index.umd.js.map +1 -1
  18. package/dist/internal/useBuildCustomizationController.d.ts +2 -0
  19. package/dist/types/analytics_controller.d.ts +7 -0
  20. package/dist/types/collections.d.ts +3 -0
  21. package/dist/types/customization_controller.d.ts +47 -0
  22. package/dist/types/entity_callbacks.d.ts +17 -3
  23. package/dist/types/firecms_context.d.ts +6 -46
  24. package/dist/types/index.d.ts +2 -0
  25. package/dist/util/icons.d.ts +4 -1
  26. package/dist/util/useTraceUpdate.d.ts +1 -1
  27. package/package.json +3 -3
  28. package/src/components/DeleteEntityDialog.tsx +9 -3
  29. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +28 -5
  30. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +4 -5
  31. package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
  32. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +125 -122
  33. package/src/components/EntityCollectionTable/filters/DateTimeFilterField.tsx +2 -2
  34. package/src/components/EntityCollectionTable/internal/default_entity_actions.tsx +3 -3
  35. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +4 -3
  36. package/src/components/EntityCollectionView/EntityCollectionView.tsx +74 -50
  37. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -3
  38. package/src/components/EntityPreview.tsx +11 -7
  39. package/src/components/HomePage/DefaultHomePage.tsx +9 -8
  40. package/src/components/HomePage/NavigationCollectionCard.tsx +6 -5
  41. package/src/components/ReferenceSelectionInner.tsx +13 -9
  42. package/src/components/VirtualTable/VirtualTable.tsx +23 -20
  43. package/src/components/VirtualTable/VirtualTableCell.tsx +27 -9
  44. package/src/components/VirtualTable/VirtualTableHeader.tsx +1 -1
  45. package/src/components/VirtualTable/VirtualTableProps.tsx +2 -2
  46. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +2 -2
  47. package/src/contexts/AnalyticsContext.tsx +4 -0
  48. package/src/contexts/CustomizationControllerContext.tsx +4 -0
  49. package/src/core/Drawer.tsx +7 -6
  50. package/src/core/FireCMS.tsx +39 -29
  51. package/src/form/EntityForm.tsx +16 -5
  52. package/src/form/PropertyFieldBinding.tsx +8 -10
  53. package/src/form/components/CustomIdField.tsx +7 -5
  54. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +1 -2
  55. package/src/form/field_bindings/DateTimeFieldBinding.tsx +2 -2
  56. package/src/form/field_bindings/KeyValueFieldBinding.tsx +4 -6
  57. package/src/hooks/data/save.ts +8 -3
  58. package/src/hooks/index.tsx +1 -0
  59. package/src/hooks/useAnalyticsController.tsx +8 -0
  60. package/src/hooks/useCustomizationController.tsx +14 -0
  61. package/src/hooks/useFireCMSContext.tsx +8 -7
  62. package/src/internal/EntityView.tsx +4 -2
  63. package/src/internal/useBuildCustomizationController.tsx +5 -0
  64. package/src/internal/useBuildSideDialogsController.tsx +0 -1
  65. package/src/preview/PropertyPreview.tsx +4 -3
  66. package/src/preview/components/DatePreview.tsx +4 -5
  67. package/src/preview/components/ReferencePreview.tsx +17 -8
  68. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +3 -3
  69. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +3 -3
  70. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +3 -3
  71. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +4 -4
  72. package/src/preview/property_previews/ArrayOneOfPreview.tsx +3 -3
  73. package/src/preview/property_previews/ArrayPropertyPreview.tsx +3 -3
  74. package/src/types/analytics_controller.tsx +10 -0
  75. package/src/types/collections.ts +3 -0
  76. package/src/types/customization_controller.tsx +58 -0
  77. package/src/types/entity_callbacks.ts +22 -3
  78. package/src/types/firecms_context.tsx +6 -51
  79. package/src/types/index.ts +2 -0
  80. package/src/util/icons.tsx +22 -19
  81. package/src/util/useTraceUpdate.tsx +5 -5
@@ -363,6 +363,9 @@ export type WhereFilterOp =
363
363
 
364
364
  /**
365
365
  * Used to define filters applied in collections
366
+ *
367
+ * e.g. `{ age: [">=", 18] }`
368
+ *
366
369
  * @group Models
367
370
  */
368
371
  export type FilterValues<Key extends string> =
@@ -0,0 +1,58 @@
1
+ import React from "react";
2
+ import { EntityLinkBuilder } from "./entity_link_builder";
3
+ import { FireCMSPlugin } from "./plugins";
4
+ import { EntityCustomView } from "./collections";
5
+ import { Locale } from "./locales";
6
+ import { PropertyConfig } from "./property_config";
7
+
8
+ export type CustomizationController = {
9
+
10
+ /**
11
+ * Builder for generating utility links for entities
12
+ */
13
+ entityLinkBuilder?: EntityLinkBuilder;
14
+
15
+ /**
16
+ * Use plugins to modify the behaviour of the CMS.
17
+ */
18
+ plugins?: FireCMSPlugin<any, any, any>[];
19
+
20
+ /**
21
+ * List of additional custom views for entities.
22
+ * You can use the key to reference the custom view in
23
+ * the `entityViews` prop of a collection.
24
+ *
25
+ * You can also define an entity view from the UI.
26
+ */
27
+
28
+ entityViews?: EntityCustomView[];
29
+
30
+ /**
31
+ * Format of the dates in the CMS.
32
+ * Defaults to 'MMMM dd, yyyy, HH:mm:ss'
33
+ */
34
+ dateTimeFormat?: string;
35
+
36
+ /**
37
+ * Locale of the CMS, currently only affecting dates
38
+ */
39
+ locale?: Locale;
40
+
41
+ /**
42
+ * Record of custom form fields to be used in the CMS.
43
+ * You can use the key to reference the custom field in
44
+ * the `propertyConfig` prop of a property in a collection.
45
+ */
46
+ propertyConfigs: Record<string, PropertyConfig>;
47
+
48
+ components?: {
49
+
50
+ /**
51
+ * Component to render when a reference is missing
52
+ */
53
+ missingReference?: React.ComponentType<{
54
+ path: string,
55
+ }>;
56
+
57
+ };
58
+ }
@@ -30,7 +30,7 @@ export type EntityCallbacks<M extends Record<string, any> = any, UserType extend
30
30
  * Callback used when saving fails
31
31
  * @param entitySaveProps
32
32
  */
33
- onSaveFailure?(entitySaveProps: EntityOnSaveProps<M, UserType>)
33
+ onSaveFailure?(entitySaveProps: EntityOnSaveFailureProps<M, UserType>)
34
34
  : Promise<void> | void;
35
35
 
36
36
  /**
@@ -39,7 +39,7 @@ export type EntityCallbacks<M extends Record<string, any> = any, UserType extend
39
39
  * error snackbar gets displayed.
40
40
  * @param entitySaveProps
41
41
  */
42
- onPreSave?(entitySaveProps: EntityOnSaveProps<M, UserType>)
42
+ onPreSave?(entitySaveProps: EntityOnPreSaveProps<M, UserType>)
43
43
  : Promise<Partial<EntityValues<M>>> | Partial<EntityValues<M>>;
44
44
 
45
45
  /**
@@ -96,6 +96,25 @@ export interface EntityOnFetchProps<M extends Record<string, any> = any, UserTyp
96
96
  context: FireCMSContext<UserType>;
97
97
  }
98
98
 
99
+ /**
100
+ * Parameters passed to hooks before an entity is saved
101
+ * @group Models
102
+ */
103
+ export type EntityOnPreSaveProps<M extends Record<string, any> = any, UserType extends User = User> =
104
+ Omit<EntityOnSaveProps<M, UserType>, "entityId">
105
+ & {
106
+ entityId?: string;
107
+ }
108
+ /**
109
+ * Parameters passed to hooks before an entity is saved
110
+ * @group Models
111
+ */
112
+ export type EntityOnSaveFailureProps<M extends Record<string, any> = any, UserType extends User = User> =
113
+ Omit<EntityOnSaveProps<M, UserType>, "entityId">
114
+ & {
115
+ entityId?: string;
116
+ }
117
+
99
118
  /**
100
119
  * Parameters passed to hooks when an entity is saved
101
120
  * @group Models
@@ -121,7 +140,7 @@ export interface EntityOnSaveProps<M extends Record<string, any> = any, UserType
121
140
  /**
122
141
  * ID of the entity
123
142
  */
124
- entityId?: string;
143
+ entityId: string;
125
144
 
126
145
  /**
127
146
  * Values being saved
@@ -1,19 +1,15 @@
1
- import { Locale } from "./locales";
2
1
  import { DataSource } from "./datasource";
3
2
  import { StorageSource } from "./storage";
4
3
  import { NavigationController } from "./navigation";
5
4
  import { SideEntityController } from "./side_entity_controller";
6
5
  import { AuthController } from "./auth";
7
- import { EntityLinkBuilder } from "./entity_link_builder";
8
6
  import { User } from "./user";
9
7
  import { SnackbarController } from "../hooks";
10
8
  import { UserConfigurationPersistence } from "./local_config_persistence";
11
9
  import { SideDialogsController } from "./side_dialogs_controller";
12
- import { FireCMSPlugin } from "./plugins";
13
- import { CMSAnalyticsEvent } from "./analytics";
14
- import { PropertyConfig } from "./property_config";
15
- import { EntityCustomView } from "./collections";
16
10
  import { DialogsController } from "./dialogs_controller";
11
+ import { CustomizationController } from "./customization_controller";
12
+ import { AnalyticsController } from "./analytics_controller";
17
13
 
18
14
  /**
19
15
  * Context that includes the internal controllers and contexts used by the app.
@@ -65,9 +61,9 @@ export type FireCMSContext<UserType extends User = User, AuthControllerType exte
65
61
  authController: AuthControllerType;
66
62
 
67
63
  /**
68
- * Builder for generating utility links for entities
64
+ * This controller holds the customization options for the CMS.
69
65
  */
70
- entityLinkBuilder?: EntityLinkBuilder;
66
+ customizationController: CustomizationController;
71
67
 
72
68
  /**
73
69
  * Use this controller to display snackbars
@@ -80,49 +76,8 @@ export type FireCMSContext<UserType extends User = User, AuthControllerType exte
80
76
  userConfigPersistence?: UserConfigurationPersistence;
81
77
 
82
78
  /**
83
- * Use plugins to modify the behaviour of the CMS.
84
- * Currently, in ALPHA, and likely subject to change.
79
+ * Callback to send analytics events
85
80
  */
86
- plugins?: FireCMSPlugin[];
81
+ analyticsController?: AnalyticsController;
87
82
 
88
- /**
89
- * Callback used to get analytics events from the CMS
90
- */
91
- onAnalyticsEvent?: (event: CMSAnalyticsEvent, data?: object) => void;
92
-
93
- /**
94
- * Record of custom form fields to be used in the CMS.
95
- * You can use the key to reference the custom field in
96
- * the `propertyConfig` prop of a property in a collection.
97
- */
98
- propertyConfigs: Record<string, PropertyConfig>;
99
-
100
- /**
101
- * List of additional custom views for entities.
102
- * You can use the key to reference the custom view in
103
- * the `entityViews` prop of a collection.
104
- *
105
- * You can also define an entity view from the UI.
106
- */
107
- entityViews?: EntityCustomView[];
108
-
109
- /**
110
- * Format of the dates in the CMS.
111
- * Defaults to 'MMMM dd, yyyy, HH:mm:ss'
112
- */
113
- dateTimeFormat?: string;
114
-
115
- /**
116
- * Locale of the CMS, currently only affecting dates
117
- */
118
- locale?: Locale;
119
-
120
- components?: {
121
-
122
- /**
123
- * Component to render when a reference is missing
124
- */
125
- missingReference?: React.ComponentType<{ path: string }>;
126
-
127
- }
128
83
  };
@@ -24,3 +24,5 @@ export * from "./firecms";
24
24
  export * from "./appcheck";
25
25
  export * from "./export_import";
26
26
  export * from "./modify_collections";
27
+ export * from "./analytics_controller";
28
+ export * from "./customization_controller";
@@ -3,8 +3,9 @@ import { CMSView, EntityCollection } from "../types";
3
3
  import { hashString } from "./hash";
4
4
  import { coolIconKeys, Icon, iconKeys } from "@firecms/ui";
5
5
  import { slugify } from "./strings";
6
+ import equal from "react-fast-compare"
6
7
 
7
- export function getIcon(iconKey?: string, className?:string): React.ReactElement | undefined {
8
+ export function getIcon(iconKey?: string, className?: string): React.ReactElement | undefined {
8
9
  if (!iconKey) return undefined;
9
10
  iconKey = slugify(iconKey);
10
11
  if (!(iconKey in iconKeysMap)) {
@@ -13,31 +14,33 @@ export function getIcon(iconKey?: string, className?:string): React.ReactElement
13
14
  return iconKey in iconKeysMap ? <Icon iconKey={iconKey} size={"medium"} className={className}/> : undefined;
14
15
  }
15
16
 
16
- export function getIconForView(collectionOrView: EntityCollection | CMSView, className?:string): React.ReactElement {
17
+ export const IconForView = React.memo(
18
+ function IconForView({ collectionOrView, className }: { collectionOrView: EntityCollection | CMSView, className?: string }): React.ReactElement {
19
+ const icon = getIcon(collectionOrView.icon, className);
20
+ if (collectionOrView?.icon && icon)
21
+ return icon;
17
22
 
18
- const icon = getIcon(collectionOrView.icon, className);
19
- if (collectionOrView?.icon && icon)
20
- return icon;
23
+ let slugName = slugify(("singularName" in collectionOrView ? collectionOrView.singularName : undefined) ?? collectionOrView.name);
21
24
 
22
- let slugName = slugify(("singularName" in collectionOrView ? collectionOrView.singularName : undefined) ?? collectionOrView.name);
23
-
24
- let key: string | undefined;
25
- if (slugName in iconKeysMap)
26
- key = slugName;
27
-
28
- if (!key) {
29
- slugName = slugify(collectionOrView.path);
25
+ let key: string | undefined;
30
26
  if (slugName in iconKeysMap)
31
27
  key = slugName;
32
- }
33
28
 
34
- const iconsCount = coolIconKeys.length;
29
+ if (!key) {
30
+ slugName = slugify(collectionOrView.path);
31
+ if (slugName in iconKeysMap)
32
+ key = slugName;
33
+ }
35
34
 
36
- if (!key)
37
- key = coolIconKeys[hashString(collectionOrView.path) % iconsCount];
35
+ const iconsCount = coolIconKeys.length;
38
36
 
39
- return <Icon iconKey={key} size={"medium"} className={className}/>;
40
- }
37
+ if (!key)
38
+ key = coolIconKeys[hashString(collectionOrView.path) % iconsCount];
39
+
40
+ return <Icon iconKey={key} size={"medium"} className={className}/>;
41
+ }, (prevProps, nextProps) => {
42
+ return equal(prevProps.collectionOrView.icon, nextProps.collectionOrView.icon);
43
+ });
41
44
 
42
45
  const iconKeysMap: Record<string, string> = iconKeys.reduce((acc: Record<string, string>, key) => {
43
46
  acc[key] = key;
@@ -1,12 +1,12 @@
1
1
  import { useEffect, useRef } from "react";
2
2
 
3
- function printChanged(props: any, prev: any, path = "", depth = 0) {
4
- if (depth > 10) {
3
+ function printChanged(props: any, prev: any, path = "", depth = 0, maxDepth: number) {
4
+ if (depth > maxDepth) {
5
5
  return;
6
6
  }
7
7
  if (props && prev && typeof props === "object" && typeof prev === "object") {
8
8
  Object.keys(props).forEach((key) => {
9
- printChanged(props[key], prev[key], path + "." + key, depth + 1);
9
+ printChanged(props[key], prev[key], path + "." + key, depth + 1, maxDepth);
10
10
  });
11
11
  } else if (props !== prev) {
12
12
  console.log("Changed props:", path);
@@ -14,10 +14,10 @@ function printChanged(props: any, prev: any, path = "", depth = 0) {
14
14
 
15
15
  }
16
16
 
17
- export function useTraceUpdate(props: any) {
17
+ export function useTraceUpdate(props: any, maxDepth = 3) {
18
18
  const prev = useRef(props);
19
19
  useEffect(() => {
20
- printChanged(props, prev.current, "");
20
+ printChanged(props, prev.current, "", 0, maxDepth);
21
21
  prev.current = props;
22
22
  });
23
23
  }