Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Tatuya Kamada
gitlab-ce
Commits
1b7eddd8
Commit
1b7eddd8
authored
Mar 24, 2017
by
Alfredo Sumaran
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'refactor-templates-js' into 'master'
Refactor template selector JavaScript See merge request !9792
parents
453d755a
faf7865c
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
425 additions
and
475 deletions
+425
-475
app/assets/javascripts/blob/blob_ci_yaml.js
app/assets/javascripts/blob/blob_ci_yaml.js
+0
-42
app/assets/javascripts/blob/blob_dockerfile_selector.js
app/assets/javascripts/blob/blob_dockerfile_selector.js
+0
-19
app/assets/javascripts/blob/blob_dockerfile_selectors.js
app/assets/javascripts/blob/blob_dockerfile_selectors.js
+0
-27
app/assets/javascripts/blob/blob_file_dropzone.js
app/assets/javascripts/blob/blob_file_dropzone.js
+59
-62
app/assets/javascripts/blob/blob_gitignore_selector.js
app/assets/javascripts/blob/blob_gitignore_selector.js
+0
-23
app/assets/javascripts/blob/blob_gitignore_selectors.js
app/assets/javascripts/blob/blob_gitignore_selectors.js
+0
-26
app/assets/javascripts/blob/blob_license_selector.js
app/assets/javascripts/blob/blob_license_selector.js
+0
-28
app/assets/javascripts/blob/blob_license_selectors.js
app/assets/javascripts/blob/blob_license_selectors.js
+0
-23
app/assets/javascripts/blob/template_selector.js
app/assets/javascripts/blob/template_selector.js
+0
-101
app/assets/javascripts/blob/template_selectors/blob_ci_yaml_selector.js
...ascripts/blob/template_selectors/blob_ci_yaml_selector.js
+9
-0
app/assets/javascripts/blob/template_selectors/blob_ci_yaml_selectors.js
...scripts/blob/template_selectors/blob_ci_yaml_selectors.js
+23
-0
app/assets/javascripts/blob/template_selectors/blob_dockerfile_selector.js
...ripts/blob/template_selectors/blob_dockerfile_selector.js
+9
-0
app/assets/javascripts/blob/template_selectors/blob_dockerfile_selectors.js
...ipts/blob/template_selectors/blob_dockerfile_selectors.js
+23
-0
app/assets/javascripts/blob/template_selectors/blob_gitignore_selector.js
...cripts/blob/template_selectors/blob_gitignore_selector.js
+9
-0
app/assets/javascripts/blob/template_selectors/blob_gitignore_selectors.js
...ripts/blob/template_selectors/blob_gitignore_selectors.js
+23
-0
app/assets/javascripts/blob/template_selectors/blob_license_selector.js
...ascripts/blob/template_selectors/blob_license_selector.js
+13
-0
app/assets/javascripts/blob/template_selectors/blob_license_selectors.js
...scripts/blob/template_selectors/blob_license_selectors.js
+24
-0
app/assets/javascripts/blob/template_selectors/template_selector.js
.../javascripts/blob/template_selectors/template_selector.js
+92
-0
app/assets/javascripts/blob_edit/blob_bundle.js
app/assets/javascripts/blob_edit/blob_bundle.js
+32
-0
app/assets/javascripts/blob_edit/blob_edit_bundle.js
app/assets/javascripts/blob_edit/blob_edit_bundle.js
+0
-15
app/assets/javascripts/blob_edit/edit_blob.js
app/assets/javascripts/blob_edit/edit_blob.js
+94
-83
app/assets/javascripts/main.js
app/assets/javascripts/main.js
+0
-9
app/assets/javascripts/templates/issuable_template_selector.js
...ssets/javascripts/templates/issuable_template_selector.js
+7
-7
app/views/projects/blob/_upload.html.haml
app/views/projects/blob/_upload.html.haml
+3
-6
app/views/projects/blob/edit.html.haml
app/views/projects/blob/edit.html.haml
+1
-1
app/views/projects/blob/new.html.haml
app/views/projects/blob/new.html.haml
+1
-1
config/webpack.config.js
config/webpack.config.js
+1
-1
spec/javascripts/test_bundle.js
spec/javascripts/test_bundle.js
+2
-1
No files found.
app/assets/javascripts/blob/blob_ci_yaml.js
deleted
100644 → 0
View file @
453d755a
/* eslint-disable no-param-reassign, comma-dangle */
/* global Api */
require
(
'
./template_selector
'
);
((
global
)
=>
{
class
BlobCiYamlSelector
extends
gl
.
TemplateSelector
{
requestFile
(
query
)
{
return
Api
.
gitlabCiYml
(
query
.
name
,
this
.
requestFileSuccess
.
bind
(
this
));
}
requestFileSuccess
(
file
)
{
return
super
.
requestFileSuccess
(
file
);
}
}
global
.
BlobCiYamlSelector
=
BlobCiYamlSelector
;
class
BlobCiYamlSelectors
{
constructor
({
editor
,
$dropdowns
}
=
{})
{
this
.
editor
=
editor
;
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-gitlab-ci-yml-selector
'
);
this
.
initSelectors
();
}
initSelectors
()
{
const
editor
=
this
.
editor
;
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
return
new
BlobCiYamlSelector
({
editor
,
pattern
:
/
(
.gitlab-ci.yml
)
/
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-gitlab-ci-yml-selector-wrap
'
),
dropdown
:
$dropdown
});
});
}
}
global
.
BlobCiYamlSelectors
=
BlobCiYamlSelectors
;
})(
window
.
gl
||
(
window
.
gl
=
{}));
app/assets/javascripts/blob/blob_dockerfile_selector.js
deleted
100644 → 0
View file @
453d755a
/* global Api */
require
(
'
./template_selector
'
);
(()
=>
{
const
global
=
window
.
gl
||
(
window
.
gl
=
{});
class
BlobDockerfileSelector
extends
gl
.
TemplateSelector
{
requestFile
(
query
)
{
return
Api
.
dockerfileYml
(
query
.
name
,
this
.
requestFileSuccess
.
bind
(
this
));
}
requestFileSuccess
(
file
)
{
return
super
.
requestFileSuccess
(
file
);
}
}
global
.
BlobDockerfileSelector
=
BlobDockerfileSelector
;
})();
app/assets/javascripts/blob/blob_dockerfile_selectors.js
deleted
100644 → 0
View file @
453d755a
(()
=>
{
const
global
=
window
.
gl
||
(
window
.
gl
=
{});
class
BlobDockerfileSelectors
{
constructor
({
editor
,
$dropdowns
}
=
{})
{
this
.
editor
=
editor
;
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-dockerfile-selector
'
);
this
.
initSelectors
();
}
initSelectors
()
{
const
editor
=
this
.
editor
;
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
return
new
gl
.
BlobDockerfileSelector
({
editor
,
pattern
:
/
(
Dockerfile
)
/
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-dockerfile-selector-wrap
'
),
dropdown
:
$dropdown
,
});
});
}
}
global
.
BlobDockerfileSelectors
=
BlobDockerfileSelectors
;
})();
app/assets/javascripts/blob/blob_file_dropzone.js
View file @
1b7eddd8
/* eslint-disable func-names,
space-before-function-paren, wrap-iife, one-var, no-var, one-var-declaration-per-line, camelcase, object-shorthand, quotes, comma-dangle, prefer-arrow-callback, no-unused-vars, prefer-template, no-useless-escape, no-alert, max-len
*/
/* eslint-disable func-names,
object-shorthand, prefer-arrow-callback
*/
/* global Dropzone */
(
function
()
{
this
.
BlobFileDropzone
=
(
function
()
{
function
BlobFileDropzone
(
form
,
method
)
{
var
dropzone
,
form_dropzone
,
submitButton
;
form_dropzone
=
form
.
find
(
'
.dropzone
'
);
Dropzone
.
autoDiscover
=
false
;
dropzone
=
form_dropzone
.
dropzone
({
autoDiscover
:
false
,
autoProcessQueue
:
false
,
url
:
form
.
attr
(
'
action
'
),
// Rails uses a hidden input field for PUT
// http://stackoverflow.com/questions/21056482/how-to-set-method-put-in-form-tag-in-rails
method
:
method
,
clickable
:
true
,
uploadMultiple
:
false
,
paramName
:
"
file
"
,
maxFilesize
:
gon
.
max_file_size
||
10
,
parallelUploads
:
1
,
maxFiles
:
1
,
addRemoveLinks
:
true
,
previewsContainer
:
'
.dropzone-previews
'
,
headers
:
{
"
X-CSRF-Token
"
:
$
(
"
meta[name=
\"
csrf-token
\"
]
"
).
attr
(
"
content
"
)
},
init
:
function
()
{
this
.
on
(
'
addedfile
'
,
function
(
file
)
{
$
(
'
.dropzone-alerts
'
).
html
(
''
).
hide
();
});
this
.
on
(
'
success
'
,
function
(
header
,
response
)
{
window
.
location
.
href
=
response
.
filePath
;
});
this
.
on
(
'
maxfilesexceeded
'
,
function
(
file
)
{
this
.
removeFile
(
file
);
});
return
this
.
on
(
'
sending
'
,
function
(
file
,
xhr
,
formData
)
{
formData
.
append
(
'
target_branch
'
,
form
.
find
(
'
input[name="target_branch"]
'
).
val
());
formData
.
append
(
'
create_merge_request
'
,
form
.
find
(
'
.js-create-merge-request
'
).
val
());
formData
.
append
(
'
commit_message
'
,
form
.
find
(
'
.js-commit-message
'
).
val
());
});
},
// Override behavior of adding error underneath preview
error
:
function
(
file
,
errorMessage
)
{
var
stripped
;
stripped
=
$
(
"
<div/>
"
).
html
(
errorMessage
).
text
();
$
(
'
.dropzone-alerts
'
).
html
(
'
Error uploading file:
\
"
'
+
stripped
+
'
\
"
'
).
show
();
export
default
class
BlobFileDropzone
{
constructor
(
form
,
method
)
{
const
formDropzone
=
form
.
find
(
'
.dropzone
'
);
Dropzone
.
autoDiscover
=
false
;
const
dropzone
=
formDropzone
.
dropzone
({
autoDiscover
:
false
,
autoProcessQueue
:
false
,
url
:
form
.
attr
(
'
action
'
),
// Rails uses a hidden input field for PUT
// http://stackoverflow.com/questions/21056482/how-to-set-method-put-in-form-tag-in-rails
method
:
method
,
clickable
:
true
,
uploadMultiple
:
false
,
paramName
:
'
file
'
,
maxFilesize
:
gon
.
max_file_size
||
10
,
parallelUploads
:
1
,
maxFiles
:
1
,
addRemoveLinks
:
true
,
previewsContainer
:
'
.dropzone-previews
'
,
headers
:
{
'
X-CSRF-Token
'
:
$
(
'
meta[name="csrf-token"]
'
).
attr
(
'
content
'
),
},
init
:
function
()
{
this
.
on
(
'
addedfile
'
,
function
()
{
$
(
'
.dropzone-alerts
'
).
html
(
''
).
hide
();
});
this
.
on
(
'
success
'
,
function
(
header
,
response
)
{
window
.
location
.
href
=
response
.
filePath
;
});
this
.
on
(
'
maxfilesexceeded
'
,
function
(
file
)
{
this
.
removeFile
(
file
);
}
});
submitButton
=
form
.
find
(
'
#submit-all
'
)[
0
];
submitButton
.
addEventListener
(
'
click
'
,
function
(
e
)
{
e
.
preventDefault
();
e
.
stopPropagation
();
if
(
dropzone
[
0
].
dropzone
.
getQueuedFiles
().
length
===
0
)
{
alert
(
"
Please select a file
"
);
}
dropzone
[
0
].
dropzone
.
processQueue
();
return
false
;
});
}
});
this
.
on
(
'
sending
'
,
function
(
file
,
xhr
,
formData
)
{
formData
.
append
(
'
target_branch
'
,
form
.
find
(
'
input[name="target_branch"]
'
).
val
());
formData
.
append
(
'
create_merge_request
'
,
form
.
find
(
'
.js-create-merge-request
'
).
val
());
formData
.
append
(
'
commit_message
'
,
form
.
find
(
'
.js-commit-message
'
).
val
());
});
},
// Override behavior of adding error underneath preview
error
:
function
(
file
,
errorMessage
)
{
const
stripped
=
$
(
'
<div/>
'
).
html
(
errorMessage
).
text
();
$
(
'
.dropzone-alerts
'
).
html
(
`Error uploading file: "
${
stripped
}
"`
).
show
();
this
.
removeFile
(
file
);
},
});
return
BlobFileDropzone
;
})();
}).
call
(
window
);
const
submitButton
=
form
.
find
(
'
#submit-all
'
)[
0
];
submitButton
.
addEventListener
(
'
click
'
,
function
(
e
)
{
e
.
preventDefault
();
e
.
stopPropagation
();
if
(
dropzone
[
0
].
dropzone
.
getQueuedFiles
().
length
===
0
)
{
// eslint-disable-next-line no-alert
alert
(
'
Please select a file
'
);
}
dropzone
[
0
].
dropzone
.
processQueue
();
return
false
;
});
}
}
app/assets/javascripts/blob/blob_gitignore_selector.js
deleted
100644 → 0
View file @
453d755a
/* eslint-disable func-names, space-before-function-paren, max-len, one-var, no-var, no-restricted-syntax, vars-on-top, no-use-before-define, no-param-reassign, new-cap, no-underscore-dangle, wrap-iife, prefer-rest-params */
/* global Api */
require
(
'
./template_selector
'
);
(
function
()
{
var
extend
=
function
(
child
,
parent
)
{
for
(
var
key
in
parent
)
{
if
(
hasProp
.
call
(
parent
,
key
))
child
[
key
]
=
parent
[
key
];
}
function
ctor
()
{
this
.
constructor
=
child
;
}
ctor
.
prototype
=
parent
.
prototype
;
child
.
prototype
=
new
ctor
();
child
.
__super__
=
parent
.
prototype
;
return
child
;
},
hasProp
=
{}.
hasOwnProperty
;
this
.
BlobGitignoreSelector
=
(
function
(
superClass
)
{
extend
(
BlobGitignoreSelector
,
superClass
);
function
BlobGitignoreSelector
()
{
return
BlobGitignoreSelector
.
__super__
.
constructor
.
apply
(
this
,
arguments
);
}
BlobGitignoreSelector
.
prototype
.
requestFile
=
function
(
query
)
{
return
Api
.
gitignoreText
(
query
.
name
,
this
.
requestFileSuccess
.
bind
(
this
));
};
return
BlobGitignoreSelector
;
})(
gl
.
TemplateSelector
);
}).
call
(
window
);
app/assets/javascripts/blob/blob_gitignore_selectors.js
deleted
100644 → 0
View file @
453d755a
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-unused-expressions, no-cond-assign, no-sequences, comma-dangle, max-len */
/* global BlobGitignoreSelector */
(
function
()
{
this
.
BlobGitignoreSelectors
=
(
function
()
{
function
BlobGitignoreSelectors
(
opts
)
{
var
ref
;
this
.
$dropdowns
=
(
ref
=
opts
.
$dropdowns
)
!=
null
?
ref
:
$
(
'
.js-gitignore-selector
'
),
this
.
editor
=
opts
.
editor
;
this
.
$dropdowns
.
each
((
function
(
_this
)
{
return
function
(
i
,
dropdown
)
{
var
$dropdown
;
$dropdown
=
$
(
dropdown
);
return
new
BlobGitignoreSelector
({
pattern
:
/
(
.gitignore
)
/
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-gitignore-selector-wrap
'
),
dropdown
:
$dropdown
,
editor
:
_this
.
editor
});
};
})(
this
));
}
return
BlobGitignoreSelectors
;
})();
}).
call
(
window
);
app/assets/javascripts/blob/blob_license_selector.js
deleted
100644 → 0
View file @
453d755a
/* eslint-disable func-names, space-before-function-paren, max-len, one-var, no-var, no-restricted-syntax, vars-on-top, no-use-before-define, no-param-reassign, new-cap, no-underscore-dangle, wrap-iife, prefer-rest-params, comma-dangle */
/* global Api */
require
(
'
./template_selector
'
);
(
function
()
{
var
extend
=
function
(
child
,
parent
)
{
for
(
var
key
in
parent
)
{
if
(
hasProp
.
call
(
parent
,
key
))
child
[
key
]
=
parent
[
key
];
}
function
ctor
()
{
this
.
constructor
=
child
;
}
ctor
.
prototype
=
parent
.
prototype
;
child
.
prototype
=
new
ctor
();
child
.
__super__
=
parent
.
prototype
;
return
child
;
},
hasProp
=
{}.
hasOwnProperty
;
this
.
BlobLicenseSelector
=
(
function
(
superClass
)
{
extend
(
BlobLicenseSelector
,
superClass
);
function
BlobLicenseSelector
()
{
return
BlobLicenseSelector
.
__super__
.
constructor
.
apply
(
this
,
arguments
);
}
BlobLicenseSelector
.
prototype
.
requestFile
=
function
(
query
)
{
var
data
;
data
=
{
project
:
this
.
dropdown
.
data
(
'
project
'
),
fullname
:
this
.
dropdown
.
data
(
'
fullname
'
)
};
return
Api
.
licenseText
(
query
.
id
,
data
,
this
.
requestFileSuccess
.
bind
(
this
));
};
return
BlobLicenseSelector
;
})(
gl
.
TemplateSelector
);
}).
call
(
window
);
app/assets/javascripts/blob/blob_license_selectors.js
deleted
100644 → 0
View file @
453d755a
/* eslint-disable no-unused-vars, no-param-reassign */
/* global BlobLicenseSelector */
((
global
)
=>
{
class
BlobLicenseSelectors
{
constructor
({
$dropdowns
,
editor
})
{
this
.
$dropdowns
=
$
(
'
.js-license-selector
'
);
this
.
editor
=
editor
;
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
return
new
BlobLicenseSelector
({
editor
,
pattern
:
/^
(
.+
\/)?(
licen
[
sc
]
e|copying
)(
$|
\.)
/i
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-license-selector-wrap
'
),
dropdown
:
$dropdown
,
});
});
}
}
global
.
BlobLicenseSelectors
=
BlobLicenseSelectors
;
})(
window
.
gl
||
(
window
.
gl
=
{}));
app/assets/javascripts/blob/template_selector.js
deleted
100644 → 0
View file @
453d755a
/* eslint-disable comma-dangle, object-shorthand, func-names, space-before-function-paren, arrow-parens, no-unused-vars, class-methods-use-this, no-var, consistent-return, no-param-reassign, max-len */
((
global
)
=>
{
class
TemplateSelector
{
constructor
({
dropdown
,
data
,
pattern
,
wrapper
,
editor
,
fileEndpoint
,
$input
}
=
{})
{
this
.
onClick
=
this
.
onClick
.
bind
(
this
);
this
.
dropdown
=
dropdown
;
this
.
data
=
data
;
this
.
pattern
=
pattern
;
this
.
wrapper
=
wrapper
;
this
.
editor
=
editor
;
this
.
fileEndpoint
=
fileEndpoint
;
this
.
$input
=
$input
||
$
(
'
#file_name
'
);
this
.
dropdownIcon
=
$
(
'
.fa-chevron-down
'
,
this
.
dropdown
);
this
.
buildDropdown
();
this
.
bindEvents
();
this
.
onFilenameUpdate
();
this
.
autosizeUpdateEvent
=
document
.
createEvent
(
'
Event
'
);
this
.
autosizeUpdateEvent
.
initEvent
(
'
autosize:update
'
,
true
,
false
);
}
buildDropdown
()
{
return
this
.
dropdown
.
glDropdown
({
data
:
this
.
data
,
filterable
:
true
,
selectable
:
true
,
toggleLabel
:
this
.
toggleLabel
,
search
:
{
fields
:
[
'
name
'
]
},
clicked
:
this
.
onClick
,
text
:
function
(
item
)
{
return
item
.
name
;
}
});
}
bindEvents
()
{
return
this
.
$input
.
on
(
'
keyup blur
'
,
(
e
)
=>
this
.
onFilenameUpdate
());
}
toggleLabel
(
item
)
{
return
item
.
name
;
}
onFilenameUpdate
()
{
var
filenameMatches
;
if
(
!
this
.
$input
.
length
)
{
return
;
}
filenameMatches
=
this
.
pattern
.
test
(
this
.
$input
.
val
().
trim
());
if
(
!
filenameMatches
)
{
this
.
wrapper
.
addClass
(
'
hidden
'
);
return
;
}
return
this
.
wrapper
.
removeClass
(
'
hidden
'
);
}
onClick
(
item
,
el
,
e
)
{
e
.
preventDefault
();
return
this
.
requestFile
(
item
);
}
requestFile
(
item
)
{
// This `requestFile` method is an abstract method that should
// be added by all subclasses.
}
// To be implemented on the extending class
// e.g.
// Api.gitignoreText item.name, @requestFileSuccess.bind(@)
requestFileSuccess
(
file
,
{
skipFocus
}
=
{})
{
if
(
!
file
)
return
;
const
oldValue
=
this
.
editor
.
getValue
();
const
newValue
=
file
.
content
;
this
.
editor
.
setValue
(
newValue
,
1
);
if
(
!
skipFocus
)
this
.
editor
.
focus
();
if
(
this
.
editor
instanceof
jQuery
)
{
this
.
editor
.
get
(
0
).
dispatchEvent
(
this
.
autosizeUpdateEvent
);
}
}
startLoadingSpinner
()
{
this
.
dropdownIcon
.
addClass
(
'
fa-spinner fa-spin
'
)
.
removeClass
(
'
fa-chevron-down
'
);
}
stopLoadingSpinner
()
{
this
.
dropdownIcon
.
addClass
(
'
fa-chevron-down
'
)
.
removeClass
(
'
fa-spinner fa-spin
'
);
}
}
global
.
TemplateSelector
=
TemplateSelector
;
})(
window
.
gl
||
(
window
.
gl
=
{}));
app/assets/javascripts/blob/template_selectors/blob_ci_yaml_selector.js
0 → 100644
View file @
1b7eddd8
/* global Api */
import
TemplateSelector
from
'
./template_selector
'
;
export
default
class
BlobCiYamlSelector
extends
TemplateSelector
{
requestFile
(
query
)
{
return
Api
.
gitlabCiYml
(
query
.
name
,
(
file
,
config
)
=>
this
.
setEditorContent
(
file
,
config
));
}
}
app/assets/javascripts/blob/template_selectors/blob_ci_yaml_selectors.js
0 → 100644
View file @
1b7eddd8
/* global Api */
import
BlobCiYamlSelector
from
'
./blob_ci_yaml_selector
'
;
export
default
class
BlobCiYamlSelectors
{
constructor
({
editor
,
$dropdowns
})
{
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-gitlab-ci-yml-selector
'
);
this
.
initSelectors
(
editor
);
}
initSelectors
(
editor
)
{
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
return
new
BlobCiYamlSelector
({
editor
,
pattern
:
/
(
.gitlab-ci.yml
)
/
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-gitlab-ci-yml-selector-wrap
'
),
dropdown
:
$dropdown
,
});
});
}
}
app/assets/javascripts/blob/template_selectors/blob_dockerfile_selector.js
0 → 100644
View file @
1b7eddd8
/* global Api */
import
TemplateSelector
from
'
./template_selector
'
;
export
default
class
BlobDockerfileSelector
extends
TemplateSelector
{
requestFile
(
query
)
{
return
Api
.
dockerfileYml
(
query
.
name
,
(
file
,
config
)
=>
this
.
setEditorContent
(
file
,
config
));
}
}
app/assets/javascripts/blob/template_selectors/blob_dockerfile_selectors.js
0 → 100644
View file @
1b7eddd8
import
BlobDockerfileSelector
from
'
./blob_dockerfile_selector
'
;
export
default
class
BlobDockerfileSelectors
{
constructor
({
editor
,
$dropdowns
})
{
this
.
editor
=
editor
;
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-dockerfile-selector
'
);
this
.
initSelectors
();
}
initSelectors
()
{
const
editor
=
this
.
editor
;
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
return
new
BlobDockerfileSelector
({
editor
,
pattern
:
/
(
Dockerfile
)
/
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-dockerfile-selector-wrap
'
),
dropdown
:
$dropdown
,
});
});
}
}
app/assets/javascripts/blob/template_selectors/blob_gitignore_selector.js
0 → 100644
View file @
1b7eddd8
/* global Api */
import
TemplateSelector
from
'
./template_selector
'
;
export
default
class
BlobGitignoreSelector
extends
TemplateSelector
{
requestFile
(
query
)
{
return
Api
.
gitignoreText
(
query
.
name
,
(
file
,
config
)
=>
this
.
setEditorContent
(
file
,
config
));
}
}
app/assets/javascripts/blob/template_selectors/blob_gitignore_selectors.js
0 → 100644
View file @
1b7eddd8
import
BlobGitignoreSelector
from
'
./blob_gitignore_selector
'
;
export
default
class
BlobGitignoreSelectors
{
constructor
({
editor
,
$dropdowns
})
{
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-gitignore-selector
'
);
this
.
editor
=
editor
;
this
.
initSelectors
();
}
initSelectors
()
{
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
return
new
BlobGitignoreSelector
({
pattern
:
/
(
.gitignore
)
/
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-gitignore-selector-wrap
'
),
dropdown
:
$dropdown
,
editor
:
this
.
editor
,
});
});
}
}
app/assets/javascripts/blob/template_selectors/blob_license_selector.js
0 → 100644
View file @
1b7eddd8
/* global Api */
import
TemplateSelector
from
'
./template_selector
'
;
export
default
class
BlobLicenseSelector
extends
TemplateSelector
{
requestFile
(
query
)
{
const
data
=
{
project
:
this
.
dropdown
.
data
(
'
project
'
),
fullname
:
this
.
dropdown
.
data
(
'
fullname
'
),
};
return
Api
.
licenseText
(
query
.
id
,
data
,
(
file
,
config
)
=>
this
.
setEditorContent
(
file
,
config
));
}
}
app/assets/javascripts/blob/template_selectors/blob_license_selectors.js
0 → 100644
View file @
1b7eddd8
/* eslint-disable no-unused-vars, no-param-reassign */
import
BlobLicenseSelector
from
'
./blob_license_selector
'
;
export
default
class
BlobLicenseSelectors
{
constructor
({
$dropdowns
,
editor
})
{
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-license-selector
'
);
this
.
initSelectors
(
editor
);
}
initSelectors
(
editor
)
{
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
return
new
BlobLicenseSelector
({
editor
,
pattern
:
/^
(
.+
\/)?(
licen
[
sc
]
e|copying
)(
$|
\.)
/i
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-license-selector-wrap
'
),
dropdown
:
$dropdown
,
});
});
}
}
app/assets/javascripts/blob/template_selectors/template_selector.js
0 → 100644
View file @
1b7eddd8
/* eslint-disable class-methods-use-this, no-unused-vars */
export
default
class
TemplateSelector
{
constructor
({
dropdown
,
data
,
pattern
,
wrapper
,
editor
,
$input
}
=
{})
{
this
.
pattern
=
pattern
;
this
.
editor
=
editor
;
this
.
dropdown
=
dropdown
;
this
.
$dropdownContainer
=
wrapper
;
this
.
$filenameInput
=
$input
||
$
(
'
#file_name
'
);
this
.
$dropdownIcon
=
$
(
'
.fa-chevron-down
'
,
dropdown
);
this
.
initDropdown
(
dropdown
,
data
);
this
.
listenForFilenameInput
();
this
.
renderMatchedDropdown
();
this
.
initAutosizeUpdateEvent
();
}
initDropdown
(
dropdown
,
data
)
{
return
$
(
dropdown
).
glDropdown
({
data
,
filterable
:
true
,
selectable
:
true
,
toggleLabel
:
item
=>
item
.
name
,
search
:
{
fields
:
[
'
name
'
],
},
clicked
:
(
item
,
el
,
e
)
=>
this
.
fetchFileTemplate
(
item
,
el
,
e
),
text
:
item
=>
item
.
name
,
});
}
initAutosizeUpdateEvent
()
{
this
.
autosizeUpdateEvent
=
document
.
createEvent
(
'
Event
'
);
this
.
autosizeUpdateEvent
.
initEvent
(
'
autosize:update
'
,
true
,
false
);
}
listenForFilenameInput
()
{
return
this
.
$filenameInput
.
on
(
'
keyup blur
'
,
e
=>
this
.
renderMatchedDropdown
(
e
));
}
renderMatchedDropdown
()
{
if
(
!
this
.
$filenameInput
.
length
)
{
return
null
;
}
const
filenameMatches
=
this
.
pattern
.
test
(
this
.
$filenameInput
.
val
().
trim
());
if
(
!
filenameMatches
)
{
return
this
.
$dropdownContainer
.
addClass
(
'
hidden
'
);
}
return
this
.
$dropdownContainer
.
removeClass
(
'
hidden
'
);
}
fetchFileTemplate
(
item
,
el
,
e
)
{
e
.
preventDefault
();
return
this
.
requestFile
(
item
);
}
requestFile
(
item
)
{
// This `requestFile` method is an abstract method that should
// be added by all subclasses.
}
// To be implemented on the extending class
// e.g. Api.gitlabCiYml(query.name, file => this.setEditorContent(file));
setEditorContent
(
file
,
{
skipFocus
}
=
{})
{
if
(
!
file
)
return
;
const
newValue
=
file
.
content
;
this
.
editor
.
setValue
(
newValue
,
1
);
if
(
!
skipFocus
)
this
.
editor
.
focus
();
if
(
this
.
editor
instanceof
jQuery
)
{
this
.
editor
.
get
(
0
).
dispatchEvent
(
this
.
autosizeUpdateEvent
);
}
}
startLoadingSpinner
()
{
this
.
$dropdownIcon
.
addClass
(
'
fa-spinner fa-spin
'
)
.
removeClass
(
'
fa-chevron-down
'
);
}
stopLoadingSpinner
()
{
this
.
$dropdownIcon
.
addClass
(
'
fa-chevron-down
'
)
.
removeClass
(
'
fa-spinner fa-spin
'
);
}
}
app/assets/javascripts/blob_edit/blob_bundle.js
0 → 100644
View file @
1b7eddd8
/* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, no-var, quotes, vars-on-top, no-unused-vars, no-new, max-len */
/* global EditBlob */
/* global NewCommitForm */
import
EditBlob
from
'
./edit_blob
'
;
import
BlobFileDropzone
from
'
../blob/blob_file_dropzone
'
;
$
(()
=>
{
const
editBlobForm
=
$
(
'
.js-edit-blob-form
'
);
const
uploadBlobForm
=
$
(
'
.js-upload-blob-form
'
);
if
(
editBlobForm
.
length
)
{
const
urlRoot
=
editBlobForm
.
data
(
'
relative-url-root
'
);
const
assetsPath
=
editBlobForm
.
data
(
'
assets-prefix
'
);
const
blobLanguage
=
editBlobForm
.
data
(
'
blob-language
'
);
new
EditBlob
(
`
${
urlRoot
}${
assetsPath
}
`
,
blobLanguage
);
new
NewCommitForm
(
editBlobForm
);
}
if
(
uploadBlobForm
.
length
)
{
const
method
=
uploadBlobForm
.
data
(
'
method
'
);
new
BlobFileDropzone
(
uploadBlobForm
,
method
);
new
NewCommitForm
(
uploadBlobForm
);
window
.
gl
.
utils
.
disableButtonIfEmptyField
(
uploadBlobForm
.
find
(
'
.js-commit-message
'
),
'
.btn-upload-file
'
,
);
}
});
app/assets/javascripts/blob_edit/blob_edit_bundle.js
deleted
100644 → 0
View file @
453d755a
/* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, no-var, quotes, vars-on-top, no-unused-vars, no-new, max-len */
/* global EditBlob */
/* global NewCommitForm */
require
(
'
./edit_blob
'
);
(
function
()
{
$
(
function
()
{
var
url
=
$
(
"
.js-edit-blob-form
"
).
data
(
"
relative-url-root
"
);
url
+=
$
(
"
.js-edit-blob-form
"
).
data
(
"
assets-prefix
"
);
var
blob
=
new
EditBlob
(
url
,
$
(
'
.js-edit-blob-form
'
).
data
(
'
blob-language
'
));
new
NewCommitForm
(
$
(
'
.js-edit-blob-form
'
));
});
}).
call
(
window
);
app/assets/javascripts/blob_edit/edit_blob.js
View file @
1b7eddd8
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, camelcase, no-param-reassign, quotes, prefer-template, no-new, comma-dangle, one-var, one-var-declaration-per-line, prefer-arrow-callback, no-else-return, no-unused-vars, max-len */
/* global ace */
/* global BlobGitignoreSelectors */
(
function
()
{
var
bind
=
function
(
fn
,
me
)
{
return
function
()
{
return
fn
.
apply
(
me
,
arguments
);
};
};
this
.
EditBlob
=
(
function
()
{
function
EditBlob
(
assets_path
,
ace_mode
)
{
if
(
ace_mode
==
null
)
{
ace_mode
=
null
;
}
this
.
editModeLinkClickHandler
=
bind
(
this
.
editModeLinkClickHandler
,
this
);
ace
.
config
.
set
(
"
modePath
"
,
assets_path
+
"
/ace
"
);
ace
.
config
.
loadModule
(
"
ace/ext/searchbox
"
);
this
.
editor
=
ace
.
edit
(
"
editor
"
);
this
.
editor
.
focus
();
if
(
ace_mode
)
{
this
.
editor
.
getSession
().
setMode
(
"
ace/mode/
"
+
ace_mode
);
}
$
(
'
form
'
).
submit
((
function
(
_this
)
{
return
function
()
{
return
$
(
"
#file-content
"
).
val
(
_this
.
editor
.
getValue
());
};
// Before a form submission, move the content from the Ace editor into the
// submitted textarea
})(
this
));
this
.
initModePanesAndLinks
();
this
.
initSoftWrap
();
new
gl
.
BlobLicenseSelectors
({
editor
:
this
.
editor
});
import
BlobLicenseSelectors
from
'
../blob/template_selectors/blob_license_selectors
'
;
import
BlobGitignoreSelectors
from
'
../blob/template_selectors/blob_gitignore_selectors
'
;
import
BlobCiYamlSelectors
from
'
../blob/template_selectors/blob_ci_yaml_selectors
'
;
import
BlobDockerfileSelectors
from
'
../blob/template_selectors/blob_dockerfile_selectors
'
;
export
default
class
EditBlob
{
constructor
(
assetsPath
,
aceMode
)
{
this
.
configureAceEditor
(
aceMode
,
assetsPath
);
this
.
prepFileContentForSubmit
();
this
.
initModePanesAndLinks
();
this
.
initSoftWrap
();
this
.
initFileSelectors
();
}
configureAceEditor
(
aceMode
,
assetsPath
)
{
ace
.
config
.
set
(
'
modePath
'
,
`
${
assetsPath
}
/ace`
);
ace
.
config
.
loadModule
(
'
ace/ext/searchbox
'
);
this
.
editor
=
ace
.
edit
(
'
editor
'
);
this
.
editor
.
focus
();
if
(
aceMode
)
{
this
.
editor
.
getSession
().
setMode
(
`ace/mode/
${
aceMode
}
`
);
}
}
prepFileContentForSubmit
()
{
$
(
'
form
'
).
submit
(()
=>
{
$
(
'
#file-content
'
).
val
(
this
.
editor
.
getValue
());
});
}
initFileSelectors
()
{
this
.
blobTemplateSelectors
=
[
new
BlobLicenseSelectors
({
editor
:
this
.
editor
,
}),
new
BlobGitignoreSelectors
({
editor
:
this
.
editor
});
new
gl
.
BlobCiYamlSelectors
({
editor
:
this
.
editor
});
new
gl
.
BlobDockerfileSelectors
({
editor
:
this
.
editor
editor
:
this
.
editor
,
}),
new
BlobCiYamlSelectors
({
editor
:
this
.
editor
,
}),
new
BlobDockerfileSelectors
({
editor
:
this
.
editor
,
}),
];
}
initModePanesAndLinks
()
{
this
.
$editModePanes
=
$
(
'
.js-edit-mode-pane
'
);
this
.
$editModeLinks
=
$
(
'
.js-edit-mode a
'
);
this
.
$editModeLinks
.
on
(
'
click
'
,
e
=>
this
.
editModeLinkClickHandler
(
e
));
}
editModeLinkClickHandler
(
e
)
{
e
.
preventDefault
();
const
currentLink
=
$
(
e
.
target
);
const
paneId
=
currentLink
.
attr
(
'
href
'
);
const
currentPane
=
this
.
$editModePanes
.
filter
(
paneId
);
this
.
$editModeLinks
.
parent
().
removeClass
(
'
active hover
'
);
currentLink
.
parent
().
addClass
(
'
active hover
'
);
this
.
$editModePanes
.
hide
();
currentPane
.
fadeIn
(
200
);
if
(
paneId
===
'
#preview
'
)
{
this
.
$toggleButton
.
hide
();
return
$
.
post
(
currentLink
.
data
(
'
preview-url
'
),
{
content
:
this
.
editor
.
getValue
(),
},
(
response
)
=>
{
currentPane
.
empty
().
append
(
response
);
return
currentPane
.
renderGFM
();
});
}
EditBlob
.
prototype
.
initModePanesAndLinks
=
function
()
{
this
.
$editModePanes
=
$
(
"
.js-edit-mode-pane
"
);
this
.
$editModeLinks
=
$
(
"
.js-edit-mode a
"
);
return
this
.
$editModeLinks
.
click
(
this
.
editModeLinkClickHandler
);
};
EditBlob
.
prototype
.
editModeLinkClickHandler
=
function
(
event
)
{
var
currentLink
,
currentPane
,
paneId
;
event
.
preventDefault
();
currentLink
=
$
(
event
.
target
);
paneId
=
currentLink
.
attr
(
"
href
"
);
currentPane
=
this
.
$editModePanes
.
filter
(
paneId
);
this
.
$editModeLinks
.
parent
().
removeClass
(
"
active hover
"
);
currentLink
.
parent
().
addClass
(
"
active hover
"
);
this
.
$editModePanes
.
hide
();
currentPane
.
fadeIn
(
200
);
if
(
paneId
===
"
#preview
"
)
{
this
.
$toggleButton
.
hide
();
return
$
.
post
(
currentLink
.
data
(
"
preview-url
"
),
{
content
:
this
.
editor
.
getValue
()
},
function
(
response
)
{
currentPane
.
empty
().
append
(
response
);
return
currentPane
.
renderGFM
();
});
}
else
{
this
.
$toggleButton
.
show
();
return
this
.
editor
.
focus
();
}
};
EditBlob
.
prototype
.
initSoftWrap
=
function
()
{
this
.
isSoftWrapped
=
false
;
this
.
$toggleButton
=
$
(
'
.soft-wrap-toggle
'
);
this
.
$toggleButton
.
on
(
'
click
'
,
this
.
toggleSoftWrap
.
bind
(
this
));
};
EditBlob
.
prototype
.
toggleSoftWrap
=
function
(
e
)
{
this
.
isSoftWrapped
=
!
this
.
isSoftWrapped
;
this
.
$toggleButton
.
toggleClass
(
'
soft-wrap-active
'
,
this
.
isSoftWrapped
);
this
.
editor
.
getSession
().
setUseWrapMode
(
this
.
isSoftWrapped
);
};
return
EditBlob
;
})();
}).
call
(
window
);
this
.
$toggleButton
.
show
();
return
this
.
editor
.
focus
();
}
initSoftWrap
()
{
this
.
isSoftWrapped
=
false
;
this
.
$toggleButton
=
$
(
'
.soft-wrap-toggle
'
);
this
.
$toggleButton
.
on
(
'
click
'
,
()
=>
this
.
toggleSoftWrap
());
}
toggleSoftWrap
()
{
this
.
isSoftWrapped
=
!
this
.
isSoftWrapped
;
this
.
$toggleButton
.
toggleClass
(
'
soft-wrap-active
'
,
this
.
isSoftWrapped
);
this
.
editor
.
getSession
().
setUseWrapMode
(
this
.
isSoftWrapped
);
}
}
app/assets/javascripts/main.js
View file @
1b7eddd8
...
...
@@ -47,15 +47,6 @@ import { installGlEmojiElement } from './behaviors/gl_emoji';
installGlEmojiElement
();
// blob
import
'
./blob/blob_ci_yaml
'
;
import
'
./blob/blob_dockerfile_selector
'
;
import
'
./blob/blob_dockerfile_selectors
'
;
import
'
./blob/blob_file_dropzone
'
;
import
'
./blob/blob_gitignore_selector
'
;
import
'
./blob/blob_gitignore_selectors
'
;
import
'
./blob/blob_license_selector
'
;
import
'
./blob/blob_license_selectors
'
;
import
'
./blob/template_selector
'
;
import
'
./blob/create_branch_dropdown
'
;
import
'
./blob/target_branch_dropdown
'
;
...
...
app/assets/javascripts/templates/issuable_template_selector.js
View file @
1b7eddd8
/* eslint-disable comma-dangle, max-len, no-useless-return, no-param-reassign, max-len */
/* global Api */
require
(
'
../blob/template_selector
'
)
;
import
TemplateSelector
from
'
../blob/template_selectors/template_selector
'
;
((
global
)
=>
{
class
IssuableTemplateSelector
extends
gl
.
TemplateSelector
{
class
IssuableTemplateSelector
extends
TemplateSelector
{
constructor
(...
args
)
{
super
(...
args
);
this
.
projectPath
=
this
.
dropdown
.
data
(
'
project-path
'
);
this
.
namespacePath
=
this
.
dropdown
.
data
(
'
namespace-path
'
);
this
.
issuableType
=
this
.
wrapp
er
.
data
(
'
issuable-type
'
);
this
.
issuableType
=
this
.
$dropdownContain
er
.
data
(
'
issuable-type
'
);
this
.
titleInput
=
$
(
`#
${
this
.
issuableType
}
_title`
);
const
initialQuery
=
{
...
...
@@ -41,16 +41,16 @@ require('../blob/template_selector');
}
setInputValueToTemplateContent
()
{
// `this.
requestFileSuccess
` sets the value of the description input field
// `this.
setEditorContent
` sets the value of the description input field
// to the content of the template selected.
if
(
this
.
titleInput
.
val
()
===
''
)
{
// If the title has not yet been set, focus the title input and
// skip focusing the description input by setting `true` as the
// `skipFocus` option to `
requestFileSuccess
`.
this
.
requestFileSuccess
(
this
.
currentTemplate
,
{
skipFocus
:
true
});
// `skipFocus` option to `
setEditorContent
`.
this
.
setEditorContent
(
this
.
currentTemplate
,
{
skipFocus
:
true
});
this
.
titleInput
.
focus
();
}
else
{
this
.
requestFileSuccess
(
this
.
currentTemplate
,
{
skipFocus
:
false
});
this
.
setEditorContent
(
this
.
currentTemplate
,
{
skipFocus
:
false
});
}
return
;
}
...
...
app/views/projects/blob/_upload.html.haml
View file @
1b7eddd8
...
...
@@ -5,7 +5,7 @@
%a
.close
{
href:
"#"
,
"data-dismiss"
=>
"modal"
}
×
%h3
.page-title
=
title
.modal-body
=
form_tag
form_path
,
method:
method
,
class:
'js-quick-submit js-upload-blob-form form-horizontal'
do
=
form_tag
form_path
,
method:
method
,
class:
'js-quick-submit js-upload-blob-form form-horizontal'
,
data:
{
method:
method
}
do
.dropzone
.dropzone-previews.blob-upload-dropzone-previews
%p
.dz-message.light
...
...
@@ -24,8 +24,5 @@
.inline.prepend-left-10
=
commit_in_fork_help
:javascript
gl
.
utils
.
disableButtonIfEmptyField
(
$
(
'
.js-upload-blob-form
'
).
find
(
'
.js-commit-message
'
),
'
.btn-upload-file
'
);
new
BlobFileDropzone
(
$
(
'
.js-upload-blob-form
'
),
'
#{
method
}
'
);
new
NewCommitForm
(
$
(
'
.js-upload-blob-form
'
))
-
content_for
:page_specific_javascripts
do
=
page_specific_javascript_bundle_tag
(
'blob'
)
app/views/projects/blob/edit.html.haml
View file @
1b7eddd8
...
...
@@ -2,7 +2,7 @@
-
page_title
"Edit"
,
@blob
.
path
,
@ref
-
content_for
:page_specific_javascripts
do
=
page_specific_javascript_tag
(
'lib/ace.js'
)
=
page_specific_javascript_bundle_tag
(
'blob
_edit
'
)
=
page_specific_javascript_bundle_tag
(
'blob'
)
=
render
"projects/commits/head"
%div
{
class:
container_class
}
...
...
app/views/projects/blob/new.html.haml
View file @
1b7eddd8
-
page_title
"New File"
,
@path
.
presence
,
@ref
-
content_for
:page_specific_javascripts
do
=
page_specific_javascript_tag
(
'lib/ace.js'
)
=
page_specific_javascript_bundle_tag
(
'blob
_edit
'
)
=
page_specific_javascript_bundle_tag
(
'blob'
)
%h3
.page-title
New File
...
...
config/webpack.config.js
View file @
1b7eddd8
...
...
@@ -21,7 +21,7 @@ var config = {
common_vue
:
[
'
vue
'
,
'
./vue_shared/common_vue.js
'
],
common_d3
:
[
'
d3
'
],
main
:
'
./main.js
'
,
blob
_edit
:
'
./blob_edit/blob_edit
_bundle.js
'
,
blob
:
'
./blob_edit/blob
_bundle.js
'
,
boards
:
'
./boards/boards_bundle.js
'
,
simulate_drag
:
'
./test_utils/simulate_drag.js
'
,
cycle_analytics
:
'
./cycle_analytics/cycle_analytics_bundle.js
'
,
...
...
spec/javascripts/test_bundle.js
View file @
1b7eddd8
...
...
@@ -35,7 +35,8 @@ testsContext.keys().forEach(function (path) {
if
(
process
.
env
.
BABEL_ENV
===
'
coverage
'
)
{
// exempt these files from the coverage report
const
troubleMakers
=
[
'
./blob_edit/blob_edit_bundle.js
'
,
'
./blob_edit/blob_bundle.js
'
,
'
./boards/boards_bundle.js
'
,
'
./cycle_analytics/components/stage_plan_component.js
'
,
'
./cycle_analytics/components/stage_staging_component.js
'
,
'
./cycle_analytics/components/stage_test_component.js
'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment