diff --git a/config/application.rb b/config/application.rb
index a1ed5fbd58aafae442593f41c30ad0ee7d69a33b..a9008e387cfa65b8ad319301272c4e444134730c 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -268,6 +268,7 @@ class Application < Rails::Application
     config.assets.precompile << "page_bundles/branches.css"
     config.assets.precompile << "page_bundles/build.css"
     config.assets.precompile << "page_bundles/ci_status.css"
+    config.assets.precompile << "page_bundles/ci_cd_settings.css"
     config.assets.precompile << "page_bundles/cluster_agents.css"
     config.assets.precompile << "page_bundles/clusters.css"
     config.assets.precompile << "page_bundles/cycle_analytics.css"
diff --git a/ee/app/assets/javascripts/protected_environments/add_approvers.vue b/ee/app/assets/javascripts/protected_environments/add_approvers.vue
new file mode 100644
index 0000000000000000000000000000000000000000..7f972fc7f22f91f2d7f99ec5ef3e76abc8237654
--- /dev/null
+++ b/ee/app/assets/javascripts/protected_environments/add_approvers.vue
@@ -0,0 +1,206 @@
+<script>
+import { GlFormGroup, GlCollapse, GlAvatar, GlLink, GlFormInput } from '@gitlab/ui';
+import * as Sentry from '@sentry/browser';
+import { uniqueId } from 'lodash';
+import Api from 'ee/api';
+import { getUser } from '~/rest_api';
+import { s__ } from '~/locale';
+import AccessDropdown from '~/projects/settings/components/access_dropdown.vue';
+import { ACCESS_LEVELS } from './constants';
+
+const mapUserToApprover = (user) => ({
+  name: user.name,
+  entityName: user.name,
+  webUrl: user.web_url,
+  avatarUrl: user.avatar_url,
+  id: user.id,
+  avatarShape: 'circle',
+  approvals: 1,
+  inputDisabled: true,
+  type: 'user',
+});
+
+const mapGroupToApprover = (group) => ({
+  name: group.full_name,
+  entityName: group.name,
+  webUrl: group.web_url,
+  avatarUrl: group.avatar_url,
+  id: group.id,
+  avatarShape: 'rect',
+  approvals: 1,
+  type: 'group',
+});
+
+const MIN_APPROVALS_COUNT = 1;
+
+const MAX_APPROVALS_COUNT = 5;
+
+export default {
+  ACCESS_LEVELS,
+  components: {
+    GlFormGroup,
+    GlCollapse,
+    GlAvatar,
+    GlLink,
+    GlFormInput,
+    AccessDropdown,
+  },
+  inject: { accessLevelsData: { default: [] } },
+  props: {
+    disabled: {
+      type: Boolean,
+      required: false,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      approvers: [],
+      approverInfo: [],
+      uniqueId: uniqueId('deployment-approvers-'),
+    };
+  },
+  computed: {
+    approvalRules() {
+      return this.approverInfo.map((info) => {
+        switch (info.type) {
+          case 'user':
+            return { user_id: info.id, required_approvals: info.approvals };
+          case 'group':
+            return { group_id: info.id, required_approvals: info.approvals };
+          case 'access':
+            return { access_level: info.accessLevel, required_approvals: info.approvals };
+          default:
+            return {};
+        }
+      });
+    },
+    hasSelectedApprovers() {
+      return Boolean(this.approvers.length);
+    },
+  },
+  watch: {
+    async approvers() {
+      try {
+        this.$emit('error', '');
+        this.approverInfo = await Promise.all(
+          this.approvers.map((approver) => {
+            if (approver.user_id) {
+              return getUser(approver.user_id).then(({ data }) => mapUserToApprover(data));
+            }
+
+            if (approver.group_id) {
+              return Api.group(approver.group_id).then(mapGroupToApprover);
+            }
+
+            return Promise.resolve({
+              accessLevel: approver.access_level,
+              name: this.accessLevelsData.find(({ id }) => id === approver.access_level).text,
+              approvals: 1,
+              type: 'access',
+            });
+          }),
+        );
+      } catch (e) {
+        Sentry.captureException(e);
+        this.$emit(
+          'error',
+          s__(
+            'ProtectedEnvironments|An error occurred while fetching information on the selected approvers.',
+          ),
+        );
+      }
+    },
+    approvalRules() {
+      this.$emit('change', this.approvalRules);
+    },
+  },
+  methods: {
+    updateApprovers(permissions) {
+      this.approvers = permissions;
+    },
+    isApprovalValid(approvals) {
+      const count = parseFloat(approvals);
+      return count >= MIN_APPROVALS_COUNT && count <= MAX_APPROVALS_COUNT;
+    },
+    approvalsId(index) {
+      return `${this.uniqueId}-${index}`;
+    },
+  },
+  i18n: {
+    approverLabel: s__('ProtectedEnvironment|Approvers'),
+    approverHelp: s__(
+      'ProtectedEnvironments|Set which groups, access levels or users are required to approve.',
+    ),
+    approvalRulesLabel: s__('ProtectedEnvironments|Approval rules'),
+    approvalsInvalid: s__('ProtectedEnvironments|Number of approvals must be between 1 and 5'),
+  },
+};
+</script>
+<template>
+  <div>
+    <gl-form-group
+      data-testid="create-approver-dropdown"
+      label-for="create-approver-dropdown"
+      :label="$options.i18n.approverLabel"
+    >
+      <template #label-description>
+        {{ $options.i18n.approverHelp }}
+      </template>
+      <access-dropdown
+        id="create-approver-dropdown"
+        :access-levels-data="accessLevelsData"
+        :access-level="$options.ACCESS_LEVELS.DEPLOY"
+        :disabled="disabled"
+        :preselected-items="approvers"
+        @hidden="updateApprovers"
+      />
+    </gl-form-group>
+    <gl-collapse :visible="hasSelectedApprovers">
+      <span class="gl-font-weight-bold">{{ $options.i18n.approvalRulesLabel }}</span>
+      <div
+        data-testid="approval-rules"
+        class="protected-environment-approvers gl-display-grid gl-gap-5 gl-align-items-center"
+      >
+        <span class="protected-environment-approvers-label">{{ __('Approvers') }}</span>
+        <span>{{ __('Approvals required') }}</span>
+        <template v-for="(approver, index) in approverInfo">
+          <gl-avatar
+            v-if="approver.avatarShape"
+            :key="`${index}-avatar`"
+            :src="approver.avatarUrl"
+            :size="24"
+            :entity-id="approver.id"
+            :entity-name="approver.entityName"
+            :shape="approver.avatarShape"
+          />
+          <span v-else :key="`${index}-avatar`" class="gl-w-6"></span>
+          <gl-link v-if="approver.webUrl" :key="`${index}-name`" :href="approver.webUrl">
+            {{ approver.name }}
+          </gl-link>
+          <span v-else :key="`${index}-name`">{{ approver.name }}</span>
+
+          <gl-form-group
+            :key="`${index}-approvals`"
+            :state="isApprovalValid(approver.approvals)"
+            :label="$options.i18n.approverLabel"
+            :label-for="approvalsId(index)"
+            label-sr-only
+          >
+            <gl-form-input
+              :id="approvalsId(index)"
+              v-model="approver.approvals"
+              :disabled="approver.inputDisabled"
+              :state="isApprovalValid(approver.approvals)"
+              :name="`approval-count-${approver.name}`"
+              type="number"
+            />
+            <template #invalid-feedback>
+              {{ $options.i18n.approvalsInvalid }}
+            </template>
+          </gl-form-group>
+        </template>
+      </div>
+    </gl-collapse>
+  </div>
+</template>
diff --git a/ee/app/assets/javascripts/protected_environments/create_protected_environment.vue b/ee/app/assets/javascripts/protected_environments/create_protected_environment.vue
index 84fb738e83c444a6bdb3c5ca76aa15f15f296713..4a2732b606907e38a5016a8d2de1876eb6f75fdd 100644
--- a/ee/app/assets/javascripts/protected_environments/create_protected_environment.vue
+++ b/ee/app/assets/javascripts/protected_environments/create_protected_environment.vue
@@ -6,61 +6,31 @@ import {
   GlFormGroup,
   GlCollapse,
   GlCollapsibleListbox,
-  GlAvatar,
   GlLink,
-  GlFormInput,
   GlSprintf,
 } from '@gitlab/ui';
 import * as Sentry from '@sentry/browser';
 import Api from 'ee/api';
