diff --git a/client/src/app/core/core-services/projector.service.ts b/client/src/app/core/core-services/projector.service.ts index c29343f90..550cc86d4 100644 --- a/client/src/app/core/core-services/projector.service.ts +++ b/client/src/app/core/core-services/projector.service.ts @@ -16,8 +16,8 @@ import { import { HttpService } from './http.service'; import { SlideManager } from 'app/slides/services/slide-manager.service'; import { BaseModel } from 'app/shared/models/base/base-model'; -import { BaseViewModel } from 'app/site/base/base-view-model'; import { ViewModelStoreService } from './view-model-store.service'; +import { BaseProjectableViewModel } from 'app/site/base/base-projectable-view-model'; /** * This service cares about Projectables being projected and manage all projection-related @@ -260,9 +260,15 @@ export class ProjectorService { * @param element The projector element * @returns the view model from the projector element */ - public getViewModelFromProjectorElement(element: IdentifiableProjectorElement): T { + public getViewModelFromProjectorElement( + element: IdentifiableProjectorElement + ): T { this.assertElementIsMappable(element); - return this.viewModelStore.get(element.name, element.id); + const viewModel = this.viewModelStore.get(element.name, element.id); + if (!isProjectable(viewModel)) { + console.error('The view model is not projectable', viewModel, element); + } + return viewModel; } /** diff --git a/client/src/app/core/repositories/motions/motion-repository.service.ts b/client/src/app/core/repositories/motions/motion-repository.service.ts index 233409a94..ffe2d1574 100644 --- a/client/src/app/core/repositories/motions/motion-repository.service.ts +++ b/client/src/app/core/repositories/motions/motion-repository.service.ts @@ -138,6 +138,7 @@ export class MotionRepositoryService extends BaseRepository return viewMotion.getTitle(); } }; + viewMotion.getProjectorTitle = viewMotion.getAgendaTitle; viewMotion.getAgendaTitleWithType = () => { // Append the verbose name only, if not the special format 'Motion ' is used. if (viewMotion.identifier) { diff --git a/client/src/app/core/repositories/projector/projectormessage-repository.service.spec.ts b/client/src/app/core/repositories/projector/projector-message-repository.service.spec.ts similarity index 85% rename from client/src/app/core/repositories/projector/projectormessage-repository.service.spec.ts rename to client/src/app/core/repositories/projector/projector-message-repository.service.spec.ts index cdd7c68c2..ac0b49fb7 100644 --- a/client/src/app/core/repositories/projector/projectormessage-repository.service.spec.ts +++ b/client/src/app/core/repositories/projector/projector-message-repository.service.spec.ts @@ -1,7 +1,7 @@ import { TestBed, inject } from '@angular/core/testing'; import { E2EImportsModule } from 'e2e-imports.module'; -import { ProjectorMessageRepositoryService } from './projectormessage-repository.service'; +import { ProjectorMessageRepositoryService } from './projector-message-repository.service'; describe('ProjectorMessageRepositoryService', () => { beforeEach(() => { diff --git a/client/src/app/core/repositories/projector/projectormessage-repository.service.ts b/client/src/app/core/repositories/projector/projector-message-repository.service.ts similarity index 78% rename from client/src/app/core/repositories/projector/projectormessage-repository.service.ts rename to client/src/app/core/repositories/projector/projector-message-repository.service.ts index 86a2cc164..d8f90f779 100644 --- a/client/src/app/core/repositories/projector/projectormessage-repository.service.ts +++ b/client/src/app/core/repositories/projector/projector-message-repository.service.ts @@ -4,9 +4,10 @@ import { BaseRepository } from '../base-repository'; import { Identifiable } from 'app/shared/models/base/identifiable'; import { CollectionStringMapperService } from '../../core-services/collectionStringMapper.service'; import { ProjectorMessage } from 'app/shared/models/core/projector-message'; -import { ViewProjectorMessage } from 'app/site/projector/models/view-projectormessage'; +import { ViewProjectorMessage } from 'app/site/projector/models/view-projector-message'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { TranslateService } from '@ngx-translate/core'; +import { DataSendService } from 'app/core/core-services/data-send.service'; @Injectable({ providedIn: 'root' @@ -16,7 +17,8 @@ export class ProjectorMessageRepositoryService extends BaseRepository { - throw new Error('TODO'); + return await this.dataSend.createModel(message); } public async update(message: Partial, viewMessage: ViewProjectorMessage): Promise { - throw new Error('TODO'); + const update = viewMessage.projectormessage; + update.patchValues(message); + await this.dataSend.updateModel(update); } public async delete(viewMessage: ViewProjectorMessage): Promise { - throw new Error('TODO'); + await this.dataSend.deleteModel(viewMessage.projectormessage); } } diff --git a/client/src/app/shared/components/projection-dialog/projection-dialog.component.html b/client/src/app/shared/components/projection-dialog/projection-dialog.component.html index c648005af..6137ae627 100644 --- a/client/src/app/shared/components/projection-dialog/projection-dialog.component.html +++ b/client/src/app/shared/components/projection-dialog/projection-dialog.component.html @@ -1,13 +1,10 @@

- Project {{ projectorElementBuildDescriptor.getTitle() }}? - Project motion {{ projectorElementBuildDescriptor.getTitle() }}? + Project {{ projectorElementBuildDescriptor.getTitle() }}?

-
+ [ngClass]="isProjectedOn(projector) ? 'projected' : ''"> {{ projector.name | translate }} diff --git a/client/src/app/shared/components/projector/projector.component.html b/client/src/app/shared/components/projector/projector.component.html index f899c60ca..41a1b7646 100644 --- a/client/src/app/shared/components/projector/projector.component.html +++ b/client/src/app/shared/components/projector/projector.component.html @@ -13,7 +13,7 @@
-
+
diff --git a/client/src/app/shared/components/projector/projector.component.scss b/client/src/app/shared/components/projector/projector.component.scss index 5f8936b64..da9298595 100644 --- a/client/src/app/shared/components/projector/projector.component.scss +++ b/client/src/app/shared/components/projector/projector.component.scss @@ -51,14 +51,6 @@ } } } - .content { - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 50px; - right: 50px; - } #footer { position: fixed; diff --git a/client/src/app/shared/components/slide-container/slide-container.component.html b/client/src/app/shared/components/slide-container/slide-container.component.html index eeb146cf0..1f70a1ad3 100644 --- a/client/src/app/shared/components/slide-container/slide-container.component.html +++ b/client/src/app/shared/components/slide-container/slide-container.component.html @@ -1 +1,6 @@ -
+
+ +
diff --git a/client/src/app/shared/components/slide-container/slide-container.component.scss b/client/src/app/shared/components/slide-container/slide-container.component.scss index 2f5906446..ff8d831f2 100644 --- a/client/src/app/shared/components/slide-container/slide-container.component.scss +++ b/client/src/app/shared/components/slide-container/slide-container.component.scss @@ -1,6 +1,14 @@ #slide { - width: calc(100% - 100px); + width: 100%; + height: 100%; + + &.content { + width: calc(100% - 100px); + margin-left: 50px; + margin-right: 50px; + } } + ::ng-deep #slide { z-index: 5; height: 100%; diff --git a/client/src/app/shared/components/slide-container/slide-container.component.ts b/client/src/app/shared/components/slide-container/slide-container.component.ts index 43759d1d1..31126fa46 100644 --- a/client/src/app/shared/components/slide-container/slide-container.component.ts +++ b/client/src/app/shared/components/slide-container/slide-container.component.ts @@ -88,7 +88,7 @@ export class SlideContainerComponent extends BaseComponent { /** * The current slideoptions. */ - private slideOptions: SlideOptions = { scaleable: false, scrollable: false }; + public slideOptions: SlideOptions = { scaleable: false, scrollable: false }; /** * Styles for scaling and scrolling. diff --git a/client/src/app/shared/utils/strip-html-tags.ts b/client/src/app/shared/utils/strip-html-tags.ts new file mode 100644 index 000000000..d7a62b614 --- /dev/null +++ b/client/src/app/shared/utils/strip-html-tags.ts @@ -0,0 +1,11 @@ +/** + * Helper to remove html tags from a string. + * CAUTION: It is just a basic "don't show distracting html tags in a + * preview", not an actual tested sanitizer! + * + * @param inputString + */ +export function stripHtmlTags(inputString: string): string { + const regexp = new RegExp(/<[^ ][^<>]*(>|$)/g); + return inputString.replace(regexp, '').trim(); +} diff --git a/client/src/app/site/agenda/components/agenda-import-list/agenda-import-list.component.ts b/client/src/app/site/agenda/components/agenda-import-list/agenda-import-list.component.ts index b96cdd19f..eaf390bcf 100644 --- a/client/src/app/site/agenda/components/agenda-import-list/agenda-import-list.component.ts +++ b/client/src/app/site/agenda/components/agenda-import-list/agenda-import-list.component.ts @@ -10,6 +10,7 @@ import { DurationService } from 'app/core/ui-services/duration.service'; import { FileExportService } from 'app/core/ui-services/file-export.service'; import { itemVisibilityChoices } from 'app/shared/models/agenda/item'; import { ViewCreateTopic } from '../../models/view-create-topic'; +import { stripHtmlTags } from 'app/shared/utils/strip-html-tags'; /** * Component for the agenda import list view. @@ -59,9 +60,9 @@ export class AgendaImportListComponent extends BaseImportListComponent 50) { - return this.stripHtmlTags(input.substring(0, 47)) + '...'; + return stripHtmlTags(input.substring(0, 47)) + '...'; } - return this.stripHtmlTags(input); + return stripHtmlTags(input); } /** @@ -77,28 +78,15 @@ export class AgendaImportListComponent extends BaseImportListComponent]*(>|$)/g); - return inputString.replace(regexp, '').trim(); - } - /** * Triggers an example csv download */ diff --git a/client/src/app/site/base/base-projectable-view-model.ts b/client/src/app/site/base/base-projectable-view-model.ts index 3911fa849..52785577a 100644 --- a/client/src/app/site/base/base-projectable-view-model.ts +++ b/client/src/app/site/base/base-projectable-view-model.ts @@ -6,4 +6,11 @@ import { BaseViewModel } from './base-view-model'; */ export abstract class BaseProjectableViewModel extends BaseViewModel implements Projectable { public abstract getSlide(): ProjectorElementBuildDeskriptor; + + /** + * @returns the projector title used for managing projector elements. + */ + public getProjectorTitle = () => { + return this.getTitle(); + }; } diff --git a/client/src/app/site/motions/components/motion-import-list/motion-import-list.component.ts b/client/src/app/site/motions/components/motion-import-list/motion-import-list.component.ts index e4e361548..f6f5a5f84 100644 --- a/client/src/app/site/motions/components/motion-import-list/motion-import-list.component.ts +++ b/client/src/app/site/motions/components/motion-import-list/motion-import-list.component.ts @@ -8,6 +8,7 @@ import { BaseImportListComponent } from 'app/site/base/base-import-list'; import { MotionCsvExportService } from '../../services/motion-csv-export.service'; import { MotionImportService } from '../../services/motion-import.service'; import { ViewMotion } from '../../models/view-motion'; +import { stripHtmlTags } from 'app/shared/utils/strip-html-tags'; /** * Component for the motion import list view. @@ -43,9 +44,9 @@ export class MotionImportListComponent extends BaseImportListComponent 50) { - return this.stripHtmlTags(input.substring(0, 47)) + '...'; + return stripHtmlTags(input.substring(0, 47)) + '...'; } - return this.stripHtmlTags(input); + return stripHtmlTags(input); } /** @@ -56,26 +57,15 @@ export class MotionImportListComponent extends BaseImportListComponent]*(>|$)/g); - return inputString.replace(regexp, '').trim(); - } - /** * Triggers an example csv download */ diff --git a/client/src/app/site/motions/components/statute-paragraph-list/statute-import-list/statute-import-list.component.ts b/client/src/app/site/motions/components/statute-paragraph-list/statute-import-list/statute-import-list.component.ts index cf06e9f07..f50dd3971 100644 --- a/client/src/app/site/motions/components/statute-paragraph-list/statute-import-list/statute-import-list.component.ts +++ b/client/src/app/site/motions/components/statute-paragraph-list/statute-import-list/statute-import-list.component.ts @@ -7,6 +7,7 @@ import { BaseImportListComponent } from 'app/site/base/base-import-list'; import { ViewStatuteParagraph } from 'app/site/motions/models/view-statute-paragraph'; import { StatuteImportService } from 'app/site/motions/services/statute-import.service'; import { StatuteCsvExportService } from 'app/site/motions/services/statute-csv-export.service'; +import { stripHtmlTags } from 'app/shared/utils/strip-html-tags'; /** * Component for the statute paragraphs import list view. @@ -42,9 +43,9 @@ export class StatuteImportListComponent extends BaseImportListComponent 50) { - return this.stripHtmlTags(input.substring(0, 47)) + '...'; + return stripHtmlTags(input.substring(0, 47)) + '...'; } - return this.stripHtmlTags(input); + return stripHtmlTags(input); } /** @@ -55,26 +56,15 @@ export class StatuteImportListComponent extends BaseImportListComponent]*(>|$)/g); - return inputString.replace(regexp, '').trim(); - } - /** * Triggers an example csv download */ diff --git a/client/src/app/site/motions/models/view-motion.ts b/client/src/app/site/motions/models/view-motion.ts index 76ec1f50d..14bc08797 100644 --- a/client/src/app/site/motions/models/view-motion.ts +++ b/client/src/app/site/motions/models/view-motion.ts @@ -580,7 +580,7 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable { } ], projectionDefaultName: 'motions', - getTitle: () => this.identifier + getTitle: this.getAgendaTitle }; } diff --git a/client/src/app/site/projector/components/countdown-list/countdown-list.component.ts b/client/src/app/site/projector/components/countdown-list/countdown-list.component.ts index 4e644cfeb..e4f29b0cc 100644 --- a/client/src/app/site/projector/components/countdown-list/countdown-list.component.ts +++ b/client/src/app/site/projector/components/countdown-list/countdown-list.component.ts @@ -1,12 +1,12 @@ import { Component, OnInit } from '@angular/core'; import { Title } from '@angular/platform-browser'; +import { MatSnackBar } from '@angular/material'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { TranslateService } from '@ngx-translate/core'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { PromptService } from 'app/core/ui-services/prompt.service'; import { BaseViewComponent } from '../../../base/base-view'; -import { MatSnackBar } from '@angular/material'; import { ViewCountdown } from '../../models/view-countdown'; import { CountdownRepositoryService } from 'app/core/repositories/projector/countdown-repository.service'; import { Countdown } from 'app/shared/models/core/countdown'; diff --git a/client/src/app/site/projector/components/projector-detail/projector-detail.component.html b/client/src/app/site/projector/components/projector-detail/projector-detail.component.html index c03a20aac..a60d8c9bd 100644 --- a/client/src/app/site/projector/components/projector-detail/projector-detail.component.html +++ b/client/src/app/site/projector/components/projector-detail/projector-detail.component.html @@ -7,11 +7,14 @@
@@ -75,7 +78,7 @@

