countdown: new title field, description optional

This commit is contained in:
Maximilian Krambach 2019-02-27 16:08:22 +01:00 committed by Emanuel Schütze
parent 08e076f4a4
commit 44d16eb244
11 changed files with 125 additions and 37 deletions

View File

@ -8,7 +8,8 @@ export class Countdown extends BaseModel<Countdown> {
public static COLLECTIONSTRING = 'core/countdown';
public id: number;
public description: string;
public description?: string;
public title: string;
public default_time: number;
public countdown_time: number;
public running: boolean;

View File

@ -64,7 +64,7 @@ export class ViewTopic extends BaseAgendaViewModel {
}
public getTitle = () => {
if (this.agendaItem) {
if (this.agendaItem && this.agendaItem.itemNumber) {
return this.agendaItem.itemNumber + ' · ' + this.title;
} else {
return this.title;

View File

@ -9,18 +9,23 @@
<mat-card *ngIf="countdownToCreate">
<mat-card-title translate>New countdown</mat-card-title>
<mat-card-content>
<form [formGroup]="createForm"
(keydown)="onKeyDownCreate($event)">
<form [formGroup]="createForm" (keydown)="onKeyDownCreate($event)">
<p>
<mat-form-field>
<input formControlName="description" matInput placeholder="{{'Description' | translate}}" required>
<mat-hint *ngIf="!createForm.controls.description.valid">
<input formControlName="title" matInput placeholder="{{ 'Title' | translate }}" required />
<mat-hint *ngIf="!createForm.controls.title.valid">
<span translate>Required</span>
</mat-hint>
</mat-form-field>
</p><p>
</p>
<p>
<mat-form-field>
<input formControlName="default_time" matInput placeholder="{{ 'Time' | translate}}" required>
<input formControlName="description" matInput placeholder="{{ 'Description' | translate }}" />
</mat-form-field>
</p>
<p>
<mat-form-field>
<input formControlName="default_time" matInput placeholder="{{ 'Time' | translate }}" required />
<mat-hint *ngIf="!createForm.controls.default_time.valid">
<span translate>Required</span>
</mat-hint>
@ -39,9 +44,13 @@
</mat-card>
<mat-accordion class="os-card">
<mat-expansion-panel *ngFor="let countdown of countdowns" (opened)="openId = countdown.id"
(closed)="panelClosed(countdown)" [expanded]="openId === countdown.id" multiple="false">
<mat-expansion-panel
*ngFor="let countdown of countdowns"
(opened)="openId = countdown.id"
(closed)="panelClosed(countdown)"
[expanded]="openId === countdown.id"
multiple="false"
>
<!-- Projector button and countdown description-->
<mat-expansion-panel-header>
<mat-panel-title>
@ -50,7 +59,7 @@
<os-projector-button [object]="countdown"></os-projector-button>
</div>
<div class="header-name">
{{ countdown.description }}
{{ countdown.getTitle() | translate }}
</div>
<div class="header-controls">
<os-countdown-controls [countdown]="countdown"></os-countdown-controls>
@ -58,20 +67,28 @@
</div>
</mat-panel-title>
</mat-expansion-panel-header>
<form [formGroup]="updateForm"
*ngIf="editId === countdown.id"
(keydown)="onKeyDownUpdate($event)">
<form [formGroup]="updateForm" *ngIf="editId === countdown.id" (keydown)="onKeyDownUpdate($event)">
<h5 translate>Edit countdown</h5>
<p>
<mat-form-field>
<input formControlName="description" matInput placeholder="{{ 'Description' | translate}}" required>
<mat-hint *ngIf="!updateForm.controls.description.valid">
<input formControlName="title" matInput placeholder="{{ 'Title' | translate }}" required />
<mat-hint *ngIf="!updateForm.controls.title.valid">
<span translate>Required</span>
</mat-hint>
</mat-form-field>
</p><p>
</p>
<p>
<mat-form-field>
<input formControlName="default_time" matInput placeholder="{{ 'Time' | translate}}" required>
<input
formControlName="description"
matInput
placeholder="{{ 'Description' | translate }}"
/>
</mat-form-field>
</p>
<p>
<mat-form-field>
<input formControlName="default_time" matInput placeholder="{{ 'Time' | translate }}" required />
<mat-hint *ngIf="!updateForm.controls.default_time.valid">
<span translate>Required</span>
</mat-hint>
@ -79,19 +96,34 @@
</p>
</form>
<mat-action-row>
<button *ngIf="editId !== countdown.id" mat-button class="on-transition-fade" (click)="onEditButton(countdown)"
mat-icon-button>
<button
*ngIf="editId !== countdown.id"
mat-button
class="on-transition-fade"
(click)="onEditButton(countdown)"
mat-icon-button
>
<mat-icon>edit</mat-icon>
</button>
<button *ngIf="editId === countdown.id" mat-button class="on-transition-fade" (click)="onCancelUpdate()"
mat-icon-button>
<button
*ngIf="editId === countdown.id"
mat-button
class="on-transition-fade"
(click)="onCancelUpdate()"
mat-icon-button
>
<mat-icon>close</mat-icon>
</button>
<button *ngIf="editId === countdown.id" mat-button class="on-transition-fade" (click)="onSaveButton(countdown)"
mat-icon-button>
<button
*ngIf="editId === countdown.id"
mat-button
class="on-transition-fade"
(click)="onSaveButton(countdown)"
mat-icon-button
>
<mat-icon>save</mat-icon>
</button>
<button mat-button class='on-transition-fade' (click)=onDeleteButton(countdown) mat-icon-button>
<button mat-button class="on-transition-fade" (click)="onDeleteButton(countdown)" mat-icon-button>
<mat-icon>delete</mat-icon>
</button>
</mat-action-row>

View File

@ -50,8 +50,9 @@ export class CountdownListComponent extends BaseViewComponent implements OnInit
super(titleService, translate, matSnackBar);
const form = {
description: ['', Validators.required],
default_time: ['', Validators.required]
description: [''],
default_time: ['', Validators.required],
title: ['', Validators.required]
};
this.createForm = this.formBuilder.group(form);
this.updateForm = this.formBuilder.group(form);
@ -77,6 +78,7 @@ export class CountdownListComponent extends BaseViewComponent implements OnInit
this.createForm.reset();
this.createForm.setValue({
description: '',
title: '',
default_time: '1:00 m'
});
this.countdownToCreate = new Countdown();
@ -95,6 +97,7 @@ export class CountdownListComponent extends BaseViewComponent implements OnInit
const newValues: Partial<Countdown> = {
description: this.createForm.value.description,
title: this.createForm.value.title,
default_time: default_time
};
newValues.countdown_time = default_time;
@ -114,6 +117,7 @@ export class CountdownListComponent extends BaseViewComponent implements OnInit
this.updateForm.setValue({
description: countdown.description,
title: this.translate.instant(countdown.title),
default_time: this.durationService.durationToString(countdown.default_time, 'm')
});
}
@ -129,6 +133,7 @@ export class CountdownListComponent extends BaseViewComponent implements OnInit
default_time = 60;
}
const newValues: Partial<Countdown> = {
title: this.updateForm.value.title,
description: this.updateForm.value.description,
default_time: default_time
};
@ -147,7 +152,7 @@ export class CountdownListComponent extends BaseViewComponent implements OnInit
* @param countdown The countdown to delete
*/
public async onDeleteButton(countdown: ViewCountdown): Promise<void> {
const content = this.translate.instant('Delete countdown') + ` ${countdown.description}?`;
const content = this.translate.instant('Delete countdown') + ` ${this.translate.instant(countdown.title)}?`;
if (await this.promptService.open('Are you sure?', content)) {
this.repo.delete(countdown).then(() => (this.openId = this.editId = null), this.raiseError);
}

View File

@ -14,7 +14,6 @@
</a>
<!-- Controls under the projector preview -->
<div class="control-group projector-controls">
<!-- scale up -->
<button type="button" mat-icon-button (click)="scale(scrollScaleDirection.Up)">
<mat-icon>zoom_in</mat-icon>
@ -44,7 +43,6 @@
</button>
<!-- scroll indicator -->
<div class="button-size" [ngClass]="projector.scroll != 0 ? 'warn' : ''">{{ projector.scroll }}</div>
</div>
</div>
<div class="column-right" *osPerms="'core.can_manage_projector'">
@ -73,7 +71,10 @@
<div>
<div *ngIf="projector.non_stable_elements.length">
<mat-list>
<mat-list-item *ngFor="let element of projector.non_stable_elements" class="currentElement backgroundColorAccent">
<mat-list-item
*ngFor="let element of projector.non_stable_elements"
class="currentElement backgroundColorAccent"
>
<button type="button" mat-icon-button (click)="unprojectCurrent(element)">
<mat-icon>videocam</mat-icon>
</button>
@ -96,7 +97,6 @@
<mat-expansion-panel-header>
<span translate>Queue</span>
</mat-expansion-panel-header>
<div
cdkDropList
class="drop-list"
@ -161,7 +161,7 @@
<button type="button" mat-icon-button (click)="project(countdown)">
<mat-icon>videocam</mat-icon>
</button>
{{ countdown.description }}
{{ countdown.getTitle() | translate }}
</mat-list-item>
</mat-list>
<mat-action-row>

View File

@ -29,7 +29,11 @@ export class ViewCountdown extends BaseProjectableViewModel {
}
public get description(): string {
return this.countdown.description;
return this.countdown.description || '';
}
public get title(): string {
return this.countdown.title;
}
/**
@ -42,8 +46,12 @@ export class ViewCountdown extends BaseProjectableViewModel {
this._countdown = countdown;
}
/**
* @returns a title for the countdown, consisting of the title and additional
* text info that may be displayed on the projector
*/
public getTitle = () => {
return this.description;
return this.description ? `${this.title} (${this.description})` : this.title;
};
public updateDependencies(update: BaseViewModel): void {}

View File

@ -423,6 +423,7 @@ class Speaker(RESTModelMixin, models.Model):
pk=1,
defaults={
"default_time": config["projector_default_countdown"],
"title": "Default countdown",
"countdown_time": config["projector_default_countdown"],
},
)

View File

@ -0,0 +1,15 @@
# Generated by Django 2.1.5 on 2019-02-27 11:17
from django.db import migrations
def delete_old_countdowns(apps, schema_editor):
Countdowns = apps.get_model("core", "countdown")
Countdowns.objects.all().delete()
class Migration(migrations.Migration):
dependencies = [("core", "0018_auto_20190222_1209")]
operations = [migrations.RunPython(delete_old_countdowns)]

View File

@ -0,0 +1,16 @@
# Generated by Django 2.1.5 on 2019-02-27 11:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("core", "0019_countdown_title_1")]
operations = [
migrations.AddField(
model_name="countdown",
name="title",
field=models.CharField(max_length=256, unique=True),
)
]

View File

@ -232,6 +232,8 @@ class Countdown(RESTModelMixin, models.Model):
access_permissions = CountdownAccessPermissions()
title = models.CharField(max_length=256, unique=True, default="")
description = models.CharField(max_length=256, blank=True)
running = models.BooleanField(default=False)

View File

@ -165,7 +165,15 @@ class CountdownSerializer(ModelSerializer):
class Meta:
model = Countdown
fields = ("id", "description", "default_time", "countdown_time", "running")
fields = (
"id",
"title",
"description",
"default_time",
"countdown_time",
"running",
)
unique_together = ("title",)
class HistorySerializer(ModelSerializer):