From dcc64f44f9f81d32c8071c6bdac86546eaeb57a0 Mon Sep 17 00:00:00 2001 From: Maxime Quandalle Date: Wed, 27 May 2015 17:17:00 +0200 Subject: UI improvements * Implement visibility choice on board creation; * Rework the board header bar. Remove links to un-implemented features; * Implement a board star counter (visible if the board have >2 stars); * Define a new icon (a thin cross) to close elements; * Remove $(document).on('mouseover') event handlers that were basically fired hundreds of times for nothing, we now define a proper Tracker dependency to execute jquery-ui plugin initialization only when something has changed; * Bug fixes related to list scrolling. --- client/components/lists/body.jade | 29 +------------ client/components/lists/body.js | 34 +++++++-------- client/components/lists/main.js | 87 ++++++++++++++++++++++----------------- 3 files changed, 67 insertions(+), 83 deletions(-) (limited to 'client/components/lists') diff --git a/client/components/lists/body.jade b/client/components/lists/body.jade index 9d4a903d..3e769206 100644 --- a/client/components/lists/body.jade +++ b/client/components/lists/body.jade @@ -5,32 +5,7 @@ template(name="listBody") +inlinedForm(autoclose=false position="top") +addCardForm(listId=_id position="top") each cards - .minicard.card.js-minicard( - class="{{#if isSelected}}is-selected{{/if}}") - a.minicard-details.clearfix.show(href=absoluteUrl) - if cover - .minicard-cover.js-card-cover(style="background-image: url({{cover.url}});") - if labels - .minicard-labels - each labels - .minicard-label(class="card-label-{{color}}" title="{{name}}") - .minicard-title= title - if members - .minicard-members.js-minicard-members - each members - +userAvatar(userId=this size="small" cardId="{{../_id}}") - .badges - if comments.count - .badge(title="{{_ 'card-comments-title' comments.count }}") - span.badge-icon.icon-sm.fa.fa-comment-o - .badge-text= comments.count - if description - .badge.badge-state-image-only(title=description) - span.badge-icon.icon-sm.fa.fa-align-left - if attachments.count - .badge - span.badge-icon.icon-sm.fa.fa-paperclip - span.badge-text= attachments.count + +minicard(this) if currentUser.isBoardMember +inlinedForm(autoclose=false position="bottom") +addCardForm(listId=_id position="bottom") @@ -49,4 +24,4 @@ template(name="addCardForm") .minicard-members.js-minicard-composer-members .add-controls.clearfix button.primary.confirm(type="submit") {{_ 'add'}} - a.fa.fa-times.dark-hover.cancel.js-close-inlined-form + a.fa.fa-times-thin.js-close-inlined-form diff --git a/client/components/lists/body.js b/client/components/lists/body.js index d8238c9a..8400af96 100644 --- a/client/components/lists/body.js +++ b/client/components/lists/body.js @@ -7,10 +7,6 @@ BlazeComponent.extendComponent({ return [Mixins.PerfectScrollbar]; }, - isSelected: function() { - return Session.equals('currentCard', this.currentData()._id); - }, - openForm: function(options) { options = options || {}; options.position = options.position || 'top'; @@ -37,11 +33,6 @@ BlazeComponent.extendComponent({ sortIndex = Utils.getSortIndex(this.find('.js-minicard:last'), null); } - // Clear the form in-memory cache - // var inputCacheKey = "addCard-" + this.listId; - // InputsCache.set(inputCacheKey, ''); - - // title trim if not empty then if ($.trim(title)) { Cards.insert({ title: title, @@ -49,16 +40,18 @@ BlazeComponent.extendComponent({ boardId: this.data().board()._id, sort: sortIndex }, function(err, _id) { - // In case the filter is active we need to add the newly - // inserted card in the list of exceptions -- cards that are - // not filtered. Otherwise the card will disappear instantly. + // In case the filter is active we need to add the newly inserted card + // in the list of exceptions -- cards that are not filtered. Otherwise + // the card will disappear instantly. // See https://github.com/libreboard/libreboard/issues/80 Filter.addException(_id); }); // We keep the form opened, empty it, and scroll to it. textarea.val('').focus(); - Utils.Scroll(this.find('.js-minicards')).top(1000, true); + if (position === 'bottom') { + this.scrollToBottom(); + } } }, @@ -67,9 +60,9 @@ BlazeComponent.extendComponent({ }, scrollToBottom: function() { - var $container = $(this.firstNode()); - $container.animate({ - scrollTop: $container.height() + var container = this.firstNode(); + $(container).animate({ + scrollTop: container.scrollHeight }); }, @@ -94,7 +87,12 @@ BlazeComponent.extendComponent({ // Pressing Enter should submit the card if (evt.keyCode === 13) { evt.preventDefault(); - $(evt.currentTarget).parents('form:first').submit(); + var $form = $(evt.currentTarget).parents('form:first'); + // XXX For some reason $form.submit() does not work (it's probably a bug + // of blaze-component related to the fact that the submit event is non- + // bubbling). This is why we click on the submit button instead -- which + // work. + $form.find('button[type=submit]').click(); // Pressing Tab should open the form of the next column, and Maj+Tab go // in the reverse order @@ -102,7 +100,7 @@ BlazeComponent.extendComponent({ evt.preventDefault(); var isReverse = evt.shiftKey; var list = $('#js-list-' + this.data().listId); - var listSelector = '.js-list:not(.js-add-list)'; + var listSelector = '.js-list:not(.js-list-composer)'; var nextList = list[isReverse ? 'prev' : 'next'](listSelector).get(0); // If there isn't no next list, loop back to the beginning. if (! nextList) { diff --git a/client/components/lists/main.js b/client/components/lists/main.js index 3464865a..8f86183a 100644 --- a/client/components/lists/main.js +++ b/client/components/lists/main.js @@ -24,58 +24,69 @@ BlazeComponent.extendComponent({ // powerful enough for our use casesShould we “simply” write the drag&drop // code ourselves? onRendered: function() { - if (Meteor.user().isBoardMember()) { - var boardComponent = this.componentParent(); - var itemsSelector = '.js-minicard:not(.placeholder, .hide, .js-composer)'; - var $cards = this.$('.js-minicards'); - $cards.sortable({ - connectWith: '.js-minicards', - tolerance: 'pointer', - appendTo: '.js-lists', - helper: 'clone', - items: itemsSelector, - placeholder: 'minicard placeholder', - start: function(event, ui) { - $('.minicard.placeholder').height(ui.item.height()); - Popup.close(); - boardComponent.showNewCardForms(false); - }, - stop: function(event, ui) { - // To attribute the new index number, we need to get the dom element - // of the previous and the following card -- if any. - var cardDomElement = ui.item.get(0); - var prevCardDomElement = ui.item.prev('.js-minicard').get(0); - var nextCardDomElement = ui.item.next('.js-minicard').get(0); - var sort = Utils.getSortIndex(prevCardDomElement, nextCardDomElement); - var cardId = Blaze.getData(cardDomElement)._id; - var listId = Blaze.getData(ui.item.parents('.list').get(0))._id; - Cards.update(cardId, { - $set: { - listId: listId, - sort: sort - } - }); - boardComponent.showNewCardForms(true); - } - }).disableSelection(); + var self = this; + if (! Meteor.userId() || ! Meteor.user().isBoardMember()) + return; - $(document).on('mouseover', function() { + var boardComponent = self.componentParent(); + var itemsSelector = '.js-minicard:not(.placeholder, .hide, .js-composer)'; + var $cards = self.$('.js-minicards'); + $cards.sortable({ + connectWith: '.js-minicards', + tolerance: 'pointer', + appendTo: '.js-lists', + helper: 'clone', + items: itemsSelector, + placeholder: 'minicard placeholder', + start: function(event, ui) { + $('.minicard.placeholder').height(ui.item.height()); + Popup.close(); + boardComponent.showNewCardForms(false); + }, + stop: function(event, ui) { + // To attribute the new index number, we need to get the dom element + // of the previous and the following card -- if any. + var cardDomElement = ui.item.get(0); + var prevCardDomElement = ui.item.prev('.js-minicard').get(0); + var nextCardDomElement = ui.item.next('.js-minicard').get(0); + var sort = Utils.getSortIndex(prevCardDomElement, nextCardDomElement); + var cardId = Blaze.getData(cardDomElement)._id; + var listId = Blaze.getData(ui.item.parents('.list').get(0))._id; + Cards.update(cardId, { + $set: { + listId: listId, + sort: sort + } + }); + boardComponent.showNewCardForms(true); + } + }); + + // We want to re-run this function any time a card is added. + self.autorun(function() { + var currentBoardId = Tracker.nonreactive(function() { + return Session.get('currentBoard'); + }); + Cards.find({ boardId: currentBoardId }).fetch(); + Tracker.afterFlush(function() { $cards.find(itemsSelector).droppable({ hoverClass: 'draggable-hover-card', accept: '.js-member,.js-label', drop: function(event, ui) { var cardId = Blaze.getData(this)._id; + var addToSet; if (ui.draggable.hasClass('js-member')) { var memberId = Blaze.getData(ui.draggable.get(0)).userId; - Cards.update(cardId, {$addToSet: {members: memberId}}); + addToSet = { members: memberId }; } else { var labelId = Blaze.getData(ui.draggable.get(0))._id; - Cards.update(cardId, {$addToSet: {labelIds: labelId}}); + addToSet = { labelIds: labelId }; } + Cards.update(cardId, { $addToSet: addToSet }); } }); }); - } + }); } }).register('list'); -- cgit v1.2.3-1-g7c22