UNPKG

@xit/utility

Version:

Composants et services de la zone Utility des applications XiT

671 lines (662 loc) 206 kB
import * as i0 from '@angular/core'; import { InjectionToken, Injectable, Inject, EventEmitter, Component, Input, Output, HostBinding, Directive, NgModule, forwardRef, ChangeDetectionStrategy, Optional, ViewChild, TemplateRef, ContentChild, ContentChildren, ViewEncapsulation, PLATFORM_ID } from '@angular/core'; import * as i2 from '@angular/forms'; import { Validators, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { Observable, Subject, Subscription, timer, BehaviorSubject } from 'rxjs'; import { shareReplay, tap, catchError, takeUntil, filter, map, first, startWith } from 'rxjs/operators'; import * as i1 from '@angular/common/http'; import * as i3 from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field'; import * as i4 from '@angular/material/select'; import { MatSelectModule } from '@angular/material/select'; import * as i5 from '@angular/material/core'; import * as i4$1 from '@angular/material/progress-spinner'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import * as i7 from '@angular/material/input'; import { MatInputModule } from '@angular/material/input'; import * as i4$2 from '@angular/common'; import { CommonModule, isPlatformBrowser, DOCUMENT } from '@angular/common'; import * as i1$1 from '@angular/router'; import { NavigationEnd, RouterModule } from '@angular/router'; import { faAngleRight, faTimes, faArrowLeft, faArrowToBottom, faImage, faTrashAlt } from '@fortawesome/pro-duotone-svg-icons'; import * as i2$1 from '@fortawesome/angular-fontawesome'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import * as i1$2 from '@angular/flex-layout'; import { FlexLayoutModule } from '@angular/flex-layout'; import { CdkPortalOutlet, TemplatePortal } from '@angular/cdk/portal'; import { matTabsAnimations, MatTabsModule } from '@angular/material/tabs'; import * as i1$3 from '@angular/cdk/bidi'; import { coerceNumberProperty } from '@angular/cdk/coercion'; import * as i1$4 from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; import * as i2$2 from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button'; import * as i7$1 from '@angular/flex-layout/flex'; import * as i2$3 from '@angular/material/snack-bar'; import { MAT_SNACK_BAR_DATA, MatSnackBarModule } from '@angular/material/snack-bar'; import * as i3$1 from '@angular/material/progress-bar'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import * as i8 from '@angular/material/checkbox'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatDividerModule } from '@angular/material/divider'; import { MatRadioModule } from '@angular/material/radio'; const UTILITY_CONFIG = new InjectionToken('UtilityConfig'); class LogService { /** * Conserve une trace de l'action * @param operation - nom de l'opération à logguer * @param data - donnée associée à l'opération */ log(operation, data) { console.log(operation, data || ''); } } /** @nocollapse */ /** @nocollapse */ LogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: LogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); /** @nocollapse */ /** @nocollapse */ LogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: LogService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: LogService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); class ErrorService { constructor(logService) { this.logService = logService; } /** * Capture l'erreur de la requête Http. * Fait en sorte que l'application continue. * @param operation - nom de l'operation qui a caus� l'erreur */ handleError(operation = 'operation') { return (value) => { this.logService.log(`${operation} failed: ${value.message}`); return new Observable(observer => observer.error(value)); }; } } /** @nocollapse */ /** @nocollapse */ ErrorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: ErrorService, deps: [{ token: LogService }], target: i0.ɵɵFactoryTarget.Injectable }); /** @nocollapse */ /** @nocollapse */ ErrorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: ErrorService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: ErrorService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: LogService }]; } }); class CountryService { constructor(config, http, errorService, logService) { this.config = config; this.http = http; this.errorService = errorService; this.logService = logService; this.countryUrl = `${this.config.url}/${this.config.version}/${this.config.services.countries}`; } countriesByRegion(region, langs) { if (!this.countries$) { const operation = 'Country service (countries)'; this.countries$ = this.http .get(`${this.countryUrl}/regions/${region}/langs/${langs.join()}`) .pipe(shareReplay(1), tap((c) => this.logService.log(operation, c)), catchError(this.errorService.handleError(operation))); } return this.countries$; } } /** @nocollapse */ /** @nocollapse */ CountryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: CountryService, deps: [{ token: UTILITY_CONFIG }, { token: i1.HttpClient }, { token: ErrorService }, { token: LogService }], target: i0.ɵɵFactoryTarget.Injectable }); /** @nocollapse */ /** @nocollapse */ CountryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: CountryService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: CountryService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [UTILITY_CONFIG] }] }, { type: i1.HttpClient }, { type: ErrorService }, { type: LogService }]; } }); class AddressFormComponent { constructor(formBuilder, countryService) { this.formBuilder = formBuilder; this.countryService = countryService; this.loadingCountries = false; this.destroy = new Subject(); this.canceled = new EventEmitter(); this.submitted = new EventEmitter(); this.formAddress = this.formBuilder.group({ country: [{ value: '', disabled: true }, [Validators.required]], default: [false, [Validators.required]], locality: ['', [Validators.required]], postalCode: ['', [Validators.required, Validators.maxLength(5), Validators.pattern(/^988\d{2}$/)]], state: [''], streetAddress: ['', [Validators.required]] }); } get address() { return this._address; } set address(value) { this._address = value; this.init(); } getControls() { const controls = new Array(); const countryControl = this.formAddress.get('country'); const defaultControl = this.formAddress.get('default'); const localityControl = this.formAddress.get('locality'); const postalCodeControl = this.formAddress.get('postalCode'); const stateControl = this.formAddress.get('state'); const streetAddressControl = this.formAddress.get('streetAddress'); if (countryControl) { controls.push(countryControl); } if (defaultControl) { controls.push(defaultControl); } if (localityControl) { controls.push(localityControl); } if (postalCodeControl) { controls.push(postalCodeControl); } if (stateControl) { controls.push(stateControl); } if (streetAddressControl) { controls.push(streetAddressControl); } return controls; } init() { if (this.address) { this.formAddress.setValue({ country: this.address.country, default: this.address.default, locality: this.address.locality, postalCode: this.address.postalCode, state: this.address.state, streetAddress: this.address.streetAddress }); } } ngOnInit() { this.loadingCountries = true; this.countryService.countriesByRegion('oceania', ['fr']) .pipe(takeUntil(this.destroy)) .subscribe((result) => { this.countries = result.sort((a, b) => a.fr.localeCompare(b.fr, 'fr', { ignorePunctuation: true })); this.formAddress.controls['country'].enable(); this.loadingCountries = false; }, () => this.loadingCountries = false); } ngOnDestroy() { this.destroy.next(true); } cancel() { this.init(); this.getControls().forEach((a) => a.markAsPristine()); this.canceled.emit(this.address); } submit() { if (this.formAddress.valid) { const address = { ...this.address }; const countryControl = this.formAddress.get('country'); const defaultControl = this.formAddress.get('default'); const localityControl = this.formAddress.get('locality'); const postalCodeControl = this.formAddress.get('postalCode'); const stateControl = this.formAddress.get('state'); const streetAddressControl = this.formAddress.get('streetAddress'); if (countryControl) { address.country = countryControl.value; } if (defaultControl) { address.default = defaultControl.value; } if (localityControl) { address.locality = localityControl.value; } if (postalCodeControl) { address.postalCode = postalCodeControl.value; } if (stateControl) { address.state = stateControl.value; } if (streetAddressControl) { address.streetAddress = streetAddressControl.value; } this.submitted.emit(address); } } } /** @nocollapse */ /** @nocollapse */ AddressFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AddressFormComponent, deps: [{ token: i2.FormBuilder }, { token: CountryService }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ /** @nocollapse */ AddressFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.0", type: AddressFormComponent, selector: "xit-address-form", inputs: { saving: "saving", address: "address" }, outputs: { canceled: "canceled", submitted: "submitted" }, providers: [CountryService], ngImport: i0, template: "<form [formGroup]=\"formAddress\" cdkTrapFocus>\r\n <div class=\"address-form-content\">\r\n <div class=\"address-form-fields\">\r\n <mat-form-field appearance=\"outline\" [color]=\"'primary'\">\r\n <mat-label><span i18n=\"street address text|Nom de rue@@streetAddressText\">Nom de rue</span></mat-label>\r\n <input\r\n #addressElement\r\n matInput\r\n cdkFocusInitial\r\n required\r\n id=\"adressAutoComplete\"\r\n placeholder=\"Cherchez un nom de rue\"\r\n formControlName=\"streetAddress\"\r\n maxlength=\"50\">\r\n <mat-error *ngIf=\"formAddress?.get('streetAddress')?.hasError('required')\">\r\n <span i18n=\"required street address|Une adresse est obligatoire@@requiredStreetAddress\">Une adresse est obligatoire</span>\r\n </mat-error>\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\" [color]=\"'primary'\">\r\n <mat-label><span i18n=\"postal code text|Code postal@@postalCodeText\">Code postal</span></mat-label>\r\n <input\r\n #postalCode\r\n matInput\r\n required\r\n placeholder=\"Saisissez un code postal\"\r\n formControlName=\"postalCode\"\r\n maxlength=\"5\">\r\n <mat-hint align=\"end\">{{ postalCode.value?.length || 0 }}<span i18n=\"postal code max length|/5@@postalCodeMaxLength\">/5</span></mat-hint>\r\n <mat-error *ngIf=\"formAddress?.get('postalCode')?.hasError('required')\">\r\n <span i18n=\"required postal code|Un code postal est obligatoire@@requiredPostalCode\">Un code postal est obligatoire</span>\r\n </mat-error>\r\n <mat-error *ngIf=\"formAddress?.get('postalCode')?.hasError('pattern')\">\r\n <span i18n=\"invalid postal code|Le code postal n'est pas valide@@invalidPostalCode\">Le code postal n'est pas valide</span>\r\n </mat-error>\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\" [color]=\"'primary'\">\r\n <mat-label><span i18n=\"locality text|Ville@@localityText\">Ville</span></mat-label>\r\n <input\r\n matInput\r\n required\r\n placeholder=\"Saisissez une ville\"\r\n formControlName=\"locality\"\r\n maxlength=\"30\">\r\n <mat-error *ngIf=\"formAddress?.get('locality')?.hasError('required')\">\r\n <span i18n=\"required locality|Une ville est obligatoire@@requiredLocality\">Une ville est obligatoire</span>\r\n </mat-error>\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\" [color]=\"'primary'\">\r\n <mat-label><span i18n=\"state text|R\u00E9gion@@stateText\">R\u00E9gion</span></mat-label>\r\n <input\r\n matInput\r\n placeholder=\"Saisissez une r\u00E9gion\"\r\n formControlName=\"state\"\r\n maxlength=\"30\">\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\" [color]=\"'primary'\">\r\n <mat-label><span i18n=\"country text|Pays@@countryText\">Pays</span></mat-label>\r\n <mat-select\r\n required\r\n placeholder=\"Choisissez un pays\"\r\n formControlName=\"country\">\r\n <mat-option *ngFor=\"let country of countries\" [value]=\"country.fr\">\r\n <span>{{ country.fr }}</span>\r\n </mat-option>\r\n </mat-select>\r\n <mat-spinner matSuffix *ngIf=\"loadingCountries\" mode=\"indeterminate\" diameter=\"17\"></mat-spinner>\r\n <mat-error *ngIf=\"formAddress?.get('country')?.hasError('required')\">\r\n <span i18n=\"required country|Un pays est obligatoire@@requiredCountry\">Un pays est obligatoire</span>\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n</form>\r\n", styles: [".address-form-content{position:relative;height:auto}.address-form-content .address-form-fields{display:flex;flex-direction:column;align-items:flex-start;justify-content:center}.address-form-content .address-form-fields .mat-form-field{width:100%;margin-bottom:8px}.address-form-content .address-form-fields .mat-checkbox{margin:1.25em 0}\n"], components: [{ type: i3.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i4.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i5.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i4$1.MatSpinner, selector: "mat-spinner", inputs: ["color"] }], directives: [{ type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i3.MatLabel, selector: "mat-label" }, { type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i4$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.MatError, selector: "mat-error", inputs: ["id"] }, { type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { type: i4$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.MatSuffix, selector: "[matSuffix]" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AddressFormComponent, decorators: [{ type: Component, args: [{ selector: 'xit-address-form', providers: [CountryService], template: "<form [formGroup]=\"formAddress\" cdkTrapFocus>\r\n <div class=\"address-form-content\">\r\n <div class=\"address-form-fields\">\r\n <mat-form-field appearance=\"outline\" [color]=\"'primary'\">\r\n <mat-label><span i18n=\"street address text|Nom de rue@@streetAddressText\">Nom de rue</span></mat-label>\r\n <input\r\n #addressElement\r\n matInput\r\n cdkFocusInitial\r\n required\r\n id=\"adressAutoComplete\"\r\n placeholder=\"Cherchez un nom de rue\"\r\n formControlName=\"streetAddress\"\r\n maxlength=\"50\">\r\n <mat-error *ngIf=\"formAddress?.get('streetAddress')?.hasError('required')\">\r\n <span i18n=\"required street address|Une adresse est obligatoire@@requiredStreetAddress\">Une adresse est obligatoire</span>\r\n </mat-error>\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\" [color]=\"'primary'\">\r\n <mat-label><span i18n=\"postal code text|Code postal@@postalCodeText\">Code postal</span></mat-label>\r\n <input\r\n #postalCode\r\n matInput\r\n required\r\n placeholder=\"Saisissez un code postal\"\r\n formControlName=\"postalCode\"\r\n maxlength=\"5\">\r\n <mat-hint align=\"end\">{{ postalCode.value?.length || 0 }}<span i18n=\"postal code max length|/5@@postalCodeMaxLength\">/5</span></mat-hint>\r\n <mat-error *ngIf=\"formAddress?.get('postalCode')?.hasError('required')\">\r\n <span i18n=\"required postal code|Un code postal est obligatoire@@requiredPostalCode\">Un code postal est obligatoire</span>\r\n </mat-error>\r\n <mat-error *ngIf=\"formAddress?.get('postalCode')?.hasError('pattern')\">\r\n <span i18n=\"invalid postal code|Le code postal n'est pas valide@@invalidPostalCode\">Le code postal n'est pas valide</span>\r\n </mat-error>\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\" [color]=\"'primary'\">\r\n <mat-label><span i18n=\"locality text|Ville@@localityText\">Ville</span></mat-label>\r\n <input\r\n matInput\r\n required\r\n placeholder=\"Saisissez une ville\"\r\n formControlName=\"locality\"\r\n maxlength=\"30\">\r\n <mat-error *ngIf=\"formAddress?.get('locality')?.hasError('required')\">\r\n <span i18n=\"required locality|Une ville est obligatoire@@requiredLocality\">Une ville est obligatoire</span>\r\n </mat-error>\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\" [color]=\"'primary'\">\r\n <mat-label><span i18n=\"state text|R\u00E9gion@@stateText\">R\u00E9gion</span></mat-label>\r\n <input\r\n matInput\r\n placeholder=\"Saisissez une r\u00E9gion\"\r\n formControlName=\"state\"\r\n maxlength=\"30\">\r\n </mat-form-field>\r\n <mat-form-field appearance=\"outline\" [color]=\"'primary'\">\r\n <mat-label><span i18n=\"country text|Pays@@countryText\">Pays</span></mat-label>\r\n <mat-select\r\n required\r\n placeholder=\"Choisissez un pays\"\r\n formControlName=\"country\">\r\n <mat-option *ngFor=\"let country of countries\" [value]=\"country.fr\">\r\n <span>{{ country.fr }}</span>\r\n </mat-option>\r\n </mat-select>\r\n <mat-spinner matSuffix *ngIf=\"loadingCountries\" mode=\"indeterminate\" diameter=\"17\"></mat-spinner>\r\n <mat-error *ngIf=\"formAddress?.get('country')?.hasError('required')\">\r\n <span i18n=\"required country|Un pays est obligatoire@@requiredCountry\">Un pays est obligatoire</span>\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n</form>\r\n", styles: [".address-form-content{position:relative;height:auto}.address-form-content .address-form-fields{display:flex;flex-direction:column;align-items:flex-start;justify-content:center}.address-form-content .address-form-fields .mat-form-field{width:100%;margin-bottom:8px}.address-form-content .address-form-fields .mat-checkbox{margin:1.25em 0}\n"] }] }], ctorParameters: function () { return [{ type: i2.FormBuilder }, { type: CountryService }]; }, propDecorators: { saving: [{ type: Input }], address: [{ type: Input }], canceled: [{ type: Output }], submitted: [{ type: Output }] } }); // import { Component, Input, Output, EventEmitter, Renderer2, OnInit, OnDestroy } from '@angular/core'; // import { MatDialog } from '@angular/material/dialog'; // import { MatSnackBar } from '@angular/material/snack-bar'; // import { Address, AddressForm, User, Claim } from '@xit/dto'; // import { UserService } from '@xit/identity'; // import { Subject } from 'rxjs/Subject'; // import { first } from 'rxjs/operators/first'; // import { switchMap } from 'rxjs/operators/switchMap'; // import { takeUntil } from 'rxjs/operators'; // import { AddressFormComponent } from './address-form/address-form.component'; // import { AddressRemoveComponent } from './address-remove/address-remove.component'; // import { ErrorComponent } from '../shared/error/error.component'; // import { LocationService } from '../location/location.service'; class AddressComponent { // private _canAdd: boolean; // private _canEdit: boolean; // private _canRemove: boolean; // private _user: User; // private destroy: Subject<boolean>; // address: Address; // @Input('canAdd') // get canAdd(): boolean { // return this.user && ((this._canAdd === undefined || this._canAdd === null) ? true : this._canAdd); // } // set canAdd(value: boolean) { // this._canAdd = value; // } // @Input('canEdit') // get canEdit(): boolean { // return (this._canEdit === undefined || this._canEdit === null) ? true : this._canEdit; // } // set canEdit(value: boolean) { // this._canEdit = value; // } // @Input('canRemove') // get canRemove(): boolean { // return (this._canRemove === undefined || this._canRemove === null) ? true : this._canRemove; // } // set canRemove(value: boolean) { // this._canRemove = value; // } // @Input() // color: string; // @Input('user') // get user(): User { // return this._user; // } // set user(user: User) { // this._user = user; // if (this._user && this._user.address) { // if (!(this._user.address instanceof Array)) { // this._user.address = [this._user.address as Address]; // } // if (!this.address && this._user.address.length > 0) { // const index = this._user.address.findIndex(a => a.default); // this.address = this._user.address[(index === -1) ? 0 : index]; // this.change.emit(this.address); // } // } // } // @Output() // add: EventEmitter<boolean>; // @Output() // change: EventEmitter<Address>; // @Output() // remove: EventEmitter<boolean>; // @Output() // update: EventEmitter<boolean>; // constructor( // private dialog: MatDialog, // private snackBar: MatSnackBar, // private renderer: Renderer2, // private locationService: LocationService, // private userService: UserService // ) { // this.destroy = new Subject<boolean>(); // this.add = new EventEmitter<boolean>(); // this.change = new EventEmitter<Address>(); // this.update = new EventEmitter<boolean>(); // this.remove = new EventEmitter<boolean>(); // } ngOnInit() { // this.locationService.addOpenStreetMapTags(this.renderer); } ngOnDestroy() { // this.destroy.next(true); // this.locationService.removeOpenStreetMapTags(this.renderer); } } /** @nocollapse */ /** @nocollapse */ AddressComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AddressComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ /** @nocollapse */ AddressComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.0", type: AddressComponent, selector: "xit-address", ngImport: i0, template: "<!-- <div class=\"address-content\">\r\n <h3 i18n=\"address selection title|S\u00E9lectionnez une adresse@@addressSelectionTitle\">S\u00E9lectionnez une adresse</h3>\r\n <div *ngIf=\"user?.address\">\r\n <mat-form-field appearance=\"standard\" [color]=\"color || 'primary'\">\r\n <mat-label><span i18n=\"address book text|Votre carnet d'adresse@@addressBookText\">Votre carnet d'adresse</span></mat-label>\r\n <mat-select placeholder=\"Choisissez une adresse\" [ngModel]=\"address\" (ngModelChange)=\"addressChange($event)\">\r\n <mat-option *ngFor=\"let a of user?.address; trackBy: trackByIndex;\" [value]=\"a\">\r\n <span>{{ a?.streetAddress }}</span>\r\n <span i18n=\"default address|Adresse par d\u00E9faut@@defaultAddress\" *ngIf=\"a?.default\"> (d\u00E9faut)</span>\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <h3 i18n=\"detail address|Adresse compl\u00E8te@@detailAddress\">Adresse compl\u00E8te</h3>\r\n <div *ngIf=\"!address\">\r\n <span i18n=\"empty address|Aucune adresse@@emptyAddress\">Aucune adresse s\u00E9lectionn\u00E9e</span>\r\n </div>\r\n <div *ngIf=\"address\">\r\n <div class=\"mat-body-2\">{{ address?.streetAddress }}</div>\r\n <div class=\"mat-body-1\">\r\n <span>{{ address?.postalCode }}</span>\r\n <span i18n=\"address separator|S\u00E9parateur d'adresse@@addressSeparator\">, </span>\r\n <span>{{ address?.locality }}</span>\r\n </div>\r\n <div class=\"mat-body-1\" *ngIf=\"address?.state\">{{ address?.state }}</div>\r\n <div class=\"mat-body-1\">{{ address?.country }}</div>\r\n </div>\r\n </div>\r\n <div class=\"empty-address-book\" *ngIf=\"!user?.address\">\r\n <span i18n=\"empty address book|Votre carnet d'adresse est vide@@emptyAddressBook\">Votre carnet d'adresse est vide</span>\r\n </div>\r\n</div>\r\n<div class=\"address-actions\" *ngIf=\"canAdd || canEdit || canRemove\">\r\n <div *ngIf=\"address\">\r\n <button mat-icon-button type=\"button\" (click)=\"removeAddress()\" *ngIf=\"canRemove\">\r\n <fa-icon [icon]=\"['fas', 'trash']\" size=\"lg\"></fa-icon>\r\n </button>\r\n <button mat-icon-button type=\"button\" (click)=\"editAddress()\" *ngIf=\"canEdit\">\r\n <fa-icon [icon]=\"['fas', 'pen']\" size=\"lg\"></fa-icon>\r\n </button>\r\n </div>\r\n <button mat-icon-button type=\"button\" (click)=\"addAddress()\" *ngIf=\"canAdd\">\r\n <fa-icon [icon]=\"['fas', 'plus']\" size=\"lg\"></fa-icon>\r\n </button>\r\n</div> -->\r\n", styles: [""] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: AddressComponent, decorators: [{ type: Component, args: [{ selector: 'xit-address', template: "<!-- <div class=\"address-content\">\r\n <h3 i18n=\"address selection title|S\u00E9lectionnez une adresse@@addressSelectionTitle\">S\u00E9lectionnez une adresse</h3>\r\n <div *ngIf=\"user?.address\">\r\n <mat-form-field appearance=\"standard\" [color]=\"color || 'primary'\">\r\n <mat-label><span i18n=\"address book text|Votre carnet d'adresse@@addressBookText\">Votre carnet d'adresse</span></mat-label>\r\n <mat-select placeholder=\"Choisissez une adresse\" [ngModel]=\"address\" (ngModelChange)=\"addressChange($event)\">\r\n <mat-option *ngFor=\"let a of user?.address; trackBy: trackByIndex;\" [value]=\"a\">\r\n <span>{{ a?.streetAddress }}</span>\r\n <span i18n=\"default address|Adresse par d\u00E9faut@@defaultAddress\" *ngIf=\"a?.default\"> (d\u00E9faut)</span>\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <h3 i18n=\"detail address|Adresse compl\u00E8te@@detailAddress\">Adresse compl\u00E8te</h3>\r\n <div *ngIf=\"!address\">\r\n <span i18n=\"empty address|Aucune adresse@@emptyAddress\">Aucune adresse s\u00E9lectionn\u00E9e</span>\r\n </div>\r\n <div *ngIf=\"address\">\r\n <div class=\"mat-body-2\">{{ address?.streetAddress }}</div>\r\n <div class=\"mat-body-1\">\r\n <span>{{ address?.postalCode }}</span>\r\n <span i18n=\"address separator|S\u00E9parateur d'adresse@@addressSeparator\">, </span>\r\n <span>{{ address?.locality }}</span>\r\n </div>\r\n <div class=\"mat-body-1\" *ngIf=\"address?.state\">{{ address?.state }}</div>\r\n <div class=\"mat-body-1\">{{ address?.country }}</div>\r\n </div>\r\n </div>\r\n <div class=\"empty-address-book\" *ngIf=\"!user?.address\">\r\n <span i18n=\"empty address book|Votre carnet d'adresse est vide@@emptyAddressBook\">Votre carnet d'adresse est vide</span>\r\n </div>\r\n</div>\r\n<div class=\"address-actions\" *ngIf=\"canAdd || canEdit || canRemove\">\r\n <div *ngIf=\"address\">\r\n <button mat-icon-button type=\"button\" (click)=\"removeAddress()\" *ngIf=\"canRemove\">\r\n <fa-icon [icon]=\"['fas', 'trash']\" size=\"lg\"></fa-icon>\r\n </button>\r\n <button mat-icon-button type=\"button\" (click)=\"editAddress()\" *ngIf=\"canEdit\">\r\n <fa-icon [icon]=\"['fas', 'pen']\" size=\"lg\"></fa-icon>\r\n </button>\r\n </div>\r\n <button mat-icon-button type=\"button\" (click)=\"addAddress()\" *ngIf=\"canAdd\">\r\n <fa-icon [icon]=\"['fas', 'plus']\" size=\"lg\"></fa-icon>\r\n </button>\r\n</div> -->\r\n", styles: [""] }] }] }); const ROUTE_DATA_BREADCRUMB = 'breadcrumb'; class BreadcrumbComponent { constructor(activatedRoute, library, router) { this.activatedRoute = activatedRoute; this.library = library; this.router = router; this.breadcrumbs = new Array(); this.library.addIcons(faAngleRight); } get class() { return true; } get homeLabel() { return this._homeLabel || 'Accueil'; } set homeLabel(value) { this._homeLabel = value; } get useParams() { return this._useParams || false; } set useParams(value) { this._useParams = value; } ngOnInit() { // subscribe to the NavigationEnd event this.router.events .pipe(filter((event) => event instanceof NavigationEnd)) .subscribe(() => this.breadcrumbs = this.getBreadcrumbs(this.activatedRoute.root)); } trackByIndex(index, value) { return index; } getBreadcrumbs(route, url = '', breadcrumbs = new Array()) { // get the child routes const children = route.children; // return if there are no more children if (children.length === 0) { return breadcrumbs; } // iterate over each children for (const child of children) { // verify the custom data property 'breadcrumb' is specified on the route if (!child.snapshot.data.hasOwnProperty(ROUTE_DATA_BREADCRUMB)) { return this.getBreadcrumbs(child, url, breadcrumbs); } // get the route's URL segment const routeURL = child.snapshot .pathFromRoot .map(v => v.url.map(segment => segment.toString()).join('/')) .join('/'); // append route URL to URL // url += `/${routeURL}`; // add breadcrumb const breadcrumb = { label: child.snapshot.data[ROUTE_DATA_BREADCRUMB], params: child.snapshot.params, url: routeURL }; if (breadcrumbs.findIndex((b) => b.label === breadcrumb.label) === -1) { breadcrumbs.push(breadcrumb); } // recursive return this.getBreadcrumbs(child, url, breadcrumbs); } } } /** @nocollapse */ /** @nocollapse */ BreadcrumbComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: BreadcrumbComponent, deps: [{ token: i1$1.ActivatedRoute }, { token: i2$1.FaIconLibrary }, { token: i1$1.Router }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ /** @nocollapse */ BreadcrumbComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.0", type: BreadcrumbComponent, selector: "xit-breadcrumb", inputs: { homeLabel: "homeLabel", useParams: "useParams" }, host: { properties: { "class.xit-breadcrumb": "this.class" } }, ngImport: i0, template: "<ol>\r\n <li><a routerLink=\"\">{{ homeLabel }}</a></li>\r\n <li *ngFor=\"let breadcrumb of breadcrumbs; trackBy: trackByIndex;\">\r\n <fa-duotone-icon [icon]=\"['fad', 'angle-right']\"></fa-duotone-icon>\r\n <a [routerLink]=\"[breadcrumb.url]\" [queryParams]=\"((useParams) ? breadcrumb.params : null)\">{{ breadcrumb.label }}</a>\r\n </li>\r\n</ol>\r\n", styles: [":host.xit-breadcrumb>ol{display:flex;list-style:none}:host.xit-breadcrumb>ol>li fa-duotone-icon{padding:0 8px}:host.xit-breadcrumb>ol>li a{color:inherit;text-decoration:none}\n"], components: [{ type: i2$1.FaDuotoneIconComponent, selector: "fa-duotone-icon", inputs: ["swapOpacity", "primaryOpacity", "secondaryOpacity", "primaryColor", "secondaryColor"] }], directives: [{ type: i1$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { type: i4$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: BreadcrumbComponent, decorators: [{ type: Component, args: [{ selector: 'xit-breadcrumb', template: "<ol>\r\n <li><a routerLink=\"\">{{ homeLabel }}</a></li>\r\n <li *ngFor=\"let breadcrumb of breadcrumbs; trackBy: trackByIndex;\">\r\n <fa-duotone-icon [icon]=\"['fad', 'angle-right']\"></fa-duotone-icon>\r\n <a [routerLink]=\"[breadcrumb.url]\" [queryParams]=\"((useParams) ? breadcrumb.params : null)\">{{ breadcrumb.label }}</a>\r\n </li>\r\n</ol>\r\n", styles: [":host.xit-breadcrumb>ol{display:flex;list-style:none}:host.xit-breadcrumb>ol>li fa-duotone-icon{padding:0 8px}:host.xit-breadcrumb>ol>li a{color:inherit;text-decoration:none}\n"] }] }], ctorParameters: function () { return [{ type: i1$1.ActivatedRoute }, { type: i2$1.FaIconLibrary }, { type: i1$1.Router }]; }, propDecorators: { class: [{ type: HostBinding, args: ['class.xit-breadcrumb'] }], homeLabel: [{ type: Input }], useParams: [{ type: Input }] } }); class FileService { constructor(config, http, errorService, logService) { this.config = config; this.http = http; this.errorService = errorService; this.logService = logService; // tslint:disable-next-line:max-line-length this.fileUrl = `${this.config.url}/${this.config.version}/${this.config.services.files}`; } getById(id) { const operation = 'File service (getById)'; return this.http.get(`${this.fileUrl}/${id}`) .pipe(map((response) => ({ data: response.body, height: response.headers.get('xit-file-height'), name: response.headers.get('xit-file-name'), width: response.headers.get('xit-file-width') })), tap((result) => this.logService.log(operation, result)), catchError(this.errorService.handleError(operation))); } getFileInfo(id) { const operation = 'File service (getFileInfo)'; return this.http .get(`${this.fileUrl}/${id}/infos`) .pipe(tap((result) => this.logService.log(operation, result)), catchError(this.errorService.handleError(operation))); } download(id, startCallback, endCallback) { const operation = 'File service (download)'; if (startCallback) { startCallback(); } this.http .get(`${this.fileUrl}/${id}/download`, { observe: 'response', responseType: 'blob' }) .pipe(first(), tap((data) => this.logService.log(operation, data)), catchError(this.errorService.handleError(operation))) .subscribe((response) => { if (endCallback) { endCallback(); } const url = window.URL.createObjectURL(response.body); const a = document.createElement('a'); a.setAttribute('style', 'display: none'); a.href = url; a.download = response.headers.get('xit-file-name'); document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); a.remove(); }); } rename(id, name) { const operation = 'File service (rename)'; return this.http .put(`${this.fileUrl}/${id}/rename`, JSON.stringify(name)) .pipe(first(), tap((data) => this.logService.log(operation, data)), catchError(this.errorService.handleError(operation))); } resize(id, q, w, h, s) { const operation = 'File service (resize)'; const params = new Array(); if (q) { params.push(`q=${q}`); } if (w) { params.push(`w=${w}`); } if (h) { params.push(`h=${h}`); } if (s) { params.push(`s=${s}`); } return this.http .get(`${this.fileUrl}/${id}/resize${(params.length > 0) ? '?'.concat(params.join('&')) : ''}`, { observe: 'response', responseType: 'blob' }) .pipe(map((response) => ({ data: response.body, height: response.headers.get('xit-file-height'), name: response.headers.get('xit-file-name'), width: response.headers.get('xit-file-width') })), tap((data) => this.logService.log(operation, data)), catchError(this.errorService.handleError(operation))); } crop(id, q, x, y, w, h, s) { const operation = 'File service (crop)'; const params = new Array(); if (q) { params.push(`q=${q}`); } if (x) { params.push(`x=${x}`); } if (y) { params.push(`y=${y}`); } if (w) { params.push(`w=${w}`); } if (h) { params.push(`h=${h}`); } if (s) { params.push(`s=${s}`); } return this.http .get(`${this.fileUrl}/${id}/crop${(params.length > 0) ? '?'.concat(params.join('&')) : ''}`, { observe: 'response', responseType: 'blob' }) .pipe(map((response) => ({ data: response.body, height: response.headers.get('xit-file-height'), name: response.headers.get('xit-file-name'), width: response.headers.get('xit-file-width') })), tap((data) => this.logService.log(operation, data)), catchError(this.errorService.handleError(operation))); } resizeAndCrop(id, q, x, y, w, h, s) { const operation = 'File service (resizeAndCrop)'; const params = new Array(); if (q) { params.push(`q=${q}`); } if (x) { params.push(`x=${x}`); } if (y) { params.push(`y=${y}`); } if (w) { params.push(`w=${w}`); } if (h) { params.push(`h=${h}`); } if (s) { params.push(`s=${s}`); } return this.http .get(`${this.fileUrl}/${id}/resizeandcrop${(params.length > 0) ? '?'.concat(params.join('&')) : ''}`, { observe: 'response', responseType: 'blob' }) .pipe(map((response) => ({ data: response.body, height: response.headers.get('xit-file-height'), name: response.headers.get('xit-file-name'), width: response.headers.get('xit-file-width') })), tap((data) => this.logService.log(operation, data)), catchError(this.errorService.handleError(operation))); } } /** @nocollapse */ /** @nocollapse */ FileService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: FileService, deps: [{ token: UTILITY_CONFIG }, { token: i1.HttpClient }, { token: ErrorService }, { token: LogService }], target: i0.ɵɵFactoryTarget.Injectable }); /** @nocollapse */ /** @nocollapse */ FileService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: FileService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: FileService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [UTILITY_CONFIG] }] }, { type: i1.HttpClient }, { type: ErrorService }, { type: LogService }]; } }); class CanvasDirective { constructor(mediaObserver, elementRef, fileService) { this.mediaObserver = mediaObserver; this.elementRef = elementRef; this.fileService = fileService; this.hostClass = true; // elementRef.nativeElement.classList.add('xit-canvas'); this.change = new EventEmitter(); this.destroy = new Subject(); this.loaded = false; this.loading = new EventEmitter(); } get fileId() { return this._fileId; } set fileId(value) { if (this._fileId !== value) { this._fileId = value; if (value) { this.loadFile(); } } } ngOnInit() { this.mediaObserver.media$ .pipe(takeUntil(this.destroy)) .subscribe(() => { if (this.loaded && this.fileId) { this.loadFile(); } }); } ngOnDestroy() { this.destroy.next(true); } loadFile() { // Le settimeout permet au DOM de se créer avant de dessiner le canvas (pour le redimensionnement) setTimeout(() => { // const canvas = this.elementRef.nativeElement as HTMLCanvasElement; const service = (this.type === 'crop') ? this.fileService.resizeAndCrop(this.fileId, this.original ? undefined : 95, 0, 0, this.original ? undefined : this.elementRef.nativeElement.clientWidth, this.original ? undefined : this.elementRef.nativeElement.clientHeight, this.original ? `${window.innerWidth}x${window.innerHeight}` : undefined) : this.fileService.resize(this.fileId, this.original ? undefined : 95, this.original ? undefined : this.elementRef.nativeElement.clientWidth, this.original ? undefined : this.elementRef.nativeElement.clientHeight, this.original ? `${window.innerWidth}x${window.innerHeight}` : undefined); this.loading.emit(true); service .pipe(takeUntil(this.destroy)) .subscribe((file) => { // Émission des events this.loading.emit(false); this.change.emit(file); // Renseigne l'identifiant du fichier this.file = file; if (!this.file.id) { this.file.id = this.fileId; } // Dessine l'image sur le canvas if (file && file.data) { const reader = new FileReader(); reader.addEventListener('load', () => { this.drawImage(file, reader); }, false); reader.readAsDataURL(file.data); } }, () => { this.loading.emit(false); this.change.emit(null); this.file = null; this.drawEmpty(); }); }); } drawEmpty() { const canvas = this.elementRef.nativeElement; // this.renderer.createElement('canvas') as HTMLCanvasElement; const context = canvas.getContext('2d'); if (context) { context.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight); } } drawImage(file, reader) { // Récupère l'objet hôte canvas const canvas = this.elementRef.nativeElement; // this.renderer.createElement('canvas') as HTMLCanvasElement; // Charge le context 2D du canvas const context = canvas.getContext('2d'); // Crée une image cons