@firecms/core 3.0.1 → 3.1.0-canary.768c91f

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 (185) hide show
  1. package/README.md +1 -1
  2. package/dist/components/AIIcon.d.ts +16 -0
  3. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +7 -1
  4. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
  5. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +14 -0
  6. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +6 -0
  7. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +5 -4
  8. package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +6 -0
  9. package/dist/components/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +2 -2
  10. package/dist/components/EntityCollectionView/Board.d.ts +2 -0
  11. package/dist/components/EntityCollectionView/BoardColumn.d.ts +42 -0
  12. package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +9 -0
  13. package/dist/components/EntityCollectionView/BoardSortableList.d.ts +14 -0
  14. package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +26 -0
  15. package/dist/components/EntityCollectionView/EntityCard.d.ts +19 -0
  16. package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +20 -0
  17. package/dist/components/EntityCollectionView/EntityCollectionCardView.d.ts +31 -0
  18. package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +2 -2
  19. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +7 -3
  20. package/dist/components/EntityCollectionView/FiltersDialog.d.ts +14 -0
  21. package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +44 -0
  22. package/dist/components/EntityCollectionView/board_types.d.ts +105 -0
  23. package/dist/components/EntityCollectionView/useBoardDataController.d.ts +60 -0
  24. package/dist/components/ErrorBoundary.d.ts +1 -1
  25. package/dist/components/SelectableTable/SelectableTable.d.ts +5 -1
  26. package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +2 -1
  27. package/dist/components/VirtualTable/VirtualTableCell.d.ts +6 -0
  28. package/dist/components/VirtualTable/VirtualTableHeader.d.ts +3 -1
  29. package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
  30. package/dist/components/VirtualTable/VirtualTableProps.d.ts +11 -0
  31. package/dist/components/VirtualTable/fields/VirtualTableDateField.d.ts +1 -0
  32. package/dist/components/VirtualTable/types.d.ts +2 -0
  33. package/dist/components/index.d.ts +3 -0
  34. package/dist/contexts/index.d.ts +10 -0
  35. package/dist/core/DrawerNavigationGroup.d.ts +45 -0
  36. package/dist/core/index.d.ts +1 -0
  37. package/dist/form/components/ErrorFocus.d.ts +1 -1
  38. package/dist/form/validation.d.ts +3 -2
  39. package/dist/hooks/useBreadcrumbsController.d.ts +16 -0
  40. package/dist/hooks/useCollapsedGroups.d.ts +4 -1
  41. package/dist/index.es.js +5266 -1578
  42. package/dist/index.es.js.map +1 -1
  43. package/dist/index.umd.js +5260 -1573
  44. package/dist/index.umd.js.map +1 -1
  45. package/dist/internal/useRestoreScroll.d.ts +1 -1
  46. package/dist/preview/PropertyPreviewProps.d.ts +5 -0
  47. package/dist/preview/components/DatePreview.d.ts +13 -3
  48. package/dist/preview/components/ImagePreview.d.ts +5 -1
  49. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  50. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  51. package/dist/preview/property_previews/ArrayOfStorageComponentsPreview.d.ts +1 -1
  52. package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +1 -1
  53. package/dist/preview/property_previews/SkeletonPropertyComponent.d.ts +1 -1
  54. package/dist/types/analytics.d.ts +1 -1
  55. package/dist/types/collections.d.ts +50 -2
  56. package/dist/types/datasource.d.ts +0 -1
  57. package/dist/types/plugins.d.ts +62 -1
  58. package/dist/types/properties.d.ts +259 -4
  59. package/dist/util/__tests__/conditions.test.d.ts +1 -0
  60. package/dist/util/__tests__/objects.test.d.ts +1 -0
  61. package/dist/util/conditions.d.ts +26 -0
  62. package/dist/util/entities.d.ts +2 -3
  63. package/dist/util/index.d.ts +2 -1
  64. package/dist/util/property_utils.d.ts +2 -1
  65. package/dist/util/resolutions.d.ts +3 -3
  66. package/package.json +14 -11
  67. package/src/app/Scaffold.tsx +14 -15
  68. package/src/components/AIIcon.tsx +39 -0
  69. package/src/components/ArrayContainer.tsx +1 -4
  70. package/src/components/ClearFilterSortButton.tsx +19 -16
  71. package/src/components/ConfirmationDialog.tsx +0 -2
  72. package/src/components/DeleteEntityDialog.tsx +2 -4
  73. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +74 -41
  74. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +130 -79
  75. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +121 -104
  76. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +132 -103
  77. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +20 -42
  78. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +90 -49
  79. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
  80. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
  81. package/src/components/EntityCollectionView/Board.tsx +324 -0
  82. package/src/components/EntityCollectionView/BoardColumn.tsx +158 -0
  83. package/src/components/EntityCollectionView/BoardColumnTitle.tsx +45 -0
  84. package/src/components/EntityCollectionView/BoardSortableList.tsx +172 -0
  85. package/src/components/EntityCollectionView/EntityBoardCard.tsx +212 -0
  86. package/src/components/EntityCollectionView/EntityCard.tsx +235 -0
  87. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +733 -0
  88. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +244 -0
  89. package/src/components/EntityCollectionView/EntityCollectionView.tsx +519 -203
  90. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +31 -19
  91. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +84 -15
  92. package/src/components/EntityCollectionView/FiltersDialog.tsx +249 -0
  93. package/src/components/EntityCollectionView/ViewModeToggle.tsx +199 -0
  94. package/src/components/EntityCollectionView/board_types.ts +113 -0
  95. package/src/components/EntityCollectionView/useBoardDataController.tsx +490 -0
  96. package/src/components/ErrorTooltip.tsx +2 -1
  97. package/src/components/HomePage/DefaultHomePage.tsx +47 -10
  98. package/src/components/HomePage/HomePageDnD.tsx +56 -41
  99. package/src/components/HomePage/NavigationCard.tsx +20 -18
  100. package/src/components/HomePage/NavigationGroup.tsx +17 -16
  101. package/src/components/HomePage/RenameGroupDialog.tsx +0 -2
  102. package/src/components/HomePage/SmallNavigationCard.tsx +10 -9
  103. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -10
  104. package/src/components/ReferenceWidget.tsx +2 -4
  105. package/src/components/SelectableTable/SelectableTable.tsx +75 -67
  106. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +7 -6
  107. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +39 -40
  108. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +38 -38
  109. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +49 -58
  110. package/src/components/UnsavedChangesDialog.tsx +0 -2
  111. package/src/components/UserDisplay.tsx +4 -4
  112. package/src/components/VirtualTable/VirtualTable.tsx +272 -118
  113. package/src/components/VirtualTable/VirtualTableCell.tsx +18 -2
  114. package/src/components/VirtualTable/VirtualTableHeader.tsx +59 -50
  115. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +158 -42
  116. package/src/components/VirtualTable/VirtualTableProps.tsx +14 -1
  117. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  118. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -0
  119. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +19 -6
  120. package/src/components/VirtualTable/types.tsx +2 -0
  121. package/src/components/common/useColumnsIds.tsx +95 -3
  122. package/src/components/index.tsx +4 -0
  123. package/src/contexts/BreacrumbsContext.tsx +15 -8
  124. package/src/contexts/index.ts +10 -0
  125. package/src/core/DefaultAppBar.tsx +40 -27
  126. package/src/core/DefaultDrawer.tsx +42 -56
  127. package/src/core/DrawerNavigationGroup.tsx +118 -0
  128. package/src/core/DrawerNavigationItem.tsx +4 -3
  129. package/src/core/EntityEditView.tsx +41 -43
  130. package/src/core/EntitySidePanel.tsx +28 -26
  131. package/src/core/SideDialogs.tsx +4 -2
  132. package/src/core/field_configs.tsx +14 -9
  133. package/src/core/index.tsx +1 -0
  134. package/src/form/EntityForm.tsx +69 -60
  135. package/src/form/PropertyFieldBinding.tsx +61 -46
  136. package/src/form/components/ErrorFocus.tsx +3 -3
  137. package/src/form/components/StorageItemPreview.tsx +2 -1
  138. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +0 -1
  139. package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -16
  140. package/src/form/field_bindings/KeyValueFieldBinding.tsx +0 -1
  141. package/src/form/field_bindings/MapFieldBinding.tsx +69 -67
  142. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +22 -18
  143. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +83 -83
  144. package/src/form/field_bindings/TextFieldBinding.tsx +71 -35
  145. package/src/form/validation.ts +245 -160
  146. package/src/hooks/useBreadcrumbsController.tsx +18 -0
  147. package/src/hooks/useBuildNavigationController.tsx +46 -23
  148. package/src/hooks/useCollapsedGroups.ts +12 -4
  149. package/src/hooks/useValidateAuthenticator.tsx +1 -1
  150. package/src/internal/useBuildDataSource.ts +68 -34
  151. package/src/internal/useBuildSideDialogsController.tsx +11 -8
  152. package/src/internal/useBuildSideEntityController.tsx +2 -4
  153. package/src/internal/useRestoreScroll.tsx +26 -14
  154. package/src/preview/PropertyPreview.tsx +41 -32
  155. package/src/preview/PropertyPreviewProps.tsx +6 -0
  156. package/src/preview/components/DatePreview.tsx +72 -4
  157. package/src/preview/components/EmptyValue.tsx +1 -1
  158. package/src/preview/components/ImagePreview.tsx +37 -21
  159. package/src/preview/components/StorageThumbnail.tsx +16 -12
  160. package/src/preview/components/UrlComponentPreview.tsx +28 -25
  161. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +9 -7
  162. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +11 -9
  163. package/src/preview/property_previews/ArrayPropertyPreview.tsx +26 -24
  164. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +61 -56
  165. package/src/routes/CustomCMSRoute.tsx +1 -0
  166. package/src/routes/FireCMSRoute.tsx +26 -13
  167. package/src/types/analytics.ts +10 -0
  168. package/src/types/collections.ts +57 -3
  169. package/src/types/datasource.ts +54 -56
  170. package/src/types/plugins.tsx +69 -1
  171. package/src/types/properties.ts +347 -27
  172. package/src/util/__tests__/conditions.test.ts +506 -0
  173. package/src/util/__tests__/objects.test.ts +196 -0
  174. package/src/util/callbacks.ts +6 -3
  175. package/src/util/collections.ts +51 -6
  176. package/src/util/conditions.ts +339 -0
  177. package/src/util/entities.ts +29 -30
  178. package/src/util/entity_cache.ts +2 -1
  179. package/src/util/index.ts +2 -1
  180. package/src/util/join_collections.ts +10 -8
  181. package/src/util/objects.ts +31 -13
  182. package/src/util/{references.ts → previews.ts} +16 -2
  183. package/src/util/property_utils.tsx +37 -11
  184. package/src/util/resolutions.ts +62 -58
  185. /package/dist/util/{references.d.ts → previews.d.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  export declare function useRestoreScroll(): {
3
- containerRef: React.RefObject<HTMLDivElement>;
3
+ containerRef: React.RefObject<HTMLDivElement | null>;
4
4
  scroll: number;
5
5
  direction: "up" | "down";
6
6
  };
@@ -42,4 +42,9 @@ export interface PropertyPreviewProps<T extends CMSType = any, CustomProps = any
42
42
  * This applies only to videos.
43
43
  */
44
44
  interactive?: boolean;
45
+ /**
46
+ * If true, image previews will fill their container completely.
47
+ * Only applies to image type properties.
48
+ */
49
+ fill?: boolean;
45
50
  }
