Skip to content

Commit

Permalink
Merge pull request #360 from fujaba/refactor/assignments-services
Browse files Browse the repository at this point in the history
Refactor Frontend Assignment Services
  • Loading branch information
Clashsoft authored Sep 23, 2023
2 parents 5e9f6c0 + 8625f51 commit 3a41b81
Show file tree
Hide file tree
Showing 31 changed files with 389 additions and 348 deletions.
32 changes: 31 additions & 1 deletion frontend/src/app/assignment/assignment.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {CommonModule} from '@angular/common';
import {HttpClientModule} from '@angular/common/http';
import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';

Expand All @@ -19,6 +19,19 @@ import {OverviewComponent} from './pages/overview/overview.component';
import {SettingsComponent} from './pages/settings/settings.component';
import {TokenModalComponent} from './pages/token-modal/token-modal.component';
import {ConfigService} from './services/config.service';
import {TokenInterceptor} from "./services/token.interceptor";
import {AssignmentService} from "./services/assignment.service";
import {TokenService} from "./services/token.service";
import {SolutionService} from "./services/solution.service";
import {TelemetryService} from "./services/telemetry.service";
import {CourseService} from "./services/course.service";
import {SelectionService} from "./services/selection.service";
import {SolutionContainerService} from "./services/solution-container.service";
import {TaskService} from "./services/task.service";
import {SubmitService} from "./modules/assignment/submit.service";
import {AssigneeService} from "./services/assignee.service";
import {EvaluationService} from "./services/evaluation.service";
import {EmbeddingService} from "./services/embedding.service";

