Merge pull request #4585 from FinnStutzenstein/projectorListCleanup
Put projector cards in own components in the listview
This commit is contained in:
commit
e7624c0d1e
@ -0,0 +1,113 @@
|
||||
<os-meta-text-block showActionRow="false" *ngIf="projector">
|
||||
<ng-container class="meta-text-block-title">
|
||||
{{ projector.getTitle() | translate }}
|
||||
</ng-container>
|
||||
<ng-container class="meta-text-block-action-row" *ngIf="canManage">
|
||||
<button mat-icon-button *ngIf="!isEditing" (click)="onEditButton()">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button *ngIf="isEditing" (click)="onCancelButton()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button *ngIf="isEditing" (click)="onSaveButton()">
|
||||
<mat-icon>save</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="onDeleteButton()">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-container class="meta-text-block-content">
|
||||
<a class="no-markup" [routerLink]="['/projectors/detail', projector.id]">
|
||||
<div class="projector">
|
||||
<os-projector [projector]="projector"></os-projector>
|
||||
</div>
|
||||
</a>
|
||||
<ng-container *ngIf="isEditing">
|
||||
<form [formGroup]="updateForm" (keydown)="keyDownFunction($event, projector)">
|
||||
<!-- Name field -->
|
||||
<mat-form-field>
|
||||
<input formControlName="name" matInput placeholder="{{ 'Name' | translate }}" required />
|
||||
<mat-hint *ngIf="!updateForm.controls.name.valid">
|
||||
<span translate>Required</span>
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<h3 translate>Resolution and size</h3>
|
||||
<!-- Aspect ratio field -->
|
||||
<mat-radio-group formControlName="aspectRatio" [name]="projector.id">
|
||||
<mat-radio-button *ngFor="let ratio of aspectRatiosKeys" [value]="ratio">
|
||||
{{ ratio }}
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<mat-slider
|
||||
[thumbLabel]="true"
|
||||
min="800"
|
||||
max="3840"
|
||||
step="10"
|
||||
(change)="widthSliderValueChanged($event)"
|
||||
></mat-slider>
|
||||
{{ updateForm.value.width }}
|
||||
|
||||
<!-- projection defaults -->
|
||||
<h3 translate>Projection defaults</h3>
|
||||
<mat-select formControlName="projectiondefaults_id" placeholder="{{ 'Projection defaults' | translate }}" [multiple]="true">
|
||||
<mat-option *ngFor="let pd of projectionDefaults" [value]="pd.id">
|
||||
{{ pd.getTitle() | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
|
||||
<!-- colors -->
|
||||
<mat-form-field>
|
||||
<span translate>Background color</span>
|
||||
<input matInput formControlName="background_color" type="color" />
|
||||
<mat-hint *ngIf="!updateForm.controls.background_color.valid">
|
||||
<span translate>Required</span>
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<span translate>Header background color</span>
|
||||
<input matInput formControlName="header_background_color" type="color" />
|
||||
<mat-hint *ngIf="!updateForm.controls.header_background_color.valid">
|
||||
<span translate>Required</span>
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<span translate>Header font color</span>
|
||||
<input matInput formControlName="header_font_color" type="color" />
|
||||
<mat-hint *ngIf="!updateForm.controls.header_font_color.valid">
|
||||
<span translate>Required</span>
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<span translate>Headline color</span>
|
||||
<input matInput formControlName="header_h1_color" type="color" />
|
||||
<mat-hint *ngIf="!updateForm.controls.header_h1_color.valid">
|
||||
<span translate>Required</span>
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- checkboxes -->
|
||||
<div>
|
||||
<mat-checkbox formControlName="show_header_footer">
|
||||
<span translate>Show header and footer</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<mat-checkbox formControlName="show_title">
|
||||
<span translate>Show title</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<mat-checkbox formControlName="show_logo">
|
||||
<span translate>Show logo</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<mat-checkbox formControlName="clock">
|
||||
<span translate>Show clock</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</form>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</os-meta-text-block>
|
@ -0,0 +1,19 @@
|
||||
.projector {
|
||||
width: 320px;
|
||||
color: black;
|
||||
border: 1px solid lightgrey;
|
||||
}
|
||||
|
||||
form {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
::ng-deep mat-card {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.no-markup {
|
||||
/* Do not let the a tag ruin the projector */
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { E2EImportsModule } from '../../../../../e2e-imports.module';
|
||||
import { ProjectorModule } from '../../projector.module';
|
||||
import { ProjectorListEntryComponent } from './projector-list-entry.component';
|
||||
|
||||
describe('ProjectorListEntryComponent', () => {
|
||||
let component: ProjectorListEntryComponent;
|
||||
let fixture: ComponentFixture<ProjectorListEntryComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [E2EImportsModule, ProjectorModule]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ProjectorListEntryComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,229 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { MatSnackBar, MatSliderChange } from '@angular/material';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service';
|
||||
import { ViewProjector } from '../../models/view-projector';
|
||||
import { Projector } from 'app/shared/models/core/projector';
|
||||
import { BaseViewComponent } from 'app/site/base/base-view';
|
||||
import { PromptService } from 'app/core/ui-services/prompt.service';
|
||||
import { ClockSlideService } from '../../services/clock-slide.service';
|
||||
import { OperatorService } from 'app/core/core-services/operator.service';
|
||||
import { ViewProjectionDefault } from '../../models/view-projection-default';
|
||||
import { ProjectionDefaultRepositoryService } from 'app/core/repositories/projector/projection-default-repository.service';
|
||||
|
||||
/**
|
||||
* All supported aspect rations for projectors.
|
||||
*/
|
||||
const aspectRatios: { [ratio: string]: number } = {
|
||||
'4:3': 4 / 3,
|
||||
'16:9': 16 / 9,
|
||||
'16:10': 16 / 10
|
||||
};
|
||||
|
||||
/**
|
||||
* List for all projectors.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'os-projector-list-entry',
|
||||
templateUrl: './projector-list-entry.component.html',
|
||||
styleUrls: ['./projector-list-entry.component.scss']
|
||||
})
|
||||
export class ProjectorListEntryComponent extends BaseViewComponent implements OnInit {
|
||||
/**
|
||||
* The update form. Will be refreahed for each projector. Just one update
|
||||
* form can be shown per time.
|
||||
*/
|
||||
public updateForm: FormGroup;
|
||||
|
||||
/**
|
||||
* Saves, if this projector currently is edited.
|
||||
*/
|
||||
public isEditing = false;
|
||||
|
||||
/**
|
||||
* All ProjectionDefaults to select from.
|
||||
*/
|
||||
public projectionDefaults: ViewProjectionDefault[];
|
||||
|
||||
/**
|
||||
* All aspect ratio keys/strings for the UI.
|
||||
*/
|
||||
public aspectRatiosKeys: string[];
|
||||
|
||||
/**
|
||||
* The projector shown by this entry.
|
||||
*/
|
||||
@Input()
|
||||
public projector: ViewProjector;
|
||||
|
||||
/**
|
||||
* Helper to check manage permissions
|
||||
*
|
||||
* @returns true if the user can manage projectors
|
||||
*/
|
||||
public get canManage(): boolean {
|
||||
return this.operator.hasPerms('core.can_manage_projector');
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Initializes the update form.
|
||||
*
|
||||
* @param titleService
|
||||
* @param translate
|
||||
* @param matSnackBar
|
||||
* @param repo
|
||||
* @param formBuilder
|
||||
* @param promptService
|
||||
* @param clockSlideService
|
||||
* @param operator OperatorService
|
||||
*/
|
||||
public constructor(
|
||||
titleService: Title,
|
||||
protected translate: TranslateService, // protected required for ng-translate-extract
|
||||
matSnackBar: MatSnackBar,
|
||||
private repo: ProjectorRepositoryService,
|
||||
private formBuilder: FormBuilder,
|
||||
private promptService: PromptService,
|
||||
private clockSlideService: ClockSlideService,
|
||||
private operator: OperatorService,
|
||||
private projectionDefaultRepo: ProjectionDefaultRepositoryService
|
||||
) {
|
||||
super(titleService, translate, matSnackBar);
|
||||
|
||||
this.aspectRatiosKeys = Object.keys(aspectRatios);
|
||||
|
||||
this.updateForm = this.formBuilder.group({
|
||||
name: ['', Validators.required],
|
||||
aspectRatio: ['', Validators.required],
|
||||
width: [0, Validators.required],
|
||||
projectiondefaults_id: [[]],
|
||||
clock: [true],
|
||||
background_color: ['', Validators.required],
|
||||
header_background_color: ['', Validators.required],
|
||||
header_font_color: ['', Validators.required],
|
||||
header_h1_color: ['', Validators.required],
|
||||
show_header_footer: [],
|
||||
show_title: [],
|
||||
show_logo: []
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Watches all projectiondefaults.
|
||||
*/
|
||||
public ngOnInit(): void {
|
||||
this.projectionDefaults = this.projectionDefaultRepo.getViewModelList();
|
||||
this.subscriptions.push(
|
||||
this.projectionDefaultRepo.getViewModelListObservable().subscribe(pds => (this.projectionDefaults = pds))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Event on Key Down in update form.
|
||||
*
|
||||
* @param event the keyboard event
|
||||
* @param the current view in scope
|
||||
*/
|
||||
public keyDownFunction(event: KeyboardEvent): void {
|
||||
if (event.key === 'Enter') {
|
||||
this.onSaveButton();
|
||||
}
|
||||
if (event.key === 'Escape') {
|
||||
this.onCancelButton();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the aspect ratio of the given projector.
|
||||
* If no matching ratio is found, the first ratio is returned.
|
||||
*
|
||||
* @param projector The projector to check
|
||||
* @returns the found ratio key.
|
||||
*/
|
||||
public getAspectRatioKey(): string {
|
||||
const ratio = this.projector.width / this.projector.height;
|
||||
const RATIO_ENVIRONMENT = 0.05;
|
||||
const foundRatioKey = Object.keys(aspectRatios).find(key => {
|
||||
const value = aspectRatios[key];
|
||||
return value >= ratio - RATIO_ENVIRONMENT && value <= ratio + RATIO_ENVIRONMENT;
|
||||
});
|
||||
if (!foundRatioKey) {
|
||||
return Object.keys(aspectRatios)[0];
|
||||
} else {
|
||||
return foundRatioKey;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts editing for the given projector.
|
||||
*/
|
||||
public onEditButton(): void {
|
||||
if (this.isEditing) {
|
||||
return;
|
||||
}
|
||||
this.isEditing = true;
|
||||
this.updateForm.reset();
|
||||
|
||||
this.updateForm.patchValue(this.projector.projector);
|
||||
this.updateForm.patchValue({
|
||||
name: this.translate.instant(this.projector.name),
|
||||
aspectRatio: this.getAspectRatioKey(),
|
||||
clock: this.clockSlideService.isProjectedOn(this.projector)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the current editing.
|
||||
*/
|
||||
public onCancelButton(): void {
|
||||
this.isEditing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the projector
|
||||
*
|
||||
* @param projector The projector to save.
|
||||
*/
|
||||
public async onSaveButton(): Promise<void> {
|
||||
const updateProjector: Partial<Projector> = this.updateForm.value;
|
||||
updateProjector.height = Math.round(
|
||||
this.updateForm.value.width / aspectRatios[this.updateForm.value.aspectRatio]
|
||||
);
|
||||
|
||||
try {
|
||||
await this.clockSlideService.setProjectedOn(this.projector, this.updateForm.value.clock);
|
||||
await this.repo.update(updateProjector, this.projector);
|
||||
this.isEditing = false;
|
||||
} catch (e) {
|
||||
this.raiseError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the projector.
|
||||
*/
|
||||
public async onDeleteButton(): Promise<void> {
|
||||
const title = this.translate.instant('Are you sure you want to delete this projector?');
|
||||
if (await this.promptService.open(title, this.projector.name)) {
|
||||
this.repo.delete(this.projector).then(null, this.raiseError);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Eventhandler for slider changes. Directly saves the new aspect ratio.
|
||||
*
|
||||
* @param event The slider value
|
||||
*/
|
||||
public widthSliderValueChanged(event: MatSliderChange): void {
|
||||
const aspectRatio = this.getAspectRatioKey();
|
||||
const updateProjector: Partial<Projector> = {
|
||||
width: event.value
|
||||
};
|
||||
updateProjector.height = Math.round(event.value / aspectRatios[aspectRatio]);
|
||||
this.repo.update(updateProjector, this.projector).then(null, this.raiseError);
|
||||
}
|
||||
}
|
@ -45,120 +45,7 @@
|
||||
</mat-card>
|
||||
|
||||
<div id="card-wrapper">
|
||||
<div class="projector-card" *ngFor="let projector of projectors">
|
||||
<os-meta-text-block showActionRow="false">
|
||||
<ng-container class="meta-text-block-title">
|
||||
{{ projector.name | translate }}
|
||||
</ng-container>
|
||||
<ng-container class="meta-text-block-action-row" *ngIf="canManage">
|
||||
<button mat-icon-button *ngIf="editId !== projector.id" (click)="onEditButton(projector)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button *ngIf="editId === projector.id" (click)="onCancelButton(projector)">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button *ngIf="editId === projector.id" (click)="onSaveButton(projector)">
|
||||
<mat-icon>save</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="onDeleteButton(projector)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-container class="meta-text-block-content">
|
||||
<a class="no-markup" [routerLink]="['/projectors/detail', projector.id]">
|
||||
<div class="projector">
|
||||
<os-projector [projector]="projector"></os-projector>
|
||||
</div>
|
||||
</a>
|
||||
<ng-container *ngIf="editId === projector.id">
|
||||
<form [formGroup]="updateForm" (keydown)="keyDownFunction($event, projector)">
|
||||
<!-- Name field -->
|
||||
<mat-form-field>
|
||||
<input formControlName="name" matInput placeholder="{{ 'Name' | translate }}" required />
|
||||
<mat-hint *ngIf="!updateForm.controls.name.valid">
|
||||
<span translate>Required</span>
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<h3 translate>Resolution and size</h3>
|
||||
<!-- Aspect ratio field -->
|
||||
<mat-radio-group formControlName="aspectRatio" [name]="projector.id">
|
||||
<mat-radio-button *ngFor="let ratio of aspectRatiosKeys" [value]="ratio">
|
||||
{{ ratio }}
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<mat-slider
|
||||
[thumbLabel]="true"
|
||||
formControlName="width"
|
||||
min="800"
|
||||
max="3840"
|
||||
step="10"
|
||||
(change)="widthSliderValueChanged(projector, $event)"
|
||||
></mat-slider>
|
||||
{{ updateForm.value.width }}
|
||||
|
||||
<!-- projection defaults -->
|
||||
<h3 translate>Projection defaults</h3>
|
||||
<mat-select formControlName="projectiondefaults_id" placeholder="{{ 'Projection defaults' | translate }}" [multiple]="true">
|
||||
<mat-option *ngFor="let pd of projectionDefaults" [value]="pd.id">
|
||||
{{ pd.getTitle() | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
|
||||
<!-- colors -->
|
||||
<mat-form-field>
|
||||
<span translate>Background color</span>
|
||||
<input matInput formControlName="background_color" type="color" />
|
||||
<mat-hint *ngIf="!updateForm.controls.background_color.valid">
|
||||
<span translate>Required</span>
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<span translate>Header background color</span>
|
||||
<input matInput formControlName="header_background_color" type="color" />
|
||||
<mat-hint *ngIf="!updateForm.controls.header_background_color.valid">
|
||||
<span translate>Required</span>
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<span translate>Header font color</span>
|
||||
<input matInput formControlName="header_font_color" type="color" />
|
||||
<mat-hint *ngIf="!updateForm.controls.header_font_color.valid">
|
||||
<span translate>Required</span>
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<span translate>Headline color</span>
|
||||
<input matInput formControlName="header_h1_color" type="color" />
|
||||
<mat-hint *ngIf="!updateForm.controls.header_h1_color.valid">
|
||||
<span translate>Required</span>
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- checkboxes -->
|
||||
<div>
|
||||
<mat-checkbox formControlName="show_header_footer">
|
||||
<span translate>Show header and footer</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<mat-checkbox formControlName="show_title">
|
||||
<span translate>Show title</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<mat-checkbox formControlName="show_logo">
|
||||
<span translate>Show logo</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<mat-checkbox formControlName="clock">
|
||||
<span translate>Show clock</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</form>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</os-meta-text-block>
|
||||
<div class="projector-card" *ngFor="let projector of projectors; trackBy: trackByIndex">
|
||||
<os-projector-list-entry [projector]="projector"></os-projector-list-entry>
|
||||
</div>
|
||||
</div>
|
@ -6,25 +6,5 @@
|
||||
width: 350px;
|
||||
margin: 10px;
|
||||
float: left;
|
||||
|
||||
.projector {
|
||||
width: 320px;
|
||||
color: black;
|
||||
border: 1px solid lightgrey;
|
||||
}
|
||||
|
||||
form {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
::ng-deep mat-card {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.no-markup {
|
||||
/* Do not let the a tag ruin the projector */
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { MatSnackBar, MatSelectChange, MatSliderChange } from '@angular/material';
|
||||
import { MatSnackBar, MatSelectChange } from '@angular/material';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@ -9,20 +9,7 @@ import { ProjectorRepositoryService } from 'app/core/repositories/projector/proj
|
||||
import { ViewProjector } from '../../models/view-projector';
|
||||
import { Projector } from 'app/shared/models/core/projector';
|
||||
import { BaseViewComponent } from 'app/site/base/base-view';
|
||||
import { PromptService } from 'app/core/ui-services/prompt.service';
|
||||
import { ClockSlideService } from '../../services/clock-slide.service';
|
||||
import { OperatorService } from 'app/core/core-services/operator.service';
|
||||
import { ProjectionDefaultRepositoryService } from 'app/core/repositories/projector/projection-default-repository.service';
|
||||
import { ViewProjectionDefault } from '../../models/view-projection-default';
|
||||
|
||||
/**
|
||||
* All supported aspect rations for projectors.
|
||||
*/
|
||||
const aspectRatios: { [ratio: string]: number } = {
|
||||
'4:3': 4 / 3,
|
||||
'16:9': 16 / 9,
|
||||
'16:10': 16 / 10
|
||||
};
|
||||
|
||||
/**
|
||||
* List for all projectors.
|
||||
@ -43,17 +30,6 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit
|
||||
*/
|
||||
public createForm: FormGroup;
|
||||
|
||||
/**
|
||||
* The update form. Will be refreahed for each projector. Just one update
|
||||
* form can be shown per time.
|
||||
*/
|
||||
public updateForm: FormGroup;
|
||||
|
||||
/**
|
||||
* The id of the currently edited projector.
|
||||
*/
|
||||
public editId: number | null = null;
|
||||
|
||||
/**
|
||||
* All aspect ratio keys/strings for the UI.
|
||||
*/
|
||||
@ -64,8 +40,6 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit
|
||||
*/
|
||||
public projectors: ViewProjector[];
|
||||
|
||||
public projectionDefaults: ViewProjectionDefault[];
|
||||
|
||||
/**
|
||||
* Helper to check manage permissions
|
||||
*
|
||||
@ -93,32 +67,13 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit
|
||||
matSnackBar: MatSnackBar,
|
||||
private repo: ProjectorRepositoryService,
|
||||
private formBuilder: FormBuilder,
|
||||
private promptService: PromptService,
|
||||
private clockSlideService: ClockSlideService,
|
||||
private operator: OperatorService,
|
||||
private projectionDefaultRepo: ProjectionDefaultRepositoryService
|
||||
private operator: OperatorService
|
||||
) {
|
||||
super(titleService, translate, matSnackBar);
|
||||
|
||||
this.aspectRatiosKeys = Object.keys(aspectRatios);
|
||||
|
||||
this.createForm = this.formBuilder.group({
|
||||
name: ['', Validators.required]
|
||||
});
|
||||
this.updateForm = this.formBuilder.group({
|
||||
name: ['', Validators.required],
|
||||
aspectRatio: ['', Validators.required],
|
||||
width: [0, Validators.required],
|
||||
projectiondefaults_id: [[]],
|
||||
clock: [true],
|
||||
background_color: ['', Validators.required],
|
||||
header_background_color: ['', Validators.required],
|
||||
header_font_color: ['', Validators.required],
|
||||
header_h1_color: ['', Validators.required],
|
||||
show_header_footer: [],
|
||||
show_title: [],
|
||||
show_logo: []
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,8 +83,6 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit
|
||||
super.setTitle('Projectors');
|
||||
this.projectors = this.repo.getViewModelList();
|
||||
this.repo.getViewModelListObservable().subscribe(projectors => (this.projectors = projectors));
|
||||
this.projectionDefaults = this.projectionDefaultRepo.getViewModelList();
|
||||
this.projectionDefaultRepo.getViewModelListObservable().subscribe(pds => (this.projectionDefaults = pds));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,112 +112,15 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit
|
||||
* Event on Key Down in update or create form.
|
||||
*
|
||||
* @param event the keyboard event
|
||||
* @param the current view in scope
|
||||
*/
|
||||
public keyDownFunction(event: KeyboardEvent, projector?: ViewProjector): void {
|
||||
if (event.key === 'Enter' && event.shiftKey) {
|
||||
if (projector) {
|
||||
this.onSaveButton(projector);
|
||||
} else {
|
||||
public keyDownFunction(event: KeyboardEvent): void {
|
||||
if (event.key === 'Enter') {
|
||||
this.create();
|
||||
}
|
||||
}
|
||||
if (event.key === 'Escape') {
|
||||
if (projector) {
|
||||
this.onCancelButton(projector);
|
||||
} else {
|
||||
this.projectorToCreate = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the aspect ratio of the given projector.
|
||||
* If no matching ratio is found, the first ratio is returned.
|
||||
*
|
||||
* @param projector The projector to check
|
||||
* @returns the found ratio key.
|
||||
*/
|
||||
public getAspectRatioKey(projector: ViewProjector): string {
|
||||
const ratio = projector.width / projector.height;
|
||||
const RATIO_ENVIRONMENT = 0.05;
|
||||
const foundRatioKey = Object.keys(aspectRatios).find(key => {
|
||||
const value = aspectRatios[key];
|
||||
return value >= ratio - RATIO_ENVIRONMENT && value <= ratio + RATIO_ENVIRONMENT;
|
||||
});
|
||||
if (!foundRatioKey) {
|
||||
return Object.keys(aspectRatios)[0];
|
||||
} else {
|
||||
return foundRatioKey;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts editing for the given projector.
|
||||
*
|
||||
* @param projector The projector to edit
|
||||
*/
|
||||
public onEditButton(projector: ViewProjector): void {
|
||||
if (this.editId !== null) {
|
||||
return;
|
||||
}
|
||||
this.editId = projector.id;
|
||||
this.updateForm.reset();
|
||||
|
||||
this.updateForm.patchValue(projector.projector);
|
||||
this.updateForm.patchValue({
|
||||
name: this.translate.instant(projector.name),
|
||||
aspectRatio: this.getAspectRatioKey(projector),
|
||||
clock: this.clockSlideService.isProjectedOn(projector)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the current editing.
|
||||
* @param projector the projector
|
||||
*/
|
||||
public onCancelButton(projector: ViewProjector): void {
|
||||
if (projector.id !== this.editId) {
|
||||
return;
|
||||
}
|
||||
this.editId = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the projector
|
||||
*
|
||||
* @param projector The projector to save.
|
||||
*/
|
||||
public async onSaveButton(projector: ViewProjector): Promise<void> {
|
||||
if (projector.id !== this.editId || !this.updateForm.valid) {
|
||||
return;
|
||||
}
|
||||
const updateProjector: Partial<Projector> = this.updateForm.value;
|
||||
updateProjector.height = Math.round(
|
||||
this.updateForm.value.width / aspectRatios[this.updateForm.value.aspectRatio]
|
||||
);
|
||||
|
||||
try {
|
||||
await this.clockSlideService.setProjectedOn(projector, this.updateForm.value.clock);
|
||||
await this.repo.update(updateProjector, projector);
|
||||
this.editId = null;
|
||||
} catch (e) {
|
||||
this.raiseError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the projector.
|
||||
*
|
||||
* @param projector The projector to delete
|
||||
*/
|
||||
public async onDeleteButton(projector: ViewProjector): Promise<void> {
|
||||
const title = this.translate.instant('Are you sure you want to delete this projector?');
|
||||
const content = projector.name;
|
||||
if (await this.promptService.open(title, content)) {
|
||||
this.repo.delete(projector).then(null, this.raiseError);
|
||||
}
|
||||
}
|
||||
|
||||
public onSelectReferenceProjector(change: MatSelectChange): void {
|
||||
const update: Partial<Projector> = {
|
||||
@ -275,13 +131,4 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit
|
||||
});
|
||||
Promise.all(promises).then(null, this.raiseError);
|
||||
}
|
||||
|
||||
public widthSliderValueChanged(projector: ViewProjector, event: MatSliderChange): void {
|
||||
const aspectRatio = this.getAspectRatioKey(projector);
|
||||
const updateProjector: Partial<Projector> = {
|
||||
width: event.value
|
||||
};
|
||||
updateProjector.height = Math.round(event.value / aspectRatios[aspectRatio]);
|
||||
this.repo.update(updateProjector, projector).then(null, this.raiseError);
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,13 @@ import { CountdownControlsComponent } from './components/countdown-controls/coun
|
||||
import { CountdownDialogComponent } from './components/countdown-dialog/countdown-dialog.component';
|
||||
import { MessageControlsComponent } from './components/message-controls/message-controls.component';
|
||||
import { MessageDialogComponent } from './components/message-dialog/message-dialog.component';
|
||||
import { ProjectorListEntryComponent } from './components/projector-list-entry/projector-list-entry.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, ProjectorRoutingModule, SharedModule],
|
||||
declarations: [
|
||||
ProjectorListComponent,
|
||||
ProjectorListEntryComponent,
|
||||
ProjectorDetailComponent,
|
||||
CountdownControlsComponent,
|
||||
CountdownDialogComponent,
|
||||
|
Loading…
Reference in New Issue
Block a user