@@ -297,6 +297,8 @@ private IQueryable<ResourceKey> ApplySingleLanguageFilter(IQueryable<ResourceKey
297297 KeyPath = request . KeyPath ,
298298 IsPlural = request . IsPlural ,
299299 Comment = request . Comment ,
300+ // Store the default language value as SourceText for translation reference
301+ SourceText = request . DefaultLanguageValue ,
300302 Version = 1 ,
301303 CreatedAt = DateTime . UtcNow ,
302304 UpdatedAt = DateTime . UtcNow
@@ -467,6 +469,10 @@ private IQueryable<ResourceKey> ApplySingleLanguageFilter(IQueryable<ResourceKey
467469 var translation = resourceKey . Translations
468470 . FirstOrDefault ( t => t . LanguageCode == languageCode && t . PluralForm == request . PluralForm ) ;
469471
472+ // Get project to check if we're updating the default language
473+ var project = await _db . Projects . FindAsync ( projectId ) ;
474+ var isDefaultLanguage = project != null && languageCode == project . DefaultLanguage ;
475+
470476 if ( translation == null )
471477 {
472478 // Create new translation
@@ -483,6 +489,18 @@ private IQueryable<ResourceKey> ApplySingleLanguageFilter(IQueryable<ResourceKey
483489 } ;
484490
485491 _db . Translations . Add ( translation ) ;
492+
493+ // If creating translation for default language, also update SourceText
494+ if ( isDefaultLanguage && string . IsNullOrEmpty ( request . PluralForm ) )
495+ {
496+ resourceKey . SourceText = request . Value ;
497+ resourceKey . UpdatedAt = DateTime . UtcNow ;
498+ }
499+ else if ( isDefaultLanguage && request . PluralForm == "other" )
500+ {
501+ resourceKey . SourcePluralText = request . Value ;
502+ resourceKey . UpdatedAt = DateTime . UtcNow ;
503+ }
486504 }
487505 else
488506 {
@@ -498,6 +516,18 @@ private IQueryable<ResourceKey> ApplySingleLanguageFilter(IQueryable<ResourceKey
498516 translation . Comment = request . Comment ;
499517 translation . UpdatedAt = DateTime . UtcNow ;
500518 translation . Version ++ ;
519+
520+ // If updating the default language, also update SourceText
521+ if ( isDefaultLanguage && string . IsNullOrEmpty ( request . PluralForm ) )
522+ {
523+ resourceKey . SourceText = request . Value ;
524+ resourceKey . UpdatedAt = DateTime . UtcNow ;
525+ }
526+ else if ( isDefaultLanguage && request . PluralForm == "other" )
527+ {
528+ resourceKey . SourcePluralText = request . Value ;
529+ resourceKey . UpdatedAt = DateTime . UtcNow ;
530+ }
501531 }
502532
503533 await _db . SaveChangesAsync ( ) ;
@@ -529,6 +559,10 @@ private IQueryable<ResourceKey> ApplySingleLanguageFilter(IQueryable<ResourceKey
529559 return ( false , 0 , "You don't have permission to manage resources in this project" ) ;
530560 }
531561
562+ // Get project to check if we're updating the default language
563+ var project = await _db . Projects . FindAsync ( projectId ) ;
564+ var isDefaultLanguage = project != null && languageCode == project . DefaultLanguage ;
565+
532566 var updatedCount = 0 ;
533567
534568 foreach ( var update in updates )
@@ -578,6 +612,18 @@ private IQueryable<ResourceKey> ApplySingleLanguageFilter(IQueryable<ResourceKey
578612 translation . Version ++ ;
579613 }
580614
615+ // If updating the default language, also update SourceText
616+ if ( isDefaultLanguage && string . IsNullOrEmpty ( update . PluralForm ) )
617+ {
618+ resourceKey . SourceText = update . Value ;
619+ resourceKey . UpdatedAt = DateTime . UtcNow ;
620+ }
621+ else if ( isDefaultLanguage && update . PluralForm == "other" )
622+ {
623+ resourceKey . SourcePluralText = update . Value ;
624+ resourceKey . UpdatedAt = DateTime . UtcNow ;
625+ }
626+
581627 updatedCount ++ ;
582628 }
583629
@@ -1023,6 +1069,7 @@ private ResourceKeyDto MapToResourceKeyDto(ResourceKey key)
10231069 KeyName = key . KeyName ,
10241070 KeyPath = key . KeyPath ,
10251071 IsPlural = key . IsPlural ,
1072+ SourceText = key . SourceText ,
10261073 SourcePluralText = key . SourcePluralText ,
10271074 Comment = key . Comment ,
10281075 Version = key . Version ,
@@ -1039,19 +1086,47 @@ private ResourceKeyDetailDto MapToResourceKeyDetailDto(ResourceKey key)
10391086
10401087 private ResourceKeyDetailDto MapToResourceKeyDetailDto ( ResourceKey key , string ? defaultLanguage )
10411088 {
1089+ var translations = key . Translations . Select ( t => MapToTranslationDto ( t , defaultLanguage ) ) . ToList ( ) ;
1090+
1091+ // Add virtual translation for source language display if SourceText exists
1092+ // but no translation exists for the default language (or empty LanguageCode)
1093+ if ( ! string . IsNullOrEmpty ( defaultLanguage ) && ! string . IsNullOrEmpty ( key . SourceText ) && ! key . IsPlural )
1094+ {
1095+ var hasDefaultLangTranslation = key . Translations . Any ( t =>
1096+ ( t . LanguageCode == defaultLanguage || string . IsNullOrEmpty ( t . LanguageCode ) )
1097+ && string . IsNullOrEmpty ( t . PluralForm ) ) ;
1098+
1099+ if ( ! hasDefaultLangTranslation )
1100+ {
1101+ // Insert virtual source translation for grid display
1102+ translations . Insert ( 0 , new TranslationDto
1103+ {
1104+ Id = 0 ,
1105+ LanguageCode = defaultLanguage ,
1106+ Value = key . SourceText ,
1107+ PluralForm = "" ,
1108+ Status = "source" ,
1109+ Version = 0 ,
1110+ UpdatedAt = key . UpdatedAt ,
1111+ IsVirtual = true
1112+ } ) ;
1113+ }
1114+ }
1115+
10421116 return new ResourceKeyDetailDto
10431117 {
10441118 Id = key . Id ,
10451119 KeyName = key . KeyName ,
10461120 KeyPath = key . KeyPath ,
10471121 IsPlural = key . IsPlural ,
1122+ SourceText = key . SourceText ,
10481123 SourcePluralText = key . SourcePluralText ,
10491124 Comment = key . Comment ,
10501125 Version = key . Version ,
10511126 TranslationCount = key . Translations . Count ,
10521127 CreatedAt = key . CreatedAt ,
10531128 UpdatedAt = key . UpdatedAt ,
1054- Translations = key . Translations . Select ( t => MapToTranslationDto ( t , defaultLanguage ) ) . ToList ( )
1129+ Translations = translations
10551130 } ;
10561131 }
10571132
@@ -1371,6 +1446,9 @@ public async Task<BatchSaveResponse> BatchSaveWithHistoryAsync(
13711446 var response = new BatchSaveResponse ( ) ;
13721447 var changes = new List < SyncChangeEntry > ( ) ;
13731448
1449+ // Get project to check default language for SourceText updates
1450+ var project = await _db . Projects . FindAsync ( projectId ) ;
1451+
13741452 await using var transaction = await _db . Database . BeginTransactionAsync ( ) ;
13751453
13761454 try
@@ -1402,6 +1480,7 @@ public async Task<BatchSaveResponse> BatchSaveWithHistoryAsync(
14021480 {
14031481 Key = keyChange . KeyName ,
14041482 Lang = "" ,
1483+ PluralForm = "" ,
14051484 ChangeType = "modified" ,
14061485 BeforeComment = beforeComment ,
14071486 AfterComment = keyChange . Comment
@@ -1483,13 +1562,29 @@ public async Task<BatchSaveResponse> BatchSaveWithHistoryAsync(
14831562 translation . Version ++ ;
14841563 }
14851564
1565+ // If updating the default language, also update SourceText on ResourceKey
1566+ if ( project != null && translationChange . LanguageCode == project . DefaultLanguage )
1567+ {
1568+ if ( string . IsNullOrEmpty ( pluralForm ) )
1569+ {
1570+ resourceKey . SourceText = translation . Value ;
1571+ resourceKey . UpdatedAt = DateTime . UtcNow ;
1572+ }
1573+ else if ( pluralForm == "other" )
1574+ {
1575+ resourceKey . SourcePluralText = translation . Value ;
1576+ resourceKey . UpdatedAt = DateTime . UtcNow ;
1577+ }
1578+ }
1579+
14861580 response . TranslationsModified ++ ;
14871581
14881582 // Record the change
14891583 changes . Add ( new SyncChangeEntry
14901584 {
14911585 Key = translationChange . KeyName ,
14921586 Lang = translationChange . LanguageCode ,
1587+ PluralForm = pluralForm ,
14931588 ChangeType = changeType ,
14941589 BeforeValue = beforeValue ,
14951590 AfterValue = translation . Value ,
0 commit comments