Commit 61b83522 authored by Phil Hughes's avatar Phil Hughes

Added design management empty state

parent 5801ee3c
<script>
import UploadButton from './upload/button.vue';
export default {
components: {
UploadButton,
},
props: {
canUploadDesign: {
type: Boolean,
required: true,
},
isSaving: {
type: Boolean,
required: true,
},
},
methods: {
onFileUploadChange(files) {
this.$emit('upload', files);
},
},
};
</script>
<template>
<div class="empty-state row">
<div class="col-12">
<div class="text-content">
<h4 class="center">
{{ s__('DesignManagement|The one place for your designs') }}
</h4>
<p>
{{
s__(`DesignManagement|Upload and view the latest designs for this issue.
Consistent and easy to find, so everyone is up to date.`)
}}
</p>
<div v-if="canUploadDesign" class="center">
<upload-button :is-saving="isSaving" @upload="onFileUploadChange" />
</div>
</div>
</div>
</div>
</template>
<script>
import { GlButton, GlLoadingIcon } from '@gitlab/ui';
export default {
components: {
GlButton,
GlLoadingIcon,
},
props: {
isSaving: {
type: Boolean,
required: true,
},
isInverted: {
type: Boolean,
required: false,
default: false,
},
},
methods: {
openFileUpload() {
this.$refs.fileUpload.click();
},
onFileUploadChange() {
this.$emit('upload', this.$refs.fileUpload.files);
},
},
};
</script>
<template>
<div>
<gl-button
:disabled="isSaving"
:class="{
'btn-inverted': isInverted,
}"
variant="primary"
@click="openFileUpload"
>
{{ s__('DesignManagement|Upload designs') }}
<gl-loading-icon v-if="isSaving" inline class="ml-1" />
</gl-button>
<input
ref="fileUpload"
type="file"
name="design_file"
accept="image/*"
class="hide"
multiple
@change="onFileUploadChange"
/>
</div>
</template>
<script>
import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import UploadButton from './button.vue';
export default {
components: {
GlButton,
GlLoadingIcon,
UploadButton,
},
props: {
isSaving: {
......@@ -17,11 +16,8 @@ export default {
},
},
methods: {
openFileUpload() {
this.$refs.fileUpload.click();
},
onFileUploadChange() {
this.$emit('upload', this.$refs.fileUpload.files);
onFileUploadChange(files) {
this.$emit('upload', files);
},
},
};
......@@ -30,24 +26,11 @@ export default {
<template>
<header class="row-content-block border-top-0 p-2 d-flex">
<div>
<gl-button
<upload-button
v-if="canUploadDesign"
:disabled="isSaving"
variant="primary"
class="btn-inverted"
@click="openFileUpload"
>
{{ s__('DesignManagement|Upload designs') }}
<gl-loading-icon v-if="isSaving" inline class="ml-1" />
</gl-button>
<input
ref="fileUpload"
type="file"
name="design_file"
accept="image/*"
class="hide"
multiple
@change="onFileUploadChange"
:is-saving="isSaving"
:is-inverted="true"
@upload="onFileUploadChange"
/>
</div>
</header>
......
......@@ -4,6 +4,7 @@ import createFlash from '~/flash';
import { s__ } from '~/locale';
import DesignList from '../components/list/index.vue';
import UploadForm from '../components/upload/form.vue';
import EmptyState from '../components/empty_state.vue';
import allDesignsQuery from '../queries/allDesigns.graphql';
import uploadDesignQuery from '../queries/uploadDesign.graphql';
import appDataQuery from '../queries/appData.graphql';
......@@ -14,6 +15,7 @@ export default {
GlLoadingIcon,
DesignList,
UploadForm,
EmptyState,
},
apollo: {
appData: {
......@@ -44,7 +46,9 @@ export default {
data() {
return {
designs: [],
permissions: {},
permissions: {
createDesign: false,
},
error: false,
isSaving: false,
projectPath: '',
......@@ -53,11 +57,17 @@ export default {
},
computed: {
isLoading() {
return this.$apollo.queries.designs.loading && this.$apollo.queries.permissions.loading;
return this.$apollo.queries.designs.loading || this.$apollo.queries.permissions.loading;
},
canCreateDesign() {
return this.permissions.createDesign;
},
showUploadForm() {
return this.canCreateDesign && this.hasDesigns;
},
hasDesigns() {
return this.designs.length > 0;
},
},
methods: {
onUploadDesign(files) {
......@@ -110,7 +120,7 @@ export default {
<template>
<div>
<upload-form
v-if="canCreateDesign"
v-if="showUploadForm"
:can-upload-design="canCreateDesign"
:is-saving="isSaving"
@upload="onUploadDesign"
......@@ -120,8 +130,13 @@ export default {
<div v-else-if="error" class="alert alert-danger">
{{ __('An error occurred while loading designs. Please try again.') }}
</div>
<design-list v-else-if="designs.length" :designs="designs" />
<div v-else>{{ __('No designs found.') }}</div>
<design-list v-else-if="hasDesigns" :designs="designs" />
<empty-state
v-else
:can-upload-design="canCreateDesign"
:is-saving="isSaving"
@upload="onUploadDesign"
/>
</div>
<router-view />
</div>
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Design management upload button component renders inverted upload design button 1`] = `
<div>
<glbutton-stub
class="btn-inverted"
variant="primary"
>
Upload designs
<!---->
</glbutton-stub>
<input
accept="image/*"
class="hide"
multiple="multiple"
name="design_file"
type="file"
/>
</div>
`;
exports[`Design management upload button component renders loading icon 1`] = `
<div>
<glbutton-stub
class=""
disabled="true"
variant="primary"
>
Upload designs
<glloadingicon-stub
class="ml-1"
color="orange"
inline="true"
label="Loading"
size="sm"
/>
</glbutton-stub>
<input
accept="image/*"
class="hide"
multiple="multiple"
name="design_file"
type="file"
/>
</div>
`;
exports[`Design management upload button component renders upload design button 1`] = `
<div>
<glbutton-stub
class=""
variant="primary"
>
Upload designs
<!---->
</glbutton-stub>
<input
accept="image/*"
class="hide"
multiple="multiple"
name="design_file"
type="file"
/>
</div>
`;
......@@ -6,47 +6,6 @@ exports[`Design management upload form component hides button if cant upload 1`]
>
<div>
<!---->
<input
accept="image/*"
class="hide"
multiple="multiple"
name="design_file"
type="file"
/>
</div>
</header>
`;
exports[`Design management upload form component renders loading icon 1`] = `
<header
class="row-content-block border-top-0 p-2 d-flex"
>
<div>
<glbutton-stub
class="btn-inverted"
disabled="true"
variant="primary"
>
Upload designs
<glloadingicon-stub
class="ml-1"
color="orange"
inline="true"
label="Loading"
size="sm"
/>
</glbutton-stub>
<input
accept="image/*"
class="hide"
multiple="multiple"
name="design_file"
type="file"
/>
</div>
</header>
`;
......@@ -56,22 +15,8 @@ exports[`Design management upload form component renders upload design button 1`
class="row-content-block border-top-0 p-2 d-flex"
>
<div>
<glbutton-stub
class="btn-inverted"
variant="primary"
>
Upload designs
<!---->
</glbutton-stub>
<input
accept="image/*"
class="hide"
multiple="multiple"
name="design_file"
type="file"
<uploadbutton-stub
isinverted="true"
/>
</div>
</header>
......
import { shallowMount } from '@vue/test-utils';
import UploadButton from 'ee/design_management/components/upload/button.vue';
describe('Design management upload button component', () => {
let vm;
function createComponent(isSaving = false, isInverted = false) {
vm = shallowMount(UploadButton, {
propsData: {
isSaving,
isInverted,
},
});
}
afterEach(() => {
vm.destroy();
});
it('renders upload design button', () => {
createComponent();
expect(vm.element).toMatchSnapshot();
});
it('renders inverted upload design button', () => {
createComponent(false, true);
expect(vm.element).toMatchSnapshot();
});
it('renders loading icon', () => {
createComponent(true);
expect(vm.element).toMatchSnapshot();
});
describe('onFileUploadChange', () => {
it('emits upload event', () => {
createComponent();
jest.spyOn(vm.find({ ref: 'fileUpload' }).element, 'files', 'get').mockReturnValue('test');
vm.vm.onFileUploadChange('test');
expect(vm.emitted().upload[0]).toEqual(['test']);
});
});
describe('openFileUpload', () => {
it('triggers click on input', () => {
createComponent();
const clickSpy = jest.spyOn(vm.find({ ref: 'fileUpload' }).element, 'click');
vm.vm.openFileUpload();
expect(clickSpy).toHaveBeenCalled();
});
});
});
......@@ -13,14 +13,12 @@ describe('Design management upload form component', () => {
});
}
it('renders upload design button', () => {
createComponent();
expect(vm.element).toMatchSnapshot();
afterEach(() => {
vm.destroy();
});
it('renders loading icon', () => {
createComponent(true);
it('renders upload design button', () => {
createComponent();
expect(vm.element).toMatchSnapshot();
});
......@@ -35,23 +33,9 @@ describe('Design management upload form component', () => {
it('emits upload event', () => {
createComponent();
jest.spyOn(vm.find({ ref: 'fileUpload' }).element, 'files', 'get').mockReturnValue('test');
vm.vm.onFileUploadChange();
vm.vm.onFileUploadChange('test');
expect(vm.emitted().upload[0]).toEqual(['test']);
});
});
describe('openFileUpload', () => {
it('triggers click on input', () => {
createComponent();
const clickSpy = jest.spyOn(vm.find({ ref: 'fileUpload' }).element, 'click');
vm.vm.openFileUpload();
expect(clickSpy).toHaveBeenCalled();
});
});
});
......@@ -20,16 +20,14 @@ exports[`Design management index page designs renders designs list 1`] = `
exports[`Design management index page designs renders empty text 1`] = `
<div>
<uploadform-stub
canuploaddesign="true"
/>
<!---->
<div
class="mt-4"
>
<div>
No designs found.
</div>
<emptystate-stub
canuploaddesign="true"
/>
</div>
<router-view-stub />
......@@ -38,9 +36,7 @@ exports[`Design management index page designs renders empty text 1`] = `
exports[`Design management index page designs renders error 1`] = `
<div>
<uploadform-stub
canuploaddesign="true"
/>
<!---->
<div
class="mt-4"
......@@ -60,9 +56,7 @@ exports[`Design management index page designs renders error 1`] = `
exports[`Design management index page designs renders loading icon 1`] = `
<div>
<uploadform-stub
canuploaddesign="true"
/>
<!---->
<div
class="mt-4"
......
import { shallowMount } from '@vue/test-utils';
import Index from 'ee/design_management/pages/index.vue';
import UploadForm from 'ee/design_management/components/upload/form.vue';
import uploadDesignQuery from 'ee/design_management/queries/uploadDesign.graphql';
describe('Design management index page', () => {
let mutate;
let vm;
function createComponent(loading = false) {
function createComponent(loading = false, designs = []) {
mutate = jest.fn(() => Promise.resolve());
const $apollo = {
queries: {
......@@ -26,12 +27,17 @@ describe('Design management index page', () => {
});
vm.setData({
designs,
permissions: {
createDesign: true,
},
});
}
afterEach(() => {
vm.destroy();
});
describe('designs', () => {
it('renders loading icon', () => {
createComponent(true);
......@@ -54,11 +60,23 @@ describe('Design management index page', () => {
});
it('renders designs list', () => {
createComponent(false, ['design']);
expect(vm.element).toMatchSnapshot();
});
});
describe('upload form', () => {
it('hides upload form', () => {
createComponent();
vm.setData({ designs: ['design'] });
expect(vm.find(UploadForm).exists()).toBe(false);
});
expect(vm.element).toMatchSnapshot();
it('renders upload form', () => {
createComponent(false, ['design']);
expect(vm.find(UploadForm).exists()).toBe(true);
});
});
......
......@@ -3667,6 +3667,12 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
msgid "DesignManagement|The one place for your designs"
msgstr ""
msgid "DesignManagement|Upload and view the latest designs for this issue. Consistent and easy to find, so everyone is up to date."
msgstr ""
msgid "DesignManagement|Upload designs"
msgstr ""
......@@ -7372,9 +7378,6 @@ msgstr ""
msgid "No credit card required."
msgstr ""
msgid "No designs found."
msgstr ""
msgid "No details available"
msgstr ""
......
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