MOBILE-4550 quiz: Move quiz service constants to constants file
parent
df3b328bac
commit
17bd64a5e0
|
@ -15,8 +15,9 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { AddonModQuizAccessRuleHandler } from '@addons/mod/quiz/services/access-rules-delegate';
|
||||
import { AddonModQuizAttemptWSData, AddonModQuizProvider } from '@addons/mod/quiz/services/quiz';
|
||||
import { AddonModQuizAttemptWSData } from '@addons/mod/quiz/services/quiz';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { ADDON_MOD_QUIZ_SHOW_TIME_BEFORE_DEADLINE } from '@addons/mod/quiz/constants';
|
||||
|
||||
/**
|
||||
* Handler to support open/close date access rule.
|
||||
|
@ -50,8 +51,8 @@ export class AddonModQuizAccessOpenCloseDateHandlerService implements AddonModQu
|
|||
return false;
|
||||
}
|
||||
|
||||
// Show the time left only if it's less than QUIZ_SHOW_TIME_BEFORE_DEADLINE.
|
||||
if (timeNow > endTime - AddonModQuizProvider.QUIZ_SHOW_TIME_BEFORE_DEADLINE) {
|
||||
// Show the time left only if it's less than ADDON_MOD_QUIZ_SHOW_TIME_BEFORE_DEADLINE.
|
||||
if (timeNow > endTime - ADDON_MOD_QUIZ_SHOW_TIME_BEFORE_DEADLINE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ import {
|
|||
AddonModQuizGetAttemptAccessInformationWSResponse,
|
||||
AddonModQuizGetQuizAccessInformationWSResponse,
|
||||
AddonModQuizGetUserBestGradeWSResponse,
|
||||
AddonModQuizProvider,
|
||||
} from '../../services/quiz';
|
||||
import { AddonModQuizAttempt, AddonModQuizHelper, AddonModQuizQuizData } from '../../services/quiz-helper';
|
||||
import {
|
||||
|
@ -45,6 +44,8 @@ import {
|
|||
AddonModQuizSyncProvider,
|
||||
AddonModQuizSyncResult,
|
||||
} from '../../services/quiz-sync';
|
||||
import { ADDON_MOD_QUIZ_ATTEMPT_FINISHED_EVENT, ADDON_MOD_QUIZ_COMPONENT, AddonModQuizGradeMethods } from '../../constants';
|
||||
import { QuestionDisplayOptionsMarks } from '@features/question/constants';
|
||||
|
||||
/**
|
||||
* Component that displays a quiz entry page.
|
||||
|
@ -56,7 +57,7 @@ import {
|
|||
})
|
||||
export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComponent implements OnInit, OnDestroy {
|
||||
|
||||
component = AddonModQuizProvider.COMPONENT;
|
||||
component = ADDON_MOD_QUIZ_COMPONENT;
|
||||
pluginName = 'quiz';
|
||||
quiz?: AddonModQuizQuizData; // The quiz.
|
||||
now?: number; // Current time.
|
||||
|
@ -110,7 +111,7 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
|
||||
// Listen for attempt finished events.
|
||||
this.finishedObserver = CoreEvents.on(
|
||||
AddonModQuizProvider.ATTEMPT_FINISHED_EVENT,
|
||||
ADDON_MOD_QUIZ_ATTEMPT_FINISHED_EVENT,
|
||||
(data) => {
|
||||
// Go to review attempt if an attempt in this quiz was finished and synced.
|
||||
if (this.quiz && data.quizId == this.quiz.id) {
|
||||
|
@ -609,12 +610,12 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
// Calculate data to construct the header of the attempts table.
|
||||
AddonModQuizHelper.setQuizCalculatedData(quiz, this.options);
|
||||
|
||||
this.overallStats = !!lastFinished && this.options.alloptions.marks >= AddonModQuizProvider.QUESTION_OPTIONS_MARK_AND_MAX;
|
||||
this.overallStats = !!lastFinished && this.options.alloptions.marks >= QuestionDisplayOptionsMarks.MARK_AND_MAX;
|
||||
|
||||
// Calculate data to show for each attempt.
|
||||
const formattedAttempts = await Promise.all(attempts.map((attempt, index) => {
|
||||
// Highlight the highest grade if appropriate.
|
||||
const shouldHighlight = this.overallStats && quiz.grademethod == AddonModQuizProvider.GRADEHIGHEST &&
|
||||
const shouldHighlight = this.overallStats && quiz.grademethod === AddonModQuizGradeMethods.HIGHEST_GRADE &&
|
||||
attempts.length > 1;
|
||||
const isLast = index == attempts.length - 1;
|
||||
|
||||
|
|
|
@ -12,4 +12,30 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
export const ADDON_MOD_QUIZ_COMPONENT = 'mmaModQuiz';
|
||||
|
||||
export const ADDON_MOD_QUIZ_FEATURE_NAME = 'CoreCourseModuleDelegate_AddonModQuiz';
|
||||
|
||||
export const ADDON_MOD_QUIZ_ATTEMPT_FINISHED_EVENT = 'addon_mod_quiz_attempt_finished';
|
||||
|
||||
export const ADDON_MOD_QUIZ_SHOW_TIME_BEFORE_DEADLINE = 3600;
|
||||
|
||||
/**
|
||||
* Possible grade methods for a quiz.
|
||||
*/
|
||||
export const enum AddonModQuizGradeMethods {
|
||||
HIGHEST_GRADE = 1,
|
||||
AVERAGE_GRADE = 2,
|
||||
FIRST_ATTEMPT = 3,
|
||||
LAST_ATTEMPT = 4,
|
||||
}
|
||||
|
||||
/**
|
||||
* Possible states for an attempt.
|
||||
*/
|
||||
export const enum AddonModQuizAttemptStates {
|
||||
IN_PROGRESS = 'inprogress',
|
||||
OVERDUE = 'overdue',
|
||||
FINISHED = 'finished',
|
||||
ABANDONED = 'abandoned',
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ import {
|
|||
AddonModQuiz,
|
||||
AddonModQuizAttemptWSData,
|
||||
AddonModQuizGetQuizAccessInformationWSResponse,
|
||||
AddonModQuizProvider,
|
||||
} from '../../services/quiz';
|
||||
import { AddonModQuizAttempt, AddonModQuizHelper, AddonModQuizQuizData } from '../../services/quiz-helper';
|
||||
import { ADDON_MOD_QUIZ_COMPONENT } from '../../constants';
|
||||
|
||||
/**
|
||||
* Page that displays some summary data about an attempt.
|
||||
|
@ -39,7 +39,7 @@ export class AddonModQuizAttemptPage implements OnInit {
|
|||
courseId!: number; // The course ID the quiz belongs to.
|
||||
quiz?: AddonModQuizQuizData; // The quiz the attempt belongs to.
|
||||
attempt?: AddonModQuizAttempt; // The attempt to view.
|
||||
component = AddonModQuizProvider.COMPONENT; // Component to link the files to.
|
||||
component = ADDON_MOD_QUIZ_COMPONENT; // Component to link the files to.
|
||||
componentId?: number; // Component ID to use in conjunction with the component.
|
||||
loaded = false; // Whether data has been loaded.
|
||||
feedback?: string; // Attempt feedback.
|
||||
|
|
|
@ -38,7 +38,6 @@ import {
|
|||
AddonModQuizAttemptWSData,
|
||||
AddonModQuizGetAttemptAccessInformationWSResponse,
|
||||
AddonModQuizGetQuizAccessInformationWSResponse,
|
||||
AddonModQuizProvider,
|
||||
AddonModQuizQuizWSData,
|
||||
} from '../../services/quiz';
|
||||
import { AddonModQuizAttempt, AddonModQuizHelper } from '../../services/quiz-helper';
|
||||
|
@ -50,6 +49,7 @@ import { CoreTime } from '@singletons/time';
|
|||
import { CoreDirectivesRegistry } from '@singletons/directives-registry';
|
||||
import { CoreWSError } from '@classes/errors/wserror';
|
||||
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
||||
import { ADDON_MOD_QUIZ_ATTEMPT_FINISHED_EVENT, AddonModQuizAttemptStates, ADDON_MOD_QUIZ_COMPONENT } from '../../constants';
|
||||
|
||||
/**
|
||||
* Page that allows attempting a quiz.
|
||||
|
@ -68,7 +68,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
|
|||
quiz?: AddonModQuizQuizWSData; // The quiz the attempt belongs to.
|
||||
attempt?: AddonModQuizAttempt; // The attempt being attempted.
|
||||
moduleUrl?: string; // URL to the module in the site.
|
||||
component = AddonModQuizProvider.COMPONENT; // Component to link the files to.
|
||||
component = ADDON_MOD_QUIZ_COMPONENT; // Component to link the files to.
|
||||
loaded = false; // Whether data has been loaded.
|
||||
quizAborted = false; // Whether the quiz was aborted due to an error.
|
||||
offline = false; // Whether the quiz is being attempted in offline mode.
|
||||
|
@ -146,7 +146,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
|
|||
|
||||
if (this.quiz) {
|
||||
// Unblock the quiz so it can be synced.
|
||||
CoreSync.unblockOperation(AddonModQuizProvider.COMPONENT, this.quiz.id);
|
||||
CoreSync.unblockOperation(ADDON_MOD_QUIZ_COMPONENT, this.quiz.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
|
|||
return;
|
||||
}
|
||||
|
||||
if (page != -1 && (this.attempt.state == AddonModQuizProvider.ATTEMPT_OVERDUE || this.attempt.finishedOffline)) {
|
||||
if (page != -1 && (this.attempt.state === AddonModQuizAttemptStates.OVERDUE || this.attempt.finishedOffline)) {
|
||||
// We can't load a page if overdue or the local attempt is finished.
|
||||
return;
|
||||
} else if (page == this.attempt.currentpage && !this.showSummary && slot !== undefined) {
|
||||
|
@ -341,7 +341,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
|
|||
this.quiz = await AddonModQuiz.getQuiz(this.courseId, this.cmId);
|
||||
|
||||
// Block the quiz so it cannot be synced.
|
||||
CoreSync.blockOperation(AddonModQuizProvider.COMPONENT, this.quiz.id);
|
||||
CoreSync.blockOperation(ADDON_MOD_QUIZ_COMPONENT, this.quiz.id);
|
||||
|
||||
// Wait for any ongoing sync to finish. We won't sync a quiz while it's being played.
|
||||
await AddonModQuizSync.waitForSync(this.quiz.id);
|
||||
|
@ -408,7 +408,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
|
|||
|
||||
try {
|
||||
// Show confirm if the user clicked the finish button and the quiz is in progress.
|
||||
if (!timeUp && this.attempt.state == AddonModQuizProvider.ATTEMPT_IN_PROGRESS) {
|
||||
if (!timeUp && this.attempt.state === AddonModQuizAttemptStates.IN_PROGRESS) {
|
||||
let message = Translate.instant('addon.mod_quiz.confirmclose');
|
||||
|
||||
const unansweredCount = this.summaryQuestions
|
||||
|
@ -444,7 +444,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
|
|||
await this.processAttempt(userFinish, timeUp);
|
||||
|
||||
// Trigger an event to notify the attempt was finished.
|
||||
CoreEvents.trigger(AddonModQuizProvider.ATTEMPT_FINISHED_EVENT, {
|
||||
CoreEvents.trigger(ADDON_MOD_QUIZ_ATTEMPT_FINISHED_EVENT, {
|
||||
quizId: this.quiz.id,
|
||||
attemptId: this.attempt.id,
|
||||
synced: !this.offline,
|
||||
|
@ -679,7 +679,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
|
|||
});
|
||||
|
||||
this.showSummary = true;
|
||||
this.canReturn = this.attempt.state == AddonModQuizProvider.ATTEMPT_IN_PROGRESS && !this.attempt.finishedOffline;
|
||||
this.canReturn = this.attempt.state === AddonModQuizAttemptStates.IN_PROGRESS && !this.attempt.finishedOffline;
|
||||
this.preventSubmitMessages = AddonModQuiz.getPreventSubmitMessages(this.summaryQuestions);
|
||||
|
||||
this.dueDateWarning = AddonModQuiz.getAttemptDueDateWarning(this.quiz, this.attempt);
|
||||
|
@ -904,7 +904,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
|
|||
|
||||
await this.loadNavigation();
|
||||
|
||||
if (this.attempt.state != AddonModQuizProvider.ATTEMPT_OVERDUE && !this.attempt.finishedOffline) {
|
||||
if (this.attempt.state !== AddonModQuizAttemptStates.OVERDUE && !this.attempt.finishedOffline) {
|
||||
// Attempt not overdue and not finished in offline, load page.
|
||||
await this.loadPage(this.attempt.currentpage ?? 0);
|
||||
|
||||
|
|
|
@ -32,12 +32,13 @@ import {
|
|||
AddonModQuizAttemptWSData,
|
||||
AddonModQuizCombinedReviewOptions,
|
||||
AddonModQuizGetAttemptReviewResponse,
|
||||
AddonModQuizProvider,
|
||||
AddonModQuizQuizWSData,
|
||||
AddonModQuizWSAdditionalData,
|
||||
} from '../../services/quiz';
|
||||
import { AddonModQuizHelper } from '../../services/quiz-helper';
|
||||
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
|
||||
import { AddonModQuizAttemptStates, ADDON_MOD_QUIZ_COMPONENT } from '../../constants';
|
||||
import { QuestionDisplayOptionsMarks } from '@features/question/constants';
|
||||
|
||||
/**
|
||||
* Page that allows reviewing a quiz attempt.
|
||||
|
@ -52,7 +53,7 @@ export class AddonModQuizReviewPage implements OnInit {
|
|||
@ViewChild(IonContent) content?: IonContent;
|
||||
|
||||
attempt?: AddonModQuizAttemptWSData; // The attempt being reviewed.
|
||||
component = AddonModQuizProvider.COMPONENT; // Component to link the files to.
|
||||
component = ADDON_MOD_QUIZ_COMPONENT; // Component to link the files to.
|
||||
showAll = false; // Whether to view all questions in the same page.
|
||||
numPages = 1; // Number of pages.
|
||||
showCompleted = false; // Whether to show completed time.
|
||||
|
@ -265,7 +266,7 @@ export class AddonModQuizReviewPage implements OnInit {
|
|||
|
||||
this.readableState = AddonModQuiz.getAttemptReadableStateName(this.attempt.state ?? '');
|
||||
|
||||
if (this.attempt.state != AddonModQuizProvider.ATTEMPT_FINISHED) {
|
||||
if (this.attempt.state !== AddonModQuizAttemptStates.FINISHED) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -299,7 +300,7 @@ export class AddonModQuizReviewPage implements OnInit {
|
|||
}
|
||||
|
||||
// Treat grade.
|
||||
if (this.options && this.options.someoptions.marks >= AddonModQuizProvider.QUESTION_OPTIONS_MARK_AND_MAX &&
|
||||
if (this.options && this.options.someoptions.marks >= QuestionDisplayOptionsMarks.MARK_AND_MAX &&
|
||||
AddonModQuiz.quizHasGrades(this.quiz)) {
|
||||
|
||||
if (data.grade === null || data.grade === undefined) {
|
||||
|
|
|
@ -33,7 +33,7 @@ import { AddonModQuizPrefetchHandler } from './services/handlers/prefetch';
|
|||
import { AddonModQuizPushClickHandler } from './services/handlers/push-click';
|
||||
import { AddonModQuizReviewLinkHandler } from './services/handlers/review-link';
|
||||
import { AddonModQuizSyncCronHandler } from './services/handlers/sync-cron';
|
||||
import { AddonModQuizProvider } from './services/quiz';
|
||||
import { ADDON_MOD_QUIZ_COMPONENT } from './constants';
|
||||
|
||||
/**
|
||||
* Get mod Quiz services.
|
||||
|
@ -98,7 +98,7 @@ const routes: Routes = [
|
|||
CorePushNotificationsDelegate.registerClickHandler(AddonModQuizPushClickHandler.instance);
|
||||
CoreCronDelegate.register(AddonModQuizSyncCronHandler.instance);
|
||||
|
||||
CoreCourseHelper.registerModuleReminderClick(AddonModQuizProvider.COMPONENT);
|
||||
CoreCourseHelper.registerModuleReminderClick(ADDON_MOD_QUIZ_COMPONENT);
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -32,11 +32,11 @@ import {
|
|||
AddonModQuiz,
|
||||
AddonModQuizAttemptWSData,
|
||||
AddonModQuizGetQuizAccessInformationWSResponse,
|
||||
AddonModQuizProvider,
|
||||
AddonModQuizQuizWSData,
|
||||
} from '../quiz';
|
||||
import { AddonModQuizHelper } from '../quiz-helper';
|
||||
import { AddonModQuizSync, AddonModQuizSyncResult } from '../quiz-sync';
|
||||
import { AddonModQuizAttemptStates, ADDON_MOD_QUIZ_COMPONENT } from '../../constants';
|
||||
|
||||
/**
|
||||
* Handler to prefetch quizzes.
|
||||
|
@ -46,7 +46,7 @@ export class AddonModQuizPrefetchHandlerService extends CoreCourseActivityPrefet
|
|||
|
||||
name = 'AddonModQuiz';
|
||||
modName = 'quiz';
|
||||
component = AddonModQuizProvider.COMPONENT;
|
||||
component = ADDON_MOD_QUIZ_COMPONENT;
|
||||
updatesNames = /^configuration$|^.*files$|^grades$|^gradeitems$|^questions$|^attempts$/;
|
||||
|
||||
/**
|
||||
|
@ -321,7 +321,7 @@ export class AddonModQuizPrefetchHandlerService extends CoreCourseActivityPrefet
|
|||
AddonModQuiz.getUserAttempts(quiz.id, modOptions),
|
||||
AddonModQuiz.getAttemptAccessInformation(quiz.id, 0, modOptions),
|
||||
AddonModQuiz.getQuizRequiredQtypes(quiz.id, modOptions),
|
||||
CoreFilepool.addFilesToQueue(siteId, introFiles, AddonModQuizProvider.COMPONENT, module.id),
|
||||
CoreFilepool.addFilesToQueue(siteId, introFiles, ADDON_MOD_QUIZ_COMPONENT, module.id),
|
||||
]);
|
||||
|
||||
// Check if we need to start a new attempt.
|
||||
|
@ -353,17 +353,17 @@ export class AddonModQuizPrefetchHandlerService extends CoreCourseActivityPrefet
|
|||
|
||||
const attemptFiles = await this.getAttemptsFeedbackFiles(quiz, attempts, siteId);
|
||||
|
||||
return CoreFilepool.addFilesToQueue(siteId, attemptFiles, AddonModQuizProvider.COMPONENT, module.id);
|
||||
return CoreFilepool.addFilesToQueue(siteId, attemptFiles, ADDON_MOD_QUIZ_COMPONENT, module.id);
|
||||
}));
|
||||
|
||||
// Update the download time to prevent detecting the new attempt as an update.
|
||||
promises.push(CoreUtils.ignoreErrors(
|
||||
CoreFilepool.updatePackageDownloadTime(siteId, AddonModQuizProvider.COMPONENT, module.id),
|
||||
CoreFilepool.updatePackageDownloadTime(siteId, ADDON_MOD_QUIZ_COMPONENT, module.id),
|
||||
));
|
||||
} else {
|
||||
// Use the already fetched attempts.
|
||||
promises.push(this.getAttemptsFeedbackFiles(quiz, attempts, siteId).then((attemptFiles) =>
|
||||
CoreFilepool.addFilesToQueue(siteId, attemptFiles, AddonModQuizProvider.COMPONENT, module.id)));
|
||||
CoreFilepool.addFilesToQueue(siteId, attemptFiles, ADDON_MOD_QUIZ_COMPONENT, module.id)));
|
||||
}
|
||||
|
||||
// Fetch attempt related data.
|
||||
|
@ -444,7 +444,7 @@ export class AddonModQuizPrefetchHandlerService extends CoreCourseActivityPrefet
|
|||
promises.push(AddonModQuiz.getAttemptAccessInformation(quiz.id, attempt.id, modOptions));
|
||||
promises.push(AddonModQuiz.getAttemptSummary(attempt.id, preflightData, modOptions));
|
||||
|
||||
if (attempt.state == AddonModQuizProvider.ATTEMPT_IN_PROGRESS) {
|
||||
if (attempt.state === AddonModQuizAttemptStates.IN_PROGRESS) {
|
||||
// Get data for each page.
|
||||
promises = promises.concat(pages.map(async (page) => {
|
||||
if (isSequential && typeof attempt.currentpage === 'number' && page < attempt.currentpage) {
|
||||
|
|
|
@ -30,10 +30,11 @@ import {
|
|||
AddonModQuizAttemptWSData,
|
||||
AddonModQuizCombinedReviewOptions,
|
||||
AddonModQuizGetQuizAccessInformationWSResponse,
|
||||
AddonModQuizProvider,
|
||||
AddonModQuizQuizWSData,
|
||||
} from './quiz';
|
||||
import { AddonModQuizOffline } from './quiz-offline';
|
||||
import { AddonModQuizAttemptStates } from '../constants';
|
||||
import { QuestionDisplayOptionsMarks } from '@features/question/constants';
|
||||
|
||||
/**
|
||||
* Helper service that provides some features for quiz.
|
||||
|
@ -291,7 +292,7 @@ export class AddonModQuizHelperProvider {
|
|||
|
||||
// Highlight the highest grade if appropriate.
|
||||
formattedAttempt.highlightGrade = !!(highlight && !attempt.preview &&
|
||||
attempt.state == AddonModQuizProvider.ATTEMPT_FINISHED && formattedAttempt.readableGrade == bestGrade);
|
||||
attempt.state === AddonModQuizAttemptStates.FINISHED && formattedAttempt.readableGrade == bestGrade);
|
||||
} else {
|
||||
formattedAttempt.readableGrade = '';
|
||||
}
|
||||
|
@ -317,7 +318,7 @@ export class AddonModQuizHelperProvider {
|
|||
formattedQuiz.gradeFormatted = AddonModQuiz.formatGrade(quiz.grade, quiz.decimalpoints);
|
||||
|
||||
formattedQuiz.showAttemptColumn = quiz.attempts != 1;
|
||||
formattedQuiz.showGradeColumn = options.someoptions.marks >= AddonModQuizProvider.QUESTION_OPTIONS_MARK_AND_MAX &&
|
||||
formattedQuiz.showGradeColumn = options.someoptions.marks >= QuestionDisplayOptionsMarks.MARK_AND_MAX &&
|
||||
AddonModQuiz.quizHasGrades(quiz);
|
||||
formattedQuiz.showMarkColumn = formattedQuiz.showGradeColumn && quiz.grade != quiz.sumgrades;
|
||||
formattedQuiz.showFeedbackColumn = !!quiz.hasfeedback && !!options.alloptions.overallfeedback;
|
||||
|
@ -356,7 +357,7 @@ export class AddonModQuizHelperProvider {
|
|||
|
||||
try {
|
||||
if (attempt) {
|
||||
if (attempt.state != AddonModQuizProvider.ATTEMPT_OVERDUE && !attempt.finishedOffline) {
|
||||
if (attempt.state !== AddonModQuizAttemptStates.OVERDUE && !attempt.finishedOffline) {
|
||||
// We're continuing an attempt. Call getAttemptData to validate the preflight data.
|
||||
await AddonModQuiz.getAttemptData(attempt.id, attempt.currentpage ?? 0, preflightData, modOptions);
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ import { CoreUtils } from '@services/utils/utils';
|
|||
import { makeSingleton, Translate } from '@singletons';
|
||||
import { CoreLogger } from '@singletons/logger';
|
||||
import { AddonModQuizAttemptDBRecord, ATTEMPTS_TABLE_NAME } from './database/quiz';
|
||||
import { AddonModQuizAttemptWSData, AddonModQuizProvider, AddonModQuizQuizWSData } from './quiz';
|
||||
import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from './quiz';
|
||||
import { ADDON_MOD_QUIZ_COMPONENT } from '../constants';
|
||||
|
||||
/**
|
||||
* Service to handle offline quiz.
|
||||
|
@ -103,7 +104,7 @@ export class AddonModQuizOfflineProvider {
|
|||
* @returns Promise resolved with the answers.
|
||||
*/
|
||||
getAttemptAnswers(attemptId: number, siteId?: string): Promise<CoreQuestionAnswerDBRecord[]> {
|
||||
return CoreQuestion.getAttemptAnswers(AddonModQuizProvider.COMPONENT, attemptId, siteId);
|
||||
return CoreQuestion.getAttemptAnswers(ADDON_MOD_QUIZ_COMPONENT, attemptId, siteId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,7 +150,7 @@ export class AddonModQuizOfflineProvider {
|
|||
|
||||
await Promise.all(questions.map(async (question) => {
|
||||
const dbQuestion = await CoreUtils.ignoreErrors(
|
||||
CoreQuestion.getQuestion(AddonModQuizProvider.COMPONENT, attemptId, question.slot, siteId),
|
||||
CoreQuestion.getQuestion(ADDON_MOD_QUIZ_COMPONENT, attemptId, question.slot, siteId),
|
||||
);
|
||||
|
||||
if (!dbQuestion) {
|
||||
|
@ -230,8 +231,8 @@ export class AddonModQuizOfflineProvider {
|
|||
const db = await CoreSites.getSiteDb(siteId);
|
||||
|
||||
await Promise.all([
|
||||
CoreQuestion.removeAttemptAnswers(AddonModQuizProvider.COMPONENT, attemptId, siteId),
|
||||
CoreQuestion.removeAttemptQuestions(AddonModQuizProvider.COMPONENT, attemptId, siteId),
|
||||
CoreQuestion.removeAttemptAnswers(ADDON_MOD_QUIZ_COMPONENT, attemptId, siteId),
|
||||
CoreQuestion.removeAttemptQuestions(ADDON_MOD_QUIZ_COMPONENT, attemptId, siteId),
|
||||
db.deleteRecords(ATTEMPTS_TABLE_NAME, { id: attemptId }),
|
||||
]);
|
||||
}
|
||||
|
@ -248,8 +249,8 @@ export class AddonModQuizOfflineProvider {
|
|||
siteId = siteId || CoreSites.getCurrentSiteId();
|
||||
|
||||
await Promise.all([
|
||||
CoreQuestion.removeQuestion(AddonModQuizProvider.COMPONENT, attemptId, slot, siteId),
|
||||
CoreQuestion.removeQuestionAnswers(AddonModQuizProvider.COMPONENT, attemptId, slot, siteId),
|
||||
CoreQuestion.removeQuestion(ADDON_MOD_QUIZ_COMPONENT, attemptId, slot, siteId),
|
||||
CoreQuestion.removeQuestionAnswers(ADDON_MOD_QUIZ_COMPONENT, attemptId, slot, siteId),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -299,7 +300,7 @@ export class AddonModQuizOfflineProvider {
|
|||
|
||||
const state = await CoreQuestionBehaviourDelegate.determineNewState(
|
||||
quiz.preferredbehaviour ?? '',
|
||||
AddonModQuizProvider.COMPONENT,
|
||||
ADDON_MOD_QUIZ_COMPONENT,
|
||||
attempt.id,
|
||||
question,
|
||||
quiz.coursemodule,
|
||||
|
@ -312,12 +313,12 @@ export class AddonModQuizOfflineProvider {
|
|||
}
|
||||
|
||||
// Delete previously stored answers for this question.
|
||||
await CoreQuestion.removeQuestionAnswers(AddonModQuizProvider.COMPONENT, attempt.id, question.slot, siteId);
|
||||
await CoreQuestion.removeQuestionAnswers(ADDON_MOD_QUIZ_COMPONENT, attempt.id, question.slot, siteId);
|
||||
}));
|
||||
|
||||
// Now save the answers.
|
||||
await CoreQuestion.saveAnswers(
|
||||
AddonModQuizProvider.COMPONENT,
|
||||
ADDON_MOD_QUIZ_COMPONENT,
|
||||
quiz.id,
|
||||
attempt.id,
|
||||
attempt.userid ?? CoreSites.getCurrentSiteUserId(),
|
||||
|
@ -332,7 +333,7 @@ export class AddonModQuizOfflineProvider {
|
|||
const question = questionsWithAnswers[Number(slot)];
|
||||
|
||||
await CoreQuestion.saveQuestion(
|
||||
AddonModQuizProvider.COMPONENT,
|
||||
ADDON_MOD_QUIZ_COMPONENT,
|
||||
quiz.id,
|
||||
attempt.id,
|
||||
attempt.userid ?? CoreSites.getCurrentSiteUserId(),
|
||||
|
|
|
@ -29,8 +29,9 @@ import { makeSingleton, Translate } from '@singletons';
|
|||
import { CoreEvents } from '@singletons/events';
|
||||
import { AddonModQuizAttemptDBRecord } from './database/quiz';
|
||||
import { AddonModQuizPrefetchHandler } from './handlers/prefetch';
|
||||
import { AddonModQuiz, AddonModQuizAttemptWSData, AddonModQuizProvider, AddonModQuizQuizWSData } from './quiz';
|
||||
import { AddonModQuiz, AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from './quiz';
|
||||
import { AddonModQuizOffline, AddonModQuizQuestionsWithAnswers } from './quiz-offline';
|
||||
import { ADDON_MOD_QUIZ_COMPONENT } from '../constants';
|
||||
|
||||
/**
|
||||
* Service to sync quizzes.
|
||||
|
@ -79,7 +80,7 @@ export class AddonModQuizSyncProvider extends CoreCourseActivitySyncBaseProvider
|
|||
for (const slot in options.onlineQuestions) {
|
||||
promises.push(CoreQuestionDelegate.deleteOfflineData(
|
||||
options.onlineQuestions[slot],
|
||||
AddonModQuizProvider.COMPONENT,
|
||||
ADDON_MOD_QUIZ_COMPONENT,
|
||||
quiz.coursemodule,
|
||||
siteId,
|
||||
));
|
||||
|
@ -204,7 +205,7 @@ export class AddonModQuizSyncProvider extends CoreCourseActivitySyncBaseProvider
|
|||
}
|
||||
quizIds[attempt.quizid] = true;
|
||||
|
||||
if (CoreSync.isBlocked(AddonModQuizProvider.COMPONENT, attempt.quizid, siteId)) {
|
||||
if (CoreSync.isBlocked(ADDON_MOD_QUIZ_COMPONENT, attempt.quizid, siteId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -268,7 +269,7 @@ export class AddonModQuizSyncProvider extends CoreCourseActivitySyncBaseProvider
|
|||
}
|
||||
|
||||
// Verify that quiz isn't blocked.
|
||||
if (CoreSync.isBlocked(AddonModQuizProvider.COMPONENT, quiz.id, siteId)) {
|
||||
if (CoreSync.isBlocked(ADDON_MOD_QUIZ_COMPONENT, quiz.id, siteId)) {
|
||||
this.logger.debug('Cannot sync quiz ' + quiz.id + ' because it is blocked.');
|
||||
|
||||
throw new CoreError(Translate.instant('core.errorsyncblocked', { $a: this.componentTranslate }));
|
||||
|
@ -300,7 +301,7 @@ export class AddonModQuizSyncProvider extends CoreCourseActivitySyncBaseProvider
|
|||
|
||||
// Sync offline logs.
|
||||
await CoreUtils.ignoreErrors(
|
||||
CoreCourseLogHelper.syncActivity(AddonModQuizProvider.COMPONENT, quiz.id, siteId),
|
||||
CoreCourseLogHelper.syncActivity(ADDON_MOD_QUIZ_COMPONENT, quiz.id, siteId),
|
||||
);
|
||||
|
||||
// Get all the offline attempts for the quiz. It should always be 0 or 1 attempt
|
||||
|
@ -381,7 +382,7 @@ export class AddonModQuizSyncProvider extends CoreCourseActivitySyncBaseProvider
|
|||
await CoreQuestionDelegate.prepareSyncData(
|
||||
onlineQuestion,
|
||||
offlineQuestions[slot].answers,
|
||||
AddonModQuizProvider.COMPONENT,
|
||||
ADDON_MOD_QUIZ_COMPONENT,
|
||||
quiz.coursemodule,
|
||||
siteId,
|
||||
);
|
||||
|
|
|
@ -42,8 +42,12 @@ import { AddonModQuizOffline, AddonModQuizQuestionsWithAnswers } from './quiz-of
|
|||
import { AddonModQuizAutoSyncData, AddonModQuizSyncProvider } from './quiz-sync';
|
||||
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
||||
import { QUESTION_INVALID_STATE_CLASSES, QUESTION_TODO_STATE_CLASSES } from '@features/question/constants';
|
||||
|
||||
const ROOT_CACHE_KEY = 'mmaModQuiz:';
|
||||
import {
|
||||
ADDON_MOD_QUIZ_ATTEMPT_FINISHED_EVENT,
|
||||
AddonModQuizAttemptStates,
|
||||
ADDON_MOD_QUIZ_COMPONENT,
|
||||
AddonModQuizGradeMethods,
|
||||
} from '../constants';
|
||||
|
||||
declare module '@singletons/events' {
|
||||
|
||||
|
@ -53,7 +57,7 @@ declare module '@singletons/events' {
|
|||
* @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
|
||||
*/
|
||||
export interface CoreEventsData {
|
||||
[AddonModQuizProvider.ATTEMPT_FINISHED_EVENT]: AddonModQuizAttemptFinishedData;
|
||||
[ADDON_MOD_QUIZ_ATTEMPT_FINISHED_EVENT]: AddonModQuizAttemptFinishedData;
|
||||
[AddonModQuizSyncProvider.AUTO_SYNCED]: AddonModQuizAutoSyncData;
|
||||
}
|
||||
|
||||
|
@ -65,27 +69,7 @@ declare module '@singletons/events' {
|
|||
@Injectable({ providedIn: 'root' })
|
||||
export class AddonModQuizProvider {
|
||||
|
||||
static readonly COMPONENT = 'mmaModQuiz';
|
||||
static readonly ATTEMPT_FINISHED_EVENT = 'addon_mod_quiz_attempt_finished';
|
||||
|
||||
// Grade methods.
|
||||
static readonly GRADEHIGHEST = 1;
|
||||
static readonly GRADEAVERAGE = 2;
|
||||
static readonly ATTEMPTFIRST = 3;
|
||||
static readonly ATTEMPTLAST = 4;
|
||||
|
||||
// Question options.
|
||||
static readonly QUESTION_OPTIONS_MAX_ONLY = 1;
|
||||
static readonly QUESTION_OPTIONS_MARK_AND_MAX = 2;
|
||||
|
||||
// Attempt state.
|
||||
static readonly ATTEMPT_IN_PROGRESS = 'inprogress';
|
||||
static readonly ATTEMPT_OVERDUE = 'overdue';
|
||||
static readonly ATTEMPT_FINISHED = 'finished';
|
||||
static readonly ATTEMPT_ABANDONED = 'abandoned';
|
||||
|
||||
// Show the countdown timer if there is less than this amount of time left before the the quiz close date.
|
||||
static readonly QUIZ_SHOW_TIME_BEFORE_DEADLINE = 3600;
|
||||
protected static readonly ROOT_CACHE_KEY = 'mmaModQuiz:';
|
||||
|
||||
protected logger: CoreLogger;
|
||||
|
||||
|
@ -164,7 +148,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getAttemptAccessInformationCommonCacheKey(quizId: number): string {
|
||||
return ROOT_CACHE_KEY + 'attemptAccessInformation:' + quizId;
|
||||
return AddonModQuizProvider.ROOT_CACHE_KEY + 'attemptAccessInformation:' + quizId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -189,7 +173,7 @@ export class AddonModQuizProvider {
|
|||
};
|
||||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getAttemptAccessInformationCacheKey(quizId, attemptId),
|
||||
component: AddonModQuizProvider.COMPONENT,
|
||||
component: ADDON_MOD_QUIZ_COMPONENT,
|
||||
componentId: options.cmId,
|
||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||
};
|
||||
|
@ -215,7 +199,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getAttemptDataCommonCacheKey(attemptId: number): string {
|
||||
return ROOT_CACHE_KEY + 'attemptData:' + attemptId;
|
||||
return AddonModQuizProvider.ROOT_CACHE_KEY + 'attemptData:' + attemptId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -248,7 +232,7 @@ export class AddonModQuizProvider {
|
|||
};
|
||||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getAttemptDataCacheKey(attemptId, page),
|
||||
component: AddonModQuizProvider.COMPONENT,
|
||||
component: ADDON_MOD_QUIZ_COMPONENT,
|
||||
componentId: options.cmId,
|
||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||
};
|
||||
|
@ -288,10 +272,10 @@ export class AddonModQuizProvider {
|
|||
}
|
||||
|
||||
switch (attempt.state) {
|
||||
case AddonModQuizProvider.ATTEMPT_IN_PROGRESS:
|
||||
case AddonModQuizAttemptStates.IN_PROGRESS:
|
||||
return dueDate * 1000;
|
||||
|
||||
case AddonModQuizProvider.ATTEMPT_OVERDUE:
|
||||
case AddonModQuizAttemptStates.OVERDUE:
|
||||
return (dueDate + (quiz.graceperiod ?? 0)) * 1000;
|
||||
|
||||
default:
|
||||
|
@ -311,7 +295,7 @@ export class AddonModQuizProvider {
|
|||
getAttemptDueDateWarning(quiz: AddonModQuizQuizWSData, attempt: AddonModQuizAttemptWSData): string | undefined {
|
||||
const dueDate = this.getAttemptDueDate(quiz, attempt);
|
||||
|
||||
if (attempt.state === AddonModQuizProvider.ATTEMPT_OVERDUE) {
|
||||
if (attempt.state === AddonModQuizAttemptStates.OVERDUE) {
|
||||
return Translate.instant(
|
||||
'addon.mod_quiz.overduemustbesubmittedby',
|
||||
{ $a: CoreTimeUtils.userDate(dueDate) },
|
||||
|
@ -334,10 +318,10 @@ export class AddonModQuizProvider {
|
|||
}
|
||||
|
||||
switch (attempt.state) {
|
||||
case AddonModQuizProvider.ATTEMPT_IN_PROGRESS:
|
||||
case AddonModQuizAttemptStates.IN_PROGRESS:
|
||||
return [Translate.instant('addon.mod_quiz.stateinprogress')];
|
||||
|
||||
case AddonModQuizProvider.ATTEMPT_OVERDUE: {
|
||||
case AddonModQuizAttemptStates.OVERDUE: {
|
||||
const sentences: string[] = [];
|
||||
const dueDate = this.getAttemptDueDate(quiz, attempt);
|
||||
|
||||
|
@ -353,7 +337,7 @@ export class AddonModQuizProvider {
|
|||
return sentences;
|
||||
}
|
||||
|
||||
case AddonModQuizProvider.ATTEMPT_FINISHED:
|
||||
case AddonModQuizAttemptStates.FINISHED:
|
||||
return [
|
||||
Translate.instant('addon.mod_quiz.statefinished'),
|
||||
Translate.instant(
|
||||
|
@ -362,7 +346,7 @@ export class AddonModQuizProvider {
|
|||
),
|
||||
];
|
||||
|
||||
case AddonModQuizProvider.ATTEMPT_ABANDONED:
|
||||
case AddonModQuizAttemptStates.ABANDONED:
|
||||
return [Translate.instant('addon.mod_quiz.stateabandoned')];
|
||||
|
||||
default:
|
||||
|
@ -378,16 +362,16 @@ export class AddonModQuizProvider {
|
|||
*/
|
||||
getAttemptReadableStateName(state: string): string {
|
||||
switch (state) {
|
||||
case AddonModQuizProvider.ATTEMPT_IN_PROGRESS:
|
||||
case AddonModQuizAttemptStates.IN_PROGRESS:
|
||||
return Translate.instant('addon.mod_quiz.stateinprogress');
|
||||
|
||||
case AddonModQuizProvider.ATTEMPT_OVERDUE:
|
||||
case AddonModQuizAttemptStates.OVERDUE:
|
||||
return Translate.instant('addon.mod_quiz.stateoverdue');
|
||||
|
||||
case AddonModQuizProvider.ATTEMPT_FINISHED:
|
||||
case AddonModQuizAttemptStates.FINISHED:
|
||||
return Translate.instant('addon.mod_quiz.statefinished');
|
||||
|
||||
case AddonModQuizProvider.ATTEMPT_ABANDONED:
|
||||
case AddonModQuizAttemptStates.ABANDONED:
|
||||
return Translate.instant('addon.mod_quiz.stateabandoned');
|
||||
|
||||
default:
|
||||
|
@ -413,7 +397,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getAttemptReviewCommonCacheKey(attemptId: number): string {
|
||||
return ROOT_CACHE_KEY + 'attemptReview:' + attemptId;
|
||||
return AddonModQuizProvider.ROOT_CACHE_KEY + 'attemptReview:' + attemptId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -438,7 +422,7 @@ export class AddonModQuizProvider {
|
|||
const preSets = {
|
||||
cacheKey: this.getAttemptReviewCacheKey(attemptId, page),
|
||||
cacheErrors: ['noreview'],
|
||||
component: AddonModQuizProvider.COMPONENT,
|
||||
component: ADDON_MOD_QUIZ_COMPONENT,
|
||||
componentId: options.cmId,
|
||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||
};
|
||||
|
@ -457,7 +441,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getAttemptSummaryCacheKey(attemptId: number): string {
|
||||
return ROOT_CACHE_KEY + 'attemptSummary:' + attemptId;
|
||||
return AddonModQuizProvider.ROOT_CACHE_KEY + 'attemptSummary:' + attemptId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -487,7 +471,7 @@ export class AddonModQuizProvider {
|
|||
};
|
||||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getAttemptSummaryCacheKey(attemptId),
|
||||
component: AddonModQuizProvider.COMPONENT,
|
||||
component: ADDON_MOD_QUIZ_COMPONENT,
|
||||
componentId: options.cmId,
|
||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||
};
|
||||
|
@ -521,7 +505,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getCombinedReviewOptionsCommonCacheKey(quizId: number): string {
|
||||
return ROOT_CACHE_KEY + 'combinedReviewOptions:' + quizId;
|
||||
return AddonModQuizProvider.ROOT_CACHE_KEY + 'combinedReviewOptions:' + quizId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -544,7 +528,7 @@ export class AddonModQuizProvider {
|
|||
};
|
||||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getCombinedReviewOptionsCacheKey(quizId, userId),
|
||||
component: AddonModQuizProvider.COMPONENT,
|
||||
component: ADDON_MOD_QUIZ_COMPONENT,
|
||||
componentId: options.cmId,
|
||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||
};
|
||||
|
@ -581,7 +565,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getFeedbackForGradeCommonCacheKey(quizId: number): string {
|
||||
return ROOT_CACHE_KEY + 'feedbackForGrade:' + quizId;
|
||||
return AddonModQuizProvider.ROOT_CACHE_KEY + 'feedbackForGrade:' + quizId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -606,7 +590,7 @@ export class AddonModQuizProvider {
|
|||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getFeedbackForGradeCacheKey(quizId, grade),
|
||||
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||
component: AddonModQuizProvider.COMPONENT,
|
||||
component: ADDON_MOD_QUIZ_COMPONENT,
|
||||
componentId: options.cmId,
|
||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||
};
|
||||
|
@ -719,7 +703,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getQuizDataCacheKey(courseId: number): string {
|
||||
return ROOT_CACHE_KEY + 'quiz:' + courseId;
|
||||
return AddonModQuizProvider.ROOT_CACHE_KEY + 'quiz:' + courseId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -746,7 +730,7 @@ export class AddonModQuizProvider {
|
|||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getQuizDataCacheKey(courseId),
|
||||
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||
component: AddonModQuizProvider.COMPONENT,
|
||||
component: ADDON_MOD_QUIZ_COMPONENT,
|
||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||
};
|
||||
|
||||
|
@ -797,7 +781,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getQuizAccessInformationCacheKey(quizId: number): string {
|
||||
return ROOT_CACHE_KEY + 'quizAccessInformation:' + quizId;
|
||||
return AddonModQuizProvider.ROOT_CACHE_KEY + 'quizAccessInformation:' + quizId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -818,7 +802,7 @@ export class AddonModQuizProvider {
|
|||
};
|
||||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getQuizAccessInformationCacheKey(quizId),
|
||||
component: AddonModQuizProvider.COMPONENT,
|
||||
component: ADDON_MOD_QUIZ_COMPONENT,
|
||||
componentId: options.cmId,
|
||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||
};
|
||||
|
@ -842,13 +826,13 @@ export class AddonModQuizProvider {
|
|||
}
|
||||
|
||||
switch (method) {
|
||||
case AddonModQuizProvider.GRADEHIGHEST:
|
||||
case AddonModQuizGradeMethods.HIGHEST_GRADE:
|
||||
return Translate.instant('addon.mod_quiz.gradehighest');
|
||||
case AddonModQuizProvider.GRADEAVERAGE:
|
||||
case AddonModQuizGradeMethods.AVERAGE_GRADE:
|
||||
return Translate.instant('addon.mod_quiz.gradeaverage');
|
||||
case AddonModQuizProvider.ATTEMPTFIRST:
|
||||
case AddonModQuizGradeMethods.FIRST_ATTEMPT:
|
||||
return Translate.instant('addon.mod_quiz.attemptfirst');
|
||||
case AddonModQuizProvider.ATTEMPTLAST:
|
||||
case AddonModQuizGradeMethods.LAST_ATTEMPT:
|
||||
return Translate.instant('addon.mod_quiz.attemptlast');
|
||||
default:
|
||||
return '';
|
||||
|
@ -862,7 +846,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getQuizRequiredQtypesCacheKey(quizId: number): string {
|
||||
return ROOT_CACHE_KEY + 'quizRequiredQtypes:' + quizId;
|
||||
return AddonModQuizProvider.ROOT_CACHE_KEY + 'quizRequiredQtypes:' + quizId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -881,7 +865,7 @@ export class AddonModQuizProvider {
|
|||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getQuizRequiredQtypesCacheKey(quizId),
|
||||
updateFrequency: CoreSite.FREQUENCY_SOMETIMES,
|
||||
component: AddonModQuizProvider.COMPONENT,
|
||||
component: ADDON_MOD_QUIZ_COMPONENT,
|
||||
componentId: options.cmId,
|
||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||
};
|
||||
|
@ -1015,7 +999,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getUserAttemptsCommonCacheKey(quizId: number): string {
|
||||
return ROOT_CACHE_KEY + 'userAttempts:' + quizId;
|
||||
return AddonModQuizProvider.ROOT_CACHE_KEY + 'userAttempts:' + quizId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1045,7 +1029,7 @@ export class AddonModQuizProvider {
|
|||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getUserAttemptsCacheKey(quizId, userId),
|
||||
updateFrequency: CoreSite.FREQUENCY_SOMETIMES,
|
||||
component: AddonModQuizProvider.COMPONENT,
|
||||
component: ADDON_MOD_QUIZ_COMPONENT,
|
||||
componentId: options.cmId,
|
||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||
};
|
||||
|
@ -1073,7 +1057,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getUserBestGradeCommonCacheKey(quizId: number): string {
|
||||
return ROOT_CACHE_KEY + 'userBestGrade:' + quizId;
|
||||
return AddonModQuizProvider.ROOT_CACHE_KEY + 'userBestGrade:' + quizId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1093,7 +1077,7 @@ export class AddonModQuizProvider {
|
|||
};
|
||||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getUserBestGradeCacheKey(quizId, userId),
|
||||
component: AddonModQuizProvider.COMPONENT,
|
||||
component: ADDON_MOD_QUIZ_COMPONENT,
|
||||
componentId: options.cmId,
|
||||
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||
};
|
||||
|
@ -1430,7 +1414,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Whether it's finished.
|
||||
*/
|
||||
isAttemptFinished(state?: string): boolean {
|
||||
return state == AddonModQuizProvider.ATTEMPT_FINISHED || state == AddonModQuizProvider.ATTEMPT_ABANDONED;
|
||||
return state === AddonModQuizAttemptStates.FINISHED || state === AddonModQuizAttemptStates.ABANDONED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1461,7 +1445,7 @@ export class AddonModQuizProvider {
|
|||
* @returns Whether it's nearly over or over.
|
||||
*/
|
||||
isAttemptTimeNearlyOver(quiz: AddonModQuizQuizWSData, attempt: AddonModQuizAttemptWSData): boolean {
|
||||
if (attempt.state != AddonModQuizProvider.ATTEMPT_IN_PROGRESS) {
|
||||
if (attempt.state !== AddonModQuizAttemptStates.IN_PROGRESS) {
|
||||
// Attempt not in progress, return true.
|
||||
return true;
|
||||
}
|
||||
|
@ -1600,7 +1584,7 @@ export class AddonModQuizProvider {
|
|||
return CoreCourseLogHelper.log(
|
||||
'mod_quiz_view_attempt_review',
|
||||
params,
|
||||
AddonModQuizProvider.COMPONENT,
|
||||
ADDON_MOD_QUIZ_COMPONENT,
|
||||
quizId,
|
||||
siteId,
|
||||
);
|
||||
|
@ -1633,7 +1617,7 @@ export class AddonModQuizProvider {
|
|||
return CoreCourseLogHelper.log(
|
||||
'mod_quiz_view_attempt_summary',
|
||||
params,
|
||||
AddonModQuizProvider.COMPONENT,
|
||||
ADDON_MOD_QUIZ_COMPONENT,
|
||||
quizId,
|
||||
siteId,
|
||||
);
|
||||
|
@ -1654,7 +1638,7 @@ export class AddonModQuizProvider {
|
|||
return CoreCourseLogHelper.log(
|
||||
'mod_quiz_view_quiz',
|
||||
params,
|
||||
AddonModQuizProvider.COMPONENT,
|
||||
ADDON_MOD_QUIZ_COMPONENT,
|
||||
id,
|
||||
siteId,
|
||||
);
|
||||
|
@ -1897,7 +1881,7 @@ export class AddonModQuizProvider {
|
|||
shouldShowTimeLeft(rules: string[], attempt: AddonModQuizAttemptWSData, endTime: number): boolean {
|
||||
const timeNow = CoreTimeUtils.timestamp();
|
||||
|
||||
if (attempt.state != AddonModQuizProvider.ATTEMPT_IN_PROGRESS) {
|
||||
if (attempt.state !== AddonModQuizAttemptStates.IN_PROGRESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2392,7 +2376,7 @@ export type AddonModQuizViewQuizWSParams = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Data passed to ATTEMPT_FINISHED_EVENT event.
|
||||
* Data passed to ADDON_MOD_QUIZ_ATTEMPT_FINISHED_EVENT event.
|
||||
*/
|
||||
export type AddonModQuizAttemptFinishedData = {
|
||||
quizId: number;
|
||||
|
|
|
@ -19,3 +19,8 @@ export const QUESTION_NEEDS_GRADING_STATE_CLASSES = ['requiresgrading', 'complet
|
|||
export const QUESTION_FINISHED_STATE_CLASSES = ['complete'] as const;
|
||||
export const QUESTION_GAVE_UP_STATE_CLASSES = ['notanswered'] as const;
|
||||
export const QUESTION_GRADED_STATE_CLASSES = ['complete', 'incorrect', 'partiallycorrect', 'correct'] as const;
|
||||
|
||||
export const enum QuestionDisplayOptionsMarks {
|
||||
MAX_ONLY = 1,
|
||||
MARK_AND_MAX = 2,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue