Start designing the card details pane

Implement a dynamic overflow to focus sight on the pane.
This commit is contained in:
Maxime Quandalle 2015-06-05 21:37:13 +02:00
parent 97807abd70
commit dea52907bd
24 changed files with 305 additions and 850 deletions

View file

@ -12,6 +12,8 @@ template(name="boardComponent")
class=sidebarSize class=sidebarSize
class="{{#if MultiSelection.isActive}}is-multiselection-active{{/if}}" class="{{#if MultiSelection.isActive}}is-multiselection-active{{/if}}"
class="{{#if draggingActive.get}}is-dragging-active{{/if}}") class="{{#if draggingActive.get}}is-dragging-active{{/if}}")
if showOverlay.get
.board-overlay
.lists.js-lists .lists.js-lists
each lists each lists
+list(this) +list(this)
@ -28,10 +30,10 @@ template(name="addListForm")
+inlinedForm(autoclose=false) +inlinedForm(autoclose=false)
input.list-name-input(type="text" placeholder="{{_ 'add-list'}}" input.list-name-input(type="text" placeholder="{{_ 'add-list'}}"
autocomplete="off" autofocus) autocomplete="off" autofocus)
div.edit-controls.clearfix .edit-controls.clearfix
button.primary.confirm.js-save-edit(type="submit") {{_ 'save'}} button.primary.confirm(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form a.fa.fa-times-thin.js-close-inlined-form
else else
.js-open-inlined-form a.js-open-inlined-form
i.fa.fa-plus i.fa.fa-plus
| {{_ 'add-list'}} | {{_ 'add-list'}}

View file

@ -14,12 +14,16 @@ BlazeComponent.extendComponent({
onCreated: function() { onCreated: function() {
this.draggingActive = new ReactiveVar(false); this.draggingActive = new ReactiveVar(false);
this.showOverlay = new ReactiveVar(false);
}, },
openNewListForm: function() { openNewListForm: function() {
this.componentChildren('addListForm')[0].open(); this.componentChildren('addListForm')[0].open();
}, },
// XXX Flow components allow us to avoid creating these two setter methods by
// exposing a public API to modify the component state. We need to investigate
// best practices here.
setIsDragging: function(bool) { setIsDragging: function(bool) {
this.draggingActive.set(bool); this.draggingActive.set(bool);
}, },
@ -60,9 +64,9 @@ BlazeComponent.extendComponent({
var removeNode = _.once(function() { var removeNode = _.once(function() {
node.parentNode.removeChild(node); node.parentNode.removeChild(node);
}); });
if ($(node).hasClass('js-card-detail')) { if ($(node).hasClass('js-card-details')) {
$(node).css({ $(node).css({
flex: '0 0 0', flexBasis: 0,
padding: 0 padding: 0
}); });
$(lists).one(endTransitionEvents, removeNode); $(lists).one(endTransitionEvents, removeNode);

View file

@ -1,21 +1,29 @@
@import 'nib' @import 'nib'
.board-wrapper position()
left: 0 if arguments[0] == cover
top: 0
bottom: 0
right: 0
position: absolute
overflow: hidden
.board-canvas
position: absolute position: absolute
left: 0 left: 0
right: 0 right: 0
top: 0 top: 0
bottom: 0 bottom: 0
else
position: arguments
.board-wrapper
position: cover
.board-canvas
position: cover
transition: margin .1s transition: margin .1s
.board-overlay
position: cover
background: black
opacity: 0.33
animation: fadeIn 0.2s
z-index: 10
&.next-sidebar &.next-sidebar
margin-right: 248px margin-right: 248px
@ -25,16 +33,18 @@
.open-minicard-composer .open-minicard-composer
display: none display: none
.lists .lists
align-items: flex-start align-items: flex-start
display: flex display: flex
flex-direction: row flex-direction: row
margin-bottom: 10px margin-bottom: 10px
overflow-x: auto overflow: auto
overflow-y: hidden padding-bottom: 5px
padding-bottom: 10px position: cover
position: absolute
top: 0 // In order for the card details pane to overlap the header we need to
right: 0 // virtually increase this container size with the below hack. (Note that it
bottom: 0 // is not possible to set overflow-x: auto, overflow-y: hidden as I
left: 0 // originally tried).
padding-top: 10px
top: -10px

View file

@ -30,17 +30,6 @@
background-size: auto background-size: auto
background-repeat: repeat background-repeat: repeat
.details
height: 84px
padding-right: 36px
bottom: 0
left: 0
overflow: hidden
padding: 9px 12px
position: absolute
right: 0
top: 0
.board-list-item-sub-name .board-list-item-sub-name
color: rgba(255, 255, 255, .5) color: rgba(255, 255, 255, .5)
display: block display: block

View file

@ -2,9 +2,9 @@
// http://flatuicolors.com // http://flatuicolors.com
// //
// XXX Centralizing all these properties in a single file just because their // XXX Centralizing all these properties in a single file just because their
// value is derivedform the same color, doesn't make any sense. We should create // value is derived from the same color, doesn't make any sense. We should
// a macro that would generate 6 version of a given propertie and dispatch this // create a mixin/macro that would generate 6 versions of a given property and
// list in the other stylus files. // dispatch this list in the other stylus files.
setBoardColor(color) setBoardColor(color)
&#header, &#header,
&.sk-spinner div, &.sk-spinner div,

View file

@ -1,47 +1,105 @@
template(name="cardDetails") template(name="cardDetails")
.card-detail.js-card-detail: .card-detail-canvas section.card-details.js-card-details: .card-details-canvas
if cover if cover
.card-detail-cover(style="background-image: url({{ card.cover.url }})") .card-details-cover(style="background-image: url({{ cover.url }})")
.card-detail-header(class="{{#if currentUser.isBoardMember}}editable{{/if}}")
a.js-close-card-detail .card-details-header
i.fa.fa-times-thin +inlinedForm(classNames="js-card-details-title")
h2.card-detail-title.js-card-title= title input.field.single-line(type="text" value=title autofocus)
p.card-detail-list.js-move-card .edit-controls.clearfix
| {{_ 'in-list'}} button.primary.confirm(type="submit") {{_ 'save'}}
a.card-detail-list-title( a.fa.fa-times-thin.js-close-inlined-form
class="{{#if currentUser.isBoardMember}}js-open-move-from-header is-editable{{/if}}") else
= list.title a.fa.fa-angle-left.close-card-details.js-close-card-details
hr a.fa.fa-bars.card-details-menu.js-open-card-details-menu
//- if card.members h2.card-details-title.js-card-title(
.card-detail-item.card-detail-item-members.clearfix.js-card-detail-members class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}")
h3.card-detail-item-header {{_ 'members'}} = title
.js-card-detail-members-list.clearfix p.card-details-list
| {{_ 'in-list'}}
a.card-details-list-title(
class="{{#if currentUser.isBoardMember}}js-move-card is-editable{{/if}}")
= list.title
if currentUser.isBoardMember
i.fa.fa-chevron-down
.card-details-items
.card-details-item.card-details-item-members
h3 {{_ 'members'}}
each members each members
+userAvatar(userId=this size="small" cardId=../_id) +userAvatar(userId=this size="small" cardId=../_id)
a.card-detail-item-add-button.dark-hover.js-details-edit-members a.member.add-member.card-details-item-add-button.js-add-members
i.fa.fa-plus i.fa.fa-plus
//- We should use "editable" to avoide repetiting ourselves
.clearfix .card-details-item.card-details-item-labels
h3 {{_ 'labels'}}
.js-add-labels
each labels
span.card-label(class="card-label-{{color}}" title=name)= name
a.card-label.add-label.js-add-labels
i.fa.fa-plus
//- XXX We should use "editable" to avoide repetiting ourselves
if currentUser.isBoardMember if currentUser.isBoardMember
h3 Description h3 Description
+inlinedForm(classNames="js-card-description") +inlinedForm(classNames="js-card-description")
a.fa.fa-times-thin.js-close-inlined-form
+editor(autofocus=true) +editor(autofocus=true)
= description = description
button(type="submit") {{_ 'edit'}} .edit-controls.clearfix
button.primary(type="submit") {{_ 'edit'}}
a.fa.fa-times-thin.js-close-inlined-form
else else
.js-open-inlined-form a.js-open-inlined-form
a {{_ 'edit'}} if description
+viewer +viewer
= description = description
else
| {{_ 'edit'}}
else if description else if description
h3 Description h3 Description
+viewer +viewer
= description = description
hr
if attachments.count if attachments.count
hr
+WindowAttachmentsModule(card=this) +WindowAttachmentsModule(card=this)
+WindowActivityModule(card=this) if isLoaded
hr
+WindowActivityModule(card=this)
template(name="cardDetailsActionsPopup")
if currentUser.isBoardMember
ul.pop-over-list
li: a.js-members Edit Members…
li: a.js-labels Edit Labels…
li: a.js-attachments Edit Attachments…
hr
ul.pop-over-list
li: a.js-copy Copy card
li: a.js-archive Archive Card
template(name="moveCardPopup") template(name="moveCardPopup")
+boardLists +boardLists
template(name="cardMembersPopup")
ul.pop-over-member-list
each board.members
li.item(class="{{#if isCardMember}}active{{/if}}")
a.name.js-select-member(href="#")
+userAvatar(user=user size="small")
span.full-name
= user.profile.name
| (<span class="username">{{ user.username }}</span>)
if isCardMember
i.fa.fa-check
template(name="cardLabelsPopup")
ul.edit-labels-pop-over
each board.labels
li
a.card-label-edit-button.fa.fa-pencil.js-edit-label
span.card-label.card-label-selectable.js-select-label(class="card-label-{{color}}"
class="{{# if isLabelSelected ../_id }}active{{/ if }}")
= name
if currentUser.isBoardAdmin
span.card-label-selectable-icon.fa.fa-check
a.quiet-button.full.js-add-label {{_ 'label-create'}}

View file

@ -8,7 +8,7 @@ BlazeComponent.extendComponent({
}, },
calculateNextPeak: function() { calculateNextPeak: function() {
var altitude = this.find('.js-card-detail').scrollHeight; var altitude = this.find('.js-card-details').scrollHeight;
this.callFirstWith(this, 'setNextPeak', altitude); this.callFirstWith(this, 'setNextPeak', altitude);
}, },
@ -25,77 +25,67 @@ BlazeComponent.extendComponent({
bodyBoardComponent.scrollLeft(scollLeft); bodyBoardComponent.scrollLeft(scollLeft);
}, },
onDestroyed: function() {
this.componentParent().showOverlay.set(false);
},
updateCard: function(modifier) {
Cards.update(this.data()._id, {
$set: modifier
});
},
events: function() { events: function() {
return [{ return [{
'click .js-close-card-details': function() {
Utils.goBoardId(this.data().boardId);
},
'click .js-move-card': Popup.open('moveCard'), 'click .js-move-card': Popup.open('moveCard'),
'click .js-open-card-details-menu': Popup.open('cardDetailsActions'),
'submit .js-card-description': function(evt) { 'submit .js-card-description': function(evt) {
evt.preventDefault(); evt.preventDefault();
var cardId = Session.get('currentCard'); var description = this.currentComponent().getValue();
var form = this.componentChildren('inlinedForm')[0]; this.updateCard({ description: description });
var newDescription = form.getValue();
Cards.update(cardId, {
$set: {
description: newDescription
}
});
form.close();
}, },
'click .js-close-card-detail': function() { 'submit .js-card-details-title': function(evt) {
Utils.goBoardId(Session.get('currentBoard')); evt.preventDefault();
}, var title = this.currentComponent().getValue();
'click .editable .js-card-title': function(event, t) {
var editable = t.$('.card-detail-title');
// add class editing and focus
$('.editing').removeClass('editing');
editable.addClass('editing');
editable.find('#title').focus();
},
'click .js-edit-desc': function(event, t) {
var editable = t.$('.card-detail-item');
// editing remove based and add current editing.
$('.editing').removeClass('editing');
editable.addClass('editing');
editable.find('#desc').focus();
event.preventDefault();
},
'click .js-cancel-edit': function() {
// remove editing hide.
$('.editing').removeClass('editing');
},
'submit #WindowTitleEdit': function(event, t) {
var title = t.find('#title').value;
if ($.trim(title)) { if ($.trim(title)) {
Cards.update(this.card._id, { this.updateCard({ title: title });
$set: {
title: title
}
}, function(err) {
if (! err) $('.editing').removeClass('editing');
});
} }
event.preventDefault();
}, },
'submit #WindowDescEdit': function(event, t) { 'click .js-member': Popup.open('cardMember'),
Cards.update(this.card._id, { 'click .js-add-members': Popup.open('cardMembers'),
$set: { 'click .js-add-labels': Popup.open('cardLabels'),
description: t.find('#desc').value 'mouseenter .js-card-details': function() {
} this.componentParent().showOverlay.set(true);
}, function(err) {
if (! err) $('.editing').removeClass('editing');
});
event.preventDefault();
}, },
'click .member': Popup.open('cardMember'), 'mouseleave .js-card-details': function(evt) {
'click .js-details-edit-members': Popup.open('cardMembers'), // We don't want to hide the overlay if the mouse is entering a pop-over
'click .js-details-edit-labels': Popup.open('cardLabels') var $pointedElement = $(evt.toElement || evt.relatedTarget);
if ($pointedElement.closest('.pop-over').length === 0)
this.componentParent().showOverlay.set(false);
}
}]; }];
} }
}).register('cardDetails'); }).register('cardDetails');
Template.cardDetailsActionsPopup.events({
'click .js-members': Popup.open('cardMembers'),
'click .js-labels': Popup.open('cardLabels'),
'click .js-attachments': Popup.open('cardAttachments'),
// 'click .js-copy': Popup.open(),
'click .js-archive': function(evt) {
evt.preventDefault();
Cards.update(this._id, {
$set: {
archived: true
}
});
Popup.close();
}
});
Template.moveCardPopup.events({ Template.moveCardPopup.events({
'click .js-select-list': function() { 'click .js-select-list': function() {
// XXX We should *not* get the currentCard from the global state, but // XXX We should *not* get the currentCard from the global state, but
@ -107,5 +97,6 @@ Template.moveCardPopup.events({
listId: newListId listId: newListId
} }
}); });
Popup.close();
} }
}); });

