Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/issues_list')
-rw-r--r--app/assets/javascripts/issues_list/components/issues_list_app.vue26
-rw-r--r--app/assets/javascripts/issues_list/components/new_issue_dropdown.vue7
-rw-r--r--app/assets/javascripts/issues_list/constants.js28
-rw-r--r--app/assets/javascripts/issues_list/index.js6
-rw-r--r--app/assets/javascripts/issues_list/queries/get_issues.query.graphql10
-rw-r--r--app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql22
-rw-r--r--app/assets/javascripts/issues_list/queries/get_issues_list_details.query.graphql2
-rw-r--r--app/assets/javascripts/issues_list/queries/iteration.fragment.graphql6
-rw-r--r--app/assets/javascripts/issues_list/queries/search_projects.query.graphql1
-rw-r--r--app/assets/javascripts/issues_list/service_desk_helper.js8
-rw-r--r--app/assets/javascripts/issues_list/utils.js34
11 files changed, 125 insertions, 25 deletions
diff --git a/app/assets/javascripts/issues_list/components/issues_list_app.vue b/app/assets/javascripts/issues_list/components/issues_list_app.vue
index 7b51f6ee46a..7f2082e5b90 100644
--- a/app/assets/javascripts/issues_list/components/issues_list_app.vue
+++ b/app/assets/javascripts/issues_list/components/issues_list_app.vue
@@ -36,6 +36,7 @@ import {
TOKEN_TYPE_LABEL,
TOKEN_TYPE_MILESTONE,
TOKEN_TYPE_MY_REACTION,
+ TOKEN_TYPE_RELEASE,
TOKEN_TYPE_TYPE,
TOKEN_TYPE_WEIGHT,
UPDATED_DESC,
@@ -65,6 +66,7 @@ import {
TOKEN_TITLE_LABEL,
TOKEN_TITLE_MILESTONE,
TOKEN_TITLE_MY_REACTION,
+ TOKEN_TITLE_RELEASE,
TOKEN_TITLE_TYPE,
TOKEN_TITLE_WEIGHT,
} from '~/vue_shared/components/filtered_search_bar/constants';
@@ -88,6 +90,8 @@ const LabelToken = () =>
import('~/vue_shared/components/filtered_search_bar/tokens/label_token.vue');
const MilestoneToken = () =>
import('~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue');
+const ReleaseToken = () =>
+ import('~/vue_shared/components/filtered_search_bar/tokens/release_token.vue');
const WeightToken = () =>
import('~/vue_shared/components/filtered_search_bar/tokens/weight_token.vue');
@@ -165,6 +169,9 @@ export default {
newIssuePath: {
default: '',
},
+ releasesPath: {
+ default: '',
+ },
rssPath: {
default: '',
},
@@ -288,6 +295,7 @@ export default {
avatar_url: gon.current_user_avatar_url,
});
}
+
const tokens = [
{
type: TOKEN_TYPE_AUTHOR,
@@ -297,7 +305,6 @@ export default {
dataType: 'user',
unique: true,
defaultAuthors: [],
- operators: OPERATOR_IS_ONLY,
fetchAuthors: this.fetchUsers,
preloadedAuthors,
},
@@ -317,7 +324,6 @@ export default {
title: TOKEN_TITLE_MILESTONE,
icon: 'clock',
token: MilestoneToken,
- unique: true,
fetchMilestones: this.fetchMilestones,
},
{
@@ -333,7 +339,6 @@ export default {
title: TOKEN_TITLE_TYPE,
icon: 'issues',
token: GlFilteredSearchToken,
- operators: OPERATOR_IS_ONLY,
options: [
{ icon: 'issue-type-issue', title: 'issue', value: 'issue' },
{ icon: 'issue-type-incident', title: 'incident', value: 'incident' },
@@ -342,6 +347,16 @@ export default {
},
];
+ if (this.isProject) {
+ tokens.push({
+ type: TOKEN_TYPE_RELEASE,
+ title: TOKEN_TITLE_RELEASE,
+ icon: 'rocket',
+ token: ReleaseToken,
+ fetchReleases: this.fetchReleases,
+ });
+ }
+
if (this.isSignedIn) {
tokens.push({
type: TOKEN_TYPE_MY_REACTION,
@@ -349,7 +364,6 @@ export default {
icon: 'thumb-up',
token: EmojiToken,
unique: true,
- operators: OPERATOR_IS_ONLY,
fetchEmojis: this.fetchEmojis,
});
@@ -373,7 +387,6 @@ export default {
title: TOKEN_TITLE_ITERATION,
icon: 'iteration',
token: IterationToken,
- unique: true,
fetchIterations: this.fetchIterations,
});
}
@@ -459,6 +472,9 @@ export default {
fetchEmojis(search) {
return this.fetchWithCache(this.autocompleteAwardEmojisPath, 'emojis', 'name', search);
},
+ fetchReleases(search) {
+ return this.fetchWithCache(this.releasesPath, 'releases', 'tag', search);
+ },
fetchLabels(search) {
return this.$apollo
.query({
diff --git a/app/assets/javascripts/issues_list/components/new_issue_dropdown.vue b/app/assets/javascripts/issues_list/components/new_issue_dropdown.vue
index 037fd9be542..e749579af80 100644
--- a/app/assets/javascripts/issues_list/components/new_issue_dropdown.vue
+++ b/app/assets/javascripts/issues_list/components/new_issue_dropdown.vue
@@ -71,8 +71,11 @@ export default {
hasSelectedProject() {
return this.selectedProject.id;
},
+ projectsWithIssuesEnabled() {
+ return this.projects.filter((project) => project.issuesEnabled);
+ },
showNoSearchResultsText() {
- return !this.projects.length && this.search;
+ return !this.projectsWithIssuesEnabled.length && this.search;
},
},
methods: {
@@ -110,7 +113,7 @@ export default {
<gl-loading-icon v-if="$apollo.queries.projects.loading" />
<template v-else>
<gl-dropdown-item
- v-for="project of projects"
+ v-for="project of projectsWithIssuesEnabled"
:key="project.id"
@click="selectProject(project)"
>
diff --git a/app/assets/javascripts/issues_list/constants.js b/app/assets/javascripts/issues_list/constants.js
index 5bdc1bd9f90..da9b96d0e22 100644
--- a/app/assets/javascripts/issues_list/constants.js
+++ b/app/assets/javascripts/issues_list/constants.js
@@ -166,6 +166,7 @@ const LABEL_PRIORITY_ASC_SORT = 'label_priority_asc';
const POPULARITY_ASC_SORT = 'popularity_asc';
const WEIGHT_DESC_SORT = 'weight_desc';
const BLOCKING_ISSUES_DESC_SORT = 'blocking_issues_desc';
+const TITLE_ASC_SORT = 'title_asc';
const TITLE_DESC_SORT = 'title_desc';
export const urlSortParams = {
@@ -187,7 +188,7 @@ export const urlSortParams = {
[WEIGHT_ASC]: WEIGHT,
[WEIGHT_DESC]: WEIGHT_DESC_SORT,
[BLOCKING_ISSUES_DESC]: BLOCKING_ISSUES_DESC_SORT,
- [TITLE_ASC]: TITLE,
+ [TITLE_ASC]: TITLE_ASC_SORT,
[TITLE_DESC]: TITLE_DESC_SORT,
};
@@ -211,6 +212,7 @@ export const TOKEN_TYPE_ASSIGNEE = 'assignee_username';
export const TOKEN_TYPE_MILESTONE = 'milestone';
export const TOKEN_TYPE_LABEL = 'labels';
export const TOKEN_TYPE_TYPE = 'type';
+export const TOKEN_TYPE_RELEASE = 'release';
export const TOKEN_TYPE_MY_REACTION = 'my_reaction_emoji';
export const TOKEN_TYPE_CONFIDENTIAL = 'confidential';
export const TOKEN_TYPE_ITERATION = 'iteration';
@@ -271,6 +273,7 @@ export const filters = {
[OPERATOR_IS]: {
[NORMAL_FILTER]: 'label_name[]',
[SPECIAL_FILTER]: 'label_name[]',
+ [ALTERNATIVE_FILTER]: 'label_name',
},
[OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[label_name][]',
@@ -280,12 +283,28 @@ export const filters = {
[TOKEN_TYPE_TYPE]: {
[API_PARAM]: {
[NORMAL_FILTER]: 'types',
- [SPECIAL_FILTER]: 'types',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
[NORMAL_FILTER]: 'type[]',
- [SPECIAL_FILTER]: 'type[]',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[type][]',
+ },
+ },
+ },
+ [TOKEN_TYPE_RELEASE]: {
+ [API_PARAM]: {
+ [NORMAL_FILTER]: 'releaseTag',
+ [SPECIAL_FILTER]: 'releaseTagWildcardId',
+ },
+ [URL_PARAM]: {
+ [OPERATOR_IS]: {
+ [NORMAL_FILTER]: 'release_tag',
+ [SPECIAL_FILTER]: 'release_tag',
+ },
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[release_tag]',
},
},
},
@@ -299,6 +318,9 @@ export const filters = {
[NORMAL_FILTER]: 'my_reaction_emoji',
[SPECIAL_FILTER]: 'my_reaction_emoji',
},
+ [OPERATOR_IS_NOT]: {
+ [NORMAL_FILTER]: 'not[my_reaction_emoji]',
+ },
},
},
[TOKEN_TYPE_CONFIDENTIAL]: {
diff --git a/app/assets/javascripts/issues_list/index.js b/app/assets/javascripts/issues_list/index.js
index 47af20f5271..59034964afb 100644
--- a/app/assets/javascripts/issues_list/index.js
+++ b/app/assets/javascripts/issues_list/index.js
@@ -24,7 +24,7 @@ export function mountJiraIssuesListApp() {
}
Vue.use(VueApollo);
- const defaultClient = createDefaultClient({}, { assumeImmutableResults: true });
+ const defaultClient = createDefaultClient();
const apolloProvider = new VueApollo({
defaultClient,
});
@@ -103,7 +103,7 @@ export function mountIssuesListApp() {
},
};
- const defaultClient = createDefaultClient(resolvers, { assumeImmutableResults: true });
+ const defaultClient = createDefaultClient(resolvers);
const apolloProvider = new VueApollo({
defaultClient,
});
@@ -137,6 +137,7 @@ export function mountIssuesListApp() {
newIssuePath,
projectImportJiraPath,
quickActionsHelpPath,
+ releasesPath,
resetPath,
rssPath,
showNewIssueLink,
@@ -164,6 +165,7 @@ export function mountIssuesListApp() {
isSignedIn: parseBoolean(isSignedIn),
jiraIntegrationPath,
newIssuePath,
+ releasesPath,
rssPath,
showNewIssueLink: parseBoolean(showNewIssueLink),
signInPath,
diff --git a/app/assets/javascripts/issues_list/queries/get_issues.query.graphql b/app/assets/javascripts/issues_list/queries/get_issues.query.graphql
index 6df72cf6596..9866efbcecc 100644
--- a/app/assets/javascripts/issues_list/queries/get_issues.query.graphql
+++ b/app/assets/javascripts/issues_list/queries/get_issues.query.graphql
@@ -11,9 +11,13 @@ query getIssues(
$assigneeId: String
$assigneeUsernames: [String!]
$authorUsername: String
+ $confidential: Boolean
$labelName: [String]
$milestoneTitle: [String]
$milestoneWildcardId: MilestoneWildcardId
+ $myReactionEmoji: String
+ $releaseTag: [String!]
+ $releaseTagWildcardId: ReleaseTagWildcardId
$types: [IssueType!]
$not: NegatedIssueFilterInput
$beforeCursor: String
@@ -30,9 +34,11 @@ query getIssues(
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
authorUsername: $authorUsername
+ confidential: $confidential
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
+ myReactionEmoji: $myReactionEmoji
types: $types
not: $not
before: $beforeCursor
@@ -57,9 +63,13 @@ query getIssues(
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
authorUsername: $authorUsername
+ confidential: $confidential
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
+ myReactionEmoji: $myReactionEmoji
+ releaseTag: $releaseTag
+ releaseTagWildcardId: $releaseTagWildcardId
types: $types
not: $not
before: $beforeCursor
diff --git a/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql b/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql
index 7bcdbbb28fc..5e755ec5870 100644
--- a/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql
+++ b/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql
@@ -5,9 +5,13 @@ query getIssuesCount(
$assigneeId: String
$assigneeUsernames: [String!]
$authorUsername: String
+ $confidential: Boolean
$labelName: [String]
$milestoneTitle: [String]
$milestoneWildcardId: MilestoneWildcardId
+ $myReactionEmoji: String
+ $releaseTag: [String!]
+ $releaseTagWildcardId: ReleaseTagWildcardId
$types: [IssueType!]
$not: NegatedIssueFilterInput
) {
@@ -19,9 +23,11 @@ query getIssuesCount(
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
authorUsername: $authorUsername
+ confidential: $confidential
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
+ myReactionEmoji: $myReactionEmoji
types: $types
not: $not
) {
@@ -34,9 +40,11 @@ query getIssuesCount(
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
authorUsername: $authorUsername
+ confidential: $confidential
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
+ myReactionEmoji: $myReactionEmoji
types: $types
not: $not
) {
@@ -49,9 +57,11 @@ query getIssuesCount(
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
authorUsername: $authorUsername
+ confidential: $confidential
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
+ myReactionEmoji: $myReactionEmoji
types: $types
not: $not
) {
@@ -65,9 +75,13 @@ query getIssuesCount(
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
authorUsername: $authorUsername
+ confidential: $confidential
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
+ myReactionEmoji: $myReactionEmoji
+ releaseTag: $releaseTag
+ releaseTagWildcardId: $releaseTagWildcardId
types: $types
not: $not
) {
@@ -79,9 +93,13 @@ query getIssuesCount(
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
authorUsername: $authorUsername
+ confidential: $confidential
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
+ myReactionEmoji: $myReactionEmoji
+ releaseTag: $releaseTag
+ releaseTagWildcardId: $releaseTagWildcardId
types: $types
not: $not
) {
@@ -93,9 +111,13 @@ query getIssuesCount(
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
authorUsername: $authorUsername
+ confidential: $confidential
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
+ myReactionEmoji: $myReactionEmoji
+ releaseTag: $releaseTag
+ releaseTagWildcardId: $releaseTagWildcardId
types: $types
not: $not
) {
diff --git a/app/assets/javascripts/issues_list/queries/get_issues_list_details.query.graphql b/app/assets/javascripts/issues_list/queries/get_issues_list_details.query.graphql
index 8f9b888d19b..8c95e6114d3 100644
--- a/app/assets/javascripts/issues_list/queries/get_issues_list_details.query.graphql
+++ b/app/assets/javascripts/issues_list/queries/get_issues_list_details.query.graphql
@@ -1,4 +1,4 @@
-query($fullPath: ID!) {
+query getIssuesListDetails($fullPath: ID!) {
project(fullPath: $fullPath) {
issues {
nodes {
diff --git a/app/assets/javascripts/issues_list/queries/iteration.fragment.graphql b/app/assets/javascripts/issues_list/queries/iteration.fragment.graphql
index 78a368089a8..4f7217be7f7 100644
--- a/app/assets/javascripts/issues_list/queries/iteration.fragment.graphql
+++ b/app/assets/javascripts/issues_list/queries/iteration.fragment.graphql
@@ -1,4 +1,10 @@
fragment Iteration on Iteration {
id
title
+ startDate
+ dueDate
+ iterationCadence {
+ id
+ title
+ }
}
diff --git a/app/assets/javascripts/issues_list/queries/search_projects.query.graphql b/app/assets/javascripts/issues_list/queries/search_projects.query.graphql
index df1f330139a..75463f643a2 100644
--- a/app/assets/javascripts/issues_list/queries/search_projects.query.graphql
+++ b/app/assets/javascripts/issues_list/queries/search_projects.query.graphql
@@ -3,6 +3,7 @@ query searchProjects($fullPath: ID!, $search: String) {
projects(search: $search, includeSubgroups: true) {
nodes {
id
+ issuesEnabled
name
nameWithNamespace
webUrl
diff --git a/app/assets/javascripts/issues_list/service_desk_helper.js b/app/assets/javascripts/issues_list/service_desk_helper.js
index f96567ef53b..815f338f1a0 100644
--- a/app/assets/javascripts/issues_list/service_desk_helper.js
+++ b/app/assets/javascripts/issues_list/service_desk_helper.js
@@ -1,4 +1,4 @@
-import { s__ } from '~/locale';
+import { __, s__ } from '~/locale';
/**
* Generates empty state messages for Service Desk issues list.
@@ -20,12 +20,12 @@ export function generateMessages(emptyStateMeta) {
);
const serviceDeskSupportedMessage = s__(
- 'ServiceDesk|Issues created from Service Desk emails appear here. Each comment becomes part of the email conversation.',
+ 'ServiceDesk|Issues created from Service Desk emails will appear here. Each comment becomes part of the email conversation.',
);
const commonDescription = `
<span>${serviceDeskSupportedMessage}</span>
- <a href="${serviceDeskHelpPage}">${s__('Learn more.')}</a>`;
+ <a href="${serviceDeskHelpPage}">${__('Learn more.')}</a>`;
return {
serviceDeskEnabledAndCanEditProjectSettings: {
@@ -60,7 +60,7 @@ export function generateMessages(emptyStateMeta) {
'ServiceDesk|To enable Service Desk on this instance, an instance administrator must first set up incoming email.',
),
primaryLink: incomingEmailHelpPage,
- primaryText: s__('Learn more.'),
+ primaryText: __('Learn more.'),
},
serviceDeskIsNotEnabled: {
title: s__('ServiceDesk|Service Desk is not enabled'),
diff --git a/app/assets/javascripts/issues_list/utils.js b/app/assets/javascripts/issues_list/utils.js
index 1d3d07475af..0e57e2bff83 100644
--- a/app/assets/javascripts/issues_list/utils.js
+++ b/app/assets/javascripts/issues_list/utils.js
@@ -21,9 +21,13 @@ import {
RELATIVE_POSITION_ASC,
SPECIAL_FILTER,
SPECIAL_FILTER_VALUES,
+ TITLE_ASC,
+ TITLE_DESC,
TOKEN_TYPE_ASSIGNEE,
+ TOKEN_TYPE_CONFIDENTIAL,
TOKEN_TYPE_ITERATION,
TOKEN_TYPE_MILESTONE,
+ TOKEN_TYPE_RELEASE,
TOKEN_TYPE_TYPE,
UPDATED_ASC,
UPDATED_DESC,
@@ -113,11 +117,19 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature)
descending: RELATIVE_POSITION_ASC,
},
},
+ {
+ id: 9,
+ title: __('Title'),
+ sortDirection: {
+ ascending: TITLE_ASC,
+ descending: TITLE_DESC,
+ },
+ },
];
if (hasIssueWeightsFeature) {
sortOptions.push({
- id: 9,
+ id: sortOptions.length + 1,
title: __('Weight'),
sortDirection: {
ascending: WEIGHT_ASC,
@@ -128,7 +140,7 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature)
if (hasBlockedIssuesFeature) {
sortOptions.push({
- id: 10,
+ id: sortOptions.length + 1,
title: __('Blocking'),
sortDirection: {
ascending: BLOCKING_ISSUES_DESC,
@@ -193,17 +205,23 @@ const getFilterType = (data, tokenType = '') =>
? SPECIAL_FILTER
: NORMAL_FILTER;
+const wildcardTokens = [TOKEN_TYPE_ITERATION, TOKEN_TYPE_MILESTONE, TOKEN_TYPE_RELEASE];
+
const isWildcardValue = (tokenType, value) =>
- (tokenType === TOKEN_TYPE_ITERATION || tokenType === TOKEN_TYPE_MILESTONE) &&
- SPECIAL_FILTER_VALUES.includes(value);
+ wildcardTokens.includes(tokenType) && SPECIAL_FILTER_VALUES.includes(value);
const requiresUpperCaseValue = (tokenType, value) =>
tokenType === TOKEN_TYPE_TYPE || isWildcardValue(tokenType, value);
-const formatData = (token) =>
- requiresUpperCaseValue(token.type, token.value.data)
- ? token.value.data.toUpperCase()
- : token.value.data;
+const formatData = (token) => {
+ if (requiresUpperCaseValue(token.type, token.value.data)) {
+ return token.value.data.toUpperCase();
+ }
+ if (token.type === TOKEN_TYPE_CONFIDENTIAL) {
+ return token.value.data === 'yes';
+ }
+ return token.value.data;
+};
export const convertToApiParams = (filterTokens) => {
const params = {};