ng-prime-tools 1.0.73 → 1.0.75

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.
@@ -3,7 +3,7 @@ import { Pipe, EventEmitter, ViewChild, Output, Input, Component, NgModule, Inje
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i2 from '@angular/forms';
6
- import { FormControl, Validators, ReactiveFormsModule, FormsModule, FormGroup } from '@angular/forms';
6
+ import { FormGroup, FormControl, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
7
7
  import * as i3 from 'primeng/table';
8
8
  import { TableModule } from 'primeng/table';
9
9
  import * as i1$1 from 'primeng/api';
@@ -41,6 +41,8 @@ import * as i3$3 from 'primeng/toggleswitch';
41
41
  import { ToggleSwitchModule } from 'primeng/toggleswitch';
42
42
  import * as i3$4 from 'primeng/textarea';
43
43
  import { TextareaModule } from 'primeng/textarea';
44
+ import * as i6$1 from 'primeng/password';
45
+ import { PasswordModule } from 'primeng/password';
44
46
  import * as i3$5 from 'primeng/select';
45
47
  import { SelectModule } from 'primeng/select';
46
48
  import { Chart, registerables } from 'chart.js';
@@ -1125,11 +1127,11 @@ class PTAdvancedPrimeTableComponent {
1125
1127
  return [value];
1126
1128
  }
1127
1129
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTAdvancedPrimeTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1128
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTAdvancedPrimeTableComponent, isStandalone: false, selector: "pt-advanced-prime-table", inputs: { data: "data", columns: "columns", totalRecords: "totalRecords", rowsPerPage: "rowsPerPage", hasSearchFilter: "hasSearchFilter", hasExportExcel: "hasExportExcel", hasExportPDF: "hasExportPDF", hasColumnFilter: "hasColumnFilter", isPaginated: "isPaginated", isLazy: "isLazy", actions: "actions", isSortable: "isSortable", loading: "loading", maxHeight: "maxHeight", isRowReorderable: "isRowReorderable", rowReorderIdField: "rowReorderIdField", rowOrderStartAt: "rowOrderStartAt", selectionDataKey: "selectionDataKey", selectionMode: "selectionMode", selection: "selection" }, outputs: { selectionChange: "selectionChange", rowSelect: "rowSelect", rowUnselect: "rowUnselect", lazyLoad: "lazyLoad", search: "search", exportExcelEvent: "exportExcelEvent", exportPdfEvent: "exportPdfEvent", onPageChange: "onPageChange", onSortColumn: "onSortColumn", onFilterColumn: "onFilterColumn", rowReorderChange: "rowReorderChange" }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }], usesOnChanges: 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]=\"isLazy\"\n [filterDelay]=\"0\"\n [dataKey]=\"selectionDataKey || rowReorderIdField || 'id'\"\n styleClass=\"p-datatable-gridlines p-datatable-striped\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onRowReorder)=\"onRowReorder($event)\"\n (onPage)=\"changePage($event)\"\n (onSort)=\"sortColumn($event)\"\n (onFilter)=\"filterColumn($event)\"\n [selectionMode]=\"selectionMode\"\n [(selection)]=\"selection\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (onRowSelect)=\"rowSelect.emit($event.data)\"\n (onRowUnselect)=\"rowUnselect.emit($event.data)\"\n >\n <ng-template pTemplate=\"colgroup\" let-columns>\n <colgroup>\n @if (canUseRowReorder()) {\n <col style=\"width: 3rem\" />\n }\n @for (col of columns; track col) {\n <col\n [style.width]=\"col.width || getHeaderWidth(col)\"\n />\n }\n </colgroup>\n </ng-template>\n\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n @if (hasSearchFilter) {\n <button\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\n @if (hasExportExcel) {\n <button\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\n @if (hasExportPDF) {\n <button\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 }\n </div>\n\n @if (hasSearchFilter) {\n <div class=\"ml-auto\">\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 }\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n @if (canUseRowReorder()) {\n <th style=\"width: 3rem\"></th>\n }\n\n @for (col of columns; track col) {\n @if (!col.children) {\n <th\n [pSortableColumn]=\"col.code\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [ngClass]=\"[\n getHeaderAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : '',\n ]\"\n colspan=\"1\"\n >\n @if (isSortable && col.isSortable !== false) {\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon [field]=\"col.code\" />\n @if (hasColumnFilter && col.isFilter !== false) {\n @if (col.type === TableTypeEnum.COMPOSED) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n type=\"text\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"false\"\n [showOperator]=\"false\"\n (onClear)=\"onComposedColumnClear(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n >\n @for (composedName of col.composedNames; track composedName) {\n <div>\n @if (\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n ) {\n <p-multiSelect\n [options]=\"filters[composedName]?.options\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"filters[composedName]?.value ?? []\"\n (ngModelChange)=\"\n onComposedFilterValueChange(\n col,\n composedName,\n $event\n );\n filter($event ?? [])\n \"\n [placeholder]=\"filters[composedName]?.placeholder\"\n display=\"chip\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n @if (item.image) {\n <img\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n }\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n }\n </div>\n }\n </ng-template>\n </p-columnFilter>\n }\n @if (col.type !== TableTypeEnum.COMPOSED) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"col.type !== TableTypeEnum.MULTISELECT\"\n [showOperator]=\"col.type !== TableTypeEnum.MULTISELECT\"\n [matchMode]=\"\n col.type === TableTypeEnum.MULTISELECT\n ? 'in'\n : undefined\n \"\n (onClear)=\"onFilterClear(col.code!)\"\n >\n @if (\n col.type === TableTypeEnum.NUMBER ||\n col.type === TableTypeEnum.AMOUNT\n ; as value) {\n <ng-template\n pTemplate=\"filter\"\n let-value\n >\n <input\n pInputText\n type=\"text\"\n inputmode=\"decimal\"\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onNumberFilterChange(col.code!, $event)\n \"\n placeholder=\"Enter a number\"\n />\n </ng-template>\n }\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n let-filter=\"filterCallback\"\n let-value\n >\n <p-datepicker\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event)\n \"\n dateFormat=\"dd/mm/yy\"\n placeholder=\"Choose a date\"\n ></p-datepicker>\n </ng-template>\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"\n col.type === TableTypeEnum.MULTISELECT &&\n col.filterOptions &&\n col.filterOptions.length > 0\n \"\n let-filter=\"filterCallback\"\n let-value\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? value ?? []\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event ?? [])\n \"\n display=\"chip\"\n placeholder=\"Choose option\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n }\n }\n </div>\n </div>\n } @else {\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n @if (hasColumnFilter && col.isFilter !== false) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"\n getColumnFilterType(col) !== 'multiSelect'\n \"\n [showOperator]=\"getColumnFilterType(col) !== 'multiSelect'\"\n [matchMode]=\"\n getColumnFilterType(col) === 'multiSelect'\n ? 'in'\n : undefined\n \"\n (onClear)=\"onFilterClear(col.code!)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n let-value\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-datepicker\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event)\n \"\n dateFormat=\"dd/mm/yy\"\n ></p-datepicker>\n </ng-template>\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n let-value\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"latestFilterValues[col.code!] ?? value ?? []\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event ?? [])\n \"\n display=\"chip\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n }\n </div>\n }\n </th>\n } @else {\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getHeaderAlignClass(col)\"\n >\n <span>{{ col.title }}</span>\n </th>\n }\n }\n </tr>\n\n @if (hasGroupedColumns) {\n <tr>\n @if (canUseRowReorder()) {\n <th style=\"width: 3rem\"></th>\n }\n @for (col of columns; track col) {\n @if (col.children) {\n @for (child of col.children; track child) {\n <th\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n ></th>\n }\n }\n }\n </tr>\n }\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <tr class=\"p-datatable-emptymessage\">\n <td\n class=\"empty-message-cell\"\n [attr.colspan]=\"columns.length + (canUseRowReorder() ? 1 : 0)\"\n >\n <div class=\"empty-message-wrapper\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </div>\n </td>\n </tr>\n </ng-template>\n\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n @if (!loading) {\n <tr\n [pEditableRow]=\"isEdit ? data : null\"\n [pReorderableRow]=\"canUseRowReorder() ? ri : null\"\n [pSelectableRow]=\"selectionMode ? data : null\"\n >\n @if (canUseRowReorder()) {\n <td style=\"width: 3rem; text-align: center\">\n <span\n pReorderableRowHandle\n style=\"cursor: move; display: inline-flex; align-items: center\"\n title=\"D\u00E9placer la ligne\"\n >\n <i class=\"pi pi-bars\"></i>\n </span>\n </td>\n }\n @for (col of columns; track col) {\n @if (!col.children) {\n @if (\n isEditable(col.code!) && col.type !== TableTypeEnum.ACTION) {\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getDataAlignClass(col)\"\n [ngStyle]=\"getCellStyle(col, data)\"\n >\n <div [ngClass]=\"getCellInnerAlignClass(col)\">\n @if (isMultiSelect(col.code)) {\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 @for (\n rec of getMultiSelectValues(data[col.code!])\n ; track\n rec) {\n <p-tag [value]=\"rec\"></p-tag>\n }\n </div>\n </ng-template>\n </p-cellEditor>\n } @else {\n @if (isDatePicker(col.code)) {\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-datepicker\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-datepicker>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code!] | customDate }}\n </ng-template>\n </p-cellEditor>\n } @else {\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 @if (\n 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 } @else {\n {{ data[col.code!] }}\n }\n </ng-template>\n </p-cellEditor>\n }\n }\n </div>\n </td>\n } @else {\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"[\n getDataAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : '',\n ]\"\n [ngStyle]=\"getCellStyle(col, data)\"\n >\n @if (col.type === TableTypeEnum.ACTION) {\n <div class=\"action-buttons-container\">\n @if (isDelete) {\n <button\n pButton\n pRipple\n pTooltip=\"Supprimer\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (isEdit) {\n <div>\n @if (!editing) {\n <button\n pInitEditableRow\n pButton\n pRipple\n pTooltip=\"Modifier\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (editing) {\n <button\n pSaveEditableRow\n pButton\n pRipple\n pTooltip=\"Enregistrer\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (editing) {\n <button\n pCancelEditableRow\n pButton\n pRipple\n pTooltip=\"Annuler\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n </div>\n }\n @for (act of customActions; track act) {\n @if (isActionVisible(act, data)) {\n <button\n pButton\n pRipple\n [pTooltip]=\"act.tooltip || ''\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n class=\"p-button-rounded p-button-text\"\n [icon]=\"act.icon || 'pi pi-ellipsis-h'\"\n [ngClass]=\"act.styleClass\"\n [disabled]=\"isActionDisabled(act, data)\"\n (click)=\"onCustomActionClick(act, data)\"\n ></button>\n }\n }\n </div>\n } @else {\n <div [ngClass]=\"getCellInnerAlignClass(col)\">\n @if (\n col.type === TableTypeEnum.COMPOSED) {\n <div class=\"composed-cell\">\n @for (\n composedName of col.composedNames; track\n composedName; let i = $index) {\n @if (\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n ) {\n <img\n [src]=\"data[col.code!]?.[composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"\n getMergedComposedImageStyle(\n col,\n composedName,\n data\n )\n \"\n />\n }\n @if (\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n ) {\n <span\n class=\"composed-text\"\n [ngStyle]=\"\n getMergedComposedTextStyle(\n col,\n composedName,\n data\n )\n \"\n >\n {{ data[col.code!]?.[composedName] }}\n </span>\n }\n }\n </div>\n } @else {\n @if (\n col.type === TableTypeEnum.PROGRESS) {\n <div class=\"progress-cell\">\n <p-progressBar\n [value]=\"getProgressValue(col, data)\"\n [showValue]=\"false\"\n [ngClass]=\"\n 'pt-progress-' + getProgressSeverity(col, data)\n \"\n ></p-progressBar>\n @if (isProgressShowValue(col)) {\n <span\n class=\"progress-cell-value\"\n >\n {{ getProgressValue(col, data)\n }}{{ getProgressUnit(col) }}\n </span>\n }\n </div>\n } @else {\n @if (col.type === TableTypeEnum.TAG) {\n <p-tag\n [value]=\"getTagValue(col, data)\"\n [severity]=\"$any(getTagSeverity(col, data))\"\n [icon]=\"getTagIcon(col, data)\"\n [rounded]=\"isTagRounded(col)\"\n ></p-tag>\n } @else {\n @if (\n 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 } @else {\n @if (\n col.type === TableTypeEnum.NUMBER) {\n {{\n formatNumber(\n data[col.code!],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n } @else {\n @if (\n col.type === TableTypeEnum.DATE ||\n col.type === TableTypeEnum.DATETIME) {\n @if (col.type === TableTypeEnum.DATE) {\n {{\n formatDateWithColumn(\n parseAnyDate(data[col.code!]),\n col\n )\n }}\n }\n @if (col.type === TableTypeEnum.DATETIME) {\n {{\n formatDateTimeWithColumn(\n parseAnyDate(data[col.code!]),\n col\n )\n }}\n }\n } @else {\n @if (\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT,\n ].includes(col.type!)\n ) {\n {{ data[col.code!] }}\n }\n }\n }\n }\n }\n }\n }\n </div>\n }\n </td>\n }\n } @else {\n @for (child of col.children; track child) {\n <td\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [ngClass]=\"getDataAlignClass(child)\"\n [ngStyle]=\"getCellStyle(child, data)\"\n >\n <div [ngClass]=\"getCellInnerAlignClass(child)\">\n @if (isEditable(child.code)) {\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"child.code ? data[child.code] : null\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </p-cellEditor>\n } @else {\n @if (\n child.type === TableTypeEnum.TAG) {\n <p-tag\n [value]=\"getTagValue(child, data)\"\n [severity]=\"$any(getTagSeverity(child, data))\"\n [icon]=\"getTagIcon(child, data)\"\n [rounded]=\"isTagRounded(child)\"\n ></p-tag>\n } @else {\n {{ child.code ? data[child.code] : \"\" }}\n }\n }\n </div>\n </td>\n }\n }\n }\n </tr>\n }\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;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 .header-title-left,.pt-advanced-prime-table ::ng-deep .header-title-center,.pt-advanced-prime-table ::ng-deep .header-title-right{flex:1}.pt-advanced-prime-table ::ng-deep .header-title-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-title-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-title-right{text-align:right}.pt-advanced-prime-table ::ng-deep .header-align-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-align-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-align-right{text-align:right}.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:block;width:100%}.pt-advanced-prime-table ::ng-deep .p-datatable-emptymessage>td.empty-message-cell{padding:0!important}.pt-advanced-prime-table .empty-message-wrapper{width:100%;height:100%;min-height:180px;display:flex;align-items:center;justify-content:center}.pt-advanced-prime-table .empty-message{text-align:center;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}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-left{text-align:left!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-center{text-align:center!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-right{text-align:right!important}.pt-advanced-prime-table .cell-inner-left,.pt-advanced-prime-table .cell-inner-center,.pt-advanced-prime-table .cell-inner-right{width:100%;display:flex;align-items:center}.pt-advanced-prime-table .cell-inner-left{justify-content:flex-start;text-align:left}.pt-advanced-prime-table .cell-inner-center{justify-content:center;text-align:center}.pt-advanced-prime-table .cell-inner-right{justify-content:flex-end;text-align:right}.pt-advanced-prime-table ::ng-deep .p-tag{font-size:.72rem;font-weight:800;padding:.2rem .55rem;line-height:1.2;white-space:nowrap}.pt-advanced-prime-table ::ng-deep .p-tag .p-tag-icon{margin-right:.25rem}.pt-advanced-prime-table .progress-cell{width:100%;min-width:160px;display:flex;align-items:center;gap:.5rem}.pt-advanced-prime-table ::ng-deep .progress-cell .p-progressbar{flex:1;width:100%;min-width:120px;height:.75rem!important;background:#e5e7eb!important;border-radius:999px;overflow:hidden}.pt-advanced-prime-table ::ng-deep .progress-cell .p-progressbar-value{display:block!important;height:100%!important;border-radius:999px}.pt-advanced-prime-table .progress-cell-value{min-width:38px;font-size:.72rem;font-weight:800;color:#334155;text-align:right}.pt-advanced-prime-table ::ng-deep th.action-column,.pt-advanced-prime-table ::ng-deep td.action-column{text-align:center!important;justify-content:center;align-items:center;overflow:hidden;white-space:nowrap;padding:0}.pt-advanced-prime-table ::ng-deep .action-buttons-container{width:100%;display:flex;justify-content:center!important;align-items:center!important;gap:.35rem}.pt-advanced-prime-table ::ng-deep .action-buttons-container .p-button.p-button-rounded.p-button-text{padding:.25rem!important;min-width:22px!important;height:22px!important}.pt-advanced-prime-table ::ng-deep .pt-progress-success .p-progressbar-value{background:#22c55e!important}.pt-advanced-prime-table ::ng-deep .pt-progress-warning .p-progressbar-value{background:#f59e0b!important}.pt-advanced-prime-table ::ng-deep .pt-progress-danger .p-progressbar-value{background:#ef4444!important}.pt-advanced-prime-table ::ng-deep .pt-progress-info .p-progressbar-value{background:#3b82f6!important}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i3.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i3.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "component", type: i3.CellEditor, selector: "p-cellEditor" }, { kind: "component", type: i3.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "directive", type: i3.ReorderableRowHandle, selector: "[pReorderableRowHandle]" }, { kind: "directive", type: i3.ReorderableRow, selector: "[pReorderableRow]", inputs: ["pReorderableRow", "pReorderableRowDisabled"] }, { kind: "directive", type: i3.EditableRow, selector: "[pEditableRow]", inputs: ["pEditableRow", "pEditableRowDisabled"] }, { kind: "directive", type: i3.InitEditableRow, selector: "[pInitEditableRow]" }, { kind: "directive", type: i3.SaveEditableRow, selector: "[pSaveEditableRow]" }, { kind: "directive", type: i3.CancelEditableRow, selector: "[pCancelEditableRow]" }, { kind: "component", type: i3.ColumnFilter, selector: "p-columnFilter, p-column-filter, 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", "filterOn", "useGrouping", "showButtons", "ariaLabel", "filterButtonProps", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i7.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "component", type: i8.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "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", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "component", type: i9.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: i10.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "component", type: i11.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "directive", type: i12.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i13.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "unit", "mode", "color"] }, { kind: "pipe", type: CustomCurrencyPipe, name: "customCurrency" }, { kind: "pipe", type: CustomDatePipe, name: "customDate" }] }); }
1130
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTAdvancedPrimeTableComponent, isStandalone: false, selector: "pt-advanced-prime-table", inputs: { data: "data", columns: "columns", totalRecords: "totalRecords", rowsPerPage: "rowsPerPage", hasSearchFilter: "hasSearchFilter", hasExportExcel: "hasExportExcel", hasExportPDF: "hasExportPDF", hasColumnFilter: "hasColumnFilter", isPaginated: "isPaginated", isLazy: "isLazy", actions: "actions", isSortable: "isSortable", loading: "loading", maxHeight: "maxHeight", isRowReorderable: "isRowReorderable", rowReorderIdField: "rowReorderIdField", rowOrderStartAt: "rowOrderStartAt", selectionDataKey: "selectionDataKey", selectionMode: "selectionMode", selection: "selection" }, outputs: { selectionChange: "selectionChange", rowSelect: "rowSelect", rowUnselect: "rowUnselect", lazyLoad: "lazyLoad", search: "search", exportExcelEvent: "exportExcelEvent", exportPdfEvent: "exportPdfEvent", onPageChange: "onPageChange", onSortColumn: "onSortColumn", onFilterColumn: "onFilterColumn", rowReorderChange: "rowReorderChange" }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }], usesOnChanges: 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]=\"isLazy\"\n [filterDelay]=\"0\"\n [dataKey]=\"selectionDataKey || rowReorderIdField || 'id'\"\n styleClass=\"p-datatable-gridlines p-datatable-striped\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onRowReorder)=\"onRowReorder($event)\"\n (onPage)=\"changePage($event)\"\n (onSort)=\"sortColumn($event)\"\n (onFilter)=\"filterColumn($event)\"\n [selectionMode]=\"selectionMode\"\n [(selection)]=\"selection\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (onRowSelect)=\"rowSelect.emit($event.data)\"\n (onRowUnselect)=\"rowUnselect.emit($event.data)\"\n >\n <ng-template pTemplate=\"colgroup\" let-columns>\n <colgroup>\n @if (canUseRowReorder()) {\n <col style=\"width: 3rem\" />\n }\n @for (col of columns; track col) {\n <col\n [style.width]=\"col.width || getHeaderWidth(col)\"\n />\n }\n </colgroup>\n </ng-template>\n\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n @if (hasSearchFilter) {\n <button\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\n @if (hasExportExcel) {\n <button\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\n @if (hasExportPDF) {\n <button\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 }\n </div>\n\n @if (hasSearchFilter) {\n <div class=\"ml-auto\">\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 }\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n @if (canUseRowReorder()) {\n <th style=\"width: 3rem\"></th>\n }\n\n @for (col of columns; track col) {\n @if (!col.children) {\n <th\n [pSortableColumn]=\"col.code\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [ngClass]=\"[\n getHeaderAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : '',\n ]\"\n colspan=\"1\"\n >\n @if (isSortable && col.isSortable !== false) {\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon [field]=\"col.code\" />\n @if (hasColumnFilter && col.isFilter !== false) {\n @if (col.type === TableTypeEnum.COMPOSED) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n type=\"text\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"false\"\n [showOperator]=\"false\"\n (onClear)=\"onComposedColumnClear(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n >\n @for (composedName of col.composedNames; track composedName) {\n <div>\n @if (\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n ) {\n <p-multiSelect\n [options]=\"filters[composedName]?.options\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"filters[composedName]?.value ?? []\"\n (ngModelChange)=\"\n onComposedFilterValueChange(\n col,\n composedName,\n $event\n );\n filter($event ?? [])\n \"\n [placeholder]=\"filters[composedName]?.placeholder\"\n display=\"chip\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n @if (item.image) {\n <img\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n }\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n }\n </div>\n }\n </ng-template>\n </p-columnFilter>\n }\n @if (col.type !== TableTypeEnum.COMPOSED) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"col.type !== TableTypeEnum.MULTISELECT\"\n [showOperator]=\"col.type !== TableTypeEnum.MULTISELECT\"\n [matchMode]=\"\n col.type === TableTypeEnum.MULTISELECT\n ? 'in'\n : undefined\n \"\n (onClear)=\"onFilterClear(col.code!)\"\n >\n @if (\n col.type === TableTypeEnum.NUMBER ||\n col.type === TableTypeEnum.AMOUNT\n ; as value) {\n <ng-template\n pTemplate=\"filter\"\n let-value\n >\n <input\n pInputText\n type=\"text\"\n inputmode=\"decimal\"\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onNumberFilterChange(col.code!, $event)\n \"\n placeholder=\"Enter a number\"\n />\n </ng-template>\n }\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n let-filter=\"filterCallback\"\n let-value\n >\n <p-datepicker\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event)\n \"\n dateFormat=\"dd/mm/yy\"\n placeholder=\"Choose a date\"\n ></p-datepicker>\n </ng-template>\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"\n col.type === TableTypeEnum.MULTISELECT &&\n col.filterOptions &&\n col.filterOptions.length > 0\n \"\n let-filter=\"filterCallback\"\n let-value\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? value ?? []\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event ?? [])\n \"\n display=\"chip\"\n placeholder=\"Choose option\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n }\n }\n </div>\n </div>\n } @else {\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n @if (hasColumnFilter && col.isFilter !== false) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"\n getColumnFilterType(col) !== 'multiSelect'\n \"\n [showOperator]=\"getColumnFilterType(col) !== 'multiSelect'\"\n [matchMode]=\"\n getColumnFilterType(col) === 'multiSelect'\n ? 'in'\n : undefined\n \"\n (onClear)=\"onFilterClear(col.code!)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n let-value\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-datepicker\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event)\n \"\n dateFormat=\"dd/mm/yy\"\n ></p-datepicker>\n </ng-template>\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n let-value\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"latestFilterValues[col.code!] ?? value ?? []\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event ?? [])\n \"\n display=\"chip\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n }\n </div>\n }\n </th>\n } @else {\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getHeaderAlignClass(col)\"\n >\n <span>{{ col.title }}</span>\n </th>\n }\n }\n </tr>\n\n @if (hasGroupedColumns) {\n <tr>\n @if (canUseRowReorder()) {\n <th style=\"width: 3rem\"></th>\n }\n @for (col of columns; track col) {\n @if (col.children) {\n @for (child of col.children; track child) {\n <th\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n ></th>\n }\n }\n }\n </tr>\n }\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <tr class=\"p-datatable-emptymessage\">\n <td\n class=\"empty-message-cell\"\n [attr.colspan]=\"columns.length + (canUseRowReorder() ? 1 : 0)\"\n >\n <div class=\"empty-message-wrapper\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </div>\n </td>\n </tr>\n </ng-template>\n\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n @if (!loading) {\n <tr\n [pEditableRow]=\"isEdit ? data : null\"\n [pReorderableRow]=\"canUseRowReorder() ? ri : null\"\n [pSelectableRow]=\"selectionMode ? data : null\"\n >\n @if (canUseRowReorder()) {\n <td style=\"width: 3rem; text-align: center\">\n <span\n pReorderableRowHandle\n style=\"cursor: move; display: inline-flex; align-items: center\"\n title=\"D\u00E9placer la ligne\"\n >\n <i class=\"pi pi-bars\"></i>\n </span>\n </td>\n }\n @for (col of columns; track col) {\n @if (!col.children) {\n @if (\n isEditable(col.code!) && col.type !== TableTypeEnum.ACTION) {\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getDataAlignClass(col)\"\n [ngStyle]=\"getCellStyle(col, data)\"\n >\n <div [ngClass]=\"getCellInnerAlignClass(col)\">\n @if (isMultiSelect(col.code)) {\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 @for (\n rec of getMultiSelectValues(data[col.code!])\n ; track\n rec) {\n <p-tag [value]=\"rec\"></p-tag>\n }\n </div>\n </ng-template>\n </p-cellEditor>\n } @else {\n @if (isDatePicker(col.code)) {\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-datepicker\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-datepicker>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code!] | customDate }}\n </ng-template>\n </p-cellEditor>\n } @else {\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 @if (\n 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 } @else {\n {{ data[col.code!] }}\n }\n </ng-template>\n </p-cellEditor>\n }\n }\n </div>\n </td>\n } @else {\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"[\n getDataAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : '',\n ]\"\n [ngStyle]=\"getCellStyle(col, data)\"\n >\n @if (col.type === TableTypeEnum.ACTION) {\n <div class=\"action-buttons-container\">\n @if (isDelete) {\n <button\n pButton\n pRipple\n pTooltip=\"Supprimer\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (isEdit) {\n <div>\n @if (!editing) {\n <button\n pInitEditableRow\n pButton\n pRipple\n pTooltip=\"Modifier\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (editing) {\n <button\n pSaveEditableRow\n pButton\n pRipple\n pTooltip=\"Enregistrer\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (editing) {\n <button\n pCancelEditableRow\n pButton\n pRipple\n pTooltip=\"Annuler\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n </div>\n }\n @for (act of customActions; track act) {\n @if (isActionVisible(act, data)) {\n <button\n pButton\n pRipple\n [pTooltip]=\"act.tooltip || ''\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n class=\"p-button-rounded p-button-text\"\n [icon]=\"act.icon || 'pi pi-ellipsis-h'\"\n [ngClass]=\"act.styleClass\"\n [disabled]=\"isActionDisabled(act, data)\"\n (click)=\"onCustomActionClick(act, data)\"\n ></button>\n }\n }\n </div>\n } @else {\n <div [ngClass]=\"getCellInnerAlignClass(col)\">\n @if (\n col.type === TableTypeEnum.COMPOSED) {\n <div class=\"composed-cell\">\n @for (\n composedName of col.composedNames; track\n composedName; let i = $index) {\n @if (\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n ) {\n <img\n [src]=\"data[col.code!]?.[composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"\n getMergedComposedImageStyle(\n col,\n composedName,\n data\n )\n \"\n />\n }\n @if (\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n ) {\n <span\n class=\"composed-text\"\n [ngStyle]=\"\n getMergedComposedTextStyle(\n col,\n composedName,\n data\n )\n \"\n >\n {{ data[col.code!]?.[composedName] }}\n </span>\n }\n }\n </div>\n } @else {\n @if (\n col.type === TableTypeEnum.PROGRESS) {\n <div class=\"progress-cell\">\n <p-progressBar\n [value]=\"getProgressValue(col, data)\"\n [showValue]=\"false\"\n [ngClass]=\"\n 'pt-progress-' + getProgressSeverity(col, data)\n \"\n ></p-progressBar>\n @if (isProgressShowValue(col)) {\n <span\n class=\"progress-cell-value\"\n >\n {{ getProgressValue(col, data)\n }}{{ getProgressUnit(col) }}\n </span>\n }\n </div>\n } @else {\n @if (col.type === TableTypeEnum.TAG) {\n <p-tag\n [value]=\"getTagValue(col, data)\"\n [severity]=\"$any(getTagSeverity(col, data))\"\n [icon]=\"getTagIcon(col, data)\"\n [rounded]=\"isTagRounded(col)\"\n ></p-tag>\n } @else {\n @if (\n 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 } @else {\n @if (\n col.type === TableTypeEnum.NUMBER) {\n {{\n formatNumber(\n data[col.code!],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n } @else {\n @if (\n col.type === TableTypeEnum.DATE ||\n col.type === TableTypeEnum.DATETIME) {\n @if (col.type === TableTypeEnum.DATE) {\n {{\n formatDateWithColumn(\n parseAnyDate(data[col.code!]),\n col\n )\n }}\n }\n @if (col.type === TableTypeEnum.DATETIME) {\n {{\n formatDateTimeWithColumn(\n parseAnyDate(data[col.code!]),\n col\n )\n }}\n }\n } @else {\n @if (\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT,\n ].includes(col.type!)\n ) {\n {{ data[col.code!] }}\n }\n }\n }\n }\n }\n }\n }\n </div>\n }\n </td>\n }\n } @else {\n @for (child of col.children; track child) {\n <td\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [ngClass]=\"getDataAlignClass(child)\"\n [ngStyle]=\"getCellStyle(child, data)\"\n >\n <div [ngClass]=\"getCellInnerAlignClass(child)\">\n @if (isEditable(child.code)) {\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"child.code ? data[child.code] : null\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </p-cellEditor>\n } @else {\n @if (\n child.type === TableTypeEnum.TAG) {\n <p-tag\n [value]=\"getTagValue(child, data)\"\n [severity]=\"$any(getTagSeverity(child, data))\"\n [icon]=\"getTagIcon(child, data)\"\n [rounded]=\"isTagRounded(child)\"\n ></p-tag>\n } @else {\n {{ child.code ? data[child.code] : \"\" }}\n }\n }\n </div>\n </td>\n }\n }\n }\n </tr>\n }\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;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 .header-title-left,.pt-advanced-prime-table ::ng-deep .header-title-center,.pt-advanced-prime-table ::ng-deep .header-title-right{flex:1}.pt-advanced-prime-table ::ng-deep .header-title-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-title-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-title-right{text-align:right}.pt-advanced-prime-table ::ng-deep .header-align-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-align-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-align-right{text-align:right}.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:-.8rem;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:block;width:100%}.pt-advanced-prime-table ::ng-deep .p-datatable-emptymessage>td.empty-message-cell{padding:0!important}.pt-advanced-prime-table .empty-message-wrapper{width:100%;height:100%;min-height:180px;display:flex;align-items:center;justify-content:center}.pt-advanced-prime-table .empty-message{text-align:center;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}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-left{text-align:left!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-center{text-align:center!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-right{text-align:right!important}.pt-advanced-prime-table .cell-inner-left,.pt-advanced-prime-table .cell-inner-center,.pt-advanced-prime-table .cell-inner-right{width:100%;display:flex;align-items:center}.pt-advanced-prime-table .cell-inner-left{justify-content:flex-start;text-align:left}.pt-advanced-prime-table .cell-inner-center{justify-content:center;text-align:center}.pt-advanced-prime-table .cell-inner-right{justify-content:flex-end;text-align:right}.pt-advanced-prime-table ::ng-deep .p-tag{font-size:.72rem;font-weight:800;padding:.2rem .55rem;line-height:1.2;white-space:nowrap}.pt-advanced-prime-table ::ng-deep .p-tag .p-tag-icon{margin-right:.25rem}.pt-advanced-prime-table .progress-cell{width:100%;min-width:160px;display:flex;align-items:center;gap:.5rem}.pt-advanced-prime-table ::ng-deep .progress-cell .p-progressbar{flex:1;width:100%;min-width:120px;height:.75rem!important;background:#e5e7eb!important;border-radius:999px;overflow:hidden}.pt-advanced-prime-table ::ng-deep .progress-cell .p-progressbar-value{display:block!important;height:100%!important;border-radius:999px}.pt-advanced-prime-table .progress-cell-value{min-width:38px;font-size:.72rem;font-weight:800;color:#334155;text-align:right}.pt-advanced-prime-table ::ng-deep th.action-column,.pt-advanced-prime-table ::ng-deep td.action-column{text-align:center!important;justify-content:center;align-items:center;overflow:hidden;white-space:nowrap;padding:0}.pt-advanced-prime-table ::ng-deep .action-buttons-container{width:100%;display:flex;justify-content:center!important;align-items:center!important;gap:.35rem}.pt-advanced-prime-table ::ng-deep .action-buttons-container .p-button.p-button-rounded.p-button-text{padding:.25rem!important;min-width:22px!important;height:22px!important}.pt-advanced-prime-table ::ng-deep .pt-progress-success .p-progressbar-value{background:#22c55e!important}.pt-advanced-prime-table ::ng-deep .pt-progress-warning .p-progressbar-value{background:#f59e0b!important}.pt-advanced-prime-table ::ng-deep .pt-progress-danger .p-progressbar-value{background:#ef4444!important}.pt-advanced-prime-table ::ng-deep .pt-progress-info .p-progressbar-value{background:#3b82f6!important}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i3.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i3.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "component", type: i3.CellEditor, selector: "p-cellEditor" }, { kind: "component", type: i3.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "directive", type: i3.ReorderableRowHandle, selector: "[pReorderableRowHandle]" }, { kind: "directive", type: i3.ReorderableRow, selector: "[pReorderableRow]", inputs: ["pReorderableRow", "pReorderableRowDisabled"] }, { kind: "directive", type: i3.EditableRow, selector: "[pEditableRow]", inputs: ["pEditableRow", "pEditableRowDisabled"] }, { kind: "directive", type: i3.InitEditableRow, selector: "[pInitEditableRow]" }, { kind: "directive", type: i3.SaveEditableRow, selector: "[pSaveEditableRow]" }, { kind: "directive", type: i3.CancelEditableRow, selector: "[pCancelEditableRow]" }, { kind: "component", type: i3.ColumnFilter, selector: "p-columnFilter, p-column-filter, 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", "filterOn", "useGrouping", "showButtons", "ariaLabel", "filterButtonProps", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i7.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "component", type: i8.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "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", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "component", type: i9.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: i10.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "component", type: i11.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "directive", type: i12.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i13.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "unit", "mode", "color"] }, { kind: "pipe", type: CustomCurrencyPipe, name: "customCurrency" }, { kind: "pipe", type: CustomDatePipe, name: "customDate" }] }); }
1129
1131
  }
1130
1132
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTAdvancedPrimeTableComponent, decorators: [{
1131
1133
  type: Component,
1132
- args: [{ selector: 'pt-advanced-prime-table', standalone: false, 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]=\"isLazy\"\n [filterDelay]=\"0\"\n [dataKey]=\"selectionDataKey || rowReorderIdField || 'id'\"\n styleClass=\"p-datatable-gridlines p-datatable-striped\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onRowReorder)=\"onRowReorder($event)\"\n (onPage)=\"changePage($event)\"\n (onSort)=\"sortColumn($event)\"\n (onFilter)=\"filterColumn($event)\"\n [selectionMode]=\"selectionMode\"\n [(selection)]=\"selection\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (onRowSelect)=\"rowSelect.emit($event.data)\"\n (onRowUnselect)=\"rowUnselect.emit($event.data)\"\n >\n <ng-template pTemplate=\"colgroup\" let-columns>\n <colgroup>\n @if (canUseRowReorder()) {\n <col style=\"width: 3rem\" />\n }\n @for (col of columns; track col) {\n <col\n [style.width]=\"col.width || getHeaderWidth(col)\"\n />\n }\n </colgroup>\n </ng-template>\n\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n @if (hasSearchFilter) {\n <button\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\n @if (hasExportExcel) {\n <button\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\n @if (hasExportPDF) {\n <button\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 }\n </div>\n\n @if (hasSearchFilter) {\n <div class=\"ml-auto\">\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 }\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n @if (canUseRowReorder()) {\n <th style=\"width: 3rem\"></th>\n }\n\n @for (col of columns; track col) {\n @if (!col.children) {\n <th\n [pSortableColumn]=\"col.code\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [ngClass]=\"[\n getHeaderAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : '',\n ]\"\n colspan=\"1\"\n >\n @if (isSortable && col.isSortable !== false) {\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon [field]=\"col.code\" />\n @if (hasColumnFilter && col.isFilter !== false) {\n @if (col.type === TableTypeEnum.COMPOSED) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n type=\"text\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"false\"\n [showOperator]=\"false\"\n (onClear)=\"onComposedColumnClear(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n >\n @for (composedName of col.composedNames; track composedName) {\n <div>\n @if (\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n ) {\n <p-multiSelect\n [options]=\"filters[composedName]?.options\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"filters[composedName]?.value ?? []\"\n (ngModelChange)=\"\n onComposedFilterValueChange(\n col,\n composedName,\n $event\n );\n filter($event ?? [])\n \"\n [placeholder]=\"filters[composedName]?.placeholder\"\n display=\"chip\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n @if (item.image) {\n <img\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n }\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n }\n </div>\n }\n </ng-template>\n </p-columnFilter>\n }\n @if (col.type !== TableTypeEnum.COMPOSED) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"col.type !== TableTypeEnum.MULTISELECT\"\n [showOperator]=\"col.type !== TableTypeEnum.MULTISELECT\"\n [matchMode]=\"\n col.type === TableTypeEnum.MULTISELECT\n ? 'in'\n : undefined\n \"\n (onClear)=\"onFilterClear(col.code!)\"\n >\n @if (\n col.type === TableTypeEnum.NUMBER ||\n col.type === TableTypeEnum.AMOUNT\n ; as value) {\n <ng-template\n pTemplate=\"filter\"\n let-value\n >\n <input\n pInputText\n type=\"text\"\n inputmode=\"decimal\"\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onNumberFilterChange(col.code!, $event)\n \"\n placeholder=\"Enter a number\"\n />\n </ng-template>\n }\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n let-filter=\"filterCallback\"\n let-value\n >\n <p-datepicker\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event)\n \"\n dateFormat=\"dd/mm/yy\"\n placeholder=\"Choose a date\"\n ></p-datepicker>\n </ng-template>\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"\n col.type === TableTypeEnum.MULTISELECT &&\n col.filterOptions &&\n col.filterOptions.length > 0\n \"\n let-filter=\"filterCallback\"\n let-value\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? value ?? []\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event ?? [])\n \"\n display=\"chip\"\n placeholder=\"Choose option\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n }\n }\n </div>\n </div>\n } @else {\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n @if (hasColumnFilter && col.isFilter !== false) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"\n getColumnFilterType(col) !== 'multiSelect'\n \"\n [showOperator]=\"getColumnFilterType(col) !== 'multiSelect'\"\n [matchMode]=\"\n getColumnFilterType(col) === 'multiSelect'\n ? 'in'\n : undefined\n \"\n (onClear)=\"onFilterClear(col.code!)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n let-value\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-datepicker\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event)\n \"\n dateFormat=\"dd/mm/yy\"\n ></p-datepicker>\n </ng-template>\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n let-value\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"latestFilterValues[col.code!] ?? value ?? []\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event ?? [])\n \"\n display=\"chip\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n }\n </div>\n }\n </th>\n } @else {\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getHeaderAlignClass(col)\"\n >\n <span>{{ col.title }}</span>\n </th>\n }\n }\n </tr>\n\n @if (hasGroupedColumns) {\n <tr>\n @if (canUseRowReorder()) {\n <th style=\"width: 3rem\"></th>\n }\n @for (col of columns; track col) {\n @if (col.children) {\n @for (child of col.children; track child) {\n <th\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n ></th>\n }\n }\n }\n </tr>\n }\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <tr class=\"p-datatable-emptymessage\">\n <td\n class=\"empty-message-cell\"\n [attr.colspan]=\"columns.length + (canUseRowReorder() ? 1 : 0)\"\n >\n <div class=\"empty-message-wrapper\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </div>\n </td>\n </tr>\n </ng-template>\n\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n @if (!loading) {\n <tr\n [pEditableRow]=\"isEdit ? data : null\"\n [pReorderableRow]=\"canUseRowReorder() ? ri : null\"\n [pSelectableRow]=\"selectionMode ? data : null\"\n >\n @if (canUseRowReorder()) {\n <td style=\"width: 3rem; text-align: center\">\n <span\n pReorderableRowHandle\n style=\"cursor: move; display: inline-flex; align-items: center\"\n title=\"D\u00E9placer la ligne\"\n >\n <i class=\"pi pi-bars\"></i>\n </span>\n </td>\n }\n @for (col of columns; track col) {\n @if (!col.children) {\n @if (\n isEditable(col.code!) && col.type !== TableTypeEnum.ACTION) {\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getDataAlignClass(col)\"\n [ngStyle]=\"getCellStyle(col, data)\"\n >\n <div [ngClass]=\"getCellInnerAlignClass(col)\">\n @if (isMultiSelect(col.code)) {\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 @for (\n rec of getMultiSelectValues(data[col.code!])\n ; track\n rec) {\n <p-tag [value]=\"rec\"></p-tag>\n }\n </div>\n </ng-template>\n </p-cellEditor>\n } @else {\n @if (isDatePicker(col.code)) {\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-datepicker\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-datepicker>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code!] | customDate }}\n </ng-template>\n </p-cellEditor>\n } @else {\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 @if (\n 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 } @else {\n {{ data[col.code!] }}\n }\n </ng-template>\n </p-cellEditor>\n }\n }\n </div>\n </td>\n } @else {\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"[\n getDataAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : '',\n ]\"\n [ngStyle]=\"getCellStyle(col, data)\"\n >\n @if (col.type === TableTypeEnum.ACTION) {\n <div class=\"action-buttons-container\">\n @if (isDelete) {\n <button\n pButton\n pRipple\n pTooltip=\"Supprimer\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (isEdit) {\n <div>\n @if (!editing) {\n <button\n pInitEditableRow\n pButton\n pRipple\n pTooltip=\"Modifier\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (editing) {\n <button\n pSaveEditableRow\n pButton\n pRipple\n pTooltip=\"Enregistrer\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (editing) {\n <button\n pCancelEditableRow\n pButton\n pRipple\n pTooltip=\"Annuler\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n </div>\n }\n @for (act of customActions; track act) {\n @if (isActionVisible(act, data)) {\n <button\n pButton\n pRipple\n [pTooltip]=\"act.tooltip || ''\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n class=\"p-button-rounded p-button-text\"\n [icon]=\"act.icon || 'pi pi-ellipsis-h'\"\n [ngClass]=\"act.styleClass\"\n [disabled]=\"isActionDisabled(act, data)\"\n (click)=\"onCustomActionClick(act, data)\"\n ></button>\n }\n }\n </div>\n } @else {\n <div [ngClass]=\"getCellInnerAlignClass(col)\">\n @if (\n col.type === TableTypeEnum.COMPOSED) {\n <div class=\"composed-cell\">\n @for (\n composedName of col.composedNames; track\n composedName; let i = $index) {\n @if (\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n ) {\n <img\n [src]=\"data[col.code!]?.[composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"\n getMergedComposedImageStyle(\n col,\n composedName,\n data\n )\n \"\n />\n }\n @if (\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n ) {\n <span\n class=\"composed-text\"\n [ngStyle]=\"\n getMergedComposedTextStyle(\n col,\n composedName,\n data\n )\n \"\n >\n {{ data[col.code!]?.[composedName] }}\n </span>\n }\n }\n </div>\n } @else {\n @if (\n col.type === TableTypeEnum.PROGRESS) {\n <div class=\"progress-cell\">\n <p-progressBar\n [value]=\"getProgressValue(col, data)\"\n [showValue]=\"false\"\n [ngClass]=\"\n 'pt-progress-' + getProgressSeverity(col, data)\n \"\n ></p-progressBar>\n @if (isProgressShowValue(col)) {\n <span\n class=\"progress-cell-value\"\n >\n {{ getProgressValue(col, data)\n }}{{ getProgressUnit(col) }}\n </span>\n }\n </div>\n } @else {\n @if (col.type === TableTypeEnum.TAG) {\n <p-tag\n [value]=\"getTagValue(col, data)\"\n [severity]=\"$any(getTagSeverity(col, data))\"\n [icon]=\"getTagIcon(col, data)\"\n [rounded]=\"isTagRounded(col)\"\n ></p-tag>\n } @else {\n @if (\n 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 } @else {\n @if (\n col.type === TableTypeEnum.NUMBER) {\n {{\n formatNumber(\n data[col.code!],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n } @else {\n @if (\n col.type === TableTypeEnum.DATE ||\n col.type === TableTypeEnum.DATETIME) {\n @if (col.type === TableTypeEnum.DATE) {\n {{\n formatDateWithColumn(\n parseAnyDate(data[col.code!]),\n col\n )\n }}\n }\n @if (col.type === TableTypeEnum.DATETIME) {\n {{\n formatDateTimeWithColumn(\n parseAnyDate(data[col.code!]),\n col\n )\n }}\n }\n } @else {\n @if (\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT,\n ].includes(col.type!)\n ) {\n {{ data[col.code!] }}\n }\n }\n }\n }\n }\n }\n }\n </div>\n }\n </td>\n }\n } @else {\n @for (child of col.children; track child) {\n <td\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [ngClass]=\"getDataAlignClass(child)\"\n [ngStyle]=\"getCellStyle(child, data)\"\n >\n <div [ngClass]=\"getCellInnerAlignClass(child)\">\n @if (isEditable(child.code)) {\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"child.code ? data[child.code] : null\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </p-cellEditor>\n } @else {\n @if (\n child.type === TableTypeEnum.TAG) {\n <p-tag\n [value]=\"getTagValue(child, data)\"\n [severity]=\"$any(getTagSeverity(child, data))\"\n [icon]=\"getTagIcon(child, data)\"\n [rounded]=\"isTagRounded(child)\"\n ></p-tag>\n } @else {\n {{ child.code ? data[child.code] : \"\" }}\n }\n }\n </div>\n </td>\n }\n }\n }\n </tr>\n }\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;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 .header-title-left,.pt-advanced-prime-table ::ng-deep .header-title-center,.pt-advanced-prime-table ::ng-deep .header-title-right{flex:1}.pt-advanced-prime-table ::ng-deep .header-title-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-title-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-title-right{text-align:right}.pt-advanced-prime-table ::ng-deep .header-align-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-align-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-align-right{text-align:right}.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:block;width:100%}.pt-advanced-prime-table ::ng-deep .p-datatable-emptymessage>td.empty-message-cell{padding:0!important}.pt-advanced-prime-table .empty-message-wrapper{width:100%;height:100%;min-height:180px;display:flex;align-items:center;justify-content:center}.pt-advanced-prime-table .empty-message{text-align:center;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}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-left{text-align:left!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-center{text-align:center!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-right{text-align:right!important}.pt-advanced-prime-table .cell-inner-left,.pt-advanced-prime-table .cell-inner-center,.pt-advanced-prime-table .cell-inner-right{width:100%;display:flex;align-items:center}.pt-advanced-prime-table .cell-inner-left{justify-content:flex-start;text-align:left}.pt-advanced-prime-table .cell-inner-center{justify-content:center;text-align:center}.pt-advanced-prime-table .cell-inner-right{justify-content:flex-end;text-align:right}.pt-advanced-prime-table ::ng-deep .p-tag{font-size:.72rem;font-weight:800;padding:.2rem .55rem;line-height:1.2;white-space:nowrap}.pt-advanced-prime-table ::ng-deep .p-tag .p-tag-icon{margin-right:.25rem}.pt-advanced-prime-table .progress-cell{width:100%;min-width:160px;display:flex;align-items:center;gap:.5rem}.pt-advanced-prime-table ::ng-deep .progress-cell .p-progressbar{flex:1;width:100%;min-width:120px;height:.75rem!important;background:#e5e7eb!important;border-radius:999px;overflow:hidden}.pt-advanced-prime-table ::ng-deep .progress-cell .p-progressbar-value{display:block!important;height:100%!important;border-radius:999px}.pt-advanced-prime-table .progress-cell-value{min-width:38px;font-size:.72rem;font-weight:800;color:#334155;text-align:right}.pt-advanced-prime-table ::ng-deep th.action-column,.pt-advanced-prime-table ::ng-deep td.action-column{text-align:center!important;justify-content:center;align-items:center;overflow:hidden;white-space:nowrap;padding:0}.pt-advanced-prime-table ::ng-deep .action-buttons-container{width:100%;display:flex;justify-content:center!important;align-items:center!important;gap:.35rem}.pt-advanced-prime-table ::ng-deep .action-buttons-container .p-button.p-button-rounded.p-button-text{padding:.25rem!important;min-width:22px!important;height:22px!important}.pt-advanced-prime-table ::ng-deep .pt-progress-success .p-progressbar-value{background:#22c55e!important}.pt-advanced-prime-table ::ng-deep .pt-progress-warning .p-progressbar-value{background:#f59e0b!important}.pt-advanced-prime-table ::ng-deep .pt-progress-danger .p-progressbar-value{background:#ef4444!important}.pt-advanced-prime-table ::ng-deep .pt-progress-info .p-progressbar-value{background:#3b82f6!important}\n"] }]
1134
+ args: [{ selector: 'pt-advanced-prime-table', standalone: false, 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]=\"isLazy\"\n [filterDelay]=\"0\"\n [dataKey]=\"selectionDataKey || rowReorderIdField || 'id'\"\n styleClass=\"p-datatable-gridlines p-datatable-striped\"\n [scrollable]=\"true\"\n [scrollHeight]=\"maxHeight !== null ? maxHeight : undefined\"\n (onRowReorder)=\"onRowReorder($event)\"\n (onPage)=\"changePage($event)\"\n (onSort)=\"sortColumn($event)\"\n (onFilter)=\"filterColumn($event)\"\n [selectionMode]=\"selectionMode\"\n [(selection)]=\"selection\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (onRowSelect)=\"rowSelect.emit($event.data)\"\n (onRowUnselect)=\"rowUnselect.emit($event.data)\"\n >\n <ng-template pTemplate=\"colgroup\" let-columns>\n <colgroup>\n @if (canUseRowReorder()) {\n <col style=\"width: 3rem\" />\n }\n @for (col of columns; track col) {\n <col\n [style.width]=\"col.width || getHeaderWidth(col)\"\n />\n }\n </colgroup>\n </ng-template>\n\n <ng-template pTemplate=\"caption\">\n <div class=\"flex\">\n <div>\n <h3>Total: {{ totalRecords }}</h3>\n </div>\n\n <div>\n @if (hasSearchFilter) {\n <button\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\n @if (hasExportExcel) {\n <button\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\n @if (hasExportPDF) {\n <button\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 }\n </div>\n\n @if (hasSearchFilter) {\n <div class=\"ml-auto\">\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 }\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr class=\"sticky-header\">\n @if (canUseRowReorder()) {\n <th style=\"width: 3rem\"></th>\n }\n\n @for (col of columns; track col) {\n @if (!col.children) {\n <th\n [pSortableColumn]=\"col.code\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [ngClass]=\"[\n getHeaderAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : '',\n ]\"\n colspan=\"1\"\n >\n @if (isSortable && col.isSortable !== false) {\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n <div\n class=\"icons d-flex align-items-center\"\n [style.width]=\"'77px'\"\n >\n <p-sortIcon [field]=\"col.code\" />\n @if (hasColumnFilter && col.isFilter !== false) {\n @if (col.type === TableTypeEnum.COMPOSED) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n type=\"text\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"false\"\n [showOperator]=\"false\"\n (onClear)=\"onComposedColumnClear(col)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n >\n @for (composedName of col.composedNames; track composedName) {\n <div>\n @if (\n getComposedFieldType(col, composedName) ===\n TableTypeEnum.STRING\n ) {\n <p-multiSelect\n [options]=\"filters[composedName]?.options\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"filters[composedName]?.value ?? []\"\n (ngModelChange)=\"\n onComposedFilterValueChange(\n col,\n composedName,\n $event\n );\n filter($event ?? [])\n \"\n [placeholder]=\"filters[composedName]?.placeholder\"\n display=\"chip\"\n >\n <ng-template let-item pTemplate=\"item\">\n <div class=\"custom-multiselect-item\">\n @if (item.image) {\n <img\n [src]=\"item.image\"\n alt=\"icon\"\n class=\"filter-image\"\n />\n }\n <span>{{ item.label }}</span>\n </div>\n </ng-template>\n </p-multiSelect>\n }\n </div>\n }\n </ng-template>\n </p-columnFilter>\n }\n @if (col.type !== TableTypeEnum.COMPOSED) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"col.type !== TableTypeEnum.MULTISELECT\"\n [showOperator]=\"col.type !== TableTypeEnum.MULTISELECT\"\n [matchMode]=\"\n col.type === TableTypeEnum.MULTISELECT\n ? 'in'\n : undefined\n \"\n (onClear)=\"onFilterClear(col.code!)\"\n >\n @if (\n col.type === TableTypeEnum.NUMBER ||\n col.type === TableTypeEnum.AMOUNT\n ; as value) {\n <ng-template\n pTemplate=\"filter\"\n let-value\n >\n <input\n pInputText\n type=\"text\"\n inputmode=\"decimal\"\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onNumberFilterChange(col.code!, $event)\n \"\n placeholder=\"Enter a number\"\n />\n </ng-template>\n }\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"col.type === TableTypeEnum.DATE\"\n let-filter=\"filterCallback\"\n let-value\n >\n <p-datepicker\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event)\n \"\n dateFormat=\"dd/mm/yy\"\n placeholder=\"Choose a date\"\n ></p-datepicker>\n </ng-template>\n <ng-template\n pTemplate=\"filter\"\n *ngIf=\"\n col.type === TableTypeEnum.MULTISELECT &&\n col.filterOptions &&\n col.filterOptions.length > 0\n \"\n let-filter=\"filterCallback\"\n let-value\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"\n latestFilterValues[col.code!] ?? value ?? []\n \"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event ?? [])\n \"\n display=\"chip\"\n placeholder=\"Choose option\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n }\n }\n </div>\n </div>\n } @else {\n <div\n class=\"header-container d-flex align-items-center justify-content-between\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [style.padding]=\"'0px'\"\n [style.margin]=\"'10px'\"\n >\n <span [ngClass]=\"getHeaderTitleClass(col)\">\n {{ col.title }}\n </span>\n @if (hasColumnFilter && col.isFilter !== false) {\n <p-columnFilter\n display=\"menu\"\n [field]=\"col.code\"\n [type]=\"getColumnFilterType(col)\"\n [currency]=\"getCurrencySymbol(col)\"\n [showApplyButton]=\"true\"\n [showClearButton]=\"true\"\n [showMatchModes]=\"\n getColumnFilterType(col) !== 'multiSelect'\n \"\n [showOperator]=\"getColumnFilterType(col) !== 'multiSelect'\"\n [matchMode]=\"\n getColumnFilterType(col) === 'multiSelect'\n ? 'in'\n : undefined\n \"\n (onClear)=\"onFilterClear(col.code!)\"\n >\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n let-value\n *ngIf=\"getColumnFilterType(col) === 'date'\"\n >\n <p-datepicker\n [ngModel]=\"latestFilterValues[col.code!] ?? value\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event)\n \"\n dateFormat=\"dd/mm/yy\"\n ></p-datepicker>\n </ng-template>\n <ng-template\n pTemplate=\"filter\"\n let-filter=\"filterCallback\"\n let-value\n *ngIf=\"getColumnFilterType(col) === 'multiSelect'\"\n >\n <p-multiSelect\n [options]=\"col.filterOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"latestFilterValues[col.code!] ?? value ?? []\"\n (ngModelChange)=\"\n onFilterValueChange(col.code!, null, $event);\n filter($event ?? [])\n \"\n display=\"chip\"\n placeholder=\"Select\"\n class=\"custom-multiselect\"\n ></p-multiSelect>\n </ng-template>\n </p-columnFilter>\n }\n </div>\n }\n </th>\n } @else {\n <th\n [attr.colspan]=\"col.children?.length\"\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getHeaderAlignClass(col)\"\n >\n <span>{{ col.title }}</span>\n </th>\n }\n }\n </tr>\n\n @if (hasGroupedColumns) {\n <tr>\n @if (canUseRowReorder()) {\n <th style=\"width: 3rem\"></th>\n }\n @for (col of columns; track col) {\n @if (col.children) {\n @for (child of col.children; track child) {\n <th\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [style.padding]=\"'0px'\"\n ></th>\n }\n }\n }\n </tr>\n }\n </ng-template>\n\n <ng-template pTemplate=\"emptymessage\">\n <tr class=\"p-datatable-emptymessage\">\n <td\n class=\"empty-message-cell\"\n [attr.colspan]=\"columns.length + (canUseRowReorder() ? 1 : 0)\"\n >\n <div class=\"empty-message-wrapper\">\n <div class=\"empty-message\">\n <i class=\"pi pi-info-circle\"></i>\n <p>No records available to display.</p>\n </div>\n </div>\n </td>\n </tr>\n </ng-template>\n\n <ng-template\n pTemplate=\"body\"\n let-data\n let-editing=\"editing\"\n let-ri=\"rowIndex\"\n >\n @if (!loading) {\n <tr\n [pEditableRow]=\"isEdit ? data : null\"\n [pReorderableRow]=\"canUseRowReorder() ? ri : null\"\n [pSelectableRow]=\"selectionMode ? data : null\"\n >\n @if (canUseRowReorder()) {\n <td style=\"width: 3rem; text-align: center\">\n <span\n pReorderableRowHandle\n style=\"cursor: move; display: inline-flex; align-items: center\"\n title=\"D\u00E9placer la ligne\"\n >\n <i class=\"pi pi-bars\"></i>\n </span>\n </td>\n }\n @for (col of columns; track col) {\n @if (!col.children) {\n @if (\n isEditable(col.code!) && col.type !== TableTypeEnum.ACTION) {\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"getDataAlignClass(col)\"\n [ngStyle]=\"getCellStyle(col, data)\"\n >\n <div [ngClass]=\"getCellInnerAlignClass(col)\">\n @if (isMultiSelect(col.code)) {\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 @for (\n rec of getMultiSelectValues(data[col.code!])\n ; track\n rec) {\n <p-tag [value]=\"rec\"></p-tag>\n }\n </div>\n </ng-template>\n </p-cellEditor>\n } @else {\n @if (isDatePicker(col.code)) {\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <p-datepicker\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-datepicker>\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ data[col.code!] | customDate }}\n </ng-template>\n </p-cellEditor>\n } @else {\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 @if (\n 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 } @else {\n {{ data[col.code!] }}\n }\n </ng-template>\n </p-cellEditor>\n }\n }\n </div>\n </td>\n } @else {\n <td\n [style.width]=\"col.width || getHeaderWidth(col)\"\n [ngClass]=\"[\n getDataAlignClass(col),\n col.type === TableTypeEnum.ACTION ? 'action-column' : '',\n ]\"\n [ngStyle]=\"getCellStyle(col, data)\"\n >\n @if (col.type === TableTypeEnum.ACTION) {\n <div class=\"action-buttons-container\">\n @if (isDelete) {\n <button\n pButton\n pRipple\n pTooltip=\"Supprimer\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-trash\"\n (click)=\"Delete(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (isEdit) {\n <div>\n @if (!editing) {\n <button\n pInitEditableRow\n pButton\n pRipple\n pTooltip=\"Modifier\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-pencil\"\n (click)=\"initEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (editing) {\n <button\n pSaveEditableRow\n pButton\n pRipple\n pTooltip=\"Enregistrer\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-check\"\n (click)=\"saveEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n @if (editing) {\n <button\n pCancelEditableRow\n pButton\n pRipple\n pTooltip=\"Annuler\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n icon=\"pi pi-times\"\n (click)=\"cancelEditableRow(data)\"\n class=\"p-button-rounded p-button-text\"\n ></button>\n }\n </div>\n }\n @for (act of customActions; track act) {\n @if (isActionVisible(act, data)) {\n <button\n pButton\n pRipple\n [pTooltip]=\"act.tooltip || ''\"\n tooltipPosition=\"top\"\n appendTo=\"body\"\n type=\"button\"\n class=\"p-button-rounded p-button-text\"\n [icon]=\"act.icon || 'pi pi-ellipsis-h'\"\n [ngClass]=\"act.styleClass\"\n [disabled]=\"isActionDisabled(act, data)\"\n (click)=\"onCustomActionClick(act, data)\"\n ></button>\n }\n }\n </div>\n } @else {\n <div [ngClass]=\"getCellInnerAlignClass(col)\">\n @if (\n col.type === TableTypeEnum.COMPOSED) {\n <div class=\"composed-cell\">\n @for (\n composedName of col.composedNames; track\n composedName; let i = $index) {\n @if (\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.IMAGE\n ) {\n <img\n [src]=\"data[col.code!]?.[composedName]\"\n alt=\"composed-img\"\n class=\"composed-image\"\n [ngStyle]=\"\n getMergedComposedImageStyle(\n col,\n composedName,\n data\n )\n \"\n />\n }\n @if (\n col.composedTypes &&\n col.composedTypes[i] === TableTypeEnum.STRING\n ) {\n <span\n class=\"composed-text\"\n [ngStyle]=\"\n getMergedComposedTextStyle(\n col,\n composedName,\n data\n )\n \"\n >\n {{ data[col.code!]?.[composedName] }}\n </span>\n }\n }\n </div>\n } @else {\n @if (\n col.type === TableTypeEnum.PROGRESS) {\n <div class=\"progress-cell\">\n <p-progressBar\n [value]=\"getProgressValue(col, data)\"\n [showValue]=\"false\"\n [ngClass]=\"\n 'pt-progress-' + getProgressSeverity(col, data)\n \"\n ></p-progressBar>\n @if (isProgressShowValue(col)) {\n <span\n class=\"progress-cell-value\"\n >\n {{ getProgressValue(col, data)\n }}{{ getProgressUnit(col) }}\n </span>\n }\n </div>\n } @else {\n @if (col.type === TableTypeEnum.TAG) {\n <p-tag\n [value]=\"getTagValue(col, data)\"\n [severity]=\"$any(getTagSeverity(col, data))\"\n [icon]=\"getTagIcon(col, data)\"\n [rounded]=\"isTagRounded(col)\"\n ></p-tag>\n } @else {\n @if (\n 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 } @else {\n @if (\n col.type === TableTypeEnum.NUMBER) {\n {{\n formatNumber(\n data[col.code!],\n col.decimalPlaces,\n col.thousandSeparator,\n col.decimalSeparator\n )\n }}\n } @else {\n @if (\n col.type === TableTypeEnum.DATE ||\n col.type === TableTypeEnum.DATETIME) {\n @if (col.type === TableTypeEnum.DATE) {\n {{\n formatDateWithColumn(\n parseAnyDate(data[col.code!]),\n col\n )\n }}\n }\n @if (col.type === TableTypeEnum.DATETIME) {\n {{\n formatDateTimeWithColumn(\n parseAnyDate(data[col.code!]),\n col\n )\n }}\n }\n } @else {\n @if (\n [\n TableTypeEnum.STRING,\n TableTypeEnum.MULTISELECT,\n ].includes(col.type!)\n ) {\n {{ data[col.code!] }}\n }\n }\n }\n }\n }\n }\n }\n </div>\n }\n </td>\n }\n } @else {\n @for (child of col.children; track child) {\n <td\n [style.width]=\"child.width || getHeaderWidth(child)\"\n [ngClass]=\"getDataAlignClass(child)\"\n [ngStyle]=\"getCellStyle(child, data)\"\n >\n <div [ngClass]=\"getCellInnerAlignClass(child)\">\n @if (isEditable(child.code)) {\n <p-cellEditor>\n <ng-template pTemplate=\"input\">\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"child.code ? data[child.code] : null\"\n (change)=\"onChange($event, data.id, child.code)\"\n />\n </ng-template>\n <ng-template pTemplate=\"output\">\n {{ child.code ? data[child.code] : \"\" }}\n </ng-template>\n </p-cellEditor>\n } @else {\n @if (\n child.type === TableTypeEnum.TAG) {\n <p-tag\n [value]=\"getTagValue(child, data)\"\n [severity]=\"$any(getTagSeverity(child, data))\"\n [icon]=\"getTagIcon(child, data)\"\n [rounded]=\"isTagRounded(child)\"\n ></p-tag>\n } @else {\n {{ child.code ? data[child.code] : \"\" }}\n }\n }\n </div>\n </td>\n }\n }\n }\n </tr>\n }\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;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 .header-title-left,.pt-advanced-prime-table ::ng-deep .header-title-center,.pt-advanced-prime-table ::ng-deep .header-title-right{flex:1}.pt-advanced-prime-table ::ng-deep .header-title-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-title-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-title-right{text-align:right}.pt-advanced-prime-table ::ng-deep .header-align-left{text-align:left}.pt-advanced-prime-table ::ng-deep .header-align-center{text-align:center}.pt-advanced-prime-table ::ng-deep .header-align-right{text-align:right}.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:-.8rem;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:block;width:100%}.pt-advanced-prime-table ::ng-deep .p-datatable-emptymessage>td.empty-message-cell{padding:0!important}.pt-advanced-prime-table .empty-message-wrapper{width:100%;height:100%;min-height:180px;display:flex;align-items:center;justify-content:center}.pt-advanced-prime-table .empty-message{text-align:center;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}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-left{text-align:left!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-center{text-align:center!important}.pt-advanced-prime-table ::ng-deep .p-datatable-tbody>tr>td.cell-align-right{text-align:right!important}.pt-advanced-prime-table .cell-inner-left,.pt-advanced-prime-table .cell-inner-center,.pt-advanced-prime-table .cell-inner-right{width:100%;display:flex;align-items:center}.pt-advanced-prime-table .cell-inner-left{justify-content:flex-start;text-align:left}.pt-advanced-prime-table .cell-inner-center{justify-content:center;text-align:center}.pt-advanced-prime-table .cell-inner-right{justify-content:flex-end;text-align:right}.pt-advanced-prime-table ::ng-deep .p-tag{font-size:.72rem;font-weight:800;padding:.2rem .55rem;line-height:1.2;white-space:nowrap}.pt-advanced-prime-table ::ng-deep .p-tag .p-tag-icon{margin-right:.25rem}.pt-advanced-prime-table .progress-cell{width:100%;min-width:160px;display:flex;align-items:center;gap:.5rem}.pt-advanced-prime-table ::ng-deep .progress-cell .p-progressbar{flex:1;width:100%;min-width:120px;height:.75rem!important;background:#e5e7eb!important;border-radius:999px;overflow:hidden}.pt-advanced-prime-table ::ng-deep .progress-cell .p-progressbar-value{display:block!important;height:100%!important;border-radius:999px}.pt-advanced-prime-table .progress-cell-value{min-width:38px;font-size:.72rem;font-weight:800;color:#334155;text-align:right}.pt-advanced-prime-table ::ng-deep th.action-column,.pt-advanced-prime-table ::ng-deep td.action-column{text-align:center!important;justify-content:center;align-items:center;overflow:hidden;white-space:nowrap;padding:0}.pt-advanced-prime-table ::ng-deep .action-buttons-container{width:100%;display:flex;justify-content:center!important;align-items:center!important;gap:.35rem}.pt-advanced-prime-table ::ng-deep .action-buttons-container .p-button.p-button-rounded.p-button-text{padding:.25rem!important;min-width:22px!important;height:22px!important}.pt-advanced-prime-table ::ng-deep .pt-progress-success .p-progressbar-value{background:#22c55e!important}.pt-advanced-prime-table ::ng-deep .pt-progress-warning .p-progressbar-value{background:#f59e0b!important}.pt-advanced-prime-table ::ng-deep .pt-progress-danger .p-progressbar-value{background:#ef4444!important}.pt-advanced-prime-table ::ng-deep .pt-progress-info .p-progressbar-value{background:#3b82f6!important}\n"] }]
1133
1135
  }], propDecorators: { data: [{
1134
1136
  type: Input
1135
1137
  }], columns: [{
@@ -1198,43 +1200,128 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1198
1200
  }] } });