View file

@ -1,57 +1,73 @@
@import 'nib' @import 'nib'
.card-detail .card-details
padding: 0 20px padding: 0 20px
height: 100% height: 100%
flex: 0 0 470px flex-shrink: 0
flex-basis: 470px
will-change: flex-basis
overflow: hidden overflow: hidden
background: white background: white
border-radius: 3px border-radius: 3px
z-index: 20 !important z-index: 20 !important
animation: growIn 0.2s animation: flexGrowIn 0.2s
box-shadow: 0 0 7px 0 darken(white, 30%) box-shadow: 0 0 7px 0 darken(white, 30%)
transition: flex 0.2s, padding 0.2s transition: flex-basis 0.2s, padding 0.2s
margin-top: -9px
.card-detail-canvas .card-details-canvas
width: 470px width: 470px
.card-detail-header .card-details-header
margin: 0 -20px 5px margin: 0 -20px 5px
padding 7px 20px 0 padding 7px 20px 0
background: #F7F7F7 background: #F7F7F7
border-bottom: 1px solid darken(white, 10%) border-bottom: 1px solid darken(white, 10%)
min-height: 38px min-height: 38px
position: relative
i.fa .close-card-details
float: left
font-size: 24px
padding: 8px
padding-right: 11px
margin-left: -18px
.card-details-menu
float: right float: right
font-size: 1.3em position: absolute
color: darken(white, 35%) bottom: 6px
margin-top: 7px right: 15px
.card-detail-title .card-details-title
font-weight: bold font-weight: bold
font-size: 1.7em font-size: 1.33em
margin: 3px 0 0 margin: 3px 0
padding: 0 padding: 0
.card-detail-list .card-details-list
font-size: 0.85em font-size: 0.85em
margin-bottom: 3px margin-bottom: 3px
a.card-detail-list-title a.card-details-list-title
font-weight: bold font-weight: bold
&.is-editable &.is-editable
display: inline-block display: inline-block
background: darken(white, 10%) background: darken(white, 10%)
border-radius: 3px border-radius: 3px
padding: 0px 5px padding: 0px 5px
@keyframes growIn .card-details-items
from display: flex
flex: 0 0 0 margin: 15px 0
to
flex: 0 0 470px .card-details-item
flex-grow: 1
h3
font-size: 14px
color: darken(white, 45%)
.new-comment .new-comment
position: relative position: relative
@ -107,30 +123,6 @@
&:focus &:focus
cursor: auto cursor: auto
.list-voters.compact .voter
position: relative
min-height: 36px
.member
left: 0
position: absolute
top: 0
.title
display: block
line-height: 30px
left: 0
overflow: hidden
padding-left: 38px
position: absolute
text-overflow: ellipsis
top: 0
white-space: nowrap
width: 230px
.list-voters .title
display: none
.card-composer .card-composer
padding-bottom: 8px padding-bottom: 8px

