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

First pass implementation of new paginated/inlined topic rendering. #8302

Merged
merged 1 commit into from
Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions kolibri/core/assets/src/api-resources/contentNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,22 +161,13 @@ export default new Resource({
* may be both pagination and non-pagination specific parameters
* @return {Promise<ContentNode>} Promise that resolves with the model data
*/
fetchTree(id, params) {
fetchTree({ id, params }) {
const promise = new ConditionalPromise();
const url = urls['kolibri:core:contentnode_tree_detail'](id);
return this.client({ url, params }).then(response => {
promise._promise = this.client({ url, params }).then(response => {
this.cacheData(response.data);
return response.data;
});
},
/**
* A method to simplify requesting more items from a previously paginated response from fetchTree
* @param {Object} more - the 'more' property of the 'children' pagination object from a response.
* @param {string} more.id - the id of the parent node for this request
* @param {Object} more.params - the GET parameters to return more results,
* may be both pagination and non-pagination specific parameters
* @return {Promise<ContentNode>} Promise that resolves with the model data
*/
fetchMoreTree({ id, params }) {
return this.fetchTree(id, params);
return promise;
},
});
13 changes: 7 additions & 6 deletions kolibri/plugins/learn/assets/src/modules/topicsTree/handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,19 @@ export function showTopicsTopic(store, { id, isRoot = false }) {
return store.dispatch('loading').then(() => {
store.commit('SET_PAGE_NAME', isRoot ? PageNames.TOPICS_CHANNEL : PageNames.TOPICS_TOPIC);
const promises = [
ContentNodeResource.fetchModel({ id, force: true }), // the topic
ContentNodeResource.fetchCollection({
getParams: {
parent: id,
ContentNodeResource.fetchTree({
id,
params: {
include_coach_content:
store.getters.isAdmin || store.getters.isCoach || store.getters.isSuperuser,
},
}), // the topic's children
}),
store.dispatch('setChannelInfo'),
];

return ConditionalPromise.all(promises).only(
samePageCheckGenerator(store),
([topic, children]) => {
([topic]) => {
const currentChannel = store.getters.getChannelObject(topic.channel_id);
if (!currentChannel) {
router.replace({ name: PageNames.CONTENT_UNAVAILABLE });
Expand All @@ -73,6 +72,8 @@ export function showTopicsTopic(store, { id, isRoot = false }) {
topic.tagline = currentChannel.tagline;
topic.thumbnail = currentChannel.thumbnail;
}
const children = topic.children.results || [];

store.commit('topicsTree/SET_STATE', {
isRoot,
channel: currentChannel,
Expand Down
9 changes: 9 additions & 0 deletions kolibri/plugins/learn/assets/src/modules/topicsTree/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ export default {
state.topic = payload.topic || {};
state.recommended = payload.recommended || [];
},
ADD_MORE_CONTENTS(state, payload) {
state.contents = state.contents.concat(payload.results);
state.topic.children.more = payload.more;
},
ADD_MORE_CHILD_CONTENTS(state, payload) {
const child = state.contents[payload.index];
child.children.results = child.children.results.concat(payload.results);
child.children.more = payload.more;
},
RESET_STATE(state) {
Object.assign(state, defaultState());
},
Expand Down
7 changes: 6 additions & 1 deletion kolibri/plugins/learn/assets/src/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,15 @@ export default [
{
name: PageNames.TOPICS_TOPIC,
path: '/topics/t/:id',
handler: toRoute => {
handler: (toRoute, fromRoute) => {
if (unassignedContentGuard()) {
return unassignedContentGuard();
}
// If navigation is triggered by a custom navigation updating the
// context query param, do not run the handler
if (toRoute.params.id === fromRoute.params.id) {
return;
}
showTopicsTopic(store, { id: toRoute.params.id });
},
},
Expand Down
46 changes: 40 additions & 6 deletions kolibri/plugins/learn/assets/src/views/TopicsPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,27 @@
</KGrid>

</div>

<div v-for="t in topics" :key="t.id">
<h3>
{{ t.title }}
</h3>
<ContentCardGroupGrid
v-if="t.children.results && t.children.results.length"
:contents="t.children.results"
:genContentLink="genContentLink"
/>
<KButton v-if="t.children && t.children.more" @click="childLoadMore(t.children.more)">
{{ $tr('viewMore') }}
</KButton>
</div>
<ContentCardGroupGrid
v-if="contents.length"
:contents="contents"
v-if="resources.length"
:contents="resources"
:genContentLink="genContentLink"
/>

<KButton v-if="topic.children && topic.children.more" @click="loadMore()">
{{ $tr('viewMore') }}
</KButton>
</div>

</div>
Expand All @@ -89,9 +103,11 @@

<script>

import { mapState } from 'vuex';
import { mapMutations, mapState } from 'vuex';
import responsiveWindowMixin from 'kolibri.coreVue.mixins.responsiveWindowMixin';
import ProgressIcon from 'kolibri.coreVue.components.ProgressIcon';
import { ContentNodeKinds } from 'kolibri.coreVue.vuex.constants';
import { ContentNodeResource } from 'kolibri.resources';
import { PageNames } from '../constants';
import ContentCardGroupGrid from './ContentCardGroupGrid';
import CustomContentRenderer from './ChannelRenderer/CustomContentRenderer';
Expand Down Expand Up @@ -126,6 +142,12 @@
channelTitle() {
return this.channel.title;
},
resources() {
return this.contents.filter(content => content.kind !== ContentNodeKinds.TOPIC);
},
topics() {
return this.contents.filter(content => content.kind === ContentNodeKinds.TOPIC);
},
topicOrChannel() {
// Get the channel if we're root, topic if not
return this.isRoot ? this.channel : this.topic;
Expand All @@ -136,7 +158,6 @@
this.topic &&
this.topic.options.modality === 'CUSTOM_NAVIGATION'
) {
this.topic.options.modality === 'CUSTOM_NAVIGATION';
return true;
}
return false;
Expand All @@ -158,13 +179,25 @@
},
},
methods: {
...mapMutations('topicsTree', ['ADD_MORE_CONTENTS', 'ADD_MORE_CHILD_CONTENTS']),
genContentLink(id, isLeaf) {
const routeName = isLeaf ? PageNames.TOPICS_CONTENT : PageNames.TOPICS_TOPIC;
return {
name: routeName,
params: { id },
};
},
loadMore() {
return ContentNodeResource.fetchTree(this.topic.children.more).then(data => {
this.ADD_MORE_CONTENTS(data.children);
});
},
childLoadMore(more) {
return ContentNodeResource.fetchTree(more).then(data => {
const index = this.contents.findIndex(content => content.id === more.id);
this.ADD_MORE_CHILD_CONTENTS({ index, ...data.children });
});
},
},
$trs: {
documentTitleForChannel: {
Expand All @@ -176,6 +209,7 @@
message: '{ topicTitle } - { channelTitle }',
context: 'DO NOT TRANSLATE',
},
viewMore: 'View more',
},
};

Expand Down