Skip to content

Commit

Permalink
Address PR feedback, fix downloads page reactivity problems
Browse files Browse the repository at this point in the history
  • Loading branch information
marcellamaki committed Sep 27, 2023
1 parent 91adefa commit 6f2315a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 114 deletions.
66 changes: 11 additions & 55 deletions kolibri/plugins/learn/assets/src/composables/useDownloadRequests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* A composable function containing logic related to download requests
*/

import { computed, getCurrentInstance, reactive, ref } from 'kolibri.lib.vueCompositionApi';
import { getCurrentInstance, reactive, ref } from 'kolibri.lib.vueCompositionApi';
import { ContentRequestResource } from 'kolibri.resources';
import { createTranslator } from 'kolibri.utils.i18n';
import { get, set } from '@vueuse/core';
Expand Down Expand Up @@ -41,7 +41,7 @@ export default function useDownloadRequests(store) {
return ContentRequestResource.list(params)
.then(downloadRequests => {
for (const obj of downloadRequests) {
set(downloadRequestMap, obj.id, obj);
set(downloadRequestMap, obj.contentnode_id, obj);
}
set(loading, false);
})
Expand All @@ -67,14 +67,14 @@ export default function useDownloadRequests(store) {
redirectBrowser(urls['kolibri:kolibri.plugins.learn:my_downloads']());
}

function addDownloadRequest(content) {
function addDownloadRequest(contentNode) {
const metadata = {
title: content.title,
file_size: content.files.reduce((size, f) => size + f.file_size, 0),
learning_activities: content.learning_activities,
title: contentNode.title,
file_size: contentNode.files.reduce((size, f) => size + f.file_size, 0),
learning_activities: contentNode.learning_activities,
};
const data = {
contentnode_id: content.id,
contentnode_id: contentNode.id,
metadata,
source_id: store.getters.currentUserId,
source_instance_id: get(instanceId),
Expand All @@ -84,7 +84,7 @@ export default function useDownloadRequests(store) {
date_added: new Date(),
};
ContentRequestResource.create(data).then(downloadRequest => {
set(downloadRequestMap, downloadRequest.node_id, downloadRequest);
set(downloadRequestMap, downloadRequest.contentnode_id, downloadRequest);
});

store.commit('CORE_CREATE_SNACKBAR', {
Expand All @@ -98,54 +98,14 @@ export default function useDownloadRequests(store) {
return Promise.resolve();
}

function removeDownloadRequest(content) {
function removeDownloadRequest(contentRequest) {
ContentRequestResource.deleteModel({
id: content.id,
contentnode_id: content.contentnode_id,
id: contentRequest.id,
});
Vue.delete(downloadRequestMap, content.id);
Vue.delete(downloadRequestMap, contentRequest.contentnode_id);
return Promise.resolve();
}

function sortedFilteredDownloads() {
const query = computed(() => get(route).query);
const route = computed(() => store.state.route);
const sort = computed(() => query.value.sort);
const activityType = computed(() => query.value.activity || 'all');
let downloadsToDisplay = [];
if (downloadRequestMap) {
for (const [, value] of Object.entries(downloadRequestMap)) {
downloadsToDisplay.push(value);
}
if (activityType) {
if (activityType.value !== 'all') {
downloadsToDisplay = downloadsToDisplay.filter(download =>
download.metadata.learning_activities.includes(activityType.value)
);
}
}
if (sort) {
switch (sort.value) {
case 'newest':
downloadsToDisplay.sort((a, b) => new Date(b.requested_at) - new Date(a.requested_at));
break;
case 'oldest':
downloadsToDisplay.sort((a, b) => new Date(a.requested_at) - new Date(b.requested_at));
break;
case 'smallest':
downloadsToDisplay.sort((a, b) => a.metadata.file_size - b.metadata.file_size);
break;
case 'largest':
downloadsToDisplay.sort((a, b) => b.metadata.file_size - a.metadata.file_size);
break;
default:
// If no valid sort option provided, return unsorted array
break;
}
}
}
}

function isDownloadingByLearner(content) {
if (!content || !content.id) {
return false;
Expand All @@ -162,17 +122,13 @@ export default function useDownloadRequests(store) {
return Boolean(downloadRequest && downloadRequest.status === 'COMPLETED');
}

const downloads = computed(() => this.sortedFilteredDownloads());

return {
fetchUserDownloadRequests,
fetchAvailableFreespace,
availableSpace,
downloadRequestMap,
addDownloadRequest,
loading,
downloads,
sortedFilteredDownloads,
removeDownloadRequest,
downloadRequestsTranslator,
isDownloadingByLearner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
<form>

<PaginatedListContainerWithBackend
v-if="downloadItemsListLength > 0"
v-model="currentPage"
:itemsPerPage="itemsPerPage"
:totalPageNumber="totalPageNumber"
:numFilteredItems="downloadItemsListLength"
:numFilteredItems="downloadItemListLength"
>
<CoreTable>
<template #headers>
Expand All @@ -26,7 +25,7 @@
<th> {{ coreString('dateAdded') }} </th>
</template>
<template #tbody>
<tbody v-if="!loading && downloadRequestMap">
<tbody v-if="!loading">
<tr
v-for="download in paginatedDownloads"
:key="download.contentnode_id"
Expand Down Expand Up @@ -83,7 +82,7 @@
</tbody>
</template>
</CoreTable>
<p v-if="!loading && (!downloadRequestMap || !downloadItemsListLength)">
<p v-if="!loading && !downloadItemListLength">
{{ coreString('noResourcesDownloaded') }}
</p>
</PaginatedListContainerWithBackend>
Expand Down Expand Up @@ -137,53 +136,11 @@
const store = getCurrentInstance().proxy.$store;
const query = computed(() => get(route).query);
const route = computed(() => store.state.route);
const sort = computed(() => query.value.sort);
const pageSizeNumber = computed(() => Number(query.value.page_size || 25));
const activityType = computed(() => query.value.activity || 'all');
const downloads = computed(() => {
let downloadsToDisplay = [];
if (downloadRequestMap) {
for (const [, value] of Object.entries(downloadRequestMap)) {
downloadsToDisplay.push(value);
}
if (activityType) {
if (activityType.value !== 'all') {
downloadsToDisplay = downloadsToDisplay.filter(download =>
download.metadata.learning_activities.includes(activityType.value)
);
}
}
if (sort) {
switch (sort.value) {
case 'newest':
downloadsToDisplay.sort(
(a, b) => new Date(b.requested_at) - new Date(a.requested_at)
);
break;
case 'oldest':
downloadsToDisplay.sort(
(a, b) => new Date(a.requested_at) - new Date(b.requested_at)
);
break;
case 'smallest':
downloadsToDisplay.sort((a, b) => a.metadata.file_size - b.metadata.file_size);
break;
case 'largest':
downloadsToDisplay.sort((a, b) => b.metadata.file_size - a.metadata.file_size);
break;
default:
// If no valid sort option provided, return unsorted array
break;
}
}
}
return downloadsToDisplay;
});
return {
downloadRequestMap,
pageSizeNumber,
getLearningActivityIcon,
downloads,
networkDevices,
availableSpace,
genExternalContentURLBackLinkCurrentPage,
Expand Down Expand Up @@ -233,25 +190,58 @@
});
},
},
downloads() {
const sort = this.$route.query.sort;
const activityType = this.$route.query.activity;
console.log(Object.values(this.downloadRequestMap));
const downloadsToDisplay = Object.values(this.downloadRequestMap).filter(download => {
if (activityType && activityType !== 'all') {
return download.metadata.learning_activities.includes(activityType);
}
return true;
});
if (sort) {
switch (sort) {
case 'newest':
downloadsToDisplay.sort(
(a, b) => new Date(b.requested_at) - new Date(a.requested_at)
);
break;
case 'oldest':
downloadsToDisplay.sort(
(a, b) => new Date(a.requested_at) - new Date(b.requested_at)
);
break;
case 'smallest':
downloadsToDisplay.sort((a, b) => a.metadata.file_size - b.metadata.file_size);
break;
case 'largest':
downloadsToDisplay.sort((a, b) => b.metadata.file_size - a.metadata.file_size);
break;
default:
// If no valid sort option provided, return unsorted array
break;
}
}
return downloadsToDisplay;
},
paginatedDownloads() {
if (this.downloads.length > 0) {
console.log([...this.downloads]);
if (this.downloads && this.downloads.length > 0) {
const startIndex = (this.currentPage - 1) * this.itemsPerPage;
const endIndex = startIndex + this.itemsPerPage;
return this.downloads.slice(startIndex, endIndex);
} else {
return [];
}
},
downloadItemsListLength() {
return Object.keys(this.downloadRequestMap).length;
downloadItemListLength() {
return this.downloads ? this.downloads.length : 0;
},
totalPageNumber() {
if (
this.downloadsToDisplay &&
this.downloadsToDisplay.length &&
this.pageSizeNumber.value
) {
return Math.ceil(this.downloadsToDisplay.length / this.pageSizeNumber.value);
if (this.downloads && this.downloads.length && this.pageSizeNumber) {
return Math.ceil(this.downloads.length / this.pageSizeNumber);
}
return 1;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
:deviceId="device['instance_id']"
:deviceName="device['device_name']"
:deviceIcon="getDeviceIcon(device)"
:channels="device.channels"
:channels="deviceChannelsMap[device['instance_id']]"
:totalChannels="device['total_count']"
:pinIcon="getPinIcon(true)"
:showDescription="device['instance_id'] === studioId"
Expand All @@ -51,7 +51,7 @@
:deviceId="device['instance_id']"
:deviceName="device['device_name']"
:deviceIcon="getDeviceIcon(device)"
:channels="device.channels"
:channels="deviceChannelsMap[device['instance_id']]"
:totalChannels="device['total_count']"
:pinIcon="getPinIcon(false)"
@togglePin="handlePinToggle"
Expand Down
5 changes: 3 additions & 2 deletions kolibri/plugins/learn/assets/src/views/LibraryPage/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@
import useCardViewStyle from '../../composables/useCardViewStyle';
import useContentLink from '../../composables/useContentLink';
import useCoreLearn from '../../composables/useCoreLearn';
import {
import useDevices, {
currentDeviceData,
setCurrentDevice,
StudioNotAllowedError,
Expand Down Expand Up @@ -337,7 +337,8 @@
const { canAddDownloads, canDownloadExternally } = useCoreLearn();
const { currentCardViewStyle } = useCardViewStyle();
const { back } = useContentLink();
const { baseurl, deviceName, fetchDevices } = currentDeviceData();
const { baseurl, deviceName } = currentDeviceData();
const { fetchDevices } = useDevices();
const { fetchChannels } = useChannels();
const { fetchPinsForUser } = usePinnedDevices();
Expand Down

0 comments on commit 6f2315a

Please sign in to comment.