@arsedizioni/ars-utils 22.5.36 → 22.5.38

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.
Files changed (26) hide show
  1. package/README.md +179 -179
  2. package/fesm2022/arsedizioni-ars-utils-clipper.ui.mjs +174 -151
  3. package/fesm2022/arsedizioni-ars-utils-clipper.ui.mjs.map +1 -1
  4. package/fesm2022/arsedizioni-ars-utils-core.date.mjs +16 -5
  5. package/fesm2022/arsedizioni-ars-utils-core.date.mjs.map +1 -1
  6. package/fesm2022/arsedizioni-ars-utils-core.mjs +43 -7
  7. package/fesm2022/arsedizioni-ars-utils-core.mjs.map +1 -1
  8. package/fesm2022/arsedizioni-ars-utils-core.validators.mjs +0 -6
  9. package/fesm2022/arsedizioni-ars-utils-core.validators.mjs.map +1 -1
  10. package/fesm2022/arsedizioni-ars-utils-ui.controls.mjs +73 -3
  11. package/fesm2022/arsedizioni-ars-utils-ui.controls.mjs.map +1 -1
  12. package/fesm2022/arsedizioni-ars-utils-ui.dialogs.auth.mjs +91 -30
  13. package/fesm2022/arsedizioni-ars-utils-ui.dialogs.auth.mjs.map +1 -1
  14. package/fesm2022/arsedizioni-ars-utils-ui.dialogs.mjs.map +1 -1
  15. package/fesm2022/arsedizioni-ars-utils-ui.dialogs.prompt.mjs +97 -42
  16. package/fesm2022/arsedizioni-ars-utils-ui.dialogs.prompt.mjs.map +1 -1
  17. package/fesm2022/arsedizioni-ars-utils-ui.dialogs.select.mjs +24 -10
  18. package/fesm2022/arsedizioni-ars-utils-ui.dialogs.select.mjs.map +1 -1
  19. package/fesm2022/arsedizioni-ars-utils-ui.files.mjs.map +1 -1
  20. package/package.json +1 -1
  21. package/types/arsedizioni-ars-utils-clipper.ui.d.ts +79 -23
  22. package/types/arsedizioni-ars-utils-core.d.ts +46 -10
  23. package/types/arsedizioni-ars-utils-ui.controls.d.ts +34 -1
  24. package/types/arsedizioni-ars-utils-ui.dialogs.auth.d.ts +116 -6
  25. package/types/arsedizioni-ars-utils-ui.dialogs.prompt.d.ts +93 -11
  26. package/types/arsedizioni-ars-utils-ui.dialogs.select.d.ts +29 -1
@@ -3,7 +3,7 @@ import { viewChildren, computed, signal, forwardRef, ChangeDetectionStrategy, Co
3
3
  import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
4
4
  import * as i1 from '@angular/material/tooltip';
5
5
  import { MatTooltipModule } from '@angular/material/tooltip';
6
- import { SystemUtils, SafeHtmlPipe } from '@arsedizioni/ars-utils/core';
6
+ import { SystemUtils, DtoUtils, SafeHtmlPipe } from '@arsedizioni/ars-utils/core';
7
7
  import { MAT_DIALOG_DATA, MatDialogTitle, MatDialogContent, MatDialogActions, MatDialogClose, MatDialogRef } from '@angular/material/dialog';
8
8
  import * as i1$2 from '@arsedizioni/ars-utils/ui';
9
9
  import { FlexLayoutModule, PromptDialogType } from '@arsedizioni/ars-utils/ui';
@@ -254,6 +254,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
254
254
  args: [{ selector: 'password-strength', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatTooltipModule], template: "<div class=\"wide x-small bold\" style=\"white-space: nowrap; padding-top:4px\" [matTooltip]=\"strength().suggestions?.join('\\n ')\">\r\n <span [class]=\"scoreClass()\">{{strength().label}}</span>\r\n</div>", styles: [".score-2{color:#f44336!important;font-weight:700}.score-3{color:#ff9800!important;font-weight:700}.score-4{color:#ffc107!important;font-weight:700}.score-5{color:#8bc34a!important;font-weight:700}.score-6{color:#4caf50!important;font-weight:700}.x-small{font-size:x-small}\n"] }]
255
255
  }], propDecorators: { password: [{ type: i0.Input, args: [{ isSignal: true, alias: "password", required: false }] }] } });
256
256
 
257
+ /** Neutral form model: it declares every field the form owns and its empty value. */
258
+ const _EMPTY_ITEM$3 = { user: '', password: '', rememberMe: false, code: '' };
257
259
  class CredentialsDialogComponent {
258
260
  constructor() {
259
261
  /** Error text of a field: the message declared in the schema, or the shared fallback. */
@@ -283,12 +285,7 @@ class CredentialsDialogComponent {
283
285
  })(), /* @ts-ignore */
284
286
  ...(ngDevMode ? [{ debugName: "dialogData" }] : /* istanbul ignore next */ []));
285
287
  /** Model backing the signal form, pre-filled with the user name from dialog data when provided. */
286
- this.model = signal({
287
- user: inject(MAT_DIALOG_DATA)?.user ?? '',
288
- password: '',
289
- rememberMe: false,
290
- code: '',
291
- }, /* @ts-ignore */
288
+ this.model = signal(this.toForm(), /* @ts-ignore */
292
289
  ...(ngDevMode ? [{ debugName: "model" }] : /* istanbul ignore next */ []));
293
290
  /**
294
291
  * Signal form for the credentials. Validators follow the active mode: the user
@@ -310,6 +307,23 @@ class CredentialsDialogComponent {
310
307
  this.showPassword = signal(false, /* @ts-ignore */
311
308
  ...(ngDevMode ? [{ debugName: "showPassword" }] : /* istanbul ignore next */ []));
312
309
  }
310
+ /**
311
+ * Builds the form model from the dialog data, which may carry the account name to
312
+ * pre-fill.
313
+ * @returns A fresh form model.
314
+ */
315
+ toForm() {
316
+ return DtoUtils.toForm(_EMPTY_ITEM$3, { user: this.dialogData().user });
317
+ }
318
+ /**
319
+ * Builds the dialog result from the current form model. The fields the active mode
320
+ * does not use are left empty by the template and dropped here, so they travel as
321
+ * absent instead of as empty strings.
322
+ * @returns The credentials to emit through `done` or `recoveringPassword`.
323
+ */
324
+ toPayload() {
325
+ return DtoUtils.toPayload(this.model());
326
+ }
313
327
  /**
314
328
  * Switches the input mode of the dialog at runtime (e.g. from login to OTP).
315
329
  * Intended to be called from outside via the dialog component reference.
@@ -327,14 +341,14 @@ class CredentialsDialogComponent {
327
341
  * Emits the current form result and closes the dialog.
328
342
  */
329
343
  ok() {
330
- this.done.emit(this.model());
344
+ this.done.emit(this.toPayload());
331
345
  }
332
346
  /**
333
347
  * Emits the current form result for the password-recovery flow and optionally
334
348
  * opens the recovery URL in a new tab.
335
349
  */
