Add change signals for the listview

The projector-button now emits a signal if changed
List-of-speaker-button is now able to detect it's own updates
This commit is contained in:
Sean Engelhardt 2019-08-22 14:01:17 +02:00
parent b80ac3ac68
commit 0f606b5a7e
5 changed files with 100 additions and 18 deletions

View File

@ -33,7 +33,7 @@
<!-- Projector column --> <!-- Projector column -->
<div *pblNgridCellDef="'projector'; row as viewModel" class="fill ngrid-lg"> <div *pblNgridCellDef="'projector'; row as viewModel" class="fill ngrid-lg">
<os-projector-button class="projector-button" [object]="getProjectable(viewModel)"></os-projector-button> <os-projector-button class="projector-button" [object]="getProjectable(viewModel)" (changeEvent)="viewUpdateEvent()"></os-projector-button>
</div> </div>
<!-- No Results --> <!-- No Results -->

View File

@ -394,6 +394,13 @@ export class ListViewTableComponent<V extends BaseViewModel, M extends BaseModel
} }
} }
/**
* Receive manual view updates
*/
public viewUpdateEvent(): void {
this.cd.markForCheck();
}
/** /**
* Generic click handler for rows. Allow so (multi) select anywhere * Generic click handler for rows. Allow so (multi) select anywhere
* @param event the clicked row * @param event the clicked row

View File

@ -1,16 +1,31 @@
<ng-container *osPerms="'core.can_manage_projector'"> <ng-container *osPerms="'core.can_manage_projector'">
<button type="button" *ngIf="!text && !menuItem" mat-mini-fab (click)="onClick($event)" <button
[ngClass]="isProjected() ? 'projector-active' : 'projector-inactive'"> type="button"
*ngIf="!text && !menuItem"
mat-mini-fab
(click)="onClick($event)"
[ngClass]="isProjected ? 'projector-active' : 'projector-inactive'"
>
<mat-icon>videocam</mat-icon> <mat-icon>videocam</mat-icon>
</button> </button>
<button type="button" *ngIf="text && !menuItem" mat-button (click)="onClick($event)" <button
[ngClass]="isProjected() ? 'projector-active' : 'projector-inactive'"> type="button"
*ngIf="text && !menuItem"
mat-button
(click)="onClick($event)"
[ngClass]="isProjected ? 'projector-active' : 'projector-inactive'"
>
<mat-icon>videocam</mat-icon> <mat-icon>videocam</mat-icon>
{{ text | translate }} {{ text | translate }}
</button> </button>
<button type="button" *ngIf="menuItem" mat-menu-item (click)="onClick()" <button
[ngClass]="isProjected() ? 'projector-active' : 'projector-inactive'"> type="button"
*ngIf="menuItem"
mat-menu-item
(click)="onClick()"
[ngClass]="isProjected ? 'projector-active' : 'projector-inactive'"
>
<mat-icon>videocam</mat-icon> <mat-icon>videocam</mat-icon>
{{ (text || 'Project') | translate }} {{ text || 'Project' | translate }}
</button> </button>
</ng-container> </ng-container>

View File

@ -1,6 +1,10 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { Subscription } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { ProjectorService } from 'app/core/core-services/projector.service'; import { ProjectorService } from 'app/core/core-services/projector.service';
import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service';
import { ProjectionDialogService } from 'app/core/ui-services/projection-dialog.service'; import { ProjectionDialogService } from 'app/core/ui-services/projection-dialog.service';
import { Projector } from 'app/shared/models/core/projector'; import { Projector } from 'app/shared/models/core/projector';
import { import {
@ -23,7 +27,7 @@ import {
templateUrl: './projector-button.component.html', templateUrl: './projector-button.component.html',
styleUrls: ['./projector-button.component.scss'] styleUrls: ['./projector-button.component.scss']
}) })
export class ProjectorButtonComponent implements OnInit { export class ProjectorButtonComponent implements OnInit, OnDestroy {
/** /**
* The object to project. * The object to project.
*/ */
@ -33,6 +37,8 @@ export class ProjectorButtonComponent implements OnInit {
return this._object; return this._object;
} }
public isProjected = false;
@Input() @Input()
public set object(obj: Projectable | ProjectorElementBuildDeskriptor) { public set object(obj: Projectable | ProjectorElementBuildDeskriptor) {
if (isProjectable(obj) || isProjectorElementBuildDeskriptor(obj)) { if (isProjectable(obj) || isProjectorElementBuildDeskriptor(obj)) {
@ -48,16 +54,22 @@ export class ProjectorButtonComponent implements OnInit {
@Input() @Input()
public menuItem = false; public menuItem = false;
@Output()
public changeEvent: EventEmitter<void> = new EventEmitter();
/** /**
* Pre-define projection target * Pre-define projection target
*/ */
@Input() @Input()
public projector: Projector | null; public projector: Projector | null;
private projectorRepoSub: Subscription;
/** /**
* The constructor * The constructor
*/ */
public constructor( public constructor(
private projectorRepo: ProjectorRepositoryService,
private projectionDialogService: ProjectionDialogService, private projectionDialogService: ProjectionDialogService,
private projectorService: ProjectorService private projectorService: ProjectorService
) {} ) {}
@ -65,7 +77,27 @@ export class ProjectorButtonComponent implements OnInit {
/** /**
* Initialization function * Initialization function
*/ */
public ngOnInit(): void {} public ngOnInit(): void {
this.isProjected = this.checkIsProjected();
this.projectorRepoSub = this.projectorRepo
.getGeneralViewModelObservable()
.pipe(distinctUntilChanged())
.subscribe(() => {
const isProjected = this.checkIsProjected();
if (this.isProjected !== isProjected) {
this.isProjected = isProjected;
this.changeEvent.next();
}
});
}
public ngOnDestroy(): void {
if (this.projectorRepoSub) {
this.projectorRepoSub.unsubscribe();
this.projectorRepoSub = null;
}
}
/** /**
* Click on the projector button * Click on the projector button
@ -79,7 +111,7 @@ export class ProjectorButtonComponent implements OnInit {
if (this.object) { if (this.object) {
if (this.projector) { if (this.projector) {
// if the projection target was defines before // if the projection target was defines before
if (this.isProjected()) { if (this.checkIsProjected()) {
// remove the projected object // remove the projected object
this.projectorService.removeFrom(this.projector, this.object); this.projectorService.removeFrom(this.projector, this.object);
} else { } else {
@ -98,7 +130,7 @@ export class ProjectorButtonComponent implements OnInit {
* *
* @returns true, if the object is projected on one projector. * @returns true, if the object is projected on one projector.
*/ */
public isProjected(): boolean { public checkIsProjected(): boolean {
if (!this.object) { if (!this.object) {
return false; return false;
} }

View File

@ -1,4 +1,7 @@
import { Component, Input } from '@angular/core'; import { Component, Input, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { ListOfSpeakersRepositoryService } from 'app/core/repositories/agenda/list-of-speakers-repository.service'; import { ListOfSpeakersRepositoryService } from 'app/core/repositories/agenda/list-of-speakers-repository.service';
import { ContentObject, isContentObject } from 'app/shared/models/base/content-object'; import { ContentObject, isContentObject } from 'app/shared/models/base/content-object';
@ -18,15 +21,27 @@ import {
selector: 'os-speaker-button', selector: 'os-speaker-button',
templateUrl: './speaker-button.component.html' templateUrl: './speaker-button.component.html'
}) })
export class SpeakerButtonComponent { export class SpeakerButtonComponent implements OnDestroy {
@Input() @Input()
public set object(obj: BaseViewModelWithListOfSpeakers | ContentObject | null) { public set object(obj: BaseViewModelWithListOfSpeakers | ContentObject | null) {
let listOfSpeakers: ViewListOfSpeakers;
if (isBaseViewModelWithListOfSpeakers(obj)) { if (isBaseViewModelWithListOfSpeakers(obj)) {
this.listOfSpeakers = obj.listOfSpeakers; listOfSpeakers = obj.listOfSpeakers;
} else if (isContentObject(obj)) { } else if (isContentObject(obj)) {
this.listOfSpeakers = this.listOfSpeakersRepo.findByContentObject(obj); listOfSpeakers = this.listOfSpeakersRepo.findByContentObject(obj);
} else { } else {
this.listOfSpeakers = null; listOfSpeakers = null;
}
this.cleanLosSub();
if (!!listOfSpeakers) {
this.losSub = this.listOfSpeakersRepo
.getViewModelObservable(listOfSpeakers.id)
.pipe(distinctUntilChanged())
.subscribe(speakerObj => {
this.listOfSpeakers = speakerObj;
});
} }
} }
@ -52,8 +67,21 @@ export class SpeakerButtonComponent {
return this.listOfSpeakers.closed ? 'The list of speakers is closed.' : 'List of speakers'; return this.listOfSpeakers.closed ? 'The list of speakers is closed.' : 'List of speakers';
} }
private losSub: Subscription;
/** /**
* The constructor * The constructor
*/ */
public constructor(private listOfSpeakersRepo: ListOfSpeakersRepositoryService) {} public constructor(private listOfSpeakersRepo: ListOfSpeakersRepositoryService) {}
public ngOnDestroy(): void {
this.cleanLosSub();
}
private cleanLosSub(): void {
if (this.losSub) {
this.losSub.unsubscribe();
this.losSub = null;
}
}
} }