summaryrefslogtreecommitdiffstats
path: root/client/components
diff options
context:
space:
mode:
Diffstat (limited to 'client/components')
-rw-r--r--client/components/cards/minicard.jade6
-rw-r--r--client/components/cards/minicard.js9
-rw-r--r--client/components/cards/minicard.styl37
-rw-r--r--client/components/lists/listBody.jade13
-rw-r--r--client/components/lists/listBody.js119
5 files changed, 159 insertions, 25 deletions
diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade
index 3f7e0940..95fa6e31 100644
--- a/client/components/cards/minicard.jade
+++ b/client/components/cards/minicard.jade
@@ -1,5 +1,7 @@
template(name="minicard")
- .minicard
+ .minicard(
+ class="{{#if importedCard}}imported-card{{/if}}"
+ class="{{#if importedBoard}}imported-board{{/if}}")
if cover
.minicard-cover(style="background-image: url('{{cover.url}}');")
if labels
@@ -13,6 +15,8 @@ template(name="minicard")
if $eq 'prefix-with-parent' currentBoard.presentParentTask
.parent-prefix
| {{ parentCardName }}
+ if imported
+ span.imported-icon.fa.fa-share-alt
+viewer
| {{ title }}
if $eq 'subtext-with-full-path' currentBoard.presentParentTask
diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js
index a98b5730..5202232b 100644
--- a/client/components/cards/minicard.js
+++ b/client/components/cards/minicard.js
@@ -6,4 +6,13 @@ BlazeComponent.extendComponent({
template() {
return 'minicard';
},
+ importedCard() {
+ return this.currentData().type === 'cardType-importedCard';
+ },
+ importedBoard() {
+ return this.currentData().type === 'cardType-importedBoard';
+ },
+ imported() {
+ return this.importedCard() || this.importedBoard();
+ },
}).register('minicard');
diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl
index 5624787c..ea737c6b 100644
--- a/client/components/cards/minicard.styl
+++ b/client/components/cards/minicard.styl
@@ -44,6 +44,41 @@
transition: transform 0.2s,
border-radius 0.2s
+ &.imported-board
+ background-color: #efd8e6
+ &:hover:not(.minicard-composer),
+ .is-selected &,
+ .draggable-hover-card &
+ background: darken(#efd8e6, 3%)
+
+ .is-selected &
+ border-left: 3px solid darken(#efd8e6, 50%)
+
+ .minicard-title
+ font-style: italic
+ font-weight: bold
+
+ &.imported-card
+ background-color: #d5e4bd
+ &:hover:not(.minicard-composer),
+ .is-selected &,
+ .draggable-hover-card &
+ background: darken(#d5e4bd, 3%)
+
+ .is-selected &
+ border-left: 3px solid darken(#d5e4bd, 50%)
+
+ .minicard-title
+ font-style: italic
+
+ &.imported-board
+ &.imported-card
+ .imported-icon
+ display: inline-block
+ margin-right: 11px
+ vertical-align: baseline
+ font-size: 0.9em
+
.is-selected &
transform: translateX(11px)
border-bottom-right-radius: 0
@@ -87,6 +122,8 @@
.minicard-title
p:last-child
margin-bottom: 0
+ .viewer
+ display: inline-block
.dates
display: flex;
flex-direction: row;
diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade
index e0655fc2..419e158a 100644
--- a/client/components/lists/listBody.jade
+++ b/client/components/lists/listBody.jade
@@ -37,6 +37,10 @@ template(name="addCardForm")
span.quiet
| {{_ 'or'}}
a.js-import {{_ 'import'}}
+ span.quiet
+ |  
+ | /
+ a.js-search {{_ 'search'}}
template(name="autocompleteLabelLine")
.minicard-label(class="card-label-{{colorName}}" title=labelName)
@@ -51,7 +55,7 @@ template(name="importCardPopup")
option(value="{{_id}}" selected) {{_ 'current'}}
else
option(value="{{_id}}") {{title}}
- input.primary.confirm.js-import-board(type="submit" value="{{_ 'add'}}")
+ input.primary.confirm.js-import-board(type="button" value="{{_ 'import'}}")
label {{_ 'swimlanes'}}:
select.js-select-swimlanes
@@ -64,15 +68,12 @@ template(name="importCardPopup")
option(value="{{_id}}") {{title}}
label {{_ 'cards'}}:
- select.js-select-lists
+ select.js-select-cards
each cards
option(value="{{_id}}") {{title}}
.edit-controls.clearfix
- input.primary.confirm.js-done(type="submit" value="{{_ 'done'}}")
- span.quiet
- | {{_ 'or'}}
- a.js-search {{_ 'search'}}
+ input.primary.confirm.js-done(type="button" value="{{_ 'import'}}")
template(name="searchCardPopup")
label {{_ 'boards'}}:
diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js
index 1aece121..39614108 100644
--- a/client/components/lists/listBody.js
+++ b/client/components/lists/listBody.js
@@ -201,6 +201,7 @@ BlazeComponent.extendComponent({
return [{
keydown: this.pressKey,
'click .js-import': Popup.open('importCard'),
+ 'click .js-search': Popup.open('searchCard'),
}];
},
@@ -275,14 +276,39 @@ BlazeComponent.extendComponent({
BlazeComponent.extendComponent({
onCreated() {
- subManager.subscribe('board', Session.get('currentBoard'));
- this.selectedBoardId = new ReactiveVar(Session.get('currentBoard'));
+ // Prefetch first non-current board id
+ const boardId = Boards.findOne({
+ archived: false,
+ 'members.userId': Meteor.userId(),
+ _id: {$ne: Session.get('currentBoard')},
+ })._id;
+ // Subscribe to this board
+ subManager.subscribe('board', boardId);
+ this.selectedBoardId = new ReactiveVar(boardId);
+ this.selectedSwimlaneId = new ReactiveVar('');
+ this.selectedListId = new ReactiveVar('');
+
+ this.boardId = Session.get('currentBoard');
+ // In order to get current board info
+ subManager.subscribe('board', this.boardId);
+ const board = Boards.findOne(this.boardId);
+ // List where to insert card
+ const list = $(Popup._getTopStack().openerElement).closest('.js-list');
+ this.listId = Blaze.getData(list[0])._id;
+ // Swimlane where to insert card
+ const swimlane = $(Popup._getTopStack().openerElement).closest('.js-swimlane');
+ this.swimlaneId = '';
+ if (board.view === 'board-view-swimlanes')
+ this.swimlaneId = Blaze.getData(swimlane[0])._id;
+ else
+ this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id;
},
boards() {
const boards = Boards.find({
archived: false,
'members.userId': Meteor.userId(),
+ _id: {$ne: Session.get('currentBoard')},
}, {
sort: ['title'],
});
@@ -290,18 +316,26 @@ BlazeComponent.extendComponent({
},
swimlanes() {
- const board = Boards.findOne(this.selectedBoardId.get());
- return board.swimlanes();
+ const swimlanes = Swimlanes.find({boardId: this.selectedBoardId.get()});
+ if (swimlanes.count())
+ this.selectedSwimlaneId.set(swimlanes.fetch()[0]._id);
+ return swimlanes;
},
lists() {
- const board = Boards.findOne(this.selectedBoardId.get());
- return board.lists();
+ const lists = Lists.find({boardId: this.selectedBoardId.get()});
+ if (lists.count())
+ this.selectedListId.set(lists.fetch()[0]._id);
+ return lists;
},
cards() {
- const board = Boards.findOne(this.selectedBoardId.get());
- return board.cards();
+ return Cards.find({
+ boardId: this.selectedBoardId.get(),
+ swimlaneId: this.selectedSwimlaneId.get(),
+ listId: this.selectedListId.get(),
+ archived: false,
+ });
},
events() {
@@ -310,24 +344,44 @@ BlazeComponent.extendComponent({
this.selectedBoardId.set($(evt.currentTarget).val());
subManager.subscribe('board', this.selectedBoardId.get());
},
- 'submit .js-done' (evt) {
+ 'change .js-select-swimlanes'(evt) {
+ this.selectedSwimlaneId.set($(evt.currentTarget).val());
+ },
+ 'change .js-select-lists'(evt) {
+ this.selectedListId.set($(evt.currentTarget).val());
+ },
+ 'click .js-done' (evt) {
// IMPORT CARD
+ evt.stopPropagation();
evt.preventDefault();
- // XXX We should *not* get the currentCard from the global state, but
- // instead from a “component” state.
- const card = Cards.findOne(Session.get('currentCard'));
- const lSelect = $('.js-select-lists')[0];
- const newListId = lSelect.options[lSelect.selectedIndex].value;
- const slSelect = $('.js-select-swimlanes')[0];
- card.swimlaneId = slSelect.options[slSelect.selectedIndex].value;
+ const _id = Cards.insert({
+ title: $('.js-select-cards option:selected').text(), //dummy
+ listId: this.listId,
+ swimlaneId: this.swimlaneId,
+ boardId: this.boardId,
+ sort: Lists.findOne(this.listId).cards().count(),
+ type: 'cardType-importedCard',
+ importedId: $('.js-select-cards option:selected').val(),
+ });
+ Filter.addException(_id);
Popup.close();
},
- 'submit .js-import-board' (evt) {
+ 'click .js-import-board' (evt) {
//IMPORT BOARD
+ evt.stopPropagation();
evt.preventDefault();
+ const _id = Cards.insert({
+ title: $('.js-select-boards option:selected').text(), //dummy
+ listId: this.listId,
+ swimlaneId: this.swimlaneId,
+ boardId: this.boardId,
+ sort: Lists.findOne(this.listId).cards().count(),
+ type: 'cardType-importedBoard',
+ importedId: $('.js-select-boards option:selected').val(),
+ });
+ Filter.addException(_id);
Popup.close();
},
- 'click .js-search': Popup.open('searchCard'),
}];
},
}).register('importCardPopup');
@@ -338,13 +392,30 @@ BlazeComponent.extendComponent({
},
onCreated() {
+ // Prefetch first non-current board id
const boardId = Boards.findOne({
archived: false,
'members.userId': Meteor.userId(),
_id: {$ne: Session.get('currentBoard')},
})._id;
+ // Subscribe to this board
subManager.subscribe('board', boardId);
this.selectedBoardId = new ReactiveVar(boardId);
+
+ this.boardId = Session.get('currentBoard');
+ // In order to get current board info
+ subManager.subscribe('board', this.boardId);
+ const board = Boards.findOne(this.boardId);
+ // List where to insert card
+ const list = $(Popup._getTopStack().openerElement).closest('.js-list');
+ this.listId = Blaze.getData(list[0])._id;
+ // Swimlane where to insert card
+ const swimlane = $(Popup._getTopStack().openerElement).closest('.js-swimlane');
+ this.swimlaneId = '';
+ if (board.view === 'board-view-swimlanes')
+ this.swimlaneId = Blaze.getData(swimlane[0])._id;
+ else
+ this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id;
this.term = new ReactiveVar('');
},
@@ -376,6 +447,18 @@ BlazeComponent.extendComponent({
},
'click .js-minicard'(evt) {
// IMPORT CARD
+ const card = Blaze.getData(evt.currentTarget);
+ const _id = Cards.insert({
+ title: card.title, //dummy
+ listId: this.listId,
+ swimlaneId: this.swimlaneId,
+ boardId: this.boardId,
+ sort: Lists.findOne(this.listId).cards().count(),
+ type: 'cardType-importedCard',
+ importedId: card._id,
+ });
+ Filter.addException(_id);
+ Popup.close();
},
}];
},