Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

number of resources updates on selection #11825

37 changes: 25 additions & 12 deletions kolibri/plugins/coach/assets/src/composables/useQuizResources.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,31 +47,44 @@ export default function useQuizResources({ topicId } = {}) {
* the_resources have been updated, filtering out all topics which do not have assessments
*/
async function annotateTopicsWithDescendantCounts(topicIds = []) {
return ContentNodeResource.fetchDescendantsAssessments(topicIds)
.then(({ data: topicsWithDescendantCounts }) => {
const promises = [
ContentNodeResource.fetchDescendantsAssessments(topicIds),
ContentNodeResource.fetchDescendants(topicIds, {
descendant__kind: ContentNodeKinds.EXERCISE,
}),
];
return Promise.all(promises)
.then(([{ data: topicsWithAssessmentCounts }, { data: exerciseDescendants }]) => {
const childrenWithAnnotatedTopics = get(_resources)
.map(node => {
// We'll map so that the topics are updated in place with the num_assessments, others
// are left as-is
if (node.kind === ContentNodeKinds.TOPIC) {
const topic = topicsWithDescendantCounts.find(t => t.id === node.id);
if (topic) {
node.num_assessments = topic.num_assessments;
if ([ContentNodeKinds.TOPIC, ContentNodeKinds.CHANNEL].includes(node.kind)) {
const topicWithAssessments = topicsWithAssessmentCounts.find(t => t.id === node.id);
if (topicWithAssessments) {
node.num_assessments = topicWithAssessments.num_assessments;
}
exerciseDescendants.forEach(exercise => {
if (exercise.ancestor_id === node.id) {
node.num_exercises ? (node.num_exercises += 1) : (node.num_exercises = 1);
}
});

if (!validateObject(node, QuizExercise)) {
logger.warn('Topic node was not a valid QuizExercise after annotation:', node);
logger.error('Topic node was not a valid QuizExercise after annotation:', node);
}
}
return node;
})
.filter(node => {
// Only keep topics which have assessments in them to begin with
if (node.kind !== ContentNodeKinds.TOPIC) {
return true;
}
return node.num_assessments > 0;
return (
node.kind === ContentNodeKinds.EXERCISE ||
([ContentNodeKinds.TOPIC, ContentNodeKinds.CHANNEL].includes(node.kind) &&
node.num_assessments > 0)
);
});
set(_resources, childrenWithAnnotatedTopics);
setResources(childrenWithAnnotatedTopics);
})
.catch(e => {
// TODO Work out best UX for this situation -- it may depend on if we're fetching more
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
//selectFoldersOrExercises$,
numberOfSelectedResources$,
numberOfResources$,
selectedResourcesInformation$,
} = enhancedQuizManagementStrings;

// TODO let's not use text for this
Expand Down Expand Up @@ -227,7 +228,7 @@
// to the value of the channels (treating those channels as the topics) -- we then
// call this annotateTopicsWithDescendantCounts method to ensure that the channels are
// annotated with their num_assessments and those without assessments are filtered out
annotateTopicsWithDescendantCounts(channels.value.map(c => c.id)).then(() => {
annotateTopicsWithDescendantCounts(resources.value.map(c => c.id)).then(() => {
_loading.value = false;
});
});
Expand Down Expand Up @@ -294,6 +295,7 @@
addToWorkingResourcePool,
removeFromWorkingResourcePool,
showBookmarks,
selectedResourcesInformation$,
};
},
props: {
Expand All @@ -320,29 +322,7 @@
this.contentList.some(content => workingResourceIds.includes(content.id))
);
},
selectionMetadata(/*content*/) {
// TODO This should return a function that returns a string telling us how many of this
// topic's descendants are selected out of its total descendants -- basically answering
// "How many resources in the working resource_pool are from this topic?"
// Tracked in https://github.com/learningequality/kolibri/issues/11741
return () => '';
// let count = 0;
// let total = 0;
// if (this.ancestorCounts[content.id]) {
// count = this.ancestorCounts[content.id].count;
// total = this.ancestorCounts[content.id].total;
// }
// if (count) {
// return this.$tr('selectionInformation', {
// count,
// total,
// });
// }
// return '';
// return function() {
// console.log('Dynamic function called');
// };
},

getBookmarksLink() {
// Inject the showBookmarks parameter so that
// the resourceSelection component now renderes only the
Expand Down Expand Up @@ -391,21 +371,18 @@
},
toggleSelected({ content, checked }) {
if (checked) {
this.addToSelectedResources(content);
this.addToWorkingResourcePool([content]);
} else {
this.removeFromWorkingResourcePool(content);
}
},
addToSelectedResources(content) {
this.addToWorkingResourcePool([content]);
},
toggleTopicInWorkingResources(isChecked) {
if (isChecked) {
this.isSelectAllChecked = true;
this.addToWorkingResourcePool(this.contentList);
} else {
this.isSelectAllChecked = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the setting of isSelectAllChecked here is good as it's a computed property.

In my note on that isSelectAllChecked property I mentioned that the side-effects of manipulating the working resource pool should probably be moved here.

In the else block here, however, rather than resetWorkingResourcePool this should instead remove all items in the content list from the working resource pool. resetWorkingResourcePool just undoes all changes the user has made since opening the panel, which is not desired here.

In this case, you'd need to do a this.contentList.forEach(content => this.removeFromWorkingResourcePool(content)) (or something along those lines -- you'll probably also want to be sure to filter out Topics as we aren't permitting full topic selection until #11790 is implemented)

this.resetWorkingResourcePool();
this.contentList.forEach(content => {
this.removeFromWorkingResourcePool(content);
});
}
},
topicListingLink({ topicId }) {
Expand Down Expand Up @@ -433,19 +410,23 @@

this.$router.replace(this.closePanelRoute);
},
// 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 '';
// },
selectionMetadata(content) {
if (content.kind === ContentNodeKinds.TOPIC) {
const total = content.num_exercises;
const numberOfresourcesSelected = this.workingResourcePool.reduce((acc, wr) => {
if (wr.ancestors.map(ancestor => ancestor.id).includes(content.id)) {
return acc + 1;
}
return acc;
}, 0);

return this.selectedResourcesInformation$({
count: numberOfresourcesSelected,
total: total,
});
}
return '';
},
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,8 @@ export const enhancedQuizManagementStrings = createTranslator('EnhancedQuizManag
numberOfResources: {
message: '{count, number} {count, plural, one {resource selected} other {resources selected}}',
},
selectedResourcesInformation: {
message:
'{count, number, integer} of {total, number, integer} {total, plural, one {resource selected} other {resources selected}}',
},
});