336
350
  recoverPassword() {
337
- this.recoveringPassword.emit(this.model());
351
+ this.recoveringPassword.emit(this.toPayload());
338
352
  const url = this.dialogData().recoverPasswordUrl;
339
353
  if (url) {
340
354
  window.open(url, '_blank');
@@ -363,7 +377,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
363
377
  ], template: "<div class=\"dialog-info\">\n @if (form().invalid()) {\n <span class=\"dialog-info-error\">Ci sono ancora dei campi obbligatori (*) non compilati.</span>\n } @else {\n <span class=\"dialog-info-ok\">Tutti i campi obbligatori (*) sono compilati.</span>\n }\n</div>\n<div mat-dialog-title [innerHTML]=\"dialogData().title | safeHtml\"></div>\n<mat-dialog-content class=\"dialog-content\">\n @if (dialogData().message) {\n <div [innerHtml]=\"dialogData().message | safeHtml\" style=\"padding-bottom: 20px;\"></div>\n }\n <form [formRoot]=\"form\" (keyup.enter)=\"!form().invalid() ? ok() : undefined\" novalidate>\n @if(dialogData().mode !== 'otp') {\n @if (dialogData().mode === 'email') {\n <mat-form-field style=\"width: 100%;\" [appearance]=\"dialogData().appearance\">\n <mat-label>Email</mat-label>\n <input type=\"email\" matInput [formField]=\"form.user\" [attr.aria-label]=\"'Email'\">\n @if (form.user().invalid()) {\n <mat-error>{{ getErrorMessage(form.user().errors()) }}</mat-error>\n }\n </mat-form-field>\n } @else if (dialogData().mode === 'user') {\n <mat-form-field style=\"width: 100%;\" [appearance]=\"dialogData().appearance\">\n <mat-label>Utente</mat-label>\n <input matInput [formField]=\"form.user\" [attr.aria-label]=\"'user'\">\n @if (form.user().invalid()) {\n <mat-error>{{ getErrorMessage(form.user().errors()) }}</mat-error>\n }\n </mat-form-field>\n }\n <mat-form-field style=\"width: 100%;\" [appearance]=\"dialogData().appearance\">\n <mat-label>La tua password abilitata</mat-label>\n <input matInput [type]=\"!showPassword() ? 'password' : 'text'\"\n [formField]=\"form.password\" [attr.aria-label]=\"'La tua password abilitata'\" autocomplete=\"on\">\n @if(form.password().value()) {\n <password-strength [password]=\"form.password().value()\"></password-strength>\n }\n <button type=\"button\" mat-icon-button class=\"toolbar-suffix\" matSuffix (click)=\"showPassword.set(!showPassword())\">\n <mat-icon>{{showPassword() ? 'visibility' : 'visibility_off'}}</mat-icon>\n </button>\n <mat-hint>Attento a maiuscole e minuscole</mat-hint>\n @if (form.password().invalid()) {\n <mat-error>{{ getErrorMessage(form.password().errors()) }}</mat-error>\n }\n </mat-form-field>\n @if (dialogData().remember || dialogData().recoverPassword) {\n <div fxLayout=\"row\" fxLayoutGap=\"20px\" fxFill style=\"margin-top: 20px;\">\n <div>\n @if (dialogData().remember) {\n <mat-checkbox fxFlexAlign=\"center\" [formField]=\"form.rememberMe\"> Ricordami</mat-checkbox>\n }\n </div>\n <div fxLayoutAlign=\"end\">\n @if (dialogData().recoverPassword) {\n <button fxFlexAlign=\"center\" mat-button (click)=\"recoverPassword()\" title=\"Recupero password\"\n >Non riesco ad accedere</button>\n }\n </div>\n </div>\n }\n } @else {\n <otp-input [formField]=\"form.code\"></otp-input>\n }\n </form>\n</mat-dialog-content>\n<mat-dialog-actions>\n <div fxLayout=\"row\" fxLayoutAlign=\"end\" fxFill>\n <button mat-flat-button [disabled]=\"form().invalid()\" (click)=\"ok()\">{{dialogData().okCaption}}</button>\n <button mat-stroked-button [mat-dialog-close]=\"true\">Annulla</button>\n </div>\n</mat-dialog-actions>\n", styles: [".fill,.wide{min-width:100%!important;max-width:100%!important;width:100%!important}.dialog-info{font-size:x-small;font-weight:700;text-align:right;padding:10px}.dialog-info-green,.dialog-info-ok{color:var(--ars-color-ok, #388E3C)}.dialog-info-red,.dialog-info-error{color:var(--mat-form-field-error-text-color, #a80710)}.dialog-header{padding-bottom:20px}.dialog-toolbar{padding:0 5px 0 24px;height:48px;min-height:48px}.dialog-close{margin-right:5px;margin-top:0}.dialog-menu{margin-left:10px;margin-top:10px}.dialog-title{padding:0 24px}.section-title{font-size:large;font-weight:600;padding-top:10px;padding-bottom:8px}.center{text-align:center}.fill{min-height:100%!important;max-height:100%!important;height:100%!important}.scroll-auto{overflow:auto;height:100%}.scroll-hidden{overflow:hidden;height:100%}b{font-weight:700}.large{font-size:large!important;line-height:1.2!important}.smaller{font-size:smaller!important;line-height:1.2!important}.small{font-size:small!important;line-height:1.2!important}.small-icon-button{width:1.5rem!important;height:1.5rem!important;padding:0!important;display:inline-flex!important;align-items:center;justify-content:center}.small-icon-button .mat-mdc-button-touch-target{width:1.5rem!important;height:1.5rem!important}.x-small{font-size:x-small!important;line-height:1.2!important}.bold{font-weight:700}.uppercase{text-transform:uppercase!important}.lowercase{text-transform:lowercase!important}.truncated{min-width:0;max-width:100%}@supports (-webkit-line-clamp: 2){.truncated{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}.truncated span,.truncated div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@supports (-webkit-line-clamp: 2){.truncated span,.truncated div{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}.clipped{min-width:0;max-width:100%}.clipped span,.clipped div{white-space:nowrap;overflow:hidden;text-overflow:clip}.accent{color:var(--ars-color-accent, #7894ae)!important}.primary{color:var(--ars-color-primary, #00a293)!important}.secondary{color:var(--ars-color-secondary, #4a635f)!important}.error{color:var(--ars-color-error, #ff5449)!important}.success{color:var(--ars-color-ok, #388E3C)!important}.warning{color:var(--ars-color-warning, #FFC107)!important}.text{color:var(--ars-color-text, #191c1b)!important}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10;background-color:var(--ars-color-overlay, rgba(255, 255, 255, .75))}.drawer-content{padding-top:10px}.drawer .title-container,.drawer .title-container-with-loader,.drawer-small .title-container,.drawer-small .title-container-with-loader{padding-right:5px;padding-bottom:20px;padding-left:0}.drawer .title-container,.drawer-small .title-container{padding-top:20px}.drawer .title-container-with-loader,.drawer-small .title-container-with-loader{padding-top:14px}.drawer .title,.drawer-small .title{font-size:19.2px!important;font-weight:600;padding-left:15px;min-width:150px;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.drawer .accordion-panel,.drawer-small .accordion-panel{background-color:transparent!important}.drawer .accordion-header,.drawer-small .accordion-header{padding-left:10px;padding-right:10px;border-radius:var(--mat-expansion-container-shape)}.drawer .mat-expansion-panel-body,.drawer-small .mat-expansion-panel-body{padding-left:10px!important;padding-right:10px!important;padding-bottom:20px!important}@media screen and (min-width:0px)and (max-width:430px){.drawer,.drawer-small{border-radius:0!important;min-width:100%!important;max-width:100%!important}}@media screen and (min-width:431px){.drawer{min-width:420px!important;max-width:420px!important}.drawer .title{min-width:200px}.drawer .mat-expansion-panel-body{padding-left:15px!important;padding-right:15px!important;padding-bottom:20px!important}.drawer-small{min-width:360px!important;max-width:360px!important}}.drawer-with-loader{padding-top:0!important}.drawer-transparent{background-color:transparent}.fade-in{animation:fadein .5s linear}@keyframes fadein{0%{opacity:0}to{opacity:1}}.bright{filter:brightness(.7)!important}@media(prefers-color-scheme:dark){.dialog-info-green,.dialog-info-ok{color:var(--ars-color-ok, #4CAF50)}.dialog-info-red,.dialog-info-error{color:var(--mat-form-field-error-text-color, #ff5449)}b,.bold{font-weight:600}.bright{filter:brightness(1.5)!important}}input[type=password]::-ms-reveal{display:none}input[type=password]::-webkit-credentials-auto-fill-button{visibility:hidden;display:none!important}.dialog-content{padding:0 24px 24px!important}\n"] }]
