@flusys/ng-localization 9.1.0 → 9.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flusys-ng-localization-translation-key-form.page-Dgn58Sh7.mjs","names":[],"sources":["../../../projects/ng-localization/pages/translation-key-form/translation-key-form.page.ts"],"sourcesContent":["import {\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n OnInit,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { FormsModule } from '@angular/forms';\nimport { disabled, form, FormField, required } from '@angular/forms/signals';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport {\n CardComponent,\n FButtonDirective,\n InputTextDirective,\n MessageService,\n ProgressSpinnerComponent,\n SelectComponent,\n TagComponent,\n TextareaDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport { finalize, forkJoin, from } from 'rxjs';\nimport { ILanguage } from '../../interfaces/language.interface';\nimport {\n ICreateTranslationKeyDto,\n ITranslationKey,\n IUpdateTranslationKeyDto,\n} from '../../interfaces/translation-key.interface';\nimport { LanguageApiService } from '../../services/language-api.service';\nimport {\n IBulkUpdateTranslationDto,\n TranslationApiService,\n} from '../../services/translation-api.service';\nimport { TranslationKeyApiService } from '../../services/translation-key-api.service';\n\ninterface ITranslationValue {\n languageId: string;\n value: string;\n translationId?: string;\n}\n\ninterface ITranslationKeyFormModel {\n key: string;\n module: string;\n defaultMessage: string;\n description: string;\n variables: string;\n}\n\n@Component({\n selector: 'lib-translation-key-form-page',\n imports: [\n CardComponent,\n InputTextDirective,\n SelectComponent,\n TextareaDirective,\n ProgressSpinnerComponent,\n TagComponent,\n FButtonDirective,\n UiIconComponent,\n FormsModule,\n FormField,\n TranslatePipe,\n ],\n providers: [MessageService],\n template: `\n <f-card>\n <ng-template #header>\n <div class=\"flex justify-between items-center p-4\">\n <h2 class=\"text-xl font-semibold m-0\">\n {{\n isEditMode()\n ? ('localization.key.edit' | translate)\n : ('localization.key.new' | translate)\n }}\n </h2>\n </div>\n </ng-template>\n\n <form (ngSubmit)=\"onSubmit()\" class=\"flex flex-col gap-6\">\n <!-- Key Info Section -->\n <div class=\"p-4 surface-ground rounded-lg\">\n <h4 class=\"font-semibold mt-0 mb-4\">\n {{ 'localization.key.about' | translate }}\n </h4>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <!-- Key Name -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"key\" class=\"font-medium\"\n >{{ 'localization.key.name' | translate }} *</label\n >\n <input\n fInputText\n id=\"key\"\n [formField]=\"formTree.key\"\n [placeholder]=\"'localization.placeholder.key.name' | translate\"\n />\n </div>\n\n <!-- Module -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"module\" class=\"font-medium\"\n >{{ 'localization.key.module' | translate }} *</label\n >\n <f-select\n id=\"module\"\n [ngModel]=\"formModel().module\"\n (ngModelChange)=\"updateModule($event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [options]=\"moduleOptions()\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [editable]=\"true\"\n [disabled]=\"isReadonly()\"\n [placeholder]=\"'localization.key.select.module' | translate\"\n class=\"w-full\"\n />\n </div>\n\n @if (isReadonly()) {\n <div class=\"md:col-span-2 -mt-2\">\n <small class=\"text-muted-color\">{{\n 'localization.key.readonly.edit.hint' | translate\n }}</small>\n </div>\n }\n\n <!-- Default Message -->\n <div class=\"flex flex-col gap-2 md:col-span-2\">\n <label for=\"defaultMessage\" class=\"font-medium\"\n >{{ 'localization.key.default.message' | translate }} *</label\n >\n <textarea\n fTextarea\n id=\"defaultMessage\"\n [formField]=\"formTree.defaultMessage\"\n [rows]=\"2\"\n [placeholder]=\"\n 'localization.placeholder.default.message' | translate\n \"\n ></textarea>\n </div>\n\n <!-- Description -->\n <div class=\"flex flex-col gap-2 md:col-span-2\">\n <label for=\"description\" class=\"font-medium\">{{\n 'localization.key.description' | translate\n }}</label>\n <input\n fInputText\n id=\"description\"\n [formField]=\"formTree.description\"\n [placeholder]=\"\n 'localization.placeholder.key.description' | translate\n \"\n />\n </div>\n\n <!-- Variables -->\n <div class=\"flex flex-col gap-2 md:col-span-2\">\n <label for=\"variables\" class=\"font-medium\">{{\n 'localization.key.variables' | translate\n }}</label>\n <input\n fInputText\n id=\"variables\"\n [formField]=\"formTree.variables\"\n [placeholder]=\"\n 'localization.key.variables.placeholder' | translate\n \"\n />\n <small class=\"text-muted-color\">{{\n 'localization.key.variables.hint' | translate\n }}</small>\n </div>\n </div>\n </div>\n\n <!-- Translations Section -->\n <div class=\"p-4 surface-ground rounded-lg\">\n <h4 class=\"font-semibold mt-0 mb-4\">\n {{ 'localization.key.translations.section' | translate }}\n </h4>\n @if (isLoadingLanguages()) {\n <div class=\"flex justify-center py-4\">\n <f-progressspinner strokeWidth=\"4\" />\n </div>\n } @else if (languages().length === 0) {\n <p class=\"text-muted-color text-center py-4\">\n {{ 'localization.key.no.languages' | translate }}\n </p>\n } @else {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n @for (lang of languages(); track lang.id) {\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex justify-between items-center\">\n <label class=\"font-medium\">\n {{ lang.name }}\n @if (lang.nativeName && lang.nativeName !== lang.name) {\n <span class=\"text-muted-color\"\n >({{ lang.nativeName }})</span\n >\n }\n </label>\n <f-tag\n [value]=\"lang.code\"\n severity=\"secondary\"\n class=\"uppercase\"\n />\n </div>\n <textarea\n fTextarea\n [ngModel]=\"getTranslationValue(lang.id)\"\n (ngModelChange)=\"setTranslationValue(lang.id, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [rows]=\"2\"\n [placeholder]=\"\n formModel().defaultMessage ||\n ('localization.key.enter.translation' | translate)\n \"\n ></textarea>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Actions -->\n <div class=\"flex justify-end gap-4 pt-4\">\n <button\n fButton\n type=\"button\"\n severity=\"secondary\"\n [outlined]=\"true\"\n (click)=\"onCancel()\"\n >\n <span pButtonLabel>{{ 'shared.cancel' | translate }}</span>\n </button>\n <button\n fButton\n type=\"submit\"\n [disabled]=\"!isFormValid() || isSaving()\"\n >\n @if (isSaving()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ \n isEditMode()\n ? ('shared.update' | translate)\n : ('shared.create' | translate)\n }}</span>\n </button>\n </div>\n </form>\n </f-card>\n `,\n})\nexport class TranslationKeyFormPage implements OnInit {\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n private readonly languageService = inject(LanguageApiService);\n private readonly translationKeyService = inject(TranslationKeyApiService);\n private readonly translationService = inject(TranslationApiService);\n private readonly messageService = inject(MessageService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly routeParams = toSignal(this.route.paramMap);\n private loadTriggered = false;\n\n readonly isSaving = signal(false);\n readonly isLoadingLanguages = signal(false);\n readonly existingKey = signal<ITranslationKey | null>(null);\n readonly isEditMode = computed(() => !!this.existingKey());\n readonly isReadonly = computed(() => this.existingKey()?.isReadonly ?? false);\n readonly languages = signal<ILanguage[]>([]);\n readonly modules = signal<string[]>([]);\n readonly translations = signal<ITranslationValue[]>([]);\n\n private translate(\n key: string,\n vars?: Record<string, string | number>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n readonly moduleOptions = computed(() =>\n this.modules().map((m) => ({ label: m, value: m })),\n );\n\n readonly formModel = signal<ITranslationKeyFormModel>({\n key: '',\n module: '',\n defaultMessage: '',\n description: '',\n variables: '',\n });\n\n readonly formTree = form(this.formModel, (f) => {\n required(f.key, {\n message: this.translate('localization.validation.key.required'),\n });\n required(f.defaultMessage, {\n message: this.translate(\n 'localization.validation.default.message.required',\n ),\n });\n disabled(f.key, { when: () => this.isReadonly() });\n });\n\n readonly isFormValid = computed(() => {\n const model = this.formModel();\n return (\n model.key.trim().length > 0 &&\n model.module.trim().length > 0 &&\n model.defaultMessage.trim().length > 0\n );\n });\n\n constructor() {\n effect(() => {\n const params = this.routeParams();\n if (!params || this.loadTriggered) return;\n\n this.loadTriggered = true;\n const id = params.get('id');\n if (id && id !== 'new') {\n this.loadTranslationKey(id);\n }\n });\n }\n\n ngOnInit(): void {\n this.isLoadingLanguages.set(true);\n\n forkJoin({\n languages: from(\n this.languageService.getAll({\n pagination: { currentPage: 0, pageSize: 100 },\n filter: {},\n sort: { serial: 'ASC', name: 'ASC' },\n }),\n ),\n modules: this.translationKeyService.getModules(),\n })\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isLoadingLanguages.set(false)),\n )\n .subscribe({\n next: ({ languages, modules }) => {\n if (languages.success && languages.data) {\n const activeLanguages = languages.data.filter((l) => l.isActive);\n this.languages.set(activeLanguages);\n this.initializeTranslations(activeLanguages);\n }\n if (modules.success && modules.data) {\n this.modules.set(modules.data);\n }\n },\n });\n }\n\n initializeTranslations(languages: ILanguage[]): void {\n const current = this.translations();\n if (current.length === 0) {\n this.translations.set(\n languages.map((lang) => ({ languageId: lang.id, value: '' })),\n );\n }\n }\n\n updateModule(value: string): void {\n this.formModel.update((m) => ({ ...m, module: value ?? '' }));\n }\n\n getTranslationValue(languageId: string): string {\n return (\n this.translations().find((t) => t.languageId === languageId)?.value ?? ''\n );\n }\n\n setTranslationValue(languageId: string, value: string): void {\n this.translations.update((list) => {\n const existing = list.find((t) => t.languageId === languageId);\n if (existing) {\n return list.map((t) =>\n t.languageId === languageId ? { ...t, value } : t,\n );\n }\n return [...list, { languageId, value }];\n });\n }\n\n loadTranslationKey(id: string): void {\n this.isSaving.set(true);\n from(this.translationKeyService.findById(id))\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isSaving.set(false)),\n )\n .subscribe({\n next: (response) => {\n if (response.success && response.data) {\n this.existingKey.set(response.data);\n this.formModel.set(this.toFormModel(response.data));\n this.loadExistingTranslations(id);\n }\n },\n error: () => this.router.navigate(['/localization/keys']),\n });\n }\n\n loadExistingTranslations(keyId: string): void {\n this.translationService\n .getByKeyId(keyId)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n if (response.success && response.data) {\n this.translations.update((list) => {\n const updated = [...list];\n response.data!.forEach((t) => {\n const existing = updated.find(\n (tr) => tr.languageId === t.languageId,\n );\n if (existing) {\n existing.value = t.value;\n existing.translationId = t.id;\n } else {\n updated.push({\n languageId: t.languageId,\n value: t.value,\n translationId: t.id,\n });\n }\n });\n return updated;\n });\n }\n },\n });\n }\n\n private toFormModel(key: ITranslationKey): ITranslationKeyFormModel {\n return {\n key: key.key,\n module: key.module,\n defaultMessage: key.defaultMessage,\n description: key.description ?? '',\n variables: key.variables?.join(', ') ?? '',\n };\n }\n\n onSubmit(): void {\n if (!this.isFormValid()) return;\n\n this.isSaving.set(true);\n const model = this.formModel();\n\n const variables = model.variables\n .split(',')\n .map((v) => v.trim())\n .filter((v) => v.length > 0);\n\n if (this.isEditMode()) {\n this.updateKey(model, variables);\n } else {\n this.createKey(model, variables);\n }\n }\n\n private createKey(\n model: ITranslationKeyFormModel,\n variables: string[],\n ): void {\n const createDto: ICreateTranslationKeyDto = {\n key: model.key,\n module: model.module,\n defaultMessage: model.defaultMessage,\n description: model.description || undefined,\n variables: variables.length > 0 ? variables : undefined,\n };\n\n from(this.translationKeyService.insert(createDto))\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n if (response.success && response.data) {\n this.saveTranslations(\n response.data.id,\n response.messageKey,\n response.messageVariables as Record<string, string | number>,\n );\n } else {\n this.isSaving.set(false);\n }\n },\n error: () => this.isSaving.set(false),\n });\n }\n\n private updateKey(\n model: ITranslationKeyFormModel,\n variables: string[],\n ): void {\n const updateDto: IUpdateTranslationKeyDto = {\n id: this.existingKey()!.id,\n key: model.key,\n module: model.module,\n defaultMessage: model.defaultMessage,\n description: model.description || undefined,\n variables: variables.length > 0 ? variables : undefined,\n };\n\n from(this.translationKeyService.update(updateDto))\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n if (response.success) {\n this.saveTranslations(\n this.existingKey()!.id,\n response.messageKey,\n response.messageVariables as Record<string, string | number>,\n );\n } else {\n this.isSaving.set(false);\n }\n },\n error: () => this.isSaving.set(false),\n });\n }\n\n private saveTranslations(\n keyId: string,\n messageKey?: string,\n messageVariables?: Record<string, string | number>,\n ): void {\n const translationsToSave: IBulkUpdateTranslationDto[] = this.translations()\n .filter((t) => t.value?.trim())\n .map((t) => ({\n id: t.translationId,\n languageId: t.languageId,\n translationKeyId: keyId,\n value: t.value,\n isVerified: false,\n }));\n\n if (translationsToSave.length === 0) {\n this.onSaveSuccess(messageKey, messageVariables);\n return;\n }\n\n this.translationService\n .bulkUpdate(translationsToSave)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: () => this.onSaveSuccess(messageKey, messageVariables),\n error: () => this.onSaveSuccess(messageKey, messageVariables),\n });\n }\n\n private onSaveSuccess(\n messageKey?: string,\n messageVariables?: Record<string, string | number>,\n ): void {\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: messageKey ? this.translate(messageKey, messageVariables) : '',\n });\n this.isSaving.set(false);\n this.router.navigate(['/localization/keys']);\n }\n\n onCancel(): void {\n this.router.navigate(['/localization/keys']);\n }\n}\n"],"mappings":"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"}