fix(calendar): blank task titles from invalid translation LanguageId#996
Merged
Merged
Conversation
…eate/update Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…id from modal Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Fixes blank calendar/task titles caused by persisting translations under invalid/non-SDK LanguageId values, and makes title resolution resilient when a user-language translation is missing or empty.
Changes:
- Frontend: resolve Danish source title’s real SDK
Languages.IdbylanguageCodeinstead of hardcodinglanguageId: 1. - Backend write path: defensively remap incoming
CommonTranslationsModel.LanguageIdvalues that don’t exist in SDKLanguagesbefore persisting. - Backend read path: centralize task title resolution via
ResolveTaskTitlewith cross-language + whitespace-aware fallback, plus unit/integration coverage.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationTaskWizardService/BackendConfigurationTaskWizardService.cs | Remaps incoming translation LanguageIds on create/update to avoid minting bad rows. |
| eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationCalendarService/BackendConfigurationCalendarService.cs | Uses shared ResolveTaskTitle helper for consistent, fallback-capable title resolution. |
| eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Infrastructure/Helpers/AreaRuleLanguageHelper.cs | Adds existence-guarded remap helper for frontend-sourced translation ids. |
| eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/BackendConfiguration.Pn.csproj | Exposes internals to unit test assembly for direct helper testing. |
| eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Test/Services/ResolveTaskTitleTests.cs | Unit tests for title resolution fallbacks and whitespace handling. |
| eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarTranslationLanguageIdRemapTests.cs | Integration tests validating remap behavior on shifted-id tenants. |
| eform-client/src/app/plugins/modules/backend-configuration-pn/modules/calendar/modals/task-create-edit-modal/task-create-edit-modal.component.ts | Frontend now looks up Danish SDK language id from loaded languages instead of hardcoding 1. |
Comment on lines
+4452
to
+4461
| var list = translations?.ToList() ?? new List<AreaRuleTranslation>(); | ||
| // 1) user-language, non-empty name | ||
| var byLang = list.FirstOrDefault(t => t.LanguageId == userLanguageId | ||
| && !string.IsNullOrWhiteSpace(t.Name))?.Name; | ||
| if (!string.IsNullOrWhiteSpace(byLang)) return byLang!; | ||
| // 2) any translation with a non-empty name (cross-language fallback) | ||
| var any = list.FirstOrDefault(t => !string.IsNullOrWhiteSpace(t.Name))?.Name; | ||
| if (!string.IsNullOrWhiteSpace(any)) return any!; | ||
| // 3) caller-supplied fallback (e.g. compliance.ItemName), else empty | ||
| return string.IsNullOrWhiteSpace(finalFallback) ? "" : finalFallback!; |
Comment on lines
+386
to
+389
| // Remap each translate's LanguageId to the real SDK Languages.Id before it is persisted | ||
| // into PlanningNameTranslation and AreaRuleTranslations below. The calendar modal | ||
| // hardcodes the Danish source title to app-locale id 1, which is not a valid SDK id and | ||
| // would otherwise store the title under a language no reader ever queries (blank title). |
Comment on lines
+97
to
+101
| /// The calendar create/edit modal hardcodes the Danish source title's LanguageId to the | ||
| /// frontend app-locale id 1 (see task-create-edit-modal.component.ts), while target-language | ||
| /// translates already carry the real SDK Languages.Id returned by GET /settings/languages. | ||
| /// Persisting the verbatim id stores the Danish title under LanguageId=1, which no reader ever | ||
| /// queries (readers match against the user's SDK Languages.Id resolved by LanguageCode), so the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Calendar/task titles were rendering blank (the tile showed only the numeric id, e.g. "113") for tasks whose Danish title translation was stored under an invalid LanguageId. Affected both the Angular calendar and the Flutter mobile app (both read the same
GetTasksForWeektitle resolution).Root cause
languageId: 1, and the backend persisted it verbatim intoAreaRuleTranslationsandPlanningNameTranslation.Languagestable is customer-specific (e.g. this tenant: da=2, en-US=5, de-DE=8, no id 1). So the Danish title was stored under a language id no reader ever queries → blank title. Confirmed live: AreaRule 113 was created today and still gotLanguageId=1. The earlier#985"remap seed LanguageId" fix only covered seed paths, not the calendar create/update path.Fix
Write path (stop minting bad rows):
1.AreaRuleLanguageHelper.RemapCommonTranslationLanguageIdsAsyncdefensively remaps any incoming translationLanguageIdthat is absent from SDK Languages, resolving via language code → SDKLanguages.Id. Applied on Create + Update, covering bothAreaRuleTranslationsandPlanningNameTranslation. Existence-based guard: valid SDK ids are never touched (avoids corrupting multi-language targets on shifted-id tenants).Read path (graceful degrade):
ResolveTaskTitlehelper replaces 4 inconsistent title-computation sites (recurrence, moved-in, compliance in GetTasksForWeek, compliance in GetTaskTrackerList). Order: user-language non-empty → any non-empty translation → caller fallback (e.g. compliance.ItemName) → "". UsesIsNullOrWhiteSpaceso empty-string names also fall through (the old??only caught null).Tests
ResolveTaskTitle: user-lang wins, empty-string fall-through, cross-language fallback, null collection, all-empty → "".Note
Existing mis-keyed rows in a database (created before this fix) still carry the bad LanguageId; the read-path fallback makes them display correctly, and they can be repaired by remapping
AreaRuleTranslations/PlanningNameTranslationrows whose LanguageId is absent from SDKLanguagesto the correct id by code (done for the local 420 DB during investigation).🤖 Generated with Claude Code