Layout and translation fixes
This commit is contained in:
parent
c5b38cc430
commit
b64b49cc2e
@ -44,3 +44,10 @@ A running OpenSlides (2.2 or higher) instance is expected on port 8000.
|
||||
|
||||
Start OpenSlides as usual using
|
||||
`python manage.py start --no-browser --host 0.0.0.0`
|
||||
|
||||
### Translation
|
||||
|
||||
We are using ngx-translate for translation purposes.
|
||||
Use `npm run extract` to extract strings and update elements an with translation functions.
|
||||
|
||||
Language files can be found in `/src/assets/i18n`.
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Injector } from '@angular/core';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { OpenSlidesComponent } from './openslides.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
/**
|
||||
* Provides functionalities that will be used by most components
|
||||
@ -20,7 +20,7 @@ export abstract class BaseComponent extends OpenSlidesComponent {
|
||||
/**
|
||||
* Child constructor that implements the titleServices and calls Super from OpenSlidesComponent
|
||||
*/
|
||||
constructor(protected titleService?: Title) {
|
||||
constructor(protected titleService?: Title, protected translate?: TranslateService) {
|
||||
super();
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ export abstract class BaseComponent extends OpenSlidesComponent {
|
||||
* TODO Might translate the prefix here?
|
||||
*/
|
||||
setTitle(prefix: string): void {
|
||||
this.titleService.setTitle(prefix + this.titleSuffix);
|
||||
const translatedPrefix = this.translate.instant(prefix);
|
||||
this.titleService.setTitle(translatedPrefix + this.titleSuffix);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { BaseComponent } from 'app/base.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-agenda-list',
|
||||
@ -8,12 +9,11 @@ import { BaseComponent } from 'app/base.component';
|
||||
styleUrls: ['./agenda-list.component.css']
|
||||
})
|
||||
export class AgendaListComponent extends BaseComponent implements OnInit {
|
||||
constructor(titleService: Title) {
|
||||
super(titleService);
|
||||
constructor(titleService: Title, protected translate: TranslateService) {
|
||||
super(titleService, translate);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
//TODO translate
|
||||
super.setTitle('Agenda');
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,21 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { BaseComponent } from '../../../base.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: 'app-assignment-list',
|
||||
templateUrl: './assignment-list.component.html',
|
||||
styleUrls: ['./assignment-list.component.css']
|
||||
})
|
||||
export class AssignmentListComponent implements OnInit {
|
||||
constructor() {}
|
||||
export class AssignmentListComponent extends BaseComponent implements OnInit {
|
||||
constructor(titleService: Title, protected translate: TranslateService) {
|
||||
super(titleService, translate);
|
||||
}
|
||||
|
||||
ngOnInit() {}
|
||||
ngOnInit() {
|
||||
super.setTitle('Assignments');
|
||||
}
|
||||
|
||||
downloadAssignmentButton(): void {
|
||||
console.log('Hello World');
|
||||
|
@ -7,6 +7,7 @@ import { AuthService } from 'app/core/services/auth.service';
|
||||
import { OperatorService } from 'app/core/services/operator.service';
|
||||
import { ErrorStateMatcher } from '@angular/material';
|
||||
import { FormControl, FormGroupDirective, NgForm, FormGroup, Validators, FormBuilder } from '@angular/forms';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
/**
|
||||
* Custom error states. Might become part of the shared module later.
|
||||
@ -64,6 +65,7 @@ export class LoginComponent extends BaseComponent implements OnInit {
|
||||
inProcess = false;
|
||||
|
||||
/**
|
||||
* Constructor for the login component
|
||||
*
|
||||
* @param titleService Setting the title
|
||||
* @param authService Authenticating the user
|
||||
@ -72,13 +74,14 @@ export class LoginComponent extends BaseComponent implements OnInit {
|
||||
* @param formBuilder To build the form and validate
|
||||
*/
|
||||
constructor(
|
||||
titleService: Title,
|
||||
protected titleService: Title,
|
||||
protected translate: TranslateService,
|
||||
private authService: AuthService,
|
||||
private operator: OperatorService,
|
||||
private router: Router,
|
||||
private formBuilder: FormBuilder
|
||||
) {
|
||||
super(titleService);
|
||||
super(titleService, translate);
|
||||
this.createForm();
|
||||
}
|
||||
|
||||
@ -89,6 +92,8 @@ export class LoginComponent extends BaseComponent implements OnInit {
|
||||
* Observes the operator, if a user was already logged in, recreate to user and skip the login
|
||||
*/
|
||||
ngOnInit() {
|
||||
//this is necessary since the HTML document never uses the word "Log In"
|
||||
const loginWord = this.translate.instant('Log In');
|
||||
super.setTitle('Log In');
|
||||
|
||||
// if there is stored login information, try to login directly.
|
||||
|
@ -1,12 +1,19 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { BaseComponent } from '../../../base.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-mediafile-list',
|
||||
templateUrl: './mediafile-list.component.html',
|
||||
styleUrls: ['./mediafile-list.component.css']
|
||||
})
|
||||
export class MediafileListComponent implements OnInit {
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
export class MediafileListComponent extends BaseComponent implements OnInit {
|
||||
constructor(titleService: Title, protected translate: TranslateService) {
|
||||
super(titleService, translate);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.setTitle('Files');
|
||||
}
|
||||
}
|
||||
|
@ -39,3 +39,103 @@
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
||||
<mat-card class="os-card card-plus-distance">
|
||||
<div class="app-content">
|
||||
Motion Works
|
||||
</div>
|
||||
</mat-card>
|
@ -1,6 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { BaseComponent } from 'app/base.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-motion-list',
|
||||
@ -8,8 +9,8 @@ import { BaseComponent } from 'app/base.component';
|
||||
styleUrls: ['./motion-list.component.css']
|
||||
})
|
||||
export class MotionListComponent extends BaseComponent implements OnInit {
|
||||
constructor(titleService: Title) {
|
||||
super(titleService);
|
||||
constructor(titleService: Title, protected translate: TranslateService) {
|
||||
super(titleService, translate);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
@ -1,12 +1,19 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { BaseComponent } from '../../../base.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-list',
|
||||
templateUrl: './settings-list.component.html',
|
||||
styleUrls: ['./settings-list.component.css']
|
||||
})
|
||||
export class SettingsListComponent implements OnInit {
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
export class SettingsListComponent extends BaseComponent implements OnInit {
|
||||
constructor(titleService: Title, protected translate: TranslateService) {
|
||||
super(titleService, translate);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.setTitle('Settings');
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
<mat-sidenav-container autosize class='main-container'>
|
||||
<mat-sidenav #sideNav [mode]="isMobile ? 'push' : 'side'" [opened]='!isMobile' disableClose='!isMobile' class="side-panel">
|
||||
<mat-toolbar class='nav-toolbar'>
|
||||
|
||||
<!-- logo -->
|
||||
<mat-toolbar-row class='os-logo-container'>
|
||||
<!-- <img src='/assets/img/openslides-logo-h-dark-transparent.svg' alt='OpenSlides-logo'> -->
|
||||
</mat-toolbar-row>
|
||||
</mat-toolbar>
|
||||
|
||||
@ -16,7 +14,6 @@
|
||||
</mat-expansion-panel-header>
|
||||
<mat-nav-list>
|
||||
<!-- <mat-list-item> -->
|
||||
|
||||
<a (click)='logOutButton()' mat-list-item>
|
||||
<fa-icon icon='user-cog'></fa-icon>
|
||||
<span translate>Edit Profile</span>
|
||||
@ -30,24 +27,7 @@
|
||||
<fa-icon icon='sign-out-alt'></fa-icon>
|
||||
<span translate>Logout</span>
|
||||
</a>
|
||||
|
||||
<!-- <button (click)='logOutButton()' mat-button>
|
||||
<fa-icon icon='user-cog'></fa-icon> Edit Profile</button> -->
|
||||
<!-- </mat-list-item>
|
||||
<mat-list-item>
|
||||
<button (click)='logOutButton()' mat-button>
|
||||
<fa-icon icon='key'></fa-icon> Change Password</button>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item>
|
||||
<button (click)='logOutButton()' mat-button>
|
||||
<fa-icon icon='sign-out-alt'> </fa-icon>Logout</button>
|
||||
</mat-list-item> -->
|
||||
</mat-nav-list>
|
||||
<!-- TODO translate -->
|
||||
|
||||
|
||||
|
||||
</mat-expansion-panel>
|
||||
|
||||
<!-- navigation -->
|
||||
@ -87,9 +67,12 @@
|
||||
|
||||
|
||||
<footer>
|
||||
<!-- TODO Translate -->
|
||||
<button mat-button (click)='openLegalNotice()'>Legal Notice</button>
|
||||
<button mat-button (click)='openPrivacyPolicy()'>Privacy Policy</button>
|
||||
<button mat-button (click)='openLegalNotice()'>
|
||||
<span translate>Legal Notice</span>
|
||||
</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>
|
||||
@ -102,7 +85,6 @@
|
||||
<mat-toolbar color='primary'>
|
||||
|
||||
<!-- show/hide menu button -->
|
||||
<!-- <button mat-icon-button (click)='sideNav.toggle()'> -->
|
||||
<button mat-icon-button *ngIf="isMobile" (click)='sideNav.toggle()'>
|
||||
<fa-icon icon='bars'></fa-icon>
|
||||
</button>
|
||||
|
@ -1,11 +1,16 @@
|
||||
mat-sidenav-container {
|
||||
height: 100%;
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.projector-button {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
.os-logo-container {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit, HostBinding } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout';
|
||||
|
||||
@ -29,7 +29,6 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
||||
* True if Viewport equals mobile or small resolution. Set by breakpointObserver.
|
||||
*/
|
||||
isMobile = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -47,7 +46,7 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
||||
private operator: OperatorService,
|
||||
private router: Router,
|
||||
private breakpointObserver: BreakpointObserver,
|
||||
private translate: TranslateService,
|
||||
protected translate: TranslateService,
|
||||
public dialog: MatDialog
|
||||
) {
|
||||
super();
|
||||
|
@ -17,12 +17,12 @@ export class StartComponent extends BaseComponent implements OnInit {
|
||||
//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);
|
||||
constructor(titleService: Title, protected translate: TranslateService, private operator: OperatorService) {
|
||||
super(titleService, translate);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.setTitle('Start page'); //TODO translate
|
||||
super.setTitle('Home');
|
||||
}
|
||||
|
||||
//quick testing of some data store functions
|
||||
|
@ -1,12 +1,19 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { BaseComponent } from '../../../base.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-user-list',
|
||||
templateUrl: './user-list.component.html',
|
||||
styleUrls: ['./user-list.component.css']
|
||||
})
|
||||
export class UserListComponent implements OnInit {
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
export class UserListComponent extends BaseComponent implements OnInit {
|
||||
constructor(titleService: Title, protected translate: TranslateService) {
|
||||
super(titleService, translate);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.setTitle('Users');
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,21 @@
|
||||
{
|
||||
"Agenda": "Tagesordnung",
|
||||
"Assignments": "Wahlen",
|
||||
"Change Password": "Passwort ändern",
|
||||
"Edit Profile": "Profil bearbeiten",
|
||||
"English": "Englisch",
|
||||
"French": "",
|
||||
"Files": "Dateien",
|
||||
"French": "Französisch",
|
||||
"German": "Deutsch",
|
||||
"Hello user": "Hallo {{user}}",
|
||||
"Home": "Startseite",
|
||||
"Legal Notice": "Impressum",
|
||||
"Log In": "Anmelden",
|
||||
"Logout": "Abmelden",
|
||||
"Motions": "Anträge",
|
||||
"Participants": "Teilnehmer",
|
||||
"Privacy Policy": "Datenschutz",
|
||||
"Settings": "Einstellungen",
|
||||
"Users": "Benutzer",
|
||||
"Welcome to OpenSlides": "Willkommen bei OpenSlides"
|
||||
}
|
||||
|
@ -1,10 +1,21 @@
|
||||
{
|
||||
"Agenda": "Agenda",
|
||||
"English": "English",
|
||||
"Agenda": "",
|
||||
"Assignments": "",
|
||||
"Change Password": "",
|
||||
"Edit Profile": "",
|
||||
"English": "",
|
||||
"Files": "",
|
||||
"French": "",
|
||||
"German": "German",
|
||||
"German": "",
|
||||
"Hello user": "Hello {{user}}",
|
||||
"Home": "Home",
|
||||
"Motions": "Motions",
|
||||
"Welcome to OpenSlides": "Welcome to OpenSlides"
|
||||
"Home": "",
|
||||
"Legal Notice": "",
|
||||
"Log In": "",
|
||||
"Logout": "",
|
||||
"Motions": "",
|
||||
"Participants": "",
|
||||
"Privacy Policy": "",
|
||||
"Settings": "",
|
||||
"Users": "",
|
||||
"Welcome to OpenSlides": ""
|
||||
}
|
||||
|
@ -1,10 +1,21 @@
|
||||
{
|
||||
"Agenda": "",
|
||||
"Assignments": "",
|
||||
"Change Password": "",
|
||||
"Edit Profile": "",
|
||||
"English": "",
|
||||
"Files": "",
|
||||
"French": "",
|
||||
"German": "",
|
||||
"Hello user": "",
|
||||
"Home": "",
|
||||
"Legal Notice": "",
|
||||
"Log In": "",
|
||||
"Logout": "",
|
||||
"Motions": "",
|
||||
"Participants": "",
|
||||
"Privacy Policy": "",
|
||||
"Settings": "",
|
||||
"Users": "",
|
||||
"Welcome to OpenSlides": ""
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ body {
|
||||
right: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
@ -39,9 +38,8 @@ body {
|
||||
|
||||
router-outlet ~ * {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
height: 100% !important;
|
||||
width: 100%;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
/**the plus button in Motion, Agenda, etc*/
|
||||
|
Loading…
Reference in New Issue
Block a user