@NgModule({
declarations: [
Expand All @@ -43,7 +56,24 @@ import {ConfigService} from './services/config.service';
ModalModule,
],
providers: [
{
provide: HTTP_INTERCEPTORS,
multi: true,
useClass: TokenInterceptor,
},
TokenService,
ConfigService,
AssignmentService,
SolutionService,
TelemetryService,
CourseService,
SelectionService,
SolutionContainerService,
TaskService,
SubmitService,
AssigneeService,
EvaluationService,
EmbeddingService,
],
})
export class AssignmentModule {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import {StatisticsBlockComponent} from './statistics-block/statistics-block.comp
import {StatisticsComponent} from './statistics/statistics.component';
import {SubmitModalComponent} from './submit-modal/submit-modal.component';
import {AssignmentTasksComponent} from './tasks/tasks.component';
import {StatisticsService} from "./statistics.service";
import {SubmitService} from "./submit.service";

@NgModule({
declarations: [
Expand Down Expand Up @@ -53,6 +55,10 @@ import {AssignmentTasksComponent} from './tasks/tasks.component';
RouteTabsModule,
ModalModule,
],
providers: [
StatisticsService,
SubmitService,
],
})
export class AssignmentModule {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {Component, OnInit, TrackByFunction} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {ToastService} from '@mean-stream/ngbx';
import {ClipboardService} from 'ngx-clipboard';
import {BehaviorSubject, combineLatest, firstValueFrom, forkJoin, Observable} from 'rxjs';
import {BehaviorSubject, combineLatest, forkJoin, Observable} from 'rxjs';
import {debounceTime, distinctUntilChanged, map, switchMap, tap} from 'rxjs/operators';
import {Assignee} from '../../../model/assignee';
import Assignment, {ReadAssignmentDto} from '../../../model/assignment';
Expand All @@ -15,6 +15,8 @@ import {TaskService} from '../../../services/task.service';
import {TelemetryService} from '../../../services/telemetry.service';
import {SubmitService} from "../submit.service";
import {UserService} from "../../../../user/user.service";
import {AssigneeService} from "../../../services/assignee.service";
import {EvaluationService} from "../../../services/evaluation.service";

type SearchKey = keyof AuthorInfo | 'assignee';
const searchKeys: readonly SearchKey[] = [
Expand Down Expand Up @@ -56,6 +58,8 @@ export class SolutionTableComponent implements OnInit {
constructor(
private assignmentService: AssignmentService,
private solutionService: SolutionService,
private assigneeService: AssigneeService,
private evaluationService: EvaluationService,
private solutionContainerService: SolutionContainerService,
private configService: ConfigService,
private router: Router,
Expand All @@ -78,7 +82,7 @@ export class SolutionTableComponent implements OnInit {
});

this.activatedRoute.params.pipe(
switchMap(({aid}) => this.solutionService.getAssignees(aid)),
switchMap(({aid}) => this.assigneeService.getAssignees(aid)),
).subscribe(assignees => {
this.assignees = {};
const names = new Set<string>();
Expand All @@ -91,8 +95,8 @@ export class SolutionTableComponent implements OnInit {

this.activatedRoute.params.pipe(
switchMap(({aid}) => forkJoin([
this.solutionService.getEvaluationValues<string>(aid, 'solution', {codeSearch: false}),
this.solutionService.getEvaluationValues<string>(aid, 'solution', {codeSearch: true}),
this.evaluationService.distinctValues<string>(aid, 'solution', {codeSearch: false}),
this.evaluationService.distinctValues<string>(aid, 'solution', {codeSearch: true}),
])),
).subscribe(([manual, codeSearch]) => {
this.evaluated = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ export interface AssignmentStatistics {
tasks: TaskStatistics[];
}

@Injectable({
providedIn: 'root',
})
@Injectable()
export class StatisticsService {
constructor(
private http: HttpClient,
Expand Down
12 changes: 4 additions & 8 deletions frontend/src/app/assignment/modules/assignment/submit.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {firstValueFrom} from 'rxjs';
import {environment} from '../../../../environments/environment';
import {UserService} from '../../../user/user.service';
import {ReadAssignmentDto} from '../../model/assignment';
import {Evaluation, Snippet} from '../../model/evaluation';
import Solution from '../../model/solution';
import Task from '../../model/task';
import {AssignmentService} from '../../services/assignment.service';
import {SolutionService} from '../../services/solution.service';
import {TaskService} from '../../services/task.service';
import {EvaluationService} from "../../services/evaluation.service";

export interface Issue {
number: number;
Expand All @@ -20,16 +19,13 @@ export interface Issue {

export type IssueDto = Omit<Issue, 'number'>;

@Injectable({
providedIn: 'root',
})
@Injectable()
export class SubmitService {

constructor(
private assignmentService: AssignmentService,
private evaluationService: EvaluationService,
private solutionService: SolutionService,
private taskService: TaskService,
private userService: UserService,
private http: HttpClient,
) {
}
Expand Down Expand Up @@ -73,7 +69,7 @@ export class SubmitService {
}

private async renderTasks(assignment: ReadAssignmentDto, solution: Solution) {
const evaluations = await firstValueFrom(this.solutionService.getEvaluations(assignment._id, solution._id!));
const evaluations = await firstValueFrom(this.evaluationService.findAll(assignment._id, solution._id!));
const evaluationRecord: Record<string, Evaluation> = {};
for (let evaluation of evaluations) {
evaluationRecord[evaluation.task] = evaluation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ 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";


@NgModule({
Expand All @@ -42,6 +43,9 @@ import {TemplateComponent} from './template/template.component';
RouteTabsModule,
ModalModule,
],
providers: [
TaskMarkdownService,
],
})
export class EditAssignmentModule {
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import {extractTaskItem, TASK_ITEM_PATTERN} from '../../../../modes/task-list-co
import Task from '../../model/task';
import {TaskService} from '../../services/task.service';

@Injectable({
providedIn: 'root',
})
@Injectable()
export class TaskMarkdownService {
constructor(
private taskService: TaskService,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {Component, OnInit} from '@angular/core';
import {EstimatedCosts} from "../../../model/solution";
import {SolutionService} from "../../../services/solution.service";
import {ActivatedRoute} from "@angular/router";
import {tap} from "rxjs/operators";
import {switchMap, tap} from "rxjs/operators";
import {EmbeddingService} from "../../../services/embedding.service";

@Component({
selector: 'app-import-embeddings',
Expand All @@ -14,18 +14,20 @@ export class ImportEmbeddingsComponent implements OnInit {
finalCosts?: EstimatedCosts;

constructor(
private solutionService: SolutionService,
private embeddingService: EmbeddingService,
private route: ActivatedRoute,
) {
}

ngOnInit() {
this.solutionService.importEmbeddings(this.route.snapshot.params.aid, true).subscribe(costs => this.estimatedCosts = costs);
this.route.params.pipe(
switchMap(({aid}) => this.embeddingService.import(aid, true)),
).subscribe(costs => this.estimatedCosts = costs);
}

import() {
const assignmentId = this.route.snapshot.params.aid;
return this.solutionService.importEmbeddings(assignmentId).pipe(
return this.embeddingService.import(assignmentId).pipe(
tap(result => this.finalCosts = result),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {ToastService} from '@mean-stream/ngbx';
import {Observable} from 'rxjs';
import {debounceTime, distinctUntilChanged, map} from 'rxjs/operators';
import {Assignee} from '../../../model/assignee';
import {SolutionService} from '../../../services/solution.service';
import {AssigneeService} from "../../../services/assignee.service";

@Component({
selector: 'app-assignee-input',
Expand All @@ -29,14 +29,14 @@ export class AssigneeInputComponent {
);

constructor(
private solutionService: SolutionService,
private assigneeService: AssigneeService,
private toastService: ToastService,
) {
}

save(): void {
this.saving = true;
this.solutionService.setAssignee(this.assignment, this.solution, this.assignee).subscribe(result => {
this.assigneeService.setAssignee(this.assignment, this.solution, this.assignee).subscribe(result => {
this.saving = false;
this.saved.next(result);
this.assigneeChange.next(result.assignee);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Task from '../../../model/task';
import {ConfigService} from '../../../services/config.service';
import {SolutionService} from '../../../services/solution.service';
import {TelemetryService} from '../../../services/telemetry.service';
import {EvaluationService} from "../../../services/evaluation.service";

@Component({
selector: 'app-task-list',
Expand All @@ -21,6 +22,7 @@ export class TaskListComponent {
constructor(
private telemetryService: TelemetryService,
private solutionService: SolutionService,
private evaluationService: EvaluationService,
private configService: ConfigService,
private toastService: ToastService,
private route: ActivatedRoute,
Expand All @@ -38,10 +40,10 @@ export class TaskListComponent {

givePoints(task: Task, points: number) {
const {aid, sid} = this.route.snapshot.params;
this.solutionService.getEvaluationByTask(aid, sid, task._id).pipe(
this.evaluationService.findByTask(aid, sid, task._id).pipe(
switchMap(evaluation => evaluation ?
this.solutionService.updateEvaluation(aid, sid, evaluation._id, {points}) :
this.solutionService.createEvaluation(aid, sid, {
this.evaluationService.update(aid, sid, evaluation._id, {points}) :
this.evaluationService.create(aid, sid, {
task: task._id,
points,
author: this.configService.get('name'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import {Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {ToastService} from '@mean-stream/ngbx';
import {Subscription} from 'rxjs';
import {mapTo, switchMap, take, tap} from 'rxjs/operators';
import {mapTo, switchMap, tap} from 'rxjs/operators';
import {UserService} from '../../../../user/user.service';
import Comment from '../../../model/comment';
import {ConfigService} from '../../../services/config.service';
import {SolutionService} from '../../../services/solution.service';
import {CommentService} from "../comment.service";

@Component({
selector: 'app-comment-list',
Expand All @@ -27,6 +28,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
constructor(
private userService: UserService,
private solutionService: SolutionService,
private commentService: CommentService,
private configService: ConfigService,
private toastService: ToastService,
private route: ActivatedRoute,
Expand All @@ -36,11 +38,11 @@ export class CommentListComponent implements OnInit, OnDestroy {
ngOnInit(): void {
const eventSub = this.route.params.pipe(
tap(({sid}) => this.loadCommentDraft(sid)),
switchMap(params => this.solutionService.getComments(params.aid, params.sid).pipe(
switchMap(params => this.commentService.findAll(params.aid, params.sid).pipe(
tap(comments => this.comments = comments),
mapTo(params),
)),
switchMap(({aid, sid}) => this.solutionService.streamComments(aid, sid)),
switchMap(({aid, sid}) => this.commentService.stream(aid, sid)),
).subscribe(({event, comment}) => {
this.safeApply(comment._id!, event === 'deleted' ? undefined : comment);
});
Expand Down Expand Up @@ -71,14 +73,14 @@ export class CommentListComponent implements OnInit, OnDestroy {
loadCommentDraft(solution: string): void {
this.commentName = this.configService.get('name');
this.commentEmail = this.configService.get('email');
this.commentBody = this.solutionService.getCommentDraft(solution) || '';
this.commentBody = this.commentService.getDraft(solution) || '';
}

saveCommentDraft(): void {
const solution = this.route.snapshot.params.sid;
this.configService.set('name', this.commentName);
this.configService.set('email', this.commentEmail);
this.solutionService.setCommentDraft(solution, this.commentBody);
this.commentService.setDraft(solution, this.commentBody);
}

submitComment(): void {
Expand All @@ -92,7 +94,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
email: this.commentEmail,
body: this.commentBody,
};
this.solutionService.postComment(aid, sid, comment).subscribe(result => {
this.commentService.post(aid, sid, comment).subscribe(result => {
this.safeApply(result._id!, result);
this.commentBody = '';
this.saveCommentDraft();
Expand All @@ -109,7 +111,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
}

const {sid, aid} = this.route.snapshot.params;
this.solutionService.deleteComment(aid, sid, comment._id!).subscribe(result => {
this.commentService.delete(aid, sid, comment._id!).subscribe(result => {
this.safeApply(result._id!, undefined);
this.toastService.warn('Comment', 'Successfully deleted comment');
}, error => {
Expand Down
Loading

0 comments on commit 3a41b81

Please sign in to comment.