Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assignee Notes #415

Merged
merged 8 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"ngx-drag-drop": "^17.0.0",
"rxjs": "~7.8.1",
"tslib": "^2.6.2",
"turndown": "^7.1.2",
"zone.js": "^0.14.4"
},
"devDependencies": {
Expand All @@ -63,6 +64,7 @@
"@types/jasminewd2": "~2.0.13",
"@types/markdown-it": "^13.0.7",
"@types/node": "^20.11.19",
"@types/turndown": "^5.0.4",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"eslint": "^8.56.0",
Expand Down
20 changes: 20 additions & 0 deletions frontend/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/src/app/assignment/model/assignee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export interface Assignee {
assignee: string;
duration?: number;
feedback?: Feedback;
notes?: string;
}

export type UpdateAssigneeDto = Omit<Assignee, 'assignment' | 'solution'>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ <h2>General Info</h2>
</div>
<div class="mb-3">
<label for="descriptionInput" class="form-label">Description</label>
<textarea id="descriptionInput" class="form-control" rows="6"
placeholder="A short description for this course..."
[(ngModel)]="course.description" (change)="saveDraft()">
</textarea>
<div class="form-text">
<a href="https://commonmark.org/help/" target="_blank">Markdown syntax</a> is supported.
</div>
<app-markdown-editor
textareaId="descriptionInput"
[rows]="6"
placeholder="A short description for this course..."
[(content)]="course.description"
(change)="saveDraft()"
></app-markdown-editor>
</div>
</div>
}
Expand All @@ -48,7 +48,7 @@ <h2>Assignments</h2>
</li>
@for (assignment of assignments; track assignment; let i = $index) {
<li

class="timeline-item"
dndType="assignment"
[dndDraggable]="assignment"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@
</div>
<div class="mb-3">
<label class="form-label" for="descriptionInput">Description</label>
<textarea id="descriptionInput" class="form-control" rows="6" [(ngModel)]="assignment.description"
(change)="saveDraft()"></textarea>
<div class="form-text">
<a href="https://commonmark.org/help/" target="_blank">Markdown syntax</a> is supported.
</div>
<app-markdown-editor
textareaId="descriptionInput"
[(content)]="assignment.description"
[rows]="6"
(change)="saveDraft()"
></app-markdown-editor>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,11 @@
</div>
</div>
<div class="card-body">
<textarea
class="form-control"
aria-label="Comment Body"
[(ngModel)]="commentBody"
<app-markdown-editor
[(content)]="commentBody"
(change)="saveCommentDraft()"
(keyup.control.enter)="submitComment()"></textarea>
<div class="form-text">
<a href="https://commonmark.org/help/" target="_blank">Markdown syntax</a> is supported.
</div>
(submit)="submitComment()"
></app-markdown-editor>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,11 @@
</div>
<div class="mb-3">
<label class="form-label" for="remarkInput">Remark</label>
<textarea
class="form-control" id="remarkInput"
ngbAutofocus
[(ngModel)]="dto.remark"
<app-markdown-editor
textareaId="remarkInput"
[(content)]="dto.remark"
[rows]="remarkLines"
></textarea>
<div class="form-text">
<a href="https://commonmark.org/help/" target="_blank">Markdown Syntax</a> is supported.
</div>
></app-markdown-editor>
</div>
<div class="mb-3">
<label class="form-label" for="nameInput">Name</label>
Expand Down
31 changes: 16 additions & 15 deletions frontend/src/app/assignment/modules/solution/solution.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {NgbPopoverModule, NgbTooltipModule, NgbTypeaheadModule} from '@ng-bootstrap/ng-bootstrap';
import {NgbCollapse, NgbPopoverModule, NgbTooltipModule, NgbTypeaheadModule} from '@ng-bootstrap/ng-bootstrap';
import {FormsModule as NgbxFormsModule, ModalModule, RouteTabsModule} from '@mean-stream/ngbx';
import {ClipboardModule} from 'ngx-clipboard';
import {SharedModule} from '../../../shared/shared.module';
Expand Down Expand Up @@ -41,20 +41,21 @@ import { SnippetListComponent } from './snippet-list/snippet-list.component';
AssigneeFeedbackComponent,
SnippetListComponent,
],
imports: [
CommonModule,
SharedModule,
FormsModule,
NgbTooltipModule,
ClipboardModule,
SolutionRoutingModule,
AssignmentSharedModule,
NgbTypeaheadModule,
RouteTabsModule,
ModalModule,
NgbPopoverModule,
NgbxFormsModule,
],
imports: [
CommonModule,
SharedModule,
FormsModule,
NgbTooltipModule,
ClipboardModule,
SolutionRoutingModule,
AssignmentSharedModule,
NgbTypeaheadModule,
RouteTabsModule,
ModalModule,
NgbPopoverModule,
NgbxFormsModule,
NgbCollapse,
],
providers: [
CommentService,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
Launch in Projects
</button>
<app-timetracking #timer [(duration)]="assignee.duration!" class="me-2"></app-timetracking>
<a class="btn btn-danger bi-stop" (click)="timer.pause(); saveDuration(); evaluating = false" routerLink="feedback">
<a class="btn btn-danger bi-stop me-2" (click)="timer.pause(); saveDuration(); evaluating = false" routerLink="feedback">
Stop
</a>
} @else {
Expand All @@ -20,21 +20,49 @@
<span class="text-muted me-2">Duration: {{ assignee.duration | duration }}</span>
}
@if (assignee.feedback) {
<a routerLink="feedback">View Feedback</a>
<a routerLink="feedback me-2">View Feedback</a>
}
}
<div class="form-check form-switch ms-auto">
<input class="form-check-input" type="checkbox" role="switch" id="switch-show-notes" [(ngModel)]="showNotes">
<label class="form-check-label" for="switch-show-notes">Show Notes</label>
</div>
</div>
</div>
}
@if (assignment) {
<app-task-list
[allTasks]="assignment.tasks"
[tasks]="assignment.tasks"
[evaluations]="evaluations"
[editable]="evaluating"
[points]="points"
></app-task-list>
} @else {
Loading...
}
<div class="row">
<div class="col">
@if (assignment) {
<app-task-list
[allTasks]="assignment.tasks"
[tasks]="assignment.tasks"
[evaluations]="evaluations"
[editable]="evaluating"
[points]="points"
></app-task-list>
} @else {
Loading...
}
</div>
@if (showNotes) {
<div class="col">
<div class="mb-3">
<label for="notes-textarea" class="form-label">
Notes
<i class="bi-question-circle" ngbTooltip="Notes are private and only visible to assignees."></i>
</label>
<app-markdown-editor
textareaId="notes-textarea"
placeholder="Add notes for this solution..."
[rows]="10"
[content]="assignee?.notes ?? ''"
(contentChange)="assignee && (assignee.notes = $event)"
></app-markdown-editor>
</div>
<button class="btn btn-primary" (click)="saveNotes()">
Save
</button>
</div>
}
</div>
<router-outlet></router-outlet>
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export class SolutionTasksComponent implements OnInit, OnDestroy {
launching = false;
assignee?: UpdateAssigneeDto;

showNotes = false;

constructor(
private assignmentService: AssignmentService,
private evaluationService: EvaluationService,
Expand All @@ -55,6 +57,7 @@ export class SolutionTasksComponent implements OnInit, OnDestroy {
).subscribe(assignee => {
assignee.duration ||= 0;
this.assignee = assignee;
this.showNotes = !!assignee.notes;
});

this.route.params.pipe(
Expand Down Expand Up @@ -121,6 +124,18 @@ export class SolutionTasksComponent implements OnInit, OnDestroy {
});
}

saveNotes() {
if (!this.assignee) {
return;
}
this.assigneeService.update(this.assignment!._id, this.solution!._id!, {
notes: this.assignee.notes,
}).subscribe({
next: () => this.toastService.success('Update Notes', 'Successfully saved notes'),
error: error => this.toastService.error('Update Notes', 'Failed to save notes', error),
});
}

saveDuration() {
if (!this.assignee) {
return;
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/app/services/markdown.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Injectable} from '@angular/core';
import MarkdownIt from 'markdown-it';
import TurndownService from 'turndown';
import {Observable} from 'rxjs';

@Injectable({
Expand All @@ -12,6 +13,17 @@ export class MarkdownService {
langPrefix: 'language-',
});

private readonly turndownService = new TurndownService({
headingStyle: 'atx',
hr: '---',
bulletListMarker: '-',
codeBlockStyle: 'fenced',
});

parseMarkdown(html: string): string {
return this.turndownService.turndown(html);
}

renderMarkdown(md: string, options: { imageBaseUrl?: string; linkBaseUrl?: string; } = {}): Observable<string> {
return new Observable(subscriber => {
subscriber.next(this.renderMarkdownSync(md, options));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<div class="d-flex align-items-center" role="toolbar">
<div class="btn-group me-2">
<button class="btn btn-outline-secondary btn-sm bi-type-bold" (click)="span('**', '**')"></button>
<button class="btn btn-outline-secondary btn-sm bi-type-italic" (click)="span('*', '*')"></button>
<button class="btn btn-outline-secondary btn-sm bi-type-strikethrough" (click)="span('~~', '~~')"></button>
<button class="btn btn-outline-secondary btn-sm bi-link" (click)="span('[', '](https://)')"></button>
<button class="btn btn-outline-secondary btn-sm bi-image" (click)="span('![', '](https://)')"></button>
</div>
<div class="form-check form-switch me-2">
<input class="form-check-input" type="checkbox" id="switch-preview" [(ngModel)]="preview">
<label class="form-check-label" for="switch-preview">Preview</label>
</div>
<a class="bi-question-circle me-2" href="https://commonmark.org/help/" target="_blank" ngbTooltip="Markdown Syntax Help"></a>
</div>
@if (preview) {
<div class="card">
<div class="card-body">
<app-markdown [markdown]="content"></app-markdown>
</div>
</div>
} @else {
<textarea
#textarea
class="form-control"
[id]="textareaId"
[rows]="rows"
[placeholder]="placeholder"
[(ngModel)]="content"
(paste)="paste($event)"
(ngModelChange)="contentChange.emit($event)"
(change)="change.next(content)"
(keyup.control.enter)="submit.next(content)"
></textarea>
}
Empty file.
Loading
Loading