@@ -1,7 +1,17 @@
1
1
  import React from "react";
2
+ export interface DatePreviewProps {
3
+ date: Date;
4
+ /**
5
+ * Display mode: "date" for date-only, "date_time" for date and time
6
+ */
7
+ mode?: "date" | "date_time";
8
+ /**
9
+ * IANA timezone identifier (e.g., "America/New_York")
10
+ * When specified, the date will be displayed in this timezone
11
+ */
12
+ timezone?: string;
13
+ }
2
14
  /**
3
15
  * @group Preview components
4
16
  */
5
- export declare function DatePreview({ date }: {
6
- date: Date;
7
- }): React.ReactElement;
17
+ export declare function DatePreview({ date, mode, timezone }: DatePreviewProps): React.ReactElement;
@@ -5,8 +5,12 @@ import { PreviewSize } from "../PropertyPreviewProps";
5
5
  export interface ImagePreviewProps {
6
6
  size: PreviewSize;
7
7
  url: string;
8
+ /**
9
+ * If true, image fills its container completely with object-fit cover
10
+ */
11
+ fill?: boolean;
8
12
  }
9
13
  /**
10
14
  * @group Preview components
11
15
  */
12
- export declare function ImagePreview({ size, url }: ImagePreviewProps): import("react/jsx-runtime").JSX.Element;
16
+ export declare function ImagePreview({ size, url, fill }: ImagePreviewProps): import("react/jsx-runtime").JSX.Element;
@@ -5,10 +5,11 @@ type StorageThumbnailProps = {
5
5
  storeUrl: boolean;
6
6
  size: PreviewSize;
7
7
  interactive?: boolean;
8
+ fill?: boolean;
8
9
  };
