/** * This file is part of Anis Client. * * @copyright Laboratoire d'Astrophysique de Marseille / CNRS * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ import { Component, OnDestroy, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { ActivatedRoute, Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { Observable, Subscription } from 'rxjs'; import { UserProfile } from 'src/app/auth/user-profile.model'; import { Instance, WebpageFamily, Webpage } from 'src/app/metamodel/models'; import * as authActions from 'src/app/auth/auth.actions'; import * as authSelector from 'src/app/auth/auth.selector'; import * as datasetActions from 'src/app/metamodel/actions/dataset.actions'; import * as datasetFamilyActions from 'src/app/metamodel/actions/dataset-family.actions'; import * as instanceSelector from 'src/app/metamodel/selectors/instance.selector'; import * as datasetGroupActions from 'src/app/metamodel/actions/dataset-group.actions'; import * as webpageFamilyActions from 'src/app/metamodel/actions/webpage-family.actions'; import * as webpageFamilySelector from 'src/app/metamodel/selectors/webpage-family.selector'; import * as webpageActions from 'src/app/metamodel/actions/webpage.actions'; import * as webpageSelector from 'src/app/metamodel/selectors/webpage.selector'; import { AppConfigService } from 'src/app/app-config.service'; import { InstanceStyleService } from './instance-style.service'; /** * @class * @classdesc Instance container * * @implements OnInit * @implements OnDestroy */ @Component({ selector: 'app-instance', templateUrl: 'instance.component.html' }) export class InstanceComponent implements OnInit, OnDestroy { public favIcon: HTMLLinkElement = document.querySelector('#favicon'); public body: HTMLBodyElement = document.querySelector('body'); public instance: Observable<Instance>; public isAuthenticated: Observable<boolean>; public userProfile: Observable<UserProfile>; public userRoles: Observable<string[]>; public webpageFamilyListIsLoading: Observable<boolean>; public webpageFamilyListIsLoaded: Observable<boolean>; public webpageFamilyList: Observable<WebpageFamily[]>; public webpageListIsLoading: Observable<boolean>; public webpageListIsLoaded: Observable<boolean>; public webpageList: Observable<Webpage[]>; public firstWebpage: Observable<Webpage>; public instanceSubscription: Subscription; public firstWebpageSubscription: Subscription; constructor( private store: Store<{ }>, private config: AppConfigService, private http: HttpClient, private route: ActivatedRoute, private router: Router, private style: InstanceStyleService ) { this.instance = store.select(instanceSelector.selectInstanceByRouteName); this.isAuthenticated = store.select(authSelector.selectIsAuthenticated); this.userProfile = store.select(authSelector.selectUserProfile); this.userRoles = store.select(authSelector.selectUserRoles); this.webpageFamilyListIsLoading = store.select(webpageFamilySelector.selectWebpageFamilyListIsLoading); this.webpageFamilyListIsLoaded = store.select(webpageFamilySelector.selectWebpageFamilyListIsLoaded); this.webpageFamilyList = store.select(webpageFamilySelector.selectAllWebpageFamilies); this.webpageListIsLoading = store.select(webpageSelector.selectWebpageListIsLoading); this.webpageListIsLoaded = store.select(webpageSelector.selectWebpageListIsLoaded); this.webpageList = store.select(webpageSelector.selectAllWebpages); this.firstWebpage = store.select(webpageSelector.selectFirstWebpage); } ngOnInit() { // Create a micro task that is processed after the current synchronous code // This micro task prevent the expression has changed after view init error Promise.resolve(null).then(() => this.store.dispatch(datasetFamilyActions.loadDatasetFamilyList())); Promise.resolve(null).then(() => this.store.dispatch(datasetActions.loadDatasetList())); Promise.resolve(null).then(() => this.store.dispatch(datasetGroupActions.loadDatasetGroupList())); Promise.resolve(null).then(() => this.store.dispatch(webpageFamilyActions.loadWebpageFamilyList())); Promise.resolve(null).then(() => this.store.dispatch(webpageActions.loadWebpageList())); this.instanceSubscription = this.instance.subscribe(instance => { if (instance) { if (instance.design_favicon !== '') { this.setFaviconHref(instance); } if(document.styleSheets.length > 0) { this.body.style.backgroundColor = instance.design_background_color; this.style.applyInstanceStyle(instance); } } }); this.firstWebpageSubscription = this.firstWebpage.subscribe(webpage => { const iname = this.route.snapshot.paramMap.get('iname'); if (webpage && this.router.url === `/instance/${iname}`) { this.router.navigate(['webpage', webpage.name], { relativeTo: this.route }); } }); } setFaviconHref(instance: Instance) { const src = `${this.config.apiUrl}/instance/${instance.name}/file-explorer${instance.design_favicon}`; if (instance.public) { this.favIcon.href = src; } else { this.http.get(src, { responseType: 'blob' }).subscribe(data => { const reader = new FileReader(); reader.readAsDataURL(data); reader.onloadend = () => { const base64data = reader.result; this.favIcon.href = base64data as string; } }); } } /** * Checks if authentication is enabled. * * @return boolean */ getAuthenticationEnabled(): boolean { return this.config.authenticationEnabled; } /** * Returns admin roles list * * @returns string[] */ getAdminRoles(): string[] { return this.config.adminRoles; } /** * Returns API URL. * * @return string */ getApiUrl(): string { return this.config.apiUrl; } /** * Dispatches action to log in. */ login(): void { this.store.dispatch(authActions.login({ redirectUri: window.location.toString() })); } /** * Dispatches action to log out. */ logout(): void { this.store.dispatch(authActions.logout()); } /** * Dispatches action to open profile editor. */ openEditProfile(): void { this.store.dispatch(authActions.openEditProfile()); } /** * Unsubscribes to instance when component is destroyed. */ ngOnDestroy() { if (this.instanceSubscription) this.instanceSubscription.unsubscribe(); if (this.firstWebpageSubscription) this.firstWebpageSubscription.unsubscribe(); this.store.dispatch(webpageFamilyActions.emptyWebpageFamilyList()); this.store.dispatch(webpageActions.emptyWebpageList()); } }