@firecms/core 3.0.0-alpha.72 → 3.0.0-alpha.74

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 (65) hide show
  1. package/dist/components/{EntityCollectionTable/internal/DeleteEntityDialog.d.ts → DeleteEntityDialog.d.ts} +1 -1
  2. package/dist/components/EntityCollectionTable/{internal/EntityCollectionRowActions.d.ts → EntityCollectionRowActions.d.ts} +3 -3
  3. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
  4. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +3 -3
  5. package/dist/components/EntityCollectionTable/{internal/PropertyTableCell.d.ts → PropertyTableCell.d.ts} +2 -2
  6. package/dist/components/EntityCollectionTable/SimpleEntityCollectionTable.d.ts +95 -0
  7. package/dist/components/EntityCollectionTable/column_utils.d.ts +16 -0
  8. package/dist/components/EntityCollectionTable/index.d.ts +4 -0
  9. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -1
  10. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
  11. package/dist/components/EntityCollectionTable/types.d.ts +2 -2
  12. package/dist/components/EntityCollectionTable/useDataSourceEntityCollectionTableController.d.ts +3 -3
  13. package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +2 -2
  14. package/dist/components/VirtualTable/VirtualTableCell.d.ts +1 -1
  15. package/dist/components/VirtualTable/VirtualTableProps.d.ts +2 -3
  16. package/dist/components/VirtualTable/types.d.ts +1 -1
  17. package/dist/form/components/FieldHelperText.d.ts +1 -1
  18. package/dist/index.es.js +5004 -4214
  19. package/dist/index.es.js.map +1 -1
  20. package/dist/index.umd.js +587 -4
  21. package/dist/index.umd.js.map +1 -1
  22. package/dist/types/collections.d.ts +2 -2
  23. package/dist/types/plugins.d.ts +2 -0
  24. package/package.json +3 -3
  25. package/src/components/{EntityCollectionTable/internal/DeleteEntityDialog.tsx → DeleteEntityDialog.tsx} +4 -4
  26. package/src/components/EntityCollectionTable/{internal/EntityCollectionRowActions.tsx → EntityCollectionRowActions.tsx} +4 -4
  27. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +13 -48
  28. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +3 -3
  29. package/src/components/EntityCollectionTable/{internal/PropertyTableCell.tsx → PropertyTableCell.tsx} +19 -18
  30. package/src/components/EntityCollectionTable/SimpleEntityCollectionTable.tsx +369 -0
  31. package/src/components/EntityCollectionTable/column_utils.tsx +74 -0
  32. package/src/components/EntityCollectionTable/index.tsx +4 -0
  33. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -3
  34. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +1 -2
  35. package/src/components/EntityCollectionTable/internal/default_entity_actions.tsx +1 -1
  36. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +18 -18
  37. package/src/components/EntityCollectionTable/types.tsx +2 -2
  38. package/src/components/EntityCollectionTable/useDataSourceEntityCollectionTableController.tsx +3 -3
  39. package/src/components/EntityCollectionView/EntityCollectionView.tsx +4 -4
  40. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +2 -2
  41. package/src/components/ReferenceSelectionInner.tsx +1 -1
  42. package/src/components/VirtualTable/VirtualTableCell.tsx +9 -13
  43. package/src/components/VirtualTable/VirtualTableProps.tsx +3 -4
  44. package/src/components/VirtualTable/VirtualTableRow.tsx +0 -1
  45. package/src/components/VirtualTable/types.tsx +1 -1
  46. package/src/core/EntitySidePanel.tsx +0 -1
  47. package/src/core/FireCMS.tsx +2 -2
  48. package/src/form/EntityForm.tsx +7 -8
  49. package/src/form/PropertyFieldBinding.tsx +3 -1
  50. package/src/form/components/FieldHelperText.tsx +2 -2
  51. package/src/form/field_bindings/DateTimeFieldBinding.tsx +2 -1
  52. package/src/form/field_bindings/MapFieldBinding.tsx +3 -9
  53. package/src/form/field_bindings/MarkdownFieldBinding.tsx +585 -585
  54. package/src/form/validation.ts +5 -1
  55. package/src/internal/EntityView.tsx +6 -6
  56. package/src/internal/useBuildDataSource.ts +0 -2
  57. package/src/internal/useBuildSideEntityController.tsx +27 -15
  58. package/src/preview/components/BooleanPreview.tsx +1 -1
  59. package/src/preview/property_previews/MapPropertyPreview.tsx +3 -1
  60. package/src/preview/property_previews/StringPropertyPreview.tsx +1 -2
  61. package/src/types/collections.ts +2 -2
  62. package/src/types/plugins.tsx +4 -2
  63. package/src/util/enums.ts +1 -2
  64. package/dist/util/chip_utils.d.ts +0 -3
  65. package/src/util/chip_utils.ts +0 -13
@@ -0,0 +1,74 @@
1
+ import React from "react";
2
+ import { getTableCellAlignment, getTablePropertyColumnWidth } from "./internal/common";
3
+ import { FilterValues, ResolvedProperties, ResolvedProperty } from "../../types";
4
+ import { VirtualTableColumn } from "../VirtualTable";
5
+ import { getIconForProperty, getResolvedPropertyInPath } from "../../util";
6
+ import { getColumnKeysForProperty } from "../EntityCollectionView/useColumnsIds";
7
+
8
+ export function buildIdColumn(largeLayout?: boolean): VirtualTableColumn {
9
+ return {
10
+ key: "id_ewcfedcswdf3",
11
+ width: (largeLayout ? 160 : 130),
12
+ title: "ID",
13
+ resizable: false,
14
+ frozen: largeLayout ?? false,
15
+ headerAlign: "center",
16
+ align: "center",
17
+ };
18
+ }
19
+
20
+ export interface PropertiesToColumnsParams<M extends Record<string, any>> {
21
+ properties: ResolvedProperties<M>;
22
+ sortable?: boolean;
23
+ forceFilter?: FilterValues<keyof M extends string ? keyof M : never>;
24
+ disabledFilter?: boolean;
25
+ AdditionalHeaderWidget?: (props: {
26
+ property: ResolvedProperty,
27
+ propertyKey: string,
28
+ onHover: boolean,
29
+ }) => React.ReactNode;
30
+ }
31
+
32
+ export function propertiesToColumns<M extends Record<string, any>>({ properties, sortable, forceFilter, disabledFilter, AdditionalHeaderWidget }: PropertiesToColumnsParams<M>): VirtualTableColumn[] {
33
+ return Object.entries<ResolvedProperty>(properties)
34
+ .flatMap(([key, property]) => getColumnKeysForProperty(property, key))
35
+ .map(({
36
+ key,
37
+ disabled
38
+ }) => {
39
+ const property = getResolvedPropertyInPath(properties, key);
40
+ if (!property)
41
+ throw Error("Internal error: no property found in path " + key);
42
+ const filterable = filterableProperty(property);
43
+ return {
44
+ key: key as string,
45
+ align: getTableCellAlignment(property),
46
+ icon: (hoverOrOpen) => getIconForProperty(property, "small"),
47
+ title: property.name ?? key as string,
48
+ sortable: sortable && (forceFilter ? Object.keys(forceFilter).includes(key) : true),
49
+ filter: !disabledFilter && filterable,
50
+ width: getTablePropertyColumnWidth(property),
51
+ resizable: true,
52
+ custom: {
53
+ resolvedProperty: property,
54
+ disabled
55
+ },
56
+ AdditionalHeaderWidget: AdditionalHeaderWidget
57
+ ? ({ onHover }) => <AdditionalHeaderWidget property={property} propertyKey={key} onHover={onHover}/>
58
+ : undefined
59
+ } satisfies VirtualTableColumn;
60
+ });
61
+ }
62
+
63
+ function filterableProperty(property: ResolvedProperty, partOfArray = false): boolean {
64
+ if (partOfArray) {
65
+ return ["string", "number", "date", "reference"].includes(property.dataType);
66
+ }
67
+ if (property.dataType === "array") {
68
+ if (property.of)
69
+ return filterableProperty(property.of, true);
70
+ else
71
+ return false;
72
+ }
73
+ return ["string", "number", "boolean", "date", "reference", "array"].includes(property.dataType);
74
+ }
@@ -13,4 +13,8 @@ export type {
13
13
  OnCellValueChangeParams
14
14
  } from "./types";
15
15
 
16
+ export * from "./PropertyTableCell";
17
+ export * from "./SimpleEntityCollectionTable";
18
+ export * from "./EntityCollectionRowActions";
16
19
  export * from "./useDataSourceEntityCollectionTableController";
20
+ export * from "./column_utils";
@@ -17,7 +17,7 @@ interface CollectionTableToolbarProps {
17
17
  size: CollectionSize;
18
18
  filterIsSet: boolean;
19
19
  loading: boolean;
20
- forceFilter: boolean;
20
+ forceFilter?: boolean;
21
21
  actionsStart?: React.ReactNode;
22
22
  actions?: React.ReactNode;
23
23
  title?: React.ReactNode,
@@ -71,9 +71,9 @@ export function CollectionTableToolbar(props: CollectionTableToolbarProps) {
71
71
 
72
72
  return (
73
73
  <div
74
- className={cn(defaultBorderMixin, "no-scrollbar min-h-[56px] overflow-x-auto px-4 bg-gray-50 dark:bg-gray-900 border-b flex flex-row justify-between items-center w-full")}>
74
+ className={cn(defaultBorderMixin, "no-scrollbar min-h-[56px] overflow-x-auto px-2 md:px-4 bg-gray-50 dark:bg-gray-900 border-b flex flex-row justify-between items-center w-full")}>
75
75
 
76
- <div className="flex items-center gap-2">
76
+ <div className="flex items-center gap-2 md:mr-4 mr-2">
77
77
 
78
78
  {props.title && <div className={"hidden lg:block"}>
79
79
  {props.title}
@@ -4,8 +4,7 @@ import useMeasure from "react-use-measure";
4
4
 
5
5
  import { VirtualTableSize } from "../../VirtualTable";
6
6
  import { getRowHeight } from "../../VirtualTable/common";
7
- import { cn, RemoveCircleIcon, Tooltip } from "@firecms/ui";
8
- import { useOutsideAlerter } from "@firecms/ui";
7
+ import { useOutsideAlerter, cn, RemoveCircleIcon, Tooltip } from "@firecms/ui";
9
8
  import { ErrorBoundary } from "../../../components";
10
9
 
11
10
  interface EntityTableCellProps {
@@ -1,6 +1,6 @@
1
1
  import { EntityAction } from "../../../types";
2
- import { DeleteEntityDialog } from "./DeleteEntityDialog";
3
2
  import { ArchiveIcon, DeleteIcon, FileCopyIcon, KeyboardTabIcon, OpenInNewIcon } from "@firecms/ui";
3
+ import { DeleteEntityDialog } from "../../DeleteEntityDialog";
4
4
 
5
5
  export const editEntityAction: EntityAction = {
6
6
  icon: <KeyboardTabIcon/>,
@@ -40,7 +40,7 @@ interface PopupFormFieldProps<M extends Record<string, any>> {
40
40
  * Callback when the value of a cell has been edited
41
41
  * @param params
42
42
  */
43
- onCellValueChange?: (params: OnCellValueChangeParams<any, M>) => Promise<void>;
43
+ onCellValueChange?: (params: OnCellValueChangeParams<any, M>) => Promise<void> | void;
44
44
  }
45
45
 
46
46
  export function PopupFormField<M extends Record<string, any>>(props: PopupFormFieldProps<M>) {
@@ -63,7 +63,7 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
63
63
  container
64
64
  }: PopupFormFieldProps<M>) {
65
65
 
66
- const dataSource = useDataSource();
66
+ // const dataSource = useDataSource();
67
67
  const fireCMSContext = useFireCMSContext();
68
68
 
69
69
  const [savingError, setSavingError] = React.useState<any>();
@@ -74,22 +74,22 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
74
74
 
75
75
  const entityId = entityProp?.id;
76
76
  const [entity, setEntity] = useState<Entity<M> | undefined>(entityProp);
77
- useEffect(() => {
78
- if (entityId && inputCollection) {
79
- return dataSource.listenEntity?.({
80
- path,
81
- entityId,
82
- collection: inputCollection,
83
- onUpdate: (e) => {
84
- setEntity(e);
85
- setInternalValue(e?.values);
86
- }
87
- });
88
- } else {
89
- return () => {
90
- };
91
- }
92
- }, [dataSource, entityId, inputCollection, path, open]);
77
+ // useEffect(() => {
78
+ // if (entityId && inputCollection) {
79
+ // return dataSource.listenEntity?.({
80
+ // path,
81
+ // entityId,
82
+ // collection: inputCollection,
83
+ // onUpdate: (e) => {
84
+ // setEntity(e);
85
+ // setInternalValue(e?.values);
86
+ // }
87
+ // });
88
+ // } else {
89
+ // return () => {
90
+ // };
91
+ // }
92
+ // }, [dataSource, entityId, inputCollection, path, open]);
93
93
 
94
94
  const [internalValue, setInternalValue] = useState<EntityValues<M> | undefined>(entity?.values);
95
95
 
@@ -31,7 +31,7 @@ export type EntityCollectionTableController<M extends Record<string, any>> = {
31
31
  * Props passed in a callback when the content of a cell in a table has been edited
32
32
  * @group Collection components
33
33
  */
34
- export interface OnCellValueChangeParams<T, M extends Record<string, any>> {
34
+ export interface OnCellValueChangeParams<T = any, M extends Record<string, any> = any> {
35
35
  value: T,
36
36
  propertyKey: string,
37
37
  entity: Entity<M>,
@@ -55,4 +55,4 @@ export type UniqueFieldValidator = (props: {
55
55
  * Callback when a cell has changed in a table
56
56
  * @group Collection components
57
57
  */
58
- export type OnCellValueChange<T, M extends Record<string, any>> = (params: OnCellValueChangeParams<T, M>) => Promise<void>;
58
+ export type OnCellValueChange<T, M extends Record<string, any>> = (params: OnCellValueChangeParams<T, M>) => Promise<void> | void;
@@ -8,7 +8,7 @@ import {
8
8
  FilterValues,
9
9
  FireCMSContext,
10
10
  SelectedCellProps,
11
- TableController,
11
+ EntityTableController,
12
12
  User
13
13
  } from "../../types";
14
14
  import { useDebouncedData } from "./useDebouncedData";
@@ -38,7 +38,7 @@ export type DataSourceEntityCollectionTableControllerProps<M extends Record<stri
38
38
  * Use this hook to build a controller for the {@link EntityCollectionTable}.
39
39
  * This controller is bound to data in a path in your specified datasource.
40
40
  *
41
- * Note that you can build your own hook returning a {@link TableController}
41
+ * Note that you can build your own hook returning a {@link EntityTableController}
42
42
  * if you would like to display different data.
43
43
  *
44
44
  * @param fullPath
@@ -55,7 +55,7 @@ export function useDataSourceEntityCollectionTableController<M extends Record<st
55
55
  lastDeleteTimestamp,
56
56
  forceFilter: forceFilterFromProps,
57
57
  }: DataSourceEntityCollectionTableControllerProps<M>)
58
- : TableController<M> {
58
+ : EntityTableController<M> {
59
59
 
60
60
  const {
61
61
  initialFilter,
@@ -22,8 +22,7 @@ import {
22
22
  UniqueFieldValidator
23
23
  } from "../EntityCollectionTable";
24
24
 
25
- import { EntityCollectionRowActions } from "../EntityCollectionTable/internal/EntityCollectionRowActions";
26
- import { DeleteEntityDialog } from "../EntityCollectionTable/internal/DeleteEntityDialog";
25
+ import { EntityCollectionRowActions } from "../EntityCollectionTable/EntityCollectionRowActions";
27
26
 
28
27
  import {
29
28
  canCreateEntity,
@@ -72,6 +71,7 @@ import {
72
71
  deleteEntityAction,
73
72
  editEntityAction
74
73
  } from "../EntityCollectionTable/internal/default_entity_actions";
74
+ import { DeleteEntityDialog } from "../DeleteEntityDialog";
75
75
 
76
76
  const COLLECTION_GROUP_PARENT_ID = "collectionGroupParent";
77
77
 
@@ -570,7 +570,7 @@ export const EntityCollectionView = React.memo(
570
570
  setTextSearchLoading(true);
571
571
  Promise.all(context.plugins?.map(p => {
572
572
  if (p.collectionView?.onTextSearchClick)
573
- return p.collectionView.onTextSearchClick({ context, path: resolvedFullPath, collection });
573
+ return p.collectionView.onTextSearchClick({ context, path: resolvedFullPath, collection, parentCollectionIds });
574
574
  return Promise.resolve(true);
575
575
  }) as Promise<boolean>[])
576
576
  .then((res) => {
@@ -583,7 +583,7 @@ export const EntityCollectionView = React.memo(
583
583
  context.plugins?.forEach(p => {
584
584
  if (!textSearchEnabled)
585
585
  if (p.collectionView?.showTextSearchBar) {
586
- textSearchEnabled = p.collectionView.showTextSearchBar({ context, path: resolvedFullPath, collection });
586
+ textSearchEnabled = p.collectionView.showTextSearchBar({ context, path: resolvedFullPath, collection, parentCollectionIds });
587
587
  }
588
588
  })
589
589
  }
@@ -2,7 +2,7 @@ import React from "react";
2
2
 
3
3
  import { canCreateEntity, canDeleteEntity, fullPathToCollectionSegments } from "../../util";
4
4
  import { useAuthController, useFireCMSContext, useLargeLayout } from "../../hooks";
5
- import { CollectionActionsProps, EntityCollection, SelectionController, TableController } from "../../types";
5
+ import { CollectionActionsProps, EntityCollection, SelectionController, EntityTableController } from "../../types";
6
6
  import { AddIcon, Button, DeleteIcon, IconButton, Tooltip } from "@firecms/ui";
7
7
  import { toArray } from "../../util/arrays";
8
8
  import { ErrorBoundary } from "../ErrorBoundary";
@@ -16,7 +16,7 @@ export type EntityCollectionViewActionsProps<M extends Record<string, any>> = {
16
16
  onNewClick: () => void;
17
17
  onMultipleDeleteClick: () => void;
18
18
  selectionController: SelectionController<M>;
19
- tableController: TableController<M>;
19
+ tableController: EntityTableController<M>;
20
20
  collectionEntitiesCount: number;
21
21
  }
22
22
 
@@ -2,7 +2,7 @@ import React, { MouseEventHandler, useCallback, useEffect, useMemo, useState } f
2
2
  import { CollectionSize, Entity, EntityCollection, FilterValues } from "../types";
3
3
 
4
4
  import { EntityCollectionTable } from "./EntityCollectionTable";
5
- import { EntityCollectionRowActions } from "./EntityCollectionTable/internal/EntityCollectionRowActions";
5
+ import { EntityCollectionRowActions } from "./EntityCollectionTable/EntityCollectionRowActions";
6
6
  import {
7
7
  useAuthController,
8
8
  useDataSource,
@@ -12,23 +12,19 @@ type VirtualTableCellProps<T extends any> = {
12
12
  cellData: any;
13
13
  rowIndex: any;
14
14
  columnIndex: number;
15
- cellRenderer: (params: CellRendererParams<T>) => React.ReactNode;
15
+ cellRenderer: React.ComponentType<CellRendererParams<T>>;
16
16
  };
17
17
 
18
18
  export const VirtualTableCell = React.memo<VirtualTableCellProps<any>>(
19
19
  function VirtualTableCell<T extends any>(props: VirtualTableCellProps<T>) {
20
- return props.rowData && props.cellRenderer(
21
- {
22
- cellData: props.cellData,
23
- rowData: props.rowData,
24
- rowIndex: props.rowIndex,
25
- isScrolling: false,
26
- column: props.column,
27
- columns: props.columns,
28
- columnIndex: props.columnIndex,
29
- width: props.column.width
30
- } as CellRendererParams<T>
31
- );
20
+ return props.rowData && <props.cellRenderer
21
+ rowData={props.rowData}
22
+ rowIndex={props.rowIndex}
23
+ isScrolling={false}
24
+ column={props.column}
25
+ columns={props.columns}
26
+ columnIndex={props.columnIndex}
27
+ width={props.column.width}/>
32
28
  },
33
29
  (a, b) => {
34
30
  return equal(a, b);
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { WhereFilterOp } from "../../types";
2
+ import { ResolvedProperty, WhereFilterOp } from "../../types";
3
3
  import { FilterFormFieldProps } from "./VirtualTableHeader";
4
4
 
5
5
  export type OnRowClickParams<T extends Record<string, any>> = {
@@ -29,7 +29,7 @@ export interface VirtualTableProps<T extends Record<string, any>> {
29
29
  * Custom cell renderer
30
30
  * The renderer receives props `{ cellData, columns, column, columnIndex, rowData, rowIndex, container, isScrolling }`
31
31
  */
32
- cellRenderer: (params: CellRendererParams<T>) => React.ReactNode;
32
+ cellRenderer: React.ComponentType<CellRendererParams<T>>;
33
33
 
34
34
  /**
35
35
  * If enabled, content is loaded in batch
@@ -144,8 +144,7 @@ export interface VirtualTableProps<T extends Record<string, any>> {
144
144
 
145
145
  }
146
146
 
147
- export type CellRendererParams<T extends any> = {
148
- cellData?: any;
147
+ export type CellRendererParams<T extends any = any> = {
149
148
  column: VirtualTableColumn;
150
149
  columns: VirtualTableColumn[];
151
150
  columnIndex: number;
@@ -19,7 +19,6 @@ export const VirtualTableRow = React.memo<VirtualTableRowProps<any>>(
19
19
  }: VirtualTableRowProps<T>) {
20
20
 
21
21
  const onClick = useCallback((event: React.SyntheticEvent) => {
22
- console.debug("VirtualTableRow click");
23
22
  if (onRowClick)
24
23
  onRowClick({
25
24
  rowData,
@@ -26,7 +26,7 @@ export type VirtualTableContextProps<T extends any> = {
26
26
  data?: T[];
27
27
  size?: VirtualTableSize,
28
28
  columns: VirtualTableColumn[];
29
- cellRenderer: (params: CellRendererParams<T>) => React.ReactNode;
29
+ cellRenderer: React.ComponentType<CellRendererParams<T>>;
30
30
  currentSort: "asc" | "desc" | undefined;
31
31
  filter?: VirtualTableFilterValues<any>;
32
32
  onRowClick?: (props: OnRowClickParams<any>) => void;
@@ -74,7 +74,6 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
74
74
 
75
75
  return (
76
76
  <>
77
-
78
77
  <ErrorBoundary>
79
78
  <EntityView
80
79
  {...props}
@@ -95,7 +95,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
95
95
 
96
96
  if (navigationController.navigationLoadingError) {
97
97
  return (
98
- <CenteredView maxWidth={"md"} fullScreen={true}>
98
+ <CenteredView maxWidth={"md"}>
99
99
  <ErrorView
100
100
  title={"Error loading navigation"}
101
101
  error={navigationController.navigationLoadingError}/>
@@ -105,7 +105,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
105
105
 
106
106
  if (authController.authError) {
107
107
  return (
108
- <CenteredView maxWidth={"md"} fullScreen={true}>
108
+ <CenteredView maxWidth={"md"}>
109
109
  <ErrorView
110
110
  title={"Error loading auth"}
111
111
  error={authController.authError}/>
@@ -28,7 +28,7 @@ import {
28
28
  import { useAuthController, useDataSource, useFireCMSContext, useSideEntityController } from "../hooks";
29
29
  import { ErrorFocus } from "./components/ErrorFocus";
30
30
  import { CustomIdField } from "./components/CustomIdField";
31
- import { Button, cn, DialogActions, IconButton, Typography } from "@firecms/ui";
31
+ import { Alert, Button, cn, DialogActions, IconButton, Typography } from "@firecms/ui";
32
32
  import { ErrorBoundary } from "../components";
33
33
  import {
34
34
  copyEntityAction,
@@ -400,25 +400,24 @@ function EntityFormInternal<M extends Record<string, any>>({
400
400
  )).filter(Boolean));
401
401
  }
402
402
 
403
- return <div
404
- className="h-full overflow-auto"
405
- >
403
+ return <div className="h-full overflow-auto">
406
404
 
407
405
  {pluginActions.length > 0 && <div
408
406
  className={cn("w-full flex justify-end items-center sticky top-0 right-0 left-0 z-10 bg-opacity-60 bg-slate-200 dark:bg-opacity-60 dark:bg-slate-800 backdrop-blur-md")}>
409
407
  {pluginActions}
410
408
  </div>}
411
409
 
412
- <div
413
- className="pl-4 pr-4 pt-12 pb-16 md:pl-8"
414
- >
410
+ <div className="pl-4 pr-4 pt-12 pb-16 md:pl-8">
415
411
  <div
416
- className={`w-full py-2 flex items-center mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>
412
+ className={`w-full py-2 flex flex-col items-start mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>
417
413
 
418
414
  <Typography
419
415
  className={"mt-4 flex-grow " + inputCollection.hideIdFromForm ? "mb-2" : "mb-0"}
420
416
  variant={"h4"}>{inputCollection.singularName ?? inputCollection.name}
421
417
  </Typography>
418
+ <Alert color={"base"} className={"w-full"} size={"small"}>
419
+ <code className={"text-xs select-all"}>{path}/{entityId}</code>
420
+ </Alert>
422
421
  </div>
423
422
 
424
423
  {!hideId &&
@@ -197,12 +197,14 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
197
197
  const error = getIn(fieldProps.form.errors, propertyKey);
198
198
  const touched = getIn(fieldProps.form.touched, propertyKey);
199
199
 
200
+ console.log("error", propertyKey, error);
201
+
200
202
  const showError: boolean = error &&
201
203
  (fieldProps.form.submitCount > 0 || property.validation?.unique) &&
202
204
  (!Array.isArray(error) || !!error.filter((e: any) => !!e).length);
203
205
 
204
206
  const WrappedComponent: ComponentType<FieldProps<T, any, M>> | null = useWrappedComponent(context.path, context.collection, propertyKey, property, Component, plugins);
205
- const UsedComponent: ComponentType<FieldProps<T>> = Component;
207
+ const UsedComponent: ComponentType<FieldProps<T>> = WrappedComponent ?? Component;
206
208
 
207
209
  const isSubmitting = fieldProps.form.isSubmitting;
208
210
 
@@ -12,7 +12,7 @@ export function FieldHelperText({
12
12
  includeDescription = true,
13
13
  disabled
14
14
  }: {
15
- error: string,
15
+ error?: string,
16
16
  showError: boolean,
17
17
  property: ResolvedProperty,
18
18
  includeDescription?: boolean,
@@ -27,7 +27,7 @@ export function FieldHelperText({
27
27
 
28
28
  if (showError && error) {
29
29
  return <Typography variant={"caption"}
30
- className={"ml-3.5 text-red-500"}>
30
+ className={"ml-3.5 text-red-500 dark:text-red-500"}>
31
31
  {error}
32
32
  </Typography>
33
33
  }
@@ -48,10 +48,11 @@ export function DateTimeFieldBinding({
48
48
  mode={property.mode}
49
49
  clearable={property.clearable}
50
50
  locale={locale}
51
+ error={showError}
51
52
  label={<LabelWithIcon
52
53
  icon={getIconForProperty(property, "small")}
53
54
  required={property.validation?.required}
54
- className={"text-text-secondary dark:text-text-secondary-dark"}
55
+ className={showError ? "text-red-500 dark:text-red-500" : "text-text-secondary dark:text-text-secondary-dark"}
55
56
  title={property.name}/>}
56
57
  />
57
58
 
@@ -51,12 +51,6 @@ export function MapFieldBinding<T extends Record<string, any>>({
51
51
  mapProperties = property.properties;
52
52
  }
53
53
 
54
- // useClearRestoreValue({
55
- // property,
56
- // value,
57
- // setValue
58
- // });
59
-
60
54
  const mapFormView = <>
61
55
  <div className="py-1 flex flex-col space-y-2">
62
56
  {Object.entries(mapProperties)
@@ -99,14 +93,14 @@ export function MapFieldBinding<T extends Record<string, any>>({
99
93
  <>
100
94
 
101
95
  {!tableMode && !partOfBlock && <ExpandablePanel initiallyExpanded={expanded}
102
- className={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2"}
103
- title={title}>{mapFormView}</ExpandablePanel>}
96
+ className={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2"}
97
+ title={title}>{mapFormView}</ExpandablePanel>}
104
98
 
105
99
  {(tableMode || partOfBlock) && mapFormView}
106
100
 
107
101
  <FieldHelperText includeDescription={includeDescription}
108
102
  showError={showError}
109
- error={error}
103
+ error={error ? (typeof error === "string" ? error : "A property of this map has an error") : undefined}
110
104
  disabled={disabled}
111
105
  property={property}/>
112
106