Commit c44c1185 authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch '324339-large-pdf-button' into 'master'

Display download button for large PDFs

See merge request gitlab-org/gitlab!75909
parents 99545a10 f3025f51
...@@ -38,7 +38,13 @@ export default { ...@@ -38,7 +38,13 @@ export default {
<div v-if="loading && !error" class="text-center loading"> <div v-if="loading && !error" class="text-center loading">
<gl-loading-icon class="mt-5" size="lg" /> <gl-loading-icon class="mt-5" size="lg" />
</div> </div>
<pdf-lab v-if="!loadError" :pdf="pdf" @pdflabload="onLoad" @pdflaberror="onError" /> <pdf-lab
v-if="!loadError"
:pdf="pdf"
@pdflabload="onLoad"
@pdflaberror="onError"
v-on="$listeners"
/>
<p v-if="error" class="text-center"> <p v-if="error" class="text-center">
<span v-if="loadError" ref="loadError"> <span v-if="loadError" ref="loadError">
{{ __('An error occurred while loading the file. Please try again later.') }} {{ __('An error occurred while loading the file. Please try again later.') }}
......
...@@ -45,7 +45,7 @@ export default { ...@@ -45,7 +45,7 @@ export default {
.promise.then(this.renderPages) .promise.then(this.renderPages)
.then((pages) => { .then((pages) => {
this.pages = pages; this.pages = pages;
this.$emit('pdflabload'); this.$emit('pdflabload', pages.length);
}) })
.catch((error) => { .catch((error) => {
this.$emit('pdflaberror', error); this.$emit('pdflaberror', error);
......
...@@ -40,6 +40,7 @@ export const viewerProps = (type, blob) => { ...@@ -40,6 +40,7 @@ export const viewerProps = (type, blob) => {
}, },
pdf: { pdf: {
url: blob.rawPath, url: blob.rawPath,
fileSize: blob.rawSize,
}, },
}[type]; }[type];
}; };
<script> <script>
import { GlButton } from '@gitlab/ui';
import PdfViewer from '~/blob/pdf/pdf_viewer.vue'; import PdfViewer from '~/blob/pdf/pdf_viewer.vue';
import { __ } from '~/locale';
import { PDF_MAX_FILE_SIZE, PDF_MAX_PAGE_LIMIT } from '../../constants';
export default { export default {
components: { PdfViewer }, components: { GlButton, PdfViewer },
i18n: {
tooLargeDescription: __('This PDF is too large to display. Please download to view.'),
tooLargeButtonText: __('Download PDF'),
},
props: { props: {
url: { url: {
type: String, type: String,
required: true, required: true,
}, },
fileSize: {
type: Number,
required: true,
},
},
data() {
return { totalPages: 0 };
},
computed: {
tooLargeToDisplay() {
return this.fileSize > PDF_MAX_FILE_SIZE || this.totalPages > PDF_MAX_PAGE_LIMIT;
},
},
methods: {
handleOnLoad(totalPages) {
this.totalPages = totalPages;
},
}, },
}; };
</script> </script>
<template> <template>
<pdf-viewer :pdf="url" /> <div>
<pdf-viewer v-if="!tooLargeToDisplay" :pdf="url" @pdflabload="handleOnLoad" />
<div v-else class="gl-display-flex gl-flex-direction-column gl-align-items-center gl-p-5">
<p>{{ $options.i18n.tooLargeDescription }}</p>
<gl-button icon="download" category="secondary" variant="confirm" :href="url" download>{{
$options.i18n.tooLargeButtonText
}}</gl-button>
</div>
</div>
</template> </template>
...@@ -20,3 +20,6 @@ export const COMMIT_MESSAGE_BODY_MAX_LENGTH = 72; ...@@ -20,3 +20,6 @@ export const COMMIT_MESSAGE_BODY_MAX_LENGTH = 72;
export const LIMITED_CONTAINER_WIDTH_CLASS = 'limit-container-width'; export const LIMITED_CONTAINER_WIDTH_CLASS = 'limit-container-width';
export const I18N_COMMIT_DATA_FETCH_ERROR = __('An error occurred while fetching commit data.'); export const I18N_COMMIT_DATA_FETCH_ERROR = __('An error occurred while fetching commit data.');
export const PDF_MAX_FILE_SIZE = 10000000; // 10 MB
export const PDF_MAX_PAGE_LIMIT = 50;
...@@ -12524,6 +12524,9 @@ msgstr "" ...@@ -12524,6 +12524,9 @@ msgstr ""
msgid "Download CSV" msgid "Download CSV"
msgstr "" msgstr ""
msgid "Download PDF"
msgstr ""
msgid "Download artifacts" msgid "Download artifacts"
msgstr "" msgstr ""
...@@ -35558,6 +35561,9 @@ msgstr "" ...@@ -35558,6 +35561,9 @@ msgstr ""
msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode." msgid "This GitLab instance is undergoing maintenance and is operating in read-only mode."
msgstr "" msgstr ""
msgid "This PDF is too large to display. Please download to view."
msgstr ""
msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring" msgid "This Project is currently archived and read-only. Please unarchive the project first if you want to resume Pull mirroring"
msgstr "" msgstr ""
......
import { shallowMount } from '@vue/test-utils'; import { GlButton } from '@gitlab/ui';
import Component from '~/repository/components/blob_viewers/pdf_viewer.vue'; import Component from '~/repository/components/blob_viewers/pdf_viewer.vue';
import PdfViewer from '~/blob/pdf/pdf_viewer.vue'; import PdfViewer from '~/blob/pdf/pdf_viewer.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
describe('PDF Viewer', () => { describe('PDF Viewer', () => {
let wrapper; let wrapper;
const propsData = { url: 'some/pdf_blob.pdf' }; const defaultPropsData = { url: 'some/pdf_blob.pdf' };
const createComponent = () => { const createComponent = (fileSize = 999) => {
wrapper = shallowMount(Component, { propsData }); wrapper = shallowMountExtended(Component, { propsData: { ...defaultPropsData, fileSize } });
}; };
const findPDFViewer = () => wrapper.findComponent(PdfViewer); const findPDFViewer = () => wrapper.findComponent(PdfViewer);
const findHelpText = () => wrapper.find('p');
const findDownLoadButton = () => wrapper.findComponent(GlButton);
it('renders a PDF Viewer component', () => { it('renders a PDF Viewer component', () => {
createComponent(); createComponent();
expect(findPDFViewer().exists()).toBe(true); expect(findPDFViewer().exists()).toBe(true);
expect(findPDFViewer().props('pdf')).toBe(propsData.url); expect(findPDFViewer().props('pdf')).toBe(defaultPropsData.url);
});
describe('Too large', () => {
beforeEach(() => createComponent(20000000));
it('does not a PDF Viewer component', () => {
expect(findPDFViewer().exists()).toBe(false);
});
it('renders help text', () => {
expect(findHelpText().text()).toBe(
'This PDF is too large to display. Please download to view.',
);
});
it('renders a download button', () => {
expect(findDownLoadButton().text()).toBe('Download PDF');
expect(findDownLoadButton().props('icon')).toBe('download');
});
});
describe('Too many pages', () => {
beforeEach(() => {
createComponent();
findPDFViewer().vm.$emit('pdflabload', 100);
});
it('does not a PDF Viewer component', () => {
expect(findPDFViewer().exists()).toBe(false);
});
it('renders a download button', () => {
expect(findDownLoadButton().exists()).toBe(true);
});
}); });
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment