diff --git a/app/components/viewer/index.js b/app/components/viewer/index.js
index 0b8af271e6f9e4d2e6ff10f4f16d3f0c2a211440..f7a47f92983faf5e05f5a441848abe26d18aa0cb 100644
--- a/app/components/viewer/index.js
+++ b/app/components/viewer/index.js
@@ -3,6 +3,7 @@ import { tracked } from '@glimmer/tracking';
 import { service } from '@ember/service';
 import { action } from '@ember/object';
 import { A } from '@ember/array';
+import { reposition_items } from 'papermerge/utils/array';
 
 
 export default class ViewerComponent extends Component {
@@ -145,9 +146,15 @@ export default class ViewerComponent extends Component {
 
   @action
   onThumbnailsPositionChanged({original_pos, drop_pos, page_ids}) {
+    let all_pages;
+
     console.log(`onThumbnailsPositionChanged`);
     console.log(`original_pos=${original_pos}, drop_pos=${drop_pos}, page_ids=${page_ids}`);
-    this._pages = [];
+    this._pages = reposition_items({
+      items: all_pages,
+      selected_ids: page_ids,
+      drop_pos: drop_pos
+    });
   }
 
   @action
diff --git a/app/utils/array.js b/app/utils/array.js
index 8744ab5d3d38e7ec60044ea2b8540b28ac24bc42..6f36cd397d165005d27599fded1f2cee9c27a45a 100644
--- a/app/utils/array.js
+++ b/app/utils/array.js
@@ -7,6 +7,7 @@ function get_id(item) {
   return item.get('id');
 }
 
+
 function merge_items(item_id, items) {
   /*
   Returns a list of {id: <item.id>} objects with no duplicates.
@@ -36,6 +37,36 @@ function merge_items(item_id, items) {
   return result_items;
 }
 
+function reposition_items({items, selected_ids, drop_pos}) {
+  let selected_items = [],
+    remaining_items = Array.from(items),
+    result = [],
+    i, j;
+
+  selected_ids.forEach(item_id => {
+    let idx, extracted_item;
+
+    idx = remaining_items.findIndex(p => get_id(p) == item_id);
+
+    extracted_item = remaining_items.slice(idx, 1);
+    selected_items.push(extracted_item);
+  });
+
+  for (i=0, j=0; i < items.length; j++) {
+    if (i == drop_pos) {
+      result.push(selected_items);
+      i += selected_items.length + 1;
+    } else { // i < drop_pos || i > drop_pos
+      result.push(remaining_items[j]);
+      i++;
+    }
+  }
+
+  return result;
+}
+
 export {
-  merge_items
+  get_id,
+  merge_items,
+  reposition_items,
 }
\ No newline at end of file
diff --git a/tests/unit/utils/array-test.js b/tests/unit/utils/array-test.js
new file mode 100644
index 0000000000000000000000000000000000000000..c0c50bc25820b2fd0f6b39c9d75bd75c7877f3e9
--- /dev/null
+++ b/tests/unit/utils/array-test.js
@@ -0,0 +1,27 @@
+import { module, test } from 'qunit';
+import { get_id, reposition_items } from 'papermerge/utils/array';
+
+
+module('Unit | Utils | Array', function () {
+
+  test('get_id 1', function (assert) {
+    let item;
+
+    item = {'id': 5};
+    assert.strictEqual(get_id(item), 5);
+  });
+
+  test('get_id 2', function (assert) {
+    let item;
+
+    item = {'id': 5};
+    assert.strictEqual(get_id(item), 5);
+
+    item = {
+      'get': () => 13
+    };
+
+    assert.strictEqual(get_id(item), 13);
+  });
+});
+
diff --git a/tests/unit/point-test.js b/tests/unit/utils/point-test.js
similarity index 100%
rename from tests/unit/point-test.js
rename to tests/unit/utils/point-test.js
diff --git a/tests/unit/rectangle-test.js b/tests/unit/utils/rectangle-test.js
similarity index 100%
rename from tests/unit/rectangle-test.js
rename to tests/unit/utils/rectangle-test.js
diff --git a/tests/unit/utils-test.js b/tests/unit/utils/utils-test.js
similarity index 100%
rename from tests/unit/utils-test.js
rename to tests/unit/utils/utils-test.js