@firecms/core 3.0.0-alpha.27 → 3.0.0-alpha.28

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 (51) hide show
  1. package/dist/components/Popover.d.ts +3 -1
  2. package/dist/core/builders.d.ts +3 -3
  3. package/dist/core/components/EntityCollectionTable/filters/ReferenceFilterField.d.ts +3 -3
  4. package/dist/core/components/FieldConfigBadge.d.ts +3 -3
  5. package/dist/core/components/VirtualTable/VirtualTableHeader.d.ts +2 -2
  6. package/dist/core/form_field_configs.d.ts +3 -3
  7. package/dist/core/util/property_utils.d.ts +5 -5
  8. package/dist/core/util/references.d.ts +2 -2
  9. package/dist/core/util/resolutions.d.ts +5 -5
  10. package/dist/hooks/index.d.ts +1 -0
  11. package/dist/hooks/useBuildDataSource.d.ts +23 -0
  12. package/dist/index.es.js +6877 -6634
  13. package/dist/index.es.js.map +1 -1
  14. package/dist/index.umd.js +14 -14
  15. package/dist/index.umd.js.map +1 -1
  16. package/dist/types/datasource.d.ts +120 -11
  17. package/dist/types/fields.d.ts +1 -1
  18. package/dist/types/firecms.d.ts +3 -3
  19. package/dist/types/firecms_context.d.ts +3 -3
  20. package/dist/types/index.d.ts +1 -1
  21. package/dist/types/properties.d.ts +1 -1
  22. package/dist/types/{field_config.d.ts → property_config.d.ts} +3 -4
  23. package/package.json +2 -2
  24. package/src/components/Popover.tsx +10 -3
  25. package/src/components/TextareaAutosize.tsx +2 -1
  26. package/src/core/builders.ts +5 -5
  27. package/src/core/components/EntityCollectionTable/EntityCollectionTable.tsx +4 -4
  28. package/src/core/components/EntityCollectionTable/filters/ReferenceFilterField.tsx +11 -6
  29. package/src/core/components/EntityCollectionTable/internal/PropertyTableCell.tsx +2 -2
  30. package/src/core/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +6 -2
  31. package/src/core/components/EntityCollectionView/EntityCollectionView.tsx +1 -1
  32. package/src/core/components/FieldConfigBadge.tsx +4 -4
  33. package/src/core/components/VirtualTable/VirtualTableHeader.tsx +21 -18
  34. package/src/core/form_field_configs.tsx +5 -5
  35. package/src/core/util/property_utils.tsx +5 -5
  36. package/src/core/util/references.ts +2 -2
  37. package/src/core/util/resolutions.ts +16 -11
  38. package/src/form/EntityForm.tsx +1 -1
  39. package/src/form/PropertyFieldBinding.tsx +4 -4
  40. package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
  41. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +4 -6
  42. package/src/hooks/index.tsx +1 -0
  43. package/src/hooks/useBuildDataSource.ts +351 -0
  44. package/src/preview/property_previews/StringPropertyPreview.tsx +4 -2
  45. package/src/types/datasource.ts +174 -10
  46. package/src/types/fields.tsx +1 -1
  47. package/src/types/firecms.tsx +3 -3
  48. package/src/types/firecms_context.tsx +3 -3
  49. package/src/types/index.ts +1 -1
  50. package/src/types/properties.ts +1 -1
  51. package/src/types/{field_config.tsx → property_config.tsx} +3 -4
@@ -1,6 +1,6 @@
1
- import { Entity, EntityStatus, EntityValues } from "./entities";
1
+ import { Entity, EntityReference, EntityStatus, EntityValues, GeoPoint } from "./entities";
2
2
  import { EntityCollection, FilterValues } from "./collections";
3
- import { ResolvedEntityCollection, ResolvedProperty } from "./resolved_entities";
3
+ import { ResolvedEntityCollection } from "./resolved_entities";
4
4
  /**
5
5
  * @category Datasource
6
6
  */
