summaryrefslogtreecommitdiffstats
path: root/client/components/boards
diff options
context:
space:
mode:
authorMaxime Quandalle <maxime@quandalle.com>2015-05-24 12:30:58 +0200
committerMaxime Quandalle <maxime@quandalle.com>2015-05-24 22:11:40 +0200
commit781577db041e0008de22f31bcc1cb11ae96670e0 (patch)
treeb45e220039b81149c463ee060dcc03d79e589a77 /client/components/boards
parent40b605f7d897db6eb2697be1748741221378e71c (diff)
downloadwekan-781577db041e0008de22f31bcc1cb11ae96670e0.tar.gz
wekan-781577db041e0008de22f31bcc1cb11ae96670e0.tar.bz2
wekan-781577db041e0008de22f31bcc1cb11ae96670e0.zip
Experiment new ergonomics to interact with card details
The idea is that by displaying card details in a sidebar stuck on the right of the screen, the mouse had to travel too much before interacting with it. I also don’t want to use the Trello solution (modal) on big screens, because I like the ability to interact with the selected card and with the board at the same time (like in a e-mail client). The solution introduced in this commit consist of opening the card detail in a column next to the minicard list. This commit also fix right sidebar members and labels drag and drop.
Diffstat (limited to 'client/components/boards')
-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
5 files changed, 98 insertions, 41 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);
+ }
+});