mirror of
https://github.com/wekan/wekan.git
synced 2025-12-15 23:10:13 +01:00
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.
This commit is contained in:
parent
40b605f7d8
commit
781577db04
22 changed files with 225 additions and 203 deletions
5
.jscsrc
5
.jscsrc
|
|
@ -66,11 +66,6 @@
|
||||||
"catch",
|
"catch",
|
||||||
"typeof"
|
"typeof"
|
||||||
],
|
],
|
||||||
"safeContextKeyword": [
|
|
||||||
"self",
|
|
||||||
"context",
|
|
||||||
"view"
|
|
||||||
],
|
|
||||||
"validateLineBreaks": "LF",
|
"validateLineBreaks": "LF",
|
||||||
"validateQuoteMarks": "'",
|
"validateQuoteMarks": "'",
|
||||||
"validateIndentation": 2,
|
"validateIndentation": 2,
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,6 @@
|
||||||
// XXX Temp, we should remove these
|
// XXX Temp, we should remove these
|
||||||
"allowIsBoardAdmin": true,
|
"allowIsBoardAdmin": true,
|
||||||
"allowIsBoardMember": true,
|
"allowIsBoardMember": true,
|
||||||
"BoardSubsManager": true,
|
|
||||||
"currentlyOpenedForm": true,
|
"currentlyOpenedForm": true,
|
||||||
"Emoji": true
|
"Emoji": true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
//-
|
//-
|
||||||
XXX This template can't be transformed into a component because it is
|
XXX This template can't be transformed into a component because it is
|
||||||
included by iron-router. That's a bug.
|
included by iron-router. That's a bug.
|
||||||
|
See https://github.com/peerlibrary/meteor-blaze-components/issues/44
|
||||||
template(name="board")
|
template(name="board")
|
||||||
+boardComponent
|
+boardComponent
|
||||||
|
|
||||||
|
|
@ -11,11 +12,11 @@ template(name="boardComponent")
|
||||||
.lists.js-lists
|
.lists.js-lists
|
||||||
each lists
|
each lists
|
||||||
+list(this)
|
+list(this)
|
||||||
|
if currentCardIsInThisList
|
||||||
|
+cardDetails(currentCard)
|
||||||
if currentUser.isBoardMember
|
if currentUser.isBoardMember
|
||||||
+addListForm
|
+addListForm
|
||||||
+boardSidebar
|
+boardSidebar
|
||||||
if currentCard
|
|
||||||
+cardSidebar(currentCard)
|
|
||||||
else
|
else
|
||||||
+message(label="board-no-found")
|
+message(label="board-no-found")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,12 @@
|
||||||
|
// XXX This event list must be abstracted somewhere else.
|
||||||
|
var endTransitionEvents = [
|
||||||
|
'webkitTransitionEnd',
|
||||||
|
'otransitionend',
|
||||||
|
'oTransitionEnd',
|
||||||
|
'msTransitionEnd',
|
||||||
|
'transitionend'
|
||||||
|
].join(' ');
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
template: function() {
|
template: function() {
|
||||||
return 'boardComponent';
|
return 'boardComponent';
|
||||||
|
|
@ -17,50 +26,78 @@ BlazeComponent.extendComponent({
|
||||||
// TODO
|
// TODO
|
||||||
},
|
},
|
||||||
|
|
||||||
|
currentCardIsInThisList: function() {
|
||||||
|
var currentCard = Cards.findOne(Session.get('currentCard'));
|
||||||
|
var listId = this.currentData()._id;
|
||||||
|
return currentCard && currentCard.listId === listId;
|
||||||
|
},
|
||||||
|
|
||||||
onRendered: function() {
|
onRendered: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.scrollLeft();
|
self.scrollLeft();
|
||||||
|
|
||||||
if (Meteor.user().isBoardMember()) {
|
var lists = this.find('.js-lists');
|
||||||
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
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If there is no data in the board (ie, no lists) we autofocus the list
|
// We want to animate the card details window closing. We rely on CSS
|
||||||
// creation form by clicking on the corresponding element.
|
// transition for the actual animation.
|
||||||
if (self.data().lists().count() === 0) {
|
lists._uihooks = {
|
||||||
this.openNewListForm();
|
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;
|
||||||
|
|
||||||
|
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() {
|
sidebarSize: function() {
|
||||||
var sidebar = this.componentChildren('boardSidebar')[0];
|
var sidebar = this.componentChildren('boardSidebar')[0];
|
||||||
if (Session.get('currentCard') !== null)
|
if (sidebar && sidebar.isOpen())
|
||||||
return 'next-large-sidebar';
|
return 'next-sidebar';
|
||||||
else if (sidebar && sidebar.isOpen())
|
|
||||||
return 'next-small-sidebar';
|
|
||||||
}
|
}
|
||||||
}).register('boardComponent');
|
}).register('boardComponent');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,9 @@
|
||||||
bottom: 0
|
bottom: 0
|
||||||
transition: margin .1s
|
transition: margin .1s
|
||||||
|
|
||||||
&.next-small-sidebar
|
&.next-sidebar
|
||||||
margin-right: 248px
|
margin-right: 248px
|
||||||
|
|
||||||
&.next-large-sidebar
|
|
||||||
opacity: 0.8
|
|
||||||
margin-right: 496px
|
|
||||||
|
|
||||||
.lists
|
.lists
|
||||||
align-items: flex-start
|
align-items: flex-start
|
||||||
display: flex
|
display: flex
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ setBoardColor(color)
|
||||||
background-color: color
|
background-color: color
|
||||||
|
|
||||||
& .minicard.is-selected .minicard-details
|
& .minicard.is-selected .minicard-details
|
||||||
border-bottom: 2px solid color
|
border-left: 3px solid color
|
||||||
|
|
||||||
button[type=submit].primary, input[type=submit].primary
|
button[type=submit].primary, input[type=submit].primary
|
||||||
background-color: darken(color, 20%)
|
background-color: darken(color, 20%)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
Meteor.subscribe('boards');
|
Meteor.subscribe('boards');
|
||||||
|
|
||||||
BoardSubsManager = new SubsManager();
|
var boardSubsManager = new SubsManager();
|
||||||
|
|
||||||
Router.route('/boards', {
|
Router.route('/boards', {
|
||||||
name: 'Boards',
|
name: 'Boards',
|
||||||
|
|
@ -17,6 +17,7 @@ Router.route('/boards/:_id/:slug', {
|
||||||
name: 'Board',
|
name: 'Board',
|
||||||
template: 'board',
|
template: 'board',
|
||||||
onAfterAction: function() {
|
onAfterAction: function() {
|
||||||
|
// XXX We probably shouldn't rely on Session
|
||||||
Session.set('sidebarIsOpen', true);
|
Session.set('sidebarIsOpen', true);
|
||||||
Session.set('currentWidget', 'home');
|
Session.set('currentWidget', 'home');
|
||||||
Session.set('menuWidgetIsOpen', false);
|
Session.set('menuWidgetIsOpen', false);
|
||||||
|
|
@ -26,9 +27,31 @@ Router.route('/boards/:_id/:slug', {
|
||||||
Session.set('currentBoard', params._id);
|
Session.set('currentBoard', params._id);
|
||||||
Session.set('currentCard', null);
|
Session.set('currentCard', null);
|
||||||
|
|
||||||
return BoardSubsManager.subscribe('board', params._id, params.slug);
|
return boardSubsManager.subscribe('board', params._id, params.slug);
|
||||||
},
|
},
|
||||||
data: function() {
|
data: function() {
|
||||||
return Boards.findOne(this.params._id);
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,46 @@
|
||||||
template(name="cardSidebar")
|
template(name="cardDetails")
|
||||||
.card-sidebar.sidebar
|
.card-detail.js-card-detail: .card-detail-canvas
|
||||||
.card-detail.sidebar-content.js-card-sidebar-content
|
if cover
|
||||||
if cover
|
.card-detail-cover(style="background-image: url({{ card.cover.url }})")
|
||||||
.card-detail-cover(style="background-image: url({{ card.cover.url }})")
|
.card-detail-header(class="{{#if currentUser.isBoardMember}}editable{{/if}}")
|
||||||
.card-detail-header(class="{{#if currentUser.isBoardMember}}editable{{/if}}")
|
a.js-close-card-detail
|
||||||
a.js-close-card-detail
|
i.fa.fa-times
|
||||||
i.fa.fa-times
|
h2.card-detail-title.js-card-title= title
|
||||||
h2.card-detail-title.js-card-title= title
|
p.card-detail-list.js-move-card
|
||||||
p.card-detail-list.js-move-card
|
| {{_ 'in-list'}}
|
||||||
| {{_ 'in-list'}}
|
a.card-detail-list-title(
|
||||||
a.card-detail-list-title(
|
class="{{#if currentUser.isBoardMember}}js-open-move-from-header is-editable{{/if}}")
|
||||||
class="{{#if currentUser.isBoardMember}}js-open-move-from-header is-editable{{/if}}")
|
= list.title
|
||||||
= list.title
|
hr
|
||||||
hr
|
//- if card.members
|
||||||
//- if card.members
|
.card-detail-item.card-detail-item-members.clearfix.js-card-detail-members
|
||||||
.card-detail-item.card-detail-item-members.clearfix.js-card-detail-members
|
h3.card-detail-item-header {{_ 'members'}}
|
||||||
h3.card-detail-item-header {{_ 'members'}}
|
.js-card-detail-members-list.clearfix
|
||||||
.js-card-detail-members-list.clearfix
|
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.card-detail-item-add-button.dark-hover.js-details-edit-members
|
i.fa.fa-plus
|
||||||
i.fa.fa-plus
|
//- We should use "editable" to avoide repetiting ourselves
|
||||||
//- We should use "editable" to avoide repetiting ourselves
|
.clearfix
|
||||||
.clearfix
|
if currentUser.isBoardMember
|
||||||
if currentUser.isBoardMember
|
h3 Description
|
||||||
h3 Description
|
+inlinedForm(classNames="js-card-description")
|
||||||
+inlinedForm(classNames="js-card-description")
|
i.fa.fa-times.js-close-inlined-form
|
||||||
i.fa.fa-times.js-close-inlined-form
|
textarea(autofocus)= description
|
||||||
textarea(autofocus)= description
|
button(type="submit") {{_ 'edit'}}
|
||||||
button(type="submit") {{_ 'edit'}}
|
else
|
||||||
else
|
.js-open-inlined-form
|
||||||
.js-open-inlined-form
|
a {{_ 'edit'}}
|
||||||
a {{_ 'edit'}}
|
+viewer
|
||||||
+viewer
|
= description
|
||||||
= description
|
else if description
|
||||||
else if description
|
h3 Description
|
||||||
h3 Description
|
+viewer
|
||||||
+viewer
|
= description
|
||||||
= description
|
hr
|
||||||
hr
|
if attachments.count
|
||||||
if attachments.count
|
+WindowAttachmentsModule(card=this)
|
||||||
+WindowAttachmentsModule(card=this)
|
+WindowActivityModule(card=this)
|
||||||
+WindowActivityModule(card=this)
|
|
||||||
|
|
||||||
template(name="moveCardPopup")
|
template(name="moveCardPopup")
|
||||||
+boardLists
|
+boardLists
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
template: function() {
|
template: function() {
|
||||||
return 'cardSidebar';
|
return 'cardDetails';
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: function() {
|
mixins: function() {
|
||||||
|
|
@ -8,7 +8,7 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
calculateNextPeak: function() {
|
calculateNextPeak: function() {
|
||||||
var altitude = this.find('.js-card-sidebar-content').scrollHeight;
|
var altitude = this.find('.js-card-detail').scrollHeight;
|
||||||
this.callFirstWith(this, 'setNextPeak', altitude);
|
this.callFirstWith(this, 'setNextPeak', altitude);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ BlazeComponent.extendComponent({
|
||||||
'click .js-details-edit-labels': Popup.open('cardLabels')
|
'click .js-details-edit-labels': Popup.open('cardLabels')
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
}).register('cardSidebar');
|
}).register('cardDetails');
|
||||||
|
|
||||||
Template.moveCardPopup.events({
|
Template.moveCardPopup.events({
|
||||||
'click .js-select-list': function() {
|
'click .js-select-list': function() {
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,57 @@
|
||||||
@import 'nib'
|
@import 'nib'
|
||||||
|
|
||||||
.card-sidebar.sidebar
|
.card-detail
|
||||||
width: 496px
|
padding: 0 20px
|
||||||
top: -46px
|
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.sidebar-content
|
.card-detail-canvas
|
||||||
padding: 0 20px
|
width: 470px
|
||||||
z-index: 20 !important
|
|
||||||
// XXX Animate apparition
|
|
||||||
|
|
||||||
.card-detail-header
|
.card-detail-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
|
||||||
|
|
||||||
i.fa
|
i.fa
|
||||||
float: right
|
float: right
|
||||||
font-size: 1.3em
|
font-size: 1.3em
|
||||||
color: darken(white, 35%)
|
color: darken(white, 35%)
|
||||||
margin-top: 7px
|
margin-top: 7px
|
||||||
|
|
||||||
.card-detail-title
|
.card-detail-title
|
||||||
font-weight: bold
|
font-weight: bold
|
||||||
font-size: 1.7em
|
font-size: 1.7em
|
||||||
margin: 3px 0 0
|
margin: 3px 0 0
|
||||||
padding: 0
|
padding: 0
|
||||||
|
|
||||||
.card-detail-list
|
.card-detail-list
|
||||||
font-size: 0.85em
|
font-size: 0.85em
|
||||||
margin-bottom: 3px
|
margin-bottom: 3px
|
||||||
|
|
||||||
a.card-detail-list-title
|
a.card-detail-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
|
||||||
|
from
|
||||||
|
flex: 0 0 0
|
||||||
|
to
|
||||||
|
flex: 0 0 470px
|
||||||
|
|
||||||
.new-comment
|
.new-comment
|
||||||
position: relative
|
position: relative
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
border-radius: 2px
|
border-radius: 2px
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
margin-bottom: 9px
|
margin-bottom: 9px
|
||||||
max-width: 300px
|
|
||||||
min-height: 20px
|
min-height: 20px
|
||||||
position: relative
|
position: relative
|
||||||
z-index: 0
|
z-index: 0
|
||||||
|
|
@ -42,10 +41,16 @@
|
||||||
position: relative
|
position: relative
|
||||||
z-index: 10
|
z-index: 10
|
||||||
|
|
||||||
|
|
||||||
&.is-selected
|
&.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
|
.minicard-details
|
||||||
padding-bottom: 0
|
margin-right: 11px
|
||||||
|
|
||||||
a.minicard-details
|
a.minicard-details
|
||||||
text-decoration:none
|
text-decoration:none
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -4,7 +4,7 @@ template(name="listBody")
|
||||||
+inlinedForm(autoclose=false position="top")
|
+inlinedForm(autoclose=false position="top")
|
||||||
+addCardForm(listId=_id position="top")
|
+addCardForm(listId=_id position="top")
|
||||||
each cards
|
each cards
|
||||||
.minicard.card.js-minicard.js-member-droppable(
|
.minicard.card.js-minicard(
|
||||||
class="{{#if isSelected}}is-selected{{/if}}")
|
class="{{#if isSelected}}is-selected{{/if}}")
|
||||||
a.minicard-details.clearfix.show(href=absoluteUrl)
|
a.minicard-details.clearfix.show(href=absoluteUrl)
|
||||||
if cover
|
if cover
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,14 @@ BlazeComponent.extendComponent({
|
||||||
onRendered: function() {
|
onRendered: function() {
|
||||||
if (Meteor.user().isBoardMember()) {
|
if (Meteor.user().isBoardMember()) {
|
||||||
var boardComponent = this.componentParent();
|
var boardComponent = this.componentParent();
|
||||||
|
var itemsSelector = '.js-minicard:not(.placeholder, .hide, .js-composer)';
|
||||||
var $cards = this.$('.js-minicards');
|
var $cards = this.$('.js-minicards');
|
||||||
$cards.sortable({
|
$cards.sortable({
|
||||||
connectWith: '.js-minicards',
|
connectWith: '.js-minicards',
|
||||||
tolerance: 'pointer',
|
tolerance: 'pointer',
|
||||||
appendTo: '.js-lists',
|
appendTo: '.js-lists',
|
||||||
helper: 'clone',
|
helper: 'clone',
|
||||||
items: '.js-minicard:not(.placeholder, .hide, .js-composer)',
|
items: itemsSelector,
|
||||||
placeholder: 'minicard placeholder',
|
placeholder: 'minicard placeholder',
|
||||||
start: function(event, ui) {
|
start: function(event, ui) {
|
||||||
$('.minicard.placeholder').height(ui.item.height());
|
$('.minicard.placeholder').height(ui.item.height());
|
||||||
|
|
@ -57,24 +58,20 @@ BlazeComponent.extendComponent({
|
||||||
}
|
}
|
||||||
}).disableSelection();
|
}).disableSelection();
|
||||||
|
|
||||||
Utils.liveEvent('mouseover', function($el) {
|
$(document).on('mouseover', function() {
|
||||||
$el.find('.js-member-droppable').droppable({
|
$cards.find(itemsSelector).droppable({
|
||||||
hoverClass: 'draggable-hover-card',
|
hoverClass: 'draggable-hover-card',
|
||||||
accept: '.js-member',
|
accept: '.js-member,.js-label',
|
||||||
drop: function(event, ui) {
|
drop: function(event, ui) {
|
||||||
var memberId = Blaze.getData(ui.draggable.get(0)).userId;
|
|
||||||
var cardId = Blaze.getData(this)._id;
|
var cardId = Blaze.getData(this)._id;
|
||||||
Cards.update(cardId, {$addToSet: {members: memberId}});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$el.find('.js-member-droppable').droppable({
|
if (ui.draggable.hasClass('js-member')) {
|
||||||
hoverClass: 'draggable-hover-card',
|
var memberId = Blaze.getData(ui.draggable.get(0)).userId;
|
||||||
accept: '.js-label',
|
Cards.update(cardId, {$addToSet: {members: memberId}});
|
||||||
drop: function(event, ui) {
|
} else {
|
||||||
var labelId = Blaze.getData(ui.draggable.get(0))._id;
|
var labelId = Blaze.getData(ui.draggable.get(0))._id;
|
||||||
var cardId = Blaze.getData(this)._id;
|
Cards.update(cardId, {$addToSet: {labelIds: labelId}});
|
||||||
Cards.update(cardId, {$addToSet: {labelIds: labelId}});
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@
|
||||||
// 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, 10%)
|
||||||
height: 100%
|
height: 100%
|
||||||
border-right: 1px solid darken(white, 17%)
|
border-left: 1px solid darken(white, 20%)
|
||||||
border-left: 1px solid darken(white, 4%)
|
|
||||||
padding: 12px 7px 5px
|
padding: 12px 7px 5px
|
||||||
overflow-y: auto
|
overflow-y: auto
|
||||||
|
|
||||||
|
|
@ -19,9 +18,8 @@
|
||||||
margin-left: 5px
|
margin-left: 5px
|
||||||
border-left: none
|
border-left: none
|
||||||
|
|
||||||
&:last-child
|
.card-detail + &
|
||||||
margin-right: 5px
|
border-left: none
|
||||||
border-right: none
|
|
||||||
|
|
||||||
&.editable
|
&.editable
|
||||||
cursor: grab
|
cursor: grab
|
||||||
|
|
@ -87,9 +85,6 @@
|
||||||
margin: 0
|
margin: 0
|
||||||
|
|
||||||
.minicards
|
.minicards
|
||||||
// flex: 1 1 auto
|
|
||||||
overflow-y: auto
|
|
||||||
overflow-x: hidden
|
|
||||||
padding: 4px 4px 1px
|
padding: 4px 4px 1px
|
||||||
z-index: 1
|
z-index: 1
|
||||||
height: 100%
|
height: 100%
|
||||||
|
|
@ -105,7 +100,6 @@
|
||||||
padding: 7px 10px
|
padding: 7px 10px
|
||||||
position: relative
|
position: relative
|
||||||
text-decoration: none
|
text-decoration: none
|
||||||
animation: fadeIn 0.2s
|
|
||||||
|
|
||||||
i.fa
|
i.fa
|
||||||
margin-right: 7px
|
margin-right: 7px
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// XXX This event list should be abstracted somewhere else.
|
// XXX This event list must be abstracted somewhere else.
|
||||||
var endTransitionEvents = [
|
var endTransitionEvents = [
|
||||||
'webkitTransitionEnd',
|
'webkitTransitionEnd',
|
||||||
'otransitionend',
|
'otransitionend',
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
Template.membersWidget.rendered = function() {
|
Template.membersWidget.onRendered(function() {
|
||||||
|
var self = this;
|
||||||
if (! Meteor.user().isBoardMember())
|
if (! Meteor.user().isBoardMember())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_.each(['.js-member', '.js-label'], function(className) {
|
_.each(['.js-member', '.js-label'], function(className) {
|
||||||
Utils.liveEvent('mouseover', function($this) {
|
$(document).on('mouseover', function() {
|
||||||
$this.find(className).draggable({
|
self.$(className).draggable({
|
||||||
appendTo: 'body',
|
appendTo: 'body',
|
||||||
helper: 'clone',
|
helper: 'clone',
|
||||||
revert: 'invalid',
|
revert: 'invalid',
|
||||||
|
|
@ -17,5 +18,4 @@ Template.membersWidget.rendered = function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
onCreated: function() {
|
onCreated: function() {
|
||||||
this._isOpen = new ReactiveVar(true);
|
this._isOpen = new ReactiveVar(! Session.get('currentCard'));
|
||||||
|
Sidebar = this;
|
||||||
},
|
},
|
||||||
|
|
||||||
isOpen: function() {
|
isOpen: function() {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ Router.configure({
|
||||||
|
|
||||||
// Reset default sessions
|
// Reset default sessions
|
||||||
Session.set('error', false);
|
Session.set('error', false);
|
||||||
Session.set('warning', false);
|
|
||||||
|
|
||||||
Popup.close();
|
Popup.close();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,7 @@ Mousetrap.bind('esc', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
Mousetrap.bind('w', function() {
|
Mousetrap.bind('w', function() {
|
||||||
if (! Session.get('currentCard')) {
|
Sidebar.toogle();
|
||||||
Sidebar.toogle();
|
|
||||||
} else {
|
|
||||||
Utils.goBoardId(Session.get('currentBoard'));
|
|
||||||
Sidebar.hide();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Mousetrap.bind('q', function() {
|
Mousetrap.bind('q', function() {
|
||||||
|
|
|
||||||
|
|
@ -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
|
// XXX We should remove these two methods
|
||||||
goBoardId: function(_id) {
|
goBoardId: function(_id) {
|
||||||
var board = Boards.findOne(_id);
|
var board = Boards.findOne(_id);
|
||||||
|
|
@ -49,12 +37,6 @@ Utils = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
liveEvent: function(events, callback) {
|
|
||||||
$(document).on(events, function() {
|
|
||||||
callback($(this));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
capitalize: function(string) {
|
capitalize: function(string) {
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -229,6 +229,8 @@ dd
|
||||||
font-weight: 700
|
font-weight: 700
|
||||||
line-height: 18px
|
line-height: 18px
|
||||||
|
|
||||||
|
.ui-draggable-dragging
|
||||||
|
z-index: 200
|
||||||
|
|
||||||
.board-backgrounds-list
|
.board-backgrounds-list
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue