@firecms/core 3.0.0-canary.43 → 3.0.0-canary.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
3
  "type": "module",
4
- "version": "3.0.0-canary.43",
4
+ "version": "3.0.0-canary.45",
5
5
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/firecmsco"
@@ -46,8 +46,8 @@
46
46
  "./package.json": "./package.json"
47
47
  },
48
48
  "dependencies": {
49
- "@firecms/formex": "^3.0.0-canary.43",
50
- "@firecms/ui": "^3.0.0-canary.43",
49
+ "@firecms/formex": "^3.0.0-canary.45",
50
+ "@firecms/ui": "^3.0.0-canary.45",
51
51
  "@fontsource/jetbrains-mono": "^5.0.19",
52
52
  "@hello-pangea/dnd": "^16.6.0",
53
53
  "@radix-ui/react-portal": "^1.0.4",
@@ -118,7 +118,7 @@
118
118
  "dist",
119
119
  "src"
120
120
  ],
121
- "gitHead": "fedcb0d43c504245dd76b702e4ab4479fa8592df",
121
+ "gitHead": "7f22bfa3bb20479ad23becd9c10f78cac1a3bc32",
122
122
  "publishConfig": {
123
123
  "access": "public"
124
124
  }
@@ -15,6 +15,7 @@ import { renderSkeletonText } from "../../preview";
15
15
  import { propertiesToColumns } from "./column_utils";
16
16
  import { ErrorView } from "../ErrorView";
17
17
  import { SelectableTable } from "../SelectableTable/SelectableTable";
18
+ import { cn } from "@firecms/ui";
18
19
 
19
20
  /**
20
21
  * This component is in charge of rendering a collection table with a high
@@ -42,6 +43,7 @@ import { SelectableTable } from "../SelectableTable/SelectableTable";
42
43
  */
43
44
  export const EntityCollectionTable = function EntityCollectionTable<M extends Record<string, any>, UserType extends User>
44
45
  ({
46
+ className,
45
47
  forceFilter,
46
48
  actionsStart,
47
49
  actions,
@@ -72,7 +74,8 @@ export const EntityCollectionTable = function EntityCollectionTable<M extends Re
72
74
  emptyComponent,
73
75
  getIdColumnWidth,
74
76
  onTextSearchClick,
75
- textSearchLoading
77
+ textSearchLoading,
78
+ enablePopupIcon
76
79
  }: EntityCollectionTableProps<M>) {
77
80
 
78
81
  const ref = useRef<HTMLDivElement>(null);
@@ -147,6 +150,7 @@ export const EntityCollectionTable = function EntityCollectionTable<M extends Re
147
150
  height={getRowHeight(size)}
148
151
  entity={entity}
149
152
  disabled={disabled}
153
+ enablePopupIcon={enablePopupIcon}
150
154
  path={entity.path}/>
151
155
  : renderSkeletonText()
152
156
  }
@@ -290,7 +294,7 @@ export const EntityCollectionTable = function EntityCollectionTable<M extends Re
290
294
  return (
291
295
 
292
296
  <div ref={ref}
293
- className="h-full w-full flex flex-col bg-white dark:bg-gray-950">
297
+ className={cn("h-full w-full flex flex-col bg-white dark:bg-gray-950", className)}>
294
298
 
295
299
  <CollectionTableToolbar
296
300
  onTextSearch={textSearchEnabled ? onTextSearch : undefined}
@@ -12,13 +12,13 @@ import {
12
12
  } from "../../types";
13
13
  import { OnCellValueChange, OnColumnResizeParams, UniqueFieldValidator } from "../common/types";
14
14
 
15
-
16
15
  /**
17
16
  * @group Collection components
18
17
  */
19
18
  export type EntityCollectionTableProps<M extends Record<string, any>,
20
19
  UserType extends User = User> = {
21
20
 
21
+ className?: string;
22
22
  /**
23
23
  * Display these entities as selected
24
24
  */
@@ -131,7 +131,9 @@ export type EntityCollectionTableProps<M extends Record<string, any>,
131
131
  onTextSearchClick?: () => void;
132
132
 
133
133
  textSearchLoading?: boolean;
134
- }
134
+
135
+ enablePopupIcon: boolean;
136
+ };
135
137
 
