diff --git a/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.html b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.html new file mode 100644 index 0000000000000000000000000000000000000000..1915d7b3d277c927ce213e1b508319796b7e4c4e --- /dev/null +++ b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.html @@ -0,0 +1,24 @@ +<div mat-dialog-content + *ngIf="editRoom"> + <div fxLayout="column"> + <mat-slide-toggle (change)="showMessage('words-will-be-overwritten', $event.checked)" [(ngModel)]="profanityCheck"> + {{ 'room-page.profanity-filter' | translate }} + </mat-slide-toggle> + <mat-slide-toggle *ngIf="profanityCheck" + (change)="showMessage('only-specific-language-will-be-filtered', $event.checked)" + [(ngModel)]="censorLanguageSpecificCheck"> + {{ 'room-page.language-specific-filter' | translate }} + </mat-slide-toggle> + <mat-slide-toggle *ngIf="profanityCheck" (change)="showMessage('partial-words-will-be-filtered', $event.checked)" + [(ngModel)]="censorPartialWordsCheck"> + {{ 'room-page.partial-words-filter' | translate }} + </mat-slide-toggle> + </div> +</div> +<app-dialog-action-buttons + buttonsLabelSection="room-page" + confirmButtonLabel="update" + + [cancelButtonClickAction]="buildCloseDialogActionCallback()" + [confirmButtonClickAction]="buildSaveActionCallback()" +></app-dialog-action-buttons> diff --git a/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.scss b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.spec.ts b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..89f7b20011d98808e17822e7cf742950e30f2022 --- /dev/null +++ b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.spec.ts @@ -0,0 +1,25 @@ +// import { ComponentFixture, TestBed } from '@angular/core/testing'; +// +// import { ProfanitySettingsComponent } from './profanity-settings.component'; +// +// describe('ProfanitySettingsComponent', () => { +// let component: ProfanitySettingsComponent; +// let fixture: ComponentFixture<ProfanitySettingsComponent>; +// +// beforeEach(async () => { +// await TestBed.configureTestingModule({ +// declarations: [ ProfanitySettingsComponent ] +// }) +// .compileComponents(); +// }); +// +// beforeEach(() => { +// fixture = TestBed.createComponent(ProfanitySettingsComponent); +// component = fixture.componentInstance; +// fixture.detectChanges(); +// }); +// +// it('should create', () => { +// expect(component).toBeTruthy(); +// }); +// }); diff --git a/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.ts b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..ad81ba4ead5ed15fbf9034f0fddbaf3c604ee956 --- /dev/null +++ b/src/app/components/creator/_dialogs/profanity-settings/profanity-settings.component.ts @@ -0,0 +1,85 @@ +import {Component,Inject,OnInit} from '@angular/core'; +import {MAT_DIALOG_DATA,MatDialog,MatDialogRef} from '@angular/material/dialog'; +import {RoomCreatorPageComponent} from '../../room-creator-page/room-creator-page.component'; +import {NotificationService} from '../../../../services/util/notification.service'; +import {TranslateService} from '@ngx-translate/core'; +import {RoomService} from '../../../../services/http/room.service'; +import {Router} from '@angular/router'; +import {EventService} from '../../../../services/util/event.service'; +import {ProfanityFilter,Room} from '../../../../models/room'; + +@Component({ + selector:'app-profanity-settings', + templateUrl:'./profanity-settings.component.html', + styleUrls:['./profanity-settings.component.scss'] +}) +export class ProfanitySettingsComponent implements OnInit{ + + editRoom: Room; + check=false; + profanityCheck: boolean; + censorPartialWordsCheck: boolean; + censorLanguageSpecificCheck: boolean; + + constructor(public dialogRef: MatDialogRef<RoomCreatorPageComponent>, + public dialog: MatDialog, + public notificationService: NotificationService, + public translationService: TranslateService, + protected roomService: RoomService, + public router: Router, + public eventService: EventService, + @Inject(MAT_DIALOG_DATA) public data: any){ + } + + ngOnInit(){ + this.profanityCheck=this.editRoom.profanityFilter!==ProfanityFilter.deactivated; + if(this.editRoom.profanityFilter===ProfanityFilter.all){ + this.censorLanguageSpecificCheck=this.censorPartialWordsCheck=true; + }else if(this.profanityCheck){ + this.censorLanguageSpecificCheck=this.editRoom.profanityFilter===ProfanityFilter.languageSpecific; + this.censorPartialWordsCheck=this.editRoom.profanityFilter===ProfanityFilter.partialWords; + } + } + + showMessage(label: string,event: boolean){ + if(event){ + this.translationService.get('room-page.'+label).subscribe(msg=>{ + this.notificationService.show(msg); + }); + } + } + + + /** + * Returns a lambda which closes the dialog on call. + */ + buildCloseDialogActionCallback(): () => void{ + return ()=>this.closeDialog('abort'); + } + + /** + * Returns a lambda which executes the dialog dedicated action on call. + */ + buildSaveActionCallback(): () => void{ + return ()=>this.save(); + } + + closeDialog(type: string): void{ + this.dialogRef.close(type); + } + + save(): void{ + this.editRoom.questionsBlocked=this.check; + this.editRoom.profanityFilter=this.profanityCheck?ProfanityFilter.none:ProfanityFilter.deactivated; + if(this.profanityCheck){ + if(this.censorLanguageSpecificCheck&&this.censorPartialWordsCheck){ + this.editRoom.profanityFilter=ProfanityFilter.all; + }else{ + this.editRoom.profanityFilter=this.censorLanguageSpecificCheck?ProfanityFilter.languageSpecific:ProfanityFilter.none; + this.editRoom.profanityFilter=this.censorPartialWordsCheck?ProfanityFilter.partialWords:this.editRoom.profanityFilter; + } + } + this.closeDialog('update'); + } + +} diff --git a/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.html b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.html new file mode 100644 index 0000000000000000000000000000000000000000..50b4fdab337336a77344cd04acd6f9525fb3cc0b --- /dev/null +++ b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.html @@ -0,0 +1,43 @@ +<div mat-dialog-content + *ngIf="editRoom"> + <mat-tab-group> + <mat-tab label="{{'room-page.description' | translate}}"> + <mat-form-field class="input-block"> + <textarea + (focus)="eventService.makeFocusOnInputTrue()" + (blur)="eventService.makeFocusOnInputFalse()" + [(ngModel)]="editRoom.description" + matInput + matTextareaAutosize + matAutosizeMinRows="2" + matAutosizeMaxRows="5" + maxlength="500" + name="description" + aria-labelledby="description" + ></textarea> + <mat-hint align="start"> + <span aria-hidden="true"> + {{ 'room-page.Markdown-hint' | translate }} + </span> + </mat-hint> + <mat-hint align="end"> + <span aria-hidden="true"> + {{ editRoom.description?editRoom.description.length:0 }} / 500 + </span> + </mat-hint> + </mat-form-field> + </mat-tab> + <mat-tab label="{{'session.preview' | translate}}" + [disabled]="!editRoom.description"> + <markdown class="images" katex emoji lineNumbers lineHighlight + [data]="editRoom.description"></markdown> + </mat-tab> + </mat-tab-group> +</div> +<app-dialog-action-buttons + buttonsLabelSection="room-page" + confirmButtonLabel="update" + + [cancelButtonClickAction]="buildCloseDialogActionCallback()" + [confirmButtonClickAction]="buildSaveActionCallback()" +></app-dialog-action-buttons> diff --git a/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.scss b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.spec.ts b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..32a8c08c6970557863d0d91cb3d0e5be6476bf64 --- /dev/null +++ b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.spec.ts @@ -0,0 +1,25 @@ +// import { ComponentFixture, TestBed } from '@angular/core/testing'; +// +// import { RoomDescriptionSettingsComponent } from './room-description-settings.component'; +// +// describe('RoomDescriptionSettingsComponent', () => { +// let component: RoomDescriptionSettingsComponent; +// let fixture: ComponentFixture<RoomDescriptionSettingsComponent>; +// +// beforeEach(async () => { +// await TestBed.configureTestingModule({ +// declarations: [ RoomDescriptionSettingsComponent ] +// }) +// .compileComponents(); +// }); +// +// beforeEach(() => { +// fixture = TestBed.createComponent(RoomDescriptionSettingsComponent); +// component = fixture.componentInstance; +// fixture.detectChanges(); +// }); +// +// it('should create', () => { +// expect(component).toBeTruthy(); +// }); +// }); diff --git a/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.ts b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..cd5f3ac74bf44d7f926629a15046dadc5bebdfc1 --- /dev/null +++ b/src/app/components/creator/_dialogs/room-description-settings/room-description-settings.component.ts @@ -0,0 +1,57 @@ +import {Component,Inject,OnInit} from '@angular/core'; +import {MAT_DIALOG_DATA,MatDialog,MatDialogRef} from '@angular/material/dialog'; +import {RoomCreatorPageComponent} from '../../room-creator-page/room-creator-page.component'; +import {NotificationService} from '../../../../services/util/notification.service'; +import {TranslateService} from '@ngx-translate/core'; +import {RoomService} from '../../../../services/http/room.service'; +import {Router} from '@angular/router'; +import {EventService} from '../../../../services/util/event.service'; +import {ProfanityFilter,Room} from '../../../../models/room'; +import {FormControl,Validators} from '@angular/forms'; + +@Component({ + selector:'app-room-description-settings', + templateUrl:'./room-description-settings.component.html', + styleUrls:['./room-description-settings.component.scss'] +}) +export class RoomDescriptionSettingsComponent implements OnInit{ + editRoom: Room; + roomNameFormControl=new FormControl('',[Validators.required,Validators.minLength(3),Validators.maxLength(30)]); + + constructor(public dialogRef: MatDialogRef<RoomCreatorPageComponent>, + public dialog: MatDialog, + public notificationService: NotificationService, + public translationService: TranslateService, + protected roomService: RoomService, + public router: Router, + public eventService: EventService, + @Inject(MAT_DIALOG_DATA) public data: any){ + } + + + ngOnInit(){ + } + + buildCloseDialogActionCallback(): () => void{ + return ()=>this.closeDialog('abort'); + } + + buildSaveActionCallback(): () => void{ + return ()=>this.save(); + } + + closeDialog(type: string): void{ + this.dialogRef.close(type); + } + + save(): void{ + this.roomService.updateRoom(this.editRoom).subscribe(r=>this.editRoom=r); + if(!this.roomNameFormControl.hasError('required') + && !this.roomNameFormControl.hasError('minlength') + && !this.roomNameFormControl.hasError('maxlength')){ + this.closeDialog('update'); + } + this.closeDialog('update'); + } + +} diff --git a/src/app/components/creator/creator.module.ts b/src/app/components/creator/creator.module.ts index 10b0706bd73293cd45e16b584f072917b30750d4..b876aea134afe3d6bebcb146b45e339e0cf7881c 100644 --- a/src/app/components/creator/creator.module.ts +++ b/src/app/components/creator/creator.module.ts @@ -23,6 +23,8 @@ import { DeleteAnswerComponent } from './_dialogs/delete-answer/delete-answer.co import { QuestionWallComponent } from '../shared/questionwall/question-wall/question-wall.component'; import { ArsModule } from '../../../../projects/ars/src/lib/ars.module'; import { MatRippleModule } from '@angular/material/core'; +import { ProfanitySettingsComponent } from './_dialogs/profanity-settings/profanity-settings.component'; +import { RoomDescriptionSettingsComponent } from './_dialogs/room-description-settings/room-description-settings.component'; @NgModule({ imports: [ @@ -56,7 +58,9 @@ import { MatRippleModule } from '@angular/material/core'; DeleteCommentComponent, BonusDeleteComponent, DeleteAnswerComponent, - QuestionWallComponent + QuestionWallComponent, + ProfanitySettingsComponent, + RoomDescriptionSettingsComponent ], exports: [] }) diff --git a/src/app/components/creator/room-creator-page/room-creator-page.component.html b/src/app/components/creator/room-creator-page/room-creator-page.component.html index 7e675f2bf840c8bc6796ab6e1e272719ab77674b..887173270548bec4f3a946f445437ea09ffee260 100644 --- a/src/app/components/creator/room-creator-page/room-creator-page.component.html +++ b/src/app/components/creator/room-creator-page/room-creator-page.component.html @@ -65,15 +65,6 @@ {{ 'room-page.tags' | translate}} </button> </mat-menu> - <button id="settings-menu" - mat-icon-button - class="corner-icons" - [matMenuTriggerFor]="settingsMenu" - aria-labelledby="settings"> - <mat-icon class="corner-icon" - matTooltip="{{ 'room-page.session-settings' | translate}}">settings - </mat-icon> - </button> </div> <mat-card-content *ngIf="room.description" fxLayoutAlign="center"> diff --git a/src/app/components/creator/room-creator-page/room-creator-page.component.ts b/src/app/components/creator/room-creator-page/room-creator-page.component.ts index f7e1967f66974f88d4427adfbc602f3130552315..6783a52836206829b173df498b147bf23c107fee 100644 --- a/src/app/components/creator/room-creator-page/room-creator-page.component.ts +++ b/src/app/components/creator/room-creator-page/room-creator-page.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit, Renderer2, OnDestroy, AfterContentInit } from '@angular/core'; import { RoomService } from '../../../services/http/room.service'; -import { ActivatedRoute } from '@angular/router'; +import {ActivatedRoute,Router} from '@angular/router'; import { RoomPageComponent } from '../../shared/room-page/room-page.component'; -import { Room } from '../../../models/room'; +import {ProfanityFilter,Room} from '../../../models/room'; import { CommentSettingsDialog } from '../../../models/comment-settings-dialog'; import { Location } from '@angular/common'; import { NotificationService } from '../../../services/util/notification.service'; @@ -27,6 +27,10 @@ import { Export } from '../../../models/export'; import { BonusTokenService } from '../../../services/http/bonus-token.service'; import { TopicCloudFilterComponent } from '../../shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component'; import {HeaderService} from '../../../services/util/header.service'; +import {RoomDeleteComponent} from '../_dialogs/room-delete/room-delete.component'; +import {RoomDeleted} from '../../../models/events/room-deleted'; +import {ProfanitySettingsComponent} from '../_dialogs/profanity-settings/profanity-settings.component'; +import {RoomDescriptionSettingsComponent} from '../_dialogs/room-description-settings/room-description-settings.component'; @Component({ selector: 'app-room-creator-page', @@ -60,7 +64,9 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni public eventService: EventService, public titleService: TitleService, private notificationService: NotificationService, - private bonusTokenService: BonusTokenService) { + private bonusTokenService: BonusTokenService, + public router: Router, + public translationService: TranslateService) { super(roomService, route, location, wsCommentService, commentService, eventService); this.commentCounterEmitSubscription = this.commentCounterEmit.subscribe(e => { this.titleService.attachTitle('(' + e + ')'); @@ -71,35 +77,15 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni initNavigation() { const navigation = {}; const nav = (b, c) => navigation[b] = c; + nav('deleteRoom',()=>this.openDeleteRoomDialog()); + nav('profanityFilter',()=>this.toggleProfanityFilter()); + nav('editSessionDescription',()=>this.editSessionDescription()); nav('roomBonusToken', () => this.showBonusTokenDialog()); nav('moderator', () => this.showModeratorsDialog()); nav('tags', () => this.showTagsDialog()); nav('topicCloud', () => this.showTagCloud()); - nav('exportQuestions', () => { - const exp: Export = new Export( - this.room, - this.commentService, - this.bonusTokenService, - this.translateService, - 'comment-list', - this.notificationService); - exp.exportAsCsv(); - }); - nav('deleteQuestions', () => { - const dialogRef = this.dialog.open(DeleteCommentsComponent, { - width: '400px' - }); - dialogRef.componentInstance.roomId = this.room.id; - dialogRef.afterClosed() - .subscribe(result => { - if (result === 'delete') { - this.translateService.get('room-page.comments-deleted').subscribe(msg => { - this.notificationService.show(msg); - }); - this.commentService.deleteCommentsByRoomId(this.room.id).subscribe(); - } - }); - }); + nav('exportQuestions', () => this.exportQuestions()); + nav('deleteQuestions', () => this.deleteQuestions()); this.headerInterface = this.eventService.on<string>('navigate').subscribe(e => { if (navigation.hasOwnProperty(e)) { navigation[e](); @@ -107,6 +93,47 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni }); } + toggleProfanityFilter(){ + const dialogRef = this.dialog.open(ProfanitySettingsComponent, { + width: '400px' + }); + dialogRef.componentInstance.editRoom=this.room; + } + + editSessionDescription(){ + const dialogRef = this.dialog.open(RoomDescriptionSettingsComponent, { + width: '400px' + }); + dialogRef.componentInstance.editRoom=this.room; + } + + exportQuestions(){ + const exp: Export = new Export( + this.room, + this.commentService, + this.bonusTokenService, + this.translateService, + 'comment-list', + this.notificationService); + exp.exportAsCsv(); + } + + deleteQuestions(){ + const dialogRef = this.dialog.open(DeleteCommentsComponent, { + width: '400px' + }); + dialogRef.componentInstance.roomId = this.room.id; + dialogRef.afterClosed() + .subscribe(result => { + if (result === 'delete') { + this.translateService.get('room-page.comments-deleted').subscribe(msg => { + this.notificationService.show(msg); + }); + this.commentService.deleteCommentsByRoomId(this.room.id).subscribe(); + } + }); + } + ngOnDestroy() { super.ngOnDestroy(); this.commentCounterEmitSubscription.unsubscribe(); @@ -307,6 +334,30 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni }); } + openDeleteRoomDialog(): void { + const dialogRef = this.dialog.open(RoomDeleteComponent, { + width: '400px' + }); + dialogRef.componentInstance.room = this.room; + dialogRef.afterClosed() + .subscribe(result => { + if (result === 'delete') { + this.deleteRoom(); + } + }); + } + + deleteRoom(): void { + this.translationService.get('room-page.deleted').subscribe(msg => { + this.notificationService.show(this.room.name + msg); + }); + this.roomService.deleteRoom(this.room.id).subscribe(result => { + const event = new RoomDeleted(this.room.id); + this.eventService.broadcast(event.type, event.payload); + this.location.back(); + }); + } + copyShortId(): void { const selBox = document.createElement('textarea'); selBox.style.position = 'fixed'; diff --git a/src/app/components/shared/header/header.component.html b/src/app/components/shared/header/header.component.html index fac23d0c986b9505e2bcb6fed29e2ebc679e5012..28738808fd7ac9cdf2fc101b265841b51982f7fe 100644 --- a/src/app/components/shared/header/header.component.html +++ b/src/app/components/shared/header/header.component.html @@ -234,7 +234,7 @@ <ng-container *ngIf="router.url.includes('/creator/room/')"> <button mat-menu-item - (click)="navigateModerator()" + (click)="navigateEditSessionDescription()" tabindex="0"> <mat-icon>flag</mat-icon> <span>{{'header.edit-session-description' | translate}}</span> @@ -242,8 +242,8 @@ <button mat-menu-item *ngIf="user" - (click)="navigateModerator()" - tabindex="0"> + tabindex="0" + routerLink="moderator/room/{{shortId}}/moderator/comments"> <mat-icon class="gavel">visibility_off</mat-icon> <span>{{'header.moderation-mode' | translate}}</span> </button> @@ -287,7 +287,7 @@ </button> <button mat-menu-item - (click)="navigateModerator()" + (click)="navigateProfanityFilter()" tabindex="0"> <mat-icon>clear</mat-icon> <span>{{'header.profanity-filter' | translate}}</span> @@ -362,7 +362,7 @@ <button mat-menu-item *ngIf="user && user.role == 3 && !router.url.includes('/participant') && !router.url.endsWith('/comments') && !router.url.includes('/comment/') && !router.url.endsWith('tagcloud')" - (click)="delete()" + (click)="navigateDeleteRoom()" tabindex="0"> <mat-icon class="color-warn">delete</mat-icon> <span>{{'header.delete-room' | translate}}</span> diff --git a/src/app/components/shared/header/header.component.ts b/src/app/components/shared/header/header.component.ts index b62e23372a924753aec289196c8f7ace6e5ea99a..43159cf93dc68cddd5f127c6297ba6191d4caccd 100644 --- a/src/app/components/shared/header/header.component.ts +++ b/src/app/components/shared/header/header.component.ts @@ -335,6 +335,18 @@ export class HeaderComponent implements OnInit { this.eventService.broadcast('navigate', 'createQuestion'); } + public navigateDeleteRoom(){ + this.eventService.broadcast('navigate', 'deleteRoom'); + } + + public navigateProfanityFilter() { + this.eventService.broadcast('navigate', 'profanityFilter'); + } + + public navigateEditSessionDescription() { + this.eventService.broadcast('navigate', 'editSessionDescription'); + } + public navigateTopicCloud() { const confirmDialogRef = this.confirmDialog.open(TopicCloudFilterComponent, { autoFocus: false