A bunch of style/polish for newfiles

fixes: CNVS-15244 CNVS-15261 CNVS-15374

changes:
handles overflow by scrolling
matches blake's mockup

test plan:
try the folder tree in both new files and by pressing
the "add image" icon in the tinyMCE toolbar and going
to the "From Canvas" tab.

TODO: 'active' style

it should look good and work well.

Change-Id: I6219da771758fd00d6ed3005ed459097a83fcd7e
Reviewed-on: https://gerrit.instructure.com/40922
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Clay Diffrient <cdiffrient@instructure.com>
Product-Review: Ryan Shaw <ryan@instructure.com>
QA-Review: Ryan Shaw <ryan@instructure.com>
This commit is contained in:
Ryan Shaw 2014-09-09 15:58:08 -06:00
parent 54d78fa663
commit 87b1dac236
16 changed files with 193 additions and 242 deletions

View File

@ -1,29 +1,32 @@
define [
'i18n!react_files'
'underscore'
'react'
'react-router'
'compiled/react/shared/utils/withReactDOM'
'compiled/fn/preventDefault'
], (_, React, ReactRouter, withReactDOM, preventDefault) ->
], (I18n, _, React, ReactRouter, withReactDOM, preventDefault) ->
columns = [
displayName: 'Name'
displayName: I18n.t('name', 'Name')
property: 'name'
className: 'ef-name-col'
,
displayName: 'Date Created'
displayNameShort: I18n.t('created_at_short', 'Created')
displayName: I18n.t('created_at', 'Date Created')
property: 'created_at'
className: 'ef-date-created-col'
,
displayName: 'Date Modified'
displayNameShort: I18n.t('updated_at_short', 'Modified')
displayName: I18n.t('updated_at', 'Date Modified')
property: 'updated_at'
className: 'ef-date-modified-col'
,
displayName: 'Modified By'
displayName: I18n.t('modified_by', 'Modified By')
className: 'ef-modified-by-col'
property: 'user'
,
displayName: 'Size'
displayName: I18n.t('size', 'Size')
property: 'size'
className: 'ef-size-col'
]
@ -46,8 +49,14 @@ define [
columns.map (column) =>
isSortedCol = sort is column.property
div key: column.property, className: "#{column.className} #{'current-filter' if isSortedCol}",
ReactRouter.Link _.defaults({to: @props.to, query: @queryParamsFor(column.property)}, @props.params),
ReactRouter.Link _.defaults({to: @props.to, query: @queryParamsFor(column.property), className: 'ef-plain-link'}, @props.params),
span className: ('visible-desktop' if column.displayNameShort),
column.displayName
i className:'icon-arrow-up' if isSortedCol and order is 'asc'
i className:'icon-arrow-down' if isSortedCol and order is 'desc'
if column.displayNameShort
span className: 'hidden-desktop',
column.displayNameShort
i className:'icon-mini-arrow-up' if isSortedCol and order is 'asc'
i className:'icon-mini-arrow-down' if isSortedCol and order is 'desc'
div className:'ef-links-col'

View File

@ -10,8 +10,7 @@ define [
'compiled/models/Folder'
'compiled/fn/preventDefault'
'./PublishCloud'
'../utils/downloadStuffAsAZip'
], (I18n, React, {Link}, BackboneMixin, withReactDOM, FriendlyDatetime, ItemCog, friendlyBytes, Folder, preventDefault, PublishCloud, downloadStuffAsAZip) ->
], (I18n, React, {Link}, BackboneMixin, withReactDOM, FriendlyDatetime, ItemCog, friendlyBytes, Folder, preventDefault, PublishCloud) ->
FolderChild = React.createClass
@ -41,11 +40,15 @@ define [
render: withReactDOM ->
div className:"ef-item-row #{'ef-item-selected' if @props.isSelected}", onClick: @props.toggleSelected,
div {
onClick: @props.toggleSelected
className: "ef-item-row #{'ef-item-selected' if @props.isSelected}"
},
label className: 'screenreader-only',
input type: 'checkbox', defaultChecked: @props.isSelected, onChange: @props.toggleSelected,
I18n.t('labels.select', 'Select This Item')
div className:'ef-name-col',
div className:'ef-name-col ellipsis',
if @state.editing
form className: 'ef-edit-name-form', onSubmit: preventDefault(@saveNameEdit),
input({
@ -59,40 +62,43 @@ define [
button type: 'button', className: 'btn btn-link ef-edit-name-cancel', onClick: @cancelEditingName,
i className: 'icon-x'
else if @props.model instanceof Folder
Link to: 'folder', contextType: @props.params.contextType, contextId: @props.params.contextId, splat: @props.model.urlPath(),
i className:'icon-folder',
@props.model.get('name')
Link {
to: 'folder'
contextType: @props.params.contextType
contextId: @props.params.contextId
splat: @props.model.urlPath()
className: 'media'
},
span className: 'pull-left',
i className: 'icon-folder media-object ef-big-icon'
span className: 'media-body',
@props.model.displayName()
else
a href: @props.model.get('url'),
a href: @props.model.get('url'), className: 'media',
span className: 'pull-left',
if @props.model.get('thumbnail_url')
img src: @props.model.get('thumbnail_url'), className:'ef-thumbnail', alt:''
span
className: 'media-object ef-thumbnail'
style:
backgroundImage: "url('#{ @props.model.get('thumbnail_url') }')"
else
i className:'icon-document'
@props.model.get('display_name')
i className:'icon-document media-object ef-big-icon'
span className: 'media-body',
@props.model.displayName()
div className:'ef-date-created-col',
FriendlyDatetime datetime: @props.model.get('created_at'),
div className:'ef-date-modified-col',
FriendlyDatetime datetime: @props.model.get('updated_at'),
div className:'ef-modified-by-col',
a href: @props.model.get('user')?.html_url,
@props.model.get('user')?.display_name,
div className:'ef-modified-by-col ellipsis',
a href: @props.model.get('user')?.html_url, className: 'ef-plain-link',
@props.model.get('user')?.display_name
div className:'ef-size-col',
friendlyBytes(@props.model.get('size')),
div( {className:'ef-links-col'},
friendlyBytes(@props.model.get('size'))
div className: 'ef-links-col',
PublishCloud(model: @props.model),
a (if @props.model instanceof Folder
href: '#'
onClick: preventDefault =>
downloadStuffAsAZip([@props.model], {
contextType: @props.params.contextType
contextId: @props.params.contextId
})
else
href: @props.model.get('url')
),
i className:'icon-download'
ItemCog(model: @props.model, startEditingName: @startEditingName)
)

View File

@ -21,7 +21,15 @@ define [
fudged = $.fudgeDateForProfileTimezone(datetime)
timeTitle = $.datetimeString(datetime)
@transferPropsTo(React.DOM.time({
@transferPropsTo React.DOM.time {
title: $.datetimeString(datetime)
dateTime: datetime.toISOString()
}, $.friendlyDatetime(fudged)))
},
React.DOM.span className: 'visible-desktop',
# something like: Mar 6, 2014
$.friendlyDatetime(fudged)
React.DOM.span className: 'hidden-desktop',
# something like: 3/3/2014
fudged.toLocaleDateString()

View File

@ -4,11 +4,13 @@ define [
'compiled/react/shared/utils/withReactDOM'
'compiled/fn/preventDefault'
'compiled/models/FilesystemObject'
'compiled/models/Folder'
'./RestrictedDialogForm'
'../utils/openMoveDialog'
'../utils/downloadStuffAsAZip'
'jquery'
'jqueryui/dialog'
], (I18n, React, withReactDOM, preventDefault, FilesystemObject, RestrictedDialogForm, openMoveDialog, $) ->
], (I18n, React, withReactDOM, preventDefault, FilesystemObject, Folder, RestrictedDialogForm, openMoveDialog, downloadStuffAsAZip, $) ->
ItemCog = React.createClass
@ -55,6 +57,18 @@ define [
i className:'icon-mini-arrow-down'
ul className:'al-options',
li {},
a (if @props.model instanceof Folder
href: '#'
onClick: preventDefault =>
downloadStuffAsAZip([@props.model], {
contextType: @props.params.contextType
contextId: @props.params.contextId
})
else
href: @props.model.get('url')
),
I18n.t('download', 'Download')
li {},
a href:'#', onClick: preventDefault(@props.startEditingName),
I18n.t('edit_name', 'Edit Name')

View File

@ -41,7 +41,7 @@ define [
render: withReactDOM ->
header className:'ef-header',
form onSubmit: @onSubmitSearch, className:'ef-search-container',
i className:'icon-search',
i({className:'icon-search'}),
input placeholder: I18n.t('search', 'Search for files'), type:'search', ref:'searchTerm', defaultValue: @props.query.search_term #, onKeyUp: @onKeyUp
div className: 'ef-main-buttons',

View File

@ -33,6 +33,7 @@ define [
initialize: ->
@tagId = _.uniqueId 'treenode-'
@render = _.debounce(@render)
@model.on 'all', @render, this
@model.files.on 'all', @render, this
@model.folders.on 'all', @render, this
@ -57,17 +58,27 @@ define [
renderSelf: ->
@$el.attr @attributes()
@$label ||= $("<a class='folderLabel' role='presentation' tabindex='-1' title='#{@title_text()}'/>").prependTo(@$el)
$text = $('<span>', {
text: @title_text(),
click: (event) => @onClick?(event, @model)
})
@$label ||= do =>
@$labelInner = $('<span>').click (event) => @onClick?(event, @model)
$("""
<a
class="folderLabel"
role="presentation"
tabindex="-1"
>
<i class="icon-mini-arrow-right"></i>
<i class="icon-folder"></i>
</a>
""").append(@$labelInner).prependTo(@$el)
@$labelInner.text(@title_text())
@$label
.attr('href', @href?(@model) || '#')
.html($text)
.toggleClass('expanded', !!@model.isExpanded)
.toggleClass('loading after', !!@model.isExpanding)
renderContents: ->
if @model.isExpanded
unless @$folderContents

View File

@ -50,6 +50,7 @@
@import "vendor/bootstrap/thumbnails";
@import "vendor/bootstrap/labels-badges";
@import "vendor/bootstrap/progress-bars";
@import "vendor/bootstrap/media";
//@import "vendor/bootstrap/accordion"; // use jqueryUI instead
//these are just commented out because we dont use them yet, if you want them just uncomment.
//@import "vendor/bootstrap/carousel";

View File

@ -67,7 +67,7 @@
// this passes by itself with a 4.93 ratio
// in case you're wondering where $use_high_contrast is
$canvas-neutral: #bbb;
$canvas-neutral: hsl(0,0,95);
@if $use_high_contrast { $canvas-neutral: #6d6d6d; }
$canvas-action: #ba3fa5;
@ -122,8 +122,13 @@
$eportfolio-name--disabled: #777;
@if $use_high_contrast {$eportfolio-name--disabled: #686868;}
$base-font-color-light: $canvas-light;
$base-font-color-dark: $canvas-dark;
$base-border-color: $canvas-neutral;
$base-list-item-background--hover: #eef7ff;
$base-list-item-background--selected: #d9edf9;
$announcements_disscussion-summary-color: $canvas-dark;

View File

@ -19,7 +19,6 @@ $pages-inner-border: 1px solid #e1e3e4
$index-background: #e8ecef
$item-background: #ffffff
$item-hover-background: #eef7ff
$shadow: 0 1px 0 rgba(0,0,0,0.15)
$table-shadow: 0 1px 0 #dde0e4
@ -173,7 +172,7 @@ $revision-button-hover-color: #2590cf
:text-decoration inherit
:color inherit
&.clickable:hover
:background $item-hover-background
:background $base-list-item-background--hover
:text-decoration inherit
:color inherit
td:first-child

View File

@ -239,11 +239,11 @@ is for items that are not draggable.
}
&:hover {
background-color: #eef7ff;
background-color: $base-list-item-background--hover;
}
&:focus {
background-color: #eef7ff;
background-color: $base-list-item-background--hover;
}
&:before {

View File

@ -1,42 +1,35 @@
@import 'base/environment';
$triangle-edge-size: 5px;
.folderTree {
&:focus { outline: none; }
font-size: 12px;
&, ul {
@include reset-list;
}
ul { margin-left: 8px; }
li a {
padding: 1px 7px 1px 35px;
display: block;
background: url(/images/inst_tree/file_types/page_white.png) no-repeat 13px 3px;
position: relative;
&.folderLabel {
background-image: url(/images/inst_tree/folder.png);
&:before{
position: absolute;
top: $triangle-edge-size;
left: 4px;
border: solid transparent;
border-width: $triangle-edge-size;
border-left-color: $button-text-color;
content: '';
}
&.expanded:before{
left: 0;
top: 7px;
border-left-color: transparent;
border-top-color: $button-text-color;
}
}
padding-bottom: 2px;
display: flex;
white-space: nowrap;
&.active { background-color: $activeBG; }
}
.preview-thumbnail-holder {
display: inline-block;
width: 42px;
height: 42px;
padding-right: 6px;
.preview-thumbnail {
margin-left: -23px;
max-width: 200px;
height: 30px;
vertical-align: middle;
max-width: 100%;
max-height: 100%;
}
}
.icon-folder:before {
font-size: 11px;
}
i[class*=icon-], i[class^=icon-] { color: $base-font-color-dark }
.icon-mini-arrow-right { transition: transform 0.2s }
.expanded .icon-mini-arrow-right { transform: rotate(90deg) }
}

View File

@ -1,55 +0,0 @@
@import 'base/environment';
$triangle-edge-size: 5px;
.folderTree {
&, ul {
@include reset-list;
}
ul { margin-left: 8px; }
.folderContents ul.hidden {
display: none;
}
li a {
padding: 1px 7px 1px 35px;
display: block;
background: url(/images/inst_tree/file_types/page_white.png) no-repeat 13px 3px;
position: relative;
&.folderLabel {
background-image: url(/images/inst_tree/folder.png);
&:before{
position: absolute;
top: $triangle-edge-size;
left: 4px;
border: solid transparent;
border-width: $triangle-edge-size;
border-left-color: $button-text-color;
content: '';
}
&.expanded:before{
left: 0;
top: 7px;
border-left-color: transparent;
border-top-color: $button-text-color;
}
&.loading:after {
// these are the height/width of /images/ajax-loader-linear.gif
width: 16px;
height: 11px;
background: url(/images/ajax-loader-linear.gif);
content: '';
display: inline-block;
margin-left: 7px;
}
}
&:focus { background-color: #f2fafd; }
}
.preview-thumbnail {
margin-left: -23px;
max-width: 200px;
height: 30px;
vertical-align: middle;
}
}

View File

@ -157,7 +157,7 @@
}
&:hover {
background: #eef7ff;
background: $base-list-item-background--hover;
}
a {

View File

@ -1,11 +1,14 @@
@import "base/environment";
$replace-this-with-a-variable-for-focus-bg: hsl(0, 0%, 95%);
$ef-thumbnail-size: 36px;
@mixin hideForPhone {
@media (max-width:767px){
@media (max-width:800px){
display: none;
}
}
$border: #e5e4e4;
.form-horizontal{
.dialog-adapter-form-calendar-label{
@ -13,19 +16,9 @@ $border: #e5e4e4;
margin-left: 0px;
}
}
.dateSelectInput { width: 100px }
.controls.dateSelectInputContainer{ margin-left: 100px }
.adminCog-download-link{
color: black;
margin-right: 10px;
}
.dateSelectInput{
width: 100px;
}
.controls.dateSelectInputContainer{
margin-left: 100px;
}
.ef-search-container{
position: relative;
height: 30px;
@ -66,45 +59,13 @@ $border: #e5e4e4;
left: 8px;
}
.ef-admin-cog{
margin-left: 10px;
}
.ef-header{
height: 75px;
padding-left: 20px;
padding-right: 20px;
display: flex;
align-items: center;
}
.ef-breadcrumbs{
padding-left: 20px;
border-top: 1px solid $border;
border-bottom: 1px solid $border;
height: 40px;
display: flex;
align-items: center;
a {
background-color: transparent;
background-image: url("/images/breadcrumb-chevron.png");
background-repeat: no-repeat;
background-position: 0 50%;
line-height: 29px;
padding-left: 12px;
margin-left: 8px;
&:first-of-type {
background: none;
padding-left: 0;
margin-left: 0;
}
&.active:link, &.active:visited{
color: #999da5;
}
}
border-bottom: 1px solid $base-border-color;
}
.ef-main{
@ -112,22 +73,16 @@ $border: #e5e4e4;
display: flex;
.ef-folder-content{
border-right: 1px solid #f2f2f2;
border-right: 1px solid $base-border-color;
display: flex;
flex-direction: column;
flex: 1 1 0;
padding: 0px;
[role=tree]{
position: relative;
margin: 10px;
.folderTree {
margin: 10px
}
i {
color: black;
}
[aria-selected=true] > .ef-folder-header{
background-color: #f2f2f2;
font-weight: bold;
@ -145,6 +100,7 @@ $border: #e5e4e4;
.ef-folder-list{
flex: 10 10 0;
font-size: 12px;
overflow: auto;
}
.ef-folder-totals{
@ -154,7 +110,7 @@ $border: #e5e4e4;
flex: 1 1 0;
height: 30px;
font-size: 16px;
border-top: 1px solid $border;
border-top: 1px solid $base-border-color;
padding-left: 20px;
}
}
@ -169,35 +125,35 @@ $border: #e5e4e4;
.ef-directory-header{
display: flex;
padding: 5px;
border-bottom: 1px solid #f2f2f2;
a{
color: black;
}
border-bottom: 1px solid $base-border-color;
}
.ef-plain-link, .ef-plain-link:hover { color: $base-font-color-dark; }
.ef-item-row{
display: flex;
padding: 5px;
user-select: none; /* so that we can shift-click to select */
margin-bottom: 1px;
border-radius: 3px;
line-height: $ef-thumbnail-size;
&.ef-item-selected{
background-color: #d9edf9;
// :hover style needs to be before 'selected' so item that is both hovered and selected gets selected color
&:hover { background-color: $base-list-item-background--hover }
&.ef-item-selected { background-color: $base-list-item-background--selected }
.al-trigger { opacity: 0 }
&:hover .al-trigger, .al-trigger.ui-state-active { opacity: 1 }
.btn-link { border-width: 0 }
}
.al-trigger {
opacity: 0
}
&:hover .al-trigger,
.al-trigger.ui-state-active {
opacity: 1
}
&:hover{
background-color: #d9edf9;
.ef-big-icon {
width: $ef-thumbnail-size !important;
color: $base-font-color-dark;
&:before {
font-size: $ef-thumbnail-size - 16px !important;
left: 7px;
}
}
@ -227,30 +183,27 @@ $border: #e5e4e4;
.ef-links-col{
display: flex;
width: 85px;
width: 63px;
}
.ef-hover-options{
.al-trigger{
color: black;
}
margin-left: 14px;
}
.ef-thumbnail {
width: 45px;
width: $ef-thumbnail-size;
height: $ef-thumbnail-size;
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.2);
}
.ef-edit-name-form {
position: relative;
}
.ef-edit-name-form { position: relative }
.ef-edit-name-cancel {
position: absolute;
top: 0;
right: 0;
}
.file-rename-form__form-label {
float: left;
margin-top: 5px;

View File

@ -10,7 +10,6 @@
.media,
.media-body {
overflow: hidden;
*overflow: visible;
zoom: 1;
}
@ -37,12 +36,14 @@
// Media image alignment
// -------------------------
.media .pull-left {
.media {
> .pull-left {
margin-right: 10px;
}
.media .pull-right {
> .pull-right {
margin-left: 10px;
}
}
// Media list variation
@ -50,6 +51,6 @@
// Undo default ul/ol styles
.media-list {
margin-left: 0;
padding-left: 0;
list-style: none;
}

View File

@ -1,4 +1,10 @@
<a href="#" data-fullsize="{{preview_url}}" role="presentation" tabindex="-1" class="treeFile ellipsis" title="{{display_name}}">
{{#if thumbnail_url}}
<span class="preview-thumbnail-holder">
<img class="preview-thumbnail" src="{{thumbnail_url}}">
</span>
{{else}}
<i class="icon-document"></i>
{{/if}}
{{display_name}}
</a>