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
Léo-Paul Géneau
gitlab-ce
Commits
5b0e0869
Commit
5b0e0869
authored
May 16, 2017
by
blackst0ne
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add an ability to cancel attaching file and redesign attaching files UI
parent
20987f4f
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
330 additions
and
117 deletions
+330
-117
app/assets/javascripts/dropzone_input.js
app/assets/javascripts/dropzone_input.js
+158
-94
app/assets/stylesheets/pages/note_form.scss
app/assets/stylesheets/pages/note_form.scss
+43
-0
app/helpers/icons_helper.rb
app/helpers/icons_helper.rb
+3
-2
app/views/shared/notes/_hints.html.haml
app/views/shared/notes/_hints.html.haml
+24
-3
changelogs/unreleased/add_ability_to_cancel_attaching_file_and_redesign_attaching_files_ui.yml
...cancel_attaching_file_and_redesign_attaching_files_ui.yml
+4
-0
spec/features/uploads/user_uploads_file_to_note_spec.rb
spec/features/uploads/user_uploads_file_to_note_spec.rb
+68
-8
spec/support/dropzone_helper.rb
spec/support/dropzone_helper.rb
+30
-10
No files found.
app/assets/javascripts/dropzone_input.js
View file @
5b0e0869
This diff is collapsed.
Click to expand it.
app/assets/stylesheets/pages/note_form.scss
View file @
5b0e0869
...
@@ -277,6 +277,7 @@
...
@@ -277,6 +277,7 @@
.toolbar-text
{
.toolbar-text
{
font-size
:
14px
;
font-size
:
14px
;
line-height
:
16px
;
line-height
:
16px
;
margin-top
:
2px
;
@media
(
min-width
:
$screen-md-min
)
{
@media
(
min-width
:
$screen-md-min
)
{
float
:
left
;
float
:
left
;
...
@@ -402,3 +403,45 @@
...
@@ -402,3 +403,45 @@
}
}
}
}
}
}
.uploading-container
{
float
:
right
;
@media
(
max-width
:
$screen-xs-max
)
{
float
:
left
;
margin-top
:
5px
;
}
}
.uploading-error-icon
,
.uploading-error-message
{
color
:
$gl-text-red
;
}
.uploading-error-message
{
@media
(
max-width
:
$screen-xs-max
)
{
&
:
:
after
{
content
:
"\a"
;
white-space
:
pre
;
}
}
}
.uploading-progress
{
margin-right
:
5px
;
}
.attach-new-file
,
.button-attach-file
,
.retry-uploading-link
{
color
:
$gl-link-color
;
padding
:
0
;
background
:
none
;
border
:
0
;
font-size
:
14px
;
line-height
:
16px
;
}
.markdown-selector
{
color
:
$gl-link-color
;
}
app/helpers/icons_helper.rb
View file @
5b0e0869
...
@@ -7,9 +7,10 @@ module IconsHelper
...
@@ -7,9 +7,10 @@ module IconsHelper
# font-awesome-rails gem, but should we ever use a different icon pack in the
# font-awesome-rails gem, but should we ever use a different icon pack in the
# future we won't have to change hundreds of method calls.
# future we won't have to change hundreds of method calls.
def
icon
(
names
,
options
=
{})
def
icon
(
names
,
options
=
{})
if
(
options
.
keys
&
%w[aria-hidden aria-label]
).
empty?
if
(
options
.
keys
&
%w[aria-hidden aria-label
data-hidden
]
).
empty?
# Add
`aria-hidden` if there are no aria's set
# Add
'aria-hidden' and 'data-hidden' if they are not set in options.
options
[
'aria-hidden'
]
=
true
options
[
'aria-hidden'
]
=
true
options
[
'data-hidden'
]
=
true
end
end
options
.
include?
(
:base
)
?
fa_stacked_icon
(
names
,
options
)
:
fa_icon
(
names
,
options
)
options
.
include?
(
:base
)
?
fa_stacked_icon
(
names
,
options
)
:
fa_icon
(
names
,
options
)
...
...
app/views/shared/notes/_hints.html.haml
View file @
5b0e0869
...
@@ -9,6 +9,27 @@
...
@@ -9,6 +9,27 @@
-
else
-
else
is
is
supported
supported
%button
.toolbar-button.markdown-selector
{
type:
'button'
,
tabindex:
'-1'
}
=
icon
(
'file-image-o'
,
class:
'toolbar-button-icon'
)
%span
.uploading-container
Attach a file
%span
.uploading-progress-container.hide
=
icon
(
'file-image-o'
,
class:
'toolbar-button-icon'
)
%span
.attaching-file-message
-# Populated by app/assets/javascripts/dropzone_input.js
%span
.uploading-progress
0%
%span
.uploading-spinner
=
icon
(
'spinner spin'
,
class:
'toolbar-button-icon'
)
%span
.uploading-error-container.hide
%span
.uploading-error-icon
=
icon
(
'file-image-o'
,
class:
'toolbar-button-icon'
)
%span
.uploading-error-message
-# Populated by app/assets/javascripts/dropzone_input.js
%button
.retry-uploading-link
{
type:
'button'
}
Try again
or
%button
.attach-new-file.markdown-selector
{
type:
'button'
}
attach a new file
%button
.markdown-selector.button-attach-file
{
type:
'button'
,
tabindex:
'-1'
}
=
icon
(
'file-image-o'
,
class:
'toolbar-button-icon'
)
Attach a file
%button
.btn.btn-default.btn-xs.hide.button-cancel-uploading-files
{
type:
'button'
}
Cancel
changelogs/unreleased/add_ability_to_cancel_attaching_file_and_redesign_attaching_files_ui.yml
0 → 100644
View file @
5b0e0869
---
title
:
Add an ability to cancel attaching file and redesign attaching files UI
merge_request
:
9431
author
:
blackst0ne
spec/features/uploads/user_uploads_file_to_note_spec.rb
View file @
5b0e0869
...
@@ -5,18 +5,78 @@ feature 'User uploads file to note', feature: true do
...
@@ -5,18 +5,78 @@ feature 'User uploads file to note', feature: true do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:empty_project
,
creator:
user
,
namespace:
user
.
namespace
)
}
let
(
:project
)
{
create
(
:empty_project
,
creator:
user
,
namespace:
user
.
namespace
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
,
author:
user
)
}
scenario
'they see the attached file'
,
js:
true
do
before
do
issue
=
create
(
:issue
,
project:
project
,
author:
user
)
login_as
(
user
)
login_as
(
user
)
visit
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
visit
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
end
context
'before uploading'
do
it
'shows "Attach a file" button'
,
js:
true
do
expect
(
page
).
to
have_button
(
'Attach a file'
)
expect
(
page
).
not_to
have_selector
(
'.uploading-progress-container'
,
visible:
true
)
end
end
context
'uploading is in progress'
do
it
'shows "Cancel" button on uploading'
,
js:
true
do
dropzone_file
([
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'dk.png'
)],
0
,
false
)
expect
(
page
).
to
have_button
(
'Cancel'
)
end
it
'cancels uploading on clicking to "Cancel" button'
,
js:
true
do
dropzone_file
([
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'dk.png'
)],
0
,
false
)
click_button
'Cancel'
expect
(
page
).
to
have_button
(
'Attach a file'
)
expect
(
page
).
not_to
have_button
(
'Cancel'
)
expect
(
page
).
not_to
have_selector
(
'.uploading-progress-container'
,
visible:
true
)
end
it
'shows "Attaching a file" message on uploading 1 file'
,
js:
true
do
dropzone_file
([
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'dk.png'
)],
0
,
false
)
expect
(
page
).
to
have_selector
(
'.attaching-file-message'
,
visible:
true
,
text:
'Attaching a file -'
)
end
it
'shows "Attaching 2 files" message on uploading 2 file'
,
js:
true
do
dropzone_file
([
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'video_sample.mp4'
),
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'dk.png'
)],
0
,
false
)
expect
(
page
).
to
have_selector
(
'.attaching-file-message'
,
visible:
true
,
text:
'Attaching 2 files -'
)
end
it
'shows error message, "retry" and "attach a new file" link a if file is too big'
,
js:
true
do
dropzone_file
([
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'video_sample.mp4'
)],
0.01
)
error_text
=
'File is too big (0.06MiB). Max filesize: 0.01MiB.'
expect
(
page
).
to
have_selector
(
'.uploading-error-message'
,
visible:
true
,
text:
error_text
)
expect
(
page
).
to
have_selector
(
'.retry-uploading-link'
,
visible:
true
,
text:
'Try again'
)
expect
(
page
).
to
have_selector
(
'.attach-new-file'
,
visible:
true
,
text:
'attach a new file'
)
expect
(
page
).
not_to
have_button
(
'Attach a file'
)
end
end
context
'uploading is complete'
do
it
'shows "Attach a file" button on uploading complete'
,
js:
true
do
dropzone_file
([
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'dk.png'
)])
wait_for_ajax
expect
(
page
).
to
have_button
(
'Attach a file'
)
expect
(
page
).
not_to
have_selector
(
'.uploading-progress-container'
,
visible:
true
)
end
dropzone_file
(
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'dk.png'
))
scenario
'they see the attached file'
,
js:
true
do
click_button
'Comment'
dropzone_file
([
Rails
.
root
.
join
(
'spec'
,
'fixtures'
,
'dk.png'
)])
wait_for_ajax
click_button
'Comment'
wait_for_ajax
expect
(
find
(
'a.no-attachment-icon img[alt="dk"]'
)[
'src'
])
expect
(
find
(
'a.no-attachment-icon img[alt="dk"]'
)[
'src'
])
.
to
match
(
%r{/
#{
project
.
full_path
}
/uploads/
\h
{32}/dk
\.
png$}
)
.
to
match
(
%r{/
#{
project
.
full_path
}
/uploads/
\h
{32}/dk
\.
png$}
)
end
end
end
end
end
spec/support/dropzone_helper.rb
View file @
5b0e0869
...
@@ -6,32 +6,52 @@ module DropzoneHelper
...
@@ -6,32 +6,52 @@ module DropzoneHelper
# Dropzone events to perform the actual upload.
# Dropzone events to perform the actual upload.
#
#
# This method waits for the upload to complete before returning.
# This method waits for the upload to complete before returning.
def
dropzone_file
(
file_path
)
# max_file_size is an optional parameter.
# If it's not 0, then it used in dropzone.maxFilesize parameter.
# wait_for_queuecomplete is an optional parameter.
# If it's 'false', then the helper will NOT wait for backend response
# It lets to test behaviors while AJAX is processing.
def
dropzone_file
(
files
,
max_file_size
=
0
,
wait_for_queuecomplete
=
true
)
# Generate a fake file input that Capybara can attach to
# Generate a fake file input that Capybara can attach to
page
.
execute_script
<<-
JS
.
strip_heredoc
page
.
execute_script
<<-
JS
.
strip_heredoc
$('#fakeFileInput').remove();
var fakeFileInput = window.$('<input/>').attr(
var fakeFileInput = window.$('<input/>').attr(
{id: 'fakeFileInput', type: 'file'}
{id: 'fakeFileInput', type: 'file'
, multiple: true
}
).appendTo('body');
).appendTo('body');
window._dropzoneComplete = false;
window._dropzoneComplete = false;
JS
JS
# Attach
the file
to the fake input selector with Capybara
# Attach
files
to the fake input selector with Capybara
attach_file
(
'fakeFileInput'
,
file
_path
)
attach_file
(
'fakeFileInput'
,
file
s
)
# Manually trigger a Dropzone "drop" event with the fake input's file list
# Manually trigger a Dropzone "drop" event with the fake input's file list
page
.
execute_script
<<-
JS
.
strip_heredoc
page
.
execute_script
<<-
JS
.
strip_heredoc
var fileList = [$('#fakeFileInput')[0].files[0]];
var e = jQuery.Event('drop', { dataTransfer : { files : fileList } });
var dropzone = $('.div-dropzone')[0].dropzone;
var dropzone = $('.div-dropzone')[0].dropzone;
dropzone.options.autoProcessQueue = false;
if (
#{
max_file_size
}
> 0) {
dropzone.options.maxFilesize =
#{
max_file_size
}
;
}
dropzone.on('queuecomplete', function() {
dropzone.on('queuecomplete', function() {
window._dropzoneComplete = true;
window._dropzoneComplete = true;
});
});
dropzone.listeners[0].events.drop(e);
var fileList = [$('#fakeFileInput')[0].files];
$.map(fileList, function(file){
var e = jQuery.Event('drop', { dataTransfer : { files : file } });
dropzone.listeners[0].events.drop(e);
});
dropzone.processQueue();
JS
JS
# Wait until Dropzone's fired `queuecomplete`
if
wait_for_queuecomplete
loop
until
page
.
evaluate_script
(
'window._dropzoneComplete === true'
)
# Wait until Dropzone's fired `queuecomplete`
loop
until
page
.
evaluate_script
(
'window._dropzoneComplete === true'
)
end
end
end
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