View file

@ -24,6 +24,10 @@
width: @height width: @height
padding: 0 padding: 0
&.add-label
box-shadow: 0 0 0 2px darken(white, 25%) inset
background: darken(white, 5%)
.card-label-green .card-label-green
background-color: #3cb500 background-color: #3cb500
@ -84,31 +88,6 @@
left: 0 left: 0
width: 260px width: 260px
.minicard-labels
position: relative
z-index: 30
top: -6px
.card-label
border-radius: 0
float: left
height: 4px
margin-bottom: 1px
padding: 0
width: 40px
line-height: 100px
.card-detail-item-labels .card-label
border-radius: 3px
display: block
float: left
height: 20px
line-height: 20px
margin: 0 4px 4px 0
min-width: 30px
padding: 5px 10px
width: auto
.editable-labels .card-label:hover .editable-labels .card-label:hover
cursor: pointer cursor: pointer
opacity: .75 opacity: .75
@ -170,19 +149,3 @@
&:hover &:hover
background: #dbdbdb background: #dbdbdb
.card-label-color-select-icon
left: 14px
position: absolute
top: 9px
.phenom .card-label
display: inline-block
font-size: 12px
height: 14px
line-height: 13px
padding: 0 4px
min-width: 16px
overflow: ellipsis
.board-widget .phenom .card-label
max-width: 130px

