ng-prime-tools 1.0.88 → 1.0.90

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.
@@ -45,6 +45,8 @@ import * as i6$1 from 'primeng/password';
45
45
  import { PasswordModule } from 'primeng/password';
46
46
  import * as i3$5 from 'primeng/select';
47
47
  import { SelectModule } from 'primeng/select';
48
+ import * as i3$6 from 'primeng/inputotp';
49
+ import { InputOtpModule } from 'primeng/inputotp';
48
50
  import { Chart, registerables } from 'chart.js';
49
51
  import ChartDataLabels from 'chartjs-plugin-datalabels';
50
52
  import { Subject, interval, BehaviorSubject } from 'rxjs';
@@ -53,7 +55,7 @@ import * as i1$2 from '@angular/router';
53
55
  import { RouterModule, NavigationEnd } from '@angular/router';
54
56
  import * as i2$1 from 'primeng/breadcrumb';
55
57
  import { BreadcrumbModule } from 'primeng/breadcrumb';
56
- import * as i3$6 from 'primeng/confirmdialog';
58
+ import * as i3$7 from 'primeng/confirmdialog';
57
59
  import { ConfirmDialogModule } from 'primeng/confirmdialog';
58
60
  import * as i2$2 from 'primeng/toast';
59
61
  import { ToastModule } from 'primeng/toast';
@@ -1791,6 +1793,7 @@ var FormInputTypeEnum;
1791
1793
  FormInputTypeEnum["CHECKBOX"] = "CHECKBOX";
1792
1794
  FormInputTypeEnum["SWITCH"] = "SWITCH";
1793
1795
  FormInputTypeEnum["PASSWORD"] = "PASSWORD";
1796
+ FormInputTypeEnum["OTP"] = "OTP";
1794
1797
  })(FormInputTypeEnum || (FormInputTypeEnum = {}));
1795
1798
 
1796
1799
  var ButtonColorEnum;
@@ -3123,6 +3126,116 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
3123
3126
  type: Output
3124
3127
  }] } });
3125
3128
 
3129
+ class PTOtpInputComponent {
3130
+ ngOnInit() {
3131
+ this.initializeDefaults();
3132
+ this.setupControl();
3133
+ }
3134
+ ngOnDestroy() {
3135
+ this.valueChangesSubscription?.unsubscribe();
3136
+ }
3137
+ get inputId() {
3138
+ return `pt-otp-input-${this.formField?.name || 'field'}`;
3139
+ }
3140
+ get resolvedLength() {
3141
+ return this.formField.otpLength ?? 6;
3142
+ }
3143
+ get resolvedIntegerOnly() {
3144
+ return this.formField.otpIntegerOnly ?? true;
3145
+ }
3146
+ get resolvedMask() {
3147
+ return this.formField.otpMask ?? false;
3148
+ }
3149
+ get control() {
3150
+ return this.formGroup.get(this.formField.name);
3151
+ }
3152
+ setupControl() {
3153
+ const control = this.control;
3154
+ if (!control) {
3155
+ return;
3156
+ }
3157
+ control.setValidators(this.getValidators());
3158
+ this.valueChangesSubscription?.unsubscribe();
3159
+ if (this.formField.disabled) {
3160
+ control.disable({ emitEvent: false });
3161
+ }
3162
+ else {
3163
+ control.enable({ emitEvent: false });
3164
+ this.valueChangesSubscription = control.valueChanges.subscribe((value) => {
3165
+ this.normalizeOtpValue(value);
3166
+ });
3167
+ }
3168
+ control.updateValueAndValidity({ emitEvent: false });
3169
+ }
3170
+ hasError() {
3171
+ const control = this.control;
3172
+ return !!(control?.invalid && (control.touched || control.dirty));
3173
+ }
3174
+ getErrorMessage() {
3175
+ const control = this.control;
3176
+ if (control?.hasError('required')) {
3177
+ return (this.formField.errorText ??
3178
+ `${this.formField.label ?? 'OTP code'} is required`);
3179
+ }
3180
+ if (control?.hasError('pattern')) {
3181
+ return (this.formField.errorText ??
3182
+ `${this.formField.label ?? 'OTP code'} must contain exactly ${this.resolvedLength} ${this.resolvedIntegerOnly ? 'digits' : 'characters'}`);
3183
+ }
3184
+ return '';
3185
+ }
3186
+ initializeDefaults() {
3187
+ this.formField = {
3188
+ required: true,
3189
+ otpLength: 6,
3190
+ otpIntegerOnly: true,
3191
+ otpMask: false,
3192
+ width: '100%',
3193
+ ...this.formField,
3194
+ };
3195
+ }
3196
+ getValidators() {
3197
+ const validators = [];
3198
+ if (this.formField.required) {
3199
+ validators.push(Validators.required);
3200
+ }
3201
+ validators.push(Validators.pattern(this.buildOtpPattern()));
3202
+ return validators;
3203
+ }
3204
+ buildOtpPattern() {
3205
+ if (this.resolvedIntegerOnly) {
3206
+ return new RegExp(`^[0-9]{${this.resolvedLength}}$`);
3207
+ }
3208
+ return new RegExp(`^[A-Za-z0-9]{${this.resolvedLength}}$`);
3209
+ }
3210
+ normalizeOtpValue(value) {
3211
+ const control = this.control;
3212
+ if (!control || value === null || value === undefined) {
3213
+ return;
3214
+ }
3215
+ let normalizedValue = String(value).trim();
3216
+ if (this.resolvedIntegerOnly) {
3217
+ normalizedValue = normalizedValue.replace(/[^0-9]/g, '');
3218
+ }
3219
+ else {
3220
+ normalizedValue = normalizedValue.replace(/[^A-Za-z0-9]/g, '');
3221
+ }
3222
+ normalizedValue = normalizedValue.slice(0, this.resolvedLength);
3223
+ if (normalizedValue !== String(value)) {
3224
+ control.setValue(normalizedValue, { emitEvent: false });
3225
+ }
3226
+ }
3227
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3228
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTOtpInputComponent, isStandalone: false, selector: "pt-otp-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 class=\"field-label\">\n {{ formField.label }}\n </label>\n }\n\n <div class=\"otp-input-wrapper\">\n <p-inputOtp\n [formControlName]=\"formField.name\"\n [length]=\"resolvedLength\"\n [integerOnly]=\"resolvedIntegerOnly\"\n [mask]=\"resolvedMask\"\n [readonly]=\"formField.disabled ?? false\"\n styleClass=\"pt-otp-input\"\n ></p-inputOtp>\n </div>\n\n @if (hasError()) {\n <div class=\"form-info-row\">\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;width:100%}.form-field{width:100%}.field-label{display:block;margin-bottom:.85rem;color:#172554;font-size:1.1rem;font-weight:700;letter-spacing:.01em}.otp-input-wrapper{display:flex;width:100%;justify-content:center}.form-info-row{display:flex;min-height:1.35rem;margin-top:.65rem;justify-content:center}.field-error{color:#fca5a5;font-size:.82rem;font-weight:600;text-align:center}:host ::ng-deep .pt-otp-input{display:flex;width:100%;justify-content:center;gap:.7rem}:host ::ng-deep .pt-otp-input .p-inputotp-input{width:3.7rem;height:4rem;border:2px solid rgba(255,255,255,.62);border-radius:.85rem;background:#fffffff0;box-shadow:0 6px 14px #0f172a29,inset 0 1px #ffffffe6;color:#172554;font-size:1.75rem;font-weight:800;text-align:center;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease}:host ::ng-deep .pt-otp-input .p-inputotp-input:hover{border-color:#60a5fa;transform:translateY(-2px)}:host ::ng-deep .pt-otp-input .p-inputotp-input:focus{border-color:#2563eb;box-shadow:0 0 0 4px #2563eb33,0 8px 18px #0f172a33;outline:none}@media(max-width:480px){:host ::ng-deep .pt-otp-input{gap:.42rem}:host ::ng-deep .pt-otp-input .p-inputotp-input{width:2.85rem;height:3.3rem;font-size:1.4rem}}\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$6.InputOtp, selector: "p-inputOtp, p-inputotp, p-input-otp", inputs: ["readonly", "tabindex", "length", "styleClass", "mask", "integerOnly", "autofocus", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }] }); }
3229
+ }
3230
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpInputComponent, decorators: [{
3231
+ type: Component,
3232
+ args: [{ selector: 'pt-otp-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 class=\"field-label\">\n {{ formField.label }}\n </label>\n }\n\n <div class=\"otp-input-wrapper\">\n <p-inputOtp\n [formControlName]=\"formField.name\"\n [length]=\"resolvedLength\"\n [integerOnly]=\"resolvedIntegerOnly\"\n [mask]=\"resolvedMask\"\n [readonly]=\"formField.disabled ?? false\"\n styleClass=\"pt-otp-input\"\n ></p-inputOtp>\n </div>\n\n @if (hasError()) {\n <div class=\"form-info-row\">\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;width:100%}.form-field{width:100%}.field-label{display:block;margin-bottom:.85rem;color:#172554;font-size:1.1rem;font-weight:700;letter-spacing:.01em}.otp-input-wrapper{display:flex;width:100%;justify-content:center}.form-info-row{display:flex;min-height:1.35rem;margin-top:.65rem;justify-content:center}.field-error{color:#fca5a5;font-size:.82rem;font-weight:600;text-align:center}:host ::ng-deep .pt-otp-input{display:flex;width:100%;justify-content:center;gap:.7rem}:host ::ng-deep .pt-otp-input .p-inputotp-input{width:3.7rem;height:4rem;border:2px solid rgba(255,255,255,.62);border-radius:.85rem;background:#fffffff0;box-shadow:0 6px 14px #0f172a29,inset 0 1px #ffffffe6;color:#172554;font-size:1.75rem;font-weight:800;text-align:center;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease}:host ::ng-deep .pt-otp-input .p-inputotp-input:hover{border-color:#60a5fa;transform:translateY(-2px)}:host ::ng-deep .pt-otp-input .p-inputotp-input:focus{border-color:#2563eb;box-shadow:0 0 0 4px #2563eb33,0 8px 18px #0f172a33;outline:none}@media(max-width:480px){:host ::ng-deep .pt-otp-input{gap:.42rem}:host ::ng-deep .pt-otp-input .p-inputotp-input{width:2.85rem;height:3.3rem;font-size:1.4rem}}\n"] }]
3233
+ }], propDecorators: { formGroup: [{
3234
+ type: Input
3235
+ }], formField: [{
3236
+ type: Input
3237
+ }] } });
3238
+
3126
3239
  class PTDynamicFormFieldComponent {
3127
3240
  constructor() {
3128
3241
  this.FormInputTypeEnum = FormInputTypeEnum;
@@ -3151,12 +3264,15 @@ class PTDynamicFormFieldComponent {
3151
3264
  asSwitchField(field) {
3152
3265
  return field;
3153
3266
  }
3267
+ asOtpField(field) {
3268
+ return field;
3269
+ }
3154
3270
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDynamicFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3155
- 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.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\n <!-- EMAIL -->\n @case (FormInputTypeEnum.EMAIL) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- NUMBER -->\n @case (FormInputTypeEnum.NUMBER) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- AMOUNT -->\n @case (FormInputTypeEnum.AMOUNT) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\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\n <!-- DATE -->\n @case (FormInputTypeEnum.DATE) {\n <pt-date-input\n [formGroup]=\"form\"\n [formField]=\"asDateField(field)\"\n ></pt-date-input>\n }\n\n <!-- MULTISELECT -->\n @case (FormInputTypeEnum.MULTISELECT) {\n <pt-multi-select\n [formGroup]=\"form\"\n [formField]=\"asMultiSelectField(field)\"\n ></pt-multi-select>\n }\n\n <!-- SELECT -->\n @case (FormInputTypeEnum.SELECT) {\n <pt-dropdown\n [formGroup]=\"form\"\n [formField]=\"asSelectField(field)\"\n ></pt-dropdown>\n }\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\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", "config", "value"], outputs: ["valueChange", "switchChange"] }, { 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"] }] }); }
3271
+ 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.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\n <!-- EMAIL -->\n @case (FormInputTypeEnum.EMAIL) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- NUMBER -->\n @case (FormInputTypeEnum.NUMBER) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- AMOUNT -->\n @case (FormInputTypeEnum.AMOUNT) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\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\n <!-- DATE -->\n @case (FormInputTypeEnum.DATE) {\n <pt-date-input\n [formGroup]=\"form\"\n [formField]=\"asDateField(field)\"\n ></pt-date-input>\n }\n\n <!-- MULTISELECT -->\n @case (FormInputTypeEnum.MULTISELECT) {\n <pt-multi-select\n [formGroup]=\"form\"\n [formField]=\"asMultiSelectField(field)\"\n ></pt-multi-select>\n }\n\n <!-- SELECT -->\n @case (FormInputTypeEnum.SELECT) {\n <pt-dropdown\n [formGroup]=\"form\"\n [formField]=\"asSelectField(field)\"\n ></pt-dropdown>\n }\n\n <!-- OTP -->\n @case (FormInputTypeEnum.OTP) {\n <pt-otp-input\n [formGroup]=\"form\"\n [formField]=\"asOtpField(field)\"\n ></pt-otp-input>\n }\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\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", "config", "value"], outputs: ["valueChange", "switchChange"] }, { 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"] }, { kind: "component", type: PTOtpInputComponent, selector: "pt-otp-input", inputs: ["formGroup", "formField"] }] }); }
3156
3272
  }
3157
3273
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDynamicFormFieldComponent, decorators: [{
3158
3274
  type: Component,
3159
- args: [{ selector: 'pt-dynamic-form-field', standalone: false, template: "<div\n [formGroup]=\"form\"\n class=\"form-field\"\n [ngStyle]=\"{\n width:\n field.type !== FormInputTypeEnum.CHECKBOX\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\n <!-- EMAIL -->\n @case (FormInputTypeEnum.EMAIL) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- NUMBER -->\n @case (FormInputTypeEnum.NUMBER) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- AMOUNT -->\n @case (FormInputTypeEnum.AMOUNT) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\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\n <!-- DATE -->\n @case (FormInputTypeEnum.DATE) {\n <pt-date-input\n [formGroup]=\"form\"\n [formField]=\"asDateField(field)\"\n ></pt-date-input>\n }\n\n <!-- MULTISELECT -->\n @case (FormInputTypeEnum.MULTISELECT) {\n <pt-multi-select\n [formGroup]=\"form\"\n [formField]=\"asMultiSelectField(field)\"\n ></pt-multi-select>\n }\n\n <!-- SELECT -->\n @case (FormInputTypeEnum.SELECT) {\n <pt-dropdown\n [formGroup]=\"form\"\n [formField]=\"asSelectField(field)\"\n ></pt-dropdown>\n }\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\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"] }]
3275
+ args: [{ selector: 'pt-dynamic-form-field', standalone: false, template: "<div\n [formGroup]=\"form\"\n class=\"form-field\"\n [ngStyle]=\"{\n width:\n field.type !== FormInputTypeEnum.CHECKBOX\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\n <!-- EMAIL -->\n @case (FormInputTypeEnum.EMAIL) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- NUMBER -->\n @case (FormInputTypeEnum.NUMBER) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- AMOUNT -->\n @case (FormInputTypeEnum.AMOUNT) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\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\n <!-- DATE -->\n @case (FormInputTypeEnum.DATE) {\n <pt-date-input\n [formGroup]=\"form\"\n [formField]=\"asDateField(field)\"\n ></pt-date-input>\n }\n\n <!-- MULTISELECT -->\n @case (FormInputTypeEnum.MULTISELECT) {\n <pt-multi-select\n [formGroup]=\"form\"\n [formField]=\"asMultiSelectField(field)\"\n ></pt-multi-select>\n }\n\n <!-- SELECT -->\n @case (FormInputTypeEnum.SELECT) {\n <pt-dropdown\n [formGroup]=\"form\"\n [formField]=\"asSelectField(field)\"\n ></pt-dropdown>\n }\n\n <!-- OTP -->\n @case (FormInputTypeEnum.OTP) {\n <pt-otp-input\n [formGroup]=\"form\"\n [formField]=\"asOtpField(field)\"\n ></pt-otp-input>\n }\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\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"] }]
3160
3276
  }], propDecorators: { field: [{
3161
3277
  type: Input
3162
3278
  }], form: [{
@@ -3266,11 +3382,22 @@ class PTFormBuilderComponent {
3266
3382
  case FormInputTypeEnum.EMAIL:
3267
3383
  validators.push(Validators.email);
3268
3384
  break;
3385
+ case FormInputTypeEnum.OTP:
3386
+ validators.push(Validators.pattern(this.buildOtpPattern(field)));
3387
+ break;
3269
3388
  default:
3270
3389
  break;
3271
3390
  }
3272
3391
  return validators;
3273
3392
  }
3393
+ buildOtpPattern(field) {
3394
+ const length = field.otpLength ?? 6;
3395
+ const integerOnly = field.otpIntegerOnly ?? true;
3396
+ if (integerOnly) {
3397
+ return new RegExp(`^[0-9]{${length}}$`);
3398
+ }
3399
+ return new RegExp(`^[A-Za-z0-9]{${length}}$`);
3400
+ }
3274
3401
  isInvalid(field) {
3275
3402
  const control = this.form.get(field.name);
3276
3403
  return !!control && control.invalid && (control.touched || control.dirty);
@@ -3493,6 +3620,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
3493
3620
  }]
3494
3621
  }] });
3495
3622
 
3623
+ class PTOtpInputModule {
3624
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpInputModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3625
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.14", ngImport: i0, type: PTOtpInputModule, declarations: [PTOtpInputComponent], imports: [CommonModule, FormsModule, ReactiveFormsModule, InputOtpModule], exports: [PTOtpInputComponent] }); }
3626
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpInputModule, imports: [CommonModule, FormsModule, ReactiveFormsModule, InputOtpModule] }); }
3627
+ }
3628
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpInputModule, decorators: [{
3629
+ type: NgModule,
3630
+ args: [{
3631
+ declarations: [PTOtpInputComponent],
3632
+ imports: [CommonModule, FormsModule, ReactiveFormsModule, InputOtpModule],
3633
+ exports: [PTOtpInputComponent],
3634
+ }]
3635
+ }] });
3636
+
3496
3637
  class PTDynamicFormFieldModule {
3497
3638
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDynamicFormFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3498
3639
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.14", ngImport: i0, type: PTDynamicFormFieldModule, declarations: [PTDynamicFormFieldComponent], imports: [CommonModule,
@@ -3505,7 +3646,8 @@ class PTDynamicFormFieldModule {
3505
3646
  PTTextAreaInputModule,
3506
3647
  PTTextInputModule,
3507
3648
  PTDropdownModule,
3508
- PTMultiSelectModule], exports: [PTDynamicFormFieldComponent] }); }
3649
+ PTMultiSelectModule,
3650
+ PTOtpInputModule], exports: [PTDynamicFormFieldComponent] }); }
3509
3651
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDynamicFormFieldModule, imports: [CommonModule,
3510
3652
  ReactiveFormsModule,
3511
3653
  // Inputs
@@ -3516,7 +3658,8 @@ class PTDynamicFormFieldModule {
3516
3658
  PTTextAreaInputModule,
3517
3659
  PTTextInputModule,
3518
3660
  PTDropdownModule,
3519
- PTMultiSelectModule] }); }
3661
+ PTMultiSelectModule,
3662
+ PTOtpInputModule] }); }
3520
3663
  }
3521
3664
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDynamicFormFieldModule, decorators: [{
3522
3665
  type: NgModule,
@@ -3534,6 +3677,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
3534
3677
  PTTextInputModule,
3535
3678
  PTDropdownModule,
3536
3679
  PTMultiSelectModule,
3680
+ PTOtpInputModule,
3537
3681
  ],
3538
3682
  exports: [PTDynamicFormFieldComponent],
3539
3683
  }]
@@ -6037,7 +6181,7 @@ class PTLoginCardComponent {
6037
6181
  };
6038
6182
  }
6039
6183
  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 }); }
6040
- 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 @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 <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 @if (loginErrorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ loginErrorMessage }}\n </div>\n }\n\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (loginPageConfig.login?.errorMessage) {\n <div class=\"error-message\" role=\"alert\">\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 <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"loginPageConfig.buttonConfig!\"></pt-button>\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 [rel]=\"\n loginPageConfig.forgotPasswordConfig?.target === '_blank'\n ? 'noopener noreferrer'\n : null\n \"\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 @if (visibleAdditionalContent.length > 0) {\n <div class=\"additional-content-list\">\n @for (item of visibleAdditionalContent; track item.id || $index) {\n <div\n class=\"additional-content-item\"\n [ngClass]=\"getAdditionalContentClass(item)\"\n [ngStyle]=\"item.style\"\n >\n @switch (item.type) {\n @case (\"link\") {\n @if (item.linkText && item.url) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n }\n }\n\n @case (\"text-with-link\") {\n @if (\n item.linkPosition === \"before\" && item.linkText && item.url\n ) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n } @else {\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n\n @if (item.linkText && item.url) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n }\n }\n }\n\n @default {\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n }\n }\n </div>\n }\n </div>\n }\n </form>\n\n <div class=\"login-footer\">\n {{ loginPageConfig.footer?.version }}\n\n <span>\n {{ loginPageConfig.footer?.copyright }}\n </span>\n </div>\n</pt-card>\n", styles: [":host{display:block;width:100%;min-width:0}.logo-container{display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem}.logo-container img{display:block;max-width:100%;object-fit:contain}.title-container{margin-bottom:1.25rem;text-align:center}.title-container h1{margin:0;line-height:1.25}.form-container{width:100%}.field{display:flex;flex-direction:column;width:100%;margin-bottom:1.25rem}.error-message{width:100%;box-sizing:border-box;margin-bottom:.75rem;padding:.75rem .875rem;color:var(--p-message-error-color, #b91c1c);background:var(--p-message-error-background, #fef2f2);border:1px solid var(--p-message-error-border-color, #fecaca);border-radius:var(--p-content-border-radius, .5rem);font-size:.875rem;line-height:1.4;text-align:center}.submit-btn{display:flex;justify-content:center;width:100%}:host ::ng-deep .submit-btn pt-button{display:block;width:100%}:host ::ng-deep .submit-btn p-button,:host ::ng-deep .submit-btn p-button button{width:100%}.forgot-password-container{display:flex;width:100%;box-sizing:border-box;margin-top:.875rem;margin-bottom:0;font-size:.875rem;line-height:1.4}.forgot-password-left{justify-content:flex-start;text-align:left}.forgot-password-center{justify-content:center;text-align:center}.forgot-password-right{justify-content:flex-end;text-align:right}.forgot-password-link,.additional-content-link{color:var(--p-primary-color, #2563eb);font-size:.875rem;font-weight:500;line-height:1.4;text-decoration:none;cursor:pointer;transition:color .16s ease,text-decoration-color .16s ease}.forgot-password-link:hover,.additional-content-link:hover{color:var(--p-primary-hover-color, #1d4ed8);text-decoration:underline;text-underline-offset:.2rem}.forgot-password-link:focus-visible,.additional-content-link:focus-visible{outline:2px solid var(--p-primary-color, #2563eb);outline-offset:.2rem;border-radius:.2rem}.additional-content-list{display:flex;flex-direction:column;width:100%;margin-top:1rem;gap:.55rem}.forgot-password-container+.additional-content-list{margin-top:.75rem}.additional-content-item{display:flex;flex-wrap:wrap;align-items:baseline;width:100%;box-sizing:border-box;gap:.3rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.875rem;line-height:1.45}.additional-content-left{justify-content:flex-start;text-align:left}.additional-content-center{justify-content:center;text-align:center}.additional-content-right{justify-content:flex-end;text-align:right}.additional-content-text{color:inherit}.login-footer{margin-top:1.25rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.8rem;line-height:1.4;text-align:center}.login-footer span{display:block;margin-top:.25rem}:host-context(.p-dark) .error-message,:host-context(.app-dark) .error-message,:host-context(.dark) .error-message,:host-context(.dark-mode) .error-message,:host-context([data-theme=\"dark\"]) .error-message{color:var(--p-message-error-color, #fca5a5);background:var(--p-message-error-background, rgba(127, 29, 29, .25));border-color:var(--p-message-error-border-color, rgba(248, 113, 113, .4))}:host-context(.p-dark) .forgot-password-link,:host-context(.app-dark) .forgot-password-link,:host-context(.dark) .forgot-password-link,:host-context(.dark-mode) .forgot-password-link,:host-context([data-theme=\"dark\"]) .forgot-password-link,:host-context(.p-dark) .additional-content-link,:host-context(.app-dark) .additional-content-link,:host-context(.dark) .additional-content-link,:host-context(.dark-mode) .additional-content-link,:host-context([data-theme=\"dark\"]) .additional-content-link{color:var(--p-primary-color, #60a5fa)}:host-context(.p-dark) .forgot-password-link:hover,:host-context(.app-dark) .forgot-password-link:hover,:host-context(.dark) .forgot-password-link:hover,:host-context(.dark-mode) .forgot-password-link:hover,:host-context([data-theme=\"dark\"]) .forgot-password-link:hover,:host-context(.p-dark) .additional-content-link:hover,:host-context(.app-dark) .additional-content-link:hover,:host-context(.dark) .additional-content-link:hover,:host-context(.dark-mode) .additional-content-link:hover,:host-context([data-theme=\"dark\"]) .additional-content-link:hover{color:var(--p-primary-hover-color, #93c5fd)}:host-context(.p-dark) .additional-content-item,:host-context(.app-dark) .additional-content-item,:host-context(.dark) .additional-content-item,:host-context(.dark-mode) .additional-content-item,:host-context([data-theme=\"dark\"]) .additional-content-item,:host-context(.p-dark) .login-footer,:host-context(.app-dark) .login-footer,:host-context(.dark) .login-footer,:host-context(.dark-mode) .login-footer,:host-context([data-theme=\"dark\"]) .login-footer{color:var(--p-text-muted-color, var(--text-color-secondary, #cbd5e1))}@media(max-width:768px){:host ::ng-deep pt-card{width:100%;max-width:100%}.submit-btn{min-width:100%}.forgot-password-container{margin-top:.75rem}.additional-content-list{margin-top:.875rem}.forgot-password-container+.additional-content-list{margin-top:.65rem}}@media(max-width:480px){.logo-container,.title-container,.field{margin-bottom:1rem}.forgot-password-container,.forgot-password-link,.additional-content-item,.additional-content-link{font-size:.82rem}.additional-content-list{gap:.5rem}}\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"] }] }); }
6184
+ 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 @if (loginPageConfig.logoUrl; as logoUrl) {\n @if (logoUrl.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"logoUrl.imageUrl\"\n [alt]=\"logoUrl.altText || 'Logo'\"\n [style.width]=\"logoUrl.width || '100px'\"\n [style.height]=\"logoUrl.height || 'auto'\"\n />\n </div>\n }\n }\n\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 @if (loginErrorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ loginErrorMessage }}\n </div>\n }\n\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (loginPageConfig.login; as login) {\n @if (login.errorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ login.errorMessage }}\n </div>\n }\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 <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"loginPageConfig.buttonConfig!\"></pt-button>\n </div>\n\n @if (loginPageConfig.forgotPasswordConfig; as forgotPasswordConfig) {\n @if (forgotPasswordConfig.text && forgotPasswordConfig.url) {\n <div\n class=\"forgot-password-container\"\n [ngClass]=\"\n 'forgot-password-' + (forgotPasswordConfig.align || 'center')\n \"\n >\n <a\n [href]=\"forgotPasswordConfig.url\"\n [target]=\"forgotPasswordConfig.target || '_self'\"\n [rel]=\"\n forgotPasswordConfig.target === '_blank'\n ? 'noopener noreferrer'\n : null\n \"\n [ngStyle]=\"forgotPasswordConfig.style\"\n [class]=\"forgotPasswordConfig.styleClass || 'forgot-password-link'\"\n >\n {{ forgotPasswordConfig.text }}\n </a>\n </div>\n }\n }\n\n @if (visibleAdditionalContent.length > 0) {\n <div class=\"additional-content-list\">\n @for (item of visibleAdditionalContent; track item.id || $index) {\n <div\n class=\"additional-content-item\"\n [ngClass]=\"getAdditionalContentClass(item)\"\n [ngStyle]=\"item.style\"\n >\n @switch (item.type) {\n @case (\"link\") {\n @if (item.linkText && item.url) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n }\n }\n\n @case (\"text-with-link\") {\n @if (\n item.linkPosition === \"before\" && item.linkText && item.url\n ) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n } @else {\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n\n @if (item.linkText && item.url) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n }\n }\n }\n\n @default {\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n }\n }\n </div>\n }\n </div>\n }\n </form>\n\n <div class=\"login-footer\">\n {{ loginPageConfig.footer?.version }}\n\n <span>\n {{ loginPageConfig.footer?.copyright }}\n </span>\n </div>\n</pt-card>\n", styles: [":host{display:block;width:100%;min-width:0}.logo-container{display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem}.logo-container img{display:block;max-width:100%;object-fit:contain}.title-container{margin-bottom:1.25rem;text-align:center}.title-container h1{margin:0;line-height:1.25}.form-container{width:100%}.field{display:flex;flex-direction:column;width:100%;margin-bottom:1.25rem}.error-message{width:100%;box-sizing:border-box;margin-bottom:.75rem;padding:.75rem .875rem;color:var(--p-message-error-color, #b91c1c);background:var(--p-message-error-background, #fef2f2);border:1px solid var(--p-message-error-border-color, #fecaca);border-radius:var(--p-content-border-radius, .5rem);font-size:.875rem;line-height:1.4;text-align:center}.submit-btn{display:flex;justify-content:center;width:100%}:host ::ng-deep .submit-btn pt-button{display:block;width:100%}:host ::ng-deep .submit-btn p-button,:host ::ng-deep .submit-btn p-button button{width:100%}.forgot-password-container{display:flex;width:100%;box-sizing:border-box;margin-top:.875rem;margin-bottom:0;font-size:.875rem;line-height:1.4}.forgot-password-left{justify-content:flex-start;text-align:left}.forgot-password-center{justify-content:center;text-align:center}.forgot-password-right{justify-content:flex-end;text-align:right}.forgot-password-link,.additional-content-link{color:var(--p-primary-color, #2563eb);font-size:.875rem;font-weight:500;line-height:1.4;text-decoration:none;cursor:pointer;transition:color .16s ease,text-decoration-color .16s ease}.forgot-password-link:hover,.additional-content-link:hover{color:var(--p-primary-hover-color, #1d4ed8);text-decoration:underline;text-underline-offset:.2rem}.forgot-password-link:focus-visible,.additional-content-link:focus-visible{outline:2px solid var(--p-primary-color, #2563eb);outline-offset:.2rem;border-radius:.2rem}.additional-content-list{display:flex;flex-direction:column;width:100%;margin-top:1rem;gap:.55rem}.forgot-password-container+.additional-content-list{margin-top:.75rem}.additional-content-item{display:flex;flex-wrap:wrap;align-items:baseline;width:100%;box-sizing:border-box;gap:.3rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.875rem;line-height:1.45}.additional-content-left{justify-content:flex-start;text-align:left}.additional-content-center{justify-content:center;text-align:center}.additional-content-right{justify-content:flex-end;text-align:right}.additional-content-text{color:inherit}.login-footer{margin-top:1.25rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.8rem;line-height:1.4;text-align:center}.login-footer span{display:block;margin-top:.25rem}:host-context(.p-dark) .error-message,:host-context(.app-dark) .error-message,:host-context(.dark) .error-message,:host-context(.dark-mode) .error-message,:host-context([data-theme=\"dark\"]) .error-message{color:var(--p-message-error-color, #fca5a5);background:var(--p-message-error-background, rgba(127, 29, 29, .25));border-color:var(--p-message-error-border-color, rgba(248, 113, 113, .4))}:host-context(.p-dark) .forgot-password-link,:host-context(.app-dark) .forgot-password-link,:host-context(.dark) .forgot-password-link,:host-context(.dark-mode) .forgot-password-link,:host-context([data-theme=\"dark\"]) .forgot-password-link,:host-context(.p-dark) .additional-content-link,:host-context(.app-dark) .additional-content-link,:host-context(.dark) .additional-content-link,:host-context(.dark-mode) .additional-content-link,:host-context([data-theme=\"dark\"]) .additional-content-link{color:var(--p-primary-color, #60a5fa)}:host-context(.p-dark) .forgot-password-link:hover,:host-context(.app-dark) .forgot-password-link:hover,:host-context(.dark) .forgot-password-link:hover,:host-context(.dark-mode) .forgot-password-link:hover,:host-context([data-theme=\"dark\"]) .forgot-password-link:hover,:host-context(.p-dark) .additional-content-link:hover,:host-context(.app-dark) .additional-content-link:hover,:host-context(.dark) .additional-content-link:hover,:host-context(.dark-mode) .additional-content-link:hover,:host-context([data-theme=\"dark\"]) .additional-content-link:hover{color:var(--p-primary-hover-color, #93c5fd)}:host-context(.p-dark) .additional-content-item,:host-context(.app-dark) .additional-content-item,:host-context(.dark) .additional-content-item,:host-context(.dark-mode) .additional-content-item,:host-context([data-theme=\"dark\"]) .additional-content-item,:host-context(.p-dark) .login-footer,:host-context(.app-dark) .login-footer,:host-context(.dark) .login-footer,:host-context(.dark-mode) .login-footer,:host-context([data-theme=\"dark\"]) .login-footer{color:var(--p-text-muted-color, var(--text-color-secondary, #cbd5e1))}@media(max-width:768px){:host ::ng-deep pt-card{width:100%;max-width:100%}.submit-btn{min-width:100%}.forgot-password-container{margin-top:.75rem}.additional-content-list{margin-top:.875rem}.forgot-password-container+.additional-content-list{margin-top:.65rem}}@media(max-width:480px){.logo-container,.title-container,.field{margin-bottom:1rem}.forgot-password-container,.forgot-password-link,.additional-content-item,.additional-content-link{font-size:.82rem}.additional-content-list{gap:.5rem}}\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"] }] }); }
6041
6185
  }
