diff --git a/kolibri/plugins/coach/assets/src/constants/index.js b/kolibri/plugins/coach/assets/src/constants/index.js
index 6515529c713..9a9deee6934 100644
--- a/kolibri/plugins/coach/assets/src/constants/index.js
+++ b/kolibri/plugins/coach/assets/src/constants/index.js
@@ -8,9 +8,6 @@ export const PageNames = {
NEW_COACH_PAGES: 'NEW_COACH_PAGES',
EXAMS: 'EXAMS',
EXAM_CREATION_ROOT: 'EXAM_CREATION_ROOT',
- EXAM_CREATION_PRACTICE_QUIZ: 'EXAM_CREATION_PRACTICE_QUIZ',
- EXAM_CREATION_SELECT_PRACTICE_QUIZ_TOPIC: 'EXAM_CREATION_SELECT_PRACTICE_QUIZ_TOPIC',
- EXAM_CREATION_PRACTICE_QUIZ_PREVIEW: 'EXAM_CREATION_PRACTICE_QUIZ_PREVIEW',
/** Newly added routes */
QUIZ_SECTION_EDITOR: 'QUIZ_SECTION_EDITOR',
@@ -19,15 +16,6 @@ export const PageNames = {
QUIZ_SELECT_PRACTICE_QUIZ: 'QUIZ_SELECT_PRACTICE_QUIZ',
BOOK_MARKED_RESOURCES: 'BOOK_MARKED_RESOURCES',
- /** TODO Remove unused */
- EXAM_CREATION_TOPIC: 'EXAM_CREATION_TOPIC',
- EXAM_CREATION_BOOKMARKS: 'EXAM_CREATION_BOOKMARKS',
- EXAM_CREATION_BOOKMARKS_MAIN: 'EXAM_CREATION_BOOKMARKS_MAIN',
- EXAM_CREATION_PREVIEW: 'EXAM_CREATION_PREVIEW',
- EXAM_CREATION_SEARCH: 'EXAM_CREATION_SEARCH',
- EXAM_CREATION_QUESTION_SELECTION: 'EXAM_CREATION_QUESTION_SELECTION',
- EXAM_SIDE_PANEL: 'EXAM_SIDE_PANEL',
- EXAM_PREVIEW: 'EXAM_PREVIEW',
EXAM_REPORT: 'EXAM_REPORT',
EXAM_REPORT_DETAIL: 'EXAM_REPORT_DETAIL',
EXAM_REPORT_DETAIL_ROOT: 'EXAM_REPORT_DETAIL_ROOT',
diff --git a/kolibri/plugins/coach/assets/src/modules/examCreation/actions.js b/kolibri/plugins/coach/assets/src/modules/examCreation/actions.js
deleted file mode 100644
index 613c96d910d..00000000000
--- a/kolibri/plugins/coach/assets/src/modules/examCreation/actions.js
+++ /dev/null
@@ -1,248 +0,0 @@
-import pickBy from 'lodash/pickBy';
-import uniq from 'lodash/uniq';
-import unionBy from 'lodash/unionBy';
-import union from 'lodash/union';
-import shuffled from 'kolibri.utils.shuffled';
-import { ContentNodeResource, ContentNodeSearchResource } from 'kolibri.resources';
-import { getContentNodeThumbnail } from 'kolibri.utils.contentNode';
-import router from 'kolibri.coreVue.router';
-import { ContentNodeKinds } from 'kolibri.coreVue.vuex.constants';
-import { PageNames } from '../../constants';
-import { MAX_QUESTIONS } from '../../constants/examConstants';
-import { createExam } from '../examShared/exams';
-
-export function resetExamCreationState(store) {
- store.commit('RESET_STATE');
-}
-
-export function addToSelectedExercises(store, exercises) {
- store.commit('ADD_TO_SELECTED_EXERCISES', exercises);
- return updateAvailableQuestions(store);
-}
-
-export function removeFromSelectedExercises(store, exercises) {
- store.commit('REMOVE_FROM_SELECTED_EXERCISES', exercises);
- return updateAvailableQuestions(store);
-}
-
-export function updateAvailableQuestions(store) {
- const { selectedExercises } = store.state;
- // Only bother checking this if there is any doubt that we have sufficient
- // questions available. If we have selected more exercises than we allow questions
- // then we are sure to have this.
- if (Object.keys(selectedExercises).length > 0) {
- if (MAX_QUESTIONS > Object.keys(selectedExercises).length) {
- return ContentNodeResource.fetchNodeAssessments(Object.keys(selectedExercises)).then(resp => {
- store.commit('SET_AVAILABLE_QUESTIONS', resp.data);
- });
- } else {
- store.commit('SET_AVAILABLE_QUESTIONS', MAX_QUESTIONS);
- return Promise.resolve();
- }
- }
- store.commit('SET_AVAILABLE_QUESTIONS', 0);
- return Promise.resolve();
-}
-
-export function fetchAdditionalSearchResults(store, params) {
- let kinds;
- if (params.kind) {
- kinds = [params.kind];
- } else {
- kinds = [ContentNodeKinds.EXERCISE, ContentNodeKinds.TOPIC];
- }
- return ContentNodeSearchResource.fetchCollection({
- getParams: {
- ...pickBy({
- search: params.searchTerm,
- channel_id: params.channelId,
- exclude_content_ids: store.state.searchResults.contentIdsFetched,
- }),
- kind_in: kinds,
- },
- }).then(results => {
- return filterAndAnnotateContentList(results.results).then(contentList => {
- const updatedChannelIds = union(store.state.searchResults.channel_ids, results.channel_ids);
- const updatedContentKinds = union(
- store.state.searchResults.content_kinds,
- results.content_kinds
- ).filter(kind => [ContentNodeKinds.TOPIC, ContentNodeKinds.EXERCISE].includes(kind));
- const updatedResults = unionBy([...store.state.searchResults.results, ...contentList], 'id');
- const updatedContentIdsFetched = uniq([
- ...store.state.searchResults.contentIdsFetched,
- ...results.results.map(({ content_id }) => content_id),
- ]);
- const searchResults = {
- total_results: store.state.searchResults.total_results,
- channel_ids: updatedChannelIds,
- content_kinds: updatedContentKinds,
- results: updatedResults,
- contentIdsFetched: updatedContentIdsFetched,
- };
- store.commit('SET_SEARCH_RESULTS', searchResults);
- });
- });
-}
-
-export function createPracticeQuizAndRoute(store, { classId, randomized }) {
- // 'randomized' means question order IS random, so fixed order means randomized is false
- store.commit('SET_FIXED_ORDER', !randomized);
- const exam = {
- collection: classId,
- title: store.state.title,
- seed: store.state.seed,
- question_count: store.state.selectedQuestions.length,
- question_sources: store.state.selectedQuestions,
- assignments: [classId],
- learners_see_fixed_order: store.state.learnersSeeFixedOrder,
- date_archived: null,
- date_activated: null,
- };
- return createExam(store, exam).then(() => {
- return router.push({ name: PageNames.EXAMS });
- });
-}
-
-export function createExamAndRoute(store, { classId }) {
- const exam = {
- collection: classId,
- title: store.state.title,
- seed: store.state.seed,
- question_count: store.state.selectedQuestions.length,
- question_sources: store.state.selectedQuestions,
- assignments: [classId],
- learners_see_fixed_order: store.state.learnersSeeFixedOrder,
- date_archived: null,
- date_activated: null,
- };
- return createExam(store, exam).then(() => {
- return router.push({ name: PageNames.EXAMS });
- });
-}
-
-function _getTopicsWithExerciseDescendants(topicIds = []) {
- return new Promise(resolve => {
- if (!topicIds.length) {
- resolve([]);
- return;
- }
- const topicsNumAssessmentDescendantsPromise = ContentNodeResource.fetchDescendantsAssessments(
- topicIds
- );
-
- topicsNumAssessmentDescendantsPromise.then(response => {
- const topicsWithExerciseDescendants = [];
- response.data.forEach(descendantAssessments => {
- if (descendantAssessments.num_assessments > 0) {
- topicsWithExerciseDescendants.push({
- id: descendantAssessments.id,
- numAssessments: descendantAssessments.num_assessments,
- exercises: [],
- });
- }
- });
-
- ContentNodeResource.fetchDescendants(
- topicsWithExerciseDescendants.map(topic => topic.id),
- {
- descendant_kind: ContentNodeKinds.EXERCISE,
- }
- ).then(response => {
- response.data.forEach(exercise => {
- const topic = topicsWithExerciseDescendants.find(t => t.id === exercise.ancestor_id);
- topic.exercises.push(exercise);
- });
- resolve(topicsWithExerciseDescendants);
- });
- });
- });
-}
-
-export function filterAndAnnotateContentList(childNodes) {
- return new Promise(resolve => {
- const childTopics = childNodes.filter(({ kind }) => kind === ContentNodeKinds.TOPIC);
- const topicIds = childTopics.map(({ id }) => id);
- const topicsThatHaveExerciseDescendants = _getTopicsWithExerciseDescendants(topicIds);
-
- topicsThatHaveExerciseDescendants.then(topics => {
- const childNodesWithExerciseDescendants = childNodes
- .map(childNode => {
- const index = topics.findIndex(topic => topic.id === childNode.id);
- if (index !== -1) {
- return { ...childNode, ...topics[index] };
- }
- return childNode;
- })
- .filter(childNode => {
- if (childNode.kind === ContentNodeKinds.TOPIC && (childNode.numAssessments || 0) < 1) {
- return false;
- }
- return true;
- });
-
- const contentList = childNodesWithExerciseDescendants.map(node => ({
- ...node,
- thumbnail: getContentNodeThumbnail(node),
- }));
- resolve(contentList);
- });
- });
-}
-
-export function updateSelectedQuestions(store) {
- if (!Object.keys(store.state.selectedExercises).length) {
- store.commit('SET_SELECTED_QUESTIONS', []);
- return Promise.resolve();
- }
-
- return new Promise(resolve => {
- // If there are more exercises than questions, no need to fetch them all so
- // choose N at random where N is the the number of questions.
- const exerciseIds = shuffled(
- Object.keys(store.state.selectedExercises),
- store.state.seed
- ).slice(0, store.state.numberOfQuestions);
-
- store.commit('LOADING_NEW_QUESTIONS', true);
-
- // The selectedExercises don't have the assessment metadata yet so fetch that
- ContentNodeResource.fetchCollection({
- getParams: { ids: exerciseIds },
- }).then(contentNodes => {
- store.commit('UPDATE_SELECTED_EXERCISES', contentNodes); // update with full metadata
- const exercises = {};
- contentNodes.forEach(exercise => {
- exercises[exercise.id] = exercise;
- });
- // TODO This file needs to be cleaned up when updates to quiz management are complete -- this
- // will be removed altogether so just no-op for now is ok
- const doNothing = () => null;
- const availableExercises = exerciseIds.filter(id => exercises[id]);
- const exerciseTitles = availableExercises.map(id => exercises[id].title);
- const questionIdArrays = availableExercises.map(id =>
- exercises[id].assessmentmetadata ? exercises[id].assessmentmetadata.assessment_item_ids : []
- );
- store.commit(
- 'SET_SELECTED_QUESTIONS',
- doNothing(
- store.state.numberOfQuestions,
- availableExercises,
- exerciseTitles,
- questionIdArrays,
- store.state.seed
- )
- );
- store.commit('LOADING_NEW_QUESTIONS', false);
- resolve();
- });
- });
-}
-
-export function fetchPracticeQuizzes(parent = null) {
- return ContentNodeResource.fetchCollection({
- getParams: {
- [parent ? 'parent' : 'parent__isnull']: parent ? parent : true,
- contains_quiz: true,
- },
- });
-}
diff --git a/kolibri/plugins/coach/assets/src/modules/examCreation/handlers.js b/kolibri/plugins/coach/assets/src/modules/examCreation/handlers.js
deleted file mode 100644
index a537b35b76e..00000000000
--- a/kolibri/plugins/coach/assets/src/modules/examCreation/handlers.js
+++ /dev/null
@@ -1,335 +0,0 @@
-import pickBy from 'lodash/pickBy';
-import uniq from 'lodash/uniq';
-import { ContentNodeKinds } from 'kolibri.coreVue.vuex.constants';
-import {
- ContentNodeResource,
- BookmarksResource,
- ContentNodeSearchResource,
- ChannelResource,
-} from 'kolibri.resources';
-import router from 'kolibri.coreVue.router';
-import chunk from 'lodash/chunk';
-import { PageNames } from '../../constants';
-import { filterAndAnnotateContentList, fetchPracticeQuizzes } from './actions';
-
-function showExamCreationPage(store, params) {
- const { contentList, bookmarksList, pageName, ancestors = [], searchResults = null } = params;
- return store.dispatch('loading').then(() => {
- store.commit('examCreation/SET_ANCESTORS', ancestors);
- store.commit('examCreation/SET_CONTENT_LIST', contentList);
- store.commit('examCreation/SET_BOOKMARKS_LIST', bookmarksList);
- if (searchResults) {
- store.commit('examCreation/SET_SEARCH_RESULTS', searchResults);
- }
- store.commit('SET_PAGE_NAME', pageName);
- store.dispatch('notLoading');
- });
-}
-
-export function showExamCreationRootPage(store, params) {
- return store.dispatch('loading').then(() => {
- return ChannelResource.fetchCollection({
- getParams: { available: true, has_exercise: true },
- }).then(channels => {
- const channelContentList = channels.map(channel => ({
- ...channel,
- id: channel.root,
- title: channel.name,
- kind: ContentNodeKinds.CHANNEL,
- is_leaf: false,
- }));
- store.commit('SET_TOOLBAR_ROUTE', {
- name: PageNames.EXAMS,
- });
- return showExamCreationPage(store, {
- classId: params.classId,
- contentList: channelContentList,
- pageName: PageNames.EXAM_CREATION_ROOT,
- });
- });
- });
-}
-export function showPracticeQuizCreationRootPage(store, params) {
- return fetchPracticeQuizzes().then(channels => {
- const channelContentList = channels.map(channel => ({
- ...channel,
- id: channel.id,
- title: channel.title,
- kind: ContentNodeKinds.CHANNEL,
- is_leaf: false,
- }));
- store.commit('SET_TOOLBAR_ROUTE', {
- name: PageNames.EXAMS,
- });
- return showExamCreationPage(store, {
- classId: params.classId,
- contentList: channelContentList,
- pageName: PageNames.EXAM_CREATION_PRACTICE_QUIZ,
- });
- });
-}
-export function showPracticeQuizCreationTopicPage(store, params) {
- return store.dispatch('loading').then(() => {
- const { topicId } = params;
- const topicNodePromise = ContentNodeResource.fetchModel({ id: topicId });
- const childNodesPromise = ContentNodeResource.fetchCollection({
- getParams: {
- parent: topicId,
- kind_in: [ContentNodeKinds.TOPIC, ContentNodeKinds.EXERCISE],
- contains_quiz: true,
- },
- });
- const loadRequirements = [topicNodePromise, childNodesPromise];
-
- return Promise.all(loadRequirements).then(([topicNode, childNodes]) => {
- return filterAndAnnotateContentList(childNodes).then(contentList => {
- store.commit('SET_TOOLBAR_ROUTE', {
- name: PageNames.EXAMS,
- });
-
- return showExamCreationPage(store, {
- classId: params.classId,
- contentList,
- pageName: PageNames.EXAM_CREATION_SELECT_PRACTICE_QUIZ_TOPIC,
- ancestors: [...topicNode.ancestors, topicNode],
- });
- });
- });
- });
-}
-export function showExamCreationTopicPage(store, params) {
- return store.dispatch('loading').then(() => {
- const { topicId } = params;
- const topicNodePromise = ContentNodeResource.fetchModel({ id: topicId });
- const childNodesPromise = ContentNodeResource.fetchCollection({
- getParams: {
- parent: topicId,
- kind_in: [ContentNodeKinds.TOPIC, ContentNodeKinds.EXERCISE],
- },
- });
- const loadRequirements = [topicNodePromise, childNodesPromise];
-
- return Promise.all(loadRequirements).then(([topicNode, childNodes]) => {
- return filterAndAnnotateContentList(childNodes).then(contentList => {
- store.commit('SET_TOOLBAR_ROUTE', {
- name: PageNames.EXAMS,
- });
-
- return showExamCreationPage(store, {
- classId: params.classId,
- contentList,
- pageName: PageNames.EXAM_CREATION_TOPIC,
- ancestors: [...topicNode.ancestors, topicNode],
- });
- });
- });
- });
-}
-
-export function showExamCreationBookmarksPage(store, params) {
- return store.dispatch('loading').then(() => {
- const { topicId } = params;
- const topicNodePromise = ContentNodeResource.fetchModel({ id: topicId });
- const childNodesPromise = ContentNodeResource.fetchCollection({
- getParams: {
- parent: topicId,
- kind_in: [ContentNodeKinds.TOPIC, ContentNodeKinds.VIDEO, ContentNodeKinds.EXERCISE],
- },
- });
- const loadRequirements = [topicNodePromise, childNodesPromise];
-
- return Promise.all(loadRequirements).then(([topicNode, childNodes]) => {
- return filterAndAnnotateContentList(childNodes).then(() => {
- store.commit('SET_TOOLBAR_ROUTE', {
- name: PageNames.EXAMS,
- });
- return showExamCreationPage(store, {
- classId: params.classId,
- bookmarksList: childNodes,
- pageName: PageNames.EXAM_CREATION_BOOKMARKS,
- ancestors: [...topicNode.ancestors, topicNode],
- });
- });
- });
- });
-}
-export function showExamCreationAllBookmarks(store) {
- return store.dispatch('loading').then(() => {
- getBookmarks().then(bookmarks => {
- return showExamCreationPage(store, {
- bookmarksList: bookmarks[0],
- });
- });
- });
-}
-function getBookmarks() {
- return BookmarksResource.fetchCollection()
- .then(bookmarks => bookmarks.map(bookmark => bookmark.contentnode_id))
- .then(contentNodeIds => {
- const chunkedContentNodeIds = chunk(contentNodeIds, 50); // Breaking contentNodeIds into lists no more than 50 in length
- // Now we will create an array of promises, each of which queries for the 50-id chunk
- const fetchPromises = chunkedContentNodeIds.map(idsChunk => {
- return ContentNodeResource.fetchCollection({
- getParams: {
- ids: idsChunk, // This filters only the ids we want
- },
- });
- });
- return Promise.all(fetchPromises);
- });
-}
-
-export function showExamCreationPreviewPage(store, params, fromRoute, query = {}) {
- const { classId, contentId } = params;
- return store.dispatch('loading').then(() => {
- return Promise.all([_prepExamContentPreview(store, classId, contentId)])
- .then(([contentNode]) => {
- const { searchTerm, ...otherQueryParams } = query;
- if (searchTerm) {
- store.commit('SET_TOOLBAR_ROUTE', {
- name: PageNames.EXAM_CREATION_SEARCH,
- params: {
- searchTerm,
- },
- query: otherQueryParams,
- });
- } else if (fromRoute && fromRoute.name === PageNames.EXAM_CREATION_TOPIC) {
- store.commit('SET_TOOLBAR_ROUTE', {
- name: PageNames.EXAM_CREATION_TOPIC,
- params: {
- topicId: contentNode.parent,
- },
- });
- } else {
- store.commit('SET_TOOLBAR_ROUTE', {
- name: PageNames.EXAM_CREATION_ROOT,
- });
- }
- store.dispatch('notLoading');
- })
- .catch(error => {
- store.dispatch('notLoading');
- return store.dispatch('handleApiError', { error, reloadOnReconnect: true });
- });
- });
-}
-export function showPracticeQuizCreationPreviewPage(store, params) {
- const { classId, contentId } = params;
- return store.dispatch('loading').then(() => {
- return Promise.all([_prepPracticeQuizContentPreview(store, classId, contentId)])
- .then(([contentNode]) => {
- store.commit('SET_TOOLBAR_ROUTE', {
- name: PageNames.EXAM_CREATION_SELECT_PRACTICE_QUIZ_TOPIC,
- params: {
- topicId: contentNode.parent,
- },
- });
- store.dispatch('notLoading');
- })
- .catch(error => {
- store.dispatch('notLoading');
- return store.dispatch('handleApiError', { error, reloadOnReconnect: true });
- });
- });
-}
-
-function _prepPracticeQuizContentPreview(store, classId, contentId) {
- return ContentNodeResource.fetchModel({ id: contentId }).then(
- contentNode => {
- const assessmentMetadata = contentNode.assessmentmetadata || {};
- store.commit('SET_TOOLBAR_ROUTE', {});
- store.commit('examCreation/SET_CURRENT_CONTENT_NODE', { ...contentNode });
- store.commit('examCreation/SET_PREVIEW_STATE', {
- questions: assessmentMetadata.assessment_item_ids,
- completionData: assessmentMetadata.mastery_model,
- });
- store.commit('SET_PAGE_NAME', PageNames.EXAM_CREATION_PRACTICE_QUIZ_PREVIEW);
- return contentNode;
- },
- error => {
- return store.dispatch('handleApiError', { error, reloadOnReconnect: true });
- }
- );
-}
-function _prepExamContentPreview(store, classId, contentId) {
- return ContentNodeResource.fetchModel({ id: contentId }).then(
- contentNode => {
- const assessmentMetadata = contentNode.assessmentmetadata || {};
- store.commit('SET_TOOLBAR_ROUTE', {});
- store.commit('examCreation/SET_CURRENT_CONTENT_NODE', { ...contentNode });
- store.commit('examCreation/SET_PREVIEW_STATE', {
- questions: assessmentMetadata.assessment_item_ids,
- completionData: assessmentMetadata.mastery_model,
- });
- store.commit('SET_PAGE_NAME', PageNames.EXAM_CREATION_PREVIEW);
- return contentNode;
- },
- error => {
- return store.dispatch('handleApiError', { error, reloadOnReconnect: true });
- }
- );
-}
-
-export function showExamCreationSearchPage(store, params, query = {}) {
- return store.dispatch('loading').then(() => {
- let kinds;
- if (query.kind) {
- kinds = [query.kind];
- } else {
- kinds = [ContentNodeKinds.EXERCISE, ContentNodeKinds.TOPIC];
- }
-
- store.commit('SET_TOOLBAR_ROUTE', {
- name: PageNames.EXAM_CREATION_ROOT,
- params: {},
- });
-
- return ContentNodeSearchResource.fetchCollection({
- getParams: {
- search: params.searchTerm,
- kind_in: kinds,
- ...pickBy({ channel_id: query.channel }),
- },
- }).then(results => {
- return filterAndAnnotateContentList(results.results).then(contentList => {
- const searchResults = {
- ...results,
- results: contentList,
- content_kinds: results.content_kinds.filter(kind =>
- [ContentNodeKinds.TOPIC, ContentNodeKinds.EXERCISE].includes(kind)
- ),
- contentIdsFetched: uniq(results.results.map(({ content_id }) => content_id)),
- };
- return showExamCreationPage(store, {
- classId: params.classId,
- contentList: contentList,
- pageName: PageNames.EXAM_CREATION_SEARCH,
- searchResults,
- });
- });
- });
- });
-}
-
-const creationPages = [
- PageNames.EXAM_CREATION_ROOT,
- PageNames.EXAM_CREATION_TOPIC,
- PageNames.EXAM_CREATION_PREVIEW,
- PageNames.EXAM_CREATION_SEARCH,
- PageNames.EXAM_CREATION_BOOKMARKS,
- PageNames.EXAM_CREATION_BOOKMARKS_MAIN,
-];
-
-export function showExamCreationQuestionSelectionPage(store, toRoute, fromRoute) {
- // if we got here from somewhere else, start over
- if (!creationPages.includes(fromRoute.name)) {
- router.replace({
- name: PageNames.EXAM_CREATION_ROOT,
- params: toRoute.params,
- });
- }
- store.commit('SET_PAGE_NAME', 'EXAM_CREATION_QUESTION_SELECTION');
- store.commit('SET_TOOLBAR_ROUTE', { name: fromRoute.name, params: fromRoute.params });
- store.dispatch('examCreation/updateSelectedQuestions');
- store.dispatch('notLoading');
-}
diff --git a/kolibri/plugins/coach/assets/src/modules/examCreation/index.js b/kolibri/plugins/coach/assets/src/modules/examCreation/index.js
deleted file mode 100644
index 2e829077c1b..00000000000
--- a/kolibri/plugins/coach/assets/src/modules/examCreation/index.js
+++ /dev/null
@@ -1,113 +0,0 @@
-import Vue from 'kolibri.lib.vue';
-import * as actions from './actions';
-
-function getRandomInt() {
- return Math.floor(Math.random() * 1000);
-}
-
-function defaultState() {
- return {
- title: '',
- numberOfQuestions: 10,
- seed: getRandomInt(), // consistent seed is used for question selection
- contentList: [],
- bookmarksList: [],
- selectedExercises: {},
- availableQuestions: 0,
- searchResults: {
- channel_ids: [],
- content_kinds: [],
- results: [],
- total_results: 0,
- contentIdsFetched: [], // to account for topics without exercises that are filtered out
- },
- ancestors: [],
- examsModalSet: false,
- currentContentNode: {},
- preview: {
- completionData: null,
- questions: null,
- },
- selectedQuestions: [],
- learnersSeeFixedOrder: false,
- loadingNewQuestions: false,
- };
-}
-
-export default {
- namespaced: true,
- state: defaultState(),
- actions,
- getters: {
- numRemainingSearchResults(state) {
- return state.searchResults.total_results - state.searchResults.contentIdsFetched.length;
- },
- },
- mutations: {
- SET_STATE(state, payload) {
- Object.assign(state, payload);
- },
- RESET_STATE(state) {
- Object.assign(state, defaultState());
- },
- SET_TITLE(state, title) {
- state.title = title;
- },
- LOADING_NEW_QUESTIONS(state, value) {
- state.loadingNewQuestions = value;
- },
- SET_NUMBER_OF_QUESTIONS(state, numberOfQuestions) {
- state.numberOfQuestions = numberOfQuestions;
- },
- RANDOMIZE_SEED(state) {
- state.seed = getRandomInt();
- },
- SET_FIXED_ORDER(state, value) {
- state.learnersSeeFixedOrder = value;
- },
- SET_SELECTED_QUESTIONS(state, questions) {
- state.selectedQuestions = questions;
- },
- SET_CONTENT_LIST(state, contentList) {
- state.contentList = contentList;
- },
- SET_BOOKMARKS_LIST(state, bookmarksList) {
- state.bookmarksList = bookmarksList;
- },
- ADD_TO_SELECTED_EXERCISES(state, exercises) {
- state.selectedExercises = Object.assign(
- {},
- state.selectedExercises,
- ...exercises.map(exercise => ({ [exercise.id]: exercise }))
- );
- },
- REMOVE_FROM_SELECTED_EXERCISES(state, exercises) {
- exercises.forEach(exercise => {
- Vue.delete(state.selectedExercises, exercise.id);
- });
- },
- UPDATE_SELECTED_EXERCISES(state, exercises) {
- exercises.forEach(newExercise => {
- Vue.set(state.selectedExercises, newExercise.id, newExercise);
- });
- },
- SET_AVAILABLE_QUESTIONS(state, availableQuestions) {
- state.availableQuestions = availableQuestions;
- },
- SET_ANCESTORS(state, ancestors) {
- state.ancestors = [...ancestors];
- },
- SET_SEARCH_RESULTS(state, searchResults) {
- state.searchResults = searchResults;
- },
- SET_EXAMS_MODAL(state, modalName) {
- state.examsModalSet = modalName;
- },
- SET_CURRENT_CONTENT_NODE(state, contentNode) {
- state.currentContentNode = contentNode;
- },
- SET_PREVIEW_STATE(state, previewState) {
- state.preview = previewState;
- },
- },
-};
diff --git a/kolibri/plugins/coach/assets/src/modules/pluginModule.js b/kolibri/plugins/coach/assets/src/modules/pluginModule.js
index 135dbac8263..318c7576c20 100644
--- a/kolibri/plugins/coach/assets/src/modules/pluginModule.js
+++ b/kolibri/plugins/coach/assets/src/modules/pluginModule.js
@@ -1,8 +1,7 @@
import { ClassroomResource } from 'kolibri.resources';
import logger from 'kolibri.lib.logging';
-import { pageNameToModuleMap, PageNames } from '../constants';
+import { pageNameToModuleMap } from '../constants';
import { LessonsPageNames } from '../constants/lessonsConstants';
-import examCreation from './examCreation';
import examReportDetail from './examReportDetail';
import exerciseDetail from './exerciseDetail';
import groups from './groups';
@@ -102,9 +101,6 @@ export default {
) {
return store.dispatch('lessonSummary/resetLessonSummaryState');
}
- if (toRoute.name === PageNames.EXAMS) {
- return store.dispatch('examCreation/resetExamCreationState');
- }
const moduleName = pageNameToModuleMap[fromRoute.name];
if (moduleName) {
store.commit(`${moduleName}/RESET_STATE`);
@@ -136,7 +132,6 @@ export default {
modules: {
classSummary,
coachNotifications,
- examCreation,
examReportDetail,
exerciseDetail,
groups,
diff --git a/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js b/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js
index ca05380ff3a..365c6be98f6 100644
--- a/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js
+++ b/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js
@@ -1,26 +1,10 @@
-import store from 'kolibri.coreVue.vuex.store';
import { PageNames } from '../constants';
-import {
- showExamCreationTopicPage,
- showExamCreationBookmarksPage,
- showExamCreationAllBookmarks,
- showExamCreationSearchPage,
- showExamCreationQuestionSelectionPage,
- showExamCreationPreviewPage,
- showPracticeQuizCreationRootPage,
- showPracticeQuizCreationTopicPage,
- showPracticeQuizCreationPreviewPage,
-} from '../modules/examCreation/handlers';
-import CreatePracticeQuizPage from '../views/plan/CreateExamPage/CreatePracticeQuizPage.vue';
import CreateExamPage from '../views/plan/CreateExamPage';
-import CreateExamPreview from '../views/plan/CreateExamPage/CreateExamPreview.vue';
import SectionEditor from '../views/plan/CreateExamPage/SectionEditor.vue';
import ResourceSelection from '../views/plan/CreateExamPage/ResourceSelection.vue';
import ReplaceQuestions from '../views/plan/CreateExamPage/ReplaceQuestions.vue';
-import PlanQuizPreviewPage from '../views/plan/PlanQuizPreviewPage';
import CoachExamsPage from '../views/plan/CoachExamsPage';
import QuizSummaryPage from '../views/plan/QuizSummaryPage';
-import PlanPracticeQuizPreviewPage from '../views/plan/CreateExamPage/PlanPracticeQuizPreviewPage';
export default [
{
@@ -61,78 +45,6 @@ export default [
},
],
},
- {
- name: PageNames.EXAM_CREATION_PRACTICE_QUIZ,
- path: '/:classId/plan/quizzes/new/practice_quiz',
- component: CreatePracticeQuizPage,
- handler: toRoute => {
- showPracticeQuizCreationRootPage(store, toRoute.params);
- },
- },
- {
- name: PageNames.EXAM_CREATION_SELECT_PRACTICE_QUIZ_TOPIC,
- path: '/:classId/plan/quizzes/new/practice_quiz/topic/:topicId',
- component: CreatePracticeQuizPage,
- handler: toRoute => {
- showPracticeQuizCreationTopicPage(store, toRoute.params);
- },
- },
- {
- name: PageNames.EXAM_CREATION_TOPIC,
- path: '/:classId/plan/quizzes/new/topic/:topicId',
- component: CreateExamPage,
- handler: toRoute => {
- showExamCreationTopicPage(store, toRoute.params);
- },
- },
- {
- name: PageNames.EXAM_CREATION_BOOKMARKS,
- path: '/:classId/plan/quizzes/new/bookmark/:topicId',
- component: CreateExamPage,
- handler: toRoute => {
- showExamCreationBookmarksPage(store, toRoute.params);
- },
- },
- {
- name: PageNames.EXAM_CREATION_BOOKMARKS_MAIN,
- path: '/:classId/plan/quizzes/new/bookmarks',
- component: CreateExamPage,
- handler: toRoute => {
- showExamCreationAllBookmarks(store, toRoute.params);
- },
- },
- {
- name: PageNames.EXAM_CREATION_SEARCH,
- path: '/:classId/plan/quizzes/new/search/:searchTerm',
- component: CreateExamPage,
- handler: toRoute => {
- showExamCreationSearchPage(store, toRoute.params, toRoute.query);
- },
- },
- {
- name: PageNames.EXAM_CREATION_QUESTION_SELECTION,
- path: '/:classId/plan/quizzes/new/finalize',
- component: CreateExamPreview,
- handler: (toRoute, fromRoute) => {
- showExamCreationQuestionSelectionPage(store, toRoute, fromRoute);
- },
- },
- {
- name: PageNames.EXAM_CREATION_PRACTICE_QUIZ_PREVIEW,
- path: '/:classId/plan/quizzes/new/practice_quiz/preview/',
- component: PlanPracticeQuizPreviewPage,
- handler: toRoute => {
- showPracticeQuizCreationPreviewPage(store, toRoute.params);
- },
- },
- {
- name: PageNames.EXAM_CREATION_PREVIEW,
- path: '/:classId/plan/quizzes/new/preview/',
- component: PlanQuizPreviewPage,
- handler: (toRoute, fromRoute) => {
- showExamCreationPreviewPage(store, toRoute.params, fromRoute);
- },
- },
{
name: QuizSummaryPage.name,
path: '/:classId/plan/quizzes/:quizId',
diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/AssessmentQuestionListItem.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/AssessmentQuestionListItem.vue
index 84de402eb5f..a7796d46e1d 100644
--- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/AssessmentQuestionListItem.vue
+++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/AssessmentQuestionListItem.vue
@@ -63,10 +63,6 @@
type: Boolean,
required: true,
},
- questionNumberOfExercise: {
- type: Number,
- default: null,
- },
isSelected: {
type: Boolean,
required: true,
@@ -97,13 +93,7 @@
if (!this.exerciseName) {
return this.coreString('resourceNotFoundOnDevice');
}
- if (this.questionNumberOfExercise === undefined || this.questionNumberOfExercise === null) {
- return this.exerciseName;
- }
- return this.coachString('nthExerciseName', {
- name: this.exerciseName,
- number: this.questionNumberOfExercise,
- });
+ return this.exerciseName;
},
focusRing() {
return this.$computedClass({ ':focus': this.$coreOutline });
diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateExamPreview.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateExamPreview.vue
deleted file mode 100644
index bc12e14660b..00000000000
--- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateExamPreview.vue
+++ /dev/null
@@ -1,326 +0,0 @@
-
-
- {{ $tr('preview') }}
- {{ coachString('detailsLabel') }}
-
- {{ coachString('questionOrderLabel') }}
-
-
- {{ $tr('questionsLabel') }}
-
-
- {{ $tr('selectPracticeQuizLabel') }}
-