@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.
- package/dist/components/Popover.d.ts +3 -1
- package/dist/core/builders.d.ts +3 -3
- package/dist/core/components/EntityCollectionTable/filters/ReferenceFilterField.d.ts +3 -3
- package/dist/core/components/FieldConfigBadge.d.ts +3 -3
- package/dist/core/components/VirtualTable/VirtualTableHeader.d.ts +2 -2
- package/dist/core/form_field_configs.d.ts +3 -3
- package/dist/core/util/property_utils.d.ts +5 -5
- package/dist/core/util/references.d.ts +2 -2
- package/dist/core/util/resolutions.d.ts +5 -5
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useBuildDataSource.d.ts +23 -0
- package/dist/index.es.js +6877 -6634
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +14 -14
- package/dist/index.umd.js.map +1 -1
- package/dist/types/datasource.d.ts +120 -11
- package/dist/types/fields.d.ts +1 -1
- package/dist/types/firecms.d.ts +3 -3
- package/dist/types/firecms_context.d.ts +3 -3
- package/dist/types/index.d.ts +1 -1
- package/dist/types/properties.d.ts +1 -1
- package/dist/types/{field_config.d.ts → property_config.d.ts} +3 -4
- package/package.json +2 -2
- package/src/components/Popover.tsx +10 -3
- package/src/components/TextareaAutosize.tsx +2 -1
- package/src/core/builders.ts +5 -5
- package/src/core/components/EntityCollectionTable/EntityCollectionTable.tsx +4 -4
- package/src/core/components/EntityCollectionTable/filters/ReferenceFilterField.tsx +11 -6
- package/src/core/components/EntityCollectionTable/internal/PropertyTableCell.tsx +2 -2
- package/src/core/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +6 -2
- package/src/core/components/EntityCollectionView/EntityCollectionView.tsx +1 -1
- package/src/core/components/FieldConfigBadge.tsx +4 -4
- package/src/core/components/VirtualTable/VirtualTableHeader.tsx +21 -18
- package/src/core/form_field_configs.tsx +5 -5
- package/src/core/util/property_utils.tsx +5 -5
- package/src/core/util/references.ts +2 -2
- package/src/core/util/resolutions.ts +16 -11
- package/src/form/EntityForm.tsx +1 -1
- package/src/form/PropertyFieldBinding.tsx +4 -4
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +4 -6
- package/src/hooks/index.tsx +1 -0
- package/src/hooks/useBuildDataSource.ts +351 -0
- package/src/preview/property_previews/StringPropertyPreview.tsx +4 -2
- package/src/types/datasource.ts +174 -10
- package/src/types/fields.tsx +1 -1
- package/src/types/firecms.tsx +3 -3
- package/src/types/firecms_context.tsx +3 -3
- package/src/types/index.ts +1 -1
- package/src/types/properties.ts +1 -1
- 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
|
|
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,
|
|
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
|
|
146
|
-
*/
|
|
147
|
-
isFilterCombinationValid?(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
}
|
package/dist/types/fields.d.ts
CHANGED
|
@@ -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 =
|
|
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"
|
package/dist/types/firecms.d.ts
CHANGED
|
@@ -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 {
|
|
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 `
|
|
80
|
+
* the `propertyConfig` prop of a property in a collection.
|
|
81
81
|
*/
|
|
82
|
-
fields?: Record<string,
|
|
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 {
|
|
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 `
|
|
84
|
+
* the `propertyConfig` prop of a property in a collection.
|
|
85
85
|
*/
|
|
86
|
-
fields: Record<string,
|
|
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
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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 "./
|
|
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
|
-
|
|
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
|
|
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
|
|
8
|
+
export type PropertyConfig<T extends CMSType = any> = {
|
|
10
9
|
/**
|
|
11
|
-
* Key used to identify this
|
|
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.
|
|
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": "
|
|
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}
|
|
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-
|
|
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 + (!
|
|
128
|
+
const outerHeightStyle = outerHeight + (!ignoreBoxSizing && boxSizing === "border-box" ? padding + border : 0);
|
|
128
129
|
|
|
129
130
|
const overflow = Math.abs(outerHeight - innerHeight) <= 1;
|
|
130
131
|
|
package/src/core/builders.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
EntityCollection,
|
|
9
9
|
EnumValueConfig,
|
|
10
10
|
EnumValues,
|
|
11
|
-
|
|
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
|
|
133
|
+
* @param propertyConfig
|
|
134
134
|
* @category Builder
|
|
135
135
|
*/
|
|
136
136
|
export function buildFieldConfig<T extends CMSType = CMSType>(
|
|
137
|
-
|
|
138
|
-
):
|
|
139
|
-
return
|
|
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
|
-
|
|
437
|
-
|
|
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
|
-
|
|
463
|
-
|
|
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
|
-
|
|
19
|
-
|
|
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
|
-
|
|
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
|
-
|
|
121
|
+
setHidden(false);
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
);
|
|
125
125
|
|
|
126
126
|
const doOpenDialog = () => {
|
|
127
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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:
|
|
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,
|
|
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 {
|
|
2
|
+
import { PropertyConfig } from "../../types";
|
|
3
3
|
|
|
4
|
-
export function FieldConfigBadge({
|
|
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:
|
|
10
|
+
background: propertyConfig?.color ?? "#888"
|
|
11
11
|
}}>
|
|
12
|
-
{getIconForWidget(
|
|
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
|
-
|
|
17
|
-
|
|
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
|
-
|
|
26
|
-
|
|
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
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
191
|
-
|
|
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
|
-
|
|
220
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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.
|
|
390
|
-
return property.
|
|
389
|
+
if (property.propertyConfig)
|
|
390
|
+
return property.propertyConfig;
|
|
391
391
|
return getDefaultFieldId(property);
|
|
392
392
|
}
|