Skip to content
代码片段 群组 项目
未验证 提交 7f13dcdf 编辑于 作者: Florie Guibert's avatar Florie Guibert 提交者: GitLab
浏览文件

Merge branch...

Merge branch '434169-implement-search-mechanism-for-work-item-epic-in-legacy-issue-s-sidebar' into 'master' 

Enable search mechanism if work item epic are shown in issue sidebar

See merge request https://gitlab.com/gitlab-org/gitlab/-/merge_requests/144737



Merged-by: default avatarFlorie Guibert <fguibert@gitlab.com>
Approved-by: default avatarSerena Fang <sfang@gitlab.com>
Approved-by: default avatarFlorie Guibert <fguibert@gitlab.com>
Approved-by: default avatarElwyn Benson <ebenson@gitlab.com>
Co-authored-by: default avatarRajan Mistry <rmistry@gitlab.com>
No related branches found
No related tags found
无相关合并请求
...@@ -29,6 +29,7 @@ import { ...@@ -29,6 +29,7 @@ import {
import { issuableAttributesQueries } from 'ee_else_ce/sidebar/queries/constants'; import { issuableAttributesQueries } from 'ee_else_ce/sidebar/queries/constants';
import { createAlert } from '~/alert'; import { createAlert } from '~/alert';
import { PathIdSeparator } from '~/related_issues/constants'; import { PathIdSeparator } from '~/related_issues/constants';
import { WORK_ITEM_TYPE_ENUM_EPIC } from '~/work_items/constants';
export default { export default {
noAttributeId, noAttributeId,
...@@ -123,6 +124,10 @@ export default { ...@@ -123,6 +124,10 @@ export default {
includeWorkItems: this.showWorkItemEpics, includeWorkItems: this.showWorkItemEpics,
}; };
if (this.showWorkItemEpics) {
variables.types = [WORK_ITEM_TYPE_ENUM_EPIC];
}
if (epicIidPattern.test(this.searchTerm)) { if (epicIidPattern.test(this.searchTerm)) {
const matches = this.searchTerm.match(epicIidPattern); const matches = this.searchTerm.match(epicIidPattern);
variables.iidStartsWith = matches.groups.iid; variables.iidStartsWith = matches.groups.iid;
...@@ -222,12 +227,7 @@ export default { ...@@ -222,12 +227,7 @@ export default {
@show="handleShow" @show="handleShow"
@shown="setFocus" @shown="setFocus"
> >
<gl-search-box-by-type <gl-search-box-by-type ref="search" v-model="searchTerm" :placeholder="__('Search')" />
v-if="!showWorkItemEpics"
ref="search"
v-model="searchTerm"
:placeholder="__('Search')"
/>
<gl-dropdown-item <gl-dropdown-item
:data-testid="`no-${formatIssuableAttribute.kebab}-item`" :data-testid="`no-${formatIssuableAttribute.kebab}-item`"
is-check-item is-check-item
......
...@@ -7,6 +7,7 @@ query issueEpics( ...@@ -7,6 +7,7 @@ query issueEpics(
$in: [IssuableSearchableField!] $in: [IssuableSearchableField!]
$iidStartsWith: String $iidStartsWith: String
$includeWorkItems: Boolean! $includeWorkItems: Boolean!
$types: [IssueType!]
) { ) {
workspace: group(fullPath: $fullPath) { workspace: group(fullPath: $fullPath) {
id id
...@@ -23,7 +24,7 @@ query issueEpics( ...@@ -23,7 +24,7 @@ query issueEpics(
state state
} }
} }
workItems @include(if: $includeWorkItems) { workItems(types: $types) @include(if: $includeWorkItems) {
nodes { nodes {
id id
title title
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
before do before do
group.add_owner(user) group.add_owner(user)
# disable work item search until work items filters are available
stub_feature_flags(display_work_item_epic_issue_sidebar: false) stub_feature_flags(display_work_item_epic_issue_sidebar: false)
sign_in user sign_in user
...@@ -55,6 +54,7 @@ ...@@ -55,6 +54,7 @@
expect(page).to have_content epic1.title expect(page).to have_content epic1.title
expect(page).to have_content epic2.title expect(page).to have_content epic2.title
expect(page).to have_content epic3.title expect(page).to have_content epic3.title
expect(page).not_to have_content work_item_epic.title
end end
end end
end end
...@@ -170,6 +170,11 @@ ...@@ -170,6 +170,11 @@
click_edit click_edit
aggregate_failures do aggregate_failures do
expect(page).to have_selector('.gl-dropdown-contents .gl-dropdown-item', count: 5)
expect(page).to have_content 'No epic'
expect(page).to have_content epic1.title
expect(page).to have_content epic2.title
expect(page).to have_content epic3.title
expect(page).to have_content work_item_epic.title expect(page).to have_content work_item_epic.title
end end
end end
......
import { GlDropdown, GlFormInput, GlSearchBoxByType } from '@gitlab/ui'; import { GlDropdown, GlFormInput } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import Vue from 'vue'; import Vue from 'vue';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
...@@ -19,7 +19,7 @@ import { extendedWrapper } from 'helpers/vue_test_utils_helper'; ...@@ -19,7 +19,7 @@ import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { createAlert } from '~/alert'; import { createAlert } from '~/alert';
import { TYPE_ISSUE } from '~/issues/constants'; import { TYPE_ISSUE } from '~/issues/constants';
import { WORK_ITEM_TYPE_VALUE_EPIC } from '~/work_items/constants'; import { WORK_ITEM_TYPE_VALUE_EPIC, WORK_ITEM_TYPE_ENUM_EPIC } from '~/work_items/constants';
import { clickEdit, search } from '../helpers'; import { clickEdit, search } from '../helpers';
import { import {
...@@ -51,7 +51,6 @@ describe('SidebarDropdownWidget', () => { ...@@ -51,7 +51,6 @@ describe('SidebarDropdownWidget', () => {
const findSidebarDropdown = () => wrapper.findComponent(SidebarDropdown); const findSidebarDropdown = () => wrapper.findComponent(SidebarDropdown);
const findPopoverCta = () => wrapper.findByTestId('confirm-edit-cta'); const findPopoverCta = () => wrapper.findByTestId('confirm-edit-cta');
const findPopoverCancel = () => wrapper.findByTestId('confirm-edit-cancel'); const findPopoverCancel = () => wrapper.findByTestId('confirm-edit-cancel');
const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
const waitForDropdown = async () => { const waitForDropdown = async () => {
/** This sequence is important to wait for /** This sequence is important to wait for
...@@ -108,6 +107,7 @@ describe('SidebarDropdownWidget', () => { ...@@ -108,6 +107,7 @@ describe('SidebarDropdownWidget', () => {
describe('with mock apollo', () => { describe('with mock apollo', () => {
let error; let error;
const mockSearchTerm = 'foobar';
beforeEach(() => { beforeEach(() => {
jest.spyOn(Sentry, 'captureException'); jest.spyOn(Sentry, 'captureException');
...@@ -155,8 +155,6 @@ describe('SidebarDropdownWidget', () => { ...@@ -155,8 +155,6 @@ describe('SidebarDropdownWidget', () => {
let groupEpicsSpy; let groupEpicsSpy;
describe('when a user is searching epics', () => { describe('when a user is searching epics', () => {
const mockSearchTerm = 'foobar';
beforeEach(async () => { beforeEach(async () => {
groupEpicsSpy = jest.fn().mockResolvedValueOnce(emptyGroupEpicsResponse); groupEpicsSpy = jest.fn().mockResolvedValueOnce(emptyGroupEpicsResponse);
await createComponentWithApollo({ groupEpicsSpy }); await createComponentWithApollo({ groupEpicsSpy });
...@@ -301,15 +299,6 @@ describe('SidebarDropdownWidget', () => { ...@@ -301,15 +299,6 @@ describe('SidebarDropdownWidget', () => {
.mockResolvedValue(mockSetWorkItemEpicNullMutationResponse); .mockResolvedValue(mockSetWorkItemEpicNullMutationResponse);
const groupWorkItemEpicsSpy = jest.fn().mockResolvedValue(mockGroupWorkItemEpicsResponse); const groupWorkItemEpicsSpy = jest.fn().mockResolvedValue(mockGroupWorkItemEpicsResponse);
it('search textbox is not displayed', async () => {
await createComponentWithApollo({
showWorkItemEpics: true,
});
await clickEdit(wrapper);
expect(findSearchBox().exists()).toBe(false);
});
describe('when hasParent is true', () => { describe('when hasParent is true', () => {
beforeEach(async () => { beforeEach(async () => {
await createComponentWithApollo({ await createComponentWithApollo({
...@@ -322,6 +311,20 @@ describe('SidebarDropdownWidget', () => { ...@@ -322,6 +311,20 @@ describe('SidebarDropdownWidget', () => {
await clickEdit(wrapper); await clickEdit(wrapper);
}); });
it('sends a groupEpics query with the entered search term "foo" and in TITLE param', async () => {
await search(wrapper, mockSearchTerm);
expect(groupWorkItemEpicsSpy).toHaveBeenCalledWith({
fullPath: mockIssue.groupPath,
sort: 'TITLE_ASC',
state: 'opened',
title: mockSearchTerm,
includeWorkItems: true,
in: 'TITLE',
types: [WORK_ITEM_TYPE_ENUM_EPIC],
});
});
it('calls work item query to fetch current work item epic', () => { it('calls work item query to fetch current work item epic', () => {
expect(currentEpicHasParentSpy).toHaveBeenCalled(); expect(currentEpicHasParentSpy).toHaveBeenCalled();
expect(currentWorkItemEpicSpy).toHaveBeenCalled(); expect(currentWorkItemEpicSpy).toHaveBeenCalled();
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册