diff --git a/modules/fbs-core/web/src/app/dialogs/task-new-dialog/task-new-dialog.component.html b/modules/fbs-core/web/src/app/dialogs/task-new-dialog/task-new-dialog.component.html index 3a54e1aec..3459e7952 100644 --- a/modules/fbs-core/web/src/app/dialogs/task-new-dialog/task-new-dialog.component.html +++ b/modules/fbs-core/web/src/app/dialogs/task-new-dialog/task-new-dialog.component.html @@ -1,45 +1,43 @@ -
- {{ "dialog.task.new.title-create" | i18nextEager }} -
-
- {{ "dialog.task.new.title-edit" | i18nextEager }} -
- Neue Aufgabe erstellen + {{ "dialog.task.new.title-create" | i18nextEager }}
- Aufgabe bearbeiten + {{ "dialog.task.new.title-edit" | i18nextEager }}
- Ausgewählte Aufgaben bearbeiten + {{ "dialog.task.new.title-edit-multiple" | i18nextEager }}
Ausgewählte Aufgaben: - {{ task.name }}; + + {{ task.name }}; +
- Deadline - + {{ "dialog.task.new.placeholder-deadline" | i18nextEager }} +
- Mediatype - + {{ "dialog.task.new.label-mediatype" | i18nextEager }} +
- Verbindlichkeit - + {{ "dialog.task.new.label-requirement" | i18nextEager }} +
- Sichtbarkeit - + {{ "dialog.task.new.label-visibility" | i18nextEager }} +
@@ -89,7 +87,7 @@ [readonly]="true" matInput [ngxMatDatetimePicker]="picker" - [disabled]="datePickerDisabled || !datePickerSelected" + [disabled]="datePickerDisabled || !selectedFormFields.datePicker" placeholder="{{ 'dialog.task.new.placeholder-deadline' | i18nextEager }}" @@ -101,7 +99,7 @@ @@ -110,7 +108,7 @@ formControlName="expCheck" class="noDeadline" (change)="setMaxExpirationDate($event)" - [disabled]="!datePickerSelected" + [disabled]="!selectedFormFields.datePicker" > {{ "dialog.task.new.toggle-no-deadline" | i18nextEager }} @@ -122,7 +120,7 @@ }} {{ @@ -137,14 +135,14 @@ - + {{ "dialog.task.new.label-requirement" | i18nextEager }} {{ "dialog.task.new.option-compulsory" | i18nextEager @@ -164,7 +162,10 @@ {{ "dialog.task.new.label-visibility" | i18nextEager }} - + {{ "dialog.task.new.option-students" | i18nextEager }} @@ -297,17 +298,7 @@ *ngIf="updateCondition === allUpdateConditions.UPDATE_MULTIPLE" mat-flat-button color="accent" - [disabled]="!taskForm.valid" - (click)="updateMultipleTaskDetails(selectedTasks)" - > - Ausgewählte Aufgaben bearbeiten - - diff --git a/modules/fbs-core/web/src/app/dialogs/task-new-dialog/task-new-dialog.component.ts b/modules/fbs-core/web/src/app/dialogs/task-new-dialog/task-new-dialog.component.ts index b3e6e03da..f4e7d81c0 100644 --- a/modules/fbs-core/web/src/app/dialogs/task-new-dialog/task-new-dialog.component.ts +++ b/modules/fbs-core/web/src/app/dialogs/task-new-dialog/task-new-dialog.component.ts @@ -23,6 +23,7 @@ import { CheckerConfig } from "../../model/CheckerConfig"; import { CheckerFileType } from "src/app/enums/checkerFileType"; import { MatSlideToggle } from "@angular/material/slide-toggle"; import { TaskUpdateConditions } from "src/app/enums/taskUpdateConditions"; +import { SelectedFormFields } from "src/app/model/SelectedFormFields"; const defaultMediaType = "text/plain"; const defaultrequirement = "mandatory"; @@ -51,15 +52,17 @@ export class TaskNewDialogComponent implements OnInit { pointFields: new UntypedFormControl(""), decimals: new UntypedFormControl(2), expCheck: new FormControl(false), - datePickerSelected: new FormControl(false), + // datePickerSelected: new FormControl(false), }); updateCondition: TaskUpdateConditions = TaskUpdateConditions.CREATE; allUpdateConditions = TaskUpdateConditions; - datePickerSelected = false; - mediaTypeSelected = false; - requirementTypeSelected = false; - isPrivateSelected = false; + selectedFormFields: SelectedFormFields = { + datePicker: false, + mediaType: false, + requirementType: false, + isPrivate: false, + }; courseId: number; datePickerDisabled: boolean = false; @@ -121,6 +124,12 @@ export class TaskNewDialogComponent implements OnInit { if (this.data.task) { this.updateCondition = TaskUpdateConditions.UPDATE; this.task = this.data.task; + + this.selectedFormFields.datePicker = true; + this.selectedFormFields.mediaType = true; + this.selectedFormFields.requirementType = true; + this.selectedFormFields.isPrivate = true; + this.setValues(); } else if (this.data.tasks) { this.updateCondition = TaskUpdateConditions.UPDATE_MULTIPLE; @@ -357,6 +366,21 @@ export class TaskNewDialogComponent implements OnInit { } updateMultipleTaskDetails(tasks: Task[]) { - this.taskService.updateMultipleTasks(this.courseId, tasks, this.task); + this.getValues(); + this.taskService + .updateMultipleTasks( + this.courseId, + tasks, + this.task, + this.selectedFormFields + ) + .subscribe((success) => { + if (success) { + this.dialogRef.close({ success: true }); + } else { + this.dialogRef.close({ success: false }); + this.snackBar.open("Error while updating tasks", "ok"); + } + }); } } diff --git a/modules/fbs-core/web/src/app/model/SelectedFormFields.ts b/modules/fbs-core/web/src/app/model/SelectedFormFields.ts new file mode 100644 index 000000000..08332c1ad --- /dev/null +++ b/modules/fbs-core/web/src/app/model/SelectedFormFields.ts @@ -0,0 +1,6 @@ +export interface SelectedFormFields { + datePicker: boolean; + mediaType: boolean; + requirementType: boolean; + isPrivate: boolean; +} diff --git a/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.html b/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.html index e4844c5ec..942b8ec50 100644 --- a/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.html +++ b/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.html @@ -81,7 +81,7 @@ mat-icon-button *ngIf="isAuthorized()" (click)="enableEditTasks()" - matTooltip="Kursinhalt bearbeiten" + matTooltip="{{ 'course.edit-multiple-tasks' | i18nextEager }}" > toggle_off toggle_on @@ -144,7 +144,7 @@
{{ (course | async)?.description }}
-
+
+ -
+

{{ "course.progress-title" | i18nextEager }}

diff --git a/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.scss b/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.scss index e624ef5bf..500832e87 100644 --- a/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.scss +++ b/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.scss @@ -109,9 +109,16 @@ .select-all-container { display: flex; + align-items: center; justify-content: flex-start; - margin-bottom: 10px; - margin-top: 10px; + margin-bottom: 30px; + margin-top: 30px; + margin-left: 15px; + + .edit-multiple-tasks-btn { + margin-left: 150px; + cursor: pointer; + } } .mat-progress-bar { height: 15px; diff --git a/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.ts b/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.ts index 07992c020..691e3faab 100644 --- a/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.ts +++ b/modules/fbs-core/web/src/app/page-components/course-detail/course-detail.component.ts @@ -171,12 +171,6 @@ export class CourseDetailComponent implements OnInit { // calculate total bonus points based on succeded requirements this.calculatedBonusPoints = 0; - console.log(taskResults); - - req.forEach((element) => { - console.log(element); - }); - // check in requirements if tasks are passed based on taskResults, match via id if (req.length > 0) { this.coursePassed = true; @@ -391,12 +385,6 @@ export class CourseDetailComponent implements OnInit { } updateMultipleTaskDetails(tasks: Task[]) { - console.log(tasks); - - // for (let task in tasks) { - // console.log(task); - // } - this.dialog .open(TaskNewDialogComponent, { height: "auto", @@ -569,7 +557,6 @@ export class CourseDetailComponent implements OnInit { if (this.isAllSelected()) { this.selectedTasks = []; } else { - console.log("not all selected"); this.selectedTasks = this.tasks; } } diff --git a/modules/fbs-core/web/src/app/service/task.service.ts b/modules/fbs-core/web/src/app/service/task.service.ts index 91a302cdc..afec59548 100644 --- a/modules/fbs-core/web/src/app/service/task.service.ts +++ b/modules/fbs-core/web/src/app/service/task.service.ts @@ -1,9 +1,11 @@ import { Injectable } from "@angular/core"; -import { Observable } from "rxjs"; +import { forkJoin, Observable } from "rxjs"; +import { take, catchError, map } from "rxjs/operators"; import { Task } from "../model/Task"; import { HttpClient } from "@angular/common/http"; import { UserTaskResult } from "../model/UserTaskResult"; import { saveAs } from "file-saver"; +import { SelectedFormFields } from "../model/SelectedFormFields"; @Injectable({ providedIn: "root", @@ -81,15 +83,39 @@ export class TaskService { * @param task The new task state * @return Observable that succeeds if updated successfully */ - updateMultipleTasks(cid: number, tasks: Task[], referenceTask: Task) { - tasks.forEach((task) => { - if (task.deadline !== null) task.deadline = referenceTask.deadline; - if (task.isPrivate !== null) task.isPrivate = referenceTask.isPrivate; - if (task.mediaType !== null) task.mediaType = referenceTask.mediaType; - // if (task. !== null) task.name = referenceTask.name; + updateMultipleTasks( + cid: number, + tasks: Task[], + referenceTask: Task, + selectedFormFields: SelectedFormFields + ): Observable { + const updateObservables = tasks.map((task) => { + if (selectedFormFields.datePicker) { + task.deadline = referenceTask.deadline; + } + if (selectedFormFields.isPrivate) { + task.isPrivate = referenceTask.isPrivate; + } + if (selectedFormFields.mediaType) { + task.mediaType = referenceTask.mediaType; + } + if (selectedFormFields.requirementType) { + task.requirementType = referenceTask.requirementType; + } - // this.updateTask(cid, id, task); + return this.updateTask(cid, task.id, task).pipe( + take(1), + catchError((error) => { + console.error(`Failed to update task ${task.id}:`, error); + return []; + }) + ); }); + + return forkJoin(updateObservables).pipe( + map(() => true), + catchError(async () => false) + ); } /** diff --git a/modules/fbs-core/web/src/i18n/de.ts b/modules/fbs-core/web/src/i18n/de.ts index 885ab09a5..9534d8a92 100644 --- a/modules/fbs-core/web/src/i18n/de.ts +++ b/modules/fbs-core/web/src/i18n/de.ts @@ -16,6 +16,9 @@ export const germanTranslation = { "course.switch-to-feedback-app": "Zur Feedback App wechseln", "course.view-sql-checker-results": "SQL-Checker", "course.settings": "Einstellungen", + "course.edit-multiple-tasks": "Mehrere Aufgaben bearbeiten", + "course.edit-multiple-tasks-select-all": "Alle auswählen", + "course.edit-multiple-tasks-de-select-all": "Auswahl aufheben", "course.edit": "Kurs bearbeiten", "course.points": "Punkte", "course.show-course-shortlinks": "Kurs Kurzlinks anzeigen", @@ -237,6 +240,7 @@ export const germanTranslation = { "dialog.spreadsheet.button.select": "Auswählen", "dialog.task.new.title-create": "Neue Aufgabe erstellen", "dialog.task.new.title-edit": "Aufgabe bearbeiten", + "dialog.task.new.title-edit-multiple": "Aufgaben bearbeiten", "dialog.task.new.placeholder-name": "Name", "dialog.task.new.label-description": "Beschreibung", "dialog.task.new.label-deadline": "Deadline", diff --git a/modules/fbs-core/web/src/i18n/en.ts b/modules/fbs-core/web/src/i18n/en.ts index e60da732a..4638e5ae5 100644 --- a/modules/fbs-core/web/src/i18n/en.ts +++ b/modules/fbs-core/web/src/i18n/en.ts @@ -16,6 +16,9 @@ export const englishTranslation = { "course.switch-to-feedback-app": "Switch to Feedback App", "course.view-sql-checker-results": "SQL Checker", "course.settings": "Settings", + "course.edit-multiple-tasks": "Edit Multiple Tasks", + "course.edit-multiple-tasks-select-all": "Select All", + "course.edit-multiple-tasks-de-select-all": "Deselect All", "course.edit": "Edit Course", "course.points": "Points", "course.show-course-shortlinks": "Show Course Shortlinks", @@ -231,6 +234,7 @@ export const englishTranslation = { "dialog.spreadsheet.button.select": "Select", "dialog.task.new.title-create": "Create new task", "dialog.task.new.title-edit": "Edit task", + "dialog.task.new.title-edit-multiple": "Edit multiple tasks", "dialog.task.new.placeholder-name": "Name", "dialog.task.new.label-description": "Description", "dialog.task.new.label-deadline": "Deadline",