Commit 574f3bce authored by Phil Hughes's avatar Phil Hughes

Merge branch '222364-update-banner-create-issue' into 'master'

Improve error message when creating issue

See merge request gitlab-org/gitlab!40525
parents 207688e5 a167b495
......@@ -13,6 +13,8 @@ function createMainApp() {
createIssueUrl: vulnerability.create_issue_url,
projectFingerprint: vulnerability.project_fingerprint,
vulnerabilityId: vulnerability.id,
issueTrackingHelpPath: vulnerability.issueTrackingHelpPath,
permissionsHelpPath: vulnerability.permissionsHelpPath,
},
render: h =>
......
<script>
import axios from 'axios';
import { GlButton } from '@gitlab/ui';
import { GlButton, GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
import RelatedIssuesStore from '~/related_issues/stores/related_issues_store';
import RelatedIssuesBlock from '~/related_issues/components/related_issues_block.vue';
import { issuableTypesMap, PathIdSeparator } from '~/related_issues/constants';
......@@ -15,6 +15,9 @@ export default {
components: {
RelatedIssuesBlock,
GlButton,
GlAlert,
GlSprintf,
GlLink,
},
props: {
endpoint: {
......@@ -45,6 +48,7 @@ export default {
isFetching: false,
isSubmitting: false,
isFormVisible: false,
errorCreatingIssue: false,
inputValue: '',
};
},
......@@ -69,6 +73,12 @@ export default {
reportType: {
type: String,
},
issueTrackingHelpPath: {
type: String,
},
permissionsHelpPath: {
type: String,
},
},
created() {
this.fetchRelatedIssues();
......@@ -76,6 +86,7 @@ export default {
methods: {
createIssue() {
this.isProcessingAction = true;
this.errorCreatingIssue = false;
return axios
.post(this.createIssueUrl, {
......@@ -95,9 +106,7 @@ export default {
})
.catch(() => {
this.isProcessingAction = false;
createFlash(
s__('VulnerabilityManagement|Something went wrong, could not create an issue.'),
);
this.errorCreatingIssue = true;
});
},
toggleFormVisibility() {
......@@ -204,44 +213,76 @@ export default {
autoCompleteSources: gl?.GfmAutoComplete?.dataSources,
issuableType: issuableTypesMap.ISSUE,
pathIdSeparator: PathIdSeparator.Issue,
i18n: {
relatedIssues: __('Related issues'),
createIssue: __('Create issue'),
createIssueErrorTitle: __('Could not create issue'),
createIssueErrorBody: s__(
'SecurityReports|Ensure that %{trackingStart}issue tracking%{trackingEnd} is enabled for this project and you have %{permissionsStart}permission to create new issues%{permissionsEnd}.',
),
},
};
</script>
<template>
<related-issues-block
:help-path="helpPath"
:is-fetching="isFetching"
:is-submitting="isSubmitting"
:related-issues="state.relatedIssues"
:can-admin="canModifyRelatedIssues"
:pending-references="state.pendingReferences"
:is-form-visible="isFormVisible"
:input-value="inputValue"
:auto-complete-sources="$options.autoCompleteSources"
:issuable-type="$options.issuableType"
:path-id-separator="$options.pathIdSeparator"
:show-categorized-issues="false"
@toggleAddRelatedIssuesForm="toggleFormVisibility"
@addIssuableFormInput="addPendingReferences"
@addIssuableFormBlur="processAllReferences"
@addIssuableFormSubmit="addRelatedIssue"
@addIssuableFormCancel="resetForm"
@pendingIssuableRemoveRequest="removePendingReference"
@relatedIssueRemoveRequest="removeRelatedIssue"
>
<template #headerText>
{{ __('Related issues') }}
</template>
<template v-if="!isIssueAlreadyCreated && !isFetching" #headerActions>
<gl-button
ref="createIssue"
variant="success"
category="secondary"
:loading="isProcessingAction"
@click="createIssue"
>
{{ __('Create issue') }}
</gl-button>
</template>
</related-issues-block>
<div>
<gl-alert
v-if="errorCreatingIssue"
variant="danger"
class="gl-mt-5"
@dismiss="errorCreatingIssue = false"
>
<p class="gl-font-weight-bold gl-mb-2">{{ $options.i18n.createIssueErrorTitle }}</p>
<p class="gl-mb-0">
<gl-sprintf :message="$options.i18n.createIssueErrorBody">
<template #tracking="{ content }">
<gl-link class="gl-display-inline-block" :href="issueTrackingHelpPath" target="_blank">
{{ content }}
</gl-link>
</template>
<template #permissions="{ content }">
<gl-link class="gl-display-inline-block" :href="permissionsHelpPath" target="_blank">
{{ content }}
</gl-link>
</template>
</gl-sprintf>
</p>
</gl-alert>
<related-issues-block
:help-path="helpPath"
:is-fetching="isFetching"
:is-submitting="isSubmitting"
:related-issues="state.relatedIssues"
:can-admin="canModifyRelatedIssues"
:pending-references="state.pendingReferences"
:is-form-visible="isFormVisible"
:input-value="inputValue"
:auto-complete-sources="$options.autoCompleteSources"
:issuable-type="$options.issuableType"
:path-id-separator="$options.pathIdSeparator"
:show-categorized-issues="false"
@toggleAddRelatedIssuesForm="toggleFormVisibility"
@addIssuableFormInput="addPendingReferences"
@addIssuableFormBlur="processAllReferences"
@addIssuableFormSubmit="addRelatedIssue"
@addIssuableFormCancel="resetForm"
@pendingIssuableRemoveRequest="removePendingReference"
@relatedIssueRemoveRequest="removeRelatedIssue"
>
<template #headerText>
{{ $options.i18n.relatedIssues }}
</template>
<template v-if="!isIssueAlreadyCreated && !isFetching" #headerActions>
<gl-button
ref="createIssue"
variant="success"
category="secondary"
:loading="isProcessingAction"
@click="createIssue"
>
{{ $options.i18n.createIssue }}
</gl-button>
</template>
</related-issues-block>
</div>
</template>
......@@ -18,7 +18,9 @@ module VulnerabilitiesHelper
vulnerability_feedback_help_path: help_page_path('user/application_security/index', anchor: 'interacting-with-the-vulnerabilities'),
related_issues_help_path: help_page_path('user/application_security/index', anchor: 'managing-related-issues-for-a-vulnerability'),
pipeline: vulnerability_pipeline_data(pipeline),
can_modify_related_issues: current_user.can?(:admin_vulnerability_issue_link, vulnerability)
can_modify_related_issues: current_user.can?(:admin_vulnerability_issue_link, vulnerability),
issue_tracking_help_path: help_page_path('user/project/settings', anchor: 'sharing-and-permissions'),
permissions_help_path: help_page_path('user/permissions', anchor: 'project-members-permissions')
}
result.merge(vulnerability_data(vulnerability), vulnerability_finding_data(vulnerability))
......
---
title: Improve error message when creating issue fails
merge_request: 40525
author:
type: changed
import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import RelatedIssues from 'ee/vulnerabilities/components/related_issues.vue';
......@@ -27,6 +28,8 @@ describe('Vulnerability related issues component', () => {
const vulnerabilityId = 5131;
const createIssueUrl = '/create/issue';
const projectFingerprint = 'project-fingerprint';
const issueTrackingHelpPath = '/help/issue/tracking';
const permissionsHelpPath = '/help/permissions';
const reportType = 'vulnerability';
const issue1 = { id: 3, vulnerabilityLinkId: 987 };
const issue2 = { id: 25, vulnerabilityLinkId: 876 };
......@@ -40,6 +43,8 @@ describe('Vulnerability related issues component', () => {
projectFingerprint,
createIssueUrl,
reportType,
issueTrackingHelpPath,
permissionsHelpPath,
},
...opts,
});
......@@ -54,6 +59,7 @@ describe('Vulnerability related issues component', () => {
const blockProp = prop => relatedIssuesBlock().props(prop);
const blockEmit = (eventName, data) => relatedIssuesBlock().vm.$emit(eventName, data);
const findCreateIssueButton = () => wrapper.find({ ref: 'createIssue' });
const findAlert = () => wrapper.find(GlAlert);
afterEach(() => {
wrapper.destroy();
......@@ -275,6 +281,13 @@ describe('Vulnerability related issues component', () => {
});
describe('when linked issue is not yet created', () => {
const failCreateIssueAction = async () => {
mockAxios.onPost(createIssueUrl).reply(500);
expect(findAlert().exists()).toBe(false);
findCreateIssueButton().vm.$emit('click');
await waitForPromises();
};
beforeEach(async () => {
mockAxios.onGet(propsData.endpoint).replyOnce(httpStatusCodes.OK, [issue1, issue2]);
createWrapper({}, { stubs: { RelatedIssuesBlock } });
......@@ -313,15 +326,17 @@ describe('Vulnerability related issues component', () => {
});
});
it('shows an error message when issue creation fails', () => {
mockAxios.onPost(createIssueUrl).reply(500);
findCreateIssueButton().vm.$emit('click');
return waitForPromises().then(() => {
expect(mockAxios.history.post).toHaveLength(1);
expect(createFlash).toHaveBeenCalledWith(
'Something went wrong, could not create an issue.',
);
});
it('shows an error message when issue creation fails', async () => {
await failCreateIssueAction();
expect(mockAxios.history.post).toHaveLength(1);
expect(findAlert().exists()).toBe(true);
});
it('dismisses the error message', async () => {
await failCreateIssueAction();
findAlert().vm.$emit('dismiss');
await wrapper.vm.$nextTick();
expect(findAlert().exists()).toBe(false);
});
});
});
......@@ -7021,6 +7021,9 @@ msgstr ""
msgid "Could not create group"
msgstr ""
msgid "Could not create issue"
msgstr ""
msgid "Could not create project"
msgstr ""
......@@ -21867,6 +21870,9 @@ msgstr ""
msgid "SecurityReports|Either you don't have permission to view this dashboard or the dashboard has not been setup. Please check your permission settings with your administrator or check your dashboard configurations to proceed."
msgstr ""
msgid "SecurityReports|Ensure that %{trackingStart}issue tracking%{trackingEnd} is enabled for this project and you have %{permissionsStart}permission to create new issues%{permissionsEnd}."
msgstr ""
msgid "SecurityReports|Error fetching the vulnerability counts. Please check your network connection and try again."
msgstr ""
......@@ -27547,9 +27553,6 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong while trying to unlink the issue. Please try again later."
msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not create an issue."
msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not get user."
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