Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speaking time edit and overtime #3160

Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Injectable } from '@angular/core';
import { marker as _ } from '@colsen1991/ngx-translate-extract-marker';
import { Identifiable } from 'src/app/domain/interfaces';
import { StructureLevelListOfSpeakers } from 'src/app/domain/models/structure-levels/structure-level-list-of-speakers';
import { StructureLevelListOfSpeakersAction } from 'src/app/gateways/repositories/structure-level-list-of-speakers/structure-level-list-of-speakers.action';
import { ViewStructureLevelListOfSpeakers } from 'src/app/site/pages/meetings/pages/participants/pages/structure-levels/view-models';

import { BaseMeetingRelatedRepository } from '../base-meeting-related-repository';
Expand All @@ -19,4 +21,20 @@ export class StructureLevelListOfSpeakersRepositoryService extends BaseMeetingRe

public getVerboseName = (): string => _(`StructureLevelListOfSpeakers`);
public getTitle = (): string => ``;

public async create(payload: any[]): Promise<void | void[]> {
return this.createAction(StructureLevelListOfSpeakersAction.CREATE, payload).resolve();
}

public async update(payload: any[]): Promise<void | void[]> {
return this.createAction(StructureLevelListOfSpeakersAction.UPDATE, payload).resolve();
}

public async delete(payload: Identifiable[]): Promise<void | void[]> {
return this.createAction(StructureLevelListOfSpeakersAction.DELETE, payload).resolve();
}

public async add_time(payload: Identifiable[]): Promise<void | void[]> {
return this.createAction(StructureLevelListOfSpeakersAction.ADD_TIME, payload).resolve();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class StructureLevelListOfSpeakersAction {
public static readonly CREATE = `structure_level_list_of_speakers.create`;
public static readonly UPDATE = `structure_level_list_of_speakers.update`;
public static readonly DELETE = `structure_level_list_of_speakers.delete`;
public static readonly ADD_TIME = `structure_level_list_of_speakers.add_time`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ export class ListOfSpeakersContentComponent extends BaseMeetingComponent impleme
};
} else if (this.structureLevelCountdownEnabled && speaker.structure_level_list_of_speakers) {
const speakingTime = speaker.structure_level_list_of_speakers;
const remaining = speakingTime.remaining_time + (speakingTime.additional_time || 0);
const remaining = speakingTime.remaining_time;
return {
running: !!speakingTime.current_start_time,
countdown_time: speakingTime.current_start_time
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { MatCardModule } from '@angular/material/card';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatLegacyMenuModule as MatMenuModule } from '@angular/material/legacy-menu';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatTabsModule } from '@angular/material/tabs';
import { MatTooltipModule } from '@angular/material/tooltip';
Expand Down Expand Up @@ -39,15 +44,20 @@ import { SpeakingTimesComponent } from './components/speaking-times/speaking-tim
MatProgressBarModule,
MatTabsModule,
MatTooltipModule,
MatFormFieldModule,
MatIconModule,
MatDialogModule,
ListOfSpeakersContentModule,
HeadBarModule,
CountdownTimeModule,
OpenSlidesTranslationModule.forChild(),
PollModule,
MotionPollModule,
MatMenuModule,
TopicPollModule,
AssignmentPollModule
AssignmentPollModule,
ReactiveFormsModule,
MatInputModule
]
})
export class AutopilotModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,29 @@ <h1 class="line-and-icon">
>
<mat-card class="os-card spacer-bottom-60">
<mat-card-content>
<p class="subtitle-text" translate>Speaking times</p>
<div class="action-title">
<p class="subtitle-text" translate>Speaking times</p>
<ng-container *ngIf="permission.projectorCanManage">
<button type="button" mat-icon-button [matMenuTriggerFor]="projectionMenu">
<mat-icon>more_horiz</mat-icon>
</button>
</ng-container>
</div>
<os-speaking-times
[currentSpeakingTimes]="listOfSpeakers.structure_level_list_of_speakers_ids"
></os-speaking-times>
</mat-card-content>
</mat-card>
</div>
</div>

<mat-menu #projectionMenu="matMenu">
<button mat-menu-item (click)="showAllStructureLevels()">
<mat-icon>videocam</mat-icon>
<span>{{ 'Project all structure levels' | translate }}</span>
</button>
<button mat-menu-item (click)="showActiveStructureLevel()">
<mat-icon>videocam</mat-icon>
<span>{{ 'Project active structure level' | translate }}</span>
</button>
</mat-menu>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { DetailNavigable, isDetailNavigable } from 'src/app/domain/interfaces/de
import { Mediafile } from 'src/app/domain/models/mediafiles/mediafile';
import { Topic } from 'src/app/domain/models/topics/topic';
import { BaseViewModel } from 'src/app/site/base/base-view-model';
import { DurationService } from 'src/app/site/services/duration.service';
import { OperatorService } from 'src/app/site/services/operator.service';

