Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
84fa224
Assessment: add editable-mode signals to UnifiedFeedbackComponent
musaberkay Jul 1, 2026
0c6466c
Assessment: render editable feedback form in UnifiedFeedbackComponent
musaberkay Jul 1, 2026
3e782a2
Assessment: migrate unreferenced feedback card to UnifiedFeedbackComp…
musaberkay Jul 1, 2026
f3d22f9
Assessment: migrate text block feedback editor to UnifiedFeedbackComp…
musaberkay Jul 1, 2026
d057d20
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 1, 2026
5da95c0
Assessment: address PR review feedback on unified feedback editing
musaberkay Jul 1, 2026
1946d7f
Merge branch 'feature/assessment/uniform-feedback-editing' of https:/…
musaberkay Jul 1, 2026
e5e0e2a
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 1, 2026
e296c79
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 3, 2026
1720e2a
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 4, 2026
f96dd60
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 9, 2026
06e764d
Assessment: add missing branch coverage for didChange unchanged-text …
musaberkay Jul 9, 2026
7e571b6
Text exercise: cover ngOnDestroy false-branch for client coverage gate
musaberkay Jul 9, 2026
11b47ce
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 13, 2026
670dd95
Fix: Update ngModel binding for feedback credits input to handle null…
musaberkay Jul 13, 2026
e9f6b3b
Fix: Add showReference binding to jhi-unified-feedback component
musaberkay Jul 13, 2026
ef87d09
Fix: Prevent click events from bubbling in unified feedback toolbar a…
musaberkay Jul 13, 2026
dc262ab
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 13, 2026
d4fb8ba
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 13, 2026
d5c8565
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 15, 2026
f046c8e
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 20, 2026
7cfb046
Style: Adjust spacing and padding in unified feedback component for i…
musaberkay Jul 20, 2026
a85cfff
Development: Use a minus icon for not_attempted feedback in the unifi…
musaberkay Jul 20, 2026
c6bc3b8
Style: Add circular icon badge and pill-shaped points badge to unifie…
musaberkay Jul 20, 2026
94544cc
Development: Add a footer display variant to FeedbackSuggestionBadgeC…
musaberkay Jul 20, 2026
f55a8bb
Style: Move the AI feedback suggestion badge to a footer strip in uni…
musaberkay Jul 20, 2026
3b12bf2
Development: Update AI feedback suggestion badge wording
musaberkay Jul 20, 2026
1cdd078
Test: Cover the isFeedbackSuggestion-only branch of the unified feedb…
musaberkay Jul 21, 2026
4b82115
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 21, 2026
756c487
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 23, 2026
8512093
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 24, 2026
86d57f2
Merge branch 'feature/assessment/uniform-feedback-editing' of https:/…
musaberkay Jul 24, 2026
c555274
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 24, 2026
474eb6c
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 25, 2026
901aafc
Refactor unified feedback component: enhance input layout and update …
musaberkay Jul 26, 2026
c1c1179
refactor: remove feedback suggestion handling from code editor compon…
musaberkay Jul 29, 2026
293a6eb
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 29, 2026
cf0022c
Merge branch 'feature/assessment/uniform-feedback-editing' of https:/…
musaberkay Jul 29, 2026
4c91ab9
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 30, 2026
5e58162
Development: Replace NgbTooltip with TumUiTooltip in feedback components
musaberkay Jul 30, 2026
dfd95ba
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 30, 2026
afcad8f
Merge branch 'feature/assessment/uniform-feedback-editing' of https:/…
musaberkay Jul 30, 2026
dfbded6
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 30, 2026
f1921d9
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Jul 30, 2026
d36717e
Merge remote-tracking branch 'origin/develop' into feature/assessment…
musaberkay Aug 3, 2026
26b569b
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 3, 2026
99d304f
Merge remote-tracking branch 'origin/develop' into feature/assessment…
musaberkay Aug 4, 2026
a1d5aa0
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 5, 2026
e53ebd7
Programming assessment: Fix stale Athena feedback suggestions on subm…
musaberkay Aug 5, 2026
1b0ece0
Merge branch 'feature/assessment/uniform-feedback-editing' of https:/…
musaberkay Aug 5, 2026
0d1f8bf
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 7, 2026
1e36872
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 7, 2026
f2f57a2
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 9, 2026
8bf074b
Development: Update imports for TumUiTooltipDirective to use the new …
musaberkay Aug 9, 2026
a81b0a1
Assessment: Fix review feedback on unified feedback editing
musaberkay Aug 9, 2026
2d26feb
Assessment: Add missing detail input indication in unified feedback c…
musaberkay Aug 9, 2026
ca0ec91
Assessment: Remove useDefaultFeedbackSuggestionBadgeText from feedbac…
musaberkay Aug 9, 2026
56728cb
Assessment: Hide AI feedback suggestion badge from student-facing views
musaberkay Aug 9, 2026
1f0ed22
Assessment: Restore full-card drag target for structured grading inst…
musaberkay Aug 9, 2026
6a8738e
Assessment: Refactor feedback suggestion handling by removing 'ADAPTE…
musaberkay Aug 9, 2026
b6e4143
Assessment: Restore ADAPTED feedback suggestion type and string-based…
musaberkay Aug 10, 2026
0e7539c
Assessment: Fix feedback suggestion badge staleness by keying it on p…
musaberkay Aug 10, 2026
7fc7552
Assessment: Mark accepted feedback suggestions as adapted on edit, ce…
musaberkay Aug 10, 2026
f716e0e
Assessment: Strip adapted-suggestion prefix from published programmin…
musaberkay Aug 10, 2026
5a30dcd
Assessment: Restore adapted-suggestion text-prefix marking for modeli…
musaberkay Aug 10, 2026
73f3664
Assessment: Migrate programming inline feedback editing to UnifiedFee…
musaberkay Aug 10, 2026
c1a2507
Assessment: Wire the unified feedback dismiss control to cancel the o…
musaberkay Aug 10, 2026
c089da3
Assessment: Fix stale Playwright selectors in AbstractExerciseAssessm…
musaberkay Aug 11, 2026
0862ded
Assessment: Restore E2E selector hooks for unreferenced feedback add …
musaberkay Aug 11, 2026
a86ac0f
Assessment: Fix programming inline feedback title and cancel affordances
musaberkay Aug 11, 2026
1c062c6
Merge remote-tracking branch 'origin/develop' into feature/assessment…
musaberkay Aug 13, 2026
627810b
Merge remote-tracking branch 'origin/develop' into feature/assessment…
musaberkay Aug 19, 2026
47704e1
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 19, 2026
37130f7
Merge branch 'feature/assessment/uniform-feedback-editing' of https:/…
musaberkay Aug 19, 2026
0cfb467
Refactor feedback handling in UnreferencedFeedbackDetailComponent and…
musaberkay Aug 20, 2026
c864871
Update unified-feedback-detail-input-missing style to use left border…
musaberkay Aug 20, 2026
3c0f12e
Implement editable title as a textarea with auto-resizing and update …
musaberkay Aug 20, 2026
a19d654
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 20, 2026
e6cb80e
Exam mode: Fix TextExerciseAssessmentPage selectors after unified fee…
musaberkay Aug 21, 2026
26171ba
Exam mode: Fix duplicate unreferenced feedback card on long-feedback …
musaberkay Aug 21, 2026
2cf92f8
Exam mode: Fix stale automatic-feedback banner and missing unsaved-ch…
musaberkay Aug 21, 2026
e2133b1
Exam mode: Centralize accepted-to-adapted transition in text feedback…
musaberkay Aug 21, 2026
74cf5fd
Uniform feedback editing: Fix failing client tests and focus regression
musaberkay Aug 21, 2026
663f58b
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 21, 2026
fc030ea
Uniform feedback editing: Clear hasLongFeedbackText on hydrated clone
musaberkay Aug 21, 2026
f27e054
Uniform feedback editing: Require confirmation to dismiss grading-ins…
musaberkay Aug 21, 2026
8720994
Exam mode: Reset loadingFeedbackSuggestions on submission navigation
musaberkay Aug 21, 2026
a7b0c60
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 21, 2026
9b47f35
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 23, 2026
1ec53c8
Enhancement: Add stepper buttons for adjusting feedback points and up…
musaberkay Aug 23, 2026
a7ee400
Enhancement: Show read-only feedback points as a color-tinted pill by…
musaberkay Aug 23, 2026
8da49a6
Fix: Use local constant instead of protected CREDITS_STEP in spec
musaberkay Aug 23, 2026
047fb70
Fix: Drive feedback points via stepper in E2E page objects
musaberkay Aug 23, 2026
b8d8bed
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 23, 2026
b89b9f0
Assessment: Migrate programming inline feedback read-only view to Uni…
musaberkay Aug 23, 2026
f293e5b
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 24, 2026
b5818cc
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 25, 2026
5bcb2a2
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
musaberkay Aug 25, 2026
e9b63f4
Merge branch 'develop' into feature/assessment/uniform-feedback-editing
SultanTheHL Aug 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,105 +1,15 @@
<div (drop)="updateFeedbackOnDrop($event)" (dragover)="$event.preventDefault()" class="unreferenced-feedback-detail card mb-3" [class.is-suggestion]="isSuggestion()">
<div class="card-header">
@if (isSuggestion() || Feedback.isFeedbackSuggestion(feedback())) {
<jhi-feedback-suggestion-badge [feedback]="feedback()" [useDefaultText]="useDefaultFeedbackSuggestionBadgeText()" />
}
@if (feedback().gradingInstruction) {
<jhi-grading-instruction-link-icon [feedback]="feedback()" />
}
@if (!readOnly()) {
<button
jhiDeleteButton
[buttonSize]="ButtonSize.SMALL"
[translateValues]="{ text: this.feedback() | feedbackContent | quoted: ' ' }"
deleteQuestion="artemisApp.feedback.delete.question"
(delete)="delete()"
[dialogError]="dialogError$"
[renderButtonStyle]="false"
[renderButtonText]="false"
class="btn float-end"
>
<fa-icon [icon]="faTrashAlt" />
</button>
}
<!-- Accept/Discard for feedback suggestions -->
@if (isSuggestion()) {
<div class="row float-end suggestion-action-buttons">
<button class="btn btn-success m-1 btn-sm" (click)="onAcceptSuggestion.emit(feedback())">
<fa-icon [icon]="faCheck" />
<span jhiTranslate="artemisApp.assessment.detail.accept"></span>
</button>
<button class="btn btn-danger m-1 btn-sm" (click)="onDiscardSuggestion.emit(feedback())">
<fa-icon [icon]="faTrash" />
<span jhiTranslate="artemisApp.assessment.detail.discard"></span>
</button>
</div>
}
</div>
<div class="card-body">
<div class="form-group row">
<label for="feedback-points" class="col-4 feedback-label" jhiTranslate="artemisApp.exercise.score"></label>
<input
id="feedback-points"
class="col form-control"
type="number"
step="0.5"
[(ngModel)]="feedback().credits"
(ngModelChange)="emitChanges()"
[disabled]="!!feedback().gradingInstruction || readOnly()"
[readOnly]="!!feedback().gradingInstruction || readOnly()"
[required]="!feedback().gradingInstruction"
/>
</div>
<div class="form-group row">
<div class="col-4 assessment-label">
<label class="pe-0" jhiTranslate="artemisApp.assessment.detail.feedback"></label>
@if (feedback().gradingInstruction) {
<div>
<fa-icon [icon]="faQuestionCircle" class="text-secondary ps-1" [ngbTooltip]="'artemisApp.assessment.feedbackHint' | artemisTranslate" />
</div>
}
</div>
<div class="col p-0">
@if (feedback().gradingInstruction) {
<div>
<span>{{ feedback().gradingInstruction!.feedback }}</span>
</div>
}
<textarea
id="feedback-textarea"
class="form-control"
rows="2"
[(ngModel)]="feedback().detailText"
(ngModelChange)="emitChanges()"
[readOnly]="readOnly()"
[disabled]="readOnly()"
[placeholder]="
feedback().gradingInstruction?.feedback
? ('artemisApp.assessment.additionalFeedbackCommentPlaceholder' | artemisTranslate)
: ('artemisApp.assessment.feedbackCommentPlaceholder' | artemisTranslate)
"
[required]="!feedback().gradingInstruction?.feedback"
></textarea>
</div>
</div>
<!-- Text showing whether the tutor feedback is correct or not (upon validation on the server) -->
@if (feedback().correctionStatus !== undefined) {
<div>
@if (feedback().correctionStatus === 'CORRECT') {
<span class="text-success">{{ 'artemisApp.exampleSubmission.feedback.' + feedback().correctionStatus! | artemisTranslate }} </span>
}
@if (feedback().correctionStatus !== 'CORRECT') {
<span class="text-danger">{{ 'artemisApp.exampleSubmission.feedback.' + feedback().correctionStatus! | artemisTranslate }} </span>
}
<!-- :warning: emoji was rendered as a black-white glyph, hence the solution with the fa-icon -->
@if (feedback().correctionStatus !== 'CORRECT') {
<fa-layers>
<fa-icon class="text-warning" [icon]="faExclamationTriangle" />
<fa-icon class="text-dark exclamation-icon" [icon]="faExclamation" size="2x" transform="shrink-10" />
</fa-layers>
}
</div>
}
<jhi-assessment-correction-round-badge [feedback]="feedback()" [highlightDifferences]="highlightDifferences()" />
</div>
<div class="unreferenced-feedback-detail" (drop)="updateFeedbackOnDrop($event)" (dragover)="$event.preventDefault()">
<jhi-unified-feedback
[editable]="true"
[readOnly]="readOnly()"
[feedback]="feedback()"
[highlightDifferences]="highlightDifferences()"
[(feedbackTitle)]="feedback().text"
[(feedbackDetail)]="feedback().detailText"
[(feedbackCredits)]="feedback().credits!"
Comment thread
musaberkay marked this conversation as resolved.
(feedbackTitleChange)="emitChanges()"
(feedbackDetailChange)="emitChanges()"
(feedbackCreditsChange)="emitChanges()"
(onDelete)="delete()"
/>
</div>
Original file line number Diff line number Diff line change
@@ -1,42 +0,0 @@
.card-body {
padding-top: 5px;
padding-bottom: 5px;
}

