Commit 23f058eb authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '36925-design-view-flashes-warnings-are-not-visible' into 'master'

Add error flashes to Design view

See merge request gitlab-org/gitlab!20889
parents cd688518 ef359df4
<script> <script>
import { ApolloMutation } from 'vue-apollo'; import { ApolloMutation } from 'vue-apollo';
import createFlash from '~/flash';
import projectQuery from '../graphql/queries/project.query.graphql'; import projectQuery from '../graphql/queries/project.query.graphql';
import destroyDesignMutation from '../graphql/mutations/destroyDesign.mutation.graphql'; import destroyDesignMutation from '../graphql/mutations/destroyDesign.mutation.graphql';
import { updateStoreAfterDesignsDelete } from '../utils/cache_update'; import { updateStoreAfterDesignsDelete } from '../utils/cache_update';
import { designDeletionError } from '../utils/error_messages';
export default { export default {
components: { components: {
...@@ -33,10 +31,6 @@ export default { ...@@ -33,10 +31,6 @@ export default {
}, },
}, },
methods: { methods: {
onError() {
const errorMessage = designDeletionError(this.filenames.length === 1);
createFlash(errorMessage);
},
updateStoreAfterDelete( updateStoreAfterDelete(
store, store,
{ {
...@@ -65,7 +59,6 @@ export default { ...@@ -65,7 +59,6 @@ export default {
iid, iid,
}" }"
:update="updateStoreAfterDelete" :update="updateStoreAfterDelete"
@error="onError"
v-on="$listeners" v-on="$listeners"
> >
<slot v-bind="{ mutate, loading, error }"></slot> <slot v-bind="{ mutate, loading, error }"></slot>
......
<script> <script>
import { ApolloMutation } from 'vue-apollo'; import { ApolloMutation } from 'vue-apollo';
import createFlash from '~/flash';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue'; import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
import allVersionsMixin from '../../mixins/all_versions'; import allVersionsMixin from '../../mixins/all_versions';
import createNoteMutation from '../../graphql/mutations/createNote.mutation.graphql'; import createNoteMutation from '../../graphql/mutations/createNote.mutation.graphql';
...@@ -8,7 +7,6 @@ import getDesignQuery from '../../graphql/queries/getDesign.query.graphql'; ...@@ -8,7 +7,6 @@ import getDesignQuery from '../../graphql/queries/getDesign.query.graphql';
import DesignNote from './design_note.vue'; import DesignNote from './design_note.vue';
import DesignReplyForm from './design_reply_form.vue'; import DesignReplyForm from './design_reply_form.vue';
import { updateStoreAfterAddDiscussionComment } from '../../utils/cache_update'; import { updateStoreAfterAddDiscussionComment } from '../../utils/cache_update';
import { ADD_DISCUSSION_COMMENT_ERROR } from '../../utils/error_messages';
export default { export default {
components: { components: {
...@@ -83,8 +81,8 @@ export default { ...@@ -83,8 +81,8 @@ export default {
this.discussionComment = ''; this.discussionComment = '';
this.hideForm(); this.hideForm();
}, },
onError() { onError(err) {
createFlash(ADD_DISCUSSION_COMMENT_ERROR); this.$emit('error', err);
}, },
hideForm() { hideForm() {
this.isFormRendered = false; this.isFormRendered = false;
......
<script> <script>
import { ApolloMutation } from 'vue-apollo'; import { ApolloMutation } from 'vue-apollo';
import Mousetrap from 'mousetrap'; import Mousetrap from 'mousetrap';
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { s__ } from '~/locale';
import allVersionsMixin from '../../mixins/all_versions'; import allVersionsMixin from '../../mixins/all_versions';
import Toolbar from '../../components/toolbar/index.vue'; import Toolbar from '../../components/toolbar/index.vue';
import DesignImage from '../../components/image.vue'; import DesignImage from '../../components/image.vue';
...@@ -16,7 +15,12 @@ import appDataQuery from '../../graphql/queries/appData.query.graphql'; ...@@ -16,7 +15,12 @@ import appDataQuery from '../../graphql/queries/appData.query.graphql';
import createImageDiffNoteMutation from '../../graphql/mutations/createImageDiffNote.mutation.graphql'; import createImageDiffNoteMutation from '../../graphql/mutations/createImageDiffNote.mutation.graphql';
import { extractDiscussions, extractDesign } from '../../utils/design_management_utils'; import { extractDiscussions, extractDesign } from '../../utils/design_management_utils';
import { updateStoreAfterAddImageDiffNote } from '../../utils/cache_update'; import { updateStoreAfterAddImageDiffNote } from '../../utils/cache_update';
import { ADD_DISCUSSION_COMMENT_ERROR } from '../../utils/error_messages'; import {
ADD_DISCUSSION_COMMENT_ERROR,
DESIGN_NOT_FOUND_ERROR,
DESIGN_NOT_EXIST_ERROR,
designDeletionError,
} from '../../utils/error_messages';
export default { export default {
components: { components: {
...@@ -28,6 +32,7 @@ export default { ...@@ -28,6 +32,7 @@ export default {
Toolbar, Toolbar,
DesignReplyForm, DesignReplyForm,
GlLoadingIcon, GlLoadingIcon,
GlAlert,
}, },
mixins: [allVersionsMixin], mixins: [allVersionsMixin],
props: { props: {
...@@ -47,6 +52,7 @@ export default { ...@@ -47,6 +52,7 @@ export default {
}, },
projectPath: '', projectPath: '',
issueId: '', issueId: '',
errorMessage: '',
}; };
}, },
apollo: { apollo: {
...@@ -67,14 +73,15 @@ export default { ...@@ -67,14 +73,15 @@ export default {
update: data => extractDesign(data), update: data => extractDesign(data),
result({ data }) { result({ data }) {
if (!data) { if (!data) {
createFlash(s__('DesignManagement|Could not find design, please try again.')); this.onQueryError(DESIGN_NOT_FOUND_ERROR);
this.$router.push({ name: 'designs' });
} }
if (this.$route.query.version && !this.hasValidVersion) { if (this.$route.query.version && !this.hasValidVersion) {
createFlash(s__('DesignManagement|Requested design version does not exist')); this.onQueryError(DESIGN_NOT_EXIST_ERROR);
this.$router.push({ name: 'designs' });
} }
}, },
error() {
this.onQueryError(DESIGN_NOT_FOUND_ERROR);
},
}, },
}, },
computed: { computed: {
...@@ -144,8 +151,18 @@ export default { ...@@ -144,8 +151,18 @@ export default {
this.designVariables, this.designVariables,
); );
}, },
onMutationError(e) { onQueryError(message) {
createFlash(ADD_DISCUSSION_COMMENT_ERROR); // because we redirect user to /designs (the issue page),
// we want to create these flashes on the issue page
createFlash(message);
this.$router.push({ name: 'designs' });
},
onDiffNoteError(e) {
this.errorMessage = ADD_DISCUSSION_COMMENT_ERROR;
throw e;
},
onDesignDeleteError(e) {
this.errorMessage = designDeletionError({ singular: true });
throw e; throw e;
}, },
openCommentForm(position) { openCommentForm(position) {
...@@ -194,7 +211,7 @@ export default { ...@@ -194,7 +211,7 @@ export default {
:project-path="projectPath" :project-path="projectPath"
:iid="issueIid" :iid="issueIid"
@done="$router.push({ name: 'designs' })" @done="$router.push({ name: 'designs' })"
@error="$router.push({ name: 'designs' })" @error="onDesignDeleteError"
> >
<template v-slot="{ mutate, loading, error }"> <template v-slot="{ mutate, loading, error }">
<toolbar <toolbar
...@@ -207,6 +224,11 @@ export default { ...@@ -207,6 +224,11 @@ export default {
</template> </template>
</design-destroyer> </design-destroyer>
<div class="d-flex flex-column h-100 mh-100 position-relative"> <div class="d-flex flex-column h-100 mh-100 position-relative">
<div class="p-3">
<gl-alert v-if="errorMessage" variant="danger" @dismiss="errorMessage = null">
{{ errorMessage }}
</gl-alert>
</div>
<design-image <design-image
:image="design.image" :image="design.image"
:name="design.filename" :name="design.filename"
...@@ -230,6 +252,7 @@ export default { ...@@ -230,6 +252,7 @@ export default {
:noteable-id="design.id" :noteable-id="design.id"
:discussion-index="index + 1" :discussion-index="index + 1"
:markdown-preview-path="markdownPreviewPath" :markdown-preview-path="markdownPreviewPath"
@error="onDiffNoteError"
/> />
<apollo-mutation <apollo-mutation
v-if="annotationCoordinates" v-if="annotationCoordinates"
...@@ -240,7 +263,7 @@ export default { ...@@ -240,7 +263,7 @@ export default {
}" }"
:update="addImageDiffNoteToStore" :update="addImageDiffNoteToStore"
@done="closeCommentForm" @done="closeCommentForm"
@error="onMutationError" @error="onDiffNoteError"
> >
<design-reply-form <design-reply-form
v-model="comment" v-model="comment"
......
...@@ -11,7 +11,7 @@ import uploadDesignMutation from '../graphql/mutations/uploadDesign.mutation.gra ...@@ -11,7 +11,7 @@ import uploadDesignMutation from '../graphql/mutations/uploadDesign.mutation.gra
import permissionsQuery from '../graphql/queries/permissions.query.graphql'; import permissionsQuery from '../graphql/queries/permissions.query.graphql';
import projectQuery from '../graphql/queries/project.query.graphql'; import projectQuery from '../graphql/queries/project.query.graphql';
import allDesignsMixin from '../mixins/all_designs'; import allDesignsMixin from '../mixins/all_designs';
import { UPLOAD_DESIGN_ERROR } from '../utils/error_messages'; import { UPLOAD_DESIGN_ERROR, designDeletionError } from '../utils/error_messages';
import { updateStoreAfterUploadDesign } from '../utils/cache_update'; import { updateStoreAfterUploadDesign } from '../utils/cache_update';
import { designUploadOptimisticResponse } from '../utils/design_management_utils'; import { designUploadOptimisticResponse } from '../utils/design_management_utils';
...@@ -178,6 +178,10 @@ export default { ...@@ -178,6 +178,10 @@ export default {
this.selectedDesigns = []; this.selectedDesigns = [];
if (this.$route.query.version) this.$router.push({ name: 'designs' }); if (this.$route.query.version) this.$router.push({ name: 'designs' });
}, },
onDesignDeleteError() {
const errorMessage = designDeletionError({ singular: this.selectedDesigns.length === 1 });
createFlash(errorMessage);
},
}, },
beforeRouteUpdate(to, from, next) { beforeRouteUpdate(to, from, next) {
this.selectedDesigns = []; this.selectedDesigns = [];
...@@ -205,6 +209,7 @@ export default { ...@@ -205,6 +209,7 @@ export default {
:project-path="projectPath" :project-path="projectPath"
:iid="issueIid" :iid="issueIid"
@done="onDesignDelete" @done="onDesignDelete"
@error="onDesignDeleteError"
> >
<delete-button <delete-button
v-if="isLatestVersion" v-if="isLatestVersion"
......
...@@ -179,7 +179,7 @@ const onError = (data, message) => { ...@@ -179,7 +179,7 @@ const onError = (data, message) => {
*/ */
export const updateStoreAfterDesignsDelete = (store, data, query, designs) => { export const updateStoreAfterDesignsDelete = (store, data, query, designs) => {
if (data.errors) { if (data.errors) {
onError(data, designDeletionError(designs.length === 1)); onError(data, designDeletionError({ singular: designs.length === 1 }));
} else { } else {
deleteDesignsFromStore(store, query, designs); deleteDesignsFromStore(store, query, designs);
addNewVersionToStore(store, query, data.version); addNewVersionToStore(store, query, data.version);
......
import { __, s__, sprintf } from '~/locale'; import { __, s__, sprintf } from '~/locale';
export const designDeletionError = (singular = true) => { export const designDeletionError = ({ singular = true } = {}) => {
const design = singular ? __('a design') : __('designs'); const design = singular ? __('a design') : __('designs');
return sprintf(s__('DesignManagement|We could not delete %{design}. Please try again.'), { return sprintf(s__('Could not delete %{design}. Please try again.'), {
design, design,
}); });
}; };
export const ADD_DISCUSSION_COMMENT_ERROR = s__( export const ADD_DISCUSSION_COMMENT_ERROR = s__(
'DesignManagement|Could not add a new comment. Please try again', 'DesignManagement|Could not add a new comment. Please try again.',
); );
export const ADD_IMAGE_DIFF_NOTE_ERROR = s__( export const ADD_IMAGE_DIFF_NOTE_ERROR = s__(
'DesignManagement|Could not create new discussion. Please try again.', 'DesignManagement|Could not create new discussion. Please try again.',
); );
export const UPLOAD_DESIGN_ERROR = s__( export const UPLOAD_DESIGN_ERROR = s__(
'DesignManagement|Error uploading a new design. Please try again', 'DesignManagement|Error uploading a new design. Please try again.',
); );
export const DESIGN_NOT_FOUND_ERROR = __('Could not find design');
export const DESIGN_NOT_EXIST_ERROR = __('Requested design version does not exist');
---
title: Add error flashes to Design view
merge_request: 20889
author:
type: fixed
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Design management design index page with error GlAlert is rendered in correct position with correct content 1`] = `
<div
class="design-detail fixed-top w-100 position-bottom-0 d-flex justify-content-center flex-column flex-lg-row"
>
<div
class="d-flex overflow-hidden flex-lg-grow-1 flex-column"
>
<designdestroyer-stub
filenames="test.jpg"
iid="1"
projectpath=""
/>
<div
class="d-flex flex-column h-100 mh-100 position-relative"
>
<div
class="p-3"
>
<glalert-stub
dismissible="true"
dismisslabel="Dismiss"
primarybuttonlink=""
primarybuttontext=""
secondarybuttonlink=""
secondarybuttontext=""
title=""
variant="danger"
>
woops
</glalert-stub>
</div>
<designimage-stub
image="test.jpg"
name="test.jpg"
/>
<designoverlay-stub
notes=""
position="[object Object]"
/>
</div>
</div>
<div
class="image-notes"
>
<h2
class="new-discussion-disclaimer m-0"
>
Click the image where you'd like to start a new discussion
</h2>
</div>
</div>
`;
exports[`Design management design index page renders design index 1`] = ` exports[`Design management design index page renders design index 1`] = `
<div <div
class="design-detail fixed-top w-100 position-bottom-0 d-flex justify-content-center flex-column flex-lg-row" class="design-detail fixed-top w-100 position-bottom-0 d-flex justify-content-center flex-column flex-lg-row"
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlAlert } from '@gitlab/ui';
import { ApolloMutation } from 'vue-apollo'; import { ApolloMutation } from 'vue-apollo';
import DesignIndex from 'ee/design_management/pages/design/index.vue'; import DesignIndex from 'ee/design_management/pages/design/index.vue';
import DesignDiscussion from 'ee/design_management/components/design_notes/design_discussion.vue'; import DesignDiscussion from 'ee/design_management/components/design_notes/design_discussion.vue';
...@@ -91,6 +92,7 @@ describe('Design management design index page', () => { ...@@ -91,6 +92,7 @@ describe('Design management design index page', () => {
}); });
expect(wrapper.element).toMatchSnapshot(); expect(wrapper.element).toMatchSnapshot();
expect(wrapper.find(GlAlert).exists()).toBe(false);
}); });
describe('when has no discussions', () => { describe('when has no discussions', () => {
...@@ -175,4 +177,23 @@ describe('Design management design index page', () => { ...@@ -175,4 +177,23 @@ describe('Design management design index page', () => {
expect(findDiscussionForm().exists()).toBe(false); expect(findDiscussionForm().exists()).toBe(false);
}); });
}); });
describe('with error', () => {
beforeEach(() => {
setDesign();
wrapper.setData({
design: {
...design,
discussions: {
edges: [],
},
},
errorMessage: 'woops',
});
});
it('GlAlert is rendered in correct position with correct content', () => {
expect(wrapper.element).toMatchSnapshot();
});
});
}); });
...@@ -5045,12 +5045,18 @@ msgstr "" ...@@ -5045,12 +5045,18 @@ msgstr ""
msgid "Could not create project" msgid "Could not create project"
msgstr "" msgstr ""
msgid "Could not delete %{design}. Please try again."
msgstr ""
msgid "Could not delete chat nickname %{chat_name}." msgid "Could not delete chat nickname %{chat_name}."
msgstr "" msgstr ""
msgid "Could not fetch projects" msgid "Could not fetch projects"
msgstr "" msgstr ""
msgid "Could not find design"
msgstr ""
msgid "Could not remove the trigger." msgid "Could not remove the trigger."
msgstr "" msgstr ""
...@@ -6062,15 +6068,12 @@ msgstr "" ...@@ -6062,15 +6068,12 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?" msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr "" msgstr ""
msgid "DesignManagement|Could not add a new comment. Please try again" msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr "" msgstr ""
msgid "DesignManagement|Could not create new discussion. Please try again." msgid "DesignManagement|Could not create new discussion. Please try again."
msgstr "" msgstr ""
msgid "DesignManagement|Could not find design, please try again."
msgstr ""
msgid "DesignManagement|Delete" msgid "DesignManagement|Delete"
msgstr "" msgstr ""
...@@ -6083,7 +6086,7 @@ msgstr "" ...@@ -6083,7 +6086,7 @@ msgstr ""
msgid "DesignManagement|Deselect all" msgid "DesignManagement|Deselect all"
msgstr "" msgstr ""
msgid "DesignManagement|Error uploading a new design. Please try again" msgid "DesignManagement|Error uploading a new design. Please try again."
msgstr "" msgstr ""
msgid "DesignManagement|Go back to designs" msgid "DesignManagement|Go back to designs"
...@@ -6095,9 +6098,6 @@ msgstr "" ...@@ -6095,9 +6098,6 @@ msgstr ""
msgid "DesignManagement|Go to previous design" msgid "DesignManagement|Go to previous design"
msgstr "" msgstr ""
msgid "DesignManagement|Requested design version does not exist"
msgstr ""
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead" msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr "" msgstr ""
...@@ -6113,9 +6113,6 @@ msgstr "" ...@@ -6113,9 +6113,6 @@ msgstr ""
msgid "DesignManagement|Upload and view the latest designs for this issue. Consistent and easy to find, so everyone is up to date." msgid "DesignManagement|Upload and view the latest designs for this issue. Consistent and easy to find, so everyone is up to date."
msgstr "" msgstr ""
msgid "DesignManagement|We could not delete %{design}. Please try again."
msgstr ""
msgid "Designs" msgid "Designs"
msgstr "" msgstr ""
...@@ -15237,6 +15234,9 @@ msgstr "" ...@@ -15237,6 +15234,9 @@ msgstr ""
msgid "Requested %{time_ago}" msgid "Requested %{time_ago}"
msgstr "" msgstr ""
msgid "Requested design version does not exist"
msgstr ""
msgid "Requests Profiles" msgid "Requests Profiles"
msgstr "" 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