Countdowns -

@@ -92,16 +95,16 @@

Messages -

- + - Message {{ i + 1 }} + {{ message.getPreview(40) }}
diff --git a/client/src/app/site/projector/components/projector-detail/projector-detail.component.ts b/client/src/app/site/projector/components/projector-detail/projector-detail.component.ts index e3e6707ac..f3bf25e16 100644 --- a/client/src/app/site/projector/components/projector-detail/projector-detail.component.ts +++ b/client/src/app/site/projector/components/projector-detail/projector-detail.component.ts @@ -16,8 +16,8 @@ import { moveItemInArray, CdkDragDrop } from '@angular/cdk/drag-drop'; import { ProjectorElement } from 'app/shared/models/core/projector'; import { SlideManager } from 'app/slides/services/slide-manager.service'; import { CountdownRepositoryService } from 'app/core/repositories/projector/countdown-repository.service'; -import { ProjectorMessageRepositoryService } from 'app/core/repositories/projector/projectormessage-repository.service'; -import { ViewProjectorMessage } from 'app/site/projector/models/view-projectormessage'; +import { ProjectorMessageRepositoryService } from 'app/core/repositories/projector/projector-message-repository.service'; +import { ViewProjectorMessage } from 'app/site/projector/models/view-projector-message'; import { ViewCountdown } from 'app/site/projector/models/view-countdown'; import { Projectable } from 'app/site/base/projectable'; import { CurrentListOfSpeakersSlideService } from '../../services/current-list-of-of-speakers-slide.service'; @@ -121,7 +121,7 @@ export class ProjectorDetailComponent extends BaseViewComponent implements OnIni const idElement = this.slideManager.getIdentifialbeProjectorElement(element); const viewModel = this.projectorService.getViewModelFromProjectorElement(idElement); if (viewModel) { - return viewModel.getTitle(); + return viewModel.getProjectorTitle(); } } diff --git a/client/src/app/site/projector/components/projector-list/projector-list.component.html b/client/src/app/site/projector/components/projector-list/projector-list.component.html index c132acc69..7eba4a8aa 100644 --- a/client/src/app/site/projector/components/projector-list/projector-list.component.html +++ b/client/src/app/site/projector/components/projector-list/projector-list.component.html @@ -111,12 +111,12 @@
- - + diff --git a/client/src/app/site/projector/components/projector-message-list/projector-message-list.component.html b/client/src/app/site/projector/components/projector-message-list/projector-message-list.component.html new file mode 100644 index 000000000..b5781f9f2 --- /dev/null +++ b/client/src/app/site/projector/components/projector-message-list/projector-message-list.component.html @@ -0,0 +1,83 @@ + + +
+

