Merge pull request #3815 from tsiegleauq/MobileObserveService

ViewportService and new Prefix
This commit is contained in:
Finn Stutzenstein 2018-08-23 17:38:42 +02:00 committed by GitHub
commit cbf8a33b8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 90 additions and 41 deletions

View File

@ -1,13 +1,13 @@
{
"/users/login": {
"/apps/users/login": {
"target": "http://localhost:8000",
"secure": false
},
"/users/logout": {
"/apps/users/logout": {
"target": "http://localhost:8000",
"secure": false
},
"/users/whoami": {
"/apps/users/whoami": {
"target": "http://localhost:8000",
"secure": false
},

View File

@ -12,6 +12,7 @@ import { OperatorService } from './services/operator.service';
import { WebsocketService } from './services/websocket.service';
import { AddHeaderInterceptor } from './http-interceptor';
import { DataSendService } from './services/data-send.service';
import { ViewportService } from './services/viewport.service';
/** Global Core Module. Contains all global (singleton) services
*
@ -26,6 +27,7 @@ import { DataSendService } from './services/data-send.service';
DataStoreService,
DataSendService,
OperatorService,
ViewportService,
WebsocketService,
{
provide: HTTP_INTERCEPTORS,

View File

@ -5,6 +5,7 @@ import { catchError, tap } from 'rxjs/operators';
import { OperatorService } from 'app/core/services/operator.service';
import { OpenSlidesComponent } from '../../openslides.component';
import { environment } from 'environments/environment';
/**
* Authenticates an OpenSlides user with username and password
@ -44,7 +45,7 @@ export class AuthService extends OpenSlidesComponent {
username: username,
password: password
};
return this.http.post<any>('/users/login/', user).pipe(
return this.http.post<any>(environment.urlPrefix + '/users/login/', user).pipe(
tap(resp => this.operator.storeUser(resp.user)),
catchError(this.handleError())
);
@ -60,6 +61,6 @@ export class AuthService extends OpenSlidesComponent {
//TODO not yet used
logout(): Observable<any> {
this.operator.clear();
return this.http.post<any>('/users/logout/', {});
return this.http.post<any>(environment.urlPrefix + '/users/logout/', {});
}
}

View File

@ -5,6 +5,7 @@ import { tap, catchError, share } from 'rxjs/operators';
import { OpenSlidesComponent } from 'app/openslides.component';
import { Group } from 'app/shared/models/users/group';
import { User } from '../../shared/models/users/user';
import { environment } from 'environments/environment';
/**
* The operator represents the user who is using OpenSlides.
@ -74,10 +75,10 @@ export class OperatorService extends OpenSlidesComponent {
}
/**
* calls `/users/whoami` to find out the real operator
* calls `/apps/users/whoami` to find out the real operator
*/
public whoAmI(): Observable<any> {
return this.http.get<any>('/users/whoami/').pipe(
return this.http.get<any>(environment.urlPrefix + '/users/whoami/').pipe(
tap(whoami => {
if (whoami && whoami.user) {
this.storeUser(whoami.user as User);

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { ViewportService } from './viewport.service';
describe('ViewportService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ViewportService]
});
});
it('should be created', inject([ViewportService], (service: ViewportService) => {
expect(service).toBeTruthy();
}));
});

View File

@ -0,0 +1,30 @@
import { Injectable } from '@angular/core';
import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout';
@Injectable({
providedIn: 'root'
})
export class ViewportService {
/**
* True if Viewport equals mobile or small resolution.
*/
private _isMobile = false;
constructor(private breakpointObserver: BreakpointObserver) {}
checkForChange() {
this.breakpointObserver
.observe([Breakpoints.Small, Breakpoints.HandsetPortrait])
.subscribe((state: BreakpointState) => {
if (state.matches) {
this._isMobile = true;
} else {
this._isMobile = false;
}
});
}
get isMobile() {
return this._isMobile;
}
}

View File

@ -1,5 +1,5 @@
<mat-sidenav-container autosize class='main-container'>
<mat-sidenav #sideNav [mode]="isMobile ? 'push' : 'side'" [opened]='!isMobile' disableClose='!isMobile' class="side-panel">
<mat-sidenav #sideNav [mode]="vp.isMobile ? 'push' : 'side'" [opened]='!vp.isMobile' disableClose='!vp.isMobile' class="side-panel">
<mat-toolbar class='nav-toolbar'>
<!-- logo -->
<mat-toolbar-row class='os-logo-container'>
@ -42,39 +42,39 @@
<!-- navigation -->
<mat-nav-list class='main-nav'>
<a [@navItemAnim] *appOsPerms="['core.can_see_frontpage']" mat-list-item routerLink='/' routerLinkActive='active' [routerLinkActiveOptions]="{exact: true}"
(click)='isMobile ? sideNav.toggle() : null'>
(click)='toggleSideNav()'>
<fa-icon icon='home'></fa-icon>
<span translate>Home</span>
</a>
<a [@navItemAnim] *appOsPerms="['agenda.can_see']" mat-list-item routerLink='/agenda' routerLinkActive='active' (click)='isMobile ? sideNav.toggle() : null'>
<a [@navItemAnim] *appOsPerms="['agenda.can_see']" mat-list-item routerLink='/agenda' routerLinkActive='active' (click)='toggleSideNav()'>
<fa-icon icon='calendar'></fa-icon>
<span translate>Agenda</span>
</a>
<a [@navItemAnim] *appOsPerms="['motions.can_see']" mat-list-item routerLink='/motions' routerLinkActive='active' (click)='isMobile ? sideNav.toggle() : null'>
<a [@navItemAnim] *appOsPerms="['motions.can_see']" mat-list-item routerLink='/motions' routerLinkActive='active' (click)='toggleSideNav()'>
<fa-icon icon='file-alt'></fa-icon>
<span translate>Motions</span>
</a>
<a [@navItemAnim] *appOsPerms="['assignments.can_see']" mat-list-item routerLink='/assignments' routerLinkActive='active'
(click)='isMobile ? sideNav.toggle() : null'>
(click)='vp.isMobile ? sideNav.toggle() : null'>
<fa-icon icon='chart-pie'></fa-icon>
<span translate>Assignments</span>
</a>
<a [@navItemAnim] *appOsPerms="['users.can_see_name']" mat-list-item routerLink='/users' routerLinkActive='active' (click)='isMobile ? sideNav.toggle() : null'>
<a [@navItemAnim] *appOsPerms="['users.can_see_name']" mat-list-item routerLink='/users' routerLinkActive='active' (click)='toggleSideNav()'>
<fa-icon icon='user'></fa-icon>
<span translate>Participants</span>
</a>
<a [@navItemAnim] *appOsPerms="['mediafiles.can_see']" mat-list-item routerLink='/mediafiles' routerLinkActive='active' (click)='isMobile ? sideNav.toggle() : null'>
<a [@navItemAnim] *appOsPerms="['mediafiles.can_see']" mat-list-item routerLink='/mediafiles' routerLinkActive='active' (click)='toggleSideNav()'>
<fa-icon icon='paperclip'></fa-icon>
<span translate>Files</span>
</a>
<a [@navItemAnim] *appOsPerms="['core.can_manage_config']" mat-list-item routerLink='/settings' routerLinkActive='active'
(click)='isMobile ? sideNav.toggle() : null'>
(click)='toggleSideNav()'>
<fa-icon icon='cog'></fa-icon>
<span translate>Settings</span>
</a>
<mat-divider></mat-divider>
<a [@navItemAnim] *appOsPerms="['core.can_see_projector']" mat-list-item routerLink='/projector' routerLinkActive='active'
(click)='isMobile ? sideNav.toggle() : null'>
(click)='toggleSideNav()'>
<fa-icon icon='video'></fa-icon>
<span translate>Projector</span>
</a>
@ -83,18 +83,15 @@
<footer>
<button mat-button>
<a routerLink='/legalnotice' (click)='isMobile ? sideNav.toggle() : null'>
<a routerLink='/legalnotice' (click)='toggleSideNav()'>
<span translate>Legal Notice</span>
</a>
</button>
<button mat-button>
<a routerLink='/privacypolicy' (click)='isMobile ? sideNav.toggle() : null'>
<a routerLink='/privacypolicy' (click)='toggleSideNav()'>
<span translate>Privacy Policy</span>
</a>
</button>
<!-- <button mat-button (click)='openPrivacyPolicy()'>
<span translate>Privacy Policy</span>
</button> -->
<br>
<span align="center">© Copyright by
<a href='https://openslides.org/'>OpenSlides</a>
@ -107,7 +104,7 @@
<mat-toolbar color='primary'>
<!-- show/hide menu button -->
<button mat-icon-button *ngIf="isMobile" (click)='sideNav.toggle()'>
<button mat-icon-button *ngIf="vp.isMobile" (click)='sideNav.toggle()'>
<fa-icon icon='bars'></fa-icon>
</button>
@ -122,4 +119,4 @@
<main [@pageTransition]="o.isActivated ? o.activatedRoute : ''">
<router-outlet #o="outlet"></router-outlet>
</main>
</mat-sidenav-container>
</mat-sidenav-container>

View File

@ -1,4 +1,4 @@
import { Component, OnInit, HostBinding } from '@angular/core';
import { Component, OnInit, HostBinding, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout';
@ -9,7 +9,8 @@ import { OperatorService } from 'app/core/services/operator.service';
import { TranslateService } from '@ngx-translate/core'; //showcase
import { BaseComponent } from 'app/base.component';
import { pageTransition, navItemAnim } from 'app/shared/animations';
import { MatDialog } from '@angular/material';
import { MatDialog, MatSidenav } from '@angular/material';
import { ViewportService } from '../core/services/viewport.service';
@Component({
selector: 'app-site',
@ -18,16 +19,16 @@ import { MatDialog } from '@angular/material';
styleUrls: ['./site.component.scss']
})
export class SiteComponent extends BaseComponent implements OnInit {
/**
* HTML element of the side panel
*/
@ViewChild('sideNav') sideNav: MatSidenav;
/**
* Get the username from the operator (should be known already)
*/
username = this.operator.username;
/**
* True if Viewport equals mobile or small resolution. Set by breakpointObserver.
*/
isMobile = false;
/**
* Constructor
*
@ -44,7 +45,7 @@ export class SiteComponent extends BaseComponent implements OnInit {
private autoupdateService: AutoupdateService,
private operator: OperatorService,
private router: Router,
private breakpointObserver: BreakpointObserver,
public vp: ViewportService,
public translate: TranslateService,
public dialog: MatDialog
) {
@ -55,15 +56,7 @@ export class SiteComponent extends BaseComponent implements OnInit {
* Initialize the site component
*/
ngOnInit() {
this.breakpointObserver
.observe([Breakpoints.Small, Breakpoints.HandsetPortrait])
.subscribe((state: BreakpointState) => {
if (state.matches) {
this.isMobile = true;
} else {
this.isMobile = false;
}
});
this.vp.checkForChange();
// get a translation via code: use the translation service
// this.translate.get('Motions').subscribe((res: string) => {
@ -82,6 +75,15 @@ export class SiteComponent extends BaseComponent implements OnInit {
});
}
/**
* Closes the sidenav in mobile view
*/
toggleSideNav() {
if (this.vp.isMobile) {
this.sideNav.toggle();
}
}
/**
* Let the user change the language
* @param lang the desired language (en, de, fr, ...)

View File

@ -3,7 +3,8 @@
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false
production: false,
urlPrefix: '/apps'
};
/*