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
670254b6
Commit
670254b6
authored
Jan 05, 2021
by
Olena Horal-Koretska
Committed by
David O'Regan
Jan 05, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace GlDeprecatedDropdown in related_items_tree
parent
3ae06d3d
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
59 additions
and
134 deletions
+59
-134
ee/app/assets/javascripts/related_items_tree/components/create_issue_form.vue
...ripts/related_items_tree/components/create_issue_form.vue
+22
-51
ee/app/assets/javascripts/related_items_tree/components/epic_issue_actions_split_button.vue
...items_tree/components/epic_issue_actions_split_button.vue
+14
-26
ee/changelogs/unreleased/233596-replace-deprecated-dropdown.yml
...ngelogs/unreleased/233596-replace-deprecated-dropdown.yml
+5
-0
ee/spec/frontend/related_items_tree/components/create_issue_form_spec.js
...d/related_items_tree/components/create_issue_form_spec.js
+18
-57
No files found.
ee/app/assets/javascripts/related_items_tree/components/create_issue_form.vue
View file @
670254b6
...
...
@@ -2,8 +2,8 @@
import
{
mapState
,
mapActions
}
from
'
vuex
'
;
import
{
GlButton
,
GlD
eprecatedD
ropdown
,
GlD
eprecatedD
ropdownItem
,
GlDropdown
,
GlDropdownItem
,
GlFormInput
,
GlSearchBoxByType
,
GlLoadingIcon
,
...
...
@@ -17,8 +17,8 @@ import { SEARCH_DEBOUNCE } from '../constants';
export
default
{
components
:
{
GlButton
,
GlD
eprecatedD
ropdown
,
GlD
eprecatedD
ropdownItem
,
GlDropdown
,
GlDropdownItem
,
GlFormInput
,
GlSearchBoxByType
,
GlLoadingIcon
,
...
...
@@ -29,7 +29,6 @@ export default {
selectedProject
:
null
,
searchKey
:
''
,
title
:
''
,
preventDropdownClose
:
false
,
};
},
computed
:
{
...
...
@@ -83,32 +82,6 @@ export default {
this
.
searchKey
=
''
;
this
.
fetchProjects
();
},
handleDropdownHide
(
e
)
{
// Check if dropdown closure is to be prevented.
if
(
this
.
preventDropdownClose
)
{
e
.
preventDefault
();
this
.
preventDropdownClose
=
false
;
}
},
/**
* As GlDropdown can get closed if any item within
* it is clicked, we have to work around that behaviour
* by preventing dropdown close if user has clicked
* clear button on search input field. This hack
* won't be required once we add support for
* `BDropdownForm` https://bootstrap-vue.js.org/docs/components/dropdown#b-dropdown-form
* within GitLab UI.
*/
handleSearchInputContainerClick
({
target
})
{
// Check if clicked target was an icon.
if
(
target
?.
classList
.
contains
(
'
gl-icon
'
)
||
target
?.
getAttribute
(
'
href
'
)?.
includes
(
'
clear
'
)
)
{
// Enable flag to prevent dropdown close.
this
.
preventDropdownClose
=
true
;
}
},
},
};
</
script
>
...
...
@@ -129,43 +102,41 @@ export default {
</div>
<div
class=
"col-sm"
>
<label
class=
"label-bold"
>
{{
__
(
'
Project
'
)
}}
</label>
<gl-d
eprecated-d
ropdown
<gl-dropdown
ref=
"dropdownButton"
:text=
"dropdownToggleText"
class=
"
w-100
projects-dropdown"
menu-class=
"
w-100 overflow-hidden
"
toggle-class=
"
d-flex align-items-center justify-content-between
text-truncate"
class=
"
gl-w-full
projects-dropdown"
menu-class=
"
gl-w-full! gl-overflow-hidden!
"
toggle-class=
"
gl-display-flex gl-align-items-center gl-justify-content-between gl-
text-truncate"
@
show=
"handleDropdownShow"
@
hide=
"handleDropdownHide"
>
<div
class=
"mx-2 mb-1"
@
click=
"handleSearchInputContainerClick"
>
<gl-search-box-by-type
ref=
"searchInputField"
v-model=
"searchKey"
:disabled=
"projectsFetchInProgress"
/>
</div>
<gl-search-box-by-type
ref=
"searchInputField"
v-model=
"searchKey"
class=
"gl-mx-3 gl-mb-2"
:disabled=
"projectsFetchInProgress"
/>
<gl-loading-icon
v-show=
"projectsFetchInProgress"
class=
"projects-fetch-loading
align-items-center p-2
"
class=
"projects-fetch-loading
gl-align-items-center gl-p-3
"
size=
"md"
/>
<div
v-if=
"!projectsFetchInProgress"
class=
"dropdown-contents
overflow-auto p-1
"
>
<span
v-if=
"!projects.length"
class=
"
d-block text-center p-2
"
>
{{
<div
v-if=
"!projectsFetchInProgress"
class=
"dropdown-contents
gl-overflow-auto gl-p-2
"
>
<span
v-if=
"!projects.length"
class=
"
gl-display-block text-center gl-p-3
"
>
{{
__
(
'
No matches found
'
)
}}
</span>
<gl-d
eprecated-d
ropdown-item
<gl-dropdown-item
v-for=
"project in projects"
:key=
"project.id"
class=
"w-100"
class=
"gl-w-full"
:secondary-text=
"project.namespace.name"
@
click=
"selectedProject = project"
>
<project-avatar
:project=
"project"
:size=
"32"
/>
{{
project
.
name
}}
<div
class=
"text-secondary"
>
{{
project
.
namespace
.
name
}}
</div>
</gl-deprecated-dropdown-item>
</gl-dropdown-item>
</div>
</gl-d
eprecated-d
ropdown>
</gl-dropdown>
</div>
</div>
...
...
ee/app/assets/javascripts/related_items_tree/components/epic_issue_actions_split_button.vue
View file @
670254b6
<
script
>
import
{
GlDeprecatedDropdown
,
GlDeprecatedDropdownDivider
,
GlDeprecatedDropdownHeader
,
GlDeprecatedDropdownItem
,
}
from
'
@gitlab/ui
'
;
import
{
GlDropdown
,
GlDropdownDivider
,
GlDropdownSectionHeader
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
s__
,
__
}
from
'
~/locale
'
;
...
...
@@ -34,10 +29,10 @@ export default {
epicActionItems
,
issueActionItems
,
components
:
{
GlD
eprecatedD
ropdown
,
GlD
eprecatedD
ropdownDivider
,
GlD
eprecatedDropdow
nHeader
,
GlD
eprecatedD
ropdownItem
,
GlDropdown
,
GlDropdownDivider
,
GlD
ropdownSectio
nHeader
,
GlDropdownItem
,
},
props
:
{
allowSubEpics
:
{
...
...
@@ -55,32 +50,25 @@ export default {
</
script
>
<
template
>
<gl-deprecated-dropdown
:text=
"__('Add')"
variant=
"secondary"
data-qa-selector=
"epic_issue_actions_split_button"
right
>
<gl-deprecated-dropdown-header>
{{
__
(
'
Issue
'
)
}}
</gl-deprecated-dropdown-header>
<gl-deprecated-dropdown-item
<gl-dropdown
:text=
"__('Add')"
data-qa-selector=
"epic_issue_actions_split_button"
right
>
<gl-dropdown-section-header>
{{
__
(
'
Issue
'
)
}}
</gl-dropdown-section-header>
<gl-dropdown-item
v-for=
"item in $options.issueActionItems"
:key=
"item.eventName"
active-class=
"is-active"
@
click=
"change(item)"
>
{{
item
.
title
}}
</gl-d
eprecated-d
ropdown-item>
</gl-dropdown-item>
<template
v-if=
"allowSubEpics"
>
<gl-d
eprecated-d
ropdown-divider
/>
<gl-d
eprecated-dropdown-header>
{{
__
(
'
Epic
'
)
}}
</gl-deprecated-dropdow
n-header>
<gl-d
eprecated-d
ropdown-item
<gl-dropdown-divider
/>
<gl-d
ropdown-section-header>
{{
__
(
'
Epic
'
)
}}
</gl-dropdown-sectio
n-header>
<gl-dropdown-item
v-for=
"item in $options.epicActionItems"
:key=
"item.eventName"
active-class=
"is-active"
@
click=
"change(item)"
>
{{
item
.
title
}}
</gl-d
eprecated-d
ropdown-item>
</gl-dropdown-item>
</
template
>
</gl-d
eprecated-d
ropdown>
</gl-dropdown>
</template>
ee/changelogs/unreleased/233596-replace-deprecated-dropdown.yml
0 → 100644
View file @
670254b6
---
title
:
Update the create issue form and epic issue actions dropdowns to use our Pajamas compliant components
merge_request
:
50633
author
:
type
:
other
ee/spec/frontend/related_items_tree/components/create_issue_form_spec.js
View file @
670254b6
import
{
GlButton
,
GlD
eprecatedD
ropdown
,
GlD
eprecatedD
ropdownItem
,
GlDropdown
,
GlDropdownItem
,
GlFormInput
,
GlSearchBoxByType
,
GlLoadingIcon
,
...
...
@@ -48,7 +48,6 @@ describe('CreateIssueForm', () => {
expect
(
wrapper
.
vm
.
selectedProject
).
toBeNull
();
expect
(
wrapper
.
vm
.
searchKey
).
toBe
(
''
);
expect
(
wrapper
.
vm
.
title
).
toBe
(
''
);
expect
(
wrapper
.
vm
.
preventDropdownClose
).
toBe
(
false
);
});
});
...
...
@@ -111,51 +110,12 @@ describe('CreateIssueForm', () => {
expect
(
handleDropdownShow
).
toHaveBeenCalled
();
});
});
describe
(
'
handleDropdownHide
'
,
()
=>
{
it
(
'
sets `searchKey` prop to empty string and calls action `fetchProjects`
'
,
()
=>
{
const
event
=
{
preventDefault
:
jest
.
fn
(),
};
const
preventDefault
=
jest
.
spyOn
(
event
,
'
preventDefault
'
);
wrapper
.
setData
({
preventDropdownClose
:
true
,
});
wrapper
.
vm
.
handleDropdownHide
(
event
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
preventDefault
).
toHaveBeenCalled
();
expect
(
wrapper
.
vm
.
preventDropdownClose
).
toBe
(
false
);
});
});
});
describe
(
'
handleSearchInputContainerClick
'
,
()
=>
{
it
(
'
sets `preventDropdownClose` to `true` when target element contains class `gl-icon`
'
,
()
=>
{
const
target
=
document
.
createElement
(
'
span
'
);
target
.
setAttribute
(
'
class
'
,
'
gl-icon
'
);
wrapper
.
vm
.
handleSearchInputContainerClick
({
target
});
expect
(
wrapper
.
vm
.
preventDropdownClose
).
toBe
(
true
);
});
it
(
'
sets `preventDropdownClose` to `true` when target element href contains text `clear`
'
,
()
=>
{
const
target
=
document
.
createElement
(
'
user
'
);
target
.
setAttribute
(
'
href
'
,
'
foo.svg#clear
'
);
wrapper
.
vm
.
handleSearchInputContainerClick
({
target
});
expect
(
wrapper
.
vm
.
preventDropdownClose
).
toBe
(
true
);
});
});
});
describe
(
'
templates
'
,
()
=>
{
it
(
'
renders Issue title input field
'
,
()
=>
{
const
issueTitleFieldLabel
=
wrapper
.
findAll
(
'
label
'
).
at
(
0
);
const
issueTitleFieldInput
=
wrapper
.
find
(
GlFormInput
);
const
issueTitleFieldInput
=
wrapper
.
find
Component
(
GlFormInput
);
expect
(
issueTitleFieldLabel
.
text
()).
toBe
(
'
Title
'
);
expect
(
issueTitleFieldInput
.
attributes
(
'
placeholder
'
)).
toBe
(
'
New issue title
'
);
...
...
@@ -163,7 +123,7 @@ describe('CreateIssueForm', () => {
it
(
'
renders Projects dropdown field
'
,
()
=>
{
const
projectsDropdownLabel
=
wrapper
.
findAll
(
'
label
'
).
at
(
1
);
const
projectsDropdownButton
=
wrapper
.
find
(
GlDeprecated
Dropdown
);
const
projectsDropdownButton
=
wrapper
.
find
Component
(
Gl
Dropdown
);
expect
(
projectsDropdownLabel
.
text
()).
toBe
(
'
Project
'
);
expect
(
projectsDropdownButton
.
props
(
'
text
'
)).
toBe
(
'
Select a project
'
);
...
...
@@ -173,15 +133,16 @@ describe('CreateIssueForm', () => {
wrapper
.
vm
.
$store
.
dispatch
(
'
receiveProjectsSuccess
'
,
mockProjects
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
const
projectsDropdownButton
=
wrapper
.
find
(
GlDeprecatedDropdown
);
const
dropdownItems
=
projectsDropdownButton
.
findAll
(
GlDeprecatedDropdownItem
);
const
projectsDropdownButton
=
wrapper
.
findComponent
(
GlDropdown
);
const
dropdownItems
=
projectsDropdownButton
.
findAllComponents
(
GlDropdownItem
);
const
dropdownItem
=
dropdownItems
.
at
(
0
);
expect
(
projectsDropdownButton
.
find
(
GlSearchBoxByType
).
exists
()).
toBe
(
true
);
expect
(
projectsDropdownButton
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
true
);
expect
(
projectsDropdownButton
.
find
Component
(
GlSearchBoxByType
).
exists
()).
toBe
(
true
);
expect
(
projectsDropdownButton
.
find
Component
(
GlLoadingIcon
).
exists
()).
toBe
(
true
);
expect
(
dropdownItems
).
toHaveLength
(
mockProjects
.
length
);
expect
(
dropdownItem
s
.
at
(
0
).
text
()).
toContain
(
mockProjects
[
0
].
name
);
expect
(
dropdownItem
s
.
at
(
0
).
text
()).
toContain
(
mockProjects
[
0
].
namespace
.
name
);
expect
(
dropdownItem
s
.
at
(
0
).
find
(
ProjectAvatar
).
exists
()).
toBe
(
true
);
expect
(
dropdownItem
.
text
()).
toBe
(
mockProjects
[
0
].
name
);
expect
(
dropdownItem
.
attributes
(
'
secondarytext
'
)).
toBe
(
mockProjects
[
0
].
namespace
.
name
);
expect
(
dropdownItem
.
findComponent
(
ProjectAvatar
).
exists
()).
toBe
(
true
);
});
});
...
...
@@ -190,7 +151,7 @@ describe('CreateIssueForm', () => {
const
filteredMockProjects
=
mockProjects
.
filter
((
project
)
=>
project
.
name
===
searchKey
);
jest
.
spyOn
(
wrapper
.
vm
,
'
fetchProjects
'
).
mockImplementation
(
jest
.
fn
());
wrapper
.
find
(
GlDeprecated
Dropdown
).
trigger
(
'
click
'
);
wrapper
.
find
Component
(
Gl
Dropdown
).
trigger
(
'
click
'
);
wrapper
.
setData
({
searchKey
,
...
...
@@ -202,7 +163,7 @@ describe('CreateIssueForm', () => {
wrapper
.
vm
.
$store
.
dispatch
(
'
receiveProjectsSuccess
'
,
filteredMockProjects
);
})
.
then
(()
=>
{
expect
(
wrapper
.
findAll
(
GlDeprecated
DropdownItem
)).
toHaveLength
(
1
);
expect
(
wrapper
.
findAll
Components
(
Gl
DropdownItem
)).
toHaveLength
(
1
);
});
});
...
...
@@ -211,7 +172,7 @@ describe('CreateIssueForm', () => {
const
filteredMockProjects
=
mockProjects
.
filter
((
project
)
=>
project
.
name
===
searchKey
);
jest
.
spyOn
(
wrapper
.
vm
,
'
fetchProjects
'
).
mockImplementation
(
jest
.
fn
());
wrapper
.
find
(
GlDeprecated
Dropdown
).
trigger
(
'
click
'
);
wrapper
.
find
Component
(
Gl
Dropdown
).
trigger
(
'
click
'
);
wrapper
.
setData
({
searchKey
,
...
...
@@ -228,7 +189,7 @@ describe('CreateIssueForm', () => {
});
it
(
'
renders `Create issue` button
'
,
()
=>
{
const
createIssueButton
=
wrapper
.
findAll
(
GlButton
).
at
(
0
);
const
createIssueButton
=
wrapper
.
findAll
Components
(
GlButton
).
at
(
0
);
expect
(
createIssueButton
.
exists
()).
toBe
(
true
);
expect
(
createIssueButton
.
text
()).
toBe
(
'
Create issue
'
);
...
...
@@ -238,7 +199,7 @@ describe('CreateIssueForm', () => {
wrapper
.
vm
.
$store
.
dispatch
(
'
requestCreateItem
'
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
const
createIssueButton
=
wrapper
.
findAll
(
GlButton
).
at
(
0
);
const
createIssueButton
=
wrapper
.
findAll
Components
(
GlButton
).
at
(
0
);
expect
(
createIssueButton
.
exists
()).
toBe
(
true
);
expect
(
createIssueButton
.
props
(
'
disabled
'
)).
toBe
(
true
);
...
...
@@ -247,7 +208,7 @@ describe('CreateIssueForm', () => {
});
it
(
'
renders `Cancel` button
'
,
()
=>
{
const
cancelButton
=
wrapper
.
findAll
(
GlButton
).
at
(
1
);
const
cancelButton
=
wrapper
.
findAll
Components
(
GlButton
).
at
(
1
);
expect
(
cancelButton
.
exists
()).
toBe
(
true
);
expect
(
cancelButton
.
text
()).
toBe
(
'
Cancel
'
);
...
...
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