diff options
author | Maxime Quandalle <maxime@quandalle.com> | 2015-06-05 21:37:13 +0200 |
---|---|---|
committer | Maxime Quandalle <maxime@quandalle.com> | 2015-06-05 21:37:13 +0200 |
commit | dea52907bdbed92c95dec7e7e832ac95d9f9d388 (patch) | |
tree | 22edfa8b3eb623084edcb2e25abb0bd8285b9cc4 /client/components/cards | |
parent | 97807abd709f4355964b52105c0931d6671ff20b (diff) | |
download | wekan-dea52907bdbed92c95dec7e7e832ac95d9f9d388.tar.gz wekan-dea52907bdbed92c95dec7e7e832ac95d9f9d388.tar.bz2 wekan-dea52907bdbed92c95dec7e7e832ac95d9f9d388.zip |
Start designing the card details pane
Implement a dynamic overflow to focus sight on the pane.
Diffstat (limited to 'client/components/cards')
-rw-r--r-- | client/components/cards/details.jade | 112 | ||||
-rw-r--r-- | client/components/cards/details.js | 107 | ||||
-rw-r--r-- | client/components/cards/details.styl | 96 | ||||
-rw-r--r-- | client/components/cards/labels.styl | 45 | ||||
-rw-r--r-- | client/components/cards/minicard.js | 8 | ||||
-rw-r--r-- | client/components/cards/minicard.styl | 36 | ||||
-rw-r--r-- | client/components/cards/popups.jade | 11 | ||||
-rw-r--r-- | client/components/cards/templates.html | 54 |
8 files changed, 213 insertions, 256 deletions
diff --git a/client/components/cards/details.jade b/client/components/cards/details.jade index 4e8fd8c0..46929f56 100644 --- a/client/components/cards/details.jade +++ b/client/components/cards/details.jade @@ -1,47 +1,105 @@ template(name="cardDetails") - .card-detail.js-card-detail: .card-detail-canvas + section.card-details.js-card-details: .card-details-canvas if cover - .card-detail-cover(style="background-image: url({{ card.cover.url }})") - .card-detail-header(class="{{#if currentUser.isBoardMember}}editable{{/if}}") - a.js-close-card-detail - i.fa.fa-times-thin - h2.card-detail-title.js-card-title= title - p.card-detail-list.js-move-card - | {{_ 'in-list'}} - a.card-detail-list-title( - class="{{#if currentUser.isBoardMember}}js-open-move-from-header is-editable{{/if}}") - = list.title - hr - //- if card.members - .card-detail-item.card-detail-item-members.clearfix.js-card-detail-members - h3.card-detail-item-header {{_ 'members'}} - .js-card-detail-members-list.clearfix + .card-details-cover(style="background-image: url({{ cover.url }})") + + .card-details-header + +inlinedForm(classNames="js-card-details-title") + input.field.single-line(type="text" value=title autofocus) + .edit-controls.clearfix + button.primary.confirm(type="submit") {{_ 'save'}} + a.fa.fa-times-thin.js-close-inlined-form + else + a.fa.fa-angle-left.close-card-details.js-close-card-details + a.fa.fa-bars.card-details-menu.js-open-card-details-menu + h2.card-details-title.js-card-title( + class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}") + = title + 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 +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 - //- 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 h3 Description +inlinedForm(classNames="js-card-description") - a.fa.fa-times-thin.js-close-inlined-form +editor(autofocus=true) = description - button(type="submit") {{_ 'edit'}} + .edit-controls.clearfix + button.primary(type="submit") {{_ 'edit'}} + a.fa.fa-times-thin.js-close-inlined-form else - .js-open-inlined-form - a {{_ 'edit'}} - +viewer - = description + a.js-open-inlined-form + if description + +viewer + = description + else + | {{_ 'edit'}} else if description h3 Description +viewer = description - hr if attachments.count + hr +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") +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'}} diff --git a/client/components/cards/details.js b/client/components/cards/details.js index 385310bb..d44adb67 100644 --- a/client/components/cards/details.js +++ b/client/components/cards/details.js @@ -8,7 +8,7 @@ BlazeComponent.extendComponent({ }, calculateNextPeak: function() { - var altitude = this.find('.js-card-detail').scrollHeight; + var altitude = this.find('.js-card-details').scrollHeight; this.callFirstWith(this, 'setNextPeak', altitude); }, @@ -25,77 +25,67 @@ BlazeComponent.extendComponent({ bodyBoardComponent.scrollLeft(scollLeft); }, + onDestroyed: function() { + this.componentParent().showOverlay.set(false); + }, + + updateCard: function(modifier) { + Cards.update(this.data()._id, { + $set: modifier + }); + }, + events: function() { return [{ + 'click .js-close-card-details': function() { + Utils.goBoardId(this.data().boardId); + }, 'click .js-move-card': Popup.open('moveCard'), + 'click .js-open-card-details-menu': Popup.open('cardDetailsActions'), 'submit .js-card-description': function(evt) { evt.preventDefault(); - var cardId = Session.get('currentCard'); - var form = this.componentChildren('inlinedForm')[0]; - var newDescription = form.getValue(); - Cards.update(cardId, { - $set: { - description: newDescription - } - }); - form.close(); - }, - 'click .js-close-card-detail': function() { - Utils.goBoardId(Session.get('currentBoard')); - }, - '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'); + var description = this.currentComponent().getValue(); + this.updateCard({ description: description }); }, - 'submit #WindowTitleEdit': function(event, t) { - var title = t.find('#title').value; + 'submit .js-card-details-title': function(evt) { + evt.preventDefault(); + var title = this.currentComponent().getValue(); if ($.trim(title)) { - Cards.update(this.card._id, { - $set: { - title: title - } - }, function(err) { - if (! err) $('.editing').removeClass('editing'); - }); + this.updateCard({ title: title }); } - - event.preventDefault(); }, - 'submit #WindowDescEdit': function(event, t) { - Cards.update(this.card._id, { - $set: { - description: t.find('#desc').value - } - }, function(err) { - if (! err) $('.editing').removeClass('editing'); - }); - event.preventDefault(); + 'click .js-member': Popup.open('cardMember'), + 'click .js-add-members': Popup.open('cardMembers'), + 'click .js-add-labels': Popup.open('cardLabels'), + 'mouseenter .js-card-details': function() { + this.componentParent().showOverlay.set(true); }, - 'click .member': Popup.open('cardMember'), - 'click .js-details-edit-members': Popup.open('cardMembers'), - 'click .js-details-edit-labels': Popup.open('cardLabels') + 'mouseleave .js-card-details': function(evt) { + // We don't want to hide the overlay if the mouse is entering a pop-over + var $pointedElement = $(evt.toElement || evt.relatedTarget); + if ($pointedElement.closest('.pop-over').length === 0) + this.componentParent().showOverlay.set(false); + } }]; } }).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({ 'click .js-select-list': function() { // XXX We should *not* get the currentCard from the global state, but @@ -107,5 +97,6 @@ Template.moveCardPopup.events({ listId: newListId } }); + Popup.close(); } }); diff --git a/client/components/cards/details.styl b/client/components/cards/details.styl index 6b1a4cd4..4da8a371 100644 --- a/client/components/cards/details.styl +++ b/client/components/cards/details.styl @@ -1,57 +1,73 @@ @import 'nib' -.card-detail +.card-details padding: 0 20px height: 100% - flex: 0 0 470px + flex-shrink: 0 + flex-basis: 470px + will-change: flex-basis overflow: hidden background: white border-radius: 3px z-index: 20 !important - animation: growIn 0.2s + animation: flexGrowIn 0.2s 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 - .card-detail-header + .card-details-header margin: 0 -20px 5px padding 7px 20px 0 background: #F7F7F7 border-bottom: 1px solid darken(white, 10%) 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 - font-size: 1.3em - color: darken(white, 35%) - margin-top: 7px + position: absolute + bottom: 6px + right: 15px - .card-detail-title + .card-details-title font-weight: bold - font-size: 1.7em - margin: 3px 0 0 + font-size: 1.33em + margin: 3px 0 padding: 0 - .card-detail-list - font-size: 0.85em - margin-bottom: 3px + .card-details-list + font-size: 0.85em + margin-bottom: 3px - a.card-detail-list-title - font-weight: bold + a.card-details-list-title + font-weight: bold + + &.is-editable + display: inline-block + background: darken(white, 10%) + border-radius: 3px + padding: 0px 5px - &.is-editable - display: inline-block - background: darken(white, 10%) - border-radius: 3px - padding: 0px 5px + .card-details-items + display: flex + margin: 15px 0 -@keyframes growIn - from - flex: 0 0 0 - to - flex: 0 0 470px + .card-details-item + flex-grow: 1 + + h3 + font-size: 14px + color: darken(white, 45%) .new-comment position: relative @@ -107,30 +123,6 @@ &:focus 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 padding-bottom: 8px diff --git a/client/components/cards/labels.styl b/client/components/cards/labels.styl index 9514ce45..c93ecd12 100644 --- a/client/components/cards/labels.styl +++ b/client/components/cards/labels.styl @@ -24,6 +24,10 @@ width: @height padding: 0 + &.add-label + box-shadow: 0 0 0 2px darken(white, 25%) inset + background: darken(white, 5%) + .card-label-green background-color: #3cb500 @@ -84,31 +88,6 @@ left: 0 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 cursor: pointer opacity: .75 @@ -170,19 +149,3 @@ &:hover 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 diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js index 81d8c0d4..8f229be8 100644 --- a/client/components/cards/minicard.js +++ b/client/components/cards/minicard.js @@ -23,6 +23,14 @@ BlazeComponent.extendComponent({ evt.preventDefault(); var methodName = evt.shiftKey ? 'toogleRange' : 'toogle'; 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')); } }, diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl index a5110584..ebad8dec 100644 --- a/client/components/cards/minicard.styl +++ b/client/components/cards/minicard.styl @@ -43,14 +43,13 @@ color: #4d4d4d overflow: hidden transition: transform 0.2s, - border-radius 0.2s, - border-left 0.2s + border-radius 0.2s .is-selected & transform: translateX(11px) border-bottom-right-radius: 0 border-top-right-radius: 0 - z-index: 100 + z-index: 25 box-shadow: -2px 1px 2px rgba(0,0,0,.2) .minicard-cover @@ -66,56 +65,33 @@ background-size: auto background-position: center - .minicard-details-overlay - background: transparent - bottom: 0 - left: 0 - position: absolute - right: 0 - top: 0 - .minicard-dropzone display: none .minicard.drophover .minicard-dropzone 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 display: block font-weight: 400 - margin: 0 0 4px overflow: hidden + margin-bottom: 2px text-decoration: none word-wrap: break-word + clear: both &::selection background: transparent .minicard-labels - padding-top: 3px - margin-top: 4px float: right .minicard-label float: right - width: 8px + width: 11px height: @width border-radius: 2px - margin-left: 4px + margin-right: 3px .minicard-members float: right diff --git a/client/components/cards/popups.jade b/client/components/cards/popups.jade deleted file mode 100644 index 0d10c147..00000000 --- a/client/components/cards/popups.jade +++ /dev/null @@ -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 diff --git a/client/components/cards/templates.html b/client/components/cards/templates.html index 4c65e429..23f9ce4f 100644 --- a/client/components/cards/templates.html +++ b/client/components/cards/templates.html @@ -33,26 +33,6 @@ </p> </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"> <div> <ul class="pop-over-list"> @@ -114,7 +94,7 @@ </template> <template name="cardDetailSidebarOld"> - <div class="card-detail-window clearfix"> + <div class="card-details-window clearfix"> {{# 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> @@ -127,7 +107,7 @@ {{ /if }} <div class="window-header clearfix"> <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> <div class="edit edit-heavy"> <form id="WindowTitleEdit"> @@ -147,39 +127,39 @@ </div> </div> <div class="window-main-col clearfix"> - <div class="card-detail-data gutter clearfix"> - <div class="card-detail-item card-detail-item-block clear clearfix editable"> + <div class="card-details-data gutter clearfix"> + <div class="card-details-item card-details-item-block clear clearfix editable"> {{# if card.members }} - <div class="card-detail-item card-detail-item-members clearfix js-card-detail-members"> - <h3 class="card-detail-item-header">{{_ 'members'}}</h3> - <div class="js-card-detail-members-list clearfix"> + <div class="card-details-item card-details-item-members clearfix js-card-details-members"> + <h3 class="card-details-item-header">{{_ 'members'}}</h3> + <div class="js-card-details-members-list clearfix"> {{# each card.members }} {{> userAvatar userId=this size="small" cardId=../card._id }} {{/ 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> </a> </div> </div> {{/ if }} {{# if card.labels }} - <div class="card-detail-item card-detail-item-labels clearfix js-card-detail-labels"> - <h3 class="card-detail-item-header">{{_ 'labels'}}</h3> - <div class="js-card-detail-labels-list clearfix editable-labels js-edit-label"> + <div class="card-details-item card-details-item-labels clearfix js-card-details-labels"> + <h3 class="card-details-item-header">{{_ 'labels'}}</h3> + <div class="js-card-details-labels-list clearfix editable-labels js-edit-label"> {{# each card.labels }} <span class="card-label card-label-{{color}}" title="{{name}}">{{ name }}</span> {{/ 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> </a> </div> </div> {{/ 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 }} - <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 }} - <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 }} <div class="current markeddown hide-on-edit js-card-desc js-show-with-desc"> {{#viewer}}{{ card.description }}{{/viewer}} @@ -194,7 +174,7 @@ </p> {{/ if }} {{/ if }} - <div class="card-detail-edit edit"> + <div class="card-details-edit edit"> <form id="WindowDescEdit"> {{#editor class="field single-line2" id="desc"}}{{ card.description }}{{/editor}} <div class="edit-controls clearfix"> @@ -218,7 +198,7 @@ </template> <template name="WindowActivityModule"> - <div class="card-detailwindow-module"> + <div class="card-detailswindow-module"> <div class="window-module-title window-module-title-no-divider"> <span class="window-module-title-icon icon-lg fa fa-comments-o"></span> <h3>{{ _ 'activity'}}</h3> |