@open-mercato/ui 0.6.6-develop.6253.1.a8c2b49d90 → 0.6.6-develop.6256.1.9fc16aedc4
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/backend/DataTable.js +60 -11
- package/dist/backend/DataTable.js.map +3 -3
- package/dist/backend/PerspectiveSidebar.js +1 -1
- package/dist/backend/PerspectiveSidebar.js.map +2 -2
- package/package.json +3 -3
- package/src/backend/DataTable.tsx +79 -11
- package/src/backend/PerspectiveSidebar.tsx +2 -2
- package/src/backend/__tests__/DataTable.perspectiveGuardedMutation.test.tsx +16 -3
|
@@ -788,6 +788,7 @@ function DataTable({
|
|
|
788
788
|
perspectives: [],
|
|
789
789
|
defaultPerspectiveId: null,
|
|
790
790
|
rolePerspectives: [],
|
|
791
|
+
manageableRolePerspectives: [],
|
|
791
792
|
roles: [],
|
|
792
793
|
canApplyToRoles: false
|
|
793
794
|
};
|
|
@@ -1215,6 +1216,10 @@ function DataTable({
|
|
|
1215
1216
|
initialPerspectiveAppliedRef.current = true;
|
|
1216
1217
|
}, [perspectiveTableId, applyPerspectiveSettings, advancedFilter]);
|
|
1217
1218
|
const perspectiveQueryKey = ["table-perspectives", perspectiveTableId];
|
|
1219
|
+
const rolePerspectivesForLocking = React.useMemo(
|
|
1220
|
+
() => perspectiveData?.manageableRolePerspectives ?? perspectiveData?.rolePerspectives ?? [],
|
|
1221
|
+
[perspectiveData]
|
|
1222
|
+
);
|
|
1218
1223
|
const perspectiveMutationContextId = `data-table-perspectives:${perspectiveTableId ?? "unknown"}`;
|
|
1219
1224
|
const { runMutation: runPerspectiveMutation, retryLastMutation: retryPerspectiveMutation } = useGuardedMutation({
|
|
1220
1225
|
contextId: perspectiveMutationContextId,
|
|
@@ -1231,13 +1236,28 @@ function DataTable({
|
|
|
1231
1236
|
const savePerspectiveMutation = useMutation({
|
|
1232
1237
|
mutationFn: async (input) => {
|
|
1233
1238
|
if (!perspectiveTableId) throw new Error("Missing table id");
|
|
1239
|
+
const roleExpectedUpdatedAtByRoleId = {};
|
|
1240
|
+
const roleExpectedUpdatedAtByPerspectiveId = {};
|
|
1241
|
+
for (const roleId of input.applyToRoles) {
|
|
1242
|
+
const rolePerspectives = rolePerspectivesForLocking.filter((p) => p.roleId === roleId);
|
|
1243
|
+
const matching = rolePerspectives.find((p) => p.name.trim() === input.name.trim()) ?? null;
|
|
1244
|
+
const defaultPerspective = input.setRoleDefault ? rolePerspectives.find((p) => p.isDefault) ?? null : null;
|
|
1245
|
+
for (const candidate of [matching, defaultPerspective]) {
|
|
1246
|
+
if (!candidate?.updatedAt) continue;
|
|
1247
|
+
roleExpectedUpdatedAtByPerspectiveId[candidate.id] = candidate.updatedAt;
|
|
1248
|
+
}
|
|
1249
|
+
const roleFallback = matching ?? defaultPerspective;
|
|
1250
|
+
if (roleFallback?.updatedAt) roleExpectedUpdatedAtByRoleId[roleId] = roleFallback.updatedAt;
|
|
1251
|
+
}
|
|
1234
1252
|
const payload = {
|
|
1235
1253
|
perspectiveId: input.perspectiveId ?? void 0,
|
|
1236
1254
|
name: input.name,
|
|
1237
1255
|
settings: input.settings ?? getCurrentSettings(),
|
|
1238
1256
|
isDefault: input.isDefault,
|
|
1239
1257
|
applyToRoles: input.applyToRoles,
|
|
1240
|
-
setRoleDefault: input.setRoleDefault
|
|
1258
|
+
setRoleDefault: input.setRoleDefault,
|
|
1259
|
+
...Object.keys(roleExpectedUpdatedAtByRoleId).length > 0 ? { roleExpectedUpdatedAtByRoleId } : {},
|
|
1260
|
+
...Object.keys(roleExpectedUpdatedAtByPerspectiveId).length > 0 ? { roleExpectedUpdatedAtByPerspectiveId } : {}
|
|
1241
1261
|
};
|
|
1242
1262
|
if (process.env.NODE_ENV !== "production") {
|
|
1243
1263
|
console.debug("[DataTable] perspective payload", payload);
|
|
@@ -1301,11 +1321,15 @@ function DataTable({
|
|
|
1301
1321
|
const deletePerspectiveMutation = useMutation({
|
|
1302
1322
|
mutationFn: async ({ perspectiveId }) => {
|
|
1303
1323
|
if (!perspectiveTableId) throw new Error("Missing table id");
|
|
1324
|
+
const existing = perspectiveData?.perspectives.find((p) => p.id === perspectiveId) ?? null;
|
|
1304
1325
|
await runPerspectiveMutation({
|
|
1305
1326
|
operation: async () => {
|
|
1306
|
-
const call = await
|
|
1307
|
-
|
|
1308
|
-
|
|
1327
|
+
const call = await withScopedApiRequestHeaders(
|
|
1328
|
+
buildOptimisticLockHeader(existing?.updatedAt ?? null),
|
|
1329
|
+
() => apiCall(
|
|
1330
|
+
`/api/perspectives/${encodeURIComponent(perspectiveTableId)}/${encodeURIComponent(perspectiveId)}`,
|
|
1331
|
+
{ method: "DELETE" }
|
|
1332
|
+
)
|
|
1309
1333
|
);
|
|
1310
1334
|
if (call.status === 404) throw new Error(t("ui.dataTable.perspectives.error.apiUnavailable", "Perspectives API is not available. Run `yarn generate` and restart the dev server."));
|
|
1311
1335
|
if (!call.ok) {
|
|
@@ -1337,16 +1361,29 @@ function DataTable({
|
|
|
1337
1361
|
setActivePerspectiveId(null);
|
|
1338
1362
|
initialPerspectiveAppliedRef.current = false;
|
|
1339
1363
|
}
|
|
1364
|
+
},
|
|
1365
|
+
onError: () => {
|
|
1366
|
+
if (perspectiveTableId) {
|
|
1367
|
+
void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey });
|
|
1368
|
+
}
|
|
1340
1369
|
}
|
|
1341
1370
|
});
|
|
1342
1371
|
const clearRoleMutation = useMutation({
|
|
1343
|
-
mutationFn: async ({ roleId }) => {
|
|
1372
|
+
mutationFn: async ({ roleId, updatedAt, expectedUpdatedAtByPerspectiveId }) => {
|
|
1344
1373
|
if (!perspectiveTableId) throw new Error("Missing table id");
|
|
1374
|
+
const hasPerRowVersions = expectedUpdatedAtByPerspectiveId && Object.keys(expectedUpdatedAtByPerspectiveId).length > 0;
|
|
1345
1375
|
await runPerspectiveMutation({
|
|
1346
1376
|
operation: async () => {
|
|
1347
|
-
const call = await
|
|
1348
|
-
|
|
1349
|
-
|
|
1377
|
+
const call = await withScopedApiRequestHeaders(
|
|
1378
|
+
hasPerRowVersions ? {} : buildOptimisticLockHeader(updatedAt ?? null),
|
|
1379
|
+
() => apiCall(
|
|
1380
|
+
`/api/perspectives/${encodeURIComponent(perspectiveTableId)}/roles/${encodeURIComponent(roleId)}`,
|
|
1381
|
+
hasPerRowVersions ? {
|
|
1382
|
+
method: "DELETE",
|
|
1383
|
+
headers: { "Content-Type": "application/json" },
|
|
1384
|
+
body: JSON.stringify({ roleExpectedUpdatedAtByPerspectiveId: expectedUpdatedAtByPerspectiveId })
|
|
1385
|
+
} : { method: "DELETE" }
|
|
1386
|
+
)
|
|
1350
1387
|
);
|
|
1351
1388
|
if (call.status === 404) throw new Error(t("ui.dataTable.perspectives.error.apiUnavailable", "Perspectives API is not available. Run `yarn generate` and restart the dev server."));
|
|
1352
1389
|
if (!call.ok) {
|
|
@@ -1378,6 +1415,11 @@ function DataTable({
|
|
|
1378
1415
|
initialPerspectiveAppliedRef.current = false;
|
|
1379
1416
|
}
|
|
1380
1417
|
}
|
|
1418
|
+
},
|
|
1419
|
+
onError: () => {
|
|
1420
|
+
if (perspectiveTableId) {
|
|
1421
|
+
void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey });
|
|
1422
|
+
}
|
|
1381
1423
|
}
|
|
1382
1424
|
});
|
|
1383
1425
|
const handlePerspectiveActivate = React.useCallback((item, _source) => {
|
|
@@ -1397,9 +1439,16 @@ function DataTable({
|
|
|
1397
1439
|
const handlePerspectiveDelete = React.useCallback(async (perspectiveId) => {
|
|
1398
1440
|
await deletePerspectiveMutation.mutateAsync({ perspectiveId });
|
|
1399
1441
|
}, [deletePerspectiveMutation]);
|
|
1400
|
-
const handleClearRole = React.useCallback(async (
|
|
1401
|
-
|
|
1402
|
-
|
|
1442
|
+
const handleClearRole = React.useCallback(async (perspective2) => {
|
|
1443
|
+
const expectedUpdatedAtByPerspectiveId = Object.fromEntries(
|
|
1444
|
+
rolePerspectivesForLocking.filter((item) => item.roleId === perspective2.roleId && item.updatedAt).map((item) => [item.id, item.updatedAt])
|
|
1445
|
+
);
|
|
1446
|
+
await clearRoleMutation.mutateAsync({
|
|
1447
|
+
roleId: perspective2.roleId,
|
|
1448
|
+
updatedAt: perspective2.updatedAt ?? null,
|
|
1449
|
+
expectedUpdatedAtByPerspectiveId
|
|
1450
|
+
});
|
|
1451
|
+
}, [clearRoleMutation, rolePerspectivesForLocking]);
|
|
1403
1452
|
const handleColumnChooserToggle = React.useCallback((key) => {
|
|
1404
1453
|
const column = table.getColumn(key);
|
|
1405
1454
|
if (!column) return;
|