diff --git a/app/assets/javascripts/pages/dashboard/merge_requests/index.js b/app/assets/javascripts/pages/dashboard/merge_requests/index.js
index 1350837476b8ef8e7061e2489cf12b48b228ecb4..f86dc2e2e3054583e3f4498fbad4dfbe7798179c 100644
--- a/app/assets/javascripts/pages/dashboard/merge_requests/index.js
+++ b/app/assets/javascripts/pages/dashboard/merge_requests/index.js
@@ -3,6 +3,9 @@ import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered
 import { FILTERED_SEARCH } from '~/filtered_search/constants';
 import initFilteredSearch from '~/pages/search/init_filtered_search';
 import projectSelect from '~/project_select';
+import { initNewResourceDropdown } from '~/vue_shared/components/new_resource_dropdown/init_new_resource_dropdown';
+import { RESOURCE_TYPE_MERGE_REQUEST } from '~/vue_shared/components/new_resource_dropdown/constants';
+import searchUserProjectsWithMergeRequestsEnabled from '~/vue_shared/components/new_resource_dropdown/graphql/search_user_projects_with_merge_requests_enabled.query.graphql';
 
 addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys, true);
 
@@ -13,3 +16,7 @@ initFilteredSearch({
 });
 
 projectSelect();
+initNewResourceDropdown({
+  resourceType: RESOURCE_TYPE_MERGE_REQUEST,
+  query: searchUserProjectsWithMergeRequestsEnabled,
+});
diff --git a/app/assets/javascripts/pages/dashboard/milestones/index/index.js b/app/assets/javascripts/pages/dashboard/milestones/index/index.js
index b526fce6f7bd35ee7fe05490397dda78918f4d46..951941cc83de55a000d0444d55d881484df915b0 100644
--- a/app/assets/javascripts/pages/dashboard/milestones/index/index.js
+++ b/app/assets/javascripts/pages/dashboard/milestones/index/index.js
@@ -1,3 +1,14 @@
 import projectSelect from '~/project_select';
+import { initNewResourceDropdown } from '~/vue_shared/components/new_resource_dropdown/init_new_resource_dropdown';
+import { RESOURCE_TYPE_MILESTONE } from '~/vue_shared/components/new_resource_dropdown/constants';
+import searchUserGroupsAndProjects from '~/vue_shared/components/new_resource_dropdown/graphql/search_user_groups_and_projects.query.graphql';
 
 projectSelect();
+initNewResourceDropdown({
+  resourceType: RESOURCE_TYPE_MILESTONE,
+  query: searchUserGroupsAndProjects,
+  extractProjects: (data) => [
+    ...(data?.user?.groups?.nodes ?? []),
+    ...(data?.projects?.nodes ?? []),
+  ],
+});
diff --git a/app/assets/javascripts/pages/groups/merge_requests/index.js b/app/assets/javascripts/pages/groups/merge_requests/index.js
index bf0147ca8853dfe2562090b4cb4a20864441abef..40b4c289ab0d491012d1c01ddac3e4dbe99c062d 100644
--- a/app/assets/javascripts/pages/groups/merge_requests/index.js
+++ b/app/assets/javascripts/pages/groups/merge_requests/index.js
@@ -4,6 +4,9 @@ import { FILTERED_SEARCH } from '~/filtered_search/constants';
 import { initBulkUpdateSidebar } from '~/issuable';
 import initFilteredSearch from '~/pages/search/init_filtered_search';
 import projectSelect from '~/project_select';
+import { initNewResourceDropdown } from '~/vue_shared/components/new_resource_dropdown/init_new_resource_dropdown';
+import { RESOURCE_TYPE_MERGE_REQUEST } from '~/vue_shared/components/new_resource_dropdown/constants';
+import searchUserGroupProjectsWithMergeRequestsEnabled from '~/vue_shared/components/new_resource_dropdown/graphql/search_user_group_projects_with_merge_requests_enabled.query.graphql';
 
 const ISSUABLE_BULK_UPDATE_PREFIX = 'merge_request_';
 
@@ -17,3 +20,8 @@ initFilteredSearch({
   filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
 });
 projectSelect();