6042
6186
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTLoginCardComponent, decorators: [{
6043
6187
  type: Component,
@@ -6048,7 +6192,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6048
6192
  PTCardModule,
6049
6193
  PTButtonModule,
6050
6194
  PTTextInputModule,
6051
- ], template: "<pt-card [config]=\"loginPageConfig.loginCardConfig!\">\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 <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 @if (loginErrorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ loginErrorMessage }}\n </div>\n }\n\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (loginPageConfig.login?.errorMessage) {\n <div class=\"error-message\" role=\"alert\">\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 <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"loginPageConfig.buttonConfig!\"></pt-button>\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 [rel]=\"\n loginPageConfig.forgotPasswordConfig?.target === '_blank'\n ? 'noopener noreferrer'\n : null\n \"\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 @if (visibleAdditionalContent.length > 0) {\n <div class=\"additional-content-list\">\n @for (item of visibleAdditionalContent; track item.id || $index) {\n <div\n class=\"additional-content-item\"\n [ngClass]=\"getAdditionalContentClass(item)\"\n [ngStyle]=\"item.style\"\n >\n @switch (item.type) {\n @case (\"link\") {\n @if (item.linkText && item.url) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n }\n }\n\n @case (\"text-with-link\") {\n @if (\n item.linkPosition === \"before\" && item.linkText && item.url\n ) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n } @else {\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n\n @if (item.linkText && item.url) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n }\n }\n }\n\n @default {\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n }\n }\n </div>\n }\n </div>\n }\n </form>\n\n <div class=\"login-footer\">\n {{ loginPageConfig.footer?.version }}\n\n <span>\n {{ loginPageConfig.footer?.copyright }}\n </span>\n </div>\n</pt-card>\n", styles: [":host{display:block;width:100%;min-width:0}.logo-container{display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem}.logo-container img{display:block;max-width:100%;object-fit:contain}.title-container{margin-bottom:1.25rem;text-align:center}.title-container h1{margin:0;line-height:1.25}.form-container{width:100%}.field{display:flex;flex-direction:column;width:100%;margin-bottom:1.25rem}.error-message{width:100%;box-sizing:border-box;margin-bottom:.75rem;padding:.75rem .875rem;color:var(--p-message-error-color, #b91c1c);background:var(--p-message-error-background, #fef2f2);border:1px solid var(--p-message-error-border-color, #fecaca);border-radius:var(--p-content-border-radius, .5rem);font-size:.875rem;line-height:1.4;text-align:center}.submit-btn{display:flex;justify-content:center;width:100%}:host ::ng-deep .submit-btn pt-button{display:block;width:100%}:host ::ng-deep .submit-btn p-button,:host ::ng-deep .submit-btn p-button button{width:100%}.forgot-password-container{display:flex;width:100%;box-sizing:border-box;margin-top:.875rem;margin-bottom:0;font-size:.875rem;line-height:1.4}.forgot-password-left{justify-content:flex-start;text-align:left}.forgot-password-center{justify-content:center;text-align:center}.forgot-password-right{justify-content:flex-end;text-align:right}.forgot-password-link,.additional-content-link{color:var(--p-primary-color, #2563eb);font-size:.875rem;font-weight:500;line-height:1.4;text-decoration:none;cursor:pointer;transition:color .16s ease,text-decoration-color .16s ease}.forgot-password-link:hover,.additional-content-link:hover{color:var(--p-primary-hover-color, #1d4ed8);text-decoration:underline;text-underline-offset:.2rem}.forgot-password-link:focus-visible,.additional-content-link:focus-visible{outline:2px solid var(--p-primary-color, #2563eb);outline-offset:.2rem;border-radius:.2rem}.additional-content-list{display:flex;flex-direction:column;width:100%;margin-top:1rem;gap:.55rem}.forgot-password-container+.additional-content-list{margin-top:.75rem}.additional-content-item{display:flex;flex-wrap:wrap;align-items:baseline;width:100%;box-sizing:border-box;gap:.3rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.875rem;line-height:1.45}.additional-content-left{justify-content:flex-start;text-align:left}.additional-content-center{justify-content:center;text-align:center}.additional-content-right{justify-content:flex-end;text-align:right}.additional-content-text{color:inherit}.login-footer{margin-top:1.25rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.8rem;line-height:1.4;text-align:center}.login-footer span{display:block;margin-top:.25rem}:host-context(.p-dark) .error-message,:host-context(.app-dark) .error-message,:host-context(.dark) .error-message,:host-context(.dark-mode) .error-message,:host-context([data-theme=\"dark\"]) .error-message{color:var(--p-message-error-color, #fca5a5);background:var(--p-message-error-background, rgba(127, 29, 29, .25));border-color:var(--p-message-error-border-color, rgba(248, 113, 113, .4))}:host-context(.p-dark) .forgot-password-link,:host-context(.app-dark) .forgot-password-link,:host-context(.dark) .forgot-password-link,:host-context(.dark-mode) .forgot-password-link,:host-context([data-theme=\"dark\"]) .forgot-password-link,:host-context(.p-dark) .additional-content-link,:host-context(.app-dark) .additional-content-link,:host-context(.dark) .additional-content-link,:host-context(.dark-mode) .additional-content-link,:host-context([data-theme=\"dark\"]) .additional-content-link{color:var(--p-primary-color, #60a5fa)}:host-context(.p-dark) .forgot-password-link:hover,:host-context(.app-dark) .forgot-password-link:hover,:host-context(.dark) .forgot-password-link:hover,:host-context(.dark-mode) .forgot-password-link:hover,:host-context([data-theme=\"dark\"]) .forgot-password-link:hover,:host-context(.p-dark) .additional-content-link:hover,:host-context(.app-dark) .additional-content-link:hover,:host-context(.dark) .additional-content-link:hover,:host-context(.dark-mode) .additional-content-link:hover,:host-context([data-theme=\"dark\"]) .additional-content-link:hover{color:var(--p-primary-hover-color, #93c5fd)}:host-context(.p-dark) .additional-content-item,:host-context(.app-dark) .additional-content-item,:host-context(.dark) .additional-content-item,:host-context(.dark-mode) .additional-content-item,:host-context([data-theme=\"dark\"]) .additional-content-item,:host-context(.p-dark) .login-footer,:host-context(.app-dark) .login-footer,:host-context(.dark) .login-footer,:host-context(.dark-mode) .login-footer,:host-context([data-theme=\"dark\"]) .login-footer{color:var(--p-text-muted-color, var(--text-color-secondary, #cbd5e1))}@media(max-width:768px){:host ::ng-deep pt-card{width:100%;max-width:100%}.submit-btn{min-width:100%}.forgot-password-container{margin-top:.75rem}.additional-content-list{margin-top:.875rem}.forgot-password-container+.additional-content-list{margin-top:.65rem}}@media(max-width:480px){.logo-container,.title-container,.field{margin-bottom:1rem}.forgot-password-container,.forgot-password-link,.additional-content-item,.additional-content-link{font-size:.82rem}.additional-content-list{gap:.5rem}}\n"] }]
6195
+ ], template: "<pt-card [config]=\"loginPageConfig.loginCardConfig!\">\n @if (loginPageConfig.logoUrl; as logoUrl) {\n @if (logoUrl.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"logoUrl.imageUrl\"\n [alt]=\"logoUrl.altText || 'Logo'\"\n [style.width]=\"logoUrl.width || '100px'\"\n [style.height]=\"logoUrl.height || 'auto'\"\n />\n </div>\n }\n }\n\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 @if (loginErrorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ loginErrorMessage }}\n </div>\n }\n\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (loginPageConfig.login; as login) {\n @if (login.errorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ login.errorMessage }}\n </div>\n }\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 <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"loginPageConfig.buttonConfig!\"></pt-button>\n </div>\n\n @if (loginPageConfig.forgotPasswordConfig; as forgotPasswordConfig) {\n @if (forgotPasswordConfig.text && forgotPasswordConfig.url) {\n <div\n class=\"forgot-password-container\"\n [ngClass]=\"\n 'forgot-password-' + (forgotPasswordConfig.align || 'center')\n \"\n >\n <a\n [href]=\"forgotPasswordConfig.url\"\n [target]=\"forgotPasswordConfig.target || '_self'\"\n [rel]=\"\n forgotPasswordConfig.target === '_blank'\n ? 'noopener noreferrer'\n : null\n \"\n [ngStyle]=\"forgotPasswordConfig.style\"\n [class]=\"forgotPasswordConfig.styleClass || 'forgot-password-link'\"\n >\n {{ forgotPasswordConfig.text }}\n </a>\n </div>\n }\n }\n\n @if (visibleAdditionalContent.length > 0) {\n <div class=\"additional-content-list\">\n @for (item of visibleAdditionalContent; track item.id || $index) {\n <div\n class=\"additional-content-item\"\n [ngClass]=\"getAdditionalContentClass(item)\"\n [ngStyle]=\"item.style\"\n >\n @switch (item.type) {\n @case (\"link\") {\n @if (item.linkText && item.url) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n }\n }\n\n @case (\"text-with-link\") {\n @if (\n item.linkPosition === \"before\" && item.linkText && item.url\n ) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n } @else {\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n\n @if (item.linkText && item.url) {\n <a\n [href]=\"item.url\"\n [target]=\"item.target || '_self'\"\n [rel]=\"getLinkRel(item)\"\n [class]=\"item.linkStyleClass || 'additional-content-link'\"\n [ngStyle]=\"item.linkStyle\"\n >\n {{ item.linkText }}\n </a>\n }\n }\n }\n\n @default {\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n }\n }\n </div>\n }\n </div>\n }\n </form>\n\n <div class=\"login-footer\">\n {{ loginPageConfig.footer?.version }}\n\n <span>\n {{ loginPageConfig.footer?.copyright }}\n </span>\n </div>\n</pt-card>\n", styles: [":host{display:block;width:100%;min-width:0}.logo-container{display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem}.logo-container img{display:block;max-width:100%;object-fit:contain}.title-container{margin-bottom:1.25rem;text-align:center}.title-container h1{margin:0;line-height:1.25}.form-container{width:100%}.field{display:flex;flex-direction:column;width:100%;margin-bottom:1.25rem}.error-message{width:100%;box-sizing:border-box;margin-bottom:.75rem;padding:.75rem .875rem;color:var(--p-message-error-color, #b91c1c);background:var(--p-message-error-background, #fef2f2);border:1px solid var(--p-message-error-border-color, #fecaca);border-radius:var(--p-content-border-radius, .5rem);font-size:.875rem;line-height:1.4;text-align:center}.submit-btn{display:flex;justify-content:center;width:100%}:host ::ng-deep .submit-btn pt-button{display:block;width:100%}:host ::ng-deep .submit-btn p-button,:host ::ng-deep .submit-btn p-button button{width:100%}.forgot-password-container{display:flex;width:100%;box-sizing:border-box;margin-top:.875rem;margin-bottom:0;font-size:.875rem;line-height:1.4}.forgot-password-left{justify-content:flex-start;text-align:left}.forgot-password-center{justify-content:center;text-align:center}.forgot-password-right{justify-content:flex-end;text-align:right}.forgot-password-link,.additional-content-link{color:var(--p-primary-color, #2563eb);font-size:.875rem;font-weight:500;line-height:1.4;text-decoration:none;cursor:pointer;transition:color .16s ease,text-decoration-color .16s ease}.forgot-password-link:hover,.additional-content-link:hover{color:var(--p-primary-hover-color, #1d4ed8);text-decoration:underline;text-underline-offset:.2rem}.forgot-password-link:focus-visible,.additional-content-link:focus-visible{outline:2px solid var(--p-primary-color, #2563eb);outline-offset:.2rem;border-radius:.2rem}.additional-content-list{display:flex;flex-direction:column;width:100%;margin-top:1rem;gap:.55rem}.forgot-password-container+.additional-content-list{margin-top:.75rem}.additional-content-item{display:flex;flex-wrap:wrap;align-items:baseline;width:100%;box-sizing:border-box;gap:.3rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.875rem;line-height:1.45}.additional-content-left{justify-content:flex-start;text-align:left}.additional-content-center{justify-content:center;text-align:center}.additional-content-right{justify-content:flex-end;text-align:right}.additional-content-text{color:inherit}.login-footer{margin-top:1.25rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.8rem;line-height:1.4;text-align:center}.login-footer span{display:block;margin-top:.25rem}:host-context(.p-dark) .error-message,:host-context(.app-dark) .error-message,:host-context(.dark) .error-message,:host-context(.dark-mode) .error-message,:host-context([data-theme=\"dark\"]) .error-message{color:var(--p-message-error-color, #fca5a5);background:var(--p-message-error-background, rgba(127, 29, 29, .25));border-color:var(--p-message-error-border-color, rgba(248, 113, 113, .4))}:host-context(.p-dark) .forgot-password-link,:host-context(.app-dark) .forgot-password-link,:host-context(.dark) .forgot-password-link,:host-context(.dark-mode) .forgot-password-link,:host-context([data-theme=\"dark\"]) .forgot-password-link,:host-context(.p-dark) .additional-content-link,:host-context(.app-dark) .additional-content-link,:host-context(.dark) .additional-content-link,:host-context(.dark-mode) .additional-content-link,:host-context([data-theme=\"dark\"]) .additional-content-link{color:var(--p-primary-color, #60a5fa)}:host-context(.p-dark) .forgot-password-link:hover,:host-context(.app-dark) .forgot-password-link:hover,:host-context(.dark) .forgot-password-link:hover,:host-context(.dark-mode) .forgot-password-link:hover,:host-context([data-theme=\"dark\"]) .forgot-password-link:hover,:host-context(.p-dark) .additional-content-link:hover,:host-context(.app-dark) .additional-content-link:hover,:host-context(.dark) .additional-content-link:hover,:host-context(.dark-mode) .additional-content-link:hover,:host-context([data-theme=\"dark\"]) .additional-content-link:hover{color:var(--p-primary-hover-color, #93c5fd)}:host-context(.p-dark) .additional-content-item,:host-context(.app-dark) .additional-content-item,:host-context(.dark) .additional-content-item,:host-context(.dark-mode) .additional-content-item,:host-context([data-theme=\"dark\"]) .additional-content-item,:host-context(.p-dark) .login-footer,:host-context(.app-dark) .login-footer,:host-context(.dark) .login-footer,:host-context(.dark-mode) .login-footer,:host-context([data-theme=\"dark\"]) .login-footer{color:var(--p-text-muted-color, var(--text-color-secondary, #cbd5e1))}@media(max-width:768px){:host ::ng-deep pt-card{width:100%;max-width:100%}.submit-btn{min-width:100%}.forgot-password-container{margin-top:.75rem}.additional-content-list{margin-top:.875rem}.forgot-password-container+.additional-content-list{margin-top:.65rem}}@media(max-width:480px){.logo-container,.title-container,.field{margin-bottom:1rem}.forgot-password-container,.forgot-password-link,.additional-content-item,.additional-content-link{font-size:.82rem}.additional-content-list{gap:.5rem}}\n"] }]
6052
6196
  }], ctorParameters: () => [{ type: i2.FormBuilder }], propDecorators: { loginPageConfig: [{
6053
6197
  type: Input
6054
6198
  }], loginErrorMessage: [{
@@ -6475,7 +6619,7 @@ class PTConfirmDialogComponent {
6475
6619
  }
6476
6620
  }
6477
6621
  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 }); }
6478
- 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:var(--pt-confirm-dialog-bg, #ffffff)!important;box-shadow:var( --pt-confirm-dialog-shadow, 0 24px 60px rgba(15, 23, 42, .3) )!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:var(--pt-confirm-dialog-bg, #ffffff);color:var(--pt-confirm-dialog-text, #0f172a);overflow:hidden}.pt-confirm-dialog-body{position:relative;width:100%;min-height:190px;padding:2rem 2.25rem;border-bottom:1px solid var(--pt-confirm-dialog-border, #e5e7eb);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;color:var(--pt-confirm-dialog-title, #0f172a)}.pt-confirm-dialog-message-text{margin:0;line-height:1.55;font-weight:400;color:var(--pt-confirm-dialog-message, #475569)}.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:var(--pt-confirm-dialog-close-bg, rgba(255, 255, 255, .85));color:var(--pt-confirm-dialog-close-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:var(--pt-confirm-dialog-close-hover-bg, #ffffff);color:var(--pt-confirm-dialog-close-hover-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:var(--pt-confirm-dialog-footer-bg, #ffffff);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"] }] }); }
6622
+ 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:var(--pt-confirm-dialog-bg, #ffffff)!important;box-shadow:var( --pt-confirm-dialog-shadow, 0 24px 60px rgba(15, 23, 42, .3) )!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:var(--pt-confirm-dialog-bg, #ffffff);color:var(--pt-confirm-dialog-text, #0f172a);overflow:hidden}.pt-confirm-dialog-body{position:relative;width:100%;min-height:190px;padding:2rem 2.25rem;border-bottom:1px solid var(--pt-confirm-dialog-border, #e5e7eb);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;color:var(--pt-confirm-dialog-title, #0f172a)}.pt-confirm-dialog-message-text{margin:0;line-height:1.55;font-weight:400;color:var(--pt-confirm-dialog-message, #475569)}.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:var(--pt-confirm-dialog-close-bg, rgba(255, 255, 255, .85));color:var(--pt-confirm-dialog-close-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:var(--pt-confirm-dialog-close-hover-bg, #ffffff);color:var(--pt-confirm-dialog-close-hover-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:var(--pt-confirm-dialog-footer-bg, #ffffff);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$7.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"] }] }); }
6479
6623
  }
6480
6624
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTConfirmDialogComponent, decorators: [{
6481
6625
  type: Component,
@@ -6732,6 +6876,272 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6732
6876
  }]
6733
6877
  }] });
6734
6878
 
