@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';
|
|
@@ -2124,7 +2124,7 @@ function unique(fieldName, excludedId, modelService) {
|
|
|
2124
2124
|
};
|
|
2125
2125
|
const qvm = new NaturalQueryVariablesManager();
|
|
2126
2126
|
qvm.set('variables', variables);
|
|
2127
|
-
return timer(500).pipe(switchMap(() => modelService.count(qvm).pipe(map(count => (count > 0 ? { duplicateValue: count } : null)))));
|
|
2127
|
+
return timer(500).pipe(switchMap(() => modelService.count(qvm).pipe(first(), map(count => (count > 0 ? { duplicateValue: count } : null)))));
|
|
2128
2128
|
};
|
|
2129
2129
|
}
|
|
2130
2130
|
/**
|
|
@@ -2349,53 +2349,52 @@ class NaturalAbstractDetail extends NaturalAbstractPanel {
|
|
|
2349
2349
|
this.form.disable();
|
|
2350
2350
|
this.service
|
|
2351
2351
|
.create(this.data.model)
|
|
2352
|
-
.pipe(
|
|
2353
|
-
.subscribe(model => {
|
|
2352
|
+
.pipe(switchMap$1(model => {
|
|
2354
2353
|
this.alertService.info($localize `Créé`);
|
|
2355
2354
|
this.form.patchValue(model);
|
|
2356
|
-
this.postCreate(model).
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2355
|
+
return this.postCreate(model).pipe(endWith(model), last());
|
|
2356
|
+
}), switchMap$1(model => {
|
|
2357
|
+
var _a;
|
|
2358
|
+
if (redirect) {
|
|
2359
|
+
if (this.isPanel) {
|
|
2360
|
+
const oldUrl = this.router.url;
|
|
2361
|
+
const nextUrl = (_a = this.panelData) === null || _a === void 0 ? void 0 : _a.config.params.nextRoute;
|
|
2362
|
+
const newUrl = oldUrl.replace('/new', '/' + model.id) + (nextUrl ? '/' + nextUrl : '');
|
|
2363
|
+
return this.router.navigateByUrl(newUrl); // replace /new by /123
|
|
2364
|
+
}
|
|
2365
|
+
else {
|
|
2366
|
+
return this.router.navigate(['..', model.id], { relativeTo: this.route });
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
return EMPTY;
|
|
2370
|
+
}), finalize(() => this.form.enable()))
|
|
2371
|
+
.subscribe();
|
|
2373
2372
|
}
|
|
2374
2373
|
delete(redirectionRoute) {
|
|
2374
|
+
this.form.disable();
|
|
2375
2375
|
this.alertService
|
|
2376
2376
|
.confirm($localize `Suppression`, $localize `Voulez-vous supprimer définitivement cet élément ?`, $localize `Supprimer définitivement`)
|
|
2377
|
-
.
|
|
2378
|
-
if (confirmed) {
|
|
2379
|
-
|
|
2380
|
-
this.form.disable();
|
|
2381
|
-
this.service
|
|
2382
|
-
.delete([this.data.model])
|
|
2383
|
-
.pipe(finalize(() => this.form.enable()))
|
|
2384
|
-
.subscribe(() => {
|
|
2385
|
-
var _a;
|
|
2386
|
-
this.alertService.info($localize `Supprimé`);
|
|
2387
|
-
if (!this.isPanel) {
|
|
2388
|
-
const defaultRoute = ['../../' + kebabCase(this.key)];
|
|
2389
|
-
this.router.navigate(redirectionRoute ? redirectionRoute : defaultRoute, {
|
|
2390
|
-
relativeTo: this.route,
|
|
2391
|
-
});
|
|
2392
|
-
}
|
|
2393
|
-
else {
|
|
2394
|
-
(_a = this.panelService) === null || _a === void 0 ? void 0 : _a.goToPenultimatePanel();
|
|
2395
|
-
}
|
|
2396
|
-
});
|
|
2377
|
+
.pipe(switchMap$1(confirmed => {
|
|
2378
|
+
if (!confirmed) {
|
|
2379
|
+
return EMPTY;
|
|
2397
2380
|
}
|
|
2398
|
-
|
|
2381
|
+
this.preDelete(this.data.model);
|
|
2382
|
+
return this.service.delete([this.data.model]).pipe(switchMap$1(() => {
|
|
2383
|
+
var _a;
|
|
2384
|
+
this.alertService.info($localize `Supprimé`);
|
|
2385
|
+
if (this.isPanel) {
|
|
2386
|
+
(_a = this.panelService) === null || _a === void 0 ? void 0 : _a.goToPenultimatePanel();
|
|
2387
|
+
return EMPTY;
|
|
2388
|
+
}
|
|
2389
|
+
else {
|
|
2390
|
+
const defaultRoute = ['../../' + kebabCase(this.key)];
|
|
2391
|
+
return this.router.navigate(redirectionRoute ? redirectionRoute : defaultRoute, {
|
|
2392
|
+
relativeTo: this.route,
|
|
2393
|
+
});
|
|
2394
|
+
}
|
|
2395
|
+
}));
|
|
2396
|
+
}), finalize(() => this.form.enable()))
|
|
2397
|
+
.subscribe();
|
|
2399
2398
|
}
|
|
2400
2399
|
postUpdate(model) { }
|
|
2401
2400
|
/**
|
|
@@ -3433,7 +3432,10 @@ class NaturalAbstractNavigableList extends NaturalAbstractList {
|
|
|
3433
3432
|
const variables = { filter: { groups: [{ conditions: [condition] }] } };
|
|
3434
3433
|
const qvm = new NaturalQueryVariablesManager();
|
|
3435
3434
|
qvm.set('variables', variables);
|
|
3436
|
-
this.service
|
|
3435
|
+
this.service
|
|
3436
|
+
.count(qvm)
|
|
3437
|
+
.pipe(first$1())
|
|
3438
|
+
.subscribe(count => (navigableItem.hasNavigation = count > 0));
|
|
3437
3439
|
return navigableItem;
|
|
3438
3440
|
});
|
|
3439
3441
|
const navigableResult = Object.assign(Object.assign({}, result), { items: navigableItems });
|
|
@@ -3559,6 +3561,7 @@ function cancellableTimeout(canceller, milliSeconds = 0) {
|
|
|
3559
3561
|
function debug(debugName) {
|
|
3560
3562
|
return tap({
|
|
3561
3563
|
subscribe: () => console.log('SUBSCRIBE', debugName),
|
|
3564
|
+
unsubscribe: () => console.log('UNSUBSCRIBE', debugName),
|
|
3562
3565
|
next: value => console.log('NEXT', debugName, value),
|
|
3563
3566
|
error: error => console.log('ERROR', debugName, error),
|
|
3564
3567
|
complete: () => console.log('COMPLETE', debugName),
|
|
@@ -3566,18 +3569,15 @@ function debug(debugName) {
|
|
|
3566
3569
|
}
|
|
3567
3570
|
|
|
3568
3571
|
class NaturalAbstractModelService {
|
|
3569
|
-
constructor(apollo, name, oneQuery, allQuery, createMutation, updateMutation, deleteMutation) {
|
|
3572
|
+
constructor(apollo, naturalDebounceService, name, oneQuery, allQuery, createMutation, updateMutation, deleteMutation) {
|
|
3570
3573
|
this.apollo = apollo;
|
|
3574
|
+
this.naturalDebounceService = naturalDebounceService;
|
|
3571
3575
|
this.name = name;
|
|
3572
3576
|
this.oneQuery = oneQuery;
|
|
3573
3577
|
this.allQuery = allQuery;
|
|
3574
3578
|
this.createMutation = createMutation;
|
|
3575
3579
|
this.updateMutation = updateMutation;
|
|
3576
3580
|
this.deleteMutation = deleteMutation;
|
|
3577
|
-
/**
|
|
3578
|
-
* Stores the debounced update function
|
|
3579
|
-
*/
|
|
3580
|
-
this.debouncedUpdateCache = new Map();
|
|
3581
3581
|
/**
|
|
3582
3582
|
* Store the creation mutations that are pending
|
|
3583
3583
|
*/
|
|
@@ -3809,36 +3809,7 @@ class NaturalAbstractModelService {
|
|
|
3809
3809
|
this.throwIfNotQuery(this.updateMutation);
|
|
3810
3810
|
// Keep a single instance of the debounced update function
|
|
3811
3811
|
const id = object.id;
|
|
3812
|
-
|
|
3813
|
-
if (!debounced) {
|
|
3814
|
-
const source = new ReplaySubject(1);
|
|
3815
|
-
let wasCancelled = false;
|
|
3816
|
-
const canceller = new Subject();
|
|
3817
|
-
canceller.subscribe(() => {
|
|
3818
|
-
wasCancelled = true;
|
|
3819
|
-
source.complete();
|
|
3820
|
-
canceller.complete();
|
|
3821
|
-
});
|
|
3822
|
-
// Create debounced update function
|
|
3823
|
-
const result = source.pipe(debounceTime(2000), // Wait 2sec.
|
|
3824
|
-
take(1), mergeMap(() => {
|
|
3825
|
-
this.debouncedUpdateCache.delete(id);
|
|
3826
|
-
if (wasCancelled) {
|
|
3827
|
-
return EMPTY;
|
|
3828
|
-
}
|
|
3829
|
-
return this.updateNow(object);
|
|
3830
|
-
}), shareReplay());
|
|
3831
|
-
debounced = {
|
|
3832
|
-
source,
|
|
3833
|
-
canceller,
|
|
3834
|
-
result,
|
|
3835
|
-
};
|
|
3836
|
-
this.debouncedUpdateCache.set(id, debounced);
|
|
3837
|
-
}
|
|
3838
|
-
// Notify our debounced update each time we ask to update
|
|
3839
|
-
debounced.source.next();
|
|
3840
|
-
// Return and observable that is updated when mutation is done
|
|
3841
|
-
return debounced.result;
|
|
3812
|
+
return this.naturalDebounceService.debounce(this, id, this.updateNow(object));
|
|
3842
3813
|
}
|
|
3843
3814
|
/**
|
|
3844
3815
|
* Update an object immediately when subscribing
|
|
@@ -3890,8 +3861,7 @@ class NaturalAbstractModelService {
|
|
|
3890
3861
|
this.throwIfNotQuery(this.deleteMutation);
|
|
3891
3862
|
const ids = objects.map(o => {
|
|
3892
3863
|
// Cancel pending update
|
|
3893
|
-
|
|
3894
|
-
debounced === null || debounced === void 0 ? void 0 : debounced.canceller.next();
|
|
3864
|
+
this.naturalDebounceService.cancel(this, o.id);
|
|
3895
3865
|
return o.id;
|
|
3896
3866
|
});
|
|
3897
3867
|
const variables = merge({
|
|
@@ -3939,7 +3909,7 @@ class NaturalAbstractModelService {
|
|
|
3939
3909
|
return input;
|
|
3940
3910
|
}
|
|
3941
3911
|
/**
|
|
3942
|
-
* Return the number of objects matching the query
|
|
3912
|
+
* Return the number of objects matching the query. It may never complete.
|
|
3943
3913
|
*
|
|
3944
3914
|
* This is used for the unique validator
|
|
3945
3915
|
*/
|
|
@@ -4072,6 +4042,132 @@ class NaturalAbstractModelService {
|
|
|
4072
4042
|
}
|
|
4073
4043
|
}
|
|
4074
4044
|
|
|
4045
|
+
/**
|
|
4046
|
+
* Debounce subscriptions to observable, with possibility to cancel one, or flush all of them. Typically,
|
|
4047
|
+
* observables are object updates, so `NaturalAbstractModelService.updateNow()`.
|
|
4048
|
+
*
|
|
4049
|
+
* `key` must be an instance of `NaturalAbstractModelService` to separate objects by their types. So User with ID 1 is
|
|
4050
|
+
* not confused with Product with ID 1. It has no other purpose.
|
|
4051
|
+
*
|
|
4052
|
+
* `id` should be the ID of the object that will be updated.
|
|
4053
|
+
*/
|
|
4054
|
+
class NaturalDebounceService {
|
|
4055
|
+
constructor() {
|
|
4056
|
+
this.flusher = new Subject();
|
|
4057
|
+
/**
|
|
4058
|
+
* Stores the debounced update function
|
|
4059
|
+
*/
|
|
4060
|
+
this.allDebouncedUpdateCache = new Map();
|
|
4061
|
+
}
|
|
4062
|
+
/**
|
|
4063
|
+
* Debounce the given source observable for a short time. If called multiple times with the same key and id,
|
|
4064
|
+
* it will postpone the subscription to the source observable.
|
|
4065
|
+
*
|
|
4066
|
+
* Giving the same key and id but a different source observable will replace the original observable, but
|
|
4067
|
+
* keep the same debouncing timeline.
|
|
4068
|
+
*/
|
|
4069
|
+
debounce(key, id, source) {
|
|
4070
|
+
const debouncedUpdateCache = this.getMap(key);
|
|
4071
|
+
let debounced = debouncedUpdateCache.get(id);
|
|
4072
|
+
if (debounced) {
|
|
4073
|
+
debounced.source = source;
|
|
4074
|
+
}
|
|
4075
|
+
else {
|
|
4076
|
+
const debouncer = new ReplaySubject(1);
|
|
4077
|
+
let wasCancelled = false;
|
|
4078
|
+
const canceller = new Subject();
|
|
4079
|
+
canceller.subscribe(() => {
|
|
4080
|
+
wasCancelled = true;
|
|
4081
|
+
debouncer.complete();
|
|
4082
|
+
canceller.complete();
|
|
4083
|
+
this.delete(key, id);
|
|
4084
|
+
});
|
|
4085
|
+
debounced = {
|
|
4086
|
+
debouncer,
|
|
4087
|
+
canceller,
|
|
4088
|
+
source,
|
|
4089
|
+
result: debouncer.pipe(debounceTime$1(2000), // Wait 2 seconds...
|
|
4090
|
+
raceWith(this.flusher), // ...unless flusher is triggered
|
|
4091
|
+
take$1(1), mergeMap(() => {
|
|
4092
|
+
this.delete(key, id);
|
|
4093
|
+
if (wasCancelled || !debounced) {
|
|
4094
|
+
return EMPTY;
|
|
4095
|
+
}
|
|
4096
|
+
return debounced.source;
|
|
4097
|
+
}), shareReplay$1()),
|
|
4098
|
+
};
|
|
4099
|
+
debouncedUpdateCache.set(id, debounced);
|
|
4100
|
+
}
|
|
4101
|
+
// Notify our debounced update each time we ask to update
|
|
4102
|
+
debounced.debouncer.next();
|
|
4103
|
+
// Return and observable that is updated when mutation is done
|
|
4104
|
+
return debounced.result;
|
|
4105
|
+
}
|
|
4106
|
+
cancel(key, id) {
|
|
4107
|
+
var _a;
|
|
4108
|
+
const debounced = (_a = this.allDebouncedUpdateCache.get(key)) === null || _a === void 0 ? void 0 : _a.get(id);
|
|
4109
|
+
debounced === null || debounced === void 0 ? void 0 : debounced.canceller.next();
|
|
4110
|
+
}
|
|
4111
|
+
/**
|
|
4112
|
+
* Immediately execute all pending updates.
|
|
4113
|
+
*
|
|
4114
|
+
* It should typically be called before login out.
|
|
4115
|
+
*
|
|
4116
|
+
* The returned observable will complete when all updates complete, even if some of them error.
|
|
4117
|
+
*/
|
|
4118
|
+
flush() {
|
|
4119
|
+
const all = [];
|
|
4120
|
+
this.allDebouncedUpdateCache.forEach(map => map.forEach(debounced => {
|
|
4121
|
+
all.push(debounced.result.pipe(catchError(() => of(undefined))));
|
|
4122
|
+
}));
|
|
4123
|
+
if (!all.length) {
|
|
4124
|
+
all.push(of(undefined));
|
|
4125
|
+
}
|
|
4126
|
+
return new Observable(subscriber => {
|
|
4127
|
+
const subscription = forkJoin(all)
|
|
4128
|
+
.pipe(map$1(() => undefined))
|
|
4129
|
+
.subscribe(subscriber);
|
|
4130
|
+
// Flush only after subscription process is finished
|
|
4131
|
+
this.flusher.next();
|
|
4132
|
+
return subscription;
|
|
4133
|
+
});
|
|
4134
|
+
}
|
|
4135
|
+
/**
|
|
4136
|
+
* Count of pending updates
|
|
4137
|
+
*/
|
|
4138
|
+
get count() {
|
|
4139
|
+
let count = 0;
|
|
4140
|
+
this.allDebouncedUpdateCache.forEach(map => (count += map.size));
|
|
4141
|
+
return count;
|
|
4142
|
+
}
|
|
4143
|
+
getMap(key) {
|
|
4144
|
+
let debouncedUpdateCache = this.allDebouncedUpdateCache.get(key);
|
|
4145
|
+
if (!debouncedUpdateCache) {
|
|
4146
|
+
debouncedUpdateCache = new Map();
|
|
4147
|
+
this.allDebouncedUpdateCache.set(key, debouncedUpdateCache);
|
|
4148
|
+
}
|
|
4149
|
+
return debouncedUpdateCache;
|
|
4150
|
+
}
|
|
4151
|
+
delete(key, id) {
|
|
4152
|
+
const map = this.allDebouncedUpdateCache.get(key);
|
|
4153
|
+
if (!map) {
|
|
4154
|
+
return;
|
|
4155
|
+
}
|
|
4156
|
+
map.delete(id);
|
|
4157
|
+
if (!map.size) {
|
|
4158
|
+
this.allDebouncedUpdateCache.delete(key);
|
|
4159
|
+
}
|
|
4160
|
+
}
|
|
4161
|
+
}
|
|
4162
|
+
NaturalDebounceService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDebounceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4163
|
+
NaturalDebounceService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDebounceService, providedIn: 'root' });
|
|
4164
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalDebounceService, decorators: [{
|
|
4165
|
+
type: Injectable,
|
|
4166
|
+
args: [{
|
|
4167
|
+
providedIn: 'root',
|
|
4168
|
+
}]
|
|
4169
|
+
}] });
|
|
4170
|
+
|
|
4075
4171
|
const enumTypeQuery = gql `
|
|
4076
4172
|
query EnumType($name: String!) {
|
|
4077
4173
|
__type(name: $name) {
|
|
@@ -4280,6 +4376,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
|
|
|
4280
4376
|
}]
|
|
4281
4377
|
}], ctorParameters: function () { return [{ type: i1$1.Apollo }]; } });
|
|
4282
4378
|
|
|
4379
|
+
const patterns = [
|
|
4380
|
+
/^(?<day>\d{1,2})\.(?<month>\d{1,2})\.(?<year>\d{4}|\d{2})$/,
|
|
4381
|
+
/^(?<day>\d{1,2})-(?<month>\d{1,2})-(?<year>\d{4}|\d{2})$/,
|
|
4382
|
+
/^(?<day>\d{1,2})\/(?<month>\d{1,2})\/(?<year>\d{4}|\d{2})$/,
|
|
4383
|
+
/^(?<day>\d{1,2})\\(?<month>\d{1,2})\\(?<year>\d{4}|\d{2})$/,
|
|
4384
|
+
// strict ISO format
|
|
4385
|
+
/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/,
|
|
4386
|
+
];
|
|
4283
4387
|
class NaturalSwissParsingDateAdapter extends NativeDateAdapter {
|
|
4284
4388
|
/**
|
|
4285
4389
|
* Parse commonly accepted swiss format, such as:
|
|
@@ -4293,24 +4397,24 @@ class NaturalSwissParsingDateAdapter extends NativeDateAdapter {
|
|
|
4293
4397
|
return new Date(value);
|
|
4294
4398
|
}
|
|
4295
4399
|
if (typeof value === 'string') {
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4400
|
+
const trimmed = value.trim();
|
|
4401
|
+
for (const pattern of patterns) {
|
|
4402
|
+
const m = trimmed.match(pattern);
|
|
4403
|
+
if (m === null || m === void 0 ? void 0 : m.groups) {
|
|
4404
|
+
const year = +m.groups.year;
|
|
4405
|
+
const month = +m.groups.month;
|
|
4406
|
+
const day = +m.groups.day;
|
|
4407
|
+
return this.createDateIfValid(year, month, day);
|
|
4302
4408
|
}
|
|
4303
|
-
return this.createDateIfValid(year, +m[2], +m[1]);
|
|
4304
|
-
}
|
|
4305
|
-
// Attempt strict ISO format
|
|
4306
|
-
m = value.match(/(\d{4})-(\d{2})-(\d{2})/);
|
|
4307
|
-
if (m) {
|
|
4308
|
-
return this.createDateIfValid(+m[1], +m[2], +m[3]);
|
|
4309
4409
|
}
|
|
4310
4410
|
}
|
|
4311
4411
|
return null;
|
|
4312
4412
|
}
|
|
4313
4413
|
createDateIfValid(year, month, date) {
|
|
4414
|
+
// Assume year 2000 if only two digits
|
|
4415
|
+
if (year < 100) {
|
|
4416
|
+
year += 2000;
|
|
4417
|
+
}
|
|
4314
4418
|
month = month - 1;
|
|
4315
4419
|
if (month >= 0 && month <= 11 && date >= 1 && date <= 31) {
|
|
4316
4420
|
return this.createDate(year, month, date);
|
|
@@ -5983,10 +6087,10 @@ class NaturalSelectComponent extends AbstractSelect {
|
|
|
5983
6087
|
}
|
|
5984
6088
|
}
|
|
5985
6089
|
NaturalSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
5986
|
-
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" }] });
|
|
6090
|
+
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" }] });
|
|
5987
6091
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectComponent, decorators: [{
|
|
5988
6092
|
type: Component,
|
|
5989
|
-
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"] }]
|
|
6093
|
+
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"] }]
|
|
5990
6094
|
}], propDecorators: { autoTrigger: [{
|
|
5991
6095
|
type: ViewChild,
|
|
5992
6096
|
args: [MatAutocompleteTrigger]
|
|
@@ -6272,7 +6376,7 @@ class NaturalHierarchicSelectorService {
|
|
|
6272
6376
|
}
|
|
6273
6377
|
countItems(node, contextFilters = null) {
|
|
6274
6378
|
const configurations = this.getContextualizedConfigs(node, contextFilters, null);
|
|
6275
|
-
const observables = configurations.map(c => c.configuration.injectedService.count(c.variablesManager));
|
|
6379
|
+
const observables = configurations.map(c => c.configuration.injectedService.count(c.variablesManager).pipe(first$1()));
|
|
6276
6380
|
forkJoin(observables).subscribe(results => {
|
|
6277
6381
|
const totalItems = results.reduce((total, length) => total + length, 0);
|
|
6278
6382
|
node.expandable = totalItems > 0;
|
|
@@ -6309,12 +6413,6 @@ class NaturalHierarchicSelectorService {
|
|
|
6309
6413
|
}
|
|
6310
6414
|
return configsAndServices;
|
|
6311
6415
|
}
|
|
6312
|
-
/**
|
|
6313
|
-
* Check configuration to return a boolean that allows or denies the selection for the given element
|
|
6314
|
-
*/
|
|
6315
|
-
isSelectable(node) {
|
|
6316
|
-
return !!node.node.config.selectableAtKey;
|
|
6317
|
-
}
|
|
6318
6416
|
/**
|
|
6319
6417
|
* Return models matching given FlatNodes
|
|
6320
6418
|
* Returns a Literal of models grouped by their configuration attribute "selectableAtKey"
|
|
@@ -7015,7 +7113,7 @@ class NaturalHierarchicSelectorComponent extends NaturalAbstractController {
|
|
|
7015
7113
|
}
|
|
7016
7114
|
else if (!this.multiple) {
|
|
7017
7115
|
if (this.flatNodesSelection.isSelected(flatNode)) {
|
|
7018
|
-
this.unselectSingleFlatNode(
|
|
7116
|
+
this.unselectSingleFlatNode();
|
|
7019
7117
|
}
|
|
7020
7118
|
else {
|
|
7021
7119
|
// If not multiple, and we want to select an element, unselect everything before to keep a single selection
|
|
@@ -7186,7 +7284,7 @@ class NaturalHierarchicSelectorComponent extends NaturalAbstractController {
|
|
|
7186
7284
|
/**
|
|
7187
7285
|
* Clear all selected and select the given node
|
|
7188
7286
|
*/
|
|
7189
|
-
unselectSingleFlatNode(
|
|
7287
|
+
unselectSingleFlatNode() {
|
|
7190
7288
|
this.flatNodesSelection.clear();
|
|
7191
7289
|
this.selectedNodes = [];
|
|
7192
7290
|
this.updateSelection(this.selectedNodes);
|
|
@@ -7874,10 +7972,10 @@ class NaturalSelectHierarchicComponent extends AbstractSelect {
|
|
|
7874
7972
|
}
|
|
7875
7973
|
}
|
|
7876
7974
|
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 });
|
|
7877
|
-
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"] }] });
|
|
7975
|
+
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"] }] });
|
|
7878
7976
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalSelectHierarchicComponent, decorators: [{
|
|
7879
7977
|
type: Component,
|
|
7880
|
-
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"] }]
|
|
7978
|
+
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"] }]
|
|
7881
7979
|
}], ctorParameters: function () {
|
|
7882
7980
|
return [{ type: NaturalHierarchicSelectorDialogService }, { type: i3.NgControl, decorators: [{
|
|
7883
7981
|
type: Optional
|
|
@@ -8125,6 +8223,17 @@ function createFileInput(document) {
|
|
|
8125
8223
|
fileElem.type = 'file';
|
|
8126
8224
|
return fileElem;
|
|
8127
8225
|
}
|
|
8226
|
+
function isDirectory(file) {
|
|
8227
|
+
return file
|
|
8228
|
+
.slice(0, 1)
|
|
8229
|
+
.text()
|
|
8230
|
+
.then(text => {
|
|
8231
|
+
// Firefox will return empty string for a folder, so we must check that special case.
|
|
8232
|
+
// That means that any empty file will incorrectly be interpreted as a folder on all
|
|
8233
|
+
// browsers, but that's tolerable because there is no real use-case to upload an empty file.
|
|
8234
|
+
return text !== '';
|
|
8235
|
+
}, () => false);
|
|
8236
|
+
}
|
|
8128
8237
|
function stopEvent(event) {
|
|
8129
8238
|
event.preventDefault();
|
|
8130
8239
|
event.stopPropagation();
|
|
@@ -8223,10 +8332,6 @@ class NaturalAbstractFile extends NaturalAbstractController {
|
|
|
8223
8332
|
this.element = element;
|
|
8224
8333
|
this.naturalFileService = naturalFileService;
|
|
8225
8334
|
this.document = document;
|
|
8226
|
-
this.validators = [
|
|
8227
|
-
{ name: 'accept', fn: this.acceptValidator },
|
|
8228
|
-
{ name: 'fileSize', fn: this.fileSizeValidator },
|
|
8229
|
-
];
|
|
8230
8335
|
/**
|
|
8231
8336
|
* Whether we should accept a single file or multiple files
|
|
8232
8337
|
*/
|
|
@@ -8323,8 +8428,7 @@ class NaturalAbstractFile extends NaturalAbstractController {
|
|
|
8323
8428
|
valid: [],
|
|
8324
8429
|
invalid: [],
|
|
8325
8430
|
};
|
|
8326
|
-
|
|
8327
|
-
const error = this.validate(file);
|
|
8431
|
+
forkJoin(files.map(file => this.validate(file).pipe(tap$1(error => {
|
|
8328
8432
|
if (error) {
|
|
8329
8433
|
selection.invalid.push({
|
|
8330
8434
|
file: file,
|
|
@@ -8334,17 +8438,18 @@ class NaturalAbstractFile extends NaturalAbstractController {
|
|
|
8334
8438
|
else {
|
|
8335
8439
|
selection.valid.push(file);
|
|
8336
8440
|
}
|
|
8337
|
-
}
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
}
|
|
8341
|
-
if (selection.valid.length || selection.invalid.length) {
|
|
8342
|
-
this.filesChange.emit(selection);
|
|
8343
|
-
if (this.broadcast) {
|
|
8344
|
-
this.naturalFileService.filesChanged.next(selection);
|
|
8441
|
+
})))).subscribe(() => {
|
|
8442
|
+
if (selection.valid.length) {
|
|
8443
|
+
this.fileChange.emit(selection.valid[0]);
|
|
8345
8444
|
}
|
|
8346
|
-
|
|
8347
|
-
|
|
8445
|
+
if (selection.valid.length || selection.invalid.length) {
|
|
8446
|
+
this.filesChange.emit(selection);
|
|
8447
|
+
if (this.broadcast) {
|
|
8448
|
+
this.naturalFileService.filesChanged.next(selection);
|
|
8449
|
+
}
|
|
8450
|
+
}
|
|
8451
|
+
this.getFileElement().value = '';
|
|
8452
|
+
});
|
|
8348
8453
|
}
|
|
8349
8454
|
/**
|
|
8350
8455
|
* Called when input has files
|
|
@@ -8391,18 +8496,18 @@ class NaturalAbstractFile extends NaturalAbstractController {
|
|
|
8391
8496
|
this.handleFiles(files);
|
|
8392
8497
|
}
|
|
8393
8498
|
validate(file) {
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
|
|
8499
|
+
return forkJoin({
|
|
8500
|
+
accept: of(acceptType(this.accept, file.type, file.name)),
|
|
8501
|
+
fileSize: of(!(this.maxSize && file.size > this.maxSize)),
|
|
8502
|
+
directory: isDirectory(file),
|
|
8503
|
+
}).pipe(map$1(result => {
|
|
8504
|
+
for (const [key, value] of Object.entries(result)) {
|
|
8505
|
+
if (!value) {
|
|
8506
|
+
return key;
|
|
8507
|
+
}
|
|
8397
8508
|
}
|
|
8398
|
-
|
|
8399
|
-
|
|
8400
|
-
}
|
|
8401
|
-
acceptValidator(item) {
|
|
8402
|
-
return acceptType(this.accept, item.type, item.name);
|
|
8403
|
-
}
|
|
8404
|
-
fileSizeValidator(item) {
|
|
8405
|
-
return !(this.maxSize && item.size > this.maxSize);
|
|
8509
|
+
return null;
|
|
8510
|
+
}));
|
|
8406
8511
|
}
|
|
8407
8512
|
}
|
|
8408
8513
|
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 });
|
|
@@ -8760,9 +8865,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
|
|
|
8760
8865
|
*/
|
|
8761
8866
|
|
|
8762
8867
|
class NaturalFixedButtonDetailComponent {
|
|
8763
|
-
constructor() {
|
|
8868
|
+
constructor(route) {
|
|
8869
|
+
this.canChange = true;
|
|
8870
|
+
this.isCreation = false;
|
|
8764
8871
|
this.create = new EventEmitter();
|
|
8765
8872
|
this.delete = new EventEmitter();
|
|
8873
|
+
route.params.subscribe(() => (this.canChange = true));
|
|
8874
|
+
}
|
|
8875
|
+
get model() {
|
|
8876
|
+
return this._model;
|
|
8877
|
+
}
|
|
8878
|
+
set model(value) {
|
|
8879
|
+
this._model = value;
|
|
8880
|
+
if (this.canChange) {
|
|
8881
|
+
this.isCreation = !this._model.id;
|
|
8882
|
+
}
|
|
8766
8883
|
}
|
|
8767
8884
|
clickCreate() {
|
|
8768
8885
|
if (this.form.enabled) {
|
|
@@ -8775,12 +8892,12 @@ class NaturalFixedButtonDetailComponent {
|
|
|
8775
8892
|
}
|
|
8776
8893
|
}
|
|
8777
8894
|
}
|
|
8778
|
-
NaturalFixedButtonDetailComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalFixedButtonDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8779
|
-
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=\"
|
|
8895
|
+
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 });
|
|
8896
|
+
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"] }] });
|
|
8780
8897
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NaturalFixedButtonDetailComponent, decorators: [{
|
|
8781
8898
|
type: Component,
|
|
8782
|
-
args: [{ selector: 'natural-fixed-button-detail', template: "<natural-fixed-button\n (click)=\"clickCreate()\"\n *ngIf=\"
|
|
8783
|
-
}], propDecorators: { model: [{
|
|
8899
|
+
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" }]
|
|
8900
|
+
}], ctorParameters: function () { return [{ type: i2$1.ActivatedRoute }]; }, propDecorators: { model: [{
|
|
8784
8901
|
type: Input
|
|
8785
8902
|
}], form: [{
|
|
8786
8903
|
type: Input
|
|
@@ -10916,5 +11033,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
|
|
|
10916
11033
|
* Generated bundle index. Do not edit.
|
|
10917
11034
|
*/
|
|
10918
11035
|
|
|
10919
|
-
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 };
|
|
11036
|
+
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 };
|
|
10920
11037
|
//# sourceMappingURL=ecodev-natural.mjs.map
|