diff --git a/src/main/webapp/app/entities/competency.model.ts b/src/main/webapp/app/entities/competency.model.ts
index 245cfd71553c..51afaa1b18a3 100644
--- a/src/main/webapp/app/entities/competency.model.ts
+++ b/src/main/webapp/app/entities/competency.model.ts
@@ -46,7 +46,11 @@ export enum CourseCompetencyType {
export const DEFAULT_MASTERY_THRESHOLD = 100;
+export const HIGH_COMPETENCY_LINK_WEIGHT = 1;
export const MEDIUM_COMPETENCY_LINK_WEIGHT = 0.5;
+export const LOW_COMPETENCY_LINK_WEIGHT = 0.25;
+export const LOW_COMPETENCY_LINK_WEIGHT_CUT_OFF = 0.375; // halfway between low and medium
+export const MEDIUM_COMPETENCY_LINK_WEIGHT_CUT_OFF = 0.75; // halfway between medium and high
export abstract class BaseCompetency implements BaseEntity {
id?: number;
diff --git a/src/main/webapp/app/shared/competency-selection/competency-selection.component.html b/src/main/webapp/app/shared/competency-selection/competency-selection.component.html
index b15b8f4cfd8f..7fba47389226 100644
--- a/src/main/webapp/app/shared/competency-selection/competency-selection.component.html
+++ b/src/main/webapp/app/shared/competency-selection/competency-selection.component.html
@@ -32,6 +32,23 @@
{{ competencyLink.competency.title }}
+ @if (checkboxStates[competencyLink.competency.id]) {
+
+ }
}
}
diff --git a/src/main/webapp/app/shared/competency-selection/competency-selection.component.ts b/src/main/webapp/app/shared/competency-selection/competency-selection.component.ts
index 224abeb3cabe..41f2dcf0e67a 100644
--- a/src/main/webapp/app/shared/competency-selection/competency-selection.component.ts
+++ b/src/main/webapp/app/shared/competency-selection/competency-selection.component.ts
@@ -1,7 +1,16 @@
import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
-import { CompetencyLearningObjectLink, CourseCompetency, MEDIUM_COMPETENCY_LINK_WEIGHT, getIcon } from 'app/entities/competency.model';
+import {
+ CompetencyLearningObjectLink,
+ CourseCompetency,
+ HIGH_COMPETENCY_LINK_WEIGHT,
+ LOW_COMPETENCY_LINK_WEIGHT,
+ LOW_COMPETENCY_LINK_WEIGHT_CUT_OFF,
+ MEDIUM_COMPETENCY_LINK_WEIGHT,
+ MEDIUM_COMPETENCY_LINK_WEIGHT_CUT_OFF,
+ getIcon,
+} from 'app/entities/competency.model';
import { ActivatedRoute } from '@angular/router';
import { CourseStorageService } from 'app/course/manage/course-storage.service';
import { finalize } from 'rxjs';
@@ -40,6 +49,12 @@ export class CompetencySelectionComponent implements OnInit, ControlValueAccesso
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_onChange = (value: any) => {};
+ protected readonly HIGH_COMPETENCY_LINK_WEIGHT = HIGH_COMPETENCY_LINK_WEIGHT;
+ protected readonly MEDIUM_COMPETENCY_LINK_WEIGHT = MEDIUM_COMPETENCY_LINK_WEIGHT;
+ protected readonly LOW_COMPETENCY_LINK_WEIGHT = LOW_COMPETENCY_LINK_WEIGHT;
+ protected readonly LOW_COMPETENCY_LINK_WEIGHT_CUT_OFF = LOW_COMPETENCY_LINK_WEIGHT_CUT_OFF; // halfway between low and medium
+ protected readonly MEDIUM_COMPETENCY_LINK_WEIGHT_CUT_OFF = MEDIUM_COMPETENCY_LINK_WEIGHT_CUT_OFF; // halfway between medium and high
+
constructor(
private route: ActivatedRoute,
private courseStorageService: CourseStorageService,
@@ -122,7 +137,19 @@ export class CompetencySelectionComponent implements OnInit, ControlValueAccesso
}
}
+ updateLinkWeight(link: CompetencyLearningObjectLink, value: number) {
+ link.weight = value;
+
+ this._onChange(this.selectedCompetencyLinks);
+ this.valueChange.emit(this.selectedCompetencyLinks);
+ }
+
writeValue(value?: CompetencyLearningObjectLink[]): void {
+ this.competencyLinks?.forEach((link) => {
+ const selectedLink = value?.find((value) => value.competency?.id === link.competency?.id);
+ link.weight = selectedLink?.weight ?? MEDIUM_COMPETENCY_LINK_WEIGHT;
+ });
+
if (value && this.competencyLinks) {
// Compare the ids of the competencies instead of the whole objects
const ids = value.map((el) => el.competency?.id);
diff --git a/src/main/webapp/i18n/de/competency.json b/src/main/webapp/i18n/de/competency.json
index aaef36b9f34a..f06f02951cda 100644
--- a/src/main/webapp/i18n/de/competency.json
+++ b/src/main/webapp/i18n/de/competency.json
@@ -117,7 +117,13 @@
"link": {
"title": "Verbundene Kompetenzen",
"lectureUnit": "Verbinde diese Vorlesungseinheit wahlweise mit einer oder mehreren Kompetenzen.",
- "exercise": "Verbinde diese Übung wahlweise mit einer oder mehreren Kompetenzen."
+ "exercise": "Verbinde diese Übung wahlweise mit einer oder mehreren Kompetenzen.",
+ "weightTooltip": "Die Relevanz dieses Lernobjektes für die Kompetenz.",
+ "weightLabels": {
+ "low": "Niedrig",
+ "medium": "Mittel",
+ "high": "Hoch"
+ }
},
"competencyCard": {
"connectedLectureUnits": "Verbundene Vorlesungseinheiten",
diff --git a/src/main/webapp/i18n/en/competency.json b/src/main/webapp/i18n/en/competency.json
index e4aedbe82c77..6cac8ddf0256 100644
--- a/src/main/webapp/i18n/en/competency.json
+++ b/src/main/webapp/i18n/en/competency.json
@@ -117,7 +117,13 @@
"link": {
"title": "Linked Competencies",
"lectureUnit": "Optionally link this lecture unit to one or more competencies.",
- "exercise": "Optionally link this exercise to one or more competencies."
+ "exercise": "Optionally link this exercise to one or more competencies.",
+ "weightTooltip": "The relevance of this learning object for the competency.",
+ "weightLabels": {
+ "low": "Low",
+ "medium": "Medium",
+ "high": "High"
+ }
},
"competencyCard": {
"connectedLectureUnits": "Linked Lecture Units",
diff --git a/src/test/javascript/spec/component/shared/competency-selection.component.spec.ts b/src/test/javascript/spec/component/shared/competency-selection.component.spec.ts
index a58b665e45cc..13cdf686b9c9 100644
--- a/src/test/javascript/spec/component/shared/competency-selection.component.spec.ts
+++ b/src/test/javascript/spec/component/shared/competency-selection.component.spec.ts
@@ -14,6 +14,7 @@ import { By } from '@angular/platform-browser';
import { CourseStorageService } from 'app/course/manage/course-storage.service';
import { ChangeDetectorRef } from '@angular/core';
import { CourseCompetencyService } from 'app/course/competencies/course-competency.service';
+import { Prerequisite } from 'app/entities/prerequisite.model';
describe('CompetencySelection', () => {
let fixture: ComponentFixture;
@@ -122,6 +123,22 @@ describe('CompetencySelection', () => {
expect(component.selectedCompetencyLinks?.first()?.competency?.title).toBe('test');
});
+ it('should update link weight when value is written', () => {
+ jest.spyOn(courseStorageService, 'getCourse').mockReturnValue({
+ competencies: [{ id: 1, title: 'test' } as Competency, { id: 2, title: 'testAgain' } as Prerequisite, { id: 3, title: 'testMore' } as Competency],
+ });
+
+ fixture.detectChanges();
+
+ component.writeValue([
+ new CompetencyLearningObjectLink({ id: 1, title: 'other' } as Competency, 0.5),
+ new CompetencyLearningObjectLink({ id: 3, title: 'otherMore' } as Competency, 1),
+ ]);
+ expect(component.selectedCompetencyLinks).toBeArrayOfSize(2);
+ expect(component.selectedCompetencyLinks?.first()?.weight).toBe(0.5);
+ expect(component.selectedCompetencyLinks?.last()?.weight).toBe(1);
+ });
+
it('should trigger change detection after loading competencies', () => {
jest.spyOn(courseStorageService, 'getCourse').mockReturnValue({ competencies: undefined });
const changeDetector = fixture.debugElement.injector.get(ChangeDetectorRef);