summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/components/boards/body.jade5
-rw-r--r--client/components/boards/body.js99
-rw-r--r--client/components/boards/body.styl6
-rw-r--r--client/components/boards/colors.styl2
-rw-r--r--client/components/boards/router.js27
-rw-r--r--client/components/cards/details.jade87
-rw-r--r--client/components/cards/details.js6
-rw-r--r--client/components/cards/details.styl92
-rw-r--r--client/components/cards/minicard.styl11
-rw-r--r--client/components/cards/router.js15
-rw-r--r--client/components/lists/body.jade2
-rw-r--r--client/components/lists/main.js27
-rw-r--r--client/components/lists/main.styl12
-rw-r--r--client/components/main/popup.js2
-rw-r--r--client/components/sidebar/rendered.js10
-rw-r--r--client/components/sidebar/sidebar.js3
-rw-r--r--client/config/router.js1
-rw-r--r--client/lib/keyboard.js7
-rw-r--r--client/lib/utils.js18
-rw-r--r--client/styles/main.styl2
20 files changed, 231 insertions, 203 deletions
diff --git a/client/components/boards/body.jade b/client/components/boards/body.jade
index 4abc0baf..4b4c2b90 100644
--- a/client/components/boards/body.jade
+++ b/client/components/boards/body.jade
@@ -1,6 +1,7 @@
//-
XXX This template can't be transformed into a component because it is
included by iron-router. That's a bug.
+ See https://github.com/peerlibrary/meteor-blaze-components/issues/44
template(name="board")
+boardComponent
@@ -11,11 +12,11 @@ template(name="boardComponent")
.lists.js-lists
each lists
+list(this)
+ if currentCardIsInThisList
+ +cardDetails(currentCard)
if currentUser.isBoardMember
+addListForm
+boardSidebar
- if currentCard
- +cardSidebar(currentCard)
else
+message(label="board-no-found")
diff --git a/client/components/boards/body.js b/client/components/boards/body.js
index ffb132c5..5e743001 100644
--- a/client/components/boards/body.js
+++ b/client/components/boards/body.js
@@ -1,3 +1,12 @@
+// XXX This event list must be abstracted somewhere else.
+var endTransitionEvents = [
+ 'webkitTransitionEnd',
+ 'otransitionend',
+ 'oTransitionEnd',
+ 'msTransitionEnd',
+ 'transitionend'
+].join(' ');
+
BlazeComponent.extendComponent({
template: function() {
return 'boardComponent';
@@ -17,50 +26,78 @@ BlazeComponent.extendComponent({
// TODO
},
+ currentCardIsInThisList: function() {
+ var currentCard = Cards.findOne(Session.get('currentCard'));
+ var listId = this.currentData()._id;
+ return currentCard && currentCard.listId === listId;
+ },
+
onRendered: function() {
var self = this;
self.scrollLeft();
- if (Meteor.user().isBoardMember()) {
- self.$('.js-lists').sortable({
- tolerance: 'pointer',
- appendTo: '.js-lists',
- helper: 'clone',
- items: '.js-list:not(.add-list)',
- placeholder: 'list placeholder',
- start: function(event, ui) {
- $('.list.placeholder').height(ui.item.height());
- Popup.close();
- },
- stop: function() {
- self.$('.js-lists').find('.js-list:not(.add-list)').each(
- function(i, list) {
- var data = Blaze.getData(list);
- Lists.update(data._id, {
- $set: {
- sort: i
- }
- });
- }
- );
+ var lists = this.find('.js-lists');
+
+ // We want to animate the card details window closing. We rely on CSS
+ // transition for the actual animation.
+ lists._uihooks = {
+ removeElement: function(node) {
+ var removeNode = function() {
+ node.parentNode.removeChild(node);
+ };
+ if ($(node).hasClass('js-card-detail')) {
+ $(node).css({
+ flex: '0',
+ padding: 0
+ });
+ $(lists).one(endTransitionEvents, function() {
+ removeNode();
+ });
+ } else {
+ removeNode();
}
- });
+ }
+ };
+
+ if (! Meteor.user().isBoardMember())
+ return;
- // If there is no data in the board (ie, no lists) we autofocus the list
- // creation form by clicking on the corresponding element.
- if (self.data().lists().count() === 0) {
- this.openNewListForm();
+ self.$(lists).sortable({
+ tolerance: 'pointer',
+ appendTo: '.js-lists',
+ helper: 'clone',
+ items: '.js-list:not(.add-list)',
+ placeholder: 'list placeholder',
+ start: function(event, ui) {
+ $('.list.placeholder').height(ui.item.height());
+ Popup.close();
+ },
+ stop: function() {
+ self.$('.js-lists').find('.js-list:not(.add-list)').each(
+ function(i, list) {
+ var data = Blaze.getData(list);
+ Lists.update(data._id, {
+ $set: {
+ sort: i
+ }
+ });
+ }
+ );
}
+ });
+
+ // If there is no data in the board (ie, no lists) we autofocus the list
+ // creation form by clicking on the corresponding element.
+ if (self.data().lists().count() === 0) {
+ this.openNewListForm();
}
},
sidebarSize: function() {
var sidebar = this.componentChildren('boardSidebar')[0];
- if (Session.get('currentCard') !== null)
- return 'next-large-sidebar';
- else if (sidebar && sidebar.isOpen())
- return 'next-small-sidebar';
+ if (sidebar && sidebar.isOpen())
+ return 'next-sidebar';
}
}).register('boardComponent');
diff --git a/client/components/boards/body.styl b/client/components/boards/body.styl
index cb351e46..07f35bb8 100644
--- a/client/components/boards/body.styl
+++ b/client/components/boards/body.styl
@@ -16,13 +16,9 @@
bottom: 0
transition: margin .1s
- &.next-small-sidebar
+ &.next-sidebar
margin-right: 248px
- &.next-large-sidebar
- opacity: 0.8
- margin-right: 496px
-
.lists
align-items: flex-start
display: flex
diff --git a/client/components/boards/colors.styl b/client/components/boards/colors.styl
index 1db44845..a3f74ab8 100644
--- a/client/components/boards/colors.styl
+++ b/client/components/boards/colors.styl
@@ -10,7 +10,7 @@ setBoardColor(color)
background-color: color
& .minicard.is-selected .minicard-details
- border-bottom: 2px solid color
+ border-left: 3px solid color
button[type=submit].primary, input[type=submit].primary
background-color: darken(color, 20%)
diff --git a/client/components/boards/router.js b/client/components/boards/router.js
index 6845b7f2..9c5bee35 100644
--- a/client/components/boards/router.js
+++ b/client/components/boards/router.js
@@ -1,6 +1,6 @@
Meteor.subscribe('boards');
-BoardSubsManager = new SubsManager();
+var boardSubsManager = new SubsManager();
Router.route('/boards', {
name: 'Boards',
@@ -17,6 +17,7 @@ Router.route('/boards/:_id/:slug', {
name: 'Board',
template: 'board',
onAfterAction: function() {
+ // XXX We probably shouldn't rely on Session
Session.set('sidebarIsOpen', true);
Session.set('currentWidget', 'home');
Session.set('menuWidgetIsOpen', false);
@@ -26,9 +27,31 @@ Router.route('/boards/:_id/:slug', {
Session.set('currentBoard', params._id);
Session.set('currentCard', null);
- return BoardSubsManager.subscribe('board', params._id, params.slug);
+ return boardSubsManager.subscribe('board', params._id, params.slug);
},
data: function() {
return Boards.findOne(this.params._id);
}
});
+
+Router.route('/boards/:boardId/:slug/:cardId', {
+ name: 'Card',
+ template: 'board',
+ onAfterAction: function() {
+ Tracker.nonreactive(function() {
+ if (! Session.get('currentCard') && typeof Sidebar !== 'undefined') {
+ Sidebar.hide();
+ }
+ });
+ var params = this.params;
+ Session.set('currentBoard', params.boardId);
+ Session.set('currentCard', params.cardId);
+ },
+ waitOn: function() {
+ var params = this.params;
+ return boardSubsManager.subscribe('board', params.boardId, params.slug);
+ },
+ data: function() {
+ return Boards.findOne(this.params.boardId);
+ }
+});
diff --git a/client/components/cards/details.jade b/client/components/cards/details.jade
index 0de59297..55cc4b9e 100644
--- a/client/components/cards/details.jade
+++ b/client/components/cards/details.jade
@@ -1,47 +1,46 @@
-template(name="cardSidebar")
- .card-sidebar.sidebar
- .card-detail.sidebar-content.js-card-sidebar-content
- 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
- 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
- each members
- +userAvatar(userId=this size="small" cardId=../_id)
- a.card-detail-item-add-button.dark-hover.js-details-edit-members
- i.fa.fa-plus
- //- We should use "editable" to avoide repetiting ourselves
- .clearfix
- if currentUser.isBoardMember
- h3 Description
- +inlinedForm(classNames="js-card-description")
- i.fa.fa-times.js-close-inlined-form
- textarea(autofocus)= description
- button(type="submit") {{_ 'edit'}}
- else
- .js-open-inlined-form
- a {{_ 'edit'}}
- +viewer
- = description
- else if description
- h3 Description
- +viewer
- = description
- hr
- if attachments.count
- +WindowAttachmentsModule(card=this)
- +WindowActivityModule(card=this)
+template(name="cardDetails")
+ .card-detail.js-card-detail: .card-detail-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
+ 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
+ each members
+ +userAvatar(userId=this size="small" cardId=../_id)
+ a.card-detail-item-add-button.dark-hover.js-details-edit-members
+ i.fa.fa-plus
+ //- We should use "editable" to avoide repetiting ourselves
+ .clearfix
+ if currentUser.isBoardMember
+ h3 Description
+ +inlinedForm(classNames="js-card-description")
+ i.fa.fa-times.js-close-inlined-form
+ textarea(autofocus)= description
+ button(type="submit") {{_ 'edit'}}
+ else
+ .js-open-inlined-form
+ a {{_ 'edit'}}
+ +viewer
+ = description
+ else if description
+ h3 Description
+ +viewer
+ = description
+ hr
+ if attachments.count
+ +WindowAttachmentsModule(card=this)
+ +WindowActivityModule(card=this)
template(name="moveCardPopup")
+boardLists
diff --git a/client/components/cards/details.js b/client/components/cards/details.js
index cb1a3ef3..d0395129 100644
--- a/client/components/cards/details.js
+++ b/client/components/cards/details.js
@@ -1,6 +1,6 @@
BlazeComponent.extendComponent({
template: function() {
- return 'cardSidebar';
+ return 'cardDetails';
},
mixins: function() {
@@ -8,7 +8,7 @@ BlazeComponent.extendComponent({
},
calculateNextPeak: function() {
- var altitude = this.find('.js-card-sidebar-content').scrollHeight;
+ var altitude = this.find('.js-card-detail').scrollHeight;
this.callFirstWith(this, 'setNextPeak', altitude);
},
@@ -86,7 +86,7 @@ BlazeComponent.extendComponent({
'click .js-details-edit-labels': Popup.open('cardLabels')
}];
}
-}).register('cardSidebar');
+}).register('cardDetails');
Template.moveCardPopup.events({
'click .js-select-list': function() {
diff --git a/client/components/cards/details.styl b/client/components/cards/details.styl
index 106a9cfd..68a436f9 100644
--- a/client/components/cards/details.styl
+++ b/client/components/cards/details.styl
@@ -1,45 +1,57 @@
@import 'nib'
-.card-sidebar.sidebar
- width: 496px
- top: -46px
-
- .card-detail.sidebar-content
- padding: 0 20px
- z-index: 20 !important
- // XXX Animate apparition
-
- .card-detail-header
- margin: 0 -20px 5px
- padding 7px 20px 0
- background: #F7F7F7
- border-bottom: 1px solid darken(white, 10%)
- min-height: 38px
-
- i.fa
- float: right
- font-size: 1.3em
- color: darken(white, 35%)
- margin-top: 7px
-
- .card-detail-title
- font-weight: bold
- font-size: 1.7em
- margin: 3px 0 0
- padding: 0
-
- .card-detail-list
- font-size: 0.85em
- margin-bottom: 3px
-
- a.card-detail-list-title
- font-weight: bold
-
- &.is-editable
- display: inline-block
- background: darken(white, 10%)
- border-radius: 3px
- padding: 0px 5px
+.card-detail
+ padding: 0 20px
+ height: 100%
+ flex: 0 0 470px
+ overflow: hidden
+ background: white
+ border-radius: 3px
+ z-index: 20 !important
+ animation: growIn 0.2s
+ box-shadow: 0 0 7px 0 darken(white, 30%)
+ transition: flex 0.2s, padding 0.2s
+
+ .card-detail-canvas
+ width: 470px
+
+ .card-detail-header
+ margin: 0 -20px 5px
+ padding 7px 20px 0
+ background: #F7F7F7
+ border-bottom: 1px solid darken(white, 10%)
+ min-height: 38px
+
+ i.fa
+ float: right
+ font-size: 1.3em
+ color: darken(white, 35%)
+ margin-top: 7px
+
+ .card-detail-title
+ font-weight: bold
+ font-size: 1.7em
+ margin: 3px 0 0
+ padding: 0
+
+ .card-detail-list
+ font-size: 0.85em
+ margin-bottom: 3px
+
+ a.card-detail-list-title
+ font-weight: bold
+
+ &.is-editable
+ display: inline-block
+ background: darken(white, 10%)
+ border-radius: 3px
+ padding: 0px 5px
+
+@keyframes growIn
+ from
+ flex: 0 0 0
+ to
+ flex: 0 0 470px
.new-comment
position: relative
diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl
index a78cd46f..1b9e60b5 100644
--- a/client/components/cards/minicard.styl
+++ b/client/components/cards/minicard.styl
@@ -4,7 +4,6 @@
border-radius: 2px
cursor: pointer
margin-bottom: 9px
- max-width: 300px
min-height: 20px
position: relative
z-index: 0
@@ -42,10 +41,16 @@
position: relative
z-index: 10
-
&.is-selected
+ margin-left: -11px
+ transform: translateX(- @margin-left)
+ border-bottom-right-radius: 0
+ border-top-right-radius: 0
+ z-index: 100
+ box-shadow: -2px 1px 2px rgba(0,0,0,.2)
+
.minicard-details
- padding-bottom: 0
+ margin-right: 11px
a.minicard-details
text-decoration:none
diff --git a/client/components/cards/router.js b/client/components/cards/router.js
deleted file mode 100644
index 48bb9a95..00000000
--- a/client/components/cards/router.js
+++ /dev/null
@@ -1,15 +0,0 @@
-Router.route('/boards/:boardId/:slug/:cardId', {
- name: 'Card',
- template: 'board',
- waitOn: function() {
- var params = this.params;
- // XXX We probably shouldn't rely on Session
- Session.set('currentBoard', params.boardId);
- Session.set('currentCard', params.cardId);
-
- return BoardSubsManager.subscribe('board', params.boardId, params.slug);
- },
- data: function() {
- return Boards.findOne(this.params.boardId);
- }
-});
diff --git a/client/components/lists/body.jade b/client/components/lists/body.jade
index 7bd3392f..dfbe05b7 100644
--- a/client/components/lists/body.jade
+++ b/client/components/lists/body.jade
@@ -4,7 +4,7 @@ template(name="listBody")
+inlinedForm(autoclose=false position="top")
+addCardForm(listId=_id position="top")
each cards
- .minicard.card.js-minicard.js-member-droppable(
+ .minicard.card.js-minicard(
class="{{#if isSelected}}is-selected{{/if}}")
a.minicard-details.clearfix.show(href=absoluteUrl)
if cover
diff --git a/client/components/lists/main.js b/client/components/lists/main.js
index 78aad17c..8a96f5ce 100644
--- a/client/components/lists/main.js
+++ b/client/components/lists/main.js
@@ -25,13 +25,14 @@ BlazeComponent.extendComponent({
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: '.js-minicard:not(.placeholder, .hide, .js-composer)',
+ items: itemsSelector,
placeholder: 'minicard placeholder',
start: function(event, ui) {
$('.minicard.placeholder').height(ui.item.height());
@@ -57,24 +58,20 @@ BlazeComponent.extendComponent({
}
}).disableSelection();
- Utils.liveEvent('mouseover', function($el) {
- $el.find('.js-member-droppable').droppable({
+ $(document).on('mouseover', function() {
+ $cards.find(itemsSelector).droppable({
hoverClass: 'draggable-hover-card',
- accept: '.js-member',
+ accept: '.js-member,.js-label',
drop: function(event, ui) {
- var memberId = Blaze.getData(ui.draggable.get(0)).userId;
var cardId = Blaze.getData(this)._id;
- Cards.update(cardId, {$addToSet: {members: memberId}});
- }
- });
- $el.find('.js-member-droppable').droppable({
- hoverClass: 'draggable-hover-card',
- accept: '.js-label',
- drop: function(event, ui) {
- var labelId = Blaze.getData(ui.draggable.get(0))._id;
- var cardId = Blaze.getData(this)._id;
- Cards.update(cardId, {$addToSet: {labelIds: labelId}});
+ if (ui.draggable.hasClass('js-member')) {
+ var memberId = Blaze.getData(ui.draggable.get(0)).userId;
+ Cards.update(cardId, {$addToSet: {members: memberId}});
+ } else {
+ var labelId = Blaze.getData(ui.draggable.get(0))._id;
+ Cards.update(cardId, {$addToSet: {labelIds: labelId}});
+ }
}
});
});
diff --git a/client/components/lists/main.styl b/client/components/lists/main.styl
index ce408990..60a6ab98 100644
--- a/client/components/lists/main.styl
+++ b/client/components/lists/main.styl
@@ -10,8 +10,7 @@
// transparent, because that won't work during a list drag.
background: darken(white, 10%)
height: 100%
- border-right: 1px solid darken(white, 17%)
- border-left: 1px solid darken(white, 4%)
+ border-left: 1px solid darken(white, 20%)
padding: 12px 7px 5px
overflow-y: auto
@@ -19,9 +18,8 @@
margin-left: 5px
border-left: none
- &:last-child
- margin-right: 5px
- border-right: none
+ .card-detail + &
+ border-left: none
&.editable
cursor: grab
@@ -87,9 +85,6 @@
margin: 0
.minicards
- // flex: 1 1 auto
- overflow-y: auto
- overflow-x: hidden
padding: 4px 4px 1px
z-index: 1
height: 100%
@@ -105,7 +100,6 @@
padding: 7px 10px
position: relative
text-decoration: none
- animation: fadeIn 0.2s
i.fa
margin-right: 7px
diff --git a/client/components/main/popup.js b/client/components/main/popup.js
index dbd99e4d..8abe1697 100644
--- a/client/components/main/popup.js
+++ b/client/components/main/popup.js
@@ -1,4 +1,4 @@
-// XXX This event list should be abstracted somewhere else.
+// XXX This event list must be abstracted somewhere else.
var endTransitionEvents = [
'webkitTransitionEnd',
'otransitionend',
diff --git a/client/components/sidebar/rendered.js b/client/components/sidebar/rendered.js
index 2b58bf33..36b1255c 100644
--- a/client/components/sidebar/rendered.js
+++ b/client/components/sidebar/rendered.js
@@ -1,10 +1,11 @@
-Template.membersWidget.rendered = function() {
+Template.membersWidget.onRendered(function() {
+ var self = this;
if (! Meteor.user().isBoardMember())
return;
_.each(['.js-member', '.js-label'], function(className) {
- Utils.liveEvent('mouseover', function($this) {
- $this.find(className).draggable({
+ $(document).on('mouseover', function() {
+ self.$(className).draggable({
appendTo: 'body',
helper: 'clone',
revert: 'invalid',
@@ -17,5 +18,4 @@ Template.membersWidget.rendered = function() {
});
});
});
-};
-
+});
diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js
index 3f0142d4..af676bf2 100644
--- a/client/components/sidebar/sidebar.js
+++ b/client/components/sidebar/sidebar.js
@@ -8,7 +8,8 @@ BlazeComponent.extendComponent({
},
onCreated: function() {
- this._isOpen = new ReactiveVar(true);
+ this._isOpen = new ReactiveVar(! Session.get('currentCard'));
+ Sidebar = this;
},
isOpen: function() {
diff --git a/client/config/router.js b/client/config/router.js
index c859013f..2fa1908d 100644
--- a/client/config/router.js
+++ b/client/config/router.js
@@ -19,7 +19,6 @@ Router.configure({
// Reset default sessions
Session.set('error', false);
- Session.set('warning', false);
Popup.close();
diff --git a/client/lib/keyboard.js b/client/lib/keyboard.js
index c1267938..8601e623 100644
--- a/client/lib/keyboard.js
+++ b/client/lib/keyboard.js
@@ -19,12 +19,7 @@ Mousetrap.bind('esc', function() {
});
Mousetrap.bind('w', function() {
- if (! Session.get('currentCard')) {
- Sidebar.toogle();
- } else {
- Utils.goBoardId(Session.get('currentBoard'));
- Sidebar.hide();
- }
+ Sidebar.toogle();
});
Mousetrap.bind('q', function() {
diff --git a/client/lib/utils.js b/client/lib/utils.js
index 9e92e999..7c117d4b 100644
--- a/client/lib/utils.js
+++ b/client/lib/utils.js
@@ -18,18 +18,6 @@ Utils = {
};
},
- Warning: {
- get: function() {
- return Session.get('warning');
- },
- open: function(desc) {
- Session.set('warning', { desc: desc });
- },
- close: function() {
- Session.set('warning', false);
- }
- },
-
// XXX We should remove these two methods
goBoardId: function(_id) {
var board = Boards.findOne(_id);
@@ -49,12 +37,6 @@ Utils = {
});
},
- liveEvent: function(events, callback) {
- $(document).on(events, function() {
- callback($(this));
- });
- },
-
capitalize: function(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
},
diff --git a/client/styles/main.styl b/client/styles/main.styl
index 0f12e35e..8d1f9591 100644
--- a/client/styles/main.styl
+++ b/client/styles/main.styl
@@ -229,6 +229,8 @@ dd
font-weight: 700
line-height: 18px
+.ui-draggable-dragging
+ z-index: 200
.board-backgrounds-list