9
10
  /**
10
11
  * @group Preview components
11
12
  */
12
13
  export declare const StorageThumbnail: React.FunctionComponent<StorageThumbnailProps>;
13
- export declare function StorageThumbnailInternal({ storeUrl, interactive, storagePathOrDownloadUrl, size }: StorageThumbnailProps): import("react/jsx-runtime").JSX.Element | null;
14
+ export declare function StorageThumbnailInternal({ storeUrl, interactive, storagePathOrDownloadUrl, size, fill }: StorageThumbnailProps): import("react/jsx-runtime").JSX.Element | null;
14
15
  export {};
@@ -4,10 +4,11 @@ import { PreviewSize } from "../PropertyPreviewProps";
4
4
  /**
5
5
  * @group Preview components
6
6
  */
7
- export declare function UrlComponentPreview({ url, previewType, size, hint, interactive }: {
7
+ export declare function UrlComponentPreview({ url, previewType, size, hint, interactive, fill }: {
8
8
  url: string;
9
9
  previewType?: PreviewType;
10
10
  size: PreviewSize;
11
11
  hint?: string;
12
12
  interactive?: boolean;
13
+ fill?: boolean;
13
14
  }): React.ReactElement;
@@ -2,4 +2,4 @@ import { PropertyPreviewProps } from "../PropertyPreviewProps";
2
2
  /**
3
3
  * @group Preview components
4
4
  */
5
- export declare function ArrayOfStorageComponentsPreview({ propertyKey, value, property: inputProperty, size }: PropertyPreviewProps<any[]>): import("react/jsx-runtime").JSX.Element;
5
+ export declare function ArrayOfStorageComponentsPreview({ propertyKey, value, property: inputProperty, size }: PropertyPreviewProps<any[]>): import("react/jsx-runtime").JSX.Element | null;
@@ -2,4 +2,4 @@ import { PropertyPreviewProps } from "../../preview";
2
2
  /**
3
3
  * @group Preview components
4
4
  */
5
- export declare function ArrayOfStringsPreview({ propertyKey, value, property: inputProperty, size }: PropertyPreviewProps<string[]>): import("react/jsx-runtime").JSX.Element;
5
+ export declare function ArrayOfStringsPreview({ propertyKey, value, property: inputProperty, size }: PropertyPreviewProps<string[]>): import("react/jsx-runtime").JSX.Element | null;
@@ -8,7 +8,7 @@ export interface SkeletonPropertyComponentProps {
8
8
  * @group Preview components
9
9
  */
10
10
  export declare function SkeletonPropertyComponent({ property, size }: SkeletonPropertyComponentProps): any;
11
- export declare function renderSkeletonImageThumbnail(size: PreviewSize): import("react/jsx-runtime").JSX.Element;
11
+ export declare function renderSkeletonImageThumbnail(size: PreviewSize, fill?: boolean): import("react/jsx-runtime").JSX.Element;
12
12
  export declare function renderSkeletonText(index?: number, width?: number): import("react/jsx-runtime").JSX.Element;
13
13
  export declare function renderSkeletonCaptionText(index?: number): import("react/jsx-runtime").JSX.Element;
14
14
  export declare function renderSkeletonIcon(): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- export type CMSAnalyticsEvent = "entity_click" | "entity_click_from_reference" | "reference_selection_clear" | "reference_selection_toggle" | "reference_selected_single" | "reference_selection_new_entity" | "edit_entity_clicked" | "entity_edited" | "new_entity_click" | "new_entity_saved" | "copy_entity_click" | "entity_copied" | "single_delete_dialog_open" | "multiple_delete_dialog_open" | "single_entity_deleted" | "multiple_entities_deleted" | "drawer_navigate_to_home" | "drawer_navigate_to_collection" | "drawer_navigate_to_view" | "home_navigate_to_collection" | "home_favorite_navigate_to_collection" | "home_navigate_to_view" | "home_navigate_to_admin_view" | "home_favorite_navigate_to_view" | "home_move_card" | "home_move_group" | "home_drop_new_group" | "collection_inline_editing" | "unmapped_event";
1
+ export type CMSAnalyticsEvent = "entity_click" | "entity_click_from_reference" | "reference_selection_clear" | "reference_selection_toggle" | "reference_selected_single" | "reference_selection_new_entity" | "edit_entity_clicked" | "entity_edited" | "new_entity_click" | "new_entity_saved" | "copy_entity_click" | "entity_copied" | "single_delete_dialog_open" | "multiple_delete_dialog_open" | "single_entity_deleted" | "multiple_entities_deleted" | "drawer_navigate_to_home" | "drawer_navigate_to_collection" | "drawer_navigate_to_view" | "home_navigate_to_collection" | "home_favorite_navigate_to_collection" | "home_navigate_to_view" | "home_navigate_to_admin_view" | "home_favorite_navigate_to_view" | "home_move_card" | "home_move_group" | "home_drop_new_group" | "collection_inline_editing" | "view_mode_changed" | "kanban_card_moved" | "kanban_column_reorder" | "kanban_property_changed" | "kanban_new_entity_in_column" | "kanban_backfill_order" | "card_view_entity_click" | "unmapped_event";
@@ -318,7 +318,54 @@ export interface EntityCollection<M extends Record<string, any> = any, USER exte
318
318
  * Defaults to `manual_apply`.
319
319
  */
320
320
  localChangesBackup?: "manual_apply" | "auto_apply" | false;
321
+ /**
322
+ * Default view mode for displaying this collection.
323
+ * - "table": Display entities in a spreadsheet-like table (default)
324
+ * - "cards": Display entities as a grid of cards with thumbnails
325
+ * - "kanban": Display entities in a Kanban board grouped by a property
326
+ * Defaults to "table".
327
+ */
328
+ defaultViewMode?: ViewMode;
329
+ /**
330
+ * Which view modes are available for this collection.
331
+ * Possible values: "table", "cards", "kanban".
332
+ * Defaults to all three: ["table", "cards", "kanban"].
333
+ * Note: "kanban" will only be available if the collection has at least
334
+ * one string property with enumValues defined, regardless of this setting.
335
+ */
336
+ enabledViews?: ViewMode[];
337
+ /**
338
+ * Configuration for Kanban board view mode.
339
+ * When set, the Kanban view mode becomes available.
340
+ */
341
+ kanban?: KanbanConfig<M>;
342
+ /**
343
+ * Property key to use for ordering items.
344
+ * Must reference a number property. When items are reordered,
345
+ * this property will be updated to reflect the new order using
346
+ * fractional indexing. Used by Kanban view for ordering within columns
347
+ * and can be used for general ordering purposes.
348
+ */
349
+ orderProperty?: Extract<keyof M, string>;
321
350
  }
351
+ /**
352
+ * Configuration for Kanban board view mode.
353
+ * @group Collections
354
+ */
355
+ export interface KanbanConfig<M extends Record<string, any> = any> {
356
+ /**
357
+ * Property key to use for Kanban board columns.
358
+ * Must reference a string property with enumValues defined.
359
+ * Entities will be grouped into columns based on this property's value.
360
+ * The column order is determined by the order of enumValues in the property.
361
+ */
362
+ columnProperty: Extract<keyof M, string>;
363
+ }
364
+ /**
365
+ * View mode for displaying a collection.
366
+ * @group Collections
367
+ */
368
+ export type ViewMode = "table" | "cards" | "kanban";
322
369
  /**
323
370
  * Parameter passed to the `Actions` prop in the collection configuration.
324
371
  * The component will receive this prop when it is rendered in the collection
@@ -359,9 +406,10 @@ export interface CollectionActionsProps<M extends Record<string, any> = any, USE
359
406
  */
360
407
  context: FireCMSContext<USER>;
361
408
  /**
362
- * Count of the entities in this collection
409
+ * Count of the entities in this collection.
410
+ * undefined means the count is still loading.
363
411
  */
364
- collectionEntitiesCount: number;
412
+ collectionEntitiesCount?: number;
365
413
  }
366
414
  /**
367
415
  * Use this controller to retrieve the selected entities or modify them in
@@ -267,7 +267,6 @@ export interface DataSourceDelegate {
267
267
  currentTime?: () => any;
268
268
  delegateToCMSModel: (data: any) => any;
269
269
  cmsToDelegateModel: (data: any) => any;
270
- setDateToMidnight: (input?: any) => any;
271
270
  initTextSearch?: (props: {
272
271
  context: FireCMSContext;
273
272
  path: string;
@@ -6,7 +6,7 @@ import { FieldProps, FormContext } from "./fields";
6
6
  import { CMSType, Property } from "./properties";
7
7
  import { EntityStatus } from "./entities";
8
8
  import { ResolvedProperty } from "./resolved_entities";
9
- import { NavigationGroupMapping } from "./navigation";
9
+ import { NavigationGroupMapping, CMSView } from "./navigation";
10
10
  import { InternalUserManagement } from "./internal_user_management";
11
11
  /**
12
12
  * Interface used to define plugins for FireCMS.
@@ -39,6 +39,11 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
39
39
  props?: PROPS;
40
40
  };
41
41
  userManagement?: InternalUserManagement;
42
+ /**
43
+ * Views to be automatically added to the navigation.
44
+ * These views will be merged with the views provided to useBuildNavigationController.
45
+ */
46
+ views?: CMSView[];
42
47
  homePage?: {
43
48
  /**
44
49
  * Additional actions to be rendered in the home page, close to the search bar.
@@ -86,6 +91,18 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
86
91
  onNavigationEntriesUpdate?: (entries: NavigationGroupMapping[]) => void;
87
92
  };
88
93
  collectionView?: {
94
+ /**
95
+ * Custom component to render when a collection loading error occurs.
96
+ * If provided, this replaces the default error view in all collection view modes
97
+ * (table, card, kanban).
98
+ * Return `null` from the component to fall back to the default error view.
99
+ */
100
+ CollectionError?: React.ComponentType<{
101
+ path: string;
102
+ collection: EC;
103
+ parentCollectionIds?: string[];
104
+ error: Error;
105
+ }>;
89
106
  /**
90
107
  * Use this component to add custom actions to the entity collections
91
108
  * toolbar.
@@ -135,6 +152,46 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
135
152
  collection: EC;
136
153
  tableController: EntityTableController;
137
154
  }>;
155
+ /**
156
+ * Callback called when columns are reordered via drag and drop.
157
+ * Used by plugins to persist the new column order.
158
+ */
159
+ onColumnsReorder?: (props: {
160
+ fullPath: string;
161
+ parentCollectionIds: string[];
162
+ collection: EC;
163
+ newPropertiesOrder: string[];
164
+ }) => void;
165
+ /**
166
+ * Callback called when Kanban board columns are reordered via drag and drop.
167
+ * Used by plugins to persist the new Kanban column order.
168
+ */
169
+ onKanbanColumnsReorder?: (props: {
170
+ fullPath: string;
171
+ parentCollectionIds: string[];
172
+ collection: EC;
173
+ kanbanColumnProperty: string;
174
+ newColumnsOrder: string[];
175
+ }) => void;
176
+ /**
177
+ * Component to render when Kanban view is missing configuration.
178
+ * Used to provide a CTA to open the collection editor to configure Kanban.
179
+ */
180
+ KanbanSetupComponent?: React.ComponentType<{
181
+ collection: EC;
182
+ fullPath: string;
183
+ parentCollectionIds: string[];
184
+ }>;
185
+ /**
186
+ * Component to render an "Add Column" button at the end of the Kanban board.
187
+ * Used to allow adding new enum values to the column property.
188
+ */
189
+ AddKanbanColumnComponent?: React.ComponentType<{
190
+ collection: EC;
191
+ fullPath: string;
192
+ parentCollectionIds: string[];
193
+ columnProperty: string;
194
+ }>;
138
195
  };
139
196
  form?: {
140
197
  provider?: {
@@ -149,6 +206,10 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
149
206
  * Add custom actions to the top of the form
150
207
  */
151
208
  ActionsTop?: React.ComponentType<PluginFormActionProps<any, EC>>;
209
+ /**
210
+ * Add custom content above the entity title in the form view
211
+ */
212
+ BeforeTitle?: React.ComponentType<PluginFormActionProps<any, EC>>;
152
213
  fieldBuilder?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T, any, EC>) => React.ComponentType<FieldProps<T>> | null;
153
214
  fieldBuilderEnabled?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T>) => boolean;
154
215
  };
@@ -113,6 +113,18 @@ export interface BaseProperty<T extends CMSType, CustomProps = any> {
113
113
  * It defaults to 100, but you can set it to 50 to have two fields in the same row.
114
114
  */
115
115
  widthPercentage?: number;
116
+ /**
117
+ * Declarative conditions for dynamic property behavior using JSON Logic.
118
+ *
119
+ * An alternative to PropertyBuilder functions that can be:
120
+ * - Stored in the database as JSON
121
+ * - Edited via the collection editor UI
122
+ * - Evaluated at runtime like property builders
123
+ *
124
+ * @see PropertyConditions for available condition options
125
+ * @see https://jsonlogic.com/ for JSON Logic syntax
126
+ */
127
+ conditions?: PropertyConditions;
116
128
  }
117
129
  /**
118
130
  * @group Entity properties
@@ -136,6 +148,220 @@ export interface PropertyDisabledConfig {
136
148
  */
137
149
  hidden?: boolean;
138
150
  }
151
+ /**
152
+ * A JSON Logic rule that gets evaluated at runtime.
153
+ * @see https://jsonlogic.com/
154
+ *
155
+ * Common operators:
156
+ * - Comparison: ==, !=, ===, !==, >, <, >=, <=
157
+ * - Logic: and, or, !, !!
158
+ * - Data access: var, missing, missing_some
159
+ * - Array: in, map, filter, reduce, all, some, none, merge
160
+ * - String: substr, cat
161
+ * - Numeric: +, -, *, /, %, min, max
162
+ *
163
+ * Custom operators:
164
+ * - hasRole(roleId) - check if user has role by ID
165
+ * - hasAnyRole([roleIds]) - check if user has any of the roles
166
+ * - isToday(timestamp) - check if timestamp is today
167
+ * - isPast(timestamp) - check if timestamp is in the past
168
+ * - isFuture(timestamp) - check if timestamp is in the future
169
+ *
170
+ * @group Entity properties
171
+ */
172
+ export type JsonLogicRule = Record<string, any>;
173
+ /**
174
+ * Conditions for individual enum values within a property.
175
+ * @group Entity properties
176
+ */
177
+ export interface EnumValueConditions {
178
+ /**
179
+ * Disable this enum option when condition is true.
180
+ * The option appears grayed out and cannot be selected.
181
+ */
182
+ disabled?: JsonLogicRule;
183
+ /**
184
+ * Message explaining why this option is disabled.
185
+ */
186
+ disabledMessage?: string;
187
+ /**
188
+ * Completely hide this enum option when condition is true.
189
+ * The option is removed from the dropdown/list.
190
+ */
191
+ hidden?: JsonLogicRule;
192
+ }
193
+ /**
194
+ * Declarative conditions for dynamic property behavior.
195
+ * All conditions are JSON Logic rules evaluated against ConditionContext.
196
+ *
197
+ * An alternative to PropertyBuilder functions that can be:
198
+ * - Stored in the database as JSON
199
+ * - Edited via the collection editor UI
200
+ * - Evaluated at runtime like property builders
201
+ *
202
+ * @see https://jsonlogic.com/ for JSON Logic syntax
203
+ * @group Entity properties
204
+ */
205
+ export interface PropertyConditions {
206
+ /**
207
+ * Disable the field when this condition evaluates to true.
208
+ * The field becomes non-editable but still visible (unless also hidden).
209
+ *
210
+ * @example Disable when another field has a specific value
211
+ * ```json
212
+ * { "==": [{ "var": "values.status" }, "archived"] }
213
+ * ```
214
+ */
215
+ disabled?: JsonLogicRule;
216
+ /**
217
+ * Message to display when the field is disabled by a condition.
218
+ */
219
+ disabledMessage?: string;
220
+ /**
221
+ * Clear the field's value when it becomes disabled.
222
+ * @default false
223
+ */
224
+ clearOnDisabled?: boolean;
225
+ /**
226
+ * Hide the field completely when this condition evaluates to true.
227
+ * The field is removed from the form (not just visually hidden).
228
+ */
229
+ hidden?: JsonLogicRule;
230
+ /**
231
+ * Make the field read-only when this condition evaluates to true.
232
+ * Renders as a preview instead of an input.
233
+ */
234
+ readOnly?: JsonLogicRule;
235
+ /**
236
+ * Make the field required when this condition evaluates to true.
237
+ * Overrides the static `validation.required` setting.
238
+ */
239
+ required?: JsonLogicRule;
240
+ /**
241
+ * Custom message when conditional required validation fails.
242
+ */
243
+ requiredMessage?: string;
244
+ /**
245
+ * Dynamic minimum value for number/string length.
246
+ * Should evaluate to a number.
247
+ */
248
+ min?: JsonLogicRule;
249
+ /**
250
+ * Dynamic maximum value for number/string length.
251
+ * Should evaluate to a number.
252
+ */
253
+ max?: JsonLogicRule;
254
+ /**
255
+ * Dynamic default value for new entities.
256
+ * Should evaluate to a value of the appropriate type for the field.
257
+ * Only applied when entityId is empty (new entity).
258
+ */
259
+ defaultValue?: JsonLogicRule;
260
+ /**
261
+ * Conditions for individual enum values.
262
+ * Keys are the enum value IDs, values are condition configs.
263
+ *
264
+ * @example Disable certain enum options based on user role
265
+ * ```json
266
+ * {
267
+ * "admin": {
268
+ * "disabled": { "!": { "hasRole": "admin" } },
269
+ * "disabledMessage": "Admin option requires admin role"
270
+ * }
271
+ * }
272
+ * ```
273
+ */
274
+ enumConditions?: Record<string | number, EnumValueConditions>;
275
+ /**
276
+ * Filter which enum values are available.
277
+ * Should evaluate to an array of allowed enum value IDs.
278
+ */
279
+ allowedEnumValues?: JsonLogicRule;
280
+ /**
281
+ * Exclude specific enum values.
282
+ * Should evaluate to an array of enum value IDs to exclude.
283
+ */
284
+ excludedEnumValues?: JsonLogicRule;
285
+ /**
286
+ * Dynamic path for reference properties.
287
+ * Should evaluate to a collection path string.
288
+ */
289
+ referencePath?: JsonLogicRule;
290
+ /**
291
+ * Dynamic filter for reference selection.
292
+ * Should evaluate to a FilterValues object.
293
+ */
294
+ referenceFilter?: JsonLogicRule;
295
+ /**
296
+ * Can elements be added to the array?
297
+ */
298
+ canAddElements?: JsonLogicRule;
299
+ /**
300
+ * Can elements be reordered in the array?
301
+ */
302
+ sortable?: JsonLogicRule;
303
+ /**
304
+ * Dynamic accepted file types.
305
+ * Should evaluate to an array of MIME types.
306
+ */
307
+ acceptedFiles?: JsonLogicRule;
308
+ /**
309
+ * Dynamic maximum file size in bytes.
310
+ * Should evaluate to a number.
311
+ */
312
+ maxFileSize?: JsonLogicRule;
313
+ }
314
+ /**
315
+ * Context available during JSON Logic condition evaluation.
316
+ * Mirrors PropertyBuilderProps but adapted for JSON serialization.
317
+ * @group Entity properties
318
+ */
319
+ export interface ConditionContext {
320
+ /**
321
+ * Current form/entity values.
322
+ * Date values are converted to Unix timestamps (milliseconds).
323
+ */
324
+ values: Record<string, any>;
325
+ /**
326
+ * Previous values before the current edit session.
327
+ */
328
+ previousValues: Record<string, any>;
329
+ /**
330
+ * Current value of this property specifically.
331
+ */
332
+ propertyValue: any;
333
+ /**
334
+ * Collection path (e.g., "products", "users/uid123/orders")
335
+ */
336
+ path: string;
337
+ /**
338
+ * Entity ID. Undefined for new entities.
339
+ */
340
+ entityId?: string;
341
+ /**
342
+ * Whether this is a new entity being created.
343
+ */
344
+ isNew: boolean;
345
+ /**
346
+ * Index of this property (only for array items).
347
+ */
348
+ index?: number;
349
+ /**
350
+ * Current authenticated user information.
351
+ */
352
+ user: {
353
+ uid: string;
354
+ email: string | null;
355
+ displayName: string | null;
356
+ photoURL: string | null;
357
+ /** Role IDs the user has (extracted from Role[].id) */
358
+ roles: string[];
359
+ };
360
+ /**
361
+ * Current timestamp as Unix milliseconds.
362
+ */
363
+ now: number;
364
+ }
139
365
  /**
140
366
  * @group Entity properties
141
367
  */