364
378
  }], propDecorators: { done: [{ type: i0.Output, args: ["done"] }], recoveringPassword: [{ type: i0.Output, args: ["recoveringPassword"] }] } });
365
379
 
380
+ /** Neutral form model: it declares every field the form owns and its empty value. */
381
+ const _EMPTY_ITEM$2 = {
382
+ userId: null,
383
+ userEmail: '',
384
+ oldPassword: '',
385
+ password: '',
386
+ password2: '',
387
+ code: '',
388
+ };
366
389
  class ResetPasswordDialogComponent {
390
+ /**
391
+ * Builds the form model from the dialog data, which identifies the account either by
392
+ * id or by email depending on the mode.
393
+ * @returns A fresh form model.
394
+ */
395
+ toForm() {
396
+ const data = this.dialogData();
397
+ return DtoUtils.toForm(_EMPTY_ITEM$2, { userId: data.userId, userEmail: data.userEmail });
398
+ }
399
+ /**
400
+ * Builds the dialog result from the current form model. The fields the active mode
401
+ * does not use are left empty by the template and dropped here, so they travel as
402
+ * absent instead of as empty strings.
403
+ * @returns The reset data to emit through `done`.
404
+ */
405
+ toPayload() {
406
+ return DtoUtils.toPayload(this.model());
407
+ }
367
408
  constructor() {
368
409
  /** Error text of a field: the message declared in the schema, or the shared fallback. */
369
410
  this.getErrorMessage = SignalsUtils.getFieldErrorMessage;
@@ -378,13 +419,7 @@ class ResetPasswordDialogComponent {
378
419
  })(), /* @ts-ignore */
379
420
  ...(ngDevMode ? [{ debugName: "dialogData" }] : /* istanbul ignore next */ []));
380
421
  /** Model backing the signal form. */
