Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • arsnova/arsnova-lite
1 result
Show changes
Commits on Source (41)
Showing
with 316 additions and 126 deletions
......@@ -72,6 +72,8 @@ import { ContentListComponent } from './content-list/content-list.component';
import { ContentService } from './content.service';
import { ContentAnswersListComponent } from './content-answers-list/content-answers-list.component';
import { ContentAnswerService } from './content-answer.service';
import { RoomDeletionComponent } from './room-deletion/room-deletion.component';
import { RoomModificationComponent } from './room-modification/room-modification.component';
@NgModule({
declarations: [
......@@ -97,12 +99,16 @@ import { ContentAnswerService } from './content-answer.service';
CreatorRoomComponent,
ContentDetailComponent,
ContentListComponent,
ContentAnswersListComponent
ContentAnswersListComponent,
RoomDeletionComponent,
RoomModificationComponent
],
entryComponents: [
RegisterComponent,
PasswordResetComponent,
RoomCreationComponent
RoomCreationComponent,
RoomDeletionComponent,
RoomModificationComponent
],
imports: [
AppRoutingModule,
......
<div fxLayout="column" fxLayoutAlign="center" fxLayoutGap="10">
<div *ngFor="let comment of comments">
<mat-card>
<mat-card-content>
<div class="comment-body">
<h3>{{comment.subject}}</h3><br>
<div fxLayout="row" fxLayoutAlign="center">
<div fxLayout="column" fxLayoutGap="20px">
<div *ngFor="let comment of comments">
<mat-card>
<mat-card-content>
<h3>{{comment.subject}}</h3>
{{comment.body}}
{{comment.body}}
<div class="trash-icon">
<i class="material-icons" (click)="delete(comment)">delete</i>
</div>
</div>
</mat-card-content>
<mat-card-footer>
<div class="date">
<i> Submitted on {{comment.creationTimestamp | date:'dd-MM-yyyy HH:mm:ss' : format}} </i>
</div>
</mat-card-footer>
</mat-card><br>
<div class="body-buttons" fxLayout="Column" fxLayoutGap="5px" fxLayoutAlign="end">
<button *ngIf="!comment.read" mat-fab color="warn" matTooltip="Is not read" (click)="setRead(comment)">
<mat-icon>clear</mat-icon>
</button>
<button *ngIf="comment.read" mat-fab color="primary" matTooltip="Is read" (click)="setRead(comment)">
<mat-icon>check</mat-icon>
</button>
<button class="trash-icon" mat-fab color="primary" matTooltip="Delete" (click)="delete(comment)">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-card-content>
<mat-card-footer>
<div class="date">
<i> Submitted on {{comment.creationTimestamp | date:'dd-MM-yyyy HH:mm:ss' : format}} </i>
</div>
</mat-card-footer>
</mat-card><br>
</div>
<button class="back-button" mat-raised-button color="primary" (click)="goBack()">Back</button>
</div>
</div>
<button mat-raised-button color="primary" (click)="goBack()">Back</button>
.trash-icon {
mat-card {
min-width: 800px;
justify-content: center;
}
mat-card-content {
min-height: 100px;
}
mat-card:hover {
box-shadow: 0 6px 6px 6px rgba(0,0,0,.2), 0 6px 6px 0 rgba(0,0,0,.14), 0 6px 6px 0 rgba(0,0,0,.12) !important;
transition: background .4s cubic-bezier(.25,.8,.25,1),box-shadow 300ms cubic-bezier(.3,0,.2,1);
}
.trash-icon:hover {
background: #F44336;
}
.back-button {
min-width: 800px;
}
.body-buttons {
position: absolute;
top: 50%;
left: 98%;
top: 10%;
left: 92%;
}
.date {
text-align: right;
font-size: 80%;
margin-right: 10px;
margin-bottom: 3px;
}
import { Component, Input, OnInit } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { Comment } from '../comment';
import { CommentService} from '../comment.service';
import { CommentService } from '../comment.service';
import { RoomService } from '../room.service';
import { NotificationService } from '../notification.service';
......@@ -30,15 +30,20 @@ export class CommentListComponent implements OnInit {
getRoom(id: string): void {
this.roomService.getRoom(id).subscribe(
params => {
this.getComments(params['id'], params['name']);
this.getComments(params['id']);
});
}
getComments(roomId: string, roomName: string): void {
getComments(roomId: string): void {
this.commentService.getComments(roomId)
.subscribe(comments => this.comments = comments);
}
setRead(comment: Comment): void {
this.comments.find( c => c.id === comment.id).read = !comment.read;
this.commentService.updateComment(comment).subscribe();
}
delete(comment: Comment): void {
this.comments = this.comments.filter(c => c !== comment);
this.commentService.deleteComment(comment).subscribe(room => {
......
......@@ -39,4 +39,11 @@ export class CommentService extends ErrorHandlingService {
catchError(this.handleError<Comment[]>('getComments', []))
);
}
updateComment(comment: Comment): Observable<any> {
return this.http.put(this.commentsUrl, comment, httpOptions).pipe(
tap(_ => ''),
catchError(this.handleError<any>('updateComment'))
);
}
}
......@@ -16,8 +16,9 @@ export class ContentAnswerService extends ErrorHandlingService {
super();
}
getAnswerTexts(): Observable<AnswerText[]> {
return this.http.get<AnswerText[]>(this.answerUrl).pipe(
getAnswerTexts(contentId: string): Observable<AnswerText[]> {
const url = `${this.answerUrl}/?contentId=${contentId}`;
return this.http.get<AnswerText[]>(url).pipe(
catchError(this.handleError('getAnswerTexts', []))
);
}
......
import { Component, OnInit } from '@angular/core';
import { ContentAnswerService } from '../content-answer.service';
import { AnswerText } from '../answer-text';
import { ActivatedRoute } from '@angular/router';
import { ContentService } from '../content.service';
@Component({
selector: 'app-content-answers-list',
......@@ -10,15 +12,27 @@ import { AnswerText } from '../answer-text';
export class ContentAnswersListComponent implements OnInit {
textAnswers: AnswerText[];
constructor(private contentAnswerService: ContentAnswerService) { }
constructor(
private contentService: ContentService,
private contentAnswerService: ContentAnswerService,
private route: ActivatedRoute
) { }
ngOnInit() {
this.getAnswerTexts();
this.route.params.subscribe(params => {
this.getContent(params['id']);
});
}
getAnswerTexts(): void {
this.contentAnswerService.getAnswerTexts().
subscribe(textAnswers => {
getContent(id: string): void {
this.contentService.getContent(id).subscribe(params => {
this.getAnswerTexts(params['id']);
})
}
getAnswerTexts(id: string): void {
this.contentAnswerService.getAnswerTexts(id)
.subscribe(textAnswers => {
this.textAnswers = textAnswers;
});
}
......
import { Component, OnInit } from '@angular/core';
import { ContentService } from '../content.service';
import { Content } from '../content';
import { ActivatedRoute } from '@angular/router';
import { RoomService } from '../room.service';
@Component({
selector: 'app-content-list',
......@@ -10,14 +12,27 @@ import { Content } from '../content';
export class ContentListComponent implements OnInit {
contents: Content[];
constructor(private contentService: ContentService) { }
constructor(
private contentService: ContentService,
private route: ActivatedRoute,
private roomService: RoomService,
) { }
ngOnInit() {
this.getContents();
this.route.params.subscribe(params => {
this.getRoom(params['roomId']);
});
}
getRoom(id: string): void {
this.roomService.getRoom(id).subscribe(
params => {
this.getContents(params['id']);
});
}
getContents(): void {
this.contentService.getContents()
getContents(roomId: string): void {
this.contentService.getContents(roomId)
.subscribe(contents => {
this.contents = contents;
});
......
......@@ -16,8 +16,9 @@ export class ContentService extends ErrorHandlingService {
super();
}
getContents(): Observable<Content[]> {
return this.http.get<Content[]>(this.contentUrl).pipe(
getContents(roomId: string): Observable<Content[]> {
const url = `${this.contentUrl}/?roomId=${roomId}`;
return this.http.get<Content[]>(url).pipe(
catchError(this.handleError('getContents', []))
);
}
......
<div fxLayout="column" fxLayoutAlign="start" fxLayoutGap="20px" fxFill>
<div fxLayout="row" fxLayoutAlign="center">
<mat-card *ngIf="room && !modify && !deleteDialog" class="input-form">
<mat-card *ngIf="room" class="input-form">
<mat-card-header>
<mat-card-title>
<h3 class="subheading-2">{{ room.name }}</h3>
......@@ -30,13 +30,10 @@
routerLink="/creator/room/{{room.id}}/comments">
Comments
</button>
<button *ngIf="!modify" (click)="showEditDialog()" mat-button color="primary">
<button (click)="showEditDialog()" mat-button color="primary">
Edit room
</button>
<button *ngIf="modify" (click)="updateRoom(roomName.valueOf(), roomShortID.valueOf(), roomDescription.valueOf())" mat-button color="primary" matTooltip="Update room's details">
Update room
</button>
<button mat-button color="warn" (click)="showDeletionDialog()">
<button mat-button color="warn" (click)="openDeletionRoomDialog()">
Delete room
</button>
<button mat-button color="primary" (click)="goBack()">
......@@ -44,44 +41,6 @@
</button>
</mat-card-actions>
</mat-card>
<mat-card *ngIf="modify && room" class="input-form">
<mat-card-header>
<h3>Modify properties</h3>
</mat-card-header>
<mat-card-content fxLayout="column">
<mat-form-field *ngIf="modify">
<input [(ngModel)]="room.name" #roomName matInput/>
</mat-form-field>
<mat-form-field>
<input [(ngModel)]="room.shortId" #roomShortID matInput/>
</mat-form-field>
<mat-form-field>
<textarea [(ngModel)]="room.description" #roomDescription matInput matTextareaAutosize
matAutosizeMinRows="2"
matAutosizeMaxRows="5"></textarea>
</mat-form-field>
</mat-card-content>
<mat-card-actions>
<button (click)="hideEditDialog()" mat-button color="primary">
Leave
</button>
<button (click)="updateRoom()" mat-button color="primary">
Update
</button>
</mat-card-actions>
</mat-card>
<mat-card *ngIf="deleteDialog">
<mat-card-header><h3>Do you really want to delete this room?<br>This action can not be undone.</h3>
</mat-card-header>
<mat-card-content>
<button mat-raised-button color="warn" (click)="deleteRoom(room)">
Delete room
</button>
<button mat-raised-button color="primary" (click)="hideDeletionDialog()">
Leave
</button>
</mat-card-content>
</mat-card>
<div *ngIf="!isLoading && !room">Error: room could not be found!</div>
</div>
</div>
......@@ -5,6 +5,9 @@ import { RoomComponent } from '../room/room.component';
import { Room } from '../room';
import { Location } from '@angular/common';
import { NotificationService } from '../notification.service';
import { MatDialog } from '@angular/material';
import { RoomDeletionComponent } from '../room-deletion/room-deletion.component';
import { RoomModificationComponent } from '../room-modification/room-modification.component';
@Component({
selector: 'app-creator-room',
......@@ -13,15 +16,12 @@ import { NotificationService } from '../notification.service';
})
export class CreatorRoomComponent extends RoomComponent implements OnInit {
room: Room;
modify = false;
deleteDialog = false;
roomName: string;
roomShortId: string;
roomDescription: string;
updRoom: Room;
constructor(protected roomService: RoomService,
protected notification: NotificationService,
protected route: ActivatedRoute,
public dialog: MatDialog,
protected location: Location) {
super(roomService, route, location);
}
......@@ -36,41 +36,64 @@ export class CreatorRoomComponent extends RoomComponent implements OnInit {
this.location.back();
}
showEditDialog(): void {
this.roomName = this.room.name;
this.roomShortId = this.room.shortId;
this.roomDescription = this.room.description;
this.modify = true;
}
hideEditDialog(): void {
this.modify = false;
}
updateRoom(): void {
if ((this.roomName === this.room.name) &&
(this.roomShortId === this.room.shortId) &&
(this.roomDescription === this.room.description)
if ((this.updRoom.name === this.room.name) &&
(this.updRoom.shortId === this.room.shortId) &&
(this.updRoom.description === this.room.description)
) {
this.notification.show('There were no changes');
return;
} else {
this.notification.show('Changes are made');
this.room.name = this.updRoom.name;
this.room.shortId = this.updRoom.shortId;
this.room.description = this.updRoom.description;
this.roomService.updateRoom(this.room)
.subscribe(() => this.goBack());
.subscribe();
}
}
showDeletionDialog(): void {
this.deleteDialog = true;
}
hideDeletionDialog(): void {
this.deleteDialog = false;
}
deleteRoom(room: Room): void {
const msg = room.name + ' deleted';
this.notification.show(msg);
this.delete(room);
}
confirmDeletion(dialogAnswer: string): void {
if (dialogAnswer === 'delete') {
this.deleteRoom(this.room);
}
}
openDeletionRoomDialog(): void {
const dialogRef = this.dialog.open(RoomDeletionComponent, {
width: '400px'
});
dialogRef.componentInstance.room = this.room;
dialogRef.afterClosed()
.subscribe(result => {
this.confirmDeletion(result);
});
}
showEditDialog(): void {
this.updRoom = new Room();
this.updRoom.name = this.room.name;
this.updRoom.shortId = this.room.shortId;
this.updRoom.description = this.room.description;
const dialogRef = this.dialog.open(RoomModificationComponent, {
width: '400px'
});
dialogRef.componentInstance.editRoom = this.updRoom;
dialogRef.afterClosed()
.subscribe(result => {
if (result === 'abort') {
return;
}
if (result === 'edit') {
this.updateRoom();
}
});
}
}
......@@ -107,7 +107,7 @@ export class InMemoryDataService implements InMemoryDbService {
{
id: '1',
revision: '1',
contendId: '1',
contentId: '1',
round: '1',
subject: 'Textaufgabe 1',
body: 'gamma, delta',
......@@ -117,7 +117,7 @@ export class InMemoryDataService implements InMemoryDbService {
{
id: '1',
revision: '1',
contendId: '1',
contentId: '1',
round: '1',
subject: 'Textaufgabe 1',
body: 'epsilon, phi',
......@@ -127,7 +127,7 @@ export class InMemoryDataService implements InMemoryDbService {
{
id: '2',
revision: '2',
contendId: '2',
contentId: '2',
round: '3',
subject: 'Textaufgabe 2',
body: 'Der Turm ist 20m hoch',
......
<form>
<div fxLayout="row" fxLayoutAlign="center" fxLayoutGap="10px">
<mat-form-field class="input-block">
<input matInput #roomId placeholder="Room-Id"/>
</mat-form-field>
<button mat-fab color="primary" routerLink="room/{{ roomId.value }}">
<mat-icon>send</mat-icon>
</button>
</div>
<form (ngSubmit)="joinRoom(roomId.value)">
<div fxLayout="row" fxLayoutAlign="center" fxLayoutGap="10px">
<mat-form-field class="input-block">
<input matInput #roomId placeholder="Room-Id" [formControl]="roomFormControl"
[errorStateMatcher]="matcher" maxlength="8"/>
<mat-hint align="end">{{roomId.value.length}} / 8</mat-hint>
<mat-error *ngIf="roomFormControl.hasError('required')">Please enter a room-id.</mat-error>
</mat-form-field>
<button mat-fab color="primary" (click)="joinRoom(roomId.value)">
<mat-icon>send</mat-icon>
</button>
</div>
</form>
import { Component, OnInit } from '@angular/core';
import { Room } from '../room';
import { RoomService } from '../room.service';
import { Router } from '@angular/router';
import { RegisterErrorStateMatcher } from '../register/register.component';
import { FormControl, FormGroupDirective, NgForm, Validators } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material';
import { NotificationService } from '../notification.service';
export class JoinErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
const isSubmitted = form && form.submitted;
return (control && control.invalid && (control.dirty || control.touched || isSubmitted));
}
}
@Component({
selector: 'app-join-room',
......@@ -7,9 +21,34 @@ import { Component, OnInit } from '@angular/core';
})
export class JoinRoomComponent implements OnInit {
constructor() { }
room: Room;
isExisting = true;
roomFormControl = new FormControl('', [Validators.required]);
matcher = new RegisterErrorStateMatcher();
constructor(private roomService: RoomService,
private router: Router,
public notificationService: NotificationService
) {
}
ngOnInit() {
}
joinRoom(id: string): void {
if (!this.roomFormControl.hasError('required')) {
this.roomService.getRoom(id)
.subscribe(room => {
this.room = room;
if (!room) {
this.notificationService.show(`No room was found with id: ${id}`);
} else {
this.router.navigate([`/participant/room/${this.room.id}`]);
}
});
}
}
}
<h3>Are you sure?</h3>
<p>Do you really want to delete room <strong>{{room.name}}</strong>? This action can not be undone.</p>
<div fxLayout="row" fxLayoutAlign="center" fxLayoutGap="10px">
<button mat-raised-button color="warn" (click)="dialogRef.close('delete')">
Delete room
</button>
<button mat-raised-button color="primary" (click)="onNoClick()">
Leave
</button>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RoomDeletionComponent } from './room-deletion.component';
describe('RoomDeletionComponent', () => {
let component: RoomDeletionComponent;
let fixture: ComponentFixture<RoomDeletionComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ RoomDeletionComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(RoomDeletionComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, Inject, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
import { NotificationService } from '../notification.service';
import { RoomCreationComponent } from '../room-creation/room-creation.component';
import { RoomService } from '../room.service';
import { Room } from '../room';
@Component({
selector: 'app-room-deletion',
templateUrl: './room-deletion.component.html',
styleUrls: ['./room-deletion.component.scss']
})
export class RoomDeletionComponent implements OnInit {
room: Room;
constructor(private roomService: RoomService,
private router: Router,
private notification: NotificationService,
public dialogRef: MatDialogRef<RoomCreationComponent>,
@Inject(MAT_DIALOG_DATA) public data: any) {
}
onNoClick(): void {
this.dialogRef.close();
}
ngOnInit() {
}
}
<div *ngIf="editRoom">
<mat-form-field class="input-block">
<input [(ngModel)]="editRoom.name" #roomName matInput/>
</mat-form-field>
<mat-form-field class="input-block">
<input [(ngModel)]="editRoom.shortId" #roomShortID matInput/>
</mat-form-field>
<mat-form-field class="input-block">
<textarea [(ngModel)]="editRoom.description" #roomDescription matInput matTextareaAutosize
matAutosizeMinRows="2"
matAutosizeMaxRows="5"></textarea>
</mat-form-field>
<div fxLayout="row" fxLayoutAlign="center" fxLayoutGap="10px">
<button (click)="dialogRef.close('abort')" mat-button color="primary">
Leave
</button>
<button (click)="dialogRef.close('edit')" mat-button color="primary">
Update
</button>
</div>
</div>