466 lines
29 KiB
HTML
466 lines
29 KiB
HTML
<core-loading [hideUntil]="loaded">
|
|
<div class="list-item-limited-width">
|
|
<!-- Time limit is over. -->
|
|
<ion-card *ngIf="timeLimitFinished && (canEdit || canSubmit)" class="core-danger-card">
|
|
<ion-item class="ion-text-wrap">
|
|
<ion-icon name="fas-triangle-exclamation" slot="start" aria-hidden="true"></ion-icon>
|
|
<ion-label>
|
|
<p>{{ 'addon.mod_assign.caneditsubmission' | translate }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
</ion-card>
|
|
|
|
<!-- User and status of the submission. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="!blindMarking && user" core-user-link [userId]="submitId" [courseId]="courseId"
|
|
[attr.aria-label]="user!.fullname">
|
|
<core-user-avatar [user]="user" slot="start" [linkProfile]="false"></core-user-avatar>
|
|
<ion-label>
|
|
<p class="item-heading">{{ user!.fullname }}</p>
|
|
<ng-container *ngTemplateOutlet="submissionStatus"></ng-container>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Status of the submission if user is blinded. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="blindMarking && !user">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.hiddenuser' | translate }} {{blindId}}</p>
|
|
<ng-container *ngTemplateOutlet="submissionStatus"></ng-container>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Status of the submission in the rest of cases. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="(blindMarking && user) || (!blindMarking && !user)">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.submissionstatus' | translate }}</p>
|
|
<ng-container *ngTemplateOutlet="submissionStatus"></ng-container>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Tabs: see the submission or grade it. -->
|
|
<core-tabs [hideUntil]="loaded" parentScrollable="true" (ionChange)="tabSelected($event)">
|
|
<!-- View the submission tab. -->
|
|
<core-tab [title]="'addon.mod_assign.submission' | translate" id="submission">
|
|
<ng-template>
|
|
<!-- Render some data about the submission. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="currentAttempt && !isGrading">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.attemptnumber' | translate }}</p>
|
|
<p *ngIf="assign!.maxattempts === unlimitedAttempts">
|
|
{{ 'addon.mod_assign.outof' | translate :
|
|
{'$a': {'current': currentAttempt, 'total': maxAttemptsText} } }}
|
|
</p>
|
|
<p *ngIf="assign!.maxattempts !== unlimitedAttempts">
|
|
{{ 'addon.mod_assign.outof' | translate :
|
|
{'$a': {'current': currentAttempt, 'total': assign!.maxattempts} } }}
|
|
</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Submission is locked. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="lastAttempt?.locked">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.submissionslocked' | translate }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Dates. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="showDates && fromDate && !isSubmittedForGrading">
|
|
<ion-label>
|
|
<p *ngIf="assign!.intro"
|
|
[innerHTML]="'addon.mod_assign.allowsubmissionsfromdatesummary' | translate: {'$a': fromDate}">
|
|
</p>
|
|
<p [innerHTML]="'addon.mod_assign.allowsubmissionsanddescriptionfromdatesummary' | translate: {'$a': fromDate}"
|
|
*ngIf="!assign!.intro">
|
|
</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<ion-item class="ion-text-wrap" *ngIf="showDates && assign!.duedate && !isSubmittedForGrading">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.duedate' | translate }}</p>
|
|
<p *ngIf="assign!.duedate">{{ assign!.duedate * 1000 | coreFormatDate }}</p>
|
|
<p *ngIf="!assign!.duedate">{{ 'addon.mod_assign.duedateno' | translate }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<ion-item class="ion-text-wrap" *ngIf="assign!.duedate && assign!.cutoffdate && isSubmittedForGrading">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.cutoffdate' | translate }}</p>
|
|
<p>{{ assign!.cutoffdate * 1000 | coreFormatDate }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<ion-item class="ion-text-wrap" *ngIf="assign!.duedate && lastAttempt?.extensionduedate && !isSubmittedForGrading">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.extensionduedate' | translate }}</p>
|
|
<p>{{ lastAttempt!.extensionduedate * 1000 | coreFormatDate }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Time remaining. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="timeRemaining || timeLimitEndTime > 0" [ngClass]="[timeRemainingClass]">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.timeremaining' | translate }}</p>
|
|
<p *ngIf="!timeLimitEndTime" [innerHTML]="timeRemaining"></p>
|
|
<core-timer *ngIf="timeLimitEndTime > 0" [endTime]="timeLimitEndTime" mode="basic" timeUpText="00:00:00"
|
|
[timeLeftClassThreshold]="-1" [underTimeClassThresholds]="[300, 900]" (finished)="timeUp()">
|
|
</core-timer>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Time limit. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="assign && assign.timelimit">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.timelimit' | translate }}</p>
|
|
<p>{{ assign.timelimit | coreDuration }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Editing status. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="lastAttempt && isSubmittedForGrading && lastAttempt!.caneditowner !== undefined"
|
|
[ngClass]="{submissioneditable: lastAttempt!.caneditowner, submissionnoteditable: !lastAttempt!.caneditowner}">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.editingstatus' | translate }}</p>
|
|
<p *ngIf="lastAttempt!.caneditowner">{{ 'addon.mod_assign.submissioneditable' | translate }}</p>
|
|
<p *ngIf="!lastAttempt!.caneditowner">{{ 'addon.mod_assign.submissionnoteditable' | translate }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Last modified. -->
|
|
<ion-item class="ion-text-wrap"
|
|
*ngIf="userSubmission && userSubmission!.status !== statusNew && userSubmission!.timemodified">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.timemodified' | translate }}</p>
|
|
<p>{{ userSubmission!.timemodified * 1000 | coreFormatDate }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<addon-mod-assign-submission-plugin *ngFor="let plugin of submissionPlugins" [assign]="assign"
|
|
[submission]="userSubmission" [plugin]="plugin">
|
|
</addon-mod-assign-submission-plugin>
|
|
|
|
<!-- Team members that need to submit it too. -->
|
|
<ion-item-divider class="ion-text-wrap" *ngIf="membersToSubmit && membersToSubmit.length > 0">
|
|
<ion-label>
|
|
<h2>{{ 'addon.mod_assign.userswhoneedtosubmit' | translate: {$a: ''} }}</h2>
|
|
</ion-label>
|
|
</ion-item-divider>
|
|
<ng-container *ngIf="membersToSubmit && membersToSubmit.length > 0 && !blindMarking">
|
|
<ng-container *ngFor="let user of membersToSubmit">
|
|
<ion-item class="ion-text-wrap" core-user-link [userId]="user.id" [courseId]="courseId"
|
|
[attr.aria-label]="user.fullname">
|
|
<core-user-avatar [user]="user" slot="start" [linkProfile]="false"></core-user-avatar>
|
|
<ion-label>
|
|
<p class="item-heading">{{ user.fullname }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
</ng-container>
|
|
</ng-container>
|
|
<ng-container *ngIf="membersToSubmit && membersToSubmit.length > 0 && blindMarking">
|
|
<ng-container *ngFor="let blindId of membersToSubmitBlind">
|
|
<ion-item class="ion-text-wrap">
|
|
<ion-label>{{ 'addon.mod_assign.hiddenuser' | translate }} {{ blindId }}</ion-label>
|
|
</ion-item>
|
|
</ng-container>
|
|
</ng-container>
|
|
|
|
<!-- Add or edit submission. -->
|
|
<div collapsible-footer *ngIf="loaded && !isSubmittedForGrading" [hidden]="selectedTab !== 'submission'" slot="fixed">
|
|
<div class="list-item-limited-width" *ngIf="canEdit || canSubmit">
|
|
<ng-container *ngIf="canEdit">
|
|
<ng-container *ngIf=" !unsupportedEditPlugins.length && !showErrorStatementEdit">
|
|
<!-- If has offline data, show edit. -->
|
|
<ion-button expand="block" class="ion-text-wrap" *ngIf="hasOffline" (click)="goToEdit()">
|
|
{{ 'addon.mod_assign.editsubmission' | translate }}
|
|
</ion-button>
|
|
<!-- If no submission or is new, show add submission. -->
|
|
<ion-button expand="block" class="ion-text-wrap" (click)="goToEdit()" *ngIf="!hasOffline &&
|
|
(!userSubmission || !userSubmission!.status || userSubmission!.status === statusNew)">
|
|
<ng-container *ngIf="!assign?.timelimit || userSubmission?.timestarted">
|
|
{{ 'addon.mod_assign.addsubmission' | translate }}
|
|
</ng-container>
|
|
<ng-container *ngIf="assign?.timelimit && (!userSubmission || !userSubmission.timestarted)">
|
|
{{ 'addon.mod_assign.beginassignment' | translate }}
|
|
</ng-container>
|
|
</ion-button>
|
|
<!-- If reopened, show addfromprevious and addnewattempt. -->
|
|
<ng-container *ngIf="!hasOffline && userSubmission?.status === statusReopened">
|
|
<ion-button *ngIf="!isPreviousAttemptEmpty" expand="block" class="ion-text-wrap"
|
|
(click)="copyPrevious()">
|
|
{{ 'addon.mod_assign.addnewattemptfromprevious' | translate }}
|
|
</ion-button>
|
|
<ion-button expand="block" class="ion-text-wrap" (click)="goToEdit()">
|
|
{{ 'addon.mod_assign.addnewattempt' | translate }}
|
|
</ion-button>
|
|
</ng-container>
|
|
<!-- Else show editsubmission. -->
|
|
<ion-button expand="block" class="ion-text-wrap" *ngIf="!hasOffline && userSubmission &&
|
|
userSubmission!.status && userSubmission!.status !== statusNew &&
|
|
userSubmission!.status !== statusReopened" (click)="goToEdit()">
|
|
{{ 'addon.mod_assign.editsubmission' | translate }}
|
|
</ion-button>
|
|
</ng-container>
|
|
<ion-item class="core-danger-item ion-text-wrap"
|
|
*ngIf="(unsupportedEditPlugins.length && !showErrorStatementEdit)|| showErrorStatementEdit">
|
|
<ion-label>
|
|
<ng-container
|
|
*ngIf="unsupportedEditPlugins && unsupportedEditPlugins.length && !showErrorStatementEdit">
|
|
<p class="ion-padding-horizontal">
|
|
{{ 'addon.mod_assign.erroreditpluginsnotsupported' | translate }}</p>
|
|
<ul>
|
|
<li *ngFor="let name of unsupportedEditPlugins">{{ name }}</li>
|
|
</ul>
|
|
<ion-button expand="block" *ngIf="submissionUrl" [href]="submissionUrl" core-link
|
|
[showBrowserWarning]="false">
|
|
{{ 'core.openinbrowser' | translate }}
|
|
<ion-icon name="fas-up-right-from-square" slot="end" aria-hidden="true"></ion-icon>
|
|
</ion-button>
|
|
|
|
</ng-container>
|
|
<ng-container *ngIf="showErrorStatementEdit">
|
|
<p>{{ 'addon.mod_assign.cannoteditduetostatementsubmission' | translate }}</p>
|
|
</ng-container>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
</ng-container>
|
|
|
|
<!-- Submit for grading form. -->
|
|
<ng-container *ngIf="canSubmit">
|
|
<ion-item class="ion-text-wrap" *ngIf="submissionStatement">
|
|
<ion-label>
|
|
<core-format-text [text]="submissionStatement" [filter]="false"></core-format-text>
|
|
</ion-label>
|
|
<ion-checkbox slot="end" name="submissionstatement" [(ngModel)]="acceptStatement">
|
|
</ion-checkbox>
|
|
</ion-item>
|
|
<!-- Submit button. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="!showErrorStatementSubmit">
|
|
<ion-label>
|
|
<ion-button expand="block" class="ion-text-wrap" (click)="submitForGrading(acceptStatement)">
|
|
{{ 'addon.mod_assign.submitassignment' | translate }}
|
|
</ion-button>
|
|
<p>{{ 'addon.mod_assign.submitassignment_help' | translate }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
<!-- Error because we lack submissions statement. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="showErrorStatementSubmit">
|
|
<ion-label>
|
|
<p class="core-danger-item">
|
|
{{ 'addon.mod_assign.cannotsubmitduetostatementsubmission' | translate }}
|
|
</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
</ng-container>
|
|
</div>
|
|
<core-course-module-navigation [courseId]="courseId" [currentModuleId]="moduleId">
|
|
</core-course-module-navigation>
|
|
</div>
|
|
</ng-template>
|
|
</core-tab>
|
|
|
|
<!-- Grade the submission tab. -->
|
|
<core-tab [title]="'addon.mod_assign.grade' | translate" *ngIf="feedback || isGrading" id="grade">
|
|
<ng-template>
|
|
<!-- Current grade if method is advanced. -->
|
|
<ion-item class="ion-text-wrap core-grading-summary"
|
|
*ngIf="feedback?.gradefordisplay && (!isGrading || grade.method !== 'simple')">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.currentgrade' | translate }}</p>
|
|
<p>
|
|
<core-format-text [text]="feedback!.gradefordisplay" [filter]="false"></core-format-text>
|
|
</p>
|
|
</ion-label>
|
|
<ion-button slot="end" *ngIf="feedback!.advancedgrade" (click)="showAdvancedGrade()"
|
|
[attr.aria-label]="'core.showadvanced' |translate">
|
|
<ion-icon name="fas-magnifying-glass" slot="icon-only" aria-hidden="true"></ion-icon>
|
|
</ion-button>
|
|
</ion-item>
|
|
|
|
<ng-container *ngIf="isGrading">
|
|
<!-- Numeric grade.
|
|
Use a text input because otherwise we cannot readthe value if it has an invalid character. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="grade.method === 'simple' && !grade.scale">
|
|
<ion-label position="stacked">
|
|
<p class="item-heading">{{ 'addon.mod_assign.gradeoutof' | translate: {$a: gradeInfo!.grade} }}</p>
|
|
</ion-label>
|
|
<ion-input *ngIf="!grade.disabled" type="text" [(ngModel)]="grade.grade" min="0" [max]="gradeInfo!.grade"
|
|
[lang]="grade.lang">
|
|
</ion-input>
|
|
<p *ngIf="grade.disabled">{{ 'addon.mod_assign.gradelocked' | translate }}</p>
|
|
</ion-item>
|
|
|
|
<!-- Grade using a scale. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="grade.method === 'simple' && grade.scale">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.grade' | translate }}</p>
|
|
</ion-label>
|
|
<ion-select [(ngModel)]="grade.grade" interface="action-sheet" [disabled]="grade.disabled"
|
|
[cancelText]="'core.cancel' | translate"
|
|
[interfaceOptions]="{header: 'addon.mod_assign.grade' | translate}">
|
|
<ion-select-option *ngFor="let grade of grade.scale" [value]="grade.value">
|
|
{{grade.label}}
|
|
</ion-select-option>
|
|
</ion-select>
|
|
</ion-item>
|
|
|
|
<!-- Outcomes. -->
|
|
<ion-item class="ion-text-wrap" *ngFor="let outcome of gradeInfo!.outcomes">
|
|
<ion-label>
|
|
<p class="item-heading">{{ outcome.name }}</p>
|
|
</ion-label>
|
|
<ion-select *ngIf="canSaveGrades && outcome.itemNumber" [(ngModel)]="outcome.selectedId"
|
|
interface="action-sheet" [disabled]="gradeInfo!.disabled" [cancelText]="'core.cancel' | translate"
|
|
[interfaceOptions]="{header: outcome.name }">
|
|
<ion-select-option *ngFor="let grade of outcome.options" [value]="grade.value">
|
|
{{grade.label}}
|
|
</ion-select-option>
|
|
</ion-select>
|
|
<p *ngIf="!canSaveGrades || !outcome.itemNumber">{{ outcome.selected }}</p>
|
|
</ion-item>
|
|
|
|
<!-- Assign grade if it wasn't released to gradebook. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="gradeInfo && grade.unreleasedGrade !== undefined">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.currentassigngrade' | translate }}</p>
|
|
<p *ngIf="grade.method !== 'simple' || !grade.scale">{{ grade.unreleasedGrade}} / {{ gradeInfo.grade }}</p>
|
|
<p *ngIf="grade.method === 'simple' && grade.scale">{{ grade.unreleasedGrade }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Gradebook grade for simple grading. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="grade.method === 'simple'">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.currentgrade' | translate }}</p>
|
|
<p *ngIf="grade.gradebookGrade && !grade.scale">
|
|
{{ grade.gradebookGrade }}
|
|
</p>
|
|
<p *ngIf="grade.gradebookGrade && grade.scale">
|
|
{{ grade.scale[grade.gradebookGrade].label }}
|
|
</p>
|
|
<p *ngIf="!grade.gradebookGrade">-</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
</ng-container>
|
|
|
|
<ng-container *ngIf="feedback">
|
|
<addon-mod-assign-feedback-plugin *ngFor="let plugin of feedback.plugins" [assign]="assign"
|
|
[submission]="userSubmission" [userId]="submitId" [plugin]="plugin" [canEdit]="canSaveGrades">
|
|
</addon-mod-assign-feedback-plugin>
|
|
</ng-container>
|
|
|
|
<!-- Workflow status. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="workflowStatusTranslationId">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.markingworkflowstate' | translate }}</p>
|
|
<p>{{ workflowStatusTranslationId | translate }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!--- Apply grade to all team members. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="assign!.teamsubmission && canSaveGrades">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.groupsubmissionsettings' | translate }}</p>
|
|
<p>{{ 'addon.mod_assign.applytoteam' | translate }}</p>
|
|
</ion-label>
|
|
<ion-toggle [(ngModel)]="grade.applyToAll" slot="end"></ion-toggle>
|
|
</ion-item>
|
|
|
|
<!-- Attempt status. -->
|
|
<ng-container *ngIf="isGrading && assign!.attemptreopenmethod !== attemptReopenMethodNone">
|
|
<ion-item class="ion-text-wrap">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.attemptsettings' | translate }}</p>
|
|
<p *ngIf="assign!.maxattempts === unlimitedAttempts">
|
|
{{ 'addon.mod_assign.outof' | translate :
|
|
{'$a': {'current': currentAttempt, 'total': maxAttemptsText} } }}
|
|
</p>
|
|
<p *ngIf="assign!.maxattempts !== unlimitedAttempts">
|
|
{{ 'addon.mod_assign.outof' | translate :
|
|
{'$a': {'current': currentAttempt, 'total': assign!.maxattempts} } }}
|
|
</p>
|
|
<p>
|
|
{{ 'addon.mod_assign.attemptreopenmethod' | translate }}:
|
|
{{ 'addon.mod_assign.attemptreopenmethod_' + assign!.attemptreopenmethod | translate }}
|
|
</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
<ion-item *ngIf="canSaveGrades && allowAddAttempt">
|
|
<ion-label>{{ 'addon.mod_assign.addattempt' | translate }}</ion-label>
|
|
<ion-toggle [(ngModel)]="grade.addAttempt" slot="end"></ion-toggle>
|
|
</ion-item>
|
|
</ng-container>
|
|
|
|
<!-- Data about the grader (teacher who graded). -->
|
|
<ion-item class="ion-text-wrap" *ngIf="grader" core-user-link [userId]="grader!.id" [courseId]="courseId"
|
|
[attr.aria-label]="grader!.fullname" [detail]="true">
|
|
<core-user-avatar [user]="grader" slot="start" [linkProfile]="false"></core-user-avatar>
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.gradedby' | translate }}</p>
|
|
<p class="item-heading">{{ grader!.fullname }}</p>
|
|
<p *ngIf="feedback!.gradeddate">{{ feedback!.gradeddate * 1000 | coreFormatDate }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Grader is hidden, display only the grade date. -->
|
|
<ion-item class="ion-text-wrap" *ngIf="!grader && feedback?.gradeddate">
|
|
<ion-label>
|
|
<p class="item-heading">{{ 'addon.mod_assign.gradedon' | translate }}</p>
|
|
<p>{{ feedback!.gradeddate * 1000 | coreFormatDate }}</p>
|
|
</ion-label>
|
|
</ion-item>
|
|
|
|
<!-- Warning message if cannot save grades. -->
|
|
<ion-card *ngIf="isGrading && !canSaveGrades" class="core-warning-card">
|
|
<ion-item>
|
|
<ion-icon name="fas-triangle-exclamation" slot="start" aria-hidden="true"></ion-icon>
|
|
<ion-label>
|
|
<p>{{ 'addon.mod_assign.cannotgradefromapp' | translate }}</p>
|
|
<ion-button expand="block" *ngIf="gradeUrl" [href]="gradeUrl" core-link [showBrowserWarning]="false">
|
|
{{ 'core.openinbrowser' | translate }}
|
|
<ion-icon name="fas-up-right-from-square" slot="end" aria-hidden="true"></ion-icon>
|
|
</ion-button>
|
|
</ion-label>
|
|
</ion-item>
|
|
</ion-card>
|
|
</ng-template>
|
|
</core-tab>
|
|
</core-tabs>
|
|
</div>
|
|
</core-loading>
|
|
|
|
<!-- Template to render some data regarding the submission status. -->
|
|
<ng-template #submissionStatus>
|
|
<ng-container *ngIf="assign && assign!.teamsubmission && lastAttempt">
|
|
<p *ngIf="lastAttempt.submissiongroup && lastAttempt.submissiongroupname" class="core-groupname">
|
|
<core-format-text [text]="lastAttempt.submissiongroupname" contextLevel="course" [contextInstanceId]="courseId"
|
|
[wsNotFiltered]="true">
|
|
</core-format-text>
|
|
</p>
|
|
<ng-container *ngIf="assign!.preventsubmissionnotingroup &&
|
|
!lastAttempt!.submissiongroup &&
|
|
(!lastAttempt!.usergroups || lastAttempt!.usergroups.length <= 0)">
|
|
<p class="text-danger"><strong>{{ 'addon.mod_assign.noteam' | translate }}</strong></p>
|
|
<p class="text-danger">{{ 'addon.mod_assign.noteam_desc' | translate }}</p>
|
|
</ng-container>
|
|
<ng-container *ngIf="assign!.preventsubmissionnotingroup &&
|
|
!lastAttempt!.submissiongroup &&
|
|
lastAttempt!.usergroups &&
|
|
lastAttempt!.usergroups.length > 1">
|
|
<p class="text-danger"><strong>{{ 'addon.mod_assign.multipleteams' | translate }}</strong></p>
|
|
<p class="text-danger">{{ 'addon.mod_assign.multipleteams_desc' | translate }}</p>
|
|
</ng-container>
|
|
<p *ngIf="!assign!.preventsubmissionnotingroup && !lastAttempt!.submissiongroup">
|
|
{{ 'addon.mod_assign.defaultteam' | translate }}
|
|
</p>
|
|
</ng-container>
|
|
<p>
|
|
<ion-badge *ngIf="statusTranslated" [color]="statusColor" class="ion-text-wrap ion-text-start">
|
|
{{ statusTranslated }}
|
|
</ion-badge>
|
|
<ion-badge class="ion-text-wrap ion-text-start" *ngIf="gradingStatusTranslationId" [color]="gradingColor">
|
|
{{ gradingStatusTranslationId | translate }}
|
|
</ion-badge>
|
|
</p>
|
|
</ng-template>
|