diff --git a/app/assets/javascripts/boards/boards_bundle.js.es6 b/app/assets/javascripts/boards/boards_bundle.js.es6
index ca44a9912579878663f3c3db0d6ee7bba30eaddf..c8c85f4ec91ea1484e12f26b42b3f3a0c51a0d59 100644
--- a/app/assets/javascripts/boards/boards_bundle.js.es6
+++ b/app/assets/javascripts/boards/boards_bundle.js.es6
@@ -35,7 +35,7 @@ $(function () {
           const boards = resp.json();
 
           boards.forEach((board) => {
-            const list = BoardsStore.new(board, false);
+            const list = BoardsStore.addList(board);
 
             if (list.type === 'done') {
               list.position = 9999999;
diff --git a/app/assets/javascripts/boards/components/board.js.es6 b/app/assets/javascripts/boards/components/board.js.es6
index 1f3a417aecdd55f3aeac4a14fff6d4e6cd5fa8a5..ff9bffafd99a78e8955600cf31850305778cb521 100644
--- a/app/assets/javascripts/boards/components/board.js.es6
+++ b/app/assets/javascripts/boards/components/board.js.es6
@@ -45,7 +45,6 @@
         group: 'boards',
         draggable: '.is-draggable',
         handle: '.js-board-handle',
-        filter: '.board-delete',
         onUpdate: function (e) {
           BoardsStore.moveList(e.oldIndex, e.newIndex);
         }
diff --git a/app/assets/javascripts/boards/components/board_card.js.es6 b/app/assets/javascripts/boards/components/board_card.js.es6
new file mode 100644
index 0000000000000000000000000000000000000000..14191cb881be8a9ac61f4fc3096860d8f3c5fffd
--- /dev/null
+++ b/app/assets/javascripts/boards/components/board_card.js.es6
@@ -0,0 +1,25 @@
+(() => {
+  const BoardCard = Vue.extend({
+    props: {
+      issue: Object,
+      issueLinkBase: String,
+      disabled: Boolean
+    },
+    methods: {
+      filterByLabel: function (label, $event) {
+        const labelIndex = BoardsStore.state.filters['label_name'].indexOf(label.title);
+        // $($event.target).tooltip('hide');
+
+        if (labelIndex === -1) {
+          BoardsStore.state.filters['label_name'].push(label.title);
+        } else {
+          BoardsStore.state.filters['label_name'].splice(labelIndex, 1);
+        }
+
+        BoardsStore.updateFiltersUrl();
+      }
+    }
+  });
+
+  Vue.component('board-card', BoardCard);
+})();
diff --git a/app/assets/javascripts/boards/components/board_delete.js.es6 b/app/assets/javascripts/boards/components/board_delete.js.es6
index b9afb5724f5fa2697a97720c4754980dfa685257..958d85cd326e36fc7e1abff235a3f9f308d6f2d2 100644
--- a/app/assets/javascripts/boards/components/board_delete.js.es6
+++ b/app/assets/javascripts/boards/components/board_delete.js.es6
@@ -1,14 +1,14 @@
 (() => {
   const BoardDelete = Vue.extend({
     props: {
-      boardId: Number
+      list: Object
     },
     methods: {
       deleteBoard: function () {
         $(this.$el).tooltip('destroy');
 
         if (confirm('Are you sure you want to delete this list?')) {
-          BoardsStore.removeList(this.boardId);
+          this.list.destroy();
         }
       }
     }
diff --git a/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6 b/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6
index 2b2620fd8a1db7474915944ef55ff24f0c79617a..4509589edf22d63b2c413a2f8dd020065f6d549c 100644
--- a/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6
+++ b/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6
@@ -8,6 +8,7 @@
     fallbackClass: 'is-dragging',
     fallbackOnBody: true,
     ghostClass: 'is-ghost',
+    filter: '.has-tooltip',
     scrollSensitivity: 50,
     scrollSpeed: 10,
     onStart: function () {
diff --git a/app/assets/javascripts/boards/models/label.js.es6 b/app/assets/javascripts/boards/models/label.js.es6
index d2ce30c37ea9226944cde90ec36458080b2de054..99daf093d373820f76926beb393b44759df0c708 100644
--- a/app/assets/javascripts/boards/models/label.js.es6
+++ b/app/assets/javascripts/boards/models/label.js.es6
@@ -3,5 +3,6 @@ class Label {
     this.id = obj.id;
     this.title = obj.title;
     this.color = obj.color;
+    this.description = obj.description;
   }
 }
diff --git a/app/assets/javascripts/boards/models/list.js.es6 b/app/assets/javascripts/boards/models/list.js.es6
index c2b06e4ed73ebbd17ea0d2d9aaec74ee4bb06f12..60214e2c79899b96ec02f327d061301079ea096f 100644
--- a/app/assets/javascripts/boards/models/list.js.es6
+++ b/app/assets/javascripts/boards/models/list.js.es6
@@ -33,6 +33,11 @@ class List {
 
   destroy () {
     if (this.type !== 'blank') {
+      BoardsStore.state.lists = _.reject(BoardsStore.state.lists, (list) => {
+        return list.id === this.id;
+      });
+      BoardsStore.updateNewListDropdown();
+
       gl.boardService.destroyList(this.id);
     }
   }
diff --git a/app/assets/javascripts/boards/stores/boards_store.js.es6 b/app/assets/javascripts/boards/stores/boards_store.js.es6
index fe2b11a9a8ecb6dd5234f45212139883a806a2b7..84acbeef10272611f30a8303b201d7ffab0cf0dd 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js.es6
+++ b/app/assets/javascripts/boards/stores/boards_store.js.es6
@@ -11,53 +11,51 @@
         label_name: gl.utils.getParameterValues('label_name[]')
       };
     },
-    new: function (board, persist = true) {
-      const doneList = this.findList('type', 'done'),
-            backlogList = this.findList('type', 'backlog'),
-            list = new List(board);
+    addList: function (listObj) {
+      const list = new List(listObj);
       this.state.lists.push(list);
 
-      if (persist) {
-        list
-          .save()
-          .then(function () {
-            // Remove any new issues from the backlog
-            // as they will be visible in the new list
-            _.each(list.issues, backlogList.removeIssue.bind(backlogList));
-          });
-        this.removeBlankState();
-      }
-
       return list;
     },
+    new: function (listObj) {
+      const list = this.addList(listObj),
+            backlogList = this.findList('type', 'backlog');
+
+      list
+        .save()
+        .then(function () {
+          // Remove any new issues from the backlog
+          // as they will be visible in the new list
+          _.each(list.issues, backlogList.removeIssue.bind(backlogList));
+        });
+      this.removeBlankState();
+    },
     updateNewListDropdown: function () {
       const data = $('.js-new-board-list').data('glDropdown').renderedData;
-      $('.js-new-board-list').data('glDropdown').renderData(data);
+
+      if (data) {
+        $('.js-new-board-list').data('glDropdown').renderData(data);
+      }
     },
     shouldAddBlankState: function () {
       // Decide whether to add the blank state
-      let addBlankState = _.find(this.state.lists, function (list) {
+      return !_.find(this.state.lists, function (list) {
         return list.type === 'backlog' || list.type === 'done';
       });
-      return !addBlankState;
     },
     addBlankState: function () {
-      const addBlankState = this.shouldAddBlankState();
-
       if (this.welcomeIsHidden() || this.disabled) return;
 
-      if (addBlankState) {
-        this.new({
+      if (this.shouldAddBlankState()) {
+        this.addList({
           id: 'blank',
           list_type: 'blank',
           title: 'Welcome to your Issue Board!',
           position: 0
-        }, false);
+        });
       }
     },
     removeBlankState: function () {
-      if (this.welcomeIsHidden()) return;
-
       this.removeList('blank');
 
       $.cookie('issue_board_welcome_hidden', 'true', {
@@ -72,13 +70,9 @@
 
       if (!list) return;
 
-      list.destroy();
-
-      this.state.lists = _.reject(this.state.lists, function (list) {
+      this.state.lists = _.reject(this.state.lists, (list) => {
         return list.id === id;
       });
-
-      this.updateNewListDropdown();
     },
     moveList: function (oldIndex, newIndex) {
       if (oldIndex === newIndex) return;
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index 1af91f001b53822fdbd0a1c2e71a73e8e973a54b..364e5a41bb0d98b12c20118e50871d4fcdd0f45a 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -250,6 +250,11 @@
   a {
     cursor: pointer;
   }
+
+  .label {
+    border: 0;
+    outline: 0;
+  }
 }
 
 .card-title {
diff --git a/app/views/projects/boards/components/_board.html.haml b/app/views/projects/boards/components/_board.html.haml
index f7f1fb832c8575cd2732b1ed33961e6014cc7293..baf367af6760a7f9b8c74d4ad0a3a096945bff30 100644
--- a/app/views/projects/boards/components/_board.html.haml
+++ b/app/views/projects/boards/components/_board.html.haml
@@ -6,12 +6,14 @@
   .board{ ":class" => "{ 'is-draggable': !isPreset }" }
     .board-inner
       %header.board-header{ ":class" => "{ 'has-border': list.label }", ":style" => "{ borderTopColor: (list.label ? list.label.color : null) }" }
-        %h3.board-title.js-board-handle{ ":class" => "{ 'user-can-drag': !disabled }" }
+        %h3.board-title.js-board-handle{ ":class" => "{ 'user-can-drag': (!disabled && !isPreset) }" }
           {{ list.title }}
           %span.pull-right{ "v-if" => "list.type !== 'blank'" }
             {{ list.issues.length }}
           - if current_user
-            %board-delete{ "inline-template" => true, "v-if" => "!isPreset", ":board-id" => "list.id" }
+            %board-delete{ "inline-template" => true,
+              "v-if" => "!isPreset",
+              ":list" => "list" }
               %button.board-delete.has-tooltip.pull-right{ type: "button", title: "Delete list", "aria-label" => "Delete list", data: { placement: "bottom" }, "@click" => "deleteBoard" }
                 = icon("trash")
       .board-inner-container.board-search-container{ "v-if" => "list.canSearch()" }
diff --git a/app/views/projects/boards/components/_card.html.haml b/app/views/projects/boards/components/_card.html.haml
index 447b8af399144193c84e408ae723c495b0665cce..a7000607f1c19212d6e9c0fb20da5e172189fc9b 100644
--- a/app/views/projects/boards/components/_card.html.haml
+++ b/app/views/projects/boards/components/_card.html.haml
@@ -1,19 +1,26 @@
-%li.card{ ":data-issue" => "issue.id",
+%board-card{ "inline-template" => true,
   "v-for" => "issue in issues | orderBy 'id' -1",
-  "track-by" => "id",
-  ":class" => "{ 'user-can-drag': !disabled }" }
-  %h4.card-title
-    %a{ ":href" => "issueLinkBase + '/' + issue.id",
-      ":title" => "issue.title" }
-      {{ issue.title }}
-  .card-footer
-    %span.card-number
-      = precede '#' do
-        {{ issue.id }}
-    %span.label.color-label{ "v-for" => "label in issue.labels",
-      ":style" => "{ backgroundColor: label.color, color: label.textColor }" }
-      {{ label.title }}
-    %a.has-tooltip{ ":href" => "'/u/' + issue.assignee.username",
-      ":title" => "'Assigned to ' + issue.assignee.name",
-      "v-if" => "issue.assignee" }
-      %img.avatar.avatar-inline.s20{ ":src" => "issue.assignee.avatar", width: 20, height: 20 }
+  ":issue" => "issue",
+  ":issue-link-base" => "issueLinkBase",
+  ":disabled" => "disabled",
+  "track-by" => "id" }
+  %li.card{ ":data-issue" => "issue.id",
+    ":class" => "{ 'user-can-drag': !disabled }" }
+    %h4.card-title
+      %a{ ":href" => "issueLinkBase + '/' + issue.id",
+        ":title" => "issue.title" }
+        {{ issue.title }}
+    .card-footer
+      %span.card-number
+        = precede '#' do
+          {{ issue.id }}
+      %button.label.color-label.has-tooltip{ "v-for" => "label in issue.labels",
+        type: "button",
+        "@click" => "filterByLabel(label, $event)",
+        ":style" => "{ backgroundColor: label.color, color: label.textColor }",
+        ":title" => "label.description" }
+        {{ label.title }}
+      %a.has-tooltip{ ":href" => "'/u/' + issue.assignee.username",
+        ":title" => "'Assigned to ' + issue.assignee.name",
+        "v-if" => "issue.assignee" }
+        %img.avatar.avatar-inline.s20{ ":src" => "issue.assignee.avatar", width: 20, height: 20 }