@open-mercato/ui 0.6.5-develop.4534.1.b459babe6d → 0.6.5-develop.4559.1.839e136509
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/.turbo/turbo-build.log +1 -1
- package/AGENTS.md +1 -0
- package/dist/backend/AppShell.js +6 -0
- package/dist/backend/AppShell.js.map +2 -2
- package/dist/backend/CrudForm.js +57 -11
- package/dist/backend/CrudForm.js.map +2 -2
- package/dist/backend/DataTable.js +20 -8
- package/dist/backend/DataTable.js.map +3 -3
- package/dist/backend/PerspectiveSidebar.js +8 -1
- package/dist/backend/PerspectiveSidebar.js.map +2 -2
- package/dist/backend/RowActions.js +1 -1
- package/dist/backend/RowActions.js.map +2 -2
- package/dist/backend/conflicts/RecordConflictBanner.js +73 -0
- package/dist/backend/conflicts/RecordConflictBanner.js.map +7 -0
- package/dist/backend/conflicts/index.js +32 -0
- package/dist/backend/conflicts/index.js.map +7 -0
- package/dist/backend/conflicts/store.js +50 -0
- package/dist/backend/conflicts/store.js.map +7 -0
- package/dist/backend/injection/useGuardedMutation.js +8 -1
- package/dist/backend/injection/useGuardedMutation.js.map +2 -2
- package/dist/backend/sidebar/SidebarCustomizationEditor.js +23 -7
- package/dist/backend/sidebar/SidebarCustomizationEditor.js.map +2 -2
- package/dist/backend/utils/optimisticLock.js +34 -0
- package/dist/backend/utils/optimisticLock.js.map +7 -0
- package/package.json +7 -3
- package/src/backend/AppShell.tsx +10 -0
- package/src/backend/CrudForm.tsx +99 -9
- package/src/backend/DataTable.tsx +22 -8
- package/src/backend/PerspectiveSidebar.tsx +8 -1
- package/src/backend/RowActions.tsx +1 -1
- package/src/backend/__tests__/CrudForm.optimisticLock.test.tsx +288 -0
- package/src/backend/conflicts/RecordConflictBanner.tsx +77 -0
- package/src/backend/conflicts/__tests__/RecordConflictBanner.test.tsx +61 -0
- package/src/backend/conflicts/__tests__/store.test.ts +78 -0
- package/src/backend/conflicts/index.ts +49 -0
- package/src/backend/conflicts/store.ts +94 -0
- package/src/backend/injection/__tests__/useGuardedMutation.optimisticLock.test.tsx +118 -0
- package/src/backend/injection/useGuardedMutation.ts +16 -1
- package/src/backend/sidebar/SidebarCustomizationEditor.tsx +35 -11
- package/src/backend/utils/__tests__/optimisticLock.test.ts +126 -0
- package/src/backend/utils/optimisticLock.ts +70 -0
|
@@ -31,7 +31,9 @@ import { useAppEvent } from "./injection/useAppEvent.js";
|
|
|
31
31
|
import { useInjectionDataWidgets } from "./injection/useInjectionDataWidgets.js";
|
|
32
32
|
import { resolveInjectedIcon } from "./injection/resolveInjectedIcon.js";
|
|
33
33
|
import { serializeExport, defaultExportFilename } from "@open-mercato/shared/lib/crud/exporters";
|
|
34
|
-
import { apiCall } from "./utils/apiCall.js";
|
|
34
|
+
import { apiCall, withScopedApiRequestHeaders } from "./utils/apiCall.js";
|
|
35
|
+
import { buildOptimisticLockHeader } from "./utils/optimisticLock.js";
|
|
36
|
+
import { surfaceRecordConflict } from "./conflicts/index.js";
|
|
35
37
|
import { raiseCrudError } from "./utils/serverErrors.js";
|
|
36
38
|
import { PerspectiveSidebar } from "./PerspectiveSidebar.js";
|
|
37
39
|
import { Popover, PopoverTrigger, PopoverContent } from "../primitives/popover.js";
|
|
@@ -1224,13 +1226,17 @@ function DataTable({
|
|
|
1224
1226
|
if (process.env.NODE_ENV !== "production") {
|
|
1225
1227
|
console.debug("[DataTable] perspective payload", payload);
|
|
1226
1228
|
}
|
|
1227
|
-
const
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1229
|
+
const existing = input.perspectiveId ? perspectiveData?.perspectives.find((p) => p.id === input.perspectiveId) ?? null : null;
|
|
1230
|
+
const call = await withScopedApiRequestHeaders(
|
|
1231
|
+
buildOptimisticLockHeader(existing?.updatedAt ?? null),
|
|
1232
|
+
() => apiCall(
|
|
1233
|
+
`/api/perspectives/${encodeURIComponent(perspectiveTableId)}`,
|
|
1234
|
+
{
|
|
1235
|
+
method: "POST",
|
|
1236
|
+
headers: { "Content-Type": "application/json" },
|
|
1237
|
+
body: JSON.stringify(payload)
|
|
1238
|
+
}
|
|
1239
|
+
)
|
|
1234
1240
|
);
|
|
1235
1241
|
if (call.status === 404) {
|
|
1236
1242
|
throw new Error(t("ui.dataTable.perspectives.error.apiUnavailable", "Perspectives API is not available. Run `yarn generate` to regenerate module routes and restart the dev server."));
|
|
@@ -1249,6 +1255,12 @@ function DataTable({
|
|
|
1249
1255
|
if (data2.perspective) {
|
|
1250
1256
|
applyPerspectiveSettings(data2.perspective.settings, data2.perspective.id);
|
|
1251
1257
|
}
|
|
1258
|
+
},
|
|
1259
|
+
onError: (error2) => {
|
|
1260
|
+
if (perspectiveTableId) {
|
|
1261
|
+
void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey });
|
|
1262
|
+
}
|
|
1263
|
+
surfaceRecordConflict(error2, t);
|
|
1252
1264
|
}
|
|
1253
1265
|
});
|
|
1254
1266
|
const resolveColumnLabel = React.useCallback((column) => {
|