Commit b8709555 authored by Phil Hughes's avatar Phil Hughes

Merge branch '333186-add-link-to-incident-title' into 'master'

Add link to incident title in list

See merge request gitlab-org/gitlab!82373
parents ce215249 32642d5e
<script> <script>
import { import {
GlLink,
GlLoadingIcon, GlLoadingIcon,
GlTable, GlTable,
GlAvatarsInline, GlAvatarsInline,
...@@ -106,6 +107,7 @@ export default { ...@@ -106,6 +107,7 @@ export default {
], ],
MAX_VISIBLE_ASSIGNEES, MAX_VISIBLE_ASSIGNEES,
components: { components: {
GlLink,
GlLoadingIcon, GlLoadingIcon,
GlTable, GlTable,
GlAvatarsInline, GlAvatarsInline,
...@@ -271,7 +273,7 @@ export default { ...@@ -271,7 +273,7 @@ export default {
return Boolean(assignees.nodes?.length); return Boolean(assignees.nodes?.length);
}, },
navigateToIncidentDetails({ iid }) { navigateToIncidentDetails({ iid }) {
return visitUrl(joinPaths(this.issuePath, INCIDENT_DETAILS_PATH, iid)); return visitUrl(this.showIncidentLink({ iid }));
}, },
navigateToCreateNewIncident() { navigateToCreateNewIncident() {
const { category, action } = this.$options.trackIncidentCreateNewOptions; const { category, action } = this.$options.trackIncidentCreateNewOptions;
...@@ -297,6 +299,9 @@ export default { ...@@ -297,6 +299,9 @@ export default {
getEscalationStatus(escalationStatus) { getEscalationStatus(escalationStatus) {
return ESCALATION_STATUSES[escalationStatus] || this.$options.i18n.noEscalationStatus; return ESCALATION_STATUSES[escalationStatus] || this.$options.i18n.noEscalationStatus;
}, },
showIncidentLink({ iid }) {
return joinPaths(this.issuePath, INCIDENT_DETAILS_PATH, iid);
},
pageChanged(pagination) { pageChanged(pagination) {
this.pagination = pagination; this.pagination = pagination;
}, },
...@@ -384,12 +389,14 @@ export default { ...@@ -384,12 +389,14 @@ export default {
<template #cell(title)="{ item }"> <template #cell(title)="{ item }">
<div :class="{ 'gl-display-flex gl-align-items-center': item.state === 'closed' }"> <div :class="{ 'gl-display-flex gl-align-items-center': item.state === 'closed' }">
<tooltip-on-truncate <gl-link
v-gl-tooltip
:title="item.title" :title="item.title"
class="gl-max-w-full gl-text-truncate gl-display-block" data-testid="incident-link"
:href="showIncidentLink(item)"
> >
{{ item.title }} {{ item.title }}
</tooltip-on-truncate> </gl-link>
<gl-icon <gl-icon
v-if="item.state === 'closed'" v-if="item.state === 'closed'"
name="issue-close" name="issue-close"
......
import { GlAlert, GlLoadingIcon, GlTable, GlAvatar, GlEmptyState } from '@gitlab/ui'; import { GlAlert, GlLoadingIcon, GlTable, GlAvatar, GlEmptyState } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import IncidentsList from '~/incidents/components/incidents_list.vue'; import IncidentsList from '~/incidents/components/incidents_list.vue';
import { import {
I18N, I18N,
...@@ -19,7 +20,7 @@ import mockIncidents from '../mocks/incidents.json'; ...@@ -19,7 +20,7 @@ import mockIncidents from '../mocks/incidents.json';
jest.mock('~/lib/utils/url_utility', () => ({ jest.mock('~/lib/utils/url_utility', () => ({
visitUrl: jest.fn().mockName('visitUrlMock'), visitUrl: jest.fn().mockName('visitUrlMock'),
joinPaths: jest.fn(), joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths,
mergeUrlParams: jest.fn(), mergeUrlParams: jest.fn(),
setUrlParams: jest.fn(), setUrlParams: jest.fn(),
updateHistory: jest.fn(), updateHistory: jest.fn(),
...@@ -49,48 +50,51 @@ describe('Incidents List', () => { ...@@ -49,48 +50,51 @@ describe('Incidents List', () => {
const findEmptyState = () => wrapper.find(GlEmptyState); const findEmptyState = () => wrapper.find(GlEmptyState);
const findSeverity = () => wrapper.findAll(SeverityToken); const findSeverity = () => wrapper.findAll(SeverityToken);
const findEscalationStatus = () => wrapper.findAll('[data-testid="incident-escalation-status"]'); const findEscalationStatus = () => wrapper.findAll('[data-testid="incident-escalation-status"]');
const findIncidentLink = () => wrapper.findByTestId('incident-link');
function mountComponent({ data = {}, loading = false, provide = {} } = {}) { function mountComponent({ data = {}, loading = false, provide = {} } = {}) {
wrapper = mount(IncidentsList, { wrapper = extendedWrapper(
data() { mount(IncidentsList, {
return { data() {
incidents: [], return {
incidentsCount: {}, incidents: [],
...data, incidentsCount: {},
}; ...data,
}, };
mocks: { },
$apollo: { mocks: {
queries: { $apollo: {
incidents: { queries: {
loading, incidents: {
loading,
},
}, },
}, },
}, },
}, provide: {
provide: { projectPath: '/project/path',
projectPath: '/project/path', newIssuePath,
newIssuePath, incidentTemplateName,
incidentTemplateName, incidentType,
incidentType, issuePath: '/project/issues',
issuePath: '/project/issues', publishedAvailable: true,
publishedAvailable: true, emptyListSvgPath,
emptyListSvgPath, textQuery: '',
textQuery: '', authorUsernameQuery: '',
authorUsernameQuery: '', assigneeUsernameQuery: '',
assigneeUsernameQuery: '', slaFeatureAvailable: true,
slaFeatureAvailable: true, canCreateIncident: true,
canCreateIncident: true, incidentEscalationsAvailable: true,
incidentEscalationsAvailable: true, ...provide,
...provide, },
}, stubs: {
stubs: { GlButton: true,
GlButton: true, GlAvatar: true,
GlAvatar: true, GlEmptyState: true,
GlEmptyState: true, ServiceLevelAgreementCell: true,
ServiceLevelAgreementCell: true, },
}, }),
}); );
} }
afterEach(() => { afterEach(() => {
...@@ -160,6 +164,14 @@ describe('Incidents List', () => { ...@@ -160,6 +164,14 @@ describe('Incidents List', () => {
expect(findTimeAgo().length).toBe(mockIncidents.length); expect(findTimeAgo().length).toBe(mockIncidents.length);
}); });
it('renders a link to the incident as the incident title', () => {
const { title, iid } = mockIncidents[0];
const link = findIncidentLink();
expect(link.text()).toBe(title);
expect(link.attributes('href')).toContain(`issues/incident/${iid}`);
});
describe('Assignees', () => { describe('Assignees', () => {
it('shows Unassigned when there are no assignees', () => { it('shows Unassigned when there are no assignees', () => {
expect(findAssignees().at(0).text()).toBe(I18N.unassigned); expect(findAssignees().at(0).text()).toBe(I18N.unassigned);
......
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