diff --git a/app/assets/javascripts/boards/components/modal/filters.js.es6 b/app/assets/javascripts/boards/components/modal/filters.js.es6
new file mode 100644
index 0000000000000000000000000000000000000000..6de06811d94482a8a7bb8f0f84263567303ce634
--- /dev/null
+++ b/app/assets/javascripts/boards/components/modal/filters.js.es6
@@ -0,0 +1,49 @@
+/* global Vue */
+const userFilter = require('./filters/user');
+const milestoneFilter = require('./filters/milestone');
+const labelFilter = require('./filters/label');
+
+module.exports = Vue.extend({
+  name: 'modal-filters',
+  props: {
+    projectId: {
+      type: Number,
+      required: true,
+    },
+    milestonePath: {
+      type: String,
+      required: true,
+    },
+    labelPath: {
+      type: String,
+      required: true,
+    },
+  },
+  destroyed() {
+    gl.issueBoards.ModalStore.setDefaultFilter();
+  },
+  components: {
+    userFilter,
+    milestoneFilter,
+    labelFilter,
+  },
+  template: `
+    <div class="modal-filters">
+      <user-filter
+        dropdown-class-name="dropdown-menu-author"
+        toggle-class-name="js-user-search js-author-search"
+        toggle-label="Author"
+        field-name="author_id"
+        :project-id="projectId"></user-filter>
+      <user-filter
+        dropdown-class-name="dropdown-menu-author"
+        toggle-class-name="js-assignee-search"
+        toggle-label="Assignee"
+        field-name="assignee_id"
+        :null-user="true"
+        :project-id="projectId"></user-filter>
+      <milestone-filter :milestone-path="milestonePath"></milestone-filter>
+      <label-filter :label-path="labelPath"></label-filter>
+    </div>
+  `,
+});
diff --git a/app/assets/javascripts/boards/components/modal/filters/label.js.es6 b/app/assets/javascripts/boards/components/modal/filters/label.js.es6
new file mode 100644
index 0000000000000000000000000000000000000000..4fc8f72a145673c8423f1ea032371a5af2c87adb
--- /dev/null
+++ b/app/assets/javascripts/boards/components/modal/filters/label.js.es6
@@ -0,0 +1,54 @@
+/* eslint-disable no-new */
+/* global Vue */
+/* global LabelsSelect */
+module.exports = Vue.extend({
+  name: 'filter-label',
+  props: {
+    labelPath: {
+      type: String,
+      required: true,
+    },
+  },
+  mounted() {
+    new LabelsSelect(this.$refs.dropdown);
+  },
+  template: `
+    <div class="dropdown">
+      <button
+        class="dropdown-menu-toggle js-label-select js-multiselect js-extra-options"
+        type="button"
+        data-toggle="dropdown"
+        data-show-any="true"
+        data-show-no="true"
+        :data-labels="labelPath"
+        ref="dropdown">
+        <span class="dropdown-toggle-text">
+          Label
+        </span>
+        <i class="fa fa-chevron-down"></i>
+      </button>
+      <div class="dropdown-menu dropdown-select dropdown-menu-paging dropdown-menu-labels dropdown-menu-selectable">
+        <div class="dropdown-title">
+          Filter by label
+          <button
+            class="dropdown-title-button dropdown-menu-close"
+            aria-label="Close"
+            type="button">
+            <i class="fa fa-times dropdown-menu-close-icon"></i>
+          </button>
+        </div>
+        <div class="dropdown-input">
+          <input
+            type="search"
+            class="dropdown-input-field"
+            placeholder="Search"
+            autocomplete="off" />
+          <i class="fa fa-search dropdown-input-search"></i>
+          <i role="button" class="fa fa-times dropdown-input-clear js-dropdown-input-clear"></i>
+        </div>
+        <div class="dropdown-content"></div>
+        <div class="dropdown-loading"><i class="fa fa-spinner fa-spin"></i></div>
+      </div>
+    </div>
+  `,
+});
diff --git a/app/assets/javascripts/boards/components/modal/filters/milestone.js.es6 b/app/assets/javascripts/boards/components/modal/filters/milestone.js.es6
new file mode 100644
index 0000000000000000000000000000000000000000..d555599d300684307ddba009165d18ab5edb66fd
--- /dev/null
+++ b/app/assets/javascripts/boards/components/modal/filters/milestone.js.es6
@@ -0,0 +1,55 @@
+/* eslint-disable no-new */
+/* global Vue */
+/* global MilestoneSelect */
+module.exports = Vue.extend({
+  name: 'filter-milestone',
+  props: {
+    milestonePath: {
+      type: String,
+      required: true,
+    },
+  },
+  mounted() {
+    new MilestoneSelect(null, this.$refs.dropdown);
+  },
+  template: `
+    <div class="dropdown">
+      <button
+        class="dropdown-menu-toggle js-milestone-select"
+        type="button"
+        data-toggle="dropdown"
+        data-show-any="true"
+        data-show-upcoming="true"
+        data-field-name="milestone_title"
+        :data-milestones="milestonePath"
+        ref="dropdown">
+        <span class="dropdown-toggle-text">
+          Milestone
+        </span>
+        <i class="fa fa-chevron-down"></i>
+      </button>
+      <div class="dropdown-menu dropdown-select dropdown-menu-selectable dropdown-menu-milestone">
+        <div class="dropdown-title">
+          <span>Filter by milestone</span>
+          <button
+            class="dropdown-title-button dropdown-menu-close"
+            aria-label="Close"
+            type="button">
+            <i class="fa fa-times dropdown-menu-close-icon"></i>
+          </button>
+        </div>
+        <div class="dropdown-input">
+          <input
+            type="search"
+            class="dropdown-input-field"
+            placeholder="Search milestones"
+            autocomplete="off" />
+          <i class="fa fa-search dropdown-input-search"></i>
+          <i role="button" class="fa fa-times dropdown-input-clear js-dropdown-input-clear"></i>
+        </div>
+        <div class="dropdown-content"></div>
+        <div class="dropdown-loading"><i class="fa fa-spinner fa-spin"></i></div>
+      </div>
+    </div>
+  `,
+});
diff --git a/app/assets/javascripts/boards/components/modal/filters/user.js.es6 b/app/assets/javascripts/boards/components/modal/filters/user.js.es6
new file mode 100644
index 0000000000000000000000000000000000000000..8523028c29c11998cbb3d30ef374f9b2bdceded2
--- /dev/null
+++ b/app/assets/javascripts/boards/components/modal/filters/user.js.es6
@@ -0,0 +1,96 @@
+/* eslint-disable no-new */
+/* global Vue */
+/* global UsersSelect */
+module.exports = Vue.extend({
+  name: 'filter-user',
+  props: {
+    toggleClassName: {
+      type: String,
+      required: true,
+    },
+    dropdownClassName: {
+      type: String,
+      required: false,
+      default: '',
+    },
+    toggleLabel: {
+      type: String,
+      required: true,
+    },
+    fieldName: {
+      type: String,
+      required: true,
+    },
+    nullUser: {
+      type: Boolean,
+      required: false,
+      default: false,
+    },
+    projectId: {
+      type: Number,
+      required: true,
+    },
+  },
+  mounted() {
+    new UsersSelect(null, this.$refs.dropdown);
+  },
+  computed: {
+    currentUsername() {
+      return gon.current_username;
+    },
+    dropdownTitle() {
+      return `Filter by ${this.toggleLabel.toLowerCase()}`;
+    },
+    inputPlaceholder() {
+      return `Search ${this.toggleLabel.toLowerCase()}`;
+    },
+  },
+  template: `
+    <div class="dropdown">
+      <button
+        class="dropdown-menu-toggle js-user-search"
+        :class="toggleClassName"
+        type="button"
+        data-toggle="dropdown"
+        data-current-user="true"
+        :data-any-user="'Any ' + toggleLabel"
+        :data-null-user="nullUser"
+        :data-field-name="fieldName"
+        :data-project-id="projectId"
+        :data-first-user="currentUsername"
+        ref="dropdown">
+        <span class="dropdown-toggle-text">
+          {{ toggleLabel }}
+        </span>
+        <i class="fa fa-chevron-down"></i>
+      </button>
+      <div
+        class="dropdown-menu dropdown-select dropdown-menu-user dropdown-menu-selectable"
+        :class="dropdownClassName">
+        <div class="dropdown-title">
+          {{ dropdownTitle }}
+          <button
+            class="dropdown-title-button dropdown-menu-close"
+            aria-label="Close"
+            type="button">
+            <i class="fa fa-times dropdown-menu-close-icon"></i>
+          </button>
+        </div>
+        <div class="dropdown-input">
+          <input
+            type="search"
+            class="dropdown-input-field"
+            autocomplete="off"
+            :placeholder="inputPlaceholder" />
+          <i class="fa fa-search dropdown-input-search"></i>
+          <i
+            role="button"
+            class="fa fa-times dropdown-input-clear js-dropdown-input-clear">
+          </i>
+        </div>
+        <div class="dropdown-content"></div>
+        <div class="dropdown-loading"><i class="fa fa-spinner fa-spin"></i></div>
+      </div>
+    </div>
+  `,
+});
diff --git a/app/assets/javascripts/boards/components/modal/header.js.es6 b/app/assets/javascripts/boards/components/modal/header.js.es6
index ab903722ba4bf38b8121402736f1bcf41eeb3e9a..70c088f905414d195cf9f7be4521cc5ff143ddfd 100644
--- a/app/assets/javascripts/boards/components/modal/header.js.es6
+++ b/app/assets/javascripts/boards/components/modal/header.js.es6
@@ -1,12 +1,26 @@
 /* global Vue */