import { BaseMeetingComponent } from '../../../../base/base-meeting.component';
Expand Down Expand Up @@ -115,8 +114,7 @@ export class AutopilotComponent extends BaseMeetingComponent implements OnInit {
private operator: OperatorService,
projectorRepo: ProjectorControllerService,
closService: CurrentListOfSpeakersService,
private listOfSpeakersRepo: ListOfSpeakersControllerService,
private durationService: DurationService
private listOfSpeakersRepo: ListOfSpeakersControllerService
) {
super(componentServiceCollector, translate);

Expand Down Expand Up @@ -149,4 +147,22 @@ export class AutopilotComponent extends BaseMeetingComponent implements OnInit {
public async readdLastSpeaker(): Promise<void> {
await this.listOfSpeakersRepo.readdLastSpeaker(this.listOfSpeakers!).catch(this.raiseError);
}

public showAllStructureLevels(): void {
/**
* TODO
* - a dialog should open to select the projector
* (see election-list -> projector button for similar dialog)
* - every structure level/time/colour etc. should be projected onto the selected projector(s)
*/
}

public showActiveStructureLevel(): void {
/**
* TODO
* - a dialog should open to select the projector(s), "fullscreen"-mode and display type
* (see projector-detail -> countdowns -> "open projection dialog"-dialog for similar dialog)
* - only the structure level/time/colour of the currently speaking person should be projected
*/
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,64 @@
<div class="structure-level-list">
<div class="structure-level" *ngFor="let structure_level of getStructureLevels()">
<span class="structure-level-time" [ngStyle]="{ 'border-top-color': structure_level.color }">
<os-countdown-time [unstyled]="true" [countdown]="structure_level.countdown"></os-countdown-time>
</span>
<div class="structure-level-name">{{ structure_level.name }}</div>
<div>
<span class="structure-level-time" [ngStyle]="{ 'border-top-color': structure_level.color }">
<os-countdown-time [unstyled]="true" [countdown]="structure_level.countdown"></os-countdown-time>
</span>
<div class="structure-level-name">{{ structure_level.name }}</div>
</div>
<ng-container *ngIf="permission.projectorCanManage">
<button
type="button"
mat-icon-button
[matMenuTriggerFor]="projectionMenu"
[matMenuTriggerData]="{ structure_level: structure_level }"
>
<mat-icon>more_vert</mat-icon>
</button>
</ng-container>
</div>
</div>

<mat-menu #projectionMenu="matMenu">
<ng-template let-structure_level="structure_level" matMenuContent>
<button mat-menu-item (click)="setTotalTime(structure_level.id)" [disabled]="hasSpokenFlag">
<mat-icon>edit</mat-icon>
<span>{{ 'Edit total time' | translate }}</span>
</button>
<button
mat-menu-item
(click)="distributOverhangTime(structure_level.id)"
[disabled]="!isInOvertimeAndNotSpeaking(structure_level.id)"
>
<mat-icon>more_time</mat-icon>
<span>{{ 'Distribute overhang time' | translate }}</span>
</button>
</ng-template>
</mat-menu>

<!-- Template for total times dialog -->
<ng-template #totalTimeDialog>
<h2 mat-dialog-title>{{ 'Change total time of' | translate }} {{ currentEntry.name }}</h2>
<div class="os-form-card-mobile" mat-dialog-content>
<form [formGroup]="totalTimeForm" (keydown)="onKeyDown($event)">
<!-- total time -->
<mat-form-field>
<mat-label>{{ 'Total time' | translate }}</mat-label>
<input type="number" formControlName="totalTime" matInput required />
<mat-error>
{{ 'A total time is required and must be greater than 0.' | translate }}
</mat-error>
</mat-form-field>
</form>
<p class="warn">{{ 'This will overwrite the current time.' | translate }}</p>
</div>

<div mat-dialog-actions>
<button mat-button [disabled]="!totalTimeForm.valid" [mat-dialog-close]="true">
<span>{{ 'OK' | translate }}</span>
</button>
<button mat-button [mat-dialog-close]="false">
<span>{{ 'Cancel' | translate }}</span>
</button>
</div>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
.structure-level {
width: 33%;
margin-bottom: 26px;
display: flex;
}
.structure-level-time {
border-top-color: transparent;
Expand Down
Loading