Merge pull request #5330 from tsiegleauq/mark-first-time-speaker

Show first contribution hint in list of speaker
This commit is contained in:
Emanuel Schütze 2020-04-30 15:03:55 +02:00 committed by GitHub
commit 3842f66877
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 3 deletions

View File

@ -224,6 +224,10 @@ export class ListOfSpeakersRepositoryService extends BaseHasContentObjectReposit
await this.httpService.post('/rest/agenda/list-of-speakers/delete_all_speakers/');
}
public isFirstContribution(speaker: ViewSpeaker): boolean {
return !this.getViewModelList().some(list => list.hasSpeakerSpoken(speaker));
}
/**
* Helper function get the url to the speaker rest address
*

View File

@ -95,9 +95,18 @@
<!-- implicit speaker references into the component using ng-template slot -->
<ng-template let-speaker>
<span *osPerms="'agenda.can_manage_list_of_speakers'">
<!-- Speaker count -->
<span *ngIf="hasSpokenCount(speaker)" class="red-warning-text speaker-warning">
{{ hasSpokenCount(speaker) + 1 }}. <span>{{ 'contribution' | translate }}</span>
</span>
<!-- First contribution -->
<span *ngIf="showFistContributionHint && isFirstContribution(speaker)" class="speaker-warning">
{{ 'First contribution' | translate }}
</span>
<!-- Speaker gender -->
<span *ngIf="speaker.gender">({{ speaker.gender | translate }})</span>
</span>

View File

@ -1,4 +1,4 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ChangeDetectionStrategy, Component, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Title } from '@angular/platform-browser';
@ -31,7 +31,8 @@ import { SpeakerState, ViewSpeaker } from '../../models/view-speaker';
@Component({
selector: 'os-list-of-speakers',
templateUrl: './list-of-speakers.component.html',
styleUrls: ['./list-of-speakers.component.scss']
styleUrls: ['./list-of-speakers.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ListOfSpeakersComponent extends BaseViewComponent implements OnInit {
@ViewChild(SortingListComponent)
@ -122,6 +123,8 @@ export class ListOfSpeakersComponent extends BaseViewComponent implements OnInit
private closSubscription: Subscription | null;
public showFistContributionHint: boolean;
/**
* Constructor for speaker list component. Generates the forms.
*
@ -205,6 +208,9 @@ export class ListOfSpeakersComponent extends BaseViewComponent implements OnInit
this.subscriptions.push(
this.config.get('agenda_present_speakers_only').subscribe(() => {
this.filterUsers();
}),
this.config.get<boolean>('agenda_show_first_contribution').subscribe(show => {
this.showFistContributionHint = show;
})
);
}
@ -416,6 +422,15 @@ export class ListOfSpeakersComponent extends BaseViewComponent implements OnInit
}).length;
}
/**
* Returns true if the speaker did never appear on any list of speakers
*
* @param speaker
*/
public isFirstContribution(speaker: ViewSpeaker): boolean {
return this.listOfSpeakersRepo.isFirstContribution(speaker);
}
/**
* Closes the current list of speakers
*/

View File

@ -24,11 +24,19 @@ export class ViewListOfSpeakers extends BaseViewModelWithContentObject<ListOfSpe
return this._model;
}
public get finishedSpeakers(): ViewSpeaker[] {
return this.speakers.filter(speaker => speaker.state === SpeakerState.FINISHED);
}
/**
* Gets the amount of waiting speakers
*/
public get waitingSpeakerAmount(): number {
return this.speakers.filter(speaker => speaker.state === SpeakerState.WAITING).length;
return this.waitingSpeakers.length;
}
public get waitingSpeakers(): ViewSpeaker[] {
return this.speakers.filter(speaker => speaker.state === SpeakerState.WAITING);
}
public get listOfSpeakersUrl(): string {
@ -51,6 +59,10 @@ export class ViewListOfSpeakers extends BaseViewModelWithContentObject<ListOfSpe
getDialogTitle: () => this.getTitle()
};
}
public hasSpeakerSpoken(checkSpeaker: ViewSpeaker): boolean {
return this.finishedSpeakers.findIndex(speaker => speaker.user_id === checkSpeaker.user_id) !== -1;
}
}
interface IListOfSpeakersRelations {
speakers: ViewSpeaker[];

View File

@ -188,3 +188,13 @@ def get_config_variables():
group="Agenda",
subgroup="List of speakers",
)
yield ConfigVariable(
name="agenda_show_first_contribution",
default_value=False,
input_type="boolean",
label="Show a note when a speaker appears for the first time",
weight=234,
group="Agenda",
subgroup="List of speakers",
)