Merge pull request #4297 from mfilser/checklist_action_menu_and_move_checklist

Added "move checklist" and created a "Checklist Action Menu"
This commit is contained in:
Lauri Ojansivu 2022-01-18 01:02:08 +02:00 committed by GitHub
commit cd6b4529be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 304 additions and 12 deletions

View file

@ -31,7 +31,7 @@ template(name="checklistDetail")
.checklist-title
span
if canModifyCard
a.js-delete-checklist.toggle-delete-checklist-dialog {{_ "delete"}}...
a.fa.fa-navicon.checklist-details-menu.js-open-checklist-details-menu(title="{{_ 'checklistActionsPopup-title'}}")
if canModifyCard
h2.title.js-open-inlined-form.is-editable
@ -133,3 +133,41 @@ template(name="boardsSwimlanesAndLists")
.edit-controls.clearfix
button.primary.confirm.js-done {{_ 'done'}}
template(name="checklistActionsPopup")
ul.pop-over-list
li
a.js-delete-checklist.delete-checklist
i.fa.fa-trash
| {{_ "delete"}} ...
a.js-move-checklist.move-checklist
i.fa.fa-arrow-right
| {{_ "moveChecklist"}} ...
template(name="moveChecklistPopup")
unless currentUser.isWorker
label {{_ 'boards'}}:
select.js-select-boards(autofocus)
each boards
if $eq _id currentBoard._id
option(value="{{_id}}" selected) {{_ 'current'}}
else
option(value="{{_id}}" selected="{{#if isMoveChecklistDialogOptionBoardId _id}}selected{{/if}}") {{title}}
label {{_ 'swimlanes'}}:
select.js-select-swimlanes
each swimlanes
option(value="{{_id}}" selected="{{#if isMoveChecklistDialogOptionSwimlaneId _id}}selected{{/if}}") {{title}}
label {{_ 'lists'}}:
select.js-select-lists
each lists
option(value="{{_id}}" selected="{{#if isMoveChecklistDialogOptionListId _id}}selected{{/if}}") {{title}}
label {{_ 'cards'}}:
select.js-select-cards
each cards
option(value="{{_id}}" selected="{{#if isMoveChecklistDialogOptionCardId _id}}selected{{/if}}") {{title}}
.edit-controls.clearfix
button.primary.confirm.js-done {{_ 'done'}}

View file

