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>
import { ApolloMutation } from 'vue-apollo';
import createFlash from '~/flash';
import projectQuery from '../graphql/queries/project.query.graphql';
import destroyDesignMutation from '../graphql/mutations/destroyDesign.mutation.graphql';
import { updateStoreAfterDesignsDelete } from '../utils/cache_update';
import { designDeletionError } from '../utils/error_messages';
export default {
components: {
......@@ -33,10 +31,6 @@ export default {
},
},
methods: {
onError() {
const errorMessage = designDeletionError(this.filenames.length === 1);
createFlash(errorMessage);
},
updateStoreAfterDelete(
store,
{
......@@ -65,7 +59,6 @@ export default {
iid,
}"
:update="updateStoreAfterDelete"
@error="onError"
v-on="$listeners"
>
<slot v-bind="{ mutate, loading, error }"></slot>
......
<script>
import { ApolloMutation } from 'vue-apollo';
import createFlash from '~/flash';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
import allVersionsMixin from '../../mixins/all_versions';
import createNoteMutation from '../../graphql/mutations/createNote.mutation.graphql';
......@@ -8,7 +7,6 @@ import getDesignQuery from '../../graphql/queries/getDesign.query.graphql';
import DesignNote from './design_note.vue';
import DesignReplyForm from './design_reply_form.vue';
import { updateStoreAfterAddDiscussionComment } from '../../utils/cache_update';
import { ADD_DISCUSSION_COMMENT_ERROR } from '../../utils/error_messages';
export default {
components: {
......@@ -83,8 +81,8 @@ export default {
this.discussionComment = '';
this.hideForm();
},
onError() {
createFlash(ADD_DISCUSSION_COMMENT_ERROR);
onError(err) {
this.$emit('error', err);
},
hideForm() {
this.isFormRendered = false;
......
<script>
import { ApolloMutation } from 'vue-apollo';
import Mousetrap from 'mousetrap';
import { GlLoadingIcon } from '@gitlab/ui';
import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
import createFlash from '~/flash';
import { s__ } from '~/locale';
import allVersionsMixin from '../../mixins/all_versions';
import Toolbar from '../../components/toolbar/index.vue';
import DesignImage from '../../components/image.vue';
......@@ -16,7 +15,12 @@ import appDataQuery from '../../graphql/queries/appData.query.graphql';
import createImageDiffNoteMutation from '../../graphql/mutations/createImageDiffNote.mutation.graphql';
import { extractDiscussions, extractDesign } from '../../utils/design_management_utils';
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 {
components: {
......@@ -28,6 +32,7 @@ export default {
Toolbar,
DesignReplyForm,
GlLoadingIcon,
GlAlert,
},
mixins: [allVersionsMixin],
props: {
......@@ -47,6 +52,7 @@ export default {
},
projectPath: '',
issueId: '',
errorMessage: '',
};
},
apollo: {
......@@ -67,14 +73,15 @@ export default {
update: data => extractDesign(data),
result({ data }) {
if (!data) {
createFlash(s__('DesignManagement|Could not find design, please try again.'));
this.$router.push({ name: 'designs' });
this.onQueryError(DESIGN_NOT_FOUND_ERROR);
}
if (this.$route.query.version && !this.hasValidVersion) {
createFlash(s__('DesignManagement|Requested design version does not exist'));
this.$router.push({ name: 'designs' });
this.onQueryError(DESIGN_NOT_EXIST_ERROR);
}
},
error() {
this.onQueryError(DESIGN_NOT_FOUND_ERROR);
},
},
},
computed: {
......@@ -144,8 +151,18 @@ export default {
this.designVariables,
);
},
onMutationError(e) {
createFlash(ADD_DISCUSSION_COMMENT_ERROR);
onQueryError(message) {
// 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;
},
openCommentForm(position) {
......@@ -194,7 +211,7 @@ export default {
:project-path="projectPath"
:iid="issueIid"
@done="$router.push({ name: 'designs' })"
@error="$router.push({ name: 'designs' })"
@error="onDesignDeleteError"
>
<template v-slot="{ mutate, loading, error }">
<toolbar
......@@ -207,6 +224,11 @@ export default {
</template>
</design-destroyer>
<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
:image="design.image"
:name="design.filename"
......@@ -230,6 +252,7 @@ export default {
:noteable-id="design.id"
:discussion-index="index + 1"
:markdown-preview-path="markdownPreviewPath"
@error="onDiffNoteError"
/>
<apollo-mutation
v-if="annotationCoordinates"
......@@ -240,7 +263,7 @@ export default {
}"
:update="addImageDiffNoteToStore"
@done="closeCommentForm"
@error="onMutationError"
@error="onDiffNoteError"
>
<design-reply-form
v-model="comment"
......
......@@ -11,7 +11,7 @@ import uploadDesignMutation from '../graphql/mutations/uploadDesign.mutation.gra
import permissionsQuery from '../graphql/queries/permissions.query.graphql';
import projectQuery from '../graphql/queries/project.query.graphql';
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 { designUploadOptimisticResponse } from '../utils/design_management_utils';
......@@ -178,6 +178,10 @@ export default {
this.selectedDesigns = [];
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) {
this.selectedDesigns = [];
......@@ -205,6 +209,7 @@ export default {
:project-path="projectPath"
:iid="issueIid"
@done="onDesignDelete"
@error="onDesignDeleteError"
>
<delete-button
v-if="isLatestVersion"
......
......@@ -179,7 +179,7 @@ const onError = (data, message) => {
*/
export const updateStoreAfterDesignsDelete = (store, data, query, designs) => {
if (data.errors) {
onError(data, designDeletionError(designs.length === 1));
onError(data, designDeletionError({ singular: designs.length === 1 }));
} else {
deleteDesignsFromStore(store, query, designs);
addNewVersionToStore(store, query, data.version);
......
import { __, s__, sprintf } from '~/locale';
export const designDeletionError = (singular = true) => {
export const designDeletionError = ({ singular = true } = {}) => {
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,
});
};
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__(
'DesignManagement|Could not create new discussion. Please try again.',
);
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
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`] = `
<div
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 { GlAlert } from '@gitlab/ui';
import { ApolloMutation } from 'vue-apollo';
import DesignIndex from 'ee/design_management/pages/design/index.vue';
import DesignDiscussion from 'ee/design_management/components/design_notes/design_discussion.vue';
......@@ -91,6 +92,7 @@ describe('Design management design index page', () => {
});
expect(wrapper.element).toMatchSnapshot();
expect(wrapper.find(GlAlert).exists()).toBe(false);
});
describe('when has no discussions', () => {
......@@ -175,4 +177,23 @@ describe('Design management design index page', () => {
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 ""
msgid "Could not create project"
msgstr ""
msgid "Could not delete %{design}. Please try again."
msgstr ""
msgid "Could not delete chat nickname %{chat_name}."
msgstr ""
msgid "Could not fetch projects"
msgstr ""
msgid "Could not find design"
msgstr ""
msgid "Could not remove the trigger."
msgstr ""
......@@ -6062,15 +6068,12 @@ msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
msgid "DesignManagement|Could not add a new comment. Please try again"
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
msgid "DesignManagement|Could not create new discussion. Please try again."
msgstr ""
msgid "DesignManagement|Could not find design, please try again."
msgstr ""
msgid "DesignManagement|Delete"
msgstr ""
......@@ -6083,7 +6086,7 @@ msgstr ""
msgid "DesignManagement|Deselect all"
msgstr ""
msgid "DesignManagement|Error uploading a new design. Please try again"
msgid "DesignManagement|Error uploading a new design. Please try again."
msgstr ""
msgid "DesignManagement|Go back to designs"
......@@ -6095,9 +6098,6 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgstr ""
msgid "DesignManagement|Requested design version does not exist"
msgstr ""
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
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."
msgstr ""
msgid "DesignManagement|We could not delete %{design}. Please try again."
msgstr ""
msgid "Designs"
msgstr ""
......@@ -15237,6 +15234,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
msgid "Requested design version does not exist"
msgstr ""
msgid "Requests Profiles"
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