1199
1201
 
1200
1202
  class PTMultiSelectComponent {
1203
+ constructor() {
1204
+ /**
1205
+ * Two-way standalone value.
1206
+ */
1207
+ this.value = [];
1208
+ this.valueChange = new EventEmitter();
1209
+ this.selectionChange = new EventEmitter();
1210
+ this.standaloneFormGroup = new FormGroup({});
1211
+ }
1201
1212
  ngOnInit() {
1202
- this.setupControl();
1213
+ this.setupControl(true);
1203
1214
  }
1204
1215
  ngOnChanges(changes) {
1205
- if (changes['formField'] && !changes['formField'].firstChange) {
1206
- this.setupControl();
1216
+ if (changes['formGroup'] ||
1217
+ changes['formField'] ||
1218
+ changes['config'] ||
1219
+ changes['value']) {
1220
+ this.setupControl(false);
1207
1221
  }
1208
1222
  }
1223
+ ngOnDestroy() {
1224
+ this.valueChangesSubscription?.unsubscribe();
1225
+ }
1226
+ get activeFormGroup() {
1227
+ return this.formGroup || this.standaloneFormGroup;
1228
+ }
1229
+ get controlName() {
1230
+ return this.formField?.name || this.config?.name || 'multiSelect';
1231
+ }
1209
1232
  get inputId() {
1210
- return `pt-multiselect-${this.formField?.name || 'field'}`;
1233
+ return `pt-multiselect-${this.controlName}`;
1211
1234
  }
1212
- setupControl() {
1213
- const name = this.formField?.name;
1214
- if (!name || !this.formGroup) {
1235
+ get resolvedHidden() {
1236
+ return this.formField?.hidden ?? this.config?.hidden ?? false;
1237
+ }
1238
+ get resolvedLabel() {
1239
+ return this.formField?.label || this.config?.label;
1240
+ }
1241
+ get resolvedWidth() {
1242
+ return this.formField?.width || this.config?.width || '100%';
1243
+ }
1244
+ get resolvedOptions() {
1245
+ return this.formField?.options || this.config?.options || [];
1246
+ }
1247
+ get resolvedPlaceholder() {
1248
+ return (this.formField?.placeholder ||
1249
+ this.config?.placeholder ||
1250
+ 'Select options');
1251
+ }
1252
+ get resolvedOptionLabel() {
1253
+ return this.config?.optionLabel || 'label';
1254
+ }
1255
+ get resolvedOptionValue() {
1256
+ return this.config?.optionValue || 'value';
1257
+ }
1258
+ get resolvedRequired() {
1259
+ return this.formField?.required ?? this.config?.required ?? false;
1260
+ }
1261
+ get resolvedDisabled() {
1262
+ return this.formField?.disabled ?? this.config?.disabled ?? false;
1263
+ }
1264
+ get resolvedErrorText() {
1265
+ return this.formField?.errorText || this.config?.errorText;
1266
+ }
1267
+ get resolvedFilter() {
1268
+ return this.config?.filter === true;
1269
+ }
1270
+ get resolvedFilterBy() {
1271
+ return this.config?.filterBy || this.resolvedOptionLabel;
1272
+ }
1273
+ get resolvedDisplay() {
1274
+ return this.config?.display || 'comma';
1275
+ }
1276
+ get resolvedMaxSelectedLabels() {
1277
+ return this.config?.maxSelectedLabels ?? 3;
1278
+ }
1279
+ get resolvedSelectedItemsLabel() {
1280
+ return this.config?.selectedItemsLabel || '{0} items selected';
1281
+ }
1282
+ setupControl(forceValueFromConfig) {
1283
+ const name = this.controlName;
1284
+ if (!name) {
1215
1285
  return;
1216
1286
  }
1217
- let control = this.formGroup.get(name);
1218
- const normalizedValue = this.normalizeValue(this.formField?.value);
1287
+ let control = this.activeFormGroup.get(name);
1219
1288
  if (!control) {
1220
- control = new FormControl(normalizedValue);
1221
- this.formGroup.addControl(name, control);
1289
+ control = new FormControl(this.getInitialValue());
1290
+ this.activeFormGroup.addControl(name, control);
1222
1291
  }
1223
- else {
1224
- control.setValue(normalizedValue, { emitEvent: false });
1292
+ else if (forceValueFromConfig) {
1293
+ control.setValue(this.getInitialValue(), { emitEvent: false });
1294
+ }
1295
+ else if (!this.formGroup && this.value !== undefined) {
1296
+ control.setValue(this.normalizeValue(this.value), { emitEvent: false });
1225
1297
  }
1226
1298
  control.setValidators(this.getValidators());
1227
- if (this.formField?.disabled) {
1299
+ if (this.resolvedDisabled) {
1228
1300
  control.disable({ emitEvent: false });
1229
1301
  }
1230
1302
  else {
1231
1303
  control.enable({ emitEvent: false });
1232
1304
  }
1233
1305
  control.updateValueAndValidity({ emitEvent: false });
1306
+ this.valueChangesSubscription?.unsubscribe();
1307
+ this.valueChangesSubscription = control.valueChanges.subscribe((selectedValues) => {
1308
+ const normalizedValues = this.normalizeValue(selectedValues);
1309
+ this.valueChange.emit(normalizedValues);
1310
+ this.selectionChange.emit(normalizedValues);
1311
+ });
1312
+ }
1313
+ getInitialValue() {
1314
+ if (this.formField?.value !== undefined) {
1315
+ return this.normalizeValue(this.formField.value);
1316
+ }
1317
+ if (this.value !== undefined && Array.isArray(this.value)) {
1318
+ return this.normalizeValue(this.value);
1319
+ }
1320
+ return this.normalizeValue(this.config?.value);
1234
1321
  }
1235
1322
  getValidators() {
1236
1323
  const validators = [];
1237
- if (this.formField?.required) {
1324
+ if (this.resolvedRequired) {
1238
1325
  validators.push(Validators.required);
1239
1326
  }
1240
1327
  return validators;
@@ -1254,26 +1341,41 @@ class PTMultiSelectComponent {
1254
1341
  return value;
1255
1342
  }
1256
1343
  return value
1257
- .map((item) => item?.value ?? item?.id ?? null)
1344
+ .map((item) => {
1345
+ const optionValue = this.resolvedOptionValue;
1346
+ if (item?.[optionValue] !== undefined) {
1347
+ return item[optionValue];
1348
+ }
1349
+ return item?.value ?? item?.id ?? null;
1350
+ })
1258
1351
  .filter((item) => item !== null && item !== undefined);
1259
1352
  }
1260
1353
  getErrorMessage() {
1261
- const control = this.formGroup.get(this.formField.name);
1354
+ const control = this.activeFormGroup.get(this.controlName);
1262
1355
  if (control?.hasError('required')) {
1263
- return this.formField.errorText || `${this.formField.label} is required`;
1356
+ return (this.resolvedErrorText ||
1357
+ `${this.resolvedLabel || this.controlName} is required`);
1264
1358
  }
1265
1359
  return '';
1266
1360
  }
1267
1361
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTMultiSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1268
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTMultiSelectComponent, isStandalone: false, selector: "pt-multi-select", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\">\n {{ formField.label }}\n </label>\n }\n <p-multiSelect\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [options]=\"formField.options\"\n [placeholder]=\"formField.placeholder || 'Select options'\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [appendTo]=\"'body'\"\n [overlayOptions]=\"{ baseZIndex: 11000 }\"\n ></p-multiSelect>\n @if (\n formGroup.get(formField.name)?.invalid &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div\n >\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i8.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "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", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }] }); }
1362
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTMultiSelectComponent, isStandalone: false, selector: "pt-multi-select", inputs: { formGroup: "formGroup", formField: "formField", config: "config", value: "value" }, outputs: { valueChange: "valueChange", selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: resolvedWidth }\"\n >\n @if (resolvedLabel) {\n <label [for]=\"inputId\" class=\"field-label\">\n {{ resolvedLabel }}\n </label>\n }\n\n <p-multiSelect\n [inputId]=\"inputId\"\n [name]=\"controlName\"\n [formControlName]=\"controlName\"\n [options]=\"resolvedOptions\"\n [placeholder]=\"resolvedPlaceholder\"\n [optionLabel]=\"resolvedOptionLabel\"\n [optionValue]=\"resolvedOptionValue\"\n [filter]=\"resolvedFilter\"\n [filterBy]=\"resolvedFilterBy\"\n [display]=\"resolvedDisplay\"\n [maxSelectedLabels]=\"resolvedMaxSelectedLabels\"\n [selectedItemsLabel]=\"resolvedSelectedItemsLabel\"\n [appendTo]=\"'body'\"\n [overlayOptions]=\"{ baseZIndex: 11000 }\"\n ></p-multiSelect>\n\n @if (\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-multiselect{width:100%}.form-field ::ng-deep .p-multiselect.ng-invalid.ng-touched,.form-field ::ng-deep .p-multiselect.ng-invalid.ng-dirty{border-color:#dc2626}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i8.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "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", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }] }); }
1269
1363
  }
1270
1364
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTMultiSelectComponent, decorators: [{
1271
1365
  type: Component,
1272
- args: [{ selector: 'pt-multi-select', standalone: false, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\">\n {{ formField.label }}\n </label>\n }\n <p-multiSelect\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [options]=\"formField.options\"\n [placeholder]=\"formField.placeholder || 'Select options'\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [appendTo]=\"'body'\"\n [overlayOptions]=\"{ baseZIndex: 11000 }\"\n ></p-multiSelect>\n @if (\n formGroup.get(formField.name)?.invalid &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div\n >\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"] }]
1366
+ args: [{ selector: 'pt-multi-select', standalone: false, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: resolvedWidth }\"\n >\n @if (resolvedLabel) {\n <label [for]=\"inputId\" class=\"field-label\">\n {{ resolvedLabel }}\n </label>\n }\n\n <p-multiSelect\n [inputId]=\"inputId\"\n [name]=\"controlName\"\n [formControlName]=\"controlName\"\n [options]=\"resolvedOptions\"\n [placeholder]=\"resolvedPlaceholder\"\n [optionLabel]=\"resolvedOptionLabel\"\n [optionValue]=\"resolvedOptionValue\"\n [filter]=\"resolvedFilter\"\n [filterBy]=\"resolvedFilterBy\"\n [display]=\"resolvedDisplay\"\n [maxSelectedLabels]=\"resolvedMaxSelectedLabels\"\n [selectedItemsLabel]=\"resolvedSelectedItemsLabel\"\n [appendTo]=\"'body'\"\n [overlayOptions]=\"{ baseZIndex: 11000 }\"\n ></p-multiSelect>\n\n @if (\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-multiselect{width:100%}.form-field ::ng-deep .p-multiselect.ng-invalid.ng-touched,.form-field ::ng-deep .p-multiselect.ng-invalid.ng-dirty{border-color:#dc2626}\n"] }]
1273
1367
  }], propDecorators: { formGroup: [{
1274
1368
  type: Input
1275
1369
  }], formField: [{
1276
1370
  type: Input
1371
+ }], config: [{
1372
+ type: Input
1373
+ }], value: [{
1374
+ type: Input
1375
+ }], valueChange: [{
1376
+ type: Output
1377
+ }], selectionChange: [{
1378
+ type: Output
1277
1379
  }] } });
1278
1380
 
1279
1381
  class PTMultiSelectModule {
@@ -1296,7 +1398,6 @@ class PTButtonComponent {
1296
1398
  this.el = el;
1297
1399
  }
1298
1400
  ngOnInit() {
1299
- // Fallback to default config if undefined
1300
1401
  if (!this.buttonConfig) {
1301
1402
  this.buttonConfig = {
1302
1403
  label: 'Click Me',
@@ -1317,87 +1418,123 @@ class PTButtonComponent {
1317
1418
  }
1318
1419
  ngOnChanges(changes) {
1319
1420
  const configChange = changes['buttonConfig'];
1320
- if (configChange) {
1321
- const prev = configChange.previousValue;
1322
- const curr = configChange.currentValue;
1323
- if (prev && curr) {
1324
- const onlyDisabledChanged = prev.disabled !== curr.disabled &&
1325
- JSON.stringify({ ...prev, disabled: undefined }) ===
1326
- JSON.stringify({ ...curr, disabled: undefined });
1327
- if (onlyDisabledChanged) {
1328
- this.updateDisabledStyles(curr.disabled ?? false);
1329
- }
1330
- else {
1331
- this.applyButtonStyles();
1332
- }
1421
+ if (!configChange) {
1422
+ return;
1423
+ }
1424
+ const prev = configChange.previousValue;
1425
+ const curr = configChange.currentValue;
1426
+ if (prev && curr) {
1427
+ const onlyDisabledChanged = prev.disabled !== curr.disabled &&
1428
+ JSON.stringify({ ...prev, disabled: undefined }) ===
1429
+ JSON.stringify({ ...curr, disabled: undefined });
1430
+ if (onlyDisabledChanged) {
1431
+ setTimeout(() => this.updateDisabledStyles(curr.disabled ?? false));
1333
1432
  }
1334
1433
  else {
1335
- // If no previous value (first load), apply full styles
1336
- this.applyButtonStyles();
1434
+ setTimeout(() => this.applyButtonStyles());
1337
1435
  }
1436
+ return;
1338
1437
  }
1438
+ setTimeout(() => this.applyButtonStyles());
1339
1439
  }
1340
1440
  ngAfterViewInit() {
1341
- this.applyButtonStyles();
1441
+ setTimeout(() => this.applyButtonStyles());
1342
1442
  }
1343
1443
  getIconPos() {
1344
- return this.buttonConfig.iconPos === 'right' ? 'right' : 'left';
1444
+ return this.buttonConfig?.iconPos === 'right' ? 'right' : 'left';
1345
1445
  }
1346
1446
  getType() {
1347
- return this.buttonConfig.type || 'button';
1447
+ return this.buttonConfig?.type || 'button';
1448
+ }
1449
+ hasCustomColors() {
1450
+ return !!(this.buttonConfig?.backgroundColor ||
1451
+ this.buttonConfig?.borderColor ||
1452
+ this.buttonConfig?.fontColor);
1453
+ }
1454
+ getSeverity() {
1455
+ /**
1456
+ * If custom colors are provided, do not pass PrimeNG severity.
1457
+ * PrimeNG severity classes can override custom background/border colors.
1458
+ */
1459
+ if (this.hasCustomColors()) {
1460
+ return undefined;
1461
+ }
1462
+ return this.buttonConfig?.severity;
1463
+ }
1464
+ getStyleClass() {
1465
+ const classes = [];
1466
+ if (this.buttonConfig?.styleClass) {
1467
+ classes.push(this.buttonConfig.styleClass);
1468
+ }
1469
+ if (this.hasCustomColors()) {
1470
+ classes.push('pt-custom-colored-button');
1471
+ }
1472
+ return classes.join(' ');
1348
1473
  }
1349
1474
  updateDisabledStyles(isDisabled) {
1350
- const buttonElement = this.el.nativeElement.querySelector('button.p-element');
1351
- if (buttonElement) {
1352
- this.renderer.setStyle(buttonElement, 'color', isDisabled ? '#999' : this.buttonConfig.fontColor);
1353
- this.renderer.setStyle(buttonElement, 'background-color', isDisabled ? '#e0e0e0' : this.buttonConfig.backgroundColor);
1354
- this.renderer.setStyle(buttonElement, 'border-color', isDisabled ? '#bdbdbd' : this.buttonConfig.borderColor);
1475
+ const buttonElement = this.getButtonElement();
1476
+ if (!buttonElement || !this.buttonConfig) {
1477
+ return;
1478
+ }
1479
+ if (this.hasCustomColors()) {
1480
+ this.renderer.setStyle(buttonElement, 'color', isDisabled ? '#999' : this.buttonConfig.fontColor || '#ffffff');
1481
+ this.renderer.setStyle(buttonElement, 'background-color', isDisabled
1482
+ ? '#e0e0e0'
1483
+ : this.buttonConfig.backgroundColor || 'transparent');
1484
+ this.renderer.setStyle(buttonElement, 'border-color', isDisabled
1485
+ ? '#bdbdbd'
1486
+ : this.buttonConfig.borderColor ||
1487
+ this.buttonConfig.backgroundColor ||
1488
+ 'transparent');
1489
+ return;
1355
1490
  }
1491
+ this.renderer.removeStyle(buttonElement, 'color');
1492
+ this.renderer.removeStyle(buttonElement, 'background-color');
1493
+ this.renderer.removeStyle(buttonElement, 'border-color');
1356
1494
  }
1357
1495
  /**
1358
- * We delegate colors to PrimeNG theme when:
1359
- * - outlined = true
1360
- * - and no manual color is provided (no backgroundColor, borderColor, fontColor)
1496
+ * We delegate colors to PrimeNG theme when no manual color is provided.
1361
1497
  */
1362
1498
  shouldUseThemeColors() {
1363
- if (!this.buttonConfig) {
1364
- return false;
1365
- }
1366
- const outlined = !!this.buttonConfig.outlined; // ✅ coerce to boolean
1367
- return (outlined &&
1368
- !this.buttonConfig.backgroundColor &&
1369
- !this.buttonConfig.borderColor &&
1370
- !this.buttonConfig.fontColor);
1499
+ return !this.hasCustomColors();
1371
1500
  }
1372
1501
  applyButtonStyles() {
1373
- const buttonElement = this.el.nativeElement.querySelector('button.p-element');
1502
+ const buttonElement = this.getButtonElement();
1374
1503
  if (!buttonElement || !this.buttonConfig) {
1375
1504
  return;
1376
1505
  }
1377
1506
  const isDisabled = !!this.buttonConfig.disabled;
1378
1507
  const useThemeColors = this.shouldUseThemeColors();
1379
- // Width / height always applied
1380
1508
  this.renderer.setStyle(buttonElement, 'width', this.buttonConfig.width || 'auto');
1381
1509
  this.renderer.setStyle(buttonElement, 'height', this.buttonConfig.height || 'auto');
1382
- // ✅ Only override colors when we are NOT delegating to PrimeNG theme
1383
1510
  if (!useThemeColors) {
1384
- this.renderer.setStyle(buttonElement, 'color', isDisabled ? '#999' : this.buttonConfig.fontColor);
1385
- this.renderer.setStyle(buttonElement, 'background-color', isDisabled ? '#e0e0e0' : this.buttonConfig.backgroundColor);
1386
- this.renderer.setStyle(buttonElement, 'border-color', isDisabled ? '#bdbdbd' : this.buttonConfig.borderColor);
1387
- }
1388
- else {
1389
- // If we delegate to theme, clear any inline overrides
1390
- this.renderer.removeStyle(buttonElement, 'color');
1391
- this.renderer.removeStyle(buttonElement, 'background-color');
1392
- this.renderer.removeStyle(buttonElement, 'border-color');
1511
+ this.renderer.setStyle(buttonElement, 'color', isDisabled ? '#999' : this.buttonConfig.fontColor || '#ffffff');
1512
+ this.renderer.setStyle(buttonElement, 'background-color', isDisabled
1513
+ ? '#e0e0e0'
1514
+ : this.buttonConfig.backgroundColor || 'transparent');
1515
+ this.renderer.setStyle(buttonElement, 'border-color', isDisabled
1516
+ ? '#bdbdbd'
1517
+ : this.buttonConfig.borderColor ||
1518
+ this.buttonConfig.backgroundColor ||
1519
+ 'transparent');
1520
+ return;
1393
1521
  }
1522
+ this.renderer.removeStyle(buttonElement, 'color');
1523
+ this.renderer.removeStyle(buttonElement, 'background-color');
1524
+ this.renderer.removeStyle(buttonElement, 'border-color');
1525
+ }
1526
+ getButtonElement() {
1527
+ return (this.el.nativeElement.querySelector('button.p-button') ||
1528
+ this.el.nativeElement.querySelector('button.p-element') ||
1529
+ this.el.nativeElement.querySelector('.p-button') ||
1530
+ this.el.nativeElement.querySelector('button'));
1394
1531
  }
1395
1532
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTButtonComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
1396
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: PTButtonComponent, isStandalone: false, 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: i6.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }] }); }
1533
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: PTButtonComponent, isStandalone: false, 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 [styleClass]=\"getStyleClass()\"\n [type]=\"getType()\"\n [severity]=\"getSeverity()\"\n [outlined]=\"buttonConfig.outlined\"\n></p-button>\n", styles: [":host{display:inline-block}:host ::ng-deep p-button{display:block}:host ::ng-deep .pt-custom-colored-button.p-button{box-shadow:none}:host ::ng-deep .pt-custom-colored-button.p-button:hover:not(:disabled){filter:brightness(.95)}:host ::ng-deep .pt-custom-colored-button.p-button:disabled{filter:none;cursor:not-allowed}\n"], dependencies: [{ kind: "component", type: i6.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }] }); }
1397
1534
  }
