Commit 5dea2792 authored by Peter Leitzen's avatar Peter Leitzen

Merge branch '244939-epics-issues-realted-filter' into 'master'

Filter out incidents in related issues from epics

See merge request gitlab-org/gitlab!41807
parents 7bc75068 21c5073c
import { issuableTypesMap, PathIdSeparator } from '~/related_issues/constants'; import { issuableTypesMap, PathIdSeparator } from '~/related_issues/constants';
import { processIssueTypeIssueSources } from '../utils/epic_utils';
export const autoCompleteSources = () => gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources; export const autoCompleteSources = () => gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources;
...@@ -11,6 +12,14 @@ export const itemAutoCompleteSources = (state, getters) => { ...@@ -11,6 +12,14 @@ export const itemAutoCompleteSources = (state, getters) => {
if (getters.isEpic) { if (getters.isEpic) {
return state.autoCompleteEpics ? getters.autoCompleteSources : {}; return state.autoCompleteEpics ? getters.autoCompleteSources : {};
} }
if (state.issuesEndpoint.includes('epics')) {
return {
...getters.autoCompleteSources,
issues: processIssueTypeIssueSources(['issue'], getters.autoCompleteSources),
};
}
return state.autoCompleteIssues ? getters.autoCompleteSources : {}; return state.autoCompleteIssues ? getters.autoCompleteSources : {};
}; };
......
import { PathIdSeparator } from '~/related_issues/constants'; import { PathIdSeparator } from '~/related_issues/constants';
import { mergeUrlParams } from '~/lib/utils/url_utility';
import createGqClient, { fetchPolicies } from '~/lib/graphql'; import createGqClient, { fetchPolicies } from '~/lib/graphql';
import { ChildType } from '../constants'; import { ChildType } from '../constants';
...@@ -101,3 +102,16 @@ export const extractChildIssues = issues => ...@@ -101,3 +102,16 @@ export const extractChildIssues = issues =>
*/ */
export const processQueryResponse = ({ epic }) => export const processQueryResponse = ({ epic }) =>
applySorts([...extractChildEpics(epic.children), ...extractChildIssues(epic.issues)]); applySorts([...extractChildEpics(epic.children), ...extractChildIssues(epic.issues)]);
/**
* Returns formatted query string with the supplied issue_types
* to be used for autoCompleteSources issues
*
* @param {Array} issueTypes
* @param {Object} autoCompleteSources
* @return {String} autoCompleteSources
*/
export const processIssueTypeIssueSources = (issueTypes, autoCompleteSources) =>
autoCompleteSources.issues
? mergeUrlParams({ issue_types: issueTypes }, autoCompleteSources.issues)
: '';
...@@ -9,7 +9,7 @@ class Groups::AutocompleteSourcesController < Groups::ApplicationController ...@@ -9,7 +9,7 @@ class Groups::AutocompleteSourcesController < Groups::ApplicationController
def issues def issues
render json: issuable_serializer.represent( render json: issuable_serializer.represent(
@autocomplete_service.issues(confidential_only: params[:confidential_only]), @autocomplete_service.issues(confidential_only: params[:confidential_only], issue_types: params[:issue_types]),
parent_group: @group parent_group: @group
) )
end end
......
...@@ -5,9 +5,10 @@ module Groups ...@@ -5,9 +5,10 @@ module Groups
include LabelsAsHash include LabelsAsHash
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def issues(confidential_only: false) def issues(confidential_only: false, issue_types: nil)
finder_params = { group_id: group.id, include_subgroups: true, state: 'opened' } finder_params = { group_id: group.id, include_subgroups: true, state: 'opened' }
finder_params[:confidential] = true if confidential_only.present? finder_params[:confidential] = true if confidential_only.present?
finder_params[:issue_types] = issue_types if issue_types.present?
IssuesFinder.new(current_user, finder_params) IssuesFinder.new(current_user, finder_params)
.execute .execute
......
---
title: Filter out incidents from related issues in epics
merge_request: 41807
author:
type: changed
...@@ -3,12 +3,15 @@ ...@@ -3,12 +3,15 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Groups::AutocompleteSourcesController do RSpec.describe Groups::AutocompleteSourcesController do
let(:user) { create(:user) } let_it_be(:user) { create(:user) }
let(:group) { create(:group, :private) } let_it_be_with_reload(:group) { create(:group, :private) }
let!(:epic) { create(:epic, group: group) } let_it_be(:epic) { create(:epic, group: group) }
before do before_all do
group.add_developer(user) group.add_developer(user)
end
before do
stub_licensed_features(epics: true) stub_licensed_features(epics: true)
sign_in(user) sign_in(user)
end end
...@@ -30,6 +33,41 @@ RSpec.describe Groups::AutocompleteSourcesController do ...@@ -30,6 +33,41 @@ RSpec.describe Groups::AutocompleteSourcesController do
end end
end end
describe '#issues' do
using RSpec::Parameterized::TableSyntax
let_it_be(:project) { create(:project, group: group) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:incident) { create(:incident, project: project) }
let_it_be(:test_case) { create(:quality_test_case, project: project) }
let(:none) { [] }
let(:all) { [issue, incident, test_case] }
where(:issue_types, :expected) do
nil | :all
'' | :all
'invalid' | :none
'issue' | :issue
'incident' | :incident
'test_case' | :test_case
end
with_them do
it 'returns the correct response', :aggregate_failures do
issues = Array(expected).flat_map { |sym| public_send(sym) }
params = { group_id: group, issue_types: issue_types }.compact
get :issues, params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an(Array)
expect(json_response.size).to eq(issues.size)
expect(json_response.map { |issue| issue['iid'] })
.to match_array(issues.map(&:iid))
end
end
end
describe '#milestones' do describe '#milestones' do
it 'returns correct response' do it 'returns correct response' do
parent_group = create(:group, :private) parent_group = create(:group, :private)
......
...@@ -90,6 +90,28 @@ describe('RelatedItemsTree', () => { ...@@ -90,6 +90,28 @@ describe('RelatedItemsTree', () => {
expect.objectContaining({}), expect.objectContaining({}),
); );
}); });
it('returns autoCompleteSources with a formatted issue_type query URL for issues when parent is epic', () => {
const mockGetter = {
autoCompleteSources: {
issues: 'foo',
},
};
state.issuesEndpoint = '/epics';
state.issuableType = issuableTypesMap.Issue;
state.autoCompleteIssues = true;
expect(getters.itemAutoCompleteSources(state, mockGetter)).toEqual({
issues: 'foo?issue_types=issue',
});
state.issuesEndpoint = '/';
state.autoCompleteEpics = false;
expect(getters.itemAutoCompleteSources(state, mockGetter)).toEqual({
issues: 'foo',
});
});
}); });
describe('itemPathIdSeparator', () => { describe('itemPathIdSeparator', () => {
......
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