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
aa137fd3
Commit
aa137fd3
authored
Aug 09, 2019
by
minghuan lei
Committed by
Paul Slaughter
Aug 09, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add repo-refs control for search page
- only in blobs result
parent
e0e6e9e7
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
196 additions
and
28 deletions
+196
-28
app/assets/javascripts/lib/utils/forms.js
app/assets/javascripts/lib/utils/forms.js
+12
-0
app/assets/javascripts/pages/projects/project.js
app/assets/javascripts/pages/projects/project.js
+11
-12
app/assets/javascripts/pages/search/show/search.js
app/assets/javascripts/pages/search/show/search.js
+3
-0
app/views/search/_form.html.haml
app/views/search/_form.html.haml
+1
-0
app/views/search/_results.html.haml
app/views/search/_results.html.haml
+12
-4
app/views/shared/_ref_switcher.html.haml
app/views/shared/_ref_switcher.html.haml
+11
-4
changelogs/unreleased/59712-resolve-the-search-problem-issue.yml
...ogs/unreleased/59712-resolve-the-search-problem-issue.yml
+5
-0
locale/gitlab.pot
locale/gitlab.pot
+6
-0
spec/features/search/user_searches_for_code_spec.rb
spec/features/search/user_searches_for_code_spec.rb
+61
-8
spec/frontend/lib/utils/forms_spec.js
spec/frontend/lib/utils/forms_spec.js
+74
-0
No files found.
app/assets/javascripts/lib/utils/forms.js
0 → 100644
View file @
aa137fd3
export
const
serializeFormEntries
=
entries
=>
entries
.
reduce
((
acc
,
{
name
,
value
})
=>
Object
.
assign
(
acc
,
{
[
name
]:
value
}),
{});
export
const
serializeForm
=
form
=>
{
const
fdata
=
new
FormData
(
form
);
const
entries
=
Array
.
from
(
fdata
.
keys
()).
map
(
key
=>
{
const
val
=
fdata
.
getAll
(
key
);
return
{
name
:
key
,
value
:
val
.
length
===
1
?
val
[
0
]
:
val
};
});
return
serializeFormEntries
(
entries
);
};
app/assets/javascripts/pages/projects/project.js
View file @
aa137fd3
/* eslint-disable func-names, no-var, no-return-assign, o
ne-var, o
bject-shorthand, vars-on-top */
/* eslint-disable func-names, no-var, no-return-assign, object-shorthand, vars-on-top */
import
$
from
'
jquery
'
;
import
$
from
'
jquery
'
;
import
Cookies
from
'
js-cookie
'
;
import
Cookies
from
'
js-cookie
'
;
import
{
__
}
from
'
~/locale
'
;
import
{
__
}
from
'
~/locale
'
;
import
{
visitUrl
}
from
'
~/lib/utils/url_utility
'
;
import
{
visitUrl
,
mergeUrlParams
}
from
'
~/lib/utils/url_utility
'
;
import
{
serializeForm
}
from
'
~/lib/utils/forms
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
flash
from
'
~/flash
'
;
import
flash
from
'
~/flash
'
;
import
projectSelect
from
'
../../project_select
'
;
import
projectSelect
from
'
../../project_select
'
;
...
@@ -107,9 +108,10 @@ export default class Project {
...
@@ -107,9 +108,10 @@ export default class Project {
refLink
.
href
=
'
#
'
;
refLink
.
href
=
'
#
'
;
return
$
(
'
.js-project-refs-dropdown
'
).
each
(
function
()
{
return
$
(
'
.js-project-refs-dropdown
'
).
each
(
function
()
{
var
$dropdown
,
selected
;
var
$dropdown
=
$
(
this
);
$dropdown
=
$
(
this
);
var
selected
=
$dropdown
.
data
(
'
selected
'
);
selected
=
$dropdown
.
data
(
'
selected
'
);
var
fieldName
=
$dropdown
.
data
(
'
fieldName
'
);
var
shouldVisit
=
Boolean
(
$dropdown
.
data
(
'
visit
'
));
return
$dropdown
.
glDropdown
({
return
$dropdown
.
glDropdown
({
data
(
term
,
callback
)
{
data
(
term
,
callback
)
{
axios
axios
...
@@ -127,7 +129,7 @@ export default class Project {
...
@@ -127,7 +129,7 @@ export default class Project {
filterRemote
:
true
,
filterRemote
:
true
,
filterByText
:
true
,
filterByText
:
true
,
inputFieldName
:
$dropdown
.
data
(
'
inputFieldName
'
),
inputFieldName
:
$dropdown
.
data
(
'
inputFieldName
'
),
fieldName
:
$dropdown
.
data
(
'
fieldName
'
)
,
fieldName
,
renderRow
:
function
(
ref
)
{
renderRow
:
function
(
ref
)
{
var
li
=
refListItem
.
cloneNode
(
false
);
var
li
=
refListItem
.
cloneNode
(
false
);
...
@@ -158,15 +160,12 @@ export default class Project {
...
@@ -158,15 +160,12 @@ export default class Project {
clicked
:
function
(
options
)
{
clicked
:
function
(
options
)
{
const
{
e
}
=
options
;
const
{
e
}
=
options
;
e
.
preventDefault
();
e
.
preventDefault
();
if
(
$
(
'
input[name="ref"]
'
).
length
)
{
if
(
$
(
`input[name="
${
fieldName
}
"]`
).
length
)
{
var
$form
=
$dropdown
.
closest
(
'
form
'
);
var
$form
=
$dropdown
.
closest
(
'
form
'
);
var
$visit
=
$dropdown
.
data
(
'
visit
'
);
var
shouldVisit
=
$visit
?
true
:
$visit
;
var
action
=
$form
.
attr
(
'
action
'
);
var
action
=
$form
.
attr
(
'
action
'
);
var
divider
=
action
.
indexOf
(
'
?
'
)
===
-
1
?
'
?
'
:
'
&
'
;
if
(
shouldVisit
)
{
if
(
shouldVisit
)
{
visitUrl
(
`
${
action
}${
divider
}${
$form
.
serialize
()}
`
);
visitUrl
(
mergeUrlParams
(
serializeForm
(
$form
[
0
]),
action
)
);
}
}
}
}
},
},
...
...
app/assets/javascripts/pages/search/show/search.js
View file @
aa137fd3
...
@@ -2,6 +2,7 @@ import $ from 'jquery';
...
@@ -2,6 +2,7 @@ import $ from 'jquery';
import
Flash
from
'
~/flash
'
;
import
Flash
from
'
~/flash
'
;
import
Api
from
'
~/api
'
;
import
Api
from
'
~/api
'
;
import
{
__
}
from
'
~/locale
'
;
import
{
__
}
from
'
~/locale
'
;
import
Project
from
'
~/pages/projects/project
'
;
export
default
class
Search
{
export
default
class
Search
{
constructor
()
{
constructor
()
{
...
@@ -69,6 +70,8 @@ export default class Search {
...
@@ -69,6 +70,8 @@ export default class Search {
},
},
clicked
:
()
=>
Search
.
submitSearch
(),
clicked
:
()
=>
Search
.
submitSearch
(),
});
});
Project
.
initRefSwitcher
();
}
}
eventListeners
()
{
eventListeners
()
{
...
...
app/views/search/_form.html.haml
View file @
aa137fd3
=
form_tag
search_path
,
method: :get
,
class:
'search-page-form js-search-form'
do
|
f
|
=
form_tag
search_path
,
method: :get
,
class:
'search-page-form js-search-form'
do
|
f
|
=
hidden_field_tag
:snippets
,
params
[
:snippets
]
=
hidden_field_tag
:snippets
,
params
[
:snippets
]
=
hidden_field_tag
:scope
,
params
[
:scope
]
=
hidden_field_tag
:scope
,
params
[
:scope
]
=
hidden_field_tag
:repository_ref
,
params
[
:repository_ref
]
.d-lg-flex.align-items-end
.d-lg-flex.align-items-end
.search-field-holder.form-group.mr-lg-1.mb-lg-0
.search-field-holder.form-group.mr-lg-1.mb-lg-0
...
...
app/views/search/_results.html.haml
View file @
aa137fd3
...
@@ -2,17 +2,25 @@
...
@@ -2,17 +2,25 @@
=
render
partial:
"search/results/empty"
=
render
partial:
"search/results/empty"
=
render_if_exists
'shared/promotions/promote_advanced_search'
=
render_if_exists
'shared/promotions/promote_advanced_search'
-
else
-
else
.row-content-block
.row-content-block
.d-md-flex.text-left.align-items-center
-
unless
@search_objects
.
is_a?
(
Kaminari
::
PaginatableWithoutCount
)
-
unless
@search_objects
.
is_a?
(
Kaminari
::
PaginatableWithoutCount
)
=
search_entries_info
(
@search_objects
,
@scope
,
@search_term
)
=
search_entries_info
(
@search_objects
,
@scope
,
@search_term
)
-
unless
@show_snippets
-
unless
@show_snippets
-
if
@project
-
if
@project
-
link_to_project
=
link_to
(
@project
.
full_name
,
[
@project
.
namespace
.
becomes
(
Namespace
),
@project
])
-
link_to_project
=
link_to
(
@project
.
full_name
,
[
@project
.
namespace
.
becomes
(
Namespace
),
@project
],
class:
'ml-md-1'
)
-
if
@scope
==
'blobs'
-
repository_ref
=
params
[
:repository_ref
].
to_s
.
presence
||
@project
.
default_branch
=
s_
(
"SearchCodeResults|in"
)
.mx-md-1
=
render
partial:
"shared/ref_switcher"
,
locals:
{
ref:
repository_ref
,
form_path:
request
.
fullpath
,
field_name:
'repository_ref'
}
=
s_
(
'SearchCodeResults|of %{link_to_project}'
).
html_safe
%
{
link_to_project:
link_to_project
}
-
else
=
_
(
"in project %{link_to_project}"
).
html_safe
%
{
link_to_project:
link_to_project
}
=
_
(
"in project %{link_to_project}"
).
html_safe
%
{
link_to_project:
link_to_project
}
-
elsif
@group
-
elsif
@group
-
link_to_group
=
link_to
(
@group
.
name
,
@group
)
-
link_to_group
=
link_to
(
@group
.
name
,
@group
,
class:
'ml-md-1'
)
=
_
(
"in group %{link_to_group}"
).
html_safe
%
{
link_to_group:
link_to_group
}
=
_
(
"in group %{link_to_group}"
).
html_safe
%
{
link_to_group:
link_to_group
}
=
render_if_exists
'shared/promotions/promote_advanced_search'
=
render_if_exists
'shared/promotions/promote_advanced_search'
.results.prepend-top-10
.results.prepend-top-10
-
if
@scope
==
'commits'
-
if
@scope
==
'commits'
%ul
.content-list.commit-list
%ul
.content-list.commit-list
...
...
app/views/shared/_ref_switcher.html.haml
View file @
aa137fd3
-
dropdown_toggle_text
=
@ref
||
@project
.
default_branch
-
return
unless
@project
=
form_tag
switch_project_refs_path
(
@project
),
method: :get
,
class:
"project-refs-form"
do
-
ref
=
local_assigns
.
fetch
(
:ref
,
@ref
)
-
form_path
=
local_assigns
.
fetch
(
:form_path
,
switch_project_refs_path
(
@project
))
-
dropdown_toggle_text
=
ref
||
@project
.
default_branch
-
field_name
=
local_assigns
.
fetch
(
:field_name
,
'ref'
)
=
form_tag
form_path
,
method: :get
,
class:
"project-refs-form"
do
-
if
defined?
(
destination
)
=
hidden_field_tag
:destination
,
destination
=
hidden_field_tag
:destination
,
destination
-
if
defined?
(
path
)
-
if
defined?
(
path
)
=
hidden_field_tag
:path
,
path
=
hidden_field_tag
:path
,
path
-
@options
&&
@options
.
each
do
|
key
,
value
|
-
@options
&&
@options
.
each
do
|
key
,
value
|
=
hidden_field_tag
key
,
value
,
id:
nil
=
hidden_field_tag
key
,
value
,
id:
nil
.dropdown
.dropdown
=
dropdown_toggle
dropdown_toggle_text
,
{
toggle:
"dropdown"
,
selected:
dropdown_toggle_text
,
ref:
@ref
,
refs_url:
refs_project_path
(
@project
,
sort:
'updated_desc'
),
field_name:
'ref'
,
submit_form_on_click:
true
,
visit:
true
},
{
toggle_class:
"js-project-refs-dropdown qa-branches-select"
}
=
dropdown_toggle
dropdown_toggle_text
,
{
toggle:
"dropdown"
,
selected:
dropdown_toggle_text
,
ref:
ref
,
refs_url:
refs_project_path
(
@project
,
sort:
'updated_desc'
),
field_name:
field_name
,
submit_form_on_click:
true
,
visit:
true
},
{
toggle_class:
"js-project-refs-dropdown qa-branches-select"
}
.dropdown-menu.dropdown-menu-selectable.git-revision-dropdown.dropdown-menu-paging.qa-branches-dropdown
{
class:
(
"dropdown-menu-right"
if
local_assigns
[
:align_right
])
}
.dropdown-menu.dropdown-menu-selectable.git-revision-dropdown.dropdown-menu-paging.qa-branches-dropdown
{
class:
(
"dropdown-menu-right"
if
local_assigns
[
:align_right
])
}
.dropdown-page-one
.dropdown-page-one
=
dropdown_title
_
(
"Switch branch/tag"
)
=
dropdown_title
_
(
"Switch branch/tag"
)
...
...
changelogs/unreleased/59712-resolve-the-search-problem-issue.yml
0 → 100644
View file @
aa137fd3
---
title
:
Add branch/tags/commits dropdown filter on the search page for searching codes
merge_request
:
28282
author
:
minghuan lei
type
:
changed
locale/gitlab.pot
View file @
aa137fd3
...
@@ -9666,6 +9666,12 @@ msgstr ""
...
@@ -9666,6 +9666,12 @@ msgstr ""
msgid "SearchAutocomplete|in this project"
msgid "SearchAutocomplete|in this project"
msgstr ""
msgstr ""
msgid "SearchCodeResults|in"
msgstr ""
msgid "SearchCodeResults|of %{link_to_project}"
msgstr ""
msgid "SearchResults|Showing %{from} - %{to} of %{count} %{scope} for \"%{term}\""
msgid "SearchResults|Showing %{from} - %{to} of %{count} %{scope} for \"%{term}\""
msgstr ""
msgstr ""
...
...
spec/features/search/user_searches_for_code_spec.rb
View file @
aa137fd3
...
@@ -6,6 +6,21 @@ describe 'User searches for code' do
...
@@ -6,6 +6,21 @@ describe 'User searches for code' do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
,
:repository
,
namespace:
user
.
namespace
)
}
let
(
:project
)
{
create
(
:project
,
:repository
,
namespace:
user
.
namespace
)
}
def
submit_search
(
search
,
with_send_keys:
false
)
page
.
within
(
'.search'
)
do
field
=
find_field
(
'search'
)
field
.
fill_in
(
with:
search
)
if
with_send_keys
field
.
send_keys
(
:enter
)
else
click_button
(
"Go"
)
end
end
click_link
(
'Code'
)
end
context
'when signed in'
do
context
'when signed in'
do
before
do
before
do
project
.
add_maintainer
(
user
)
project
.
add_maintainer
(
user
)
...
@@ -15,12 +30,7 @@ describe 'User searches for code' do
...
@@ -15,12 +30,7 @@ describe 'User searches for code' do
it
'finds a file'
do
it
'finds a file'
do
visit
(
project_path
(
project
))
visit
(
project_path
(
project
))
page
.
within
(
'.search'
)
do
submit_search
(
'application.js'
)
fill_in
(
'search'
,
with:
'application.js'
)
click_button
(
'Go'
)
end
click_link
(
'Code'
)
expect
(
page
).
to
have_selector
(
'.file-content .code'
)
expect
(
page
).
to
have_selector
(
'.file-content .code'
)
expect
(
page
).
to
have_selector
(
"span.line[lang='javascript']"
)
expect
(
page
).
to
have_selector
(
"span.line[lang='javascript']"
)
...
@@ -48,6 +58,50 @@ describe 'User searches for code' do
...
@@ -48,6 +58,50 @@ describe 'User searches for code' do
end
end
end
end
end
end
context
'search code within refs'
,
:js
do
let
(
:ref_name
)
{
'v1.0.0'
}
before
do
visit
(
project_tree_path
(
project
,
ref_name
))
submit_search
(
'gitlab-grack'
,
with_send_keys:
true
)
end
it
'shows ref switcher in code result summary'
do
expect
(
find
(
'.js-project-refs-dropdown'
)).
to
have_text
(
ref_name
)
end
it
'persists branch name across search'
do
find
(
'.btn-search'
).
click
expect
(
find
(
'.js-project-refs-dropdown'
)).
to
have_text
(
ref_name
)
end
# this example is use to test the desgine that the refs is not
# only repersent the branch as well as the tags.
it
'ref swither list all the branchs and tags'
do
find
(
'.js-project-refs-dropdown'
).
click
expect
(
find
(
'.dropdown-page-one .dropdown-content'
)).
to
have_link
(
'sha-starting-with-large-number'
)
expect
(
find
(
'.dropdown-page-one .dropdown-content'
)).
to
have_link
(
'v1.0.0'
)
end
it
'search result changes when refs switched'
do
expect
(
find
(
'.search-results'
)).
not_to
have_content
(
'path = gitlab-grack'
)
find
(
'.js-project-refs-dropdown'
).
click
find
(
'.dropdown-page-one .dropdown-content'
).
click_link
(
'master'
)
expect
(
find
(
'.search-results'
)).
to
have_content
(
'path = gitlab-grack'
)
end
end
it
'no ref switcher shown in issue result summary'
,
:js
do
issue
=
create
(
:issue
,
title:
'test'
,
project:
project
)
visit
(
project_tree_path
(
project
))
submit_search
(
'test'
,
with_send_keys:
true
)
expect
(
page
).
to
have_selector
(
'.js-project-refs-dropdown'
)
page
.
within
(
'.search-filter'
)
do
click_link
(
'Issues'
)
end
expect
(
find
(
:css
,
'.search-results'
)).
to
have_link
(
issue
.
title
)
expect
(
page
).
not_to
have_selector
(
'.js-project-refs-dropdown'
)
end
end
end
context
'when signed out'
do
context
'when signed out'
do
...
@@ -58,8 +112,7 @@ describe 'User searches for code' do
...
@@ -58,8 +112,7 @@ describe 'User searches for code' do
end
end
it
'finds code'
do
it
'finds code'
do
fill_in
(
'search'
,
with:
'rspec'
)
submit_search
(
'rspec'
)
click_button
(
'Go'
)
page
.
within
(
'.results'
)
do
page
.
within
(
'.results'
)
do
expect
(
find
(
:css
,
'.search-results'
)).
to
have_content
(
'Update capybara, rspec-rails, poltergeist to recent versions'
)
expect
(
find
(
:css
,
'.search-results'
)).
to
have_content
(
'Update capybara, rspec-rails, poltergeist to recent versions'
)
...
...
spec/frontend/lib/utils/forms_spec.js
0 → 100644
View file @
aa137fd3
import
{
serializeForm
}
from
'
~/lib/utils/forms
'
;
describe
(
'
lib/utils/forms
'
,
()
=>
{
const
createDummyForm
=
inputs
=>
{
const
form
=
document
.
createElement
(
'
form
'
);
form
.
innerHTML
=
inputs
.
map
(({
type
,
name
,
value
})
=>
{
let
str
=
``
;
if
(
type
===
'
select
'
)
{
str
=
`<select name="
${
name
}
">`
;
value
.
forEach
(
v
=>
{
if
(
v
.
length
>
0
)
{
str
+=
`<option value="
${
v
}
"></option> `
;
}
});
str
+=
`</select>`
;
}
else
{
str
=
`<input type="
${
type
}
" name="
${
name
}
" value="
${
value
}
" checked/>`
;
}
return
str
;
})
.
join
(
''
);
return
form
;
};
describe
(
'
serializeForm
'
,
()
=>
{
it
(
'
returns an object of key values from inputs
'
,
()
=>
{
const
form
=
createDummyForm
([
{
type
:
'
text
'
,
name
:
'
foo
'
,
value
:
'
foo-value
'
},
{
type
:
'
text
'
,
name
:
'
bar
'
,
value
:
'
bar-value
'
},
]);
const
data
=
serializeForm
(
form
);
expect
(
data
).
toEqual
({
foo
:
'
foo-value
'
,
bar
:
'
bar-value
'
,
});
});
it
(
'
works with select
'
,
()
=>
{
const
form
=
createDummyForm
([
{
type
:
'
select
'
,
name
:
'
foo
'
,
value
:
[
'
foo-value1
'
,
'
foo-value2
'
]
},
{
type
:
'
text
'
,
name
:
'
bar
'
,
value
:
'
bar-value1
'
},
]);
const
data
=
serializeForm
(
form
);
expect
(
data
).
toEqual
({
foo
:
'
foo-value1
'
,
bar
:
'
bar-value1
'
,
});
});
it
(
'
works with multiple inputs of the same name
'
,
()
=>
{
const
form
=
createDummyForm
([
{
type
:
'
checkbox
'
,
name
:
'
foo
'
,
value
:
'
foo-value3
'
},
{
type
:
'
checkbox
'
,
name
:
'
foo
'
,
value
:
'
foo-value2
'
},
{
type
:
'
checkbox
'
,
name
:
'
foo
'
,
value
:
'
foo-value1
'
},
{
type
:
'
text
'
,
name
:
'
bar
'
,
value
:
'
bar-value2
'
},
{
type
:
'
text
'
,
name
:
'
bar
'
,
value
:
'
bar-value1
'
},
]);
const
data
=
serializeForm
(
form
);
expect
(
data
).
toEqual
({
foo
:
[
'
foo-value3
'
,
'
foo-value2
'
,
'
foo-value1
'
],
bar
:
[
'
bar-value2
'
,
'
bar-value1
'
],
});
});
});
});
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