From 591a93cf7ec80a5f81b4f9b36ba6b72899ddfc17 Mon Sep 17 00:00:00 2001 From: Jacob Pierce Date: Tue, 31 Oct 2023 08:51:58 -0700 Subject: [PATCH 01/50] set not loading when quiz creator comes up --- .../coach/assets/src/views/plan/CreateExamPage/index.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue index 41aadf022c..7b57201251 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue @@ -108,6 +108,9 @@ created() { this.quizForge.initializeQuiz(); }, + mounted() { + this.$store.dispatch('notLoading'); + }, $trs: { createNewExamLabel: { message: 'Create new quiz', From c6c2f8eb40016b327e3888ef9f41ef289af89b6f Mon Sep 17 00:00:00 2001 From: Jacob Pierce Date: Thu, 12 Oct 2023 15:44:31 -0700 Subject: [PATCH 02/50] add DEBUG option to useQuizCreation; bootstrap basic accordion setup --- .../assets/src/composables/useQuizCreation.js | 44 ++++++++++-- .../plan/CreateExamPage/AccordionItem.vue | 2 +- .../plan/CreateExamPage/CreateQuizSection.vue | 67 ++++++++++++++----- .../src/views/plan/CreateExamPage/index.vue | 15 +++-- 4 files changed, 100 insertions(+), 28 deletions(-) diff --git a/kolibri/plugins/coach/assets/src/composables/useQuizCreation.js b/kolibri/plugins/coach/assets/src/composables/useQuizCreation.js index 67e547dc9a..64b6ff280f 100644 --- a/kolibri/plugins/coach/assets/src/composables/useQuizCreation.js +++ b/kolibri/plugins/coach/assets/src/composables/useQuizCreation.js @@ -8,7 +8,7 @@ import { get, set } from '@vueuse/core'; import { computed, ref } from 'kolibri.lib.vueCompositionApi'; // TODO: Probably move this to this file's local dir import selectQuestions from '../modules/examCreation/selectQuestions.js'; -import { Quiz, QuizSection } from './quizCreationSpecs.js'; +import { Quiz, QuizSection, QuizQuestion } from './quizCreationSpecs.js'; /** Validators **/ /* objectSpecs expects every property to be available -- but we don't want to have to make an @@ -30,7 +30,7 @@ function isExercise(o) { /** * Composable function presenting primary interface for Quiz Creation */ -export default () => { +export default (DEBUG = true) => { // ----------- // Local state // ----------- @@ -53,6 +53,38 @@ export default () => { /** @type {ref} A counter for use in naming new sections */ const _sectionLabelCounter = ref(1); + // Debug Data Generators + function _quizQuestions(num = 5) { + const questions = []; + for (let i = 0; i <= num; i++) { + const overrides = { + title: `Quiz Question ${i}`, + question_id: `${i}`, + }; + questions.push(objectWithDefaults(overrides, QuizQuestion)); + } + return questions; + } + + function _quizSections(num = 5, numQuestions = 5) { + const sections = []; + for (let i = 0; i <= num; i++) { + const overrides = { + section_id: `${i}`, + section_title: `A section ${i}`, + questions: _quizQuestions(numQuestions), + }; + sections.push(objectWithDefaults(overrides, QuizSection)); + } + return sections; + } + + function _generateTestData(numSections = 5, numQuestions = 5) { + const sections = _quizSections(numSections, numQuestions); + updateQuiz({ question_sources: sections }); + setActiveSection(sections[0].section_id); + } + // ------------------ // Section Management // ------------------ @@ -162,8 +194,12 @@ export default () => { * use */ function initializeQuiz() { set(_quiz, objectWithDefaults({}, Quiz)); - const newSection = addSection(); - setActiveSection(newSection.section_id); + if (DEBUG) { + _generateTestData(); + } else { + const newSection = addSection(); + setActiveSection(newSection.section_id); + } _fetchChannels(); } diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/AccordionItem.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/AccordionItem.vue index f0d32869a5..27e61bc3ad 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/AccordionItem.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/AccordionItem.vue @@ -32,7 +32,7 @@ required: true, }, id: { - type: Number, + type: String, required: true, }, }, 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 6f9dc0adbb..8abe3f331c 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue @@ -153,28 +153,51 @@ tabsId="quizSectionTabs" :activeTabId="quizForge.activeSection.value ? quizForge.activeSection.value.section_id : ''" > - -

{{ quizForge.activeSection.value.section_id }}

-
- ? -
+
+
+ ? +
-

- {{ noQuestionsInSection$() }} -

+

+ {{ noQuestionsInSection$() }} +

-

{{ addQuizSectionQuestionsInstructions$() }}

+

{{ addQuizSectionQuestionsInstructions$() }}

- - {{ addQuestionsLabel$() }} - + + {{ addQuestionsLabel$() }} + +
+ + + + @@ -191,12 +214,16 @@ import commonCoreStrings from 'kolibri.coreVue.mixins.commonCoreStrings'; import { enhancedQuizManagementStrings } from 'kolibri-common/strings/enhancedQuizManagementStrings'; import commonCoach from '../../common'; - import SectionSidePanel from './SectionSidePanel.vue'; - import TabsWithOverflow from './TabsWithOverflow.vue'; + import SectionSidePanel from './SectionSidePanel'; + import TabsWithOverflow from './TabsWithOverflow'; + import AccordionContainer from './AccordionContainer'; + import AccordionItem from './AccordionItem'; export default { name: 'CreateQuizSection', components: { + AccordionContainer, + AccordionItem, TabsWithOverflow, SectionSidePanel, }, @@ -264,6 +291,10 @@ }, ]; }, + accordionQuestions() { + const mapQuestionToAccordionItem = q => ({ id: q.question_id, title: q.title }); + return get(this.quizForge.activeQuestions).map(mapQuestionToAccordionItem); + }, }, methods: { tabRefLabel(section_id) { diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue index 7b57201251..fba6c77f1c 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue @@ -20,7 +20,7 @@ :style="{ ...maxContainerHeight, maxWidth: '1000px', margin: '0 auto' }" > - + @@ -41,6 +41,8 @@ diff --git a/packages/kolibri-common/strings/enhancedQuizManagementStrings.js b/packages/kolibri-common/strings/enhancedQuizManagementStrings.js index 296bbb08e1..c3b0a009a9 100644 --- a/packages/kolibri-common/strings/enhancedQuizManagementStrings.js +++ b/packages/kolibri-common/strings/enhancedQuizManagementStrings.js @@ -10,6 +10,10 @@ export const enhancedQuizManagementStrings = createTranslator('EnhancedQuizManag createNewQuiz: { message: 'Create new quiz', }, + quizSectionsLabel: { + message: 'Quiz sections', + context: 'Used as an aria-label for screen readers to describe the purpose of the list of tabs', + }, quizTitle: { message: 'Quiz title', }, From 444909933cc901b9fe8e717287126ffa8d85f9b4 Mon Sep 17 00:00:00 2001 From: Jacob Pierce Date: Wed, 25 Oct 2023 22:04:37 -0700 Subject: [PATCH 18/50] handle quiz title field --- .../assets/src/views/plan/CreateExamPage/CreateQuizSection.vue | 1 + 1 file changed, 1 insertion(+) 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 25bb10830b..ad0b77be76 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue @@ -24,6 +24,7 @@ :autofocus="true" :maxlength="100" @blur="e => quizForge.updateQuiz({ title: e.target.value })" + @change="title => quizForge.updateQuiz({ title })" /> From f2b5f0ee62d8915ba6b63aa0528773c36438f114 Mon Sep 17 00:00:00 2001 From: Jacob Pierce Date: Wed, 25 Oct 2023 22:22:02 -0700 Subject: [PATCH 19/50] update link to kds commit/pr --- kolibri/core/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kolibri/core/package.json b/kolibri/core/package.json index 2f6110f152..6744c698d4 100644 --- a/kolibri/core/package.json +++ b/kolibri/core/package.json @@ -21,7 +21,7 @@ "js-cookie": "^3.0.5", "knuth-shuffle-seeded": "^1.0.6", "kolibri-constants": "0.2.0", - "kolibri-design-system": "https://github.com/learningequality/kolibri-design-system#83c9f97871ce7e09f0a6ebba023b126d51e91931", + "kolibri-design-system": "https://github.com/learningequality/kolibri-design-system#1f497630cbe15e35c777935e1d60632023885d50", "lockr": "0.8.5", "lodash": "^4.17.21", "loglevel": "^1.8.1", From 21e6893e6e35d8290367244c34363b11fee01e60 Mon Sep 17 00:00:00 2001 From: Jacob Pierce Date: Wed, 15 Nov 2023 17:54:35 -0800 Subject: [PATCH 20/50] Ensure [Tab]-nav flow works properly when leaving Options button KDS commit 047379f579ad7067381a9576edc21abd12ad8378 is a req for this change --- .../assets/src/views/plan/CreateExamPage/CreateQuizSection.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 ad0b77be76..0f21e57384 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue @@ -154,6 +154,7 @@ :disabled="false" :hasIcons="true" :options="activeSectionActions" + @tab="e => (e.preventDefault() || $refs.selectAllCheckbox.focus())" @select="handleActiveSectionAction" /> @@ -161,7 +162,6 @@ - Date: Wed, 15 Nov 2023 18:13:55 -0800 Subject: [PATCH 21/50] not debug by default --- kolibri/plugins/coach/assets/src/composables/useQuizCreation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kolibri/plugins/coach/assets/src/composables/useQuizCreation.js b/kolibri/plugins/coach/assets/src/composables/useQuizCreation.js index 923fadeff1..db10418e6a 100644 --- a/kolibri/plugins/coach/assets/src/composables/useQuizCreation.js +++ b/kolibri/plugins/coach/assets/src/composables/useQuizCreation.js @@ -31,7 +31,7 @@ function isExercise(o) { /** * Composable function presenting primary interface for Quiz Creation */ -export default (DEBUG = true) => { +export default (DEBUG = false) => { // ----------- // Local state // ----------- From 1ceee065e36925f009a63d2eafd22c5ad0f006bb Mon Sep 17 00:00:00 2001 From: Jacob Pierce Date: Thu, 16 Nov 2023 15:09:41 -0800 Subject: [PATCH 22/50] fix eternal loading state when navigation routes --- .../plan/CreateExamPage/CreateQuizSection.vue | 28 +++++++++++++++---- .../src/views/plan/CreateExamPage/index.vue | 4 +++ 2 files changed, 27 insertions(+), 5 deletions(-) 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 0f21e57384..e7b78407e3 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/CreateQuizSection.vue @@ -109,6 +109,28 @@ >
+ + + + + + +
?
@@ -439,9 +461,6 @@ ]; }, }, - mounted() { - this.$store.dispatch('notLoading'); - }, methods: { handleReplaceSelection() { const section_id = get(this.quizForge.activeSection).section_id; @@ -454,7 +473,6 @@ this.$router.replace({ path: 'new/' + section_id + '/edit' }); break; case this.deleteSectionLabel$(): - console.log('Deleting, ', this.quizForge.activeSection.value.section_id); this.quizForge.removeSection(this.quizForge.activeSection.value.section_id); this.focusActiveSectionTab(); break; @@ -698,7 +716,7 @@ } /deep/ .overflow-tabs svg { - top: 7px !important; + top: 5px !important; } .select-all-box { diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue index fba6c77f1c..0ed911db4a 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue @@ -103,6 +103,10 @@ }, }, watch: { + $route: function() { + // FIXME Coach shouldn't be setting loading in a beforeEach here maybe? + this.$store.dispatch('notLoading'); + }, filters(newVal) { this.$router.push({ query: { ...this.$route.query, ...pickBy(newVal) }, From 4aa72d2a3f6f07fa97dcbde02b73bb517f9b6d92 Mon Sep 17 00:00:00 2001 From: Jacob Pierce Date: Thu, 16 Nov 2023 15:35:12 -0800 Subject: [PATCH 23/50] update kds --- kolibri/core/package.json | 2 +- yarn.lock | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/kolibri/core/package.json b/kolibri/core/package.json index 6744c698d4..d1d1535726 100644 --- a/kolibri/core/package.json +++ b/kolibri/core/package.json @@ -21,7 +21,7 @@ "js-cookie": "^3.0.5", "knuth-shuffle-seeded": "^1.0.6", "kolibri-constants": "0.2.0", - "kolibri-design-system": "https://github.com/learningequality/kolibri-design-system#1f497630cbe15e35c777935e1d60632023885d50", + "kolibri-design-system": "https://github.com/learningequality/kolibri-design-system#f19ca3fc5677fc7f3b4cdbfee33950f5adde5290", "lockr": "0.8.5", "lodash": "^4.17.21", "loglevel": "^1.8.1", diff --git a/yarn.lock b/yarn.lock index 83628e7410..bf2759e20f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7648,6 +7648,22 @@ kolibri-constants@0.2.0: resolved "https://registry.yarnpkg.com/kolibri-constants/-/kolibri-constants-0.2.0.tgz#47c9d773894e23251ba5ac4db420822e45603142" integrity sha512-WYDMGDzB9gNxRbpX1O2cGe1HrJvLvSZGwMuAv6dqrxJgPf7iO+Hi40/1CXjHM7nk5CRt+hn5bqnMzCBmj1omPA== +"kolibri-design-system@https://github.com/learningequality/kolibri-design-system#f19ca3fc5677fc7f3b4cdbfee33950f5adde5290": + version "1.3.0" + resolved "https://github.com/learningequality/kolibri-design-system#f19ca3fc5677fc7f3b4cdbfee33950f5adde5290" + dependencies: + aphrodite "https://github.com/learningequality/aphrodite/" + autosize "^3.0.21" + css-element-queries "^1.2.0" + frame-throttle "^3.0.0" + fuzzysearch "^1.0.3" + keen-ui "^1.3.0" + lodash "^4.17.15" + popper.js "^1.14.6" + purecss "^0.6.2" + tippy.js "^4.2.1" + vue-intl "^3.1.0" + "kolibri-design-system@https://github.com/learningequality/kolibri-design-system#v2.0.0-beta1": version "1.3.0" resolved "https://github.com/learningequality/kolibri-design-system#13e539592fd87508cd32f60e4ad22c1ec320559b" From b4f196f7b4da056e69af516e5e697ccf16a604d1 Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Mon, 6 Nov 2023 22:20:15 +0300 Subject: [PATCH 24/50] fixed loading failure --- .../coach/assets/src/views/plan/CreateExamPage/index.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue index 0ed911db4a..8a12850b64 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/index.vue @@ -120,6 +120,9 @@ mounted() { this.$store.dispatch('notLoading'); }, + mounted() { + this.$store.dispatch('notLoading'); + }, $trs: { createNewExamLabel: { message: 'Create new quiz', From 63239d3a63be8d1eee7d7000d4206a2b06af7d26 Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Tue, 7 Nov 2023 20:23:15 +0300 Subject: [PATCH 25/50] resource sidepanel header added --- .../plan/CreateExamPage/ResourceSelection.vue | 61 ++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) 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 86e9b8d5f0..4be8e0be68 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue @@ -1,14 +1,62 @@ + + + From 5c97f6dd867023e75889121535335bd311457385 Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Tue, 7 Nov 2023 22:09:49 +0300 Subject: [PATCH 26/50] added search component --- .../plan/CreateExamPage/ResourceSelection.vue | 87 ++++++++++++------- 1 file changed, 54 insertions(+), 33 deletions(-) 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 4be8e0be68..11011a1943 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue @@ -4,41 +4,42 @@
- {{ sectionSettings$() }} + + Select folders or exercises from these channels
- - - - -

Math

-
+

Select from bookmarks

+ + - -

Early math

-
-
-
+

+ Addition and subtraction within 20A +

+

+ Learn to add and subtract numbers that are 20 or less. +

- + + -

Addition and subtraction within 20A

-
-
+ select all + +
@@ -47,9 +48,13 @@ diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/QuizResourceCard.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/QuizResourceCard.vue new file mode 100644 index 0000000000..947e479471 --- /dev/null +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/QuizResourceCard.vue @@ -0,0 +1,65 @@ + + + + + + + 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 11011a1943..f9607efce4 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue @@ -11,35 +11,45 @@

Select from bookmarks

+ + -

- Addition and subtraction within 20A -

-

- Learn to add and subtract numbers that are 20 or less. -

- -
- - - select all - -
+ @@ -49,11 +59,15 @@ import { enhancedQuizManagementStrings } from 'kolibri-common/strings/enhancedQuizManagementStrings'; import LessonsSearchBox from './../LessonResourceSelectionPage/SearchTools/LessonsSearchBox.vue'; + import BookMarkedResource from './BookMarkedResource.vue'; + // import ChannelCard from './ChannelCard.vue'; export default { name: 'ResourceSelection', components: { LessonsSearchBox, + BookMarkedResource, + // ChannelCard, }, setup() { const { sectionSettings$ } = enhancedQuizManagementStrings; @@ -81,20 +95,4 @@ font-weight:600; font-size: 1.4em; } -.section-topic-style{ - font-weight:600; - font-size: 1.4em; -} -.section-subtopic-style{ - font-size: 1.2em; -} -.select-all-style{ - font-size:1.2em; - font-weight:600; - display: inline-flex; - justify-content: space-between; -} -.space-content-left{ - margin-left: .5em; -} From 827c0b6a3e2eb58214c1e4db1ea91344d8663c98 Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Thu, 9 Nov 2023 01:57:09 +0300 Subject: [PATCH 28/50] adds channel cards to select resource side panel --- .../plan/CreateExamPage/ResourceSelection.vue | 139 ++++++++++++++---- 1 file changed, 110 insertions(+), 29 deletions(-) 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 f9607efce4..073be07c44 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue @@ -18,38 +18,58 @@ placeholder="search by keyword" searchTerm="searchTerm" :inputPlaceHolderStyle="inputPlaceHolderStyle" - style="margin-top:1em;" + style="margin-top:1em;margin-bottom:1em;" @searchterm="search" /> - - + + + @@ -57,17 +77,22 @@ + + + diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/QuizResourceCard.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/QuizResourceCard.vue index 947e479471..b80354a763 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/QuizResourceCard.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/QuizResourceCard.vue @@ -27,14 +27,12 @@ Channel name

- + @@ -45,12 +43,12 @@ - From 53512bbd17ba6ddc8841d7cec25325dc5f5efd10 Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Fri, 17 Nov 2023 21:58:45 +0300 Subject: [PATCH 34/50] added the bookmark card --- .../CreateExamPage/BookMarkedResource.vue | 267 +++--------------- .../plan/CreateExamPage/ResourceSelection.vue | 191 +++++-------- .../strings/enhancedQuizManagementStrings.js | 3 + 3 files changed, 115 insertions(+), 346 deletions(-) diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue index 28b4debe43..d26f2a8ff2 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue @@ -2,83 +2,28 @@
- -
+ - - - - - + + - - - -

- -

-

- -

- - - - - - - - -
-
- -
-
+ + +

{{ bookmarksLabel$() }}

+ {{ numberOfSelectedBookmarks$({ count: numberOfBookMarkedResources }) }} +
+
+
@@ -86,125 +31,41 @@ diff --git a/packages/kolibri-common/strings/enhancedQuizManagementStrings.js b/packages/kolibri-common/strings/enhancedQuizManagementStrings.js index c3b0a009a9..8daeee61f0 100644 --- a/packages/kolibri-common/strings/enhancedQuizManagementStrings.js +++ b/packages/kolibri-common/strings/enhancedQuizManagementStrings.js @@ -71,6 +71,9 @@ export const enhancedQuizManagementStrings = createTranslator('EnhancedQuizManag selectFoldersOrExercises: { message: 'Select folders or exercises from these channels', }, + bookmarksLabel: { + message: 'Bookmark', + }, numberOfSelectedBookmarks: { message: '{ count, number } { count, plural, one { bookmark } other { bookmarks }}', }, From c683194b62a6c65c828b08efd848e5c679088e24 Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Tue, 21 Nov 2023 20:19:00 +0300 Subject: [PATCH 35/50] replaced quizforge data with composable --- .../assets/src/composables/useResources.js | 33 ++++++++ .../CreateExamPage/BookMarkedResource.vue | 64 +++++++-------- .../plan/CreateExamPage/ResourceSelection.vue | 80 ++----------------- 3 files changed, 72 insertions(+), 105 deletions(-) create mode 100644 kolibri/plugins/coach/assets/src/composables/useResources.js diff --git a/kolibri/plugins/coach/assets/src/composables/useResources.js b/kolibri/plugins/coach/assets/src/composables/useResources.js new file mode 100644 index 0000000000..817a317237 --- /dev/null +++ b/kolibri/plugins/coach/assets/src/composables/useResources.js @@ -0,0 +1,33 @@ +import { ref, onMounted } from 'kolibri.lib.vueCompositionApi'; +import { ChannelResource, ContentNodeResource as bookMarkedResource } from 'kolibri.resources'; + +export function useResources() { + const resources = ref(null); + const channels = ref([]); + const bookmarks = ref([]); + + function fetchChannelResource() { + ChannelResource.fetchCollection({ params: { has_exercises: true, available: true } }).then( + response => { + channels.value = response; + } + ); + } + + function fetchBookMarkedResource() { + bookMarkedResource.fetchBookmarks({ params: { limit: 25, available: true } }).then(data => { + bookmarks.value = data.results ? data.results : []; + }); + } + + onMounted(() => { + fetchChannelResource(); + fetchBookMarkedResource(); + }); + + return { + resources, + channels, + bookmarks, + }; +} diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue index d26f2a8ff2..732b6f772c 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue @@ -3,27 +3,32 @@ @@ -32,7 +37,6 @@ 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 e6ebca0301..c4e498c7e6 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue @@ -12,8 +12,10 @@

Select from bookmarks

import { ContentNodeKinds, ContentNodeResource } from 'kolibri.coreVue.vuex.constants'; - import { ContentNodeResource as bookMarkedResource } from 'kolibri.resources'; import { enhancedQuizManagementStrings } from 'kolibri-common/strings/enhancedQuizManagementStrings'; import every from 'lodash/every'; import pickBy from 'lodash/pickBy'; import { PageNames } from '../../../constants'; import { LessonsPageNames } from '../../../constants/lessonsConstants'; + import { useResources } from '../../../composables/useResources'; import LessonsSearchBox from './../LessonResourceSelectionPage/SearchTools/LessonsSearchBox.vue'; import BookMarkedResource from './BookMarkedResource.vue'; import ContentCardList from './../LessonResourceSelectionPage/ContentCardList.vue'; - // import LessonContentCard from './../LessonResourceSelectionPage/LessonContentCard/index.vue'; - // import ResourceSelection from './ResourceSelection.vue'; - // import ResourceSelectionBreadcrumbs from './../../../views/plan/LessonResourceS - // electionPage/SearchTools/ResourceSelectionBreadcrumbs.vue' export default { name: 'ResourceSelection', @@ -66,23 +64,21 @@ LessonsSearchBox, BookMarkedResource, ContentCardList, - // ResourceSelection, - // ResourceSelectionBreadcrumbs, - // LessonContentCard, }, inject: ['quizForge'], setup() { const { sectionSettings$ } = enhancedQuizManagementStrings; + const { channels, bookmarks } = useResources(); return { sectionSettings$, + channels, + bookmarks, }; }, data() { return { viewMoreButtonState: 'no_more_results', - // contentHasCheckbox: () => false, - // contentIsSelected: () => '', searchTerm: '', search: '', filters: { @@ -91,29 +87,9 @@ role: this.$route.query.role || null, }, visibleResources: [], - bookmarks: [], }; }, computed: { - // filteredContentList() { - // const { role } = this.filters; - // if (!this.inSearchMode) { - // return this.quizForge.channels.value; - // } - // const list = this.quizForge.channels.value - // ? this.quizForge.channels.value - // : this.bookmarksList; - // return list.filter(contentNode => { - // let passesFilters = true; - // if (role === 'nonCoach') { - // passesFilters = passesFilters && contentNode.num_coach_contents === 0; - // } - // if (role === 'coach') { - // passesFilters = passesFilters && contentNode.num_coach_contents > 0; - // } - // return passesFilters; - // }); - // }, inSearchMode() { return this.pageName === LessonsPageNames.SELECTION_SEARCH; }, @@ -190,16 +166,6 @@ }); } }, - created() { - console.log(this.quizForge.channels.value); - bookMarkedResource.fetchBookmarks({ params: { limit: 25, available: true } }).then(data => { - this.more = data.more; - this.bookmarks = data.results ? data.results : []; - console.log(this.bookmarks); - this.loading = false; - this.fetchContentNodeProgress({ ids: this.bookmarks.map(b => b.id) }); - }); - }, mounted() { if (this.quizForge.channels.value.length > 0) { this.visibleResources = this.quizForge.channels.value; @@ -212,19 +178,7 @@ focusFirstEl() { this.$refs.textbox.focus(); }, - // selectionMetadata(content) { - // if (content.kind === ContentNodeKinds.TOPIC) { - // const count = content.exercises.filter(exercise => - // Boolean(this.selectedExercises[exercise.id]) - // ).length; - // if (count === 0) { - // return ''; - // } - // const total = content.exercises.length; - // return this.$tr('total_number', { count, total }); - // } - // return ''; - // }, + contentLink(content) { if (!content.is_leaf) { return { @@ -304,24 +258,6 @@ }); }); }, - // filteredquizForge.channels.value() { - // const { role } = this.filters; - // if (!this.inSearchMode) { - // return this.quizForge.channels.value; - // } - // const list = this.quizForge.channels.value ? - // this.quizForge.channels.value : this.bookmarksList; - // return list.filter(contentNode => { - // let passesFilters = true; - // if (role === 'nonCoach') { - // passesFilters = passesFilters && contentNode.num_coach_contents === 0; - // } - // if (role === 'coach') { - // passesFilters = passesFilters && contentNode.num_coach_contents > 0; - // } - // return passesFilters; - // }); - // }, }, }; From 59ab6dd479021a073c0da28927e4cba9e1f5da9d Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Tue, 21 Nov 2023 20:31:05 +0300 Subject: [PATCH 36/50] cleanedup bookmarkicon area --- .../CreateExamPage/BookMarkedResource.vue | 53 ++++++++----------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue index 732b6f772c..ccb3330aa1 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue @@ -3,32 +3,29 @@ @@ -109,10 +106,6 @@ text-decoration: none; } - .thumb-area { - margin-bottom: 16px; - } - .text-area { margin-bottom: $footer-height; } From 8ebe621f28deb1fcd420b41290718f33650595d6 Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:21:40 +0300 Subject: [PATCH 37/50] add show resourc component --- .../coach/assets/src/constants/index.js | 1 + .../coach/assets/src/routes/planExamRoutes.js | 4 + .../CreateExamPage/BookMarkedResource.vue | 60 ++++++----- .../plan/CreateExamPage/ResourceSelection.vue | 16 ++- .../plan/CreateExamPage/SectionSidePanel.vue | 3 + .../ShowBookMarkedResources.vue | 102 ++++++++++++++++++ 6 files changed, 159 insertions(+), 27 deletions(-) create mode 100644 kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ShowBookMarkedResources.vue diff --git a/kolibri/plugins/coach/assets/src/constants/index.js b/kolibri/plugins/coach/assets/src/constants/index.js index 4dae241107..b9f407758a 100644 --- a/kolibri/plugins/coach/assets/src/constants/index.js +++ b/kolibri/plugins/coach/assets/src/constants/index.js @@ -17,6 +17,7 @@ export const PageNames = { QUIZ_REPLACE_QUESTIONS: 'QUIZ_REPLACE_QUESTIONS', QUIZ_SELECT_RESOURCES: 'QUIZ_SELECT_RESOURCES', SELECT_FROM_RESOURCE:'SELECT_FROM_RESOURCE', + BOOK_MARKED_RESOURCES:'BOOK_MARKED_RESOURCES', /** TODO Remove unused */ EXAM_CREATION_TOPIC: 'EXAM_CREATION_TOPIC', diff --git a/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js b/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js index 4ac868046c..c41c591254 100644 --- a/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js +++ b/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js @@ -57,6 +57,10 @@ export default [ } ] }, + { + name: PageNames.BOOK_MARKED_RESOURCES, + path: ':section_id/book-marked-resources', + }, ], }, { diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue index ccb3330aa1..3ec1358e47 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/BookMarkedResource.vue @@ -3,29 +3,34 @@ @@ -54,6 +59,10 @@ type: Number, required: true, }, + to:{ + type:Object, + required:true, + } }, computed: { bookMarkBackgroundColor() { @@ -62,6 +71,9 @@ }; }, }, + mounted(){ + console.log(this.$route.params); + } }; @@ -91,7 +103,7 @@ .card { position: relative; vertical-align: top; - border-radius: 8px; + border-radius: 2px; transition: box-shadow $core-time ease; &:focus { 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 c4e498c7e6..2d95d65b9c 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ResourceSelection.vue @@ -15,6 +15,7 @@ v-if="bookmarks.length > 0" kind="bookmark" :isMobile="true" + :to="to" :bookMarkedResoures="bookmarks.length" /> @@ -139,6 +140,15 @@ content => !this.contentIsDirectoryKind(content) && !this.contentIsInLesson(content) ); }, + to(){ + return { + name: PageNames.BOOK_MARKED_RESOURCES, + params:{ + classId: this.$route.params.classId, + section_id: this.$route.params.section_id, + } + } + } }, watch: { @@ -157,9 +167,9 @@ }, }, beforeRouteEnter(to, from, next) { - console.log(to); - console.log(from); - console.log(to.params.topic_id); + // console.log(to); + // console.log(from); + // console.log(to.params.topic_id); if (to.params.topic_id) { this.showChannelQuizCreationTopicPage(this.$store, to.params).then(() => { next(); diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/SectionSidePanel.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/SectionSidePanel.vue index 0d88da67d3..0ae0338da1 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/SectionSidePanel.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/SectionSidePanel.vue @@ -23,11 +23,13 @@ import SectionEditor from './SectionEditor'; import ReplaceQuestions from './ReplaceQuestions'; import ResourceSelection from './ResourceSelection'; + import ShowBookMarkedResources from './ShowBookMarkedResources.vue'; const pageNameComponentMap = { [PageNames.QUIZ_SECTION_EDITOR]: SectionEditor, [PageNames.QUIZ_REPLACE_QUESTIONS]: ReplaceQuestions, [PageNames.QUIZ_SELECT_RESOURCES]: ResourceSelection, + [PageNames.BOOK_MARKED_RESOURCES]:ShowBookMarkedResources, }; export default { @@ -38,6 +40,7 @@ ReplaceQuestions, ResourceSelection, ResourceSelectionBreadcrumbs, + ShowBookMarkedResources, }, inject: ['quizForge'], data() { diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ShowBookMarkedResources.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ShowBookMarkedResources.vue new file mode 100644 index 0000000000..9ed71781b5 --- /dev/null +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ShowBookMarkedResources.vue @@ -0,0 +1,102 @@ + + + \ No newline at end of file From b14457f4a848e4ff38a623ed6325cb67121bc41e Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Wed, 22 Nov 2023 18:10:42 +0300 Subject: [PATCH 38/50] implement content filtering for select resource side panel --- .../assets/src/composables/useResources.js | 76 ++++++++++++++++++- .../coach/assets/src/routes/planExamRoutes.js | 8 ++ .../ShowBookMarkedResources.vue | 2 +- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/kolibri/plugins/coach/assets/src/composables/useResources.js b/kolibri/plugins/coach/assets/src/composables/useResources.js index 817a317237..ca9704fac1 100644 --- a/kolibri/plugins/coach/assets/src/composables/useResources.js +++ b/kolibri/plugins/coach/assets/src/composables/useResources.js @@ -1,5 +1,7 @@ import { ref, onMounted } from 'kolibri.lib.vueCompositionApi'; -import { ChannelResource, ContentNodeResource as bookMarkedResource } from 'kolibri.resources'; +import { ChannelResource,ContentNodeResource} from 'kolibri.resources'; +import { ContentNodeKinds } from 'kolibri.coreVue.vuex.constants'; +import { getContentNodeThumbnail } from 'kolibri.utils.contentNode'; export function useResources() { const resources = ref(null); @@ -15,14 +17,84 @@ export function useResources() { } function fetchBookMarkedResource() { - bookMarkedResource.fetchBookmarks({ params: { limit: 25, available: true } }).then(data => { + ContentNodeResource.fetchBookmarks({ params: { limit: 25, available: true } }).then(data => { bookmarks.value = data.results ? data.results : []; }); } + function _getTopicsWithExerciseDescendants(topicIds = []) { + return new Promise(resolve => { + if (!topicIds.length) { + resolve([]); + return; + } + const topicsNumAssessmentDescendantsPromise = ContentNodeResource.fetchDescendantsAssessments( + topicIds + ); + + topicsNumAssessmentDescendantsPromise.then(response => { + const topicsWithExerciseDescendants = []; + response.data.forEach(descendantAssessments => { + if (descendantAssessments.num_assessments > 0) { + topicsWithExerciseDescendants.push({ + id: descendantAssessments.id, + numAssessments: descendantAssessments.num_assessments, + exercises: [], + }); + } + }); + + ContentNodeResource.fetchDescendants( + topicsWithExerciseDescendants.map(topic => topic.id), + { + descendant_kind: ContentNodeKinds.EXERCISE, + } + ).then(response => { + response.data.forEach(exercise => { + const topic = topicsWithExerciseDescendants.find(t => t.id === exercise.ancestor_id); + topic.exercises.push(exercise); + }); + resolve(topicsWithExerciseDescendants); + }); + }); + }); + } + + function filterAndAnnotateContentList(childNodes) { + return new Promise(resolve => { + const childTopics = childNodes.filter(({ kind }) => kind === ContentNodeKinds.TOPIC); + const topicIds = childTopics.map(({ id }) => id); + const topicsThatHaveExerciseDescendants = _getTopicsWithExerciseDescendants(topicIds); + + topicsThatHaveExerciseDescendants.then(topics => { + const childNodesWithExerciseDescendants = childNodes + .map(childNode => { + const index = topics.findIndex(topic => topic.id === childNode.id); + if (index !== -1) { + return { ...childNode, ...topics[index] }; + } + return childNode; + }) + .filter(childNode => { + if (childNode.kind === ContentNodeKinds.TOPIC && (childNode.numAssessments || 0) < 1) { + return false; + } + return true; + }); + + const contentList = childNodesWithExerciseDescendants.map(node => ({ + ...node, + thumbnail: getContentNodeThumbnail(node), + })); + resolve(contentList); + }); + }); + } + onMounted(() => { fetchChannelResource(); fetchBookMarkedResource(); + filterAndAnnotateContentList() }); return { diff --git a/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js b/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js index c41c591254..54ae6b9cdd 100644 --- a/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js +++ b/kolibri/plugins/coach/assets/src/routes/planExamRoutes.js @@ -47,6 +47,8 @@ export default [ path: ':section_id/replace-questions', }, { + // this is basically show how the routing works once you in the select resources page and bookmarked resources page + // once you are in the bookmark resources page the only thing that we are interested in is the topic Id that always get updated name: PageNames.QUIZ_SELECT_RESOURCES, path: ':section_id/select-resources', @@ -60,6 +62,12 @@ export default [ { name: PageNames.BOOK_MARKED_RESOURCES, path: ':section_id/book-marked-resources', + children:[ + { + name:PageNames.SELECT_FROM_RESOURCE, + path:':topic_id', + } + ] }, ], }, diff --git a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ShowBookMarkedResources.vue b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ShowBookMarkedResources.vue index 9ed71781b5..7cdcd67905 100644 --- a/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ShowBookMarkedResources.vue +++ b/kolibri/plugins/coach/assets/src/views/plan/CreateExamPage/ShowBookMarkedResources.vue @@ -1,4 +1,4 @@ -