diff --git a/client/package-lock.json b/client/package-lock.json index e38140ad1..c71ab4669 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -4271,7 +4271,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4292,12 +4293,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4312,17 +4315,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -4439,7 +4445,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -4451,6 +4458,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4465,6 +4473,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4472,12 +4481,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -4496,6 +4507,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -4576,7 +4588,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -4588,6 +4601,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -4673,7 +4687,8 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -4709,6 +4724,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4728,6 +4744,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4771,12 +4788,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts index ca0c46f21..f8e311e49 100644 --- a/client/src/app/app.component.ts +++ b/client/src/app/app.component.ts @@ -1,16 +1,18 @@ import { Component, OnInit } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; -import { OpenslidesService } from 'app/core/services/openslides.service'; import { AutoupdateService } from 'app/core/services/autoupdate.service'; +// import { AuthService } from 'app/core/services/auth.service'; +import { OperatorService } from 'app/core/services/operator.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) -export class AppComponent implements OnInit { +// export class AppComponent implements OnInit { +export class AppComponent { constructor( - private openSlides: OpenslidesService, + private operator: OperatorService, private autoupdate: AutoupdateService, private translate: TranslateService ) { @@ -23,8 +25,4 @@ export class AppComponent implements OnInit { // try to use the browser language if it is available. If not, uses english. translate.use(translate.getLangs().includes(browserLang) ? browserLang : 'en'); } - - ngOnInit() { - this.openSlides.bootup(); - } } diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts index c09101b98..8020888dd 100644 --- a/client/src/app/app.module.ts +++ b/client/src/app/app.module.ts @@ -41,6 +41,7 @@ import { AlertComponent } from './core/directives/alert/alert.component'; //translation module. TODO: Potetially a SharedModule and own files import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { PruningTranslationLoader } from './core/pruning-loader'; +import { OsPermsDirective } from './core/directives/os-perms.directive'; export function HttpLoaderFactory(http: HttpClient) { return new PruningTranslationLoader(http); @@ -60,7 +61,8 @@ library.add(fas); SiteComponent, StartComponent, ProjectorContainerComponent, - AlertComponent + AlertComponent, + OsPermsDirective ], imports: [ BrowserModule, diff --git a/client/src/app/base.component.ts b/client/src/app/base.component.ts index 1537dace2..93787b8f6 100644 --- a/client/src/app/base.component.ts +++ b/client/src/app/base.component.ts @@ -1,20 +1,16 @@ import { Injector } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { DataStoreService } from 'app/core/services/DS.service'; -// import { TranslateService } from '@ngx-translate/core'; // provides functions that might be used by a lot of components export abstract class BaseComponent { protected injector: Injector; protected dataStore: DataStoreService; - // would die in every scope change. disabled for now - // protected _translateService: TranslateService; private titleSuffix = ' - OpenSlides 3'; constructor(protected titleService?: Title) { // throws a warning even tho it is the new syntax. Ignored for now. this.injector = Injector.create([{ provide: DataStoreService, useClass: DataStoreService, deps: [] }]); - // this._injector = Injector.create([{ provide: TranslateService, useClass: TranslateService, deps: [] }]); } setTitle(prefix: string) { @@ -29,11 +25,4 @@ export abstract class BaseComponent { } return this.dataStore; } - - // get translate(): TranslateService { - // if (this._translateService == null) { - // this._translateService = this._injector.get(TranslateService); - // } - // return this._translateService; - // } } diff --git a/client/src/app/core/directives/os-perms.directive.spec.ts b/client/src/app/core/directives/os-perms.directive.spec.ts new file mode 100644 index 000000000..797b9f406 --- /dev/null +++ b/client/src/app/core/directives/os-perms.directive.spec.ts @@ -0,0 +1,8 @@ +import { OsPermsDirective } from './os-perms.directive'; + +describe('OsPermsDirective', () => { + it('should create an instance', () => { + const directive = new OsPermsDirective(); + expect(directive).toBeTruthy(); + }); +}); diff --git a/client/src/app/core/directives/os-perms.directive.ts b/client/src/app/core/directives/os-perms.directive.ts new file mode 100644 index 000000000..8e7235ead --- /dev/null +++ b/client/src/app/core/directives/os-perms.directive.ts @@ -0,0 +1,69 @@ +import { Directive, Input, ElementRef, TemplateRef, ViewContainerRef, OnInit } from '@angular/core'; +import { OperatorService } from 'app/core/services/operator.service'; +import { BaseComponent } from 'app/base.component'; +import { Group } from 'app/core/models/users/group'; + +@Directive({ + selector: '[appOsPerms]' +}) +export class OsPermsDirective extends BaseComponent { + private userPermissions: string[]; + private permissions; + + constructor( + private element: ElementRef, + private template: TemplateRef, + private viewContainer: ViewContainerRef, //TODO private operator. OperatorService + private operator: OperatorService + ) { + super(); + this.userPermissions = []; + + // observe groups of operator, so the directive can actively react to changes + this.operator.getObservable().subscribe(content => { + console.log('os-perms did monitor changes in observer: ', content); + if (content instanceof Group && this.permissions !== '') { + console.log('content was a Group'); + this.userPermissions = [...this.userPermissions, ...content.permissions]; + this.updateView(); + } + }); + } + + @Input() + set appOsPerms(value) { + this.permissions = value; + this.readUserPermissions(); + this.updateView(); + } + + private readUserPermissions(): void { + const opGroups = this.operator.getGroups(); + console.log('operator Groups: ', opGroups); + opGroups.forEach(group => { + this.userPermissions = [...this.userPermissions, ...group.permissions]; + }); + } + + // hides or shows a contrainer + private updateView(): void { + if (this.checkPermissions()) { + // will just render the page normally + this.viewContainer.createEmbeddedView(this.template); + } else { + // will remove the content of the container + this.viewContainer.clear(); + } + } + + // checks for the required permission + private checkPermissions(): boolean { + let isPermitted = false; + if (this.userPermissions && this.permissions) { + this.permissions.forEach(perm => { + isPermitted = this.userPermissions.find(userPerm => userPerm === perm) ? true : false; + }); + } + return isPermitted; + } +} diff --git a/client/src/app/core/services/DS.service.ts b/client/src/app/core/services/DS.service.ts index 62d71d615..1e5658252 100644 --- a/client/src/app/core/services/DS.service.ts +++ b/client/src/app/core/services/DS.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpResponse, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; -import { Observable, of } from 'rxjs'; -import { tap } from 'rxjs/operators'; +import { Observable, of, BehaviorSubject } from 'rxjs'; +import { tap, map } from 'rxjs/operators'; import { ImproperlyConfiguredError } from 'app/core/exceptions'; import { BaseModel, ModelId } from 'app/core/models/baseModel'; @@ -28,6 +28,8 @@ const httpOptions = { export class DataStoreService { // needs to be static cause becauseusing dependency injection, services are unique for a scope. private static store: Storrage = {}; + // observe datastore to enable dynamic changes in models and view + private static dataStoreSubject: BehaviorSubject = new BehaviorSubject(null); constructor(private http: HttpClient) {} @@ -58,7 +60,7 @@ export class DataStoreService { } // TODO: type for callback function - // example: this.DS.filder(User, myUser => myUser.first_name === "Max") + // example: this.DS.filter(User, myUser => myUser.first_name === "Max") filter(Type, callback): BaseModel[] { let filterCollection = []; const typeCollection = this.get(Type); @@ -86,7 +88,7 @@ export class DataStoreService { DataStoreService.store[collectionString] = {}; } DataStoreService.store[collectionString][model.id] = model; - // console.log('add model ', model, ' into Datastore'); + this.setObservable(model); }); } @@ -132,4 +134,12 @@ export class DataStoreService { }) ); } + + public getObservable(): Observable { + return DataStoreService.dataStoreSubject.asObservable(); + } + + private setObservable(value) { + DataStoreService.dataStoreSubject.next(value); + } } diff --git a/client/src/app/core/services/auth-guard.service.ts b/client/src/app/core/services/auth-guard.service.ts index f8aafb974..e82de858a 100644 --- a/client/src/app/core/services/auth-guard.service.ts +++ b/client/src/app/core/services/auth-guard.service.ts @@ -2,30 +2,23 @@ import { Injectable } from '@angular/core'; import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { AuthService } from './auth.service'; +import { OperatorService } from './operator.service'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate { - constructor(private authService: AuthService, private router: Router) {} + constructor(private authService: AuthService, private operator: OperatorService, private router: Router) {} - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any { const url: string = state.url; - return this.checkLogin(url); - } - checkLogin(url: string): boolean { - //check if the user is already logged in. - //TODO: This is faked - if (this.authService.isLoggedIn) { + if (this.operator.id) { return true; + } else { + this.authService.redirectUrl = url; + this.router.navigate(['/login']); + return false; } - - // Store the attempted URL for redirecting - this.authService.redirectUrl = url; - - // Navigate to the login page with extras - this.router.navigate(['/login']); - return false; } } diff --git a/client/src/app/core/services/auth.service.ts b/client/src/app/core/services/auth.service.ts index 7a5a1c3cc..ea9db6c54 100644 --- a/client/src/app/core/services/auth.service.ts +++ b/client/src/app/core/services/auth.service.ts @@ -3,7 +3,7 @@ import { HttpClient, HttpResponse, HttpErrorResponse, HttpHeaders } from '@angul import { Observable, of, throwError } from 'rxjs'; import { catchError, tap } from 'rxjs/operators'; -import { User } from 'app/core/models/users/user'; +import { OperatorService } from 'app/core/services/operator.service'; const httpOptions = { withCredentials: true, @@ -16,54 +16,27 @@ const httpOptions = { providedIn: 'root' }) export class AuthService { - isLoggedIn: boolean; - - // store the URL so we can redirect after logging in redirectUrl: string; - constructor(private http: HttpClient) { - //check for the cookie in local storrage - //TODO checks for username now since django does not seem to return a cookie - if (localStorage.getItem('username')) { - this.isLoggedIn = true; - } else { - this.isLoggedIn = false; - } - } - - // Initialize the service by querying the server - // Not sure if this makes sense, since a service is not supposed to init() - init(): Observable { - return this.http.get('/users/whoami/', httpOptions).pipe( - tap(val => { - console.log('auth-init-whami : ', val); - }), - catchError(this.handleError()) - ); - } + constructor(private http: HttpClient, private operator: OperatorService) {} //loggins a users. expects a user model - login(username: string, password: string): Observable { + login(username: string, password: string): Observable { const user: any = { username: username, password: password }; return this.http.post('/users/login/', user, httpOptions).pipe( - tap(val => { - localStorage.setItem('username', val.username); - this.isLoggedIn = true; - }), + tap(resp => this.operator.storeUser(resp.user)), catchError(this.handleError()) ); } //logout the user //TODO not yet used - logout(): Observable { - this.isLoggedIn = false; - localStorage.removeItem('username'); - - return this.http.post('/users/logout/', {}, httpOptions); + logout(): Observable { + this.operator.clear(); + return this.http.post('/users/logout/', {}, httpOptions); } //very generic error handling function. diff --git a/client/src/app/core/services/autoupdate.service.ts b/client/src/app/core/services/autoupdate.service.ts index 7d26d8bb2..e99dfb68b 100644 --- a/client/src/app/core/services/autoupdate.service.ts +++ b/client/src/app/core/services/autoupdate.service.ts @@ -34,13 +34,18 @@ export class AutoupdateService extends BaseComponent { constructor(private websocketService: WebsocketService) { super(); + } + + // initialte autpupdate Service + startAutoupdate(): void { + console.log('start autoupdate'); this.socket = this.websocketService.connect(); this.socket.subscribe(response => { this.storeResponse(response); }); } - //create models out of socket answer + // create models out of socket answer storeResponse(socketResponse): void { socketResponse.forEach(model => { switch (model.collection) { diff --git a/client/src/app/core/services/openslides.service.ts b/client/src/app/core/services/openslides.service.ts index e424d2e86..1a322de9a 100644 --- a/client/src/app/core/services/openslides.service.ts +++ b/client/src/app/core/services/openslides.service.ts @@ -3,22 +3,22 @@ import { Router } from '@angular/router'; import { AuthService } from './auth.service'; -//it seems that this service is useless @Injectable({ providedIn: 'root' }) export class OpenslidesService { constructor(private auth: AuthService, private router: Router) {} - bootup() { - // TODO Lock the interface.. - this.auth.init().subscribe(whoami => { - console.log(whoami); - if (!whoami.user && !whoami.guest_enabled) { - this.router.navigate(['/login']); - } else { - // It's ok! - } - }); - } + // now in authService + // bootup() { + // // TODO Lock the interface.. + // this.auth.init().subscribe(whoami => { + // console.log(whoami); + // if (!whoami.user && !whoami.guest_enabled) { + // this.router.navigate(['/login']); + // } else { + // // It's ok! + // } + // }); + // } } diff --git a/client/src/app/core/services/operator.service.spec.ts b/client/src/app/core/services/operator.service.spec.ts new file mode 100644 index 000000000..86df87dec --- /dev/null +++ b/client/src/app/core/services/operator.service.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { OperatorService } from './operator.service'; + +describe('OperatorService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [OperatorService] + }); + }); + + it('should be created', inject([OperatorService], (service: OperatorService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/client/src/app/core/services/operator.service.ts b/client/src/app/core/services/operator.service.ts new file mode 100644 index 000000000..f723ee582 --- /dev/null +++ b/client/src/app/core/services/operator.service.ts @@ -0,0 +1,198 @@ +import { Injectable } from '@angular/core'; +import { Observable, of, BehaviorSubject } from 'rxjs'; +import { HttpClient, HttpResponse, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; +import { tap, catchError, share } from 'rxjs/operators'; +import { BaseComponent } from 'app/base.component'; +import { Group } from 'app/core/models/users/group'; + +// TODO: Dry +const httpOptions = { + withCredentials: true, + headers: new HttpHeaders({ + 'Content-Type': 'application/json' + }) +}; + +@Injectable({ + providedIn: 'root' +}) +export class OperatorService extends BaseComponent { + // default variables + about_me: string; + comment: string; + default_password: string; + email: string; + first_name: string; + groups_id: number[]; + id: number; + is_active: boolean; + is_committee: boolean; + is_present: boolean; + last_email_send: string; + last_name: string; + number: string; + structure_level: string; + title: string; + username: string; + logged_in: boolean; + // subject + private operatorSubject: BehaviorSubject = new BehaviorSubject(null); + // real groups, once they arrived in datastore + private groups: Group[] = new Array(); + + constructor(private http: HttpClient) { + super(); + + // recreate old operator from localStorage. + if (localStorage.getItem('operator')) { + const oldOperator = JSON.parse(localStorage.getItem('operator')); + if (Object.keys(oldOperator).length > 0) { + this.storeUser(oldOperator); + } + } + + // observe the datastore now to avoid race conditions. Ensures to + // find the groups in time + this.observeDataStore(); + } + + // calls 'whoami' to find out the operator + public whoAmI(): Observable { + return this.http.get('/users/whoami/', httpOptions).pipe( + tap(whoami => { + if (whoami && whoami.user) { + this.storeUser(whoami.user); + } + }), + catchError(this.handleError()) + ); + } + + public storeUser(user: any): void { + // store in file + this.about_me = user.about_me; + this.comment = user.comment; + this.default_password = user.default_password; + this.email = user.email; + this.first_name = user.first_name; + this.groups_id = user.groups_id; + this.id = user.id; + this.is_active = user.is_active; + this.is_committee = user.is_committee; + this.is_present = user.is_present; + this.last_email_send = user.last_email_send; + this.last_name = user.last_name; + this.number = user.number; + this.structure_level = user.structure_level; + this.title = user.title; + this.username = user.username; + // also store in localstorrage + this.updateLocalStorrage(); + // update mode to inform observers + this.updateMode(); + } + + public clear() { + this.about_me = null; + this.comment = null; + this.default_password = null; + this.email = null; + this.first_name = null; + this.groups_id = null; + this.id = null; + this.is_active = null; + this.is_committee = null; + this.is_present = null; + this.last_email_send = null; + this.last_name = null; + this.number = null; + this.structure_level = null; + this.title = null; + this.username = null; + this.updateMode(); + localStorage.removeItem('operator'); + } + + private updateLocalStorrage(): void { + localStorage.setItem('operator', JSON.stringify(this.getUpdateObject())); + console.log('update local storrage: groups: ', this.groups_id); + } + + private updateMode(): void { + this.setObservable(this.getUpdateObject()); + } + + private getUpdateObject(): any { + return { + about_me: this.about_me, + comment: this.comment, + default_password: this.default_password, + email: this.email, + first_name: this.first_name, + groups_id: this.groups_id, + id: this.id, + is_active: this.is_active, + is_committee: this.is_committee, + is_present: this.is_present, + last_email_send: this.last_email_send, + last_name: this.last_name, + number: this.number, + structure_level: this.structure_level, + title: this.title, + username: this.username, + logged_in: this.logged_in + }; + } + + // observe dataStore to set groups once they are there + // TODO logic to remove groups / user from certain groups + private observeDataStore(): void { + console.log('Operator observes DataStore'); + this.DS.getObservable().subscribe(newModel => { + if (newModel instanceof Group) { + this.addGroup(newModel); + } + }); + } + + // read out the Groups from the DataStore by the operators 'groups_id' + // requires that the DataStore has been setup (websocket.service) + // requires that the whoAmI did return a valid operator + public readGroupsFromStore(): void { + this.DS.filter(Group, myGroup => { + if (this.groups_id.includes(myGroup.id)) { + this.addGroup(myGroup); + } + }); + } + + public getObservable() { + return this.operatorSubject.asObservable(); + } + + private setObservable(value) { + this.operatorSubject.next(value); + } + + public getGroups() { + return this.groups; + } + + // if the operator has the corresponding ID, set the group + private addGroup(newGroup: Group): void { + if (this.groups_id.includes(newGroup.id)) { + this.groups.push(newGroup); + // inform the observers about new groups (appOsPerms) + console.log('pushed a group into operator'); + this.setObservable(newGroup); + } + } + + // TODO Dry + private handleError() { + return (error: any): Observable => { + console.error(error); + return of(error); + }; + } +} diff --git a/client/src/app/site/agenda/agenda.component.html b/client/src/app/site/agenda/agenda.component.html index e061ae779..cc8d3a64b 100644 --- a/client/src/app/site/agenda/agenda.component.html +++ b/client/src/app/site/agenda/agenda.component.html @@ -16,4 +16,12 @@
Agenda Works -
\ No newline at end of file +
+
+ everyone should see this +
+
+
+ Only permitted users should see this +
+ diff --git a/client/src/app/site/login/login.component.ts b/client/src/app/site/login/login.component.ts index 209200edc..0b2406880 100644 --- a/client/src/app/site/login/login.component.ts +++ b/client/src/app/site/login/login.component.ts @@ -5,6 +5,7 @@ import { MatSnackBar } from '@angular/material'; import { BaseComponent } from 'app/base.component'; import { AuthService } from 'app/core/services/auth.service'; +import { OperatorService } from 'app/core/services/operator.service'; @Component({ selector: 'app-login', @@ -19,20 +20,22 @@ export class LoginComponent extends BaseComponent implements OnInit { constructor( titleService: Title, private authService: AuthService, + private operator: OperatorService, private router: Router, private snackBar: MatSnackBar ) { super(titleService); - this.setInfo(); } ngOnInit() { - //TODO translate - super.setTitle('Anmelden'); - } + super.setTitle('Log In'); - setInfo() { - this.info = 'Logged in? ' + (this.authService.isLoggedIn ? 'in' : 'out'); + // if there is stored login information, try to login directly. + this.operator.getObservable().subscribe(user => { + if (user && user.id) { + this.router.navigate(['/']); + } + }); } openSnackBar(message: string) { @@ -41,24 +44,17 @@ export class LoginComponent extends BaseComponent implements OnInit { }); } - //Todo: This serves as a prototype and need enhancement, - //like saving a "logged in state" and real checking the server - //if logIn was fine + // Todo: This serves as a prototype and need enhancement, + // if logIn was fine + // like saving a "logged in state" and real checking the server formLogin(): void { this.authService.login(this.username, this.password).subscribe(res => { if (res.status === 400) { //TODO translate - console.log('res: ', res); this.openSnackBar(res.error.detail); } else { - // this.toastService.success('Logged in! :)'); - this.setInfo(); - if (this.authService.isLoggedIn) { - // Get the redirect URL from our auth service - // If no redirect has been set, use the default + if (res.user_id) { const redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/'; - - // Redirect the user this.router.navigate([redirect]); } } diff --git a/client/src/app/site/site.component.html b/client/src/app/site/site.component.html index 39d0a480e..7aab83d7c 100644 --- a/client/src/app/site/site.component.html +++ b/client/src/app/site/site.component.html @@ -11,8 +11,8 @@ - - UserName + + {{username}} diff --git a/client/src/app/site/site.component.ts b/client/src/app/site/site.component.ts index 0fd7dc325..0ef0e9889 100644 --- a/client/src/app/site/site.component.ts +++ b/client/src/app/site/site.component.ts @@ -3,6 +3,8 @@ import { Router } from '@angular/router'; import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout'; import { AuthService } from 'app/core/services/auth.service'; +import { AutoupdateService } from 'app/core/services/autoupdate.service'; +import { OperatorService } from 'app/core/services/operator.service'; import { Subject } from 'rxjs'; import { tap } from 'rxjs/operators'; @@ -15,10 +17,13 @@ import { BaseComponent } from 'app/base.component'; styleUrls: ['./site.component.css'] }) export class SiteComponent extends BaseComponent implements OnInit { + username = this.operator.username; isMobile = false; constructor( private authService: AuthService, + private autoupdateService: AutoupdateService, + private operator: OperatorService, private router: Router, private breakpointObserver: BreakpointObserver, private translate: TranslateService @@ -39,7 +44,18 @@ export class SiteComponent extends BaseComponent implements OnInit { //get a translation via code: use the translation service this.translate.get('Motions').subscribe((res: string) => { - console.log(res); + console.log('translation of motions in the target language: ' + res); + }); + + //start autoupdate if the user is logged in: + this.operator.whoAmI().subscribe(resp => { + if (resp.user) { + this.autoupdateService.startAutoupdate(); + } else { + //if whoami is not sucsessfull, forward to login again + this.operator.clear(); + this.router.navigate(['/login']); + } }); } diff --git a/client/src/app/site/start/start.component.html b/client/src/app/site/start/start.component.html index 8dc17742c..2e7e167aa 100644 --- a/client/src/app/site/start/start.component.html +++ b/client/src/app/site/start/start.component.html @@ -5,7 +5,8 @@
{{'Welcome to OpenSlides' | translate}}
-

Hello user

+ +

{{'Hello user' | translate:username}}


diff --git a/client/src/app/site/start/start.component.ts b/client/src/app/site/start/start.component.ts index d0d7cc979..3df840fac 100644 --- a/client/src/app/site/start/start.component.ts +++ b/client/src/app/site/start/start.component.ts @@ -5,6 +5,7 @@ import { BaseComponent } from 'app/base.component'; import { TranslateService } from '@ngx-translate/core'; //showcase // for testing the DS and BaseModel +import { OperatorService } from 'app/core/services/operator.service'; import { User } from 'app/core/models/users/user'; import { Group } from 'app/core/models/users/group'; @@ -14,12 +15,15 @@ import { Group } from 'app/core/models/users/group'; styleUrls: ['./start.component.css'] }) export class StartComponent extends BaseComponent implements OnInit { - constructor(titleService: Title, private translate: TranslateService) { + //useage of translation with variables in code and view + username = { user: this.operator.username }; + + constructor(titleService: Title, private translate: TranslateService, private operator: OperatorService) { super(titleService); } ngOnInit() { - super.setTitle('Start page'); + super.setTitle('Start page'); //TODO translate } //quick testing of some data store functions diff --git a/package.json b/package.json deleted file mode 100644 index 06cd01ae9..000000000 --- a/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "openslides", - "private": true, - "scripts": { - "prepublish": "bower install && gulp", - "karma": "karma start tests/karma/karma.conf.js", - "karma:watch": "karma start tests/karma/karma.conf.js --single-run=false" - }, - "devDependencies": { - "angular-mocks": "~1.5.11", - "bower": "^1.8.0", - "gulp": "~4.0.0", - "gulp-angular-gettext": "^2.2.0", - "gulp-angular-templatecache": "^2.0.0", - "gulp-concat": "^2.6.1", - "gulp-cssnano": "^2.1.2", - "gulp-if": "^2.0.2", - "gulp-inject-string": "^1.1.0", - "gulp-jshint": "^2.0.4", - "gulp-rename": "^1.2.2", - "gulp-sass": "^3.1.0", - "gulp-sourcemaps": "^2.6.0", - "gulp-uglify": "^2.1.2", - "jasmine-core": "^2.6.1", - "jshint": "^2.9.4", - "karma": "^1.5.0", - "karma-chrome-launcher": "^2.0.0", - "karma-jasmine": "^1.1.0", - "karma-phantomjs-launcher": "^1.0.4", - "main-bower-files": "^2.13.1", - "sprintf-js": "^1.0.3", - "through2": "^2.0.3", - "yargs": "^7.1.0" - } -}