@ -190,13 +190,7 @@ BlazeComponent.extendComponent({
return [
{
...events,
'click .toggle-delete-checklist-dialog' : Popup.afterConfirm('checklistDelete', function () {
Popup.close();
const checklist = this.checklist;
if (checklist && checklist._id) {
Checklists.remove(checklist._id);
}
}),
'click .js-open-checklist-details-menu': Popup.open('checklistActions'),
'submit .js-add-checklist': this.addChecklist,
'submit .js-edit-checklist-title': this.editChecklist,
'submit .js-add-checklist-item': this.addChecklistItem,
@ -293,6 +287,23 @@ BlazeComponent.extendComponent({
}
}).register('addChecklistItemForm');
BlazeComponent.extendComponent({
events() {
return [
{
'click .js-delete-checklist' : Popup.afterConfirm('checklistDelete', function () {
Popup.back(2);
const checklist = this.checklist;
if (checklist && checklist._id) {
Checklists.remove(checklist._id);
}
}),
'click .js-move-checklist' : Popup.open('moveChecklist'),
}
]
}
}).register('checklistActionsPopup');
BlazeComponent.extendComponent({
onRendered() {
autosize(this.$('textarea.js-edit-checklist-item'));
@ -352,3 +363,155 @@ BlazeComponent.extendComponent({
];
},
}).register('checklistItemDetail');
BlazeComponent.extendComponent({
onCreated() {
const boardId = Utils.getCurrentBoardId();
subManager.subscribe('board', boardId, false);
// subManager.subscribe('swimlane', swimlaneId, false);
// subManager.subscribe('list', listId, false);
// subManager.subscribe('card', cardId, false);
this.selectedBoardId = new ReactiveVar(boardId);
this.selectedSwimlaneId = new ReactiveVar('');
this.selectedListId = new ReactiveVar('');
this.selectedCardId = new ReactiveVar('');
this.setMoveChecklistDialogOption(boardId);
},
/** set the last confirmed dialog field values
* @param boardId the current board id
*/
setMoveChecklistDialogOption(boardId) {
this.moveChecklistDialogOption = {
'boardId' : "",
'swimlaneId' : "",
'listId' : "",
'cardId': "",
}
let currentOptions = Meteor.user().getMoveChecklistDialogOptions();
if (currentOptions && boardId && currentOptions[boardId]) {
this.moveChecklistDialogOption = currentOptions[boardId];
}
const board = Boards.findOne(boardId);
try {
const swimlaneId = board.swimlanes().fetch()[0]._id;
this.selectedSwimlaneId.set(swimlaneId);
} catch (e) {}
try {
const listId = board.lists().fetch()[0];
this.selectedListId.set(listId);
} catch (e) {}
const cardId = Utils.getCurrentCardId();
this.selectedCardId.set(cardId);
},
/** returns if the board id was the last confirmed one
* @param boardId check this board id
* @return if the board id was the last confirmed one
*/
isMoveChecklistDialogOptionBoardId(boardId) {
let ret = this.moveChecklistDialogOption.boardId == boardId;
return ret;
},
/** returns if the swimlane id was the last confirmed one
* @param swimlaneId check this swimlane id
* @return if the swimlane id was the last confirmed one
*/
isMoveChecklistDialogOptionSwimlaneId(swimlaneId) {
let ret = this.moveChecklistDialogOption.swimlaneId == swimlaneId;
return ret;
},
/** returns if the list id was the last confirmed one
* @param listId check this list id
* @return if the list id was the last confirmed one
*/
isMoveChecklistDialogOptionListId(listId) {
let ret = this.moveChecklistDialogOption.listId == listId;
return ret;
},
/** returns if the card id was the last confirmed one
* @param cardId check this card id
* @return if the card id was the last confirmed one
*/
isMoveChecklistDialogOptionCardId(cardId) {
let ret = this.moveChecklistDialogOption.cardId == cardId;
return ret;
},
boards() {
return Boards.find(
{
archived: false,
'members.userId': Meteor.userId(),
_id: { $ne: Meteor.user().getTemplatesBoardId() },
},
{
sort: { sort: 1 },
},
);
},
swimlanes() {
const board = Boards.findOne(this.selectedBoardId.get());
return board.swimlanes();
},
lists() {
const board = Boards.findOne(this.selectedBoardId.get());
return board.lists();
},
cards() {
const list = Lists.findOne(this.selectedListId.get());
const ret = list.cards(this.selectedSwimlaneId.get());
return ret;
},
events() {
return [
{
'click .js-done'() {
const boardSelect = this.$('.js-select-boards')[0];
const boardId = boardSelect.options[boardSelect.selectedIndex].value;
const listSelect = this.$('.js-select-lists')[0];
const listId = listSelect.options[listSelect.selectedIndex].value;
const swimlaneSelect = this.$('.js-select-swimlanes')[0];
const swimlaneId = swimlaneSelect.options[swimlaneSelect.selectedIndex].value;
const cardSelect = this.$('.js-select-cards')[0];
const cardId = cardSelect.options[cardSelect.selectedIndex].value;
const options = {
'boardId' : boardId,
'swimlaneId' : swimlaneId,
'listId' : listId,
'cardId': cardId,
}
Meteor.user().setMoveChecklistDialogOption(boardId, options);
this.data().checklist.move(cardId);
Popup.back(2);
},
'change .js-select-boards'(event) {
const boardId = $(event.currentTarget).val();
subManager.subscribe('board', boardId, false);
this.setMoveChecklistDialogOption(boardId);
this.selectedBoardId.set(boardId);
},
'change .js-select-swimlanes'(event) {
this.selectedSwimlaneId.set($(event.currentTarget).val());
},
'change .js-select-lists'(event) {
this.selectedListId.set($(event.currentTarget).val());
},
},
];
},
}).register('moveChecklistPopup');

View file

@ -39,9 +39,6 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
&.is-finished
color: #3cb500
.js-delete-checklist
@extends .delete-text
span.fa.checklist-handle
padding-right: 20px
padding-top: 3px
@ -142,3 +139,7 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
background: #dbdbdb
color: #222
box-shadow: 0 1px 2px rgba(0,0,0,.2)
.checklist-details-menu
float: right
padding: 6px 10px 6px 10px

View file

@ -1138,5 +1138,8 @@
"custom-legal-notice-link-url": "Custom legal notice page URL",
"acceptance_of_our_legalNotice": "By continuing, you accept our",
"legalNotice": "legal notice",
"copied": "Copied!"
"copied": "Copied!",
"checklistActionsPopup-title": "Checklist Actions",
"moveChecklist": "Move Checklist",
"moveChecklistPopup-title": "Move Checklist"
}

View file

@ -147,6 +147,37 @@ Checklists.mutations({
setTitle(title) {
return { $set: { title } };
},
/** move the checklist to another card
* @param newCardId move the checklist to this cardId
*/
move(newCardId) {
// update every activity
Activities.find(
{checklistId: this._id}
).forEach(activity => {
Activities.update(activity._id, {
$set: {
cardId: newCardId,
},
});
});
// update every checklist-item
ChecklistItems.find(
{checklistId: this._id}
).forEach(checklistItem => {
ChecklistItems.update(checklistItem._id, {
$set: {
cardId: newCardId,
},
});
});
// update the checklist itself
return {
$set: {
cardId: newCardId,
},
};
},
});
if (Meteor.isServer) {

View file

@ -252,6 +252,38 @@ Users.attachSchema(
*/
type: String,
},
'profile.moveChecklistDialog' : {
/**
* move and copy card dialog
*/
type: Object,
optional: true,
blackbox: true,
},
'profile.moveChecklistDialog.$.boardId': {
/**
* last selected board id
*/
type: String,
},
'profile.moveChecklistDialog.$.swimlaneId': {
/**
* last selected swimlane id
*/
type: String,
},
'profile.moveChecklistDialog.$.listId': {
/**
* last selected list id
*/
type: String,
},
'profile.moveChecklistDialog.$.cardId': {
/**
* last selected card id
*/
type: String,
},
'profile.notifications': {
/**
* enabled notifications for the user
@ -653,6 +685,17 @@ Users.helpers({
return _ret;
},
/** returns all confirmed move checklist dialog field values
* <li> the board, swimlane, list and card id is stored for each board
*/
getMoveChecklistDialogOptions() {
let _ret = {}
if (this.profile && this.profile.moveChecklistDialog) {
_ret = this.profile.moveChecklistDialog;
}
return _ret;
},
hasTag(tag) {
const { tags = [] } = this.profile || {};
return _.contains(tags, tag);
@ -781,6 +824,19 @@ Users.mutations({
},
};
},
/** set the confirmed board id/swimlane id/list id/card id of a board
* @param boardId the current board id
* @param options an object with the confirmed field values
*/
setMoveChecklistDialogOption(boardId, options) {
let currentOptions = this.getMoveChecklistDialogOptions();
currentOptions[boardId] = options;
return {
$set: {
'profile.moveChecklistDialog': currentOptions,
},
};
},
toggleBoardStar(boardId) {
const queryKind = this.hasStarred(boardId) ? '$pull' : '$addToSet';
return {