@flusys/ng-email 3.0.0 → 4.0.0-rc

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-email-email-config-form.component-Cj2U6Tgf.mjs","sources":["../../../projects/ng-email/pages/config/email-config-form.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n effect,\n inject,\n signal,\n} from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { APP_CONFIG, DEFAULT_APP_NAME, TRANSLATE_ADAPTER } from '@flusys/ng-core';\nimport { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';\nimport { AngularModule, PrimeModule, TranslatePipe } from '@flusys/ng-shared';\nimport { MessageService } from 'primeng/api';\nimport { EmailProviderEnum } from '../../enums/email-provider.enum';\nimport {\n EmailProviderConfig,\n IEmailConfig,\n IMailgunConfig,\n ISendGridConfig,\n ISmtpConfig,\n} from '../../interfaces/email-config.interface';\nimport { EmailConfigApiService } from '../../services/email-config-api.service';\n\n/**\n * Email configuration form component (create/edit)\n */\n@Component({\n selector: 'lib-email-config-form',\n imports: [AngularModule, PrimeModule, TranslatePipe],\n providers: [MessageService],\n template: `\n <div class=\"card\">\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4\">\n <div>\n <h3 class=\"text-lg sm:text-xl font-semibold m-0\">\n {{ (isEditMode() ? 'email.config.edit.title' : 'email.config.new.title') | translate }}\n </h3>\n @if (showCompanyInfo()) {\n <p class=\"text-sm text-muted-color mt-1\">\n {{ 'common.company' | translate }}: {{ currentCompanyName() }}\n </p>\n }\n </div>\n </div>\n\n <!-- Form Fields -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <!-- Common Fields -->\n <div class=\"field\">\n <label for=\"name\" class=\"block font-medium mb-2\"\n >{{ 'email.config.name' | translate }} *</label\n >\n <input\n pInputText\n id=\"name\"\n [ngModel]=\"formModel.name\"\n (ngModelChange)=\"updateFormModel('name', $event)\"\n class=\"w-full\"\n [placeholder]=\"'email.config.name.example' | translate\"\n />\n </div>\n\n <div class=\"field\">\n <label for=\"provider\" class=\"block font-medium mb-2\"\n >{{ 'email.config.provider' | translate }} *</label\n >\n <p-select\n id=\"provider\"\n [options]=\"providerOptions()\"\n [ngModel]=\"formModel.provider\"\n (ngModelChange)=\"updateFormModel('provider', $event)\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'email.config.select.provider' | translate\"\n class=\"w-full\"\n />\n </div>\n\n <div class=\"field\">\n <label for=\"fromEmail\" class=\"block font-medium mb-2\"\n >{{ 'email.config.from.email' | translate }}</label\n >\n <input\n pInputText\n id=\"fromEmail\"\n [ngModel]=\"formModel.fromEmail\"\n (ngModelChange)=\"updateFormModel('fromEmail', $event)\"\n class=\"w-full\"\n [placeholder]=\"'email.config.from.email.example' | translate\"\n />\n </div>\n\n <div class=\"field\">\n <label for=\"fromName\" class=\"block font-medium mb-2\"\n >{{ 'email.config.from.name' | translate }}</label\n >\n <input\n pInputText\n id=\"fromName\"\n [ngModel]=\"formModel.fromName\"\n (ngModelChange)=\"updateFormModel('fromName', $event)\"\n class=\"w-full\"\n [placeholder]=\"'email.config.from.name.example' | translate\"\n />\n </div>\n\n <div class=\"field flex items-center gap-2\">\n <p-toggleswitch [ngModel]=\"formModel.isActive\" (ngModelChange)=\"updateFormModel('isActive', $event)\" />\n <label>{{ 'common.active' | translate }}</label>\n </div>\n\n <div class=\"field flex items-center gap-2\">\n <p-toggleswitch [ngModel]=\"formModel.isDefault\" (ngModelChange)=\"updateFormModel('isDefault', $event)\" />\n <label>{{ 'email.config.set.as.default' | translate }}</label>\n </div>\n </div>\n\n <!-- SMTP Fields -->\n @if (formModel.provider === providerEnum.SMTP) {\n <div class=\"border-t border-surface mt-4 pt-4\">\n <h3 class=\"font-semibold mb-4\">{{ 'email.config.smtp.settings' | translate }}</h3>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div class=\"field\">\n <label for=\"smtpHost\" class=\"block font-medium mb-2\"\n >{{ 'email.config.smtp.host' | translate }} *</label\n >\n <input\n pInputText\n id=\"smtpHost\"\n [ngModel]=\"formModel.smtpHost\"\n (ngModelChange)=\"updateFormModel('smtpHost', $event)\"\n class=\"w-full\"\n [placeholder]=\"'email.config.smtp.host.example' | translate\"\n />\n </div>\n <div class=\"field\">\n <label for=\"smtpPort\" class=\"block font-medium mb-2\"\n >{{ 'email.config.port' | translate }} *</label\n >\n <p-inputNumber\n id=\"smtpPort\"\n [ngModel]=\"formModel.smtpPort\"\n (ngModelChange)=\"updateFormModel('smtpPort', $event)\"\n [useGrouping]=\"false\"\n class=\"w-full\"\n [placeholder]=\"'email.config.smtp.port.example' | translate\"\n />\n </div>\n <div class=\"field\">\n <label for=\"smtpUser\" class=\"block font-medium mb-2\"\n >{{ 'email.config.username' | translate }} *</label\n >\n <input\n pInputText\n id=\"smtpUser\"\n [ngModel]=\"formModel.smtpUser\"\n (ngModelChange)=\"updateFormModel('smtpUser', $event)\"\n class=\"w-full\"\n [placeholder]=\"'email.config.smtp.user.example' | translate\"\n />\n </div>\n <div class=\"field\">\n <label for=\"smtpPass\" class=\"block font-medium mb-2\"\n >{{ 'email.config.password' | translate }} *</label\n >\n <p-password\n id=\"smtpPass\"\n [ngModel]=\"formModel.smtpPass\"\n (ngModelChange)=\"updateFormModel('smtpPass', $event)\"\n [feedback]=\"false\"\n [toggleMask]=\"true\"\n styleClass=\"w-full\"\n inputStyleClass=\"w-full\"\n [placeholder]=\"'email.config.smtp.password.example' | translate\"\n />\n </div>\n <div class=\"field flex items-center gap-2\">\n <p-toggleswitch [ngModel]=\"formModel.smtpSecure\" (ngModelChange)=\"updateFormModel('smtpSecure', $event)\" />\n <label>{{ 'email.config.use.ssl.tls' | translate }}</label>\n </div>\n </div>\n </div>\n }\n\n <!-- SendGrid Fields -->\n @if (formModel.provider === providerEnum.SENDGRID) {\n <div class=\"border-t border-surface mt-4 pt-4\">\n <h3 class=\"font-semibold mb-4\">{{ 'email.config.sendgrid.settings' | translate }}</h3>\n <div class=\"grid grid-cols-1 gap-4\">\n <div class=\"field\">\n <label for=\"sendgridApiKey\" class=\"block font-medium mb-2\"\n >{{ 'email.config.api.key' | translate }} *</label\n >\n <p-password\n id=\"sendgridApiKey\"\n [ngModel]=\"formModel.sendgridApiKey\"\n (ngModelChange)=\"updateFormModel('sendgridApiKey', $event)\"\n [feedback]=\"false\"\n [toggleMask]=\"true\"\n styleClass=\"w-full\"\n inputStyleClass=\"w-full\"\n [placeholder]=\"'email.config.sendgrid.api.key.example' | translate\"\n />\n </div>\n </div>\n </div>\n }\n\n <!-- Mailgun Fields -->\n @if (formModel.provider === providerEnum.MAILGUN) {\n <div class=\"border-t border-surface mt-4 pt-4\">\n <h3 class=\"font-semibold mb-4\">{{ 'email.config.mailgun.settings' | translate }}</h3>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div class=\"field\">\n <label for=\"mailgunApiKey\" class=\"block font-medium mb-2\"\n >{{ 'email.config.api.key' | translate }} *</label\n >\n <p-password\n id=\"mailgunApiKey\"\n [ngModel]=\"formModel.mailgunApiKey\"\n (ngModelChange)=\"updateFormModel('mailgunApiKey', $event)\"\n [feedback]=\"false\"\n [toggleMask]=\"true\"\n styleClass=\"w-full\"\n inputStyleClass=\"w-full\"\n [placeholder]=\"'email.config.mailgun.api.key.example' | translate\"\n />\n </div>\n <div class=\"field\">\n <label for=\"mailgunDomain\" class=\"block font-medium mb-2\"\n >{{ 'email.config.domain' | translate }} *</label\n >\n <input\n pInputText\n id=\"mailgunDomain\"\n [ngModel]=\"formModel.mailgunDomain\"\n (ngModelChange)=\"updateFormModel('mailgunDomain', $event)\"\n class=\"w-full\"\n [placeholder]=\"'email.config.mailgun.domain.example' | translate\"\n />\n </div>\n <div class=\"field\">\n <label for=\"mailgunRegion\" class=\"block font-medium mb-2\"\n >{{ 'email.config.region' | translate }}</label\n >\n <p-select\n id=\"mailgunRegion\"\n [options]=\"regionOptions()\"\n [ngModel]=\"formModel.mailgunRegion\"\n (ngModelChange)=\"updateFormModel('mailgunRegion', $event)\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'email.config.select.region' | translate\"\n class=\"w-full\"\n />\n </div>\n </div>\n </div>\n }\n\n <!-- Form Actions -->\n <div class=\"flex justify-end gap-2 mt-6 pt-4 border-t border-surface\">\n <p-button\n [label]=\"'common.cancel' | translate\"\n severity=\"secondary\"\n [outlined]=\"true\"\n routerLink=\"../\"\n />\n <p-button\n [label]=\"(isEditMode() ? 'common.update' : 'common.create') | translate\"\n icon=\"pi pi-save\"\n [loading]=\"isLoading()\"\n (onClick)=\"onSave()\"\n />\n </div>\n </div>\n\n <p-toast />\n `,\n})\nexport class EmailConfigFormComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly configService = inject(EmailConfigApiService);\n private readonly messageService = inject(MessageService);\n private readonly appConfig = inject(APP_CONFIG);\n private readonly companyContext = inject(LAYOUT_AUTH_STATE, { optional: true });\n private readonly translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });\n\n // Route params as signal\n private readonly routeParams = toSignal(this.route.paramMap);\n\n readonly providerEnum = EmailProviderEnum;\n\n readonly showCompanyInfo = computed(\n () => this.appConfig.enableCompanyFeature && !!this.companyContext,\n );\n readonly currentCompanyName = computed(\n () => this.companyContext?.currentCompanyInfo()?.name ?? DEFAULT_APP_NAME,\n );\n\n readonly isLoading = signal(false);\n readonly existingConfig = signal<IEmailConfig | null>(null);\n readonly isEditMode = computed(() => !!this.existingConfig());\n\n readonly providerOptions = computed(() => [\n { label: this.translate('email.provider.smtp'), value: EmailProviderEnum.SMTP },\n { label: this.translate('email.provider.sendgrid'), value: EmailProviderEnum.SENDGRID },\n { label: this.translate('email.provider.mailgun'), value: EmailProviderEnum.MAILGUN },\n ]);\n\n readonly regionOptions = computed(() => [\n { label: this.translate('email.region.us'), value: 'us' },\n { label: this.translate('email.region.eu'), value: 'eu' },\n ]);\n\n /** Form model as signal for zoneless change detection */\n private readonly _formModel = signal({\n id: '',\n name: '',\n provider: EmailProviderEnum.SMTP as EmailProviderEnum,\n fromEmail: '',\n fromName: '',\n isActive: true,\n isDefault: false,\n // SMTP\n smtpHost: '',\n smtpPort: 587,\n smtpUser: '',\n smtpPass: '',\n smtpSecure: false,\n // SendGrid\n sendgridApiKey: '',\n // Mailgun\n mailgunApiKey: '',\n mailgunDomain: '',\n mailgunRegion: 'us',\n });\n\n /** Expose form model for template binding */\n get formModel() {\n return this._formModel();\n }\n\n /** Update form model field - triggers change detection */\n updateFormModel<K extends keyof ReturnType<typeof this._formModel>>(\n field: K,\n value: ReturnType<typeof this._formModel>[K],\n ): void {\n this._formModel.update((m) => ({ ...m, [field]: value }));\n }\n\n constructor() {\n // Effect to handle route-based initialization\n effect(() => {\n const params = this.routeParams();\n if (!params) return;\n\n const id = params.get('id');\n if (id) {\n this.loadConfig(id);\n }\n });\n }\n\n async loadConfig(id: string): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await this.configService.findByIdAsync(id);\n if (response.success && response.data) {\n const emailConfig = response.data;\n this.existingConfig.set(emailConfig);\n this._formModel.set(this.mapConfigToFormModel(emailConfig));\n }\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this.isLoading.set(false);\n }\n }\n\n private mapConfigToFormModel(emailConfig: IEmailConfig) {\n const providerConfig = emailConfig.config;\n\n return {\n id: emailConfig.id,\n name: emailConfig.name,\n provider: emailConfig.provider,\n fromEmail: emailConfig.fromEmail || '',\n fromName: emailConfig.fromName || '',\n isActive: emailConfig.isActive,\n isDefault: emailConfig.isDefault ?? false,\n // SMTP fields\n smtpHost: this.isSmtpConfig(providerConfig) ? providerConfig.host : '',\n smtpPort: this.isSmtpConfig(providerConfig) ? providerConfig.port : 587,\n smtpUser: this.isSmtpConfig(providerConfig) ? providerConfig.auth.user : '',\n smtpPass: this.isSmtpConfig(providerConfig) ? providerConfig.auth.pass : '',\n smtpSecure: this.isSmtpConfig(providerConfig) ? providerConfig.secure ?? false : false,\n // SendGrid fields\n sendgridApiKey: this.isSendGridConfig(providerConfig) ? providerConfig.apiKey : '',\n // Mailgun fields\n mailgunApiKey: this.isMailgunConfig(providerConfig) ? providerConfig.apiKey : '',\n mailgunDomain: this.isMailgunConfig(providerConfig) ? providerConfig.domain : '',\n mailgunRegion: this.isMailgunConfig(providerConfig) ? providerConfig.region ?? 'us' : 'us',\n };\n }\n\n private isSmtpConfig(config: EmailProviderConfig): config is ISmtpConfig {\n return 'host' in config && 'auth' in config;\n }\n\n private isSendGridConfig(config: EmailProviderConfig): config is ISendGridConfig {\n return 'apiKey' in config && !('domain' in config);\n }\n\n private isMailgunConfig(config: EmailProviderConfig): config is IMailgunConfig {\n return 'apiKey' in config && 'domain' in config;\n }\n\n private buildProviderConfig(): EmailProviderConfig {\n const form = this.formModel;\n\n switch (form.provider) {\n case EmailProviderEnum.SMTP:\n return {\n host: form.smtpHost,\n port: form.smtpPort,\n secure: form.smtpSecure,\n auth: { user: form.smtpUser, pass: form.smtpPass },\n } satisfies ISmtpConfig;\n\n case EmailProviderEnum.SENDGRID:\n return { apiKey: form.sendgridApiKey } satisfies ISendGridConfig;\n\n case EmailProviderEnum.MAILGUN:\n return {\n apiKey: form.mailgunApiKey,\n domain: form.mailgunDomain,\n region: form.mailgunRegion as 'us' | 'eu',\n } satisfies IMailgunConfig;\n }\n }\n\n async onSave(): Promise<void> {\n if (!this.formModel.name || !this.formModel.provider) {\n this.messageService.add({\n severity: 'warn',\n summary: this.translate('common.validation'),\n detail: this.translate('common.fill.required.fields'),\n });\n return;\n }\n\n this.isLoading.set(true);\n try {\n const dto = this.buildSaveDto();\n\n if (this.isEditMode()) {\n await this.configService.updateAsync({ id: this.formModel.id, ...dto });\n } else {\n await this.configService.insertAsync(dto);\n }\n\n this.messageService.add({\n severity: 'success',\n summary: this.translate('common.success'),\n detail: this.translate(this.isEditMode() ? 'email.config.updated' : 'email.config.created'),\n });\n\n this.router.navigate(['../'], { relativeTo: this.route });\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this.isLoading.set(false);\n }\n }\n\n private translate(key: string, variables?: Record<string, string | number>): string {\n return this.translateAdapter?.translate(key, variables) ?? key;\n }\n\n private buildSaveDto() {\n return {\n name: this.formModel.name,\n provider: this.formModel.provider,\n config: this.buildProviderConfig(),\n fromEmail: this.formModel.fromEmail || undefined,\n fromName: this.formModel.fromName || undefined,\n isActive: this.formModel.isActive,\n isDefault: this.formModel.isDefault,\n };\n }\n}\n"],"names":["i3","i7","i9"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { inject, signal, computed, Component } from '@angular/core';
3
3
  import { Router } from '@angular/router';
4
4
  import { firstValueFrom } from 'rxjs';
5
- import { APP_CONFIG, DEFAULT_APP_NAME } from '@flusys/ng-core';
5
+ import { APP_CONFIG, TRANSLATE_ADAPTER, DEFAULT_APP_NAME } from '@flusys/ng-core';
6
6
  import { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';
7
- import { EMAIL_CONFIG_PERMISSIONS, AngularModule, PrimeModule, HasPermissionDirective } from '@flusys/ng-shared';
7
+ import { EMAIL_CONFIG_PERMISSIONS, AngularModule, PrimeModule, HasPermissionDirective, TranslatePipe } from '@flusys/ng-shared';
8
8
  import { ConfirmationService, MessageService } from 'primeng/api';
9
9
  import { EmailConfigApiService, EmailProviderEnum } from './flusys-ng-email.mjs';
10
10
  import * as i1 from '@angular/forms';
@@ -30,6 +30,7 @@ class EmailConfigListComponent {
30
30
  messageService = inject(MessageService);
31
31
  appConfig = inject(APP_CONFIG);
32
32
  companyContext = inject(LAYOUT_AUTH_STATE, { optional: true });
33
+ translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
33
34
  isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
34
35
  configs = signal([], ...(ngDevMode ? [{ debugName: "configs" }] : []));
35
36
  totalRecords = signal(0, ...(ngDevMode ? [{ debugName: "totalRecords" }] : []));
@@ -65,6 +66,9 @@ class EmailConfigListComponent {
65
66
  this.totalRecords.set(response.meta?.total ?? 0);
66
67
  }
67
68
  }
69
+ catch {
70
+ // Error toast handled by global interceptor
71
+ }
68
72
  finally {
69
73
  this.isLoading.set(false);
70
74
  }
@@ -75,16 +79,21 @@ class EmailConfigListComponent {
75
79
  this.loadConfigs();
76
80
  }
77
81
  providerMeta = {
78
- [EmailProviderEnum.SMTP]: { icon: 'pi pi-server', label: 'SMTP', severity: 'info' },
79
- [EmailProviderEnum.SENDGRID]: { icon: 'pi pi-cloud', label: 'SendGrid', severity: 'success' },
80
- [EmailProviderEnum.MAILGUN]: { icon: 'pi pi-cloud', label: 'Mailgun', severity: 'warn' },
82
+ [EmailProviderEnum.SMTP]: { icon: 'pi pi-server', labelKey: 'email.providers.smtp', severity: 'info' },
83
+ [EmailProviderEnum.SENDGRID]: { icon: 'pi pi-cloud', labelKey: 'email.providers.sendgrid', severity: 'success' },
84
+ [EmailProviderEnum.MAILGUN]: { icon: 'pi pi-cloud', labelKey: 'email.providers.mailgun', severity: 'warn' },
81
85
  };
82
- defaultProviderMeta = { icon: 'pi pi-envelope', label: '', severity: 'secondary' };
86
+ defaultProviderMeta = { icon: 'pi pi-envelope', labelKey: '', severity: 'secondary' };
83
87
  getProviderIcon(provider) {
84
88
  return this.providerMeta[provider]?.icon ?? this.defaultProviderMeta.icon;
85
89
  }
86
90
  getProviderLabel(provider) {
87
- return this.providerMeta[provider]?.label ?? provider ?? '';
91
+ const labelKey = this.providerMeta[provider]?.labelKey;
92
+ if (labelKey) {
93
+ return this.translate(labelKey);
94
+ }
95
+ // Fallback to dynamic key for unknown providers
96
+ return provider ? this.translate(`email.providers.${provider}`) : '';
88
97
  }
89
98
  getProviderSeverity(provider) {
90
99
  return this.providerMeta[provider]?.severity ?? this.defaultProviderMeta.severity;
@@ -100,8 +109,8 @@ class EmailConfigListComponent {
100
109
  if (!config || !recipient) {
101
110
  this.messageService.add({
102
111
  severity: 'warn',
103
- summary: 'Validation',
104
- detail: 'Please enter a recipient email address.',
112
+ summary: this.translate('common.validation'),
113
+ detail: this.translate('email.config.enter.recipient'),
105
114
  });
106
115
  return;
107
116
  }
@@ -111,16 +120,16 @@ class EmailConfigListComponent {
111
120
  if (response.data?.success) {
112
121
  this.messageService.add({
113
122
  severity: 'success',
114
- summary: 'Success',
115
- detail: `Test email sent successfully! Message ID: ${response.data.messageId}`,
123
+ summary: this.translate('common.success'),
124
+ detail: this.translate('email.config.test.sent.success', { messageId: response.data.messageId ?? '' }),
116
125
  });
117
126
  this.showTestDialog.set(false);
118
127
  }
119
128
  else {
120
129
  this.messageService.add({
121
130
  severity: 'error',
122
- summary: 'Error',
123
- detail: response.data?.error || 'Failed to send test email.',
131
+ summary: this.translate('common.error'),
132
+ detail: response.data?.error || this.translate('email.config.test.sent.failed'),
124
133
  });
125
134
  }
126
135
  }
@@ -133,8 +142,8 @@ class EmailConfigListComponent {
133
142
  }
134
143
  onDelete(config) {
135
144
  this.confirmationService.confirm({
136
- message: `Are you sure you want to delete "${config.name}"?`,
137
- header: 'Delete Configuration',
145
+ message: this.translate('email.config.delete.confirm', { name: config.name }),
146
+ header: this.translate('email.config.delete.title'),
138
147
  icon: 'pi pi-exclamation-triangle',
139
148
  acceptButtonStyleClass: 'p-button-danger',
140
149
  accept: async () => {
@@ -142,8 +151,8 @@ class EmailConfigListComponent {
142
151
  await this.configService.deleteAsync({ id: config.id, type: 'delete' });
143
152
  this.messageService.add({
144
153
  severity: 'success',
145
- summary: 'Success',
146
- detail: 'Configuration deleted successfully.',
154
+ summary: this.translate('common.success'),
155
+ detail: this.translate('email.config.deleted'),
147
156
  });
148
157
  this.loadConfigs();
149
158
  }
@@ -153,21 +162,24 @@ class EmailConfigListComponent {
153
162
  },
154
163
  });
155
164
  }
165
+ translate(key, variables) {
166
+ return this.translateAdapter?.translate(key, variables) ?? key;
167
+ }
156
168
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: EmailConfigListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
157
169
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: EmailConfigListComponent, isStandalone: true, selector: "lib-email-config-list", providers: [ConfirmationService, MessageService], ngImport: i0, template: `
158
170
  <div class="card">
159
171
  <div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4">
160
172
  <div>
161
- <h3 class="text-lg sm:text-xl font-semibold m-0">Email Configurations</h3>
173
+ <h3 class="text-lg sm:text-xl font-semibold m-0">{{ 'email.config.title' | translate }}</h3>
162
174
  @if (showCompanyInfo()) {
163
175
  <p class="text-sm text-muted-color mt-1">
164
- Company: {{ currentCompanyName() }}
176
+ {{ 'common.company' | translate }}: {{ currentCompanyName() }}
165
177
  </p>
166
178
  }
167
179
  </div>
168
180
  <p-button
169
181
  *hasPermission="EMAIL_CONFIG_PERMISSIONS.CREATE"
170
- label="New Configuration"
182
+ [label]="'email.config.new' | translate"
171
183
  icon="pi pi-plus"
172
184
  (onClick)="onCreate()"
173
185
  styleClass="w-full sm:w-auto"
@@ -190,12 +202,12 @@ class EmailConfigListComponent {
190
202
  >
191
203
  <ng-template #header>
192
204
  <tr>
193
- <th>Name</th>
194
- <th>Provider</th>
195
- <th class="hidden md:table-cell">From Email</th>
196
- <th>Status</th>
197
- <th class="hidden lg:table-cell">Created</th>
198
- <th class="w-[120px]">Actions</th>
205
+ <th>{{ 'common.name' | translate }}</th>
206
+ <th>{{ 'email.config.provider' | translate }}</th>
207
+ <th class="hidden md:table-cell">{{ 'email.config.from.email' | translate }}</th>
208
+ <th>{{ 'common.status' | translate }}</th>
209
+ <th class="hidden lg:table-cell">{{ 'common.created' | translate }}</th>
210
+ <th class="w-[120px]">{{ 'common.actions' | translate }}</th>
199
211
  </tr>
200
212
  </ng-template>
201
213
 
@@ -205,7 +217,7 @@ class EmailConfigListComponent {
205
217
  <i [class]="getProviderIcon(config.provider)" class="mr-2 text-muted-color"></i>
206
218
  {{ config.name }}
207
219
  @if (config.isDefault) {
208
- <p-tag value="Default" severity="contrast" class="ml-2" />
220
+ <p-tag [value]="'common.default' | translate" severity="contrast" class="ml-2" />
209
221
  }
210
222
  </td>
211
223
  <td>
@@ -214,10 +226,10 @@ class EmailConfigListComponent {
214
226
  [severity]="getProviderSeverity(config.provider)"
215
227
  />
216
228
  </td>
217
- <td class="hidden md:table-cell">{{ config.fromEmail || '-' }}</td>
229
+ <td class="hidden md:table-cell">{{ config.fromEmail || ('shared.na' | translate) }}</td>
218
230
  <td>
219
231
  <p-tag
220
- [value]="config.isActive ? 'Active' : 'Inactive'"
232
+ [value]="(config.isActive ? 'common.active' : 'common.inactive') | translate"
221
233
  [severity]="config.isActive ? 'success' : 'secondary'"
222
234
  />
223
235
  </td>
@@ -229,7 +241,7 @@ class EmailConfigListComponent {
229
241
  icon="pi pi-send"
230
242
  [text]="true"
231
243
  size="small"
232
- pTooltip="Test"
244
+ [pTooltip]="'common.test' | translate"
233
245
  (onClick)="onTest(config)"
234
246
  />
235
247
  <p-button
@@ -238,7 +250,7 @@ class EmailConfigListComponent {
238
250
  [text]="true"
239
251
  severity="secondary"
240
252
  size="small"
241
- pTooltip="Edit"
253
+ [pTooltip]="'common.edit' | translate"
242
254
  (onClick)="onEdit(config.id)"
243
255
  />
244
256
  <p-button
@@ -247,7 +259,7 @@ class EmailConfigListComponent {
247
259
  [text]="true"
248
260
  severity="danger"
249
261
  size="small"
250
- pTooltip="Delete"
262
+ [pTooltip]="'common.delete' | translate"
251
263
  (onClick)="onDelete(config)"
252
264
  />
253
265
  </div>
@@ -258,7 +270,7 @@ class EmailConfigListComponent {
258
270
  <ng-template #emptymessage>
259
271
  <tr>
260
272
  <td colspan="6" class="text-center py-4 text-muted-color">
261
- No email configurations found. Add a provider to start sending emails.
273
+ {{ 'email.config.empty' | translate }}
262
274
  </td>
263
275
  </tr>
264
276
  </ng-template>
@@ -268,7 +280,7 @@ class EmailConfigListComponent {
268
280
 
269
281
  <!-- Test Email Dialog -->
270
282
  <p-dialog
271
- header="Test Email Configuration"
283
+ [header]="'email.config.test.dialog.title' | translate"
272
284
  [visible]="showTestDialog()"
273
285
  (visibleChange)="showTestDialog.set($event)"
274
286
  [modal]="true"
@@ -277,7 +289,7 @@ class EmailConfigListComponent {
277
289
  >
278
290
  <div class="grid gap-4">
279
291
  <div class="field">
280
- <label class="block font-medium mb-2">Configuration</label>
292
+ <label class="block font-medium mb-2">{{ 'email.config.configuration' | translate }}</label>
281
293
  <input
282
294
  pInputText
283
295
  [value]="selectedConfig()?.name || ''"
@@ -287,7 +299,7 @@ class EmailConfigListComponent {
287
299
  </div>
288
300
 
289
301
  <div class="field">
290
- <label class="block font-medium mb-2">Provider</label>
302
+ <label class="block font-medium mb-2">{{ 'email.config.provider' | translate }}</label>
291
303
  <p-tag
292
304
  [value]="getProviderLabel(selectedConfig()?.provider || '')"
293
305
  [severity]="getProviderSeverity(selectedConfig()?.provider || '')"
@@ -295,30 +307,30 @@ class EmailConfigListComponent {
295
307
  </div>
296
308
 
297
309
  <div class="field">
298
- <label class="block font-medium mb-2">Recipient Email *</label>
310
+ <label class="block font-medium mb-2">{{ 'email.config.recipient.email' | translate }} *</label>
299
311
  <input
300
312
  pInputText
301
313
  [ngModel]="testRecipient()"
302
314
  (ngModelChange)="testRecipient.set($event)"
303
315
  class="w-full"
304
- placeholder="recipient@example.com"
316
+ [placeholder]="'email.recipient.example' | translate"
305
317
  type="email"
306
318
  />
307
319
  <small class="text-muted-color mt-1 block">
308
- A test email will be sent to this address
320
+ {{ 'email.config.test.dialog.hint' | translate }}
309
321
  </small>
310
322
  </div>
311
323
  </div>
312
324
 
313
325
  <ng-template #footer>
314
326
  <p-button
315
- label="Cancel"
327
+ [label]="'common.cancel' | translate"
316
328
  severity="secondary"
317
329
  [outlined]="true"
318
330
  (onClick)="showTestDialog.set(false)"
319
331
  />
320
332
  <p-button
321
- label="Send Test"
333
+ [label]="'email.config.send.test' | translate"
322
334
  icon="pi pi-send"
323
335
  [loading]="isSendingTest()"
324
336
  (onClick)="sendTestEmail()"
@@ -328,29 +340,28 @@ class EmailConfigListComponent {
328
340
 
329
341
  <p-confirmDialog />
330
342
  <p-toast />
331
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i7.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "component", type: i8.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: i8$1.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "motionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "directive", type: i10.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "pipe", type: i11.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
343
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i7.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "component", type: i8.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: i8$1.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "motionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "directive", type: i10.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "pipe", type: i11.DatePipe, name: "date" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
332
344
  }
333
345
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: EmailConfigListComponent, decorators: [{
334
346
  type: Component,
335
347
  args: [{
336
348
  selector: 'lib-email-config-list',
337
- changeDetection: ChangeDetectionStrategy.OnPush,
338
- imports: [AngularModule, PrimeModule, HasPermissionDirective],
349
+ imports: [AngularModule, PrimeModule, HasPermissionDirective, TranslatePipe],
339
350
  providers: [ConfirmationService, MessageService],
340
351
  template: `
341
352
  <div class="card">
342
353
  <div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4">
343
354
  <div>
344
- <h3 class="text-lg sm:text-xl font-semibold m-0">Email Configurations</h3>
355
+ <h3 class="text-lg sm:text-xl font-semibold m-0">{{ 'email.config.title' | translate }}</h3>
345
356
  @if (showCompanyInfo()) {
346
357
  <p class="text-sm text-muted-color mt-1">
347
- Company: {{ currentCompanyName() }}
358
+ {{ 'common.company' | translate }}: {{ currentCompanyName() }}
348
359
  </p>
349
360
  }
350
361
  </div>
351
362
  <p-button
352
363
  *hasPermission="EMAIL_CONFIG_PERMISSIONS.CREATE"
353
- label="New Configuration"
364
+ [label]="'email.config.new' | translate"
354
365
  icon="pi pi-plus"
355
366
  (onClick)="onCreate()"
356
367
  styleClass="w-full sm:w-auto"
@@ -373,12 +384,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
373
384
  >
374
385
  <ng-template #header>
375
386
  <tr>
376
- <th>Name</th>
377
- <th>Provider</th>
378
- <th class="hidden md:table-cell">From Email</th>
379
- <th>Status</th>
380
- <th class="hidden lg:table-cell">Created</th>
381
- <th class="w-[120px]">Actions</th>
387
+ <th>{{ 'common.name' | translate }}</th>
388
+ <th>{{ 'email.config.provider' | translate }}</th>
389
+ <th class="hidden md:table-cell">{{ 'email.config.from.email' | translate }}</th>
390
+ <th>{{ 'common.status' | translate }}</th>
391
+ <th class="hidden lg:table-cell">{{ 'common.created' | translate }}</th>
392
+ <th class="w-[120px]">{{ 'common.actions' | translate }}</th>
382
393
  </tr>
383
394
  </ng-template>
384
395
 
@@ -388,7 +399,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
388
399
  <i [class]="getProviderIcon(config.provider)" class="mr-2 text-muted-color"></i>
389
400
  {{ config.name }}
390
401
  @if (config.isDefault) {
391
- <p-tag value="Default" severity="contrast" class="ml-2" />
402
+ <p-tag [value]="'common.default' | translate" severity="contrast" class="ml-2" />
392
403
  }
393
404
  </td>
394
405
  <td>
@@ -397,10 +408,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
397
408
  [severity]="getProviderSeverity(config.provider)"
398
409
  />
399
410
  </td>
400
- <td class="hidden md:table-cell">{{ config.fromEmail || '-' }}</td>
411
+ <td class="hidden md:table-cell">{{ config.fromEmail || ('shared.na' | translate) }}</td>
401
412
  <td>
402
413
  <p-tag
403
- [value]="config.isActive ? 'Active' : 'Inactive'"
414
+ [value]="(config.isActive ? 'common.active' : 'common.inactive') | translate"
404
415
  [severity]="config.isActive ? 'success' : 'secondary'"
405
416
  />
406
417
  </td>
@@ -412,7 +423,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
412
423
  icon="pi pi-send"
413
424
  [text]="true"
414
425
  size="small"
415
- pTooltip="Test"
426
+ [pTooltip]="'common.test' | translate"
416
427
  (onClick)="onTest(config)"
417
428
  />
418
429
  <p-button
@@ -421,7 +432,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
421
432
  [text]="true"
422
433
  severity="secondary"
423
434
  size="small"
424
- pTooltip="Edit"
435
+ [pTooltip]="'common.edit' | translate"
425
436
  (onClick)="onEdit(config.id)"
426
437
  />
427
438
  <p-button
@@ -430,7 +441,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
430
441
  [text]="true"
431
442
  severity="danger"
432
443
  size="small"
433
- pTooltip="Delete"
444
+ [pTooltip]="'common.delete' | translate"
434
445
  (onClick)="onDelete(config)"
435
446
  />
436
447
  </div>
@@ -441,7 +452,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
441
452
  <ng-template #emptymessage>
442
453
  <tr>
443
454
  <td colspan="6" class="text-center py-4 text-muted-color">
444
- No email configurations found. Add a provider to start sending emails.
455
+ {{ 'email.config.empty' | translate }}
445
456
  </td>
446
457
  </tr>
447
458
  </ng-template>
@@ -451,7 +462,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
451
462
 
452
463
  <!-- Test Email Dialog -->
453
464
  <p-dialog
454
- header="Test Email Configuration"
465
+ [header]="'email.config.test.dialog.title' | translate"
455
466
  [visible]="showTestDialog()"
456
467
  (visibleChange)="showTestDialog.set($event)"
457
468
  [modal]="true"
@@ -460,7 +471,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
460
471
  >
461
472
  <div class="grid gap-4">
462
473
  <div class="field">
463
- <label class="block font-medium mb-2">Configuration</label>
474
+ <label class="block font-medium mb-2">{{ 'email.config.configuration' | translate }}</label>
464
475
  <input
465
476
  pInputText
466
477
  [value]="selectedConfig()?.name || ''"
@@ -470,7 +481,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
470
481
  </div>
471
482
 
472
483
  <div class="field">
473
- <label class="block font-medium mb-2">Provider</label>
484
+ <label class="block font-medium mb-2">{{ 'email.config.provider' | translate }}</label>
474
485
  <p-tag
475
486
  [value]="getProviderLabel(selectedConfig()?.provider || '')"
476
487
  [severity]="getProviderSeverity(selectedConfig()?.provider || '')"
@@ -478,30 +489,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
478
489
  </div>
479
490
 
480
491
  <div class="field">
481
- <label class="block font-medium mb-2">Recipient Email *</label>
492
+ <label class="block font-medium mb-2">{{ 'email.config.recipient.email' | translate }} *</label>
482
493
  <input
483
494
  pInputText
484
495
  [ngModel]="testRecipient()"
485
496
  (ngModelChange)="testRecipient.set($event)"
486
497
  class="w-full"
487
- placeholder="recipient@example.com"
498
+ [placeholder]="'email.recipient.example' | translate"
488
499
  type="email"
489
500
  />
490
501
  <small class="text-muted-color mt-1 block">
491
- A test email will be sent to this address
502
+ {{ 'email.config.test.dialog.hint' | translate }}
492
503
  </small>
493
504
  </div>
494
505
  </div>
495
506
 
496
507
  <ng-template #footer>
497
508
  <p-button
498
- label="Cancel"
509
+ [label]="'common.cancel' | translate"
499
510
  severity="secondary"
500
511
  [outlined]="true"
501
512
  (onClick)="showTestDialog.set(false)"
502
513
  />
503
514
  <p-button
504
- label="Send Test"
515
+ [label]="'email.config.send.test' | translate"
505
516
  icon="pi pi-send"
506
517
  [loading]="isSendingTest()"
507
518
  (onClick)="sendTestEmail()"
@@ -516,4 +527,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
516
527
  }] });
517
528
 
518
529
  export { EmailConfigListComponent };
519
- //# sourceMappingURL=flusys-ng-email-email-config-list.component-Dt9PY9xD.mjs.map
530
+ //# sourceMappingURL=flusys-ng-email-email-config-list.component-oznfQvxo.mjs.map