@ecodev/natural 44.0.5 → 45.0.1
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/esm2020/lib/classes/abstract-detail.mjs +39 -40
- package/esm2020/lib/classes/abstract-navigable-list.mjs +6 -2
- package/esm2020/lib/classes/rxjs.mjs +2 -1
- package/esm2020/lib/classes/validators.mjs +2 -2
- package/esm2020/lib/modules/file/abstract-file.mjs +26 -29
- package/esm2020/lib/modules/file/utils.mjs +12 -1
- package/esm2020/lib/modules/fixed-button-detail/fixed-button-detail.component.mjs +22 -9
- package/esm2020/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.component.mjs +3 -3
- package/esm2020/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.service.mjs +3 -9
- package/esm2020/lib/modules/select/select/select.component.mjs +3 -3
- package/esm2020/lib/modules/select/select-hierarchic/select-hierarchic.component.mjs +3 -3
- package/esm2020/lib/services/abstract-model.service.mjs +8 -41
- package/esm2020/lib/services/debounce.service.mjs +128 -0
- package/esm2020/lib/services/swiss-parsing-date-adapter.service.mjs +21 -13
- package/esm2020/public-api.mjs +2 -1
- package/fesm2015/ecodev-natural.mjs +257 -140
- package/fesm2015/ecodev-natural.mjs.map +1 -1
- package/fesm2020/ecodev-natural.mjs +254 -138
- package/fesm2020/ecodev-natural.mjs.map +1 -1
- package/lib/modules/file/abstract-file.d.ts +0 -3
- package/lib/modules/file/utils.d.ts +1 -0
- package/lib/modules/fixed-button-detail/fixed-button-detail.component.d.ts +14 -6
- package/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.component.d.ts +5 -6
- package/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.service.d.ts +5 -14
- package/lib/services/abstract-model.service.d.ts +4 -6
- package/lib/services/debounce.service.d.ts +46 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import '@angular/localize/init';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { Directive, Component, Inject, Injectable, HostBinding, HostListener, InjectionToken, Input, NgModule, EventEmitter, ChangeDetectionStrategy, Output, ContentChildren, Pipe, TemplateRef, ViewEncapsulation, ViewChild, Injector, Optional, Self, ContentChild, createEnvironmentInjector, createComponent, PLATFORM_ID, ErrorHandler } from '@angular/core';
|
|
4
|
-
import { Subject, BehaviorSubject, of, timer, EMPTY, Observable, first as first$1, combineLatest, ReplaySubject, forkJoin, merge as merge$1,
|
|
4
|
+
import { Subject, BehaviorSubject, of, timer, switchMap as switchMap$1, endWith, last, EMPTY, Observable, first as first$1, combineLatest, ReplaySubject, debounceTime as debounceTime$1, raceWith, take as take$1, mergeMap, shareReplay as shareReplay$1, catchError, forkJoin, map as map$1, merge as merge$1, tap as tap$1, asyncScheduler } from 'rxjs';
|
|
5
5
|
import * as i3 from '@angular/forms';
|
|
6
6
|
import { FormGroup, FormArray, Validators, UntypedFormGroup, UntypedFormArray, UntypedFormControl, FormsModule, FormControl, FormControlDirective, FormControlName, ReactiveFormsModule } from '@angular/forms';
|
|
7
7
|
import * as i2$1 from '@angular/router';
|
|
@@ -13,7 +13,7 @@ import * as i4 from '@angular/material/button';
|
|
|
13
13
|
import { MatButtonModule } from '@angular/material/button';
|
|
14
14
|
import * as i2 from '@angular/material/snack-bar';
|
|
15
15
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
16
|
-
import { switchMap,
|
|
16
|
+
import { switchMap, first, map, filter, finalize, takeUntil, take, tap, takeWhile, debounceTime, shareReplay, startWith, distinctUntilChanged, throttleTime } from 'rxjs/operators';
|
|
17
17
|
import * as i7$2 from '@angular/material/table';
|
|
18
18
|
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
|
19
19
|
import { DataSource, SelectionModel } from '@angular/cdk/collections';
|
|
@@ -2121,7 +2121,7 @@ function unique(fieldName, excludedId, modelService) {
|
|
|
2121
2121
|
};
|
|
2122
2122
|
const qvm = new NaturalQueryVariablesManager();
|
|
2123
2123
|
qvm.set('variables', variables);
|
|
2124
|
-
return timer(500).pipe(switchMap(() => modelService.count(qvm).pipe(map(count => (count > 0 ? { duplicateValue: count } : null)))));
|
|
2124
|
+
return timer(500).pipe(switchMap(() => modelService.count(qvm).pipe(first(), map(count => (count > 0 ? { duplicateValue: count } : null)))));
|
|
2125
2125
|
};
|
|
2126
2126
|
}
|
|
2127
2127
|
/**
|
|
@@ -2346,51 +2346,50 @@ class NaturalAbstractDetail extends NaturalAbstractPanel {
|
|
|
2346
2346
|
this.form.disable();
|
|
2347
2347
|
this.service
|
|
2348
2348
|
.create(this.data.model)
|
|
2349
|
-
.pipe(
|
|
2350
|
-
.subscribe(model => {
|
|
2349
|
+
.pipe(switchMap$1(model => {
|
|
2351
2350
|
this.alertService.info($localize `Créé`);
|
|
2352
2351
|
this.form.patchValue(model);
|
|
2353
|
-
this.postCreate(model).
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2352
|
+
return this.postCreate(model).pipe(endWith(model), last());
|
|
2353
|
+
}), switchMap$1(model => {
|
|
2354
|
+
if (redirect) {
|
|
2355
|
+
if (this.isPanel) {
|
|
2356
|
+
const oldUrl = this.router.url;
|
|
2357
|
+
const nextUrl = this.panelData?.config.params.nextRoute;
|
|
2358
|
+
const newUrl = oldUrl.replace('/new', '/' + model.id) + (nextUrl ? '/' + nextUrl : '');
|
|
2359
|
+
return this.router.navigateByUrl(newUrl); // replace /new by /123
|
|
2360
|
+
}
|
|
2361
|
+
else {
|
|
2362
|
+
return this.router.navigate(['..', model.id], { relativeTo: this.route });
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
return EMPTY;
|
|
2366
|
+
}), finalize(() => this.form.enable()))
|
|
2367
|
+
.subscribe();
|
|
2369
2368
|
}
|
|
2370
2369
|
delete(redirectionRoute) {
|
|
2370
|
+
this.form.disable();
|
|
2371
2371
|
this.alertService
|
|
2372
2372
|
.confirm($localize `Suppression`, $localize `Voulez-vous supprimer définitivement cet élément ?`, $localize `Supprimer définitivement`)
|
|
2373
|
-
.
|
|
2374
|
-
if (confirmed) {
|
|
2375
|
-
|
|
2376
|
-
this.form.disable();
|
|
2377
|
-
this.service
|
|
2378
|
-
.delete([this.data.model])
|
|
2379
|
-
.pipe(finalize(() => this.form.enable()))
|
|
2380
|
-
.subscribe(() => {
|
|
2381
|
-
this.alertService.info($localize `Supprimé`);
|
|
2382
|
-
if (!this.isPanel) {
|
|
2383
|
-
const defaultRoute = ['../../' + kebabCase(this.key)];
|
|
2384
|
-
this.router.navigate(redirectionRoute ? redirectionRoute : defaultRoute, {
|
|
2385
|
-
relativeTo: this.route,
|
|
2386
|
-
});
|
|
2387
|
-
}
|
|
2388
|
-
else {
|
|
2389
|
-
this.panelService?.goToPenultimatePanel();
|
|
2390
|
-
}
|
|
2391
|
-
});
|
|
2373
|
+
.pipe(switchMap$1(confirmed => {
|
|
2374
|
+
if (!confirmed) {
|
|
2375
|
+
return EMPTY;
|
|
2392
2376
|
}
|
|
2393
|
-
|
|
2377
|
+
this.preDelete(this.data.model);
|
|
2378
|
+
return this.service.delete([this.data.model]).pipe(switchMap$1(() => {
|
|
2379
|
+
this.alertService.info($localize `Supprimé`);
|
|
2380
|
+
if (this.isPanel) {
|
|
2381
|
+
this.panelService?.goToPenultimatePanel();
|
|
2382
|
+
return EMPTY;
|
|
2383
|
+
}
|
|
2384
|
+
else {
|
|
2385
|
+
const defaultRoute = ['../../' + kebabCase(this.key)];
|
|
2386
|
+
return this.router.navigate(redirectionRoute ? redirectionRoute : defaultRoute, {
|
|
2387
|
+
relativeTo: this.route,
|
|
2388
|
+
});
|
|
2389
|
+
}
|
|
2390
|
+
}));
|
|
2391
|
+
}), finalize(() => this.form.enable()))
|
|
2392
|
+
.subscribe();
|
|
2394
2393
|
}
|
|
2395
2394
|
postUpdate(model) { }
|
|
2396
2395
|
/**
|
|
@@ -3424,7 +3423,10 @@ class NaturalAbstractNavigableList extends NaturalAbstractList {
|
|
|
3424
3423
|
const variables = { filter: { groups: [{ conditions: [condition] }] } };
|
|
3425
3424
|
const qvm = new NaturalQueryVariablesManager();
|
|
3426
3425
|
qvm.set('variables', variables);
|
|
3427
|
-
this.service
|
|
3426
|
+
this.service
|
|
3427
|
+
.count(qvm)
|
|
3428
|
+
.pipe(first$1())
|
|
3429
|
+
.subscribe(count => (navigableItem.hasNavigation = count > 0));
|
|
3428
3430
|
return navigableItem;
|
|
3429
3431
|
});
|
|
3430
3432
|
const navigableResult = {
|
|
@@ -3553,6 +3555,7 @@ function cancellableTimeout(canceller, milliSeconds = 0) {
|
|
|
3553
3555
|
function debug(debugName) {
|
|
3554
3556
|
return tap({
|
|
3555
3557
|
subscribe: () => console.log('SUBSCRIBE', debugName),
|
|
3558
|
+
unsubscribe: () => console.log('UNSUBSCRIBE', debugName),
|
|
3556
3559
|
next: value => console.log('NEXT', debugName, value),
|
|
3557
3560
|
error: error => console.log('ERROR', debugName, error),
|
|
3558
3561
|
complete: () => console.log('COMPLETE', debugName),
|
|
@@ -3560,18 +3563,15 @@ function debug(debugName) {
|
|
|
3560
3563
|
}
|
|
3561
3564
|
|
|
3562
3565
|
class NaturalAbstractModelService {
|
|
3563
|
-
constructor(apollo, name, oneQuery, allQuery, createMutation, updateMutation, deleteMutation) {
|
|
3566
|
+
constructor(apollo, naturalDebounceService, name, oneQuery, allQuery, createMutation, updateMutation, deleteMutation) {
|
|
3564
3567
|
this.apollo = apollo;
|
|
3568
|
+
this.naturalDebounceService = naturalDebounceService;
|
|
3565
3569
|
this.name = name;
|
|
3566
3570
|
this.oneQuery = oneQuery;
|
|
3567
3571
|
this.allQuery = allQuery;
|
|
3568
3572
|
this.createMutation = createMutation;
|
|
3569
3573
|
this.updateMutation = updateMutation;
|
|
3570
3574
|
this.deleteMutation = deleteMutation;
|
|
3571
|
-
/**
|
|
3572
|
-
* Stores the debounced update function
|
|
3573
|
-
*/
|
|
3574
|
-
this.debouncedUpdateCache = new Map();
|
|
3575
3575
|
/**
|
|
3576
3576
|
* Store the creation mutations that are pending
|
|
3577
3577
|
*/
|
|
@@ -3803,36 +3803,7 @@ class NaturalAbstractModelService {
|
|
|
3803
3803
|
this.throwIfNotQuery(this.updateMutation);
|
|
3804
3804
|
// Keep a single instance of the debounced update function
|
|
3805
3805
|
const id = object.id;
|
|
3806
|
-
|
|
3807
|
-
if (!debounced) {
|
|
3808
|
-
const source = new ReplaySubject(1);
|
|
3809
|
-
let wasCancelled = false;
|
|
3810
|
-
const canceller = new Subject();
|
|
3811
|
-
canceller.subscribe(() => {
|
|
3812
|
-
wasCancelled = true;
|
|
3813
|
-
source.complete();
|
|
3814
|
-
canceller.complete();
|
|
3815
|
-
});
|
|
3816
|
-
// Create debounced update function
|
|
3817
|
-
const result = source.pipe(debounceTime(2000), // Wait 2sec.
|
|
3818
|
-
take(1), mergeMap(() => {
|
|
3819
|
-
this.debouncedUpdateCache.delete(id);
|
|
3820
|
-
if (wasCancelled) {
|
|
3821
|
-
return EMPTY;
|
|
3822
|
-
}
|
|
3823
|
-
return this.updateNow(object);
|
|
3824
|
-
}), shareReplay());
|
|
3825
|
-
debounced = {
|
|
3826
|
-
source,
|
|
3827
|
-
canceller,
|
|
3828
|
-
result,
|
|
3829
|
-
};
|
|
3830
|
-
this.debouncedUpdateCache.set(id, debounced);
|
|
3831
|
-
}
|
|
3832
|
-
// Notify our debounced update each time we ask to update
|
|
3833
|
-
debounced.source.next();
|
|
3834
|
-
// Return and observable that is updated when mutation is done
|
|
3835
|
-
return debounced.result;
|
|
3806
|
+
return this.naturalDebounceService.debounce(this, id, this.updateNow(object));
|
|
3836
3807
|
}
|
|
3837
3808
|
/**
|
|
3838
3809
|
* Update an object immediately when subscribing
|
|
@@ -3884,8 +3855,7 @@ class NaturalAbstractModelService {
|
|
|
3884
3855
|
this.throwIfNotQuery(this.deleteMutation);
|
|
3885
3856
|
const ids = objects.map(o => {
|
|
3886
3857
|
// Cancel pending update
|
|
3887
|
-
|
|
3888
|
-
debounced?.canceller.next();
|
|
3858
|
+
this.naturalDebounceService.cancel(this, o.id);
|
|
3889
3859
|
return o.id;
|
|
3890
3860
|
});
|
|
3891
3861
|
const variables = merge({
|
|
@@ -3933,7 +3903,7 @@ class NaturalAbstractModelService {
|
|
|
3933
3903
|
return input;
|
|
3934
3904
|
}
|
|
3935
3905
|
/**
|
|
3936
|
-
* Return the number of objects matching the query
|
|
3906
|
+
* Return the number of objects matching the query. It may never complete.
|
|
3937
3907
|
*
|
|
3938
3908
|
* This is used for the unique validator
|
|
3939
3909
|
*/
|
|
@@ -4066,6 +4036,131 @@ class NaturalAbstractModelService {
|
|
|
4066
4036
|
}
|
|
4067
4037
|
}
|
|
4068
4038
|
|
|
4039
|
+
/**
|
|
4040
|
+
* Debounce subscriptions to observable, with possibility to cancel one, or flush all of them. Typically,
|
|
4041
|
+
* observables are object updates, so `NaturalAbstractModelService.updateNow()`.
|
|
4042
|
+
*
|
|
4043
|
+
* `key` must be an instance of `NaturalAbstractModelService` to separate objects by their types. So User with ID 1 is
|
|
4044
|
+
* not confused with Product with ID 1. It has no other purpose.
|
|
4045
|
+
*
|
|
4046
|
+
* `id` should be the ID of the object that will be updated.
|
|
4047
|
+
*/
|
|
4048
|
+
class NaturalDebounceService {
|
|
4049
|
+
constructor() {
|
|
4050
|
+
this.flusher = new Subject();
|
|
4051
|
+
/**
|
|
4052
|
+
* Stores the debounced update function
|
|
4053
|
+
*/
|
|
4054
|
+
this.allDebouncedUpdateCache = new Map();
|
|
4055
|
+
}
|
|
4056
|
+
/**
|
|
4057
|
+
* Debounce the given source observable for a short time. If called multiple times with the same key and id,
|
|
4058
|
+
* it will postpone the subscription to the source observable.
|
|
4059
|
+
*
|
|
4060
|
+
* Giving the same key and id but a different source observable will replace the original observable, but
|
|
4061
|
+
* keep the same debouncing timeline.
|
|
4062
|
+
*/
|
|
4063
|
+
debounce(key, id, source) {
|
|
4064
|
+
const debouncedUpdateCache = this.getMap(key);
|
|
4065
|
+
let debounced = debouncedUpdateCache.get(id);
|
|
4066
|
+
if (debounced) {
|
|
4067
|
+
debounced.source = source;
|
|
4068
|
+
}
|
|
4069
|
+
else {
|
|
4070
|
+
const debouncer = new ReplaySubject(1);
|
|
4071
|
+
let wasCancelled = false;
|
|
4072
|
+
const canceller = new Subject();
|
|
4073
|
+
canceller.subscribe(() => {
|
|
4074
|
+
wasCancelled = true;
|
|
4075
|
+
debouncer.complete();
|
|
4076
|
+
canceller.complete();
|
|
4077
|
+
this.delete(key, id);
|
|
4078
|
+
});
|
|
4079
|
+
debounced = {
|
|
4080
|
+
debouncer,
|
|
4081
|
+
canceller,
|
|
4082
|
+
source,
|
|
4083
|
+
result: debouncer.pipe(debounceTime$1(2000), // Wait 2 seconds...
|
|
4084
|
+
raceWith(this.flusher), // ...unless flusher is triggered
|
|
4085
|
+
take$1(1), mergeMap(() => {
|
|
4086
|
+
this.delete(key, id);
|
|
4087
|
+
if (wasCancelled || !debounced) {
|
|
4088
|
+
return EMPTY;
|
|
4089
|
+
}
|
|
4090
|
+
return debounced.source;
|
|
4091
|
+
}), shareReplay$1()),
|
|
4092
|
+
};
|
|
4093
|
+
debouncedUpdateCache.set(id, debounced);
|
|
4094
|
+
}
|
|
4095
|
+
// Notify our debounced update each time we ask to update
|
|
4096
|
+
debounced.debouncer.next();
|
|
4097
|
+
// Return and observable that is updated when mutation is done
|
|
4098
|
+
return debounced.result;
|
|
4099
|
+
}
|
|
4100
|
+
cancel(key, id) {
|
|
4101
|
+
const debounced = this.allDebouncedUpdateCache.get(key)?.get(id);
|
|
4102
|
+
debounced?.canceller.next();
|
|
4103
|
+
}
|
|
4104
|
+
/**
|
|
4105
|
+
* Immediately execute all pending updates.
|
|
4106
|
+
*
|
|
4107
|
+
* It should typically be called before login out.
|
|
4108
|
+
*
|
|
4109
|
+
* The returned observable will complete when all updates complete, even if some of them error.
|
|
4110
|
+
*/
|
|
4111
|
+
flush() {
|
|
4112
|
+
const all = [];
|
|
4113
|
+
this.allDebouncedUpdateCache.forEach(map => map.forEach(debounced => {
|
|
4114
|
+
all.push(debounced.result.pipe(catchError(() => of(undefined))));
|
|
4115
|
+
}));
|
|
4116
|
+
if (!all.length) {
|
|
4117
|
+
all.push(of(undefined));
|
|
4118
|
+
}
|
|
4119
|
+
return new Observable(subscriber => {
|
|
4120
|
+
const subscription = forkJoin(all)
|
|
4121
|
+
.pipe(map$1(() => undefined))
|
|
4122
|
+
.subscribe(subscriber);
|
|
4123
|
+
// Flush only after subscription process is finished
|
|
4124
|
+
this.flusher.next();
|
|
4125
|
+
return subscription;
|
|
4126
|
+
});
|
|
4127
|
+
}
|
|
4128
|
+
/**
|
|
4129
|
+
* Count of pending updates
|
|
4130
|
+
*/
|
|
4131
|
+
get count() {
|
|
4132
|
+
let count = 0;
|
|
4133
|
+
this.allDebouncedUpdateCache.forEach(map => (count += map.size));
|
|
4134
|
+
return count;
|
|
4135
|
+
}
|
|
4136
|
+
getMap(key) {
|
|
4137
|
+
let debouncedUpdateCache = this.allDebouncedUpdateCache.get(key);
|
|
4138
|
+
if (!debouncedUpdateCache) {
|
|
4139
|
+
debouncedUpdateCache = new Map();
|
|
4140
|
+
this.allDebouncedUpdateCache.set(key, debouncedUpdateCache);
|
|
4141
|
+
}
|
|
4142
|
+
return debouncedUpdateCache;
|
|
4143
|
+
}
|
|
4144
|
+
delete(key, id) {
|
|
4145
|
+
const map = this.allDebouncedUpdateCache.get(key);
|
|
4146
|
+
if (!map) {
|
|
4147
|
+
return;
|
|
4148
|
+
}
|
|
4149
|
+
map.delete(id);
|
|
4150
|
+
if (!map.size) {
|
|
4151
|
+
this.allDebouncedUpdateCache.delete(key);
|
|
4152
|
+
}
|
|
4153
|
+
}
|
|
4154
|
+
}
|
|
4155
|
+
NaturalDebounceService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDebounceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4156
|
+
NaturalDebounceService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDebounceService, providedIn: 'root' });
|
|
4157
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDebounceService, decorators: [{
|
|
4158
|
+
type: Injectable,
|
|
4159
|
+
args: [{
|
|
4160
|
+
providedIn: 'root',
|
|
4161
|
+
}]
|
|
4162
|
+
}] });
|
|
4163
|
+
|
|
4069
4164
|
const enumTypeQuery = gql `
|
|
4070
4165
|
query EnumType($name: String!) {
|
|
4071
4166
|
__type(name: $name) {
|
|
@@ -4273,6 +4368,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
|
|
|
4273
4368
|
}]
|
|
4274
4369
|
}], ctorParameters: function () { return [{ type: i1$1.Apollo }]; } });
|
|
4275
4370
|
|
|
4371
|
+
const patterns = [
|
|
4372
|
+
/^(?<day>\d{1,2})\.(?<month>\d{1,2})\.(?<year>\d{4}|\d{2})$/,
|
|
4373
|
+
/^(?<day>\d{1,2})-(?<month>\d{1,2})-(?<year>\d{4}|\d{2})$/,
|
|
4374
|
+
/^(?<day>\d{1,2})\/(?<month>\d{1,2})\/(?<year>\d{4}|\d{2})$/,
|
|
4375
|
+
/^(?<day>\d{1,2})\\(?<month>\d{1,2})\\(?<year>\d{4}|\d{2})$/,
|
|
4376
|
+
// strict ISO format
|
|
4377
|
+
/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/,
|
|
4378
|
+
];
|
|
4276
4379
|
class NaturalSwissParsingDateAdapter extends NativeDateAdapter {
|
|
4277
4380
|
/**
|
|
4278
4381
|
* Parse commonly accepted swiss format, such as:
|
|
@@ -4286,24 +4389,24 @@ class NaturalSwissParsingDateAdapter extends NativeDateAdapter {
|
|
|
4286
4389
|
return new Date(value);
|
|
4287
4390
|
}
|
|
4288
4391
|
if (typeof value === 'string') {
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4392
|
+
const trimmed = value.trim();
|
|
4393
|
+
for (const pattern of patterns) {
|
|
4394
|
+
const m = trimmed.match(pattern);
|
|
4395
|
+
if (m?.groups) {
|
|
4396
|
+
const year = +m.groups.year;
|
|
4397
|
+
const month = +m.groups.month;
|
|
4398
|
+
const day = +m.groups.day;
|
|
4399
|
+
return this.createDateIfValid(year, month, day);
|
|
4295
4400
|
}
|
|
4296
|
-
return this.createDateIfValid(year, +m[2], +m[1]);
|
|
4297
|
-
}
|
|
4298
|
-
// Attempt strict ISO format
|
|
4299
|
-
m = value.match(/(\d{4})-(\d{2})-(\d{2})/);
|
|
4300
|
-
if (m) {
|
|
4301
|
-
return this.createDateIfValid(+m[1], +m[2], +m[3]);
|
|
4302
4401
|
}
|
|
4303
4402
|
}
|
|
4304
4403
|
return null;
|
|
4305
4404
|
}
|
|
4306
4405
|
createDateIfValid(year, month, date) {
|
|
4406
|
+
// Assume year 2000 if only two digits
|
|
4407
|
+
if (year < 100) {
|
|
4408
|
+
year += 2000;
|
|
4409
|
+
}
|
|
4307
4410
|
month = month - 1;
|
|
4308
4411
|
if (month >= 0 && month <= 11 && date >= 1 && date <= 31) {
|
|
4309
4412
|
return this.createDate(year, month, date);
|
|
@@ -5948,10 +6051,10 @@ class NaturalSelectComponent extends AbstractSelect {
|
|
|
5948
6051
|
}
|
|
5949
6052
|
}
|
|
5950
6053
|
NaturalSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
5951
|
-
NaturalSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSelectComponent, selector: "natural-select", inputs: { service: "service", optionRequired: "optionRequired", searchField: "searchField", filter: "filter", disabled: "disabled" }, queries: [{ propertyName: "itemTemplate", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "autoTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true }], usesInheritance: true, ngImport: i0, template: "<!-- Autocomplete menu -->\n<mat-autocomplete\n #ac=\"matAutocomplete\"\n (optionSelected)=\"propagateValue($event.option.value)\"\n [displayWith]=\"getDisplayFn()\"\n panelWidth=\"auto !important\"\n>\n <mat-option *ngFor=\"let item of items | async\" [value]=\"item\">\n <ng-template\n [ngTemplateOutletContext]=\"{item: item}\"\n [ngTemplateOutlet]=\"itemTemplate ? itemTemplate : defaultACItem\"\n ></ng-template>\n </mat-option>\n <div *ngIf=\"moreNbItems > 0\" class=\"mat-caption\" i18n style=\"padding: 5px 10px\"\n >{{ moreNbItems }} \u00E9l\u00E9ment(s) suppl\u00E9mentaire(s)</div\n >\n</mat-autocomplete>\n\n<ng-template #defaultACItem let-item=\"item\">\n <span>{{ getDisplayFn()(item) }}</span>\n</ng-template>\n\n<!-- Input for autocomplete -->\n<mat-form-field [floatLabel]=\"floatPlaceholder\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <input\n (blur)=\"touch(); blur.emit()\"\n (change)=\"onInternalFormChange()\"\n (click)=\"autoTrigger.openPanel()\"\n (focus)=\"startSearch()\"\n (keydown.esc)=\"clear()\"\n [formControl]=\"internalCtrl\"\n [matAutocomplete]=\"ac\"\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n [errorStateMatcher]=\"matcher\"\n />\n\n <!-- Meta data -->\n <natural-icon *ngIf=\"!loading && showIcon\" [name]=\"icon\" matPrefix></natural-icon>\n <mat-progress-spinner\n *ngIf=\"loading\"\n [diameter]=\"21\"\n [strokeWidth]=\"5\"\n matPrefix\n mode=\"indeterminate\"\n ></mat-progress-spinner>\n\n <!-- Clear button -->\n <div class=\"suffix-buttons\" matSuffix>\n <button\n (click)=\"clear(); $event.stopPropagation()\"\n *ngIf=\"internalCtrl.value && internalCtrl.enabled && !clearLabel\"\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"D\u00E9s\u00E9lectionner\"\n >\n <natural-icon name=\"close\"></natural-icon>\n </button>\n <button\n *ngIf=\"internalCtrl.value && navigateTo\"\n [routerLink]=\"navigateTo\"\n mat-button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n >\n <natural-icon name=\"open_in_browser\"></natural-icon>\n </button>\n </div>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error>\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n<div *ngIf=\"showClearButton()\" class=\"external-buttons\">\n <button (click)=\"clear()\" *ngIf=\"showClearButton()\" color=\"warn\" mat-button>{{ clearLabel }}</button>\n</div>\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host>mat-autocomplete{margin-bottom:0!important}:host .suffix-buttons,:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}\n"], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$3.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i2$3.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i1$7.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }] });
|
|
6054
|
+
NaturalSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSelectComponent, selector: "natural-select", inputs: { service: "service", optionRequired: "optionRequired", searchField: "searchField", filter: "filter", disabled: "disabled" }, queries: [{ propertyName: "itemTemplate", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "autoTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true }], usesInheritance: true, ngImport: i0, template: "<!-- Autocomplete menu -->\n<mat-autocomplete\n #ac=\"matAutocomplete\"\n (optionSelected)=\"propagateValue($event.option.value)\"\n [displayWith]=\"getDisplayFn()\"\n panelWidth=\"auto !important\"\n>\n <mat-option *ngFor=\"let item of items | async\" [value]=\"item\">\n <ng-template\n [ngTemplateOutletContext]=\"{item: item}\"\n [ngTemplateOutlet]=\"itemTemplate ? itemTemplate : defaultACItem\"\n ></ng-template>\n </mat-option>\n <div *ngIf=\"moreNbItems > 0\" class=\"mat-caption\" i18n style=\"padding: 5px 10px\"\n >{{ moreNbItems }} \u00E9l\u00E9ment(s) suppl\u00E9mentaire(s)</div\n >\n</mat-autocomplete>\n\n<ng-template #defaultACItem let-item=\"item\">\n <span>{{ getDisplayFn()(item) }}</span>\n</ng-template>\n\n<!-- Input for autocomplete -->\n<mat-form-field [floatLabel]=\"floatPlaceholder\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <input\n (blur)=\"touch(); blur.emit()\"\n (change)=\"onInternalFormChange()\"\n (click)=\"autoTrigger.openPanel()\"\n (focus)=\"startSearch()\"\n (keydown.esc)=\"clear()\"\n [formControl]=\"internalCtrl\"\n [matAutocomplete]=\"ac\"\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n [errorStateMatcher]=\"matcher\"\n />\n\n <!-- Meta data -->\n <natural-icon *ngIf=\"!loading && showIcon\" [name]=\"icon\" matPrefix></natural-icon>\n <mat-progress-spinner\n *ngIf=\"loading\"\n [diameter]=\"21\"\n [strokeWidth]=\"5\"\n matPrefix\n mode=\"indeterminate\"\n ></mat-progress-spinner>\n\n <!-- Clear button -->\n <div class=\"suffix-buttons\" matSuffix>\n <button\n (click)=\"clear(); $event.stopPropagation()\"\n *ngIf=\"internalCtrl.value && internalCtrl.enabled && !clearLabel\"\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"D\u00E9s\u00E9lectionner\"\n >\n <natural-icon name=\"close\"></natural-icon>\n </button>\n <button\n *ngIf=\"internalCtrl.value && navigateTo\"\n [routerLink]=\"navigateTo\"\n (click)=\"$event.stopPropagation()\"\n mat-button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n >\n <natural-icon name=\"open_in_browser\"></natural-icon>\n </button>\n </div>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error>\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n<div *ngIf=\"showClearButton()\" class=\"external-buttons\">\n <button (click)=\"clear()\" *ngIf=\"showClearButton()\" color=\"warn\" mat-button>{{ clearLabel }}</button>\n</div>\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host>mat-autocomplete{margin-bottom:0!important}:host .suffix-buttons,:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}\n"], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$3.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i2$3.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: i1$7.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }] });
|
|
5952
6055
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectComponent, decorators: [{
|
|
5953
6056
|
type: Component,
|
|
5954
|
-
args: [{ selector: 'natural-select', template: "<!-- Autocomplete menu -->\n<mat-autocomplete\n #ac=\"matAutocomplete\"\n (optionSelected)=\"propagateValue($event.option.value)\"\n [displayWith]=\"getDisplayFn()\"\n panelWidth=\"auto !important\"\n>\n <mat-option *ngFor=\"let item of items | async\" [value]=\"item\">\n <ng-template\n [ngTemplateOutletContext]=\"{item: item}\"\n [ngTemplateOutlet]=\"itemTemplate ? itemTemplate : defaultACItem\"\n ></ng-template>\n </mat-option>\n <div *ngIf=\"moreNbItems > 0\" class=\"mat-caption\" i18n style=\"padding: 5px 10px\"\n >{{ moreNbItems }} \u00E9l\u00E9ment(s) suppl\u00E9mentaire(s)</div\n >\n</mat-autocomplete>\n\n<ng-template #defaultACItem let-item=\"item\">\n <span>{{ getDisplayFn()(item) }}</span>\n</ng-template>\n\n<!-- Input for autocomplete -->\n<mat-form-field [floatLabel]=\"floatPlaceholder\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <input\n (blur)=\"touch(); blur.emit()\"\n (change)=\"onInternalFormChange()\"\n (click)=\"autoTrigger.openPanel()\"\n (focus)=\"startSearch()\"\n (keydown.esc)=\"clear()\"\n [formControl]=\"internalCtrl\"\n [matAutocomplete]=\"ac\"\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n [errorStateMatcher]=\"matcher\"\n />\n\n <!-- Meta data -->\n <natural-icon *ngIf=\"!loading && showIcon\" [name]=\"icon\" matPrefix></natural-icon>\n <mat-progress-spinner\n *ngIf=\"loading\"\n [diameter]=\"21\"\n [strokeWidth]=\"5\"\n matPrefix\n mode=\"indeterminate\"\n ></mat-progress-spinner>\n\n <!-- Clear button -->\n <div class=\"suffix-buttons\" matSuffix>\n <button\n (click)=\"clear(); $event.stopPropagation()\"\n *ngIf=\"internalCtrl.value && internalCtrl.enabled && !clearLabel\"\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"D\u00E9s\u00E9lectionner\"\n >\n <natural-icon name=\"close\"></natural-icon>\n </button>\n <button\n *ngIf=\"internalCtrl.value && navigateTo\"\n [routerLink]=\"navigateTo\"\n mat-button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n >\n <natural-icon name=\"open_in_browser\"></natural-icon>\n </button>\n </div>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error>\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n<div *ngIf=\"showClearButton()\" class=\"external-buttons\">\n <button (click)=\"clear()\" *ngIf=\"showClearButton()\" color=\"warn\" mat-button>{{ clearLabel }}</button>\n</div>\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host>mat-autocomplete{margin-bottom:0!important}:host .suffix-buttons,:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}\n"] }]
|
|
6057
|
+
args: [{ selector: 'natural-select', template: "<!-- Autocomplete menu -->\n<mat-autocomplete\n #ac=\"matAutocomplete\"\n (optionSelected)=\"propagateValue($event.option.value)\"\n [displayWith]=\"getDisplayFn()\"\n panelWidth=\"auto !important\"\n>\n <mat-option *ngFor=\"let item of items | async\" [value]=\"item\">\n <ng-template\n [ngTemplateOutletContext]=\"{item: item}\"\n [ngTemplateOutlet]=\"itemTemplate ? itemTemplate : defaultACItem\"\n ></ng-template>\n </mat-option>\n <div *ngIf=\"moreNbItems > 0\" class=\"mat-caption\" i18n style=\"padding: 5px 10px\"\n >{{ moreNbItems }} \u00E9l\u00E9ment(s) suppl\u00E9mentaire(s)</div\n >\n</mat-autocomplete>\n\n<ng-template #defaultACItem let-item=\"item\">\n <span>{{ getDisplayFn()(item) }}</span>\n</ng-template>\n\n<!-- Input for autocomplete -->\n<mat-form-field [floatLabel]=\"floatPlaceholder\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <input\n (blur)=\"touch(); blur.emit()\"\n (change)=\"onInternalFormChange()\"\n (click)=\"autoTrigger.openPanel()\"\n (focus)=\"startSearch()\"\n (keydown.esc)=\"clear()\"\n [formControl]=\"internalCtrl\"\n [matAutocomplete]=\"ac\"\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n [errorStateMatcher]=\"matcher\"\n />\n\n <!-- Meta data -->\n <natural-icon *ngIf=\"!loading && showIcon\" [name]=\"icon\" matPrefix></natural-icon>\n <mat-progress-spinner\n *ngIf=\"loading\"\n [diameter]=\"21\"\n [strokeWidth]=\"5\"\n matPrefix\n mode=\"indeterminate\"\n ></mat-progress-spinner>\n\n <!-- Clear button -->\n <div class=\"suffix-buttons\" matSuffix>\n <button\n (click)=\"clear(); $event.stopPropagation()\"\n *ngIf=\"internalCtrl.value && internalCtrl.enabled && !clearLabel\"\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"D\u00E9s\u00E9lectionner\"\n >\n <natural-icon name=\"close\"></natural-icon>\n </button>\n <button\n *ngIf=\"internalCtrl.value && navigateTo\"\n [routerLink]=\"navigateTo\"\n (click)=\"$event.stopPropagation()\"\n mat-button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n >\n <natural-icon name=\"open_in_browser\"></natural-icon>\n </button>\n </div>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error>\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n<div *ngIf=\"showClearButton()\" class=\"external-buttons\">\n <button (click)=\"clear()\" *ngIf=\"showClearButton()\" color=\"warn\" mat-button>{{ clearLabel }}</button>\n</div>\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host>mat-autocomplete{margin-bottom:0!important}:host .suffix-buttons,:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}\n"] }]
|
|
5955
6058
|
}], propDecorators: { autoTrigger: [{
|
|
5956
6059
|
type: ViewChild,
|
|
5957
6060
|
args: [MatAutocompleteTrigger]
|
|
@@ -6231,7 +6334,7 @@ class NaturalHierarchicSelectorService {
|
|
|
6231
6334
|
}
|
|
6232
6335
|
countItems(node, contextFilters = null) {
|
|
6233
6336
|
const configurations = this.getContextualizedConfigs(node, contextFilters, null);
|
|
6234
|
-
const observables = configurations.map(c => c.configuration.injectedService.count(c.variablesManager));
|
|
6337
|
+
const observables = configurations.map(c => c.configuration.injectedService.count(c.variablesManager).pipe(first$1()));
|
|
6235
6338
|
forkJoin(observables).subscribe(results => {
|
|
6236
6339
|
const totalItems = results.reduce((total, length) => total + length, 0);
|
|
6237
6340
|
node.expandable = totalItems > 0;
|
|
@@ -6268,12 +6371,6 @@ class NaturalHierarchicSelectorService {
|
|
|
6268
6371
|
}
|
|
6269
6372
|
return configsAndServices;
|
|
6270
6373
|
}
|
|
6271
|
-
/**
|
|
6272
|
-
* Check configuration to return a boolean that allows or denies the selection for the given element
|
|
6273
|
-
*/
|
|
6274
|
-
isSelectable(node) {
|
|
6275
|
-
return !!node.node.config.selectableAtKey;
|
|
6276
|
-
}
|
|
6277
6374
|
/**
|
|
6278
6375
|
* Return models matching given FlatNodes
|
|
6279
6376
|
* Returns a Literal of models grouped by their configuration attribute "selectableAtKey"
|
|
@@ -6972,7 +7069,7 @@ class NaturalHierarchicSelectorComponent extends NaturalAbstractController {
|
|
|
6972
7069
|
}
|
|
6973
7070
|
else if (!this.multiple) {
|
|
6974
7071
|
if (this.flatNodesSelection.isSelected(flatNode)) {
|
|
6975
|
-
this.unselectSingleFlatNode(
|
|
7072
|
+
this.unselectSingleFlatNode();
|
|
6976
7073
|
}
|
|
6977
7074
|
else {
|
|
6978
7075
|
// If not multiple, and we want to select an element, unselect everything before to keep a single selection
|
|
@@ -7143,7 +7240,7 @@ class NaturalHierarchicSelectorComponent extends NaturalAbstractController {
|
|
|
7143
7240
|
/**
|
|
7144
7241
|
* Clear all selected and select the given node
|
|
7145
7242
|
*/
|
|
7146
|
-
unselectSingleFlatNode(
|
|
7243
|
+
unselectSingleFlatNode() {
|
|
7147
7244
|
this.flatNodesSelection.clear();
|
|
7148
7245
|
this.selectedNodes = [];
|
|
7149
7246
|
this.updateSelection(this.selectedNodes);
|
|
@@ -7822,10 +7919,10 @@ class NaturalSelectHierarchicComponent extends AbstractSelect {
|
|
|
7822
7919
|
}
|
|
7823
7920
|
}
|
|
7824
7921
|
NaturalSelectHierarchicComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectHierarchicComponent, deps: [{ token: NaturalHierarchicSelectorDialogService }, { token: i3.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
7825
|
-
NaturalSelectHierarchicComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSelectHierarchicComponent, selector: "natural-select-hierarchic", inputs: { selectLabel: "selectLabel", config: "config", filters: "filters" }, usesInheritance: true, ngImport: i0, template: "<mat-form-field [floatLabel]=\"floatPlaceholder\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <!-- Input for hierarchical selector -->\n <input\n (blur)=\"blur.emit()\"\n (focus)=\"openDialog()\"\n (keydown.esc)=\"clear()\"\n [formControl]=\"internalCtrl\"\n [errorStateMatcher]=\"matcher\"\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n />\n\n <!-- Meta data -->\n <natural-icon *ngIf=\"showIcon\" [name]=\"icon\" matPrefix></natural-icon>\n\n <!-- Clear button -->\n <div class=\"suffix-buttons\" matSuffix>\n <button\n (click)=\"clear(); $event.stopPropagation()\"\n *ngIf=\"internalCtrl.value && internalCtrl.enabled && !clearLabel\"\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"D\u00E9s\u00E9lectionner\"\n >\n <natural-icon name=\"close\"></natural-icon>\n </button>\n <button\n *ngIf=\"internalCtrl.value && navigateTo\"\n [routerLink]=\"navigateTo\"\n mat-button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n >\n <natural-icon name=\"open_in_browser\"></natural-icon>\n </button>\n </div>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error>\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n<div *ngIf=\"showSelectButton() || showClearButton()\" class=\"external-buttons\">\n <button (click)=\"openDialog()\" *ngIf=\"showSelectButton()\" color=\"primary\" mat-flat-button>{{ selectLabel }}</button>\n <button (click)=\"clear()\" *ngIf=\"showClearButton()\" color=\"warn\" mat-button>{{ clearLabel }}</button>\n</div>\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host .suffix-buttons,:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}\n"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }] });
|
|
7922
|
+
NaturalSelectHierarchicComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalSelectHierarchicComponent, selector: "natural-select-hierarchic", inputs: { selectLabel: "selectLabel", config: "config", filters: "filters" }, usesInheritance: true, ngImport: i0, template: "<mat-form-field [floatLabel]=\"floatPlaceholder\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <!-- Input for hierarchical selector -->\n <input\n (blur)=\"blur.emit()\"\n (focus)=\"openDialog()\"\n (keydown.esc)=\"clear()\"\n [formControl]=\"internalCtrl\"\n [errorStateMatcher]=\"matcher\"\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n />\n\n <!-- Meta data -->\n <natural-icon *ngIf=\"showIcon\" [name]=\"icon\" matPrefix></natural-icon>\n\n <!-- Clear button -->\n <div class=\"suffix-buttons\" matSuffix>\n <button\n (click)=\"clear(); $event.stopPropagation()\"\n *ngIf=\"internalCtrl.value && internalCtrl.enabled && !clearLabel\"\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"D\u00E9s\u00E9lectionner\"\n >\n <natural-icon name=\"close\"></natural-icon>\n </button>\n <button\n *ngIf=\"internalCtrl.value && navigateTo\"\n [routerLink]=\"navigateTo\"\n (click)=\"$event.stopPropagation()\"\n mat-button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n >\n <natural-icon name=\"open_in_browser\"></natural-icon>\n </button>\n </div>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error>\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n<div *ngIf=\"showSelectButton() || showClearButton()\" class=\"external-buttons\">\n <button (click)=\"openDialog()\" *ngIf=\"showSelectButton()\" color=\"primary\" mat-flat-button>{{ selectLabel }}</button>\n <button (click)=\"clear()\" *ngIf=\"showClearButton()\" color=\"warn\" mat-button>{{ clearLabel }}</button>\n</div>\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host .suffix-buttons,:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}\n"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4$2.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i4$2.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: NaturalIconComponent, selector: "natural-icon", inputs: ["label", "labelColor", "labelPosition", "name", "size"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }] });
|
|
7826
7923
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectHierarchicComponent, decorators: [{
|
|
7827
7924
|
type: Component,
|
|
7828
|
-
args: [{ selector: 'natural-select-hierarchic', template: "<mat-form-field [floatLabel]=\"floatPlaceholder\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <!-- Input for hierarchical selector -->\n <input\n (blur)=\"blur.emit()\"\n (focus)=\"openDialog()\"\n (keydown.esc)=\"clear()\"\n [formControl]=\"internalCtrl\"\n [errorStateMatcher]=\"matcher\"\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n />\n\n <!-- Meta data -->\n <natural-icon *ngIf=\"showIcon\" [name]=\"icon\" matPrefix></natural-icon>\n\n <!-- Clear button -->\n <div class=\"suffix-buttons\" matSuffix>\n <button\n (click)=\"clear(); $event.stopPropagation()\"\n *ngIf=\"internalCtrl.value && internalCtrl.enabled && !clearLabel\"\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"D\u00E9s\u00E9lectionner\"\n >\n <natural-icon name=\"close\"></natural-icon>\n </button>\n <button\n *ngIf=\"internalCtrl.value && navigateTo\"\n [routerLink]=\"navigateTo\"\n mat-button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n >\n <natural-icon name=\"open_in_browser\"></natural-icon>\n </button>\n </div>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error>\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n<div *ngIf=\"showSelectButton() || showClearButton()\" class=\"external-buttons\">\n <button (click)=\"openDialog()\" *ngIf=\"showSelectButton()\" color=\"primary\" mat-flat-button>{{ selectLabel }}</button>\n <button (click)=\"clear()\" *ngIf=\"showClearButton()\" color=\"warn\" mat-button>{{ clearLabel }}</button>\n</div>\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host .suffix-buttons,:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}\n"] }]
|
|
7925
|
+
args: [{ selector: 'natural-select-hierarchic', template: "<mat-form-field [floatLabel]=\"floatPlaceholder\">\n <mat-label>{{ placeholder }}</mat-label>\n\n <!-- Input for hierarchical selector -->\n <input\n (blur)=\"blur.emit()\"\n (focus)=\"openDialog()\"\n (keydown.esc)=\"clear()\"\n [formControl]=\"internalCtrl\"\n [errorStateMatcher]=\"matcher\"\n aria-label=\"Recherche et s\u00E9lection\"\n i18n-aria-label\n matInput\n />\n\n <!-- Meta data -->\n <natural-icon *ngIf=\"showIcon\" [name]=\"icon\" matPrefix></natural-icon>\n\n <!-- Clear button -->\n <div class=\"suffix-buttons\" matSuffix>\n <button\n (click)=\"clear(); $event.stopPropagation()\"\n *ngIf=\"internalCtrl.value && internalCtrl.enabled && !clearLabel\"\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"D\u00E9s\u00E9lectionner\"\n >\n <natural-icon name=\"close\"></natural-icon>\n </button>\n <button\n *ngIf=\"internalCtrl.value && navigateTo\"\n [routerLink]=\"navigateTo\"\n (click)=\"$event.stopPropagation()\"\n mat-button\n mat-icon-button\n i18n-matTooltip\n matTooltip=\"Naviguer vers\"\n >\n <natural-icon name=\"open_in_browser\"></natural-icon>\n </button>\n </div>\n\n <mat-error *ngIf=\"hasRequiredError()\" i18n>Ce champ est requis</mat-error>\n</mat-form-field>\n\n<!-- Additional (un)select/(un)link buttons for more visual cohesion with natural-relations --><!-- [clearLabel] and/or [selectLabel] has to be given as attribute input -->\n<div *ngIf=\"showSelectButton() || showClearButton()\" class=\"external-buttons\">\n <button (click)=\"openDialog()\" *ngIf=\"showSelectButton()\" color=\"primary\" mat-flat-button>{{ selectLabel }}</button>\n <button (click)=\"clear()\" *ngIf=\"showClearButton()\" color=\"warn\" mat-button>{{ clearLabel }}</button>\n</div>\n", styles: [":host{display:flex;flex-direction:column}:host>*:not(:last-child){margin-bottom:20px}:host .suffix-buttons,:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons{display:flex;flex-direction:row}:host .external-buttons>*:not(:last-child){margin-right:10px}\n"] }]
|
|
7829
7926
|
}], ctorParameters: function () { return [{ type: NaturalHierarchicSelectorDialogService }, { type: i3.NgControl, decorators: [{
|
|
7830
7927
|
type: Optional
|
|
7831
7928
|
}, {
|
|
@@ -8069,6 +8166,17 @@ function createFileInput(document) {
|
|
|
8069
8166
|
fileElem.type = 'file';
|
|
8070
8167
|
return fileElem;
|
|
8071
8168
|
}
|
|
8169
|
+
function isDirectory(file) {
|
|
8170
|
+
return file
|
|
8171
|
+
.slice(0, 1)
|
|
8172
|
+
.text()
|
|
8173
|
+
.then(text => {
|
|
8174
|
+
// Firefox will return empty string for a folder, so we must check that special case.
|
|
8175
|
+
// That means that any empty file will incorrectly be interpreted as a folder on all
|
|
8176
|
+
// browsers, but that's tolerable because there is no real use-case to upload an empty file.
|
|
8177
|
+
return text !== '';
|
|
8178
|
+
}, () => false);
|
|
8179
|
+
}
|
|
8072
8180
|
function stopEvent(event) {
|
|
8073
8181
|
event.preventDefault();
|
|
8074
8182
|
event.stopPropagation();
|
|
@@ -8164,10 +8272,6 @@ class NaturalAbstractFile extends NaturalAbstractController {
|
|
|
8164
8272
|
this.element = element;
|
|
8165
8273
|
this.naturalFileService = naturalFileService;
|
|
8166
8274
|
this.document = document;
|
|
8167
|
-
this.validators = [
|
|
8168
|
-
{ name: 'accept', fn: this.acceptValidator },
|
|
8169
|
-
{ name: 'fileSize', fn: this.fileSizeValidator },
|
|
8170
|
-
];
|
|
8171
8275
|
/**
|
|
8172
8276
|
* Whether we should accept a single file or multiple files
|
|
8173
8277
|
*/
|
|
@@ -8264,8 +8368,7 @@ class NaturalAbstractFile extends NaturalAbstractController {
|
|
|
8264
8368
|
valid: [],
|
|
8265
8369
|
invalid: [],
|
|
8266
8370
|
};
|
|
8267
|
-
|
|
8268
|
-
const error = this.validate(file);
|
|
8371
|
+
forkJoin(files.map(file => this.validate(file).pipe(tap$1(error => {
|
|
8269
8372
|
if (error) {
|
|
8270
8373
|
selection.invalid.push({
|
|
8271
8374
|
file: file,
|
|
@@ -8275,17 +8378,18 @@ class NaturalAbstractFile extends NaturalAbstractController {
|
|
|
8275
8378
|
else {
|
|
8276
8379
|
selection.valid.push(file);
|
|
8277
8380
|
}
|
|
8278
|
-
}
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
}
|
|
8282
|
-
if (selection.valid.length || selection.invalid.length) {
|
|
8283
|
-
this.filesChange.emit(selection);
|
|
8284
|
-
if (this.broadcast) {
|
|
8285
|
-
this.naturalFileService.filesChanged.next(selection);
|
|
8381
|
+
})))).subscribe(() => {
|
|
8382
|
+
if (selection.valid.length) {
|
|
8383
|
+
this.fileChange.emit(selection.valid[0]);
|
|
8286
8384
|
}
|
|
8287
|
-
|
|
8288
|
-
|
|
8385
|
+
if (selection.valid.length || selection.invalid.length) {
|
|
8386
|
+
this.filesChange.emit(selection);
|
|
8387
|
+
if (this.broadcast) {
|
|
8388
|
+
this.naturalFileService.filesChanged.next(selection);
|
|
8389
|
+
}
|
|
8390
|
+
}
|
|
8391
|
+
this.getFileElement().value = '';
|
|
8392
|
+
});
|
|
8289
8393
|
}
|
|
8290
8394
|
/**
|
|
8291
8395
|
* Called when input has files
|
|
@@ -8332,18 +8436,18 @@ class NaturalAbstractFile extends NaturalAbstractController {
|
|
|
8332
8436
|
this.handleFiles(files);
|
|
8333
8437
|
}
|
|
8334
8438
|
validate(file) {
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
|
|
8439
|
+
return forkJoin({
|
|
8440
|
+
accept: of(acceptType(this.accept, file.type, file.name)),
|
|
8441
|
+
fileSize: of(!(this.maxSize && file.size > this.maxSize)),
|
|
8442
|
+
directory: isDirectory(file),
|
|
8443
|
+
}).pipe(map$1(result => {
|
|
8444
|
+
for (const [key, value] of Object.entries(result)) {
|
|
8445
|
+
if (!value) {
|
|
8446
|
+
return key;
|
|
8447
|
+
}
|
|
8338
8448
|
}
|
|
8339
|
-
|
|
8340
|
-
|
|
8341
|
-
}
|
|
8342
|
-
acceptValidator(item) {
|
|
8343
|
-
return acceptType(this.accept, item.type, item.name);
|
|
8344
|
-
}
|
|
8345
|
-
fileSizeValidator(item) {
|
|
8346
|
-
return !(this.maxSize && item.size > this.maxSize);
|
|
8449
|
+
return null;
|
|
8450
|
+
}));
|
|
8347
8451
|
}
|
|
8348
8452
|
}
|
|
8349
8453
|
NaturalAbstractFile.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalAbstractFile, deps: [{ token: i0.ElementRef }, { token: NaturalFileService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive });
|
|
@@ -8695,9 +8799,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
|
|
|
8695
8799
|
*/
|
|
8696
8800
|
|
|
8697
8801
|
class NaturalFixedButtonDetailComponent {
|
|
8698
|
-
constructor() {
|
|
8802
|
+
constructor(route) {
|
|
8803
|
+
this.canChange = true;
|
|
8804
|
+
this.isCreation = false;
|
|
8699
8805
|
this.create = new EventEmitter();
|
|
8700
8806
|
this.delete = new EventEmitter();
|
|
8807
|
+
route.params.subscribe(() => (this.canChange = true));
|
|
8808
|
+
}
|
|
8809
|
+
get model() {
|
|
8810
|
+
return this._model;
|
|
8811
|
+
}
|
|
8812
|
+
set model(value) {
|
|
8813
|
+
this._model = value;
|
|
8814
|
+
if (this.canChange) {
|
|
8815
|
+
this.isCreation = !this._model.id;
|
|
8816
|
+
}
|
|
8701
8817
|
}
|
|
8702
8818
|
clickCreate() {
|
|
8703
8819
|
if (this.form.enabled) {
|
|
@@ -8710,12 +8826,12 @@ class NaturalFixedButtonDetailComponent {
|
|
|
8710
8826
|
}
|
|
8711
8827
|
}
|
|
8712
8828
|
}
|
|
8713
|
-
NaturalFixedButtonDetailComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalFixedButtonDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8714
|
-
NaturalFixedButtonDetailComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalFixedButtonDetailComponent, selector: "natural-fixed-button-detail", inputs: { model: "model", form: "form" }, outputs: { create: "create", delete: "delete" }, ngImport: i0, template: "<natural-fixed-button\n (click)=\"clickCreate()\"\n *ngIf=\"
|
|
8829
|
+
NaturalFixedButtonDetailComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalFixedButtonDetailComponent, deps: [{ token: i2$1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Component });
|
|
8830
|
+
NaturalFixedButtonDetailComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: NaturalFixedButtonDetailComponent, selector: "natural-fixed-button-detail", inputs: { model: "model", form: "form" }, outputs: { create: "create", delete: "delete" }, ngImport: i0, template: "<natural-fixed-button\n (click)=\"clickCreate()\"\n *ngIf=\"isCreation\"\n [disabled]=\"form.disabled\"\n [color]=\"form.valid ? 'accent' : 'warn'\"\n class=\"detail-speed-dial\"\n icon=\"save\"\n></natural-fixed-button>\n\n<natural-fixed-button\n (click)=\"clickDelete()\"\n *ngIf=\"!isCreation && (!model.permissions || model.permissions.delete)\"\n [disabled]=\"form.disabled\"\n class=\"detail-speed-dial\"\n color=\"warn\"\n icon=\"delete_forever\"\n i18n-matTooltip\n matTooltip=\"Supprimer d\u00E9finitivement\"\n matTooltipPosition=\"left\"\n></natural-fixed-button>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NaturalFixedButtonComponent, selector: "natural-fixed-button", inputs: ["icon", "link", "color", "disabled"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
|
|
8715
8831
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalFixedButtonDetailComponent, decorators: [{
|
|
8716
8832
|
type: Component,
|
|
8717
|
-
args: [{ selector: 'natural-fixed-button-detail', template: "<natural-fixed-button\n (click)=\"clickCreate()\"\n *ngIf=\"
|
|
8718
|
-
}], propDecorators: { model: [{
|
|
8833
|
+
args: [{ selector: 'natural-fixed-button-detail', template: "<natural-fixed-button\n (click)=\"clickCreate()\"\n *ngIf=\"isCreation\"\n [disabled]=\"form.disabled\"\n [color]=\"form.valid ? 'accent' : 'warn'\"\n class=\"detail-speed-dial\"\n icon=\"save\"\n></natural-fixed-button>\n\n<natural-fixed-button\n (click)=\"clickDelete()\"\n *ngIf=\"!isCreation && (!model.permissions || model.permissions.delete)\"\n [disabled]=\"form.disabled\"\n class=\"detail-speed-dial\"\n color=\"warn\"\n icon=\"delete_forever\"\n i18n-matTooltip\n matTooltip=\"Supprimer d\u00E9finitivement\"\n matTooltipPosition=\"left\"\n></natural-fixed-button>\n" }]
|
|
8834
|
+
}], ctorParameters: function () { return [{ type: i2$1.ActivatedRoute }]; }, propDecorators: { model: [{
|
|
8719
8835
|
type: Input
|
|
8720
8836
|
}], form: [{
|
|
8721
8837
|
type: Input
|
|
@@ -10842,5 +10958,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
|
|
|
10842
10958
|
* Generated bundle index. Do not edit.
|
|
10843
10959
|
*/
|
|
10844
10960
|
|
|
10845
|
-
export { AvatarComponent, AvatarService, FileComponent, IconsConfigService, LOCAL_STORAGE, NATURAL_DROPDOWN_DATA, NATURAL_SEO_CONFIG, NaturalAbstractController, NaturalAbstractDetail, NaturalAbstractEditableList, NaturalAbstractList, NaturalAbstractModelService, NaturalAbstractNavigableList, NaturalAbstractPanel, NaturalAlertModule, NaturalAlertService, NaturalAvatarModule, NaturalCapitalizePipe, NaturalColumnsPickerColumnDirective, NaturalColumnsPickerComponent, NaturalColumnsPickerModule, NaturalCommonModule, NaturalConfirmComponent, NaturalDataSource, NaturalDetailHeaderComponent, NaturalDetailHeaderModule, NaturalDialogTriggerComponent, NaturalDialogTriggerModule, NaturalDropdownComponentsModule, NaturalDropdownRef, NaturalEllipsisPipe, NaturalEnumPipe, NaturalEnumService, NaturalErrorHandler, NaturalErrorModule, NaturalFileDropDirective, NaturalFileModule, NaturalFileSelectDirective, NaturalFileService, NaturalFixedButtonComponent, NaturalFixedButtonDetailComponent, NaturalFixedButtonDetailModule, NaturalFixedButtonModule, NaturalHierarchicSelectorComponent, NaturalHierarchicSelectorDialogComponent, NaturalHierarchicSelectorDialogService, NaturalHierarchicSelectorModule, NaturalHierarchicSelectorService, NaturalHttpPrefixDirective, NaturalIconComponent, NaturalIconModule, NaturalLinkMutationService, NaturalLinkableTabDirective, NaturalLoggerConfigExtra, NaturalLoggerConfigUrl, NaturalMatomoModule, NaturalMatomoService, NaturalMemoryStorage, NaturalPanelsComponent, NaturalPanelsModule, NaturalPanelsService, NaturalPersistenceService, NaturalQueryVariablesManager, NaturalRelationsComponent, NaturalRelationsModule, NaturalSearchComponent, NaturalSearchModule, NaturalSelectComponent, NaturalSelectEnumComponent, NaturalSelectHierarchicComponent, NaturalSelectModule, NaturalSeoService, NaturalSidenavComponent, NaturalSidenavContainerComponent, NaturalSidenavContentComponent, NaturalSidenavModule, NaturalSidenavService, NaturalSidenavStackService, NaturalSrcDensityDirective, NaturalStampComponent, NaturalStampModule, NaturalSwissDatePipe, NaturalSwissParsingDateAdapter, NaturalTableButtonComponent, NaturalTableButtonModule, PanelsHooksConfig, SESSION_STORAGE, SortingOrder, TypeDateComponent, TypeDateRangeComponent, TypeHierarchicSelectorComponent, TypeNaturalSelectComponent, TypeNumberComponent, TypeSelectComponent, TypeTextComponent, available, cancellableTimeout, cleanSameValues, collectErrors, copyToClipboard, debug, decimal, deepFreeze, deliverableEmail, ensureHttpPrefix, fallbackIfNoOpenedPanels, formatIsoDate, formatIsoDateTime, fromUrl, getForegroundColor, hasFilesAndProcessDate, ifValid, integer, localStorageFactory, localStorageProvider, lowerCaseFirstLetter, makePlural, memoryLocalStorageProvider, memorySessionStorageProvider, mergeOverrideArray, money, naturalPanelsUrlMatcher, relationsToIds, replaceObjectKeepingReference, replaceOperatorByField, replaceOperatorByName, sessionStorageFactory, sessionStorageProvider, toGraphQLDoctrineFilter, toNavigationParameters, toUrl, unique, upperCaseFirstLetter, urlValidator, validTlds, validateAllFormControls, wrapLike };
|
|
10961
|
+
export { AvatarComponent, AvatarService, FileComponent, IconsConfigService, LOCAL_STORAGE, NATURAL_DROPDOWN_DATA, NATURAL_SEO_CONFIG, NaturalAbstractController, NaturalAbstractDetail, NaturalAbstractEditableList, NaturalAbstractList, NaturalAbstractModelService, NaturalAbstractNavigableList, NaturalAbstractPanel, NaturalAlertModule, NaturalAlertService, NaturalAvatarModule, NaturalCapitalizePipe, NaturalColumnsPickerColumnDirective, NaturalColumnsPickerComponent, NaturalColumnsPickerModule, NaturalCommonModule, NaturalConfirmComponent, NaturalDataSource, NaturalDebounceService, NaturalDetailHeaderComponent, NaturalDetailHeaderModule, NaturalDialogTriggerComponent, NaturalDialogTriggerModule, NaturalDropdownComponentsModule, NaturalDropdownRef, NaturalEllipsisPipe, NaturalEnumPipe, NaturalEnumService, NaturalErrorHandler, NaturalErrorModule, NaturalFileDropDirective, NaturalFileModule, NaturalFileSelectDirective, NaturalFileService, NaturalFixedButtonComponent, NaturalFixedButtonDetailComponent, NaturalFixedButtonDetailModule, NaturalFixedButtonModule, NaturalHierarchicSelectorComponent, NaturalHierarchicSelectorDialogComponent, NaturalHierarchicSelectorDialogService, NaturalHierarchicSelectorModule, NaturalHierarchicSelectorService, NaturalHttpPrefixDirective, NaturalIconComponent, NaturalIconModule, NaturalLinkMutationService, NaturalLinkableTabDirective, NaturalLoggerConfigExtra, NaturalLoggerConfigUrl, NaturalMatomoModule, NaturalMatomoService, NaturalMemoryStorage, NaturalPanelsComponent, NaturalPanelsModule, NaturalPanelsService, NaturalPersistenceService, NaturalQueryVariablesManager, NaturalRelationsComponent, NaturalRelationsModule, NaturalSearchComponent, NaturalSearchModule, NaturalSelectComponent, NaturalSelectEnumComponent, NaturalSelectHierarchicComponent, NaturalSelectModule, NaturalSeoService, NaturalSidenavComponent, NaturalSidenavContainerComponent, NaturalSidenavContentComponent, NaturalSidenavModule, NaturalSidenavService, NaturalSidenavStackService, NaturalSrcDensityDirective, NaturalStampComponent, NaturalStampModule, NaturalSwissDatePipe, NaturalSwissParsingDateAdapter, NaturalTableButtonComponent, NaturalTableButtonModule, PanelsHooksConfig, SESSION_STORAGE, SortingOrder, TypeDateComponent, TypeDateRangeComponent, TypeHierarchicSelectorComponent, TypeNaturalSelectComponent, TypeNumberComponent, TypeSelectComponent, TypeTextComponent, available, cancellableTimeout, cleanSameValues, collectErrors, copyToClipboard, debug, decimal, deepFreeze, deliverableEmail, ensureHttpPrefix, fallbackIfNoOpenedPanels, formatIsoDate, formatIsoDateTime, fromUrl, getForegroundColor, hasFilesAndProcessDate, ifValid, integer, localStorageFactory, localStorageProvider, lowerCaseFirstLetter, makePlural, memoryLocalStorageProvider, memorySessionStorageProvider, mergeOverrideArray, money, naturalPanelsUrlMatcher, relationsToIds, replaceObjectKeepingReference, replaceOperatorByField, replaceOperatorByName, sessionStorageFactory, sessionStorageProvider, toGraphQLDoctrineFilter, toNavigationParameters, toUrl, unique, upperCaseFirstLetter, urlValidator, validTlds, validateAllFormControls, wrapLike };
|
|
10846
10962
|
//# sourceMappingURL=ecodev-natural.mjs.map
|