From f0b7591a825ce62f51be998be8f0f83707269a47 Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Wed, 27 Nov 2024 11:05:57 -0500 Subject: [PATCH 01/25] Refactor views lessons side panel view handling --- .../coach/assets/src/routes/lessonsRoutes.js | 2 +- .../sidePanels/LessonResourceSelection.vue | 249 ------------------ .../LessonResourceSelection/index.vue | 146 ++++++++++ .../subPages/SelectFromBookmarks.vue | 14 + .../subPages/SelectFromChannels.vue | 14 + .../subPages/SelectionIndex.vue | 118 +++++++++ .../useResourceSelection.js | 51 ++++ 7 files changed, 344 insertions(+), 250 deletions(-) delete mode 100644 kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection.vue create mode 100644 kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue create mode 100644 kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromBookmarks.vue create mode 100644 kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromChannels.vue create mode 100644 kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectionIndex.vue create mode 100644 kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/useResourceSelection.js diff --git a/kolibri/plugins/coach/assets/src/routes/lessonsRoutes.js b/kolibri/plugins/coach/assets/src/routes/lessonsRoutes.js index 825b54842d9..c89085e27a1 100644 --- a/kolibri/plugins/coach/assets/src/routes/lessonsRoutes.js +++ b/kolibri/plugins/coach/assets/src/routes/lessonsRoutes.js @@ -133,7 +133,7 @@ export default [ }, { name: PageNames.LESSON_SELECT_RESOURCES, - path: 'select-resources/:topicId?', + path: 'select-resources/:viewId?', component: LessonResourceSelection, }, { diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection.vue deleted file mode 100644 index 65865cc6e13..00000000000 --- a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection.vue +++ /dev/null @@ -1,249 +0,0 @@ - - - - - - - diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue new file mode 100644 index 00000000000..5769150491b --- /dev/null +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue @@ -0,0 +1,146 @@ + + + + + + + diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromBookmarks.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromBookmarks.vue new file mode 100644 index 00000000000..538c3a70515 --- /dev/null +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromBookmarks.vue @@ -0,0 +1,14 @@ + + + + diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromChannels.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromChannels.vue new file mode 100644 index 00000000000..ce3370258bc --- /dev/null +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromChannels.vue @@ -0,0 +1,14 @@ + + + + diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectionIndex.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectionIndex.vue new file mode 100644 index 00000000000..922b8a66e6f --- /dev/null +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectionIndex.vue @@ -0,0 +1,118 @@ + + + + + + + diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/useResourceSelection.js b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/useResourceSelection.js new file mode 100644 index 00000000000..03e0b7d283c --- /dev/null +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/useResourceSelection.js @@ -0,0 +1,51 @@ +import { ref, provide, inject } from '@vue/composition-api'; +import ContentNodeResource from 'kolibri-common/apiResources/ContentNodeResource'; +import ChannelResource from 'kolibri-common/apiResources/ChannelResource'; + +export default function useResourceSelection() { + const loading = ref(false); + const bookmarks = ref([]); + const channels = ref([]); + + const loadBookmarks = async () => { + const data = await ContentNodeResource.fetchBookmarks({ + params: { limit: 25, available: true }, + }); + + bookmarks.value = data.results || []; + }; + + const loadChannels = async () => { + const response = await ChannelResource.fetchCollection({ + getParams: { + available: true, + }, + }); + channels.value = response; + }; + + const loadData = async () => { + loading.value = true; + await Promise.all([loadBookmarks(), loadChannels()]); + loading.value = false; + }; + + loadData(); + + provide('bookmarks', bookmarks); + provide('channels', channels); + + return { + loading, + }; +} + +export function injectResourceSelection() { + const bookmarks = inject('bookmarks'); + const channels = inject('channels'); + + return { + bookmarks, + channels, + }; +} From 26c5735066de11b7afca468481ac21ee82a63268 Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Wed, 27 Nov 2024 13:26:08 -0500 Subject: [PATCH 02/25] Add basic implementation of UpdateResourceSelection --- .../assets/src/views/CoachAppBarPage.vue | 2 - .../ContentCardList.vue | 3 +- .../UpdatedResourceSelection.vue | 294 ++++++++++++++++++ .../subPages/SelectFromBookmarks.vue | 12 +- 4 files changed, 307 insertions(+), 4 deletions(-) create mode 100644 kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue diff --git a/kolibri/plugins/coach/assets/src/views/CoachAppBarPage.vue b/kolibri/plugins/coach/assets/src/views/CoachAppBarPage.vue index b156b6599d6..bea413b0459 100644 --- a/kolibri/plugins/coach/assets/src/views/CoachAppBarPage.vue +++ b/kolibri/plugins/coach/assets/src/views/CoachAppBarPage.vue @@ -12,8 +12,6 @@ - - diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/ContentCardList.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/ContentCardList.vue index 60523dd3bfd..7fa302da277 100644 --- a/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/ContentCardList.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/ContentCardList.vue @@ -153,7 +153,8 @@ // Function that returns a string that appears in the corner of the card contentCardMessage: { type: Function, // ContentNode => String - required: true, + required: false, + default: () => '', }, // Function that returns a route object to which the card navigates contentCardLink: { diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue new file mode 100644 index 00000000000..9ff94b529af --- /dev/null +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue @@ -0,0 +1,294 @@ + + + + + + + diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromBookmarks.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromBookmarks.vue index 538c3a70515..aa69f2037c3 100644 --- a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromBookmarks.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/subPages/SelectFromBookmarks.vue @@ -1,14 +1,24 @@ From 09d17986af9af327f616ddba19b0cd6c9b04420d Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Wed, 27 Nov 2024 14:03:59 -0500 Subject: [PATCH 03/25] Add selection and deselection of resources --- .../UpdatedResourceSelection.vue | 16 ++++++--- .../useResourceSelection.js | 34 +++++++++++++++++-- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue index 9ff94b529af..556b9b1a06b 100644 --- a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue @@ -62,7 +62,9 @@ topic, bookmarks, selectionRules = [], - selectedResources = [], + selectedResources, + selectResources, + deselectResources, } = injectResourceSelection(); const contentList = computed(() => { @@ -90,6 +92,8 @@ selectedResources, fetchMoreResources, viewMoreButtonState, + selectResources, + deselectResources, }; }, props: { @@ -99,7 +103,7 @@ }, multi: { type: Boolean, - deafult: true, + default: true, }, source: { type: String, @@ -152,13 +156,17 @@ return false; }, contentIsChecked(resource) { - return !!resource; + return this.selectedResources.find(res => res.id === resource.id); }, contentIsIndeterminate(resource) { return !resource; }, toggleSelected({ content, checked }) { - return content && checked; + if (checked) { + this.selectResources([content]); + } else { + this.deselectResources([content]); + } }, showCheckbox(node) { return node.kind !== ContentNodeKinds.TOPIC; diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/useResourceSelection.js b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/useResourceSelection.js index 03e0b7d283c..74e8e0f3ebc 100644 --- a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/useResourceSelection.js +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/useResourceSelection.js @@ -1,3 +1,4 @@ +import uniqBy from 'lodash/uniqBy'; import { ref, provide, inject } from '@vue/composition-api'; import ContentNodeResource from 'kolibri-common/apiResources/ContentNodeResource'; import ChannelResource from 'kolibri-common/apiResources/ChannelResource'; @@ -6,6 +7,7 @@ export default function useResourceSelection() { const loading = ref(false); const bookmarks = ref([]); const channels = ref([]); + const selectedResources = ref([]); const loadBookmarks = async () => { const data = await ContentNodeResource.fetchBookmarks({ @@ -32,8 +34,28 @@ export default function useResourceSelection() { loadData(); - provide('bookmarks', bookmarks); + const selectResources = (resources = []) => { + if (resources.length === 1) { + const [newResource] = resources; + if (!selectedResources.value.find(res => res.id === newResource.id)) { + selectedResources.value = [...selectedResources.value, newResource]; + } + } else { + selectedResources.value = uniqBy([...selectedResources.value, ...resources], 'id'); + } + }; + + const deselectResources = (resources = []) => { + selectedResources.value = selectedResources.value.filter(res => { + return !resources.find(unselectedResource => unselectedResource.id === res.id); + }); + }; + provide('channels', channels); + provide('bookmarks', bookmarks); + provide('selectedResources', selectedResources); + provide('selectResources', selectResources); + provide('deselectResources', deselectResources); return { loading, @@ -41,11 +63,17 @@ export default function useResourceSelection() { } export function injectResourceSelection() { - const bookmarks = inject('bookmarks'); const channels = inject('channels'); + const bookmarks = inject('bookmarks'); + const selectedResources = inject('selectedResources'); + const selectResources = inject('selectResources'); + const deselectResources = inject('deselectResources'); return { - bookmarks, channels, + bookmarks, + selectResources, + deselectResources, + selectedResources, }; } From eab52003d1eb4009597c54ca8c195dac70929e39 Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Wed, 27 Nov 2024 16:14:39 -0500 Subject: [PATCH 04/25] Fix styles and details to select from bookmarks --- .../UpdatedResourceSelection.vue | 29 ++++++++++++------- .../LessonResourceSelection/index.vue | 11 +++---- .../components/SidePanelModal/index.vue | 21 +++++++++----- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue index 556b9b1a06b..44452f0e67c 100644 --- a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/UpdatedResourceSelection.vue @@ -124,10 +124,17 @@ }; }, selectAllIndeterminate() { - return false; + return ( + !this.selectAllChecked && + this.contentList.some(resource => + this.selectedResources.some(selectedResource => selectedResource.id === resource.id), + ) + ); }, selectAllChecked() { - return false; + return this.contentList.every(resource => + this.selectedResources.some(selectedResource => selectedResource.id === resource.id), + ); }, }, methods: { @@ -149,14 +156,18 @@ topicsLink(topic_id) { return this.contentLink({ id: topic_id }); }, - handleSelectAll() { - return 'select all'; + handleSelectAll(checked) { + if (checked) { + this.selectResources(this.contentList); + } else { + this.deselectResources(this.contentList); + } }, - contentCheckboxDisabled() { - return false; + contentCheckboxDisabled(resource) { + return !this.selectionRules.every(rule => rule(resource) === true); }, contentIsChecked(resource) { - return this.selectedResources.find(res => res.id === resource.id); + return this.selectedResources.some(res => res.id === resource.id); }, contentIsIndeterminate(resource) { return !resource; @@ -181,10 +192,6 @@ @import '~kolibri-design-system/lib/styles/definitions'; - .select-resource { - padding-bottom: 6em; - } - .title-style { font-size: 1.4em; font-weight: 600; diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue index 5769150491b..5b46482a029 100644 --- a/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/index.vue @@ -14,7 +14,7 @@ icon="back" @click="goBack" /> -

{{ view.title || $tr('manageLessonResourcesTitle') }}

+

{{ view.title }}

@@ -66,10 +66,11 @@ setup() { const { loading } = useResourceSelection(); - const { saveAndFinishAction$ } = coreStrings; + const { saveAndFinishAction$, selectFromBookmarks$ } = coreStrings; return { loading, + selectFromBookmarks$, saveAndFinishAction$, }; }, @@ -84,16 +85,16 @@ view() { const componentMap = { [ResourceSelectionView.SELECTION_INDEX]: { - title: 'Select resources', + title: this.$tr('manageLessonResourcesTitle'), component: SelectionIndex, }, [ResourceSelectionView.SELECT_FROM_BOOKMARKS]: { - title: 'Select from bookmarks', + title: this.selectFromBookmarks$(), component: SelectFromBookmarks, back: ResourceSelectionView.SELECTION_INDEX, }, [ResourceSelectionView.SELECT_FROM_CHANNELS]: { - title: 'Select from channels', + title: this.$tr('manageLessonResourcesTitle'), component: SelectFromChannels, back: ResourceSelectionView.SELECTION_INDEX, }, diff --git a/packages/kolibri-common/components/SidePanelModal/index.vue b/packages/kolibri-common/components/SidePanelModal/index.vue index 978faf87e51..2a1683754fd 100644 --- a/packages/kolibri-common/components/SidePanelModal/index.vue +++ b/packages/kolibri-common/components/SidePanelModal/index.vue @@ -45,7 +45,9 @@
@@ -83,7 +85,8 @@ /* Will be calculated in mounted() as it will get the height of the fixedHeader then */ // @type {RefImpl} windowBreakpoint, - fixedHeaderHeight: '0px', + fixedHeaderHeight: 0, + fixedBottombarHeight: 0, lastFocus: null, }; }, @@ -213,13 +216,14 @@ } }, contentStyles() { + const fixedHeights = this.fixedHeaderHeight + this.fixedBottombarHeight; return { - /* When the header margin is 0px from top, add 24 to accomodate close button */ - 'margin-top': this.fixedHeaderHeight === '0px' ? '16px' : this.fixedHeaderHeight, + marginTop: `${this.fixedHeaderHeight || 16}px`, + marginBottom: `${this.fixedBottombarHeight}px`, padding: '24px 32px 16px', - 'overflow-y': 'scroll', - 'overflow-x': 'hidden', - height: `calc(100vh - ${this.fixedHeaderHeight})`, + overflowY: 'scroll', + overflowX: 'hidden', + height: `calc(100vh - ${fixedHeights}px)`, }; }, }, @@ -233,7 +237,10 @@ const htmlTag = window.document.getElementsByTagName('html')[0]; htmlTag.style['overflow-y'] = 'hidden'; // Gets the height of the fixed header - adds 40 to account for padding + 24 for closeButton - this.fixedHeaderHeight = `${this.$refs.fixedHeader.clientHeight}px`; + this.fixedHeaderHeight = this.$refs.fixedHeader.clientHeight; + if (this.$refs.fixedBottombar) { + this.fixedBottombarHeight = this.$refs.fixedBottombar.clientHeight; + } this.$nextTick(() => { this.$emit('shouldFocusFirstEl'); }); From 181209ee3c04990fcb0890fa4ab420fdd30c86a0 Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Thu, 28 Nov 2024 09:51:25 -0500 Subject: [PATCH 05/25] Fix fetch more resources in quizzes --- kolibri/plugins/coach/assets/src/composables/useFetchTree.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kolibri/plugins/coach/assets/src/composables/useFetchTree.js b/kolibri/plugins/coach/assets/src/composables/useFetchTree.js index 85a5b861db2..3cf4fa3dbc8 100644 --- a/kolibri/plugins/coach/assets/src/composables/useFetchTree.js +++ b/kolibri/plugins/coach/assets/src/composables/useFetchTree.js @@ -59,10 +59,11 @@ export default function useFetchTree({ topicId, params = {} } = {}) { // results is the list of all children from this call to the API // more is an object that contains the parameters we need to fetch the next batch of nodes const { results, more } = topicTree.children || { results: [], more: null }; + const moreParams = more?.params || null; set(_resources, [...get(_resources), ...results]); set(_topic, topicTree); - set(_moreParams, more); + set(_moreParams, moreParams); set(_loading, false); return results; From 6dee068a278f924502317d41c49f1320eeb0c480 Mon Sep 17 00:00:00 2001 From: Alex Velez Date: Thu, 28 Nov 2024 09:56:07 -0500 Subject: [PATCH 06/25] Add fetch and fetch more management --- .../ContentCardList.vue | 8 +- .../UpdatedResourceSelection.vue | 34 ++++--- .../LessonResourceSelection/constants.js | 11 +++ .../LessonResourceSelection/index.vue | 28 ++++-- .../subPages/SelectFromBookmarks.vue | 8 +- .../subPages/SelectionIndex.vue | 29 ++++-- .../LessonResourceSelection/useFetch.js | 89 +++++++++++++++++++ .../useResourceSelection.js | 68 ++++++++------ .../CreateExamPage/ResourceSelection.vue | 21 ++--- 9 files changed, 218 insertions(+), 78 deletions(-) create mode 100644 kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/constants.js create mode 100644 kolibri/plugins/coach/assets/src/views/lessons/LessonSummaryPage/sidePanels/LessonResourceSelection/useFetch.js diff --git a/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/ContentCardList.vue b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/ContentCardList.vue index 7fa302da277..5eadce16842 100644 --- a/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/ContentCardList.vue +++ b/kolibri/plugins/coach/assets/src/views/lessons/LessonResourceSelectionPage/ContentCardList.vue @@ -63,13 +63,13 @@