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
f9802861
Commit
f9802861
authored
Apr 06, 2021
by
Jose Ivan Vargas
Committed by
Mayra Cabrera
Apr 06, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move branches dropdown to gl-dropdown [RUN ALL RSPEC] [RUN AS-IF-FOSS]
parent
fbe9c42b
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
388 additions
and
16 deletions
+388
-16
app/assets/javascripts/branches/branch_sort_dropdown.js
app/assets/javascripts/branches/branch_sort_dropdown.js
+25
-0
app/assets/javascripts/branches/components/sort_dropdown.vue
app/assets/javascripts/branches/components/sort_dropdown.vue
+88
-0
app/assets/javascripts/pages/projects/branches/index/index.js
...assets/javascripts/pages/projects/branches/index/index.js
+2
-0
app/controllers/projects/branches_controller.rb
app/controllers/projects/branches_controller.rb
+3
-0
app/helpers/branches_helper.rb
app/helpers/branches_helper.rb
+4
-0
app/views/projects/branches/index.html.haml
app/views/projects/branches/index.html.haml
+18
-14
config/feature_flags/development/gldropdown_branches.yml
config/feature_flags/development/gldropdown_branches.yml
+8
-0
spec/features/projects/branches/user_deletes_branch_spec.rb
spec/features/projects/branches/user_deletes_branch_spec.rb
+22
-2
spec/features/projects/branches_spec.rb
spec/features/projects/branches_spec.rb
+77
-0
spec/features/protected_branches_spec.rb
spec/features/protected_branches_spec.rb
+35
-0
spec/frontend/branches/components/sort_dropdown_spec.js
spec/frontend/branches/components/sort_dropdown_spec.js
+91
-0
spec/helpers/branches_helper_spec.rb
spec/helpers/branches_helper_spec.rb
+15
-0
No files found.
app/assets/javascripts/branches/branch_sort_dropdown.js
0 → 100644
View file @
f9802861
import
Vue
from
'
vue
'
;
import
SortDropdown
from
'
./components/sort_dropdown.vue
'
;
const
mountDropdownApp
=
(
el
)
=>
{
const
{
mode
,
projectBranchesFilteredPath
,
sortOptions
}
=
el
.
dataset
;
return
new
Vue
({
el
,
name
:
'
SortBranchesDropdownApp
'
,
components
:
{
SortDropdown
,
},
provide
:
{
mode
,
projectBranchesFilteredPath
,
sortOptions
:
JSON
.
parse
(
sortOptions
),
},
render
:
(
createElement
)
=>
createElement
(
SortDropdown
),
});
};
export
default
()
=>
{
const
el
=
document
.
getElementById
(
'
js-branches-sort-dropdown
'
);
return
el
?
mountDropdownApp
(
el
)
:
null
;
};
app/assets/javascripts/branches/components/sort_dropdown.vue
0 → 100644
View file @
f9802861
<
script
>
import
{
GlDropdown
,
GlDropdownItem
,
GlSearchBoxByClick
}
from
'
@gitlab/ui
'
;
import
{
mergeUrlParams
,
visitUrl
,
getParameterValues
}
from
'
~/lib/utils/url_utility
'
;
import
{
s__
}
from
'
~/locale
'
;
const
OVERVIEW_MODE
=
'
overview
'
;
export
default
{
i18n
:
{
searchPlaceholder
:
s__
(
'
Branches|Filter by branch name
'
),
},
components
:
{
GlDropdown
,
GlDropdownItem
,
GlSearchBoxByClick
,
},
inject
:
[
'
projectBranchesFilteredPath
'
,
'
sortOptions
'
,
'
mode
'
],
data
()
{
return
{
selectedKey
:
'
updated_desc
'
,
searchTerm
:
''
,
};
},
computed
:
{
shouldShowDropdown
()
{
return
this
.
mode
!==
OVERVIEW_MODE
;
},
selectedSortMethodName
()
{
return
this
.
sortOptions
[
this
.
selectedKey
];
},
},
created
()
{
const
sortValue
=
getParameterValues
(
'
sort
'
);
const
searchValue
=
getParameterValues
(
'
search
'
);
if
(
sortValue
.
length
>
0
)
{
[
this
.
selectedKey
]
=
sortValue
;
}
if
(
searchValue
.
length
>
0
)
{
[
this
.
searchTerm
]
=
searchValue
;
}
},
methods
:
{
isSortMethodSelected
(
sortKey
)
{
return
sortKey
===
this
.
selectedKey
;
},
visitUrlFromOption
(
sortKey
)
{
this
.
selectedKey
=
sortKey
;
const
urlParams
=
{};
if
(
this
.
mode
!==
OVERVIEW_MODE
)
{
urlParams
.
sort
=
sortKey
;
}
urlParams
.
search
=
this
.
searchTerm
.
length
>
0
?
this
.
searchTerm
:
null
;
const
newUrl
=
mergeUrlParams
(
urlParams
,
this
.
projectBranchesFilteredPath
);
visitUrl
(
newUrl
);
},
},
};
</
script
>
<
template
>
<div
class=
"gl-display-flex gl-pr-4"
>
<gl-search-box-by-click
v-model=
"searchTerm"
:placeholder=
"$options.i18n.searchPlaceholder"
class=
"gl-pr-4"
data-testid=
"branch-search"
@
submit=
"visitUrlFromOption(selectedKey)"
/>
<gl-dropdown
v-if=
"shouldShowDropdown"
:text=
"selectedSortMethodName"
data-testid=
"branches-dropdown"
>
<gl-dropdown-item
v-for=
"(value, key) in sortOptions"
:key=
"key"
:is-checked=
"isSortMethodSelected(key)"
is-check-item
@
click=
"visitUrlFromOption(key)"
>
{{
value
}}
</gl-dropdown-item
>
</gl-dropdown>
</div>
</
template
>
app/assets/javascripts/pages/projects/branches/index/index.js
View file @
f9802861
import
AjaxLoadingSpinner
from
'
~/branches/ajax_loading_spinner
'
;
import
BranchSortDropdown
from
'
~/branches/branch_sort_dropdown
'
;
import
DeleteModal
from
'
~/branches/branches_delete_modal
'
;
import
initDiverganceGraph
from
'
~/branches/divergence_graph
'
;
AjaxLoadingSpinner
.
init
();
new
DeleteModal
();
// eslint-disable-line no-new
initDiverganceGraph
(
document
.
querySelector
(
'
.js-branch-list
'
).
dataset
.
divergingCountsEndpoint
);
BranchSortDropdown
();
app/controllers/projects/branches_controller.rb
View file @
f9802861
...
...
@@ -12,6 +12,9 @@ class Projects::BranchesController < Projects::ApplicationController
# Support legacy URLs
before_action
:redirect_for_legacy_index_sort_or_search
,
only:
[
:index
]
before_action
:limit_diverging_commit_counts!
,
only:
[
:diverging_commit_counts
]
before_action
do
push_frontend_feature_flag
(
:gldropdown_branches
)
end
feature_category
:source_code_management
...
...
app/helpers/branches_helper.rb
View file @
f9802861
...
...
@@ -20,6 +20,10 @@ module BranchesHelper
end
end
end
def
gldropdrown_branches_enabled?
Feature
.
enabled?
(
:gldropdown_branches
)
end
end
BranchesHelper
.
prepend_if_ee
(
'EE::BranchesHelper'
)
app/views/projects/branches/index.html.haml
View file @
f9802861
...
...
@@ -16,6 +16,7 @@
=
link_to
s_
(
'Branches|All'
),
project_branches_filtered_path
(
@project
,
state:
'all'
),
title:
s_
(
'Branches|Show all branches'
)
.nav-controls
-
if
!
gldropdrown_branches_enabled?
=
form_tag
(
project_branches_filtered_path
(
@project
,
state:
'all'
),
method: :get
)
do
=
search_field_tag
:search
,
params
[
:search
],
{
placeholder:
s_
(
'Branches|Filter by branch name'
),
id:
'branch-search'
,
class:
'form-control search-text-input input-short'
,
spellcheck:
false
}
...
...
@@ -32,6 +33,9 @@
%li
=
link_to
title
,
project_branches_filtered_path
(
@project
,
state:
'all'
,
search:
params
[
:search
],
sort:
value
),
class:
(
"is-active"
if
@sort
==
value
)
-
else
#js-branches-sort-dropdown
{
data:
{
project_branches_filtered_path:
project_branches_path
(
@project
,
state:
'all'
),
sort_options:
branches_sort_options_hash
.
to_json
,
mode:
@mode
}
}
-
if
can?
current_user
,
:push_code
,
@project
=
link_to
project_merged_branches_path
(
@project
),
class:
'gl-button btn btn-danger btn-danger-secondary has-tooltip qa-delete-merged-branches'
,
...
...
config/feature_flags/development/gldropdown_branches.yml
0 → 100644
View file @
f9802861
---
name
:
gldropdown_branches
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57760
rollout_issue_url
:
https://gitlab.com/gitlab-org/gitlab/-/issues/326549
milestone
:
'
13.11'
type
:
development
group
:
group::continuous integration
default_enabled
:
false
spec/features/projects/branches/user_deletes_branch_spec.rb
View file @
f9802861
...
...
@@ -9,12 +9,31 @@ RSpec.describe "User deletes branch", :js do
before
do
project
.
add_developer
(
user
)
sign_in
(
user
)
end
it
"deletes branch"
do
stub_feature_flags
(
gldropdown_branches:
false
)
visit
(
project_branches_path
(
project
))
fill_in
(
"branch-search"
,
with:
"improve/awesome"
).
native
.
send_keys
(
:enter
)
page
.
within
(
".js-branch-improve
\\
/awesome"
)
do
accept_alert
{
find
(
".btn-danger"
).
click
}
end
wait_for_requests
expect
(
page
).
to
have_css
(
".js-branch-improve
\\
/awesome"
,
visible: :hidden
)
end
context
'with gldropdown_branches enabled'
do
it
"deletes branch"
do
fill_in
(
"branch-search"
,
with:
"improve/awesome"
).
native
.
send_keys
(
:enter
)
visit
(
project_branches_path
(
project
))
branch_search
=
find
(
'input[data-testid="branch-search"]'
)
branch_search
.
set
(
'improve/awesome'
)
branch_search
.
native
.
send_keys
(
:enter
)
page
.
within
(
".js-branch-improve
\\
/awesome"
)
do
accept_alert
{
find
(
".btn-danger"
).
click
}
...
...
@@ -24,4 +43,5 @@ RSpec.describe "User deletes branch", :js do
expect
(
page
).
to
have_css
(
".js-branch-improve
\\
/awesome"
,
visible: :hidden
)
end
end
end
spec/features/projects/branches_spec.rb
View file @
f9802861
...
...
@@ -86,6 +86,7 @@ RSpec.describe 'Branches' do
describe
'Find branches'
do
it
'shows filtered branches'
,
:js
do
stub_feature_flags
(
gldropdown_branches:
false
)
visit
project_branches_path
(
project
)
fill_in
'branch-search'
,
with:
'fix'
...
...
@@ -94,6 +95,20 @@ RSpec.describe 'Branches' do
expect
(
page
).
to
have_content
(
'fix'
)
expect
(
find
(
'.all-branches'
)).
to
have_selector
(
'li'
,
count:
1
)
end
context
'with gldropdown_branches enabled'
do
it
'shows filtered branches'
,
:js
do
visit
project_branches_path
(
project
)
branch_search
=
find
(
'input[data-testid="branch-search"]'
)
branch_search
.
set
(
'fix'
)
branch_search
.
native
.
send_keys
(
:enter
)
expect
(
page
).
to
have_content
(
'fix'
)
expect
(
find
(
'.all-branches'
)).
to
have_selector
(
'li'
,
count:
1
)
end
end
end
describe
'Delete unprotected branch on Overview'
do
...
...
@@ -115,6 +130,7 @@ RSpec.describe 'Branches' do
end
it
'sorts the branches by name'
do
stub_feature_flags
(
gldropdown_branches:
false
)
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
click_button
"Last updated"
# Open sorting dropdown
...
...
@@ -123,7 +139,21 @@ RSpec.describe 'Branches' do
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
20
,
sort_by: :name
))
end
context
'with gldropdown_branches enabled'
do
it
'sorts the branches by name'
,
:js
do
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
click_button
"Last updated"
# Open sorting dropdown
within
'[data-testid="branches-dropdown"]'
do
find
(
'p'
,
text:
'Name'
).
click
end
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
20
,
sort_by: :name
))
end
end
it
'sorts the branches by oldest updated'
do
stub_feature_flags
(
gldropdown_branches:
false
)
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
click_button
"Last updated"
# Open sorting dropdown
...
...
@@ -132,6 +162,19 @@ RSpec.describe 'Branches' do
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
20
,
sort_by: :updated_asc
))
end
context
'with gldropdown_branches enabled'
do
it
'sorts the branches by oldest updated'
,
:js
do
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
click_button
"Last updated"
# Open sorting dropdown
within
'[data-testid="branches-dropdown"]'
do
find
(
'p'
,
text:
'Oldest updated'
).
click
end
expect
(
page
).
to
have_content
(
sorted_branches
(
repository
,
count:
20
,
sort_by: :updated_asc
))
end
end
it
'avoids a N+1 query in branches index'
do
control_count
=
ActiveRecord
::
QueryRecorder
.
new
{
visit
project_branches_path
(
project
)
}.
count
...
...
@@ -143,6 +186,7 @@ RSpec.describe 'Branches' do
describe
'Find branches on All branches'
do
it
'shows filtered branches'
,
:js
do
stub_feature_flags
(
gldropdown_branches:
false
)
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
fill_in
'branch-search'
,
with:
'fix'
...
...
@@ -151,10 +195,25 @@ RSpec.describe 'Branches' do
expect
(
page
).
to
have_content
(
'fix'
)
expect
(
find
(
'.all-branches'
)).
to
have_selector
(
'li'
,
count:
1
)
end
context
'with gldropdown_branches enabled'
do
it
'shows filtered branches'
,
:js
do
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
branch_search
=
find
(
'input[data-testid="branch-search"]'
)
branch_search
.
set
(
'fix'
)
branch_search
.
native
.
send_keys
(
:enter
)
expect
(
page
).
to
have_content
(
'fix'
)
expect
(
find
(
'.all-branches'
)).
to
have_selector
(
'li'
,
count:
1
)
end
end
end
describe
'Delete unprotected branch on All branches'
do
it
'removes branch after confirmation'
,
:js
do
stub_feature_flags
(
gldropdown_branches:
false
)
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
fill_in
'branch-search'
,
with:
'fix'
...
...
@@ -168,6 +227,24 @@ RSpec.describe 'Branches' do
expect
(
page
).
not_to
have_content
(
'fix'
)
expect
(
find
(
'.all-branches'
)).
to
have_selector
(
'li'
,
count:
0
)
end
context
'with gldropdown_branches enabled'
do
it
'removes branch after confirmation'
,
:js
do
visit
project_branches_filtered_path
(
project
,
state:
'all'
)
branch_search
=
find
(
'input[data-testid="branch-search"]'
)
branch_search
.
set
(
'fix'
)
branch_search
.
native
.
send_keys
(
:enter
)
expect
(
page
).
to
have_content
(
'fix'
)
expect
(
find
(
'.all-branches'
)).
to
have_selector
(
'li'
,
count:
1
)
accept_confirm
{
find
(
'.js-branch-fix .btn-danger'
).
click
}
expect
(
page
).
not_to
have_content
(
'fix'
)
expect
(
find
(
'.all-branches'
)).
to
have_selector
(
'li'
,
count:
0
)
end
end
end
context
'on project with 0 branch'
do
...
...
spec/features/protected_branches_spec.rb
View file @
f9802861
...
...
@@ -22,6 +22,7 @@ RSpec.describe 'Protected Branches', :js do
end
it
'does not allow developer to removes protected branch'
do
stub_feature_flags
(
gldropdown_branches:
false
)
visit
project_branches_path
(
project
)
fill_in
'branch-search'
,
with:
'fix'
...
...
@@ -29,6 +30,17 @@ RSpec.describe 'Protected Branches', :js do
expect
(
page
).
to
have_css
(
'.btn-danger.disabled'
)
end
context
'with gldropdown_branches enabled'
do
it
'does not allow developer to removes protected branch'
do
visit
project_branches_path
(
project
)
find
(
'input[data-testid="branch-search"]'
).
set
(
'fix'
)
find
(
'input[data-testid="branch-search"]'
).
native
.
send_keys
(
:enter
)
expect
(
page
).
to
have_css
(
'.btn-danger.disabled'
)
end
end
end
end
...
...
@@ -45,6 +57,7 @@ RSpec.describe 'Protected Branches', :js do
end
it
'removes branch after modal confirmation'
do
stub_feature_flags
(
gldropdown_branches:
false
)
visit
project_branches_path
(
project
)
fill_in
'branch-search'
,
with:
'fix'
...
...
@@ -63,6 +76,28 @@ RSpec.describe 'Protected Branches', :js do
expect
(
page
).
to
have_content
(
'No branches to show'
)
end
context
'with gldropdown_branches enabled'
do
it
'removes branch after modal confirmation'
do
visit
project_branches_path
(
project
)
find
(
'input[data-testid="branch-search"]'
).
set
(
'fix'
)
find
(
'input[data-testid="branch-search"]'
).
native
.
send_keys
(
:enter
)
expect
(
page
).
to
have_content
(
'fix'
)
expect
(
find
(
'.all-branches'
)).
to
have_selector
(
'li'
,
count:
1
)
page
.
find
(
'[data-target="#modal-delete-branch"]'
).
click
expect
(
page
).
to
have_css
(
'.js-delete-branch[disabled]'
)
fill_in
'delete_branch_input'
,
with:
'fix'
click_link
'Delete protected branch'
find
(
'input[data-testid="branch-search"]'
).
set
(
'fix'
)
find
(
'input[data-testid="branch-search"]'
).
native
.
send_keys
(
:enter
)
expect
(
page
).
to
have_content
(
'No branches to show'
)
end
end
end
end
...
...
spec/frontend/branches/components/sort_dropdown_spec.js
0 → 100644
View file @
f9802861
import
{
GlSearchBoxByClick
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
SortDropdown
from
'
~/branches/components/sort_dropdown.vue
'
;
import
*
as
urlUtils
from
'
~/lib/utils/url_utility
'
;
describe
(
'
Branches Sort Dropdown
'
,
()
=>
{
let
wrapper
;
const
createWrapper
=
(
props
=
{})
=>
{
return
extendedWrapper
(
mount
(
SortDropdown
,
{
provide
:
{
mode
:
'
overview
'
,
projectBranchesFilteredPath
:
'
/root/ci-cd-project-demo/-/branches?state=all
'
,
sortOptions
:
{
name_asc
:
'
Name
'
,
updated_asc
:
'
Oldest updated
'
,
updated_desc
:
'
Last updated
'
,
},
...
props
,
},
}),
);
};
const
findSearchBox
=
()
=>
wrapper
.
findComponent
(
GlSearchBoxByClick
);
const
findBranchesDropdown
=
()
=>
wrapper
.
findByTestId
(
'
branches-dropdown
'
);
afterEach
(()
=>
{
if
(
wrapper
)
{
wrapper
.
destroy
();
}
});
describe
(
'
When in overview mode
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createWrapper
();
});
it
(
'
should have a search box with a placeholder
'
,
()
=>
{
const
searchBox
=
findSearchBox
();
expect
(
searchBox
.
exists
()).
toBe
(
true
);
expect
(
searchBox
.
find
(
'
input
'
).
attributes
(
'
placeholder
'
)).
toBe
(
'
Filter by branch name
'
);
});
it
(
'
should not have a branches dropdown when in overview mode
'
,
()
=>
{
const
branchesDropdown
=
findBranchesDropdown
();
expect
(
branchesDropdown
.
exists
()).
toBe
(
false
);
});
});
describe
(
'
when in All branches mode
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createWrapper
({
mode
:
'
all
'
});
});
it
(
'
should have a search box with a placeholder
'
,
()
=>
{
const
searchBox
=
findSearchBox
();
expect
(
searchBox
.
exists
()).
toBe
(
true
);
expect
(
searchBox
.
find
(
'
input
'
).
attributes
(
'
placeholder
'
)).
toBe
(
'
Filter by branch name
'
);
});
it
(
'
should have a branches dropdown when in all branches mode
'
,
()
=>
{
const
branchesDropdown
=
findBranchesDropdown
();
expect
(
branchesDropdown
.
exists
()).
toBe
(
true
);
});
});
describe
(
'
when submitting a search term
'
,
()
=>
{
beforeEach
(()
=>
{
urlUtils
.
visitUrl
=
jest
.
fn
();
wrapper
=
createWrapper
();
});
it
(
'
should call visitUrl
'
,
()
=>
{
const
searchBox
=
findSearchBox
();
searchBox
.
vm
.
$emit
(
'
submit
'
);
expect
(
urlUtils
.
visitUrl
).
toHaveBeenCalledWith
(
'
/root/ci-cd-project-demo/-/branches?state=all
'
,
);
});
});
});
spec/helpers/branches_helper_spec.rb
View file @
f9802861
...
...
@@ -47,4 +47,19 @@ RSpec.describe BranchesHelper do
end
end
end
describe
'#gl_dropdown_branches_enabled?'
do
context
'when the feature is enabled'
do
it
'returns true'
do
expect
(
helper
.
gldropdrown_branches_enabled?
).
to
be_truthy
end
end
context
'when the feature is disabled'
do
it
'returns false'
do
stub_feature_flags
(
gldropdown_branches:
false
)
expect
(
helper
.
gldropdrown_branches_enabled?
).
to
be_falsy
end
end
end
end
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