@@ -262,6 +488,25 @@ export interface BooleanProperty extends BaseProperty<boolean> {
262
488
  */
263
489
  validation?: PropertyValidationSchema;
264
490
  }
491
+ /**
492
+ * Configuration options for the markdown editor.
493
+ * @group Entity properties
494
+ */
495
+ export interface MarkdownConfig {
496
+ /**
497
+ * Allow HTML input/output. When set to false, HTML tags in pasted content
498
+ * will be stripped and only markdown-compatible formatting will be preserved.
499
+ * Defaults to true for backwards compatibility.
500
+ */
501
+ html?: boolean;
502
+ /**
503
+ * Convert pasted text to markdown format. When enabled, rich text pasted
504
+ * from external sources (like Google Docs or Word) will be converted to
505
+ * clean markdown instead of preserving HTML styles.
506
+ * Defaults to false.
507
+ */
508
+ transformPastedText?: boolean;
509
+ }
265
510
  /**
266
511
  * @group Entity properties
267
512
  */
@@ -275,10 +520,13 @@ export interface StringProperty extends BaseProperty<string> {
275
520
  multiline?: boolean;
276
521
  /**
277
522
  * Should this string property be displayed as a markdown field. If true,
278
- * the field is rendered as a text editors that supports markdown highlight
523
+ * the field is rendered as a text editor that supports markdown highlight
279
524
  * syntax. It also includes a preview of the result.
525
+ *
526
+ * You can also pass a configuration object to customize the markdown editor
527
+ * behavior, particularly how HTML content is handled during paste operations.
280
528
  */
281
- markdown?: boolean;
529
+ markdown?: boolean | MarkdownConfig;
282
530
  /**
283
531
  * You can use the enum values providing a map of possible
284
532
  * exclusive values the property can take, mapped to the label that it is
@@ -486,6 +734,13 @@ export interface DateProperty extends BaseProperty<Date> {
486
734
  * Add an icon to clear the value and set it to `null`. Defaults to `false`
487
735
  */
488
736
  clearable?: boolean;
737
+ /**
738
+ * IANA timezone string (e.g., "America/New_York", "Europe/London").
739
+ * Used to display and input dates in the specified timezone.
740
+ * The value stored will always be in UTC.
741
+ * If not provided, uses the user's local timezone.
742
+ */
743
+ timezone?: string;
489
744
  }
