Skip to content

Commit df20ae9

Browse files
committed
fix: enhance locale mapping logic and improve handling of unmatched sources in LoadLanguageMapper
- Added checks for exact destination matches to improve locale mapping accuracy. - Implemented handling for unmatched source locales, ensuring they are assigned to available destinations. - Enhanced logging for better visibility into the mapping process and state changes. - Updated cmsLocaleOptions to guarantee the master locale is always listed first.
1 parent 0f61f22 commit df20ae9

File tree

1 file changed

+94
-21
lines changed

1 file changed

+94
-21
lines changed

ui/src/components/DestinationStack/Actions/LoadLanguageMapper.tsx

Lines changed: 94 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,12 +1117,42 @@ const LanguageMapper = ({stack, uid} :{ stack : IDropDown, uid : string}) => {
11171117
const sourceLocaleValue = (singleSourceLocale.value || singleSourceLocale.label || '').toLowerCase();
11181118
const destinationLocale = (stack?.master_locale || 'en-us').toLowerCase();
11191119

1120+
const hasExactDestination = allLocales.some(dest => {
1121+
const destValue = (dest.value || dest.label || '').toLowerCase();
1122+
return destValue === sourceLocaleValue;
1123+
});
1124+
1125+
if (!hasExactDestination && sourceLocaleValue !== destinationLocale) {
1126+
console.info('⚠️ [Single Locale] No exact destination match found. Leaving master locale unmapped.', {
1127+
sourceLocaleValue,
1128+
destinationLocale,
1129+
allLocales: allLocales.map(dest => dest.value || dest.label)
1130+
});
1131+
1132+
if (cmsLocaleOptions?.length === 0) {
1133+
setcmsLocaleOptions([{
1134+
label: destinationLocale,
1135+
value: destinationLocale
1136+
}]);
1137+
}
1138+
1139+
setAutoSelectedSourceLocale(null);
1140+
setMapperLocaleState({});
1141+
if (isStackChanged) {
1142+
setisStackChanged(false);
1143+
}
1144+
setTimeout(() => {
1145+
isProcessingRef.current = false;
1146+
}, 0);
1147+
return;
1148+
}
1149+
11201150
console.info('🔥 [Single Locale Auto-Map] Mapping single source to destination master:', {
11211151
source: sourceLocaleValue,
11221152
destination: destinationLocale,
11231153
source_locale_object: singleSourceLocale,
11241154
stack_master_locale: stack?.master_locale,
1125-
reason: 'Single source locale - no other choice'
1155+
reason: hasExactDestination ? 'Exact destination match found' : 'Source equals master locale'
11261156
});
11271157

11281158
const autoMapping = {
@@ -1314,49 +1344,81 @@ const LanguageMapper = ({stack, uid} :{ stack : IDropDown, uid : string}) => {
13141344
autoMapping[match.source] = match.dest;
13151345
});
13161346

1317-
// 🔥 CRITICAL FIX: Update cmsLocaleOptions with master locale ALWAYS first
1318-
const destinationLocalesInMapping = new Set<string>();
1347+
const leftoverAssignments: Array<{ source: string; dest: string }> = [];
1348+
const assignedDestinations = new Set<string>();
1349+
if (masterLocaleMatch) {
1350+
assignedDestinations.add(masterLocaleMatch.dest);
1351+
}
1352+
exactMatches.forEach(match => {
1353+
if (!(match.source === normalizedStackMaster && masterLocaleMatch)) {
1354+
assignedDestinations.add(match.dest);
1355+
}
1356+
});
1357+
assignedDestinations.add(normalizedStackMaster);
13191358

1320-
// 🔥 Don't use Set for ordering - use array to maintain master-first order
1321-
const orderedDestLocales: string[] = [];
1359+
const availableDestLocales = allLocales
1360+
.map(dest => (dest.value || dest.label || '').toLowerCase())
1361+
.filter(dest => dest && dest !== normalizedStackMaster && !assignedDestinations.has(dest));
13221362

1323-
// 🔥 STEP 1: ALWAYS add master locale first
1324-
orderedDestLocales.push(normalizedStackMaster);
1363+
unmatchedSources.forEach((sourceValue, idx) => {
1364+
const candidateDest = availableDestLocales[idx];
1365+
if (!candidateDest) {
1366+
console.info('⚠️ [TC-03/TC-08] No available destination locale to assign for:', { sourceValue });
1367+
return;
1368+
}
1369+
console.info('🎯 [TC-03] Assigning unmatched source to remaining destination:', {
1370+
sourceValue,
1371+
candidateDest
1372+
});
1373+
autoMapping[sourceValue] = candidateDest;
1374+
leftoverAssignments.push({ source: sourceValue, dest: candidateDest });
1375+
assignedDestinations.add(candidateDest);
1376+
});
13251377

1326-
// 🔥 STEP 2: Add all other exact match destinations (excluding master if already added)
1378+
const destinationLocalesInMapping = new Set<string>();
1379+
destinationLocalesInMapping.add(normalizedStackMaster);
13271380
exactMatches.forEach(match => {
1328-
if (match.dest !== normalizedStackMaster && !orderedDestLocales.includes(match.dest)) {
1329-
orderedDestLocales.push(match.dest);
1330-
}
1381+
destinationLocalesInMapping.add(match.dest);
1382+
});
1383+
leftoverAssignments.forEach(assign => {
1384+
destinationLocalesInMapping.add(assign.dest);
13311385
});
13321386

13331387
setcmsLocaleOptions(() => {
13341388
const newList: { label: string; value: string }[] = [];
1389+
const processedLocales = new Set<string>();
13351390

1336-
// Build list in order from orderedDestLocales array
1337-
orderedDestLocales.forEach(destLocale => {
1391+
if (!processedLocales.has(normalizedStackMaster)) {
13381392
newList.push({
1339-
label: destLocale,
1340-
value: destLocale
1393+
label: normalizedStackMaster,
1394+
value: normalizedStackMaster
13411395
});
1396+
processedLocales.add(normalizedStackMaster);
1397+
}
1398+
1399+
destinationLocalesInMapping.forEach(destLocale => {
1400+
if (!processedLocales.has(destLocale)) {
1401+
newList.push({
1402+
label: destLocale,
1403+
value: destLocale
1404+
});
1405+
processedLocales.add(destLocale);
1406+
}
13421407
});
13431408

13441409
console.info('🔥 [Multi-locale] Updated cmsLocaleOptions (master GUARANTEED first):', {
13451410
newList,
13461411
first: newList[0],
13471412
second: newList[1],
13481413
length: newList.length,
1349-
orderedDestLocales,
1414+
orderedDestLocales: Array.from(destinationLocalesInMapping),
13501415
VERIFY_MASTER_IS_FIRST: newList[0]?.label === normalizedStackMaster
13511416
});
13521417
return newList;
13531418
});
13541419

1355-
// 🔥 CRITICAL FIX: Update mapperLocaleState with proper keys
13561420
const updatedMapperState: ExistingFieldType = {};
13571421

1358-
// 🔥 CRITICAL: Keys MUST be destination locale codes (what appears in cmsLocaleOptions)
1359-
// Values MUST be source locale objects (what should appear in the source dropdown)
13601422
if (masterLocaleMatch) {
13611423
updatedMapperState[normalizedStackMaster] = {
13621424
label: masterLocaleMatch.source,
@@ -1380,14 +1442,13 @@ const LanguageMapper = ({stack, uid} :{ stack : IDropDown, uid : string}) => {
13801442
});
13811443
}
13821444

1383-
// 🔥 For other matched rows - use destination locale as key, source locale as value
13841445
exactMatches.forEach(match => {
13851446
if (match.dest === normalizedStackMaster) {
13861447
console.info('🔥 [Multi-locale] Skipping duplicate master:', {
13871448
match_dest: match.dest,
13881449
normalizedStackMaster
13891450
});
1390-
return; // Already processed as master
1451+
return;
13911452
}
13921453

13931454
updatedMapperState[match.dest] = {
@@ -1401,6 +1462,18 @@ const LanguageMapper = ({stack, uid} :{ stack : IDropDown, uid : string}) => {
14011462
});
14021463
});
14031464

1465+
leftoverAssignments.forEach(assign => {
1466+
updatedMapperState[assign.dest] = {
1467+
label: assign.source,
1468+
value: assign.source
1469+
};
1470+
console.info('🔥 [Multi-locale] Set leftover row:', {
1471+
key: assign.dest,
1472+
value: assign.source,
1473+
full_object: updatedMapperState[assign.dest]
1474+
});
1475+
});
1476+
14041477
console.info('🔥 [Multi-locale] Final mapperLocaleState:', {
14051478
updatedMapperState,
14061479
keys: Object.keys(updatedMapperState),

0 commit comments

Comments
 (0)