Commit 95da7f7e authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '322755-convert-some-search-apis-from-rest-to-graphql' into 'master'

Convert filter searching to GraphQL in issues refactor

See merge request gitlab-org/gitlab!64642
parents fd3ddd35 dbf848ce
...@@ -11,6 +11,7 @@ import { ...@@ -11,6 +11,7 @@ import {
import fuzzaldrinPlus from 'fuzzaldrin-plus'; import fuzzaldrinPlus from 'fuzzaldrin-plus';
import getIssuesQuery from 'ee_else_ce/issues_list/queries/get_issues.query.graphql'; import getIssuesQuery from 'ee_else_ce/issues_list/queries/get_issues.query.graphql';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue'; import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
import IssuableByEmail from '~/issuable/components/issuable_by_email.vue'; import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
import IssuableList from '~/issuable_list/components/issuable_list_root.vue'; import IssuableList from '~/issuable_list/components/issuable_list_root.vue';
...@@ -70,6 +71,10 @@ import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label ...@@ -70,6 +71,10 @@ import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label
import MilestoneToken from '~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue'; import MilestoneToken from '~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue';
import WeightToken from '~/vue_shared/components/filtered_search_bar/tokens/weight_token.vue'; import WeightToken from '~/vue_shared/components/filtered_search_bar/tokens/weight_token.vue';
import eventHub from '../eventhub'; import eventHub from '../eventhub';
import searchIterationsQuery from '../queries/search_iterations.query.graphql';
import searchLabelsQuery from '../queries/search_labels.query.graphql';
import searchMilestonesQuery from '../queries/search_milestones.query.graphql';
import searchUsersQuery from '../queries/search_users.query.graphql';
import IssueCardTimeInfo from './issue_card_time_info.vue'; import IssueCardTimeInfo from './issue_card_time_info.vue';
export default { export default {
...@@ -94,9 +99,6 @@ export default { ...@@ -94,9 +99,6 @@ export default {
autocompleteAwardEmojisPath: { autocompleteAwardEmojisPath: {
default: '', default: '',
}, },
autocompleteUsersPath: {
default: '',
},
calendarPath: { calendarPath: {
default: '', default: '',
}, },
...@@ -118,6 +120,9 @@ export default { ...@@ -118,6 +120,9 @@ export default {
hasIssueWeightsFeature: { hasIssueWeightsFeature: {
default: false, default: false,
}, },
hasIterationsFeature: {
default: false,
},
hasMultipleIssueAssigneesFeature: { hasMultipleIssueAssigneesFeature: {
default: false, default: false,
}, },
...@@ -139,15 +144,6 @@ export default { ...@@ -139,15 +144,6 @@ export default {
newIssuePath: { newIssuePath: {
default: '', default: '',
}, },
projectIterationsPath: {
default: '',
},
projectLabelsPath: {
default: '',
},
projectMilestonesPath: {
default: '',
},
projectPath: { projectPath: {
default: '', default: '',
}, },
...@@ -233,7 +229,7 @@ export default { ...@@ -233,7 +229,7 @@ export default {
if (gon.current_user_id) { if (gon.current_user_id) {
preloadedAuthors.push({ preloadedAuthors.push({
id: gon.current_user_id, id: convertToGraphQLId('User', gon.current_user_id), // eslint-disable-line @gitlab/require-i18n-strings
name: gon.current_user_fullname, name: gon.current_user_fullname,
username: gon.current_username, username: gon.current_username,
avatar_url: gon.current_user_avatar_url, avatar_url: gon.current_user_avatar_url,
...@@ -308,7 +304,7 @@ export default { ...@@ -308,7 +304,7 @@ export default {
}); });
} }
if (this.projectIterationsPath) { if (this.hasIterationsFeature) {
tokens.push({ tokens.push({
type: TOKEN_TYPE_ITERATION, type: TOKEN_TYPE_ITERATION,
title: TOKEN_TITLE_ITERATION, title: TOKEN_TITLE_ITERATION,
...@@ -407,19 +403,42 @@ export default { ...@@ -407,19 +403,42 @@ export default {
: epics.filter((epic) => epic.id === number); : epics.filter((epic) => epic.id === number);
}, },
fetchLabels(search) { fetchLabels(search) {
return this.fetchWithCache(this.projectLabelsPath, 'labels', 'title', search); return this.$apollo
.query({
query: searchLabelsQuery,
variables: { projectPath: this.projectPath, search },
})
.then(({ data }) => data.project.labels.nodes);
}, },
fetchMilestones(search) { fetchMilestones(search) {
return this.fetchWithCache(this.projectMilestonesPath, 'milestones', 'title', search, true); return this.$apollo
.query({
query: searchMilestonesQuery,
variables: { projectPath: this.projectPath, search },
})
.then(({ data }) => data.project.milestones.nodes);
}, },
fetchIterations(search) { fetchIterations(search) {
const id = Number(search); const id = Number(search);
return !search || Number.isNaN(id) const variables =
? axios.get(this.projectIterationsPath, { params: { search } }) !search || Number.isNaN(id)
: axios.get(this.projectIterationsPath, { params: { id } }); ? { projectPath: this.projectPath, search }
: { projectPath: this.projectPath, id };
return this.$apollo
.query({
query: searchIterationsQuery,
variables,
})
.then(({ data }) => data.project.iterations.nodes);
}, },
fetchUsers(search) { fetchUsers(search) {
return axios.get(this.autocompleteUsersPath, { params: { search } }); return this.$apollo
.query({
query: searchUsersQuery,
variables: { projectPath: this.projectPath, search },
})
.then(({ data }) => data.project.projectMembers.nodes.map((member) => member.user));
}, },
getExportCsvPathWithQuery() { getExportCsvPathWithQuery() {
return `${this.exportCsvPath}${window.location.search}`; return `${this.exportCsvPath}${window.location.search}`;
......
...@@ -82,7 +82,6 @@ export function mountIssuesListApp() { ...@@ -82,7 +82,6 @@ export function mountIssuesListApp() {
const { const {
autocompleteAwardEmojisPath, autocompleteAwardEmojisPath,
autocompleteUsersPath,
calendarPath, calendarPath,
canBulkUpdate, canBulkUpdate,
canEdit, canEdit,
...@@ -95,6 +94,7 @@ export function mountIssuesListApp() { ...@@ -95,6 +94,7 @@ export function mountIssuesListApp() {
hasBlockedIssuesFeature, hasBlockedIssuesFeature,
hasIssuableHealthStatusFeature, hasIssuableHealthStatusFeature,
hasIssueWeightsFeature, hasIssueWeightsFeature,
hasIterationsFeature,
hasMultipleIssueAssigneesFeature, hasMultipleIssueAssigneesFeature,
hasProjectIssues, hasProjectIssues,
importCsvIssuesPath, importCsvIssuesPath,
...@@ -106,9 +106,6 @@ export function mountIssuesListApp() { ...@@ -106,9 +106,6 @@ export function mountIssuesListApp() {
maxAttachmentSize, maxAttachmentSize,
newIssuePath, newIssuePath,
projectImportJiraPath, projectImportJiraPath,
projectIterationsPath,
projectLabelsPath,
projectMilestonesPath,
projectPath, projectPath,
quickActionsHelpPath, quickActionsHelpPath,
resetPath, resetPath,
...@@ -122,7 +119,6 @@ export function mountIssuesListApp() { ...@@ -122,7 +119,6 @@ export function mountIssuesListApp() {
apolloProvider, apolloProvider,
provide: { provide: {
autocompleteAwardEmojisPath, autocompleteAwardEmojisPath,
autocompleteUsersPath,
calendarPath, calendarPath,
canBulkUpdate: parseBoolean(canBulkUpdate), canBulkUpdate: parseBoolean(canBulkUpdate),
emptyStateSvgPath, emptyStateSvgPath,
...@@ -130,15 +126,13 @@ export function mountIssuesListApp() { ...@@ -130,15 +126,13 @@ export function mountIssuesListApp() {
hasBlockedIssuesFeature: parseBoolean(hasBlockedIssuesFeature), hasBlockedIssuesFeature: parseBoolean(hasBlockedIssuesFeature),
hasIssuableHealthStatusFeature: parseBoolean(hasIssuableHealthStatusFeature), hasIssuableHealthStatusFeature: parseBoolean(hasIssuableHealthStatusFeature),
hasIssueWeightsFeature: parseBoolean(hasIssueWeightsFeature), hasIssueWeightsFeature: parseBoolean(hasIssueWeightsFeature),
hasIterationsFeature: parseBoolean(hasIterationsFeature),
hasMultipleIssueAssigneesFeature: parseBoolean(hasMultipleIssueAssigneesFeature), hasMultipleIssueAssigneesFeature: parseBoolean(hasMultipleIssueAssigneesFeature),
hasProjectIssues: parseBoolean(hasProjectIssues), hasProjectIssues: parseBoolean(hasProjectIssues),
isSignedIn: parseBoolean(isSignedIn), isSignedIn: parseBoolean(isSignedIn),
issuesPath, issuesPath,
jiraIntegrationPath, jiraIntegrationPath,
newIssuePath, newIssuePath,
projectIterationsPath,
projectLabelsPath,
projectMilestonesPath,
projectPath, projectPath,
rssPath, rssPath,
showNewIssueLink: parseBoolean(showNewIssueLink), showNewIssueLink: parseBoolean(showNewIssueLink),
......
query searchIterations($projectPath: ID!, $search: String, $id: ID) {
project(fullPath: $projectPath) {
iterations(title: $search, id: $id) {
nodes {
id
title
}
}
}
}
query searchLabels($projectPath: ID!, $search: String) {
project(fullPath: $projectPath) {
labels(searchTerm: $search, includeAncestorGroups: true) {
nodes {
id
color
textColor
title
}
}
}
}
query searchMilestones($projectPath: ID!, $search: String) {
project(fullPath: $projectPath) {
milestones(searchTitle: $search, includeAncestors: true) {
nodes {
id
title
}
}
}
}
query searchUsers($projectPath: ID!, $search: String) {
project(fullPath: $projectPath) {
projectMembers(search: $search) {
nodes {
user {
id
avatarUrl
name
username
}
}
}
}
}
...@@ -6,6 +6,7 @@ import { ...@@ -6,6 +6,7 @@ import {
GlDropdownSectionHeader, GlDropdownSectionHeader,
GlLoadingIcon, GlLoadingIcon,
} from '@gitlab/ui'; } from '@gitlab/ui';
import { debounce } from 'lodash';
import { DEBOUNCE_DELAY } from '../constants'; import { DEBOUNCE_DELAY } from '../constants';
import { getRecentlyUsedSuggestions, setTokenValueToRecentlyUsed } from '../filtered_search_utils'; import { getRecentlyUsedSuggestions, setTokenValueToRecentlyUsed } from '../filtered_search_utils';
...@@ -128,12 +129,12 @@ export default { ...@@ -128,12 +129,12 @@ export default {
}, },
}, },
methods: { methods: {
handleInput({ data }) { handleInput: debounce(function debouncedSearch({ data }) {
this.searchKey = data; this.searchKey = data;
setTimeout(() => { if (!this.suggestionsLoading) {
if (!this.suggestionsLoading) this.$emit('fetch-suggestions', data); this.$emit('fetch-suggestions', data);
}, DEBOUNCE_DELAY); }
}, }, DEBOUNCE_DELAY),
handleTokenValueSelected(activeTokenValue) { handleTokenValueSelected(activeTokenValue) {
// Make sure that; // Make sure that;
// 1. Recently used values feature is enabled // 1. Recently used values feature is enabled
......
...@@ -7,6 +7,7 @@ import { ...@@ -7,6 +7,7 @@ import {
} from '@gitlab/ui'; } from '@gitlab/ui';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { DEBOUNCE_DELAY, DEFAULT_ITERATIONS } from '../constants'; import { DEBOUNCE_DELAY, DEFAULT_ITERATIONS } from '../constants';
...@@ -30,7 +31,7 @@ export default { ...@@ -30,7 +31,7 @@ export default {
data() { data() {
return { return {
iterations: this.config.initialIterations || [], iterations: this.config.initialIterations || [],
loading: true, loading: false,
}; };
}, },
computed: { computed: {
...@@ -38,7 +39,9 @@ export default { ...@@ -38,7 +39,9 @@ export default {
return this.value.data; return this.value.data;
}, },
activeIteration() { activeIteration() {
return this.iterations.find((iteration) => iteration.id === Number(this.currentValue)); return this.iterations.find(
(iteration) => getIdFromGraphQLId(iteration.id) === Number(this.currentValue),
);
}, },
defaultIterations() { defaultIterations() {
return this.config.defaultIterations || DEFAULT_ITERATIONS; return this.config.defaultIterations || DEFAULT_ITERATIONS;
...@@ -55,6 +58,9 @@ export default { ...@@ -55,6 +58,9 @@ export default {
}, },
}, },
methods: { methods: {
getValue(iteration) {
return String(getIdFromGraphQLId(iteration.id));
},
fetchIterationBySearchTerm(searchTerm) { fetchIterationBySearchTerm(searchTerm) {
const fetchPromise = this.config.fetchPath const fetchPromise = this.config.fetchPath
? this.config.fetchIterations(this.config.fetchPath, searchTerm) ? this.config.fetchIterations(this.config.fetchPath, searchTerm)
...@@ -102,7 +108,7 @@ export default { ...@@ -102,7 +108,7 @@ export default {
<gl-filtered-search-suggestion <gl-filtered-search-suggestion
v-for="iteration in iterations" v-for="iteration in iterations"
:key="iteration.id" :key="iteration.id"
:value="String(iteration.id)" :value="getValue(iteration)"
> >
{{ iteration.title }} {{ iteration.title }}
</gl-filtered-search-suggestion> </gl-filtered-search-suggestion>
......
...@@ -35,7 +35,7 @@ export default { ...@@ -35,7 +35,7 @@ export default {
return { return {
milestones: this.config.initialMilestones || [], milestones: this.config.initialMilestones || [],
defaultMilestones: this.config.defaultMilestones || DEFAULT_MILESTONES, defaultMilestones: this.config.defaultMilestones || DEFAULT_MILESTONES,
loading: true, loading: false,
}; };
}, },
computed: { computed: {
...@@ -60,11 +60,16 @@ export default { ...@@ -60,11 +60,16 @@ export default {
}, },
methods: { methods: {
fetchMilestoneBySearchTerm(searchTerm = '') { fetchMilestoneBySearchTerm(searchTerm = '') {
if (this.loading) {
return;
}
this.loading = true; this.loading = true;
this.config this.config
.fetchMilestones(searchTerm) .fetchMilestones(searchTerm)
.then(({ data }) => { .then((response) => {
this.milestones = data.sort(sortMilestonesByDueDate); const data = Array.isArray(response) ? response : response.data;
this.milestones = data.slice().sort(sortMilestonesByDueDate);
}) })
.catch(() => createFlash({ message: __('There was a problem fetching milestones.') })) .catch(() => createFlash({ message: __('There was a problem fetching milestones.') }))
.finally(() => { .finally(() => {
......
...@@ -181,7 +181,6 @@ module IssuesHelper ...@@ -181,7 +181,6 @@ module IssuesHelper
def issues_list_data(project, current_user, finder) def issues_list_data(project, current_user, finder)
{ {
autocomplete_users_path: autocomplete_users_path(active: true, current_user: true, project_id: project.id, format: :json),
autocomplete_award_emojis_path: autocomplete_award_emojis_path, autocomplete_award_emojis_path: autocomplete_award_emojis_path,
calendar_path: url_for(safe_params.merge(calendar_url_options)), calendar_path: url_for(safe_params.merge(calendar_url_options)),
can_bulk_update: can?(current_user, :admin_issue, project).to_s, can_bulk_update: can?(current_user, :admin_issue, project).to_s,
...@@ -201,8 +200,6 @@ module IssuesHelper ...@@ -201,8 +200,6 @@ module IssuesHelper
max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes), max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes),
new_issue_path: new_project_issue_path(project, issue: { milestone_id: finder.milestones.first.try(:id) }), new_issue_path: new_project_issue_path(project, issue: { milestone_id: finder.milestones.first.try(:id) }),
project_import_jira_path: project_import_jira_path(project), project_import_jira_path: project_import_jira_path(project),
project_labels_path: project_labels_path(project, include_ancestor_groups: true, format: :json),
project_milestones_path: project_milestones_path(project, format: :json),
project_path: project.full_path, project_path: project.full_path,
quick_actions_help_path: help_page_path('user/project/quick_actions'), quick_actions_help_path: help_page_path('user/project/quick_actions'),
reset_path: new_issuable_address_project_path(project, issuable_type: 'issue'), reset_path: new_issuable_address_project_path(project, issuable_type: 'issue'),
......
...@@ -48,6 +48,7 @@ module EE ...@@ -48,6 +48,7 @@ module EE
has_blocked_issues_feature: project.feature_available?(:blocked_issues).to_s, has_blocked_issues_feature: project.feature_available?(:blocked_issues).to_s,
has_issuable_health_status_feature: project.feature_available?(:issuable_health_status).to_s, has_issuable_health_status_feature: project.feature_available?(:issuable_health_status).to_s,
has_issue_weights_feature: project.feature_available?(:issue_weights).to_s, has_issue_weights_feature: project.feature_available?(:issue_weights).to_s,
has_iterations_feature: project.feature_available?(:iterations).to_s,
has_multiple_issue_assignees_feature: project.feature_available?(:multiple_issue_assignees).to_s has_multiple_issue_assignees_feature: project.feature_available?(:multiple_issue_assignees).to_s
) )
...@@ -55,10 +56,6 @@ module EE ...@@ -55,10 +56,6 @@ module EE
data[:group_epics_path] = group_epics_path(project.group, format: :json) data[:group_epics_path] = group_epics_path(project.group, format: :json)
end end
if project.feature_available?(:iterations)
data[:project_iterations_path] = api_v4_projects_iterations_path(id: project.id)
end
data data
end end
end end
......
...@@ -145,9 +145,9 @@ RSpec.describe EE::IssuesHelper do ...@@ -145,9 +145,9 @@ RSpec.describe EE::IssuesHelper do
has_blocked_issues_feature: 'true', has_blocked_issues_feature: 'true',
has_issuable_health_status_feature: 'true', has_issuable_health_status_feature: 'true',
has_issue_weights_feature: 'true', has_issue_weights_feature: 'true',
has_iterations_feature: 'true',
has_multiple_issue_assignees_feature: 'true', has_multiple_issue_assignees_feature: 'true',
group_epics_path: group_epics_path(project.group, format: :json), group_epics_path: group_epics_path(project.group, format: :json)
project_iterations_path: api_v4_projects_iterations_path(id: project.id)
} }
expect(helper.issues_list_data(project, current_user, finder)).to include(expected) expect(helper.issues_list_data(project, current_user, finder)).to include(expected)
...@@ -172,6 +172,7 @@ RSpec.describe EE::IssuesHelper do ...@@ -172,6 +172,7 @@ RSpec.describe EE::IssuesHelper do
has_blocked_issues_feature: 'false', has_blocked_issues_feature: 'false',
has_issuable_health_status_feature: 'false', has_issuable_health_status_feature: 'false',
has_issue_weights_feature: 'false', has_issue_weights_feature: 'false',
has_iterations_feature: 'false',
has_multiple_issue_assignees_feature: 'false' has_multiple_issue_assignees_feature: 'false'
} }
...@@ -179,7 +180,6 @@ RSpec.describe EE::IssuesHelper do ...@@ -179,7 +180,6 @@ RSpec.describe EE::IssuesHelper do
expect(result).to include(expected) expect(result).to include(expected)
expect(result).not_to include(:group_epics_path) expect(result).not_to include(:group_epics_path)
expect(result).not_to include(:project_iterations_path)
end end
end end
end end
......
...@@ -15,6 +15,7 @@ import { ...@@ -15,6 +15,7 @@ import {
urlParams, urlParams,
} from 'jest/issues_list/mock_data'; } from 'jest/issues_list/mock_data';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue'; import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
import IssuableByEmail from '~/issuable/components/issuable_by_email.vue'; import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
import IssuableList from '~/issuable_list/components/issuable_list_root.vue'; import IssuableList from '~/issuable_list/components/issuable_list_root.vue';
...@@ -54,19 +55,18 @@ describe('IssuesListApp component', () => { ...@@ -54,19 +55,18 @@ describe('IssuesListApp component', () => {
localVue.use(VueApollo); localVue.use(VueApollo);
const defaultProvide = { const defaultProvide = {
autocompleteUsersPath: 'autocomplete/users/path',
calendarPath: 'calendar/path', calendarPath: 'calendar/path',
canBulkUpdate: false, canBulkUpdate: false,
emptyStateSvgPath: 'empty-state.svg', emptyStateSvgPath: 'empty-state.svg',
exportCsvPath: 'export/csv/path', exportCsvPath: 'export/csv/path',
hasBlockedIssuesFeature: true, hasBlockedIssuesFeature: true,
hasIssueWeightsFeature: true, hasIssueWeightsFeature: true,
hasIterationsFeature: true,
hasProjectIssues: true, hasProjectIssues: true,
isSignedIn: false, isSignedIn: false,
issuesPath: 'path/to/issues', issuesPath: 'path/to/issues',
jiraIntegrationPath: 'jira/integration/path', jiraIntegrationPath: 'jira/integration/path',
newIssuePath: 'new/issue/path', newIssuePath: 'new/issue/path',
projectLabelsPath: 'project/labels/path',
projectPath: 'path/to/project', projectPath: 'path/to/project',
rssPath: 'rss/path', rssPath: 'rss/path',
showNewIssueLink: true, showNewIssueLink: true,
...@@ -545,9 +545,13 @@ describe('IssuesListApp component', () => { ...@@ -545,9 +545,13 @@ describe('IssuesListApp component', () => {
}); });
it('renders all tokens', () => { it('renders all tokens', () => {
const preloadedAuthors = [
{ ...mockCurrentUser, id: convertToGraphQLId('User', mockCurrentUser.id) },
];
expect(findIssuableList().props('searchTokens')).toMatchObject([ expect(findIssuableList().props('searchTokens')).toMatchObject([
{ type: TOKEN_TYPE_AUTHOR, preloadedAuthors: [mockCurrentUser] }, { type: TOKEN_TYPE_AUTHOR, preloadedAuthors },
{ type: TOKEN_TYPE_ASSIGNEE, preloadedAuthors: [mockCurrentUser] }, { type: TOKEN_TYPE_ASSIGNEE, preloadedAuthors },
{ type: TOKEN_TYPE_MILESTONE }, { type: TOKEN_TYPE_MILESTONE },
{ type: TOKEN_TYPE_LABEL }, { type: TOKEN_TYPE_LABEL },
{ type: TOKEN_TYPE_MY_REACTION }, { type: TOKEN_TYPE_MY_REACTION },
......
...@@ -294,7 +294,6 @@ RSpec.describe IssuesHelper do ...@@ -294,7 +294,6 @@ RSpec.describe IssuesHelper do
expected = { expected = {
autocomplete_award_emojis_path: autocomplete_award_emojis_path, autocomplete_award_emojis_path: autocomplete_award_emojis_path,
autocomplete_users_path: autocomplete_users_path(active: true, current_user: true, project_id: project.id, format: :json),
calendar_path: '#', calendar_path: '#',
can_bulk_update: 'true', can_bulk_update: 'true',
can_edit: 'true', can_edit: 'true',
...@@ -313,8 +312,6 @@ RSpec.describe IssuesHelper do ...@@ -313,8 +312,6 @@ RSpec.describe IssuesHelper do
max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes), max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes),
new_issue_path: new_project_issue_path(project, issue: { milestone_id: finder.milestones.first.id }), new_issue_path: new_project_issue_path(project, issue: { milestone_id: finder.milestones.first.id }),
project_import_jira_path: project_import_jira_path(project), project_import_jira_path: project_import_jira_path(project),
project_labels_path: project_labels_path(project, include_ancestor_groups: true, format: :json),
project_milestones_path: project_milestones_path(project, format: :json),
project_path: project.full_path, project_path: project.full_path,
quick_actions_help_path: help_page_path('user/project/quick_actions'), quick_actions_help_path: help_page_path('user/project/quick_actions'),
reset_path: new_issuable_address_project_path(project, issuable_type: 'issue'), reset_path: new_issuable_address_project_path(project, issuable_type: 'issue'),
......
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