@firecms/core 3.0.0-canary.50 → 3.0.0-canary.51

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.
@@ -31,7 +31,7 @@ export function EntityView<M extends Record<string, any>>(
31
31
  entityId: entity.id,
32
32
  values: entity.values,
33
33
  fields: customizationController.propertyConfigs
34
- }), [collection, path, entity]);
34
+ }), [collection, path, entity, customizationController.propertyConfigs]);
35
35
 
36
36
  const properties: ResolvedProperties = resolvedCollection.properties;
37
37
 
@@ -1,4 +1,4 @@
1
- import { ContentPasteIcon, IconButton, Typography } from "@firecms/ui";
1
+ import { ContentCopyIcon, IconButton, Typography } from "@firecms/ui";
2
2
  import { useCallback, useState } from "react";
3
3
 
4
4
  export function PropertyIdCopyTooltipContent({ propertyId }: { propertyId: string }) {
@@ -12,9 +12,8 @@ export function PropertyIdCopyTooltipContent({ propertyId }: { propertyId: strin
12
12
  color={"disabled"}>{copied ? "Copied" : "Property ID"}</Typography>
13
13
  <Typography variant={"caption"} className={"text-white"}><code>{propertyId}</code></Typography>
14
14
  </div>
15
- {/* Copy to clipboard button*/}
16
15
  <IconButton size={"small"}>
17
- <ContentPasteIcon size={"smallest"}
16
+ <ContentCopyIcon size={"smallest"}
18
17
  className={"text-white"}
19
18
  onClick={useCallback(() => {
20
19
  navigator.clipboard.writeText(propertyId);
@@ -122,7 +122,7 @@ export function ReferenceWidget<M extends Record<string, any>>({
122
122
  size={size}/>
123
123
 
124
124
  }
125
- return <div className={cn("text-sm font-medium text-gray-500",
125
+ return <div className={cn("text-sm font-medium",
126
126
  "min-w-80 flex flex-col gap-4",
127
127
  "relative transition-colors duration-200 ease-in rounded font-medium",
128
128
  disabled ? "bg-opacity-50" : "hover:bg-opacity-75",
@@ -1,4 +1,4 @@
1
- import { CollectionSize, FireCMSContext, ResolvedProperty, SelectedCellProps } from "../../types";
1
+ import { CollectionSize, ResolvedProperty, SelectedCellProps } from "../../types";
2
2
 
3
3
  export type EntityCollectionTableController<M extends Record<string, any>> = {
4
4
 
@@ -2,31 +2,37 @@ import React, { useCallback } from "react";
2
2
 
3
3
  import { useLargeLayout, useNavigationController } from "../hooks";
4
4
 
5
- import { NavLink, useNavigate } from "react-router-dom";
5
+ import { useNavigate } from "react-router-dom";
6
6
  import { CMSAnalyticsEvent, TopNavigationEntry, TopNavigationResult } from "../types";
7
7
  import { IconForView } from "../util";
8
8
  import { cn, IconButton, Menu, MenuItem, MoreVertIcon, Tooltip, Typography } from "@firecms/ui";
9
9
  import { useAnalyticsController } from "../hooks/useAnalyticsController";
10
+ import { useDrawer } from "./Scaffold";
11
+ import { DrawerNavigationItem } from "./DrawerNavigationItem";
10
12
 
11
13
  /**
12
14
  * Props used in case you need to override the default drawer
13
15
  * @group Core
14
16
  */
15
- export type DrawerProps<T = {}> = T & {
17
+ export type DrawerProps = {
16
18
  hovered: boolean,
17
19
  drawerOpen: boolean,
18
- closeDrawer: () => any,
20
+ openDrawer: () => void,
21
+ closeDrawer: () => void,
22
+ autoOpenDrawer?: boolean
19
23
  }
20
24
 
21
25
  /**
22
26
  * Default drawer used in the CMS
23
27
  * @group Core
24
28
  */
25
- export function Drawer({
26
- hovered,
27
- drawerOpen,
28
- closeDrawer
29
- }: DrawerProps) {
29
+ export function Drawer() {
30
+
31
+ const {
32
+ hovered,
33
+ drawerOpen,
34
+ closeDrawer,
35
+ } = useDrawer();
30
36
 
31
37
  const analyticsController = useAnalyticsController();
32
38
  const navigation = useNavigationController();
@@ -131,61 +137,3 @@ export function Drawer({
131
137
  </>
132
138
  );
133
139
  }
134
-
135
- export function DrawerNavigationItem({
136
- name,
137
- icon,
138
- drawerOpen,
139
- tooltipsOpen,
140
- url,
141
- onClick
142
- }: {
143
- icon: React.ReactElement,
144
- name: string,
145
- tooltipsOpen: boolean,
146
- drawerOpen: boolean,
147
- url: string,
148
- onClick?: () => void,
149
- }) {
150
-
151
- const iconWrap = <div
152
- className={"text-gray-600 dark:text-gray-500"}>
153
- {icon}
154
- </div>;
155
-
156
- const listItem = <NavLink
157
- onClick={onClick}
158
- style={{
159
- width: !drawerOpen ? "72px" : "280px",
160
- transition: drawerOpen ? "width 150ms ease-in" : undefined
161
- }}
162
- className={({ isActive }: any) => cn("rounded-r-xl truncate",
163
- "hover:bg-slate-300 hover:bg-opacity-75 dark:hover:bg-gray-700 dark:hover:bg-opacity-75 text-gray-800 dark:text-gray-200 hover:text-gray-900 hover:dark:text-white",
164
- "flex flex-row items-center mr-8",
165
- // "transition-all ease-in-out delay-100 duration-300",
166
- // drawerOpen ? "w-full" : "w-18",
167
- drawerOpen ? "pl-8 h-12" : "pl-6 h-11",
168
- "font-medium text-sm",
169
- isActive ? "bg-slate-200 bg-opacity-75 dark:bg-gray-800" : ""
170
- )}
171
- to={url}
172
- >
173
-
174
- {iconWrap}
175
-
176
- <div
177
- className={cn(
178
- drawerOpen ? "opacity-100" : "opacity-0 hidden",
179
- "ml-4 font-inherit text-inherit"
180
- )}>
181
- {name.toUpperCase()}
182
- </div>
183
- </NavLink>;
184
-
185
- return <Tooltip
186
- open={drawerOpen ? false : tooltipsOpen}
187
- side="right"
188
- title={name}>
189
- {listItem}
190
- </Tooltip>;
191
- }
@@ -0,0 +1,62 @@
1
+ import React from "react";
2
+
3
+ import { NavLink } from "react-router-dom";
4
+ import { cn, Tooltip } from "@firecms/ui";
5
+
6
+ export function DrawerNavigationItem({
7
+ name,
8
+ icon,
9
+ drawerOpen,
10
+ tooltipsOpen,
11
+ url,
12
+ onClick
13
+ }: {
14
+ icon: React.ReactElement,
15
+ name: string,
16
+ tooltipsOpen: boolean,
17
+ drawerOpen: boolean,
18
+ url: string,
19
+ onClick?: () => void,
20
+ }) {
21
+
22
+ const iconWrap = <div
23
+ className={"text-gray-600 dark:text-gray-500"}>
24
+ {icon}
25
+ </div>;
26
+
27
+ const listItem = <NavLink
28
+ onClick={onClick}
29
+ style={{
30
+ width: !drawerOpen ? "72px" : "280px",
31
+ transition: drawerOpen ? "width 150ms ease-in" : undefined
32
+ }}
33
+ className={({ isActive }: any) => cn("rounded-r-lg truncate",
34
+ "hover:bg-slate-300 hover:bg-opacity-75 dark:hover:bg-gray-700 dark:hover:bg-opacity-75 text-gray-800 dark:text-gray-200 hover:text-gray-900 hover:dark:text-white",
35
+ "flex flex-row items-center mr-8",
36
+ // "transition-all ease-in-out delay-100 duration-300",
37
+ // drawerOpen ? "w-full" : "w-18",
38
+ drawerOpen ? "pl-8 h-12" : "pl-6 h-11",
39
+ "font-medium text-sm",
40
+ isActive ? "bg-slate-200 bg-opacity-60 dark:bg-gray-800 dark:bg-opacity-30" : ""
41
+ )}
42
+ to={url}
43
+ >
44
+
45
+ {iconWrap}
46
+
47
+ <div
48
+ className={cn(
49
+ drawerOpen ? "opacity-100" : "opacity-0 hidden",
50
+ "ml-4 font-inherit text-inherit"
51
+ )}>
52
+ {name.toUpperCase()}
53
+ </div>
54
+ </NavLink>;
55
+
56
+ return <Tooltip
57
+ open={drawerOpen ? false : tooltipsOpen}
58
+ side="right"
59
+ title={name}>
60
+ {listItem}
61
+ </Tooltip>;
62
+ }
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from "react";
2
2
 
3
- import { EntityCollection, FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
3
+ import { CustomizationController, EntityCollection, FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
4
4
  import { AuthControllerContext, ModeControllerContext } from "../contexts";
5
5
  import { useBuildSideEntityController } from "../internal/useBuildSideEntityController";
6
6
  import { useCustomizationController, useFireCMSContext, useModeController } from "../hooks";
@@ -15,7 +15,6 @@ import { SideDialogsControllerContext } from "../contexts/SideDialogsControllerC
15
15
  import { CenteredView, Typography, useLocaleConfig } from "@firecms/ui";
16
16
  import { DialogsProvider } from "../contexts/DialogsProvider";
17
17
  import { useBuildDataSource } from "../internal/useBuildDataSource";
18
- import { useBuildCustomizationController } from "../internal/useBuildCustomizationController";
19
18
  import { CustomizationControllerContext } from "../contexts/CustomizationControllerContext";
20
19
  import { AnalyticsContext } from "../contexts/AnalyticsContext";
21
20
  import { useProjectLog } from "../hooks/useProjectLog";
@@ -54,6 +53,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
54
53
 
55
54
  useLocaleConfig(locale);
56
55
 
56
+ console.debug("FireCMS propertyConfigs", propertyConfigs);
57
57
  /**
58
58
  * Controller in charge of fetching and persisting data
59
59
  */
@@ -70,7 +70,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
70
70
 
71
71
  const loading = authController.initialLoading || navigationController.loading || pluginsLoading;
72
72
 
73
- const customizationController = useBuildCustomizationController({
73
+ const customizationController: CustomizationController = {
74
74
  dateTimeFormat,
75
75
  locale,
76
76
  entityLinkBuilder,
@@ -78,7 +78,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
78
78
  entityViews: entityViews ?? [],
79
79
  propertyConfigs: propertyConfigs ?? {},
80
80
  components
81
- });
81
+ };
82
82
 
83
83
  const analyticsController = useMemo(() => ({
84
84
  onAnalyticsEvent
@@ -9,10 +9,26 @@ import { ChevronLeftIcon, cn, defaultBorderMixin, IconButton, MenuIcon, Sheet, T
9
9
 
10
10
  export const DRAWER_WIDTH = 280;
11
11
 
12
+ const DrawerContext = React.createContext<DrawerProps>({
13
+ hovered: false,
14
+ drawerOpen: false,
15
+ openDrawer: () => {
16
+ throw new Error("openDrawer not implemented");
17
+ },
18
+ closeDrawer: () => {
19
+ throw new Error("closeDrawer not implemented");
20
+ },
21
+ autoOpenDrawer: false
22
+ });
23
+
24
+ export function useDrawer() {
25
+ return React.useContext(DrawerContext);
26
+ }
27
+
12
28
  /**
13
29
  * @group Core
14
30
  */
15
- export interface ScaffoldProps<ExtraDrawerProps = object, ExtraAppbarProps = object> {
31
+ export interface ScaffoldProps<ExtraAppbarProps = object> {
16
32
 
17
33
  /**
18
34
  * Name of the app, displayed as the main title and in the tab title
@@ -30,15 +46,10 @@ export interface ScaffoldProps<ExtraDrawerProps = object, ExtraAppbarProps = obj
30
46
  includeDrawer?: boolean;
31
47
 
32
48
  /**
33
- * In case you need to override the view that gets rendered as a drawer
34
- * @see DefaultDrawer
35
- */
36
- Drawer?: React.ComponentType<DrawerProps<ExtraDrawerProps>>;
37
-
38
- /**
39
- * Additional props passed to the custom Drawer
49
+ * You can define a custom drawer to be displayed in the scaffold.
50
+ * Use the hook `useDrawer` to access the context values.
40
51
  */
41
- drawerProps?: Partial<DrawerProps> & ExtraDrawerProps;
52
+ drawer?: React.ReactNode;
42
53
 
43
54
  /**
44
55
  * Open the drawer on hover
@@ -78,8 +89,7 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
78
89
  logo,
79
90
  includeDrawer = true,
80
91
  autoOpenDrawer,
81
- Drawer = DefaultDrawer,
82
- drawerProps,
92
+ drawer = <DefaultDrawer/>,
83
93
  FireCMSAppBar = DefaultFireCMSAppBar,
84
94
  fireCMSAppBarProps,
85
95
  } = props;
@@ -92,61 +102,65 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
92
102
  const setOnHoverTrue = useCallback(() => setOnHover(true), []);
93
103
  const setOnHoverFalse = useCallback(() => setOnHover(false), []);
94
104
 
105
+ const handleDrawerOpen = useCallback(() => {
106
+ setDrawerOpen(true);
107
+ }, []);
108
+
95
109
  const handleDrawerClose = useCallback(() => {
96
110
  setDrawerOpen(false);
97
111
  }, []);
98
112
 
99
113
  const computedDrawerOpen: boolean = drawerOpen || Boolean(largeLayout && autoOpenDrawer && onHover);
114
+
100
115
  return (
101
- <div
102
- className="flex h-screen w-screen bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white overflow-hidden"
103
- style={{
104
- paddingTop: "env(safe-area-inset-top)",
105
- paddingLeft: "env(safe-area-inset-left)",
106
- paddingRight: "env(safe-area-inset-right)",
107
- paddingBottom: "env(safe-area-inset-bottom)",
108
- height: "100dvh"
109
- // "@supports (height: 100dvh)": {
110
- // height: "100dvh"
111
- // }
112
- }}>
113
-
114
- <FireCMSAppBar title={name}
115
- includeDrawer={includeDrawer}
116
- logo={logo}
117
- drawerOpen={computedDrawerOpen}
118
- {...fireCMSAppBarProps}/>
119
-
120
- <StyledDrawer
121
- displayed={includeDrawer}
122
- onMouseEnter={setOnHoverTrue}
123
- onMouseMove={setOnHoverTrue}
124
- onMouseLeave={setOnHoverFalse}
125
- open={computedDrawerOpen}
126
- logo={logo}
127
- hovered={onHover}
128
- setDrawerOpen={setDrawerOpen}>
129
- {includeDrawer && (
130
- <Drawer
131
- hovered={onHover}
132
- drawerOpen={computedDrawerOpen}
133
- closeDrawer={handleDrawerClose}
134
- {...drawerProps}/>)}
135
- </StyledDrawer>
136
-
137
- <main
138
- className="flex flex-col flex-grow overflow-auto">
139
- <DrawerHeader/>
140
- <div
141
- className={cn(defaultBorderMixin, "flex-grow overflow-auto lg:m-0 lg:mx-4 lg:mb-4 lg:rounded-lg lg:border lg:border-solid m-0 mt-1")}>
142
-
143
- <ErrorBoundary>
144
- {children}
145
- </ErrorBoundary>
146
-
147
- </div>
148
- </main>
149
- </div>
116
+ <DrawerContext.Provider value={{
117
+ hovered: onHover,
118
+ drawerOpen: computedDrawerOpen,
119
+ closeDrawer: handleDrawerClose,
120
+ openDrawer: handleDrawerOpen,
121
+ autoOpenDrawer
122
+ }}>
123
+ <div
124
+ className="flex h-screen w-screen bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white overflow-hidden"
125
+ style={{
126
+ paddingTop: "env(safe-area-inset-top)",
127
+ paddingLeft: "env(safe-area-inset-left)",
128
+ paddingRight: "env(safe-area-inset-right)",
129
+ paddingBottom: "env(safe-area-inset-bottom)",
130
+ height: "100dvh"
131
+ }}>
132
+
133
+ <FireCMSAppBar title={name}
134
+ includeDrawer={includeDrawer}
135
+ logo={logo}
136
+ drawerOpen={computedDrawerOpen}
137
+ {...fireCMSAppBarProps}/>
138
+ <DrawerWrapper
139
+ displayed={includeDrawer}
140
+ onMouseEnter={setOnHoverTrue}
141
+ onMouseMove={setOnHoverTrue}
142
+ onMouseLeave={setOnHoverFalse}
143
+ open={computedDrawerOpen}
144
+ logo={logo}
145
+ hovered={onHover}
146
+ setDrawerOpen={setDrawerOpen}>
147
+ {includeDrawer && drawer}
148
+ </DrawerWrapper>
149
+
150
+ <main
151
+ className="flex flex-col flex-grow overflow-auto">
152
+ <DrawerHeader/>
153
+ <div
154
+ className={cn(defaultBorderMixin, "flex-grow overflow-auto lg:m-0 lg:mx-4 lg:mb-4 lg:rounded-lg lg:border lg:border-solid m-0 mt-1")}>
155
+
156
+ <ErrorBoundary>
157
+ {children}
158
+ </ErrorBoundary>
159
+
160
+ </div>
161
+ </main>
162
+ </div>
163
+ </DrawerContext.Provider>
150
164
  );
151
165
  },
152
166
  equal
@@ -158,7 +172,7 @@ const DrawerHeader = () => {
158
172
  );
159
173
  };
160
174
 
161
- function StyledDrawer(props: {
175
+ function DrawerWrapper(props: {
162
176
  children: React.ReactNode,
163
177
  displayed: boolean,
164
178
  open: boolean,
@@ -1,10 +1,9 @@
1
1
  export * from "./FireCMS";
2
2
 
3
- export type { ScaffoldProps } from "./Scaffold";
4
- export { Scaffold } from "./Scaffold";
3
+ export * from "./Scaffold";
5
4
 
6
- export type { DrawerProps } from "./Drawer";
7
- export { Drawer, DrawerNavigationItem } from "./Drawer";
5
+ export * from "./Drawer";
6
+ export * from "./DrawerNavigationItem";
8
7
 
9
8
  export * from "./field_configs";
10
9
 
@@ -179,6 +179,7 @@ function EntityFormInternal<M extends Record<string, any>>({
179
179
  const analyticsController = useAnalyticsController();
180
180
 
181
181
  const customizationController = useCustomizationController();
182
+ console.log("EntityFormInternal propertyConfigs", customizationController.propertyConfigs);
182
183
 
183
184
  const context = useFireCMSContext();
184
185
  const dataSource = useDataSource(inputCollection);
@@ -189,7 +190,7 @@ function EntityFormInternal<M extends Record<string, any>>({
189
190
  path,
190
191
  values: entity?.values,
191
192
  fields: customizationController.propertyConfigs
192
- }), [entity?.values, path]);
193
+ }), [entity?.values, path, customizationController.propertyConfigs]);
193
194
 
194
195
  const mustSetCustomId: boolean = (status === "new" || status === "copy") &&
195
196
  (Boolean(initialResolvedCollection.customId) && initialResolvedCollection.customId !== "optional");
@@ -10,6 +10,7 @@ export * from "./useResolvedNavigationFrom";
10
10
 
11
11
  export * from "./useStorageSource";
12
12
  export * from "./useAuthController";
13
+ export * from "./useDialogsController";
13
14
  export * from "./useSideDialogsController";
14
15
  export * from "./useSideEntityController";
15
16
  export * from "./useFireCMSContext";
@@ -101,5 +101,5 @@ export interface StorageSource {
101
101
  * @param props
102
102
  * @param bucket
103
103
  */
104
- getFile: (path:string, bucket?: string) => Promise<File | null>;
104
+ getFile: (path: string, bucket?: string) => Promise<File | null>;
105
105
  }
@@ -144,6 +144,7 @@ export const iconSynonyms = {
144
144
  auto_stories: "audiobook flipping pages reading story",
145
145
  av_timer: "clock countdown duration minutes seconds stopwatch",
146
146
  baby_changing_station: "babies bathroom body children father human infant kids mother newborn people person toddler wc young",
147
+ back: "arrow_back",
147
148
  backpack: "bookbag knapsack storage travel",
148
149
  backspace: "arrow cancel clear correct delete erase remove",
149
150
  backup: "arrow cloud data drive files folders point storage submit upload",
@@ -357,8 +358,8 @@ export const iconSynonyms = {
357
358
  contact_phone: "account avatar call communicate face human information message mobile number people person profile user",
358
359
  contacts: "account address avatar call cell face human information mobile number people person phone profile user",
359
360
  contact_support: "? alert announcement bubble chat comment communicate help information mark message punctuation speech symbol vquestion",
360
- content_copy: "cut document duplicate file multiple past",
361
- content_cut: "copy document file past scissors trim",
361
+ content_copy: "copy document duplicate file multiple past",
362
+ content_cut: "cut document file past scissors trim",
362
363
  content_paste: "clipboard copy cut document file multiple",
363
364
  content_paste_go: "clipboard disabled document enabled file slash",
364
365
  content_paste_off: "clipboard disabled document enabled file slash",
@@ -1,2 +0,0 @@
1
- import { CustomizationController } from "../types/customization_controller";
2
- export declare function useBuildCustomizationController(controller: CustomizationController): CustomizationController;
@@ -1,5 +0,0 @@
1
- import { CustomizationController } from "../types/customization_controller";
2
-
3
- export function useBuildCustomizationController(controller: CustomizationController): CustomizationController {
4
- return controller;
5
- }