+initNewResourceDropdown({
+  resourceType: RESOURCE_TYPE_MERGE_REQUEST,
+  query: searchUserGroupProjectsWithMergeRequestsEnabled,
+  extractProjects: (data) => data?.group?.projects?.nodes,
+});
diff --git a/app/assets/javascripts/vue_shared/components/new_resource_dropdown/graphql/search_user_group_projects_with_merge_requests_enabled.query.graphql b/app/assets/javascripts/vue_shared/components/new_resource_dropdown/graphql/search_user_group_projects_with_merge_requests_enabled.query.graphql
new file mode 100644
index 0000000000000000000000000000000000000000..578914dbbaf2301e4a39882fca8240cc49144d6f
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/new_resource_dropdown/graphql/search_user_group_projects_with_merge_requests_enabled.query.graphql
@@ -0,0 +1,18 @@
+query searchUserGroupProjectsWithMergeRequestsEnabled($fullPath: ID!, $search: String) {
+  group(fullPath: $fullPath) {
+    id
+    projects(
+      search: $search
+      withMergeRequestsEnabled: true
+      includeSubgroups: true
+      sort: ACTIVITY_DESC
+    ) {
+      nodes {
+        id
+        name
+        nameWithNamespace
+        webUrl
+      }
+    }
+  }
+}
diff --git a/app/assets/javascripts/vue_shared/components/new_resource_dropdown/graphql/search_user_groups_and_projects.query.graphql b/app/assets/javascripts/vue_shared/components/new_resource_dropdown/graphql/search_user_groups_and_projects.query.graphql
new file mode 100644
index 0000000000000000000000000000000000000000..8fe92cf7c6cc0e7740260c073762e6f2ddba4a1a
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/new_resource_dropdown/graphql/search_user_groups_and_projects.query.graphql
@@ -0,0 +1,21 @@
+query searchUserGroupsAndProjects($username: String!, $search: String) {
+  projects(sort: "latest_activity_desc", membership: true) {
+    nodes {
+      id
+      name
+      nameWithNamespace
+      webUrl
+    }
+  }
+
+  user(username: $username) {
+    id
+    groups(search: $search) {
+      nodes {
+        id
+        name
+        webUrl
+      }
+    }
+  }
+}
diff --git a/app/assets/javascripts/vue_shared/components/new_resource_dropdown/graphql/search_user_projects_with_merge_requests_enabled.query.graphql b/app/assets/javascripts/vue_shared/components/new_resource_dropdown/graphql/search_user_projects_with_merge_requests_enabled.query.graphql
new file mode 100644
index 0000000000000000000000000000000000000000..44ebf755728bf0e32b80d5e95a4bda49d3744bb1
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/new_resource_dropdown/graphql/search_user_projects_with_merge_requests_enabled.query.graphql
@@ -0,0 +1,15 @@
+query searchUserProjectsWithMergeRequestsEnabled($search: String) {
+  projects(
+    search: $search
+    membership: true
+    withMergeRequestsEnabled: true
+    sort: "latest_activity_desc"
+  ) {
+    nodes {
+      id
+      name
+      nameWithNamespace
+      webUrl
+    }
+  }
+}
diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml
index 97fb35b28ab0cac8b3d1cf415b3a6aa953ecde0b..677e2bd60077d70d2b86c1fb3e3835a0d5336a66 100644
--- a/app/views/dashboard/merge_requests.html.haml
+++ b/app/views/dashboard/merge_requests.html.haml
@@ -10,7 +10,7 @@
 
   - if current_user
     .page-title-controls.ml-0.mb-3.ml-sm-auto.mb-sm-0
-      = render 'shared/new_project_item_select', path: 'merge_requests/new', label: _("merge request"), with_feature_enabled: 'merge_requests', type: :merge_requests
+      = render 'shared/new_project_item_vue_select'
 
 .top-area
   = render 'shared/issuable/nav', type: :merge_requests, display_count: !@no_filters_set
diff --git a/app/views/dashboard/milestones/index.html.haml b/app/views/dashboard/milestones/index.html.haml
index bc8e3e6ab69efb3862c5f888975737190bd3ba9b..2556791da12fec755317ed3871750860656b0cb2 100644
--- a/app/views/dashboard/milestones/index.html.haml
+++ b/app/views/dashboard/milestones/index.html.haml
@@ -8,9 +8,7 @@
 
   - if current_user
     .page-title-controls
-      = render 'shared/new_project_item_select',
-        path: '-/milestones/new', label: _('Milestone'),
-        include_groups: true, type: :milestones
+      = render 'shared/new_project_item_vue_select'
 
 - if @milestone_states.any? { |name, count| count > 0 }
   .top-area
@@ -22,9 +20,7 @@
     = render 'shared/empty_states/milestones_tab', active_tab: params[:state] do
       - if current_user
         .page-title-controls
-          = render 'shared/new_project_item_select',
-            path: '-/milestones/new', label: _('Milestone'),
-            include_groups: true, type: :milestones
+          = render 'shared/new_project_item_vue_select'
   - else
     .milestones
       %ul.content-list
@@ -35,6 +31,4 @@
   = render 'shared/empty_states/milestones' do
     - if current_user
       .page-title-controls
-        = render 'shared/new_project_item_select',
-          path: '-/milestones/new', label: _('Milestone'),
-          include_groups: true, type: :milestones
+        = render 'shared/new_project_item_vue_select'
diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml
index 92f6c896e7b791fee22271e7d9d1bbec1af20ad0..f2d0cfc42fd62027ecfb588ca512e2bd2b99b1db 100644
--- a/app/views/groups/merge_requests.html.haml
+++ b/app/views/groups/merge_requests.html.haml
@@ -10,7 +10,7 @@
       - if @can_bulk_update
         = render_if_exists 'projects/merge_requests/bulk_update_button'
 
-      = render 'shared/new_project_item_select', path: 'merge_requests/new', label: _("merge request"), type: :merge_requests, with_feature_enabled: 'merge_requests', with_shared: false, include_projects_in_subgroups: true
+      = render 'shared/new_project_item_vue_select'
 
 = render 'shared/issuable/search_bar', type: :merge_requests
 - if @can_bulk_update
diff --git a/app/views/shared/_new_project_item_vue_select.html.haml b/app/views/shared/_new_project_item_vue_select.html.haml
index 24d275c4975e775cc1564635a9a21dda8d4dae35..9ea99df106e9d0888b45190afab700a19e8eadc7 100644
--- a/app/views/shared/_new_project_item_vue_select.html.haml
+++ b/app/views/shared/_new_project_item_vue_select.html.haml
@@ -1,2 +1,2 @@
 - if any_projects?(@projects)
-  .js-new-resource-dropdown
+  .js-new-resource-dropdown{ data: { group_id: @group&.id, full_path: @group&.full_path, username: @current_user&.username } }
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
index a146a6987bc99674b25a2d7f97d1e5d74f32cbae..34bab9dffd0cfaf9a287dcc54f288272d55f392d 100644
--- a/spec/features/dashboard/merge_requests_spec.rb
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -36,11 +36,16 @@
     end
 
     it 'shows projects only with merge requests feature enabled', :js do
-      click_button 'Toggle project select'
+      click_button 'Select project to create merge request'
+      wait_for_requests
 
-      page.within('.select2-results') do
+      page.within('[data-testid="new-resource-dropdown"]') do
         expect(page).to have_content(project.full_name)
         expect(page).not_to have_content(project_with_disabled_merge_requests.full_name)
+
+        find_button(project.full_name).click
+
+        expect(page).to have_link("New merge request in #{project.name}")
       end
     end
   end
diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb
index a9f23f90bb1407e70d32edd04c2d07b8a1bb8946..3b197bbf009d73b2b9ff75cf58ca6b3315c8d46c 100644
--- a/spec/features/dashboard/milestones_spec.rb
+++ b/spec/features/dashboard/milestones_spec.rb
@@ -37,19 +37,13 @@
 
     describe 'new milestones dropdown', :js do
       it 'takes user to a new milestone page', :js do
-        click_button 'Toggle project select'
+        click_button 'Select project to create milestone'
 
-        page.within('.select2-results') do
-          first('.select2-result-label').click
+        page.within('[data-testid="new-resource-dropdown"]') do
+          click_button group.name
+          click_link "New milestone in #{group.name}"
         end
 
-        a_el = find('.js-new-project-item-link')
-
-        expect(a_el).to have_content('New Milestone in ')
-        expect(a_el).to have_no_content('New New Milestone in ')
-
-        a_el.click
-
         expect(page).to have_current_path(new_group_milestone_path(group), ignore_query: true)
       end
     end
diff --git a/spec/features/groups/empty_states_spec.rb b/spec/features/groups/empty_states_spec.rb
index a37c40f50e02b4fa77bc65c7e4bc66c240d8028f..e123e223ae5fabb29d17fb6f9344127343663e2d 100644
--- a/spec/features/groups/empty_states_spec.rb
+++ b/spec/features/groups/empty_states_spec.rb
@@ -98,13 +98,9 @@
           end
 
           it "the new #{issuable_name} button opens a project dropdown" do
-            click_button 'Toggle project select'
+            click_button "Select project to create #{issuable_name}"
 
-            if issuable == :issue
-              expect(page).to have_button project.name
-            else
-              expect(page).to have_selector('.ajax-project-dropdown')
-            end
+            expect(page).to have_button project.name
           end
         end
       end
diff --git a/spec/features/groups/merge_requests_spec.rb b/spec/features/groups/merge_requests_spec.rb
index 8a3401d05720d37d8de2eb2e7dca85ac490e7c05..bbb7d322b9a3ea3db504d7e0d9fae8ceaf6631fc 100644
--- a/spec/features/groups/merge_requests_spec.rb
+++ b/spec/features/groups/merge_requests_spec.rb
@@ -77,9 +77,9 @@
     end
 
     it 'shows projects only with merge requests feature enabled', :js do
-      find('.js-new-project-item-link').click
+      click_button 'Select project to create merge request'
 
-      page.within('.select2-results') do
+      page.within('[data-testid="new-resource-dropdown"]') do
         expect(page).to have_content(project.name_with_namespace)
         expect(page).not_to have_content(project_with_merge_requests_disabled.name_with_namespace)
       end
@@ -95,7 +95,7 @@
       visit path
 
       expect(page).to have_selector('.empty-state')
-      expect(page).to have_link('Select project to create merge request')
+      expect(page).to have_button('Select project to create merge request')
       expect(page).to have_selector('.issues-filters')
     end
 
@@ -105,7 +105,7 @@
         visit path
 
         expect(page).to have_selector('.empty-state')
-        expect(page).to have_link('Select project to create merge request')
+        expect(page).to have_button('Select project to create merge request')
         expect(page).to have_selector('.issues-filters')
       end
     end