@firecms/core 3.0.0-rc.1 → 3.0.0-rc.3

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 (96) hide show
  1. package/dist/components/HomePage/HomePageDnD.d.ts +2 -1
  2. package/dist/components/PropertyCollectionView.d.ts +23 -0
  3. package/dist/components/UserDisplay.d.ts +7 -0
  4. package/dist/components/VirtualTable/fields/VirtualTableUserSelect.d.ts +12 -0
  5. package/dist/contexts/InternalUserManagementContext.d.ts +3 -0
  6. package/dist/core/EntityEditView.d.ts +10 -4
  7. package/dist/core/FireCMS.d.ts +0 -1
  8. package/dist/core/field_configs.d.ts +1 -1
  9. package/dist/form/EntityForm.d.ts +5 -2
  10. package/dist/form/components/LocalChangesMenu.d.ts +11 -0
  11. package/dist/form/field_bindings/UserSelectFieldBinding.d.ts +12 -0
  12. package/dist/form/index.d.ts +2 -1
  13. package/dist/hooks/index.d.ts +2 -0
  14. package/dist/hooks/useCollapsedGroups.d.ts +9 -0
  15. package/dist/hooks/useInternalUserManagementController.d.ts +12 -0
  16. package/dist/index.es.js +1983 -650
  17. package/dist/index.es.js.map +1 -1
  18. package/dist/index.umd.js +1981 -648
  19. package/dist/index.umd.js.map +1 -1
  20. package/dist/preview/components/UserPreview.d.ts +8 -0
  21. package/dist/preview/index.d.ts +1 -0
  22. package/dist/types/collections.d.ts +13 -0
  23. package/dist/types/entities.d.ts +5 -1
  24. package/dist/types/firecms.d.ts +15 -0
  25. package/dist/types/firecms_context.d.ts +16 -0
  26. package/dist/types/index.d.ts +1 -0
  27. package/dist/types/internal_user_management.d.ts +20 -0
  28. package/dist/types/plugins.d.ts +2 -0
  29. package/dist/types/properties.d.ts +41 -6
  30. package/dist/types/property_config.d.ts +1 -1
  31. package/dist/types/user.d.ts +1 -1
  32. package/dist/util/collections.d.ts +1 -0
  33. package/dist/util/entity_cache.d.ts +6 -1
  34. package/dist/util/make_properties_editable.d.ts +1 -2
  35. package/dist/util/objects.d.ts +1 -0
  36. package/dist/util/useStorageUploadController.d.ts +1 -0
  37. package/package.json +6 -6
  38. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +47 -47
  39. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +12 -0
  40. package/src/components/EntityCollectionView/EntityCollectionView.tsx +6 -1
  41. package/src/components/EntityView.tsx +29 -40
  42. package/src/components/ErrorView.tsx +1 -1
  43. package/src/components/HomePage/DefaultHomePage.tsx +21 -34
  44. package/src/components/HomePage/HomePageDnD.tsx +143 -83
  45. package/src/components/HomePage/RenameGroupDialog.tsx +9 -3
  46. package/src/components/PropertyCollectionView.tsx +329 -0
  47. package/src/components/PropertyConfigBadge.tsx +2 -2
  48. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +2 -1
  49. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +1 -2
  50. package/src/components/UserDisplay.tsx +55 -0
  51. package/src/components/VirtualTable/fields/VirtualTableUserSelect.tsx +99 -0
  52. package/src/components/common/useColumnsIds.tsx +1 -8
  53. package/src/contexts/InternalUserManagementContext.tsx +4 -0
  54. package/src/core/EntityEditView.tsx +27 -14
  55. package/src/core/EntityEditViewFormActions.tsx +33 -18
  56. package/src/core/EntitySidePanel.tsx +9 -3
  57. package/src/core/FireCMS.tsx +22 -13
  58. package/src/core/field_configs.tsx +15 -1
  59. package/src/form/EntityForm.tsx +173 -42
  60. package/src/form/EntityFormActions.tsx +30 -15
  61. package/src/form/PropertyFieldBinding.tsx +4 -0
  62. package/src/form/components/ErrorFocus.tsx +22 -29
  63. package/src/form/components/LocalChangesMenu.tsx +144 -0
  64. package/src/form/field_bindings/UserSelectFieldBinding.tsx +94 -0
  65. package/src/form/index.tsx +5 -1
  66. package/src/hooks/index.tsx +3 -0
  67. package/src/hooks/useBrowserTitleAndIcon.tsx +1 -1
  68. package/src/hooks/useBuildNavigationController.tsx +104 -31
  69. package/src/hooks/useCollapsedGroups.ts +64 -0
  70. package/src/hooks/useFireCMSContext.tsx +6 -2
  71. package/src/hooks/useInternalUserManagementController.tsx +16 -0
  72. package/src/preview/PropertyPreview.tsx +8 -0
  73. package/src/preview/components/ReferencePreview.tsx +4 -2
  74. package/src/preview/components/UserPreview.tsx +27 -0
  75. package/src/preview/index.ts +1 -0
  76. package/src/preview/property_previews/ArrayPropertyPreview.tsx +1 -1
  77. package/src/preview/property_previews/MapPropertyPreview.tsx +2 -2
  78. package/src/preview/property_previews/NumberPropertyPreview.tsx +2 -2
  79. package/src/types/collections.ts +14 -0
  80. package/src/types/entities.ts +7 -1
  81. package/src/types/firecms.tsx +16 -0
  82. package/src/types/firecms_context.tsx +17 -0
  83. package/src/types/index.ts +1 -0
  84. package/src/types/internal_user_management.ts +24 -0
  85. package/src/types/plugins.tsx +3 -0
  86. package/src/types/properties.ts +45 -6
  87. package/src/types/property_config.tsx +1 -0
  88. package/src/types/user.ts +1 -1
  89. package/src/util/collections.ts +8 -0
  90. package/src/util/createFormexStub.tsx +4 -0
  91. package/src/util/entities.ts +1 -1
  92. package/src/util/entity_cache.ts +72 -53
  93. package/src/util/join_collections.ts +3 -3
  94. package/src/util/make_properties_editable.ts +0 -22
  95. package/src/util/objects.ts +40 -2
  96. package/src/util/useStorageUploadController.tsx +71 -34
