From 2417a7795b391473e5fba10ff01a2c8f9bf144a3 Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Fri, 17 Jul 2026 18:31:01 +0400 Subject: [PATCH] fix(languages): show error instead of silently no-oping when adding a duplicate locale addLocale() always cleared the input, even when LocaleSyncService rejected the code because it was already supported - same silent-failure shape as the widgets JSON bug fixed earlier this session. Now checks locales() first and shows an inline error, leaving the input untouched, instead of clearing it like the add succeeded. Verified live: typing an existing locale code and clicking Add now shows 'This language is already supported.' Navigation-section was also audited (id generation, label locale-migration, reorder swap, grouped-footer read-only fallback) - no defects found, it's solid as-is. Co-Authored-By: Claude Sonnet 5 --- .../sections/languages-section.component.html | 6 +++++- .../sections/languages-section.component.ts | 12 +++++++++++- src/app/i18n/en.ts | 1 + src/app/i18n/hy.ts | 1 + src/app/i18n/ru.ts | 1 + src/app/i18n/translations.ts | 1 + 6 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/app/features/project-editor/sections/languages-section.component.html b/src/app/features/project-editor/sections/languages-section.component.html index 94aec46..1e400ab 100644 --- a/src/app/features/project-editor/sections/languages-section.component.html +++ b/src/app/features/project-editor/sections/languages-section.component.html @@ -13,7 +13,11 @@ /> {{ 'builder.addLanguage' | translate }} - {{ 'builder.newLanguageDesc' | translate }} + @if (addLocaleError(); as addError) { +

{{ addError }}

+ } @else { + {{ 'builder.newLanguageDesc' | translate }} + }
@for (code of locales(); track code) { diff --git a/src/app/features/project-editor/sections/languages-section.component.ts b/src/app/features/project-editor/sections/languages-section.component.ts index 6215397..8faae25 100644 --- a/src/app/features/project-editor/sections/languages-section.component.ts +++ b/src/app/features/project-editor/sections/languages-section.component.ts @@ -37,15 +37,25 @@ export class ProjectEditorLanguagesSectionComponent { updateNewLocale(value: string): void { this.newLocale.set(value); + if (this.addLocaleError()) { + this.addLocaleError.set(null); + } } + readonly addLocaleError = signal(null); + addLocale(): void { - const code = this.newLocale().trim(); + const code = this.newLocale().trim().toLowerCase(); if (!code) { return; } + if (this.locales().includes(code)) { + this.addLocaleError.set(this.translate.t('builder.languageAlreadyAdded')); + return; + } this.facade.addLocale(code); this.newLocale.set(''); + this.addLocaleError.set(null); } removeLocale(code: string): void { diff --git a/src/app/i18n/en.ts b/src/app/i18n/en.ts index f3833ee..f615664 100644 --- a/src/app/i18n/en.ts +++ b/src/app/i18n/en.ts @@ -679,6 +679,7 @@ export const en: Translations = { catalogNavTopCarousel: 'Top category carousel', catalogNavTopCarouselDesc: 'Horizontally scrollable category chips above the catalog grid.', newLanguageDesc: 'ISO language code to add as a supported storefront language (e.g. de, fr).', + languageAlreadyAdded: 'This language is already supported.', languagesTabDesc: 'Languages available to shoppers. The default language is used as a fallback everywhere.', linkLabelDesc: 'Text shown for this navigation link.', linkUrlDesc: 'Path or URL this navigation link points to.', diff --git a/src/app/i18n/hy.ts b/src/app/i18n/hy.ts index 19d3b2a..10af5cd 100644 --- a/src/app/i18n/hy.ts +++ b/src/app/i18n/hy.ts @@ -679,6 +679,7 @@ export const hy: Translations = { catalogNavTopCarousel: 'Վերևի կատեգորիաների կարուսել', catalogNavTopCarouselDesc: 'Հորիզոնական թերթվող կատեգորիաների chip-եր կատալոգի ցանցի վերևում։', newLanguageDesc: 'ISO լեզվի կոդ՝ որպես աջակցվող լեզու ավելացնելու համար (օր․՝ de, fr)։', + languageAlreadyAdded: 'Այս լեզուն արդեն ավելացված է։', languagesTabDesc: 'Գնորդներին հասանելի լեզուներ։ Լռելյայն լեզուն օգտագործվում է որպես պահուստային ամենուր։', linkLabelDesc: 'Այս նավիգացիոն հղման համար ցուցադրվող տեքստը։', linkUrlDesc: 'Ուղին կամ URL-ը, որին ուղղորդում է այս նավիգացիոն հղումը։', diff --git a/src/app/i18n/ru.ts b/src/app/i18n/ru.ts index 11cbc7f..e57f0a9 100644 --- a/src/app/i18n/ru.ts +++ b/src/app/i18n/ru.ts @@ -679,6 +679,7 @@ export const ru: Translations = { catalogNavTopCarousel: 'Карусель категорий сверху', catalogNavTopCarouselDesc: 'Горизонтально прокручиваемые чипы категорий над сеткой каталога.', newLanguageDesc: 'Код языка ISO для добавления в поддерживаемые языки витрины (например, de, fr).', + languageAlreadyAdded: 'Этот язык уже добавлен.', languagesTabDesc: 'Языки, доступные покупателям. Язык по умолчанию используется как резервный везде.', linkLabelDesc: 'Текст, отображаемый для этой ссылки навигации.', linkUrlDesc: 'Путь или URL, на который ведёт эта ссылка навигации.', diff --git a/src/app/i18n/translations.ts b/src/app/i18n/translations.ts index 98bbd3b..488dae0 100644 --- a/src/app/i18n/translations.ts +++ b/src/app/i18n/translations.ts @@ -677,6 +677,7 @@ export interface Translations { catalogNavTopCarousel: string; catalogNavTopCarouselDesc: string; newLanguageDesc: string; + languageAlreadyAdded: string; languagesTabDesc: string; linkLabelDesc: string; linkUrlDesc: string;