countdown: new title field, description optional
This commit is contained in:
parent
08e076f4a4
commit
44d16eb244
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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 {}
|
||||
|
@ -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"],
|
||||
},
|
||||
)
|
||||
|
15
openslides/core/migrations/0019_countdown_title_1.py
Normal file
15
openslides/core/migrations/0019_countdown_title_1.py
Normal 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)]
|
16
openslides/core/migrations/0019_countdown_title_2.py
Normal file
16
openslides/core/migrations/0019_countdown_title_2.py
Normal 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),
|
||||
)
|
||||
]
|
@ -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)
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user