diff --git a/app/assets/javascripts/boards/boards_bundle.js.es6 b/app/assets/javascripts/boards/boards_bundle.js.es6
index b3dbf8270a8839fd972dabe636a484a00d44f360..d01d863361186e227e8fb43f24aaef01ccf0c0b7 100644
--- a/app/assets/javascripts/boards/boards_bundle.js.es6
+++ b/app/assets/javascripts/boards/boards_bundle.js.es6
@@ -1,6 +1,7 @@
 //= require vue
 //= require vue-resource
 //= require Sortable
+//= require_tree ./models
 //= require_tree ./stores
 //= require_tree ./services
 //= require_tree ./components
@@ -16,8 +17,8 @@ $(function () {
     ready: function () {
       service.all()
         .then((resp) => {
-          resp.data.forEach((board) => {
-            BoardsStore.state.lists.push(board);
+          resp.json().forEach((board) => {
+            BoardsStore.new(board);
           });
         });
     }
diff --git a/app/assets/javascripts/boards/components/board.js.es6 b/app/assets/javascripts/boards/components/board.js.es6
index 75fdf61821d2e3c011420c4889718eed1967f60d..9836790eb74fd791af6d18c3a6c7707ef9112990 100644
--- a/app/assets/javascripts/boards/components/board.js.es6
+++ b/app/assets/javascripts/boards/components/board.js.es6
@@ -27,7 +27,7 @@
         fallbackClass: 'is-dragging',
         ghostClass: 'is-ghost',
         onUpdate: function (e) {
-          BoardsStore.moveBoard(e.oldIndex + 1, e.newIndex + 1);
+          BoardsStore.moveList(e.oldIndex + 1, e.newIndex + 1);
         }
       });
     },
diff --git a/app/assets/javascripts/boards/components/board_delete.js.es6 b/app/assets/javascripts/boards/components/board_delete.js.es6
index 75157f8ff3381de92ac22431cd8c46d87aee0929..cff93f226128cb9136d268ce0f4de53654d97521 100644
--- a/app/assets/javascripts/boards/components/board_delete.js.es6
+++ b/app/assets/javascripts/boards/components/board_delete.js.es6
@@ -8,7 +8,7 @@
         $(this.$el).tooltip('destroy');
 
         if (confirm('Are you sure you want to delete this list?')) {
-          BoardsStore.removeBoard(this.boardId);
+          BoardsStore.removeList(this.boardId);
         }
       }
     }
