forked from doubtfire-lms/doubtfire-web
-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: enable students to request extra scorm attempt
- Loading branch information
Showing
17 changed files
with
402 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
src/app/api/models/task-comment/scorm-extension-comment.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import {Observable} from 'rxjs'; | ||
import {tap} from 'rxjs/operators'; | ||
import {AppInjector} from 'src/app/app-injector'; | ||
import {TaskCommentService} from '../../services/task-comment.service'; | ||
import {TaskComment, Task} from '../doubtfire-model'; | ||
|
||
export class ScormExtensionComment extends TaskComment { | ||
assessed: boolean; | ||
granted: boolean; | ||
dateAssessed: Date; | ||
taskScormExtensions: number; | ||
|
||
constructor(task: Task) { | ||
super(task); | ||
} | ||
|
||
private assessScormExtension(): Observable<TaskComment> { | ||
const tcs: TaskCommentService = AppInjector.get(TaskCommentService); | ||
return tcs.assessScormExtension(this).pipe( | ||
tap((tc: TaskComment) => { | ||
const scormExtension: ScormExtensionComment = tc as ScormExtensionComment; | ||
|
||
const task = tc.task; | ||
task.scormExtensions = scormExtension.taskScormExtensions; | ||
}), | ||
); | ||
} | ||
|
||
public deny(): Observable<TaskComment> { | ||
this.granted = false; | ||
return this.assessScormExtension(); | ||
} | ||
|
||
public grant(): Observable<TaskComment> { | ||
this.granted = true; | ||
return this.assessScormExtension(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
src/app/common/modals/scorm-extension-modal/scorm-extension-modal.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<h3 mat-dialog-title>Extra attempt request</h3> | ||
<div mat-dialog-content [formGroup]="extensionData"> | ||
<p class="w-full"> | ||
Please explain why you require an extra attempt for this knowledge check, the teaching team will | ||
assess the request shortly. | ||
</p> | ||
|
||
<mat-form-field style="width: 100%" appearance="outline"> | ||
<mat-label>Reason</mat-label> | ||
<textarea | ||
type="text" | ||
matInput | ||
[formControl]="extensionData.controls.extensionReason" | ||
[errorStateMatcher]="matcher" | ||
placeholder="Reason" | ||
></textarea> | ||
<mat-hint align="end" | ||
>{{ extensionData.controls.extensionReason.value.length }} / {{ reasonMaxLength }}</mat-hint | ||
> | ||
@if (extensionData.controls.extensionReason.hasError('required')) { | ||
<mat-error>You must enter a reason</mat-error> | ||
} | ||
@if (extensionData.controls.extensionReason.hasError('minlength')) { | ||
<mat-error>The reason must be at least {{ reasonMinLength }} characters long</mat-error> | ||
} | ||
@if (extensionData.controls.extensionReason.hasError('maxlength')) { | ||
<mat-error>The reason must be less than {{ reasonMaxLength }} characters long</mat-error> | ||
} | ||
</mat-form-field> | ||
</div> | ||
|
||
<div mat-dialog-actions style="float: right"> | ||
<button mat-dialog-close mat-stroked-button color="warn">Cancel</button> | ||
<button | ||
mat-dialog-close | ||
style="margin-right: 10px" | ||
mat-stroked-button | ||
color="primary" | ||
mat-button | ||
[disabled]="!extensionData.valid" | ||
(click)="submitApplication()" | ||
> | ||
Request extra attempt | ||
</button> | ||
</div> |
67 changes: 67 additions & 0 deletions
67
src/app/common/modals/scorm-extension-modal/scorm-extension-modal.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import {Component, Inject, LOCALE_ID} from '@angular/core'; | ||
import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog'; | ||
import {TaskComment, TaskCommentService, Task} from 'src/app/api/models/doubtfire-model'; | ||
import {AppInjector} from 'src/app/app-injector'; | ||
import {FormControl, Validators, FormGroup, FormGroupDirective, NgForm} from '@angular/forms'; | ||
import {ErrorStateMatcher} from '@angular/material/core'; | ||
import {AlertService} from '../../services/alert.service'; | ||
|
||
/** Error when invalid control is dirty, touched, or submitted. */ | ||
export class ReasonErrorStateMatcher 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: 'f-scorm-extension-modal', | ||
templateUrl: './scorm-extension-modal.component.html', | ||
}) | ||
export class ScormExtensionModalComponent { | ||
protected reasonMinLength: number = 15; | ||
protected reasonMaxLength: number = 256; | ||
constructor( | ||
public dialogRef: MatDialogRef<ScormExtensionModalComponent>, | ||
@Inject(MAT_DIALOG_DATA) public data: {task: Task; afterApplication?: () => void}, | ||
private alerts: AlertService, | ||
) {} | ||
|
||
matcher = new ReasonErrorStateMatcher(); | ||
currentLocale = AppInjector.get(LOCALE_ID); | ||
extensionData = new FormGroup({ | ||
extensionReason: new FormControl('', [ | ||
Validators.required, | ||
Validators.minLength(this.reasonMinLength), | ||
Validators.maxLength(this.reasonMaxLength), | ||
]), | ||
}); | ||
|
||
private scrollCommentsDown(): void { | ||
setTimeout(() => { | ||
const objDiv = document.querySelector('div.comments-body'); | ||
// let wrappedResult = angular.element(objDiv); | ||
objDiv.scrollTop = objDiv.scrollHeight; | ||
}, 50); | ||
} | ||
|
||
submitApplication() { | ||
const tcs: TaskCommentService = AppInjector.get(TaskCommentService); | ||
tcs | ||
.requestScormExtension(this.extensionData.controls.extensionReason.value, this.data.task) | ||
.subscribe({ | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
next: ((tc: TaskComment) => { | ||
this.alerts.success('Extra attempt requested.', 2000); | ||
this.scrollCommentsDown(); | ||
if (typeof this.data.afterApplication === 'function') { | ||
this.data.afterApplication(); | ||
} | ||
}).bind(this), | ||
error: ((response: never) => { | ||
this.alerts.error('Error requesting extra attempt ' + response); | ||
console.log(response); | ||
}).bind(this), | ||
}); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/app/common/modals/scorm-extension-modal/scorm-extension-modal.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import {Injectable} from '@angular/core'; | ||
import {Task} from 'src/app/api/models/task'; | ||
import {MatDialogRef, MatDialog} from '@angular/material/dialog'; | ||
import {ScormExtensionModalComponent} from './scorm-extension-modal.component'; | ||
|
||
@Injectable({ | ||
providedIn: 'root', | ||
}) | ||
export class ScormExtensionModalService { | ||
constructor(public dialog: MatDialog) {} | ||
|
||
public show(task: Task, afterApplication?: any) { | ||
let dialogRef: MatDialogRef<ScormExtensionModalComponent, any>; | ||
|
||
dialogRef = this.dialog.open(ScormExtensionModalComponent, { | ||
data: { | ||
task, | ||
afterApplication, | ||
}, | ||
}); | ||
|
||
dialogRef.afterOpened().subscribe((result: any) => {}); | ||
|
||
dialogRef.afterClosed().subscribe((result: any) => {}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
...tasks/task-comments-viewer/scorm-extension-comment/scorm-extension-comment.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<div class="flex flex-row justify-evenly items-center"> | ||
@if (comment.assessed) { | ||
<div class="flex flex-col justify-around items-center"> | ||
<hr class="hr-text" [attr.data-content]="message" /> | ||
<p class="fade-text"><strong> reason:</strong> {{ comment.text }}</p> | ||
</div> | ||
} | ||
|
||
@if (!comment.assessed) { | ||
<div class="flex flex-col justify-around items-center"> | ||
<hr class="hr-fade" /> | ||
<p> | ||
{{ message }} <br /> | ||
<strong> reason:</strong> {{ comment.text }} | ||
</p> | ||
@if (isNotStudent) { | ||
<div class="flex flex-row justify-evenly items-center"> | ||
<button | ||
(click)="grantExtension()" | ||
mat-flat-button | ||
color="primary" | ||
style="background-color: #43a047" | ||
> | ||
Grant | ||
</button> | ||
<button (click)="denyExtension()" mat-flat-button color="warn">Deny</button> | ||
</div> | ||
} | ||
<hr class="hr-fade" /> | ||
</div> | ||
} | ||
</div> |
Oops, something went wrong.