@firecms/core 3.0.0-canary.283 → 3.0.0-canary.284
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/core/EntityEditView.d.ts +2 -2
- package/dist/form/EntityForm.d.ts +3 -1
- package/dist/form/index.d.ts +2 -1
- package/dist/index.es.js +121 -97
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +119 -95
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collections.d.ts +7 -0
- package/package.json +5 -5
- package/src/core/EntityEditView.tsx +13 -10
- package/src/core/EntityEditViewFormActions.tsx +33 -18
- package/src/form/EntityForm.tsx +49 -25
- package/src/form/EntityFormActions.tsx +30 -15
- package/src/form/components/ErrorFocus.tsx +22 -29
- package/src/form/index.tsx +5 -1
- package/src/types/collections.ts +8 -0
- package/src/util/entity_cache.ts +0 -1
package/dist/index.umd.js
CHANGED
|
@@ -14987,61 +14987,60 @@
|
|
|
14987
14987
|
] });
|
|
14988
14988
|
}
|
|
14989
14989
|
const ErrorFocus = (t0) => {
|
|
14990
|
-
const $ = reactCompilerRuntime.c(
|
|
14990
|
+
const $ = reactCompilerRuntime.c(10);
|
|
14991
14991
|
const {
|
|
14992
14992
|
containerRef
|
|
14993
14993
|
} = t0;
|
|
14994
14994
|
const {
|
|
14995
|
-
isSubmitting,
|
|
14996
14995
|
isValidating,
|
|
14997
|
-
errors
|
|
14996
|
+
errors,
|
|
14997
|
+
version
|
|
14998
14998
|
} = formex.useFormex();
|
|
14999
|
+
const prevVersion = React.useRef(version);
|
|
14999
15000
|
let t1;
|
|
15000
|
-
|
|
15001
|
-
if ($[0] !== containerRef || $[1] !== errors || $[2] !== isSubmitting || $[3] !== isValidating) {
|
|
15001
|
+
if ($[0] !== containerRef?.current || $[1] !== errors || $[2] !== isValidating || $[3] !== version) {
|
|
15002
15002
|
t1 = () => {
|
|
15003
|
+
if (version === prevVersion.current) {
|
|
15004
|
+
return;
|
|
15005
|
+
}
|
|
15003
15006
|
const keys = Object.keys(errors);
|
|
15004
|
-
if (keys.length > 0
|
|
15007
|
+
if (!isValidating && keys.length > 0) {
|
|
15005
15008
|
const errorElement = containerRef?.current?.querySelector(`#form_field_${keys[0]}`);
|
|
15006
|
-
if (errorElement
|
|
15007
|
-
|
|
15008
|
-
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
top: scrollableParent.scrollTop + top - 196,
|
|
15012
|
-
behavior: "smooth"
|
|
15013
|
-
});
|
|
15014
|
-
}
|
|
15009
|
+
if (errorElement) {
|
|
15010
|
+
errorElement.scrollIntoView({
|
|
15011
|
+
behavior: "smooth",
|
|
15012
|
+
block: "center"
|
|
15013
|
+
});
|
|
15015
15014
|
const input = errorElement.querySelector("input");
|
|
15016
15015
|
if (input) {
|
|
15017
15016
|
input.focus();
|
|
15018
15017
|
}
|
|
15019
15018
|
}
|
|
15019
|
+
prevVersion.current = version;
|
|
15020
15020
|
}
|
|
15021
15021
|
};
|
|
15022
|
-
|
|
15023
|
-
$[0] = containerRef;
|
|
15022
|
+
$[0] = containerRef?.current;
|
|
15024
15023
|
$[1] = errors;
|
|
15025
|
-
$[2] =
|
|
15026
|
-
$[3] =
|
|
15024
|
+
$[2] = isValidating;
|
|
15025
|
+
$[3] = version;
|
|
15027
15026
|
$[4] = t1;
|
|
15028
|
-
$[5] = t2;
|
|
15029
15027
|
} else {
|
|
15030
15028
|
t1 = $[4];
|
|
15031
|
-
|
|
15029
|
+
}
|
|
15030
|
+
let t2;
|
|
15031
|
+
if ($[5] !== containerRef || $[6] !== errors || $[7] !== isValidating || $[8] !== version) {
|
|
15032
|
+
t2 = [isValidating, errors, containerRef, version];
|
|
15033
|
+
$[5] = containerRef;
|
|
15034
|
+
$[6] = errors;
|
|
15035
|
+
$[7] = isValidating;
|
|
15036
|
+
$[8] = version;
|
|
15037
|
+
$[9] = t2;
|
|
15038
|
+
} else {
|
|
15039
|
+
t2 = $[9];
|
|
15032
15040
|
}
|
|
15033
15041
|
React.useEffect(t1, t2);
|
|
15034
15042
|
return null;
|
|
15035
15043
|
};
|
|
15036
|
-
const isScrollable = (ele) => {
|
|
15037
|
-
const hasScrollableContent = ele && ele.scrollHeight > ele.clientHeight;
|
|
15038
|
-
const overflowYStyle = ele ? window.getComputedStyle(ele).overflowY : null;
|
|
15039
|
-
const isOverflowHidden = overflowYStyle && overflowYStyle.indexOf("hidden") !== -1;
|
|
15040
|
-
return hasScrollableContent && !isOverflowHidden;
|
|
15041
|
-
};
|
|
15042
|
-
const getScrollableParent = (ele) => {
|
|
15043
|
-
return !ele || ele === document.body ? document.body : isScrollable(ele) ? ele : getScrollableParent(ele.parentNode);
|
|
15044
|
-
};
|
|
15045
15044
|
function EntityFormActions(t0) {
|
|
15046
15045
|
const $ = reactCompilerRuntime.c(16);
|
|
15047
15046
|
const {
|
|
@@ -15062,7 +15061,7 @@
|
|
|
15062
15061
|
const context = useFireCMSContext();
|
|
15063
15062
|
const sideEntityController = useSideEntityController();
|
|
15064
15063
|
let t1;
|
|
15065
|
-
if ($[0] !== collection || $[1] !== context || $[2] !== disabled || $[3] !== entity || $[4] !== formContext || $[5] !== formex2
|
|
15064
|
+
if ($[0] !== collection || $[1] !== context || $[2] !== disabled || $[3] !== entity || $[4] !== formContext || $[5] !== formex2 || $[6] !== fullIdPath || $[7] !== fullPath || $[8] !== layout || $[9] !== navigateBack || $[10] !== openEntityMode || $[11] !== pluginActions || $[12] !== savingError || $[13] !== sideEntityController || $[14] !== status) {
|
|
15066
15065
|
t1 = layout === "bottom" ? buildBottomActions$1({
|
|
15067
15066
|
fullPath,
|
|
15068
15067
|
fullIdPath,
|
|
@@ -15071,13 +15070,13 @@
|
|
|
15071
15070
|
collection,
|
|
15072
15071
|
context,
|
|
15073
15072
|
sideEntityController,
|
|
15074
|
-
isSubmitting: formex2.isSubmitting,
|
|
15075
15073
|
disabled,
|
|
15076
15074
|
status,
|
|
15077
15075
|
pluginActions,
|
|
15078
15076
|
openEntityMode,
|
|
15079
15077
|
navigateBack,
|
|
15080
|
-
formContext
|
|
15078
|
+
formContext,
|
|
15079
|
+
formex: formex2
|
|
15081
15080
|
}) : buildSideActions$1({
|
|
15082
15081
|
fullPath,
|
|
15083
15082
|
fullIdPath,
|
|
@@ -15086,18 +15085,18 @@
|
|
|
15086
15085
|
collection,
|
|
15087
15086
|
context,
|
|
15088
15087
|
sideEntityController,
|
|
15089
|
-
isSubmitting: formex2.isSubmitting,
|
|
15090
15088
|
disabled,
|
|
15091
15089
|
status,
|
|
15092
15090
|
pluginActions,
|
|
15093
|
-
openEntityMode
|
|
15091
|
+
openEntityMode,
|
|
15092
|
+
formex: formex2
|
|
15094
15093
|
});
|
|
15095
15094
|
$[0] = collection;
|
|
15096
15095
|
$[1] = context;
|
|
15097
15096
|
$[2] = disabled;
|
|
15098
15097
|
$[3] = entity;
|
|
15099
15098
|
$[4] = formContext;
|
|
15100
|
-
$[5] = formex2
|
|
15099
|
+
$[5] = formex2;
|
|
15101
15100
|
$[6] = fullIdPath;
|
|
15102
15101
|
$[7] = fullPath;
|
|
15103
15102
|
$[8] = layout;
|
|
@@ -15122,14 +15121,15 @@
|
|
|
15122
15121
|
collection,
|
|
15123
15122
|
context,
|
|
15124
15123
|
sideEntityController,
|
|
15125
|
-
isSubmitting,
|
|
15126
15124
|
disabled,
|
|
15127
15125
|
status,
|
|
15128
15126
|
pluginActions,
|
|
15129
15127
|
openEntityMode,
|
|
15130
15128
|
navigateBack,
|
|
15131
|
-
formContext
|
|
15129
|
+
formContext,
|
|
15130
|
+
formex: formex2
|
|
15132
15131
|
}) {
|
|
15132
|
+
const hasErrors = Object.keys(formex2.errors).length > 0 && formex2.submitCount > 0;
|
|
15133
15133
|
return /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { position: "absolute", children: [
|
|
15134
15134
|
savingError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "error", children: savingError.message }) }),
|
|
15135
15135
|
entity && (formActions ?? []).length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow flex overflow-auto no-scrollbar", children: (formActions ?? []).map((action) => /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { color: "primary", onClick: (event) => {
|
|
@@ -15148,8 +15148,8 @@
|
|
|
15148
15148
|
});
|
|
15149
15149
|
}, children: action.icon }, action.name)) }),
|
|
15150
15150
|
pluginActions,
|
|
15151
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", disabled: disabled || isSubmitting, color: "primary", type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
15152
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "filled", color: "primary", type: "submit", disabled: disabled || isSubmitting, children: [
|
|
15151
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", disabled: disabled || formex2.isSubmitting, color: "primary", type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
15152
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "filled", color: "primary", type: "submit", disabled: disabled || formex2.isSubmitting, startIcon: hasErrors ? /* @__PURE__ */ jsxRuntime.jsx(ui.ErrorIcon, {}) : void 0, children: [
|
|
15153
15153
|
status === "existing" && "Save",
|
|
15154
15154
|
status === "copy" && "Create copy",
|
|
15155
15155
|
status === "new" && "Create"
|
|
@@ -15166,22 +15166,35 @@
|
|
|
15166
15166
|
collection,
|
|
15167
15167
|
context,
|
|
15168
15168
|
sideEntityController,
|
|
15169
|
-
isSubmitting,
|
|
15170
15169
|
disabled,
|
|
15171
15170
|
status,
|
|
15172
|
-
pluginActions
|
|
15171
|
+
pluginActions,
|
|
15172
|
+
formex: formex2
|
|
15173
15173
|
}) {
|
|
15174
|
+
const hasErrors = Object.keys(formex2.errors).length > 0 && formex2.submitCount > 0;
|
|
15174
15175
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("overflow-auto h-full flex flex-col gap-2 w-80 2xl:w-96 px-4 py-16 sticky top-0 border-l", ui.defaultBorderMixin), children: [
|
|
15175
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.LoadingButton, { fullWidth: true, variant: "filled", color: "primary", type: "submit", size: "large", disabled: disabled || isSubmitting, children: [
|
|
15176
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.LoadingButton, { fullWidth: true, variant: "filled", color: "primary", type: "submit", size: "large", startIcon: hasErrors ? /* @__PURE__ */ jsxRuntime.jsx(ui.ErrorIcon, {}) : void 0, disabled: disabled || formex2.isSubmitting, children: [
|
|
15176
15177
|
status === "existing" && "Save",
|
|
15177
15178
|
status === "copy" && "Create copy",
|
|
15178
15179
|
status === "new" && "Create"
|
|
15179
15180
|
] }),
|
|
15180
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { fullWidth: true, variant: "text", disabled: disabled || isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
15181
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { fullWidth: true, variant: "text", disabled: disabled || formex2.isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
15181
15182
|
pluginActions,
|
|
15182
15183
|
savingError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "error", children: savingError.message }) })
|
|
15183
15184
|
] });
|
|
15184
15185
|
}
|
|
15186
|
+
function extractTouchedValues(values, touched) {
|
|
15187
|
+
let acc = {};
|
|
15188
|
+
if (!touched || typeof touched !== "object") {
|
|
15189
|
+
return acc;
|
|
15190
|
+
}
|
|
15191
|
+
Object.entries(touched).forEach(([key, value]) => {
|
|
15192
|
+
if (value) {
|
|
15193
|
+
acc = formex.setIn(acc, key, formex.getIn(values, key));
|
|
15194
|
+
}
|
|
15195
|
+
});
|
|
15196
|
+
return acc;
|
|
15197
|
+
}
|
|
15185
15198
|
function EntityForm({
|
|
15186
15199
|
path,
|
|
15187
15200
|
fullIdPath,
|
|
@@ -15239,7 +15252,7 @@
|
|
|
15239
15252
|
const customizationController = useCustomizationController();
|
|
15240
15253
|
const context = useFireCMSContext();
|
|
15241
15254
|
const analyticsController = useAnalyticsController();
|
|
15242
|
-
const [underlyingChanges
|
|
15255
|
+
const [underlyingChanges] = React.useState({});
|
|
15243
15256
|
const [customIdLoading, setCustomIdLoading] = React.useState(false);
|
|
15244
15257
|
const mustSetCustomId = (status === "new" || status === "copy") && Boolean(collection.customId) && collection.customId !== "optional";
|
|
15245
15258
|
const initialEntityId = React.useMemo(() => {
|
|
@@ -15287,16 +15300,30 @@
|
|
|
15287
15300
|
formexController.setSubmitting(false);
|
|
15288
15301
|
});
|
|
15289
15302
|
};
|
|
15303
|
+
const baseInitialValues = getInitialEntityValues(authController, collection, path, status, entity, customizationController.propertyConfigs);
|
|
15304
|
+
const initialValues = initialDirtyValues ? mergeDeep(baseInitialValues, initialDirtyValues) : baseInitialValues;
|
|
15305
|
+
const initialDirty = Boolean(initialDirtyValues) && initialDirtyValues && Object.keys(initialDirtyValues).length > 0;
|
|
15290
15306
|
const formex$1 = formexProp ?? formex.useCreateFormex({
|
|
15291
|
-
initialValues
|
|
15292
|
-
initialDirty
|
|
15307
|
+
initialValues,
|
|
15308
|
+
initialDirty,
|
|
15309
|
+
initialTouched: initialDirtyValues ? formex.flattenKeys(initialDirtyValues).reduce((previousValue, currentValue) => ({
|
|
15310
|
+
...previousValue,
|
|
15311
|
+
[currentValue]: true
|
|
15312
|
+
}), {}) : {},
|
|
15293
15313
|
onSubmit,
|
|
15294
15314
|
onReset: () => {
|
|
15295
15315
|
clearDirtyCache();
|
|
15296
15316
|
onValuesModified?.(false);
|
|
15297
15317
|
},
|
|
15298
|
-
|
|
15299
|
-
|
|
15318
|
+
onValuesChangeDeferred: (values_0, controller) => {
|
|
15319
|
+
const key = status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId;
|
|
15320
|
+
if (controller.dirty) {
|
|
15321
|
+
const touchedValues = extractTouchedValues(values_0, controller.touched);
|
|
15322
|
+
saveEntityToCache(key, touchedValues);
|
|
15323
|
+
}
|
|
15324
|
+
},
|
|
15325
|
+
validation: (values_1) => {
|
|
15326
|
+
return validationSchema?.validate(values_1, {
|
|
15300
15327
|
abortEarly: false
|
|
15301
15328
|
}).then(() => {
|
|
15302
15329
|
return {};
|
|
@@ -15379,7 +15406,7 @@
|
|
|
15379
15406
|
console.error(e_3);
|
|
15380
15407
|
}, [entityId, path, snackbarController]);
|
|
15381
15408
|
const saveEntity = ({
|
|
15382
|
-
values:
|
|
15409
|
+
values: values_2,
|
|
15383
15410
|
previousValues,
|
|
15384
15411
|
entityId: entityId_0,
|
|
15385
15412
|
collection: collection_0,
|
|
@@ -15388,7 +15415,7 @@
|
|
|
15388
15415
|
return saveEntityWithCallbacks({
|
|
15389
15416
|
path: path_0,
|
|
15390
15417
|
entityId: entityId_0,
|
|
15391
|
-
values:
|
|
15418
|
+
values: values_2,
|
|
15392
15419
|
previousValues,
|
|
15393
15420
|
collection: collection_0,
|
|
15394
15421
|
status,
|
|
@@ -15404,34 +15431,34 @@
|
|
|
15404
15431
|
collection: collection_1,
|
|
15405
15432
|
path: path_1,
|
|
15406
15433
|
entityId: entityId_1,
|
|
15407
|
-
values:
|
|
15434
|
+
values: values_3,
|
|
15408
15435
|
previousValues: previousValues_0,
|
|
15409
15436
|
autoSave: autoSave_0
|
|
15410
15437
|
}) => {
|
|
15411
15438
|
if (!status) return;
|
|
15412
15439
|
if (autoSave_0) {
|
|
15413
|
-
setValuesToBeSaved(
|
|
15440
|
+
setValuesToBeSaved(values_3);
|
|
15414
15441
|
} else {
|
|
15415
15442
|
return saveEntity({
|
|
15416
15443
|
collection: collection_1,
|
|
15417
15444
|
path: path_1,
|
|
15418
15445
|
entityId: entityId_1,
|
|
15419
|
-
values:
|
|
15446
|
+
values: values_3,
|
|
15420
15447
|
previousValues: previousValues_0
|
|
15421
15448
|
});
|
|
15422
15449
|
}
|
|
15423
15450
|
};
|
|
15424
15451
|
const lastSavedValues = React.useRef(entity?.values);
|
|
15425
|
-
const save = (
|
|
15426
|
-
lastSavedValues.current =
|
|
15452
|
+
const save = (values_4) => {
|
|
15453
|
+
lastSavedValues.current = values_4;
|
|
15427
15454
|
return onSaveEntityRequest({
|
|
15428
15455
|
collection: resolvedCollection,
|
|
15429
15456
|
path,
|
|
15430
15457
|
entityId,
|
|
15431
|
-
values:
|
|
15458
|
+
values: values_4,
|
|
15432
15459
|
previousValues: entity?.values,
|
|
15433
15460
|
autoSave: autoSave ?? false
|
|
15434
|
-
}).then((
|
|
15461
|
+
}).then(() => {
|
|
15435
15462
|
const eventName = status === "new" ? "new_entity_saved" : status === "copy" ? "entity_copied" : status === "existing" ? "entity_edited" : "unmapped_event";
|
|
15436
15463
|
analyticsController.onAnalyticsEvent?.(eventName, {
|
|
15437
15464
|
path
|
|
@@ -15465,7 +15492,8 @@
|
|
|
15465
15492
|
type: "error",
|
|
15466
15493
|
message: "Error updating id, check the console"
|
|
15467
15494
|
});
|
|
15468
|
-
|
|
15495
|
+
console.error(error);
|
|
15496
|
+
}, [snackbarController]);
|
|
15469
15497
|
const pluginActions = [];
|
|
15470
15498
|
const plugins = customizationController.plugins;
|
|
15471
15499
|
const actionsDisabled = disabled || formex$1.isSubmitting || status === "existing" && !formex$1.dirty || Boolean(disabledProp);
|
|
@@ -15514,20 +15542,12 @@
|
|
|
15514
15542
|
onValuesModified?.(modified);
|
|
15515
15543
|
}
|
|
15516
15544
|
}, [formex$1.dirty]);
|
|
15517
|
-
const deferredValues = React.useDeferredValue(formex$1.values);
|
|
15518
15545
|
const modified = formex$1.dirty;
|
|
15519
15546
|
const uniqueFieldValidator = React.useCallback(({
|
|
15520
15547
|
name,
|
|
15521
|
-
value
|
|
15522
|
-
property
|
|
15548
|
+
value
|
|
15523
15549
|
}) => dataSource.checkUniqueField(path, name, value, entityId, collection), [dataSource, path, entityId]);
|
|
15524
15550
|
const validationSchema = React.useMemo(() => entityId ? getYupEntitySchema(entityId, resolvedCollection.properties, uniqueFieldValidator) : void 0, [entityId, resolvedCollection.properties, uniqueFieldValidator]);
|
|
15525
|
-
React.useEffect(() => {
|
|
15526
|
-
const key = status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId;
|
|
15527
|
-
if (modified) {
|
|
15528
|
-
saveEntityToCache(key, deferredValues);
|
|
15529
|
-
}
|
|
15530
|
-
}, [deferredValues, modified, path, entityId, status]);
|
|
15531
15551
|
useOnAutoSave(autoSave, formex$1, lastSavedValues, save);
|
|
15532
15552
|
React.useEffect(() => {
|
|
15533
15553
|
if (!autoSave && !formex$1.isSubmitting && underlyingChanges && entity) {
|
|
@@ -15546,18 +15566,18 @@
|
|
|
15546
15566
|
return /* @__PURE__ */ jsxRuntime.jsx(Builder, { collection, entity, modifiedValues: formex$1.values, formContext });
|
|
15547
15567
|
}
|
|
15548
15568
|
return /* @__PURE__ */ jsxRuntime.jsx(FormLayout, { children: formFieldKeys.map((key_1) => {
|
|
15549
|
-
const
|
|
15550
|
-
if (
|
|
15569
|
+
const property = resolvedCollection.properties[key_1];
|
|
15570
|
+
if (property) {
|
|
15551
15571
|
const underlyingValueHasChanged = !!underlyingChanges && Object.keys(underlyingChanges).includes(key_1) && formex$1.touched[key_1];
|
|
15552
|
-
const disabled_0 = disabledProp || !autoSave && formex$1.isSubmitting || isReadOnly(
|
|
15553
|
-
const hidden = isHidden(
|
|
15572
|
+
const disabled_0 = disabledProp || !autoSave && formex$1.isSubmitting || isReadOnly(property) || Boolean(property.disabled);
|
|
15573
|
+
const hidden = isHidden(property);
|
|
15554
15574
|
if (hidden) return null;
|
|
15555
|
-
const widthPercentage =
|
|
15575
|
+
const widthPercentage = property.widthPercentage ?? 100;
|
|
15556
15576
|
const cmsFormFieldProps = {
|
|
15557
15577
|
propertyKey: key_1,
|
|
15558
15578
|
disabled: disabled_0,
|
|
15559
|
-
property
|
|
15560
|
-
includeDescription:
|
|
15579
|
+
property,
|
|
15580
|
+
includeDescription: property.description || property.longDescription,
|
|
15561
15581
|
underlyingValueHasChanged: underlyingValueHasChanged && !autoSave,
|
|
15562
15582
|
context: formContext,
|
|
15563
15583
|
partOfArray: false,
|
|
@@ -15613,7 +15633,7 @@
|
|
|
15613
15633
|
}
|
|
15614
15634
|
const dialogActions = /* @__PURE__ */ jsxRuntime.jsx(EntityFormActionsComponent, { collection: resolvedCollection, path, fullPath: path, fullIdPath, entity, layout: forceActionsAtTheBottom ? "bottom" : "side", savingError, formex: formex$1, disabled: actionsDisabled, status, pluginActions: pluginActions ?? [], openEntityMode, showDefaultActions, navigateBack, formContext });
|
|
15615
15635
|
return /* @__PURE__ */ jsxRuntime.jsx(formex.Formex, { value: formex$1, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: formex$1.handleSubmit, onReset: () => formex$1.resetForm({
|
|
15616
|
-
values:
|
|
15636
|
+
values: baseInitialValues
|
|
15617
15637
|
}), noValidate: true, className: ui.cls("flex-1 flex flex-row w-full overflow-y-auto justify-center", className), children: [
|
|
15618
15638
|
/* @__PURE__ */ jsxRuntime.jsx("div", { id: `form_${path}`, className: ui.cls("relative flex flex-row max-w-4xl lg:max-w-3xl xl:max-w-4xl 2xl:max-w-6xl w-full h-fit"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("flex flex-col w-full pt-12 pb-16 px-4 sm:px-8 md:px-10"), children: [
|
|
15619
15639
|
formex$1.dirty ? /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Local unsaved changes", className: "self-end sticky top-4 z-10", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { size: "small", colorScheme: "orangeDarker", children: /* @__PURE__ */ jsxRuntime.jsx(ui.EditIcon, { size: "smallest" }) }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "In sync with the database", className: "self-end sticky top-4 z-10", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { size: "small", children: /* @__PURE__ */ jsxRuntime.jsx(ui.CheckIcon, { size: "smallest" }) }) }),
|
|
@@ -22826,14 +22846,14 @@
|
|
|
22826
22846
|
collection,
|
|
22827
22847
|
context,
|
|
22828
22848
|
sideEntityController,
|
|
22829
|
-
isSubmitting: formex2.isSubmitting,
|
|
22830
22849
|
disabled,
|
|
22831
22850
|
status,
|
|
22832
22851
|
sideDialogContext,
|
|
22833
22852
|
pluginActions,
|
|
22834
22853
|
openEntityMode,
|
|
22835
22854
|
navigateBack,
|
|
22836
|
-
formContext
|
|
22855
|
+
formContext,
|
|
22856
|
+
formex: formex2
|
|
22837
22857
|
}) : buildSideActions({
|
|
22838
22858
|
savingError,
|
|
22839
22859
|
entity,
|
|
@@ -22841,14 +22861,14 @@
|
|
|
22841
22861
|
collection,
|
|
22842
22862
|
context,
|
|
22843
22863
|
sideEntityController,
|
|
22844
|
-
isSubmitting: formex2.isSubmitting,
|
|
22845
22864
|
sideDialogContext,
|
|
22846
22865
|
disabled,
|
|
22847
22866
|
status,
|
|
22848
22867
|
pluginActions,
|
|
22849
22868
|
openEntityMode,
|
|
22850
22869
|
navigateBack,
|
|
22851
|
-
formContext
|
|
22870
|
+
formContext,
|
|
22871
|
+
formex: formex2
|
|
22852
22872
|
});
|
|
22853
22873
|
}
|
|
22854
22874
|
function buildBottomActions({
|
|
@@ -22858,15 +22878,16 @@
|
|
|
22858
22878
|
collection,
|
|
22859
22879
|
context,
|
|
22860
22880
|
sideEntityController,
|
|
22861
|
-
isSubmitting,
|
|
22862
22881
|
disabled,
|
|
22863
22882
|
status,
|
|
22864
22883
|
sideDialogContext,
|
|
22865
22884
|
pluginActions,
|
|
22866
22885
|
openEntityMode,
|
|
22867
22886
|
navigateBack,
|
|
22868
|
-
formContext
|
|
22887
|
+
formContext,
|
|
22888
|
+
formex: formex2
|
|
22869
22889
|
}) {
|
|
22890
|
+
const hasErrors = Object.keys(formex2.errors).length > 0 && formex2.submitCount > 0;
|
|
22870
22891
|
const canClose = openEntityMode === "side_panel";
|
|
22871
22892
|
return /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { position: "absolute", children: [
|
|
22872
22893
|
savingError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "error", children: savingError.message }) }),
|
|
@@ -22886,15 +22907,16 @@
|
|
|
22886
22907
|
return /* @__PURE__ */ jsxRuntime.jsx(EntityActionButton, { action, enabled: isEnabled, props }, action.key);
|
|
22887
22908
|
}) }),
|
|
22888
22909
|
pluginActions,
|
|
22889
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22890
|
-
/* @__PURE__ */ jsxRuntime.
|
|
22910
|
+
hasErrors ? /* @__PURE__ */ jsxRuntime.jsx(ErrorTooltip, { title: "This form has errors", children: /* @__PURE__ */ jsxRuntime.jsx(ui.ErrorIcon, { className: "ml-4", color: "error", size: "smallest" }) }) : null,
|
|
22911
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", color: "primary", disabled: disabled || formex2.isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
22912
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: canClose ? "text" : "filled", color: "primary", type: "submit", disabled: disabled || formex2.isSubmitting, onClick: () => {
|
|
22891
22913
|
sideDialogContext.setPendingClose(false);
|
|
22892
22914
|
}, children: [
|
|
22893
22915
|
status === "existing" && "Save",
|
|
22894
22916
|
status === "copy" && "Create copy",
|
|
22895
22917
|
status === "new" && "Create"
|
|
22896
22918
|
] }),
|
|
22897
|
-
canClose && /* @__PURE__ */ jsxRuntime.jsxs(ui.LoadingButton, { variant: "filled", color: "primary", type: "submit", loading: isSubmitting, disabled, onClick: () => {
|
|
22919
|
+
canClose && /* @__PURE__ */ jsxRuntime.jsxs(ui.LoadingButton, { variant: "filled", color: "primary", type: "submit", loading: formex2.isSubmitting, disabled, onClick: () => {
|
|
22898
22920
|
sideDialogContext.setPendingClose?.(true);
|
|
22899
22921
|
}, children: [
|
|
22900
22922
|
status === "existing" && "Save and close",
|
|
@@ -22910,24 +22932,25 @@
|
|
|
22910
22932
|
collection,
|
|
22911
22933
|
context,
|
|
22912
22934
|
sideEntityController,
|
|
22913
|
-
isSubmitting,
|
|
22914
22935
|
disabled,
|
|
22915
22936
|
status,
|
|
22916
22937
|
sideDialogContext,
|
|
22917
22938
|
pluginActions,
|
|
22918
22939
|
openEntityMode,
|
|
22919
22940
|
navigateBack,
|
|
22920
|
-
formContext
|
|
22941
|
+
formContext,
|
|
22942
|
+
formex: formex2
|
|
22921
22943
|
}) {
|
|
22944
|
+
const hasErrors = Object.keys(formex2.errors).length > 0 && formex2.submitCount > 0;
|
|
22922
22945
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("overflow-auto h-full flex flex-col gap-2 w-80 2xl:w-96 px-4 py-16 sticky top-0 border-l", ui.defaultBorderMixin), children: [
|
|
22923
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.LoadingButton, { fullWidth: true, variant: "filled", color: "primary", type: "submit", size: "large", disabled: disabled || isSubmitting, onClick: () => {
|
|
22946
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.LoadingButton, { fullWidth: true, variant: "filled", color: "primary", type: "submit", size: "large", startIcon: hasErrors ? /* @__PURE__ */ jsxRuntime.jsx(ui.ErrorIcon, {}) : void 0, disabled: disabled || formex2.isSubmitting, onClick: () => {
|
|
22924
22947
|
sideDialogContext.setPendingClose?.(false);
|
|
22925
22948
|
}, children: [
|
|
22926
22949
|
status === "existing" && "Save",
|
|
22927
22950
|
status === "copy" && "Create copy",
|
|
22928
22951
|
status === "new" && "Create"
|
|
22929
22952
|
] }),
|
|
22930
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { fullWidth: true, variant: "text", disabled: disabled || isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
22953
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { fullWidth: true, variant: "text", disabled: disabled || formex2.isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
22931
22954
|
pluginActions,
|
|
22932
22955
|
formActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row flex-wrap mt-2", children: formActions.map((action) => {
|
|
22933
22956
|
const props = {
|
|
@@ -23155,7 +23178,8 @@
|
|
|
23155
23178
|
databaseId: props.databaseId,
|
|
23156
23179
|
useCache: false
|
|
23157
23180
|
});
|
|
23158
|
-
const
|
|
23181
|
+
const enableLocalChangesBackup = props.collection.enableLocalChangesBackup !== void 0 ? props.collection.enableLocalChangesBackup : true;
|
|
23182
|
+
const initialDirtyValues = enableLocalChangesBackup ? entityId ? getEntityFromCache(props.path + "/" + entityId) : getEntityFromCache(props.path + "#new") : void 0;
|
|
23159
23183
|
const authController = useAuthController();
|
|
23160
23184
|
const initialStatus = props.copy ? "copy" : entityId ? "existing" : "new";
|
|
23161
23185
|
const [status, setStatus] = React.useState(initialStatus);
|
|
@@ -23166,13 +23190,13 @@
|
|
|
23166
23190
|
return entity ? canEditEntity(props.collection, authController, props.path, entity ?? null) : void 0;
|
|
23167
23191
|
}
|
|
23168
23192
|
}, [authController, entity, status]);
|
|
23169
|
-
if (dataLoading && !
|
|
23193
|
+
if (dataLoading && !initialDirtyValues || (!entity || canEdit === void 0) && (status === "existing" || status === "copy")) {
|
|
23170
23194
|
return /* @__PURE__ */ jsxRuntime.jsx(CircularProgressCenter, {});
|
|
23171
23195
|
}
|
|
23172
|
-
if (entityId && !entity && !
|
|
23196
|
+
if (entityId && !entity && !initialDirtyValues) {
|
|
23173
23197
|
console.error(`Entity with id ${entityId} not found in collection ${props.path}`);
|
|
23174
23198
|
}
|
|
23175
|
-
return /* @__PURE__ */ jsxRuntime.jsx(EntityEditViewInner, { ...props, entityId, entity,
|
|
23199
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EntityEditViewInner, { ...props, entityId, entity, initialDirtyValues, dataLoading, status, setStatus, canEdit });
|
|
23176
23200
|
}
|
|
23177
23201
|
function EntityEditViewInner({
|
|
23178
23202
|
path,
|
|
@@ -23185,7 +23209,7 @@
|
|
|
23185
23209
|
onSaved,
|
|
23186
23210
|
onTabChange,
|
|
23187
23211
|
entity,
|
|
23188
|
-
|
|
23212
|
+
initialDirtyValues,
|
|
23189
23213
|
dataLoading,
|
|
23190
23214
|
layout = "side_panel",
|
|
23191
23215
|
barActions,
|
|
@@ -23313,7 +23337,7 @@
|
|
|
23313
23337
|
/* @__PURE__ */ jsxRuntime.jsx(EntityView, { className: "px-8 h-full overflow-auto", entity, path, collection }),
|
|
23314
23338
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-16" })
|
|
23315
23339
|
] }) }) : null;
|
|
23316
|
-
const entityView = /* @__PURE__ */ jsxRuntime.jsx(EntityForm, { fullIdPath, collection, path, entityId: entityId ?? usedEntity?.id, onValuesModified, entity, initialDirtyValues
|
|
23340
|
+
const entityView = /* @__PURE__ */ jsxRuntime.jsx(EntityForm, { fullIdPath, collection, path, entityId: entityId ?? usedEntity?.id, onValuesModified, entity, initialDirtyValues, openEntityMode: layout, forceActionsAtTheBottom: actionsAtTheBottom, initialStatus: status, className: ui.cls((!mainViewVisible || !canEdit) && !selectedSecondaryForm ? "hidden" : "", formProps?.className), EntityFormActionsComponent: EntityEditViewFormActions, disabled: !canEdit, ...formProps, onEntityChange: (entity_0) => {
|
|
23317
23341
|
setUsedEntity(entity_0);
|
|
23318
23342
|
formProps?.onEntityChange?.(entity_0);
|
|
23319
23343
|
}, onStatusChange: (status_0) => {
|