Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
33597ad8
Commit
33597ad8
authored
Oct 27, 2021
by
Coung Ngo
Committed by
Phil Hughes
Oct 27, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add release filter and title sort to issues page refactor
parent
dfce9333
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
296 additions
and
19 deletions
+296
-19
app/assets/javascripts/issues_list/components/issues_list_app.vue
...ts/javascripts/issues_list/components/issues_list_app.vue
+20
-2
app/assets/javascripts/issues_list/constants.js
app/assets/javascripts/issues_list/constants.js
+18
-1
app/assets/javascripts/issues_list/index.js
app/assets/javascripts/issues_list/index.js
+2
-0
app/assets/javascripts/issues_list/queries/get_issues.query.graphql
.../javascripts/issues_list/queries/get_issues.query.graphql
+4
-0
app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql
...ripts/issues_list/queries/get_issues_counts.query.graphql
+8
-0
app/assets/javascripts/issues_list/utils.js
app/assets/javascripts/issues_list/utils.js
+16
-4
app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js
...ts/vue_shared/components/filtered_search_bar/constants.js
+1
-0
app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/release_token.vue
...d/components/filtered_search_bar/tokens/release_token.vue
+85
-0
app/helpers/issues_helper.rb
app/helpers/issues_helper.rb
+1
-0
ee/app/assets/javascripts/issues_list/queries/get_issues.query.graphql
.../javascripts/issues_list/queries/get_issues.query.graphql
+4
-0
ee/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql
...ripts/issues_list/queries/get_issues_counts.query.graphql
+8
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
spec/frontend/issues_list/components/issues_list_app_spec.js
spec/frontend/issues_list/components/issues_list_app_spec.js
+2
-0
spec/frontend/issues_list/mock_data.js
spec/frontend/issues_list/mock_data.js
+32
-8
spec/frontend/issues_list/utils_spec.js
spec/frontend/issues_list/utils_spec.js
+4
-4
spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
...nd/vue_shared/components/filtered_search_bar/mock_data.js
+9
-0
spec/frontend/vue_shared/components/filtered_search_bar/tokens/release_token_spec.js
...mponents/filtered_search_bar/tokens/release_token_spec.js
+78
-0
spec/helpers/issues_helper_spec.rb
spec/helpers/issues_helper_spec.rb
+1
-0
No files found.
app/assets/javascripts/issues_list/components/issues_list_app.vue
View file @
33597ad8
...
...
@@ -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
:
''
,
},
...
...
@@ -317,7 +324,6 @@ export default {
title
:
TOKEN_TITLE_MILESTONE
,
icon
:
'
clock
'
,
token
:
MilestoneToken
,
unique
:
true
,
fetchMilestones
:
this
.
fetchMilestones
,
},
{
...
...
@@ -341,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
,
...
...
@@ -371,7 +387,6 @@ export default {
title
:
TOKEN_TITLE_ITERATION
,
icon
:
'
iteration
'
,
token
:
IterationToken
,
unique
:
true
,
fetchIterations
:
this
.
fetchIterations
,
});
}
...
...
@@ -457,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
({
...
...
app/assets/javascripts/issues_list/constants.js
View file @
33597ad8
...
...
@@ -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
'
;
...
...
@@ -291,6 +293,21 @@ export const filters = {
},
},
},
[
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]
'
,
},
},
},
[
TOKEN_TYPE_MY_REACTION
]:
{
[
API_PARAM
]:
{
[
NORMAL_FILTER
]:
'
myReactionEmoji
'
,
...
...
app/assets/javascripts/issues_list/index.js
View file @
33597ad8
...
...
@@ -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
,
...
...
app/assets/javascripts/issues_list/queries/get_issues.query.graphql
View file @
33597ad8
...
...
@@ -16,6 +16,8 @@ query getIssues(
$milestoneTitle
:
[
String
]
$milestoneWildcardId
:
MilestoneWildcardId
$myReactionEmoji
:
String
$releaseTag
:
[
String
!]
$releaseTagWildcardId
:
ReleaseTagWildcardId
$types
:
[
IssueType
!]
$not
:
NegatedIssueFilterInput
$beforeCursor
:
String
...
...
@@ -66,6 +68,8 @@ query getIssues(
milestoneTitle
:
$milestoneTitle
milestoneWildcardId
:
$milestoneWildcardId
myReactionEmoji
:
$myReactionEmoji
releaseTag
:
$releaseTag
releaseTagWildcardId
:
$releaseTagWildcardId
types
:
$types
not
:
$not
before
:
$beforeCursor
...
...
app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql
View file @
33597ad8
...
...
@@ -10,6 +10,8 @@ query getIssuesCount(
$milestoneTitle
:
[
String
]
$milestoneWildcardId
:
MilestoneWildcardId
$myReactionEmoji
:
String
$releaseTag
:
[
String
!]
$releaseTagWildcardId
:
ReleaseTagWildcardId
$types
:
[
IssueType
!]
$not
:
NegatedIssueFilterInput
)
{
...
...
@@ -78,6 +80,8 @@ query getIssuesCount(
milestoneTitle
:
$milestoneTitle
milestoneWildcardId
:
$milestoneWildcardId
myReactionEmoji
:
$myReactionEmoji
releaseTag
:
$releaseTag
releaseTagWildcardId
:
$releaseTagWildcardId
types
:
$types
not
:
$not
)
{
...
...
@@ -94,6 +98,8 @@ query getIssuesCount(
milestoneTitle
:
$milestoneTitle
milestoneWildcardId
:
$milestoneWildcardId
myReactionEmoji
:
$myReactionEmoji
releaseTag
:
$releaseTag
releaseTagWildcardId
:
$releaseTagWildcardId
types
:
$types
not
:
$not
)
{
...
...
@@ -110,6 +116,8 @@ query getIssuesCount(
milestoneTitle
:
$milestoneTitle
milestoneWildcardId
:
$milestoneWildcardId
myReactionEmoji
:
$myReactionEmoji
releaseTag
:
$releaseTag
releaseTagWildcardId
:
$releaseTagWildcardId
types
:
$types
not
:
$not
)
{
...
...
app/assets/javascripts/issues_list/utils.js
View file @
33597ad8
...
...
@@ -21,10 +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
,
...
...
@@ -114,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
,
...
...
@@ -129,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
,
...
...
@@ -194,9 +205,10 @@ 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
);
...
...
app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js
View file @
33597ad8
...
...
@@ -53,6 +53,7 @@ export const TOKEN_TITLE_ASSIGNEE = __('Assignee');
export
const
TOKEN_TITLE_MILESTONE
=
__
(
'
Milestone
'
);
export
const
TOKEN_TITLE_LABEL
=
__
(
'
Label
'
);
export
const
TOKEN_TITLE_TYPE
=
__
(
'
Type
'
);
export
const
TOKEN_TITLE_RELEASE
=
__
(
'
Release
'
);
export
const
TOKEN_TITLE_MY_REACTION
=
__
(
'
My-Reaction
'
);
export
const
TOKEN_TITLE_CONFIDENTIAL
=
__
(
'
Confidential
'
);
export
const
TOKEN_TITLE_ITERATION
=
__
(
'
Iteration
'
);
...
...
app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/release_token.vue
0 → 100644
View file @
33597ad8
<
script
>
import
{
GlFilteredSearchSuggestion
}
from
'
@gitlab/ui
'
;
import
createFlash
from
'
~/flash
'
;
import
{
__
}
from
'
~/locale
'
;
import
BaseToken
from
'
~/vue_shared/components/filtered_search_bar/tokens/base_token.vue
'
;
import
{
DEFAULT_NONE_ANY
}
from
'
../constants
'
;
export
default
{
components
:
{
BaseToken
,
GlFilteredSearchSuggestion
,
},
props
:
{
active
:
{
type
:
Boolean
,
required
:
true
,
},
config
:
{
type
:
Object
,
required
:
true
,
},
value
:
{
type
:
Object
,
required
:
true
,
},
},
data
()
{
return
{
releases
:
this
.
config
.
initialReleases
||
[],
loading
:
false
,
};
},
computed
:
{
defaultReleases
()
{
return
this
.
config
.
defaultReleases
||
DEFAULT_NONE_ANY
;
},
},
methods
:
{
getActiveRelease
(
releases
,
data
)
{
return
releases
.
find
((
release
)
=>
release
.
tag
.
toLowerCase
()
===
data
.
toLowerCase
());
},
fetchReleases
(
searchTerm
)
{
this
.
loading
=
true
;
this
.
config
.
fetchReleases
(
searchTerm
)
.
then
((
response
)
=>
{
this
.
releases
=
response
;
})
.
catch
(()
=>
{
createFlash
({
message
:
__
(
'
There was a problem fetching releases.
'
)
});
})
.
finally
(()
=>
{
this
.
loading
=
false
;
});
},
},
};
</
script
>
<
template
>
<base-token
:active=
"active"
:config=
"config"
:value=
"value"
:default-suggestions=
"defaultReleases"
:suggestions=
"releases"
:suggestions-loading=
"loading"
:get-active-token-value=
"getActiveRelease"
@
fetch-suggestions=
"fetchReleases"
v-on=
"$listeners"
>
<template
#view
="
{ viewTokenProps: { inputValue, activeTokenValue } }">
{{
activeTokenValue
?
activeTokenValue
.
tag
:
inputValue
}}
</
template
>
<
template
#suggestions-list=
"{ suggestions }"
>
<gl-filtered-search-suggestion
v-for=
"release in suggestions"
:key=
"release.id"
:value=
"release.tag"
>
{{
release
.
tag
}}
</gl-filtered-search-suggestion>
</
template
>
</base-token>
</template>
app/helpers/issues_helper.rb
View file @
33597ad8
...
...
@@ -233,6 +233,7 @@ module IssuesHelper
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
),
quick_actions_help_path:
help_page_path
(
'user/project/quick_actions'
),
releases_path:
project_releases_path
(
project
,
format: :json
),
reset_path:
new_issuable_address_project_path
(
project
,
issuable_type:
'issue'
),
show_new_issue_link:
show_new_issue_link?
(
project
).
to_s
)
...
...
ee/app/assets/javascripts/issues_list/queries/get_issues.query.graphql
View file @
33597ad8
...
...
@@ -16,6 +16,8 @@ query getIssues(
$milestoneTitle
:
[
String
]
$milestoneWildcardId
:
MilestoneWildcardId
$myReactionEmoji
:
String
$releaseTag
:
[
String
!]
$releaseTagWildcardId
:
ReleaseTagWildcardId
$types
:
[
IssueType
!]
$epicId
:
String
$iterationId
:
[
ID
]
...
...
@@ -79,6 +81,8 @@ query getIssues(
milestoneTitle
:
$milestoneTitle
milestoneWildcardId
:
$milestoneWildcardId
myReactionEmoji
:
$myReactionEmoji
releaseTag
:
$releaseTag
releaseTagWildcardId
:
$releaseTagWildcardId
types
:
$types
epicId
:
$epicId
iterationId
:
$iterationId
...
...
ee/app/assets/javascripts/issues_list/queries/get_issues_counts.query.graphql
View file @
33597ad8
...
...
@@ -10,6 +10,8 @@ query getIssuesCount(
$milestoneTitle
:
[
String
]
$milestoneWildcardId
:
MilestoneWildcardId
$myReactionEmoji
:
String
$releaseTag
:
[
String
!]
$releaseTagWildcardId
:
ReleaseTagWildcardId
$types
:
[
IssueType
!]
$epicId
:
String
$iterationId
:
[
ID
]
...
...
@@ -98,6 +100,8 @@ query getIssuesCount(
milestoneTitle
:
$milestoneTitle
milestoneWildcardId
:
$milestoneWildcardId
myReactionEmoji
:
$myReactionEmoji
releaseTag
:
$releaseTag
releaseTagWildcardId
:
$releaseTagWildcardId
types
:
$types
epicId
:
$epicId
iterationId
:
$iterationId
...
...
@@ -119,6 +123,8 @@ query getIssuesCount(
milestoneTitle
:
$milestoneTitle
milestoneWildcardId
:
$milestoneWildcardId
myReactionEmoji
:
$myReactionEmoji
releaseTag
:
$releaseTag
releaseTagWildcardId
:
$releaseTagWildcardId
types
:
$types
epicId
:
$epicId
iterationId
:
$iterationId
...
...
@@ -140,6 +146,8 @@ query getIssuesCount(
milestoneTitle
:
$milestoneTitle
milestoneWildcardId
:
$milestoneWildcardId
myReactionEmoji
:
$myReactionEmoji
releaseTag
:
$releaseTag
releaseTagWildcardId
:
$releaseTagWildcardId
types
:
$types
epicId
:
$epicId
iterationId
:
$iterationId
...
...
locale/gitlab.pot
View file @
33597ad8
...
...
@@ -34507,6 +34507,9 @@ msgstr ""
msgid "There was a problem fetching recent projects."
msgstr ""
msgid "There was a problem fetching releases."
msgstr ""
msgid "There was a problem fetching the job token scope value"
msgstr ""
...
...
spec/frontend/issues_list/components/issues_list_app_spec.js
View file @
33597ad8
...
...
@@ -37,6 +37,7 @@ import {
TOKEN_TYPE_LABEL
,
TOKEN_TYPE_MILESTONE
,
TOKEN_TYPE_MY_REACTION
,
TOKEN_TYPE_RELEASE
,
TOKEN_TYPE_TYPE
,
TOKEN_TYPE_WEIGHT
,
urlSortParams
,
...
...
@@ -581,6 +582,7 @@ describe('IssuesListApp component', () => {
{
type
:
TOKEN_TYPE_MILESTONE
},
{
type
:
TOKEN_TYPE_LABEL
},
{
type
:
TOKEN_TYPE_TYPE
},
{
type
:
TOKEN_TYPE_RELEASE
},
{
type
:
TOKEN_TYPE_MY_REACTION
},
{
type
:
TOKEN_TYPE_CONFIDENTIAL
},
{
type
:
TOKEN_TYPE_ITERATION
},
...
...
spec/frontend/issues_list/mock_data.js
View file @
33597ad8
...
...
@@ -95,12 +95,18 @@ export const locationSearch = [
'
assignee_username[]=lisa
'
,
'
not[assignee_username][]=patty
'
,
'
not[assignee_username][]=selma
'
,
'
milestone_title=season+3
'
,
'
milestone_title=season+4
'
,
'
not[milestone_title]=season+20
'
,
'
not[milestone_title]=season+30
'
,
'
label_name[]=cartoon
'
,
'
label_name[]=tv
'
,
'
not[label_name][]=live action
'
,
'
not[label_name][]=drama
'
,
'
release_tag=v3
'
,
'
release_tag=v4
'
,
'
not[release_tag]=v20
'
,
'
not[release_tag]=v30
'
,
'
type[]=issue
'
,
'
type[]=feature
'
,
'
not[type][]=bug
'
,
...
...
@@ -109,7 +115,9 @@ export const locationSearch = [
'
not[my_reaction_emoji]=thumbsdown
'
,
'
confidential=yes
'
,
'
iteration_id=4
'
,
'
iteration_id=12
'
,
'
not[iteration_id]=20
'
,
'
not[iteration_id]=42
'
,
'
epic_id=12
'
,
'
not[epic_id]=34
'
,
'
weight=1
'
,
...
...
@@ -122,6 +130,7 @@ export const locationSearchWithSpecialValues = [
'
my_reaction_emoji=None
'
,
'
iteration_id=Current
'
,
'
label_name[]=None
'
,
'
release_tag=None
'
,
'
milestone_title=Upcoming
'
,
'
epic_id=None
'
,
'
weight=None
'
,
...
...
@@ -134,12 +143,18 @@ export const filteredTokens = [
{
type
:
'
assignee_username
'
,
value
:
{
data
:
'
lisa
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
assignee_username
'
,
value
:
{
data
:
'
patty
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
assignee_username
'
,
value
:
{
data
:
'
selma
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
milestone
'
,
value
:
{
data
:
'
season 3
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
milestone
'
,
value
:
{
data
:
'
season 4
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
milestone
'
,
value
:
{
data
:
'
season 20
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
milestone
'
,
value
:
{
data
:
'
season 30
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
labels
'
,
value
:
{
data
:
'
cartoon
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
labels
'
,
value
:
{
data
:
'
tv
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
labels
'
,
value
:
{
data
:
'
live action
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
labels
'
,
value
:
{
data
:
'
drama
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
release
'
,
value
:
{
data
:
'
v3
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
release
'
,
value
:
{
data
:
'
v4
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
release
'
,
value
:
{
data
:
'
v20
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
release
'
,
value
:
{
data
:
'
v30
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
type
'
,
value
:
{
data
:
'
issue
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
type
'
,
value
:
{
data
:
'
feature
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
type
'
,
value
:
{
data
:
'
bug
'
,
operator
:
OPERATOR_IS_NOT
}
},
...
...
@@ -148,7 +163,9 @@ export const filteredTokens = [
{
type
:
'
my_reaction_emoji
'
,
value
:
{
data
:
'
thumbsdown
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
confidential
'
,
value
:
{
data
:
'
yes
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
iteration
'
,
value
:
{
data
:
'
4
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
iteration
'
,
value
:
{
data
:
'
12
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
iteration
'
,
value
:
{
data
:
'
20
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
iteration
'
,
value
:
{
data
:
'
42
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
epic_id
'
,
value
:
{
data
:
'
12
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
epic_id
'
,
value
:
{
data
:
'
34
'
,
operator
:
OPERATOR_IS_NOT
}
},
{
type
:
'
weight
'
,
value
:
{
data
:
'
1
'
,
operator
:
OPERATOR_IS
}
},
...
...
@@ -163,6 +180,7 @@ export const filteredTokensWithSpecialValues = [
{
type
:
'
my_reaction_emoji
'
,
value
:
{
data
:
'
None
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
iteration
'
,
value
:
{
data
:
'
Current
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
labels
'
,
value
:
{
data
:
'
None
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
release
'
,
value
:
{
data
:
'
None
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
milestone
'
,
value
:
{
data
:
'
Upcoming
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
epic_id
'
,
value
:
{
data
:
'
None
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
weight
'
,
value
:
{
data
:
'
None
'
,
operator
:
OPERATOR_IS
}
},
...
...
@@ -171,22 +189,24 @@ export const filteredTokensWithSpecialValues = [
export
const
apiParams
=
{
authorUsername
:
'
homer
'
,
assigneeUsernames
:
[
'
bart
'
,
'
lisa
'
],
milestoneTitle
:
'
season 4
'
,
milestoneTitle
:
[
'
season 3
'
,
'
season 4
'
]
,
labelName
:
[
'
cartoon
'
,
'
tv
'
],
releaseTag
:
[
'
v3
'
,
'
v4
'
],
types
:
[
'
ISSUE
'
,
'
FEATURE
'
],
myReactionEmoji
:
'
thumbsup
'
,
confidential
:
true
,
iterationId
:
'
4
'
,
iterationId
:
[
'
4
'
,
'
12
'
]
,
epicId
:
'
12
'
,
weight
:
'
1
'
,
not
:
{
authorUsername
:
'
marge
'
,
assigneeUsernames
:
[
'
patty
'
,
'
selma
'
],
milestoneTitle
:
'
season 20
'
,
milestoneTitle
:
[
'
season 20
'
,
'
season 30
'
]
,
labelName
:
[
'
live action
'
,
'
drama
'
],
releaseTag
:
[
'
v20
'
,
'
v30
'
],
types
:
[
'
BUG
'
,
'
INCIDENT
'
],
myReactionEmoji
:
'
thumbsdown
'
,
iterationId
:
'
20
'
,
iterationId
:
[
'
20
'
,
'
42
'
]
,
epicId
:
'
34
'
,
weight
:
'
3
'
,
},
...
...
@@ -197,6 +217,7 @@ export const apiParamsWithSpecialValues = {
assigneeUsernames
:
'
bart
'
,
labelName
:
'
None
'
,
myReactionEmoji
:
'
None
'
,
releaseTagWildcardId
:
'
NONE
'
,
iterationWildcardId
:
'
CURRENT
'
,
milestoneWildcardId
:
'
UPCOMING
'
,
epicId
:
'
None
'
,
...
...
@@ -208,17 +229,19 @@ export const urlParams = {
'
not[author_username]
'
:
'
marge
'
,
'
assignee_username[]
'
:
[
'
bart
'
,
'
lisa
'
],
'
not[assignee_username][]
'
:
[
'
patty
'
,
'
selma
'
],
milestone_title
:
'
season 4
'
,
'
not[milestone_title]
'
:
'
season 20
'
,
milestone_title
:
[
'
season 3
'
,
'
season 4
'
]
,
'
not[milestone_title]
'
:
[
'
season 20
'
,
'
season 30
'
]
,
'
label_name[]
'
:
[
'
cartoon
'
,
'
tv
'
],
'
not[label_name][]
'
:
[
'
live action
'
,
'
drama
'
],
release_tag
:
[
'
v3
'
,
'
v4
'
],
'
not[release_tag]
'
:
[
'
v20
'
,
'
v30
'
],
'
type[]
'
:
[
'
issue
'
,
'
feature
'
],
'
not[type][]
'
:
[
'
bug
'
,
'
incident
'
],
my_reaction_emoji
:
'
thumbsup
'
,
'
not[my_reaction_emoji]
'
:
'
thumbsdown
'
,
confidential
:
'
yes
'
,
iteration_id
:
'
4
'
,
'
not[iteration_id]
'
:
'
20
'
,
iteration_id
:
[
'
4
'
,
'
12
'
]
,
'
not[iteration_id]
'
:
[
'
20
'
,
'
42
'
]
,
epic_id
:
'
12
'
,
'
not[epic_id]
'
:
'
34
'
,
weight
:
'
1
'
,
...
...
@@ -229,6 +252,7 @@ export const urlParamsWithSpecialValues = {
assignee_id
:
'
123
'
,
'
assignee_username[]
'
:
'
bart
'
,
'
label_name[]
'
:
'
None
'
,
release_tag
:
'
None
'
,
my_reaction_emoji
:
'
None
'
,
iteration_id
:
'
Current
'
,
milestone_title
:
'
Upcoming
'
,
...
...
spec/frontend/issues_list/utils_spec.js
View file @
33597ad8
...
...
@@ -58,10 +58,10 @@ describe('getDueDateValue', () => {
describe
(
'
getSortOptions
'
,
()
=>
{
describe
.
each
`
hasIssueWeightsFeature | hasBlockedIssuesFeature | length | containsWeight | containsBlocking
${
false
}
|
${
false
}
|
${
8
}
|
${
false
}
|
${
false
}
${
true
}
|
${
false
}
|
${
9
}
|
${
true
}
|
${
false
}
${
false
}
|
${
true
}
|
${
9
}
|
${
false
}
|
${
true
}
${
true
}
|
${
true
}
|
${
1
0
}
|
${
true
}
|
${
true
}
${
false
}
|
${
false
}
|
${
9
}
|
${
false
}
|
${
false
}
${
true
}
|
${
false
}
|
${
10
}
|
${
true
}
|
${
false
}
${
false
}
|
${
true
}
|
${
10
}
|
${
false
}
|
${
true
}
${
true
}
|
${
true
}
|
${
1
1
}
|
${
true
}
|
${
true
}
`
(
'
when hasIssueWeightsFeature=$hasIssueWeightsFeature and hasBlockedIssuesFeature=$hasBlockedIssuesFeature
'
,
({
...
...
spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
View file @
33597ad8
...
...
@@ -9,6 +9,7 @@ import EpicToken from '~/vue_shared/components/filtered_search_bar/tokens/epic_t
import
IterationToken
from
'
~/vue_shared/components/filtered_search_bar/tokens/iteration_token.vue
'
;
import
LabelToken
from
'
~/vue_shared/components/filtered_search_bar/tokens/label_token.vue
'
;
import
MilestoneToken
from
'
~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue
'
;
import
ReleaseToken
from
'
~/vue_shared/components/filtered_search_bar/tokens/release_token.vue
'
;
import
WeightToken
from
'
~/vue_shared/components/filtered_search_bar/tokens/weight_token.vue
'
;
export
const
mockAuthor1
=
{
...
...
@@ -132,6 +133,14 @@ export const mockMilestoneToken = {
fetchMilestones
:
()
=>
Promise
.
resolve
({
data
:
mockMilestones
}),
};
export
const
mockReleaseToken
=
{
type
:
'
release
'
,
icon
:
'
rocket
'
,
title
:
'
Release
'
,
token
:
ReleaseToken
,
fetchReleases
:
()
=>
Promise
.
resolve
(),
};
export
const
mockEpicToken
=
{
type
:
'
epic_iid
'
,
icon
:
'
clock
'
,
...
...
spec/frontend/vue_shared/components/filtered_search_bar/tokens/release_token_spec.js
0 → 100644
View file @
33597ad8
import
{
GlFilteredSearchToken
,
GlFilteredSearchTokenSegment
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
createFlash
from
'
~/flash
'
;
import
ReleaseToken
from
'
~/vue_shared/components/filtered_search_bar/tokens/release_token.vue
'
;
import
{
mockReleaseToken
}
from
'
../mock_data
'
;
jest
.
mock
(
'
~/flash
'
);
describe
(
'
ReleaseToken
'
,
()
=>
{
const
id
=
123
;
let
wrapper
;
const
createComponent
=
({
config
=
mockReleaseToken
,
value
=
{
data
:
''
}
}
=
{})
=>
mount
(
ReleaseToken
,
{
propsData
:
{
active
:
false
,
config
,
value
,
},
provide
:
{
portalName
:
'
fake target
'
,
alignSuggestions
:
function
fakeAlignSuggestions
()
{},
suggestionsListClass
:
()
=>
'
custom-class
'
,
},
});
afterEach
(()
=>
{
wrapper
.
destroy
();
});
it
(
'
renders release value
'
,
async
()
=>
{
wrapper
=
createComponent
({
value
:
{
data
:
id
}
});
await
wrapper
.
vm
.
$nextTick
();
const
tokenSegments
=
wrapper
.
findAllComponents
(
GlFilteredSearchTokenSegment
);
expect
(
tokenSegments
).
toHaveLength
(
3
);
// `Release` `=` `v1`
expect
(
tokenSegments
.
at
(
2
).
text
()).
toBe
(
id
.
toString
());
});
it
(
'
fetches initial values
'
,
()
=>
{
const
fetchReleasesSpy
=
jest
.
fn
().
mockResolvedValue
();
wrapper
=
createComponent
({
config
:
{
...
mockReleaseToken
,
fetchReleases
:
fetchReleasesSpy
},
value
:
{
data
:
id
},
});
expect
(
fetchReleasesSpy
).
toHaveBeenCalledWith
(
id
);
});
it
(
'
fetches releases on user input
'
,
()
=>
{
const
search
=
'
hello
'
;
const
fetchReleasesSpy
=
jest
.
fn
().
mockResolvedValue
();
wrapper
=
createComponent
({
config
:
{
...
mockReleaseToken
,
fetchReleases
:
fetchReleasesSpy
},
});
wrapper
.
findComponent
(
GlFilteredSearchToken
).
vm
.
$emit
(
'
input
'
,
{
data
:
search
});
expect
(
fetchReleasesSpy
).
toHaveBeenCalledWith
(
search
);
});
it
(
'
renders error message when request fails
'
,
async
()
=>
{
const
fetchReleasesSpy
=
jest
.
fn
().
mockRejectedValue
();
wrapper
=
createComponent
({
config
:
{
...
mockReleaseToken
,
fetchReleases
:
fetchReleasesSpy
},
});
await
waitForPromises
();
expect
(
createFlash
).
toHaveBeenCalledWith
({
message
:
'
There was a problem fetching releases.
'
,
});
});
});
spec/helpers/issues_helper_spec.rb
View file @
33597ad8
...
...
@@ -326,6 +326,7 @@ RSpec.describe IssuesHelper do
new_issue_path:
new_project_issue_path
(
project
,
issue:
{
milestone_id:
finder
.
milestones
.
first
.
id
}),
project_import_jira_path:
project_import_jira_path
(
project
),
quick_actions_help_path:
help_page_path
(
'user/project/quick_actions'
),
releases_path:
project_releases_path
(
project
,
format: :json
),
reset_path:
new_issuable_address_project_path
(
project
,
issuable_type:
'issue'
),
rss_path:
'#'
,
show_new_issue_link:
'true'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment