ng-prime-tools 1.0.85 → 1.0.87

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.
@@ -5886,6 +5886,7 @@ class PTLoginCardComponent {
5886
5886
  this.fb = fb;
5887
5887
  this.loginErrorMessage = null;
5888
5888
  this.loginSubmit = new EventEmitter();
5889
+ this.destroy$ = new Subject();
5889
5890
  this.formGroup = this.fb.group({});
5890
5891
  }
5891
5892
  ngOnInit() {
@@ -5895,23 +5896,26 @@ class PTLoginCardComponent {
5895
5896
  username: this.loginPageConfig?.login?.username || '',
5896
5897
  password: this.loginPageConfig?.login?.password || '',
5897
5898
  });
5898
- // Enable/Disable the button based on form validity
5899
- this.formGroup.statusChanges.subscribe((status) => {
5900
- this.loginPageConfig.buttonConfig = {
5901
- ...this.loginPageConfig.buttonConfig,
5902
- disabled: status !== 'VALID',
5903
- };
5899
+ this.updateButtonDisabledState(this.formGroup.valid);
5900
+ this.formGroup.statusChanges
5901
+ .pipe(takeUntil(this.destroy$))
5902
+ .subscribe((status) => {
5903
+ this.updateButtonDisabledState(status === 'VALID');
5904
5904
  });
5905
5905
  }
5906
- // Initialize default values for all fields in loginPageConfig if not set
5906
+ ngOnDestroy() {
5907
+ this.destroy$.next();
5908
+ this.destroy$.complete();
5909
+ }
5910
+ get visibleAdditionalContent() {
5911
+ return (this.loginPageConfig.additionalContent?.filter((item) => item.visible !== false) ?? []);
5912
+ }
5907
5913
  initializeDefaults() {
5908
- // Initialize backgroundImage
5909
5914
  this.loginPageConfig.backgroundImage = {
5910
5915
  imageUrl: this.loginPageConfig.backgroundImage?.imageUrl || '',
5911
5916
  transparencyPercentage: this.loginPageConfig.backgroundImage?.transparencyPercentage || '100',
5912
5917
  ...this.loginPageConfig.backgroundImage,
5913
5918
  };
5914
- // Initialize title
5915
5919
  this.loginPageConfig.title = {
5916
5920
  text: this.loginPageConfig.title?.text || 'Login',
5917
5921
  position: this.loginPageConfig.title?.position || 'center',
@@ -5919,7 +5923,6 @@ class PTLoginCardComponent {
5919
5923
  fontSize: this.loginPageConfig.title?.fontSize || '24px',
5920
5924
  ...this.loginPageConfig.title,
5921
5925
  };
5922
- // Initialize logoUrl
5923
5926
  this.loginPageConfig.logoUrl = {
5924
5927
  altText: this.loginPageConfig.logoUrl?.altText || 'Logo',
5925
5928
  imageUrl: this.loginPageConfig.logoUrl?.imageUrl || '',
@@ -5927,13 +5930,11 @@ class PTLoginCardComponent {
5927
5930
  height: this.loginPageConfig.logoUrl?.height || 'auto',
5928
5931
  ...this.loginPageConfig.logoUrl,
5929
5932
  };
5930
- // Initialize footer
5931
5933
  this.loginPageConfig.footer = {
5932
5934
  version: this.loginPageConfig.footer?.version || 'V1.0',
5933
5935
  copyright: this.loginPageConfig.footer?.copyright || 'Your Company © 2024',
5934
5936
  ...this.loginPageConfig.footer,
5935
5937
  };
5936
- // Initialize login
5937
5938
  this.loginPageConfig.login = {
5938
5939
  username: this.loginPageConfig.login?.username || '',
5939
5940
  password: this.loginPageConfig.login?.password || '',
@@ -5942,14 +5943,12 @@ class PTLoginCardComponent {
5942
5943
  "Veuillez saisir votre nom d'utilisateur et votre mot de passe !",
5943
5944
  ...this.loginPageConfig.login,
5944
5945
  };
5945
- // Initialize cardConfig
5946
5946
  this.loginPageConfig.loginCardConfig = {
5947
5947
  noBorder: this.loginPageConfig.loginCardConfig?.noBorder ?? true,
5948
5948
  width: this.loginPageConfig.loginCardConfig?.width ?? '400px',
5949
5949
  padding: this.loginPageConfig.loginCardConfig?.padding ?? '40px',
5950
5950
  ...this.loginPageConfig.loginCardConfig,
5951
5951
  };
5952
- // Initialize usernameField
5953
5952
  this.loginPageConfig.usernameField = {
5954
5953
  name: this.loginPageConfig.usernameField?.name || 'username',
5955
5954
  label: this.loginPageConfig.usernameField?.label || "Nom d'utilisateur",
@@ -5958,7 +5957,6 @@ class PTLoginCardComponent {
5958
5957
  "Entrer votre nom d'utilisateur",
5959
5958
  ...this.loginPageConfig.usernameField,
5960
5959
  };
5961
- // Initialize passwordField
5962
5960
  this.loginPageConfig.passwordField = {
5963
5961
  name: this.loginPageConfig.passwordField?.name || 'password',
5964
5962
  label: this.loginPageConfig.passwordField?.label || 'Mot de passe',
@@ -5966,13 +5964,10 @@ class PTLoginCardComponent {
5966
5964
  placeholder: this.loginPageConfig.passwordField?.placeholder ||
5967
5965
  'Entrer votre mot de passe',
5968
5966
  type: this.loginPageConfig.passwordField?.type || FormInputTypeEnum.PASSWORD,
5969
- // Show / hide password is now handled by pt-text-input via PrimeNG p-password.
5970
5967
  toggleMask: this.loginPageConfig.passwordField?.toggleMask ?? true,
5971
- // Disabled by default for login forms.
5972
5968
  feedback: this.loginPageConfig.passwordField?.feedback ?? false,
5973
5969
  ...this.loginPageConfig.passwordField,
5974
5970
  };
5975
- // Initialize buttonConfig
5976
5971
  this.loginPageConfig.buttonConfig = {
5977
5972
  label: this.loginPageConfig.buttonConfig?.label || 'Login',
5978
5973
  type: this.loginPageConfig.buttonConfig?.type || 'submit',
@@ -5983,40 +5978,77 @@ class PTLoginCardComponent {
5983
5978
  width: this.loginPageConfig.buttonConfig?.width ?? '100%',
5984
5979
  ...this.loginPageConfig.buttonConfig,
5985
5980
  };
5981
+ this.loginPageConfig.additionalContent =
5982
+ this.loginPageConfig.additionalContent?.map((item) => ({
5983
+ type: item.type ?? this.resolveItemType(item),
5984
+ target: item.target ?? '_self',
5985
+ linkPosition: item.linkPosition ?? 'after',
5986
+ align: item.align ?? 'center',
5987
+ visible: item.visible ?? true,
5988
+ ...item,
5989
+ })) ?? [];
5986
5990
  }
5987
5991
  onSubmit() {
5988
5992
  if (this.formGroup.valid) {
5989
- this.loginSubmit.emit(this.formGroup.value);
5990
- }
5991
- else {
5992
- this.loginPageConfig.login.errorMessage =
5993
- this.loginPageConfig.login?.emptyFieldsErrorMessage;
5993
+ this.loginSubmit.emit(this.formGroup.getRawValue());
5994
+ return;
5994
5995
  }
5996
+ this.formGroup.markAllAsTouched();
5997
+ this.loginPageConfig.login.errorMessage =
5998
+ this.loginPageConfig.login?.emptyFieldsErrorMessage;
5995
5999
  }
5996
- // Setup form fields using the usernameField and passwordField from LoginPageConfig
5997
6000
  setupFormFields() {
5998
- const usernameValidators = this.loginPageConfig.usernameField?.required
6001
+ const usernameField = this.loginPageConfig.usernameField;
6002
+ const passwordField = this.loginPageConfig.passwordField;
6003
+ const usernameValidators = usernameField.required
5999
6004
  ? [Validators.required]
6000
6005
  : [];
6001
- const passwordValidators = this.loginPageConfig.passwordField?.required
6006
+ const passwordValidators = passwordField.required
6002
6007
  ? [Validators.required]
6003
6008
  : [];
6004
- this.formGroup.addControl(this.loginPageConfig.usernameField.name, this.fb.control(this.loginPageConfig.login?.username, usernameValidators));
6005
- this.formGroup.addControl(this.loginPageConfig.passwordField.name, this.fb.control(this.loginPageConfig.login?.password, passwordValidators));
6009
+ this.formGroup.addControl(usernameField.name, this.fb.control(this.loginPageConfig.login?.username ?? '', usernameValidators));
6010
+ this.formGroup.addControl(passwordField.name, this.fb.control(this.loginPageConfig.login?.password ?? '', passwordValidators));
6011
+ }
6012
+ getAdditionalContentClass(item) {
6013
+ return [
6014
+ `additional-content-${item.align ?? 'center'}`,
6015
+ item.styleClass ?? '',
6016
+ ].filter(Boolean);
6017
+ }
6018
+ getLinkRel(item) {
6019
+ if (item.rel) {
6020
+ return item.rel;
6021
+ }
6022
+ return item.target === '_blank' ? 'noopener noreferrer' : null;
6023
+ }
6024
+ resolveItemType(item) {
6025
+ if (item.text && item.linkText && item.url) {
6026
+ return 'text-with-link';
6027
+ }
6028
+ if (item.linkText && item.url) {
6029
+ return 'link';
6030
+ }
6031
+ return 'text';
6032
+ }
6033
+ updateButtonDisabledState(formValid) {
6034
+ this.loginPageConfig.buttonConfig = {
6035
+ ...this.loginPageConfig.buttonConfig,
6036
+ disabled: !formValid,
6037
+ };
6006
6038
  }
6007
6039
  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 }); }
6008
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTLoginCardComponent, isStandalone: true, selector: "pt-login-card", inputs: { loginPageConfig: "loginPageConfig", loginErrorMessage: "loginErrorMessage" }, outputs: { loginSubmit: "loginSubmit" }, ngImport: i0, template: "<pt-card [config]=\"loginPageConfig.loginCardConfig!\">\n <!-- Logo -->\n @if (loginPageConfig.logoUrl?.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"loginPageConfig.logoUrl?.imageUrl\"\n [alt]=\"loginPageConfig.logoUrl?.altText || 'Logo'\"\n [style.width]=\"loginPageConfig.logoUrl?.width || '100px'\"\n [style.height]=\"loginPageConfig.logoUrl?.height || 'auto'\"\n />\n </div>\n }\n\n <!-- Title -->\n <div class=\"title-container\">\n <h1\n [ngStyle]=\"{\n color: loginPageConfig.title?.color || '#333',\n 'font-size': loginPageConfig.title?.fontSize || '24px',\n }\"\n >\n {{ loginPageConfig.title?.text || \"Default Title\" }}\n </h1>\n </div>\n\n <!-- External Error Message -->\n @if (loginErrorMessage) {\n <div class=\"error-message\">\n {{ loginErrorMessage }}\n </div>\n }\n\n <!-- Form -->\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (loginPageConfig.login?.errorMessage) {\n <div class=\"error-message\">\n {{ loginPageConfig.login?.errorMessage }}\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.usernameField!\"\n ></pt-text-input>\n </div>\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.passwordField!\"\n ></pt-text-input>\n </div>\n\n @if (\n loginPageConfig.forgotPasswordConfig?.text &&\n loginPageConfig.forgotPasswordConfig?.url\n ) {\n <div\n class=\"forgot-password-container\"\n [ngClass]=\"\n 'forgot-password-' +\n (loginPageConfig.forgotPasswordConfig?.align || 'center')\n \"\n >\n <a\n [href]=\"loginPageConfig.forgotPasswordConfig?.url\"\n [target]=\"loginPageConfig.forgotPasswordConfig?.target || '_self'\"\n [ngStyle]=\"loginPageConfig.forgotPasswordConfig?.style\"\n [class]=\"\n loginPageConfig.forgotPasswordConfig?.styleClass ||\n 'forgot-password-link'\n \"\n >\n {{ loginPageConfig.forgotPasswordConfig?.text }}\n </a>\n </div>\n }\n\n <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"loginPageConfig.buttonConfig!\"></pt-button>\n </div>\n </form>\n\n <div class=\"login-footer\">\n {{ loginPageConfig.footer?.version }}\n <span>{{ loginPageConfig.footer?.copyright }}</span>\n </div>\n</pt-card>\n", styles: [".logo-container{display:flex;justify-content:center;align-items:center;margin-bottom:20px}.title-container{text-align:center;margin-bottom:20px}.form-container{width:100%}.field{display:flex;flex-direction:column;margin-bottom:20px;width:100%}.error-message{color:red;background-color:#ffe6e6;border:1px solid red;padding:10px;margin-bottom:10px;border-radius:5px;width:100%;text-align:center}.forgot-password-container{width:100%;display:flex;justify-content:center;margin-top:-10px;margin-bottom:20px}.forgot-password-left{justify-content:flex-start}.forgot-password-center{justify-content:center}.forgot-password-right{justify-content:flex-end}.forgot-password-link{color:#2563eb;font-size:.9rem;font-weight:500;text-decoration:none;cursor:pointer;transition:color .2s ease}.forgot-password-link:hover{color:#1d4ed8;text-decoration:underline}.submit-btn{display:flex;justify-content:center;width:100%}::ng-deep pt-button{width:100%}::ng-deep .submit-btn p-button button{width:100%}.login-footer{margin-top:20px;text-align:center;font-size:.9em;color:#555}.login-footer span{display:block;margin-top:.25rem}@media(max-width:768px){pt-card{max-width:300px}.submit-btn{min-width:100%}.forgot-password-container{justify-content:center}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PTCardModule }, { kind: "component", type: PTCardComponent, selector: "pt-card", inputs: ["config"] }, { kind: "ngmodule", type: PTButtonModule }, { kind: "component", type: PTButtonComponent, selector: "pt-button", inputs: ["buttonConfig"] }, { kind: "ngmodule", type: PTTextInputModule }, { kind: "component", type: PTTextInputComponent, selector: "pt-text-input", inputs: ["formGroup", "formField"] }] }); }
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"] }] }); }
6009
6041
  }
6010
6042
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTLoginCardComponent, decorators: [{
6011
6043
  type: Component,
6012
- args: [{ selector: 'pt-login-card', imports: [
6044
+ args: [{ selector: 'pt-login-card', standalone: true, imports: [
6013
6045
  CommonModule,
6014
6046
  FormsModule,
6015
6047
  ReactiveFormsModule,
6016
6048
  PTCardModule,
6017
6049
  PTButtonModule,
6018
6050
  PTTextInputModule,
6019
- ], template: "<pt-card [config]=\"loginPageConfig.loginCardConfig!\">\n <!-- Logo -->\n @if (loginPageConfig.logoUrl?.imageUrl) {\n <div class=\"logo-container\">\n <img\n [src]=\"loginPageConfig.logoUrl?.imageUrl\"\n [alt]=\"loginPageConfig.logoUrl?.altText || 'Logo'\"\n [style.width]=\"loginPageConfig.logoUrl?.width || '100px'\"\n [style.height]=\"loginPageConfig.logoUrl?.height || 'auto'\"\n />\n </div>\n }\n\n <!-- Title -->\n <div class=\"title-container\">\n <h1\n [ngStyle]=\"{\n color: loginPageConfig.title?.color || '#333',\n 'font-size': loginPageConfig.title?.fontSize || '24px',\n }\"\n >\n {{ loginPageConfig.title?.text || \"Default Title\" }}\n </h1>\n </div>\n\n <!-- External Error Message -->\n @if (loginErrorMessage) {\n <div class=\"error-message\">\n {{ loginErrorMessage }}\n </div>\n }\n\n <!-- Form -->\n <form class=\"form-container\" [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n @if (loginPageConfig.login?.errorMessage) {\n <div class=\"error-message\">\n {{ loginPageConfig.login?.errorMessage }}\n </div>\n }\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.usernameField!\"\n ></pt-text-input>\n </div>\n\n <div class=\"field\">\n <pt-text-input\n [formGroup]=\"formGroup\"\n [formField]=\"loginPageConfig.passwordField!\"\n ></pt-text-input>\n </div>\n\n @if (\n loginPageConfig.forgotPasswordConfig?.text &&\n loginPageConfig.forgotPasswordConfig?.url\n ) {\n <div\n class=\"forgot-password-container\"\n [ngClass]=\"\n 'forgot-password-' +\n (loginPageConfig.forgotPasswordConfig?.align || 'center')\n \"\n >\n <a\n [href]=\"loginPageConfig.forgotPasswordConfig?.url\"\n [target]=\"loginPageConfig.forgotPasswordConfig?.target || '_self'\"\n [ngStyle]=\"loginPageConfig.forgotPasswordConfig?.style\"\n [class]=\"\n loginPageConfig.forgotPasswordConfig?.styleClass ||\n 'forgot-password-link'\n \"\n >\n {{ loginPageConfig.forgotPasswordConfig?.text }}\n </a>\n </div>\n }\n\n <div class=\"submit-btn\">\n <pt-button [buttonConfig]=\"loginPageConfig.buttonConfig!\"></pt-button>\n </div>\n </form>\n\n <div class=\"login-footer\">\n {{ loginPageConfig.footer?.version }}\n <span>{{ loginPageConfig.footer?.copyright }}</span>\n </div>\n</pt-card>\n", styles: [".logo-container{display:flex;justify-content:center;align-items:center;margin-bottom:20px}.title-container{text-align:center;margin-bottom:20px}.form-container{width:100%}.field{display:flex;flex-direction:column;margin-bottom:20px;width:100%}.error-message{color:red;background-color:#ffe6e6;border:1px solid red;padding:10px;margin-bottom:10px;border-radius:5px;width:100%;text-align:center}.forgot-password-container{width:100%;display:flex;justify-content:center;margin-top:-10px;margin-bottom:20px}.forgot-password-left{justify-content:flex-start}.forgot-password-center{justify-content:center}.forgot-password-right{justify-content:flex-end}.forgot-password-link{color:#2563eb;font-size:.9rem;font-weight:500;text-decoration:none;cursor:pointer;transition:color .2s ease}.forgot-password-link:hover{color:#1d4ed8;text-decoration:underline}.submit-btn{display:flex;justify-content:center;width:100%}::ng-deep pt-button{width:100%}::ng-deep .submit-btn p-button button{width:100%}.login-footer{margin-top:20px;text-align:center;font-size:.9em;color:#555}.login-footer span{display:block;margin-top:.25rem}@media(max-width:768px){pt-card{max-width:300px}.submit-btn{min-width:100%}.forgot-password-container{justify-content:center}}\n"] }]
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"] }]
6020
6052
  }], ctorParameters: () => [{ type: i2.FormBuilder }], propDecorators: { loginPageConfig: [{
6021
6053
  type: Input
6022
6054
  }], loginErrorMessage: [{
@@ -7323,6 +7355,324 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
7323
7355
  }]
7324
7356
  }] });
7325
7357
 
7358
+ class PTChangePasswordCardComponent {
7359
+ constructor(formBuilder) {
7360
+ this.formBuilder = formBuilder;
7361
+ this.changePasswordErrorMessage = null;
7362
+ this.passwordValueChange = new EventEmitter();
7363
+ this.changePasswordSubmit = new EventEmitter();
7364
+ this.destroy$ = new Subject();
7365
+ this.formGroup = this.formBuilder.group({}, {
7366
+ validators: [this.passwordMatchValidator()],
7367
+ });
7368
+ }
7369
+ ngOnInit() {
7370
+ this.initializeDefaults();
7371
+ this.setupFormFields();
7372
+ this.listenToPasswordChanges();
7373
+ this.updateButtonDisabledState();
7374
+ }
7375
+ ngOnDestroy() {
7376
+ this.destroy$.next();
7377
+ this.destroy$.complete();
7378
+ }
7379
+ get confirmationPasswordControl() {
7380
+ return this.formGroup.get(this.changePasswordPageConfig.confirmationPasswordField?.name ??
7381
+ 'confirmationPassword');
7382
+ }
7383
+ get visiblePasswordPolicyRules() {
7384
+ return (this.changePasswordPageConfig.passwordPolicyRules?.filter((rule) => rule.visible !== false) ?? []);
7385
+ }
7386
+ get visibleAdditionalContent() {
7387
+ return (this.changePasswordPageConfig.additionalContent?.filter((item) => item.visible !== false) ?? []);
7388
+ }
7389
+ onSubmit() {
7390
+ this.formGroup.markAllAsTouched();
7391
+ if (!this.formGroup.valid) {
7392
+ this.changePasswordPageConfig.errorMessage =
7393
+ this.changePasswordPageConfig.emptyFieldsErrorMessage ??
7394
+ 'Veuillez renseigner tous les champs obligatoires.';
7395
+ return;
7396
+ }
7397
+ if (!this.areFrontendPasswordPolicyRulesValid()) {
7398
+ this.changePasswordPageConfig.errorMessage =
7399
+ 'Le nouveau mot de passe ne respecte pas les règles de sécurité.';
7400
+ return;
7401
+ }
7402
+ this.changePasswordPageConfig.errorMessage = '';
7403
+ this.changePasswordSubmit.emit(this.buildChangePasswordModel());
7404
+ }
7405
+ getAdditionalContentClass(item) {
7406
+ return [
7407
+ `additional-content-${item.align ?? 'center'}`,
7408
+ item.styleClass ?? '',
7409
+ ].filter(Boolean);
7410
+ }
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
+ setupFormFields() {
7495
+ const changePassword = this.changePasswordPageConfig.changePassword;
7496
+ if (this.changePasswordPageConfig.showCurrentPasswordField) {
7497
+ const currentPasswordField = this.changePasswordPageConfig.currentPasswordField;
7498
+ this.formGroup.addControl(currentPasswordField.name, this.formBuilder.control(changePassword.currentPassword ?? '', currentPasswordField.required ? [Validators.required] : []));
7499
+ }
7500
+ const newPasswordField = this.changePasswordPageConfig.newPasswordField;
7501
+ this.formGroup.addControl(newPasswordField.name, this.formBuilder.control(changePassword.newPassword ?? '', newPasswordField.required ? [Validators.required] : []));
7502
+ const confirmationPasswordField = this.changePasswordPageConfig.confirmationPasswordField;
7503
+ this.formGroup.addControl(confirmationPasswordField.name, this.formBuilder.control(changePassword.confirmationPassword ?? '', confirmationPasswordField.required ? [Validators.required] : []));
7504
+ }
7505
+ listenToPasswordChanges() {
7506
+ this.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(() => {
7507
+ const changePasswordModel = this.buildChangePasswordModel();
7508
+ this.changePasswordPageConfig.changePassword = changePasswordModel;
7509
+ this.passwordValueChange.emit(changePasswordModel);
7510
+ this.formGroup.updateValueAndValidity({
7511
+ emitEvent: false,
7512
+ });
7513
+ this.updateButtonDisabledState();
7514
+ });
7515
+ this.formGroup.statusChanges
7516
+ .pipe(takeUntil(this.destroy$))
7517
+ .subscribe(() => {
7518
+ this.updateButtonDisabledState();
7519
+ });
7520
+ }
7521
+ buildChangePasswordModel() {
7522
+ const currentPasswordFieldName = this.changePasswordPageConfig.currentPasswordField?.name ??
7523
+ 'currentPassword';
7524
+ const newPasswordFieldName = this.changePasswordPageConfig.newPasswordField?.name ?? 'newPassword';
7525
+ const confirmationPasswordFieldName = this.changePasswordPageConfig.confirmationPasswordField?.name ??
7526
+ 'confirmationPassword';
7527
+ return {
7528
+ currentPassword: this.changePasswordPageConfig.showCurrentPasswordField
7529
+ ? String(this.formGroup.get(currentPasswordFieldName)?.value ?? '')
7530
+ : undefined,
7531
+ newPassword: String(this.formGroup.get(newPasswordFieldName)?.value ?? ''),
7532
+ confirmationPassword: String(this.formGroup.get(confirmationPasswordFieldName)?.value ?? ''),
7533
+ };
7534
+ }
7535
+ passwordMatchValidator() {
7536
+ return (control) => {
7537
+ const newPasswordFieldName = this.changePasswordPageConfig?.newPasswordField?.name ?? 'newPassword';
7538
+ const confirmationPasswordFieldName = this.changePasswordPageConfig?.confirmationPasswordField?.name ??
7539
+ 'confirmationPassword';
7540
+ const newPassword = String(control.get(newPasswordFieldName)?.value ?? '');
7541
+ const confirmationPassword = String(control.get(confirmationPasswordFieldName)?.value ?? '');
7542
+ if (!newPassword || !confirmationPassword) {
7543
+ return null;
7544
+ }
7545
+ return newPassword === confirmationPassword
7546
+ ? null
7547
+ : { passwordMismatch: true };
7548
+ };
7549
+ }
7550
+ areFrontendPasswordPolicyRulesValid() {
7551
+ return this.visiblePasswordPolicyRules
7552
+ .filter((rule) => !rule.backendOnly)
7553
+ .every((rule) => rule.valid === true);
7554
+ }
7555
+ updateButtonDisabledState() {
7556
+ const isFormValid = this.formGroup.valid;
7557
+ const arePoliciesValid = this.areFrontendPasswordPolicyRulesValid();
7558
+ this.changePasswordPageConfig.buttonConfig = {
7559
+ ...this.changePasswordPageConfig.buttonConfig,
7560
+ disabled: !isFormValid || !arePoliciesValid,
7561
+ };
7562
+ }
7563
+ 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"] }] }); }
7565
+ }
7566
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTChangePasswordCardComponent, decorators: [{
7567
+ type: Component,
7568
+ args: [{ selector: 'pt-change-password-card', standalone: true, imports: [
7569
+ CommonModule,
7570
+ ReactiveFormsModule,
7571
+ PTCardModule,
7572
+ PTButtonModule,
7573
+ PTTextInputModule,
7574
+ 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"] }]
7576
+ }], ctorParameters: () => [{ type: i2.FormBuilder }], propDecorators: { changePasswordPageConfig: [{
7577
+ type: Input
7578
+ }], changePasswordErrorMessage: [{
7579
+ type: Input
7580
+ }], passwordValueChange: [{
7581
+ type: Output
7582
+ }], changePasswordSubmit: [{
7583
+ type: Output
7584
+ }] } });
7585
+
7586
+ class PTChangePasswordPageComponent {
7587
+ constructor() {
7588
+ this.changePasswordErrorMessage = null;
7589
+ this.passwordValueChange = new EventEmitter();
7590
+ this.changePasswordSubmit = new EventEmitter();
7591
+ this.defaultCardConfig = {
7592
+ borderRadius: '0',
7593
+ margin: '0',
7594
+ width: '100%',
7595
+ height: '100%',
7596
+ noBorder: true,
7597
+ alignContent: 'center',
7598
+ alignBodyContent: 'center',
7599
+ };
7600
+ }
7601
+ ngOnInit() {
7602
+ this.initializeDefaultPosition();
7603
+ this.applyDefaultConfigs();
7604
+ }
7605
+ onPasswordValueChange(changePasswordModel) {
7606
+ this.passwordValueChange.emit(changePasswordModel);
7607
+ }
7608
+ onChangePasswordSubmit(changePasswordModel) {
7609
+ this.changePasswordSubmit.emit(changePasswordModel);
7610
+ }
7611
+ initializeDefaultPosition() {
7612
+ this.changePasswordPageConfig.position =
7613
+ this.changePasswordPageConfig.position ?? 'center';
7614
+ }
7615
+ applyDefaultConfigs() {
7616
+ this.changePasswordPageConfig.centerCardConfig = this.applyDefaults(this.changePasswordPageConfig.centerCardConfig);
7617
+ this.changePasswordPageConfig.leftCardConfig = this.applyDefaults(this.changePasswordPageConfig.leftCardConfig);
7618
+ this.changePasswordPageConfig.rightCardConfig = this.applyDefaults(this.changePasswordPageConfig.rightCardConfig);
7619
+ }
7620
+ applyDefaults(config) {
7621
+ return {
7622
+ ...this.defaultCardConfig,
7623
+ ...(config ?? {}),
7624
+ };
7625
+ }
7626
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTChangePasswordPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7627
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTChangePasswordPageComponent, isStandalone: false, selector: "pt-change-password-page", inputs: { changePasswordPageConfig: "changePasswordPageConfig", changePasswordErrorMessage: "changePasswordErrorMessage" }, outputs: { passwordValueChange: "passwordValueChange", changePasswordSubmit: "changePasswordSubmit" }, ngImport: i0, template: "<!-- Center Position -->\n<ng-container>\n @if (changePasswordPageConfig.position === \"center\") {\n <div class=\"center-container\">\n @if (changePasswordPageConfig.centerCardConfig) {\n <pt-card [config]=\"changePasswordPageConfig.centerCardConfig\">\n <pt-change-password-card\n [changePasswordErrorMessage]=\"changePasswordErrorMessage\"\n [changePasswordPageConfig]=\"changePasswordPageConfig\"\n (passwordValueChange)=\"onPasswordValueChange($event)\"\n (changePasswordSubmit)=\"onChangePasswordSubmit($event)\"\n ></pt-change-password-card>\n </pt-card>\n }\n </div>\n }\n\n @if (\n changePasswordPageConfig.position === \"left\" ||\n changePasswordPageConfig.position === \"right\"\n ) {\n <div class=\"left-right-container\">\n @if (changePasswordPageConfig.leftCardConfig) {\n <pt-card [config]=\"changePasswordPageConfig.leftCardConfig\">\n @if (changePasswordPageConfig.position === \"left\") {\n <pt-change-password-card\n [changePasswordErrorMessage]=\"changePasswordErrorMessage\"\n [changePasswordPageConfig]=\"changePasswordPageConfig\"\n (passwordValueChange)=\"onPasswordValueChange($event)\"\n (changePasswordSubmit)=\"onChangePasswordSubmit($event)\"\n ></pt-change-password-card>\n }\n </pt-card>\n }\n\n @if (changePasswordPageConfig.rightCardConfig) {\n <pt-card [config]=\"changePasswordPageConfig.rightCardConfig\">\n @if (changePasswordPageConfig.position === \"right\") {\n <pt-change-password-card\n [changePasswordErrorMessage]=\"changePasswordErrorMessage\"\n [changePasswordPageConfig]=\"changePasswordPageConfig\"\n (passwordValueChange)=\"onPasswordValueChange($event)\"\n (changePasswordSubmit)=\"onChangePasswordSubmit($event)\"\n ></pt-change-password-card>\n }\n </pt-card>\n }\n </div>\n }\n</ng-container>\n", styles: [":host{display:block;width:100%;min-width:0}.left-right-container{display:flex;width:100%;min-height:100vh}.left-right-container pt-card{display:flex;flex:1;flex-direction:column;align-items:center;justify-content:center;width:50%;max-width:50%;min-height:100vh;box-sizing:border-box}.center-container{display:flex;align-items:center;justify-content:center;width:100%;min-height:100vh;box-sizing:border-box;margin:0;padding:0}.center-container pt-card{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;min-height:100vh;box-sizing:border-box}.center-container pt-card pt-change-password-card,.left-right-container pt-card pt-change-password-card{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;box-sizing:border-box;margin:0;padding:1rem}@media(max-width:768px){.left-right-container{flex-direction:column}.left-right-container pt-card{width:100%;max-width:100%;min-height:50vh}.center-container{align-items:flex-start;padding:1rem}.center-container pt-card{min-height:auto}.center-container pt-card pt-change-password-card,.left-right-container pt-card pt-change-password-card{padding:0}}\n"], dependencies: [{ kind: "component", type: PTCardComponent, selector: "pt-card", inputs: ["config"] }, { kind: "component", type: PTChangePasswordCardComponent, selector: "pt-change-password-card", inputs: ["changePasswordPageConfig", "changePasswordErrorMessage"], outputs: ["passwordValueChange", "changePasswordSubmit"] }] }); }
7628
+ }
7629
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTChangePasswordPageComponent, decorators: [{
7630
+ type: Component,
7631
+ args: [{ selector: 'pt-change-password-page', standalone: false, template: "<!-- Center Position -->\n<ng-container>\n @if (changePasswordPageConfig.position === \"center\") {\n <div class=\"center-container\">\n @if (changePasswordPageConfig.centerCardConfig) {\n <pt-card [config]=\"changePasswordPageConfig.centerCardConfig\">\n <pt-change-password-card\n [changePasswordErrorMessage]=\"changePasswordErrorMessage\"\n [changePasswordPageConfig]=\"changePasswordPageConfig\"\n (passwordValueChange)=\"onPasswordValueChange($event)\"\n (changePasswordSubmit)=\"onChangePasswordSubmit($event)\"\n ></pt-change-password-card>\n </pt-card>\n }\n </div>\n }\n\n @if (\n changePasswordPageConfig.position === \"left\" ||\n changePasswordPageConfig.position === \"right\"\n ) {\n <div class=\"left-right-container\">\n @if (changePasswordPageConfig.leftCardConfig) {\n <pt-card [config]=\"changePasswordPageConfig.leftCardConfig\">\n @if (changePasswordPageConfig.position === \"left\") {\n <pt-change-password-card\n [changePasswordErrorMessage]=\"changePasswordErrorMessage\"\n [changePasswordPageConfig]=\"changePasswordPageConfig\"\n (passwordValueChange)=\"onPasswordValueChange($event)\"\n (changePasswordSubmit)=\"onChangePasswordSubmit($event)\"\n ></pt-change-password-card>\n }\n </pt-card>\n }\n\n @if (changePasswordPageConfig.rightCardConfig) {\n <pt-card [config]=\"changePasswordPageConfig.rightCardConfig\">\n @if (changePasswordPageConfig.position === \"right\") {\n <pt-change-password-card\n [changePasswordErrorMessage]=\"changePasswordErrorMessage\"\n [changePasswordPageConfig]=\"changePasswordPageConfig\"\n (passwordValueChange)=\"onPasswordValueChange($event)\"\n (changePasswordSubmit)=\"onChangePasswordSubmit($event)\"\n ></pt-change-password-card>\n }\n </pt-card>\n }\n </div>\n }\n</ng-container>\n", styles: [":host{display:block;width:100%;min-width:0}.left-right-container{display:flex;width:100%;min-height:100vh}.left-right-container pt-card{display:flex;flex:1;flex-direction:column;align-items:center;justify-content:center;width:50%;max-width:50%;min-height:100vh;box-sizing:border-box}.center-container{display:flex;align-items:center;justify-content:center;width:100%;min-height:100vh;box-sizing:border-box;margin:0;padding:0}.center-container pt-card{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;min-height:100vh;box-sizing:border-box}.center-container pt-card pt-change-password-card,.left-right-container pt-card pt-change-password-card{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;box-sizing:border-box;margin:0;padding:1rem}@media(max-width:768px){.left-right-container{flex-direction:column}.left-right-container pt-card{width:100%;max-width:100%;min-height:50vh}.center-container{align-items:flex-start;padding:1rem}.center-container pt-card{min-height:auto}.center-container pt-card pt-change-password-card,.left-right-container pt-card pt-change-password-card{padding:0}}\n"] }]
7632
+ }], propDecorators: { changePasswordPageConfig: [{
7633
+ type: Input
7634
+ }], changePasswordErrorMessage: [{
7635
+ type: Input
7636
+ }], passwordValueChange: [{
7637
+ type: Output
7638
+ }], changePasswordSubmit: [{
7639
+ type: Output
7640
+ }] } });
7641
+
7642
+ class PTChangePasswordPageModule {
7643
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTChangePasswordPageModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
7644
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.14", ngImport: i0, type: PTChangePasswordPageModule, declarations: [PTChangePasswordPageComponent], imports: [CommonModule,
7645
+ FormsModule,
7646
+ ReactiveFormsModule,
7647
+ PTTextInputModule,
7648
+ PTCardModule,
7649
+ PTButtonModule,
7650
+ PTChangePasswordCardComponent], exports: [PTChangePasswordPageComponent] }); }
7651
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTChangePasswordPageModule, imports: [CommonModule,
7652
+ FormsModule,
7653
+ ReactiveFormsModule,
7654
+ PTTextInputModule,
7655
+ PTCardModule,
7656
+ PTButtonModule,
7657
+ PTChangePasswordCardComponent] }); }
7658
+ }
7659
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTChangePasswordPageModule, decorators: [{
7660
+ type: NgModule,
7661
+ args: [{
7662
+ declarations: [PTChangePasswordPageComponent],
7663
+ imports: [
7664
+ CommonModule,
7665
+ FormsModule,
7666
+ ReactiveFormsModule,
7667
+ PTTextInputModule,
7668
+ PTCardModule,
7669
+ PTButtonModule,
7670
+ PTChangePasswordCardComponent,
7671
+ ],
7672
+ exports: [PTChangePasswordPageComponent],
7673
+ }]
7674
+ }] });
7675
+
7326
7676
  // nav-bar-menu-config.model.ts
