import { inject } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivateFn, Data, Router, RouterStateSnapshot, } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { Observable, of as observableOf, } from 'rxjs'; import { map, switchMap, } from 'rxjs/operators'; import { PAGE_NOT_FOUND_PATH } from '../app-routing-paths'; import { BrowseDefinitionDataService } from '../core/browse/browse-definition-data.service'; import { RemoteData } from '../core/data/remote-data'; import { BrowseDefinition } from '../core/shared/browse-definition.model'; import { getFirstCompletedRemoteData } from '../core/shared/operators'; import { hasNoValue, hasValue, } from '../shared/empty.util'; export const browseByGuard: CanActivateFn = ( route: ActivatedRouteSnapshot, state: RouterStateSnapshot, browseDefinitionService: BrowseDefinitionDataService = inject(BrowseDefinitionDataService), router: Router = inject(Router), translate: TranslateService = inject(TranslateService), ): Observable<boolean> => { const title = route.data.title; const id = route.params.id || route.queryParams.id || route.data.id; let browseDefinition$: Observable<BrowseDefinition | undefined>; if (hasNoValue(route.data.browseDefinition) && hasValue(id)) { browseDefinition$ = browseDefinitionService.findById(id).pipe( getFirstCompletedRemoteData(), map((browseDefinitionRD: RemoteData<BrowseDefinition>) => browseDefinitionRD.payload), ); } else { browseDefinition$ = observableOf(route.data.browseDefinition); } const scope = route.queryParams.scope ?? route.parent?.params.id; const value = route.queryParams.value; const metadataTranslated = translate.instant(`browse.metadata.${id}`); return browseDefinition$.pipe( switchMap((browseDefinition: BrowseDefinition | undefined) => { if (hasValue(browseDefinition)) { route.data = createData(title, id, browseDefinition, metadataTranslated, value, route, scope); return observableOf(true); } else { void router.navigate([PAGE_NOT_FOUND_PATH]); return observableOf(false); } }), ); }; function createData(title: string, id: string, browseDefinition: BrowseDefinition, field: string, value: string, route: ActivatedRouteSnapshot, scope: string): Data { return Object.assign({}, route.data, { title: title, id: id, browseDefinition: browseDefinition, field: field, value: hasValue(value) ? `"${value}"` : '', scope: scope, }); }