490
745
  /**
491
746
  * @group Entity properties
@@ -764,7 +1019,7 @@ export interface ImageResize {
764
1019
  * - `contain`: Scale down to fit within bounds, preserving aspect ratio (default)
765
1020
  * - `cover`: Scale to fill bounds, preserving aspect ratio (may crop)
766
1021
  */
767
- mode?: 'contain' | 'cover';
1022
+ mode?: "contain" | "cover";
768
1023
  /**
769
1024
  * Output format for the resized image.
770
1025
  * - `original`: Keep the original format (default)
@@ -772,7 +1027,7 @@ export interface ImageResize {
772
1027
  * - `png`: Convert to PNG
773
1028
  * - `webp`: Convert to WebP
774
1029
  */
775
- format?: 'original' | 'jpeg' | 'png' | 'webp';
1030
+ format?: "original" | "jpeg" | "png" | "webp";
776
1031
  /**
777
1032
  * Quality for lossy formats (JPEG, WebP). Number between 0 and 100.
778
1033
  * Higher is better quality but larger file size. Defaults to 80.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ import { AuthController, ConditionContext, JsonLogicRule, ResolvedProperty, CMSType } from "../types";
2
+ /**
3
+ * Register custom JSON Logic operations for FireCMS.
4
+ * Call this once at app initialization.
5
+ */
6
+ export declare function registerConditionOperations(): void;
7
+ /**
8
+ * Evaluate a JSON Logic rule against the given context.
9
+ */
10
+ export declare function evaluateCondition(rule: JsonLogicRule, context: ConditionContext): any;
11
+ /**
12
+ * Build a ConditionContext from the current property resolution context.
13
+ */
14
+ export declare function buildConditionContext(params: {
15
+ propertyKey?: string;
16
+ values?: Record<string, any>;
17
+ previousValues?: Record<string, any>;
18
+ path: string;
19
+ entityId?: string;
20
+ index?: number;
21
+ authController: AuthController;
22
+ }): ConditionContext;
23
+ /**
24
+ * Apply PropertyConditions to a resolved property, evaluating all JSON Logic rules.
25
+ */
26
+ export declare function applyPropertyConditions<T extends CMSType>(property: ResolvedProperty<T>, context: ConditionContext): ResolvedProperty<T>;
@@ -1,7 +1,7 @@
1
1
  import { CMSType, DataType, Entity, EntityReference, EntityStatus, EntityValues, PropertiesOrBuilders, Property, PropertyBuilder, PropertyOrBuilder, ResolvedProperties, ResolvedProperty } from "../types";
