summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.jshintrc1
-rw-r--r--.meteor/packages1
-rw-r--r--.meteor/versions1
-rw-r--r--bower.json7
-rw-r--r--client/components/boards/body.jade4
-rw-r--r--client/components/boards/body.js22
-rw-r--r--client/components/boards/body.styl16
-rw-r--r--client/components/cards/details.js8
-rw-r--r--client/components/cards/minicard.styl14
-rw-r--r--client/components/lists/body.jade79
-rw-r--r--client/components/lists/body.js14
-rw-r--r--client/components/lists/main.jade5
-rw-r--r--client/components/lists/main.js7
-rw-r--r--client/components/lists/main.styl59
-rw-r--r--client/components/mixins/infiniteScrolling.js (renamed from client/components/sidebar/infiniteScrolling.js)0
-rw-r--r--client/components/mixins/perfectScrollbar.js6
-rw-r--r--client/components/mixins/perfectScrollbar.styl2
-rw-r--r--client/components/sidebar/helpers.js2
-rw-r--r--client/components/sidebar/rendered.js21
-rw-r--r--client/components/sidebar/sidebar.jade (renamed from client/components/sidebar/templates.jade)4
-rw-r--r--client/components/sidebar/sidebar.js26
-rw-r--r--client/styles/fancy-scrollbar.styl45
22 files changed, 162 insertions, 182 deletions
diff --git a/.jshintrc b/.jshintrc
index ebbf3c24..c6fcaf8d 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -54,6 +54,7 @@
"SubsManager": false,
"Mousetrap": false,
"Avatar": true,
+ "Ps": true,
// Our collections
"Boards": true,
diff --git a/.meteor/packages b/.meteor/packages
index 96888a0d..c04186c6 100644
--- a/.meteor/packages
+++ b/.meteor/packages
@@ -32,6 +32,7 @@ audit-argument-checks
iron:router
meteorhacks:subs-manager
mquandalle:autofocus
+mquandalle:bower
mquandalle:moment
ongoworks:speakingurl
raix:handlebar-helpers
diff --git a/.meteor/versions b/.meteor/versions
index 9b5f0177..bfa2145d 100644
--- a/.meteor/versions
+++ b/.meteor/versions
@@ -77,6 +77,7 @@ mongo@1.1.0
mongo-livedata@1.0.8
mousetrap:mousetrap@1.4.6_1
mquandalle:autofocus@1.0.0
+mquandalle:bower@1.4.1
mquandalle:jade@0.4.3
mquandalle:jade-compiler@0.4.3
mquandalle:jquery-textcomplete@0.3.9_1
diff --git a/bower.json b/bower.json
new file mode 100644
index 00000000..deca1fda
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,7 @@
+{
+ "name": "LibreBoard",
+ "dependencies": {
+ "perfect-scrollbar": "0.6.2"
+ },
+ "private": true
+}
diff --git a/client/components/boards/body.jade b/client/components/boards/body.jade
index 4b4c2b90..b157b742 100644
--- a/client/components/boards/body.jade
+++ b/client/components/boards/body.jade
@@ -16,12 +16,12 @@ template(name="boardComponent")
+cardDetails(currentCard)
if currentUser.isBoardMember
+addListForm
- +boardSidebar
+ +sidebar
else
+message(label="board-no-found")
template(name="addListForm")
- .list.js-list.add-list.js-add-list
+ .list.js-list.list-composer.js-list-composer
+inlinedForm(autoclose=false)
input.list-name-input(type="text" placeholder="{{_ 'add-list'}}"
autocomplete="off" autofocus value=getCache)
diff --git a/client/components/boards/body.js b/client/components/boards/body.js
index 5e743001..e4aad646 100644
--- a/client/components/boards/body.js
+++ b/client/components/boards/body.js
@@ -22,8 +22,20 @@ BlazeComponent.extendComponent({
});
},
- scrollLeft: function() {
- // TODO
+ scrollLeft: function(position) {
+ position = position || 0;
+ var $container = $(this.find('.js-lists'));
+ var containerWidth = $container.width();
+ var currentScrollPosition = $container.scrollLeft();
+ if (position < currentScrollPosition) {
+ $container.animate({
+ scrollLeft: position
+ });
+ } else if (position > currentScrollPosition + containerWidth) {
+ $container.animate({
+ scrollLeft: Math.max(0, position - containerWidth)
+ });
+ }
},
currentCardIsInThisList: function() {
@@ -67,14 +79,14 @@ BlazeComponent.extendComponent({
tolerance: 'pointer',
appendTo: '.js-lists',
helper: 'clone',
- items: '.js-list:not(.add-list)',
+ items: '.js-list:not(.js-list-composer)',
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(
+ self.$('.js-lists').find('.js-list:not(.js-list-composer)').each(
function(i, list) {
var data = Blaze.getData(list);
Lists.update(data._id, {
@@ -95,7 +107,7 @@ BlazeComponent.extendComponent({
},
sidebarSize: function() {
- var sidebar = this.componentChildren('boardSidebar')[0];
+ var sidebar = this.componentChildren('sidebar')[0];
if (sidebar && sidebar.isOpen())
return 'next-sidebar';
}
diff --git a/client/components/boards/body.styl b/client/components/boards/body.styl
index 07f35bb8..de4963ab 100644
--- a/client/components/boards/body.styl
+++ b/client/components/boards/body.styl
@@ -32,19 +32,3 @@
right: 0
bottom: 0
left: 0
-
- &::-webkit-scrollbar
- height: 13px
- width: 13px
-
- &::-webkit-scrollbar-thumb:vertical,
- &::-webkit-scrollbar-thumb:horizontal
- background: rgba(255, 255, 255, .4)
-
- &::-webkit-scrollbar-track-piece
- background: rgba(0, 0, 0, .15)
-
- &::-webkit-scrollbar-button
- display: block
- height: 5px
- width: 5px
diff --git a/client/components/cards/details.js b/client/components/cards/details.js
index d0395129..385310bb 100644
--- a/client/components/cards/details.js
+++ b/client/components/cards/details.js
@@ -17,6 +17,14 @@ BlazeComponent.extendComponent({
activitiesComponent.loadNextPage();
},
+ onRendered: function() {
+ var bodyBoardComponent = this.componentParent();
+ var additionalMargin = 550;
+ var $cardDetails = this.$(this.firstNode());
+ var scollLeft = $cardDetails.offset().left + additionalMargin;
+ bodyBoardComponent.scrollLeft(scollLeft);
+ },
+
events: function() {
return [{
'click .js-move-card': Popup.open('moveCard'),
diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl
index 1b9e60b5..775d31eb 100644
--- a/client/components/cards/minicard.styl
+++ b/client/components/cards/minicard.styl
@@ -8,6 +8,9 @@
position: relative
z-index: 0
overflow: hidden
+ transition: transform 0.2s,
+ border-radius 0.2s,
+ border-left 0.2s
a
color: #4d4d4d
@@ -39,19 +42,15 @@
.minicard-details
padding: 6px 8px 2px
position: relative
- z-index: 10
+ // z-index: 1
&.is-selected
- margin-left: -11px
- transform: translateX(- @margin-left)
+ transform: translateX(11px)
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
- margin-right: 11px
-
a.minicard-details
text-decoration:none
@@ -122,6 +121,9 @@
.minicard-members:empty
display: none
+ &.ui-sortable-helper
+ transform: rotate(4deg)
+
.badges
float: left
diff --git a/client/components/lists/body.jade b/client/components/lists/body.jade
index dfbe05b7..9d4a903d 100644
--- a/client/components/lists/body.jade
+++ b/client/components/lists/body.jade
@@ -1,43 +1,44 @@
template(name="listBody")
- .minicards.clearfix.js-minicards
- if cards.count
- +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
- if currentUser.isBoardMember
- +inlinedForm(autoclose=false position="bottom")
- +addCardForm(listId=_id position="bottom")
- else
- if newCardFormIsVisible.get
- a.open-card-composer.js-open-inlined-form
- i.fa.fa-plus
- | {{_ 'add-card'}}
+ .list-body.js-perfect-scrollbar
+ .minicards.clearfix.js-minicards
+ if cards.count
+ +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
+ if currentUser.isBoardMember
+ +inlinedForm(autoclose=false position="bottom")
+ +addCardForm(listId=_id position="bottom")
+ else
+ if newCardFormIsVisible.get
+ a.open-card-composer.js-open-inlined-form
+ i.fa.fa-plus
+ | {{_ 'add-card'}}
template(name="addCardForm")
.minicard.js-composer
diff --git a/client/components/lists/body.js b/client/components/lists/body.js
index 70db42d1..d8238c9a 100644
--- a/client/components/lists/body.js
+++ b/client/components/lists/body.js
@@ -3,6 +3,10 @@ BlazeComponent.extendComponent({
return 'listBody';
},
+ mixins: function() {
+ return [Mixins.PerfectScrollbar];
+ },
+
isSelected: function() {
return Session.equals('currentCard', this.currentData()._id);
},
@@ -62,13 +66,21 @@ BlazeComponent.extendComponent({
this.newCardFormIsVisible.set(value);
},
+ scrollToBottom: function() {
+ var $container = $(this.firstNode());
+ $container.animate({
+ scrollTop: $container.height()
+ });
+ },
+
onCreated: function() {
this.newCardFormIsVisible = new ReactiveVar(true);
},
events: function() {
return [{
- submit: this.addCard
+ submit: this.addCard,
+ 'click .open-card-composer': this.scrollToBottom
}];
}
}).register('listBody');
diff --git a/client/components/lists/main.jade b/client/components/lists/main.jade
index dd4bb49a..c959b87f 100644
--- a/client/components/lists/main.jade
+++ b/client/components/lists/main.jade
@@ -1,5 +1,4 @@
template(name='list')
.list.js-list(id="js-list-{{_id}}")
- .list-wrapper
- +listHeader
- +listBody
+ +listHeader
+ +listBody
diff --git a/client/components/lists/main.js b/client/components/lists/main.js
index 8a96f5ce..3464865a 100644
--- a/client/components/lists/main.js
+++ b/client/components/lists/main.js
@@ -19,9 +19,10 @@ BlazeComponent.extendComponent({
// XXX The jQuery UI sortable plugin is far from ideal here. First we include
// all jQuery components but only use one. Second, it modifies the DOM itself,
// resulting in Blaze abandoning reactive update of the nodes that have been
- // moved which result in bugs if multiple users use the board in real time.
- // I tried sortable:sortable but that was not better. Should we “simply” write
- // the drag&drop code ourselves?
+ // moved which result in bugs if multiple users use the board in real time. I
+ // tried sortable:sortable but that was not better. And dragula is not
+ // powerful enough for our use casesShould we “simply” write the drag&drop
+ // code ourselves?
onRendered: function() {
if (Meteor.user().isBoardMember()) {
var boardComponent = this.componentParent();
diff --git a/client/components/lists/main.styl b/client/components/lists/main.styl
index 60a6ab98..47dfcf28 100644
--- a/client/components/lists/main.styl
+++ b/client/components/lists/main.styl
@@ -11,8 +11,7 @@
background: darken(white, 10%)
height: 100%
border-left: 1px solid darken(white, 20%)
- padding: 12px 7px 5px
- overflow-y: auto
+ padding: 0
&:first-child
margin-left: 5px
@@ -21,15 +20,20 @@
.card-detail + &
border-left: none
- &.editable
- cursor: grab
+ &.ui-sortable-helper
+ cursor: grabbing
+ box-shadow: -2px 2px 8px rgba(0, 0, 0, .3),
+ 0 0 1px rgba(0, 0, 0, .5)
+ transform: rotate(4deg)
- .list-wrapper
- cursor: default
+ &.placeholder
+ background-color: rgba(0, 0, 0, .2)
+ border-color: transparent
+ box-shadow: none
+ height: 100px
- &.add-list
- &.fade
- opacity: 0
+ &.list-composer
+ padding: 17px
.list-name-input
background: rgba(0, 0, 0, .05)
@@ -55,7 +59,7 @@
.list-header
flex: 0 0 auto
- padding: 10px 26px 4px 6px
+ margin: 20px 15px 4px
position: relative
min-height: 20px
@@ -74,24 +78,23 @@
.list-header-menu-icon
background-clip: content-box
background-origin: content-box
- padding: 6px 8px
+ // padding: 6px 8px
position: absolute
- top: 3px
- right: -5px
+ top: 0
+ right: 0
color: #a6a6a6
.list-header-num-cards
color: #8c8c8c
margin: 0
-.minicards
- padding: 4px 4px 1px
- z-index: 1
- height: 100%
+.list-body
+ flex: 1
+ overflow-y: auto
+ padding: 5px 11px
- &::-webkit-scrollbar-button
- display: block
- height: 4px
+ .ps-scrollbar-y-rail
+ transform: translateX(2px)
.open-card-composer
border-radius: 2px
@@ -100,6 +103,7 @@
padding: 7px 10px
position: relative
text-decoration: none
+ animation: fadeIn 0.3s
i.fa
margin-right: 7px
@@ -117,18 +121,3 @@
opacity: 0
to
opacity: 1
-
-.list.placeholder
- background-color: rgba(0, 0, 0, .2)
- border-color: transparent
- box-shadow: none
- height: 100px
-
-.list.ui-sortable-helper
- cursor: grabbing
- box-shadow: -2px 2px 8px rgba(0, 0, 0, .3), 0 0 1px rgba(0, 0, 0, .5)
- transform: rotate(4deg)
-
-
-.list.ui-sortable-helper .list-header-menu-icon
- display: none
diff --git a/client/components/sidebar/infiniteScrolling.js b/client/components/mixins/infiniteScrolling.js
index df3b8901..df3b8901 100644
--- a/client/components/sidebar/infiniteScrolling.js
+++ b/client/components/mixins/infiniteScrolling.js
diff --git a/client/components/mixins/perfectScrollbar.js b/client/components/mixins/perfectScrollbar.js
new file mode 100644
index 00000000..06e8aedd
--- /dev/null
+++ b/client/components/mixins/perfectScrollbar.js
@@ -0,0 +1,6 @@
+Mixins.PerfectScrollbar = BlazeComponent.extendComponent({
+ onRendered: function() {
+ var component = this.mixinParent();
+ Ps.initialize(component.find('.js-perfect-scrollbar'));
+ }
+});
diff --git a/client/components/mixins/perfectScrollbar.styl b/client/components/mixins/perfectScrollbar.styl
new file mode 100644
index 00000000..c8267668
--- /dev/null
+++ b/client/components/mixins/perfectScrollbar.styl
@@ -0,0 +1,2 @@
+.ps-container
+ position: relative
diff --git a/client/components/sidebar/helpers.js b/client/components/sidebar/helpers.js
index a76dad7f..15035bd4 100644
--- a/client/components/sidebar/helpers.js
+++ b/client/components/sidebar/helpers.js
@@ -3,7 +3,7 @@ var widgetTitles = {
background: 'change-background'
};
-Template.boardSidebar.helpers({
+Template.sidebar.helpers({
currentWidget: function() {
return Session.get('currentWidget') + 'Sidebar';
},
diff --git a/client/components/sidebar/rendered.js b/client/components/sidebar/rendered.js
deleted file mode 100644
index 36b1255c..00000000
--- a/client/components/sidebar/rendered.js
+++ /dev/null
@@ -1,21 +0,0 @@
-Template.membersWidget.onRendered(function() {
- var self = this;
- if (! Meteor.user().isBoardMember())
- return;
-
- _.each(['.js-member', '.js-label'], function(className) {
- $(document).on('mouseover', function() {
- self.$(className).draggable({
- appendTo: 'body',
- helper: 'clone',
- revert: 'invalid',
- revertDuration: 150,
- snap: false,
- snapMode: 'both',
- start: function() {
- Popup.close();
- }
- });
- });
- });
-});
diff --git a/client/components/sidebar/templates.jade b/client/components/sidebar/sidebar.jade
index 23a1a87e..07cd777c 100644
--- a/client/components/sidebar/templates.jade
+++ b/client/components/sidebar/sidebar.jade
@@ -1,9 +1,9 @@
-template(name="boardSidebar")
+template(name="sidebar")
.board-sidebar.sidebar(class="{{#if isOpen}}is-open{{/if}}")
a.sidebar-tongue.js-toogle-sidebar(
class="{{#if isTongueHidden}}is-hidden{{/if}}")
i.fa.fa-chevron-left
- .sidebar-content.js-board-sidebar-content
+ .sidebar-content.js-board-sidebar-content.js-perfect-scrollbar
//- XXX https://github.com/peerlibrary/meteor-blaze-components/issues/30
if Filter.isActive
+filterSidebar
diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js
index af676bf2..764f16eb 100644
--- a/client/components/sidebar/sidebar.js
+++ b/client/components/sidebar/sidebar.js
@@ -1,10 +1,10 @@
BlazeComponent.extendComponent({
template: function() {
- return 'boardSidebar';
+ return 'sidebar';
},
mixins: function() {
- return [Mixins.InfiniteScrolling];
+ return [Mixins.InfiniteScrolling, Mixins.PerfectScrollbar];
},
onCreated: function() {
@@ -46,6 +46,26 @@ BlazeComponent.extendComponent({
return this.isOpen() && Filter.isActive();
},
+ onRendered: function() {
+ var self = this;
+ if (! Meteor.user().isBoardMember())
+ return;
+
+ $(document).on('mouseover', function() {
+ self.$('.js-member,.js-label').draggable({
+ appendTo: 'body',
+ helper: 'clone',
+ revert: 'invalid',
+ revertDuration: 150,
+ snap: false,
+ snapMode: 'both',
+ start: function() {
+ Popup.close();
+ }
+ });
+ });
+ },
+
events: function() {
// XXX Hacky, we need some kind of `super`
var mixinEvents = this.getMixin(Mixins.InfiniteScrolling).events();
@@ -53,4 +73,4 @@ BlazeComponent.extendComponent({
'click .js-toogle-sidebar': this.toogle
}]);
}
-}).register('boardSidebar');
+}).register('sidebar');
diff --git a/client/styles/fancy-scrollbar.styl b/client/styles/fancy-scrollbar.styl
deleted file mode 100644
index c7a30018..00000000
--- a/client/styles/fancy-scrollbar.styl
+++ /dev/null
@@ -1,45 +0,0 @@
-.fancy-scrollbar
- -webkit-overflow-scrolling: touch
-
- .fancy-scrollbar::-webkit-scrollbar
- height: 9px
- width: 9px
-
- &::-webkit-scrollbar-button:start:decrement,
- &::-webkit-scrollbar-button:end:increment
- background: transparent
- display: none
-
- &::-webkit-scrollbar-track-piece
- background: #dbdbdb
-
- &:vertical:start
- border-top-left-radius: 5px
- border-top-right-radius: 5px
- border-bottom-right-radius: 0
- border-bottom-left-radius: 0
-
- &:vertical:end
- border-top-left-radius: 0
- border-top-right-radius: 0
- border-bottom-right-radius: 5px
- border-bottom-left-radius: 5px
-
- &:horizontal:start
- border-top-left-radius: 5px
- border-top-right-radius: 0
- border-bottom-right-radius: 0
- border-bottom-left-radius: 5px
-
- &:horizontal:end
- border-top-left-radius: 0
- border-top-right-radius: 5px
- border-bottom-right-radius: 5px
- border-bottom-left-radius: 0
-
- &::-webkit-scrollbar-thumb:vertical,
- &::-webkit-scrollbar-thumb:horizontal
- background: #c2c2c2
- border-radius: 5px
- display: block
- height: 50px