mirror of
https://github.com/wekan/wekan.git
synced 2025-09-22 01:50:48 +02:00
Allow swimlane creation from template
Mix lists with same name to avoid duplicates
This commit is contained in:
parent
f888cfd565
commit
60be4df76e
10 changed files with 100 additions and 35 deletions
|
@ -247,9 +247,6 @@ template(name="cardDetailsActionsPopup")
|
||||||
unless archived
|
unless archived
|
||||||
li: a.js-archive {{_ 'archive-card'}}
|
li: a.js-archive {{_ 'archive-card'}}
|
||||||
li: a.js-more {{_ 'cardMorePopup-title'}}
|
li: a.js-more {{_ 'cardMorePopup-title'}}
|
||||||
hr
|
|
||||||
ul.pop-over-list
|
|
||||||
li: a.js-template-card {{_ 'cardTemplatePopup-title'}}
|
|
||||||
|
|
||||||
template(name="moveCardPopup")
|
template(name="moveCardPopup")
|
||||||
+boardsAndLists
|
+boardsAndLists
|
||||||
|
|
|
@ -365,9 +365,6 @@ Template.cardDetailsActionsPopup.events({
|
||||||
if (!err && ret) Popup.close();
|
if (!err && ret) Popup.close();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'click .js-template-card' () {
|
|
||||||
console.log('REMOVE Creating template card');
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.editCardTitleForm.onRendered(function () {
|
Template.editCardTitleForm.onRendered(function () {
|
||||||
|
|
|
@ -91,7 +91,7 @@ template(name="linkCardPopup")
|
||||||
unless isSandstorm
|
unless isSandstorm
|
||||||
input.primary.confirm.js-done(type="button" value="{{_ 'link'}}")
|
input.primary.confirm.js-done(type="button" value="{{_ 'link'}}")
|
||||||
|
|
||||||
template(name="searchCardPopup")
|
template(name="searchElementPopup")
|
||||||
unless isTemplateSearch
|
unless isTemplateSearch
|
||||||
label {{_ 'boards'}}:
|
label {{_ 'boards'}}:
|
||||||
.link-board-wrapper
|
.link-board-wrapper
|
||||||
|
@ -110,6 +110,9 @@ template(name="searchCardPopup")
|
||||||
if isSwimlaneTemplateSearch
|
if isSwimlaneTemplateSearch
|
||||||
a.minicard-wrapper.js-minicard
|
a.minicard-wrapper.js-minicard
|
||||||
+miniswimlane(this)
|
+miniswimlane(this)
|
||||||
|
if isCardTemplateSearch
|
||||||
|
a.minicard-wrapper.js-minicard
|
||||||
|
+minicard(this)
|
||||||
unless isTemplateSearch
|
unless isTemplateSearch
|
||||||
a.minicard-wrapper.js-minicard
|
a.minicard-wrapper.js-minicard
|
||||||
+minicard(this)
|
+minicard(this)
|
||||||
|
|
|
@ -315,8 +315,8 @@ BlazeComponent.extendComponent({
|
||||||
return [{
|
return [{
|
||||||
keydown: this.pressKey,
|
keydown: this.pressKey,
|
||||||
'click .js-link': Popup.open('linkCard'),
|
'click .js-link': Popup.open('linkCard'),
|
||||||
'click .js-search': Popup.open('searchCard'),
|
'click .js-search': Popup.open('searchElement'),
|
||||||
'click .js-search-template': Popup.open('searchCard'),
|
'click .js-card-template': Popup.open('searchElement'),
|
||||||
}];
|
}];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -526,7 +526,7 @@ BlazeComponent.extendComponent({
|
||||||
onCreated() {
|
onCreated() {
|
||||||
this.isCardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-card-template');
|
this.isCardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-card-template');
|
||||||
this.isListTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-list-template');
|
this.isListTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-list-template');
|
||||||
this.isSwimlaneTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-swimlane-template');
|
this.isSwimlaneTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-open-add-swimlane-menu');
|
||||||
this.isTemplateSearch = this.isCardTemplateSearch || this.isListTemplateSearch || this.isSwimlaneTemplateSearch;
|
this.isTemplateSearch = this.isCardTemplateSearch || this.isListTemplateSearch || this.isSwimlaneTemplateSearch;
|
||||||
let board = {};
|
let board = {};
|
||||||
if (this.isTemplateSearch) {
|
if (this.isTemplateSearch) {
|
||||||
|
@ -551,14 +551,13 @@ BlazeComponent.extendComponent({
|
||||||
this.boardId = Session.get('currentBoard');
|
this.boardId = Session.get('currentBoard');
|
||||||
// In order to get current board info
|
// In order to get current board info
|
||||||
subManager.subscribe('board', this.boardId);
|
subManager.subscribe('board', this.boardId);
|
||||||
board = Boards.findOne(this.boardId);
|
|
||||||
// List where to insert card
|
// List where to insert card
|
||||||
const list = $(Popup._getTopStack().openerElement).closest('.js-list');
|
const list = $(Popup._getTopStack().openerElement).closest('.js-list');
|
||||||
this.listId = Blaze.getData(list[0])._id;
|
this.listId = Blaze.getData(list[0])._id;
|
||||||
// Swimlane where to insert card
|
// Swimlane where to insert card
|
||||||
const swimlane = $(Popup._getTopStack().openerElement).closest('.js-swimlane');
|
const swimlane = $(Popup._getTopStack().openerElement).parents('.js-swimlane');
|
||||||
this.swimlaneId = '';
|
this.swimlaneId = '';
|
||||||
if (board.view === 'board-view-swimlanes')
|
if (Meteor.user().profile.boardView === 'board-view-swimlanes')
|
||||||
this.swimlaneId = Blaze.getData(swimlane[0])._id;
|
this.swimlaneId = Blaze.getData(swimlane[0])._id;
|
||||||
else
|
else
|
||||||
this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id;
|
this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id;
|
||||||
|
@ -606,7 +605,6 @@ BlazeComponent.extendComponent({
|
||||||
'click .js-minicard'(evt) {
|
'click .js-minicard'(evt) {
|
||||||
// 0. Common
|
// 0. Common
|
||||||
let element = Blaze.getData(evt.currentTarget);
|
let element = Blaze.getData(evt.currentTarget);
|
||||||
console.log(element);
|
|
||||||
element.boardId = this.boardId;
|
element.boardId = this.boardId;
|
||||||
let _id = '';
|
let _id = '';
|
||||||
if (!this.isTemplateSearch || this.isCardTemplateSearch) {
|
if (!this.isTemplateSearch || this.isCardTemplateSearch) {
|
||||||
|
@ -630,14 +628,17 @@ BlazeComponent.extendComponent({
|
||||||
Filter.addException(_id);
|
Filter.addException(_id);
|
||||||
// List insertion
|
// List insertion
|
||||||
} else if (this.isListTemplateSearch) {
|
} else if (this.isListTemplateSearch) {
|
||||||
element.swimlaneId = '';
|
|
||||||
element.sort = Swimlanes.findOne(this.swimlaneId).lists().count();
|
element.sort = Swimlanes.findOne(this.swimlaneId).lists().count();
|
||||||
element.type = 'list';
|
element.type = 'list';
|
||||||
element.swimlaneId = this.swimlaneId;
|
element.swimlaneId = this.swimlaneId;
|
||||||
_id = element.copy();
|
_id = element.copy();
|
||||||
|
} else if (this.isSwimlaneTemplateSearch) {
|
||||||
|
element.sort = Boards.findOne(this.boardId).swimlanes().count();
|
||||||
|
element.type = 'swimlalne';
|
||||||
|
_id = element.copy();
|
||||||
}
|
}
|
||||||
Popup.close();
|
Popup.close();
|
||||||
},
|
},
|
||||||
}];
|
}];
|
||||||
},
|
},
|
||||||
}).register('searchCardPopup');
|
}).register('searchElementPopup');
|
||||||
|
|
|
@ -40,6 +40,11 @@ template(name="swimlaneAddPopup")
|
||||||
autocomplete="off" autofocus)
|
autocomplete="off" autofocus)
|
||||||
.edit-controls.clearfix
|
.edit-controls.clearfix
|
||||||
button.primary.confirm(type="submit") {{_ 'add'}}
|
button.primary.confirm(type="submit") {{_ 'add'}}
|
||||||
|
unless currentBoard.isTemplatesBoard
|
||||||
|
unless currentBoard.isTemplateBoard
|
||||||
|
span.quiet
|
||||||
|
| {{_ 'or'}}
|
||||||
|
a.js-swimlane-template {{_ 'template'}}
|
||||||
|
|
||||||
template(name="setSwimlaneColorPopup")
|
template(name="setSwimlaneColorPopup")
|
||||||
form.edit-label
|
form.edit-label
|
||||||
|
|
|
@ -65,6 +65,7 @@ BlazeComponent.extendComponent({
|
||||||
// with a minimum of interactions
|
// with a minimum of interactions
|
||||||
Popup.close();
|
Popup.close();
|
||||||
},
|
},
|
||||||
|
'click .js-swimlane-template': Popup.open('searchElement'),
|
||||||
}];
|
}];
|
||||||
},
|
},
|
||||||
}).register('swimlaneAddPopup');
|
}).register('swimlaneAddPopup');
|
||||||
|
|
|
@ -154,8 +154,8 @@ BlazeComponent.extendComponent({
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
onCreated() {
|
onCreated() {
|
||||||
currentBoard = Boards.findOne(Session.get('currentBoard'));
|
this.currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||||
this.isListTemplatesSwimlane = currentBoard.isTemplatesBoard() && this.currentData().isListTemplatesSwimlane();
|
this.isListTemplatesSwimlane = this.currentBoard.isTemplatesBoard() && this.currentData().isListTemplatesSwimlane();
|
||||||
this.currentSwimlane = this.currentData();
|
this.currentSwimlane = this.currentData();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -176,14 +176,14 @@ BlazeComponent.extendComponent({
|
||||||
boardId: Session.get('currentBoard'),
|
boardId: Session.get('currentBoard'),
|
||||||
sort: $('.list').length,
|
sort: $('.list').length,
|
||||||
type: (this.isListTemplatesSwimlane)?'template-list':'list',
|
type: (this.isListTemplatesSwimlane)?'template-list':'list',
|
||||||
swimlaneId: (this.isListTemplatesSwimlane)?this.currentSwimlane._id:'',
|
swimlaneId: (this.currentBoard.isTemplatesBoard())?this.currentSwimlane._id:'',
|
||||||
});
|
});
|
||||||
|
|
||||||
titleInput.value = '';
|
titleInput.value = '';
|
||||||
titleInput.focus();
|
titleInput.focus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'click .js-list-template': Popup.open('searchCard'),
|
'click .js-list-template': Popup.open('searchElement'),
|
||||||
}];
|
}];
|
||||||
},
|
},
|
||||||
}).register('addListForm');
|
}).register('addListForm');
|
||||||
|
|
|
@ -463,6 +463,30 @@ Boards.helpers({
|
||||||
return _id;
|
return _id;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
searchSwimlanes(term) {
|
||||||
|
check(term, Match.OneOf(String, null, undefined));
|
||||||
|
|
||||||
|
const query = { boardId: this._id };
|
||||||
|
if (this.isTemplatesBoard()) {
|
||||||
|
query.type = 'template-swimlane';
|
||||||
|
query.archived = false;
|
||||||
|
} else {
|
||||||
|
query.type = {$nin: ['template-swimlane']};
|
||||||
|
}
|
||||||
|
const projection = { limit: 10, sort: { createdAt: -1 } };
|
||||||
|
|
||||||
|
if (term) {
|
||||||
|
const regex = new RegExp(term, 'i');
|
||||||
|
|
||||||
|
query.$or = [
|
||||||
|
{ title: regex },
|
||||||
|
{ description: regex },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Swimlanes.find(query, projection);
|
||||||
|
},
|
||||||
|
|
||||||
searchLists(term) {
|
searchLists(term) {
|
||||||
check(term, Match.OneOf(String, null, undefined));
|
check(term, Match.OneOf(String, null, undefined));
|
||||||
|
|
||||||
|
|
|
@ -139,8 +139,17 @@ Lists.allow({
|
||||||
Lists.helpers({
|
Lists.helpers({
|
||||||
copy() {
|
copy() {
|
||||||
const oldId = this._id;
|
const oldId = this._id;
|
||||||
this._id = null;
|
let _id = null;
|
||||||
const _id = Lists.insert(this);
|
existingListWithSameName = Lists.findOne({
|
||||||
|
boardId: this.boardId,
|
||||||
|
title: this.title,
|
||||||
|
});
|
||||||
|
if (existingListWithSameName) {
|
||||||
|
_id = existingListWithSameName._id;
|
||||||
|
} else {
|
||||||
|
this._id = null;
|
||||||
|
_id = Lists.insert(this);
|
||||||
|
}
|
||||||
|
|
||||||
// Copy all cards in list
|
// Copy all cards in list
|
||||||
Cards.find({
|
Cards.find({
|
||||||
|
@ -213,23 +222,20 @@ Lists.mutations({
|
||||||
},
|
},
|
||||||
|
|
||||||
archive() {
|
archive() {
|
||||||
Cards.find({
|
if (this.isTemplateList()) {
|
||||||
listId: this._id,
|
this.cards().forEach((card) => {
|
||||||
archived: false,
|
return card.archive();
|
||||||
}).forEach((card) => {
|
});
|
||||||
return card.archive();
|
}
|
||||||
});
|
|
||||||
return { $set: { archived: true } };
|
return { $set: { archived: true } };
|
||||||
},
|
},
|
||||||
|
|
||||||
restore() {
|
restore() {
|
||||||
cardsToRestore = Cards.find({
|
if (this.isTemplateList()) {
|
||||||
listId: this._id,
|
this.allCards().forEach((card) => {
|
||||||
archived: true,
|
return card.restore();
|
||||||
});
|
});
|
||||||
cardsToRestore.forEach((card) => {
|
}
|
||||||
card.restore();
|
|
||||||
});
|
|
||||||
return { $set: { archived: false } };
|
return { $set: { archived: false } };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,23 @@ Swimlanes.allow({
|
||||||
});
|
});
|
||||||
|
|
||||||
Swimlanes.helpers({
|
Swimlanes.helpers({
|
||||||
|
copy() {
|
||||||
|
const oldId = this._id;
|
||||||
|
this._id = null;
|
||||||
|
const _id = Swimlanes.insert(this);
|
||||||
|
|
||||||
|
// Copy all lists in swimlane
|
||||||
|
Lists.find({
|
||||||
|
swimlaneId: oldId,
|
||||||
|
archived: false,
|
||||||
|
}).forEach((list) => {
|
||||||
|
list.type = 'list';
|
||||||
|
list.swimlaneId = _id;
|
||||||
|
list.boardId = this.boardId;
|
||||||
|
list.copy();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
cards() {
|
cards() {
|
||||||
return Cards.find(Filter.mongoSelector({
|
return Cards.find(Filter.mongoSelector({
|
||||||
swimlaneId: this._id,
|
swimlaneId: this._id,
|
||||||
|
@ -115,6 +132,10 @@ Swimlanes.helpers({
|
||||||
}), { sort: ['sort'] });
|
}), { sort: ['sort'] });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
allLists() {
|
||||||
|
return Lists.find({ swimlaneId: this._id });
|
||||||
|
},
|
||||||
|
|
||||||
allCards() {
|
allCards() {
|
||||||
return Cards.find({ swimlaneId: this._id });
|
return Cards.find({ swimlaneId: this._id });
|
||||||
},
|
},
|
||||||
|
@ -159,10 +180,20 @@ Swimlanes.mutations({
|
||||||
},
|
},
|
||||||
|
|
||||||
archive() {
|
archive() {
|
||||||
|
if (this.isTemplateSwimlane()) {
|
||||||
|
this.lists().forEach((list) => {
|
||||||
|
return list.archive();
|
||||||
|
});
|
||||||
|
}
|
||||||
return { $set: { archived: true } };
|
return { $set: { archived: true } };
|
||||||
},
|
},
|
||||||
|
|
||||||
restore() {
|
restore() {
|
||||||
|
if (this.isTemplateSwimlane()) {
|
||||||
|
this.allLists().forEach((list) => {
|
||||||
|
return list.restore();
|
||||||
|
});
|
||||||
|
}
|
||||||
return { $set: { archived: false } };
|
return { $set: { archived: false } };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue