@flusys/ng-localization 9.1.2 → 9.2.1
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.
- package/fesm2022/{flusys-ng-localization-language-form.page-BdxZ6meb.mjs → flusys-ng-localization-language-form.page-DB-cn7MO.mjs} +24 -20
- package/fesm2022/flusys-ng-localization-language-form.page-DB-cn7MO.mjs.map +1 -0
- package/fesm2022/{flusys-ng-localization-language-list.page-B8wnYNNd.mjs → flusys-ng-localization-language-list.page-CfM-mc9g.mjs} +29 -21
- package/fesm2022/{flusys-ng-localization-language-list.page-B8wnYNNd.mjs.map → flusys-ng-localization-language-list.page-CfM-mc9g.mjs.map} +1 -1
- package/fesm2022/flusys-ng-localization-localization-container.page-CsrYVvth.mjs.map +1 -1
- package/fesm2022/{flusys-ng-localization-translation-key-form.page-Dgn58Sh7.mjs → flusys-ng-localization-translation-key-form.page-BCkDs0tt.mjs} +43 -36
- package/fesm2022/flusys-ng-localization-translation-key-form.page-BCkDs0tt.mjs.map +1 -0
- package/fesm2022/{flusys-ng-localization-translation-key-list.page-DhRI5UvT.mjs → flusys-ng-localization-translation-key-list.page-CGC5125Z.mjs} +28 -15
- package/fesm2022/flusys-ng-localization-translation-key-list.page-CGC5125Z.mjs.map +1 -0
- package/fesm2022/flusys-ng-localization.mjs +42 -19
- package/fesm2022/flusys-ng-localization.mjs.map +1 -1
- package/package.json +5 -5
- package/types/flusys-ng-localization.d.ts +2 -0
- package/fesm2022/flusys-ng-localization-language-form.page-BdxZ6meb.mjs.map +0 -1
- package/fesm2022/flusys-ng-localization-translation-key-form.page-Dgn58Sh7.mjs.map +0 -1
- package/fesm2022/flusys-ng-localization-translation-key-list.page-DhRI5UvT.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
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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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-localization-translation-key-list.page-DhRI5UvT.mjs","names":[],"sources":["../../../projects/ng-localization/pages/translation-key-list/translation-key-list.page.ts"],"sourcesContent":["import {\n Component,\n computed,\n DestroyRef,\n inject,\n OnInit,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormsModule } from '@angular/forms';\nimport { Router } from '@angular/router';\nimport {\n HasPermissionDirective,\n TranslatePipe,\n TranslateService,\n TRANSLATION_KEY_PERMISSIONS,\n} from '@flusys/ng-shared';\nimport {\n ConfirmationService,\n FButtonDirective,\n IconFieldComponent,\n InputIconComponent,\n InputTextDirective,\n MessageService,\n SelectComponent,\n TableComponent,\n TagComponent,\n TooltipDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport { forkJoin, from } from 'rxjs';\nimport { ILanguage } from '../../interfaces/language.interface';\nimport { ITranslationKey } from '../../interfaces/translation-key.interface';\nimport { LanguageApiService } from '../../services/language-api.service';\nimport { TranslationApiService } from '../../services/translation-api.service';\nimport { TranslationKeyApiService } from '../../services/translation-key-api.service';\n\n@Component({\n selector: 'lib-translation-key-list-page',\n imports: [\n FButtonDirective,\n UiIconComponent,\n SelectComponent,\n IconFieldComponent,\n InputIconComponent,\n InputTextDirective,\n TableComponent,\n TagComponent,\n TooltipDirective,\n FormsModule,\n HasPermissionDirective,\n TranslatePipe,\n ],\n template: `\n <div class=\"card\">\n <div\n class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4\"\n >\n <div>\n <h3 class=\"text-lg sm:text-xl font-semibold m-0\">\n {{ 'localization.key.title' | translate }}\n </h3>\n <p class=\"text-sm text-muted-color mt-1\">\n {{ 'localization.key.subtitle' | translate }}\n </p>\n </div>\n <div class=\"flex gap-2\">\n <button\n fButton\n *hasPermission=\"TRANSLATION_KEY_PERMISSIONS.CREATE\"\n (click)=\"onCreate()\"\n >\n <ui-icon pButtonIcon name=\"plus\"></ui-icon>\n <span pButtonLabel>{{ 'localization.key.new' | translate }}</span>\n </button>\n </div>\n </div>\n\n <div class=\"flex flex-col md:flex-row gap-4 mb-4\">\n <div class=\"flex-1\">\n <f-select\n [options]=\"moduleOptions()\"\n [ngModel]=\"selectedModule()\"\n (ngModelChange)=\"onModuleChange($event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'localization.key.filter.module' | translate\"\n [showClear]=\"true\"\n class=\"w-full\"\n />\n </div>\n <div class=\"flex-1\">\n <f-iconfield class=\"w-full\">\n <f-inputicon icon=\"search\" />\n <input\n fInputText\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"searchTerm.set($event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [placeholder]=\"'shared.search' | translate\"\n class=\"w-full\"\n />\n </f-iconfield>\n </div>\n </div>\n\n <!-- Table -->\n <f-table\n [value]=\"filteredKeys()\"\n [loading]=\"isLoading()\"\n [paginator]=\"true\"\n [rows]=\"15\"\n [rowsPerPageOptions]=\"[10, 15, 25, 50]\"\n >\n <ng-template #header>\n <tr>\n <th style=\"width: 15%\">\n {{ 'localization.key.module' | translate }}\n </th>\n <th style=\"width: 25%\">\n {{ 'localization.key.name' | translate }}\n </th>\n <th style=\"width: 35%\">\n {{ 'localization.key.default.message' | translate }}\n </th>\n <th style=\"width: 10%\">\n {{ 'localization.key.translations' | translate }}\n </th>\n <th style=\"width: 15%\">{{ 'shared.actions' | translate }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-key>\n @let translationCount = getTranslationCount(key.id);\n @let languageCount = languages().length;\n <tr>\n <td>\n <f-tag [value]=\"key.module\" severity=\"secondary\" />\n </td>\n <td>\n <div class=\"flex items-center gap-2\">\n <span class=\"font-medium\">{{ key.key }}</span>\n @if (key.isReadonly) {\n <f-tag\n [value]=\"'shared.read.only' | translate\"\n severity=\"warn\"\n />\n }\n </div>\n @if (key.description) {\n <small class=\"text-muted-color\">{{ key.description }}</small>\n }\n </td>\n <td>{{ key.defaultMessage }}</td>\n <td class=\"text-center\">\n <span\n class=\"text-sm\"\n [class.text-green-500]=\"translationCount === languageCount\"\n [class.text-orange-500]=\"\n translationCount < languageCount && translationCount > 0\n \"\n [class.text-muted-color]=\"translationCount === 0\"\n >\n {{ translationCount }}/{{ languageCount }}\n </span>\n </td>\n <td>\n <div class=\"flex gap-1\">\n <button\n fButton\n *hasPermission=\"TRANSLATION_KEY_PERMISSIONS.UPDATE\"\n [text]=\"true\"\n severity=\"secondary\"\n size=\"small\"\n [fTooltip]=\"'shared.edit' | translate\"\n (click)=\"onEdit(key)\"\n >\n <ui-icon pButtonIcon name=\"pencil\"></ui-icon>\n </button>\n <button\n fButton\n *hasPermission=\"TRANSLATION_KEY_PERMISSIONS.DELETE\"\n [text]=\"true\"\n severity=\"danger\"\n size=\"small\"\n [disabled]=\"key.isReadonly\"\n [fTooltip]=\"\n (key.isReadonly\n ? 'localization.key.readonly.delete.forbidden'\n : 'shared.delete'\n ) | translate\n \"\n (click)=\"onDelete(key)\"\n >\n <ui-icon pButtonIcon name=\"trash\"></ui-icon>\n </button>\n </div>\n </td>\n </tr>\n </ng-template>\n <ng-template #emptymessage>\n <tr>\n <td colspan=\"5\" class=\"text-center py-4 text-muted-color\">\n {{ 'localization.key.empty' | translate }}\n </td>\n </tr>\n </ng-template>\n </f-table>\n </div>\n `,\n})\nexport class TranslationKeyListPage implements OnInit {\n readonly TRANSLATION_KEY_PERMISSIONS = TRANSLATION_KEY_PERMISSIONS;\n\n private readonly router = inject(Router);\n private readonly languageService = inject(LanguageApiService);\n private readonly translationKeyService = inject(TranslationKeyApiService);\n private readonly translationService = inject(TranslationApiService);\n private readonly confirmationService = inject(ConfirmationService);\n private readonly messageService = inject(MessageService);\n private readonly translateService = inject(TranslateService);\n private readonly destroyRef = inject(DestroyRef);\n\n readonly isLoading = signal(false);\n readonly languages = signal<ILanguage[]>([]);\n readonly modules = signal<string[]>([]);\n readonly translationKeys = signal<ITranslationKey[]>([]);\n readonly translationCounts = signal<Map<string, number>>(new Map());\n readonly selectedModule = signal<string | null>(null);\n readonly searchTerm = signal('');\n\n readonly moduleOptions = computed(() => [\n { label: this.translateService.translate('shared.all'), value: null },\n ...this.modules().map((m) => ({ label: m, value: m })),\n ]);\n\n readonly filteredKeys = computed(() => {\n let keys = this.translationKeys();\n const module = this.selectedModule();\n const search = this.searchTerm().toLowerCase().trim();\n\n if (module) {\n keys = keys.filter((k) => k.module === module);\n }\n\n if (search) {\n keys = keys.filter(\n (k) =>\n k.key.toLowerCase().includes(search) ||\n k.defaultMessage.toLowerCase().includes(search) ||\n k.module.toLowerCase().includes(search),\n );\n }\n\n return keys;\n });\n\n ngOnInit(): void {\n this.loadData();\n }\n\n loadData(): void {\n this.isLoading.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 keys: from(\n this.translationKeyService.getAll({\n pagination: { currentPage: 0, pageSize: 1000 },\n filter: {},\n sort: { module: 'ASC', key: 'ASC' },\n }),\n ),\n })\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: ({ languages, modules, keys }) => {\n if (languages.success && languages.data) {\n this.languages.set(languages.data.filter((l) => l.isActive));\n }\n if (modules.success && modules.data) {\n this.modules.set(modules.data);\n }\n if (keys.success && keys.data) {\n this.translationKeys.set(keys.data);\n this.loadTranslationCounts();\n }\n this.isLoading.set(false);\n },\n error: () => {\n this.isLoading.set(false);\n },\n });\n }\n\n loadTranslationCounts(): void {\n this.translationService\n .getCounts()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n if (response.success && response.data) {\n this.translationCounts.set(new Map(Object.entries(response.data)));\n }\n },\n });\n }\n\n getTranslationCount(keyId: string): number {\n return this.translationCounts().get(keyId) ?? 0;\n }\n\n onModuleChange(value: string | null): void {\n this.selectedModule.set(value);\n }\n\n onCreate(): void {\n this.router.navigate(['/localization/keys/new']);\n }\n\n onEdit(key: ITranslationKey): void {\n this.router.navigate(['/localization/keys', key.id]);\n }\n\n onDelete(key: ITranslationKey): void {\n this.confirmationService.confirm({\n message: this.translateService.translate('shared.confirm.delete'),\n header: this.translateService.translate('localization.key.delete.title'),\n icon: 'exclamation-triangle',\n acceptButtonStyleClass: 'p-button-danger',\n accept: () => {\n from(this.translationKeyService.delete({ id: key.id, type: 'delete' }))\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n if (response.success) {\n this.messageService.add({\n severity: 'success',\n summary: this.translateService.translate('shared.success'),\n detail: response.messageKey\n ? this.translateService.translate(\n response.messageKey,\n response.messageVariables as Record<\n string,\n string | number\n >,\n )\n : (response.message ?? ''),\n });\n this.loadData();\n }\n },\n });\n },\n });\n }\n}\n"],"mappings":"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"}
|