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
bd8290d9
Commit
bd8290d9
authored
Feb 21, 2018
by
Jacob Schatz
Committed by
Clement Ho
Feb 21, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rest of Dispatcher Refactor
parent
ace12dd1
Changes
54
Show whitespace changes
Inline
Side-by-side
Showing
54 changed files
with
319 additions
and
338 deletions
+319
-338
app/assets/javascripts/blob_edit/blob_bundle.js
app/assets/javascripts/blob_edit/blob_bundle.js
+2
-2
app/assets/javascripts/boards/filtered_search_boards.js
app/assets/javascripts/boards/filtered_search_boards.js
+2
-1
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+0
-5
app/assets/javascripts/docs/docs_bundle.js
app/assets/javascripts/docs/docs_bundle.js
+2
-5
app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.js
...red_search/components/recent_searches_dropdown_content.js
+2
-1
app/assets/javascripts/filtered_search/dropdown_emoji.js
app/assets/javascripts/filtered_search/dropdown_emoji.js
+4
-6
app/assets/javascripts/filtered_search/dropdown_hint.js
app/assets/javascripts/filtered_search/dropdown_hint.js
+8
-8
app/assets/javascripts/filtered_search/dropdown_non_user.js
app/assets/javascripts/filtered_search/dropdown_non_user.js
+5
-7
app/assets/javascripts/filtered_search/dropdown_user.js
app/assets/javascripts/filtered_search/dropdown_user.js
+6
-7
app/assets/javascripts/filtered_search/dropdown_utils.js
app/assets/javascripts/filtered_search/dropdown_utils.js
+10
-10
app/assets/javascripts/filtered_search/filtered_search_dropdown.js
...s/javascripts/filtered_search/filtered_search_dropdown.js
+6
-6
app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
...ripts/filtered_search/filtered_search_dropdown_manager.js
+22
-18
app/assets/javascripts/filtered_search/filtered_search_manager.js
...ts/javascripts/filtered_search/filtered_search_manager.js
+36
-32
app/assets/javascripts/filtered_search/filtered_search_tokenizer.js
.../javascripts/filtered_search/filtered_search_tokenizer.js
+1
-4
app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
...ascripts/filtered_search/filtered_search_visual_tokens.js
+10
-12
app/assets/javascripts/help/help.js
app/assets/javascripts/help/help.js
+7
-5
app/assets/javascripts/pages/dashboard/groups/index/index.js
app/assets/javascripts/pages/dashboard/groups/index/index.js
+2
-4
app/assets/javascripts/pages/groups/show/index.js
app/assets/javascripts/pages/groups/show/index.js
+1
-1
app/assets/javascripts/pages/help/index.js
app/assets/javascripts/pages/help/index.js
+0
-3
app/assets/javascripts/pages/help/index/index.js
app/assets/javascripts/pages/help/index/index.js
+7
-0
app/assets/javascripts/pages/help/show/index.js
app/assets/javascripts/pages/help/show/index.js
+3
-0
app/assets/javascripts/pages/help/ui/index.js
app/assets/javascripts/pages/help/ui/index.js
+3
-0
app/assets/javascripts/pages/import/gitlab_projects/new/index.js
...ets/javascripts/pages/import/gitlab_projects/new/index.js
+3
-0
app/assets/javascripts/pages/profiles/accounts/show/index.js
app/assets/javascripts/pages/profiles/accounts/show/index.js
+3
-0
app/assets/javascripts/pages/projects/blob/edit/index.js
app/assets/javascripts/pages/projects/blob/edit/index.js
+3
-0
app/assets/javascripts/pages/projects/blob/new/index.js
app/assets/javascripts/pages/projects/blob/new/index.js
+3
-0
app/assets/javascripts/pages/projects/init_blob.js
app/assets/javascripts/pages/projects/init_blob.js
+3
-0
app/assets/javascripts/pages/projects/tree/show/index.js
app/assets/javascripts/pages/projects/tree/show/index.js
+2
-0
app/assets/javascripts/pages/search/init_filtered_search.js
app/assets/javascripts/pages/search/init_filtered_search.js
+3
-12
app/assets/javascripts/profile/account/index.js
app/assets/javascripts/profile/account/index.js
+24
-24
app/assets/javascripts/projects/project_import_gitlab_project.js
...ets/javascripts/projects/project_import_gitlab_project.js
+1
-7
app/assets/javascripts/search_autocomplete.js
app/assets/javascripts/search_autocomplete.js
+1
-0
app/assets/javascripts/ui_development_kit.js
app/assets/javascripts/ui_development_kit.js
+2
-2
app/views/groups/issues.html.haml
app/views/groups/issues.html.haml
+0
-1
app/views/groups/merge_requests.html.haml
app/views/groups/merge_requests.html.haml
+0
-1
app/views/help/index.html.haml
app/views/help/index.html.haml
+0
-2
app/views/help/show.html.haml
app/views/help/show.html.haml
+0
-2
app/views/import/gitlab_projects/new.html.haml
app/views/import/gitlab_projects/new.html.haml
+0
-2
app/views/profiles/accounts/show.html.haml
app/views/profiles/accounts/show.html.haml
+0
-3
app/views/projects/blob/_upload.html.haml
app/views/projects/blob/_upload.html.haml
+1
-1
app/views/projects/blob/edit.html.haml
app/views/projects/blob/edit.html.haml
+0
-1
app/views/projects/blob/new.html.haml
app/views/projects/blob/new.html.haml
+0
-1
app/views/projects/blob/show.html.haml
app/views/projects/blob/show.html.haml
+0
-4
app/views/projects/merge_requests/index.html.haml
app/views/projects/merge_requests/index.html.haml
+0
-1
app/views/shared/boards/_show.html.haml
app/views/shared/boards/_show.html.haml
+0
-1
config/karma.config.js
config/karma.config.js
+1
-1
config/webpack.config.js
config/webpack.config.js
+0
-2
spec/javascripts/filtered_search/dropdown_user_spec.js
spec/javascripts/filtered_search/dropdown_user_spec.js
+17
-19
spec/javascripts/filtered_search/dropdown_utils_spec.js
spec/javascripts/filtered_search/dropdown_utils_spec.js
+47
-48
spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
.../filtered_search/filtered_search_dropdown_manager_spec.js
+10
-12
spec/javascripts/filtered_search/filtered_search_manager_spec.js
...vascripts/filtered_search/filtered_search_manager_spec.js
+34
-33
spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js
...scripts/filtered_search/filtered_search_tokenizer_spec.js
+11
-11
spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
...pts/filtered_search/filtered_search_visual_tokens_spec.js
+10
-9
spec/javascripts/projects/project_import_gitlab_project_spec.js
...avascripts/projects/project_import_gitlab_project_spec.js
+1
-1
No files found.
app/assets/javascripts/blob_edit/blob_bundle.js
View file @
bd8290d9
...
@@ -4,7 +4,7 @@ import NewCommitForm from '../new_commit_form';
...
@@ -4,7 +4,7 @@ import NewCommitForm from '../new_commit_form';
import
EditBlob
from
'
./edit_blob
'
;
import
EditBlob
from
'
./edit_blob
'
;
import
BlobFileDropzone
from
'
../blob/blob_file_dropzone
'
;
import
BlobFileDropzone
from
'
../blob/blob_file_dropzone
'
;
$
(
()
=>
{
export
default
()
=>
{
const
editBlobForm
=
$
(
'
.js-edit-blob-form
'
);
const
editBlobForm
=
$
(
'
.js-edit-blob-form
'
);
const
uploadBlobForm
=
$
(
'
.js-upload-blob-form
'
);
const
uploadBlobForm
=
$
(
'
.js-upload-blob-form
'
);
const
deleteBlobForm
=
$
(
'
.js-delete-blob-form
'
);
const
deleteBlobForm
=
$
(
'
.js-delete-blob-form
'
);
...
@@ -34,4 +34,4 @@ $(() => {
...
@@ -34,4 +34,4 @@ $(() => {
if
(
deleteBlobForm
.
length
)
{
if
(
deleteBlobForm
.
length
)
{
new
NewCommitForm
(
deleteBlobForm
);
new
NewCommitForm
(
deleteBlobForm
);
}
}
}
)
;
};
app/assets/javascripts/boards/filtered_search_boards.js
View file @
bd8290d9
/* eslint-disable class-methods-use-this */
/* eslint-disable class-methods-use-this */
import
FilteredSearchContainer
from
'
../filtered_search/container
'
;
import
FilteredSearchContainer
from
'
../filtered_search/container
'
;
import
FilteredSearchManager
from
'
../filtered_search/filtered_search_manager
'
;
export
default
class
FilteredSearchBoards
extends
gl
.
FilteredSearchManager
{
export
default
class
FilteredSearchBoards
extends
FilteredSearchManager
{
constructor
(
store
,
updateUrl
=
false
,
cantEdit
=
[])
{
constructor
(
store
,
updateUrl
=
false
,
cantEdit
=
[])
{
super
(
'
boards
'
);
super
(
'
boards
'
);
...
...
app/assets/javascripts/dispatcher.js
View file @
bd8290d9
...
@@ -174,11 +174,6 @@ var Dispatcher;
...
@@ -174,11 +174,6 @@ var Dispatcher;
.
catch
(
fail
);
.
catch
(
fail
);
shortcut_handler
=
true
;
shortcut_handler
=
true
;
break
;
break
;
case
'
help:index
'
:
import
(
'
./pages/help
'
)
.
then
(
callDefault
)
.
catch
(
fail
);
break
;
case
'
search:show
'
:
case
'
search:show
'
:
import
(
'
./pages/search/show
'
)
import
(
'
./pages/search/show
'
)
.
then
(
callDefault
)
.
then
(
callDefault
)
...
...
app/assets/javascripts/docs/docs_bundle.js
View file @
bd8290d9
...
@@ -4,10 +4,7 @@ function addMousetrapClick(el, key) {
...
@@ -4,10 +4,7 @@ function addMousetrapClick(el, key) {
el
.
addEventListener
(
'
click
'
,
()
=>
Mousetrap
.
trigger
(
key
));
el
.
addEventListener
(
'
click
'
,
()
=>
Mousetrap
.
trigger
(
key
));
}
}
function
domContentLoaded
()
{
export
default
()
=>
{
addMousetrapClick
(
document
.
querySelector
(
'
.js-trigger-shortcut
'
),
'
?
'
);
addMousetrapClick
(
document
.
querySelector
(
'
.js-trigger-shortcut
'
),
'
?
'
);
addMousetrapClick
(
document
.
querySelector
(
'
.js-trigger-search-bar
'
),
'
s
'
);
addMousetrapClick
(
document
.
querySelector
(
'
.js-trigger-search-bar
'
),
'
s
'
);
}
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
domContentLoaded
);
app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.js
View file @
bd8290d9
import
eventHub
from
'
../event_hub
'
;
import
eventHub
from
'
../event_hub
'
;
import
FilteredSearchTokenizer
from
'
../filtered_search_tokenizer
'
;
export
default
{
export
default
{
name
:
'
RecentSearchesDropdownContent
'
,
name
:
'
RecentSearchesDropdownContent
'
,
...
@@ -23,7 +24,7 @@ export default {
...
@@ -23,7 +24,7 @@ export default {
processedItems
()
{
processedItems
()
{
return
this
.
items
.
map
((
item
)
=>
{
return
this
.
items
.
map
((
item
)
=>
{
const
{
tokens
,
searchToken
}
const
{
tokens
,
searchToken
}
=
gl
.
FilteredSearchTokenizer
.
processTokens
(
item
,
this
.
allowedKeys
);
=
FilteredSearchTokenizer
.
processTokens
(
item
,
this
.
allowedKeys
);
const
resultantTokens
=
tokens
.
map
(
token
=>
({
const
resultantTokens
=
tokens
.
map
(
token
=>
({
prefix
:
`
${
token
.
key
}
:`
,
prefix
:
`
${
token
.
key
}
:`
,
...
...
app/assets/javascripts/filtered_search/dropdown_emoji.js
View file @
bd8290d9
import
Flash
from
'
../flash
'
;
import
Flash
from
'
../flash
'
;
import
Ajax
from
'
../droplab/plugins/ajax
'
;
import
Ajax
from
'
../droplab/plugins/ajax
'
;
import
Filter
from
'
../droplab/plugins/filter
'
;
import
Filter
from
'
../droplab/plugins/filter
'
;
import
'
./filtered_search_dropdown
'
;
import
FilteredSearchDropdown
from
'
./filtered_search_dropdown
'
;
import
DropdownUtils
from
'
./dropdown_utils
'
;
class
DropdownEmoji
extends
gl
.
FilteredSearchDropdown
{
export
default
class
DropdownEmoji
extends
FilteredSearchDropdown
{
constructor
(
options
=
{})
{
constructor
(
options
=
{})
{
super
(
options
);
super
(
options
);
this
.
config
=
{
this
.
config
=
{
...
@@ -49,7 +50,7 @@ class DropdownEmoji extends gl.FilteredSearchDropdown {
...
@@ -49,7 +50,7 @@ class DropdownEmoji extends gl.FilteredSearchDropdown {
itemClicked
(
e
)
{
itemClicked
(
e
)
{
super
.
itemClicked
(
e
,
(
selected
)
=>
{
super
.
itemClicked
(
e
,
(
selected
)
=>
{
const
name
=
selected
.
querySelector
(
'
.js-data-value
'
).
innerText
.
trim
();
const
name
=
selected
.
querySelector
(
'
.js-data-value
'
).
innerText
.
trim
();
return
gl
.
DropdownUtils
.
getEscapedText
(
name
);
return
DropdownUtils
.
getEscapedText
(
name
);
});
});
}
}
...
@@ -76,6 +77,3 @@ class DropdownEmoji extends gl.FilteredSearchDropdown {
...
@@ -76,6 +77,3 @@ class DropdownEmoji extends gl.FilteredSearchDropdown {
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
Ajax
,
Filter
],
this
.
config
).
init
();
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
Ajax
,
Filter
],
this
.
config
).
init
();
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
gl
.
DropdownEmoji
=
DropdownEmoji
;
app/assets/javascripts/filtered_search/dropdown_hint.js
View file @
bd8290d9
import
Filter
from
'
~/droplab/plugins/filter
'
;
import
Filter
from
'
~/droplab/plugins/filter
'
;
import
'
./filtered_search_dropdown
'
;
import
FilteredSearchDropdown
from
'
./filtered_search_dropdown
'
;
import
DropdownUtils
from
'
./dropdown_utils
'
;
import
FilteredSearchDropdownManager
from
'
./filtered_search_dropdown_manager
'
;
import
FilteredSearchVisualTokens
from
'
./filtered_search_visual_tokens
'
;
class
DropdownHint
extends
gl
.
FilteredSearchDropdown
{
export
default
class
DropdownHint
extends
FilteredSearchDropdown
{
constructor
(
options
=
{})
{
constructor
(
options
=
{})
{
const
{
input
,
tokenKeys
}
=
options
;
const
{
input
,
tokenKeys
}
=
options
;
super
(
options
);
super
(
options
);
this
.
config
=
{
this
.
config
=
{
Filter
:
{
Filter
:
{
template
:
'
hint
'
,
template
:
'
hint
'
,
filterFunction
:
gl
.
DropdownUtils
.
filterHint
.
bind
(
null
,
{
filterFunction
:
DropdownUtils
.
filterHint
.
bind
(
null
,
{
input
,
input
,
allowedKeys
:
tokenKeys
.
getKeys
(),
allowedKeys
:
tokenKeys
.
getKeys
(),
}),
}),
...
@@ -45,10 +48,10 @@ class DropdownHint extends gl.FilteredSearchDropdown {
...
@@ -45,10 +48,10 @@ class DropdownHint extends gl.FilteredSearchDropdown {
});
});
if
(
searchTerms
.
length
>
0
)
{
if
(
searchTerms
.
length
>
0
)
{
gl
.
FilteredSearchVisualTokens
.
addSearchVisualToken
(
searchTerms
.
join
(
'
'
));
FilteredSearchVisualTokens
.
addSearchVisualToken
(
searchTerms
.
join
(
'
'
));
}
}
gl
.
FilteredSearchDropdownManager
.
addWordToInput
(
token
.
replace
(
'
:
'
,
''
),
''
,
false
,
this
.
container
);
FilteredSearchDropdownManager
.
addWordToInput
(
token
.
replace
(
'
:
'
,
''
),
''
,
false
,
this
.
container
);
}
}
this
.
dismissDropdown
();
this
.
dismissDropdown
();
this
.
dispatchInputEvent
();
this
.
dispatchInputEvent
();
...
@@ -73,6 +76,3 @@ class DropdownHint extends gl.FilteredSearchDropdown {
...
@@ -73,6 +76,3 @@ class DropdownHint extends gl.FilteredSearchDropdown {
this
.
droplab
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
Filter
],
this
.
config
).
init
();
this
.
droplab
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
Filter
],
this
.
config
).
init
();
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
gl
.
DropdownHint
=
DropdownHint
;
app/assets/javascripts/filtered_search/dropdown_non_user.js
View file @
bd8290d9
import
Flash
from
'
../flash
'
;
import
Flash
from
'
../flash
'
;
import
Ajax
from
'
../droplab/plugins/ajax
'
;
import
Ajax
from
'
../droplab/plugins/ajax
'
;
import
Filter
from
'
../droplab/plugins/filter
'
;
import
Filter
from
'
../droplab/plugins/filter
'
;
import
'
./filtered_search_dropdown
'
;
import
FilteredSearchDropdown
from
'
./filtered_search_dropdown
'
;
import
DropdownUtils
from
'
./dropdown_utils
'
;
class
DropdownNonUser
extends
gl
.
FilteredSearchDropdown
{
export
default
class
DropdownNonUser
extends
FilteredSearchDropdown
{
constructor
(
options
=
{})
{
constructor
(
options
=
{})
{
const
{
input
,
endpoint
,
symbol
,
preprocessing
}
=
options
;
const
{
input
,
endpoint
,
symbol
,
preprocessing
}
=
options
;
super
(
options
);
super
(
options
);
...
@@ -21,7 +22,7 @@ class DropdownNonUser extends gl.FilteredSearchDropdown {
...
@@ -21,7 +22,7 @@ class DropdownNonUser extends gl.FilteredSearchDropdown {
},
},
},
},
Filter
:
{
Filter
:
{
filterFunction
:
gl
.
DropdownUtils
.
filterWithSymbol
.
bind
(
null
,
this
.
symbol
,
input
),
filterFunction
:
DropdownUtils
.
filterWithSymbol
.
bind
(
null
,
this
.
symbol
,
input
),
template
:
'
title
'
,
template
:
'
title
'
,
},
},
};
};
...
@@ -30,7 +31,7 @@ class DropdownNonUser extends gl.FilteredSearchDropdown {
...
@@ -30,7 +31,7 @@ class DropdownNonUser extends gl.FilteredSearchDropdown {
itemClicked
(
e
)
{
itemClicked
(
e
)
{
super
.
itemClicked
(
e
,
(
selected
)
=>
{
super
.
itemClicked
(
e
,
(
selected
)
=>
{
const
title
=
selected
.
querySelector
(
'
.js-data-value
'
).
innerText
.
trim
();
const
title
=
selected
.
querySelector
(
'
.js-data-value
'
).
innerText
.
trim
();
return
`
${
this
.
symbol
}${
gl
.
DropdownUtils
.
getEscapedText
(
title
)}
`
;
return
`
${
this
.
symbol
}${
DropdownUtils
.
getEscapedText
(
title
)}
`
;
});
});
}
}
...
@@ -45,6 +46,3 @@ class DropdownNonUser extends gl.FilteredSearchDropdown {
...
@@ -45,6 +46,3 @@ class DropdownNonUser extends gl.FilteredSearchDropdown {
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
Ajax
,
Filter
],
this
.
config
).
init
();
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
Ajax
,
Filter
],
this
.
config
).
init
();
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
gl
.
DropdownNonUser
=
DropdownNonUser
;
app/assets/javascripts/filtered_search/dropdown_user.js
View file @
bd8290d9
import
Flash
from
'
../flash
'
;
import
Flash
from
'
../flash
'
;
import
AjaxFilter
from
'
../droplab/plugins/ajax_filter
'
;
import
AjaxFilter
from
'
../droplab/plugins/ajax_filter
'
;
import
'
./filtered_search_dropdown
'
;
import
FilteredSearchDropdown
from
'
./filtered_search_dropdown
'
;
import
{
addClassIfElementExists
}
from
'
../lib/utils/dom_utils
'
;
import
{
addClassIfElementExists
}
from
'
../lib/utils/dom_utils
'
;
import
DropdownUtils
from
'
./dropdown_utils
'
;
import
FilteredSearchTokenizer
from
'
./filtered_search_tokenizer
'
;
class
DropdownUser
extends
gl
.
FilteredSearchDropdown
{
export
default
class
DropdownUser
extends
FilteredSearchDropdown
{
constructor
(
options
=
{})
{
constructor
(
options
=
{})
{
const
{
tokenKeys
}
=
options
;
const
{
tokenKeys
}
=
options
;
super
(
options
);
super
(
options
);
...
@@ -56,8 +58,8 @@ class DropdownUser extends gl.FilteredSearchDropdown {
...
@@ -56,8 +58,8 @@ class DropdownUser extends gl.FilteredSearchDropdown {
}
}
getSearchInput
()
{
getSearchInput
()
{
const
query
=
gl
.
DropdownUtils
.
getSearchInput
(
this
.
input
);
const
query
=
DropdownUtils
.
getSearchInput
(
this
.
input
);
const
{
lastToken
}
=
gl
.
FilteredSearchTokenizer
.
processTokens
(
query
,
this
.
tokenKeys
.
get
());
const
{
lastToken
}
=
FilteredSearchTokenizer
.
processTokens
(
query
,
this
.
tokenKeys
.
get
());
let
value
=
lastToken
||
''
;
let
value
=
lastToken
||
''
;
...
@@ -78,6 +80,3 @@ class DropdownUser extends gl.FilteredSearchDropdown {
...
@@ -78,6 +80,3 @@ class DropdownUser extends gl.FilteredSearchDropdown {
this
.
droplab
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
AjaxFilter
],
this
.
config
).
init
();
this
.
droplab
.
addHook
(
this
.
input
,
this
.
dropdown
,
[
AjaxFilter
],
this
.
config
).
init
();
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
gl
.
DropdownUser
=
DropdownUser
;
app/assets/javascripts/filtered_search/dropdown_utils.js
View file @
bd8290d9
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
FilteredSearchContainer
from
'
./container
'
;
import
FilteredSearchContainer
from
'
./container
'
;
import
FilteredSearchTokenizer
from
'
./filtered_search_tokenizer
'
;
import
FilteredSearchDropdownManager
from
'
./filtered_search_dropdown_manager
'
;
import
FilteredSearchVisualTokens
from
'
./filtered_search_visual_tokens
'
;
class
DropdownUtils
{
export
default
class
DropdownUtils
{
static
getEscapedText
(
text
)
{
static
getEscapedText
(
text
)
{
let
escapedText
=
text
;
let
escapedText
=
text
;
const
hasSpace
=
text
.
indexOf
(
'
'
)
!==
-
1
;
const
hasSpace
=
text
.
indexOf
(
'
'
)
!==
-
1
;
...
@@ -24,7 +27,7 @@ class DropdownUtils {
...
@@ -24,7 +27,7 @@ class DropdownUtils {
static
filterWithSymbol
(
filterSymbol
,
input
,
item
)
{
static
filterWithSymbol
(
filterSymbol
,
input
,
item
)
{
const
updatedItem
=
item
;
const
updatedItem
=
item
;
const
searchInput
=
gl
.
DropdownUtils
.
getSearchInput
(
input
);
const
searchInput
=
DropdownUtils
.
getSearchInput
(
input
);
const
title
=
updatedItem
.
title
.
toLowerCase
();
const
title
=
updatedItem
.
title
.
toLowerCase
();
let
value
=
searchInput
.
toLowerCase
();
let
value
=
searchInput
.
toLowerCase
();
...
@@ -114,9 +117,9 @@ class DropdownUtils {
...
@@ -114,9 +117,9 @@ class DropdownUtils {
static
filterHint
(
config
,
item
)
{
static
filterHint
(
config
,
item
)
{
const
{
input
,
allowedKeys
}
=
config
;
const
{
input
,
allowedKeys
}
=
config
;
const
updatedItem
=
item
;
const
updatedItem
=
item
;
const
searchInput
=
gl
.
DropdownUtils
.
getSearchQuery
(
input
);
const
searchInput
=
DropdownUtils
.
getSearchQuery
(
input
);
const
{
lastToken
,
tokens
}
=
const
{
lastToken
,
tokens
}
=
gl
.
FilteredSearchTokenizer
.
processTokens
(
searchInput
,
allowedKeys
);
FilteredSearchTokenizer
.
processTokens
(
searchInput
,
allowedKeys
);
const
lastKey
=
lastToken
.
key
||
lastToken
||
''
;
const
lastKey
=
lastToken
.
key
||
lastToken
||
''
;
const
allowMultiple
=
item
.
type
===
'
array
'
;
const
allowMultiple
=
item
.
type
===
'
array
'
;
const
itemInExistingTokens
=
tokens
.
some
(
t
=>
t
.
key
===
item
.
hint
);
const
itemInExistingTokens
=
tokens
.
some
(
t
=>
t
.
key
===
item
.
hint
);
...
@@ -140,7 +143,7 @@ class DropdownUtils {
...
@@ -140,7 +143,7 @@ class DropdownUtils {
const
dataValue
=
selected
.
getAttribute
(
'
data-value
'
);
const
dataValue
=
selected
.
getAttribute
(
'
data-value
'
);
if
(
dataValue
)
{
if
(
dataValue
)
{
gl
.
FilteredSearchDropdownManager
.
addWordToInput
(
filter
,
dataValue
,
true
);
FilteredSearchDropdownManager
.
addWordToInput
(
filter
,
dataValue
,
true
);
}
}
// Return boolean based on whether it was set
// Return boolean based on whether it was set
...
@@ -190,7 +193,7 @@ class DropdownUtils {
...
@@ -190,7 +193,7 @@ class DropdownUtils {
}
}
}
else
if
(
token
.
classList
.
contains
(
'
input-token
'
))
{
}
else
if
(
token
.
classList
.
contains
(
'
input-token
'
))
{
const
{
isLastVisualTokenValid
}
=
const
{
isLastVisualTokenValid
}
=
gl
.
FilteredSearchVisualTokens
.
getLastVisualTokenBeforeInput
();
FilteredSearchVisualTokens
.
getLastVisualTokenBeforeInput
();
const
input
=
FilteredSearchContainer
.
container
.
querySelector
(
'
.filtered-search
'
);
const
input
=
FilteredSearchContainer
.
container
.
querySelector
(
'
.filtered-search
'
);
const
inputValue
=
input
&&
input
.
value
;
const
inputValue
=
input
&&
input
.
value
;
...
@@ -211,7 +214,7 @@ class DropdownUtils {
...
@@ -211,7 +214,7 @@ class DropdownUtils {
static
getSearchInput
(
filteredSearchInput
)
{
static
getSearchInput
(
filteredSearchInput
)
{
const
inputValue
=
filteredSearchInput
.
value
;
const
inputValue
=
filteredSearchInput
.
value
;
const
{
right
}
=
gl
.
DropdownUtils
.
getInputSelectionPosition
(
filteredSearchInput
);
const
{
right
}
=
DropdownUtils
.
getInputSelectionPosition
(
filteredSearchInput
);
return
inputValue
.
slice
(
0
,
right
);
return
inputValue
.
slice
(
0
,
right
);
}
}
...
@@ -252,6 +255,3 @@ class DropdownUtils {
...
@@ -252,6 +255,3 @@ class DropdownUtils {
};
};
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
gl
.
DropdownUtils
=
DropdownUtils
;
app/assets/javascripts/filtered_search/filtered_search_dropdown.js
View file @
bd8290d9
import
DropdownUtils
from
'
./dropdown_utils
'
;
import
FilteredSearchDropdownManager
from
'
./filtered_search_dropdown_manager
'
;
const
DATA_DROPDOWN_TRIGGER
=
'
data-dropdown-trigger
'
;
const
DATA_DROPDOWN_TRIGGER
=
'
data-dropdown-trigger
'
;
class
FilteredSearchDropdown
{
export
default
class
FilteredSearchDropdown
{
constructor
({
droplab
,
dropdown
,
input
,
filter
})
{
constructor
({
droplab
,
dropdown
,
input
,
filter
})
{
this
.
droplab
=
droplab
;
this
.
droplab
=
droplab
;
this
.
hookId
=
input
&&
input
.
id
;
this
.
hookId
=
input
&&
input
.
id
;
...
@@ -30,11 +33,11 @@ class FilteredSearchDropdown {
...
@@ -30,11 +33,11 @@ class FilteredSearchDropdown {
const
{
selected
}
=
e
.
detail
;
const
{
selected
}
=
e
.
detail
;
if
(
selected
.
tagName
===
'
LI
'
&&
selected
.
innerHTML
)
{
if
(
selected
.
tagName
===
'
LI
'
&&
selected
.
innerHTML
)
{
const
dataValueSet
=
gl
.
DropdownUtils
.
setDataValueIfSelected
(
this
.
filter
,
selected
);
const
dataValueSet
=
DropdownUtils
.
setDataValueIfSelected
(
this
.
filter
,
selected
);
if
(
!
dataValueSet
)
{
if
(
!
dataValueSet
)
{
const
value
=
getValueFunction
(
selected
);
const
value
=
getValueFunction
(
selected
);
gl
.
FilteredSearchDropdownManager
.
addWordToInput
(
this
.
filter
,
value
,
true
);
FilteredSearchDropdownManager
.
addWordToInput
(
this
.
filter
,
value
,
true
);
}
}
this
.
resetFilters
();
this
.
resetFilters
();
...
@@ -117,6 +120,3 @@ class FilteredSearchDropdown {
...
@@ -117,6 +120,3 @@ class FilteredSearchDropdown {
}
}
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
gl
.
FilteredSearchDropdown
=
FilteredSearchDropdown
;
app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
View file @
bd8290d9
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
DropLab
from
'
~/droplab/drop_lab
'
;
import
DropLab
from
'
~/droplab/drop_lab
'
;
import
FilteredSearchContainer
from
'
./container
'
;
import
FilteredSearchContainer
from
'
./container
'
;
import
FilteredSearchTokenKeys
from
'
./filtered_search_token_keys
'
;
class
FilteredSearchDropdownManager
{
import
DropdownUtils
from
'
./dropdown_utils
'
;
import
DropdownHint
from
'
./dropdown_hint
'
;
import
DropdownEmoji
from
'
./dropdown_emoji
'
;
import
DropdownNonUser
from
'
./dropdown_non_user
'
;
import
DropdownUser
from
'
./dropdown_user
'
;
import
FilteredSearchVisualTokens
from
'
./filtered_search_visual_tokens
'
;
export
default
class
FilteredSearchDropdownManager
{
constructor
(
baseEndpoint
=
''
,
tokenizer
,
page
,
isGroup
,
filteredSearchTokenKeys
)
{
constructor
(
baseEndpoint
=
''
,
tokenizer
,
page
,
isGroup
,
filteredSearchTokenKeys
)
{
this
.
container
=
FilteredSearchContainer
.
container
;
this
.
container
=
FilteredSearchContainer
.
container
;
this
.
baseEndpoint
=
baseEndpoint
.
replace
(
/
\/
$/
,
''
);
this
.
baseEndpoint
=
baseEndpoint
.
replace
(
/
\/
$/
,
''
);
this
.
tokenizer
=
tokenizer
;
this
.
tokenizer
=
tokenizer
;
this
.
filteredSearchTokenKeys
=
filteredSearchTokenKeys
;
this
.
filteredSearchTokenKeys
=
filteredSearchTokenKeys
||
FilteredSearchTokenKeys
;
this
.
filteredSearchInput
=
this
.
container
.
querySelector
(
'
.filtered-search
'
);
this
.
filteredSearchInput
=
this
.
container
.
querySelector
(
'
.filtered-search
'
);
this
.
page
=
page
;
this
.
page
=
page
;
...
@@ -33,24 +40,24 @@ class FilteredSearchDropdownManager {
...
@@ -33,24 +40,24 @@ class FilteredSearchDropdownManager {
const
allowedMappings
=
{
const
allowedMappings
=
{
hint
:
{
hint
:
{
reference
:
null
,
reference
:
null
,
gl
:
'
DropdownHint
'
,
gl
:
DropdownHint
,
element
:
this
.
container
.
querySelector
(
'
#js-dropdown-hint
'
),
element
:
this
.
container
.
querySelector
(
'
#js-dropdown-hint
'
),
},
},
};
};
const
availableMappings
=
{
const
availableMappings
=
{
author
:
{
author
:
{
reference
:
null
,
reference
:
null
,
gl
:
'
DropdownUser
'
,
gl
:
DropdownUser
,
element
:
this
.
container
.
querySelector
(
'
#js-dropdown-author
'
),
element
:
this
.
container
.
querySelector
(
'
#js-dropdown-author
'
),
},
},
assignee
:
{
assignee
:
{
reference
:
null
,
reference
:
null
,
gl
:
'
DropdownUser
'
,
gl
:
DropdownUser
,
element
:
this
.
container
.
querySelector
(
'
#js-dropdown-assignee
'
),
element
:
this
.
container
.
querySelector
(
'
#js-dropdown-assignee
'
),
},
},
milestone
:
{
milestone
:
{
reference
:
null
,
reference
:
null
,
gl
:
'
DropdownNonUser
'
,
gl
:
DropdownNonUser
,
extraArguments
:
{
extraArguments
:
{
endpoint
:
`
${
this
.
baseEndpoint
}
/milestones.json`
,
endpoint
:
`
${
this
.
baseEndpoint
}
/milestones.json`
,
symbol
:
'
%
'
,
symbol
:
'
%
'
,
...
@@ -59,17 +66,17 @@ class FilteredSearchDropdownManager {
...
@@ -59,17 +66,17 @@ class FilteredSearchDropdownManager {
},
},
label
:
{
label
:
{
reference
:
null
,
reference
:
null
,
gl
:
'
DropdownNonUser
'
,
gl
:
DropdownNonUser
,
extraArguments
:
{
extraArguments
:
{
endpoint
:
`
${
this
.
baseEndpoint
}
/labels.json`
,
endpoint
:
`
${
this
.
baseEndpoint
}
/labels.json`
,
symbol
:
'
~
'
,
symbol
:
'
~
'
,
preprocessing
:
gl
.
DropdownUtils
.
duplicateLabelPreprocessing
,
preprocessing
:
DropdownUtils
.
duplicateLabelPreprocessing
,
},
},
element
:
this
.
container
.
querySelector
(
'
#js-dropdown-label
'
),
element
:
this
.
container
.
querySelector
(
'
#js-dropdown-label
'
),
},
},
'
my-reaction
'
:
{
'
my-reaction
'
:
{
reference
:
null
,
reference
:
null
,
gl
:
'
DropdownEmoji
'
,
gl
:
DropdownEmoji
,
element
:
this
.
container
.
querySelector
(
'
#js-dropdown-my-reaction
'
),
element
:
this
.
container
.
querySelector
(
'
#js-dropdown-my-reaction
'
),
},
},
};
};
...
@@ -86,11 +93,11 @@ class FilteredSearchDropdownManager {
...
@@ -86,11 +93,11 @@ class FilteredSearchDropdownManager {
static
addWordToInput
(
tokenName
,
tokenValue
=
''
,
clicked
=
false
)
{
static
addWordToInput
(
tokenName
,
tokenValue
=
''
,
clicked
=
false
)
{
const
input
=
FilteredSearchContainer
.
container
.
querySelector
(
'
.filtered-search
'
);
const
input
=
FilteredSearchContainer
.
container
.
querySelector
(
'
.filtered-search
'
);
gl
.
FilteredSearchVisualTokens
.
addFilterVisualToken
(
tokenName
,
tokenValue
);
FilteredSearchVisualTokens
.
addFilterVisualToken
(
tokenName
,
tokenValue
);
input
.
value
=
''
;
input
.
value
=
''
;
if
(
clicked
)
{
if
(
clicked
)
{
gl
.
FilteredSearchVisualTokens
.
moveInputToTheRight
();
FilteredSearchVisualTokens
.
moveInputToTheRight
();
}
}
}
}
...
@@ -131,9 +138,9 @@ class FilteredSearchDropdownManager {
...
@@ -131,9 +138,9 @@ class FilteredSearchDropdownManager {
const
extraArguments
=
mappingKey
.
extraArguments
||
{};
const
extraArguments
=
mappingKey
.
extraArguments
||
{};
const
glArguments
=
Object
.
assign
({},
defaultArguments
,
extraArguments
);
const
glArguments
=
Object
.
assign
({},
defaultArguments
,
extraArguments
);
// Passing glArguments to `new gl
[glClass]
(<arguments>)`
// Passing glArguments to `new gl
Class
(<arguments>)`
mappingKey
.
reference
=
mappingKey
.
reference
=
new
(
Function
.
prototype
.
bind
.
apply
(
gl
[
glClass
]
,
[
null
,
glArguments
]))();
new
(
Function
.
prototype
.
bind
.
apply
(
gl
Class
,
[
null
,
glArguments
]))();
}
}
if
(
firstLoad
)
{
if
(
firstLoad
)
{
...
@@ -171,7 +178,7 @@ class FilteredSearchDropdownManager {
...
@@ -171,7 +178,7 @@ class FilteredSearchDropdownManager {
}
}
setDropdown
()
{
setDropdown
()
{
const
query
=
gl
.
DropdownUtils
.
getSearchQuery
(
true
);
const
query
=
DropdownUtils
.
getSearchQuery
(
true
);
const
{
lastToken
,
searchToken
}
=
const
{
lastToken
,
searchToken
}
=
this
.
tokenizer
.
processTokens
(
query
,
this
.
filteredSearchTokenKeys
.
getKeys
());
this
.
tokenizer
.
processTokens
(
query
,
this
.
filteredSearchTokenKeys
.
getKeys
());
...
@@ -216,6 +223,3 @@ class FilteredSearchDropdownManager {
...
@@ -216,6 +223,3 @@ class FilteredSearchDropdownManager {
this
.
droplab
.
destroy
();
this
.
droplab
.
destroy
();
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
gl
.
FilteredSearchDropdownManager
=
FilteredSearchDropdownManager
;
app/assets/javascripts/filtered_search/filtered_search_manager.js
View file @
bd8290d9
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
{
getParameterByName
,
getUrlParamsArray
,
}
from
'
~/lib/utils/common_utils
'
;
import
{
visitUrl
}
from
'
../lib/utils/url_utility
'
;
import
{
visitUrl
}
from
'
../lib/utils/url_utility
'
;
import
Flash
from
'
../flash
'
;
import
Flash
from
'
../flash
'
;
import
FilteredSearchContainer
from
'
./container
'
;
import
FilteredSearchContainer
from
'
./container
'
;
import
RecentSearchesRoot
from
'
./recent_searches_root
'
;
import
FilteredSearchTokenKeys
from
'
./filtered_search_token_keys
'
;
import
FilteredSearchTokenKeys
from
'
./filtered_search_token_keys
'
;
import
RecentSearchesRoot
from
'
./recent_searches_root
'
;
import
RecentSearchesStore
from
'
./stores/recent_searches_store
'
;
import
RecentSearchesStore
from
'
./stores/recent_searches_store
'
;
import
RecentSearchesService
from
'
./services/recent_searches_service
'
;
import
RecentSearchesService
from
'
./services/recent_searches_service
'
;
import
eventHub
from
'
./event_hub
'
;
import
eventHub
from
'
./event_hub
'
;
import
{
addClassIfElementExists
}
from
'
../lib/utils/dom_utils
'
;
import
{
addClassIfElementExists
}
from
'
../lib/utils/dom_utils
'
;
import
FilteredSearchTokenizer
from
'
./filtered_search_tokenizer
'
;
import
FilteredSearchDropdownManager
from
'
./filtered_search_dropdown_manager
'
;
import
FilteredSearchVisualTokens
from
'
./filtered_search_visual_tokens
'
;
import
DropdownUtils
from
'
./dropdown_utils
'
;
class
FilteredSearchManager
{
export
default
class
FilteredSearchManager
{
constructor
({
constructor
({
page
,
page
,
filteredSearchTokenKeys
=
FilteredSearchTokenKeys
,
filteredSearchTokenKeys
=
FilteredSearchTokenKeys
,
...
@@ -66,8 +74,8 @@ class FilteredSearchManager {
...
@@ -66,8 +74,8 @@ class FilteredSearchManager {
});
});
if
(
this
.
filteredSearchInput
)
{
if
(
this
.
filteredSearchInput
)
{
this
.
tokenizer
=
gl
.
FilteredSearchTokenizer
;
this
.
tokenizer
=
FilteredSearchTokenizer
;
this
.
dropdownManager
=
new
gl
.
FilteredSearchDropdownManager
(
this
.
dropdownManager
=
new
FilteredSearchDropdownManager
(
this
.
filteredSearchInput
.
getAttribute
(
'
data-base-endpoint
'
)
||
''
,
this
.
filteredSearchInput
.
getAttribute
(
'
data-base-endpoint
'
)
||
''
,
this
.
tokenizer
,
this
.
tokenizer
,
this
.
page
,
this
.
page
,
...
@@ -85,7 +93,6 @@ class FilteredSearchManager {
...
@@ -85,7 +93,6 @@ class FilteredSearchManager {
this
.
bindEvents
();
this
.
bindEvents
();
this
.
loadSearchParamsFromURL
();
this
.
loadSearchParamsFromURL
();
this
.
dropdownManager
.
setDropdown
();
this
.
dropdownManager
.
setDropdown
();
this
.
cleanupWrapper
=
this
.
cleanup
.
bind
(
this
);
this
.
cleanupWrapper
=
this
.
cleanup
.
bind
(
this
);
document
.
addEventListener
(
'
beforeunload
'
,
this
.
cleanupWrapper
);
document
.
addEventListener
(
'
beforeunload
'
,
this
.
cleanupWrapper
);
}
}
...
@@ -197,8 +204,8 @@ class FilteredSearchManager {
...
@@ -197,8 +204,8 @@ class FilteredSearchManager {
// 8 = Backspace Key
// 8 = Backspace Key
// 46 = Delete Key
// 46 = Delete Key
if
(
e
.
keyCode
===
8
||
e
.
keyCode
===
46
)
{
if
(
e
.
keyCode
===
8
||
e
.
keyCode
===
46
)
{
const
{
lastVisualToken
}
=
gl
.
FilteredSearchVisualTokens
.
getLastVisualTokenBeforeInput
();
const
{
lastVisualToken
}
=
FilteredSearchVisualTokens
.
getLastVisualTokenBeforeInput
();
const
{
tokenName
,
tokenValue
}
=
gl
.
DropdownUtils
.
getVisualTokenValues
(
lastVisualToken
);
const
{
tokenName
,
tokenValue
}
=
DropdownUtils
.
getVisualTokenValues
(
lastVisualToken
);
const
canEdit
=
tokenName
&&
this
.
canEdit
&&
this
.
canEdit
(
tokenName
,
tokenValue
);
const
canEdit
=
tokenName
&&
this
.
canEdit
&&
this
.
canEdit
(
tokenName
,
tokenValue
);
if
(
this
.
filteredSearchInput
.
value
===
''
&&
lastVisualToken
&&
canEdit
)
{
if
(
this
.
filteredSearchInput
.
value
===
''
&&
lastVisualToken
&&
canEdit
)
{
...
@@ -206,8 +213,8 @@ class FilteredSearchManager {
...
@@ -206,8 +213,8 @@ class FilteredSearchManager {
if
(
backspaceCount
===
2
)
{
if
(
backspaceCount
===
2
)
{
backspaceCount
=
0
;
backspaceCount
=
0
;
this
.
filteredSearchInput
.
value
=
gl
.
FilteredSearchVisualTokens
.
getLastTokenPartial
();
this
.
filteredSearchInput
.
value
=
FilteredSearchVisualTokens
.
getLastTokenPartial
();
gl
.
FilteredSearchVisualTokens
.
removeLastTokenPartial
();
FilteredSearchVisualTokens
.
removeLastTokenPartial
();
}
}
}
}
...
@@ -275,7 +282,7 @@ class FilteredSearchManager {
...
@@ -275,7 +282,7 @@ class FilteredSearchManager {
e
.
stopImmediatePropagation
();
e
.
stopImmediatePropagation
();
const
button
=
e
.
target
.
closest
(
'
.selectable
'
);
const
button
=
e
.
target
.
closest
(
'
.selectable
'
);
gl
.
FilteredSearchVisualTokens
.
selectToken
(
button
,
true
);
FilteredSearchVisualTokens
.
selectToken
(
button
,
true
);
this
.
removeSelectedToken
();
this
.
removeSelectedToken
();
}
}
}
}
...
@@ -287,7 +294,7 @@ class FilteredSearchManager {
...
@@ -287,7 +294,7 @@ class FilteredSearchManager {
const
isElementTokensContainer
=
e
.
target
.
classList
.
contains
(
'
tokens-container
'
);
const
isElementTokensContainer
=
e
.
target
.
classList
.
contains
(
'
tokens-container
'
);
if
((
!
isElementInFilteredSearch
&&
!
isElementInFilterDropdown
)
||
isElementTokensContainer
)
{
if
((
!
isElementInFilteredSearch
&&
!
isElementInFilterDropdown
)
||
isElementTokensContainer
)
{
gl
.
FilteredSearchVisualTokens
.
moveInputToTheRight
();
FilteredSearchVisualTokens
.
moveInputToTheRight
();
this
.
dropdownManager
.
resetDropdowns
();
this
.
dropdownManager
.
resetDropdowns
();
}
}
}
}
...
@@ -300,13 +307,13 @@ class FilteredSearchManager {
...
@@ -300,13 +307,13 @@ class FilteredSearchManager {
if
(
token
&&
canEdit
)
{
if
(
token
&&
canEdit
)
{
e
.
preventDefault
();
e
.
preventDefault
();
e
.
stopPropagation
();
e
.
stopPropagation
();
gl
.
FilteredSearchVisualTokens
.
editToken
(
token
);
FilteredSearchVisualTokens
.
editToken
(
token
);
this
.
tokenChange
();
this
.
tokenChange
();
}
}
}
}
toggleClearSearchButton
()
{
toggleClearSearchButton
()
{
const
query
=
gl
.
DropdownUtils
.
getSearchQuery
();
const
query
=
DropdownUtils
.
getSearchQuery
();
const
hidden
=
'
hidden
'
;
const
hidden
=
'
hidden
'
;
const
hasHidden
=
this
.
clearSearchButton
.
classList
.
contains
(
hidden
);
const
hasHidden
=
this
.
clearSearchButton
.
classList
.
contains
(
hidden
);
...
@@ -318,7 +325,7 @@ class FilteredSearchManager {
...
@@ -318,7 +325,7 @@ class FilteredSearchManager {
}
}
handleInputPlaceholder
()
{
handleInputPlaceholder
()
{
const
query
=
gl
.
DropdownUtils
.
getSearchQuery
();
const
query
=
DropdownUtils
.
getSearchQuery
();
const
placeholder
=
'
Search or filter results...
'
;
const
placeholder
=
'
Search or filter results...
'
;
const
currentPlaceholder
=
this
.
filteredSearchInput
.
placeholder
;
const
currentPlaceholder
=
this
.
filteredSearchInput
.
placeholder
;
...
@@ -338,7 +345,7 @@ class FilteredSearchManager {
...
@@ -338,7 +345,7 @@ class FilteredSearchManager {
}
}
removeSelectedToken
()
{
removeSelectedToken
()
{
gl
.
FilteredSearchVisualTokens
.
removeSelectedToken
();
FilteredSearchVisualTokens
.
removeSelectedToken
();
this
.
handleInputPlaceholder
();
this
.
handleInputPlaceholder
();
this
.
toggleClearSearchButton
();
this
.
toggleClearSearchButton
();
this
.
dropdownManager
.
updateCurrentDropdownOffset
();
this
.
dropdownManager
.
updateCurrentDropdownOffset
();
...
@@ -358,7 +365,7 @@ class FilteredSearchManager {
...
@@ -358,7 +365,7 @@ class FilteredSearchManager {
let
canClearToken
=
t
.
classList
.
contains
(
'
js-visual-token
'
);
let
canClearToken
=
t
.
classList
.
contains
(
'
js-visual-token
'
);
if
(
canClearToken
)
{
if
(
canClearToken
)
{
const
{
tokenName
,
tokenValue
}
=
gl
.
DropdownUtils
.
getVisualTokenValues
(
t
);
const
{
tokenName
,
tokenValue
}
=
DropdownUtils
.
getVisualTokenValues
(
t
);
canClearToken
=
this
.
canEdit
&&
this
.
canEdit
(
tokenName
,
tokenValue
);
canClearToken
=
this
.
canEdit
&&
this
.
canEdit
(
tokenName
,
tokenValue
);
}
}
...
@@ -386,12 +393,12 @@ class FilteredSearchManager {
...
@@ -386,12 +393,12 @@ class FilteredSearchManager {
const
{
tokens
,
searchToken
}
const
{
tokens
,
searchToken
}
=
this
.
tokenizer
.
processTokens
(
input
.
value
,
this
.
filteredSearchTokenKeys
.
getKeys
());
=
this
.
tokenizer
.
processTokens
(
input
.
value
,
this
.
filteredSearchTokenKeys
.
getKeys
());
const
{
isLastVisualTokenValid
}
const
{
isLastVisualTokenValid
}
=
gl
.
FilteredSearchVisualTokens
.
getLastVisualTokenBeforeInput
();
=
FilteredSearchVisualTokens
.
getLastVisualTokenBeforeInput
();
if
(
isLastVisualTokenValid
)
{
if
(
isLastVisualTokenValid
)
{
tokens
.
forEach
((
t
)
=>
{
tokens
.
forEach
((
t
)
=>
{
input
.
value
=
input
.
value
.
replace
(
`
${
t
.
key
}
:
${
t
.
symbol
}${
t
.
value
}
`
,
''
);
input
.
value
=
input
.
value
.
replace
(
`
${
t
.
key
}
:
${
t
.
symbol
}${
t
.
value
}
`
,
''
);
gl
.
FilteredSearchVisualTokens
.
addFilterVisualToken
(
t
.
key
,
`
${
t
.
symbol
}${
t
.
value
}
`
);
FilteredSearchVisualTokens
.
addFilterVisualToken
(
t
.
key
,
`
${
t
.
symbol
}${
t
.
value
}
`
);
});
});
const
fragments
=
searchToken
.
split
(
'
:
'
);
const
fragments
=
searchToken
.
split
(
'
:
'
);
...
@@ -404,10 +411,10 @@ class FilteredSearchManager {
...
@@ -404,10 +411,10 @@ class FilteredSearchManager {
const
searchTerms
=
inputValues
.
join
(
'
'
);
const
searchTerms
=
inputValues
.
join
(
'
'
);
input
.
value
=
input
.
value
.
replace
(
searchTerms
,
''
);
input
.
value
=
input
.
value
.
replace
(
searchTerms
,
''
);
gl
.
FilteredSearchVisualTokens
.
addSearchVisualToken
(
searchTerms
);
FilteredSearchVisualTokens
.
addSearchVisualToken
(
searchTerms
);
}
}
gl
.
FilteredSearchVisualTokens
.
addFilterVisualToken
(
tokenKey
);
FilteredSearchVisualTokens
.
addFilterVisualToken
(
tokenKey
);
input
.
value
=
input
.
value
.
replace
(
`
${
tokenKey
}
:`
,
''
);
input
.
value
=
input
.
value
.
replace
(
`
${
tokenKey
}
:`
,
''
);
}
}
}
else
{
}
else
{
...
@@ -415,7 +422,7 @@ class FilteredSearchManager {
...
@@ -415,7 +422,7 @@ class FilteredSearchManager {
const
valueCompletedRegex
=
/
([
~%@
]{0,1}
".+"
)
|
([
~%@
]{0,1}
'.+'
)
|^
((?![
~%@
]
'
)(?![
~%@
]
"
)(?!
'
)(?!
"
))
.*/g
;
const
valueCompletedRegex
=
/
([
~%@
]{0,1}
".+"
)
|
([
~%@
]{0,1}
'.+'
)
|^
((?![
~%@
]
'
)(?![
~%@
]
"
)(?!
'
)(?!
"
))
.*/g
;
if
(
searchToken
.
match
(
valueCompletedRegex
)
&&
input
.
value
[
input
.
value
.
length
-
1
]
===
'
'
)
{
if
(
searchToken
.
match
(
valueCompletedRegex
)
&&
input
.
value
[
input
.
value
.
length
-
1
]
===
'
'
)
{
gl
.
FilteredSearchVisualTokens
.
addFilterVisualToken
(
searchToken
);
FilteredSearchVisualTokens
.
addFilterVisualToken
(
searchToken
);
// Trim the last space as seen in the if statement above
// Trim the last space as seen in the if statement above
input
.
value
=
input
.
value
.
replace
(
searchToken
,
''
).
trim
();
input
.
value
=
input
.
value
.
replace
(
searchToken
,
''
).
trim
();
...
@@ -431,7 +438,7 @@ class FilteredSearchManager {
...
@@ -431,7 +438,7 @@ class FilteredSearchManager {
saveCurrentSearchQuery
()
{
saveCurrentSearchQuery
()
{
// Don't save before we have fetched the already saved searches
// Don't save before we have fetched the already saved searches
this
.
fetchingRecentSearchesPromise
.
then
(()
=>
{
this
.
fetchingRecentSearchesPromise
.
then
(()
=>
{
const
searchQuery
=
gl
.
DropdownUtils
.
getSearchQuery
();
const
searchQuery
=
DropdownUtils
.
getSearchQuery
();
if
(
searchQuery
.
length
>
0
)
{
if
(
searchQuery
.
length
>
0
)
{
const
resultantSearches
=
this
.
recentSearchesStore
.
addRecentSearch
(
searchQuery
);
const
resultantSearches
=
this
.
recentSearchesStore
.
addRecentSearch
(
searchQuery
);
this
.
recentSearchesService
.
save
(
resultantSearches
);
this
.
recentSearchesService
.
save
(
resultantSearches
);
...
@@ -447,7 +454,7 @@ class FilteredSearchManager {
...
@@ -447,7 +454,7 @@ class FilteredSearchManager {
}
}
loadSearchParamsFromURL
()
{
loadSearchParamsFromURL
()
{
const
urlParams
=
g
l
.
utils
.
g
etUrlParamsArray
();
const
urlParams
=
getUrlParamsArray
();
const
params
=
this
.
getAllParams
(
urlParams
);
const
params
=
this
.
getAllParams
(
urlParams
);
const
usernameParams
=
this
.
getUsernameParams
();
const
usernameParams
=
this
.
getUsernameParams
();
let
hasFilteredSearch
=
false
;
let
hasFilteredSearch
=
false
;
...
@@ -463,7 +470,7 @@ class FilteredSearchManager {
...
@@ -463,7 +470,7 @@ class FilteredSearchManager {
if
(
condition
)
{
if
(
condition
)
{
hasFilteredSearch
=
true
;
hasFilteredSearch
=
true
;
const
canEdit
=
this
.
canEdit
&&
this
.
canEdit
(
condition
.
tokenKey
);
const
canEdit
=
this
.
canEdit
&&
this
.
canEdit
(
condition
.
tokenKey
);
gl
.
FilteredSearchVisualTokens
.
addFilterVisualToken
(
FilteredSearchVisualTokens
.
addFilterVisualToken
(
condition
.
tokenKey
,
condition
.
tokenKey
,
condition
.
value
,
condition
.
value
,
canEdit
,
canEdit
,
...
@@ -492,7 +499,7 @@ class FilteredSearchManager {
...
@@ -492,7 +499,7 @@ class FilteredSearchManager {
hasFilteredSearch
=
true
;
hasFilteredSearch
=
true
;
const
canEdit
=
this
.
canEdit
&&
this
.
canEdit
(
sanitizedKey
,
sanitizedValue
);
const
canEdit
=
this
.
canEdit
&&
this
.
canEdit
(
sanitizedKey
,
sanitizedValue
);
gl
.
FilteredSearchVisualTokens
.
addFilterVisualToken
(
FilteredSearchVisualTokens
.
addFilterVisualToken
(
sanitizedKey
,
sanitizedKey
,
`
${
symbol
}${
quotationsToUse
}${
sanitizedValue
}${
quotationsToUse
}
`
,
`
${
symbol
}${
quotationsToUse
}${
sanitizedValue
}${
quotationsToUse
}
`
,
canEdit
,
canEdit
,
...
@@ -503,7 +510,7 @@ class FilteredSearchManager {
...
@@ -503,7 +510,7 @@ class FilteredSearchManager {
hasFilteredSearch
=
true
;
hasFilteredSearch
=
true
;
const
tokenName
=
'
assignee
'
;
const
tokenName
=
'
assignee
'
;
const
canEdit
=
this
.
canEdit
&&
this
.
canEdit
(
tokenName
);
const
canEdit
=
this
.
canEdit
&&
this
.
canEdit
(
tokenName
);
gl
.
FilteredSearchVisualTokens
.
addFilterVisualToken
(
tokenName
,
`@
${
usernameParams
[
id
]}
`
,
canEdit
);
FilteredSearchVisualTokens
.
addFilterVisualToken
(
tokenName
,
`@
${
usernameParams
[
id
]}
`
,
canEdit
);
}
}
}
else
if
(
!
match
&&
keyParam
===
'
author_id
'
)
{
}
else
if
(
!
match
&&
keyParam
===
'
author_id
'
)
{
const
id
=
parseInt
(
value
,
10
);
const
id
=
parseInt
(
value
,
10
);
...
@@ -511,7 +518,7 @@ class FilteredSearchManager {
...
@@ -511,7 +518,7 @@ class FilteredSearchManager {
hasFilteredSearch
=
true
;
hasFilteredSearch
=
true
;
const
tokenName
=
'
author
'
;
const
tokenName
=
'
author
'
;
const
canEdit
=
this
.
canEdit
&&
this
.
canEdit
(
tokenName
);
const
canEdit
=
this
.
canEdit
&&
this
.
canEdit
(
tokenName
);
gl
.
FilteredSearchVisualTokens
.
addFilterVisualToken
(
tokenName
,
`@
${
usernameParams
[
id
]}
`
,
canEdit
);
FilteredSearchVisualTokens
.
addFilterVisualToken
(
tokenName
,
`@
${
usernameParams
[
id
]}
`
,
canEdit
);
}
}
}
else
if
(
!
match
&&
keyParam
===
'
search
'
)
{
}
else
if
(
!
match
&&
keyParam
===
'
search
'
)
{
hasFilteredSearch
=
true
;
hasFilteredSearch
=
true
;
...
@@ -543,13 +550,13 @@ class FilteredSearchManager {
...
@@ -543,13 +550,13 @@ class FilteredSearchManager {
search
(
state
=
null
)
{
search
(
state
=
null
)
{
const
paths
=
[];
const
paths
=
[];
const
searchQuery
=
gl
.
DropdownUtils
.
getSearchQuery
();
const
searchQuery
=
DropdownUtils
.
getSearchQuery
();
this
.
saveCurrentSearchQuery
();
this
.
saveCurrentSearchQuery
();
const
{
tokens
,
searchToken
}
const
{
tokens
,
searchToken
}
=
this
.
tokenizer
.
processTokens
(
searchQuery
,
this
.
filteredSearchTokenKeys
.
getKeys
());
=
this
.
tokenizer
.
processTokens
(
searchQuery
,
this
.
filteredSearchTokenKeys
.
getKeys
());
const
currentState
=
state
||
g
l
.
utils
.
g
etParameterByName
(
'
state
'
)
||
'
opened
'
;
const
currentState
=
state
||
getParameterByName
(
'
state
'
)
||
'
opened
'
;
paths
.
push
(
`state=
${
currentState
}
`
);
paths
.
push
(
`state=
${
currentState
}
`
);
tokens
.
forEach
((
token
)
=>
{
tokens
.
forEach
((
token
)
=>
{
...
@@ -628,6 +635,3 @@ class FilteredSearchManager {
...
@@ -628,6 +635,3 @@ class FilteredSearchManager {
return
true
;
return
true
;
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
gl
.
FilteredSearchManager
=
FilteredSearchManager
;
app/assets/javascripts/filtered_search/filtered_search_tokenizer.js
View file @
bd8290d9
import
'
./filtered_search_token_keys
'
;
import
'
./filtered_search_token_keys
'
;
class
FilteredSearchTokenizer
{
export
default
class
FilteredSearchTokenizer
{
static
processTokens
(
input
,
allowedKeys
)
{
static
processTokens
(
input
,
allowedKeys
)
{
// Regex extracts `(token):(symbol)(value)`
// Regex extracts `(token):(symbol)(value)`
// Values that start with a double quote must end in a double quote (same for single)
// Values that start with a double quote must end in a double quote (same for single)
...
@@ -50,6 +50,3 @@ class FilteredSearchTokenizer {
...
@@ -50,6 +50,3 @@ class FilteredSearchTokenizer {
};
};
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
gl
.
FilteredSearchTokenizer
=
FilteredSearchTokenizer
;
app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
View file @
bd8290d9
...
@@ -3,8 +3,9 @@ import AjaxCache from '../lib/utils/ajax_cache';
...
@@ -3,8 +3,9 @@ import AjaxCache from '../lib/utils/ajax_cache';
import
Flash
from
'
../flash
'
;
import
Flash
from
'
../flash
'
;
import
FilteredSearchContainer
from
'
./container
'
;
import
FilteredSearchContainer
from
'
./container
'
;
import
UsersCache
from
'
../lib/utils/users_cache
'
;
import
UsersCache
from
'
../lib/utils/users_cache
'
;
import
DropdownUtils
from
'
./dropdown_utils
'
;
class
FilteredSearchVisualTokens
{
export
default
class
FilteredSearchVisualTokens
{
static
getLastVisualTokenBeforeInput
()
{
static
getLastVisualTokenBeforeInput
()
{
const
inputLi
=
FilteredSearchContainer
.
container
.
querySelector
(
'
.input-token
'
);
const
inputLi
=
FilteredSearchContainer
.
container
.
querySelector
(
'
.input-token
'
);
const
lastVisualToken
=
inputLi
&&
inputLi
.
previousElementSibling
;
const
lastVisualToken
=
inputLi
&&
inputLi
.
previousElementSibling
;
...
@@ -74,7 +75,7 @@ class FilteredSearchVisualTokens {
...
@@ -74,7 +75,7 @@ class FilteredSearchVisualTokens {
let
processed
=
labels
;
let
processed
=
labels
;
if
(
!
labels
.
preprocessed
)
{
if
(
!
labels
.
preprocessed
)
{
processed
=
gl
.
DropdownUtils
.
duplicateLabelPreprocessing
(
labels
);
processed
=
DropdownUtils
.
duplicateLabelPreprocessing
(
labels
);
AjaxCache
.
override
(
labelsEndpoint
,
processed
);
AjaxCache
.
override
(
labelsEndpoint
,
processed
);
processed
.
preprocessed
=
true
;
processed
.
preprocessed
=
true
;
}
}
...
@@ -90,7 +91,7 @@ class FilteredSearchVisualTokens {
...
@@ -90,7 +91,7 @@ class FilteredSearchVisualTokens {
return
AjaxCache
.
retrieve
(
labelsEndpoint
)
return
AjaxCache
.
retrieve
(
labelsEndpoint
)
.
then
(
FilteredSearchVisualTokens
.
preprocessLabel
.
bind
(
null
,
labelsEndpoint
))
.
then
(
FilteredSearchVisualTokens
.
preprocessLabel
.
bind
(
null
,
labelsEndpoint
))
.
then
((
labels
)
=>
{
.
then
((
labels
)
=>
{
const
matchingLabel
=
(
labels
||
[]).
find
(
label
=>
`~
${
gl
.
DropdownUtils
.
getEscapedText
(
label
.
title
)}
`
===
tokenValue
);
const
matchingLabel
=
(
labels
||
[]).
find
(
label
=>
`~
${
DropdownUtils
.
getEscapedText
(
label
.
title
)}
`
===
tokenValue
);
if
(
!
matchingLabel
)
{
if
(
!
matchingLabel
)
{
return
;
return
;
...
@@ -259,11 +260,11 @@ class FilteredSearchVisualTokens {
...
@@ -259,11 +260,11 @@ class FilteredSearchVisualTokens {
static
tokenizeInput
()
{
static
tokenizeInput
()
{
const
input
=
FilteredSearchContainer
.
container
.
querySelector
(
'
.filtered-search
'
);
const
input
=
FilteredSearchContainer
.
container
.
querySelector
(
'
.filtered-search
'
);
const
{
isLastVisualTokenValid
}
=
const
{
isLastVisualTokenValid
}
=
gl
.
FilteredSearchVisualTokens
.
getLastVisualTokenBeforeInput
();
FilteredSearchVisualTokens
.
getLastVisualTokenBeforeInput
();
if
(
input
.
value
)
{
if
(
input
.
value
)
{
if
(
isLastVisualTokenValid
)
{
if
(
isLastVisualTokenValid
)
{
gl
.
FilteredSearchVisualTokens
.
addSearchVisualToken
(
input
.
value
);
FilteredSearchVisualTokens
.
addSearchVisualToken
(
input
.
value
);
}
else
{
}
else
{
FilteredSearchVisualTokens
.
addValueToPreviousVisualTokenElement
(
input
.
value
);
FilteredSearchVisualTokens
.
addValueToPreviousVisualTokenElement
(
input
.
value
);
}
}
...
@@ -324,12 +325,12 @@ class FilteredSearchVisualTokens {
...
@@ -324,12 +325,12 @@ class FilteredSearchVisualTokens {
if
(
!
tokenContainer
.
lastElementChild
.
isEqualNode
(
inputLi
))
{
if
(
!
tokenContainer
.
lastElementChild
.
isEqualNode
(
inputLi
))
{
const
{
isLastVisualTokenValid
}
=
const
{
isLastVisualTokenValid
}
=
gl
.
FilteredSearchVisualTokens
.
getLastVisualTokenBeforeInput
();
FilteredSearchVisualTokens
.
getLastVisualTokenBeforeInput
();
if
(
!
isLastVisualTokenValid
)
{
if
(
!
isLastVisualTokenValid
)
{
const
lastPartial
=
gl
.
FilteredSearchVisualTokens
.
getLastTokenPartial
();
const
lastPartial
=
FilteredSearchVisualTokens
.
getLastTokenPartial
();
gl
.
FilteredSearchVisualTokens
.
removeLastTokenPartial
();
FilteredSearchVisualTokens
.
removeLastTokenPartial
();
gl
.
FilteredSearchVisualTokens
.
addSearchVisualToken
(
lastPartial
);
FilteredSearchVisualTokens
.
addSearchVisualToken
(
lastPartial
);
}
}
tokenContainer
.
removeChild
(
inputLi
);
tokenContainer
.
removeChild
(
inputLi
);
...
@@ -337,6 +338,3 @@ class FilteredSearchVisualTokens {
...
@@ -337,6 +338,3 @@ class FilteredSearchVisualTokens {
}
}
}
}
}
}
window
.
gl
=
window
.
gl
||
{};
gl
.
FilteredSearchVisualTokens
=
FilteredSearchVisualTokens
;
app/assets/javascripts/help/help.js
View file @
bd8290d9
// We will render the icons list here
// We will render the icons list here
if
(
$
(
'
#user-content-gitlab-icons
'
).
length
>
0
)
{
export
default
()
=>
{
if
(
$
(
'
#user-content-gitlab-icons
'
).
length
>
0
)
{
const
$iconsHeader
=
$
(
'
#user-content-gitlab-icons
'
);
const
$iconsHeader
=
$
(
'
#user-content-gitlab-icons
'
);
const
$iconsList
=
$
(
'
<div id="iconsList">ICONS</div>
'
);
const
$iconsList
=
$
(
'
<div id="iconsList">ICONS</div>
'
);
$
(
$iconsList
).
insertAfter
(
$iconsHeader
.
parent
());
$
(
$iconsList
).
insertAfter
(
$iconsHeader
.
parent
());
}
}
};
app/assets/javascripts/pages/dashboard/groups/index/index.js
View file @
bd8290d9
import
initGroupsList
from
'
../../../..
/groups
'
;
import
initGroupsList
from
'
~
/groups
'
;
export
default
()
=>
{
export
default
initGroupsList
;
initGroupsList
();
};
app/assets/javascripts/pages/groups/show/index.js
View file @
bd8290d9
...
@@ -5,7 +5,7 @@ import notificationsDropdown from '~/notifications_dropdown';
...
@@ -5,7 +5,7 @@ import notificationsDropdown from '~/notifications_dropdown';
import
NotificationsForm
from
'
~/notifications_form
'
;
import
NotificationsForm
from
'
~/notifications_form
'
;
import
ProjectsList
from
'
~/projects_list
'
;
import
ProjectsList
from
'
~/projects_list
'
;
import
ShortcutsNavigation
from
'
~/shortcuts_navigation
'
;
import
ShortcutsNavigation
from
'
~/shortcuts_navigation
'
;
import
initGroupsList
from
'
../../..
/groups
'
;
import
initGroupsList
from
'
~
/groups
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
newGroupChildWrapper
=
document
.
querySelector
(
'
.js-new-project-subgroup
'
);
const
newGroupChildWrapper
=
document
.
querySelector
(
'
.js-new-project-subgroup
'
);
...
...
app/assets/javascripts/pages/help/index.js
deleted
100644 → 0
View file @
ace12dd1
import
VersionCheckImage
from
'
../../version_check_image
'
;
export
default
()
=>
VersionCheckImage
.
bindErrorEvent
(
$
(
'
img.js-version-status-badge
'
));
app/assets/javascripts/pages/help/index/index.js
0 → 100644
View file @
bd8290d9
import
VersionCheckImage
from
'
~/version_check_image
'
;
import
docs
from
'
~/docs/docs_bundle
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
docs
();
VersionCheckImage
.
bindErrorEvent
(
$
(
'
img.js-version-status-badge
'
));
});
app/assets/javascripts/pages/help/show/index.js
0 → 100644
View file @
bd8290d9
import
initHelp
from
'
~/help/help
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initHelp
);
app/assets/javascripts/pages/help/ui/index.js
0 → 100644
View file @
bd8290d9
import
initUIKit
from
'
~/ui_development_kit
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initUIKit
);
app/assets/javascripts/pages/import/gitlab_projects/new/index.js
0 → 100644
View file @
bd8290d9
import
initGitLabImportProject
from
'
~/projects/project_import_gitlab_project
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initGitLabImportProject
);
app/assets/javascripts/pages/profiles/accounts/show/index.js
0 → 100644
View file @
bd8290d9
import
initProfileAccount
from
'
~/profile/account
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initProfileAccount
);
app/assets/javascripts/pages/projects/blob/edit/index.js
0 → 100644
View file @
bd8290d9
import
initBlobBundle
from
'
~/blob_edit/blob_bundle
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initBlobBundle
);
app/assets/javascripts/pages/projects/blob/new/index.js
0 → 100644
View file @
bd8290d9
import
initBlobBundle
from
'
~/blob_edit/blob_bundle
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initBlobBundle
);
app/assets/javascripts/pages/projects/init_blob.js
View file @
bd8290d9
...
@@ -3,6 +3,7 @@ import BlobLinePermalinkUpdater from '~/blob/blob_line_permalink_updater';
...
@@ -3,6 +3,7 @@ import BlobLinePermalinkUpdater from '~/blob/blob_line_permalink_updater';
import
ShortcutsNavigation
from
'
~/shortcuts_navigation
'
;
import
ShortcutsNavigation
from
'
~/shortcuts_navigation
'
;
import
ShortcutsBlob
from
'
~/shortcuts_blob
'
;
import
ShortcutsBlob
from
'
~/shortcuts_blob
'
;
import
BlobForkSuggestion
from
'
~/blob/blob_fork_suggestion
'
;
import
BlobForkSuggestion
from
'
~/blob/blob_fork_suggestion
'
;
import
initBlobBundle
from
'
~/blob_edit/blob_bundle
'
;
export
default
()
=>
{
export
default
()
=>
{
new
LineHighlighter
();
// eslint-disable-line no-new
new
LineHighlighter
();
// eslint-disable-line no-new
...
@@ -30,4 +31,6 @@ export default () => {
...
@@ -30,4 +31,6 @@ export default () => {
suggestionSections
:
document
.
querySelectorAll
(
'
.js-file-fork-suggestion-section
'
),
suggestionSections
:
document
.
querySelectorAll
(
'
.js-file-fork-suggestion-section
'
),
actionTextPieces
:
document
.
querySelectorAll
(
'
.js-file-fork-suggestion-section-action
'
),
actionTextPieces
:
document
.
querySelectorAll
(
'
.js-file-fork-suggestion-section-action
'
),
}).
init
();
}).
init
();
initBlobBundle
();
};
};
app/assets/javascripts/pages/projects/tree/show/index.js
View file @
bd8290d9
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
initBlob
from
'
~/blob_edit/blob_bundle
'
;
import
commitPipelineStatus
from
'
~/projects/tree/components/commit_pipeline_status_component.vue
'
;
import
commitPipelineStatus
from
'
~/projects/tree/components/commit_pipeline_status_component.vue
'
;
import
TreeView
from
'
../../../../tree
'
;
import
TreeView
from
'
../../../../tree
'
;
import
ShortcutsNavigation
from
'
../../../../shortcuts_navigation
'
;
import
ShortcutsNavigation
from
'
../../../../shortcuts_navigation
'
;
...
@@ -14,6 +15,7 @@ export default () => {
...
@@ -14,6 +15,7 @@ export default () => {
$
(
'
#tree-slider
'
).
waitForImages
(()
=>
$
(
'
#tree-slider
'
).
waitForImages
(()
=>
ajaxGet
(
document
.
querySelector
(
'
.js-tree-content
'
).
dataset
.
logsPath
));
ajaxGet
(
document
.
querySelector
(
'
.js-tree-content
'
).
dataset
.
logsPath
));
initBlob
();
const
commitPipelineStatusEl
=
document
.
querySelector
(
'
.js-commit-pipeline-status
'
);
const
commitPipelineStatusEl
=
document
.
querySelector
(
'
.js-commit-pipeline-status
'
);
const
statusLink
=
document
.
querySelector
(
'
.commit-actions .ci-status-link
'
);
const
statusLink
=
document
.
querySelector
(
'
.commit-actions .ci-status-link
'
);
if
(
statusLink
!=
null
)
{
if
(
statusLink
!=
null
)
{
...
...
app/assets/javascripts/pages/search/init_filtered_search.js
View file @
bd8290d9
import
'
~/filtered_search/dropdown_emoji
'
;
import
FilteredSearchManager
from
'
~/filtered_search/filtered_search_manager
'
;
import
'
~/filtered_search/dropdown_hint
'
;
import
'
~/filtered_search/dropdown_non_user
'
;
import
'
~/filtered_search/dropdown_user
'
;
import
'
~/filtered_search/dropdown_utils
'
;
import
'
~/filtered_search/filtered_search_dropdown_manager
'
;
import
'
~/filtered_search/filtered_search_dropdown
'
;
import
'
~/filtered_search/filtered_search_manager
'
;
import
'
~/filtered_search/filtered_search_tokenizer
'
;
import
'
~/filtered_search/filtered_search_visual_tokens
'
;
export
default
({
page
})
=>
{
export
default
({
page
})
=>
{
const
filteredSearchEnabled
=
gl
.
FilteredSearchManager
&&
document
.
querySelector
(
'
.filtered-search
'
);
const
filteredSearchEnabled
=
FilteredSearchManager
&&
document
.
querySelector
(
'
.filtered-search
'
);
if
(
filteredSearchEnabled
)
{
if
(
filteredSearchEnabled
)
{
const
filteredSearchManager
=
new
gl
.
FilteredSearchManager
({
page
});
const
filteredSearchManager
=
new
FilteredSearchManager
({
page
});
filteredSearchManager
.
setup
();
filteredSearchManager
.
setup
();
}
}
};
};
app/assets/javascripts/profile/account/index.js
View file @
bd8290d9
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
Translate
from
'
~/vue_shared/translate
'
;
import
Translate
from
'
~/vue_shared/translate
'
;
import
deleteAccountModal
from
'
./components/delete_account_modal.vue
'
;
import
deleteAccountModal
from
'
./components/delete_account_modal.vue
'
;
Vue
.
use
(
Translate
);
export
default
()
=>
{
Vue
.
use
(
Translate
);
const
deleteAccountButton
=
document
.
getElementById
(
'
delete-account-button
'
);
const
deleteAccountButton
=
document
.
getElementById
(
'
delete-account-button
'
);
const
deleteAccountModalEl
=
document
.
getElementById
(
'
delete-account-modal
'
);
const
deleteAccountModalEl
=
document
.
getElementById
(
'
delete-account-modal
'
);
// eslint-disable-next-line no-new
// eslint-disable-next-line no-new
new
Vue
({
new
Vue
({
el
:
deleteAccountModalEl
,
el
:
deleteAccountModalEl
,
components
:
{
components
:
{
deleteAccountModal
,
deleteAccountModal
,
...
@@ -26,4 +25,5 @@ new Vue({
...
@@ -26,4 +25,5 @@ new Vue({
},
},
});
});
},
},
});
});
};
app/assets/javascripts/projects/project_import_gitlab_project.js
View file @
bd8290d9
import
{
getParameterValues
}
from
'
../lib/utils/url_utility
'
;
import
{
getParameterValues
}
from
'
../lib/utils/url_utility
'
;
const
bindEvents
=
()
=>
{
export
default
()
=>
{
const
path
=
getParameterValues
(
'
path
'
)[
0
];
const
path
=
getParameterValues
(
'
path
'
)[
0
];
// get the path url and append it in the inputS
// get the path url and append it in the inputS
$
(
'
.js-path-name
'
).
val
(
path
);
$
(
'
.js-path-name
'
).
val
(
path
);
};
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
bindEvents
);
export
default
{
bindEvents
,
};
app/assets/javascripts/search_autocomplete.js
View file @
bd8290d9
/* eslint-disable no-return-assign, one-var, no-var, no-underscore-dangle, one-var-declaration-per-line, no-unused-vars, no-cond-assign, consistent-return, object-shorthand, prefer-arrow-callback, func-names, space-before-function-paren, prefer-template, quotes, class-methods-use-this, no-sequences, wrap-iife, no-lonely-if, no-else-return, no-param-reassign, vars-on-top, max-len */
/* eslint-disable no-return-assign, one-var, no-var, no-underscore-dangle, one-var-declaration-per-line, no-unused-vars, no-cond-assign, consistent-return, object-shorthand, prefer-arrow-callback, func-names, space-before-function-paren, prefer-template, quotes, class-methods-use-this, no-sequences, wrap-iife, no-lonely-if, no-else-return, no-param-reassign, vars-on-top, max-len */
import
axios
from
'
./lib/utils/axios_utils
'
;
import
axios
from
'
./lib/utils/axios_utils
'
;
import
DropdownUtils
from
'
./filtered_search/dropdown_utils
'
;
import
{
isInGroupsPage
,
isInProjectPage
,
getGroupSlug
,
getProjectSlug
}
from
'
./lib/utils/common_utils
'
;
import
{
isInGroupsPage
,
isInProjectPage
,
getGroupSlug
,
getProjectSlug
}
from
'
./lib/utils/common_utils
'
;
/**
/**
...
...
app/assets/javascripts/ui_development_kit.js
View file @
bd8290d9
import
Api
from
'
./api
'
;
import
Api
from
'
./api
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
export
default
()
=>
{
$
(
'
#js-project-dropdown
'
).
glDropdown
({
$
(
'
#js-project-dropdown
'
).
glDropdown
({
data
:
(
term
,
callback
)
=>
{
data
:
(
term
,
callback
)
=>
{
Api
.
projects
(
term
,
{
Api
.
projects
(
term
,
{
...
@@ -19,4 +19,4 @@ document.addEventListener('DOMContentLoaded', () => {
...
@@ -19,4 +19,4 @@ document.addEventListener('DOMContentLoaded', () => {
id
:
data
=>
data
.
id
,
id
:
data
=>
data
.
id
,
isSelected
:
data
=>
(
data
.
id
===
2
),
isSelected
:
data
=>
(
data
.
id
===
2
),
});
});
}
)
;
};
app/views/groups/issues.html.haml
View file @
bd8290d9
...
@@ -5,7 +5,6 @@
...
@@ -5,7 +5,6 @@
-
content_for
:page_specific_javascripts
do
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
'common_vue'
=
webpack_bundle_tag
'common_vue'
=
webpack_bundle_tag
'filtered_search'
-
if
group_issues_exists
-
if
group_issues_exists
.top-area
.top-area
...
...
app/views/groups/merge_requests.html.haml
View file @
bd8290d9
...
@@ -2,7 +2,6 @@
...
@@ -2,7 +2,6 @@
-
content_for
:page_specific_javascripts
do
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
'common_vue'
=
webpack_bundle_tag
'common_vue'
=
webpack_bundle_tag
'filtered_search'
-
if
@group_merge_requests
.
empty?
-
if
@group_merge_requests
.
empty?
=
render
'shared/empty_states/merge_requests'
,
project_select_button:
true
=
render
'shared/empty_states/merge_requests'
,
project_select_button:
true
...
...
app/views/help/index.html.haml
View file @
bd8290d9
=
webpack_bundle_tag
'docs'
%div
%div
-
if
Gitlab
::
CurrentSettings
.
help_page_text
.
present?
-
if
Gitlab
::
CurrentSettings
.
help_page_text
.
present?
=
markdown_field
(
Gitlab
::
CurrentSettings
.
current_application_settings
,
:help_page_text
)
=
markdown_field
(
Gitlab
::
CurrentSettings
.
current_application_settings
,
:help_page_text
)
...
...
app/views/help/show.html.haml
View file @
bd8290d9
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
'help'
-
page_title
@path
.
split
(
"/"
).
reverse
.
map
(
&
:humanize
)
-
page_title
@path
.
split
(
"/"
).
reverse
.
map
(
&
:humanize
)
.documentation.wiki.prepend-top-default
.documentation.wiki.prepend-top-default
=
markdown
@markdown
=
markdown
@markdown
app/views/import/gitlab_projects/new.html.haml
View file @
bd8290d9
-
page_title
"GitLab Import"
-
page_title
"GitLab Import"
-
header_title
"Projects"
,
root_path
-
header_title
"Projects"
,
root_path
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
'project_import_gl'
%h3
.page-title
%h3
.page-title
=
icon
(
'gitlab'
)
=
icon
(
'gitlab'
)
...
...
app/views/profiles/accounts/show.html.haml
View file @
bd8290d9
...
@@ -102,6 +102,3 @@
...
@@ -102,6 +102,3 @@
%p
%p
=
s_
(
"Profiles|You don't have access to delete this user."
)
=
s_
(
"Profiles|You don't have access to delete this user."
)
.append-bottom-default
.append-bottom-default
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
(
'account'
)
app/views/projects/blob/_upload.html.haml
View file @
bd8290d9
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
.modal-dialog.modal-lg
.modal-dialog.modal-lg
.modal-content
.modal-content
.modal-header
.modal-header
%a
.close
{
href:
"#"
,
"data-dismiss"
=>
"modal"
}
×
%a
.close
{
href:
"#"
,
"data-dismiss"
=>
"modal"
}
×
%h3
.page-title
=
title
%h3
.page-title
=
title
.modal-body
.modal-body
=
form_tag
form_path
,
method:
method
,
class:
'js-quick-submit js-upload-blob-form form-horizontal'
,
data:
{
method:
method
}
do
=
form_tag
form_path
,
method:
method
,
class:
'js-quick-submit js-upload-blob-form form-horizontal'
,
data:
{
method:
method
}
do
...
...
app/views/projects/blob/edit.html.haml
View file @
bd8290d9
...
@@ -3,7 +3,6 @@
...
@@ -3,7 +3,6 @@
-
page_title
"Edit"
,
@blob
.
path
,
@ref
-
page_title
"Edit"
,
@blob
.
path
,
@ref
-
content_for
:page_specific_javascripts
do
-
content_for
:page_specific_javascripts
do
=
page_specific_javascript_tag
(
'lib/ace.js'
)
=
page_specific_javascript_tag
(
'lib/ace.js'
)
=
webpack_bundle_tag
(
'blob'
)
%div
{
class:
container_class
}
%div
{
class:
container_class
}
-
if
@conflict
-
if
@conflict
...
...
app/views/projects/blob/new.html.haml
View file @
bd8290d9
...
@@ -2,7 +2,6 @@
...
@@ -2,7 +2,6 @@
-
page_title
"New File"
,
@path
.
presence
,
@ref
-
page_title
"New File"
,
@path
.
presence
,
@ref
-
content_for
:page_specific_javascripts
do
-
content_for
:page_specific_javascripts
do
=
page_specific_javascript_tag
(
'lib/ace.js'
)
=
page_specific_javascript_tag
(
'lib/ace.js'
)
=
webpack_bundle_tag
(
'blob'
)
.editor-title-row
.editor-title-row
%h3
.page-title.blob-new-page-title
%h3
.page-title.blob-new-page-title
New file
New file
...
...
app/views/projects/blob/show.html.haml
View file @
bd8290d9
...
@@ -3,10 +3,6 @@
...
@@ -3,10 +3,6 @@
-
page_title
@blob
.
path
,
@ref
-
page_title
@blob
.
path
,
@ref
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
'blob'
%div
{
class:
container_class
}
%div
{
class:
container_class
}
=
render
'projects/last_push'
=
render
'projects/last_push'
...
...
app/views/projects/merge_requests/index.html.haml
View file @
bd8290d9
...
@@ -8,7 +8,6 @@
...
@@ -8,7 +8,6 @@
-
content_for
:page_specific_javascripts
do
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
'common_vue'
=
webpack_bundle_tag
'common_vue'
=
webpack_bundle_tag
'filtered_search'
%div
{
class:
container_class
}
%div
{
class:
container_class
}
=
render
'projects/last_push'
=
render
'projects/last_push'
...
...
app/views/shared/boards/_show.html.haml
View file @
bd8290d9
...
@@ -6,7 +6,6 @@
...
@@ -6,7 +6,6 @@
-
content_for
:page_specific_javascripts
do
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
'common_vue'
=
webpack_bundle_tag
'common_vue'
=
webpack_bundle_tag
'filtered_search'
=
webpack_bundle_tag
'boards'
=
webpack_bundle_tag
'boards'
%script
#js-board-template
{
type:
"text/x-template"
}=
render
"shared/boards/components/board"
%script
#js-board-template
{
type:
"text/x-template"
}=
render
"shared/boards/components/board"
...
...
config/karma.config.js
View file @
bd8290d9
config/webpack.config.js
View file @
bd8290d9
...
@@ -48,7 +48,6 @@ var config = {
...
@@ -48,7 +48,6 @@ var config = {
},
},
context
:
path
.
join
(
ROOT_PATH
,
'
app/assets/javascripts
'
),
context
:
path
.
join
(
ROOT_PATH
,
'
app/assets/javascripts
'
),
entry
:
{
entry
:
{
account
:
'
./profile/account/index.js
'
,
balsamiq_viewer
:
'
./blob/balsamiq_viewer.js
'
,
balsamiq_viewer
:
'
./blob/balsamiq_viewer.js
'
,
blob
:
'
./blob_edit/blob_bundle.js
'
,
blob
:
'
./blob_edit/blob_bundle.js
'
,
boards
:
'
./boards/boards_bundle.js
'
,
boards
:
'
./boards/boards_bundle.js
'
,
...
@@ -57,7 +56,6 @@ var config = {
...
@@ -57,7 +56,6 @@ var config = {
cycle_analytics
:
'
./cycle_analytics/cycle_analytics_bundle.js
'
,
cycle_analytics
:
'
./cycle_analytics/cycle_analytics_bundle.js
'
,
commit_pipelines
:
'
./commit/pipelines/pipelines_bundle.js
'
,
commit_pipelines
:
'
./commit/pipelines/pipelines_bundle.js
'
,
deploy_keys
:
'
./deploy_keys/index.js
'
,
deploy_keys
:
'
./deploy_keys/index.js
'
,
docs
:
'
./docs/docs_bundle.js
'
,
diff_notes
:
'
./diff_notes/diff_notes_bundle.js
'
,
diff_notes
:
'
./diff_notes/diff_notes_bundle.js
'
,
environments
:
'
./environments/environments_bundle.js
'
,
environments
:
'
./environments/environments_bundle.js
'
,
environments_folder
:
'
./environments/folder/environments_folder_bundle.js
'
,
environments_folder
:
'
./environments/folder/environments_folder_bundle.js
'
,
...
...
spec/javascripts/filtered_search/dropdown_user_spec.js
View file @
bd8290d9
import
'
~/filtered_search/dropdown_utils
'
;
import
DropdownUtils
from
'
~/filtered_search/dropdown_utils
'
;
import
'
~/filtered_search/filtered_search_tokenizer
'
;
import
DropdownUser
from
'
~/filtered_search/dropdown_user
'
;
import
'
~/filtered_search/filtered_search_dropdown
'
;
import
FilteredSearchTokenizer
from
'
~/filtered_search/filtered_search_tokenizer
'
;
import
'
~/filtered_search/dropdown_user
'
;
import
FilteredSearchTokenKeys
from
'
~/filtered_search/filtered_search_token_keys
'
;
import
FilteredSearchTokenKeys
from
'
~/filtered_search/filtered_search_token_keys
'
;
describe
(
'
Dropdown User
'
,
()
=>
{
describe
(
'
Dropdown User
'
,
()
=>
{
...
@@ -10,18 +8,18 @@ describe('Dropdown User', () => {
...
@@ -10,18 +8,18 @@ describe('Dropdown User', () => {
let
dropdownUser
;
let
dropdownUser
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
spyOn
(
gl
.
DropdownUser
.
prototype
,
'
bindEvents
'
).
and
.
callFake
(()
=>
{});
spyOn
(
DropdownUser
.
prototype
,
'
bindEvents
'
).
and
.
callFake
(()
=>
{});
spyOn
(
gl
.
DropdownUser
.
prototype
,
'
getProjectId
'
).
and
.
callFake
(()
=>
{});
spyOn
(
DropdownUser
.
prototype
,
'
getProjectId
'
).
and
.
callFake
(()
=>
{});
spyOn
(
gl
.
DropdownUser
.
prototype
,
'
getGroupId
'
).
and
.
callFake
(()
=>
{});
spyOn
(
DropdownUser
.
prototype
,
'
getGroupId
'
).
and
.
callFake
(()
=>
{});
spyOn
(
gl
.
DropdownUtils
,
'
getSearchInput
'
).
and
.
callFake
(()
=>
{});
spyOn
(
DropdownUtils
,
'
getSearchInput
'
).
and
.
callFake
(()
=>
{});
dropdownUser
=
new
gl
.
DropdownUser
({
dropdownUser
=
new
DropdownUser
({
tokenKeys
:
FilteredSearchTokenKeys
,
tokenKeys
:
FilteredSearchTokenKeys
,
});
});
});
});
it
(
'
should not return the double quote found in value
'
,
()
=>
{
it
(
'
should not return the double quote found in value
'
,
()
=>
{
spyOn
(
gl
.
FilteredSearchTokenizer
,
'
processTokens
'
).
and
.
returnValue
({
spyOn
(
FilteredSearchTokenizer
,
'
processTokens
'
).
and
.
returnValue
({
lastToken
:
'
"johnny appleseed
'
,
lastToken
:
'
"johnny appleseed
'
,
});
});
...
@@ -29,7 +27,7 @@ describe('Dropdown User', () => {
...
@@ -29,7 +27,7 @@ describe('Dropdown User', () => {
});
});
it
(
'
should not return the single quote found in value
'
,
()
=>
{
it
(
'
should not return the single quote found in value
'
,
()
=>
{
spyOn
(
gl
.
FilteredSearchTokenizer
,
'
processTokens
'
).
and
.
returnValue
({
spyOn
(
FilteredSearchTokenizer
,
'
processTokens
'
).
and
.
returnValue
({
lastToken
:
'
\'
larry boy
'
,
lastToken
:
'
\'
larry boy
'
,
});
});
...
@@ -39,22 +37,22 @@ describe('Dropdown User', () => {
...
@@ -39,22 +37,22 @@ describe('Dropdown User', () => {
describe
(
'
config AjaxFilter
\'
s endpoint
'
,
()
=>
{
describe
(
'
config AjaxFilter
\'
s endpoint
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
spyOn
(
gl
.
DropdownUser
.
prototype
,
'
bindEvents
'
).
and
.
callFake
(()
=>
{});
spyOn
(
DropdownUser
.
prototype
,
'
bindEvents
'
).
and
.
callFake
(()
=>
{});
spyOn
(
gl
.
DropdownUser
.
prototype
,
'
getProjectId
'
).
and
.
callFake
(()
=>
{});
spyOn
(
DropdownUser
.
prototype
,
'
getProjectId
'
).
and
.
callFake
(()
=>
{});
spyOn
(
gl
.
DropdownUser
.
prototype
,
'
getGroupId
'
).
and
.
callFake
(()
=>
{});
spyOn
(
DropdownUser
.
prototype
,
'
getGroupId
'
).
and
.
callFake
(()
=>
{});
});
});
it
(
'
should return endpoint
'
,
()
=>
{
it
(
'
should return endpoint
'
,
()
=>
{
window
.
gon
=
{
window
.
gon
=
{
relative_url_root
:
''
,
relative_url_root
:
''
,
};
};
const
dropdown
=
new
gl
.
DropdownUser
();
const
dropdown
=
new
DropdownUser
();
expect
(
dropdown
.
config
.
AjaxFilter
.
endpoint
).
toBe
(
'
/autocomplete/users.json
'
);
expect
(
dropdown
.
config
.
AjaxFilter
.
endpoint
).
toBe
(
'
/autocomplete/users.json
'
);
});
});
it
(
'
should return endpoint when relative_url_root is undefined
'
,
()
=>
{
it
(
'
should return endpoint when relative_url_root is undefined
'
,
()
=>
{
const
dropdown
=
new
gl
.
DropdownUser
();
const
dropdown
=
new
DropdownUser
();
expect
(
dropdown
.
config
.
AjaxFilter
.
endpoint
).
toBe
(
'
/autocomplete/users.json
'
);
expect
(
dropdown
.
config
.
AjaxFilter
.
endpoint
).
toBe
(
'
/autocomplete/users.json
'
);
});
});
...
@@ -63,7 +61,7 @@ describe('Dropdown User', () => {
...
@@ -63,7 +61,7 @@ describe('Dropdown User', () => {
window
.
gon
=
{
window
.
gon
=
{
relative_url_root
:
'
/gitlab_directory
'
,
relative_url_root
:
'
/gitlab_directory
'
,
};
};
const
dropdown
=
new
gl
.
DropdownUser
();
const
dropdown
=
new
DropdownUser
();
expect
(
dropdown
.
config
.
AjaxFilter
.
endpoint
).
toBe
(
'
/gitlab_directory/autocomplete/users.json
'
);
expect
(
dropdown
.
config
.
AjaxFilter
.
endpoint
).
toBe
(
'
/gitlab_directory/autocomplete/users.json
'
);
});
});
...
@@ -84,7 +82,7 @@ describe('Dropdown User', () => {
...
@@ -84,7 +82,7 @@ describe('Dropdown User', () => {
loadFixtures
(
fixtureTemplate
);
loadFixtures
(
fixtureTemplate
);
authorFilterDropdownElement
=
document
.
querySelector
(
'
#js-dropdown-author
'
);
authorFilterDropdownElement
=
document
.
querySelector
(
'
#js-dropdown-author
'
);
const
dummyInput
=
document
.
createElement
(
'
div
'
);
const
dummyInput
=
document
.
createElement
(
'
div
'
);
dropdown
=
new
gl
.
DropdownUser
({
dropdown
=
new
DropdownUser
({
dropdown
:
authorFilterDropdownElement
,
dropdown
:
authorFilterDropdownElement
,
input
:
dummyInput
,
input
:
dummyInput
,
});
});
...
...
spec/javascripts/filtered_search/dropdown_utils_spec.js
View file @
bd8290d9
import
'
~/filtered_search/dropdown_utils
'
;
import
DropdownUtils
from
'
~/filtered_search/dropdown_utils
'
;
import
'
~/filtered_search/filtered_search_tokenizer
'
;
import
FilteredSearchDropdownManager
from
'
~/filtered_search/filtered_search_dropdown_manager
'
;
import
'
~/filtered_search/filtered_search_dropdown_manager
'
;
import
FilteredSearchTokenKeys
from
'
~/filtered_search/filtered_search_token_keys
'
;
import
FilteredSearchTokenKeys
from
'
~/filtered_search/filtered_search_token_keys
'
;
import
FilteredSearchSpecHelper
from
'
../helpers/filtered_search_spec_helper
'
;
import
FilteredSearchSpecHelper
from
'
../helpers/filtered_search_spec_helper
'
;
...
@@ -10,25 +9,25 @@ describe('Dropdown Utils', () => {
...
@@ -10,25 +9,25 @@ describe('Dropdown Utils', () => {
describe
(
'
getEscapedText
'
,
()
=>
{
describe
(
'
getEscapedText
'
,
()
=>
{
it
(
'
should return same word when it has no space
'
,
()
=>
{
it
(
'
should return same word when it has no space
'
,
()
=>
{
const
escaped
=
gl
.
DropdownUtils
.
getEscapedText
(
'
textWithoutSpace
'
);
const
escaped
=
DropdownUtils
.
getEscapedText
(
'
textWithoutSpace
'
);
expect
(
escaped
).
toBe
(
'
textWithoutSpace
'
);
expect
(
escaped
).
toBe
(
'
textWithoutSpace
'
);
});
});
it
(
'
should escape with double quotes
'
,
()
=>
{
it
(
'
should escape with double quotes
'
,
()
=>
{
let
escaped
=
gl
.
DropdownUtils
.
getEscapedText
(
'
text with space
'
);
let
escaped
=
DropdownUtils
.
getEscapedText
(
'
text with space
'
);
expect
(
escaped
).
toBe
(
'
"text with space"
'
);
expect
(
escaped
).
toBe
(
'
"text with space"
'
);
escaped
=
gl
.
DropdownUtils
.
getEscapedText
(
'
won
\'
t fix
'
);
escaped
=
DropdownUtils
.
getEscapedText
(
'
won
\'
t fix
'
);
expect
(
escaped
).
toBe
(
'
"won
\'
t fix"
'
);
expect
(
escaped
).
toBe
(
'
"won
\'
t fix"
'
);
});
});
it
(
'
should escape with single quotes
'
,
()
=>
{
it
(
'
should escape with single quotes
'
,
()
=>
{
const
escaped
=
gl
.
DropdownUtils
.
getEscapedText
(
'
won"t fix
'
);
const
escaped
=
DropdownUtils
.
getEscapedText
(
'
won"t fix
'
);
expect
(
escaped
).
toBe
(
'
\'
won"t fix
\'
'
);
expect
(
escaped
).
toBe
(
'
\'
won"t fix
\'
'
);
});
});
it
(
'
should escape with single quotes by default
'
,
()
=>
{
it
(
'
should escape with single quotes by default
'
,
()
=>
{
const
escaped
=
gl
.
DropdownUtils
.
getEscapedText
(
'
won"t
\'
fix
'
);
const
escaped
=
DropdownUtils
.
getEscapedText
(
'
won"t
\'
fix
'
);
expect
(
escaped
).
toBe
(
'
\'
won"t
\'
fix
\'
'
);
expect
(
escaped
).
toBe
(
'
\'
won"t
\'
fix
\'
'
);
});
});
});
});
...
@@ -50,14 +49,14 @@ describe('Dropdown Utils', () => {
...
@@ -50,14 +49,14 @@ describe('Dropdown Utils', () => {
it
(
'
should filter without symbol
'
,
()
=>
{
it
(
'
should filter without symbol
'
,
()
=>
{
input
.
value
=
'
roo
'
;
input
.
value
=
'
roo
'
;
const
updatedItem
=
gl
.
DropdownUtils
.
filterWithSymbol
(
'
@
'
,
input
,
item
);
const
updatedItem
=
DropdownUtils
.
filterWithSymbol
(
'
@
'
,
input
,
item
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
});
});
it
(
'
should filter with symbol
'
,
()
=>
{
it
(
'
should filter with symbol
'
,
()
=>
{
input
.
value
=
'
@roo
'
;
input
.
value
=
'
@roo
'
;
const
updatedItem
=
gl
.
DropdownUtils
.
filterWithSymbol
(
'
@
'
,
input
,
item
);
const
updatedItem
=
DropdownUtils
.
filterWithSymbol
(
'
@
'
,
input
,
item
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
});
});
...
@@ -69,56 +68,56 @@ describe('Dropdown Utils', () => {
...
@@ -69,56 +68,56 @@ describe('Dropdown Utils', () => {
it
(
'
should filter with double quote
'
,
()
=>
{
it
(
'
should filter with double quote
'
,
()
=>
{
input
.
value
=
'
"
'
;
input
.
value
=
'
"
'
;
const
updatedItem
=
gl
.
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
const
updatedItem
=
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
});
});
it
(
'
should filter with double quote and symbol
'
,
()
=>
{
it
(
'
should filter with double quote and symbol
'
,
()
=>
{
input
.
value
=
'
~"
'
;
input
.
value
=
'
~"
'
;
const
updatedItem
=
gl
.
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
const
updatedItem
=
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
});
});
it
(
'
should filter with double quote and multiple words
'
,
()
=>
{
it
(
'
should filter with double quote and multiple words
'
,
()
=>
{
input
.
value
=
'
"community con
'
;
input
.
value
=
'
"community con
'
;
const
updatedItem
=
gl
.
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
const
updatedItem
=
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
});
});
it
(
'
should filter with double quote, symbol and multiple words
'
,
()
=>
{
it
(
'
should filter with double quote, symbol and multiple words
'
,
()
=>
{
input
.
value
=
'
~"community con
'
;
input
.
value
=
'
~"community con
'
;
const
updatedItem
=
gl
.
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
const
updatedItem
=
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
});
});
it
(
'
should filter with single quote
'
,
()
=>
{
it
(
'
should filter with single quote
'
,
()
=>
{
input
.
value
=
'
\'
'
;
input
.
value
=
'
\'
'
;
const
updatedItem
=
gl
.
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
const
updatedItem
=
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
});
});
it
(
'
should filter with single quote and symbol
'
,
()
=>
{
it
(
'
should filter with single quote and symbol
'
,
()
=>
{
input
.
value
=
'
~
\'
'
;
input
.
value
=
'
~
\'
'
;
const
updatedItem
=
gl
.
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
const
updatedItem
=
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
});
});
it
(
'
should filter with single quote and multiple words
'
,
()
=>
{
it
(
'
should filter with single quote and multiple words
'
,
()
=>
{
input
.
value
=
'
\'
community con
'
;
input
.
value
=
'
\'
community con
'
;
const
updatedItem
=
gl
.
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
const
updatedItem
=
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
});
});
it
(
'
should filter with single quote, symbol and multiple words
'
,
()
=>
{
it
(
'
should filter with single quote, symbol and multiple words
'
,
()
=>
{
input
.
value
=
'
~
\'
community con
'
;
input
.
value
=
'
~
\'
community con
'
;
const
updatedItem
=
gl
.
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
const
updatedItem
=
DropdownUtils
.
filterWithSymbol
(
'
~
'
,
input
,
multipleWordItem
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
});
});
});
});
...
@@ -150,26 +149,26 @@ describe('Dropdown Utils', () => {
...
@@ -150,26 +149,26 @@ describe('Dropdown Utils', () => {
it
(
'
should filter
'
,
()
=>
{
it
(
'
should filter
'
,
()
=>
{
input
.
value
=
'
l
'
;
input
.
value
=
'
l
'
;
let
updatedItem
=
gl
.
DropdownUtils
.
filterHint
(
config
(),
{
let
updatedItem
=
DropdownUtils
.
filterHint
(
config
(),
{
hint
:
'
label
'
,
hint
:
'
label
'
,
});
});
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
input
.
value
=
'
o
'
;
input
.
value
=
'
o
'
;
updatedItem
=
gl
.
DropdownUtils
.
filterHint
(
config
(),
{
updatedItem
=
DropdownUtils
.
filterHint
(
config
(),
{
hint
:
'
label
'
,
hint
:
'
label
'
,
});
});
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
true
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
true
);
});
});
it
(
'
should return droplab_hidden false when item has no hint
'
,
()
=>
{
it
(
'
should return droplab_hidden false when item has no hint
'
,
()
=>
{
const
updatedItem
=
gl
.
DropdownUtils
.
filterHint
(
config
(),
{},
''
);
const
updatedItem
=
DropdownUtils
.
filterHint
(
config
(),
{},
''
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
false
);
});
});
it
(
'
should allow multiple if item.type is array
'
,
()
=>
{
it
(
'
should allow multiple if item.type is array
'
,
()
=>
{
input
.
value
=
'
label:~first la
'
;
input
.
value
=
'
label:~first la
'
;
const
updatedItem
=
gl
.
DropdownUtils
.
filterHint
(
config
(),
{
const
updatedItem
=
DropdownUtils
.
filterHint
(
config
(),
{
hint
:
'
label
'
,
hint
:
'
label
'
,
type
:
'
array
'
,
type
:
'
array
'
,
});
});
...
@@ -178,12 +177,12 @@ describe('Dropdown Utils', () => {
...
@@ -178,12 +177,12 @@ describe('Dropdown Utils', () => {
it
(
'
should prevent multiple if item.type is not array
'
,
()
=>
{
it
(
'
should prevent multiple if item.type is not array
'
,
()
=>
{
input
.
value
=
'
milestone:~first mile
'
;
input
.
value
=
'
milestone:~first mile
'
;
let
updatedItem
=
gl
.
DropdownUtils
.
filterHint
(
config
(),
{
let
updatedItem
=
DropdownUtils
.
filterHint
(
config
(),
{
hint
:
'
milestone
'
,
hint
:
'
milestone
'
,
});
});
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
true
);
expect
(
updatedItem
.
droplab_hidden
).
toBe
(
true
);
updatedItem
=
gl
.
DropdownUtils
.
filterHint
(
config
(),
{
updatedItem
=
DropdownUtils
.
filterHint
(
config
(),
{
hint
:
'
milestone
'
,
hint
:
'
milestone
'
,
type
:
'
string
'
,
type
:
'
string
'
,
});
});
...
@@ -205,7 +204,7 @@ describe('Dropdown Utils', () => {
...
@@ -205,7 +204,7 @@ describe('Dropdown Utils', () => {
color
:
'
#000000
'
,
color
:
'
#000000
'
,
};
};
const
updated
=
gl
.
DropdownUtils
.
mergeDuplicateLabels
(
dataMap
,
newLabel
);
const
updated
=
DropdownUtils
.
mergeDuplicateLabels
(
dataMap
,
newLabel
);
expect
(
updated
[
newLabel
.
title
]).
toEqual
(
newLabel
);
expect
(
updated
[
newLabel
.
title
]).
toEqual
(
newLabel
);
});
});
...
@@ -215,36 +214,36 @@ describe('Dropdown Utils', () => {
...
@@ -215,36 +214,36 @@ describe('Dropdown Utils', () => {
color
:
'
#000000
'
,
color
:
'
#000000
'
,
};
};
const
updated
=
gl
.
DropdownUtils
.
mergeDuplicateLabels
(
dataMap
,
duplicate
);
const
updated
=
DropdownUtils
.
mergeDuplicateLabels
(
dataMap
,
duplicate
);
expect
(
updated
.
label
.
multipleColors
).
toEqual
([
dataMap
.
label
.
color
,
duplicate
.
color
]);
expect
(
updated
.
label
.
multipleColors
).
toEqual
([
dataMap
.
label
.
color
,
duplicate
.
color
]);
});
});
});
});
describe
(
'
duplicateLabelColor
'
,
()
=>
{
describe
(
'
duplicateLabelColor
'
,
()
=>
{
it
(
'
should linear-gradient 2 colors
'
,
()
=>
{
it
(
'
should linear-gradient 2 colors
'
,
()
=>
{
const
gradient
=
gl
.
DropdownUtils
.
duplicateLabelColor
([
'
#FFFFFF
'
,
'
#000000
'
]);
const
gradient
=
DropdownUtils
.
duplicateLabelColor
([
'
#FFFFFF
'
,
'
#000000
'
]);
expect
(
gradient
).
toEqual
(
'
linear-gradient(#FFFFFF 0%, #FFFFFF 50%, #000000 50%, #000000 100%)
'
);
expect
(
gradient
).
toEqual
(
'
linear-gradient(#FFFFFF 0%, #FFFFFF 50%, #000000 50%, #000000 100%)
'
);
});
});
it
(
'
should linear-gradient 3 colors
'
,
()
=>
{
it
(
'
should linear-gradient 3 colors
'
,
()
=>
{
const
gradient
=
gl
.
DropdownUtils
.
duplicateLabelColor
([
'
#FFFFFF
'
,
'
#000000
'
,
'
#333333
'
]);
const
gradient
=
DropdownUtils
.
duplicateLabelColor
([
'
#FFFFFF
'
,
'
#000000
'
,
'
#333333
'
]);
expect
(
gradient
).
toEqual
(
'
linear-gradient(#FFFFFF 0%, #FFFFFF 33%, #000000 33%, #000000 66%, #333333 66%, #333333 100%)
'
);
expect
(
gradient
).
toEqual
(
'
linear-gradient(#FFFFFF 0%, #FFFFFF 33%, #000000 33%, #000000 66%, #333333 66%, #333333 100%)
'
);
});
});
it
(
'
should linear-gradient 4 colors
'
,
()
=>
{
it
(
'
should linear-gradient 4 colors
'
,
()
=>
{
const
gradient
=
gl
.
DropdownUtils
.
duplicateLabelColor
([
'
#FFFFFF
'
,
'
#000000
'
,
'
#333333
'
,
'
#DDDDDD
'
]);
const
gradient
=
DropdownUtils
.
duplicateLabelColor
([
'
#FFFFFF
'
,
'
#000000
'
,
'
#333333
'
,
'
#DDDDDD
'
]);
expect
(
gradient
).
toEqual
(
'
linear-gradient(#FFFFFF 0%, #FFFFFF 25%, #000000 25%, #000000 50%, #333333 50%, #333333 75%, #DDDDDD 75%, #DDDDDD 100%)
'
);
expect
(
gradient
).
toEqual
(
'
linear-gradient(#FFFFFF 0%, #FFFFFF 25%, #000000 25%, #000000 50%, #333333 50%, #333333 75%, #DDDDDD 75%, #DDDDDD 100%)
'
);
});
});
it
(
'
should not linear-gradient more than 4 colors
'
,
()
=>
{
it
(
'
should not linear-gradient more than 4 colors
'
,
()
=>
{
const
gradient
=
gl
.
DropdownUtils
.
duplicateLabelColor
([
'
#FFFFFF
'
,
'
#000000
'
,
'
#333333
'
,
'
#DDDDDD
'
,
'
#EEEEEE
'
]);
const
gradient
=
DropdownUtils
.
duplicateLabelColor
([
'
#FFFFFF
'
,
'
#000000
'
,
'
#333333
'
,
'
#DDDDDD
'
,
'
#EEEEEE
'
]);
expect
(
gradient
.
indexOf
(
'
#EEEEEE
'
)
===
-
1
).
toEqual
(
true
);
expect
(
gradient
.
indexOf
(
'
#EEEEEE
'
)
===
-
1
).
toEqual
(
true
);
});
});
});
});
describe
(
'
duplicateLabelPreprocessing
'
,
()
=>
{
describe
(
'
duplicateLabelPreprocessing
'
,
()
=>
{
it
(
'
should set preprocessed to true
'
,
()
=>
{
it
(
'
should set preprocessed to true
'
,
()
=>
{
const
results
=
gl
.
DropdownUtils
.
duplicateLabelPreprocessing
([]);
const
results
=
DropdownUtils
.
duplicateLabelPreprocessing
([]);
expect
(
results
.
preprocessed
).
toEqual
(
true
);
expect
(
results
.
preprocessed
).
toEqual
(
true
);
});
});
...
@@ -256,7 +255,7 @@ describe('Dropdown Utils', () => {
...
@@ -256,7 +255,7 @@ describe('Dropdown Utils', () => {
title
:
'
label2
'
,
title
:
'
label2
'
,
color
:
'
#000000
'
,
color
:
'
#000000
'
,
}];
}];
const
results
=
gl
.
DropdownUtils
.
duplicateLabelPreprocessing
(
data
);
const
results
=
DropdownUtils
.
duplicateLabelPreprocessing
(
data
);
expect
(
results
.
length
).
toEqual
(
2
);
expect
(
results
.
length
).
toEqual
(
2
);
expect
(
results
[
0
]).
toEqual
(
data
[
0
]);
expect
(
results
[
0
]).
toEqual
(
data
[
0
]);
...
@@ -271,14 +270,14 @@ describe('Dropdown Utils', () => {
...
@@ -271,14 +270,14 @@ describe('Dropdown Utils', () => {
title
:
'
label
'
,
title
:
'
label
'
,
color
:
'
#000000
'
,
color
:
'
#000000
'
,
}];
}];
const
results
=
gl
.
DropdownUtils
.
duplicateLabelPreprocessing
(
data
);
const
results
=
DropdownUtils
.
duplicateLabelPreprocessing
(
data
);
it
(
'
should merge duplicate labels
'
,
()
=>
{
it
(
'
should merge duplicate labels
'
,
()
=>
{
expect
(
results
.
length
).
toEqual
(
1
);
expect
(
results
.
length
).
toEqual
(
1
);
});
});
it
(
'
should convert multiple colored labels into linear-gradient
'
,
()
=>
{
it
(
'
should convert multiple colored labels into linear-gradient
'
,
()
=>
{
expect
(
results
[
0
].
color
).
toEqual
(
gl
.
DropdownUtils
.
duplicateLabelColor
([
'
#FFFFFF
'
,
'
#000000
'
]));
expect
(
results
[
0
].
color
).
toEqual
(
DropdownUtils
.
duplicateLabelColor
([
'
#FFFFFF
'
,
'
#000000
'
]));
});
});
it
(
'
should set multiple colored label text color to black
'
,
()
=>
{
it
(
'
should set multiple colored label text color to black
'
,
()
=>
{
...
@@ -289,7 +288,7 @@ describe('Dropdown Utils', () => {
...
@@ -289,7 +288,7 @@ describe('Dropdown Utils', () => {
describe
(
'
setDataValueIfSelected
'
,
()
=>
{
describe
(
'
setDataValueIfSelected
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
spyOn
(
gl
.
FilteredSearchDropdownManager
,
'
addWordToInput
'
)
spyOn
(
FilteredSearchDropdownManager
,
'
addWordToInput
'
)
.
and
.
callFake
(()
=>
{});
.
and
.
callFake
(()
=>
{});
});
});
...
@@ -298,8 +297,8 @@ describe('Dropdown Utils', () => {
...
@@ -298,8 +297,8 @@ describe('Dropdown Utils', () => {
getAttribute
:
()
=>
'
value
'
,
getAttribute
:
()
=>
'
value
'
,
};
};
gl
.
DropdownUtils
.
setDataValueIfSelected
(
null
,
selected
);
DropdownUtils
.
setDataValueIfSelected
(
null
,
selected
);
expect
(
gl
.
FilteredSearchDropdownManager
.
addWordToInput
.
calls
.
count
()).
toEqual
(
1
);
expect
(
FilteredSearchDropdownManager
.
addWordToInput
.
calls
.
count
()).
toEqual
(
1
);
});
});
it
(
'
returns true when dataValue exists
'
,
()
=>
{
it
(
'
returns true when dataValue exists
'
,
()
=>
{
...
@@ -307,7 +306,7 @@ describe('Dropdown Utils', () => {
...
@@ -307,7 +306,7 @@ describe('Dropdown Utils', () => {
getAttribute
:
()
=>
'
value
'
,
getAttribute
:
()
=>
'
value
'
,
};
};
const
result
=
gl
.
DropdownUtils
.
setDataValueIfSelected
(
null
,
selected
);
const
result
=
DropdownUtils
.
setDataValueIfSelected
(
null
,
selected
);
expect
(
result
).
toBe
(
true
);
expect
(
result
).
toBe
(
true
);
});
});
...
@@ -316,7 +315,7 @@ describe('Dropdown Utils', () => {
...
@@ -316,7 +315,7 @@ describe('Dropdown Utils', () => {
getAttribute
:
()
=>
null
,
getAttribute
:
()
=>
null
,
};
};
const
result
=
gl
.
DropdownUtils
.
setDataValueIfSelected
(
null
,
selected
);
const
result
=
DropdownUtils
.
setDataValueIfSelected
(
null
,
selected
);
expect
(
result
).
toBe
(
false
);
expect
(
result
).
toBe
(
false
);
});
});
});
});
...
@@ -326,7 +325,7 @@ describe('Dropdown Utils', () => {
...
@@ -326,7 +325,7 @@ describe('Dropdown Utils', () => {
const
value
=
'
label:none
'
;
const
value
=
'
label:none
'
;
it
(
'
should return selectionStart when cursor is at the trailing space
'
,
()
=>
{
it
(
'
should return selectionStart when cursor is at the trailing space
'
,
()
=>
{
const
{
left
,
right
}
=
gl
.
DropdownUtils
.
getInputSelectionPosition
({
const
{
left
,
right
}
=
DropdownUtils
.
getInputSelectionPosition
({
selectionStart
:
11
,
selectionStart
:
11
,
value
,
value
,
});
});
...
@@ -336,7 +335,7 @@ describe('Dropdown Utils', () => {
...
@@ -336,7 +335,7 @@ describe('Dropdown Utils', () => {
});
});
it
(
'
should return input when cursor is at the start of input
'
,
()
=>
{
it
(
'
should return input when cursor is at the start of input
'
,
()
=>
{
const
{
left
,
right
}
=
gl
.
DropdownUtils
.
getInputSelectionPosition
({
const
{
left
,
right
}
=
DropdownUtils
.
getInputSelectionPosition
({
selectionStart
:
0
,
selectionStart
:
0
,
value
,
value
,
});
});
...
@@ -346,7 +345,7 @@ describe('Dropdown Utils', () => {
...
@@ -346,7 +345,7 @@ describe('Dropdown Utils', () => {
});
});
it
(
'
should return input when cursor is at the middle of input
'
,
()
=>
{
it
(
'
should return input when cursor is at the middle of input
'
,
()
=>
{
const
{
left
,
right
}
=
gl
.
DropdownUtils
.
getInputSelectionPosition
({
const
{
left
,
right
}
=
DropdownUtils
.
getInputSelectionPosition
({
selectionStart
:
7
,
selectionStart
:
7
,
value
,
value
,
});
});
...
@@ -356,7 +355,7 @@ describe('Dropdown Utils', () => {
...
@@ -356,7 +355,7 @@ describe('Dropdown Utils', () => {
});
});
it
(
'
should return input when cursor is at the end of input
'
,
()
=>
{
it
(
'
should return input when cursor is at the end of input
'
,
()
=>
{
const
{
left
,
right
}
=
gl
.
DropdownUtils
.
getInputSelectionPosition
({
const
{
left
,
right
}
=
DropdownUtils
.
getInputSelectionPosition
({
selectionStart
:
10
,
selectionStart
:
10
,
value
,
value
,
});
});
...
@@ -370,7 +369,7 @@ describe('Dropdown Utils', () => {
...
@@ -370,7 +369,7 @@ describe('Dropdown Utils', () => {
const
value
=
'
label:~"Community Contribution"
'
;
const
value
=
'
label:~"Community Contribution"
'
;
it
(
'
should return input when cursor is after the first word
'
,
()
=>
{
it
(
'
should return input when cursor is after the first word
'
,
()
=>
{
const
{
left
,
right
}
=
gl
.
DropdownUtils
.
getInputSelectionPosition
({
const
{
left
,
right
}
=
DropdownUtils
.
getInputSelectionPosition
({
selectionStart
:
17
,
selectionStart
:
17
,
value
,
value
,
});
});
...
@@ -380,7 +379,7 @@ describe('Dropdown Utils', () => {
...
@@ -380,7 +379,7 @@ describe('Dropdown Utils', () => {
});
});
it
(
'
should return input when cursor is before the second word
'
,
()
=>
{
it
(
'
should return input when cursor is before the second word
'
,
()
=>
{
const
{
left
,
right
}
=
gl
.
DropdownUtils
.
getInputSelectionPosition
({
const
{
left
,
right
}
=
DropdownUtils
.
getInputSelectionPosition
({
selectionStart
:
18
,
selectionStart
:
18
,
value
,
value
,
});
});
...
@@ -394,7 +393,7 @@ describe('Dropdown Utils', () => {
...
@@ -394,7 +393,7 @@ describe('Dropdown Utils', () => {
const
value
=
'
label:~"Community Contribution
'
;
const
value
=
'
label:~"Community Contribution
'
;
it
(
'
should return entire input when cursor is at the start of input
'
,
()
=>
{
it
(
'
should return entire input when cursor is at the start of input
'
,
()
=>
{
const
{
left
,
right
}
=
gl
.
DropdownUtils
.
getInputSelectionPosition
({
const
{
left
,
right
}
=
DropdownUtils
.
getInputSelectionPosition
({
selectionStart
:
0
,
selectionStart
:
0
,
value
,
value
,
});
});
...
@@ -404,7 +403,7 @@ describe('Dropdown Utils', () => {
...
@@ -404,7 +403,7 @@ describe('Dropdown Utils', () => {
});
});
it
(
'
should return entire input when cursor is at the end of input
'
,
()
=>
{
it
(
'
should return entire input when cursor is at the end of input
'
,
()
=>
{
const
{
left
,
right
}
=
gl
.
DropdownUtils
.
getInputSelectionPosition
({
const
{
left
,
right
}
=
DropdownUtils
.
getInputSelectionPosition
({
selectionStart
:
30
,
selectionStart
:
30
,
value
,
value
,
});
});
...
@@ -434,7 +433,7 @@ describe('Dropdown Utils', () => {
...
@@ -434,7 +433,7 @@ describe('Dropdown Utils', () => {
const
valueContainer
=
authorToken
.
querySelector
(
'
.value-container
'
);
const
valueContainer
=
authorToken
.
querySelector
(
'
.value-container
'
);
valueContainer
.
dataset
.
originalValue
=
originalValue
;
valueContainer
.
dataset
.
originalValue
=
originalValue
;
const
searchQuery
=
gl
.
DropdownUtils
.
getSearchQuery
();
const
searchQuery
=
DropdownUtils
.
getSearchQuery
();
expect
(
searchQuery
).
toBe
(
'
search term author:original dance
'
);
expect
(
searchQuery
).
toBe
(
'
search term author:original dance
'
);
});
});
...
...
spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
View file @
bd8290d9
import
'
~/filtered_search/filtered_search_visual_tokens
'
;
import
FilteredSearchDropdownManager
from
'
~/filtered_search/filtered_search_dropdown_manager
'
;
import
'
~/filtered_search/filtered_search_tokenizer
'
;
import
'
~/filtered_search/filtered_search_dropdown_manager
'
;
describe
(
'
Filtered Search Dropdown Manager
'
,
()
=>
{
describe
(
'
Filtered Search Dropdown Manager
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
...
@@ -28,7 +26,7 @@ describe('Filtered Search Dropdown Manager', () => {
...
@@ -28,7 +26,7 @@ describe('Filtered Search Dropdown Manager', () => {
describe
(
'
input has no existing value
'
,
()
=>
{
describe
(
'
input has no existing value
'
,
()
=>
{
it
(
'
should add just tokenName
'
,
()
=>
{
it
(
'
should add just tokenName
'
,
()
=>
{
gl
.
FilteredSearchDropdownManager
.
addWordToInput
(
'
milestone
'
);
FilteredSearchDropdownManager
.
addWordToInput
(
'
milestone
'
);
const
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
const
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
...
@@ -38,7 +36,7 @@ describe('Filtered Search Dropdown Manager', () => {
...
@@ -38,7 +36,7 @@ describe('Filtered Search Dropdown Manager', () => {
});
});
it
(
'
should add tokenName and tokenValue
'
,
()
=>
{
it
(
'
should add tokenName and tokenValue
'
,
()
=>
{
gl
.
FilteredSearchDropdownManager
.
addWordToInput
(
'
label
'
);
FilteredSearchDropdownManager
.
addWordToInput
(
'
label
'
);
let
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
let
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
...
@@ -46,9 +44,9 @@ describe('Filtered Search Dropdown Manager', () => {
...
@@ -46,9 +44,9 @@ describe('Filtered Search Dropdown Manager', () => {
expect
(
token
.
querySelector
(
'
.name
'
).
innerText
).
toBe
(
'
label
'
);
expect
(
token
.
querySelector
(
'
.name
'
).
innerText
).
toBe
(
'
label
'
);
expect
(
getInputValue
()).
toBe
(
''
);
expect
(
getInputValue
()).
toBe
(
''
);
gl
.
FilteredSearchDropdownManager
.
addWordToInput
(
'
label
'
,
'
none
'
);
FilteredSearchDropdownManager
.
addWordToInput
(
'
label
'
,
'
none
'
);
// We have to get that reference again
// We have to get that reference again
// Because
gl.
FilteredSearchDropdownManager deletes the previous token
// Because FilteredSearchDropdownManager deletes the previous token
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
expect
(
token
.
classList
.
contains
(
'
filtered-search-token
'
)).
toEqual
(
true
);
expect
(
token
.
classList
.
contains
(
'
filtered-search-token
'
)).
toEqual
(
true
);
...
@@ -61,7 +59,7 @@ describe('Filtered Search Dropdown Manager', () => {
...
@@ -61,7 +59,7 @@ describe('Filtered Search Dropdown Manager', () => {
describe
(
'
input has existing value
'
,
()
=>
{
describe
(
'
input has existing value
'
,
()
=>
{
it
(
'
should be able to just add tokenName
'
,
()
=>
{
it
(
'
should be able to just add tokenName
'
,
()
=>
{
setInputValue
(
'
a
'
);
setInputValue
(
'
a
'
);
gl
.
FilteredSearchDropdownManager
.
addWordToInput
(
'
author
'
);
FilteredSearchDropdownManager
.
addWordToInput
(
'
author
'
);
const
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
const
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
...
@@ -71,10 +69,10 @@ describe('Filtered Search Dropdown Manager', () => {
...
@@ -71,10 +69,10 @@ describe('Filtered Search Dropdown Manager', () => {
});
});
it
(
'
should replace tokenValue
'
,
()
=>
{
it
(
'
should replace tokenValue
'
,
()
=>
{
gl
.
FilteredSearchDropdownManager
.
addWordToInput
(
'
author
'
);
FilteredSearchDropdownManager
.
addWordToInput
(
'
author
'
);
setInputValue
(
'
roo
'
);
setInputValue
(
'
roo
'
);
gl
.
FilteredSearchDropdownManager
.
addWordToInput
(
null
,
'
@root
'
);
FilteredSearchDropdownManager
.
addWordToInput
(
null
,
'
@root
'
);
const
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
const
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
...
@@ -85,10 +83,10 @@ describe('Filtered Search Dropdown Manager', () => {
...
@@ -85,10 +83,10 @@ describe('Filtered Search Dropdown Manager', () => {
});
});
it
(
'
should add tokenValues containing spaces
'
,
()
=>
{
it
(
'
should add tokenValues containing spaces
'
,
()
=>
{
gl
.
FilteredSearchDropdownManager
.
addWordToInput
(
'
label
'
);
FilteredSearchDropdownManager
.
addWordToInput
(
'
label
'
);
setInputValue
(
'
"test
'
);
setInputValue
(
'
"test
'
);
gl
.
FilteredSearchDropdownManager
.
addWordToInput
(
'
label
'
,
'
~
\'
"test me"
\'
'
);
FilteredSearchDropdownManager
.
addWordToInput
(
'
label
'
,
'
~
\'
"test me"
\'
'
);
const
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
const
token
=
document
.
querySelector
(
'
.tokens-container .js-visual-token
'
);
...
...
spec/javascripts/filtered_search/filtered_search_manager_spec.js
View file @
bd8290d9
...
@@ -5,9 +5,10 @@ import RecentSearchesServiceError from '~/filtered_search/services/recent_search
...
@@ -5,9 +5,10 @@ import RecentSearchesServiceError from '~/filtered_search/services/recent_search
import
RecentSearchesRoot
from
'
~/filtered_search/recent_searches_root
'
;
import
RecentSearchesRoot
from
'
~/filtered_search/recent_searches_root
'
;
import
FilteredSearchTokenKeys
from
'
~/filtered_search/filtered_search_token_keys
'
;
import
FilteredSearchTokenKeys
from
'
~/filtered_search/filtered_search_token_keys
'
;
import
'
~/lib/utils/common_utils
'
;
import
'
~/lib/utils/common_utils
'
;
import
'
~/filtered_search/filtered_search_tokenizer
'
;
import
DropdownUtils
from
'
~/filtered_search/dropdown_utils
'
;
import
'
~/filtered_search/filtered_search_dropdown_manager
'
;
import
FilteredSearchVisualTokens
from
'
~/filtered_search/filtered_search_visual_tokens
'
;
import
'
~/filtered_search/filtered_search_manager
'
;
import
FilteredSearchDropdownManager
from
'
~/filtered_search/filtered_search_dropdown_manager
'
;
import
FilteredSearchManager
from
'
~/filtered_search/filtered_search_manager
'
;
import
FilteredSearchSpecHelper
from
'
../helpers/filtered_search_spec_helper
'
;
import
FilteredSearchSpecHelper
from
'
../helpers/filtered_search_spec_helper
'
;
describe
(
'
Filtered Search Manager
'
,
()
=>
{
describe
(
'
Filtered Search Manager
'
,
()
=>
{
...
@@ -49,21 +50,21 @@ describe('Filtered Search Manager', () => {
...
@@ -49,21 +50,21 @@ describe('Filtered Search Manager', () => {
</div>
</div>
`
);
`
);
spyOn
(
gl
.
FilteredSearchDropdownManager
.
prototype
,
'
setDropdown
'
).
and
.
callFake
(()
=>
{});
spyOn
(
FilteredSearchDropdownManager
.
prototype
,
'
setDropdown
'
).
and
.
callFake
(()
=>
{});
});
});
const
initializeManager
=
()
=>
{
const
initializeManager
=
()
=>
{
/* eslint-disable jasmine/no-unsafe-spy */
/* eslint-disable jasmine/no-unsafe-spy */
spyOn
(
gl
.
FilteredSearchManager
.
prototype
,
'
loadSearchParamsFromURL
'
).
and
.
callFake
(()
=>
{});
spyOn
(
FilteredSearchManager
.
prototype
,
'
loadSearchParamsFromURL
'
).
and
.
callFake
(()
=>
{});
spyOn
(
gl
.
FilteredSearchManager
.
prototype
,
'
tokenChange
'
).
and
.
callFake
(()
=>
{});
spyOn
(
FilteredSearchManager
.
prototype
,
'
tokenChange
'
).
and
.
callFake
(()
=>
{});
spyOn
(
gl
.
FilteredSearchDropdownManager
.
prototype
,
'
updateDropdownOffset
'
).
and
.
callFake
(()
=>
{});
spyOn
(
FilteredSearchDropdownManager
.
prototype
,
'
updateDropdownOffset
'
).
and
.
callFake
(()
=>
{});
spyOn
(
gl
.
utils
,
'
getParameterByName
'
).
and
.
returnValue
(
null
);
spyOn
(
gl
.
utils
,
'
getParameterByName
'
).
and
.
returnValue
(
null
);
spyOn
(
gl
.
FilteredSearchVisualTokens
,
'
unselectTokens
'
).
and
.
callThrough
();
spyOn
(
FilteredSearchVisualTokens
,
'
unselectTokens
'
).
and
.
callThrough
();
/* eslint-enable jasmine/no-unsafe-spy */
/* eslint-enable jasmine/no-unsafe-spy */
input
=
document
.
querySelector
(
'
.filtered-search
'
);
input
=
document
.
querySelector
(
'
.filtered-search
'
);
tokensContainer
=
document
.
querySelector
(
'
.tokens-container
'
);
tokensContainer
=
document
.
querySelector
(
'
.tokens-container
'
);
manager
=
new
gl
.
FilteredSearchManager
({
page
});
manager
=
new
FilteredSearchManager
({
page
});
manager
.
setup
();
manager
.
setup
();
};
};
...
@@ -81,7 +82,7 @@ describe('Filtered Search Manager', () => {
...
@@ -81,7 +82,7 @@ describe('Filtered Search Manager', () => {
});
});
it
(
'
should instantiate RecentSearchesStore with isLocalStorageAvailable
'
,
()
=>
{
it
(
'
should instantiate RecentSearchesStore with isLocalStorageAvailable
'
,
()
=>
{
manager
=
new
gl
.
FilteredSearchManager
({
page
});
manager
=
new
FilteredSearchManager
({
page
});
expect
(
RecentSearchesService
.
isAvailable
).
toHaveBeenCalled
();
expect
(
RecentSearchesService
.
isAvailable
).
toHaveBeenCalled
();
expect
(
recentSearchesStoreSrc
.
default
).
toHaveBeenCalledWith
({
expect
(
recentSearchesStoreSrc
.
default
).
toHaveBeenCalledWith
({
...
@@ -93,7 +94,7 @@ describe('Filtered Search Manager', () => {
...
@@ -93,7 +94,7 @@ describe('Filtered Search Manager', () => {
describe
(
'
setup
'
,
()
=>
{
describe
(
'
setup
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
manager
=
new
gl
.
FilteredSearchManager
({
page
});
manager
=
new
FilteredSearchManager
({
page
});
});
});
it
(
'
should not instantiate Flash if an RecentSearchesServiceError is caught
'
,
()
=>
{
it
(
'
should not instantiate Flash if an RecentSearchesServiceError is caught
'
,
()
=>
{
...
@@ -108,7 +109,7 @@ describe('Filtered Search Manager', () => {
...
@@ -108,7 +109,7 @@ describe('Filtered Search Manager', () => {
describe
(
'
searchState
'
,
()
=>
{
describe
(
'
searchState
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
spyOn
(
gl
.
FilteredSearchManager
.
prototype
,
'
search
'
).
and
.
callFake
(()
=>
{});
spyOn
(
FilteredSearchManager
.
prototype
,
'
search
'
).
and
.
callFake
(()
=>
{});
initializeManager
();
initializeManager
();
});
});
...
@@ -134,7 +135,7 @@ describe('Filtered Search Manager', () => {
...
@@ -134,7 +135,7 @@ describe('Filtered Search Manager', () => {
};
};
manager
.
searchState
(
e
);
manager
.
searchState
(
e
);
expect
(
gl
.
FilteredSearchManager
.
prototype
.
search
).
not
.
toHaveBeenCalled
();
expect
(
FilteredSearchManager
.
prototype
.
search
).
not
.
toHaveBeenCalled
();
});
});
it
(
'
should call search when there is state
'
,
()
=>
{
it
(
'
should call search when there is state
'
,
()
=>
{
...
@@ -149,7 +150,7 @@ describe('Filtered Search Manager', () => {
...
@@ -149,7 +150,7 @@ describe('Filtered Search Manager', () => {
};
};
manager
.
searchState
(
e
);
manager
.
searchState
(
e
);
expect
(
gl
.
FilteredSearchManager
.
prototype
.
search
).
toHaveBeenCalledWith
(
'
opened
'
);
expect
(
FilteredSearchManager
.
prototype
.
search
).
toHaveBeenCalledWith
(
'
opened
'
);
});
});
});
});
...
@@ -251,44 +252,44 @@ describe('Filtered Search Manager', () => {
...
@@ -251,44 +252,44 @@ describe('Filtered Search Manager', () => {
});
});
it
(
'
removes last token
'
,
()
=>
{
it
(
'
removes last token
'
,
()
=>
{
spyOn
(
gl
.
FilteredSearchVisualTokens
,
'
removeLastTokenPartial
'
).
and
.
callThrough
();
spyOn
(
FilteredSearchVisualTokens
,
'
removeLastTokenPartial
'
).
and
.
callThrough
();
dispatchBackspaceEvent
(
input
,
'
keyup
'
);
dispatchBackspaceEvent
(
input
,
'
keyup
'
);
dispatchBackspaceEvent
(
input
,
'
keyup
'
);
dispatchBackspaceEvent
(
input
,
'
keyup
'
);
expect
(
gl
.
FilteredSearchVisualTokens
.
removeLastTokenPartial
).
toHaveBeenCalled
();
expect
(
FilteredSearchVisualTokens
.
removeLastTokenPartial
).
toHaveBeenCalled
();
});
});
it
(
'
sets the input
'
,
()
=>
{
it
(
'
sets the input
'
,
()
=>
{
spyOn
(
gl
.
FilteredSearchVisualTokens
,
'
getLastTokenPartial
'
).
and
.
callThrough
();
spyOn
(
FilteredSearchVisualTokens
,
'
getLastTokenPartial
'
).
and
.
callThrough
();
dispatchDeleteEvent
(
input
,
'
keyup
'
);
dispatchDeleteEvent
(
input
,
'
keyup
'
);
dispatchDeleteEvent
(
input
,
'
keyup
'
);
dispatchDeleteEvent
(
input
,
'
keyup
'
);
expect
(
gl
.
FilteredSearchVisualTokens
.
getLastTokenPartial
).
toHaveBeenCalled
();
expect
(
FilteredSearchVisualTokens
.
getLastTokenPartial
).
toHaveBeenCalled
();
expect
(
input
.
value
).
toEqual
(
'
~bug
'
);
expect
(
input
.
value
).
toEqual
(
'
~bug
'
);
});
});
});
});
it
(
'
does not remove token or change input when there is existing input
'
,
()
=>
{
it
(
'
does not remove token or change input when there is existing input
'
,
()
=>
{
spyOn
(
gl
.
FilteredSearchVisualTokens
,
'
removeLastTokenPartial
'
).
and
.
callThrough
();
spyOn
(
FilteredSearchVisualTokens
,
'
removeLastTokenPartial
'
).
and
.
callThrough
();
spyOn
(
gl
.
FilteredSearchVisualTokens
,
'
getLastTokenPartial
'
).
and
.
callThrough
();
spyOn
(
FilteredSearchVisualTokens
,
'
getLastTokenPartial
'
).
and
.
callThrough
();
input
.
value
=
'
text
'
;
input
.
value
=
'
text
'
;
dispatchDeleteEvent
(
input
,
'
keyup
'
);
dispatchDeleteEvent
(
input
,
'
keyup
'
);
expect
(
gl
.
FilteredSearchVisualTokens
.
removeLastTokenPartial
).
not
.
toHaveBeenCalled
();
expect
(
FilteredSearchVisualTokens
.
removeLastTokenPartial
).
not
.
toHaveBeenCalled
();
expect
(
gl
.
FilteredSearchVisualTokens
.
getLastTokenPartial
).
not
.
toHaveBeenCalled
();
expect
(
FilteredSearchVisualTokens
.
getLastTokenPartial
).
not
.
toHaveBeenCalled
();
expect
(
input
.
value
).
toEqual
(
'
text
'
);
expect
(
input
.
value
).
toEqual
(
'
text
'
);
});
});
it
(
'
does not remove previous token on single backspace press
'
,
()
=>
{
it
(
'
does not remove previous token on single backspace press
'
,
()
=>
{
spyOn
(
gl
.
FilteredSearchVisualTokens
,
'
removeLastTokenPartial
'
).
and
.
callThrough
();
spyOn
(
FilteredSearchVisualTokens
,
'
removeLastTokenPartial
'
).
and
.
callThrough
();
spyOn
(
gl
.
FilteredSearchVisualTokens
,
'
getLastTokenPartial
'
).
and
.
callThrough
();
spyOn
(
FilteredSearchVisualTokens
,
'
getLastTokenPartial
'
).
and
.
callThrough
();
input
.
value
=
'
t
'
;
input
.
value
=
'
t
'
;
dispatchDeleteEvent
(
input
,
'
keyup
'
);
dispatchDeleteEvent
(
input
,
'
keyup
'
);
expect
(
gl
.
FilteredSearchVisualTokens
.
removeLastTokenPartial
).
not
.
toHaveBeenCalled
();
expect
(
FilteredSearchVisualTokens
.
removeLastTokenPartial
).
not
.
toHaveBeenCalled
();
expect
(
gl
.
FilteredSearchVisualTokens
.
getLastTokenPartial
).
not
.
toHaveBeenCalled
();
expect
(
FilteredSearchVisualTokens
.
getLastTokenPartial
).
not
.
toHaveBeenCalled
();
expect
(
input
.
value
).
toEqual
(
'
t
'
);
expect
(
input
.
value
).
toEqual
(
'
t
'
);
});
});
});
});
...
@@ -309,7 +310,7 @@ describe('Filtered Search Manager', () => {
...
@@ -309,7 +310,7 @@ describe('Filtered Search Manager', () => {
describe
(
'
unselected token
'
,
()
=>
{
describe
(
'
unselected token
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
spyOn
(
gl
.
FilteredSearchManager
.
prototype
,
'
removeSelectedToken
'
).
and
.
callThrough
();
spyOn
(
FilteredSearchManager
.
prototype
,
'
removeSelectedToken
'
).
and
.
callThrough
();
tokensContainer
.
innerHTML
=
FilteredSearchSpecHelper
.
createTokensContainerHTML
(
tokensContainer
.
innerHTML
=
FilteredSearchSpecHelper
.
createTokensContainerHTML
(
FilteredSearchSpecHelper
.
createFilterVisualTokenHTML
(
'
milestone
'
,
'
none
'
),
FilteredSearchSpecHelper
.
createFilterVisualTokenHTML
(
'
milestone
'
,
'
none
'
),
...
@@ -380,16 +381,16 @@ describe('Filtered Search Manager', () => {
...
@@ -380,16 +381,16 @@ describe('Filtered Search Manager', () => {
describe
(
'
removeSelectedToken
'
,
()
=>
{
describe
(
'
removeSelectedToken
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
spyOn
(
gl
.
FilteredSearchVisualTokens
,
'
removeSelectedToken
'
).
and
.
callThrough
();
spyOn
(
FilteredSearchVisualTokens
,
'
removeSelectedToken
'
).
and
.
callThrough
();
spyOn
(
gl
.
FilteredSearchManager
.
prototype
,
'
handleInputPlaceholder
'
).
and
.
callThrough
();
spyOn
(
FilteredSearchManager
.
prototype
,
'
handleInputPlaceholder
'
).
and
.
callThrough
();
spyOn
(
gl
.
FilteredSearchManager
.
prototype
,
'
toggleClearSearchButton
'
).
and
.
callThrough
();
spyOn
(
FilteredSearchManager
.
prototype
,
'
toggleClearSearchButton
'
).
and
.
callThrough
();
initializeManager
();
initializeManager
();
});
});
it
(
'
calls FilteredSearchVisualTokens.removeSelectedToken
'
,
()
=>
{
it
(
'
calls FilteredSearchVisualTokens.removeSelectedToken
'
,
()
=>
{
manager
.
removeSelectedToken
();
manager
.
removeSelectedToken
();
expect
(
gl
.
FilteredSearchVisualTokens
.
removeSelectedToken
).
toHaveBeenCalled
();
expect
(
FilteredSearchVisualTokens
.
removeSelectedToken
).
toHaveBeenCalled
();
});
});
it
(
'
calls handleInputPlaceholder
'
,
()
=>
{
it
(
'
calls handleInputPlaceholder
'
,
()
=>
{
...
@@ -421,12 +422,12 @@ describe('Filtered Search Manager', () => {
...
@@ -421,12 +422,12 @@ describe('Filtered Search Manager', () => {
manager
.
filteredSearchInput
.
value
=
inputValue
;
manager
.
filteredSearchInput
.
value
=
inputValue
;
manager
.
filteredSearchInput
.
dispatchEvent
(
new
Event
(
'
input
'
));
manager
.
filteredSearchInput
.
dispatchEvent
(
new
Event
(
'
input
'
));
expect
(
gl
.
DropdownUtils
.
getSearchQuery
()).
toEqual
(
inputValue
);
expect
(
DropdownUtils
.
getSearchQuery
()).
toEqual
(
inputValue
);
manager
.
clearSearchButton
.
click
();
manager
.
clearSearchButton
.
click
();
expect
(
manager
.
filteredSearchInput
.
value
).
toEqual
(
''
);
expect
(
manager
.
filteredSearchInput
.
value
).
toEqual
(
''
);
expect
(
gl
.
DropdownUtils
.
getSearchQuery
()).
toEqual
(
''
);
expect
(
DropdownUtils
.
getSearchQuery
()).
toEqual
(
''
);
});
});
});
});
...
...
spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js
View file @
bd8290d9
import
FilteredSearchTokenKeys
from
'
~/filtered_search/filtered_search_token_keys
'
;
import
FilteredSearchTokenKeys
from
'
~/filtered_search/filtered_search_token_keys
'
;
import
'
~/filtered_search/filtered_search_tokenizer
'
;
import
FilteredSearchTokenizer
from
'
~/filtered_search/filtered_search_tokenizer
'
;
describe
(
'
Filtered Search Tokenizer
'
,
()
=>
{
describe
(
'
Filtered Search Tokenizer
'
,
()
=>
{
const
allowedKeys
=
FilteredSearchTokenKeys
.
getKeys
();
const
allowedKeys
=
FilteredSearchTokenKeys
.
getKeys
();
describe
(
'
processTokens
'
,
()
=>
{
describe
(
'
processTokens
'
,
()
=>
{
it
(
'
returns for input containing only search value
'
,
()
=>
{
it
(
'
returns for input containing only search value
'
,
()
=>
{
const
results
=
gl
.
FilteredSearchTokenizer
.
processTokens
(
'
searchTerm
'
,
allowedKeys
);
const
results
=
FilteredSearchTokenizer
.
processTokens
(
'
searchTerm
'
,
allowedKeys
);
expect
(
results
.
searchToken
).
toBe
(
'
searchTerm
'
);
expect
(
results
.
searchToken
).
toBe
(
'
searchTerm
'
);
expect
(
results
.
tokens
.
length
).
toBe
(
0
);
expect
(
results
.
tokens
.
length
).
toBe
(
0
);
expect
(
results
.
lastToken
).
toBe
(
results
.
searchToken
);
expect
(
results
.
lastToken
).
toBe
(
results
.
searchToken
);
});
});
it
(
'
returns for input containing only tokens
'
,
()
=>
{
it
(
'
returns for input containing only tokens
'
,
()
=>
{
const
results
=
gl
.
FilteredSearchTokenizer
const
results
=
FilteredSearchTokenizer
.
processTokens
(
'
author:@root label:~"Very Important" milestone:%v1.0 assignee:none
'
,
allowedKeys
);
.
processTokens
(
'
author:@root label:~"Very Important" milestone:%v1.0 assignee:none
'
,
allowedKeys
);
expect
(
results
.
searchToken
).
toBe
(
''
);
expect
(
results
.
searchToken
).
toBe
(
''
);
expect
(
results
.
tokens
.
length
).
toBe
(
4
);
expect
(
results
.
tokens
.
length
).
toBe
(
4
);
...
@@ -37,7 +37,7 @@ describe('Filtered Search Tokenizer', () => {
...
@@ -37,7 +37,7 @@ describe('Filtered Search Tokenizer', () => {
});
});
it
(
'
returns for input starting with search value and ending with tokens
'
,
()
=>
{
it
(
'
returns for input starting with search value and ending with tokens
'
,
()
=>
{
const
results
=
gl
.
FilteredSearchTokenizer
const
results
=
FilteredSearchTokenizer
.
processTokens
(
'
searchTerm anotherSearchTerm milestone:none
'
,
allowedKeys
);
.
processTokens
(
'
searchTerm anotherSearchTerm milestone:none
'
,
allowedKeys
);
expect
(
results
.
searchToken
).
toBe
(
'
searchTerm anotherSearchTerm
'
);
expect
(
results
.
searchToken
).
toBe
(
'
searchTerm anotherSearchTerm
'
);
expect
(
results
.
tokens
.
length
).
toBe
(
1
);
expect
(
results
.
tokens
.
length
).
toBe
(
1
);
...
@@ -48,7 +48,7 @@ describe('Filtered Search Tokenizer', () => {
...
@@ -48,7 +48,7 @@ describe('Filtered Search Tokenizer', () => {
});
});
it
(
'
returns for input starting with tokens and ending with search value
'
,
()
=>
{
it
(
'
returns for input starting with tokens and ending with search value
'
,
()
=>
{
const
results
=
gl
.
FilteredSearchTokenizer
const
results
=
FilteredSearchTokenizer
.
processTokens
(
'
assignee:@user searchTerm
'
,
allowedKeys
);
.
processTokens
(
'
assignee:@user searchTerm
'
,
allowedKeys
);
expect
(
results
.
searchToken
).
toBe
(
'
searchTerm
'
);
expect
(
results
.
searchToken
).
toBe
(
'
searchTerm
'
);
...
@@ -60,7 +60,7 @@ describe('Filtered Search Tokenizer', () => {
...
@@ -60,7 +60,7 @@ describe('Filtered Search Tokenizer', () => {
});
});
it
(
'
returns for input containing search value wrapped between tokens
'
,
()
=>
{
it
(
'
returns for input containing search value wrapped between tokens
'
,
()
=>
{
const
results
=
gl
.
FilteredSearchTokenizer
const
results
=
FilteredSearchTokenizer
.
processTokens
(
'
author:@root label:~"Won
\'
t fix" searchTerm anotherSearchTerm milestone:none
'
,
allowedKeys
);
.
processTokens
(
'
author:@root label:~"Won
\'
t fix" searchTerm anotherSearchTerm milestone:none
'
,
allowedKeys
);
expect
(
results
.
searchToken
).
toBe
(
'
searchTerm anotherSearchTerm
'
);
expect
(
results
.
searchToken
).
toBe
(
'
searchTerm anotherSearchTerm
'
);
...
@@ -81,7 +81,7 @@ describe('Filtered Search Tokenizer', () => {
...
@@ -81,7 +81,7 @@ describe('Filtered Search Tokenizer', () => {
});
});
it
(
'
returns for input containing search value in between tokens
'
,
()
=>
{
it
(
'
returns for input containing search value in between tokens
'
,
()
=>
{
const
results
=
gl
.
FilteredSearchTokenizer
const
results
=
FilteredSearchTokenizer
.
processTokens
(
'
author:@root searchTerm assignee:none anotherSearchTerm label:~Doing
'
,
allowedKeys
);
.
processTokens
(
'
author:@root searchTerm assignee:none anotherSearchTerm label:~Doing
'
,
allowedKeys
);
expect
(
results
.
searchToken
).
toBe
(
'
searchTerm anotherSearchTerm
'
);
expect
(
results
.
searchToken
).
toBe
(
'
searchTerm anotherSearchTerm
'
);
expect
(
results
.
tokens
.
length
).
toBe
(
3
);
expect
(
results
.
tokens
.
length
).
toBe
(
3
);
...
@@ -101,14 +101,14 @@ describe('Filtered Search Tokenizer', () => {
...
@@ -101,14 +101,14 @@ describe('Filtered Search Tokenizer', () => {
});
});
it
(
'
returns search value for invalid tokens
'
,
()
=>
{
it
(
'
returns search value for invalid tokens
'
,
()
=>
{
const
results
=
gl
.
FilteredSearchTokenizer
.
processTokens
(
'
fake:token
'
,
allowedKeys
);
const
results
=
FilteredSearchTokenizer
.
processTokens
(
'
fake:token
'
,
allowedKeys
);
expect
(
results
.
lastToken
).
toBe
(
'
fake:token
'
);
expect
(
results
.
lastToken
).
toBe
(
'
fake:token
'
);
expect
(
results
.
searchToken
).
toBe
(
'
fake:token
'
);
expect
(
results
.
searchToken
).
toBe
(
'
fake:token
'
);
expect
(
results
.
tokens
.
length
).
toEqual
(
0
);
expect
(
results
.
tokens
.
length
).
toEqual
(
0
);
});
});
it
(
'
returns search value and token for mix of valid and invalid tokens
'
,
()
=>
{
it
(
'
returns search value and token for mix of valid and invalid tokens
'
,
()
=>
{
const
results
=
gl
.
FilteredSearchTokenizer
.
processTokens
(
'
label:real fake:token
'
,
allowedKeys
);
const
results
=
FilteredSearchTokenizer
.
processTokens
(
'
label:real fake:token
'
,
allowedKeys
);
expect
(
results
.
tokens
.
length
).
toEqual
(
1
);
expect
(
results
.
tokens
.
length
).
toEqual
(
1
);
expect
(
results
.
tokens
[
0
].
key
).
toBe
(
'
label
'
);
expect
(
results
.
tokens
[
0
].
key
).
toBe
(
'
label
'
);
expect
(
results
.
tokens
[
0
].
value
).
toBe
(
'
real
'
);
expect
(
results
.
tokens
[
0
].
value
).
toBe
(
'
real
'
);
...
@@ -118,13 +118,13 @@ describe('Filtered Search Tokenizer', () => {
...
@@ -118,13 +118,13 @@ describe('Filtered Search Tokenizer', () => {
});
});
it
(
'
returns search value for invalid symbols
'
,
()
=>
{
it
(
'
returns search value for invalid symbols
'
,
()
=>
{
const
results
=
gl
.
FilteredSearchTokenizer
.
processTokens
(
'
std::includes
'
,
allowedKeys
);
const
results
=
FilteredSearchTokenizer
.
processTokens
(
'
std::includes
'
,
allowedKeys
);
expect
(
results
.
lastToken
).
toBe
(
'
std::includes
'
);
expect
(
results
.
lastToken
).
toBe
(
'
std::includes
'
);
expect
(
results
.
searchToken
).
toBe
(
'
std::includes
'
);
expect
(
results
.
searchToken
).
toBe
(
'
std::includes
'
);
});
});
it
(
'
removes duplicated values
'
,
()
=>
{
it
(
'
removes duplicated values
'
,
()
=>
{
const
results
=
gl
.
FilteredSearchTokenizer
.
processTokens
(
'
label:~foo label:~foo
'
,
allowedKeys
);
const
results
=
FilteredSearchTokenizer
.
processTokens
(
'
label:~foo label:~foo
'
,
allowedKeys
);
expect
(
results
.
tokens
.
length
).
toBe
(
1
);
expect
(
results
.
tokens
.
length
).
toBe
(
1
);
expect
(
results
.
tokens
[
0
].
key
).
toBe
(
'
label
'
);
expect
(
results
.
tokens
[
0
].
key
).
toBe
(
'
label
'
);
expect
(
results
.
tokens
[
0
].
value
).
toBe
(
'
foo
'
);
expect
(
results
.
tokens
[
0
].
value
).
toBe
(
'
foo
'
);
...
...
spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
View file @
bd8290d9
...
@@ -2,11 +2,12 @@ import _ from 'underscore';
...
@@ -2,11 +2,12 @@ import _ from 'underscore';
import
AjaxCache
from
'
~/lib/utils/ajax_cache
'
;
import
AjaxCache
from
'
~/lib/utils/ajax_cache
'
;
import
UsersCache
from
'
~/lib/utils/users_cache
'
;
import
UsersCache
from
'
~/lib/utils/users_cache
'
;
import
'
~/filtered_search/filtered_search_visual_tokens
'
;
import
FilteredSearchVisualTokens
from
'
~/filtered_search/filtered_search_visual_tokens
'
;
import
DropdownUtils
from
'
~/filtered_search//dropdown_utils
'
;
import
FilteredSearchSpecHelper
from
'
../helpers/filtered_search_spec_helper
'
;
import
FilteredSearchSpecHelper
from
'
../helpers/filtered_search_spec_helper
'
;
describe
(
'
Filtered Search Visual Tokens
'
,
()
=>
{
describe
(
'
Filtered Search Visual Tokens
'
,
()
=>
{
const
subject
=
gl
.
FilteredSearchVisualTokens
;
const
subject
=
FilteredSearchVisualTokens
;
const
findElements
=
(
tokenElement
)
=>
{
const
findElements
=
(
tokenElement
)
=>
{
const
tokenNameElement
=
tokenElement
.
querySelector
(
'
.name
'
);
const
tokenNameElement
=
tokenElement
.
querySelector
(
'
.name
'
);
...
@@ -860,25 +861,25 @@ describe('Filtered Search Visual Tokens', () => {
...
@@ -860,25 +861,25 @@ describe('Filtered Search Visual Tokens', () => {
it
(
'
does not preprocess more than once
'
,
()
=>
{
it
(
'
does not preprocess more than once
'
,
()
=>
{
let
labels
=
[];
let
labels
=
[];
spyOn
(
gl
.
DropdownUtils
,
'
duplicateLabelPreprocessing
'
).
and
.
callFake
(()
=>
[]);
spyOn
(
DropdownUtils
,
'
duplicateLabelPreprocessing
'
).
and
.
callFake
(()
=>
[]);
labels
=
gl
.
FilteredSearchVisualTokens
.
preprocessLabel
(
endpoint
,
labels
);
labels
=
FilteredSearchVisualTokens
.
preprocessLabel
(
endpoint
,
labels
);
gl
.
FilteredSearchVisualTokens
.
preprocessLabel
(
endpoint
,
labels
);
FilteredSearchVisualTokens
.
preprocessLabel
(
endpoint
,
labels
);
expect
(
gl
.
DropdownUtils
.
duplicateLabelPreprocessing
.
calls
.
count
()).
toEqual
(
1
);
expect
(
DropdownUtils
.
duplicateLabelPreprocessing
.
calls
.
count
()).
toEqual
(
1
);
});
});
describe
(
'
not preprocessed before
'
,
()
=>
{
describe
(
'
not preprocessed before
'
,
()
=>
{
it
(
'
returns preprocessed labels
'
,
()
=>
{
it
(
'
returns preprocessed labels
'
,
()
=>
{
let
labels
=
[];
let
labels
=
[];
expect
(
labels
.
preprocessed
).
not
.
toEqual
(
true
);
expect
(
labels
.
preprocessed
).
not
.
toEqual
(
true
);
labels
=
gl
.
FilteredSearchVisualTokens
.
preprocessLabel
(
endpoint
,
labels
);
labels
=
FilteredSearchVisualTokens
.
preprocessLabel
(
endpoint
,
labels
);
expect
(
labels
.
preprocessed
).
toEqual
(
true
);
expect
(
labels
.
preprocessed
).
toEqual
(
true
);
});
});
it
(
'
overrides AjaxCache with preprocessed results
'
,
()
=>
{
it
(
'
overrides AjaxCache with preprocessed results
'
,
()
=>
{
spyOn
(
AjaxCache
,
'
override
'
).
and
.
callFake
(()
=>
{});
spyOn
(
AjaxCache
,
'
override
'
).
and
.
callFake
(()
=>
{});
gl
.
FilteredSearchVisualTokens
.
preprocessLabel
(
endpoint
,
[]);
FilteredSearchVisualTokens
.
preprocessLabel
(
endpoint
,
[]);
expect
(
AjaxCache
.
override
.
calls
.
count
()).
toEqual
(
1
);
expect
(
AjaxCache
.
override
.
calls
.
count
()).
toEqual
(
1
);
});
});
});
});
...
@@ -926,7 +927,7 @@ describe('Filtered Search Visual Tokens', () => {
...
@@ -926,7 +927,7 @@ describe('Filtered Search Visual Tokens', () => {
};
};
const
findLabel
=
tokenValue
=>
labelData
.
find
(
const
findLabel
=
tokenValue
=>
labelData
.
find
(
label
=>
tokenValue
===
`~
${
gl
.
DropdownUtils
.
getEscapedText
(
label
.
title
)}
`
,
label
=>
tokenValue
===
`~
${
DropdownUtils
.
getEscapedText
(
label
.
title
)}
`
,
);
);
it
(
'
updates the color of a label token
'
,
(
done
)
=>
{
it
(
'
updates the color of a label token
'
,
(
done
)
=>
{
...
...
spec/javascripts/projects/project_import_gitlab_project_spec.js
View file @
bd8290d9
...
@@ -10,7 +10,7 @@ describe('Import Gitlab project', () => {
...
@@ -10,7 +10,7 @@ describe('Import Gitlab project', () => {
<input class="js-path-name" />
<input class="js-path-name" />
`
);
`
);
projectImportGitlab
.
bindEvents
();
projectImportGitlab
();
});
});
afterEach
(()
=>
{
afterEach
(()
=>
{
...
...
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