2
2
  export declare function isReadOnly(property: Property<any> | ResolvedProperty<any>): boolean;
3
3
  export declare function isHidden(property: Property | ResolvedProperty): boolean;
4
- export declare function isPropertyBuilder<T extends CMSType, M extends Record<string, any>>(propertyOrBuilder?: PropertyOrBuilder<T, M> | Property<T> | ResolvedProperty<T>): propertyOrBuilder is PropertyBuilder<T, M>;
4
+ export declare function isPropertyBuilder<T extends CMSType = CMSType, M extends Record<string, any> = any>(propertyOrBuilder?: PropertyOrBuilder<T, M> | Property | ResolvedProperty): propertyOrBuilder is PropertyBuilder<T, M>;
5
5
  export declare function getDefaultValuesFor<M extends Record<string, any>>(properties: PropertiesOrBuilders<M> | ResolvedProperties<M>): Partial<EntityValues<M>>;
6
6
  export declare function getDefaultValueFor(property?: PropertyOrBuilder): {} | null | undefined;
7
7
  export declare function getDefaultValueForDataType(dataType: DataType): {} | null;
@@ -9,12 +9,11 @@ export declare function getDefaultValueForDataType(dataType: DataType): {} | nul
9
9
  * Update the automatic values in an entity before save
10
10
  * @group Datasource