1398
1535
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTButtonComponent, decorators: [{
1399
1536
  type: Component,
1400
- args: [{ selector: 'pt-button', standalone: false, 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"] }]
1537
+ args: [{ selector: 'pt-button', standalone: false, template: "<p-button\n [label]=\"buttonConfig.label\"\n [icon]=\"buttonConfig.icon || ''\"\n [iconPos]=\"getIconPos()\"\n [disabled]=\"buttonConfig.disabled\"\n [loading]=\"buttonConfig.loading\"\n [styleClass]=\"getStyleClass()\"\n [type]=\"getType()\"\n [severity]=\"getSeverity()\"\n [outlined]=\"buttonConfig.outlined\"\n></p-button>\n", styles: [":host{display:inline-block}:host ::ng-deep p-button{display:block}:host ::ng-deep .pt-custom-colored-button.p-button{box-shadow:none}:host ::ng-deep .pt-custom-colored-button.p-button:hover:not(:disabled){filter:brightness(.95)}:host ::ng-deep .pt-custom-colored-button.p-button:disabled{filter:none;cursor:not-allowed}\n"] }]
1401
1538
  }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }], propDecorators: { buttonConfig: [{
1402
1539
  type: Input
1403
1540
  }] } });
@@ -1848,11 +1985,11 @@ class PTCheckBoxInputComponent {
1848
1985
  return '';
1849
1986
  }
