implement new upload styles in new files
closes CNVS-15365 until OPS-442 goes through this will need to be tested locally using local uploads, or on an S3 instance that accepts 'content-type' headers also makes naming conflict dialog focus the primary button, and if not there, falls back to the close button test plan: - enable new files - navigate to the course files - select the 'Upload' button on the toolbar - select one or more files to upload - files should upload successfully - naming conflict window (if needed) should continue to work - upload progress should be displayed Change-Id: I997a7619190efa8f5601475cdacd3f5fd849bb71 Reviewed-on: https://gerrit.instructure.com/40809 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Clay Diffrient <cdiffrient@instructure.com> Product-Review: Jason Madsen <jmadsen@instructure.com> QA-Review: Jason Madsen <jmadsen@instructure.com>
This commit is contained in:
parent
d109585a3b
commit
90217a2774
|
@ -1,15 +1,17 @@
|
|||
define [
|
||||
'i18n!current_uploads'
|
||||
'react'
|
||||
'compiled/react/shared/utils/withReactDOM'
|
||||
'../modules/UploadQueue'
|
||||
'./UploadProgress'
|
||||
'compiled/jquery.rails_flash_notifications'
|
||||
], (React, withReactDOM, UploadQueue, UploadProgress) ->
|
||||
], (I18n, React, withReactDOM, UploadQueue, UploadProgress) ->
|
||||
|
||||
CurrentUploads = React.createClass
|
||||
|
||||
getInitialState: ->
|
||||
{currentUploads: []}
|
||||
currentUploads: []
|
||||
isOpen: false
|
||||
|
||||
componentWillMount: ->
|
||||
UploadQueue.onChange = =>
|
||||
|
@ -19,6 +21,11 @@ define [
|
|||
componentWillUnMount: ->
|
||||
UploadQueue.onChange = ->
|
||||
#noop
|
||||
handleCloseClick: ->
|
||||
@setState isOpen: false
|
||||
|
||||
handleBrowseClick: ->
|
||||
console.log('browse click')
|
||||
|
||||
screenReaderUploadStatus: ->
|
||||
currentUploader = UploadQueue.getCurrentUploader()
|
||||
|
@ -27,11 +34,40 @@ define [
|
|||
percent = currentUploader.roundProgress()
|
||||
$.screenReaderFlashMessage "#{name} - #{percent}%"
|
||||
|
||||
buildInstructions: ->
|
||||
div className: 'current_uploads__instructions',
|
||||
a
|
||||
role: 'button'
|
||||
'aria-label': I18n.t('close', 'close')
|
||||
onClick: @handleCloseClick
|
||||
className: 'current_uploads__instructions__close',
|
||||
'\u2A09'
|
||||
i className: 'icon-upload current_uploads__instructions__icon-upload'
|
||||
div {},
|
||||
p className: 'current_uploads__instructions__drag',
|
||||
I18n.t('drag_files_here', 'Drag Folders and Files here')
|
||||
a
|
||||
role: 'button'
|
||||
onClick: @handleBrowseClick,
|
||||
I18n.t('click_to_browse', 'or click to browse your computer')
|
||||
|
||||
shouldDisplay: ->
|
||||
!!@state.isOpen || @state.currentUploads.length
|
||||
|
||||
buildProgressViews: ->
|
||||
@state.currentUploads.map (uploader) ->
|
||||
progressBars = @state.currentUploads.map (uploader) ->
|
||||
UploadProgress uploader: uploader, key: uploader.getFileName()
|
||||
div className: 'current_uploads__uploaders',
|
||||
progressBars
|
||||
|
||||
buildContent: ->
|
||||
if @state.currentUploads.length
|
||||
@buildProgressViews()
|
||||
else if !!@state.isOpen
|
||||
@buildInstructions()
|
||||
|
||||
render: withReactDOM ->
|
||||
div className:'react_files_uploads',
|
||||
div className: 'react-files-uploads__uploaders',
|
||||
@buildProgressViews()
|
||||
divName = ''
|
||||
divName = 'current_uploads' if @shouldDisplay()
|
||||
div className: divName,
|
||||
@buildContent()
|
||||
|
|
|
@ -31,7 +31,11 @@ define [
|
|||
@dialog.open()
|
||||
#focus the close button after one tick (let render happen first)
|
||||
setTimeout =>
|
||||
$(@node).parents('.ui-dialog').find('.ui-dialog-titlebar-close').focus()
|
||||
primary = $(_this.node).parent().find('.btn-primary')
|
||||
if primary
|
||||
primary.focus()
|
||||
else
|
||||
$(@node).parents('.ui-dialog').find('.ui-dialog-titlebar-close').focus()
|
||||
, 1
|
||||
else
|
||||
@dialog.close()
|
||||
|
|
|
@ -65,8 +65,8 @@ define [
|
|||
render: withReactDOM ->
|
||||
return div({ref: 'emptyDiv'}) unless @props.currentFolder
|
||||
div className:'ef-directory',
|
||||
ColumnHeaders(to: (if @props.params.splat then 'folder' else 'rootFolder'), subject: @props.currentFolder, params: @props.params, query: @props.query),
|
||||
CurrentUploads({})
|
||||
ColumnHeaders(to: (if @props.params.splat then 'folder' else 'rootFolder'), subject: @props.currentFolder, params: @props.params, query: @props.query),
|
||||
if @props.currentFolder.isEmpty()
|
||||
div ref: 'folderEmpty', className: 'muted', I18n.t('this_folder_is_empty', 'This folder is empty')
|
||||
else
|
||||
|
|
|
@ -2,34 +2,31 @@ define [
|
|||
'react'
|
||||
'compiled/react/shared/utils/withReactDOM'
|
||||
'../modules/FileUploader'
|
||||
'i18n!upload_progress_view'
|
||||
], (React, withReactDOM, FileUploader, I18n) ->
|
||||
], (React, withReactDOM, FileUploader) ->
|
||||
|
||||
UploadProgressView = React.createClass
|
||||
|
||||
propTypes:
|
||||
uploader: React.PropTypes.instanceOf(FileUploader).isRequired
|
||||
|
||||
getProgressWithLabel: ->
|
||||
"#{@props.uploader.getFileName()} - #{@props.uploader.roundProgress()}%"
|
||||
getLabel: withReactDOM ->
|
||||
span {},
|
||||
i className: 'icon-document'
|
||||
span ref: 'fileName', @props.uploader.getFileName()
|
||||
|
||||
createWidthStyle: ->
|
||||
width: "#{@props.uploader.roundProgress()}%"
|
||||
|
||||
buildSpinner: withReactDOM ->
|
||||
img
|
||||
className: 'upload-progress-view__indeterminate'
|
||||
src:'/images/ajax-loader-black-on-white.gif'
|
||||
alt: I18n.t('processing', 'processing')
|
||||
|
||||
render: withReactDOM ->
|
||||
almostDone = ''
|
||||
almostDone = ' almost-done' if @props.uploader.roundProgress() == 100
|
||||
div className: 'upload-progress-view',
|
||||
div className: 'upload-progress-view__label',
|
||||
div {},
|
||||
@getProgressWithLabel()
|
||||
@buildSpinner() if @props.uploader.roundProgress() == 100
|
||||
div className: 'upload-progress-view__bar-container',
|
||||
@getLabel()
|
||||
div ref: 'container', className: 'upload-progress-view__bar-container' + almostDone,
|
||||
div
|
||||
className: 'upload-progress-view__bar'
|
||||
ref: 'bar'
|
||||
className: 'upload-progress-view__bar' + almostDone
|
||||
ref: 'bar'
|
||||
style: @createWidthStyle()
|
||||
|
|
|
@ -256,25 +256,69 @@ $border: #e5e4e4;
|
|||
margin-top: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.upload-progress-view__bar-container {
|
||||
height: 3px;
|
||||
margin-bottom: 12px;
|
||||
background: $canvas-neutral;
|
||||
width: 100%;
|
||||
.upload-progress-view {
|
||||
padding-top: 25px;
|
||||
clear: both;
|
||||
}
|
||||
.upload-progress-view__label {
|
||||
margin-left: 5px;
|
||||
margin-top: 5px;
|
||||
width: 49%;
|
||||
color: ensure-contrast(#000, $canvas-secondary);
|
||||
font-size: 0.95em;
|
||||
float: left;
|
||||
}
|
||||
.upload-progress-view__indeterminate{
|
||||
margin-left: 6px;
|
||||
margin-bottom: 2px;
|
||||
.upload-progress-view__bar-container {
|
||||
height: 9px;
|
||||
width: 49%;
|
||||
margin-bottom: 12px;
|
||||
border: solid $canvas-primary 1px;
|
||||
border-radius: 20px;
|
||||
float: right;
|
||||
margin-top: 10px;
|
||||
|
||||
&.almost-done {
|
||||
border: solid $canvas-success 1px;
|
||||
}
|
||||
}
|
||||
.upload-progress-view__bar {
|
||||
position: relative;
|
||||
background: $canvas-primary;
|
||||
border: none;
|
||||
height: 3px;
|
||||
height: 9px;
|
||||
border-radius: 20px;
|
||||
|
||||
&.almost-done {
|
||||
background: $canvas-success;
|
||||
}
|
||||
}
|
||||
.current_uploads {
|
||||
border-radius: 10px;
|
||||
border: dashed $canvas-neutral 2px;
|
||||
padding: 10px 10px 40px 10px;
|
||||
}
|
||||
.current_uploads__uploaders {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.current_uploads__instructions {
|
||||
text-align: center;
|
||||
}
|
||||
.current_uploads__instructions__close {
|
||||
float: right;
|
||||
color: $canvas-neutral;
|
||||
font-size: -1.8em;
|
||||
pointer: cursor;
|
||||
}
|
||||
i[class*=current_uploads__instructions__icon-upload]:before {
|
||||
font-size: 100px;
|
||||
}
|
||||
i[class*=current_uploads__instructions__icon-upload] {
|
||||
color: $canvas-primary;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.current_uploads__instructions__drag {
|
||||
font-size: 1.8em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@ define [
|
|||
resetUploader(@uploader)
|
||||
React.unmountComponentAtNode(@prog.getDOMNode().parentNode)
|
||||
|
||||
test 'getProgressWithLabel concats file name and progress', ->
|
||||
equal(@prog.getProgressWithLabel(), 'filename - 35%')
|
||||
test 'getLabel displays file name', ->
|
||||
equal(@prog.refs.fileName.getDOMNode().textContent, 'filename')
|
||||
|
||||
test 'createWidthStyle returns object with correct percentage from progress', ->
|
||||
equal(@prog.createWidthStyle().width, '35%')
|
||||
|
@ -38,7 +38,7 @@ define [
|
|||
test 'shows indeterminate loader when progress is 100 but not yet complete', ->
|
||||
ul = mockUploader('filename', 100)
|
||||
prog = React.renderComponent(UploadProgress(uploader: ul), $('<div>').appendTo('body')[0])
|
||||
equal $(prog.getDOMNode()).find('.upload-progress-view__indeterminate').length, 1
|
||||
ok prog.refs.container.getDOMNode().className.match(/almost-done/)
|
||||
resetUploader(ul)
|
||||
React.unmountComponentAtNode(prog.getDOMNode().parentNode)
|
||||
|
||||
|
|
Loading…
Reference in New Issue