11
11
  */
12
- export declare function updateDateAutoValues<M extends Record<string, any>>({ inputValues, properties, status, timestampNowValue, setDateToMidnight }: {
12
+ export declare function updateDateAutoValues<M extends Record<string, any>>({ inputValues, properties, status, timestampNowValue }: {
13
13
  inputValues: Partial<EntityValues<M>>;
14
14
  properties: ResolvedProperties<M>;
15
15
  status: EntityStatus;
16
16
  timestampNowValue: any;
17
- setDateToMidnight: (input?: any) => any | undefined;
18
17
  }): EntityValues<M>;
19
18
  /**
20
19
  * Add missing required fields, expected in the collection, to the values of an entity
@@ -16,7 +16,7 @@ export * from "./icon_list";
16
16
  export * from "./icon_synonyms";
17
17
  export * from "./icons";
18
18
  export * from "./plurals";
19
- export * from "./references";
19
+ export * from "./previews";
20
20
  export * from "./flatten_object";
21
21
  export * from "./make_properties_editable";
22
22
  export * from "./join_collections";
@@ -24,3 +24,4 @@ export * from "./builders";
24
24
  export * from "./useTraceUpdate";
25
25
  export * from "./storage";
26
26
  export * from "./callbacks";
27
+ export * from "./conditions";