View file

@ -23,6 +23,14 @@ BlazeComponent.extendComponent({
evt.preventDefault(); evt.preventDefault();
var methodName = evt.shiftKey ? 'toogleRange' : 'toogle'; var methodName = evt.shiftKey ? 'toogleRange' : 'toogle';
MultiSelection[methodName](this.currentData()._id); MultiSelection[methodName](this.currentData()._id);
// If the card is already selected, we want to de-select it.
// XXX We should probably modify the minicard href attribute instead of
// overwriting the event in case the card is already selected.
} else if (Session.equals('currentCard', this.currentData()._id)) {
evt.stopImmediatePropagation();
evt.preventDefault();
Utils.goBoardId(Session.get('currentBoard'));
} }
}, },

View file

@ -43,14 +43,13 @@
color: #4d4d4d color: #4d4d4d
overflow: hidden overflow: hidden
transition: transform 0.2s, transition: transform 0.2s,
border-radius 0.2s, border-radius 0.2s
border-left 0.2s
.is-selected & .is-selected &
transform: translateX(11px) transform: translateX(11px)
border-bottom-right-radius: 0 border-bottom-right-radius: 0
border-top-right-radius: 0 border-top-right-radius: 0
z-index: 100 z-index: 25
box-shadow: -2px 1px 2px rgba(0,0,0,.2) box-shadow: -2px 1px 2px rgba(0,0,0,.2)
.minicard-cover .minicard-cover
@ -66,56 +65,33 @@
background-size: auto background-size: auto
background-position: center background-position: center
.minicard-details-overlay
background: transparent
bottom: 0
left: 0
position: absolute
right: 0
top: 0
.minicard-dropzone .minicard-dropzone
display: none display: none
.minicard.drophover .minicard-dropzone .minicard.drophover .minicard-dropzone
background: rgba(255, 255, 255, .8) background: rgba(255, 255, 255, .8)
// border-radius: 3px
// bottom: 0
// display: block
// font-weight: 700
// line-height: 100%
// left: 0
// margin: 0
// opacity: 1
// padding: 0
// position: absolute
// right: 0
// text-align: center
// top: 0
// z-index: 40
.minicard-title .minicard-title
display: block display: block
font-weight: 400 font-weight: 400
margin: 0 0 4px
overflow: hidden overflow: hidden
margin-bottom: 2px
text-decoration: none text-decoration: none
word-wrap: break-word word-wrap: break-word
clear: both
&::selection &::selection
background: transparent background: transparent
.minicard-labels .minicard-labels
padding-top: 3px
margin-top: 4px
float: right float: right
.minicard-label .minicard-label
float: right float: right
width: 8px width: 11px
height: @width height: @width
border-radius: 2px border-radius: 2px
margin-left: 4px margin-right: 3px
.minicard-members .minicard-members
float: right float: right

View file

@ -1,11 +0,0 @@
template(name="cardMembersPopup")
ul.pop-over-member-list.js-mem-list
each board.members
li.item(class="{{#if isCardMember}}active{{/if}}")
a.name.js-select-member(href="#")
+userAvatar(user=user size="small")
span.full-name
= user.profile.name
| (<span class="username">{{ user.username }}</span>)
if isCardMember
i.fa.fa-check

View file