-import { getUser } from '~/rest_api';
 import axios from '~/lib/utils/axios_utils';
 import { __, s__ } from '~/locale';
 import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
 import AccessDropdown from '~/projects/settings/components/access_dropdown.vue';
+import AddApprovers from './add_approvers.vue';
 import { ACCESS_LEVELS } from './constants';
 
-const mapUserToApprover = (user) => ({
-  name: user.name,
-  entityName: user.name,
-  webUrl: user.web_url,
-  avatarUrl: user.avatar_url,
-  id: user.id,
-  avatarShape: 'circle',
-  approvals: 1,
-  inputDisabled: true,
-  type: 'user',
-});
-
-const mapGroupToApprover = (group) => ({
-  name: group.full_name,
-  entityName: group.name,
-  webUrl: group.web_url,
-  avatarUrl: group.avatar_url,
-  id: group.id,
-  avatarShape: 'rect',
-  approvals: 1,
-  type: 'group',
-});
-
-const MIN_APPROVALS_COUNT = 1;
-
-const MAX_APPROVALS_COUNT = 5;
-
 export default {
   ACCESS_LEVELS,
   components: {
     GlAlert,
-    GlAvatar,
     GlButton,
     GlCard,
     GlCollapse,
     GlFormGroup,
     GlCollapsibleListbox,
     GlLink,
-    GlFormInput,
     GlSprintf,
     AccessDropdown,
+    AddApprovers,
   },
   mixins: [glFeatureFlagsMixin()],
   inject: { accessLevelsData: { default: [] }, apiLink: {}, docsLink: {} },
@@ -84,7 +54,6 @@ export default {
       environments: [],
       environmentsLoading: false,
       errorMessage: '',
-      approverInfo: [],
       alertDismissed: false,
     };
   },
