@firecms/core 3.0.0-canary.285 → 3.0.0-canary.287
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 +8 -2
- package/dist/form/EntityForm.d.ts +1 -1
- package/dist/form/components/LocalChangesMenu.d.ts +11 -0
- package/dist/index.es.js +363 -45
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +361 -43
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collections.d.ts +10 -6
- package/dist/util/collections.d.ts +1 -0
- package/dist/util/entity_cache.d.ts +5 -2
- package/package.json +5 -5
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +5 -2
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +1 -1
- package/src/core/EntityEditView.tsx +20 -8
- package/src/core/EntitySidePanel.tsx +9 -3
- package/src/form/EntityForm.tsx +77 -22
- package/src/form/components/LocalChangesMenu.tsx +157 -0
- package/src/types/collections.ts +10 -6
- package/src/util/collections.ts +8 -0
- package/src/util/createFormexStub.tsx +4 -0
- package/src/util/entity_cache.ts +18 -22
package/dist/index.umd.js
CHANGED
|
@@ -1052,6 +1052,12 @@
|
|
|
1052
1052
|
};
|
|
1053
1053
|
});
|
|
1054
1054
|
};
|
|
1055
|
+
function getLocalChangesBackup(collection) {
|
|
1056
|
+
if (!collection.localChangesBackup) {
|
|
1057
|
+
return "manual_apply";
|
|
1058
|
+
}
|
|
1059
|
+
return collection.localChangesBackup;
|
|
1060
|
+
}
|
|
1055
1061
|
const kebabCaseRegex = /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g;
|
|
1056
1062
|
const toKebabCase = (str) => {
|
|
1057
1063
|
const regExpMatchArray = str.match(kebabCaseRegex);
|
|
@@ -9755,7 +9761,6 @@
|
|
|
9755
9761
|
return value;
|
|
9756
9762
|
}
|
|
9757
9763
|
function saveEntityToCache(path, data) {
|
|
9758
|
-
entityCache.set(path, data);
|
|
9759
9764
|
if (isLocalStorageAvailable) {
|
|
9760
9765
|
try {
|
|
9761
9766
|
const key = LOCAL_STORAGE_PREFIX + path;
|
|
@@ -9766,17 +9771,22 @@
|
|
|
9766
9771
|
}
|
|
9767
9772
|
}
|
|
9768
9773
|
}
|
|
9769
|
-
function
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
+
function removeEntityFromMemoryCache(path) {
|
|
9775
|
+
entityCache.delete(path);
|
|
9776
|
+
}
|
|
9777
|
+
function saveEntityToMemoryCache(path, data) {
|
|
9778
|
+
entityCache.set(path, data);
|
|
9779
|
+
}
|
|
9780
|
+
function getEntityFromMemoryCache(path) {
|
|
9781
|
+
return entityCache.get(path);
|
|
9782
|
+
}
|
|
9783
|
+
function getEntityFromCache(path) {
|
|
9784
|
+
if (isLocalStorageAvailable) {
|
|
9774
9785
|
try {
|
|
9775
9786
|
const key = LOCAL_STORAGE_PREFIX + path;
|
|
9776
9787
|
const entityString = localStorage.getItem(key);
|
|
9777
9788
|
if (entityString) {
|
|
9778
9789
|
const entity = JSON.parse(entityString, customReviver);
|
|
9779
|
-
entityCache.set(path, entity);
|
|
9780
9790
|
return entity;
|
|
9781
9791
|
}
|
|
9782
9792
|
} catch (error) {
|
|
@@ -9785,12 +9795,7 @@
|
|
|
9785
9795
|
}
|
|
9786
9796
|
return void 0;
|
|
9787
9797
|
}
|
|
9788
|
-
function hasEntityInCache(path) {
|
|
9789
|
-
return entityCache.has(path);
|
|
9790
|
-
}
|
|
9791
9798
|
function removeEntityFromCache(path) {
|
|
9792
|
-
console.debug("Removing entity from cache", path);
|
|
9793
|
-
entityCache.delete(path);
|
|
9794
9799
|
if (isLocalStorageAvailable) {
|
|
9795
9800
|
try {
|
|
9796
9801
|
const key = LOCAL_STORAGE_PREFIX + path;
|
|
@@ -9827,7 +9832,8 @@
|
|
|
9827
9832
|
const hasCollapsedActions = actions.some((a) => a.collapsed || a.collapsed === void 0);
|
|
9828
9833
|
const collapsedActions = actions.filter((a_0) => a_0.collapsed || a_0.collapsed === void 0);
|
|
9829
9834
|
const uncollapsedActions = actions.filter((a_1) => a_1.collapsed === false);
|
|
9830
|
-
const
|
|
9835
|
+
const enableLocalChangesBackup = collection ? getLocalChangesBackup(collection) : false;
|
|
9836
|
+
const hasDraft = enableLocalChangesBackup ? getEntityFromCache(fullPath + "/" + entity.id) : false;
|
|
9831
9837
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("h-full flex items-center justify-center flex-col bg-surface-50 dark:bg-surface-900 bg-opacity-90 dark:bg-opacity-90 z-10", frozen ? "sticky left-0" : ""), onClick: React.useCallback((event) => {
|
|
9832
9838
|
event.stopPropagation();
|
|
9833
9839
|
}, []), style: {
|
|
@@ -15162,6 +15168,273 @@
|
|
|
15162
15168
|
savingError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "error", children: savingError.message }) })
|
|
15163
15169
|
] });
|
|
15164
15170
|
}
|
|
15171
|
+
function LocalChangesMenu(t0) {
|
|
15172
|
+
const $ = reactCompilerRuntime.c(43);
|
|
15173
|
+
const {
|
|
15174
|
+
localChangesData,
|
|
15175
|
+
formex: formex$1,
|
|
15176
|
+
onClearLocalChanges,
|
|
15177
|
+
cacheKey,
|
|
15178
|
+
properties
|
|
15179
|
+
} = t0;
|
|
15180
|
+
const snackbarController = useSnackbarController();
|
|
15181
|
+
const [previewDialogOpen, setPreviewDialogOpen] = React.useState(false);
|
|
15182
|
+
const [open, setOpen] = React.useState(false);
|
|
15183
|
+
let t1;
|
|
15184
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
15185
|
+
t1 = () => {
|
|
15186
|
+
setOpen(true);
|
|
15187
|
+
};
|
|
15188
|
+
$[0] = t1;
|
|
15189
|
+
} else {
|
|
15190
|
+
t1 = $[0];
|
|
15191
|
+
}
|
|
15192
|
+
const handleOpenMenu = t1;
|
|
15193
|
+
let t2;
|
|
15194
|
+
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
|
15195
|
+
t2 = () => {
|
|
15196
|
+
setOpen(false);
|
|
15197
|
+
};
|
|
15198
|
+
$[1] = t2;
|
|
15199
|
+
} else {
|
|
15200
|
+
t2 = $[1];
|
|
15201
|
+
}
|
|
15202
|
+
const handleCloseMenu = t2;
|
|
15203
|
+
let t3;
|
|
15204
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
15205
|
+
t3 = () => {
|
|
15206
|
+
setPreviewDialogOpen(true);
|
|
15207
|
+
handleCloseMenu();
|
|
15208
|
+
};
|
|
15209
|
+
$[2] = t3;
|
|
15210
|
+
} else {
|
|
15211
|
+
t3 = $[2];
|
|
15212
|
+
}
|
|
15213
|
+
const handlePreview = t3;
|
|
15214
|
+
let t4;
|
|
15215
|
+
if ($[3] !== formex$1 || $[4] !== localChangesData || $[5] !== onClearLocalChanges || $[6] !== snackbarController) {
|
|
15216
|
+
t4 = () => {
|
|
15217
|
+
const mergedValues = mergeDeep(formex$1.values, localChangesData);
|
|
15218
|
+
const touched = {
|
|
15219
|
+
...formex$1.touched
|
|
15220
|
+
};
|
|
15221
|
+
const newTouched = formex.flattenKeys(localChangesData);
|
|
15222
|
+
newTouched.forEach((key) => {
|
|
15223
|
+
touched[key] = true;
|
|
15224
|
+
});
|
|
15225
|
+
formex$1.setTouched(touched);
|
|
15226
|
+
formex$1.setValues(mergedValues);
|
|
15227
|
+
snackbarController.open({
|
|
15228
|
+
type: "info",
|
|
15229
|
+
message: "Local changes applied to the form"
|
|
15230
|
+
});
|
|
15231
|
+
handleCloseMenu();
|
|
15232
|
+
onClearLocalChanges?.();
|
|
15233
|
+
};
|
|
15234
|
+
$[3] = formex$1;
|
|
15235
|
+
$[4] = localChangesData;
|
|
15236
|
+
$[5] = onClearLocalChanges;
|
|
15237
|
+
$[6] = snackbarController;
|
|
15238
|
+
$[7] = t4;
|
|
15239
|
+
} else {
|
|
15240
|
+
t4 = $[7];
|
|
15241
|
+
}
|
|
15242
|
+
const handleApply = t4;
|
|
15243
|
+
let t5;
|
|
15244
|
+
if ($[8] !== cacheKey || $[9] !== onClearLocalChanges || $[10] !== snackbarController) {
|
|
15245
|
+
t5 = () => {
|
|
15246
|
+
removeEntityFromCache(cacheKey);
|
|
15247
|
+
snackbarController.open({
|
|
15248
|
+
type: "info",
|
|
15249
|
+
message: "Local changes discarded"
|
|
15250
|
+
});
|
|
15251
|
+
handleCloseMenu();
|
|
15252
|
+
onClearLocalChanges?.();
|
|
15253
|
+
};
|
|
15254
|
+
$[8] = cacheKey;
|
|
15255
|
+
$[9] = onClearLocalChanges;
|
|
15256
|
+
$[10] = snackbarController;
|
|
15257
|
+
$[11] = t5;
|
|
15258
|
+
} else {
|
|
15259
|
+
t5 = $[11];
|
|
15260
|
+
}
|
|
15261
|
+
const handleDiscard = t5;
|
|
15262
|
+
let t6;
|
|
15263
|
+
if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
|
|
15264
|
+
t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.WarningIcon, { size: "smallest", className: "mr-1 text-yellow-600 dark:text-yellow-400" });
|
|
15265
|
+
$[12] = t6;
|
|
15266
|
+
} else {
|
|
15267
|
+
t6 = $[12];
|
|
15268
|
+
}
|
|
15269
|
+
let t7;
|
|
15270
|
+
if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
|
|
15271
|
+
t7 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "small", className: "font-semibold text-xs rounded-full px-4 py-1 bg-yellow-200 dark:bg-yellow-900 hover:bg-yellow-300 dark:hover:bg-yellow-800 text-yellow-800 dark:text-yellow-200", onClick: handleOpenMenu, children: [
|
|
15272
|
+
t6,
|
|
15273
|
+
"Unsaved Local changes",
|
|
15274
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.KeyboardArrowDownIcon, { size: "smallest" })
|
|
15275
|
+
] });
|
|
15276
|
+
$[13] = t7;
|
|
15277
|
+
} else {
|
|
15278
|
+
t7 = $[13];
|
|
15279
|
+
}
|
|
15280
|
+
let t8;
|
|
15281
|
+
if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
|
|
15282
|
+
t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-xs px-4 py-4 text-sm text-gray-700 dark:text-gray-300", children: "This document was edited locally and has unsaved changes." });
|
|
15283
|
+
$[14] = t8;
|
|
15284
|
+
} else {
|
|
15285
|
+
t8 = $[14];
|
|
15286
|
+
}
|
|
15287
|
+
let t9;
|
|
15288
|
+
if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
|
|
15289
|
+
t9 = /* @__PURE__ */ jsxRuntime.jsxs(ui.MenuItem, { dense: true, onClick: handlePreview, children: [
|
|
15290
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.VisibilityIcon, { size: "small" }),
|
|
15291
|
+
"Preview Changes"
|
|
15292
|
+
] });
|
|
15293
|
+
$[15] = t9;
|
|
15294
|
+
} else {
|
|
15295
|
+
t9 = $[15];
|
|
15296
|
+
}
|
|
15297
|
+
let t10;
|
|
15298
|
+
if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
|
|
15299
|
+
t10 = /* @__PURE__ */ jsxRuntime.jsx(ui.CheckIcon, { size: "small" });
|
|
15300
|
+
$[16] = t10;
|
|
15301
|
+
} else {
|
|
15302
|
+
t10 = $[16];
|
|
15303
|
+
}
|
|
15304
|
+
let t11;
|
|
15305
|
+
if ($[17] !== handleApply) {
|
|
15306
|
+
t11 = /* @__PURE__ */ jsxRuntime.jsxs(ui.MenuItem, { dense: true, onClick: handleApply, children: [
|
|
15307
|
+
t10,
|
|
15308
|
+
"Apply Changes"
|
|
15309
|
+
] });
|
|
15310
|
+
$[17] = handleApply;
|
|
15311
|
+
$[18] = t11;
|
|
15312
|
+
} else {
|
|
15313
|
+
t11 = $[18];
|
|
15314
|
+
}
|
|
15315
|
+
let t12;
|
|
15316
|
+
if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
|
|
15317
|
+
t12 = /* @__PURE__ */ jsxRuntime.jsx(ui.CancelIcon, { size: "small" });
|
|
15318
|
+
$[19] = t12;
|
|
15319
|
+
} else {
|
|
15320
|
+
t12 = $[19];
|
|
15321
|
+
}
|
|
15322
|
+
let t13;
|
|
15323
|
+
if ($[20] !== handleDiscard) {
|
|
15324
|
+
t13 = /* @__PURE__ */ jsxRuntime.jsxs(ui.MenuItem, { dense: true, onClick: handleDiscard, children: [
|
|
15325
|
+
t12,
|
|
15326
|
+
"Discard Local Changes"
|
|
15327
|
+
] });
|
|
15328
|
+
$[20] = handleDiscard;
|
|
15329
|
+
$[21] = t13;
|
|
15330
|
+
} else {
|
|
15331
|
+
t13 = $[21];
|
|
15332
|
+
}
|
|
15333
|
+
let t14;
|
|
15334
|
+
if ($[22] !== open || $[23] !== t11 || $[24] !== t13) {
|
|
15335
|
+
t14 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Menu, { trigger: t7, open, onOpenChange: setOpen, children: [
|
|
15336
|
+
t8,
|
|
15337
|
+
t9,
|
|
15338
|
+
t11,
|
|
15339
|
+
t13
|
|
15340
|
+
] });
|
|
15341
|
+
$[22] = open;
|
|
15342
|
+
$[23] = t11;
|
|
15343
|
+
$[24] = t13;
|
|
15344
|
+
$[25] = t14;
|
|
15345
|
+
} else {
|
|
15346
|
+
t14 = $[25];
|
|
15347
|
+
}
|
|
15348
|
+
let t15;
|
|
15349
|
+
let t16;
|
|
15350
|
+
if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
|
|
15351
|
+
t15 = /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-2xl mb-4", children: "Preview Local Changes" });
|
|
15352
|
+
t16 = /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4", children: "These are the local changes that will be applied to the form." });
|
|
15353
|
+
$[26] = t15;
|
|
15354
|
+
$[27] = t16;
|
|
15355
|
+
} else {
|
|
15356
|
+
t15 = $[26];
|
|
15357
|
+
t16 = $[27];
|
|
15358
|
+
}
|
|
15359
|
+
let t17;
|
|
15360
|
+
if ($[28] !== localChangesData || $[29] !== properties) {
|
|
15361
|
+
t17 = formex.flattenKeys(localChangesData).map((key_0) => {
|
|
15362
|
+
const value = formex.getIn(localChangesData, key_0);
|
|
15363
|
+
const property = getPropertyInPath(properties, key_0);
|
|
15364
|
+
if (!property) {
|
|
15365
|
+
return null;
|
|
15366
|
+
}
|
|
15367
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-12 gap-x-4 px-4 py-3 items-center", children: [
|
|
15368
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-3 text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "caption", className: "text-gray-500 dark:text-gray-400 break-words", children: property.name || key_0 }) }),
|
|
15369
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-9", children: /* @__PURE__ */ jsxRuntime.jsx(PropertyPreview, { propertyKey: key_0, value, property, size: "small" }) })
|
|
15370
|
+
] }, key_0);
|
|
15371
|
+
});
|
|
15372
|
+
$[28] = localChangesData;
|
|
15373
|
+
$[29] = properties;
|
|
15374
|
+
$[30] = t17;
|
|
15375
|
+
} else {
|
|
15376
|
+
t17 = $[30];
|
|
15377
|
+
}
|
|
15378
|
+
let t18;
|
|
15379
|
+
if ($[31] !== t17) {
|
|
15380
|
+
t18 = /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { children: [
|
|
15381
|
+
t15,
|
|
15382
|
+
t16,
|
|
15383
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `border rounded-lg divide-y divide-surface-200 divide-surface-opacity-40 dark:divide-surface-700 dark:divide-opacity-40 ${ui.defaultBorderMixin}`, children: t17 })
|
|
15384
|
+
] });
|
|
15385
|
+
$[31] = t17;
|
|
15386
|
+
$[32] = t18;
|
|
15387
|
+
} else {
|
|
15388
|
+
t18 = $[32];
|
|
15389
|
+
}
|
|
15390
|
+
let t19;
|
|
15391
|
+
if ($[33] === Symbol.for("react.memo_cache_sentinel")) {
|
|
15392
|
+
t19 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: () => setPreviewDialogOpen(false), children: "Close" });
|
|
15393
|
+
$[33] = t19;
|
|
15394
|
+
} else {
|
|
15395
|
+
t19 = $[33];
|
|
15396
|
+
}
|
|
15397
|
+
let t20;
|
|
15398
|
+
if ($[34] !== handleApply) {
|
|
15399
|
+
t20 = /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { children: [
|
|
15400
|
+
t19,
|
|
15401
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "filled", onClick: () => {
|
|
15402
|
+
handleApply();
|
|
15403
|
+
setPreviewDialogOpen(false);
|
|
15404
|
+
}, children: "Apply changes" })
|
|
15405
|
+
] });
|
|
15406
|
+
$[34] = handleApply;
|
|
15407
|
+
$[35] = t20;
|
|
15408
|
+
} else {
|
|
15409
|
+
t20 = $[35];
|
|
15410
|
+
}
|
|
15411
|
+
let t21;
|
|
15412
|
+
if ($[36] !== previewDialogOpen || $[37] !== t18 || $[38] !== t20) {
|
|
15413
|
+
t21 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Dialog, { open: previewDialogOpen, onOpenChange: setPreviewDialogOpen, maxWidth: "4xl", children: [
|
|
15414
|
+
t18,
|
|
15415
|
+
t20
|
|
15416
|
+
] });
|
|
15417
|
+
$[36] = previewDialogOpen;
|
|
15418
|
+
$[37] = t18;
|
|
15419
|
+
$[38] = t20;
|
|
15420
|
+
$[39] = t21;
|
|
15421
|
+
} else {
|
|
15422
|
+
t21 = $[39];
|
|
15423
|
+
}
|
|
15424
|
+
let t22;
|
|
15425
|
+
if ($[40] !== t14 || $[41] !== t21) {
|
|
15426
|
+
t22 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
15427
|
+
t14,
|
|
15428
|
+
t21
|
|
15429
|
+
] });
|
|
15430
|
+
$[40] = t14;
|
|
15431
|
+
$[41] = t21;
|
|
15432
|
+
$[42] = t22;
|
|
15433
|
+
} else {
|
|
15434
|
+
t22 = $[42];
|
|
15435
|
+
}
|
|
15436
|
+
return t22;
|
|
15437
|
+
}
|
|
15165
15438
|
function extractTouchedValues(values, touched) {
|
|
15166
15439
|
let acc = {};
|
|
15167
15440
|
if (!touched || typeof touched !== "object") {
|
|
@@ -15249,6 +15522,12 @@
|
|
|
15249
15522
|
const [entityIdError, setEntityIdError] = React.useState(false);
|
|
15250
15523
|
const [savingError, setSavingError] = React.useState();
|
|
15251
15524
|
const autoSave = collection.formAutoSave && !collection.customId;
|
|
15525
|
+
const baseInitialValues = React.useMemo(() => getInitialEntityValues(authController, collection, path, status, entity, customizationController.propertyConfigs), [authController, collection, path, status, entity, customizationController.propertyConfigs]);
|
|
15526
|
+
const localChangesDataRaw = React.useMemo(() => entityId ? getEntityFromCache(path + "/" + entityId) : getEntityFromCache(path + "#new"), [entityId, path]);
|
|
15527
|
+
const [localChangesCleared, setLocalChangesCleared] = React.useState(false);
|
|
15528
|
+
const localChangesBackup = getLocalChangesBackup(collection);
|
|
15529
|
+
const autoApplyLocalChanges = localChangesBackup === "auto_apply";
|
|
15530
|
+
const manualApplyLocalChanges = localChangesBackup === "manual_apply";
|
|
15252
15531
|
const onSubmit = (values, formexController) => {
|
|
15253
15532
|
if (mustSetCustomId && !entityId) {
|
|
15254
15533
|
console.error("Missing custom Id");
|
|
@@ -15279,12 +15558,31 @@
|
|
|
15279
15558
|
formexController.setSubmitting(false);
|
|
15280
15559
|
});
|
|
15281
15560
|
};
|
|
15282
|
-
const
|
|
15283
|
-
|
|
15284
|
-
|
|
15561
|
+
const [initialValues_0, initialDirty_0] = React.useMemo(() => {
|
|
15562
|
+
const initialValuesWithLocalChanges = autoApplyLocalChanges && localChangesDataRaw ? mergeDeep(baseInitialValues, localChangesDataRaw) : baseInitialValues;
|
|
15563
|
+
const initialValues = initialDirtyValues ? mergeDeep(initialValuesWithLocalChanges, initialDirtyValues) : initialValuesWithLocalChanges;
|
|
15564
|
+
const initialDirty = Boolean(initialDirtyValues) && initialDirtyValues && Object.keys(initialDirtyValues).length > 0;
|
|
15565
|
+
return [initialValues, initialDirty];
|
|
15566
|
+
}, [autoApplyLocalChanges, localChangesDataRaw, baseInitialValues, initialDirtyValues]);
|
|
15567
|
+
const localChangesData = React.useMemo(() => {
|
|
15568
|
+
if (!localChangesDataRaw) {
|
|
15569
|
+
return void 0;
|
|
15570
|
+
}
|
|
15571
|
+
let filteredChanges = {};
|
|
15572
|
+
const flattenedKeys = formex.flattenKeys(localChangesDataRaw);
|
|
15573
|
+
flattenedKeys.forEach((key) => {
|
|
15574
|
+
const localValue = formex.getIn(localChangesDataRaw, key);
|
|
15575
|
+
const initialValue = formex.getIn(initialValues_0, key);
|
|
15576
|
+
if (!equal(localValue, initialValue)) {
|
|
15577
|
+
filteredChanges = formex.setIn(filteredChanges, key, localValue);
|
|
15578
|
+
}
|
|
15579
|
+
});
|
|
15580
|
+
return filteredChanges;
|
|
15581
|
+
}, [localChangesDataRaw, initialValues_0]);
|
|
15582
|
+
const hasLocalChanges = !localChangesCleared && localChangesData && Object.keys(localChangesData).length > 0;
|
|
15285
15583
|
const formex$1 = formexProp ?? formex.useCreateFormex({
|
|
15286
|
-
initialValues,
|
|
15287
|
-
initialDirty,
|
|
15584
|
+
initialValues: initialValues_0,
|
|
15585
|
+
initialDirty: initialDirty_0,
|
|
15288
15586
|
initialTouched: initialDirtyValues ? formex.flattenKeys(initialDirtyValues).reduce((previousValue, currentValue) => ({
|
|
15289
15587
|
...previousValue,
|
|
15290
15588
|
[currentValue]: true
|
|
@@ -15292,13 +15590,13 @@
|
|
|
15292
15590
|
onSubmit,
|
|
15293
15591
|
onReset: () => {
|
|
15294
15592
|
clearDirtyCache();
|
|
15295
|
-
onValuesModified?.(false);
|
|
15593
|
+
onValuesModified?.(false, initialValues_0);
|
|
15296
15594
|
},
|
|
15297
15595
|
onValuesChangeDeferred: (values_0, controller) => {
|
|
15298
|
-
const
|
|
15596
|
+
const key_0 = status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId;
|
|
15299
15597
|
if (controller.dirty) {
|
|
15300
15598
|
const touchedValues = extractTouchedValues(values_0, controller.touched);
|
|
15301
|
-
saveEntityToCache(
|
|
15599
|
+
saveEntityToCache(key_0, touchedValues);
|
|
15302
15600
|
}
|
|
15303
15601
|
},
|
|
15304
15602
|
validation: (values_1) => {
|
|
@@ -15351,14 +15649,16 @@
|
|
|
15351
15649
|
}, [snackbarController]);
|
|
15352
15650
|
function clearDirtyCache() {
|
|
15353
15651
|
if (status === "new" || status === "copy") {
|
|
15652
|
+
removeEntityFromMemoryCache(path + "#new");
|
|
15354
15653
|
removeEntityFromCache(path + "#new");
|
|
15355
15654
|
} else {
|
|
15655
|
+
removeEntityFromMemoryCache(path + "/" + entityId);
|
|
15356
15656
|
removeEntityFromCache(path + "/" + entityId);
|
|
15357
15657
|
}
|
|
15358
15658
|
}
|
|
15359
15659
|
const onSaveSuccess = (updatedEntity) => {
|
|
15360
15660
|
clearDirtyCache();
|
|
15361
|
-
onValuesModified?.(false);
|
|
15661
|
+
onValuesModified?.(false, updatedEntity.values);
|
|
15362
15662
|
if (!autoSave) snackbarController.open({
|
|
15363
15663
|
type: "success",
|
|
15364
15664
|
message: `${collection.singularName ?? collection.name}: Saved correctly`
|
|
@@ -15518,7 +15818,7 @@
|
|
|
15518
15818
|
}, [doOnIdUpdate]);
|
|
15519
15819
|
React.useEffect(() => {
|
|
15520
15820
|
if (!autoSave) {
|
|
15521
|
-
onValuesModified?.(modified);
|
|
15821
|
+
onValuesModified?.(modified, formex$1.values);
|
|
15522
15822
|
}
|
|
15523
15823
|
}, [formex$1.dirty]);
|
|
15524
15824
|
const modified = formex$1.dirty;
|
|
@@ -15530,11 +15830,11 @@
|
|
|
15530
15830
|
useOnAutoSave(autoSave, formex$1, lastSavedValues, save);
|
|
15531
15831
|
React.useEffect(() => {
|
|
15532
15832
|
if (!autoSave && !formex$1.isSubmitting && underlyingChanges && entity) {
|
|
15533
|
-
Object.entries(underlyingChanges).forEach(([
|
|
15534
|
-
const formValue = formex$1.values[
|
|
15535
|
-
if (!equal(value_0, formValue) && !formex$1.touched[
|
|
15536
|
-
console.debug("Updated value from the datasource:",
|
|
15537
|
-
formex$1.setFieldValue(
|
|
15833
|
+
Object.entries(underlyingChanges).forEach(([key_1, value_0]) => {
|
|
15834
|
+
const formValue = formex$1.values[key_1];
|
|
15835
|
+
if (!equal(value_0, formValue) && !formex$1.touched[key_1]) {
|
|
15836
|
+
console.debug("Updated value from the datasource:", key_1, value_0);
|
|
15837
|
+
formex$1.setFieldValue(key_1, value_0 !== void 0 ? value_0 : null);
|
|
15538
15838
|
}
|
|
15539
15839
|
});
|
|
15540
15840
|
}
|
|
@@ -15544,16 +15844,16 @@
|
|
|
15544
15844
|
if (Builder) {
|
|
15545
15845
|
return /* @__PURE__ */ jsxRuntime.jsx(Builder, { collection, entity, modifiedValues: formex$1.values, formContext });
|
|
15546
15846
|
}
|
|
15547
|
-
return /* @__PURE__ */ jsxRuntime.jsx(FormLayout, { children: formFieldKeys.map((
|
|
15548
|
-
const property = resolvedCollection.properties[
|
|
15847
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FormLayout, { children: formFieldKeys.map((key_2) => {
|
|
15848
|
+
const property = resolvedCollection.properties[key_2];
|
|
15549
15849
|
if (property) {
|
|
15550
|
-
const underlyingValueHasChanged = !!underlyingChanges && Object.keys(underlyingChanges).includes(
|
|
15850
|
+
const underlyingValueHasChanged = !!underlyingChanges && Object.keys(underlyingChanges).includes(key_2) && formex$1.touched[key_2];
|
|
15551
15851
|
const disabled_0 = disabledProp || !autoSave && formex$1.isSubmitting || isReadOnly(property) || Boolean(property.disabled);
|
|
15552
15852
|
const hidden = isHidden(property);
|
|
15553
15853
|
if (hidden) return null;
|
|
15554
15854
|
const widthPercentage = property.widthPercentage ?? 100;
|
|
15555
15855
|
const cmsFormFieldProps = {
|
|
15556
|
-
propertyKey:
|
|
15856
|
+
propertyKey: key_2,
|
|
15557
15857
|
disabled: disabled_0,
|
|
15558
15858
|
property,
|
|
15559
15859
|
includeDescription: property.description || property.longDescription,
|
|
@@ -15563,9 +15863,9 @@
|
|
|
15563
15863
|
minimalistView: false,
|
|
15564
15864
|
autoFocus: false
|
|
15565
15865
|
};
|
|
15566
|
-
return /* @__PURE__ */ jsxRuntime.jsx(FormEntry, { propertyKey:
|
|
15866
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FormEntry, { propertyKey: key_2, widthPercentage, children: /* @__PURE__ */ jsxRuntime.jsx(PropertyFieldBinding, { ...cmsFormFieldProps }) }, `field_${key_2}`);
|
|
15567
15867
|
}
|
|
15568
|
-
const additionalField = resolvedCollection.additionalFields?.find((f) => f.key ===
|
|
15868
|
+
const additionalField = resolvedCollection.additionalFields?.find((f) => f.key === key_2);
|
|
15569
15869
|
if (additionalField && entity) {
|
|
15570
15870
|
const Builder_0 = additionalField.Builder;
|
|
15571
15871
|
if (!Builder_0 && !additionalField.value) {
|
|
@@ -15576,11 +15876,11 @@
|
|
|
15576
15876
|
context
|
|
15577
15877
|
})?.toString() });
|
|
15578
15878
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
15579
|
-
/* @__PURE__ */ jsxRuntime.jsx(LabelWithIconAndTooltip, { propertyKey:
|
|
15879
|
+
/* @__PURE__ */ jsxRuntime.jsx(LabelWithIconAndTooltip, { propertyKey: key_2, icon: /* @__PURE__ */ jsxRuntime.jsx(ui.NotesIcon, { size: "small" }), title: additionalField.name, className: "text-text-secondary dark:text-text-secondary-dark ml-3.5" }),
|
|
15580
15880
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls(ui.paperMixin, "w-full min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar"), children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: child }) })
|
|
15581
|
-
] }, `additional_${
|
|
15881
|
+
] }, `additional_${key_2}`);
|
|
15582
15882
|
}
|
|
15583
|
-
console.warn(`Property ${
|
|
15883
|
+
console.warn(`Property ${key_2} not found in collection ${resolvedCollection.name} in properties or additional fields. Skipping.`);
|
|
15584
15884
|
return null;
|
|
15585
15885
|
}).filter(Boolean) });
|
|
15586
15886
|
};
|
|
@@ -15615,7 +15915,10 @@
|
|
|
15615
15915
|
values: baseInitialValues
|
|
15616
15916
|
}), noValidate: true, className: ui.cls("flex-1 flex flex-row w-full overflow-y-auto justify-center", className), children: [
|
|
15617
15917
|
/* @__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: [
|
|
15618
|
-
|
|
15918
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row gap-4 self-end sticky top-4 z-10", children: [
|
|
15919
|
+
manualApplyLocalChanges && hasLocalChanges && /* @__PURE__ */ jsxRuntime.jsx(LocalChangesMenu, { cacheKey: status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId, properties: resolvedCollection.properties, localChangesData, formex: formex$1, onClearLocalChanges: () => setLocalChangesCleared(true) }),
|
|
15920
|
+
formex$1.dirty ? /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "There are local unsaved changes", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { size: "small", colorScheme: "orangeDarker", children: /* @__PURE__ */ jsxRuntime.jsx(ui.EditIcon, { size: "smallest" }) }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "The current form is in sync with the database", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { size: "small", children: /* @__PURE__ */ jsxRuntime.jsx(ui.CheckIcon, { size: "smallest" }) }) })
|
|
15921
|
+
] }),
|
|
15619
15922
|
formView
|
|
15620
15923
|
] }) }),
|
|
15621
15924
|
dialogActions
|
|
@@ -20425,7 +20728,7 @@
|
|
|
20425
20728
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "subtitle2", children: "So empty..." }),
|
|
20426
20729
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { color: "primary", variant: "outlined", onClick: onNewClick, className: "mt-4", children: [
|
|
20427
20730
|
/* @__PURE__ */ jsxRuntime.jsx(ui.AddIcon, {}),
|
|
20428
|
-
"Create your first
|
|
20731
|
+
"Create your first entry"
|
|
20429
20732
|
] })
|
|
20430
20733
|
] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "label", children: "No results with the applied filter/sort" }), hoverRow, inlineEditing: checkInlineEditing(), AdditionalHeaderWidget: buildAdditionalHeaderWidget, AddColumnComponent: addColumnComponentInternal, getIdColumnWidth, additionalIDHeaderWidget: /* @__PURE__ */ jsxRuntime.jsx(EntityIdHeaderWidget, { path: fullPath, fullIdPath: fullIdPath ?? fullPath, collection }), openEntityMode }, `collection_table_${fullPath}`),
|
|
20431
20734
|
popupCell && /* @__PURE__ */ jsxRuntime.jsx(PopupFormField, { open: Boolean(popupCell), onClose: onPopupClose, cellRect: popupCell?.cellRect, propertyKey: popupCell?.propertyKey, collection, entityId: popupCell.entityId, tableKey: tableKey.current, customFieldValidator: uniqueFieldValidator, path: resolvedFullPath, onCellValueChange: onValueChange, container: containerRef.current }, `popup_form_${popupCell?.propertyKey}_${popupCell?.entityId}`),
|
|
@@ -23084,6 +23387,7 @@
|
|
|
23084
23387
|
function createFormexStub(values) {
|
|
23085
23388
|
const errorMessage = "You are in a read-only context. You cannot modify the formex controller.";
|
|
23086
23389
|
return {
|
|
23390
|
+
debugId: "",
|
|
23087
23391
|
values,
|
|
23088
23392
|
initialValues: values,
|
|
23089
23393
|
touched: {},
|
|
@@ -23098,6 +23402,9 @@
|
|
|
23098
23402
|
setValues: () => {
|
|
23099
23403
|
throw new Error(errorMessage);
|
|
23100
23404
|
},
|
|
23405
|
+
setTouched(touched) {
|
|
23406
|
+
throw new Error(errorMessage);
|
|
23407
|
+
},
|
|
23101
23408
|
setFieldValue: () => {
|
|
23102
23409
|
throw new Error(errorMessage);
|
|
23103
23410
|
},
|
|
@@ -23157,8 +23464,7 @@
|
|
|
23157
23464
|
databaseId: props.databaseId,
|
|
23158
23465
|
useCache: false
|
|
23159
23466
|
});
|
|
23160
|
-
const
|
|
23161
|
-
const initialDirtyValues = entityId ? getEntityFromCache(props.path + "/" + entityId, enableLocalChangesBackup) : getEntityFromCache(props.path + "#new", enableLocalChangesBackup);
|
|
23467
|
+
const initialDirtyValues = entityId ? getEntityFromMemoryCache(props.path + "/" + entityId) : getEntityFromMemoryCache(props.path + "#new");
|
|
23162
23468
|
const authController = useAuthController();
|
|
23163
23469
|
const initialStatus = props.copy ? "copy" : entityId ? "existing" : "new";
|
|
23164
23470
|
const [status, setStatus] = React.useState(initialStatus);
|
|
@@ -23317,6 +23623,7 @@
|
|
|
23317
23623
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-16" })
|
|
23318
23624
|
] }) }) : null;
|
|
23319
23625
|
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) => {
|
|
23626
|
+
console.log("333 EntityEditView onEntityChange:", entity_0);
|
|
23320
23627
|
setUsedEntity(entity_0);
|
|
23321
23628
|
formProps?.onEntityChange?.(entity_0);
|
|
23322
23629
|
}, onStatusChange: (status_0) => {
|
|
@@ -23339,7 +23646,12 @@
|
|
|
23339
23646
|
const shouldShowTopBar = Boolean(barActions) || hasAdditionalViews;
|
|
23340
23647
|
let result = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col h-full w-full bg-white dark:bg-surface-900", children: [
|
|
23341
23648
|
shouldShowTopBar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("h-14 items-center flex overflow-visible overflow-x-scroll w-full no-scrollbar h-14 border-b pl-2 pr-2 pt-1 flex bg-surface-50 dark:bg-surface-900", ui.defaultBorderMixin), children: [
|
|
23342
|
-
barActions
|
|
23649
|
+
barActions?.({
|
|
23650
|
+
path: fullIdPath ?? path,
|
|
23651
|
+
entityId,
|
|
23652
|
+
values: formContext?.values ?? usedEntity?.values ?? {},
|
|
23653
|
+
status
|
|
23654
|
+
}),
|
|
23343
23655
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow" }),
|
|
23344
23656
|
pluginActionsTop,
|
|
23345
23657
|
globalLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "self-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.CircularProgress, { size: "small" }) }),
|
|
@@ -23442,9 +23754,14 @@
|
|
|
23442
23754
|
if (!props || !collection) {
|
|
23443
23755
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full" });
|
|
23444
23756
|
}
|
|
23445
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(EntityEditView, { ...props, fullIdPath, layout: "side_panel", collection, parentCollectionIds, onValuesModified, onSaved: onUpdate, barActions:
|
|
23757
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(EntityEditView, { ...props, fullIdPath, layout: "side_panel", collection, parentCollectionIds, onValuesModified, onSaved: onUpdate, barActions: ({
|
|
23758
|
+
status,
|
|
23759
|
+
values
|
|
23760
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
23446
23761
|
/* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, { size: "small" }) }),
|
|
23447
23762
|
allowFullScreen && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", onClick: () => {
|
|
23763
|
+
const key = status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId;
|
|
23764
|
+
saveEntityToMemoryCache(key, values);
|
|
23448
23765
|
if (entityId) navigate(location.pathname);
|
|
23449
23766
|
else navigate(location.pathname + "#new");
|
|
23450
23767
|
}, children: /* @__PURE__ */ jsxRuntime.jsx(ui.OpenInFullIcon, { size: "small" }) })
|
|
@@ -26224,6 +26541,7 @@
|
|
|
26224
26541
|
exports2.getIdIcon = getIdIcon;
|
|
26225
26542
|
exports2.getLabelOrConfigFrom = getLabelOrConfigFrom;
|
|
26226
26543
|
exports2.getLastSegment = getLastSegment;
|
|
26544
|
+
exports2.getLocalChangesBackup = getLocalChangesBackup;
|
|
26227
26545
|
exports2.getPropertiesWithPropertiesOrder = getPropertiesWithPropertiesOrder;
|
|
26228
26546
|
exports2.getPropertyInPath = getPropertyInPath;
|
|
26229
26547
|
exports2.getRandomId = getRandomId;
|