123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- const { calculateIndexData, enableClickOnTouch } = Utils;
- function initSorting(items) {
- items.sortable({
- tolerance: 'pointer',
- helper: 'clone',
- items: '.js-checklist-item:not(.placeholder)',
- connectWith: '.js-checklist-items',
- appendTo: '.board-canvas',
- distance: 7,
- placeholder: 'checklist-item placeholder',
- scroll: false,
- start(evt, ui) {
- ui.placeholder.height(ui.helper.height());
- EscapeActions.executeUpTo('popup-close');
- },
- stop(evt, ui) {
- const parent = ui.item.parents('.js-checklist-items');
- const checklistId = Blaze.getData(parent.get(0)).checklist._id;
- let prevItem = ui.item.prev('.js-checklist-item').get(0);
- if (prevItem) {
- prevItem = Blaze.getData(prevItem).item;
- }
- let nextItem = ui.item.next('.js-checklist-item').get(0);
- if (nextItem) {
- nextItem = Blaze.getData(nextItem).item;
- }
- const nItems = 1;
- const sortIndex = calculateIndexData(prevItem, nextItem, nItems);
- const checklistDomElement = ui.item.get(0);
- const checklistData = Blaze.getData(checklistDomElement);
- const checklistItem = checklistData.item;
- items.sortable('cancel');
- checklistItem.move(checklistId, sortIndex.base);
- },
- });
- // ugly touch event hotfix
- enableClickOnTouch('.js-checklist-item:not(.placeholder)');
- }
- BlazeComponent.extendComponent({
- onRendered() {
- const self = this;
- self.itemsDom = this.$('.js-checklist-items');
- initSorting(self.itemsDom);
- self.itemsDom.mousedown(function(evt) {
- evt.stopPropagation();
- });
- function userIsMember() {
- return Meteor.user() && Meteor.user().isBoardMember();
- }
- // Disable sorting if the current user is not a board member
- self.autorun(() => {
- const $itemsDom = $(self.itemsDom);
- if ($itemsDom.data('sortable')) {
- $(self.itemsDom).sortable('option', 'disabled', !userIsMember());
- }
- });
- },
- canModifyCard() {
- return (
- Meteor.user() &&
- Meteor.user().isBoardMember() &&
- !Meteor.user().isCommentOnly()
- );
- },
- }).register('checklistDetail');
- BlazeComponent.extendComponent({
- addChecklist(event) {
- event.preventDefault();
- const textarea = this.find('textarea.js-add-checklist-item');
- const title = textarea.value.trim();
- let cardId = this.currentData().cardId;
- const card = Cards.findOne(cardId);
- if (card.isLinked()) cardId = card.linkedId;
- if (title) {
- Checklists.insert({
- cardId,
- title,
- sort: card.checklists().count(),
- });
- setTimeout(() => {
- this.$('.add-checklist-item')
- .last()
- .click();
- }, 100);
- }
- textarea.value = '';
- textarea.focus();
- },
- addChecklistItem(event) {
- event.preventDefault();
- const textarea = this.find('textarea.js-add-checklist-item');
- const title = textarea.value.trim();
- const checklist = this.currentData().checklist;
- if (title) {
- ChecklistItems.insert({
- title,
- checklistId: checklist._id,
- cardId: checklist.cardId,
- sort: checklist.itemCount(),
- });
- }
- // We keep the form opened, empty it.
- textarea.value = '';
- textarea.focus();
- },
- canModifyCard() {
- return (
- Meteor.user() &&
- Meteor.user().isBoardMember() &&
- !Meteor.user().isCommentOnly()
- );
- },
- deleteChecklist() {
- const checklist = this.currentData().checklist;
- if (checklist && checklist._id) {
- Checklists.remove(checklist._id);
- this.toggleDeleteDialog.set(false);
- }
- },
- deleteItem() {
- const checklist = this.currentData().checklist;
- const item = this.currentData().item;
- if (checklist && item && item._id) {
- ChecklistItems.remove(item._id);
- }
- },
- editChecklist(event) {
- event.preventDefault();
- const textarea = this.find('textarea.js-edit-checklist-item');
- const title = textarea.value.trim();
- const checklist = this.currentData().checklist;
- checklist.setTitle(title);
- },
- editChecklistItem(event) {
- event.preventDefault();
- const textarea = this.find('textarea.js-edit-checklist-item');
- const title = textarea.value.trim();
- const item = this.currentData().item;
- item.setTitle(title);
- },
- onCreated() {
- this.toggleDeleteDialog = new ReactiveVar(false);
- this.checklistToDelete = null; //Store data context to pass to checklistDeleteDialog template
- },
- pressKey(event) {
- //If user press enter key inside a form, submit it
- //Unless the user is also holding down the 'shift' key
- if (event.keyCode === 13 && !event.shiftKey) {
- event.preventDefault();
- const $form = $(event.currentTarget).closest('form');
- $form.find('button[type=submit]').click();
- }
- },
- events() {
- const events = {
- 'click .toggle-delete-checklist-dialog'(event) {
- if ($(event.target).hasClass('js-delete-checklist')) {
- this.checklistToDelete = this.currentData().checklist; //Store data context
- }
- this.toggleDeleteDialog.set(!this.toggleDeleteDialog.get());
- },
- };
- return [
- {
- ...events,
- 'submit .js-add-checklist': this.addChecklist,
- 'submit .js-edit-checklist-title': this.editChecklist,
- 'submit .js-add-checklist-item': this.addChecklistItem,
- 'submit .js-edit-checklist-item': this.editChecklistItem,
- 'click .js-delete-checklist-item': this.deleteItem,
- 'click .confirm-checklist-delete': this.deleteChecklist,
- keydown: this.pressKey,
- },
- ];
- },
- }).register('checklists');
- Template.checklistDeleteDialog.onCreated(() => {
- const $cardDetails = this.$('.card-details');
- this.scrollState = {
- position: $cardDetails.scrollTop(), //save current scroll position
- top: false, //required for smooth scroll animation
- };
- //Callback's purpose is to only prevent scrolling after animation is complete
- $cardDetails.animate({ scrollTop: 0 }, 500, () => {
- this.scrollState.top = true;
- });
- //Prevent scrolling while dialog is open
- $cardDetails.on('scroll', () => {
- if (this.scrollState.top) {
- //If it's already in position, keep it there. Otherwise let animation scroll
- $cardDetails.scrollTop(0);
- }
- });
- });
- Template.checklistDeleteDialog.onDestroyed(() => {
- const $cardDetails = this.$('.card-details');
- $cardDetails.off('scroll'); //Reactivate scrolling
- $cardDetails.animate({ scrollTop: this.scrollState.position });
- });
- Template.checklistItemDetail.helpers({
- canModifyCard() {
- return (
- Meteor.user() &&
- Meteor.user().isBoardMember() &&
- !Meteor.user().isCommentOnly()
- );
- },
- });
- BlazeComponent.extendComponent({
- toggleItem() {
- const checklist = this.currentData().checklist;
- const item = this.currentData().item;
- if (checklist && item && item._id) {
- item.toggleItem();
- }
- },
- events() {
- return [
- {
- 'click .js-checklist-item .check-box': this.toggleItem,
- },
- ];
- },
- }).register('checklistItemDetail');
|