Skip to content

Commit

Permalink
Merge pull request #13043 from AlexVelezLl/migrate-quizzes-to-updated…
Browse files Browse the repository at this point in the history
…ResourceSelection

Migrate quizzes to updated resource selection
  • Loading branch information
AlexVelezLl authored Feb 10, 2025
2 parents 80eec9b + 8d30c6e commit a61b643
Show file tree
Hide file tree
Showing 29 changed files with 1,867 additions and 1,423 deletions.
7 changes: 7 additions & 0 deletions kolibri/plugins/coach/assets/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ class CoachToolsModule extends KolibriApp {
PageNames.QUIZ_REPLACE_QUESTIONS,
PageNames.QUIZ_SELECT_PRACTICE_QUIZ,
PageNames.QUIZ_SELECT_RESOURCES,
PageNames.QUIZ_SELECT_RESOURCES_INDEX,
PageNames.QUIZ_SELECT_RESOURCES_BOOKMARKS,
PageNames.QUIZ_SELECT_RESOURCES_TOPIC_TREE,
PageNames.QUIZ_PREVIEW_SELECTED_RESOURCES,
PageNames.QUIZ_SELECT_RESOURCES_SETTINGS,
PageNames.QUIZ_PREVIEW_RESOURCE,
PageNames.QUIZ_SELECT_RESOURCES_LANDING_SETTINGS,
PageNames.QUIZ_SECTION_ORDER,
PageNames.QUIZ_BOOK_MARKED_RESOURCES,
PageNames.QUIZ_LEARNER_REPORT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ import useFetch from './useFetch';
* and topic trees, and offers methods to add, remove, or override selected resources.
*
* @param {Object} options
* @param {Object} options.bookmarks Configuration object for bookmarks fetch. It can contain
* `filters` an object with extra query params, and `annotator` a function to annotate the results.
* @param {Object} options.channels Configuration object for channels fetch. It can contain
* `filters` an object with extra query params, and `annotator` a function to annotate the results.
* @param {Object} options.topicTree Configuration object for topic tree fetch. It can contain
* `filters` an object with extra query params, and `annotator` a function to annotate the results.
* @param {string} options.searchResultsRouteName The name of the route where the search results
* will be displayed so that we can redirect to it when the search terms are updated.
*
Expand Down Expand Up @@ -51,7 +57,12 @@ import useFetch from './useFetch';
*
* @returns {UseResourceSelectionResponse}
*/
export default function useResourceSelection({ searchResultsRouteName } = {}) {
export default function useResourceSelection({
searchResultsRouteName,
bookmarks,
channels,
topicTree,
} = {}) {
const store = getCurrentInstance().proxy.$store;
const route = computed(() => store.state.route);
const topicId = computed(() => route.value.query.topicId);
Expand All @@ -60,24 +71,42 @@ export default function useResourceSelection({ searchResultsRouteName } = {}) {
const selectedResources = ref([]);
const topic = ref(null);

const fetchBookmarks = async params => {
const response = await ContentNodeResource.fetchBookmarks(params);
if (bookmarks?.annotator) {
const annotatedResults = await bookmarks.annotator(response.results);
return {
...response,
results: annotatedResults,
};
}
return response;
};
const bookmarksFetch = useFetch({
fetchMethod: () =>
ContentNodeResource.fetchBookmarks({
params: { limit: 25, available: true },
fetchBookmarks({
params: { limit: 25, available: true, ...bookmarks?.filters },
}),
fetchMoreMethod: more =>
ContentNodeResource.fetchBookmarks({
params: more,
}),
});

const fetchChannels = async () => {
const result = await ChannelResource.fetchCollection({
getParams: {
available: true,
...channels?.filters,
},
});
if (channels?.annotator) {
return channels.annotator(result);
}
return result;
};
const channelsFetch = useFetch({
fetchMethod: () =>
ChannelResource.fetchCollection({
getParams: {
available: true,
},
}),
fetchMethod: fetchChannels,
});

const waitForTopicLoad = () => {
Expand Down Expand Up @@ -123,11 +152,22 @@ export default function useResourceSelection({ searchResultsRouteName } = {}) {
if (topic.value?.id !== newTopic.id) {
topic.value = newTopic;
}
if (topicTree?.annotator) {
const annotatedResults = await topicTree.annotator(topic.value.children.results);
return {
...topic.value.children,
results: annotatedResults,
};
}
return topic.value.children;
};

const treeFetch = useFetch({
fetchMethod: () => fetchTree({ id: topicId.value, params: { include_coach_content: true } }),
fetchMethod: () =>
fetchTree({
id: topicId.value,
params: { include_coach_content: true, ...topicTree?.filters },
}),
fetchMoreMethod: more => fetchTree(more),
});

Expand Down
13 changes: 12 additions & 1 deletion kolibri/plugins/coach/assets/src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,23 @@ export const PageNames = {
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_RESOURCES_OLD: 'QUIZ_SELECT_RESOURCES_OLD',
QUIZ_SELECT_PRACTICE_QUIZ: 'QUIZ_SELECT_PRACTICE_QUIZ',
QUIZ_SECTION_ORDER: 'QUIZ_SECTION_ORDER',
QUIZ_QUESTION_PAGE_ROOT: 'QUIZ_QUESTION_PAGE_ROOT',
QUIZ_QUESTION_REPORT: 'QUIZ_QUESTION_REPORT',
QUIZ_BOOK_MARKED_RESOURCES: 'QUIZ_BOOK_MARKED_RESOURCES',
QUIZ_SECTION_SIDE_PANEL: 'QUIZ_SECTION_SIDE_PANEL',
QUIZ_SELECT_RESOURCES: 'QUIZ_SELECT_RESOURCES',
QUIZ_PREVIEW_RESOURCE: 'QUIZ_PREVIEW_RESOURCE',
QUIZ_PREVIEW_SELECTED_RESOURCES: 'QUIZ_PREVIEW_SELECTED_RESOURCES',
QUIZ_SELECT_RESOURCES_INDEX: 'QUIZ_SELECT_RESOURCES_INDEX',
QUIZ_SELECT_RESOURCES_SEARCH: 'QUIZ_SELECT_RESOURCES_SEARCH',
QUIZ_SELECT_RESOURCES_BOOKMARKS: 'QUIZ_SELECT_RESOURCES_BOOKMARKS',
QUIZ_SELECT_RESOURCES_TOPIC_TREE: 'QUIZ_SELECT_RESOURCES_TOPIC_TREE',
QUIZ_SELECT_RESOURCES_SEARCH_RESULTS: 'QUIZ_SELECT_RESOURCES_SEARCH_RESULTS',
QUIZ_SELECT_RESOURCES_SETTINGS: 'QUIZ_SELECT_RESOURCES_SETTINGS',
QUIZ_SELECT_RESOURCES_LANDING_SETTINGS: 'QUIZ_SELECT_RESOURCES_LANDING_SETTINGS',

/* Lessons */
LESSONS_ROOT: 'LESSONS_ROOT',
Expand Down
113 changes: 90 additions & 23 deletions kolibri/plugins/coach/assets/src/routes/examRoutes.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import store from 'kolibri/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 SectionEditor from '../views/quizzes/CreateExamPage/sidePanels/SectionSidePanel/SectionEditor.vue';
import ReplaceQuestions from '../views/quizzes/CreateExamPage/sidePanels/SectionSidePanel/ReplaceQuestions.vue';
import ExamsRootPage from '../views/quizzes/ExamsRootPage';
import QuizSummaryPage from '../views/quizzes/QuizSummaryPage';
import SectionOrder from '../views/quizzes/CreateExamPage/SectionOrder';
import SectionOrder from '../views/quizzes/CreateExamPage/sidePanels/SectionSidePanel/SectionOrder.vue';
import SectionSidePanel from '../views/quizzes/CreateExamPage/sidePanels/SectionSidePanel/index.vue';
import QuizResourceSelection from '../views/quizzes/CreateExamPage/sidePanels/QuizResourceSelection/index.vue';
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 SelectionIndex from '../views/common/resourceSelection/subPages/SelectionIndex.vue';
import SelectFromChannels from '../views/common/resourceSelection/subPages/SelectFromTopicTree.vue';
import SelectFromBookmarks from '../views/common/resourceSelection/subPages/SelectFromBookmarks.vue';
import ManageSelectedResources from '../views/common/resourceSelection/subPages/ManageSelectedResources.vue';
import PreviewSelectedResources from '../views/common/resourceSelection/subPages/PreviewSelectedResources/index.vue';
import {
generateQuestionDetailHandler,
questionRootRedirectHandler,
} from '../modules/questionDetail/handlers';
import QuestionsSettings from '../views/quizzes/CreateExamPage/sidePanels/QuizResourceSelection/subPages/QuestionsSettings.vue';
import { classIdParamRequiredGuard, RouteSegments } from './utils';

const {
Expand Down Expand Up @@ -52,31 +59,91 @@ export default [
},
children: [
{
name: PageNames.QUIZ_SECTION_EDITOR,
path: 'edit',
component: SectionEditor,
},
{
name: PageNames.QUIZ_REPLACE_QUESTIONS,
path: 'replace-questions',
component: ReplaceQuestions,
name: PageNames.QUIZ_SECTION_SIDE_PANEL,
path: 'details',
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_SECTION_ORDER,
path: 'section-order',
component: SectionOrder,
},
],
},
{
name: PageNames.QUIZ_SELECT_RESOURCES,
path: 'select-resources/:topic_id?',
component: ResourceSelection,
},
{
name: PageNames.QUIZ_SECTION_ORDER,
path: 'section-order',
component: SectionOrder,
path: 'select-resources',
component: QuizResourceSelection,
redirect: 'select-resources/landing-settings',
children: [
{
name: PageNames.QUIZ_SELECT_RESOURCES_LANDING_SETTINGS,
path: 'landing-settings',
component: QuestionsSettings,
props: {
isLanding: true,
},
},
{
name: PageNames.QUIZ_SELECT_RESOURCES_INDEX,
path: 'index',
component: SelectionIndex,
},
{
name: PageNames.QUIZ_SELECT_RESOURCES_BOOKMARKS,
path: 'bookmarks',
component: SelectFromBookmarks,
},
{
name: PageNames.QUIZ_SELECT_RESOURCES_TOPIC_TREE,
path: 'channels',
component: SelectFromChannels,
},
{
name: PageNames.QUIZ_PREVIEW_SELECTED_RESOURCES,
path: 'preview-resources',
component: ManageSelectedResources,
},
{
name: PageNames.QUIZ_SELECT_RESOURCES_SETTINGS,
path: 'settings',
component: QuestionsSettings,
},
{
name: PageNames.QUIZ_PREVIEW_RESOURCE,
path: 'preview',
component: PreviewSelectedResources,
props: toRoute => {
const contentId = toRoute.query.contentId;
return {
contentId,
};
},
},
],
},
{
name: PageNames.QUIZ_SELECT_PRACTICE_QUIZ,
path: 'select-quiz/:topic_id?',
component: ResourceSelection,
props: {
selectPracticeQuiz: true,
path: 'select-quiz',
redirect: to => {
const { params } = to;
return {
name: PageNames.QUIZ_SELECT_RESOURCES_INDEX,
params,
query: {
selectPracticeQuiz: true,
},
};
},
},
],
Expand Down
15 changes: 5 additions & 10 deletions kolibri/plugins/coach/assets/src/routes/lessonsRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ import {
import LessonLearnerExercisePage from '../views/lessons/reports/LessonLearnerExercisePage.vue';
import QuestionLearnersPage from '../views/common/reports/QuestionLearnersPage.vue';
import EditLessonDetails from '../views/lessons/LessonSummaryPage/sidePanels/EditLessonDetails';
import PreviewSelectedResources from '../views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/PreviewSelectedResources';
import SelectionIndex from '../views/common/resourceSelection/subPages/SelectionIndex.vue';
import SelectFromBookmarks from '../views/common/resourceSelection/subPages/SelectFromBookmarks.vue';
import SelectFromTopicTree from '../views/common/resourceSelection/subPages/SelectFromTopicTree.vue';
import ManageSelectedResources from '../views/common/resourceSelection/subPages/ManageSelectedResources.vue';
import PreviewSelectedResources from '../views/common/resourceSelection/subPages/PreviewSelectedResources/index.vue';
import LessonResourceSelection from '../views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue';
import SearchFilters from '../views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SearchFilters.vue';
import SelectionIndex from '../views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectionIndex.vue';
import SelectFromBookmarks from '../views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromBookmarks.vue';
import SelectFromTopicTree from '../views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromTopicTree.vue';
import SelectFromSearchResults from '../views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromSearchResults.vue';
import ManageSelectedResources from '../views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/ManageSelectedResources.vue';
import { classIdParamRequiredGuard, RouteSegments } from './utils';

const {
Expand Down Expand Up @@ -185,11 +185,6 @@ export default [
},
],
},
{
name: PageNames.LESSON_PREVIEW_RESOURCE,
path: 'preview-resources/:nodeId',
component: PreviewSelectedResources,
},
],
},
{
Expand Down
Loading

0 comments on commit a61b643

Please sign in to comment.