diff --git a/app/assets/javascripts/boards/components/board_list.js.es6 b/app/assets/javascripts/boards/components/board_list.js.es6
index ea40563ebe946af3b801fadf75895cc16e9cd026..942382ff543a65b2a47e3ce9a966caf97df641b6 100644
--- a/app/assets/javascripts/boards/components/board_list.js.es6
+++ b/app/assets/javascripts/boards/components/board_list.js.es6
@@ -62,13 +62,13 @@
         fallbackClass: 'is-dragging',
         ghostClass: 'is-ghost',
         onAdd: (e) => {
-          let fromBoardId = e.from.getAttribute('data-board');
-          fromBoardId = parseInt(fromBoardId) || fromBoardId;
-          let toBoardId = e.to.getAttribute('data-board');
-          toBoardId = parseInt(toBoardId) || toBoardId;
+          let fromListId = e.from.getAttribute('data-board');
+          fromListId = parseInt(fromListId) || fromListId;
+          let toListId = e.to.getAttribute('data-board');
+          toListId = parseInt(toListId) || toListId;
           const issueId = parseInt(e.item.getAttribute('data-issue'));
 
-          BoardsStore.moveCardToBoard(fromBoardId, toBoardId, issueId, e.newIndex);
+          BoardsStore.moveCardToList(fromListId, toListId, issueId, e.newIndex);
         },
         onUpdate: (e) => {
           console.log(e.newIndex, e.oldIndex);
diff --git a/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 b/app/assets/javascripts/boards/components/new_list_dropdown.js.es6
new file mode 100644
index 0000000000000000000000000000000000000000..0796a95219ee16a1aaf0987b1c739f88603f0dec
--- /dev/null
+++ b/app/assets/javascripts/boards/components/new_list_dropdown.js.es6
@@ -0,0 +1,32 @@
+$(() => {
+  $('.js-new-board-list').each(function () {
+    const $this = $(this);
+
+    $this.glDropdown({
+      data: function(term, callback) {
+        $.ajax({
+          url: $this.attr('data-labels')
+        }).then((resp) => {
+          callback(resp);
+        });
+      },
+      renderRow: (label) => {
+        const $li = $('<li />'),
+              $a = $('<a />', {
+                text: label.title,
+                href: '#'
+              }),
+              $labelColor = $('<span />', {
+                class: 'dropdown-label-box',
+                style: `background-color: ${label.color}`
+              });
+
+        return $li.append($a.prepend($labelColor));
+      },
+      selectable: true,
+      clicked: (label, $el, e) => {
+        e.preventDefault();
+      }
+    });
+  });
+});
diff --git a/app/assets/javascripts/boards/models/issue.js.es6 b/app/assets/javascripts/boards/models/issue.js.es6
new file mode 100644
index 0000000000000000000000000000000000000000..a8fed848445c27ff2d37ad41a315992020e5d852
--- /dev/null
+++ b/app/assets/javascripts/boards/models/issue.js.es6
@@ -0,0 +1,35 @@
+class Issue {
+  constructor (obj) {
+    this.id = obj.id;
+    this.title = obj.title;
+    this.labels = [];
+
+    obj.labels.forEach((label) => {
+      this.labels.push(new Label(label));
+    });
+  }
+
+  addLabel (label) {
+    if (label) {
+      const hasLabel = this.findLabel(label);
+
+      if (!hasLabel) {
+        this.labels.push(new Label(label));
+      }
+    }
+  }
+
+  findLabel (findLabel) {
+    return _.find(this.labels, (label) => {
+      return label.title === findLabel.title;
+    });
+  }
+
+  removeLabel (removeLabel) {
+    if (removeLabel) {
+      this.labels = _.reject(this.labels, (label) => {
+        return removeLabel.title === label.title;
+      });
+    }
+  }
+}
diff --git a/app/assets/javascripts/boards/models/label.js.es6 b/app/assets/javascripts/boards/models/label.js.es6
new file mode 100644
index 0000000000000000000000000000000000000000..93da376de7cbd054f8ec85eac5c1bef8cdafbfc9
--- /dev/null
+++ b/app/assets/javascripts/boards/models/label.js.es6
@@ -0,0 +1,7 @@
+class Label {
+  constructor (obj) {
+    this.title = obj.title;
+    this.backgroundColor = obj.backgroundColor;
+    this.textColor = obj.textColor;
+  }
+}
diff --git a/app/assets/javascripts/boards/models/list.js.es6 b/app/assets/javascripts/boards/models/list.js.es6
new file mode 100644
index 0000000000000000000000000000000000000000..ebef8bc6fd70ddd00efab897674092cd88f4b6fa
--- /dev/null
+++ b/app/assets/javascripts/boards/models/list.js.es6
@@ -0,0 +1,49 @@
+class List {
+  constructor (obj) {
+    this.id = obj.id;
+    this.index = obj.index;
+    this.search = obj.search || false;
+    this.title = obj.title;
+
+    if (obj.label) {
+      this.label = new Label(obj.label);
+    }
+
+    if (obj.issues) {
+      this.issues = [];
+      obj.issues.forEach((issue) => {
+        this.issues.push(new Issue(issue));
+      });
+    }
+  }
+
+  addIssue (issue, index) {
+    this.issues.splice(index, 0, issue);
+
+    issue.addLabel(this.label);
+  }
+
+  findIssue (id) {
+    return _.find(this.issues, (issue) => {
+      return issue.id === id;
+    });
+  }
+
+  removeIssue (removeIssue, listLabels) {
+    this.issues = _.reject(this.issues, (issue) => {
+      const matchesRemove = removeIssue.id === issue.id;
+
+      if (matchesRemove) {
+        if (typeof listLabels !== 'undefined') {
+          listLabels.forEach((listLabel) => {
+            issue.removeLabel(listLabel);
+          });
+        } else {
+          issue.removeLabel(this.label);
+        }
+      }
+
+      return matchesRemove;
+    });
+  }
+}
diff --git a/app/assets/javascripts/boards/stores/boards_store.js.es6 b/app/assets/javascripts/boards/stores/boards_store.js.es6
index 6e5da9ea9f0cbaf340546c16e53101f2543292a3..be80447d0d7d30fd4f94e19df64a5996b97a365c 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js.es6
+++ b/app/assets/javascripts/boards/stores/boards_store.js.es6
@@ -9,103 +9,63 @@
         milestone: {},
       }
     },
