Merge pull request #4211 from tsiegleauq/current-list-of-speakers
Add current list of speakers to agenda-list
This commit is contained in:
commit
768b97816f
@ -12,6 +12,7 @@ const routes: Routes = [
|
|||||||
{ path: 'import', component: AgendaImportListComponent },
|
{ path: 'import', component: AgendaImportListComponent },
|
||||||
{ path: 'topics/new', component: TopicDetailComponent },
|
{ path: 'topics/new', component: TopicDetailComponent },
|
||||||
{ path: 'sort-agenda', component: AgendaSortComponent },
|
{ path: 'sort-agenda', component: AgendaSortComponent },
|
||||||
|
{ path: 'speakers', component: SpeakerListComponent },
|
||||||
{ path: 'topics/:id', component: TopicDetailComponent },
|
{ path: 'topics/:id', component: TopicDetailComponent },
|
||||||
{ path: ':id/speakers', component: SpeakerListComponent }
|
{ path: ':id/speakers', component: SpeakerListComponent }
|
||||||
];
|
];
|
||||||
|
@ -110,7 +110,12 @@
|
|||||||
<span translate>Sort</span>
|
<span translate>Sort</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- csv export -->
|
<!-- Current list of speakers -->
|
||||||
|
<button mat-menu-item routerLink="speakers">
|
||||||
|
<mat-icon>mic</mat-icon>
|
||||||
|
<span translate>Current list of speakers</span>
|
||||||
|
</button>
|
||||||
|
<!-- CSV export -->
|
||||||
<button mat-menu-item (click)="csvExportItemList()">
|
<button mat-menu-item (click)="csvExportItemList()">
|
||||||
<mat-icon>archive</mat-icon>
|
<mat-icon>archive</mat-icon>
|
||||||
<span translate>Export as CSV</span>
|
<span translate>Export as CSV</span>
|
||||||
|
@ -1,16 +1,33 @@
|
|||||||
<os-head-bar [nav]="false" [goBack]="true">
|
<os-head-bar [nav]="false" [goBack]="true">
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<div class="title-slot">
|
<div class="title-slot">
|
||||||
<h2><span translate>List of speakers</span></h2>
|
<h2>
|
||||||
|
<span *ngIf="!currentListOfSpeakers">List of speakers</span>
|
||||||
|
<span *ngIf="currentListOfSpeakers">Current list of speakers</span>
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-slot" *osPerms="'agenda.can_manage_list_of_speakers'">
|
<div class="menu-slot" *osPerms="'agenda.can_manage_list_of_speakers'">
|
||||||
<button type="button" mat-icon-button [matMenuTriggerFor]="speakerMenu"><mat-icon>more_vert</mat-icon></button>
|
<button type="button" mat-icon-button [matMenuTriggerFor]="speakerMenu"><mat-icon>more_vert</mat-icon></button>
|
||||||
</div>
|
</div>
|
||||||
</os-head-bar>
|
</os-head-bar>
|
||||||
|
|
||||||
|
<!-- Select projector -->
|
||||||
|
<mat-card *ngIf="currentListOfSpeakers">
|
||||||
|
<h3 translate>
|
||||||
|
Manage the list of speakers for...
|
||||||
|
</h3>
|
||||||
|
<mat-form-field *ngIf="projectors && projectors.length > 0">
|
||||||
|
<mat-select [value]="projectors[0]" (selectionChange)="onSelectProjector($event)">
|
||||||
|
<mat-option *ngFor="let projector of projectors" [value]="projector">
|
||||||
|
{{ projector.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</mat-card>
|
||||||
|
|
||||||
<h1 class="title-left on-transition-fade" *ngIf="viewItem">{{ viewItem.getTitle() }}</h1>
|
<h1 class="title-left on-transition-fade" *ngIf="viewItem">{{ viewItem.getTitle() }}</h1>
|
||||||
|
|
||||||
<mat-card class="speaker-card">
|
<mat-card class="speaker-card" *ngIf="viewItem">
|
||||||
<!-- List of finished speakers -->
|
<!-- List of finished speakers -->
|
||||||
<mat-expansion-panel *ngIf="finishedSpeakers && finishedSpeakers.length > 0" class="finished-list">
|
<mat-expansion-panel *ngIf="finishedSpeakers && finishedSpeakers.length > 0" class="finished-list">
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
|
@ -1,20 +1,24 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { BehaviorSubject, Subscription } from 'rxjs';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { FormGroup, FormControl } from '@angular/forms';
|
import { FormGroup, FormControl } from '@angular/forms';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { MatSnackBar, MatSelectChange } from '@angular/material';
|
||||||
|
|
||||||
import { SpeakerState } from 'app/shared/models/agenda/speaker';
|
|
||||||
import { User } from 'app/shared/models/users/user';
|
|
||||||
import { ViewSpeaker } from '../../models/view-speaker';
|
|
||||||
import { DataStoreService } from 'app/core/core-services/data-store.service';
|
|
||||||
import { AgendaRepositoryService } from 'app/core/repositories/agenda/agenda-repository.service';
|
|
||||||
import { ViewItem } from '../../models/view-item';
|
|
||||||
import { OperatorService } from 'app/core/core-services/operator.service';
|
|
||||||
import { BaseViewComponent } from 'app/site/base/base-view';
|
|
||||||
import { Title } from '@angular/platform-browser';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { MatSnackBar } from '@angular/material';
|
|
||||||
|
import { AgendaRepositoryService } from 'app/core/repositories/agenda/agenda-repository.service';
|
||||||
|
import { BaseViewComponent } from 'app/site/base/base-view';
|
||||||
|
import { CurrentListOfSpeakersSlideService } from 'app/site/projector/services/current-list-of-of-speakers-slide.service';
|
||||||
|
import { DataStoreService } from 'app/core/core-services/data-store.service';
|
||||||
|
import { OperatorService } from 'app/core/core-services/operator.service';
|
||||||
|
import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service';
|
||||||
import { PromptService } from 'app/core/ui-services/prompt.service';
|
import { PromptService } from 'app/core/ui-services/prompt.service';
|
||||||
|
import { SpeakerState } from 'app/shared/models/agenda/speaker';
|
||||||
|
import { Title } from '@angular/platform-browser';
|
||||||
|
import { User } from 'app/shared/models/users/user';
|
||||||
|
import { ViewItem } from '../../models/view-item';
|
||||||
|
import { ViewSpeaker } from '../../models/view-speaker';
|
||||||
|
import { ViewProjector } from 'app/site/projector/models/view-projector';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of speakers for agenda items.
|
* The list of speakers for agenda items.
|
||||||
@ -25,6 +29,11 @@ import { PromptService } from 'app/core/ui-services/prompt.service';
|
|||||||
styleUrls: ['./speaker-list.component.scss']
|
styleUrls: ['./speaker-list.component.scss']
|
||||||
})
|
})
|
||||||
export class SpeakerListComponent extends BaseViewComponent implements OnInit {
|
export class SpeakerListComponent extends BaseViewComponent implements OnInit {
|
||||||
|
/**
|
||||||
|
* Determine if the user is viewing the current list if speakers
|
||||||
|
*/
|
||||||
|
public currentListOfSpeakers = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the view item to the given topic
|
* Holds the view item to the given topic
|
||||||
*/
|
*/
|
||||||
@ -35,6 +44,16 @@ export class SpeakerListComponent extends BaseViewComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
public speakers: ViewSpeaker[];
|
public speakers: ViewSpeaker[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds a list of projectors. Only in CurrentListOfSpeakers mode
|
||||||
|
*/
|
||||||
|
public projectors: ViewProjector[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the subscription to the current projector (if any)
|
||||||
|
*/
|
||||||
|
private projectorSubscription: Subscription;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the active speaker
|
* Holds the active speaker
|
||||||
*/
|
*/
|
||||||
@ -76,6 +95,7 @@ export class SpeakerListComponent extends BaseViewComponent implements OnInit {
|
|||||||
* @param title
|
* @param title
|
||||||
* @param translate
|
* @param translate
|
||||||
* @param snackBar
|
* @param snackBar
|
||||||
|
* @param projectorRepo
|
||||||
* @param route Angulars ActivatedRoute
|
* @param route Angulars ActivatedRoute
|
||||||
* @param DS the DataStore
|
* @param DS the DataStore
|
||||||
* @param itemRepo Repository fpr agenda items
|
* @param itemRepo Repository fpr agenda items
|
||||||
@ -85,15 +105,27 @@ export class SpeakerListComponent extends BaseViewComponent implements OnInit {
|
|||||||
title: Title,
|
title: Title,
|
||||||
translate: TranslateService,
|
translate: TranslateService,
|
||||||
snackBar: MatSnackBar,
|
snackBar: MatSnackBar,
|
||||||
|
projectorRepo: ProjectorRepositoryService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private DS: DataStoreService,
|
private DS: DataStoreService,
|
||||||
private itemRepo: AgendaRepositoryService,
|
private itemRepo: AgendaRepositoryService,
|
||||||
private op: OperatorService,
|
private op: OperatorService,
|
||||||
private promptService: PromptService
|
private promptService: PromptService,
|
||||||
|
private currentListOfSpeakersService: CurrentListOfSpeakersSlideService
|
||||||
) {
|
) {
|
||||||
super(title, translate, snackBar);
|
super(title, translate, snackBar);
|
||||||
|
this.isCurrentListOfSpeakers();
|
||||||
this.addSpeakerForm = new FormGroup({ user_id: new FormControl([]) });
|
this.addSpeakerForm = new FormGroup({ user_id: new FormControl([]) });
|
||||||
this.getAgendaItemByUrl();
|
|
||||||
|
if (this.currentListOfSpeakers) {
|
||||||
|
this.projectors = projectorRepo.getViewModelList();
|
||||||
|
this.showClosOfProjector(this.projectors[0]);
|
||||||
|
projectorRepo.getViewModelListObservable().subscribe(newProjectors => {
|
||||||
|
this.projectors = newProjectors;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.getItemByUrl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,19 +152,64 @@ export class SpeakerListComponent extends BaseViewComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the URL to determine a current list of Speakers
|
||||||
|
*/
|
||||||
|
private isCurrentListOfSpeakers(): void {
|
||||||
|
if (this.route.snapshot.url[0]) {
|
||||||
|
this.currentListOfSpeakers = this.route.snapshot.url[0].path === 'speakers';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executed by selecting projectors
|
||||||
|
*
|
||||||
|
* @param event Holds the selected projector
|
||||||
|
*/
|
||||||
|
public onSelectProjector(event: MatSelectChange): void {
|
||||||
|
this.showClosOfProjector(event.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the current lost of speakers of a given projector.
|
||||||
|
* Triggers after mat-select-change
|
||||||
|
*
|
||||||
|
* @param event Mat select change event, holds the projector in value
|
||||||
|
*/
|
||||||
|
private showClosOfProjector(projector: ViewProjector): void {
|
||||||
|
if (this.projectorSubscription) {
|
||||||
|
this.projectorSubscription.unsubscribe();
|
||||||
|
this.viewItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.projectorSubscription = this.currentListOfSpeakersService
|
||||||
|
.getAgendaItemIdObservable(projector)
|
||||||
|
.subscribe(agendaId => {
|
||||||
|
if (agendaId) {
|
||||||
|
this.setSpeakerList(agendaId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the ID from the url
|
* Extract the ID from the url
|
||||||
* Determine whether the speaker list belongs to a motion or a topic
|
* Determine whether the speaker list belongs to a motion or a topic
|
||||||
*/
|
*/
|
||||||
public getAgendaItemByUrl(): void {
|
private getItemByUrl(): void {
|
||||||
const id = +this.route.snapshot.url[0];
|
const id = +this.route.snapshot.url[0];
|
||||||
|
this.setSpeakerList(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current item as list of speakers
|
||||||
|
*
|
||||||
|
* @param item the item to use as List of Speakers
|
||||||
|
*/
|
||||||
|
private setSpeakerList(id: number): void {
|
||||||
this.itemRepo.getViewModelObservable(id).subscribe(newAgendaItem => {
|
this.itemRepo.getViewModelObservable(id).subscribe(newAgendaItem => {
|
||||||
if (newAgendaItem) {
|
if (newAgendaItem) {
|
||||||
this.viewItem = newAgendaItem;
|
this.viewItem = newAgendaItem;
|
||||||
|
|
||||||
const allSpeakers = this.itemRepo.createViewSpeakers(newAgendaItem.item);
|
const allSpeakers = this.itemRepo.createViewSpeakers(newAgendaItem.item);
|
||||||
|
|
||||||
this.speakers = allSpeakers.filter(speaker => speaker.state === SpeakerState.WAITING);
|
this.speakers = allSpeakers.filter(speaker => speaker.state === SpeakerState.WAITING);
|
||||||
this.finishedSpeakers = allSpeakers.filter(speaker => speaker.state === SpeakerState.FINISHED);
|
this.finishedSpeakers = allSpeakers.filter(speaker => speaker.state === SpeakerState.FINISHED);
|
||||||
this.activeSpeaker = allSpeakers.find(speaker => speaker.state === SpeakerState.CURRENT);
|
this.activeSpeaker = allSpeakers.find(speaker => speaker.state === SpeakerState.CURRENT);
|
||||||
@ -142,6 +219,7 @@ export class SpeakerListComponent extends BaseViewComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a speaker out of an id
|
* Create a speaker out of an id
|
||||||
|
*
|
||||||
* @param userId the user id to add to the list. No parameter adds the operators user as speaker.
|
* @param userId the user id to add to the list. No parameter adds the operators user as speaker.
|
||||||
*/
|
*/
|
||||||
public addNewSpeaker(userId?: number): void {
|
public addNewSpeaker(userId?: number): void {
|
||||||
|
Loading…
Reference in New Issue
Block a user