1850
1987
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTCheckBoxInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1851
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTCheckBoxInputComponent, isStandalone: false, selector: "pt-check-box-input", inputs: { formGroup: "formGroup", formField: "formField" }, ngImport: i0, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n <div class=\"checkbox-container\">\n <p-checkbox\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [binary]=\"true\"\n ></p-checkbox>\n @if (formField.label) {\n <label [for]=\"inputId\" class=\"checkbox-label\">\n {{ formField.label }}\n </label>\n }\n </div>\n @if (\n formGroup.get(formField.name)?.errors &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div\n class=\"error-container\"\n >\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700;font-size:1rem}.checkbox-container{display:flex;align-items:center}.p-error{font-size:.8rem;color:#f44336}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }] }); }
1988
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTCheckBoxInputComponent, isStandalone: false, selector: "pt-check-box-input", inputs: { formGroup: "formGroup", formField: "formField" }, ngImport: i0, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n <div class=\"checkbox-container\">\n <p-checkbox\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [binary]=\"true\"\n ></p-checkbox>\n\n @if (formField.label) {\n <label [for]=\"inputId\" class=\"checkbox-label\">\n {{ formField.label }}\n </label>\n }\n </div>\n\n @if (\n formGroup.get(formField.name)?.errors &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.checkbox-container{display:flex;align-items:center;gap:.5rem;min-height:2.75rem}.checkbox-container .checkbox-label{display:inline-flex;align-items:center;margin:0;padding:0;font-weight:600;font-size:1rem;line-height:1;cursor:pointer}.checkbox-container ::ng-deep .p-checkbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.checkbox-container ::ng-deep .p-checkbox-box{width:1.25rem;height:1.25rem}.error-container{margin-top:.25rem}.p-error{font-size:.8rem;color:#f44336}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }] }); }
1852
1989
  }
1853
1990
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTCheckBoxInputComponent, decorators: [{
1854
1991
  type: Component,
1855
- args: [{ selector: 'pt-check-box-input', standalone: false, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n <div class=\"checkbox-container\">\n <p-checkbox\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [binary]=\"true\"\n ></p-checkbox>\n @if (formField.label) {\n <label [for]=\"inputId\" class=\"checkbox-label\">\n {{ formField.label }}\n </label>\n }\n </div>\n @if (\n formGroup.get(formField.name)?.errors &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div\n class=\"error-container\"\n >\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700;font-size:1rem}.checkbox-container{display:flex;align-items:center}.p-error{font-size:.8rem;color:#f44336}\n"] }]
1992
+ args: [{ selector: 'pt-check-box-input', standalone: false, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n <div class=\"checkbox-container\">\n <p-checkbox\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [binary]=\"true\"\n ></p-checkbox>\n\n @if (formField.label) {\n <label [for]=\"inputId\" class=\"checkbox-label\">\n {{ formField.label }}\n </label>\n }\n </div>\n\n @if (\n formGroup.get(formField.name)?.errors &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.checkbox-container{display:flex;align-items:center;gap:.5rem;min-height:2.75rem}.checkbox-container .checkbox-label{display:inline-flex;align-items:center;margin:0;padding:0;font-weight:600;font-size:1rem;line-height:1;cursor:pointer}.checkbox-container ::ng-deep .p-checkbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.checkbox-container ::ng-deep .p-checkbox-box{width:1.25rem;height:1.25rem}.error-container{margin-top:.25rem}.p-error{font-size:.8rem;color:#f44336}\n"] }]
1856
1993
  }], propDecorators: { formGroup: [{
1857
1994
  type: Input
1858
1995
  }], formField: [{
@@ -1990,79 +2127,187 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1990
2127
  class PTDateInputComponent {
1991
2128
  constructor(dateService) {
1992
2129
  this.dateService = dateService;
2130
+ /**
2131
+ * Two-way standalone value.
2132
+ */
2133
+ this.value = null;
2134
+ this.valueChange = new EventEmitter();
2135
+ this.dateChange = new EventEmitter();
1993
2136
  this.minDate = null;
1994
2137
  this.maxDate = null;
1995
2138
  this.defaultPlaceholder = 'Select date';
1996
2139
  this.defaultDateFormat = 'dd/mm/yy';
2140
+ this.standaloneFormGroup = new FormGroup({});
1997
2141
  }
1998
2142
  ngOnInit() {
1999
- this.defaultDateFormat = this.dateService.assignDefaultDateFormat(this.formField.dateInputType || 'date', this.formField.dateFormat);
2000
- this.setupControl();
2001
- this.initializeDateLimits();
2002
- try {
2003
- this.dateService.validateDateFormatAndType(this.defaultDateFormat, this.formField.dateInputType || 'date', this.formField.minValue, this.formField.maxValue, this.formField.hourFormat || '24');
2004
- }
2005
- catch (error) {
2006
- if (error instanceof Error) {
2007
- console.error(error.message);
2008
- }
2009
- else {
2010
- console.error('An unknown error occurred.');
2011
- }
2143
+ this.initializeComponent();
2144
+ }
2145
+ ngOnChanges(changes) {
2146
+ if (changes['formGroup'] ||
2147
+ changes['formField'] ||
2148
+ changes['config'] ||
2149
+ changes['value']) {
2150
+ this.initializeComponent();
2012
2151
  }
2013
- this.defaultPlaceholder = getDefaultPlaceholder(this.formField.dateInputType || 'date');
2152
+ }
2153
+ ngOnDestroy() {
2154
+ this.valueChangesSubscription?.unsubscribe();
2155
+ }
2156
+ get activeFormGroup() {
2157
+ return this.formGroup || this.standaloneFormGroup;
2158
+ }
2159
+ get controlName() {
2160
+ return this.formField?.name || this.config?.name || 'date';
2014
2161
  }
2015
2162
  get inputId() {
2016
- return `pt-date-${this.formField?.name || 'field'}`;
2163
+ return `pt-date-${this.controlName}`;
2164
+ }
2165
+ get resolvedHidden() {
2166
+ return this.formField?.hidden ?? this.config?.hidden ?? false;
2167
+ }
2168
+ get resolvedLabel() {
2169
+ return this.formField?.label || this.config?.label;
2170
+ }
2171
+ get resolvedWidth() {
2172
+ return this.formField?.width || this.config?.width || '100%';
2173
+ }
2174
+ get resolvedPlaceholder() {
2175
+ return (this.formField?.placeholder ||
2176
+ this.config?.placeholder ||
2177
+ this.defaultPlaceholder);
2178
+ }
2179
+ get resolvedDateInputType() {
2180
+ return (this.formField?.dateInputType ||
2181
+ this.config?.dateInputType ||
2182
+ 'date');
2183
+ }
2184
+ get resolvedDateFormat() {
2185
+ return (this.formField?.dateFormat ||
2186
+ this.config?.dateFormat ||
2187
+ this.defaultDateFormat);
2188
+ }
2189
+ get resolvedHourFormat() {
2190
+ return (this.formField?.hourFormat ||
2191
+ this.config?.hourFormat ||
2192
+ '24');
2193
+ }
2194
+ get resolvedRequired() {
2195
+ return this.formField?.required ?? this.config?.required ?? false;
2196
+ }
2197
+ get resolvedDisabled() {
2198
+ return this.formField?.disabled ?? this.config?.disabled ?? false;
2199
+ }
2200
+ get resolvedShowIcon() {
2201
+ return this.config?.showIcon ?? true;
2202
+ }
2203
+ get resolvedMinValue() {
2204
+ return this.formField?.minValue || this.config?.minValue;
2205
+ }
2206
+ get resolvedMaxValue() {
2207
+ return this.formField?.maxValue || this.config?.maxValue;
2208
+ }
2209
+ get resolvedErrorText() {
2210
+ return this.formField?.errorText || this.config?.errorText;
2211
+ }
2212
+ initializeComponent() {
2213
+ this.defaultDateFormat = this.dateService.assignDefaultDateFormat(this.resolvedDateInputType, this.formField?.dateFormat || this.config?.dateFormat);
2214
+ this.setupControl();
2215
+ this.initializeDateLimits();
2216
+ this.validateConfiguration();
2217
+ this.defaultPlaceholder = getDefaultPlaceholder(this.resolvedDateInputType);
2017
2218
  }
2018
2219
  setupControl() {
2019
- let control = this.formGroup.get(this.formField.name);
2220
+ const name = this.controlName;
2221
+ if (!name) {
2222
+ return;
2223
+ }
2224
+ let control = this.activeFormGroup.get(name);
2020
2225
  if (!control) {
2021
- control = new FormControl(null);
2022
- this.formGroup.addControl(this.formField.name, control);
2226
+ control = new FormControl(this.getInitialValue());
2227
+ this.activeFormGroup.addControl(name, control);
2228
+ }
2229
+ if (!this.formGroup &&
2230
+ this.value !== undefined &&
2231
+ control.value !== this.value) {
2232
+ control.setValue(this.value, { emitEvent: false });
2023
2233
  }
2024
2234
  control.setValidators(this.getValidators());
2025
- if (this.formField.disabled) {
2235
+ if (this.resolvedDisabled) {
2026
2236
  control.disable({ emitEvent: false });
2027
2237
  }
2028
2238
  else {
2029
2239
  control.enable({ emitEvent: false });
2030
2240
  }
2031
2241
  control.updateValueAndValidity({ emitEvent: false });
2242
+ this.valueChangesSubscription?.unsubscribe();
2243
+ this.valueChangesSubscription = control.valueChanges.subscribe((selectedValue) => {
2244
+ this.valueChange.emit(selectedValue);
2245
+ this.dateChange.emit(selectedValue);
2246
+ });
2247
+ }
2248
+ getInitialValue() {
2249
+ if (this.formField?.value !== undefined) {
2250
+ return this.formField.value;
2251
+ }
2252
+ if (this.value !== undefined && this.value !== null) {
2253
+ return this.value;
2254
+ }
2255
+ return this.config?.value ?? null;
2032
2256
  }
2033
2257
  initializeDateLimits() {
2034
- const dateFormat = this.formField.dateFormat;
2035
- if (this.formField.minValue) {
2036
- this.minDate = parseDate(this.formField.minValue, dateFormat);
2258
+ this.minDate = this.resolvedMinValue
2259
+ ? parseDate(this.resolvedMinValue, this.resolvedDateFormat)
2260
+ : null;
2261
+ this.maxDate = this.resolvedMaxValue
2262
+ ? parseDate(this.resolvedMaxValue, this.resolvedDateFormat)
2263
+ : null;
2264
+ }
2265
+ validateConfiguration() {
2266
+ try {
2267
+ this.dateService.validateDateFormatAndType(this.resolvedDateFormat, this.resolvedDateInputType, this.resolvedMinValue, this.resolvedMaxValue, this.resolvedHourFormat);
2037
2268
  }
2038
- if (this.formField.maxValue) {
2039
- this.maxDate = parseDate(this.formField.maxValue, dateFormat);
2269
+ catch (error) {
2270
+ if (error instanceof Error) {
2271
+ console.error(error.message);
2272
+ }
2273
+ else {
2274
+ console.error('An unknown error occurred.');
2275
+ }
2040
2276
  }
2041
2277
  }
2042
2278
  getValidators() {
2043
2279
  const validators = [];
2044
- if (this.formField.required) {
2280
+ if (this.resolvedRequired) {
2045
2281
  validators.push(Validators.required);
2046
2282
  }
2047
2283
  return validators;
2048
2284
  }
2049
2285
  getErrorMessage() {
2050
- const control = this.formGroup.get(this.formField.name);
2286
+ const control = this.activeFormGroup.get(this.controlName);
2051
2287
  if (control?.hasError('required')) {
2052
- return this.formField.errorText || `${this.formField.label} is required`;
2288
+ return (this.resolvedErrorText ||
2289
+ `${this.resolvedLabel || this.controlName} is required`);
2053
2290
  }
2054
2291
  return '';
2055
2292
  }
2056
2293
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDateInputComponent, deps: [{ token: PTDateService }], target: i0.ɵɵFactoryTarget.Component }); }
2057
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDateInputComponent, isStandalone: false, selector: "pt-date-input", inputs: { formGroup: "formGroup", formField: "formField" }, ngImport: i0, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\">\n {{ formField.label }}\n </label>\n }\n <p-datepicker\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder || defaultPlaceholder\"\n [dateFormat]=\"formField.dateFormat || defaultDateFormat\"\n [showIcon]=\"true\"\n [minDate]=\"minDate\"\n [maxDate]=\"maxDate\"\n [showTime]=\"\n formField.dateInputType === 'datetime' ||\n formField.dateInputType === 'time'\n \"\n [timeOnly]=\"formField.dateInputType === 'time'\"\n [hourFormat]=\"formField.hourFormat || '24'\"\n [selectionMode]=\"formField.dateInputType === 'range' ? 'range' : 'single'\"\n appendTo=\"body\"\n [panelStyle]=\"{ zIndex: 99999 }\"\n ></p-datepicker>\n @if (\n formGroup.get(formField.name)?.invalid &&\n formGroup.get(formField.name)?.touched\n ) {\n <div\n >\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem;overflow:visible}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i7.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }] }); }
2294
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDateInputComponent, isStandalone: false, selector: "pt-date-input", inputs: { formGroup: "formGroup", formField: "formField", config: "config", value: "value" }, outputs: { valueChange: "valueChange", dateChange: "dateChange" }, usesOnChanges: true, ngImport: i0, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: resolvedWidth }\"\n >\n @if (resolvedLabel) {\n <label [for]=\"inputId\" class=\"field-label\">\n {{ resolvedLabel }}\n </label>\n }\n\n <p-datepicker\n [inputId]=\"inputId\"\n [name]=\"controlName\"\n [formControlName]=\"controlName\"\n [placeholder]=\"resolvedPlaceholder\"\n [dateFormat]=\"resolvedDateFormat\"\n [showIcon]=\"resolvedShowIcon\"\n [minDate]=\"minDate\"\n [maxDate]=\"maxDate\"\n [showTime]=\"\n resolvedDateInputType === 'datetime' || resolvedDateInputType === 'time'\n \"\n [timeOnly]=\"resolvedDateInputType === 'time'\"\n [hourFormat]=\"resolvedHourFormat\"\n [selectionMode]=\"resolvedDateInputType === 'range' ? 'range' : 'single'\"\n appendTo=\"body\"\n [panelStyle]=\"{ zIndex: 99999 }\"\n ></p-datepicker>\n\n @if (\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem;overflow:visible}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-datepicker.ng-invalid.ng-touched .p-inputtext,.form-field ::ng-deep .p-datepicker.ng-invalid.ng-dirty .p-inputtext{border-color:#dc2626}.form-field ::ng-deep .p-datepicker-input.ng-invalid.ng-touched,.form-field ::ng-deep .p-datepicker-input.ng-invalid.ng-dirty{border-color:#dc2626}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i7.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }] }); }
2058
2295
  }
2059
2296
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDateInputComponent, decorators: [{
2060
2297
  type: Component,
2061
- args: [{ selector: 'pt-date-input', standalone: false, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\">\n {{ formField.label }}\n </label>\n }\n <p-datepicker\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder || defaultPlaceholder\"\n [dateFormat]=\"formField.dateFormat || defaultDateFormat\"\n [showIcon]=\"true\"\n [minDate]=\"minDate\"\n [maxDate]=\"maxDate\"\n [showTime]=\"\n formField.dateInputType === 'datetime' ||\n formField.dateInputType === 'time'\n \"\n [timeOnly]=\"formField.dateInputType === 'time'\"\n [hourFormat]=\"formField.hourFormat || '24'\"\n [selectionMode]=\"formField.dateInputType === 'range' ? 'range' : 'single'\"\n appendTo=\"body\"\n [panelStyle]=\"{ zIndex: 99999 }\"\n ></p-datepicker>\n @if (\n formGroup.get(formField.name)?.invalid &&\n formGroup.get(formField.name)?.touched\n ) {\n <div\n >\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem;overflow:visible}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"] }]
2298
+ args: [{ selector: 'pt-date-input', standalone: false, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: resolvedWidth }\"\n >\n @if (resolvedLabel) {\n <label [for]=\"inputId\" class=\"field-label\">\n {{ resolvedLabel }}\n </label>\n }\n\n <p-datepicker\n [inputId]=\"inputId\"\n [name]=\"controlName\"\n [formControlName]=\"controlName\"\n [placeholder]=\"resolvedPlaceholder\"\n [dateFormat]=\"resolvedDateFormat\"\n [showIcon]=\"resolvedShowIcon\"\n [minDate]=\"minDate\"\n [maxDate]=\"maxDate\"\n [showTime]=\"\n resolvedDateInputType === 'datetime' || resolvedDateInputType === 'time'\n \"\n [timeOnly]=\"resolvedDateInputType === 'time'\"\n [hourFormat]=\"resolvedHourFormat\"\n [selectionMode]=\"resolvedDateInputType === 'range' ? 'range' : 'single'\"\n appendTo=\"body\"\n [panelStyle]=\"{ zIndex: 99999 }\"\n ></p-datepicker>\n\n @if (\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem;overflow:visible}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-datepicker.ng-invalid.ng-touched .p-inputtext,.form-field ::ng-deep .p-datepicker.ng-invalid.ng-dirty .p-inputtext{border-color:#dc2626}.form-field ::ng-deep .p-datepicker-input.ng-invalid.ng-touched,.form-field ::ng-deep .p-datepicker-input.ng-invalid.ng-dirty{border-color:#dc2626}\n"] }]
2062
2299
  }], ctorParameters: () => [{ type: PTDateService }], propDecorators: { formGroup: [{
2063
2300
  type: Input
2064
2301
  }], formField: [{
2065
2302
  type: Input
2303
+ }], config: [{
2304
+ type: Input
2305
+ }], value: [{
2306
+ type: Input
2307
+ }], valueChange: [{
2308
+ type: Output
2309
+ }], dateChange: [{
2310
+ type: Output
2066
2311
  }] } });
2067
2312
 
2068
2313
  class PTNumberInputComponent {
@@ -2146,11 +2391,11 @@ class PTNumberInputComponent {
2146
2391
  return '';
2147
2392
  }
2148
2393
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTNumberInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2149
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTNumberInputComponent, isStandalone: false, selector: "pt-number-input", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\">\n {{ formField.label }}\n </label>\n }\n <p-inputGroup>\n @if (!formField.iconPosition || formField.iconPosition === 'left') {\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\"></i>\n }\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n <p-inputNumber\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits || 0\"\n [maxFractionDigits]=\"formField.decimalDigits || 0\"\n [placeholder]=\"formField.placeholder || ''\"\n ></p-inputNumber>\n }\n @if (formField.iconPosition === 'right') {\n <p-inputNumber\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits || 0\"\n [maxFractionDigits]=\"formField.decimalDigits || 0\"\n [placeholder]=\"formField.placeholder || ''\"\n ></p-inputNumber>\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\"></i>\n }\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n }\n </p-inputGroup>\n @if (\n formGroup.get(formField.name)?.invalid &&\n formGroup.get(formField.name)?.touched\n ) {\n <div\n >\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$2.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "component", type: i4.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "component", type: i8$1.InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "placeholder", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "autocomplete", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }] }); }
2394
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTNumberInputComponent, isStandalone: false, selector: "pt-number-input", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\" class=\"field-label\">\n {{ formField.label }}\n </label>\n }\n\n <p-inputGroup>\n @if (!formField.iconPosition || formField.iconPosition === \"left\") {\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\"></i>\n }\n\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n\n <p-inputNumber\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits || 0\"\n [maxFractionDigits]=\"formField.decimalDigits || 0\"\n [placeholder]=\"formField.placeholder || ''\"\n ></p-inputNumber>\n }\n\n @if (formField.iconPosition === \"right\") {\n <p-inputNumber\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits || 0\"\n [maxFractionDigits]=\"formField.decimalDigits || 0\"\n [placeholder]=\"formField.placeholder || ''\"\n ></p-inputNumber>\n\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\"></i>\n }\n\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n }\n </p-inputGroup>\n\n @if (\n formGroup.get(formField.name)?.invalid &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.form-field ::ng-deep .p-inputnumber{width:100%}.form-field ::ng-deep .p-inputnumber-input{width:100%}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-inputnumber.ng-invalid.ng-touched .p-inputnumber-input,.form-field ::ng-deep .p-inputnumber.ng-invalid.ng-dirty .p-inputnumber-input{border-color:#dc2626}.form-field ::ng-deep .p-inputnumber-input.ng-invalid.ng-touched,.form-field ::ng-deep .p-inputnumber-input.ng-invalid.ng-dirty{border-color:#dc2626}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$2.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "component", type: i4.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "component", type: i8$1.InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "placeholder", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "autocomplete", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }] }); }
2150
2395
  }
2151
2396
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTNumberInputComponent, decorators: [{
2152
2397
  type: Component,
2153
- args: [{ selector: 'pt-number-input', standalone: false, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\">\n {{ formField.label }}\n </label>\n }\n <p-inputGroup>\n @if (!formField.iconPosition || formField.iconPosition === 'left') {\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\"></i>\n }\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n <p-inputNumber\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits || 0\"\n [maxFractionDigits]=\"formField.decimalDigits || 0\"\n [placeholder]=\"formField.placeholder || ''\"\n ></p-inputNumber>\n }\n @if (formField.iconPosition === 'right') {\n <p-inputNumber\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits || 0\"\n [maxFractionDigits]=\"formField.decimalDigits || 0\"\n [placeholder]=\"formField.placeholder || ''\"\n ></p-inputNumber>\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\"></i>\n }\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n }\n </p-inputGroup>\n @if (\n formGroup.get(formField.name)?.invalid &&\n formGroup.get(formField.name)?.touched\n ) {\n <div\n >\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"] }]
2398
+ args: [{ selector: 'pt-number-input', standalone: false, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\" class=\"field-label\">\n {{ formField.label }}\n </label>\n }\n\n <p-inputGroup>\n @if (!formField.iconPosition || formField.iconPosition === \"left\") {\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\"></i>\n }\n\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n\n <p-inputNumber\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits || 0\"\n [maxFractionDigits]=\"formField.decimalDigits || 0\"\n [placeholder]=\"formField.placeholder || ''\"\n ></p-inputNumber>\n }\n\n @if (formField.iconPosition === \"right\") {\n <p-inputNumber\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits || 0\"\n [maxFractionDigits]=\"formField.decimalDigits || 0\"\n [placeholder]=\"formField.placeholder || ''\"\n ></p-inputNumber>\n\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\"></i>\n }\n\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n }\n </p-inputGroup>\n\n @if (\n formGroup.get(formField.name)?.invalid &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.form-field ::ng-deep .p-inputnumber{width:100%}.form-field ::ng-deep .p-inputnumber-input{width:100%}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-inputnumber.ng-invalid.ng-touched .p-inputnumber-input,.form-field ::ng-deep .p-inputnumber.ng-invalid.ng-dirty .p-inputnumber-input{border-color:#dc2626}.form-field ::ng-deep .p-inputnumber-input.ng-invalid.ng-touched,.form-field ::ng-deep .p-inputnumber-input.ng-invalid.ng-dirty{border-color:#dc2626}\n"] }]
2154
2399
  }], propDecorators: { formGroup: [{
2155
2400
  type: Input
2156
2401
  }], formField: [{
@@ -2210,11 +2455,11 @@ class PTSwitchInputComponent {
2210
2455
  return '';
2211
2456
  }
2212
2457
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTSwitchInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2213
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTSwitchInputComponent, isStandalone: false, selector: "pt-switch-input", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n <div class=\"switch-container\" style=\"display: flex; align-items: center\">\n <p-toggleswitch\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n ></p-toggleswitch>\n\n @if (formField.label) {\n <label [for]=\"inputId\" style=\"margin-left: 8px\">\n {{ formField.label }}\n </label>\n }\n </div>\n\n @if (\n formGroup.get(formField.name)?.errors &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".switch-container{display:flex;align-items:center}.error-container{margin-top:5px}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$3.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }] }); }
2458
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTSwitchInputComponent, isStandalone: false, selector: "pt-switch-input", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n <div class=\"switch-container\">\n <p-toggleswitch\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n ></p-toggleswitch>\n\n @if (formField.label) {\n <label [for]=\"inputId\" class=\"switch-label\">\n {{ formField.label }}\n </label>\n }\n </div>\n\n @if (\n formGroup.get(formField.name)?.errors &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.switch-container{display:flex;align-items:center;gap:.5rem;min-height:2.75rem}.switch-label{display:inline-flex;align-items:center;margin:0;padding:0;font-weight:600;font-size:1rem;line-height:1;cursor:pointer}.error-container{margin-top:.25rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-toggleswitch.ng-invalid.ng-touched .p-toggleswitch-slider,.form-field ::ng-deep .p-toggleswitch.ng-invalid.ng-dirty .p-toggleswitch-slider{border-color:#dc2626}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$3.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }] }); }
2214
2459
  }