7327
7677
 
7328
7678
  // src/lib/models/pt-dialog-config.model.ts
@@ -7384,5 +7734,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
7384
7734
  * Generated bundle index. Do not edit.
7385
7735
  */
7386
7736
 
7387
- export { AlignEnum, BadgeType, BadgeTypeStyles, ButtonColorEnum, DateUtilityService, FormInputTypeEnum, InputValidationEnum, MultiSearchCriteriaComponent, MultiSearchCriteriaModule, NgPrimeToolsModule, PTAdvancedPrimeTableComponent, PTAdvancedPrimeTableModule, PTBreadCrumbComponent, PTBreadCrumbModule, PTButtonComponent, PTButtonModule, PTCardComponent, PTCardModule, PTChartComparisonComponent, PTChartComparisonModule, PTChartComponent, PTChartModule, PTCheckBoxInputComponent, PTCheckBoxInputModule, PTConfirmDialogComponent, PTConfirmDialogModule, PTDateInputComponent, PTDateInputModule, PTDialogComponent, PTDialogModule, PTDropdownComponent, PTDropdownModule, PTFooterComponent, PTFooterModule, PTFormBuilderComponent, PTFormBuilderModule, PTGroupComponent, PTGroupModule, PTLineChartComponent, PTLineChartModule, PTLoginPageComponent, PTLoginPageModule, PTMenuComponent, PTMenuFancyComponent, PTMenuFancyModule, PTMenuModule, PTMetricCardComponent, PTMetricCardGroupComponent, PTMetricCardGroupModule, PTMetricCardModule, PTMetricPanelComponent, PTMetricPanelModule, PTMultiSelectComponent, PTMultiSelectModule, PTNavbarMenuComponent, PTNavbarMenuModule, PTNumberInputComponent, PTNumberInputModule, PTPageSkeletonComponent, PTPageSkeletonModule, PTSideBarMenuComponent, PTSideBarMenuModule, PTSwitchInputComponent, PTSwitchInputModule, PTTextAreaInputComponent, PTTextAreaInputModule, PTTextInputComponent, PTTextInputModule, PTToastNotifierComponent, PTToastNotifierModule, SearchCriteriaTypeEnum, SeverityEnum, TableTypeEnum };
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 };
7388
7738
  //# sourceMappingURL=ng-prime-tools.mjs.map