Pārlūkot izejas kodu

Fix migration. Replace old checklist-item sort algorithm.

Andrés Manelli 7 gadi atpakaļ
vecāks
revīzija
153960742c

+ 2 - 2
client/components/cards/checklists.jade

@@ -70,7 +70,7 @@ template(name="editChecklistItemForm")
 
 template(name="checklistItems")
   .checklist-items.js-checklist-items
-    each item in checklist.getItemsSorted
+    each item in checklist.items
       +inlinedForm(classNames="js-edit-checklist-item" item = item checklist = checklist)
         +editChecklistItemForm(type = 'item' item = item checklist = checklist)
       else
@@ -84,7 +84,7 @@ template(name="checklistItems")
           | {{_ 'add-checklist-item'}}...
 
 template(name='itemDetail')
-  .item.js-checklist-item
+  .js-checklist-item.checklist-item
     if canModifyCard
       .check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
       .item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")

+ 32 - 34
client/components/cards/checklists.js

@@ -1,11 +1,14 @@
+const { calculateIndexData } = Utils;
+
 function initSorting(items) {
   items.sortable({
     tolerance: 'pointer',
     helper: 'clone',
     items: '.js-checklist-item:not(.placeholder)',
-    axis: 'y',
+    connectWith: '.js-checklist-items',
+    appendTo: '.board-canvas',
     distance: 7,
-    placeholder: 'placeholder',
+    placeholder: 'checklist-item placeholder',
     scroll: false,
     start(evt, ui) {
       ui.placeholder.height(ui.helper.height());
@@ -13,33 +16,24 @@ function initSorting(items) {
     },
     stop(evt, ui) {
       const parent = ui.item.parents('.js-checklist-items');
-      const orderedItems = [];
-      parent.find('.js-checklist-item').each(function(i, item) {
-        const checklistItem = Blaze.getData(item).item;
-        orderedItems.push(checklistItem._id);
-      });
-      items.sortable('cancel');
-      const formerParent = ui.item.parents('.js-checklist-items');
-      const checklist = Blaze.getData(parent.get(0)).checklist;
-      const oldChecklist = Blaze.getData(formerParent.get(0)).checklist;
-      if (oldChecklist._id !== checklist._id) {
-        const currentItem = Blaze.getData(ui.item.get(0)).item;
-        for (let i = 0; i < orderedItems.length; i++) {
-          const itemId = orderedItems[i];
-          if (itemId !== currentItem._id) continue;
-          const newItem = {
-            _id: checklist.getNewItemId(),
-            title: currentItem.title,
-            sort: i,
-            isFinished: currentItem.isFinished,
-          };
-          checklist.addFullItem(newItem);
-          orderedItems[i] = currentItem._id;
-          oldChecklist.removeItem(itemId);
-        }
-      } else {
-        checklist.sortItems(orderedItems);
+      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);
     },
   });
 }
@@ -95,7 +89,12 @@ BlazeComponent.extendComponent({
     const checklist = this.currentData().checklist;
 
     if (title) {
-      checklist.addItem(title);
+      ChecklistItems.insert({
+        title,
+        checklistId: checklist._id,
+        cardId: checklist.cardId,
+        sort: checklist.itemCount(),
+      });
     }
     // We keep the form opened, empty it.
     textarea.value = '';
@@ -118,7 +117,7 @@ BlazeComponent.extendComponent({
     const checklist = this.currentData().checklist;
     const item = this.currentData().item;
     if (checklist && item && item._id) {
-      checklist.removeItem(item._id);
+      ChecklistItems.remove(item._id);
     }
   },
 
@@ -135,9 +134,8 @@ BlazeComponent.extendComponent({
 
     const textarea = this.find('textarea.js-edit-checklist-item');
     const title = textarea.value.trim();
-    const itemId = this.currentData().item._id;
-    const checklist = this.currentData().checklist;
-    checklist.editItem(itemId, title);
+    const item = this.currentData().item;
+    item.setTitle(title);
   },
 
   onCreated() {
@@ -211,7 +209,7 @@ BlazeComponent.extendComponent({
     const checklist = this.currentData().checklist;
     const item = this.currentData().item;
     if (checklist && item && item._id) {
-      checklist.toggleItem(item._id);
+      item.toggleItem();
     }
   },
   events() {

+ 39 - 28
client/components/cards/checklists.styl

@@ -78,34 +78,45 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
   bottom: -600px
   right: 0
 
-.checklist-items
+.checklist-item
   margin: 0 0 0.5em 1.33em
+  line-height: 25px
+  font-size: 1.1em
+  margin-top: 3px
+  display: flex
 
-  .item
-    line-height: 25px
-    font-size: 1.1em
-    margin-top: 3px
-    display: flex
-    &:hover
-      background-color: darken(white, 8%)
-
-    .check-box
-      margin-top: 5px
-      &.is-checked
-        border-bottom: 2px solid #3cb500
-        border-right: 2px solid #3cb500
-
-    .item-title
-      flex: 1
-      padding-left: 10px;
-      &.is-checked
-        color: #8c8c8c
-        font-style: italic
-
-  .js-delete-checklist-item
-    @extends .delete-text
-    padding: 12px 0 0 0
+  &.placeholder
+    background: darken(white, 20%)
+    border-radius: 2px
+
+  &.ui-sortable-helper
+    box-shadow: -2px 2px 8px rgba(0, 0, 0, .3),
+                0 0 1px rgba(0, 0, 0, .5)
+    transform: rotate(4deg)
+    cursor: grabbing
+
+  &:hover
+    background-color: darken(white, 8%)
+
+  .check-box
+    margin-top: 5px
+    &.is-checked
+      border-bottom: 2px solid #3cb500
+      border-right: 2px solid #3cb500
+
+  .item-title
+    flex: 1
+    padding-left: 10px;
+    &.is-checked
+      color: #8c8c8c
+      font-style: italic
+
+.js-delete-checklist-item
+  margin: 0 0 0.5em 1.33em
+  @extends .delete-text
+  padding: 12px 0 0 0
 
-  .add-checklist-item
-    padding-top: 0.5em
-    display: inline-block
+.add-checklist-item
+  margin: 0 0 0.5em 1.33em
+  padding-top: 0.5em
+  display: inline-block

+ 31 - 0
client/lib/utils.js

@@ -33,6 +33,37 @@ Utils = {
     return $(window).width() <= 800;
   },
 
+  calculateIndexData(prevData, nextData, nItems = 1) {
+    let base, increment;
+    // If we drop the card to an empty column
+    if (!prevData && !nextData) {
+      base = 0;
+      increment = 1;
+    // If we drop the card in the first position
+    } else if (!prevData) {
+      base = nextData.sort - 1;
+      increment = -1;
+    // If we drop the card in the last position
+    } else if (!nextData) {
+      base = prevData.sort + 1;
+      increment = 1;
+    }
+    // In the general case take the average of the previous and next element
+    // sort indexes.
+    else {
+      const prevSortIndex = prevData.sort;
+      const nextSortIndex = nextData.sort;
+      increment = (nextSortIndex - prevSortIndex) / (nItems + 1);
+      base = prevSortIndex + increment;
+    }
+    // XXX Return a generator that yield values instead of a base with a
+    // increment number.
+    return {
+      base,
+      increment,
+    };
+  },
+
   // Determine the new sort index
   calculateIndex(prevCardDomElement, nextCardDomElement, nCards = 1) {
     let base, increment;

+ 1 - 1
models/activities.js

@@ -42,7 +42,7 @@ Activities.helpers({
     return Checklists.findOne(this.checklistId);
   },
   checklistItem() {
-    return Checklists.findOne(this.checklistId).getItem(this.checklistItemId);
+    return ChecklistItems.findOne(this.checklistItemId);
   },
 });
 

+ 10 - 0
models/checklistItems.js

@@ -47,6 +47,16 @@ ChecklistItems.mutations({
   toggleItem() {
     return { $set: { isFinished: !this.isFinished } };
   },
+  move(checklistId, sortIndex) {
+    const cardId = Checklists.findOne(checklistId).cardId;
+    const mutatedFields = {
+      cardId,
+      checklistId,
+      sort: sortIndex,
+    };
+
+    return {$set: mutatedFields};
+  }
 });
 
 // Activities helper

+ 2 - 2
server/migrations.js

@@ -191,10 +191,10 @@ Migrations.add('add-views', () => {
 Migrations.add('add-checklist-items', () => {
   Checklists.find().forEach((checklist) => {
     // Create new items
-    _.sortBy(checklist.items, 'sort').forEach((item) => {
+    _.sortBy(checklist.items, 'sort').forEach((item, index) => {
       ChecklistItems.direct.insert({
         title: item.title,
-        sort: item.sort,
+        sort: index,
         isFinished: item.isFinished,
         checklistId: checklist._id,
         cardId: checklist.cardId,