Messages

+
+
+ +
+ + New message + +
+

+ +

+
+
+ + + + +
+ + + + + + + +
+
+ +
+
+ {{ message.getPreview() }} +
+
+ +
+
+
+
Edit message
+

+ +

+
+ +
+
No message
+
+ + + + + + +
+
+ + + +
No messages
+
+
diff --git a/client/src/app/site/projector/components/projector-message-list/projector-message-list.component.scss b/client/src/app/site/projector/components/projector-message-list/projector-message-list.component.scss new file mode 100644 index 000000000..6aaff8f85 --- /dev/null +++ b/client/src/app/site/projector/components/projector-message-list/projector-message-list.component.scss @@ -0,0 +1,42 @@ +.head-spacer { + width: 100%; + height: 60px; + line-height: 60px; + text-align: right; + background: white; /* TODO: remove this and replace with theme */ + border-bottom: 1px solid rgba(0, 0, 0, 0.12); +} + +mat-card { + margin-bottom: 20px; +} + +.header-container { + display: grid; + grid-template-rows: auto; + grid-template-columns: 40px 1fr; + width: 100%; + + > div { + grid-row-start: 1; + grid-row-end: span 1; + grid-column-end: span 2; + } + + .header-projector-button { + grid-column-start: 1; + } + + .header-name { + grid-column-start: 2; + padding: 10px; + } +} + +.message { + text-align: center; + + ::ng-deep p { + margin: 0 0 10px; + } +} diff --git a/client/src/app/site/projector/components/projectormessage-list/projectormessage-list.component.spec.ts b/client/src/app/site/projector/components/projector-message-list/projector-message-list.component.spec.ts similarity index 90% rename from client/src/app/site/projector/components/projectormessage-list/projectormessage-list.component.spec.ts rename to client/src/app/site/projector/components/projector-message-list/projector-message-list.component.spec.ts index d9ed47bcc..4df9a213c 100644 --- a/client/src/app/site/projector/components/projectormessage-list/projectormessage-list.component.spec.ts +++ b/client/src/app/site/projector/components/projector-message-list/projector-message-list.component.spec.ts @@ -1,7 +1,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { E2EImportsModule } from 'e2e-imports.module'; -import { ProjectorMessageListComponent } from './projectormessage-list.component'; +import { ProjectorMessageListComponent } from './projector-message-list.component'; describe('CountdownListComponent', () => { let component: ProjectorMessageListComponent; diff --git a/client/src/app/site/projector/components/projector-message-list/projector-message-list.component.ts b/client/src/app/site/projector/components/projector-message-list/projector-message-list.component.ts new file mode 100644 index 000000000..f72847bf8 --- /dev/null +++ b/client/src/app/site/projector/components/projector-message-list/projector-message-list.component.ts @@ -0,0 +1,192 @@ +import { Component, OnInit } from '@angular/core'; +import { Title, SafeHtml, DomSanitizer } from '@angular/platform-browser'; +import { MatSnackBar } from '@angular/material'; +import { FormGroup, FormBuilder } from '@angular/forms'; + +import { TranslateService } from '@ngx-translate/core'; + +import { BaseViewComponent } from '../../../base/base-view'; +import { ProjectorMessage } from 'app/shared/models/core/projector-message'; +import { ViewProjectorMessage } from '../../models/view-projector-message'; +import { ProjectorMessageRepositoryService } from 'app/core/repositories/projector/projector-message-repository.service'; +import { PromptService } from 'app/core/ui-services/prompt.service'; + +/** + * List view for the projector messages. + */ +@Component({ + selector: 'os-projector-message-list', + templateUrl: './projector-message-list.component.html', + styleUrls: ['./projector-message-list.component.scss'] +}) +export class ProjectorMessageListComponent extends BaseViewComponent implements OnInit { + public messageToCreate: ProjectorMessage | null; + + /** + * Source of the Data + */ + public messages: ViewProjectorMessage[] = []; + + /** + * The current focussed formgroup + */ + public updateForm: FormGroup; + + public createForm: FormGroup; + + public openId: number | null; + public editId: number | null; + + /** + */ + public constructor( + titleService: Title, + translate: TranslateService, + matSnackBar: MatSnackBar, + private repo: ProjectorMessageRepositoryService, + private formBuilder: FormBuilder, + private promptService: PromptService, + private santinizer: DomSanitizer + ) { + super(titleService, translate, matSnackBar); + + const form = { + message: [''] + }; + this.createForm = this.formBuilder.group(form); + this.updateForm = this.formBuilder.group(form); + } + + /** + * Init function. + * + * Sets the title and gets/observes messages from DataStore + */ + public ngOnInit(): void { + super.setTitle('Messages'); + this.messages = this.repo.getViewModelList(); + this.repo.getViewModelListObservable().subscribe(messages => (this.messages = messages)); + } + + public getSafeMessage(message: ViewProjectorMessage): SafeHtml { + return this.santinizer.bypassSecurityTrustHtml(message.message); + } + + /** + * Add a new message. + */ + public onPlusButton(): void { + if (!this.messageToCreate) { + this.createForm.reset(); + this.createForm.setValue({ + message: '' + }); + this.messageToCreate = new ProjectorMessage(); + } + } + + /** + * Handler when clicking on create to create a new statute paragraph + */ + public create(): void { + if (this.createForm.valid) { + this.messageToCreate.patchValues(this.createForm.value as ProjectorMessage); + this.repo.create(this.messageToCreate).then(() => { + this.messageToCreate = null; + }, this.raiseError); + } + } + + /** + * Executed on edit button + * @param message + */ + public onEditButton(message: ViewProjectorMessage): void { + this.editId = message.id; + + this.updateForm.setValue({ + message: message.message + }); + } + + /** + * Saves the message + * @param message The message to save + */ + public onSaveButton(message: ViewProjectorMessage): void { + if (this.updateForm.valid) { + this.repo.update(this.updateForm.value as Partial, message).then(() => { + this.openId = this.editId = null; + }, this.raiseError); + } + } + + /** + * Is executed, when the delete button is pressed + * + * @param message The message to delete + */ + public async onDeleteButton(message: ViewProjectorMessage): Promise { + const content = this.translate.instant('Delete this message?'); + if (await this.promptService.open('Are you sure?', content)) { + this.repo.delete(message).then(() => (this.openId = this.editId = null), this.raiseError); + } + } + + /** + * Is executed when a mat-extension-panel is closed + * + * @param message the message in the panel + */ + public panelClosed(message: ViewProjectorMessage): void { + this.openId = null; + if (this.editId) { + this.onSaveButton(message); + } + } + + /** + * clicking Shift and Enter will save automatically + * clicking Escape will cancel the process + * + * @param event has the code + */ + public onKeyDownCreate(event: KeyboardEvent): void { + if (event.key === 'Enter' && event.shiftKey) { + this.create(); + } + if (event.key === 'Escape') { + this.onCancelCreate(); + } + } + + /** + * Cancels the current form action + */ + public onCancelCreate(): void { + this.messageToCreate = null; + } + + /** + * clicking Shift and Enter will save automatically + * clicking Escape will cancel the process + * + * @param event has the code + */ + public onKeyDownUpdate(event: KeyboardEvent): void { + if (event.key === 'Enter' && event.shiftKey) { + const message = this.messages.find(x => x.id === this.editId); + this.onSaveButton(message); + } + if (event.key === 'Escape') { + this.onCancelUpdate(); + } + } + + /** + * Cancels the current form action + */ + public onCancelUpdate(): void { + this.editId = null; + } +} diff --git a/client/src/app/site/projector/components/projectormessage-list/projectormessage-list.component.html b/client/src/app/site/projector/components/projectormessage-list/projectormessage-list.component.html deleted file mode 100644 index 4eb85dff5..000000000 --- a/client/src/app/site/projector/components/projectormessage-list/projectormessage-list.component.html +++ /dev/null @@ -1,9 +0,0 @@ - - -
-

Messages

-
-
- -
-

TODO

diff --git a/client/src/app/site/projector/components/projectormessage-list/projectormessage-list.component.scss b/client/src/app/site/projector/components/projectormessage-list/projectormessage-list.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/src/app/site/projector/components/projectormessage-list/projectormessage-list.component.ts b/client/src/app/site/projector/components/projectormessage-list/projectormessage-list.component.ts deleted file mode 100644 index db9bb9b92..000000000 --- a/client/src/app/site/projector/components/projectormessage-list/projectormessage-list.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { Title } from '@angular/platform-browser'; - -import { TranslateService } from '@ngx-translate/core'; - -import { BaseViewComponent } from '../../../base/base-view'; -import { MatSnackBar } from '@angular/material'; - -/** - * List view for the projector messages. - */ -@Component({ - selector: 'os-projectormessage-list', - templateUrl: './projectormessage-list.component.html', - styleUrls: ['./projectormessage-list.component.scss'] -}) -export class ProjectorMessageListComponent extends BaseViewComponent implements OnInit { - public constructor(titleService: Title, translate: TranslateService, matSnackBar: MatSnackBar) { - super(titleService, translate, matSnackBar); - } - - /** - * Init function. - * - * Sets the title and gets/observes messages from DataStore - */ - public ngOnInit(): void { - super.setTitle('Messages'); - } - - public onPlusButton(): void {} -} diff --git a/client/src/app/site/projector/models/view-projectormessage.ts b/client/src/app/site/projector/models/view-projector-message.ts similarity index 74% rename from client/src/app/site/projector/models/view-projectormessage.ts rename to client/src/app/site/projector/models/view-projector-message.ts index 3c4a2711c..0cebcef0b 100644 --- a/client/src/app/site/projector/models/view-projectormessage.ts +++ b/client/src/app/site/projector/models/view-projector-message.ts @@ -2,22 +2,23 @@ import { BaseProjectableViewModel } from 'app/site/base/base-projectable-view-mo import { ProjectorElementBuildDeskriptor } from 'app/site/base/projectable'; import { ProjectorMessage } from 'app/shared/models/core/projector-message'; import { BaseViewModel } from 'app/site/base/base-view-model'; +import { stripHtmlTags } from 'app/shared/utils/strip-html-tags'; export class ViewProjectorMessage extends BaseProjectableViewModel { public static COLLECTIONSTRING = ProjectorMessage.COLLECTIONSTRING; private _message: ProjectorMessage; - public get projctormessage(): ProjectorMessage { + public get projectormessage(): ProjectorMessage { return this._message; } public get id(): number { - return this.projctormessage.id; + return this.projectormessage.id; } public get message(): string { - return this.projctormessage.message; + return this.projectormessage.message; } /** @@ -49,4 +50,13 @@ export class ViewProjectorMessage extends BaseProjectableViewModel { getTitle: () => this.getTitle() }; } + + public getPreview(maxLength: number = 100): string { + const html = stripHtmlTags(this.message); + if (html.length > maxLength) { + return html.substring(0, maxLength) + ' ...'; + } else { + return html; + } + } } diff --git a/client/src/app/site/projector/projector-routing.module.ts b/client/src/app/site/projector/projector-routing.module.ts index 28899efd5..e44692588 100644 --- a/client/src/app/site/projector/projector-routing.module.ts +++ b/client/src/app/site/projector/projector-routing.module.ts @@ -3,7 +3,7 @@ import { Routes, RouterModule } from '@angular/router'; import { ProjectorListComponent } from './components/projector-list/projector-list.component'; import { ProjectorDetailComponent } from './components/projector-detail/projector-detail.component'; import { CountdownListComponent } from './components/countdown-list/countdown-list.component'; -import { ProjectorMessageListComponent } from './components/projectormessage-list/projectormessage-list.component'; +import { ProjectorMessageListComponent } from './components/projector-message-list/projector-message-list.component'; const routes: Routes = [ { diff --git a/client/src/app/site/projector/projector.config.ts b/client/src/app/site/projector/projector.config.ts index dec57c983..010d9a135 100644 --- a/client/src/app/site/projector/projector.config.ts +++ b/client/src/app/site/projector/projector.config.ts @@ -4,10 +4,10 @@ import { Countdown } from 'app/shared/models/core/countdown'; import { ProjectorMessage } from 'app/shared/models/core/projector-message'; import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service'; import { CountdownRepositoryService } from 'app/core/repositories/projector/countdown-repository.service'; -import { ProjectorMessageRepositoryService } from 'app/core/repositories/projector/projectormessage-repository.service'; +import { ProjectorMessageRepositoryService } from 'app/core/repositories/projector/projector-message-repository.service'; import { ViewProjector } from './models/view-projector'; import { ViewCountdown } from './models/view-countdown'; -import { ViewProjectorMessage } from './models/view-projectormessage'; +import { ViewProjectorMessage } from './models/view-projector-message'; export const ProjectorAppConfig: AppConfig = { name: 'projector', diff --git a/client/src/app/site/projector/projector.module.ts b/client/src/app/site/projector/projector.module.ts index e03749bae..ced2fd5c3 100644 --- a/client/src/app/site/projector/projector.module.ts +++ b/client/src/app/site/projector/projector.module.ts @@ -9,7 +9,7 @@ import { ClockSlideService } from './services/clock-slide.service'; import { ProjectorDataService } from './services/projector-data.service'; import { CurrentListOfSpeakersSlideService } from './services/current-list-of-of-speakers-slide.service'; import { CountdownListComponent } from './components/countdown-list/countdown-list.component'; -import { ProjectorMessageListComponent } from './components/projectormessage-list/projectormessage-list.component'; +import { ProjectorMessageListComponent } from './components/projector-message-list/projector-message-list.component'; @NgModule({ providers: [ClockSlideService, ProjectorDataService, CurrentListOfSpeakersSlideService], diff --git a/client/src/app/slides/all-slides.ts b/client/src/app/slides/all-slides.ts index 82ba5eaca..196afd63a 100644 --- a/client/src/app/slides/all-slides.ts +++ b/client/src/app/slides/all-slides.ts @@ -41,7 +41,7 @@ export const allSlides: SlideManifest[] = [ { slide: 'core/clock', path: 'core/clock', - loadChildren: './slides/core/clock/core-clock-slide.module#CoreClockSlideModule', + loadChildren: './slides/core/clock/clock-slide.module#ClockSlideModule', scaleable: false, scrollable: false, verboseName: 'Clock', @@ -51,13 +51,23 @@ export const allSlides: SlideManifest[] = [ { slide: 'core/countdown', path: 'core/countdown', - loadChildren: './slides/core/countdown/core-countdown-slide.module#CoreCountdownSlideModule', + loadChildren: './slides/core/countdown/countdown-slide.module#CountdownSlideModule', scaleable: false, scrollable: false, verboseName: 'Countdown', elementIdentifiers: ['name', 'id'], canBeMappedToModel: true }, + { + slide: 'core/projector-message', + path: 'core/projector-message', + loadChildren: './slides/core/projector-message/projector-message-slide.module#ProjectorMessageSlideModule', + scaleable: false, + scrollable: false, + verboseName: 'Message', + elementIdentifiers: ['name', 'id'], + canBeMappedToModel: true + }, { slide: 'agenda/current-list-of-speakers', path: 'agenda/current-list-of-speakers', @@ -79,5 +89,15 @@ export const allSlides: SlideManifest[] = [ verboseName: 'Current list of speakers overlay', elementIdentifiers: ['name', 'id'], canBeMappedToModel: false + }, + { + slide: 'assignments/assignment', + path: 'assignments/assignment', + loadChildren: './slides/assignments/assignment/assignment-slide.module#AssignmentSlideModule', + scaleable: true, + scrollable: true, + verboseName: 'Election', + elementIdentifiers: ['name', 'id'], + canBeMappedToModel: true } ]; diff --git a/client/src/app/slides/assignments/assignment/assignment-slide-data.ts b/client/src/app/slides/assignments/assignment/assignment-slide-data.ts new file mode 100644 index 000000000..f7ac4994e --- /dev/null +++ b/client/src/app/slides/assignments/assignment/assignment-slide-data.ts @@ -0,0 +1,3 @@ +export interface AssignmentSlideData { + user: string; +} diff --git a/client/src/app/slides/assignments/assignment/assignment-slide.component.html b/client/src/app/slides/assignments/assignment/assignment-slide.component.html new file mode 100644 index 000000000..edc11e288 --- /dev/null +++ b/client/src/app/slides/assignments/assignment/assignment-slide.component.html @@ -0,0 +1,3 @@ +
+

TODO

+
diff --git a/client/src/app/site/config/components/config-field/config-field.component.spec.ts b/client/src/app/slides/assignments/assignment/assignment-slide.component.scss similarity index 100% rename from client/src/app/site/config/components/config-field/config-field.component.spec.ts rename to client/src/app/slides/assignments/assignment/assignment-slide.component.scss diff --git a/client/src/app/slides/core/countdown/core-countdown-slide.component.spec.ts b/client/src/app/slides/assignments/assignment/assignment-slide.component.spec.ts similarity index 57% rename from client/src/app/slides/core/countdown/core-countdown-slide.component.spec.ts rename to client/src/app/slides/assignments/assignment/assignment-slide.component.spec.ts index 387a6cdea..be74f8294 100644 --- a/client/src/app/slides/core/countdown/core-countdown-slide.component.spec.ts +++ b/client/src/app/slides/assignments/assignment/assignment-slide.component.spec.ts @@ -1,21 +1,21 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { CoreCountdownSlideComponent } from './core-countdown-slide.component'; +import { AssignmentSlideComponent } from './assignment-slide.component'; import { E2EImportsModule } from '../../../../e2e-imports.module'; -describe('CoreCountdownSlideComponent', () => { - let component: CoreCountdownSlideComponent; - let fixture: ComponentFixture; +describe('AssignmentSlideComponent', () => { + let component: AssignmentSlideComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [E2EImportsModule], - declarations: [CoreCountdownSlideComponent] + declarations: [AssignmentSlideComponent] }).compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(CoreCountdownSlideComponent); + fixture = TestBed.createComponent(AssignmentSlideComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/client/src/app/slides/assignments/assignment/assignment-slide.component.ts b/client/src/app/slides/assignments/assignment/assignment-slide.component.ts new file mode 100644 index 000000000..bdb728c38 --- /dev/null +++ b/client/src/app/slides/assignments/assignment/assignment-slide.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; + +import { BaseSlideComponent } from 'app/slides/base-slide-component'; +import { AssignmentSlideData } from './assignment-slide-data'; + +@Component({ + selector: 'os-assignment-slide', + templateUrl: './assignment-slide.component.html', + styleUrls: ['./assignment-slide.component.scss'] +}) +export class AssignmentSlideComponent extends BaseSlideComponent { + public constructor() { + super(); + } +} diff --git a/client/src/app/slides/assignments/assignment/assignment-slide.module.spec.ts b/client/src/app/slides/assignments/assignment/assignment-slide.module.spec.ts new file mode 100644 index 000000000..fed92d424 --- /dev/null +++ b/client/src/app/slides/assignments/assignment/assignment-slide.module.spec.ts @@ -0,0 +1,13 @@ +import { AssignmentSlideModule } from './assignment-slide.module'; + +describe('UsersUserSlideModule', () => { + let usersUserSlideModule: AssignmentSlideModule; + + beforeEach(() => { + usersUserSlideModule = new AssignmentSlideModule(); + }); + + it('should create an instance', () => { + expect(usersUserSlideModule).toBeTruthy(); + }); +}); diff --git a/client/src/app/slides/assignments/assignment/assignment-slide.module.ts b/client/src/app/slides/assignments/assignment/assignment-slide.module.ts new file mode 100644 index 000000000..31960a6b0 --- /dev/null +++ b/client/src/app/slides/assignments/assignment/assignment-slide.module.ts @@ -0,0 +1,7 @@ +import { NgModule } from '@angular/core'; + +import { makeSlideModule } from 'app/slides/base-slide-module'; +import { AssignmentSlideComponent } from './assignment-slide.component'; + +@NgModule(makeSlideModule(AssignmentSlideComponent)) +export class AssignmentSlideModule {} diff --git a/client/src/app/slides/core/clock/core-clock-slide.component.html b/client/src/app/slides/core/clock/clock-slide.component.html similarity index 100% rename from client/src/app/slides/core/clock/core-clock-slide.component.html rename to client/src/app/slides/core/clock/clock-slide.component.html diff --git a/client/src/app/slides/core/clock/core-clock-slide.component.scss b/client/src/app/slides/core/clock/clock-slide.component.scss similarity index 100% rename from client/src/app/slides/core/clock/core-clock-slide.component.scss rename to client/src/app/slides/core/clock/clock-slide.component.scss diff --git a/client/src/app/slides/core/clock/clock-slide.component.spec.ts b/client/src/app/slides/core/clock/clock-slide.component.spec.ts new file mode 100644 index 000000000..4324772f7 --- /dev/null +++ b/client/src/app/slides/core/clock/clock-slide.component.spec.ts @@ -0,0 +1,26 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ClockSlideComponent } from './clock-slide.component'; +import { E2EImportsModule } from '../../../../e2e-imports.module'; + +describe('ClockSlideComponent', () => { + let component: ClockSlideComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [E2EImportsModule], + declarations: [ClockSlideComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ClockSlideComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/client/src/app/slides/core/clock/core-clock-slide.component.ts b/client/src/app/slides/core/clock/clock-slide.component.ts similarity index 83% rename from client/src/app/slides/core/clock/core-clock-slide.component.ts rename to client/src/app/slides/core/clock/clock-slide.component.ts index f1e0727a3..6fa19005b 100644 --- a/client/src/app/slides/core/clock/core-clock-slide.component.ts +++ b/client/src/app/slides/core/clock/clock-slide.component.ts @@ -1,14 +1,16 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; -import { BaseSlideComponent } from 'app/slides/base-slide-component'; -import { ServertimeService } from 'app/core/core-services/servertime.service'; + import { Subscription } from 'rxjs'; +import { BaseSlideComponent } from 'app/slides/base-slide-component'; +import { ServertimeService } from 'app/core/core-services/servertime.service'; + @Component({ - selector: 'os-core-clock-slide', - templateUrl: './core-clock-slide.component.html', - styleUrls: ['./core-clock-slide.component.scss'] + selector: 'os-clock-slide', + templateUrl: './clock-slide.component.html', + styleUrls: ['./clock-slide.component.scss'] }) -export class CoreClockSlideComponent extends BaseSlideComponent<{}> implements OnInit, OnDestroy { +export class ClockSlideComponent extends BaseSlideComponent<{}> implements OnInit, OnDestroy { public time: string; private servertimeSubscription: Subscription | null = null; diff --git a/client/src/app/slides/core/clock/clock-slide.module.spec.ts b/client/src/app/slides/core/clock/clock-slide.module.spec.ts new file mode 100644 index 000000000..2525aad8c --- /dev/null +++ b/client/src/app/slides/core/clock/clock-slide.module.spec.ts @@ -0,0 +1,13 @@ +import { ClockSlideModule } from './clock-slide.module'; + +describe('ClockSlideModule', () => { + let clockSlideModule: ClockSlideModule; + + beforeEach(() => { + clockSlideModule = new ClockSlideModule(); + }); + + it('should create an instance', () => { + expect(clockSlideModule).toBeTruthy(); + }); +}); diff --git a/client/src/app/slides/core/clock/clock-slide.module.ts b/client/src/app/slides/core/clock/clock-slide.module.ts new file mode 100644 index 000000000..e72395584 --- /dev/null +++ b/client/src/app/slides/core/clock/clock-slide.module.ts @@ -0,0 +1,7 @@ +import { NgModule } from '@angular/core'; + +import { makeSlideModule } from 'app/slides/base-slide-module'; +import { ClockSlideComponent } from './clock-slide.component'; + +@NgModule(makeSlideModule(ClockSlideComponent)) +export class ClockSlideModule {} diff --git a/client/src/app/slides/core/clock/core-clock-slide.module.spec.ts b/client/src/app/slides/core/clock/core-clock-slide.module.spec.ts deleted file mode 100644 index 6a8c23c3c..000000000 --- a/client/src/app/slides/core/clock/core-clock-slide.module.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CoreClockSlideModule } from './core-clock-slide.module'; - -describe('CoreClockSlideModule', () => { - let coreClockSlideModule: CoreClockSlideModule; - - beforeEach(() => { - coreClockSlideModule = new CoreClockSlideModule(); - }); - - it('should create an instance', () => { - expect(coreClockSlideModule).toBeTruthy(); - }); -}); diff --git a/client/src/app/slides/core/clock/core-clock-slide.module.ts b/client/src/app/slides/core/clock/core-clock-slide.module.ts deleted file mode 100644 index 8fbd78589..000000000 --- a/client/src/app/slides/core/clock/core-clock-slide.module.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NgModule } from '@angular/core'; - -import { makeSlideModule } from 'app/slides/base-slide-module'; -import { CoreClockSlideComponent } from './core-clock-slide.component'; - -@NgModule(makeSlideModule(CoreClockSlideComponent)) -export class CoreClockSlideModule {} diff --git a/client/src/app/slides/core/countdown/core-countdown-slide-data.ts b/client/src/app/slides/core/countdown/core-countdown-slide-data.ts deleted file mode 100644 index b5e45a00f..000000000 --- a/client/src/app/slides/core/countdown/core-countdown-slide-data.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface CoreCountdownSlideData { - error: string; -} diff --git a/client/src/app/slides/core/countdown/core-countdown-slide.component.ts b/client/src/app/slides/core/countdown/core-countdown-slide.component.ts deleted file mode 100644 index 466e44046..000000000 --- a/client/src/app/slides/core/countdown/core-countdown-slide.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component } from '@angular/core'; -import { BaseSlideComponent } from 'app/slides/base-slide-component'; -import { CoreCountdownSlideData } from './core-countdown-slide-data'; - -@Component({ - selector: 'os-core-countdown-slide', - templateUrl: './core-countdown-slide.component.html', - styleUrls: ['./core-countdown-slide.component.scss'] -}) -export class CoreCountdownSlideComponent extends BaseSlideComponent { - public constructor() { - super(); - } -} diff --git a/client/src/app/slides/core/countdown/core-countdown-slide.module.spec.ts b/client/src/app/slides/core/countdown/core-countdown-slide.module.spec.ts deleted file mode 100644 index 7e56b05b0..000000000 --- a/client/src/app/slides/core/countdown/core-countdown-slide.module.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CoreCountdownSlideModule } from './core-countdown-slide.module'; - -describe('CoreCountdownSlideModule', () => { - let coreCountdownSlideModule: CoreCountdownSlideModule; - - beforeEach(() => { - coreCountdownSlideModule = new CoreCountdownSlideModule(); - }); - - it('should create an instance', () => { - expect(CoreCountdownSlideModule).toBeTruthy(); - }); -}); diff --git a/client/src/app/slides/core/countdown/core-countdown-slide.module.ts b/client/src/app/slides/core/countdown/core-countdown-slide.module.ts deleted file mode 100644 index c2c870f5e..000000000 --- a/client/src/app/slides/core/countdown/core-countdown-slide.module.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NgModule } from '@angular/core'; - -import { makeSlideModule } from 'app/slides/base-slide-module'; -import { CoreCountdownSlideComponent } from './core-countdown-slide.component'; - -@NgModule(makeSlideModule(CoreCountdownSlideComponent)) -export class CoreCountdownSlideModule {} diff --git a/client/src/app/slides/core/countdown/countdown-slide-data.ts b/client/src/app/slides/core/countdown/countdown-slide-data.ts new file mode 100644 index 000000000..ec46d6d0a --- /dev/null +++ b/client/src/app/slides/core/countdown/countdown-slide-data.ts @@ -0,0 +1,3 @@ +export interface CountdownSlideData { + error: string; +} diff --git a/client/src/app/slides/core/countdown/core-countdown-slide.component.html b/client/src/app/slides/core/countdown/countdown-slide.component.html similarity index 100% rename from client/src/app/slides/core/countdown/core-countdown-slide.component.html rename to client/src/app/slides/core/countdown/countdown-slide.component.html diff --git a/client/src/app/slides/core/countdown/core-countdown-slide.component.scss b/client/src/app/slides/core/countdown/countdown-slide.component.scss similarity index 100% rename from client/src/app/slides/core/countdown/core-countdown-slide.component.scss rename to client/src/app/slides/core/countdown/countdown-slide.component.scss diff --git a/client/src/app/slides/core/clock/core-clock-slide.component.spec.ts b/client/src/app/slides/core/countdown/countdown-slide.component.spec.ts similarity index 59% rename from client/src/app/slides/core/clock/core-clock-slide.component.spec.ts rename to client/src/app/slides/core/countdown/countdown-slide.component.spec.ts index 5db866409..41021de96 100644 --- a/client/src/app/slides/core/clock/core-clock-slide.component.spec.ts +++ b/client/src/app/slides/core/countdown/countdown-slide.component.spec.ts @@ -1,21 +1,21 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { CoreClockSlideComponent } from './core-clock-slide.component'; +import { CountdownSlideComponent } from './countdown-slide.component'; import { E2EImportsModule } from '../../../../e2e-imports.module'; -describe('CoreClockSlideComponent', () => { - let component: CoreClockSlideComponent; - let fixture: ComponentFixture; +describe('CountdownSlideComponent', () => { + let component: CountdownSlideComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [E2EImportsModule], - declarations: [CoreClockSlideComponent] + declarations: [CountdownSlideComponent] }).compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(CoreClockSlideComponent); + fixture = TestBed.createComponent(CountdownSlideComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/client/src/app/slides/core/countdown/countdown-slide.component.ts b/client/src/app/slides/core/countdown/countdown-slide.component.ts new file mode 100644 index 000000000..e9c9cfc54 --- /dev/null +++ b/client/src/app/slides/core/countdown/countdown-slide.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { BaseSlideComponent } from 'app/slides/base-slide-component'; +import { CountdownSlideData } from './countdown-slide-data'; + +@Component({ + selector: 'os-countdown-slide', + templateUrl: './countdown-slide.component.html', + styleUrls: ['./countdown-slide.component.scss'] +}) +export class CountdownSlideComponent extends BaseSlideComponent { + public constructor() { + super(); + } +} diff --git a/client/src/app/slides/core/countdown/countdown-slide.module.spec.ts b/client/src/app/slides/core/countdown/countdown-slide.module.spec.ts new file mode 100644 index 000000000..c7b159de1 --- /dev/null +++ b/client/src/app/slides/core/countdown/countdown-slide.module.spec.ts @@ -0,0 +1,13 @@ +import { CountdownSlideModule } from './countdown-slide.module'; + +describe('CountdownSlideModule', () => { + let countdownSlideModule: CountdownSlideModule; + + beforeEach(() => { + countdownSlideModule = new CountdownSlideModule(); + }); + + it('should create an instance', () => { + expect(countdownSlideModule).toBeTruthy(); + }); +}); diff --git a/client/src/app/slides/core/countdown/countdown-slide.module.ts b/client/src/app/slides/core/countdown/countdown-slide.module.ts new file mode 100644 index 000000000..47c4a42dc --- /dev/null +++ b/client/src/app/slides/core/countdown/countdown-slide.module.ts @@ -0,0 +1,7 @@ +import { NgModule } from '@angular/core'; + +import { makeSlideModule } from 'app/slides/base-slide-module'; +import { CountdownSlideComponent } from './countdown-slide.component'; + +@NgModule(makeSlideModule(CountdownSlideComponent)) +export class CountdownSlideModule {} diff --git a/client/src/app/slides/core/projector-message/projector-message-slide-data.ts b/client/src/app/slides/core/projector-message/projector-message-slide-data.ts new file mode 100644 index 000000000..2a99ccbb9 --- /dev/null +++ b/client/src/app/slides/core/projector-message/projector-message-slide-data.ts @@ -0,0 +1,3 @@ +export interface ProjectorMessageSlideData { + message: string; +} diff --git a/client/src/app/slides/core/projector-message/projector-message-slide.component.html b/client/src/app/slides/core/projector-message/projector-message-slide.component.html new file mode 100644 index 000000000..d5fb346ba --- /dev/null +++ b/client/src/app/slides/core/projector-message/projector-message-slide.component.html @@ -0,0 +1,5 @@ +
+
+
+
+
diff --git a/client/src/app/slides/core/projector-message/projector-message-slide.component.scss b/client/src/app/slides/core/projector-message/projector-message-slide.component.scss new file mode 100644 index 000000000..82ebb2aec --- /dev/null +++ b/client/src/app/slides/core/projector-message/projector-message-slide.component.scss @@ -0,0 +1,29 @@ +#background { + position: absolute; + left: 0; + top: 0; + background-color: rgba($color: #000000, $alpha: 0.5); + z-index: 10; + width: 100%; + height: 100%; + display: grid; + grid-template-rows: auto; + grid-template-columns: auto; + + #message { + align-self: center; + width: 80%; + text-align: center; + justify-self: center; + border-radius: 0.2em; + background: #ffffff; + font-size: 2.75em; + padding: 0.2em 0; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + min-height: 20px; + + ::ng-deep p { + margin: 0 0 10px; + } + } +} diff --git a/client/src/app/slides/core/projector-message/projector-message-slide.component.spec.ts b/client/src/app/slides/core/projector-message/projector-message-slide.component.spec.ts new file mode 100644 index 000000000..d5c77559e --- /dev/null +++ b/client/src/app/slides/core/projector-message/projector-message-slide.component.spec.ts @@ -0,0 +1,26 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { E2EImportsModule } from '../../../../e2e-imports.module'; +import { ProjectorMessageSlideComponent } from './projector-message-slide.component'; + +describe('ProjectorMessageSlideComponent', () => { + let component: ProjectorMessageSlideComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [E2EImportsModule], + declarations: [ProjectorMessageSlideComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ProjectorMessageSlideComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/client/src/app/slides/core/projector-message/projector-message-slide.component.ts b/client/src/app/slides/core/projector-message/projector-message-slide.component.ts new file mode 100644 index 000000000..f9350b6b3 --- /dev/null +++ b/client/src/app/slides/core/projector-message/projector-message-slide.component.ts @@ -0,0 +1,20 @@ +import { Component } from '@angular/core'; +import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; + +import { BaseSlideComponent } from 'app/slides/base-slide-component'; +import { ProjectorMessageSlideData } from './projector-message-slide-data'; + +@Component({ + selector: 'os-projector-message-slide', + templateUrl: './projector-message-slide.component.html', + styleUrls: ['./projector-message-slide.component.scss'] +}) +export class ProjectorMessageSlideComponent extends BaseSlideComponent { + public constructor(private sanitizer: DomSanitizer) { + super(); + } + + public trustHTML(html: string): SafeHtml { + return this.sanitizer.bypassSecurityTrustHtml(html); + } +} diff --git a/client/src/app/slides/core/projector-message/projector-message-slide.module.spec.ts b/client/src/app/slides/core/projector-message/projector-message-slide.module.spec.ts new file mode 100644 index 000000000..848289605 --- /dev/null +++ b/client/src/app/slides/core/projector-message/projector-message-slide.module.spec.ts @@ -0,0 +1,13 @@ +import { ProjectorMessageSlideModule } from './projector-message-slide.module'; + +describe('ProjectormessageSlideModule', () => { + let projectorMessageSlideModule: ProjectorMessageSlideModule; + + beforeEach(() => { + projectorMessageSlideModule = new ProjectorMessageSlideModule(); + }); + + it('should create an instance', () => { + expect(projectorMessageSlideModule).toBeTruthy(); + }); +}); diff --git a/client/src/app/slides/core/projector-message/projector-message-slide.module.ts b/client/src/app/slides/core/projector-message/projector-message-slide.module.ts new file mode 100644 index 000000000..c013b23a9 --- /dev/null +++ b/client/src/app/slides/core/projector-message/projector-message-slide.module.ts @@ -0,0 +1,7 @@ +import { NgModule } from '@angular/core'; + +import { makeSlideModule } from 'app/slides/base-slide-module'; +import { ProjectorMessageSlideComponent } from './projector-message-slide.component'; + +@NgModule(makeSlideModule(ProjectorMessageSlideComponent)) +export class ProjectorMessageSlideModule {}