@3kles/kles-material-dynamicforms 21.7.4 → 21.7.6
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.
|
@@ -4,7 +4,7 @@ import * as i1 from '@angular/common';
|
|
|
4
4
|
import { CommonModule, AsyncPipe } from '@angular/common';
|
|
5
5
|
import * as i2 from '@angular/forms';
|
|
6
6
|
import { Validators, FormControl, ReactiveFormsModule, FormsModule, FormControlDirective, FormControlName, FormArray, FormGroup, UntypedFormBuilder, NG_VALUE_ACCESSOR, UntypedFormGroup } from '@angular/forms';
|
|
7
|
-
import { concat, of, Subject, combineLatest, startWith, map as map$1, takeUntil, Observable, defer,
|
|
7
|
+
import { concat, of, Subject, combineLatest, startWith, map as map$1, takeUntil, Observable, defer, ReplaySubject, switchMap as switchMap$1, isObservable, timer, distinctUntilChanged as distinctUntilChanged$1, shareReplay as shareReplay$1 } from 'rxjs';
|
|
8
8
|
import { tap, take, catchError, map, takeUntil as takeUntil$1, distinctUntilChanged, filter, switchMap, startWith as startWith$1, shareReplay, debounceTime, debounce } from 'rxjs/operators';
|
|
9
9
|
import * as i3 from '@angular/material/form-field';
|
|
10
10
|
import { MatError, MatFormFieldModule, MatFormField, MatHint, MatLabel, MatSuffix } from '@angular/material/form-field';
|
|
@@ -29,7 +29,7 @@ import { MatInputModule, MatInput, MatLabel as MatLabel$1, MatFormField as MatFo
|
|
|
29
29
|
import * as i6 from '@angular/material/select';
|
|
30
30
|
import { MatSelectModule, MatSelect, MatSelectTrigger } from '@angular/material/select';
|
|
31
31
|
import { MatRadioModule, MatRadioButton, MatRadioGroup } from '@angular/material/radio';
|
|
32
|
-
import * as
|
|
32
|
+
import * as i3$6 from '@angular/material/chips';
|
|
33
33
|
import { MatChipsModule, MatChipOption, MatChipListbox } from '@angular/material/chips';
|
|
34
34
|
import * as i4$1 from '@angular/material/tooltip';
|
|
35
35
|
import { MatTooltipModule, MatTooltip } from '@angular/material/tooltip';
|
|
@@ -344,16 +344,16 @@ function isDestroyable(value) {
|
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
class KlesDynamicFieldDirective {
|
|
347
|
-
constructor(container, injector) {
|
|
347
|
+
constructor(container, injector, applicationRef) {
|
|
348
348
|
this.container = container;
|
|
349
349
|
this.injector = injector;
|
|
350
|
+
this.applicationRef = applicationRef;
|
|
350
351
|
this.context = null;
|
|
351
352
|
this.subComponents = [];
|
|
353
|
+
this.subComponentViews = new Map();
|
|
352
354
|
}
|
|
353
355
|
ngOnDestroy() {
|
|
354
|
-
|
|
355
|
-
this.componentRef.destroy();
|
|
356
|
-
}
|
|
356
|
+
this.destroyComponents();
|
|
357
357
|
}
|
|
358
358
|
ngOnInit() {
|
|
359
359
|
this.buildComponent();
|
|
@@ -384,11 +384,7 @@ class KlesDynamicFieldDirective {
|
|
|
384
384
|
}
|
|
385
385
|
}
|
|
386
386
|
buildComponent() {
|
|
387
|
-
|
|
388
|
-
this.subComponents.forEach((c) => c.destroy());
|
|
389
|
-
this.subComponents = [];
|
|
390
|
-
this.componentRef.destroy();
|
|
391
|
-
}
|
|
387
|
+
this.destroyComponents();
|
|
392
388
|
const options = {
|
|
393
389
|
providers: [
|
|
394
390
|
...(this.field.providers || []),
|
|
@@ -481,6 +477,14 @@ class KlesDynamicFieldDirective {
|
|
|
481
477
|
createSubComponent(componentType, options) {
|
|
482
478
|
const injector = Injector.create(options);
|
|
483
479
|
const component = this.container.createComponent(componentType, { injector });
|
|
480
|
+
// The host element is projected into the field component. Keeping its view
|
|
481
|
+
// in this container would make Angular's logical DOM differ from the real DOM.
|
|
482
|
+
const viewIndex = this.container.indexOf(component.hostView);
|
|
483
|
+
const detachedView = viewIndex !== -1 ? this.container.detach(viewIndex) : null;
|
|
484
|
+
if (detachedView) {
|
|
485
|
+
this.applicationRef.attachView(detachedView);
|
|
486
|
+
this.subComponentViews.set(component, detachedView);
|
|
487
|
+
}
|
|
484
488
|
component.onDestroy(() => {
|
|
485
489
|
if (isDestroyable(injector)) {
|
|
486
490
|
injector.destroy();
|
|
@@ -488,7 +492,20 @@ class KlesDynamicFieldDirective {
|
|
|
488
492
|
});
|
|
489
493
|
return component;
|
|
490
494
|
}
|
|
491
|
-
|
|
495
|
+
destroyComponents() {
|
|
496
|
+
this.componentRef?.destroy();
|
|
497
|
+
this.componentRef = undefined;
|
|
498
|
+
this.subComponents.forEach((component) => {
|
|
499
|
+
const view = this.subComponentViews.get(component);
|
|
500
|
+
if (view) {
|
|
501
|
+
this.applicationRef.detachView(view);
|
|
502
|
+
}
|
|
503
|
+
component.destroy();
|
|
504
|
+
});
|
|
505
|
+
this.subComponents = [];
|
|
506
|
+
this.subComponentViews.clear();
|
|
507
|
+
}
|
|
508
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KlesDynamicFieldDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.Injector }, { token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
492
509
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: KlesDynamicFieldDirective, isStandalone: true, selector: "[klesDynamicField]", inputs: { field: "field", group: "group", ui: "ui", siblingFields: "siblingFields", context: "context" }, usesOnChanges: true, ngImport: i0 }); }
|
|
493
510
|
}
|
|
494
511
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KlesDynamicFieldDirective, decorators: [{
|
|
@@ -497,7 +514,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImpo
|
|
|
497
514
|
selector: '[klesDynamicField]',
|
|
498
515
|
standalone: true,
|
|
499
516
|
}]
|
|
500
|
-
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.Injector }], propDecorators: { field: [{
|
|
517
|
+
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.Injector }, { type: i0.ApplicationRef }], propDecorators: { field: [{
|
|
501
518
|
type: Input
|
|
502
519
|
}], group: [{
|
|
503
520
|
type: Input
|
|
@@ -5338,208 +5355,311 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImpo
|
|
|
5338
5355
|
class KlesFormChipGridComponent extends KlesFieldAbstract {
|
|
5339
5356
|
constructor() {
|
|
5340
5357
|
super(...arguments);
|
|
5341
|
-
this.options = this.field.options;
|
|
5342
5358
|
this.control = this.group.controls[this.field.name];
|
|
5343
5359
|
this.intl = inject(KlesDynamicFormIntl);
|
|
5344
5360
|
this.separatorKeysCodes = [ENTER, COMMA];
|
|
5345
|
-
|
|
5346
|
-
|
|
5361
|
+
/*
|
|
5362
|
+
* any est volontaire :
|
|
5363
|
+
* MatAutocomplete peut momentanément pousser l'objet
|
|
5364
|
+
* sélectionné dans le FormControl de recherche.
|
|
5365
|
+
*/
|
|
5366
|
+
this.searchControl = new FormControl('', {
|
|
5367
|
+
nonNullable: true,
|
|
5368
|
+
});
|
|
5369
|
+
/*
|
|
5370
|
+
* ReplaySubject permet de ne pas perdre le premier focus
|
|
5371
|
+
* si l'Observable lazy n'est pas encore abonné.
|
|
5372
|
+
*/
|
|
5373
|
+
this.loadOptions$ = new ReplaySubject(1);
|
|
5347
5374
|
}
|
|
5348
5375
|
ngOnInit() {
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
if (isFocused) {
|
|
5352
|
-
let obs$;
|
|
5353
|
-
if (this.field.options instanceof Observable) {
|
|
5354
|
-
obs$ = this.field.options;
|
|
5355
|
-
}
|
|
5356
|
-
else if (this.field.options instanceof Function) {
|
|
5357
|
-
obs$ = this.field.options();
|
|
5358
|
-
}
|
|
5359
|
-
else {
|
|
5360
|
-
obs$ = of(this.field.options ?? []);
|
|
5361
|
-
}
|
|
5362
|
-
return concat(of({ loading: true, options: [] }), obs$.pipe(map$1((options) => {
|
|
5363
|
-
return { loading: false, options };
|
|
5364
|
-
})));
|
|
5365
|
-
}
|
|
5366
|
-
else {
|
|
5367
|
-
return of({ loading: false, options: [] });
|
|
5368
|
-
}
|
|
5369
|
-
}));
|
|
5370
|
-
}
|
|
5371
|
-
else {
|
|
5372
|
-
if (this.field.options instanceof Observable) {
|
|
5373
|
-
this.options$ = concat(of({ loading: true, options: [] }), this.field.options.pipe(map$1((options) => {
|
|
5374
|
-
return { loading: false, options };
|
|
5375
|
-
})));
|
|
5376
|
-
}
|
|
5377
|
-
else if (this.field.options instanceof Function) {
|
|
5378
|
-
this.options$ = concat(of({ loading: true, options: [] }), this.field.options().pipe(map$1((options) => {
|
|
5379
|
-
return { loading: false, options };
|
|
5380
|
-
})));
|
|
5381
|
-
}
|
|
5382
|
-
else {
|
|
5383
|
-
this.options$ = of({ loading: false, options: this.field.options });
|
|
5384
|
-
}
|
|
5385
|
-
}
|
|
5386
|
-
this.filteredOption$ = concat(combineLatest([this.searchControl?.valueChanges.pipe(startWith('')) ?? of(''), this.options$]).pipe(map$1(([data, response]) => {
|
|
5376
|
+
this.options$ = this.createOptionsStream();
|
|
5377
|
+
this.filteredOption$ = combineLatest([this.searchControl.valueChanges.pipe(startWith(this.searchControl.value)), this.options$, this.control.valueChanges.pipe(startWith(this.control.value ?? []))]).pipe(map$1(([search, response, selectedValues]) => {
|
|
5387
5378
|
if (response.loading) {
|
|
5388
5379
|
return response;
|
|
5389
5380
|
}
|
|
5390
|
-
|
|
5391
|
-
|
|
5381
|
+
const selected = Array.isArray(selectedValues) ? selectedValues : [];
|
|
5382
|
+
/*
|
|
5383
|
+
* On retire de la liste les options
|
|
5384
|
+
* déjà présentes dans les chips.
|
|
5385
|
+
*/
|
|
5386
|
+
let options = response.options.filter((option) => !selected.some((selectedValue) => this.isSameOption(option, selectedValue)));
|
|
5387
|
+
/*
|
|
5388
|
+
* Le contrôle peut momentanément contenir
|
|
5389
|
+
* un objet pendant une sélection autocomplete.
|
|
5390
|
+
*/
|
|
5391
|
+
if (typeof search === 'string' && search.trim()) {
|
|
5392
|
+
options = this.filterData(search, options);
|
|
5392
5393
|
}
|
|
5393
|
-
|
|
5394
|
+
return {
|
|
5395
|
+
loading: false,
|
|
5396
|
+
options,
|
|
5397
|
+
};
|
|
5398
|
+
}));
|
|
5394
5399
|
super.ngOnInit();
|
|
5395
5400
|
}
|
|
5396
|
-
ngOnDestroy() {
|
|
5397
|
-
super.ngOnDestroy();
|
|
5398
|
-
}
|
|
5399
5401
|
onFocus() {
|
|
5400
5402
|
if (this.field.lazy) {
|
|
5401
|
-
this.
|
|
5403
|
+
this.loadOptions$.next();
|
|
5402
5404
|
}
|
|
5403
5405
|
super.onFocus();
|
|
5404
5406
|
}
|
|
5405
5407
|
onTokenEnd(event) {
|
|
5406
|
-
|
|
5408
|
+
/*
|
|
5409
|
+
* Quand property est renseignée, les valeurs sont
|
|
5410
|
+
* considérées comme des objets provenant de l'autocomplete.
|
|
5411
|
+
*
|
|
5412
|
+
* On évite donc d'ajouter une string libre au tableau.
|
|
5413
|
+
*/
|
|
5414
|
+
if (this.field.property) {
|
|
5415
|
+
return;
|
|
5416
|
+
}
|
|
5417
|
+
const value = event.value.trim();
|
|
5418
|
+
if (!value) {
|
|
5419
|
+
return;
|
|
5420
|
+
}
|
|
5421
|
+
this.addChip(value);
|
|
5407
5422
|
event.chipInput.clear();
|
|
5423
|
+
this.searchControl.setValue('');
|
|
5408
5424
|
}
|
|
5409
|
-
addChip(
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
this.control.setValue([...(this.control.value ?? []), value]);
|
|
5425
|
+
addChip(value) {
|
|
5426
|
+
if (value === null || value === undefined || value === '') {
|
|
5427
|
+
return;
|
|
5413
5428
|
}
|
|
5429
|
+
const values = Array.isArray(this.control.value) ? this.control.value : [];
|
|
5430
|
+
/*
|
|
5431
|
+
* Empêche d'ajouter deux fois la même valeur.
|
|
5432
|
+
*/
|
|
5433
|
+
const exists = values.some((currentValue) => this.isSameOption(currentValue, value));
|
|
5434
|
+
if (exists) {
|
|
5435
|
+
return;
|
|
5436
|
+
}
|
|
5437
|
+
this.control.setValue([...values, value]);
|
|
5438
|
+
this.control.markAsDirty();
|
|
5414
5439
|
}
|
|
5415
5440
|
removeChip(value) {
|
|
5416
|
-
const values = this.control.value;
|
|
5417
|
-
const index = values.
|
|
5418
|
-
if (index
|
|
5419
|
-
|
|
5420
|
-
this.control.setValue(values);
|
|
5441
|
+
const values = Array.isArray(this.control.value) ? [...this.control.value] : [];
|
|
5442
|
+
const index = values.findIndex((currentValue) => this.isSameOption(currentValue, value));
|
|
5443
|
+
if (index === -1) {
|
|
5444
|
+
return;
|
|
5421
5445
|
}
|
|
5446
|
+
values.splice(index, 1);
|
|
5447
|
+
this.control.setValue(values);
|
|
5448
|
+
this.control.markAsDirty();
|
|
5422
5449
|
}
|
|
5423
|
-
selected(event) {
|
|
5424
|
-
|
|
5450
|
+
selected(event, chipInput) {
|
|
5451
|
+
const value = event.option.value;
|
|
5452
|
+
/*
|
|
5453
|
+
* On ajoute d'abord l'objet sélectionné aux chips.
|
|
5454
|
+
*/
|
|
5455
|
+
this.addChip(value);
|
|
5456
|
+
/*
|
|
5457
|
+
* L'autocomplete n'est ici qu'une source de sélection.
|
|
5458
|
+
* La sélection réelle est représentée par les chips.
|
|
5459
|
+
*/
|
|
5425
5460
|
event.option.deselect();
|
|
5426
|
-
|
|
5461
|
+
/*
|
|
5462
|
+
* Important :
|
|
5463
|
+
* MatChipInput.clear() nettoie réellement l'input HTML.
|
|
5464
|
+
*/
|
|
5465
|
+
chipInput.clear();
|
|
5466
|
+
/*
|
|
5467
|
+
* Et on synchronise le FormControl afin de :
|
|
5468
|
+
* - vider l'état Angular ;
|
|
5469
|
+
* - supprimer le filtre ;
|
|
5470
|
+
* - recalculer filteredOption$.
|
|
5471
|
+
*/
|
|
5472
|
+
this.searchControl.setValue('');
|
|
5427
5473
|
}
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
if (typeof value === 'string' && Object.prototype.toString.call(value) === '[object String]') {
|
|
5432
|
-
filterValue = value.toLowerCase();
|
|
5474
|
+
displayValue(value) {
|
|
5475
|
+
if (value === null || value === undefined) {
|
|
5476
|
+
return '';
|
|
5433
5477
|
}
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
filterValue = value[property]?.toLowerCase();
|
|
5437
|
-
}
|
|
5478
|
+
if (this.field.property) {
|
|
5479
|
+
return value?.[this.field.property] ?? '';
|
|
5438
5480
|
}
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5481
|
+
return value;
|
|
5482
|
+
}
|
|
5483
|
+
createOptionsStream() {
|
|
5484
|
+
/*
|
|
5485
|
+
* Lazy :
|
|
5486
|
+
* recharge les options à chaque focus.
|
|
5487
|
+
*/
|
|
5488
|
+
if (this.field.lazy) {
|
|
5489
|
+
return this.loadOptions$.pipe(switchMap$1(() => concat(of({
|
|
5490
|
+
loading: true,
|
|
5491
|
+
options: [],
|
|
5492
|
+
}), this.resolveOptions().pipe(map$1((options) => ({
|
|
5493
|
+
loading: false,
|
|
5494
|
+
options,
|
|
5495
|
+
}))))));
|
|
5444
5496
|
}
|
|
5445
|
-
|
|
5497
|
+
/*
|
|
5498
|
+
* Liste statique :
|
|
5499
|
+
* aucun chargement à afficher.
|
|
5500
|
+
*/
|
|
5501
|
+
if (Array.isArray(this.field.options)) {
|
|
5502
|
+
return of({
|
|
5503
|
+
loading: false,
|
|
5504
|
+
options: this.field.options,
|
|
5505
|
+
});
|
|
5506
|
+
}
|
|
5507
|
+
/*
|
|
5508
|
+
* Observable ou fonction :
|
|
5509
|
+
* spinner jusqu'à réception des options.
|
|
5510
|
+
*/
|
|
5511
|
+
return concat(of({
|
|
5512
|
+
loading: true,
|
|
5513
|
+
options: [],
|
|
5514
|
+
}), this.resolveOptions().pipe(map$1((options) => ({
|
|
5515
|
+
loading: false,
|
|
5516
|
+
options,
|
|
5517
|
+
}))));
|
|
5518
|
+
}
|
|
5519
|
+
resolveOptions() {
|
|
5520
|
+
const source = typeof this.field.options === 'function' ? this.field.options() : this.field.options;
|
|
5521
|
+
if (isObservable(source)) {
|
|
5522
|
+
return source;
|
|
5523
|
+
}
|
|
5524
|
+
return of(source ?? []);
|
|
5525
|
+
}
|
|
5526
|
+
filterData(search, options) {
|
|
5527
|
+
if (typeof search !== 'string') {
|
|
5528
|
+
return options;
|
|
5529
|
+
}
|
|
5530
|
+
const filterValue = search.trim().toLowerCase();
|
|
5531
|
+
if (!filterValue) {
|
|
5446
5532
|
return options;
|
|
5447
5533
|
}
|
|
5534
|
+
return options.filter((option) => {
|
|
5535
|
+
const value = this.displayValue(option);
|
|
5536
|
+
return String(value ?? '')
|
|
5537
|
+
.toLowerCase()
|
|
5538
|
+
.startsWith(filterValue);
|
|
5539
|
+
});
|
|
5540
|
+
}
|
|
5541
|
+
isSameOption(a, b) {
|
|
5542
|
+
/*
|
|
5543
|
+
* Primitive identique ou même référence objet.
|
|
5544
|
+
*/
|
|
5545
|
+
if (a === b) {
|
|
5546
|
+
return true;
|
|
5547
|
+
}
|
|
5548
|
+
/*
|
|
5549
|
+
* En mode objet, property sert actuellement
|
|
5550
|
+
* également à identifier les doublons.
|
|
5551
|
+
*/
|
|
5552
|
+
if (this.field.property && a !== null && a !== undefined && b !== null && b !== undefined) {
|
|
5553
|
+
return a[this.field.property] === b[this.field.property];
|
|
5554
|
+
}
|
|
5555
|
+
return false;
|
|
5448
5556
|
}
|
|
5449
5557
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KlesFormChipGridComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
5450
5558
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: KlesFormChipGridComponent, isStandalone: true, selector: "kles-form-chip-grid", usesInheritance: true, ngImport: i0, template: `
|
|
5451
5559
|
<mat-form-field [formGroup]="group" [matTooltip]="tooltip()" [appearance]="appearance()">
|
|
5452
5560
|
<mat-label>{{ label() }}</mat-label>
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5561
|
+
|
|
5562
|
+
<mat-chip-grid #reactiveChipGrid [formControl]="control">
|
|
5563
|
+
@for (value of control.value ?? []; track $index) {
|
|
5564
|
+
<mat-chip-row [value]="value" (removed)="removeChip(value)">
|
|
5565
|
+
{{ displayValue(value) | klesTransform: field.pipeTransform }}
|
|
5566
|
+
|
|
5457
5567
|
<button matChipRemove>
|
|
5458
5568
|
<mat-icon>cancel</mat-icon>
|
|
5459
5569
|
</button>
|
|
5460
5570
|
</mat-chip-row>
|
|
5461
5571
|
}
|
|
5462
5572
|
</mat-chip-grid>
|
|
5573
|
+
|
|
5463
5574
|
<input
|
|
5464
|
-
#
|
|
5575
|
+
#chipInput="matChipInput"
|
|
5465
5576
|
[formControl]="searchControl"
|
|
5466
5577
|
[placeholder]="placeholder()"
|
|
5467
5578
|
[matChipInputFor]="reactiveChipGrid"
|
|
5468
|
-
(matChipInputTokenEnd)="onTokenEnd($event)"
|
|
5469
5579
|
[matAutocomplete]="auto"
|
|
5470
5580
|
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
|
5581
|
+
(matChipInputTokenEnd)="onTokenEnd($event)"
|
|
5471
5582
|
(focus)="onFocus()"
|
|
5472
5583
|
(blur)="onBlur()"
|
|
5473
5584
|
/>
|
|
5474
5585
|
|
|
5475
|
-
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)
|
|
5586
|
+
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event, chipInput)">
|
|
5476
5587
|
@if (filteredOption$ | async; as filteredOption) {
|
|
5477
5588
|
@if (filteredOption.loading) {
|
|
5478
5589
|
<mat-option disabled>
|
|
5479
5590
|
<div class="loadingSelect">
|
|
5480
5591
|
{{ intl.loading }}...
|
|
5481
|
-
|
|
5592
|
+
|
|
5593
|
+
<mat-spinner class="spinner" diameter="20" />
|
|
5482
5594
|
</div>
|
|
5483
5595
|
</mat-option>
|
|
5484
5596
|
} @else {
|
|
5485
5597
|
@for (item of filteredOption.options; track item) {
|
|
5486
|
-
<mat-option [value]="item" [disabled]="item?.disabled">
|
|
5598
|
+
<mat-option [value]="item" [disabled]="item?.disabled">
|
|
5599
|
+
{{ displayValue(item) | klesTransform: field.pipeTransform }}
|
|
5600
|
+
</mat-option>
|
|
5487
5601
|
}
|
|
5488
5602
|
}
|
|
5489
5603
|
}
|
|
5490
5604
|
</mat-autocomplete>
|
|
5491
5605
|
|
|
5492
|
-
<mat-error matErrorMessage [validations]="field.validations" [asyncValidations]="field.asyncValidations"
|
|
5606
|
+
<mat-error matErrorMessage [validations]="field.validations" [asyncValidations]="field.asyncValidations" />
|
|
5493
5607
|
</mat-form-field>
|
|
5494
|
-
`, isInline: true, styles: [".suffix{display:flex;align-items:center}\n", ".field-bottom .mat-mdc-form-field-bottom-align:before{content:none!important}\n", ".loadingSelect{display:flex;flex-direction:row;justify-content:space-between;align-items:center}\n", "mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
5608
|
+
`, isInline: true, styles: [".suffix{display:flex;align-items:center}\n", ".field-bottom .mat-mdc-form-field-bottom-align:before{content:none!important}\n", ".loadingSelect{display:flex;flex-direction:row;justify-content:space-between;align-items:center}\n", "mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i5.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i5.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i3$6.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i3$6.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i3$6.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i3$6.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: MatErrorMessageDirective, selector: "[matErrorMessage]", inputs: ["validations", "asyncValidations"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: KlesTransformPipe, name: "klesTransform" }] }); }
|
|
5495
5609
|
}
|
|
5496
5610
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KlesFormChipGridComponent, decorators: [{
|
|
5497
5611
|
type: Component,
|
|
5498
5612
|
args: [{ selector: 'kles-form-chip-grid', template: `
|
|
5499
5613
|
<mat-form-field [formGroup]="group" [matTooltip]="tooltip()" [appearance]="appearance()">
|
|
5500
5614
|
<mat-label>{{ label() }}</mat-label>
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5615
|
+
|
|
5616
|
+
<mat-chip-grid #reactiveChipGrid [formControl]="control">
|
|
5617
|
+
@for (value of control.value ?? []; track $index) {
|
|
5618
|
+
<mat-chip-row [value]="value" (removed)="removeChip(value)">
|
|
5619
|
+
{{ displayValue(value) | klesTransform: field.pipeTransform }}
|
|
5620
|
+
|
|
5505
5621
|
<button matChipRemove>
|
|
5506
5622
|
<mat-icon>cancel</mat-icon>
|
|
5507
5623
|
</button>
|
|
5508
5624
|
</mat-chip-row>
|
|
5509
5625
|
}
|
|
5510
5626
|
</mat-chip-grid>
|
|
5627
|
+
|
|
5511
5628
|
<input
|
|
5512
|
-
#
|
|
5629
|
+
#chipInput="matChipInput"
|
|
5513
5630
|
[formControl]="searchControl"
|
|
5514
5631
|
[placeholder]="placeholder()"
|
|
5515
5632
|
[matChipInputFor]="reactiveChipGrid"
|
|
5516
|
-
(matChipInputTokenEnd)="onTokenEnd($event)"
|
|
5517
5633
|
[matAutocomplete]="auto"
|
|
5518
5634
|
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
|
5635
|
+
(matChipInputTokenEnd)="onTokenEnd($event)"
|
|
5519
5636
|
(focus)="onFocus()"
|
|
5520
5637
|
(blur)="onBlur()"
|
|
5521
5638
|
/>
|
|
5522
5639
|
|
|
5523
|
-
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)
|
|
5640
|
+
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event, chipInput)">
|
|
5524
5641
|
@if (filteredOption$ | async; as filteredOption) {
|
|
5525
5642
|
@if (filteredOption.loading) {
|
|
5526
5643
|
<mat-option disabled>
|
|
5527
5644
|
<div class="loadingSelect">
|
|
5528
5645
|
{{ intl.loading }}...
|
|
5529
|
-
|
|
5646
|
+
|
|
5647
|
+
<mat-spinner class="spinner" diameter="20" />
|
|
5530
5648
|
</div>
|
|
5531
5649
|
</mat-option>
|
|
5532
5650
|
} @else {
|
|
5533
5651
|
@for (item of filteredOption.options; track item) {
|
|
5534
|
-
<mat-option [value]="item" [disabled]="item?.disabled">
|
|
5652
|
+
<mat-option [value]="item" [disabled]="item?.disabled">
|
|
5653
|
+
{{ displayValue(item) | klesTransform: field.pipeTransform }}
|
|
5654
|
+
</mat-option>
|
|
5535
5655
|
}
|
|
5536
5656
|
}
|
|
5537
5657
|
}
|
|
5538
5658
|
</mat-autocomplete>
|
|
5539
5659
|
|
|
5540
|
-
<mat-error matErrorMessage [validations]="field.validations" [asyncValidations]="field.asyncValidations"
|
|
5660
|
+
<mat-error matErrorMessage [validations]="field.validations" [asyncValidations]="field.asyncValidations" />
|
|
5541
5661
|
</mat-form-field>
|
|
5542
|
-
`, standalone: true, imports: [
|
|
5662
|
+
`, standalone: true, imports: [AsyncPipe, KlesTransformPipe, MatAutocompleteModule, MatChipsModule, MatError, MatErrorMessageDirective, MatFormFieldModule, MatIconModule, MatProgressSpinnerModule, MatTooltip, ReactiveFormsModule], styles: [".suffix{display:flex;align-items:center}\n", ".field-bottom .mat-mdc-form-field-bottom-align:before{content:none!important}\n", ".loadingSelect{display:flex;flex-direction:row;justify-content:space-between;align-items:center}\n", "mat-form-field{width:100%}\n"] }]
|
|
5543
5663
|
}] });
|
|
5544
5664
|
|
|
5545
5665
|
const components = [
|