136
138
  export type GetPropertyForProps<M extends Record<string, any>> = {
137
139
  propertyKey: string,
@@ -141,5 +143,5 @@ export type GetPropertyForProps<M extends Record<string, any>> = {
141
143
 
142
144
  export type PropertyColumnConfig = {
143
145
  key: string,
144
- disabled: boolean,
146
+ disabled?: boolean,
145
147
  };
@@ -46,6 +46,7 @@ export interface PropertyTableCellProps<T extends CMSType> {
46
46
  entity: Entity<any>;
47
47
  path: string;
48
48
  disabled: boolean;
49
+ enablePopupIcon?: boolean;
49
50
  }
50
51
 
51
52
  function isStorageProperty(property: ResolvedProperty) {
@@ -74,11 +75,10 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
74
75
  path,
75
76
  entity,
76
77
  readonly,
77
- disabled: disabledProp
78
+ disabled: disabledProp,
79
+ enablePopupIcon = true
78
80
  }: PropertyTableCellProps<T>) {
79
81
 
80
- const context = useFireCMSContext();
81
-
82
82
  const {
83
83
  onValueChange,
84
84
  size,
@@ -140,15 +140,19 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
140
140
  setValidationError(undefined);
141
141
  internalValueRef.current = value;
142
142
  if (onValueChange) {
143
- onValueChange({
144
- value,
145
- propertyKey,
146
- setError,
147
- onValueUpdated,
148
- entity,
149
- fullPath: path,
150
- context
151
- });
143
+ try {
144
+ onValueChange({
145
+ value,
146
+ propertyKey,
147
+ setError,
148
+ onValueUpdated,
149
+ data: entity,
150
+ });
151
+ } catch (e:any) {
152
+ console.error("onValueChange error", e);
153
+ setError(e);
154
+ }
155
+
152
156
  }
153
157
  })
154
158
  .catch((e) => {
@@ -399,7 +403,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
399
403
 
400
404
  if (!innerComponent) {
401
405
  allowScroll = false;
402
- showExpandIcon = selected && !innerComponent && !disabled && !readOnlyProperty;
406
+ showExpandIcon = enablePopupIcon && selected && !innerComponent && !disabled && !readOnlyProperty;
403
407
  innerComponent = (
404
408
  <PropertyPreview width={width}
405
409
  height={height}
@@ -41,7 +41,7 @@ interface PopupFormFieldProps<M extends Record<string, any>> {
41
41
  * Callback when the value of a cell has been edited
42
42
  * @param params
43
43
  */
44
- onCellValueChange?: (params: OnCellValueChangeParams<any, M>) => Promise<void> | void;
44
+ onCellValueChange?: (params: OnCellValueChangeParams<any, any>) => Promise<void> | void;
45
45
  }
46
46
 
47
47
  export function PopupFormField<M extends Record<string, any>>(props: PopupFormFieldProps<M>) {
@@ -205,12 +205,10 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
205
205
  return onCellValueChange({
206
206
  value: values[propertyKey as string],
207
207
  propertyKey: propertyKey as string,
208
- entity,
208
+ data: entity,
209
209
  setError: setSavingError,
210
210
  onValueUpdated: () => {
211
211
  },
212
- fullPath: path,
213
- context: fireCMSContext
214
212
  });
215
213
  }
216
214
  return Promise.resolve();
@@ -34,7 +34,7 @@ import {
34
34
  saveEntityWithCallbacks,
35
35
  useAuthController,
36
36
  useCustomizationController,
37
- useDataSource,
37
+ useDataSource, useFireCMSContext,
38
38
  useLargeLayout,
39
39
  useNavigationController,
40
40
  useSideEntityController
@@ -94,7 +94,9 @@ export type EntityCollectionViewProps<M extends Record<string, any>> = {
94
94
  * Whether this is a subcollection or not.
95
95
  */
96
96
  isSubCollection?: boolean;
97
+
97
98
  className?: string;
99
+
98
100
  } & EntityCollection<M>;
99
101
 
100
102
  /**
@@ -131,6 +133,7 @@ export const EntityCollectionView = React.memo(
131
133
  }: EntityCollectionViewProps<M>
132
134
  ) {
133
135
 
136
+ const context = useFireCMSContext();
134
137
  const fullPath = fullPathProp ?? collectionProp.path;
135
138
  const dataSource = useDataSource(collectionProp);
136
139
  const navigation = useNavigationController();
@@ -311,13 +314,11 @@ export const EntityCollectionView = React.memo(
311
314
  [fullPath]);
312
315
 
313
316
  const onValueChange: OnCellValueChange<any, any> = ({
314
- fullPath,
315
- context,
316
317
  value,
317
318
  propertyKey,
318
319
  onValueUpdated,
319
320
  setError,
320
- entity,
321
+ data: entity,
321
322
  }) => {
322
323
 
323
324
  const updatedValues = setIn({ ...entity.values }, propertyKey, value);
@@ -334,7 +335,6 @@ export const EntityCollectionView = React.memo(
334
335
  return saveEntityWithCallbacks({
335
336
  ...saveProps,
336
337
  collection,
337
- callbacks: collection.callbacks,
338
338
  dataSource,
339
339
  context,
340
340
  onSaveSuccess: () => {
@@ -603,6 +603,7 @@ export const EntityCollectionView = React.memo(
603
603
  key={`collection_table_${fullPath}`}
604
604
  additionalFields={additionalFields}
605
605
  tableController={tableController}
606
+ enablePopupIcon={true}
606
607
  displayedColumnIds={displayedColumnIds}
607
608
  onSizeChanged={onSizeChanged}
608
609
  onEntityClick={onEntityClick}
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
 
3
3
  import { Link as ReactLink } from "react-router-dom";
4
- import { ErrorBoundary } from "../components";
4
+ import { ErrorBoundary, FireCMSLogo } from "../components";
5
5
  import {
6
6
  Avatar,
7
7
  cn,
@@ -18,7 +18,8 @@ import { useAuthController, useLargeLayout, useModeController, useNavigationCont
18
18
  import { User } from "../types";
19
19
 
20
20
  export type FireCMSAppBarProps<ADDITIONAL_PROPS = object> = {
21
- title: string;
21
+
22
+ title: React.ReactNode;
22
23
  /**
23
24
  * A component that gets rendered on the upper side of the main toolbar
24
25
  */
@@ -36,6 +37,8 @@ export type FireCMSAppBarProps<ADDITIONAL_PROPS = object> = {
36
37
 
37
38
  style?: React.CSSProperties;
38
39
 
40
+ logo?: string;
41
+
39
42
  user?: User;
40
43
  } & ADDITIONAL_PROPS;
41
44
 
@@ -57,6 +60,7 @@ export const FireCMSAppBar = function FireCMSAppBar({
57
60
  includeDrawer,
58
61
  className,
59
62
  style,
63
+ logo,
60
64
  user: userProp
61
65
  }: FireCMSAppBarProps) {
62
66
  const navigation = useNavigationController();
@@ -102,7 +106,7 @@ export const FireCMSAppBar = function FireCMSAppBar({
102
106
  "w-[calc(100%-64px)]": includeDrawer && !(drawerOpen && largeLayout),
103
107
  "w-[calc(100%-17rem)]": includeDrawer && (drawerOpen && largeLayout),
104
108
  "duration-150": drawerOpen && largeLayout,
105
- fixed: true,
109
+ fixed: true
106
110
  },
107
111
  className)}>
108
112
 
@@ -110,16 +114,27 @@ export const FireCMSAppBar = function FireCMSAppBar({
110
114
 
111
115
  {startAdornment}
112
116
 
117
+
113
118
  {navigation && <div className="mr-8 hidden lg:block">
114
119
  <ReactLink
115
120
  className="visited:text-inherit visited:dark:text-inherit"
116
121
  to={navigation?.basePath ?? "/"}
117
122
  >
118
- <Typography variant="subtitle1"
119
- noWrap
120
- className={"ml-2 !font-medium"}>
121
- {title}
122
- </Typography>
123
+ <div className={"flex flex-row gap-4"}>
124
+ {!includeDrawer && (logo
125
+ ? <img src={logo}
126
+ alt="Logo"
127
+ className={cn("w-[32px] h-[32px]")}/>
128
+ : <FireCMSLogo width={"32px"} height={"32px"}/>)}
129
+
130
+ {typeof title === "string"
131
+ ? <Typography variant="subtitle1"
132
+ noWrap
133
+ className={"ml-2 !font-medium"}>
134
+ {title}
135
+ </Typography>
136
+ : title}
137
+ </div>
123
138
  </ReactLink>
124
139
  </div>}
125
140
 
@@ -291,6 +291,7 @@ export function ReferenceSelectionTable<M extends Record<string, any>>(
291
291
  displayedColumnIds={displayedColumnIds}
292
292
  onEntityClick={onEntityClick}
293
293
  tableController={tableController}
294
+ enablePopupIcon={false}
294
295
  tableRowActionsBuilder={tableRowActionsBuilder}
295
296
  title={<Typography variant={"subtitle2"}>
296
297
  {collection.singularName ? `Select ${collection.singularName}` : `Select from ${collection.name}`}
@@ -404,7 +404,7 @@ const SafeLinkRenderer: React.FC<{
404
404
  const urlRegex = /https?:\/\/[^\s]+/g;
405
405
  const htmlContent = text.replace(urlRegex, (url) => {
406
406
  // For each URL found, replace it with an HTML <a> tag
407
- return `<a href="${url}" target="_blank">Link</a><br/>`;
407
+ return `<a href="${url}" class="underline" target="_blank">Link</a><br/>`;
408
408
  });
409
409
 
410
410
  return (
@@ -1,4 +1,4 @@
1
- import { CollectionSize, Entity, FireCMSContext, ResolvedProperty, SelectedCellProps } from "../../types";
1
+ import { CollectionSize, FireCMSContext, ResolvedProperty, SelectedCellProps } from "../../types";
2
2
 
3
3
  export type EntityCollectionTableController<M extends Record<string, any>> = {
4
4
 
@@ -31,14 +31,12 @@ 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 = any, M extends Record<string, any> = any> {
34
+ export interface OnCellValueChangeParams<T = any, D = any> {
35
35
  value: T,
36
36
  propertyKey: string,
37
- entity: Entity<M>,
37
+ data?: D,
38
38
  onValueUpdated: () => void
39
39
  setError: (e: Error | undefined) => void
40
- fullPath: string
41
- context: FireCMSContext
42
40
  }
43
41
 
44
42
  /**
@@ -13,7 +13,7 @@ export type NavigationRoutesProps = {
13
13
  /**
14
14
  * In case you need to override the home page
15
15
  */
16
- HomePage?: React.ComponentType;
16
+ homePage?: React.ReactNode;
17
17
 
18
18
  customRoutes?: React.ReactNode[]
19
19
 
@@ -28,10 +28,9 @@ export type NavigationRoutesProps = {
28
28
  * @constructor
29
29
  * @group Components
30
30
  */
31
-
32
31
  export const NavigationRoutes = React.memo<NavigationRoutesProps>(
33
32
  function NavigationRoutes({
34
- HomePage = DefaultHomePage,
33
+ homePage = <DefaultHomePage/>,
35
34
  customRoutes
36
35
  }: NavigationRoutesProps) {
37
36
 
@@ -93,7 +92,7 @@ export const NavigationRoutes = React.memo<NavigationRoutesProps>(
93
92
 
94
93
  const homeRoute = (
95
94
  <Route path={"/"}
96
- element={<HomePage/>}/>
95
+ element={homePage}/>
97
96
  );
98
97
 
99
98
  const notFoundRoute = <Route path={"*"}
@@ -17,7 +17,7 @@ export interface ScaffoldProps<ExtraDrawerProps = object, ExtraAppbarProps = obj
17
17
  /**
18
18
  * Name of the app, displayed as the main title and in the tab title
19
19
  */
20
- name: string;
20
+ name: React.ReactNode;
21
21
 
22
22
  /**
23
23
  * Logo to be displayed in the drawer of the CMS
@@ -112,9 +112,10 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
112
112
  }}>
113
113
 
114
114
  <FireCMSAppBar title={name}
115
- includeDrawer={includeDrawer}
116
- drawerOpen={computedDrawerOpen}
117
- {...fireCMSAppBarProps}/>
115
+ includeDrawer={includeDrawer}
116
+ logo={logo}
117
+ drawerOpen={computedDrawerOpen}
118
+ {...fireCMSAppBarProps}/>
118
119
 
119
120
  <StyledDrawer
120
121
  displayed={includeDrawer}
@@ -17,7 +17,6 @@ import { resolveCollection } from "../../util";
17
17
  export type SaveEntityWithCallbacksProps<M extends Record<string, any>> =
18
18
  SaveEntityProps<M> &
19
19
  {
20
- callbacks?: EntityCallbacks<M>;
21
20
  onSaveSuccess?: (updatedEntity: Entity<M>) => void,
22
21
  onSaveFailure?: (e: Error) => void,
23
22
  onPreSaveHookError?: (e: Error) => void,