diff --git a/client/src/app/core/ui-services/projection-dialog.service.ts b/client/src/app/core/ui-services/projection-dialog.service.ts
index f59350bb0..0f44623c7 100644
--- a/client/src/app/core/ui-services/projection-dialog.service.ts
+++ b/client/src/app/core/ui-services/projection-dialog.service.ts
@@ -36,7 +36,6 @@ export class ProjectionDialogService {
} else {
descriptor = obj;
}
-
const dialogRef = this.dialog.open<
ProjectionDialogComponent,
ProjectorElementBuildDeskriptor,
diff --git a/client/src/app/shared/components/projection-dialog/projection-dialog.component.scss b/client/src/app/shared/components/projection-dialog/projection-dialog.component.scss
index 4f28b3d89..ed019cb6c 100644
--- a/client/src/app/shared/components/projection-dialog/projection-dialog.component.scss
+++ b/client/src/app/shared/components/projection-dialog/projection-dialog.component.scss
@@ -5,8 +5,13 @@ mat-dialog-content {
div.projectors {
padding: 15px 0;
+ mat-checkbox {
+ padding: 0 10px;
+ }
+
.right {
float: right;
+ padding-right: 10px;
}
}
}
diff --git a/client/src/app/shared/components/projector-button/projector-button.component.ts b/client/src/app/shared/components/projector-button/projector-button.component.ts
index f8fb91fcb..dad433ed8 100644
--- a/client/src/app/shared/components/projector-button/projector-button.component.ts
+++ b/client/src/app/shared/components/projector-button/projector-button.component.ts
@@ -24,7 +24,7 @@ export class ProjectorButtonComponent implements OnInit {
/**
* The object to project.
*/
- private _object: Projectable | ProjectorElementBuildDeskriptor;
+ private _object: Projectable | ProjectorElementBuildDeskriptor | null;
public get object(): Projectable | ProjectorElementBuildDeskriptor {
return this._object;
@@ -35,10 +35,7 @@ export class ProjectorButtonComponent implements OnInit {
if (isProjectable(obj) || isProjectorElementBuildDeskriptor(obj)) {
this._object = obj;
} else {
- console.error(
- 'Your model for the projectorbutton is not projectable and not' + 'a projectorElementBuildDescriptor!',
- obj
- );
+ this.object = null;
}
}
@@ -62,7 +59,9 @@ export class ProjectorButtonComponent implements OnInit {
*/
public onClick(event: Event): void {
event.stopPropagation();
- this.projectionDialogService.openProjectDialogFor(this.object);
+ if (this.object) {
+ this.projectionDialogService.openProjectDialogFor(this.object);
+ }
}
/**
diff --git a/client/src/app/site/agenda/components/agenda-list/agenda-list.component.html b/client/src/app/site/agenda/components/agenda-list/agenda-list.component.html
index 0a7cd0a25..d30c5acf2 100644
--- a/client/src/app/site/agenda/components/agenda-list/agenda-list.component.html
+++ b/client/src/app/site/agenda/components/agenda-list/agenda-list.component.html
@@ -28,6 +28,16 @@
+
+
+ Projector
+
+
+
+
+
+
+
Topic
diff --git a/client/src/app/site/agenda/components/agenda-list/agenda-list.component.ts b/client/src/app/site/agenda/components/agenda-list/agenda-list.component.ts
index c93caaab3..a5a97aaa4 100644
--- a/client/src/app/site/agenda/components/agenda-list/agenda-list.component.ts
+++ b/client/src/app/site/agenda/components/agenda-list/agenda-list.component.ts
@@ -54,6 +54,7 @@ export class AgendaListComponent extends ListViewBaseComponent impleme
* @param titleService Setting the browser tab title
* @param translate translations
* @param matSnackBar Shows errors and messages
+ * @param operator The current user
* @param route Angulars ActivatedRoute
* @param router Angulars router
* @param repo the agenda repository,
@@ -66,12 +67,12 @@ export class AgendaListComponent extends ListViewBaseComponent impleme
* @param filterService: service for filtering data
* @param agendaPdfService: service for preparing a pdf of the agenda
* @param pdfService: Service for exporting a pdf
- * @param operator the current user
*/
public constructor(
titleService: Title,
translate: TranslateService,
matSnackBar: MatSnackBar,
+ private operator: OperatorService,
private route: ActivatedRoute,
private router: Router,
private repo: ItemRepositoryService,
@@ -83,8 +84,7 @@ export class AgendaListComponent extends ListViewBaseComponent impleme
private csvExport: AgendaCsvExportService,
public filterService: AgendaFilterListService,
private agendaPdfService: AgendaPdfService,
- private pdfService: PdfDocumentService,
- private operator: OperatorService
+ private pdfService: PdfDocumentService
) {
super(titleService, translate, matSnackBar);
@@ -238,11 +238,14 @@ export class AgendaListComponent extends ListViewBaseComponent impleme
* @returns an array of strings with the dialogs to show
*/
public getColumnDefinition(): string[] {
- const list = this.vp.isMobile ? this.displayedColumnsMobile : this.displayedColumnsDesktop;
- if (this.isMultiSelect) {
- return ['selector'].concat(list);
+ let columns = this.vp.isMobile ? this.displayedColumnsMobile : this.displayedColumnsDesktop;
+ if (this.operator.hasPerms('core.can_manage_projector')) {
+ columns = ['projector'].concat(columns);
}
- return list;
+ if (this.isMultiSelect) {
+ columns = ['selector'].concat(columns);
+ }
+ return columns;
}
/**
diff --git a/client/src/app/site/agenda/models/view-topic.ts b/client/src/app/site/agenda/models/view-topic.ts
index 7ff96d190..1e02bd80e 100644
--- a/client/src/app/site/agenda/models/view-topic.ts
+++ b/client/src/app/site/agenda/models/view-topic.ts
@@ -96,7 +96,16 @@ export class ViewTopic extends BaseAgendaViewModel {
}
public getSlide(): ProjectorElementBuildDeskriptor {
- throw new Error('TODO');
+ return {
+ getBasicProjectorElement: () => ({
+ name: Topic.COLLECTIONSTRING,
+ id: this.id,
+ getIdentifiers: () => ['name', 'id']
+ }),
+ slideOptions: [],
+ projectionDefaultName: 'topics',
+ getTitle: () => this.getTitle()
+ };
}
public hasAttachments(): boolean {
diff --git a/client/src/app/site/assignments/models/view-assignment.ts b/client/src/app/site/assignments/models/view-assignment.ts
index fb829c399..5e5e3131e 100644
--- a/client/src/app/site/assignments/models/view-assignment.ts
+++ b/client/src/app/site/assignments/models/view-assignment.ts
@@ -80,6 +80,15 @@ export class ViewAssignment extends BaseAgendaViewModel {
}
public getSlide(): ProjectorElementBuildDeskriptor {
- throw new Error('TODO');
+ return {
+ getBasicProjectorElement: () => ({
+ name: Assignment.COLLECTIONSTRING,
+ id: this.id,
+ getIdentifiers: () => ['name', 'id']
+ }),
+ slideOptions: [],
+ projectionDefaultName: 'assignments',
+ getTitle: () => this.getTitle()
+ };
}
}
diff --git a/client/src/app/site/base/projectable.ts b/client/src/app/site/base/projectable.ts
index 0011317fc..182f6c58a 100644
--- a/client/src/app/site/base/projectable.ts
+++ b/client/src/app/site/base/projectable.ts
@@ -5,6 +5,7 @@ import { SlideOptions } from './slide-options';
export function isProjectorElementBuildDeskriptor(obj: any): obj is ProjectorElementBuildDeskriptor {
const deskriptor = obj;
return (
+ !!deskriptor &&
deskriptor.slideOptions !== undefined &&
deskriptor.getBasicProjectorElement !== undefined &&
deskriptor.getTitle !== undefined
@@ -23,7 +24,11 @@ export interface ProjectorElementBuildDeskriptor {
}
export function isProjectable(obj: any): obj is Projectable {
- return (obj).getSlide !== undefined;
+ if (obj) {
+ return (obj).getSlide !== undefined;
+ } else {
+ return false;
+ }
}
/**
diff --git a/client/src/app/slides/agenda/topic/topics-topic-slide-data.ts b/client/src/app/slides/agenda/topic/topics-topic-slide-data.ts
new file mode 100644
index 000000000..dfa23048b
--- /dev/null
+++ b/client/src/app/slides/agenda/topic/topics-topic-slide-data.ts
@@ -0,0 +1,4 @@
+export interface TopicsTopicSlideData {
+ title: string;
+ text: string;
+}
diff --git a/client/src/app/slides/agenda/topic/topics-topic-slide.component.html b/client/src/app/slides/agenda/topic/topics-topic-slide.component.html
new file mode 100644
index 000000000..1def91c3f
--- /dev/null
+++ b/client/src/app/slides/agenda/topic/topics-topic-slide.component.html
@@ -0,0 +1,5 @@
+
+
{{ data.data.title }}
+
+
+
diff --git a/client/src/app/slides/agenda/topic/topics-topic-slide.component.scss b/client/src/app/slides/agenda/topic/topics-topic-slide.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/client/src/app/slides/agenda/topic/topics-topic-slide.component.spec.ts b/client/src/app/slides/agenda/topic/topics-topic-slide.component.spec.ts
new file mode 100644
index 000000000..2edf21d5e
--- /dev/null
+++ b/client/src/app/slides/agenda/topic/topics-topic-slide.component.spec.ts
@@ -0,0 +1,26 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TopicsTopicSlideComponent } from './topics-topic-slide.component';
+import { E2EImportsModule } from 'e2e-imports.module';
+
+describe('TopicsTopicSlideComponent', () => {
+ let component: TopicsTopicSlideComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [E2EImportsModule],
+ declarations: [TopicsTopicSlideComponent]
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TopicsTopicSlideComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/client/src/app/slides/agenda/topic/topics-topic-slide.component.ts b/client/src/app/slides/agenda/topic/topics-topic-slide.component.ts
new file mode 100644
index 000000000..8267de3b7
--- /dev/null
+++ b/client/src/app/slides/agenda/topic/topics-topic-slide.component.ts
@@ -0,0 +1,14 @@
+import { Component } from '@angular/core';
+import { BaseSlideComponent } from 'app/slides/base-slide-component';
+import { TopicsTopicSlideData } from './topics-topic-slide-data';
+
+@Component({
+ selector: 'os-topic-slide',
+ templateUrl: './topics-topic-slide.component.html',
+ styleUrls: ['./topics-topic-slide.component.scss']
+})
+export class TopicsTopicSlideComponent extends BaseSlideComponent {
+ public constructor() {
+ super();
+ }
+}
diff --git a/client/src/app/slides/agenda/topic/topics-topic-slide.module.spec.ts b/client/src/app/slides/agenda/topic/topics-topic-slide.module.spec.ts
new file mode 100644
index 000000000..6661ad8f1
--- /dev/null
+++ b/client/src/app/slides/agenda/topic/topics-topic-slide.module.spec.ts
@@ -0,0 +1,13 @@
+import { TopicsTopicSlideModule } from './topics-topic-slide.module';
+
+describe('TopicsTopicSlideModule', () => {
+ let topicsTopicSlideModule: TopicsTopicSlideModule;
+
+ beforeEach(() => {
+ topicsTopicSlideModule = new TopicsTopicSlideModule();
+ });
+
+ it('should create an instance', () => {
+ expect(topicsTopicSlideModule).toBeTruthy();
+ });
+});
diff --git a/client/src/app/slides/agenda/topic/topics-topic-slide.module.ts b/client/src/app/slides/agenda/topic/topics-topic-slide.module.ts
new file mode 100644
index 000000000..1e30afea4
--- /dev/null
+++ b/client/src/app/slides/agenda/topic/topics-topic-slide.module.ts
@@ -0,0 +1,7 @@
+import { NgModule } from '@angular/core';
+
+import { makeSlideModule } from 'app/slides/base-slide-module';
+import { TopicsTopicSlideComponent } from './topics-topic-slide.component';
+
+@NgModule(makeSlideModule(TopicsTopicSlideComponent))
+export class TopicsTopicSlideModule {}
diff --git a/client/src/app/slides/all-slides.ts b/client/src/app/slides/all-slides.ts
index dddc056df..82ba5eaca 100644
--- a/client/src/app/slides/all-slides.ts
+++ b/client/src/app/slides/all-slides.ts
@@ -8,6 +8,16 @@ import { SlideManifest } from './slide-manifest';
* is no such thing as "dynamic update" in this case..
*/
export const allSlides: SlideManifest[] = [
+ {
+ slide: 'topics/topic',
+ path: 'topics/topic',
+ loadChildren: './slides/agenda/topic/topics-topic-slide.module#TopicsTopicSlideModule',
+ scaleable: true,
+ scrollable: true,
+ verboseName: 'Topic',
+ elementIdentifiers: ['name', 'id'],
+ canBeMappedToModel: true
+ },
{
slide: 'motions/motion',
path: 'motions/motion',
diff --git a/client/src/app/slides/users/user/users-user-slide.component.scss b/client/src/app/slides/users/user/users-user-slide.component.scss
index 3e34e6385..e69de29bb 100644
--- a/client/src/app/slides/users/user/users-user-slide.component.scss
+++ b/client/src/app/slides/users/user/users-user-slide.component.scss
@@ -1,9 +0,0 @@
-#outer {
- position: absolute;
- right: 0;
- top: 0;
- background-color: green;
- height: 30px;
- margin: 10px;
- z-index: 2;
-}
diff --git a/openslides/topics/projector.py b/openslides/topics/projector.py
index 6c6b6663f..43f7906a8 100644
--- a/openslides/topics/projector.py
+++ b/openslides/topics/projector.py
@@ -1,6 +1,10 @@
from typing import Any, Dict
-from ..utils.projector import AllData, register_projector_slide
+from ..utils.projector import (
+ AllData,
+ ProjectorElementException,
+ register_projector_slide,
+)
# Important: All functions have to be prune. This means, that thay can only
@@ -12,8 +16,22 @@ from ..utils.projector import AllData, register_projector_slide
def topic_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
"""
Topic slide.
+
+ The returned dict can contain the following fields:
+ * title
+ * text
"""
- return {"error": "TODO"}
+ topic_id = element.get("id")
+
+ if topic_id is None:
+ raise ProjectorElementException("id is required for topic slide")
+
+ try:
+ topic = all_data["topics/topic"][topic_id]
+ except KeyError:
+ raise ProjectorElementException(f"topic with id {topic_id} does not exist")
+
+ return {"title": topic["title"], "text": topic["text"]}
def register_projector_slides() -> None: