diff --git a/app/assets/javascripts/work_items/components/work_item_relationships/work_item_relationship_list.vue b/app/assets/javascripts/work_items/components/work_item_relationships/work_item_relationship_list.vue index e01708a01d455f111dbda659cbd0fdc677c3611b..2a8dec9ef135b790b0b3449492b196b4d063f604 100644 --- a/app/assets/javascripts/work_items/components/work_item_relationships/work_item_relationship_list.vue +++ b/app/assets/javascripts/work_items/components/work_item_relationships/work_item_relationship_list.vue @@ -10,10 +10,16 @@ import { sortableStart, sortableEnd } from '~/sortable/utils'; import WorkItemLinkChildContents from 'ee_else_ce/work_items/components/shared/work_item_link_child_contents.vue'; +import { SUPPORT_BOT_USERNAME } from '~/issues/show/utils/issuable_data'; + import removeLinkedItemsMutation from '../../graphql/remove_linked_items.mutation.graphql'; import addLinkedItemsMutation from '../../graphql/add_linked_items.mutation.graphql'; -import { RELATIONSHIP_TYPE_ENUM, WORK_ITEM_TYPE_NAME_INCIDENT } from '../../constants'; +import { + RELATIONSHIP_TYPE_ENUM, + WORK_ITEM_TYPE_NAME_INCIDENT, + WORK_ITEM_TYPE_NAME_ISSUE, +} from '../../constants'; export default { RELATIONSHIP_TYPE_ENUM, @@ -189,13 +195,21 @@ export default { } }, handleLinkedItemClick(event, linkedItem) { - // if the linkedItem is incident, redirect to the incident page - if (linkedItem?.workItem?.workItemType?.name === WORK_ITEM_TYPE_NAME_INCIDENT) { + if (this.isIncident(linkedItem) || this.isServiceDeskIssue(linkedItem)) { visitUrl(linkedItem.workItem.webUrl); } else { this.$emit('showModal', { event, child: linkedItem.workItem }); } }, + isIncident(linkedItem) { + return linkedItem?.workItem?.workItemType?.name === WORK_ITEM_TYPE_NAME_INCIDENT; + }, + isServiceDeskIssue(linkedItem) { + return ( + linkedItem?.workItem?.workItemType?.name === WORK_ITEM_TYPE_NAME_ISSUE && + linkedItem?.workItem?.author?.username === SUPPORT_BOT_USERNAME + ); + }, }, }; diff --git a/app/assets/javascripts/work_items/graphql/work_item_linked_items.fragment.graphql b/app/assets/javascripts/work_items/graphql/work_item_linked_items.fragment.graphql index 347adf57e6c10410029c173294eb536a3bd42a4f..6935de9829d0424fb47e4a924ed0844202cacc0c 100644 --- a/app/assets/javascripts/work_items/graphql/work_item_linked_items.fragment.graphql +++ b/app/assets/javascripts/work_items/graphql/work_item_linked_items.fragment.graphql @@ -22,6 +22,9 @@ fragment WorkItemLinkedItemsFragment on WorkItem { id fullPath } + author { + username + } workItemType { id name diff --git a/spec/frontend/work_items/components/work_item_relationships/work_item_relationship_list_spec.js b/spec/frontend/work_items/components/work_item_relationships/work_item_relationship_list_spec.js index ccc2dee353fee865f8daec81dd623d099788c639..cb2d9f6282dfeb1343c02c8574dfe41f070a5a9d 100644 --- a/spec/frontend/work_items/components/work_item_relationships/work_item_relationship_list_spec.js +++ b/spec/frontend/work_items/components/work_item_relationships/work_item_relationship_list_spec.js @@ -9,7 +9,7 @@ import WorkItemLinkChildContents from 'ee_else_ce/work_items/components/shared/w import removeLinkedItemsMutation from '~/work_items/graphql/remove_linked_items.mutation.graphql'; import addLinkedItemsMutation from '~/work_items/graphql/add_linked_items.mutation.graphql'; -import { mockBlockingLinkedItem } from '../../mock_data'; +import { mockBlockingLinkedItem, incidentType, issueType } from '../../mock_data'; jest.mock('~/lib/utils/url_utility'); @@ -108,26 +108,35 @@ describe('WorkItemRelationshipList', () => { ]); }); - it('redirects to the url of the linked item on click when the item is an incident', () => { - const mockLinkedItemsWithIncident = [ + describe('redirects to URL on click', () => { + const createMockLinkedItemWithType = (workItemType, additionalProps = {}) => [ { ...mockLinkedItems[0], workItem: { ...mockLinkedItems[0].workItem, - workItemType: { - id: 'gid://gitlab/WorkItems::Type/5', - name: 'Incident', - iconName: 'issue-type-incident', - __typename: 'WorkItemType', - }, + workItemType, + ...additionalProps, }, }, ]; - createComponent({ linkedItems: mockLinkedItemsWithIncident }); - findWorkItemLinkChildContents().vm.$emit('click'); + it.each([ + { + description: 'when the item is an incident', + linkedItems: createMockLinkedItemWithType(incidentType), + }, + { + description: 'when the item is a Service Desk issue', + linkedItems: createMockLinkedItemWithType(issueType, { + author: { username: 'support-bot' }, + }), + }, + ])('$description', ({ linkedItems }) => { + createComponent({ linkedItems }); + findWorkItemLinkChildContents().vm.$emit('click'); - expect(visitUrl).toHaveBeenCalledWith(mockLinkedItemsWithIncident[0].workItem.webUrl); + expect(visitUrl).toHaveBeenCalledWith(linkedItems[0].workItem.webUrl); + }); }); describe('drag start', () => { diff --git a/spec/frontend/work_items/mock_data.js b/spec/frontend/work_items/mock_data.js index 603726626a4498bb4f9d0a0a81e8657e4f8040a1..c797424157ffe853b1852a3dc8be6fc1d7c88605 100644 --- a/spec/frontend/work_items/mock_data.js +++ b/spec/frontend/work_items/mock_data.js @@ -798,6 +798,13 @@ export const issueType = { iconName: 'issue-type-issue', }; +export const incidentType = { + id: 'gid://gitlab/WorkItems::Type/5', + name: 'Incident', + iconName: 'issue-type-incident', + __typename: 'WorkItemType', +}; + export const epicType = { __typename: 'WorkItemType', id: 'gid://gitlab/WorkItems::Type/2411', @@ -829,6 +836,9 @@ export const mockBlockingLinkedItem = { id: 'gid://gitlab/WorkItem/675', iid: '83', confidential: true, + author: { + username: 'fbar', + }, workItemType: { id: 'gid://gitlab/WorkItems::Type/5', name: 'Task',