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
17a35da6
Commit
17a35da6
authored
Oct 30, 2017
by
Filipa Lacerda
Committed by
Phil Hughes
Oct 30, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Ee 38869 importer status - Remove code from global namespace
parent
3dc544f4
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
306 additions
and
477 deletions
+306
-477
app/assets/javascripts/boards/components/board_sidebar.js
app/assets/javascripts/boards/components/board_sidebar.js
+1
-1
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+3
-3
app/assets/javascripts/importer_status.js
app/assets/javascripts/importer_status.js
+71
-73
app/assets/javascripts/init_issuable_sidebar.js
app/assets/javascripts/init_issuable_sidebar.js
+1
-1
app/assets/javascripts/issuable_bulk_update_actions.js
app/assets/javascripts/issuable_bulk_update_actions.js
+0
-1
app/assets/javascripts/issuable_bulk_update_sidebar.js
app/assets/javascripts/issuable_bulk_update_sidebar.js
+4
-0
app/assets/javascripts/issuable_context.js
app/assets/javascripts/issuable_context.js
+56
-57
app/assets/javascripts/issuable_form.js
app/assets/javascripts/issuable_form.js
+97
-100
app/assets/javascripts/issuable_index.js
app/assets/javascripts/issuable_index.js
+36
-165
app/assets/javascripts/main.js
app/assets/javascripts/main.js
+2
-3
spec/javascripts/issuable_context_spec.js
spec/javascripts/issuable_context_spec.js
+1
-2
spec/javascripts/issuable_spec.js
spec/javascripts/issuable_spec.js
+33
-69
spec/javascripts/labels_issue_sidebar_spec.js
spec/javascripts/labels_issue_sidebar_spec.js
+1
-2
No files found.
app/assets/javascripts/boards/components/board_sidebar.js
View file @
17a35da6
/* eslint-disable comma-dangle, space-before-function-paren, no-new */
/* eslint-disable comma-dangle, space-before-function-paren, no-new */
/* global IssuableContext */
/* global MilestoneSelect */
/* global MilestoneSelect */
/* global LabelsSelect */
/* global LabelsSelect */
/* global Sidebar */
/* global Sidebar */
...
@@ -11,6 +10,7 @@ import AssigneeTitle from '../../sidebar/components/assignees/assignee_title';
...
@@ -11,6 +10,7 @@ import AssigneeTitle from '../../sidebar/components/assignees/assignee_title';
import
Assignees
from
'
../../sidebar/components/assignees/assignees
'
;
import
Assignees
from
'
../../sidebar/components/assignees/assignees
'
;
import
DueDateSelectors
from
'
../../due_date_select
'
;
import
DueDateSelectors
from
'
../../due_date_select
'
;
import
'
./sidebar/remove_issue
'
;
import
'
./sidebar/remove_issue
'
;
import
IssuableContext
from
'
../../issuable_context
'
;
const
Store
=
gl
.
issueBoards
.
BoardsStore
;
const
Store
=
gl
.
issueBoards
.
BoardsStore
;
...
...
app/assets/javascripts/dispatcher.js
View file @
17a35da6
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, wrap-iife, no-shadow, consistent-return, one-var, one-var-declaration-per-line, camelcase, default-case, no-new, quotes, no-duplicate-case, no-case-declarations, no-fallthrough, max-len */
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, wrap-iife, no-shadow, consistent-return, one-var, one-var-declaration-per-line, camelcase, default-case, no-new, quotes, no-duplicate-case, no-case-declarations, no-fallthrough, max-len */
/* global ProjectSelect */
/* global ProjectSelect */
/* global IssuableIndex */
import
IssuableIndex
from
'
./issuable_index
'
;
/* global Milestone */
/* global Milestone */
/* global IssuableForm */
import
IssuableForm
from
'
./issuable_form
'
;
/* global LabelsSelect */
/* global LabelsSelect */
/* global MilestoneSelect */
/* global MilestoneSelect */
/* global NewBranchForm */
/* global NewBranchForm */
...
@@ -197,7 +197,7 @@ import initGroupAnalytics from './init_group_analytics';
...
@@ -197,7 +197,7 @@ import initGroupAnalytics from './init_group_analytics';
filteredSearchManager
.
setup
();
filteredSearchManager
.
setup
();
}
}
const
pagePrefix
=
page
===
'
projects:merge_requests:index
'
?
'
merge_request_
'
:
'
issue_
'
;
const
pagePrefix
=
page
===
'
projects:merge_requests:index
'
?
'
merge_request_
'
:
'
issue_
'
;
IssuableIndex
.
init
(
pagePrefix
);
new
IssuableIndex
(
pagePrefix
);
shortcut_handler
=
new
ShortcutsNavigation
();
shortcut_handler
=
new
ShortcutsNavigation
();
new
UsersSelect
();
new
UsersSelect
();
...
...
app/assets/javascripts/importer_status.js
View file @
17a35da6
/* eslint-disable func-names, space-before-function-paren, wrap-iife, camelcase, no-var, one-var, one-var-declaration-per-line, prefer-template, quotes, object-shorthand, comma-dangle, no-unused-vars, prefer-arrow-callback, no-else-return, vars-on-top, no-new, max-len */
class
ImporterStatus
{
constructor
(
jobsUrl
,
importUrl
)
{
this
.
jobsUrl
=
jobsUrl
;
this
.
importUrl
=
importUrl
;
this
.
initStatusPage
();
this
.
setAutoUpdate
();
}
(
function
()
{
initStatusPage
()
{
window
.
ImporterStatus
=
(
function
()
{
$
(
'
.js-add-to-import
'
)
function
ImporterStatus
(
jobs_url
,
import_url
)
{
.
off
(
'
click
'
)
this
.
jobs_url
=
jobs_url
;
.
on
(
'
click
'
,
(
event
)
=>
{
this
.
import_url
=
import_url
;
const
$btn
=
$
(
event
.
currentTarget
);
this
.
initStatusPage
();
const
$tr
=
$btn
.
closest
(
'
tr
'
);
this
.
setAutoUpdate
();
const
$targetField
=
$tr
.
find
(
'
.import-target
'
);
}
const
$namespaceInput
=
$targetField
.
find
(
'
.js-select-namespace option:selected
'
);
const
id
=
$tr
.
attr
(
'
id
'
).
replace
(
'
repo_
'
,
''
);
let
targetNamespace
;
let
newName
;
if
(
$namespaceInput
.
length
>
0
)
{
targetNamespace
=
$namespaceInput
[
0
].
innerHTML
;
newName
=
$targetField
.
find
(
'
#path
'
).
prop
(
'
value
'
);
$targetField
.
empty
().
append
(
`
${
targetNamespace
}
/
${
newName
}
`
);
}
$btn
.
disable
().
addClass
(
'
is-loading
'
);
ImporterStatus
.
prototype
.
initStatusPage
=
function
()
{
return
$
.
post
(
this
.
importUrl
,
{
$
(
'
.js-add-to-import
'
).
off
(
'
click
'
).
on
(
'
click
'
,
(
function
(
_this
)
{
repo_id
:
id
,
return
function
(
e
)
{
target_namespace
:
targetNamespace
,
var
$btn
,
$namespace_input
,
$target_field
,
$tr
,
id
,
target_namespace
,
newName
;
new_name
:
newName
,
$btn
=
$
(
e
.
currentTarget
);
},
{
$tr
=
$btn
.
closest
(
'
tr
'
);
dataType
:
'
script
'
,
$target_field
=
$tr
.
find
(
'
.import-target
'
);
});
$namespace_input
=
$target_field
.
find
(
'
.js-select-namespace option:selected
'
);
});
id
=
$tr
.
attr
(
'
id
'
).
replace
(
'
repo_
'
,
''
);
target_namespace
=
null
;
$
(
'
.js-import-all
'
)
newName
=
null
;
.
off
(
'
click
'
)
if
(
$namespace_input
.
length
>
0
)
{
.
on
(
'
click
'
,
function
onClickImportAll
()
{
target_namespace
=
$namespace_input
[
0
].
innerHTML
;
const
$btn
=
$
(
this
);
newName
=
$target_field
.
find
(
'
#path
'
).
prop
(
'
value
'
);
$target_field
.
empty
().
append
(
target_namespace
+
"
/
"
+
newName
);
}
$btn
.
disable
().
addClass
(
'
is-loading
'
);
return
$
.
post
(
_this
.
import_url
,
{
repo_id
:
id
,
target_namespace
:
target_namespace
,
new_name
:
newName
},
{
dataType
:
'
script
'
});
};
})(
this
));
return
$
(
'
.js-import-all
'
).
off
(
'
click
'
).
on
(
'
click
'
,
function
(
e
)
{
var
$btn
;
$btn
=
$
(
this
);
$btn
.
disable
().
addClass
(
'
is-loading
'
);
$btn
.
disable
().
addClass
(
'
is-loading
'
);
return
$
(
'
.js-add-to-import
'
).
each
(
function
()
{
return
$
(
'
.js-add-to-import
'
).
each
(
function
triggerAddImport
()
{
return
$
(
this
).
trigger
(
'
click
'
);
return
$
(
this
).
trigger
(
'
click
'
);
});
});
});
});
};
}
setAutoUpdate
()
{
return
setInterval
(()
=>
$
.
get
(
this
.
jobsUrl
,
data
=>
$
.
each
(
data
,
(
i
,
job
)
=>
{
const
jobItem
=
$
(
`#project_
${
job
.
id
}
`
);
const
statusField
=
jobItem
.
find
(
'
.job-status
'
);
ImporterStatus
.
prototype
.
setAutoUpdate
=
function
()
{
const
spinner
=
'
<i class="fa fa-spinner fa-spin"></i>
'
;
return
setInterval
(((
function
(
_this
)
{
return
function
()
{
return
$
.
get
(
_this
.
jobs_url
,
function
(
data
)
{
return
$
.
each
(
data
,
function
(
i
,
job
)
{
var
job_item
,
status_field
;
job_item
=
$
(
"
#project_
"
+
job
.
id
);
status_field
=
job_item
.
find
(
"
.job-status
"
);
if
(
job
.
import_status
===
'
finished
'
)
{
job_item
.
removeClass
(
"
active
"
).
addClass
(
"
success
"
);
return
status_field
.
html
(
'
<span><i class="fa fa-check"></i> done</span>
'
);
}
else
if
(
job
.
import_status
===
'
scheduled
'
)
{
return
status_field
.
html
(
"
<i class='fa fa-spinner fa-spin'></i> scheduled
"
);
}
else
if
(
job
.
import_status
===
'
started
'
)
{
return
status_field
.
html
(
"
<i class='fa fa-spinner fa-spin'></i> started
"
);
}
else
{
return
status_field
.
html
(
job
.
import_status
);
}
});
});
};
})(
this
)),
4000
);
};
return
ImporterStatus
;
switch
(
job
.
import_status
)
{
})();
case
'
finished
'
:
jobItem
.
removeClass
(
'
active
'
).
addClass
(
'
success
'
);
statusField
.
html
(
'
<span><i class="fa fa-check"></i> done</span>
'
);
break
;
case
'
scheduled
'
:
statusField
.
html
(
`
${
spinner
}
scheduled`
);
break
;
case
'
started
'
:
statusField
.
html
(
`
${
spinner
}
started`
);
break
;
default
:
statusField
.
html
(
job
.
import_status
);
break
;
}
})),
4000
);
}
}
$
(
function
()
{
// eslint-disable-next-line consistent-return
if
(
$
(
'
.js-importer-status
'
).
length
)
{
export
default
function
initImporterStatus
()
{
var
jobsImportPath
=
$
(
'
.js-importer-status
'
).
data
(
'
jobs-import-path
'
);
const
importerStatus
=
document
.
querySelector
(
'
.js-importer-status
'
);
var
importPath
=
$
(
'
.js-importer-status
'
).
data
(
'
import-path
'
);
new
window
.
ImporterStatus
(
jobsImportPath
,
importPath
);
if
(
importerStatus
)
{
}
const
data
=
importerStatus
.
dataset
;
});
return
new
ImporterStatus
(
data
.
jobsImportPath
,
data
.
importPath
);
}).
call
(
window
);
}
}
app/assets/javascripts/init_issuable_sidebar.js
View file @
17a35da6
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
/* global MilestoneSelect */
/* global MilestoneSelect */
/* global LabelsSelect */
/* global LabelsSelect */
/* global WeightSelect */
/* global WeightSelect */
/* global IssuableContext */
import
IssuableContext
from
'
./issuable_context
'
;
/* global Sidebar */
/* global Sidebar */
import
DueDateSelectors
from
'
./due_date_select
'
;
import
DueDateSelectors
from
'
./due_date_select
'
;
...
...
app/assets/javascripts/issuable_bulk_update_actions.js
View file @
17a35da6
/* eslint-disable comma-dangle, quotes, consistent-return, func-names, array-callback-return, space-before-function-paren, prefer-arrow-callback, max-len, no-unused-expressions, no-sequences, no-underscore-dangle, no-unused-vars, no-param-reassign */
/* eslint-disable comma-dangle, quotes, consistent-return, func-names, array-callback-return, space-before-function-paren, prefer-arrow-callback, max-len, no-unused-expressions, no-sequences, no-underscore-dangle, no-unused-vars, no-param-reassign */
/* global IssuableIndex */
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
Flash
from
'
./flash
'
;
import
Flash
from
'
./flash
'
;
...
...
app/assets/javascripts/issuable_bulk_update_sidebar.js
View file @
17a35da6
...
@@ -5,6 +5,10 @@
...
@@ -5,6 +5,10 @@
/* global SubscriptionSelect */
/* global SubscriptionSelect */
import
IssuableBulkUpdateActions
from
'
./issuable_bulk_update_actions
'
;
import
IssuableBulkUpdateActions
from
'
./issuable_bulk_update_actions
'
;
import
'
./milestone_select
'
;
import
'
./issue_status_select
'
;
import
'
./subscription_select
'
;
import
'
./labels_select
'
;
const
HIDDEN_CLASS
=
'
hidden
'
;
const
HIDDEN_CLASS
=
'
hidden
'
;
const
DISABLED_CONTENT_CLASS
=
'
disabled-content
'
;
const
DISABLED_CONTENT_CLASS
=
'
disabled-content
'
;
...
...
app/assets/javascripts/issuable_context.js
View file @
17a35da6
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-new, comma-dangle, quotes, prefer-arrow-callback, consistent-return, one-var, no-var, one-var-declaration-per-line, no-underscore-dangle, max-len */
import
Cookies
from
'
js-cookie
'
;
import
Cookies
from
'
js-cookie
'
;
import
bp
from
'
./breakpoints
'
;
import
bp
from
'
./breakpoints
'
;
import
UsersSelect
from
'
./users_select
'
;
import
UsersSelect
from
'
./users_select
'
;
const
PARTICIPANTS_ROW_COUNT
=
7
;
const
PARTICIPANTS_ROW_COUNT
=
7
;
(
function
()
{
export
default
class
IssuableContext
{
this
.
IssuableContext
=
(
function
()
{
constructor
(
currentUser
)
{
function
IssuableContext
(
currentUser
)
{
this
.
initParticipants
();
this
.
initParticipants
();
this
.
userSelect
=
new
UsersSelect
(
currentUser
);
new
UsersSelect
(
currentUser
);
$
(
'
select.select2
'
).
select2
({
$
(
'
select.select2
'
).
select2
({
width
:
'
resolve
'
,
width
:
'
resolve
'
,
dropdownAutoWidth
:
true
dropdownAutoWidth
:
true
,
});
});
$
(
"
.issuable-sidebar .inline-update
"
).
on
(
"
change
"
,
"
select
"
,
function
()
{
return
$
(
this
).
submit
();
$
(
'
.issuable-sidebar .inline-update
'
).
on
(
'
change
'
,
'
select
'
,
function
onClickSelect
()
{
});
return
$
(
this
).
submit
();
$
(
"
.issuable-sidebar .inline-update
"
).
on
(
"
change
"
,
"
.js-assignee
"
,
function
()
{
});
return
$
(
this
).
submit
();
$
(
'
.issuable-sidebar .inline-update
'
).
on
(
'
change
'
,
'
.js-assignee
'
,
function
onClickAssignee
()
{
});
return
$
(
this
).
submit
();
$
(
document
).
off
(
'
click
'
,
'
.issuable-sidebar .dropdown-content a
'
).
on
(
'
click
'
,
'
.issuable-sidebar .dropdown-content a
'
,
function
(
e
)
{
});
return
e
.
preventDefault
();
$
(
document
)
});
.
off
(
'
click
'
,
'
.issuable-sidebar .dropdown-content a
'
)
$
(
document
).
off
(
'
click
'
,
'
.edit-link
'
).
on
(
'
click
'
,
'
.edit-link
'
,
function
(
e
)
{
.
on
(
'
click
'
,
'
.issuable-sidebar .dropdown-content a
'
,
e
=>
e
.
preventDefault
());
var
$block
,
$selectbox
;
$
(
document
)
.
off
(
'
click
'
,
'
.edit-link
'
)
.
on
(
'
click
'
,
'
.edit-link
'
,
function
onClickEdit
(
e
)
{
e
.
preventDefault
();
e
.
preventDefault
();
$block
=
$
(
this
).
parents
(
'
.block
'
);
const
$block
=
$
(
this
).
parents
(
'
.block
'
);
$selectbox
=
$block
.
find
(
'
.selectbox
'
);
const
$selectbox
=
$block
.
find
(
'
.selectbox
'
);
if
(
$selectbox
.
is
(
'
:visible
'
))
{
if
(
$selectbox
.
is
(
'
:visible
'
))
{
$selectbox
.
hide
();
$selectbox
.
hide
();
$block
.
find
(
'
.value
'
).
show
();
$block
.
find
(
'
.value
'
).
show
();
...
@@ -35,46 +37,43 @@ const PARTICIPANTS_ROW_COUNT = 7;
...
@@ -35,46 +37,43 @@ const PARTICIPANTS_ROW_COUNT = 7;
$selectbox
.
show
();
$selectbox
.
show
();
$block
.
find
(
'
.value
'
).
hide
();
$block
.
find
(
'
.value
'
).
hide
();
}
}
if
(
$selectbox
.
is
(
'
:visible
'
))
{
if
(
$selectbox
.
is
(
'
:visible
'
))
{
return
setTimeout
(
function
()
{
setTimeout
(()
=>
$block
.
find
(
'
.dropdown-menu-toggle
'
).
trigger
(
'
click
'
),
0
);
return
$block
.
find
(
'
.dropdown-menu-toggle
'
).
trigger
(
'
click
'
);
},
0
);
}
}
});
});
window
.
addEventListener
(
'
beforeunload
'
,
function
()
{
// collapsed_gutter cookie hides the sidebar
var
bpBreakpoint
=
bp
.
getBreakpointSize
();
if
(
bpBreakpoint
===
'
xs
'
||
bpBreakpoint
===
'
sm
'
)
{
Cookies
.
set
(
'
collapsed_gutter
'
,
true
);
}
});
}
IssuableContext
.
prototype
.
initParticipants
=
function
()
{
window
.
addEventListener
(
'
beforeunload
'
,
()
=>
{
$
(
document
).
on
(
'
click
'
,
'
.js-participants-more
'
,
this
.
toggleHiddenParticipants
);
// collapsed_gutter cookie hides the sidebar
return
$
(
'
.js-participants-author
'
).
each
(
function
(
i
)
{
const
bpBreakpoint
=
bp
.
getBreakpointSize
();
if
(
i
>=
PARTICIPANTS_ROW_COUNT
)
{
if
(
bpBreakpoint
===
'
xs
'
||
bpBreakpoint
===
'
sm
'
)
{
return
$
(
this
).
addClass
(
'
js-participants-hidden
'
).
hide
(
);
Cookies
.
set
(
'
collapsed_gutter
'
,
true
);
}
}
});
});
};
}
IssuableContext
.
prototype
.
toggleHiddenParticipants
=
function
()
{
initParticipants
()
{
const
currentText
=
$
(
this
).
text
().
trim
();
$
(
document
).
on
(
'
click
'
,
'
.js-participants-more
'
,
this
.
toggleHiddenParticipants
);
const
lessText
=
$
(
this
).
data
(
'
less-text
'
);
return
$
(
'
.js-participants-author
'
).
each
(
function
forEachAuthor
(
i
)
{
const
originalText
=
$
(
this
).
data
(
'
original-text
'
);
if
(
i
>=
PARTICIPANTS_ROW_COUNT
)
{
$
(
this
).
addClass
(
'
js-participants-hidden
'
).
hide
();
}
});
}
if
(
currentText
===
originalText
)
{
toggleHiddenParticipants
()
{
$
(
this
).
text
(
lessText
);
const
currentText
=
$
(
this
).
text
().
trim
();
const
lessText
=
$
(
this
).
data
(
'
less-text
'
);
const
originalText
=
$
(
this
).
data
(
'
original-text
'
);
if
(
gl
.
lazyLoader
)
gl
.
lazyLoader
.
loadCheck
();
if
(
currentText
===
originalText
)
{
}
else
{
$
(
this
).
text
(
lessText
);
$
(
this
).
text
(
originalText
);
}
$
(
'
.js-participants-hidden
'
).
toggle
();
if
(
gl
.
lazyLoader
)
gl
.
lazyLoader
.
loadCheck
();
};
}
else
{
$
(
this
).
text
(
originalText
);
}
return
IssuableContext
;
$
(
'
.js-participants-hidden
'
).
toggle
()
;
}
)();
}
}
).
call
(
window
);
}
app/assets/javascripts/issuable_form.js
View file @
17a35da6
/* eslint-disable func-names,
space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-use-before-define, no-useless-escape, no-new, quotes
, object-shorthand, no-unused-vars, comma-dangle, no-alert, consistent-return, no-else-return, prefer-template, one-var, one-var-declaration-per-line, curly, max-len */
/* eslint-disable func-names,
prefer-rest-params, wrap-iife, no-use-before-define, no-useless-escape, no-new
, object-shorthand, no-unused-vars, comma-dangle, no-alert, consistent-return, no-else-return, prefer-template, one-var, one-var-declaration-per-line, curly, max-len */
/* global GitLab */
/* global GitLab */
import
Pikaday
from
'
pikaday
'
;
import
Pikaday
from
'
pikaday
'
;
...
@@ -9,104 +9,101 @@ import ZenMode from './zen_mode';
...
@@ -9,104 +9,101 @@ import ZenMode from './zen_mode';
import
{
parsePikadayDate
,
pikadayToString
}
from
'
./lib/utils/datefix
'
;
import
{
parsePikadayDate
,
pikadayToString
}
from
'
./lib/utils/datefix
'
;
import
groupsSelect
from
'
./groups_select
'
;
import
groupsSelect
from
'
./groups_select
'
;
(
function
()
{
export
default
class
IssuableForm
{
this
.
IssuableForm
=
(
function
()
{
constructor
(
form
)
{
IssuableForm
.
prototype
.
wipRegex
=
/^
\s
*
(\[
WIP
\]\s
*|WIP:
\s
*|WIP
\s
+
)
+
\s
*/i
;
this
.
form
=
form
;
this
.
toggleWip
=
this
.
toggleWip
.
bind
(
this
);
function
IssuableForm
(
form
)
{
this
.
renderWipExplanation
=
this
.
renderWipExplanation
.
bind
(
this
);
var
$issuableDueDate
,
calendar
;
this
.
resetAutosave
=
this
.
resetAutosave
.
bind
(
this
);
this
.
form
=
form
;
this
.
handleSubmit
=
this
.
handleSubmit
.
bind
(
this
);
this
.
toggleWip
=
this
.
toggleWip
.
bind
(
this
);
this
.
wipRegex
=
/^
\s
*
(\[
WIP
\]\s
*|WIP:
\s
*|WIP
\s
+
)
+
\s
*/i
;
this
.
renderWipExplanation
=
this
.
renderWipExplanation
.
bind
(
this
);
this
.
resetAutosave
=
this
.
resetAutosave
.
bind
(
this
);
new
GfmAutoComplete
(
gl
.
GfmAutoComplete
&&
gl
.
GfmAutoComplete
.
dataSources
).
setup
();
this
.
handleSubmit
=
this
.
handleSubmit
.
bind
(
this
);
new
UsersSelect
();
new
GfmAutoComplete
(
gl
.
GfmAutoComplete
&&
gl
.
GfmAutoComplete
.
dataSources
).
setup
();
groupsSelect
();
new
UsersSelect
();
new
ZenMode
();
groupsSelect
();
new
ZenMode
();
this
.
titleField
=
this
.
form
.
find
(
'
input[name*="[title]"]
'
);
this
.
titleField
=
this
.
form
.
find
(
"
input[name*='[title]']
"
);
this
.
descriptionField
=
this
.
form
.
find
(
'
textarea[name*="[description]"]
'
);
this
.
descriptionField
=
this
.
form
.
find
(
"
textarea[name*='[description]']
"
);
if
(
!
(
this
.
titleField
.
length
&&
this
.
descriptionField
.
length
))
{
if
(
!
(
this
.
titleField
.
length
&&
this
.
descriptionField
.
length
))
{
return
;
return
;
}
this
.
initAutosave
();
this
.
form
.
on
(
"
submit
"
,
this
.
handleSubmit
);
this
.
form
.
on
(
"
click
"
,
"
.btn-cancel
"
,
this
.
resetAutosave
);
this
.
initWip
();
$issuableDueDate
=
$
(
'
#issuable-due-date
'
);
if
(
$issuableDueDate
.
length
)
{
calendar
=
new
Pikaday
({
field
:
$issuableDueDate
.
get
(
0
),
theme
:
'
gitlab-theme animate-picker
'
,
format
:
'
yyyy-mm-dd
'
,
container
:
$issuableDueDate
.
parent
().
get
(
0
),
parse
:
dateString
=>
parsePikadayDate
(
dateString
),
toString
:
date
=>
pikadayToString
(
date
),
onSelect
:
function
(
dateText
)
{
$issuableDueDate
.
val
(
calendar
.
toString
(
dateText
));
}
});
calendar
.
setDate
(
parsePikadayDate
(
$issuableDueDate
.
val
()));
}
}
}
IssuableForm
.
prototype
.
initAutosave
=
function
()
{
this
.
initAutosave
();
new
Autosave
(
this
.
titleField
,
[
document
.
location
.
pathname
,
document
.
location
.
search
,
"
title
"
]);
this
.
form
.
on
(
'
submit
'
,
this
.
handleSubmit
);
return
new
Autosave
(
this
.
descriptionField
,
[
document
.
location
.
pathname
,
document
.
location
.
search
,
"
description
"
]);
this
.
form
.
on
(
'
click
'
,
'
.btn-cancel
'
,
this
.
resetAutosave
);
};
this
.
initWip
();
IssuableForm
.
prototype
.
handleSubmit
=
function
()
{
const
$issuableDueDate
=
$
(
'
#issuable-due-date
'
);
return
this
.
resetAutosave
();
};
if
(
$issuableDueDate
.
length
)
{
const
calendar
=
new
Pikaday
({
IssuableForm
.
prototype
.
resetAutosave
=
function
()
{
field
:
$issuableDueDate
.
get
(
0
),
this
.
titleField
.
data
(
"
autosave
"
).
reset
();
theme
:
'
gitlab-theme animate-picker
'
,
return
this
.
descriptionField
.
data
(
"
autosave
"
).
reset
();
format
:
'
yyyy-mm-dd
'
,
};
container
:
$issuableDueDate
.
parent
().
get
(
0
),
parse
:
dateString
=>
parsePikadayDate
(
dateString
),
IssuableForm
.
prototype
.
initWip
=
function
()
{
toString
:
date
=>
pikadayToString
(
date
),
this
.
$wipExplanation
=
this
.
form
.
find
(
"
.js-wip-explanation
"
);
onSelect
:
dateText
=>
$issuableDueDate
.
val
(
calendar
.
toString
(
dateText
)),
this
.
$noWipExplanation
=
this
.
form
.
find
(
"
.js-no-wip-explanation
"
);
});
if
(
!
(
this
.
$wipExplanation
.
length
&&
this
.
$noWipExplanation
.
length
))
{
calendar
.
setDate
(
parsePikadayDate
(
$issuableDueDate
.
val
()));
return
;
}
}
}
this
.
form
.
on
(
"
click
"
,
"
.js-toggle-wip
"
,
this
.
toggleWip
);
this
.
titleField
.
on
(
"
keyup blur
"
,
this
.
renderWipExplanation
);
initAutosave
()
{
return
this
.
renderWipExplanation
();
new
Autosave
(
this
.
titleField
,
[
document
.
location
.
pathname
,
document
.
location
.
search
,
'
title
'
]);
};
return
new
Autosave
(
this
.
descriptionField
,
[
document
.
location
.
pathname
,
document
.
location
.
search
,
'
description
'
]);
}
IssuableForm
.
prototype
.
workInProgress
=
function
()
{
return
this
.
wipRegex
.
test
(
this
.
titleField
.
val
());
handleSubmit
()
{
};
return
this
.
resetAutosave
();
}
IssuableForm
.
prototype
.
renderWipExplanation
=
function
()
{
if
(
this
.
workInProgress
())
{
resetAutosave
()
{
this
.
$wipExplanation
.
show
();
this
.
titleField
.
data
(
'
autosave
'
).
reset
();
return
this
.
$noWipExplanation
.
hide
();
return
this
.
descriptionField
.
data
(
'
autosave
'
).
reset
();
}
else
{
}
this
.
$wipExplanation
.
hide
();
return
this
.
$noWipExplanation
.
show
();
initWip
()
{
}
this
.
$wipExplanation
=
this
.
form
.
find
(
'
.js-wip-explanation
'
);
};
this
.
$noWipExplanation
=
this
.
form
.
find
(
'
.js-no-wip-explanation
'
);
if
(
!
(
this
.
$wipExplanation
.
length
&&
this
.
$noWipExplanation
.
length
))
{
IssuableForm
.
prototype
.
toggleWip
=
function
(
event
)
{
return
;
event
.
preventDefault
();
}
if
(
this
.
workInProgress
())
{
this
.
form
.
on
(
'
click
'
,
'
.js-toggle-wip
'
,
this
.
toggleWip
);
this
.
removeWip
();
this
.
titleField
.
on
(
'
keyup blur
'
,
this
.
renderWipExplanation
);
}
else
{
return
this
.
renderWipExplanation
();
this
.
addWip
();
}
}
return
this
.
renderWipExplanation
();
workInProgress
()
{
};
return
this
.
wipRegex
.
test
(
this
.
titleField
.
val
());
}
IssuableForm
.
prototype
.
removeWip
=
function
()
{
return
this
.
titleField
.
val
(
this
.
titleField
.
val
().
replace
(
this
.
wipRegex
,
""
));
renderWipExplanation
()
{
};
if
(
this
.
workInProgress
())
{
this
.
$wipExplanation
.
show
();
IssuableForm
.
prototype
.
addWip
=
function
()
{
return
this
.
$noWipExplanation
.
hide
();
return
this
.
titleField
.
val
(
"
WIP:
"
+
(
this
.
titleField
.
val
()));
}
else
{
};
this
.
$wipExplanation
.
hide
();
return
this
.
$noWipExplanation
.
show
();
return
IssuableForm
;
}
})();
}
}).
call
(
window
);
toggleWip
(
event
)
{
event
.
preventDefault
();
if
(
this
.
workInProgress
())
{
this
.
removeWip
();
}
else
{
this
.
addWip
();
}
return
this
.
renderWipExplanation
();
}
removeWip
()
{
return
this
.
titleField
.
val
(
this
.
titleField
.
val
().
replace
(
this
.
wipRegex
,
''
));
}
addWip
()
{
this
.
titleField
.
val
(
`WIP:
${(
this
.
titleField
.
val
())}
`
);
}
}
app/assets/javascripts/issuable_index.js
View file @
17a35da6
/* eslint-disable no-param-reassign, func-names, no-var, camelcase, no-unused-vars, object-shorthand, space-before-function-paren, no-return-assign, comma-dangle, consistent-return, one-var, one-var-declaration-per-line, quotes, prefer-template, prefer-arrow-callback, wrap-iife, max-len */
/* global IssuableIndex */
import
_
from
'
underscore
'
;
import
IssuableBulkUpdateSidebar
from
'
./issuable_bulk_update_sidebar
'
;
import
IssuableBulkUpdateSidebar
from
'
./issuable_bulk_update_sidebar
'
;
import
IssuableBulkUpdateActions
from
'
./issuable_bulk_update_actions
'
;
import
IssuableBulkUpdateActions
from
'
./issuable_bulk_update_actions
'
;
((
global
)
=>
{
export
default
class
IssuableIndex
{
var
issuable_created
;
constructor
(
pagePrefix
)
{
this
.
initBulkUpdate
(
pagePrefix
);
issuable_created
=
false
;
IssuableIndex
.
resetIncomingEmailToken
();
}
global
.
IssuableIndex
=
{
initBulkUpdate
(
pagePrefix
)
{
init
:
function
(
pagePrefix
)
{
const
userCanBulkUpdate
=
$
(
'
.issues-bulk-update
'
).
length
>
0
;
IssuableIndex
.
initTemplates
();
const
alreadyInitialized
=
!!
this
.
bulkUpdateSidebar
;
IssuableIndex
.
initSearch
();
IssuableIndex
.
initBulkUpdate
(
pagePrefix
);
if
(
userCanBulkUpdate
&&
!
alreadyInitialized
)
{
IssuableIndex
.
initResetFilters
();
IssuableBulkUpdateActions
.
init
({
IssuableIndex
.
resetIncomingEmailToken
();
prefixId
:
pagePrefix
,
IssuableIndex
.
initLabelFilterRemove
();
},
initTemplates
:
function
()
{
return
IssuableIndex
.
labelRow
=
_
.
template
(
'
<% _.each(labels, function(label){ %> <span class="label-row btn-group" role="group" aria-label="<%- label.title %>" style="color: <%- label.text_color %>;"> <a href="#" class="btn btn-transparent has-tooltip" style="background-color: <%- label.color %>;" title="<%- label.description %>" data-container="body"> <%- label.title %> </a> <button type="button" class="btn btn-transparent label-remove js-label-filter-remove" style="background-color: <%- label.color %>;" data-label="<%- label.title %>"> <i class="fa fa-times"></i> </button> </span> <% }); %>
'
);
},
initSearch
:
function
()
{
const
$searchInput
=
$
(
'
#issuable_search
'
);
IssuableIndex
.
initSearchState
(
$searchInput
);
// `immediate` param set to false debounces on the `trailing` edge, lets user finish typing
const
debouncedExecSearch
=
_
.
debounce
(
IssuableIndex
.
executeSearch
,
1000
,
false
);
$searchInput
.
off
(
'
keyup
'
).
on
(
'
keyup
'
,
debouncedExecSearch
);
// ensures existing filters are preserved when manually submitted
$
(
'
#issuable_search_form
'
).
on
(
'
submit
'
,
(
e
)
=>
{
e
.
preventDefault
();
debouncedExecSearch
(
e
);
});
},
initSearchState
:
function
(
$searchInput
)
{
const
currentSearchVal
=
$searchInput
.
val
();
IssuableIndex
.
searchState
=
{
elem
:
$searchInput
,
current
:
currentSearchVal
};
IssuableIndex
.
maybeFocusOnSearch
();
},
accessSearchPristine
:
function
(
set
)
{
// store reference to previous value to prevent search on non-mutating keyup
const
state
=
IssuableIndex
.
searchState
;
const
currentSearchVal
=
state
.
elem
.
val
();
if
(
set
)
{
state
.
current
=
currentSearchVal
;
}
else
{
return
state
.
current
===
currentSearchVal
;
}
},
maybeFocusOnSearch
:
function
()
{
const
currentSearchVal
=
IssuableIndex
.
searchState
.
current
;
if
(
currentSearchVal
&&
currentSearchVal
!==
''
)
{
const
queryLength
=
currentSearchVal
.
length
;
const
$searchInput
=
IssuableIndex
.
searchState
.
elem
;
/* The following ensures that the cursor is initially placed at
* the end of search input when focus is applied. It accounts
* for differences in browser implementations of `setSelectionRange`
* and cursor placement for elements in focus.
*/
$searchInput
.
focus
();
if
(
$searchInput
.
setSelectionRange
)
{
$searchInput
.
setSelectionRange
(
queryLength
,
queryLength
);
}
else
{
$searchInput
.
val
(
currentSearchVal
);
}
}
},
executeSearch
:
function
(
e
)
{
const
$search
=
$
(
'
#issuable_search
'
);
const
$searchName
=
$search
.
attr
(
'
name
'
);
const
$searchValue
=
$search
.
val
();
const
$filtersForm
=
$
(
'
.js-filter-form
'
);
const
$input
=
$
(
`input[name='
${
$searchName
}
']`
,
$filtersForm
);
const
isPristine
=
IssuableIndex
.
accessSearchPristine
();
if
(
isPristine
)
{
return
;
}
if
(
!
$input
.
length
)
{
$filtersForm
.
append
(
`<input type='hidden' name='
${
$searchName
}
' value='
${
_
.
escape
(
$searchValue
)}
'/>`
);
}
else
{
$input
.
val
(
$searchValue
);
}
IssuableIndex
.
filterResults
(
$filtersForm
);
},
initLabelFilterRemove
:
function
()
{
return
$
(
document
).
off
(
'
click
'
,
'
.js-label-filter-remove
'
).
on
(
'
click
'
,
'
.js-label-filter-remove
'
,
function
(
e
)
{
var
$button
;
$button
=
$
(
this
);
// Remove the label input box
$
(
'
input[name="label_name[]"]
'
).
filter
(
function
()
{
return
this
.
value
===
$button
.
data
(
'
label
'
);
}).
remove
();
// Submit the form to get new data
IssuableIndex
.
filterResults
(
$
(
'
.filter-form
'
));
});
},
filterResults
:
(
function
(
_this
)
{
return
function
(
form
)
{
var
formAction
,
formData
,
issuesUrl
;
formData
=
form
.
serializeArray
();
formData
=
formData
.
filter
(
function
(
data
)
{
return
data
.
value
!==
''
;
});
formData
=
$
.
param
(
formData
);
formAction
=
form
.
attr
(
'
action
'
);
issuesUrl
=
formAction
;
issuesUrl
+=
""
+
(
formAction
.
indexOf
(
'
?
'
)
===
-
1
?
'
?
'
:
'
&
'
);
issuesUrl
+=
formData
;
return
gl
.
utils
.
visitUrl
(
issuesUrl
);
};
})(
this
),
initResetFilters
:
function
()
{
$
(
'
.reset-filters
'
).
on
(
'
click
'
,
function
(
e
)
{
e
.
preventDefault
();
const
target
=
e
.
target
;
const
$form
=
$
(
target
).
parents
(
'
.js-filter-form
'
);
const
baseIssuesUrl
=
target
.
href
;
$form
.
attr
(
'
action
'
,
baseIssuesUrl
);
gl
.
utils
.
visitUrl
(
baseIssuesUrl
);
});
});
},
initBulkUpdate
:
function
(
pagePrefix
)
{
const
userCanBulkUpdate
=
$
(
'
.issues-bulk-update
'
).
length
>
0
;
const
alreadyInitialized
=
!!
this
.
bulkUpdateSidebar
;
if
(
userCanBulkUpdate
&&
!
alreadyInitialized
)
{
IssuableBulkUpdateActions
.
init
({
prefixId
:
pagePrefix
,
});
this
.
bulkUpdateSidebar
=
new
IssuableBulkUpdateSidebar
();
}
},
resetIncomingEmailToken
:
function
()
{
$
(
'
.incoming-email-token-reset
'
).
on
(
'
click
'
,
function
(
e
)
{
e
.
preventDefault
();
$
.
ajax
({
this
.
bulkUpdateSidebar
=
new
IssuableBulkUpdateSidebar
();
type
:
'
PUT
'
,
url
:
$
(
'
.incoming-email-token-reset
'
).
attr
(
'
href
'
),
dataType
:
'
json
'
,
success
:
function
(
response
)
{
$
(
'
#issue_email
'
).
val
(
response
.
new_issue_address
).
focus
();
},
beforeSend
:
function
()
{
$
(
'
.incoming-email-token-reset
'
).
text
(
'
resetting...
'
);
},
complete
:
function
()
{
$
(
'
.incoming-email-token-reset
'
).
text
(
'
reset it
'
);
}
});
});
}
}
};
}
})(
window
);
static
resetIncomingEmailToken
()
{
$
(
'
.incoming-email-token-reset
'
).
on
(
'
click
'
,
(
e
)
=>
{
e
.
preventDefault
();
$
.
ajax
({
type
:
'
PUT
'
,
url
:
$
(
'
.incoming-email-token-reset
'
).
attr
(
'
href
'
),
dataType
:
'
json
'
,
success
(
response
)
{
$
(
'
#issue_email
'
).
val
(
response
.
new_issue_address
).
focus
();
},
beforeSend
()
{
$
(
'
.incoming-email-token-reset
'
).
text
(
'
resetting...
'
);
},
complete
()
{
$
(
'
.incoming-email-token-reset
'
).
text
(
'
reset it
'
);
},
});
});
}
}
app/assets/javascripts/main.js
View file @
17a35da6
...
@@ -57,9 +57,7 @@ import './gl_field_error';
...
@@ -57,9 +57,7 @@ import './gl_field_error';
import
'
./gl_field_errors
'
;
import
'
./gl_field_errors
'
;
import
'
./gl_form
'
;
import
'
./gl_form
'
;
import
'
./header
'
;
import
'
./header
'
;
import
'
./importer_status
'
;
import
initImporterStatus
from
'
./importer_status
'
;
import
'
./issuable_index
'
;
import
'
./issuable_context
'
;
import
'
./issuable_form
'
;
import
'
./issuable_form
'
;
import
'
./issue
'
;
import
'
./issue
'
;
import
'
./issue_status_select
'
;
import
'
./issue_status_select
'
;
...
@@ -149,6 +147,7 @@ $(function () {
...
@@ -149,6 +147,7 @@ $(function () {
var
fitSidebarForSize
;
var
fitSidebarForSize
;
initBreadcrumbs
();
initBreadcrumbs
();
initImporterStatus
();
// Set the default path for all cookies to GitLab's root directory
// Set the default path for all cookies to GitLab's root directory
Cookies
.
defaults
.
path
=
gon
.
relative_url_root
||
'
/
'
;
Cookies
.
defaults
.
path
=
gon
.
relative_url_root
||
'
/
'
;
...
...
spec/javascripts/issuable_context_spec.js
View file @
17a35da6
/* global IssuableContext */
import
'
~/issuable_context
'
;
import
$
from
'
jquery
'
;
import
$
from
'
jquery
'
;
import
IssuableContext
from
'
~/issuable_context
'
;
describe
(
'
IssuableContext
'
,
()
=>
{
describe
(
'
IssuableContext
'
,
()
=>
{
describe
(
'
toggleHiddenParticipants
'
,
()
=>
{
describe
(
'
toggleHiddenParticipants
'
,
()
=>
{
...
...
spec/javascripts/issuable_spec.js
View file @
17a35da6
/* global IssuableIndex */
import
IssuableIndex
from
'
~/issuable_index
'
;
import
'
~/lib/utils/url_utility
'
;
describe
(
'
Issuable
'
,
()
=>
{
import
'
~/issuable_index
'
;
let
Issuable
;
describe
(
'
initBulkUpdate
'
,
()
=>
{
(()
=>
{
it
(
'
should not set bulkUpdateSidebar
'
,
()
=>
{
const
BASE_URL
=
'
/user/project/issues?scope=all&state=closed
'
;
Issuable
=
new
IssuableIndex
(
'
issue_
'
);
const
DEFAULT_PARAMS
=
'
&utf8=%E2%9C%93
'
;
expect
(
Issuable
.
bulkUpdateSidebar
).
not
.
toBeDefined
();
function
updateForm
(
formValues
,
form
)
{
$
.
each
(
formValues
,
(
id
,
value
)
=>
{
$
(
`#
${
id
}
`
,
form
).
val
(
value
);
});
}
function
resetForm
(
form
)
{
$
(
'
input[name!="utf8"]
'
,
form
).
each
((
index
,
input
)
=>
{
input
.
setAttribute
(
'
value
'
,
''
);
});
});
}
describe
(
'
Issuable
'
,
()
=>
{
it
(
'
should set bulkUpdateSidebar
'
,
()
=>
{
preloadFixtures
(
'
static/issuable_filter.html.raw
'
);
const
element
=
document
.
createElement
(
'
div
'
);
element
.
classList
.
add
(
'
issues-bulk-update
'
);
document
.
body
.
appendChild
(
element
);
beforeEach
(()
=>
{
Issuable
=
new
IssuableIndex
(
'
issue_
'
);
loadFixtures
(
'
static/issuable_filter.html.raw
'
);
expect
(
Issuable
.
bulkUpdateSidebar
).
toBeDefined
();
IssuableIndex
.
init
();
});
it
(
'
should be defined
'
,
()
=>
{
expect
(
window
.
IssuableIndex
).
toBeDefined
();
});
});
});
describe
(
'
filtering
'
,
()
=>
{
describe
(
'
resetIncomingEmailToken
'
,
()
=>
{
let
$filtersForm
;
beforeEach
(()
=>
{
const
element
=
document
.
createElement
(
'
a
'
);
beforeEach
(()
=>
{
element
.
classList
.
add
(
'
incoming-email-token-reset
'
);
$filtersForm
=
$
(
'
.js-filter-form
'
);
element
.
setAttribute
(
'
href
'
,
'
foo
'
);
loadFixtures
(
'
static/issuable_filter.html.raw
'
);
document
.
body
.
appendChild
(
element
);
resetForm
(
$filtersForm
);
});
it
(
'
should contain only the default parameters
'
,
()
=>
{
spyOn
(
gl
.
utils
,
'
visitUrl
'
);
IssuableIndex
.
filterResults
(
$filtersForm
);
expect
(
gl
.
utils
.
visitUrl
).
toHaveBeenCalledWith
(
BASE_URL
+
DEFAULT_PARAMS
);
});
it
(
'
should filter for the phrase "broken"
'
,
()
=>
{
spyOn
(
gl
.
utils
,
'
visitUrl
'
);
updateForm
({
search
:
'
broken
'
},
$filtersForm
);
IssuableIndex
.
filterResults
(
$filtersForm
);
const
params
=
`
${
DEFAULT_PARAMS
}
&search=broken`
;
expect
(
gl
.
utils
.
visitUrl
).
toHaveBeenCalledWith
(
BASE_URL
+
params
);
});
it
(
'
should keep query parameters after modifying filter
'
,
()
=>
{
spyOn
(
gl
.
utils
,
'
visitUrl
'
);
// initial filter
const
input
=
document
.
createElement
(
'
input
'
);
updateForm
({
milestone_title
:
'
v1.0
'
},
$filtersForm
);
input
.
setAttribute
(
'
id
'
,
'
issue_email
'
);
document
.
body
.
appendChild
(
input
);
IssuableIndex
.
filterResults
(
$filtersForm
);
Issuable
=
new
IssuableIndex
(
'
issue_
'
);
let
params
=
`
${
DEFAULT_PARAMS
}
&milestone_title=v1.0`
;
});
expect
(
gl
.
utils
.
visitUrl
).
toHaveBeenCalledWith
(
BASE_URL
+
params
);
// update filter
it
(
'
should send request to reset email token
'
,
()
=>
{
updateForm
({
label_name
:
'
Frontend
'
},
$filtersForm
);
spyOn
(
jQuery
,
'
ajax
'
).
and
.
callThrough
();
document
.
querySelector
(
'
.incoming-email-token-reset
'
).
click
();
IssuableIndex
.
filterResults
(
$filtersForm
);
expect
(
jQuery
.
ajax
).
toHaveBeenCalled
();
params
=
`
${
DEFAULT_PARAMS
}
&milestone_title=v1.0&label_name=Frontend`
;
expect
(
jQuery
.
ajax
.
calls
.
argsFor
(
0
)[
0
].
url
).
toEqual
(
'
foo
'
);
expect
(
gl
.
utils
.
visitUrl
).
toHaveBeenCalledWith
(
BASE_URL
+
params
);
});
});
});
});
});
})();
});
spec/javascripts/labels_issue_sidebar_spec.js
View file @
17a35da6
/* eslint-disable no-new */
/* eslint-disable no-new */
/* global IssuableContext */
import
IssuableContext
from
'
~/issuable_context
'
;
/* global LabelsSelect */
/* global LabelsSelect */
import
'
~/gl_dropdown
'
;
import
'
~/gl_dropdown
'
;
import
'
select2
'
;
import
'
select2
'
;
import
'
~/api
'
;
import
'
~/api
'
;
import
'
~/create_label
'
;
import
'
~/create_label
'
;
import
'
~/issuable_context
'
;
import
'
~/users_select
'
;
import
'
~/users_select
'
;
import
'
~/labels_select
'
;
import
'
~/labels_select
'
;
...
...
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