mirror of
https://gitlab.com/openlp/web-remote.git
synced 2024-12-22 11:32:47 +00:00
Merge branch 'small-adjustments' into 'master'
Various small adjustments Closes #28 e #29 See merge request openlp/web-remote!60
This commit is contained in:
commit
0e9567fc76
7
.browserslistrc
Normal file
7
.browserslistrc
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
last 10 Chrome version
|
||||||
|
last 10 Firefox version
|
||||||
|
last 10 Edge major versions
|
||||||
|
last 2 Safari major versions
|
||||||
|
last 2 iOS major versions
|
||||||
|
Firefox ESR
|
||||||
|
not IE >= 0 # IE is dead
|
@ -19,17 +19,29 @@
|
|||||||
<mat-sidenav-container>
|
<mat-sidenav-container>
|
||||||
<mat-sidenav #menu mode="over">
|
<mat-sidenav #menu mode="over">
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<a mat-list-item (click)="menu.close()" routerLink="/service"><mat-icon>list</mat-icon> Service</a>
|
<a mat-list-item (click)="menu.close()" routerLink="/service" routerLinkActive #serviceRoute="routerLinkActive" [activated]="serviceRoute.isActive">
|
||||||
<a mat-list-item (click)="menu.close()" routerLink="/slides"><mat-icon>collections</mat-icon> Slides</a>
|
<mat-icon>list</mat-icon> Service
|
||||||
<a mat-list-item (click)="menu.close()" routerLink="/alerts"><mat-icon>error</mat-icon> Alerts</a>
|
</a>
|
||||||
<a mat-list-item (click)="menu.close()" routerLink="/search"><mat-icon>search</mat-icon> Search</a>
|
<a mat-list-item (click)="menu.close()" routerLink="/slides" routerLinkActive #slidesRoute="routerLinkActive" [activated]="slidesRoute.isActive">
|
||||||
<a mat-list-item (click)="menu.close()" routerLink="/themes"><mat-icon>image</mat-icon> Themes</a>
|
<mat-icon>collections</mat-icon> Slides
|
||||||
|
</a>
|
||||||
|
<a mat-list-item (click)="menu.close()" routerLink="/alerts" routerLinkActive #alertsRoute="routerLinkActive" [activated]="alertsRoute.isActive">
|
||||||
|
<mat-icon>error</mat-icon> Alerts
|
||||||
|
</a>
|
||||||
|
<a mat-list-item (click)="menu.close()" routerLink="/search" routerLinkActive #searchRoute="routerLinkActive" [activated]="searchRoute.isActive">
|
||||||
|
<mat-icon>search</mat-icon> Search
|
||||||
|
</a>
|
||||||
|
<a mat-list-item (click)="menu.close()" routerLink="/themes" routerLinkActive #themesRoute="routerLinkActive" [activated]="themesRoute.isActive">
|
||||||
|
<mat-icon>image</mat-icon> Themes
|
||||||
|
</a>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<a mat-list-item (click)="menu.close()" routerLink="/main">Main View</a>
|
<a mat-list-item (click)="menu.close()" routerLink="/main">Main View</a>
|
||||||
<a mat-list-item (click)="menu.close()" routerLink="/stage">Stage View</a>
|
<a mat-list-item (click)="menu.close()" routerLink="/stage">Stage View</a>
|
||||||
<a mat-list-item (click)="menu.close()" routerLink="/chords">Chord View</a>
|
<a mat-list-item (click)="menu.close()" routerLink="/chords">Chord View</a>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<a mat-list-item (click)="menu.close()" routerLink="/settings"><mat-icon>settings</mat-icon> Settings</a>
|
<a mat-list-item (click)="menu.close()" routerLink="/settings" routerLinkActive #settingsRoute="routerLinkActive" [activated]="settingsRoute.isActive">
|
||||||
|
<mat-icon>settings</mat-icon> Settings
|
||||||
|
</a>
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
</mat-sidenav>
|
</mat-sidenav>
|
||||||
<mat-sidenav-content>
|
<mat-sidenav-content>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<app-stage-view-item [slide]="currentSlides[activeSlide]" [active]="true"></app-stage-view-item>
|
<app-stage-view-item [slide]="currentSlides[activeSlide]" [active]="true"></app-stage-view-item>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<div class="nextSlides">
|
<div class="nextSlides">
|
||||||
<ng-container *ngFor="let slide of nextSlides">
|
<ng-container *ngFor="let slide of nextSlides; trackBy: trackByIndex">
|
||||||
<app-chord-view-item [slide]="slide" *ngIf="slide?.chords; else elseNextSlideNoChords"></app-chord-view-item>
|
<app-chord-view-item [slide]="slide" *ngIf="slide?.chords; else elseNextSlideNoChords"></app-chord-view-item>
|
||||||
<ng-template #elseNextSlideNoChords>
|
<ng-template #elseNextSlideNoChords>
|
||||||
<app-stage-view-item [slide]="slide"></app-stage-view-item>
|
<app-stage-view-item [slide]="slide"></app-stage-view-item>
|
||||||
|
29
src/app/components/no-items.scss
Normal file
29
src/app/components/no-items.scss
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
.no-items {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: gray;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-right: 0.25em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 1em;
|
||||||
|
margin-top: 0.25em;
|
||||||
|
|
||||||
|
button, a {
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 0.813rem;
|
||||||
|
height: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -138,6 +138,7 @@
|
|||||||
|
|
||||||
.back-button {
|
.back-button {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: ($mobile-breakpoint - 0.125px)){
|
@media screen and (max-width: ($mobile-breakpoint - 0.125px)){
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
<ng-container *ngIf="items?.length; else noServiceItems">
|
||||||
<openlp-service-item
|
<openlp-service-item
|
||||||
*ngFor="let item of items"
|
*ngFor="let item of items"
|
||||||
[item]="item"
|
[item]="item"
|
||||||
@ -5,3 +6,18 @@
|
|||||||
(selectItem)="onItemSelected($event)"
|
(selectItem)="onItemSelected($event)"
|
||||||
[tabindex]="item.id"
|
[tabindex]="item.id"
|
||||||
></openlp-service-item>
|
></openlp-service-item>
|
||||||
|
</ng-container>
|
||||||
|
<ng-template #noServiceItems>
|
||||||
|
<div class="no-items" *ngIf="!loading">
|
||||||
|
<div class="no-items-title">
|
||||||
|
<span class="material-icons icon">info</span>
|
||||||
|
No service items.
|
||||||
|
</div>
|
||||||
|
<div class="no-items-actions">
|
||||||
|
<a routerLink="/search" mat-stroked-button color="primary" size="small">
|
||||||
|
<span class="material-icons">add</span>
|
||||||
|
Add Item
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
@ -7,12 +7,13 @@ import { ServiceItem } from '../../../responses';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'openlp-service-list',
|
selector: 'openlp-service-list',
|
||||||
templateUrl: './service-list.component.html',
|
templateUrl: './service-list.component.html',
|
||||||
styleUrls: ['./service-list.component.scss'],
|
styleUrls: ['./service-list.component.scss', '../../no-items.scss'],
|
||||||
})
|
})
|
||||||
|
|
||||||
export class ServiceListComponent implements OnInit, OnDestroy {
|
export class ServiceListComponent implements OnInit, OnDestroy {
|
||||||
items: ServiceItem[] = [];
|
items: ServiceItem[] = [];
|
||||||
_subscription: Subscription;
|
_subscription: Subscription;
|
||||||
|
loading = false;
|
||||||
|
|
||||||
@Output() itemSelected = new EventEmitter<ServiceItem>();
|
@Output() itemSelected = new EventEmitter<ServiceItem>();
|
||||||
|
|
||||||
@ -25,7 +26,11 @@ export class ServiceListComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fetchServiceItems() {
|
fetchServiceItems() {
|
||||||
this.openlpService.getServiceItems().subscribe(items => this.items = items);
|
this.loading = true;
|
||||||
|
this.openlpService.getServiceItems().subscribe(items => {
|
||||||
|
this.items = items;
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private openlpService: OpenLPService) {
|
constructor(private openlpService: OpenLPService) {
|
||||||
|
@ -1 +1,23 @@
|
|||||||
<openlp-slide-item *ngFor="let slide of slides; let index = index" [slide]="slide" [tabindex]="counter" [selected]="slide.selected" (selectSlide)="onSlideSelected($event, index)"></openlp-slide-item>
|
<ng-container *ngIf="slides?.length; else noSlideItems">
|
||||||
|
<openlp-slide-item
|
||||||
|
*ngFor="let slide of slides; let index = index"
|
||||||
|
[slide]="slide"
|
||||||
|
[tabindex]="counter"
|
||||||
|
[selected]="slide.selected"
|
||||||
|
(selectSlide)="onSlideSelected($event, index)"
|
||||||
|
></openlp-slide-item>
|
||||||
|
</ng-container>
|
||||||
|
<ng-template #noSlideItems>
|
||||||
|
<div class="no-items" *ngIf="!loading">
|
||||||
|
<div class="no-items-title">
|
||||||
|
<span class="material-icons icon">info</span>
|
||||||
|
No slide items.
|
||||||
|
</div>
|
||||||
|
<div class="no-items-actions">
|
||||||
|
<a routerLink="/search" mat-stroked-button color="primary" size="small">
|
||||||
|
<span class="material-icons">add</span>
|
||||||
|
Add Item to Service
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
@ -7,13 +7,14 @@ import { OpenLPService } from '../../../openlp.service';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'openlp-slide-list',
|
selector: 'openlp-slide-list',
|
||||||
templateUrl: './slide-list.component.html',
|
templateUrl: './slide-list.component.html',
|
||||||
styleUrls: ['./slide-list.component.scss'],
|
styleUrls: ['./slide-list.component.scss', '../../no-items.scss'],
|
||||||
})
|
})
|
||||||
|
|
||||||
export class SlideListComponent implements OnInit, OnDestroy {
|
export class SlideListComponent implements OnInit, OnDestroy {
|
||||||
slides: Slide[] = null;
|
slides: Slide[] = null;
|
||||||
@Output() slideSelected = new EventEmitter<SlideListItem>();
|
@Output() slideSelected = new EventEmitter<SlideListItem>();
|
||||||
_subscription: Subscription;
|
_subscription: Subscription;
|
||||||
|
loading = false;
|
||||||
|
|
||||||
constructor(private openlpService: OpenLPService) {
|
constructor(private openlpService: OpenLPService) {
|
||||||
this._subscription = openlpService.stateChanged$.subscribe(item => this.fetchSlides());
|
this._subscription = openlpService.stateChanged$.subscribe(item => this.fetchSlides());
|
||||||
@ -32,7 +33,9 @@ export class SlideListComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fetchSlides() {
|
fetchSlides() {
|
||||||
|
this.loading = true;
|
||||||
this.openlpService.getServiceItem().subscribe(serviceItem => {
|
this.openlpService.getServiceItem().subscribe(serviceItem => {
|
||||||
|
this.loading = false;
|
||||||
if (serviceItem instanceof Array) {
|
if (serviceItem instanceof Array) {
|
||||||
this.slides = serviceItem;
|
this.slides = serviceItem;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<app-stage-view-item [slide]="currentSlides[activeSlide]" [active]="true"></app-stage-view-item>
|
<app-stage-view-item [slide]="currentSlides[activeSlide]" [active]="true"></app-stage-view-item>
|
||||||
<div class="nextSlides">
|
<div class="nextSlides">
|
||||||
<app-stage-view-item [slide]="slide" *ngFor="let slide of nextSlides"></app-stage-view-item>
|
<app-stage-view-item [slide]="slide" *ngFor="let slide of nextSlides; trackBy: trackByIndex"></app-stage-view-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,6 +41,8 @@ export class StageViewComponent implements OnInit, OnDestroy {
|
|||||||
setInterval(() => this.time = new Date(), 1000);
|
setInterval(() => this.time = new Date(), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nextSlides: Slide[] = [];
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.updateCurrentSlides(null, null);
|
this.updateCurrentSlides(null, null);
|
||||||
this.openlpService.stateChanged$.subscribe(item => this.updateCurrentSlides(item.item, item.slide));
|
this.openlpService.stateChanged$.subscribe(item => this.updateCurrentSlides(item.item, item.slide));
|
||||||
@ -74,16 +76,13 @@ export class StageViewComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get nextSlides(): Slide[] {
|
|
||||||
return this.currentSlides.slice(this.activeSlide + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
setNewSlides(slides: Slide[], currentSlide: number): void {
|
setNewSlides(slides: Slide[], currentSlide: number): void {
|
||||||
if (slides.length === 0) {
|
if (slides.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.currentSlides = slides;
|
this.currentSlides = slides;
|
||||||
this.activeSlide = slides.findIndex(s => s.selected);
|
this.activeSlide = slides.findIndex(s => s.selected);
|
||||||
|
this.nextSlides = this.currentSlides.slice(this.activeSlide + 1);
|
||||||
this.updateTags();
|
this.updateTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,4 +128,8 @@ export class StageViewComponent implements OnInit, OnDestroy {
|
|||||||
lastIndex = index;
|
lastIndex = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trackByIndex(index: number, el: any) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,25 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
@use '@angular/material' as mat;
|
||||||
@import '@angular/material/theming';
|
@import '@angular/material/theming';
|
||||||
|
|
||||||
@include mat-core();
|
@include mat.core();
|
||||||
$primary: mat-palette($mat-indigo);
|
$olp-primary: mat.define-palette(mat.$indigo-palette, 500);
|
||||||
$accent: mat-palette($mat-light-blue, A200, A100, A400);
|
$olp-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
|
||||||
$theme: mat-light-theme($primary, $accent);
|
|
||||||
@include angular-material-theme($theme);
|
// The "warn" palette is optional and defaults to red if not specified.
|
||||||
|
$olp-warn: mat.define-palette(mat.$red-palette);
|
||||||
|
|
||||||
|
$olp-theme: mat.define-light-theme((
|
||||||
|
color: (
|
||||||
|
primary: $olp-primary,
|
||||||
|
accent: $olp-accent,
|
||||||
|
warn: $olp-warn,
|
||||||
|
),
|
||||||
|
density: 0,
|
||||||
|
));
|
||||||
|
|
||||||
|
// Including only used components
|
||||||
|
@include mat.all-component-themes($olp-theme);
|
||||||
|
|
||||||
* {
|
* {
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
@ -111,3 +125,13 @@ footer {
|
|||||||
footer {
|
footer {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This rule is to avoid the left menu scrolling with the page itself.
|
||||||
|
.mat-drawer.mat-sidenav {
|
||||||
|
position: fixed;
|
||||||
|
padding-top: $mat-toolbar-height-desktop;
|
||||||
|
|
||||||
|
@media ($mat-xsmall) {
|
||||||
|
padding-top: $mat-toolbar-height-mobile;
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,8 @@
|
|||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"target": "es5",
|
"target": "es2022",
|
||||||
|
"useDefineForClassFields": false,
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"node_modules/@types"
|
"node_modules/@types"
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user