summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/components/boards/boardBody.js103
-rw-r--r--client/components/cards/cardDetails.js2
-rw-r--r--client/components/import/import.jade19
-rw-r--r--client/components/lists/list.js74
-rw-r--r--client/components/swimlanes/swimlanes.jade2
-rw-r--r--client/components/swimlanes/swimlanes.js76
-rw-r--r--client/components/swimlanes/swimlanes.styl3
7 files changed, 144 insertions, 135 deletions
diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js
index 94f9af39..aa7b6a75 100644
--- a/client/components/boards/boardBody.js
+++ b/client/components/boards/boardBody.js
@@ -1,12 +1,8 @@
const subManager = new SubsManager();
+const { calculateIndex } = Utils;
BlazeComponent.extendComponent({
- openNewListForm() {
- this.childComponents('addListForm')[0].open();
- },
onCreated() {
- this.draggingActive = new ReactiveVar(false);
- this.showOverlay = new ReactiveVar(false);
this.isBoardReady = new ReactiveVar(false);
// The pattern we use to manually handle data loading is described here:
@@ -24,30 +20,70 @@ BlazeComponent.extendComponent({
});
});
});
+ },
- this._isDragging = false;
- this._lastDragPositionX = 0;
+ onlyShowCurrentCard() {
+ return Utils.isMiniScreen() && Session.get('currentCard');
+ },
+
+}).register('board');
+BlazeComponent.extendComponent({
+ onCreated() {
+ this.showOverlay = new ReactiveVar(false);
+ this.draggingActive = new ReactiveVar(false);
+ this._isDragging = false;
// Used to set the overlay
this.mouseHasEnterCardDetails = false;
},
+ onRendered() {
+ const boardComponent = this;
+ const $swimlanesDom = boardComponent.$('.js-swimlanes');
- // XXX Flow components allow us to avoid creating these two setter methods by
- // exposing a public API to modify the component state. We need to investigate
- // best practices here.
- setIsDragging(bool) {
- this.draggingActive.set(bool);
- },
+ $swimlanesDom.sortable({
+ tolerance: 'pointer',
+ appendTo: '.board-canvas',
+ helper: 'clone',
+ handle: '.js-swimlane-header',
+ items: '.js-swimlane:not(.placeholder)',
+ placeholder: 'swimlane placeholder',
+ distance: 7,
+ start(evt, ui) {
+ ui.placeholder.height(ui.helper.height());
+ EscapeActions.executeUpTo('popup-close');
+ boardComponent.setIsDragging(true);
+ },
+ stop(evt, ui) {
+ // To attribute the new index number, we need to get the DOM element
+ // of the previous and the following card -- if any.
+ const prevSwimlaneDom = ui.item.prev('.js-swimlane').get(0);
+ const nextSwimlaneDom = ui.item.next('.js-swimlane').get(0);
+ const sortIndex = calculateIndex(prevSwimlaneDom, nextSwimlaneDom, 1);
- scrollLeft(position = 0) {
- const lists = this.$('.js-lists');
- lists && lists.animate({
- scrollLeft: position,
+ $swimlanesDom.sortable('cancel');
+ const swimlaneDomElement = ui.item.get(0);
+ const swimlane = Blaze.getData(swimlaneDomElement);
+
+ Swimlanes.update(swimlane._id, {
+ $set: {
+ sort: sortIndex.base,
+ },
+ });
+
+ boardComponent.setIsDragging(false);
+ },
});
- },
- onlyShowCurrentCard() {
- return Utils.isMiniScreen() && Session.get('currentCard');
+ function userIsMember() {
+ return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
+ }
+
+ // If there is no data in the board (ie, no lists) we autofocus the list
+ // creation form by clicking on the corresponding element.
+ const currentBoard = Boards.findOne(Session.get('currentBoard'));
+ if (userIsMember() && currentBoard.lists().count() === 0) {
+ boardComponent.openNewListForm();
+ }
},
isViewSwimlanes() {
@@ -62,6 +98,16 @@ BlazeComponent.extendComponent({
return (board.view === 'board-view-lists');
},
+ openNewListForm() {
+ if (this.isViewSwimlanes()) {
+ this.childComponents('swimlane')[0]
+ .childComponents('addListAndSwimlaneForm')[0].open();
+ } else if (this.isViewLists()) {
+ this.childComponents('listsGroup')[0]
+ .childComponents('addListForm')[0].open();
+ }
+ },
+
events() {
return [{
// XXX The board-overlay div should probably be moved to the parent
@@ -78,4 +124,19 @@ BlazeComponent.extendComponent({
},
}];
},
-}).register('board');
+
+ // XXX Flow components allow us to avoid creating these two setter methods by
+ // exposing a public API to modify the component state. We need to investigate
+ // best practices here.
+ setIsDragging(bool) {
+ this.draggingActive.set(bool);
+ },
+
+ scrollLeft(position = 0) {
+ const swimlanes = this.$('.js-swimlanes');
+ swimlanes && swimlanes.animate({
+ scrollLeft: position,
+ });
+ },
+
+}).register('boardBody');
diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js
index 701bcd1b..ab8a6288 100644
--- a/client/components/cards/cardDetails.js
+++ b/client/components/cards/cardDetails.js
@@ -44,8 +44,8 @@ BlazeComponent.extendComponent({
const cardPanelWidth = 510;
const bodyBoardComponent = this.parentComponent().parentComponent();
- const $cardContainer = bodyBoardComponent.$('.js-lists');
const $cardView = this.$(this.firstNode());
+ const $cardContainer = bodyBoardComponent.$('.js-swimlanes');
const cardContainerScroll = $cardContainer.scrollLeft();
const cardContainerWidth = $cardContainer.width();
diff --git a/client/components/import/import.jade b/client/components/import/import.jade
index c6dc1bef..a1fbd83b 100644
--- a/client/components/import/import.jade
+++ b/client/components/import/import.jade
@@ -11,17 +11,14 @@ template(name="import")
+Template.dynamic(template=currentTemplate)
template(name="importTextarea")
- unless isSandstorm
- form
- p: label(for='import-textarea') {{_ instruction}}
- textarea.js-import-json(placeholder="{{_ 'import-json-placeholder'}}" autofocus)
- | {{jsonText}}
- if isSandstorm
- p.warning {{_ 'import-sandstorm-warning'}}
- input.primary.wide(type="submit" value="{{_ 'import'}}")
- if isSandstorm
- p.warning 'Import disabled because of data loss bug https://github.com/wekan/wekan/issues/1430'
-
+ form
+ p: label(for='import-textarea') {{_ instruction}}
+ textarea.js-import-json(placeholder="{{_ 'import-json-placeholder'}}" autofocus)
+ | {{jsonText}}
+ if isSandstorm
+ h1.warning DANGER !!! THIS DESTROYS YOUR IMPORTED DATA, CAUSES BOARD NOT FOUND ERROR WHEN YOU OPEN THIS GRAIN AGAIN https://github.com/wekan/wekan/issues/1430
+ p.warning {{_ 'import-sandstorm-warning'}}
+ input.primary.wide(type="submit" value="{{_ 'import'}}")
template(name="importMapMembers")
h2 {{_ 'import-map-members'}}
diff --git a/client/components/lists/list.js b/client/components/lists/list.js
index 081b1e50..38a87674 100644
--- a/client/components/lists/list.js
+++ b/client/components/lists/list.js
@@ -19,85 +19,11 @@ BlazeComponent.extendComponent({
// comment below provides further details.
onRendered() {
const boardComponent = this.parentComponent().parentComponent();
- const $listsDom = boardComponent.$('.js-lists');
-
- if (!Session.get('currentCard')) {
- boardComponent.scrollLeft();
- }
-
- // We want to animate the card details window closing. We rely on CSS
- // transition for the actual animation.
- $listsDom._uihooks = {
- removeElement(node) {
- const removeNode = _.once(() => {
- node.parentNode.removeChild(node);
- });
- if ($(node).hasClass('js-card-details')) {
- $(node).css({
- flexBasis: 0,
- padding: 0,
- });
- $listsDom.one(CSSEvents.transitionend, removeNode);
- } else {
- removeNode();
- }
- },
- };
-
- $listsDom.sortable({
- tolerance: 'pointer',
- helper: 'clone',
- handle: '.js-list-header',
- items: '.js-list:not(.js-list-composer)',
- placeholder: 'list placeholder',
- distance: 7,
- start(evt, ui) {
- ui.placeholder.height(ui.helper.height());
- EscapeActions.executeUpTo('popup-close');
- boardComponent.setIsDragging(true);
- },
- stop(evt, ui) {
- // To attribute the new index number, we need to get the DOM element
- // of the previous and the following card -- if any.
- const prevListDom = ui.item.prev('.js-list').get(0);
- const nextListDom = ui.item.next('.js-list').get(0);
- const sortIndex = calculateIndex(prevListDom, nextListDom, 1);
-
- $listsDom.sortable('cancel');
- const listDomElement = ui.item.get(0);
- const list = Blaze.getData(listDomElement);
-
- Lists.update(list._id, {
- $set: {
- sort: sortIndex.base,
- },
- });
-
- boardComponent.setIsDragging(false);
- },
- });
function userIsMember() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
}
- // Disable drag-dropping while in multi-selection mode, or if the current user
- // is not a board member
- boardComponent.autorun(() => {
- const $listDom = $listsDom;
- if ($listDom.data('sortable')) {
- $listsDom.sortable('option', 'disabled',
- MultiSelection.isActive() || !userIsMember());
- }
- });
-
- // If there is no data in the board (ie, no lists) we autofocus the list
- // creation form by clicking on the corresponding element.
- const currentBoard = Boards.findOne(Session.get('currentBoard'));
- if (userIsMember() && currentBoard.lists().count() === 0) {
- boardComponent.openNewListForm();
- }
-
const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)';
const $cards = this.$('.js-minicards');
$cards.sortable({
diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade
index 0c3fc5de..76f54c66 100644
--- a/client/components/swimlanes/swimlanes.jade
+++ b/client/components/swimlanes/swimlanes.jade
@@ -18,7 +18,7 @@ template(name="swimlane")
+addListAndSwimlaneForm
template(name="listsGroup")
- .swimlane.js-lists
+ .swimlane.list-group.js-lists
if isMiniScreen
if currentList
+list(currentList)
diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js
index dacb487e..3dd7f208 100644
--- a/client/components/swimlanes/swimlanes.js
+++ b/client/components/swimlanes/swimlanes.js
@@ -3,15 +3,37 @@ const { calculateIndex } = Utils;
BlazeComponent.extendComponent({
onRendered() {
const boardComponent = this.parentComponent();
- const $swimlanesDom = boardComponent.$('.js-swimlanes');
+ const $listsDom = this.$('.js-lists');
+
+ if (!Session.get('currentCard')) {
+ boardComponent.scrollLeft();
+ }
+
+ // We want to animate the card details window closing. We rely on CSS
+ // transition for the actual animation.
+ $listsDom._uihooks = {
+ removeElement(node) {
+ const removeNode = _.once(() => {
+ node.parentNode.removeChild(node);
+ });
+ if ($(node).hasClass('js-card-details')) {
+ $(node).css({
+ flexBasis: 0,
+ padding: 0,
+ });
+ $listsDom.one(CSSEvents.transitionend, removeNode);
+ } else {
+ removeNode();
+ }
+ },
+ };
- $swimlanesDom.sortable({
+ $listsDom.sortable({
tolerance: 'pointer',
- appendTo: '.board-canvas',
helper: 'clone',
- handle: '.js-swimlane-header',
- items: '.js-swimlane:not(.placeholder)',
- placeholder: 'swimlane placeholder',
+ handle: '.js-list-header',
+ items: '.js-list:not(.js-list-composer)',
+ placeholder: 'list placeholder',
distance: 7,
start(evt, ui) {
ui.placeholder.height(ui.helper.height());
@@ -21,15 +43,15 @@ BlazeComponent.extendComponent({
stop(evt, ui) {
// To attribute the new index number, we need to get the DOM element
// of the previous and the following card -- if any.
- const prevSwimlaneDom = ui.item.prev('.js-swimlane').get(0);
- const nextSwimlaneDom = ui.item.next('.js-swimlane').get(0);
- const sortIndex = calculateIndex(prevSwimlaneDom, nextSwimlaneDom, 1);
+ const prevListDom = ui.item.prev('.js-list').get(0);
+ const nextListDom = ui.item.next('.js-list').get(0);
+ const sortIndex = calculateIndex(prevListDom, nextListDom, 1);
- $swimlanesDom.sortable('cancel');
- const swimlaneDomElement = ui.item.get(0);
- const swimlane = Blaze.getData(swimlaneDomElement);
+ $listsDom.sortable('cancel');
+ const listDomElement = ui.item.get(0);
+ const list = Blaze.getData(listDomElement);
- Swimlanes.update(swimlane._id, {
+ Lists.update(list._id, {
$set: {
sort: sortIndex.base,
},
@@ -38,6 +60,20 @@ BlazeComponent.extendComponent({
boardComponent.setIsDragging(false);
},
});
+
+ function userIsMember() {
+ return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
+ }
+
+ // Disable drag-dropping while in multi-selection mode, or if the current user
+ // is not a board member
+ boardComponent.autorun(() => {
+ const $listDom = $listsDom;
+ if ($listDom.data('sortable')) {
+ $listsDom.sortable('option', 'disabled',
+ MultiSelection.isActive() || !userIsMember());
+ }
+ });
},
onCreated() {
this.draggingActive = new ReactiveVar(false);
@@ -50,20 +86,6 @@ BlazeComponent.extendComponent({
return this._id;
},
- // XXX Flow components allow us to avoid creating these two setter methods by
- // exposing a public API to modify the component state. We need to investigate
- // best practices here.
- setIsDragging(bool) {
- this.draggingActive.set(bool);
- },
-
- scrollLeft(position = 0) {
- const lists = this.$('.js-lists');
- lists && lists.animate({
- scrollLeft: position,
- });
- },
-
currentCardIsInThisList(listId, swimlaneId) {
const currentCard = Cards.findOne(Session.get('currentCard'));
const currentBoardId = Session.get('currentBoard');
diff --git a/client/components/swimlanes/swimlanes.styl b/client/components/swimlanes/swimlanes.styl
index 29054d32..555bcd3b 100644
--- a/client/components/swimlanes/swimlanes.styl
+++ b/client/components/swimlanes/swimlanes.styl
@@ -49,3 +49,6 @@
.swimlane-header-menu
position: absolute
padding: 20px 20px
+
+.list-group
+ height: 100%