diff --git a/kolibri/plugins/coach/assets/src/constants/index.js b/kolibri/plugins/coach/assets/src/constants/index.js
index b38f0f7c756..6cdd0045e3a 100644
--- a/kolibri/plugins/coach/assets/src/constants/index.js
+++ b/kolibri/plugins/coach/assets/src/constants/index.js
@@ -25,6 +25,7 @@ export const PageNames = {
EXAM_CREATION_PREVIEW: 'EXAM_CREATION_PREVIEW',
EXAM_CREATION_SEARCH: 'EXAM_CREATION_SEARCH',
EXAM_CREATION_QUESTION_SELECTION: 'EXAM_CREATION_QUESTION_SELECTION',
+ EXAM_SIDE_PANEL: 'EXAM_SIDE_PANEL',
EXAM_PREVIEW: 'EXAM_PREVIEW',
EXAM_REPORT: 'EXAM_REPORT',
EXAM_REPORT_DETAIL: 'EXAM_REPORT_DETAIL',
diff --git a/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js b/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js
index 5d2f629c50b..ff95e2c181d 100644
--- a/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js
+++ b/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js
@@ -14,6 +14,10 @@ import {
import CreatePracticeQuizPage from '../views/plan/CreateExamPage/CreatePracticeQuizPage.vue';
import CreateExamPage from '../views/plan/CreateExamPage';
import CreateExamPreview from '../views/plan/CreateExamPage/CreateExamPreview.vue';
+import SectionSidePanel from '../views/plan/CreateExamPage/SectionSidePanel.vue';
+import SectionEditor from '../views/plan/CreateExamPage/SectionEditor.vue';
+import ResourceSelection from '../views/plan/CreateExamPage/ResourceSelection.vue';
+import ReplaceQuestions from '../views/plan/CreateExamPage/ReplaceQuestions.vue';
import PlanQuizPreviewPage from '../views/plan/PlanQuizPreviewPage';
import CoachExamsPage from '../views/plan/CoachExamsPage';
import { showExamsPage } from '../modules/examsRoot/handlers';
@@ -37,26 +41,30 @@ export default [
name: PageNames.EXAM_CREATION_ROOT,
path: '/:classId/plan/quizzes/new',
component: CreateExamPage,
- },
- {
- name: PageNames.QUIZ_SECTION_EDITOR,
- path: '/:classId/plan/quizzes/new/:section_id/edit',
- component: CreateExamPage,
- },
- {
- name: PageNames.QUIZ_REPLACE_QUESTIONS,
- path: '/:classId/plan/quizzes/new/:section_id/replace-questions',
- component: CreateExamPage,
- },
- {
- name: PageNames.QUIZ_SELECT_RESOURCES,
- path: '/:classId/plan/quizzes/new/:section_id/select-resources/:topic_id?',
- component: CreateExamPage,
- },
- {
- name: PageNames.BOOK_MARKED_RESOURCES,
- path: '/:classId/plan/quizzes/new/:section_id/select-resources/bookmarks',
- component: CreateExamPage,
+ children: [
+ {
+ name: PageNames.EXAM_SIDE_PANEL,
+ path: ':section_id',
+ component: SectionSidePanel,
+ 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.EXAM_CREATION_PRACTICE_QUIZ,
diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ConfirmCancellationModal.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ConfirmCancellationModal.vue
index 38497c9b061..e60e3640bb0 100644
--- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ConfirmCancellationModal.vue
+++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ConfirmCancellationModal.vue
@@ -48,16 +48,9 @@
export default {
name: 'ConfirmCancellationModal',
mixins: [commonCoreStrings],
- props: {
- closePanelRoute: {
- type: Object,
- required: true,
- },
- },
methods: {
handleContinueAction() {
this.$emit('continue');
- this.$router.replace(this.closePanelRoute);
},
closeModal() {
this.$emit('cancel');
diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue
index f3edc5cbba3..0e028cca79d 100644
--- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue
+++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue
@@ -313,8 +313,6 @@
-
-
@@ -334,7 +332,7 @@
import Draggable from 'kolibri.coreVue.components.Draggable';
import { injectQuizCreation } from '../../../composables/useQuizCreation';
import commonCoach from '../../common';
- import SectionSidePanel from './SectionSidePanel';
+ import { PageNames } from '../../../constants';
import TabsWithOverflow from './TabsWithOverflow';
import AccordionContainer from './AccordionContainer';
import AccordionItem from './AccordionItem';
@@ -351,7 +349,6 @@
DragSortWidget,
DragHandle,
TabsWithOverflow,
- SectionSidePanel,
},
mixins: [commonCoreStrings, commonCoach],
setup() {
@@ -509,13 +506,15 @@
methods: {
handleReplaceSelection() {
const section_id = get(this.activeSection).section_id;
- this.$router.replace({ path: 'new/' + section_id + '/replace-questions' });
+ const route = this.$router.getRoute(PageNames.QUIZ_REPLACE_QUESTIONS, { section_id });
+ this.$router.push(route);
},
handleActiveSectionAction(opt) {
const section_id = this.activeSection.section_id;
+ const editRoute = this.$router.getRoute(PageNames.QUIZ_SECTION_EDITOR, { section_id });
switch (opt.label) {
case this.editSectionLabel$():
- this.$router.replace({ path: 'new/' + section_id + '/edit' });
+ this.$router.push(editRoute);
break;
case this.deleteSectionLabel$():
this.removeSection(this.activeSection.section_id);
@@ -573,7 +572,8 @@
set(this.dragActive, true);
},
openSelectResources(section_id) {
- this.$router.replace({ path: 'new/' + section_id + '/select-resources' });
+ const route = this.$router.getRoute(PageNames.QUIZ_SELECT_RESOURCES, { section_id });
+ this.$router.push(route);
},
},
};
diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue
index d11589743bb..80315507f76 100644
--- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue
+++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue
@@ -105,13 +105,18 @@
style="float: right;"
:text="coreString('saveChangesAction')"
:primary="true"
- :disabled="!hasTopicId() && !showBookmarks"
+ :disabled="!workingPoolHasChanged"
@click="saveSelectedResource"
/>
+
@@ -133,6 +138,7 @@
import { injectQuizCreation } from '../../../composables/useQuizCreation';
import LessonsSearchBox from '../LessonResourceSelectionPage/SearchTools/LessonsSearchBox.vue';
import ContentCardList from './../LessonResourceSelectionPage/ContentCardList.vue';
+ import ConfirmCancellationModal from './ConfirmCancellationModal.vue';
import ResourceSelectionBreadcrumbs from './../LessonResourceSelectionPage/SearchTools/ResourceSelectionBreadcrumbs.vue';
export default {
@@ -142,9 +148,10 @@
BookmarkIcon,
LessonsSearchBox,
ResourceSelectionBreadcrumbs,
+ ConfirmCancellationModal,
},
mixins: [commonCoreStrings],
- setup() {
+ setup(_, context) {
const store = getCurrentInstance().proxy.$store;
const route = computed(() => store.state.route);
const topicId = computed(() => route.value.params.topic_id);
@@ -154,6 +161,9 @@
const showBookmarks = computed(() => route.value.query.showBookmarks);
const searchQuery = computed(() => route.value.query.search);
const { updateSection, activeResourcePool, selectAllQuestions } = injectQuizCreation();
+ const showConfirmationModal = ref(false);
+
+ const prevRoute = ref({ name: PageNames.EXAM_CREATION_ROOT });
const {
sectionSettings$,
@@ -377,6 +387,7 @@
// call this annotateTopicsWithDescendantCounts method to ensure that the channels are
// annotated with their num_assessments and those without assessments are filtered out
annotateTopicsWithDescendantCounts(resources.value.map(c => c.id)).then(() => {
+ channels.value = resources.value;
_loading.value = false;
});
});
@@ -408,6 +419,10 @@
return searchResults.value;
}
+ if (!topicId.value) {
+ return channels.value;
+ }
+
return resources.value;
});
@@ -432,16 +447,36 @@
return fetchMoreQuizResources();
}
+ function handleCancelClose() {
+ showConfirmationModal.value = false;
+ }
+
+ function handleConfirmClose() {
+ context.emit('closePanel');
+ }
+
+ const workingPoolHasChanged = computed(() => {
+ return (
+ workingResourcePool.value.length != activeResourcePool.value.length ||
+ !isEqual(workingResourcePool.value.sort(), activeResourcePool.value.sort())
+ );
+ });
+
return {
selectAllChecked,
selectAllIndeterminate,
showSelectAll,
handleSelectAll,
toggleSelected,
+ prevRoute,
+ workingPoolHasChanged,
+ handleConfirmClose,
+ handleCancelClose,
topic,
topicId,
contentList,
resources,
+ showConfirmationModal,
hasCheckbox,
loading,
hasMore,
@@ -464,18 +499,13 @@
updateSection,
selectAllQuestions,
workingResourcePool,
+ activeResourcePool,
addToWorkingResourcePool,
removeFromWorkingResourcePool,
showBookmarks,
selectedResourcesInformation$,
};
},
- props: {
- closePanelRoute: {
- type: Object,
- required: true,
- },
- },
computed: {
isTopicIdSet() {
return this.$route.params.topic_id;
@@ -506,6 +536,19 @@
this.bookmarksCount = newVal.length;
},
},
+ beforeRouteEnter(_, from, next) {
+ next(vm => {
+ vm.prevRoute = from;
+ });
+ },
+ beforeRouteLeave(_, __, next) {
+ if (!this.showConfirmationModal && this.workingPoolHasChanged) {
+ this.showConfirmationModal = true;
+ next(false);
+ } else {
+ next();
+ }
+ },
methods: {
showTopicSizeWarningCard(content) {
return !this.hasCheckbox(content) && content.kind === ContentNodeKinds.TOPIC;
@@ -547,9 +590,6 @@
topicsLink(topicId) {
return this.topicListingLink({ ...this.$route.params, topicId });
},
- hasTopicId() {
- return Boolean(this.$route.params.topic_id);
- },
saveSelectedResource() {
this.updateSection({
section_id: this.$route.params.section_id,
@@ -559,7 +599,7 @@
//Also reset workingResourcePool
this.resetWorkingResourcePool();
- this.$router.replace(this.closePanelRoute);
+ this.$router.replace(this.prevRoute);
},
selectionMetadata(content) {
if (content.kind === ContentNodeKinds.TOPIC) {
diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/SectionEditor.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/SectionEditor.vue
index f3c76ca92a9..57042cc5d68 100644
--- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/SectionEditor.vue
+++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/SectionEditor.vue
@@ -15,7 +15,7 @@
:layout4="{ span: 2 }"
>
@@ -29,7 +29,7 @@
@@ -43,8 +43,8 @@
icon="minus"
aria-hidden="true"
class="number-btn"
- :disabled="numberOfQuestions === 1"
- @click="numberOfQuestions -= 1"
+ :disabled="question_count === 1"
+ @click="question_count -= 1"
/>
@@ -62,7 +62,7 @@
+
@@ -222,23 +227,69 @@