Skip to content

Commit de9591b

Browse files
committed
Implement downloadFile action to download files
1 parent 0f45ee3 commit de9591b

3 files changed

Lines changed: 47 additions & 9 deletions

File tree

contentcuration/contentcuration/frontend/channelEdit/views/files/FileUploadItem.vue

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969

7070
<script>
7171
72-
import { mapGetters } from 'vuex';
72+
import { mapActions, mapGetters } from 'vuex';
7373
import FileStatusText from 'shared/views/files/FileStatusText';
7474
import Uploader from 'shared/views/files/Uploader';
7575
import { constantsTranslationMixin, fileSizeMixin, fileStatusMixin } from 'shared/mixins';
@@ -159,7 +159,7 @@
159159
label: this.$tr('downloadMenuOptionLabel'),
160160
value: 'DOWNLOAD_FILE',
161161
onClick: () => {
162-
this.downloadFile();
162+
this.initiateFileDownload();
163163
},
164164
condition: this.fileDisplay,
165165
},
@@ -184,6 +184,8 @@
184184
},
185185
},
186186
methods: {
187+
...mapActions('file', ['downloadFile']),
188+
...mapActions(['showSnackbar']),
187189
completeUpload(fileUpload) {
188190
if (fileUpload.id === this.fileUploadId) {
189191
this.uploadCompleteHandler(fileUpload);
@@ -192,8 +194,17 @@
192194
uploadingHandler(fileUpload) {
193195
this.fileUploadId = fileUpload.id;
194196
},
195-
downloadFile() {
196-
window.open(this.fileDisplay.url, '_blank');
197+
initiateFileDownload() {
198+
try {
199+
this.downloadFile({
200+
url: this.fileDisplay.url,
201+
fileName: this.formattedFileDisplay,
202+
});
203+
} catch (e) {
204+
this.showSnackbar({
205+
text: this.$tr('downloadFailed'),
206+
});
207+
}
197208
},
198209
removeFile() {
199210
this.$emit('remove', this.file);
@@ -204,6 +215,7 @@
204215
replaceFileMenuOptionLabel: 'Replace file',
205216
downloadMenuOptionLabel: 'Download',
206217
removeMenuOptionLabel: 'Remove',
218+
downloadFailed: 'Failed to download file',
207219
/* eslint-disable kolibri/vue-no-unused-translations */
208220
removeFileButton: 'Remove',
209221
retryUpload: 'Retry upload',

contentcuration/contentcuration/frontend/channelEdit/views/files/__tests__/fileUpload.spec.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const testFiles = [
1111
preset: {
1212
id: 'document',
1313
supplementary: false,
14-
order: 1,
14+
order: 2,
1515
},
1616
},
1717
{
@@ -71,8 +71,8 @@ describe('fileUpload', () => {
7171
});
7272
describe('computed', () => {
7373
it('should map the files to the correct presets', () => {
74-
expect(wrapper.vm.primaryFileMapping[0].file.id).toBe('file-1');
75-
expect(wrapper.vm.primaryFileMapping[1].file.id).toBe('file-3');
74+
expect(wrapper.vm.primaryFileMapping[0].file.id).toBe('file-3');
75+
expect(wrapper.vm.primaryFileMapping[1].file.id).toBe('file-1');
7676
expect(wrapper.vm.primaryFileMapping).toHaveLength(2);
7777
});
7878
it('should disallow file removal if there is only one primary file', () => {
@@ -98,11 +98,11 @@ describe('fileUpload', () => {
9898
uploadItem = wrapper.findAll(FileUploadItem).at(0);
9999
});
100100
it('should automatically select the first file on load', () => {
101-
expect(wrapper.vm.selected).toBe('file-1');
101+
expect(wrapper.vm.selected).toBe('file-3');
102102
});
103103
it('selectPreview should select the preview when items are selected in the list', () => {
104104
uploadItem.vm.$emit('selected');
105-
expect(wrapper.vm.selected).toBe('file-1');
105+
expect(wrapper.vm.selected).toBe('file-3');
106106
});
107107
it('emitted remove event should trigger removal dialog', () => {
108108
const deleteFile = jest.fn();

contentcuration/contentcuration/frontend/shared/vuex/file/actions.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,29 @@ export function getAudioData(context, url) {
281281
.catch(reject);
282282
});
283283
}
284+
285+
export function downloadFile(context, { url, fileName }) {
286+
return new Promise((resolve, reject) => {
287+
client
288+
.get(url, {
289+
responseType: 'blob',
290+
})
291+
.then(response => {
292+
try {
293+
const blobUrl = window.URL.createObjectURL(response.data);
294+
const anchor = document.createElement('a');
295+
anchor.href = blobUrl;
296+
anchor.download = fileName;
297+
anchor.style.display = 'none';
298+
document.body.appendChild(anchor);
299+
anchor.click();
300+
document.body.removeChild(anchor);
301+
window.URL.revokeObjectURL(blobUrl);
302+
resolve(true);
303+
} catch (error) {
304+
reject(error);
305+
}
306+
})
307+
.catch(reject);
308+
});
309+
}

0 commit comments

Comments
 (0)