FIX: Fixed category reordering using arrow icons (#7374)

FIX: Fixed category reordering using arrow icons (#7374)

diff --git a/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6 b/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6
index 70b48b5..f3cac07 100644
--- a/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6
+++ b/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6
@@ -36,10 +36,35 @@ export default Ember.Controller.extend(ModalFunctionality, Ember.Evented, {
 
   moveDir(cat, dir) {
     const cats = this.get("categoriesOrdered");
-    const curIdx = cats.indexOf(cat);
-    const desiredIdx = curIdx + dir;
+    const curIdx = cat.get("position");
+    let desiredIdx = curIdx + dir;
     if (desiredIdx >= 0 && desiredIdx < cats.get("length")) {
-      const otherCat = cats.objectAt(desiredIdx);
+      let otherCat = cats.objectAt(desiredIdx);
+
+      // Respect children
+      const parentIdx = otherCat.get("parent_category_id");
+      if (parentIdx && parentIdx !== cat.get("parent_category_id")) {
+        if (parentIdx === cat.get("id")) {
+          // We want to move down
+          for (let i = curIdx + 1; i < cats.get("length"); i++) {
+            let tmpCat = cats.objectAt(i);
+            if (!tmpCat.get("parent_category_id")) {
+              desiredIdx = cats.indexOf(tmpCat);
+              otherCat = tmpCat;
+              break;
+            }
+          }
+        } else {
+          // We want to move up
+          cats.forEach(function(tmpCat) {
+            if (tmpCat.get("id") === parentIdx) {
+              desiredIdx = cats.indexOf(tmpCat);
+              otherCat = tmpCat;
+            }
+          });
+        }
+      }
+
       otherCat.set("position", curIdx);
       cat.set("position", desiredIdx);
       this.send("commit");
@@ -89,7 +114,7 @@ export default Ember.Controller.extend(ModalFunctionality, Ember.Evented, {
         Math.max(position, 0),
         this.get("categoriesOrdered").length - 1
       );
-      this.moveDir(cat, amount - this.get("categoriesOrdered").indexOf(cat));
+      this.moveDir(cat, amount - cat.get("position"));
     },
 
     moveUp(cat) {
diff --git a/test/javascripts/controllers/reorder-categories-test.js.es6 b/test/javascripts/controllers/reorder-categories-test.js.es6
index 96941be..1b65368 100644
--- a/test/javascripts/controllers/reorder-categories-test.js.es6
+++ b/test/javascripts/controllers/reorder-categories-test.js.es6
@@ -157,3 +157,51 @@ QUnit.test(
     );
   }
 );
+
+QUnit.test(
+  "changing the position through click on arrow of a category should place it at given position and respect children",
+  function(assert) {
+    const store = createStore();
+
+    const elem1 = store.createRecord("category", {
+      id: 1,
+      position: 0,
+      slug: "foo"
+    });
+
+    const child1 = store.createRecord("category", {
+      id: 4,
+      position: 1,
+      slug: "foochild",
+      parent_category_id: 1
+    });
+
+    const elem2 = store.createRecord("category", {
+      id: 2,
+      position: 2,
+      slug: "bar"
+    });
+
+    const elem3 = store.createRecord("category", {
+      id: 3,
+      position: 3,
+      slug: "test"
+    });
+
+    const categories = [elem1, child1, elem2, elem3];
+    const site = Ember.Object.create({ categories: categories });
+    const reorderCategoriesController = this.subject({ site });
+
+    reorderCategoriesController.fixIndices();
+
+    reorderCategoriesController.actions.moveDown.call(
+      reorderCategoriesController,
+      elem1
+    );
+
+    assert.deepEqual(
+      reorderCategoriesController.get("categoriesOrdered").mapBy("slug"),
+      ["bar", "foo", "foochild", "test"]
+    );
+  }
+);

GitHub sha: 00ee68f7