@@ -131,7 +131,7 @@ export interface DataSource {
131
131
  * @param entityId
132
132
  * @return `true` if there are no other fields besides the given entity
133
133
  */
134
- checkUniqueField(path: string, name: string, value: any, property: ResolvedProperty, entityId?: string): Promise<boolean>;
134
+ checkUniqueField(path: string, name: string, value: any, entityId?: string): Promise<boolean>;
135
135
  /**
136
136
  * Generate an id for a new entity
137
137
  */
@@ -142,12 +142,121 @@ export interface DataSource {
142
142
  countEntities<M extends Record<string, any> = any>(props: FetchCollectionProps<M>): Promise<number>;
143
143
  /**
144
144
  * Check if the given filter combination is valid
145
- * @param params
146
- */
147
- isFilterCombinationValid?(params: {
148
- path: string;
149
- collection: EntityCollection<any>;
150
- filterValues: FilterValues<any>;
151
- sortBy?: [string, "asc" | "desc"];
152
- }): boolean;
145
+ * @param props
146
+ */
147
+ isFilterCombinationValid?(props: FilterCombinationValidProps): boolean;
148
+ }
149
+ export type FilterCombinationValidProps = {
150
+ path: string;
151
+ collection: EntityCollection<any>;
152
+ filterValues: FilterValues<any>;
153
+ sortBy?: [string, "asc" | "desc"];
154
+ };
155
+ export type SaveEntityDelegateProps<M extends Record<string, any> = any> = Omit<SaveEntityProps<M>, "collection">;
156
+ export type FetchCollectionDelegateProps<M extends Record<string, any> = any> = Omit<FetchCollectionProps<M>, "collection"> & {
157
+ isCollectionGroup?: boolean;
158
+ };
159
+ export type ListenCollectionDelegateProps<M extends Record<string, any> = any> = Omit<ListenCollectionProps<M>, "collection"> & {
160
+ isCollectionGroup?: boolean;
161
+ };
162
+ export interface DataSourceDelegate {
163
+ /**
164
+ * Fetch data from a collection
165
+ * @param path
166
+ * @param filter
167
+ * @param limit
168
+ * @param startAfter
169
+ * @param orderBy
170
+ * @param order
171
+ * @param searchString
172
+ * @return Function to cancel subscription
173
+ * @see useCollectionFetch if you need this functionality implemented as a hook
174
+ */
175
+ fetchCollection<M extends Record<string, any> = any>({ path, filter, limit, startAfter, orderBy, order, searchString }: FetchCollectionDelegateProps<M>): Promise<Entity<M>[]>;
176
+ /**
177
+ * Listen to a collection in a given path. If you don't implement this method
178
+ * `fetchCollection` will be used instead, with no real time updates.
179
+ * @param path
180
+ * @param onUpdate
181
+ * @param onError
182
+ * @param filter
183
+ * @param limit
184
+ * @param startAfter
185
+ * @param orderBy
186
+ * @param order
187
+ * @param searchString
188
+ * @return Function to cancel subscription
189
+ * @see useCollectionFetch if you need this functionality implemented as a hook
190
+ */
191
+ listenCollection?<M extends Record<string, any> = any>({ path, filter, limit, startAfter, searchString, orderBy, order, onUpdate, onError }: ListenCollectionDelegateProps<M>): () => void;
192
+ /**
193
+ * Retrieve an entity given a path and a collection
194
+ * @param path
195
+ * @param entityId
196
+ */
197
+ fetchEntity<M extends Record<string, any> = any>({ path, entityId, }: Omit<FetchEntityProps<M>, "collection">): Promise<Entity<M> | undefined>;
198
+ /**
199
+ * Get realtime updates on one entity.
200
+ * @param path
201
+ * @param entityId
202
+ * @param collection
203
+ * @param onUpdate
204
+ * @param onError
205
+ * @return Function to cancel subscription
206
+ */
207
+ listenEntity?<M extends Record<string, any> = any>({ path, entityId, onUpdate, onError }: Omit<ListenEntityProps<M>, "collection">): () => void;
208
+ /**
209
+ * Save entity to the specified path
210
+ * @param path
211
+ * @param id
212
+ * @param collection
213
+ * @param status
214
+ */
215
+ saveEntity<M extends Record<string, any> = any>({ path, entityId, values, status }: SaveEntityDelegateProps<M>): Promise<Entity<M>>;
216
+ /**
217
+ * Delete an entity
218
+ * @param entity
219
+ * @return was the whole deletion flow successful
220
+ */
221
+ deleteEntity<M extends Record<string, any> = any>({ entity }: DeleteEntityProps<M>): Promise<void>;
222
+ /**
223
+ * Check if the given property is unique in the given collection
224
+ * @param path Collection path
225
+ * @param name of the property
226
+ * @param value
227
+ * @param entityId
228
+ * @return `true` if there are no other fields besides the given entity
229
+ */
230
+ checkUniqueField(path: string, name: string, value: any, entityId?: string): Promise<boolean>;
231
+ /**
232
+ * Generate an id for a new entity
233
+ */
234
+ generateEntityId(path: string): string;
235
+ /**
236
+ * Count the number of entities in a collection
237
+ */
238
+ countEntities<M extends Record<string, any> = any>(props: FetchCollectionDelegateProps<M>): Promise<number>;
239
+ /**
240
+ * Check if the given filter combination is valid
241
+ * @param props
242
+ */
243
+ isFilterCombinationValid?(props: Omit<FilterCombinationValidProps, "collection">): boolean;
244
+ /**
245
+ * Convert a FireCMS reference to a reference that can be used by the datasource
246
+ * @param reference
247
+ */
248
+ buildReference: (reference: EntityReference) => any;
249
+ /**
250
+ * Convert a FireCMS GeoPoint to a GeoPoint that can be used by the datasource
251
+ * @param geoPoint
252
+ */
253
+ buildGeoPoint: (geoPoint: GeoPoint) => any;
254
+ /**
255
+ * Get the object to generate the current time in the datasource
256
+ */
257
+ currentTime(): any;
258
+ buildDate: (date: Date) => any;
259
+ buildDeleteFieldValue: () => any;
260
+ delegateToCMSModel: (data: any) => any;
261
+ setDateToMidnight: (input?: any) => any;
153
262
  }
@@ -7,7 +7,7 @@ import { ResolvedEntityCollection, ResolvedProperty } from "./resolved_entities"
7
7
  *
8
8
  * @category Form custom fields
9
9
  */
10
- export interface FieldProps<T extends CMSType = CMSType, CustomProps = any, M extends Record<string, any> = any> {
10
+ export interface FieldProps<T extends CMSType = any, CustomProps = any, M extends Record<string, any> = any> {
11
11
  /**
12
12
  * Key of the property
13
13
  * E.g. "user.name" for a property with path "user.name"
@@ -5,7 +5,7 @@ import { DataSource } from "./datasource";
5
5
  import { EntityCollection, EntityCustomView } from "./collections";
6
6
  import { CMSView } from "./navigation";
7
7
  import { FireCMSContext } from "./firecms_context";
8
- import { FieldConfig } from "./field_config";
8
+ import { PropertyConfig } from "./property_config";
9
9
  import { Locale } from "./locales";
10
10
  import { StorageSource } from "./storage";
11
11
  import { EntityLinkBuilder } from "./entity_link_builder";
@@ -77,9 +77,9 @@ export type FireCMSProps<UserType extends User> = {
77
77
  /**
78
78
  * Record of custom form fields to be used in the CMS.
79
79
  * You can use the key to reference the custom field in
80
- * the `fieldConfig` prop of a property in a collection.
80
+ * the `propertyConfig` prop of a property in a collection.
81
81
  */
82
- fields?: Record<string, FieldConfig>;
82
+ fields?: Record<string, PropertyConfig>;
83
83
  /**
84
84
  * List of additional custom views for entities.
85
85
  * You can use the key to reference the custom view in
@@ -11,7 +11,7 @@ import { UserConfigurationPersistence } from "./local_config_persistence";
11
11
  import { SideDialogsController } from "./side_dialogs_controller";
12
12
  import { FireCMSPlugin } from "./plugins";
13
13
  import { CMSAnalyticsEvent } from "./analytics";
14
- import { FieldConfig } from "./field_config";
14
+ import { PropertyConfig } from "./property_config";
15
15
  import { EntityCustomView } from "./collections";
16
16
  /**
17
17
  * Context that includes the internal controllers and contexts used by the app.
@@ -81,9 +81,9 @@ export type FireCMSContext<UserType extends User = User, AuthControllerType exte
81
81
  /**
82
82
  * Record of custom form fields to be used in the CMS.
83
83
  * You can use the key to reference the custom field in
84
- * the `fieldConfig` prop of a property in a collection.
84
+ * the `propertyConfig` prop of a property in a collection.
85
85
  */
86
- fields: Record<string, FieldConfig>;
86
+ fields: Record<string, PropertyConfig>;
87
87
  /**
88
88
  * List of additional custom views for entities.
89
89
  * You can use the key to reference the custom view in
@@ -10,7 +10,7 @@ export * from "./user";
10
10
  export * from "./colors";
11
11
  export * from "./storage";
12
12
  export * from "./fields";
13
- export * from "./field_config";
13
+ export * from "./property_config";
14
14
  export * from "./datasource";
15
15
  export * from "./entity_link_builder";
16
16
  export * from "./side_entity_controller";
@@ -44,7 +44,7 @@ export interface BaseProperty<T extends CMSType, CustomProps = any> {
44
44
  * All the configuration will be taken from the inherited config, and
45
45
  * overwritten by the current property config.
46
46
  */
47
- fieldConfig?: string;
47
+ propertyConfig?: string;
48
48
  /**
49
49
  * Longer description of a field, displayed under a popover
50
50
  */
@@ -1,14 +1,13 @@
1
1
  import React from "react";
2
2
  import { CMSType, PropertyOrBuilder } from "./properties";
3
3
  /**
4
- * This is the configuration object for the field component generated for a
5
- * property.
4
+ * This is the configuration object for a property.
6
5
  * These configs are generated by default for the properties defined in your
7
6
  * collections' configuration, but you can define your own to be used.
8
7
  */
9
- export type FieldConfig<T extends CMSType = any> = {
8
+ export type PropertyConfig<T extends CMSType = any> = {
10
9
  /**
11
- * Key used to identify this field type.
10
+ * Key used to identify this property config.
12
11
  */
13
12
  key: string;
14
13
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
- "version": "3.0.0-alpha.27",
3
+ "version": "3.0.0-alpha.28",
4
4
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
5
5
  "funding": {
6
6
  "url": "https://github.com/sponsors/firecmsco"
@@ -133,7 +133,7 @@
133
133
  "dist",
134
134
  "src"
135
135
  ],
136
- "gitHead": "deb0ef4491986b9a599919a2cd581f40ac6920c1",
136
+ "gitHead": "aba9501b45cf2dc84dc172084510b90e417b42f1",
137
137
  "publishConfig": {
138
138
  "access": "public"
139
139
  }
@@ -22,6 +22,8 @@ export interface PopoverProps {
22
22
  hideWhenDetached?: boolean;
23
23
  avoidCollisions?: boolean;
24
24
  enabled?: boolean;
25
+ modal?: boolean;
26
+ className?: string;
25
27
  }
26
28
 
27
29
  export function Popover({
@@ -37,7 +39,9 @@ export function Popover({
37
39
  sticky,
38
40
  hideWhenDetached,
39
41
  avoidCollisions,
40
- enabled = true
42
+ enabled = true,
43
+ modal = false,
44
+ className
41
45
  }: PopoverProps) {
42
46
 
43
47
  useInjectStyles("Popover", popoverStyles);
@@ -45,12 +49,15 @@ export function Popover({
45
49
  if (!enabled)
46
50
  return <>{trigger}</>;
47
51
 
48
- return <PopoverPrimitive.Root open={open} onOpenChange={onOpenChange}>
52
+ return <PopoverPrimitive.Root open={open}
53
+ onOpenChange={onOpenChange}
54
+ modal={modal}
55
+ >
49
56
  <PopoverPrimitive.Trigger asChild>
50
57
  {trigger}
51
58
  </PopoverPrimitive.Trigger>
52
59
  <PopoverPrimitive.Portal>
53
- <PopoverPrimitive.Content className={cn(paperMixin, "PopoverContent shadow z-50")}
60
+ <PopoverPrimitive.Content className={cn(paperMixin, "PopoverContent shadow z-40", className)}
54
61
  side={side}
55
62
  sideOffset={sideOffset}
56
63
  align={align}
@@ -55,6 +55,7 @@ export const TextareaAutosize = React.forwardRef(function TextareaAutosize(
55
55
  onFocus,
56
56
  onBlur,
57
57
  sizeRef,
58
+ ignoreBoxSizing,
58
59
  ...other
59
60
  } = props;
60
61
 
@@ -124,7 +125,7 @@ export const TextareaAutosize = React.forwardRef(function TextareaAutosize(
124
125
  outerHeight = Math.max(outerHeight, singleRowHeight, minHeight);
125
126
 
126
127
  // Take the box sizing into account for applying this value as a style.
127
- const outerHeightStyle = outerHeight + (!props.ignoreBoxSizing && boxSizing === "border-box" ? padding + border : 0);
128
+ const outerHeightStyle = outerHeight + (!ignoreBoxSizing && boxSizing === "border-box" ? padding + border : 0);
128
129
 
129
130
  const overflow = Math.abs(outerHeight - innerHeight) <= 1;
130
131
 
@@ -8,7 +8,7 @@ import {
8
8
  EntityCollection,
9
9
  EnumValueConfig,
10
10
  EnumValues,
11
- FieldConfig,
11
+ PropertyConfig,
12
12
  GeopointProperty,
13
13
  MapProperty,
14
14
  NumberProperty,
@@ -130,11 +130,11 @@ export function buildAdditionalFieldDelegate<M extends Record<string, any>, Addi
130
130
  /**
131
131
  * Identity function we use to defeat the type system of Typescript and build
132
132
  * additional field delegates views with all its properties
133
- * @param fieldConfig
133
+ * @param propertyConfig
134
134
  * @category Builder
135
135
  */
136
136
  export function buildFieldConfig<T extends CMSType = CMSType>(
137
- fieldConfig: FieldConfig<T>
138
- ): FieldConfig<T> {
139
- return fieldConfig;
137
+ propertyConfig: PropertyConfig<T>
138
+ ): PropertyConfig<T> {
139
+ return propertyConfig;
140
140
  }
@@ -433,8 +433,8 @@ function createFilterField({
433
433
  filterValue,
434
434
  setFilterValue,
435
435
  column,
436
- popupOpen,
437
- setPopupOpen
436
+ hidden,
437
+ setHidden
438
438
  }: FilterFormFieldProps<{
439
439
  resolvedProperty: ResolvedProperty,
440
440
  disabled: boolean,
@@ -459,8 +459,8 @@ function createFilterField({
459
459
  path={baseProperty.path}
460
460
  title={resolvedProperty?.name}
461
461
  previewProperties={baseProperty?.previewProperties}
462
- popupOpen={popupOpen}
463
- setPopupOpen={setPopupOpen}/>;
462
+ hidden={hidden}
463
+ setHidden={setHidden}/>;
464
464
  } else if (baseProperty.dataType === "number" || baseProperty.dataType === "string") {
465
465
  const name = baseProperty.name;
466
466
  const enumValues = baseProperty.enumValues ? enumToObjectEntries(baseProperty.enumValues) : undefined;
@@ -15,8 +15,8 @@ interface ReferenceFilterFieldProps {
15
15
  path?: string;
16
16
  title?: string;
17
17
  previewProperties?: string[];
18
- popupOpen: boolean;
19
- setPopupOpen: (open: boolean) => void;
18
+ hidden: boolean;
19
+ setHidden: (hidden: boolean) => void;
20
20
  }
21
21
 
22
22
  const operationLabels = {
@@ -42,7 +42,7 @@ export function ReferenceFilterField({
42
42
  path,
43
43
  title,
44
44
  previewProperties,
45
- setPopupOpen
45
+ setHidden
46
46
  }: ReferenceFilterFieldProps) {
47
47
 
48
48
  const possibleOperations: (keyof typeof operationLabels) [] = isArray
@@ -118,13 +118,13 @@ export function ReferenceFilterField({
118
118
  onMultipleEntitiesSelected,
119
119
  selectedEntityIds,
120
120
  onClose: () => {
121
- setPopupOpen(true);
121
+ setHidden(false);
122
122
  }
123
123
  }
124
124
  );
125
125
 
126
126
  const doOpenDialog = () => {
127
- setPopupOpen(false);
127
+ setHidden(true);
128
128
  referenceDialogController.open();
129
129
  };
130
130
 
@@ -148,6 +148,10 @@ export function ReferenceFilterField({
148
148
  );
149
149
  };
150
150
 
151
+ console.log("ReferenceFilterField", {
152
+ internalValue
153
+
154
+ })
151
155
  return (
152
156
 
153
157
  <div className="flex w-[440px] flex-row">
@@ -175,7 +179,8 @@ export function ReferenceFilterField({
175
179
  </div>}
176
180
  {(!internalValue || (Array.isArray(internalValue) && internalValue.length === 0)) &&
177
181
  <Button onClick={doOpenDialog}
178
- className="h-full">
182
+ variant={"outlined"}
183
+ className="h-full w-full">
179
184
  {multiple ? "Select references" : "Select reference"}
180
185
  </Button>
181
186
  }
@@ -375,7 +375,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
375
375
  hideOverflow = false;
376
376
  }
377
377
  } else if (arrayProperty.of.dataType === "reference") {
378
- if (typeof arrayProperty.of.key === "string") {
378
+ if (typeof arrayProperty.of.path === "string") {
379
379
  innerComponent =
380
380
  <TableReferenceField
381
381
  name={propertyKey as string}
@@ -384,7 +384,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
384
384
  updateValue={updateValue}
385
385
  size={size}
386
386
  multiselect={true}
387
- path={arrayProperty.of.key}
387
+ path={arrayProperty.of.path}
388
388
  previewProperties={arrayProperty.of.previewProperties}
389
389
  title={arrayProperty.of.name}
390
390
  forceFilter={arrayProperty.of.forceFilter}
@@ -82,13 +82,16 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
82
82
  path,
83
83
  entityId,
84
84
  collection: inputCollection,
85
- onUpdate: setEntity
85
+ onUpdate: (e) => {
86
+ setEntity(e);
87
+ setInternalValue(e?.values);
88
+ }
86
89
  });
87
90
  } else {
88
91
  return () => {
89
92
  };
90
93
  }
91
- }, [dataSource, entityId, inputCollection, path]);
94
+ }, [dataSource, entityId, inputCollection, path, open]);
92
95
 
93
96
  const [internalValue, setInternalValue] = useState<EntityValues<M> | undefined>(entity?.values);
94
97
 
@@ -221,6 +224,7 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
221
224
  className={`text-gray-900 dark:text-white overflow-auto rounded rounded-md bg-white dark:bg-gray-950 ${!open ? "hidden" : ""} cursor-grab max-w-[100vw]`}>
222
225
  <Formik
223
226
  initialValues={(entity?.values ?? {}) as EntityValues<M>}
227
+ enableReinitialize={true}
224
228
  validationSchema={validationSchema}
225
229
  validateOnMount={true}
226
230
  validate={(values) => console.debug("Validating", values)}
@@ -271,7 +271,7 @@ export const EntityCollectionView = React.memo(
271
271
  value,
272
272
  property,
273
273
  entityId
274
- }) => dataSource.checkUniqueField(fullPath, name, value, property, entityId),
274
+ }) => dataSource.checkUniqueField(fullPath, name, value, entityId),
275
275
  [fullPath]);
276
276
 
277
277
  const onValueChange: OnCellValueChange<any, any> = ({
@@ -1,14 +1,14 @@
1
1
  import { getIconForWidget } from "../util";
2
- import { FieldConfig } from "../../types";
2
+ import { PropertyConfig } from "../../types";
3
3
 
4
- export function FieldConfigBadge({ fieldConfig }: { fieldConfig: FieldConfig | undefined }): React.ReactNode {
4
+ export function FieldConfigBadge({ propertyConfig }: { propertyConfig: PropertyConfig | undefined }): React.ReactNode {
5
5
  const classes = "h-8 w-8 p-1 rounded-full shadow text-white";
6
6
 
7
7
  return <div
8
8
  className={classes}
9
9
  style={{
10
- background: fieldConfig?.color ?? "#888"
10
+ background: propertyConfig?.color ?? "#888"
11
11
  }}>
12
- {getIconForWidget(fieldConfig, "medium")}
12
+ {getIconForWidget(propertyConfig, "medium")}
13
13
  </div>
14
14
  }
@@ -1,4 +1,4 @@
1
- import React, { RefObject, useCallback, useEffect, useState } from "react";
1
+ import React, { RefObject, useCallback, useEffect, useRef, useState } from "react";
2
2
  import equal from "react-fast-compare";
3
3
 
4
4
  import { VirtualTableColumn, VirtualTableSort, VirtualTableWhereFilterOp } from "./VirtualTableProps";
@@ -13,8 +13,8 @@ interface FilterFormProps<T> {
13
13
  filter?: [VirtualTableWhereFilterOp, any];
14
14
  onHover: boolean,
15
15
  createFilterField: (props: FilterFormFieldProps<T>) => React.ReactNode;
16
- popupOpen: boolean;
17
- setPopupOpen: (open: boolean) => void;
16
+ hidden: boolean;
17
+ setHidden: (hidden: boolean) => void;
18
18
  }
19
19
 
20
20
  export type FilterFormFieldProps<CustomProps> = {
@@ -22,8 +22,8 @@ export type FilterFormFieldProps<CustomProps> = {
22
22
  filterValue: [VirtualTableWhereFilterOp, any] | undefined,
23
23
  setFilterValue: (filterValue?: [VirtualTableWhereFilterOp, any]) => void;
24
24
  column: VirtualTableColumn<CustomProps>;
25
- popupOpen: boolean;
26
- setPopupOpen: (open: boolean) => void;
25
+ hidden: boolean;
26
+ setHidden: (hidden: boolean) => void;
27
27
  };
28
28
 
29
29
  type VirtualTableHeaderProps<M extends Record<string, any>> = {
@@ -58,6 +58,7 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
58
58
  const [onHover, setOnHover] = useState(false);
59
59
 
60
60
  const [openFilter, setOpenFilter] = React.useState(false);
61
+ const [hidden, setHidden] = React.useState(false);
61
62
 
62
63
  const handleSettingsClick = useCallback((event: any) => {
63
64
  setOpenFilter(true);
@@ -145,6 +146,8 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
145
146
  <Popover
146
147
  open={openFilter}
147
148
  onOpenChange={setOpenFilter}
149
+ className={hidden ? "hidden" : undefined}
150
+ modal={true}
148
151
  trigger={
149
152
  <IconButton
150
153
  className={onHover || openFilter ? "bg-white dark:bg-gray-950" : undefined}
@@ -153,17 +156,18 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
153
156
  <FilterListIcon size={"small"}/>
154
157
  </IconButton>}
155
158
  >
156
- {column.filter &&
157
- <FilterForm column={column}
158
- filter={filter}
159
- onHover={onHover}
160
- onFilterUpdate={update}
161
- createFilterField={createFilterField}
162
- popupOpen={openFilter}
163
- setPopupOpen={setOpenFilter}/>}
159
+ <FilterForm column={column}
160
+ filter={filter}
161
+ onHover={onHover}
162
+ onFilterUpdate={update}
163
+ createFilterField={createFilterField}
164
+ hidden={hidden}
165
+ setHidden={setHidden}/>
166
+
164
167
  </Popover>
165
168
 
166
169
  </Badge>
170
+
167
171
  </div>}
168
172
 
169
173
  {column.resizable && <div
@@ -176,7 +180,6 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
176
180
  />}
177
181
  </div>
178
182
 
179
-
180
183
  </ErrorBoundary>
181
184
  );
182
185
  }, equal) as React.FunctionComponent<VirtualTableHeaderProps<any>>;
@@ -187,8 +190,8 @@ function FilterForm<M>({
187
190
  filter,
188
191
  onHover,
189
192
  createFilterField,
190
- popupOpen,
191
- setPopupOpen,
193
+ hidden,
194
+ setHidden,
192
195
  }: FilterFormProps<M>) {
193
196
 
194
197
  const id = column.key;
@@ -216,8 +219,8 @@ function FilterForm<M>({
216
219
  filterValue: filterInternal,
217
220
  setFilterValue: setFilterInternal,
218
221
  column,
219
- popupOpen,
220
- setPopupOpen
222
+ hidden,
223
+ setHidden
221
224
  });
222
225
 
223
226
  if (!filterField) return null;
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { ArrayProperty, FieldConfig, FieldProps, Property, ResolvedProperty } from "../types";
3
+ import { ArrayProperty, PropertyConfig, FieldProps, Property, ResolvedProperty } from "../types";
4
4
  import {
5
5
  ArrayCustomShapedFieldBinding,
6
6
  ArrayOfReferencesFieldBinding,
@@ -44,7 +44,7 @@ export function isDefaultFieldConfigId(id: string) {
44
44
  return Object.keys(DEFAULT_FIELD_CONFIGS).includes(id);
45
45
  }
46
46
 
47
- export const DEFAULT_FIELD_CONFIGS: Record<string, FieldConfig<any>> = {
47
+ export const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {
48
48
  text_field: {
49
49
  key: "text_field",
50
50
  name: "Text field",
@@ -313,7 +313,7 @@ export const DEFAULT_FIELD_CONFIGS: Record<string, FieldConfig<any>> = {
313
313
  }
314
314
  };
315
315
 
316
- export function getFieldConfig(property: Property | ResolvedProperty, customFields: Record<string, FieldConfig<any>>): FieldConfig | undefined {
316
+ export function getFieldConfig(property: Property | ResolvedProperty, customFields: Record<string, PropertyConfig<any>>): PropertyConfig | undefined {
317
317
  const fieldId = getFieldId(property);
318
318
  const defaultFieldId = getDefaultFieldId(property);
319
319
  // console.log("fieldId", { fieldId });
@@ -386,7 +386,7 @@ export function getDefaultFieldId(property: Property | ResolvedProperty) {
386
386
  }
387
387
 
388
388
  export function getFieldId(property: Property | ResolvedProperty): string | undefined {
389
- if (property.fieldConfig)
390
- return property.fieldConfig;
389
+ if (property.propertyConfig)
390
+ return property.propertyConfig;
391
391
  return getDefaultFieldId(property);
392
392
  }