ng-prime-tools 1.0.31 → 1.0.32
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/esm2022/lib/models/button.model.mjs +1 -1
- package/esm2022/lib/pt-advanced-prime-table/pt-advanced-prime-table.component.mjs +37 -52
- package/esm2022/lib/pt-button/pt-button.component.mjs +44 -16
- package/esm2022/lib/pt-dialog/pt-dialog.component.mjs +164 -129
- package/fesm2022/ng-prime-tools.mjs +241 -194
- package/fesm2022/ng-prime-tools.mjs.map +1 -1
- package/lib/models/button.model.d.ts +1 -0
- package/lib/models/button.model.d.ts.map +1 -1
- package/lib/pt-advanced-prime-table/pt-advanced-prime-table.component.d.ts +7 -2
- package/lib/pt-advanced-prime-table/pt-advanced-prime-table.component.d.ts.map +1 -1
- package/lib/pt-button/pt-button.component.d.ts +7 -1
- package/lib/pt-button/pt-button.component.d.ts.map +1 -1
- package/lib/pt-dialog/pt-dialog.component.d.ts +18 -1
- package/lib/pt-dialog/pt-dialog.component.d.ts.map +1 -1
- package/lib/pt-metric-panel/pt-metric-panel.component.d.ts +1 -1
- package/package.json +1 -1
|
@@ -7,7 +7,7 @@ import { FormControl, Validators, ReactiveFormsModule, FormsModule, FormGroup }
|
|
|
7
7
|
import * as i2 from 'primeng/table';
|
|
8
8
|
import { TableModule } from 'primeng/table';
|
|
9
9
|
import * as i1$1 from 'primeng/api';
|
|
10
|
-
import {
|
|
10
|
+
import { ConfirmationService, MessageService } from 'primeng/api';
|
|
11
11
|
import * as i4 from 'primeng/inputtext';
|
|
12
12
|
import { InputTextModule } from 'primeng/inputtext';
|
|
13
13
|
import * as i3 from 'primeng/button';
|
|
@@ -47,7 +47,7 @@ import { filter } from 'rxjs/operators';
|
|
|
47
47
|
import { BehaviorSubject } from 'rxjs';
|
|
48
48
|
import * as i3$6 from 'primeng/breadcrumb';
|
|
49
49
|
import { BreadcrumbModule } from 'primeng/breadcrumb';
|
|
50
|
-
import * as
|
|
50
|
+
import * as i4$2 from 'primeng/confirmdialog';
|
|
51
51
|
import { ConfirmDialogModule } from 'primeng/confirmdialog';
|
|
52
52
|
import { DialogModule } from 'primeng/dialog';
|
|
53
53
|
import * as i2$2 from 'primeng/toast';
|
|
@@ -181,6 +181,7 @@ class PTAdvancedPrimeTableComponent {
|
|
|
181
181
|
this.search = new EventEmitter();
|
|
182
182
|
this.exportExcelEvent = new EventEmitter();
|
|
183
183
|
this.exportPdfEvent = new EventEmitter();
|
|
184
|
+
this.pageChange = new EventEmitter();
|
|
184
185
|
this.TableTypeEnum = TableTypeEnum;
|
|
185
186
|
this.searchValue = '';
|
|
186
187
|
this.filters = {};
|
|
@@ -204,13 +205,15 @@ class PTAdvancedPrimeTableComponent {
|
|
|
204
205
|
this.hasGroupedColumns = false;
|
|
205
206
|
}
|
|
206
207
|
ngOnInit() {
|
|
208
|
+
console.log('PTAdvancedPrimeTable columns:', this.columns);
|
|
209
|
+
console.log('PTAdvancedPrimeTable totalRecords input:', this.totalRecords);
|
|
207
210
|
this.hasGroupedColumns = this.columns.some((col) => col.children && col.children.length > 0);
|
|
208
211
|
this.globalFilterFields = this.columns
|
|
209
212
|
.filter((col) => col.code !== undefined && col.isFilter !== false)
|
|
210
213
|
.map((col) => col.code);
|
|
211
214
|
this.initializePagination();
|
|
212
215
|
this.initializeActions();
|
|
213
|
-
// Set default value for isSortable
|
|
216
|
+
// Set default value for isSortable / isEditable + widths
|
|
214
217
|
this.columns.forEach((col) => {
|
|
215
218
|
if (col.type === TableTypeEnum.ACTION) {
|
|
216
219
|
col.isEditable = false;
|
|
@@ -242,85 +245,81 @@ class PTAdvancedPrimeTableComponent {
|
|
|
242
245
|
options: col.filterOptions,
|
|
243
246
|
value: [],
|
|
244
247
|
label: 'Filter by ' + composedName,
|
|
245
|
-
placeholder: 'Select
|
|
248
|
+
placeholder: 'Select option',
|
|
246
249
|
};
|
|
247
250
|
});
|
|
248
251
|
}
|
|
249
252
|
// Get the column type for composed fields (STRING, IMAGE, etc.)
|
|
250
253
|
getComposedFieldType(col, composedName) {
|
|
251
|
-
// Ensure that col.composedNames and col.composedTypes are valid arrays
|
|
252
254
|
if (col.composedNames && col.composedTypes) {
|
|
253
255
|
const index = col.composedNames.indexOf(composedName);
|
|
254
|
-
// Check if index is a valid number (not -1) and within bounds of composedTypes array
|
|
255
256
|
if (index >= 0 && index < col.composedTypes.length) {
|
|
256
|
-
return col.composedTypes[index];
|
|
257
|
+
return col.composedTypes[index];
|
|
257
258
|
}
|
|
258
259
|
}
|
|
259
|
-
return undefined;
|
|
260
|
+
return undefined;
|
|
260
261
|
}
|
|
261
|
-
onComposedFilterChange(composedName, selectedValues) {
|
|
262
|
-
console.log('Selected Values:', selectedValues);
|
|
263
|
-
console.log('Data Before Filtering:', this.data);
|
|
264
|
-
// Update the filter value with the selected values
|
|
262
|
+
onComposedFilterChange(col, composedName, selectedValues) {
|
|
265
263
|
this.filters[composedName].value = selectedValues;
|
|
266
|
-
// Emit the filter event to notify the parent component (if needed)
|
|
267
264
|
this.filter.emit(this.filters);
|
|
268
|
-
// Get the filter value (joining array into a string)
|
|
269
265
|
const filterValue = selectedValues.join(',');
|
|
270
|
-
|
|
271
|
-
|
|
266
|
+
let matchResults = [];
|
|
267
|
+
selectedValues.forEach((value) => {
|
|
268
|
+
const matches = this.dt.value.filter((row) => {
|
|
269
|
+
return row[col.code]?.[composedName]
|
|
270
|
+
?.toString()
|
|
271
|
+
.toLowerCase()
|
|
272
|
+
.includes(value.toLowerCase());
|
|
273
|
+
});
|
|
274
|
+
matchResults = [...matchResults, ...matches];
|
|
275
|
+
});
|
|
276
|
+
matchResults = Array.from(new Set(matchResults));
|
|
277
|
+
this.dt.filteredValue = matchResults;
|
|
272
278
|
this.dt.filterGlobal(filterValue, 'contains');
|
|
273
279
|
}
|
|
280
|
+
// ⛔ Don't override totalRecords here – we are in server-side mode
|
|
274
281
|
onFilter(event) {
|
|
275
|
-
this.
|
|
282
|
+
this.filter.emit(event);
|
|
283
|
+
// this.totalRecords = event.filteredValue?.length || 0; // removed
|
|
284
|
+
}
|
|
285
|
+
onPageChange(event) {
|
|
286
|
+
const page = event.page ?? Math.floor((event.first || 0) / event.rows);
|
|
287
|
+
const rows = event.rows;
|
|
288
|
+
this.rows = rows;
|
|
289
|
+
this.pageChange.emit({ page, rows });
|
|
276
290
|
}
|
|
277
291
|
onCalendarFilterChange(event, columnCode, filterCallback) {
|
|
278
|
-
// Log the data's date format for debugging
|
|
279
|
-
console.log('Data Before Filtering:', this.data.map((item) => item[columnCode]));
|
|
280
|
-
console.log('event : ' + event);
|
|
281
|
-
// Convert the event value to a string (in the desired date format)
|
|
282
292
|
const filterValue = event ? new Date(event) : null;
|
|
283
|
-
console.log('filterValue : ' + filterValue);
|
|
284
|
-
// If the filterValue is empty, do not trigger filterCallback
|
|
285
293
|
if (!filterValue) {
|
|
286
294
|
return;
|
|
287
295
|
}
|
|
288
|
-
// Manually trigger the filterCallback after updating the value (passing the string value)
|
|
289
296
|
filterCallback(filterValue);
|
|
290
297
|
const filterValueString = event ? this.formatDate(event) : '';
|
|
291
|
-
// Call the onFilter event to update totalRecords
|
|
292
298
|
this.onFilter({
|
|
293
299
|
filteredValue: this.data.filter((item) => {
|
|
294
300
|
const columnValue = item[columnCode];
|
|
295
|
-
// If the column value is a string, use it as is for comparison
|
|
296
301
|
if (columnValue) {
|
|
297
|
-
// Convert the item value to a string (in the same format)
|
|
298
302
|
const itemDateString = this.formatDate(new Date(columnValue));
|
|
299
|
-
return itemDateString === filterValueString;
|
|
303
|
+
return itemDateString === filterValueString;
|
|
300
304
|
}
|
|
301
305
|
return false;
|
|
302
306
|
}),
|
|
303
307
|
});
|
|
304
308
|
}
|
|
305
|
-
// Filter logic for composed columns (to check against multi-select values)
|
|
306
309
|
filterComposedData(item, composedName, value) {
|
|
307
310
|
if (Array.isArray(value) && value.length > 0) {
|
|
308
311
|
return value.some((filterValue) => item[composedName]?.toLowerCase().includes(filterValue.toLowerCase()));
|
|
309
312
|
}
|
|
310
313
|
return true;
|
|
311
314
|
}
|
|
312
|
-
// Function to calculate column width based on text in header and data
|
|
313
315
|
calculateColumnWidth(col) {
|
|
314
316
|
const calculatedWidth = calculateTextWidth(col, col.title);
|
|
315
317
|
const totalWidth = calculatedWidth + this.iconWidth + 20;
|
|
316
318
|
return `${totalWidth}px`;
|
|
317
319
|
}
|
|
318
320
|
getHeaderWidth(col) {
|
|
319
|
-
// Remove 'px' from col.width and convert it to a number
|
|
320
321
|
const widthWithoutPx = parseInt(col.width?.replace('px', '') || '0', 10);
|
|
321
|
-
// Add 20 to the calculated width
|
|
322
322
|
const headerWidth = widthWithoutPx + 20;
|
|
323
|
-
// Return the new width in 'px'
|
|
324
323
|
return `${headerWidth}px`;
|
|
325
324
|
}
|
|
326
325
|
clear(table) {
|
|
@@ -330,7 +329,6 @@ class PTAdvancedPrimeTableComponent {
|
|
|
330
329
|
parseDate(dateString) {
|
|
331
330
|
const parts = dateString.split('/');
|
|
332
331
|
if (parts.length === 3) {
|
|
333
|
-
// Assuming date format is DD/MM/YYYY
|
|
334
332
|
const day = parseInt(parts[0], 10);
|
|
335
333
|
const month = parseInt(parts[1], 10) - 1;
|
|
336
334
|
const year = parseInt(parts[2], 10);
|
|
@@ -341,7 +339,6 @@ class PTAdvancedPrimeTableComponent {
|
|
|
341
339
|
}
|
|
342
340
|
initializePagination() {
|
|
343
341
|
if (this.isPaginated) {
|
|
344
|
-
// Check if rowsPerPage is undefined or an empty array
|
|
345
342
|
if (!this.rowsPerPage || this.rowsPerPage.length === 0) {
|
|
346
343
|
this.rowsPerPage = [20, 30, 40];
|
|
347
344
|
}
|
|
@@ -422,7 +419,6 @@ class PTAdvancedPrimeTableComponent {
|
|
|
422
419
|
return 'text';
|
|
423
420
|
}
|
|
424
421
|
}
|
|
425
|
-
// State Check Methods
|
|
426
422
|
isEditable(key) {
|
|
427
423
|
let column = this.columns.find((item) => item.code === key);
|
|
428
424
|
return column?.isEditable !== false;
|
|
@@ -444,7 +440,6 @@ class PTAdvancedPrimeTableComponent {
|
|
|
444
440
|
return (this.columns.find((item) => item.code === key)?.type ===
|
|
445
441
|
TableTypeEnum.DATE);
|
|
446
442
|
}
|
|
447
|
-
// Utility Methods
|
|
448
443
|
dateConverter(value) {
|
|
449
444
|
return new Date(value).toLocaleDateString('en-US');
|
|
450
445
|
}
|
|
@@ -461,14 +456,12 @@ class PTAdvancedPrimeTableComponent {
|
|
|
461
456
|
filterGlobal(event) {
|
|
462
457
|
const target = event.target;
|
|
463
458
|
const value = target.value.toLowerCase();
|
|
464
|
-
// Create a new filtered dataset
|
|
465
459
|
const filteredData = this.data.filter((item) => {
|
|
466
460
|
return this.globalFilterFields.some((field) => {
|
|
467
461
|
const column = this.columns.find((col) => col.code === field);
|
|
468
462
|
if (!column) {
|
|
469
463
|
return false;
|
|
470
464
|
}
|
|
471
|
-
// Handle different column types
|
|
472
465
|
if (column.type === TableTypeEnum.DATE) {
|
|
473
466
|
const itemDate = this.formatDate(item[field]);
|
|
474
467
|
return itemDate && itemDate.includes(value);
|
|
@@ -478,7 +471,6 @@ class PTAdvancedPrimeTableComponent {
|
|
|
478
471
|
return (item[field] && item[field].toString().toLowerCase().includes(value));
|
|
479
472
|
}
|
|
480
473
|
else if (column.type === TableTypeEnum.COMPOSED) {
|
|
481
|
-
// Handle composed type by searching for text in the composed cells
|
|
482
474
|
return this.filterComposedColumn(item[field], value);
|
|
483
475
|
}
|
|
484
476
|
else {
|
|
@@ -486,14 +478,12 @@ class PTAdvancedPrimeTableComponent {
|
|
|
486
478
|
}
|
|
487
479
|
});
|
|
488
480
|
});
|
|
489
|
-
// Update the table's value
|
|
490
481
|
this.dt.value = filteredData;
|
|
491
|
-
//
|
|
492
|
-
this.totalRecords = filteredData.length ?? 0;
|
|
482
|
+
// ⛔ do NOT override totalRecords in server-side mode
|
|
483
|
+
// this.totalRecords = filteredData.length ?? 0;
|
|
493
484
|
}
|
|
494
485
|
filterComposedColumn(composedData, value) {
|
|
495
486
|
if (composedData) {
|
|
496
|
-
// Iterate over composed keys and check if any key's value contains the search text
|
|
497
487
|
return Object.keys(composedData).some((key) => {
|
|
498
488
|
const cellValue = composedData[key];
|
|
499
489
|
if (typeof cellValue === 'string') {
|
|
@@ -508,20 +498,17 @@ class PTAdvancedPrimeTableComponent {
|
|
|
508
498
|
if (!date)
|
|
509
499
|
return '';
|
|
510
500
|
if (date instanceof Date) {
|
|
511
|
-
// Handle Date object
|
|
512
501
|
const day = date.getDate().toString().padStart(2, '0');
|
|
513
502
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
514
503
|
const year = date.getFullYear().toString();
|
|
515
504
|
return `${day}/${month}/${year}`;
|
|
516
505
|
}
|
|
517
506
|
else if (typeof date === 'string') {
|
|
518
|
-
// Handle string date
|
|
519
507
|
const parts = date.split('/');
|
|
520
508
|
if (parts.length === 3) {
|
|
521
509
|
return `${parts[0]}/${parts[1]}/${parts[2]}`;
|
|
522
510
|
}
|
|
523
511
|
else {
|
|
524
|
-
// Handle partial dates
|
|
525
512
|
return date;
|
|
526
513
|
}
|
|
527
514
|
}
|
|
@@ -539,7 +526,6 @@ class PTAdvancedPrimeTableComponent {
|
|
|
539
526
|
width: style.width || 'auto',
|
|
540
527
|
height: style.height || 'auto',
|
|
541
528
|
};
|
|
542
|
-
// Fallback to empty string if margin, marginLeft, or marginRight are undefined
|
|
543
529
|
if (style.margin) {
|
|
544
530
|
imageStyle.margin = style.margin;
|
|
545
531
|
}
|
|
@@ -572,15 +558,12 @@ class PTAdvancedPrimeTableComponent {
|
|
|
572
558
|
formatNumber(value, decimalPlaces, thousandSeparator = 'comma', decimalSeparator = 'dot') {
|
|
573
559
|
if (value === null || value === undefined || isNaN(value))
|
|
574
560
|
return '';
|
|
575
|
-
// Convert the number to a string with full precision if decimalPlaces is undefined
|
|
576
561
|
let formattedNumber = decimalPlaces !== undefined
|
|
577
562
|
? value.toFixed(decimalPlaces)
|
|
578
563
|
: value.toString();
|
|
579
|
-
// Replace decimal separator (default is "dot")
|
|
580
564
|
if (decimalSeparator === 'comma') {
|
|
581
565
|
formattedNumber = formattedNumber.replace('.', ',');
|
|
582
566
|
}
|
|
583
|
-
// Apply thousand separator only if the number is >= 1000
|
|
584
567
|
if (thousandSeparator && Math.abs(value) >= 1000) {
|
|
585
568
|
const parts = formattedNumber.split(decimalSeparator === 'comma' ? ',' : '.');
|
|
586
569
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator === 'comma' ? ',' : ' ');
|
|
@@ -589,11 +572,11 @@ class PTAdvancedPrimeTableComponent {
|
|
|
589
572
|
return formattedNumber;
|
|
590
573
|
}
|
|
591
574
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTAdvancedPrimeTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
592
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTAdvancedPrimeTableComponent, selector: "pt-advanced-prime-table", inputs: { data: "data", columns: "columns", totalRecords: "totalRecords", rowsPerPage: "rowsPerPage", hasSearchFilter: "hasSearchFilter", hasExportExcel: "hasExportExcel", hasExportPDF: "hasExportPDF", hasColumnFilter: "hasColumnFilter", isPaginated: "isPaginated", actions: "actions", isSortable: "isSortable", loading: "loading", maxHeight: "maxHeight" }, outputs: { filter: "filter", search: "search", exportExcelEvent: "exportExcelEvent", exportPdfEvent: "exportPdfEvent" }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }], ngImport: i0, template: "<div class=\"pt-advanced-prime-table table-container\">\n <p-table\n #dt\n [value]=\"data\"\n [loading]=\"loading\"\n [rows]=\"rows\"\n [paginator]=\"isPaginated\"\n [globalFilterFields]=\"globalFilterFields\"\n [rowsPerPageOptions]=\"rowsPerPage\"\n dataKey=\"id\"\n styleClass=\"p-datatable-gridlines\"\n styleClass=\"p-datatable-striped\"\n editMode=\"row\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"onFilter($event)\"\n >\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n <!-- Clear filters -->\n <button\n *ngIf=\"hasSearchFilter\"\n pButton\n icon=\"pi pi-filter-slash\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"clear(dt)\"\n title=\"Clear filters\"\n ></button>\n\n <!-- Export to Excel Button -->\n <button\n *ngIf=\"hasExportExcel\"\n pButton\n icon=\"pi pi-file-excel\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportExcel()\"\n title=\"Export to Excel\"\n ></button>\n\n <!-- Export to PDF Button -->\n <button\n *ngIf=\"hasExportPDF\"\n pButton\n icon=\"pi pi-file-pdf\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportPdf()\"\n title=\"Export to PDF\"\n ></button>\n </div>\n <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <!-- Add this wrapper div with ml-auto class -->\n <p-iconField iconPosition=\"left\" class=\"ml-auto\">\n <p-inputIcon>\n <i class=\"pi pi-search\"></i>\n </p-inputIcon>\n <input\n pInputText\n type=\"text\"\n [(ngModel)]=\"searchValue\"\n (input)=\"filterGlobal($event)\"\n placeholder=\"Search keyword\"\n />\n </p-iconField>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n <ng-container *ngFor=\"let col of columns\">\n <th\n *ngIf=\"!col.children; else groupHeader\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n colspan=\"1\"\n >\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <th\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span>{{ col.title }}</span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon field=\"{{ col.code }}\" />\n <ng-container *ngIf=\"col.isFilter !== false\">\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n showClearButton=\"false\"\n showApplyButton=\"false\"\n >\n <!-- TableTypeEnum.COMPOSED -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n (onFilter)=\"onFilter($event)\"\n >\n <div *ngFor=\"let composedName of col.composedNames\">\n <ng-container\n *ngIf=\"\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n \"\n >\n <p-multiSelect\n [ngModel]=\"filters[composedName]?.value\"\n [options]=\"filters[composedName]?.options\"\n (onChange)=\"\n onComposedFilterChange(\n composedName,\n $event.value\n )\n \"\n [placeholder]=\"\n filters[composedName]?.placeholder\n \"\n [display]=\"'chip'\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n </ng-container>\n </div>\n\n <!-- Define itemTemplate here -->\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </ng-template>\n </p-columnFilter>\n\n <!-- other TableTypeEnum.XXX -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n hideOnClear=\"true\"\n >\n <!-- TableTypeEnum.NUMBER -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.NUMBER\"\n (onFilter)=\"onFilter($event)\"\n >\n <input\n pInputText\n type=\"number\"\n [step]=\"\n col.decimalPlaces\n ? '0.' + '1'.padEnd(col.decimalPlaces, '0')\n : 'any'\n \"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [placeholder]=\"'Enter a number'\"\n />\n </ng-template>\n\n <!-- TableTypeEnum.DATE -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n (onFilter)=\"onFilter($event)\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"\n onCalendarFilterChange(\n $event,\n col.code!,\n filterCallback\n )\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n [placeholder]=\"'Choose a date'\"\n ></p-calendar>\n </ng-template>\n\n <!-- TableTypeEnum.MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.MULTISELECT\"\n (onFilter)=\"onFilter($event)\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [display]=\"'chip'\"\n [placeholder]=\"'Choose option'\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </div>\n </th>\n </ng-container>\n <ng-template #noSortHeader>\n <th>\n <div class=\"header-container\">\n <span>{{ col.title }}</span>\n <ng-container *ngIf=\"col.isFilter !== false\">\n <p-columnFilter\n *ngIf=\"col.type === 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n ></p-columnFilter>\n\n <p-columnFilter\n *ngIf=\"col.type !== 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [display]=\"'chip'\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </th>\n </ng-template>\n </th>\n <!-- Grouped headers -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.text-align]=\"'center'\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n <!-- Child headers (Second Row) -->\n <tr *ngIf=\"hasGroupedColumns\">\n <ng-container *ngFor=\"let col of columns\">\n <ng-container *ngIf=\"col.children\">\n <th\n *ngFor=\"let child of col.children\"\n [style.width]=\"getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n >\n <!-- Sortable/Filterable header logic for child columns -->\n </th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- Empty message template -->\n <ng-template pTemplate=\"emptymessage\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </ng-template>\n\n <!-- Body -->\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n <!-- Render a table row and make it editable if `isEdit` is true -->\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <!-- Loop through each column -->\n <ng-container *ngFor=\"let col of columns\">\n <!-- Check if the column has children -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- Render a single cell for columns without children -->\n <ng-container\n *ngIf=\"col.code !== undefined && data[col.code] !== undefined\"\n >\n <td\n *ngIf=\"isEditable(col.code); else normalTD\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <!-- Editable input for the column -->\n <ng-container *ngIf=\"isMultiSelect(col.code); else datePicker\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-multiSelect\n appendTo=\"body\"\n [ngModel]=\"data[col.code]\"\n [style]=\"{ width: '100%' }\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [options]=\"optionValues\"\n ></p-multiSelect>\n </ng-template>\n <ng-template pTemplate=\"output\">\n <div class=\"multi-select-container\">\n <ng-container *ngFor=\"let rec of data[col.code]\">\n <p-tag [value]=\"rec\"></p-tag>\n </ng-container>\n </div>\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #datePicker>\n <ng-container\n *ngIf=\"isDatePicker(col.code); else normalInput\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-calendar\n [inputId]=\"data[col.code]\"\n [ngModel]=\"data[col.code]\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code] | customDate }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n </ng-template>\n\n <ng-template #normalInput>\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[col.code]\"\n (change)=\"onChange($event, data.id, col.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.AMOUNT;\n else normalOutput\n \"\n >\n {{\n data[col.code]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n <ng-template #normalOutput>\n {{ data[col.code] }}\n </ng-template>\n </ng-template>\n </p-cellEditor>\n </ng-template>\n </td>\n\n <ng-template #normalTD>\n <td [style.width]=\"getHeaderWidth(col)\">\n <!-- COMPOSED -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.COMPOSED\">\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- Check if the composedType is IMAGE -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n \"\n >\n <img\n [src]=\"data[col.code][composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"getImageStyle(col.composedStyles?.[composedName])\"\n />\n </ng-container>\n\n <!-- Check if the composedType is STRING -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n \"\n >\n <span\n class=\"composed-text\"\n [ngStyle]=\"getTitleStyle(col.composedStyles?.[composedName])\"\n >\n {{ data[col.code][composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- AMOUNT-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.AMOUNT\">\n {{\n data[col.code]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n\n <!-- NUMBER-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.NUMBER\">\n {{\n formatNumber(\n data[col.code],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <!-- DATE -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.DATE\">\n <!-- Format the date using your formatDate method -->\n {{ formatDate(data[col.code]) }}\n </ng-container>\n\n <!-- STRING, MULTISELECT-->\n <ng-container\n *ngIf=\"\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT\n ].includes(col.type!)\n \"\n >\n {{ data[col.code] }}\n </ng-container>\n </td>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <!-- Render child columns if the column has children -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <ng-container\n *ngIf=\"\n child.code !== undefined && data[child.code] !== undefined\n \"\n >\n <td [style.width]=\"getHeaderWidth(child)\">\n <!-- Render editable or normal cells for child columns -->\n <ng-container\n *ngIf=\"isEditable(child.code); else childNormalTD\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[child.code]\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[child.code] }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ data[child.code] }}\n </ng-template>\n </td>\n </ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n\n <!-- Render action buttons if there are any actions defined -->\n <td *ngIf=\"actions?.length\">\n <div class=\"action-buttons-container\">\n <div *ngIf=\"isDelete\">\n <button\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data.id)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n <div>\n <button\n pInitEditableRow\n *ngIf=\"!editing\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pSaveEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pCancelEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n </div>\n </td>\n </tr>\n </ng-template>\n </p-table>\n</div>\n", styles: [".pt-advanced-prime-table .bread-crumb{margin-bottom:15px}.pt-advanced-prime-table .date{width:100%;height:5rem;display:grid;justify-items:start;align-items:center}.pt-advanced-prime-table .filter-container{width:100%;display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .settings{display:flex;gap:1rem}.pt-advanced-prime-table .multi-select-container{display:flex;justify-content:center;align-items:center;gap:.3rem}.pt-advanced-prime-table ::ng-deep p-table{min-width:50rem}.pt-advanced-prime-table ::ng-deep .custom-multiselect .p-hidden-accessible input{display:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column.p-highlight:hover{background:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column:focus{box-shadow:none;outline:0 none}.pt-advanced-prime-table ::ng-deep .header-container{display:flex;justify-content:space-between;align-items:center;width:100%}.pt-advanced-prime-table ::ng-deep p-columnfilter.p-element.ng-star-inserted{margin-top:4px}.pt-advanced-prime-table .flex{display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .ml-auto{margin-left:auto}.pt-advanced-prime-table ::ng-deep p-inputicon{margin-right:-1.5rem;z-index:2;position:relative}.pt-advanced-prime-table ::ng-deep .p-inputtext{padding-left:1.7rem}.pt-advanced-prime-table ::ng-deep .bt-filter-btn button{cursor:pointer;margin-left:1rem}.pt-advanced-prime-table ::ng-deep .p-icon-field-left .p-input-icon:first-of-type{left:-1rem}.pt-advanced-prime-table .table-row{text-align:center;display:flex;gap:1rem;justify-content:center}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-excel{font-size:1.25em;color:green}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-pdf{font-size:1.25em;color:red}.pt-advanced-prime-table .table-container{display:flex;flex-direction:column;height:100%;overflow:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable{display:flex;flex-direction:column;width:100%;border-collapse:collapse;table-layout:fixed}.pt-advanced-prime-table ::ng-deep .p-datatable thead{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tfoot{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tbody{display:block;overflow-y:auto;overflow-x:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable tbody tr{display:table;width:100%;table-layout:fixed}.pt-advanced-prime-table .empty-message{text-align:center;padding:2rem;color:#888;font-size:1.2rem}.pt-advanced-prime-table .empty-message i{display:block;font-size:2rem;margin-bottom:.5rem}.pt-advanced-prime-table th{white-space:normal;word-wrap:break-word}.filter-image{width:22px;height:14px;margin-right:5px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "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", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], 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: "directive", type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i2.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "component", type: i2.CellEditor, selector: "p-cellEditor" }, { kind: "component", type: i2.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "directive", type: i2.EditableRow, selector: "[pEditableRow]", inputs: ["pEditableRow", "pEditableRowDisabled"] }, { kind: "directive", type: i2.InitEditableRow, selector: "[pInitEditableRow]" }, { kind: "directive", type: i2.SaveEditableRow, selector: "[pSaveEditableRow]" }, { kind: "directive", type: i2.CancelEditableRow, selector: "[pCancelEditableRow]" }, { kind: "component", type: i2.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping", "showButtons", "ariaLabel"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "directive", type: i3.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i6.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepYearPicker", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "directive", type: i2$1.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: i2$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8.MultiSelect, selector: "p-multiSelect", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "component", type: i9.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: i10.IconField, selector: "p-iconField", inputs: ["iconPosition"] }, { kind: "component", type: i11.InputIcon, selector: "p-inputIcon", inputs: ["styleClass"] }, { kind: "pipe", type: CustomCurrencyPipe, name: "customCurrency" }, { kind: "pipe", type: CustomDatePipe, name: "customDate" }] }); }
|
|
575
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTAdvancedPrimeTableComponent, selector: "pt-advanced-prime-table", inputs: { data: "data", columns: "columns", totalRecords: "totalRecords", rowsPerPage: "rowsPerPage", hasSearchFilter: "hasSearchFilter", hasExportExcel: "hasExportExcel", hasExportPDF: "hasExportPDF", hasColumnFilter: "hasColumnFilter", isPaginated: "isPaginated", actions: "actions", isSortable: "isSortable", loading: "loading", maxHeight: "maxHeight" }, outputs: { filter: "filter", search: "search", exportExcelEvent: "exportExcelEvent", exportPdfEvent: "exportPdfEvent", pageChange: "pageChange" }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }], ngImport: i0, template: "<div class=\"pt-advanced-prime-table table-container\">\n <p-table\n #dt\n [value]=\"data\"\n [loading]=\"loading\"\n [rows]=\"rows\"\n [paginator]=\"isPaginated\"\n [globalFilterFields]=\"globalFilterFields\"\n [rowsPerPageOptions]=\"rowsPerPage\"\n [totalRecords]=\"totalRecords\"\n [lazy]=\"true\"\n dataKey=\"id\"\n styleClass=\"p-datatable-gridlines\"\n styleClass=\"p-datatable-striped\"\n editMode=\"row\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"onFilter($event)\"\n (onPage)=\"onPageChange($event)\"\n >\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n <!-- Clear filters -->\n <button\n *ngIf=\"hasSearchFilter\"\n pButton\n icon=\"pi pi-filter-slash\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"clear(dt)\"\n title=\"Clear filters\"\n ></button>\n\n <!-- Export to Excel Button -->\n <button\n *ngIf=\"hasExportExcel\"\n pButton\n icon=\"pi pi-file-excel\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportExcel()\"\n title=\"Export to Excel\"\n ></button>\n\n <!-- Export to PDF Button -->\n <button\n *ngIf=\"hasExportPDF\"\n pButton\n icon=\"pi pi-file-pdf\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportPdf()\"\n title=\"Export to PDF\"\n ></button>\n </div>\n <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <!-- Add this wrapper div with ml-auto class -->\n <p-iconField iconPosition=\"left\" class=\"ml-auto\">\n <p-inputIcon>\n <i class=\"pi pi-search\"></i>\n </p-inputIcon>\n <input\n pInputText\n type=\"text\"\n [(ngModel)]=\"searchValue\"\n (input)=\"filterGlobal($event)\"\n placeholder=\"Search keyword\"\n />\n </p-iconField>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n <ng-container *ngFor=\"let col of columns\">\n <th\n *ngIf=\"!col.children; else groupHeader\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n colspan=\"1\"\n >\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <th\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span>{{ col.title }}</span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon field=\"{{ col.code }}\" />\n <ng-container *ngIf=\"col.isFilter !== false\">\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n showClearButton=\"false\"\n showApplyButton=\"false\"\n >\n <!-- TableTypeEnum.COMPOSED -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n (onFilter)=\"onFilter($event)\"\n >\n <div *ngFor=\"let composedName of col.composedNames\">\n <ng-container\n *ngIf=\"\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n \"\n >\n <p-multiSelect\n [ngModel]=\"filters[composedName]?.value\"\n [options]=\"filters[composedName]?.options\"\n (onChange)=\"\n onComposedFilterChange(\n col,\n composedName,\n $event.value\n )\n \"\n [placeholder]=\"\n filters[composedName]?.placeholder\n \"\n [display]=\"'chip'\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n </ng-container>\n </div>\n\n <!-- Define itemTemplate here -->\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </ng-template>\n </p-columnFilter>\n\n <!-- other TableTypeEnum.XXX -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n hideOnClear=\"true\"\n >\n <!-- TableTypeEnum.NUMBER -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.NUMBER\"\n (onFilter)=\"onFilter($event)\"\n >\n <input\n pInputText\n type=\"number\"\n [step]=\"\n col.decimalPlaces\n ? '0.' + '1'.padEnd(col.decimalPlaces, '0')\n : 'any'\n \"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [placeholder]=\"'Enter a number'\"\n />\n </ng-template>\n\n <!-- TableTypeEnum.DATE -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n (onFilter)=\"onFilter($event)\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"\n onCalendarFilterChange(\n $event,\n col.code!,\n filterCallback\n )\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n [placeholder]=\"'Choose a date'\"\n ></p-calendar>\n </ng-template>\n\n <!-- TableTypeEnum.MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"\n col.type === TableTypeEnum.MULTISELECT &&\n col.filterOptions &&\n col.filterOptions.length > 0\n \"\n (onFilter)=\"onFilter($event)\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [display]=\"'chip'\"\n [placeholder]=\"'Choose option'\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </div>\n </th>\n </ng-container>\n <ng-template #noSortHeader>\n <th>\n <div class=\"header-container\">\n <span>{{ col.title }}</span>\n <ng-container *ngIf=\"col.isFilter !== false\">\n <p-columnFilter\n *ngIf=\"col.type === 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n ></p-columnFilter>\n\n <p-columnFilter\n *ngIf=\"col.type !== 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [display]=\"'chip'\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </th>\n </ng-template>\n </th>\n <!-- Grouped headers -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.text-align]=\"'center'\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n <!-- Child headers (Second Row) -->\n <tr *ngIf=\"hasGroupedColumns\">\n <ng-container *ngFor=\"let col of columns\">\n <ng-container *ngIf=\"col.children\">\n <th\n *ngFor=\"let child of col.children\"\n [style.width]=\"getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n >\n <!-- Sortable/Filterable header logic for child columns -->\n </th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- Empty message template -->\n <ng-template pTemplate=\"emptymessage\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </ng-template>\n\n <!-- Body -->\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n <!-- Render a table row and make it editable if `isEdit` is true -->\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <!-- Loop through each column -->\n <ng-container *ngFor=\"let col of columns\">\n <!-- Check if the column has children -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- Render a single cell for columns without children -->\n <ng-container\n *ngIf=\"col.code !== undefined && data[col.code] !== undefined\"\n >\n <td\n *ngIf=\"isEditable(col.code); else normalTD\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <!-- Editable input for the column -->\n <ng-container *ngIf=\"isMultiSelect(col.code); else datePicker\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-multiSelect\n appendTo=\"body\"\n [ngModel]=\"data[col.code]\"\n [style]=\"{ width: '100%' }\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [options]=\"optionValues\"\n ></p-multiSelect>\n </ng-template>\n <ng-template pTemplate=\"output\">\n <div class=\"multi-select-container\">\n <ng-container *ngFor=\"let rec of data[col.code]\">\n <p-tag [value]=\"rec\"></p-tag>\n </ng-container>\n </div>\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #datePicker>\n <ng-container\n *ngIf=\"isDatePicker(col.code); else normalInput\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-calendar\n [inputId]=\"data[col.code]\"\n [ngModel]=\"data[col.code]\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code] | customDate }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n </ng-template>\n\n <ng-template #normalInput>\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[col.code]\"\n (change)=\"onChange($event, data.id, col.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.AMOUNT;\n else normalOutput\n \"\n >\n {{\n data[col.code]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n <ng-template #normalOutput>\n {{ data[col.code] }}\n </ng-template>\n </ng-template>\n </p-cellEditor>\n </ng-template>\n </td>\n\n <ng-template #normalTD>\n <td [style.width]=\"getHeaderWidth(col)\">\n <!-- COMPOSED -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.COMPOSED\">\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- Check if the composedType is IMAGE -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n \"\n >\n <img\n [src]=\"data[col.code][composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"getImageStyle(col.composedStyles?.[composedName])\"\n />\n </ng-container>\n\n <!-- Check if the composedType is STRING -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n \"\n >\n <span\n class=\"composed-text\"\n [ngStyle]=\"getTitleStyle(col.composedStyles?.[composedName])\"\n >\n {{ data[col.code][composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- AMOUNT-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.AMOUNT\">\n {{\n data[col.code]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n\n <!-- NUMBER-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.NUMBER\">\n {{\n formatNumber(\n data[col.code],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <!-- DATE -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.DATE\">\n <!-- Format the date using your formatDate method -->\n {{ formatDate(data[col.code]) }}\n </ng-container>\n\n <!-- STRING, MULTISELECT-->\n <ng-container\n *ngIf=\"\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT\n ].includes(col.type!)\n \"\n >\n {{ data[col.code] }}\n </ng-container>\n </td>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <!-- Render child columns if the column has children -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <ng-container\n *ngIf=\"\n child.code !== undefined && data[child.code] !== undefined\n \"\n >\n <td [style.width]=\"getHeaderWidth(child)\">\n <!-- Render editable or normal cells for child columns -->\n <ng-container\n *ngIf=\"isEditable(child.code); else childNormalTD\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[child.code]\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[child.code] }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ data[child.code] }}\n </ng-template>\n </td>\n </ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n\n <!-- Render action buttons if there are any actions defined -->\n <td *ngIf=\"actions?.length\">\n <div class=\"action-buttons-container\">\n <div *ngIf=\"isDelete\">\n <button\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data.id)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n <div>\n <button\n pInitEditableRow\n *ngIf=\"!editing\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pSaveEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pCancelEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n </div>\n </td>\n </tr>\n </ng-template>\n </p-table>\n</div>\n", styles: [".pt-advanced-prime-table .bread-crumb{margin-bottom:15px}.pt-advanced-prime-table .date{width:100%;height:5rem;display:grid;justify-items:start;align-items:center}.pt-advanced-prime-table .filter-container{width:100%;display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .settings{display:flex;gap:1rem}.pt-advanced-prime-table .multi-select-container{display:flex;justify-content:center;align-items:center;gap:.3rem}.pt-advanced-prime-table ::ng-deep p-table{min-width:50rem}.pt-advanced-prime-table ::ng-deep .custom-multiselect .p-hidden-accessible input{display:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column.p-highlight:hover{background:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column:focus{box-shadow:none;outline:0 none}.pt-advanced-prime-table ::ng-deep .header-container{display:flex;justify-content:space-between;align-items:center;width:100%}.pt-advanced-prime-table ::ng-deep p-columnfilter.p-element.ng-star-inserted{margin-top:4px}.pt-advanced-prime-table .flex{display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .ml-auto{margin-left:auto}.pt-advanced-prime-table ::ng-deep p-inputicon{margin-right:-1.5rem;z-index:2;position:relative}.pt-advanced-prime-table ::ng-deep .p-inputtext{padding-left:1.7rem}.pt-advanced-prime-table ::ng-deep .bt-filter-btn button{cursor:pointer;margin-left:1rem}.pt-advanced-prime-table ::ng-deep .p-icon-field-left .p-input-icon:first-of-type{left:-1rem}.pt-advanced-prime-table .table-row{text-align:center;display:flex;gap:1rem;justify-content:center}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-excel{font-size:1.25em;color:green}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-pdf{font-size:1.25em;color:red}.pt-advanced-prime-table .table-container{display:flex;flex-direction:column;height:100%;overflow:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable{display:flex;flex-direction:column;width:100%;border-collapse:collapse;table-layout:fixed}.pt-advanced-prime-table ::ng-deep .p-datatable thead{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tfoot{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tbody{display:block;overflow-y:auto;overflow-x:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable tbody tr{display:table;width:100%;table-layout:fixed}.pt-advanced-prime-table .empty-message{text-align:center;padding:2rem;color:#888;font-size:1.2rem}.pt-advanced-prime-table .empty-message i{display:block;font-size:2rem;margin-bottom:.5rem}.pt-advanced-prime-table th{white-space:normal;word-wrap:break-word}.filter-image{width:22px;height:14px;margin-right:5px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "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", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], 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: "directive", type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i2.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "component", type: i2.CellEditor, selector: "p-cellEditor" }, { kind: "component", type: i2.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "directive", type: i2.EditableRow, selector: "[pEditableRow]", inputs: ["pEditableRow", "pEditableRowDisabled"] }, { kind: "directive", type: i2.InitEditableRow, selector: "[pInitEditableRow]" }, { kind: "directive", type: i2.SaveEditableRow, selector: "[pSaveEditableRow]" }, { kind: "directive", type: i2.CancelEditableRow, selector: "[pCancelEditableRow]" }, { kind: "component", type: i2.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping", "showButtons", "ariaLabel"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "directive", type: i3.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i6.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepYearPicker", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "directive", type: i2$1.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: i2$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8.MultiSelect, selector: "p-multiSelect", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "component", type: i9.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: i10.IconField, selector: "p-iconField", inputs: ["iconPosition"] }, { kind: "component", type: i11.InputIcon, selector: "p-inputIcon", inputs: ["styleClass"] }, { kind: "pipe", type: CustomCurrencyPipe, name: "customCurrency" }, { kind: "pipe", type: CustomDatePipe, name: "customDate" }] }); }
|
|
593
576
|
}
|
|
594
577
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTAdvancedPrimeTableComponent, decorators: [{
|
|
595
578
|
type: Component,
|
|
596
|
-
args: [{ selector: 'pt-advanced-prime-table', template: "<div class=\"pt-advanced-prime-table table-container\">\n <p-table\n #dt\n [value]=\"data\"\n [loading]=\"loading\"\n [rows]=\"rows\"\n [paginator]=\"isPaginated\"\n [globalFilterFields]=\"globalFilterFields\"\n [rowsPerPageOptions]=\"rowsPerPage\"\n dataKey=\"id\"\n styleClass=\"p-datatable-gridlines\"\n styleClass=\"p-datatable-striped\"\n editMode=\"row\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"onFilter($event)\"\n >\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n <!-- Clear filters -->\n <button\n *ngIf=\"hasSearchFilter\"\n pButton\n icon=\"pi pi-filter-slash\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"clear(dt)\"\n title=\"Clear filters\"\n ></button>\n\n <!-- Export to Excel Button -->\n <button\n *ngIf=\"hasExportExcel\"\n pButton\n icon=\"pi pi-file-excel\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportExcel()\"\n title=\"Export to Excel\"\n ></button>\n\n <!-- Export to PDF Button -->\n <button\n *ngIf=\"hasExportPDF\"\n pButton\n icon=\"pi pi-file-pdf\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportPdf()\"\n title=\"Export to PDF\"\n ></button>\n </div>\n <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <!-- Add this wrapper div with ml-auto class -->\n <p-iconField iconPosition=\"left\" class=\"ml-auto\">\n <p-inputIcon>\n <i class=\"pi pi-search\"></i>\n </p-inputIcon>\n <input\n pInputText\n type=\"text\"\n [(ngModel)]=\"searchValue\"\n (input)=\"filterGlobal($event)\"\n placeholder=\"Search keyword\"\n />\n </p-iconField>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n <ng-container *ngFor=\"let col of columns\">\n <th\n *ngIf=\"!col.children; else groupHeader\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n colspan=\"1\"\n >\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <th\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span>{{ col.title }}</span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon field=\"{{ col.code }}\" />\n <ng-container *ngIf=\"col.isFilter !== false\">\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n showClearButton=\"false\"\n showApplyButton=\"false\"\n >\n <!-- TableTypeEnum.COMPOSED -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n (onFilter)=\"onFilter($event)\"\n >\n <div *ngFor=\"let composedName of col.composedNames\">\n <ng-container\n *ngIf=\"\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n \"\n >\n <p-multiSelect\n [ngModel]=\"filters[composedName]?.value\"\n [options]=\"filters[composedName]?.options\"\n (onChange)=\"\n onComposedFilterChange(\n composedName,\n $event.value\n )\n \"\n [placeholder]=\"\n filters[composedName]?.placeholder\n \"\n [display]=\"'chip'\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n </ng-container>\n </div>\n\n <!-- Define itemTemplate here -->\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </ng-template>\n </p-columnFilter>\n\n <!-- other TableTypeEnum.XXX -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n hideOnClear=\"true\"\n >\n <!-- TableTypeEnum.NUMBER -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.NUMBER\"\n (onFilter)=\"onFilter($event)\"\n >\n <input\n pInputText\n type=\"number\"\n [step]=\"\n col.decimalPlaces\n ? '0.' + '1'.padEnd(col.decimalPlaces, '0')\n : 'any'\n \"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [placeholder]=\"'Enter a number'\"\n />\n </ng-template>\n\n <!-- TableTypeEnum.DATE -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n (onFilter)=\"onFilter($event)\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"\n onCalendarFilterChange(\n $event,\n col.code!,\n filterCallback\n )\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n [placeholder]=\"'Choose a date'\"\n ></p-calendar>\n </ng-template>\n\n <!-- TableTypeEnum.MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.MULTISELECT\"\n (onFilter)=\"onFilter($event)\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [display]=\"'chip'\"\n [placeholder]=\"'Choose option'\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </div>\n </th>\n </ng-container>\n <ng-template #noSortHeader>\n <th>\n <div class=\"header-container\">\n <span>{{ col.title }}</span>\n <ng-container *ngIf=\"col.isFilter !== false\">\n <p-columnFilter\n *ngIf=\"col.type === 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n ></p-columnFilter>\n\n <p-columnFilter\n *ngIf=\"col.type !== 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [display]=\"'chip'\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </th>\n </ng-template>\n </th>\n <!-- Grouped headers -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.text-align]=\"'center'\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n <!-- Child headers (Second Row) -->\n <tr *ngIf=\"hasGroupedColumns\">\n <ng-container *ngFor=\"let col of columns\">\n <ng-container *ngIf=\"col.children\">\n <th\n *ngFor=\"let child of col.children\"\n [style.width]=\"getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n >\n <!-- Sortable/Filterable header logic for child columns -->\n </th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- Empty message template -->\n <ng-template pTemplate=\"emptymessage\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </ng-template>\n\n <!-- Body -->\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n <!-- Render a table row and make it editable if `isEdit` is true -->\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <!-- Loop through each column -->\n <ng-container *ngFor=\"let col of columns\">\n <!-- Check if the column has children -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- Render a single cell for columns without children -->\n <ng-container\n *ngIf=\"col.code !== undefined && data[col.code] !== undefined\"\n >\n <td\n *ngIf=\"isEditable(col.code); else normalTD\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <!-- Editable input for the column -->\n <ng-container *ngIf=\"isMultiSelect(col.code); else datePicker\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-multiSelect\n appendTo=\"body\"\n [ngModel]=\"data[col.code]\"\n [style]=\"{ width: '100%' }\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [options]=\"optionValues\"\n ></p-multiSelect>\n </ng-template>\n <ng-template pTemplate=\"output\">\n <div class=\"multi-select-container\">\n <ng-container *ngFor=\"let rec of data[col.code]\">\n <p-tag [value]=\"rec\"></p-tag>\n </ng-container>\n </div>\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #datePicker>\n <ng-container\n *ngIf=\"isDatePicker(col.code); else normalInput\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-calendar\n [inputId]=\"data[col.code]\"\n [ngModel]=\"data[col.code]\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code] | customDate }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n </ng-template>\n\n <ng-template #normalInput>\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[col.code]\"\n (change)=\"onChange($event, data.id, col.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.AMOUNT;\n else normalOutput\n \"\n >\n {{\n data[col.code]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n <ng-template #normalOutput>\n {{ data[col.code] }}\n </ng-template>\n </ng-template>\n </p-cellEditor>\n </ng-template>\n </td>\n\n <ng-template #normalTD>\n <td [style.width]=\"getHeaderWidth(col)\">\n <!-- COMPOSED -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.COMPOSED\">\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- Check if the composedType is IMAGE -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n \"\n >\n <img\n [src]=\"data[col.code][composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"getImageStyle(col.composedStyles?.[composedName])\"\n />\n </ng-container>\n\n <!-- Check if the composedType is STRING -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n \"\n >\n <span\n class=\"composed-text\"\n [ngStyle]=\"getTitleStyle(col.composedStyles?.[composedName])\"\n >\n {{ data[col.code][composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- AMOUNT-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.AMOUNT\">\n {{\n data[col.code]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n\n <!-- NUMBER-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.NUMBER\">\n {{\n formatNumber(\n data[col.code],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <!-- DATE -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.DATE\">\n <!-- Format the date using your formatDate method -->\n {{ formatDate(data[col.code]) }}\n </ng-container>\n\n <!-- STRING, MULTISELECT-->\n <ng-container\n *ngIf=\"\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT\n ].includes(col.type!)\n \"\n >\n {{ data[col.code] }}\n </ng-container>\n </td>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <!-- Render child columns if the column has children -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <ng-container\n *ngIf=\"\n child.code !== undefined && data[child.code] !== undefined\n \"\n >\n <td [style.width]=\"getHeaderWidth(child)\">\n <!-- Render editable or normal cells for child columns -->\n <ng-container\n *ngIf=\"isEditable(child.code); else childNormalTD\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[child.code]\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[child.code] }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ data[child.code] }}\n </ng-template>\n </td>\n </ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n\n <!-- Render action buttons if there are any actions defined -->\n <td *ngIf=\"actions?.length\">\n <div class=\"action-buttons-container\">\n <div *ngIf=\"isDelete\">\n <button\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data.id)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n <div>\n <button\n pInitEditableRow\n *ngIf=\"!editing\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pSaveEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pCancelEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n </div>\n </td>\n </tr>\n </ng-template>\n </p-table>\n</div>\n", styles: [".pt-advanced-prime-table .bread-crumb{margin-bottom:15px}.pt-advanced-prime-table .date{width:100%;height:5rem;display:grid;justify-items:start;align-items:center}.pt-advanced-prime-table .filter-container{width:100%;display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .settings{display:flex;gap:1rem}.pt-advanced-prime-table .multi-select-container{display:flex;justify-content:center;align-items:center;gap:.3rem}.pt-advanced-prime-table ::ng-deep p-table{min-width:50rem}.pt-advanced-prime-table ::ng-deep .custom-multiselect .p-hidden-accessible input{display:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column.p-highlight:hover{background:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column:focus{box-shadow:none;outline:0 none}.pt-advanced-prime-table ::ng-deep .header-container{display:flex;justify-content:space-between;align-items:center;width:100%}.pt-advanced-prime-table ::ng-deep p-columnfilter.p-element.ng-star-inserted{margin-top:4px}.pt-advanced-prime-table .flex{display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .ml-auto{margin-left:auto}.pt-advanced-prime-table ::ng-deep p-inputicon{margin-right:-1.5rem;z-index:2;position:relative}.pt-advanced-prime-table ::ng-deep .p-inputtext{padding-left:1.7rem}.pt-advanced-prime-table ::ng-deep .bt-filter-btn button{cursor:pointer;margin-left:1rem}.pt-advanced-prime-table ::ng-deep .p-icon-field-left .p-input-icon:first-of-type{left:-1rem}.pt-advanced-prime-table .table-row{text-align:center;display:flex;gap:1rem;justify-content:center}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-excel{font-size:1.25em;color:green}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-pdf{font-size:1.25em;color:red}.pt-advanced-prime-table .table-container{display:flex;flex-direction:column;height:100%;overflow:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable{display:flex;flex-direction:column;width:100%;border-collapse:collapse;table-layout:fixed}.pt-advanced-prime-table ::ng-deep .p-datatable thead{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tfoot{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tbody{display:block;overflow-y:auto;overflow-x:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable tbody tr{display:table;width:100%;table-layout:fixed}.pt-advanced-prime-table .empty-message{text-align:center;padding:2rem;color:#888;font-size:1.2rem}.pt-advanced-prime-table .empty-message i{display:block;font-size:2rem;margin-bottom:.5rem}.pt-advanced-prime-table th{white-space:normal;word-wrap:break-word}.filter-image{width:22px;height:14px;margin-right:5px}\n"] }]
|
|
579
|
+
args: [{ selector: 'pt-advanced-prime-table', template: "<div class=\"pt-advanced-prime-table table-container\">\n <p-table\n #dt\n [value]=\"data\"\n [loading]=\"loading\"\n [rows]=\"rows\"\n [paginator]=\"isPaginated\"\n [globalFilterFields]=\"globalFilterFields\"\n [rowsPerPageOptions]=\"rowsPerPage\"\n [totalRecords]=\"totalRecords\"\n [lazy]=\"true\"\n dataKey=\"id\"\n styleClass=\"p-datatable-gridlines\"\n styleClass=\"p-datatable-striped\"\n editMode=\"row\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onFilter)=\"onFilter($event)\"\n (onPage)=\"onPageChange($event)\"\n >\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n <!-- Clear filters -->\n <button\n *ngIf=\"hasSearchFilter\"\n pButton\n icon=\"pi pi-filter-slash\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"clear(dt)\"\n title=\"Clear filters\"\n ></button>\n\n <!-- Export to Excel Button -->\n <button\n *ngIf=\"hasExportExcel\"\n pButton\n icon=\"pi pi-file-excel\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportExcel()\"\n title=\"Export to Excel\"\n ></button>\n\n <!-- Export to PDF Button -->\n <button\n *ngIf=\"hasExportPDF\"\n pButton\n icon=\"pi pi-file-pdf\"\n class=\"p-button-rounded p-button-text\"\n (click)=\"exportPdf()\"\n title=\"Export to PDF\"\n ></button>\n </div>\n <div class=\"ml-auto\" *ngIf=\"hasSearchFilter\">\n <!-- Add this wrapper div with ml-auto class -->\n <p-iconField iconPosition=\"left\" class=\"ml-auto\">\n <p-inputIcon>\n <i class=\"pi pi-search\"></i>\n </p-inputIcon>\n <input\n pInputText\n type=\"text\"\n [(ngModel)]=\"searchValue\"\n (input)=\"filterGlobal($event)\"\n placeholder=\"Search keyword\"\n />\n </p-iconField>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n <ng-container *ngFor=\"let col of columns\">\n <th\n *ngIf=\"!col.children; else groupHeader\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n colspan=\"1\"\n >\n <ng-container\n *ngIf=\"isSortable && col.isSortable !== false; else noSortHeader\"\n >\n <th\n pSortableColumn=\"{{ col.code }}\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span>{{ col.title }}</span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon field=\"{{ col.code }}\" />\n <ng-container *ngIf=\"col.isFilter !== false\">\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type === TableTypeEnum.COMPOSED\"\n showClearButton=\"false\"\n showApplyButton=\"false\"\n >\n <!-- TableTypeEnum.COMPOSED -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n (onFilter)=\"onFilter($event)\"\n >\n <div *ngFor=\"let composedName of col.composedNames\">\n <ng-container\n *ngIf=\"\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n \"\n >\n <p-multiSelect\n [ngModel]=\"filters[composedName]?.value\"\n [options]=\"filters[composedName]?.options\"\n (onChange)=\"\n onComposedFilterChange(\n col,\n composedName,\n $event.value\n )\n \"\n [placeholder]=\"\n filters[composedName]?.placeholder\n \"\n [display]=\"'chip'\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n </ng-container>\n </div>\n\n <!-- Define itemTemplate here -->\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n <img\n *ngIf=\"item.image\"\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </ng-template>\n </p-columnFilter>\n\n <!-- other TableTypeEnum.XXX -->\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\n *ngIf=\"col.type !== TableTypeEnum.COMPOSED\"\n hideOnClear=\"true\"\n >\n <!-- TableTypeEnum.NUMBER -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.NUMBER\"\n (onFilter)=\"onFilter($event)\"\n >\n <input\n pInputText\n type=\"number\"\n [step]=\"\n col.decimalPlaces\n ? '0.' + '1'.padEnd(col.decimalPlaces, '0')\n : 'any'\n \"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [placeholder]=\"'Enter a number'\"\n />\n </ng-template>\n\n <!-- TableTypeEnum.DATE -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n (onFilter)=\"onFilter($event)\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"\n onCalendarFilterChange(\n $event,\n col.code!,\n filterCallback\n )\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n [placeholder]=\"'Choose a date'\"\n ></p-calendar>\n </ng-template>\n\n <!-- TableTypeEnum.MULTISELECT -->\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"\n col.type === TableTypeEnum.MULTISELECT &&\n col.filterOptions &&\n col.filterOptions.length > 0\n \"\n (onFilter)=\"onFilter($event)\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [display]=\"'chip'\"\n [placeholder]=\"'Choose option'\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </div>\n </th>\n </ng-container>\n <ng-template #noSortHeader>\n <th>\n <div class=\"header-container\">\n <span>{{ col.title }}</span>\n <ng-container *ngIf=\"col.isFilter !== false\">\n <p-columnFilter\n *ngIf=\"col.type === 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n ></p-columnFilter>\n\n <p-columnFilter\n *ngIf=\"col.type !== 'AMOUNT'\"\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-calendar\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n\n <ng-template\n pTemplate=\"filter\"\n let-value\n let-filterCallback=\"filterCallback\"\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n [ngModel]=\"value\"\n (ngModelChange)=\"filterCallback($event)\"\n [display]=\"'chip'\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n </ng-container>\n </div>\n </th>\n </ng-template>\n </th>\n <!-- Grouped headers -->\n <ng-template #groupHeader>\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"getHeaderWidth(col)\"\n [style.text-align]=\"'center'\"\n >\n <span>{{ col.title }}</span>\n </th>\n </ng-template>\n </ng-container>\n </tr>\n <!-- Child headers (Second Row) -->\n <tr *ngIf=\"hasGroupedColumns\">\n <ng-container *ngFor=\"let col of columns\">\n <ng-container *ngIf=\"col.children\">\n <th\n *ngFor=\"let child of col.children\"\n [style.width]=\"getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n >\n <!-- Sortable/Filterable header logic for child columns -->\n </th>\n </ng-container>\n </ng-container>\n </tr>\n </ng-template>\n\n <!-- Empty message template -->\n <ng-template pTemplate=\"emptymessage\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </ng-template>\n\n <!-- Body -->\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n <!-- Render a table row and make it editable if `isEdit` is true -->\n <tr *ngIf=\"!loading\" [pEditableRow]=\"isEdit ? data : null\">\n <!-- Loop through each column -->\n <ng-container *ngFor=\"let col of columns\">\n <!-- Check if the column has children -->\n <ng-container *ngIf=\"!col.children; else childColumns\">\n <!-- Render a single cell for columns without children -->\n <ng-container\n *ngIf=\"col.code !== undefined && data[col.code] !== undefined\"\n >\n <td\n *ngIf=\"isEditable(col.code); else normalTD\"\n [style.width]=\"getHeaderWidth(col)\"\n >\n <!-- Editable input for the column -->\n <ng-container *ngIf=\"isMultiSelect(col.code); else datePicker\">\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-multiSelect\n appendTo=\"body\"\n [ngModel]=\"data[col.code]\"\n [style]=\"{ width: '100%' }\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [options]=\"optionValues\"\n ></p-multiSelect>\n </ng-template>\n <ng-template pTemplate=\"output\">\n <div class=\"multi-select-container\">\n <ng-container *ngFor=\"let rec of data[col.code]\">\n <p-tag [value]=\"rec\"></p-tag>\n </ng-container>\n </div>\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #datePicker>\n <ng-container\n *ngIf=\"isDatePicker(col.code); else normalInput\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-calendar\n [inputId]=\"data[col.code]\"\n [ngModel]=\"data[col.code]\"\n (ngModelChange)=\"\n changeHandler(data.id, col.code, $event)\n \"\n [dateFormat]=\"'dd/mm/yy'\"\n ></p-calendar>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code] | customDate }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n </ng-template>\n\n <ng-template #normalInput>\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[col.code]\"\n (change)=\"onChange($event, data.id, col.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n <ng-container\n *ngIf=\"\n col.type === TableTypeEnum.AMOUNT;\n else normalOutput\n \"\n >\n {{\n data[col.code]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n <ng-template #normalOutput>\n {{ data[col.code] }}\n </ng-template>\n </ng-template>\n </p-cellEditor>\n </ng-template>\n </td>\n\n <ng-template #normalTD>\n <td [style.width]=\"getHeaderWidth(col)\">\n <!-- COMPOSED -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.COMPOSED\">\n <div class=\"composed-cell\">\n <ng-container\n *ngFor=\"\n let composedName of col.composedNames;\n let i = index\n \"\n >\n <!-- Check if the composedType is IMAGE -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n \"\n >\n <img\n [src]=\"data[col.code][composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"getImageStyle(col.composedStyles?.[composedName])\"\n />\n </ng-container>\n\n <!-- Check if the composedType is STRING -->\n <ng-container\n *ngIf=\"\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n \"\n >\n <span\n class=\"composed-text\"\n [ngStyle]=\"getTitleStyle(col.composedStyles?.[composedName])\"\n >\n {{ data[col.code][composedName] }}\n </span>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- AMOUNT-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.AMOUNT\">\n {{\n data[col.code]\n | customCurrency\n : getCurrencySymbol(col)\n : col.decimalPlaces\n : col.thousandSeparator\n : col.decimalSeparator\n }}\n </ng-container>\n\n <!-- NUMBER-->\n <ng-container *ngIf=\"col.type === TableTypeEnum.NUMBER\">\n {{\n formatNumber(\n data[col.code],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n </ng-container>\n\n <!-- DATE -->\n <ng-container *ngIf=\"col.type === TableTypeEnum.DATE\">\n <!-- Format the date using your formatDate method -->\n {{ formatDate(data[col.code]) }}\n </ng-container>\n\n <!-- STRING, MULTISELECT-->\n <ng-container\n *ngIf=\"\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT\n ].includes(col.type!)\n \"\n >\n {{ data[col.code] }}\n </ng-container>\n </td>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <!-- Render child columns if the column has children -->\n <ng-template #childColumns>\n <ng-container *ngFor=\"let child of col.children\">\n <ng-container\n *ngIf=\"\n child.code !== undefined && data[child.code] !== undefined\n \"\n >\n <td [style.width]=\"getHeaderWidth(child)\">\n <!-- Render editable or normal cells for child columns -->\n <ng-container\n *ngIf=\"isEditable(child.code); else childNormalTD\"\n >\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"data[child.code]\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[child.code] }}\n </ng-template>\n </p-cellEditor>\n </ng-container>\n\n <ng-template #childNormalTD>\n {{ data[child.code] }}\n </ng-template>\n </td>\n </ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n\n <!-- Render action buttons if there are any actions defined -->\n <td *ngIf=\"actions?.length\">\n <div class=\"action-buttons-container\">\n <div *ngIf=\"isDelete\">\n <button\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data.id)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n <div>\n <button\n pInitEditableRow\n *ngIf=\"!editing\"\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pSaveEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n <button\n *ngIf=\"editing\"\n pCancelEditableRow\n pButton\n pRipple\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n </div>\n </div>\n </td>\n </tr>\n </ng-template>\n </p-table>\n</div>\n", styles: [".pt-advanced-prime-table .bread-crumb{margin-bottom:15px}.pt-advanced-prime-table .date{width:100%;height:5rem;display:grid;justify-items:start;align-items:center}.pt-advanced-prime-table .filter-container{width:100%;display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .settings{display:flex;gap:1rem}.pt-advanced-prime-table .multi-select-container{display:flex;justify-content:center;align-items:center;gap:.3rem}.pt-advanced-prime-table ::ng-deep p-table{min-width:50rem}.pt-advanced-prime-table ::ng-deep .custom-multiselect .p-hidden-accessible input{display:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column.p-highlight:hover{background:none}.pt-advanced-prime-table ::ng-deep .p-datatable .p-sortable-column:focus{box-shadow:none;outline:0 none}.pt-advanced-prime-table ::ng-deep .header-container{display:flex;justify-content:space-between;align-items:center;width:100%}.pt-advanced-prime-table ::ng-deep p-columnfilter.p-element.ng-star-inserted{margin-top:4px}.pt-advanced-prime-table .flex{display:flex;justify-content:space-between;align-items:center}.pt-advanced-prime-table .ml-auto{margin-left:auto}.pt-advanced-prime-table ::ng-deep p-inputicon{margin-right:-1.5rem;z-index:2;position:relative}.pt-advanced-prime-table ::ng-deep .p-inputtext{padding-left:1.7rem}.pt-advanced-prime-table ::ng-deep .bt-filter-btn button{cursor:pointer;margin-left:1rem}.pt-advanced-prime-table ::ng-deep .p-icon-field-left .p-input-icon:first-of-type{left:-1rem}.pt-advanced-prime-table .table-row{text-align:center;display:flex;gap:1rem;justify-content:center}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-excel{font-size:1.25em;color:green}.pt-advanced-prime-table ::ng-deep span.p-button-icon.pi.pi-file-pdf{font-size:1.25em;color:red}.pt-advanced-prime-table .table-container{display:flex;flex-direction:column;height:100%;overflow:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable{display:flex;flex-direction:column;width:100%;border-collapse:collapse;table-layout:fixed}.pt-advanced-prime-table ::ng-deep .p-datatable thead{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tfoot{display:table;width:100%;table-layout:fixed;background:#fff;z-index:2}.pt-advanced-prime-table ::ng-deep .p-datatable tbody{display:block;overflow-y:auto;overflow-x:hidden}.pt-advanced-prime-table ::ng-deep .p-datatable tbody tr{display:table;width:100%;table-layout:fixed}.pt-advanced-prime-table .empty-message{text-align:center;padding:2rem;color:#888;font-size:1.2rem}.pt-advanced-prime-table .empty-message i{display:block;font-size:2rem;margin-bottom:.5rem}.pt-advanced-prime-table th{white-space:normal;word-wrap:break-word}.filter-image{width:22px;height:14px;margin-right:5px}\n"] }]
|
|
597
580
|
}], ctorParameters: () => [], propDecorators: { data: [{
|
|
598
581
|
type: Input
|
|
599
582
|
}], columns: [{
|
|
@@ -628,6 +611,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
628
611
|
type: Output
|
|
629
612
|
}], exportPdfEvent: [{
|
|
630
613
|
type: Output
|
|
614
|
+
}], pageChange: [{
|
|
615
|
+
type: Output
|
|
631
616
|
}], dt: [{
|
|
632
617
|
type: ViewChild,
|
|
633
618
|
args: ['dt', { static: false }]
|
|
@@ -3368,6 +3353,7 @@ class PTButtonComponent {
|
|
|
3368
3353
|
fontColor: '#000',
|
|
3369
3354
|
backgroundColor: '#fff',
|
|
3370
3355
|
borderColor: '#000',
|
|
3356
|
+
outlined: false,
|
|
3371
3357
|
};
|
|
3372
3358
|
}
|
|
3373
3359
|
}
|
|
@@ -3381,7 +3367,7 @@ class PTButtonComponent {
|
|
|
3381
3367
|
JSON.stringify({ ...prev, disabled: undefined }) ===
|
|
3382
3368
|
JSON.stringify({ ...curr, disabled: undefined });
|
|
3383
3369
|
if (onlyDisabledChanged) {
|
|
3384
|
-
this.updateDisabledStyles(curr.disabled);
|
|
3370
|
+
this.updateDisabledStyles(curr.disabled ?? false);
|
|
3385
3371
|
}
|
|
3386
3372
|
else {
|
|
3387
3373
|
this.applyButtonStyles();
|
|
@@ -3393,14 +3379,6 @@ class PTButtonComponent {
|
|
|
3393
3379
|
}
|
|
3394
3380
|
}
|
|
3395
3381
|
}
|
|
3396
|
-
updateDisabledStyles(isDisabled) {
|
|
3397
|
-
const buttonElement = this.el.nativeElement.querySelector('button.p-element');
|
|
3398
|
-
if (buttonElement) {
|
|
3399
|
-
this.renderer.setStyle(buttonElement, 'color', isDisabled ? '#999' : this.buttonConfig.fontColor);
|
|
3400
|
-
this.renderer.setStyle(buttonElement, 'background-color', isDisabled ? '#e0e0e0' : this.buttonConfig.backgroundColor);
|
|
3401
|
-
this.renderer.setStyle(buttonElement, 'border-color', isDisabled ? '#bdbdbd' : this.buttonConfig.borderColor);
|
|
3402
|
-
}
|
|
3403
|
-
}
|
|
3404
3382
|
ngAfterViewInit() {
|
|
3405
3383
|
this.applyButtonStyles();
|
|
3406
3384
|
}
|
|
@@ -3410,23 +3388,58 @@ class PTButtonComponent {
|
|
|
3410
3388
|
getType() {
|
|
3411
3389
|
return this.buttonConfig.type || 'button';
|
|
3412
3390
|
}
|
|
3391
|
+
updateDisabledStyles(isDisabled) {
|
|
3392
|
+
const buttonElement = this.el.nativeElement.querySelector('button.p-element');
|
|
3393
|
+
if (buttonElement) {
|
|
3394
|
+
this.renderer.setStyle(buttonElement, 'color', isDisabled ? '#999' : this.buttonConfig.fontColor);
|
|
3395
|
+
this.renderer.setStyle(buttonElement, 'background-color', isDisabled ? '#e0e0e0' : this.buttonConfig.backgroundColor);
|
|
3396
|
+
this.renderer.setStyle(buttonElement, 'border-color', isDisabled ? '#bdbdbd' : this.buttonConfig.borderColor);
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
/**
|
|
3400
|
+
* We delegate colors to PrimeNG theme when:
|
|
3401
|
+
* - outlined = true
|
|
3402
|
+
* - and no manual color is provided (no backgroundColor, borderColor, fontColor)
|
|
3403
|
+
*/
|
|
3404
|
+
shouldUseThemeColors() {
|
|
3405
|
+
if (!this.buttonConfig) {
|
|
3406
|
+
return false;
|
|
3407
|
+
}
|
|
3408
|
+
const outlined = !!this.buttonConfig.outlined; // ✅ coerce to boolean
|
|
3409
|
+
return (outlined &&
|
|
3410
|
+
!this.buttonConfig.backgroundColor &&
|
|
3411
|
+
!this.buttonConfig.borderColor &&
|
|
3412
|
+
!this.buttonConfig.fontColor);
|
|
3413
|
+
}
|
|
3413
3414
|
applyButtonStyles() {
|
|
3414
3415
|
const buttonElement = this.el.nativeElement.querySelector('button.p-element');
|
|
3415
|
-
if (buttonElement
|
|
3416
|
-
|
|
3416
|
+
if (!buttonElement || !this.buttonConfig) {
|
|
3417
|
+
return;
|
|
3418
|
+
}
|
|
3419
|
+
const isDisabled = !!this.buttonConfig.disabled;
|
|
3420
|
+
const useThemeColors = this.shouldUseThemeColors();
|
|
3421
|
+
// Width / height always applied
|
|
3422
|
+
this.renderer.setStyle(buttonElement, 'width', this.buttonConfig.width || 'auto');
|
|
3423
|
+
this.renderer.setStyle(buttonElement, 'height', this.buttonConfig.height || 'auto');
|
|
3424
|
+
// ✅ Only override colors when we are NOT delegating to PrimeNG theme
|
|
3425
|
+
if (!useThemeColors) {
|
|
3417
3426
|
this.renderer.setStyle(buttonElement, 'color', isDisabled ? '#999' : this.buttonConfig.fontColor);
|
|
3418
3427
|
this.renderer.setStyle(buttonElement, 'background-color', isDisabled ? '#e0e0e0' : this.buttonConfig.backgroundColor);
|
|
3419
3428
|
this.renderer.setStyle(buttonElement, 'border-color', isDisabled ? '#bdbdbd' : this.buttonConfig.borderColor);
|
|
3420
|
-
|
|
3421
|
-
|
|
3429
|
+
}
|
|
3430
|
+
else {
|
|
3431
|
+
// If we delegate to theme, clear any inline overrides
|
|
3432
|
+
this.renderer.removeStyle(buttonElement, 'color');
|
|
3433
|
+
this.renderer.removeStyle(buttonElement, 'background-color');
|
|
3434
|
+
this.renderer.removeStyle(buttonElement, 'border-color');
|
|
3422
3435
|
}
|
|
3423
3436
|
}
|
|
3424
3437
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTButtonComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3425
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTButtonComponent, selector: "pt-button", inputs: { buttonConfig: "buttonConfig" }, usesOnChanges: true, ngImport: i0, template: "<p-button\n [label]=\"buttonConfig.label\"\n [icon]=\"buttonConfig.icon || ''\"\n [iconPos]=\"getIconPos()\"\n [disabled]=\"buttonConfig.disabled\"\n [loading]=\"buttonConfig.loading\"\n [class]=\"buttonConfig.styleClass || ''\"\n [type]=\"getType()\"\n></p-button>\n", styles: ["::ng-deep p-button{display:block}\n"], dependencies: [{ kind: "component", type: i3.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }] }); }
|
|
3438
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTButtonComponent, selector: "pt-button", inputs: { buttonConfig: "buttonConfig" }, usesOnChanges: true, ngImport: i0, template: "<p-button\n [label]=\"buttonConfig.label\"\n [icon]=\"buttonConfig.icon || ''\"\n [iconPos]=\"getIconPos()\"\n [disabled]=\"buttonConfig.disabled\"\n [loading]=\"buttonConfig.loading\"\n [class]=\"buttonConfig.styleClass || ''\"\n [type]=\"getType()\"\n [severity]=\"buttonConfig.severity\"\n [outlined]=\"buttonConfig.outlined\"\n></p-button>\n", styles: ["::ng-deep p-button{display:block}\n"], dependencies: [{ kind: "component", type: i3.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }] }); }
|
|
3426
3439
|
}
|
|
3427
3440
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTButtonComponent, decorators: [{
|
|
3428
3441
|
type: Component,
|
|
3429
|
-
args: [{ selector: 'pt-button', template: "<p-button\n [label]=\"buttonConfig.label\"\n [icon]=\"buttonConfig.icon || ''\"\n [iconPos]=\"getIconPos()\"\n [disabled]=\"buttonConfig.disabled\"\n [loading]=\"buttonConfig.loading\"\n [class]=\"buttonConfig.styleClass || ''\"\n [type]=\"getType()\"\n></p-button>\n", styles: ["::ng-deep p-button{display:block}\n"] }]
|
|
3442
|
+
args: [{ selector: 'pt-button', template: "<p-button\n [label]=\"buttonConfig.label\"\n [icon]=\"buttonConfig.icon || ''\"\n [iconPos]=\"getIconPos()\"\n [disabled]=\"buttonConfig.disabled\"\n [loading]=\"buttonConfig.loading\"\n [class]=\"buttonConfig.styleClass || ''\"\n [type]=\"getType()\"\n [severity]=\"buttonConfig.severity\"\n [outlined]=\"buttonConfig.outlined\"\n></p-button>\n", styles: ["::ng-deep p-button{display:block}\n"] }]
|
|
3430
3443
|
}], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }], propDecorators: { buttonConfig: [{
|
|
3431
3444
|
type: Input
|
|
3432
3445
|
}] } });
|
|
@@ -3668,49 +3681,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
3668
3681
|
}]
|
|
3669
3682
|
}] });
|
|
3670
3683
|
|
|
3671
|
-
|
|
3684
|
+
/**
|
|
3685
|
+
* Styles per severity:
|
|
3686
|
+
* - Only header (text/color) is provided here.
|
|
3687
|
+
* - No default "content" text anymore.
|
|
3688
|
+
*/
|
|
3672
3689
|
const DIALOG_STYLES = {
|
|
3673
3690
|
[SeverityEnum.WARNING]: {
|
|
3674
|
-
header: { text: '
|
|
3675
|
-
content: { text: 'This is a warning message!', color: '#d98300' },
|
|
3676
|
-
confirmButtonConfig: { backgroundColor: '#d98300', fontColor: '#fff' },
|
|
3677
|
-
cancelButtonConfig: { backgroundColor: '#6c757d', fontColor: '#fff' },
|
|
3691
|
+
header: { text: 'Avertissement', color: '#8a4b00' },
|
|
3678
3692
|
},
|
|
3679
3693
|
[SeverityEnum.SUCCESS]: {
|
|
3680
|
-
header: { text: '
|
|
3681
|
-
content: { text: 'Operation was successful!', color: '#28a745' },
|
|
3682
|
-
confirmButtonConfig: { backgroundColor: '#28a745', fontColor: '#fff' },
|
|
3683
|
-
cancelButtonConfig: { backgroundColor: '#6c757d', fontColor: '#fff' },
|
|
3694
|
+
header: { text: 'Succès', color: '#166534' },
|
|
3684
3695
|
},
|
|
3685
3696
|
[SeverityEnum.DANGER]: {
|
|
3686
|
-
header: { text: '
|
|
3687
|
-
content: { text: 'An error occurred!', color: '#dc3545' },
|
|
3688
|
-
confirmButtonConfig: { backgroundColor: '#dc3545', fontColor: '#fff' },
|
|
3689
|
-
cancelButtonConfig: { backgroundColor: '#6c757d', fontColor: '#fff' },
|
|
3697
|
+
header: { text: 'Erreur', color: '#7f1d1d' },
|
|
3690
3698
|
},
|
|
3691
3699
|
[SeverityEnum.INFO]: {
|
|
3692
|
-
header: { text: 'Information', color: '#
|
|
3693
|
-
content: { text: 'Here is some important information.', color: '#007bff' },
|
|
3694
|
-
confirmButtonConfig: { backgroundColor: '#007bff', fontColor: '#fff' },
|
|
3695
|
-
cancelButtonConfig: { backgroundColor: '#6c757d', fontColor: '#fff' },
|
|
3700
|
+
header: { text: 'Information', color: '#2563eb' },
|
|
3696
3701
|
},
|
|
3697
3702
|
};
|
|
3698
|
-
|
|
3703
|
+
/**
|
|
3704
|
+
* Default config:
|
|
3705
|
+
* - content is now empty string (no default message).
|
|
3706
|
+
*/
|
|
3699
3707
|
const DEFAULT_DIALOG_CONFIG = {
|
|
3700
3708
|
header: { text: 'Confirmation' },
|
|
3701
3709
|
visible: false,
|
|
3702
|
-
width: '
|
|
3710
|
+
width: '720px',
|
|
3703
3711
|
height: 'auto',
|
|
3704
|
-
content: '
|
|
3712
|
+
content: '', // no default message
|
|
3705
3713
|
confirmButtonConfig: {
|
|
3706
|
-
label: '
|
|
3707
|
-
fontColor: '#fff',
|
|
3708
|
-
backgroundColor: '#007bff',
|
|
3714
|
+
label: 'Confirmer',
|
|
3709
3715
|
},
|
|
3710
3716
|
cancelButtonConfig: {
|
|
3711
|
-
label: '
|
|
3712
|
-
fontColor: '#fff',
|
|
3713
|
-
backgroundColor: '#6c757d',
|
|
3717
|
+
label: 'Annuler',
|
|
3714
3718
|
},
|
|
3715
3719
|
dialogStyle: SeverityEnum.INFO,
|
|
3716
3720
|
};
|
|
@@ -3723,11 +3727,13 @@ class PTDialogComponent {
|
|
|
3723
3727
|
this.dialogConfig = { ...DEFAULT_DIALOG_CONFIG };
|
|
3724
3728
|
this.confirm = new EventEmitter();
|
|
3725
3729
|
this.cancel = new EventEmitter();
|
|
3730
|
+
this.SeverityEnum = SeverityEnum;
|
|
3726
3731
|
}
|
|
3727
3732
|
ngOnChanges(changes) {
|
|
3728
3733
|
if (changes['dialogConfig']) {
|
|
3729
|
-
|
|
3730
|
-
|
|
3734
|
+
const current = changes['dialogConfig'].currentValue;
|
|
3735
|
+
if (changes['dialogConfig'].previousValue?.dialogStyle !==
|
|
3736
|
+
current?.dialogStyle) {
|
|
3731
3737
|
this.applyDialogStyle();
|
|
3732
3738
|
}
|
|
3733
3739
|
if (this.dialogConfig.visible) {
|
|
@@ -3735,80 +3741,124 @@ class PTDialogComponent {
|
|
|
3735
3741
|
}
|
|
3736
3742
|
}
|
|
3737
3743
|
}
|
|
3744
|
+
/**
|
|
3745
|
+
* Merge defaults + current config + severity style.
|
|
3746
|
+
* We are careful NOT to spread header (it can be string or object).
|
|
3747
|
+
*/
|
|
3738
3748
|
applyDialogStyle() {
|
|
3739
3749
|
const dialogStyle = this.dialogConfig.dialogStyle || SeverityEnum.INFO;
|
|
3740
3750
|
const styleConfig = DIALOG_STYLES[dialogStyle] || {};
|
|
3751
|
+
const current = this.dialogConfig;
|
|
3752
|
+
// Decide which header to use without spreading non-object types
|
|
3753
|
+
const mergedHeader = current.header !== undefined
|
|
3754
|
+
? current.header
|
|
3755
|
+
: styleConfig.header !== undefined
|
|
3756
|
+
? styleConfig.header
|
|
3757
|
+
: DEFAULT_DIALOG_CONFIG.header;
|
|
3741
3758
|
this.dialogConfig = {
|
|
3742
3759
|
...DEFAULT_DIALOG_CONFIG,
|
|
3760
|
+
...current,
|
|
3743
3761
|
...styleConfig,
|
|
3762
|
+
header: mergedHeader,
|
|
3744
3763
|
confirmButtonConfig: {
|
|
3745
3764
|
...DEFAULT_DIALOG_CONFIG.confirmButtonConfig,
|
|
3746
|
-
...
|
|
3765
|
+
...current.confirmButtonConfig,
|
|
3747
3766
|
},
|
|
3748
3767
|
cancelButtonConfig: {
|
|
3749
3768
|
...DEFAULT_DIALOG_CONFIG.cancelButtonConfig,
|
|
3750
|
-
...
|
|
3769
|
+
...current.cancelButtonConfig,
|
|
3751
3770
|
},
|
|
3771
|
+
visible: current.visible,
|
|
3772
|
+
};
|
|
3773
|
+
}
|
|
3774
|
+
getSeverityClass() {
|
|
3775
|
+
const style = this.dialogConfig.dialogStyle ?? SeverityEnum.INFO;
|
|
3776
|
+
switch (style) {
|
|
3777
|
+
case SeverityEnum.DANGER:
|
|
3778
|
+
return 'pt-dialog-danger';
|
|
3779
|
+
case SeverityEnum.WARNING:
|
|
3780
|
+
return 'pt-dialog-warning';
|
|
3781
|
+
case SeverityEnum.SUCCESS:
|
|
3782
|
+
return 'pt-dialog-success';
|
|
3783
|
+
case SeverityEnum.INFO:
|
|
3784
|
+
default:
|
|
3785
|
+
return 'pt-dialog-info';
|
|
3786
|
+
}
|
|
3787
|
+
}
|
|
3788
|
+
/** SUCCESS & INFO share same behaviour, only color differs */
|
|
3789
|
+
getSeverityColors() {
|
|
3790
|
+
const style = this.dialogConfig.dialogStyle ?? SeverityEnum.INFO;
|
|
3791
|
+
switch (style) {
|
|
3792
|
+
case SeverityEnum.DANGER:
|
|
3793
|
+
return { header: '#b91c1c', message: '#4b5563' };
|
|
3794
|
+
case SeverityEnum.WARNING:
|
|
3795
|
+
return { header: '#b45309', message: '#92400e' };
|
|
3796
|
+
case SeverityEnum.SUCCESS:
|
|
3797
|
+
return { header: '#15803d', message: '#166534' };
|
|
3798
|
+
case SeverityEnum.INFO:
|
|
3799
|
+
default:
|
|
3800
|
+
return { header: '#2563eb', message: '#2563eb' };
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
// ───────────── Button models for pt-button ─────────────
|
|
3804
|
+
get confirmButtonModel() {
|
|
3805
|
+
const style = this.dialogConfig.dialogStyle ?? SeverityEnum.INFO;
|
|
3806
|
+
const confirmSeverity = style === SeverityEnum.DANGER
|
|
3807
|
+
? SeverityEnum.DANGER
|
|
3808
|
+
: style === SeverityEnum.WARNING
|
|
3809
|
+
? SeverityEnum.WARNING
|
|
3810
|
+
: style === SeverityEnum.SUCCESS
|
|
3811
|
+
? SeverityEnum.SUCCESS
|
|
3812
|
+
: SeverityEnum.INFO;
|
|
3813
|
+
return {
|
|
3814
|
+
label: this.dialogConfig.confirmButtonConfig?.label ?? 'Confirmer',
|
|
3815
|
+
icon: this.dialogConfig.confirmButtonConfig?.icon ?? 'pi pi-check',
|
|
3816
|
+
iconPos: 'left',
|
|
3817
|
+
type: 'button',
|
|
3818
|
+
outlined: true,
|
|
3819
|
+
severity: confirmSeverity,
|
|
3820
|
+
styleClass: (this.dialogConfig.confirmButtonConfig?.styleClass || '') +
|
|
3821
|
+
' pt-dialog-confirm-btn',
|
|
3822
|
+
width: 'auto',
|
|
3823
|
+
};
|
|
3824
|
+
}
|
|
3825
|
+
get cancelButtonModel() {
|
|
3826
|
+
return {
|
|
3827
|
+
label: this.dialogConfig.cancelButtonConfig?.label ?? 'Annuler',
|
|
3828
|
+
icon: this.dialogConfig.cancelButtonConfig?.icon ?? 'pi pi-times',
|
|
3829
|
+
iconPos: 'left',
|
|
3830
|
+
type: 'button',
|
|
3831
|
+
outlined: true,
|
|
3832
|
+
severity: SeverityEnum.INFO,
|
|
3833
|
+
styleClass: (this.dialogConfig.cancelButtonConfig?.styleClass || '') +
|
|
3834
|
+
' pt-dialog-cancel-btn',
|
|
3835
|
+
width: 'auto',
|
|
3752
3836
|
};
|
|
3753
3837
|
}
|
|
3754
3838
|
showDialog() {
|
|
3755
3839
|
this.confirmationService.confirm({
|
|
3756
|
-
header:
|
|
3840
|
+
header: '',
|
|
3841
|
+
// message is not really used visually, but kept here
|
|
3757
3842
|
message: this.getDialogContentText(),
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
acceptButtonStyleClass: this.getButtonStyle(this.dialogConfig.confirmButtonConfig, true),
|
|
3761
|
-
rejectButtonStyleClass: this.getButtonStyle(this.dialogConfig.cancelButtonConfig, false),
|
|
3762
|
-
acceptIcon: this.dialogConfig.confirmButtonConfig?.icon || 'pi pi-check',
|
|
3763
|
-
rejectIcon: this.dialogConfig.cancelButtonConfig?.icon || 'pi pi-times',
|
|
3764
|
-
accept: () => {
|
|
3765
|
-
this.confirm.emit();
|
|
3766
|
-
if (this.dialogConfig.toastOnConfirm) {
|
|
3767
|
-
}
|
|
3768
|
-
},
|
|
3769
|
-
reject: (type) => {
|
|
3770
|
-
this.cancel.emit();
|
|
3771
|
-
if (type === ConfirmEventType.REJECT &&
|
|
3772
|
-
this.dialogConfig.toastOnCancel) {
|
|
3773
|
-
}
|
|
3774
|
-
},
|
|
3843
|
+
accept: () => this.confirm.emit(),
|
|
3844
|
+
reject: (_type) => this.cancel.emit(),
|
|
3775
3845
|
});
|
|
3776
|
-
// Use renderer to apply dynamic styles
|
|
3777
3846
|
setTimeout(() => {
|
|
3778
|
-
const dialogElement =
|
|
3847
|
+
const dialogElement = document.querySelector('.p-confirm-dialog');
|
|
3779
3848
|
if (dialogElement) {
|
|
3780
|
-
this.renderer.
|
|
3849
|
+
this.renderer.addClass(dialogElement, 'pt-dialog-overlay');
|
|
3850
|
+
this.renderer.removeClass(dialogElement, 'pt-dialog-danger');
|
|
3851
|
+
this.renderer.removeClass(dialogElement, 'pt-dialog-warning');
|
|
3852
|
+
this.renderer.removeClass(dialogElement, 'pt-dialog-success');
|
|
3853
|
+
this.renderer.removeClass(dialogElement, 'pt-dialog-info');
|
|
3854
|
+
const severityClass = this.getSeverityClass();
|
|
3855
|
+
this.renderer.addClass(dialogElement, severityClass);
|
|
3856
|
+
this.renderer.setStyle(dialogElement, 'width', this.dialogConfig.width || '720px');
|
|
3781
3857
|
this.renderer.setStyle(dialogElement, 'height', this.dialogConfig.height || 'auto');
|
|
3782
3858
|
}
|
|
3783
3859
|
}, 0);
|
|
3784
3860
|
}
|
|
3785
|
-
|
|
3786
|
-
let styleClass = buttonConfig?.styleClass ?? 'p-button-sm';
|
|
3787
|
-
// ✅ Apply width dynamically if provided, otherwise default to 100%
|
|
3788
|
-
const buttonWidth = buttonConfig?.width ?? '100%';
|
|
3789
|
-
// ✅ Set default severity: SUCCESS for confirm, SECONDARY for cancel
|
|
3790
|
-
const defaultSeverity = isConfirm ? SeverityEnum.DANGER : SeverityEnum.INFO;
|
|
3791
|
-
const severity = buttonConfig?.severity ?? defaultSeverity;
|
|
3792
|
-
// ✅ Apply severity-based styles only if no custom background color is set
|
|
3793
|
-
if (!buttonConfig?.backgroundColor) {
|
|
3794
|
-
switch (severity) {
|
|
3795
|
-
case SeverityEnum.WARNING:
|
|
3796
|
-
styleClass += ' p-button-warning';
|
|
3797
|
-
break;
|
|
3798
|
-
case SeverityEnum.DANGER:
|
|
3799
|
-
styleClass += ' p-button-danger';
|
|
3800
|
-
break;
|
|
3801
|
-
case SeverityEnum.SUCCESS:
|
|
3802
|
-
styleClass += ' p-button-success';
|
|
3803
|
-
break;
|
|
3804
|
-
case SeverityEnum.INFO:
|
|
3805
|
-
default:
|
|
3806
|
-
styleClass += ' p-button-secondary';
|
|
3807
|
-
break;
|
|
3808
|
-
}
|
|
3809
|
-
}
|
|
3810
|
-
return `${styleClass.trim()} width-${buttonWidth.replace('%', '')}`;
|
|
3811
|
-
}
|
|
3861
|
+
// ── header / icon / content helpers ───────────────────────────────
|
|
3812
3862
|
getDialogHeaderText() {
|
|
3813
3863
|
const header = this.dialogConfig.header;
|
|
3814
3864
|
const dialogStyle = this.dialogConfig.dialogStyle ?? SeverityEnum.INFO;
|
|
@@ -3821,88 +3871,85 @@ class PTDialogComponent {
|
|
|
3821
3871
|
styleHeader !== null &&
|
|
3822
3872
|
'text' in styleHeader
|
|
3823
3873
|
? styleHeader.text
|
|
3824
|
-
: 'Confirmation';
|
|
3874
|
+
: 'Confirmation';
|
|
3825
3875
|
}
|
|
3826
3876
|
getDialogHeaderStyle() {
|
|
3827
3877
|
const header = this.dialogConfig.header;
|
|
3828
|
-
const
|
|
3829
|
-
const
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
color: typeof styleHeader === 'object' ? styleHeader?.color : '#333',
|
|
3838
|
-
fontSize: '25px',
|
|
3839
|
-
};
|
|
3878
|
+
const { header: color } = this.getSeverityColors();
|
|
3879
|
+
const fontSize = typeof header === 'object' && header !== null && header.fontSize
|
|
3880
|
+
? header.fontSize
|
|
3881
|
+
: '20px';
|
|
3882
|
+
return {
|
|
3883
|
+
color,
|
|
3884
|
+
fontSize,
|
|
3885
|
+
fontWeight: 700,
|
|
3886
|
+
};
|
|
3840
3887
|
}
|
|
3841
3888
|
getDialogIconClass() {
|
|
3842
3889
|
const header = this.dialogConfig.header;
|
|
3843
|
-
const dialogStyle = this.dialogConfig.dialogStyle ?? SeverityEnum.INFO;
|
|
3844
|
-
const styleHeader = DIALOG_STYLES[dialogStyle]?.header;
|
|
3845
|
-
// ✅ Ensure header.icon exists and is an object before accessing .code
|
|
3890
|
+
const dialogStyle = this.dialogConfig.dialogStyle ?? SeverityEnum.INFO;
|
|
3891
|
+
const styleHeader = DIALOG_STYLES[dialogStyle]?.header;
|
|
3846
3892
|
const icon = typeof header === 'object' && header !== null && 'icon' in header
|
|
3847
3893
|
? header.icon
|
|
3848
3894
|
: typeof styleHeader === 'object' && 'icon' in styleHeader
|
|
3849
3895
|
? styleHeader.icon
|
|
3850
3896
|
: undefined;
|
|
3851
|
-
// ✅ If `icon` is an object, extract `.code`, otherwise return as string or default value
|
|
3852
3897
|
return typeof icon === 'string'
|
|
3853
3898
|
? icon
|
|
3854
3899
|
: icon?.code || 'pi pi-exclamation-circle';
|
|
3855
3900
|
}
|
|
3856
3901
|
getDialogIconStyle() {
|
|
3857
3902
|
const header = this.dialogConfig.header;
|
|
3858
|
-
const
|
|
3859
|
-
const styleHeader = DIALOG_STYLES[dialogStyle]?.header;
|
|
3903
|
+
const { header: defaultColor } = this.getSeverityColors();
|
|
3860
3904
|
const icon = typeof header === 'object' && header !== null && 'icon' in header
|
|
3861
3905
|
? header.icon
|
|
3862
3906
|
: undefined;
|
|
3863
3907
|
return {
|
|
3864
|
-
color: icon?.color ||
|
|
3865
|
-
|
|
3866
|
-
fontSize: icon?.fontSize || '1.5rem',
|
|
3867
|
-
backgroundColor: icon?.backgroundColor || 'transparent',
|
|
3868
|
-
borderRadius: icon?.shape === 'circular' ? '50%' : '4px',
|
|
3869
|
-
padding: '5px',
|
|
3908
|
+
color: icon?.color || defaultColor,
|
|
3909
|
+
fontSize: icon?.fontSize || '2.2rem',
|
|
3870
3910
|
};
|
|
3871
3911
|
}
|
|
3912
|
+
/**
|
|
3913
|
+
* No default text anymore.
|
|
3914
|
+
* - If dialogConfig.content is a string, we return it.
|
|
3915
|
+
* - If it is an object with text, we use that.
|
|
3916
|
+
* - Otherwise we return '' (empty) so the body is blank.
|
|
3917
|
+
*/
|
|
3872
3918
|
getDialogContentText() {
|
|
3873
3919
|
const content = this.dialogConfig.content;
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
: 'Are you sure?');
|
|
3920
|
+
if (typeof content === 'string') {
|
|
3921
|
+
return content;
|
|
3922
|
+
}
|
|
3923
|
+
if (content && typeof content === 'object' && 'text' in content) {
|
|
3924
|
+
return content.text ?? '';
|
|
3925
|
+
}
|
|
3926
|
+
return '';
|
|
3882
3927
|
}
|
|
3883
3928
|
getDialogContentStyle() {
|
|
3884
3929
|
const content = this.dialogConfig.content;
|
|
3885
|
-
const
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
fontSize: content.fontSize || '20px',
|
|
3892
|
-
textAlign: content.position || 'left',
|
|
3930
|
+
const { message } = this.getSeverityColors();
|
|
3931
|
+
let fontSize = '18px';
|
|
3932
|
+
let textAlign;
|
|
3933
|
+
if (typeof content === 'object' && content !== null) {
|
|
3934
|
+
if (content.fontSize) {
|
|
3935
|
+
fontSize = content.fontSize;
|
|
3893
3936
|
}
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3937
|
+
if (content.position) {
|
|
3938
|
+
textAlign = content.position;
|
|
3939
|
+
}
|
|
3940
|
+
}
|
|
3941
|
+
return {
|
|
3942
|
+
color: message,
|
|
3943
|
+
fontSize,
|
|
3944
|
+
...(textAlign ? { textAlign } : {}),
|
|
3945
|
+
};
|
|
3899
3946
|
}
|
|
3900
3947
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTDialogComponent, deps: [{ token: i1$1.ConfirmationService }, { token: i1$1.MessageService }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3901
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTDialogComponent, selector: "pt-dialog", inputs: { dialogConfig: "dialogConfig" }, outputs: { confirm: "confirm", cancel: "cancel" }, providers: [ConfirmationService, MessageService], usesOnChanges: true, ngImport: i0, template: "<div class=\"pt-dialog\">\n <p-confirmDialog>\n
|
|
3948
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTDialogComponent, selector: "pt-dialog", inputs: { dialogConfig: "dialogConfig" }, outputs: { confirm: "confirm", cancel: "cancel" }, providers: [ConfirmationService, MessageService], usesOnChanges: true, ngImport: i0, template: "<div class=\"pt-dialog\">\n <p-confirmDialog #cd>\n <ng-template pTemplate=\"header\"></ng-template>\n\n <ng-template pTemplate=\"message\">\n <div class=\"pt-dialog-card\">\n <div class=\"pt-dialog-card-top\">\n <div class=\"pt-dialog-icon-wrapper\">\n <i\n class=\"pt-dialog-icon\"\n [class]=\"getDialogIconClass()\"\n [ngStyle]=\"getDialogIconStyle()\"\n ></i>\n </div>\n\n <div class=\"pt-dialog-text-wrapper\">\n <div class=\"pt-dialog-title\" [ngStyle]=\"getDialogHeaderStyle()\">\n {{ getDialogHeaderText() }}\n </div>\n\n <div class=\"pt-dialog-message\" [ngStyle]=\"getDialogContentStyle()\">\n {{ getDialogContentText() }}\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"pt-dialog-footer-buttons\">\n <pt-button\n *ngIf=\"dialogConfig.cancelButtonConfig\"\n [buttonConfig]=\"cancelButtonModel\"\n (click)=\"cd.reject()\"\n ></pt-button>\n\n <pt-button\n *ngIf=\"dialogConfig.confirmButtonConfig\"\n [buttonConfig]=\"confirmButtonModel\"\n (click)=\"cd.accept()\"\n ></pt-button>\n </div>\n </ng-template>\n </p-confirmDialog>\n</div>\n", styles: ["::ng-deep .p-confirm-dialog.pt-dialog-overlay{border-radius:18px;overflow:hidden;box-shadow:0 20px 45px #0f172a59}::ng-deep .p-confirm-dialog.pt-dialog-overlay .p-dialog-header{display:none!important;padding:0!important;border:0!important}::ng-deep .p-confirm-dialog.pt-dialog-overlay .p-dialog-content{padding:0;background:transparent;border-top-left-radius:18px;border-top-right-radius:18px}.pt-dialog-card{border-radius:18px 18px 0 0;overflow:hidden}.pt-dialog-card-top{padding:28px 40px;display:flex;align-items:flex-start}::ng-deep .p-confirm-dialog.pt-dialog-danger .pt-dialog-card{background-color:#fde4e4}::ng-deep .p-confirm-dialog.pt-dialog-warning .pt-dialog-card{background-color:#fff4d1}::ng-deep .p-confirm-dialog.pt-dialog-success .pt-dialog-card{background-color:#dcfce7}::ng-deep .p-confirm-dialog.pt-dialog-info .pt-dialog-card{background-color:#e0f2fe}.pt-dialog-icon-wrapper{width:60px;height:60px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin-right:18px;box-sizing:border-box}.pt-dialog-icon{font-size:30px;line-height:1;color:#b91c1c}.pt-dialog-text-wrapper{flex:1}.pt-dialog-title{font-size:22px;font-weight:700;margin-bottom:8px;color:#b91c1c}.pt-dialog-message{font-size:18px;line-height:1.5;color:#4b5563}::ng-deep .p-confirm-dialog.pt-dialog-overlay .p-dialog-footer{background:#fff;border-top:1px solid rgba(148,163,184,.25);padding:16px 32px 22px}.pt-dialog-footer-buttons{display:flex;justify-content:center;gap:16px}::ng-deep .p-confirm-dialog .p-dialog-footer .p-button{border-radius:9999px;padding:.75rem 1.8rem;font-weight:600}::ng-deep .p-confirm-dialog .p-dialog-footer .p-button i.pi{margin-right:.5rem}::ng-deep .p-confirm-dialog.pt-dialog-danger .p-dialog-footer .p-button{background:#fff!important;border-color:#dc2626!important;color:#dc2626!important}::ng-deep .p-confirm-dialog.pt-dialog-warning .p-dialog-footer .p-button{background:#fff!important;border-color:#d97706!important;color:#b45309!important}::ng-deep .p-confirm-dialog.pt-dialog-success .p-dialog-footer .p-button{background:#fff!important;border-color:#16a34a!important;color:#15803d!important}::ng-deep .p-confirm-dialog.pt-dialog-info .p-dialog-footer .p-button{background:#fff!important;border-color:#2563eb!important;color:#2563eb!important}::ng-deep .p-confirm-dialog.pt-dialog-info .p-dialog-footer .p-button:hover{background:#eff6ff!important}::ng-deep .p-confirm-dialog.pt-dialog-overlay .p-dialog-content{padding:0;background:transparent;border-top-left-radius:18px;border-top-right-radius:18px;display:block}.pt-dialog-card{border-radius:18px 18px 0 0;overflow:hidden;width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: PTButtonComponent, selector: "pt-button", inputs: ["buttonConfig"] }, { kind: "component", type: i4$2.ConfirmDialog, selector: "p-confirmDialog", 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", "visible", "position"], outputs: ["onHide"] }] }); }
|
|
3902
3949
|
}
|
|
3903
3950
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTDialogComponent, decorators: [{
|
|
3904
3951
|
type: Component,
|
|
3905
|
-
args: [{ selector: 'pt-dialog', providers: [ConfirmationService, MessageService], template: "<div class=\"pt-dialog\">\n <p-confirmDialog>\n
|
|
3952
|
+
args: [{ selector: 'pt-dialog', providers: [ConfirmationService, MessageService], template: "<div class=\"pt-dialog\">\n <p-confirmDialog #cd>\n <ng-template pTemplate=\"header\"></ng-template>\n\n <ng-template pTemplate=\"message\">\n <div class=\"pt-dialog-card\">\n <div class=\"pt-dialog-card-top\">\n <div class=\"pt-dialog-icon-wrapper\">\n <i\n class=\"pt-dialog-icon\"\n [class]=\"getDialogIconClass()\"\n [ngStyle]=\"getDialogIconStyle()\"\n ></i>\n </div>\n\n <div class=\"pt-dialog-text-wrapper\">\n <div class=\"pt-dialog-title\" [ngStyle]=\"getDialogHeaderStyle()\">\n {{ getDialogHeaderText() }}\n </div>\n\n <div class=\"pt-dialog-message\" [ngStyle]=\"getDialogContentStyle()\">\n {{ getDialogContentText() }}\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"pt-dialog-footer-buttons\">\n <pt-button\n *ngIf=\"dialogConfig.cancelButtonConfig\"\n [buttonConfig]=\"cancelButtonModel\"\n (click)=\"cd.reject()\"\n ></pt-button>\n\n <pt-button\n *ngIf=\"dialogConfig.confirmButtonConfig\"\n [buttonConfig]=\"confirmButtonModel\"\n (click)=\"cd.accept()\"\n ></pt-button>\n </div>\n </ng-template>\n </p-confirmDialog>\n</div>\n", styles: ["::ng-deep .p-confirm-dialog.pt-dialog-overlay{border-radius:18px;overflow:hidden;box-shadow:0 20px 45px #0f172a59}::ng-deep .p-confirm-dialog.pt-dialog-overlay .p-dialog-header{display:none!important;padding:0!important;border:0!important}::ng-deep .p-confirm-dialog.pt-dialog-overlay .p-dialog-content{padding:0;background:transparent;border-top-left-radius:18px;border-top-right-radius:18px}.pt-dialog-card{border-radius:18px 18px 0 0;overflow:hidden}.pt-dialog-card-top{padding:28px 40px;display:flex;align-items:flex-start}::ng-deep .p-confirm-dialog.pt-dialog-danger .pt-dialog-card{background-color:#fde4e4}::ng-deep .p-confirm-dialog.pt-dialog-warning .pt-dialog-card{background-color:#fff4d1}::ng-deep .p-confirm-dialog.pt-dialog-success .pt-dialog-card{background-color:#dcfce7}::ng-deep .p-confirm-dialog.pt-dialog-info .pt-dialog-card{background-color:#e0f2fe}.pt-dialog-icon-wrapper{width:60px;height:60px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin-right:18px;box-sizing:border-box}.pt-dialog-icon{font-size:30px;line-height:1;color:#b91c1c}.pt-dialog-text-wrapper{flex:1}.pt-dialog-title{font-size:22px;font-weight:700;margin-bottom:8px;color:#b91c1c}.pt-dialog-message{font-size:18px;line-height:1.5;color:#4b5563}::ng-deep .p-confirm-dialog.pt-dialog-overlay .p-dialog-footer{background:#fff;border-top:1px solid rgba(148,163,184,.25);padding:16px 32px 22px}.pt-dialog-footer-buttons{display:flex;justify-content:center;gap:16px}::ng-deep .p-confirm-dialog .p-dialog-footer .p-button{border-radius:9999px;padding:.75rem 1.8rem;font-weight:600}::ng-deep .p-confirm-dialog .p-dialog-footer .p-button i.pi{margin-right:.5rem}::ng-deep .p-confirm-dialog.pt-dialog-danger .p-dialog-footer .p-button{background:#fff!important;border-color:#dc2626!important;color:#dc2626!important}::ng-deep .p-confirm-dialog.pt-dialog-warning .p-dialog-footer .p-button{background:#fff!important;border-color:#d97706!important;color:#b45309!important}::ng-deep .p-confirm-dialog.pt-dialog-success .p-dialog-footer .p-button{background:#fff!important;border-color:#16a34a!important;color:#15803d!important}::ng-deep .p-confirm-dialog.pt-dialog-info .p-dialog-footer .p-button{background:#fff!important;border-color:#2563eb!important;color:#2563eb!important}::ng-deep .p-confirm-dialog.pt-dialog-info .p-dialog-footer .p-button:hover{background:#eff6ff!important}::ng-deep .p-confirm-dialog.pt-dialog-overlay .p-dialog-content{padding:0;background:transparent;border-top-left-radius:18px;border-top-right-radius:18px;display:block}.pt-dialog-card{border-radius:18px 18px 0 0;overflow:hidden;width:100%}\n"] }]
|
|
3906
3953
|
}], ctorParameters: () => [{ type: i1$1.ConfirmationService }, { type: i1$1.MessageService }, { type: i0.Renderer2 }, { type: i0.ElementRef }], propDecorators: { dialogConfig: [{
|
|
3907
3954
|
type: Input
|
|
3908
3955
|
}], confirm: [{
|