@firecms/core 3.0.0-canary.283 → 3.0.0-canary.285
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 +123 -120
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +121 -118
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collections.d.ts +7 -0
- package/dist/util/entity_cache.d.ts +2 -1
- package/package.json +5 -5
- package/src/core/EntityEditView.tsx +11 -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 +22 -34
package/dist/index.umd.js
CHANGED
|
@@ -9754,27 +9754,6 @@
|
|
|
9754
9754
|
}
|
|
9755
9755
|
return value;
|
|
9756
9756
|
}
|
|
9757
|
-
if (isLocalStorageAvailable) {
|
|
9758
|
-
try {
|
|
9759
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
9760
|
-
const fullKey = localStorage.key(i);
|
|
9761
|
-
if (fullKey && fullKey.startsWith(LOCAL_STORAGE_PREFIX)) {
|
|
9762
|
-
const path = fullKey.substring(LOCAL_STORAGE_PREFIX.length);
|
|
9763
|
-
const entityString = localStorage.getItem(fullKey);
|
|
9764
|
-
if (entityString) {
|
|
9765
|
-
try {
|
|
9766
|
-
const entity = JSON.parse(entityString, customReviver);
|
|
9767
|
-
entityCache.set(path, entity);
|
|
9768
|
-
} catch (parseError) {
|
|
9769
|
-
console.error(`Failed to parse entity for path "${path}" from localStorage:`, parseError);
|
|
9770
|
-
}
|
|
9771
|
-
}
|
|
9772
|
-
}
|
|
9773
|
-
}
|
|
9774
|
-
} catch (error) {
|
|
9775
|
-
console.error("Error accessing localStorage during initialization:", error);
|
|
9776
|
-
}
|
|
9777
|
-
}
|
|
9778
9757
|
function saveEntityToCache(path, data) {
|
|
9779
9758
|
entityCache.set(path, data);
|
|
9780
9759
|
if (isLocalStorageAvailable) {
|
|
@@ -9787,11 +9766,11 @@
|
|
|
9787
9766
|
}
|
|
9788
9767
|
}
|
|
9789
9768
|
}
|
|
9790
|
-
function getEntityFromCache(path) {
|
|
9769
|
+
function getEntityFromCache(path, useLocalStorage = true) {
|
|
9791
9770
|
if (entityCache.has(path)) {
|
|
9792
9771
|
return entityCache.get(path);
|
|
9793
9772
|
}
|
|
9794
|
-
if (isLocalStorageAvailable) {
|
|
9773
|
+
if (isLocalStorageAvailable && useLocalStorage) {
|
|
9795
9774
|
try {
|
|
9796
9775
|
const key = LOCAL_STORAGE_PREFIX + path;
|
|
9797
9776
|
const entityString = localStorage.getItem(key);
|
|
@@ -14987,61 +14966,60 @@
|
|
|
14987
14966
|
] });
|
|
14988
14967
|
}
|
|
14989
14968
|
const ErrorFocus = (t0) => {
|
|
14990
|
-
const $ = reactCompilerRuntime.c(
|
|
14969
|
+
const $ = reactCompilerRuntime.c(10);
|
|
14991
14970
|
const {
|
|
14992
14971
|
containerRef
|
|
14993
14972
|
} = t0;
|
|
14994
14973
|
const {
|
|
14995
|
-
isSubmitting,
|
|
14996
14974
|
isValidating,
|
|
14997
|
-
errors
|
|
14975
|
+
errors,
|
|
14976
|
+
version
|
|
14998
14977
|
} = formex.useFormex();
|
|
14978
|
+
const prevVersion = React.useRef(version);
|
|
14999
14979
|
let t1;
|
|
15000
|
-
|
|
15001
|
-
if ($[0] !== containerRef || $[1] !== errors || $[2] !== isSubmitting || $[3] !== isValidating) {
|
|
14980
|
+
if ($[0] !== containerRef?.current || $[1] !== errors || $[2] !== isValidating || $[3] !== version) {
|
|
15002
14981
|
t1 = () => {
|
|
14982
|
+
if (version === prevVersion.current) {
|
|
14983
|
+
return;
|
|
14984
|
+
}
|
|
15003
14985
|
const keys = Object.keys(errors);
|
|
15004
|
-
if (keys.length > 0
|
|
14986
|
+
if (!isValidating && keys.length > 0) {
|
|
15005
14987
|
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
|
-
}
|
|
14988
|
+
if (errorElement) {
|
|
14989
|
+
errorElement.scrollIntoView({
|
|
14990
|
+
behavior: "smooth",
|
|
14991
|
+
block: "center"
|
|
14992
|
+
});
|
|
15015
14993
|
const input = errorElement.querySelector("input");
|
|
15016
14994
|
if (input) {
|
|
15017
14995
|
input.focus();
|
|
15018
14996
|
}
|
|
15019
14997
|
}
|
|
14998
|
+
prevVersion.current = version;
|
|
15020
14999
|
}
|
|
15021
15000
|
};
|
|
15022
|
-
|
|
15023
|
-
$[0] = containerRef;
|
|
15001
|
+
$[0] = containerRef?.current;
|
|
15024
15002
|
$[1] = errors;
|
|
15025
|
-
$[2] =
|
|
15026
|
-
$[3] =
|
|
15003
|
+
$[2] = isValidating;
|
|
15004
|
+
$[3] = version;
|
|
15027
15005
|
$[4] = t1;
|
|
15028
|
-
$[5] = t2;
|
|
15029
15006
|
} else {
|
|
15030
15007
|
t1 = $[4];
|
|
15031
|
-
|
|
15008
|
+
}
|
|
15009
|
+
let t2;
|
|
15010
|
+
if ($[5] !== containerRef || $[6] !== errors || $[7] !== isValidating || $[8] !== version) {
|
|
15011
|
+
t2 = [isValidating, errors, containerRef, version];
|
|
15012
|
+
$[5] = containerRef;
|
|
15013
|
+
$[6] = errors;
|
|
15014
|
+
$[7] = isValidating;
|
|
15015
|
+
$[8] = version;
|
|
15016
|
+
$[9] = t2;
|
|
15017
|
+
} else {
|
|
15018
|
+
t2 = $[9];
|
|
15032
15019
|
}
|
|
15033
15020
|
React.useEffect(t1, t2);
|
|
15034
15021
|
return null;
|
|
15035
15022
|
};
|
|
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
15023
|
function EntityFormActions(t0) {
|
|
15046
15024
|
const $ = reactCompilerRuntime.c(16);
|
|
15047
15025
|
const {
|
|
@@ -15062,7 +15040,7 @@
|
|
|
15062
15040
|
const context = useFireCMSContext();
|
|
15063
15041
|
const sideEntityController = useSideEntityController();
|
|
15064
15042
|
let t1;
|
|
15065
|
-
if ($[0] !== collection || $[1] !== context || $[2] !== disabled || $[3] !== entity || $[4] !== formContext || $[5] !== formex2
|
|
15043
|
+
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
15044
|
t1 = layout === "bottom" ? buildBottomActions$1({
|
|
15067
15045
|
fullPath,
|
|
15068
15046
|
fullIdPath,
|
|
@@ -15071,13 +15049,13 @@
|
|
|
15071
15049
|
collection,
|
|
15072
15050
|
context,
|
|
15073
15051
|
sideEntityController,
|
|
15074
|
-
isSubmitting: formex2.isSubmitting,
|
|
15075
15052
|
disabled,
|
|
15076
15053
|
status,
|
|
15077
15054
|
pluginActions,
|
|
15078
15055
|
openEntityMode,
|
|
15079
15056
|
navigateBack,
|
|
15080
|
-
formContext
|
|
15057
|
+
formContext,
|
|
15058
|
+
formex: formex2
|
|
15081
15059
|
}) : buildSideActions$1({
|
|
15082
15060
|
fullPath,
|
|
15083
15061
|
fullIdPath,
|
|
@@ -15086,18 +15064,18 @@
|
|
|
15086
15064
|
collection,
|
|
15087
15065
|
context,
|
|
15088
15066
|
sideEntityController,
|
|
15089
|
-
isSubmitting: formex2.isSubmitting,
|
|
15090
15067
|
disabled,
|
|
15091
15068
|
status,
|
|
15092
15069
|
pluginActions,
|
|
15093
|
-
openEntityMode
|
|
15070
|
+
openEntityMode,
|
|
15071
|
+
formex: formex2
|
|
15094
15072
|
});
|
|
15095
15073
|
$[0] = collection;
|
|
15096
15074
|
$[1] = context;
|
|
15097
15075
|
$[2] = disabled;
|
|
15098
15076
|
$[3] = entity;
|
|
15099
15077
|
$[4] = formContext;
|
|
15100
|
-
$[5] = formex2
|
|
15078
|
+
$[5] = formex2;
|
|
15101
15079
|
$[6] = fullIdPath;
|
|
15102
15080
|
$[7] = fullPath;
|
|
15103
15081
|
$[8] = layout;
|
|
@@ -15122,14 +15100,15 @@
|
|
|
15122
15100
|
collection,
|
|
15123
15101
|
context,
|
|
15124
15102
|
sideEntityController,
|
|
15125
|
-
isSubmitting,
|
|
15126
15103
|
disabled,
|
|
15127
15104
|
status,
|
|
15128
15105
|
pluginActions,
|
|
15129
15106
|
openEntityMode,
|
|
15130
15107
|
navigateBack,
|
|
15131
|
-
formContext
|
|
15108
|
+
formContext,
|
|
15109
|
+
formex: formex2
|
|
15132
15110
|
}) {
|
|
15111
|
+
const hasErrors = Object.keys(formex2.errors).length > 0 && formex2.submitCount > 0;
|
|
15133
15112
|
return /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { position: "absolute", children: [
|
|
15134
15113
|
savingError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "error", children: savingError.message }) }),
|
|
15135
15114
|
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 +15127,8 @@
|
|
|
15148
15127
|
});
|
|
15149
15128
|
}, children: action.icon }, action.name)) }),
|
|
15150
15129
|
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: [
|
|
15130
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", disabled: disabled || formex2.isSubmitting, color: "primary", type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
15131
|
+
/* @__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
15132
|
status === "existing" && "Save",
|
|
15154
15133
|
status === "copy" && "Create copy",
|
|
15155
15134
|
status === "new" && "Create"
|
|
@@ -15166,22 +15145,35 @@
|
|
|
15166
15145
|
collection,
|
|
15167
15146
|
context,
|
|
15168
15147
|
sideEntityController,
|
|
15169
|
-
isSubmitting,
|
|
15170
15148
|
disabled,
|
|
15171
15149
|
status,
|
|
15172
|
-
pluginActions
|
|
15150
|
+
pluginActions,
|
|
15151
|
+
formex: formex2
|
|
15173
15152
|
}) {
|
|
15153
|
+
const hasErrors = Object.keys(formex2.errors).length > 0 && formex2.submitCount > 0;
|
|
15174
15154
|
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: [
|
|
15155
|
+
/* @__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
15156
|
status === "existing" && "Save",
|
|
15177
15157
|
status === "copy" && "Create copy",
|
|
15178
15158
|
status === "new" && "Create"
|
|
15179
15159
|
] }),
|
|
15180
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { fullWidth: true, variant: "text", disabled: disabled || isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
15160
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { fullWidth: true, variant: "text", disabled: disabled || formex2.isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
15181
15161
|
pluginActions,
|
|
15182
15162
|
savingError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "error", children: savingError.message }) })
|
|
15183
15163
|
] });
|
|
15184
15164
|
}
|
|
15165
|
+
function extractTouchedValues(values, touched) {
|
|
15166
|
+
let acc = {};
|
|
15167
|
+
if (!touched || typeof touched !== "object") {
|
|
15168
|
+
return acc;
|
|
15169
|
+
}
|
|
15170
|
+
Object.entries(touched).forEach(([key, value]) => {
|
|
15171
|
+
if (value) {
|
|
15172
|
+
acc = formex.setIn(acc, key, formex.getIn(values, key));
|
|
15173
|
+
}
|
|
15174
|
+
});
|
|
15175
|
+
return acc;
|
|
15176
|
+
}
|
|
15185
15177
|
function EntityForm({
|
|
15186
15178
|
path,
|
|
15187
15179
|
fullIdPath,
|
|
@@ -15239,7 +15231,7 @@
|
|
|
15239
15231
|
const customizationController = useCustomizationController();
|
|
15240
15232
|
const context = useFireCMSContext();
|
|
15241
15233
|
const analyticsController = useAnalyticsController();
|
|
15242
|
-
const [underlyingChanges
|
|
15234
|
+
const [underlyingChanges] = React.useState({});
|
|
15243
15235
|
const [customIdLoading, setCustomIdLoading] = React.useState(false);
|
|
15244
15236
|
const mustSetCustomId = (status === "new" || status === "copy") && Boolean(collection.customId) && collection.customId !== "optional";
|
|
15245
15237
|
const initialEntityId = React.useMemo(() => {
|
|
@@ -15287,16 +15279,30 @@
|
|
|
15287
15279
|
formexController.setSubmitting(false);
|
|
15288
15280
|
});
|
|
15289
15281
|
};
|
|
15282
|
+
const baseInitialValues = getInitialEntityValues(authController, collection, path, status, entity, customizationController.propertyConfigs);
|
|
15283
|
+
const initialValues = initialDirtyValues ? mergeDeep(baseInitialValues, initialDirtyValues) : baseInitialValues;
|
|
15284
|
+
const initialDirty = Boolean(initialDirtyValues) && initialDirtyValues && Object.keys(initialDirtyValues).length > 0;
|
|
15290
15285
|
const formex$1 = formexProp ?? formex.useCreateFormex({
|
|
15291
|
-
initialValues
|
|
15292
|
-
initialDirty
|
|
15286
|
+
initialValues,
|
|
15287
|
+
initialDirty,
|
|
15288
|
+
initialTouched: initialDirtyValues ? formex.flattenKeys(initialDirtyValues).reduce((previousValue, currentValue) => ({
|
|
15289
|
+
...previousValue,
|
|
15290
|
+
[currentValue]: true
|
|
15291
|
+
}), {}) : {},
|
|
15293
15292
|
onSubmit,
|
|
15294
15293
|
onReset: () => {
|
|
15295
15294
|
clearDirtyCache();
|
|
15296
15295
|
onValuesModified?.(false);
|
|
15297
15296
|
},
|
|
15298
|
-
|
|
15299
|
-
|
|
15297
|
+
onValuesChangeDeferred: (values_0, controller) => {
|
|
15298
|
+
const key = status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId;
|
|
15299
|
+
if (controller.dirty) {
|
|
15300
|
+
const touchedValues = extractTouchedValues(values_0, controller.touched);
|
|
15301
|
+
saveEntityToCache(key, touchedValues);
|
|
15302
|
+
}
|
|
15303
|
+
},
|
|
15304
|
+
validation: (values_1) => {
|
|
15305
|
+
return validationSchema?.validate(values_1, {
|
|
15300
15306
|
abortEarly: false
|
|
15301
15307
|
}).then(() => {
|
|
15302
15308
|
return {};
|
|
@@ -15379,7 +15385,7 @@
|
|
|
15379
15385
|
console.error(e_3);
|
|
15380
15386
|
}, [entityId, path, snackbarController]);
|
|
15381
15387
|
const saveEntity = ({
|
|
15382
|
-
values:
|
|
15388
|
+
values: values_2,
|
|
15383
15389
|
previousValues,
|
|
15384
15390
|
entityId: entityId_0,
|
|
15385
15391
|
collection: collection_0,
|
|
@@ -15388,7 +15394,7 @@
|
|
|
15388
15394
|
return saveEntityWithCallbacks({
|
|
15389
15395
|
path: path_0,
|
|
15390
15396
|
entityId: entityId_0,
|
|
15391
|
-
values:
|
|
15397
|
+
values: values_2,
|
|
15392
15398
|
previousValues,
|
|
15393
15399
|
collection: collection_0,
|
|
15394
15400
|
status,
|
|
@@ -15404,34 +15410,34 @@
|
|
|
15404
15410
|
collection: collection_1,
|
|
15405
15411
|
path: path_1,
|
|
15406
15412
|
entityId: entityId_1,
|
|
15407
|
-
values:
|
|
15413
|
+
values: values_3,
|
|
15408
15414
|
previousValues: previousValues_0,
|
|
15409
15415
|
autoSave: autoSave_0
|
|
15410
15416
|
}) => {
|
|
15411
15417
|
if (!status) return;
|
|
15412
15418
|
if (autoSave_0) {
|
|
15413
|
-
setValuesToBeSaved(
|
|
15419
|
+
setValuesToBeSaved(values_3);
|
|
15414
15420
|
} else {
|
|
15415
15421
|
return saveEntity({
|
|
15416
15422
|
collection: collection_1,
|
|
15417
15423
|
path: path_1,
|
|
15418
15424
|
entityId: entityId_1,
|
|
15419
|
-
values:
|
|
15425
|
+
values: values_3,
|
|
15420
15426
|
previousValues: previousValues_0
|
|
15421
15427
|
});
|
|
15422
15428
|
}
|
|
15423
15429
|
};
|
|
15424
15430
|
const lastSavedValues = React.useRef(entity?.values);
|
|
15425
|
-
const save = (
|
|
15426
|
-
lastSavedValues.current =
|
|
15431
|
+
const save = (values_4) => {
|
|
15432
|
+
lastSavedValues.current = values_4;
|
|
15427
15433
|
return onSaveEntityRequest({
|
|
15428
15434
|
collection: resolvedCollection,
|
|
15429
15435
|
path,
|
|
15430
15436
|
entityId,
|
|
15431
|
-
values:
|
|
15437
|
+
values: values_4,
|
|
15432
15438
|
previousValues: entity?.values,
|
|
15433
15439
|
autoSave: autoSave ?? false
|
|
15434
|
-
}).then((
|
|
15440
|
+
}).then(() => {
|
|
15435
15441
|
const eventName = status === "new" ? "new_entity_saved" : status === "copy" ? "entity_copied" : status === "existing" ? "entity_edited" : "unmapped_event";
|
|
15436
15442
|
analyticsController.onAnalyticsEvent?.(eventName, {
|
|
15437
15443
|
path
|
|
@@ -15465,7 +15471,8 @@
|
|
|
15465
15471
|
type: "error",
|
|
15466
15472
|
message: "Error updating id, check the console"
|
|
15467
15473
|
});
|
|
15468
|
-
|
|
15474
|
+
console.error(error);
|
|
15475
|
+
}, [snackbarController]);
|
|
15469
15476
|
const pluginActions = [];
|
|
15470
15477
|
const plugins = customizationController.plugins;
|
|
15471
15478
|
const actionsDisabled = disabled || formex$1.isSubmitting || status === "existing" && !formex$1.dirty || Boolean(disabledProp);
|
|
@@ -15514,20 +15521,12 @@
|
|
|
15514
15521
|
onValuesModified?.(modified);
|
|
15515
15522
|
}
|
|
15516
15523
|
}, [formex$1.dirty]);
|
|
15517
|
-
const deferredValues = React.useDeferredValue(formex$1.values);
|
|
15518
15524
|
const modified = formex$1.dirty;
|
|
15519
15525
|
const uniqueFieldValidator = React.useCallback(({
|
|
15520
15526
|
name,
|
|
15521
|
-
value
|
|
15522
|
-
property
|
|
15527
|
+
value
|
|
15523
15528
|
}) => dataSource.checkUniqueField(path, name, value, entityId, collection), [dataSource, path, entityId]);
|
|
15524
15529
|
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
15530
|
useOnAutoSave(autoSave, formex$1, lastSavedValues, save);
|
|
15532
15531
|
React.useEffect(() => {
|
|
15533
15532
|
if (!autoSave && !formex$1.isSubmitting && underlyingChanges && entity) {
|
|
@@ -15546,18 +15545,18 @@
|
|
|
15546
15545
|
return /* @__PURE__ */ jsxRuntime.jsx(Builder, { collection, entity, modifiedValues: formex$1.values, formContext });
|
|
15547
15546
|
}
|
|
15548
15547
|
return /* @__PURE__ */ jsxRuntime.jsx(FormLayout, { children: formFieldKeys.map((key_1) => {
|
|
15549
|
-
const
|
|
15550
|
-
if (
|
|
15548
|
+
const property = resolvedCollection.properties[key_1];
|
|
15549
|
+
if (property) {
|
|
15551
15550
|
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(
|
|
15551
|
+
const disabled_0 = disabledProp || !autoSave && formex$1.isSubmitting || isReadOnly(property) || Boolean(property.disabled);
|
|
15552
|
+
const hidden = isHidden(property);
|
|
15554
15553
|
if (hidden) return null;
|
|
15555
|
-
const widthPercentage =
|
|
15554
|
+
const widthPercentage = property.widthPercentage ?? 100;
|
|
15556
15555
|
const cmsFormFieldProps = {
|
|
15557
15556
|
propertyKey: key_1,
|
|
15558
15557
|
disabled: disabled_0,
|
|
15559
|
-
property
|
|
15560
|
-
includeDescription:
|
|
15558
|
+
property,
|
|
15559
|
+
includeDescription: property.description || property.longDescription,
|
|
15561
15560
|
underlyingValueHasChanged: underlyingValueHasChanged && !autoSave,
|
|
15562
15561
|
context: formContext,
|
|
15563
15562
|
partOfArray: false,
|
|
@@ -15613,7 +15612,7 @@
|
|
|
15613
15612
|
}
|
|
15614
15613
|
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
15614
|
return /* @__PURE__ */ jsxRuntime.jsx(formex.Formex, { value: formex$1, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: formex$1.handleSubmit, onReset: () => formex$1.resetForm({
|
|
15616
|
-
values:
|
|
15615
|
+
values: baseInitialValues
|
|
15617
15616
|
}), noValidate: true, className: ui.cls("flex-1 flex flex-row w-full overflow-y-auto justify-center", className), children: [
|
|
15618
15617
|
/* @__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
15618
|
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 +22825,14 @@
|
|
|
22826
22825
|
collection,
|
|
22827
22826
|
context,
|
|
22828
22827
|
sideEntityController,
|
|
22829
|
-
isSubmitting: formex2.isSubmitting,
|
|
22830
22828
|
disabled,
|
|
22831
22829
|
status,
|
|
22832
22830
|
sideDialogContext,
|
|
22833
22831
|
pluginActions,
|
|
22834
22832
|
openEntityMode,
|
|
22835
22833
|
navigateBack,
|
|
22836
|
-
formContext
|
|
22834
|
+
formContext,
|
|
22835
|
+
formex: formex2
|
|
22837
22836
|
}) : buildSideActions({
|
|
22838
22837
|
savingError,
|
|
22839
22838
|
entity,
|
|
@@ -22841,14 +22840,14 @@
|
|
|
22841
22840
|
collection,
|
|
22842
22841
|
context,
|
|
22843
22842
|
sideEntityController,
|
|
22844
|
-
isSubmitting: formex2.isSubmitting,
|
|
22845
22843
|
sideDialogContext,
|
|
22846
22844
|
disabled,
|
|
22847
22845
|
status,
|
|
22848
22846
|
pluginActions,
|
|
22849
22847
|
openEntityMode,
|
|
22850
22848
|
navigateBack,
|
|
22851
|
-
formContext
|
|
22849
|
+
formContext,
|
|
22850
|
+
formex: formex2
|
|
22852
22851
|
});
|
|
22853
22852
|
}
|
|
22854
22853
|
function buildBottomActions({
|
|
@@ -22858,15 +22857,16 @@
|
|
|
22858
22857
|
collection,
|
|
22859
22858
|
context,
|
|
22860
22859
|
sideEntityController,
|
|
22861
|
-
isSubmitting,
|
|
22862
22860
|
disabled,
|
|
22863
22861
|
status,
|
|
22864
22862
|
sideDialogContext,
|
|
22865
22863
|
pluginActions,
|
|
22866
22864
|
openEntityMode,
|
|
22867
22865
|
navigateBack,
|
|
22868
|
-
formContext
|
|
22866
|
+
formContext,
|
|
22867
|
+
formex: formex2
|
|
22869
22868
|
}) {
|
|
22869
|
+
const hasErrors = Object.keys(formex2.errors).length > 0 && formex2.submitCount > 0;
|
|
22870
22870
|
const canClose = openEntityMode === "side_panel";
|
|
22871
22871
|
return /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { position: "absolute", children: [
|
|
22872
22872
|
savingError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "error", children: savingError.message }) }),
|
|
@@ -22886,15 +22886,16 @@
|
|
|
22886
22886
|
return /* @__PURE__ */ jsxRuntime.jsx(EntityActionButton, { action, enabled: isEnabled, props }, action.key);
|
|
22887
22887
|
}) }),
|
|
22888
22888
|
pluginActions,
|
|
22889
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22890
|
-
/* @__PURE__ */ jsxRuntime.
|
|
22889
|
+
hasErrors ? /* @__PURE__ */ jsxRuntime.jsx(ErrorTooltip, { title: "This form has errors", children: /* @__PURE__ */ jsxRuntime.jsx(ui.ErrorIcon, { className: "ml-4", color: "error", size: "smallest" }) }) : null,
|
|
22890
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", color: "primary", disabled: disabled || formex2.isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
22891
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: canClose ? "text" : "filled", color: "primary", type: "submit", disabled: disabled || formex2.isSubmitting, onClick: () => {
|
|
22891
22892
|
sideDialogContext.setPendingClose(false);
|
|
22892
22893
|
}, children: [
|
|
22893
22894
|
status === "existing" && "Save",
|
|
22894
22895
|
status === "copy" && "Create copy",
|
|
22895
22896
|
status === "new" && "Create"
|
|
22896
22897
|
] }),
|
|
22897
|
-
canClose && /* @__PURE__ */ jsxRuntime.jsxs(ui.LoadingButton, { variant: "filled", color: "primary", type: "submit", loading: isSubmitting, disabled, onClick: () => {
|
|
22898
|
+
canClose && /* @__PURE__ */ jsxRuntime.jsxs(ui.LoadingButton, { variant: "filled", color: "primary", type: "submit", loading: formex2.isSubmitting, disabled, onClick: () => {
|
|
22898
22899
|
sideDialogContext.setPendingClose?.(true);
|
|
22899
22900
|
}, children: [
|
|
22900
22901
|
status === "existing" && "Save and close",
|
|
@@ -22910,24 +22911,25 @@
|
|
|
22910
22911
|
collection,
|
|
22911
22912
|
context,
|
|
22912
22913
|
sideEntityController,
|
|
22913
|
-
isSubmitting,
|
|
22914
22914
|
disabled,
|
|
22915
22915
|
status,
|
|
22916
22916
|
sideDialogContext,
|
|
22917
22917
|
pluginActions,
|
|
22918
22918
|
openEntityMode,
|
|
22919
22919
|
navigateBack,
|
|
22920
|
-
formContext
|
|
22920
|
+
formContext,
|
|
22921
|
+
formex: formex2
|
|
22921
22922
|
}) {
|
|
22923
|
+
const hasErrors = Object.keys(formex2.errors).length > 0 && formex2.submitCount > 0;
|
|
22922
22924
|
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: () => {
|
|
22925
|
+
/* @__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
22926
|
sideDialogContext.setPendingClose?.(false);
|
|
22925
22927
|
}, children: [
|
|
22926
22928
|
status === "existing" && "Save",
|
|
22927
22929
|
status === "copy" && "Create copy",
|
|
22928
22930
|
status === "new" && "Create"
|
|
22929
22931
|
] }),
|
|
22930
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { fullWidth: true, variant: "text", disabled: disabled || isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
22932
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { fullWidth: true, variant: "text", disabled: disabled || formex2.isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
|
|
22931
22933
|
pluginActions,
|
|
22932
22934
|
formActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row flex-wrap mt-2", children: formActions.map((action) => {
|
|
22933
22935
|
const props = {
|
|
@@ -23155,7 +23157,8 @@
|
|
|
23155
23157
|
databaseId: props.databaseId,
|
|
23156
23158
|
useCache: false
|
|
23157
23159
|
});
|
|
23158
|
-
const
|
|
23160
|
+
const enableLocalChangesBackup = props.collection.enableLocalChangesBackup !== void 0 ? props.collection.enableLocalChangesBackup : true;
|
|
23161
|
+
const initialDirtyValues = entityId ? getEntityFromCache(props.path + "/" + entityId, enableLocalChangesBackup) : getEntityFromCache(props.path + "#new", enableLocalChangesBackup);
|
|
23159
23162
|
const authController = useAuthController();
|
|
23160
23163
|
const initialStatus = props.copy ? "copy" : entityId ? "existing" : "new";
|
|
23161
23164
|
const [status, setStatus] = React.useState(initialStatus);
|
|
@@ -23166,13 +23169,13 @@
|
|
|
23166
23169
|
return entity ? canEditEntity(props.collection, authController, props.path, entity ?? null) : void 0;
|
|
23167
23170
|
}
|
|
23168
23171
|
}, [authController, entity, status]);
|
|
23169
|
-
if (dataLoading && !
|
|
23172
|
+
if (dataLoading && !initialDirtyValues || (!entity || canEdit === void 0) && (status === "existing" || status === "copy")) {
|
|
23170
23173
|
return /* @__PURE__ */ jsxRuntime.jsx(CircularProgressCenter, {});
|
|
23171
23174
|
}
|
|
23172
|
-
if (entityId && !entity && !
|
|
23175
|
+
if (entityId && !entity && !initialDirtyValues) {
|
|
23173
23176
|
console.error(`Entity with id ${entityId} not found in collection ${props.path}`);
|
|
23174
23177
|
}
|
|
23175
|
-
return /* @__PURE__ */ jsxRuntime.jsx(EntityEditViewInner, { ...props, entityId, entity,
|
|
23178
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EntityEditViewInner, { ...props, entityId, entity, initialDirtyValues, dataLoading, status, setStatus, canEdit });
|
|
23176
23179
|
}
|
|
23177
23180
|
function EntityEditViewInner({
|
|
23178
23181
|
path,
|
|
@@ -23185,7 +23188,7 @@
|
|
|
23185
23188
|
onSaved,
|
|
23186
23189
|
onTabChange,
|
|
23187
23190
|
entity,
|
|
23188
|
-
|
|
23191
|
+
initialDirtyValues,
|
|
23189
23192
|
dataLoading,
|
|
23190
23193
|
layout = "side_panel",
|
|
23191
23194
|
barActions,
|
|
@@ -23313,7 +23316,7 @@
|
|
|
23313
23316
|
/* @__PURE__ */ jsxRuntime.jsx(EntityView, { className: "px-8 h-full overflow-auto", entity, path, collection }),
|
|
23314
23317
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-16" })
|
|
23315
23318
|
] }) }) : null;
|
|
23316
|
-
const entityView = /* @__PURE__ */ jsxRuntime.jsx(EntityForm, { fullIdPath, collection, path, entityId: entityId ?? usedEntity?.id, onValuesModified, entity, initialDirtyValues
|
|
23319
|
+
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
23320
|
setUsedEntity(entity_0);
|
|
23318
23321
|
formProps?.onEntityChange?.(entity_0);
|
|
23319
23322
|
}, onStatusChange: (status_0) => {
|