inserting fixed footer (with @tsiegleauq)
This commit is contained in:
parent
1b02b7c692
commit
9f226c75ee
@ -2,6 +2,8 @@ import { trigger, animate, transition, style, query, stagger, group } from '@ang
|
||||
|
||||
export const pageTransition = trigger('pageTransition', [
|
||||
transition('* => *', [
|
||||
/** this will avoid the dom-copy-effect */
|
||||
query(':enter, :leave', style({ position: 'absolute', width: '100%' }), { optional: true }),
|
||||
/** keep the dom clean - let all items "just" enter */
|
||||
query(':enter mat-card', [style({ opacity: 0 })], { optional: true }),
|
||||
query(':enter .on-transition-fade', [style({ opacity: 0 })], { optional: true }),
|
||||
@ -11,19 +13,63 @@ export const pageTransition = trigger('pageTransition', [
|
||||
/** parallel vanishing */
|
||||
group([
|
||||
/** animate fade out for the selected components */
|
||||
query(':leave .on-transition-fade', [style({ opacity: 1 }), animate('0.2s', style({ opacity: 0 }))], {
|
||||
optional: true
|
||||
}),
|
||||
/** how the material cards are leaving */
|
||||
query(':leave mat-card', [style({ opacity: 1 }), animate('0.2s', style({ opacity: 0 }))], {
|
||||
optional: true
|
||||
}),
|
||||
query(':leave mat-row', [style({ opacity: 1 }), animate('0.2s', style({ opacity: 0 }))], {
|
||||
optional: true
|
||||
}),
|
||||
query(':leave mat-expansion-panel', [style({ opacity: 1 }), animate('0.2s', style({ opacity: 0 }))], {
|
||||
optional: true
|
||||
query(
|
||||
':leave .on-transition-fade',
|
||||
[
|
||||
style({ opacity: 1 }),
|
||||
animate(
|
||||
'200ms ease-in-out',
|
||||
style({
|
||||
transform: 'translateY(0%)',
|
||||
opacity: 0
|
||||
})
|
||||
)
|
||||
],
|
||||
{ optional: true }
|
||||
),
|
||||
/** how the material cards are leaving */
|
||||
query(
|
||||
':leave mat-card',
|
||||
[
|
||||
style({ transform: 'translateY(0%)', opacity: 1 }),
|
||||
animate(
|
||||
'200ms ease-in-out',
|
||||
style({
|
||||
transform: 'translateY(0%)',
|
||||
opacity: 0
|
||||
})
|
||||
)
|
||||
],
|
||||
{ optional: true }
|
||||
),
|
||||
query(
|
||||
':leave mat-row',
|
||||
[
|
||||
style({ transform: 'translateY(0%)', opacity: 1 }),
|
||||
animate(
|
||||
'200ms ease-in-out',
|
||||
style({
|
||||
transform: 'translateY(0%)',
|
||||
opacity: 0
|
||||
})
|
||||
)
|
||||
],
|
||||
{ optional: true }
|
||||
),
|
||||
query(
|
||||
':leave mat-expansion-panel',
|
||||
[
|
||||
style({ transform: 'translateY(0%)', opacity: 1 }),
|
||||
animate(
|
||||
'200ms ease-in-out',
|
||||
style({
|
||||
transform: 'translateY(0%)',
|
||||
opacity: 0
|
||||
})
|
||||
)
|
||||
],
|
||||
{ optional: true }
|
||||
)
|
||||
]),
|
||||
|
||||
/** parallel appearing */
|
||||
|
@ -0,0 +1,12 @@
|
||||
<mat-toolbar color='primary' class="footer">
|
||||
<mat-toolbar-row>
|
||||
<button mat-button class="footer-link" [routerLink]="['/legalnotice']">
|
||||
<span translate>Legal Notice</span>
|
||||
</button>
|
||||
<button mat-button class="footer-link" [routerLink]="['/privacypolicy']">
|
||||
<span translate>Privacy Policy</span>
|
||||
</button>
|
||||
<span class="footer-right">© <span translate>Copyright by</span> <a href='https://openslides.org/'>OpenSlides</a>
|
||||
</span>
|
||||
</mat-toolbar-row>
|
||||
</mat-toolbar>
|
@ -0,0 +1,11 @@
|
||||
.footer-link,
|
||||
.footer-right {
|
||||
font-size: 12px;
|
||||
z-index: inherit;
|
||||
}
|
||||
|
||||
.footer-right {
|
||||
a {
|
||||
color: white;
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FooterComponent } from './footer.component';
|
||||
|
||||
describe('FooterComponent', () => {
|
||||
let component: FooterComponent;
|
||||
let fixture: ComponentFixture<FooterComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [FooterComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FooterComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
29
client/src/app/shared/components/footer/footer.component.ts
Normal file
29
client/src/app/shared/components/footer/footer.component.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Reusable footer Apps.
|
||||
*
|
||||
* ## Examples:
|
||||
*
|
||||
* ### Usage of the selector:
|
||||
*
|
||||
* ```html
|
||||
* <os-footer></os-footer>
|
||||
* ```
|
||||
*/
|
||||
@Component({
|
||||
selector: 'os-footer',
|
||||
templateUrl: './footer.component.html',
|
||||
styleUrls: ['./footer.component.scss']
|
||||
})
|
||||
export class FooterComponent implements OnInit {
|
||||
/**
|
||||
* Empty constructor
|
||||
*/
|
||||
public constructor() {}
|
||||
|
||||
/**
|
||||
* empty onInit
|
||||
*/
|
||||
public ngOnInit() {}
|
||||
}
|
@ -35,6 +35,9 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { PermsDirective } from './directives/perms.directive';
|
||||
import { DomChangeDirective } from './directives/dom-change.directive';
|
||||
import { HeadBarComponent } from './components/head-bar/head-bar.component';
|
||||
import { FooterComponent } from './components/footer/footer.component';
|
||||
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
library.add(fas);
|
||||
|
||||
@ -70,7 +73,8 @@ library.add(fas);
|
||||
MatSnackBarModule,
|
||||
MatDialogModule,
|
||||
TranslateModule.forChild(),
|
||||
FontAwesomeModule
|
||||
FontAwesomeModule,
|
||||
RouterModule
|
||||
],
|
||||
exports: [
|
||||
FormsModule,
|
||||
@ -96,8 +100,9 @@ library.add(fas);
|
||||
TranslateModule,
|
||||
PermsDirective,
|
||||
DomChangeDirective,
|
||||
FooterComponent,
|
||||
HeadBarComponent
|
||||
],
|
||||
declarations: [PermsDirective, DomChangeDirective, HeadBarComponent]
|
||||
declarations: [PermsDirective, DomChangeDirective, HeadBarComponent, FooterComponent]
|
||||
})
|
||||
export class SharedModule {}
|
||||
|
@ -1,8 +1,11 @@
|
||||
<!-- The actual form -->
|
||||
<mat-toolbar class="login-logo-bar" color="primary">
|
||||
<header>
|
||||
<mat-toolbar class="login-logo-bar" color="primary">
|
||||
<img src='/assets/img/openslides-logo-h-dark-transparent.svg' alt='OpenSlides-logo'>
|
||||
</mat-toolbar>
|
||||
<div class="form-wrapper">
|
||||
</mat-toolbar>
|
||||
</header>
|
||||
<main>
|
||||
<div class="form-wrapper">
|
||||
|
||||
<mat-spinner *ngIf="inProcess"></mat-spinner>
|
||||
<form [formGroup]="loginForm" class="login-form" (ngSubmit)="formLogin()">
|
||||
@ -24,8 +27,12 @@
|
||||
<br>
|
||||
<!-- TODO: Next to each other...-->
|
||||
<button mat-raised-button color="primary" class='login-button' type="submit" translate>Login</button>
|
||||
<button mat-raised-button *ngIf="areGuestsEnabled()" color="primary" class='login-button'
|
||||
type="button" (click)="guestLogin()" translate>Login as Guest</button>
|
||||
<button mat-raised-button *ngIf="areGuestsEnabled()" color="primary" class='login-button' type="button" (click)="guestLogin()" translate>Login as Guest</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
<footer class="page-footer">
|
||||
<os-footer></os-footer>
|
||||
</footer>
|
||||
|
@ -2,15 +2,21 @@ mat-form-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-logo-bar {
|
||||
height: 45% !important;
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
mat-toolbar {
|
||||
min-height: 200px !important;
|
||||
}
|
||||
.login-logo-bar {
|
||||
img {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
max-width: 400px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.forgot-password-button {
|
||||
@ -29,7 +35,6 @@ mat-form-field {
|
||||
.form-wrapper {
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
|
||||
mat-spinner {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@ -44,3 +49,7 @@ mat-form-field {
|
||||
margin: 0 auto;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
footer {
|
||||
bottom: 0; //black magic to keep the toolbar active here
|
||||
}
|
||||
|
@ -0,0 +1,3 @@
|
||||
mat-card {
|
||||
height: 100%;
|
||||
}
|
@ -80,26 +80,9 @@
|
||||
<span translate>Projector</span>
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
|
||||
|
||||
<footer>
|
||||
<button mat-button>
|
||||
<a routerLink='/legalnotice' (click)='toggleSideNav()'>
|
||||
<span translate>Legal Notice</span>
|
||||
</a>
|
||||
</button>
|
||||
<button mat-button>
|
||||
<a routerLink='/privacypolicy' (click)='toggleSideNav()'>
|
||||
<span translate>Privacy Policy</span>
|
||||
</a>
|
||||
</button>
|
||||
<br>
|
||||
<span align="center">© Copyright by
|
||||
<a href='https://openslides.org/'>OpenSlides</a>
|
||||
</span>
|
||||
</footer>
|
||||
</mat-sidenav>
|
||||
|
||||
<div class="content">
|
||||
<header>
|
||||
<!-- the first toolbar row is (still) a global element
|
||||
the second one shall be handled by the apps -->
|
||||
<mat-toolbar color='primary'>
|
||||
@ -115,9 +98,15 @@
|
||||
<fa-icon icon='search'></fa-icon>
|
||||
</button>
|
||||
</mat-toolbar>
|
||||
</header>
|
||||
|
||||
<!-- continue with <mat-toolbar> in the app-->
|
||||
<div class="relax">
|
||||
<main [@pageTransition]="o.isActivated ? o.activatedRoute : ''">
|
||||
<router-outlet #o="outlet"></router-outlet>
|
||||
</main>
|
||||
<footer>
|
||||
<os-footer></os-footer>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</mat-sidenav-container>
|
||||
|
@ -1,12 +1,3 @@
|
||||
mat-sidenav-container {
|
||||
height: 100%;
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.projector-button {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
@ -25,14 +16,30 @@ mat-sidenav-container {
|
||||
box-shadow: 3px 0px 10px 0px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
.content {
|
||||
min-height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
span {
|
||||
// width: 100%;
|
||||
mat-sidenav-container {
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.relax {
|
||||
position: initial;
|
||||
padding-bottom: 70px;
|
||||
}
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 50;
|
||||
flex: 1;
|
||||
> *:not(router-outlet) {
|
||||
flex: 1;
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,56 @@
|
||||
{
|
||||
"Agenda": "Tagesordnung",
|
||||
"Assignments": "Wahlen",
|
||||
"Category": "",
|
||||
"Change Password": "Passwort ändern",
|
||||
"Content": "",
|
||||
"Cookies": "",
|
||||
"Copyright by": "Copyright by",
|
||||
"Database": "",
|
||||
"DeleteMotion": "",
|
||||
"Deleting Files": "",
|
||||
"Edit Profile": "Profil bearbeiten",
|
||||
"English": "Englisch",
|
||||
"Export As": {
|
||||
"0": {
|
||||
"0": {
|
||||
"0": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"FILTER": "",
|
||||
"Files": "Dateien",
|
||||
"French": "Französisch",
|
||||
"German": "Deutsch",
|
||||
"Hello user": "Hallo {{user}}",
|
||||
"Home": "Startseite",
|
||||
"Identifier": "",
|
||||
"Legal Notice": "Impressum",
|
||||
"Log In": "Anmelden",
|
||||
"Logfiles": "",
|
||||
"Login": "",
|
||||
"Login as Guest": "",
|
||||
"Logout": "Abmelden",
|
||||
"Meta information": "",
|
||||
"Motion": "",
|
||||
"Motions": "Anträge",
|
||||
"OK": "",
|
||||
"Offline mode: You can use OpenSlides but changes are not saved": {
|
||||
"0": ""
|
||||
},
|
||||
"Origin": "",
|
||||
"Participants": "Teilnehmer",
|
||||
"Personal note": "",
|
||||
"Privacy Policy": "Datenschutz",
|
||||
"Project": "",
|
||||
"Projector": "",
|
||||
"Reason": "",
|
||||
"Reset State": "",
|
||||
"Reset recommendation": "",
|
||||
"SORT": "",
|
||||
"Settings": "Einstellungen",
|
||||
"Users": "Benutzer",
|
||||
"Welcome to OpenSlides": "Willkommen bei OpenSlides"
|
||||
"State": "",
|
||||
"Submitters": "",
|
||||
"Supporters": "",
|
||||
"The assembly may decide:": "",
|
||||
"Welcome to OpenSlides": "Willkommen bei OpenSlides",
|
||||
"by": ""
|
||||
}
|
||||
|
@ -1,21 +1,56 @@
|
||||
{
|
||||
"Agenda": "",
|
||||
"Assignments": "",
|
||||
"Category": "",
|
||||
"Change Password": "",
|
||||
"Content": "",
|
||||
"Cookies": "",
|
||||
"Copyright by": "",
|
||||
"Database": "",
|
||||
"DeleteMotion": "",
|
||||
"Deleting Files": "",
|
||||
"Edit Profile": "",
|
||||
"English": "",
|
||||
"Export As": {
|
||||
"0": {
|
||||
"0": {
|
||||
"0": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"FILTER": "",
|
||||
"Files": "",
|
||||
"French": "",
|
||||
"German": "",
|
||||
"Hello user": "Hello {{user}}",
|
||||
"Home": "",
|
||||
"Identifier": "",
|
||||
"Legal Notice": "",
|
||||
"Log In": "",
|
||||
"Logfiles": "",
|
||||
"Login": "",
|
||||
"Login as Guest": "",
|
||||
"Logout": "",
|
||||
"Meta information": "",
|
||||
"Motion": "",
|
||||
"Motions": "",
|
||||
"OK": "",
|
||||
"Offline mode: You can use OpenSlides but changes are not saved": {
|
||||
"0": ""
|
||||
},
|
||||
"Origin": "",
|
||||
"Participants": "",
|
||||
"Personal note": "",
|
||||
"Privacy Policy": "",
|
||||
"Project": "",
|
||||
"Projector": "",
|
||||
"Reason": "",
|
||||
"Reset State": "",
|
||||
"Reset recommendation": "",
|
||||
"SORT": "",
|
||||
"Settings": "",
|
||||
"Users": "",
|
||||
"Welcome to OpenSlides": ""
|
||||
"State": "",
|
||||
"Submitters": "",
|
||||
"Supporters": "",
|
||||
"The assembly may decide:": "",
|
||||
"Welcome to OpenSlides": "",
|
||||
"by": ""
|
||||
}
|
||||
|
@ -1,21 +1,56 @@
|
||||
{
|
||||
"Agenda": "",
|
||||
"Assignments": "",
|
||||
"Category": "",
|
||||
"Change Password": "",
|
||||
"Content": "",
|
||||
"Cookies": "",
|
||||
"Copyright by": "",
|
||||
"Database": "",
|
||||
"DeleteMotion": "",
|
||||
"Deleting Files": "",
|
||||
"Edit Profile": "",
|
||||
"English": "",
|
||||
"Export As": {
|
||||
"0": {
|
||||
"0": {
|
||||
"0": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"FILTER": "",
|
||||
"Files": "",
|
||||
"French": "",
|
||||
"German": "",
|
||||
"Hello user": "",
|
||||
"Home": "",
|
||||
"Identifier": "",
|
||||
"Legal Notice": "",
|
||||
"Log In": "",
|
||||
"Logfiles": "",
|
||||
"Login": "",
|
||||
"Login as Guest": "",
|
||||
"Logout": "",
|
||||
"Meta information": "",
|
||||
"Motion": "",
|
||||
"Motions": "",
|
||||
"OK": "",
|
||||
"Offline mode: You can use OpenSlides but changes are not saved": {
|
||||
"0": ""
|
||||
},
|
||||
"Origin": "",
|
||||
"Participants": "",
|
||||
"Personal note": "",
|
||||
"Privacy Policy": "",
|
||||
"Project": "",
|
||||
"Projector": "",
|
||||
"Reason": "",
|
||||
"Reset State": "",
|
||||
"Reset recommendation": "",
|
||||
"SORT": "",
|
||||
"Settings": "",
|
||||
"Users": "",
|
||||
"Welcome to OpenSlides": ""
|
||||
"State": "",
|
||||
"Submitters": "",
|
||||
"Supporters": "",
|
||||
"The assembly may decide:": "",
|
||||
"Welcome to OpenSlides": "",
|
||||
"by": ""
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
@import '~@angular/material/theming';
|
||||
|
||||
@include mat-core();
|
||||
|
||||
/** Import brand theme and (new) component themes */
|
||||
@import './assets/styles/openslides-theme';
|
||||
@import './app/site/site.component.scss-theme';
|
||||
|
||||
@mixin openslides-components-theme($theme) {
|
||||
@include os-site-theme($theme);
|
||||
/** More components are added here */
|
||||
@ -13,35 +11,16 @@
|
||||
|
||||
@include angular-material-theme($openslides-theme);
|
||||
@include openslides-components-theme($openslides-theme);
|
||||
|
||||
* {
|
||||
font-family: Arial, Helvetica, sans-serif !important;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
body {
|
||||
// background: #e8eaed;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
router-outlet ~ * {
|
||||
position: absolute;
|
||||
height: 100% !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/**the plus button in Motion, Agenda, etc*/
|
||||
.generic-plus-button {
|
||||
bottom: -30px;
|
||||
@ -52,6 +31,7 @@ router-outlet ~ * {
|
||||
bottom: -28px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.os-card {
|
||||
max-width: 90%;
|
||||
margin-top: 10px;
|
||||
@ -83,3 +63,11 @@ router-outlet ~ * {
|
||||
.on-transition-fade {
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user