2215
2460
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTSwitchInputComponent, decorators: [{
2216
2461
  type: Component,
2217
- args: [{ selector: 'pt-switch-input', standalone: false, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n <div class=\"switch-container\" style=\"display: flex; align-items: center\">\n <p-toggleswitch\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n ></p-toggleswitch>\n\n @if (formField.label) {\n <label [for]=\"inputId\" style=\"margin-left: 8px\">\n {{ formField.label }}\n </label>\n }\n </div>\n\n @if (\n formGroup.get(formField.name)?.errors &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".switch-container{display:flex;align-items:center}.error-container{margin-top:5px}\n"] }]
2462
+ args: [{ selector: 'pt-switch-input', standalone: false, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n <div class=\"switch-container\">\n <p-toggleswitch\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n ></p-toggleswitch>\n\n @if (formField.label) {\n <label [for]=\"inputId\" class=\"switch-label\">\n {{ formField.label }}\n </label>\n }\n </div>\n\n @if (\n formGroup.get(formField.name)?.errors &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.switch-container{display:flex;align-items:center;gap:.5rem;min-height:2.75rem}.switch-label{display:inline-flex;align-items:center;margin:0;padding:0;font-weight:600;font-size:1rem;line-height:1;cursor:pointer}.error-container{margin-top:.25rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-toggleswitch.ng-invalid.ng-touched .p-toggleswitch-slider,.form-field ::ng-deep .p-toggleswitch.ng-invalid.ng-dirty .p-toggleswitch-slider{border-color:#dc2626}\n"] }]
2218
2463
  }], propDecorators: { formGroup: [{
2219
2464
  type: Input
2220
2465
  }], formField: [{
@@ -2369,6 +2614,15 @@ class PTTextInputComponent {
2369
2614
  return 'text';
2370
2615
  }
2371
2616
  }
2617
+ isPasswordInput() {
2618
+ return this.formField.type === FormInputTypeEnum.PASSWORD;
2619
+ }
2620
+ getPasswordToggleMask() {
2621
+ return this.formField.toggleMask ?? true;
2622
+ }
2623
+ getPasswordFeedback() {
2624
+ return this.formField.feedback ?? false;
2625
+ }
2372
2626
  getValidators() {
2373
2627
  const validators = [];
2374
2628
  if (this.formField.required) {
@@ -2411,11 +2665,11 @@ class PTTextInputComponent {
2411
2665
  return '';
2412
2666
  }
2413
2667
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTTextInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2414
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTTextInputComponent, isStandalone: false, selector: "pt-text-input", inputs: { formGroup: "formGroup", formField: "formField" }, ngImport: i0, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\">\n {{ formField.label }}\n </label>\n }\n @if (formField.iconClass) {\n <p-iconField [iconPosition]=\"formField.iconPosition || 'left'\">\n @if (formField.iconClass) {\n <p-inputIcon\n [styleClass]=\"formField.iconClass\"\n ></p-inputIcon>\n }\n <input\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n pInputText\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n />\n </p-iconField>\n } @else {\n <input\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n pInputText\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n />\n }\n <div class=\"form-info-row\">\n @if (\n formGroup.get(formField.name)?.invalid &&\n formGroup.get(formField.name)?.touched\n ) {\n <small\n class=\"p-error\"\n >\n {{ getErrorMessage() }}\n </small>\n }\n <div class=\"spacer\"></div>\n @if (!formField.disabled && formField.maxLength !== undefined) {\n <div\n class=\"character-counter\"\n >\n {{ characterCount }}/{{ formField.maxLength }} characters\n </div>\n }\n </div>\n </div>\n}\n", styles: [".form-field{position:relative}.form-field label{display:block;margin-bottom:.5rem;font-weight:700;font-size:1rem}.form-info-row{display:flex;justify-content:space-between;align-items:center;margin-top:.5rem}.spacer{flex-grow:1}.character-counter{font-size:.8rem;color:#888;text-align:right;margin-left:auto}.p-error{font-size:.8rem;color:#f44336}input:focus{outline:none;box-shadow:none;border-color:inherit}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i10.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "component", type: i11.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }] }); }
2668
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTTextInputComponent, isStandalone: false, selector: "pt-text-input", inputs: { formGroup: "formGroup", formField: "formField" }, ngImport: i0, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n margin: formField.margin || null,\n }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\" class=\"field-label\">\n {{ formField.label }}\n </label>\n }\n\n @if (formField.iconClass) {\n <p-iconField [iconPosition]=\"formField.iconPosition || 'left'\">\n <p-inputIcon [styleClass]=\"formField.iconClass\"></p-inputIcon>\n\n @if (isPasswordInput()) {\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [inputStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n } @else {\n <input\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n pInputText\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n />\n }\n </p-iconField>\n } @else {\n @if (isPasswordInput()) {\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [inputStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n } @else {\n <input\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n pInputText\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n />\n }\n }\n\n <div class=\"form-info-row\">\n @if (\n formGroup.get(formField.name)?.invalid &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n }\n\n <div class=\"spacer\"></div>\n\n @if (!formField.disabled && formField.maxLength !== undefined) {\n <div class=\"character-counter\">\n {{ characterCount }}/{{ formField.maxLength }} characters\n </div>\n }\n </div>\n </div>\n}\n", styles: [":host{display:block;width:100%}.form-field{width:100%}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.form-info-row{display:flex;align-items:center;gap:.5rem;min-height:1.25rem;margin-top:.35rem}.spacer{flex:1 1 auto}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.character-counter{font-size:.8rem;font-weight:500;color:#64748b;white-space:nowrap}.form-field input.ng-invalid.ng-touched,.form-field input.ng-invalid.ng-dirty{border-color:#dc2626}::ng-deep .pt-password-input{width:100%!important;display:block!important}::ng-deep .pt-password-input .p-password{width:100%!important;display:block!important}::ng-deep .pt-password-input .p-password-input{width:100%!important}::ng-deep .pt-password-input input{width:100%!important;box-sizing:border-box}::ng-deep .pt-password-input.ng-invalid.ng-touched input,::ng-deep .pt-password-input.ng-invalid.ng-dirty input,::ng-deep .pt-password-input input.ng-invalid.ng-touched,::ng-deep .pt-password-input input.ng-invalid.ng-dirty{border-color:#dc2626}::ng-deep .pt-password-input .p-password-toggle-mask-icon,::ng-deep .pt-password-input .p-password-toggle-mask{right:1rem}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i10.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "component", type: i11.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "component", type: i6$1.Password, selector: "p-password", inputs: ["ariaLabel", "ariaLabelledBy", "label", "promptLabel", "mediumRegex", "strongRegex", "weakLabel", "mediumLabel", "maxLength", "strongLabel", "inputId", "feedback", "toggleMask", "inputStyleClass", "styleClass", "inputStyle", "showTransitionOptions", "hideTransitionOptions", "autocomplete", "placeholder", "showClear", "autofocus", "tabindex", "appendTo", "motionOptions", "overlayOptions"], outputs: ["onFocus", "onBlur", "onClear"] }] }); }
2415
2669
  }
2416
2670
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTTextInputComponent, decorators: [{
2417
2671
  type: Component,
2418
- args: [{ selector: 'pt-text-input', standalone: false, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\">\n {{ formField.label }}\n </label>\n }\n @if (formField.iconClass) {\n <p-iconField [iconPosition]=\"formField.iconPosition || 'left'\">\n @if (formField.iconClass) {\n <p-inputIcon\n [styleClass]=\"formField.iconClass\"\n ></p-inputIcon>\n }\n <input\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n pInputText\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n />\n </p-iconField>\n } @else {\n <input\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n pInputText\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n />\n }\n <div class=\"form-info-row\">\n @if (\n formGroup.get(formField.name)?.invalid &&\n formGroup.get(formField.name)?.touched\n ) {\n <small\n class=\"p-error\"\n >\n {{ getErrorMessage() }}\n </small>\n }\n <div class=\"spacer\"></div>\n @if (!formField.disabled && formField.maxLength !== undefined) {\n <div\n class=\"character-counter\"\n >\n {{ characterCount }}/{{ formField.maxLength }} characters\n </div>\n }\n </div>\n </div>\n}\n", styles: [".form-field{position:relative}.form-field label{display:block;margin-bottom:.5rem;font-weight:700;font-size:1rem}.form-info-row{display:flex;justify-content:space-between;align-items:center;margin-top:.5rem}.spacer{flex-grow:1}.character-counter{font-size:.8rem;color:#888;text-align:right;margin-left:auto}.p-error{font-size:.8rem;color:#f44336}input:focus{outline:none;box-shadow:none;border-color:inherit}\n"] }]
2672
+ args: [{ selector: 'pt-text-input', standalone: false, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n margin: formField.margin || null,\n }\"\n >\n @if (formField.label) {\n <label [for]=\"inputId\" class=\"field-label\">\n {{ formField.label }}\n </label>\n }\n\n @if (formField.iconClass) {\n <p-iconField [iconPosition]=\"formField.iconPosition || 'left'\">\n <p-inputIcon [styleClass]=\"formField.iconClass\"></p-inputIcon>\n\n @if (isPasswordInput()) {\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [inputStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n } @else {\n <input\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n pInputText\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n />\n }\n </p-iconField>\n } @else {\n @if (isPasswordInput()) {\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [inputStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n } @else {\n <input\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n pInputText\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n }\"\n />\n }\n }\n\n <div class=\"form-info-row\">\n @if (\n formGroup.get(formField.name)?.invalid &&\n (formGroup.get(formField.name)?.touched ||\n formGroup.get(formField.name)?.dirty)\n ) {\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n }\n\n <div class=\"spacer\"></div>\n\n @if (!formField.disabled && formField.maxLength !== undefined) {\n <div class=\"character-counter\">\n {{ characterCount }}/{{ formField.maxLength }} characters\n </div>\n }\n </div>\n </div>\n}\n", styles: [":host{display:block;width:100%}.form-field{width:100%}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.form-info-row{display:flex;align-items:center;gap:.5rem;min-height:1.25rem;margin-top:.35rem}.spacer{flex:1 1 auto}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.character-counter{font-size:.8rem;font-weight:500;color:#64748b;white-space:nowrap}.form-field input.ng-invalid.ng-touched,.form-field input.ng-invalid.ng-dirty{border-color:#dc2626}::ng-deep .pt-password-input{width:100%!important;display:block!important}::ng-deep .pt-password-input .p-password{width:100%!important;display:block!important}::ng-deep .pt-password-input .p-password-input{width:100%!important}::ng-deep .pt-password-input input{width:100%!important;box-sizing:border-box}::ng-deep .pt-password-input.ng-invalid.ng-touched input,::ng-deep .pt-password-input.ng-invalid.ng-dirty input,::ng-deep .pt-password-input input.ng-invalid.ng-touched,::ng-deep .pt-password-input input.ng-invalid.ng-dirty{border-color:#dc2626}::ng-deep .pt-password-input .p-password-toggle-mask-icon,::ng-deep .pt-password-input .p-password-toggle-mask{right:1rem}\n"] }]
2419
2673
  }], propDecorators: { formGroup: [{
2420
2674
  type: Input
2421
2675
  }], formField: [{
@@ -2423,42 +2677,125 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2423
2677
  }] } });
2424
2678
 
2425
2679
  class PTDropdownComponent {
2680
+ constructor() {
2681
+ /**
2682
+ * Two-way standalone value.
2683
+ */
2684
+ this.value = null;
2685
+ this.valueChange = new EventEmitter();
2686
+ this.selectionChange = new EventEmitter();
2687
+ this.standaloneFormGroup = new FormGroup({});
2688
+ }
2426
2689
  ngOnInit() {
2427
2690
  this.setupControl();
2428
2691
  }
2429
2692
  ngOnChanges(changes) {
2430
- if (changes['formField'] && !changes['formField'].firstChange) {
2693
+ if (changes['formGroup'] ||
2694
+ changes['formField'] ||
2695
+ changes['config'] ||
2696
+ changes['value']) {
2431
2697
  this.setupControl();
2432
2698
  }
2433
2699
  }
2700
+ ngOnDestroy() {
2701
+ this.valueChangesSubscription?.unsubscribe();
2702
+ }
2703
+ get activeFormGroup() {
2704
+ return this.formGroup || this.standaloneFormGroup;
2705
+ }
2706
+ get controlName() {
2707
+ return this.formField?.name || this.config?.name || 'dropdown';
2708
+ }
2434
2709
  get inputId() {
2435
- return `pt-dropdown-${this.formField?.name || 'field'}`;
2710
+ return `pt-dropdown-${this.controlName}`;
2436
2711
  }
2437
2712
  get labelId() {
2438
- return `pt-dropdown-label-${this.formField?.name || 'field'}`;
2713
+ return `pt-dropdown-label-${this.controlName}`;
2714
+ }
2715
+ get resolvedHidden() {
2716
+ return this.formField?.hidden ?? this.config?.hidden ?? false;
2717
+ }
2718
+ get resolvedLabel() {
2719
+ return this.formField?.label || this.config?.label;
2720
+ }
2721
+ get resolvedWidth() {
2722
+ return this.formField?.width || this.config?.width || '100%';
2723
+ }
2724
+ get resolvedOptions() {
2725
+ return this.formField?.options || this.config?.options || [];
2726
+ }
2727
+ get resolvedPlaceholder() {
2728
+ return (this.formField?.placeholder ||
2729
+ this.config?.placeholder ||
2730
+ 'Select an option');
2731
+ }
2732
+ get resolvedOptionLabel() {
2733
+ return this.formField?.optionLabel || this.config?.optionLabel || 'label';
2734
+ }
2735
+ get resolvedOptionValue() {
2736
+ return this.formField?.optionValue || this.config?.optionValue || 'value';
2737
+ }
2738
+ get resolvedOptionDisabled() {
2739
+ return (this.formField?.optionDisabled ||
2740
+ this.config?.optionDisabled ||
2741
+ 'disabled');
2742
+ }
2743
+ get resolvedFilter() {
2744
+ return this.formField?.filter === true || this.config?.filter === true;
2745
+ }
2746
+ get resolvedFilterBy() {
2747
+ return this.formField?.filterBy || this.config?.filterBy || 'label';
2748
+ }
2749
+ get resolvedRequired() {
2750
+ return this.formField?.required ?? this.config?.required ?? false;
2751
+ }
2752
+ get resolvedDisabled() {
2753
+ return this.formField?.disabled ?? this.config?.disabled ?? false;
2754
+ }
2755
+ get resolvedErrorText() {
2756
+ return this.formField?.errorText || this.config?.errorText;
2757
+ }
2758
+ get resolvedIcon() {
2759
+ return this.formField?.icon || this.config?.icon;
2439
2760
  }
2440
2761
  setupControl() {
2441
- if (!this.formGroup || !this.formField?.name) {
2762
+ const name = this.controlName;
2763
+ if (!name) {
2442
2764
  return;
2443
2765
  }
2444
- const hasExplicitValue = this.hasExplicitFieldValue(this.formField.value);
2445
- const normalizedValue = this.normalizeValue(this.formField.value);
2446
- let control = this.formGroup.get(this.formField.name);
2766
+ const initialValue = this.getInitialValue();
2767
+ const hasExplicitValue = this.hasExplicitFieldValue(initialValue);
2768
+ const normalizedValue = this.normalizeValue(initialValue);
2769
+ let control = this.activeFormGroup.get(name);
2447
2770
  if (!control) {
2448
2771
  control = new FormControl(hasExplicitValue ? normalizedValue : null);
2449
- this.formGroup.addControl(this.formField.name, control);
2772
+ this.activeFormGroup.addControl(name, control);
2450
2773
  }
2451
- else if (hasExplicitValue) {
2452
- control.setValue(normalizedValue, { emitEvent: false });
2774
+ else if (!this.formGroup && this.hasExplicitFieldValue(this.value)) {
2775
+ control.setValue(this.normalizeValue(this.value), { emitEvent: false });
2453
2776
  }
2454
2777
  control.setValidators(this.getValidators());
2455
- if (this.formField.disabled) {
2778
+ if (this.resolvedDisabled) {
2456
2779
  control.disable({ emitEvent: false });
2457
2780
  }
2458
2781
  else {
2459
2782
  control.enable({ emitEvent: false });
2460
2783
  }
2461
2784
  control.updateValueAndValidity({ emitEvent: false });
2785
+ this.valueChangesSubscription?.unsubscribe();
2786
+ this.valueChangesSubscription = control.valueChanges.subscribe((selectedValue) => {
2787
+ this.valueChange.emit(selectedValue);
2788
+ this.selectionChange.emit(selectedValue);
2789
+ });
2790
+ }
2791
+ getInitialValue() {
2792
+ if (this.formField?.value !== undefined) {
2793
+ return this.formField.value;
2794
+ }
2795
+ if (this.value !== undefined && this.value !== null && this.value !== '') {
2796
+ return this.value;
2797
+ }
2798
+ return this.config?.value ?? null;
2462
2799
  }
2463
2800
  hasExplicitFieldValue(value) {
2464
2801
  return value !== null && value !== undefined && value !== '';
@@ -2474,15 +2811,16 @@ class PTDropdownComponent {
2474
2811
  }
2475
2812
  getValidators() {
2476
2813
  const validators = [];
2477
- if (this.formField.required) {
2814
+ if (this.resolvedRequired) {
2478
2815
  validators.push(Validators.required);
2479
2816
  }
2480
2817
  return validators;
2481
2818
  }
2482
2819
  getErrorMessage() {
2483
- const control = this.formGroup.get(this.formField.name);
2820
+ const control = this.activeFormGroup.get(this.controlName);
2484
2821
  if (control?.hasError('required')) {
2485
- return this.formField.errorText || `${this.formField.label} is required`;
2822
+ return (this.resolvedErrorText ||
2823
+ `${this.resolvedLabel || this.controlName} is required`);
2486
2824
  }
2487
2825
  return '';
2488
2826
  }
@@ -2490,7 +2828,7 @@ class PTDropdownComponent {
2490
2828
  const source = option?.iconStyle ||
2491
2829
  option?.iconImageStyle ||
2492
2830
  option?.icon ||
2493
- this.formField.icon;
2831
+ this.resolvedIcon;
2494
2832
  if (!source) {
2495
2833
  return { type: 'none' };
2496
2834
  }
@@ -2547,18 +2885,24 @@ class PTDropdownComponent {
2547
2885
  }
2548
2886
  buildImageStyle(icon) {
2549
2887
  const styles = {};
2550
- if (icon.width)
2888
+ if (icon.width) {
2551
2889
  styles.width = icon.width;
2552
- if (icon.height)
2890
+ }
2891
+ if (icon.height) {
2553
2892
  styles.height = icon.height;
2554
- if (icon.marginLeft)
2893
+ }
2894
+ if (icon.marginLeft) {
2555
2895
  styles['margin-left'] = icon.marginLeft;
2556
- if (icon.marginRight)
2896
+ }
2897
+ if (icon.marginRight) {
2557
2898
  styles['margin-right'] = icon.marginRight;
2558
- if (icon.marginTop)
2899
+ }
2900
+ if (icon.marginTop) {
2559
2901
  styles['margin-top'] = icon.marginTop;
2560
- if (icon.marginBottom)
2902
+ }
2903
+ if (icon.marginBottom) {
2561
2904
  styles['margin-bottom'] = icon.marginBottom;
2905
+ }
2562
2906
  if (icon.shape === 'circular') {
2563
2907
  styles['border-radius'] = '50%';
2564
2908
  }
@@ -2571,7 +2915,7 @@ class PTDropdownComponent {
2571
2915
  const src = option?.iconStyle ||
2572
2916
  option?.iconImageStyle ||
2573
2917
  option?.icon ||
2574
- this.formField.icon;
2918
+ this.resolvedIcon;
2575
2919
  if (this.isIconStyle(src) && src.position) {
2576
2920
  return src.position;
2577
2921
  }
@@ -2581,15 +2925,23 @@ class PTDropdownComponent {
2581
2925
  return 'left';
2582
2926
  }
2583
2927
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2584
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDropdownComponent, isStandalone: false, selector: "pt-dropdown", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n @if (formField.label) {\n <label [id]=\"labelId\">\n {{ formField.label }}\n </label>\n }\n <p-select\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [options]=\"formField.options\"\n [placeholder]=\"formField.placeholder || 'Select an option'\"\n [optionLabel]=\"formField.optionLabel || 'label'\"\n [optionValue]=\"formField.optionValue || 'value'\"\n [optionDisabled]=\"formField.optionDisabled || 'disabled'\"\n dataKey=\"value\"\n [filter]=\"formField.filter === true\"\n [filterBy]=\"formField.filterBy || 'label'\"\n [appendTo]=\"'body'\"\n [overlayOptions]=\"{ baseZIndex: 11000 }\"\n [ariaLabelledBy]=\"labelId\"\n >\n <ng-template pTemplate=\"selectedItem\" let-option>\n @if (option) {\n <div class=\"pt-dropdown-item\">\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === 'image') {\n <img\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n class=\"pt-dropdown-icon-image\"\n />\n }\n @if (iconMeta.type === 'font') {\n <i\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n class=\"pt-dropdown-icon-font\"\n ></i>\n }\n }\n <span class=\"pt-dropdown-label\">{{ option.label }}</span>\n </div>\n } @else {\n <span>{{ formField.placeholder || \"Select an option\" }}</span>\n }\n </ng-template>\n <ng-template pTemplate=\"item\" let-option>\n <div\n class=\"pt-dropdown-item\"\n [class.pt-dropdown-parent-option]=\"option?.isParent\"\n [class.pt-dropdown-child-option]=\"option?.isChild\"\n [class.pt-dropdown-disabled-option]=\"option?.disabled\"\n [ngStyle]=\"{ 'padding-left': option?.indent || '0rem' }\"\n >\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === 'image') {\n <img\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n class=\"pt-dropdown-icon-image\"\n />\n }\n @if (iconMeta.type === 'font') {\n <i\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n class=\"pt-dropdown-icon-font\"\n ></i>\n }\n }\n <span class=\"pt-dropdown-label\">{{ option.label }}</span>\n </div>\n </ng-template>\n </p-select>\n @if (\n formGroup.get(formField.name)?.invalid &&\n formGroup.get(formField.name)?.touched\n ) {\n <div\n >\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{display:flex;flex-direction:column;margin-bottom:1rem;gap:.25rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700;font-size:1rem}.pt-dropdown-item{display:flex;align-items:center;gap:.5rem}.pt-dropdown-icon-font{display:inline-flex;align-items:center;justify-content:center}.pt-dropdown-label{display:inline-block}.pt-dropdown-item{display:flex;align-items:center;gap:.55rem}.pt-dropdown-parent-option{font-weight:700}.pt-dropdown-child-option{font-weight:400}.pt-dropdown-disabled-option{opacity:.65;cursor:not-allowed}.pt-dropdown-icon-font{width:1.25rem;text-align:center}.pt-dropdown-icon-image{object-fit:cover}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }] }); }
2928
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDropdownComponent, isStandalone: false, selector: "pt-dropdown", inputs: { formGroup: "formGroup", formField: "formField", config: "config", value: "value" }, outputs: { valueChange: "valueChange", selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: resolvedWidth }\"\n >\n @if (resolvedLabel) {\n <label [id]=\"labelId\" class=\"field-label\">\n {{ resolvedLabel }}\n </label>\n }\n\n <p-select\n [inputId]=\"inputId\"\n [name]=\"controlName\"\n [formControlName]=\"controlName\"\n [options]=\"resolvedOptions\"\n [placeholder]=\"resolvedPlaceholder\"\n [optionLabel]=\"resolvedOptionLabel\"\n [optionValue]=\"resolvedOptionValue\"\n [optionDisabled]=\"resolvedOptionDisabled\"\n [dataKey]=\"resolvedOptionValue\"\n [filter]=\"resolvedFilter\"\n [filterBy]=\"resolvedFilterBy\"\n [appendTo]=\"'body'\"\n [overlayOptions]=\"{ baseZIndex: 11000 }\"\n [ariaLabelledBy]=\"labelId\"\n >\n <ng-template pTemplate=\"selectedItem\" let-option>\n @if (option) {\n <div class=\"pt-dropdown-item\">\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === \"image\") {\n <img\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n class=\"pt-dropdown-icon-image\"\n />\n }\n\n @if (iconMeta.type === \"font\") {\n <i\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n class=\"pt-dropdown-icon-font\"\n ></i>\n }\n }\n\n <span class=\"pt-dropdown-label\">\n {{ option[resolvedOptionLabel] }}\n </span>\n </div>\n } @else {\n <span>{{ resolvedPlaceholder }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-option>\n <div\n class=\"pt-dropdown-item\"\n [class.pt-dropdown-parent-option]=\"option?.isParent\"\n [class.pt-dropdown-child-option]=\"option?.isChild\"\n [class.pt-dropdown-disabled-option]=\"option?.disabled\"\n [ngStyle]=\"{ 'padding-left': option?.indent || '0rem' }\"\n >\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === \"image\") {\n <img\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n class=\"pt-dropdown-icon-image\"\n />\n }\n\n @if (iconMeta.type === \"font\") {\n <i\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n class=\"pt-dropdown-icon-font\"\n ></i>\n }\n }\n\n <span class=\"pt-dropdown-label\">\n {{ option[resolvedOptionLabel] }}\n </span>\n </div>\n </ng-template>\n </p-select>\n\n @if (\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{display:flex;flex-direction:column;margin-bottom:1rem;gap:.25rem}.field-label{display:block;margin-bottom:.5rem;font-weight:700;font-size:1rem}.pt-dropdown-item{display:flex;align-items:center;gap:.55rem}.pt-dropdown-label{display:inline-block}.pt-dropdown-parent-option{font-weight:700}.pt-dropdown-child-option{font-weight:400}.pt-dropdown-disabled-option{opacity:.65;cursor:not-allowed}.pt-dropdown-icon-font{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;text-align:center}.pt-dropdown-icon-image{object-fit:cover}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-select.ng-invalid.ng-touched{border-color:#dc2626}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }] }); }
2585
2929
  }
2586
2930
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDropdownComponent, decorators: [{
2587
2931
  type: Component,
2588
- args: [{ selector: 'pt-dropdown', standalone: false, template: "@if (!formField.hidden) {\n <div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: formField.width || '100%' }\"\n >\n @if (formField.label) {\n <label [id]=\"labelId\">\n {{ formField.label }}\n </label>\n }\n <p-select\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [options]=\"formField.options\"\n [placeholder]=\"formField.placeholder || 'Select an option'\"\n [optionLabel]=\"formField.optionLabel || 'label'\"\n [optionValue]=\"formField.optionValue || 'value'\"\n [optionDisabled]=\"formField.optionDisabled || 'disabled'\"\n dataKey=\"value\"\n [filter]=\"formField.filter === true\"\n [filterBy]=\"formField.filterBy || 'label'\"\n [appendTo]=\"'body'\"\n [overlayOptions]=\"{ baseZIndex: 11000 }\"\n [ariaLabelledBy]=\"labelId\"\n >\n <ng-template pTemplate=\"selectedItem\" let-option>\n @if (option) {\n <div class=\"pt-dropdown-item\">\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === 'image') {\n <img\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n class=\"pt-dropdown-icon-image\"\n />\n }\n @if (iconMeta.type === 'font') {\n <i\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n class=\"pt-dropdown-icon-font\"\n ></i>\n }\n }\n <span class=\"pt-dropdown-label\">{{ option.label }}</span>\n </div>\n } @else {\n <span>{{ formField.placeholder || \"Select an option\" }}</span>\n }\n </ng-template>\n <ng-template pTemplate=\"item\" let-option>\n <div\n class=\"pt-dropdown-item\"\n [class.pt-dropdown-parent-option]=\"option?.isParent\"\n [class.pt-dropdown-child-option]=\"option?.isChild\"\n [class.pt-dropdown-disabled-option]=\"option?.disabled\"\n [ngStyle]=\"{ 'padding-left': option?.indent || '0rem' }\"\n >\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === 'image') {\n <img\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n class=\"pt-dropdown-icon-image\"\n />\n }\n @if (iconMeta.type === 'font') {\n <i\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n class=\"pt-dropdown-icon-font\"\n ></i>\n }\n }\n <span class=\"pt-dropdown-label\">{{ option.label }}</span>\n </div>\n </ng-template>\n </p-select>\n @if (\n formGroup.get(formField.name)?.invalid &&\n formGroup.get(formField.name)?.touched\n ) {\n <div\n >\n <small class=\"p-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{display:flex;flex-direction:column;margin-bottom:1rem;gap:.25rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700;font-size:1rem}.pt-dropdown-item{display:flex;align-items:center;gap:.5rem}.pt-dropdown-icon-font{display:inline-flex;align-items:center;justify-content:center}.pt-dropdown-label{display:inline-block}.pt-dropdown-item{display:flex;align-items:center;gap:.55rem}.pt-dropdown-parent-option{font-weight:700}.pt-dropdown-child-option{font-weight:400}.pt-dropdown-disabled-option{opacity:.65;cursor:not-allowed}.pt-dropdown-icon-font{width:1.25rem;text-align:center}.pt-dropdown-icon-image{object-fit:cover}\n"] }]
2932
+ args: [{ selector: 'pt-dropdown', standalone: false, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: resolvedWidth }\"\n >\n @if (resolvedLabel) {\n <label [id]=\"labelId\" class=\"field-label\">\n {{ resolvedLabel }}\n </label>\n }\n\n <p-select\n [inputId]=\"inputId\"\n [name]=\"controlName\"\n [formControlName]=\"controlName\"\n [options]=\"resolvedOptions\"\n [placeholder]=\"resolvedPlaceholder\"\n [optionLabel]=\"resolvedOptionLabel\"\n [optionValue]=\"resolvedOptionValue\"\n [optionDisabled]=\"resolvedOptionDisabled\"\n [dataKey]=\"resolvedOptionValue\"\n [filter]=\"resolvedFilter\"\n [filterBy]=\"resolvedFilterBy\"\n [appendTo]=\"'body'\"\n [overlayOptions]=\"{ baseZIndex: 11000 }\"\n [ariaLabelledBy]=\"labelId\"\n >\n <ng-template pTemplate=\"selectedItem\" let-option>\n @if (option) {\n <div class=\"pt-dropdown-item\">\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === \"image\") {\n <img\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n class=\"pt-dropdown-icon-image\"\n />\n }\n\n @if (iconMeta.type === \"font\") {\n <i\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n class=\"pt-dropdown-icon-font\"\n ></i>\n }\n }\n\n <span class=\"pt-dropdown-label\">\n {{ option[resolvedOptionLabel] }}\n </span>\n </div>\n } @else {\n <span>{{ resolvedPlaceholder }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-option>\n <div\n class=\"pt-dropdown-item\"\n [class.pt-dropdown-parent-option]=\"option?.isParent\"\n [class.pt-dropdown-child-option]=\"option?.isChild\"\n [class.pt-dropdown-disabled-option]=\"option?.disabled\"\n [ngStyle]=\"{ 'padding-left': option?.indent || '0rem' }\"\n >\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === \"image\") {\n <img\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n class=\"pt-dropdown-icon-image\"\n />\n }\n\n @if (iconMeta.type === \"font\") {\n <i\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n class=\"pt-dropdown-icon-font\"\n ></i>\n }\n }\n\n <span class=\"pt-dropdown-label\">\n {{ option[resolvedOptionLabel] }}\n </span>\n </div>\n </ng-template>\n </p-select>\n\n @if (\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{display:flex;flex-direction:column;margin-bottom:1rem;gap:.25rem}.field-label{display:block;margin-bottom:.5rem;font-weight:700;font-size:1rem}.pt-dropdown-item{display:flex;align-items:center;gap:.55rem}.pt-dropdown-label{display:inline-block}.pt-dropdown-parent-option{font-weight:700}.pt-dropdown-child-option{font-weight:400}.pt-dropdown-disabled-option{opacity:.65;cursor:not-allowed}.pt-dropdown-icon-font{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;text-align:center}.pt-dropdown-icon-image{object-fit:cover}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-select.ng-invalid.ng-touched{border-color:#dc2626}\n"] }]
2589
2933
  }], propDecorators: { formGroup: [{
2590
2934
  type: Input
2591
2935
  }], formField: [{
2592
2936
  type: Input
2937
+ }], config: [{
2938
+ type: Input
2939
+ }], value: [{
2940
+ type: Input
2941
+ }], valueChange: [{
2942
+ type: Output
2943
+ }], selectionChange: [{
2944
+ type: Output
2593
2945
  }] } });
2594
2946
 
2595
2947
  class PTDynamicFormFieldComponent {
@@ -2621,7 +2973,7 @@ class PTDynamicFormFieldComponent {
2621
2973
  return field;
2622
2974
  }
2623
2975
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDynamicFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2624
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDynamicFormFieldComponent, isStandalone: false, selector: "pt-dynamic-form-field", inputs: { field: "field", form: "form", inputWidth: "inputWidth" }, ngImport: i0, template: "<div\n [formGroup]=\"form\"\n class=\"form-field\"\n [ngStyle]=\"{\n width:\n field.type !== FormInputTypeEnum.CHECKBOX &&\n field.type !== FormInputTypeEnum.SWITCH\n ? field.width || inputWidth\n : 'auto'\n }\"\n >\n @switch (field.type) {\n <!-- TEXT -->\n @case (FormInputTypeEnum.TEXT) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n <!-- EMAIL (NEW) -->\n @case (FormInputTypeEnum.EMAIL) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n <!-- NUMBER -->\n @case (FormInputTypeEnum.NUMBER) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n <!-- AMOUNT -->\n @case (FormInputTypeEnum.AMOUNT) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n <!-- TEXTAREA -->\n @case (FormInputTypeEnum.TEXTAREA) {\n <pt-text-area-input\n [formGroup]=\"form\"\n [formField]=\"asTextAreaField(field)\"\n ></pt-text-area-input>\n }\n <!-- DATE -->\n @case (FormInputTypeEnum.DATE) {\n <pt-date-input\n [formGroup]=\"form\"\n [formField]=\"asDateField(field)\"\n ></pt-date-input>\n }\n <!-- MULTISELECT -->\n @case (FormInputTypeEnum.MULTISELECT) {\n <pt-multi-select\n [formGroup]=\"form\"\n [formField]=\"asMultiSelectField(field)\"\n ></pt-multi-select>\n }\n <!-- SELECT -->\n @case (FormInputTypeEnum.SELECT) {\n <pt-dropdown\n [formGroup]=\"form\"\n [formField]=\"asSelectField(field)\"\n ></pt-dropdown>\n }\n <!-- CHECKBOX -->\n @case (FormInputTypeEnum.CHECKBOX) {\n <pt-check-box-input\n [formGroup]=\"form\"\n [formField]=\"asCheckboxField(field)\"\n ></pt-check-box-input>\n }\n <!-- SWITCH -->\n @case (FormInputTypeEnum.SWITCH) {\n <pt-switch-input\n [formGroup]=\"form\"\n [formField]=\"asSwitchField(field)\"\n ></pt-switch-input>\n }\n }\n</div>\n", styles: [".form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: PTCheckBoxInputComponent, selector: "pt-check-box-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTDateInputComponent, selector: "pt-date-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTNumberInputComponent, selector: "pt-number-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTSwitchInputComponent, selector: "pt-switch-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTTextAreaInputComponent, selector: "pt-text-area-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTTextInputComponent, selector: "pt-text-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTDropdownComponent, selector: "pt-dropdown", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTMultiSelectComponent, selector: "pt-multi-select", inputs: ["formGroup", "formField"] }] }); }
2976
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDynamicFormFieldComponent, isStandalone: false, selector: "pt-dynamic-form-field", inputs: { field: "field", form: "form", inputWidth: "inputWidth" }, ngImport: i0, template: "<div\n [formGroup]=\"form\"\n class=\"form-field\"\n [ngStyle]=\"{\n width:\n field.type !== FormInputTypeEnum.CHECKBOX &&\n field.type !== FormInputTypeEnum.SWITCH\n ? field.width || inputWidth\n : 'auto'\n }\"\n >\n @switch (field.type) {\n <!-- TEXT -->\n @case (FormInputTypeEnum.TEXT) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n <!-- EMAIL (NEW) -->\n @case (FormInputTypeEnum.EMAIL) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n <!-- NUMBER -->\n @case (FormInputTypeEnum.NUMBER) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n <!-- AMOUNT -->\n @case (FormInputTypeEnum.AMOUNT) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n <!-- TEXTAREA -->\n @case (FormInputTypeEnum.TEXTAREA) {\n <pt-text-area-input\n [formGroup]=\"form\"\n [formField]=\"asTextAreaField(field)\"\n ></pt-text-area-input>\n }\n <!-- DATE -->\n @case (FormInputTypeEnum.DATE) {\n <pt-date-input\n [formGroup]=\"form\"\n [formField]=\"asDateField(field)\"\n ></pt-date-input>\n }\n <!-- MULTISELECT -->\n @case (FormInputTypeEnum.MULTISELECT) {\n <pt-multi-select\n [formGroup]=\"form\"\n [formField]=\"asMultiSelectField(field)\"\n ></pt-multi-select>\n }\n <!-- SELECT -->\n @case (FormInputTypeEnum.SELECT) {\n <pt-dropdown\n [formGroup]=\"form\"\n [formField]=\"asSelectField(field)\"\n ></pt-dropdown>\n }\n <!-- CHECKBOX -->\n @case (FormInputTypeEnum.CHECKBOX) {\n <pt-check-box-input\n [formGroup]=\"form\"\n [formField]=\"asCheckboxField(field)\"\n ></pt-check-box-input>\n }\n <!-- SWITCH -->\n @case (FormInputTypeEnum.SWITCH) {\n <pt-switch-input\n [formGroup]=\"form\"\n [formField]=\"asSwitchField(field)\"\n ></pt-switch-input>\n }\n }\n</div>\n", styles: [".form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: PTCheckBoxInputComponent, selector: "pt-check-box-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTDateInputComponent, selector: "pt-date-input", inputs: ["formGroup", "formField", "config", "value"], outputs: ["valueChange", "dateChange"] }, { kind: "component", type: PTNumberInputComponent, selector: "pt-number-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTSwitchInputComponent, selector: "pt-switch-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTTextAreaInputComponent, selector: "pt-text-area-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTTextInputComponent, selector: "pt-text-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTDropdownComponent, selector: "pt-dropdown", inputs: ["formGroup", "formField", "config", "value"], outputs: ["valueChange", "selectionChange"] }, { kind: "component", type: PTMultiSelectComponent, selector: "pt-multi-select", inputs: ["formGroup", "formField", "config", "value"], outputs: ["valueChange", "selectionChange"] }] }); }
2625
2977
  }
2626
2978
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDynamicFormFieldComponent, decorators: [{
2627
2979
  type: Component,
@@ -2766,11 +3118,11 @@ class PTFormBuilderComponent {
2766
3118
  this.formChange.emit(this.form.getRawValue());
2767
3119
  }
2768
3120
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTFormBuilderComponent, deps: [{ token: i2.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
2769
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTFormBuilderComponent, isStandalone: false, selector: "pt-form-builder", inputs: { mainGroup: "mainGroup", buttons: "buttons", title: "title", titleStyle: "titleStyle", inputWidth: "inputWidth", formWidth: "formWidth", language: "language" }, outputs: { formSubmit: "formSubmit", formReady: "formReady", formChange: "formChange" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"pt-form-builder-wrapper\"\n [ngStyle]=\"{ width: formWidth, maxWidth: formWidth }\"\n >\n @if (title) {\n <div [ngStyle]=\"titleStyle\" class=\"form-title\">{{ title }}</div>\n }\n\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n @for (field of mainGroup.fields; track field) {\n <pt-dynamic-form-field\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n ></pt-dynamic-form-field>\n }\n\n @for (group of mainGroup.groups; track group) {\n <div\n class=\"form-field-group\"\n [ngStyle]=\"{ width: group.width || '100%' }\"\n >\n @for (field of group.fields; track field) {\n <pt-dynamic-form-field\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n class=\"flex-item\"\n ></pt-dynamic-form-field>\n }\n </div>\n }\n\n <div class=\"button-group\">\n @for (button of buttons; track button) {\n <button\n type=\"button\"\n pButton\n [label]=\"button.text\"\n [icon]=\"button.icon || ''\"\n [class]=\"button.color\"\n (click)=\"\n button.isSubmit\n ? onSubmit()\n : button.isClear\n ? onClear()\n : button.action\n ? button.action()\n : null\n \"\n ></button>\n }\n </div>\n </form>\n</div>\n", styles: [".pt-form-builder-wrapper{width:100%;margin:0 auto}.form-title{text-align:center;margin-bottom:1rem;font-size:1.5rem;font-weight:700}.form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}::ng-deep .p-inputtext,::ng-deep .p-inputtextarea,::ng-deep .p-calendar,::ng-deep .p-inputnumber,::ng-deep .p-multiselect,::ng-deep .p-dropdown{width:100%!important}::ng-deep .p-inputnumber,::ng-deep p-inputnumber{display:flex!important}.button-group{display:flex;gap:1rem;margin-top:1rem;justify-content:space-between}.button-group button{flex:1;display:flex;align-items:center;justify-content:center}.button-group button i{margin-right:.5rem}.button-group button.p-button-primary{background-color:#007bff;color:#fff}.button-group button.p-button-secondary{background-color:#6c757d;color:#fff}.button-group button.p-button-success{background-color:#28a745;color:#fff}.button-group button:hover{opacity:.9}.form-field-group{display:flex;gap:1rem}.form-field-group .flex-item{flex:1}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: PTDynamicFormFieldComponent, selector: "pt-dynamic-form-field", inputs: ["field", "form", "inputWidth"] }] }); }
3121
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTFormBuilderComponent, isStandalone: false, selector: "pt-form-builder", inputs: { mainGroup: "mainGroup", buttons: "buttons", title: "title", titleStyle: "titleStyle", inputWidth: "inputWidth", formWidth: "formWidth", language: "language" }, outputs: { formSubmit: "formSubmit", formReady: "formReady", formChange: "formChange" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"pt-form-builder-wrapper\"\n [ngStyle]=\"{ width: formWidth, maxWidth: formWidth }\"\n>\n @if (title) {\n <div [ngStyle]=\"titleStyle\" class=\"form-title\">{{ title }}</div>\n }\n\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n @for (field of mainGroup.fields; track field.name) {\n <pt-dynamic-form-field\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n ></pt-dynamic-form-field>\n }\n\n @for (group of mainGroup.groups; track $index) {\n <div\n class=\"form-field-group\"\n [ngStyle]=\"{ width: group.width || '100%' }\"\n >\n @for (field of group.fields; track field.name) {\n <pt-dynamic-form-field\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n class=\"flex-item\"\n ></pt-dynamic-form-field>\n }\n </div>\n }\n\n <div class=\"button-group\">\n @for (button of buttons; track button.text) {\n <button\n type=\"button\"\n pButton\n [label]=\"button.text\"\n [icon]=\"button.icon || ''\"\n [class]=\"button.color || ''\"\n [ngStyle]=\"{\n color: button.fontColor || null,\n 'background-color': button.backgroundColor || null,\n 'border-color':\n button.borderColor || button.backgroundColor || null,\n }\"\n (click)=\"\n button.isSubmit\n ? onSubmit()\n : button.isClear\n ? onClear()\n : button.action\n ? button.action()\n : null\n \"\n ></button>\n }\n </div>\n </form>\n</div>\n", styles: [".pt-form-builder-wrapper{width:100%;margin:0 auto}.form-title{text-align:center;margin-bottom:1rem;font-size:1.5rem;font-weight:700}.form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}::ng-deep .p-inputtext,::ng-deep .p-inputtextarea,::ng-deep .p-calendar,::ng-deep .p-inputnumber,::ng-deep .p-multiselect,::ng-deep .p-dropdown{width:100%!important}::ng-deep .p-inputnumber,::ng-deep p-inputnumber{display:flex!important}.button-group{display:flex;gap:1rem;margin-top:1rem;justify-content:space-between}.button-group button{flex:1;display:flex;align-items:center;justify-content:center}.button-group button i{margin-right:.5rem}.button-group button.p-button-primary{background-color:#007bff;color:#fff}.button-group button.p-button-secondary{background-color:#6c757d;color:#fff}.button-group button.p-button-success{background-color:#28a745;color:#fff}.button-group button:hover{opacity:.9}.form-field-group{display:flex;gap:1rem}.form-field-group .flex-item{flex:1}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: PTDynamicFormFieldComponent, selector: "pt-dynamic-form-field", inputs: ["field", "form", "inputWidth"] }] }); }
2770
3122
  }
2771
3123
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTFormBuilderComponent, decorators: [{
2772
3124
  type: Component,
2773
- args: [{ selector: 'pt-form-builder', standalone: false, template: "<div\n class=\"pt-form-builder-wrapper\"\n [ngStyle]=\"{ width: formWidth, maxWidth: formWidth }\"\n >\n @if (title) {\n <div [ngStyle]=\"titleStyle\" class=\"form-title\">{{ title }}</div>\n }\n\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n @for (field of mainGroup.fields; track field) {\n <pt-dynamic-form-field\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n ></pt-dynamic-form-field>\n }\n\n @for (group of mainGroup.groups; track group) {\n <div\n class=\"form-field-group\"\n [ngStyle]=\"{ width: group.width || '100%' }\"\n >\n @for (field of group.fields; track field) {\n <pt-dynamic-form-field\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n class=\"flex-item\"\n ></pt-dynamic-form-field>\n }\n </div>\n }\n\n <div class=\"button-group\">\n @for (button of buttons; track button) {\n <button\n type=\"button\"\n pButton\n [label]=\"button.text\"\n [icon]=\"button.icon || ''\"\n [class]=\"button.color\"\n (click)=\"\n button.isSubmit\n ? onSubmit()\n : button.isClear\n ? onClear()\n : button.action\n ? button.action()\n : null\n \"\n ></button>\n }\n </div>\n </form>\n</div>\n", styles: [".pt-form-builder-wrapper{width:100%;margin:0 auto}.form-title{text-align:center;margin-bottom:1rem;font-size:1.5rem;font-weight:700}.form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}::ng-deep .p-inputtext,::ng-deep .p-inputtextarea,::ng-deep .p-calendar,::ng-deep .p-inputnumber,::ng-deep .p-multiselect,::ng-deep .p-dropdown{width:100%!important}::ng-deep .p-inputnumber,::ng-deep p-inputnumber{display:flex!important}.button-group{display:flex;gap:1rem;margin-top:1rem;justify-content:space-between}.button-group button{flex:1;display:flex;align-items:center;justify-content:center}.button-group button i{margin-right:.5rem}.button-group button.p-button-primary{background-color:#007bff;color:#fff}.button-group button.p-button-secondary{background-color:#6c757d;color:#fff}.button-group button.p-button-success{background-color:#28a745;color:#fff}.button-group button:hover{opacity:.9}.form-field-group{display:flex;gap:1rem}.form-field-group .flex-item{flex:1}\n"] }]
3125
+ args: [{ selector: 'pt-form-builder', standalone: false, template: "<div\n class=\"pt-form-builder-wrapper\"\n [ngStyle]=\"{ width: formWidth, maxWidth: formWidth }\"\n>\n @if (title) {\n <div [ngStyle]=\"titleStyle\" class=\"form-title\">{{ title }}</div>\n }\n\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n @for (field of mainGroup.fields; track field.name) {\n <pt-dynamic-form-field\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n ></pt-dynamic-form-field>\n }\n\n @for (group of mainGroup.groups; track $index) {\n <div\n class=\"form-field-group\"\n [ngStyle]=\"{ width: group.width || '100%' }\"\n >\n @for (field of group.fields; track field.name) {\n <pt-dynamic-form-field\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n class=\"flex-item\"\n ></pt-dynamic-form-field>\n }\n </div>\n }\n\n <div class=\"button-group\">\n @for (button of buttons; track button.text) {\n <button\n type=\"button\"\n pButton\n [label]=\"button.text\"\n [icon]=\"button.icon || ''\"\n [class]=\"button.color || ''\"\n [ngStyle]=\"{\n color: button.fontColor || null,\n 'background-color': button.backgroundColor || null,\n 'border-color':\n button.borderColor || button.backgroundColor || null,\n }\"\n (click)=\"\n button.isSubmit\n ? onSubmit()\n : button.isClear\n ? onClear()\n : button.action\n ? button.action()\n : null\n \"\n ></button>\n }\n </div>\n </form>\n</div>\n", styles: [".pt-form-builder-wrapper{width:100%;margin:0 auto}.form-title{text-align:center;margin-bottom:1rem;font-size:1.5rem;font-weight:700}.form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}::ng-deep .p-inputtext,::ng-deep .p-inputtextarea,::ng-deep .p-calendar,::ng-deep .p-inputnumber,::ng-deep .p-multiselect,::ng-deep .p-dropdown{width:100%!important}::ng-deep .p-inputnumber,::ng-deep p-inputnumber{display:flex!important}.button-group{display:flex;gap:1rem;margin-top:1rem;justify-content:space-between}.button-group button{flex:1;display:flex;align-items:center;justify-content:center}.button-group button i{margin-right:.5rem}.button-group button.p-button-primary{background-color:#007bff;color:#fff}.button-group button.p-button-secondary{background-color:#6c757d;color:#fff}.button-group button.p-button-success{background-color:#28a745;color:#fff}.button-group button:hover{opacity:.9}.form-field-group{display:flex;gap:1rem}.form-field-group .flex-item{flex:1}\n"] }]
2774
3126
  }], ctorParameters: () => [{ type: i2.FormBuilder }], propDecorators: { mainGroup: [{
2775
3127
  type: Input
2776
3128
  }], buttons: [{
@@ -2858,15 +3210,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2858
3210
  class PTTextInputModule {
2859
3211
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTTextInputModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2860
3212
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.14", ngImport: i0, type: PTTextInputModule, declarations: [PTTextInputComponent], imports: [CommonModule,
3213
+ FormsModule,
2861
3214
  ReactiveFormsModule,
2862
3215
  InputTextModule,
2863
3216
  IconFieldModule,
2864
- InputIconModule], exports: [PTTextInputComponent] }); }
3217
+ InputIconModule,
3218
+ PasswordModule], exports: [PTTextInputComponent] }); }
2865
3219
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTTextInputModule, imports: [CommonModule,
3220
+ FormsModule,
2866
3221
  ReactiveFormsModule,
2867
3222
  InputTextModule,
2868
3223
  IconFieldModule,
2869
- InputIconModule] }); }
3224
+ InputIconModule,
3225
+ PasswordModule] }); }
2870
3226
  }
