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
0
Merge Requests
0
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
iv
gitlab-ce
Commits
4b3d3446
Commit
4b3d3446
authored
8 years ago
by
Alfredo Sumaran
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Working version of autocomplete with categorized results
parent
bc590ce6
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
229 additions
and
49 deletions
+229
-49
app/assets/javascripts/dispatcher.js.coffee
app/assets/javascripts/dispatcher.js.coffee
+1
-6
app/assets/javascripts/lib/category_autocomplete.js.coffee
app/assets/javascripts/lib/category_autocomplete.js.coffee
+17
-0
app/assets/javascripts/search_autocomplete.js.coffee
app/assets/javascripts/search_autocomplete.js.coffee
+161
-8
app/helpers/search_helper.rb
app/helpers/search_helper.rb
+33
-26
app/views/layouts/_search.html.haml
app/views/layouts/_search.html.haml
+4
-9
app/views/shared/_location_badge.html.haml
app/views/shared/_location_badge.html.haml
+13
-0
No files found.
app/assets/javascripts/dispatcher.js.coffee
View file @
4b3d3446
...
@@ -151,9 +151,4 @@ class Dispatcher
...
@@ -151,9 +151,4 @@ class Dispatcher
new
Shortcuts
()
new
Shortcuts
()
initSearch
:
->
initSearch
:
->
opts
=
$
(
'.search-autocomplete-opts'
)
new
SearchAutocomplete
()
path
=
opts
.
data
(
'autocomplete-path'
)
project_id
=
opts
.
data
(
'autocomplete-project-id'
)
project_ref
=
opts
.
data
(
'autocomplete-project-ref'
)
new
SearchAutocomplete
(
path
,
project_id
,
project_ref
)
This diff is collapsed.
Click to expand it.
app/assets/javascripts/lib/category_autocomplete.js.coffee
0 → 100644
View file @
4b3d3446
$
.
widget
(
"custom.catcomplete"
,
$
.
ui
.
autocomplete
,
_create
:
->
@
_super
();
@
widget
().
menu
(
"option"
,
"items"
,
"> :not(.ui-autocomplete-category)"
)
_renderMenu
:
(
ul
,
items
)
->
currentCategory
=
''
$
.
each
items
,
(
index
,
item
)
=>
if
item
.
category
isnt
currentCategory
ul
.
append
(
"<li class='ui-autocomplete-category'>
#{
item
.
category
}
</li>"
)
currentCategory
=
item
.
category
li
=
@
_renderItemData
(
ul
,
item
)
if
item
.
category
?
li
.
attr
(
'aria-label'
,
item
.
category
+
" : "
+
item
.
label
)
)
This diff is collapsed.
Click to expand it.
app/assets/javascripts/search_autocomplete.js.coffee
View file @
4b3d3446
class
@
SearchAutocomplete
class
@
SearchAutocomplete
constructor
:
(
search_autocomplete_path
,
project_id
,
project_ref
)
->
constructor
:
(
opts
=
{})
->
project_id
=
''
unless
project_id
{
project_ref
=
''
unless
project_ref
@
wrap
=
$
(
'.search'
)
query
=
"?project_id="
+
project_id
+
"&project_ref="
+
project_ref
@
optsEl
=
@
wrap
.
find
(
'.search-autocomplete-opts'
)
@
autocompletePath
=
@
optsEl
.
data
(
'autocomplete-path'
)
@
projectId
=
@
optsEl
.
data
(
'autocomplete-project-id'
)
||
''
@
projectRef
=
@
optsEl
.
data
(
'autocomplete-project-ref'
)
||
''
}
=
opts
$
(
"#search"
).
autocomplete
@
keyCode
=
source
:
search_autocomplete_path
+
query
ESCAPE
:
27
BACKSPACE
:
8
TAB
:
9
ENTER
:
13
@
locationBadgeEl
=
@
$
(
'.search-location-badge'
)
@
locationText
=
@
$
(
'.location-text'
)
@
searchInput
=
@
$
(
'.search-input'
)
@
projectInputEl
=
@
$
(
'#project_id'
)
@
groupInputEl
=
@
$
(
'#group_id'
)
@
searchCodeInputEl
=
@
$
(
'#search_code'
)
@
repositoryInputEl
=
@
$
(
'#repository_ref'
)
@
scopeInputEl
=
@
$
(
'#scope'
)
@
saveOriginalState
()
@
createAutocomplete
()
@
bindEvents
()
$
:
(
selector
)
->
@
wrap
.
find
(
selector
)
saveOriginalState
:
->
@
originalState
=
@
serializeState
()
restoreOriginalState
:
->
inputs
=
Object
.
keys
@
originalState
for
input
in
inputs
@
$
(
"#
#{
input
}
"
).
val
(
@
originalState
[
input
])
if
@
originalState
.
_location
is
''
@
locationBadgeEl
.
html
(
''
)
else
@
addLocationBadge
(
value
:
@
originalState
.
_location
)
serializeState
:
->
{
# Search Criteria
project_id
:
@
projectInputEl
.
val
()
group_id
:
@
groupInputEl
.
val
()
search_code
:
@
searchCodeInputEl
.
val
()
repository_ref
:
@
repositoryInputEl
.
val
()
# Location badge
_location
:
$
.
trim
(
@
locationText
.
text
())
}
createAutocomplete
:
->
@
query
=
"?project_id="
+
@
projectId
+
"&project_ref="
+
@
projectRef
@
catComplete
=
@
searchInput
.
catcomplete
appendTo
:
'form.navbar-form'
source
:
@
autocompletePath
+
@
query
minLength
:
1
minLength
:
1
select
:
(
event
,
ui
)
->
close
:
(
e
)
->
location
.
href
=
ui
.
item
.
url
e
.
preventDefault
()
select
:
(
event
,
ui
)
=>
# Pressing enter choses an alternative
if
event
.
keyCode
is
@
keyCode
.
ENTER
@
goToResult
(
ui
.
item
)
else
# Pressing tab sets the scope
if
event
.
keyCode
is
@
keyCode
.
TAB
and
ui
.
item
.
scope
?
@
setLocationBadge
(
ui
.
item
)
@
searchInput
.
val
(
''
)
# remove selected value from input
.
focus
()
else
# If option is not a scope go to page
@
goToResult
(
ui
.
item
)
# Return false to avoid focus on the next element
return
false
bindEvents
:
->
@
searchInput
.
on
'keydown'
,
@
onSearchKeyDown
@
wrap
.
on
'click'
,
'.remove-badge'
,
@
onRemoveLocationBadgeClick
onRemoveLocationBadgeClick
:
(
e
)
=>
e
.
preventDefault
()
@
removeLocationBadge
()
@
searchInput
.
focus
()
onSearchKeyDown
:
(
e
)
=>
# Remove tag when pressing backspace and input search is empty
if
e
.
keyCode
is
@
keyCode
.
BACKSPACE
and
e
.
currentTarget
.
value
is
''
@
removeLocationBadge
()
@
destroyAutocomplete
()
@
searchInput
.
focus
()
else
if
e
.
keyCode
is
@
keyCode
.
ESCAPE
@
restoreOriginalState
()
else
# Create new autocomplete instance if it's not created
@
createAutocomplete
()
unless
@
catcomplete
?
addLocationBadge
:
(
item
)
->
category
=
if
item
.
category
?
then
"
#{
item
.
category
}
: "
else
''
value
=
if
item
.
value
?
then
item
.
value
else
''
html
=
"<span class='label label-primary'>
<i class='location-text'>
#{
category
}#{
value
}
</i>
<a class='remove-badge' href='#'>x</a>
</span>"
@
locationBadgeEl
.
html
(
html
)
setLocationBadge
:
(
item
)
->
@
addLocationBadge
(
item
)
# Reset input states
@
resetSearchState
()
switch
item
.
scope
when
'projects'
@
projectInputEl
.
val
(
item
.
id
)
# @searchCodeInputEl.val('true') # TODO: always true for projects?
# @repositoryInputEl.val('master') # TODO: always master?
when
'groups'
@
groupInputEl
.
val
(
item
.
id
)
removeLocationBadge
:
->
@
locationBadgeEl
.
empty
()
# Reset state
@
resetSearchState
()
resetSearchState
:
->
# Remove scope
@
scopeInputEl
.
val
(
''
)
# Remove group
@
groupInputEl
.
val
(
''
)
# Remove project id
@
projectInputEl
.
val
(
''
)
# Remove code search
@
searchCodeInputEl
.
val
(
''
)
# Remove repository ref
@
repositoryInputEl
.
val
(
''
)
goToResult
:
(
result
)
->
location
.
href
=
result
.
url
destroyAutocomplete
:
->
@
catComplete
.
destroy
()
if
@
catcomplete
?
@
catComplete
=
null
This diff is collapsed.
Click to expand it.
app/helpers/search_helper.rb
View file @
4b3d3446
...
@@ -23,45 +23,45 @@ module SearchHelper
...
@@ -23,45 +23,45 @@ module SearchHelper
# Autocomplete results for various settings pages
# Autocomplete results for various settings pages
def
default_autocomplete
def
default_autocomplete
[
[
{
label:
"Profile settings"
,
url:
profile_path
},
{
category:
"Settings"
,
label:
"Profile settings"
,
url:
profile_path
},
{
label:
"SSH Keys"
,
url:
profile_keys_path
},
{
category:
"Settings"
,
label:
"SSH Keys"
,
url:
profile_keys_path
},
{
label:
"Dashboard"
,
url:
root_path
},
{
category:
"Settings"
,
label:
"Dashboard"
,
url:
root_path
},
{
label:
"Admin Section"
,
url:
admin_root_path
},
{
category:
"Settings"
,
label:
"Admin Section"
,
url:
admin_root_path
},
]
]
end
end
# Autocomplete results for internal help pages
# Autocomplete results for internal help pages
def
help_autocomplete
def
help_autocomplete
[
[
{
label:
"help:
API Help"
,
url:
help_page_path
(
"api"
,
"README"
)
},
{
category:
"Help"
,
label:
"
API Help"
,
url:
help_page_path
(
"api"
,
"README"
)
},
{
label:
"help:
Markdown Help"
,
url:
help_page_path
(
"markdown"
,
"markdown"
)
},
{
category:
"Help"
,
label:
"
Markdown Help"
,
url:
help_page_path
(
"markdown"
,
"markdown"
)
},
{
label:
"help:
Permissions Help"
,
url:
help_page_path
(
"permissions"
,
"permissions"
)
},
{
category:
"Help"
,
label:
"
Permissions Help"
,
url:
help_page_path
(
"permissions"
,
"permissions"
)
},
{
label:
"help:
Public Access Help"
,
url:
help_page_path
(
"public_access"
,
"public_access"
)
},
{
category:
"Help"
,
label:
"
Public Access Help"
,
url:
help_page_path
(
"public_access"
,
"public_access"
)
},
{
label:
"help:
Rake Tasks Help"
,
url:
help_page_path
(
"raketasks"
,
"README"
)
},
{
category:
"Help"
,
label:
"
Rake Tasks Help"
,
url:
help_page_path
(
"raketasks"
,
"README"
)
},
{
label:
"help:
SSH Keys Help"
,
url:
help_page_path
(
"ssh"
,
"README"
)
},
{
category:
"Help"
,
label:
"
SSH Keys Help"
,
url:
help_page_path
(
"ssh"
,
"README"
)
},
{
label:
"help:
System Hooks Help"
,
url:
help_page_path
(
"system_hooks"
,
"system_hooks"
)
},
{
category:
"Help"
,
label:
"
System Hooks Help"
,
url:
help_page_path
(
"system_hooks"
,
"system_hooks"
)
},
{
label:
"help:
Webhooks Help"
,
url:
help_page_path
(
"web_hooks"
,
"web_hooks"
)
},
{
category:
"Help"
,
label:
"
Webhooks Help"
,
url:
help_page_path
(
"web_hooks"
,
"web_hooks"
)
},
{
label:
"help:
Workflow Help"
,
url:
help_page_path
(
"workflow"
,
"README"
)
},
{
category:
"Help"
,
label:
"
Workflow Help"
,
url:
help_page_path
(
"workflow"
,
"README"
)
},
]
]
end
end
# Autocomplete results for the current project, if it's defined
# Autocomplete results for the current project, if it's defined
def
project_autocomplete
def
project_autocomplete
if
@project
&&
@project
.
repository
.
exists?
&&
@project
.
repository
.
root_ref
if
@project
&&
@project
.
repository
.
exists?
&&
@project
.
repository
.
root_ref
prefix
=
search_result_sanitize
(
@project
.
name_with_namespace
)
prefix
=
"Project - "
+
search_result_sanitize
(
@project
.
name_with_namespace
)
ref
=
@ref
||
@project
.
repository
.
root_ref
ref
=
@ref
||
@project
.
repository
.
root_ref
[
[
{
label:
"
#{
prefix
}
-
Files"
,
url:
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
ref
)
},
{
category:
prefix
,
label:
"
Files"
,
url:
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
ref
)
},
{
label:
"
#{
prefix
}
-
Commits"
,
url:
namespace_project_commits_path
(
@project
.
namespace
,
@project
,
ref
)
},
{
category:
prefix
,
label:
"
Commits"
,
url:
namespace_project_commits_path
(
@project
.
namespace
,
@project
,
ref
)
},
{
label:
"
#{
prefix
}
-
Network"
,
url:
namespace_project_network_path
(
@project
.
namespace
,
@project
,
ref
)
},
{
category:
prefix
,
label:
"
Network"
,
url:
namespace_project_network_path
(
@project
.
namespace
,
@project
,
ref
)
},
{
label:
"
#{
prefix
}
-
Graph"
,
url:
namespace_project_graph_path
(
@project
.
namespace
,
@project
,
ref
)
},
{
category:
prefix
,
label:
"
Graph"
,
url:
namespace_project_graph_path
(
@project
.
namespace
,
@project
,
ref
)
},
{
label:
"
#{
prefix
}
-
Issues"
,
url:
namespace_project_issues_path
(
@project
.
namespace
,
@project
)
},
{
category:
prefix
,
label:
"
Issues"
,
url:
namespace_project_issues_path
(
@project
.
namespace
,
@project
)
},
{
label:
"
#{
prefix
}
-
Merge Requests"
,
url:
namespace_project_merge_requests_path
(
@project
.
namespace
,
@project
)
},
{
category:
prefix
,
label:
"
Merge Requests"
,
url:
namespace_project_merge_requests_path
(
@project
.
namespace
,
@project
)
},
{
label:
"
#{
prefix
}
-
Milestones"
,
url:
namespace_project_milestones_path
(
@project
.
namespace
,
@project
)
},
{
category:
prefix
,
label:
"
Milestones"
,
url:
namespace_project_milestones_path
(
@project
.
namespace
,
@project
)
},
{
label:
"
#{
prefix
}
-
Snippets"
,
url:
namespace_project_snippets_path
(
@project
.
namespace
,
@project
)
},
{
category:
prefix
,
label:
"
Snippets"
,
url:
namespace_project_snippets_path
(
@project
.
namespace
,
@project
)
},
{
label:
"
#{
prefix
}
-
Members"
,
url:
namespace_project_project_members_path
(
@project
.
namespace
,
@project
)
},
{
category:
prefix
,
label:
"
Members"
,
url:
namespace_project_project_members_path
(
@project
.
namespace
,
@project
)
},
{
label:
"
#{
prefix
}
-
Wiki"
,
url:
namespace_project_wikis_path
(
@project
.
namespace
,
@project
)
},
{
category:
prefix
,
label:
"
Wiki"
,
url:
namespace_project_wikis_path
(
@project
.
namespace
,
@project
)
},
]
]
else
else
[]
[]
...
@@ -72,7 +72,10 @@ module SearchHelper
...
@@ -72,7 +72,10 @@ module SearchHelper
def
groups_autocomplete
(
term
,
limit
=
5
)
def
groups_autocomplete
(
term
,
limit
=
5
)
current_user
.
authorized_groups
.
search
(
term
).
limit
(
limit
).
map
do
|
group
|
current_user
.
authorized_groups
.
search
(
term
).
limit
(
limit
).
map
do
|
group
|
{
{
label:
"group:
#{
search_result_sanitize
(
group
.
name
)
}
"
,
category:
"Groups"
,
scope:
"groups"
,
id:
group
.
id
,
label:
"
#{
search_result_sanitize
(
group
.
name
)
}
"
,
url:
group_path
(
group
)
url:
group_path
(
group
)
}
}
end
end
...
@@ -83,7 +86,11 @@ module SearchHelper
...
@@ -83,7 +86,11 @@ module SearchHelper
current_user
.
authorized_projects
.
search_by_title
(
term
).
current_user
.
authorized_projects
.
search_by_title
(
term
).
sorted_by_stars
.
non_archived
.
limit
(
limit
).
map
do
|
p
|
sorted_by_stars
.
non_archived
.
limit
(
limit
).
map
do
|
p
|
{
{
label:
"project:
#{
search_result_sanitize
(
p
.
name_with_namespace
)
}
"
,
category:
"Projects"
,
scope:
"projects"
,
id:
p
.
id
,
value:
"
#{
search_result_sanitize
(
p
.
name
)
}
"
,
label:
"
#{
search_result_sanitize
(
p
.
name_with_namespace
)
}
"
,
url:
namespace_project_path
(
p
.
namespace
,
p
)
url:
namespace_project_path
(
p
.
namespace
,
p
)
}
}
end
end
...
...
This diff is collapsed.
Click to expand it.
app/views/layouts/_search.html.haml
View file @
4b3d3446
.search
.search
=
form_tag
search_path
,
method: :get
,
class:
'navbar-form pull-left'
do
|
f
|
=
form_tag
search_path
,
method: :get
,
class:
'navbar-form pull-left'
do
|
f
|
=
render
'shared/location_badge'
=
search_field_tag
"search"
,
nil
,
placeholder:
'Search'
,
class:
"search-input form-control"
,
spellcheck:
false
,
tabindex:
"1"
=
search_field_tag
"search"
,
nil
,
placeholder:
'Search'
,
class:
"search-input form-control"
,
spellcheck:
false
,
tabindex:
"1"
=
hidden_field_tag
:group_id
,
@group
.
try
(
:id
)
=
hidden_field_tag
:group_id
,
@group
.
try
(
:id
)
-
if
@project
&&
@project
.
persisted?
=
hidden_field_tag
:project_id
,
@project
.
id
=
hidden_field_tag
:project_id
,
@project
&&
@project
.
persisted?
?
@project
.
id
:
''
-
if
@project
&&
@project
.
persisted?
-
if
current_controller?
(
:issues
)
-
if
current_controller?
(
:issues
)
=
hidden_field_tag
:scope
,
'issues'
=
hidden_field_tag
:scope
,
'issues'
-
elsif
current_controller?
(
:merge_requests
)
-
elsif
current_controller?
(
:merge_requests
)
...
@@ -21,10 +23,3 @@
...
@@ -21,10 +23,3 @@
=
hidden_field_tag
:repository_ref
,
@ref
=
hidden_field_tag
:repository_ref
,
@ref
=
button_tag
'Go'
if
ENV
[
'RAILS_ENV'
]
==
'test'
=
button_tag
'Go'
if
ENV
[
'RAILS_ENV'
]
==
'test'
.search-autocomplete-opts.hide
{
:'data-autocomplete-path'
=>
search_autocomplete_path
,
:'data-autocomplete-project-id'
=>
@project
.
try
(
:id
),
:'data-autocomplete-project-ref'
=>
@ref
}
.search-autocomplete-opts.hide
{
:'data-autocomplete-path'
=>
search_autocomplete_path
,
:'data-autocomplete-project-id'
=>
@project
.
try
(
:id
),
:'data-autocomplete-project-ref'
=>
@ref
}
:javascript
$
(
'
.search-input
'
).
on
(
'
keyup
'
,
function
(
e
)
{
if
(
e
.
keyCode
==
27
)
{
$
(
'
.search-input
'
).
blur
();
}
});
This diff is collapsed.
Click to expand it.
app/views/shared/_location_badge.html.haml
0 → 100644
View file @
4b3d3446
-
if
controller
.
controller_path
=~
/^groups/
-
label
=
'This group'
-
if
controller
.
controller_path
=~
/^projects/
-
label
=
'This project'
.search-location-badge
-
if
label
.
present?
%span
.label.label-primary
%i
.location-text
=
label
%a
.remove-badge
{
href:
'#'
}
x
This diff is collapsed.
Click to expand it.
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