UNPKG

cocori-ng

Version:

Cocori-ng is an Angular full of great components & utilites based on Material

1 lines 118 kB
{"version":3,"file":"cocori-ng-src-feature-core.mjs","sources":["../../../projects/cocori-ng/src/feature-core/service/http.service.ts","../../../projects/cocori-ng/src/feature-core/service/storage.service.ts","../../../projects/cocori-ng/src/feature-core/service/token.service.ts","../../../projects/cocori-ng/src/feature-core/service/broadcast-event.service.ts","../../../projects/cocori-ng/src/feature-core/service/interceptors/global-error-interceptor.service.ts","../../../projects/cocori-ng/src/feature-core/service/interceptors/loading-interceptor.service.ts","../../../projects/cocori-ng/src/feature-core/service/interceptors/request-interceptor.service.ts","../../../projects/cocori-ng/src/feature-core/service/sort/sort.service.ts","../../../projects/cocori-ng/src/feature-core/service/scroll.service.ts","../../../projects/cocori-ng/src/feature-core/service/inject-component.service.ts","../../../projects/cocori-ng/src/feature-core/service/helper/helper.service.ts","../../../projects/cocori-ng/src/feature-core/service/validators.service.ts","../../../projects/cocori-ng/src/feature-core/service/current-url-routing.service.ts","../../../projects/cocori-ng/src/feature-core/service/odata-query-builder/enums.ts","../../../projects/cocori-ng/src/feature-core/service/odata-query-builder/queryFragment.ts","../../../projects/cocori-ng/src/feature-core/service/odata-query-builder/queryBuilder.ts","../../../projects/cocori-ng/src/feature-core/service/file/file.service.ts","../../../projects/cocori-ng/src/feature-core/service/form-map-value/mapping.service.ts","../../../projects/cocori-ng/src/feature-core/service/helper/helper-form.service.ts","../../../projects/cocori-ng/src/feature-core/service/helper/url-helper.ts","../../../projects/cocori-ng/src/feature-core/service/helper/helper-uploader.service.ts","../../../projects/cocori-ng/src/feature-core/service/wysiwyg.service.ts","../../../projects/cocori-ng/src/feature-core/model/data-source.model.ts","../../../projects/cocori-ng/src/feature-core/service/datasource.service.ts","../../../projects/cocori-ng/src/feature-core/service/string.service.ts","../../../projects/cocori-ng/src/feature-core/model/odata.model.ts","../../../projects/cocori-ng/src/feature-core/model/form-input-components.model.ts","../../../projects/cocori-ng/src/feature-core/model/schema-datas.model.ts","../../../projects/cocori-ng/src/feature-core/model/component-inputs.model.ts","../../../projects/cocori-ng/src/feature-core/cocori-ng-src-feature-core.ts"],"sourcesContent":["import { HttpBackend, HttpClient, HttpEvent, HttpHeaders, HttpParams } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\nimport { map } from 'rxjs/operators';\r\n\r\nexport enum SkipHeaders {\r\n TRUE = 'true',\r\n FALSE = 'false',\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class HttpService {\r\n protected withCredentialsOption: boolean = false;\r\n httpWithoutInterceptor: HttpClient;\r\n\r\n private skip: SkipHeaders = SkipHeaders.FALSE;\r\n\r\n constructor(\r\n private http: HttpClient,\r\n private httpBackend: HttpBackend\r\n ) {\r\n this.httpWithoutInterceptor = new HttpClient(httpBackend);\r\n }\r\n\r\n public set withCredentials(value: boolean) {\r\n this.withCredentialsOption = value;\r\n }\r\n\r\n public get withCredentials() {\r\n return this.withCredentialsOption;\r\n }\r\n\r\n /** TODO: à tester car pas sûr que cela fonctionne... */\r\n delete<T>(path: string, params?: Object, skip: string = SkipHeaders.FALSE): Observable<T> {\r\n let options = { params: this.buildUrlParams(params), withCredentials: this.withCredentialsOption }\r\n\r\n if (skip === SkipHeaders.FALSE) {\r\n\r\n options['headers'] = { skip: skip }\r\n\r\n return this.http.delete(`${path}`, options)\r\n .pipe(\r\n map(this.extractData.bind(this))\r\n ) as Observable<T>;\r\n } else {\r\n return this.httpWithoutInterceptor.delete(`${path}`, options)\r\n .pipe(\r\n map(this.extractData.bind(this))\r\n ) as Observable<T>;\r\n }\r\n }\r\n\r\n get<T>(path: string, params?: Object, skip: string = SkipHeaders.FALSE): Observable<T> {\r\n let options = { params: this.buildUrlParams(params), withCredentials: this.withCredentialsOption }\r\n\r\n if (skip === SkipHeaders.FALSE) {\r\n options['headers'] = { skip: skip }\r\n\r\n return this.http.get(`${path}`, options)\r\n .pipe(map(this.extractData.bind(this)))\r\n } else {\r\n return this.httpWithoutInterceptor.get(`${path}`, options)\r\n .pipe(map(this.extractData.bind(this)))\r\n }\r\n }\r\n\r\n post<T>(path: string, body: Object = {}, skip: string = SkipHeaders.FALSE): Observable<T> {\r\n let options: Object = { withCredentials: this.withCredentialsOption }\r\n\r\n if (skip === SkipHeaders.FALSE) {\r\n options['headers'] = new HttpHeaders().set('skip', skip)\r\n\r\n return this.http.post(\r\n `${path}`,\r\n JSON.stringify(body),\r\n options\r\n ).pipe(map(this.extractData.bind(this)))\r\n } else {\r\n options['headers'] = new HttpHeaders()\r\n .set('Content-Type', 'application/json; charset=utf-8')\r\n\r\n return this.httpWithoutInterceptor.post(\r\n `${path}`,\r\n JSON.stringify(body),\r\n options\r\n ).pipe(map(this.extractData.bind(this)))\r\n }\r\n }\r\n\r\n put<T>(path: string, body: Object = {}, skip: string = SkipHeaders.FALSE): Observable<any> {\r\n let options = { withCredentials: this.withCredentialsOption }\r\n\r\n if (skip === SkipHeaders.FALSE) {\r\n options['headers'] = { skip: skip }\r\n\r\n return this.http.put(\r\n `${path}`,\r\n JSON.stringify(body),\r\n options\r\n ).pipe(map(this.extractData.bind(this)))\r\n } else {\r\n return this.httpWithoutInterceptor.put(`${path}`, JSON.stringify(body))\r\n .pipe(map(this.extractData.bind(this)))\r\n }\r\n }\r\n\r\n patch<T>(path: string, body: Object = {}, skip: string = SkipHeaders.FALSE): Observable<T> {\r\n let options: Object = { withCredentials: this.withCredentialsOption }\r\n\r\n if (skip === SkipHeaders.FALSE) {\r\n options['headers'] = new HttpHeaders().set('skip', skip)\r\n\r\n return this.http.patch(\r\n `${path}`,\r\n JSON.stringify(body),\r\n options\r\n ).pipe(map(this.extractData.bind(this)))\r\n } else {\r\n options['headers'] = new HttpHeaders()\r\n .set('Content-Type', 'application/json; charset=utf-8')\r\n\r\n return this.httpWithoutInterceptor.patch(\r\n `${path}`,\r\n JSON.stringify(body),\r\n options\r\n ).pipe(map(this.extractData.bind(this)))\r\n }\r\n }\r\n\r\n file<T>(path: string, params?: Object): Observable<T> {\r\n return this.http.get(`${path}`, { params: this.buildUrlParams(params), withCredentials: this.withCredentialsOption, responseType: 'blob' })\r\n .pipe(\r\n map(this.extractData.bind(this))\r\n ) as Observable<T>;\r\n }\r\n\r\n upload<T>(path: string, body: Object = {}, options: Object = { withCredentials: this.withCredentialsOption }): Observable<HttpEvent<T>> {\r\n options['headers'] = new HttpHeaders().set('Content-Type', 'application/json; charset=utf-8');\r\n options['reportProgress'] = true;\r\n options['observe'] = \"events\";\r\n\r\n return this.http.post(\r\n `${path}`,\r\n JSON.stringify(body),\r\n options\r\n ) as Observable<HttpEvent<T>>;\r\n }\r\n\r\n protected extractData(res: Response) {\r\n if (!res) return res\r\n\r\n const body: any = (<any>res.body);\r\n\r\n if (res.status === 204) return res.body;\r\n\r\n if (body) {\r\n return typeof res.body === 'string' ? JSON.parse(<any>res.body) : res.body;\r\n }\r\n\r\n return res;\r\n }\r\n\r\n protected buildUrlParams(parameters: any): HttpParams {\r\n let params = new HttpParams();\r\n for (const property in parameters) {\r\n if (parameters.hasOwnProperty(property)) {\r\n params = params.append(property, parameters[property]);\r\n }\r\n }\r\n return params;\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class StorageService {\r\n constructor() { }\r\n\r\n public setSessionStorageItem(key: string, item: any) {\r\n sessionStorage.setItem(key, JSON.stringify(item));\r\n }\r\n\r\n public getSessionStorageItem(key: string): any {\r\n let a = null\r\n\r\n try {\r\n a = JSON.parse(sessionStorage.getItem(key));\r\n } catch (e) {\r\n console.error(`Session storage, erreur in parsing JSON : `, e)\r\n } finally {\r\n return a\r\n }\r\n }\r\n\r\n public deleteSessionStorageItem(key: string) {\r\n sessionStorage.removeItem(key);\r\n }\r\n\r\n public setLocalStorageItem(key: string, item: any) {\r\n localStorage.setItem(key, JSON.stringify(item));\r\n }\r\n\r\n public getLocalStorageItem(key: string): any {\r\n let a = null\r\n\r\n try {\r\n a = JSON.parse(localStorage.getItem(key));\r\n } catch (e) {\r\n console.error(`Local storage, erreur in parsing JSON : `, e)\r\n } finally {\r\n return a\r\n }\r\n }\r\n\r\n public deleteLocalStorageItem(key: string) {\r\n localStorage.removeItem(key);\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\nimport { StorageService } from './storage.service';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class TokenService {\r\n\r\n constructor(private storageService: StorageService) { }\r\n\r\n get accessToken(): string {\r\n const token: string = this.storageService.getLocalStorageItem('accessToken');\r\n return token || null;\r\n }\r\n\r\n set accessToken(token: string) {\r\n this.storageService.setLocalStorageItem('accessToken', token);\r\n }\r\n\r\n get refreshToken(): string {\r\n const token: string = this.storageService.getLocalStorageItem('refreshToken');\r\n\r\n return token || null;\r\n }\r\n\r\n set refreshToken(token: string) {\r\n this.storageService.setLocalStorageItem('refreshToken', token);\r\n }\r\n\r\n deleteTokens() {\r\n this.storageService.deleteLocalStorageItem('refreshToken');\r\n this.storageService.deleteLocalStorageItem('accessToken');\r\n }\r\n\r\n decryptAccessToken<T>(): T {\r\n if (this.accessToken) {\r\n const base64Array: string[] = this.accessToken.split('.');\r\n const decodedToken = JSON.parse(window.atob(base64Array[1]));\r\n return decodedToken;\r\n }\r\n return null;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Observable, Subject } from 'rxjs';\r\nimport { filter, map } from 'rxjs/operators';\r\n\r\ninterface BroadcastEvent {\r\n eventKeys: EventKeys;\r\n eventData?: any;\r\n}\r\n\r\ninterface Event<T> {\r\n eventKey: string;\r\n event: Observable<T>;\r\n}\r\n\r\ntype EventKeys = (string | number)[];\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class BroadcastEventService {\r\n private _eventBus: Subject<BroadcastEvent>;\r\n private _broadcastedEvents: Event<any>[] = [];\r\n\r\n constructor() {\r\n this._eventBus = new Subject<BroadcastEvent>();\r\n }\r\n\r\n broadcast(event: BroadcastEvent) {\r\n this._eventBus.next(event);\r\n }\r\n\r\n listen<T>(keys: EventKeys): Observable<T> {\r\n const eventKey: string = keys.join(\"-\")\r\n\r\n if (!this.isEventKnown(eventKey)) {\r\n const newEvent: Observable<T> = this._eventBus.asObservable()\r\n .pipe(\r\n filter(event => (event.eventKeys.join(\"-\")) === eventKey),\r\n map(event => event.eventData),\r\n );\r\n\r\n this._broadcastedEvents.push(<Event<T>>{ eventKey: eventKey, event: newEvent });\r\n\r\n return newEvent;\r\n } else {\r\n return this.returnEvent(eventKey);\r\n }\r\n }\r\n\r\n private isEventKnown(eventKey: string): boolean {\r\n const index = this._broadcastedEvents.findIndex(entrée => entrée.eventKey === eventKey);\r\n\r\n return index >= 0;\r\n }\r\n\r\n private returnEvent<T>(eventKey: string): Observable<T> {\r\n const event = this._broadcastedEvents.find(event => event.eventKey === eventKey);\r\n\r\n return event.event;\r\n }\r\n}\r\n","import { ErrorHandler, Injectable, Injector } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\n\r\nimport { StorageService } from '../storage.service';\r\n\r\nconst LIMIT_MAX_RELOAD: number = 2\r\nconst TIME_MAX_RELOAD: number = 30 // secondes\r\n\r\nexport interface ReloadPageModel {\r\n date: Date,\r\n count: number,\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class GlobalErrorInterceptorService implements ErrorHandler {\r\n // public globalErrorsHandlerSubject: Subject<boolean> = new Subject<boolean>();\r\n\r\n constructor(\r\n private injector: Injector,\r\n private storageService: StorageService) { }\r\n\r\n handleError(error: any): void {\r\n const chunkFailedMessage = /Loading chunk [\\d]+ failed/;\r\n\r\n const router = this.injector.get(Router);\r\n\r\n if (error.stack) {\r\n console.error(\"details errors 😱 :\");\r\n console.error(error.stack.toString());\r\n } else {\r\n console.error(\"error undefined 😡\");\r\n }\r\n\r\n if (chunkFailedMessage.test(error.message)) {\r\n // this.globalErrorsHandlerSubject.next(true)\r\n this.handleReloadPage(error.message.toString())\r\n }\r\n }\r\n\r\n private handleReloadPage(message: string) {\r\n console.log('%cPage reloaded : errors chunk versions', 'color: blue;')\r\n\r\n const reloadPage: ReloadPageModel = this.storageService.getSessionStorageItem('reloadPage');\r\n\r\n if (!reloadPage) {\r\n this.storageService.setSessionStorageItem('reloadPage', <ReloadPageModel>{ date: new Date(), count: 1 })\r\n } else if (reloadPage.count < LIMIT_MAX_RELOAD && (new Date().getTime() - new Date(reloadPage.date).getTime()) / 1000 < TIME_MAX_RELOAD) {\r\n this.storageService.setSessionStorageItem('reloadPage', <ReloadPageModel>{ date: reloadPage.date, count: reloadPage.count + 1 })\r\n } else {\r\n\r\n message = `Veuillez communiquer cette erreur à l'administrateur du site : \\n\\n ${message}`\r\n\r\n alert(message)\r\n\r\n this.storageService.deleteSessionStorageItem('reloadPage')\r\n return;\r\n }\r\n\r\n window.location.reload();\r\n }\r\n}","import { HttpEvent, HttpHandler, HttpRequest } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\nimport { finalize } from 'rxjs/operators';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class LoadingService {\r\n subject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);\r\n\r\n constructor() { }\r\n\r\n startLoading() {\r\n this.subject.next(true);\r\n }\r\n\r\n stopLoading() {\r\n this.subject.next(false);\r\n }\r\n}\r\n\r\n@Injectable({\r\n providedIn: \"root\",\r\n})\r\nexport class LoadingInterceptorService {\r\n activeRequests: number = 0;\r\n timer: any;\r\n\r\n constructor(private loadingScreenService: LoadingService) { }\r\n\r\n intercept(\r\n request: HttpRequest<any>,\r\n next: HttpHandler\r\n ): Observable<HttpEvent<any>> {\r\n if (this.activeRequests === 0) {\r\n this.loadingScreenService.startLoading();\r\n }\r\n\r\n this.activeRequests++;\r\n\r\n clearTimeout(this.timer);\r\n\r\n this.timer = setTimeout(() => {\r\n this.forceFinalize();\r\n }, 5000);\r\n\r\n return next.handle(request).pipe(\r\n finalize(() => {\r\n this.activeRequests--;\r\n\r\n if (this.activeRequests === 0) {\r\n this.loadingScreenService.stopLoading();\r\n\r\n clearTimeout(this.timer);\r\n }\r\n })\r\n );\r\n }\r\n\r\n forceFinalize() {\r\n this.activeRequests = 0;\r\n this.loadingScreenService.stopLoading();\r\n }\r\n}\r\n","import { HttpHandler, HttpHeaders, HttpInterceptor, HttpRequest } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\n\r\nimport { HttpService, SkipHeaders } from '../http.service';\r\nimport { TokenService } from '../token.service';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class RequestInterceptorService implements HttpInterceptor {\r\n\r\n constructor(\r\n private tokenService: TokenService,\r\n private httpService: HttpService) { }\r\n\r\n intercept(\r\n request: HttpRequest<any>, next: HttpHandler\r\n ): Observable<any> {\r\n\r\n request = this.addAccessTokenRequest(request);\r\n\r\n return next.handle(request);\r\n }\r\n\r\n addAccessTokenRequest(request, token?) {\r\n const accessToken = token || this.tokenService.accessToken;\r\n\r\n if (request.headers.get(\"skip\") === SkipHeaders.TRUE) {\r\n return request = request.clone({\r\n headers: request.headers.delete('skip')\r\n });\r\n }\r\n\r\n if (!accessToken) {\r\n return request;\r\n }\r\n\r\n return request.clone({\r\n headers: new HttpHeaders({\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${accessToken}`\r\n })\r\n });\r\n }\r\n}","import { Injectable } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SortService {\r\n sortObjectByKeys(objectData: any): any {\r\n return Object.keys(objectData).sort().reduce(\r\n (obj: any, key: string) => {\r\n obj[key] = objectData[key];\r\n return obj;\r\n }, {}\r\n );\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Subject } from 'rxjs';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class ScrollService {\r\n public scrollingNativeElement: HTMLElement\r\n public onScroll: Subject<boolean> = new Subject<boolean>();\r\n\r\n constructor() { }\r\n\r\n private currentScrollPosition() {\r\n // Firefox, Chrome, Opera, Safari\r\n if (self.pageYOffset) return self.pageYOffset;\r\n // Internet Explorer 6 - standards mode\r\n if (document.documentElement && document.documentElement.scrollTop) {\r\n return document.documentElement.scrollTop;\r\n }\r\n // Internet Explorer 6, 7 and 8\r\n if (document.body.scrollTop) return document.body.scrollTop;\r\n return 0;\r\n }\r\n\r\n private getElementDomPosition(elm) {\r\n let y = elm.offsetTop - 100;\r\n let node: any = elm;\r\n\r\n while (node.offsetParent && node.offsetParent !== document.body) {\r\n node = node.offsetParent;\r\n y += node.offsetTop;\r\n } return y;\r\n }\r\n\r\n scrollToTop() {\r\n const that = this;\r\n let timeOut;\r\n if (document.body.scrollTop !== 0 || document.documentElement.scrollTop !== 0) {\r\n window.scrollBy(0, -50);\r\n\r\n timeOut = setTimeout(function () {\r\n that.scrollToTop();\r\n }, 10);\r\n\r\n } else {\r\n clearTimeout(timeOut);\r\n }\r\n }\r\n\r\n scrollToIdSmooth(eID) {\r\n const startY = this.currentScrollPosition();\r\n const elm = document.getElementById(eID);\r\n const stopY = this.getElementDomPosition(elm);\r\n const distance = stopY > startY ? stopY - startY : startY - stopY;\r\n if (distance < 100) {\r\n scrollTo(0, stopY); return;\r\n }\r\n let speed = Math.round(distance / 100);\r\n\r\n if (speed >= 20) {\r\n speed = 20;\r\n }\r\n\r\n const step = Math.round(distance / 25);\r\n let leapY = stopY > startY ? startY + step : startY - step;\r\n let timer = 0;\r\n if (stopY > startY) {\r\n for (let i = startY; i < stopY; i += step) {\r\n setTimeout(\"window.scrollTo(0, \" + leapY + \")\", timer * speed);\r\n leapY += step; if (leapY > stopY) leapY = stopY; timer++;\r\n } return;\r\n }\r\n for (let i = startY; i > stopY; i -= step) {\r\n setTimeout(\"window.scrollTo(0, \" + leapY + \")\", timer * speed);\r\n leapY -= step; if (leapY < stopY) leapY = stopY; timer++;\r\n }\r\n return false;\r\n }\r\n\r\n getScrollDistanceTo(eID): number {\r\n const elm = document.getElementById(eID);\r\n\r\n if (!elm) return -1; // element not found\r\n\r\n const stopY = this.getElementDomPosition(elm);\r\n\r\n return stopY\r\n }\r\n}\r\n","import { Injectable, Type, ViewContainerRef } from '@angular/core';\r\n\r\nexport interface InputsComponent {\r\n [key: string]: any;\r\n}\r\n\r\nexport interface OutputsComponent {\r\n [key: string]: Function;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class InjectComponentService {\r\n componentsRefs: any[] = [];\r\n\r\n /**\r\n * Exemple d'utilisation:\r\n \r\n * this.injectComponentService.loadAndAddComponentToContainer(MyClasseComponent, #DomReference,\r\n { @InputName_1: Value, @InputName_2: Value }, { @OutputName_1: (valueEmited: any) => this.callback(valueEmited)})\r\n * Ou si le composant n'a pas de @Output\r\n * this.injectComponentService.loadAndAddComponentToContainer(MyClasseComponent, #DomReference,\r\n { @InputName_1: Value, @InputName_2: Value }, null)\r\n */\r\n loadAndAddComponentToContainer(\r\n componentClass: Type<any>,\r\n viewContainerRef: ViewContainerRef,\r\n inputs: InputsComponent,\r\n outputs?: OutputsComponent,\r\n index?: number\r\n ) {\r\n // const factory = this.componentFactoryResolver.resolveComponentFactory(componentClass);\r\n const componentRef = viewContainerRef.createComponent(componentClass, { index: index ? index : null });\r\n\r\n /** inputs */\r\n for (const [key, value] of Object.entries(inputs)) {\r\n (componentRef.instance)[key] = value;\r\n }\r\n\r\n /** outputs */\r\n if (outputs) {\r\n for (const [key, value] of Object.entries(outputs)) {\r\n if (key && value && (componentRef.instance)[key]) (componentRef.instance)[key].subscribe(data => value(data));\r\n }\r\n }\r\n\r\n componentRef.changeDetectorRef.detectChanges();\r\n\r\n this.componentsRefs.push(componentRef);\r\n }\r\n\r\n removeComponentFromViewContainer(index: number, viewContainerRef: ViewContainerRef) {\r\n viewContainerRef.remove(index);\r\n\r\n this.componentsRefs.splice(index, 1);\r\n }\r\n\r\n moveComponentFromViewContainer(currentIndex: number, previousIndex: number, viewContainerRef: ViewContainerRef) {\r\n viewContainerRef.move(viewContainerRef.get(previousIndex), currentIndex);\r\n\r\n this.componentsRefs.splice(previousIndex, 0, this.componentsRefs.splice(currentIndex, 1)[0]);\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class HelperService {\r\n\r\n generateGuid(): string {\r\n return this.s4() + this.s4() + '-' + this.s4() + '-' + this.s4() + '-' +\r\n this.s4() + '-' + this.s4() + this.s4() + this.s4();\r\n }\r\n\r\n private s4() {\r\n return Math.floor((1 + Math.random()) * 0x10000)\r\n .toString(16)\r\n .substring(1);\r\n }\r\n\r\n removeValueFromArrayByIndex(arrayValues: any[], index: number): any[] {\r\n if (index === -1) return arrayValues;\r\n return [...arrayValues.slice(0, index), ...arrayValues.slice(index + 1)];\r\n }\r\n\r\n /** arrondir un nombre */\r\n roundUp(num: number, precision: number) {\r\n precision = Math.pow(10, precision)\r\n return Math.ceil(num * precision) / precision\r\n }\r\n\r\n /** */\r\n\r\n static retourneNomDeDomaine(): string {\r\n return location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '');\r\n }\r\n\r\n static enleverNomDomaineUrl(url: string): string {\r\n if (!url) return null;\r\n\r\n if (!/^http[s]?:\\/\\//.test(url)) return url;\r\n\r\n const urlSansHttp: string[] = url.split(/^http[s]?:\\/\\//);\r\n\r\n const indexSlash: number = urlSansHttp[1].indexOf(\"/\");\r\n\r\n const urlValide: string = urlSansHttp[1].substring(indexSlash);\r\n\r\n return urlValide;\r\n }\r\n\r\n static retourneSegmentsURL(): string[] {\r\n const pathName: string = window.location.pathname;\r\n // on supprime du pathname le dernier caractères s'il s'agit d'un /\r\n return pathName.replace(/\\/$/, '').split('/');\r\n }\r\n\r\n static ouvrirUrlExterne(lien: string, estceNouvelOnglet: boolean = false) {\r\n if (!this.retourneNullSiNonDéfini(lien)) return;\r\n\r\n let url: string = '';\r\n if (!/^http[s]?:\\/\\//.test(lien)) {\r\n url += 'http://';\r\n }\r\n\r\n url += lien;\r\n\r\n if (estceNouvelOnglet) {\r\n window.open(url);\r\n } else {\r\n window.location.href = url;\r\n }\r\n }\r\n\r\n static nettoyerParametresUrl(ancienneUrl: string): string {\r\n let index = 0;\r\n let nouvelleUrl = ancienneUrl;\r\n index = ancienneUrl.indexOf('?');\r\n\r\n if (index === -1) {\r\n index = ancienneUrl.indexOf('#');\r\n }\r\n if (index !== -1) {\r\n nouvelleUrl = ancienneUrl.substring(0, index);\r\n }\r\n\r\n return nouvelleUrl;\r\n }\r\n\r\n static construireUrl(url: string): string {\r\n return this.retourneNomDeDomaine() + '/' + url;\r\n }\r\n\r\n static segmentsURL(url: string): string[] {\r\n if (!url) return [];\r\n // on supprime de l'url le 1er / et le de dernier /\r\n return url.replace(/\\/*/, '').replace(/\\/$/, '').split('/');\r\n }\r\n\r\n\r\n static estceUrlValide(string) {\r\n const res = string.match(/(http(s)?:\\/\\/.)?(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)/g);\r\n if (!res) {\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n }\r\n\r\n static encoderParamètresUrl(data): string {\r\n const ret = [];\r\n\r\n for (const key in data) {\r\n if (data.hasOwnProperty(key)) {\r\n const element = data[key];\r\n\r\n ret.push(encodeURIComponent(key) + '=' + encodeURIComponent(element));\r\n }\r\n }\r\n\r\n return ret.join('&');\r\n }\r\n\r\n static concaténerParamètresUrl(url: string, paramètres: string): string {\r\n return url + '?' + paramètres;\r\n }\r\n\r\n static ajouterParamètreUrl(url: string, param: string, value?: string): string {\r\n const a = document.createElement('a'), regex = /(?:\\?|&amp;|&)+([^=]+)(?:=([^&]*))*/g;\r\n let match = null;\r\n const str = []; a.href = url; param = encodeURIComponent(param);\r\n\r\n while (match = regex.exec(a.search)) {\r\n if (param !== match[1]) str.push(match[1] + (match[2] ? \"=\" + match[2] : \"\"));\r\n }\r\n\r\n str.push(param + (value ? \"=\" + encodeURIComponent(value) : \"\"));\r\n a.search = str.join(\"&\");\r\n return a.href;\r\n }\r\n\r\n /**\r\n * Retourne l'url courante sans les paramètres\r\n */\r\n static donneUrlCouranteSansParamètre(): string {\r\n return window.location.href.split(/[?#]/)[0];\r\n }\r\n\r\n /**\r\n * JavaScript Get URL Parameter\r\n * @param String prop The specific URL parameter you want to retreive the value for\r\n * @return String|Object If prop is provided a string value is returned, otherwise an object of all properties is returned\r\n */\r\n static donneParamètresUrl(prop?: string, urlStatique?: string): string | object {\r\n const params = {};\r\n const urlCourante = urlStatique ? urlStatique : window.location.href;\r\n const search = decodeURIComponent(urlCourante.slice(urlCourante.indexOf('?') + 1));\r\n\r\n if (search === urlCourante) return null;\r\n\r\n const definitions = search.split('&');\r\n\r\n definitions.forEach(function (val, key) {\r\n const parts = val.split('=', 2);\r\n params[parts[0]] = parts[1];\r\n });\r\n\r\n if ((prop && !(prop in params))) {\r\n return null;\r\n }\r\n\r\n return (prop && prop in params) ? params[prop] : params;\r\n }\r\n\r\n\r\n static retourneParamètresAccolades(url: string): string[] {\r\n if (!this.retourneNullSiNonDéfini(url)) {\r\n return [];\r\n }\r\n\r\n const résultat: string[] = url.match(/\\{(.*?)\\}/g); // entre {}\r\n\r\n return !résultat ? [] : résultat;\r\n }\r\n\r\n /** efface les paramètres entre accolades d'une chaîne */\r\n static effacerParamètresAccolades(chaine: string): string {\r\n return this.éviterDoubleSlash(this.replaceAll(chaine, /\\{(.*?)\\}/g, \"\"));\r\n }\r\n\r\n static remplacerParamètresAccolades(chercherDans: string, motif: string, valeur: string): string {\r\n return HelperService.replaceAll(chercherDans, `{${motif}}`, valeur);\r\n }\r\n\r\n static estceObjetVide(objet: any) {\r\n return Object.keys(objet).length === 0 && objet.constructor === Object;\r\n }\r\n\r\n /**\r\n * Détection de savoir s'il l'on vient d'une nouvelle page ou d'une page du site\r\n */\r\n static pageOuverteDepuisScript(): boolean {\r\n return window.opener !== null;\r\n }\r\n\r\n static éviterDoubleSlash(chaine: string): string {\r\n return HelperService.replaceAll(chaine, /(https?:\\/\\/)|(\\/){2,}/g, \"$1$2\");\r\n }\r\n\r\n /**\r\n * Vérifie s'il existe une concordance entre les `paramètres de l'url courante` et les `paramètres de la source de données`\r\n * @param urlSourceDonnées : exemple : la source de données d'une page de type formulaire, http://api.sonate-dev.fr:85/tiers/individus/{id}\r\n * @param urlCouranteStatique : l'url du navigateur, http://localhost:1200/page/lab-formulaire?id=016247a2-2c1c-4e08-bd78-9b05659ec5ee\r\n */\r\n static siConcordanceParamètresURLetSourceDonnées(urlSourceDonnées: string, urlCouranteStatique?: string): boolean {\r\n if (!urlSourceDonnées) return null;\r\n\r\n const urlCourante = urlCouranteStatique ? urlCouranteStatique : window.location.search;\r\n const paramètresAccolades: string[] = this.retourneParamètresAccolades(urlSourceDonnées);\r\n\r\n if (!paramètresAccolades.length) {\r\n return false;\r\n }\r\n\r\n for (let index = 0; index < paramètresAccolades.length; index++) {\r\n const paramètreAvecAccolades = paramètresAccolades[index];\r\n const paramètreSansAccolade: string = paramètreAvecAccolades.substring(paramètreAvecAccolades.lastIndexOf(\"{\") + 1, paramètreAvecAccolades.lastIndexOf(\"}\"));\r\n const valeurParamètre: string | object = this.donneParamètresUrl(paramètreSansAccolade, urlCourante);\r\n\r\n if (!valeurParamètre) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n static retourneNullSiNonDéfini(valeur: any) {\r\n if (Array.isArray(valeur)) {\r\n valeur = valeur.length === 0 ? null : valeur;\r\n } else if (typeof valeur === 'number') {\r\n return valeur;\r\n } else {\r\n valeur = typeof valeur === \"string\" ? valeur.trim() : valeur;\r\n }\r\n return !valeur ? null : valeur;\r\n }\r\n\r\n static replaceAll(text, pattern, newText): string {\r\n return text.replace(new RegExp(pattern, 'g'), newText);\r\n }\r\n\r\n static valeurTexteBooléen(valeur: boolean): string {\r\n if (typeof (valeur) === \"boolean\") {\r\n return valeur ? \"Oui\" : \"Non\";\r\n }\r\n\r\n return null;\r\n }\r\n\r\n static estNumerique(n: any): boolean {\r\n return !isNaN(parseFloat(n)) && isFinite(n);\r\n }\r\n\r\n // 01 02 03 04 05 -> 0102030405\r\n static adapteurEcritureTelephone(valeurAvecEspace: string): string {\r\n let valeurSansEspace: string;\r\n\r\n if (!this.retourneNullSiNonDéfini(valeurAvecEspace)) {\r\n return null;\r\n }\r\n\r\n const tmp: string[] = valeurAvecEspace.split(' ');\r\n\r\n valeurSansEspace = tmp[0] + tmp[1] + tmp[2] + tmp[3] + tmp[4];\r\n return valeurSansEspace;\r\n }\r\n\r\n static retourneValeurObjet(objet: any, propriété: string) {\r\n if (typeof objet !== 'undefined' && objet.hasOwnProperty(propriété)) {\r\n return objet[propriété];\r\n }\r\n return null;\r\n }\r\n\r\n static dupliquerTableau(tableau: any[]): any[] {\r\n return [...tableau];\r\n }\r\n\r\n static ajouterValeurTableau(tableau: any[], valeur: any): any[] {\r\n return [...tableau, valeur];\r\n }\r\n\r\n static ajouterValeurUniqueTableau(tableau: any[], valeur: any): any[] {\r\n if (tableau.indexOf(valeur) === -1) {\r\n return [...tableau, valeur];\r\n }\r\n\r\n return tableau;\r\n }\r\n\r\n static arrondirZeroCinqPrès(nombre: number): number {\r\n return Math.round(nombre * 2) * 0.5;\r\n }\r\n\r\n /**\r\n * Un GUID envoyé depuis le back au front est de la forme : (inheritor) {_value: \"0163d59a-bcd8-44fe-852f-100af77dfb9b\"}\r\n * @param objetInheritor objet GUID envoyé depuis le backoffice\r\n */\r\n static désérialiserInheritorGuid(objetInheritor: any): string {\r\n return objetInheritor._value ? objetInheritor._value : null;\r\n }\r\n\r\n static sérialiserInheritorGuid(valeur: any): object {\r\n return null\r\n // return valeur._value ? valeur : new Guid(valeur);\r\n }\r\n\r\n static estdetypeInheritorGuid(valeur: any): object {\r\n return valeur.hasOwnProperty(\"_value\");\r\n }\r\n\r\n static estdetypeGuid(valeur: string): boolean {\r\n if (!valeur) return false;\r\n return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(valeur);\r\n }\r\n\r\n /** fin bloc GUID */\r\n\r\n static valeurDéfautBooléen(valeur: any): boolean {\r\n return (typeof valeur !== \"undefined\" && !valeur) ? false : true;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { AbstractControl, UntypedFormControl, UntypedFormGroup, ValidationErrors, ValidatorFn } from '@angular/forms';\r\n\r\nimport { HelperService } from './helper/helper.service';\r\n\r\nexport interface ValidtionError {\r\n key: string;\r\n value?: any;\r\n message?: string;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ValidatorsService {\r\n\r\n public getValidationErrorMessage(error: ValidtionError): any {\r\n\r\n const configClésErreurs: any = {\r\n 'required': (!error.message ? 'Veuillez saisir ce champ' : error.message),\r\n 'invalidEmailAddress': 'L\\'e-mail n\\'est pas valide.',\r\n 'invalidCodePostal': 'Le code postal n\\'est pas valide.',\r\n 'invalidDate': \"Veuillez saisir une date valide.\",\r\n 'invalidHeure': \"L'heure n'est pas au bon format.\",\r\n 'invalideDateHeure': \"La date/heure n'est pas valide.\",\r\n 'regexInvalide': (!error.value.formatRegexEnClair ? 'Le format attendu est incorrect.' : `Fomat attendu : ${error.value.formatRegexEnClair}.`),\r\n 'invalidTypeMime': \"Le type du document n'est pas accepté.\",\r\n 'invalidTailleTotaleUpload': `La taille totale des pièces jointes est atteinte.`,\r\n 'invalidTailleUpload': `La taille limite de la pièce jointe est atteinte.`,\r\n 'datePasseeInvalide': \"La date doit être dans le passé.\",\r\n 'dateFutureInvalide': \"La date doit être dans le future.\",\r\n 'datePasseeOuPresenteInvalide': \"La date doit être passée ou présente.\",\r\n 'dateFutureOuPresenteInvalide': \"La date doit être présente ou future.\",\r\n 'invalidIMEI': \"Le numéro IMEI est invalide.\",\r\n 'invalidDateAnterieure': \"La date doit être antérieure.\",\r\n 'dateAvantUneAutre': \"La date B doit être antérieure à la date A.\",\r\n 'invalidNumeroTelephone': 'Le numéro de téléphone n\\'est pas valide.',\r\n 'adresseMailDejaUtilisee': 'L\\'adresse e-mail est déjà utilisée.',\r\n 'identiqueValidator': 'Le champ n\\'est pas identique.',\r\n 'pseudoDejaUtilisee': 'Le pseudo est déjà utilisé.',\r\n 'utilisateurMajeurInvalide': 'Vous devez être majeur.',\r\n 'entierInvalide': 'Saisissez un entier.',\r\n 'auMoinsUnChampRequis': 'Veuillez saisir au moins un critère de recherche.'\r\n };\r\n\r\n return configClésErreurs[error.key];\r\n }\r\n\r\n public static require(control: UntypedFormControl): ValidationErrors {\r\n const value = HelperService.retourneNullSiNonDéfini(control.value)\r\n\r\n if (control.hasValidator(ValidatorsService.dateValidator)) {\r\n return value === null ? { invalidDate: true } : null;\r\n } else {\r\n return value === null ? { \"required\": true } : null;\r\n }\r\n }\r\n\r\n public static emailValidator(control: UntypedFormControl): ValidationErrors {\r\n if (!control.value) return null;\r\n\r\n // RFC 2822 compliant regex\r\n if (control.value.match(/[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?/)) {\r\n return null;\r\n } else {\r\n return { 'invalidEmailAddress': true };\r\n }\r\n }\r\n\r\n public static dateValidator(control: UntypedFormControl): ValidationErrors {\r\n return null\r\n }\r\n\r\n public static telephoneValidator(control: UntypedFormControl): any {\r\n if (!control.value) return null;\r\n\r\n if (control.value.match(/^0[1-9](\\s[0-9][0-9]){4}$/)) {\r\n return null;\r\n } else {\r\n return { 'invalidNumeroTelephone': true };\r\n }\r\n }\r\n\r\n public static codepostalValidator(control: UntypedFormControl): any {\r\n if (!control.value) return null;\r\n\r\n if (control.value.match(/^(([0-8][0-9])|(9[0-5]))[0-9]{3}$/)) {\r\n return null;\r\n } else {\r\n return { 'invalidCodePostal': true };\r\n }\r\n }\r\n\r\n /** VALIDATEURS DATES */\r\n\r\n /**\r\n * La date à valider est au format UTC : 1982-11-06T00:00:00Z\r\n */\r\n // public static dateValidateurUTC(control: FormControl): any {\r\n // if (!control.value) return null;\r\n\r\n // const str = control.value;\r\n\r\n // const dateValide: boolean = DateFunctions.validerDateUTC(str);\r\n\r\n // return dateValide ? null : { 'invalidDate': true };\r\n // }\r\n\r\n // l'heure est au format 11h12\r\n // public static heureValidateur(control: FormControl): any {\r\n // if (!control.value) return null;\r\n\r\n // const str = control.value;\r\n\r\n // if (DateFunctions.validerUneHeure(str)) {\r\n // return null;\r\n // } else {\r\n // return { 'invalidHeure': true };\r\n // }\r\n // }\r\n\r\n // la date heure est au format 01/01/2018 à 12h14\r\n // public static dateHeureValidateur(control: FormControl): any {\r\n // if (!control.value) return null;\r\n\r\n // const str: string = control.value;\r\n\r\n // const valeurSplit: string[] = str.split(configdefault.date.dateTimeSeparator);\r\n\r\n // const dateValide: boolean = DateFunctions.validerDateJJMMAAAA(valeurSplit[0]);\r\n // const heureValide: boolean = DateFunctions.validerUneHeure(valeurSplit[1]);\r\n\r\n // if (!dateValide) {\r\n // return { 'invalidDate': true };\r\n // } else if (!heureValide) {\r\n // return { 'invalidHeure': true };\r\n // } else {\r\n // return null;\r\n // }\r\n // }\r\n\r\n /**\r\n * La date à valider est au format UTC : 1982-11-06T15:15:15Z\r\n * invalideDateHeure\r\n */\r\n // public static dateHeureValidateurUTC(control: FormControl): any {\r\n // if (!control.value) return null;\r\n\r\n // const str = control.value;\r\n\r\n // const dateValide: boolean = DateFunctions.validerDateUTC(str);\r\n\r\n // return dateValide ? null : { 'invalideDateHeure': true };\r\n\r\n // }\r\n\r\n // public static datePasséeValidateur(control: FormControl): any {\r\n // if (!control.value) return null;\r\n\r\n // const dates: Date[] = DateFunctions.validateurDatesAides(control.value);\r\n\r\n // if (dates[0] >= dates[1]) {\r\n // return {\r\n // 'datePasseeInvalide': true\r\n // };\r\n // }\r\n\r\n // return null;\r\n // }\r\n\r\n // public static dateFutureValidateur(control: FormControl): any {\r\n // if (!control.value) return null;\r\n\r\n // const dates: Date[] = DateFunctions.validateurDatesAides(control.value);\r\n\r\n // if (dates[0] <= dates[1]) {\r\n // return {\r\n // 'dateFutureInvalide': true\r\n // };\r\n // }\r\n\r\n // return null;\r\n // }\r\n\r\n // public static datePasséeOuPrésenteValidateur(control: FormControl): any {\r\n // if (!control.value) return null;\r\n\r\n // const dates: Date[] = DateFunctions.validateurDatesAides(control.value);\r\n\r\n // if (dates[0] > dates[1]) {\r\n // return {\r\n // 'datePasseeOuPresenteInvalide': true\r\n // };\r\n // }\r\n\r\n // return null;\r\n // }\r\n\r\n // public static dateFutureOuPrésenteValidateur(control: FormControl): any {\r\n // if (!control.value) return null;\r\n\r\n // const dates: Date[] = DateFunctions.validateurDatesAides(control.value);\r\n\r\n // if (dates[0] < dates[1]) {\r\n // return {\r\n // 'dateFutureOuPresenteInvalide': true\r\n // };\r\n // }\r\n\r\n // return null;\r\n // }\r\n\r\n /** / VALIDATEURS DATES */\r\n\r\n // https://medium.com/front-end-hacking/reactive-forms-and-form-validation-with-angular-fdcbcf98e1e8\r\n public static regexValidator(regle: string, formatRegexEnClair: string): ValidatorFn {\r\n return (control: AbstractControl): { [key: string]: any } => {\r\n if (!control.value) return null;\r\n\r\n const regexp: RegExp = new RegExp(regle);\r\n\r\n return !regexp.test(control.value) ? { 'regexInvalide': { formatRegexEnClair } } : null;\r\n };\r\n }\r\n\r\n public static numeroSinistreValidator(control: UntypedFormControl): any {\r\n if (!control.value) return null;\r\n\r\n if (control.value.match(/^([A-z0-9]{2})?(L|l)[A-z0-9](T|t)[A-z0-9]{5}$/)) {\r\n return null;\r\n } else {\r\n return { 'invalidNumeroSinistre': true };\r\n }\r\n }\r\n\r\n public static caseACocherRequireValidator(control: UntypedFormControl): any {\r\n if (control.value === true) {\r\n return null;\r\n } else {\r\n return { 'required': true };\r\n }\r\n }\r\n\r\n public static dateAvantUneAutre(champDateAvant: string, champDateAprès: string): any {\r\n return (group: UntypedFormGroup): { [key: string]: any } => {\r\n\r\n if (!group.get(champDateAvant) || !group.get(champDateAprès)) return null;\r\n\r\n const dateDébut: any = group.get(champDateAvant).value;\r\n const dateFin: any = group.get(champDateAprès).value;\r\n\r\n if (dateDébut > dateFin) {\r\n return {\r\n 'erreurDateFinAvantDébut': true\r\n };\r\n }\r\n\r\n return null;\r\n };\r\n }\r\n\r\n // https://gist.github.com/DiegoSalazar/4075533\r\n public static luhnValidator(control: UntypedFormControl): any {\r\n let valeur: string = control.value;\r\n\r\n // accept only digits, dashes or spaces\r\n if (/[^0-9-\\s]+/.test(valeur)) return { 'invalidIMEI': true };\r\n\r\n // The Luhn Algorithm. It's so pretty.\r\n let nCheck = 0;\r\n let nDigit: number = 0;\r\n let bEven: boolean = false;\r\n\r\n valeur = valeur.replace(/\\D/g, \"\");\r\n\r\n for (let n = valeur.length - 1; n >= 0; n--) {\r\n const cDigit = valeur.charAt(n);\r\n nDigit = parseInt(cDigit, 10);\r\n\r\n if (bEven) {\r\n if ((nDigit *= 2) > 9) nDigit -= 9;\r\n }\r\n\r\n nCheck += nDigit;\r\n bEven = !bEven;\r\n }\r\n\r\n if (nCheck % 10 === 0) {\r\n return null;\r\n } else {\r\n return { 'invalidIMEI': true };\r\n }\r\n }\r\n\r\n public static identiqueValidator(controle: string, controleConfirme: string): any {\r\n return (group: UntypedFormGroup): { [key: string]: any } => {\r\n const password = group.controls[controle];\r\n const confirmPassword = group.controls[controleConfirme];\r\n\r\n if (password.value !== confirmPassword.value) {\r\n return {\r\n 'identiqueValidator': true\r\n };\r\n }\r\n };\r\n }\r\n\r\n public static êtreMajeurValidateur(control: UntypedFormControl): any {\r\n if (parseInt(control.value) >= 18) {\r\n return null;\r\n } else {\r\n return { 'utilisateurMajeurInvalide': true };\r\n }\r\n }\r\n\r\n public static entierValidateur(control: UntypedFormControl): any {\r\n if (control.value.match(/^\\d+$/)) {\r\n return null;\r\n } else {\r\n return { 'entierInvalide': true };\r\n }\r\n }\r\n\r\n public static auMoinsUnChampDoitEtreRequisValidateur(): any {\r\n return (group: UntypedFormGroup): { [key: string]: any } => {\r\n let isAtLeastOne = false;\r\n\r\n if (group && group.controls) {\r\n for (const control in group.controls) {\r\n if (group.controls.hasOwnProperty(control) && group.controls[control].valid && HelperService.retourneNullSiNonDéfini(group.controls[control].value)) {\r\n isAtLeastOne = true;\r\n break;\r\n }\r\n }\r\n }\r\n return isAtLeastOne ? null : { 'auMoinsUnChampRequis': true };\r\n };\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { BehaviorSubject } from 'rxjs';\r\n\r\n@Injectable()\r\nexport class CurrentUrlRoutingService {\r\n public currentUrl = new BehaviorSubject<string>(undefined);\r\n}\r\n","export enum FragmentType {\r\n OrderBy = 1,\r\n Top = 2,\r\n Skip = 3,\r\n Count = 4,\r\n Expand = 5,\r\n Filter = 6,\r\n Select = 7\r\n }\r\n","import { FragmentType } from './enums';\r\n\r\nexport class QueryFragment {\r\n constructor(public type: FragmentType, public value: string) {}\r\n}\r\n","import { FragmentType } from './enums';\r\nimport { QueryFragment } from './queryFragment';\r\n\r\n// const orderBy = require('lodash.orderby');\r\n\r\ntype filterExpressionType = string | number | boolean | Date;\r\n\r\nexport default class FilterBuilder {\r\n private fragments: QueryFragment[] = [];\r\n filterExpression = (field: string, operator: string, value: filterExpressionType) => {\r\n this.fragments.push(\r\n new QueryFragment(FragmentType.Filter, `${field} ${operator} ${this.getValue(value)}`)\r\n );\r\n return this;\r\n };\r\n filterPhrase = (phrase: string) => {\r\n this.fragments.push(new QueryFragment(FragmentType.Filter, phrase));\r\n return this;\r\n };\r\n and = (predicate: (filter: FilterBuilder) => FilterBuilder) => {\r\n this.fragments.push(\r\n new QueryFragment(FragmentType.Filter,