Commit 7c7bcd85 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'cngo-issues-list-sort-milestones' into 'master'

Sort milestones correctly on project/issues list refactor

See merge request gitlab-org/gitlab!79945
parents c5dfee02 1beed5d9
......@@ -10,16 +10,30 @@ import {
} from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import { orderBy } from 'lodash';
import IssueCardTimeInfo from 'ee_else_ce/issues/list/components/issue_card_time_info.vue';
import getIssuesQuery from 'ee_else_ce/issues/list/queries/get_issues.query.graphql';
import getIssuesCountsQuery from 'ee_else_ce/issues/list/queries/get_issues_counts.query.graphql';
import IssueCardTimeInfo from 'ee_else_ce/issues/list/components/issue_card_time_info.vue';
import createFlash, { FLASH_TYPES } from '~/flash';
import { TYPE_USER } from '~/graphql_shared/constants';
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
import { ITEM_TYPE } from '~/groups/constants';
import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
import axios from '~/lib/utils/axios_utils';
import { scrollUp } from '~/lib/utils/scroll_utils';
import { getParameterByName, joinPaths } from '~/lib/utils/url_utility';
import {
DEFAULT_NONE_ANY,
OPERATOR_IS_ONLY,
TOKEN_TITLE_ASSIGNEE,
TOKEN_TITLE_AUTHOR,
TOKEN_TITLE_CONFIDENTIAL,
TOKEN_TITLE_LABEL,
TOKEN_TITLE_MILESTONE,
TOKEN_TITLE_MY_REACTION,
TOKEN_TITLE_RELEASE,
TOKEN_TITLE_TYPE,
} from '~/vue_shared/components/filtered_search_bar/constants';
import IssuableList from '~/vue_shared/issuable/list/components/issuable_list_root.vue';
import { IssuableListTabs, IssuableStates } from '~/vue_shared/issuable/list/constants';
import {
......@@ -40,7 +54,13 @@ import {
TOKEN_TYPE_TYPE,
UPDATED_DESC,
urlSortParams,
} from '~/issues/list/constants';
} from '../constants';
import eventHub from '../eventhub';
import reorderIssuesMutation from '../queries/reorder_issues.mutation.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 setSortPreferenceMutation from '../queries/set_sort_preference.mutation.graphql';
import {
convertToApiParams,
convertToSearchQuery,
......@@ -50,28 +70,7 @@ import {
getInitialPageParams,
getSortKey,
getSortOptions,
} from '~/issues/list/utils';
import axios from '~/lib/utils/axios_utils';
import { scrollUp } from '~/lib/utils/scroll_utils';
import { getParameterByName, joinPaths } from '~/lib/utils/url_utility';
import {
DEFAULT_NONE_ANY,
OPERATOR_IS_ONLY,
TOKEN_TITLE_ASSIGNEE,
TOKEN_TITLE_AUTHOR,
TOKEN_TITLE_CONFIDENTIAL,
TOKEN_TITLE_LABEL,
TOKEN_TITLE_MILESTONE,
TOKEN_TITLE_MY_REACTION,
TOKEN_TITLE_RELEASE,
TOKEN_TITLE_TYPE,
} from '~/vue_shared/components/filtered_search_bar/constants';
import eventHub from '../eventhub';
import reorderIssuesMutation from '../queries/reorder_issues.mutation.graphql';
import setSortPreferenceMutation from '../queries/set_sort_preference.mutation.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';
} from '../utils';
import NewIssueDropdown from './new_issue_dropdown.vue';
const AuthorToken = () =>
......@@ -103,77 +102,31 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
inject: {
autocompleteAwardEmojisPath: {
default: '',
},
calendarPath: {
default: '',
},
canBulkUpdate: {
default: false,
},
emptyStateSvgPath: {
default: '',
},
exportCsvPath: {
default: '',
},
fullPath: {
default: '',
},
hasAnyIssues: {
default: false,
},
hasAnyProjects: {
default: false,
},
hasBlockedIssuesFeature: {
default: false,
},
hasIssueWeightsFeature: {
default: false,
},
hasMultipleIssueAssigneesFeature: {
default: false,
},
initialEmail: {
default: '',
},
initialSort: {
default: '',
},
isAnonymousSearchDisabled: {
default: false,
},
isIssueRepositioningDisabled: {
default: false,
},
isProject: {
default: false,
},
isSignedIn: {
default: false,
},
jiraIntegrationPath: {
default: '',
},
newIssuePath: {
default: '',
},
releasesPath: {
default: '',
},
rssPath: {
default: '',
},
showNewIssueLink: {
default: false,
},
signInPath: {
default: '',
},
},
inject: [
'autocompleteAwardEmojisPath',
'calendarPath',
'canBulkUpdate',
'emptyStateSvgPath',
'exportCsvPath',
'fullPath',
'hasAnyIssues',
'hasAnyProjects',
'hasBlockedIssuesFeature',
'hasIssueWeightsFeature',
'hasMultipleIssueAssigneesFeature',
'initialEmail',
'initialSort',
'isAnonymousSearchDisabled',
'isIssueRepositioningDisabled',
'isProject',
'isSignedIn',
'jiraIntegrationPath',
'newIssuePath',
'releasesPath',
'rssPath',
'showNewIssueLink',
'signInPath',
],
props: {
eeSearchTokens: {
type: Array,
......@@ -349,6 +302,7 @@ export default {
token: MilestoneToken,
fetchMilestones: this.fetchMilestones,
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-milestone`,
shouldSkipSort: true,
},
{
type: TOKEN_TYPE_LABEL,
......@@ -414,7 +368,7 @@ export default {
tokens.sort((a, b) => a.title.localeCompare(b.title));
return orderBy(tokens, ['title']);
return tokens;
},
showPaginationControls() {
return this.issues.length > 0 && (this.pageInfo.hasNextPage || this.pageInfo.hasPreviousPage);
......
......@@ -7,10 +7,10 @@ import {
GlSearchBoxByType,
} from '@gitlab/ui';
import createFlash from '~/flash';
import searchProjectsQuery from '~/issues/list/queries/search_projects.query.graphql';
import { DASH_SCOPE, joinPaths } from '~/lib/utils/url_utility';
import { __, sprintf } from '~/locale';
import { DEBOUNCE_DELAY } from '~/vue_shared/components/filtered_search_bar/constants';
import searchProjectsQuery from '../queries/search_projects.query.graphql';
export default {
i18n: {
......
......@@ -3,7 +3,12 @@
query searchMilestones($fullPath: ID!, $search: String, $isProject: Boolean = false) {
group(fullPath: $fullPath) @skip(if: $isProject) {
id
milestones(searchTitle: $search, includeAncestors: true, includeDescendants: true) {
milestones(
searchTitle: $search
includeAncestors: true
includeDescendants: true
sort: EXPIRED_LAST_DUE_DATE_ASC
) {
nodes {
...Milestone
}
......@@ -11,7 +16,7 @@ query searchMilestones($fullPath: ID!, $search: String, $isProject: Boolean = fa
}
project(fullPath: $fullPath) @include(if: $isProject) {
id
milestones(searchTitle: $search, includeAncestors: true) {
milestones(searchTitle: $search, includeAncestors: true, sort: EXPIRED_LAST_DUE_DATE_ASC) {
nodes {
...Milestone
}
......
import { isPositiveInteger } from '~/lib/utils/number_utils';
import { __ } from '~/locale';
import {
FILTERED_SEARCH_TERM,
OPERATOR_IS_NOT,
} from '~/vue_shared/components/filtered_search_bar/constants';
import {
API_PARAM,
BLOCKING_ISSUES_ASC,
......@@ -36,13 +42,7 @@ import {
urlSortParams,
WEIGHT_ASC,
WEIGHT_DESC,
} from '~/issues/list/constants';
import { isPositiveInteger } from '~/lib/utils/number_utils';
import { __ } from '~/locale';
import {
FILTERED_SEARCH_TERM,
OPERATOR_IS_NOT,
} from '~/vue_shared/components/filtered_search_bar/constants';
} from './constants';
export const getInitialPageParams = (sortKey) =>
sortKey === RELATIVE_POSITION_ASC ? largePageSizeParams : defaultPageSizeParams;
......
......@@ -22,23 +22,7 @@ export default {
BlockingIssuesCount,
IssuesListApp,
},
inject: {
fullPath: {
default: '',
},
groupPath: {
default: '',
},
hasIssueWeightsFeature: {
default: false,
},
hasIterationsFeature: {
default: false,
},
isProject: {
default: false,
},
},
inject: ['fullPath', 'groupPath', 'hasIssueWeightsFeature', 'hasIterationsFeature', 'isProject'],
computed: {
namespace() {
return this.isProject ? ITEM_TYPE.PROJECT : ITEM_TYPE.GROUP;
......
......@@ -10,6 +10,7 @@ import { getIssuesCountsQueryResponse, getIssuesQueryResponse } from 'jest/issue
import { convertToGraphQLId } from '~/graphql_shared/utils';
import IssuableList from '~/vue_shared/issuable/list/components/issuable_list_root.vue';
import {
CREATED_DESC,
TOKEN_TYPE_ASSIGNEE,
TOKEN_TYPE_AUTHOR,
TOKEN_TYPE_CONFIDENTIAL,
......@@ -30,6 +31,35 @@ describe('EE IssuesListApp component', () => {
Vue.use(VueApollo);
const defaultProvide = {
autocompleteAwardEmojisPath: 'autocomplete/award/emojis/path',
calendarPath: 'calendar/path',
canBulkUpdate: false,
emptyStateSvgPath: 'empty-state.svg',
exportCsvPath: 'export/csv/path',
fullPath: 'path/to/project',
groupPath: 'group/path',
hasAnyIssues: true,
hasAnyProjects: true,
hasBlockedIssuesFeature: true,
hasIssuableHealthStatusFeature: true,
hasIssueWeightsFeature: true,
hasIterationsFeature: true,
hasMultipleIssueAssigneesFeature: true,
initialEmail: 'email@example.com',
initialSort: CREATED_DESC,
isAnonymousSearchDisabled: false,
isIssueRepositioningDisabled: false,
isProject: true,
isSignedIn: true,
jiraIntegrationPath: 'jira/integration/path',
newIssuePath: 'new/issue/path',
releasesPath: 'releases/path',
rssPath: 'rss/path',
showNewIssueLink: true,
signInPath: 'sign/in/path',
};
const defaultQueryResponse = cloneDeep(getIssuesQueryResponse);
defaultQueryResponse.data.project.issues.nodes[0].blockingCount = 1;
defaultQueryResponse.data.project.issues.nodes[0].healthStatus = null;
......@@ -51,9 +81,7 @@ describe('EE IssuesListApp component', () => {
return mount(IssuesListApp, {
apolloProvider,
provide: {
hasAnyIssues: true,
hasIssuableHealthStatusFeature: true,
isProject: true,
...defaultProvide,
...provide,
},
});
......
......@@ -62,6 +62,7 @@ describe('CE IssuesListApp component', () => {
Vue.use(VueApollo);
const defaultProvide = {
autocompleteAwardEmojisPath: 'autocomplete/award/emojis/path',
calendarPath: 'calendar/path',
canBulkUpdate: false,
emptyStateSvgPath: 'empty-state.svg',
......@@ -73,10 +74,16 @@ describe('CE IssuesListApp component', () => {
hasIssuableHealthStatusFeature: true,
hasIssueWeightsFeature: true,
hasIterationsFeature: true,
hasMultipleIssueAssigneesFeature: true,
initialEmail: 'email@example.com',
initialSort: CREATED_DESC,
isAnonymousSearchDisabled: false,
isIssueRepositioningDisabled: false,
isProject: true,
isSignedIn: true,
jiraIntegrationPath: 'jira/integration/path',
newIssuePath: 'new/issue/path',
releasesPath: 'releases/path',
rssPath: 'rss/path',
showNewIssueLink: true,
signInPath: 'sign/in/path',
......
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