diff --git a/package-lock.json b/package-lock.json index 6ee4ddaa1060204a511f0c9f88180a134d23b096..c50a960ca8b7c01008ff6febcfff565b02b645fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17998,4 +17998,4 @@ "integrity": "sha512-UAYfiuvxLN4oyuqhJwd21Uxb4CNawrq6fPS/05Su5L4G+1TN+HVDJMUHNMobVQDFJRir2cLAODXwluaOKB7HFg==" } } -} +} \ No newline at end of file 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 d7ccbb31a9649364a9bbe352b7e2461a036c9dec..e1ffc26c791a651bb8b1a9414adc322743f271df 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 @@ -25,6 +25,7 @@ import { TitleService } from '../../../services/util/title.service'; import { DeleteCommentsComponent } from '../_dialogs/delete-comments/delete-comments.component'; 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'; @Component({ selector: 'app-room-creator-page', @@ -72,6 +73,7 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni 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, @@ -275,7 +277,15 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni dialogRef.componentInstance.room = this.room; } + showTagCloud(): void { + console.log("Showtagcloud called"); + const dialogRef = this.dialog.open(TopicCloudFilterComponent, { + width: '400px' + }); + } + showTagsDialog(): void { + console.log("Showtag called"); this.updRoom = JSON.parse(JSON.stringify(this.room)); const dialogRef = this.dialog.open(TagsComponent, { width: '400px' diff --git a/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts b/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts index 852463ad44bb458578838661a8995d7f66d28a60..0efa82d0e494e4b10cb496908cf12facd35904b0 100644 --- a/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts +++ b/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts @@ -187,6 +187,10 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy { this.translateService.get('comment-list.search').subscribe(msg => { this.searchPlaceholder = msg; }); + + localStorage.setItem('currentFilters', JSON.stringify(this.currentFilter)); + localStorage.setItem('currentPeriod', JSON.stringify(this.period)); + localStorage.setItem('currentFromNowTimestamp', JSON.stringify(this.fromNow)); // can be null } checkScroll(): void { @@ -349,6 +353,9 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy { }); this.hideCommentsList = true; this.sortComments(this.currentSort); + + // set current filters to local storage for later use + localStorage.setItem('currentFilters', JSON.stringify(this.currentFilter)); } clickedUserNumber(usrNumber: number): void { @@ -424,6 +431,10 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy { } else { this.commentsFilteredByTime = this.comments; } + + localStorage.setItem('currentPeriod', JSON.stringify(this.period)); + localStorage.setItem('currentFromNowTimestamp', JSON.stringify(this.fromNow)); // can be null + this.filterComments(this.currentFilter); } } diff --git a/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts b/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts index 5e14d05cb5e5dce50b04a7112bfe9e43cd2e1530..87f620569ee0cdab4e0570f2d5ee594d9f5c5d21 100644 --- a/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts +++ b/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts @@ -1,12 +1,13 @@ import { Component, Inject, OnInit, ViewChild } from '@angular/core'; import { Comment } from '../../../../models/comment'; import { NotificationService } from '../../../../services/util/notification.service'; -import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { FormControl, Validators } from '@angular/forms'; import { User } from '../../../../models/user'; import { CommentListComponent } from '../../comment-list/comment-list.component'; import { EventService } from '../../../../services/util/event.service'; +import { SpacyDialogComponent } from '../spacy-dialog/spacy-dialog.component'; @Component({ selector: 'app-submit-comment', @@ -66,10 +67,26 @@ export class CreateCommentComponent implements OnInit { comment.creatorId = this.user.id; comment.createdFromLecturer = this.user.role === 1; comment.tag = this.selectedTag; - this.dialogRef.close(comment); + this.openSpacyDialog(comment); } } + openSpacyDialog(comment: Comment): void { + const dialogRef = this.dialog.open(SpacyDialogComponent, { + data: { + comment + } + }); + + dialogRef.afterClosed() + .subscribe(result => { + if (result) { + this.dialogRef.close(result); + } + }); + + } + /** * Returns a lambda which closes the dialog on call. diff --git a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.html b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.html new file mode 100644 index 0000000000000000000000000000000000000000..b23229d31d9fa7384a8f2e934455a09e9d2c43cb --- /dev/null +++ b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.html @@ -0,0 +1,69 @@ +<ars-row> + <div class="anchor-wrp"> + <ars-row class="content-container"> + <ars-row class="dialog-header"> + <div class="lang-selection"> + <mat-icon>more_vert</mat-icon> + <mat-select class="select-list" [(ngModel)]="selectedLang" (selectionChange)="evalInput($event.value)"> + <mat-option *ngFor="let lang of commentLang" [value]="lang.lang"> + <span *ngIf="lang.lang == 'de'">{{ 'spacy-dialog.german' | translate}}</span> + <span *ngIf="lang.lang == 'en'">{{ 'spacy-dialog.english' | translate}}</span> + <span *ngIf="lang.lang == 'fr'">{{ 'spacy-dialog.french' | translate}}</span> + </mat-option> + </mat-select> + </div> + <span *ngIf="keywords.length > 0"> + <ars-row class="select-all-section"> + <mat-icon>playlist_add_check</mat-icon> + <mat-label class="select-all-label" for="checkAll">{{ 'spacy-dialog.select-all' | translate }}</mat-label> + <mat-checkbox class="select-all-checkbox" id="checkAll" (change)="selectAll($event.checked)"></mat-checkbox> + </ars-row> + </span> + <span *ngIf="keywords.length > 0"></span> + </ars-row> + <ars-row ars-flex-box class="list-container"> + <mat-list dense class="keywords-list"> + <mat-list-item *ngFor="let keyword of keywords; let odd = odd; let even = even" + [class.keywords-alternate]="odd" + [class.keywords-even]="even" + [ngClass]="{'keyword-selected': keyword.selected}"> + <span class="keyword-span" *ngIf="!keyword.editing">{{keyword.word}}</span> + <input class="keyword-span, isEditing" *ngIf="keyword.editing" [(ngModel)]="keyword.word"/> + <div class="keywords-actions"> + <mat-checkbox [checked]="keyword.completed" + (change)="keyword.selected = $event.checked"> + </mat-checkbox> + <button *ngIf="!keyword.editing" + (click)="onEdit(keyword)" mat-icon-button + [ngClass]="{'keywords-actions-selected': keyword.selected}"> + <mat-icon>edit</mat-icon> + </button> + <button *ngIf="keyword.editing" + (click)="onEndEditing(keyword)" mat-icon-button + class = "edit-accept"> + <mat-icon>check</mat-icon> + </button> + </div> + </mat-list-item> + </mat-list> + </ars-row> + <span *ngIf="keywords.length<=0"> + <p>{{ 'spacy-dialog.empty-nouns' | translate}}</p> + </span> + </ars-row> + </div> +</ars-row> +<ars-row ars-flex-box> + <ars-fill> + </ars-fill> + <ars-col> + <app-dialog-action-buttons + buttonsLabelSection="comment-page" + confirmButtonLabel="send" + [showDivider]="false" + [spacing]="false" + [cancelButtonClickAction]="buildCloseDialogActionCallback()" + [confirmButtonClickAction]="buildCreateCommentActionCallback()"> + </app-dialog-action-buttons> + </ars-col> +</ars-row> diff --git a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.scss b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..34602fb836e85b5d22ef37bea3813562827a6331 --- /dev/null +++ b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.scss @@ -0,0 +1,71 @@ +.mat-list-base[dense] .mat-list-item, .list-item { + font-size: 14px; + height: 35px !important; +} +.keywords-list { + height: 343px; + flex-grow: 1; + flex-shrink: 1; + overflow: auto; + padding-top: 0 !important; +} +.keywords-even { +background-color: var(--alt-dialog); +} +.keyword-span { + color: var(--on-surface) !important; + opacity: 1 !important; +} +.keyword-selected { + background: var(--primary-variant); + border-bottom: 1px solid var(--alt-surface); +} +::ng-deep .mat-checkbox-checked .mat-checkbox-background { + background: var(--cancel) !important; +} +.mat-checkbox-frame { + color: var(--secondary); +} +:focus{ + outline: none; + outline-offset: 8px; +} +.lang-selection { + display: inline-flex; + vertical-align: middle; + width:100%; +} +.keywords-actions { + margin-left: auto; + color: var(--on-surface); +} +.keywords-actions-selected { + color: var(--on-surface); +} +.isEditing{ + background: var(--primary); + height: 22px; + border-radius: 5px; + color: var(--on-primary); + border: 1px solid var( --on-primary); +} +.edit-accept { + color: var(--on-surface); +} +.select-all-section { + display: inline-flex; + vertical-align: middle; + padding-top: 20px; + padding-bottom: 30px; + padding-left: 4px; +} +.select-all-label { + padding-left: 10px; +} +.select-all-checkbox { + margin-left: auto; + padding-right: 5px; +} +.mat-select { + padding-left: 14px; +} diff --git a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.spec.ts b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..a7a4bfe1ec0154ec12f9514103b9bf97d977ae18 --- /dev/null +++ b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.spec.ts @@ -0,0 +1,27 @@ +/* +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SpacyDialogComponent } from './spacy-dialog.component'; + +describe('SpacyDialogComponent', () => { + let component: SpacyDialogComponent; + let fixture: ComponentFixture<SpacyDialogComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SpacyDialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SpacyDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); +*/ diff --git a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..5fccb64f59bfde9c9300666b5208a32e9ab2e071 --- /dev/null +++ b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts @@ -0,0 +1,104 @@ +import { AfterContentInit, Component, Inject, OnInit } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { CreateCommentComponent } from '../create-comment/create-comment.component'; +import { SpacyService } from '../../../../services/http/spacy.service'; +import { LanguageService } from '../../../../services/util/language.service'; +import { Comment } from '../../../../models/comment'; + +export interface Keyword { + word: string; + completed: boolean; + editing: boolean; + selected: boolean; +} +@Component({ + selector: 'app-spacy-dialog', + templateUrl: './spacy-dialog.component.html', + styleUrls: ['./spacy-dialog.component.scss'] +}) +export class SpacyDialogComponent implements OnInit, AfterContentInit { + + commentLang = [ + { lang: 'de' }, + { lang: 'en' }, + { lang: 'fr' }, + ]; + selectedLang = localStorage.getItem('currentLang'); + comment: Comment; + keywords: Keyword[] = []; + + constructor( + protected langService: LanguageService, + private spacyService: SpacyService, + public dialogRef: MatDialogRef<CreateCommentComponent>, + @Inject(MAT_DIALOG_DATA) public data) { + } + + ngOnInit(): void { + this.comment = this.data.comment; + } + + ngAfterContentInit(): void { + this.evalInput(this.selectedLang); + } + + /** + * Returns a lambda which closes the dialog on call. + */ + buildCloseDialogActionCallback(): () => void { + return () => this.dialogRef.close(); + } + + buildCreateCommentActionCallback() { + return () => { + this.comment.keywords = this.keywords.filter(kw => kw.selected).map(kw => kw.word); + this.dialogRef.close(this.comment); + }; + } + + evalInput(model: string) { + const words: Keyword[] = []; + + // N at first pos = all Nouns(NN de/en) including singular(NN, NNP en), plural (NNPS, NNS en), proper Noun(NNE, NE de) + this.spacyService.analyse(this.comment.body, model) + .subscribe(res => { + for(const word of res.words) { + if (word.tag.charAt(0) === 'N') { + words.push({ + word: word.text, + completed: false, + editing: false, + selected: false + }); + } + } + this.keywords = words; + }, () => { + this.keywords = [] + }); + } + + onEdit(keyword){ + keyword.editing = true; + } + + onEndEditing(keyword){ + keyword.editing = false; + keyword.completed = true; + keyword.selected = true; + } + + selectAll(selected: boolean): void { + if (selected) { + this.keywords.forEach(item => { + this.onEndEditing(item); + }); + } else { + this.keywords.forEach(item => { + item.editing = false; + item.completed = false; + item.selected = false; + }); + } + } +} diff --git a/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.html b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.html new file mode 100644 index 0000000000000000000000000000000000000000..fdf95e7f172a29c2b8cefd8726b737e60b8d8500 --- /dev/null +++ b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.html @@ -0,0 +1,21 @@ +<div mat-dialog-content> + <p>{{'content.topic-cloud-content' | translate}}</p> +</div> + +<mat-divider></mat-divider> + <mat-radio-group [(ngModel)]="continueFilter" aria-label="Select an option"> + <mat-radio-button value="continueWithAll">{{'content.continue-with-all-questions' | translate}}</mat-radio-button> + <mat-radio-button checked="true" value="continueWithCurr">{{'content.continue-with-current-questions' | translate}}</mat-radio-button> + <mat-radio-button value="continueWithAllFromNow">{{'content.continue-with-all-questions-from-now' | translate}}</mat-radio-button> + </mat-radio-group> + + +<app-dialog-action-buttons + buttonsLabelSection="content" + confirmButtonLabel="continue" + buttonIcon="cloud" + + [cancelButtonClickAction]="cancelButtonActionCallback()" + [confirmButtonClickAction]="confirmButtonActionCallback()"> +</app-dialog-action-buttons> + diff --git a/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.scss b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..d0f639b53f2a3aaebcca5c9dd5c1ae7f22d83027 --- /dev/null +++ b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.scss @@ -0,0 +1,12 @@ +mat-radio-button{ + margin: 5px; + +} + + + +mat-radio-group { + display: flex; + flex-direction: column; + margin: 15px 0; +} \ No newline at end of file diff --git a/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..12f4ba73bb0dd23a573125fc061ca13bab06090e --- /dev/null +++ b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts @@ -0,0 +1,73 @@ +import { Component, Inject, OnInit, ViewChild, ElementRef, Input } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { NotificationService } from '../../../../services/util/notification.service'; +import { TranslateService } from '@ngx-translate/core'; +import { RoomCreatorPageComponent } from '../../../creator/room-creator-page/room-creator-page.component'; +import { LanguageService } from '../../../../services/util/language.service'; +import { EventService } from '../../../../services/util/event.service'; +import {Router} from '@angular/router'; + +@Component({ + selector: 'app-topic-cloud-filter', + templateUrl: './topic-cloud-filter.component.html', + styleUrls: ['./topic-cloud-filter.component.scss'] +}) +export class TopicCloudFilterComponent implements OnInit{ + @Input()filteredComments: any; + @Input()commentsFilteredByTime: any; + + continueFilter: string = 'continueWithCurr'; + tmpCurFilters: string; + tmpPeriod : string; + + constructor(public dialogRef: MatDialogRef<RoomCreatorPageComponent>, + public dialog: MatDialog, + public notificationService: NotificationService, + public translationService: TranslateService, + protected langService: LanguageService, + private router: Router, + @Inject(MAT_DIALOG_DATA) public data: any, + public eventService: EventService) { + langService.langEmitter.subscribe(lang => translationService.use(lang)); + } + + ngOnInit() { + this.translationService.use(localStorage.getItem('currentLang')); + this.tmpPeriod = localStorage.getItem('currentPeriod'); + this.tmpCurFilters = localStorage.getItem('currentFilters'); + } + + closeDialog(): void { + } + + + cancelButtonActionCallback(): () => void { + return () => this.dialogRef.close('abort'); + } + + confirmButtonActionCallback(): () => void { + localStorage.setItem('currentFilters', this.tmpCurFilters); + localStorage.setItem('currentPeriod', this.tmpPeriod); + localStorage.setItem('currentFromNowTimestamp', JSON.stringify(null)); + switch (this.continueFilter) { + case 'continueWithAll': + localStorage.setItem('currentFilters', JSON.stringify("")); + break; + + case 'continueWithCurr': + // filter set already + break; + + case 'continueWithAllFromNow': + localStorage.setItem('currentFilters', JSON.stringify("")); + localStorage.setItem('currentPeriod', JSON.stringify('from-now')); + localStorage.setItem('currentFromNowTimestamp', JSON.stringify(new Date().getTime())); + break; + + default: + break; + } + + return () => this.dialogRef.close(this.router.navigateByUrl('/participant/room/' + localStorage.getItem('roomId') + '/comments/tagcloud')); + } +} diff --git a/src/app/components/shared/comment-list/comment-list.component.ts b/src/app/components/shared/comment-list/comment-list.component.ts index 0ba2b4cd88d899533ba19ff0c1ea56cf380e4245..5bc9ba945dfee91d590f4dc957f4ee202bd0df40 100644 --- a/src/app/components/shared/comment-list/comment-list.component.ts +++ b/src/app/components/shared/comment-list/comment-list.component.ts @@ -29,6 +29,7 @@ import { DeleteCommentsComponent } from '../../creator/_dialogs/delete-comments/ import { Export } from '../../../models/export'; import { BonusTokenService } from '../../../services/http/bonus-token.service'; import { ModeratorService } from '../../../services/http/moderator.service'; +import { TopicCloudFilterComponent } from '../_dialogs/topic-cloud-filter/topic-cloud-filter.component'; export enum Period { FROMNOW = 'from-now', @@ -244,6 +245,10 @@ export class CommentListComponent implements OnInit, OnDestroy { this.translateService.get('comment-list.search').subscribe(msg => { this.searchPlaceholder = msg; }); + + localStorage.setItem('currentFilters', JSON.stringify(this.currentFilter)); + localStorage.setItem('currentPeriod', JSON.stringify(this.period)); + localStorage.setItem('currentFromNowTimestamp', JSON.stringify(this.fromNow)); // can be null } getModeratorIds() { @@ -413,7 +418,9 @@ export class CommentListComponent implements OnInit, OnDestroy { this.searchComments(); } } - + closeDialog() { + this.dialog.closeAll(); + } openCreateDialog(): void { const dialogRef = this.dialog.open(CreateCommentComponent, { width: '900px', @@ -439,6 +446,7 @@ export class CommentListComponent implements OnInit, OnDestroy { }); } + send(comment: Comment): void { let message; if (this.directSend) { @@ -504,6 +512,9 @@ export class CommentListComponent implements OnInit, OnDestroy { }); this.hideCommentsList = true; this.sortComments(this.currentSort); + + // set current filters to local storage for later use + localStorage.setItem('currentFilters', JSON.stringify(this.currentFilter)); } sort(array: any[], type: string): any[] { @@ -636,6 +647,10 @@ export class CommentListComponent implements OnInit, OnDestroy { } else { this.commentsFilteredByTime = this.comments; } + + localStorage.setItem('currentPeriod', JSON.stringify(this.period)); + localStorage.setItem('currentFromNowTimestamp', JSON.stringify(this.fromNow)); // can be null + this.filterComments(this.currentFilter); this.titleService.attachTitle('(' + this.commentsFilteredByTime.length + ')'); } diff --git a/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.html b/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.html index b6f5537ac46925ecea1602b1e8a67d60def00632..fe6843e70a778497898e8deb431813613841fa7e 100644 --- a/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.html +++ b/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.html @@ -12,7 +12,7 @@ class="mat-flat-button {{ confirmButtonType }}-confirm-button" attr.aria-labelledby="{{ ariaPrefix + 'confirm' | translate }}" (click)="performConfirmButtonClickAction()" - >{{ buttonsLabelSection + '.' + confirmButtonLabel | translate}}</button> + ><mat-icon *ngIf="buttonIcon" style="margin-right: 5px;">{{buttonIcon}}</mat-icon>{{ buttonsLabelSection + '.' + confirmButtonLabel | translate}}</button> <button *ngIf="cancelButtonClickAction !== undefined" type="button" diff --git a/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.ts b/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.ts index 2ca544872fd4243fc2968515ca99c1a27de780bb..4fa8c7d7d921f621413b051418a9510a16be5c15 100644 --- a/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.ts +++ b/src/app/components/shared/dialog/dialog-action-buttons/dialog-action-buttons.component.ts @@ -23,6 +23,11 @@ export class DialogActionButtonsComponent implements OnInit { */ @Input() buttonsLabelSection: string; + /** + * Icon for confirm. + */ + @Input() buttonIcon: string; + /** * The i18n label identifier of the confirm button. @@ -47,6 +52,7 @@ export class DialogActionButtonsComponent implements OnInit { */ @Input() cancelButtonClickAction: (Function | undefined); + @Input() resetButtonClickAction: (Function | undefined); /** * TRUE if some spacing will be rendered above the action buttons. @@ -86,4 +92,10 @@ export class DialogActionButtonsComponent implements OnInit { this.cancelButtonClickAction(); } } + public filterzu(): void{ + if (this.resetButtonClickAction !== undefined) { + this.resetButtonClickAction(); + + } + } } diff --git a/src/app/components/shared/header/header.component.html b/src/app/components/shared/header/header.component.html index 0c56aa0ccfd73a9ced7a025b6e46cdce9f75e8d4..757110d6f6fa5342988a9933d2821b58f6f01a88 100644 --- a/src/app/components/shared/header/header.component.html +++ b/src/app/components/shared/header/header.component.html @@ -1,408 +1,406 @@ -<mat-toolbar class="mat-elevation-z2"> - <mat-toolbar-row> - <button id="back-button" - mat-icon-button - aria-labelledby="back-label" - *ngIf="router.url !== '/home'" - (click)="goBack()"> - <mat-icon class="header-icons">arrow_back</mat-icon> - </button> - - <span class="fill-remaining-space"></span> - - <h2 class="oldtypo-h2" - *ngIf="router.url.includes('comments') && deviceType === 'desktop'" - fxLayoutAlign="center center"> - {{cTime}} - </h2> - - <!-- - <span *ngIf="router.url.includes('comments') && !router.url.includes('moderator/comments') && deviceType === 'desktop'" - class="fill-remaining-space"></span> - <span class="fill-remaining-space" - *ngIf="router.url.includes('comments') && deviceType === 'desktop'"></span> - <span - *ngIf="router.url.includes('comments') && moderationEnabled" - class="moderation-enabled" - fxLayoutAlign="center center"> - <mat-icon matTooltip="{{ 'header.moderation-enabled' | translate }}"> - gavel - </mat-icon> - </span> - - <h2 class="oldtypo-h2" - id="shortId-header" - *ngIf="router.url.includes('comments')" - fxLayoutAlign="center center"> - {{ shortId.slice(0, 4) }} {{ shortId.slice(4, 8) }} - </h2>--> - <!--Feedback im Hörsaal--> - <h2 class="oldtypo-h2" - *ngIf="router.url.includes('home')" - fxLayoutAlign="center center"> - {{ 'header.home-header' | translate }} - </h2> - <span class="fill-remaining-space"></span> - - <mat-menu #userMenu="matMenu" - [overlapTrigger]="false"> - <!-- <p class="mat-menu-inner-title">Account</p>--> - - <div class="mat-menu-inner-box"> - - <!-- Home --> - <ng-container *ngIf="router.url.endsWith('/home')"> - </ng-container> - - <!-- Session list --> - <ng-container *ngIf="router.url.endsWith('/user')"> - </ng-container> - - <!-- Room --> - <ng-container *ngIf="router.url.includes('/room/')"> - - <!-- Room General Options - top --> - - <!-- Moderator board / index --> - - <ng-container - *ngIf="user && user.role > 0 && (router.url.endsWith('/moderator/comments') || router.url.includes('/comment/'))"> - - <button mat-menu-item - tabindex="0" - *ngIf="user.role == 3" - routerLink="creator/room/{{shortId}}/comments"> - <mat-icon> - forum - </mat-icon> - <span>{{'header.back-to-questionboard' | translate}}</span> - </button> - - <button mat-menu-item - tabindex="0" - *ngIf="user.role > 0 && user.role < 3" - routerLink="moderator/room/{{shortId}}/comments"> - <mat-icon> - forum - </mat-icon> - <span>{{'header.back-to-questionboard' | translate}}</span> - </button> - - </ng-container> - - <ng-container *ngIf="user && user.role == 0 && router.url.includes('/comment/')"> - - <button mat-menu-item - tabindex="0" - routerLink="participant/room/{{shortId}}/comments"> - <mat-icon> - forum - </mat-icon> - <span>{{'header.back-to-questionboard' | translate}}</span> - </button> - - </ng-container> - - <!-- Question board --> - <ng-container *ngIf="router.url.endsWith('/comments')"> - - <button mat-menu-item - *ngIf="user && !router.url.endsWith('moderator/comments')" - tabindex="0" - (click)="navigateCreateQuestion();"> - <mat-icon> - add - </mat-icon> - <span>{{'header.create-question' | translate}}</span> - </button> - - <ng-container> - - <button mat-menu-item - tabindex="0" - *ngIf="user && user.role > 0 && !router.url.includes('/participant/') && !router.url.endsWith('moderator/comments')" - routerLink="moderator/room/{{shortId}}/moderator/comments"> - <mat-icon> - visibility_off - </mat-icon> - <span>{{'header.moderationboard' | translate}}</span> - </button> - - <button mat-menu-item - tabindex="0" - *ngIf="deviceType !== 'mobile'" - routerLink="participant/room/{{shortId}}/comments/questionwall"> - <mat-icon - svgIcon="beamer"> - </mat-icon> - <span>{{'header.questionwall' | translate}}</span> - </button> - - - <button mat-menu-item - tabindex="0" - routerLink="participant/room/{{shortId}}/comments/tagcloud"> - <mat-icon>cloud - </mat-icon> - <span>{{'header.tag-cloud' | translate}}</span> - </button> - - - </ng-container> - <ng-container *ngIf="router.url.includes('/participant/room/')"> - </ng-container> - <ng-container *ngIf="router.url.includes('/moderator/room/')"> - </ng-container> - <ng-container *ngIf="router.url.includes('/creator/room/')"> - </ng-container> - - <button mat-menu-item - *ngIf="user" - (click)="navigateExportQuestions()" - tabindex="0"> - <mat-icon>save</mat-icon> - <span>{{'header.export-questions' | translate}}</span> - </button> - - <button mat-menu-item - *ngIf="user && user.role > 0 && !router.url.includes('/participant/')" - (click)="navigateDeleteQuestions()" - tabindex="0"> - <mat-icon class="color-warn">delete</mat-icon> - <span>{{'header.delete-questions' | translate}}</span> - </button> - - </ng-container> - - <!-- Session --> - <ng-container *ngIf="!router.url.endsWith('/comments') && !router.url.includes('/comment/')"> - - <!-- app-room-participant-page --> - <ng-container *ngIf="router.url.includes('/participant/room/')"> - </ng-container> - <!-- app-room-creator-page --> - <ng-container *ngIf="router.url.includes('/moderator/room/')"> - </ng-container> - <!-- app-room-creator-page --> - <ng-container *ngIf="router.url.includes('/creator/room/')"> - - <button mat-menu-item - *ngIf="user" - (click)="navigateRoomBonusToken()" - tabindex="0"> - <mat-icon class="star">grade</mat-icon> - <span>{{'header.bonustoken' | translate}}</span> - </button> - - <button mat-menu-item - *ngIf="user" - (click)="navigateExportQuestions()" - tabindex="0"> - <mat-icon>save</mat-icon> - <span>{{'header.export-questions' | translate}}</span> - </button> - - <button mat-menu-item - *ngIf="user" - (click)="navigateDeleteQuestions()" - tabindex="0"> - <mat-icon class="color-warn">delete</mat-icon> - <span>{{'header.delete-questions' | translate}}</span> - </button> - - </ng-container> - - </ng-container> - - <!-- Room General Options - bot --> - - <ng-container - *ngIf="user && user.role == 3 && !router.url.includes('/participant') && !router.url.includes('/comment/')"> - - <button mat-menu-item - *ngIf="user" - (click)="navigateModerator()" - tabindex="0"> - <mat-icon>gavel</mat-icon> - <span>{{'header.edit-moderator' | translate}}</span> - </button> - - <button mat-menu-item - *ngIf="user" - (click)="navigateTags()" - tabindex="0"> - <mat-icon svgIcon="comment_tag"></mat-icon> - <span>{{'header.edit-tags' | translate}}</span> - </button> - - </ng-container> - - <button mat-menu-item - *ngIf="user && user.role > 0 && !router.url.includes('/comment/') && !router.url.endsWith('/tagcloud')" - tabindex="0" - (click)="showQRDialog();"> - <mat-icon svgIcon="qrcode" - class="header-icons qrcode"> - </mat-icon> - <span>{{'header.room-qr' | translate}}</span> - </button> - - <button mat-menu-item - *ngIf="router.url.endsWith('/tagcloud')" - tabindex="0" - (click)="navigateTopicCloudConfig()"> - <mat-icon aria-label="Configuration Icon">cloud</mat-icon> - <span>{{'header.tag-cloud-config' | translate}}</span> - </button> - - <button mat-menu-item - *ngIf="router.url.endsWith('/tagcloud')" - tabindex="0" - (click)="navigateTopicCloudAdministration()"> - <mat-icon aria-hidden="false" aria-label="Control Icon">edit</mat-icon> - <span>{{'header.tag-cloud-administration' | translate}}</span> - </button> - - <button mat-menu-item - *ngIf="router.url.endsWith('/tagcloud')" - tabindex="0" - (click)="navigateCreateQuestion();"> - <mat-icon> - add - </mat-icon> - <span>{{'header.create-question' | translate}}</span> - </button> - - <button mat-menu-item - tabindex="0" - *ngIf="router.url.endsWith('/tagcloud')" - routerLink="participant/room/{{shortId}}/comments"> - <mat-icon> - forum - </mat-icon> - <span>{{'header.back-to-questionboard' | translate}}</span> - </button> - - </ng-container> - - </div> - - <!-- General Options --> - - <button mat-menu-item - *ngIf="user && !router.url.endsWith('/user')" - routerLink="/user" - tabindex="0"> - <mat-icon class="sessions">view_list</mat-icon> - <span *ngIf="!user.isGuest">{{'header.my-sessions' | translate}}</span> - <span *ngIf="user.isGuest" - svgIcon="meeting_room">{{'header.visited-sessions' | translate}}</span> - </button> - - <button mat-menu-item - *ngIf="user" - (click)="openUserBonusTokenDialog()" - tabindex="0"> - <mat-icon class="star">grade</mat-icon> - <span>{{'header.user-bonus-token' | translate}}</span> - </button> - - <button mat-menu-item - *ngIf="user" - (click)="showMotdDialog()"> - <mat-icon> - {{ motdState ? 'notifications_active' : 'notifications_none' }} - </mat-icon> - <span>{{'header.motd' | translate}}</span> - </button> - - <button mat-menu-item - aria-hidden="true" - *ngIf="isSafari === 'false' && !router.url.includes('home')" - (click)="getRescale().toggleState();"> - <mat-icon (click)="getRescale().toggleState();">format_size - </mat-icon> - <span>{{'header.fullscreen' | translate}}</span> - </button> - - <mat-divider></mat-divider> - - <button mat-menu-item - *ngIf="user && !user.isGuest && user.loginId" - (click)="openDeleteUserDialog()" - tabindex="0"> - <mat-icon class="color-warn">delete</mat-icon> - <span>{{'header.delete-account' | translate}}</span> - </button> - - <button mat-menu-item - (click)="logout()" - tabindex="0"> - <mat-icon class="color-warn">exit_to_app</mat-icon> - <span>{{ 'header.logout' | translate }}</span> - </button> - - </mat-menu> - - <button [disabled]="cookiesDisabled()" - mat-button - *ngIf="user && deviceType === 'desktop'" - [matMenuTriggerFor]="userMenu" - aria-labelledby="session-label" - id="session-button"> - <div class="label-icon"> - <mat-icon *ngIf="!user.isGuest" - class="header-icons">more_vert - </mat-icon> - <mat-icon *ngIf="user.isGuest" - svgIcon="meeting_room" - class="header-icons"></mat-icon> - <h2 class="oldtypo-h2" - *ngIf="!user.isGuest">{{'header.my-account' | translate}}</h2> - <!--Guest Account--> - <h2 class="oldtypo-h2" - *ngIf="user.isGuest">{{'header.my-guest-account' | translate}}</h2> - </div> - </button> - - <button [disabled]="cookiesDisabled()" - mat-icon-button - *ngIf="user && deviceType === 'mobile'" - [matMenuTriggerFor]="userMenu" - aria-labelledby="session-label"> - <mat-icon *ngIf="!user.isGuest" - class="header-icons">more_vert - </mat-icon> - <mat-icon *ngIf="user.isGuest" - svgIcon="meeting_room" - class="header-icons"></mat-icon> - </button> - - <button id="login-button" - [disabled]="cookiesDisabled()" - mat-button - *ngIf="!user && deviceType === 'desktop'" - (click)=login(false) - aria-labelledby="login-label"> - <div class="label-icon"> - <mat-icon class="header-icons">person</mat-icon> - <h2 class="oldtypo-h2" - *ngIf="deviceType === 'desktop'">{{'header.login' | translate}}</h2> - </div> - </button> - - <button [disabled]="cookiesDisabled()" - mat-icon-button - *ngIf="!user && deviceType === 'mobile'" - (click)=login(false) - aria-labelledby="login-label"> - <mat-icon class="header-icons">person</mat-icon> - </button> - </mat-toolbar-row> -</mat-toolbar> - -<div class="visually-hidden"> - <div id="login-label">{{'header.accessibility-login' | translate}}</div> - <div id="back-label">{{'header.accessibility-back' | translate}}</div> - <div id="session-label">{{'header.accessibility-session' | translate}}</div> -</div> +<mat-toolbar class="mat-elevation-z2"> + <mat-toolbar-row> + <button id="back-button" + mat-icon-button + aria-labelledby="back-label" + *ngIf="router.url !== '/home'" + (click)="goBack()"> + <mat-icon class="header-icons">arrow_back</mat-icon> + </button> + + <span class="fill-remaining-space"></span> + + <h2 class="oldtypo-h2" + *ngIf="router.url.includes('comments') && deviceType === 'desktop'" + fxLayoutAlign="center center"> + {{cTime}} + </h2> + + <!-- + <span *ngIf="router.url.includes('comments') && !router.url.includes('moderator/comments') && deviceType === 'desktop'" + class="fill-remaining-space"></span> + <span class="fill-remaining-space" + *ngIf="router.url.includes('comments') && deviceType === 'desktop'"></span> + <span + *ngIf="router.url.includes('comments') && moderationEnabled" + class="moderation-enabled" + fxLayoutAlign="center center"> + <mat-icon matTooltip="{{ 'header.moderation-enabled' | translate }}"> + gavel + </mat-icon> + </span> + + <h2 class="oldtypo-h2" + id="shortId-header" + *ngIf="router.url.includes('comments')" + fxLayoutAlign="center center"> + {{ shortId.slice(0, 4) }} {{ shortId.slice(4, 8) }} + </h2>--> + <!--Feedback im Hörsaal--> + <h2 class="oldtypo-h2" + *ngIf="router.url.includes('home')" + fxLayoutAlign="center center"> + {{ 'header.home-header' | translate }} + </h2> + <span class="fill-remaining-space"></span> + + <mat-menu #userMenu="matMenu" + [overlapTrigger]="false"> + <!-- <p class="mat-menu-inner-title">Account</p>--> + + <div class="mat-menu-inner-box"> + + <!-- Home --> + <ng-container *ngIf="router.url.endsWith('/home')"> + </ng-container> + + <!-- Session list --> + <ng-container *ngIf="router.url.endsWith('/user')"> + </ng-container> + + <!-- Room --> + <ng-container *ngIf="router.url.includes('/room/')"> + + <!-- Room General Options - top --> + + <!-- Moderator board / index --> + + <ng-container + *ngIf="user && user.role > 0 && (router.url.endsWith('/moderator/comments') || router.url.includes('/comment/'))"> + + <button mat-menu-item + tabindex="0" + *ngIf="user.role == 3" + routerLink="creator/room/{{shortId}}/comments"> + <mat-icon> + forum + </mat-icon> + <span>{{'header.back-to-questionboard' | translate}}</span> + </button> + + <button mat-menu-item + tabindex="0" + *ngIf="user.role > 0 && user.role < 3" + routerLink="moderator/room/{{shortId}}/comments"> + <mat-icon> + forum + </mat-icon> + <span>{{'header.back-to-questionboard' | translate}}</span> + </button> + + </ng-container> + + <ng-container *ngIf="user && user.role == 0 && router.url.includes('/comment/')"> + + <button mat-menu-item + tabindex="0" + routerLink="participant/room/{{shortId}}/comments"> + <mat-icon> + forum + </mat-icon> + <span>{{'header.back-to-questionboard' | translate}}</span> + </button> + + </ng-container> + + <!-- Question board --> + <ng-container *ngIf="router.url.endsWith('/comments')"> + + <button mat-menu-item + *ngIf="user && !router.url.endsWith('moderator/comments')" + tabindex="0" + (click)="navigateCreateQuestion();"> + <mat-icon> + add + </mat-icon> + <span>{{'header.create-question' | translate}}</span> + </button> + + <ng-container> + + <button mat-menu-item + tabindex="0" + *ngIf="user && user.role > 0 && !router.url.includes('/participant/') && !router.url.endsWith('moderator/comments')" + routerLink="moderator/room/{{shortId}}/moderator/comments"> + <mat-icon> + visibility_off + </mat-icon> + <span>{{'header.moderationboard' | translate}}</span> + </button> + + <button mat-menu-item + tabindex="0" + *ngIf="deviceType !== 'mobile'" + routerLink="participant/room/{{shortId}}/comments/questionwall"> + <mat-icon + svgIcon="beamer"> + </mat-icon> + <span>{{'header.questionwall' | translate}}</span> + </button> + + <button mat-menu-item + tabindex="0" + (click)="navigateTopicCloud()"> + <mat-icon>cloud + </mat-icon> + <span>{{'header.tag-cloud' | translate}}</span> + </button> + + </ng-container> + <ng-container *ngIf="router.url.includes('/participant/room/')"> + </ng-container> + <ng-container *ngIf="router.url.includes('/moderator/room/')"> + </ng-container> + <ng-container *ngIf="router.url.includes('/creator/room/')"> + </ng-container> + + <button mat-menu-item + *ngIf="user" + (click)="navigateExportQuestions()" + tabindex="0"> + <mat-icon>save</mat-icon> + <span>{{'header.export-questions' | translate}}</span> + </button> + + <button mat-menu-item + *ngIf="user && user.role > 0 && !router.url.includes('/participant/')" + (click)="navigateDeleteQuestions()" + tabindex="0"> + <mat-icon class="color-warn">delete</mat-icon> + <span>{{'header.delete-questions' | translate}}</span> + </button> + + </ng-container> + + <!-- Session --> + <ng-container *ngIf="!router.url.endsWith('/comments') && !router.url.includes('/comment/')"> + + <!-- app-room-participant-page --> + <ng-container *ngIf="router.url.includes('/participant/room/')"> + </ng-container> + <!-- app-room-creator-page --> + <ng-container *ngIf="router.url.includes('/moderator/room/')"> + </ng-container> + <!-- app-room-creator-page --> + <ng-container *ngIf="router.url.includes('/creator/room/')"> + + <button mat-menu-item + *ngIf="user" + (click)="navigateRoomBonusToken()" + tabindex="0"> + <mat-icon class="star">grade</mat-icon> + <span>{{'header.bonustoken' | translate}}</span> + </button> + + <button mat-menu-item + *ngIf="user" + (click)="navigateExportQuestions()" + tabindex="0"> + <mat-icon>save</mat-icon> + <span>{{'header.export-questions' | translate}}</span> + </button> + + <button mat-menu-item + *ngIf="user" + (click)="navigateDeleteQuestions()" + tabindex="0"> + <mat-icon class="color-warn">delete</mat-icon> + <span>{{'header.delete-questions' | translate}}</span> + </button> + + </ng-container> + + </ng-container> + + <!-- Room General Options - bot --> + + <ng-container + *ngIf="user && user.role == 3 && !router.url.includes('/participant') && !router.url.includes('/comment/')"> + + <button mat-menu-item + *ngIf="user" + (click)="navigateModerator()" + tabindex="0"> + <mat-icon>gavel</mat-icon> + <span>{{'header.edit-moderator' | translate}}</span> + </button> + + <button mat-menu-item + *ngIf="user" + (click)="navigateTags()" + tabindex="0"> + <mat-icon svgIcon="comment_tag"></mat-icon> + <span>{{'header.edit-tags' | translate}}</span> + </button> + + </ng-container> + + <button mat-menu-item + *ngIf="user && user.role > 0 && !router.url.includes('/comment/') && !router.url.endsWith('/tagcloud')" + tabindex="0" + (click)="showQRDialog();"> + <mat-icon svgIcon="qrcode" + class="header-icons qrcode"> + </mat-icon> + <span>{{'header.room-qr' | translate}}</span> + </button> + + <button mat-menu-item + *ngIf="router.url.endsWith('/tagcloud')" + tabindex="0" + (click)="navigateTopicCloudConfig()"> + <mat-icon aria-label="Configuration Icon">cloud</mat-icon> + <span>{{'header.tag-cloud-config' | translate}}</span> + </button> + + <button mat-menu-item + *ngIf="router.url.endsWith('/tagcloud')" + tabindex="0" + (click)="navigateTopicCloudAdministration()"> + <mat-icon aria-hidden="false" aria-label="Control Icon">edit</mat-icon> + <span>{{'header.tag-cloud-administration' | translate}}</span> + </button> + + <button mat-menu-item + *ngIf="router.url.endsWith('/tagcloud')" + tabindex="0" + (click)="navigateCreateQuestion();"> + <mat-icon> + add + </mat-icon> + <span>{{'header.create-question' | translate}}</span> + </button> + + <button mat-menu-item + tabindex="0" + *ngIf="router.url.endsWith('/tagcloud')" + routerLink="participant/room/{{shortId}}/comments"> + <mat-icon> + forum + </mat-icon> + <span>{{'header.back-to-questionboard' | translate}}</span> + </button> + + </ng-container> + + </div> + + <!-- General Options --> + + <button mat-menu-item + *ngIf="user && !router.url.endsWith('/user')" + routerLink="/user" + tabindex="0"> + <mat-icon class="sessions">view_list</mat-icon> + <span *ngIf="!user.isGuest">{{'header.my-sessions' | translate}}</span> + <span *ngIf="user.isGuest" + svgIcon="meeting_room">{{'header.visited-sessions' | translate}}</span> + </button> + + <button mat-menu-item + *ngIf="user" + (click)="openUserBonusTokenDialog()" + tabindex="0"> + <mat-icon class="star">grade</mat-icon> + <span>{{'header.user-bonus-token' | translate}}</span> + </button> + + <button mat-menu-item + *ngIf="user" + (click)="showMotdDialog()"> + <mat-icon> + {{ motdState ? 'notifications_active' : 'notifications_none' }} + </mat-icon> + <span>{{'header.motd' | translate}}</span> + </button> + + <button mat-menu-item + aria-hidden="true" + *ngIf="isSafari === 'false' && !router.url.includes('home')" + (click)="getRescale().toggleState();"> + <mat-icon (click)="getRescale().toggleState();">format_size + </mat-icon> + <span>{{'header.fullscreen' | translate}}</span> + </button> + + <mat-divider></mat-divider> + + <button mat-menu-item + *ngIf="user && !user.isGuest && user.loginId" + (click)="openDeleteUserDialog()" + tabindex="0"> + <mat-icon class="color-warn">delete</mat-icon> + <span>{{'header.delete-account' | translate}}</span> + </button> + + <button mat-menu-item + (click)="logout()" + tabindex="0"> + <mat-icon class="color-warn">exit_to_app</mat-icon> + <span>{{ 'header.logout' | translate }}</span> + </button> + + </mat-menu> + + <button [disabled]="cookiesDisabled()" + mat-button + *ngIf="user && deviceType === 'desktop'" + [matMenuTriggerFor]="userMenu" + aria-labelledby="session-label" + id="session-button"> + <div class="label-icon"> + <mat-icon *ngIf="!user.isGuest" + class="header-icons">more_vert + </mat-icon> + <mat-icon *ngIf="user.isGuest" + svgIcon="meeting_room" + class="header-icons"></mat-icon> + <h2 class="oldtypo-h2" + *ngIf="!user.isGuest">{{'header.my-account' | translate}}</h2> + <!--Guest Account--> + <h2 class="oldtypo-h2" + *ngIf="user.isGuest">{{'header.my-guest-account' | translate}}</h2> + </div> + </button> + + <button [disabled]="cookiesDisabled()" + mat-icon-button + *ngIf="user && deviceType === 'mobile'" + [matMenuTriggerFor]="userMenu" + aria-labelledby="session-label"> + <mat-icon *ngIf="!user.isGuest" + class="header-icons">more_vert + </mat-icon> + <mat-icon *ngIf="user.isGuest" + svgIcon="meeting_room" + class="header-icons"></mat-icon> + </button> + + <button id="login-button" + [disabled]="cookiesDisabled()" + mat-button + *ngIf="!user && deviceType === 'desktop'" + (click)=login(false) + aria-labelledby="login-label"> + <div class="label-icon"> + <mat-icon class="header-icons">person</mat-icon> + <h2 class="oldtypo-h2" + *ngIf="deviceType === 'desktop'">{{'header.login' | translate}}</h2> + </div> + </button> + + <button [disabled]="cookiesDisabled()" + mat-icon-button + *ngIf="!user && deviceType === 'mobile'" + (click)=login(false) + aria-labelledby="login-label"> + <mat-icon class="header-icons">person</mat-icon> + </button> + </mat-toolbar-row> +</mat-toolbar> + +<div class="visually-hidden"> + <div id="login-label">{{'header.accessibility-login' | translate}}</div> + <div id="back-label">{{'header.accessibility-back' | translate}}</div> + <div id="session-label">{{'header.accessibility-session' | translate}}</div> +</div> diff --git a/src/app/components/shared/header/header.component.ts b/src/app/components/shared/header/header.component.ts index 7b8e4898d12893ef8d0672ecf39e490798c82434..e24a38bb68ebff49b694cb41dd78af6a3efbb33c 100644 --- a/src/app/components/shared/header/header.component.ts +++ b/src/app/components/shared/header/header.component.ts @@ -21,6 +21,7 @@ import { QrCodeDialogComponent } from '../_dialogs/qr-code-dialog/qr-code-dialog import { BonusTokenService } from '../../../services/http/bonus-token.service'; import { MotdService } from '../../../services/http/motd.service'; import { RoomService } from '../../../services/http/room.service'; +import { TopicCloudFilterComponent } from '../_dialogs/topic-cloud-filter/topic-cloud-filter.component'; @Component({ selector: 'app-header', @@ -46,7 +47,8 @@ export class HeaderComponent implements OnInit { public eventService: EventService, private bonusTokenService: BonusTokenService, private _r: Renderer2, - private motdService: MotdService + private motdService: MotdService, + private confirmDialog: MatDialog ) { } @@ -282,6 +284,12 @@ export class HeaderComponent implements OnInit { this.eventService.broadcast('navigate', 'createQuestion'); } + public navigateTopicCloud() { + const confirmDialogRef = this.confirmDialog.open(TopicCloudFilterComponent, { + autoFocus: false + }); + } + public navigateTopicCloudConfig() { this.eventService.broadcast('navigate', 'topicCloudConfig'); } diff --git a/src/app/components/shared/shared-routing.module.ts b/src/app/components/shared/shared-routing.module.ts index eda595540c19843a47e701ac7bb91f19ed80a6f3..1b15001b4ed5cbe84fea53fb90a22f39e4301622 100644 --- a/src/app/components/shared/shared-routing.module.ts +++ b/src/app/components/shared/shared-routing.module.ts @@ -3,7 +3,7 @@ import { NgModule } from '@angular/core'; import { QuestionWallComponent } from './questionwall/question-wall/question-wall.component'; import { AuthenticationGuard } from '../../guards/authentication.guard'; import { UserRole } from '../../models/user-roles.enum'; -import {TagCloudComponent} from "./tag-cloud/tag-cloud.component"; +import { TagCloudComponent } from './tag-cloud/tag-cloud.component'; const routes: Routes = [ { diff --git a/src/app/components/shared/shared.module.ts b/src/app/components/shared/shared.module.ts index 80e4999179ef44d0f585a40fcb29a7499767df2e..1ef5d48fe434617cdabeedeac4cfc440617c637c 100644 --- a/src/app/components/shared/shared.module.ts +++ b/src/app/components/shared/shared.module.ts @@ -33,6 +33,8 @@ import { TagCloudModule } from 'angular-tag-cloud-module'; import { TopicCloudConfirmDialogComponent } from './_dialogs/topic-cloud-confirm-dialog/topic-cloud-confirm-dialog.component'; import { TopicCloudAdministrationComponent } from './_dialogs/topic-cloud-administration/topic-cloud-administration.component'; import { TopicDialogCommentComponent } from './dialog/topic-dialog-comment/topic-dialog-comment.component'; +import { TopicCloudFilterComponent } from './_dialogs/topic-cloud-filter/topic-cloud-filter.component'; +import { SpacyDialogComponent } from './_dialogs/spacy-dialog/spacy-dialog.component'; @NgModule({ imports: [ @@ -70,7 +72,9 @@ import { TopicDialogCommentComponent } from './dialog/topic-dialog-comment/topic MotdMessageComponent, TopicCloudConfirmDialogComponent, TopicCloudAdministrationComponent, - TopicDialogCommentComponent + TopicDialogCommentComponent, + TopicCloudFilterComponent, + SpacyDialogComponent ], exports: [ RoomJoinComponent, @@ -85,7 +89,7 @@ import { TopicDialogCommentComponent } from './dialog/topic-dialog-comment/topic PresentCommentComponent, CommentComponent, DialogActionButtonsComponent, - UserBonusTokenComponent, + UserBonusTokenComponent ] }) export class SharedModule { diff --git a/src/app/components/shared/tag-cloud/tag-cloud.component.ts b/src/app/components/shared/tag-cloud/tag-cloud.component.ts index 507117dc166c0b795af95ff93c210893e82e81c7..1c1ec64ae35949f065204669b61bdaac33e67fe3 100644 --- a/src/app/components/shared/tag-cloud/tag-cloud.component.ts +++ b/src/app/components/shared/tag-cloud/tag-cloud.component.ts @@ -226,7 +226,7 @@ export class TagCloudComponent implements OnInit { }); }); this.translateService.use(localStorage.getItem('currentLang')); - this.commentService.getAckComments(this.roomId).subscribe((comments: Comment[]) => { + this.commentService.getFilteredComments(this.roomId).subscribe((comments: Comment[]) => { this.analyse(comments); }); this.themeService.getTheme().subscribe(() => { diff --git a/src/app/models/comment.ts b/src/app/models/comment.ts index 0fa257cc7c6b14d4dd5605a91a68592249d3c467..1d488d077c1638391e1b98accac44441fe1eb5c0 100644 --- a/src/app/models/comment.ts +++ b/src/app/models/comment.ts @@ -20,6 +20,7 @@ export class Comment { answer: string; userNumber: number; number: number; + keywords: string[]; constructor(roomId: string = '', creatorId: string = '', @@ -35,7 +36,8 @@ export class Comment { ack: boolean = true, tag: string = '', answer: string = '', - userNumber: number = 0) { + userNumber: number = 0, + keywords: string[] = []) { this.id = ''; this.roomId = roomId; this.creatorId = creatorId; @@ -53,5 +55,6 @@ export class Comment { this.tag = tag; this.answer = answer; this.userNumber = userNumber; + this.keywords = keywords; } } diff --git a/src/app/services/http/comment.service.ts b/src/app/services/http/comment.service.ts index cb19d5f274c60bcfaa8be2a16e5598e50c8d5e59..ef2533769c7ebeb2b64e86254d678fbb804821e6 100644 --- a/src/app/services/http/comment.service.ts +++ b/src/app/services/http/comment.service.ts @@ -82,7 +82,7 @@ export class CommentService extends BaseHttpService { return this.http.post<Comment>(connectionUrl, { roomId: comment.roomId, body: comment.body, - read: comment.read, creationTimestamp: comment.timestamp, tag: comment.tag + read: comment.read, creationTimestamp: comment.timestamp, tag: comment.tag, keywords: comment.keywords }, httpOptions).pipe( tap(_ => ''), catchError(this.handleError<Comment>('addComment')) @@ -97,6 +97,101 @@ export class CommentService extends BaseHttpService { ); } + + filter(com : Comment) : boolean { + /* Get Filter Options */ + const currentFilters = JSON.parse(localStorage.getItem('currentFilters')); + const period = JSON.parse(localStorage.getItem('currentPeriod')); + const timestamp = JSON.parse(localStorage.getItem('currentFromNowTimestamp')); + + /* Filter by Period */ + const currentTime = new Date(); + const hourInSeconds = 3600000; + let periodInSeconds; + + enum Period { + FROMNOW = 'from-now', + ONEHOUR = 'time-1h', + THREEHOURS = 'time-3h', + ONEDAY = 'time-1d', + ONEWEEK = 'time-1w', + TWOWEEKS = 'time-2w', + ALL = 'time-all' + } + + if (period !== Period.ALL) { + switch (period) { + case Period.FROMNOW: + break; + case Period.ONEHOUR: + periodInSeconds = hourInSeconds; + break; + case Period.THREEHOURS: + periodInSeconds = hourInSeconds * 2; + break; + case Period.ONEDAY: + periodInSeconds = hourInSeconds * 24; + break; + case Period.ONEWEEK: + periodInSeconds = hourInSeconds * 168; + break; + case Period.TWOWEEKS: + periodInSeconds = hourInSeconds * 336; + break; + } + } + + const commentTime = new Date(com.timestamp).getTime(); + const refTime = (period === Period.FROMNOW ? timestamp : (currentTime.getTime() - periodInSeconds)); + + if (commentTime < refTime) { + return false; + } + + /* Other Filters */ + const read = 'read'; + const unread = 'unread'; + const favorite = 'favorite'; + const correct = 'correct'; + const wrong = 'wrong'; + const bookmark = 'bookmark'; + const answer = 'answer'; + const unanswered = 'unanswered'; + + enum CorrectWrong { + NULL, + CORRECT, + WRONG + } + + if (currentFilters != '') { // no filters => return true + switch (currentFilters) { + case correct: + return com.correct === CorrectWrong.CORRECT ? true : false; + case wrong: + return com.correct === CorrectWrong.WRONG ? true : false; + case favorite: + return com.favorite; + case bookmark: + return com.bookmark; + case read: + return com.read; + case unread: + return !com.read; + case answer: + return com.answer != ""; + case unanswered: + return !com.answer; + } + } + + return true; + } + + getFilteredComments(roomId: string) : Observable<Comment[]> { + return this.getAckComments(roomId).pipe(map(commentList => commentList.filter(comment => this.filter(comment)))); + } + getAckComments(roomId: string): Observable<Comment[]> { const connectionUrl = this.apiUrl.base + this.apiUrl.comment + this.apiUrl.find; return this.http.post<Comment[]>(connectionUrl, { diff --git a/src/app/services/http/spacy.service.ts b/src/app/services/http/spacy.service.ts index b7d61bfdf4e456091a4887b6f411b18eca0aa186..11625da1fe470bbe316e3a1f5498facf1f1cac10 100644 --- a/src/app/services/http/spacy.service.ts +++ b/src/app/services/http/spacy.service.ts @@ -1,8 +1,8 @@ -import {Injectable} from '@angular/core'; -import {HttpClient, HttpHeaders} from '@angular/common/http'; -import {Observable} from 'rxjs'; -import {BaseHttpService} from './base-http.service'; -import {catchError} from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { BaseHttpService } from './base-http.service'; +import { catchError } from 'rxjs/operators'; export class Result { arcs: Arc[]; diff --git a/src/assets/i18n/creator/de.json b/src/assets/i18n/creator/de.json index 3b293d5425b1a8a1643295278635303b458900fb..c5951a6dc0dbf79c6dce72b937188ada431f49f7 100644 --- a/src/assets/i18n/creator/de.json +++ b/src/assets/i18n/creator/de.json @@ -81,6 +81,13 @@ "no-comments": "Es sind noch keine Fragen vorhanden.", "export-comments": "Fragen speichern" }, + "spacy-dialog":{ + "german": "Deutsch", + "english": "Englisch", + "french": "Französisch", + "empty-nouns": "Keine Nomen enthalten", + "select-all": "Alles auswählen" + }, "comment-page": { "a11y-comment_delete": "Löscht diese Frage", "a11y-comment_grade": "Markiert diese Frage als Bonus-Frage", @@ -171,7 +178,7 @@ "edit-favorite-reset": "Markierung zurücksetzen", "edit-bookmark": "Lesezeichen setzen", "edit-bookmark-reset": "Markierung zurücksetzen" - }, + }, "content": { "abort": "Abbrechen", "actions": "Option", diff --git a/src/assets/i18n/creator/en.json b/src/assets/i18n/creator/en.json index b038a98933609a23bade67de7c2a5fe11a7c3173..a484ae037827db0557da368589b936d42746de7f 100644 --- a/src/assets/i18n/creator/en.json +++ b/src/assets/i18n/creator/en.json @@ -82,6 +82,13 @@ "no-comments": "There are no questions yet.", "export-comments": "Save questions" }, + "spacy-dialog": { + "german": "German", + "english": "English", + "french": "French", + "empty-nouns": "No nouns included", + "select-all": "Select all" + }, "comment-page": { "a11y-comment_delete": "Deletes this question", "a11y-comment_grade": "Marks this question as a bonus question", diff --git a/src/assets/i18n/home/de.json b/src/assets/i18n/home/de.json index bfbab314006fa64e8ac79f1782d30dd4ec06d463..2b479ee8c3314b36a78739f99b38354e51e91b2f 100644 --- a/src/assets/i18n/home/de.json +++ b/src/assets/i18n/home/de.json @@ -45,6 +45,15 @@ "motd-title-new": "Aktuell", "motd-mark-read": "Gelesen" }, + "content": { + "topic-cloud-content": "Weiter zur Topic-Cloud mit den aktuellen Filtern?", + "cancel": "Abbrechen", + "continue": "Weiter", + "reset": "Zurücksetzen", + "continue-with-all-questions" : "Weiter mit kompletter Fragenliste", + "continue-with-current-questions": "Weiter mit aktuellen Filtern", + "continue-with-all-questions-from-now": "Weiter mit allen Fragen ab jetzt" + }, "header": { "abort": "Abbrechen", "accessibility-back": "Führt zur vorherigen Seite", diff --git a/src/assets/i18n/home/en.json b/src/assets/i18n/home/en.json index c06841d49ed87d62bfad519ea9119d316e3327ea..3dda55a3730c7f2a357d3ad41fa2cd9dcf125d60 100644 --- a/src/assets/i18n/home/en.json +++ b/src/assets/i18n/home/en.json @@ -118,6 +118,16 @@ "custom-shortid-placeholder": "a-z, A-Z, 0-9, - _ . ~ no blanks", "invalid-shortid": "This key code is not available.", "invalid-char-shortid": "This key code contains invalid characters." + }, + "content": { + "topic-cloud-content": "Continue to the Topic Cloud with the current filters?", + "cancel": "Cancel", + "continue": "Continue", + "reset": "Reset", + "continue-with-all-questions" : "Continue with complete list of questions", + "continue-with-current-questions": "Continue with current filters", + "continue-with-all-questions-from-now": "Continue with all questions from now" + }, "imprint": { "cancel": "Close", diff --git a/src/assets/i18n/participant/de.json b/src/assets/i18n/participant/de.json index 71c5ea7243c3ec071691677896ade9742e45c5c2..8cd5bcd856acf905241b0538da92738767d5b452 100644 --- a/src/assets/i18n/participant/de.json +++ b/src/assets/i18n/participant/de.json @@ -86,6 +86,13 @@ "cancel": "Abbrechen", "delete": "Löschen" }, + "spacy-dialog":{ + "german": "Deutsch", + "english": "Englisch", + "french": "Französisch", + "empty-nouns": "Keine Nomen enthalten", + "select-all": "Alles auswählen" + }, "comment-page": { "a11y-comment_input": "Gib deine Frage ein", "a11y-comment_vote_down": "Diese Frage abwerten", diff --git a/src/assets/i18n/participant/en.json b/src/assets/i18n/participant/en.json index c893ed58b2bac8dad98347bd2484cf800736f20d..cd96ce1ea92700b10efb2aca64f2216f32efa0ef 100644 --- a/src/assets/i18n/participant/en.json +++ b/src/assets/i18n/participant/en.json @@ -96,6 +96,13 @@ "cancel": "Cancel", "delete": "Delete" }, + "spacy-dialog": { + "german": "German", + "english": "English", + "french": "French", + "empty-nouns": "No nouns included", + "select-all": "Select all" + }, "comment-page": { "a11y-comment_input": "Enter your question", "a11y-comment_vote_down": "Votes down this question",