381
- this.model = signal({
382
- userEmail: '',
383
- oldPassword: '',
384
- password: '',
385
- password2: '',
386
- code: '',
387
- }, /* @ts-ignore */
422
+ this.model = signal(this.toForm(), /* @ts-ignore */
388
423
  ...(ngDevMode ? [{ debugName: "model" }] : /* istanbul ignore next */ []));
389
424
  /**
390
425
  * Signal form for the password reset. Validators follow the active mode:
@@ -436,18 +471,12 @@ class ResetPasswordDialogComponent {
436
471
  this.dialogService.error('Email utente non specificata.');
437
472
  return;
438
473
  }
439
- this.model.update(m => ({
440
- ...m,
441
- userEmail: data.userEmail ?? '',
442
- userId: data.userId,
443
- code: '',
444
- }));
445
474
  }
446
475
  /**
447
476
  * Emits the current form result to trigger the password-reset flow.
448
477
  */
449
478
  ok() {
450
- this.done.emit(this.model());
479
+ this.done.emit(this.toPayload());
451
480
  }
452
481
  /**
453
482
  * Generates a random password and populates both password fields with it.
@@ -477,6 +506,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
477
506
  ], template: "<div class=\"dialog-info\">\r\n @if (form().invalid()) {\r\n <span class=\"dialog-info-error\">Ci sono ancora dei campi obbligatori (*) non compilati.</span>\r\n } @else {\r\n <span class=\"dialog-info-ok\">Tutti i campi obbligatori (*) sono compilati.</span>\r\n }\r\n</div>\r\n<div mat-dialog-title>Reimposta password</div>\r\n<mat-dialog-content class=\"dialog-content\">\r\n <form [formRoot]=\"form\" novalidate >\r\n @if (dialogData().mode === 'forgot') {\r\n <mat-form-field style=\"width: 100%;\" [appearance]=\"dialogData().appearance\">\r\n <mat-label>Email che hai scelto quando ti sei registrato</mat-label>\r\n <input type=\"email\" matInput [formField]=\"form.userEmail\"\r\n [attr.aria-label]=\"'Email con cui ti sei registrato'\">\r\n @if (form.userEmail().invalid()) {\r\n <mat-error>{{ getErrorMessage(form.userEmail().errors()) }}</mat-error>\r\n }\r\n </mat-form-field>\r\n } @else if (dialogData().mode === 'old') {\r\n <mat-form-field style=\"width: 100%;\" [appearance]=\"dialogData().appearance\">\r\n <mat-label>Vecchia password</mat-label>\r\n <input [type]=\"!showOldPassword() ? 'password' : 'text'\" matInput autocomplete=\"on\"\r\n [formField]=\"form.oldPassword\">\r\n <button type=\"button\" mat-icon-button class=\"toolbar-suffix\" matSuffix\r\n (click)=\"showOldPassword.set(!showOldPassword())\">\r\n <mat-icon>{{showOldPassword() ? 'visibility' : 'visibility_off'}}</mat-icon>\r\n </button>\r\n @if(form.oldPassword().value()) {\r\n <password-strength [password]=\"form.oldPassword().value()\"></password-strength>\r\n }\r\n @if (form.oldPassword().invalid()) {\r\n <mat-error>{{ getErrorMessage(form.oldPassword().errors()) }}</mat-error>\r\n }\r\n </mat-form-field>\r\n } @else if (dialogData().mode === 'otp') {\r\n <div style=\"font-size: small;\">Inserisci il codice di verifica di 6 cifre che ti abbiamo inviato ora per\r\n email<br><span style=\"font-size:x-small\">(controlla anche la posta indesiderata)</span>.</div>\r\n <otp-input [formField]=\"form.code\"></otp-input>\r\n }\r\n <mat-form-field style=\"width: 100%;\" hintLabel=\"Minimo 10 car. con 1 simbolo e 1 maiuscola\"\r\n [appearance]=\"dialogData().appearance\">\r\n <mat-label>Nuova password</mat-label>\r\n <input [type]=\"!showPassword() ? 'password' : 'text'\" matInput [formField]=\"form.password\">\r\n @if(form.password().value()) {\r\n <password-strength [password]=\"form.password().value()\"></password-strength>\r\n }\r\n <button type=\"button\" mat-icon-button class=\"toolbar-suffix\" matSuffix\r\n (click)=\"showPassword.set(!showPassword())\">\r\n <mat-icon>{{showPassword() ? 'visibility' : 'visibility_off'}}</mat-icon>\r\n </button>\r\n <mat-hint align=\"end\">{{form.password().value()?.length || 0}}/30</mat-hint>\r\n @if (form.password().invalid()) {\r\n <mat-error>{{ getErrorMessage(form.password().errors()) }}</mat-error>\r\n }\r\n </mat-form-field>\r\n <mat-form-field style=\"width: 100%;\" hintLabel=\"Minimo 10 car. con 1 simbolo e 1 maiuscola\"\r\n [appearance]=\"dialogData().appearance\">\r\n <mat-label>Conferma nuova password</mat-label>\r\n <input [type]=\"!showPassword2() ? 'password' : 'text'\" matInput [formField]=\"form.password2\">\r\n <button type=\"button\" mat-icon-button class=\"toolbar-suffix\" matSuffix\r\n (click)=\"showPassword2.set(!showPassword2())\">\r\n <mat-icon>{{showPassword2() ? 'visibility' : 'visibility_off'}}</mat-icon>\r\n </button>\r\n @if(form.password2().value()) {\r\n <password-strength [password]=\"form.password2().value()\"></password-strength>\r\n }\r\n <mat-hint align=\"end\">{{form.password2().value()?.length || 0}}/30</mat-hint>\r\n @if (form.password2().invalid()) {\r\n <mat-error>{{ getErrorMessage(form.password2().errors()) }}</mat-error>\r\n }\r\n </mat-form-field>\r\n </form>\r\n</mat-dialog-content>\r\n<mat-dialog-actions>\r\n <div fxLayout=\"row\" fxLayoutGap=\"10px\" fxFill>\r\n <div fxFlex=\"30\">\r\n @if (dialogData().mode === 'admin') {\r\n <button mat-stroked-button (click)=\"generatePassword()\">Genera</button>\r\n }\r\n </div>\r\n <div fxFlex=\"70\" fxLayoutAlign=\"end\">\r\n <button mat-flat-button [disabled]=\"form().invalid()\" (click)=\"ok()\">Salva</button>\r\n @if (dialogData().mode !== 'forgot') {\r\n <button mat-stroked-button [mat-dialog-close]=\"true\">Annulla</button>\r\n }\r\n </div>\r\n </div>\r\n</mat-dialog-actions>\r\n", styles: [".fill,.wide{min-width:100%!important;max-width:100%!important;width:100%!important}.dialog-info{font-size:x-small;font-weight:700;text-align:right;padding:10px}.dialog-info-green,.dialog-info-ok{color:var(--ars-color-ok, #388E3C)}.dialog-info-red,.dialog-info-error{color:var(--mat-form-field-error-text-color, #a80710)}.dialog-header{padding-bottom:20px}.dialog-toolbar{padding:0 5px 0 24px;height:48px;min-height:48px}.dialog-close{margin-right:5px;margin-top:0}.dialog-menu{margin-left:10px;margin-top:10px}.dialog-title{padding:0 24px}.section-title{font-size:large;font-weight:600;padding-top:10px;padding-bottom:8px}.center{text-align:center}.fill{min-height:100%!important;max-height:100%!important;height:100%!important}.scroll-auto{overflow:auto;height:100%}.scroll-hidden{overflow:hidden;height:100%}b{font-weight:700}.large{font-size:large!important;line-height:1.2!important}.smaller{font-size:smaller!important;line-height:1.2!important}.small{font-size:small!important;line-height:1.2!important}.small-icon-button{width:1.5rem!important;height:1.5rem!important;padding:0!important;display:inline-flex!important;align-items:center;justify-content:center}.small-icon-button .mat-mdc-button-touch-target{width:1.5rem!important;height:1.5rem!important}.x-small{font-size:x-small!important;line-height:1.2!important}.bold{font-weight:700}.uppercase{text-transform:uppercase!important}.lowercase{text-transform:lowercase!important}.truncated{min-width:0;max-width:100%}@supports (-webkit-line-clamp: 2){.truncated{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}.truncated span,.truncated div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@supports (-webkit-line-clamp: 2){.truncated span,.truncated div{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}.clipped{min-width:0;max-width:100%}.clipped span,.clipped div{white-space:nowrap;overflow:hidden;text-overflow:clip}.accent{color:var(--ars-color-accent, #7894ae)!important}.primary{color:var(--ars-color-primary, #00a293)!important}.secondary{color:var(--ars-color-secondary, #4a635f)!important}.error{color:var(--ars-color-error, #ff5449)!important}.success{color:var(--ars-color-ok, #388E3C)!important}.warning{color:var(--ars-color-warning, #FFC107)!important}.text{color:var(--ars-color-text, #191c1b)!important}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10;background-color:var(--ars-color-overlay, rgba(255, 255, 255, .75))}.drawer-content{padding-top:10px}.drawer .title-container,.drawer .title-container-with-loader,.drawer-small .title-container,.drawer-small .title-container-with-loader{padding-right:5px;padding-bottom:20px;padding-left:0}.drawer .title-container,.drawer-small .title-container{padding-top:20px}.drawer .title-container-with-loader,.drawer-small .title-container-with-loader{padding-top:14px}.drawer .title,.drawer-small .title{font-size:19.2px!important;font-weight:600;padding-left:15px;min-width:150px;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.drawer .accordion-panel,.drawer-small .accordion-panel{background-color:transparent!important}.drawer .accordion-header,.drawer-small .accordion-header{padding-left:10px;padding-right:10px;border-radius:var(--mat-expansion-container-shape)}.drawer .mat-expansion-panel-body,.drawer-small .mat-expansion-panel-body{padding-left:10px!important;padding-right:10px!important;padding-bottom:20px!important}@media screen and (min-width:0px)and (max-width:430px){.drawer,.drawer-small{border-radius:0!important;min-width:100%!important;max-width:100%!important}}@media screen and (min-width:431px){.drawer{min-width:420px!important;max-width:420px!important}.drawer .title{min-width:200px}.drawer .mat-expansion-panel-body{padding-left:15px!important;padding-right:15px!important;padding-bottom:20px!important}.drawer-small{min-width:360px!important;max-width:360px!important}}.drawer-with-loader{padding-top:0!important}.drawer-transparent{background-color:transparent}.fade-in{animation:fadein .5s linear}@keyframes fadein{0%{opacity:0}to{opacity:1}}.bright{filter:brightness(.7)!important}@media(prefers-color-scheme:dark){.dialog-info-green,.dialog-info-ok{color:var(--ars-color-ok, #4CAF50)}.dialog-info-red,.dialog-info-error{color:var(--mat-form-field-error-text-color, #ff5449)}b,.bold{font-weight:600}.bright{filter:brightness(1.5)!important}}input[type=password]::-ms-reveal{display:none}input[type=password]::-webkit-credentials-auto-fill-button{visibility:hidden;display:none!important}.dialog-content{padding:0 24px 24px!important}\n"] }]
478
507
  }], ctorParameters: () => [], propDecorators: { done: [{ type: i0.Output, args: ["done"] }] } });
479
508
 
509
+ /** Neutral form model: it declares every field the form owns and its empty value. */
510
+ const _EMPTY_ITEM$1 = { email: '', recaptcha: false };
480
511
  class RecoverPasswordDialogComponent {
481
512
  constructor() {
482
513
  /** Error text of a field: the message declared in the schema, or the shared fallback. */
@@ -490,10 +521,7 @@ class RecoverPasswordDialogComponent {
490
521
  }, /* @ts-ignore */
491
522
  ...(ngDevMode ? [{ debugName: "dialogData" }] : /* istanbul ignore next */ []));
492
523
  /** Model backing the signal form. */
493
- this.model = signal({
494
- email: '',
495
- recaptcha: false,
496
- }, /* @ts-ignore */
524
+ this.model = signal(this.toForm(), /* @ts-ignore */
497
525
  ...(ngDevMode ? [{ debugName: "model" }] : /* istanbul ignore next */ []));
498
526
  /**
499
527
  * Signal form for the recovery request: the email is required and must be valid.
@@ -505,11 +533,27 @@ class RecoverPasswordDialogComponent {
505
533
  maxLength(p.email, 200);
506
534
  });
507
535
  }
536
+ /**
537
+ * Builds the form model. The dialog is always opened empty, so the model is the
538
+ * neutral one.
539
+ * @returns A fresh form model.
540
+ */
541
+ toForm() {
542
+ return DtoUtils.toForm(_EMPTY_ITEM$1);
543
+ }
544
+ /**
545
+ * Builds the dialog result from the current form model, dropping the email when it
546
+ * was left empty.
547
+ * @returns The result to emit through `done`.
548
+ */
549
+ toPayload() {
550
+ return DtoUtils.toPayload(this.model());
551
+ }
508
552
  /**
509
553
  * Emits the current form result to trigger the password-recovery flow.
510
554
  */
511
555
  ok() {
512
- this.done.emit(this.model());
556
+ this.done.emit(this.toPayload());
513
557
  }
514
558
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: RecoverPasswordDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
515
559
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: RecoverPasswordDialogComponent, isStandalone: true, selector: "ng-component", outputs: { done: "done" }, ngImport: i0, template: "<div class=\"dialog-info\">\n @if (form().invalid()) {\n <span class=\"dialog-info-error\">Ci sono ancora dei campi obbligatori (*) non compilati.</span>\n } @else {\n <span class=\"dialog-info-ok\">Tutti i campi obbligatori (*) sono compilati.</span>\n }\n</div>\n<div mat-dialog-title>Per quale ragione non sei in grado di effettuare l'accesso?</div>\n<mat-dialog-content class=\"dialog-content\">\n\n <b>1. Ho dimenticato la password</b>\n <p>\n Puoi recuperarla facilmente inserendo l'email a cui la password \u00E8 collegata. Non \u00E8 possibile recuperare password\n aziendali (non collegate ad un email).</p>\n <form [formRoot]=\"form\" (keyup.enter)=\"!form().invalid() ? ok() : undefined\" novalidate>\n\n <mat-form-field style=\"width:100%\" [appearance]=\"dialogData().appearance\">\n <mat-label>Email con cui ti sei registrato</mat-label>\n <input type=\"email\" matInput [formField]=\"form.email\" />\n @if (form.email().invalid()) {\n <mat-error>{{ getErrorMessage(form.email().errors()) }}</mat-error>\n }\n </mat-form-field>\n\n <div style=\"margin-top:20px; margin-bottom:20px;\">\n <button type=\"button\" mat-flat-button (click)=\"ok()\" [disabled]=\"form().invalid()\"\n aria-label=\"Recupera password\">Recupera password</button>\n </div>\n </form>\n <p></p>\n <b>2. Il sistema mi dice che la password non \u00E8 corretta.</b>\n <p>\n E' molto probabile che ci sia stato un difetto di digitazione. Per favore controlla bene che non vi siano spazi non\n richiesti e che la password rispetti perfettamente le maiuscole e minuscole. Nel caso in cui la digitazione fosse\n corretta, verifica che la data del tuo abbonamento non sia scaduta.\n </p>\n <p></p>\n <b>3. Il sistema mi dice che non pu\u00F2 accettare connessioni dal mio indirizzo IP</b>\n <p>\n Il tuo abbonamento \u00E8 stato vincolato ad un indirizzo IP (indirizzo dal quale ti colleghi). Capita sovente che\n questi indirizzi siano cambiati da parte del reparto IT per questioni di sicurezza informatica.\n Per risolvere il problema, contattate il reparto IT e fatevi dire qual'\u00E8 il nuovo indirizzo IP e comunicatelo ad\n ARS Edizioni Informatiche.\n </p>\n</mat-dialog-content>\n<mat-dialog-actions>\n <div fxLayout=\"row\" fxLayoutAlign=\"end\" fxFill>\n <button mat-stroked-button [mat-dialog-close]=\"true\" >Chiudi</button>\n </div>\n</mat-dialog-actions>", styles: [".fill,.wide{min-width:100%!important;max-width:100%!important;width:100%!important}.dialog-info{font-size:x-small;font-weight:700;text-align:right;padding:10px}.dialog-info-green,.dialog-info-ok{color:var(--ars-color-ok, #388E3C)}.dialog-info-red,.dialog-info-error{color:var(--mat-form-field-error-text-color, #a80710)}.dialog-header{padding-bottom:20px}.dialog-toolbar{padding:0 5px 0 24px;height:48px;min-height:48px}.dialog-close{margin-right:5px;margin-top:0}.dialog-menu{margin-left:10px;margin-top:10px}.dialog-title{padding:0 24px}.section-title{font-size:large;font-weight:600;padding-top:10px;padding-bottom:8px}.center{text-align:center}.fill{min-height:100%!important;max-height:100%!important;height:100%!important}.scroll-auto{overflow:auto;height:100%}.scroll-hidden{overflow:hidden;height:100%}b{font-weight:700}.large{font-size:large!important;line-height:1.2!important}.smaller{font-size:smaller!important;line-height:1.2!important}.small{font-size:small!important;line-height:1.2!important}.small-icon-button{width:1.5rem!important;height:1.5rem!important;padding:0!important;display:inline-flex!important;align-items:center;justify-content:center}.small-icon-button .mat-mdc-button-touch-target{width:1.5rem!important;height:1.5rem!important}.x-small{font-size:x-small!important;line-height:1.2!important}.bold{font-weight:700}.uppercase{text-transform:uppercase!important}.lowercase{text-transform:lowercase!important}.truncated{min-width:0;max-width:100%}@supports (-webkit-line-clamp: 2){.truncated{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}.truncated span,.truncated div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@supports (-webkit-line-clamp: 2){.truncated span,.truncated div{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}.clipped{min-width:0;max-width:100%}.clipped span,.clipped div{white-space:nowrap;overflow:hidden;text-overflow:clip}.accent{color:var(--ars-color-accent, #7894ae)!important}.primary{color:var(--ars-color-primary, #00a293)!important}.secondary{color:var(--ars-color-secondary, #4a635f)!important}.error{color:var(--ars-color-error, #ff5449)!important}.success{color:var(--ars-color-ok, #388E3C)!important}.warning{color:var(--ars-color-warning, #FFC107)!important}.text{color:var(--ars-color-text, #191c1b)!important}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10;background-color:var(--ars-color-overlay, rgba(255, 255, 255, .75))}.drawer-content{padding-top:10px}.drawer .title-container,.drawer .title-container-with-loader,.drawer-small .title-container,.drawer-small .title-container-with-loader{padding-right:5px;padding-bottom:20px;padding-left:0}.drawer .title-container,.drawer-small .title-container{padding-top:20px}.drawer .title-container-with-loader,.drawer-small .title-container-with-loader{padding-top:14px}.drawer .title,.drawer-small .title{font-size:19.2px!important;font-weight:600;padding-left:15px;min-width:150px;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.drawer .accordion-panel,.drawer-small .accordion-panel{background-color:transparent!important}.drawer .accordion-header,.drawer-small .accordion-header{padding-left:10px;padding-right:10px;border-radius:var(--mat-expansion-container-shape)}.drawer .mat-expansion-panel-body,.drawer-small .mat-expansion-panel-body{padding-left:10px!important;padding-right:10px!important;padding-bottom:20px!important}@media screen and (min-width:0px)and (max-width:430px){.drawer,.drawer-small{border-radius:0!important;min-width:100%!important;max-width:100%!important}}@media screen and (min-width:431px){.drawer{min-width:420px!important;max-width:420px!important}.drawer .title{min-width:200px}.drawer .mat-expansion-panel-body{padding-left:15px!important;padding-right:15px!important;padding-bottom:20px!important}.drawer-small{min-width:360px!important;max-width:360px!important}}.drawer-with-loader{padding-top:0!important}.drawer-transparent{background-color:transparent}.fade-in{animation:fadein .5s linear}@keyframes fadein{0%{opacity:0}to{opacity:1}}.bright{filter:brightness(.7)!important}@media(prefers-color-scheme:dark){.dialog-info-green,.dialog-info-ok{color:var(--ars-color-ok, #4CAF50)}.dialog-info-red,.dialog-info-error{color:var(--mat-form-field-error-text-color, #ff5449)}b,.bold{font-weight:600}.bright{filter:brightness(1.5)!important}}.dialog-content{padding:0 24px 24px!important}\n"], dependencies: [{ kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: FormRoot, selector: "form[formRoot]", inputs: ["formRoot"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "ngmodule", type: FlexLayoutModule }, { kind: "directive", type: i1$2.FxLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg] ", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i1$2.FxLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg] ", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i1$2.FxFlexFillDirective, selector: " [fxFlexFill], [fxFill], [fxFlexFill.xs], [fxFlexFill.sm], [fxFlexFill.md], [fxFlexFill.lg], [fxFlexFill.xl], [fxFlexFill.lt-sm], [fxFlexFill.lt-md], [fxFlexFill.lt-lg], [fxFlexFill.lt-xl], [fxFlexFill.gt-xs], [fxFlexFill.gt-sm], [fxFlexFill.gt-md], [fxFlexFill.gt-lg] ", inputs: ["fxFlexFill", "fxFill", "fxFlexFill.xs", "fxFlexFill.sm", "fxFlexFill.md", "fxFlexFill.lg", "fxFlexFill.xl", "fxFlexFill.lt-sm", "fxFlexFill.lt-md", "fxFlexFill.lt-lg", "fxFlexFill.lt-xl", "fxFlexFill.gt-xs", "fxFlexFill.gt-sm", "fxFlexFill.gt-md", "fxFlexFill.gt-lg"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
@@ -529,6 +573,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
529
573
  ], template: "<div class=\"dialog-info\">\n @if (form().invalid()) {\n <span class=\"dialog-info-error\">Ci sono ancora dei campi obbligatori (*) non compilati.</span>\n } @else {\n <span class=\"dialog-info-ok\">Tutti i campi obbligatori (*) sono compilati.</span>\n }\n</div>\n<div mat-dialog-title>Per quale ragione non sei in grado di effettuare l'accesso?</div>\n<mat-dialog-content class=\"dialog-content\">\n\n <b>1. Ho dimenticato la password</b>\n <p>\n Puoi recuperarla facilmente inserendo l'email a cui la password \u00E8 collegata. Non \u00E8 possibile recuperare password\n aziendali (non collegate ad un email).</p>\n <form [formRoot]=\"form\" (keyup.enter)=\"!form().invalid() ? ok() : undefined\" novalidate>\n\n <mat-form-field style=\"width:100%\" [appearance]=\"dialogData().appearance\">\n <mat-label>Email con cui ti sei registrato</mat-label>\n <input type=\"email\" matInput [formField]=\"form.email\" />\n @if (form.email().invalid()) {\n <mat-error>{{ getErrorMessage(form.email().errors()) }}</mat-error>\n }\n </mat-form-field>\n\n <div style=\"margin-top:20px; margin-bottom:20px;\">\n <button type=\"button\" mat-flat-button (click)=\"ok()\" [disabled]=\"form().invalid()\"\n aria-label=\"Recupera password\">Recupera password</button>\n </div>\n </form>\n <p></p>\n <b>2. Il sistema mi dice che la password non \u00E8 corretta.</b>\n <p>\n E' molto probabile che ci sia stato un difetto di digitazione. Per favore controlla bene che non vi siano spazi non\n richiesti e che la password rispetti perfettamente le maiuscole e minuscole. Nel caso in cui la digitazione fosse\n corretta, verifica che la data del tuo abbonamento non sia scaduta.\n </p>\n <p></p>\n <b>3. Il sistema mi dice che non pu\u00F2 accettare connessioni dal mio indirizzo IP</b>\n <p>\n Il tuo abbonamento \u00E8 stato vincolato ad un indirizzo IP (indirizzo dal quale ti colleghi). Capita sovente che\n questi indirizzi siano cambiati da parte del reparto IT per questioni di sicurezza informatica.\n Per risolvere il problema, contattate il reparto IT e fatevi dire qual'\u00E8 il nuovo indirizzo IP e comunicatelo ad\n ARS Edizioni Informatiche.\n </p>\n</mat-dialog-content>\n<mat-dialog-actions>\n <div fxLayout=\"row\" fxLayoutAlign=\"end\" fxFill>\n <button mat-stroked-button [mat-dialog-close]=\"true\" >Chiudi</button>\n </div>\n</mat-dialog-actions>", styles: [".fill,.wide{min-width:100%!important;max-width:100%!important;width:100%!important}.dialog-info{font-size:x-small;font-weight:700;text-align:right;padding:10px}.dialog-info-green,.dialog-info-ok{color:var(--ars-color-ok, #388E3C)}.dialog-info-red,.dialog-info-error{color:var(--mat-form-field-error-text-color, #a80710)}.dialog-header{padding-bottom:20px}.dialog-toolbar{padding:0 5px 0 24px;height:48px;min-height:48px}.dialog-close{margin-right:5px;margin-top:0}.dialog-menu{margin-left:10px;margin-top:10px}.dialog-title{padding:0 24px}.section-title{font-size:large;font-weight:600;padding-top:10px;padding-bottom:8px}.center{text-align:center}.fill{min-height:100%!important;max-height:100%!important;height:100%!important}.scroll-auto{overflow:auto;height:100%}.scroll-hidden{overflow:hidden;height:100%}b{font-weight:700}.large{font-size:large!important;line-height:1.2!important}.smaller{font-size:smaller!important;line-height:1.2!important}.small{font-size:small!important;line-height:1.2!important}.small-icon-button{width:1.5rem!important;height:1.5rem!important;padding:0!important;display:inline-flex!important;align-items:center;justify-content:center}.small-icon-button .mat-mdc-button-touch-target{width:1.5rem!important;height:1.5rem!important}.x-small{font-size:x-small!important;line-height:1.2!important}.bold{font-weight:700}.uppercase{text-transform:uppercase!important}.lowercase{text-transform:lowercase!important}.truncated{min-width:0;max-width:100%}@supports (-webkit-line-clamp: 2){.truncated{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}.truncated span,.truncated div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@supports (-webkit-line-clamp: 2){.truncated span,.truncated div{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}.clipped{min-width:0;max-width:100%}.clipped span,.clipped div{white-space:nowrap;overflow:hidden;text-overflow:clip}.accent{color:var(--ars-color-accent, #7894ae)!important}.primary{color:var(--ars-color-primary, #00a293)!important}.secondary{color:var(--ars-color-secondary, #4a635f)!important}.error{color:var(--ars-color-error, #ff5449)!important}.success{color:var(--ars-color-ok, #388E3C)!important}.warning{color:var(--ars-color-warning, #FFC107)!important}.text{color:var(--ars-color-text, #191c1b)!important}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10;background-color:var(--ars-color-overlay, rgba(255, 255, 255, .75))}.drawer-content{padding-top:10px}.drawer .title-container,.drawer .title-container-with-loader,.drawer-small .title-container,.drawer-small .title-container-with-loader{padding-right:5px;padding-bottom:20px;padding-left:0}.drawer .title-container,.drawer-small .title-container{padding-top:20px}.drawer .title-container-with-loader,.drawer-small .title-container-with-loader{padding-top:14px}.drawer .title,.drawer-small .title{font-size:19.2px!important;font-weight:600;padding-left:15px;min-width:150px;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.drawer .accordion-panel,.drawer-small .accordion-panel{background-color:transparent!important}.drawer .accordion-header,.drawer-small .accordion-header{padding-left:10px;padding-right:10px;border-radius:var(--mat-expansion-container-shape)}.drawer .mat-expansion-panel-body,.drawer-small .mat-expansion-panel-body{padding-left:10px!important;padding-right:10px!important;padding-bottom:20px!important}@media screen and (min-width:0px)and (max-width:430px){.drawer,.drawer-small{border-radius:0!important;min-width:100%!important;max-width:100%!important}}@media screen and (min-width:431px){.drawer{min-width:420px!important;max-width:420px!important}.drawer .title{min-width:200px}.drawer .mat-expansion-panel-body{padding-left:15px!important;padding-right:15px!important;padding-bottom:20px!important}.drawer-small{min-width:360px!important;max-width:360px!important}}.drawer-with-loader{padding-top:0!important}.drawer-transparent{background-color:transparent}.fade-in{animation:fadein .5s linear}@keyframes fadein{0%{opacity:0}to{opacity:1}}.bright{filter:brightness(.7)!important}@media(prefers-color-scheme:dark){.dialog-info-green,.dialog-info-ok{color:var(--ars-color-ok, #4CAF50)}.dialog-info-red,.dialog-info-error{color:var(--mat-form-field-error-text-color, #ff5449)}b,.bold{font-weight:600}.bright{filter:brightness(1.5)!important}}.dialog-content{padding:0 24px 24px!important}\n"] }]
530
574
  }], propDecorators: { done: [{ type: i0.Output, args: ["done"] }] } });
531
575
 
576
+ /** Neutral form model: it declares every field the form owns and its empty value. */
577
+ const _EMPTY_ITEM = { value: '' };
532
578
  class PromptOtpDialogComponent {
533
579
  constructor() {
534
580
  this.done = output();
@@ -546,7 +592,7 @@ class PromptOtpDialogComponent {
546
592
  })(), /* @ts-ignore */
547
593
  ...(ngDevMode ? [{ debugName: "dialogData" }] : /* istanbul ignore next */ []));
548
594
  /** Model backing the signal form. `value` holds the 6-digit OTP code. */
549
- this.model = signal({ value: '' }, /* @ts-ignore */
595
+ this.model = signal(this.toForm(), /* @ts-ignore */
550
596
  ...(ngDevMode ? [{ debugName: "model" }] : /* istanbul ignore next */ []));
551
597
  /**
552
598
  * Signal form for the OTP code. The code is always required here; the
@@ -558,6 +604,21 @@ class PromptOtpDialogComponent {
558
604
  notEmpty(p.value);
559
605
  });
560
606
  }
607
+ /**
608
+ * Builds the form model. The dialog has no incoming value, so the model is the
609
+ * neutral one.
610
+ * @returns A fresh form model.
611
+ */
612
+ toForm() {
613
+ return DtoUtils.toForm(_EMPTY_ITEM);
614
+ }
615
+ /**
616
+ * Builds the dialog result from the current form model, dropping the empty code.
617
+ * @returns The result carrying the entered OTP code.
618
+ */
619
+ toPayload() {
620
+ return DtoUtils.toPayload(this.model());
621
+ }
561
622
  /**
562
623
  * Validates the form and emits the OTP result, or shows an error if validation fails.
563
624
  */
@@ -567,7 +628,7 @@ class PromptOtpDialogComponent {
567
628
  this.dialogService.error('Ci sono degli errori da correggere.');
568
629
  return;
569
630
  }
570
- this.done.emit({ value: this.form.value().value() });
631
+ this.done.emit(this.toPayload());
571
632
  }