2871
3227
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTTextInputModule, decorators: [{
2872
3228
  type: NgModule,
@@ -2874,10 +3230,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2874
3230
  declarations: [PTTextInputComponent],
2875
3231
  imports: [
2876
3232
  CommonModule,
3233
+ FormsModule,
2877
3234
  ReactiveFormsModule,
2878
3235
  InputTextModule,
2879
3236
  IconFieldModule,
2880
3237
  InputIconModule,
3238
+ PasswordModule,
2881
3239
  ],
2882
3240
  exports: [PTTextInputComponent],
2883
3241
  }]
@@ -4687,6 +5045,10 @@ class PTLoginCardComponent {
4687
5045
  placeholder: this.loginPageConfig.passwordField?.placeholder ||
4688
5046
  'Entrer votre mot de passe',
4689
5047
  type: this.loginPageConfig.passwordField?.type || FormInputTypeEnum.PASSWORD,
5048
+ // Show / hide password is now handled by pt-text-input via PrimeNG p-password.
5049
+ toggleMask: this.loginPageConfig.passwordField?.toggleMask ?? true,
5050
+ // Disabled by default for login forms.
5051
+ feedback: this.loginPageConfig.passwordField?.feedback ?? false,
4690
5052
  ...this.loginPageConfig.passwordField,
4691
5053
  };
4692
5054
  // Initialize buttonConfig
@@ -4722,7 +5084,7 @@ class PTLoginCardComponent {
4722
5084
  this.formGroup.addControl(this.loginPageConfig.passwordField.name, this.fb.control(this.loginPageConfig.login?.password, passwordValidators));
4723
5085
  }
4724
5086
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTLoginCardComponent, deps: [{ token: i2.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
4725
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTLoginCardComponent, isStandalone: true, selector: "pt-login-card", inputs: { loginPageConfig: "loginPageConfig", loginErrorMessage: "loginErrorMessage" }, outputs: { loginSubmit: "loginSubmit" }, ngImport: i0, template: "<pt-card [config]=\"loginPageConfig.loginCardConfig!\">\n <!-- Logo -->\n @if (loginPageConfig.logoUrl?.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"loginPageConfig.logoUrl?.imageUrl\"\n [alt]=\"loginPageConfig.logoUrl?.altText || 'Logo'\"\n [style.width]=\"loginPageConfig.logoUrl?.width || '100px'\"\n [style.height]=\"loginPageConfig.logoUrl?.height || 'auto'\"\n />\n </div>\n }\n\n <!-- Title -->\n <div class=\"title-container\">\n <h1\n [ngStyle]=\"{\n color: loginPageConfig.title?.color || '#333',\n 'font-size': loginPageConfig.title?.fontSize || '24px'\n }\"\n >\n {{ loginPageConfig.title?.text || \"Default Title\" }}\n </h1>\n </div>\n <!-- Error Message -->\n @if (loginErrorMessage) {\n <div class=\"error-message\">\n {{ loginErrorMessage }}\n </div>\n }\n <!-- Form -->\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (loginPageConfig.login?.errorMessage) {\n <div class=\"error-message\">\n {{ loginPageConfig.login?.errorMessage }}\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.usernameField!\"\n ></pt-text-input>\n </div>\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.passwordField!\"\n ></pt-text-input>\n </div>\n\n <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"loginPageConfig.buttonConfig!\"></pt-button>\n </div>\n </form>\n <div class=\"login-footer\">\n {{ loginPageConfig.footer?.version }}\n <span>{{ loginPageConfig.footer?.copyright }}</span>\n </div>\n</pt-card>\n", styles: [".logo-container{display:flex;justify-content:center;align-items:center;margin-bottom:20px}.title-container{text-align:center;margin-bottom:20px}.form-container{width:100%}.field{display:flex;flex-direction:column;margin-bottom:20px;width:100%}.error-message{color:red;background-color:#ffe6e6;border:1px solid red;padding:10px;margin-bottom:10px;border-radius:5px;width:100%;text-align:center}.submit-btn{display:flex;justify-content:center;width:100%}::ng-deep pt-button{width:100%}::ng-deep .submit-btn p-button button{width:100%}.login-footer{margin-top:20px;text-align:center;font-size:.9em;color:#555}@media(max-width:768px){pt-card{max-width:300px}.submit-btn{min-width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PTCardModule }, { kind: "component", type: PTCardComponent, selector: "pt-card", inputs: ["config"] }, { kind: "ngmodule", type: PTButtonModule }, { kind: "component", type: PTButtonComponent, selector: "pt-button", inputs: ["buttonConfig"] }, { kind: "ngmodule", type: PTTextInputModule }, { kind: "component", type: PTTextInputComponent, selector: "pt-text-input", inputs: ["formGroup", "formField"] }] }); }
5087
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTLoginCardComponent, isStandalone: true, selector: "pt-login-card", inputs: { loginPageConfig: "loginPageConfig", loginErrorMessage: "loginErrorMessage" }, outputs: { loginSubmit: "loginSubmit" }, ngImport: i0, template: "<pt-card [config]=\"loginPageConfig.loginCardConfig!\">\n <!-- Logo -->\n @if (loginPageConfig.logoUrl?.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"loginPageConfig.logoUrl?.imageUrl\"\n [alt]=\"loginPageConfig.logoUrl?.altText || 'Logo'\"\n [style.width]=\"loginPageConfig.logoUrl?.width || '100px'\"\n [style.height]=\"loginPageConfig.logoUrl?.height || 'auto'\"\n />\n </div>\n }\n\n <!-- Title -->\n <div class=\"title-container\">\n <h1\n [ngStyle]=\"{\n color: loginPageConfig.title?.color || '#333',\n 'font-size': loginPageConfig.title?.fontSize || '24px',\n }\"\n >\n {{ loginPageConfig.title?.text || \"Default Title\" }}\n </h1>\n </div>\n\n <!-- External Error Message -->\n @if (loginErrorMessage) {\n <div class=\"error-message\">\n {{ loginErrorMessage }}\n </div>\n }\n\n <!-- Form -->\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (loginPageConfig.login?.errorMessage) {\n <div class=\"error-message\">\n {{ loginPageConfig.login?.errorMessage }}\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.usernameField!\"\n ></pt-text-input>\n </div>\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.passwordField!\"\n ></pt-text-input>\n </div>\n\n @if (\n loginPageConfig.forgotPasswordConfig?.text &&\n loginPageConfig.forgotPasswordConfig?.url\n ) {\n <div\n class=\"forgot-password-container\"\n [ngClass]=\"\n 'forgot-password-' +\n (loginPageConfig.forgotPasswordConfig?.align || 'center')\n \"\n >\n <a\n [href]=\"loginPageConfig.forgotPasswordConfig?.url\"\n [target]=\"loginPageConfig.forgotPasswordConfig?.target || '_self'\"\n [ngStyle]=\"loginPageConfig.forgotPasswordConfig?.style\"\n [class]=\"\n loginPageConfig.forgotPasswordConfig?.styleClass ||\n 'forgot-password-link'\n \"\n >\n {{ loginPageConfig.forgotPasswordConfig?.text }}\n </a>\n </div>\n }\n\n <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"loginPageConfig.buttonConfig!\"></pt-button>\n </div>\n </form>\n\n <div class=\"login-footer\">\n {{ loginPageConfig.footer?.version }}\n <span>{{ loginPageConfig.footer?.copyright }}</span>\n </div>\n</pt-card>\n", styles: [".logo-container{display:flex;justify-content:center;align-items:center;margin-bottom:20px}.title-container{text-align:center;margin-bottom:20px}.form-container{width:100%}.field{display:flex;flex-direction:column;margin-bottom:20px;width:100%}.error-message{color:red;background-color:#ffe6e6;border:1px solid red;padding:10px;margin-bottom:10px;border-radius:5px;width:100%;text-align:center}.forgot-password-container{width:100%;display:flex;justify-content:center;margin-top:-10px;margin-bottom:20px}.forgot-password-left{justify-content:flex-start}.forgot-password-center{justify-content:center}.forgot-password-right{justify-content:flex-end}.forgot-password-link{color:#2563eb;font-size:.9rem;font-weight:500;text-decoration:none;cursor:pointer;transition:color .2s ease}.forgot-password-link:hover{color:#1d4ed8;text-decoration:underline}.submit-btn{display:flex;justify-content:center;width:100%}::ng-deep pt-button{width:100%}::ng-deep .submit-btn p-button button{width:100%}.login-footer{margin-top:20px;text-align:center;font-size:.9em;color:#555}.login-footer span{display:block;margin-top:.25rem}@media(max-width:768px){pt-card{max-width:300px}.submit-btn{min-width:100%}.forgot-password-container{justify-content:center}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PTCardModule }, { kind: "component", type: PTCardComponent, selector: "pt-card", inputs: ["config"] }, { kind: "ngmodule", type: PTButtonModule }, { kind: "component", type: PTButtonComponent, selector: "pt-button", inputs: ["buttonConfig"] }, { kind: "ngmodule", type: PTTextInputModule }, { kind: "component", type: PTTextInputComponent, selector: "pt-text-input", inputs: ["formGroup", "formField"] }] }); }
4726
5088
  }
4727
5089
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTLoginCardComponent, decorators: [{
4728
5090
  type: Component,
@@ -4733,7 +5095,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4733
5095
  PTCardModule,
4734
5096
  PTButtonModule,
4735
5097
  PTTextInputModule,
4736
- ], template: "<pt-card [config]=\"loginPageConfig.loginCardConfig!\">\n <!-- Logo -->\n @if (loginPageConfig.logoUrl?.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"loginPageConfig.logoUrl?.imageUrl\"\n [alt]=\"loginPageConfig.logoUrl?.altText || 'Logo'\"\n [style.width]=\"loginPageConfig.logoUrl?.width || '100px'\"\n [style.height]=\"loginPageConfig.logoUrl?.height || 'auto'\"\n />\n </div>\n }\n\n <!-- Title -->\n <div class=\"title-container\">\n <h1\n [ngStyle]=\"{\n color: loginPageConfig.title?.color || '#333',\n 'font-size': loginPageConfig.title?.fontSize || '24px'\n }\"\n >\n {{ loginPageConfig.title?.text || \"Default Title\" }}\n </h1>\n </div>\n <!-- Error Message -->\n @if (loginErrorMessage) {\n <div class=\"error-message\">\n {{ loginErrorMessage }}\n </div>\n }\n <!-- Form -->\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (loginPageConfig.login?.errorMessage) {\n <div class=\"error-message\">\n {{ loginPageConfig.login?.errorMessage }}\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.usernameField!\"\n ></pt-text-input>\n </div>\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.passwordField!\"\n ></pt-text-input>\n </div>\n\n <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"loginPageConfig.buttonConfig!\"></pt-button>\n </div>\n </form>\n <div class=\"login-footer\">\n {{ loginPageConfig.footer?.version }}\n <span>{{ loginPageConfig.footer?.copyright }}</span>\n </div>\n</pt-card>\n", styles: [".logo-container{display:flex;justify-content:center;align-items:center;margin-bottom:20px}.title-container{text-align:center;margin-bottom:20px}.form-container{width:100%}.field{display:flex;flex-direction:column;margin-bottom:20px;width:100%}.error-message{color:red;background-color:#ffe6e6;border:1px solid red;padding:10px;margin-bottom:10px;border-radius:5px;width:100%;text-align:center}.submit-btn{display:flex;justify-content:center;width:100%}::ng-deep pt-button{width:100%}::ng-deep .submit-btn p-button button{width:100%}.login-footer{margin-top:20px;text-align:center;font-size:.9em;color:#555}@media(max-width:768px){pt-card{max-width:300px}.submit-btn{min-width:100%}}\n"] }]
5098
+ ], template: "<pt-card [config]=\"loginPageConfig.loginCardConfig!\">\n <!-- Logo -->\n @if (loginPageConfig.logoUrl?.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"loginPageConfig.logoUrl?.imageUrl\"\n [alt]=\"loginPageConfig.logoUrl?.altText || 'Logo'\"\n [style.width]=\"loginPageConfig.logoUrl?.width || '100px'\"\n [style.height]=\"loginPageConfig.logoUrl?.height || 'auto'\"\n />\n </div>\n }\n\n <!-- Title -->\n <div class=\"title-container\">\n <h1\n [ngStyle]=\"{\n color: loginPageConfig.title?.color || '#333',\n 'font-size': loginPageConfig.title?.fontSize || '24px',\n }\"\n >\n {{ loginPageConfig.title?.text || \"Default Title\" }}\n </h1>\n </div>\n\n <!-- External Error Message -->\n @if (loginErrorMessage) {\n <div class=\"error-message\">\n {{ loginErrorMessage }}\n </div>\n }\n\n <!-- Form -->\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (loginPageConfig.login?.errorMessage) {\n <div class=\"error-message\">\n {{ loginPageConfig.login?.errorMessage }}\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.usernameField!\"\n ></pt-text-input>\n </div>\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.passwordField!\"\n ></pt-text-input>\n </div>\n\n @if (\n loginPageConfig.forgotPasswordConfig?.text &&\n loginPageConfig.forgotPasswordConfig?.url\n ) {\n <div\n class=\"forgot-password-container\"\n [ngClass]=\"\n 'forgot-password-' +\n (loginPageConfig.forgotPasswordConfig?.align || 'center')\n \"\n >\n <a\n [href]=\"loginPageConfig.forgotPasswordConfig?.url\"\n [target]=\"loginPageConfig.forgotPasswordConfig?.target || '_self'\"\n [ngStyle]=\"loginPageConfig.forgotPasswordConfig?.style\"\n [class]=\"\n loginPageConfig.forgotPasswordConfig?.styleClass ||\n 'forgot-password-link'\n \"\n >\n {{ loginPageConfig.forgotPasswordConfig?.text }}\n </a>\n </div>\n }\n\n <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"loginPageConfig.buttonConfig!\"></pt-button>\n </div>\n </form>\n\n <div class=\"login-footer\">\n {{ loginPageConfig.footer?.version }}\n <span>{{ loginPageConfig.footer?.copyright }}</span>\n </div>\n</pt-card>\n", styles: [".logo-container{display:flex;justify-content:center;align-items:center;margin-bottom:20px}.title-container{text-align:center;margin-bottom:20px}.form-container{width:100%}.field{display:flex;flex-direction:column;margin-bottom:20px;width:100%}.error-message{color:red;background-color:#ffe6e6;border:1px solid red;padding:10px;margin-bottom:10px;border-radius:5px;width:100%;text-align:center}.forgot-password-container{width:100%;display:flex;justify-content:center;margin-top:-10px;margin-bottom:20px}.forgot-password-left{justify-content:flex-start}.forgot-password-center{justify-content:center}.forgot-password-right{justify-content:flex-end}.forgot-password-link{color:#2563eb;font-size:.9rem;font-weight:500;text-decoration:none;cursor:pointer;transition:color .2s ease}.forgot-password-link:hover{color:#1d4ed8;text-decoration:underline}.submit-btn{display:flex;justify-content:center;width:100%}::ng-deep pt-button{width:100%}::ng-deep .submit-btn p-button button{width:100%}.login-footer{margin-top:20px;text-align:center;font-size:.9em;color:#555}.login-footer span{display:block;margin-top:.25rem}@media(max-width:768px){pt-card{max-width:300px}.submit-btn{min-width:100%}.forgot-password-container{justify-content:center}}\n"] }]
4737
5099
  }], ctorParameters: () => [{ type: i2.FormBuilder }], propDecorators: { loginPageConfig: [{
4738
5100
  type: Input
4739
5101
  }], loginErrorMessage: [{
@@ -4824,79 +5186,131 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4824
5186
  }]
4825
5187
  }] });
4826
5188
 