@@ -3,6 +3,7 @@ import {
3
3
  Entity,
4
4
  EntityCollection,
5
5
  EntityStatus,
6
+ EntityValues,
6
7
  FireCMSPlugin,
7
8
  FormContext,
8
9
  PluginFormActionProps,
@@ -26,7 +27,7 @@ import {
26
27
  useLargeLayout
27
28
  } from "../hooks";
28
29
  import { CircularProgress, cls, CodeIcon, defaultBorderMixin, Tab, Tabs, Typography } from "@firecms/ui";
29
- import { getEntityFromCache } from "../util/entity_cache";
30
+ import { getEntityFromMemoryCache } from "../util/entity_cache";
30
31
  import { EntityForm, EntityFormProps } from "../form";
31
32
  import { EntityEditViewFormActions } from "./EntityEditViewFormActions";
32
33
  import { EntityJsonPreview } from "../components/EntityJsonPreview";
@@ -44,6 +45,13 @@ export type OnUpdateParams = {
44
45
  collection: EntityCollection<any>
45
46
  };
46
47
 
48
+ export type BarActionsParams = {
49
+ values: object,
50
+ status: EntityStatus,
51
+ path: string,
52
+ entityId?: string;
53
+ };
54
+
47
55
  export type OnTabChangeParams<M extends Record<string, any>> = {
48
56
  path: string;
49
57
  entityId?: string;
@@ -67,11 +75,11 @@ export interface EntityEditViewProps<M extends Record<string, any>> {
67
75
  copy?: boolean;
68
76
  selectedTab?: string;
69
77
  parentCollectionIds: string[];
70
- onValuesModified?: (modified: boolean) => void;
78
+ onValuesModified?: (modified: boolean, values:M) => void;
71
79
  onSaved?: (params: OnUpdateParams) => void;
72
80
  onTabChange?: (props: OnTabChangeParams<M>) => void;
73
81
  layout?: "side_panel" | "full_screen";
74
- barActions?: React.ReactNode;
82
+ barActions?: (params: BarActionsParams) => React.ReactNode;
75
83
  formProps?: Partial<EntityFormProps<M>>,
76
84
  }
77
85
 
@@ -97,9 +105,9 @@ export function EntityEditView<M extends Record<string, any>, USER extends User>
97
105
  useCache: false
98
106
  });
99
107
 