@@ -101,53 +70,6 @@ export default {
     hasSelectedEnvironment() {
       return Boolean(this.environment);
     },
-    hasSelectedApprovers() {
-      return Boolean(this.approvers.length);
-    },
-    approvalRules() {
-      return this.approverInfo.map((info) => {
-        switch (info.type) {
-          case 'user':
-            return { user_id: info.id, required_approvals: info.approvals };
-          case 'group':
-            return { group_id: info.id, required_approvals: info.approvals };
-          case 'access':
-            return { access_level: info.accessLevel, required_approvals: info.approvals };
-          default:
-            return {};
-        }
-      });
-    },
-  },
-  watch: {
-    async approvers() {
-      try {
-        this.errorMessage = '';
-        this.approverInfo = await Promise.all(
-          this.approvers.map((approver) => {
-            if (approver.user_id) {
-              return getUser(approver.user_id).then(({ data }) => mapUserToApprover(data));
-            }
-
-            if (approver.group_id) {
-              return Api.group(approver.group_id).then(mapGroupToApprover);
-            }
-
-            return Promise.resolve({
-              accessLevel: approver.access_level,
-              name: this.accessLevelsData.find(({ id }) => id === approver.access_level).text,
-              approvals: 1,
-              type: 'access',
-            });
-          }),
-        );
-      } catch (e) {
-        Sentry.captureException(e);
-        this.errorMessage = s__(
-          'ProtectedEnvironments|An error occurred while fetching information on the selected approvers.',
-        );
-      }
-    },
   },
   methods: {
     updateDeployers(permissions) {
@@ -187,7 +109,7 @@ export default {
         name: this.environment,
         deploy_access_levels: this.deployers,
         ...(this.canCreateMultipleRules
-          ? { approval_rules: this.approvalRules }
+          ? { approval_rules: this.approvers }
           : { required_approval_count: this.approvals }),
       };
       Api.createProtectedEnvironment(this.projectId, protectedEnvironment)
@@ -199,10 +121,6 @@ export default {
           this.errorMessage = __('Failed to protect the environment');
         });
     },
