Projectiondefaults, width slider direct save
This commit is contained in:
parent
8f393a1877
commit
cee6d55b82
@ -34,7 +34,7 @@ matrix:
|
|||||||
script:
|
script:
|
||||||
- flake8 openslides tests
|
- flake8 openslides tests
|
||||||
- isort --check-only --diff --recursive openslides tests
|
- isort --check-only --diff --recursive openslides tests
|
||||||
- black --check --diff --py36 openslides tests
|
- black --check --diff --target-version py36 openslides tests
|
||||||
- python -m mypy openslides/ tests/
|
- python -m mypy openslides/ tests/
|
||||||
- python -W ignore -m pytest --cov --cov-fail-under=70
|
- python -W ignore -m pytest --cov --cov-fail-under=70
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import { ViewModelStoreService } from './view-model-store.service';
|
|||||||
import { BaseProjectableViewModel } from 'app/site/base/base-projectable-view-model';
|
import { BaseProjectableViewModel } from 'app/site/base/base-projectable-view-model';
|
||||||
import { ConfigService } from '../ui-services/config.service';
|
import { ConfigService } from '../ui-services/config.service';
|
||||||
import { ProjectorDataService } from './projector-data.service';
|
import { ProjectorDataService } from './projector-data.service';
|
||||||
|
import { ProjectionDefault } from 'app/shared/models/core/projection-default';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service cares about Projectables being projected and manage all projection-related
|
* This service cares about Projectables being projected and manage all projection-related
|
||||||
@ -254,10 +255,13 @@ export class ProjectorService {
|
|||||||
* @param projectiondefault The projection default
|
* @param projectiondefault The projection default
|
||||||
* @return the projector associated to the given projectiondefault.
|
* @return the projector associated to the given projectiondefault.
|
||||||
*/
|
*/
|
||||||
public getProjectorForDefault(projectiondefault: string): Projector {
|
public getProjectorForDefault(projectiondefault: string): Projector | null {
|
||||||
return this.DS.getAll<Projector>('core/projector').find(projector => {
|
const pd = this.DS.find(ProjectionDefault, _pd => _pd.name === projectiondefault);
|
||||||
return projector.projectiondefaults.map(pd => pd.name).includes(projectiondefault);
|
if (pd) {
|
||||||
});
|
return this.DS.get<Projector>(Projector, pd.projector_id);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,7 +3,7 @@ import { TestBed, inject } from '@angular/core/testing';
|
|||||||
import { E2EImportsModule } from 'e2e-imports.module';
|
import { E2EImportsModule } from 'e2e-imports.module';
|
||||||
import { CountdownRepositoryService } from './countdown-repository.service';
|
import { CountdownRepositoryService } from './countdown-repository.service';
|
||||||
|
|
||||||
describe('StatuteParagraphRepositoryService', () => {
|
describe('CountdownRepositoryService', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [E2EImportsModule],
|
imports: [E2EImportsModule],
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { DataSendService } from '../../core-services/data-send.service';
|
import { DataSendService } from '../../core-services/data-send.service';
|
||||||
import { DataStoreService } from '../../core-services/data-store.service';
|
import { DataStoreService } from '../../core-services/data-store.service';
|
||||||
import { BaseRepository } from '../base-repository';
|
import { BaseRepository } from '../base-repository';
|
||||||
@ -6,7 +9,6 @@ import { CollectionStringMapperService } from '../../core-services/collectionStr
|
|||||||
import { ViewCountdown } from 'app/site/projector/models/view-countdown';
|
import { ViewCountdown } from 'app/site/projector/models/view-countdown';
|
||||||
import { Countdown } from 'app/shared/models/core/countdown';
|
import { Countdown } from 'app/shared/models/core/countdown';
|
||||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
import { ServertimeService } from 'app/core/core-services/servertime.service';
|
import { ServertimeService } from 'app/core/core-services/servertime.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@ -34,15 +36,31 @@ export class CountdownRepositoryService extends BaseRepository<ViewCountdown, Co
|
|||||||
return viewCountdown;
|
return viewCountdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a countdown.
|
||||||
|
*
|
||||||
|
* @param countdown The countdown to start.
|
||||||
|
*/
|
||||||
public async start(countdown: ViewCountdown): Promise<void> {
|
public async start(countdown: ViewCountdown): Promise<void> {
|
||||||
const endTime = this.servertimeService.getServertime() / 1000 + countdown.countdown_time;
|
const endTime = this.servertimeService.getServertime() / 1000 + countdown.countdown_time;
|
||||||
await this.update({ running: true, countdown_time: endTime }, countdown);
|
await this.update({ running: true, countdown_time: endTime }, countdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops (former `reset`) a countdown. Sets the countdown time to the default time. If
|
||||||
|
* this should not happen, use `pause()`.
|
||||||
|
*
|
||||||
|
* @param countdown The countdown to stop.
|
||||||
|
*/
|
||||||
public async stop(countdown: ViewCountdown): Promise<void> {
|
public async stop(countdown: ViewCountdown): Promise<void> {
|
||||||
await this.update({ running: false, countdown_time: countdown.default_time }, countdown);
|
await this.update({ running: false, countdown_time: countdown.default_time }, countdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pauses the countdown. The remaining time will stay.
|
||||||
|
*
|
||||||
|
* @param countdown The countdown to pause.
|
||||||
|
*/
|
||||||
public async pause(countdown: ViewCountdown): Promise<void> {
|
public async pause(countdown: ViewCountdown): Promise<void> {
|
||||||
const endTime = countdown.countdown_time - this.servertimeService.getServertime() / 1000;
|
const endTime = countdown.countdown_time - this.servertimeService.getServertime() / 1000;
|
||||||
await this.update({ running: false, countdown_time: endTime }, countdown);
|
await this.update({ running: false, countdown_time: endTime }, countdown);
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { E2EImportsModule } from '../../../../e2e-imports.module';
|
||||||
|
import { ProjectionDefaultRepositoryService } from './projection-default-repository.service';
|
||||||
|
|
||||||
|
describe('ProjectionDefaultRepositoryService', () => {
|
||||||
|
beforeEach(() =>
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [E2EImportsModule],
|
||||||
|
providers: [ProjectionDefaultRepositoryService]
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
it('should be created', inject(
|
||||||
|
[ProjectionDefaultRepositoryService],
|
||||||
|
(service: ProjectionDefaultRepositoryService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}
|
||||||
|
));
|
||||||
|
});
|
@ -0,0 +1,68 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { BaseRepository } from '../base-repository';
|
||||||
|
import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service';
|
||||||
|
import { DataSendService } from '../../core-services/data-send.service';
|
||||||
|
import { DataStoreService } from '../../core-services/data-store.service';
|
||||||
|
import { Identifiable } from 'app/shared/models/base/identifiable';
|
||||||
|
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||||
|
import { ProjectionDefault } from 'app/shared/models/core/projection-default';
|
||||||
|
import { ViewProjectionDefault } from 'app/site/projector/models/view-projection-default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages all projection default instances.
|
||||||
|
*/
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class ProjectionDefaultRepositoryService extends BaseRepository<ViewProjectionDefault, ProjectionDefault> {
|
||||||
|
/**
|
||||||
|
* Constructor calls the parent constructor
|
||||||
|
*
|
||||||
|
* @param DS The DataStore
|
||||||
|
* @param dataSend sending changed objects
|
||||||
|
* @param mapperService Maps collection strings to classes
|
||||||
|
* @param viewModelStoreService
|
||||||
|
* @param translate
|
||||||
|
*/
|
||||||
|
public constructor(
|
||||||
|
DS: DataStoreService,
|
||||||
|
dataSend: DataSendService,
|
||||||
|
mapperService: CollectionStringMapperService,
|
||||||
|
viewModelStoreService: ViewModelStoreService,
|
||||||
|
translate: TranslateService
|
||||||
|
) {
|
||||||
|
super(DS, dataSend, mapperService, viewModelStoreService, translate, ProjectionDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getVerboseName = (plural: boolean = false) => {
|
||||||
|
return this.translate.instant(plural ? 'Projectiondefaults' : 'Projectiondefault');
|
||||||
|
};
|
||||||
|
|
||||||
|
public getTitle = (projectionDefault: Partial<ProjectionDefault> | Partial<ViewProjectionDefault>) => {
|
||||||
|
return this.translate.instant(projectionDefault.display_name);
|
||||||
|
};
|
||||||
|
|
||||||
|
public createViewModel(projectionDefault: ProjectionDefault): ViewProjectionDefault {
|
||||||
|
const viewProjectionDefault = new ViewProjectionDefault(projectionDefault);
|
||||||
|
viewProjectionDefault.getVerboseName = this.getVerboseName;
|
||||||
|
viewProjectionDefault.getTitle = () => this.getTitle(viewProjectionDefault);
|
||||||
|
return viewProjectionDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creation of projection defaults is not supported.
|
||||||
|
*/
|
||||||
|
public async create(projectorData: Partial<ProjectionDefault>): Promise<Identifiable> {
|
||||||
|
throw new Error('Not supported');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletion of projection defaults is not supported.
|
||||||
|
*/
|
||||||
|
public async delete(viewProjectionDefault: ViewProjectionDefault): Promise<void> {
|
||||||
|
throw new Error('Not supported');
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ import { TestBed, inject } from '@angular/core/testing';
|
|||||||
import { ProjectorRepositoryService } from './projector-repository.service';
|
import { ProjectorRepositoryService } from './projector-repository.service';
|
||||||
import { E2EImportsModule } from '../../../../e2e-imports.module';
|
import { E2EImportsModule } from '../../../../e2e-imports.module';
|
||||||
|
|
||||||
describe('GroupRepositoryService', () => {
|
describe('ProjectorRepositoryService', () => {
|
||||||
beforeEach(() =>
|
beforeEach(() =>
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [E2EImportsModule],
|
imports: [E2EImportsModule],
|
||||||
|
@ -47,7 +47,7 @@ export class ProjectionDialogComponent {
|
|||||||
const defaultProjector: Projector = this.projectorService.getProjectorForDefault(
|
const defaultProjector: Projector = this.projectorService.getProjectorForDefault(
|
||||||
this.projectorElementBuildDescriptor.projectionDefaultName
|
this.projectorElementBuildDescriptor.projectionDefaultName
|
||||||
);
|
);
|
||||||
if (!this.selectedProjectors.includes(defaultProjector)) {
|
if (defaultProjector && !this.selectedProjectors.includes(defaultProjector)) {
|
||||||
this.selectedProjectors.push(defaultProjector);
|
this.selectedProjectors.push(defaultProjector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
client/src/app/shared/models/core/projection-default.ts
Normal file
19
client/src/app/shared/models/core/projection-default.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { BaseModel } from '../base/base-model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of a projection default
|
||||||
|
*
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
export class ProjectionDefault extends BaseModel<ProjectionDefault> {
|
||||||
|
public static COLLECTIONSTRING = 'core/projection-default';
|
||||||
|
|
||||||
|
public id: number;
|
||||||
|
public name: string;
|
||||||
|
public display_name: string;
|
||||||
|
public projector_id: number;
|
||||||
|
|
||||||
|
public constructor(input?: any) {
|
||||||
|
super(ProjectionDefault.COLLECTIONSTRING, input);
|
||||||
|
}
|
||||||
|
}
|
@ -48,17 +48,7 @@ export function elementIdentifies(a: IdentifiableProjectorElement, b: ProjectorE
|
|||||||
export type ProjectorElements = ProjectorElement[];
|
export type ProjectorElements = ProjectorElement[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A projectiondefault
|
* Representation of a projector.
|
||||||
*/
|
|
||||||
export interface ProjectionDefault {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
display_name: string;
|
|
||||||
projector_id: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Representation of a projector. Has the nested property "projectiondefaults"
|
|
||||||
*
|
*
|
||||||
* TODO: Move all function to the viewprojector.
|
* TODO: Move all function to the viewprojector.
|
||||||
*
|
*
|
||||||
@ -77,7 +67,7 @@ export class Projector extends BaseModel<Projector> {
|
|||||||
public width: number;
|
public width: number;
|
||||||
public height: number;
|
public height: number;
|
||||||
public reference_projector_id: number;
|
public reference_projector_id: number;
|
||||||
public projectiondefaults: ProjectionDefault[];
|
public projectiondefaults_id: number[];
|
||||||
public background_color: string;
|
public background_color: string;
|
||||||
public header_background_color: string;
|
public header_background_color: string;
|
||||||
public header_font_color: string;
|
public header_font_color: string;
|
||||||
|
@ -104,9 +104,18 @@
|
|||||||
min="800"
|
min="800"
|
||||||
max="3840"
|
max="3840"
|
||||||
step="10"
|
step="10"
|
||||||
|
(change)="widthSliderValueChanged(projector, $event)"
|
||||||
></mat-slider>
|
></mat-slider>
|
||||||
{{ updateForm.value.width }}
|
{{ updateForm.value.width }}
|
||||||
|
|
||||||
|
<!-- projection defaults -->
|
||||||
|
<h3 translate>Projectiondefaults</h3>
|
||||||
|
<mat-select formControlName="projectiondefaults_id" placeholder="{{ 'Projectiondefaults' | translate }}" [multiple]="true">
|
||||||
|
<mat-option *ngFor="let pd of projectionDefaults" [value]="pd.id">
|
||||||
|
{{ pd.getTitle() | translate }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
|
||||||
<!-- colors -->
|
<!-- colors -->
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<span translate>Background color</span>
|
<span translate>Background color</span>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||||
import { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
import { MatSnackBar, MatSelectChange } from '@angular/material';
|
import { MatSnackBar, MatSelectChange, MatSliderChange } from '@angular/material';
|
||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
@ -12,6 +12,8 @@ import { BaseViewComponent } from 'app/site/base/base-view';
|
|||||||
import { PromptService } from 'app/core/ui-services/prompt.service';
|
import { PromptService } from 'app/core/ui-services/prompt.service';
|
||||||
import { ClockSlideService } from '../../services/clock-slide.service';
|
import { ClockSlideService } from '../../services/clock-slide.service';
|
||||||
import { OperatorService } from 'app/core/core-services/operator.service';
|
import { OperatorService } from 'app/core/core-services/operator.service';
|
||||||
|
import { ProjectionDefaultRepositoryService } from 'app/core/repositories/projector/projection-default-repository.service';
|
||||||
|
import { ViewProjectionDefault } from '../../models/view-projection-default';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All supported aspect rations for projectors.
|
* All supported aspect rations for projectors.
|
||||||
@ -62,6 +64,8 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit
|
|||||||
*/
|
*/
|
||||||
public projectors: ViewProjector[];
|
public projectors: ViewProjector[];
|
||||||
|
|
||||||
|
public projectionDefaults: ViewProjectionDefault[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to check manage permissions
|
* Helper to check manage permissions
|
||||||
*
|
*
|
||||||
@ -91,7 +95,8 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit
|
|||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private promptService: PromptService,
|
private promptService: PromptService,
|
||||||
private clockSlideService: ClockSlideService,
|
private clockSlideService: ClockSlideService,
|
||||||
private operator: OperatorService
|
private operator: OperatorService,
|
||||||
|
private projectionDefaultRepo: ProjectionDefaultRepositoryService
|
||||||
) {
|
) {
|
||||||
super(titleService, translate, matSnackBar);
|
super(titleService, translate, matSnackBar);
|
||||||
|
|
||||||
@ -104,6 +109,7 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit
|
|||||||
name: ['', Validators.required],
|
name: ['', Validators.required],
|
||||||
aspectRatio: ['', Validators.required],
|
aspectRatio: ['', Validators.required],
|
||||||
width: [0, Validators.required],
|
width: [0, Validators.required],
|
||||||
|
projectiondefaults_id: [[]],
|
||||||
clock: [true],
|
clock: [true],
|
||||||
background_color: ['', Validators.required],
|
background_color: ['', Validators.required],
|
||||||
header_background_color: ['', Validators.required],
|
header_background_color: ['', Validators.required],
|
||||||
@ -122,6 +128,8 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit
|
|||||||
super.setTitle('Projectors');
|
super.setTitle('Projectors');
|
||||||
this.projectors = this.repo.getViewModelList();
|
this.projectors = this.repo.getViewModelList();
|
||||||
this.repo.getViewModelListObservable().subscribe(projectors => (this.projectors = projectors));
|
this.repo.getViewModelListObservable().subscribe(projectors => (this.projectors = projectors));
|
||||||
|
this.projectionDefaults = this.projectionDefaultRepo.getViewModelList();
|
||||||
|
this.projectionDefaultRepo.getViewModelListObservable().subscribe(pds => (this.projectionDefaults = pds));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -271,4 +279,13 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit
|
|||||||
});
|
});
|
||||||
Promise.all(promises).then(null, this.raiseError);
|
Promise.all(promises).then(null, this.raiseError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public widthSliderValueChanged(projector: ViewProjector, event: MatSliderChange): void {
|
||||||
|
const aspectRatio = this.getAspectRatioKey(projector);
|
||||||
|
const updateProjector: Partial<Projector> = {
|
||||||
|
width: event.value
|
||||||
|
};
|
||||||
|
updateProjector.height = Math.round(event.value / aspectRatios[aspectRatio]);
|
||||||
|
this.repo.update(updateProjector, projector).then(null, this.raiseError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
import { BaseViewModel } from '../../base/base-view-model';
|
||||||
|
import { ProjectionDefault } from 'app/shared/models/core/projection-default';
|
||||||
|
|
||||||
|
export class ViewProjectionDefault extends BaseViewModel {
|
||||||
|
public static COLLECTIONSTRING = ProjectionDefault.COLLECTIONSTRING;
|
||||||
|
|
||||||
|
private _projectionDefault: ProjectionDefault;
|
||||||
|
|
||||||
|
public get projectionDefault(): ProjectionDefault {
|
||||||
|
return this._projectionDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get id(): number {
|
||||||
|
return this.projectionDefault.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get name(): string {
|
||||||
|
return this.projectionDefault.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get display_name(): string {
|
||||||
|
return this.projectionDefault.display_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is set by the repository
|
||||||
|
*/
|
||||||
|
public getVerboseName: () => string;
|
||||||
|
public getTitle: () => string;
|
||||||
|
|
||||||
|
public constructor(projectionDefault: ProjectionDefault) {
|
||||||
|
super(ProjectionDefault.COLLECTIONSTRING);
|
||||||
|
this._projectionDefault = projectionDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getModel(): ProjectionDefault {
|
||||||
|
return this.projectionDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateDependencies(update: BaseViewModel): void {}
|
||||||
|
}
|
@ -27,6 +27,10 @@ export class ViewProjector extends BaseViewModel {
|
|||||||
return this.projector.name;
|
return this.projector.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get projectiondefaults_id(): number[] {
|
||||||
|
return this.projector.projectiondefaults_id;
|
||||||
|
}
|
||||||
|
|
||||||
public get elements(): ProjectorElements {
|
public get elements(): ProjectorElements {
|
||||||
return this.projector.elements;
|
return this.projector.elements;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,9 @@ import { ProjectorMessageRepositoryService } from 'app/core/repositories/project
|
|||||||
import { ViewProjector } from './models/view-projector';
|
import { ViewProjector } from './models/view-projector';
|
||||||
import { ViewCountdown } from './models/view-countdown';
|
import { ViewCountdown } from './models/view-countdown';
|
||||||
import { ViewProjectorMessage } from './models/view-projector-message';
|
import { ViewProjectorMessage } from './models/view-projector-message';
|
||||||
|
import { ProjectionDefault } from 'app/shared/models/core/projection-default';
|
||||||
|
import { ViewProjectionDefault } from './models/view-projection-default';
|
||||||
|
import { ProjectionDefaultRepositoryService } from 'app/core/repositories/projector/projection-default-repository.service';
|
||||||
|
|
||||||
export const ProjectorAppConfig: AppConfig = {
|
export const ProjectorAppConfig: AppConfig = {
|
||||||
name: 'projector',
|
name: 'projector',
|
||||||
@ -18,6 +21,12 @@ export const ProjectorAppConfig: AppConfig = {
|
|||||||
viewModel: ViewProjector,
|
viewModel: ViewProjector,
|
||||||
repository: ProjectorRepositoryService
|
repository: ProjectorRepositoryService
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
collectionString: 'core/projection-default',
|
||||||
|
model: ProjectionDefault,
|
||||||
|
viewModel: ViewProjectionDefault,
|
||||||
|
repository: ProjectionDefaultRepositoryService
|
||||||
|
},
|
||||||
{
|
{
|
||||||
collectionString: 'core/countdown',
|
collectionString: 'core/countdown',
|
||||||
model: Countdown,
|
model: Countdown,
|
||||||
|
@ -80,4 +80,4 @@ def clean(args=None):
|
|||||||
@command("format", help="Format code with isort and black")
|
@command("format", help="Format code with isort and black")
|
||||||
def isort(args=None):
|
def isort(args=None):
|
||||||
call("isort --recursive openslides tests")
|
call("isort --recursive openslides tests")
|
||||||
call("black --py36 openslides tests")
|
call("black --target-version py36 openslides tests")
|
||||||
|
@ -9,6 +9,14 @@ class ProjectorAccessPermissions(BaseAccessPermissions):
|
|||||||
base_permission = "core.can_see_projector"
|
base_permission = "core.can_see_projector"
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectionDefaultAccessPermissions(BaseAccessPermissions):
|
||||||
|
"""
|
||||||
|
Access permissions container for Projector and ProjectorViewSet.
|
||||||
|
"""
|
||||||
|
|
||||||
|
base_permission = "core.can_see_projector"
|
||||||
|
|
||||||
|
|
||||||
class TagAccessPermissions(BaseAccessPermissions):
|
class TagAccessPermissions(BaseAccessPermissions):
|
||||||
"""
|
"""
|
||||||
Access permissions container for Tag and TagViewSet.
|
Access permissions container for Tag and TagViewSet.
|
||||||
|
@ -33,6 +33,7 @@ class CoreAppConfig(AppConfig):
|
|||||||
HistoryViewSet,
|
HistoryViewSet,
|
||||||
ProjectorMessageViewSet,
|
ProjectorMessageViewSet,
|
||||||
ProjectorViewSet,
|
ProjectorViewSet,
|
||||||
|
ProjectionDefaultViewSet,
|
||||||
TagViewSet,
|
TagViewSet,
|
||||||
)
|
)
|
||||||
from .websocket import (
|
from .websocket import (
|
||||||
@ -74,6 +75,10 @@ class CoreAppConfig(AppConfig):
|
|||||||
router.register(
|
router.register(
|
||||||
self.get_model("Projector").get_collection_string(), ProjectorViewSet
|
self.get_model("Projector").get_collection_string(), ProjectorViewSet
|
||||||
)
|
)
|
||||||
|
router.register(
|
||||||
|
self.get_model("Projectiondefault").get_collection_string(),
|
||||||
|
ProjectionDefaultViewSet,
|
||||||
|
)
|
||||||
router.register(
|
router.register(
|
||||||
self.get_model("ChatMessage").get_collection_string(), ChatMessageViewSet
|
self.get_model("ChatMessage").get_collection_string(), ChatMessageViewSet
|
||||||
)
|
)
|
||||||
@ -121,6 +126,7 @@ class CoreAppConfig(AppConfig):
|
|||||||
"""
|
"""
|
||||||
for model_name in (
|
for model_name in (
|
||||||
"Projector",
|
"Projector",
|
||||||
|
"ProjectionDefault",
|
||||||
"ChatMessage",
|
"ChatMessage",
|
||||||
"Tag",
|
"Tag",
|
||||||
"ProjectorMessage",
|
"ProjectorMessage",
|
||||||
|
@ -16,6 +16,7 @@ from .access_permissions import (
|
|||||||
ConfigAccessPermissions,
|
ConfigAccessPermissions,
|
||||||
CountdownAccessPermissions,
|
CountdownAccessPermissions,
|
||||||
HistoryAccessPermissions,
|
HistoryAccessPermissions,
|
||||||
|
ProjectionDefaultAccessPermissions,
|
||||||
ProjectorAccessPermissions,
|
ProjectorAccessPermissions,
|
||||||
ProjectorMessageAccessPermissions,
|
ProjectorMessageAccessPermissions,
|
||||||
TagAccessPermissions,
|
TagAccessPermissions,
|
||||||
@ -123,6 +124,8 @@ class ProjectionDefault(RESTModelMixin, models.Model):
|
|||||||
name on the front end for the user.
|
name on the front end for the user.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
access_permissions = ProjectionDefaultAccessPermissions()
|
||||||
|
|
||||||
name = models.CharField(max_length=256)
|
name = models.CharField(max_length=256)
|
||||||
|
|
||||||
display_name = models.CharField(max_length=256)
|
display_name = models.CharField(max_length=256)
|
||||||
@ -131,9 +134,6 @@ class ProjectionDefault(RESTModelMixin, models.Model):
|
|||||||
Projector, on_delete=models.PROTECT, related_name="projectiondefaults"
|
Projector, on_delete=models.PROTECT, related_name="projectiondefaults"
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_root_rest_element(self):
|
|
||||||
return self.projector
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
default_permissions = ()
|
default_permissions = ()
|
||||||
|
|
||||||
|
@ -81,7 +81,6 @@ class ProjectorSerializer(ModelSerializer):
|
|||||||
elements_preview = JSONSerializerField(validators=[elements_validator])
|
elements_preview = JSONSerializerField(validators=[elements_validator])
|
||||||
elements_history = JSONSerializerField(validators=[elements_array_validator])
|
elements_history = JSONSerializerField(validators=[elements_array_validator])
|
||||||
|
|
||||||
projectiondefaults = ProjectionDefaultSerializer(many=True, read_only=True)
|
|
||||||
width = IntegerField(min_value=800, max_value=3840, required=False)
|
width = IntegerField(min_value=800, max_value=3840, required=False)
|
||||||
height = IntegerField(min_value=340, max_value=2880, required=False)
|
height = IntegerField(min_value=340, max_value=2880, required=False)
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ from .access_permissions import (
|
|||||||
ConfigAccessPermissions,
|
ConfigAccessPermissions,
|
||||||
CountdownAccessPermissions,
|
CountdownAccessPermissions,
|
||||||
HistoryAccessPermissions,
|
HistoryAccessPermissions,
|
||||||
|
ProjectionDefaultAccessPermissions,
|
||||||
ProjectorAccessPermissions,
|
ProjectorAccessPermissions,
|
||||||
ProjectorMessageAccessPermissions,
|
ProjectorMessageAccessPermissions,
|
||||||
TagAccessPermissions,
|
TagAccessPermissions,
|
||||||
@ -143,12 +144,18 @@ class ProjectorViewSet(ModelViewSet):
|
|||||||
REST API operation for DELETE requests.
|
REST API operation for DELETE requests.
|
||||||
|
|
||||||
Assigns all ProjectionDefault objects from this projector to the
|
Assigns all ProjectionDefault objects from this projector to the
|
||||||
default projector (pk=1).
|
first projector found.
|
||||||
"""
|
"""
|
||||||
|
if len(Projector.objects.all()) <= 1:
|
||||||
|
raise ValidationError({"detail": "You can't delete the last projector."})
|
||||||
projector_instance = self.get_object()
|
projector_instance = self.get_object()
|
||||||
|
new_projector_id = (
|
||||||
|
Projector.objects.exclude(pk=projector_instance.pk).first().pk
|
||||||
|
)
|
||||||
|
|
||||||
for projection_default in ProjectionDefault.objects.all():
|
for projection_default in ProjectionDefault.objects.all():
|
||||||
if projection_default.projector.id == projector_instance.id:
|
if projection_default.projector.id == projector_instance.id:
|
||||||
projection_default.projector_id = 1
|
projection_default.projector_id = new_projector_id
|
||||||
projection_default.save()
|
projection_default.save()
|
||||||
return super(ProjectorViewSet, self).destroy(*args, **kwargs)
|
return super(ProjectorViewSet, self).destroy(*args, **kwargs)
|
||||||
|
|
||||||
@ -272,32 +279,29 @@ class ProjectorViewSet(ModelViewSet):
|
|||||||
message = f"Setting scroll to {request.data} was successful."
|
message = f"Setting scroll to {request.data} was successful."
|
||||||
return Response({"detail": message})
|
return Response({"detail": message})
|
||||||
|
|
||||||
@detail_route(methods=["post"])
|
|
||||||
def set_projectiondefault(self, request, pk):
|
|
||||||
"""
|
|
||||||
REST API operation to set a projectiondefault to the requested projector. The argument
|
|
||||||
has to be an int representing the pk from the projectiondefault to be set.
|
|
||||||
|
|
||||||
It expects a POST request to
|
class ProjectionDefaultViewSet(ModelViewSet):
|
||||||
/rest/core/projector/<pk>/set_projectiondefault/ with the projectiondefault id as the argument
|
"""
|
||||||
"""
|
API endpoint for projection defaults.
|
||||||
if not isinstance(request.data, int):
|
|
||||||
raise ValidationError({"detail": "Data must be an int."})
|
|
||||||
|
|
||||||
try:
|
There are the following views: list, retrieve, create, update,
|
||||||
projectiondefault = ProjectionDefault.objects.get(pk=request.data)
|
partial_update and destroy.
|
||||||
except ProjectionDefault.DoesNotExist:
|
"""
|
||||||
raise ValidationError(
|
|
||||||
{
|
access_permissions = ProjectionDefaultAccessPermissions()
|
||||||
"detail": f"The projectiondefault with pk={request.data} was not found."
|
queryset = ProjectionDefault.objects.all()
|
||||||
}
|
|
||||||
)
|
def check_view_permissions(self):
|
||||||
|
"""
|
||||||
|
Returns True if the user has required permissions.
|
||||||
|
"""
|
||||||
|
if self.action in ("list", "retrieve"):
|
||||||
|
result = self.get_access_permissions().check_permissions(self.request.user)
|
||||||
|
elif self.action in ("create", "partial_update", "update", "destroy"):
|
||||||
|
result = has_perm(self.request.user, "core.can_manage_projector")
|
||||||
else:
|
else:
|
||||||
projector_instance = self.get_object()
|
result = False
|
||||||
projectiondefault.projector = projector_instance
|
return result
|
||||||
projectiondefault.save()
|
|
||||||
|
|
||||||
return Response()
|
|
||||||
|
|
||||||
|
|
||||||
class TagViewSet(ModelViewSet):
|
class TagViewSet(ModelViewSet):
|
||||||
|
Loading…
Reference in New Issue
Block a user