4827
- // src/app/shared/pt-confirm-dialog/pt-confirm-dialog.component.ts
4828
- const DIALOG_STYLES = {
4829
- [SeverityEnum.WARN]: {
4830
- header: {
4831
- text: 'Attention',
4832
- color: '#f59e0b',
4833
- },
5189
+ const PT_CONFIRM_DIALOG_DEFAULT_WIDTH = '560px';
5190
+ const PT_CONFIRM_DIALOG_DEFAULT_HEIGHT = 'auto';
5191
+ const PT_CONFIRM_DIALOG_OVERLAY_CLASS = 'pt-confirm-dialog-overlay';
5192
+ const PT_CONFIRM_DIALOG_NO_FOOTER_CLASS = 'pt-confirm-dialog-no-footer';
5193
+ const PT_CONFIRM_DIALOG_DEFAULT_FOOTER_ALIGN = AlignEnum.CENTER;
5194
+ const PT_CONFIRM_DIALOG_DEFAULT_SEVERITY = SeverityEnum.INFO;
5195
+ const PT_CONFIRM_DIALOG_COLORS = {
5196
+ INFO: {
5197
+ background: '#eff6ff',
5198
+ border: '#bfdbfe',
5199
+ iconBackground: '#dbeafe',
5200
+ icon: '#2563eb',
5201
+ title: '#1e40af',
5202
+ message: '#334155',
4834
5203
  },
4835
- [SeverityEnum.SUCCESS]: {
4836
- header: {
4837
- text: 'Confirmation',
4838
- color: '#16a34a',
4839
- },
5204
+ SUCCESS: {
5205
+ background: '#f0fdf4',
5206
+ border: '#bbf7d0',
5207
+ iconBackground: '#dcfce7',
5208
+ icon: '#16a34a',
5209
+ title: '#15803d',
5210
+ message: '#334155',
4840
5211
  },
4841
- [SeverityEnum.DANGER]: {
4842
- header: {
4843
- text: 'Suppression',
4844
- color: '#dc2626',
4845
- },
5212
+ WARNING: {
5213
+ background: '#fffbeb',
5214
+ border: '#fde68a',
5215
+ iconBackground: '#fef3c7',
5216
+ icon: '#d97706',
5217
+ title: '#b45309',
5218
+ message: '#334155',
4846
5219
  },
4847
- [SeverityEnum.INFO]: {
4848
- header: {
4849
- text: 'Information',
4850
- color: '#2563eb',
4851
- },
5220
+ DANGER: {
5221
+ background: '#fef2f2',
5222
+ border: '#fecaca',
5223
+ iconBackground: '#fee2e2',
5224
+ icon: '#dc2626',
5225
+ title: '#b91c1c',
5226
+ message: '#334155',
4852
5227
  },
4853
5228
  };
4854
- const DEFAULT_DIALOG_CONFIG$1 = {
4855
- header: { text: 'Confirmation' },
4856
- visible: false,
4857
- width: '720px',
4858
- height: 'auto',
4859
- content: '',
4860
- confirmButtonConfig: { label: 'Confirmer' },
4861
- cancelButtonConfig: { label: 'Annuler' },
4862
- dialogStyle: SeverityEnum.INFO,
5229
+ const PT_CONFIRM_DIALOG_SEVERITY_CLASS = {
5230
+ INFO: 'pt-confirm-dialog-info',
5231
+ SUCCESS: 'pt-confirm-dialog-success',
5232
+ WARNING: 'pt-confirm-dialog-warning',
5233
+ DANGER: 'pt-confirm-dialog-danger',
5234
+ };
5235
+ const PT_CONFIRM_DIALOG_DEFAULT_ICON = {
5236
+ INFO: 'pi pi-info-circle',
5237
+ SUCCESS: 'pi pi-check-circle',
5238
+ WARNING: 'pi pi-exclamation-triangle',
5239
+ DANGER: 'pi pi-times-circle',
5240
+ };
5241
+ const PT_CONFIRM_DIALOG_DEFAULT_HEADER = {
5242
+ INFO: 'Information',
5243
+ SUCCESS: 'Succès',
5244
+ WARNING: 'Attention',
5245
+ DANGER: 'Confirmation requise',
4863
5246
  };
5247
+
4864
5248
  class PTConfirmDialogComponent {
4865
- constructor(confirmationService, renderer) {
5249
+ constructor(confirmationService) {
4866
5250
  this.confirmationService = confirmationService;
4867
- this.renderer = renderer;
4868
- this.dialogConfig = { ...DEFAULT_DIALOG_CONFIG$1 };
5251
+ this.dialogConfig = {
5252
+ header: { text: 'Confirmation' },
5253
+ content: '',
5254
+ visible: false,
5255
+ width: PT_CONFIRM_DIALOG_DEFAULT_WIDTH,
5256
+ height: PT_CONFIRM_DIALOG_DEFAULT_HEIGHT,
5257
+ dialogStyle: PT_CONFIRM_DIALOG_DEFAULT_SEVERITY,
5258
+ closeOnEscape: true,
5259
+ footerAlign: PT_CONFIRM_DIALOG_DEFAULT_FOOTER_ALIGN,
5260
+ confirmButtonConfig: {
5261
+ label: 'Confirmer',
5262
+ icon: 'pi pi-check',
5263
+ },
5264
+ cancelButtonConfig: {
5265
+ label: 'Annuler',
5266
+ icon: 'pi pi-times',
5267
+ },
5268
+ };
4869
5269
  this.confirm = new EventEmitter();
4870
5270
  this.cancel = new EventEmitter();
4871
- this.SeverityEnum = SeverityEnum;
5271
+ this.overlayStyleClass = `${PT_CONFIRM_DIALOG_OVERLAY_CLASS} ${PT_CONFIRM_DIALOG_SEVERITY_CLASS.INFO}`;
5272
+ this.isDialogOpen = false;
4872
5273
  }
4873
5274
  ngAfterContentInit() {
4874
- // Nothing mandatory here.
5275
+ // Projection support only.
4875
5276
  }
4876
5277
  ngOnChanges(changes) {
4877
5278
  if (!changes['dialogConfig']) {
4878
5279
  return;
4879
5280
  }
4880
- this.applyDialogStyle();
4881
- if (this.dialogConfig.visible) {
5281
+ if (this.dialogConfig?.visible) {
4882
5282
  this.showDialog();
4883
5283
  }
4884
5284
  }
4885
- getActiveForm() {
4886
- if (this.formGroup) {
4887
- return this.formGroup;
4888
- }
4889
- const formBuilder = this.projectedFormBuilder;
4890
- if (formBuilder && formBuilder.form) {
4891
- return formBuilder.form;
5285
+ onEscapeKey(event) {
5286
+ if (!this.isDialogOpen || this.dialogConfig.closeOnEscape === false) {
5287
+ return;
4892
5288
  }
4893
- return null;
5289
+ event.preventDefault();
5290
+ event.stopPropagation();
5291
+ this.onCancelClick();
4894
5292
  }
4895
- isConfirmDisabled() {
4896
- const form = this.getActiveForm();
4897
- return !!form && form.invalid;
5293
+ showDialog() {
5294
+ this.overlayStyleClass = [
5295
+ PT_CONFIRM_DIALOG_OVERLAY_CLASS,
5296
+ this.getSeverityClass(),
5297
+ this.hasFooter() ? '' : PT_CONFIRM_DIALOG_NO_FOOTER_CLASS,
5298
+ ]
5299
+ .filter(Boolean)
5300
+ .join(' ');
5301
+ this.isDialogOpen = true;
5302
+ this.confirmationService.confirm({
5303
+ header: '',
5304
+ message: this.getDialogContentText() || ' ',
5305
+ accept: () => {
5306
+ this.handleConfirm();
5307
+ },
5308
+ reject: () => {
5309
+ this.handleCancel();
5310
+ },
5311
+ });
4898
5312
  }
4899
- onConfirmClick(cd) {
5313
+ onConfirmClick() {
4900
5314
  const form = this.getActiveForm();
4901
5315
  if (form) {
4902
5316
  form.markAllAsTouched();
@@ -4905,287 +5319,215 @@ class PTConfirmDialogComponent {
4905
5319
  return;
4906
5320
  }
4907
5321
  }
4908
- cd.accept();
4909
- }
4910
- applyDialogStyle() {
4911
- const dialogStyle = this.dialogConfig.dialogStyle || SeverityEnum.INFO;
4912
- const styleConfig = DIALOG_STYLES[dialogStyle] || {};
4913
- const current = this.dialogConfig || {};
4914
- const mergedHeader = current.header !== undefined
4915
- ? current.header
4916
- : styleConfig.header !== undefined
4917
- ? styleConfig.header
4918
- : DEFAULT_DIALOG_CONFIG$1.header;
4919
- this.dialogConfig = {
4920
- ...DEFAULT_DIALOG_CONFIG$1,
4921
- ...current,
4922
- ...styleConfig,
4923
- header: mergedHeader,
4924
- confirmButtonConfig: {
4925
- ...DEFAULT_DIALOG_CONFIG$1.confirmButtonConfig,
4926
- ...current.confirmButtonConfig,
4927
- },
4928
- cancelButtonConfig: {
4929
- ...DEFAULT_DIALOG_CONFIG$1.cancelButtonConfig,
4930
- ...current.cancelButtonConfig,
4931
- },
4932
- visible: current.visible,
4933
- width: current.width || DEFAULT_DIALOG_CONFIG$1.width,
4934
- height: current.height || DEFAULT_DIALOG_CONFIG$1.height,
4935
- };
5322
+ this.handleConfirm();
4936
5323
  }
4937
- getSeverityClass() {
4938
- const style = this.dialogConfig.dialogStyle ?? SeverityEnum.INFO;
4939
- switch (style) {
4940
- case SeverityEnum.DANGER:
4941
- return 'pt-confirm-dialog-danger';
4942
- case SeverityEnum.WARNING:
4943
- return 'pt-confirm-dialog-warning';
4944
- case SeverityEnum.SUCCESS:
4945
- return 'pt-confirm-dialog-success';
4946
- case SeverityEnum.INFO:
4947
- default:
4948
- return 'pt-confirm-dialog-info';
4949
- }
5324
+ onCancelClick() {
5325
+ this.handleCancel();
4950
5326
  }
4951
- getSeverityColors() {
4952
- const style = this.dialogConfig.dialogStyle ?? SeverityEnum.INFO;
4953
- switch (style) {
4954
- case SeverityEnum.DANGER:
4955
- return { header: '#b91c1c', message: '#4b5563' };
4956
- case SeverityEnum.WARNING:
4957
- return { header: '#b45309', message: '#92400e' };
4958
- case SeverityEnum.SUCCESS:
4959
- return { header: '#15803d', message: '#166534' };
4960
- case SeverityEnum.INFO:
4961
- default:
4962
- return { header: '#2563eb', message: '#2563eb' };
4963
- }
5327
+ hasFooter() {
5328
+ return !!(this.dialogConfig?.confirmButtonConfig ||
5329
+ this.dialogConfig?.cancelButtonConfig);
4964
5330
  }
4965
5331
  get confirmButtonModel() {
4966
- const style = this.dialogConfig.dialogStyle ?? SeverityEnum.INFO;
4967
- const confirmSeverity = style === SeverityEnum.DANGER
4968
- ? SeverityEnum.DANGER
4969
- : style === SeverityEnum.WARNING
4970
- ? SeverityEnum.WARNING
4971
- : style === SeverityEnum.SUCCESS
4972
- ? SeverityEnum.SUCCESS
4973
- : SeverityEnum.INFO;
5332
+ const config = this.dialogConfig.confirmButtonConfig;
4974
5333
  return {
4975
- label: this.dialogConfig.confirmButtonConfig?.label ?? 'Confirmer',
4976
- icon: this.dialogConfig.confirmButtonConfig?.icon ?? 'pi pi-check',
4977
- iconPos: 'left',
4978
- type: 'button',
4979
- outlined: true,
4980
- severity: confirmSeverity,
4981
- styleClass: (this.dialogConfig.confirmButtonConfig?.styleClass || '') +
4982
- ' pt-confirm-dialog-confirm-btn',
4983
- width: 'auto',
4984
- disabled: this.isConfirmDisabled(),
5334
+ ...(config || {}),
5335
+ label: config?.label || 'Confirmer',
5336
+ icon: config?.icon || 'pi pi-check',
5337
+ iconPos: config?.iconPos || 'left',
5338
+ type: config?.type || 'button',
5339
+ outlined: config?.outlined ?? true,
5340
+ severity: config?.severity || this.getButtonSeverity(),
5341
+ width: config?.width || 'auto',
5342
+ height: config?.height || 'auto',
5343
+ styleClass: [config?.styleClass || '', 'pt-confirm-dialog-confirm-btn']
5344
+ .join(' ')
5345
+ .trim(),
5346
+ disabled: config?.disabled || this.isConfirmDisabled(),
4985
5347
  };
4986
5348
  }
4987
5349
  get cancelButtonModel() {
5350
+ const config = this.dialogConfig.cancelButtonConfig;
4988
5351
  return {
4989
- label: this.dialogConfig.cancelButtonConfig?.label ?? 'Annuler',
4990
- icon: this.dialogConfig.cancelButtonConfig?.icon ?? 'pi pi-times',
4991
- iconPos: 'left',
4992
- type: 'button',
4993
- outlined: true,
4994
- severity: SeverityEnum.INFO,
4995
- styleClass: (this.dialogConfig.cancelButtonConfig?.styleClass || '') +
4996
- ' pt-confirm-dialog-cancel-btn',
4997
- width: 'auto',
5352
+ ...(config || {}),
5353
+ label: config?.label || 'Annuler',
5354
+ icon: config?.icon || 'pi pi-times',
5355
+ iconPos: config?.iconPos || 'left',
5356
+ type: config?.type || 'button',
5357
+ outlined: config?.outlined ?? true,
5358
+ severity: config?.severity || SeverityEnum.INFO,
5359
+ width: config?.width || 'auto',
5360
+ height: config?.height || 'auto',
5361
+ styleClass: [config?.styleClass || '', 'pt-confirm-dialog-cancel-btn']
5362
+ .join(' ')
5363
+ .trim(),
5364
+ disabled: config?.disabled || false,
4998
5365
  };
4999
5366
  }
5000
- showDialog() {
5001
- this.confirmationService.confirm({
5002
- header: '',
5003
- message: this.getDialogContentText() || ' ',
5004
- accept: () => this.confirm.emit(),
5005
- reject: (_type) => this.cancel.emit(),
5006
- });
5007
- setTimeout(() => {
5008
- const dialogElement = this.getLastConfirmDialogElement();
5009
- if (!dialogElement) {
5010
- return;
5011
- }
5012
- this.applyDialogRootStyles(dialogElement);
5013
- this.applyDialogInnerLayoutFixes(dialogElement);
5014
- }, 0);
5015
- }
5016
- getLastConfirmDialogElement() {
5017
- const dialogs = Array.from(document.querySelectorAll('.p-confirm-dialog'));
5018
- if (!dialogs.length) {
5019
- return null;
5020
- }
5021
- return dialogs[dialogs.length - 1];
5022
- }
5023
- applyDialogRootStyles(dialogElement) {
5024
- this.renderer.addClass(dialogElement, 'pt-confirm-dialog-overlay');
5025
- this.renderer.removeClass(dialogElement, 'pt-confirm-dialog-danger');
5026
- this.renderer.removeClass(dialogElement, 'pt-confirm-dialog-warning');
5027
- this.renderer.removeClass(dialogElement, 'pt-confirm-dialog-success');
5028
- this.renderer.removeClass(dialogElement, 'pt-confirm-dialog-info');
5029
- this.renderer.addClass(dialogElement, this.getSeverityClass());
5030
- this.renderer.setStyle(dialogElement, 'width', this.dialogConfig.width || '720px');
5031
- this.renderer.setStyle(dialogElement, 'max-width', '92vw');
5032
- this.renderer.setStyle(dialogElement, 'height', this.dialogConfig.height || 'auto');
5033
- this.renderer.setStyle(dialogElement, 'min-height', 'unset');
5034
- this.renderer.setStyle(dialogElement, 'max-height', 'none');
5035
- this.renderer.setStyle(dialogElement, 'display', 'block');
5036
- }
5037
- applyDialogInnerLayoutFixes(dialogElement) {
5038
- this.resetElementLayout(dialogElement.querySelector('.p-dialog-header'), {
5039
- display: 'none',
5040
- height: '0',
5041
- minHeight: '0',
5042
- padding: '0',
5043
- border: '0',
5044
- });
5045
- this.resetElementLayout(dialogElement.querySelector('.p-dialog-content'), {
5046
- display: 'block',
5047
- flex: 'unset',
5048
- flexGrow: '0',
5049
- flexShrink: '0',
5050
- flexBasis: 'auto',
5051
- height: 'auto',
5052
- minHeight: 'unset',
5053
- maxHeight: 'none',
5054
- overflow: 'visible',
5055
- padding: '0',
5056
- margin: '0',
5057
- background: 'transparent',
5058
- });
5059
- this.resetElementLayout(dialogElement.querySelector('.p-confirm-dialog-message'), {
5060
- display: 'block',
5061
- flex: 'unset',
5062
- height: 'auto',
5063
- minHeight: 'unset',
5064
- maxHeight: 'none',
5065
- margin: '0',
5066
- padding: '0',
5067
- width: '100%',
5068
- });
5069
- this.resetElementLayout(dialogElement.querySelector('.p-dialog-footer'), {
5070
- display: 'block',
5071
- flex: 'unset',
5072
- flexGrow: '0',
5073
- flexShrink: '0',
5074
- flexBasis: 'auto',
5075
- height: 'auto',
5076
- minHeight: 'unset',
5077
- maxHeight: 'none',
5078
- margin: '0',
5079
- });
5080
- this.resetElementLayout(dialogElement.querySelector('.pt-confirm-dialog-card'), {
5081
- width: '100%',
5082
- height: 'auto',
5083
- minHeight: 'unset',
5084
- maxHeight: 'none',
5085
- });
5086
- this.resetElementLayout(dialogElement.querySelector('.pt-confirm-dialog-card-top'), {
5087
- height: 'auto',
5088
- minHeight: 'unset',
5089
- maxHeight: 'none',
5090
- });
5091
- }
5092
- resetElementLayout(element, styles) {
5093
- if (!element) {
5094
- return;
5367
+ getFooterButtonsStyle() {
5368
+ const align = this.dialogConfig.footerAlign || PT_CONFIRM_DIALOG_DEFAULT_FOOTER_ALIGN;
5369
+ switch (align) {
5370
+ case AlignEnum.LEFT:
5371
+ return { justifyContent: 'flex-start' };
5372
+ case AlignEnum.RIGHT:
5373
+ return { justifyContent: 'flex-end' };
5374
+ case AlignEnum.CENTER:
5375
+ default:
5376
+ return { justifyContent: 'center' };
5095
5377
  }
5096
- const htmlElement = element;
5097
- Object.entries(styles).forEach(([property, value]) => {
5098
- this.renderer.setStyle(htmlElement, property, value);
5099
- });
5100
5378
  }
5101
5379
  getDialogHeaderText() {
5102
5380
  const header = this.dialogConfig.header;
5103
- const dialogStyle = this.dialogConfig.dialogStyle ?? SeverityEnum.INFO;
5104
- const styleHeader = DIALOG_STYLES[dialogStyle]?.header;
5105
- return typeof header === 'object' && header !== null && 'text' in header
5106
- ? header.text
5107
- : typeof header === 'string'
5108
- ? header
5109
- : typeof styleHeader === 'object' &&
5110
- styleHeader !== null &&
5111
- 'text' in styleHeader
5112
- ? styleHeader.text
5113
- : 'Confirmation';
5381
+ if (typeof header === 'string') {
5382
+ return header;
5383
+ }
5384
+ if (header && typeof header === 'object' && 'text' in header) {
5385
+ return String(header.text || this.getDefaultHeaderText());
5386
+ }
5387
+ return this.getDefaultHeaderText();
5114
5388
  }
5115
- getDialogHeaderStyle() {
5116
- const header = this.dialogConfig.header;
5117
- const { header: color } = this.getSeverityColors();
5118
- const fontSize = typeof header === 'object' && header !== null && header.fontSize
5119
- ? header.fontSize
5120
- : '20px';
5121
- return {
5122
- color,
5123
- fontSize,
5124
- fontWeight: 700,
5125
- };
5389
+ getDialogContentText() {
5390
+ const content = this.dialogConfig.content;
5391
+ if (typeof content === 'string') {
5392
+ return content;
5393
+ }
5394
+ if (content && typeof content === 'object' && 'text' in content) {
5395
+ return String(content.text || '');
5396
+ }
5397
+ return '';
5126
5398
  }
5127
5399
  getDialogIconClass() {
5128
5400
  const header = this.dialogConfig.header;
5129
- const dialogStyle = this.dialogConfig.dialogStyle ?? SeverityEnum.INFO;
5130
- const styleHeader = DIALOG_STYLES[dialogStyle]?.header;
5131
- const icon = typeof header === 'object' && header !== null && 'icon' in header
5401
+ const icon = header && typeof header === 'object' && 'icon' in header
5132
5402
  ? header.icon
5133
- : typeof styleHeader === 'object' &&
5134
- styleHeader !== null &&
5135
- 'icon' in styleHeader
5136
- ? styleHeader.icon
5137
- : undefined;
5138
- return typeof icon === 'string'
5139
- ? icon
5140
- : icon?.code || 'pi pi-exclamation-circle';
5403
+ : undefined;
5404
+ if (typeof icon === 'string') {
5405
+ return icon;
5406
+ }
5407
+ if (icon?.code) {
5408
+ return icon.code;
5409
+ }
5410
+ return PT_CONFIRM_DIALOG_DEFAULT_ICON[this.getNormalizedSeverity()];
5141
5411
  }
5142
5412
  getDialogIconStyle() {
5143
5413
  const header = this.dialogConfig.header;
5144
- const { header: defaultColor } = this.getSeverityColors();
5145
- const icon = typeof header === 'object' && header !== null && 'icon' in header
5414
+ const icon = header && typeof header === 'object' && 'icon' in header
5146
5415
  ? header.icon
5147
5416
  : undefined;
5417
+ const colors = this.getColors();
5148
5418
  return {
5149
- color: icon?.color || defaultColor,
5150
- fontSize: icon?.fontSize || '2.2rem',
5419
+ color: icon?.color || colors.icon,
5420
+ fontSize: icon?.fontSize || '2rem',
5151
5421
  };
5152
5422
  }
5153
- getDialogContentText() {
5154
- const content = this.dialogConfig.content;
5155
- if (typeof content === 'string') {
5156
- return content;
5157
- }
5158
- if (content && typeof content === 'object' && 'text' in content) {
5159
- return content.text ?? '';
5160
- }
5161
- return '';
5423
+ getDialogHeaderStyle() {
5424
+ const colors = this.getColors();
5425
+ const header = this.dialogConfig.header;
5426
+ return {
5427
+ color: header?.color || colors.title,
5428
+ fontSize: header?.fontSize || '1.35rem',
5429
+ fontWeight: 700,
5430
+ };
5162
5431
  }
5163
5432
  getDialogContentStyle() {
5433
+ const colors = this.getColors();
5164
5434
  const content = this.dialogConfig.content;
5165
- const { message } = this.getSeverityColors();
5166
- let fontSize = '18px';
5167
- let textAlign;
5168
- if (typeof content === 'object' && content !== null) {
5169
- if (content.fontSize) {
5170
- fontSize = content.fontSize;
5171
- }
5172
- if (content.position) {
5173
- textAlign = content.position;
5174
- }
5175
- }
5176
5435
  return {
5177
- color: message,
5178
- fontSize,
5179
- ...(textAlign ? { textAlign } : {}),
5436
+ color: content?.color || colors.message,
5437
+ fontSize: content?.fontSize || '1rem',
5438
+ textAlign: content?.position || AlignEnum.LEFT,
5180
5439
  };
5181
5440
  }
5182
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTConfirmDialogComponent, deps: [{ token: i1$1.ConfirmationService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
5183
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTConfirmDialogComponent, isStandalone: false, selector: "pt-confirm-dialog", inputs: { dialogConfig: "dialogConfig", formGroup: "formGroup" }, outputs: { confirm: "confirm", cancel: "cancel" }, providers: [ConfirmationService], queries: [{ propertyName: "dialogBodyTpl", first: true, predicate: ["dialogBody"], descendants: true }, { propertyName: "projectedFormBuilder", first: true, predicate: PTFormBuilderComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- src/app/shared/pt-confirm-dialog/pt-confirm-dialog.component.html -->\n\n<div class=\"pt-confirm-dialog\">\n <p-confirmDialog #cd>\n <ng-template pTemplate=\"header\"></ng-template>\n\n <ng-template pTemplate=\"message\">\n <div class=\"pt-confirm-dialog-card\">\n <div class=\"pt-confirm-dialog-card-top\">\n <div class=\"pt-confirm-dialog-icon-wrapper\">\n <i\n class=\"pt-confirm-dialog-icon\"\n [class]=\"getDialogIconClass()\"\n [ngStyle]=\"getDialogIconStyle()\"\n ></i>\n </div>\n\n <div class=\"pt-confirm-dialog-text-wrapper\">\n <div\n class=\"pt-confirm-dialog-title\"\n [ngStyle]=\"getDialogHeaderStyle()\"\n >\n {{ getDialogHeaderText() }}\n </div>\n\n @if (dialogBodyTpl) {\n <ng-container\n [ngTemplateOutlet]=\"dialogBodyTpl\"\n ></ng-container>\n } @else {\n <div\n class=\"pt-confirm-dialog-message\"\n [ngStyle]=\"getDialogContentStyle()\"\n >\n {{ getDialogContentText() }}\n </div>\n }\n\n </div>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"pt-confirm-dialog-footer-buttons\">\n @if (dialogConfig.cancelButtonConfig) {\n <pt-button\n [buttonConfig]=\"cancelButtonModel\"\n (click)=\"cd.onReject()\"\n ></pt-button>\n }\n\n @if (dialogConfig.confirmButtonConfig) {\n <pt-button\n [buttonConfig]=\"confirmButtonModel\"\n (click)=\"onConfirmClick(cd)\"\n ></pt-button>\n }\n </div>\n </ng-template>\n </p-confirmDialog>\n</div>\n", styles: ["::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay{width:520px;max-width:92vw;height:auto!important;min-height:unset!important;max-height:none!important;display:block!important;border-radius:18px;overflow:hidden;box-shadow:0 20px 45px #0f172a59}::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay .p-dialog-header{display:none!important;padding:0!important;border:0!important;height:0!important;min-height:0!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay .p-dialog-content{display:block!important;flex:unset!important;flex-grow:0!important;flex-shrink:0!important;flex-basis:auto!important;height:auto!important;min-height:unset!important;max-height:none!important;padding:0!important;margin:0!important;overflow:visible!important;background:transparent!important;border-top-left-radius:18px;border-top-right-radius:18px}::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay .p-confirm-dialog-message{display:block!important;flex:unset!important;height:auto!important;min-height:unset!important;max-height:none!important;margin:0!important;padding:0!important;width:100%!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay .p-dialog-footer{display:block!important;flex:unset!important;flex-grow:0!important;flex-shrink:0!important;flex-basis:auto!important;height:auto!important;min-height:unset!important;max-height:none!important;background:#fff;border-top:1px solid rgba(148,163,184,.25);padding:16px 32px 22px!important;margin:0!important}.pt-confirm-dialog-card{width:100%;height:auto!important;min-height:unset!important;max-height:none!important;border-radius:18px 18px 0 0;overflow:hidden}.pt-confirm-dialog-card-top{height:auto!important;min-height:unset!important;max-height:none!important;padding:28px 40px;display:flex;align-items:flex-start}::ng-deep .p-confirm-dialog.pt-confirm-dialog-danger .pt-confirm-dialog-card{background-color:#fde4e4}::ng-deep .p-confirm-dialog.pt-confirm-dialog-warning .pt-confirm-dialog-card{background-color:#fff4d1}::ng-deep .p-confirm-dialog.pt-confirm-dialog-success .pt-confirm-dialog-card{background-color:#dcfce7}::ng-deep .p-confirm-dialog.pt-confirm-dialog-info .pt-confirm-dialog-card{background-color:#e0f2fe}.pt-confirm-dialog-icon-wrapper{width:60px;height:60px;min-width:60px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin-right:18px;box-sizing:border-box}.pt-confirm-dialog-icon{font-size:30px;line-height:1;color:#b91c1c}.pt-confirm-dialog-text-wrapper{flex:1;min-width:0}.pt-confirm-dialog-title{font-size:22px;font-weight:700;margin-bottom:8px;color:#b91c1c}.pt-confirm-dialog-message{font-size:18px;line-height:1.5;color:#4b5563;margin:0}.pt-confirm-dialog-footer-buttons{display:flex;justify-content:center;align-items: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-confirm-dialog-danger .p-dialog-footer .p-button{background:#fff!important;border-color:#dc2626!important;color:#dc2626!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-danger .p-dialog-footer .p-button:hover{background:#fef2f2!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-warning .p-dialog-footer .p-button{background:#fff!important;border-color:#d97706!important;color:#b45309!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-warning .p-dialog-footer .p-button:hover{background:#fffbeb!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-success .p-dialog-footer .p-button{background:#fff!important;border-color:#16a34a!important;color:#15803d!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-success .p-dialog-footer .p-button:hover{background:#f0fdf4!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-info .p-dialog-footer .p-button{background:#fff!important;border-color:#2563eb!important;color:#2563eb!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-info .p-dialog-footer .p-button:hover{background:#eff6ff!important}@media(max-width:768px){::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay{width:calc(100vw - 2rem)!important;max-width:calc(100vw - 2rem)!important}.pt-confirm-dialog-card-top{padding:24px}.pt-confirm-dialog-icon-wrapper{width:48px;height:48px;min-width:48px;margin-right:14px}.pt-confirm-dialog-title{font-size:19px}.pt-confirm-dialog-message{font-size:16px}::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay .p-dialog-footer{padding:14px 20px 18px!important}.pt-confirm-dialog-footer-buttons{gap:10px;flex-wrap:wrap}}\n"], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i3$6.ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }, { kind: "directive", type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: PTButtonComponent, selector: "pt-button", inputs: ["buttonConfig"] }] }); }
5441
+ getDialogBodyStyle() {
5442
+ const colors = this.getColors();
5443
+ return {
5444
+ background: colors.background,
5445
+ borderColor: colors.border,
5446
+ };
5447
+ }
5448
+ getIconWrapperStyle() {
5449
+ const colors = this.getColors();
5450
+ return {
5451
+ background: colors.iconBackground,
5452
+ borderColor: colors.border,
5453
+ };
5454
+ }
5455
+ handleConfirm() {
5456
+ if (!this.isDialogOpen) {
5457
+ return;
5458
+ }
5459
+ this.isDialogOpen = false;
5460
+ this.closeDialog();
5461
+ this.confirm.emit();
5462
+ }
5463
+ handleCancel() {
5464
+ if (!this.isDialogOpen) {
5465
+ return;
5466
+ }
5467
+ this.isDialogOpen = false;
5468
+ this.closeDialog();
5469
+ this.cancel.emit();
5470
+ }
5471
+ closeDialog() {
5472
+ this.confirmationService.close();
5473
+ }
5474
+ getActiveForm() {
5475
+ if (this.formGroup) {
5476
+ return this.formGroup;
5477
+ }
5478
+ if (this.projectedFormBuilder?.form) {
5479
+ return this.projectedFormBuilder.form;
5480
+ }
5481
+ return null;
5482
+ }
5483
+ isConfirmDisabled() {
5484
+ const form = this.getActiveForm();
5485
+ return !!form && form.invalid;
5486
+ }
5487
+ getSeverityClass() {
5488
+ return PT_CONFIRM_DIALOG_SEVERITY_CLASS[this.getNormalizedSeverity()];
5489
+ }
5490
+ getNormalizedSeverity() {
5491
+ const raw = String(this.dialogConfig.dialogStyle || PT_CONFIRM_DIALOG_DEFAULT_SEVERITY)
5492
+ .trim()
5493
+ .toUpperCase();
5494
+ if (raw === 'SUCCESS') {
5495
+ return 'SUCCESS';
5496
+ }
5497
+ if (raw === 'WARNING' || raw === 'WARN') {
5498
+ return 'WARNING';
5499
+ }
5500
+ if (raw === 'DANGER' || raw === 'ERROR') {
5501
+ return 'DANGER';
5502
+ }
5503
+ return 'INFO';
5504
+ }
5505
+ getColors() {
5506
+ return PT_CONFIRM_DIALOG_COLORS[this.getNormalizedSeverity()];
5507
+ }
5508
+ getDefaultHeaderText() {
5509
+ return PT_CONFIRM_DIALOG_DEFAULT_HEADER[this.getNormalizedSeverity()];
5510
+ }
5511
+ getButtonSeverity() {
5512
+ switch (this.getNormalizedSeverity()) {
5513
+ case 'SUCCESS':
5514
+ return SeverityEnum.SUCCESS;
5515
+ case 'WARNING':
5516
+ return SeverityEnum.WARNING;
5517
+ case 'DANGER':
5518
+ return SeverityEnum.DANGER;
5519
+ case 'INFO':
5520
+ default:
5521
+ return SeverityEnum.INFO;
5522
+ }
5523
+ }
5524
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTConfirmDialogComponent, deps: [{ token: i1$1.ConfirmationService }], target: i0.ɵɵFactoryTarget.Component }); }
5525
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTConfirmDialogComponent, isStandalone: false, selector: "pt-confirm-dialog", inputs: { dialogConfig: "dialogConfig", formGroup: "formGroup" }, outputs: { confirm: "confirm", cancel: "cancel" }, host: { listeners: { "document:keydown.escape": "onEscapeKey($event)" } }, providers: [ConfirmationService], queries: [{ propertyName: "dialogBodyTpl", first: true, predicate: ["dialogBody"], descendants: true }, { propertyName: "projectedFormBuilder", first: true, predicate: PTFormBuilderComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"pt-confirm-dialog\">\n <p-confirmDialog\n #cd\n [styleClass]=\"overlayStyleClass\"\n [appendTo]=\"'body'\"\n [closable]=\"false\"\n [closeOnEscape]=\"false\"\n >\n <ng-template pTemplate=\"header\"></ng-template>\n\n <ng-template pTemplate=\"message\">\n <div class=\"pt-confirm-dialog-wrapper\">\n <div class=\"pt-confirm-dialog-body\" [ngStyle]=\"getDialogBodyStyle()\">\n <button\n type=\"button\"\n class=\"pt-confirm-dialog-close\"\n aria-label=\"Fermer\"\n (click)=\"onCancelClick()\"\n >\n <i class=\"pi pi-times\"></i>\n </button>\n\n <div class=\"pt-confirm-dialog-content\">\n <div\n class=\"pt-confirm-dialog-icon-wrapper\"\n [ngStyle]=\"getIconWrapperStyle()\"\n >\n <i\n class=\"pt-confirm-dialog-icon\"\n [class]=\"getDialogIconClass()\"\n [ngStyle]=\"getDialogIconStyle()\"\n ></i>\n </div>\n\n <div class=\"pt-confirm-dialog-text-wrapper\">\n <h3\n class=\"pt-confirm-dialog-title\"\n [ngStyle]=\"getDialogHeaderStyle()\"\n >\n {{ getDialogHeaderText() }}\n </h3>\n\n @if (dialogBodyTpl) {\n <ng-container [ngTemplateOutlet]=\"dialogBodyTpl\"></ng-container>\n } @else {\n <p\n class=\"pt-confirm-dialog-message-text\"\n [ngStyle]=\"getDialogContentStyle()\"\n >\n {{ getDialogContentText() }}\n </p>\n }\n </div>\n </div>\n </div>\n\n @if (hasFooter()) {\n <div class=\"pt-confirm-dialog-custom-footer\">\n <div\n class=\"pt-confirm-dialog-footer-buttons\"\n [ngStyle]=\"getFooterButtonsStyle()\"\n >\n @if (dialogConfig.cancelButtonConfig) {\n <div class=\"pt-confirm-dialog-button-slot\">\n <pt-button\n [buttonConfig]=\"cancelButtonModel\"\n (click)=\"onCancelClick()\"\n ></pt-button>\n </div>\n }\n\n @if (dialogConfig.confirmButtonConfig) {\n <div class=\"pt-confirm-dialog-button-slot\">\n <pt-button\n [buttonConfig]=\"confirmButtonModel\"\n (click)=\"onConfirmClick()\"\n ></pt-button>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </ng-template>\n </p-confirmDialog>\n</div>\n", styles: ["::ng-deep .pt-confirm-dialog-overlay.p-dialog,::ng-deep .p-dialog.pt-confirm-dialog-overlay,::ng-deep .pt-confirm-dialog-overlay.p-confirm-dialog,::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay,::ng-deep .pt-confirm-dialog-overlay.p-confirmdialog,::ng-deep .p-confirmdialog.pt-confirm-dialog-overlay{width:560px!important;max-width:calc(100vw - 2rem)!important;height:auto!important;min-height:unset!important;max-height:none!important;border:0!important;border-radius:28px!important;overflow:hidden!important;background:#fff!important;box-shadow:0 24px 60px #0f172a4d!important}::ng-deep .pt-confirm-dialog-overlay .p-dialog-header{display:none!important;padding:0!important;border:0!important;height:0!important;min-height:0!important}::ng-deep .pt-confirm-dialog-overlay .p-dialog-content{padding:0!important;margin:0!important;overflow:hidden!important;background:transparent!important}::ng-deep .pt-confirm-dialog-overlay .p-confirm-dialog-message,::ng-deep .pt-confirm-dialog-overlay .p-confirmdialog-message{display:block!important;width:100%!important;margin:0!important;padding:0!important}::ng-deep .pt-confirm-dialog-overlay .p-dialog-footer{display:none!important;padding:0!important;margin:0!important;border:0!important;height:0!important;min-height:0!important;max-height:0!important}.pt-confirm-dialog-wrapper{width:100%;background:#fff;overflow:hidden}.pt-confirm-dialog-body{position:relative;width:100%;min-height:190px;padding:2rem 2.25rem;border-bottom:1px solid;box-sizing:border-box}.pt-confirm-dialog-no-footer .pt-confirm-dialog-body{border-bottom:0!important}.pt-confirm-dialog-content{display:flex;align-items:center;gap:1.25rem;min-height:126px;padding-right:3rem}.pt-confirm-dialog-text-wrapper{flex:1;min-width:0}.pt-confirm-dialog-title{margin:0 0 .45rem;line-height:1.25}.pt-confirm-dialog-message-text{margin:0;line-height:1.55;font-weight:400}.pt-confirm-dialog-close{position:absolute;top:1.25rem;right:1.25rem;z-index:5;width:2.75rem;height:2.75rem;border:2px solid currentColor;border-radius:999px;background:#ffffffd9;color:#64748b;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;pointer-events:auto;transition:background-color .2s ease,color .2s ease,transform .2s ease}.pt-confirm-dialog-close:hover{background:#fff;color:#0f172a;transform:scale(1.04)}.pt-confirm-dialog-close i{font-size:1.15rem}.pt-confirm-dialog-icon-wrapper{width:4.25rem;height:4.25rem;min-width:4.25rem;border:1px solid;border-radius:999px;display:flex;align-items:center;justify-content:center}.pt-confirm-dialog-icon{line-height:1}.pt-confirm-dialog-custom-footer{width:100%;padding:1rem 1.5rem 1.35rem;background:#fff;box-sizing:border-box}.pt-confirm-dialog-footer-buttons{display:flex!important;flex-direction:row!important;align-items:center!important;flex-wrap:nowrap!important;gap:.75rem;width:100%}.pt-confirm-dialog-button-slot{display:inline-flex!important;flex:0 0 auto!important;width:auto!important;max-width:max-content!important}::ng-deep .pt-confirm-dialog-button-slot>pt-button{display:inline-flex!important;flex:0 0 auto!important;width:auto!important;max-width:max-content!important}::ng-deep .pt-confirm-dialog-button-slot p-button,::ng-deep .pt-confirm-dialog-button-slot>p-button{display:inline-flex!important;flex:0 0 auto!important;width:auto!important;max-width:max-content!important}::ng-deep .pt-confirm-dialog-button-slot .p-button,::ng-deep .pt-confirm-dialog-button-slot button{width:auto!important;min-width:7.5rem;max-width:max-content!important;border-radius:999px!important;padding:.7rem 1.35rem!important;font-weight:600!important;white-space:nowrap!important}::ng-deep .pt-confirm-dialog-button-slot .p-button .pi{margin-right:.45rem}@media(max-width:768px){.pt-confirm-dialog-body{min-height:170px;padding:1.5rem}.pt-confirm-dialog-content{gap:.85rem;padding-right:2rem}.pt-confirm-dialog-icon-wrapper{width:3.2rem;height:3.2rem;min-width:3.2rem}.pt-confirm-dialog-footer-buttons{justify-content:center;flex-wrap:wrap!important}::ng-deep .pt-confirm-dialog-button-slot .p-button,::ng-deep .pt-confirm-dialog-button-slot button{min-width:6.5rem}}\n"], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i3$6.ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "modal", "visible", "position", "draggable"], outputs: ["onHide"] }, { kind: "directive", type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: PTButtonComponent, selector: "pt-button", inputs: ["buttonConfig"] }] }); }
5184
5526
  }
5185
5527
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTConfirmDialogComponent, decorators: [{
5186
5528
  type: Component,
5187
- args: [{ selector: 'pt-confirm-dialog', providers: [ConfirmationService], standalone: false, template: "<!-- src/app/shared/pt-confirm-dialog/pt-confirm-dialog.component.html -->\n\n<div class=\"pt-confirm-dialog\">\n <p-confirmDialog #cd>\n <ng-template pTemplate=\"header\"></ng-template>\n\n <ng-template pTemplate=\"message\">\n <div class=\"pt-confirm-dialog-card\">\n <div class=\"pt-confirm-dialog-card-top\">\n <div class=\"pt-confirm-dialog-icon-wrapper\">\n <i\n class=\"pt-confirm-dialog-icon\"\n [class]=\"getDialogIconClass()\"\n [ngStyle]=\"getDialogIconStyle()\"\n ></i>\n </div>\n\n <div class=\"pt-confirm-dialog-text-wrapper\">\n <div\n class=\"pt-confirm-dialog-title\"\n [ngStyle]=\"getDialogHeaderStyle()\"\n >\n {{ getDialogHeaderText() }}\n </div>\n\n @if (dialogBodyTpl) {\n <ng-container\n [ngTemplateOutlet]=\"dialogBodyTpl\"\n ></ng-container>\n } @else {\n <div\n class=\"pt-confirm-dialog-message\"\n [ngStyle]=\"getDialogContentStyle()\"\n >\n {{ getDialogContentText() }}\n </div>\n }\n\n </div>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"pt-confirm-dialog-footer-buttons\">\n @if (dialogConfig.cancelButtonConfig) {\n <pt-button\n [buttonConfig]=\"cancelButtonModel\"\n (click)=\"cd.onReject()\"\n ></pt-button>\n }\n\n @if (dialogConfig.confirmButtonConfig) {\n <pt-button\n [buttonConfig]=\"confirmButtonModel\"\n (click)=\"onConfirmClick(cd)\"\n ></pt-button>\n }\n </div>\n </ng-template>\n </p-confirmDialog>\n</div>\n", styles: ["::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay{width:520px;max-width:92vw;height:auto!important;min-height:unset!important;max-height:none!important;display:block!important;border-radius:18px;overflow:hidden;box-shadow:0 20px 45px #0f172a59}::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay .p-dialog-header{display:none!important;padding:0!important;border:0!important;height:0!important;min-height:0!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay .p-dialog-content{display:block!important;flex:unset!important;flex-grow:0!important;flex-shrink:0!important;flex-basis:auto!important;height:auto!important;min-height:unset!important;max-height:none!important;padding:0!important;margin:0!important;overflow:visible!important;background:transparent!important;border-top-left-radius:18px;border-top-right-radius:18px}::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay .p-confirm-dialog-message{display:block!important;flex:unset!important;height:auto!important;min-height:unset!important;max-height:none!important;margin:0!important;padding:0!important;width:100%!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay .p-dialog-footer{display:block!important;flex:unset!important;flex-grow:0!important;flex-shrink:0!important;flex-basis:auto!important;height:auto!important;min-height:unset!important;max-height:none!important;background:#fff;border-top:1px solid rgba(148,163,184,.25);padding:16px 32px 22px!important;margin:0!important}.pt-confirm-dialog-card{width:100%;height:auto!important;min-height:unset!important;max-height:none!important;border-radius:18px 18px 0 0;overflow:hidden}.pt-confirm-dialog-card-top{height:auto!important;min-height:unset!important;max-height:none!important;padding:28px 40px;display:flex;align-items:flex-start}::ng-deep .p-confirm-dialog.pt-confirm-dialog-danger .pt-confirm-dialog-card{background-color:#fde4e4}::ng-deep .p-confirm-dialog.pt-confirm-dialog-warning .pt-confirm-dialog-card{background-color:#fff4d1}::ng-deep .p-confirm-dialog.pt-confirm-dialog-success .pt-confirm-dialog-card{background-color:#dcfce7}::ng-deep .p-confirm-dialog.pt-confirm-dialog-info .pt-confirm-dialog-card{background-color:#e0f2fe}.pt-confirm-dialog-icon-wrapper{width:60px;height:60px;min-width:60px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin-right:18px;box-sizing:border-box}.pt-confirm-dialog-icon{font-size:30px;line-height:1;color:#b91c1c}.pt-confirm-dialog-text-wrapper{flex:1;min-width:0}.pt-confirm-dialog-title{font-size:22px;font-weight:700;margin-bottom:8px;color:#b91c1c}.pt-confirm-dialog-message{font-size:18px;line-height:1.5;color:#4b5563;margin:0}.pt-confirm-dialog-footer-buttons{display:flex;justify-content:center;align-items: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-confirm-dialog-danger .p-dialog-footer .p-button{background:#fff!important;border-color:#dc2626!important;color:#dc2626!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-danger .p-dialog-footer .p-button:hover{background:#fef2f2!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-warning .p-dialog-footer .p-button{background:#fff!important;border-color:#d97706!important;color:#b45309!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-warning .p-dialog-footer .p-button:hover{background:#fffbeb!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-success .p-dialog-footer .p-button{background:#fff!important;border-color:#16a34a!important;color:#15803d!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-success .p-dialog-footer .p-button:hover{background:#f0fdf4!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-info .p-dialog-footer .p-button{background:#fff!important;border-color:#2563eb!important;color:#2563eb!important}::ng-deep .p-confirm-dialog.pt-confirm-dialog-info .p-dialog-footer .p-button:hover{background:#eff6ff!important}@media(max-width:768px){::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay{width:calc(100vw - 2rem)!important;max-width:calc(100vw - 2rem)!important}.pt-confirm-dialog-card-top{padding:24px}.pt-confirm-dialog-icon-wrapper{width:48px;height:48px;min-width:48px;margin-right:14px}.pt-confirm-dialog-title{font-size:19px}.pt-confirm-dialog-message{font-size:16px}::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay .p-dialog-footer{padding:14px 20px 18px!important}.pt-confirm-dialog-footer-buttons{gap:10px;flex-wrap:wrap}}\n"] }]
5188
- }], ctorParameters: () => [{ type: i1$1.ConfirmationService }, { type: i0.Renderer2 }], propDecorators: { dialogConfig: [{
5529
+ args: [{ selector: 'pt-confirm-dialog', providers: [ConfirmationService], standalone: false, template: "<div class=\"pt-confirm-dialog\">\n <p-confirmDialog\n #cd\n [styleClass]=\"overlayStyleClass\"\n [appendTo]=\"'body'\"\n [closable]=\"false\"\n [closeOnEscape]=\"false\"\n >\n <ng-template pTemplate=\"header\"></ng-template>\n\n <ng-template pTemplate=\"message\">\n <div class=\"pt-confirm-dialog-wrapper\">\n <div class=\"pt-confirm-dialog-body\" [ngStyle]=\"getDialogBodyStyle()\">\n <button\n type=\"button\"\n class=\"pt-confirm-dialog-close\"\n aria-label=\"Fermer\"\n (click)=\"onCancelClick()\"\n >\n <i class=\"pi pi-times\"></i>\n </button>\n\n <div class=\"pt-confirm-dialog-content\">\n <div\n class=\"pt-confirm-dialog-icon-wrapper\"\n [ngStyle]=\"getIconWrapperStyle()\"\n >\n <i\n class=\"pt-confirm-dialog-icon\"\n [class]=\"getDialogIconClass()\"\n [ngStyle]=\"getDialogIconStyle()\"\n ></i>\n </div>\n\n <div class=\"pt-confirm-dialog-text-wrapper\">\n <h3\n class=\"pt-confirm-dialog-title\"\n [ngStyle]=\"getDialogHeaderStyle()\"\n >\n {{ getDialogHeaderText() }}\n </h3>\n\n @if (dialogBodyTpl) {\n <ng-container [ngTemplateOutlet]=\"dialogBodyTpl\"></ng-container>\n } @else {\n <p\n class=\"pt-confirm-dialog-message-text\"\n [ngStyle]=\"getDialogContentStyle()\"\n >\n {{ getDialogContentText() }}\n </p>\n }\n </div>\n </div>\n </div>\n\n @if (hasFooter()) {\n <div class=\"pt-confirm-dialog-custom-footer\">\n <div\n class=\"pt-confirm-dialog-footer-buttons\"\n [ngStyle]=\"getFooterButtonsStyle()\"\n >\n @if (dialogConfig.cancelButtonConfig) {\n <div class=\"pt-confirm-dialog-button-slot\">\n <pt-button\n [buttonConfig]=\"cancelButtonModel\"\n (click)=\"onCancelClick()\"\n ></pt-button>\n </div>\n }\n\n @if (dialogConfig.confirmButtonConfig) {\n <div class=\"pt-confirm-dialog-button-slot\">\n <pt-button\n [buttonConfig]=\"confirmButtonModel\"\n (click)=\"onConfirmClick()\"\n ></pt-button>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </ng-template>\n </p-confirmDialog>\n</div>\n", styles: ["::ng-deep .pt-confirm-dialog-overlay.p-dialog,::ng-deep .p-dialog.pt-confirm-dialog-overlay,::ng-deep .pt-confirm-dialog-overlay.p-confirm-dialog,::ng-deep .p-confirm-dialog.pt-confirm-dialog-overlay,::ng-deep .pt-confirm-dialog-overlay.p-confirmdialog,::ng-deep .p-confirmdialog.pt-confirm-dialog-overlay{width:560px!important;max-width:calc(100vw - 2rem)!important;height:auto!important;min-height:unset!important;max-height:none!important;border:0!important;border-radius:28px!important;overflow:hidden!important;background:#fff!important;box-shadow:0 24px 60px #0f172a4d!important}::ng-deep .pt-confirm-dialog-overlay .p-dialog-header{display:none!important;padding:0!important;border:0!important;height:0!important;min-height:0!important}::ng-deep .pt-confirm-dialog-overlay .p-dialog-content{padding:0!important;margin:0!important;overflow:hidden!important;background:transparent!important}::ng-deep .pt-confirm-dialog-overlay .p-confirm-dialog-message,::ng-deep .pt-confirm-dialog-overlay .p-confirmdialog-message{display:block!important;width:100%!important;margin:0!important;padding:0!important}::ng-deep .pt-confirm-dialog-overlay .p-dialog-footer{display:none!important;padding:0!important;margin:0!important;border:0!important;height:0!important;min-height:0!important;max-height:0!important}.pt-confirm-dialog-wrapper{width:100%;background:#fff;overflow:hidden}.pt-confirm-dialog-body{position:relative;width:100%;min-height:190px;padding:2rem 2.25rem;border-bottom:1px solid;box-sizing:border-box}.pt-confirm-dialog-no-footer .pt-confirm-dialog-body{border-bottom:0!important}.pt-confirm-dialog-content{display:flex;align-items:center;gap:1.25rem;min-height:126px;padding-right:3rem}.pt-confirm-dialog-text-wrapper{flex:1;min-width:0}.pt-confirm-dialog-title{margin:0 0 .45rem;line-height:1.25}.pt-confirm-dialog-message-text{margin:0;line-height:1.55;font-weight:400}.pt-confirm-dialog-close{position:absolute;top:1.25rem;right:1.25rem;z-index:5;width:2.75rem;height:2.75rem;border:2px solid currentColor;border-radius:999px;background:#ffffffd9;color:#64748b;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;pointer-events:auto;transition:background-color .2s ease,color .2s ease,transform .2s ease}.pt-confirm-dialog-close:hover{background:#fff;color:#0f172a;transform:scale(1.04)}.pt-confirm-dialog-close i{font-size:1.15rem}.pt-confirm-dialog-icon-wrapper{width:4.25rem;height:4.25rem;min-width:4.25rem;border:1px solid;border-radius:999px;display:flex;align-items:center;justify-content:center}.pt-confirm-dialog-icon{line-height:1}.pt-confirm-dialog-custom-footer{width:100%;padding:1rem 1.5rem 1.35rem;background:#fff;box-sizing:border-box}.pt-confirm-dialog-footer-buttons{display:flex!important;flex-direction:row!important;align-items:center!important;flex-wrap:nowrap!important;gap:.75rem;width:100%}.pt-confirm-dialog-button-slot{display:inline-flex!important;flex:0 0 auto!important;width:auto!important;max-width:max-content!important}::ng-deep .pt-confirm-dialog-button-slot>pt-button{display:inline-flex!important;flex:0 0 auto!important;width:auto!important;max-width:max-content!important}::ng-deep .pt-confirm-dialog-button-slot p-button,::ng-deep .pt-confirm-dialog-button-slot>p-button{display:inline-flex!important;flex:0 0 auto!important;width:auto!important;max-width:max-content!important}::ng-deep .pt-confirm-dialog-button-slot .p-button,::ng-deep .pt-confirm-dialog-button-slot button{width:auto!important;min-width:7.5rem;max-width:max-content!important;border-radius:999px!important;padding:.7rem 1.35rem!important;font-weight:600!important;white-space:nowrap!important}::ng-deep .pt-confirm-dialog-button-slot .p-button .pi{margin-right:.45rem}@media(max-width:768px){.pt-confirm-dialog-body{min-height:170px;padding:1.5rem}.pt-confirm-dialog-content{gap:.85rem;padding-right:2rem}.pt-confirm-dialog-icon-wrapper{width:3.2rem;height:3.2rem;min-width:3.2rem}.pt-confirm-dialog-footer-buttons{justify-content:center;flex-wrap:wrap!important}::ng-deep .pt-confirm-dialog-button-slot .p-button,::ng-deep .pt-confirm-dialog-button-slot button{min-width:6.5rem}}\n"] }]
5530
+ }], ctorParameters: () => [{ type: i1$1.ConfirmationService }], propDecorators: { dialogConfig: [{
5189
5531
  type: Input
5190
5532
  }], formGroup: [{
5191
5533
  type: Input
@@ -5199,9 +5541,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
5199
5541
  }], projectedFormBuilder: [{
5200
5542
  type: ContentChild,
5201
5543
  args: [PTFormBuilderComponent]
5544
+ }], onEscapeKey: [{
5545
+ type: HostListener,
5546
+ args: ['document:keydown.escape', ['$event']]
5202
5547
  }] } });
5203
5548
 
5204
- // src/app/shared/pt-confirm-dialog/pt-confirm-dialog.module.ts
5205
5549
  class PTConfirmDialogModule {
5206
5550
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTConfirmDialogModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
5207
5551
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.14", ngImport: i0, type: PTConfirmDialogModule, declarations: [PTConfirmDialogComponent], imports: [CommonModule, ConfirmDialogModule, PTButtonModule], exports: [PTConfirmDialogComponent] }); }
@@ -5449,6 +5793,7 @@ class NgPrimeToolsModule {
5449
5793
  PTSwitchInputModule,
5450
5794
  PTTextAreaInputModule,
5451
5795
  PTTextInputModule,
5796
+ PTMultiSelectModule,
5452
5797
  // Dashboard
5453
5798
  PTMetricCardModule,
5454
5799
  PTMetricCardGroupModule,
@@ -5486,6 +5831,7 @@ class NgPrimeToolsModule {
5486
5831
  PTSwitchInputModule,
5487
5832
  PTTextAreaInputModule,
5488
5833
  PTTextInputModule,
5834
+ PTMultiSelectModule,
5489
5835
  // Dashboard
5490
5836
  PTMetricCardModule,
5491
5837
  PTMetricCardGroupModule,
@@ -5527,6 +5873,7 @@ class NgPrimeToolsModule {
5527
5873
  PTSwitchInputModule,
5528
5874
  PTTextAreaInputModule,
5529
5875
  PTTextInputModule,
5876
+ PTMultiSelectModule,
5530
5877
  // Dashboard
5531
5878
  PTMetricCardModule,
5532
5879
  PTMetricCardGroupModule,
@@ -5564,6 +5911,7 @@ class NgPrimeToolsModule {
5564
5911
  PTSwitchInputModule,
5565
5912
  PTTextAreaInputModule,
5566
5913
  PTTextInputModule,
5914
+ PTMultiSelectModule,
5567
5915
  // Dashboard
5568
5916
  PTMetricCardModule,
5569
5917
  PTMetricCardGroupModule,
@@ -5610,6 +5958,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
5610
5958
  PTSwitchInputModule,
5611
5959
  PTTextAreaInputModule,
5612
5960
  PTTextInputModule,
5961
+ PTMultiSelectModule,
5613
5962
  // Dashboard
5614
5963
  PTMetricCardModule,
5615
5964
  PTMetricCardGroupModule,
@@ -5650,6 +5999,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
5650
5999
  PTSwitchInputModule,
5651
6000
  PTTextAreaInputModule,
5652
6001
  PTTextInputModule,
6002
+ PTMultiSelectModule,
5653
6003
  // Dashboard
5654
6004
  PTMetricCardModule,
5655
6005
  PTMetricCardGroupModule,
@@ -6111,5 +6461,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6111
6461
  * Generated bundle index. Do not edit.
6112
6462
  */
6113
6463
 
6114
- export { AlignEnum, BadgeType, BadgeTypeStyles, ButtonColorEnum, DateUtilityService, FormInputTypeEnum, InputValidationEnum, MultiSearchCriteriaComponent, MultiSearchCriteriaModule, NgPrimeToolsModule, PTAdvancedPrimeTableComponent, PTAdvancedPrimeTableModule, PTBreadCrumbComponent, PTBreadCrumbModule, PTButtonComponent, PTButtonModule, PTCardComponent, PTCardModule, PTChartComparisonComponent, PTChartComparisonModule, PTChartComponent, PTChartModule, PTCheckBoxInputComponent, PTCheckBoxInputModule, PTConfirmDialogComponent, PTConfirmDialogModule, PTDateInputComponent, PTDateInputModule, PTDialogComponent, PTDialogModule, PTDropdownComponent, PTDropdownModule, PTFooterComponent, PTFooterModule, PTFormBuilderComponent, PTFormBuilderModule, PTGroupComponent, PTGroupModule, PTLineChartComponent, PTLineChartModule, PTLoginPageComponent, PTLoginPageModule, PTMenuComponent, PTMenuFancyComponent, PTMenuFancyModule, PTMenuModule, PTMetricCardComponent, PTMetricCardGroupComponent, PTMetricCardGroupModule, PTMetricCardModule, PTMetricPanelComponent, PTMetricPanelModule, PTNavbarMenuComponent, PTNavbarMenuModule, PTNumberInputComponent, PTNumberInputModule, PTPageSkeletonComponent, PTPageSkeletonModule, PTSideBarMenuComponent, PTSideBarMenuModule, PTSwitchInputComponent, PTSwitchInputModule, PTTextAreaInputComponent, PTTextAreaInputModule, PTTextInputComponent, PTTextInputModule, PTToastNotifierComponent, PTToastNotifierModule, SearchCriteriaTypeEnum, SeverityEnum, TableTypeEnum };
6464
+ export { AlignEnum, BadgeType, BadgeTypeStyles, ButtonColorEnum, DateUtilityService, FormInputTypeEnum, InputValidationEnum, MultiSearchCriteriaComponent, MultiSearchCriteriaModule, NgPrimeToolsModule, PTAdvancedPrimeTableComponent, PTAdvancedPrimeTableModule, PTBreadCrumbComponent, PTBreadCrumbModule, PTButtonComponent, PTButtonModule, PTCardComponent, PTCardModule, PTChartComparisonComponent, PTChartComparisonModule, PTChartComponent, PTChartModule, PTCheckBoxInputComponent, PTCheckBoxInputModule, PTConfirmDialogComponent, PTConfirmDialogModule, PTDateInputComponent, PTDateInputModule, PTDialogComponent, PTDialogModule, PTDropdownComponent, PTDropdownModule, PTFooterComponent, PTFooterModule, PTFormBuilderComponent, PTFormBuilderModule, PTGroupComponent, PTGroupModule, PTLineChartComponent, PTLineChartModule, PTLoginPageComponent, PTLoginPageModule, PTMenuComponent, PTMenuFancyComponent, PTMenuFancyModule, PTMenuModule, PTMetricCardComponent, PTMetricCardGroupComponent, PTMetricCardGroupModule, PTMetricCardModule, PTMetricPanelComponent, PTMetricPanelModule, PTMultiSelectComponent, PTMultiSelectModule, PTNavbarMenuComponent, PTNavbarMenuModule, PTNumberInputComponent, PTNumberInputModule, PTPageSkeletonComponent, PTPageSkeletonModule, PTSideBarMenuComponent, PTSideBarMenuModule, PTSwitchInputComponent, PTSwitchInputModule, PTTextAreaInputComponent, PTTextAreaInputModule, PTTextInputComponent, PTTextInputModule, PTToastNotifierComponent, PTToastNotifierModule, SearchCriteriaTypeEnum, SeverityEnum, TableTypeEnum };
6115
6465
  //# sourceMappingURL=ng-prime-tools.mjs.map