diff --git a/angular.json b/angular.json index 835558b24a..05c605c2b5 100644 --- a/angular.json +++ b/angular.json @@ -31,6 +31,11 @@ "demo/src/config", "demo/src/contexts", "demo/src/locale", + { + "glob": "**/*", + "input": "./dist/common/assets/", + "output": "./assets/igo2/common/" + }, { "glob": "**/*", "input": "./dist/core/assets/", diff --git a/demo/src/app/common/entity-table/entity-table.component.ts b/demo/src/app/common/entity-table/entity-table.component.ts index b8d6d91b71..eb5448b047 100644 --- a/demo/src/app/common/entity-table/entity-table.component.ts +++ b/demo/src/app/common/entity-table/entity-table.component.ts @@ -84,6 +84,9 @@ export class AppEntityTableComponent implements OnInit, OnDestroy { const ids = [2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; const entities = ids.map(id => { + if (id === 3) { + return { id , name: `Name ${id}`, description: `Description ${id}`, url: 'https://igouverte.org', image: 'https://www.igouverte.org/assets/img/NONEXISTINGIMAGE.png'}; + } return { id , name: `Name ${id}`, description: `Description ${id}`, url: 'https://igouverte.org', image: 'https://www.igouverte.org/assets/img/Igo_logoavec.png'}; }); this.store.load(entities); diff --git a/demo/src/app/geo/legend/legend.component.ts b/demo/src/app/geo/legend/legend.component.ts index ce8cfa3cb1..8be54c241c 100644 --- a/demo/src/app/geo/legend/legend.component.ts +++ b/demo/src/app/geo/legend/legend.component.ts @@ -150,12 +150,12 @@ export class AppLegendComponent { this.layerService .createAsyncLayer({ + title: 'Commission scolaire anglophone', sourceOptions: { type: 'wms', - url: 'https://geoegl.msp.gouv.qc.ca/apis/ws/igo_gouvouvert.fcgi', - optionsFromCapabilities: true, + url: 'https://geoegl.msp.gouv.qc.ca/apis/wss/all.fcgi', params: { - LAYERS: 'MELS_CS_ANGLO_S', + LAYERS: 'WMS_MEQ_CS_ANGLO', VERSION: '1.3.0' } } @@ -193,31 +193,6 @@ export class AppLegendComponent { }) .subscribe(l => this.map.addLayer(l)); - this.layerService - .createAsyncLayer({ - title: '2 styles nurc:Arc_Sample_Parent', - visible: true, - legendOptions: { - // collapsed: false, - display: true, - // url: 'https://v.seloger.com/s/width/1144/visuels/0/m/l/4/0ml42xbt1n3itaboek3qec5dtskdgw6nlscu7j69k.jpg', - stylesAvailable: [ - { name: 'rain', title: 'Pluie' }, - { name: 'raster', title: 'Défaut' } - ] // - }, - sourceOptions: { - type: 'wms', - url: 'https://demo.geo-solutions.it/geoserver/ows', - optionsFromCapabilities: true, - params: { - LAYERS: 'nurc:Arc_Sample', // , test:Linea_costa - VERSION: '1.3.0' - } - } - }) - .subscribe(l => this.map.addLayer(l)); - this.layerService .createAsyncLayer({ title: 'Avertissements routier', diff --git a/demo/src/environments/environment.prod.ts b/demo/src/environments/environment.prod.ts index 341381d744..8787b55d79 100644 --- a/demo/src/environments/environment.prod.ts +++ b/demo/src/environments/environment.prod.ts @@ -66,6 +66,7 @@ export const environment: Environment = { ] }, searchSources: { + storedqueriesreverse: { enabled: false}, nominatim: { enabled: false }, diff --git a/demo/src/environments/environment.ts b/demo/src/environments/environment.ts index c584f55dc9..09dfc8fb39 100644 --- a/demo/src/environments/environment.ts +++ b/demo/src/environments/environment.ts @@ -279,6 +279,7 @@ export const environment: Environment = { ] }, searchSources: { + storedqueriesreverse: { enabled: false}, storedqueries: { available: true, title: 'Feuillets SNRC', diff --git a/gulpfile.js b/gulpfile.js index 7a0ff25271..311b961eea 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -53,7 +53,7 @@ gulp.task('core:copyAssets', done => { gulp.task('common:copyAssets', done => { gulp - .src('./packages/common/src/assets', { + .src('./packages/common/src/assets/**/*', { base: './packages/common/src/assets/', allowEmpty: true }) @@ -64,7 +64,7 @@ gulp.task('common:copyAssets', done => { gulp.task('auth:copyAssets', done => { gulp - .src('./packages/auth/src/assets', { + .src('./packages/auth/src/assets/**/*', { base: './packages/auth/src/assets/', allowEmpty: true }) diff --git a/packages/common/src/assets/images/na.png b/packages/common/src/assets/images/na.png new file mode 100644 index 0000000000..a72ad5872c Binary files /dev/null and b/packages/common/src/assets/images/na.png differ diff --git a/packages/common/src/lib/entity/entity-table/entity-table.component.html b/packages/common/src/lib/entity/entity-table/entity-table.component.html index b419f19457..cf6a70ffce 100644 --- a/packages/common/src/lib/entity/entity-table/entity-table.component.html +++ b/packages/common/src/lib/entity/entity-table/entity-table.component.html @@ -40,7 +40,7 @@ - + {{ 'igo.common.entity-table.targetHtmlUrl' | translate }} @@ -57,7 +57,7 @@ - + {{ 'igo.geo.targetHtmlUrl' | translate }} @@ -111,7 +111,7 @@ - + {{ 'igo.geo.targetHtmlUrl' | translate }} diff --git a/packages/common/src/lib/image/image-error.directive.ts b/packages/common/src/lib/image/image-error.directive.ts new file mode 100644 index 0000000000..02f3bc26dd --- /dev/null +++ b/packages/common/src/lib/image/image-error.directive.ts @@ -0,0 +1,28 @@ +import { + Directive, + HostListener, + Input, + ElementRef +} from '@angular/core'; + +@Directive({ + selector: '[igoImageError]' +}) +export class ImageErrorDirective { + + @Input() errorImageUrl: string = '/assets/igo2/common/images/na.png'; + @Input() hideError: boolean = false; + + constructor(private el: ElementRef) {} + + @HostListener("error", ['$event']) + public onError(event: any): void { + if (this.hideError) { + this.el.nativeElement.style.display = "none"; + } else { + event.target.src = this.errorImageUrl; + } + + } + +} diff --git a/packages/common/src/lib/image/image.module.ts b/packages/common/src/lib/image/image.module.ts index c6136f8121..0df301aa0f 100644 --- a/packages/common/src/lib/image/image.module.ts +++ b/packages/common/src/lib/image/image.module.ts @@ -1,10 +1,11 @@ import { NgModule, ModuleWithProviders } from '@angular/core'; +import { ImageErrorDirective } from './image-error.directive'; import { SecureImagePipe } from './secure-image.pipe'; @NgModule({ imports: [], - declarations: [SecureImagePipe], - exports: [SecureImagePipe] + declarations: [SecureImagePipe, ImageErrorDirective], + exports: [SecureImagePipe, ImageErrorDirective] }) export class IgoImageModule { static forRoot(): ModuleWithProviders { diff --git a/packages/common/src/lib/image/index.ts b/packages/common/src/lib/image/index.ts index eeb8019a61..097cfc3bdf 100644 --- a/packages/common/src/lib/image/index.ts +++ b/packages/common/src/lib/image/index.ts @@ -1 +1,2 @@ +export * from './image-error.directive'; export * from './secure-image.pipe'; diff --git a/packages/common/src/lib/image/secure-image.pipe.ts b/packages/common/src/lib/image/secure-image.pipe.ts index fa9699048b..6c7f0fad54 100644 --- a/packages/common/src/lib/image/secure-image.pipe.ts +++ b/packages/common/src/lib/image/secure-image.pipe.ts @@ -3,7 +3,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Cacheable } from 'ts-cacheable'; import { Observable } from 'rxjs'; -import { switchMap } from 'rxjs/operators'; +import { catchError, switchMap } from 'rxjs/operators'; import { ConfigService } from '@igo2/core'; @Pipe({ @@ -20,7 +20,8 @@ export class SecureImagePipe implements PipeTransform { transform(url: string): Observable { const headers = new HttpHeaders({ 'Content-Type': 'text/plain', - activityInterceptor: 'false' + activityInterceptor: 'false', + interceptError: 'false' }); const regexDepot = new RegExp(this.configService?.getConfig('depot.url') + '.*?(?="|$)'); @@ -34,6 +35,11 @@ export class SecureImagePipe implements PipeTransform { responseType: 'blob' }) .pipe( + catchError((err) => { + err.error.caught = true; + err.error.toDisplay = false; + throw err; + }), switchMap((blob) => { return new Observable((observer) => { const reader = new FileReader(); diff --git a/packages/core/src/lib/message/shared/message.service.ts b/packages/core/src/lib/message/shared/message.service.ts index 2e858a4339..ceb350a415 100644 --- a/packages/core/src/lib/message/shared/message.service.ts +++ b/packages/core/src/lib/message/shared/message.service.ts @@ -23,7 +23,7 @@ interface ActiveMessageTranslation { export class MessageService { public messages$ = new BehaviorSubject([]); private options: MessageOptions; - private activeMessageTranslations: ActiveMessageTranslation[]; + private activeMessageTranslations: ActiveMessageTranslation[] = []; constructor( @Inject(Injector) private injector: Injector, diff --git a/packages/core/src/lib/request/error.interceptor.ts b/packages/core/src/lib/request/error.interceptor.ts index cceddde761..2ba8f4324d 100644 --- a/packages/core/src/lib/request/error.interceptor.ts +++ b/packages/core/src/lib/request/error.interceptor.ts @@ -21,9 +21,16 @@ export class ErrorInterceptor implements HttpInterceptor { ) {} intercept( - req: HttpRequest, + originalReq: HttpRequest, next: HttpHandler ): Observable> { + const interceptError = originalReq.headers.get('interceptError'); + const req = originalReq.clone({ + headers: originalReq.headers.delete('interceptError') + }); + if (interceptError === 'false') { + return next.handle(req); + } const errorContainer = { httpError: undefined }; return next.handle(req).pipe( catchError(error => this.handleError(error, errorContainer)), diff --git a/packages/geo/src/lib/feature/feature-details/feature-details.component.html b/packages/geo/src/lib/feature/feature-details/feature-details.component.html index 1597b2819b..4357d104fd 100644 --- a/packages/geo/src/lib/feature/feature-details/feature-details.component.html +++ b/packages/geo/src/lib/feature/feature-details/feature-details.component.html @@ -33,7 +33,7 @@ - + diff --git a/packages/geo/src/lib/layer/layer-legend/layer-legend.component.html b/packages/geo/src/lib/layer/layer-legend/layer-legend.component.html index d87c097ed0..7aac4dccc6 100644 --- a/packages/geo/src/lib/layer/layer-legend/layer-legend.component.html +++ b/packages/geo/src/lib/layer/layer-legend/layer-legend.component.html @@ -27,8 +27,8 @@

{{computeItemTitle(item) | async}}

- {{'igo.geo.layer.legend.loadingLegendText' | translate}} {{'igo.geo.layer.legend.noLegendScale' | translate}}