Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Programming exercises: Improve template/solution comparison visibility #8745

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
516aba4
Exchange icon
florian-glombik May 24, 2024
b33e22f
Adjusting headline and button label
florian-glombik May 24, 2024
e514cf6
Changing button color and position
florian-glombik May 27, 2024
942f43e
Merge branch 'refs/heads/develop' into chore/programming-exercises/im…
florian-glombik May 27, 2024
ce711cd
Fix import for button type
florian-glombik May 27, 2024
e6ea299
Refactor variable name
florian-glombik May 27, 2024
684639e
Unify title in modal and details view
florian-glombik May 28, 2024
cf9d539
Improve tooltip positioning
florian-glombik May 28, 2024
b660280
Adding a description
florian-glombik May 28, 2024
59e1b60
Adding a tooltip
florian-glombik May 28, 2024
76748a9
Adding translation for shortDescription
florian-glombik Jun 5, 2024
f0d0105
Make icons readonly
florian-glombik Jun 5, 2024
9d84f57
Add tooltip to section
florian-glombik Jun 5, 2024
05447ce
Merge branch 'refs/heads/develop' into chore/programming-exercises/im…
florian-glombik Jun 5, 2024
e3536df
Make coderabbit happy
florian-glombik Jun 5, 2024
2a3272a
Fix ngbTooltip binding
florian-glombik Jun 5, 2024
87b7662
Merge branch 'develop' into chore/programming-exercises/improve-templ…
florian-glombik Jun 5, 2024
81c3d07
Extend documentation, explicitly state diff view feature
florian-glombik Jun 5, 2024
2f6203c
Change translation back
florian-glombik Jun 5, 2024
e6927e7
Merge branch 'develop' into chore/programming-exercises/improve-templ…
florian-glombik Jun 5, 2024
cf2bc80
Move to other part of the documentation
florian-glombik Jun 5, 2024
8b8afef
Merge remote-tracking branch 'origin/chore/programming-exercises/impr…
florian-glombik Jun 5, 2024
03353bb
Address reviews
florian-glombik Jun 6, 2024
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
34 changes: 30 additions & 4 deletions docs/user/exercises/programming-exercise-setup.inc
Original file line number Diff line number Diff line change
Expand Up @@ -608,11 +608,37 @@ Verify the exercise configuration
.. figure:: programming/solution-template-result.png
:align: center

- The template result should have a score of **0%** with **0 of X passed** or **0 of X passed, 0 issues** (if static code analysis is enabled)
- The solution result should have a score of **100%** with **X of X passed** or **X of X passed, 0 issues** (if static code analysis is enabled)
- The template result should have a score of **0%** with **0 of X passed** or **0 of X passed, 0 issues** (if static code analysis is enabled)
- The solution result should have a score of **100%** with **X of X passed** or **X of X passed, 0 issues** (if static code analysis is enabled)

.. note::
If static code analysis is enabled and issues are found in the template/solution result, instructors should improve the template/solution or disable the rule, which produced the unwanted/unimportant issue.
.. raw:: html

<br>

.. note::
If static code analysis is enabled and issues are found in the template/solution result, instructors should improve the template/solution or disable the rule, which produced the unwanted/unimportant issue.


- You can review differences between the **template** and **solution** repositories.
The comparison allows you to review the changes students are expected to make to the exercise template to solve the exercise.

.. figure:: programming/course-management-template-solution-diff.png
:alt: Template/Solution Comparison in Exercise Management Page
:align: center

Template/Solution Comparison in Exercise Management Page

You can open the comparison view by clicking the |review-changes-button| button.

.. figure:: programming/course-management-template-solution-diff-example.png
:alt: Template/Solution Comparison Example
:align: center

Template/Solution Comparison View Example

.. |review-changes-button| image:: programming/course-management-template-solution-diff-review-changes-button.png
:alt: '*Review Changes*'
:width: 150px

