From fbe3821f5da2b44f57b0b2d431896aa57385464e Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:11:42 +0200 Subject: [PATCH 01/14] fix(assignments-service): Remove assignment check endpoints --- .../src/assignment/assignment.controller.ts | 36 +----------------- .../src/assignment/assignment.dto.ts | 15 +------- .../src/assignment/assignment.service.ts | 37 ------------------- services/apps/assignments/src/environment.ts | 3 -- 4 files changed, 3 insertions(+), 88 deletions(-) diff --git a/services/apps/assignments/src/assignment/assignment.controller.ts b/services/apps/assignments/src/assignment/assignment.controller.ts index 51012bd6f..ab725ed5a 100644 --- a/services/apps/assignments/src/assignment/assignment.controller.ts +++ b/services/apps/assignments/src/assignment/assignment.controller.ts @@ -13,17 +13,10 @@ import { Post, Query, } from '@nestjs/common'; -import {ApiCreatedResponse, ApiHeader, ApiOkResponse, ApiOperation, ApiTags, getSchemaPath} from '@nestjs/swagger'; +import {ApiCreatedResponse, ApiHeader, ApiOkResponse, ApiTags, getSchemaPath} from '@nestjs/swagger'; import {FilterQuery} from 'mongoose'; import {AssignmentAuth} from './assignment-auth.decorator'; -import { - CheckNewRequestDto, - CheckRequestDto, - CheckResponseDto, - CreateAssignmentDto, - ReadAssignmentDto, - UpdateAssignmentDto, -} from './assignment.dto'; +import {CreateAssignmentDto, ReadAssignmentDto, UpdateAssignmentDto,} from './assignment.dto'; import {Assignment} from './assignment.schema'; import {AssignmentService} from './assignment.service'; @@ -89,31 +82,6 @@ export class AssignmentController { return this.assignmentService.mask(assignment.toObject()); } - @Post('check') - @ApiOkResponse({type: CheckResponseDto}) - @ApiOperation({summary: 'Check a solution draft for a new assignment draft'}) - async checkNew( - @Body() dto: CheckNewRequestDto, - ): Promise { - return { - results: await this.assignmentService.check(dto.solution, dto), - }; - } - - @Post(':id/check') - @ApiOperation({summary: 'Check a solution draft for an existing assignment'}) - @NotFound() - @ApiOkResponse({type: CheckResponseDto}) - async check( - @Param('id') id: string, - @Body() dto: CheckRequestDto, - ): Promise { - const assignment = await this.assignmentService.findOne(id) ?? notFound(id); - return { - results: await this.assignmentService.check(dto.solution, assignment), - }; - } - @Patch(':id') @NotFound() @AssignmentAuth({forbiddenResponse}) diff --git a/services/apps/assignments/src/assignment/assignment.dto.ts b/services/apps/assignments/src/assignment/assignment.dto.ts index 359e25281..1ae805829 100644 --- a/services/apps/assignments/src/assignment/assignment.dto.ts +++ b/services/apps/assignments/src/assignment/assignment.dto.ts @@ -1,7 +1,5 @@ -import {ApiProperty, ApiPropertyOptional, OmitType, PartialType, PickType} from '@nestjs/swagger'; +import {ApiProperty, ApiPropertyOptional, OmitType, PartialType} from '@nestjs/swagger'; import {Equals, IsOptional} from 'class-validator'; -import {CreateEvaluationDto} from '../evaluation/evaluation.dto'; -import {Solution} from '../solution/solution.schema'; import {Assignment, Task} from './assignment.schema'; export class CreateAssignmentDto extends OmitType(Assignment, [ @@ -29,14 +27,3 @@ export class UpdateAssignmentDto extends PartialType(OmitType(Assignment, [ @Equals(true) token?: true; } - -export class CheckRequestDto extends PickType(Solution, ['solution'] as const) { -} - -export class CheckResponseDto { - @ApiProperty({type: [CreateEvaluationDto]}) - results: CreateEvaluationDto[]; -} - -export class CheckNewRequestDto extends PickType(Assignment, ['solution', 'tasks'] as const) { -} diff --git a/services/apps/assignments/src/assignment/assignment.service.ts b/services/apps/assignments/src/assignment/assignment.service.ts index 1a9380d2a..494f5c2e0 100644 --- a/services/apps/assignments/src/assignment/assignment.service.ts +++ b/services/apps/assignments/src/assignment/assignment.service.ts @@ -1,11 +1,8 @@ import {EventService} from '@mean-stream/nestx'; import {UserToken} from '@app/keycloak-auth'; -import {HttpService} from '@nestjs/axios'; import {Injectable} from '@nestjs/common'; import {InjectModel} from '@nestjs/mongoose'; import {FilterQuery, Model, UpdateQuery} from 'mongoose'; -import {environment} from '../environment'; -import {CreateEvaluationDto} from '../evaluation/evaluation.dto'; import {generateToken, idFilter} from '../utils'; import {CreateAssignmentDto, ReadAssignmentDto, ReadTaskDto, UpdateAssignmentDto} from './assignment.dto'; import {Assignment, AssignmentDocument, Task} from './assignment.schema'; @@ -14,7 +11,6 @@ import {Assignment, AssignmentDocument, Task} from './assignment.schema'; export class AssignmentService { constructor( @InjectModel(Assignment.name) private model: Model, - private http: HttpService, private eventService: EventService, ) { } @@ -32,39 +28,6 @@ export class AssignmentService { return undefined; } - async check(solution: string, {tasks}: Pick): Promise { - const results = await Promise.all(tasks.map(task => this.checkTasksRecursively(solution, task))); - return results.flatMap(x => x); - } - - async checkTasksRecursively(solution: string, task: Task): Promise { - const [first, rest] = await Promise.all([ - this.checkTask(solution, task), - Promise.all(task.children.map(t => this.checkTasksRecursively(solution, t))), - ]); - const flatRest = rest.flatMap(x => x); - return first ? [first, ...flatRest] : flatRest; - } - - async checkTask(solution: string, task: Task): Promise { - if (!task.verification) { - return undefined; - } - const response = await this.http.post(`${environment.compiler.apiUrl}/runcodegen`, { - privacy: 'none', - packageName: 'org.fulib.assignments', - scenarioFileName: 'Scenario.md', - scenarioText: `# Solution\n\n${solution}\n\n## Verification\n\n${task.verification}\n\n`, - }).toPromise(); - return { - task: task._id, - author: 'Autograding', - remark: response?.data.output ?? '', - points: response?.data.exitCode === 0 ? Math.max(task.points, 0) : Math.min(task.points, 0), - snippets: [], - }; - } - async create(dto: CreateAssignmentDto, userId?: string): Promise { const token = generateToken(); const created = await this.model.create({ diff --git a/services/apps/assignments/src/environment.ts b/services/apps/assignments/src/environment.ts index a16536a8d..7a7886755 100644 --- a/services/apps/assignments/src/environment.ts +++ b/services/apps/assignments/src/environment.ts @@ -19,9 +19,6 @@ export const environment = { algorithms: (process.env.AUTH_ALGORITHMS || 'RS256').split(','), issuer: process.env.AUTH_ISSUER || 'https://se.uniks.de/auth/realms/fulib.org', }, - compiler: { - apiUrl: process.env.COMPILER_API_URL || 'http://localhost:4567/api', - }, nats: { servers: process.env.NATS_URL || 'nats://localhost:4222', }, From cf861e75b54c38caecc0534721860e8ba667a4e8 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:14:32 +0200 Subject: [PATCH 02/14] fix(assignments-service): Remove Solution.solution and autograding --- .../src/classroom/classroom.service.ts | 1 - .../src/solution/solution.controller.ts | 6 +----- .../assignments/src/solution/solution.dto.ts | 1 - .../src/solution/solution.schema.ts | 5 ----- .../src/solution/solution.service.ts | 19 ------------------- 5 files changed, 1 insertion(+), 31 deletions(-) diff --git a/services/apps/assignments/src/classroom/classroom.service.ts b/services/apps/assignments/src/classroom/classroom.service.ts index c71441ea4..68fa22fad 100644 --- a/services/apps/assignments/src/classroom/classroom.service.ts +++ b/services/apps/assignments/src/classroom/classroom.service.ts @@ -68,7 +68,6 @@ export class ClassroomService { const result = await this.solutionService.bulkWrite(importSolutions.map(importSolution => { const solution: Solution = { ...importSolution, - solution: '', token: generateToken(), }; const [key, value] = Object.entries(importSolution.author).find(([, value]) => value)!; diff --git a/services/apps/assignments/src/solution/solution.controller.ts b/services/apps/assignments/src/solution/solution.controller.ts index 07eb5a0e0..50fc2cfe0 100644 --- a/services/apps/assignments/src/solution/solution.controller.ts +++ b/services/apps/assignments/src/solution/solution.controller.ts @@ -6,7 +6,6 @@ import {isMongoId} from 'class-validator'; import {FilterQuery, Types} from 'mongoose'; import {AssigneeService} from '../assignee/assignee.service'; import {AssignmentAuth} from '../assignment/assignment-auth.decorator'; -import {AssignmentService} from '../assignment/assignment.service'; import {EvaluationService} from '../evaluation/evaluation.service'; import {SolutionAuth} from './solution-auth.decorator'; import {BatchUpdateSolutionDto, CreateSolutionDto, ReadSolutionDto, UpdateSolutionDto} from './solution.dto'; @@ -29,7 +28,6 @@ const searchFields = [ @ApiTags('Solutions') export class SolutionController { constructor( - private readonly assignmentService: AssignmentService, private readonly solutionService: SolutionService, private readonly assigneeService: AssigneeService, private readonly evaluationService: EvaluationService, @@ -44,9 +42,7 @@ export class SolutionController { @Body() dto: CreateSolutionDto, @AuthUser() user?: UserToken, ): Promise { - const solution = await this.solutionService.create(assignment, dto, user?.sub); - await this.solutionService.autoGrade(solution); - return solution; + return this.solutionService.create(assignment, dto, user?.sub); } @Get('assignments/:assignment/solutions') diff --git a/services/apps/assignments/src/solution/solution.dto.ts b/services/apps/assignments/src/solution/solution.dto.ts index 34368e1ef..8b61ad607 100644 --- a/services/apps/assignments/src/solution/solution.dto.ts +++ b/services/apps/assignments/src/solution/solution.dto.ts @@ -19,7 +19,6 @@ export class CreateSolutionDto extends OmitType(Solution, [ export class UpdateSolutionDto extends PartialType(OmitType(Solution, [ ...excluded, - 'solution', 'commit', ] as const)) { } diff --git a/services/apps/assignments/src/solution/solution.schema.ts b/services/apps/assignments/src/solution/solution.schema.ts index 98b59c00d..b20b7b2ae 100644 --- a/services/apps/assignments/src/solution/solution.schema.ts +++ b/services/apps/assignments/src/solution/solution.schema.ts @@ -85,11 +85,6 @@ export class Solution { @Type(() => AuthorInfo) author: AuthorInfo; - @Prop() - @ApiProperty() - @IsString() - solution: string; - @Prop() @ApiPropertyOptional() @IsOptional() diff --git a/services/apps/assignments/src/solution/solution.service.ts b/services/apps/assignments/src/solution/solution.service.ts index 2ada13b50..8fe828ffa 100644 --- a/services/apps/assignments/src/solution/solution.service.ts +++ b/services/apps/assignments/src/solution/solution.service.ts @@ -3,10 +3,6 @@ import {UserToken} from '@app/keycloak-auth'; import {Injectable} from '@nestjs/common'; import {InjectModel} from '@nestjs/mongoose'; import {FilterQuery, Model, UpdateQuery} from 'mongoose'; -import {AssignmentService} from '../assignment/assignment.service'; -import {CreateEvaluationDto} from '../evaluation/evaluation.dto'; -import {Evaluation} from '../evaluation/evaluation.schema'; -import {EvaluationService} from '../evaluation/evaluation.service'; import {generateToken, idFilter} from '../utils'; import {BatchUpdateSolutionDto, CreateSolutionDto, ReadSolutionDto, UpdateSolutionDto} from './solution.dto'; import {Solution, SolutionDocument} from './solution.schema'; @@ -15,16 +11,10 @@ import {Solution, SolutionDocument} from './solution.schema'; export class SolutionService { constructor( @InjectModel(Solution.name) public model: Model, - private assignmentService: AssignmentService, - private evaluationService: EvaluationService, private eventService: EventService, ) { } - private async createEvaluation(solution: SolutionDocument, dto: CreateEvaluationDto): Promise { - return this.evaluationService.create(solution.assignment, solution._id, dto); - } - async create(assignment: string, dto: CreateSolutionDto, createdBy?: string): Promise { const created = await this.model.create({ ...dto, @@ -37,15 +27,6 @@ export class SolutionService { return created; } - async autoGrade(solution: SolutionDocument): Promise { - const assignment = await this.assignmentService.findOne(solution.assignment); - if (!assignment) { - return; - } - const results = await this.assignmentService.check(solution.solution, assignment); - await Promise.all(results.map(r => this.createEvaluation(solution, r))); - } - async findAll(where: FilterQuery = {}): Promise { return this.model .find(where) From 238c6c7bca57a7a4ee18f6d9e0ad431dd3f2b3a1 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:19:11 +0200 Subject: [PATCH 03/14] fix(frontend): Remove Solution.solution and editor --- frontend/src/app/assignment/model/solution.ts | 1 - .../solution/tasks/tasks.component.html | 24 ++---------------- .../modules/solution/tasks/tasks.component.ts | 5 ---- .../create-solution.component.html | 14 ----------- .../create-solution.component.ts | 25 +------------------ .../assignment/services/solution.service.ts | 8 ------ 6 files changed, 3 insertions(+), 74 deletions(-) diff --git a/frontend/src/app/assignment/model/solution.ts b/frontend/src/app/assignment/model/solution.ts index 4fa360fe4..fc647cfcd 100644 --- a/frontend/src/app/assignment/model/solution.ts +++ b/frontend/src/app/assignment/model/solution.ts @@ -26,7 +26,6 @@ export default class Solution { createdBy?: string; author: AuthorInfo; - solution: string; commit?: string; consent?: Consent; diff --git a/frontend/src/app/assignment/modules/solution/tasks/tasks.component.html b/frontend/src/app/assignment/modules/solution/tasks/tasks.component.html index 074a524c6..25b498a9c 100644 --- a/frontend/src/app/assignment/modules/solution/tasks/tasks.component.html +++ b/frontend/src/app/assignment/modules/solution/tasks/tasks.component.html @@ -1,23 +1,3 @@ -
-
-
-
- - -
- Submitted {{solution.timestamp | date:'medium'}}. -
-
-
-
-
- Tasks - -
-
+Tasks + diff --git a/frontend/src/app/assignment/modules/solution/tasks/tasks.component.ts b/frontend/src/app/assignment/modules/solution/tasks/tasks.component.ts index fbd1cb6b1..572879e7e 100644 --- a/frontend/src/app/assignment/modules/solution/tasks/tasks.component.ts +++ b/frontend/src/app/assignment/modules/solution/tasks/tasks.component.ts @@ -2,7 +2,6 @@ import {Component, OnDestroy, OnInit} from '@angular/core'; import {ActivatedRoute, Router} from '@angular/router'; import {forkJoin, Subscription} from 'rxjs'; import {switchMap, tap} from 'rxjs/operators'; -import {Marker} from '../../../../shared/model/marker'; import {ReadAssignmentDto} from '../../../model/assignment'; import {Evaluation} from '../../../model/evaluation'; import Solution from '../../../model/solution'; @@ -21,7 +20,6 @@ export class SolutionTasksComponent implements OnInit, OnDestroy { solution?: Solution; points?: Record; evaluations?: Record; - markers: Marker[] = []; subscription?: Subscription; @@ -51,9 +49,6 @@ export class SolutionTasksComponent implements OnInit, OnDestroy { ])), ).subscribe(([assignment, , evaluations]) => { this.points = this.taskService.createPointsCache(assignment.tasks, this.evaluations!); - // NB: this happens here instead of where the solution is loaded above, because the solution text needs to be updated first. - // Otherwise the markers don't show up - this.markers = this.assignmentService.lint({results: evaluations}); }, error => { if (error.status === 401 || error.status === 403) { this.router.navigate(['token'], {relativeTo: this.route}); diff --git a/frontend/src/app/assignment/pages/create-solution/create-solution.component.html b/frontend/src/app/assignment/pages/create-solution/create-solution.component.html index 54b07947e..f01abada2 100644 --- a/frontend/src/app/assignment/pages/create-solution/create-solution.component.html +++ b/frontend/src/app/assignment/pages/create-solution/create-solution.component.html @@ -4,20 +4,6 @@

Tasks

-

-
- -
- {{ status }} -
-
-

Your Info

diff --git a/frontend/src/app/assignment/pages/create-solution/create-solution.component.ts b/frontend/src/app/assignment/pages/create-solution/create-solution.component.ts index 3158547bc..3243e13f5 100644 --- a/frontend/src/app/assignment/pages/create-solution/create-solution.component.ts +++ b/frontend/src/app/assignment/pages/create-solution/create-solution.component.ts @@ -3,12 +3,10 @@ import {ActivatedRoute, Router} from '@angular/router'; import {ToastService} from '@mean-stream/ngbx'; import {forkJoin, of} from 'rxjs'; import {switchMap, tap} from 'rxjs/operators'; - -import {Marker} from '../../../shared/model/marker'; import {UserService} from '../../../user/user.service'; import {ReadAssignmentDto} from '../../model/assignment'; import Course from '../../model/course'; -import Solution, {AuthorInfo} from '../../model/solution'; +import {AuthorInfo} from '../../model/solution'; import {AssignmentService} from '../../services/assignment.service'; import {ConfigService} from '../../services/config.service'; import {CourseService} from '../../services/course.service'; @@ -22,13 +20,9 @@ import {SolutionService} from '../../services/solution.service'; export class CreateSolutionComponent implements OnInit { course?: Course; assignment?: ReadAssignmentDto; - solution: string; loggedIn = false; author: AuthorInfo; - status = 'Your solution is checked automatically when you make changes.'; - markers: Marker[] = []; - submitting: boolean; nextAssignment?: ReadAssignmentDto; @@ -57,7 +51,6 @@ export class CreateSolutionComponent implements OnInit { switchMap(params => forkJoin({ assignment: this.assignmentService.get(params.aid).pipe(tap(assignment => { this.assignment = assignment; - this.solution = this.solutionService.getDraft(this.assignment._id) ?? this.assignment.templateSolution; })), course: params.cid ? this.courseService.get(params.cid).pipe(tap(course => this.course = course)) : of(undefined), })), @@ -76,21 +69,6 @@ export class CreateSolutionComponent implements OnInit { saveDraft(): void { this.solutionService.setAuthor(this.author); - this.assignment && this.solutionService.setDraft(this.assignment._id, this.solution); - } - - check(): void { - if (!this.assignment) { - return; - } - this.saveDraft(); - this.status = 'Checking...'; - this.solutionService.check({assignment: this.assignment, solution: this.solution}).subscribe(response => { - this.status = 'Your solution was checked automatically. Don\'t forget to submit when you are done!'; - this.markers = this.assignmentService.lint(response); - }, error => { - this.status = 'Failed to check your solution automatically: ' + error.error?.message ?? error.message; - }); } submit(): void { @@ -102,7 +80,6 @@ export class CreateSolutionComponent implements OnInit { this.solutionService.submit({ assignment: this.assignment?._id, author: this.author, - solution: this.solution, }).subscribe(result => { this.submitting = false; this.toastService.success('Solution', 'Successfully submitted solution'); diff --git a/frontend/src/app/assignment/services/solution.service.ts b/frontend/src/app/assignment/services/solution.service.ts index 00df5b9c1..ab31e8c5b 100644 --- a/frontend/src/app/assignment/services/solution.service.ts +++ b/frontend/src/app/assignment/services/solution.service.ts @@ -33,14 +33,6 @@ export class SolutionService { this.storageService.set('solutionAuthor', JSON.stringify(value)); } - getDraft(assignment: string): string | null { - return this.storageService.get(`solutionDraft/${assignment}`); - } - - setDraft(assignment: string, solution: string | null): void { - this.storageService.set(`solutionDraft/${assignment}`, solution); - } - // --------------- Tokens --------------- getToken(assignment: string, id: string): string | null { From 6b4ab8239db78afd9259505d75fa9cab82e121a4 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:21:14 +0200 Subject: [PATCH 04/14] fix(assignments-service): Remove Assignment.solution and .templateSolution --- .../apps/assignments/src/assignment/assignment.dto.ts | 2 +- .../assignments/src/assignment/assignment.schema.ts | 10 ---------- .../assignments/src/assignment/assignment.service.ts | 2 +- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/services/apps/assignments/src/assignment/assignment.dto.ts b/services/apps/assignments/src/assignment/assignment.dto.ts index 1ae805829..5ae37e642 100644 --- a/services/apps/assignments/src/assignment/assignment.dto.ts +++ b/services/apps/assignments/src/assignment/assignment.dto.ts @@ -13,7 +13,7 @@ export class ReadTaskDto extends OmitType(Task, ['verification', 'note', 'childr children: ReadTaskDto[]; } -export class ReadAssignmentDto extends OmitType(Assignment, ['token', 'solution', 'tasks', 'classroom'] as const) { +export class ReadAssignmentDto extends OmitType(Assignment, ['token', 'tasks', 'classroom'] as const) { @ApiProperty({type: [ReadTaskDto]}) tasks: ReadTaskDto[]; } diff --git a/services/apps/assignments/src/assignment/assignment.schema.ts b/services/apps/assignments/src/assignment/assignment.schema.ts index 337341e2f..70323bee5 100644 --- a/services/apps/assignments/src/assignment/assignment.schema.ts +++ b/services/apps/assignments/src/assignment/assignment.schema.ts @@ -187,16 +187,6 @@ export class Assignment { @ValidateNested({each: true}) @Type(() => Task) tasks: Task[]; - - @Prop() - @ApiProperty() - @IsString() - solution: string; - - @Prop() - @ApiProperty() - @IsString() - templateSolution: string; } export type AssignmentDocument = Assignment & Document; diff --git a/services/apps/assignments/src/assignment/assignment.service.ts b/services/apps/assignments/src/assignment/assignment.service.ts index 494f5c2e0..9c8bda6f7 100644 --- a/services/apps/assignments/src/assignment/assignment.service.ts +++ b/services/apps/assignments/src/assignment/assignment.service.ts @@ -48,7 +48,7 @@ export class AssignmentService { } mask(assignment: Assignment): ReadAssignmentDto { - const {token, solution, tasks, classroom, ...rest} = assignment; + const {token, tasks, classroom, ...rest} = assignment; return { ...rest, tasks: assignment.tasks.map(t => this.maskTask(t)), From 9b3eadc0b0e2ff8753c4cd41accd8ea1357d61de Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:23:02 +0200 Subject: [PATCH 05/14] fix(frontend): Remove Assignment.solution and .templateSolution and related edit pages --- .../src/app/assignment/model/assignment.ts | 2 - .../edit-assignment-routing.module.ts | 11 ----- .../edit-assignment/edit-assignment.module.ts | 4 -- .../edit-assignment.component.ts | 2 - .../sample/sample.component.html | 29 ----------- .../sample/sample.component.scss | 0 .../sample/sample.component.ts | 49 ------------------- .../template/template.component.html | 17 ------- .../template/template.component.scss | 0 .../template/template.component.ts | 20 -------- 10 files changed, 134 deletions(-) delete mode 100644 frontend/src/app/assignment/modules/edit-assignment/sample/sample.component.html delete mode 100644 frontend/src/app/assignment/modules/edit-assignment/sample/sample.component.scss delete mode 100644 frontend/src/app/assignment/modules/edit-assignment/sample/sample.component.ts delete mode 100644 frontend/src/app/assignment/modules/edit-assignment/template/template.component.html delete mode 100644 frontend/src/app/assignment/modules/edit-assignment/template/template.component.scss delete mode 100644 frontend/src/app/assignment/modules/edit-assignment/template/template.component.ts diff --git a/frontend/src/app/assignment/model/assignment.ts b/frontend/src/app/assignment/model/assignment.ts index 6a138fbbf..56e4b9a22 100644 --- a/frontend/src/app/assignment/model/assignment.ts +++ b/frontend/src/app/assignment/model/assignment.ts @@ -26,8 +26,6 @@ export default class Assignment { }; tasks: Task[]; - solution: string; - templateSolution: string; } export type CreateAssignmentDto = Omit; diff --git a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment-routing.module.ts b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment-routing.module.ts index 1bd8b087b..d49ccaa39 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment-routing.module.ts +++ b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment-routing.module.ts @@ -5,9 +5,7 @@ import {EditAssignmentComponent} from './edit-assignment/edit-assignment.compone import {EditTaskModalComponent} from './edit-task-modal/edit-task-modal.component'; import {InfoComponent} from './info/info.component'; import {PreviewComponent} from './preview/preview.component'; -import {SampleComponent} from './sample/sample.component'; import {TasksComponent} from './tasks/tasks.component'; -import {TemplateComponent} from './template/template.component'; export const editAssignmentChildRoutes: Routes = [ {path: 'info', component: InfoComponent, data: {title: 'Info'}}, @@ -20,15 +18,6 @@ export const editAssignmentChildRoutes: Routes = [ {path: ':task', component: EditTaskModalComponent}, ], }, - {path: 'template', component: TemplateComponent, data: {title: 'Template'}}, - { - path: 'sample', - component: SampleComponent, - data: {title: 'Sample'}, - children: [ - {path: ':task', component: EditTaskModalComponent}, - ], - }, {path: 'preview', component: PreviewComponent, data: {title: 'Preview'}}, ]; diff --git a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment.module.ts b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment.module.ts index d2afd0940..eea494950 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment.module.ts +++ b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment.module.ts @@ -14,9 +14,7 @@ import {EditTaskListComponent} from './edit-task-list/edit-task-list.component'; import {EditTaskModalComponent} from './edit-task-modal/edit-task-modal.component'; import {InfoComponent} from './info/info.component'; import {PreviewComponent} from './preview/preview.component'; -import {SampleComponent} from './sample/sample.component'; import {TasksComponent} from './tasks/tasks.component'; -import {TemplateComponent} from './template/template.component'; import {TaskMarkdownService} from "./task-markdown.service"; @@ -28,9 +26,7 @@ import {TaskMarkdownService} from "./task-markdown.service"; EditTaskModalComponent, InfoComponent, PreviewComponent, - SampleComponent, TasksComponent, - TemplateComponent, ], imports: [ CommonModule, diff --git a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment/edit-assignment.component.ts b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment/edit-assignment.component.ts index cbaa28081..64315e31f 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment/edit-assignment.component.ts +++ b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment/edit-assignment.component.ts @@ -58,8 +58,6 @@ export class EditAssignmentComponent implements OnInit { deadline: new Date(), description: '', tasks: [], - solution: '', - templateSolution: '', classroom: {}, }; } diff --git a/frontend/src/app/assignment/modules/edit-assignment/sample/sample.component.html b/frontend/src/app/assignment/modules/edit-assignment/sample/sample.component.html deleted file mode 100644 index f5dbcbd36..000000000 --- a/frontend/src/app/assignment/modules/edit-assignment/sample/sample.component.html +++ /dev/null @@ -1,29 +0,0 @@ -
-
-
-
- - -
- You can provide a sample solution to ensure your assignment is solvable. - Students cannot see this. -
- {{ status }} -
-
-
-
-
- Tasks - -
-
- diff --git a/frontend/src/app/assignment/modules/edit-assignment/sample/sample.component.scss b/frontend/src/app/assignment/modules/edit-assignment/sample/sample.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/frontend/src/app/assignment/modules/edit-assignment/sample/sample.component.ts b/frontend/src/app/assignment/modules/edit-assignment/sample/sample.component.ts deleted file mode 100644 index 08e4a12d9..000000000 --- a/frontend/src/app/assignment/modules/edit-assignment/sample/sample.component.ts +++ /dev/null @@ -1,49 +0,0 @@ -import {Component} from '@angular/core'; -import {Marker} from '../../../../shared/model/marker'; -import {CreateAssignmentDto} from '../../../model/assignment'; -import {CreateEvaluationDto, Evaluation} from '../../../model/evaluation'; -import {AssignmentContext} from '../../../services/assignment.context'; -import {AssignmentService} from '../../../services/assignment.service'; -import {TaskService} from '../../../services/task.service'; - -@Component({ - selector: 'app-edit-assignment-sample', - templateUrl: './sample.component.html', - styleUrls: ['./sample.component.scss'], -}) -export class SampleComponent { - assignment: CreateAssignmentDto; - saveDraft: () => void; - - status = 'The sample solution is checked automatically when you change it.'; - evaluations?: Record; - points?: Record; - markers: Marker[] = []; - - constructor( - private assignmentService: AssignmentService, - private taskService: TaskService, - private context: AssignmentContext, - ) { - this.assignment = context.assignment; - this.saveDraft = context.saveDraft; - } - - check(): void { - this.saveDraft(); - this.status = 'Checking...'; - this.assignmentService.check(this.assignment).subscribe(response => { - this.status = 'The sample solution was checked automatically, check the task list for results.'; - this.evaluations = {}; - this.context.evaluations = this.evaluations; - for (let result of response.results) { - this.evaluations[result.task] = result; - } - this.points = this.taskService.createPointsCache(this.assignment.tasks, this.evaluations); - this.markers = this.assignmentService.lint(response); - }, error => { - this.status = 'Failed to check the sample solution automatically: ' + error.error?.message ?? error.message; - }); - } - -} diff --git a/frontend/src/app/assignment/modules/edit-assignment/template/template.component.html b/frontend/src/app/assignment/modules/edit-assignment/template/template.component.html deleted file mode 100644 index e17352b79..000000000 --- a/frontend/src/app/assignment/modules/edit-assignment/template/template.component.html +++ /dev/null @@ -1,17 +0,0 @@ -
-
- - -
- Optional. This will be shown to students in the solution editor when they first open your assignment. - You can instruct them to fill in blanks or make changes. -
-
-
diff --git a/frontend/src/app/assignment/modules/edit-assignment/template/template.component.scss b/frontend/src/app/assignment/modules/edit-assignment/template/template.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/frontend/src/app/assignment/modules/edit-assignment/template/template.component.ts b/frontend/src/app/assignment/modules/edit-assignment/template/template.component.ts deleted file mode 100644 index ff539f41e..000000000 --- a/frontend/src/app/assignment/modules/edit-assignment/template/template.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {Component} from '@angular/core'; -import {CreateAssignmentDto} from '../../../model/assignment'; -import {AssignmentContext} from '../../../services/assignment.context'; - -@Component({ - selector: 'app-edit-assignment-template', - templateUrl: './template.component.html', - styleUrls: ['./template.component.scss'], -}) -export class TemplateComponent { - assignment: CreateAssignmentDto; - saveDraft: () => void; - - constructor( - context: AssignmentContext, - ) { - this.assignment = context.assignment; - this.saveDraft = context.saveDraft; - } -} From 1c113e97526523774220910c65e4c9e0c2d45cdf Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:23:43 +0200 Subject: [PATCH 06/14] refactor(frontend): Remove unused AssignmentService methods --- .../assignment/services/assignment.service.ts | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/frontend/src/app/assignment/services/assignment.service.ts b/frontend/src/app/assignment/services/assignment.service.ts index 670942eb0..d8c3e2b0d 100644 --- a/frontend/src/app/assignment/services/assignment.service.ts +++ b/frontend/src/app/assignment/services/assignment.service.ts @@ -109,41 +109,6 @@ export class AssignmentService { }); } - check(assignment: CheckAssignment): Observable { - return this.http.post(`${environment.assignmentsApiUrl}/assignments/check`, assignment); - } - - lint(result: CheckResult): Marker[] { - const grouped = new Map(); - - for (let i = 0; i < result.results.length; i++) { - const taskNum = i + 1; - const taskResult = result.results[i]; - for (const marker of this.lintService.lint(taskResult.remark)) { - marker.from.line -= 2; - marker.to.line -= 2; - - const key = `${marker.from.line}:${marker.from.ch}-${marker.to.line}:${marker.to.ch}:${marker.severity}:${marker.message}`; - let entry = grouped.get(key); - if (entry) { - entry.tasks.push(taskNum); - } else { - entry = {marker, tasks: [taskNum]}; - grouped.set(key, entry); - } - } - } - - const markers: Marker[] = []; - - for (const {marker, tasks} of grouped.values()) { - marker.message = `[${tasks.length === 1 ? 'task' : 'tasks'} ${tasks.join(', ')}] ${marker.message}`; - markers.push(marker); - } - - return markers; - } - create(dto: CreateAssignmentDto): Observable { return this.http.post(`${environment.assignmentsApiUrl}/assignments`, dto).pipe( map(response => { From 4e8fdde2164ee8b5949b2c11e13bd6495b204221 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:25:44 +0200 Subject: [PATCH 07/14] fix(frontend): Remove assignment edit context evaluations --- .../edit-assignment/edit-assignment.component.ts | 1 - .../edit-task-modal/edit-task-modal.component.html | 8 -------- .../src/app/assignment/services/assignment.context.ts | 2 -- 3 files changed, 11 deletions(-) diff --git a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment/edit-assignment.component.ts b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment/edit-assignment.component.ts index 64315e31f..7d7dfa37b 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment/edit-assignment.component.ts +++ b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment/edit-assignment.component.ts @@ -71,7 +71,6 @@ export class EditAssignmentComponent implements OnInit { this.assignmentService.upload(file).subscribe(result => { const {_id, token, createdBy, ...rest} = result; this.context.assignment = rest as Assignment; - this.context.evaluations = undefined; this.saveDraft(); }); } diff --git a/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.html b/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.html index d10388864..87839dd9d 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.html +++ b/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.html @@ -53,14 +53,6 @@ [autoSubmit]="true" >
-
- - -
diff --git a/frontend/src/app/assignment/services/assignment.context.ts b/frontend/src/app/assignment/services/assignment.context.ts index 50d4e8963..cf2fb5428 100644 --- a/frontend/src/app/assignment/services/assignment.context.ts +++ b/frontend/src/app/assignment/services/assignment.context.ts @@ -1,10 +1,8 @@ import {Injectable} from '@angular/core'; import Assignment, {CreateAssignmentDto} from '../model/assignment'; -import {CreateEvaluationDto, Evaluation} from '../model/evaluation'; @Injectable() export class AssignmentContext { assignment: Assignment | CreateAssignmentDto; - evaluations?: Record; saveDraft: () => void; } From 9b4b548c0ced4db6822e0e4e9c3a6d51bfdf39f3 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:27:23 +0200 Subject: [PATCH 08/14] fix(frontend): Remove task verification --- frontend/src/app/assignment/model/task.ts | 1 - .../edit-task-modal/edit-task-modal.component.html | 8 -------- .../edit-task-modal/edit-task-modal.component.ts | 1 - .../modules/edit-assignment/task-markdown.service.ts | 1 - 4 files changed, 11 deletions(-) diff --git a/frontend/src/app/assignment/model/task.ts b/frontend/src/app/assignment/model/task.ts index c17ebfbb8..729f717d8 100644 --- a/frontend/src/app/assignment/model/task.ts +++ b/frontend/src/app/assignment/model/task.ts @@ -3,7 +3,6 @@ export default class Task { description: string; points: number; note?: string; - verification: string; glob?: string; children: Task[]; diff --git a/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.html b/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.html index 87839dd9d..1a3fc11dc 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.html +++ b/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.html @@ -45,14 +45,6 @@ Example: src/**/model/*.java -
- - -
diff --git a/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.ts b/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.ts index 0291f7a6a..2e255022c 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.ts +++ b/frontend/src/app/assignment/modules/edit-assignment/edit-task-modal/edit-task-modal.component.ts @@ -37,7 +37,6 @@ export class EditTaskModalComponent implements OnInit { _id, description: '', points: 0, - verification: '', children: [], }; } diff --git a/frontend/src/app/assignment/modules/edit-assignment/task-markdown.service.ts b/frontend/src/app/assignment/modules/edit-assignment/task-markdown.service.ts index a2f3636c8..7186847f2 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/task-markdown.service.ts +++ b/frontend/src/app/assignment/modules/edit-assignment/task-markdown.service.ts @@ -27,7 +27,6 @@ export class TaskMarkdownService { points: +points, description, glob, - verification: '', children: [], collapsed: true, }; From 15dbe488e05b246c3c00033d657e845331c75b20 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:28:03 +0200 Subject: [PATCH 09/14] fix(assignments-service): Remove task verification --- services/apps/assignments/src/assignment/assignment.dto.ts | 2 +- .../apps/assignments/src/assignment/assignment.schema.ts | 6 ------ .../apps/assignments/src/assignment/assignment.service.ts | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/services/apps/assignments/src/assignment/assignment.dto.ts b/services/apps/assignments/src/assignment/assignment.dto.ts index 5ae37e642..ee7423d10 100644 --- a/services/apps/assignments/src/assignment/assignment.dto.ts +++ b/services/apps/assignments/src/assignment/assignment.dto.ts @@ -8,7 +8,7 @@ export class CreateAssignmentDto extends OmitType(Assignment, [ ] as const) { } -export class ReadTaskDto extends OmitType(Task, ['verification', 'note', 'children'] as const) { +export class ReadTaskDto extends OmitType(Task, ['note', 'children'] as const) { @ApiProperty() children: ReadTaskDto[]; } diff --git a/services/apps/assignments/src/assignment/assignment.schema.ts b/services/apps/assignments/src/assignment/assignment.schema.ts index 70323bee5..c5989a743 100644 --- a/services/apps/assignments/src/assignment/assignment.schema.ts +++ b/services/apps/assignments/src/assignment/assignment.schema.ts @@ -43,12 +43,6 @@ export class Task { @IsString() note?: string; - @Prop() - @ApiPropertyOptional() - @IsOptional() - @IsString() - verification?: string; - @Prop() @ApiPropertyOptional() @IsOptional() diff --git a/services/apps/assignments/src/assignment/assignment.service.ts b/services/apps/assignments/src/assignment/assignment.service.ts index 9c8bda6f7..b66d9f02a 100644 --- a/services/apps/assignments/src/assignment/assignment.service.ts +++ b/services/apps/assignments/src/assignment/assignment.service.ts @@ -56,7 +56,7 @@ export class AssignmentService { } private maskTask(task: Task): ReadTaskDto { - const {verification, note, children, ...rest} = task; + const {note, children, ...rest} = task; return { ...rest, children: children?.map(t => this.maskTask(t)), From f2da012da86b72089efc5e56de6eff1a75a45840 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:32:31 +0200 Subject: [PATCH 10/14] fix(frontend): Fix route titles including 'Solution' --- .../src/app/assignment/modules/assignment/assignment-routes.ts | 2 +- .../app/assignment/modules/solution/solution-routing.module.ts | 2 +- .../app/assignment/modules/solution/tasks/tasks.component.html | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/assignment/modules/assignment/assignment-routes.ts b/frontend/src/app/assignment/modules/assignment/assignment-routes.ts index 137ff6e82..5cb357bcf 100644 --- a/frontend/src/app/assignment/modules/assignment/assignment-routes.ts +++ b/frontend/src/app/assignment/modules/assignment/assignment-routes.ts @@ -6,7 +6,7 @@ import {SubmitModalComponent} from './submit-modal/submit-modal.component'; import {AssignmentTasksComponent} from './tasks/tasks.component'; export const assignmentChildRoutes = [ - {path: 'tasks', component: AssignmentTasksComponent, data: {title: 'Tasks & Sample Solution'}}, + {path: 'tasks', component: AssignmentTasksComponent, data: {title: 'Tasks'}}, {path: 'share', component: ShareComponent, data: {title: 'Sharing'}}, { path: 'solutions', diff --git a/frontend/src/app/assignment/modules/solution/solution-routing.module.ts b/frontend/src/app/assignment/modules/solution/solution-routing.module.ts index 28ee43d14..7499b3305 100644 --- a/frontend/src/app/assignment/modules/solution/solution-routing.module.ts +++ b/frontend/src/app/assignment/modules/solution/solution-routing.module.ts @@ -12,7 +12,7 @@ import {SimilarModalComponent} from "./similar-modal/similar-modal.component"; export const solutionChildRoutes: Routes = [ { - path: 'tasks', component: SolutionTasksComponent, data: {title: 'Solution & Tasks'}, children: [ + path: 'tasks', component: SolutionTasksComponent, data: {title: 'Tasks'}, children: [ {path: ':task', component: EvaluationModalComponent, data: {title: 'Evaluation'}}, {path: ':task/similar', component: SimilarModalComponent, data: {title: 'Similar Solutions'}}, ], diff --git a/frontend/src/app/assignment/modules/solution/tasks/tasks.component.html b/frontend/src/app/assignment/modules/solution/tasks/tasks.component.html index 25b498a9c..878bdecde 100644 --- a/frontend/src/app/assignment/modules/solution/tasks/tasks.component.html +++ b/frontend/src/app/assignment/modules/solution/tasks/tasks.component.html @@ -1,3 +1,2 @@ -Tasks From c6da0b9b315923140909df15971176db42e1af14 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:33:39 +0200 Subject: [PATCH 11/14] fix(frontend): Simplify assignment tasks component --- .../assignment/tasks/tasks.component.html | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/frontend/src/app/assignment/modules/assignment/tasks/tasks.component.html b/frontend/src/app/assignment/modules/assignment/tasks/tasks.component.html index 1c60ec82e..417f8e228 100644 --- a/frontend/src/app/assignment/modules/assignment/tasks/tasks.component.html +++ b/frontend/src/app/assignment/modules/assignment/tasks/tasks.component.html @@ -1,20 +1,3 @@
-
-
-
-
- - -
-
-
-
- Tasks - -
-
+
From a2ad2b43d4497098dbf615f7a667faf34f061a25 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:52:12 +0200 Subject: [PATCH 12/14] fix(frontend): Split off Code Search and Moss settings from Classroom edit page --- .../src/app/assignment/model/assignment.ts | 24 +++++---- .../classroom/classroom.component.html | 54 ------------------- .../classroom/classroom.component.ts | 10 ---- .../code-search/code-search.component.html | 26 +++++++++ .../code-search/code-search.component.scss | 0 .../code-search/code-search.component.ts | 18 +++++++ .../edit-assignment-routing.module.ts | 6 ++- .../edit-assignment/edit-assignment.module.ts | 4 ++ .../plagiarism-detection.component.html | 22 ++++++++ .../plagiarism-detection.component.scss | 0 .../plagiarism-detection.component.ts | 27 ++++++++++ 11 files changed, 115 insertions(+), 76 deletions(-) create mode 100644 frontend/src/app/assignment/modules/edit-assignment/code-search/code-search.component.html create mode 100644 frontend/src/app/assignment/modules/edit-assignment/code-search/code-search.component.scss create mode 100644 frontend/src/app/assignment/modules/edit-assignment/code-search/code-search.component.ts create mode 100644 frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.html create mode 100644 frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.scss create mode 100644 frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.ts diff --git a/frontend/src/app/assignment/model/assignment.ts b/frontend/src/app/assignment/model/assignment.ts index 56e4b9a22..9a1aef4f2 100644 --- a/frontend/src/app/assignment/model/assignment.ts +++ b/frontend/src/app/assignment/model/assignment.ts @@ -1,5 +1,17 @@ import Task from './task'; +export interface ClassroomInfo { + org?: string; + prefix?: string; + token?: string; + webhook?: string; + codeSearch?: boolean; + mossId?: number; + mossLanguage?: string; + mossResult?: string; + openaiApiKey?: string; +} + export default class Assignment { _id: string; archived?: boolean; @@ -13,17 +25,7 @@ export default class Assignment { issuance?: Date | string; deadline?: Date | string; - classroom?: { - org?: string; - prefix?: string; - token?: string; - webhook?: string; - codeSearch?: boolean; - mossId?: number; - mossLanguage?: string; - mossResult?: string; - openaiApiKey?: string; - }; + classroom?: ClassroomInfo; tasks: Task[]; } diff --git a/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.html b/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.html index b3fd42dc9..bfbc2b17e 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.html +++ b/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.html @@ -56,58 +56,4 @@ or an error in case of a problem. -
- -
- - -
-
- Code Search will import the source code from Classroom repositories and index it. - It can be used to find code duplicates across submissions and allows grading multiple students at the same time. -
-
-
- - -
- Your OpenAI API key for advanced Code Search. Generate one in the - OpenAI API Keys. -
-
-
- -
- - -
-
- Use - Moss - to detect code duplicates across submissions. -
-
-
- - -
- Your Moss User ID. See "Registering for Moss" in the Moss documentation to obtain it. -
-
-
- - -
- Language to use for Moss duplicate analysis. -
-
diff --git a/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.ts b/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.ts index 70c41378f..df2b9d0f7 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.ts +++ b/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.ts @@ -9,25 +9,15 @@ import {AssignmentContext} from '../../../services/assignment.context'; }) export class ClassroomComponent { assignment: CreateAssignmentDto; - showMoss = false; saveDraft: () => void; encodeURIComponent = encodeURIComponent; - mossLanguages = { - java: 'Java', - javascript: 'JavaScript', - python: 'Python', - c: 'C', - cc: 'C++', - csharp: 'C#', - }; constructor( context: AssignmentContext, ) { this.assignment = context.assignment; this.assignment.classroom ||= {}; - this.showMoss = !!this.assignment.classroom.mossId; this.saveDraft = context.saveDraft; } } diff --git a/frontend/src/app/assignment/modules/edit-assignment/code-search/code-search.component.html b/frontend/src/app/assignment/modules/edit-assignment/code-search/code-search.component.html new file mode 100644 index 000000000..ca17bf58f --- /dev/null +++ b/frontend/src/app/assignment/modules/edit-assignment/code-search/code-search.component.html @@ -0,0 +1,26 @@ +
+ +
+ + +
+
+ Code Search will import the source code from Classroom repositories and index it. + It can be used to find code duplicates across submissions and allows grading multiple students at the same time. +
+
+
+ + +
+ Your OpenAI API key for advanced Code Search. Generate one in the + OpenAI API Keys. +
+
diff --git a/frontend/src/app/assignment/modules/edit-assignment/code-search/code-search.component.scss b/frontend/src/app/assignment/modules/edit-assignment/code-search/code-search.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/src/app/assignment/modules/edit-assignment/code-search/code-search.component.ts b/frontend/src/app/assignment/modules/edit-assignment/code-search/code-search.component.ts new file mode 100644 index 000000000..04ce78f7e --- /dev/null +++ b/frontend/src/app/assignment/modules/edit-assignment/code-search/code-search.component.ts @@ -0,0 +1,18 @@ +import {Component} from '@angular/core'; +import {AssignmentContext} from "../../../services/assignment.context"; +import {ClassroomInfo} from "../../../model/assignment"; + +@Component({ + selector: 'app-code-search', + templateUrl: './code-search.component.html', + styleUrls: ['./code-search.component.scss'] +}) +export class CodeSearchComponent { + classroom: ClassroomInfo; + + constructor( + readonly context: AssignmentContext, + ) { + this.classroom = this.context.assignment.classroom ||= {}; + } +} diff --git a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment-routing.module.ts b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment-routing.module.ts index d49ccaa39..a35e0e647 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment-routing.module.ts +++ b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment-routing.module.ts @@ -6,10 +6,11 @@ import {EditTaskModalComponent} from './edit-task-modal/edit-task-modal.componen import {InfoComponent} from './info/info.component'; import {PreviewComponent} from './preview/preview.component'; import {TasksComponent} from './tasks/tasks.component'; +import {PlagiarismDetectionComponent} from "./plagiarism-detection/plagiarism-detection.component"; +import {CodeSearchComponent} from "./code-search/code-search.component"; export const editAssignmentChildRoutes: Routes = [ {path: 'info', component: InfoComponent, data: {title: 'Info'}}, - {path: 'classroom', component: ClassroomComponent, data: {icon: 'github', title: 'Classroom'}}, { path: 'tasks', component: TasksComponent, @@ -18,6 +19,9 @@ export const editAssignmentChildRoutes: Routes = [ {path: ':task', component: EditTaskModalComponent}, ], }, + {path: 'classroom', component: ClassroomComponent, data: {icon: 'bi-github', title: 'Classroom'}}, + {path: 'code-search', component: CodeSearchComponent, data: {icon: 'bi-robot', title: 'Code Search'}}, + {path: 'plagiarism-detection', component: PlagiarismDetectionComponent, data: {icon: 'bi-incognito', title: 'Plagiarism Detection'}}, {path: 'preview', component: PreviewComponent, data: {title: 'Preview'}}, ]; diff --git a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment.module.ts b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment.module.ts index eea494950..dd1ee0604 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/edit-assignment.module.ts +++ b/frontend/src/app/assignment/modules/edit-assignment/edit-assignment.module.ts @@ -16,6 +16,8 @@ import {InfoComponent} from './info/info.component'; import {PreviewComponent} from './preview/preview.component'; import {TasksComponent} from './tasks/tasks.component'; import {TaskMarkdownService} from "./task-markdown.service"; +import { CodeSearchComponent } from './code-search/code-search.component'; +import { PlagiarismDetectionComponent } from './plagiarism-detection/plagiarism-detection.component'; @NgModule({ @@ -27,6 +29,8 @@ import {TaskMarkdownService} from "./task-markdown.service"; InfoComponent, PreviewComponent, TasksComponent, + CodeSearchComponent, + PlagiarismDetectionComponent, ], imports: [ CommonModule, diff --git a/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.html b/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.html new file mode 100644 index 000000000..eb7d55484 --- /dev/null +++ b/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.html @@ -0,0 +1,22 @@ +
+ Use + Moss + to detect code duplicates across submissions. +
+
+ + +
+ Your Moss User ID. See "Registering for Moss" in the Moss documentation to obtain it. +
+
+
+ + +
+ Language to use for Moss duplicate analysis. +
+
diff --git a/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.scss b/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.ts b/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.ts new file mode 100644 index 000000000..bef317fdc --- /dev/null +++ b/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.ts @@ -0,0 +1,27 @@ +import {Component} from '@angular/core'; +import {AssignmentContext} from "../../../services/assignment.context"; +import {ClassroomInfo} from "../../../model/assignment"; + +@Component({ + selector: 'app-plagiarism-detection', + templateUrl: './plagiarism-detection.component.html', + styleUrls: ['./plagiarism-detection.component.scss'] +}) +export class PlagiarismDetectionComponent { + classroom: ClassroomInfo; + + mossLanguages = { + java: 'Java', + javascript: 'JavaScript', + python: 'Python', + c: 'C', + cc: 'C++', + csharp: 'C#', + }; + + constructor( + readonly context: AssignmentContext, + ) { + this.classroom = context.assignment.classroom ||= {}; + } +} From f5ce03ad720dc08a78ebb0b63e0ca9ead600763f Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 14:53:57 +0200 Subject: [PATCH 13/14] refactor(frontend): Simplify Classroom component --- .../classroom/classroom.component.html | 12 ++++++------ .../edit-assignment/classroom/classroom.component.ts | 11 ++++------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.html b/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.html index bfbc2b17e..d9d1c9359 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.html +++ b/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.html @@ -9,10 +9,10 @@
https://github.com/ + [(ngModel)]="classroom.org" (change)="context.saveDraft()"> / + [(ngModel)]="classroom.prefix" (change)="context.saveDraft()"> -Student
@@ -24,19 +24,19 @@
Required for importing solutions from GitHub Classroom. You can generate a token in the GitHub Settings . Make sure your account has access to the - {{ assignment.classroom!.org }} + {{ classroom.org }} organisation and select the repo scope. @@ -47,7 +47,7 @@
diff --git a/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.ts b/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.ts index df2b9d0f7..aec08fd61 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.ts +++ b/frontend/src/app/assignment/modules/edit-assignment/classroom/classroom.component.ts @@ -1,5 +1,5 @@ import {Component} from '@angular/core'; -import {CreateAssignmentDto} from '../../../model/assignment'; +import {ClassroomInfo} from '../../../model/assignment'; import {AssignmentContext} from '../../../services/assignment.context'; @Component({ @@ -8,16 +8,13 @@ import {AssignmentContext} from '../../../services/assignment.context'; styleUrls: ['./classroom.component.scss'], }) export class ClassroomComponent { - assignment: CreateAssignmentDto; - saveDraft: () => void; + classroom: ClassroomInfo; encodeURIComponent = encodeURIComponent; constructor( - context: AssignmentContext, + readonly context: AssignmentContext, ) { - this.assignment = context.assignment; - this.assignment.classroom ||= {}; - this.saveDraft = context.saveDraft; + this.classroom = context.assignment.classroom ||= {}; } } From f7f8e5b610c9c68adcd7f10e6e22834fbcbe4152 Mon Sep 17 00:00:00 2001 From: Adrian Kunz Date: Sun, 24 Sep 2023 15:25:52 +0200 Subject: [PATCH 14/14] feat(frontend): Improve Moss form information and add quick email link --- .../plagiarism-detection.component.html | 10 ++++++++-- .../plagiarism-detection.component.ts | 4 ++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.html b/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.html index eb7d55484..93b7bce72 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.html +++ b/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.html @@ -8,15 +8,21 @@
- Your Moss User ID. See "Registering for Moss" in the Moss documentation to obtain it. + Your Moss User ID. + See "Registering for Moss" in the Moss documentation to obtain it. + Or + send an email + to request one.
- +
Language to use for Moss duplicate analysis. + See our list of supported languages + if you need a Moss-supported language that is not listed here.
diff --git a/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.ts b/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.ts index bef317fdc..fc4c22855 100644 --- a/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.ts +++ b/frontend/src/app/assignment/modules/edit-assignment/plagiarism-detection/plagiarism-detection.component.ts @@ -1,6 +1,7 @@ import {Component} from '@angular/core'; import {AssignmentContext} from "../../../services/assignment.context"; import {ClassroomInfo} from "../../../model/assignment"; +import {ConfigService} from "../../../services/config.service"; @Component({ selector: 'app-plagiarism-detection', @@ -9,6 +10,7 @@ import {ClassroomInfo} from "../../../model/assignment"; }) export class PlagiarismDetectionComponent { classroom: ClassroomInfo; + email: string; mossLanguages = { java: 'Java', @@ -21,7 +23,9 @@ export class PlagiarismDetectionComponent { constructor( readonly context: AssignmentContext, + private configService: ConfigService, ) { + this.email = configService.get('email'); this.classroom = context.assignment.classroom ||= {}; } }