Commit 5918bf63 authored by Eulyeon Ko's avatar Eulyeon Ko Committed by David O'Regan

Add link to epic in the new sidebar

Add feature spec for epic dropdown

Optionally check for group
- In a lot of tests, project doesn't have an assigned group
and trying to access @project.group.id can throw an error
- Add safe navigation operator
parent 6a03e7cd
......@@ -4,6 +4,7 @@ fragment EpicNode on Epic {
title
state
reference
webPath
webUrl
createdAt
closedAt
......
......@@ -18,7 +18,7 @@ module BoardsHelper
time_tracking_limit_to_hours: Gitlab::CurrentSettings.time_tracking_limit_to_hours.to_s,
recent_boards_endpoint: recent_boards_path,
parent: current_board_parent.model_name.param_key,
group_id: @group&.id,
group_id: group_id,
labels_filter_base_path: build_issue_link_base,
labels_fetch_path: labels_fetch_path,
labels_manage_path: labels_manage_path,
......@@ -26,6 +26,12 @@ module BoardsHelper
}
end
def group_id
return @group.id if board.group_board?
@project&.group&.id
end
def full_path
if board.group_board?
@group.full_path
......
<script>
import { GlLink } from '@gitlab/ui';
import { mapState, mapGetters, mapActions } from 'vuex';
import EpicsSelect from 'ee/vue_shared/components/sidebar/epics_select/base.vue';
import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
......@@ -11,6 +12,7 @@ export default {
components: {
BoardEditableItem,
EpicsSelect,
GlLink,
},
i18n: {
epic: __('Epic'),
......@@ -99,13 +101,14 @@ export default {
ref="sidebarItem"
:title="$options.i18n.epic"
:loading="epicFetchInProgress"
data-testid="sidebar-epic"
@open="handleOpen"
@close="handleClose"
>
<template v-if="epicData.title" #collapsed>
<a class="gl-text-gray-900! gl-font-weight-bold" href="#">
<gl-link class="gl-text-gray-900! gl-font-weight-bold" :href="epicData.webPath">
{{ epicData.title }}
</a>
</gl-link>
</template>
<epics-select
v-if="!epicFetchInProgress"
......
......@@ -4,6 +4,7 @@ fragment BoardEpicNode on BoardEpic {
title
state
reference
webPath
webUrl
createdAt
closedAt
......
---
title: Fix epics dropdown to work in project epic swimlanes
merge_request: 55954
author:
type: fixed
......@@ -11,6 +11,7 @@ RSpec.describe 'epics swimlanes sidebar', :js do
let_it_be(:label) { create(:label, project: project, name: 'Label 1') }
let_it_be(:list) { create(:list, board: board, label: label, position: 0) }
let_it_be(:epic1) { create(:epic, group: group) }
let_it_be(:epic2) { create(:epic, group: group) }
let_it_be(:issue1, reload: true) { create(:issue, project: project) }
let_it_be(:epic_issue1, reload: true) { create(:epic_issue, epic: epic1, issue: issue1) }
......@@ -40,6 +41,40 @@ RSpec.describe 'epics swimlanes sidebar', :js do
end
end
context 'epic dropdown' do
before do
group.add_owner(user)
end
context 'when the issue is associated with an epic' do
it 'displays name of epic and links to it' do
load_epic_swimlanes
click_first_issue_card
page.within('[data-testid="sidebar-epic"]') do
expect(page).to have_link(epic1.title, href: epic_path(epic1))
end
end
it 'updates the epic associated with the issue' do
load_epic_swimlanes
click_first_issue_card
page.within('[data-testid="sidebar-epic"]') do
find("[data-testid='edit-button']").click
wait_for_all_requests
find('.gl-new-dropdown-item', text: epic2.title).click
wait_for_all_requests
expect(page).to have_link(epic2.title, href: epic_path(epic2))
end
end
end
end
context 'notifications subscription' do
it 'displays notifications toggle' do
load_epic_swimlanes
......
import { GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import BoardSidebarEpicSelect from 'ee/boards/components/sidebar/board_sidebar_epic_select.vue';
......@@ -69,6 +70,7 @@ describe('ee/boards/components/sidebar/board_sidebar_epic_select.vue', () => {
const findEpicSelect = () => wrapper.find({ ref: 'epicSelect' });
const findItemWrapper = () => wrapper.find({ ref: 'sidebarItem' });
const findCollapsed = () => wrapper.find('[data-testid="collapsed-content"]');
const findEpicLink = () => wrapper.find(GlLink);
const findBoardEditableItem = () => wrapper.find(BoardEditableItem);
describe('when not editing', () => {
......@@ -173,7 +175,9 @@ describe('ee/boards/components/sidebar/board_sidebar_epic_select.vue', () => {
await wrapper.vm.$nextTick();
expect(findCollapsed().text()).toBe(mockAssignedEpic.title);
expect(findEpicLink().isVisible()).toBe(true);
expect(findEpicLink().text()).toBe(mockAssignedEpic.title);
expect(findEpicLink().attributes('href')).toBe(mockAssignedEpic.webPath);
});
});
......@@ -212,8 +216,9 @@ describe('ee/boards/components/sidebar/board_sidebar_epic_select.vue', () => {
});
it('collapses sidebar and renders epic title', () => {
expect(findCollapsed().isVisible()).toBe(true);
expect(findCollapsed().text()).toBe(mockAssignedEpic.title);
expect(findEpicLink().isVisible()).toBe(true);
expect(findEpicLink().text()).toBe(mockAssignedEpic.title);
expect(findEpicLink().attributes('href')).toBe(mockAssignedEpic.webPath);
});
describe('when the selected epic did not change', () => {
......
......@@ -226,7 +226,14 @@ export const mockEpic = {
labels: [],
};
export const mockIssueWithEpic = { ...mockIssue3, epic: { id: mockEpic.id, iid: mockEpic.iid } };
export const mockIssueWithEpic = {
...mockIssue3,
epic: {
id: mockEpic.id,
iid: mockEpic.iid,
webPath: '/gitlab-org/-/epics/41',
},
};
export const mockAssignedEpic = { ...mockIssueWithEpic.epic, title: mockEpic.title };
export const mockEpics = [
......
......@@ -4,8 +4,8 @@ require 'spec_helper'
RSpec.describe BoardsHelper do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:base_group) { create(:group, path: 'base') }
let_it_be(:project) { create(:project, group: base_group) }
let_it_be(:project_board) { create(:board, project: project) }
let_it_be(:group_board) { create(:board, group: base_group) }
......@@ -82,6 +82,10 @@ RSpec.describe BoardsHelper do
expect(helper.board_data[:labels_fetch_path]).to eq("/#{project.full_path}/-/labels.json?include_ancestor_groups=true")
expect(helper.board_data[:labels_manage_path]).to eq("/#{project.full_path}/-/labels")
end
it 'returns the group id of a project' do
expect(helper.board_data[:group_id]).to eq(project.group.id)
end
end
context 'group board' do
......@@ -102,6 +106,10 @@ RSpec.describe BoardsHelper do
expect(helper.board_data[:labels_fetch_path]).to eq("/groups/#{base_group.full_path}/-/labels.json?include_ancestor_groups=true&only_group_labels=true")
expect(helper.board_data[:labels_manage_path]).to eq("/groups/#{base_group.full_path}/-/labels")
end
it 'returns the group id' do
expect(helper.board_data[:group_id]).to eq(base_group.id)
end
end
end
......
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