| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 | 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');
 |