6879
+ class PTOtpCardComponent {
6880
+ set otpErrorMessage(value) {
6881
+ this.externalOtpErrorMessage = value;
6882
+ if (value) {
6883
+ this.otpValidated = false;
6884
+ }
6885
+ }
6886
+ constructor(fb) {
6887
+ this.fb = fb;
6888
+ this.otpValidated = null;
6889
+ this.otpSubmit = new EventEmitter();
6890
+ this.backClick = new EventEmitter();
6891
+ this.externalOtpErrorMessage = null;
6892
+ this.destroy$ = new Subject();
6893
+ this.formGroup = this.fb.group({});
6894
+ }
6895
+ ngOnInit() {
6896
+ this.initializeDefaults();
6897
+ this.setupFormField();
6898
+ this.formGroup.patchValue({
6899
+ otpCode: this.otpPageConfig.otp?.otpCode ?? '',
6900
+ });
6901
+ this.updateButtonDisabledState(this.formGroup.invalid);
6902
+ this.formGroup.statusChanges
6903
+ .pipe(takeUntil(this.destroy$))
6904
+ .subscribe(() => {
6905
+ this.updateButtonDisabledState(this.formGroup.invalid);
6906
+ });
6907
+ this.otpControl?.valueChanges
6908
+ .pipe(takeUntil(this.destroy$))
6909
+ .subscribe(() => {
6910
+ this.clearOtpValidationState();
6911
+ });
6912
+ }
6913
+ ngOnDestroy() {
6914
+ this.destroy$.next();
6915
+ this.destroy$.complete();
6916
+ }
6917
+ get otpControl() {
6918
+ const otpCodeField = this.otpPageConfig.otpCodeField;
6919
+ if (!otpCodeField) {
6920
+ return null;
6921
+ }
6922
+ return this.formGroup.get(otpCodeField.name);
6923
+ }
6924
+ get otpIconClass() {
6925
+ return this.otpValidated === true ? 'pi pi-lock-open' : 'pi pi-lock';
6926
+ }
6927
+ get otpIconStateClass() {
6928
+ return this.otpValidated === true ? 'otp-icon-valid' : 'otp-icon-invalid';
6929
+ }
6930
+ onSubmit() {
6931
+ if (this.formGroup.invalid) {
6932
+ this.formGroup.markAllAsTouched();
6933
+ this.otpValidated = false;
6934
+ this.otpPageConfig.otp = {
6935
+ ...this.otpPageConfig.otp,
6936
+ errorMessage: this.otpPageConfig.otp?.emptyFieldErrorMessage ??
6937
+ 'Veuillez saisir le code de vérification.',
6938
+ };
6939
+ return;
6940
+ }
6941
+ this.otpValidated = null;
6942
+ this.externalOtpErrorMessage = null;
6943
+ this.otpPageConfig.otp = {
6944
+ ...this.otpPageConfig.otp,
6945
+ errorMessage: '',
6946
+ };
6947
+ const otpCode = String(this.formGroup.getRawValue().otpCode ?? '').trim();
6948
+ this.otpSubmit.emit(otpCode);
6949
+ }
6950
+ onBack() {
6951
+ this.backClick.emit();
6952
+ }
6953
+ initializeDefaults() {
6954
+ this.otpPageConfig.logoUrl = {
6955
+ altText: 'Logo',
6956
+ imageUrl: '',
6957
+ width: '100px',
6958
+ height: 'auto',
6959
+ ...this.otpPageConfig.logoUrl,
6960
+ };
6961
+ this.otpPageConfig.title = {
6962
+ text: 'Vérification à deux facteurs',
6963
+ position: 'center',
6964
+ color: '#333',
6965
+ fontSize: '24px',
6966
+ ...this.otpPageConfig.title,
6967
+ };
6968
+ this.otpPageConfig.description = {
6969
+ text: 'Saisissez le code de vérification envoyé à votre adresse e-mail.',
6970
+ color: 'var(--p-text-muted-color, #64748b)',
6971
+ fontSize: '0.95rem',
6972
+ ...this.otpPageConfig.description,
6973
+ };
6974
+ this.otpPageConfig.otp = {
6975
+ otpCode: '',
6976
+ errorMessage: '',
6977
+ emptyFieldErrorMessage: 'Veuillez saisir le code de vérification.',
6978
+ ...this.otpPageConfig.otp,
6979
+ };
6980
+ this.otpPageConfig.otpCardConfig = {
6981
+ noBorder: true,
6982
+ width: '400px',
6983
+ padding: '40px',
6984
+ ...this.otpPageConfig.otpCardConfig,
6985
+ };
6986
+ this.otpPageConfig.otpCodeField = {
6987
+ name: 'otpCode',
6988
+ label: 'Code de vérification',
6989
+ required: true,
6990
+ placeholder: 'Saisissez le code à 6 chiffres',
6991
+ type: FormInputTypeEnum.OTP,
6992
+ otpLength: 6,
6993
+ otpIntegerOnly: true,
6994
+ otpMask: false,
6995
+ width: '100%',
6996
+ ...this.otpPageConfig.otpCodeField,
6997
+ };
6998
+ this.otpPageConfig.buttonConfig = {
6999
+ label: 'Vérifier le code',
7000
+ type: 'submit',
7001
+ icon: 'pi pi-shield',
7002
+ iconPos: 'left',
7003
+ styleClass: 'p-button-primary',
7004
+ disabled: true,
7005
+ width: '100%',
7006
+ ...this.otpPageConfig.buttonConfig,
7007
+ };
7008
+ this.otpPageConfig.backButtonConfig = {
7009
+ label: 'Retour',
7010
+ type: 'button',
7011
+ icon: 'pi pi-arrow-left',
7012
+ iconPos: 'left',
7013
+ styleClass: 'p-button-text',
7014
+ width: '100%',
7015
+ ...this.otpPageConfig.backButtonConfig,
7016
+ };
7017
+ this.otpPageConfig.footer = {
7018
+ version: 'V1.0',
7019
+ copyright: 'Your Company © 2026',
7020
+ ...this.otpPageConfig.footer,
7021
+ };
7022
+ }
7023
+ setupFormField() {
7024
+ const otpCodeField = this.otpPageConfig.otpCodeField;
7025
+ const otpLength = otpCodeField.otpLength ?? 6;
7026
+ const integerOnly = otpCodeField.otpIntegerOnly ?? true;
7027
+ const otpPattern = integerOnly
7028
+ ? new RegExp(`^[0-9]{${otpLength}}$`)
7029
+ : new RegExp(`^[A-Za-z0-9]{${otpLength}}$`);
7030
+ const validators = otpCodeField.required
7031
+ ? [Validators.required, Validators.pattern(otpPattern)]
7032
+ : [Validators.pattern(otpPattern)];
7033
+ this.formGroup.addControl(otpCodeField.name, this.fb.control(this.otpPageConfig.otp?.otpCode ?? '', validators));
7034
+ }
7035
+ clearOtpValidationState() {
7036
+ this.otpValidated = null;
7037
+ this.externalOtpErrorMessage = null;
7038
+ if (this.otpPageConfig.otp?.errorMessage) {
7039
+ this.otpPageConfig.otp = {
7040
+ ...this.otpPageConfig.otp,
7041
+ errorMessage: '',
7042
+ };
7043
+ }
7044
+ }
7045
+ updateButtonDisabledState(disabled) {
7046
+ this.otpPageConfig.buttonConfig = {
7047
+ ...this.otpPageConfig.buttonConfig,
7048
+ disabled,
7049
+ };
7050
+ }
7051
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpCardComponent, deps: [{ token: i2.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
7052
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTOtpCardComponent, isStandalone: true, selector: "pt-otp-card", inputs: { otpPageConfig: "otpPageConfig", otpErrorMessage: "otpErrorMessage", otpValidated: "otpValidated" }, outputs: { otpSubmit: "otpSubmit", backClick: "backClick" }, ngImport: i0, template: "<pt-card [config]=\"otpPageConfig.otpCardConfig!\">\n @if (otpPageConfig.logoUrl; as logoUrl) {\n @if (logoUrl.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"logoUrl.imageUrl\"\n [alt]=\"logoUrl.altText || 'Logo'\"\n [style.width]=\"logoUrl.width || '100px'\"\n [style.height]=\"logoUrl.height || 'auto'\"\n />\n </div>\n }\n }\n\n <div\n class=\"title-container\"\n [style.text-align]=\"otpPageConfig.title?.position || 'center'\"\n >\n <h1\n [ngStyle]=\"{\n color: otpPageConfig.title?.color || '#333',\n 'font-size': otpPageConfig.title?.fontSize || '24px',\n }\"\n >\n {{ otpPageConfig.title?.text }}\n </h1>\n </div>\n\n @if (otpPageConfig.description; as description) {\n @if (description.text) {\n <p\n class=\"description\"\n [ngStyle]=\"{\n color: description.color,\n 'font-size': description.fontSize,\n }\"\n >\n {{ description.text }}\n </p>\n }\n }\n\n <div class=\"otp-icon-container\" aria-hidden=\"true\">\n <div class=\"otp-icon\" [ngClass]=\"otpIconStateClass\">\n <i [class]=\"otpIconClass\"></i>\n </div>\n </div>\n\n @if (externalOtpErrorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ externalOtpErrorMessage }}\n </div>\n }\n\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (otpPageConfig.otp; as otp) {\n @if (otp.errorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ otp.errorMessage }}\n </div>\n }\n }\n\n <div class=\"field\">\n <pt-otp-input\n [formGroup]=\"formGroup\"\n [formField]=\"otpPageConfig.otpCodeField!\"\n ></pt-otp-input>\n </div>\n\n <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"otpPageConfig.buttonConfig!\"></pt-button>\n </div>\n\n <div class=\"back-btn\">\n <pt-button\n [buttonConfig]=\"otpPageConfig.backButtonConfig!\"\n (click)=\"onBack()\"\n ></pt-button>\n </div>\n </form>\n\n <div class=\"otp-footer\">\n {{ otpPageConfig.footer?.version }}\n\n <span>\n {{ otpPageConfig.footer?.copyright }}\n </span>\n </div>\n</pt-card>\n", styles: [":host{display:block;width:100%;min-width:0}.logo-container{display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem}.logo-container img{display:block;max-width:100%;object-fit:contain}.title-container{margin-bottom:.75rem}.title-container h1{margin:0;line-height:1.25}.description{margin:0;line-height:1.5;text-align:center}.otp-icon-container{display:flex;justify-content:center;width:100%;margin:1.25rem 0}.otp-icon{display:flex;align-items:center;justify-content:center;width:4.75rem;height:4.75rem;border:2px solid;border-radius:50%;transition:background-color .25s ease,border-color .25s ease,box-shadow .25s ease,transform .25s ease}.otp-icon i{font-size:2.1rem;transition:color .25s ease,transform .25s ease}.otp-icon-invalid{border-color:#fecacad9;background:#dc2626e6;box-shadow:0 10px 24px #7f1d1d59,inset 0 1px #ffffff47}.otp-icon-invalid i{color:#fff}.otp-icon-valid{border-color:#bbf7d0e6;background:#16a34af0;box-shadow:0 10px 24px #14532d59,inset 0 1px #ffffff4d;transform:scale(1.04)}.otp-icon-valid i{color:#fff;transform:scale(1.08)}.form-container{width:100%}.field{display:flex;flex-direction:column;width:100%;margin-bottom:1.25rem}.error-message{width:100%;box-sizing:border-box;margin-bottom:.75rem;padding:.75rem .875rem;color:var(--p-message-error-color, #b91c1c);background:var(--p-message-error-background, #fef2f2);border:1px solid var(--p-message-error-border-color, #fecaca);border-radius:var(--p-content-border-radius, .5rem);font-size:.875rem;line-height:1.4;text-align:center}.submit-btn,.back-btn{display:flex;justify-content:center;width:100%}.back-btn{margin-top:.5rem}:host ::ng-deep .submit-btn pt-button,:host ::ng-deep .back-btn pt-button,:host ::ng-deep .submit-btn p-button,:host ::ng-deep .back-btn p-button,:host ::ng-deep .submit-btn p-button button,:host ::ng-deep .back-btn p-button button{width:100%}.otp-footer{margin-top:1.25rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.8rem;line-height:1.4;text-align:center}.otp-footer span{display:block;margin-top:.25rem}:host-context(.p-dark) .error-message,:host-context(.app-dark) .error-message,:host-context(.dark) .error-message,:host-context([data-theme=\"dark\"]) .error-message{color:var(--p-message-error-color, #fca5a5);background:var(--p-message-error-background, rgba(127, 29, 29, .25));border-color:var(--p-message-error-border-color, rgba(248, 113, 113, .4))}@media(max-width:480px){.logo-container{margin-bottom:1rem}.otp-icon-container{margin:1rem 0}.otp-icon{width:4rem;height:4rem}.otp-icon i{font-size:1.75rem}.field{margin-bottom:1rem}}\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: ReactiveFormsModule }, { 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: "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: PTOtpInputModule }, { kind: "component", type: PTOtpInputComponent, selector: "pt-otp-input", inputs: ["formGroup", "formField"] }] }); }
7053
+ }
7054
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpCardComponent, decorators: [{
7055
+ type: Component,
7056
+ args: [{ selector: 'pt-otp-card', standalone: true, imports: [
7057
+ CommonModule,
7058
+ ReactiveFormsModule,
7059
+ PTCardModule,
7060
+ PTButtonModule,
7061
+ PTOtpInputModule,
7062
+ ], template: "<pt-card [config]=\"otpPageConfig.otpCardConfig!\">\n @if (otpPageConfig.logoUrl; as logoUrl) {\n @if (logoUrl.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"logoUrl.imageUrl\"\n [alt]=\"logoUrl.altText || 'Logo'\"\n [style.width]=\"logoUrl.width || '100px'\"\n [style.height]=\"logoUrl.height || 'auto'\"\n />\n </div>\n }\n }\n\n <div\n class=\"title-container\"\n [style.text-align]=\"otpPageConfig.title?.position || 'center'\"\n >\n <h1\n [ngStyle]=\"{\n color: otpPageConfig.title?.color || '#333',\n 'font-size': otpPageConfig.title?.fontSize || '24px',\n }\"\n >\n {{ otpPageConfig.title?.text }}\n </h1>\n </div>\n\n @if (otpPageConfig.description; as description) {\n @if (description.text) {\n <p\n class=\"description\"\n [ngStyle]=\"{\n color: description.color,\n 'font-size': description.fontSize,\n }\"\n >\n {{ description.text }}\n </p>\n }\n }\n\n <div class=\"otp-icon-container\" aria-hidden=\"true\">\n <div class=\"otp-icon\" [ngClass]=\"otpIconStateClass\">\n <i [class]=\"otpIconClass\"></i>\n </div>\n </div>\n\n @if (externalOtpErrorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ externalOtpErrorMessage }}\n </div>\n }\n\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (otpPageConfig.otp; as otp) {\n @if (otp.errorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ otp.errorMessage }}\n </div>\n }\n }\n\n <div class=\"field\">\n <pt-otp-input\n [formGroup]=\"formGroup\"\n [formField]=\"otpPageConfig.otpCodeField!\"\n ></pt-otp-input>\n </div>\n\n <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"otpPageConfig.buttonConfig!\"></pt-button>\n </div>\n\n <div class=\"back-btn\">\n <pt-button\n [buttonConfig]=\"otpPageConfig.backButtonConfig!\"\n (click)=\"onBack()\"\n ></pt-button>\n </div>\n </form>\n\n <div class=\"otp-footer\">\n {{ otpPageConfig.footer?.version }}\n\n <span>\n {{ otpPageConfig.footer?.copyright }}\n </span>\n </div>\n</pt-card>\n", styles: [":host{display:block;width:100%;min-width:0}.logo-container{display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem}.logo-container img{display:block;max-width:100%;object-fit:contain}.title-container{margin-bottom:.75rem}.title-container h1{margin:0;line-height:1.25}.description{margin:0;line-height:1.5;text-align:center}.otp-icon-container{display:flex;justify-content:center;width:100%;margin:1.25rem 0}.otp-icon{display:flex;align-items:center;justify-content:center;width:4.75rem;height:4.75rem;border:2px solid;border-radius:50%;transition:background-color .25s ease,border-color .25s ease,box-shadow .25s ease,transform .25s ease}.otp-icon i{font-size:2.1rem;transition:color .25s ease,transform .25s ease}.otp-icon-invalid{border-color:#fecacad9;background:#dc2626e6;box-shadow:0 10px 24px #7f1d1d59,inset 0 1px #ffffff47}.otp-icon-invalid i{color:#fff}.otp-icon-valid{border-color:#bbf7d0e6;background:#16a34af0;box-shadow:0 10px 24px #14532d59,inset 0 1px #ffffff4d;transform:scale(1.04)}.otp-icon-valid i{color:#fff;transform:scale(1.08)}.form-container{width:100%}.field{display:flex;flex-direction:column;width:100%;margin-bottom:1.25rem}.error-message{width:100%;box-sizing:border-box;margin-bottom:.75rem;padding:.75rem .875rem;color:var(--p-message-error-color, #b91c1c);background:var(--p-message-error-background, #fef2f2);border:1px solid var(--p-message-error-border-color, #fecaca);border-radius:var(--p-content-border-radius, .5rem);font-size:.875rem;line-height:1.4;text-align:center}.submit-btn,.back-btn{display:flex;justify-content:center;width:100%}.back-btn{margin-top:.5rem}:host ::ng-deep .submit-btn pt-button,:host ::ng-deep .back-btn pt-button,:host ::ng-deep .submit-btn p-button,:host ::ng-deep .back-btn p-button,:host ::ng-deep .submit-btn p-button button,:host ::ng-deep .back-btn p-button button{width:100%}.otp-footer{margin-top:1.25rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.8rem;line-height:1.4;text-align:center}.otp-footer span{display:block;margin-top:.25rem}:host-context(.p-dark) .error-message,:host-context(.app-dark) .error-message,:host-context(.dark) .error-message,:host-context([data-theme=\"dark\"]) .error-message{color:var(--p-message-error-color, #fca5a5);background:var(--p-message-error-background, rgba(127, 29, 29, .25));border-color:var(--p-message-error-border-color, rgba(248, 113, 113, .4))}@media(max-width:480px){.logo-container{margin-bottom:1rem}.otp-icon-container{margin:1rem 0}.otp-icon{width:4rem;height:4rem}.otp-icon i{font-size:1.75rem}.field{margin-bottom:1rem}}\n"] }]
7063
+ }], ctorParameters: () => [{ type: i2.FormBuilder }], propDecorators: { otpPageConfig: [{
7064
+ type: Input,
7065
+ args: [{ required: true }]
7066
+ }], otpErrorMessage: [{
7067
+ type: Input
7068
+ }], otpValidated: [{
7069
+ type: Input
7070
+ }], otpSubmit: [{
7071
+ type: Output
7072
+ }], backClick: [{
7073
+ type: Output
7074
+ }] } });
7075
+
7076
+ class PTOtpPageComponent {
7077
+ constructor() {
7078
+ this.otpErrorMessage = null;
7079
+ this.otpValidated = null;
7080
+ this.otpSubmit = new EventEmitter();
7081
+ this.backClick = new EventEmitter();
7082
+ this.defaultCardConfig = {
7083
+ borderRadius: '0',
7084
+ margin: '0',
7085
+ width: '100%',
7086
+ height: '100%',
7087
+ noBorder: true,
7088
+ alignContent: 'center',
7089
+ alignBodyContent: 'center',
7090
+ };
7091
+ }
7092
+ ngOnInit() {
7093
+ this.applyDefaultConfigs();
7094
+ }
7095
+ onOtpSubmit(otpCode) {
7096
+ this.otpSubmit.emit(otpCode);
7097
+ }
7098
+ onBackClick() {
7099
+ this.backClick.emit();
7100
+ }
7101
+ applyDefaultConfigs() {
7102
+ this.otpPageConfig.centerCardConfig = this.applyDefaults(this.otpPageConfig.centerCardConfig);
7103
+ this.otpPageConfig.leftCardConfig = this.applyDefaults(this.otpPageConfig.leftCardConfig);
7104
+ this.otpPageConfig.rightCardConfig = this.applyDefaults(this.otpPageConfig.rightCardConfig);
7105
+ }
7106
+ applyDefaults(config) {
7107
+ return {
7108
+ ...this.defaultCardConfig,
7109
+ ...(config ?? {}),
7110
+ };
7111
+ }
7112
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7113
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTOtpPageComponent, isStandalone: false, selector: "pt-otp-page", inputs: { otpPageConfig: "otpPageConfig", otpErrorMessage: "otpErrorMessage", otpValidated: "otpValidated" }, outputs: { otpSubmit: "otpSubmit", backClick: "backClick" }, ngImport: i0, template: "<ng-container>\n @if (otpPageConfig.position === \"center\") {\n <div class=\"center-container\">\n @if (otpPageConfig.centerCardConfig) {\n <pt-card [config]=\"otpPageConfig.centerCardConfig\">\n <pt-otp-card\n [otpPageConfig]=\"otpPageConfig\"\n [otpErrorMessage]=\"otpErrorMessage\"\n [otpValidated]=\"otpValidated\"\n (otpSubmit)=\"onOtpSubmit($event)\"\n (backClick)=\"onBackClick()\"\n ></pt-otp-card>\n </pt-card>\n }\n </div>\n }\n\n @if (\n otpPageConfig.position === \"left\" || otpPageConfig.position === \"right\"\n ) {\n <div class=\"left-right-container\">\n @if (otpPageConfig.leftCardConfig) {\n <pt-card [config]=\"otpPageConfig.leftCardConfig\">\n @if (otpPageConfig.position === \"left\") {\n <pt-otp-card\n [otpPageConfig]=\"otpPageConfig\"\n [otpErrorMessage]=\"otpErrorMessage\"\n [otpValidated]=\"otpValidated\"\n (otpSubmit)=\"onOtpSubmit($event)\"\n (backClick)=\"onBackClick()\"\n ></pt-otp-card>\n }\n </pt-card>\n }\n\n @if (otpPageConfig.rightCardConfig) {\n <pt-card [config]=\"otpPageConfig.rightCardConfig\">\n @if (otpPageConfig.position === \"right\") {\n <pt-otp-card\n [otpPageConfig]=\"otpPageConfig\"\n [otpErrorMessage]=\"otpErrorMessage\"\n [otpValidated]=\"otpValidated\"\n (otpSubmit)=\"onOtpSubmit($event)\"\n (backClick)=\"onBackClick()\"\n ></pt-otp-card>\n }\n </pt-card>\n }\n </div>\n }\n</ng-container>\n", styles: [".left-right-container{display:flex;width:100%;height:100vh}.left-right-container pt-card{display:flex;flex:1;flex-direction:column;align-items:center;justify-content:center;max-width:50%;height:100%}.center-container{display:flex;align-items:center;justify-content:center;width:100vw;height:100vh;margin:0;padding:0;overflow:hidden;box-sizing:border-box}.center-container pt-card{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;box-sizing:border-box}.center-container pt-card pt-otp-card{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;margin:0;padding:1rem;box-sizing:border-box}\n"], dependencies: [{ kind: "component", type: PTCardComponent, selector: "pt-card", inputs: ["config"] }, { kind: "component", type: PTOtpCardComponent, selector: "pt-otp-card", inputs: ["otpPageConfig", "otpErrorMessage", "otpValidated"], outputs: ["otpSubmit", "backClick"] }] }); }
7114
+ }
7115
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpPageComponent, decorators: [{
7116
+ type: Component,
7117
+ args: [{ selector: 'pt-otp-page', standalone: false, template: "<ng-container>\n @if (otpPageConfig.position === \"center\") {\n <div class=\"center-container\">\n @if (otpPageConfig.centerCardConfig) {\n <pt-card [config]=\"otpPageConfig.centerCardConfig\">\n <pt-otp-card\n [otpPageConfig]=\"otpPageConfig\"\n [otpErrorMessage]=\"otpErrorMessage\"\n [otpValidated]=\"otpValidated\"\n (otpSubmit)=\"onOtpSubmit($event)\"\n (backClick)=\"onBackClick()\"\n ></pt-otp-card>\n </pt-card>\n }\n </div>\n }\n\n @if (\n otpPageConfig.position === \"left\" || otpPageConfig.position === \"right\"\n ) {\n <div class=\"left-right-container\">\n @if (otpPageConfig.leftCardConfig) {\n <pt-card [config]=\"otpPageConfig.leftCardConfig\">\n @if (otpPageConfig.position === \"left\") {\n <pt-otp-card\n [otpPageConfig]=\"otpPageConfig\"\n [otpErrorMessage]=\"otpErrorMessage\"\n [otpValidated]=\"otpValidated\"\n (otpSubmit)=\"onOtpSubmit($event)\"\n (backClick)=\"onBackClick()\"\n ></pt-otp-card>\n }\n </pt-card>\n }\n\n @if (otpPageConfig.rightCardConfig) {\n <pt-card [config]=\"otpPageConfig.rightCardConfig\">\n @if (otpPageConfig.position === \"right\") {\n <pt-otp-card\n [otpPageConfig]=\"otpPageConfig\"\n [otpErrorMessage]=\"otpErrorMessage\"\n [otpValidated]=\"otpValidated\"\n (otpSubmit)=\"onOtpSubmit($event)\"\n (backClick)=\"onBackClick()\"\n ></pt-otp-card>\n }\n </pt-card>\n }\n </div>\n }\n</ng-container>\n", styles: [".left-right-container{display:flex;width:100%;height:100vh}.left-right-container pt-card{display:flex;flex:1;flex-direction:column;align-items:center;justify-content:center;max-width:50%;height:100%}.center-container{display:flex;align-items:center;justify-content:center;width:100vw;height:100vh;margin:0;padding:0;overflow:hidden;box-sizing:border-box}.center-container pt-card{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;box-sizing:border-box}.center-container pt-card pt-otp-card{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;margin:0;padding:1rem;box-sizing:border-box}\n"] }]
7118
+ }], propDecorators: { otpPageConfig: [{
7119
+ type: Input,
7120
+ args: [{ required: true }]
7121
+ }], otpErrorMessage: [{
7122
+ type: Input
7123
+ }], otpValidated: [{
7124
+ type: Input
7125
+ }], otpSubmit: [{
7126
+ type: Output
7127
+ }], backClick: [{
7128
+ type: Output
7129
+ }] } });
7130
+
7131
+ class PTOtpPageModule {
7132
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpPageModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
7133
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.14", ngImport: i0, type: PTOtpPageModule, declarations: [PTOtpPageComponent], imports: [PTCardModule, PTOtpCardComponent], exports: [PTOtpPageComponent] }); }
7134
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpPageModule, imports: [PTCardModule, PTOtpCardComponent] }); }
7135
+ }
7136
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpPageModule, decorators: [{
7137
+ type: NgModule,
7138
+ args: [{
7139
+ declarations: [PTOtpPageComponent],
7140
+ imports: [PTCardModule, PTOtpCardComponent],
7141
+ exports: [PTOtpPageComponent],
7142
+ }]
7143
+ }] });
7144
+
6735
7145
  class NgPrimeToolsModule {
6736
7146
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgPrimeToolsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
6737
7147
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.14", ngImport: i0, type: NgPrimeToolsModule, imports: [CommonModule,
@@ -6747,6 +7157,7 @@ class NgPrimeToolsModule {
6747
7157
  PTTextAreaInputModule,
6748
7158
  PTTextInputModule,
6749
7159
  PTMultiSelectModule,
7160
+ PTOtpInputModule,
6750
7161
  // Dashboard
6751
7162
  PTMetricCardModule,
6752
7163
  PTMetricCardGroupModule,
@@ -6769,6 +7180,7 @@ class NgPrimeToolsModule {
6769
7180
  PTBreadCrumbModule,
6770
7181
  // Login
6771
7182
  PTLoginPageModule,
7183
+ PTOtpPageModule,
6772
7184
  // Button
6773
7185
  PTButtonModule,
6774
7186
  // Dialog
@@ -6785,6 +7197,7 @@ class NgPrimeToolsModule {
6785
7197
  PTTextAreaInputModule,
6786
7198
  PTTextInputModule,
6787
7199
  PTMultiSelectModule,
7200
+ PTOtpInputModule,
6788
7201
  // Dashboard
6789
7202
  PTMetricCardModule,
6790
7203
  PTMetricCardGroupModule,
@@ -6807,6 +7220,7 @@ class NgPrimeToolsModule {
6807
7220
  PTBreadCrumbModule,
6808
7221
  // Login
6809
7222
  PTLoginPageModule,
7223
+ PTOtpPageModule,
6810
7224
  // Button
6811
7225
  PTButtonModule,
6812
7226
  // Dialog
@@ -6827,6 +7241,7 @@ class NgPrimeToolsModule {
6827
7241
  PTTextAreaInputModule,
6828
7242
  PTTextInputModule,
6829
7243
  PTMultiSelectModule,
7244
+ PTOtpInputModule,
6830
7245
  // Dashboard
6831
7246
  PTMetricCardModule,
6832
7247
  PTMetricCardGroupModule,
@@ -6849,6 +7264,7 @@ class NgPrimeToolsModule {
6849
7264
  PTBreadCrumbModule,
6850
7265
  // Login
6851
7266
  PTLoginPageModule,
7267
+ PTOtpPageModule,
6852
7268
  // Button
6853
7269
  PTButtonModule,
6854
7270
  // Dialog
@@ -6865,6 +7281,7 @@ class NgPrimeToolsModule {
6865
7281
  PTTextAreaInputModule,
6866
7282
  PTTextInputModule,
6867
7283
  PTMultiSelectModule,
7284
+ PTOtpInputModule,
6868
7285
  // Dashboard
6869
7286
  PTMetricCardModule,
6870
7287
  PTMetricCardGroupModule,
@@ -6887,6 +7304,7 @@ class NgPrimeToolsModule {
6887
7304
  PTBreadCrumbModule,
6888
7305
  // Login
6889
7306
  PTLoginPageModule,
7307
+ PTOtpPageModule,
6890
7308
  // Button
6891
7309
  PTButtonModule,
6892
7310
  // Dialog
@@ -6912,6 +7330,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6912
7330
  PTTextAreaInputModule,
6913
7331
  PTTextInputModule,
6914
7332
  PTMultiSelectModule,
7333
+ PTOtpInputModule,
6915
7334
  // Dashboard
6916
7335
  PTMetricCardModule,
6917
7336
  PTMetricCardGroupModule,
@@ -6934,6 +7353,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6934
7353
  PTBreadCrumbModule,
6935
7354
  // Login
6936
7355
  PTLoginPageModule,
7356
+ PTOtpPageModule,
6937
7357
  // Button
6938
7358
  PTButtonModule,
6939
7359
  // Dialog
@@ -6953,6 +7373,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6953
7373
  PTTextAreaInputModule,
6954
7374
  PTTextInputModule,
6955
7375
  PTMultiSelectModule,
7376
+ PTOtpInputModule,
6956
7377
  // Dashboard
6957
7378
  PTMetricCardModule,
6958
7379
  PTMetricCardGroupModule,
@@ -6975,6 +7396,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6975
7396
  PTBreadCrumbModule,
6976
7397
  // Login
6977
7398
  PTLoginPageModule,
7399
+ PTOtpPageModule,
6978
7400
  // Button
6979
7401
  PTButtonModule,
6980
7402
  // Dialog
@@ -7355,6 +7777,85 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
7355
7777
  }]
7356
7778
  }] });
7357
7779
 
7780
+ const applyChangePasswordCardDefaults = (config) => {
7781
+ config.title = {
7782
+ text: 'Changer le mot de passe',
7783
+ position: 'center',
7784
+ color: '#333',
7785
+ fontSize: '24px',
7786
+ ...config.title,
7787
+ };
7788
+ config.logoUrl = {
7789
+ altText: 'Logo',
7790
+ imageUrl: '',
7791
+ width: '100px',
7792
+ height: 'auto',
7793
+ ...config.logoUrl,
7794
+ };
7795
+ config.footer = {
7796
+ version: 'V1.0',
7797
+ copyright: 'Your Company © 2026',
7798
+ ...config.footer,
7799
+ };
7800
+ config.changePassword = {
7801
+ currentPassword: config.changePassword?.currentPassword ?? '',
7802
+ newPassword: config.changePassword?.newPassword ?? '',
7803
+ confirmationPassword: config.changePassword?.confirmationPassword ?? '',
7804
+ };
7805
+ config.changePasswordCardConfig = {
7806
+ noBorder: true,
7807
+ width: '480px',
7808
+ padding: '40px',
7809
+ ...config.changePasswordCardConfig,
7810
+ };
7811
+ config.showCurrentPasswordField = config.showCurrentPasswordField ?? false;
7812
+ config.showPasswordStrength = config.showPasswordStrength ?? true;
7813
+ config.newPasswordField = {
7814
+ name: 'newPassword',
7815
+ label: 'Nouveau mot de passe',
7816
+ required: true,
7817
+ placeholder: 'Saisir le nouveau mot de passe',
7818
+ type: FormInputTypeEnum.PASSWORD,
7819
+ toggleMask: true,
7820
+ feedback: false,
7821
+ ...config.newPasswordField,
7822
+ };
7823
+ config.confirmationPasswordField = {
7824
+ name: 'confirmationPassword',
7825
+ label: 'Confirmer le mot de passe',
7826
+ required: true,
7827
+ placeholder: 'Confirmer le nouveau mot de passe',
7828
+ type: FormInputTypeEnum.PASSWORD,
7829
+ toggleMask: true,
7830
+ feedback: false,
7831
+ ...config.confirmationPasswordField,
7832
+ };
7833
+ if (config.showCurrentPasswordField) {
7834
+ config.currentPasswordField = {
7835
+ name: 'currentPassword',
7836
+ label: 'Mot de passe actuel',
7837
+ required: true,
7838
+ placeholder: 'Saisir le mot de passe actuel',
7839
+ type: FormInputTypeEnum.PASSWORD,
7840
+ toggleMask: true,
7841
+ feedback: false,
7842
+ ...config.currentPasswordField,
7843
+ };
7844
+ }
7845
+ config.buttonConfig = {
7846
+ label: 'Changer le mot de passe',
7847
+ type: 'submit',
7848
+ icon: 'pi pi-lock',
7849
+ iconPos: 'left',
7850
+ styleClass: 'p-button-primary',
7851
+ disabled: true,
7852
+ width: '100%',
7853
+ ...config.buttonConfig,
7854
+ };
7855
+ config.passwordPolicyRules = config.passwordPolicyRules ?? [];
7856
+ config.additionalContent = config.additionalContent ?? [];
7857
+ };
7858
+
7358
7859
  class PTChangePasswordCardComponent {
7359
7860
  constructor(formBuilder) {
7360
7861
  this.formBuilder = formBuilder;
@@ -7362,14 +7863,29 @@ class PTChangePasswordCardComponent {
7362
7863
  this.passwordValueChange = new EventEmitter();
7363
7864
  this.changePasswordSubmit = new EventEmitter();
7364
7865
  this.destroy$ = new Subject();
7866
+ this.initialized = false;
7365
7867
  this.formGroup = this.formBuilder.group({}, {
7366
7868
  validators: [this.passwordMatchValidator()],
7367
7869
  });
7368
7870
  }
7369
7871
  ngOnInit() {
7370
- this.initializeDefaults();
7872
+ applyChangePasswordCardDefaults(this.changePasswordPageConfig);
7371
7873
  this.setupFormFields();
7372
7874
  this.listenToPasswordChanges();
7875
+ this.initialized = true;
7876
+ this.updateButtonDisabledState();
7877
+ }
7878
+ ngOnChanges(changes) {
7879
+ const configChange = changes['changePasswordPageConfig'];
7880
+ if (!configChange?.currentValue || !this.initialized) {
7881
+ return;
7882
+ }
7883
+ applyChangePasswordCardDefaults(this.changePasswordPageConfig);
7884
+ /*
7885
+ * The parent recreates the configuration after calculating
7886
+ * passwordPolicyRules. Therefore the button must be recalculated
7887
+ * each time the input configuration changes.
7888
+ */
7373
7889
  this.updateButtonDisabledState();
7374
7890
  }
7375
7891
  ngOnDestroy() {
@@ -7388,6 +7904,10 @@ class PTChangePasswordCardComponent {
7388
7904
  }
7389
7905
  onSubmit() {
7390
7906
  this.formGroup.markAllAsTouched();
7907
+ this.formGroup.updateValueAndValidity({
7908
+ emitEvent: false,
7909
+ });
7910
+ this.updateButtonDisabledState();
7391
7911
  if (!this.formGroup.valid) {
7392
7912
  this.changePasswordPageConfig.errorMessage =
7393
7913
  this.changePasswordPageConfig.emptyFieldsErrorMessage ??
@@ -7408,89 +7928,6 @@ class PTChangePasswordCardComponent {
7408
7928
  item.styleClass ?? '',
7409
7929
  ].filter(Boolean);
7410
7930
  }
7411
- initializeDefaults() {
7412
- this.changePasswordPageConfig.title = {
7413
- text: 'Changer le mot de passe',
7414
- position: 'center',
7415
- color: '#333',
7416
- fontSize: '24px',
7417
- ...this.changePasswordPageConfig.title,
7418
- };
7419
- this.changePasswordPageConfig.logoUrl = {
7420
- altText: 'Logo',
7421
- imageUrl: '',
7422
- width: '100px',
7423
- height: 'auto',
7424
- ...this.changePasswordPageConfig.logoUrl,
7425
- };
7426
- this.changePasswordPageConfig.footer = {
7427
- version: 'V1.0',
7428
- copyright: 'Your Company © 2026',
7429
- ...this.changePasswordPageConfig.footer,
7430
- };
7431
- this.changePasswordPageConfig.changePassword = {
7432
- currentPassword: this.changePasswordPageConfig.changePassword?.currentPassword ?? '',
7433
- newPassword: this.changePasswordPageConfig.changePassword?.newPassword ?? '',
7434
- confirmationPassword: this.changePasswordPageConfig.changePassword?.confirmationPassword ??
7435
- '',
7436
- };
7437
- this.changePasswordPageConfig.changePasswordCardConfig = {
7438
- noBorder: true,
7439
- width: '480px',
7440
- padding: '40px',
7441
- ...this.changePasswordPageConfig.changePasswordCardConfig,
7442
- };
7443
- this.changePasswordPageConfig.showCurrentPasswordField =
7444
- this.changePasswordPageConfig.showCurrentPasswordField ?? false;
7445
- this.changePasswordPageConfig.showPasswordStrength =
7446
- this.changePasswordPageConfig.showPasswordStrength ?? true;
7447
- this.changePasswordPageConfig.newPasswordField = {
7448
- name: 'newPassword',
7449
- label: 'Nouveau mot de passe',
7450
- required: true,
7451
- placeholder: 'Saisir le nouveau mot de passe',
7452
- type: FormInputTypeEnum.PASSWORD,
7453
- toggleMask: true,
7454
- feedback: false,
7455
- ...this.changePasswordPageConfig.newPasswordField,
7456
- };
7457
- this.changePasswordPageConfig.confirmationPasswordField = {
7458
- name: 'confirmationPassword',
7459
- label: 'Confirmer le mot de passe',
7460
- required: true,
7461
- placeholder: 'Confirmer le nouveau mot de passe',
7462
- type: FormInputTypeEnum.PASSWORD,
7463
- toggleMask: true,
7464
- feedback: false,
7465
- ...this.changePasswordPageConfig.confirmationPasswordField,
7466
- };
7467
- if (this.changePasswordPageConfig.showCurrentPasswordField) {
7468
- this.changePasswordPageConfig.currentPasswordField = {
7469
- name: 'currentPassword',
7470
- label: 'Mot de passe actuel',
7471
- required: true,
7472
- placeholder: 'Saisir le mot de passe actuel',
7473
- type: FormInputTypeEnum.PASSWORD,
7474
- toggleMask: true,
7475
- feedback: false,
7476
- ...this.changePasswordPageConfig.currentPasswordField,
7477
- };
7478
- }
7479
- this.changePasswordPageConfig.buttonConfig = {
7480
- label: 'Changer le mot de passe',
7481
- type: 'submit',
7482
- icon: 'pi pi-lock',
7483
- iconPos: 'left',
7484
- styleClass: 'p-button-primary',
7485
- disabled: true,
7486
- width: '100%',
7487
- ...this.changePasswordPageConfig.buttonConfig,
7488
- };
7489
- this.changePasswordPageConfig.passwordPolicyRules =
7490
- this.changePasswordPageConfig.passwordPolicyRules ?? [];
7491
- this.changePasswordPageConfig.additionalContent =
7492
- this.changePasswordPageConfig.additionalContent ?? [];
7493
- }
7494
7931
  setupFormFields() {
7495
7932
  const changePassword = this.changePasswordPageConfig.changePassword;
7496
7933
  if (this.changePasswordPageConfig.showCurrentPasswordField) {
@@ -7504,13 +7941,19 @@ class PTChangePasswordCardComponent {
7504
7941
  }
7505
7942
  listenToPasswordChanges() {
7506
7943
  this.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(() => {
7507
- const changePasswordModel = this.buildChangePasswordModel();
7508
- this.changePasswordPageConfig.changePassword = changePasswordModel;
7509
- this.passwordValueChange.emit(changePasswordModel);
7510
7944
  this.formGroup.updateValueAndValidity({
7511
7945
  emitEvent: false,
7512
7946
  });
7513
- this.updateButtonDisabledState();
7947
+ /*
7948
+ * First synchronize the local form state.
7949
+ */
7950
+ const changePasswordModel = this.buildChangePasswordModel();
7951
+ this.changePasswordPageConfig.changePassword = changePasswordModel;
7952
+ /*
7953
+ * The parent will compute the policy state and replace the config.
7954
+ * ngOnChanges() then recalculates disabled status with fresh rules.
7955
+ */
7956
+ this.passwordValueChange.emit(changePasswordModel);
7514
7957
  });
7515
7958
  this.formGroup.statusChanges
7516
7959
  .pipe(takeUntil(this.destroy$))
@@ -7553,6 +7996,9 @@ class PTChangePasswordCardComponent {
7553
7996
  .every((rule) => rule.valid === true);
7554
7997
  }
7555
7998
  updateButtonDisabledState() {
7999
+ if (!this.changePasswordPageConfig?.buttonConfig) {
8000
+ return;
8001
+ }
7556
8002
  const isFormValid = this.formGroup.valid;
7557
8003
  const arePoliciesValid = this.areFrontendPasswordPolicyRulesValid();
7558
8004
  this.changePasswordPageConfig.buttonConfig = {
@@ -7561,7 +8007,7 @@ class PTChangePasswordCardComponent {
7561
8007
  };
7562
8008
  }
7563
8009
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTChangePasswordCardComponent, deps: [{ token: i2.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
7564
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTChangePasswordCardComponent, isStandalone: true, selector: "pt-change-password-card", inputs: { changePasswordPageConfig: "changePasswordPageConfig", changePasswordErrorMessage: "changePasswordErrorMessage" }, outputs: { passwordValueChange: "passwordValueChange", changePasswordSubmit: "changePasswordSubmit" }, ngImport: i0, template: "<pt-card [config]=\"changePasswordPageConfig.changePasswordCardConfig!\">\n @if (changePasswordPageConfig.logoUrl?.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"changePasswordPageConfig.logoUrl?.imageUrl\"\n [alt]=\"changePasswordPageConfig.logoUrl?.altText || 'Logo'\"\n [style.width]=\"changePasswordPageConfig.logoUrl?.width || '100px'\"\n [style.height]=\"changePasswordPageConfig.logoUrl?.height || 'auto'\"\n />\n </div>\n }\n\n <div class=\"title-container\">\n <h1\n [ngStyle]=\"{\n color: changePasswordPageConfig.title?.color || '#333',\n 'font-size': changePasswordPageConfig.title?.fontSize || '24px',\n }\"\n >\n {{ changePasswordPageConfig.title?.text || \"Changer le mot de passe\" }}\n </h1>\n </div>\n\n @if (changePasswordErrorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ changePasswordErrorMessage }}\n </div>\n }\n\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (changePasswordPageConfig.errorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ changePasswordPageConfig.errorMessage }}\n </div>\n }\n\n @if (changePasswordPageConfig.showCurrentPasswordField) {\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.currentPasswordField!\"\n ></pt-text-input>\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.newPasswordField!\"\n ></pt-text-input>\n </div>\n\n @if (changePasswordPageConfig.showPasswordStrength) {\n <div class=\"password-strength-section\">\n <div class=\"password-strength-header\">\n <span>\n {{\n changePasswordPageConfig.passwordStrengthLabel ||\n \"Robustesse du mot de passe\"\n }}\n </span>\n\n <span\n class=\"strength-label\"\n [ngClass]=\"\n 'strength-' +\n (changePasswordPageConfig.passwordStrengthSeverity || 'neutral')\n \"\n >\n {{\n changePasswordPageConfig.passwordStrengthText || \"Non renseign\u00E9\"\n }}\n </span>\n </div>\n\n <p-progressbar\n [value]=\"changePasswordPageConfig.passwordStrengthPercentage || 0\"\n [showValue]=\"false\"\n [ngClass]=\"\n 'password-progressbar strength-' +\n (changePasswordPageConfig.passwordStrengthSeverity || 'neutral')\n \"\n ></p-progressbar>\n </div>\n }\n\n @if (visiblePasswordPolicyRules.length > 0) {\n <div class=\"password-policy-section\">\n <strong class=\"password-policy-title\">\n {{\n changePasswordPageConfig.passwordPolicyTitle || \"R\u00E8gles de s\u00E9curit\u00E9\"\n }}\n </strong>\n\n <ul class=\"password-policy-list\">\n @for (rule of visiblePasswordPolicyRules; track rule.code) {\n <li\n [class.valid]=\"rule.valid\"\n [class.invalid]=\"!rule.valid && !rule.backendOnly\"\n [class.backend-only]=\"rule.backendOnly\"\n >\n @if (rule.backendOnly) {\n <i class=\"pi pi-shield\"></i>\n } @else if (rule.valid) {\n <i class=\"pi pi-check-circle\"></i>\n } @else {\n <i class=\"pi pi-times-circle\"></i>\n }\n\n <span>{{ rule.label }}</span>\n </li>\n }\n </ul>\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.confirmationPasswordField!\"\n ></pt-text-input>\n\n @if (\n confirmationPasswordControl?.touched &&\n formGroup.hasError(\"passwordMismatch\")\n ) {\n <small class=\"field-error\">\n {{\n changePasswordPageConfig.passwordMismatchErrorMessage ||\n \"Les deux mots de passe ne correspondent pas.\"\n }}\n </small>\n }\n </div>\n\n <div class=\"submit-btn\">\n <pt-button\n [buttonConfig]=\"changePasswordPageConfig.buttonConfig!\"\n ></pt-button>\n </div>\n\n @if (visibleAdditionalContent.length > 0) {\n <div class=\"additional-content-list\">\n @for (item of visibleAdditionalContent; track item.id || $index) {\n <div\n class=\"additional-content-item\"\n [ngClass]=\"getAdditionalContentClass(item)\"\n [ngStyle]=\"item.style\"\n >\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n </div>\n }\n </div>\n }\n </form>\n\n <div class=\"change-password-footer\">\n {{ changePasswordPageConfig.footer?.version }}\n\n <span>\n {{ changePasswordPageConfig.footer?.copyright }}\n </span>\n </div>\n</pt-card>\n", styles: [":host{display:block;width:100%;min-width:0}.logo-container{display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem}.logo-container img{display:block;max-width:100%;object-fit:contain}.title-container{margin-bottom:1.25rem;text-align:center}.title-container h1{margin:0;line-height:1.25}.form-container{width:100%}.field{display:flex;flex-direction:column;width:100%;margin-bottom:1.25rem}.error-message{width:100%;box-sizing:border-box;margin-bottom:.75rem;padding:.75rem .875rem;color:var(--p-message-error-color, #b91c1c);background:var(--p-message-error-background, #fef2f2);border:1px solid var(--p-message-error-border-color, #fecaca);border-radius:var(--p-content-border-radius, .5rem);font-size:.875rem;line-height:1.4;text-align:center}.password-strength-section{width:100%;margin-top:-.25rem;margin-bottom:1.25rem}.password-strength-header{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:.5rem;color:var(--p-text-color, #1e293b);font-size:.875rem;font-weight:600}.strength-label{font-size:.82rem;font-weight:700;white-space:nowrap}.strength-neutral{color:var(--p-text-muted-color, #64748b)}.strength-danger{color:var(--p-red-500, #ef4444)}.strength-warn{color:var(--p-orange-500, #f97316)}.strength-success{color:var(--p-green-500, #22c55e)}:host ::ng-deep .password-progressbar{height:.65rem;overflow:hidden;border-radius:999px}:host ::ng-deep .password-progressbar .p-progressbar-value{transition:width .22s ease,background-color .22s ease}:host ::ng-deep .password-progressbar.strength-neutral .p-progressbar-value{background:var(--p-surface-400, #94a3b8)}:host ::ng-deep .password-progressbar.strength-danger .p-progressbar-value{background:var(--p-red-500, #ef4444)}:host ::ng-deep .password-progressbar.strength-warn .p-progressbar-value{background:var(--p-orange-500, #f97316)}:host ::ng-deep .password-progressbar.strength-success .p-progressbar-value{background:var(--p-green-500, #22c55e)}.password-policy-section{width:100%;box-sizing:border-box;margin-bottom:1.25rem;padding:1rem;background:var(--p-content-background, rgba(255, 255, 255, .12));border:1px solid var(--p-content-border-color, rgba(255, 255, 255, .25));border-radius:var(--p-content-border-radius, .5rem)}.password-policy-title{display:block;margin-bottom:.75rem;color:var(--p-text-color, #1e293b);font-size:.9rem;font-weight:700}.password-policy-list{display:flex;flex-direction:column;margin:0;padding:0;gap:.55rem;list-style:none}.password-policy-list li{display:flex;align-items:flex-start;gap:.6rem;color:var(--p-text-muted-color, #64748b);font-size:.84rem;line-height:1.35}.password-policy-list li i{width:1rem;margin-top:.1rem;text-align:center}.password-policy-list li.valid{color:var(--p-green-600, #16a34a)}.password-policy-list li.invalid{color:var(--p-red-500, #ef4444)}.password-policy-list li.backend-only{color:var(--p-text-muted-color, #64748b)}.password-policy-list li.backend-only i{color:var(--p-primary-color, #3b82f6)}.field-error{display:block;margin-top:.45rem;color:var(--p-message-error-color, #b91c1c);font-size:.78rem;line-height:1.35}.submit-btn{display:flex;justify-content:center;width:100%}:host ::ng-deep .submit-btn pt-button{display:block;width:100%}:host ::ng-deep .submit-btn p-button,:host ::ng-deep .submit-btn p-button button{width:100%}.additional-content-list{display:flex;flex-direction:column;width:100%;margin-top:1rem;gap:.55rem}.additional-content-item{display:flex;flex-wrap:wrap;align-items:baseline;width:100%;box-sizing:border-box;gap:.3rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.875rem;line-height:1.45}.additional-content-left{justify-content:flex-start;text-align:left}.additional-content-center{justify-content:center;text-align:center}.additional-content-right{justify-content:flex-end;text-align:right}.additional-content-text{color:inherit}.change-password-footer{margin-top:1.25rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.8rem;line-height:1.4;text-align:center}.change-password-footer span{display:block;margin-top:.25rem}:host-context(.p-dark) .error-message,:host-context(.app-dark) .error-message,:host-context(.dark) .error-message,:host-context(.dark-mode) .error-message,:host-context([data-theme=\"dark\"]) .error-message{color:var(--p-message-error-color, #fca5a5);background:var(--p-message-error-background, rgba(127, 29, 29, .25));border-color:var(--p-message-error-border-color, rgba(248, 113, 113, .4))}:host-context(.p-dark) .password-strength-header,:host-context(.app-dark) .password-strength-header,:host-context(.dark) .password-strength-header,:host-context(.dark-mode) .password-strength-header,:host-context([data-theme=\"dark\"]) .password-strength-header,:host-context(.p-dark) .password-policy-title,:host-context(.app-dark) .password-policy-title,:host-context(.dark) .password-policy-title,:host-context(.dark-mode) .password-policy-title,:host-context([data-theme=\"dark\"]) .password-policy-title{color:var(--p-text-color, #f8fafc)}:host-context(.p-dark) .password-policy-section,:host-context(.app-dark) .password-policy-section,:host-context(.dark) .password-policy-section,:host-context(.dark-mode) .password-policy-section,:host-context([data-theme=\"dark\"]) .password-policy-section{background:#0f172a59;border-color:#94a3b84d}:host-context(.p-dark) .additional-content-item,:host-context(.app-dark) .additional-content-item,:host-context(.dark) .additional-content-item,:host-context(.dark-mode) .additional-content-item,:host-context([data-theme=\"dark\"]) .additional-content-item,:host-context(.p-dark) .change-password-footer,:host-context(.app-dark) .change-password-footer,:host-context(.dark) .change-password-footer,:host-context(.dark-mode) .change-password-footer,:host-context([data-theme=\"dark\"]) .change-password-footer{color:var(--p-text-muted-color, var(--text-color-secondary, #cbd5e1))}@media(max-width:768px){:host ::ng-deep pt-card{width:100%;max-width:100%}.submit-btn{min-width:100%}.password-strength-header{align-items:flex-start;flex-direction:column;gap:.25rem}}@media(max-width:480px){.logo-container,.title-container,.field{margin-bottom:1rem}.additional-content-item{font-size:.82rem}.additional-content-list{gap:.5rem}.password-policy-section{padding:.85rem}.password-policy-list li{font-size:.8rem}}\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: ReactiveFormsModule }, { 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: "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"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i13.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "unit", "mode", "color"] }] }); }
8010
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTChangePasswordCardComponent, isStandalone: true, selector: "pt-change-password-card", inputs: { changePasswordPageConfig: "changePasswordPageConfig", changePasswordErrorMessage: "changePasswordErrorMessage" }, outputs: { passwordValueChange: "passwordValueChange", changePasswordSubmit: "changePasswordSubmit" }, usesOnChanges: true, ngImport: i0, template: "<pt-card [config]=\"changePasswordPageConfig.changePasswordCardConfig!\">\n @if (changePasswordPageConfig.logoUrl; as logoUrl) {\n @if (logoUrl.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"logoUrl.imageUrl\"\n [alt]=\"logoUrl.altText || 'Logo'\"\n [style.width]=\"logoUrl.width || '100px'\"\n [style.height]=\"logoUrl.height || 'auto'\"\n />\n </div>\n }\n }\n\n <div class=\"title-container\">\n <h1\n [ngStyle]=\"{\n color: changePasswordPageConfig.title?.color || '#333',\n 'font-size': changePasswordPageConfig.title?.fontSize || '24px',\n }\"\n >\n {{ changePasswordPageConfig.title?.text || \"Changer le mot de passe\" }}\n </h1>\n </div>\n\n @if (changePasswordErrorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ changePasswordErrorMessage }}\n </div>\n }\n\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (changePasswordPageConfig.errorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ changePasswordPageConfig.errorMessage }}\n </div>\n }\n\n @if (changePasswordPageConfig.showCurrentPasswordField) {\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.currentPasswordField!\"\n ></pt-text-input>\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.newPasswordField!\"\n ></pt-text-input>\n </div>\n\n @if (changePasswordPageConfig.showPasswordStrength) {\n <div class=\"password-strength-section\">\n <div class=\"password-strength-header\">\n <span>\n {{\n changePasswordPageConfig.passwordStrengthLabel ||\n \"Robustesse du mot de passe\"\n }}\n </span>\n\n <span\n class=\"strength-label\"\n [ngClass]=\"\n 'strength-' +\n (changePasswordPageConfig.passwordStrengthSeverity || 'neutral')\n \"\n >\n {{\n changePasswordPageConfig.passwordStrengthText || \"Non renseign\u00E9\"\n }}\n </span>\n </div>\n\n <p-progressbar\n [value]=\"changePasswordPageConfig.passwordStrengthPercentage || 0\"\n [showValue]=\"false\"\n [ngClass]=\"\n 'password-progressbar strength-' +\n (changePasswordPageConfig.passwordStrengthSeverity || 'neutral')\n \"\n ></p-progressbar>\n </div>\n }\n\n @if (visiblePasswordPolicyRules.length > 0) {\n <div class=\"password-policy-section\">\n <strong class=\"password-policy-title\">\n {{\n changePasswordPageConfig.passwordPolicyTitle || \"R\u00E8gles de s\u00E9curit\u00E9\"\n }}\n </strong>\n\n <ul class=\"password-policy-list\">\n @for (rule of visiblePasswordPolicyRules; track rule.code) {\n <li\n [class.valid]=\"rule.valid\"\n [class.invalid]=\"!rule.valid && !rule.backendOnly\"\n [class.backend-only]=\"rule.backendOnly\"\n >\n @if (rule.backendOnly) {\n <i class=\"pi pi-shield\"></i>\n } @else if (rule.valid) {\n <i class=\"pi pi-check-circle\"></i>\n } @else {\n <i class=\"pi pi-times-circle\"></i>\n }\n\n <span>{{ rule.label }}</span>\n </li>\n }\n </ul>\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.confirmationPasswordField!\"\n ></pt-text-input>\n\n @if (\n confirmationPasswordControl?.touched &&\n formGroup.hasError(\"passwordMismatch\")\n ) {\n <small class=\"field-error\">\n {{\n changePasswordPageConfig.passwordMismatchErrorMessage ||\n \"Les deux mots de passe ne correspondent pas.\"\n }}\n </small>\n }\n </div>\n\n <div class=\"submit-btn\">\n <pt-button\n [buttonConfig]=\"changePasswordPageConfig.buttonConfig!\"\n ></pt-button>\n </div>\n\n @if (visibleAdditionalContent.length > 0) {\n <div class=\"additional-content-list\">\n @for (item of visibleAdditionalContent; track item.id || $index) {\n <div\n class=\"additional-content-item\"\n [ngClass]=\"getAdditionalContentClass(item)\"\n [ngStyle]=\"item.style\"\n >\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n </div>\n }\n </div>\n }\n </form>\n\n <div class=\"change-password-footer\">\n {{ changePasswordPageConfig.footer?.version }}\n\n <span>\n {{ changePasswordPageConfig.footer?.copyright }}\n </span>\n </div>\n</pt-card>\n", styles: [":host{display:block;width:100%;min-width:0}.logo-container{display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem}.logo-container img{display:block;max-width:100%;object-fit:contain}.title-container{margin-bottom:1.25rem;text-align:center}.title-container h1{margin:0;line-height:1.25}.form-container{width:100%}.field{display:flex;flex-direction:column;width:100%;margin-bottom:1.25rem}.error-message{width:100%;box-sizing:border-box;margin-bottom:.75rem;padding:.75rem .875rem;color:var(--p-message-error-color, #b91c1c);background:var(--p-message-error-background, #fef2f2);border:1px solid var(--p-message-error-border-color, #fecaca);border-radius:var(--p-content-border-radius, .5rem);font-size:.875rem;line-height:1.4;text-align:center}.password-strength-section{width:100%;margin-top:-.25rem;margin-bottom:1.25rem}.password-strength-header{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:.5rem;color:var(--p-text-color, #1e293b);font-size:.875rem;font-weight:600}.strength-label{font-size:.82rem;font-weight:700;white-space:nowrap}.strength-neutral{color:var(--p-text-muted-color, #64748b)}.strength-danger{color:var(--p-red-500, #ef4444)}.strength-warn{color:var(--p-orange-500, #f97316)}.strength-success{color:var(--p-green-500, #22c55e)}:host ::ng-deep .password-progressbar{height:.65rem;overflow:hidden;border-radius:999px}:host ::ng-deep .password-progressbar .p-progressbar-value{transition:width .22s ease,background-color .22s ease}:host ::ng-deep .password-progressbar.strength-neutral .p-progressbar-value{background:var(--p-surface-400, #94a3b8)}:host ::ng-deep .password-progressbar.strength-danger .p-progressbar-value{background:var(--p-red-500, #ef4444)}:host ::ng-deep .password-progressbar.strength-warn .p-progressbar-value{background:var(--p-orange-500, #f97316)}:host ::ng-deep .password-progressbar.strength-success .p-progressbar-value{background:var(--p-green-500, #22c55e)}.password-policy-section{width:100%;box-sizing:border-box;margin-bottom:1.25rem;padding:1rem;background:var(--p-content-background, rgba(255, 255, 255, .12));border:1px solid var(--p-content-border-color, rgba(255, 255, 255, .25));border-radius:var(--p-content-border-radius, .5rem)}.password-policy-title{display:block;margin-bottom:.75rem;color:var(--p-text-color, #1e293b);font-size:.9rem;font-weight:700}.password-policy-list{display:flex;flex-direction:column;margin:0;padding:0;gap:.55rem;list-style:none}.password-policy-list li{display:flex;align-items:flex-start;gap:.6rem;color:var(--p-text-muted-color, #64748b);font-size:.84rem;line-height:1.35}.password-policy-list li i{width:1rem;margin-top:.1rem;text-align:center}.password-policy-list li.valid{color:var(--p-green-600, #16a34a)}.password-policy-list li.invalid{color:var(--p-red-500, #ef4444)}.password-policy-list li.backend-only{color:var(--p-text-muted-color, #64748b)}.password-policy-list li.backend-only i{color:var(--p-primary-color, #3b82f6)}.field-error{display:block;margin-top:.45rem;color:var(--p-message-error-color, #b91c1c);font-size:.78rem;line-height:1.35}.submit-btn{display:flex;justify-content:center;width:100%}:host ::ng-deep .submit-btn pt-button{display:block;width:100%}:host ::ng-deep .submit-btn p-button,:host ::ng-deep .submit-btn p-button button{width:100%}.additional-content-list{display:flex;flex-direction:column;width:100%;margin-top:1rem;gap:.55rem}.additional-content-item{display:flex;flex-wrap:wrap;align-items:baseline;width:100%;box-sizing:border-box;gap:.3rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.875rem;line-height:1.45}.additional-content-left{justify-content:flex-start;text-align:left}.additional-content-center{justify-content:center;text-align:center}.additional-content-right{justify-content:flex-end;text-align:right}.additional-content-text{color:inherit}.change-password-footer{margin-top:1.25rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.8rem;line-height:1.4;text-align:center}.change-password-footer span{display:block;margin-top:.25rem}:host-context(.p-dark) .error-message,:host-context(.app-dark) .error-message,:host-context(.dark) .error-message,:host-context(.dark-mode) .error-message,:host-context([data-theme=\"dark\"]) .error-message{color:var(--p-message-error-color, #fca5a5);background:var(--p-message-error-background, rgba(127, 29, 29, .25));border-color:var(--p-message-error-border-color, rgba(248, 113, 113, .4))}:host-context(.p-dark) .password-strength-header,:host-context(.app-dark) .password-strength-header,:host-context(.dark) .password-strength-header,:host-context(.dark-mode) .password-strength-header,:host-context([data-theme=\"dark\"]) .password-strength-header,:host-context(.p-dark) .password-policy-title,:host-context(.app-dark) .password-policy-title,:host-context(.dark) .password-policy-title,:host-context(.dark-mode) .password-policy-title,:host-context([data-theme=\"dark\"]) .password-policy-title{color:var(--p-text-color, #f8fafc)}:host-context(.p-dark) .password-policy-section,:host-context(.app-dark) .password-policy-section,:host-context(.dark) .password-policy-section,:host-context(.dark-mode) .password-policy-section,:host-context([data-theme=\"dark\"]) .password-policy-section{background:#0f172a59;border-color:#94a3b84d}:host-context(.p-dark) .additional-content-item,:host-context(.app-dark) .additional-content-item,:host-context(.dark) .additional-content-item,:host-context(.dark-mode) .additional-content-item,:host-context([data-theme=\"dark\"]) .additional-content-item,:host-context(.p-dark) .change-password-footer,:host-context(.app-dark) .change-password-footer,:host-context(.dark) .change-password-footer,:host-context(.dark-mode) .change-password-footer,:host-context([data-theme=\"dark\"]) .change-password-footer{color:var(--p-text-muted-color, var(--text-color-secondary, #cbd5e1))}@media(max-width:768px){:host ::ng-deep pt-card{width:100%;max-width:100%}.submit-btn{min-width:100%}.password-strength-header{align-items:flex-start;flex-direction:column;gap:.25rem}}@media(max-width:480px){.logo-container,.title-container,.field{margin-bottom:1rem}.additional-content-item{font-size:.82rem}.additional-content-list{gap:.5rem}.password-policy-section{padding:.85rem}.password-policy-list li{font-size:.8rem}}\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: ReactiveFormsModule }, { 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: "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"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i13.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "unit", "mode", "color"] }] }); }
7565
8011
  }
7566
8012
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTChangePasswordCardComponent, decorators: [{
7567
8013
  type: Component,
@@ -7572,7 +8018,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
7572
8018
  PTButtonModule,
7573
8019
  PTTextInputModule,
7574
8020
  ProgressBarModule,
7575
- ], template: "<pt-card [config]=\"changePasswordPageConfig.changePasswordCardConfig!\">\n @if (changePasswordPageConfig.logoUrl?.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"changePasswordPageConfig.logoUrl?.imageUrl\"\n [alt]=\"changePasswordPageConfig.logoUrl?.altText || 'Logo'\"\n [style.width]=\"changePasswordPageConfig.logoUrl?.width || '100px'\"\n [style.height]=\"changePasswordPageConfig.logoUrl?.height || 'auto'\"\n />\n </div>\n }\n\n <div class=\"title-container\">\n <h1\n [ngStyle]=\"{\n color: changePasswordPageConfig.title?.color || '#333',\n 'font-size': changePasswordPageConfig.title?.fontSize || '24px',\n }\"\n >\n {{ changePasswordPageConfig.title?.text || \"Changer le mot de passe\" }}\n </h1>\n </div>\n\n @if (changePasswordErrorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ changePasswordErrorMessage }}\n </div>\n }\n\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (changePasswordPageConfig.errorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ changePasswordPageConfig.errorMessage }}\n </div>\n }\n\n @if (changePasswordPageConfig.showCurrentPasswordField) {\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.currentPasswordField!\"\n ></pt-text-input>\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.newPasswordField!\"\n ></pt-text-input>\n </div>\n\n @if (changePasswordPageConfig.showPasswordStrength) {\n <div class=\"password-strength-section\">\n <div class=\"password-strength-header\">\n <span>\n {{\n changePasswordPageConfig.passwordStrengthLabel ||\n \"Robustesse du mot de passe\"\n }}\n </span>\n\n <span\n class=\"strength-label\"\n [ngClass]=\"\n 'strength-' +\n (changePasswordPageConfig.passwordStrengthSeverity || 'neutral')\n \"\n >\n {{\n changePasswordPageConfig.passwordStrengthText || \"Non renseign\u00E9\"\n }}\n </span>\n </div>\n\n <p-progressbar\n [value]=\"changePasswordPageConfig.passwordStrengthPercentage || 0\"\n [showValue]=\"false\"\n [ngClass]=\"\n 'password-progressbar strength-' +\n (changePasswordPageConfig.passwordStrengthSeverity || 'neutral')\n \"\n ></p-progressbar>\n </div>\n }\n\n @if (visiblePasswordPolicyRules.length > 0) {\n <div class=\"password-policy-section\">\n <strong class=\"password-policy-title\">\n {{\n changePasswordPageConfig.passwordPolicyTitle || \"R\u00E8gles de s\u00E9curit\u00E9\"\n }}\n </strong>\n\n <ul class=\"password-policy-list\">\n @for (rule of visiblePasswordPolicyRules; track rule.code) {\n <li\n [class.valid]=\"rule.valid\"\n [class.invalid]=\"!rule.valid && !rule.backendOnly\"\n [class.backend-only]=\"rule.backendOnly\"\n >\n @if (rule.backendOnly) {\n <i class=\"pi pi-shield\"></i>\n } @else if (rule.valid) {\n <i class=\"pi pi-check-circle\"></i>\n } @else {\n <i class=\"pi pi-times-circle\"></i>\n }\n\n <span>{{ rule.label }}</span>\n </li>\n }\n </ul>\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.confirmationPasswordField!\"\n ></pt-text-input>\n\n @if (\n confirmationPasswordControl?.touched &&\n formGroup.hasError(\"passwordMismatch\")\n ) {\n <small class=\"field-error\">\n {{\n changePasswordPageConfig.passwordMismatchErrorMessage ||\n \"Les deux mots de passe ne correspondent pas.\"\n }}\n </small>\n }\n </div>\n\n <div class=\"submit-btn\">\n <pt-button\n [buttonConfig]=\"changePasswordPageConfig.buttonConfig!\"\n ></pt-button>\n </div>\n\n @if (visibleAdditionalContent.length > 0) {\n <div class=\"additional-content-list\">\n @for (item of visibleAdditionalContent; track item.id || $index) {\n <div\n class=\"additional-content-item\"\n [ngClass]=\"getAdditionalContentClass(item)\"\n [ngStyle]=\"item.style\"\n >\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n </div>\n }\n </div>\n }\n </form>\n\n <div class=\"change-password-footer\">\n {{ changePasswordPageConfig.footer?.version }}\n\n <span>\n {{ changePasswordPageConfig.footer?.copyright }}\n </span>\n </div>\n</pt-card>\n", styles: [":host{display:block;width:100%;min-width:0}.logo-container{display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem}.logo-container img{display:block;max-width:100%;object-fit:contain}.title-container{margin-bottom:1.25rem;text-align:center}.title-container h1{margin:0;line-height:1.25}.form-container{width:100%}.field{display:flex;flex-direction:column;width:100%;margin-bottom:1.25rem}.error-message{width:100%;box-sizing:border-box;margin-bottom:.75rem;padding:.75rem .875rem;color:var(--p-message-error-color, #b91c1c);background:var(--p-message-error-background, #fef2f2);border:1px solid var(--p-message-error-border-color, #fecaca);border-radius:var(--p-content-border-radius, .5rem);font-size:.875rem;line-height:1.4;text-align:center}.password-strength-section{width:100%;margin-top:-.25rem;margin-bottom:1.25rem}.password-strength-header{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:.5rem;color:var(--p-text-color, #1e293b);font-size:.875rem;font-weight:600}.strength-label{font-size:.82rem;font-weight:700;white-space:nowrap}.strength-neutral{color:var(--p-text-muted-color, #64748b)}.strength-danger{color:var(--p-red-500, #ef4444)}.strength-warn{color:var(--p-orange-500, #f97316)}.strength-success{color:var(--p-green-500, #22c55e)}:host ::ng-deep .password-progressbar{height:.65rem;overflow:hidden;border-radius:999px}:host ::ng-deep .password-progressbar .p-progressbar-value{transition:width .22s ease,background-color .22s ease}:host ::ng-deep .password-progressbar.strength-neutral .p-progressbar-value{background:var(--p-surface-400, #94a3b8)}:host ::ng-deep .password-progressbar.strength-danger .p-progressbar-value{background:var(--p-red-500, #ef4444)}:host ::ng-deep .password-progressbar.strength-warn .p-progressbar-value{background:var(--p-orange-500, #f97316)}:host ::ng-deep .password-progressbar.strength-success .p-progressbar-value{background:var(--p-green-500, #22c55e)}.password-policy-section{width:100%;box-sizing:border-box;margin-bottom:1.25rem;padding:1rem;background:var(--p-content-background, rgba(255, 255, 255, .12));border:1px solid var(--p-content-border-color, rgba(255, 255, 255, .25));border-radius:var(--p-content-border-radius, .5rem)}.password-policy-title{display:block;margin-bottom:.75rem;color:var(--p-text-color, #1e293b);font-size:.9rem;font-weight:700}.password-policy-list{display:flex;flex-direction:column;margin:0;padding:0;gap:.55rem;list-style:none}.password-policy-list li{display:flex;align-items:flex-start;gap:.6rem;color:var(--p-text-muted-color, #64748b);font-size:.84rem;line-height:1.35}.password-policy-list li i{width:1rem;margin-top:.1rem;text-align:center}.password-policy-list li.valid{color:var(--p-green-600, #16a34a)}.password-policy-list li.invalid{color:var(--p-red-500, #ef4444)}.password-policy-list li.backend-only{color:var(--p-text-muted-color, #64748b)}.password-policy-list li.backend-only i{color:var(--p-primary-color, #3b82f6)}.field-error{display:block;margin-top:.45rem;color:var(--p-message-error-color, #b91c1c);font-size:.78rem;line-height:1.35}.submit-btn{display:flex;justify-content:center;width:100%}:host ::ng-deep .submit-btn pt-button{display:block;width:100%}:host ::ng-deep .submit-btn p-button,:host ::ng-deep .submit-btn p-button button{width:100%}.additional-content-list{display:flex;flex-direction:column;width:100%;margin-top:1rem;gap:.55rem}.additional-content-item{display:flex;flex-wrap:wrap;align-items:baseline;width:100%;box-sizing:border-box;gap:.3rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.875rem;line-height:1.45}.additional-content-left{justify-content:flex-start;text-align:left}.additional-content-center{justify-content:center;text-align:center}.additional-content-right{justify-content:flex-end;text-align:right}.additional-content-text{color:inherit}.change-password-footer{margin-top:1.25rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.8rem;line-height:1.4;text-align:center}.change-password-footer span{display:block;margin-top:.25rem}:host-context(.p-dark) .error-message,:host-context(.app-dark) .error-message,:host-context(.dark) .error-message,:host-context(.dark-mode) .error-message,:host-context([data-theme=\"dark\"]) .error-message{color:var(--p-message-error-color, #fca5a5);background:var(--p-message-error-background, rgba(127, 29, 29, .25));border-color:var(--p-message-error-border-color, rgba(248, 113, 113, .4))}:host-context(.p-dark) .password-strength-header,:host-context(.app-dark) .password-strength-header,:host-context(.dark) .password-strength-header,:host-context(.dark-mode) .password-strength-header,:host-context([data-theme=\"dark\"]) .password-strength-header,:host-context(.p-dark) .password-policy-title,:host-context(.app-dark) .password-policy-title,:host-context(.dark) .password-policy-title,:host-context(.dark-mode) .password-policy-title,:host-context([data-theme=\"dark\"]) .password-policy-title{color:var(--p-text-color, #f8fafc)}:host-context(.p-dark) .password-policy-section,:host-context(.app-dark) .password-policy-section,:host-context(.dark) .password-policy-section,:host-context(.dark-mode) .password-policy-section,:host-context([data-theme=\"dark\"]) .password-policy-section{background:#0f172a59;border-color:#94a3b84d}:host-context(.p-dark) .additional-content-item,:host-context(.app-dark) .additional-content-item,:host-context(.dark) .additional-content-item,:host-context(.dark-mode) .additional-content-item,:host-context([data-theme=\"dark\"]) .additional-content-item,:host-context(.p-dark) .change-password-footer,:host-context(.app-dark) .change-password-footer,:host-context(.dark) .change-password-footer,:host-context(.dark-mode) .change-password-footer,:host-context([data-theme=\"dark\"]) .change-password-footer{color:var(--p-text-muted-color, var(--text-color-secondary, #cbd5e1))}@media(max-width:768px){:host ::ng-deep pt-card{width:100%;max-width:100%}.submit-btn{min-width:100%}.password-strength-header{align-items:flex-start;flex-direction:column;gap:.25rem}}@media(max-width:480px){.logo-container,.title-container,.field{margin-bottom:1rem}.additional-content-item{font-size:.82rem}.additional-content-list{gap:.5rem}.password-policy-section{padding:.85rem}.password-policy-list li{font-size:.8rem}}\n"] }]
8021
+ ], template: "<pt-card [config]=\"changePasswordPageConfig.changePasswordCardConfig!\">\n @if (changePasswordPageConfig.logoUrl; as logoUrl) {\n @if (logoUrl.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"logoUrl.imageUrl\"\n [alt]=\"logoUrl.altText || 'Logo'\"\n [style.width]=\"logoUrl.width || '100px'\"\n [style.height]=\"logoUrl.height || 'auto'\"\n />\n </div>\n }\n }\n\n <div class=\"title-container\">\n <h1\n [ngStyle]=\"{\n color: changePasswordPageConfig.title?.color || '#333',\n 'font-size': changePasswordPageConfig.title?.fontSize || '24px',\n }\"\n >\n {{ changePasswordPageConfig.title?.text || \"Changer le mot de passe\" }}\n </h1>\n </div>\n\n @if (changePasswordErrorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ changePasswordErrorMessage }}\n </div>\n }\n\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (changePasswordPageConfig.errorMessage) {\n <div class=\"error-message\" role=\"alert\">\n {{ changePasswordPageConfig.errorMessage }}\n </div>\n }\n\n @if (changePasswordPageConfig.showCurrentPasswordField) {\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.currentPasswordField!\"\n ></pt-text-input>\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.newPasswordField!\"\n ></pt-text-input>\n </div>\n\n @if (changePasswordPageConfig.showPasswordStrength) {\n <div class=\"password-strength-section\">\n <div class=\"password-strength-header\">\n <span>\n {{\n changePasswordPageConfig.passwordStrengthLabel ||\n \"Robustesse du mot de passe\"\n }}\n </span>\n\n <span\n class=\"strength-label\"\n [ngClass]=\"\n 'strength-' +\n (changePasswordPageConfig.passwordStrengthSeverity || 'neutral')\n \"\n >\n {{\n changePasswordPageConfig.passwordStrengthText || \"Non renseign\u00E9\"\n }}\n </span>\n </div>\n\n <p-progressbar\n [value]=\"changePasswordPageConfig.passwordStrengthPercentage || 0\"\n [showValue]=\"false\"\n [ngClass]=\"\n 'password-progressbar strength-' +\n (changePasswordPageConfig.passwordStrengthSeverity || 'neutral')\n \"\n ></p-progressbar>\n </div>\n }\n\n @if (visiblePasswordPolicyRules.length > 0) {\n <div class=\"password-policy-section\">\n <strong class=\"password-policy-title\">\n {{\n changePasswordPageConfig.passwordPolicyTitle || \"R\u00E8gles de s\u00E9curit\u00E9\"\n }}\n </strong>\n\n <ul class=\"password-policy-list\">\n @for (rule of visiblePasswordPolicyRules; track rule.code) {\n <li\n [class.valid]=\"rule.valid\"\n [class.invalid]=\"!rule.valid && !rule.backendOnly\"\n [class.backend-only]=\"rule.backendOnly\"\n >\n @if (rule.backendOnly) {\n <i class=\"pi pi-shield\"></i>\n } @else if (rule.valid) {\n <i class=\"pi pi-check-circle\"></i>\n } @else {\n <i class=\"pi pi-times-circle\"></i>\n }\n\n <span>{{ rule.label }}</span>\n </li>\n }\n </ul>\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"changePasswordPageConfig.confirmationPasswordField!\"\n ></pt-text-input>\n\n @if (\n confirmationPasswordControl?.touched &&\n formGroup.hasError(\"passwordMismatch\")\n ) {\n <small class=\"field-error\">\n {{\n changePasswordPageConfig.passwordMismatchErrorMessage ||\n \"Les deux mots de passe ne correspondent pas.\"\n }}\n </small>\n }\n </div>\n\n <div class=\"submit-btn\">\n <pt-button\n [buttonConfig]=\"changePasswordPageConfig.buttonConfig!\"\n ></pt-button>\n </div>\n\n @if (visibleAdditionalContent.length > 0) {\n <div class=\"additional-content-list\">\n @for (item of visibleAdditionalContent; track item.id || $index) {\n <div\n class=\"additional-content-item\"\n [ngClass]=\"getAdditionalContentClass(item)\"\n [ngStyle]=\"item.style\"\n >\n @if (item.text) {\n <span class=\"additional-content-text\">\n {{ item.text }}\n </span>\n }\n </div>\n }\n </div>\n }\n </form>\n\n <div class=\"change-password-footer\">\n {{ changePasswordPageConfig.footer?.version }}\n\n <span>\n {{ changePasswordPageConfig.footer?.copyright }}\n </span>\n </div>\n</pt-card>\n", styles: [":host{display:block;width:100%;min-width:0}.logo-container{display:flex;align-items:center;justify-content:center;margin-bottom:1.25rem}.logo-container img{display:block;max-width:100%;object-fit:contain}.title-container{margin-bottom:1.25rem;text-align:center}.title-container h1{margin:0;line-height:1.25}.form-container{width:100%}.field{display:flex;flex-direction:column;width:100%;margin-bottom:1.25rem}.error-message{width:100%;box-sizing:border-box;margin-bottom:.75rem;padding:.75rem .875rem;color:var(--p-message-error-color, #b91c1c);background:var(--p-message-error-background, #fef2f2);border:1px solid var(--p-message-error-border-color, #fecaca);border-radius:var(--p-content-border-radius, .5rem);font-size:.875rem;line-height:1.4;text-align:center}.password-strength-section{width:100%;margin-top:-.25rem;margin-bottom:1.25rem}.password-strength-header{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:.5rem;color:var(--p-text-color, #1e293b);font-size:.875rem;font-weight:600}.strength-label{font-size:.82rem;font-weight:700;white-space:nowrap}.strength-neutral{color:var(--p-text-muted-color, #64748b)}.strength-danger{color:var(--p-red-500, #ef4444)}.strength-warn{color:var(--p-orange-500, #f97316)}.strength-success{color:var(--p-green-500, #22c55e)}:host ::ng-deep .password-progressbar{height:.65rem;overflow:hidden;border-radius:999px}:host ::ng-deep .password-progressbar .p-progressbar-value{transition:width .22s ease,background-color .22s ease}:host ::ng-deep .password-progressbar.strength-neutral .p-progressbar-value{background:var(--p-surface-400, #94a3b8)}:host ::ng-deep .password-progressbar.strength-danger .p-progressbar-value{background:var(--p-red-500, #ef4444)}:host ::ng-deep .password-progressbar.strength-warn .p-progressbar-value{background:var(--p-orange-500, #f97316)}:host ::ng-deep .password-progressbar.strength-success .p-progressbar-value{background:var(--p-green-500, #22c55e)}.password-policy-section{width:100%;box-sizing:border-box;margin-bottom:1.25rem;padding:1rem;background:var(--p-content-background, rgba(255, 255, 255, .12));border:1px solid var(--p-content-border-color, rgba(255, 255, 255, .25));border-radius:var(--p-content-border-radius, .5rem)}.password-policy-title{display:block;margin-bottom:.75rem;color:var(--p-text-color, #1e293b);font-size:.9rem;font-weight:700}.password-policy-list{display:flex;flex-direction:column;margin:0;padding:0;gap:.55rem;list-style:none}.password-policy-list li{display:flex;align-items:flex-start;gap:.6rem;color:var(--p-text-muted-color, #64748b);font-size:.84rem;line-height:1.35}.password-policy-list li i{width:1rem;margin-top:.1rem;text-align:center}.password-policy-list li.valid{color:var(--p-green-600, #16a34a)}.password-policy-list li.invalid{color:var(--p-red-500, #ef4444)}.password-policy-list li.backend-only{color:var(--p-text-muted-color, #64748b)}.password-policy-list li.backend-only i{color:var(--p-primary-color, #3b82f6)}.field-error{display:block;margin-top:.45rem;color:var(--p-message-error-color, #b91c1c);font-size:.78rem;line-height:1.35}.submit-btn{display:flex;justify-content:center;width:100%}:host ::ng-deep .submit-btn pt-button{display:block;width:100%}:host ::ng-deep .submit-btn p-button,:host ::ng-deep .submit-btn p-button button{width:100%}.additional-content-list{display:flex;flex-direction:column;width:100%;margin-top:1rem;gap:.55rem}.additional-content-item{display:flex;flex-wrap:wrap;align-items:baseline;width:100%;box-sizing:border-box;gap:.3rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.875rem;line-height:1.45}.additional-content-left{justify-content:flex-start;text-align:left}.additional-content-center{justify-content:center;text-align:center}.additional-content-right{justify-content:flex-end;text-align:right}.additional-content-text{color:inherit}.change-password-footer{margin-top:1.25rem;color:var(--p-text-muted-color, var(--text-color-secondary, #64748b));font-size:.8rem;line-height:1.4;text-align:center}.change-password-footer span{display:block;margin-top:.25rem}:host-context(.p-dark) .error-message,:host-context(.app-dark) .error-message,:host-context(.dark) .error-message,:host-context(.dark-mode) .error-message,:host-context([data-theme=\"dark\"]) .error-message{color:var(--p-message-error-color, #fca5a5);background:var(--p-message-error-background, rgba(127, 29, 29, .25));border-color:var(--p-message-error-border-color, rgba(248, 113, 113, .4))}:host-context(.p-dark) .password-strength-header,:host-context(.app-dark) .password-strength-header,:host-context(.dark) .password-strength-header,:host-context(.dark-mode) .password-strength-header,:host-context([data-theme=\"dark\"]) .password-strength-header,:host-context(.p-dark) .password-policy-title,:host-context(.app-dark) .password-policy-title,:host-context(.dark) .password-policy-title,:host-context(.dark-mode) .password-policy-title,:host-context([data-theme=\"dark\"]) .password-policy-title{color:var(--p-text-color, #f8fafc)}:host-context(.p-dark) .password-policy-section,:host-context(.app-dark) .password-policy-section,:host-context(.dark) .password-policy-section,:host-context(.dark-mode) .password-policy-section,:host-context([data-theme=\"dark\"]) .password-policy-section{background:#0f172a59;border-color:#94a3b84d}:host-context(.p-dark) .additional-content-item,:host-context(.app-dark) .additional-content-item,:host-context(.dark) .additional-content-item,:host-context(.dark-mode) .additional-content-item,:host-context([data-theme=\"dark\"]) .additional-content-item,:host-context(.p-dark) .change-password-footer,:host-context(.app-dark) .change-password-footer,:host-context(.dark) .change-password-footer,:host-context(.dark-mode) .change-password-footer,:host-context([data-theme=\"dark\"]) .change-password-footer{color:var(--p-text-muted-color, var(--text-color-secondary, #cbd5e1))}@media(max-width:768px){:host ::ng-deep pt-card{width:100%;max-width:100%}.submit-btn{min-width:100%}.password-strength-header{align-items:flex-start;flex-direction:column;gap:.25rem}}@media(max-width:480px){.logo-container,.title-container,.field{margin-bottom:1rem}.additional-content-item{font-size:.82rem}.additional-content-list{gap:.5rem}.password-policy-section{padding:.85rem}.password-policy-list li{font-size:.8rem}}\n"] }]
7576
8022
  }], ctorParameters: () => [{ type: i2.FormBuilder }], propDecorators: { changePasswordPageConfig: [{
7577
8023
  type: Input
7578
8024
  }], changePasswordErrorMessage: [{
@@ -7734,5 +8180,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
7734
8180
  * Generated bundle index. Do not edit.
7735
8181
  */
7736
8182
 
7737
- export { AlignEnum, BadgeType, BadgeTypeStyles, ButtonColorEnum, DateUtilityService, FormInputTypeEnum, InputValidationEnum, MultiSearchCriteriaComponent, MultiSearchCriteriaModule, NgPrimeToolsModule, PTAdvancedPrimeTableComponent, PTAdvancedPrimeTableModule, PTBreadCrumbComponent, PTBreadCrumbModule, PTButtonComponent, PTButtonModule, PTCardComponent, PTCardModule, PTChangePasswordPageComponent, PTChangePasswordPageModule, 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 };
8183
+ export { AlignEnum, BadgeType, BadgeTypeStyles, ButtonColorEnum, DateUtilityService, FormInputTypeEnum, InputValidationEnum, MultiSearchCriteriaComponent, MultiSearchCriteriaModule, NgPrimeToolsModule, PTAdvancedPrimeTableComponent, PTAdvancedPrimeTableModule, PTBreadCrumbComponent, PTBreadCrumbModule, PTButtonComponent, PTButtonModule, PTCardComponent, PTCardModule, PTChangePasswordPageComponent, PTChangePasswordPageModule, 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, PTOtpInputComponent, PTOtpInputModule, PTOtpPageComponent, PTOtpPageModule, PTPageSkeletonComponent, PTPageSkeletonModule, PTSideBarMenuComponent, PTSideBarMenuModule, PTSwitchInputComponent, PTSwitchInputModule, PTTextAreaInputComponent, PTTextAreaInputModule, PTTextInputComponent, PTTextInputModule, PTToastNotifierComponent, PTToastNotifierModule, SearchCriteriaTypeEnum, SeverityEnum, TableTypeEnum };
7738
8184
  //# sourceMappingURL=ng-prime-tools.mjs.map