BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
71dc5af9
Commit
71dc5af9
authored
Nov 04, 2016
by
Clement Ho
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add basic search
parent
2f1701c5
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
227 additions
and
2 deletions
+227
-2
dispatcher.js.es6
app/assets/javascripts/dispatcher.js.es6
+3
-0
filtered_search_bundle.js
...ets/javascripts/filtered_search/filtered_search_bundle.js
+14
-0
filtered_search_manager.js.es6
...avascripts/filtered_search/filtered_search_manager.js.es6
+105
-0
filters.scss
app/assets/stylesheets/framework/filters.scss
+24
-0
index.html.haml
app/views/projects/issues/index.html.haml
+4
-2
_search_bar.html.haml
app/views/shared/issuable/_search_bar.html.haml
+76
-0
application.rb
config/application.rb
+1
-0
No files found.
app/assets/javascripts/dispatcher.js.es6
View file @
71dc5af9
...
...
@@ -84,6 +84,9 @@
break;
case 'projects:merge_requests:index':
case 'projects:issues:index':
if(gl.hasOwnProperty('FilteredSearchManager')) {
new gl.FilteredSearchManager();
}
Issuable.init();
new gl.IssuableBulkActions({
prefixId: page === 'projects:merge_requests:index' ? 'merge_request_' : 'issue_',
...
...
app/assets/javascripts/filtered_search/filtered_search_bundle.js
0 → 100644
View file @
71dc5af9
/* eslint-disable */
// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
/*= require_tree . */
(
function
()
{
}).
call
(
this
);
\ No newline at end of file
app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
0 → 100644
View file @
71dc5af9
((global) => {
const TOKEN_TYPE_STRING = 'string';
const TOKEN_TYPE_ARRAY = 'array';
const validTokenKeys = [{
key: 'author',
type: 'string',
},{
key: 'assignee',
type: 'string'
},{
key: 'milestone',
type: 'string'
},{
key: 'label',
type: 'array'
},];
class FilteredSearchManager {
constructor() {
this.bindEvents();
this.clearTokens();
}
bindEvents() {
const input = document.querySelector('.filtered-search');
input.addEventListener('input', this.tokenize.bind(this));
input.addEventListener('keydown', this.checkForEnter.bind(this));
}
clearTokens() {
this.tokens = [];
this.searchToken = '';
}
tokenize(event) {
// Re-calculate tokens
this.clearTokens();
// TODO: Current implementation does not support token values that have valid spaces in them
// Example/ label:community contribution
const input = event.target.value;
const inputs = input.split(' ');
let searchTerms = '';
inputs.forEach((i) => {
const colonIndex = i.indexOf(':');
// Check if text is a token
if (colonIndex !== -1) {
const tokenKey = i.slice(0, colonIndex).toLowerCase();
const tokenValue = i.slice(colonIndex + 1);
const match = validTokenKeys.filter((v) => {
return v.name === tokenKey;
})[0];
if (match) {
this.tokens.push = {
key: match.key,
value: tokenValue,
};
}
} else {
searchTerms += i + ' ';
}
}, this);
this.searchToken = searchTerms.trim();
this.printTokens();
}
printTokens() {
console.log(this.tokens);
console.log(this.searchToken);
}
checkForEnter(event) {
if (event.key === 'Enter') {
event.stopPropagation();
event.preventDefault();
this.search();
}
}
search() {
console.log('search');
let path = '?scope=all&state=opened&utf8=✓';
this.tokens.foreach((token) => {
});
if (this.searchToken) {
path += '&search=' + this.searchToken;
}
window.location = path;
}
}
global.FilteredSearchManager = FilteredSearchManager;
})(window.gl || (window.gl = {}));
\ No newline at end of file
app/assets/stylesheets/framework/filters.scss
View file @
71dc5af9
...
...
@@ -23,3 +23,27 @@
}
}
.filtered-search-container
{
display
:
flex
;
}
.filtered-search-input-container
{
display
:
flex
;
position
:
relative
;
width
:
100%
;
.form-control
{
padding-left
:
25px
;
&
:focus
~
.fa-filter
{
color
:
#444
;
}
}
.fa-filter
{
position
:
absolute
;
left
:
10px
;
top
:
10px
;
color
:
$gray-darkest
;
}
}
app/views/projects/issues/index.html.haml
View file @
71dc5af9
...
...
@@ -6,6 +6,9 @@
=
content_for
:sub_nav
do
=
render
"projects/issues/head"
-
content_for
:page_specific_javascripts
do
=
page_specific_javascript_tag
(
'filtered_search/filtered_search_bundle.js'
)
=
content_for
:meta_tags
do
-
if
current_user
=
auto_discovery_link_tag
(
:atom
,
url_for
(
params
.
merge
(
format: :atom
,
private_token:
current_user
.
private_token
)),
title:
"
#{
@project
.
name
}
issues"
)
...
...
@@ -20,7 +23,6 @@
=
icon
(
'rss'
)
%span
.icon-label
Subscribe
=
render
'shared/issuable/search_form'
,
path:
namespace_project_issues_path
(
@project
.
namespace
,
@project
)
-
if
can?
current_user
,
:create_issue
,
@project
=
link_to
new_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
...
...
@@ -30,7 +32,7 @@
title:
"New Issue"
,
id:
"new_issue_link"
do
New Issue
=
render
'shared/issuable/
filte
r'
,
type: :issues
=
render
'shared/issuable/
search_ba
r'
,
type: :issues
.issues-holder
=
render
'issues'
...
...
app/views/shared/issuable/_search_bar.html.haml
0 → 100644
View file @
71dc5af9
-
finder
=
controller
.
controller_name
==
'issues'
||
controller
.
controller_name
==
'boards'
?
issues_finder
:
merge_requests_finder
-
boards_page
=
controller
.
controller_name
==
'boards'
.issues-filters
.issues-details-filters.row-content-block.second-block
=
form_tag
page_filter_path
(
without:
[
:assignee_id
,
:author_id
,
:milestone_title
,
:label_name
,
:search
]),
method: :get
,
class:
'filter-form js-filter-form'
do
-
if
params
[
:search
].
present?
=
hidden_field_tag
:search
,
params
[
:search
]
-
if
@bulk_edit
.check-all-holder
=
check_box_tag
"check_all_issues"
,
nil
,
false
,
class:
"check_all_issues left"
.issues-other-filters.filtered-search-container
.filtered-search-input-container
%input
.form-control.filtered-search
{
placeholder:
'Search or filter results...'
}
=
icon
(
'filter'
)
.pull-right
-
if
boards_page
#js-boards-seach
.issue-boards-search
%input
.pull-left.form-control
{
type:
"search"
,
placeholder:
"Filter by name..."
,
"v-model"
=>
"filters.search"
,
"debounce"
=>
"250"
}
-
if
can?
(
current_user
,
:admin_list
,
@project
)
.dropdown.pull-right
%button
.btn.btn-create.js-new-board-list
{
type:
"button"
,
data:
{
toggle:
"dropdown"
,
labels:
labels_filter_path
,
namespace_path:
@project
.
try
(
:namespace
).
try
(
:path
),
project_path:
@project
.
try
(
:path
)
}
}
Create new list
.dropdown-menu.dropdown-menu-paging.dropdown-menu-align-right.dropdown-menu-issues-board-new.dropdown-menu-selectable
=
render
partial:
"shared/issuable/label_page_default"
,
locals:
{
show_footer:
true
,
show_create:
true
,
show_boards_content:
true
,
title:
"Create a new list"
}
-
if
can?
(
current_user
,
:admin_label
,
@project
)
=
render
partial:
"shared/issuable/label_page_create"
=
dropdown_loading
-
else
=
render
'shared/sort_dropdown'
-
if
@bulk_edit
.issues_bulk_update.hide
=
form_tag
[
:bulk_update
,
@project
.
namespace
.
becomes
(
Namespace
),
@project
,
type
],
method: :post
,
class:
'bulk-update'
do
.filter-item.inline
=
dropdown_tag
(
"Status"
,
options:
{
toggle_class:
"js-issue-status"
,
title:
"Change status"
,
dropdown_class:
"dropdown-menu-status dropdown-menu-selectable"
,
data:
{
field_name:
"update[state_event]"
}
}
)
do
%ul
%li
%a
{
href:
"#"
,
data:
{
id:
"reopen"
}}
Open
%li
%a
{
href:
"#"
,
data:
{
id:
"close"
}}
Closed
.filter-item.inline
=
dropdown_tag
(
"Assignee"
,
options:
{
toggle_class:
"js-user-search js-update-assignee js-filter-submit js-filter-bulk-update"
,
title:
"Assign to"
,
filter:
true
,
dropdown_class:
"dropdown-menu-user dropdown-menu-selectable"
,
placeholder:
"Search authors"
,
data:
{
first_user:
(
current_user
.
username
if
current_user
),
null_user:
true
,
current_user:
true
,
project_id:
@project
.
id
,
field_name:
"update[assignee_id]"
}
})
.filter-item.inline
=
dropdown_tag
(
"Milestone"
,
options:
{
title:
"Assign milestone"
,
toggle_class:
'js-milestone-select js-extra-options js-filter-submit js-filter-bulk-update'
,
filter:
true
,
dropdown_class:
"dropdown-menu-selectable dropdown-menu-milestone"
,
placeholder:
"Search milestones"
,
data:
{
show_no:
true
,
field_name:
"update[milestone_id]"
,
project_id:
@project
.
id
,
milestones:
namespace_project_milestones_path
(
@project
.
namespace
,
@project
,
:json
),
use_id:
true
}
})
.filter-item.inline.labels-filter
=
render
"shared/issuable/label_dropdown"
,
classes:
[
'js-filter-bulk-update'
,
'js-multiselect'
],
show_create:
false
,
show_footer:
false
,
extra_options:
false
,
filter_submit:
false
,
data_options:
{
persist_when_hide:
"true"
,
field_name:
"update[label_ids][]"
,
show_no:
false
,
show_any:
false
,
use_id:
true
}
.filter-item.inline
=
dropdown_tag
(
"Subscription"
,
options:
{
toggle_class:
"js-subscription-event"
,
title:
"Change subscription"
,
dropdown_class:
"dropdown-menu-selectable"
,
data:
{
field_name:
"update[subscription_event]"
}
}
)
do
%ul
%li
%a
{
href:
"#"
,
data:
{
id:
"subscribe"
}}
Subscribe
%li
%a
{
href:
"#"
,
data:
{
id:
"unsubscribe"
}}
Unsubscribe
=
hidden_field_tag
'update[issuable_ids]'
,
[]
=
hidden_field_tag
:state_event
,
params
[
:state_event
]
.filter-item.inline
=
button_tag
"Update
#{
type
.
to_s
.
humanize
(
capitalize:
false
)
}
"
,
class:
"btn update_selected_issues btn-save"
-
has_labels
=
@labels
&&
@labels
.
any?
.row-content-block.second-block.filtered-labels
{
class:
(
"hidden"
unless
has_labels
)
}
-
if
has_labels
=
render
'shared/labels_row'
,
labels:
@labels
:javascript
new
UsersSelect
();
new
LabelsSelect
();
new
MilestoneSelect
();
new
IssueStatusSelect
();
new
SubscriptionSelect
();
$
(
'form.filter-form'
).
on
(
'submit'
,
function
(
event
)
{
event
.
preventDefault
();
Turbolinks
.
visit
(
this
.
action
+
'&'
+
$
(
this
).
serialize
());
});
config/application.rb
View file @
71dc5af9
...
...
@@ -106,6 +106,7 @@ module Gitlab
config
.
assets
.
precompile
<<
"blob_edit/blob_edit_bundle.js"
config
.
assets
.
precompile
<<
"snippet/snippet_bundle.js"
config
.
assets
.
precompile
<<
"terminal/terminal_bundle.js"
config
.
assets
.
precompile
<<
"filtered_search/filtered_search_bundle.js"
config
.
assets
.
precompile
<<
"lib/utils/*.js"
config
.
assets
.
precompile
<<
"lib/*.js"
config
.
assets
.
precompile
<<
"u2f.js"
...
...
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