@arsedizioni/ars-utils 22.5.35 → 22.5.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/arsedizioni-ars-utils-clipper.ui.mjs +174 -150
- package/fesm2022/arsedizioni-ars-utils-clipper.ui.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-core.date.mjs +92 -10
- package/fesm2022/arsedizioni-ars-utils-core.date.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-core.mjs +47 -11
- package/fesm2022/arsedizioni-ars-utils-core.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-core.validators.mjs +0 -6
- package/fesm2022/arsedizioni-ars-utils-core.validators.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.auth.mjs +91 -30
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.auth.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.prompt.mjs +97 -42
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.prompt.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.select.mjs +24 -10
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.select.mjs.map +1 -1
- package/package.json +1 -1
- package/types/arsedizioni-ars-utils-clipper.ui.d.ts +79 -23
- package/types/arsedizioni-ars-utils-core.d.ts +51 -15
- package/types/arsedizioni-ars-utils-core.date.d.ts +37 -4
- package/types/arsedizioni-ars-utils-ui.dialogs.auth.d.ts +116 -6
- package/types/arsedizioni-ars-utils-ui.dialogs.prompt.d.ts +93 -11
- package/types/arsedizioni-ars-utils-ui.dialogs.select.d.ts +29 -1
|
@@ -188,21 +188,62 @@ interface LoginResult<T> extends ApiResult<boolean> {
|
|
|
188
188
|
* The two shapes differ in one systematic way. A DTO leaves out what it does not have: a place
|
|
189
189
|
* with no phone number simply has no `phone`. A form model cannot afford that — signal forms only
|
|
190
190
|
* build a child field for a key whose value is defined, and the string validators need a `string`
|
|
191
|
-
* rather than `string | undefined` — so every editable field is present, holding its empty value
|
|
192
|
-
* (`''` for text and for the boxes of a datepicker, `false` for a checkbox, `0` for a counter).
|
|
191
|
+
* rather than `string | undefined` — so every editable field is present, holding its empty value.
|
|
193
192
|
*
|
|
194
193
|
* Doing that conversion by hand means a `?? ''` per field on the way in and a `|| undefined` per
|
|
195
|
-
* field on the way out, twice per form, kept in sync forever. {@link DtoUtils.
|
|
196
|
-
* {@link DtoUtils.
|
|
194
|
+
* field on the way out, twice per form, kept in sync forever. {@link DtoUtils.toForm} and
|
|
195
|
+
* {@link DtoUtils.toPayload} do it once, driven by a single "empty model" constant that also serves as
|
|
197
196
|
* the initial value of the form and as what a "clear" button restores.
|
|
197
|
+
*
|
|
198
|
+
* ## The convention
|
|
199
|
+
*
|
|
200
|
+
* 1. **A component that edits a DTO owns a form model of its own.** `ProfileEditComponent`
|
|
201
|
+
* receiving a `ProfileModel` declares a `ProfileForm`, derived from it — never binds the DTO
|
|
202
|
+
* to the form directly. The DTO stays free to say "absent"; the form is not.
|
|
203
|
+
* 2. **What is optional in the DTO becomes `| null` in the form model.** `phone?: string` becomes
|
|
204
|
+
* `phone: string` holding `''`, `level?: Level` becomes `level: Level | null`. The optionality
|
|
205
|
+
* is not lost, it moves into the empty value, and {@link Dto} gives it back on the way out.
|
|
206
|
+
* 3. **A date field is `Date | null`.** Always a `Date`, never a `Date | string`; `null` is its
|
|
207
|
+
* empty value, because that is what Material's date accessors — the single datepicker and both
|
|
208
|
+
* boxes of a `mat-date-range-picker` — write when an input is cleared.
|
|
209
|
+
* 4. **The empty model is named `_EMPTY_ITEM`.** One constant per form, next to its interface.
|
|
210
|
+
* 5. **The two conversions are called `toForm()` and `toPayload()`, and are written one after the
|
|
211
|
+
* other.** When a component builds more than one payload, the others are `toPayloadXxx()` and
|
|
212
|
+
* the main one keeps the bare name.
|
|
213
|
+
* 6. **A payload always goes through `toPayload()` before it reaches the API.** When the payload
|
|
214
|
+
* needs adjustments the generic conversion cannot make — a bitmask to rebuild, dates to
|
|
215
|
+
* normalize, a number to coerce, fields the model does not own — the component declares its own
|
|
216
|
+
* `toPayload()` and calls {@link DtoUtils.toPayload} inside it for the field-by-field part.
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* interface ProfileForm {
|
|
221
|
+
* name: string; // name?: string in ProfileModel
|
|
222
|
+
* level: Level | null; // level?: Level
|
|
223
|
+
* from: Date | null; // fromDate?: Date, bound to a mat-date-range-picker
|
|
224
|
+
* to: Date | null; // toDate?: Date
|
|
225
|
+
* active: boolean;
|
|
226
|
+
* }
|
|
227
|
+
*
|
|
228
|
+
* const _EMPTY_ITEM: ProfileForm = { name: '', level: null, from: null, to: null, active: false };
|
|
229
|
+
*
|
|
230
|
+
* private toForm(dto?: ProfileModel): ProfileForm {
|
|
231
|
+
* return DtoUtils.toForm(_EMPTY_ITEM, dto as Partial<ProfileForm>);
|
|
232
|
+
* }
|
|
233
|
+
*
|
|
234
|
+
* private toPayload(): ProfileModel {
|
|
235
|
+
* const { from, to, ...rest } = this.model();
|
|
236
|
+
* return { ...DtoUtils.toPayload(rest), fromDate: from ?? undefined, toDate: to ?? undefined };
|
|
237
|
+
* }
|
|
238
|
+
* ```
|
|
198
239
|
*/
|
|
199
240
|
/**
|
|
200
241
|
* The DTO shape of a form model: the same fields, without the values that stand for "empty".
|
|
201
242
|
*
|
|
202
|
-
* It mirrors what {@link DtoUtils.
|
|
203
|
-
* only works when the empty value is
|
|
204
|
-
*
|
|
205
|
-
*
|
|
243
|
+
* It mirrors what {@link DtoUtils.toPayload} does at runtime, so the payload type says the truth. It
|
|
244
|
+
* only works when the empty value is `''` or `null` — `Date | null` narrows to `Date`, and
|
|
245
|
+
* `string` (which is what `''` widens to) narrows to `string`. That is the reason a date field is
|
|
246
|
+
* `Date | null` and never `Date | string`: the latter could not be narrowed at all.
|
|
206
247
|
*/
|
|
207
248
|
type Dto<TModel> = {
|
|
208
249
|
[K in keyof TModel]: Exclude<TModel[K], '' | null>;
|
|
@@ -224,11 +265,8 @@ declare class DtoUtils {
|
|
|
224
265
|
* one takes when the DTO does not carry it.
|
|
225
266
|
* @param dto - The object coming from the API, or `undefined` when creating a new record.
|
|
226
267
|
* @returns A new model, never the same reference as `empty` nor as `dto`.
|
|
227
|
-
* @example
|
|
228
|
-
* const EMPTY_PLACE: PlaceForm = { name: '', city: '', phone: '', disabled: false };
|
|
229
|
-
* this.form().reset(DtoUtils.fromModel(EMPTY_PLACE, r.value));
|
|
230
268
|
*/
|
|
231
|
-
static
|
|
269
|
+
static toForm<TModel extends object>(empty: TModel, dto?: Partial<TModel> | null): TModel;
|
|
232
270
|
/**
|
|
233
271
|
* Builds the payload for the API from the current form model.
|
|
234
272
|
*
|
|
@@ -248,10 +286,8 @@ declare class DtoUtils {
|
|
|
248
286
|
*
|
|
249
287
|
* @param model - The current form model.
|
|
250
288
|
* @returns A shallow copy without the empty fields.
|
|
251
|
-
* @example
|
|
252
|
-
* this.scmService.places.savePlace(DtoUtils.toModel(this.model()));
|
|
253
289
|
*/
|
|
254
|
-
static
|
|
290
|
+
static toPayload<TModel extends object>(model: TModel): Dto<TModel>;
|
|
255
291
|
}
|
|
256
292
|
|
|
257
293
|
declare const UtilsMessages: {
|
|
@@ -191,7 +191,7 @@ declare class DateFnsAdapter extends DateAdapter<Date, Locale> {
|
|
|
191
191
|
static ɵprov: i0.ɵɵInjectableDeclaration<DateFnsAdapter>;
|
|
192
192
|
}
|
|
193
193
|
/**
|
|
194
|
-
* Standalone providers for the
|
|
194
|
+
* Standalone providers for the SCM date-fns adapter.
|
|
195
195
|
*
|
|
196
196
|
* Configures Angular Material to use {@link DateFnsAdapter} (Europe/Rome timezone)
|
|
197
197
|
* and the matching {@link MAT_DATE_FNS_FORMATS}. Also supports `mat-timepicker` since
|
|
@@ -199,10 +199,10 @@ declare class DateFnsAdapter extends DateAdapter<Date, Locale> {
|
|
|
199
199
|
*
|
|
200
200
|
* @example
|
|
201
201
|
* bootstrapApplication(AppComponent, {
|
|
202
|
-
* providers: [
|
|
202
|
+
* providers: [provideScmDateFns()]
|
|
203
203
|
* });
|
|
204
204
|
*/
|
|
205
|
-
declare function
|
|
205
|
+
declare function provideScmDateFns(): EnvironmentProviders;
|
|
206
206
|
|
|
207
207
|
/** Default application timezone: all dates are serialised as Europe/Rome wall-clock values. */
|
|
208
208
|
declare const DEFAULT_TIME_ZONE = "Europe/Rome";
|
|
@@ -301,4 +301,37 @@ declare function toLocalDateOnlyString(value?: Date | null, timeZone?: string):
|
|
|
301
301
|
*/
|
|
302
302
|
declare function toLocalDateTimeString(value?: Date | null, timeZone?: string): string | undefined;
|
|
303
303
|
|
|
304
|
-
|
|
304
|
+
/**
|
|
305
|
+
* Works around a MatDatepicker/Signal Forms interop bug.
|
|
306
|
+
*
|
|
307
|
+
* `MatDatepickerInputBase._onInput()` only notifies its registered validator-change
|
|
308
|
+
* callback from the branch it does not take when the parsed date is null. Signal
|
|
309
|
+
* Forms recomputes CVA parse errors from that callback or from a model value
|
|
310
|
+
* change, and neither happens while the user erases an unparseable date one
|
|
311
|
+
* character at a time (the model is already `null`, so the signal write is a
|
|
312
|
+
* no-op). The stale `matDatepickerParse` error therefore survives on an empty
|
|
313
|
+
* field. Notifying on every keystroke re-runs the datepicker validators.
|
|
314
|
+
*/
|
|
315
|
+
declare class MatDatepickerParseErrorFixDirective {
|
|
316
|
+
private readonly singleDate;
|
|
317
|
+
private readonly startDate;
|
|
318
|
+
private readonly endDate;
|
|
319
|
+
/**
|
|
320
|
+
* Re-runs the datepicker validators after Material has updated its internal
|
|
321
|
+
* parse flag.
|
|
322
|
+
*
|
|
323
|
+
* @returns Nothing.
|
|
324
|
+
*/
|
|
325
|
+
protected onInput(): void;
|
|
326
|
+
/**
|
|
327
|
+
* Notifies the validator-change callback of this input and, for range parts,
|
|
328
|
+
* of the sibling input as well.
|
|
329
|
+
*
|
|
330
|
+
* @returns Nothing.
|
|
331
|
+
*/
|
|
332
|
+
private revalidate;
|
|
333
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MatDatepickerParseErrorFixDirective, never>;
|
|
334
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<MatDatepickerParseErrorFixDirective, "input[matDatepicker], input[matStartDate], input[matEndDate]", never, {}, {}, never, never, true, never>;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export { ARS_TIME_ZONE, ArsLocalDateInterceptor, DEFAULT_TIME_ZONE, DateFnsAdapter, MAT_DATE_FNS_FORMATS, MatDatepickerParseErrorFixDirective, arsLocalDateInterceptor, provideArsLocalDates, provideScmDateFns, toLocalDateOnlyString, toLocalDateTimeString };
|
|
@@ -124,6 +124,23 @@ interface CredentialsDialogData {
|
|
|
124
124
|
mode?: 'email' | 'user' | 'otp';
|
|
125
125
|
appearance?: MatFormFieldAppearance;
|
|
126
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Form model of the credentials dialog.
|
|
129
|
+
*
|
|
130
|
+
* {@link CredentialsDialogResult} is the DTO: every field of it is optional, so it
|
|
131
|
+
* cannot back a signal form directly. Here every field is present and holds its empty
|
|
132
|
+
* value, and {@link DtoUtils.toPayload} turns the model back into the DTO on the way out.
|
|
133
|
+
*/
|
|
134
|
+
interface CredentialsForm {
|
|
135
|
+
/** The account name or email; `''` when the input is empty. */
|
|
136
|
+
user: string;
|
|
137
|
+
/** The password; `''` when the input is empty or the dialog is in `otp` mode. */
|
|
138
|
+
password: string;
|
|
139
|
+
/** Whether the session should be remembered. */
|
|
140
|
+
rememberMe: boolean;
|
|
141
|
+
/** The 6-digit OTP code; `''` outside `otp` mode. */
|
|
142
|
+
code: string;
|
|
143
|
+
}
|
|
127
144
|
declare class CredentialsDialogComponent {
|
|
128
145
|
/** Error text of a field: the message declared in the schema, or the shared fallback. */
|
|
129
146
|
protected readonly getErrorMessage: typeof SignalsUtils.getFieldErrorMessage;
|
|
@@ -135,13 +152,26 @@ declare class CredentialsDialogComponent {
|
|
|
135
152
|
protected readonly dialogData: _angular_core.WritableSignal<CredentialsDialogData>;
|
|
136
153
|
/** Model backing the signal form, pre-filled with the user name from dialog data when provided. */
|
|
137
154
|
private readonly model;
|
|
155
|
+
/**
|
|
156
|
+
* Builds the form model from the dialog data, which may carry the account name to
|
|
157
|
+
* pre-fill.
|
|
158
|
+
* @returns A fresh form model.
|
|
159
|
+
*/
|
|
160
|
+
private toForm;
|
|
161
|
+
/**
|
|
162
|
+
* Builds the dialog result from the current form model. The fields the active mode
|
|
163
|
+
* does not use are left empty by the template and dropped here, so they travel as
|
|
164
|
+
* absent instead of as empty strings.
|
|
165
|
+
* @returns The credentials to emit through `done` or `recoveringPassword`.
|
|
166
|
+
*/
|
|
167
|
+
private toPayload;
|
|
138
168
|
/**
|
|
139
169
|
* Signal form for the credentials. Validators follow the active mode: the user
|
|
140
170
|
* field is a required email in `email` mode and plain required in `user` mode,
|
|
141
171
|
* the password is required outside `otp` mode, and the OTP code is a required
|
|
142
172
|
* complete 6-digit code in `otp` mode.
|
|
143
173
|
*/
|
|
144
|
-
protected readonly form: _angular_forms_signals.FieldTree<
|
|
174
|
+
protected readonly form: _angular_forms_signals.FieldTree<CredentialsForm, string | number, "writable">;
|
|
145
175
|
/** Whether the password field is currently shown as plain text. */
|
|
146
176
|
protected readonly showPassword: _angular_core.WritableSignal<boolean>;
|
|
147
177
|
/**
|
|
@@ -171,6 +201,29 @@ interface ResetPasswordDialogData {
|
|
|
171
201
|
userEmail?: string;
|
|
172
202
|
appearance?: MatFormFieldAppearance;
|
|
173
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Form model of the password-reset dialog.
|
|
206
|
+
*
|
|
207
|
+
* {@link ResetPasswordDialogResult} is the DTO: every field of it is optional, so it
|
|
208
|
+
* cannot back a signal form directly. Here every field is present — `userId` included,
|
|
209
|
+
* which is carried through untouched — and an absent value becomes `null` for the
|
|
210
|
+
* numeric id and `''` for the text fields, the empty states signal forms and the string
|
|
211
|
+
* validators work with.
|
|
212
|
+
*/
|
|
213
|
+
interface ResetPasswordForm {
|
|
214
|
+
/** Id of the account whose password is being reset; `null` in the modes that identify it by email. */
|
|
215
|
+
userId: number | null;
|
|
216
|
+
/** Email of the account; `''` outside the modes that ask for it. */
|
|
217
|
+
userEmail: string;
|
|
218
|
+
/** The current password, asked for in `old` mode; `''` elsewhere. */
|
|
219
|
+
oldPassword: string;
|
|
220
|
+
/** The new password. */
|
|
221
|
+
password: string;
|
|
222
|
+
/** Confirmation of the new password; `''` in `admin` mode, where it is not asked for. */
|
|
223
|
+
password2: string;
|
|
224
|
+
/** The 6-digit OTP code, asked for in `otp` mode; `''` elsewhere. */
|
|
225
|
+
code: string;
|
|
226
|
+
}
|
|
174
227
|
declare class ResetPasswordDialogComponent {
|
|
175
228
|
/** Error text of a field: the message declared in the schema, or the shared fallback. */
|
|
176
229
|
protected readonly getErrorMessage: typeof SignalsUtils.getFieldErrorMessage;
|
|
@@ -182,6 +235,19 @@ declare class ResetPasswordDialogComponent {
|
|
|
182
235
|
protected readonly dialogData: _angular_core.WritableSignal<ResetPasswordDialogData>;
|
|
183
236
|
/** Model backing the signal form. */
|
|
184
237
|
private readonly model;
|
|
238
|
+
/**
|
|
239
|
+
* Builds the form model from the dialog data, which identifies the account either by
|
|
240
|
+
* id or by email depending on the mode.
|
|
241
|
+
* @returns A fresh form model.
|
|
242
|
+
*/
|
|
243
|
+
private toForm;
|
|
244
|
+
/**
|
|
245
|
+
* Builds the dialog result from the current form model. The fields the active mode
|
|
246
|
+
* does not use are left empty by the template and dropped here, so they travel as
|
|
247
|
+
* absent instead of as empty strings.
|
|
248
|
+
* @returns The reset data to emit through `done`.
|
|
249
|
+
*/
|
|
250
|
+
private toPayload;
|
|
185
251
|
/**
|
|
186
252
|
* Signal form for the password reset. Validators follow the active mode:
|
|
187
253
|
* the email is required in `forgot` mode, the old password in `old` mode,
|
|
@@ -189,7 +255,7 @@ declare class ResetPasswordDialogComponent {
|
|
|
189
255
|
* required, at least 10 characters and strong enough, and its confirmation
|
|
190
256
|
* (required outside `admin` mode) must match it.
|
|
191
257
|
*/
|
|
192
|
-
protected readonly form: _angular_forms_signals.FieldTree<
|
|
258
|
+
protected readonly form: _angular_forms_signals.FieldTree<ResetPasswordForm, string | number, "writable">;
|
|
193
259
|
/** Whether the old-password field is currently shown as plain text. */
|
|
194
260
|
protected readonly showOldPassword: _angular_core.WritableSignal<boolean>;
|
|
195
261
|
/** Whether the new-password field is currently shown as plain text. */
|
|
@@ -212,6 +278,19 @@ declare class ResetPasswordDialogComponent {
|
|
|
212
278
|
interface RecoverPasswordDialogData {
|
|
213
279
|
appearance?: MatFormFieldAppearance;
|
|
214
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* Form model of the password-recovery dialog.
|
|
283
|
+
*
|
|
284
|
+
* {@link RecoverPasswordDialogResult} is the DTO: every field of it is optional, so it
|
|
285
|
+
* cannot back a signal form directly. Here every field is present and holds its empty
|
|
286
|
+
* value, and {@link DtoUtils.toPayload} turns the model back into the DTO on the way out.
|
|
287
|
+
*/
|
|
288
|
+
interface RecoverPasswordForm {
|
|
289
|
+
/** The email the recovery link is sent to; `''` when the input is empty. */
|
|
290
|
+
email: string;
|
|
291
|
+
/** Whether the recaptcha challenge has been solved. */
|
|
292
|
+
recaptcha: boolean;
|
|
293
|
+
}
|
|
215
294
|
declare class RecoverPasswordDialogComponent {
|
|
216
295
|
/** Error text of a field: the message declared in the schema, or the shared fallback. */
|
|
217
296
|
protected readonly getErrorMessage: typeof SignalsUtils.getFieldErrorMessage;
|
|
@@ -221,10 +300,22 @@ declare class RecoverPasswordDialogComponent {
|
|
|
221
300
|
protected readonly dialogData: _angular_core.WritableSignal<RecoverPasswordDialogData>;
|
|
222
301
|
/** Model backing the signal form. */
|
|
223
302
|
private readonly model;
|
|
303
|
+
/**
|
|
304
|
+
* Builds the form model. The dialog is always opened empty, so the model is the
|
|
305
|
+
* neutral one.
|
|
306
|
+
* @returns A fresh form model.
|
|
307
|
+
*/
|
|
308
|
+
private toForm;
|
|
309
|
+
/**
|
|
310
|
+
* Builds the dialog result from the current form model, dropping the email when it
|
|
311
|
+
* was left empty.
|
|
312
|
+
* @returns The result to emit through `done`.
|
|
313
|
+
*/
|
|
314
|
+
private toPayload;
|
|
224
315
|
/**
|
|
225
316
|
* Signal form for the recovery request: the email is required and must be valid.
|
|
226
317
|
*/
|
|
227
|
-
protected readonly form: _angular_forms_signals.FieldTree<
|
|
318
|
+
protected readonly form: _angular_forms_signals.FieldTree<RecoverPasswordForm, string | number, "writable">;
|
|
228
319
|
/**
|
|
229
320
|
* Emits the current form result to trigger the password-recovery flow.
|
|
230
321
|
*/
|
|
@@ -233,20 +324,39 @@ declare class RecoverPasswordDialogComponent {
|
|
|
233
324
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<RecoverPasswordDialogComponent, "ng-component", never, {}, { "done": "done"; }, never, never, true, never>;
|
|
234
325
|
}
|
|
235
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Form model of the OTP dialog.
|
|
329
|
+
*
|
|
330
|
+
* {@link PromptOtpDialogResult} is the DTO: it leaves the code out when there is none.
|
|
331
|
+
* The form cannot, so the field is always present and holds `''` when empty.
|
|
332
|
+
*/
|
|
333
|
+
interface PromptOtpForm {
|
|
334
|
+
/** The 6-digit OTP code; `''` while the user has not completed it. */
|
|
335
|
+
value: string;
|
|
336
|
+
}
|
|
236
337
|
declare class PromptOtpDialogComponent {
|
|
237
338
|
readonly done: _angular_core.OutputEmitterRef<PromptOtpDialogResult>;
|
|
238
339
|
private readonly dialogService;
|
|
239
340
|
protected readonly dialogData: _angular_core.WritableSignal<PromptDialogData>;
|
|
240
341
|
/** Model backing the signal form. `value` holds the 6-digit OTP code. */
|
|
241
342
|
private readonly model;
|
|
343
|
+
/**
|
|
344
|
+
* Builds the form model. The dialog has no incoming value, so the model is the
|
|
345
|
+
* neutral one.
|
|
346
|
+
* @returns A fresh form model.
|
|
347
|
+
*/
|
|
348
|
+
private toForm;
|
|
349
|
+
/**
|
|
350
|
+
* Builds the dialog result from the current form model, dropping the empty code.
|
|
351
|
+
* @returns The result carrying the entered OTP code.
|
|
352
|
+
*/
|
|
353
|
+
private toPayload;
|
|
242
354
|
/**
|
|
243
355
|
* Signal form for the OTP code. The code is always required here; the
|
|
244
356
|
* "complete 6 digits" rule comes from the OtpInputComponent validator,
|
|
245
357
|
* honoured through the ControlValueAccessor interop.
|
|
246
358
|
*/
|
|
247
|
-
protected readonly form: _angular_forms_signals.FieldTree<
|
|
248
|
-
value: string;
|
|
249
|
-
}, string | number, "writable">;
|
|
359
|
+
protected readonly form: _angular_forms_signals.FieldTree<PromptOtpForm, string | number, "writable">;
|
|
250
360
|
/**
|
|
251
361
|
* Validates the form and emits the OTP result, or shows an error if validation fails.
|
|
252
362
|
*/
|
|
@@ -3,6 +3,17 @@ import * as _angular_core from '@angular/core';
|
|
|
3
3
|
import { PromptDialogResult, PromptDialogData, PromptDateDialogResult, PromptTimeDialogData } from '@arsedizioni/ars-utils/ui';
|
|
4
4
|
import { SignalsUtils } from '@arsedizioni/ars-utils/core.validators';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Form model of the generic prompt.
|
|
8
|
+
*
|
|
9
|
+
* The DTO side is {@link PromptDialogData.initialValue} on the way in and
|
|
10
|
+
* {@link PromptDialogResult.value} on the way out; both may be absent, while the form
|
|
11
|
+
* always owns the field. `value` stays `any` because its shape follows the prompt type.
|
|
12
|
+
*/
|
|
13
|
+
interface PromptForm {
|
|
14
|
+
/** The prompted value: `''` for textual types, `null` for the number and list types. */
|
|
15
|
+
value: any;
|
|
16
|
+
}
|
|
6
17
|
declare class PromptDialogComponent {
|
|
7
18
|
/** Error text of a field: the message declared in the schema, or the shared fallback. */
|
|
8
19
|
protected readonly getErrorMessage: typeof SignalsUtils.getFieldErrorMessage;
|
|
@@ -11,13 +22,31 @@ declare class PromptDialogComponent {
|
|
|
11
22
|
protected readonly dialogData: _angular_core.WritableSignal<PromptDialogData>;
|
|
12
23
|
/** Model backing the signal form. `value` type depends on the prompt type. */
|
|
13
24
|
private readonly model;
|
|
25
|
+
/**
|
|
26
|
+
* Builds the form model from the value carried by the dialog data.
|
|
27
|
+
*
|
|
28
|
+
* Ad-hoc because the empty value follows the prompt type: native inputs bound via
|
|
29
|
+
* `[formField]` report an empty number or an unselected option as `null`, while a
|
|
30
|
+
* text, date or textarea input reports `''`. The list type never takes an initial
|
|
31
|
+
* value: its options are matched by the template.
|
|
32
|
+
* @returns A fresh form model.
|
|
33
|
+
*/
|
|
34
|
+
private toForm;
|
|
35
|
+
/**
|
|
36
|
+
* Builds the dialog result from the current form model.
|
|
37
|
+
*
|
|
38
|
+
* Ad-hoc because the result also carries the prompt type and the caller's `options`,
|
|
39
|
+
* which are not part of the form model; the value itself goes through
|
|
40
|
+
* {@link DtoUtils.toPayload}, so an input left empty travels as absent instead of as
|
|
41
|
+
* an empty string or a `null`.
|
|
42
|
+
* @returns The result to emit through `done`.
|
|
43
|
+
*/
|
|
44
|
+
private toPayload;
|
|
14
45
|
/**
|
|
15
46
|
* Signal form for the prompt value. Validators mirror the previous template-driven
|
|
16
47
|
* form: `required` follows the dialog data, `min`/`max` apply to the Number type.
|
|
17
48
|
*/
|
|
18
|
-
protected readonly form: _angular_forms_signals.FieldTree<
|
|
19
|
-
value: any;
|
|
20
|
-
}, string | number, "writable">;
|
|
49
|
+
protected readonly form: _angular_forms_signals.FieldTree<PromptForm, string | number, "writable">;
|
|
21
50
|
/**
|
|
22
51
|
* Validates the form and emits the result, or shows an error if validation fails.
|
|
23
52
|
*/
|
|
@@ -26,6 +55,23 @@ declare class PromptDialogComponent {
|
|
|
26
55
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<PromptDialogComponent, "ng-component", never, {}, { "done": "done"; }, never, never, true, never>;
|
|
27
56
|
}
|
|
28
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Form model of the date prompt.
|
|
60
|
+
*
|
|
61
|
+
* The DTO side is {@link PromptDialogData.initialValue} on the way in and
|
|
62
|
+
* {@link PromptDateDialogResult.value} on the way out; both leave the value out when
|
|
63
|
+
* there is none, while the form always owns every field. Dates are always `Date | null`
|
|
64
|
+
* — never a `Date | string` — because `null` is what Material's date accessors write
|
|
65
|
+
* when a datepicker input is cleared.
|
|
66
|
+
*/
|
|
67
|
+
interface PromptDateForm {
|
|
68
|
+
/** Value of the single-date type; `null` when the input is empty. */
|
|
69
|
+
date: Date | null;
|
|
70
|
+
/** Start of the range of the date-interval type; `null` when the input is empty. */
|
|
71
|
+
from: Date | null;
|
|
72
|
+
/** End of the range of the date-interval type; `null` when the input is empty. */
|
|
73
|
+
to: Date | null;
|
|
74
|
+
}
|
|
29
75
|
declare class PromptDateDialogComponent {
|
|
30
76
|
/** Error text of a field: the message declared in the schema, or the shared fallback. */
|
|
31
77
|
protected readonly getErrorMessage: typeof SignalsUtils.getFieldErrorMessage;
|
|
@@ -53,16 +99,29 @@ declare class PromptDateDialogComponent {
|
|
|
53
99
|
* input as `null` anyway; values are normalized to `undefined` on emit.
|
|
54
100
|
*/
|
|
55
101
|
private readonly model;
|
|
102
|
+
/**
|
|
103
|
+
* Builds the form model from the value carried by the dialog data: a `Date` for the
|
|
104
|
+
* single-date type, a {@link DateInterval} for the date-interval one.
|
|
105
|
+
* @returns A fresh form model, empty when the dialog was opened without a value.
|
|
106
|
+
*/
|
|
107
|
+
private toForm;
|
|
108
|
+
/**
|
|
109
|
+
* Builds the dialog result from the current form model.
|
|
110
|
+
*
|
|
111
|
+
* Ad-hoc because the two prompt types produce different values out of the same model
|
|
112
|
+
* — a `Date` or a {@link DateInterval} — and because the result also carries the type
|
|
113
|
+
* and the caller's `options`, which are not part of the form model. The dates
|
|
114
|
+
* themselves go through {@link DtoUtils.toPayload}, so a bound left empty travels as
|
|
115
|
+
* absent instead of as `null`.
|
|
116
|
+
* @returns The result to emit through `done`.
|
|
117
|
+
*/
|
|
118
|
+
private toPayload;
|
|
56
119
|
/**
|
|
57
120
|
* Signal form for the date value(s). `required` follows the dialog data and only
|
|
58
121
|
* applies to the fields of the active prompt type; the datepicker's own parse
|
|
59
122
|
* validators are picked up through the ControlValueAccessor interop.
|
|
60
123
|
*/
|
|
61
|
-
protected readonly form: _angular_forms_signals.FieldTree<
|
|
62
|
-
date: Date | null;
|
|
63
|
-
from: Date | null;
|
|
64
|
-
to: Date | null;
|
|
65
|
-
}, string | number, "writable">;
|
|
124
|
+
protected readonly form: _angular_forms_signals.FieldTree<PromptDateForm, string | number, "writable">;
|
|
66
125
|
/** Debounced stream of keyup events on the interval inputs (shorthand typing support). */
|
|
67
126
|
private readonly intervalKeyup;
|
|
68
127
|
constructor();
|
|
@@ -90,6 +149,17 @@ declare class PromptDateDialogComponent {
|
|
|
90
149
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<PromptDateDialogComponent, "ng-component", never, {}, { "done": "done"; }, never, never, true, never>;
|
|
91
150
|
}
|
|
92
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Form model of the time prompt.
|
|
154
|
+
*
|
|
155
|
+
* The DTO side is {@link PromptTimeDialogData.initialValue} on the way in and
|
|
156
|
+
* {@link PromptDialogResult.value} on the way out; both leave the value out when there
|
|
157
|
+
* is none, while the form always owns the field and holds `''` when empty.
|
|
158
|
+
*/
|
|
159
|
+
interface PromptTimeForm {
|
|
160
|
+
/** The `"HH:MM"` time value; `''` when the input is empty. */
|
|
161
|
+
value: string;
|
|
162
|
+
}
|
|
93
163
|
declare class PromptTimeDialogComponent {
|
|
94
164
|
/** Error text of a field: the message declared in the schema, or the shared fallback. */
|
|
95
165
|
protected readonly getErrorMessage: typeof SignalsUtils.getFieldErrorMessage;
|
|
@@ -98,13 +168,25 @@ declare class PromptTimeDialogComponent {
|
|
|
98
168
|
protected readonly dialogData: _angular_core.WritableSignal<PromptTimeDialogData>;
|
|
99
169
|
/** Model backing the signal form. The value is a `"HH:MM"` time string. */
|
|
100
170
|
private readonly model;
|
|
171
|
+
/**
|
|
172
|
+
* Builds the form model from the value carried by the dialog data.
|
|
173
|
+
* @returns A fresh form model, empty when the dialog was opened without a value.
|
|
174
|
+
*/
|
|
175
|
+
private toForm;
|
|
176
|
+
/**
|
|
177
|
+
* Builds the dialog result from the current form model.
|
|
178
|
+
*
|
|
179
|
+
* Ad-hoc because the result also carries the caller's `options`, which are not part
|
|
180
|
+
* of the form model; the time itself goes through {@link DtoUtils.toPayload}, so an
|
|
181
|
+
* empty input travels as absent instead of as an empty string.
|
|
182
|
+
* @returns The result to emit through `done`.
|
|
183
|
+
*/
|
|
184
|
+
private toPayload;
|
|
101
185
|
/**
|
|
102
186
|
* Signal form for the time value: `required` follows the dialog data and the
|
|
103
187
|
* time validator enforces format and the optional allowed slots.
|
|
104
188
|
*/
|
|
105
|
-
protected readonly form: _angular_forms_signals.FieldTree<
|
|
106
|
-
value: string;
|
|
107
|
-
}, string | number, "writable">;
|
|
189
|
+
protected readonly form: _angular_forms_signals.FieldTree<PromptTimeForm, string | number, "writable">;
|
|
108
190
|
/**
|
|
109
191
|
* Validates the form and emits the result, or shows an error if validation fails.
|
|
110
192
|
*/
|
|
@@ -273,6 +273,21 @@ declare class SelectTreeDialogComponent {
|
|
|
273
273
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SelectTreeDialogComponent, "ng-component", never, {}, { "done": "done"; "append": "append"; }, never, never, true, never>;
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Form model of the send-to dialog.
|
|
278
|
+
*
|
|
279
|
+
* {@link SendToDialogResult} is the DTO: every field of it is optional, so it cannot
|
|
280
|
+
* back a signal form directly. Here every editable field is present and holds `''` when
|
|
281
|
+
* empty; `options` is not editable and is only added back by {@link toPayload}.
|
|
282
|
+
*/
|
|
283
|
+
interface SendToForm {
|
|
284
|
+
/** Semicolon-separated recipient list; `''` when the input is empty. */
|
|
285
|
+
recipients: string;
|
|
286
|
+
/** Subject of the message; `''` when the input is empty. */
|
|
287
|
+
subject: string;
|
|
288
|
+
/** Body of the message; `''` when the input is empty. */
|
|
289
|
+
text: string;
|
|
290
|
+
}
|
|
276
291
|
interface SendToDialogData {
|
|
277
292
|
count: number;
|
|
278
293
|
canPopulate?: boolean;
|
|
@@ -294,11 +309,24 @@ declare class SendToDialogComponent implements ISendToDialog {
|
|
|
294
309
|
protected readonly dialogData: _angular_core.WritableSignal<SendToDialogData>;
|
|
295
310
|
/** Model backing the signal form. */
|
|
296
311
|
private readonly model;
|
|
312
|
+
/**
|
|
313
|
+
* Builds the form model from the dialog data, which may pre-fill subject and body.
|
|
314
|
+
* @returns A fresh form model.
|
|
315
|
+
*/
|
|
316
|
+
private toForm;
|
|
317
|
+
/**
|
|
318
|
+
* Builds the dialog result from the current form model.
|
|
319
|
+
*
|
|
320
|
+
* Ad-hoc because the result also carries the caller's `options`, which the dialog
|
|
321
|
+
* only passes through and are therefore not part of the form model.
|
|
322
|
+
* @returns The message to emit through `done` or `populate`.
|
|
323
|
+
*/
|
|
324
|
+
private toPayload;
|
|
297
325
|
/**
|
|
298
326
|
* Signal form for the send-to fields: recipients (a required, valid,
|
|
299
327
|
* semicolon-separated email list), subject and text are all required.
|
|
300
328
|
*/
|
|
301
|
-
protected readonly form: _angular_forms_signals.FieldTree<
|
|
329
|
+
protected readonly form: _angular_forms_signals.FieldTree<SendToForm, string | number, "writable">;
|
|
302
330
|
/**
|
|
303
331
|
* Confirm the form and emit the result.
|
|
304
332
|
*/
|