@firecms/core 3.0.0-alpha.27 → 3.0.0-alpha.29
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/FireCMS.d.ts +2 -2
- package/dist/core/builders.d.ts +5 -5
- package/dist/core/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +4 -2
- package/dist/core/components/EntityCollectionTable/filters/ReferenceFilterField.d.ts +3 -3
- package/dist/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.d.ts +15 -11
- package/dist/core/components/EntityCollectionTable/internal/default_entity_actions.d.ts +5 -0
- package/dist/core/components/EntityCollectionTable/types.d.ts +1 -37
- package/dist/core/components/FieldConfigBadge.d.ts +3 -3
- package/dist/core/components/VirtualTable/VirtualTableHeader.d.ts +2 -2
- package/dist/core/components/VirtualTable/VirtualTableProps.d.ts +1 -1
- package/dist/core/contexts/DialogsProvider.d.ts +4 -0
- package/dist/core/form_field_configs.d.ts +3 -3
- package/dist/core/index.d.ts +1 -1
- package/dist/core/internal/useBuildNavigationContext.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 +6 -6
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useBuildDataSource.d.ts +23 -0
- package/dist/hooks/useDialogsController.d.ts +11 -0
- package/dist/index.es.js +8996 -8583
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +67 -67
- package/dist/index.umd.js.map +1 -1
- package/dist/styles.d.ts +1 -1
- package/dist/types/collections.d.ts +36 -13
- package/dist/types/datasource.d.ts +120 -11
- package/dist/types/dialogs_controller.d.ts +30 -0
- package/dist/types/entity_actions.d.ts +33 -0
- package/dist/types/fields.d.ts +1 -1
- package/dist/types/firecms.d.ts +8 -8
- package/dist/types/firecms_context.d.ts +10 -3
- package/dist/types/index.d.ts +2 -1
- package/dist/types/navigation.d.ts +3 -3
- package/dist/types/plugins.d.ts +11 -10
- package/dist/types/properties.d.ts +1 -1
- package/dist/types/{field_config.d.ts → property_config.d.ts} +3 -4
- package/package.json +3 -3
- package/src/components/Popover.tsx +10 -3
- package/src/components/Sheet.tsx +1 -0
- package/src/components/TextareaAutosize.tsx +2 -1
- package/src/core/FireCMS.tsx +9 -6
- package/src/core/builders.ts +11 -11
- package/src/core/components/ArrayContainer.tsx +1 -1
- package/src/core/components/EntityCollectionTable/EntityCollectionTable.tsx +20 -13
- package/src/core/components/EntityCollectionTable/EntityCollectionTableProps.tsx +5 -2
- package/src/core/components/EntityCollectionTable/filters/ReferenceFilterField.tsx +11 -6
- package/src/core/components/EntityCollectionTable/internal/EntityCollectionRowActions.tsx +96 -79
- package/src/core/components/EntityCollectionTable/internal/PropertyTableCell.tsx +2 -2
- package/src/core/components/EntityCollectionTable/internal/default_entity_actions.tsx +107 -0
- package/src/core/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +6 -2
- package/src/core/components/EntityCollectionTable/types.tsx +1 -56
- package/src/core/components/EntityCollectionView/EntityCollectionView.tsx +67 -43
- package/src/core/components/FieldConfigBadge.tsx +4 -4
- package/src/core/components/ReferenceSelectionInner.tsx +2 -2
- package/src/core/components/VirtualTable/VirtualTable.tsx +4 -6
- package/src/core/components/VirtualTable/VirtualTableHeader.tsx +21 -18
- package/src/core/components/VirtualTable/VirtualTableProps.tsx +1 -1
- package/src/core/contexts/DialogsProvider.tsx +50 -0
- package/src/core/form_field_configs.tsx +5 -5
- package/src/core/index.tsx +1 -1
- package/src/core/internal/useBuildNavigationContext.tsx +13 -13
- package/src/core/internal/useBuildSideEntityController.tsx +9 -1
- 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 +64 -7
- 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/hooks/useDialogsController.tsx +14 -0
- package/src/hooks/useFireCMSContext.tsx +5 -11
- package/src/preview/property_previews/StringPropertyPreview.tsx +4 -2
- package/src/styles.ts +1 -1
- package/src/types/collections.ts +36 -17
- package/src/types/datasource.ts +174 -10
- package/src/types/dialogs_controller.tsx +31 -0
- package/src/types/entity_actions.tsx +36 -0
- package/src/types/fields.tsx +1 -1
- package/src/types/firecms.tsx +8 -8
- package/src/types/firecms_context.tsx +11 -3
- package/src/types/index.ts +2 -1
- package/src/types/navigation.ts +3 -3
- package/src/types/plugins.tsx +11 -10
- package/src/types/properties.ts +1 -1
- package/src/types/{field_config.tsx → property_config.tsx} +3 -4
- /package/dist/core/contexts/{SnackbarContext.d.ts → SnackbarProvider.d.ts} +0 -0
- /package/src/core/contexts/{SnackbarContext.tsx → SnackbarProvider.tsx} +0 -0
package/src/core/index.tsx
CHANGED
|
@@ -20,7 +20,7 @@ export * from "./useBuildModeController";
|
|
|
20
20
|
export * from "../components/util/useOutsideAlerter";
|
|
21
21
|
export * from "./useBuildLocalConfigurationPersistence";
|
|
22
22
|
|
|
23
|
-
export { SnackbarProvider } from "./contexts/
|
|
23
|
+
export { SnackbarProvider } from "./contexts/SnackbarProvider";
|
|
24
24
|
export { ModeControllerProvider } from "./contexts/ModeController";
|
|
25
25
|
|
|
26
26
|
export * from "./contexts/AuthControllerContext";
|
|
@@ -25,27 +25,27 @@ import {
|
|
|
25
25
|
} from "../util";
|
|
26
26
|
import { getParentReferencesFromPath } from "../util/parent_references_from_path";
|
|
27
27
|
|
|
28
|
-
type BuildNavigationContextProps<UserType extends User> = {
|
|
28
|
+
type BuildNavigationContextProps<EC extends EntityCollection, UserType extends User> = {
|
|
29
29
|
basePath: string,
|
|
30
30
|
baseCollectionPath: string,
|
|
31
31
|
authController: AuthController<UserType>;
|
|
32
|
-
collections?:
|
|
32
|
+
collections?: EC[] | EntityCollectionsBuilder<EC>;
|
|
33
33
|
views?: CMSView[] | CMSViewsBuilder;
|
|
34
34
|
userConfigPersistence?: UserConfigurationPersistence;
|
|
35
35
|
plugins?: FireCMSPlugin[];
|
|
36
36
|
dataSource: DataSource;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
export function useBuildNavigationContext<UserType extends User>({
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
export function useBuildNavigationContext<EC extends EntityCollection, UserType extends User>({
|
|
40
|
+
basePath,
|
|
41
|
+
baseCollectionPath,
|
|
42
|
+
authController,
|
|
43
|
+
collections: baseCollections,
|
|
44
|
+
views: baseViews,
|
|
45
|
+
userConfigPersistence,
|
|
46
|
+
plugins,
|
|
47
|
+
dataSource
|
|
48
|
+
}: BuildNavigationContextProps<EC, UserType>): NavigationContext {
|
|
49
49
|
|
|
50
50
|
const location = useLocation();
|
|
51
51
|
|
|
@@ -288,7 +288,7 @@ function filterOutNotAllowedCollections(resolvedCollections: EntityCollection[],
|
|
|
288
288
|
});
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
async function resolveCollections(collections: undefined | EntityCollection[] | EntityCollectionsBuilder
|
|
291
|
+
async function resolveCollections(collections: undefined | EntityCollection[] | EntityCollectionsBuilder<any>, authController: AuthController, dataSource: DataSource, plugins?: FireCMSPlugin[]) {
|
|
292
292
|
let resolvedCollections: EntityCollection[] = [];
|
|
293
293
|
if (typeof collections === "function") {
|
|
294
294
|
resolvedCollections = await collections({
|
|
@@ -38,7 +38,15 @@ export const useBuildSideEntityController = (navigation: NavigationContext,
|
|
|
38
38
|
const newFlag = location.hash === `#${NEW_URL_HASH}`;
|
|
39
39
|
const entityOrCollectionPath = navigation.urlPathToDataPath(location.pathname);
|
|
40
40
|
const panelsFromUrl = buildSidePanelsFromUrl(entityOrCollectionPath, navigation.collections, newFlag);
|
|
41
|
-
|
|
41
|
+
for (let i = 0; i < panelsFromUrl.length; i++) {
|
|
42
|
+
const panel = panelsFromUrl[i];
|
|
43
|
+
setTimeout(() => {
|
|
44
|
+
if (i === 0)
|
|
45
|
+
sideDialogsController.replace(propsToSidePanel(panel, navigation, smallLayout));
|
|
46
|
+
else
|
|
47
|
+
sideDialogsController.open(propsToSidePanel(panel, navigation, smallLayout))
|
|
48
|
+
}, 1);
|
|
49
|
+
}
|
|
42
50
|
}
|
|
43
51
|
initialised.current = true;
|
|
44
52
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import { EntityCollection,
|
|
3
|
+
import { EntityCollection, PropertyConfig, PropertiesOrBuilders, PropertyOrBuilder, ResolvedProperty } from "../../types";
|
|
4
4
|
import { getFieldConfig } from "../form_field_configs";
|
|
5
5
|
import { isPropertyBuilder } from "./entities";
|
|
6
6
|
import { resolveProperty } from "./resolutions";
|
|
7
7
|
import { CircleIcon, FunctionsIcon } from "../../icons";
|
|
8
8
|
|
|
9
9
|
export function isReferenceProperty(propertyOrBuilder: PropertyOrBuilder,
|
|
10
|
-
fields: Record<string,
|
|
10
|
+
fields: Record<string, PropertyConfig>) {
|
|
11
11
|
const resolvedProperty = resolveProperty({
|
|
12
12
|
propertyKey: "ignore", // TODO
|
|
13
13
|
propertyOrBuilder,
|
|
@@ -28,7 +28,7 @@ export function getIdIcon(size: "small" | "medium" | "large"): React.ReactNode {
|
|
|
28
28
|
return <CircleIcon size={size}/>;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export function getIconForWidget(widget:
|
|
31
|
+
export function getIconForWidget(widget: PropertyConfig | undefined,
|
|
32
32
|
size: "small" | "medium" | "large") {
|
|
33
33
|
const Icon = widget?.Icon ?? CircleIcon;
|
|
34
34
|
return <Icon size={size}/>;
|
|
@@ -37,7 +37,7 @@ export function getIconForWidget(widget: FieldConfig | undefined,
|
|
|
37
37
|
export function getIconForProperty(
|
|
38
38
|
property: PropertyOrBuilder | ResolvedProperty,
|
|
39
39
|
size: "small" | "medium" | "large" = "small",
|
|
40
|
-
fields: Record<string,
|
|
40
|
+
fields: Record<string, PropertyConfig> = {}
|
|
41
41
|
): React.ReactNode {
|
|
42
42
|
|
|
43
43
|
if (isPropertyBuilder(property)) {
|
|
@@ -48,7 +48,7 @@ export function getIconForProperty(
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
export function getColorForProperty(property: PropertyOrBuilder, fields: Record<string,
|
|
51
|
+
export function getColorForProperty(property: PropertyOrBuilder, fields: Record<string, PropertyConfig>): string {
|
|
52
52
|
if (isPropertyBuilder(property)) {
|
|
53
53
|
return "#888";
|
|
54
54
|
} else {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { EntityCollection,
|
|
1
|
+
import { EntityCollection, PropertyConfig } from "../../types";
|
|
2
2
|
import { isReferenceProperty } from "./property_utils";
|
|
3
3
|
import { isPropertyBuilder } from "./entities";
|
|
4
4
|
|
|
5
5
|
export function getReferencePreviewKeys(targetCollection: EntityCollection<any>,
|
|
6
|
-
fields: Record<string,
|
|
6
|
+
fields: Record<string, PropertyConfig>,
|
|
7
7
|
previewProperties?: string[],
|
|
8
8
|
limit = 3) {
|
|
9
9
|
const allProperties = Object.keys(targetCollection.properties);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ArrayProperty,
|
|
3
3
|
CMSType,
|
|
4
|
-
EntityCollection,
|
|
4
|
+
EntityCollection,
|
|
5
|
+
EntityCustomView,
|
|
5
6
|
EntityValues,
|
|
6
7
|
EnumValueConfig,
|
|
7
8
|
EnumValues,
|
|
8
|
-
|
|
9
|
+
PropertyConfig,
|
|
9
10
|
NumberProperty,
|
|
10
11
|
Properties,
|
|
11
12
|
PropertiesOrBuilders,
|
|
@@ -43,7 +44,7 @@ export const resolveCollection = <M extends Record<string, any>, >
|
|
|
43
44
|
values?: Partial<EntityValues<M>>,
|
|
44
45
|
previousValues?: Partial<EntityValues<M>>,
|
|
45
46
|
userConfigPersistence?: UserConfigurationPersistence;
|
|
46
|
-
fields?: Record<string,
|
|
47
|
+
fields?: Record<string, PropertyConfig>;
|
|
47
48
|
}): ResolvedEntityCollection<M> => {
|
|
48
49
|
|
|
49
50
|
const collectionOverride = userConfigPersistence?.getCollectionConfig<M>(path);
|
|
@@ -107,7 +108,7 @@ export function resolveProperty<T extends CMSType = CMSType, M extends Record<st
|
|
|
107
108
|
entityId?: string,
|
|
108
109
|
index?: number,
|
|
109
110
|
fromBuilder?: boolean;
|
|
110
|
-
fields?: Record<string,
|
|
111
|
+
fields?: Record<string, PropertyConfig<any>>;
|
|
111
112
|
}): ResolvedProperty<T> | null {
|
|
112
113
|
|
|
113
114
|
if (typeof propertyOrBuilder === "object" && "resolved" in propertyOrBuilder) {
|
|
@@ -176,17 +177,21 @@ export function resolveProperty<T extends CMSType = CMSType, M extends Record<st
|
|
|
176
177
|
} as ResolvedProperty<T>;
|
|
177
178
|
}
|
|
178
179
|
|
|
179
|
-
if (resolvedProperty.
|
|
180
|
+
if (resolvedProperty.propertyConfig && !isDefaultFieldConfigId(resolvedProperty.propertyConfig)) {
|
|
180
181
|
const cmsFields = props.fields;
|
|
181
182
|
if (!cmsFields) {
|
|
182
|
-
throw Error(`Trying to resolve a property with key ${resolvedProperty.
|
|
183
|
+
throw Error(`Trying to resolve a property with key ${resolvedProperty.propertyConfig} that inherits from a custom field but no custom fields were provided. Use the property 'fields' in your top level component to provide them`);
|
|
183
184
|
}
|
|
184
|
-
const customField:
|
|
185
|
+
const customField: PropertyConfig<any> = cmsFields[resolvedProperty.propertyConfig];
|
|
185
186
|
if (!customField)
|
|
186
|
-
throw Error(`Trying to resolve a property that inherits from a custom field but no custom field with id ${resolvedProperty.
|
|
187
|
+
throw Error(`Trying to resolve a property that inherits from a custom field but no custom field with id ${resolvedProperty.propertyConfig} was found. Check the \`fields\` in your top level component`);
|
|
187
188
|
if (customField.property) {
|
|
189
|
+
const configPropertyOrBuilder = customField.property;
|
|
190
|
+
if ("propertyConfig" in configPropertyOrBuilder) {
|
|
191
|
+
delete configPropertyOrBuilder.propertyConfig;
|
|
192
|
+
}
|
|
188
193
|
const customFieldProperty = resolveProperty<any>({
|
|
189
|
-
propertyOrBuilder:
|
|
194
|
+
propertyOrBuilder: configPropertyOrBuilder,
|
|
190
195
|
propertyValue,
|
|
191
196
|
...props
|
|
192
197
|
});
|
|
@@ -220,7 +225,7 @@ export function resolveArrayProperty<T extends any[], M>({
|
|
|
220
225
|
entityId?: string,
|
|
221
226
|
index?: number,
|
|
222
227
|
fromBuilder?: boolean;
|
|
223
|
-
fields?: Record<string,
|
|
228
|
+
fields?: Record<string, PropertyConfig>;
|
|
224
229
|
}): ResolvedArrayProperty {
|
|
225
230
|
|
|
226
231
|
if (property.of) {
|
|
@@ -326,7 +331,7 @@ export function resolveProperties<M extends Record<string, any>>({
|
|
|
326
331
|
entityId?: string,
|
|
327
332
|
index?: number,
|
|
328
333
|
fromBuilder?: boolean;
|
|
329
|
-
fields?: Record<string,
|
|
334
|
+
fields?: Record<string, PropertyConfig>;
|
|
330
335
|
}): ResolvedProperties<M> {
|
|
331
336
|
return Object.entries<PropertyOrBuilder>(properties as Record<string, PropertyOrBuilder>)
|
|
332
337
|
.map(([key, property]) => {
|
package/src/form/EntityForm.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import React, { MutableRefObject, useCallback, useEffect, useMemo, useRef, useSt
|
|
|
3
3
|
import {
|
|
4
4
|
CMSAnalyticsEvent,
|
|
5
5
|
Entity,
|
|
6
|
+
EntityAction,
|
|
6
7
|
EntityCollection,
|
|
7
8
|
EntityStatus,
|
|
8
9
|
EntityValues,
|
|
@@ -15,13 +16,26 @@ import { Form, Formik, FormikHelpers, FormikProps } from "formik";
|
|
|
15
16
|
import { PropertyFieldBinding } from "./PropertyFieldBinding";
|
|
16
17
|
import { CustomFieldValidator, getYupEntitySchema } from "./validation";
|
|
17
18
|
import equal from "react-fast-compare"
|
|
18
|
-
import {
|
|
19
|
-
|
|
19
|
+
import {
|
|
20
|
+
canCreateEntity,
|
|
21
|
+
canDeleteEntity,
|
|
22
|
+
ErrorBoundary,
|
|
23
|
+
fullPathToCollectionSegments,
|
|
24
|
+
getDefaultValuesFor,
|
|
25
|
+
isHidden,
|
|
26
|
+
isReadOnly,
|
|
27
|
+
resolveCollection
|
|
28
|
+
} from "../core";
|
|
29
|
+
import { useAuthController, useDataSource, useFireCMSContext, useSideEntityController } from "../hooks";
|
|
20
30
|
import { ErrorFocus } from "./components/ErrorFocus";
|
|
21
31
|
import { CustomIdField } from "./components/CustomIdField";
|
|
22
|
-
import { DialogActions, Typography } from "../components";
|
|
32
|
+
import { DialogActions, IconButton, Typography } from "../components";
|
|
23
33
|
import { Button } from "../components/Button";
|
|
24
34
|
import { cn } from "../components/util/cn";
|
|
35
|
+
import {
|
|
36
|
+
copyEntityAction,
|
|
37
|
+
deleteEntityAction
|
|
38
|
+
} from "../core/components/EntityCollectionTable/internal/default_entity_actions";
|
|
25
39
|
|
|
26
40
|
/**
|
|
27
41
|
* @category Components
|
|
@@ -315,7 +329,7 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
315
329
|
name,
|
|
316
330
|
value,
|
|
317
331
|
property
|
|
318
|
-
}) => dataSource.checkUniqueField(path, name, value,
|
|
332
|
+
}) => dataSource.checkUniqueField(path, name, value, entityId),
|
|
319
333
|
[dataSource, path, entityId]);
|
|
320
334
|
|
|
321
335
|
const validationSchema = useMemo(() => entityId
|
|
@@ -326,6 +340,21 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
326
340
|
: undefined,
|
|
327
341
|
[entityId, collection.properties, uniqueFieldValidator]);
|
|
328
342
|
|
|
343
|
+
const authController = useAuthController();
|
|
344
|
+
|
|
345
|
+
const getActionsForEntity = useCallback(({ entity, customEntityActions }: { entity?: Entity<M>, customEntityActions?: EntityAction[] }): EntityAction[] => {
|
|
346
|
+
const createEnabled = canCreateEntity(collection, authController, fullPathToCollectionSegments(path), null);
|
|
347
|
+
const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPathToCollectionSegments(path), entity) : true;
|
|
348
|
+
const actions: EntityAction[] = [];
|
|
349
|
+
if (createEnabled)
|
|
350
|
+
actions.push(copyEntityAction);
|
|
351
|
+
if (deleteEnabled)
|
|
352
|
+
actions.push(deleteEntityAction);
|
|
353
|
+
if (customEntityActions)
|
|
354
|
+
actions.push(...customEntityActions);
|
|
355
|
+
return actions;
|
|
356
|
+
}, [authController, collection, path]);
|
|
357
|
+
|
|
329
358
|
return (
|
|
330
359
|
<Formik
|
|
331
360
|
initialValues={baseDataSourceValues as M}
|
|
@@ -417,7 +446,8 @@ function EntityFormInternal<M extends Record<string, any>>({
|
|
|
417
446
|
status={status}
|
|
418
447
|
savingError={savingError}
|
|
419
448
|
closeAfterSaveRef={closeAfterSaveRef}
|
|
420
|
-
autoSave={autoSave}
|
|
449
|
+
autoSave={autoSave}
|
|
450
|
+
entityActions={getActionsForEntity({ entity, customEntityActions: collection.entityActions })}/>}
|
|
421
451
|
|
|
422
452
|
</div>
|
|
423
453
|
</div>
|
|
@@ -436,7 +466,8 @@ function InnerForm<M extends Record<string, any>>(props: FormikProps<M> & {
|
|
|
436
466
|
status: "new" | "existing" | "copy",
|
|
437
467
|
savingError?: Error,
|
|
438
468
|
closeAfterSaveRef: MutableRefObject<boolean>,
|
|
439
|
-
autoSave?: boolean
|
|
469
|
+
autoSave?: boolean,
|
|
470
|
+
entityActions: EntityAction[]
|
|
440
471
|
}) {
|
|
441
472
|
|
|
442
473
|
const {
|
|
@@ -455,9 +486,14 @@ function InnerForm<M extends Record<string, any>>(props: FormikProps<M> & {
|
|
|
455
486
|
savingError,
|
|
456
487
|
dirty,
|
|
457
488
|
closeAfterSaveRef,
|
|
458
|
-
autoSave
|
|
489
|
+
autoSave,
|
|
490
|
+
entityActions
|
|
459
491
|
} = props;
|
|
460
492
|
|
|
493
|
+
const context = useFireCMSContext();
|
|
494
|
+
const formActions = entityActions.filter(a => a.includeInForm === undefined || a.includeInForm);
|
|
495
|
+
const sideEntityController = useSideEntityController();
|
|
496
|
+
|
|
461
497
|
const modified = dirty;
|
|
462
498
|
useEffect(() => {
|
|
463
499
|
if (onModified)
|
|
@@ -553,6 +589,27 @@ function InnerForm<M extends Record<string, any>>(props: FormikProps<M> & {
|
|
|
553
589
|
</Typography>
|
|
554
590
|
</div>}
|
|
555
591
|
|
|
592
|
+
{entity && formActions.length > 0 && <div className="flex-grow flex overflow-auto no-scrollbar">
|
|
593
|
+
{formActions.map(action => (
|
|
594
|
+
<IconButton
|
|
595
|
+
key={action.name}
|
|
596
|
+
color="primary"
|
|
597
|
+
onClick={(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
|
598
|
+
event.stopPropagation();
|
|
599
|
+
if (entity)
|
|
600
|
+
action.onClick({
|
|
601
|
+
entity,
|
|
602
|
+
fullPath: resolvedCollection.path,
|
|
603
|
+
collection: resolvedCollection,
|
|
604
|
+
context,
|
|
605
|
+
sideEntityController
|
|
606
|
+
});
|
|
607
|
+
}}>
|
|
608
|
+
{action.icon}
|
|
609
|
+
</IconButton>
|
|
610
|
+
))}
|
|
611
|
+
</div>}
|
|
612
|
+
|
|
556
613
|
<Button
|
|
557
614
|
variant="text"
|
|
558
615
|
disabled={disabled}
|
|
@@ -121,13 +121,13 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, CustomProps =
|
|
|
121
121
|
Component = resolvedProperty.Field as ComponentType<FieldProps<any>>;
|
|
122
122
|
}
|
|
123
123
|
} else {
|
|
124
|
-
const
|
|
125
|
-
if (!
|
|
126
|
-
console.log("INTERNAL: Could not find field config for property", { propertyKey, resolvedProperty, fields: fireCMSContext.fields,
|
|
124
|
+
const propertyConfig = getFieldConfig(resolvedProperty, fireCMSContext.fields);
|
|
125
|
+
if (!propertyConfig) {
|
|
126
|
+
console.log("INTERNAL: Could not find field config for property", { propertyKey, resolvedProperty, fields: fireCMSContext.fields, propertyConfig });
|
|
127
127
|
throw new Error(`INTERNAL: Could not find field config for property ${propertyKey}`);
|
|
128
128
|
}
|
|
129
129
|
const configProperty = resolveProperty({
|
|
130
|
-
propertyOrBuilder:
|
|
130
|
+
propertyOrBuilder: propertyConfig.property,
|
|
131
131
|
propertyValue: fieldProps.field.value,
|
|
132
132
|
values: fieldProps.form.values,
|
|
133
133
|
path: context.path,
|
|
@@ -164,7 +164,7 @@ function MapEditView<T extends Record<string, any>>({
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
const newValue = { ...(value ?? {}) } as T;
|
|
167
|
-
if (originalValue.current && fieldKey in originalValue.current) {
|
|
167
|
+
if (typeof originalValue.current === "object" && fieldKey in originalValue.current) {
|
|
168
168
|
// @ts-ignore
|
|
169
169
|
newValue[fieldKey] = undefined; // set to undefined to remove from the object, the datasource will remove it from the backend
|
|
170
170
|
} else {
|
|
@@ -3,12 +3,10 @@ import React from "react";
|
|
|
3
3
|
import { Entity, FieldProps } from "../../types";
|
|
4
4
|
|
|
5
5
|
import { PropertyPreview } from "../../preview";
|
|
6
|
-
import { LabelWithIcon } from "../components";
|
|
7
|
-
import { ErrorBoundary } from "../../core
|
|
8
|
-
import { getIconForProperty } from "../../core";
|
|
6
|
+
import { FieldHelperText, LabelWithIcon } from "../components";
|
|
7
|
+
import { ErrorBoundary, getIconForProperty } from "../../core";
|
|
9
8
|
import { paperMixin } from "../../styles";
|
|
10
|
-
import {
|
|
11
|
-
import { cn } from "../../components/util/cn";
|
|
9
|
+
import { cn } from "../../components";
|
|
12
10
|
|
|
13
11
|
/**
|
|
14
12
|
*
|
|
@@ -49,7 +47,7 @@ export function ReadOnlyFieldBinding({
|
|
|
49
47
|
}
|
|
50
48
|
|
|
51
49
|
<div
|
|
52
|
-
className={cn(paperMixin, "min-h-14 p-4 md:p-6")}>
|
|
50
|
+
className={cn(paperMixin, "min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
|
|
53
51
|
|
|
54
52
|
<ErrorBoundary>
|
|
55
53
|
<PropertyPreview propertyKey={propertyKey}
|
package/src/hooks/index.tsx
CHANGED