-    removeBoard: (id) => {
-      BoardsStore.state.lists = _.reject(BoardsStore.state.lists, (board) => {
-        return board.id === id;
+    new: function (board) {
+      const list = new List(board);
+      this.state.lists.push(list);
+    },
+    removeList: function (id) {
+      this.state.lists = _.reject(this.state.lists, (list) => {
+        return list.id === id;
       });
     },
-    moveBoard: (oldIndex, newIndex) => {
-      const boardFrom = _.find(BoardsStore.state.lists, (board) => {
-        return board.index === oldIndex;
+    moveList: function (oldIndex, newIndex) {
+      const listFrom = _.find(this.state.lists, (list) => {
+        return list.index === oldIndex;
       });
 
-      service.updateBoard(boardFrom.id, newIndex);
+      service.updateBoard(listFrom.id, newIndex);
 
-      const boardTo = _.find(BoardsStore.state.lists, (board) => {
-        return board.index === newIndex;
+      const listTo = _.find(this.state.lists, (list) => {
+        return list.index === newIndex;
       });
 
-      boardFrom.index = newIndex;
-      if (newIndex > boardTo.index) {
-        boardTo.index--;
+      listFrom.index = newIndex;
+      if (newIndex > listTo.index) {
+        listTo.index--;
       } else {
-        boardTo.index++;
+        listTo.index++;
       }
     },
-    moveCardToBoard: (boardFromId, boardToId, issueId, toIndex) => {
-      const boardFrom = _.find(BoardsStore.state.lists, (board) => {
-        return board.id === boardFromId;
-      });
-      const boardTo = _.find(BoardsStore.state.lists, (board) => {
-        return board.id === boardToId;
-      });
-      let issue = _.find(boardFrom.issues, (issue) => {
-        return issue.id === issueId;
+    moveCardToList: function (listFromId, listToId, issueId, toIndex) {
+      const listFrom = _.find(this.state.lists, (list) => {
+        return list.id === listFromId;
       });
-      const issueTo = _.find(boardTo.issues, (issue) => {
-        return issue.id === issueId;
-      });
-      const issueBoards = BoardsStore.getBoardsForIssue(issue);
-
-      // Remove the issue from old board
-      boardFrom.issues = _.reject(boardFrom.issues, (issue) => {
-        return issue.id === issueId;
+      const listTo = _.find(this.state.lists, (list) => {
+        return list.id === listToId;
       });
+      const issueTo = listTo.findIssue(issueId);
+      let issue = listFrom.findIssue(issueId);
+      const issueLists = this.getListsForIssue(issue);
+      listFrom.removeIssue(issue);
 
       // Add to new boards issues if it doesn't already exist
       if (issueTo) {
         issue = issueTo;
+        issue.removeLabel(listFrom.label);
       } else {
-        boardTo.issues.splice(toIndex, 0, issue);
+        listTo.addIssue(issue, toIndex);
       }
 
-      if (boardTo.id === 'done' && boardFrom.id !== 'backlog') {
-        BoardsStore.removeIssueFromBoards(issue, issueBoards);
-        issue.labels = _.reject(issue.labels, (label) => {
-          return label.title === boardFrom.title;
+      if (listTo.id === 'done' && listFrom.id !== 'backlog') {
+        issueLists.forEach((list) => {
+          issue.removeLabel(list.label);
+          list.removeIssue(issue);
         });
-      } else {
-        if (boardTo.label) {
-          if (boardFrom.id !== 'backlog') {
-            BoardsStore.removeIssueFromBoard(issue, boardFrom);
-          }
-          
-          foundLabel = _.find(issue.labels, (label) => {
-            return label.title === boardTo.title;
-          });
-
-          if (!foundLabel) {
-            issue.labels.push(boardTo.label);
-          }
-        }
       }
     },
-    removeIssueFromBoards: (issue, boards) => {
-      const boardLabels = _.map(boards, (board) => {
-        return board.title;
-      });
-
-      boards.issues = _.each(boards, (board) => {
-        board.issues = _.reject(board.issues, (boardIssue) => {
-          return issue.id === boardIssue.id;
-        });
-      });
-
-      issue.labels = _.reject(issue.labels, (label) => {
-        return boardLabels.indexOf(label.title) !== -1;
-      });
-    },
-    removeIssueFromBoard: (issue, board) => {
-      issue.labels = _.reject(issue.labels, (label) => {
-        return label.title === board.title;
-      });
-    },
-    getBoardsForIssue: (issue) => {
-      return _.filter(BoardsStore.state.lists, (board) => {
-        const foundIssue = _.find(board.issues, (boardIssue) => {
-          return issue.id === boardIssue.id;
-        });
-        return foundIssue;
+    getListsForIssue: function (issue) {
+      return _.filter(this.state.lists, (list) => {
+        return list.findIssue(issue.id);
       });
     },
     clearDone: () => {
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index a06679f599d055238746478f13e06a1307a4d63f..773f3975816be7f0fb55f4ef75e57e0db1c3445b 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -31,7 +31,7 @@
             = render 'shared/sort_dropdown'
           - else
             .dropdown
-              %button.btn.btn-create{ type: "button", data: { toggle: "dropdown" } }
+              %button.btn.btn-create.js-new-board-list{ type: "button", data: { toggle: "dropdown", labels: labels_filter_path } }
                 Create new list
               .dropdown-menu.dropdown-menu-paging.dropdown-menu-align-right.dropdown-menu-issues-board-new
                 = dropdown_title("Create a new list")