diff --git a/kolibri/plugins/coach/assets/src/app.js b/kolibri/plugins/coach/assets/src/app.js index ef8484f5b37..c9ec690ceb4 100644 --- a/kolibri/plugins/coach/assets/src/app.js +++ b/kolibri/plugins/coach/assets/src/app.js @@ -8,12 +8,6 @@ import useSnackbar from 'kolibri.coreVue.composables.useSnackbar'; import { PageNames } from './constants'; import routes from './routes'; import pluginModule from './modules/pluginModule'; -import { LessonsPageNames } from './constants/lessonsConstants'; -import LessonEditDetailsPage from './views/plan/LessonEditDetailsPage'; -import GroupsPage from './views/plan/GroupsPage'; -import GroupMembersPage from './views/plan/GroupMembersPage'; -import GroupEnrollPage from './views/plan/GroupEnrollPage'; -import pages from './views/reports/allReportsPages'; import HomeActivityPage from './views/home/HomeActivityPage'; function _channelListState(data) { @@ -69,8 +63,8 @@ class CoachToolsModule extends KolibriApp { PageNames.QUIZ_SELECT_PRACTICE_QUIZ, PageNames.QUIZ_SELECT_RESOURCES, PageNames.QUIZ_SECTION_ORDER, - PageNames.BOOK_MARKED_RESOURCES, - pages.ReportsQuizLearnerPage.name, + PageNames.QUIZ_BOOK_MARKED_RESOURCES, + PageNames.QUIZ_LEARNER_REPORT, ]; // If we're navigating to the same page for a quiz summary page, don't set loading if ( @@ -101,21 +95,21 @@ class CoachToolsModule extends KolibriApp { if ( to.name && [ - PageNames.EXAMS, - LessonsPageNames.PLAN_LESSONS_ROOT, - LessonsPageNames.LESSON_CREATION_ROOT, - LessonsPageNames.SUMMARY, - LessonEditDetailsPage.name, - LessonsPageNames.SELECTION_ROOT, - LessonsPageNames.SELECTION, - LessonsPageNames.SELECTION_SEARCH, - LessonsPageNames.LESSON_SELECTION_BOOKMARKS, - LessonsPageNames.LESSON_SELECTION_BOOKMARKS_MAIN, - LessonsPageNames.SELECTION_CONTENT_PREVIEW, - LessonsPageNames.RESOURCE_CONTENT_PREVIEW, - GroupsPage.name, - GroupMembersPage.name, - GroupEnrollPage.name, + PageNames.EXAMS_ROOT, + PageNames.LESSONS_ROOT, + PageNames.LESSON_CREATION_ROOT, + PageNames.LESSON_SUMMARY, + PageNames.LESSON_EDIT_DETAILS, + PageNames.LESSON_RESOURCE_SELECTION_ROOT, + PageNames.LESSON_RESOURCE_SELECTION, + PageNames.LESSON_RESOURCE_SELECTION_SEARCH, + PageNames.LESSON_SELECTION_BOOKMARKS, + PageNames.LESSON_SELECTION_BOOKMARKS_MAIN, + PageNames.LESSON_RESOURCE_SELECTION_CONTENT_PREVIEW, + PageNames.RESOURCE_CONTENT_PREVIEW, + PageNames.GROUP_SUMMARY, + PageNames.GROUP_ENROLL, + PageNames.GROUPS_ROOT, PageNames.HOME_PAGE, HomeActivityPage.name, ].includes(to.name) diff --git a/kolibri/plugins/coach/assets/src/composables/useLessons.js b/kolibri/plugins/coach/assets/src/composables/useLessons.js index 20725e865b4..cfc2ead37a2 100644 --- a/kolibri/plugins/coach/assets/src/composables/useLessons.js +++ b/kolibri/plugins/coach/assets/src/composables/useLessons.js @@ -1,7 +1,7 @@ import { ref } from 'kolibri.lib.vueCompositionApi'; import { LearnerGroupResource } from 'kolibri.resources'; import useUser from 'kolibri.coreVue.composables.useUser'; -import { LessonsPageNames } from '../constants/lessonsConstants'; +import { PageNames } from '../constants'; // Place outside the function to keep the state const lessonsAreLoading = ref(false); @@ -37,7 +37,7 @@ export function useLessons() { return Promise.all(loadRequirements).then( ([learnerGroups]) => { store.commit('lessonsRoot/SET_LEARNER_GROUPS', learnerGroups); - store.commit('SET_PAGE_NAME', LessonsPageNames.PLAN_LESSONS_ROOT); + store.commit('SET_PAGE_NAME', PageNames.LESSONS_ROOT); setLessonsLoading(false); }, error => { diff --git a/kolibri/plugins/coach/assets/src/constants/index.js b/kolibri/plugins/coach/assets/src/constants/index.js index 3955a78f834..acaf63f8d16 100644 --- a/kolibri/plugins/coach/assets/src/constants/index.js +++ b/kolibri/plugins/coach/assets/src/constants/index.js @@ -1,45 +1,67 @@ -import { LessonsPageNames } from './lessonsConstants'; - export const PageNames = { + /** Class Summary */ HOME_PAGE: 'HomePage', // make sure this matches the Coach 'Home' page name - REPORTS_PAGE: 'REPORTS_PAGE', - PLAN_PAGE: 'PLAN_PAGE', - COACH_CLASS_LIST_PAGE: 'COACH_CLASS_LIST_PAGE', - NEW_COACH_PAGES: 'NEW_COACH_PAGES', - EXAMS: 'EXAMS', EXAM_CREATION_ROOT: 'EXAM_CREATION_ROOT', - /** Newly added routes */ + /** Exams and quizzes */ + EXAMS_ROOT: 'EXAMS_ROOT', + EXAM_SUMMARY: 'EXAM_SUMMARY', + QUIZ_PREVIEW: 'QUIZ_PREVIEW', + QUIZ_LEARNER_PAGE_ROOT: 'QUIZ_LEARNER_PAGE_ROOT', + QUIZ_LEARNER_REPORT: 'QUIZ_LEARNER_REPORT', QUIZ_SECTION_EDITOR: 'QUIZ_SECTION_EDITOR', QUIZ_REPLACE_QUESTIONS: 'QUIZ_REPLACE_QUESTIONS', QUIZ_SELECT_RESOURCES: 'QUIZ_SELECT_RESOURCES', QUIZ_SELECT_PRACTICE_QUIZ: 'QUIZ_SELECT_PRACTICE_QUIZ', QUIZ_SECTION_ORDER: 'QUIZ_SECTION_ORDER', - BOOK_MARKED_RESOURCES: 'BOOK_MARKED_RESOURCES', + QUIZ_QUESTION_PAGE_ROOT: 'QUIZ_QUESTION_PAGE_ROOT', + QUIZ_QUESTION_REPORT: 'QUIZ_QUESTION_REPORT', + QUIZ_BOOK_MARKED_RESOURCES: 'QUIZ_BOOK_MARKED_RESOURCES', - EXAM_REPORT: 'EXAM_REPORT', - EXAM_REPORT_DETAIL: 'EXAM_REPORT_DETAIL', - EXAM_REPORT_DETAIL_ROOT: 'EXAM_REPORT_DETAIL_ROOT', - REPORTS_LESSON_EXERCISE_LEARNER_PAGE_ROOT: 'REPORTS_LESSON_EXERCISE_LEARNER_PAGE_ROOT', - REPORTS_GROUP_REPORT_LESSON_EXERCISE_LEARNER_PAGE_ROOT: - 'REPORTS_GROUP_REPORT_LESSON_EXERCISE_LEARNER_PAGE_ROOT', - REPORTS_LEARNER_ACTIVITY_EXERCISE_PAGE_ROOT: 'REPORTS_LEARNER_ACTIVITY_EXERCISE_PAGE_ROOT', - REPORTS_LEARNER_REPORT_LESSON_EXERCISE_PAGE_ROOT: - 'REPORTS_LEARNER_REPORT_LESSON_EXERCISE_PAGE_ROOT', - REPORTS_LESSON_LEARNER_EXERCISE_PAGE_ROOT: 'REPORTS_LESSON_LEARNER_EXERCISE_PAGE_ROOT', - REPORTS_GROUP_LEARNER_REPORT_QUIZ_PAGE_ROOT: 'REPORTS_GROUP_LEARNER_REPORT_QUIZ_PAGE_ROOT', - REPORTS_GROUP_REPORT_QUIZ_LEARNER_PAGE_ROOT: 'REPORTS_GROUP_REPORT_QUIZ_LEARNER_PAGE_ROOT', - REPORTS_LEARNER_REPORT_QUIZ_PAGE_ROOT: 'REPORTS_LEARNER_REPORT_QUIZ_PAGE_ROOT', - REPORTS_QUIZ_LEARNER_PAGE_ROOT: 'REPORTS_QUIZ_LEARNER_PAGE_ROOT', - REPORTS_LESSON_EXERCISE_QUESTION_PAGE_ROOT: 'REPORTS_LESSON_EXERCISE_QUESTION_PAGE_ROOT', - REPORTS_GROUP_REPORT_LESSON_EXERCISE_QUESTION_PAGE_ROOT: - 'REPORTS_GROUP_REPORT_LESSON_EXERCISE_QUESTION_PAGE_ROOT', - REPORTS_GROUP_REPORT_QUIZ_QUESTION_PAGE_ROOT: 'REPORTS_GROUP_REPORT_QUIZ_QUESTION_PAGE_ROOT', - REPORTS_QUIZ_QUESTION_PAGE_ROOT: 'REPORTS_QUIZ_QUESTION_PAGE_ROOT', + /* Lessons */ + LESSONS_ROOT: 'LESSONS_ROOT', + LESSONS_ROOT_BETTER: 'LESSONS_ROOT_BETTER', + LESSON_SUMMARY: 'LESSON_SUMMARY', + LESSON_CREATION_ROOT: 'LESSON_CREATION_ROOT', + LESSON_CREATION_ROOT_BETTER: 'LESSON_CREATION_ROOT_BETTER', + RESOURCE_CONTENT_PREVIEW: 'RESOURCE_CONTENT_PREVIEW', // exclusively a route name + LESSON_RESOURCE_SELECTION_ROOT: 'LESSON_RESOURCE_SELECTION_ROOT', + LESSON_RESOURCE_SELECTION: 'LESSON_RESOURCE_SELECTION', + LESSON_RESOURCE_SELECTION_SEARCH: 'LESSON_RESOURCE_SELECTION_SEARCH', + LESSON_RESOURCE_SELECTION_CONTENT_PREVIEW: 'LESSON_RESOURCE_SELECTION_CONTENT_PREVIEW', // exclusively a route name + LESSON_CONTENT_PREVIEW: 'LESSON_CONTENT_PREVIEW', + LESSON_SELECTION_BOOKMARKS: 'LESSON_SELECTION_BOOKMARKS', + LESSON_SELECTION_BOOKMARKS_MAIN: 'LESSON_SELECTION_BOOKMARKS_MAIN', LESSON_EDIT_DETAILS: 'LESSON_EDIT_DETAILS', + LESSON_EDIT_DETAILS_BETTER: 'LESSON_EDIT_DETAILS_BETTER', LESSON_SELECT_RESOURCES: 'LESSON_SELECT_RESOURCES', LESSON_PREVIEW_SELECTED_RESOURCES: 'LESSON_PREVIEW_SELECTED_RESOURCES', LESSON_PREVIEW_RESOURCE: 'LESSON_PREVIEW_RESOURCE', + LESSON_LEARNER_REPORT: 'LESSON_LEARNER_REPORT', + LESSON_RESOURCE_LEARNERS_REPORT: 'LESSON_RESOURCE_LEARNERS_REPORT', + LESSON_EXERCISE_LEARNER_PAGE_ROOT: 'LESSON_EXERCISE_LEARNER_PAGE_ROOT', + LESSON_EXERCISE_LEARNERS_REPORT: 'LESSON_EXERCISE_LEARNERS_REPORT', + LESSON_EXERCISE_LEARNER_REPORT: 'LESSON_EXERCISE_LEARNER_REPORT', + LESSON_EXERCISE_QUESTIONS_REPORT: 'LESSON_EXERCISE_QUESTIONS_REPORT', + LESSON_EXERCISE_QUESTION_PAGE_ROOT: 'LESSON_EXERCISE_QUESTION_PAGE_ROOT', + LESSON_EXERCISE_QUESTION_REPORT: 'LESSON_EXERCISE_QUESTION_REPORT', + LESSON_LEARNER_EXERCISE_PAGE_ROOT: 'LESSON_LEARNER_EXERCISE_PAGE_ROOT', + LESSON_LEARNER_EXERCISE_REPORT: 'LESSON_LEARNER_EXERCISE_REPORT', + + /* Learners */ + LEARNERS_ROOT: 'LEARNERS_ROOT', + LEARNER_SUMMARY: 'LEARNER_SUMMARY', + LEARNER_LESSON_REPORT: 'LEARNER_LESSON_REPORT', + + /** Groups */ + GROUPS_ROOT: 'GROUPS_ROOT', + GROUP_SUMMARY: 'GROUP_SUMMARY', + GROUP_ENROLL: 'GROUP_ENROLL', + GROUP_EXAM_SUMMARY: 'GROUP_EXAM_SUMMARY', + GROUP_LESSON_SUMMARY: 'GROUP_LESSON_SUMMARY', + GROUP_LESSON_LEARNER: 'GROUP_LESSON_LEARNER', + GROUP_LESSON_EXERCISE_QUESTIONS_REPORT: 'GROUP_LESSON_EXERCISE_QUESTIONS_REPORT', + GROUP_LESSON_EXERCISE_LEARNER_REPORT: 'GROUP_LESSON_EXERCISE_LEARNER_REPORT', }; export const GroupModals = { @@ -57,9 +79,7 @@ export const ViewMoreButtonStates = { }; export const pageNameToModuleMap = { - [PageNames.EXAM_REPORT_DETAIL]: 'examReportDetail', - [LessonsPageNames.PLAN_LESSONS_ROOT]: 'lessonsRoot', - [LessonsPageNames.RESOURCE_USER_REPORT]: 'exerciseDetail', + [PageNames.LESSONS_ROOT]: 'lessonsRoot', // Omitting modules for resource selection, exam creation, and preview to prevent // default module state resetting behavior. }; diff --git a/kolibri/plugins/coach/assets/src/constants/lastPagesConstants.js b/kolibri/plugins/coach/assets/src/constants/lastPagesConstants.js index 086763be11e..a0d24300627 100644 --- a/kolibri/plugins/coach/assets/src/constants/lastPagesConstants.js +++ b/kolibri/plugins/coach/assets/src/constants/lastPagesConstants.js @@ -1,7 +1,6 @@ export const LastPages = { HOME_PAGE: 'homepage', HOME_ACTIVITY: 'homeactivity', - GROUP_ACTIVITY: 'groupactivity', LEARNER_ACTIVITY: 'learneractivity', EXERCISE_LEARNER_LIST: 'exerciselearnerlist', EXERCISE_LEARNER_LIST_BY_GROUPS: 'exerciselearnerlistbygroups', diff --git a/kolibri/plugins/coach/assets/src/constants/lessonsConstants.js b/kolibri/plugins/coach/assets/src/constants/lessonsConstants.js index ea7d512759e..2a9dab0454d 100644 --- a/kolibri/plugins/coach/assets/src/constants/lessonsConstants.js +++ b/kolibri/plugins/coach/assets/src/constants/lessonsConstants.js @@ -1,21 +1,3 @@ -export const LessonsPageNames = { - PLAN_LESSONS_ROOT: 'PLAN_LESSONS_ROOT', - PLAN_LESSONS_ROOT_BETTER: 'PLAN_LESSONS_ROOT_BETTER', - LESSON_CREATION_ROOT: 'LESSON_CREATION_ROOT', - LESSON_CREATION_ROOT_BETTER: 'LESSON_CREATION_ROOT_BETTER', - SUMMARY: 'SUMMARY', - RESOURCE_USER_REPORT: 'RESOURCE_USER_REPORT', - RESOURCE_USER_REPORT_ROOT: 'RESOURCE_USER_REPORT_ROOT', - RESOURCE_CONTENT_PREVIEW: 'RESOURCE_CONTENT_PREVIEW', // exclusively a route name - SELECTION_ROOT: 'SELECTION_ROOT', - SELECTION: 'SELECTION', - SELECTION_SEARCH: 'SELECTION_SEARCH', - SELECTION_CONTENT_PREVIEW: 'SELECTION_CONTENT_PREVIEW', // exclusively a route name - CONTENT_PREVIEW: 'CONTENT_PREVIEW', - LESSON_SELECTION_BOOKMARKS: 'LESSON_SELECTION_BOOKMARKS', - LESSON_SELECTION_BOOKMARKS_MAIN: 'LESSON_SELECTION_BOOKMARKS_MAIN', -}; - export const CollectionTypes = { LEARNERGROUP: 'learnergroup', ADHOCLEARNERSGROUP: 'adhoclearnersgroup', diff --git a/kolibri/plugins/coach/assets/src/constants/tabsConstants.js b/kolibri/plugins/coach/assets/src/constants/tabsConstants.js index 2b473c7f302..e185f164f62 100644 --- a/kolibri/plugins/coach/assets/src/constants/tabsConstants.js +++ b/kolibri/plugins/coach/assets/src/constants/tabsConstants.js @@ -6,13 +6,6 @@ export const ReportsTabs = { LEARNERS: 'tabLearners', }; -export const PLAN_TABS_ID = 'coachPlan'; -export const PlanTabs = { - LESSONS: 'tabLessons', - QUIZZES: 'tabQuizzes', - GROUPS: 'tabGroups', -}; - export const REPORTS_GROUP_TABS_ID = 'coachPlanGroup'; export const ReportsGroupTabs = { REPORTS: 'tabReports', diff --git a/kolibri/plugins/coach/assets/src/modules/coachNotifications/gettersUtils.js b/kolibri/plugins/coach/assets/src/modules/coachNotifications/gettersUtils.js index 3ef5e074e4c..014a5ee2275 100644 --- a/kolibri/plugins/coach/assets/src/modules/coachNotifications/gettersUtils.js +++ b/kolibri/plugins/coach/assets/src/modules/coachNotifications/gettersUtils.js @@ -1,9 +1,9 @@ import find from 'lodash/find'; import { CollectionTypes } from '../../constants/lessonsConstants'; +import { PageNames } from '../../constants'; // Just makes an params object that should work with all the paths. // It has extra params that may not be used by some routes. -// See reportRoutes.js for details on param naming. function makeParams(notification) { return { groupId: notification.collection.id, @@ -28,15 +28,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: true, isWholeClass: false, }, - value: 'ReportsGroupReportLessonExerciseLearnerListPage', - }, - { - key: { - object: 'NonExercise', - isMultiple: true, - isWholeClass: false, - }, - value: 'ReportsGroupReportLessonResourceLearnerListPage', + value: PageNames.GROUP_LESSON_EXERCISE_LEARNER_REPORT, }, { key: { @@ -44,7 +36,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: true, isWholeClass: false, }, - value: 'ReportsGroupReportLessonPage', + value: PageNames.GROUP_LESSON_SUMMARY, }, { key: { @@ -52,7 +44,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: true, isWholeClass: false, }, - value: 'ReportsGroupReportQuizLearnerListPage', + value: PageNames.GROUP_EXAM_SUMMARY, }, { key: { @@ -60,7 +52,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: true, isWholeClass: true, }, - value: 'ReportsLessonExerciseLearnerListPage', + value: PageNames.LESSON_EXERCISE_LEARNERS_REPORT, }, { key: { @@ -68,7 +60,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: true, isWholeClass: true, }, - value: 'ReportsLessonResourceLearnerListPage', + value: PageNames.LESSON_RESOURCE_LEARNERS_REPORT, }, { key: { @@ -76,7 +68,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: true, isWholeClass: true, }, - value: 'ReportsLessonLearnerListPage', + value: PageNames.LESSON_SUMMARY, }, { key: { @@ -84,15 +76,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: true, isWholeClass: true, }, - value: 'ReportsQuizLearnerListPage', - }, - { - key: { - object: 'Exercise', - isMultiple: false, - isWholeClass: false, - }, - value: 'ReportsGroupReportLessonExerciseLearnerPage', + value: PageNames.EXAM_SUMMARY, }, { key: { @@ -100,7 +84,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: false, isWholeClass: false, }, - value: 'ReportsLessonLearnerPage', + value: PageNames.LEARNER_LESSON_REPORT, }, { key: { @@ -108,7 +92,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: false, isWholeClass: false, }, - value: 'ReportsLearnerReportQuizPage', + value: PageNames.QUIZ_LEARNER_PAGE_ROOT, }, { key: { @@ -116,7 +100,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: false, isWholeClass: true, }, - value: 'REPORTS_LESSON_EXERCISE_LEARNER_PAGE_ROOT', + value: PageNames.LESSON_EXERCISE_LEARNER_PAGE_ROOT, }, { key: { @@ -124,7 +108,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: false, isWholeClass: true, }, - value: 'ReportsLessonLearnerPage', + value: PageNames.LEARNER_LESSON_REPORT, }, { key: { @@ -132,7 +116,7 @@ const pageNameToNotificationPropsMap = [ isMultiple: false, isWholeClass: true, }, - value: 'ReportsQuizLearnerPage', + value: PageNames.QUIZ_LEARNER_PAGE_ROOT, }, ]; diff --git a/kolibri/plugins/coach/assets/src/modules/lessonResources/handlers.js b/kolibri/plugins/coach/assets/src/modules/lessonResources/handlers.js index 01cace93e85..f431a639c7c 100644 --- a/kolibri/plugins/coach/assets/src/modules/lessonResources/handlers.js +++ b/kolibri/plugins/coach/assets/src/modules/lessonResources/handlers.js @@ -8,7 +8,7 @@ import { ContentNodeKinds } from 'kolibri.coreVue.vuex.constants'; import chunk from 'lodash/chunk'; import useUser from 'kolibri.coreVue.composables.useUser'; import { get } from '@vueuse/core'; -import { LessonsPageNames } from '../../constants/lessonsConstants'; +import { PageNames } from '../../constants'; async function showResourceSelectionPage(store, params) { const { @@ -74,13 +74,13 @@ async function showResourceSelectionPage(store, params) { store.commit('lessonSummary/resources/SET_SEARCH_RESULTS', params.searchResults); } store.commit('SET_PAGE_NAME', pageName); - if (pageName === LessonsPageNames.SELECTION_SEARCH) { + if (pageName === PageNames.LESSON_RESOURCE_SELECTION_SEARCH) { store.commit('SET_TOOLBAR_ROUTE', { - name: LessonsPageNames.SELECTION_ROOT, + name: PageNames.LESSON_RESOURCE_SELECTION_ROOT, }); } else { store.commit('SET_TOOLBAR_ROUTE', { - name: LessonsPageNames.SUMMARY, + name: PageNames.LESSON_SUMMARY, }); } return setResourceCachePromise.then(() => { @@ -107,7 +107,7 @@ export function showLessonResourceSelectionRootPage(store, params) { classId: params.classId, lessonId: params.lessonId, contentList: channelContentList, - pageName: LessonsPageNames.SELECTION_ROOT, + pageName: PageNames.LESSON_RESOURCE_SELECTION_ROOT, descendantCounts, }); }, @@ -130,7 +130,7 @@ export function showLessonResourceSelectionTopicPage(store, params) { classId: params.classId, lessonId: params.lessonId, contentList: childNodes, - pageName: LessonsPageNames.SELECTION, + pageName: PageNames.LESSON_RESOURCE_SELECTION, descendantCounts, ancestors: [...topicNode.ancestors, topicNode], }); @@ -150,7 +150,7 @@ export function showLessonResourceBookmarks(store, params) { classId: params.classId, lessonId: params.lessonId, bookmarksList: childNodes, - pageName: LessonsPageNames.SELECTION, + pageName: PageNames.LESSON_RESOURCE_SELECTION, ancestors: [...topicNode.ancestors, topicNode], }); }); @@ -222,7 +222,7 @@ export async function showLessonSelectionContentPreview(store, params, query = { const { searchTerm, ...otherQueryParams } = query; if (searchTerm) { store.commit('SET_TOOLBAR_ROUTE', { - name: LessonsPageNames.SELECTION_SEARCH, + name: PageNames.LESSON_RESOURCE_SELECTION_SEARCH, params: { searchTerm, }, @@ -230,7 +230,7 @@ export async function showLessonSelectionContentPreview(store, params, query = { }); } else { store.commit('SET_TOOLBAR_ROUTE', { - name: LessonsPageNames.SELECTION, + name: PageNames.LESSON_RESOURCE_SELECTION, params: { topicId: contentNode.parent, }, @@ -273,7 +273,7 @@ function _prepLessonContentPreview(store, classId, lessonId, contentId) { }); } - store.commit('SET_PAGE_NAME', LessonsPageNames.CONTENT_PREVIEW); + store.commit('SET_PAGE_NAME', PageNames.LESSON_CONTENT_PREVIEW); return contentNode; }, error => { @@ -298,7 +298,7 @@ export function showLessonResourceSearchPage(store, params, query = {}) { lessonId: params.lessonId, contentList: results.results, searchResults: results, - pageName: LessonsPageNames.SELECTION_SEARCH, + pageName: PageNames.LESSON_RESOURCE_SELECTION_SEARCH, }); }); }); diff --git a/kolibri/plugins/coach/assets/src/modules/lessonSummary/handlers.js b/kolibri/plugins/coach/assets/src/modules/lessonSummary/handlers.js index 007c7744547..db27d9c755a 100644 --- a/kolibri/plugins/coach/assets/src/modules/lessonSummary/handlers.js +++ b/kolibri/plugins/coach/assets/src/modules/lessonSummary/handlers.js @@ -1,7 +1,7 @@ import { LearnerGroupResource } from 'kolibri.resources'; import useUser from 'kolibri.coreVue.composables.useUser'; import { get } from '@vueuse/core'; -import { LessonsPageNames } from '../../constants/lessonsConstants'; +import { PageNames } from '../../constants'; export async function setLessonSummaryState(store, params) { const { classId, lessonId } = params; @@ -37,7 +37,7 @@ export async function setLessonSummaryState(store, params) { return store.dispatch('lessonSummary/getResourceCache', resourceIds).then(() => { store.commit('lessonSummary/SET_WORKING_RESOURCES', currentLesson.resources); store.commit('lessonSummary/SET_LEARNER_GROUPS', learnerGroups); - store.commit('SET_PAGE_NAME', LessonsPageNames.SUMMARY); + store.commit('SET_PAGE_NAME', PageNames.LESSON_SUMMARY); }); }) .catch(error => { diff --git a/kolibri/plugins/coach/assets/src/modules/lessonSummary/index.js b/kolibri/plugins/coach/assets/src/modules/lessonSummary/index.js index 5f2aea0d469..7051174baee 100644 --- a/kolibri/plugins/coach/assets/src/modules/lessonSummary/index.js +++ b/kolibri/plugins/coach/assets/src/modules/lessonSummary/index.js @@ -19,6 +19,9 @@ export default { return rootState.channels.list.find(({ id }) => id === node.channel_id); }; }, + workingResources(state) { + return state.workingResources || []; + }, }, mutations: { SET_STATE(state, payload) { diff --git a/kolibri/plugins/coach/assets/src/modules/lessonsRoot/actions.js b/kolibri/plugins/coach/assets/src/modules/lessonsRoot/actions.js index 4529a43b8ee..9c794758d46 100644 --- a/kolibri/plugins/coach/assets/src/modules/lessonsRoot/actions.js +++ b/kolibri/plugins/coach/assets/src/modules/lessonsRoot/actions.js @@ -2,7 +2,7 @@ import { LessonResource } from 'kolibri.resources'; import router from 'kolibri.coreVue.router'; import { createTranslator } from 'kolibri.utils.i18n'; import useSnackbar from 'kolibri.coreVue.composables.useSnackbar'; -import { lessonSummaryLink } from '../../routes/planLessonsRouterUtils'; +import { PageNames } from '../../constants'; const translator = createTranslator('LessonRootActionTexts', { newLessonCreated: { @@ -68,7 +68,13 @@ export function createLesson(store, { classId, payload }) { createSnackbar(translator.$tr('newLessonCreated')); // Update the class summary now that we have a new lesson in town! store.dispatch('classSummary/refreshClassSummary', null, { root: true }).then(() => { - router.push(lessonSummaryLink({ classId, lessonId: newLesson.id })); + router.push({ + name: PageNames.LESSON_SUMMARY, + params: { + classId, + lessonId: newLesson.id, + }, + }); resolve(); }); }) diff --git a/kolibri/plugins/coach/assets/src/modules/pluginModule.js b/kolibri/plugins/coach/assets/src/modules/pluginModule.js index f5eb7d34e77..44539241d8d 100644 --- a/kolibri/plugins/coach/assets/src/modules/pluginModule.js +++ b/kolibri/plugins/coach/assets/src/modules/pluginModule.js @@ -2,8 +2,7 @@ import { ClassroomResource } from 'kolibri.resources'; import logger from 'kolibri.lib.logging'; import useUser from 'kolibri.coreVue.composables.useUser'; import { get } from '@vueuse/core'; -import { pageNameToModuleMap } from '../constants'; -import { LessonsPageNames } from '../constants/lessonsConstants'; +import { PageNames, pageNameToModuleMap } from '../constants'; import examReportDetail from './examReportDetail'; import exerciseDetail from './exerciseDetail'; import groups from './groups'; @@ -114,8 +113,8 @@ export default { resetModuleState(store, { toRoute, fromRoute }) { // If going from Lesson Summary to something other than Resource Selection, reset if ( - fromRoute.name === LessonsPageNames.SUMMARY && - ![LessonsPageNames.SELECTION_ROOT, LessonsPageNames.SUMMARY].includes(toRoute.name) + fromRoute.name === PageNames.LESSON_SUMMARY && + ![PageNames.LESSON_RESOURCE_SELECTION_ROOT, PageNames.LESSON_SUMMARY].includes(toRoute.name) ) { return store.dispatch('lessonSummary/resetLessonSummaryState'); } diff --git a/kolibri/plugins/coach/assets/src/routes/baseRoutes.js b/kolibri/plugins/coach/assets/src/routes/baseRoutes.js index aad97436e8c..ccf5d181fb7 100644 --- a/kolibri/plugins/coach/assets/src/routes/baseRoutes.js +++ b/kolibri/plugins/coach/assets/src/routes/baseRoutes.js @@ -1,21 +1,24 @@ import { PageNames } from '../constants'; export default { - classes: { - name: PageNames.COACH_CLASS_LIST_PAGE, - path: '/classes', - }, classHome: { name: PageNames.HOME_PAGE, path: '/:classId?/home', }, - plan: { - name: PageNames.PLAN_PAGE, - path: '/:classId?/plan', - redirect: '/:classId?/plan/lessons', + lessons: { + name: PageNames.LESSONS_ROOT, + path: '/:classId?/lessons', + }, + quizzes: { + name: PageNames.EXAMS_ROOT, + path: '/:classId?/quizzes', + }, + learners: { + name: PageNames.LEARNERS_ROOT, + path: '/:classId?/learners', }, - reports: { - name: PageNames.REPORTS_PAGE, - path: '/:classId?/reports', + groups: { + name: PageNames.GROUPS_ROOT, + path: '/:classId?/groups', }, }; diff --git a/kolibri/plugins/coach/assets/src/routes/examRoutes.js b/kolibri/plugins/coach/assets/src/routes/examRoutes.js new file mode 100644 index 00000000000..c68209dd978 --- /dev/null +++ b/kolibri/plugins/coach/assets/src/routes/examRoutes.js @@ -0,0 +1,143 @@ +import store from 'kolibri.coreVue.vuex.store'; +import { PageNames } from '../constants'; +import CreateExamPage from '../views/quizzes/CreateExamPage'; +import SectionEditor from '../views/quizzes/CreateExamPage/SectionEditor.vue'; +import ResourceSelection from '../views/quizzes/CreateExamPage/ResourceSelection.vue'; +import ReplaceQuestions from '../views/quizzes/CreateExamPage/ReplaceQuestions.vue'; +import ExamsRootPage from '../views/quizzes/ExamsRootPage'; +import QuizSummaryPage from '../views/quizzes/QuizSummaryPage'; +import SectionOrder from '../views/quizzes/CreateExamPage/SectionOrder'; +import LearnerQuizPage from '../views/common/reports/LearnerQuizPage.vue'; +import QuizPreviewPage from '../views/quizzes/reports/QuizPreviewPage.vue'; +import { generateExamReportDetailHandler } from '../modules/examReportDetail/handlers'; +import QuestionLearnersPage from '../views/common/reports/QuestionLearnersPage.vue'; +import { + generateQuestionDetailHandler, + questionRootRedirectHandler, +} from '../modules/questionDetail/handlers'; +import { classIdParamRequiredGuard, RouteSegments } from './utils'; + +const { + CLASS, + OPTIONAL_CLASS, + QUIZ, + ALL_QUIZZES, + OPTIONAL_GROUP, + LEARNER, + QUESTION, + TRY, + INTERACTION, +} = RouteSegments; + +export default [ + { + name: PageNames.EXAMS_ROOT, + path: OPTIONAL_CLASS + ALL_QUIZZES, + component: ExamsRootPage, + handler(toRoute, fromRoute, next) { + if (classIdParamRequiredGuard(toRoute, PageNames.EXAMS_ROOT, next)) { + return; + } + }, + meta: { + titleParts: ['quizzesLabel', 'CLASS_NAME'], + }, + }, + { + name: PageNames.EXAM_CREATION_ROOT, + path: CLASS + QUIZ + '/edit/:sectionIndex', + component: CreateExamPage, + children: [ + { + name: PageNames.QUIZ_SECTION_EDITOR, + path: 'edit', + component: SectionEditor, + }, + { + name: PageNames.QUIZ_REPLACE_QUESTIONS, + path: 'replace-questions', + component: ReplaceQuestions, + }, + { + name: PageNames.QUIZ_SELECT_RESOURCES, + path: 'select-resources/:topic_id?', + component: ResourceSelection, + }, + { + name: PageNames.QUIZ_SECTION_ORDER, + path: 'section-order', + component: SectionOrder, + }, + { + name: PageNames.QUIZ_SELECT_PRACTICE_QUIZ, + path: 'select-quiz/:topic_id?', + component: ResourceSelection, + props: { + selectPracticeQuiz: true, + }, + }, + ], + }, + { + name: PageNames.EXAM_SUMMARY, + path: CLASS + QUIZ + '/:tabId?', + component: QuizSummaryPage, + meta: { + titleParts: ['QUIZ_NAME', 'quizzesLabel', 'CLASS_NAME'], + }, + }, + { + path: CLASS + OPTIONAL_GROUP + QUIZ + LEARNER, + name: PageNames.QUIZ_LEARNER_PAGE_ROOT, + redirect: to => { + const { params } = to; + return { + name: PageNames.QUIZ_LEARNER_REPORT, + params: { + ...params, + questionId: 0, + interactionIndex: 0, + tryIndex: 0, + }, + }; + }, + }, + { + name: PageNames.QUIZ_LEARNER_REPORT, + path: CLASS + OPTIONAL_GROUP + QUIZ + LEARNER + TRY + QUESTION + INTERACTION, + component: LearnerQuizPage, + handler: generateExamReportDetailHandler(['groupId', 'learnerId', 'quizId']), + meta: { + titleParts: ['LEARNER_NAME', 'QUIZ_NAME', 'GROUP_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.QUIZ_PREVIEW, + path: CLASS + QUIZ + '/preview', + component: QuizPreviewPage, + handler() { + store.dispatch('notLoading'); + }, + meta: { + titleParts: ['previewLabel', 'QUIZ_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.QUIZ_QUESTION_PAGE_ROOT, + path: CLASS + OPTIONAL_GROUP + QUIZ + QUESTION, + beforeEnter: (to, from, next) => { + const { params } = to; + return questionRootRedirectHandler(params, PageNames.QUIZ_QUESTION_REPORT, next); + }, + }, + { + name: PageNames.QUIZ_QUESTION_REPORT, + path: CLASS + OPTIONAL_GROUP + QUIZ + QUESTION + LEARNER + INTERACTION, + component: QuestionLearnersPage, + handler: generateQuestionDetailHandler(['groupId', 'lessonId', 'exerciseId', 'questionId']), + meta: { + // Leaves out info on question + titleParts: ['questionLabel', 'EXERCISE_NAME', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], + }, + }, +]; diff --git a/kolibri/plugins/coach/assets/src/routes/groupsRoutes.js b/kolibri/plugins/coach/assets/src/routes/groupsRoutes.js new file mode 100644 index 00000000000..73e930eafac --- /dev/null +++ b/kolibri/plugins/coach/assets/src/routes/groupsRoutes.js @@ -0,0 +1,125 @@ +import store from 'kolibri.coreVue.vuex.store'; +import { PageNames } from '../constants'; +import { useGroups } from '../composables/useGroups'; +import GroupsRootPage from '../views/groups/GroupsRootPage'; +import GroupEnrollPage from '../views/groups/GroupEnrollPage'; +import GroupMembersPage from '../views/groups/GroupMembersPage'; +import LessonSummaryPage from '../views/lessons/LessonSummaryPage'; +import LessonLearnerPage from '../views/lessons/reports/LessonLearnerPage.vue'; +import ExerciseQuestionListPage from '../views/common/reports/ExerciseQuestionListPage.vue'; +import { generateQuestionListHandler } from '../modules/questionList/handlers'; +import GroupLessonExerciseLearnersPage from '../views/groups/reports/GroupLessonExerciseLearnersPage.vue'; +import { showLessonSummaryPage } from '../modules/lessonSummary/handlers'; +import { generateResourceHandler } from '../modules/resourceDetail/handlers'; +import QuizSummaryPage from '../views/quizzes/QuizSummaryPage'; +import { classIdParamRequiredGuard, RouteSegments } from './utils'; + +const { + CLASS, + OPTIONAL_CLASS, + ALL_GROUPS, + GROUP, + LESSON, + LEARNER, + ALL_LEARNERS, + QUESTIONS, + EXERCISE, + QUIZ, +} = RouteSegments; + +const { showGroupsPage } = useGroups(); + +function defaultHandler() { + store.dispatch('notLoading'); +} + +export default [ + { + name: PageNames.GROUPS_ROOT, + path: OPTIONAL_CLASS + ALL_GROUPS, + component: GroupsRootPage, + handler(toRoute, fromRoute, next) { + if (classIdParamRequiredGuard(toRoute, PageNames.GROUPS_ROOT, next)) { + return; + } + showGroupsPage(store, toRoute.params.classId); + }, + meta: { + titleParts: ['groupsLabel', 'CLASS_NAME'], + }, + }, + { + name: PageNames.GROUP_SUMMARY, + path: CLASS + GROUP, + component: GroupMembersPage, + handler(to) { + showGroupsPage(store, to.params.classId); + }, + meta: { + titleParts: ['membersLabel', 'GROUP_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.GROUP_ENROLL, + path: CLASS + GROUP + '/enroll', + component: GroupEnrollPage, + handler(to) { + showGroupsPage(store, to.params.classId); + }, + }, + { + name: PageNames.GROUP_LESSON_SUMMARY, + path: CLASS + GROUP + LESSON + '/:tabId?', + component: LessonSummaryPage, + handler(toRoute, fromRoute) { + if ( + fromRoute.name !== PageNames.GROUP_LESSON_SUMMARY || + toRoute.params.lessonId !== fromRoute.params.lessonId + ) { + return showLessonSummaryPage(store, toRoute.params); + } + store.dispatch('notLoading'); + }, + props: { + editable: false, + }, + meta: { + titleParts: ['LESSON_NAME', 'LEARNER_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.GROUP_LESSON_LEARNER, + path: CLASS + GROUP + LESSON + LEARNER, + component: LessonLearnerPage, + handler: defaultHandler, + meta: { + titleParts: ['learnersLabel', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.GROUP_LESSON_EXERCISE_LEARNER_REPORT, + path: CLASS + GROUP + LESSON + EXERCISE + ALL_LEARNERS, + component: GroupLessonExerciseLearnersPage, + handler: generateResourceHandler(['exerciseId']), + meta: { + titleParts: ['learnersLabel', 'EXERCISE_NAME', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.GROUP_LESSON_EXERCISE_QUESTIONS_REPORT, + path: CLASS + GROUP + LESSON + EXERCISE + QUESTIONS, + component: ExerciseQuestionListPage, + handler: generateQuestionListHandler(['groupId', 'lessonId', 'exerciseId']), + meta: { + titleParts: ['questionsLabel', 'EXERCISE_NAME', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.GROUP_EXAM_SUMMARY, + path: CLASS + GROUP + QUIZ + '/:tabId?', + component: QuizSummaryPage, + meta: { + titleParts: ['QUIZ_NAME', 'quizzesLabel', 'CLASS_NAME'], + }, + }, +]; diff --git a/kolibri/plugins/coach/assets/src/routes/index.js b/kolibri/plugins/coach/assets/src/routes/index.js index b6a6a915312..acd65b08de4 100644 --- a/kolibri/plugins/coach/assets/src/routes/index.js +++ b/kolibri/plugins/coach/assets/src/routes/index.js @@ -11,9 +11,11 @@ import HomeActivityPage from '../views/home/HomeActivityPage'; import StatusTestPage from '../views/common/status/StatusTestPage'; import { ClassesPageNames } from '../../../../learn/assets/src/constants'; import { PageNames } from '../constants'; -import reportRoutes from './reportRoutes'; -import planRoutes from './planRoutes'; import { classIdParamRequiredGuard } from './utils'; +import examRoutes from './examRoutes'; +import lessonsRoutes from './lessonsRoutes'; +import learnersRoutes from './learnersRoutes'; +import groupsRoutes from './groupsRoutes'; function showHomePage(toRoute) { const initClassInfoPromise = store.dispatch('initClassInfo', toRoute.params.classId); @@ -27,8 +29,10 @@ function showHomePage(toRoute) { } export default [ - ...planRoutes, - ...reportRoutes, + ...examRoutes, + ...lessonsRoutes, + ...learnersRoutes, + ...groupsRoutes, { name: 'AllFacilitiesPage', path: '/facilities/:subtopicName?', @@ -96,7 +100,7 @@ export default [ }, { name: ClassesPageNames.CLASS_LEARNERS_LIST_VIEWER, - path: '/:classId/learners', + path: '/:classId/learners/devices', component: ClassLearnersListPage, handler() { store.dispatch('notLoading'); diff --git a/kolibri/plugins/coach/assets/src/routes/learnersRoutes.js b/kolibri/plugins/coach/assets/src/routes/learnersRoutes.js new file mode 100644 index 00000000000..ec130360eb6 --- /dev/null +++ b/kolibri/plugins/coach/assets/src/routes/learnersRoutes.js @@ -0,0 +1,57 @@ +import store from 'kolibri.coreVue.vuex.store'; +import { PageNames } from '../constants'; +import LearnersRootPage from '../views/learners/LearnersRootPage'; +import LearnerSummaryPage from '../views/learners/LearnerSummaryPage'; +import ReportsLearnerActivityPage from '../views/learners/LearnerSummaryPage/ReportsLearnerActivityPage.vue'; +import LearnerLessonPage from '../views/learners/reports/LearnerLessonPage.vue'; +import { classIdParamRequiredGuard, RouteSegments } from './utils'; + +const { CLASS, OPTIONAL_CLASS, ALL_LEARNERS, LEARNER, LESSON } = RouteSegments; + +function defaultHandler() { + store.dispatch('notLoading'); +} + +export default [ + { + name: PageNames.LEARNERS_ROOT, + path: OPTIONAL_CLASS + ALL_LEARNERS, + component: LearnersRootPage, + handler(toRoute, fromRoute, next) { + if (classIdParamRequiredGuard(toRoute, PageNames.LEARNERS_ROOT, next)) { + return; + } + defaultHandler(); + }, + meta: { + titleParts: ['learnersLabel', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LEARNER_SUMMARY, + path: CLASS + LEARNER, + component: LearnerSummaryPage, + handler: defaultHandler, + meta: { + titleParts: ['reportsLabel', 'LEARNER_NAME', 'CLASS_NAME'], + }, + }, + { + name: 'ReportsLearnerActivityPage', // Will be removed in #12733 + path: CLASS + LEARNER + '/activity', + component: ReportsLearnerActivityPage, + handler: defaultHandler, + meta: { + titleParts: ['activityLabel', 'LEARNER_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LEARNER_LESSON_REPORT, + path: CLASS + LEARNER + LESSON, + component: LearnerLessonPage, + handler: defaultHandler, + meta: { + titleParts: ['LESSON_NAME', 'LEARNER_NAME', 'CLASS_NAME'], + }, + }, +]; diff --git a/kolibri/plugins/coach/assets/src/routes/lessonsRoutes.js b/kolibri/plugins/coach/assets/src/routes/lessonsRoutes.js new file mode 100644 index 00000000000..1c621692ad4 --- /dev/null +++ b/kolibri/plugins/coach/assets/src/routes/lessonsRoutes.js @@ -0,0 +1,358 @@ +import store from 'kolibri.coreVue.vuex.store'; +import { + showLessonResourceContentPreview, + showLessonResourceSelectionRootPage, + showLessonResourceSelectionTopicPage, + showLessonSelectionContentPreview, + showLessonResourceSearchPage, + showLessonResourceBookmarks, + showLessonResourceBookmarksMain, +} from '../modules/lessonResources/handlers'; +import { showLessonSummaryPage } from '../modules/lessonSummary/handlers'; +import { PageNames } from '../constants'; + +import { useLessons } from '../composables/useLessons'; + +import LessonsRootPage from '../views/lessons/LessonsRootPage'; +import LessonSummaryPage from '../views/lessons/LessonSummaryPage'; +import LessonResourceSelectionPage from '../views/lessons/LessonResourceSelectionPage'; +import LessonSelectionContentPreviewPage from '../views/lessons/LessonSelectionContentPreviewPage'; +import LessonEditDetailsPage from '../views/lessons/LessonEditDetailsPage'; +import LessonCreationPage from '../views/lessons/LessonCreationPage'; +import EditLessonDetails from '../views/lessons/LessonEditDetailsPage/EditLessonDetails'; +import PreviewSelectedResources from '../views/lessons/LessonSelectionContentPreviewPage/LessonContentPreview/PreviewSelectedResources'; +import LessonResourceSelection from '../views/lessons/LessonResourceSelectionPage/LessonResourceSelection'; + +import { generateResourceHandler } from '../modules/resourceDetail/handlers'; +import LessonResourceLearnersPage from '../views/lessons/reports/LessonResourceLearnersPage'; +import LessonLearnerPage from '../views/lessons/reports/LessonLearnerPage.vue'; +import LessonExerciseLearnersPage from '../views/lessons/reports/LessonExerciseLearnersPage.vue'; +import { + exerciseRootRedirectHandler, + generateExerciseDetailHandler, +} from '../modules/exerciseDetail/handlers'; +import LessonExerciseLearnerPage from '../views/lessons/reports/LessonExerciseLearnerPage.vue'; +import { generateQuestionListHandler } from '../modules/questionList/handlers'; +import ExerciseQuestionListPage from '../views/common/reports/ExerciseQuestionListPage.vue'; +import { + generateQuestionDetailHandler, + questionRootRedirectHandler, +} from '../modules/questionDetail/handlers'; +import LessonLearnerExercisePage from '../views/lessons/reports/LessonLearnerExercisePage.vue'; +import QuestionLearnersPage from '../views/common/reports/QuestionLearnersPage.vue'; +import { classIdParamRequiredGuard, RouteSegments } from './utils'; + +const { + OPTIONAL_CLASS, + CLASS, + LESSON, + ALL_LESSONS, + ALL_LESSONS_TEMP, + LESSONS_TEMP, + SELECTION, + TOPIC, + SEARCH, + PREVIEW, + RESOURCE, + ALL_LEARNERS, + LEARNER, + EXERCISE, + QUESTIONS, + QUESTION, + TRY, + INTERACTION, + OPTIONAL_GROUP, +} = RouteSegments; + +const { showLessonsRootPage } = useLessons(); + +function defaultHandler() { + store.dispatch('notLoading'); +} + +export default [ + { + name: PageNames.LESSONS_ROOT, + path: OPTIONAL_CLASS + ALL_LESSONS, + component: LessonsRootPage, + handler(toRoute, fromRoute, next) { + if (classIdParamRequiredGuard(toRoute, PageNames.LESSONS_ROOT, next)) { + return; + } + showLessonsRootPage(store, toRoute.params.classId); + }, + meta: { + titleParts: ['lessonsLabel', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LESSONS_ROOT_BETTER, + path: OPTIONAL_CLASS + ALL_LESSONS_TEMP, + component: LessonsRootPage, + handler(toRoute, fromRoute, next) { + if (classIdParamRequiredGuard(toRoute, PageNames.LESSONS_ROOT_BETTER, next)) { + return; + } + showLessonsRootPage(store, toRoute.params.classId); + }, + meta: { + titleParts: ['lessonsLabel', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LESSON_CREATION_ROOT, + path: CLASS + ALL_LESSONS + '/new', + component: LessonCreationPage, + }, + { + name: PageNames.LESSON_CREATION_ROOT_BETTER, + path: CLASS + LESSONS_TEMP + '/edit', + component: LessonCreationPage, + children: [ + { + name: PageNames.LESSON_EDIT_DETAILS_BETTER, + path: 'details/', + component: EditLessonDetails, + props: { + text: 'test', + }, + }, + { + name: PageNames.LESSON_SELECT_RESOURCES, + path: 'select-resources/:topicId?', + component: LessonResourceSelection, + }, + { + name: PageNames.LESSON_PREVIEW_SELECTED_RESOURCES, + path: 'preview-resources/', + component: PreviewSelectedResources, + }, + { + name: PageNames.LESSON_PREVIEW_RESOURCE, + path: 'preview-resources/:nodeId', + component: PreviewSelectedResources, + }, + ], + }, + { + name: PageNames.LESSON_SUMMARY, + path: CLASS + LESSON + '/:tabId?', + component: LessonSummaryPage, + handler(toRoute, fromRoute) { + if ( + fromRoute.name !== PageNames.LESSON_SUMMARY || + toRoute.params.lessonId !== fromRoute.params.lessonId + ) { + return showLessonSummaryPage(store, toRoute.params); + } + store.dispatch('notLoading'); + }, + meta: { + titleParts: ['LESSON_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LESSON_EDIT_DETAILS, + path: CLASS + LESSON + '/edit', + component: LessonEditDetailsPage, + }, + { + name: PageNames.LESSON_RESOURCE_SELECTION_ROOT, + path: CLASS + LESSON + SELECTION, + component: LessonResourceSelectionPage, + handler(toRoute) { + showLessonResourceSelectionRootPage(store, toRoute.params); + }, + }, + { + name: PageNames.LESSON_RESOURCE_SELECTION, + path: CLASS + LESSON + SELECTION + TOPIC, + component: LessonResourceSelectionPage, + handler(toRoute, fromRoute) { + // HACK if last page was LessonContentPreview, then we need to make sure + // to immediately autosave just in case a change was made there. This gets + // called whether or not a change is made, because we don't track changes + // enough steps back. + let preHandlerPromise; + if (fromRoute.name === PageNames.LESSON_RESOURCE_SELECTION_CONTENT_PREVIEW) { + preHandlerPromise = store.dispatch('lessonSummary/saveLessonResources', { + lessonId: toRoute.params.lessonId, + resources: store.state.lessonSummary.workingResources, + }); + } else { + preHandlerPromise = Promise.resolve(); + } + preHandlerPromise.then(() => { + showLessonResourceSelectionTopicPage(store, toRoute.params); + }); + }, + }, + { + name: PageNames.LESSON_RESOURCE_SELECTION_SEARCH, + path: CLASS + LESSON + SELECTION + SEARCH, + component: LessonResourceSelectionPage, + handler(toRoute) { + showLessonResourceSearchPage(store, toRoute.params, toRoute.query); + }, + }, + { + name: PageNames.LESSON_SELECTION_BOOKMARKS, + path: CLASS + LESSON + SELECTION + TOPIC, + component: LessonResourceSelectionPage, + handler(toRoute, fromRoute) { + let preHandlerPromise; + if (fromRoute.name === PageNames.LESSON_RESOURCE_SELECTION_CONTENT_PREVIEW) { + preHandlerPromise = store.dispatch('lessonSummary/saveLessonResources', { + lessonId: toRoute.params.lessonId, + resources: store.state.lessonSummary.workingResources, + }); + } else { + preHandlerPromise = Promise.resolve(); + } + preHandlerPromise.then(() => { + showLessonResourceBookmarks(store, toRoute.params, toRoute.query); + }); + }, + }, + { + name: PageNames.LESSON_SELECTION_BOOKMARKS_MAIN, + path: CLASS + LESSON + SELECTION, + component: LessonResourceSelectionPage, + handler(toRoute) { + showLessonResourceBookmarksMain(store, toRoute.params, toRoute.query); + }, + }, + { + name: PageNames.LESSON_RESOURCE_SELECTION_CONTENT_PREVIEW, + path: CLASS + LESSON + SELECTION + PREVIEW, + component: LessonSelectionContentPreviewPage, + handler(toRoute) { + showLessonSelectionContentPreview(store, toRoute.params, toRoute.query); + }, + }, + { + name: PageNames.RESOURCE_CONTENT_PREVIEW, + path: CLASS + LESSON + '/resource' + PREVIEW, + component: LessonSelectionContentPreviewPage, + props(data) { + let backRoute; + // If linked from the Reports section, go back there + if (data.query.last === PageNames.LESSON_EDIT_DETAILS) { + backRoute = { + name: PageNames.LESSON_EDIT_DETAILS, + }; + } else { + backRoute = { + name: PageNames.LESSON_SUMMARY, + }; + } + return { + showSelectOptions: false, + backRoute, + }; + }, + handler(toRoute) { + showLessonResourceContentPreview(store, toRoute.params); + }, + }, + { + name: PageNames.LESSON_RESOURCE_LEARNERS_REPORT, + path: CLASS + LESSON + RESOURCE + ALL_LEARNERS, + component: LessonResourceLearnersPage, + handler: generateResourceHandler(['resourceId']), + meta: { + titleParts: ['RESOURCE_NAME', 'LESSON_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LESSON_LEARNER_REPORT, + path: CLASS + LESSON + LEARNER, + component: LessonLearnerPage, + handler: defaultHandler, + meta: { + titleParts: ['LEARNER_NAME', 'LESSON_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LESSON_EXERCISE_LEARNERS_REPORT, + path: CLASS + LESSON + EXERCISE + ALL_LEARNERS, + component: LessonExerciseLearnersPage, + handler: generateResourceHandler(['exerciseId']), + meta: { + titleParts: ['learnersLabel', 'EXERCISE_NAME', 'LESSON_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LESSON_EXERCISE_LEARNER_PAGE_ROOT, + path: CLASS + LESSON + EXERCISE + LEARNER, + beforeEnter: (to, from, next) => { + const { params, query } = to; + return exerciseRootRedirectHandler( + params, + PageNames.LESSON_EXERCISE_LEARNER_REPORT, + next, + query, + ); + }, + meta: { + titleParts: ['LEARNER_NAME', 'EXERCISE_NAME', 'LESSON_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LESSON_EXERCISE_LEARNER_REPORT, + path: CLASS + LESSON + EXERCISE + LEARNER + TRY + QUESTION + INTERACTION, + component: LessonExerciseLearnerPage, + handler: generateExerciseDetailHandler(['learnerId', 'lessonId', 'exerciseId']), + meta: { + titleParts: ['LEARNER_NAME', 'EXERCISE_NAME', 'LESSON_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LESSON_EXERCISE_QUESTIONS_REPORT, + path: CLASS + LESSON + EXERCISE + QUESTIONS, + component: ExerciseQuestionListPage, + handler: generateQuestionListHandler(['lessonId', 'exerciseId']), + meta: { + titleParts: ['questionsLabel', 'EXERCISE_NAME', 'LESSON_NAME', 'CLASS_NAME'], + }, + }, + { + path: CLASS + LESSON + LEARNER + EXERCISE, + name: PageNames.LESSON_LEARNER_EXERCISE_PAGE_ROOT, + beforeEnter: (to, from, next) => { + const { params } = to; + return exerciseRootRedirectHandler(params, PageNames.LESSON_LEARNER_EXERCISE_REPORT, next); + }, + meta: { + titleParts: ['EXERCISE_NAME', 'LEARNER_NAME', 'LESSON_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LESSON_LEARNER_EXERCISE_REPORT, + path: CLASS + LESSON + LEARNER + EXERCISE + TRY + QUESTION + INTERACTION, + component: LessonLearnerExercisePage, + handler: generateExerciseDetailHandler(['learnerId', 'lessonId', 'exerciseId']), + meta: { + // Leaves out attempt and interaction numbers + titleParts: ['LEARNER_NAME', 'EXERCISE_NAME', 'LESSON_NAME', 'CLASS_NAME'], + }, + }, + { + name: PageNames.LESSON_EXERCISE_QUESTION_PAGE_ROOT, + path: CLASS + OPTIONAL_GROUP + LESSON + EXERCISE + QUESTION, + beforeEnter: (to, from, next) => { + const { params } = to; + return questionRootRedirectHandler(params, PageNames.LESSON_EXERCISE_QUESTION_REPORT, next); + }, + }, + { + name: PageNames.LESSON_EXERCISE_QUESTION_REPORT, + path: CLASS + OPTIONAL_GROUP + LESSON + EXERCISE + QUESTION + LEARNER + INTERACTION, + component: QuestionLearnersPage, + handler: generateQuestionDetailHandler(['groupId', 'lessonId', 'exerciseId', 'questionId']), + meta: { + // Leaves out info on question + titleParts: ['questionLabel', 'EXERCISE_NAME', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], + }, + }, +]; diff --git a/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js b/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js deleted file mode 100644 index d5f1a26077b..00000000000 --- a/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js +++ /dev/null @@ -1,62 +0,0 @@ -import { PageNames } from '../constants'; -import CreateExamPage from '../views/plan/CreateExamPage'; -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 CoachExamsPage from '../views/plan/CoachExamsPage'; -import QuizSummaryPage from '../views/plan/QuizSummaryPage'; -import SectionOrder from '../views/plan/CreateExamPage/SectionOrder'; - -export default [ - { - name: PageNames.EXAMS, - path: '/:classId/plan/quizzes', - component: CoachExamsPage, - meta: { - titleParts: ['quizzesLabel', 'CLASS_NAME'], - }, - }, - { - name: PageNames.EXAM_CREATION_ROOT, - path: '/:classId/plan/quizzes/:quizId/edit/:sectionIndex', - component: CreateExamPage, - children: [ - { - name: PageNames.QUIZ_SECTION_EDITOR, - path: 'edit', - component: SectionEditor, - }, - { - name: PageNames.QUIZ_REPLACE_QUESTIONS, - path: 'replace-questions', - component: ReplaceQuestions, - }, - { - name: PageNames.QUIZ_SELECT_RESOURCES, - path: 'select-resources/:topic_id?', - component: ResourceSelection, - }, - { - name: PageNames.QUIZ_SECTION_ORDER, - path: 'section-order', - component: SectionOrder, - }, - { - name: PageNames.QUIZ_SELECT_PRACTICE_QUIZ, - path: 'select-quiz/:topic_id?', - component: ResourceSelection, - props: { - selectPracticeQuiz: true, - }, - }, - ], - }, - { - name: QuizSummaryPage.name, - path: '/:classId/plan/quizzes/:quizId/:tabId?', - component: QuizSummaryPage, - meta: { - titleParts: ['QUIZ_NAME', 'quizzesLabel', 'CLASS_NAME'], - }, - }, -]; diff --git a/kolibri/plugins/coach/assets/src/routes/planLessonsRouterUtils.js b/kolibri/plugins/coach/assets/src/routes/planLessonsRouterUtils.js deleted file mode 100644 index 47be0f9d293..00000000000 --- a/kolibri/plugins/coach/assets/src/routes/planLessonsRouterUtils.js +++ /dev/null @@ -1,24 +0,0 @@ -import { LessonsPageNames } from '../constants/lessonsConstants'; - -// IDEA kill these in favor of using vuex param autocomplete -// Creates a Link to the Lesson Summary Page -export function lessonSummaryLink({ classId, lessonId }) { - return { - name: LessonsPageNames.SUMMARY, - params: { - classId, - lessonId, - }, - }; -} - -// Creates a Link to the Channel Browsing Page for a Lesson -export function selectionRootLink({ classId, lessonId }) { - return { - name: LessonsPageNames.SELECTION_ROOT, - params: { - classId, - lessonId, - }, - }; -} diff --git a/kolibri/plugins/coach/assets/src/routes/planLessonsRoutes.js b/kolibri/plugins/coach/assets/src/routes/planLessonsRoutes.js deleted file mode 100644 index cb6d90e3e15..00000000000 --- a/kolibri/plugins/coach/assets/src/routes/planLessonsRoutes.js +++ /dev/null @@ -1,245 +0,0 @@ -import store from 'kolibri.coreVue.vuex.store'; -import { - showLessonResourceContentPreview, - showLessonResourceSelectionRootPage, - showLessonResourceSelectionTopicPage, - showLessonSelectionContentPreview, - showLessonResourceSearchPage, - showLessonResourceBookmarks, - showLessonResourceBookmarksMain, -} from '../modules/lessonResources/handlers'; -import { showLessonSummaryPage } from '../modules/lessonSummary/handlers'; -import { LessonsPageNames } from '../constants/lessonsConstants'; -import { PageNames } from '../constants'; - -import { useLessons } from '../composables/useLessons'; - -import LessonsRootPage from '../views/plan/LessonsRootPage'; -import LessonSummaryPage from '../views/plan/LessonSummaryPage'; -import LessonResourceSelectionPage from '../views/plan/LessonResourceSelectionPage'; -import PlanLessonSelectionContentPreview from '../views/plan/PlanLessonSelectionContentPreview'; -import LessonEditDetailsPage from '../views/plan/LessonEditDetailsPage'; -import LessonCreationPage from '../views/plan/LessonCreationPage'; -import EditLessonDetails from '../views/plan/LessonEditDetailsPage/EditLessonDetails.vue'; -import PreviewSelectedResources from '../views/plan/LessonContentPreviewPage/PreviewSelectedResources.vue'; -import LessonResourceSelection from '../views/plan/LessonResourceSelectionPage/LessonResourceSelection.vue'; -import { classIdParamRequiredGuard } from './utils'; - -const OPTIONAL_CLASS = '/:classId?/plan'; -const CLASS = '/:classId/plan'; -const LESSON = '/lessons/:lessonId'; -const ALL_LESSONS = '/lessons'; -const SELECTION = '/selection'; -const TOPIC = '/topic/:topicId'; -const SEARCH = '/search/:searchTerm'; -const PREVIEW = '/preview/:contentId'; - -function path(...args) { - return args.join(''); -} - -const { showLessonsRootPage } = useLessons(); - -export default [ - { - name: LessonsPageNames.PLAN_LESSONS_ROOT, - path: path(OPTIONAL_CLASS, ALL_LESSONS), - component: LessonsRootPage, - handler(toRoute, fromRoute, next) { - if (classIdParamRequiredGuard(toRoute, PageNames.PLAN_PAGE, next)) { - return; - } - showLessonsRootPage(store, toRoute.params.classId); - }, - meta: { - titleParts: ['lessonsLabel', 'CLASS_NAME'], - }, - }, - { - name: LessonsPageNames.PLAN_LESSONS_ROOT_BETTER, - path: '/:classId/plan/lessonstemp', - component: LessonsRootPage, - handler(toRoute, fromRoute, next) { - if (classIdParamRequiredGuard(toRoute, PageNames.PLAN_PAGE, next)) { - return; - } - showLessonsRootPage(store, toRoute.params.classId); - }, - meta: { - titleParts: ['lessonsLabel', 'CLASS_NAME'], - }, - }, - { - name: LessonsPageNames.LESSON_CREATION_ROOT, - path: path(CLASS, ALL_LESSONS, '/new'), - component: LessonCreationPage, - }, - { - name: PageNames.LESSON_CREATION_ROOT_BETTER, - path: '/:classId/plan/lessonstemp/:lessonId/edit', - component: LessonCreationPage, - children: [ - { - name: PageNames.LESSON_EDIT_DETAILS, - path: 'details/', - component: EditLessonDetails, - props: { - text: 'test', - }, - }, - { - name: PageNames.LESSON_SELECT_RESOURCES, - path: 'select-resources/:topicId?', - component: LessonResourceSelection, - }, - { - name: PageNames.LESSON_PREVIEW_SELECTED_RESOURCES, - path: 'preview-resources/', - component: PreviewSelectedResources, - }, - { - name: PageNames.LESSON_PREVIEW_RESOURCE, - path: 'preview-resources/:nodeId', - component: PreviewSelectedResources, - }, - ], - }, - { - name: LessonsPageNames.SUMMARY, - path: '/:classId/plan/lessonstemp/:lessonId/:tabId?', - component: LessonSummaryPage, - handler(toRoute, fromRoute) { - if ( - fromRoute.name !== LessonsPageNames.SUMMARY || - toRoute.params.lessonId !== fromRoute.params.lessonId - ) { - return showLessonSummaryPage(store, toRoute.params); - } - store.dispatch('notLoading'); - }, - meta: { - titleParts: ['LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - name: LessonsPageNames.SUMMARY, - path: path(CLASS, LESSON), - component: LessonSummaryPage, - handler(toRoute, fromRoute) { - if ( - fromRoute.name !== LessonsPageNames.SUMMARY || - toRoute.params.lessonId !== fromRoute.params.lessonId - ) { - return showLessonSummaryPage(store, toRoute.params); - } - store.dispatch('notLoading'); - }, - meta: { - titleParts: ['LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - name: LessonEditDetailsPage.name, - path: path(CLASS, LESSON, '/edit'), - component: LessonEditDetailsPage, - }, - { - name: LessonsPageNames.SELECTION_ROOT, - path: path(CLASS, LESSON, SELECTION), - component: LessonResourceSelectionPage, - handler(toRoute) { - showLessonResourceSelectionRootPage(store, toRoute.params); - }, - }, - { - name: LessonsPageNames.SELECTION, - path: path(CLASS, LESSON, SELECTION, TOPIC), - component: LessonResourceSelectionPage, - handler(toRoute, fromRoute) { - // HACK if last page was LessonContentPreviewPage, then we need to make sure - // to immediately autosave just in case a change was made there. This gets - // called whether or not a change is made, because we don't track changes - // enough steps back. - let preHandlerPromise; - if (fromRoute.name === LessonsPageNames.SELECTION_CONTENT_PREVIEW) { - preHandlerPromise = store.dispatch('lessonSummary/saveLessonResources', { - lessonId: toRoute.params.lessonId, - resources: store.state.lessonSummary.workingResources, - }); - } else { - preHandlerPromise = Promise.resolve(); - } - preHandlerPromise.then(() => { - showLessonResourceSelectionTopicPage(store, toRoute.params); - }); - }, - }, - { - name: LessonsPageNames.SELECTION_SEARCH, - path: path(CLASS, LESSON, SELECTION, SEARCH), - component: LessonResourceSelectionPage, - handler(toRoute) { - showLessonResourceSearchPage(store, toRoute.params, toRoute.query); - }, - }, - { - name: LessonsPageNames.LESSON_SELECTION_BOOKMARKS, - path: path(CLASS, LESSON, SELECTION, TOPIC), - component: LessonResourceSelectionPage, - handler(toRoute, fromRoute) { - let preHandlerPromise; - if (fromRoute.name === LessonsPageNames.SELECTION_CONTENT_PREVIEW) { - preHandlerPromise = store.dispatch('lessonSummary/saveLessonResources', { - lessonId: toRoute.params.lessonId, - resources: store.state.lessonSummary.workingResources, - }); - } else { - preHandlerPromise = Promise.resolve(); - } - preHandlerPromise.then(() => { - showLessonResourceBookmarks(store, toRoute.params, toRoute.query); - }); - }, - }, - { - name: LessonsPageNames.LESSON_SELECTION_BOOKMARKS_MAIN, - path: path(CLASS, LESSON, SELECTION), - component: LessonResourceSelectionPage, - handler(toRoute) { - showLessonResourceBookmarksMain(store, toRoute.params, toRoute.query); - }, - }, - { - name: LessonsPageNames.SELECTION_CONTENT_PREVIEW, - path: path(CLASS, LESSON, SELECTION, PREVIEW), - component: PlanLessonSelectionContentPreview, - handler(toRoute) { - showLessonSelectionContentPreview(store, toRoute.params, toRoute.query); - }, - }, - { - name: LessonsPageNames.RESOURCE_CONTENT_PREVIEW, - path: path(CLASS, LESSON, '/resource', PREVIEW), - component: PlanLessonSelectionContentPreview, - props(data) { - let backRoute; - // If linked from the Reports section, go back there - if (data.query.last === 'LessonReportEditDetailsPage') { - backRoute = { - name: 'LessonReportEditDetailsPage', - }; - } else { - backRoute = { - name: LessonsPageNames.SUMMARY, - }; - } - return { - showSelectOptions: false, - backRoute, - }; - }, - handler(toRoute) { - showLessonResourceContentPreview(store, toRoute.params); - }, - }, -]; diff --git a/kolibri/plugins/coach/assets/src/routes/planRoutes.js b/kolibri/plugins/coach/assets/src/routes/planRoutes.js deleted file mode 100644 index 96e0b0cf1a2..00000000000 --- a/kolibri/plugins/coach/assets/src/routes/planRoutes.js +++ /dev/null @@ -1,50 +0,0 @@ -import store from 'kolibri.coreVue.vuex.store'; -import { PageNames } from '../constants'; -import { useGroups } from '../composables/useGroups'; -import GroupsPage from '../views/plan/GroupsPage'; -import GroupMembersPage from '../views/plan/GroupMembersPage'; -import GroupEnrollPage from '../views/plan/GroupEnrollPage'; -import planLessonsRoutes from './planLessonsRoutes'; -import planExamRoutes from './planExamRoutes'; - -const { showGroupsPage } = useGroups(); - -export default [ - ...planLessonsRoutes, - ...planExamRoutes, - { - name: PageNames.PLAN_PAGE, - path: '/:classId?/plan', - redirect: '/:classId?/plan/lessons', - }, - { - name: GroupsPage.name, - path: '/:classId/plan/groups', - component: GroupsPage, - handler(to) { - showGroupsPage(store, to.params.classId); - }, - meta: { - titleParts: ['groupsLabel', 'CLASS_NAME'], - }, - }, - { - name: GroupMembersPage.name, - path: '/:classId/plan/groups/:groupId', - component: GroupMembersPage, - handler(to) { - showGroupsPage(store, to.params.classId); - }, - meta: { - titleParts: ['membersLabel', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - name: GroupEnrollPage.name, - path: '/:classId/plan/groups/:groupId/enroll', - component: GroupEnrollPage, - handler(to) { - showGroupsPage(store, to.params.classId); - }, - }, -]; diff --git a/kolibri/plugins/coach/assets/src/routes/reportRoutes.js b/kolibri/plugins/coach/assets/src/routes/reportRoutes.js deleted file mode 100644 index 0025eb1d632..00000000000 --- a/kolibri/plugins/coach/assets/src/routes/reportRoutes.js +++ /dev/null @@ -1,559 +0,0 @@ -import store from 'kolibri.coreVue.vuex.store'; -import { PageNames } from '../constants'; -import pages from '../views/reports/allReportsPages'; -import { - generateExerciseDetailHandler, - exerciseRootRedirectHandler, -} from '../modules/exerciseDetail/handlers'; -import { generateExamReportDetailHandler } from '../modules/examReportDetail/handlers'; -import { - generateQuestionDetailHandler, - questionRootRedirectHandler, -} from '../modules/questionDetail/handlers'; -import { generateQuestionListHandler } from '../modules/questionList/handlers'; -import { generateResourceHandler } from '../modules/resourceDetail/handlers'; -import LessonEditDetailsPage from '../views/plan/LessonEditDetailsPage'; -import { classIdParamRequiredGuard } from './utils'; - -const ACTIVITY = '/activity'; -const OPTIONAL_CLASS = '/:classId?/reports'; -const CLASS = '/:classId/reports'; -const GROUPS = '/groups'; -const GROUP = '/groups/:groupId'; -const LEARNERS = '/learners'; -const LEARNER = '/learners/:learnerId'; -const LESSONS = '/lessons'; -const LESSON = '/lessons/:lessonId'; -const QUIZZES = '/quizzes'; -const QUIZ = '/quizzes/:quizId'; -const QUESTIONS = '/questions'; -const QUESTION = '/questions/:questionId'; -const TRY = '/try/:tryIndex'; -const INTERACTION = '/interactions/:interactionIndex'; -const EXERCISE = '/exercises/:exerciseId'; -const RESOURCES = '/resources'; -const RESOURCE = '/resources/:resourceId'; - -function path(...args) { - return args.join(''); -} - -function defaultHandler() { - store.dispatch('notLoading'); -} - -export default [ - { - name: PageNames.REPORTS_PAGE, - path: path(OPTIONAL_CLASS), - redirect: { name: 'ReportsLessonListPage' }, - }, - { - path: path(CLASS, GROUP, ACTIVITY), - component: pages.ReportsGroupActivityPage, - handler: defaultHandler, - meta: { - titleParts: ['activityLabel', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, LEARNERS), - component: pages.ReportsGroupLearnerListPage, - handler: defaultHandler, - meta: { - titleParts: ['membersLabel', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUPS), - component: pages.ReportsGroupListPage, - handler: defaultHandler, - meta: { - titleParts: ['groupsLabel', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, LESSON, LEARNER), - component: pages.ReportsGroupReportLessonLearnerPage, - handler: defaultHandler, - meta: { - titleParts: ['learnersLabel', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, LESSON, EXERCISE, LEARNERS), - component: pages.ReportsGroupReportLessonExerciseLearnerListPage, - handler: generateResourceHandler(['exerciseId']), - meta: { - titleParts: ['learnersLabel', 'EXERCISE_NAME', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, LESSON, EXERCISE, LEARNER), - name: PageNames.REPORTS_GROUP_REPORT_LESSON_EXERCISE_LEARNER_PAGE_ROOT, - beforeEnter: (to, from, next) => { - const { params } = to; - return exerciseRootRedirectHandler( - params, - pages.ReportsGroupReportLessonExerciseLearnerPage.name, - next, - ); - }, - meta: { - titleParts: ['LEARNER_NAME', 'EXERCISE_NAME', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, LESSON, EXERCISE, LEARNER, TRY, QUESTION, INTERACTION), - component: pages.ReportsGroupReportLessonExerciseLearnerPage, - handler: generateExerciseDetailHandler(['groupId', 'learnerId', 'lessonId', 'exerciseId']), - meta: { - // Leaves out attempt and interaction - titleParts: ['LEARNER_NAME', 'EXERCISE_NAME', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - - { - path: path(CLASS, GROUP, LESSON, EXERCISE, QUESTIONS), - component: pages.ReportsGroupReportLessonExerciseQuestionListPage, - handler: generateQuestionListHandler(['groupId', 'lessonId', 'exerciseId']), - meta: { - titleParts: ['questionsLabel', 'EXERCISE_NAME', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, LESSON, EXERCISE, QUESTION), - name: PageNames.REPORTS_GROUP_REPORT_LESSON_EXERCISE_QUESTION_PAGE_ROOT, - beforeEnter: (to, from, next) => { - const { params } = to; - return questionRootRedirectHandler( - params, - pages.ReportsGroupReportLessonExerciseQuestionPage.name, - next, - ); - }, - }, - { - path: path(CLASS, GROUP, LESSON, EXERCISE, QUESTION, LEARNER, INTERACTION), - component: pages.ReportsGroupReportLessonExerciseQuestionPage, - handler: generateQuestionDetailHandler(['groupId', 'lessonId', 'exerciseId', 'questionId']), - meta: { - // Leaves out info on question - titleParts: ['questionLabel', 'EXERCISE_NAME', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, LESSON, RESOURCES), - component: pages.ReportsGroupReportLessonPage, - handler: defaultHandler, - meta: { - titleParts: ['LESSON_NAME', 'LEARNER_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, LESSON, LEARNERS), - component: pages.ReportsGroupReportLessonLearnerListPage, - handler: defaultHandler, - meta: { - titleParts: ['LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, LESSON, RESOURCE, LEARNERS), - component: pages.ReportsGroupReportLessonResourceLearnerListPage, - handler: generateResourceHandler(['resourceId']), - meta: { - titleParts: ['learnersLabel', 'RESOURCE_NAME', 'LESSON_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, '/reports'), - component: pages.ReportsGroupReportPage, - handler: defaultHandler, - meta: { - titleParts: ['reportsLabel', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, QUIZ, LEARNERS), - component: pages.ReportsGroupReportQuizLearnerListPage, - handler: defaultHandler, - meta: { - titleParts: ['learnersLabel', 'QUIZ_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, QUIZ, LEARNER), - name: PageNames.REPORTS_GROUP_REPORT_QUIZ_LEARNER_PAGE_ROOT, - redirect: to => { - const { params } = to; - return { - name: pages.ReportsGroupReportQuizLearnerPage.name, - params: { - ...params, - questionId: 0, - interactionIndex: 0, - tryIndex: 0, - }, - }; - }, - }, - { - path: path(CLASS, GROUP, QUIZ, LEARNER, TRY, QUESTION, INTERACTION), - component: pages.ReportsGroupReportQuizLearnerPage, - handler: generateExamReportDetailHandler(['groupId', 'learnerId', 'quizId']), - meta: { - titleParts: ['LEARNER_NAME', 'QUIZ_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, QUIZ, QUESTIONS), - component: pages.ReportsGroupReportQuizQuestionListPage, - handler: generateQuestionListHandler(['groupId', 'quizId']), - meta: { - titleParts: ['questionsLabel', 'QUIZ_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, GROUP, QUIZ, QUESTION), - name: PageNames.REPORTS_GROUP_REPORT_QUIZ_QUESTION_PAGE_ROOT, - beforeEnter: (to, from, next) => { - const { params } = to; - return questionRootRedirectHandler( - params, - pages.ReportsGroupReportQuizQuestionPage.name, - next, - ); - }, - }, - { - path: path(CLASS, GROUP, QUIZ, QUESTION, LEARNER, INTERACTION), - component: pages.ReportsGroupReportQuizQuestionPage, - handler: generateQuestionDetailHandler(['groupId', 'quizId', 'questionId']), - meta: { - titleParts: ['questionsLabel', 'QUIZ_NAME', 'GROUP_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LEARNER, ACTIVITY, EXERCISE), - name: PageNames.REPORTS_LEARNER_ACTIVITY_EXERCISE_PAGE_ROOT, - beforeEnter: (to, from, next) => { - const { params } = to; - return exerciseRootRedirectHandler( - params, - pages.ReportsLearnerActivityExercisePage.name, - next, - ); - }, - meta: { - titleParts: ['EXERCISE_NAME', 'LEARNER_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LEARNER, ACTIVITY, EXERCISE, QUESTION, INTERACTION), - component: pages.ReportsLearnerActivityExercisePage, - handler: generateExerciseDetailHandler(['learnerId', 'exerciseId']), - meta: { - titleParts: ['EXERCISE_NAME', 'LEARNER_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LEARNER, ACTIVITY), - component: pages.ReportsLearnerActivityPage, - handler: defaultHandler, - meta: { - titleParts: ['activityLabel', 'LEARNER_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LEARNERS), - component: pages.ReportsLearnerListPage, - handler: defaultHandler, - meta: { - titleParts: ['learnersLabel', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LEARNER, LESSON, EXERCISE), - name: PageNames.REPORTS_LEARNER_REPORT_LESSON_EXERCISE_PAGE_ROOT, - beforeEnter: (to, from, next) => { - const { params } = to; - return exerciseRootRedirectHandler( - params, - pages.ReportsLearnerReportLessonExercisePage.name, - next, - ); - }, - meta: { - titleParts: ['EXERCISE_NAME', 'LESSON_NAME', 'LEARNER_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LEARNER, LESSON, EXERCISE, TRY, QUESTION, INTERACTION), - component: pages.ReportsLearnerReportLessonExercisePage, - handler: generateExerciseDetailHandler(['learnerId', 'lessonId', 'exerciseId']), - meta: { - titleParts: ['EXERCISE_NAME', 'LESSON_NAME', 'LEARNER_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LEARNER, LESSON), - component: pages.ReportsLearnerReportLessonPage, - handler: defaultHandler, - meta: { - titleParts: ['LESSON_NAME', 'LEARNER_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LEARNER, '/reports'), - component: pages.ReportsLearnerReportPage, - handler: defaultHandler, - meta: { - titleParts: ['reportsLabel', 'LEARNER_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LEARNER, QUIZ), - name: PageNames.REPORTS_LEARNER_REPORT_QUIZ_PAGE_ROOT, - redirect: to => { - const { params } = to; - return { - name: pages.ReportsLearnerReportQuizPage.name, - params: { - ...params, - questionId: 0, - interactionIndex: 0, - }, - }; - }, - }, - { - path: path(CLASS, LEARNER, QUIZ, TRY, QUESTION, INTERACTION), - component: pages.ReportsLearnerReportQuizPage, - handler: generateExamReportDetailHandler(['learnerId', 'quizId']), - meta: { - titleParts: ['QUIZ_NAME', 'LEARNER_NAME', 'CLASS_NAME'], - }, - }, - { - name: 'LessonReportEditDetailsPage', - path: path(CLASS, LESSON, '/edit'), - component: LessonEditDetailsPage, - props: { - showResourcesTable: true, - }, - handler: defaultHandler, - }, - { - path: path(CLASS, LESSON, EXERCISE, LEARNERS), - component: pages.ReportsLessonExerciseLearnerListPage, - handler: generateResourceHandler(['exerciseId']), - meta: { - titleParts: ['learnersLabel', 'EXERCISE_NAME', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LESSON, EXERCISE, LEARNER), - name: PageNames.REPORTS_LESSON_EXERCISE_LEARNER_PAGE_ROOT, - beforeEnter: (to, from, next) => { - const { params, query } = to; - return exerciseRootRedirectHandler( - params, - pages.ReportsLessonExerciseLearnerPage.name, - next, - query, - ); - }, - meta: { - titleParts: ['LEARNER_NAME', 'EXERCISE_NAME', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - - { - path: path(CLASS, LESSON, EXERCISE, LEARNER, TRY, QUESTION, INTERACTION), - component: pages.ReportsLessonExerciseLearnerPage, - handler: generateExerciseDetailHandler(['learnerId', 'lessonId', 'exerciseId']), - meta: { - titleParts: ['LEARNER_NAME', 'EXERCISE_NAME', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LESSON, EXERCISE, QUESTIONS), - component: pages.ReportsLessonExerciseQuestionListPage, - handler: generateQuestionListHandler(['lessonId', 'exerciseId']), - meta: { - titleParts: ['questionsLabel', 'EXERCISE_NAME', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - - { - path: path(CLASS, LESSON, EXERCISE, QUESTION), - name: PageNames.REPORTS_LESSON_EXERCISE_QUESTION_PAGE_ROOT, - beforeEnter: (to, from, next) => { - const { params } = to; - return questionRootRedirectHandler( - params, - pages.ReportsLessonExerciseQuestionPage.name, - next, - ); - }, - }, - { - path: path(CLASS, LESSON, EXERCISE, QUESTION, LEARNER, INTERACTION), - component: pages.ReportsLessonExerciseQuestionPage, - handler: generateQuestionDetailHandler(['lessonId', 'exerciseId', 'questionId']), - meta: { - // No info on question - titleParts: ['EXERCISE_NAME', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LESSON, LEARNER, EXERCISE), - name: PageNames.REPORTS_LESSON_LEARNER_EXERCISE_PAGE_ROOT, - beforeEnter: (to, from, next) => { - const { params } = to; - return exerciseRootRedirectHandler(params, pages.ReportsLessonLearnerExercisePage.name, next); - }, - meta: { - titleParts: ['EXERCISE_NAME', 'LEARNER_NAME', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LESSON, LEARNER, EXERCISE, TRY, QUESTION, INTERACTION), - component: pages.ReportsLessonLearnerExercisePage, - handler: generateExerciseDetailHandler(['learnerId', 'lessonId', 'exerciseId']), - meta: { - // Leaves out attempt and interaction numbers - titleParts: ['LEARNER_NAME', 'EXERCISE_NAME', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LESSON, LEARNERS), - component: pages.ReportsLessonLearnerListPage, - handler: defaultHandler, - meta: { - titleParts: ['learnersLabel', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LESSON, LEARNER), - component: pages.ReportsLessonLearnerPage, - handler: defaultHandler, - meta: { - titleParts: ['LEARNER_NAME', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(OPTIONAL_CLASS, LESSONS), - component: pages.ReportsLessonListPage, - handler: (toRoute, fromRoute, next) => { - if (classIdParamRequiredGuard(toRoute, 'ReportsLessonListPage', next)) { - return; - } - defaultHandler(); - }, - - meta: { - titleParts: ['lessonsLabel', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LESSON, '/manager'), - component: pages.ReportsLessonManagerPage, - handler: defaultHandler, - meta: { - titleParts: ['manageResourcesAction', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LESSON, RESOURCES), - component: pages.ReportsLessonReportPage, - handler: defaultHandler, - meta: { - titleParts: ['reportLabel', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, LESSON, RESOURCE, LEARNERS), - component: pages.ReportsLessonResourceLearnerListPage, - handler: generateResourceHandler(['resourceId']), - meta: { - titleParts: ['RESOURCE_NAME', 'LESSON_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, QUIZ, LEARNERS), - component: pages.ReportsQuizLearnerListPage, - handler: defaultHandler, - meta: { - titleParts: ['learnersLabel', 'QUIZ_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, QUIZ, LEARNER), - name: PageNames.REPORTS_QUIZ_LEARNER_PAGE_ROOT, - redirect: to => { - const { params } = to; - return { - name: pages.ReportsQuizLearnerPage.name, - params: { - ...params, - questionId: 0, - tryIndex: 0, - interactionIndex: 0, - }, - }; - }, - }, - { - path: path(CLASS, QUIZ, LEARNER, TRY, QUESTION, INTERACTION), - component: pages.ReportsQuizLearnerPage, - handler: generateExamReportDetailHandler(['learnerId', 'quizId']), - meta: { - // Leaves out question and interaction numbers - titleParts: ['LEARNER_NAME', 'QUIZ_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, QUIZZES), - component: pages.ReportsQuizListPage, - handler: defaultHandler, - meta: { - titleParts: ['quizzesLabel', 'CLASS_NAME'], - }, - }, - { - name: pages.ReportsQuizPreviewPage.name, - path: path(CLASS, QUIZ, '/preview'), - component: pages.ReportsQuizPreviewPage, - handler: defaultHandler, - meta: { - titleParts: ['previewLabel', 'QUIZ_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, QUIZ, QUESTIONS), - component: pages.ReportsQuizQuestionListPage, - handler: generateQuestionListHandler(['quizId']), - meta: { - titleParts: ['questionsLabel', 'QUIZ_NAME', 'CLASS_NAME'], - }, - }, - { - path: path(CLASS, QUIZ, QUESTION), - name: PageNames.REPORTS_QUIZ_QUESTION_PAGE_ROOT, - beforeEnter: (to, from, next) => { - const { params } = to; - return questionRootRedirectHandler(params, pages.ReportsQuizQuestionPage.name, next); - }, - }, - { - path: path(CLASS, QUIZ, QUESTION, LEARNER, INTERACTION), - component: pages.ReportsQuizQuestionPage, - handler: generateQuestionDetailHandler(['quizId', 'questionId']), - meta: { - // TODO Leaves out details about the question - titleParts: ['QUIZ_NAME', 'CLASS_NAME'], - }, - }, -]; diff --git a/kolibri/plugins/coach/assets/src/routes/utils.js b/kolibri/plugins/coach/assets/src/routes/utils.js index 1e782970e16..7a7bcc6daa0 100644 --- a/kolibri/plugins/coach/assets/src/routes/utils.js +++ b/kolibri/plugins/coach/assets/src/routes/utils.js @@ -15,3 +15,29 @@ export function classIdParamRequiredGuard(toRoute, subtopicName, next) { return true; } } + +export const RouteSegments = { + OPTIONAL_CLASS: '/:classId?', + CLASS: '/:classId', + LESSON: '/lessons/:lessonId', + ALL_LESSONS: '/lessons', + ALL_LESSONS_TEMP: '/lessonstemp', + LESSONS_TEMP: '/lessonstemp/:lessonId', + SELECTION: '/selection', + TOPIC: '/topic/:topicId', + SEARCH: '/search/:searchTerm', + PREVIEW: '/preview/:contentId', + RESOURCE: '/resources/:resourceId', + ALL_LEARNERS: '/learners', + LEARNER: '/learners/:learnerId', + EXERCISE: '/exercises/:exerciseId', + QUESTIONS: '/questions', + QUESTION: '/questions/:questionId', + TRY: '/try/:tryIndex', + INTERACTION: '/interactions/:interactionIndex', + OPTIONAL_GROUP: '/groups/:groupId?', + ALL_GROUPS: '/groups', + GROUP: '/groups/:groupId', + QUIZ: '/quizzes/:quizId', + ALL_QUIZZES: '/quizzes', +}; diff --git a/kolibri/plugins/coach/assets/src/views/ClassLearnersListPage.vue b/kolibri/plugins/coach/assets/src/views/ClassLearnersListPage.vue index b18f84e8dfe..ba61442e3b7 100644 --- a/kolibri/plugins/coach/assets/src/views/ClassLearnersListPage.vue +++ b/kolibri/plugins/coach/assets/src/views/ClassLearnersListPage.vue @@ -112,6 +112,7 @@ mixins: [commonCoreStrings], data: function () { return { + prevRoute: null, displayTroubleshootModal: false, classSyncStatusList: {}, // poll every 10 seconds @@ -137,8 +138,10 @@ backlink() { if (this.$route.query.last === 'homepage') { return { name: PageNames.HOME_PAGE, params: { classId: this.$route.params.classId } }; + } else if (this.prevRoute) { + return this.prevRoute; } else { - return { name: 'ReportsQuizListPage', params: { classId: this.$route.params.classId } }; + return { name: PageNames.LESSONS_ROOT, params: { classId: this.$route.params.classId } }; } }, learnerHasInsufficientStorage() { @@ -151,6 +154,11 @@ return false; }, }, + beforeRouteEnter(to, from, next) { + next(vm => { + vm.prevRoute = from; + }); + }, mounted() { this.isPolling = true; this.pollClassListSyncStatuses(); diff --git a/kolibri/plugins/coach/assets/src/views/CoachSideNavEntry.js b/kolibri/plugins/coach/assets/src/views/CoachSideNavEntry.js index f37b4f4e5b7..265cb4df57e 100644 --- a/kolibri/plugins/coach/assets/src/views/CoachSideNavEntry.js +++ b/kolibri/plugins/coach/assets/src/views/CoachSideNavEntry.js @@ -18,16 +18,28 @@ registerNavItem({ name: baseRoutes.classHome.name, }, { - label: coachStrings.$tr('reportsLabel'), - route: baseRoutes.reports.path, - icon: 'reports', - name: baseRoutes.reports.name, + label: coachStrings.$tr('lessonsLabel'), + route: baseRoutes.lessons.path, + icon: 'lesson', + name: baseRoutes.lessons.name, }, { - label: coachStrings.$tr('planLabel'), - route: baseRoutes.plan.path, - icon: 'edit', - name: baseRoutes.plan.name, + label: coachStrings.$tr('quizzesLabel'), + route: baseRoutes.quizzes.path, + icon: 'quiz', + name: baseRoutes.quizzes.name, + }, + { + label: coachStrings.$tr('learnersLabel'), + route: baseRoutes.learners.path, + icon: 'person', + name: baseRoutes.learners.name, + }, + { + label: coachStrings.$tr('groupsLabel'), + route: baseRoutes.groups.path, + icon: 'group', + name: baseRoutes.groups.name, }, ]; }, diff --git a/kolibri/plugins/coach/assets/src/views/StorageNotificationBanner.vue b/kolibri/plugins/coach/assets/src/views/StorageNotificationBanner.vue index e0fb804baf1..5e8981639cf 100644 --- a/kolibri/plugins/coach/assets/src/views/StorageNotificationBanner.vue +++ b/kolibri/plugins/coach/assets/src/views/StorageNotificationBanner.vue @@ -58,7 +58,7 @@ ...mapState('classSummary', { classId: 'id' }), url() { return { - name: PageNames.PLAN_PAGE, + name: PageNames.LESSONS_ROOT, classId: this.classId, }; }, diff --git a/kolibri/plugins/coach/assets/src/views/common.js b/kolibri/plugins/coach/assets/src/views/common.js index 19d10e017e7..7d769551a8e 100644 --- a/kolibri/plugins/coach/assets/src/views/common.js +++ b/kolibri/plugins/coach/assets/src/views/common.js @@ -168,7 +168,7 @@ export default { return router.getRoute(name, params, query); }, // Set the backLinkQuery to set the correct exit behavior - // for ReportsLessonExerciseLearnerPage and ReportsQuizLearnerPage. + // for LessonExerciseLearnerPage and QUIZ_LEARNER_PAGE_ROOT. backRouteForQuery(query) { const lastPage = query.last; @@ -177,21 +177,17 @@ export default { return this.classRoute('HomePage', {}); case LastPages.HOME_ACTIVITY: return this.classRoute('HomeActivityPage', {}); - case LastPages.GROUP_ACTIVITY: - return this.classRoute('ReportsGroupActivityPage', { - groupId: this.$route.query.last_id, - }); case LastPages.LEARNER_ACTIVITY: return this.classRoute('ReportsLearnerActivityPage', { learnerId: this.$route.query.last_id, }); case LastPages.EXERCISE_LEARNER_LIST: - return this.classRoute('ReportsLessonExerciseLearnerListPage', { + return this.classRoute(PageNames.LESSON_EXERCISE_LEARNERS_REPORT, { exerciseId: this.$route.query.exerciseId, }); case LastPages.EXERCISE_LEARNER_LIST_BY_GROUPS: return this.classRoute( - 'ReportsLessonExerciseLearnerListPage', + PageNames.LESSON_EXERCISE_LEARNERS_REPORT, { exerciseId: this.$route.query.exerciseId, }, @@ -200,16 +196,16 @@ export default { }, ); case LastPages.EXERCISE_QUESTION_LIST: - return this.classRoute('ReportsLessonExerciseQuestionListPage', { + return this.classRoute(PageNames.LESSON_EXERCISE_QUESTIONS_REPORT, { exerciseId: this.$route.query.exerciseId, }); case LastPages.RESOURCE_LEARNER_LIST: - return this.classRoute('ReportsLessonResourceLearnerListPage', { + return this.classRoute(PageNames.LESSON_RESOURCE_LEARNERS_REPORT, { resourceId: this.$route.query.resourceId, }); case LastPages.RESOURCE_LEARNER_LIST_BY_GROUPS: return this.classRoute( - 'ReportsLessonResourceLearnerListPage', + PageNames.LESSON_RESOURCE_LEARNERS_REPORT, { resourceId: this.$route.query.resourceId, }, diff --git a/kolibri/plugins/coach/assets/src/views/common/CoachHeader.vue b/kolibri/plugins/coach/assets/src/views/common/CoachHeader.vue new file mode 100644 index 00000000000..064207d75dc --- /dev/null +++ b/kolibri/plugins/coach/assets/src/views/common/CoachHeader.vue @@ -0,0 +1,62 @@ + + + + + + + diff --git a/kolibri/plugins/coach/assets/src/views/common/LearnerQuizReport.vue b/kolibri/plugins/coach/assets/src/views/common/LearnerQuizReport.vue deleted file mode 100644 index c11fa259f69..00000000000 --- a/kolibri/plugins/coach/assets/src/views/common/LearnerQuizReport.vue +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - diff --git a/kolibri/plugins/coach/assets/src/views/common/QuestionLearnersReport.vue b/kolibri/plugins/coach/assets/src/views/common/QuestionLearnersReport.vue deleted file mode 100644 index 1c015bf50e8..00000000000 --- a/kolibri/plugins/coach/assets/src/views/common/QuestionLearnersReport.vue +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - - diff --git a/kolibri/plugins/coach/assets/src/views/reports/ReportsControls.vue b/kolibri/plugins/coach/assets/src/views/common/ReportsControls.vue similarity index 91% rename from kolibri/plugins/coach/assets/src/views/reports/ReportsControls.vue rename to kolibri/plugins/coach/assets/src/views/common/ReportsControls.vue index dcfedd2071a..5b0e3d5c4b7 100644 --- a/kolibri/plugins/coach/assets/src/views/reports/ReportsControls.vue +++ b/kolibri/plugins/coach/assets/src/views/common/ReportsControls.vue @@ -51,6 +51,7 @@ import commonCoach from '../common'; import { ClassesPageNames } from '../../../../../learn/assets/src/constants'; import { LastPages } from '../../constants/lastPagesConstants'; + import { PageNames } from '../../constants'; export default { name: 'ReportsControls', @@ -75,15 +76,12 @@ }, isMainReport() { return [ - 'ReportsQuizListPage', - 'ReportsGroupListPage', - 'ReportsLearnerListPage', - 'ReportsLessonListPage', - 'QuizSummaryPage', - 'PLAN_LESSONS_ROOT', - 'PLAN_LESSONS_ROOT_BETTER', - 'EXAMS', - 'SUMMARY', + PageNames.LEARNERS_ROOT, + PageNames.LESSONS_ROOT, + PageNames.LESSONS_ROOT_BETTER, + PageNames.EXAMS_ROOT, + PageNames.EXAM_SUMMARY, + PageNames.LESSON_SUMMARY, ].includes(this.$route.name); }, classLearnersListRoute() { diff --git a/kolibri/plugins/coach/assets/src/views/reports/ReportsResourceHeader.vue b/kolibri/plugins/coach/assets/src/views/common/ReportsResourceHeader.vue similarity index 91% rename from kolibri/plugins/coach/assets/src/views/reports/ReportsResourceHeader.vue rename to kolibri/plugins/coach/assets/src/views/common/ReportsResourceHeader.vue index 33ac369a1b9..786cf070717 100644 --- a/kolibri/plugins/coach/assets/src/views/reports/ReportsResourceHeader.vue +++ b/kolibri/plugins/coach/assets/src/views/common/ReportsResourceHeader.vue @@ -8,8 +8,8 @@ @@ -117,16 +117,16 @@ :text="coachString('reportLabel')" :to=" group - ? classRoute('ReportsGroupReportLessonExerciseLearnerListPage') - : classRoute('ReportsLessonExerciseLearnerListPage') + ? classRoute(PageNames.GROUP_LESSON_EXERCISE_LEARNER_REPORT) + : classRoute(PageNames.LESSON_EXERCISE_LEARNERS_REPORT) " /> @@ -150,6 +150,7 @@ import markdownIt from 'markdown-it'; import HeaderWithOptions from '../common/HeaderWithOptions'; import commonCoach from '../common'; + import { PageNames } from '../../constants'; export default { name: 'ReportsResourceHeader', @@ -166,6 +167,11 @@ required: true, }, }, + data() { + return { + PageNames, + }; + }, computed: { practiceQuiz() { return get(this, ['resource', 'options', 'modality']) === Modalities.QUIZ; diff --git a/kolibri/plugins/coach/assets/src/views/plan/assignments/AssignmentCopyModal.vue b/kolibri/plugins/coach/assets/src/views/common/assignments/AssignmentCopyModal.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/assignments/AssignmentCopyModal.vue rename to kolibri/plugins/coach/assets/src/views/common/assignments/AssignmentCopyModal.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/assignments/AssignmentDeleteModal.vue b/kolibri/plugins/coach/assets/src/views/common/assignments/AssignmentDeleteModal.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/assignments/AssignmentDeleteModal.vue rename to kolibri/plugins/coach/assets/src/views/common/assignments/AssignmentDeleteModal.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/assignments/AssignmentDetailsModal.vue b/kolibri/plugins/coach/assets/src/views/common/assignments/AssignmentDetailsModal.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/assignments/AssignmentDetailsModal.vue rename to kolibri/plugins/coach/assets/src/views/common/assignments/AssignmentDetailsModal.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/assignments/IndividualLearnerSelector.vue b/kolibri/plugins/coach/assets/src/views/common/assignments/IndividualLearnerSelector.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/assignments/IndividualLearnerSelector.vue rename to kolibri/plugins/coach/assets/src/views/common/assignments/IndividualLearnerSelector.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/assignments/RecipientSelector.vue b/kolibri/plugins/coach/assets/src/views/common/assignments/RecipientSelector.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/assignments/RecipientSelector.vue rename to kolibri/plugins/coach/assets/src/views/common/assignments/RecipientSelector.vue diff --git a/kolibri/plugins/coach/assets/src/views/common/notifications/ActivityList.vue b/kolibri/plugins/coach/assets/src/views/common/notifications/ActivityList.vue index 106fde355d1..ecaf428117d 100644 --- a/kolibri/plugins/coach/assets/src/views/common/notifications/ActivityList.vue +++ b/kolibri/plugins/coach/assets/src/views/common/notifications/ActivityList.vue @@ -80,11 +80,7 @@ type: String, required: true, validator(value) { - return [ - 'HomeActivityPage', - 'ReportsLearnerActivityPage', - 'ReportsGroupActivityPage', - ].includes(value); + return ['HomeActivityPage', 'ReportsLearnerActivityPage'].includes(value); }, }, }, @@ -117,8 +113,6 @@ return { last: LastPages.HOME_ACTIVITY }; case 'ReportsLearnerActivityPage': return { last: LastPages.LEARNER_ACTIVITY, last_id: this.$route.params.learnerId }; - case 'ReportsGroupActivityPage': - return { last: LastPages.GROUP_ACTIVITY, last_id: this.$route.params.groupId }; default: return {}; } @@ -127,8 +121,6 @@ switch (this.embeddedPageName) { case 'ReportsLearnerActivityPage': return { learner_id: this.$route.params.learnerId }; - case 'ReportsGroupActivityPage': - return { group_id: this.$route.params.groupId }; default: return {}; } @@ -163,7 +155,6 @@ // Filter incoming notifications according to the embedded page // For HomeActivityPage - no filter // For ReportsLearnerActivityPage - notification.user_id === current learnerId - // For ReportsGroupActivityPage - notification.user_id in group.users notificationsFilter(notification) { if (notification.event === 'Answered') { return false; @@ -174,14 +165,8 @@ if (this.embeddedPageName === 'ReportsLearnerActivityPage') { return notification.user_id === this.$route.params.learnerId; } - if (this.embeddedPageName === 'ReportsGroupActivityPage') { - return this.notificationBelongsToGroup(notification, this.$route.params.groupId); - } return true; }, - notificationBelongsToGroup(notification, groupId) { - return notification.assignment_collections.includes(groupId); - }, showNotification(notification) { if (this.noFiltersApplied) { return true; diff --git a/kolibri/plugins/coach/assets/src/views/common/notifications/__test__/ActivityList.spec.js b/kolibri/plugins/coach/assets/src/views/common/notifications/__test__/ActivityList.spec.js index c180dfda848..e2c8f9e7476 100644 --- a/kolibri/plugins/coach/assets/src/views/common/notifications/__test__/ActivityList.spec.js +++ b/kolibri/plugins/coach/assets/src/views/common/notifications/__test__/ActivityList.spec.js @@ -206,16 +206,6 @@ describe('ActivityList component', () => { last: LastPages.LEARNER_ACTIVITY, last_id: 'learner_001', }); - - // Embed in Group Activity Page - wrapper.setProps({ - embeddedPageName: 'ReportsGroupActivityPage', - }); - await wrapper.vm.$nextTick(); - expect(wrapper.vm.backLinkQuery).toEqual({ - last: LastPages.GROUP_ACTIVITY, - last_id: 'group_001', - }); }); // Not tested: diff --git a/kolibri/plugins/coach/assets/src/views/common/notifications/__test__/NotificationCard.spec.js b/kolibri/plugins/coach/assets/src/views/common/notifications/__test__/NotificationCard.spec.js index 6f97a72b0f4..62bf6f9cf28 100644 --- a/kolibri/plugins/coach/assets/src/views/common/notifications/__test__/NotificationCard.spec.js +++ b/kolibri/plugins/coach/assets/src/views/common/notifications/__test__/NotificationCard.spec.js @@ -6,6 +6,7 @@ import { NotificationEvents, NotificationObjects, } from '../../../../constants/notificationsConstants'; +import { PageNames } from '../../../../constants'; const router = new VueRouter({ routes: [ @@ -68,7 +69,7 @@ describe('NotificationCard component', () => { it('shows a link if a full targetPage prop is provided', () => { const { wrapper } = makeWrapper({ notification }); const link = wrapper.findComponent({ name: 'KRouterLink' }); - expect(link.props().to.name).toEqual('ReportsLessonLearnerPage'); + expect(link.props().to.name).toEqual(PageNames.LEARNER_LESSON_REPORT); expect(link.props('text')).toEqual("JB completed 'Lesson 1'"); }); diff --git a/kolibri/plugins/coach/assets/src/views/reports/ExerciseQuestionListPageBase.vue b/kolibri/plugins/coach/assets/src/views/common/reports/ExerciseQuestionListPage.vue similarity index 79% rename from kolibri/plugins/coach/assets/src/views/reports/ExerciseQuestionListPageBase.vue rename to kolibri/plugins/coach/assets/src/views/common/reports/ExerciseQuestionListPage.vue index 5290261c022..8451fad1297 100644 --- a/kolibri/plugins/coach/assets/src/views/reports/ExerciseQuestionListPageBase.vue +++ b/kolibri/plugins/coach/assets/src/views/common/reports/ExerciseQuestionListPage.vue @@ -54,17 +54,17 @@ + + + diff --git a/kolibri/plugins/coach/assets/src/views/common/reports/QuestionLearnersPage.vue b/kolibri/plugins/coach/assets/src/views/common/reports/QuestionLearnersPage.vue new file mode 100644 index 00000000000..6e3ca80d6da --- /dev/null +++ b/kolibri/plugins/coach/assets/src/views/common/reports/QuestionLearnersPage.vue @@ -0,0 +1,213 @@ + + + + + + + diff --git a/kolibri/plugins/coach/assets/src/views/reports/ReportsLearnersTable.vue b/kolibri/plugins/coach/assets/src/views/common/tables/ReportsLearnersTable.vue similarity index 97% rename from kolibri/plugins/coach/assets/src/views/reports/ReportsLearnersTable.vue rename to kolibri/plugins/coach/assets/src/views/common/tables/ReportsLearnersTable.vue index 355fe4f1121..485ea65bf50 100644 --- a/kolibri/plugins/coach/assets/src/views/reports/ReportsLearnersTable.vue +++ b/kolibri/plugins/coach/assets/src/views/common/tables/ReportsLearnersTable.vue @@ -102,9 +102,9 @@ import isUndefined from 'lodash/isUndefined'; import commonCoreStrings from 'kolibri.coreVue.mixins.commonCoreStrings'; - import commonCoach from '../common'; - import * as csvFields from '../../csv/fields'; - import CSVExporter from '../../csv/exporter'; + import commonCoach from '../../common'; + import * as csvFields from '../../../csv/fields'; + import CSVExporter from '../../../csv/exporter'; export default { name: 'ReportsLearnersTable', @@ -225,7 +225,7 @@ diff --git a/kolibri/plugins/coach/assets/src/views/reports/ReportsGroupReportLessonExerciseLearnerListPage.vue b/kolibri/plugins/coach/assets/src/views/groups/reports/GroupLessonExerciseLearnersPage.vue similarity index 82% rename from kolibri/plugins/coach/assets/src/views/reports/ReportsGroupReportLessonExerciseLearnerListPage.vue rename to kolibri/plugins/coach/assets/src/views/groups/reports/GroupLessonExerciseLearnersPage.vue index 9619c615a2e..bf58fee4a40 100644 --- a/kolibri/plugins/coach/assets/src/views/reports/ReportsGroupReportLessonExerciseLearnerListPage.vue +++ b/kolibri/plugins/coach/assets/src/views/groups/reports/GroupLessonExerciseLearnersPage.vue @@ -30,17 +30,17 @@ import sortBy from 'lodash/sortBy'; import { mapState } from 'vuex'; import commonCoreStrings from 'kolibri.coreVue.mixins.commonCoreStrings'; - import commonCoach from '../common'; - import CoachAppBarPage from '../CoachAppBarPage'; - import { PageNames } from '../../constants'; - import CSVExporter from '../../csv/exporter'; - import * as csvFields from '../../csv/fields'; - import ReportsResourceHeader from './ReportsResourceHeader'; - import ReportsControls from './ReportsControls'; - import ReportsLearnersTable from './ReportsLearnersTable'; + import commonCoach from '../../common'; + import CoachAppBarPage from '../../CoachAppBarPage'; + import { PageNames } from '../../../constants'; + import CSVExporter from '../../../csv/exporter'; + import * as csvFields from '../../../csv/fields'; + import ReportsResourceHeader from '../../common/ReportsResourceHeader'; + import ReportsControls from '../../common/ReportsControls'; + import ReportsLearnersTable from '../../common/tables/ReportsLearnersTable'; export default { - name: 'ReportsGroupReportLessonExerciseLearnerListPage', + name: 'GroupLessonExerciseLearnersPage', components: { CoachAppBarPage, ReportsResourceHeader, @@ -83,7 +83,7 @@ }, methods: { link(learnerId) { - return this.classRoute(PageNames.REPORTS_GROUP_REPORT_LESSON_EXERCISE_LEARNER_PAGE_ROOT, { + return this.classRoute(PageNames.LESSON_EXERCISE_LEARNER_PAGE_ROOT, { learnerId, }); }, @@ -124,7 +124,7 @@ diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonCreationPage/index.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonCreationPage.vue similarity index 87% rename from kolibri/plugins/coach/assets/src/views/plan/LessonCreationPage/index.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonCreationPage.vue index 1c071bfd050..ec34838c9f0 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/LessonCreationPage/index.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonCreationPage.vue @@ -6,7 +6,7 @@ authorizedRole="adminOrCoach" icon="close" :pageTitle="coachString('createLessonAction')" - :route="{ name: 'PLAN_LESSONS_ROOT', params: { classId } }" + :route="{ name: 'LESSONS_ROOT', params: { classId } }" > @@ -111,6 +111,7 @@ import CoachContentLabel from 'kolibri.coreVue.components.CoachContentLabel'; import useSnackbar from 'kolibri.coreVue.composables.useSnackbar'; import { coachStrings } from '../../common/commonCoachStrings'; + import { PageNames } from '../../../constants'; // This is a simplified version of ResourceListTable that is supposed to work // outside of the LessonSummaryPage workflow. @@ -129,6 +130,7 @@ const { createSnackbar, clearSnackbar } = useSnackbar(); const { noResourcesInLessonLabel$ } = coachStrings; return { + PageNames, noResourcesInLessonLabel$, createSnackbar, clearSnackbar, diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonEditDetailsPage/EditLessonDetails.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonEditDetailsPage/EditLessonDetails.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonEditDetailsPage/EditLessonDetails.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonEditDetailsPage/EditLessonDetails.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonEditDetailsPage/index.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonEditDetailsPage/index.vue similarity index 92% rename from kolibri/plugins/coach/assets/src/views/plan/LessonEditDetailsPage/index.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonEditDetailsPage/index.vue index 8b71a6a5640..c6696254370 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/LessonEditDetailsPage/index.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonEditDetailsPage/index.vue @@ -40,7 +40,8 @@ import useSnackbar from 'kolibri.coreVue.composables.useSnackbar'; import { coachStringsMixin } from '../../common/commonCoachStrings'; import CoachImmersivePage from '../../CoachImmersivePage'; - import AssignmentDetailsModal from '../assignments/AssignmentDetailsModal'; + import AssignmentDetailsModal from '../../common/assignments/AssignmentDetailsModal'; + import { PageNames } from '../../../constants'; import ResourceListTable from './EditDetailsResourceListTable'; export default { @@ -91,14 +92,7 @@ }; }, previousPageRoute() { - let route; - if (this.$route.name === 'LessonEditDetailsPage') { - // i.e. Lesson Summary - route = 'SUMMARY'; - } else { - route = 'ReportsLessonReportPage'; - } - return this.$router.getRoute(route); + return this.$router.getRoute(PageNames.LESSON_SUMMARY); }, }, created() { @@ -169,12 +163,12 @@ pageTitle: { message: `Edit lesson details for '{title}'`, context: - "Page title for page which coach accesses using the 'Edit details' option on the Plan > Lessons tab.", + "Page title for page which coach accesses using the 'Edit details' option on the Lessons tab.", }, appBarTitle: { message: 'Edit lesson details', context: - "Title of window that displays when coach uses the 'Edit details' option on the 'Plan' tab.", + "Title of window that displays when coach uses the 'Edit details' option on the 'Lessons' tab.", }, submitErrorMessage: { message: 'There was a problem saving your changes', diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/ContentCardList.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/ContentCardList.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/ContentCardList.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/ContentCardList.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/LessonContentCard/BookmarkIcon.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/LessonContentCard/BookmarkIcon.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/LessonContentCard/BookmarkIcon.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/LessonContentCard/BookmarkIcon.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/LessonContentCard/CardThumbnail.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/LessonContentCard/CardThumbnail.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/LessonContentCard/CardThumbnail.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/LessonContentCard/CardThumbnail.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/LessonContentCard/card.scss b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/LessonContentCard/card.scss similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/LessonContentCard/card.scss rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/LessonContentCard/card.scss diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/LessonContentCard/index.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/LessonContentCard/index.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/LessonContentCard/index.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/LessonContentCard/index.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/LessonResourceSelection.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/LessonResourceSelection.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/LessonResourceSelection.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/LessonResourceSelection.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/SearchTools/LessonsSearchBox.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/SearchTools/LessonsSearchBox.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/SearchTools/LessonsSearchBox.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/SearchTools/LessonsSearchBox.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/SearchTools/LessonsSearchFilters.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/SearchTools/LessonsSearchFilters.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/SearchTools/LessonsSearchFilters.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/SearchTools/LessonsSearchFilters.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/SearchTools/ResourceSelectionBreadcrumbs.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/SearchTools/ResourceSelectionBreadcrumbs.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/SearchTools/ResourceSelectionBreadcrumbs.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/SearchTools/ResourceSelectionBreadcrumbs.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/SearchTools/__tests__/LessonsSearchFilters.spec.js b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/SearchTools/__tests__/LessonsSearchFilters.spec.js similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/SearchTools/__tests__/LessonsSearchFilters.spec.js rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/SearchTools/__tests__/LessonsSearchFilters.spec.js diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/__test__/LessonResourceSelectionPage.spec.js b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/__test__/LessonResourceSelectionPage.spec.js similarity index 74% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/__test__/LessonResourceSelectionPage.spec.js rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/__test__/LessonResourceSelectionPage.spec.js index d390fe19c6e..88730588299 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/__test__/LessonResourceSelectionPage.spec.js +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/__test__/LessonResourceSelectionPage.spec.js @@ -3,6 +3,7 @@ import VueRouter from 'vue-router'; import { BookmarksResource } from 'kolibri.resources'; import LessonResourceSelectionPage from '../index.vue'; import makeStore from '../../../../../test/makeStore'; +import { PageNames } from '../../../../constants'; jest.mock('kolibri.client'); jest.mock('kolibri.urls'); @@ -11,13 +12,11 @@ jest.mock('kolibri.coreVue.composables.useUser'); const router = new VueRouter({ routes: [ - { name: 'SUMMARY', path: '/summary' }, + { name: PageNames.LESSON_SUMMARY, path: '/summary' }, { name: 'SELECT_RESOURCES', path: '/' }, - { name: 'SELECTION_ROOT', path: '/select' }, - { name: 'SELECTION', path: '/select/:topicId' }, - { name: 'SELECTION_SEARCH', path: '/search/:searchTerm' }, - { name: 'ReportsLessonReportPage', path: '/reportslessonreportpage' }, - { name: 'ReportsLessonLearnerListPage', path: '/reportslessonlearnerlistpage' }, + { name: 'LESSON_RESOURCE_SELECTION_ROOT', path: '/select' }, + { name: 'LESSON_RESOURCE_SELECTION', path: '/select/:topicId' }, + { name: 'LESSON_RESOURCE_SELECTION_SEARCH', path: '/search/:searchTerm' }, ], }); @@ -28,7 +27,7 @@ const slotDiv = { }; const store = makeStore(); -store.state.toolbarRoute = { name: 'SUMMARY' }; +store.state.toolbarRoute = { name: PageNames.LESSON_SUMMARY }; function makeWrapper() { const wrapper = shallowMount(LessonResourceSelectionPage, { @@ -52,9 +51,9 @@ describe('LessonResourceSelectionPage', () => { }; beforeAll(() => { - store.state.pageName = 'SELECTION_SEARCH'; + store.state.pageName = 'LESSON_RESOURCE_SELECTION_SEARCH'; router.replace({ - name: 'SELECTION_SEARCH', + name: 'LESSON_RESOURCE_SELECTION_SEARCH', params: { searchTerm: 'painting' }, query: { last_id: 'last_topic_id', ...filterValues }, }); @@ -77,7 +76,7 @@ describe('LessonResourceSelectionPage', () => { // If last_id is in URL, link back to the topic page expect(button.props().to).toEqual({ - name: 'SELECTION', + name: 'LESSON_RESOURCE_SELECTION', params: { topicId: 'last_topic_id', }, @@ -87,11 +86,11 @@ describe('LessonResourceSelectionPage', () => { }, }); - // If there is no last_id in query params, link to SELECTION_ROOT + // If there is no last_id in query params, link to LESSON_RESOURCE_SELECTION_ROOT const noLastIdQuery = { ...filterValues }; await router.replace({ query: noLastIdQuery }); expect(button.props().to).toEqual({ - name: 'SELECTION_ROOT', + name: 'LESSON_RESOURCE_SELECTION_ROOT', params: {}, query: { ...filterValues, @@ -104,9 +103,9 @@ describe('LessonResourceSelectionPage', () => { let wrapper; beforeAll(() => { - store.state.pageName = 'SELECTION'; + store.state.pageName = 'LESSON_RESOURCE_SELECTION'; router.replace({ - name: 'SELECTION', + name: 'LESSON_RESOURCE_SELECTION', params: { topicId: 'topic_id' }, }); wrapper = makeWrapper().wrapper; @@ -115,7 +114,7 @@ describe('LessonResourceSelectionPage', () => { it('the breadcrumbs are visible and have the correct links', () => { const breadcrumbs = wrapper.findComponent({ name: 'ResourceSelectionBreadcrumbs' }); expect(breadcrumbs.exists()).toBe(true); - expect(breadcrumbs.props().channelsLink.name).toEqual('SELECTION_ROOT'); + expect(breadcrumbs.props().channelsLink.name).toEqual('LESSON_RESOURCE_SELECTION_ROOT'); }); it('the bottom bar has the correct label and link if coming from reports page', async () => { @@ -127,14 +126,11 @@ describe('LessonResourceSelectionPage', () => { const exitRoute = () => button.props().to.name; // Exit link goes to Lesson Summary page by default - expect(exitRoute()).toEqual('SUMMARY'); + expect(exitRoute()).toEqual(PageNames.LESSON_SUMMARY); // Exit link goes to report page if that's in the URL - await router.replace({ query: { last: 'ReportsLessonReportPage' } }); - expect(exitRoute()).toEqual('ReportsLessonReportPage'); - - await router.replace({ query: { last: 'ReportsLessonLearnerListPage' } }); - expect(exitRoute()).toEqual('ReportsLessonLearnerListPage'); + await router.replace({ query: { last: 'LESSON_SUMMARY' } }); + expect(exitRoute()).toEqual('LESSON_SUMMARY'); }); }); }); diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/index.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/index.vue similarity index 94% rename from kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/index.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/index.vue index ffb2ee9601d..900f9258c08 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/LessonResourceSelectionPage/index.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/index.vue @@ -124,8 +124,7 @@ import commonCoach from '../../common'; import CoachAppBarPage from '../../CoachAppBarPage'; import CoachImmersivePage from '../../CoachImmersivePage'; - import { LessonsPageNames } from '../../../constants/lessonsConstants'; - import { ViewMoreButtonStates } from '../../../constants/index'; + import { PageNames, ViewMoreButtonStates } from '../../../constants/index'; import LessonsSearchBox from './SearchTools/LessonsSearchBox'; import LessonsSearchFilters from './SearchTools/LessonsSearchFilters'; import ResourceSelectionBreadcrumbs from './SearchTools/ResourceSelectionBreadcrumbs'; @@ -231,7 +230,7 @@ return this.currentLesson.id; }, inSearchMode() { - return this.pageName === LessonsPageNames.SELECTION_SEARCH; + return this.pageName === PageNames.LESSON_RESOURCE_SELECTION_SEARCH; }, page() { return this.getUserPermissions.can_manage_content @@ -263,7 +262,7 @@ // or if all contents are topics return ( !this.inSearchMode && - this.pageName !== LessonsPageNames.SELECTION_ROOT && + this.pageName !== PageNames.LESSON_RESOURCE_SELECTION_ROOT && !every(this.contentList, this.contentIsDirectoryKind) ); }, @@ -310,18 +309,17 @@ if (this.inSearchMode && lastId) { const queryCopy = { ...this.$route.query }; delete queryCopy.last_id; - return this.$router.getRoute(LessonsPageNames.SELECTION, { topicId: lastId }, queryCopy); + return this.$router.getRoute( + PageNames.LESSON_RESOURCE_SELECTION, + { topicId: lastId }, + queryCopy, + ); } else if (this.inSearchMode) { return this.selectionRootLink({ ...this.routerParams }); - } else if (this.$route.query.last === 'ReportsLessonReportPage') { + } else if (this.$route.query.last === PageNames.LESSON_SUMMARY) { // HACK to fix #7583 and #7584 return { - name: 'ReportsLessonReportPage', - }; - } else if (this.$route.query.last === 'ReportsLessonLearnerListPage') { - // HACK to fix similar bug in Learner version of the report page - return { - name: 'ReportsLessonLearnerListPage', + name: PageNames.LESSON_SUMMARY, }; } else { return this.toolbarRoute; @@ -398,7 +396,7 @@ }, getBookmarksLink() { return { - name: LessonsPageNames.LESSON_SELECTION_BOOKMARKS_MAIN, + name: PageNames.LESSON_SELECTION_BOOKMARKS_MAIN, }; }, lessonCardClicked() { @@ -442,14 +440,22 @@ return !is_leaf; }, selectionRootLink() { - return this.$router.getRoute(LessonsPageNames.SELECTION_ROOT, {}, this.$route.query); + return this.$router.getRoute( + PageNames.LESSON_RESOURCE_SELECTION_ROOT, + {}, + this.$route.query, + ); }, topicListingLink({ topicId }) { - return this.$router.getRoute(LessonsPageNames.SELECTION, { topicId }, this.$route.query); + return this.$router.getRoute( + PageNames.LESSON_RESOURCE_SELECTION, + { topicId }, + this.$route.query, + ); }, bookmarkListingLink({ topicId }) { return this.$router.getRoute( - LessonsPageNames.LESSON_SELECTION_BOOKMARKS, + PageNames.LESSON_SELECTION_BOOKMARKS, { topicId }, this.$route.query, ); @@ -460,7 +466,7 @@ } const { query } = this.$route; return { - name: LessonsPageNames.SELECTION_CONTENT_PREVIEW, + name: PageNames.LESSON_RESOURCE_SELECTION_CONTENT_PREVIEW, params: { ...this.routerParams, contentId: content.id, @@ -479,7 +485,7 @@ } const { query } = this.$route; return { - name: LessonsPageNames.SELECTION_CONTENT_PREVIEW, + name: PageNames.LESSON_RESOURCE_SELECTION_CONTENT_PREVIEW, params: { ...this.routerParams, contentId: content.id, @@ -530,7 +536,7 @@ query.last = lastPage; } this.$router.push({ - name: LessonsPageNames.SELECTION_SEARCH, + name: PageNames.LESSON_RESOURCE_SELECTION_SEARCH, params: { searchTerm, }, diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonContentPreviewPage/ContentArea.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/LessonContentPreview/ContentArea.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonContentPreviewPage/ContentArea.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/LessonContentPreview/ContentArea.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonContentPreviewPage/PreviewSelectedResources.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/LessonContentPreview/PreviewSelectedResources.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonContentPreviewPage/PreviewSelectedResources.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/LessonContentPreview/PreviewSelectedResources.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonContentPreviewPage/QuestionList.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/LessonContentPreview/QuestionList.vue similarity index 100% rename from kolibri/plugins/coach/assets/src/views/plan/LessonContentPreviewPage/QuestionList.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/LessonContentPreview/QuestionList.vue diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonContentPreviewPage/index.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/LessonContentPreview/index.vue similarity index 99% rename from kolibri/plugins/coach/assets/src/views/plan/LessonContentPreviewPage/index.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/LessonContentPreview/index.vue index de76b78d040..4772f4f687f 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/LessonContentPreviewPage/index.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/LessonContentPreview/index.vue @@ -155,12 +155,12 @@ } from 'kolibri.utils.licenseTranslations'; import markdownIt from 'markdown-it'; import Modalities from 'kolibri-constants/Modalities'; - import commonCoach from '../../common'; + import commonCoach from '../../../common'; import QuestionList from './QuestionList'; import ContentArea from './ContentArea'; export default { - name: 'LessonContentPreviewPage', + name: 'LessonContentPreview', metaInfo() { return { title: this.currentContentNode.title, diff --git a/kolibri/plugins/coach/assets/src/views/plan/PlanLessonSelectionContentPreview.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/index.vue similarity index 88% rename from kolibri/plugins/coach/assets/src/views/plan/PlanLessonSelectionContentPreview.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/index.vue index 3ca1c96ce36..23afb28113f 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/PlanLessonSelectionContentPreview.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSelectionContentPreviewPage/index.vue @@ -7,7 +7,7 @@ :primary="false" > - Lessons section.", + "Coaches can copy lessons to a different group or another class of their facility.\n\nThe 'Copy lesson' option appears in the Lessons section.", }, }, }; diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonSummaryPage/ManageLessonModals.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/ManageLessonModals.vue similarity index 95% rename from kolibri/plugins/coach/assets/src/views/plan/LessonSummaryPage/ManageLessonModals.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/ManageLessonModals.vue index 36773bf3ae6..62d091b543b 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/LessonSummaryPage/ManageLessonModals.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/ManageLessonModals.vue @@ -33,8 +33,8 @@ import { LessonResource } from 'kolibri.resources'; import commonCoreStrings from 'kolibri.coreVue.mixins.commonCoreStrings'; import useSnackbar from 'kolibri.coreVue.composables.useSnackbar'; - import AssignmentCopyModal from '../../plan/assignments/AssignmentCopyModal'; - import AssignmentDeleteModal from '../../plan/assignments/AssignmentDeleteModal'; + import AssignmentCopyModal from '../../common/assignments/AssignmentCopyModal'; + import AssignmentDeleteModal from '../../common/assignments/AssignmentDeleteModal'; import { AssignmentActions } from '../../../constants/assignmentsConstants'; import { coachStringsMixin } from '../../common/commonCoachStrings'; @@ -121,7 +121,7 @@ return LessonResource.deleteModel({ id }) .then(() => { this.$router.replace( - this.$router.getRoute('PLAN_LESSONS_ROOT', { classId: this.classId }), + this.$router.getRoute('LESSONS_ROOT', { classId: this.classId }), () => { this.showSnackbarNotification('lessonDeleted'); }, diff --git a/kolibri/plugins/coach/assets/src/views/plan/LessonSummaryPage/index.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/index.vue similarity index 83% rename from kolibri/plugins/coach/assets/src/views/plan/LessonSummaryPage/index.vue rename to kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/index.vue index e54f48dd401..68e54c4b6da 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/LessonSummaryPage/index.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/index.vue @@ -5,8 +5,10 @@ @@ -55,16 +54,16 @@ :activeTabId="activeTabId" >