Skip to content

Commit

Permalink
Programming exercises: Allow tutors to assess submissions in the new …
Browse files Browse the repository at this point in the history
…code editor (#8437)
  • Loading branch information
pzdr7 authored Apr 26, 2024
1 parent 84fc7d3 commit 962b00a
Show file tree
Hide file tree
Showing 19 changed files with 693 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
>
@if (!loadingParticipation && !participationCouldNotBeFetched) {
<jhi-code-editor-container
[useMonacoEditor]="true"
[editable]="false"
[participation]="participation"
[feedbackSuggestions]="feedbackSuggestions"
Expand All @@ -72,7 +73,7 @@
(onUpdateFeedback)="onUpdateFeedback($event)"
(onAcceptSuggestion)="removeSuggestion($event)"
(onDiscardSuggestion)="removeSuggestion($event)"
(onFileLoad)="onFileLoad($event)"
(onFileLoad)="highlightChangedLines($event)"
>
<div editorTitle *ngTemplateOutlet="editorTitle"></div>
<div editorToolbar *ngTemplateOutlet="editorToolbar"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,20 +295,18 @@ export class CodeEditorTutorAssessmentContainerComponent implements OnInit, OnDe
}

/**
* Triggers when a new file was selected in the code editor. Compares the content of the file with the template (if available), calculates the diff
* and highlights the changed/added lines or all lines if the file is not in the template.
*
* @param selectedFile name of the file which is currently displayed
* For a file, computes the diff between the template and the submission currently being viewed, then highlights changed or edited lines in the editor.
* If the file did not exist in the template, all lines will be highlighted.
* @param selectedFile The file that has been selected in the editor.
*/
onFileLoad(selectedFile: string): void {
if (selectedFile && this.codeEditorContainer?.selectedFile && this.codeEditorContainer.aceEditor) {
// When the selectedFile is not part of the template, then this is a new file and all lines in code editor are highlighted
highlightChangedLines(selectedFile: string) {
if (selectedFile && this.codeEditorContainer?.selectedFile) {
if (!this.templateFileSession[selectedFile]) {
const lastLine = this.codeEditorContainer.aceEditor.editorSession.getLength() - 1;
const lastLine = this.codeEditorContainer.getNumberOfLines() - 1;
this.highlightLines(0, lastLine);
} else {
// Calculation of the diff, see: https://github.com/google/diff-match-patch/wiki/Line-or-Word-Diffs
const diffArray = this.diffMatchPatch.diff_linesToChars(this.templateFileSession[selectedFile], this.codeEditorContainer.aceEditor.editorSession.getValue());
const diffArray = this.diffMatchPatch.diff_linesToChars(this.templateFileSession[selectedFile], this.codeEditorContainer.getText());
const lineText1 = diffArray.chars1;
const lineText2 = diffArray.chars2;
const lineArray = diffArray.lineArray;
Expand Down Expand Up @@ -337,9 +335,7 @@ export class CodeEditorTutorAssessmentContainerComponent implements OnInit, OnDe
}

private highlightLines(firstLine: number, lastLine: number) {
if (this.codeEditorContainer?.aceEditor) {
this.codeEditorContainer.aceEditor.highlightLines(firstLine, lastLine, 'diff-newLine', 'gutter-diff-newLine');
}
this.codeEditorContainer.highlightLines(firstLine, lastLine);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,24 @@ <h4 class="editor-title"><ng-content select="[editorTitle]" /></h4>
/>
} @else {
<jhi-code-editor-monaco
#codeEditorMonaco
[commitState]="commitState"
[editorState]="editorState"
[course]="course"
[feedbacks]="participation?.results?.[0]?.feedbacks ?? []"
[feedbackSuggestions]="feedbackSuggestions"
[readOnlyManualFeedback]="readOnlyManualFeedback"
[disableActions]="!editable"
[isTutorAssessment]="isTutorAssessment"
[highlightDifferences]="highlightDifferences"
[selectedFile]="selectedFile"
[buildAnnotations]="annotations"
[sessionId]="participation?.id ?? 'test'"
(onFileContentChange)="onFileContentChange($event)"
(onUpdateFeedback)="onUpdateFeedback.emit($event)"
(onAcceptSuggestion)="onAcceptSuggestion.emit($event)"
(onDiscardSuggestion)="onDiscardSuggestion.emit($event)"
(onError)="onError($event)"
(onFileLoad)="fileLoad($event)"
/>
}
</ng-container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class CodeEditorContainerComponent implements OnChanges, ComponentCanDeac
@ViewChild(CodeEditorActionsComponent, { static: false }) actions: CodeEditorActionsComponent;
@ViewChild(CodeEditorBuildOutputComponent, { static: false }) buildOutput: CodeEditorBuildOutputComponent;
@ViewChild(CodeEditorAceComponent, { static: false }) aceEditor?: CodeEditorAceComponent;
@ViewChild('codeEditorMonaco', { static: false }) monacoEditor?: CodeEditorMonacoComponent;
@ViewChild(CodeEditorMonacoComponent, { static: false }) monacoEditor?: CodeEditorMonacoComponent;
@ViewChild(CodeEditorInstructionsComponent, { static: false }) instructions: CodeEditorInstructionsComponent;

@Input()
Expand Down Expand Up @@ -272,6 +272,24 @@ export class CodeEditorContainerComponent implements OnChanges, ComponentCanDeac
return _isEmpty(this.unsavedFiles);
}

getText(): string {
return this.monacoEditor?.getText() ?? '';
}

getNumberOfLines(): number {
if (this.aceEditor) {
return this.aceEditor.editorSession.getLength();
}
return this.monacoEditor?.getNumberOfLines() ?? 0;
}

highlightLines(startLine: number, endLine: number): void {
// Workaround: increase line number by 1 for monaco
// Will be removed once ace is gone from every instance of this component
this.monacoEditor?.highlightLines(startLine + 1, endLine + 1);
this.aceEditor?.highlightLines(startLine, endLine, 'diff-newLine', 'gutter-diff-newLine');
}

// displays the alert for confirming refreshing or closing the page if there are unsaved changes
@HostListener('window:beforeunload', ['$event'])
unloadNotification(event: any) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,52 @@
<div class="card">
<div [hidden]="true">
<div #addFeedbackButton>
<div class="monaco-add-feedback-button">
<fa-icon [icon]="faPlusSquare" />
</div>
</div>
</div>
<jhi-code-editor-header [showTabSizeSelector]="false" [filename]="selectedFile!" [isLoading]="isLoading" />
<div class="card-body card-body-monaco">
@if (selectedFile) {
@for (feedback of filterFeedbackForSelectedFile(feedbacks); track feedback) {
<!-- actual, stored feedback -->
<jhi-code-editor-tutor-assessment-inline-feedback
class="monaco-hidden-element"
[selectedFile]="selectedFile"
[codeLine]="Feedback.getReferenceLine(feedback)!"
[feedback]="feedback"
[readOnly]="true"
[highlightDifferences]="false"
[readOnly]="readOnlyManualFeedback"
[highlightDifferences]="highlightDifferences"
[course]="course"
(onUpdateFeedback)="updateFeedback($event)"
(onDeleteFeedback)="deleteFeedback($event)"
(onCancelFeedback)="cancelFeedback($event)"
/>
}
<!-- new, unsaved feedback -->
@for (line of newFeedbackLines; track line) {
<jhi-code-editor-tutor-assessment-inline-feedback
class="monaco-hidden-element"
[selectedFile]="selectedFile"
[codeLine]="line"
[feedback]="undefined"
[highlightDifferences]="highlightDifferences"
[readOnly]="readOnlyManualFeedback"
[course]="course"
(onUpdateFeedback)="updateFeedback($event)"
(onDeleteFeedback)="deleteFeedback($event)"
(onCancelFeedback)="cancelFeedback($event)"
/>
}
<!-- feedback suggestions -->
@for (suggestion of filterFeedbackForSelectedFile(feedbackSuggestions); track suggestion) {
<jhi-code-editor-tutor-assessment-inline-feedback-suggestion
[codeLine]="Feedback.getReferenceLine(suggestion)!"
[feedback]="suggestion"
[course]="course"
(onAcceptSuggestion)="acceptSuggestion($event)"
(onDiscardSuggestion)="discardSuggestion($event)"
/>
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,30 @@
.card-body-monaco {
padding: unset;
}

/* Applied e.g. to hover messages of build annotations. Makes them visible even when there are line widgets. */
.monaco-hover {
z-index: 1;
}

.monaco-add-feedback-button {
cursor: pointer;

/*
* Below are cosmetic adjustments that center the button and prevent the icon from breaking out of its row.
*/
display: flex;
width: 19px;
height: 19px;
font-size: 18px;
align-items: center;
padding-left: 1px;
}

.monaco-diff-line-highlight {
background-color: var(--monaco-editor-diff-line-highlight);
}

.monaco-diff-margin-highlight {
background-color: var(--monaco-editor-diff-margin-highlight);
}
Loading

0 comments on commit 962b00a

Please sign in to comment.