Commit a8ae15e7 authored by Olena Horal-Koretska's avatar Olena Horal-Koretska

Merge branch '321962-add-issue-reference-to-jira-issue-details-page' into 'master'

Add issue reference to Jira issue details page

See merge request gitlab-org/gitlab!54547
parents 95011e7a 75c956a9
......@@ -46,6 +46,11 @@ export default {
required: false,
default: false,
},
tooltipBoundary: {
type: String,
required: false,
default: null,
},
cssClass: {
type: String,
required: false,
......@@ -75,8 +80,11 @@ export default {
<template>
<gl-button
v-gl-tooltip="{ placement: tooltipPlacement, container: tooltipContainer }"
v-gl-tooltip.hover.blur
v-gl-tooltip.hover.blur="{
placement: tooltipPlacement,
container: tooltipContainer,
boundary: tooltipBoundary,
}"
:class="cssClass"
:title="title"
:data-clipboard-text="clipboardText"
......
<script>
import { __ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
export default {
name: 'JiraIssuesSidebarReference',
components: {
ClipboardButton,
},
props: {
reference: {
type: String,
required: true,
},
},
computed: {
clipboardProps() {
return {
category: 'tertiary',
tooltipBoundary: 'viewport',
tooltipPlacement: 'left',
text: this.reference,
title: this.$options.i18n.copyTitle,
};
},
},
i18n: {
copyTitle: __('Copy reference'),
},
};
</script>
<template>
<div class="block">
<div class="sidebar-collapsed-icon dont-change-state">
<clipboard-button css-class="btn-clipboard" v-bind="clipboardProps" />
</div>
<div class="cross-project-reference hide-collapsed">
<span
>{{ __('Reference:') }}
<cite :title="reference">{{ reference }}</cite>
</span>
<clipboard-button size="small" v-bind="clipboardProps" />
</div>
</div>
</template>
<script>
import LabelsSelect from '~/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue';
import Assignee from './assignee.vue';
import IssueReference from './issue_reference.vue';
export default {
name: 'JiraIssuesSidebar',
components: {
Assignee,
IssueReference,
LabelsSelect,
},
props: {
......@@ -23,6 +25,9 @@ export default {
// Jira issues have at most 1 assignee
return (this.issue?.assignees || [])[0];
},
reference() {
return this.issue?.references?.relative;
},
},
};
</script>
......@@ -38,5 +43,6 @@ export default {
>
{{ __('None') }}
</labels-select>
<issue-reference v-if="reference" :reference="reference" />
</div>
</template>
import { shallowMount } from '@vue/test-utils';
import IssueReference from 'ee/integrations/jira/issues_show/components/sidebar/issue_reference.vue';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
describe('IssueReference', () => {
let wrapper;
const defaultProps = {
reference: 'GL-1',
};
const createComponent = () => {
wrapper = shallowMount(IssueReference, {
propsData: defaultProps,
});
};
afterEach(() => {
if (wrapper) {
wrapper.destroy();
wrapper = null;
}
});
const findClipboardButton = () => wrapper.findComponent(ClipboardButton);
it('renders reference', () => {
createComponent();
expect(wrapper.text()).toContain(defaultProps.reference);
});
it('renders ClipboardButton', () => {
createComponent();
expect(findClipboardButton().exists()).toBe(true);
});
});
import { shallowMount } from '@vue/test-utils';
import Assignee from 'ee/integrations/jira/issues_show/components/sidebar/assignee.vue';
import IssueReference from 'ee/integrations/jira/issues_show/components/sidebar/issue_reference.vue';
import Sidebar from 'ee/integrations/jira/issues_show/components/sidebar/jira_issues_sidebar_root.vue';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import LabelsSelect from '~/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue';
......@@ -15,9 +16,9 @@ describe('JiraIssuesSidebar', () => {
issue: mockJiraIssue,
};
const createComponent = () => {
const createComponent = ({ props = {} } = {}) => {
wrapper = shallowMount(Sidebar, {
propsData: defaultProps,
propsData: { ...defaultProps, ...props },
});
};
......@@ -30,6 +31,7 @@ describe('JiraIssuesSidebar', () => {
const findLabelsSelect = () => wrapper.findComponent(LabelsSelect);
const findAssignee = () => wrapper.findComponent(Assignee);
const findIssueReference = () => wrapper.findComponent(IssueReference);
it('renders Labels block', async () => {
createComponent();
......@@ -45,4 +47,26 @@ describe('JiraIssuesSidebar', () => {
expect(assignee.exists()).toBe(true);
expect(assignee.props('assignee')).toEqual(mockJiraIssue.assignees[0]);
});
describe('when references.relative is null', () => {
it('does not render IssueReference', () => {
createComponent({
props: {
issue: {
references: {},
},
},
});
expect(findIssueReference().exists()).toBe(false);
});
});
describe('when references.relative is provided', () => {
it('renders IssueReference', () => {
createComponent();
expect(findIssueReference().exists()).toBe(true);
});
});
});
......@@ -24,5 +24,8 @@ export const mockJiraIssue = {
text_color: '#283856',
},
],
references: {
relative: 'FE-2',
},
state: 'opened',
};
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