Added theme to login data

This commit is contained in:
FinnStutzenstein 2019-03-08 09:19:05 +01:00
parent 70191ce455
commit a1018e62e2
5 changed files with 97 additions and 36 deletions

View File

@ -61,7 +61,6 @@ export class AppComponent {
// change default JS functions // change default JS functions
this.overloadArrayToString(); this.overloadArrayToString();
appRef.isStable.subscribe(s => console.log('is stable', s));
appRef.isStable appRef.isStable
.pipe( .pipe(
filter(s => s), filter(s => s),

View File

@ -3,10 +3,22 @@ import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { ConfigService } from './config.service'; import { ConfigService } from './config.service';
import { StorageService } from '../core-services/storage.service';
/** /**
* This service holds the privacy policy and the legal notice, so they are available * The login data send by the server.
* even if the user is not logged in. */
export interface LoginData {
privacy_policy: string;
legal_notice: string;
theme: string;
}
const LOGIN_DATA_STORAGE_KEY = 'LoginData';
/**
* This service holds the privacy policy, the legal notice and the OpenSlides theme, so
* they are available even if the user is not logged in.
*/ */
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -15,7 +27,7 @@ export class LoginDataService {
/** /**
* Holds the privacy policy * Holds the privacy policy
*/ */
private _privacy_policy = new BehaviorSubject<string>(''); private readonly _privacy_policy = new BehaviorSubject<string>('');
/** /**
* Returns an observable for the privacy policy * Returns an observable for the privacy policy
@ -27,7 +39,7 @@ export class LoginDataService {
/** /**
* Holds the legal notice * Holds the legal notice
*/ */
private _legal_notice = new BehaviorSubject<string>(''); private readonly _legal_notice = new BehaviorSubject<string>('');
/** /**
* Returns an observable for the legal notice * Returns an observable for the legal notice
@ -36,33 +48,76 @@ export class LoginDataService {
return this._legal_notice.asObservable(); return this._legal_notice.asObservable();
} }
/**
* Holds the theme
*/
private readonly _theme = new BehaviorSubject<string>('');
/**
* Returns an observable for the theme
*/
public get theme(): Observable<string> {
return this._theme.asObservable();
}
/** /**
* Constructs this service. The config service is needed to update the privacy * Constructs this service. The config service is needed to update the privacy
* policy and legal notice, when their config values change. * policy and legal notice, when their config values change.
* @param configService * @param configService
*/ */
public constructor(private configService: ConfigService) { public constructor(private configService: ConfigService, private storageService: StorageService) {
this.configService.get<string>('general_event_privacy_policy').subscribe(value => { this.configService.get<string>('general_event_privacy_policy').subscribe(value => {
this.setPrivacyPolicy(value); this._privacy_policy.next(value);
this.storeLoginData();
}); });
this.configService.get<string>('general_event_legal_notice').subscribe(value => { this.configService.get<string>('general_event_legal_notice').subscribe(value => {
this.setLegalNotice(value); this._legal_notice.next(value);
this.storeLoginData();
}); });
configService.get<string>('openslides_theme').subscribe(value => {
this._theme.next(value);
this.storeLoginData();
});
this.loadLoginData();
} }
/** /**
* Setter for the privacy policy * Load the login data from the storage. If it there, set it.
* @param privacyPolicy The new privacy policy to set
*/ */
public setPrivacyPolicy(privacyPolicy: string): void { private async loadLoginData(): Promise<void> {
this._privacy_policy.next(privacyPolicy); const loginData = await this.storageService.get<LoginData | null>(LOGIN_DATA_STORAGE_KEY);
if (loginData) {
this.setLoginData(loginData);
}
} }
/** /**
* Setter for the legal notice * Setter for the login data
* @param legalNotice The new legal notice to set *
* @param loginData the login data
*/ */
public setLegalNotice(legalNotice: string): void { public setLoginData(loginData: LoginData): void {
this._legal_notice.next(legalNotice); this._privacy_policy.next(loginData.privacy_policy);
this._legal_notice.next(loginData.legal_notice);
this._theme.next(loginData.theme);
this.storeLoginData(loginData);
}
/**
* Saves the login data in the storage.
*
* @param loginData If given, this data is used. If it's null, the current values
* from the behaviour subject are taken.
*/
private storeLoginData(loginData?: LoginData): void {
if (!loginData) {
loginData = {
privacy_policy: this._privacy_policy.getValue(),
legal_notice: this._legal_notice.getValue(),
theme: this._theme.getValue()
};
}
this.storageService.set(LOGIN_DATA_STORAGE_KEY, loginData);
} }
} }

View File

@ -1,31 +1,33 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { ConfigService } from './config.service';
import { LoginDataService } from './login-data.service';
/** /**
* Service to set the theme for the OpenSlides. * Service to set the theme for OpenSlides.
* Reads related data from server,
* the server sends the value of the new theme --> the new theme has only to be added to the body.
*/ */
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class ThemeService { export class ThemeService {
/** /**
* Here it will subscribe to the observer from config-service to read data. * Here it will subscribe to the observer from login data service. The stheme is part of
* the login data, so get it from there and not from the config. This service will
* also cache the theme and provide the right theme on login.
* *
* @param configService must be injected to get the data from server. * @param loginDataService must be injected to get the theme.
*/ */
public constructor(configService: ConfigService) { public constructor(loginDataService: LoginDataService) {
configService.get<string>('openslides_theme').subscribe(newTheme => { loginDataService.theme.subscribe(newTheme => {
// Listen to the related event. if (!newTheme) {
const classList = document.getElementsByTagName('body')[0].classList; // Get the classlist of the body. return;
if (newTheme) {
const toRemove = Array.from(classList).filter((item: string) => item.includes('theme'));
if (toRemove.length) {
classList.remove(...toRemove); // Remove all old themes.
}
classList.add(newTheme); // Add the new theme.
} }
const classList = document.getElementsByTagName('body')[0].classList; // Get the classlist of the body.
const toRemove = Array.from(classList).filter((item: string) => item.includes('theme'));
if (toRemove.length) {
classList.remove(...toRemove); // Remove all old themes.
}
classList.add(newTheme); // Add the new theme.
}); });
} }
} }

View File

@ -10,11 +10,15 @@ import { AuthService } from 'app/core/core-services/auth.service';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService } from 'app/core/core-services/operator.service';
import { environment } from 'environments/environment'; import { environment } from 'environments/environment';
import { OpenSlidesService } from 'app/core/core-services/openslides.service'; import { OpenSlidesService } from 'app/core/core-services/openslides.service';
import { LoginDataService } from 'app/core/ui-services/login-data.service'; import { LoginDataService, LoginData } from 'app/core/ui-services/login-data.service';
import { ParentErrorStateMatcher } from 'app/shared/parent-error-state-matcher'; import { ParentErrorStateMatcher } from 'app/shared/parent-error-state-matcher';
import { HttpService } from 'app/core/core-services/http.service'; import { HttpService } from 'app/core/core-services/http.service';
import { User } from 'app/shared/models/users/user'; import { User } from 'app/shared/models/users/user';
interface LoginDataWithInfoText extends LoginData {
info_text?: string;
}
/** /**
* Login mask component. * Login mask component.
* *
@ -94,13 +98,12 @@ export class LoginMaskComponent extends BaseComponent implements OnInit, OnDestr
// Get the login data. Save information to the login data service. If there is an // Get the login data. Save information to the login data service. If there is an
// error, ignore it. // error, ignore it.
// TODO: This has to be caught by the offline service // TODO: This has to be caught by the offline service
this.httpService.get<any>(environment.urlPrefix + '/users/login/').then( this.httpService.get<LoginDataWithInfoText>(environment.urlPrefix + '/users/login/').then(
response => { response => {
if (response.info_text) { if (response.info_text) {
this.installationNotice = response.info_text; this.installationNotice = response.info_text;
} }
this.loginDataService.setPrivacyPolicy(response.privacy_policy); this.loginDataService.setLoginData(response);
this.loginDataService.setLegalNotice(response.legal_notice);
}, },
() => {} () => {}
); );

View File

@ -521,6 +521,8 @@ class UserLoginView(APIView):
# even, it is not logged in. # even, it is not logged in.
context["privacy_policy"] = config["general_event_privacy_policy"] context["privacy_policy"] = config["general_event_privacy_policy"]
context["legal_notice"] = config["general_event_legal_notice"] context["legal_notice"] = config["general_event_legal_notice"]
# Add the theme, so the loginpage is themed correctly
context["theme"] = config["openslides_theme"]
else: else:
# self.request.method == 'POST' # self.request.method == 'POST'
context["user_id"] = self.user.pk context["user_id"] = self.user.pk