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
81e741af
Commit
81e741af
authored
Sep 14, 2015
by
Stan Hu
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9138 from liyakun/master
add "replace" and "upload" functionality
parents
c99473e5
e2ece2bc
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
273 additions
and
11 deletions
+273
-11
CHANGELOG
CHANGELOG
+1
-0
app/assets/javascripts/blob/blob_file_dropzone.js.coffee
app/assets/javascripts/blob/blob_file_dropzone.js.coffee
+52
-0
app/assets/stylesheets/pages/tree.scss
app/assets/stylesheets/pages/tree.scss
+12
-0
app/controllers/projects/blob_controller.rb
app/controllers/projects/blob_controller.rb
+24
-4
app/services/files/create_service.rb
app/services/files/create_service.rb
+2
-0
app/views/projects/blob/_actions.html.haml
app/views/projects/blob/_actions.html.haml
+3
-3
app/views/projects/blob/_replace.html.haml
app/views/projects/blob/_replace.html.haml
+28
-0
app/views/projects/blob/_upload.html.haml
app/views/projects/blob/_upload.html.haml
+28
-0
app/views/projects/blob/new.html.haml
app/views/projects/blob/new.html.haml
+8
-2
app/views/projects/blob/show.html.haml
app/views/projects/blob/show.html.haml
+1
-0
config/routes.rb
config/routes.rb
+10
-0
features/project/source/browse_files.feature
features/project/source/browse_files.feature
+23
-0
features/steps/project/source/browse_files.rb
features/steps/project/source/browse_files.rb
+81
-2
No files found.
CHANGELOG
View file @
81e741af
...
...
@@ -3,6 +3,7 @@ Please view this file on the master branch, on stable branches it's out of date.
v 8.0.0 (unreleased)
- Bump rouge to 1.10.1 to remove warning noise and fix other syntax highlighting bugs (Stan Hu)
- Gracefully handle errors in syntax highlighting by leaving the block unformatted (Stan Hu)
- Add "replace" and "upload" functionalities to allow user replace existing file and upload new file into current repository
- Fix URL construction for merge requests, issues, notes, and commits for relative URL config (Stan Hu)
- Fix emoji URLs in Markdown when relative_url_root is used (Stan Hu)
- Omit filename in Content-Disposition header in raw file download to avoid RFC 6266 encoding issues (Stan HU)
...
...
app/assets/javascripts/blob/blob_file_dropzone.js.coffee
0 → 100644
View file @
81e741af
class
@
BlobFileDropzone
constructor
:
(
form
,
method
)
->
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
or
10
parallelUploads
:
1
maxFiles
:
1
addRemoveLinks
:
true
previewsContainer
:
'.dropzone-previews'
headers
:
"X-CSRF-Token"
:
$
(
"meta[name=
\"
csrf-token
\"
]"
).
attr
(
"content"
)
success
:
(
header
,
response
)
->
window
.
location
.
href
=
response
.
filePath
return
error
:
(
temp
,
errorMessage
)
->
stripped
=
$
(
"<div/>"
).
html
(
errorMessage
).
text
();
$
(
'.dropzone-alerts'
).
html
(
'Error uploading file:
\"
'
+
stripped
+
'
\"
'
).
show
()
return
maxfilesexceeded
:
(
file
)
->
@
removeFile
file
return
removedfile
:
(
file
)
->
$
(
'.dropzone-previews'
)[
0
].
removeChild
(
file
.
previewTemplate
)
$
(
'.dropzone-alerts'
).
html
(
''
).
hide
()
return
true
sending
:
(
file
,
xhr
,
formData
)
->
formData
.
append
(
'commit_message'
,
form
.
find
(
'#commit_message'
).
val
())
return
)
submitButton
=
form
.
find
(
'#submit-all'
)[
0
]
submitButton
.
addEventListener
'click'
,
(
e
)
->
e
.
preventDefault
()
e
.
stopPropagation
()
alert
"Please select a file"
if
dropzone
[
0
].
dropzone
.
getQueuedFiles
().
length
==
0
dropzone
[
0
].
dropzone
.
processQueue
()
return
false
app/assets/stylesheets/pages/tree.scss
View file @
81e741af
...
...
@@ -116,3 +116,15 @@
}
#modal-remove-blob
>
.modal-dialog
{
width
:
850px
;
}
.blob-upload-dropzone-previews
{
text-align
:
center
;
border
:
2px
;
border-style
:
dashed
;
min-height
:
200px
;
}
.upload-link
{
font-weight
:
normal
;
color
:
#0000EE
;
}
app/controllers/projects/blob_controller.rb
View file @
81e741af
...
...
@@ -26,10 +26,16 @@ class Projects::BlobController < Projects::ApplicationController
if
result
[
:status
]
==
:success
flash
[
:notice
]
=
"Your changes have been successfully committed"
redirect_to
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
File
.
join
(
@target_branch
,
@file_path
))
respond_to
do
|
format
|
format
.
html
{
redirect_to
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
File
.
join
(
@target_branch
,
@file_path
))
}
format
.
json
{
render
json:
{
message:
"success"
,
filePath:
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
File
.
join
(
@target_branch
,
@file_path
))
}
}
end
else
flash
[
:alert
]
=
result
[
:message
]
render
:new
respond_to
do
|
format
|
format
.
html
{
render
:new
}
format
.
json
{
render
json:
{
message:
"failed"
,
filePath:
namespace_project_new_blob_path
(
@project
.
namespace
,
@project
,
@id
)
}
}
end
end
end
...
...
@@ -45,10 +51,16 @@ class Projects::BlobController < Projects::ApplicationController
if
result
[
:status
]
==
:success
flash
[
:notice
]
=
"Your changes have been successfully committed"
redirect_to
after_edit_path
respond_to
do
|
format
|
format
.
html
{
redirect_to
after_edit_path
}
format
.
json
{
render
json:
{
message:
"success"
,
filePath:
after_edit_path
}
}
end
else
flash
[
:alert
]
=
result
[
:message
]
render
:edit
respond_to
do
|
format
|
format
.
html
{
render
:edit
}
format
.
json
{
render
json:
{
message:
"failed"
,
filePath:
namespace_project_new_blob_path
(
@project
.
namespace
,
@project
,
@id
)
}
}
end
end
end
...
...
@@ -146,11 +158,19 @@ class Projects::BlobController < Projects::ApplicationController
@file_path
=
if
action_name
.
to_s
==
'create'
if
params
[
:file
].
present?
params
[
:file_name
]
=
params
[
:file
].
original_filename
end
File
.
join
(
@path
,
File
.
basename
(
params
[
:file_name
]))
else
@path
end
if
params
[
:file
].
present?
params
[
:content
]
=
Base64
.
encode64
(
params
[
:file
].
read
)
params
[
:encoding
]
=
'base64'
end
@commit_params
=
{
file_path:
@file_path
,
current_branch:
@current_branch
,
...
...
app/services/files/create_service.rb
View file @
81e741af
...
...
@@ -19,6 +19,8 @@ module Files
end
unless
project
.
empty_repo?
@file_path
.
slice!
(
0
)
if
@file_path
.
start_with?
(
'/'
)
blob
=
repository
.
blob_at_branch
(
@current_branch
,
@file_path
)
if
blob
...
...
app/views/projects/blob/_actions.html.haml
View file @
81e741af
...
...
@@ -17,6 +17,6 @@
tree_join
(
@commit
.
sha
,
@path
)),
class:
'btn btn-sm'
-
if
allowed_tree_edit?
=
button_tag
class:
'remove-blob btn btn-sm btn-remove'
,
'data-toggle'
=>
'modal'
,
'data-target'
=>
'#modal-remove-blob'
do
Remove
.btn-group
{
:role
=>
"group"
}
%button
.btn.btn-default
{
class:
'btn-primary'
,
href:
'#modal-replace-blob'
,
'data-target'
=>
'#modal-replace-blob'
,
'data-toggle'
=>
'modal'
}
Replace
%button
.btn.btn-default
{
class:
'btn-remove'
,
href:
'#modal-remove-blob'
,
'data-target'
=>
'#modal-remove-blob'
,
'data-toggle'
=>
'modal'
}
Remove
app/views/projects/blob/_replace.html.haml
0 → 100644
View file @
81e741af
#modal-replace-blob
.modal
.modal-dialog
.modal-content
.modal-header
%a
.close
{
href:
"#"
,
"data-dismiss"
=>
"modal"
}
×
%h3
.page-title
Replace
#{
@blob
.
name
}
%p
.light
From branch
%strong
=
@ref
.modal-body
=
form_tag
namespace_project_update_blob_path
(
@project
.
namespace
,
@project
,
@id
),
method: :put
,
class:
'blob-file-upload-form-js form-horizontal'
do
.dropzone
.dropzone-previews
{
class:
"blob-upload-dropzone-previews"
}
%p
.dz-message
{
class:
"hint"
}
<
Attach
files
by
dragging
&
dropping
or
&
nbsp
;
%a
{
href:
'#'
,
class:
"markdown-selector"
}
>
click to upload
%br
.dropzone-alerts
{
class:
"alert alert-danger data"
,
"data-dismiss"
=>
"alert"
,
style:
"display:none"
}
=
render
'shared/commit_message_container'
,
params:
params
,
placeholder:
'Replace this file because...'
.form-group
.col-sm-offset-2.col-sm-10
=
button_tag
'Replace file'
,
class:
'btn btn-small btn-primary btn-replace-file'
,
id:
'submit-all'
=
link_to
"Cancel"
,
'#'
,
class:
"btn btn-cancel"
,
"data-dismiss"
=>
"modal"
:coffeescript
disableButtonIfEmptyField $('.blob-file-upload-form-js').find('#commit_message'), '.btn-replace-file'
new BlobFileDropzone($('.blob-file-upload-form-js'), 'put')
app/views/projects/blob/_upload.html.haml
0 → 100644
View file @
81e741af
#modal-upload-blob
.modal
.modal-dialog
.modal-content
.modal-header
%a
.close
{
href:
"#"
,
"data-dismiss"
=>
"modal"
}
×
%h3
.page-title
Upload
%p
.light
From branch
%strong
=
@ref
.modal-body
=
form_tag
namespace_project_create_blob_path
(
@project
.
namespace
,
@project
,
@id
),
method: :post
,
class:
'blob-file-upload-form-js form-horizontal'
do
.dropzone
.dropzone-previews
{
class:
"blob-upload-dropzone-previews"
}
%p
.dz-message
{
class:
"hint"
}
<
Attach
files
by
dragging
&
dropping
or
&
nbsp
;
%a
{
href:
'#'
,
class:
"markdown-selector"
}
>
click to upload
%br
.dropzone-alerts
{
class:
"alert alert-danger data"
,
"data-dismiss"
=>
"alert"
,
style:
"display:none"
}
=
render
'shared/commit_message_container'
,
params:
params
,
placeholder:
'Upload this file because...'
.form-group
.col-sm-offset-2.col-sm-10
=
button_tag
'Upload file'
,
class:
'btn btn-small btn-primary btn-upload-file'
,
id:
'submit-all'
=
link_to
"Cancel"
,
'#'
,
class:
"btn btn-cancel"
,
"data-dismiss"
=>
"modal"
:coffeescript
disableButtonIfEmptyField $('.blob-file-upload-form-js').find('#commit_message'), '.btn-upload-file'
new BlobFileDropzone($('.blob-file-upload-form-js'), 'post')
app/views/projects/blob/new.html.haml
View file @
81e741af
-
page_title
"New File"
,
@ref
%h3
.page-title
New file
%h3
.page-title
<
Create
new
file
or
&
nbsp
;
%a
.upload-link
{
href:
'#modal-upload-blob'
,
'data-target'
=>
'#modal-upload-blob'
,
'data-toggle'
=>
'modal'
}
>
upload existing one
.file-title
=
render
'projects/blob/upload'
%br
.file-editor
=
form_tag
(
namespace_project_create_blob_path
(
@project
.
namespace
,
@project
,
@id
),
method: :post
,
class:
'form-horizontal form-new-file js-requires-input'
)
do
=
render
'projects/blob/editor'
,
ref:
@ref
...
...
app/views/projects/blob/show.html.haml
View file @
81e741af
...
...
@@ -10,3 +10,4 @@
-
if
allowed_tree_edit?
=
render
'projects/blob/remove'
=
render
'projects/blob/replace'
config/routes.rb
View file @
81e741af
...
...
@@ -358,6 +358,16 @@ Gitlab::Application.routes.draw do
to:
'blob#destroy'
,
constraints:
{
id:
/.+/
,
format:
false
}
)
put
(
'/blob/*id'
,
to:
'blob#update'
,
constraints:
{
id:
/.+/
,
format:
false
}
)
post
(
'/blob/*id'
,
to:
'blob#create'
,
constraints:
{
id:
/.+/
,
format:
false
}
)
end
scope
do
...
...
features/project/source/browse_files.feature
View file @
81e741af
...
...
@@ -33,6 +33,29 @@ Feature: Project Source Browse Files
And
I click on
"Commit Changes"
Then
I am redirected to the new file
And
I should see its new content
@javascript
Scenario
:
I
can upload file and commit
Given
I click on
"new file"
link in repo
Then
I can see new file page
And
I can see
"upload existing one"
And
I click on
"upload existing one"
And
I upload a new text file
And
I fill the upload file commit message
And
I click on
"Upload file"
Then
I can see the new text file
And
I can see the new commit message
@javascript
Scenario
:
I
can replace file and commit
Given
I click on
".gitignore"
file in repo
And
I see the
".gitignore"
And
I click on
"Replace"
And
I replace it with a text file
And
I fill the replace file commit message
And
I click on
"Replace file"
Then
I can see the new text file
And
I can see the replacement commit message
@javascript
Scenario
:
I
can create and commit file and specify new branch
...
...
features/steps/project/source/browse_files.rb
View file @
81e741af
# coding: utf-8
class
Spinach::Features::ProjectSourceBrowseFiles
<
Spinach
::
FeatureSteps
include
SharedAuthentication
include
SharedProject
...
...
@@ -78,7 +79,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
end
step
'I fill the commit message'
do
fill_in
:commit_message
,
with:
'Not yet a commit message.'
fill_in
:commit_message
,
with:
'Not yet a commit message.'
,
visible:
true
end
step
'I click link "Diff"'
do
...
...
@@ -97,6 +98,14 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
click_button
'Remove file'
end
step
'I click on "Replace"'
do
click_button
"Replace"
end
step
'I click on "Replace file"'
do
click_button
'Replace file'
end
step
'I see diff'
do
expect
(
page
).
to
have_css
'.line_holder.new'
end
...
...
@@ -106,10 +115,55 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
end
step
'I can see new file page'
do
expect
(
page
).
to
have_content
"
N
ew file"
expect
(
page
).
to
have_content
"
n
ew file"
expect
(
page
).
to
have_content
"Commit message"
end
step
'I can see "upload existing one"'
do
expect
(
page
).
to
have_content
"upload existing one"
end
step
'I click on "upload existing one"'
do
click_link
'upload existing one'
end
step
'I click on "Upload file"'
do
click_button
'Upload file'
end
step
'I can see the new commit message'
do
expect
(
page
).
to
have_content
"New upload commit message"
end
step
'I upload a new text file'
do
drop_in_dropzone
test_text_file
end
step
'I fill the upload file commit message'
do
page
.
within
(
'#modal-upload-blob'
)
do
fill_in
:commit_message
,
with:
'New upload commit message'
end
end
step
'I replace it with a text file'
do
drop_in_dropzone
test_text_file
end
step
'I fill the replace file commit message'
do
page
.
within
(
'#modal-replace-blob'
)
do
fill_in
:commit_message
,
with:
'Replacement file commit message'
end
end
step
'I can see the replacement commit message'
do
expect
(
page
).
to
have_content
"Replacement file commit message"
end
step
'I can see the new text file'
do
expect
(
page
).
to
have_content
"Lorem ipsum dolor sit amet"
expect
(
page
).
to
have_content
"Sed ut perspiciatis unde omnis"
end
step
'I click on files directory'
do
click_link
'files'
end
...
...
@@ -232,4 +286,29 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
def
new_file_name
'not_a_file.md'
end
def
drop_in_dropzone
(
file_path
)
# Generate a fake input selector
page
.
execute_script
<<-
JS
var fakeFileInput = window.$('<input/>').attr(
{id: 'fakeFileInput', type: 'file'}
).appendTo('body');
JS
# Attach the file to the fake input selector with Capybara
attach_file
(
"fakeFileInput"
,
file_path
)
# Add the file to a fileList array and trigger the fake drop event
page
.
execute_script
<<-
JS
var fileList = [$('#fakeFileInput')[0].files[0]];
var e = jQuery.Event('drop', { dataTransfer : { files : fileList } });
$('.dropzone')[0].dropzone.listeners[0].events.drop(e);
JS
end
def
test_text_file
File
.
join
(
Rails
.
root
,
'spec'
,
'fixtures'
,
'doc_sample.txt'
)
end
def
test_image_file
File
.
join
(
Rails
.
root
,
'spec'
,
'fixtures'
,
'banana_sample.gif'
)
end
end
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