MOBILE-3732 essay: Display plagiarism information

main
Dani Palou 2021-04-28 15:39:56 +02:00
parent 1abd630ffa
commit cda9e93255
4 changed files with 59 additions and 2 deletions

View File

@ -79,9 +79,18 @@
</ion-label> </ion-label>
</ion-item> </ion-item>
<!-- Answer plagiarism. -->
<ion-item class="ion-text-wrap" *ngIf="essayQuestion.answerPlagiarism">
<ion-label>
<core-format-text [component]="component" [componentId]="componentId" [text]="essayQuestion.answerPlagiarism"
[contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
</core-format-text>
</ion-label>
</ion-item>
<!-- List of attachments when reviewing. --> <!-- List of attachments when reviewing. -->
<core-files *ngIf="essayQuestion.attachments" [files]="essayQuestion.attachments" [component]="component" <core-files *ngIf="essayQuestion.attachments" [files]="essayQuestion.attachments" [component]="component"
[componentId]="componentId"> [componentId]="componentId" [extraHtml]="essayQuestion.attachmentsPlagiarisms">
</core-files> </core-files>
</ng-container> </ng-container>
</ion-list> </ion-list>

View File

@ -1,7 +1,7 @@
<ng-container *ngIf="showInline && contentText"> <ng-container *ngIf="showInline && contentText">
<core-format-text [text]="contentText" [filter]="false"></core-format-text> <core-format-text [text]="contentText" [filter]="false"></core-format-text>
</ng-container> </ng-container>
<ng-container *ngFor="let file of files"> <ng-container *ngFor="let file of files; let i = index">
<!-- Files already attached to the filearea. --> <!-- Files already attached to the filearea. -->
<core-file *ngIf="!file.name && !file.embedType" [file]="file" [component]="component" [componentId]="componentId" <core-file *ngIf="!file.name && !file.embedType" [file]="file" [component]="component" [componentId]="componentId"
[alwaysDownload]="alwaysDownload" [canDownload]="canDownload" [showSize]="showSize" [showTime]="showTime"> [alwaysDownload]="alwaysDownload" [canDownload]="canDownload" [showSize]="showSize" [showTime]="showTime">
@ -9,4 +9,11 @@
<!-- Files stored in offline to be sent later. --> <!-- Files stored in offline to be sent later. -->
<core-local-file *ngIf="file.name && !file.embedType" [file]="file"></core-local-file> <core-local-file *ngIf="file.name && !file.embedType" [file]="file"></core-local-file>
<ion-item class="ion-text-wrap" *ngIf="extraHtml && extraHtml[i]">
<ion-label>
<core-format-text [component]="component" [componentId]="componentId" [text]="extraHtml[i]">
</core-format-text>
</ion-label>
</ion-item>
</ng-container> </ng-container>

View File

@ -38,6 +38,7 @@ export class CoreFilesComponent implements OnInit, DoCheck {
@Input() showSize?: boolean | string = true; // Whether show filesize. @Input() showSize?: boolean | string = true; // Whether show filesize.
@Input() showTime?: boolean | string = true; // Whether show file time modified. @Input() showTime?: boolean | string = true; // Whether show file time modified.
@Input() showInline = false; // If true, it will reorder and try to show inline files first. @Input() showInline = false; // If true, it will reorder and try to show inline files first.
@Input() extraHtml?: string[]; // Extra HTML for each attachment. Each HTML should be at the same position as the attachment.
contentText?: string; contentText?: string;

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
import { Input, Output, EventEmitter, Component, Optional, Inject, ElementRef } from '@angular/core'; import { Input, Output, EventEmitter, Component, Optional, Inject, ElementRef } from '@angular/core';
import { CoreFileHelper } from '@services/file-helper';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
@ -274,6 +275,9 @@ export class CoreQuestionBaseComponent {
); );
} }
// Treat plagiarism.
this.handleEssayPlagiarism(questionEl);
return questionEl; return questionEl;
} }
@ -353,6 +357,40 @@ export class CoreQuestionBaseComponent {
return questionEl; return questionEl;
} }
/**
* Handle plagiarism in an essay question.
*
* @param questionEl Element with the question html.
*/
protected handleEssayPlagiarism(questionEl: HTMLElement): void {
const question = <AddonModQuizEssayQuestion> this.question!;
const answerPlagiarism = questionEl.querySelector<HTMLSpanElement>('.answer .core_plagiarism_links');
if (answerPlagiarism) {
question.answerPlagiarism = answerPlagiarism.innerHTML;
}
if (!question.attachments?.length) {
return;
}
const attachmentsPlagiarisms = questionEl.querySelectorAll<HTMLSpanElement>('.attachments .core_plagiarism_links');
question.attachmentsPlagiarisms = [];
Array.from(attachmentsPlagiarisms).forEach((plagiarism) => {
// Search the URL of the attachment it affects.
const attachmentUrl = plagiarism.parentElement?.querySelector('a')?.href;
if (!attachmentUrl) {
return;
}
const position = question.attachments!.findIndex((file) => CoreFileHelper.getFileUrl(file) == attachmentUrl);
if (position >= 0) {
question.attachmentsPlagiarisms![position] = plagiarism.innerHTML;
}
});
}
/** /**
* Initialize a question component that uses the original question text with some basic treatment. * Initialize a question component that uses the original question text with some basic treatment.
* *
@ -724,6 +762,8 @@ export type AddonModQuizEssayQuestion = AddonModQuizQuestionBasicData & {
attachmentsMaxFiles?: number; // Max number of attachments. attachmentsMaxFiles?: number; // Max number of attachments.
attachmentsAcceptedTypes?: string; // Attachments accepted file types. attachmentsAcceptedTypes?: string; // Attachments accepted file types.
attachmentsMaxBytes?: number; // Max bytes for attachments. attachmentsMaxBytes?: number; // Max bytes for attachments.
answerPlagiarism?: string; // Plagiarism HTML for the answer.
attachmentsPlagiarisms?: string[]; // Plagiarism HTML for each attachment.
}; };
/** /**