Commit a70c7aa2 authored by Phil Hughes's avatar Phil Hughes

Merge branch '322755-use-graphql-in-issues-refactor' into 'master'

Convert to use GraphQL in issues page refactor part 2

See merge request gitlab-org/gitlab!64429
parents 061dbe03 a8a7c3e1
...@@ -16,7 +16,6 @@ import IssuableByEmail from '~/issuable/components/issuable_by_email.vue'; ...@@ -16,7 +16,6 @@ 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';
import { IssuableListTabs, IssuableStates } from '~/issuable_list/constants'; import { IssuableListTabs, IssuableStates } from '~/issuable_list/constants';
import { import {
API_PARAM,
CREATED_DESC, CREATED_DESC,
i18n, i18n,
initialPageParams, initialPageParams,
...@@ -25,7 +24,7 @@ import { ...@@ -25,7 +24,7 @@ import {
PARAM_DUE_DATE, PARAM_DUE_DATE,
PARAM_SORT, PARAM_SORT,
PARAM_STATE, PARAM_STATE,
RELATIVE_POSITION_DESC, RELATIVE_POSITION_ASC,
TOKEN_TYPE_ASSIGNEE, TOKEN_TYPE_ASSIGNEE,
TOKEN_TYPE_AUTHOR, TOKEN_TYPE_AUTHOR,
TOKEN_TYPE_CONFIDENTIAL, TOKEN_TYPE_CONFIDENTIAL,
...@@ -36,12 +35,12 @@ import { ...@@ -36,12 +35,12 @@ import {
TOKEN_TYPE_MILESTONE, TOKEN_TYPE_MILESTONE,
TOKEN_TYPE_WEIGHT, TOKEN_TYPE_WEIGHT,
UPDATED_DESC, UPDATED_DESC,
URL_PARAM,
urlSortParams, urlSortParams,
} from '~/issues_list/constants'; } from '~/issues_list/constants';
import { import {
convertToParams, convertToApiParams,
convertToSearchQuery, convertToSearchQuery,
convertToUrlParams,
getDueDateValue, getDueDateValue,
getFilterTokens, getFilterTokens,
getSortKey, getSortKey,
...@@ -192,10 +191,10 @@ export default { ...@@ -192,10 +191,10 @@ export default {
...this.apiFilterParams, ...this.apiFilterParams,
}; };
}, },
update: ({ project }) => project.issues.nodes, update: ({ project }) => project?.issues.nodes ?? [],
result({ data }) { result({ data }) {
this.pageInfo = data.project.issues.pageInfo; this.pageInfo = data.project?.issues.pageInfo ?? {};
this.totalIssues = data.project.issues.count; this.totalIssues = data.project?.issues.count ?? 0;
this.exportCsvPathWithQuery = this.getExportCsvPathWithQuery(); this.exportCsvPathWithQuery = this.getExportCsvPathWithQuery();
}, },
error(error) { error(error) {
...@@ -215,32 +214,30 @@ export default { ...@@ -215,32 +214,30 @@ export default {
return this.showBulkEditSidebar || !this.issues.length; return this.showBulkEditSidebar || !this.issues.length;
}, },
isManualOrdering() { isManualOrdering() {
return this.sortKey === RELATIVE_POSITION_DESC; return this.sortKey === RELATIVE_POSITION_ASC;
}, },
isOpenTab() { isOpenTab() {
return this.state === IssuableStates.Opened; return this.state === IssuableStates.Opened;
}, },
apiFilterParams() { apiFilterParams() {
return convertToParams(this.filterTokens, API_PARAM); return convertToApiParams(this.filterTokens);
}, },
urlFilterParams() { urlFilterParams() {
return convertToParams(this.filterTokens, URL_PARAM); return convertToUrlParams(this.filterTokens);
}, },
searchQuery() { searchQuery() {
return convertToSearchQuery(this.filterTokens) || undefined; return convertToSearchQuery(this.filterTokens) || undefined;
}, },
searchTokens() { searchTokens() {
let preloadedAuthors = []; const preloadedAuthors = [];
if (gon.current_user_id) { if (gon.current_user_id) {
preloadedAuthors = [ preloadedAuthors.push({
{ id: gon.current_user_id,
id: gon.current_user_id, 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, });
},
];
} }
const tokens = [ const tokens = [
...@@ -252,6 +249,7 @@ export default { ...@@ -252,6 +249,7 @@ export default {
dataType: 'user', dataType: 'user',
unique: true, unique: true,
defaultAuthors: [], defaultAuthors: [],
operators: OPERATOR_IS_ONLY,
fetchAuthors: this.fetchUsers, fetchAuthors: this.fetchUsers,
preloadedAuthors, preloadedAuthors,
}, },
...@@ -280,7 +278,7 @@ export default { ...@@ -280,7 +278,7 @@ export default {
title: TOKEN_TITLE_LABEL, title: TOKEN_TITLE_LABEL,
icon: 'labels', icon: 'labels',
token: LabelToken, token: LabelToken,
defaultLabels: [], defaultLabels: DEFAULT_NONE_ANY,
fetchLabels: this.fetchLabels, fetchLabels: this.fetchLabels,
}, },
]; ];
...@@ -329,6 +327,7 @@ export default { ...@@ -329,6 +327,7 @@ export default {
token: EpicToken, token: EpicToken,
unique: true, unique: true,
idProperty: 'id', idProperty: 'id',
useIdValue: true,
fetchEpics: this.fetchEpics, fetchEpics: this.fetchEpics,
}); });
} }
...@@ -346,7 +345,7 @@ export default { ...@@ -346,7 +345,7 @@ export default {
return tokens; return tokens;
}, },
showPaginationControls() { showPaginationControls() {
return this.issues.length > 0; return this.issues.length > 0 && (this.pageInfo.hasNextPage || this.pageInfo.hasPreviousPage);
}, },
sortOptions() { sortOptions() {
return getSortOptions(this.hasIssueWeightsFeature, this.hasBlockedIssuesFeature); return getSortOptions(this.hasIssueWeightsFeature, this.hasBlockedIssuesFeature);
...@@ -361,22 +360,12 @@ export default { ...@@ -361,22 +360,12 @@ export default {
); );
}, },
urlParams() { urlParams() {
const filterParams = {
...this.urlFilterParams,
};
if (filterParams.epic_id) {
filterParams.epic_id = encodeURIComponent(filterParams.epic_id);
} else if (filterParams['not[epic_id]']) {
filterParams['not[epic_id]'] = encodeURIComponent(filterParams['not[epic_id]']);
}
return { return {
due_date: this.dueDateFilter, due_date: this.dueDateFilter,
search: this.searchQuery, search: this.searchQuery,
sort: urlSortParams[this.sortKey],
state: this.state, state: this.state,
...urlSortParams[this.sortKey], ...this.urlFilterParams,
...filterParams,
}; };
}, },
}, },
...@@ -424,7 +413,10 @@ export default { ...@@ -424,7 +413,10 @@ export default {
return this.fetchWithCache(this.projectMilestonesPath, 'milestones', 'title', search, true); return this.fetchWithCache(this.projectMilestonesPath, 'milestones', 'title', search, true);
}, },
fetchIterations(search) { fetchIterations(search) {
return axios.get(this.projectIterationsPath, { params: { search } }); const id = Number(search);
return !search || Number.isNaN(id)
? axios.get(this.projectIterationsPath, { params: { search } })
: axios.get(this.projectIterationsPath, { params: { id } });
}, },
fetchUsers(search) { fetchUsers(search) {
return axios.get(this.autocompleteUsersPath, { params: { search } }); return axios.get(this.autocompleteUsersPath, { params: { search } });
...@@ -471,6 +463,7 @@ export default { ...@@ -471,6 +463,7 @@ export default {
this.state = state; this.state = state;
}, },
handleFilter(filter) { handleFilter(filter) {
this.pageParams = initialPageParams;
this.filterTokens = filter; this.filterTokens = filter;
}, },
handleNextPage() { handleNextPage() {
......
...@@ -128,21 +128,21 @@ export const CREATED_ASC = 'CREATED_ASC'; ...@@ -128,21 +128,21 @@ export const CREATED_ASC = 'CREATED_ASC';
export const CREATED_DESC = 'CREATED_DESC'; export const CREATED_DESC = 'CREATED_DESC';
export const DUE_DATE_ASC = 'DUE_DATE_ASC'; export const DUE_DATE_ASC = 'DUE_DATE_ASC';
export const DUE_DATE_DESC = 'DUE_DATE_DESC'; export const DUE_DATE_DESC = 'DUE_DATE_DESC';
export const LABEL_PRIORITY_ASC = 'LABEL_PRIORITY_ASC';
export const LABEL_PRIORITY_DESC = 'LABEL_PRIORITY_DESC'; export const LABEL_PRIORITY_DESC = 'LABEL_PRIORITY_DESC';
export const MILESTONE_DUE_ASC = 'MILESTONE_DUE_ASC'; export const MILESTONE_DUE_ASC = 'MILESTONE_DUE_ASC';
export const MILESTONE_DUE_DESC = 'MILESTONE_DUE_DESC'; export const MILESTONE_DUE_DESC = 'MILESTONE_DUE_DESC';
export const POPULARITY_ASC = 'POPULARITY_ASC'; export const POPULARITY_ASC = 'POPULARITY_ASC';
export const POPULARITY_DESC = 'POPULARITY_DESC'; export const POPULARITY_DESC = 'POPULARITY_DESC';
export const PRIORITY_ASC = 'PRIORITY_ASC';
export const PRIORITY_DESC = 'PRIORITY_DESC'; export const PRIORITY_DESC = 'PRIORITY_DESC';
export const RELATIVE_POSITION_DESC = 'RELATIVE_POSITION_DESC'; export const RELATIVE_POSITION_ASC = 'RELATIVE_POSITION_ASC';
export const UPDATED_ASC = 'UPDATED_ASC'; export const UPDATED_ASC = 'UPDATED_ASC';
export const UPDATED_DESC = 'UPDATED_DESC'; export const UPDATED_DESC = 'UPDATED_DESC';
export const WEIGHT_ASC = 'WEIGHT_ASC'; export const WEIGHT_ASC = 'WEIGHT_ASC';
export const WEIGHT_DESC = 'WEIGHT_DESC'; export const WEIGHT_DESC = 'WEIGHT_DESC';
const SORT_ASC = 'asc'; const PRIORITY_ASC_SORT = 'priority_asc';
const SORT_DESC = 'desc';
const CREATED_DATE_SORT = 'created_date'; const CREATED_DATE_SORT = 'created_date';
const CREATED_ASC_SORT = 'created_asc'; const CREATED_ASC_SORT = 'created_asc';
const UPDATED_DESC_SORT = 'updated_desc'; const UPDATED_DESC_SORT = 'updated_desc';
...@@ -150,129 +150,30 @@ const UPDATED_ASC_SORT = 'updated_asc'; ...@@ -150,129 +150,30 @@ const UPDATED_ASC_SORT = 'updated_asc';
const MILESTONE_SORT = 'milestone'; const MILESTONE_SORT = 'milestone';
const MILESTONE_DUE_DESC_SORT = 'milestone_due_desc'; const MILESTONE_DUE_DESC_SORT = 'milestone_due_desc';
const DUE_DATE_DESC_SORT = 'due_date_desc'; const DUE_DATE_DESC_SORT = 'due_date_desc';
const LABEL_PRIORITY_ASC_SORT = 'label_priority_asc';
const POPULARITY_ASC_SORT = 'popularity_asc'; const POPULARITY_ASC_SORT = 'popularity_asc';
const WEIGHT_DESC_SORT = 'weight_desc'; const WEIGHT_DESC_SORT = 'weight_desc';
const BLOCKING_ISSUES_DESC_SORT = 'blocking_issues_desc'; const BLOCKING_ISSUES_DESC_SORT = 'blocking_issues_desc';
const BLOCKING_ISSUES = 'blocking_issues';
export const apiSortParams = {
[PRIORITY_DESC]: {
order_by: PRIORITY,
sort: SORT_DESC,
},
[CREATED_ASC]: {
order_by: CREATED_AT,
sort: SORT_ASC,
},
[CREATED_DESC]: {
order_by: CREATED_AT,
sort: SORT_DESC,
},
[UPDATED_ASC]: {
order_by: UPDATED_AT,
sort: SORT_ASC,
},
[UPDATED_DESC]: {
order_by: UPDATED_AT,
sort: SORT_DESC,
},
[MILESTONE_DUE_ASC]: {
order_by: MILESTONE_DUE,
sort: SORT_ASC,
},
[MILESTONE_DUE_DESC]: {
order_by: MILESTONE_DUE,
sort: SORT_DESC,
},
[DUE_DATE_ASC]: {
order_by: DUE_DATE,
sort: SORT_ASC,
},
[DUE_DATE_DESC]: {
order_by: DUE_DATE,
sort: SORT_DESC,
},
[POPULARITY_ASC]: {
order_by: POPULARITY,
sort: SORT_ASC,
},
[POPULARITY_DESC]: {
order_by: POPULARITY,
sort: SORT_DESC,
},
[LABEL_PRIORITY_DESC]: {
order_by: LABEL_PRIORITY,
sort: SORT_DESC,
},
[RELATIVE_POSITION_DESC]: {
order_by: RELATIVE_POSITION,
per_page: 100,
sort: SORT_ASC,
},
[WEIGHT_ASC]: {
order_by: WEIGHT,
sort: SORT_ASC,
},
[WEIGHT_DESC]: {
order_by: WEIGHT,
sort: SORT_DESC,
},
[BLOCKING_ISSUES_DESC]: {
order_by: BLOCKING_ISSUES,
sort: SORT_DESC,
},
};
export const urlSortParams = { export const urlSortParams = {
[PRIORITY_DESC]: { [PRIORITY_ASC]: PRIORITY_ASC_SORT,
sort: PRIORITY, [PRIORITY_DESC]: PRIORITY,
}, [CREATED_ASC]: CREATED_ASC_SORT,
[CREATED_ASC]: { [CREATED_DESC]: CREATED_DATE_SORT,
sort: CREATED_ASC_SORT, [UPDATED_ASC]: UPDATED_ASC_SORT,
}, [UPDATED_DESC]: UPDATED_DESC_SORT,
[CREATED_DESC]: { [MILESTONE_DUE_ASC]: MILESTONE_SORT,
sort: CREATED_DATE_SORT, [MILESTONE_DUE_DESC]: MILESTONE_DUE_DESC_SORT,
}, [DUE_DATE_ASC]: DUE_DATE,
[UPDATED_ASC]: { [DUE_DATE_DESC]: DUE_DATE_DESC_SORT,
sort: UPDATED_ASC_SORT, [POPULARITY_ASC]: POPULARITY_ASC_SORT,
}, [POPULARITY_DESC]: POPULARITY,
[UPDATED_DESC]: { [LABEL_PRIORITY_ASC]: LABEL_PRIORITY_ASC_SORT,
sort: UPDATED_DESC_SORT, [LABEL_PRIORITY_DESC]: LABEL_PRIORITY,
}, [RELATIVE_POSITION_ASC]: RELATIVE_POSITION,
[MILESTONE_DUE_ASC]: { [WEIGHT_ASC]: WEIGHT,
sort: MILESTONE_SORT, [WEIGHT_DESC]: WEIGHT_DESC_SORT,
}, [BLOCKING_ISSUES_DESC]: BLOCKING_ISSUES_DESC_SORT,
[MILESTONE_DUE_DESC]: {
sort: MILESTONE_DUE_DESC_SORT,
},
[DUE_DATE_ASC]: {
sort: DUE_DATE,
},
[DUE_DATE_DESC]: {
sort: DUE_DATE_DESC_SORT,
},
[POPULARITY_ASC]: {
sort: POPULARITY_ASC_SORT,
},
[POPULARITY_DESC]: {
sort: POPULARITY,
},
[LABEL_PRIORITY_DESC]: {
sort: LABEL_PRIORITY,
},
[RELATIVE_POSITION_DESC]: {
sort: RELATIVE_POSITION,
per_page: 100,
},
[WEIGHT_ASC]: {
sort: WEIGHT,
},
[WEIGHT_DESC]: {
sort: WEIGHT_DESC_SORT,
},
[BLOCKING_ISSUES_DESC]: {
sort: BLOCKING_ISSUES_DESC_SORT,
},
}; };
export const MAX_LIST_SIZE = 10; export const MAX_LIST_SIZE = 10;
...@@ -297,12 +198,7 @@ export const TOKEN_TYPE_WEIGHT = 'weight'; ...@@ -297,12 +198,7 @@ export const TOKEN_TYPE_WEIGHT = 'weight';
export const filters = { export const filters = {
[TOKEN_TYPE_AUTHOR]: { [TOKEN_TYPE_AUTHOR]: {
[API_PARAM]: { [API_PARAM]: {
[OPERATOR_IS]: { [NORMAL_FILTER]: 'authorUsername',
[NORMAL_FILTER]: 'author_username',
},
[OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[author_username]',
},
}, },
[URL_PARAM]: { [URL_PARAM]: {
[OPERATOR_IS]: { [OPERATOR_IS]: {
...@@ -315,13 +211,8 @@ export const filters = { ...@@ -315,13 +211,8 @@ export const filters = {
}, },
[TOKEN_TYPE_ASSIGNEE]: { [TOKEN_TYPE_ASSIGNEE]: {
[API_PARAM]: { [API_PARAM]: {
[OPERATOR_IS]: { [NORMAL_FILTER]: 'assigneeUsernames',
[NORMAL_FILTER]: 'assignee_username', [SPECIAL_FILTER]: 'assigneeId',
[SPECIAL_FILTER]: 'assignee_id',
},
[OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[assignee_username]',
},
}, },
[URL_PARAM]: { [URL_PARAM]: {
[OPERATOR_IS]: { [OPERATOR_IS]: {
...@@ -336,12 +227,7 @@ export const filters = { ...@@ -336,12 +227,7 @@ export const filters = {
}, },
[TOKEN_TYPE_MILESTONE]: { [TOKEN_TYPE_MILESTONE]: {
[API_PARAM]: { [API_PARAM]: {
[OPERATOR_IS]: { [NORMAL_FILTER]: 'milestoneTitle',
[NORMAL_FILTER]: 'milestone',
},
[OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[milestone]',
},
}, },
[URL_PARAM]: { [URL_PARAM]: {
[OPERATOR_IS]: { [OPERATOR_IS]: {
...@@ -354,16 +240,13 @@ export const filters = { ...@@ -354,16 +240,13 @@ export const filters = {
}, },
[TOKEN_TYPE_LABEL]: { [TOKEN_TYPE_LABEL]: {
[API_PARAM]: { [API_PARAM]: {
[OPERATOR_IS]: { [NORMAL_FILTER]: 'labelName',
[NORMAL_FILTER]: 'labels', [SPECIAL_FILTER]: 'labelName',
},
[OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[labels]',
},
}, },
[URL_PARAM]: { [URL_PARAM]: {
[OPERATOR_IS]: { [OPERATOR_IS]: {
[NORMAL_FILTER]: 'label_name[]', [NORMAL_FILTER]: 'label_name[]',
[SPECIAL_FILTER]: 'label_name[]',
}, },
[OPERATOR_IS_NOT]: { [OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[label_name][]', [NORMAL_FILTER]: 'not[label_name][]',
...@@ -372,10 +255,8 @@ export const filters = { ...@@ -372,10 +255,8 @@ export const filters = {
}, },
[TOKEN_TYPE_MY_REACTION]: { [TOKEN_TYPE_MY_REACTION]: {
[API_PARAM]: { [API_PARAM]: {
[OPERATOR_IS]: { [NORMAL_FILTER]: 'myReactionEmoji',
[NORMAL_FILTER]: 'my_reaction_emoji', [SPECIAL_FILTER]: 'myReactionEmoji',
[SPECIAL_FILTER]: 'my_reaction_emoji',
},
}, },
[URL_PARAM]: { [URL_PARAM]: {
[OPERATOR_IS]: { [OPERATOR_IS]: {
...@@ -386,9 +267,7 @@ export const filters = { ...@@ -386,9 +267,7 @@ export const filters = {
}, },
[TOKEN_TYPE_CONFIDENTIAL]: { [TOKEN_TYPE_CONFIDENTIAL]: {
[API_PARAM]: { [API_PARAM]: {
[OPERATOR_IS]: { [NORMAL_FILTER]: 'confidential',
[NORMAL_FILTER]: 'confidential',
},
}, },
[URL_PARAM]: { [URL_PARAM]: {
[OPERATOR_IS]: { [OPERATOR_IS]: {
...@@ -398,33 +277,23 @@ export const filters = { ...@@ -398,33 +277,23 @@ export const filters = {
}, },
[TOKEN_TYPE_ITERATION]: { [TOKEN_TYPE_ITERATION]: {
[API_PARAM]: { [API_PARAM]: {
[OPERATOR_IS]: { [NORMAL_FILTER]: 'iterationId',
[NORMAL_FILTER]: 'iteration_title', [SPECIAL_FILTER]: 'iterationWildcardId',
[SPECIAL_FILTER]: 'iteration_id',
},
[OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[iteration_title]',
},
}, },
[URL_PARAM]: { [URL_PARAM]: {
[OPERATOR_IS]: { [OPERATOR_IS]: {
[NORMAL_FILTER]: 'iteration_title', [NORMAL_FILTER]: 'iteration_id',
[SPECIAL_FILTER]: 'iteration_id', [SPECIAL_FILTER]: 'iteration_id',
}, },
[OPERATOR_IS_NOT]: { [OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[iteration_title]', [NORMAL_FILTER]: 'not[iteration_id]',
}, },
}, },
}, },
[TOKEN_TYPE_EPIC]: { [TOKEN_TYPE_EPIC]: {
[API_PARAM]: { [API_PARAM]: {
[OPERATOR_IS]: { [NORMAL_FILTER]: 'epicId',
[NORMAL_FILTER]: 'epic_id', [SPECIAL_FILTER]: 'epicId',
[SPECIAL_FILTER]: 'epic_id',
},
[OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[epic_id]',
},
}, },
[URL_PARAM]: { [URL_PARAM]: {
[OPERATOR_IS]: { [OPERATOR_IS]: {
...@@ -438,13 +307,8 @@ export const filters = { ...@@ -438,13 +307,8 @@ export const filters = {
}, },
[TOKEN_TYPE_WEIGHT]: { [TOKEN_TYPE_WEIGHT]: {
[API_PARAM]: { [API_PARAM]: {
[OPERATOR_IS]: { [NORMAL_FILTER]: 'weight',
[NORMAL_FILTER]: 'weight', [SPECIAL_FILTER]: 'weight',
[SPECIAL_FILTER]: 'weight',
},
[OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[weight]',
},
}, },
[URL_PARAM]: { [URL_PARAM]: {
[OPERATOR_IS]: { [OPERATOR_IS]: {
......
import { import {
API_PARAM,
BLOCKING_ISSUES_DESC, BLOCKING_ISSUES_DESC,
CREATED_ASC, CREATED_ASC,
CREATED_DESC, CREATED_DESC,
...@@ -6,29 +7,36 @@ import { ...@@ -6,29 +7,36 @@ import {
DUE_DATE_DESC, DUE_DATE_DESC,
DUE_DATE_VALUES, DUE_DATE_VALUES,
filters, filters,
LABEL_PRIORITY_ASC,
LABEL_PRIORITY_DESC, LABEL_PRIORITY_DESC,
MILESTONE_DUE_ASC, MILESTONE_DUE_ASC,
MILESTONE_DUE_DESC, MILESTONE_DUE_DESC,
NORMAL_FILTER, NORMAL_FILTER,
POPULARITY_ASC, POPULARITY_ASC,
POPULARITY_DESC, POPULARITY_DESC,
PRIORITY_ASC,
PRIORITY_DESC, PRIORITY_DESC,
RELATIVE_POSITION_DESC, RELATIVE_POSITION_ASC,
SPECIAL_FILTER, SPECIAL_FILTER,
SPECIAL_FILTER_VALUES, SPECIAL_FILTER_VALUES,
TOKEN_TYPE_ASSIGNEE, TOKEN_TYPE_ASSIGNEE,
TOKEN_TYPE_ITERATION,
UPDATED_ASC, UPDATED_ASC,
UPDATED_DESC, UPDATED_DESC,
URL_PARAM,
urlSortParams, urlSortParams,
WEIGHT_ASC, WEIGHT_ASC,
WEIGHT_DESC, WEIGHT_DESC,
} from '~/issues_list/constants'; } from '~/issues_list/constants';
import { isPositiveInteger } from '~/lib/utils/number_utils'; import { isPositiveInteger } from '~/lib/utils/number_utils';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants'; import {
FILTERED_SEARCH_TERM,
OPERATOR_IS_NOT,
} from '~/vue_shared/components/filtered_search_bar/constants';
export const getSortKey = (sort) => export const getSortKey = (sort) =>
Object.keys(urlSortParams).find((key) => urlSortParams[key].sort === sort); Object.keys(urlSortParams).find((key) => urlSortParams[key] === sort);
export const getDueDateValue = (value) => (DUE_DATE_VALUES.includes(value) ? value : undefined); export const getDueDateValue = (value) => (DUE_DATE_VALUES.includes(value) ? value : undefined);
...@@ -38,7 +46,7 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature) ...@@ -38,7 +46,7 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature)
id: 1, id: 1,
title: __('Priority'), title: __('Priority'),
sortDirection: { sortDirection: {
ascending: PRIORITY_DESC, ascending: PRIORITY_ASC,
descending: PRIORITY_DESC, descending: PRIORITY_DESC,
}, },
}, },
...@@ -86,7 +94,7 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature) ...@@ -86,7 +94,7 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature)
id: 7, id: 7,
title: __('Label priority'), title: __('Label priority'),
sortDirection: { sortDirection: {
ascending: LABEL_PRIORITY_DESC, ascending: LABEL_PRIORITY_ASC,
descending: LABEL_PRIORITY_DESC, descending: LABEL_PRIORITY_DESC,
}, },
}, },
...@@ -94,8 +102,8 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature) ...@@ -94,8 +102,8 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature)
id: 8, id: 8,
title: __('Manual'), title: __('Manual'),
sortDirection: { sortDirection: {
ascending: RELATIVE_POSITION_DESC, ascending: RELATIVE_POSITION_ASC,
descending: RELATIVE_POSITION_DESC, descending: RELATIVE_POSITION_ASC,
}, },
}, },
]; ];
...@@ -128,7 +136,7 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature) ...@@ -128,7 +136,7 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature)
const tokenTypes = Object.keys(filters); const tokenTypes = Object.keys(filters);
const getUrlParams = (tokenType) => const getUrlParams = (tokenType) =>
Object.values(filters[tokenType].urlParam).flatMap((filterObj) => Object.values(filterObj)); Object.values(filters[tokenType][URL_PARAM]).flatMap((filterObj) => Object.values(filterObj));
const urlParamKeys = tokenTypes.flatMap(getUrlParams); const urlParamKeys = tokenTypes.flatMap(getUrlParams);
...@@ -136,7 +144,7 @@ const getTokenTypeFromUrlParamKey = (urlParamKey) => ...@@ -136,7 +144,7 @@ const getTokenTypeFromUrlParamKey = (urlParamKey) =>
tokenTypes.find((tokenType) => getUrlParams(tokenType).includes(urlParamKey)); tokenTypes.find((tokenType) => getUrlParams(tokenType).includes(urlParamKey));
const getOperatorFromUrlParamKey = (tokenType, urlParamKey) => const getOperatorFromUrlParamKey = (tokenType, urlParamKey) =>
Object.entries(filters[tokenType].urlParam).find(([, filterObj]) => Object.entries(filters[tokenType][URL_PARAM]).find(([, filterObj]) =>
Object.values(filterObj).includes(urlParamKey), Object.values(filterObj).includes(urlParamKey),
)[0]; )[0];
...@@ -178,12 +186,36 @@ const getFilterType = (data, tokenType = '') => ...@@ -178,12 +186,36 @@ const getFilterType = (data, tokenType = '') =>
? SPECIAL_FILTER ? SPECIAL_FILTER
: NORMAL_FILTER; : NORMAL_FILTER;
export const convertToParams = (filterTokens, paramType) => const isIterationSpecialValue = (tokenType, value) =>
tokenType === TOKEN_TYPE_ITERATION && SPECIAL_FILTER_VALUES.includes(value);
export const convertToApiParams = (filterTokens) => {
const params = {};
const not = {};
filterTokens
.filter((token) => token.type !== FILTERED_SEARCH_TERM)
.forEach((token) => {
const filterType = getFilterType(token.value.data, token.type);
const field = filters[token.type][API_PARAM][filterType];
const obj = token.value.operator === OPERATOR_IS_NOT ? not : params;
const data = isIterationSpecialValue(token.type, token.value.data)
? token.value.data.toUpperCase()
: token.value.data;
Object.assign(obj, {
[field]: obj[field] ? [obj[field], data].flat() : data,
});
});
return Object.keys(not).length ? Object.assign(params, { not }) : params;
};
export const convertToUrlParams = (filterTokens) =>
filterTokens filterTokens
.filter((token) => token.type !== FILTERED_SEARCH_TERM) .filter((token) => token.type !== FILTERED_SEARCH_TERM)
.reduce((acc, token) => { .reduce((acc, token) => {
const filterType = getFilterType(token.value.data, token.type); const filterType = getFilterType(token.value.data, token.type);
const param = filters[token.type][paramType][token.value.operator]?.[filterType]; const param = filters[token.type][URL_PARAM][token.value.operator]?.[filterType];
return Object.assign(acc, { return Object.assign(acc, {
[param]: acc[param] ? [acc[param], token.value.data].flat() : token.value.data, [param]: acc[param] ? [acc[param], token.value.data].flat() : token.value.data,
}); });
......
...@@ -56,7 +56,7 @@ export default { ...@@ -56,7 +56,7 @@ export default {
} }
// Current value is a string. // Current value is a string.
const [groupPath, idProperty] = this.currentValue?.split('::&'); const [groupPath, idProperty] = this.currentValue?.split(this.$options.separator);
return this.epics.find( return this.epics.find(
(epic) => (epic) =>
epic.group_full_path === groupPath && epic.group_full_path === groupPath &&
...@@ -65,6 +65,9 @@ export default { ...@@ -65,6 +65,9 @@ export default {
} }
return null; return null;
}, },
displayText() {
return `${this.activeEpic?.title}${this.$options.separator}${this.activeEpic?.iid}`;
},
}, },
watch: { watch: {
active: { active: {
...@@ -103,8 +106,10 @@ export default { ...@@ -103,8 +106,10 @@ export default {
this.fetchEpicsBySearchTerm({ epicPath, search: data }); this.fetchEpicsBySearchTerm({ epicPath, search: data });
}, DEBOUNCE_DELAY), }, DEBOUNCE_DELAY),
getEpicDisplayText(epic) { getValue(epic) {
return `${epic.title}${this.$options.separator}${epic.iid}`; return this.config.useIdValue
? String(epic[this.idProperty])
: `${epic.group_full_path}${this.$options.separator}${epic[this.idProperty]}`;
}, },
}, },
}; };
...@@ -118,7 +123,7 @@ export default { ...@@ -118,7 +123,7 @@ export default {
@input="searchEpics" @input="searchEpics"
> >
<template #view="{ inputValue }"> <template #view="{ inputValue }">
{{ activeEpic ? getEpicDisplayText(activeEpic) : inputValue }} {{ activeEpic ? displayText : inputValue }}
</template> </template>
<template #suggestions> <template #suggestions>
<gl-filtered-search-suggestion <gl-filtered-search-suggestion
...@@ -131,11 +136,7 @@ export default { ...@@ -131,11 +136,7 @@ export default {
<gl-dropdown-divider v-if="defaultEpics.length" /> <gl-dropdown-divider v-if="defaultEpics.length" />
<gl-loading-icon v-if="loading" /> <gl-loading-icon v-if="loading" />
<template v-else> <template v-else>
<gl-filtered-search-suggestion <gl-filtered-search-suggestion v-for="epic in epics" :key="epic.id" :value="getValue(epic)">
v-for="epic in epics"
:key="epic.id"
:value="`${epic.group_full_path}::&${epic[idProperty]}`"
>
{{ epic.title }} {{ epic.title }}
</gl-filtered-search-suggestion> </gl-filtered-search-suggestion>
</template> </template>
......
...@@ -30,7 +30,6 @@ export default { ...@@ -30,7 +30,6 @@ export default {
data() { data() {
return { return {
iterations: this.config.initialIterations || [], iterations: this.config.initialIterations || [],
defaultIterations: this.config.defaultIterations || DEFAULT_ITERATIONS,
loading: true, loading: true,
}; };
}, },
...@@ -39,7 +38,10 @@ export default { ...@@ -39,7 +38,10 @@ export default {
return this.value.data; return this.value.data;
}, },
activeIteration() { activeIteration() {
return this.iterations.find((iteration) => iteration.title === this.currentValue); return this.iterations.find((iteration) => iteration.id === Number(this.currentValue));
},
defaultIterations() {
return this.config.defaultIterations || DEFAULT_ITERATIONS;
}, },
}, },
watch: { watch: {
...@@ -99,8 +101,8 @@ export default { ...@@ -99,8 +101,8 @@ export default {
<template v-else> <template v-else>
<gl-filtered-search-suggestion <gl-filtered-search-suggestion
v-for="iteration in iterations" v-for="iteration in iterations"
:key="iteration.title" :key="iteration.id"
:value="iteration.title" :value="String(iteration.id)"
> >
{{ iteration.title }} {{ iteration.title }}
</gl-filtered-search-suggestion> </gl-filtered-search-suggestion>
......
...@@ -21,7 +21,6 @@ import IssuableList from '~/issuable_list/components/issuable_list_root.vue'; ...@@ -21,7 +21,6 @@ import IssuableList from '~/issuable_list/components/issuable_list_root.vue';
import { IssuableListTabs, IssuableStates } from '~/issuable_list/constants'; import { IssuableListTabs, IssuableStates } from '~/issuable_list/constants';
import IssuesListApp from '~/issues_list/components/issues_list_app.vue'; import IssuesListApp from '~/issues_list/components/issues_list_app.vue';
import { import {
apiSortParams,
CREATED_DESC, CREATED_DESC,
DUE_DATE_OVERDUE, DUE_DATE_OVERDUE,
PARAM_DUE_DATE, PARAM_DUE_DATE,
...@@ -148,8 +147,8 @@ describe('IssuesListApp component', () => { ...@@ -148,8 +147,8 @@ describe('IssuesListApp component', () => {
hasPreviousPage: getIssuesQueryResponse.data.project.issues.pageInfo.hasPreviousPage, hasPreviousPage: getIssuesQueryResponse.data.project.issues.pageInfo.hasPreviousPage,
hasNextPage: getIssuesQueryResponse.data.project.issues.pageInfo.hasNextPage, hasNextPage: getIssuesQueryResponse.data.project.issues.pageInfo.hasNextPage,
urlParams: { urlParams: {
sort: urlSortParams[CREATED_DESC],
state: IssuableStates.Opened, state: IssuableStates.Opened,
...urlSortParams[CREATED_DESC],
}, },
}); });
}); });
...@@ -178,7 +177,7 @@ describe('IssuesListApp component', () => { ...@@ -178,7 +177,7 @@ describe('IssuesListApp component', () => {
describe('csv import/export component', () => { describe('csv import/export component', () => {
describe('when user is signed in', () => { describe('when user is signed in', () => {
const search = '?search=refactor&state=opened&sort=created_date'; const search = '?search=refactor&sort=created_date&state=opened';
beforeEach(() => { beforeEach(() => {
global.jsdom.reconfigure({ url: `${TEST_HOST}${search}` }); global.jsdom.reconfigure({ url: `${TEST_HOST}${search}` });
...@@ -273,13 +272,17 @@ describe('IssuesListApp component', () => { ...@@ -273,13 +272,17 @@ describe('IssuesListApp component', () => {
describe('sort', () => { describe('sort', () => {
it.each(Object.keys(urlSortParams))('is set as %s from the url params', (sortKey) => { it.each(Object.keys(urlSortParams))('is set as %s from the url params', (sortKey) => {
global.jsdom.reconfigure({ url: setUrlParams(urlSortParams[sortKey], TEST_HOST) }); global.jsdom.reconfigure({
url: setUrlParams({ sort: urlSortParams[sortKey] }, TEST_HOST),
});
wrapper = mountComponent(); wrapper = mountComponent();
expect(findIssuableList().props()).toMatchObject({ expect(findIssuableList().props()).toMatchObject({
initialSortBy: sortKey, initialSortBy: sortKey,
urlParams: urlSortParams[sortKey], urlParams: {
sort: urlSortParams[sortKey],
},
}); });
}); });
}); });
...@@ -640,7 +643,7 @@ describe('IssuesListApp component', () => { ...@@ -640,7 +643,7 @@ describe('IssuesListApp component', () => {
}); });
describe('when "sort" event is emitted by IssuableList', () => { describe('when "sort" event is emitted by IssuableList', () => {
it.each(Object.keys(apiSortParams))( it.each(Object.keys(urlSortParams))(
'updates to the new sort when payload is `%s`', 'updates to the new sort when payload is `%s`',
async (sortKey) => { async (sortKey) => {
wrapper = mountComponent(); wrapper = mountComponent();
...@@ -650,7 +653,9 @@ describe('IssuesListApp component', () => { ...@@ -650,7 +653,9 @@ describe('IssuesListApp component', () => {
jest.runOnlyPendingTimers(); jest.runOnlyPendingTimers();
await nextTick(); await nextTick();
expect(findIssuableList().props('urlParams')).toMatchObject(urlSortParams[sortKey]); expect(findIssuableList().props('urlParams')).toMatchObject({
sort: urlSortParams[sortKey],
});
}, },
); );
}); });
......
...@@ -9,7 +9,7 @@ export const getIssuesQueryResponse = { ...@@ -9,7 +9,7 @@ export const getIssuesQueryResponse = {
issues: { issues: {
count: 1, count: 1,
pageInfo: { pageInfo: {
hasNextPage: false, hasNextPage: true,
hasPreviousPage: false, hasPreviousPage: false,
startCursor: 'startcursor', startCursor: 'startcursor',
endCursor: 'endcursor', endCursor: 'endcursor',
...@@ -86,10 +86,10 @@ export const locationSearch = [ ...@@ -86,10 +86,10 @@ export const locationSearch = [
'not[label_name][]=drama', 'not[label_name][]=drama',
'my_reaction_emoji=thumbsup', 'my_reaction_emoji=thumbsup',
'confidential=no', 'confidential=no',
'iteration_title=season:+%234', 'iteration_id=4',
'not[iteration_title]=season:+%2320', 'not[iteration_id]=20',
'epic_id=gitlab-org%3A%3A%2612', 'epic_id=12',
'not[epic_id]=gitlab-org%3A%3A%2634', 'not[epic_id]=34',
'weight=1', 'weight=1',
'not[weight]=3', 'not[weight]=3',
].join('&'); ].join('&');
...@@ -118,10 +118,10 @@ export const filteredTokens = [ ...@@ -118,10 +118,10 @@ export const filteredTokens = [
{ type: 'labels', value: { data: 'drama', operator: OPERATOR_IS_NOT } }, { type: 'labels', value: { data: 'drama', operator: OPERATOR_IS_NOT } },
{ type: 'my_reaction_emoji', value: { data: 'thumbsup', operator: OPERATOR_IS } }, { type: 'my_reaction_emoji', value: { data: 'thumbsup', operator: OPERATOR_IS } },
{ type: 'confidential', value: { data: 'no', operator: OPERATOR_IS } }, { type: 'confidential', value: { data: 'no', operator: OPERATOR_IS } },
{ type: 'iteration', value: { data: 'season: #4', operator: OPERATOR_IS } }, { type: 'iteration', value: { data: '4', operator: OPERATOR_IS } },
{ type: 'iteration', value: { data: 'season: #20', operator: OPERATOR_IS_NOT } }, { type: 'iteration', value: { data: '20', operator: OPERATOR_IS_NOT } },
{ type: 'epic_id', value: { data: 'gitlab-org::&12', operator: OPERATOR_IS } }, { type: 'epic_id', value: { data: '12', operator: OPERATOR_IS } },
{ type: 'epic_id', value: { data: 'gitlab-org::&34', operator: OPERATOR_IS_NOT } }, { type: 'epic_id', value: { data: '34', operator: OPERATOR_IS_NOT } },
{ type: 'weight', value: { data: '1', operator: OPERATOR_IS } }, { type: 'weight', value: { data: '1', operator: OPERATOR_IS } },
{ type: 'weight', value: { data: '3', operator: OPERATOR_IS_NOT } }, { type: 'weight', value: { data: '3', operator: OPERATOR_IS_NOT } },
{ type: 'filtered-search-term', value: { data: 'find' } }, { type: 'filtered-search-term', value: { data: 'find' } },
...@@ -138,30 +138,32 @@ export const filteredTokensWithSpecialValues = [ ...@@ -138,30 +138,32 @@ export const filteredTokensWithSpecialValues = [
]; ];
export const apiParams = { export const apiParams = {
author_username: 'homer', authorUsername: 'homer',
'not[author_username]': 'marge', assigneeUsernames: ['bart', 'lisa'],
assignee_username: ['bart', 'lisa'], milestoneTitle: 'season 4',
'not[assignee_username]': ['patty', 'selma'], labelName: ['cartoon', 'tv'],
milestone: 'season 4', myReactionEmoji: 'thumbsup',
'not[milestone]': 'season 20',
labels: ['cartoon', 'tv'],
'not[labels]': ['live action', 'drama'],
my_reaction_emoji: 'thumbsup',
confidential: 'no', confidential: 'no',
iteration_title: 'season: #4', iterationId: '4',
'not[iteration_title]': 'season: #20', epicId: '12',
epic_id: '12',
'not[epic_id]': 'gitlab-org::&34',
weight: '1', weight: '1',
'not[weight]': '3', not: {
authorUsername: 'marge',
assigneeUsernames: ['patty', 'selma'],
milestoneTitle: 'season 20',
labelName: ['live action', 'drama'],
iterationId: '20',
epicId: '34',
weight: '3',
},
}; };
export const apiParamsWithSpecialValues = { export const apiParamsWithSpecialValues = {
assignee_id: '123', assigneeId: '123',
assignee_username: 'bart', assigneeUsernames: 'bart',
my_reaction_emoji: 'None', myReactionEmoji: 'None',
iteration_id: 'Current', iterationWildcardId: 'CURRENT',
epic_id: 'None', epicId: 'None',
weight: 'None', weight: 'None',
}; };
...@@ -176,10 +178,10 @@ export const urlParams = { ...@@ -176,10 +178,10 @@ export const urlParams = {
'not[label_name][]': ['live action', 'drama'], 'not[label_name][]': ['live action', 'drama'],
my_reaction_emoji: 'thumbsup', my_reaction_emoji: 'thumbsup',
confidential: 'no', confidential: 'no',
iteration_title: 'season: #4', iteration_id: '4',
'not[iteration_title]': 'season: #20', 'not[iteration_id]': '20',
epic_id: 'gitlab-org%3A%3A%2612', epic_id: '12',
'not[epic_id]': 'gitlab-org::&34', 'not[epic_id]': '34',
weight: '1', weight: '1',
'not[weight]': '3', 'not[weight]': '3',
}; };
......
...@@ -8,10 +8,11 @@ import { ...@@ -8,10 +8,11 @@ import {
urlParams, urlParams,
urlParamsWithSpecialValues, urlParamsWithSpecialValues,
} from 'jest/issues_list/mock_data'; } from 'jest/issues_list/mock_data';
import { API_PARAM, DUE_DATE_VALUES, URL_PARAM, urlSortParams } from '~/issues_list/constants'; import { DUE_DATE_VALUES, urlSortParams } from '~/issues_list/constants';
import { import {
convertToParams, convertToApiParams,
convertToSearchQuery, convertToSearchQuery,
convertToUrlParams,
getDueDateValue, getDueDateValue,
getFilterTokens, getFilterTokens,
getSortKey, getSortKey,
...@@ -20,7 +21,7 @@ import { ...@@ -20,7 +21,7 @@ import {
describe('getSortKey', () => { describe('getSortKey', () => {
it.each(Object.keys(urlSortParams))('returns %s given the correct inputs', (sortKey) => { it.each(Object.keys(urlSortParams))('returns %s given the correct inputs', (sortKey) => {
const { sort } = urlSortParams[sortKey]; const sort = urlSortParams[sortKey];
expect(getSortKey(sort)).toBe(sortKey); expect(getSortKey(sort)).toBe(sortKey);
}); });
}); });
...@@ -80,31 +81,23 @@ describe('getFilterTokens', () => { ...@@ -80,31 +81,23 @@ describe('getFilterTokens', () => {
}); });
}); });
describe('convertToParams', () => { describe('convertToApiParams', () => {
it('returns api params given filtered tokens', () => { it('returns api params given filtered tokens', () => {
expect(convertToParams(filteredTokens, API_PARAM)).toEqual({ expect(convertToApiParams(filteredTokens)).toEqual(apiParams);
...apiParams,
epic_id: 'gitlab-org::&12',
});
}); });
it('returns api params given filtered tokens with special values', () => { it('returns api params given filtered tokens with special values', () => {
expect(convertToParams(filteredTokensWithSpecialValues, API_PARAM)).toEqual( expect(convertToApiParams(filteredTokensWithSpecialValues)).toEqual(apiParamsWithSpecialValues);
apiParamsWithSpecialValues,
);
}); });
});
describe('convertToUrlParams', () => {
it('returns url params given filtered tokens', () => { it('returns url params given filtered tokens', () => {
expect(convertToParams(filteredTokens, URL_PARAM)).toEqual({ expect(convertToUrlParams(filteredTokens)).toEqual(urlParams);
...urlParams,
epic_id: 'gitlab-org::&12',
});
}); });
it('returns url params given filtered tokens with special values', () => { it('returns url params given filtered tokens with special values', () => {
expect(convertToParams(filteredTokensWithSpecialValues, URL_PARAM)).toEqual( expect(convertToUrlParams(filteredTokensWithSpecialValues)).toEqual(urlParamsWithSpecialValues);
urlParamsWithSpecialValues,
);
}); });
}); });
......
...@@ -7,7 +7,7 @@ import { mockIterationToken } from '../mock_data'; ...@@ -7,7 +7,7 @@ import { mockIterationToken } from '../mock_data';
jest.mock('~/flash'); jest.mock('~/flash');
describe('IterationToken', () => { describe('IterationToken', () => {
const title = 'gitlab-org: #1'; const id = 123;
let wrapper; let wrapper;
const createComponent = ({ config = mockIterationToken, value = { data: '' } } = {}) => const createComponent = ({ config = mockIterationToken, value = { data: '' } } = {}) =>
...@@ -28,14 +28,14 @@ describe('IterationToken', () => { ...@@ -28,14 +28,14 @@ describe('IterationToken', () => {
}); });
it('renders iteration value', async () => { it('renders iteration value', async () => {
wrapper = createComponent({ value: { data: title } }); wrapper = createComponent({ value: { data: id } });
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment); const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // `Iteration` `=` `gitlab-org: #1` expect(tokenSegments).toHaveLength(3); // `Iteration` `=` `gitlab-org: #1`
expect(tokenSegments.at(2).text()).toBe(title); expect(tokenSegments.at(2).text()).toBe(id.toString());
}); });
it('fetches initial values', () => { it('fetches initial values', () => {
...@@ -43,10 +43,10 @@ describe('IterationToken', () => { ...@@ -43,10 +43,10 @@ describe('IterationToken', () => {
wrapper = createComponent({ wrapper = createComponent({
config: { ...mockIterationToken, fetchIterations: fetchIterationsSpy }, config: { ...mockIterationToken, fetchIterations: fetchIterationsSpy },
value: { data: title }, value: { data: id },
}); });
expect(fetchIterationsSpy).toHaveBeenCalledWith(title); expect(fetchIterationsSpy).toHaveBeenCalledWith(id);
}); });
it('fetches iterations on user input', () => { it('fetches iterations on user input', () => {
......
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