@firecms/core 3.0.0-canary.218 → 3.0.0-canary.219
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/form/EntityForm.d.ts +5 -1
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/index.es.js +134 -117
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +134 -117
- package/dist/index.umd.js.map +1 -1
- package/dist/types/fields.d.ts +1 -0
- package/dist/types/plugins.d.ts +1 -0
- package/package.json +5 -5
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +1 -0
- package/src/core/EntityEditView.tsx +60 -57
- package/src/form/EntityForm.tsx +17 -7
- package/src/form/PropertyFieldBinding.tsx +2 -2
- package/src/form/field_bindings/SelectFieldBinding.tsx +1 -1
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +1 -1
- package/src/types/fields.tsx +2 -0
- package/src/types/plugins.tsx +1 -0
- package/src/util/resolutions.ts +1 -1
package/dist/types/fields.d.ts
CHANGED
package/dist/types/plugins.d.ts
CHANGED
|
@@ -159,6 +159,7 @@ export interface PluginFormActionProps<USER extends User = User, EC extends Enti
|
|
|
159
159
|
path: string;
|
|
160
160
|
status: EntityStatus;
|
|
161
161
|
collection: EC;
|
|
162
|
+
disabled: boolean;
|
|
162
163
|
formContext?: FormContext<any>;
|
|
163
164
|
context: FireCMSContext<USER>;
|
|
164
165
|
currentEntityId?: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-canary.
|
|
4
|
+
"version": "3.0.0-canary.219",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"./package.json": "./package.json"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@firecms/editor": "^3.0.0-canary.
|
|
54
|
-
"@firecms/formex": "^3.0.0-canary.
|
|
55
|
-
"@firecms/ui": "^3.0.0-canary.
|
|
53
|
+
"@firecms/editor": "^3.0.0-canary.219",
|
|
54
|
+
"@firecms/formex": "^3.0.0-canary.219",
|
|
55
|
+
"@firecms/ui": "^3.0.0-canary.219",
|
|
56
56
|
"@hello-pangea/dnd": "^17.0.0",
|
|
57
57
|
"@radix-ui/react-portal": "^1.1.3",
|
|
58
58
|
"clsx": "^2.1.1",
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
"dist",
|
|
106
106
|
"src"
|
|
107
107
|
],
|
|
108
|
-
"gitHead": "
|
|
108
|
+
"gitHead": "dc68bdab1dd594afc37aee70291e031f83996358",
|
|
109
109
|
"publishConfig": {
|
|
110
110
|
"access": "public"
|
|
111
111
|
},
|
|
@@ -275,6 +275,7 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
275
275
|
formex,
|
|
276
276
|
status: "existing",
|
|
277
277
|
openEntityMode: "side_panel",
|
|
278
|
+
disabled: false,
|
|
278
279
|
};
|
|
279
280
|
|
|
280
281
|
const property: ResolvedProperty<any> | undefined = propertyKey && getPropertyInPath(collection?.properties ?? {} as ResolvedProperties, propertyKey as string);
|
|
@@ -98,6 +98,10 @@ export function EntityEditView<M extends Record<string, any>, USER extends User>
|
|
|
98
98
|
}
|
|
99
99
|
}, [authController, entity, status]);
|
|
100
100
|
|
|
101
|
+
console.log({
|
|
102
|
+
canEdit
|
|
103
|
+
})
|
|
104
|
+
|
|
101
105
|
if ((dataLoading && !cachedValues) || (!entity || canEdit === undefined) && (status === "existing" || status === "copy")) {
|
|
102
106
|
return <CircularProgressCenter/>;
|
|
103
107
|
}
|
|
@@ -117,7 +121,6 @@ export function EntityEditView<M extends Record<string, any>, USER extends User>
|
|
|
117
121
|
/>;
|
|
118
122
|
}
|
|
119
123
|
|
|
120
|
-
|
|
121
124
|
export function EntityEditViewInner<M extends Record<string, any>>({
|
|
122
125
|
path,
|
|
123
126
|
entityId,
|
|
@@ -215,6 +218,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
215
218
|
const formexStub = createFormexStub<M>(usedEntity?.values ?? {} as M);
|
|
216
219
|
const usedFormContext: FormContext = formContext ?? {
|
|
217
220
|
entityId,
|
|
221
|
+
disabled: false,
|
|
218
222
|
openEntityMode: layout,
|
|
219
223
|
status: status,
|
|
220
224
|
values: usedEntity?.values ?? {},
|
|
@@ -315,61 +319,57 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
315
319
|
}
|
|
316
320
|
};
|
|
317
321
|
|
|
318
|
-
const
|
|
319
|
-
(
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}}
|
|
370
|
-
Builder={selectedSecondaryForm?.Builder}
|
|
371
|
-
/>
|
|
372
|
-
);
|
|
322
|
+
const entityReadOnlyView = <div
|
|
323
|
+
className={cls("flex-1 flex flex-row w-full overflow-y-auto justify-center", (canEdit || !mainViewVisible || selectedSecondaryForm) ? "hidden" : "")}>
|
|
324
|
+
<div
|
|
325
|
+
className={cls("relative flex flex-col max-w-4xl lg:max-w-3xl xl:max-w-4xl 2xl:max-w-6xl w-full h-fit")}>
|
|
326
|
+
<Typography className={"mt-16 mb-8 mx-8"} variant={"h4"}>
|
|
327
|
+
{collection.singularName ?? collection.name}
|
|
328
|
+
</Typography>
|
|
329
|
+
<EntityView
|
|
330
|
+
className={"px-8 h-full overflow-auto"}
|
|
331
|
+
entity={entity as Entity<M>}
|
|
332
|
+
path={path}
|
|
333
|
+
collection={collection}/>
|
|
334
|
+
</div>
|
|
335
|
+
</div>;
|
|
336
|
+
|
|
337
|
+
const entityView = <EntityForm<M>
|
|
338
|
+
collection={collection}
|
|
339
|
+
path={path}
|
|
340
|
+
entityId={entityId ?? usedEntity?.id}
|
|
341
|
+
onValuesModified={onValuesModified}
|
|
342
|
+
entity={entity}
|
|
343
|
+
initialDirtyValues={cachedDirtyValues}
|
|
344
|
+
openEntityMode={layout}
|
|
345
|
+
forceActionsAtTheBottom={actionsAtTheBottom}
|
|
346
|
+
initialStatus={status}
|
|
347
|
+
className={cls((!mainViewVisible || !canEdit) && !selectedSecondaryForm ? "hidden" : "", formProps?.className)}
|
|
348
|
+
EntityFormActionsComponent={EntityEditViewFormActions}
|
|
349
|
+
disabled={!canEdit}
|
|
350
|
+
{...formProps}
|
|
351
|
+
onEntityChange={(entity) => {
|
|
352
|
+
setUsedEntity(entity);
|
|
353
|
+
formProps?.onEntityChange?.(entity);
|
|
354
|
+
}}
|
|
355
|
+
onStatusChange={(status) => {
|
|
356
|
+
setStatus(status);
|
|
357
|
+
formProps?.onStatusChange?.(status);
|
|
358
|
+
}}
|
|
359
|
+
onFormContextReady={(formContext) => {
|
|
360
|
+
setFormContext(formContext);
|
|
361
|
+
formProps?.onFormContextReady?.(formContext);
|
|
362
|
+
}}
|
|
363
|
+
onSaved={(params) => {
|
|
364
|
+
const res = {
|
|
365
|
+
...params,
|
|
366
|
+
selectedTab: MAIN_TAB_VALUE === selectedTab ? undefined : selectedTab
|
|
367
|
+
};
|
|
368
|
+
onSaved?.(res);
|
|
369
|
+
formProps?.onSaved?.(res);
|
|
370
|
+
}}
|
|
371
|
+
Builder={selectedSecondaryForm?.Builder}
|
|
372
|
+
/>;
|
|
373
373
|
|
|
374
374
|
const subcollectionTabs = subcollections && subcollections.map((subcollection) =>
|
|
375
375
|
<Tab
|
|
@@ -436,7 +436,10 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
436
436
|
? <div className="w-full pt-12 pb-16 px-4 sm:px-8 md:px-10">
|
|
437
437
|
<CircularProgressCenter/>
|
|
438
438
|
</div>
|
|
439
|
-
:
|
|
439
|
+
: <>
|
|
440
|
+
{entityReadOnlyView}
|
|
441
|
+
{entityView}
|
|
442
|
+
</>}
|
|
440
443
|
|
|
441
444
|
{jsonView}
|
|
442
445
|
|
package/src/form/EntityForm.tsx
CHANGED
|
@@ -73,6 +73,10 @@ export type EntityFormProps<M extends Record<string, any>> = {
|
|
|
73
73
|
onEntityChange?: (entity: Entity<M>) => void;
|
|
74
74
|
formex?: FormexController<M>;
|
|
75
75
|
openEntityMode?: "side_panel" | "full_screen";
|
|
76
|
+
/**
|
|
77
|
+
* If true, the form will be disabled and no actions will be available
|
|
78
|
+
*/
|
|
79
|
+
disabled?: boolean;
|
|
76
80
|
/**
|
|
77
81
|
* Include the copy and delete actions in the form
|
|
78
82
|
*/
|
|
@@ -90,7 +94,6 @@ export type EntityFormProps<M extends Record<string, any>> = {
|
|
|
90
94
|
children?: React.ReactNode;
|
|
91
95
|
};
|
|
92
96
|
|
|
93
|
-
|
|
94
97
|
export function EntityForm<M extends Record<string, any>>({
|
|
95
98
|
path,
|
|
96
99
|
entityId: entityIdProp,
|
|
@@ -108,6 +111,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
108
111
|
onEntityChange,
|
|
109
112
|
openEntityMode = "full_screen",
|
|
110
113
|
formex: formexProp,
|
|
114
|
+
disabled: disabledProp,
|
|
111
115
|
Builder,
|
|
112
116
|
EntityFormActionsComponent = EntityFormActions,
|
|
113
117
|
showDefaultActions = true,
|
|
@@ -115,6 +119,8 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
115
119
|
children
|
|
116
120
|
}: EntityFormProps<M>) {
|
|
117
121
|
|
|
122
|
+
console.log("disabledProp", disabledProp);
|
|
123
|
+
|
|
118
124
|
if (collection.customId && collection.formAutoSave) {
|
|
119
125
|
console.warn(`The collection ${collection.path} has customId and formAutoSave enabled. This is not supported and formAutoSave will be ignored`);
|
|
120
126
|
}
|
|
@@ -402,6 +408,9 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
402
408
|
});
|
|
403
409
|
};
|
|
404
410
|
|
|
411
|
+
const disabled = formex.isSubmitting || Boolean(disabledProp);
|
|
412
|
+
console.log("disabled", disabled);
|
|
413
|
+
|
|
405
414
|
const formContext: FormContext<M> = {
|
|
406
415
|
// @ts-ignore
|
|
407
416
|
setFieldValue: useCallback(formex.setFieldValue, []),
|
|
@@ -414,7 +423,8 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
414
423
|
entity,
|
|
415
424
|
savingError,
|
|
416
425
|
status,
|
|
417
|
-
openEntityMode
|
|
426
|
+
openEntityMode,
|
|
427
|
+
disabled
|
|
418
428
|
};
|
|
419
429
|
|
|
420
430
|
useEffect(() => {
|
|
@@ -431,6 +441,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
431
441
|
const pluginActions: React.ReactNode[] = [];
|
|
432
442
|
const plugins = customizationController.plugins;
|
|
433
443
|
|
|
444
|
+
const actionsDisabled = disabled || formex.isSubmitting || (status === "existing" && !formex.dirty) || Boolean(disabledProp);
|
|
434
445
|
if (plugins && collection) {
|
|
435
446
|
const actionProps: PluginFormActionProps = {
|
|
436
447
|
entityId,
|
|
@@ -440,7 +451,8 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
440
451
|
context,
|
|
441
452
|
currentEntityId: entityId,
|
|
442
453
|
formContext,
|
|
443
|
-
openEntityMode
|
|
454
|
+
openEntityMode,
|
|
455
|
+
disabled: actionsDisabled,
|
|
444
456
|
};
|
|
445
457
|
pluginActions.push(...plugins.map((plugin) => (
|
|
446
458
|
plugin.form?.Actions
|
|
@@ -548,7 +560,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
548
560
|
!!underlyingChanges &&
|
|
549
561
|
Object.keys(underlyingChanges).includes(key) &&
|
|
550
562
|
formex.touched[key];
|
|
551
|
-
const disabled = (!autoSave && formex.isSubmitting) || isReadOnly(property) || Boolean(property.disabled);
|
|
563
|
+
const disabled = disabledProp || (!autoSave && formex.isSubmitting) || isReadOnly(property) || Boolean(property.disabled);
|
|
552
564
|
const hidden = isHidden(property);
|
|
553
565
|
if (hidden) return null;
|
|
554
566
|
const widthPercentage = property.widthPercentage ?? 100;
|
|
@@ -658,8 +670,6 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
658
670
|
onIdChange(entityId);
|
|
659
671
|
}, [entityId, onIdChange]);
|
|
660
672
|
|
|
661
|
-
const disabled = formex.isSubmitting || (!formex.dirty && status === "existing");
|
|
662
|
-
|
|
663
673
|
if (!resolvedCollection || !path) {
|
|
664
674
|
throw Error("INTERNAL: Collection and path must be defined in form context");
|
|
665
675
|
}
|
|
@@ -671,7 +681,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
671
681
|
layout={forceActionsAtTheBottom ? "bottom" : "side"}
|
|
672
682
|
savingError={savingError}
|
|
673
683
|
formex={formex}
|
|
674
|
-
disabled={
|
|
684
|
+
disabled={actionsDisabled}
|
|
675
685
|
status={status}
|
|
676
686
|
pluginActions={pluginActions ?? []}
|
|
677
687
|
openEntityMode={openEntityMode}
|
|
@@ -87,7 +87,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
87
87
|
autoFocus,
|
|
88
88
|
index,
|
|
89
89
|
size,
|
|
90
|
-
onPropertyChange
|
|
90
|
+
onPropertyChange,
|
|
91
91
|
}: PropertyFieldBindingProps<T, M>): ReactElement<PropertyFieldBindingProps<T, M>> {
|
|
92
92
|
|
|
93
93
|
const authController = useAuthController();
|
|
@@ -112,7 +112,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
|
|
|
112
112
|
authController
|
|
113
113
|
});
|
|
114
114
|
|
|
115
|
-
const disabled = disabledProp || isReadOnly(resolvedProperty) || Boolean(resolvedProperty?.disabled);
|
|
115
|
+
const disabled = disabledProp || isReadOnly(resolvedProperty) || Boolean(resolvedProperty?.disabled) || context.disabled;
|
|
116
116
|
|
|
117
117
|
if (resolvedProperty === null || isHidden(resolvedProperty)) {
|
|
118
118
|
return <></>;
|
|
@@ -66,7 +66,7 @@ export function SelectFieldBinding<T extends EnumType>({
|
|
|
66
66
|
/>
|
|
67
67
|
</PropertyIdCopyTooltip>}
|
|
68
68
|
endAdornment={
|
|
69
|
-
property.clearable && <IconButton
|
|
69
|
+
property.clearable && !disabled && <IconButton
|
|
70
70
|
onClick={handleClearClick}>
|
|
71
71
|
<CloseIcon/>
|
|
72
72
|
</IconButton>
|
|
@@ -63,7 +63,7 @@ export function StorageUploadFieldBinding({
|
|
|
63
63
|
throw new Error("StorageUploadFieldBinding: Entity id is null");
|
|
64
64
|
|
|
65
65
|
const storageSource = useStorageSource(context.collection);
|
|
66
|
-
const disabled = isReadOnly(property) || !!property.disabled || isSubmitting;
|
|
66
|
+
const disabled = isReadOnly(property) || !!property.disabled || isSubmitting || context.disabled;
|
|
67
67
|
|
|
68
68
|
const {
|
|
69
69
|
internalValue,
|
package/src/types/fields.tsx
CHANGED
package/src/types/plugins.tsx
CHANGED
|
@@ -192,6 +192,7 @@ export interface PluginFormActionProps<USER extends User = User, EC extends Enti
|
|
|
192
192
|
path: string;
|
|
193
193
|
status: EntityStatus;
|
|
194
194
|
collection: EC;
|
|
195
|
+
disabled: boolean;
|
|
195
196
|
formContext?: FormContext<any>;
|
|
196
197
|
context: FireCMSContext<USER>;
|
|
197
198
|
currentEntityId?: string;
|
package/src/util/resolutions.ts
CHANGED
|
@@ -447,7 +447,7 @@ export function resolvedSelectedEntityView<M extends Record<string, any>>(
|
|
|
447
447
|
const resolvedEntityViews = customViews ? customViews
|
|
448
448
|
.map(e => resolveEntityView(e, customizationController.entityViews))
|
|
449
449
|
.filter((e): e is EntityCustomView<M> => Boolean(e))
|
|
450
|
-
.filter((e) => canEdit || !e.includeActions)
|
|
450
|
+
// .filter((e) => canEdit || !e.includeActions)
|
|
451
451
|
: [];
|
|
452
452
|
|
|
453
453
|
const selectedEntityView = resolvedEntityViews.find(e => e.key === selectedTab);
|