From 1e45b88bc884da9416f0e86231d621523c9bf777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20H=C3=BClscher?= <25116822+eweren@users.noreply.github.com> Date: Tue, 21 Apr 2026 14:08:05 +0200 Subject: [PATCH 1/2] feat: add error handling for unresolved conflicts in Push component - Introduced errorOnUnresolvedConflict property to the Push component's content configuration to manage conflict scenarios more effectively. --- src/ui/views/Push/Push.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/views/Push/Push.tsx b/src/ui/views/Push/Push.tsx index 13a585f..0fb38d4 100644 --- a/src/ui/views/Push/Push.tsx +++ b/src/ui/views/Push/Push.tsx @@ -350,6 +350,7 @@ export const Push: FunctionalComponent = () => { content: { "application/json": { keys, + errorOnUnresolvedConflict: false, overrideMode: "RECOMMENDED", branch: branch || undefined, }, From 8fb79f9a69e1a17440f34aa5f9214a52c1b7f4b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20H=C3=BClscher?= <25116822+eweren@users.noreply.github.com> Date: Tue, 21 Apr 2026 14:18:00 +0200 Subject: [PATCH 2/2] feat: implement handling for unresolved conflicts in Push component - Added state management for unresolved conflicts during translation updates. - Displayed a warning banner to inform users of any unresolved conflicts that prevent updates. - Updated success message to reflect the number of successfully updated keys, excluding unresolved conflicts. --- src/ui/views/Push/Push.tsx | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/ui/views/Push/Push.tsx b/src/ui/views/Push/Push.tsx index 0fb38d4..c4c8c4a 100644 --- a/src/ui/views/Push/Push.tsx +++ b/src/ui/views/Push/Push.tsx @@ -34,6 +34,8 @@ import { useHasNamespacesEnabled } from "../../hooks/useHasNamespacesEnabled"; type SingleStepImportResolvableItemRequest = components["schemas"]["SingleStepImportResolvableItemRequest"]; type KeyScreenshotDto = components["schemas"]["KeyScreenshotDto"]; +type SimpleImportConflictResult = + components["schemas"]["SimpleImportConflictResult"]; export const Push: FunctionalComponent = () => { const language = useGlobalState((c) => c.config!.language!); @@ -46,6 +48,9 @@ export const Push: FunctionalComponent = () => { const [_loadingStatus, setLoadingStatus] = useState(); const [changes, setChanges] = useState(); const [pushedKeysCount, setPushedKeysCount] = useState(0); + const [unresolvedConflicts, setUnresolvedConflicts] = useState< + SimpleImportConflictResult[] + >([]); const selectedNodes = useConnectedNodes({ ignoreSelection: false }); const tolgeeConfig = useGlobalState((c) => c.config); const [uploadedScreenshotCount, setUploadedScreenshotCount] = useState(0); @@ -346,7 +351,7 @@ export const Push: FunctionalComponent = () => { }); }); - await updateTranslations.mutateAsync({ + const updateResult = await updateTranslations.mutateAsync({ content: { "application/json": { keys, @@ -357,6 +362,9 @@ export const Push: FunctionalComponent = () => { }, }); + const conflicts = updateResult?.unresolvedConflicts ?? []; + setUnresolvedConflicts(conflicts); + try { // Add tags to keys if ( @@ -455,6 +463,7 @@ export const Push: FunctionalComponent = () => { setPushedKeysCount(0); setUploadedScreenshotCount(0); setErrorMessage(undefined); + setUnresolvedConflicts([]); }; const isLoading = @@ -486,11 +495,32 @@ export const Push: FunctionalComponent = () => { // Show success screen immediately, don't wait for recompute
- Successfully updated {pushedKeysCount} key(s) + Successfully updated{" "} + {Math.max(pushedKeysCount - unresolvedConflicts.length, 0)} key(s) {uploadScreenshots ? ` and uploaded ${uploadedScreenshotCount} screenshot(s).` : "."}
+ {unresolvedConflicts.length > 0 && ( + + + }> +
+ These translations could not be updated because they are + either disabled or already reviewed: +
+ +
    + {unresolvedConflicts.map((c, i) => ( +
  • + {c.keyNamespace ? `${c.keyNamespace}:` : ""} + {c.keyName} ({c.language}) +
  • + ))} +
+
+
+ )}