Commit 5937731a authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch 'justin_ho-jira-issues-show-add-banner-with-link-to-jira-new' into 'master'

Add GlAlert with link to Jira issue

See merge request gitlab-org/gitlab!53805
parents db23c940 04d1569c
...@@ -54,7 +54,7 @@ export default { ...@@ -54,7 +54,7 @@ export default {
<template> <template>
<div> <div>
<div class="title-container"> <div class="title-container">
<h2 v-safe-html="issuable.titleHtml" class="title qa-title" dir="auto"></h2> <h2 v-safe-html="issuable.titleHtml || issuable.title" class="title qa-title" dir="auto"></h2>
<gl-button <gl-button
v-if="enableEdit" v-if="enableEdit"
v-gl-tooltip.bottom v-gl-tooltip.bottom
......
<script> <script>
import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
import { fetchIssue } from 'ee/integrations/jira/issues_show/api'; import { fetchIssue } from 'ee/integrations/jira/issues_show/api';
import { issueStates, issueStateLabels } from 'ee/integrations/jira/issues_show/constants'; import { issueStates, issueStateLabels } from 'ee/integrations/jira/issues_show/constants';
import Sidebar from 'ee/integrations/jira/issues_show/components/sidebar.vue'; import Sidebar from 'ee/integrations/jira/issues_show/components/sidebar.vue';
...@@ -9,6 +10,9 @@ import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; ...@@ -9,6 +10,9 @@ import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
export default { export default {
name: 'JiraIssuesShow', name: 'JiraIssuesShow',
components: { components: {
GlAlert,
GlSprintf,
GlLink,
IssuableShow, IssuableShow,
Sidebar, Sidebar,
}, },
...@@ -33,6 +37,9 @@ export default { ...@@ -33,6 +37,9 @@ export default {
statusBadgeText() { statusBadgeText() {
return issueStateLabels[this.issue.state]; return issueStateLabels[this.issue.state];
}, },
statusIcon() {
return this.isIssueOpen ? 'issue-open-m' : 'mobile-issue-close';
},
}, },
async mounted() { async mounted() {
this.issue = convertObjectPropsToCamelCase(await fetchIssue(this.issuesShowPath), { this.issue = convertObjectPropsToCamelCase(await fetchIssue(this.issuesShowPath), {
...@@ -44,12 +51,32 @@ export default { ...@@ -44,12 +51,32 @@ export default {
</script> </script>
<template> <template>
<div> <div class="gl-mt-5">
<gl-alert
variant="info"
:dismissible="false"
:title="s__('JiraService|This issue is synchronized with Jira')"
class="gl-mb-2"
>
<gl-sprintf
:message="
s__(
`JiraService|Not all data may be displayed here. To view more details or make changes to this issue, go to %{linkStart}Jira%{linkEnd}.`,
)
"
>
<template #link="{ content }">
<gl-link :href="issue.webUrl" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</gl-alert>
<issuable-show <issuable-show
v-if="!isLoading" v-if="!isLoading"
:issuable="issue" :issuable="issue"
:enable-edit="false" :enable-edit="false"
:status-badge-class="statusBadgeClass" :status-badge-class="statusBadgeClass"
:status-icon="statusIcon"
> >
<template #status-badge>{{ statusBadgeText }}</template> <template #status-badge>{{ statusBadgeText }}</template>
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import waitForPromises from 'helpers/wait_for_promises';
import JiraIssuesShow from 'ee/integrations/jira/issues_show/components/jira_issues_show_root.vue'; import JiraIssuesShow from 'ee/integrations/jira/issues_show/components/jira_issues_show_root.vue';
import { issueStates } from 'ee/integrations/jira/issues_show/constants';
import IssuableShow from '~/issuable_show/components/issuable_show_root.vue'; import IssuableShow from '~/issuable_show/components/issuable_show_root.vue';
import IssuableHeader from '~/issuable_show/components/issuable_header.vue';
import { mockJiraIssue } from '../mock_data'; import { mockJiraIssue } from '../mock_data';
jest.mock('ee/integrations/jira/issues_show/api', () => ({ const mockJiraIssuesShowPath = 'jira_issues_show_path';
fetchIssue: jest.fn().mockImplementation(() => mockJiraIssue),
}));
describe('JiraIssuesShow', () => { describe('JiraIssuesShow', () => {
let wrapper; let wrapper;
let mockAxios;
const findIssuableShow = () => wrapper.findComponent(IssuableShow);
const findIssuableShowStatusBadge = () =>
wrapper.findComponent(IssuableHeader).find('[data-testid="status"]');
const createComponent = () => { const createComponent = () => {
wrapper = shallowMount(JiraIssuesShow, { wrapper = shallowMount(JiraIssuesShow, {
stubs: { stubs: {
IssuableShow, IssuableShow,
IssuableHeader,
},
provide: {
issuesShowPath: mockJiraIssuesShowPath,
}, },
}); });
}; };
beforeEach(() => {
mockAxios = new MockAdapter(axios);
});
afterEach(() => { afterEach(() => {
mockAxios.restore();
if (wrapper) { if (wrapper) {
wrapper.destroy(); wrapper.destroy();
wrapper = null; wrapper = null;
} }
}); });
const findIssuableShow = () => wrapper.findComponent(IssuableShow);
it('renders IssuableShow', async () => { it('renders IssuableShow', async () => {
mockAxios.onGet(mockJiraIssuesShowPath).replyOnce(200, mockJiraIssue);
createComponent(); createComponent();
await waitForPromises();
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(findIssuableShow().exists()).toBe(true); expect(findIssuableShow().exists()).toBe(true);
}); });
describe.each`
state | statusIcon | statusBadgeClass | badgeText
${issueStates.OPENED} | ${'issue-open-m'} | ${'status-box-open'} | ${'Open'}
${issueStates.CLOSED} | ${'mobile-issue-close'} | ${'status-box-issue-closed'} | ${'Closed'}
`('when issue state is `$state`', async ({ state, statusIcon, statusBadgeClass, badgeText }) => {
beforeEach(async () => {
mockAxios.onGet(mockJiraIssuesShowPath).replyOnce(200, { ...mockJiraIssue, state });
createComponent();
await waitForPromises();
await wrapper.vm.$nextTick();
});
it('sets `statusIcon` prop correctly', () => {
expect(findIssuableShow().props('statusIcon')).toBe(statusIcon);
});
it('sets `statusBadgeClass` prop correctly', () => {
expect(findIssuableShow().props('statusBadgeClass')).toBe(statusBadgeClass);
});
it('renders correct status badge text', () => {
expect(findIssuableShowStatusBadge().text()).toBe(badgeText);
});
});
}); });
...@@ -16676,6 +16676,9 @@ msgstr "" ...@@ -16676,6 +16676,9 @@ msgstr ""
msgid "JiraService|Jira workflow transition IDs" msgid "JiraService|Jira workflow transition IDs"
msgstr "" msgstr ""
msgid "JiraService|Not all data may be displayed here. To view more details or make changes to this issue, go to %{linkStart}Jira%{linkEnd}."
msgstr ""
msgid "JiraService|Open Jira" msgid "JiraService|Open Jira"
msgstr "" msgstr ""
...@@ -16700,6 +16703,9 @@ msgstr "" ...@@ -16700,6 +16703,9 @@ msgstr ""
msgid "JiraService|This feature requires a Premium plan." msgid "JiraService|This feature requires a Premium plan."
msgstr "" msgstr ""
msgid "JiraService|This issue is synchronized with Jira"
msgstr ""
msgid "JiraService|Use a password for server version and an API token for cloud version" msgid "JiraService|Use a password for server version and an API token for cloud version"
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