100
- const cachedValues = entityId
101
- ? getEntityFromCache(props.path + "/" + entityId)
102
- : getEntityFromCache(props.path + "#new");
108
+ const initialDirtyValues = entityId
109
+ ? getEntityFromMemoryCache(props.path + "/" + entityId)
110
+ : getEntityFromMemoryCache(props.path + "#new");
103
111
 
104
112
  const authController = useAuthController();
105
113
 
@@ -114,18 +122,18 @@ export function EntityEditView<M extends Record<string, any>, USER extends User>
114
122
  }
115
123
  }, [authController, entity, status]);
116
124
 
117
- if ((dataLoading && !cachedValues) || (!entity || canEdit === undefined) && (status === "existing" || status === "copy")) {
125
+ if ((dataLoading && !initialDirtyValues) || (!entity || canEdit === undefined) && (status === "existing" || status === "copy")) {
118
126
  return <CircularProgressCenter/>;
119
127
  }
120
128
 
121
- if (entityId && !entity && !cachedValues) {
129
+ if (entityId && !entity && !initialDirtyValues) {
122
130
  console.error(`Entity with id ${entityId} not found in collection ${props.path}`);
123
131
  }
124
132
 
125
133
  return <EntityEditViewInner<M> {...props}
126
134
  entityId={entityId}
127
135
  entity={entity}
128
- cachedDirtyValues={cachedValues as Partial<M>}
136
+ initialDirtyValues={initialDirtyValues as Partial<M>}
129
137
  dataLoading={dataLoading}
130
138
  status={status}
131
139
  setStatus={setStatus}
@@ -144,7 +152,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
144
152
  onSaved,
145
153
  onTabChange,
146
154
  entity,
147
- cachedDirtyValues,
155
+ initialDirtyValues,
148
156
  dataLoading,
149
157
  layout = "side_panel",
150
158
  barActions,
@@ -154,7 +162,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
154
162
  canEdit
155
163
  }: EntityEditViewProps<M> & {
156
164
  entity?: Entity<M>,
157
- cachedDirtyValues?: Partial<M>, // dirty cached entity in memory
165
+ initialDirtyValues?: Partial<M>, // dirty cached entity in memory
158
166
  dataLoading: boolean,
159
167
  status: EntityStatus,
160
168
  setStatus: (status: EntityStatus) => void,
@@ -379,7 +387,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
379
387
  entityId={entityId ?? usedEntity?.id}
380
388
  onValuesModified={onValuesModified}
381
389
  entity={entity}
382
- initialDirtyValues={cachedDirtyValues}
390
+ initialDirtyValues={initialDirtyValues}
383
391
  openEntityMode={layout}
384
392
  forceActionsAtTheBottom={actionsAtTheBottom}
385
393
  initialStatus={status}
@@ -388,6 +396,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
388
396
  disabled={!canEdit}
389
397
  {...formProps}
390
398
  onEntityChange={(entity) => {
399
+ console.log("333 EntityEditView onEntityChange:", entity);
391
400
  setUsedEntity(entity);
392
401
  formProps?.onEntityChange?.(entity);
393
402
  }}
@@ -445,7 +454,12 @@ export function EntityEditViewInner<M extends Record<string, any>>({
445
454
  {shouldShowTopBar && <div
446
455
  className={cls("h-14 items-center flex overflow-visible overflow-x-scroll w-full no-scrollbar h-14 border-b pl-2 pr-2 pt-1 flex bg-surface-50 dark:bg-surface-900", defaultBorderMixin)}>
447
456
 
448
- {barActions}
457
+ {barActions?.({
458
+ path: fullIdPath ?? path,
459
+ entityId,
460
+ values: formContext?.values ?? usedEntity?.values ?? {},
461
+ status
462
+ })}
449
463
 
450
464
  <div className={"flex-grow"}/>
451
465
 
@@ -523,4 +537,3 @@ export function EntityEditViewInner<M extends Record<string, any>>({
523
537
 
524
538
  return result;
525
539
  }
526
-
@@ -17,6 +17,7 @@ import {
17
17
  cls,
18
18
  defaultBorderMixin,
19
19
  DialogActions,
20
+ ErrorIcon,
20
21
  IconButton,
21
22
  LoadingButton,
22
23
  Tooltip,
@@ -31,6 +32,8 @@ import {
31
32
  } from "../hooks";
32
33
  import { EntityFormActionsProps } from "../form/EntityFormActions";
33
34
  import { SideDialogController, useSideDialogContext } from "./SideDialogs";
35
+ import { FormexController } from "@firecms/formex";
36
+ import { ErrorTooltip } from "../components/ErrorTooltip";
34
37
 
35
38
  export function EntityEditViewFormActions({
36
39
  collection,
@@ -80,14 +83,14 @@ export function EntityEditViewFormActions({
80
83
  collection,
81
84
  context,
82
85
  sideEntityController,
83
- isSubmitting: formex.isSubmitting,
84
86
  disabled,
85
87
  status,
86
88
  sideDialogContext,
87
89
  pluginActions,
88
90
  openEntityMode,
89
91
  navigateBack,
90
- formContext
92
+ formContext,
93
+ formex
91
94
  })
92
95
  : buildSideActions({
93
96
  savingError,
@@ -96,14 +99,14 @@ export function EntityEditViewFormActions({
96
99
  collection,
97
100
  context,
98
101
  sideEntityController,
99
- isSubmitting: formex.isSubmitting,
100
102
  sideDialogContext,
101
103
  disabled,
102
104
  status,
103
105
  pluginActions,
104
106
  openEntityMode,
105
107
  navigateBack,
106
- formContext
108
+ formContext,
109
+ formex
107
110
  });
108
111
  }
109
112
 
@@ -114,14 +117,14 @@ type ActionsViewProps<M extends object> = {
114
117
  collection: ResolvedEntityCollection,
115
118
  context: FireCMSContext,
116
119
  sideEntityController: SideEntityController,
117
- isSubmitting: boolean,
118
120
  disabled: boolean,
119
121
  status: "new" | "existing" | "copy",
120
122
  sideDialogContext: SideDialogController,
121
123
  pluginActions?: React.ReactNode[],
122
124
  openEntityMode: "side_panel" | "full_screen";
123
125
  navigateBack: () => void;
124
- formContext: FormContext
126
+ formContext: FormContext,
127
+ formex: FormexController<any>;
125
128
  };
126
129
 
127
130
  function buildBottomActions<M extends object>({
@@ -131,16 +134,17 @@ function buildBottomActions<M extends object>({
131
134
  collection,
132
135
  context,
133
136
  sideEntityController,
134
- isSubmitting,
135
137
  disabled,
136
138
  status,
137
139
  sideDialogContext,
138
140
  pluginActions,
139
141
  openEntityMode,
140
142
  navigateBack,
141
- formContext
143
+ formContext,
144
+ formex
142
145
  }: ActionsViewProps<M>) {
143
146
 
147
+ const hasErrors = Object.keys(formex.errors).length > 0 && formex.submitCount > 0;
144
148
  const canClose = openEntityMode === "side_panel";
145
149
  return <DialogActions
146
150
  position={"absolute"}>
@@ -179,16 +183,20 @@ function buildBottomActions<M extends object>({
179
183
 
180
184
  {pluginActions}
181
185
 
186
+ {hasErrors ?
187
+ <ErrorTooltip title={"This form has errors"}>
188
+ <ErrorIcon className="ml-4" color="error" size={"smallest"}/>
189
+ </ErrorTooltip> : null}
182
190
  <Button variant="text"
183
191
  color="primary"
184
- disabled={disabled || isSubmitting}
192
+ disabled={disabled || formex.isSubmitting}
185
193
  type="reset">
186
194
  {status === "existing" ? "Discard" : "Clear"}
187
195
  </Button>
188
196
  <Button variant={canClose ? "text" : "filled"}
189
197
  color="primary"
190
198
  type="submit"
191
- disabled={disabled || isSubmitting}
199
+ disabled={disabled || formex.isSubmitting}
192
200
  onClick={() => {
193
201
  sideDialogContext.setPendingClose(false);
194
202
  }}>
@@ -199,7 +207,7 @@ function buildBottomActions<M extends object>({
199
207
  {canClose && <LoadingButton variant="filled"
200
208
  color="primary"
201
209
  type="submit"
202
- loading={isSubmitting}
210
+ loading={formex.isSubmitting}
203
211
  disabled={disabled}
204
212
  onClick={() => {
205
213
  sideDialogContext.setPendingClose?.(true);
@@ -218,28 +226,35 @@ function buildSideActions<M extends object>({
218
226
  collection,
219
227
  context,
220
228
  sideEntityController,
221
- isSubmitting,
222
229
  disabled,
223
230
  status,
224
231
  sideDialogContext,
225
232
  pluginActions,
226
233
  openEntityMode,
227
234
  navigateBack,
228
- formContext
235
+ formContext,
236
+ formex
229
237
  }: ActionsViewProps<M>) {
230
238
 
239
+ const hasErrors = Object.keys(formex.errors).length > 0 && formex.submitCount > 0;
231
240
  return <div
232
241
  className={cls("overflow-auto h-full flex flex-col gap-2 w-80 2xl:w-96 px-4 py-16 sticky top-0 border-l", defaultBorderMixin)}>
233
- <LoadingButton fullWidth={true} variant="filled" color="primary" type="submit" size={"large"}
234
- disabled={disabled || isSubmitting} onClick={() => {
235
- sideDialogContext.setPendingClose?.(false);
236
- }}>
242
+ <LoadingButton fullWidth={true}
243
+ variant="filled"
244
+ color="primary"
245
+ type="submit"
246
+ size={"large"}
247
+ startIcon={hasErrors ? <ErrorIcon/> : undefined}
248
+ disabled={disabled || formex.isSubmitting}
249
+ onClick={() => {
250
+ sideDialogContext.setPendingClose?.(false);
251
+ }}>
237
252
  {status === "existing" && "Save"}
238
253
  {status === "copy" && "Create copy"}
239
254
  {status === "new" && "Create"}
240
255
  </LoadingButton>
241
256
 
242
- <Button fullWidth={true} variant="text" disabled={disabled || isSubmitting} type="reset">
257
+ <Button fullWidth={true} variant="text" disabled={disabled || formex.isSubmitting} type="reset">
243
258
  {status === "existing" ? "Discard" : "Clear"}
244
259
  </Button>
245
260
 
@@ -1,6 +1,6 @@
1
1
  import React, { useCallback, useEffect, useMemo } from "react";
2
2
 
3
- import { EntitySidePanelProps } from "../types";
3
+ import { EntityCollection, EntitySidePanelProps } from "../types";
4
4
  import { useNavigationController, useSideEntityController } from "../hooks";
5
5
 
6
6
  import { ErrorBoundary } from "../components";
@@ -8,6 +8,7 @@ import { EntityEditView, OnUpdateParams } from "./EntityEditView";
8
8
  import { useSideDialogContext } from "./SideDialogs";
9
9
  import { CloseIcon, IconButton, OpenInFullIcon } from "@firecms/ui";
10
10
  import { useLocation, useNavigate } from "react-router-dom";
11
+ import { saveEntityToMemoryCache } from "../util/entity_cache";
11
12
 
12
13
  /**
13
14
  * This is the component in charge of rendering the side dialog used
@@ -114,11 +115,14 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
114
115
  {...props}
115
116
  fullIdPath={fullIdPath}
116
117
  layout={"side_panel"}
117
- collection={collection}
118
+ collection={collection as EntityCollection}
118
119
  parentCollectionIds={parentCollectionIds}
119
120
  onValuesModified={onValuesModified}
120
121
  onSaved={onUpdate}
121
- barActions={<>
122
+ barActions={({
123
+ status,
124
+ values
125
+ }) => <>
122
126
  <IconButton
123
127
  className="self-center"
124
128
  onClick={onClose}>
@@ -127,6 +131,8 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
127
131
  {allowFullScreen && <IconButton
128
132
  className="self-center"
129
133
  onClick={() => {
134
+ const key = (status === "new" || status === "copy") ? path + "#new" : path + "/" + entityId;
135
+ saveEntityToMemoryCache(key, values);
130
136
  if (entityId)
131
137
  navigate(location.pathname);
132
138
  else
@@ -20,6 +20,7 @@ import { CustomizationControllerContext } from "../contexts/CustomizationControl
20
20
  import { AnalyticsContext } from "../contexts/AnalyticsContext";
21
21
  import { useProjectLog } from "../hooks/useProjectLog";
22
22
  import { BreadcrumbsProvider } from "../contexts/BreacrumbsContext";
23
+ import { InternalUserManagementContext } from "../contexts/InternalUserManagementContext";
23
24
 
24
25
  /**
25
26
  * If you are using independent components of the CMS
@@ -30,7 +31,6 @@ import { BreadcrumbsProvider } from "../contexts/BreacrumbsContext";
30
31
  *
31
32
  * You only need to use this component if you are building a custom app.
32
33
  *
33
-
34
34
  * @group Core
35
35
  */
36
36
  export function FireCMS<USER extends User>(props: FireCMSProps<USER>) {
@@ -44,21 +44,28 @@ export function FireCMS<USER extends User>(props: FireCMSProps<USER>) {
44
44
  authController,
45
45
  storageSource,
46
46
  dataSourceDelegate,
47
- plugins: pluginsProp,
47
+ plugins: _pluginsProp,
48
48
  onAnalyticsEvent,
49
49
  propertyConfigs,
50
50
  entityViews,
51
51
  entityActions,
52
52
  components,
53
53
  navigationController,
54
- apiKey
54
+ apiKey,
55
+ userManagement: _userManagement
55
56
  } = props;
56
57
 
57
- if (pluginsProp) {
58
+ if (_pluginsProp) {
58
59
  console.warn("The `plugins` prop is deprecated in the FireCMS component. You should pass your plugins to `useBuildNavigationController` instead.");
59
60
  }
60
61
 
61
- const plugins = navigationController.plugins ?? pluginsProp;
62
+ const plugins = navigationController.plugins ?? _pluginsProp;
63
+ const userManagement = plugins?.find(p => p.userManagement)?.userManagement
64
+ ?? _userManagement
65
+ ?? {
66
+ users: [],
67
+ getUser: (uid: string) => null
68
+ };
62
69
 
63
70
  const sideDialogsController = useBuildSideDialogsController();
64
71
  const sideEntityController = useBuildSideEntityController(navigationController, sideDialogsController, authController);
@@ -156,14 +163,16 @@ export function FireCMS<USER extends User>(props: FireCMSProps<USER>) {
156
163
  value={sideEntityController}>
157
164
  <NavigationContext.Provider
158
165
  value={navigationController}>
159
- <DialogsProvider>
160
- <BreadcrumbsProvider>
161
- <FireCMSInternal
162
- loading={loading}>
163
- {children}
164
- </FireCMSInternal>
165
- </BreadcrumbsProvider>
166
- </DialogsProvider>
166
+ <InternalUserManagementContext.Provider value={userManagement}>
167
+ <DialogsProvider>
168
+ <BreadcrumbsProvider>
169
+ <FireCMSInternal
170
+ loading={loading}>
171
+ {children}
172
+ </FireCMSInternal>
173
+ </BreadcrumbsProvider>
174
+ </DialogsProvider>
175
+ </InternalUserManagementContext.Provider>
167
176
  </NavigationContext.Provider>
168
177
  </SideEntityControllerContext.Provider>
169
178
  </SideDialogsControllerContext.Provider>
@@ -32,14 +32,16 @@ import {
32
32
  ListAltIcon,
33
33
  ListIcon,
34
34
  MailIcon,
35
- NumbersIcon,
35
+ NumbersIcon, PersonIcon,
36
36
  RepeatIcon,
37
37
  ScheduleIcon,
38
38
  ShortTextIcon,
39
39
  SubjectIcon,
40
40
  UploadFileIcon,
41
+ VerifiedUserIcon,
41
42
  ViewStreamIcon
42
43
  } from "@firecms/ui";
44
+ import { UserSelectFieldBinding } from "../form/field_bindings/UserSelectFieldBinding";
43
45
 
44
46
  export function isDefaultFieldConfigId(id: string) {
45
47
  return Object.keys(DEFAULT_FIELD_CONFIGS).includes(id);
@@ -143,6 +145,16 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
143
145
  Field: MultiSelectFieldBinding
144
146
  }
145
147
  },
148
+ user_select: {
149
+ key: "user_select",
150
+ name: "User select",
151
+ description: "Select a user from the user management system. Store the user ID.",
152
+ Icon: PersonIcon,
153
+ property: {
154
+ dataType: "string",
155
+ Field: UserSelectFieldBinding
156
+ }
157
+ },
146
158
  number_input: {
147
159
  key: "number_input",
148
160
  name: "Number input",
@@ -360,6 +372,8 @@ export function getDefaultFieldId(property: Property | ResolvedProperty) {
360
372
  return "email";
361
373
  } else if (property.enumValues) {
362
374
  return "select";
375
+ } else if (property.userSelect) {
376
+ return "user_select";
363
377
  } else if (property.reference) {
364
378
  return "reference_as_string";
365
379
  } else {