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 -->
<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>
<!-- 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
* @param event the clicked row

View File

@ -1,16 +1,31 @@
<ng-container *osPerms="'core.can_manage_projector'">
<button type="button" *ngIf="!text && !menuItem" mat-mini-fab (click)="onClick($event)"
[ngClass]="isProjected() ? 'projector-active' : 'projector-inactive'">
<button
type="button"
*ngIf="!text && !menuItem"
mat-mini-fab
(click)="onClick($event)"
[ngClass]="isProjected ? 'projector-active' : 'projector-inactive'"
>
<mat-icon>videocam</mat-icon>
</button>
<button type="button" *ngIf="text && !menuItem" mat-button (click)="onClick($event)"
[ngClass]="isProjected() ? 'projector-active' : 'projector-inactive'">
<button
type="button"
*ngIf="text && !menuItem"
mat-button
(click)="onClick($event)"
[ngClass]="isProjected ? 'projector-active' : 'projector-inactive'"
>
<mat-icon>videocam</mat-icon>
{{ text | translate }}
</button>
<button type="button" *ngIf="menuItem" mat-menu-item (click)="onClick()"
[ngClass]="isProjected() ? 'projector-active' : 'projector-inactive'">
<button
type="button"
*ngIf="menuItem"
mat-menu-item
(click)="onClick()"
[ngClass]="isProjected ? 'projector-active' : 'projector-inactive'"
>
<mat-icon>videocam</mat-icon>
{{ (text || 'Project') | translate }}
{{ text || 'Project' | translate }}
</button>
</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 { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service';
import { ProjectionDialogService } from 'app/core/ui-services/projection-dialog.service';
import { Projector } from 'app/shared/models/core/projector';
import {
@ -23,7 +27,7 @@ import {
templateUrl: './projector-button.component.html',
styleUrls: ['./projector-button.component.scss']
})
export class ProjectorButtonComponent implements OnInit {
export class ProjectorButtonComponent implements OnInit, OnDestroy {
/**
* The object to project.
*/
@ -33,6 +37,8 @@ export class ProjectorButtonComponent implements OnInit {
return this._object;
}
public isProjected = false;
@Input()
public set object(obj: Projectable | ProjectorElementBuildDeskriptor) {
if (isProjectable(obj) || isProjectorElementBuildDeskriptor(obj)) {
@ -48,16 +54,22 @@ export class ProjectorButtonComponent implements OnInit {
@Input()
public menuItem = false;
@Output()
public changeEvent: EventEmitter<void> = new EventEmitter();
/**
* Pre-define projection target
*/
@Input()
public projector: Projector | null;
private projectorRepoSub: Subscription;
/**
* The constructor
*/
public constructor(
private projectorRepo: ProjectorRepositoryService,
private projectionDialogService: ProjectionDialogService,
private projectorService: ProjectorService
) {}
@ -65,7 +77,27 @@ export class ProjectorButtonComponent implements OnInit {
/**
* 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
@ -79,7 +111,7 @@ export class ProjectorButtonComponent implements OnInit {
if (this.object) {
if (this.projector) {
// if the projection target was defines before
if (this.isProjected()) {
if (this.checkIsProjected()) {
// remove the projected object
this.projectorService.removeFrom(this.projector, this.object);
} else {
@ -98,7 +130,7 @@ export class ProjectorButtonComponent implements OnInit {
*
* @returns true, if the object is projected on one projector.
*/
public isProjected(): boolean {
public checkIsProjected(): boolean {
if (!this.object) {
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 { ContentObject, isContentObject } from 'app/shared/models/base/content-object';
@ -18,15 +21,27 @@ import {
selector: 'os-speaker-button',
templateUrl: './speaker-button.component.html'
})
export class SpeakerButtonComponent {
export class SpeakerButtonComponent implements OnDestroy {
@Input()
public set object(obj: BaseViewModelWithListOfSpeakers | ContentObject | null) {
let listOfSpeakers: ViewListOfSpeakers;
if (isBaseViewModelWithListOfSpeakers(obj)) {
this.listOfSpeakers = obj.listOfSpeakers;
listOfSpeakers = obj.listOfSpeakers;
} else if (isContentObject(obj)) {
this.listOfSpeakers = this.listOfSpeakersRepo.findByContentObject(obj);
listOfSpeakers = this.listOfSpeakersRepo.findByContentObject(obj);
} 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';
}
private losSub: Subscription;
/**
* The constructor
*/
public constructor(private listOfSpeakersRepo: ListOfSpeakersRepositoryService) {}
public ngOnDestroy(): void {
this.cleanLosSub();
}
private cleanLosSub(): void {
if (this.losSub) {
this.losSub.unsubscribe();
this.losSub = null;
}
}
}