572
633
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: PromptOtpDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
573
634
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: PromptOtpDialogComponent, isStandalone: true, selector: "ng-component", outputs: { done: "done" }, ngImport: i0, template: "<div mat-dialog-title [innerHTML]=\"dialogData().title | safeHtml\"></div>\r\n<mat-dialog-content class=\"dialog-content\">\r\n @if (dialogData().description) {\r\n <div [innerHtml]=\"dialogData().description | safeHtml\" style=\"padding-bottom: 20px;\"></div>\r\n }\r\n <form [formRoot]=\"form\" novalidate>\r\n <div fxLayout=\"column\" fxLayoutGap=\"32px\" fxFill>\r\n <div fxFlex=\"*\" fxLayout=\"column\" fxFill>\r\n <otp-input [formField]=\"form.value\"></otp-input>\r\n </div>\r\n <br>\r\n </div>\r\n </form>\r\n</mat-dialog-content>\r\n<mat-dialog-actions>\r\n <div fxLayout=\"row\" fxLayoutAlign=\"end\" fxFill>\r\n <button mat-flat-button [disabled]=\"form().invalid()\" (click)=\"ok()\">{{dialogData().okCaption}}</button>\r\n <button mat-stroked-button [mat-dialog-close]=\"true\">{{dialogData().cancelCaption}}</button>\r\n </div>\r\n</mat-dialog-actions>\r\n", styles: [".fill,.wide{min-width:100%!important;max-width:100%!important;width:100%!important}.dialog-info{font-size:x-small;font-weight:700;text-align:right;padding:10px}.dialog-info-green,.dialog-info-ok{color:var(--ars-color-ok, #388E3C)}.dialog-info-red,.dialog-info-error{color:var(--mat-form-field-error-text-color, #a80710)}.dialog-header{padding-bottom:20px}.dialog-toolbar{padding:0 5px 0 24px;height:48px;min-height:48px}.dialog-close{margin-right:5px;margin-top:0}.dialog-menu{margin-left:10px;margin-top:10px}.dialog-title{padding:0 24px}.section-title{font-size:large;font-weight:600;padding-top:10px;padding-bottom:8px}.center{text-align:center}.fill{min-height:100%!important;max-height:100%!important;height:100%!important}.scroll-auto{overflow:auto;height:100%}.scroll-hidden{overflow:hidden;height:100%}b{font-weight:700}.large{font-size:large!important;line-height:1.2!important}.smaller{font-size:smaller!important;line-height:1.2!important}.small{font-size:small!important;line-height:1.2!important}.small-icon-button{width:1.5rem!important;height:1.5rem!important;padding:0!important;display:inline-flex!important;align-items:center;justify-content:center}.small-icon-button .mat-mdc-button-touch-target{width:1.5rem!important;height:1.5rem!important}.x-small{font-size:x-small!important;line-height:1.2!important}.bold{font-weight:700}.uppercase{text-transform:uppercase!important}.lowercase{text-transform:lowercase!important}.truncated{min-width:0;max-width:100%}@supports (-webkit-line-clamp: 2){.truncated{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}.truncated span,.truncated div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@supports (-webkit-line-clamp: 2){.truncated span,.truncated div{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}.clipped{min-width:0;max-width:100%}.clipped span,.clipped div{white-space:nowrap;overflow:hidden;text-overflow:clip}.accent{color:var(--ars-color-accent, #7894ae)!important}.primary{color:var(--ars-color-primary, #00a293)!important}.secondary{color:var(--ars-color-secondary, #4a635f)!important}.error{color:var(--ars-color-error, #ff5449)!important}.success{color:var(--ars-color-ok, #388E3C)!important}.warning{color:var(--ars-color-warning, #FFC107)!important}.text{color:var(--ars-color-text, #191c1b)!important}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10;background-color:var(--ars-color-overlay, rgba(255, 255, 255, .75))}.drawer-content{padding-top:10px}.drawer .title-container,.drawer .title-container-with-loader,.drawer-small .title-container,.drawer-small .title-container-with-loader{padding-right:5px;padding-bottom:20px;padding-left:0}.drawer .title-container,.drawer-small .title-container{padding-top:20px}.drawer .title-container-with-loader,.drawer-small .title-container-with-loader{padding-top:14px}.drawer .title,.drawer-small .title{font-size:19.2px!important;font-weight:600;padding-left:15px;min-width:150px;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.drawer .accordion-panel,.drawer-small .accordion-panel{background-color:transparent!important}.drawer .accordion-header,.drawer-small .accordion-header{padding-left:10px;padding-right:10px;border-radius:var(--mat-expansion-container-shape)}.drawer .mat-expansion-panel-body,.drawer-small .mat-expansion-panel-body{padding-left:10px!important;padding-right:10px!important;padding-bottom:20px!important}@media screen and (min-width:0px)and (max-width:430px){.drawer,.drawer-small{border-radius:0!important;min-width:100%!important;max-width:100%!important}}@media screen and (min-width:431px){.drawer{min-width:420px!important;max-width:420px!important}.drawer .title{min-width:200px}.drawer .mat-expansion-panel-body{padding-left:15px!important;padding-right:15px!important;padding-bottom:20px!important}.drawer-small{min-width:360px!important;max-width:360px!important}}.drawer-with-loader{padding-top:0!important}.drawer-transparent{background-color:transparent}.fade-in{animation:fadein .5s linear}@keyframes fadein{0%{opacity:0}to{opacity:1}}.bright{filter:brightness(.7)!important}@media(prefers-color-scheme:dark){.dialog-info-green,.dialog-info-ok{color:var(--ars-color-ok, #4CAF50)}.dialog-info-red,.dialog-info-error{color:var(--mat-form-field-error-text-color, #ff5449)}b,.bold{font-weight:600}.bright{filter:brightness(1.5)!important}}.dialog-content{padding:0 24px 24px!important}\n"], dependencies: [{ kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: FormRoot, selector: "form[formRoot]", inputs: ["formRoot"] }, { kind: "ngmodule", type: FlexLayoutModule }, { kind: "directive", type: i1$2.FxLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg] ", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i1$2.FxFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg] ", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i1$2.FxLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg] ", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i1$2.FxLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg] ", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i1$2.FxFlexFillDirective, selector: " [fxFlexFill], [fxFill], [fxFlexFill.xs], [fxFlexFill.sm], [fxFlexFill.md], [fxFlexFill.lg], [fxFlexFill.xl], [fxFlexFill.lt-sm], [fxFlexFill.lt-md], [fxFlexFill.lt-lg], [fxFlexFill.lt-xl], [fxFlexFill.gt-xs], [fxFlexFill.gt-sm], [fxFlexFill.gt-md], [fxFlexFill.gt-lg] ", inputs: ["fxFlexFill", "fxFill", "fxFlexFill.xs", "fxFlexFill.sm", "fxFlexFill.md", "fxFlexFill.lg", "fxFlexFill.xl", "fxFlexFill.lt-sm", "fxFlexFill.lt-md", "fxFlexFill.lt-lg", "fxFlexFill.lt-xl", "fxFlexFill.gt-xs", "fxFlexFill.gt-sm", "fxFlexFill.gt-md", "fxFlexFill.gt-lg"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "component", type: OtpInputComponent, selector: "otp-input" }, { kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }