@flusys/ng-email 1.1.0-beta → 1.1.0
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 +382 -168
- package/fesm2022/{flusys-ng-email-email-config-form.component-8dOBD-Q-.mjs → flusys-ng-email-email-config-form.component-tg4pKP7G.mjs} +237 -176
- package/fesm2022/flusys-ng-email-email-config-form.component-tg4pKP7G.mjs.map +1 -0
- package/fesm2022/{flusys-ng-email-email-config-list.component-CJhSPkCZ.mjs → flusys-ng-email-email-config-list.component-Dt9PY9xD.mjs} +248 -237
- package/fesm2022/flusys-ng-email-email-config-list.component-Dt9PY9xD.mjs.map +1 -0
- package/fesm2022/flusys-ng-email-template-form.component-vlfHz6VE.mjs +563 -0
- package/fesm2022/flusys-ng-email-template-form.component-vlfHz6VE.mjs.map +1 -0
- package/fesm2022/{flusys-ng-email-template-list.component-CGJxfZMT.mjs → flusys-ng-email-template-list.component-krrpsjDv.mjs} +271 -231
- package/fesm2022/flusys-ng-email-template-list.component-krrpsjDv.mjs.map +1 -0
- package/fesm2022/flusys-ng-email.mjs +118 -97
- package/fesm2022/flusys-ng-email.mjs.map +1 -1
- package/package.json +11 -10
- package/types/flusys-ng-email.d.ts +71 -48
- package/fesm2022/flusys-ng-email-email-config-form.component-8dOBD-Q-.mjs.map +0 -1
- package/fesm2022/flusys-ng-email-email-config-list.component-CJhSPkCZ.mjs.map +0 -1
- package/fesm2022/flusys-ng-email-template-form.component-DjzG_lG1.mjs +0 -529
- package/fesm2022/flusys-ng-email-template-form.component-DjzG_lG1.mjs.map +0 -1
- package/fesm2022/flusys-ng-email-template-list.component-CGJxfZMT.mjs.map +0 -1
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
import { Router } from '@angular/router';
|
|
4
|
-
import * as i1 from '@angular/forms';
|
|
5
|
-
import { FormsModule } from '@angular/forms';
|
|
6
4
|
import { firstValueFrom } from 'rxjs';
|
|
7
|
-
import { ConfirmationService, MessageService } from 'primeng/api';
|
|
8
5
|
import { APP_CONFIG, DEFAULT_APP_NAME } from '@flusys/ng-core';
|
|
9
6
|
import { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';
|
|
10
|
-
import { AngularModule, PrimeModule } from '@flusys/ng-shared';
|
|
7
|
+
import { EMAIL_TEMPLATE_PERMISSIONS, AngularModule, PrimeModule, HasPermissionDirective } from '@flusys/ng-shared';
|
|
8
|
+
import { ConfirmationService, MessageService } from 'primeng/api';
|
|
11
9
|
import { EmailTemplateApiService, EmailConfigApiService, EmailSendService } from './flusys-ng-email.mjs';
|
|
10
|
+
import * as i1 from '@angular/forms';
|
|
12
11
|
import * as i2 from 'primeng/button';
|
|
13
12
|
import * as i3 from 'primeng/confirmdialog';
|
|
14
13
|
import * as i4 from 'primeng/dialog';
|
|
@@ -16,7 +15,7 @@ import * as i5 from 'primeng/inputtext';
|
|
|
16
15
|
import * as i6 from 'primeng/select';
|
|
17
16
|
import * as i7 from 'primeng/table';
|
|
18
17
|
import * as i8 from 'primeng/tag';
|
|
19
|
-
import * as
|
|
18
|
+
import * as i8$1 from 'primeng/toast';
|
|
20
19
|
import * as i10 from 'primeng/tooltip';
|
|
21
20
|
import * as i11 from '@angular/common';
|
|
22
21
|
|
|
@@ -24,6 +23,8 @@ import * as i11 from '@angular/common';
|
|
|
24
23
|
* Email template list component
|
|
25
24
|
*/
|
|
26
25
|
class TemplateListComponent {
|
|
26
|
+
// Permission constants for template
|
|
27
|
+
EMAIL_TEMPLATE_PERMISSIONS = EMAIL_TEMPLATE_PERMISSIONS;
|
|
27
28
|
router = inject(Router);
|
|
28
29
|
templateService = inject(EmailTemplateApiService);
|
|
29
30
|
configService = inject(EmailConfigApiService);
|
|
@@ -31,23 +32,35 @@ class TemplateListComponent {
|
|
|
31
32
|
confirmationService = inject(ConfirmationService);
|
|
32
33
|
messageService = inject(MessageService);
|
|
33
34
|
appConfig = inject(APP_CONFIG);
|
|
34
|
-
companyContext = inject(LAYOUT_AUTH_STATE);
|
|
35
|
+
companyContext = inject(LAYOUT_AUTH_STATE, { optional: true });
|
|
35
36
|
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
36
37
|
templates = signal([], ...(ngDevMode ? [{ debugName: "templates" }] : []));
|
|
37
38
|
totalRecords = signal(0, ...(ngDevMode ? [{ debugName: "totalRecords" }] : []));
|
|
38
39
|
pageSize = signal(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
|
|
39
|
-
|
|
40
|
-
showCompanyInfo = computed(() => this.appConfig.enableCompanyFeature, ...(ngDevMode ? [{ debugName: "showCompanyInfo" }] : []));
|
|
41
|
-
currentCompanyName = computed(() => this.companyContext
|
|
42
|
-
// Test send dialog
|
|
43
|
-
showTestDialog = false;
|
|
40
|
+
first = signal(0, ...(ngDevMode ? [{ debugName: "first" }] : []));
|
|
41
|
+
showCompanyInfo = computed(() => this.appConfig.enableCompanyFeature && !!this.companyContext, ...(ngDevMode ? [{ debugName: "showCompanyInfo" }] : []));
|
|
42
|
+
currentCompanyName = computed(() => this.companyContext?.currentCompanyInfo()?.name ?? DEFAULT_APP_NAME, ...(ngDevMode ? [{ debugName: "currentCompanyName" }] : []));
|
|
43
|
+
// Test send dialog (signals for zoneless change detection)
|
|
44
|
+
showTestDialog = signal(false, ...(ngDevMode ? [{ debugName: "showTestDialog" }] : []));
|
|
44
45
|
selectedTemplate = signal(null, ...(ngDevMode ? [{ debugName: "selectedTemplate" }] : []));
|
|
45
46
|
configs = signal([], ...(ngDevMode ? [{ debugName: "configs" }] : []));
|
|
46
47
|
isLoadingConfigs = signal(false, ...(ngDevMode ? [{ debugName: "isLoadingConfigs" }] : []));
|
|
47
48
|
isSendingTest = signal(false, ...(ngDevMode ? [{ debugName: "isSendingTest" }] : []));
|
|
48
|
-
// Form-bound properties
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
// Form-bound properties as signals for zoneless change detection
|
|
50
|
+
_testSendModel = signal({ configId: '', recipient: '' }, ...(ngDevMode ? [{ debugName: "_testSendModel" }] : []));
|
|
51
|
+
_variableValues = signal({}, ...(ngDevMode ? [{ debugName: "_variableValues" }] : []));
|
|
52
|
+
get testSendModel() {
|
|
53
|
+
return this._testSendModel();
|
|
54
|
+
}
|
|
55
|
+
get variableValues() {
|
|
56
|
+
return this._variableValues();
|
|
57
|
+
}
|
|
58
|
+
updateTestSendModel(field, value) {
|
|
59
|
+
this._testSendModel.update((m) => ({ ...m, [field]: value }));
|
|
60
|
+
}
|
|
61
|
+
updateVariableValue(key, value) {
|
|
62
|
+
this._variableValues.update((v) => ({ ...v, [key]: value }));
|
|
63
|
+
}
|
|
51
64
|
configOptions = computed(() => this.configs().map((c) => ({
|
|
52
65
|
label: `${c.name} (${c.provider})`,
|
|
53
66
|
value: c.id,
|
|
@@ -71,9 +84,6 @@ class TemplateListComponent {
|
|
|
71
84
|
}
|
|
72
85
|
return Array.from(variables).sort();
|
|
73
86
|
}, ...(ngDevMode ? [{ debugName: "templateVariables" }] : []));
|
|
74
|
-
ngOnInit() {
|
|
75
|
-
this.loadTemplates();
|
|
76
|
-
}
|
|
77
87
|
onCreate() {
|
|
78
88
|
this.router.navigate(['/email/templates/new']);
|
|
79
89
|
}
|
|
@@ -85,7 +95,7 @@ class TemplateListComponent {
|
|
|
85
95
|
try {
|
|
86
96
|
const response = await firstValueFrom(this.templateService.getAll('', {
|
|
87
97
|
pagination: {
|
|
88
|
-
currentPage: this.
|
|
98
|
+
currentPage: Math.floor(this.first() / this.pageSize()),
|
|
89
99
|
pageSize: this.pageSize(),
|
|
90
100
|
},
|
|
91
101
|
filter: {},
|
|
@@ -101,16 +111,16 @@ class TemplateListComponent {
|
|
|
101
111
|
this.isLoading.set(false);
|
|
102
112
|
}
|
|
103
113
|
}
|
|
104
|
-
|
|
105
|
-
this.
|
|
106
|
-
this.pageSize.set(event.rows);
|
|
114
|
+
onLazyLoad(event) {
|
|
115
|
+
this.first.set(event.first ?? 0);
|
|
116
|
+
this.pageSize.set(event.rows ?? 10);
|
|
107
117
|
this.loadTemplates();
|
|
108
118
|
}
|
|
109
119
|
async onTestSend(template) {
|
|
110
120
|
this.selectedTemplate.set(template);
|
|
111
|
-
this.
|
|
112
|
-
this.
|
|
113
|
-
this.showTestDialog
|
|
121
|
+
this._testSendModel.set({ configId: '', recipient: '' });
|
|
122
|
+
this._variableValues.set({}); // Reset variable values
|
|
123
|
+
this.showTestDialog.set(true);
|
|
114
124
|
await this.loadConfigs();
|
|
115
125
|
}
|
|
116
126
|
async loadConfigs() {
|
|
@@ -132,7 +142,8 @@ class TemplateListComponent {
|
|
|
132
142
|
}
|
|
133
143
|
async sendTestEmail() {
|
|
134
144
|
const template = this.selectedTemplate();
|
|
135
|
-
|
|
145
|
+
const model = this.testSendModel;
|
|
146
|
+
if (!template || !model.configId || !model.recipient) {
|
|
136
147
|
this.messageService.add({
|
|
137
148
|
severity: 'warn',
|
|
138
149
|
summary: 'Validation',
|
|
@@ -151,8 +162,8 @@ class TemplateListComponent {
|
|
|
151
162
|
}
|
|
152
163
|
const response = await firstValueFrom(this.emailSendService.sendTemplate({
|
|
153
164
|
templateId: template.id,
|
|
154
|
-
to:
|
|
155
|
-
emailConfigId:
|
|
165
|
+
to: model.recipient,
|
|
166
|
+
emailConfigId: model.configId,
|
|
156
167
|
variables: Object.keys(variables).length > 0 ? variables : undefined,
|
|
157
168
|
}));
|
|
158
169
|
if (response.data?.success) {
|
|
@@ -161,7 +172,7 @@ class TemplateListComponent {
|
|
|
161
172
|
summary: 'Success',
|
|
162
173
|
detail: `Test email sent! Message ID: ${response.data.messageId}`,
|
|
163
174
|
});
|
|
164
|
-
this.showTestDialog
|
|
175
|
+
this.showTestDialog.set(false);
|
|
165
176
|
}
|
|
166
177
|
else {
|
|
167
178
|
this.messageService.add({
|
|
@@ -171,12 +182,8 @@ class TemplateListComponent {
|
|
|
171
182
|
});
|
|
172
183
|
}
|
|
173
184
|
}
|
|
174
|
-
catch
|
|
175
|
-
|
|
176
|
-
severity: 'error',
|
|
177
|
-
summary: 'Error',
|
|
178
|
-
detail: error?.message || 'Failed to send test email.',
|
|
179
|
-
});
|
|
185
|
+
catch {
|
|
186
|
+
// Error toast handled by global interceptor
|
|
180
187
|
}
|
|
181
188
|
finally {
|
|
182
189
|
this.isSendingTest.set(false);
|
|
@@ -198,124 +205,136 @@ class TemplateListComponent {
|
|
|
198
205
|
});
|
|
199
206
|
this.loadTemplates();
|
|
200
207
|
}
|
|
201
|
-
catch
|
|
202
|
-
|
|
203
|
-
severity: 'error',
|
|
204
|
-
summary: 'Error',
|
|
205
|
-
detail: 'Failed to delete template.',
|
|
206
|
-
});
|
|
208
|
+
catch {
|
|
209
|
+
// Error toast handled by global interceptor
|
|
207
210
|
}
|
|
208
211
|
},
|
|
209
212
|
});
|
|
210
213
|
}
|
|
211
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.
|
|
212
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.
|
|
214
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: TemplateListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
215
|
+
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: `
|
|
213
216
|
<div class="card">
|
|
214
|
-
<div class="flex justify-between items-center mb-4">
|
|
217
|
+
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4">
|
|
215
218
|
<div>
|
|
216
|
-
<h3 class="text-xl font-semibold">Email Templates</h3>
|
|
219
|
+
<h3 class="text-lg sm:text-xl font-semibold m-0">Email Templates</h3>
|
|
217
220
|
@if (showCompanyInfo()) {
|
|
218
|
-
<p class="text-sm text-
|
|
221
|
+
<p class="text-sm text-muted-color mt-1">
|
|
219
222
|
Company: {{ currentCompanyName() }}
|
|
220
223
|
</p>
|
|
221
224
|
}
|
|
222
225
|
</div>
|
|
223
226
|
<p-button
|
|
227
|
+
*hasPermission="EMAIL_TEMPLATE_PERMISSIONS.CREATE"
|
|
224
228
|
label="New Template"
|
|
225
229
|
icon="pi pi-plus"
|
|
226
230
|
(onClick)="onCreate()"
|
|
231
|
+
styleClass="w-full sm:w-auto"
|
|
227
232
|
/>
|
|
228
233
|
</div>
|
|
229
234
|
|
|
230
|
-
<
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
<
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
235
|
+
<div class="overflow-x-auto -mx-4 sm:mx-0">
|
|
236
|
+
<p-table
|
|
237
|
+
[value]="templates()"
|
|
238
|
+
[loading]="isLoading()"
|
|
239
|
+
[paginator]="totalRecords() > 0"
|
|
240
|
+
[rows]="pageSize()"
|
|
241
|
+
[first]="first()"
|
|
242
|
+
[totalRecords]="totalRecords()"
|
|
243
|
+
[lazy]="true"
|
|
244
|
+
(onLazyLoad)="onLazyLoad($event)"
|
|
245
|
+
[rowsPerPageOptions]="[10, 25, 50]"
|
|
246
|
+
styleClass="p-datatable-sm"
|
|
247
|
+
[tableStyle]="{ 'min-width': '50rem' }"
|
|
248
|
+
>
|
|
249
|
+
<ng-template #header>
|
|
250
|
+
<tr>
|
|
251
|
+
<th>Name</th>
|
|
252
|
+
<th class="hidden md:table-cell">Slug</th>
|
|
253
|
+
<th class="hidden lg:table-cell">Subject</th>
|
|
254
|
+
<th>Type</th>
|
|
255
|
+
<th>Status</th>
|
|
256
|
+
<th class="hidden xl:table-cell">Created</th>
|
|
257
|
+
<th class="w-[120px]">Actions</th>
|
|
258
|
+
</tr>
|
|
259
|
+
</ng-template>
|
|
251
260
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
261
|
+
<ng-template #body let-template>
|
|
262
|
+
<tr>
|
|
263
|
+
<td>
|
|
264
|
+
<i class="pi pi-envelope mr-2 text-muted-color"></i>
|
|
265
|
+
{{ template.name }}
|
|
266
|
+
</td>
|
|
267
|
+
<td class="hidden md:table-cell">
|
|
268
|
+
<code class="text-sm bg-surface-100 dark:bg-surface-700 px-2 py-1 rounded">{{ template.slug }}</code>
|
|
269
|
+
</td>
|
|
270
|
+
<td class="hidden lg:table-cell">{{ template.subject }}</td>
|
|
271
|
+
<td>
|
|
272
|
+
<p-tag
|
|
273
|
+
[value]="template.isHtml ? 'HTML' : 'Text'"
|
|
274
|
+
[severity]="template.isHtml ? 'info' : 'secondary'"
|
|
275
|
+
/>
|
|
276
|
+
</td>
|
|
277
|
+
<td>
|
|
278
|
+
<p-tag
|
|
279
|
+
[value]="template.isActive ? 'Active' : 'Inactive'"
|
|
280
|
+
[severity]="template.isActive ? 'success' : 'secondary'"
|
|
281
|
+
/>
|
|
282
|
+
</td>
|
|
283
|
+
<td class="hidden xl:table-cell">{{ template.createdAt | date: 'short' }}</td>
|
|
284
|
+
<td>
|
|
285
|
+
<div class="flex gap-1">
|
|
286
|
+
<p-button
|
|
287
|
+
*hasPermission="EMAIL_TEMPLATE_PERMISSIONS.UPDATE"
|
|
288
|
+
icon="pi pi-send"
|
|
289
|
+
[text]="true"
|
|
290
|
+
size="small"
|
|
291
|
+
pTooltip="Test Send"
|
|
292
|
+
(onClick)="onTestSend(template)"
|
|
293
|
+
/>
|
|
294
|
+
<p-button
|
|
295
|
+
*hasPermission="EMAIL_TEMPLATE_PERMISSIONS.UPDATE"
|
|
296
|
+
icon="pi pi-pencil"
|
|
297
|
+
[text]="true"
|
|
298
|
+
severity="secondary"
|
|
299
|
+
size="small"
|
|
300
|
+
pTooltip="Edit"
|
|
301
|
+
(onClick)="onEdit(template.id)"
|
|
302
|
+
/>
|
|
303
|
+
<p-button
|
|
304
|
+
*hasPermission="EMAIL_TEMPLATE_PERMISSIONS.DELETE"
|
|
305
|
+
icon="pi pi-trash"
|
|
306
|
+
[text]="true"
|
|
307
|
+
severity="danger"
|
|
308
|
+
size="small"
|
|
309
|
+
pTooltip="Delete"
|
|
310
|
+
(onClick)="onDelete(template)"
|
|
311
|
+
/>
|
|
312
|
+
</div>
|
|
313
|
+
</td>
|
|
314
|
+
</tr>
|
|
315
|
+
</ng-template>
|
|
300
316
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
317
|
+
<ng-template #emptymessage>
|
|
318
|
+
<tr>
|
|
319
|
+
<td colspan="7" class="text-center py-4 text-muted-color">
|
|
320
|
+
No email templates found. Create your first template to get started.
|
|
321
|
+
</td>
|
|
322
|
+
</tr>
|
|
323
|
+
</ng-template>
|
|
324
|
+
</p-table>
|
|
325
|
+
</div>
|
|
309
326
|
</div>
|
|
310
327
|
|
|
311
328
|
<!-- Test Send Dialog -->
|
|
312
329
|
<p-dialog
|
|
313
330
|
header="Test Send Email"
|
|
314
|
-
[
|
|
331
|
+
[visible]="showTestDialog()"
|
|
332
|
+
(visibleChange)="showTestDialog.set($event)"
|
|
315
333
|
[modal]="true"
|
|
316
|
-
[style]="{ width: '500px', maxHeight: '80vh' }"
|
|
334
|
+
[style]="{ width: '95vw', maxWidth: '500px', maxHeight: '80vh' }"
|
|
335
|
+
[breakpoints]="{ '575px': '95vw' }"
|
|
317
336
|
>
|
|
318
|
-
<div class="
|
|
337
|
+
<div class="flex flex-col gap-4">
|
|
319
338
|
<div class="field">
|
|
320
339
|
<label class="block font-medium mb-2">Template</label>
|
|
321
340
|
<input
|
|
@@ -329,7 +348,8 @@ class TemplateListComponent {
|
|
|
329
348
|
<div class="field">
|
|
330
349
|
<label class="block font-medium mb-2">Email Configuration *</label>
|
|
331
350
|
<p-select
|
|
332
|
-
[
|
|
351
|
+
[ngModel]="testSendModel.configId"
|
|
352
|
+
(ngModelChange)="updateTestSendModel('configId', $event)"
|
|
333
353
|
[options]="configOptions()"
|
|
334
354
|
optionLabel="label"
|
|
335
355
|
optionValue="value"
|
|
@@ -343,7 +363,8 @@ class TemplateListComponent {
|
|
|
343
363
|
<label class="block font-medium mb-2">Recipient Email *</label>
|
|
344
364
|
<input
|
|
345
365
|
pInputText
|
|
346
|
-
[
|
|
366
|
+
[ngModel]="testSendModel.recipient"
|
|
367
|
+
(ngModelChange)="updateTestSendModel('recipient', $event)"
|
|
347
368
|
class="w-full"
|
|
348
369
|
placeholder="recipient@example.com"
|
|
349
370
|
/>
|
|
@@ -351,21 +372,21 @@ class TemplateListComponent {
|
|
|
351
372
|
|
|
352
373
|
<!-- Dynamic Variables -->
|
|
353
374
|
@if (templateVariables().length > 0) {
|
|
354
|
-
<div class="border-t pt-4 mt-2">
|
|
375
|
+
<div class="border-t border-surface pt-4 mt-2">
|
|
355
376
|
<h4 class="font-medium mb-3 flex items-center gap-2">
|
|
356
|
-
<i class="pi pi-code"></i>
|
|
377
|
+
<i class="pi pi-code text-muted-color"></i>
|
|
357
378
|
Template Variables
|
|
358
379
|
</h4>
|
|
359
|
-
<div class="
|
|
380
|
+
<div class="flex flex-col gap-3">
|
|
360
381
|
@for (variable of templateVariables(); track variable) {
|
|
361
382
|
<div class="field">
|
|
362
383
|
<label class="block text-sm font-medium mb-1">
|
|
363
|
-
<code class="text-primary">{{ '{{' + variable + '}}' }}</code>
|
|
384
|
+
<code class="text-primary bg-surface-100 dark:bg-surface-700 px-1 rounded">{{ '{{' + variable + '}}' }}</code>
|
|
364
385
|
</label>
|
|
365
386
|
<input
|
|
366
387
|
pInputText
|
|
367
388
|
[ngModel]="variableValues[variable] || ''"
|
|
368
|
-
(ngModelChange)="
|
|
389
|
+
(ngModelChange)="updateVariableValue(variable, $event)"
|
|
369
390
|
class="w-full"
|
|
370
391
|
[placeholder]="'Enter value for ' + variable"
|
|
371
392
|
/>
|
|
@@ -379,8 +400,9 @@ class TemplateListComponent {
|
|
|
379
400
|
<ng-template #footer>
|
|
380
401
|
<p-button
|
|
381
402
|
label="Cancel"
|
|
382
|
-
|
|
383
|
-
|
|
403
|
+
severity="secondary"
|
|
404
|
+
[outlined]="true"
|
|
405
|
+
(onClick)="showTestDialog.set(false)"
|
|
384
406
|
/>
|
|
385
407
|
<p-button
|
|
386
408
|
label="Send Test"
|
|
@@ -393,123 +415,138 @@ class TemplateListComponent {
|
|
|
393
415
|
|
|
394
416
|
<p-confirmDialog />
|
|
395
417
|
<p-toast />
|
|
396
|
-
`, 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:
|
|
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" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
397
419
|
}
|
|
398
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.
|
|
420
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: TemplateListComponent, decorators: [{
|
|
399
421
|
type: Component,
|
|
400
422
|
args: [{
|
|
401
423
|
selector: 'lib-template-list',
|
|
402
|
-
standalone: true,
|
|
403
424
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
404
|
-
imports: [AngularModule, PrimeModule,
|
|
425
|
+
imports: [AngularModule, PrimeModule, HasPermissionDirective],
|
|
405
426
|
providers: [ConfirmationService, MessageService],
|
|
406
427
|
template: `
|
|
407
428
|
<div class="card">
|
|
408
|
-
<div class="flex justify-between items-center mb-4">
|
|
429
|
+
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4">
|
|
409
430
|
<div>
|
|
410
|
-
<h3 class="text-xl font-semibold">Email Templates</h3>
|
|
431
|
+
<h3 class="text-lg sm:text-xl font-semibold m-0">Email Templates</h3>
|
|
411
432
|
@if (showCompanyInfo()) {
|
|
412
|
-
<p class="text-sm text-
|
|
433
|
+
<p class="text-sm text-muted-color mt-1">
|
|
413
434
|
Company: {{ currentCompanyName() }}
|
|
414
435
|
</p>
|
|
415
436
|
}
|
|
416
437
|
</div>
|
|
417
438
|
<p-button
|
|
439
|
+
*hasPermission="EMAIL_TEMPLATE_PERMISSIONS.CREATE"
|
|
418
440
|
label="New Template"
|
|
419
441
|
icon="pi pi-plus"
|
|
420
442
|
(onClick)="onCreate()"
|
|
443
|
+
styleClass="w-full sm:w-auto"
|
|
421
444
|
/>
|
|
422
445
|
</div>
|
|
423
446
|
|
|
424
|
-
<
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
<
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
447
|
+
<div class="overflow-x-auto -mx-4 sm:mx-0">
|
|
448
|
+
<p-table
|
|
449
|
+
[value]="templates()"
|
|
450
|
+
[loading]="isLoading()"
|
|
451
|
+
[paginator]="totalRecords() > 0"
|
|
452
|
+
[rows]="pageSize()"
|
|
453
|
+
[first]="first()"
|
|
454
|
+
[totalRecords]="totalRecords()"
|
|
455
|
+
[lazy]="true"
|
|
456
|
+
(onLazyLoad)="onLazyLoad($event)"
|
|
457
|
+
[rowsPerPageOptions]="[10, 25, 50]"
|
|
458
|
+
styleClass="p-datatable-sm"
|
|
459
|
+
[tableStyle]="{ 'min-width': '50rem' }"
|
|
460
|
+
>
|
|
461
|
+
<ng-template #header>
|
|
462
|
+
<tr>
|
|
463
|
+
<th>Name</th>
|
|
464
|
+
<th class="hidden md:table-cell">Slug</th>
|
|
465
|
+
<th class="hidden lg:table-cell">Subject</th>
|
|
466
|
+
<th>Type</th>
|
|
467
|
+
<th>Status</th>
|
|
468
|
+
<th class="hidden xl:table-cell">Created</th>
|
|
469
|
+
<th class="w-[120px]">Actions</th>
|
|
470
|
+
</tr>
|
|
471
|
+
</ng-template>
|
|
445
472
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
473
|
+
<ng-template #body let-template>
|
|
474
|
+
<tr>
|
|
475
|
+
<td>
|
|
476
|
+
<i class="pi pi-envelope mr-2 text-muted-color"></i>
|
|
477
|
+
{{ template.name }}
|
|
478
|
+
</td>
|
|
479
|
+
<td class="hidden md:table-cell">
|
|
480
|
+
<code class="text-sm bg-surface-100 dark:bg-surface-700 px-2 py-1 rounded">{{ template.slug }}</code>
|
|
481
|
+
</td>
|
|
482
|
+
<td class="hidden lg:table-cell">{{ template.subject }}</td>
|
|
483
|
+
<td>
|
|
484
|
+
<p-tag
|
|
485
|
+
[value]="template.isHtml ? 'HTML' : 'Text'"
|
|
486
|
+
[severity]="template.isHtml ? 'info' : 'secondary'"
|
|
487
|
+
/>
|
|
488
|
+
</td>
|
|
489
|
+
<td>
|
|
490
|
+
<p-tag
|
|
491
|
+
[value]="template.isActive ? 'Active' : 'Inactive'"
|
|
492
|
+
[severity]="template.isActive ? 'success' : 'secondary'"
|
|
493
|
+
/>
|
|
494
|
+
</td>
|
|
495
|
+
<td class="hidden xl:table-cell">{{ template.createdAt | date: 'short' }}</td>
|
|
496
|
+
<td>
|
|
497
|
+
<div class="flex gap-1">
|
|
498
|
+
<p-button
|
|
499
|
+
*hasPermission="EMAIL_TEMPLATE_PERMISSIONS.UPDATE"
|
|
500
|
+
icon="pi pi-send"
|
|
501
|
+
[text]="true"
|
|
502
|
+
size="small"
|
|
503
|
+
pTooltip="Test Send"
|
|
504
|
+
(onClick)="onTestSend(template)"
|
|
505
|
+
/>
|
|
506
|
+
<p-button
|
|
507
|
+
*hasPermission="EMAIL_TEMPLATE_PERMISSIONS.UPDATE"
|
|
508
|
+
icon="pi pi-pencil"
|
|
509
|
+
[text]="true"
|
|
510
|
+
severity="secondary"
|
|
511
|
+
size="small"
|
|
512
|
+
pTooltip="Edit"
|
|
513
|
+
(onClick)="onEdit(template.id)"
|
|
514
|
+
/>
|
|
515
|
+
<p-button
|
|
516
|
+
*hasPermission="EMAIL_TEMPLATE_PERMISSIONS.DELETE"
|
|
517
|
+
icon="pi pi-trash"
|
|
518
|
+
[text]="true"
|
|
519
|
+
severity="danger"
|
|
520
|
+
size="small"
|
|
521
|
+
pTooltip="Delete"
|
|
522
|
+
(onClick)="onDelete(template)"
|
|
523
|
+
/>
|
|
524
|
+
</div>
|
|
525
|
+
</td>
|
|
526
|
+
</tr>
|
|
527
|
+
</ng-template>
|
|
494
528
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
529
|
+
<ng-template #emptymessage>
|
|
530
|
+
<tr>
|
|
531
|
+
<td colspan="7" class="text-center py-4 text-muted-color">
|
|
532
|
+
No email templates found. Create your first template to get started.
|
|
533
|
+
</td>
|
|
534
|
+
</tr>
|
|
535
|
+
</ng-template>
|
|
536
|
+
</p-table>
|
|
537
|
+
</div>
|
|
503
538
|
</div>
|
|
504
539
|
|
|
505
540
|
<!-- Test Send Dialog -->
|
|
506
541
|
<p-dialog
|
|
507
542
|
header="Test Send Email"
|
|
508
|
-
[
|
|
543
|
+
[visible]="showTestDialog()"
|
|
544
|
+
(visibleChange)="showTestDialog.set($event)"
|
|
509
545
|
[modal]="true"
|
|
510
|
-
[style]="{ width: '500px', maxHeight: '80vh' }"
|
|
546
|
+
[style]="{ width: '95vw', maxWidth: '500px', maxHeight: '80vh' }"
|
|
547
|
+
[breakpoints]="{ '575px': '95vw' }"
|
|
511
548
|
>
|
|
512
|
-
<div class="
|
|
549
|
+
<div class="flex flex-col gap-4">
|
|
513
550
|
<div class="field">
|
|
514
551
|
<label class="block font-medium mb-2">Template</label>
|
|
515
552
|
<input
|
|
@@ -523,7 +560,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
523
560
|
<div class="field">
|
|
524
561
|
<label class="block font-medium mb-2">Email Configuration *</label>
|
|
525
562
|
<p-select
|
|
526
|
-
[
|
|
563
|
+
[ngModel]="testSendModel.configId"
|
|
564
|
+
(ngModelChange)="updateTestSendModel('configId', $event)"
|
|
527
565
|
[options]="configOptions()"
|
|
528
566
|
optionLabel="label"
|
|
529
567
|
optionValue="value"
|
|
@@ -537,7 +575,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
537
575
|
<label class="block font-medium mb-2">Recipient Email *</label>
|
|
538
576
|
<input
|
|
539
577
|
pInputText
|
|
540
|
-
[
|
|
578
|
+
[ngModel]="testSendModel.recipient"
|
|
579
|
+
(ngModelChange)="updateTestSendModel('recipient', $event)"
|
|
541
580
|
class="w-full"
|
|
542
581
|
placeholder="recipient@example.com"
|
|
543
582
|
/>
|
|
@@ -545,21 +584,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
545
584
|
|
|
546
585
|
<!-- Dynamic Variables -->
|
|
547
586
|
@if (templateVariables().length > 0) {
|
|
548
|
-
<div class="border-t pt-4 mt-2">
|
|
587
|
+
<div class="border-t border-surface pt-4 mt-2">
|
|
549
588
|
<h4 class="font-medium mb-3 flex items-center gap-2">
|
|
550
|
-
<i class="pi pi-code"></i>
|
|
589
|
+
<i class="pi pi-code text-muted-color"></i>
|
|
551
590
|
Template Variables
|
|
552
591
|
</h4>
|
|
553
|
-
<div class="
|
|
592
|
+
<div class="flex flex-col gap-3">
|
|
554
593
|
@for (variable of templateVariables(); track variable) {
|
|
555
594
|
<div class="field">
|
|
556
595
|
<label class="block text-sm font-medium mb-1">
|
|
557
|
-
<code class="text-primary">{{ '{{' + variable + '}}' }}</code>
|
|
596
|
+
<code class="text-primary bg-surface-100 dark:bg-surface-700 px-1 rounded">{{ '{{' + variable + '}}' }}</code>
|
|
558
597
|
</label>
|
|
559
598
|
<input
|
|
560
599
|
pInputText
|
|
561
600
|
[ngModel]="variableValues[variable] || ''"
|
|
562
|
-
(ngModelChange)="
|
|
601
|
+
(ngModelChange)="updateVariableValue(variable, $event)"
|
|
563
602
|
class="w-full"
|
|
564
603
|
[placeholder]="'Enter value for ' + variable"
|
|
565
604
|
/>
|
|
@@ -573,8 +612,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
573
612
|
<ng-template #footer>
|
|
574
613
|
<p-button
|
|
575
614
|
label="Cancel"
|
|
576
|
-
|
|
577
|
-
|
|
615
|
+
severity="secondary"
|
|
616
|
+
[outlined]="true"
|
|
617
|
+
(onClick)="showTestDialog.set(false)"
|
|
578
618
|
/>
|
|
579
619
|
<p-button
|
|
580
620
|
label="Send Test"
|
|
@@ -592,4 +632,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
592
632
|
}] });
|
|
593
633
|
|
|
594
634
|
export { TemplateListComponent };
|
|
595
|
-
//# sourceMappingURL=flusys-ng-email-template-list.component-
|
|
635
|
+
//# sourceMappingURL=flusys-ng-email-template-list.component-krrpsjDv.mjs.map
|