@arsedizioni/ars-utils 22.5.46 → 22.5.48
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-core.validators.mjs +18 -139
- package/fesm2022/arsedizioni-ars-utils-core.validators.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.select.mjs +100 -14
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.select.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/arsedizioni-ars-utils-core.validators.d.ts +9 -64
- package/types/arsedizioni-ars-utils-ui.d.ts +31 -2
- package/types/arsedizioni-ars-utils-ui.dialogs.select.d.ts +49 -3
package/package.json
CHANGED
|
@@ -257,8 +257,8 @@ declare class TimeValidatorDirective implements Validator {
|
|
|
257
257
|
* nor an empty array. Apply `notEmpty` to a text input where non-blank content is required, or
|
|
258
258
|
* to a multi-value control that must carry at least one entry.
|
|
259
259
|
*
|
|
260
|
-
* A value that is simply absent passes: saying "obbligatorio" is the job of `required`,
|
|
261
|
-
*
|
|
260
|
+
* A value that is simply absent passes: saying "obbligatorio" is the job of `required`, which is
|
|
261
|
+
* declared next to this one when both rules belong on the same control.
|
|
262
262
|
*/
|
|
263
263
|
declare class NotEmptyValidatorDirective implements Validator {
|
|
264
264
|
/**
|
|
@@ -272,37 +272,6 @@ declare class NotEmptyValidatorDirective implements Validator {
|
|
|
272
272
|
static ɵdir: i0.ɵɵDirectiveDeclaration<NotEmptyValidatorDirective, "[notEmpty]", never, {}, {}, never, never, true, never>;
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
/**
|
|
276
|
-
* Directive that validates that a control carries actual content: present AND not blank.
|
|
277
|
-
* Apply `requiredNotEmpty` where `required notEmpty` would otherwise be spelled out together.
|
|
278
|
-
*
|
|
279
|
-
* It raises the very errors those two rules raise — `required` when the value is missing, an
|
|
280
|
-
* empty string or an empty array, `notEmpty` when a value is there but made of whitespace alone —
|
|
281
|
-
* so existing error messages and `getFieldErrorMessage` keep working untouched, and the user
|
|
282
|
-
* still reads "Obbligatorio" rather than the vaguer "Non può essere vuoto".
|
|
283
|
-
*
|
|
284
|
-
* IMPORTANT, on a Material field: this directive does NOT draw the asterisk. `MatInput` reads its
|
|
285
|
-
* own `required` input first and falls back to `hasValidator(Validators.required)`, which no
|
|
286
|
-
* directive-provided validator can satisfy — the validators of a template-driven control are
|
|
287
|
-
* merged into one composed function before they get there. Keep writing `required` on the
|
|
288
|
-
* control next to this one: the two produce the same `{ required: true }` key, so the errors
|
|
289
|
-
* merge and nothing is reported twice.
|
|
290
|
-
*
|
|
291
|
-
* `aria-required` is set here so that assistive technology is told the truth even where the
|
|
292
|
-
* `required` attribute is absent.
|
|
293
|
-
*/
|
|
294
|
-
declare class RequiredNotEmptyValidatorDirective implements Validator {
|
|
295
|
-
/**
|
|
296
|
-
* Validates that the control value is present and carries content.
|
|
297
|
-
* @param control - The form control to validate.
|
|
298
|
-
* @returns `{ required: true }` when nothing was entered, `{ notEmpty: true }` when the value
|
|
299
|
-
* is blank, `null` when the value is acceptable.
|
|
300
|
-
*/
|
|
301
|
-
validate(control: AbstractControl): ValidationErrors | null;
|
|
302
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<RequiredNotEmptyValidatorDirective, never>;
|
|
303
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<RequiredNotEmptyValidatorDirective, "[requiredNotEmpty]", never, {}, {}, never, never, true, never>;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
275
|
/**
|
|
307
276
|
* Options shared by the ARS signal-form validators.
|
|
308
277
|
*
|
|
@@ -370,12 +339,16 @@ declare function password<TPathKind extends PathKind = PathKind.Root>(path: Sche
|
|
|
370
339
|
* The signal-form counterpart of `NotEmptyValidatorDirective`, sharing its predicate through
|
|
371
340
|
* {@link isBlankValue}: a blank string and an empty array are errors, an absent value is not.
|
|
372
341
|
* That last part is not an oversight — saying "obbligatorio" belongs to `required()`, and a field
|
|
373
|
-
* that is merely blank would otherwise raise two errors that mean the same thing.
|
|
374
|
-
*
|
|
342
|
+
* that is merely blank would otherwise raise two errors that mean the same thing. Declare the two
|
|
343
|
+
* together when a field must be both present and non-blank.
|
|
375
344
|
*
|
|
376
345
|
* Replaces the `pattern(p.x, /\S/)` workaround: same rule, but the intent is in the name and the
|
|
377
346
|
* error kind is `notEmpty` rather than `pattern`.
|
|
378
347
|
*
|
|
348
|
+
* On a multi-value field this rule is the ONLY one that sees an empty selection: Angular's
|
|
349
|
+
* `required()` treats emptiness as `'' | false | null | undefined`, so an empty array walks past
|
|
350
|
+
* it. Give it a message of its own there, because the default one talks about whitespace.
|
|
351
|
+
*
|
|
379
352
|
* @param path - Path of the field to validate.
|
|
380
353
|
* @param config - Optional message override.
|
|
381
354
|
* @returns void
|
|
@@ -385,34 +358,6 @@ declare function password<TPathKind extends PathKind = PathKind.Root>(path: Sche
|
|
|
385
358
|
* const f = form(this.model, p => { notEmpty(p.tags); }); // at least one tag
|
|
386
359
|
*/
|
|
387
360
|
declare function notEmpty<TValue extends string | readonly unknown[] | undefined, TPathKind extends PathKind = PathKind.Root>(path: SchemaPath<TValue, SchemaPathRules.Supported, TPathKind>, config?: ArsValidatorConfig<TValue, TPathKind>): void;
|
|
388
|
-
/**
|
|
389
|
-
* Requires the value to be both present and made of something: the two rules a mandatory text
|
|
390
|
-
* field almost always needs together, declared once.
|
|
391
|
-
*
|
|
392
|
-
* The signal-form counterpart of `RequiredNotEmptyValidatorDirective`. It raises the errors the
|
|
393
|
-
* two rules raise on their own rather than a kind of its own — `required` when nothing was
|
|
394
|
-
* entered, `notEmpty` when a value is there but blank — so the message stays as precise as it was
|
|
395
|
-
* and nothing downstream needs to learn a new kind.
|
|
396
|
-
*
|
|
397
|
-
* The presence half is DELEGATED to Angular's own `required()` and is not reimplemented here.
|
|
398
|
-
* That call does more than validate: it writes the `REQUIRED` metadata on the field, and that
|
|
399
|
-
* metadata is the only thing the Material compatibility layer looks at when it answers
|
|
400
|
-
* `hasValidator(Validators.required)` through `field().required()`. A plain `validate()` would
|
|
401
|
-
* reject the empty value just the same and silently drop the asterisk from the label.
|
|
402
|
-
*
|
|
403
|
-
* The empty array is the one case handled here rather than there: Angular's emptiness check is
|
|
404
|
-
* `value === '' || value === false || value == null`, so an empty array walks straight past
|
|
405
|
-
* `required()`. It is reported with the `required` kind all the same, because for a multi-value
|
|
406
|
-
* field "nothing selected" is exactly what the user needs to be told.
|
|
407
|
-
*
|
|
408
|
-
* @param path - Path of the field to validate.
|
|
409
|
-
* @param config - Optional message override, applied to whichever of the two errors is raised,
|
|
410
|
-
* and `when` condition, honoured by both halves of the rule.
|
|
411
|
-
* @returns void
|
|
412
|
-
* @example
|
|
413
|
-
* const f = form(this.model, p => { requiredNotEmpty(p.city); });
|
|
414
|
-
*/
|
|
415
|
-
declare function requiredNotEmpty<TValue extends string | readonly unknown[] | undefined, TPathKind extends PathKind = PathKind.Root>(path: SchemaPath<TValue, SchemaPathRules.Supported, TPathKind>, config?: ArsValidatorConfig<TValue, TPathKind>): void;
|
|
416
361
|
/**
|
|
417
362
|
* Requires the value to differ from the value of another field of the same form.
|
|
418
363
|
*
|
|
@@ -613,5 +558,5 @@ declare class SignalsUtils {
|
|
|
613
558
|
}[], message?: string): string | undefined;
|
|
614
559
|
}
|
|
615
560
|
|
|
616
|
-
export { ARS_VALIDATOR_MESSAGES, EmailsValidatorDirective, EqualsValidatorDirective, FileSizeValidatorDirective, GuidValidatorDirective, MIN_VALID_YEAR, MaxTermsValidatorDirective, NotEmptyValidatorDirective, NotEqualValidatorDirective, NotFutureValidatorDirective, PasswordValidatorDirective,
|
|
561
|
+
export { ARS_VALIDATOR_MESSAGES, EmailsValidatorDirective, EqualsValidatorDirective, FileSizeValidatorDirective, GuidValidatorDirective, MIN_VALID_YEAR, MaxTermsValidatorDirective, NotEmptyValidatorDirective, NotEqualValidatorDirective, NotFutureValidatorDirective, PasswordValidatorDirective, SignalsUtils, SqlDateValidatorDirective, TimeValidatorDirective, UrlValidatorDirective, ValidIfDirective, ValidatorDirective, date, dateRange, emails, equals, fileSize, guid, maxTerms, notEmpty, notEqual, notFuture, otp, password, sqlDate, time, url, validIf };
|
|
617
562
|
export type { ArsValidatorConfig };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Searchable, INode,
|
|
1
|
+
import { Searchable, INode, SearchBag, DateInterval, NameValueItem } from '@arsedizioni/ars-utils/core';
|
|
2
2
|
import { MatFormFieldAppearance } from '@angular/material/form-field';
|
|
3
3
|
import * as _angular_core from '@angular/core';
|
|
4
4
|
import { TemplateRef, InjectionToken, Signal, ElementRef, Renderer2 } from '@angular/core';
|
|
@@ -111,6 +111,35 @@ interface SelectDialogData {
|
|
|
111
111
|
searchLabel?: string;
|
|
112
112
|
searchButtonLabel?: string;
|
|
113
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Data of `ListDialogComponent`: the read-only sibling of {@link SelectDialogData}.
|
|
116
|
+
*
|
|
117
|
+
* It carries no `can*` flag on purpose — the dialog shows a searchable list and closes, so there
|
|
118
|
+
* is nothing to enable — and no `mustSelect` / `okCaption` either, because there is no
|
|
119
|
+
* confirmation step to gate.
|
|
120
|
+
*/
|
|
121
|
+
interface ListDialogData {
|
|
122
|
+
/** Dialog title, rendered as HTML. */
|
|
123
|
+
title: string;
|
|
124
|
+
/** Optional description shown under the title, rendered as HTML. */
|
|
125
|
+
description?: string;
|
|
126
|
+
/** Optional header shown above the list, rendered as HTML. Hidden while the list is empty. */
|
|
127
|
+
header?: string;
|
|
128
|
+
/** Items to display. */
|
|
129
|
+
items?: SelectableItem[];
|
|
130
|
+
/** Initial search text. */
|
|
131
|
+
filter?: string;
|
|
132
|
+
/** Message shown in place of the list when there is nothing to display. Rendered as HTML. */
|
|
133
|
+
emptyMessage?: string;
|
|
134
|
+
/** Caption of the close button, which is always available. Defaults to `Chiudi`. */
|
|
135
|
+
closeCaption?: string;
|
|
136
|
+
/** Label of the search field. Defaults to `Cerca...`. */
|
|
137
|
+
searchLabel?: string;
|
|
138
|
+
/** Appearance of the search field. Defaults to `outline`. */
|
|
139
|
+
appearance?: MatFormFieldAppearance;
|
|
140
|
+
/** Preferred dialog width, in pixels, for the caller that opens it. */
|
|
141
|
+
width?: number;
|
|
142
|
+
}
|
|
114
143
|
interface SelectTreeDialogData {
|
|
115
144
|
title: string;
|
|
116
145
|
description?: string;
|
|
@@ -910,4 +939,4 @@ declare class FlexLayoutModule {
|
|
|
910
939
|
}
|
|
911
940
|
|
|
912
941
|
export { ALIAS_FAMILIES, BS5_BREAKPOINTS, CANONICAL_ALIASES, FlexLayoutModule, FxClassDirective, FxFlexAlignDirective, FxFlexDirective, FxFlexFillDirective, FxFlexOffsetDirective, FxFlexOrderDirective, FxGridAreaDirective, FxGridColumnDirective, FxGridDirective, FxLayoutAlignDirective, FxLayoutDirective, FxLayoutGapDirective, FxLayoutWrapDirective, FxShowHideDirective, FxStyleDirective, IfBpDirective, ItemNode, LAYOUT_BREAKPOINTS, LAYOUT_VALUES, MediaObserver, NON_CANONICAL_PRIORITY, PromptDialogType, ResponsiveBaseDirective, SelectableItem, SelectableNode, UIService, applyVisibility, buildAlignStyles, buildFlexStyles, buildLayoutCSS, resolve, resolveAll, resolveFlexInput, resolveNonCanonical, resolveParentFlow, validateBasis, validateLayoutValue, validateWrapValue };
|
|
913
|
-
export type { BpValues, BreakpointAlias, CanonicalKey, CredentialsDialogResult, DialogOption, DialogResult, ISelectableItem, ISendToDialog, NcValues, NonCanonicalKey, PromptDateDialogResult, PromptDialogData, PromptDialogResult, PromptOtpDialogResult, PromptTimeDialogData, RecoverPasswordDialogResult, ResetPasswordDialogResult, SelectDialogAppend, SelectDialogData, SelectDialogDelete, SelectDialogEdit, SelectDialogFilter, SelectDialogLookup, SelectDialogResult, SelectFile, SelectFileDialogData, SelectFileOption, SelectPictureFileDialogData, SelectTreeDialogData, SelectTreeDialogResult, SelectableFilter, SendToDialogResult, SendToPopulateData };
|
|
942
|
+
export type { BpValues, BreakpointAlias, CanonicalKey, CredentialsDialogResult, DialogOption, DialogResult, ISelectableItem, ISendToDialog, ListDialogData, NcValues, NonCanonicalKey, PromptDateDialogResult, PromptDialogData, PromptDialogResult, PromptOtpDialogResult, PromptTimeDialogData, RecoverPasswordDialogResult, ResetPasswordDialogResult, SelectDialogAppend, SelectDialogData, SelectDialogDelete, SelectDialogEdit, SelectDialogFilter, SelectDialogLookup, SelectDialogResult, SelectFile, SelectFileDialogData, SelectFileOption, SelectPictureFileDialogData, SelectTreeDialogData, SelectTreeDialogResult, SelectableFilter, SendToDialogResult, SendToPopulateData };
|
|
@@ -1,16 +1,62 @@
|
|
|
1
1
|
import * as _angular_forms_signals from '@angular/forms/signals';
|
|
2
2
|
import * as _angular_core from '@angular/core';
|
|
3
3
|
import { OnDestroy } from '@angular/core';
|
|
4
|
+
import { SearchFilterMetadata } from '@arsedizioni/ars-utils/core';
|
|
5
|
+
import { ListDialogData, SelectableItem, SelectDialogData, SelectDialogResult, SelectDialogEdit, SelectDialogAppend, SelectDialogDelete, SelectDialogLookup, SelectDialogFilter, SelectableFilter, ItemNode, SelectTreeDialogResult, SelectTreeDialogData, ISendToDialog, SendToDialogResult, SendToPopulateData } from '@arsedizioni/ars-utils/ui';
|
|
4
6
|
import { MatCheckboxChange } from '@angular/material/checkbox';
|
|
5
7
|
import { MatSelectionList, MatSelectionListChange } from '@angular/material/list';
|
|
6
8
|
import { MatPaginator, PageEvent } from '@angular/material/paginator';
|
|
7
|
-
import { SearchFilterMetadata } from '@arsedizioni/ars-utils/core';
|
|
8
|
-
import { SelectDialogData, SelectDialogResult, SelectDialogEdit, SelectableItem, SelectDialogAppend, SelectDialogDelete, SelectDialogLookup, SelectDialogFilter, SelectableFilter, ItemNode, SelectTreeDialogResult, SelectTreeDialogData, ISendToDialog, SendToDialogResult, SendToPopulateData } from '@arsedizioni/ars-utils/ui';
|
|
9
9
|
import * as rxjs from 'rxjs';
|
|
10
10
|
import { MatTree } from '@angular/material/tree';
|
|
11
11
|
import { MatFormFieldAppearance } from '@angular/material/form-field';
|
|
12
12
|
import { SignalsUtils } from '@arsedizioni/ars-utils/core.validators';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Read-only counterpart of `SelectDialogComponent`: it shows a list of items with a search box
|
|
16
|
+
* and nothing else.
|
|
17
|
+
*
|
|
18
|
+
* Deliberately not a selection: the list is a plain `mat-list`, not a `mat-selection-list`, so
|
|
19
|
+
* there is no selected state to read, no `done` payload and no Ok / Annulla pair — closing is the
|
|
20
|
+
* only way out and it is always available. It carries no add / edit / delete affordance either:
|
|
21
|
+
* a dialog that cannot change anything is the whole point, and a caller that needs commands wants
|
|
22
|
+
* `SelectDialogComponent` instead.
|
|
23
|
+
*
|
|
24
|
+
* Filtering is client-side, through the same `search` pipe the select dialog uses on its local
|
|
25
|
+
* items. There is no server-side lookup: paging a list nobody can act on would buy nothing.
|
|
26
|
+
*/
|
|
27
|
+
declare class ListDialogComponent {
|
|
28
|
+
private readonly cdr;
|
|
29
|
+
protected readonly dialogData: _angular_core.WritableSignal<ListDialogData>;
|
|
30
|
+
/** Items currently on screen. Seeded from the dialog data and replaceable through {@link setItems}. */
|
|
31
|
+
protected readonly items: _angular_core.WritableSignal<SelectableItem[]>;
|
|
32
|
+
/** Counters written by the `search` pipe while it filters, read back by the footer. */
|
|
33
|
+
protected filterMetadata: SearchFilterMetadata;
|
|
34
|
+
/** Current search text. */
|
|
35
|
+
protected readonly filterText: _angular_core.WritableSignal<string>;
|
|
36
|
+
/** Root signal form bound to the search input. */
|
|
37
|
+
protected readonly filterForm: _angular_forms_signals.FieldTree<string, string | number, "writable">;
|
|
38
|
+
/**
|
|
39
|
+
* Replaces the items on screen, for a caller that fills the list after opening the dialog or
|
|
40
|
+
* refreshes it while it is open.
|
|
41
|
+
* @param items - The new items to display; an empty array clears the list.
|
|
42
|
+
*/
|
|
43
|
+
setItems(items: SelectableItem[]): void;
|
|
44
|
+
/**
|
|
45
|
+
* Sets the search text programmatically.
|
|
46
|
+
* @param text - The new search string to apply.
|
|
47
|
+
*/
|
|
48
|
+
setFilter(text: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Returns the current search text.
|
|
51
|
+
* @returns The active search string.
|
|
52
|
+
*/
|
|
53
|
+
getFilter(): string;
|
|
54
|
+
/** Clears the search text, restoring the whole list. */
|
|
55
|
+
protected clearFilter(): void;
|
|
56
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ListDialogComponent, never>;
|
|
57
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ListDialogComponent, "ng-component", never, {}, {}, never, never, true, never>;
|
|
58
|
+
}
|
|
59
|
+
|
|
14
60
|
declare class SelectDialogComponent {
|
|
15
61
|
readonly paginator: _angular_core.Signal<MatPaginator>;
|
|
16
62
|
readonly selection: _angular_core.Signal<MatSelectionList>;
|
|
@@ -345,5 +391,5 @@ declare class SendToDialogComponent implements ISendToDialog {
|
|
|
345
391
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SendToDialogComponent, "ng-component", never, {}, { "done": "done"; "populate": "populate"; }, never, never, true, never>;
|
|
346
392
|
}
|
|
347
393
|
|
|
348
|
-
export { SelectDialogComponent, SelectTreeDialogComponent, SendToDialogComponent, TreeDataSource };
|
|
394
|
+
export { ListDialogComponent, SelectDialogComponent, SelectTreeDialogComponent, SendToDialogComponent, TreeDataSource };
|
|
349
395
|
export type { SelectTreeDialogAppend, SendToDialogData };
|