-
 require('./tabs');
+const modalFilters = require('./filters');
 
 (() => {
   const ModalStore = gl.issueBoards.ModalStore;
 
   gl.issueBoards.ModalHeader = Vue.extend({
     mixins: [gl.issueBoards.ModalMixins],
+    props: {
+      projectId: {
+        type: Number,
+        required: true,
+      },
+      milestonePath: {
+        type: String,
+        required: true,
+      },
+      labelPath: {
+        type: String,
+        required: true,
+      },
+    },
     data() {
       return ModalStore.store;
     },
@@ -31,6 +45,7 @@ require('./tabs');
     },
     components: {
       'modal-tabs': gl.issueBoards.ModalTabs,
+      modalFilters,
     },
     template: `
       <div>
@@ -51,6 +66,11 @@ require('./tabs');
         <div
           class="add-issues-search append-bottom-10"
           v-if="showSearch">
+          <modal-filters
+            :project-id="projectId"
+            :milestone-path="milestonePath"
+            :label-path="labelPath">
+          </modal-filters>
           <input
             placeholder="Search issues..."
             class="form-control"
diff --git a/app/assets/javascripts/boards/components/modal/index.js.es6 b/app/assets/javascripts/boards/components/modal/index.js.es6
index d367b7e42466739741a54feff5a6e4f0f10ee0df..f290cd13763d318268d8ce80d07507eae6832448 100644
--- a/app/assets/javascripts/boards/components/modal/index.js.es6
+++ b/app/assets/javascripts/boards/components/modal/index.js.es6
@@ -27,6 +27,18 @@ require('./empty_state');
         type: String,
         required: true,
       },
+      projectId: {
+        type: Number,
+        required: true,
+      },
+      milestonePath: {
+        type: String,
+        required: true,
+      },
+      labelPath: {
+        type: String,
+        required: true,
+      },
     },
     data() {
       return ModalStore.store;
@@ -52,17 +64,27 @@ require('./empty_state');
           this.issuesCount = false;
         }
       },
+      filter: {
+        handler() {
+          this.loadIssues(true);
+        },
+        deep: true,
+      },
     },
     methods: {
       searchOperation: _.debounce(function searchOperationDebounce() {
         this.loadIssues(true);
       }, 500),
       loadIssues(clearIssues = false) {
-        return gl.boardService.getBacklog({
+        if (!this.showAddIssuesModal) return false;
+
+        const queryData = Object.assign({}, this.filter, {
           search: this.searchTerm,
           page: this.page,
           per: this.perPage,
-        }).then((res) => {
+        });
+
+        return gl.boardService.getBacklog(queryData).then((res) => {
           const data = res.json();
 
           if (clearIssues) {
@@ -112,8 +134,13 @@ require('./empty_state');
         class="add-issues-modal"
         v-if="showAddIssuesModal">
         <div class="add-issues-container">
-          <modal-header></modal-header>
+          <modal-header
+            :project-id="projectId"
+            :milestone-path="milestonePath"
+            :label-path="labelPath">
+          </modal-header>
           <modal-list
+            :image="blankStateImage"
             :issue-link-base="issueLinkBase"
             :root-path="rootPath"
             v-if="!loading && showList"></modal-list>
diff --git a/app/assets/javascripts/boards/components/modal/list.js.es6 b/app/assets/javascripts/boards/components/modal/list.js.es6
index d0901219216e02e880060c107b4f4b06c4217289..3730c1ecaeb2abab384aa55a4fc25df1c4bade78 100644
--- a/app/assets/javascripts/boards/components/modal/list.js.es6
+++ b/app/assets/javascripts/boards/components/modal/list.js.es6
@@ -14,6 +14,10 @@
         type: String,
         required: true,
       },
+      image: {
+        type: String,
+        required: true,
+      },
     },
     data() {
       return ModalStore.store;
@@ -110,6 +114,19 @@
       <section
         class="add-issues-list add-issues-list-columns"
         ref="list">
+        <div
+          class="empty-state add-issues-empty-state-filter text-center"
+          v-if="issuesCount > 0 && issues.length === 0">
+          <div
+            class="svg-content"
+            v-html="image">
+          </div>
+          <div class="text-content">
+            <h4>
+              There are no issues to show.
+            </h4>
+          </div>
+        </div>
         <div
           v-for="group in groupedIssues"
           class="add-issues-list-column">
diff --git a/app/assets/javascripts/boards/stores/modal_store.js.es6 b/app/assets/javascripts/boards/stores/modal_store.js.es6
index 73518b42b8445af678019b5456f777a6173a4d08..15fc6c79e8d3891d744f235542b1c681a46d7f49 100644
--- a/app/assets/javascripts/boards/stores/modal_store.js.es6
+++ b/app/assets/javascripts/boards/stores/modal_store.js.es6
@@ -18,6 +18,17 @@
         page: 1,
         perPage: 50,
       };
+
+      this.setDefaultFilter();
+    }
+
+    setDefaultFilter() {
+      this.store.filter = {
+        author_id: '',
+        assignee_id: '',
+        milestone_title: '',
+        label_name: [],
+      };
     }
 
     selectedCount() {
diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js
index 70dc0d06b7b0311729086436d07782ae20124f9d..e4cf9057e6da7113201d1a7cfd80bd17bff5ca33 100644
--- a/app/assets/javascripts/labels_select.js
+++ b/app/assets/javascripts/labels_select.js
@@ -4,10 +4,17 @@
 
 (function() {
   this.LabelsSelect = (function() {
-    function LabelsSelect() {
-      var _this;
+    function LabelsSelect(els) {
+      var _this, $els;
       _this = this;
-      $('.js-label-select').each(function(i, dropdown) {
+
+      $els = $(els);
+
+      if (!els) {
+        $els = $('.js-label-select');
+      }
+
+      $els.each(function(i, dropdown) {
         var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelHTMLTemplate, labelNoneHTMLTemplate, labelUrl, namespacePath, projectPath, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip, initialSelected, $toggleText, fieldName, useId, propertyName, showMenuAbove, $container, $dropdownContainer;
         $dropdown = $(dropdown);
         $dropdownContainer = $dropdown.closest('.labels-filter');
@@ -324,7 +331,7 @@
           multiSelect: $dropdown.hasClass('js-multiselect'),
           vue: $dropdown.hasClass('js-issue-board-sidebar'),
           clicked: function(label, $el, e, isMarking) {
-            var isIssueIndex, isMRIndex, page;
+            var isIssueIndex, isMRIndex, page, boardsModel;
 
             page = $('body').data('page');
             isIssueIndex = page === 'projects:issues:index';
@@ -346,22 +353,31 @@
               return;
             }
 
-            if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar')) {
+            if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar') &&
+              !$dropdown.closest('.add-issues-modal').length) {
+              boardsModel = gl.issueBoards.BoardsStore.state.filters;
+            } else if ($dropdown.closest('.add-issues-modal').length) {
+              boardsModel = gl.issueBoards.ModalStore.store.filter;
+            }
+
+            if (boardsModel) {
               if (label.isAny) {
-                gl.issueBoards.BoardsStore.state.filters['label_name'] = [];
+                boardsModel['label_name'] = [];
               }
               else if ($el.hasClass('is-active')) {
-                gl.issueBoards.BoardsStore.state.filters['label_name'].push(label.title);
+                boardsModel['label_name'].push(label.title);
               }
               else {
-                var filters = gl.issueBoards.BoardsStore.state.filters['label_name'];
+                var filters = boardsModel['label_name'];
                 filters = filters.filter(function (filteredLabel) {
                   return filteredLabel !== label.title;
                 });
-                gl.issueBoards.BoardsStore.state.filters['label_name'] = filters;
+                boardsModel['label_name'] = filters;
               }
 
-              gl.issueBoards.BoardsStore.updateFiltersUrl();
+              if (!$dropdown.closest('.add-issues-modal').length) {
+                gl.issueBoards.BoardsStore.updateFiltersUrl();
+              }
               e.preventDefault();
               return;
             }
diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js
index 7ab39ffbd05b27149d4b8d9b60ec21d872223f15..2f08aa7fe8bac5ddaa78e98f6351b060ea4f4331 100644
--- a/app/assets/javascripts/milestone_select.js
+++ b/app/assets/javascripts/milestone_select.js
@@ -5,13 +5,20 @@
 
 (function() {
   this.MilestoneSelect = (function() {
-    function MilestoneSelect(currentProject) {
-      var _this;
+    function MilestoneSelect(currentProject, els) {
+      var _this, $els;
       if (currentProject != null) {
         _this = this;
         this.currentProject = JSON.parse(currentProject);
       }
-      $('.js-milestone-select').each(function(i, dropdown) {
+
+      $els = $(els);
+
+      if (!els) {
+        $els = $('.js-milestone-select');
+      }
+
+      $els.each(function(i, dropdown) {
         var $block, $dropdown, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, collapsedSidebarLabelTemplate, defaultLabel, issuableId, issueUpdateURL, milestoneLinkNoneTemplate, milestoneLinkTemplate, milestonesUrl, projectId, selectedMilestone, showAny, showNo, showUpcoming, useId, showMenuAbove;
         $dropdown = $(dropdown);
         projectId = $dropdown.data('project-id');
@@ -108,7 +115,7 @@
           },
           vue: $dropdown.hasClass('js-issue-board-sidebar'),
           clicked: function(selected, $el, e) {
-            var data, isIssueIndex, isMRIndex, page;
+            var data, isIssueIndex, isMRIndex, page, boardsStore;
             page = $('body').data('page');
             isIssueIndex = page === 'projects:issues:index';
             isMRIndex = (page === page && page === 'projects:merge_requests:index');
@@ -116,9 +123,19 @@
               e.preventDefault();
               return;
             }
-            if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar')) {
-              gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = selected.name;
-              gl.issueBoards.BoardsStore.updateFiltersUrl();
+
+            if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar') &&
+              !$dropdown.closest('.add-issues-modal').length) {
+              boardsStore = gl.issueBoards.BoardsStore.state.filters;
+            } else if ($dropdown.closest('.add-issues-modal').length) {
+              boardsStore = gl.issueBoards.ModalStore.store.filter;
+            }
+
+            if (boardsStore) {
+              boardsStore[$dropdown.data('field-name')] = selected.name;
+              if (!$dropdown.closest('.add-issues-modal').length) {
+                gl.issueBoards.BoardsStore.updateFiltersUrl();
+              }
               e.preventDefault();
             } else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
               if (selected.name != null) {
diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js
index 77d2764cdf0077121b704a86f001e4848a474074..d4b24d132995cf7a2a0a2e8edb98313f865ca757 100644
--- a/app/assets/javascripts/users_select.js
+++ b/app/assets/javascripts/users_select.js
@@ -8,7 +8,8 @@
     slice = [].slice;
 
   this.UsersSelect = (function() {
-    function UsersSelect(currentUser) {
+    function UsersSelect(currentUser, els) {
+      var $els;
       this.users = bind(this.users, this);
       this.user = bind(this.user, this);
       this.usersPath = "/autocomplete/users.json";
@@ -20,7 +21,14 @@
           this.currentUser = JSON.parse(currentUser);
         }
       }
-      $('.js-user-search').each((function(_this) {
+
+      $els = $(els);
+
+      if (!els) {
+        $els = $('.js-user-search');
+      }
+
+      $els.each((function(_this) {
         return function(i, dropdown) {
           var options = {};
           var $block, $collapsedSidebar, $dropdown, $loading, $selectbox, $value, abilityName, assignTo, assigneeTemplate, collapsedAssigneeTemplate, defaultLabel, firstUser, issueURL, selectedId, showAnyUser, showNullUser, showMenuAbove;
@@ -193,7 +201,9 @@
                 selectedId = user.id;
                 return;
               }
-              if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar')) {
+              if ($el.closest('.add-issues-modal').length) {
+                gl.issueBoards.ModalStore.store.filter[$dropdown.data('field-name')] = user.id;
+              } else if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar')) {
                 selectedId = user.id;
                 gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = user.id;
                 gl.issueBoards.BoardsStore.updateFiltersUrl();
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index 9b413f3e61c7741ea1b8afcc2e71c27112e1158c..b362cc758ccab9a0d956db8623ff7b79b5b4b4d9 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -389,6 +389,13 @@
     flex: 1;
     margin-top: 0;
 
+    &.add-issues-empty-state-filter {
+      -webkit-flex-direction: column;
+      flex-direction: column;
+      -webkit-justify-content: center;
+      justify-content: center;
+    }
+
     > .row {
       width: 100%;
       margin: auto 0;
@@ -416,6 +423,14 @@
 .add-issues-search {
   display: -webkit-flex;
   display: flex;
+
+  .form-control {
+    margin-left: auto;
+
+    @media (min-width: $screen-sm-min) {
+      max-width: 200px;
+    }
+  }
 }
 
 .add-issues-list-column {
@@ -486,3 +501,24 @@
   line-height: 15px;
   border-radius: 50%;
 }
+
+.modal-filters {
+  display: flex;
+
+  > .dropdown {
+    display: none;
+    margin-right: 10px;
+
+    @media (min-width: $screen-sm-min) {
+      display: block;
+    }
+  }
+
+  .dropdown-menu-toggle {
+    width: 100px;
+
+    @media (min-width: $screen-md-min) {
+      width: 140px;
+    }
+  }
+}
diff --git a/app/views/projects/boards/_show.html.haml b/app/views/projects/boards/_show.html.haml
index f0c76af29dc4a11637fb569ff4f96def6c3d76a8..05fe504d1c9f7da53b41484522d4f424ce86d481 100644
--- a/app/views/projects/boards/_show.html.haml
+++ b/app/views/projects/boards/_show.html.haml
@@ -29,5 +29,8 @@
   = render "projects/boards/components/sidebar"
   %board-add-issues-modal{ "blank-state-image" => render('shared/empty_states/icons/issues.svg'),
     "new-issue-path" => new_namespace_project_issue_path(@project.namespace, @project),
+    "milestone-path" => milestones_filter_dropdown_path,
+    "label-path" => labels_filter_path,
     ":issue-link-base" => "issueLinkBase",
-    ":root-path" => "rootPath" }
+    ":root-path" => "rootPath",
+    ":project-id" => @project.try(:id) }
diff --git a/spec/features/boards/modal_filter_spec.rb b/spec/features/boards/modal_filter_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1cf0d11d4480a73a9cacf56cfccc6d93fccefb18
--- /dev/null
+++ b/spec/features/boards/modal_filter_spec.rb
@@ -0,0 +1,259 @@
+require 'rails_helper'
+
+describe 'Issue Boards add issue modal filtering', :feature, :js do
+  include WaitForAjax
+  include WaitForVueResource
+
+  let(:project) { create(:empty_project, :public) }
+  let(:board) { create(:board, project: project) }
+  let(:planning) { create(:label, project: project, name: 'Planning') }
+  let!(:list1) { create(:list, board: board, label: planning, position: 0) }
+  let(:user) { create(:user) }
+  let(:user2) { create(:user) }
+  let!(:issue1) { create(:issue, project: project) }
+
+  before do
+    project.team << [user, :master]
+
+    login_as(user)
+  end
+
+  it 'shows empty state when no results found' do
+    visit_board
+
+    page.within('.add-issues-modal') do
+      find('.form-control').native.send_keys('testing empty state')
+
+      wait_for_vue_resource
+
+      expect(page).to have_content('There are no issues to show.')
+    end
+  end
+
+  it 'restores filters when closing' do
+    visit_board
+
+    page.within('.add-issues-modal') do
+      click_button 'Milestone'
+
+      wait_for_ajax
+
+      click_link 'Upcoming'
+
+      wait_for_vue_resource
+
+      expect(page).to have_selector('.card', count: 0)
+
+      click_button 'Cancel'
+    end
+
+    click_button('Add issues')
+
+    page.within('.add-issues-modal') do
+      wait_for_vue_resource
+
+      expect(page).to have_selector('.card', count: 1)
+    end
+  end
+
+  context 'author' do
+    let!(:issue) { create(:issue, project: project, author: user2) }
+
+    before do
+      project.team << [user2, :developer]
+
+      visit_board
+    end
+
+    it 'filters by any author' do
+      page.within('.add-issues-modal') do
+        click_button 'Author'
+
+        wait_for_ajax
+
+        click_link 'Any Author'
+
+        wait_for_vue_resource
+
+        expect(page).to have_selector('.card', count: 2)
+      end
+    end
+
+    it 'filters by selected user' do
+      page.within('.add-issues-modal') do
+        click_button 'Author'
+
+        wait_for_ajax
+
+        click_link user2.name
+
+        wait_for_vue_resource
+
+        expect(page).to have_selector('.card', count: 1)
+      end
+    end
+  end
+
+  context 'assignee' do
+    let!(:issue) { create(:issue, project: project, assignee: user2) }
+
+    before do
+      project.team << [user2, :developer]
+
+      visit_board
+    end
+
+    it 'filters by any assignee' do
+      page.within('.add-issues-modal') do
+        click_button 'Assignee'
+
+        wait_for_ajax
+
+        click_link 'Any Assignee'
+
+        wait_for_vue_resource
+
+        expect(page).to have_selector('.card', count: 2)
+      end
+    end
+
+    it 'filters by unassigned' do
+      page.within('.add-issues-modal') do
+        click_button 'Assignee'
+
+        wait_for_ajax
+
+        click_link 'Unassigned'
+
+        wait_for_vue_resource
+
+        expect(page).to have_selector('.card', count: 1)
+      end
+    end
+
+    it 'filters by selected user' do
+      page.within('.add-issues-modal') do
+        click_button 'Assignee'
+
+        wait_for_ajax
+
+        page.within '.dropdown-menu-user' do
+          click_link user2.name
+        end
+
+        wait_for_vue_resource
+
+        expect(page).to have_selector('.card', count: 1)
+      end
+    end
+  end
+
+  context 'milestone' do
+    let(:milestone) { create(:milestone, project: project) }
+    let!(:issue) { create(:issue, project: project, milestone: milestone) }
+
+    before do
+      visit_board
+    end
+
+    it 'filters by any milestone' do
+      page.within('.add-issues-modal') do
+        click_button 'Milestone'
+
+        wait_for_ajax
+
+        click_link 'Any Milestone'
+
+        wait_for_vue_resource
+
+        expect(page).to have_selector('.card', count: 2)
+      end
+    end
+
+    it 'filters by upcoming milestone' do
+      page.within('.add-issues-modal') do
+        click_button 'Milestone'
+
+        wait_for_ajax
+
+        click_link 'Upcoming'
+
+        wait_for_vue_resource
+
+        expect(page).to have_selector('.card', count: 0)
+      end
+    end
+
+    it 'filters by selected milestone' do
+      page.within('.add-issues-modal') do
+        click_button 'Milestone'
+
+        wait_for_ajax
+
+        click_link milestone.name
+
+        wait_for_vue_resource
+
+        expect(page).to have_selector('.card', count: 1)
+      end
+    end
+  end
+
+  context 'label' do
+    let(:label) { create(:label, project: project) }
+    let!(:issue) { create(:labeled_issue, project: project, labels: [label]) }
+
+    before do
+      visit_board
+    end
+
+    it 'filters by any label' do
+      page.within('.add-issues-modal') do
+        click_button 'Label'
+
+        wait_for_ajax
+
+        click_link 'Any Label'
+
+        wait_for_vue_resource
+
+        expect(page).to have_selector('.card', count: 2)
+      end
+    end
+
+    it 'filters by no label' do
+      page.within('.add-issues-modal') do
+        click_button 'Label'
+
+        wait_for_ajax
+
+        click_link 'No Label'
+
+        wait_for_vue_resource
+
+        expect(page).to have_selector('.card', count: 1)
+      end
+    end
+
+    it 'filters by label' do
+      page.within('.add-issues-modal') do
+        click_button 'Label'
+
+        wait_for_ajax
+
+        click_link label.title
+
+        wait_for_vue_resource
+
+        expect(page).to have_selector('.card', count: 1)
+      end
+    end
+  end
+
+  def visit_board
+    visit namespace_project_board_path(project.namespace, project, board)
+    wait_for_vue_resource
+
+    click_button('Add issues')
+  end
+end