From 9b93a0450cbcd0f1133deffcf33add22c8b852d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?=
Date: Fri, 7 Jan 2022 13:34:19 +0100
Subject: [PATCH 1/6] MOBILE-3787 assign: Fix non-null checks
---
.../mod/assign/components/index/index.ts | 54 +++++++++++--------
.../components/submission/submission.ts | 8 +--
2 files changed, 35 insertions(+), 27 deletions(-)
diff --git a/src/addons/mod/assign/components/index/index.ts b/src/addons/mod/assign/components/index/index.ts
index 0aa2a9a8e..84e64cb19 100644
--- a/src/addons/mod/assign/components/index/index.ts
+++ b/src/addons/mod/assign/components/index/index.ts
@@ -79,8 +79,8 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
submissionStatusDraft = AddonModAssignProvider.SUBMISSION_STATUS_DRAFT;
needGrading = AddonModAssignProvider.NEED_GRADING;
- protected currentUserId?: number; // Current user ID.
- protected currentSite?: CoreSite; // Current user ID.
+ protected currentUserId!: number; // Current user ID.
+ protected currentSite!: CoreSite; // Current site.
protected syncEventName = AddonModAssignSyncProvider.AUTO_SYNCED;
// Observers.
@@ -93,6 +93,9 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
@Optional() courseContentsPage?: CoreCourseContentsPage,
) {
super('AddonModLessonIndexComponent', content, courseContentsPage);
+
+ this.currentSite = CoreSites.getRequiredCurrentSite();
+ this.currentUserId = this.currentSite.getUserId();
}
/**
@@ -101,9 +104,6 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
async ngOnInit(): Promise {
super.ngOnInit();
- this.currentUserId = CoreSites.getCurrentSiteUserId();
- this.currentSite = CoreSites.getCurrentSite();
-
// Listen to events.
this.savedObserver = CoreEvents.on(
AddonModAssignProvider.SUBMISSION_SAVED_EVENT,
@@ -139,8 +139,12 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
await this.loadContent(false, true);
+ if (!this.assign) {
+ return;
+ }
+
try {
- await AddonModAssign.logView(this.assign!.id, this.assign!.name);
+ await AddonModAssign.logView(this.assign.id, this.assign.name);
CoreCourse.checkModuleCompletion(this.courseId, this.module.completiondata);
} catch {
// Ignore errors. Just don't check Module completion.
@@ -148,10 +152,10 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
if (this.canViewAllSubmissions) {
// User can see all submissions, log grading view.
- CoreUtils.ignoreErrors(AddonModAssign.logGradingView(this.assign!.id, this.assign!.name));
+ CoreUtils.ignoreErrors(AddonModAssign.logGradingView(this.assign.id, this.assign.name));
} else if (this.canViewOwnSubmission) {
// User can only see their own submission, log view the user submission.
- CoreUtils.ignoreErrors(AddonModAssign.logSubmissionView(this.assign!.id, this.assign!.name));
+ CoreUtils.ignoreErrors(AddonModAssign.logSubmissionView(this.assign.id, this.assign.name));
}
}
@@ -266,7 +270,11 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
async setGroup(groupId = 0): Promise {
this.group = groupId;
- const submissionStatus = await AddonModAssign.getSubmissionStatus(this.assign!.id, {
+ if (!this.assign) {
+ return;
+ }
+
+ const submissionStatus = await AddonModAssign.getSubmissionStatus(this.assign.id, {
groupId: this.group,
cmId: this.module.id,
});
@@ -278,10 +286,10 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
return;
}
- if (this.summary?.warnofungroupedusers === true) {
+ if (this.summary.warnofungroupedusers === true) {
this.summary.warnofungroupedusers = 'ungroupedusers';
} else {
- switch (this.summary?.warnofungroupedusers) {
+ switch (this.summary.warnofungroupedusers) {
case AddonModAssignProvider.WARN_GROUPS_REQUIRED:
this.summary.warnofungroupedusers = 'ungroupedusers';
break;
@@ -386,16 +394,16 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
* @return True if refresh is needed, false otherwise.
*/
protected isRefreshSyncNeeded(syncEventData: AddonModAssignAutoSyncData): boolean {
- if (this.assign && syncEventData.assignId == this.assign.id) {
- if (syncEventData.warnings && syncEventData.warnings.length) {
- // Show warnings.
- CoreDomUtils.showErrorModal(syncEventData.warnings[0]);
- }
-
- return true;
+ if (!this.assign || syncEventData.assignId != this.assign.id) {
+ return false;
}
- return false;
+ if (syncEventData.warnings && syncEventData.warnings.length) {
+ // Show warnings.
+ CoreDomUtils.showErrorModal(syncEventData.warnings[0]);
+ }
+
+ return true;
}
/**
@@ -403,8 +411,12 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
*
* @return Promise resolved when done.
*/
- protected sync(): Promise {
- return AddonModAssignSync.syncAssign(this.assign!.id);
+ protected async sync(): Promise {
+ if (!this.assign) {
+ return;
+ }
+
+ await AddonModAssignSync.syncAssign(this.assign.id);
}
/**
diff --git a/src/addons/mod/assign/components/submission/submission.ts b/src/addons/mod/assign/components/submission/submission.ts
index 5b7b69785..290feb84e 100644
--- a/src/addons/mod/assign/components/submission/submission.ts
+++ b/src/addons/mod/assign/components/submission/submission.ts
@@ -612,11 +612,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
// If we have data about the grader, get its profile.
if (feedback.grade && feedback.grade.grader > 0) {
- try {
- this.grader = await CoreUser.getProfile(feedback.grade.grader, this.courseId);
- } catch {
- // Ignore errors.
- }
+ this.grader = await CoreUtils.ignoreErrors(CoreUser.getProfile(feedback.grade.grader, this.courseId));
} else {
delete this.grader;
}
@@ -633,7 +629,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
if (feedback.grade && feedback.grade.grade && !this.grade.grade) {
const parsedGrade = parseFloat(feedback.grade.grade);
- this.grade!.grade = parsedGrade >= 0 ? parsedGrade : undefined;
+ this.grade.grade = parsedGrade >= 0 ? parsedGrade : undefined;
this.grade.gradebookGrade = CoreUtils.formatFloat(this.grade.grade);
this.originalGrades.grade = this.grade.grade;
}
From 59e1a4fcf549adfa425ab17b09594c947a1e454d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?=
Date: Fri, 7 Jan 2022 16:49:04 +0100
Subject: [PATCH 2/6] MOBILE-3787 assign: Always show submission status
---
.../mod/assign/classes/submissions-source.ts | 11 +++--------
.../mod/assign/components/index/index.ts | 2 +-
.../pages/submission-list/submission-list.html | 18 ++++++++++--------
3 files changed, 14 insertions(+), 17 deletions(-)
diff --git a/src/addons/mod/assign/classes/submissions-source.ts b/src/addons/mod/assign/classes/submissions-source.ts
index a1c36e70c..4faec578d 100644
--- a/src/addons/mod/assign/classes/submissions-source.ts
+++ b/src/addons/mod/assign/classes/submissions-source.ts
@@ -211,14 +211,9 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
submission.gradingstatus,
);
- // Show submission status if not submitted for grading.
- if (submission.statusColor != 'success' || !submission.gradingstatus) {
- submission.statusTranslated = Translate.instant(
- 'addon.mod_assign.submissionstatus_' + submission.status,
- );
- } else {
- submission.statusTranslated = '';
- }
+ submission.statusTranslated = Translate.instant(
+ 'addon.mod_assign.submissionstatus_' + submission.status,
+ );
if (notSynced) {
submission.gradingStatusTranslationId = 'addon.mod_assign.gradenotsynced';
diff --git a/src/addons/mod/assign/components/index/index.ts b/src/addons/mod/assign/components/index/index.ts
index 84e64cb19..72b161007 100644
--- a/src/addons/mod/assign/components/index/index.ts
+++ b/src/addons/mod/assign/components/index/index.ts
@@ -302,7 +302,7 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
}
}
- this.needsGradingAvailable = (submissionStatus.gradingsummary?.submissionsneedgradingcount || 0) > 0;
+ this.needsGradingAvailable = this.summary.submissionsneedgradingcount > 0;
}
/**
diff --git a/src/addons/mod/assign/pages/submission-list/submission-list.html b/src/addons/mod/assign/pages/submission-list/submission-list.html
index 0a6635371..40ad93441 100644
--- a/src/addons/mod/assign/pages/submission-list/submission-list.html
+++ b/src/addons/mod/assign/pages/submission-list/submission-list.html
@@ -63,14 +63,16 @@
{{ 'addon.mod_assign.defaultteam' | translate }}
-
- {{ submission.statusTranslated }}
-
-
- {{ submission.gradingStatusTranslationId | translate }}
-
+
+
+ {{ submission.statusTranslated }}
+
+
+
+
+ {{ submission.gradingStatusTranslationId | translate }}
+
+
From 03ccd026361315293d0ce2adbee2a760c4967f14 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?=
Date: Thu, 13 Jan 2022 08:54:33 +0100
Subject: [PATCH 3/6] MOBILE-3787 assign: Fix submission and grading status on
groups
---
.../mod/assign/classes/submissions-source.ts | 108 +++++++++---------
.../mod/assign/services/assign-helper.ts | 77 ++++++-------
2 files changed, 83 insertions(+), 102 deletions(-)
diff --git a/src/addons/mod/assign/classes/submissions-source.ts b/src/addons/mod/assign/classes/submissions-source.ts
index 4faec578d..fba320993 100644
--- a/src/addons/mod/assign/classes/submissions-source.ts
+++ b/src/addons/mod/assign/classes/submissions-source.ts
@@ -157,7 +157,7 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
}
// Fetch submissions and grades.
- const submissions =
+ let submissions =
await AddonModAssignHelper.getSubmissionsUserData(
assign,
this.submissionsData.submissions,
@@ -172,67 +172,61 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
const getNeedGrading = this.SELECTED_STATUS == AddonModAssignProvider.NEED_GRADING;
const searchStatus = getNeedGrading ? AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED : this.SELECTED_STATUS;
- const promises: Promise[] = [];
const showSubmissions: AddonModAssignSubmissionForList[] = [];
- submissions.forEach((submission: AddonModAssignSubmissionForList) => {
- if (!searchStatus || searchStatus == submission.status) {
- promises.push(
- CoreUtils.ignoreErrors(
- AddonModAssignOffline.getSubmissionGrade(assign.id, submission.userid),
- ).then(async (data) => {
- if (getNeedGrading) {
- // Only show the submissions that need to be graded.
- const add = await AddonModAssign.needsSubmissionToBeGraded(submission, assign.id);
+ if (searchStatus) {
+ submissions = submissions.filter((submission: AddonModAssignSubmissionForList) => searchStatus == submission.status);
+ }
- if (!add) {
- return;
- }
- }
+ const promises: Promise[] = submissions.map(async (submission: AddonModAssignSubmissionForList) => {
+ const gradeData = await CoreUtils.ignoreErrors(AddonModAssignOffline.getSubmissionGrade(assign.id, submission.userid));
+ if (getNeedGrading) {
+ // Only show the submissions that need to be graded.
+ const add = await AddonModAssign.needsSubmissionToBeGraded(submission, assign.id);
- // Load offline grades.
- const notSynced = !!data && submission.timemodified < data.timemodified;
-
- if (submission.gradingstatus == 'graded' && !assign.markingworkflow) {
- // Get the last grade of the submission.
- const grade = grades
- .filter((grade) => grade.userid == submission.userid)
- .reduce(
- (a, b) => (a && a.timemodified > b.timemodified ? a : b),
- undefined,
- );
-
- if (grade && grade.timemodified < submission.timemodified) {
- submission.gradingstatus = AddonModAssignProvider.GRADED_FOLLOWUP_SUBMIT;
- }
- }
- submission.statusColor = AddonModAssign.getSubmissionStatusColor(submission.status);
- submission.gradingColor = AddonModAssign.getSubmissionGradingStatusColor(
- submission.gradingstatus,
- );
-
- submission.statusTranslated = Translate.instant(
- 'addon.mod_assign.submissionstatus_' + submission.status,
- );
-
- if (notSynced) {
- submission.gradingStatusTranslationId = 'addon.mod_assign.gradenotsynced';
- submission.gradingColor = '';
- } else if (submission.statusColor != 'danger' || submission.gradingColor != 'danger') {
- // Show grading status if one of the statuses is not done.
- submission.gradingStatusTranslationId = AddonModAssign.getSubmissionGradingStatusTranslationId(
- submission.gradingstatus,
- );
- } else {
- submission.gradingStatusTranslationId = '';
- }
-
- showSubmissions.push(submission);
-
- return;
- }),
- );
+ if (!add) {
+ return;
+ }
}
+
+ // Load offline grades.
+ const notSynced = !!gradeData && submission.timemodified < gradeData.timemodified;
+
+ if (submission.gradingstatus == 'graded' && !assign.markingworkflow) {
+ // Get the last grade of the submission.
+ const grade = grades
+ .filter((grade) => grade.userid == submission.userid)
+ .reduce(
+ (a, b) => (a && a.timemodified > b.timemodified ? a : b),
+ undefined,
+ );
+
+ if (grade && grade.timemodified < submission.timemodified) {
+ submission.gradingstatus = AddonModAssignProvider.GRADED_FOLLOWUP_SUBMIT;
+ }
+ }
+ submission.statusColor = AddonModAssign.getSubmissionStatusColor(submission.status);
+ submission.gradingColor = AddonModAssign.getSubmissionGradingStatusColor(
+ submission.gradingstatus,
+ );
+
+ submission.statusTranslated = Translate.instant(
+ 'addon.mod_assign.submissionstatus_' + submission.status,
+ );
+
+ if (notSynced) {
+ submission.gradingStatusTranslationId = 'addon.mod_assign.gradenotsynced';
+ submission.gradingColor = '';
+ } else if (submission.statusColor != 'danger' || submission.gradingColor != 'danger') {
+ // Show grading status if one of the statuses is not done.
+ submission.gradingStatusTranslationId = AddonModAssign.getSubmissionGradingStatusTranslationId(
+ submission.gradingstatus,
+ );
+ } else {
+ submission.gradingStatusTranslationId = '';
+ }
+
+ showSubmissions.push(submission);
});
await Promise.all(promises);
diff --git a/src/addons/mod/assign/services/assign-helper.ts b/src/addons/mod/assign/services/assign-helper.ts
index 680bfbdaa..017e9a389 100644
--- a/src/addons/mod/assign/services/assign-helper.ts
+++ b/src/addons/mod/assign/services/assign-helper.ts
@@ -398,48 +398,34 @@ export class AddonModAssignHelperProvider {
groupId?: number,
options: CoreSitesCommonWSOptions = {},
): Promise {
- const parts = await this.getParticipants(assign, groupId, options);
+ const participants = await this.getParticipants(assign, groupId, options);
- const blind = assign.blindmarking && !assign.revealidentities;
- const result: AddonModAssignSubmissionFormatted[] = [];
- const participants: {[id: number]: AddonModAssignParticipant} = CoreUtils.arrayToObject(parts, 'id');
+ const blind = !!assign.blindmarking && !assign.revealidentities;
+ const teamsubmission = !!assign.teamsubmission;
- submissions.forEach((submission) => {
- submission.submitid = submission.userid && submission.userid > 0 ? submission.userid : submission.blindid;
- if (submission.submitid === undefined || submission.submitid <= 0) {
- return;
+ return participants.map((participant) => {
+ const groupId = participant.groupid ??
+ (participant.groups && participant.groups[0] ? participant.groups[0].id : 0);
+
+ const foundSubmission = submissions.find((submission) => {
+ if (teamsubmission) {
+ return submission.userid == 0 && submission.groupid == groupId;
+ }
+
+ const submitId = submission.userid && submission.userid > 0 ? submission.userid : submission.blindid;
+
+ return participant.id == submitId;
+ });
+
+ let submission: AddonModAssignSubmissionFormatted | undefined;
+ if (!foundSubmission) {
+ // Create submission if none.
+ submission = this.createEmptySubmission();
+ submission.groupid = groupId;
+ } else {
+ submission = Object.assign({}, foundSubmission);
}
- const participant = participants[submission.submitid];
- if (!participant) {
- // Avoid permission denied error. Participant not found on list.
- return;
- }
-
- delete participants[submission.submitid];
-
- if (!blind) {
- submission.userfullname = participant.fullname;
- submission.userprofileimageurl = participant.profileimageurl;
- }
-
- submission.manyGroups = !!participant.groups && participant.groups.length > 1;
- submission.noGroups = !!participant.groups && participant.groups.length == 0;
- if (participant.groupname) {
- submission.groupid = participant.groupid!;
- submission.groupname = participant.groupname;
- }
-
- // Add to the list.
- if (submission.userfullname || submission.blindid) {
- result.push(submission);
- }
- });
-
- // Create a submission for each participant left in the list (the participants already treated were removed).
- CoreUtils.objectToArray(participants).forEach((participant: AddonModAssignParticipant) => {
- const submission = this.createEmptySubmission();
-
submission.submitid = participant.id;
if (!blind) {
@@ -453,16 +439,16 @@ export class AddonModAssignHelperProvider {
submission.manyGroups = !!participant.groups && participant.groups.length > 1;
submission.noGroups = !!participant.groups && participant.groups.length == 0;
if (participant.groupname) {
- submission.groupid = participant.groupid!;
+ submission.groupid = participant.groupid;
submission.groupname = participant.groupname;
}
- submission.status = participant.submitted ? AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED :
- AddonModAssignProvider.SUBMISSION_STATUS_NEW;
- result.push(submission);
+ submission.status = submission.status ?? (participant.submitted ? AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED :
+ AddonModAssignProvider.SUBMISSION_STATUS_NEW);
+
+ return submission;
+
});
-
- return result;
}
/**
@@ -714,8 +700,9 @@ export const AddonModAssignHelper = makeSingleton(AddonModAssignHelperProvider);
* Assign submission with some calculated data.
*/
export type AddonModAssignSubmissionFormatted =
- Omit & {
+ Omit & {
userid?: number; // Student id.
+ groupid?: number; // Group id.
blindid?: number; // Calculated in the app. Blindid of the user that did the submission.
submitid?: number; // Calculated in the app. Userid or blindid of the user that did the submission.
userfullname?: string; // Calculated in the app. Full name of the user that did the submission.
From 7cdafca794eb8bf1741bf1d9989ad9a13adba647 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?=
Date: Thu, 13 Jan 2022 10:44:47 +0100
Subject: [PATCH 4/6] MOBILE-3787 assign: Add enums to different states
---
.../mod/assign/classes/submissions-source.ts | 36 ++++--
.../mod/assign/components/index/index.ts | 9 +-
.../components/submission/submission.ts | 47 +++----
.../submission-list/submission-list.page.ts | 10 +-
.../submission-review/submission-review.ts | 6 +-
.../mod/assign/services/assign-helper.ts | 9 +-
src/addons/mod/assign/services/assign.ts | 119 +++++++++++-------
src/core/singletons/colors.ts | 12 ++
8 files changed, 152 insertions(+), 96 deletions(-)
diff --git a/src/addons/mod/assign/classes/submissions-source.ts b/src/addons/mod/assign/classes/submissions-source.ts
index fba320993..4e3ee9953 100644
--- a/src/addons/mod/assign/classes/submissions-source.ts
+++ b/src/addons/mod/assign/classes/submissions-source.ts
@@ -18,13 +18,14 @@ import { CoreGroupInfo, CoreGroups } from '@services/groups';
import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils';
import { Translate } from '@singletons';
+import { CoreIonicColorNames } from '@singletons/colors';
import { CoreEvents } from '@singletons/events';
import {
AddonModAssign,
AddonModAssignAssign,
- AddonModAssignGrade,
- AddonModAssignProvider,
+ AddonModAssignGradingStates,
AddonModAssignSubmission,
+ AddonModAssignSubmissionStatusValues,
} from '../services/assign';
import { AddonModAssignHelper, AddonModAssignSubmissionFormatted } from '../services/assign-helper';
import { AddonModAssignOffline } from '../services/assign-offline';
@@ -38,15 +39,15 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
/**
* @inheritdoc
*/
- static getSourceId(courseId: number, moduleId: number, selectedStatus?: string): string {
- selectedStatus = selectedStatus ?? '__empty__';
+ static getSourceId(courseId: number, moduleId: number, selectedStatus?: AddonModAssignListFilterName): string {
+ const statusId = selectedStatus ?? '__empty__';
- return `submissions-${courseId}-${moduleId}-${selectedStatus}`;
+ return `submissions-${courseId}-${moduleId}-${statusId}`;
}
readonly COURSE_ID: number;
readonly MODULE_ID: number;
- readonly SELECTED_STATUS: string | undefined;
+ readonly SELECTED_STATUS: AddonModAssignListFilterName | undefined;
assign?: AddonModAssignAssign;
groupId = 0;
@@ -62,7 +63,7 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
canviewsubmissions: false,
};
- constructor(courseId: number, moduleId: number, selectedStatus?: string) {
+ constructor(courseId: number, moduleId: number, selectedStatus?: AddonModAssignListFilterName) {
super();
this.COURSE_ID = courseId;
@@ -169,8 +170,8 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
: [];
// Filter the submissions to get only the ones with the right status and add some extra data.
- const getNeedGrading = this.SELECTED_STATUS == AddonModAssignProvider.NEED_GRADING;
- const searchStatus = getNeedGrading ? AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED : this.SELECTED_STATUS;
+ const getNeedGrading = this.SELECTED_STATUS == AddonModAssignListFilterName.NEED_GRADING;
+ const searchStatus = getNeedGrading ? AddonModAssignSubmissionStatusValues.SUBMITTED : this.SELECTED_STATUS;
const showSubmissions: AddonModAssignSubmissionForList[] = [];
@@ -192,7 +193,7 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
// Load offline grades.
const notSynced = !!gradeData && submission.timemodified < gradeData.timemodified;
- if (submission.gradingstatus == 'graded' && !assign.markingworkflow) {
+ if (submission.gradingstatus == AddonModAssignGradingStates.GRADED && !assign.markingworkflow) {
// Get the last grade of the submission.
const grade = grades
.filter((grade) => grade.userid == submission.userid)
@@ -202,7 +203,7 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
);
if (grade && grade.timemodified < submission.timemodified) {
- submission.gradingstatus = AddonModAssignProvider.GRADED_FOLLOWUP_SUBMIT;
+ submission.gradingstatus = AddonModAssignGradingStates.GRADED_FOLLOWUP_SUBMIT;
}
}
submission.statusColor = AddonModAssign.getSubmissionStatusColor(submission.status);
@@ -217,7 +218,8 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
if (notSynced) {
submission.gradingStatusTranslationId = 'addon.mod_assign.gradenotsynced';
submission.gradingColor = '';
- } else if (submission.statusColor != 'danger' || submission.gradingColor != 'danger') {
+ } else if (submission.statusColor != CoreIonicColorNames.DANGER ||
+ submission.gradingColor != CoreIonicColorNames.DANGER) {
// Show grading status if one of the statuses is not done.
submission.gradingStatusTranslationId = AddonModAssign.getSubmissionGradingStatusTranslationId(
submission.gradingstatus,
@@ -245,3 +247,13 @@ export type AddonModAssignSubmissionForList = AddonModAssignSubmissionFormatted
statusTranslated?: string; // Calculated in the app. Translated text of the submission status.
gradingStatusTranslationId?: string; // Calculated in the app. Key of the text of the submission grading status.
};
+
+/**
+ * List filter by status name.
+ */
+export enum AddonModAssignListFilterName {
+ ALL = '',
+ NEED_GRADING = 'needgrading',
+ DRAFT = 'draft',
+ SUBMITTED = 'submitted',
+};
diff --git a/src/addons/mod/assign/components/index/index.ts b/src/addons/mod/assign/components/index/index.ts
index 72b161007..28827e331 100644
--- a/src/addons/mod/assign/components/index/index.ts
+++ b/src/addons/mod/assign/components/index/index.ts
@@ -28,6 +28,7 @@ import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils';
import { Translate } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
+import { AddonModAssignListFilterName } from '../../classes/submissions-source';
import {
AddonModAssign,
AddonModAssignAssign,
@@ -75,9 +76,9 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
};
// Status.
- submissionStatusSubmitted = AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED;
- submissionStatusDraft = AddonModAssignProvider.SUBMISSION_STATUS_DRAFT;
- needGrading = AddonModAssignProvider.NEED_GRADING;
+ submissionStatusSubmitted = AddonModAssignListFilterName.SUBMITTED;
+ submissionStatusDraft = AddonModAssignListFilterName.DRAFT;
+ needGrading = AddonModAssignListFilterName.NEED_GRADING;
protected currentUserId!: number; // Current user ID.
protected currentSite!: CoreSite; // Current site.
@@ -311,7 +312,7 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
* @param status Status to see.
* @param hasSubmissions If the status has any submission.
*/
- goToSubmissionList(status?: string, hasSubmissions = false): void {
+ goToSubmissionList(status?: AddonModAssignListFilterName, hasSubmissions = false): void {
if (status !== undefined && !hasSubmissions) {
return;
}
diff --git a/src/addons/mod/assign/components/submission/submission.ts b/src/addons/mod/assign/components/submission/submission.ts
index 290feb84e..da2154f88 100644
--- a/src/addons/mod/assign/components/submission/submission.ts
+++ b/src/addons/mod/assign/components/submission/submission.ts
@@ -25,6 +25,9 @@ import {
AddonModAssign,
AddonModAssignGetSubmissionStatusWSResponse,
AddonModAssignSavePluginData,
+ AddonModAssignGradingStates,
+ AddonModAssignSubmissionStatusValues,
+ AddonModAssignAttemptReopenMethodValues,
} from '../../services/assign';
import {
AddonModAssignAutoSyncData,
@@ -125,9 +128,9 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
showDates = false; // Whether to show some dates.
// Some constants.
- statusNew = AddonModAssignProvider.SUBMISSION_STATUS_NEW;
- statusReopened = AddonModAssignProvider.SUBMISSION_STATUS_REOPENED;
- attemptReopenMethodNone = AddonModAssignProvider.ATTEMPT_REOPEN_METHOD_NONE;
+ statusNew = AddonModAssignSubmissionStatusValues.NEW;
+ statusReopened = AddonModAssignSubmissionStatusValues.REOPENED;
+ attemptReopenMethodNone = AddonModAssignAttemptReopenMethodValues.NONE;
unlimitedAttempts = AddonModAssignProvider.UNLIMITED_ATTEMPTS;
protected siteId: string; // Current site ID.
@@ -214,7 +217,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
}
// Not submitted.
- if (!this.userSubmission || this.userSubmission.status != AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED) {
+ if (!this.userSubmission || this.userSubmission.status != AddonModAssignSubmissionStatusValues.SUBMITTED) {
if (response.lastattempt?.submissionsenabled || response.gradingsummary?.submissionsenabled) {
this.timeRemaining = Translate.instant(
@@ -651,7 +654,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
// Treat the grade info.
await this.treatGradeInfo();
- const isManual = this.assign!.attemptreopenmethod == AddonModAssignProvider.ATTEMPT_REOPEN_METHOD_MANUAL;
+ const isManual = this.assign!.attemptreopenmethod == AddonModAssignAttemptReopenMethodValues.MANUAL;
const isUnlimited = this.assign!.maxattempts == AddonModAssignProvider.UNLIMITED_ATTEMPTS;
const isLessThanMaxAttempts = !!this.userSubmission && (this.userSubmission.attemptnumber < (this.assign!.maxattempts - 1));
@@ -668,7 +671,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
if (this.lastAttempt?.gradingstatus == 'graded' && !this.assign!.markingworkflow && this.userSubmission && feedback) {
if (feedback.gradeddate < this.userSubmission.timemodified) {
- this.lastAttempt.gradingstatus = AddonModAssignProvider.GRADED_FOLLOWUP_SUBMIT;
+ this.lastAttempt.gradingstatus = AddonModAssignGradingStates.GRADED_FOLLOWUP_SUBMIT;
// Get grading text and color.
this.gradingStatusTranslationId = AddonModAssign.getSubmissionGradingStatusTranslationId(
@@ -749,43 +752,43 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
* @param status Submission status.
*/
protected setStatusNameAndClass(status: AddonModAssignGetSubmissionStatusWSResponse): void {
- const translateService = Translate.instance;
-
if (this.hasOffline || this.submittedOffline) {
// Offline data.
- this.statusTranslated = translateService.instant('core.notsent');
+ this.statusTranslated = Translate.instant('core.notsent');
this.statusColor = 'warning';
} else if (!this.assign!.teamsubmission) {
// Single submission.
if (this.userSubmission && this.userSubmission.status != this.statusNew) {
- this.statusTranslated = translateService.instant('addon.mod_assign.submissionstatus_' + this.userSubmission.status);
+ this.statusTranslated = Translate.instant('addon.mod_assign.submissionstatus_' + this.userSubmission.status);
this.statusColor = AddonModAssign.getSubmissionStatusColor(this.userSubmission.status);
} else {
if (!status.lastattempt?.submissionsenabled) {
- this.statusTranslated = translateService.instant('addon.mod_assign.noonlinesubmissions');
- this.statusColor = AddonModAssign.getSubmissionStatusColor('noonlinesubmissions');
+ this.statusTranslated = Translate.instant('addon.mod_assign.noonlinesubmissions');
+ this.statusColor =
+ AddonModAssign.getSubmissionStatusColor(AddonModAssignSubmissionStatusValues.NO_ONLINE_SUBMISSIONS);
} else {
- this.statusTranslated = translateService.instant('addon.mod_assign.noattempt');
- this.statusColor = AddonModAssign.getSubmissionStatusColor('noattempt');
+ this.statusTranslated = Translate.instant('addon.mod_assign.noattempt');
+ this.statusColor = AddonModAssign.getSubmissionStatusColor(AddonModAssignSubmissionStatusValues.NO_ATTEMPT);
}
}
} else {
// Team submission.
if (!status.lastattempt?.submissiongroup && this.assign!.preventsubmissionnotingroup) {
- this.statusTranslated = translateService.instant('addon.mod_assign.nosubmission');
- this.statusColor = AddonModAssign.getSubmissionStatusColor('nosubmission');
+ this.statusTranslated = Translate.instant('addon.mod_assign.nosubmission');
+ this.statusColor = AddonModAssign.getSubmissionStatusColor(AddonModAssignSubmissionStatusValues.NO_SUBMISSION);
} else if (this.userSubmission && this.userSubmission.status != this.statusNew) {
- this.statusTranslated = translateService.instant('addon.mod_assign.submissionstatus_' + this.userSubmission.status);
+ this.statusTranslated = Translate.instant('addon.mod_assign.submissionstatus_' + this.userSubmission.status);
this.statusColor = AddonModAssign.getSubmissionStatusColor(this.userSubmission.status);
} else {
if (!status.lastattempt?.submissionsenabled) {
- this.statusTranslated = translateService.instant('addon.mod_assign.noonlinesubmissions');
- this.statusColor = AddonModAssign.getSubmissionStatusColor('noonlinesubmissions');
+ this.statusTranslated = Translate.instant('addon.mod_assign.noonlinesubmissions');
+ this.statusColor =
+ AddonModAssign.getSubmissionStatusColor(AddonModAssignSubmissionStatusValues.NO_ONLINE_SUBMISSIONS);
} else {
- this.statusTranslated = translateService.instant('addon.mod_assign.nosubmission');
- this.statusColor = AddonModAssign.getSubmissionStatusColor('nosubmission');
+ this.statusTranslated = Translate.instant('addon.mod_assign.nosubmission');
+ this.statusColor = AddonModAssign.getSubmissionStatusColor(AddonModAssignSubmissionStatusValues.NO_SUBMISSION);
}
}
}
@@ -1180,7 +1183,7 @@ type AddonModAssignSubmissionGrade = {
grade?: number | string;
gradebookGrade?: string;
modified?: number;
- gradingStatus?: string;
+ gradingStatus?: AddonModAssignGradingStates;
addAttempt: boolean;
applyToAll: boolean;
scale?: CoreMenuItem[];
diff --git a/src/addons/mod/assign/pages/submission-list/submission-list.page.ts b/src/addons/mod/assign/pages/submission-list/submission-list.page.ts
index e0b09e3b2..9ac31e50e 100644
--- a/src/addons/mod/assign/pages/submission-list/submission-list.page.ts
+++ b/src/addons/mod/assign/pages/submission-list/submission-list.page.ts
@@ -23,7 +23,11 @@ import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { Translate } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
-import { AddonModAssignSubmissionForList, AddonModAssignSubmissionsSource } from '../../classes/submissions-source';
+import {
+ AddonModAssignListFilterName,
+ AddonModAssignSubmissionForList,
+ AddonModAssignSubmissionsSource,
+} from '../../classes/submissions-source';
import { AddonModAssignAssign, AddonModAssignProvider } from '../../services/assign';
import {
AddonModAssignSyncProvider,
@@ -85,7 +89,7 @@ export class AddonModAssignSubmissionListPage implements AfterViewInit, OnDestro
const moduleId = CoreNavigator.getRequiredRouteNumberParam('cmId');
const courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
const groupId = CoreNavigator.getRouteNumberParam('groupId') || 0;
- const selectedStatus = CoreNavigator.getRouteParam('status');
+ const selectedStatus = CoreNavigator.getRouteParam('status');
const submissionsSource = CoreRoutedItemsManagerSourcesTracker.getOrCreateSource(
AddonModAssignSubmissionsSource,
[courseId, moduleId, selectedStatus],
@@ -143,7 +147,7 @@ export class AddonModAssignSubmissionListPage implements AfterViewInit, OnDestro
this.title = Translate.instant(
selectedStatus
? (
- selectedStatus === AddonModAssignProvider.NEED_GRADING
+ selectedStatus === AddonModAssignListFilterName.NEED_GRADING
? 'addon.mod_assign.numberofsubmissionsneedgrading'
: `addon.mod_assign.submissionstatus_${selectedStatus}`
)
diff --git a/src/addons/mod/assign/pages/submission-review/submission-review.ts b/src/addons/mod/assign/pages/submission-review/submission-review.ts
index a51cf4bc4..f722bdef6 100644
--- a/src/addons/mod/assign/pages/submission-review/submission-review.ts
+++ b/src/addons/mod/assign/pages/submission-review/submission-review.ts
@@ -22,7 +22,7 @@ import { IonRefresher } from '@ionic/angular';
import { CoreNavigator } from '@services/navigator';
import { CoreScreen } from '@services/screen';
import { CoreDomUtils } from '@services/utils/dom';
-import { AddonModAssignSubmissionsSource } from '../../classes/submissions-source';
+import { AddonModAssignListFilterName, AddonModAssignSubmissionsSource } from '../../classes/submissions-source';
import { AddonModAssignSubmissionComponent } from '../../components/submission/submission';
import { AddonModAssign, AddonModAssignAssign } from '../../services/assign';
@@ -53,7 +53,7 @@ export class AddonModAssignSubmissionReviewPage implements OnInit, OnDestroy, Ca
constructor(protected route: ActivatedRoute) { }
/**
- * Component being initialized.
+ * @inheritdoc
*/
ngOnInit(): void {
this.route.queryParams.subscribe((params) => {
@@ -63,7 +63,7 @@ export class AddonModAssignSubmissionReviewPage implements OnInit, OnDestroy, Ca
this.submitId = CoreNavigator.getRouteNumberParam('submitId') || 0;
this.blindId = CoreNavigator.getRouteNumberParam('blindId', { params });
const groupId = CoreNavigator.getRequiredRouteNumberParam('groupId');
- const selectedStatus = CoreNavigator.getRouteParam('selectedStatus');
+ const selectedStatus = CoreNavigator.getRouteParam('selectedStatus');
const submissionsSource = CoreRoutedItemsManagerSourcesTracker.getOrCreateSource(
AddonModAssignSubmissionsSource,
[this.courseId, this.moduleId, selectedStatus],
diff --git a/src/addons/mod/assign/services/assign-helper.ts b/src/addons/mod/assign/services/assign-helper.ts
index 017e9a389..25653194c 100644
--- a/src/addons/mod/assign/services/assign-helper.ts
+++ b/src/addons/mod/assign/services/assign-helper.ts
@@ -25,6 +25,7 @@ import {
AddonModAssign,
AddonModAssignPlugin,
AddonModAssignSavePluginData,
+ AddonModAssignSubmissionStatusValues,
} from './assign';
import { AddonModAssignOffline } from './assign-offline';
import { CoreUtils } from '@services/utils/utils';
@@ -55,8 +56,8 @@ export class AddonModAssignHelperProvider {
return false;
}
- if (submission.status == AddonModAssignProvider.SUBMISSION_STATUS_NEW ||
- submission.status == AddonModAssignProvider.SUBMISSION_STATUS_REOPENED) {
+ if (submission.status == AddonModAssignSubmissionStatusValues.NEW ||
+ submission.status == AddonModAssignSubmissionStatusValues.REOPENED) {
// It's a new submission, allow creating it in offline.
return true;
}
@@ -443,8 +444,8 @@ export class AddonModAssignHelperProvider {
submission.groupname = participant.groupname;
}
- submission.status = submission.status ?? (participant.submitted ? AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED :
- AddonModAssignProvider.SUBMISSION_STATUS_NEW);
+ submission.status = submission.status ?? (participant.submitted ? AddonModAssignSubmissionStatusValues.SUBMITTED :
+ AddonModAssignSubmissionStatusValues.NEW);
return submission;
diff --git a/src/addons/mod/assign/services/assign.ts b/src/addons/mod/assign/services/assign.ts
index b0b198c8b..4a9623ddd 100644
--- a/src/addons/mod/assign/services/assign.ts
+++ b/src/addons/mod/assign/services/assign.ts
@@ -34,6 +34,7 @@ import { CoreWSError } from '@classes/errors/wserror';
import { AddonModAssignAutoSyncData, AddonModAssignManualSyncData, AddonModAssignSyncProvider } from './assign-sync';
import { CoreFormFields } from '@singletons/form';
import { CoreFileHelper } from '@services/file-helper';
+import { CoreIonicColorNames } from '@singletons/colors';
const ROOT_CACHE_KEY = 'mmaModAssign:';
@@ -64,23 +65,6 @@ export class AddonModAssignProvider {
static readonly SUBMISSION_COMPONENT = 'mmaModAssignSubmission';
static readonly UNLIMITED_ATTEMPTS = -1;
- // Submission status.
- static readonly SUBMISSION_STATUS_NEW = 'new';
- static readonly SUBMISSION_STATUS_REOPENED = 'reopened';
- static readonly SUBMISSION_STATUS_DRAFT = 'draft';
- static readonly SUBMISSION_STATUS_SUBMITTED = 'submitted';
-
- // "Re-open" methods (to retry the assign).
- static readonly ATTEMPT_REOPEN_METHOD_NONE = 'none';
- static readonly ATTEMPT_REOPEN_METHOD_MANUAL = 'manual';
-
- // Grading status.
- static readonly GRADING_STATUS_GRADED = 'graded';
- static readonly GRADING_STATUS_NOT_GRADED = 'notgraded';
- static readonly MARKING_WORKFLOW_STATE_RELEASED = 'released';
- static readonly NEED_GRADING = 'needgrading';
- static readonly GRADED_FOLLOWUP_SUBMIT = 'gradedfollowupsubmit';
-
// Group submissions warnings.
static readonly WARN_GROUPS_REQUIRED = 'warnrequired';
static readonly WARN_GROUPS_OPTIONAL = 'warnoptional';
@@ -108,17 +92,17 @@ export class AddonModAssignProvider {
const teamSubmission = submissionStatus.lastattempt?.teamsubmission;
if (teamSubmission) {
- if (teamSubmission.status === AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED) {
+ if (teamSubmission.status === AddonModAssignSubmissionStatusValues.SUBMITTED) {
// The assignment submission has been completed.
return false;
- } else if (userSubmission && userSubmission.status === AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED) {
+ } else if (userSubmission && userSubmission.status === AddonModAssignSubmissionStatusValues.SUBMITTED) {
// The user has already clicked the submit button on the team submission.
return false;
} else if (assign.preventsubmissionnotingroup && !submissionStatus.lastattempt?.submissiongroup) {
return false;
}
} else if (userSubmission) {
- if (userSubmission.status === AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED) {
+ if (userSubmission.status === AddonModAssignSubmissionStatusValues.SUBMITTED) {
// The assignment submission has been completed.
return false;
}
@@ -347,17 +331,17 @@ export class AddonModAssignProvider {
* @param status Grading status name
* @return The color name.
*/
- getSubmissionGradingStatusColor(status?: string): string {
+ getSubmissionGradingStatusColor(status?: AddonModAssignGradingStates): CoreIonicColorNames {
if (!status) {
- return '';
+ return CoreIonicColorNames.NONE;
}
- if (status == AddonModAssignProvider.GRADING_STATUS_GRADED ||
- status == AddonModAssignProvider.MARKING_WORKFLOW_STATE_RELEASED) {
- return 'success';
+ if (status == AddonModAssignGradingStates.GRADED
+ || status == AddonModAssignGradingStates.MARKING_WORKFLOW_STATE_RELEASED) {
+ return CoreIonicColorNames.SUCCESS;
}
- return 'danger';
+ return CoreIonicColorNames.DANGER;
}
/**
@@ -366,13 +350,14 @@ export class AddonModAssignProvider {
* @param status Grading Status name
* @return The status translation identifier.
*/
- getSubmissionGradingStatusTranslationId(status?: string): string | undefined {
+ getSubmissionGradingStatusTranslationId(status?: AddonModAssignGradingStates): string | undefined {
if (!status) {
return;
}
- if (status == AddonModAssignProvider.GRADING_STATUS_GRADED || status == AddonModAssignProvider.GRADING_STATUS_NOT_GRADED
- || status == AddonModAssignProvider.GRADED_FOLLOWUP_SUBMIT) {
+ if (status == AddonModAssignGradingStates.GRADED
+ || status == AddonModAssignGradingStates.NOT_GRADED
+ || status == AddonModAssignGradingStates.GRADED_FOLLOWUP_SUBMIT) {
return 'addon.mod_assign.' + status;
}
@@ -604,20 +589,20 @@ export class AddonModAssignProvider {
* @param status Status name
* @return The color name.
*/
- getSubmissionStatusColor(status: string): string {
+ getSubmissionStatusColor(status: AddonModAssignSubmissionStatusValues): CoreIonicColorNames {
switch (status) {
- case 'submitted':
- return 'success';
- case 'draft':
- return 'info';
- case 'new':
- case 'noattempt':
- case 'noonlinesubmissions':
- case 'nosubmission':
- case 'gradedfollowupsubmit':
- return 'danger';
+ case AddonModAssignSubmissionStatusValues.SUBMITTED:
+ return CoreIonicColorNames.SUCCESS;
+ case AddonModAssignSubmissionStatusValues.DRAFT:
+ return CoreIonicColorNames.INFO;
+ case AddonModAssignSubmissionStatusValues.NEW:
+ case AddonModAssignSubmissionStatusValues.NO_ATTEMPT:
+ case AddonModAssignSubmissionStatusValues.NO_ONLINE_SUBMISSIONS:
+ case AddonModAssignSubmissionStatusValues.NO_SUBMISSION:
+ case AddonModAssignSubmissionStatusValues.GRADED_FOLLOWUP_SUBMIT:
+ return CoreIonicColorNames.DANGER;
default:
- return 'light';
+ return CoreIonicColorNames.LIGHT;
}
}
@@ -878,7 +863,7 @@ export class AddonModAssignProvider {
}
if (submission) {
- if (assign.submissiondrafts && submission.status == AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED) {
+ if (assign.submissiondrafts && submission.status == AddonModAssignSubmissionStatusValues.SUBMITTED) {
// Drafts are tracked and the student has submitted the assignment.
return false;
}
@@ -975,8 +960,8 @@ export class AddonModAssignProvider {
return true;
}
- if (submission.gradingstatus != AddonModAssignProvider.GRADING_STATUS_GRADED &&
- submission.gradingstatus != AddonModAssignProvider.MARKING_WORKFLOW_STATE_RELEASED) {
+ if (submission.gradingstatus != AddonModAssignGradingStates.GRADED &&
+ submission.gradingstatus != AddonModAssignGradingStates.MARKING_WORKFLOW_STATE_RELEASED) {
// Not graded.
return true;
}
@@ -1349,7 +1334,7 @@ export type AddonModAssignAssign = {
blindmarking: number; // If enabled, hide identities until reveal identities actioned.
hidegrader?: number; // @since 3.7. If enabled, hide grader to student.
revealidentities: number; // Show identities for a blind marking assignment.
- attemptreopenmethod: string; // Method used to control opening new attempts.
+ attemptreopenmethod: AddonModAssignAttemptReopenMethodValues; // Method used to control opening new attempts.
maxattempts: number; // Maximum number of attempts allowed.
markingworkflow: number; // Enable marking workflow.
markingallocation: number; // Enable marking allocation.
@@ -1400,12 +1385,12 @@ export type AddonModAssignSubmission = {
attemptnumber: number; // Attempt number.
timecreated: number; // Submission creation time.
timemodified: number; // Submission last modified time.
- status: string; // Submission status.
+ status: AddonModAssignSubmissionStatusValues; // Submission status.
groupid: number; // Group id.
assignment?: number; // Assignment id.
latest?: number; // Latest attempt.
plugins?: AddonModAssignPlugin[]; // Plugins.
- gradingstatus?: string; // Grading status.
+ gradingstatus?: AddonModAssignGradingStates; // Grading status.
};
/**
@@ -1454,7 +1439,7 @@ export type AddonModAssignSubmissionAttempt = {
cansubmit: boolean; // Whether the user can submit.
extensionduedate: number; // Extension due date.
blindmarking: boolean; // Whether blind marking is enabled.
- gradingstatus: string; // Grading status.
+ gradingstatus: AddonModAssignGradingStates; // Grading status.
usergroups: number[]; // User groups in the course.
};
@@ -1749,3 +1734,41 @@ export type AddonModAssignSubmissionSavedEventData = AddonModAssignSubmittedForG
* Data sent by GRADED_EVENT event.
*/
export type AddonModAssignGradedEventData = AddonModAssignSubmittedForGradingEventData;
+
+/**
+ * Submission status.
+ * Constants on LMS starting with ASSIGN_SUBMISSION_STATUS_
+ */
+export enum AddonModAssignSubmissionStatusValues {
+ SUBMITTED = 'submitted',
+ DRAFT = 'draft',
+ NEW = 'new',
+ REOPENED = 'reopened',
+ // Added by App Statuses.
+ NO_ATTEMPT = 'noattempt',
+ NO_ONLINE_SUBMISSIONS = 'noonlinesubmissions',
+ NO_SUBMISSION = 'nosubmission',
+ GRADED_FOLLOWUP_SUBMIT = 'gradedfollowupsubmit',
+};
+
+/**
+ * Grading status.
+ * Constants on LMS starting with ASSIGN_GRADING_STATUS_
+ */
+export enum AddonModAssignGradingStates {
+ GRADED = 'graded',
+ NOT_GRADED = 'notgraded',
+ // Added by App Statuses.
+ MARKING_WORKFLOW_STATE_RELEASED = 'released', // with ASSIGN_MARKING_WORKFLOW_STATE_RELEASED
+ GRADED_FOLLOWUP_SUBMIT = 'gradedfollowupsubmit',
+};
+
+/**
+ * Reopen attempt methods.
+ * Constants on LMS starting with ASSIGN_ATTEMPT_REOPEN_METHOD_
+ */
+export enum AddonModAssignAttemptReopenMethodValues {
+ NONE = 'none',
+ MANUAL = 'manual',
+ UNTILPASS = 'untilpass',
+};
diff --git a/src/core/singletons/colors.ts b/src/core/singletons/colors.ts
index 97a2eac81..5a5eeb0c9 100644
--- a/src/core/singletons/colors.ts
+++ b/src/core/singletons/colors.ts
@@ -21,6 +21,18 @@ interface ColorComponents {
blue: number; // Blue component of an RGB color [0-255].
}
+/**
+ * Ionic color names.
+ */
+export enum CoreIonicColorNames {
+ SUCCESS = 'success',
+ INFO = 'info',
+ DANGER = 'danger',
+ DARK = 'dark',
+ LIGHT = 'light',
+ NONE = '',
+};
+
/**
* Singleton with helper functions for colors.
*/
From c5ef18183b7cfd894b1921339ac279bbaf1b5660 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?=
Date: Thu, 13 Jan 2022 10:57:36 +0100
Subject: [PATCH 5/6] MOBILE-3787 assign: Improve submission list filtering
---
.../mod/assign/classes/submissions-source.ts | 100 +++++++++---------
src/addons/mod/assign/services/assign.ts | 4 +
2 files changed, 55 insertions(+), 49 deletions(-)
diff --git a/src/addons/mod/assign/classes/submissions-source.ts b/src/addons/mod/assign/classes/submissions-source.ts
index 4e3ee9953..9fd25f21d 100644
--- a/src/addons/mod/assign/classes/submissions-source.ts
+++ b/src/addons/mod/assign/classes/submissions-source.ts
@@ -170,68 +170,69 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
: [];
// Filter the submissions to get only the ones with the right status and add some extra data.
- const getNeedGrading = this.SELECTED_STATUS == AddonModAssignListFilterName.NEED_GRADING;
- const searchStatus = getNeedGrading ? AddonModAssignSubmissionStatusValues.SUBMITTED : this.SELECTED_STATUS;
+ if (this.SELECTED_STATUS == AddonModAssignListFilterName.NEED_GRADING) {
+ const promises: Promise[] = submissions.map(async (submission: AddonModAssignSubmissionForList) => {
+ // Only show the submissions that need to be graded.
+ submission.needsGrading = await AddonModAssign.needsSubmissionToBeGraded(submission, assign.id);
+ });
- const showSubmissions: AddonModAssignSubmissionForList[] = [];
+ await Promise.all(promises);
- if (searchStatus) {
- submissions = submissions.filter((submission: AddonModAssignSubmissionForList) => searchStatus == submission.status);
+ submissions = submissions.filter((submission: AddonModAssignSubmissionForList) => submission.needsGrading);
+ } else if (this.SELECTED_STATUS) {
+ const searchStatus = this.SELECTED_STATUS == AddonModAssignListFilterName.DRAFT
+ ? AddonModAssignSubmissionStatusValues.DRAFT
+ : AddonModAssignSubmissionStatusValues.SUBMITTED;
+
+ submissions = submissions.filter((submission: AddonModAssignSubmissionForList) => submission.status == searchStatus);
}
- const promises: Promise[] = submissions.map(async (submission: AddonModAssignSubmissionForList) => {
- const gradeData = await CoreUtils.ignoreErrors(AddonModAssignOffline.getSubmissionGrade(assign.id, submission.userid));
- if (getNeedGrading) {
- // Only show the submissions that need to be graded.
- const add = await AddonModAssign.needsSubmissionToBeGraded(submission, assign.id);
+ const showSubmissions: AddonModAssignSubmissionForList[] = await Promise.all(
+ submissions.map(async (submission: AddonModAssignSubmissionForList) => {
+ const gradeData =
+ await CoreUtils.ignoreErrors(AddonModAssignOffline.getSubmissionGrade(assign.id, submission.userid));
- if (!add) {
- return;
- }
- }
+ // Load offline grades.
+ const notSynced = !!gradeData && submission.timemodified < gradeData.timemodified;
- // Load offline grades.
- const notSynced = !!gradeData && submission.timemodified < gradeData.timemodified;
-
- if (submission.gradingstatus == AddonModAssignGradingStates.GRADED && !assign.markingworkflow) {
- // Get the last grade of the submission.
- const grade = grades
- .filter((grade) => grade.userid == submission.userid)
- .reduce(
- (a, b) => (a && a.timemodified > b.timemodified ? a : b),
+ if (submission.gradingstatus == AddonModAssignGradingStates.GRADED && !assign.markingworkflow) {
+ // Get the last grade of the submission.
+ const grade = grades
+ .filter((grade) => grade.userid == submission.userid)
+ .reduce(
+ (a, b) => (a && a.timemodified > b.timemodified ? a : b),
undefined,
- );
+ );
- if (grade && grade.timemodified < submission.timemodified) {
- submission.gradingstatus = AddonModAssignGradingStates.GRADED_FOLLOWUP_SUBMIT;
+ if (grade && grade.timemodified < submission.timemodified) {
+ submission.gradingstatus = AddonModAssignGradingStates.GRADED_FOLLOWUP_SUBMIT;
+ }
}
- }
- submission.statusColor = AddonModAssign.getSubmissionStatusColor(submission.status);
- submission.gradingColor = AddonModAssign.getSubmissionGradingStatusColor(
- submission.gradingstatus,
- );
-
- submission.statusTranslated = Translate.instant(
- 'addon.mod_assign.submissionstatus_' + submission.status,
- );
-
- if (notSynced) {
- submission.gradingStatusTranslationId = 'addon.mod_assign.gradenotsynced';
- submission.gradingColor = '';
- } else if (submission.statusColor != CoreIonicColorNames.DANGER ||
- submission.gradingColor != CoreIonicColorNames.DANGER) {
- // Show grading status if one of the statuses is not done.
- submission.gradingStatusTranslationId = AddonModAssign.getSubmissionGradingStatusTranslationId(
+ submission.statusColor = AddonModAssign.getSubmissionStatusColor(submission.status);
+ submission.gradingColor = AddonModAssign.getSubmissionGradingStatusColor(
submission.gradingstatus,
);
- } else {
- submission.gradingStatusTranslationId = '';
- }
- showSubmissions.push(submission);
- });
+ submission.statusTranslated = Translate.instant(
+ 'addon.mod_assign.submissionstatus_' + submission.status,
+ );
- await Promise.all(promises);
+ if (notSynced) {
+ submission.gradingStatusTranslationId = 'addon.mod_assign.gradenotsynced';
+ submission.gradingColor = '';
+ } else if (submission.statusColor != CoreIonicColorNames.DANGER ||
+ submission.gradingColor != CoreIonicColorNames.DANGER) {
+ // Show grading status if one of the statuses is not done.
+ submission.gradingStatusTranslationId = AddonModAssign.getSubmissionGradingStatusTranslationId(
+ submission.gradingstatus,
+ );
+ } else {
+ submission.gradingStatusTranslationId = '';
+ }
+
+ return submission;
+ }),
+ );
return { items: showSubmissions };
}
@@ -246,6 +247,7 @@ export type AddonModAssignSubmissionForList = AddonModAssignSubmissionFormatted
gradingColor?: string; // Calculated in the app. Color of the submission grading status.
statusTranslated?: string; // Calculated in the app. Translated text of the submission status.
gradingStatusTranslationId?: string; // Calculated in the app. Key of the text of the submission grading status.
+ needsGrading?: boolean; // Calculated in the app. If submission and grading status means that it needs grading.
};
/**
diff --git a/src/addons/mod/assign/services/assign.ts b/src/addons/mod/assign/services/assign.ts
index 4a9623ddd..643e4647c 100644
--- a/src/addons/mod/assign/services/assign.ts
+++ b/src/addons/mod/assign/services/assign.ts
@@ -955,6 +955,10 @@ export class AddonModAssignProvider {
* @return Promise resolved with boolean: whether it needs to be graded or not.
*/
async needsSubmissionToBeGraded(submission: AddonModAssignSubmissionFormatted, assignId: number): Promise {
+ if (submission.status != AddonModAssignSubmissionStatusValues.SUBMITTED) {
+ return false;
+ }
+
if (!submission.gradingstatus) {
// This should not happen, but it's better to show rather than not showing any of the submissions.
return true;
From 4fc3c8b0d0e6471e09da0bcf97172ae8a2acc96a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?=
Date: Thu, 13 Jan 2022 12:23:03 +0100
Subject: [PATCH 6/6] MOBILE-3787 assign: Apply grading status when grades are
found
---
.../mod/assign/classes/submissions-source.ts | 23 ++++++++++---------
.../mod/assign/services/assign-helper.ts | 15 ++++++++----
src/core/components/loading/loading.scss | 1 -
3 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/src/addons/mod/assign/classes/submissions-source.ts b/src/addons/mod/assign/classes/submissions-source.ts
index 9fd25f21d..8a5ef3441 100644
--- a/src/addons/mod/assign/classes/submissions-source.ts
+++ b/src/addons/mod/assign/classes/submissions-source.ts
@@ -164,11 +164,14 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
this.submissionsData.submissions,
this.groupId,
);
+
// Get assignment grades only if workflow is not enabled to check grading date.
- const grades = !assign.markingworkflow
+ let grades = !assign.markingworkflow
? await AddonModAssign.getAssignmentGrades(assign.id, { cmId: assign.cmid })
: [];
+ // Remove grades (not graded) and sort by timemodified DESC to allow finding quicker.
+ grades = grades.filter((grade) => parseInt(grade.grade, 10) >= 0).sort((a, b) => b.timemodified - a.timemodified);
// Filter the submissions to get only the ones with the right status and add some extra data.
if (this.SELECTED_STATUS == AddonModAssignListFilterName.NEED_GRADING) {
const promises: Promise[] = submissions.map(async (submission: AddonModAssignSubmissionForList) => {
@@ -195,17 +198,15 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
// Load offline grades.
const notSynced = !!gradeData && submission.timemodified < gradeData.timemodified;
- if (submission.gradingstatus == AddonModAssignGradingStates.GRADED && !assign.markingworkflow) {
+ if (!assign.markingworkflow) {
// Get the last grade of the submission.
- const grade = grades
- .filter((grade) => grade.userid == submission.userid)
- .reduce(
- (a, b) => (a && a.timemodified > b.timemodified ? a : b),
- undefined,
- );
+ const grade = grades.find((grade) => grade.userid == submission.userid);
- if (grade && grade.timemodified < submission.timemodified) {
- submission.gradingstatus = AddonModAssignGradingStates.GRADED_FOLLOWUP_SUBMIT;
+ if (grade) {
+ // Override status if grade is found.
+ submission.gradingstatus = grade.timemodified < submission.timemodified
+ ? AddonModAssignGradingStates.GRADED_FOLLOWUP_SUBMIT
+ : AddonModAssignGradingStates.GRADED;
}
}
submission.statusColor = AddonModAssign.getSubmissionStatusColor(submission.status);
@@ -222,7 +223,7 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
submission.gradingColor = '';
} else if (submission.statusColor != CoreIonicColorNames.DANGER ||
submission.gradingColor != CoreIonicColorNames.DANGER) {
- // Show grading status if one of the statuses is not done.
+ // Show grading status if one of the statuses is not done.
submission.gradingStatusTranslationId = AddonModAssign.getSubmissionGradingStatusTranslationId(
submission.gradingstatus,
);
diff --git a/src/addons/mod/assign/services/assign-helper.ts b/src/addons/mod/assign/services/assign-helper.ts
index 25653194c..cb062c240 100644
--- a/src/addons/mod/assign/services/assign-helper.ts
+++ b/src/addons/mod/assign/services/assign-helper.ts
@@ -150,7 +150,7 @@ export class AddonModAssignHelperProvider {
attemptnumber: 0,
timecreated: 0,
timemodified: 0,
- status: '',
+ status: AddonModAssignSubmissionStatusValues.NEW,
groupid: 0,
};
}
@@ -404,13 +404,18 @@ export class AddonModAssignHelperProvider {
const blind = !!assign.blindmarking && !assign.revealidentities;
const teamsubmission = !!assign.teamsubmission;
+ if (teamsubmission) {
+ // On team submission discard user submissions.
+ submissions = submissions.filter((submission) => submission.userid == 0);
+ }
+
return participants.map((participant) => {
const groupId = participant.groupid ??
(participant.groups && participant.groups[0] ? participant.groups[0].id : 0);
const foundSubmission = submissions.find((submission) => {
if (teamsubmission) {
- return submission.userid == 0 && submission.groupid == groupId;
+ return submission.groupid == groupId;
}
const submitId = submission.userid && submission.userid > 0 ? submission.userid : submission.blindid;
@@ -423,6 +428,9 @@ export class AddonModAssignHelperProvider {
// Create submission if none.
submission = this.createEmptySubmission();
submission.groupid = groupId;
+ submission.status = participant.submitted
+ ? AddonModAssignSubmissionStatusValues.SUBMITTED
+ : AddonModAssignSubmissionStatusValues.NEW;
} else {
submission = Object.assign({}, foundSubmission);
}
@@ -444,9 +452,6 @@ export class AddonModAssignHelperProvider {
submission.groupname = participant.groupname;
}
- submission.status = submission.status ?? (participant.submitted ? AddonModAssignSubmissionStatusValues.SUBMITTED :
- AddonModAssignSubmissionStatusValues.NEW);
-
return submission;
});
diff --git a/src/core/components/loading/loading.scss b/src/core/components/loading/loading.scss
index 3861b04e2..ef26afe30 100644
--- a/src/core/components/loading/loading.scss
+++ b/src/core/components/loading/loading.scss
@@ -44,7 +44,6 @@
}
.core-loading-content {
- display: contents;
@include core-transition(opacity, 200ms);
}