-    isApprovalValid(approvals) {
-      const count = parseFloat(approvals);
-      return count >= MIN_APPROVALS_COUNT && count <= MAX_APPROVALS_COUNT;
-    },
   },
   i18n: {
     unifiedRulesAlertHeader: s__(
@@ -215,16 +133,10 @@ export default {
     environmentLabel: s__('ProtectedEnvironment|Select environment'),
     environmentText: s__('ProtectedEnvironment|Select an environment'),
     approvalLabel: s__('ProtectedEnvironment|Required approvals'),
-    approverLabel: s__('ProtectedEnvironment|Approvers'),
-    approverHelp: s__(
-      'ProtectedEnvironments|Set which groups, access levels or users are required to approve.',
-    ),
     deployerLabel: s__('ProtectedEnvironments|Allowed to deploy'),
     deployerHelp: s__(
       'ProtectedEnvironments|Set which groups, access levels or users that are allowed to deploy to this environment',
     ),
-    approvalRulesLabel: s__('ProtectedEnvironments|Approval rules'),
-    approvalsInvalid: s__('ProtectedEnvironments|Number of approvals must be between 1 and 5'),
     buttonText: s__('ProtectedEnvironment|Protect'),
   },
   APPROVAL_COUNT_OPTIONS: ['0', '1', '2', '3', '4', '5'].map((value) => ({ value, text: value })),
@@ -291,65 +203,11 @@ export default {
               @hidden="updateDeployers"
             />
           </gl-form-group>
-          <gl-form-group
-            data-testid="create-approver-dropdown"
-            label-for="create-approver-dropdown"
-            :label="$options.i18n.approverLabel"
-          >
-            <template #label-description>
-              {{ $options.i18n.approverHelp }}
-            </template>
-            <access-dropdown
-              id="create-approver-dropdown"
-              :access-levels-data="accessLevelsData"
-              :access-level="$options.ACCESS_LEVELS.DEPLOY"
-              :disabled="disabled"
-              :preselected-items="approvers"
-              @hidden="updateApprovers"
-            />
-          </gl-form-group>
-          <gl-collapse :visible="hasSelectedApprovers">
-            <span class="gl-font-weight-bold">{{ $options.i18n.approvalRulesLabel }}</span>
-            <div
-              data-testid="approval-rules"
-              class="protected-environment-approvers gl-display-grid gl-gap-5 gl-align-items-center"
-            >
-              <span class="protected-environment-approvers-label">{{ __('Approvers') }}</span>
-              <span>{{ __('Approvals required') }}</span>
-              <template v-for="(approver, index) in approverInfo">
-                <gl-avatar
-                  v-if="approver.avatarShape"
-                  :key="`${index}-avatar`"
-                  :src="approver.avatarUrl"
-                  :size="24"
-                  :entity-id="approver.id"
-                  :entity-name="approver.entityName"
-                  :shape="approver.avatarShape"
-                />
-                <span v-else :key="`${index}-avatar`" class="gl-w-6"></span>
-                <gl-link v-if="approver.webUrl" :key="`${index}-name`" :href="approver.webUrl">
-                  {{ approver.name }}
-                </gl-link>
-                <span v-else :key="`${index}-name`">{{ approver.name }}</span>
-
-                <gl-form-group
-                  :key="`${index}-approvals`"
-                  :state="isApprovalValid(approver.approvals)"
-                >
-                  <gl-form-input
-                    v-model="approver.approvals"
-                    :disabled="approver.inputDisabled"
-                    :state="isApprovalValid(approver.approvals)"
-                    :name="`approval-count-${approver.name}`"
-                    type="number"
-                  />
-                  <template #invalid-feedback>
-                    {{ $options.i18n.approvalsInvalid }}
-                  </template>
-                </gl-form-group>
-              </template>
-            </div>
-          </gl-collapse>
+          <add-approvers
+            :project-id="projectId"
+            @change="updateApprovers"
+            @error="errorMessage = $event"
+          />
         </gl-collapse>
       </template>
       <template v-else>
@@ -387,12 +245,3 @@ export default {
     </template>
   </gl-card>
 </template>
-<style>
-.protected-environment-approvers {
-  grid-template-columns: repeat(3, max-content);
-}
-
-.protected-environment-approvers-label {
-  grid-column: span 2;
-}
-</style>
diff --git a/ee/app/assets/stylesheets/page_bundles/ci_cd_settings.scss b/ee/app/assets/stylesheets/page_bundles/ci_cd_settings.scss
new file mode 100644
index 0000000000000000000000000000000000000000..67445f244c43f41578c205f43f6c185f2b870f45
--- /dev/null
+++ b/ee/app/assets/stylesheets/page_bundles/ci_cd_settings.scss
@@ -0,0 +1,7 @@
+.protected-environment-approvers {
+  grid-template-columns: repeat(3, max-content);
+}
+
+.protected-environment-approvers-label {
+  grid-column: span 2;
+}
diff --git a/ee/app/views/projects/protected_environments/_form.html.haml b/ee/app/views/projects/protected_environments/_form.html.haml
index bb7b009c1b202fec5132d978df5db56228db33e9..96cf130467d71c037131e6055ffee9d75f34a2d8 100644
--- a/ee/app/views/projects/protected_environments/_form.html.haml
+++ b/ee/app/views/projects/protected_environments/_form.html.haml
@@ -1,3 +1,5 @@
+- add_page_specific_style 'page_bundles/ci_cd_settings'
+
 .js-protected-environment-create-form{ data: { project_id: @project.id,
                                       api_link: help_page_path('api/protected_environments.md'),
                                       docs_link: help_page_path('ci/environments/deployment_approvals.md', anchor: 'multiple-approval-rules') } }
diff --git a/ee/spec/frontend/protected_environments/add_approvers_spec.js b/ee/spec/frontend/protected_environments/add_approvers_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..546f6180a9830b24f5a39a5ea31b68612c059bca
--- /dev/null
+++ b/ee/spec/frontend/protected_environments/add_approvers_spec.js
@@ -0,0 +1,186 @@
+import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
+import { GlAvatar, GlFormInput } from '@gitlab/ui';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import { TEST_HOST } from 'helpers/test_constants';
+import axios from '~/lib/utils/axios_utils';
+import AccessDropdown from '~/projects/settings/components/access_dropdown.vue';
+import { ACCESS_LEVELS } from 'ee/protected_environments/constants';
+import AddApprovers from 'ee/protected_environments/add_approvers.vue';
+import { HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_OK } from '~/lib/utils/http_status';
+import { __, s__ } from '~/locale';
+
+const PROJECT_ID = '0';
+
+describe('ee/protected_environments/add_approvers.vue', () => {
+  let wrapper;
+  let originalGon;
+  let mockAxios;
+
+  const createComponent = ({ projectId = PROJECT_ID, disabled = false } = {}) => {
+    wrapper = mountExtended(AddApprovers, {
+      propsData: {
+        projectId,
+        disabled,
+      },
+      provide: {
+        accessLevelsData: [
+          {
+            id: 40,
+            text: 'Maintainers',
+            before_divider: true,
+          },
+          {
+            id: 30,
+            text: 'Developers + Maintainers',
+            before_divider: true,
+          },
+        ],
+      },
+    });
+  };
+
+  const findApproverDropdown = () => wrapper.findComponent(AccessDropdown);
+
+  const findRequiredCountForApprover = (name) =>
+    wrapper
+      .findAllComponents(GlFormInput)
+      .wrappers.find((w) => w.attributes('name') === `approval-count-${name}`);
+
+  beforeEach(() => {
+    originalGon = window.gon;
+
+    window.gon = {
+      ...window.gon,
+      api_version: 'v4',
+      deploy_access_levels: {
+        roles: [],
+      },
+    };
+    mockAxios = new MockAdapter(axios);
+  });
+
+  afterEach(() => {
+    window.gon = originalGon;
+  });
+
+  it('renders a dropdown for selecting approvers', () => {
+    createComponent();
+
+    const approvers = findApproverDropdown();
+
+    expect(approvers.props()).toMatchObject({
+      accessLevel: ACCESS_LEVELS.DEPLOY,
+      label: __('Select users'),
+    });
+  });
+
+  it('emits an error if unable to fetch details for an approver', async () => {
+    mockAxios.onGet().replyOnce(HTTP_STATUS_BAD_REQUEST);
+
+    createComponent();
+    findApproverDropdown().vm.$emit('hidden', [{ group_id: 1 }]);
+
+    await waitForPromises();
+
+    const [[event]] = wrapper.emitted('error').reverse();
+    expect(event).toBe(
+      s__(
+        'ProtectedEnvironments|An error occurred while fetching information on the selected approvers.',
+      ),
+    );
+  });
+
+  it('emits an empty error value when fetching new details', async () => {
+    createComponent();
+    findApproverDropdown().vm.$emit('hidden', [{ group_id: 1 }]);
+
+    await waitForPromises();
+
+    mockAxios.onGet('/api/v4/users/1').replyOnce(HTTP_STATUS_OK, {
+      name: 'root',
+      web_url: `${TEST_HOST}/root`,
+      avatar_url: '/root.png',
+      id: 1,
+    });
+    findApproverDropdown().vm.$emit('hidden', [{ user_id: 1 }]);
+
+    await waitForPromises();
+
+    const [[event]] = wrapper.emitted('error').reverse();
+    expect(event).toBe('');
+  });
+
+  describe('information for approvers', () => {
+    beforeEach(() => {
+      mockAxios.onGet('/api/v4/users/1').replyOnce(HTTP_STATUS_OK, {
+        name: 'root',
+        web_url: `${TEST_HOST}/root`,
+        avatar_url: '/root.png',
+        id: 1,
+      });
+      mockAxios.onGet('/api/v4/groups/1').replyOnce(HTTP_STATUS_OK, {
+        full_name: 'root / group',
+        name: 'group',
+        web_url: `${TEST_HOST}/root/group`,
+        avatar_url: '/root/group.png',
+        id: 1,
+      });
+    });
+
+    describe.each`
+      type              | access                  | details
+      ${'access level'} | ${{ access_level: 30 }} | ${{ name: 'Developers + Maintainers' }}
+      ${'group'}        | ${{ group_id: 1 }}      | ${{ avatarUrl: '/root/group.png', href: `${TEST_HOST}/root/group`, name: 'root / group' }}
+      ${'user'}         | ${{ user_id: 1 }}       | ${{ avatarUrl: '/root.png', href: `${TEST_HOST}/root`, name: 'root', inputDisabled: true }}
+    `('it displays correct information for $type', ({ access, details }) => {
+      beforeEach(async () => {
+        createComponent();
+        findApproverDropdown().vm.$emit('hidden', [access]);
+        await nextTick();
+        await waitForPromises();
+      });
+
+      if (details.href) {
+        it('should link to the entity', () => {
+          const link = wrapper.findByRole('link', { name: details.name });
+          expect(link.attributes('href')).toBe(details.href);
+        });
+      } else {
+        it('should display the name of the entity', () => {
+          expect(wrapper.text()).toContain(details.name);
+        });
+      }
+
+      if (details.avatarUrl) {
+        it('should show an avatar', () => {
+          const avatar = wrapper.findComponent(GlAvatar);
+          expect(avatar.props('src')).toBe(details.avatarUrl);
+        });
+      }
+
+      if (details.inputDisabled) {
+        it('should have the input disabled and set to 1', () => {
+          const input = findRequiredCountForApprover(details.name);
+          expect(input.element.value).toBe('1');
+          expect(input.attributes('disabled')).toBeDefined();
+        });
+      } else {
+        it('should not have the input disabled and set to 1', () => {
+          const input = findRequiredCountForApprover(details.name);
+          expect(input.element.value).toBe('1');
+          expect(input.attributes('disabled')).toBeUndefined();
+        });
+      }
+
+      it('emits approver info', async () => {
+        const input = findRequiredCountForApprover(details.name);
+        input.vm.$emit('input', 3);
+        await nextTick();
+        const [[[event]]] = wrapper.emitted('change').reverse();
+        expect(event).toEqual({ ...access, required_approvals: 3 });
+      });
+    });
+  });
+});
diff --git a/ee/spec/frontend/protected_environments/create_protected_environment_spec.js b/ee/spec/frontend/protected_environments/create_protected_environment_spec.js
index c357ebb4bce93a7df9253c7adc87bccfab47f0e0..c49a10dee4b41e4f1a2a7ed23363577b67f6c645 100644
--- a/ee/spec/frontend/protected_environments/create_protected_environment_spec.js
+++ b/ee/spec/frontend/protected_environments/create_protected_environment_spec.js
@@ -1,6 +1,6 @@
 import MockAdapter from 'axios-mock-adapter';
 import { nextTick } from 'vue';
-import { GlAlert, GlCollapsibleListbox, GlFormInput, GlAvatar } from '@gitlab/ui';
+import { GlAlert, GlCollapsibleListbox, GlFormInput } from '@gitlab/ui';
 import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
 import { mountExtended } from 'helpers/vue_test_utils_helper';
 import waitForPromises from 'helpers/wait_for_promises';
@@ -9,6 +9,7 @@ import Api from 'ee/api';
 import axios from '~/lib/utils/axios_utils';
 import AccessDropdown from '~/projects/settings/components/access_dropdown.vue';
 import { ACCESS_LEVELS } from 'ee/protected_environments/constants';
+import AddApprovers from 'ee/protected_environments/add_approvers.vue';
 import CreateProtectedEnvironment from 'ee/protected_environments/create_protected_environment.vue';
 import { HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_OK } from '~/lib/utils/http_status';
 import { __, s__ } from '~/locale';
@@ -32,12 +33,12 @@ describe('ee/protected_environments/create_protected_environment.vue', () => {
     wrapper.findByTestId('create-deployer-dropdown').findComponent(AccessDropdown);
   const findRequiredCountSelect = () =>
     wrapper.findByTestId('create-approval-count').findComponent(GlCollapsibleListbox);
-  const findRequredCountForApprover = (name) =>
+  const findRequiredCountForApprover = (name) =>
     wrapper
       .findAllComponents(GlFormInput)
       .wrappers.find((w) => w.attributes('name') === `approval-count-${name}`);
-  const findApproverDropdown = () =>
-    wrapper.findByTestId('create-approver-dropdown').findComponent(AccessDropdown);
+  const findAddApprovers = () => wrapper.findComponent(AddApprovers);
+  const findApproverDropdown = () => findAddApprovers().findComponent(AccessDropdown);
   const findSubmitButton = () =>
     wrapper.findByRole('button', { name: s__('ProtectedEnvironment|Protect') });
 
@@ -99,6 +100,7 @@ describe('ee/protected_environments/create_protected_environment.vue', () => {
       findAccessDropdown().vm.$emit('hidden', deployAccessLevels);
       findEnvironmentsListbox().vm.$emit('select', name);
       findRequiredCountSelect().vm.$emit('select', requiredApprovalCount);
+
       await findSubmitButton().vm.$emit('click');
     };
 
@@ -196,7 +198,8 @@ describe('ee/protected_environments/create_protected_environment.vue', () => {
       findEnvironmentsListbox().vm.$emit('select', name);
       findApproverDropdown().vm.$emit('hidden', deployAccessLevels);
       await waitForPromises();
-      findRequredCountForApprover('root').vm.$emit('input', requiredApprovalCount);
+      findRequiredCountForApprover('root').vm.$emit('input', requiredApprovalCount);
+      await nextTick();
       await findSubmitButton().vm.$emit('click');
     };
 
@@ -264,11 +267,10 @@ describe('ee/protected_environments/create_protected_environment.vue', () => {
     it('renders a dropdown for selecting approvers', () => {
       createComponent();
 
-      const approvers = findApproverDropdown();
+      const approvers = findAddApprovers();
 
       expect(approvers.props()).toMatchObject({
-        accessLevel: ACCESS_LEVELS.DEPLOY,
-        label: __('Select users'),
+        disabled: false,
       });
     });
 
@@ -284,7 +286,7 @@ describe('ee/protected_environments/create_protected_environment.vue', () => {
 
       expect(Api.createProtectedEnvironment).toHaveBeenCalledWith(PROJECT_ID, {
         deploy_access_levels: deployAccessLevels,
-        approval_rules: [{ user_id: 1, required_approvals: '3' }],
+        approval_rules: [{ user_id: 1, required_approvals: requiredApprovalCount }],
         name,
       });
     });
@@ -312,71 +314,5 @@ describe('ee/protected_environments/create_protected_environment.vue', () => {
         expect(window.location.reload).not.toHaveBeenCalled();
       });
     });
-
-    describe('information for approvers', () => {
-      unmockLocation();
-      beforeEach(() => {
-        mockAxios.onGet('/api/v4/users/1').replyOnce(HTTP_STATUS_OK, {
-          name: 'root',
-          web_url: `${TEST_HOST}/root`,
-          avatar_url: '/root.png',
-          id: 1,
-        });
-        mockAxios.onGet('/api/v4/groups/1').replyOnce(HTTP_STATUS_OK, {
-          full_name: 'root / group',
-          name: 'group',
-          web_url: `${TEST_HOST}/root/group`,
-          avatar_url: '/root/group.png',
-          id: 1,
-        });
-      });
-
-      describe.each`
-        type              | access                  | details
-        ${'access level'} | ${{ access_level: 30 }} | ${{ name: 'Developers + Maintainers' }}
-        ${'group'}        | ${{ group_id: 1 }}      | ${{ avatarUrl: '/root/group.png', href: `${TEST_HOST}/root/group`, name: 'root / group' }}
-        ${'user'}         | ${{ user_id: 1 }}       | ${{ avatarUrl: '/root.png', href: `${TEST_HOST}/root`, name: 'root', inputDisabled: true }}
-      `('it displays correct information for $type', ({ access, details }) => {
-        beforeEach(async () => {
-          createComponent();
-          findEnvironmentsListbox().vm.$emit('select', 'production');
-          findApproverDropdown().vm.$emit('hidden', [access]);
-          await waitForPromises();
-          await nextTick();
-        });
-
-        if (details.href) {
-          it('should link to the entity', () => {
-            const link = wrapper.findByRole('link', { name: details.name });
-            expect(link.attributes('href')).toBe(details.href);
-          });
-        } else {
-          it('should display the name of the entity', () => {
-            expect(wrapper.text()).toContain(details.name);
-          });
-        }
-
-        if (details.avatarUrl) {
-          it('should show an avatar', () => {
-            const avatar = wrapper.findComponent(GlAvatar);
-            expect(avatar.props('src')).toBe(details.avatarUrl);
-          });
-        }
-
-        if (details.inputDisabled) {
-          it('should have the input disabled and set to 1', () => {
-            const input = findRequredCountForApprover(details.name);
-            expect(input.element.value).toBe('1');
-            expect(input.attributes('disabled')).toBeDefined();
-          });
-        } else {
-          it('should not have the input disabled and set to 0', () => {
-            const input = findRequredCountForApprover(details.name);
-            expect(input.element.value).toBe('1');
-            expect(input.attributes('disabled')).toBeUndefined();
-          });
-        }
-      });
-    });
   });
 });