.assessment-label > label {
float: left;
}

fa-icon.exclamation-icon {
width: 16px;
margin-top: -6px;
}

.is-suggestion .card-header,
.is-suggestion .card-body {
background-color: var(--feedback-suggestions-background);
}

.is-suggestion input,
.is-suggestion textarea {
background-color: var(--feedback-suggestions-input-background);
}

/* Slight opacity for suggestions until they are hovered */
.is-suggestion .card-body > * {
opacity: 0.6; /* grey out the suggestion content to indicate that it is not saved yet */
transition: opacity 0.2s ease-in-out;
}

.is-suggestion:hover .card-body > * {
opacity: 1; /* make the suggestion more readable on hover */
}

.suggestion-action-buttons button {
width: fit-content;
}

.assessment-label {
padding-left: 5px;
padding-right: 5px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@ describe('Unreferenced Feedback Detail Component', () => {
expect(getLongFeedbackTextSpy).toHaveBeenCalledWith(feedbackId);
});

it('should clear hasLongFeedbackText on the hydrated clone so a remount does not refetch indefinitely', async () => {
const feedbackId = 42;
const exampleText = 'This is a long feedback text';

fixture.componentRef.setInput('feedback', { id: feedbackId, hasLongFeedbackText: true } as Feedback);
fixture.componentRef.setInput('resultId', 1);
const getLongFeedbackTextSpy = vi.spyOn(feedbackService, 'getLongFeedbackText').mockResolvedValue(exampleText);

await comp.loadLongFeedback();

expect(comp.feedback().hasLongFeedbackText).toBeFalsy();
expect(comp.feedback().detailText).toBe(exampleText);

// Simulate the parent remounting the component with the hydrated feedback it just received.
fixture.componentRef.setInput('feedback', comp.feedback());
await comp.loadLongFeedback();

expect(getLongFeedbackTextSpy).toHaveBeenCalledOnce();
});

it('should update feedback with SGI and emit to parent', () => {
const instruction: GradingInstruction = { id: 1, credits: 2, feedback: 'test', gradingScale: 'good', instructionDescription: 'description of instruction', usageCount: 0 };
const feedback = {
Expand Down Expand Up @@ -68,19 +88,17 @@ describe('Unreferenced Feedback Detail Component', () => {
expect(emitSpy).toHaveBeenCalledOnce();
});

it('should emit the assessment change after deletion', () => {
fixture.componentRef.setInput('feedback', {
id: 1,
detailText: 'feedback1',
credits: 1.5,
} as Feedback);
it('exposes delete() as the sole deletion entry point for the unified feedback card', () => {
fixture.componentRef.setInput('feedback', { id: 1, detailText: 'feedback1', credits: 1.5 } as Feedback);
const emitSpy = vi.spyOn(comp.onFeedbackDelete, 'emit');

comp.delete();

expect(emitSpy).toHaveBeenCalledTimes(1);
expect(emitSpy).toHaveBeenCalledOnce();
expect(emitSpy).toHaveBeenCalledWith(comp.feedback());
});

it('should mark automatic feedback and feedback suggestions as adapted when they are modified', () => {
it('should mark automatic feedback as AUTOMATIC_ADAPTED when modified, without touching the suggestion badge text', () => {
fixture.componentRef.setInput('feedback', {
id: 1,
type: FeedbackType.AUTOMATIC,
Expand All @@ -93,7 +111,7 @@ describe('Unreferenced Feedback Detail Component', () => {
expect(emitSpy).toHaveBeenCalledWith({
id: 1,
type: FeedbackType.AUTOMATIC_ADAPTED,
text: 'FeedbackSuggestion:adapted:feedback1',
text: 'FeedbackSuggestion:accepted:feedback1',
detailText: 'feedback1',
credits: 1.5,
} as Feedback);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,72 +1,28 @@
import { Component, OnInit, inject, input, model, output } from '@angular/core';
import { faCheck, faExclamation, faExclamationTriangle, faQuestionCircle, faTrash, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import { Feedback, FeedbackType } from 'app/assessment/shared/entities/feedback.model';
import { StructuredGradingCriterionService } from 'app/exercise/structured-grading-criterion/structured-grading-criterion.service';
import { ButtonSize } from 'app/shared-ui/components/buttons/button/button.component';
import { Subject } from 'rxjs';
import { FeedbackService } from 'app/exercise/feedback/services/feedback.service';
import { GradingInstructionLinkIconComponent } from 'app/shared-ui/grading-instruction-link-icon/grading-instruction-link-icon.component';
import { DeleteButtonDirective } from 'app/shared-ui/delete-dialog/directive/delete-button.directive';
import { FaIconComponent, FaLayersComponent } from '@fortawesome/angular-fontawesome';
import { TranslateDirective } from 'app/foundation/language/translate.directive';
import { FormsModule } from '@angular/forms';
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
import { AssessmentCorrectionRoundBadgeComponent } from './assessment-correction-round-badge/assessment-correction-round-badge.component';
import { ArtemisTranslatePipe } from 'app/foundation/pipes/artemis-translate.pipe';
import { FeedbackContentPipe } from 'app/foundation/pipes/feedback-content.pipe';
import { QuotePipe } from 'app/foundation/pipes/quote.pipe';
import { FeedbackSuggestionBadgeComponent } from 'app/exercise/feedback/feedback-suggestion-badge/feedback-suggestion-badge.component';
import { UnifiedFeedbackComponent } from 'app/shared/components/unified-feedback/unified-feedback.component';
import { cloneWith } from 'app/foundation/util/deep-clone.util';

@Component({
selector: 'jhi-unreferenced-feedback-detail',
templateUrl: './unreferenced-feedback-detail.component.html',
styleUrls: ['./unreferenced-feedback-detail.component.scss'],
imports: [
FeedbackSuggestionBadgeComponent,
GradingInstructionLinkIconComponent,
DeleteButtonDirective,
FaIconComponent,
TranslateDirective,
FormsModule,
NgbTooltip,
FaLayersComponent,
AssessmentCorrectionRoundBadgeComponent,
ArtemisTranslatePipe,
FeedbackContentPipe,
QuotePipe,
],
imports: [UnifiedFeedbackComponent],
})
export class UnreferencedFeedbackDetailComponent implements OnInit {
structuredGradingCriterionService = inject(StructuredGradingCriterionService);

public readonly feedback = model.required<Feedback>();
readonly resultId = input.required<number>();
readonly isSuggestion = input<boolean>();
public readonly readOnly = input.required<boolean>();
readonly highlightDifferences = input<boolean>(false);
readonly useDefaultFeedbackSuggestionBadgeText = input.required<boolean>();

public readonly onFeedbackChange = output<Feedback>();
public readonly onFeedbackDelete = output<Feedback>();
readonly onAcceptSuggestion = output<Feedback>();
readonly onDiscardSuggestion = output<Feedback>();
private feedbackService = inject(FeedbackService);

// Icons
faTrashAlt = faTrashAlt;
faQuestionCircle = faQuestionCircle;
faExclamation = faExclamation;
faExclamationTriangle = faExclamationTriangle;
faCheck = faCheck;
faTrash = faTrash;

// Expose to template
protected readonly Feedback = Feedback;
readonly ButtonSize = ButtonSize;

private dialogErrorSource = new Subject<string>();
dialogError$ = this.dialogErrorSource.asObservable();

ngOnInit() {
void this.loadLongFeedback();
}
Expand All @@ -77,9 +33,10 @@ export class UnreferencedFeedbackDetailComponent implements OnInit {
public async loadLongFeedback() {
const feedback = this.feedback();
if (feedback.id && feedback.hasLongFeedbackText) {
feedback.detailText = await this.feedbackService.getLongFeedbackText(feedback.id);
this.feedback.set(feedback);
this.onFeedbackChange.emit(feedback);
const detailText = await this.feedbackService.getLongFeedbackText(feedback.id);
const updatedFeedback = cloneWith(feedback, { detailText, hasLongFeedbackText: false });
this.feedback.set(updatedFeedback);
this.onFeedbackChange.emit(updatedFeedback);
}
}

Expand All @@ -91,7 +48,6 @@ export class UnreferencedFeedbackDetailComponent implements OnInit {
if (feedback.type === FeedbackType.AUTOMATIC) {
feedback.type = FeedbackType.AUTOMATIC_ADAPTED;
}
Feedback.updateFeedbackTypeOnChange(feedback);
this.feedback.set(feedback);
this.onFeedbackChange.emit(feedback);
}
Expand All @@ -101,7 +57,6 @@ export class UnreferencedFeedbackDetailComponent implements OnInit {
*/
public delete() {
this.onFeedbackDelete.emit(this.feedback());
this.dialogErrorSource.next('');
}

updateFeedbackOnDrop(event: Event) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { describe, expect, it } from 'vitest';

import { Feedback } from 'app/assessment/shared/entities/feedback.model';
import {
FEEDBACK_SUGGESTION_ACCEPTED_IDENTIFIER,
FEEDBACK_SUGGESTION_ADAPTED_IDENTIFIER,
FEEDBACK_SUGGESTION_IDENTIFIER,
Feedback,
FeedbackSuggestionType,
} from 'app/assessment/shared/entities/feedback.model';

describe('Feedback', () => {
describe('getReferenceLineRange', () => {
Expand All @@ -16,4 +22,26 @@ describe('Feedback', () => {
},
);
});

describe('getFeedbackSuggestionType', () => {
it('should return NO_SUGGESTION for plain feedback text', () => {
expect(Feedback.getFeedbackSuggestionType('Just a comment')).toBe(FeedbackSuggestionType.NO_SUGGESTION);
expect(Feedback.getFeedbackSuggestionType(undefined)).toBe(FeedbackSuggestionType.NO_SUGGESTION);
expect(Feedback.getFeedbackSuggestionType({ text: 'Just a comment' })).toBe(FeedbackSuggestionType.NO_SUGGESTION);
});

it('should return SUGGESTED for a bare suggestion prefix', () => {
expect(Feedback.getFeedbackSuggestionType(`${FEEDBACK_SUGGESTION_IDENTIFIER}Missing null check`)).toBe(FeedbackSuggestionType.SUGGESTED);
});

it('should return ACCEPTED for an accepted-suggestion prefix', () => {
expect(Feedback.getFeedbackSuggestionType(`${FEEDBACK_SUGGESTION_ACCEPTED_IDENTIFIER}Missing null check`)).toBe(FeedbackSuggestionType.ACCEPTED);
expect(Feedback.getFeedbackSuggestionType({ text: `${FEEDBACK_SUGGESTION_ACCEPTED_IDENTIFIER}Missing null check` })).toBe(FeedbackSuggestionType.ACCEPTED);
});

it('should return ADAPTED for an adapted-suggestion prefix, accepting either a string or a Feedback object', () => {
expect(Feedback.getFeedbackSuggestionType(`${FEEDBACK_SUGGESTION_ADAPTED_IDENTIFIER}Missing null check`)).toBe(FeedbackSuggestionType.ADAPTED);
expect(Feedback.getFeedbackSuggestionType({ text: `${FEEDBACK_SUGGESTION_ADAPTED_IDENTIFIER}Missing null check` })).toBe(FeedbackSuggestionType.ADAPTED);
});
});
});
Loading
Loading