Commit 9873cd80 authored by Martin Wortschack's avatar Martin Wortschack

Merge branch 'add-single-file-support-to-upload-dropzone' into 'master'

Add singleFileSelection to uploadDropzone.vue

See merge request gitlab-org/gitlab!54462
parents 7c21775a 56ade3eb
...@@ -36,6 +36,11 @@ export default { ...@@ -36,6 +36,11 @@ export default {
required: false, required: false,
default: () => [VALID_IMAGE_FILE_MIMETYPE.mimetype], default: () => [VALID_IMAGE_FILE_MIMETYPE.mimetype],
}, },
singleFileSelection: {
type: Boolean,
required: false,
default: false,
},
}, },
data() { data() {
return { return {
...@@ -79,7 +84,7 @@ export default { ...@@ -79,7 +84,7 @@ export default {
return; return;
} }
this.$emit('change', files); this.$emit('change', this.singleFileSelection ? files[0] : files);
}, },
ondragenter(e) { ondragenter(e) {
this.dragCounter += 1; this.dragCounter += 1;
...@@ -92,7 +97,7 @@ export default { ...@@ -92,7 +97,7 @@ export default {
this.$refs.fileUpload.click(); this.$refs.fileUpload.click();
}, },
onFileInputChange(e) { onFileInputChange(e) {
this.$emit('change', e.target.files); this.$emit('change', this.singleFileSelection ? e.target.files[0] : e.target.files);
}, },
}, },
}; };
...@@ -119,9 +124,15 @@ export default { ...@@ -119,9 +124,15 @@ export default {
data-testid="dropzone-area" data-testid="dropzone-area"
> >
<gl-icon name="upload" :size="iconStyles.size" :class="iconStyles.class" /> <gl-icon name="upload" :size="iconStyles.size" :class="iconStyles.class" />
<p class="gl-mb-0"> <p class="gl-mb-0" data-testid="upload-text">
<slot name="upload-text" :openFileUpload="openFileUpload"> <slot name="upload-text" :openFileUpload="openFileUpload">
<gl-sprintf :message="__('Drop or %{linkStart}upload%{linkEnd} files to attach')"> <gl-sprintf
:message="
singleFileSelection
? __('Drop or %{linkStart}upload%{linkEnd} file to attach')
: __('Drop or %{linkStart}upload%{linkEnd} files to attach')
"
>
<template #link="{ content }"> <template #link="{ content }">
<gl-link @click.stop="openFileUpload"> <gl-link @click.stop="openFileUpload">
{{ content }} {{ content }}
...@@ -139,7 +150,7 @@ export default { ...@@ -139,7 +150,7 @@ export default {
name="upload_file" name="upload_file"
:accept="validFileMimetypes" :accept="validFileMimetypes"
class="hide" class="hide"
multiple :multiple="!singleFileSelection"
@change="onFileInputChange" @change="onFileInputChange"
/> />
</slot> </slot>
......
...@@ -10772,6 +10772,9 @@ msgstr "" ...@@ -10772,6 +10772,9 @@ msgstr ""
msgid "Drop or %{linkStart}upload%{linkEnd} designs to attach" msgid "Drop or %{linkStart}upload%{linkEnd} designs to attach"
msgstr "" msgstr ""
msgid "Drop or %{linkStart}upload%{linkEnd} file to attach"
msgstr ""
msgid "Drop or %{linkStart}upload%{linkEnd} files to attach" msgid "Drop or %{linkStart}upload%{linkEnd} files to attach"
msgstr "" msgstr ""
......
...@@ -19,6 +19,7 @@ exports[`Upload dropzone component correctly overrides description and drop mess ...@@ -19,6 +19,7 @@ exports[`Upload dropzone component correctly overrides description and drop mess
<p <p
class="gl-mb-0" class="gl-mb-0"
data-testid="upload-text"
> >
<span> <span>
Test %{linkStart}description%{linkEnd} message. Test %{linkStart}description%{linkEnd} message.
...@@ -98,10 +99,15 @@ exports[`Upload dropzone component when dragging renders correct template when d ...@@ -98,10 +99,15 @@ exports[`Upload dropzone component when dragging renders correct template when d
<p <p
class="gl-mb-0" class="gl-mb-0"
data-testid="upload-text"
> >
<gl-sprintf-stub Drop or
message="Drop or %{linkStart}upload%{linkEnd} files to attach" <gl-link-stub>
/>
upload
</gl-link-stub>
files to attach
</p> </p>
</div> </div>
</button> </button>
...@@ -178,10 +184,15 @@ exports[`Upload dropzone component when dragging renders correct template when d ...@@ -178,10 +184,15 @@ exports[`Upload dropzone component when dragging renders correct template when d
<p <p
class="gl-mb-0" class="gl-mb-0"
data-testid="upload-text"
> >
<gl-sprintf-stub Drop or
message="Drop or %{linkStart}upload%{linkEnd} files to attach" <gl-link-stub>
/>
upload
</gl-link-stub>
files to attach
</p> </p>
</div> </div>
</button> </button>
...@@ -258,10 +269,15 @@ exports[`Upload dropzone component when dragging renders correct template when d ...@@ -258,10 +269,15 @@ exports[`Upload dropzone component when dragging renders correct template when d
<p <p
class="gl-mb-0" class="gl-mb-0"
data-testid="upload-text"
> >
<gl-sprintf-stub Drop or
message="Drop or %{linkStart}upload%{linkEnd} files to attach" <gl-link-stub>
/>
upload
</gl-link-stub>
files to attach
</p> </p>
</div> </div>
</button> </button>
...@@ -337,10 +353,15 @@ exports[`Upload dropzone component when dragging renders correct template when d ...@@ -337,10 +353,15 @@ exports[`Upload dropzone component when dragging renders correct template when d
<p <p
class="gl-mb-0" class="gl-mb-0"
data-testid="upload-text"
> >
<gl-sprintf-stub Drop or
message="Drop or %{linkStart}upload%{linkEnd} files to attach" <gl-link-stub>
/>
upload
</gl-link-stub>
files to attach
</p> </p>
</div> </div>
</button> </button>
...@@ -416,10 +437,15 @@ exports[`Upload dropzone component when dragging renders correct template when d ...@@ -416,10 +437,15 @@ exports[`Upload dropzone component when dragging renders correct template when d
<p <p
class="gl-mb-0" class="gl-mb-0"
data-testid="upload-text"
> >
<gl-sprintf-stub Drop or
message="Drop or %{linkStart}upload%{linkEnd} files to attach" <gl-link-stub>
/>
upload
</gl-link-stub>
files to attach
</p> </p>
</div> </div>
</button> </button>
...@@ -495,10 +521,15 @@ exports[`Upload dropzone component when no slot provided renders default dropzon ...@@ -495,10 +521,15 @@ exports[`Upload dropzone component when no slot provided renders default dropzon
<p <p
class="gl-mb-0" class="gl-mb-0"
data-testid="upload-text"
> >
<gl-sprintf-stub Drop or
message="Drop or %{linkStart}upload%{linkEnd} files to attach" <gl-link-stub>
/>
upload
</gl-link-stub>
files to attach
</p> </p>
</div> </div>
</button> </button>
......
import { GlIcon } from '@gitlab/ui'; import { GlIcon, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import UploadDropzone from '~/vue_shared/components/upload_dropzone/upload_dropzone.vue'; import UploadDropzone from '~/vue_shared/components/upload_dropzone/upload_dropzone.vue';
...@@ -14,6 +14,7 @@ describe('Upload dropzone component', () => { ...@@ -14,6 +14,7 @@ describe('Upload dropzone component', () => {
const findDropzoneCard = () => wrapper.find('.upload-dropzone-card'); const findDropzoneCard = () => wrapper.find('.upload-dropzone-card');
const findDropzoneArea = () => wrapper.find('[data-testid="dropzone-area"]'); const findDropzoneArea = () => wrapper.find('[data-testid="dropzone-area"]');
const findIcon = () => wrapper.find(GlIcon); const findIcon = () => wrapper.find(GlIcon);
const findUploadText = () => wrapper.find('[data-testid="upload-text"]').text();
function createComponent({ slots = {}, data = {}, props = {} } = {}) { function createComponent({ slots = {}, data = {}, props = {} } = {}) {
wrapper = shallowMount(UploadDropzone, { wrapper = shallowMount(UploadDropzone, {
...@@ -22,6 +23,9 @@ describe('Upload dropzone component', () => { ...@@ -22,6 +23,9 @@ describe('Upload dropzone component', () => {
displayAsCard: true, displayAsCard: true,
...props, ...props,
}, },
stubs: {
GlSprintf,
},
data() { data() {
return data; return data;
}, },
...@@ -30,6 +34,7 @@ describe('Upload dropzone component', () => { ...@@ -30,6 +34,7 @@ describe('Upload dropzone component', () => {
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null;
}); });
describe('when slot provided', () => { describe('when slot provided', () => {
...@@ -60,6 +65,18 @@ describe('Upload dropzone component', () => { ...@@ -60,6 +65,18 @@ describe('Upload dropzone component', () => {
}); });
}); });
describe('upload text', () => {
it.each`
collection | description | props | expected
${'multiple'} | ${'by default'} | ${null} | ${'files to attach'}
${'singular'} | ${'when singleFileSelection'} | ${{ singleFileSelection: true }} | ${'file to attach'}
`('displays $collection version $description', ({ props, expected }) => {
createComponent({ props });
expect(findUploadText()).toContain(expected);
});
});
describe('when dragging', () => { describe('when dragging', () => {
it.each` it.each`
description | eventPayload description | eventPayload
...@@ -141,6 +158,21 @@ describe('Upload dropzone component', () => { ...@@ -141,6 +158,21 @@ describe('Upload dropzone component', () => {
wrapper.vm.ondrop(mockEvent); wrapper.vm.ondrop(mockEvent);
expect(wrapper.emitted()).not.toHaveProperty('error'); expect(wrapper.emitted()).not.toHaveProperty('error');
}); });
describe('singleFileSelection = true', () => {
it('emits a single file on drop', () => {
createComponent({
data: mockData,
props: { singleFileSelection: true },
});
const mockFile = { type: 'image/jpg' };
const mockEvent = mockDragEvent({ files: [mockFile] });
wrapper.vm.ondrop(mockEvent);
expect(wrapper.emitted().change[0]).toEqual([mockFile]);
});
});
}); });
}); });
......
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