@flusys/ng-email 3.0.1 → 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.
- package/README.md +2 -2
- package/fesm2022/{flusys-ng-email-email-config-form.component-tg4pKP7G.mjs → flusys-ng-email-email-config-form.component-Cj2U6Tgf.mjs} +98 -92
- package/fesm2022/flusys-ng-email-email-config-form.component-Cj2U6Tgf.mjs.map +1 -0
- package/fesm2022/{flusys-ng-email-email-config-list.component-Dt9PY9xD.mjs → flusys-ng-email-email-config-list.component-oznfQvxo.mjs} +81 -70
- package/fesm2022/flusys-ng-email-email-config-list.component-oznfQvxo.mjs.map +1 -0
- package/fesm2022/{flusys-ng-email-template-form.component-vlfHz6VE.mjs → flusys-ng-email-template-form.component-CgJZiMCa.mjs} +67 -61
- package/fesm2022/flusys-ng-email-template-form.component-CgJZiMCa.mjs.map +1 -0
- package/fesm2022/{flusys-ng-email-template-list.component-krrpsjDv.mjs → flusys-ng-email-template-list.component-DHnuMTpB.mjs} +80 -70
- package/fesm2022/flusys-ng-email-template-list.component-DHnuMTpB.mjs.map +1 -0
- package/fesm2022/flusys-ng-email.mjs +256 -31
- package/fesm2022/flusys-ng-email.mjs.map +1 -1
- package/package.json +4 -4
- package/types/flusys-ng-email.d.ts +15 -6
- package/fesm2022/flusys-ng-email-email-config-form.component-tg4pKP7G.mjs.map +0 -1
- package/fesm2022/flusys-ng-email-email-config-list.component-Dt9PY9xD.mjs.map +0 -1
- package/fesm2022/flusys-ng-email-template-form.component-vlfHz6VE.mjs.map +0 -1
- package/fesm2022/flusys-ng-email-template-list.component-krrpsjDv.mjs.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, signal, computed,
|
|
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_TEMPLATE_PERMISSIONS, AngularModule, PrimeModule, HasPermissionDirective } from '@flusys/ng-shared';
|
|
7
|
+
import { EMAIL_TEMPLATE_PERMISSIONS, AngularModule, PrimeModule, HasPermissionDirective, TranslatePipe } from '@flusys/ng-shared';
|
|
8
8
|
import { ConfirmationService, MessageService } from 'primeng/api';
|
|
9
9
|
import { EmailTemplateApiService, EmailConfigApiService, EmailSendService } from './flusys-ng-email.mjs';
|
|
10
10
|
import * as i1 from '@angular/forms';
|
|
@@ -33,6 +33,7 @@ class TemplateListComponent {
|
|
|
33
33
|
messageService = inject(MessageService);
|
|
34
34
|
appConfig = inject(APP_CONFIG);
|
|
35
35
|
companyContext = inject(LAYOUT_AUTH_STATE, { optional: true });
|
|
36
|
+
translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
|
|
36
37
|
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
37
38
|
templates = signal([], ...(ngDevMode ? [{ debugName: "templates" }] : []));
|
|
38
39
|
totalRecords = signal(0, ...(ngDevMode ? [{ debugName: "totalRecords" }] : []));
|
|
@@ -62,7 +63,7 @@ class TemplateListComponent {
|
|
|
62
63
|
this._variableValues.update((v) => ({ ...v, [key]: value }));
|
|
63
64
|
}
|
|
64
65
|
configOptions = computed(() => this.configs().map((c) => ({
|
|
65
|
-
label: `${c.name} (${c.provider})`,
|
|
66
|
+
label: `${c.name} (${this.translate(`email.providers.${c.provider}`)})`,
|
|
66
67
|
value: c.id,
|
|
67
68
|
})), ...(ngDevMode ? [{ debugName: "configOptions" }] : []));
|
|
68
69
|
/** Extract variables from template content */
|
|
@@ -107,6 +108,9 @@ class TemplateListComponent {
|
|
|
107
108
|
this.totalRecords.set(response.meta?.total ?? 0);
|
|
108
109
|
}
|
|
109
110
|
}
|
|
111
|
+
catch {
|
|
112
|
+
// Error toast handled by global interceptor
|
|
113
|
+
}
|
|
110
114
|
finally {
|
|
111
115
|
this.isLoading.set(false);
|
|
112
116
|
}
|
|
@@ -136,6 +140,9 @@ class TemplateListComponent {
|
|
|
136
140
|
this.configs.set(response.data ?? []);
|
|
137
141
|
}
|
|
138
142
|
}
|
|
143
|
+
catch {
|
|
144
|
+
// Error toast handled by global interceptor
|
|
145
|
+
}
|
|
139
146
|
finally {
|
|
140
147
|
this.isLoadingConfigs.set(false);
|
|
141
148
|
}
|
|
@@ -146,8 +153,8 @@ class TemplateListComponent {
|
|
|
146
153
|
if (!template || !model.configId || !model.recipient) {
|
|
147
154
|
this.messageService.add({
|
|
148
155
|
severity: 'warn',
|
|
149
|
-
summary: '
|
|
150
|
-
detail: '
|
|
156
|
+
summary: this.translate('common.validation'),
|
|
157
|
+
detail: this.translate('email.template.select.config.and.recipient'),
|
|
151
158
|
});
|
|
152
159
|
return;
|
|
153
160
|
}
|
|
@@ -169,16 +176,16 @@ class TemplateListComponent {
|
|
|
169
176
|
if (response.data?.success) {
|
|
170
177
|
this.messageService.add({
|
|
171
178
|
severity: 'success',
|
|
172
|
-
summary: '
|
|
173
|
-
detail:
|
|
179
|
+
summary: this.translate('common.success'),
|
|
180
|
+
detail: this.translate('email.template.test.sent.success', { messageId: response.data.messageId ?? '' }),
|
|
174
181
|
});
|
|
175
182
|
this.showTestDialog.set(false);
|
|
176
183
|
}
|
|
177
184
|
else {
|
|
178
185
|
this.messageService.add({
|
|
179
186
|
severity: 'error',
|
|
180
|
-
summary: '
|
|
181
|
-
detail: response.data?.error || '
|
|
187
|
+
summary: this.translate('common.error'),
|
|
188
|
+
detail: response.data?.error || this.translate('email.template.test.sent.failed'),
|
|
182
189
|
});
|
|
183
190
|
}
|
|
184
191
|
}
|
|
@@ -191,8 +198,8 @@ class TemplateListComponent {
|
|
|
191
198
|
}
|
|
192
199
|
onDelete(template) {
|
|
193
200
|
this.confirmationService.confirm({
|
|
194
|
-
message:
|
|
195
|
-
header: '
|
|
201
|
+
message: this.translate('email.template.delete.confirm', { name: template.name }),
|
|
202
|
+
header: this.translate('email.template.delete.title'),
|
|
196
203
|
icon: 'pi pi-exclamation-triangle',
|
|
197
204
|
acceptButtonStyleClass: 'p-button-danger',
|
|
198
205
|
accept: async () => {
|
|
@@ -200,8 +207,8 @@ class TemplateListComponent {
|
|
|
200
207
|
await this.templateService.deleteAsync({ id: template.id, type: 'delete' });
|
|
201
208
|
this.messageService.add({
|
|
202
209
|
severity: 'success',
|
|
203
|
-
summary: '
|
|
204
|
-
detail: '
|
|
210
|
+
summary: this.translate('common.success'),
|
|
211
|
+
detail: this.translate('email.template.deleted'),
|
|
205
212
|
});
|
|
206
213
|
this.loadTemplates();
|
|
207
214
|
}
|
|
@@ -211,21 +218,25 @@ class TemplateListComponent {
|
|
|
211
218
|
},
|
|
212
219
|
});
|
|
213
220
|
}
|
|
221
|
+
/** Translate helper - public for template usage with dynamic variables */
|
|
222
|
+
translate(key, variables) {
|
|
223
|
+
return this.translateAdapter?.translate(key, variables) ?? key;
|
|
224
|
+
}
|
|
214
225
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: TemplateListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
215
226
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: TemplateListComponent, isStandalone: true, selector: "lib-template-list", providers: [ConfirmationService, MessageService], ngImport: i0, template: `
|
|
216
227
|
<div class="card">
|
|
217
228
|
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4">
|
|
218
229
|
<div>
|
|
219
|
-
<h3 class="text-lg sm:text-xl font-semibold m-0">
|
|
230
|
+
<h3 class="text-lg sm:text-xl font-semibold m-0">{{ 'email.template.title' | translate }}</h3>
|
|
220
231
|
@if (showCompanyInfo()) {
|
|
221
232
|
<p class="text-sm text-muted-color mt-1">
|
|
222
|
-
|
|
233
|
+
{{ 'common.company' | translate }}: {{ currentCompanyName() }}
|
|
223
234
|
</p>
|
|
224
235
|
}
|
|
225
236
|
</div>
|
|
226
237
|
<p-button
|
|
227
238
|
*hasPermission="EMAIL_TEMPLATE_PERMISSIONS.CREATE"
|
|
228
|
-
label="
|
|
239
|
+
[label]="'email.template.new' | translate"
|
|
229
240
|
icon="pi pi-plus"
|
|
230
241
|
(onClick)="onCreate()"
|
|
231
242
|
styleClass="w-full sm:w-auto"
|
|
@@ -248,13 +259,13 @@ class TemplateListComponent {
|
|
|
248
259
|
>
|
|
249
260
|
<ng-template #header>
|
|
250
261
|
<tr>
|
|
251
|
-
<th>
|
|
252
|
-
<th class="hidden md:table-cell">
|
|
253
|
-
<th class="hidden lg:table-cell">
|
|
254
|
-
<th>
|
|
255
|
-
<th>
|
|
256
|
-
<th class="hidden xl:table-cell">
|
|
257
|
-
<th class="w-[120px]">
|
|
262
|
+
<th>{{ 'common.name' | translate }}</th>
|
|
263
|
+
<th class="hidden md:table-cell">{{ 'email.template.slug' | translate }}</th>
|
|
264
|
+
<th class="hidden lg:table-cell">{{ 'email.template.subject' | translate }}</th>
|
|
265
|
+
<th>{{ 'common.type' | translate }}</th>
|
|
266
|
+
<th>{{ 'common.status' | translate }}</th>
|
|
267
|
+
<th class="hidden xl:table-cell">{{ 'common.created' | translate }}</th>
|
|
268
|
+
<th class="w-[120px]">{{ 'common.actions' | translate }}</th>
|
|
258
269
|
</tr>
|
|
259
270
|
</ng-template>
|
|
260
271
|
|
|
@@ -270,13 +281,13 @@ class TemplateListComponent {
|
|
|
270
281
|
<td class="hidden lg:table-cell">{{ template.subject }}</td>
|
|
271
282
|
<td>
|
|
272
283
|
<p-tag
|
|
273
|
-
[value]="template.isHtml ? '
|
|
284
|
+
[value]="(template.isHtml ? 'email.template.html' : 'email.template.text') | translate"
|
|
274
285
|
[severity]="template.isHtml ? 'info' : 'secondary'"
|
|
275
286
|
/>
|
|
276
287
|
</td>
|
|
277
288
|
<td>
|
|
278
289
|
<p-tag
|
|
279
|
-
[value]="template.isActive ? '
|
|
290
|
+
[value]="(template.isActive ? 'common.active' : 'common.inactive') | translate"
|
|
280
291
|
[severity]="template.isActive ? 'success' : 'secondary'"
|
|
281
292
|
/>
|
|
282
293
|
</td>
|
|
@@ -288,7 +299,7 @@ class TemplateListComponent {
|
|
|
288
299
|
icon="pi pi-send"
|
|
289
300
|
[text]="true"
|
|
290
301
|
size="small"
|
|
291
|
-
pTooltip="
|
|
302
|
+
[pTooltip]="'email.template.test.send' | translate"
|
|
292
303
|
(onClick)="onTestSend(template)"
|
|
293
304
|
/>
|
|
294
305
|
<p-button
|
|
@@ -297,7 +308,7 @@ class TemplateListComponent {
|
|
|
297
308
|
[text]="true"
|
|
298
309
|
severity="secondary"
|
|
299
310
|
size="small"
|
|
300
|
-
pTooltip="
|
|
311
|
+
[pTooltip]="'common.edit' | translate"
|
|
301
312
|
(onClick)="onEdit(template.id)"
|
|
302
313
|
/>
|
|
303
314
|
<p-button
|
|
@@ -306,7 +317,7 @@ class TemplateListComponent {
|
|
|
306
317
|
[text]="true"
|
|
307
318
|
severity="danger"
|
|
308
319
|
size="small"
|
|
309
|
-
pTooltip="
|
|
320
|
+
[pTooltip]="'common.delete' | translate"
|
|
310
321
|
(onClick)="onDelete(template)"
|
|
311
322
|
/>
|
|
312
323
|
</div>
|
|
@@ -317,7 +328,7 @@ class TemplateListComponent {
|
|
|
317
328
|
<ng-template #emptymessage>
|
|
318
329
|
<tr>
|
|
319
330
|
<td colspan="7" class="text-center py-4 text-muted-color">
|
|
320
|
-
|
|
331
|
+
{{ 'email.template.empty' | translate }}
|
|
321
332
|
</td>
|
|
322
333
|
</tr>
|
|
323
334
|
</ng-template>
|
|
@@ -327,7 +338,7 @@ class TemplateListComponent {
|
|
|
327
338
|
|
|
328
339
|
<!-- Test Send Dialog -->
|
|
329
340
|
<p-dialog
|
|
330
|
-
header="
|
|
341
|
+
[header]="'email.template.test.dialog.title' | translate"
|
|
331
342
|
[visible]="showTestDialog()"
|
|
332
343
|
(visibleChange)="showTestDialog.set($event)"
|
|
333
344
|
[modal]="true"
|
|
@@ -336,7 +347,7 @@ class TemplateListComponent {
|
|
|
336
347
|
>
|
|
337
348
|
<div class="flex flex-col gap-4">
|
|
338
349
|
<div class="field">
|
|
339
|
-
<label class="block font-medium mb-2">
|
|
350
|
+
<label class="block font-medium mb-2">{{ 'email.template.template' | translate }}</label>
|
|
340
351
|
<input
|
|
341
352
|
pInputText
|
|
342
353
|
[value]="selectedTemplate()?.name || ''"
|
|
@@ -346,27 +357,27 @@ class TemplateListComponent {
|
|
|
346
357
|
</div>
|
|
347
358
|
|
|
348
359
|
<div class="field">
|
|
349
|
-
<label class="block font-medium mb-2">
|
|
360
|
+
<label class="block font-medium mb-2">{{ 'email.template.email.config' | translate }} *</label>
|
|
350
361
|
<p-select
|
|
351
362
|
[ngModel]="testSendModel.configId"
|
|
352
363
|
(ngModelChange)="updateTestSendModel('configId', $event)"
|
|
353
364
|
[options]="configOptions()"
|
|
354
365
|
optionLabel="label"
|
|
355
366
|
optionValue="value"
|
|
356
|
-
placeholder="
|
|
367
|
+
[placeholder]="'email.template.select.config' | translate"
|
|
357
368
|
class="w-full"
|
|
358
369
|
[loading]="isLoadingConfigs()"
|
|
359
370
|
/>
|
|
360
371
|
</div>
|
|
361
372
|
|
|
362
373
|
<div class="field">
|
|
363
|
-
<label class="block font-medium mb-2">
|
|
374
|
+
<label class="block font-medium mb-2">{{ 'email.config.recipient.email' | translate }} *</label>
|
|
364
375
|
<input
|
|
365
376
|
pInputText
|
|
366
377
|
[ngModel]="testSendModel.recipient"
|
|
367
378
|
(ngModelChange)="updateTestSendModel('recipient', $event)"
|
|
368
379
|
class="w-full"
|
|
369
|
-
placeholder="recipient
|
|
380
|
+
[placeholder]="'email.recipient.example' | translate"
|
|
370
381
|
/>
|
|
371
382
|
</div>
|
|
372
383
|
|
|
@@ -375,7 +386,7 @@ class TemplateListComponent {
|
|
|
375
386
|
<div class="border-t border-surface pt-4 mt-2">
|
|
376
387
|
<h4 class="font-medium mb-3 flex items-center gap-2">
|
|
377
388
|
<i class="pi pi-code text-muted-color"></i>
|
|
378
|
-
|
|
389
|
+
{{ 'email.template.variables' | translate }}
|
|
379
390
|
</h4>
|
|
380
391
|
<div class="flex flex-col gap-3">
|
|
381
392
|
@for (variable of templateVariables(); track variable) {
|
|
@@ -388,7 +399,7 @@ class TemplateListComponent {
|
|
|
388
399
|
[ngModel]="variableValues[variable] || ''"
|
|
389
400
|
(ngModelChange)="updateVariableValue(variable, $event)"
|
|
390
401
|
class="w-full"
|
|
391
|
-
[placeholder]="'
|
|
402
|
+
[placeholder]="translate('email.template.enter.value.for', { variable: variable })"
|
|
392
403
|
/>
|
|
393
404
|
</div>
|
|
394
405
|
}
|
|
@@ -399,13 +410,13 @@ class TemplateListComponent {
|
|
|
399
410
|
|
|
400
411
|
<ng-template #footer>
|
|
401
412
|
<p-button
|
|
402
|
-
label="
|
|
413
|
+
[label]="'common.cancel' | translate"
|
|
403
414
|
severity="secondary"
|
|
404
415
|
[outlined]="true"
|
|
405
416
|
(onClick)="showTestDialog.set(false)"
|
|
406
417
|
/>
|
|
407
418
|
<p-button
|
|
408
|
-
label="
|
|
419
|
+
[label]="'email.template.send.test' | translate"
|
|
409
420
|
icon="pi pi-send"
|
|
410
421
|
[loading]="isSendingTest()"
|
|
411
422
|
(onClick)="sendTestEmail()"
|
|
@@ -415,29 +426,28 @@ class TemplateListComponent {
|
|
|
415
426
|
|
|
416
427
|
<p-confirmDialog />
|
|
417
428
|
<p-toast />
|
|
418
|
-
`, 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: i6.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { 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" }
|
|
429
|
+
`, 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: i6.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { 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" }] });
|
|
419
430
|
}
|
|
420
431
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: TemplateListComponent, decorators: [{
|
|
421
432
|
type: Component,
|
|
422
433
|
args: [{
|
|
423
434
|
selector: 'lib-template-list',
|
|
424
|
-
|
|
425
|
-
imports: [AngularModule, PrimeModule, HasPermissionDirective],
|
|
435
|
+
imports: [AngularModule, PrimeModule, HasPermissionDirective, TranslatePipe],
|
|
426
436
|
providers: [ConfirmationService, MessageService],
|
|
427
437
|
template: `
|
|
428
438
|
<div class="card">
|
|
429
439
|
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4">
|
|
430
440
|
<div>
|
|
431
|
-
<h3 class="text-lg sm:text-xl font-semibold m-0">
|
|
441
|
+
<h3 class="text-lg sm:text-xl font-semibold m-0">{{ 'email.template.title' | translate }}</h3>
|
|
432
442
|
@if (showCompanyInfo()) {
|
|
433
443
|
<p class="text-sm text-muted-color mt-1">
|
|
434
|
-
|
|
444
|
+
{{ 'common.company' | translate }}: {{ currentCompanyName() }}
|
|
435
445
|
</p>
|
|
436
446
|
}
|
|
437
447
|
</div>
|
|
438
448
|
<p-button
|
|
439
449
|
*hasPermission="EMAIL_TEMPLATE_PERMISSIONS.CREATE"
|
|
440
|
-
label="
|
|
450
|
+
[label]="'email.template.new' | translate"
|
|
441
451
|
icon="pi pi-plus"
|
|
442
452
|
(onClick)="onCreate()"
|
|
443
453
|
styleClass="w-full sm:w-auto"
|
|
@@ -460,13 +470,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
460
470
|
>
|
|
461
471
|
<ng-template #header>
|
|
462
472
|
<tr>
|
|
463
|
-
<th>
|
|
464
|
-
<th class="hidden md:table-cell">
|
|
465
|
-
<th class="hidden lg:table-cell">
|
|
466
|
-
<th>
|
|
467
|
-
<th>
|
|
468
|
-
<th class="hidden xl:table-cell">
|
|
469
|
-
<th class="w-[120px]">
|
|
473
|
+
<th>{{ 'common.name' | translate }}</th>
|
|
474
|
+
<th class="hidden md:table-cell">{{ 'email.template.slug' | translate }}</th>
|
|
475
|
+
<th class="hidden lg:table-cell">{{ 'email.template.subject' | translate }}</th>
|
|
476
|
+
<th>{{ 'common.type' | translate }}</th>
|
|
477
|
+
<th>{{ 'common.status' | translate }}</th>
|
|
478
|
+
<th class="hidden xl:table-cell">{{ 'common.created' | translate }}</th>
|
|
479
|
+
<th class="w-[120px]">{{ 'common.actions' | translate }}</th>
|
|
470
480
|
</tr>
|
|
471
481
|
</ng-template>
|
|
472
482
|
|
|
@@ -482,13 +492,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
482
492
|
<td class="hidden lg:table-cell">{{ template.subject }}</td>
|
|
483
493
|
<td>
|
|
484
494
|
<p-tag
|
|
485
|
-
[value]="template.isHtml ? '
|
|
495
|
+
[value]="(template.isHtml ? 'email.template.html' : 'email.template.text') | translate"
|
|
486
496
|
[severity]="template.isHtml ? 'info' : 'secondary'"
|
|
487
497
|
/>
|
|
488
498
|
</td>
|
|
489
499
|
<td>
|
|
490
500
|
<p-tag
|
|
491
|
-
[value]="template.isActive ? '
|
|
501
|
+
[value]="(template.isActive ? 'common.active' : 'common.inactive') | translate"
|
|
492
502
|
[severity]="template.isActive ? 'success' : 'secondary'"
|
|
493
503
|
/>
|
|
494
504
|
</td>
|
|
@@ -500,7 +510,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
500
510
|
icon="pi pi-send"
|
|
501
511
|
[text]="true"
|
|
502
512
|
size="small"
|
|
503
|
-
pTooltip="
|
|
513
|
+
[pTooltip]="'email.template.test.send' | translate"
|
|
504
514
|
(onClick)="onTestSend(template)"
|
|
505
515
|
/>
|
|
506
516
|
<p-button
|
|
@@ -509,7 +519,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
509
519
|
[text]="true"
|
|
510
520
|
severity="secondary"
|
|
511
521
|
size="small"
|
|
512
|
-
pTooltip="
|
|
522
|
+
[pTooltip]="'common.edit' | translate"
|
|
513
523
|
(onClick)="onEdit(template.id)"
|
|
514
524
|
/>
|
|
515
525
|
<p-button
|
|
@@ -518,7 +528,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
518
528
|
[text]="true"
|
|
519
529
|
severity="danger"
|
|
520
530
|
size="small"
|
|
521
|
-
pTooltip="
|
|
531
|
+
[pTooltip]="'common.delete' | translate"
|
|
522
532
|
(onClick)="onDelete(template)"
|
|
523
533
|
/>
|
|
524
534
|
</div>
|
|
@@ -529,7 +539,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
529
539
|
<ng-template #emptymessage>
|
|
530
540
|
<tr>
|
|
531
541
|
<td colspan="7" class="text-center py-4 text-muted-color">
|
|
532
|
-
|
|
542
|
+
{{ 'email.template.empty' | translate }}
|
|
533
543
|
</td>
|
|
534
544
|
</tr>
|
|
535
545
|
</ng-template>
|
|
@@ -539,7 +549,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
539
549
|
|
|
540
550
|
<!-- Test Send Dialog -->
|
|
541
551
|
<p-dialog
|
|
542
|
-
header="
|
|
552
|
+
[header]="'email.template.test.dialog.title' | translate"
|
|
543
553
|
[visible]="showTestDialog()"
|
|
544
554
|
(visibleChange)="showTestDialog.set($event)"
|
|
545
555
|
[modal]="true"
|
|
@@ -548,7 +558,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
548
558
|
>
|
|
549
559
|
<div class="flex flex-col gap-4">
|
|
550
560
|
<div class="field">
|
|
551
|
-
<label class="block font-medium mb-2">
|
|
561
|
+
<label class="block font-medium mb-2">{{ 'email.template.template' | translate }}</label>
|
|
552
562
|
<input
|
|
553
563
|
pInputText
|
|
554
564
|
[value]="selectedTemplate()?.name || ''"
|
|
@@ -558,27 +568,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
558
568
|
</div>
|
|
559
569
|
|
|
560
570
|
<div class="field">
|
|
561
|
-
<label class="block font-medium mb-2">
|
|
571
|
+
<label class="block font-medium mb-2">{{ 'email.template.email.config' | translate }} *</label>
|
|
562
572
|
<p-select
|
|
563
573
|
[ngModel]="testSendModel.configId"
|
|
564
574
|
(ngModelChange)="updateTestSendModel('configId', $event)"
|
|
565
575
|
[options]="configOptions()"
|
|
566
576
|
optionLabel="label"
|
|
567
577
|
optionValue="value"
|
|
568
|
-
placeholder="
|
|
578
|
+
[placeholder]="'email.template.select.config' | translate"
|
|
569
579
|
class="w-full"
|
|
570
580
|
[loading]="isLoadingConfigs()"
|
|
571
581
|
/>
|
|
572
582
|
</div>
|
|
573
583
|
|
|
574
584
|
<div class="field">
|
|
575
|
-
<label class="block font-medium mb-2">
|
|
585
|
+
<label class="block font-medium mb-2">{{ 'email.config.recipient.email' | translate }} *</label>
|
|
576
586
|
<input
|
|
577
587
|
pInputText
|
|
578
588
|
[ngModel]="testSendModel.recipient"
|
|
579
589
|
(ngModelChange)="updateTestSendModel('recipient', $event)"
|
|
580
590
|
class="w-full"
|
|
581
|
-
placeholder="recipient
|
|
591
|
+
[placeholder]="'email.recipient.example' | translate"
|
|
582
592
|
/>
|
|
583
593
|
</div>
|
|
584
594
|
|
|
@@ -587,7 +597,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
587
597
|
<div class="border-t border-surface pt-4 mt-2">
|
|
588
598
|
<h4 class="font-medium mb-3 flex items-center gap-2">
|
|
589
599
|
<i class="pi pi-code text-muted-color"></i>
|
|
590
|
-
|
|
600
|
+
{{ 'email.template.variables' | translate }}
|
|
591
601
|
</h4>
|
|
592
602
|
<div class="flex flex-col gap-3">
|
|
593
603
|
@for (variable of templateVariables(); track variable) {
|
|
@@ -600,7 +610,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
600
610
|
[ngModel]="variableValues[variable] || ''"
|
|
601
611
|
(ngModelChange)="updateVariableValue(variable, $event)"
|
|
602
612
|
class="w-full"
|
|
603
|
-
[placeholder]="'
|
|
613
|
+
[placeholder]="translate('email.template.enter.value.for', { variable: variable })"
|
|
604
614
|
/>
|
|
605
615
|
</div>
|
|
606
616
|
}
|
|
@@ -611,13 +621,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
611
621
|
|
|
612
622
|
<ng-template #footer>
|
|
613
623
|
<p-button
|
|
614
|
-
label="
|
|
624
|
+
[label]="'common.cancel' | translate"
|
|
615
625
|
severity="secondary"
|
|
616
626
|
[outlined]="true"
|
|
617
627
|
(onClick)="showTestDialog.set(false)"
|
|
618
628
|
/>
|
|
619
629
|
<p-button
|
|
620
|
-
label="
|
|
630
|
+
[label]="'email.template.send.test' | translate"
|
|
621
631
|
icon="pi pi-send"
|
|
622
632
|
[loading]="isSendingTest()"
|
|
623
633
|
(onClick)="sendTestEmail()"
|
|
@@ -632,4 +642,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
632
642
|
}] });
|
|
633
643
|
|
|
634
644
|
export { TemplateListComponent };
|
|
635
|
-
//# sourceMappingURL=flusys-ng-email-template-list.component-
|
|
645
|
+
//# sourceMappingURL=flusys-ng-email-template-list.component-DHnuMTpB.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flusys-ng-email-template-list.component-DHnuMTpB.mjs","sources":["../../../projects/ng-email/pages/template/template-list.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { Router } from '@angular/router';\nimport { firstValueFrom } from 'rxjs';\nimport { APP_CONFIG, DEFAULT_APP_NAME, TRANSLATE_ADAPTER } from '@flusys/ng-core';\nimport { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';\nimport { AngularModule, EMAIL_TEMPLATE_PERMISSIONS, HasPermissionDirective, PrimeModule, TranslatePipe } from '@flusys/ng-shared';\nimport { ConfirmationService, MessageService } from 'primeng/api';\nimport { IEmailConfig } from '../../interfaces/email-config.interface';\nimport { IEmailTemplate } from '../../interfaces/email-template.interface';\nimport { EmailConfigApiService } from '../../services/email-config-api.service';\nimport { EmailSendService } from '../../services/email-send.service';\nimport { EmailTemplateApiService } from '../../services/email-template-api.service';\n\n/**\n * Email template list component\n */\n@Component({\n selector: 'lib-template-list',\n imports: [AngularModule, PrimeModule, HasPermissionDirective, TranslatePipe],\n providers: [ConfirmationService, MessageService],\n template: `\n <div class=\"card\">\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\">{{ 'email.template.title' | translate }}</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 <p-button\n *hasPermission=\"EMAIL_TEMPLATE_PERMISSIONS.CREATE\"\n [label]=\"'email.template.new' | translate\"\n icon=\"pi pi-plus\"\n (onClick)=\"onCreate()\"\n styleClass=\"w-full sm:w-auto\"\n />\n </div>\n\n <div class=\"overflow-x-auto -mx-4 sm:mx-0\">\n <p-table\n [value]=\"templates()\"\n [loading]=\"isLoading()\"\n [paginator]=\"totalRecords() > 0\"\n [rows]=\"pageSize()\"\n [first]=\"first()\"\n [totalRecords]=\"totalRecords()\"\n [lazy]=\"true\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [rowsPerPageOptions]=\"[10, 25, 50]\"\n styleClass=\"p-datatable-sm\"\n [tableStyle]=\"{ 'min-width': '50rem' }\"\n >\n <ng-template #header>\n <tr>\n <th>{{ 'common.name' | translate }}</th>\n <th class=\"hidden md:table-cell\">{{ 'email.template.slug' | translate }}</th>\n <th class=\"hidden lg:table-cell\">{{ 'email.template.subject' | translate }}</th>\n <th>{{ 'common.type' | translate }}</th>\n <th>{{ 'common.status' | translate }}</th>\n <th class=\"hidden xl:table-cell\">{{ 'common.created' | translate }}</th>\n <th class=\"w-[120px]\">{{ 'common.actions' | translate }}</th>\n </tr>\n </ng-template>\n\n <ng-template #body let-template>\n <tr>\n <td>\n <i class=\"pi pi-envelope mr-2 text-muted-color\"></i>\n {{ template.name }}\n </td>\n <td class=\"hidden md:table-cell\">\n <code class=\"text-sm bg-surface-100 dark:bg-surface-700 px-2 py-1 rounded\">{{ template.slug }}</code>\n </td>\n <td class=\"hidden lg:table-cell\">{{ template.subject }}</td>\n <td>\n <p-tag\n [value]=\"(template.isHtml ? 'email.template.html' : 'email.template.text') | translate\"\n [severity]=\"template.isHtml ? 'info' : 'secondary'\"\n />\n </td>\n <td>\n <p-tag\n [value]=\"(template.isActive ? 'common.active' : 'common.inactive') | translate\"\n [severity]=\"template.isActive ? 'success' : 'secondary'\"\n />\n </td>\n <td class=\"hidden xl:table-cell\">{{ template.createdAt | date: 'short' }}</td>\n <td>\n <div class=\"flex gap-1\">\n <p-button\n *hasPermission=\"EMAIL_TEMPLATE_PERMISSIONS.UPDATE\"\n icon=\"pi pi-send\"\n [text]=\"true\"\n size=\"small\"\n [pTooltip]=\"'email.template.test.send' | translate\"\n (onClick)=\"onTestSend(template)\"\n />\n <p-button\n *hasPermission=\"EMAIL_TEMPLATE_PERMISSIONS.UPDATE\"\n icon=\"pi pi-pencil\"\n [text]=\"true\"\n severity=\"secondary\"\n size=\"small\"\n [pTooltip]=\"'common.edit' | translate\"\n (onClick)=\"onEdit(template.id)\"\n />\n <p-button\n *hasPermission=\"EMAIL_TEMPLATE_PERMISSIONS.DELETE\"\n icon=\"pi pi-trash\"\n [text]=\"true\"\n severity=\"danger\"\n size=\"small\"\n [pTooltip]=\"'common.delete' | translate\"\n (onClick)=\"onDelete(template)\"\n />\n </div>\n </td>\n </tr>\n </ng-template>\n\n <ng-template #emptymessage>\n <tr>\n <td colspan=\"7\" class=\"text-center py-4 text-muted-color\">\n {{ 'email.template.empty' | translate }}\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n </div>\n\n <!-- Test Send Dialog -->\n <p-dialog\n [header]=\"'email.template.test.dialog.title' | translate\"\n [visible]=\"showTestDialog()\"\n (visibleChange)=\"showTestDialog.set($event)\"\n [modal]=\"true\"\n [style]=\"{ width: '95vw', maxWidth: '500px', maxHeight: '80vh' }\"\n [breakpoints]=\"{ '575px': '95vw' }\"\n >\n <div class=\"flex flex-col gap-4\">\n <div class=\"field\">\n <label class=\"block font-medium mb-2\">{{ 'email.template.template' | translate }}</label>\n <input\n pInputText\n [value]=\"selectedTemplate()?.name || ''\"\n class=\"w-full\"\n [disabled]=\"true\"\n />\n </div>\n\n <div class=\"field\">\n <label class=\"block font-medium mb-2\">{{ 'email.template.email.config' | translate }} *</label>\n <p-select\n [ngModel]=\"testSendModel.configId\"\n (ngModelChange)=\"updateTestSendModel('configId', $event)\"\n [options]=\"configOptions()\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'email.template.select.config' | translate\"\n class=\"w-full\"\n [loading]=\"isLoadingConfigs()\"\n />\n </div>\n\n <div class=\"field\">\n <label class=\"block font-medium mb-2\">{{ 'email.config.recipient.email' | translate }} *</label>\n <input\n pInputText\n [ngModel]=\"testSendModel.recipient\"\n (ngModelChange)=\"updateTestSendModel('recipient', $event)\"\n class=\"w-full\"\n [placeholder]=\"'email.recipient.example' | translate\"\n />\n </div>\n\n <!-- Dynamic Variables -->\n @if (templateVariables().length > 0) {\n <div class=\"border-t border-surface pt-4 mt-2\">\n <h4 class=\"font-medium mb-3 flex items-center gap-2\">\n <i class=\"pi pi-code text-muted-color\"></i>\n {{ 'email.template.variables' | translate }}\n </h4>\n <div class=\"flex flex-col gap-3\">\n @for (variable of templateVariables(); track variable) {\n <div class=\"field\">\n <label class=\"block text-sm font-medium mb-1\">\n <code class=\"text-primary bg-surface-100 dark:bg-surface-700 px-1 rounded\">{{ '{{' + variable + '}}' }}</code>\n </label>\n <input\n pInputText\n [ngModel]=\"variableValues[variable] || ''\"\n (ngModelChange)=\"updateVariableValue(variable, $event)\"\n class=\"w-full\"\n [placeholder]=\"translate('email.template.enter.value.for', { variable: variable })\"\n />\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <ng-template #footer>\n <p-button\n [label]=\"'common.cancel' | translate\"\n severity=\"secondary\"\n [outlined]=\"true\"\n (onClick)=\"showTestDialog.set(false)\"\n />\n <p-button\n [label]=\"'email.template.send.test' | translate\"\n icon=\"pi pi-send\"\n [loading]=\"isSendingTest()\"\n (onClick)=\"sendTestEmail()\"\n />\n </ng-template>\n </p-dialog>\n\n <p-confirmDialog />\n <p-toast />\n `,\n})\nexport class TemplateListComponent {\n // Permission constants for template\n readonly EMAIL_TEMPLATE_PERMISSIONS = EMAIL_TEMPLATE_PERMISSIONS;\n\n private readonly router = inject(Router);\n private readonly templateService = inject(EmailTemplateApiService);\n private readonly configService = inject(EmailConfigApiService);\n private readonly emailSendService = inject(EmailSendService);\n private readonly confirmationService = inject(ConfirmationService);\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 readonly isLoading = signal(false);\n readonly templates = signal<IEmailTemplate[]>([]);\n readonly totalRecords = signal(0);\n readonly pageSize = signal(10);\n readonly first = signal(0);\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 // Test send dialog (signals for zoneless change detection)\n readonly showTestDialog = signal(false);\n readonly selectedTemplate = signal<IEmailTemplate | null>(null);\n readonly configs = signal<IEmailConfig[]>([]);\n readonly isLoadingConfigs = signal(false);\n readonly isSendingTest = signal(false);\n\n // Form-bound properties as signals for zoneless change detection\n private readonly _testSendModel = signal({ configId: '', recipient: '' });\n private readonly _variableValues = signal<Record<string, string>>({});\n\n get testSendModel() {\n return this._testSendModel();\n }\n\n get variableValues() {\n return this._variableValues();\n }\n\n updateTestSendModel<K extends 'configId' | 'recipient'>(field: K, value: string): void {\n this._testSendModel.update((m) => ({ ...m, [field]: value }));\n }\n\n updateVariableValue(key: string, value: string): void {\n this._variableValues.update((v) => ({ ...v, [key]: value }));\n }\n\n readonly configOptions = computed(() =>\n this.configs().map((c) => ({\n label: `${c.name} (${this.translate(`email.providers.${c.provider}`)})`,\n value: c.id,\n })),\n );\n\n /** Extract variables from template content */\n readonly templateVariables = computed(() => {\n const template = this.selectedTemplate();\n if (!template) return [];\n\n // Combine all content sources to extract variables\n const content = [\n template.subject,\n template.htmlContent,\n template.textContent || '',\n ].join(' ');\n\n // Find all {{variableName}} patterns\n const matches = content.matchAll(/\\{\\{(\\w+)\\}\\}/g);\n const variables = new Set<string>();\n\n for (const match of matches) {\n variables.add(match[1]);\n }\n\n return Array.from(variables).sort();\n });\n\n onCreate(): void {\n this.router.navigate(['/email/templates/new']);\n }\n\n onEdit(templateId: string): void {\n this.router.navigate(['/email/templates', templateId]);\n }\n\n async loadTemplates(): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await firstValueFrom(\n this.templateService.getAll('', {\n pagination: {\n currentPage: Math.floor(this.first() / this.pageSize()),\n pageSize: this.pageSize(),\n },\n filter: {},\n select: [],\n sort: {},\n }),\n );\n\n if (response.success) {\n this.templates.set(response.data ?? []);\n this.totalRecords.set(response.meta?.total ?? 0);\n }\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this.isLoading.set(false);\n }\n }\n\n onLazyLoad(event: { first?: number | null; rows?: number | null }): void {\n this.first.set(event.first ?? 0);\n this.pageSize.set(event.rows ?? 10);\n this.loadTemplates();\n }\n\n async onTestSend(template: IEmailTemplate): Promise<void> {\n this.selectedTemplate.set(template);\n this._testSendModel.set({ configId: '', recipient: '' });\n this._variableValues.set({}); // Reset variable values\n this.showTestDialog.set(true);\n await this.loadConfigs();\n }\n\n async loadConfigs(): Promise<void> {\n this.isLoadingConfigs.set(true);\n try {\n const response = await firstValueFrom(\n this.configService.getAll('', {\n pagination: { currentPage: 0, pageSize: 100 },\n filter: { isActive: true },\n select: [],\n sort: {},\n }),\n );\n if (response.success) {\n this.configs.set(response.data ?? []);\n }\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this.isLoadingConfigs.set(false);\n }\n }\n\n async sendTestEmail(): Promise<void> {\n const template = this.selectedTemplate();\n const model = this.testSendModel;\n if (!template || !model.configId || !model.recipient) {\n this.messageService.add({\n severity: 'warn',\n summary: this.translate('common.validation'),\n detail: this.translate('email.template.select.config.and.recipient'),\n });\n return;\n }\n\n this.isSendingTest.set(true);\n try {\n // Build variables object (only include non-empty values)\n const variables: Record<string, string> = {};\n for (const [key, value] of Object.entries(this.variableValues)) {\n if (value) {\n variables[key] = value;\n }\n }\n\n const response = await firstValueFrom(\n this.emailSendService.sendTemplate({\n templateId: template.id,\n to: model.recipient,\n emailConfigId: model.configId,\n variables: Object.keys(variables).length > 0 ? variables : undefined,\n }),\n );\n\n if (response.data?.success) {\n this.messageService.add({\n severity: 'success',\n summary: this.translate('common.success'),\n detail: this.translate('email.template.test.sent.success', { messageId: response.data.messageId ?? '' }),\n });\n this.showTestDialog.set(false);\n } else {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('common.error'),\n detail: response.data?.error || this.translate('email.template.test.sent.failed'),\n });\n }\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this.isSendingTest.set(false);\n }\n }\n\n onDelete(template: IEmailTemplate): void {\n this.confirmationService.confirm({\n message: this.translate('email.template.delete.confirm', { name: template.name }),\n header: this.translate('email.template.delete.title'),\n icon: 'pi pi-exclamation-triangle',\n acceptButtonStyleClass: 'p-button-danger',\n accept: async () => {\n try {\n await this.templateService.deleteAsync({ id: template.id, type: 'delete' });\n this.messageService.add({\n severity: 'success',\n summary: this.translate('common.success'),\n detail: this.translate('email.template.deleted'),\n });\n this.loadTemplates();\n } catch {\n // Error toast handled by global interceptor\n }\n },\n });\n }\n\n /** Translate helper - public for template usage with dynamic variables */\n translate(key: string, variables?: Record<string, string | number>): string {\n return this.translateAdapter?.translate(key, variables) ?? key;\n }\n}\n"],"names":["i9"],"mappings":"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"}
|