Commit 614305ed authored by Denys Mishunov's avatar Denys Mishunov

Merge branch '216300-refactor-action-button' into 'master'

Refactor button to allow for multiple actions

See merge request gitlab-org/gitlab!31619
parents a277a89b d2e2adab
...@@ -9,7 +9,7 @@ import UsersCache from '~/lib/utils/users_cache'; ...@@ -9,7 +9,7 @@ import UsersCache from '~/lib/utils/users_cache';
import ResolutionAlert from './resolution_alert.vue'; import ResolutionAlert from './resolution_alert.vue';
import VulnerabilityStateDropdown from './vulnerability_state_dropdown.vue'; import VulnerabilityStateDropdown from './vulnerability_state_dropdown.vue';
import StatusDescription from './status_description.vue'; import StatusDescription from './status_description.vue';
import { VULNERABILITY_STATE_OBJECTS } from '../constants'; import { VULNERABILITY_STATE_OBJECTS, HEADER_ACTION_BUTTONS } from '../constants';
import VulnerabilitiesEventBus from './vulnerabilities_event_bus'; import VulnerabilitiesEventBus from './vulnerabilities_event_bus';
export default { export default {
...@@ -48,7 +48,7 @@ export default { ...@@ -48,7 +48,7 @@ export default {
data() { data() {
return { return {
isLoadingVulnerability: false, isLoadingVulnerability: false,
isCreatingIssue: false, isProcessingAction: false,
isLoadingUser: false, isLoadingUser: false,
vulnerability: this.initialVulnerability, vulnerability: this.initialVulnerability,
user: undefined, user: undefined,
...@@ -56,6 +56,15 @@ export default { ...@@ -56,6 +56,15 @@ export default {
}, },
computed: { computed: {
actionButtons() {
const buttons = [];
if (!this.hasIssue) {
buttons.push(HEADER_ACTION_BUTTONS.issueCreation);
}
return buttons;
},
hasIssue() { hasIssue() {
return Boolean(this.finding.issue_feedback?.issue_iid); return Boolean(this.finding.issue_feedback?.issue_iid);
}, },
...@@ -95,6 +104,10 @@ export default { ...@@ -95,6 +104,10 @@ export default {
}, },
methods: { methods: {
triggerClick(action) {
const fn = this[action];
if (typeof fn === 'function') fn();
},
changeVulnerabilityState(newState) { changeVulnerabilityState(newState) {
this.isLoadingVulnerability = true; this.isLoadingVulnerability = true;
...@@ -115,7 +128,7 @@ export default { ...@@ -115,7 +128,7 @@ export default {
}); });
}, },
createIssue() { createIssue() {
this.isCreatingIssue = true; this.isProcessingAction = true;
axios axios
.post(this.createIssueUrl, { .post(this.createIssueUrl, {
vulnerability_feedback: { vulnerability_feedback: {
...@@ -134,7 +147,7 @@ export default { ...@@ -134,7 +147,7 @@ export default {
redirectTo(issue_url); redirectTo(issue_url);
}) })
.catch(() => { .catch(() => {
this.isCreatingIssue = false; this.isProcessingAction = false;
createFlash( createFlash(
s__('VulnerabilityManagement|Something went wrong, could not create an issue.'), s__('VulnerabilityManagement|Something went wrong, could not create an issue.'),
); );
...@@ -182,15 +195,14 @@ export default { ...@@ -182,15 +195,14 @@ export default {
@change="changeVulnerabilityState" @change="changeVulnerabilityState"
/> />
<gl-deprecated-button <gl-deprecated-button
v-if="!hasIssue" v-if="actionButtons.length > 0"
ref="create-issue-btn"
class="ml-2" class="ml-2"
variant="success" variant="success"
category="secondary" category="secondary"
:loading="isCreatingIssue" :loading="isProcessingAction"
@click="createIssue" @click="triggerClick(actionButtons[0].action)"
> >
{{ s__('VulnerabilityManagement|Create issue') }} {{ actionButtons[0].name }}
</gl-deprecated-button> </gl-deprecated-button>
</div> </div>
</div> </div>
......
...@@ -29,3 +29,10 @@ export const VULNERABILITY_STATES = { ...@@ -29,3 +29,10 @@ export const VULNERABILITY_STATES = {
}; };
export const VULNERABILITIES_PER_PAGE = 20; export const VULNERABILITIES_PER_PAGE = 20;
export const HEADER_ACTION_BUTTONS = {
issueCreation: {
name: s__('ciReport|Create issue'),
action: 'createIssue',
},
};
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlDeprecatedButton } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import UsersMockHelper from 'helpers/user_mock_data_helper'; import UsersMockHelper from 'helpers/user_mock_data_helper';
...@@ -64,7 +65,7 @@ describe('Vulnerability Header', () => { ...@@ -64,7 +65,7 @@ describe('Vulnerability Header', () => {
return user; return user;
}; };
const findCreateIssueButton = () => wrapper.find({ ref: 'create-issue-btn' }); const findGlDeprecatedButton = () => wrapper.find(GlDeprecatedButton);
const findBadge = () => wrapper.find({ ref: 'badge' }); const findBadge = () => wrapper.find({ ref: 'badge' });
const findResolutionAlert = () => wrapper.find(ResolutionAlert); const findResolutionAlert = () => wrapper.find(ResolutionAlert);
const findStatusDescription = () => wrapper.find(StatusDescription); const findStatusDescription = () => wrapper.find(StatusDescription);
...@@ -147,16 +148,18 @@ describe('Vulnerability Header', () => { ...@@ -147,16 +148,18 @@ describe('Vulnerability Header', () => {
}); });
}); });
describe('create issue button', () => { describe('single action button', () => {
beforeEach(createWrapper); it('does not display if there are no actions', () => {
createWrapper({}, findingWithIssue);
it('does display if there is not an issue already created', () => { expect(findGlDeprecatedButton().exists()).toBe(false);
expect(findCreateIssueButton().exists()).toBe(true);
}); });
it('does not display if there is an issue already created', () => { describe('create issue', () => {
createWrapper({}, findingWithIssue); beforeEach(createWrapper);
expect(findCreateIssueButton().exists()).toBe(false);
it('does display if there is only one action and not an issue already created', () => {
expect(findGlDeprecatedButton().exists()).toBe(true);
expect(findGlDeprecatedButton().text()).toBe('Create issue');
}); });
it('calls create issue endpoint on click and redirects to new issue', () => { it('calls create issue endpoint on click and redirects to new issue', () => {
...@@ -165,7 +168,7 @@ describe('Vulnerability Header', () => { ...@@ -165,7 +168,7 @@ describe('Vulnerability Header', () => {
mockAxios.onPost(dataset.createIssueUrl).reply(200, { mockAxios.onPost(dataset.createIssueUrl).reply(200, {
issue_url: issueUrl, issue_url: issueUrl,
}); });
findCreateIssueButton().vm.$emit('click'); findGlDeprecatedButton().vm.$emit('click');
return waitForPromises().then(() => { return waitForPromises().then(() => {
expect(mockAxios.history.post).toHaveLength(1); expect(mockAxios.history.post).toHaveLength(1);
const [postRequest] = mockAxios.history.post; const [postRequest] = mockAxios.history.post;
...@@ -189,7 +192,7 @@ describe('Vulnerability Header', () => { ...@@ -189,7 +192,7 @@ describe('Vulnerability Header', () => {
it('shows an error message when issue creation fails', () => { it('shows an error message when issue creation fails', () => {
mockAxios.onPost(dataset.createIssueUrl).reply(500); mockAxios.onPost(dataset.createIssueUrl).reply(500);
findCreateIssueButton().vm.$emit('click'); findGlDeprecatedButton().vm.$emit('click');
return waitForPromises().then(() => { return waitForPromises().then(() => {
expect(mockAxios.history.post).toHaveLength(1); expect(mockAxios.history.post).toHaveLength(1);
expect(createFlash).toHaveBeenCalledWith( expect(createFlash).toHaveBeenCalledWith(
...@@ -198,6 +201,7 @@ describe('Vulnerability Header', () => { ...@@ -198,6 +201,7 @@ describe('Vulnerability Header', () => {
}); });
}); });
}); });
});
describe('state badge', () => { describe('state badge', () => {
test.each(vulnerabilityStateEntries)( test.each(vulnerabilityStateEntries)(
......
...@@ -23694,9 +23694,6 @@ msgstr "" ...@@ -23694,9 +23694,6 @@ msgstr ""
msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}" msgid "VulnerabilityManagement|Confirmed %{timeago} by %{user}"
msgstr "" msgstr ""
msgid "VulnerabilityManagement|Create issue"
msgstr ""
msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}" msgid "VulnerabilityManagement|Detected %{timeago} in pipeline %{pipelineLink}"
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