Przeglądaj źródła

Labels drag/drop

Martin Filser 3 lat temu
rodzic
commit
c8b8fb83dc

+ 4 - 2
client/components/cards/labels.jade

@@ -27,9 +27,11 @@ template(name="deleteLabelPopup")
 template(name="cardLabelsPopup")
   ul.edit-labels-pop-over
     each board.labels
-      li
+      li.js-card-label-item
         a.card-label-edit-button.fa.fa-pencil.js-edit-label
-        span.card-label.card-label-selectable.js-select-label(class="card-label-{{color}}"
+        if isMiniScreenOrShowDesktopDragHandles
+          span.fa.label-handle(class="fa-arrows" title="{{_ 'dragLabel'}}")
+        span.card-label.card-label-selectable.js-select-label.card-label-wrapper(class="card-label-{{color}}"
           class="{{# if isLabelSelected ../_id }}active{{/if}}")
             +viewer
               = name

+ 51 - 8
client/components/cards/labels.js

@@ -39,15 +39,58 @@ Template.createLabelPopup.helpers({
   },
 });
 
-Template.cardLabelsPopup.events({
-  'click .js-select-label'(event) {
-    const card = Utils.getCurrentCard();
-    const labelId = this._id;
-    card.toggleLabel(labelId);
-    event.preventDefault();
+BlazeComponent.extendComponent({
+  onRendered() {
+    const itemsSelector = 'li.js-card-label-item:not(.placeholder)';
+    const $labels = this.$('.edit-labels-pop-over');
+
+    $labels.sortable({
+      connectWith: '.edit-labels-pop-over',
+      tolerance: 'pointer',
+      appendTo: '.edit-labels-pop-over',
+      helper: 'clone',
+      distance: 7,
+      items: itemsSelector,
+      placeholder: 'card-label-wrapper placeholder',
+      start(evt, ui) {
+        ui.helper.css('z-index', 1000);
+        ui.placeholder.height(ui.helper.height());
+        EscapeActions.clickExecute(evt.target, 'inlinedForm');
+      },
+      stop(evt, ui) {
+        const newLabelOrderOnlyIds = ui.item.parent().children().toArray().map(_element => Blaze.getData(_element)._id)
+        const card = Blaze.getData(this);
+        card.board().setNewLabelOrder(newLabelOrderOnlyIds);
+      },
+    });
+    Utils.enableClickOnTouch(itemsSelector);
+
+    // Disable drag-dropping if the current user is not a board member or is comment only
+    this.autorun(() => {
+      if (Utils.isMiniScreen()) {
+        $labels.sortable({
+          handle: '.label-handle',
+        });
+      }
+    });
   },
-  'click .js-edit-label': Popup.open('editLabel'),
-  'click .js-add-label': Popup.open('createLabel'),
+  events() {
+    return [
+      {
+        'click .js-select-label'(event) {
+          const card = Utils.getCurrentCard();
+          const labelId = this._id;
+          card.toggleLabel(labelId);
+          event.preventDefault();
+        },
+        'click .js-edit-label': Popup.open('editLabel'),
+        'click .js-add-label': Popup.open('createLabel'),
+      }
+    ];
+  }
+}).register('cardLabelsPopup');
+
+Template.cardLabelsPopup.events({
 });
 
 Template.formLabel.events({

+ 3 - 0
client/components/cards/labels.styl

@@ -222,3 +222,6 @@
   &:hover
     background: #dbdbdb
 
+ul.edit-labels-pop-over
+  span.fa.label-handle
+    padding-right: 10px;

+ 14 - 0
models/boards.js

@@ -901,6 +901,20 @@ Boards.helpers({
     return _id;
   },
 
+  /** sets the new label order
+   * @param newLabelOrderOnlyIds new order array of _id, e.g. Array(4) [ "FvtD34", "PAEgDP", "LjRBxH", "YJ8sZz" ]
+   */
+  setNewLabelOrder(newLabelOrderOnlyIds) {
+    if (this.labels.length == newLabelOrderOnlyIds.length) {
+      if (this.labels.every(_label => newLabelOrderOnlyIds.indexOf(_label._id) >= 0)) {
+        const newLabels = _.sortBy(this.labels, _label => newLabelOrderOnlyIds.indexOf(_label._id));
+        if (this.labels.length == newLabels.length) {
+          Boards.direct.update(this._id, {$set: {labels: newLabels}});
+        }
+      }
+    }
+  },
+
   searchBoards(term) {
     check(term, Match.OneOf(String, null, undefined));