Merge pull request #4110 from jsaalfeld/logo_component
adding and implementing logo component
This commit is contained in:
commit
85a2597b27
@ -0,0 +1,3 @@
|
||||
<div *ngIf="getImage() != ''" class="logo-container">
|
||||
<img [src]="getImage()">
|
||||
</div>
|
10
client/src/app/shared/components/logo/logo.component.scss
Normal file
10
client/src/app/shared/components/logo/logo.component.scss
Normal file
@ -0,0 +1,10 @@
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
25
client/src/app/shared/components/logo/logo.component.spec.ts
Normal file
25
client/src/app/shared/components/logo/logo.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { E2EImportsModule } from 'e2e-imports.module';
|
||||
import { LogoComponent } from './logo.component';
|
||||
|
||||
describe('LogoComponent', () => {
|
||||
let component: LogoComponent;
|
||||
let fixture: ComponentFixture<LogoComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [E2EImportsModule]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LogoComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
155
client/src/app/shared/components/logo/logo.component.ts
Normal file
155
client/src/app/shared/components/logo/logo.component.ts
Normal file
@ -0,0 +1,155 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { MediaManageService } from '../../../site/mediafiles/services/media-manage.service';
|
||||
|
||||
/**
|
||||
* Reusable Logo component for Apps.
|
||||
*
|
||||
* Following actions are possible:
|
||||
* * "logo_projector_main"
|
||||
* * "logo_projector_header"
|
||||
* * "logo_web_header"
|
||||
* * "logo_pdf_header_L"
|
||||
* * "logo_pdf_header_R"
|
||||
* * "logo_pdf_footer_L"
|
||||
* * "logo_pdf_footer_R"
|
||||
* * "logo_pdf_ballot_paper"
|
||||
*
|
||||
* ## Examples:
|
||||
*
|
||||
* ### Usage of the selector:
|
||||
*
|
||||
* ```html
|
||||
* <os-logo
|
||||
* inputAction="logo_projector_main"
|
||||
* [footer]="false"
|
||||
* [alignment]="right">
|
||||
* </os-logo>
|
||||
* ```
|
||||
*
|
||||
* Sidenote: The footer variable is optional. Only if you want
|
||||
* alternating logos, i.E. in the sidenav. the Alignment is also
|
||||
* optional.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'os-logo',
|
||||
templateUrl: './logo.component.html',
|
||||
styleUrls: ['./logo.component.scss']
|
||||
})
|
||||
export class LogoComponent implements OnInit {
|
||||
/**
|
||||
* Constant path of the dark logo
|
||||
*/
|
||||
public static STANDARD_LOGO = '/assets/img/openslides-logo-h.svg';
|
||||
|
||||
/**
|
||||
* Holds the actions for logos. Updated via an observable
|
||||
*/
|
||||
public logoActions: string[];
|
||||
|
||||
/**
|
||||
* decides based on the actionString how to display the logo
|
||||
*/
|
||||
@Input()
|
||||
public inputAction: string;
|
||||
|
||||
/**
|
||||
* determines if the current picture is displayed in the footer.
|
||||
* Optional.
|
||||
*/
|
||||
@Input()
|
||||
public footer = false;
|
||||
|
||||
/**
|
||||
* influences text-alignment in the .logo-container css class
|
||||
*/
|
||||
@Input()
|
||||
public alignment = 'center';
|
||||
/**
|
||||
* The consotructor
|
||||
*
|
||||
* @param mmservice The Media Manage Service
|
||||
*/
|
||||
public constructor(private mmservice: MediaManageService) {}
|
||||
|
||||
/**
|
||||
* Initialization function
|
||||
*/
|
||||
public ngOnInit(): void {
|
||||
this.mmservice.getLogoActions().subscribe(action => {
|
||||
this.logoActions = action;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the image based on the inputAction and location.
|
||||
* Possible inputActions are in the class description.
|
||||
*
|
||||
* @returns path to image
|
||||
*/
|
||||
public getImage(): string {
|
||||
if (this.footer) {
|
||||
const path = this.getFooterImage(this.inputAction);
|
||||
return path;
|
||||
} else {
|
||||
const path = this.getHeaderImage(this.inputAction, this.alignment);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the header image based on logo action
|
||||
*
|
||||
* @param logoAction the logo action to be used
|
||||
* @param alignment the alignment of the logo (optional)
|
||||
* @returns path to image
|
||||
*/
|
||||
protected getHeaderImage(logoAction: string, alignment: string = 'center'): string {
|
||||
if (alignment !== 'center') {
|
||||
this.setAlignment(alignment);
|
||||
}
|
||||
let path = '';
|
||||
/* check if datastore is loaded and custom logo can be read */
|
||||
if (this.logoActions === undefined) {
|
||||
return '';
|
||||
}
|
||||
if (this.mmservice !== undefined) {
|
||||
if (this.mmservice.isImageConfigObject(this.mmservice.getMediaConfig(logoAction))) {
|
||||
const imageConfig = this.mmservice.getMediaConfig(logoAction);
|
||||
path = imageConfig.path;
|
||||
}
|
||||
}
|
||||
if (path === '') {
|
||||
path = LogoComponent.STANDARD_LOGO;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the alignment from center to either 'left' or 'right'
|
||||
*
|
||||
* @param alignment either 'right' or 'left'
|
||||
*/
|
||||
private setAlignment(alignment: string): void {
|
||||
if (alignment === 'left' || alignment === 'right') {
|
||||
const cssLogoContainer = document.getElementsByClassName('logo-container') as HTMLCollectionOf<HTMLElement>;
|
||||
if (cssLogoContainer.length !== 0) {
|
||||
cssLogoContainer[0].style.textAlign = alignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image-path for the footer
|
||||
*
|
||||
* @param logoAction the logo action to be used
|
||||
* @returns '' if no logo is set and path to standard logo if a custom
|
||||
* logo was set
|
||||
*/
|
||||
protected getFooterImage(logoAction: string): string {
|
||||
if (this.getHeaderImage(logoAction) === LogoComponent.STANDARD_LOGO || this.getHeaderImage(logoAction) === '') {
|
||||
return '';
|
||||
} else {
|
||||
return LogoComponent.STANDARD_LOGO;
|
||||
}
|
||||
}
|
||||
}
|
@ -70,6 +70,7 @@ import { ChoiceDialogComponent } from './components/choice-dialog/choice-dialog.
|
||||
import { OsSortFilterBarComponent } from './components/os-sort-filter-bar/os-sort-filter-bar.component';
|
||||
import { OsSortBottomSheetComponent } from './components/os-sort-filter-bar/os-sort-bottom-sheet/os-sort-bottom-sheet.component';
|
||||
import { FilterMenuComponent } from './components/os-sort-filter-bar/filter-menu/filter-menu.component';
|
||||
import { LogoComponent } from './components/logo/logo.component';
|
||||
|
||||
/**
|
||||
* Share Module for all "dumb" components and pipes.
|
||||
@ -171,7 +172,8 @@ import { FilterMenuComponent } from './components/os-sort-filter-bar/filter-menu
|
||||
EditorModule,
|
||||
SortingTreeComponent,
|
||||
TreeModule,
|
||||
OsSortFilterBarComponent
|
||||
OsSortFilterBarComponent,
|
||||
LogoComponent
|
||||
],
|
||||
declarations: [
|
||||
PermsDirective,
|
||||
@ -188,7 +190,8 @@ import { FilterMenuComponent } from './components/os-sort-filter-bar/filter-menu
|
||||
ChoiceDialogComponent,
|
||||
OsSortFilterBarComponent,
|
||||
OsSortBottomSheetComponent,
|
||||
FilterMenuComponent
|
||||
FilterMenuComponent,
|
||||
LogoComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: DateAdapter, useClass: OpenSlidesDateAdapter },
|
||||
|
@ -79,6 +79,18 @@ export class MediaManageService {
|
||||
return this.httpService.put<void>(restPath, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an image is an imageConfig Object
|
||||
*
|
||||
* @param object instance of something to check
|
||||
* @returns boolean if an object is a ImageConfigObject
|
||||
*/
|
||||
public isImageConfigObject(object: any): object is ImageConfigObject {
|
||||
if (object !== undefined) {
|
||||
return (<ImageConfigObject>object).path !== undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all actions that can be executed on images
|
||||
*
|
||||
|
@ -10,10 +10,14 @@
|
||||
disableClose="!vp.isMobile"
|
||||
class="side-panel"
|
||||
>
|
||||
<mat-toolbar class="nav-toolbar">
|
||||
<div class="nav-toolbar">
|
||||
<!-- logo -->
|
||||
<mat-toolbar-row class="os-logo-container" routerLink="/" (click)="toggleSideNav()"></mat-toolbar-row>
|
||||
</mat-toolbar>
|
||||
<a routerLink="/" (click)="toggleSideNav()">
|
||||
<os-logo class="os-logo-container"
|
||||
inputAction="logo_web_header"
|
||||
[footer]="false"></os-logo>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- User Menu -->
|
||||
<mat-expansion-panel class="user-menu mat-elevation-z0">
|
||||
@ -118,6 +122,11 @@
|
||||
>
|
||||
<span><small>© Copyright by OpenSlides</small></span>
|
||||
</a>
|
||||
<div class="os-footer-logo-container">
|
||||
<os-logo inputAction="logo_web_header"
|
||||
footer="true">
|
||||
</os-logo>
|
||||
</div>
|
||||
</mat-nav-list>
|
||||
</mat-sidenav>
|
||||
<mat-sidenav-content>
|
||||
|
@ -32,19 +32,35 @@ mat-sidenav-container {
|
||||
}
|
||||
}
|
||||
|
||||
/* Logo container */
|
||||
.os-logo-container {
|
||||
width: 200px;
|
||||
margin-left: 10px;
|
||||
background-image: url(/assets/img/openslides-logo-h.svg);
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
cursor: pointer;
|
||||
.nav-toolbar {
|
||||
display: flex;
|
||||
margin: auto;
|
||||
width: 250px;
|
||||
height: 80px;
|
||||
align-items: center;
|
||||
}
|
||||
/* The top logo container can contain any logo with any size.
|
||||
It needs to always fit.*/
|
||||
.os-logo-container {
|
||||
margin: auto;
|
||||
width: 250px !important;
|
||||
max-height: 80px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* The footer container only appears when custom logo is
|
||||
specified. It can only contain the standard logo */
|
||||
.os-footer-logo-container {
|
||||
width: 150px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.os-logo-container:focus,
|
||||
.os-logo-container:active,
|
||||
.os-logo-container:hover {
|
||||
.os-logo-container:hover,
|
||||
.os-footer-logo-container:focus,
|
||||
.os-footer-logo-container:active,
|
||||
.os-footer-logo-container:hover {
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user