@ -33,26 +33,6 @@
</p> </p>
</template> </template>
<template name="cardLabelsPopup">
<div>
{{! <input id="labelSearch" name="search" class="js-autofocus js-label-search" placeholder="Search labels…" value="" type="text"> }}
<ul class="edit-labels-pop-over js-labels-list">
{{# each card.board.labels }}
<li>
<a href="#" class="card-label-edit-button icon-sm fa fa-pencil js-edit-label"></a>
<span class="card-label card-label-selectable card-label-{{color}} js-select-label {{# if isLabelSelected ../card._id }}active{{/ if }}">
{{name}}
{{# if currentUser.isBoardAdmin }}
<span class="card-label-selectable-icon icon-sm fa fa-check light"></span>
{{/ if }}
</span>
</li>
{{/ each}}
</ul>
<a class="quiet-button full js-add-label">{{_ 'label-create'}}</a>
</div>
</template>
<template name="cardAttachmentsPopup"> <template name="cardAttachmentsPopup">
<div> <div>
<ul class="pop-over-list"> <ul class="pop-over-list">
@ -114,7 +94,7 @@
</template> </template>
<template name="cardDetailSidebarOld"> <template name="cardDetailSidebarOld">
<div class="card-detail-window clearfix"> <div class="card-details-window clearfix">
{{# if card.cover }} {{# if card.cover }}
<div class="window-cover js-card-cover-box js-open-card-cover-in-viewer has-cover" style="background-image: url({{ card.cover.url }}); background-color: rgb(119, 119, 119); background-size: contain;"> <div class="window-cover js-card-cover-box js-open-card-cover-in-viewer has-cover" style="background-image: url({{ card.cover.url }}); background-color: rgb(119, 119, 119); background-size: contain;">
</div> </div>
@ -127,7 +107,7 @@
{{ /if }} {{ /if }}
<div class="window-header clearfix"> <div class="window-header clearfix">
<span class="window-header-icon icon-lg fa fa-calendar-o"></span> <span class="window-header-icon icon-lg fa fa-calendar-o"></span>
<div class="window-title card-detail-title non-empty inline {{# if currentUser.isBoardMember }}editable{{/ if }}"> <div class="window-title card-details-title non-empty inline {{# if currentUser.isBoardMember }}editable{{/ if }}">
<h2 class="window-title-text current hide-on-edit js-card-title">{{ card.title }}</h2> <h2 class="window-title-text current hide-on-edit js-card-title">{{ card.title }}</h2>
<div class="edit edit-heavy"> <div class="edit edit-heavy">
<form id="WindowTitleEdit"> <form id="WindowTitleEdit">
@ -147,39 +127,39 @@
</div> </div>
</div> </div>
<div class="window-main-col clearfix"> <div class="window-main-col clearfix">
<div class="card-detail-data gutter clearfix"> <div class="card-details-data gutter clearfix">
<div class="card-detail-item card-detail-item-block clear clearfix editable"> <div class="card-details-item card-details-item-block clear clearfix editable">
{{# if card.members }} {{# if card.members }}
<div class="card-detail-item card-detail-item-members clearfix js-card-detail-members"> <div class="card-details-item card-details-item-members clearfix js-card-details-members">
<h3 class="card-detail-item-header">{{_ 'members'}}</h3> <h3 class="card-details-item-header">{{_ 'members'}}</h3>
<div class="js-card-detail-members-list clearfix"> <div class="js-card-details-members-list clearfix">
{{# each card.members }} {{# each card.members }}
{{> userAvatar userId=this size="small" cardId=../card._id }} {{> userAvatar userId=this size="small" cardId=../card._id }}
{{/ each }} {{/ each }}
<a class="card-detail-item-add-button dark-hover js-details-edit-members"> <a class="card-details-item-add-button dark-hover js-details-edit-members">
<span class="icon-sm fa fa-plus"></span> <span class="icon-sm fa fa-plus"></span>
</a> </a>
</div> </div>
</div> </div>
{{/ if }} {{/ if }}
{{# if card.labels }} {{# if card.labels }}
<div class="card-detail-item card-detail-item-labels clearfix js-card-detail-labels"> <div class="card-details-item card-details-item-labels clearfix js-card-details-labels">
<h3 class="card-detail-item-header">{{_ 'labels'}}</h3> <h3 class="card-details-item-header">{{_ 'labels'}}</h3>
<div class="js-card-detail-labels-list clearfix editable-labels js-edit-label"> <div class="js-card-details-labels-list clearfix editable-labels js-edit-label">
{{# each card.labels }} {{# each card.labels }}
<span class="card-label card-label-{{color}}" title="{{name}}">{{ name }}</span> <span class="card-label card-label-{{color}}" title="{{name}}">{{ name }}</span>
{{/ each }} {{/ each }}
<a class="card-detail-item-add-button dark-hover js-details-edit-labels"> <a class="card-details-item-add-button dark-hover js-details-edit-labels">
<span class="icon-sm fa fa-plus"></span> <span class="icon-sm fa fa-plus"></span>
</a> </a>
</div> </div>
</div> </div>
{{/ if }} {{/ if }}
<div class="card-detail-item card-detail-item-block clear clearfix editable" attr="desc"> <div class="card-details-item card-details-item-block clear clearfix editable" attr="desc">
{{# if card.description }} {{# if card.description }}
<h3 class="card-detail-item-header js-show-with-desc">{{_ 'description'}}</h3> <h3 class="card-details-item-header js-show-with-desc">{{_ 'description'}}</h3>
{{# if currentUser.isBoardMember }} {{# if currentUser.isBoardMember }}
<a href="#" class="card-detail-item-header-edit hide-on-edit js-show-with-desc js-edit-desc">{{_ 'edit'}}</a> <a href="#" class="card-details-item-header-edit hide-on-edit js-show-with-desc js-edit-desc">{{_ 'edit'}}</a>
{{/ if }} {{/ if }}
<div class="current markeddown hide-on-edit js-card-desc js-show-with-desc"> <div class="current markeddown hide-on-edit js-card-desc js-show-with-desc">
{{#viewer}}{{ card.description }}{{/viewer}} {{#viewer}}{{ card.description }}{{/viewer}}
@ -194,7 +174,7 @@
</p> </p>
{{/ if }} {{/ if }}
{{/ if }} {{/ if }}
<div class="card-detail-edit edit"> <div class="card-details-edit edit">
<form id="WindowDescEdit"> <form id="WindowDescEdit">
{{#editor class="field single-line2" id="desc"}}{{ card.description }}{{/editor}} {{#editor class="field single-line2" id="desc"}}{{ card.description }}{{/editor}}
<div class="edit-controls clearfix"> <div class="edit-controls clearfix">
@ -218,7 +198,7 @@
</template> </template>
<template name="WindowActivityModule"> <template name="WindowActivityModule">
<div class="card-detailwindow-module"> <div class="card-detailswindow-module">
<div class="window-module-title window-module-title-no-divider"> <div class="window-module-title window-module-title-no-divider">
<span class="window-module-title-icon icon-lg fa fa-comments-o"></span> <span class="window-module-title-icon icon-lg fa fa-comments-o"></span>
<h3>{{ _ 'activity'}}</h3> <h3>{{ _ 'activity'}}</h3>

View file

@ -479,6 +479,9 @@ button
color: #53492d color: #53492d
background: #e1cc93 background: #e1cc93
.is-editable
cursor: pointer
.big-link .big-link
border-radius: 3px border-radius: 3px
display: block display: block

View file

@ -76,7 +76,7 @@ BlazeComponent.extendComponent({
// Pressing Ctrl+Enter should submit the form // Pressing Ctrl+Enter should submit the form
'keydown form textarea': function(evt) { 'keydown form textarea': function(evt) {
if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) { if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) {
$(evt.currentTarget).parents('form:first').submit(); this.find('button[type=submit]').click();
} }
}, },

View file

@ -16,8 +16,7 @@ template(name="listBody")
template(name="addCardForm") template(name="addCardForm")
.minicard.minicard-composer.js-composer .minicard.minicard-composer.js-composer
.minicard-labels.js-minicard-composer-labels .minicard-detailss.clearfix
.minicard-details.clearfix
textarea.minicard-composer-textarea.js-card-title(autofocus) textarea.minicard-composer-textarea.js-card-title(autofocus)
.minicard-members.js-minicard-composer-members .minicard-members.js-minicard-composer-members
.add-controls.clearfix .add-controls.clearfix

View file

@ -3,11 +3,14 @@ template(name="listHeader")
+inlinedForm +inlinedForm
+editListTitleForm +editListTitleForm
else else
h2.list-header-name.js-open-inlined-form= title h2.list-header-name(
class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}")
= title
a.list-header-menu-icon.fa.fa-bars.js-open-list-menu a.list-header-menu-icon.fa.fa-bars.js-open-list-menu
template(name="editListTitleForm") template(name="editListTitleForm")
input.field.single-line(type="text" value=title autofocus) .list-composer
.edit-controls.clearfix input.field.single-line(type="text" value=title autofocus)
button.primary.confirm(type="submit") {{_ 'save'}} .edit-controls.clearfix
a.fa.fa-times-thin.js-close-inlined-form button.primary.confirm(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form

View file

@ -8,7 +8,7 @@
position: relative position: relative
// Even if this background color is the same as the body we can't leave it // Even if this background color is the same as the body we can't leave it
// transparent, because that won't work during a list drag. // transparent, because that won't work during a list drag.
background: darken(white, 10%) background: darken(white, 13%)
height: 100% height: 100%
border-left: 1px solid darken(white, 20%) border-left: 1px solid darken(white, 20%)
padding: 0 padding: 0
@ -17,7 +17,7 @@
margin-left: 5px margin-left: 5px
border-left: none border-left: none
.card-detail + & .card-details + &
border-left: none border-left: none
&.ui-sortable-helper &.ui-sortable-helper
@ -32,13 +32,15 @@
box-shadow: none box-shadow: none
height: 100px height: 100px
&.list-composer &.list-composer, & list-composer
padding: 17px padding: 17px
form
margin-top: -5px
.list-name-input .list-name-input
background: rgba(0, 0, 0, .05) background: rgba(255, 255, 255, .4)
border-color: #aaa border-color: #aaa
box-shadow: inset 0 1px 8px rgba(0, 0, 0, .15)
display: block display: block
margin: 0 margin: 0
transition: margin 85ms ease-in, transition: margin 85ms ease-in,
@ -52,14 +54,9 @@
overflow: hidden overflow: hidden
margin: 4px 0 0 margin: 4px 0 0
input[type=submit]
margin-top: 0
min-height: 30px
height: 30px
.list-header .list-header
flex: 0 0 auto flex: 0 0 auto
margin: 20px 15px 4px margin: 20px 12px 4px
position: relative position: relative
min-height: 20px min-height: 20px
@ -76,17 +73,9 @@
word-wrap: break-word word-wrap: break-word
.list-header-menu-icon .list-header-menu-icon
background-clip: content-box
background-origin: content-box
// padding: 6px 8px
position: absolute position: absolute
top: 0 top: 0
right: 0 right: 0
color: #a6a6a6
.list-header-num-cards
color: #8c8c8c
margin: 0
.list-body .list-body
flex: 1 flex: 1
@ -119,9 +108,3 @@
background: #fafafa background: #fafafa
color: #222 color: #222
box-shadow: 0 1px 2px rgba(0,0,0,.2) box-shadow: 0 1px 2px rgba(0,0,0,.2)
@keyframes fadeIn
from
opacity: 0
to
opacity: 1

View file

@ -2,7 +2,7 @@ template(name="sidebar")
.board-sidebar.sidebar(class="{{#if isOpen}}is-open{{/if}}") .board-sidebar.sidebar(class="{{#if isOpen}}is-open{{/if}}")
a.sidebar-tongue.js-toogle-sidebar( a.sidebar-tongue.js-toogle-sidebar(
class="{{#if isTongueHidden}}is-hidden{{/if}}") class="{{#if isTongueHidden}}is-hidden{{/if}}")
i.fa.fa-chevron-left i.fa.fa-angle-left
.sidebar-content.js-board-sidebar-content.js-perfect-scrollbar .sidebar-content.js-board-sidebar-content.js-perfect-scrollbar
unless isDefaultView unless isDefaultView
h2 h2
@ -44,9 +44,9 @@ template(name="labelsWidget")
| {{_ 'labels'}} | {{_ 'labels'}}
.board-widget-content .board-widget-content
each currentBoard.labels each currentBoard.labels
a.card-label(class="card-label-{{color}}").js-label a.card-label(class="card-label-{{color}}").js-label
span.card-label-name= name span.card-label-name= name
a.card-label.js-add-label a.card-label.add-label.js-add-label
i.fa.fa-plus i.fa.fa-plus
template(name="memberPopup") template(name="memberPopup")

View file

@ -59,88 +59,6 @@
&.is-open &.is-open
right: 0 right: 0
.board-widget-nav
border-radius: 3px
background: #dcdcdc
overflow: hidden
padding: 0
position: relative
.toggle-widget-nav
border-radius: 3px
color: #8c8c8c
margin: 0
padding: 7px 10px
position: relative
cursor: pointer
.toggle-menu-icon
position: absolute
top: 8px
right: 8px
&:hover
background: #ccc
color: #4d4d4d
.nav-list
display: block
opacity: 1
max-height: 400px
hr
margin: 2px 0
color: #ccc
background: #ccc
.nav-list-item
display: block
font-weight: 700
line-height: 30px
overflow: hidden
padding: 0 8px 0 36px
position: relative
text-decoration: none
.icon-type
left: 10px
position: absolute
top: 6px
&:hover
background: #ccc
.icon-type
color: #686868
.nav-list-sub-item
font-weight: 400
color: #666
&:hover
color: #4d4d4d
&.collapsed
.nav-list
max-height: 0
opacity: 0
hr
margin: 0
.toggle-widget-nav
color: #4d4d4d
.board-widget-title
display: block
min-height: 20px
margin-bottom: 6px
.board-widget-content
position: relative
z-index: 1
.board-widget h4 .board-widget h4
margin: 5px 0 margin: 5px 0
@ -162,7 +80,8 @@
transition: left .1s transition: left .1s
i.fa i.fa
margin: 9px padding: 3px 9px
font-size: 24px
transition: transform 0.5s transition: transform 0.5s
.board-sidebar.is-open & .board-sidebar.is-open &

View file

@ -1,6 +1,5 @@
template(name="userAvatar") template(name="userAvatar")
.member(class="{{class}} {{# if draggable }}js-member{{else}}js-member-on-card-menu{{/if}}" .member.js-member(class="{{class}}" title="{{userData.profile.name}} ({{userData.username}})")
title="{{userData.profile.name}} ({{userData.username}})")
+avatar(user=userData size=size) +avatar(user=userData size=size)
if showStatus if showStatus
span.member-presence-status(class=presenceStatusClassName) span.member-presence-status(class=presenceStatusClassName)

View file

@ -96,6 +96,13 @@ avatar-radius = 50%
line-height: 85px line-height: 85px
width: 85px width: 85px
&.add-member
display: flex
align-items: center
justify-content: center
box-shadow: 0 0 0 2px darken(white, 25%) inset
background: darken(white, 5%)
.atMention .atMention
background: #dbdbdb background: #dbdbdb
border-radius: 3px border-radius: 3px

View file

@ -13,7 +13,7 @@ html
-webkit-text-size-adjust: 100% -webkit-text-size-adjust: 100%
body body
background: darken(white, 10%) background: darken(white, 13%)
margin: 0 margin: 0
position: relative position: relative
z-index: 0 z-index: 0
@ -23,6 +23,7 @@ body
display: flex display: flex
flex-direction: column flex-direction: column
min-height: 100vh min-height: 100vh
overflow: hidden
#content #content
position: relative position: relative
@ -216,12 +217,6 @@ dd
top: 1px top: 1px
left: -38px left: -38px
.helper
bottom: 0
display: none
position: absolute
right: 9px
&.focus &.focus
.member .member
opacity: 1 opacity: 1
@ -259,368 +254,6 @@ dd
&:focus &:focus
cursor: auto cursor: auto
.editing-members
float: right
.edit-in-progress
display: inline-block
border: 1px solid #ccc
background: #ddd
margin: 0 4px
border-radius: 2px
.inline-member
cursor: default
.inline-member-av
width: 18px
height: 18px
margin: 0 0 -4px 0
.initials
margin-left: 3px
.icon
animation: pulsate 1s ease-in alternate
animation-iteration-count: infinite
@keyframes pulsate
0%
opacity: 1
to
opacity: .4
.list-voters.compact .voter
position: relative
min-height: 36px
.member
left: 0
position: absolute
top: 0
.title
display: block
line-height: 30px
left: 0
overflow: hidden
padding-left: 38px
position: absolute
text-overflow: ellipsis
top: 0
white-space: nowrap
width: 230px
.list-voters .title
display: none
.card-composer
padding-bottom: 8px
.card-detail-badge
background-color: #dbdbdb
border-radius: 3px
color: #737373
cursor: default
display: block
height: 20px
line-height: 20px
margin: 0 4px 4px 0
padding: 5px 10px
text-align: center
text-decoration: none
&:hover
color: #737373
&.badge-state-clickable
text-decoration: underline
.badge-state-clickable:hover
color: #262626
cursor: pointer
text-decoration: underline
.card-detail-badge-aging:first-letter
text-transform: uppercase
.badge
color: #8c8c8c
float: left
height: 18px
margin: 0 3px 3px 0
padding: 0 4px 0 0
position: relative
text-decoration: none
.badge-icon
float: left
.badge-text
float: left
font-size: 12px
.badge-state-image-only
padding: 0
.badge-icon
margin-right: 0
.badge-state-clickable
cursor: pointer
.badge-text
text-decoration: underline
.badge-state-complete
background-color: #4aba12
border-radius: 3px
color: #fff
.badge-icon
color: #fff
.badge-state-unread-notification
background-color: #990f0f
border-radius: 3px
color: #fff
.badge-icon
color: #fff
.badge-state-voted
background-color: #dbdbdb
border-radius: 3px
color: #8c8c8c
.badge-icon
color: #999
.badge-state-due-soon, .badge-state-due-soon:hover
background-color: #e6bf00
border-radius: 3px
color: #fff
.badge-icon
color: #fff
.badge-state-due-now, .badge-state-due-now:hover
background-color: #990f0f
border-radius: 3px
color: #fff
.badge-icon
color: #fff
.badge-state-due-past, .badge-state-due-past:hover
background-color: #ad8585
border-radius: 3px
color: #fff
.badge-icon
color: #fff
.checklist-list:empty
display: none
.checklist
margin-bottom: 16px
.checklist.placeholder
background: #dcdcdc
border-radius: 3px
.checklist.ui-sortable-helper
background: rgba(240, 240, 240, .85)
border-radius: 3px
.checklist-title,
.current,
.window-module-title
cursor: grabbing
.icon-menu
visibility: hidden
.checklist-items-list
min-height: 2px
.checklist-item
clear: both
margin: 0 0 6px
padding: 0 0 4px 38px
position: relative
transform-origin: left bottom
transition-property: transform, opacity, height, padding, margin
transition-duration: .14s
transition-timing-function: ease-in
&.placeholder
background: #dcdcdc
border-radius: 3px
margin: -5px -5px 5px 5px
padding: 5px 0
&.ui-sortable-helper
background: rgba(240, 240, 240, .85)
border-radius: 3px
margin: -3px -3px -3px 7px
padding: 3px 3px 3px 33px
.checklist-item-checkbox
top: 2px
left: 2px
.hide-completed-items .checklist-item-fade-out
height: 0
margin: 0
opacity: 0
padding: 0
transform: rotate(-5deg) translateX(-10px) translateY(-10px)
.checklist-item-checkbox
background: #fff
border-radius: 3px
box-shadow: 0 2px 3px rgba(0, 0, 0, .1)
border: 1px solid #ccc
border-bottom-color: #b3b3b3
font-weight: 700
position: absolute
left: 6px
line-height: 18px
overflow: hidden
text-align: center
text-indent: 100%
top: -2px
height: 18px
width: 18px
white-space: nowrap
&.enabled:hover
background-color: #f0f0f0
border-color: #ccc
box-shadow: 0 1px 2px rgba(0, 0, 0, .1)
color: #8c8c8c
cursor: pointer
text-indent: 0
&.enabled:active
background-color: #e3e3e3
border-color: #ccc
box-shadow: inset 0 3px 6px rgba(0, 0, 0, .1)
color: #4d4d4d
text-indent: 0
.checklist-item-details-text
min-height: 18px
margin-bottom: 0
&.enabled:hover
color: #4d4d4d
cursor: pointer
&:empty
content: "No name"
color: #8c8c8c
.checklist-item-state-complete
.checklist-item-details-text
color: #8c8c8c
font-style: italic
text-decoration: line-through
img
opacity: .3
.checklist-item-checkbox
background-color: #f0f0f0
border-color: #dbdbdb
border-bottom-color: #ccc
box-shadow: none
text-indent: 0
&.enabled:hover
background-color: #e6e6e6
border-color: #ccc
box-shadow: none
&.enabled:active
background-color: #dbdbdb
box-shadow: inset 0 3px 6px rgba(0, 0, 0, .1)
.hide-completed-items .checklist-item-state-complete
display: none
.checklist-new-item-text,
.checklist-new-item-text:hover
background: transparent
border-color: transparent
box-shadow: none
color: #8c8c8c
cursor: pointer
margin-bottom: 4px
max-height: 32px
overflow: hidden
resize: none
text-decoration: none
.checklist-new-item.focus &
background: #fff
border-color: #2b7cab
box-shadow: 0 0 3px #2b7cab
color: #4d4d4d
cursor: text
max-height: none
resize: vertical
.checklist-progress
margin-bottom: 12px
position: relative
.checklist-progress-percentage
color: #8c8c8c
font-size: 11px
line-height: 10px
position: absolute
left: 0
top: -1px
text-align: center
width: 38px
.checklist-progress-bar
background: #dbdbdb
border-radius: 3px
clear: both
height: 8px
margin: 0 0 0 38px
overflow: hidden
position: relative
.checklist-progress-bar-current
background: #479fd1
background: linear-gradient(to bottom, #479fd1 0, #2288c3 100%)
bottom: 0
left: 0
position: absolute
top: 0
transition: width .14s ease-in, background .14s ease-in
.checklist-progress-bar-current-complete
background: #24a828
.checklist-completed-text
display: block
margin: 8px 0 0 38px
.checklist .edit
clear: both
margin-top: -5px
.explorer .av-btn
background: url(about:blank)
.atMention .atMention
background: #dbdbdb background: #dbdbdb
border-radius: 3px border-radius: 3px
@ -631,45 +264,6 @@ dd
&.me &.me
background: #cfdfe8 background: #cfdfe8
.helper
background-color: #e6e6e6
border-radius: 3px
color: #8c8c8c
font-size: 13px
line-height: 15px
margin: 4px 0 0
padding: 6px 8px
width: auto
a
color: #8c8c8c
&:hover
color: #666
.empty-list, .empty
background: #e6e6e6
border: 1px dashed #ccc
border-radius: 3px
color: #8c8c8c
display: block
padding: 6px
text-align: center
.empty-list
border-radius: 6px
padding: 25px 6px
.search-results-page-contents .empty-list
margin: 12px 0 0 52px
.window-module .empty-list
margin: 8px 0 0 38px
.loading
margin: 19px auto
text-align: center
.big-message .big-message
display: block display: block
margin: 75px auto margin: 75px auto
@ -684,28 +278,13 @@ dd
font-size: 18px font-size: 18px
line-height: 22px line-height: 22px
&.with-picture
margin-top: 35px
h1
margin-top: 20px
.callout
margin: 20px 0
.callout
background: #e3e3e3
border-radius: 5px
padding: 20px
ol
text-align: left
list-style-type: decimal
margin-left: 25px
font-size: 16px
li
margin: 10px 0
.gutter .gutter
margin-left: 38px margin-left: 38px
@keyframes fadeIn
from
opacity: 0
@keyframes flexGrowIn
from
flex-basis: 0

View file

@ -188,5 +188,6 @@
"editProfilePopup-title": "Edit Profile", "editProfilePopup-title": "Edit Profile",
"changeAvatarPopup-title": "Change Avatar", "changeAvatarPopup-title": "Change Avatar",
"changePasswordPopup-title": "Change Password", "changePasswordPopup-title": "Change Password",
"cardDetailsActionsPopup-title": "Card Actions",
"disambiguateMultiLabelPopup-title": "Disambiguate Label Action" "disambiguateMultiLabelPopup-title": "Disambiguate Label Action"
} }