- Click on |edit|

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -163,25 +163,30 @@ <h3 class="section-headline" [id]="headlinesRecord[section.headline]">{{ section
}
@case (DetailType.ProgrammingDiffReport) {
<dd id="detail-value-{{ detail.title }}">
<span jhiTranslate="artemisApp.programmingExercise.diffReport.shortDescription"></span>
<div class="fw-bold">
<jhi-git-diff-line-stat
[addedLineCount]="detail.data.addedLineCount"
[removedLineCount]="detail.data.removedLineCount"
ngbTooltip="{{ 'artemisApp.programmingExercise.diffReport.lineStatTooltipDetailPage' | artemisTranslate }}"
placement="right"
/>
@if (detail.data.addedLineCount > 0 || detail.data.removedLineCount > 0) {
</div>
@if (detail.data.addedLineCount > 0 || detail.data.removedLineCount > 0) {
<div class="mt-1">
<jhi-button
[featureToggle]="FeatureToggle.ProgrammingExercises"
[isLoading]="detail.data.isLoadingDiffReport ?? false"
[btnSize]="ButtonSize.SMALL"
[icon]="faEye"
[icon]="faCodeCompare"
[title]="'artemisApp.programmingExercise.diffReport.button'"
[tooltip]="'artemisApp.programmingExercise.diffReport.tooltip'"
(onClick)="showGitDiff(detail.data.gitDiffReport)"
class="ms-2"
[btnType]="WARNING"
[tooltipPlacement]="TooltipPlacement.RIGHT"
/>
}
</div>
</div>
}
</dd>
}
@case (DetailType.ProgrammingProblemStatement) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Component, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { faArrowUpRightFromSquare, faCodeBranch, faExclamationTriangle, faEye } from '@fortawesome/free-solid-svg-icons';
import { faArrowUpRightFromSquare, faCodeBranch, faCodeCompare, faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
florian-glombik marked this conversation as resolved.
Show resolved Hide resolved
import { isEmpty } from 'lodash-es';
import { FeatureToggle } from 'app/shared/feature-toggle/feature-toggle.service';
import { ButtonSize } from 'app/shared/components/button.component';
import { ButtonSize, ButtonType, TooltipPlacement } from 'app/shared/components/button.component';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { GitDiffReportModalComponent } from 'app/exercises/programming/hestia/git-diff-report/git-diff-report-modal.component';
import { ProgrammingExerciseGitDiffReport } from 'app/entities/hestia/programming-exercise-git-diff-report.model';
Expand Down Expand Up @@ -63,12 +63,14 @@ export class DetailOverviewListComponent implements OnInit, OnDestroy {
headlinesRecord: Record<string, string>;

// icons
faExclamationTriangle = faExclamationTriangle;
faEye = faEye;
faArrowUpRightFromSquare = faArrowUpRightFromSquare;
faCodeBranch = faCodeBranch;
readonly faExclamationTriangle = faExclamationTriangle;
readonly faCodeCompare = faCodeCompare;
readonly faArrowUpRightFromSquare = faArrowUpRightFromSquare;
readonly faCodeBranch = faCodeBranch;

profileSub: Subscription;
WARNING = ButtonType.WARNING;

profileSubscription: Subscription;
isLocalVC = false;

constructor(
Expand All @@ -85,7 +87,7 @@ export class DetailOverviewListComponent implements OnInit, OnDestroy {
translationKey: section.headline,
};
});
this.profileSub = this.profileService.getProfileInfo().subscribe((profileInfo) => {
this.profileSubscription = this.profileService.getProfileInfo().subscribe((profileInfo) => {
florian-glombik marked this conversation as resolved.
Show resolved Hide resolved
florian-glombik marked this conversation as resolved.
Show resolved Hide resolved
this.isLocalVC = profileInfo.activeProfiles.includes(PROFILE_LOCALVC);
});
this.headlinesRecord = this.headlines.reduce((previousValue, currentValue) => {
Expand Down Expand Up @@ -113,6 +115,8 @@ export class DetailOverviewListComponent implements OnInit, OnDestroy {
}

ngOnDestroy() {
this.profileSub?.unsubscribe();
this.profileSubscription?.unsubscribe();
}

protected readonly TooltipPlacement = TooltipPlacement;
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ <h4 class="exercise-title">
[featureToggle]="FeatureToggle.ProgrammingExercises"
[isLoading]="isLoadingDiffReport"
[btnSize]="ButtonSize.SMALL"
[icon]="faEye"
[icon]="faCodeCompare"
[title]="'artemisApp.programmingExercise.diffReport.button'"
[tooltip]="'artemisApp.programmingExercise.diffReport.tooltipBetweenSubmissions'"
(onClick)="showGitDiff()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Exercise, IncludedInOverallScore } from 'app/entities/exercise.model';
import { ExamSubmissionComponent } from 'app/exam/participate/exercises/exam-submission.component';
import { Submission } from 'app/entities/submission.model';
import { ProgrammingExerciseStudentParticipation } from 'app/entities/participation/programming-exercise-student-participation.model';
import { faEye } from '@fortawesome/free-solid-svg-icons';
import { faCodeCompare } from '@fortawesome/free-solid-svg-icons';
import { ProgrammingExerciseGitDiffReport } from 'app/entities/hestia/programming-exercise-git-diff-report.model';
import { ExamPageComponent } from 'app/exam/participate/exercises/exam-page.component';
import { Observable, Subject, Subscription, debounceTime, take } from 'rxjs';
Expand Down Expand Up @@ -39,7 +39,7 @@ export class ProgrammingExerciseExamDiffComponent extends ExamPageComponent impl

readonly FeatureToggle = FeatureToggle;
readonly ButtonSize = ButtonSize;
readonly faEye = faEye;
readonly faCodeCompare = faCodeCompare;
readonly IncludedInOverallScore = IncludedInOverallScore;

constructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,8 @@ export class ProgrammingExerciseDetailComponent implements OnInit, OnDestroy {
},
{
type: DetailType.ProgrammingDiffReport,
title: 'artemisApp.programmingExercise.diffReport.lineStatLabel',
title: 'artemisApp.programmingExercise.diffReport.title',
titleHelpText: 'artemisApp.programmingExercise.diffReport.detailedTooltip',
data: {
addedLineCount: this.addedLineCount,
removedLineCount: this.removedLineCount,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<button
[ngClass]="['jhi-btn', 'btn', btnType, btnSize]"
[type]="shouldSubmit ? 'submit' : 'button'"
ngbTooltip="{{ tooltip | artemisTranslate }}"
[ngbTooltip]="tooltip | artemisTranslate"
florian-glombik marked this conversation as resolved.
Show resolved Hide resolved
(click)="onClick.emit($event)"
[jhiFeatureToggle]="featureToggle"
[overwriteDisabled]="disabled || isLoading"
[placement]="tooltipPlacement"
>
@if (isLoading) {
<fa-icon class="jhi-btn__loading sm" [icon]="faCircleNotch" [spin]="true" />
Expand Down
10 changes: 9 additions & 1 deletion src/main/webapp/app/shared/components/button.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ export enum ButtonSize {
LARGE = 'btn-lg',
}

export enum TooltipPlacement {
TOP = 'top',
BOTTOM = 'bottom',
LEFT = 'left',
RIGHT = 'right',
}

/**
* A generic button component that has a disabled & loading state.
* The only event output is the click.
Expand All @@ -48,6 +55,7 @@ export class ButtonComponent {
// Translation placeholders, will be translated in the component.
@Input() title: string;
@Input() tooltip: string;
@Input() tooltipPlacement: TooltipPlacement = TooltipPlacement.TOP;

@Input() disabled = false;
@Input() isLoading = false;
Expand All @@ -59,5 +67,5 @@ export class ButtonComponent {
@Output() onClick = new EventEmitter<MouseEvent>();

// Icons
faCircleNotch = faCircleNotch;
readonly faCircleNotch = faCircleNotch;
}
7 changes: 4 additions & 3 deletions src/main/webapp/i18n/de/programmingExercise.json
Original file line number Diff line number Diff line change
Expand Up @@ -546,15 +546,17 @@
}
},
"diffReport": {
"button": "Anzeigen",
"button": "Änderungen überprüfen",
"tooltip": "Zeigt den detaillierten Git-Diff zwischen den Template- und Lösungs-Repositories.",
"detailedTooltip": "Die Vergleichsansicht hebt alle Änderungen zwischen dem Vorlage- und dem Lösungs-Repository hervor. Rot markierte Zeilen zeigen Löschungen, d.h. Zeilen, die in der Lösung im Vergleich zur Vorlage entfernt wurden. Grün markierte Zeilen zeigen, was in der Lösung hinzugefügt wurde.",
"splitView": {
"enable": "Getrennte Ansicht aktivieren",
"disable": "Getrennte Ansicht deaktivieren",
"tooltip": "In der getrennten Ansicht werden beide Versionen jeder geänderten Datei nebeneinander angezeigt. Beachte, dass die getrennte Ansicht nur dann angezeigt wird, wenn dein Browserfenster breit genug ist."
},
"tooltipBetweenSubmissions": "Zeigt den detaillierten Git-Diff zwischen der aktuellen und der vorherigen Abgabe.",
"title": "Template-Lösungs-Diff",
"title": "Vergleich von Template und Lösung",
"shortDescription": "Überprüfe, welche Änderungen am Template von den Studierenden erwartet werden, um die Aufgabe zu lösen.",
"titleForSubmissions": "Abgaben-Diff",
"emptyRepository": "Leeres Repository",
"template": "Vorlage",
Expand All @@ -570,7 +572,6 @@
},
"errorWhileFetchingRepos": "Fehler beim Abrufen der Repositories. Bitte überprüfe deine Internetverbindung und öffne das Popup erneut.",
"404": "Template-Lösungs-Diff wurde noch nicht generiert. Bitte pusche etwas in die Template- oder Lösungs-Repositories, um ihn zu erstellen.",
"lineStatLabel": "Zeilen, die zwischen Vorlage und Lösung hinzugefügt/entfernt wurden",
Copy link
Contributor Author

@florian-glombik florian-glombik Jun 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The translation is not used anymore, see src/main/webapp/app/exercises/programming/manage/programming-exercise-detail.component.ts

"lineStatBetweenSubmissionsCurrentSubmissionLabel": "Zeilen, die zwischen der aktuellen Abgabe mit Commit-Hash <span class=\"font-italic text-info\"> {{ currentCommitHash }} </span>",
"lineStatBetweenSubmissionsPreviousSubmissionLabel": "und der vorherigen Abgabe mit Commit-Hash <span class=\"font-italic text-info\"> {{ previousCommitHash }} </span> hinzugefügt/entfernt wurden",
"lineStatBetweenSubmissionsTemplateLabel": "und der Vorlage hinzugefügt/entfernt wurden",
Expand Down
7 changes: 4 additions & 3 deletions src/main/webapp/i18n/en/programmingExercise.json
Original file line number Diff line number Diff line change
Expand Up @@ -548,15 +548,17 @@
}
},
"diffReport": {
"button": "Show",
"button": "Review Changes",
"tooltip": "Shows the detailed git-diff between the template and solution repositories.",
"detailedTooltip": "The comparison view highlights all changes between the template and solution repositories. Red indicates deletions from the template, while green shows additions made in the solution.",
"splitView": {
"enable": "Enable split view",
"disable": "Disable split view",
"tooltip": "In the split view, both versions of each changed file are displayed next to each other. Note that the split view will only be shown if your browser window is wide enough."
},
"tooltipBetweenSubmissions": "Shows the detailed git-diff between the current and previous submission.",
"title": "Template-Solution-Diff",
"title": "Template/Solution Comparison",
"shortDescription": "Review which changes to the template are expected from students to solve the exercise.",
"titleForSubmissions": "Submission-Diff",
"template": "Template",
"solution": "Solution",
Expand All @@ -572,7 +574,6 @@
},
"errorWhileFetchingRepos": "An error occurred while fetching the repositories. Please check your internet connection and reopen the modal.",
"404": "Template-Solution-Diff has not been generated yet. Please do a push to the template or solution repository to generate it.",
"lineStatLabel": "Lines added/removed between template and solution",
"lineStatBetweenSubmissionsCurrentSubmissionLabel": "Lines added/removed between the current submission with commit hash <span class=\"font-italic text-info\"> {{ currentCommitHash }} </span>",
"lineStatBetweenSubmissionsPreviousSubmissionLabel": " and the previous submission with commit hash <span class=\"font-italic text-info\"> {{ previousCommitHash }} </span>",
"lineStatBetweenSubmissionsTemplateLabel": "and the template",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('DetailOverviewList', () => {
expect(DetailOverviewListComponent).not.toBeNull();

component.ngOnDestroy();
expect(component.profileSub?.closed).toBeTruthy();
expect(component.profileSubscription?.closed).toBeTruthy();
});

it('should escape all falsy values', () => {
Expand Down
Loading