From 7b89fec632341709d14244ebcf738f3ca36aaa0d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eduardo=20Sanz=20Garc=C3=ADa?= <esanz-garcia@gitlab.com>
Date: Tue, 11 Jul 2023 17:49:16 +0000
Subject: [PATCH] Pass events to parent scope of GroupSelect

We use `v-on="$listeners"` to pass events to the parent scope.
`GroupSelect` becomes a transparent wrapper. Parent of `GroupSelect` can
listen to the `input` event, and any other events if added in the
future.
---
 .../components/entity_select/group_select.vue        |  1 +
 .../components/entity_select/project_select.vue      |  1 +
 .../components/entity_select/group_select_spec.js    | 12 ++++++++++++
 .../components/entity_select/project_select_spec.js  | 12 ++++++++++++
 4 files changed, 26 insertions(+)

diff --git a/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue b/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue
index ff137d764eee2..71e3bf4ff630a 100644
--- a/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue
+++ b/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue
@@ -121,6 +121,7 @@ export default {
     :default-toggle-text="$options.i18n.toggleText"
     :fetch-items="fetchGroups"
     :fetch-initial-selection-text="fetchGroupName"
+    v-on="$listeners"
   >
     <template #error>
       <gl-alert v-if="errorMessage" class="gl-mb-3" variant="danger" @dismiss="dismissError">{{
diff --git a/app/assets/javascripts/vue_shared/components/entity_select/project_select.vue b/app/assets/javascripts/vue_shared/components/entity_select/project_select.vue
index 7af3819f2a53b..13a825a68f614 100644
--- a/app/assets/javascripts/vue_shared/components/entity_select/project_select.vue
+++ b/app/assets/javascripts/vue_shared/components/entity_select/project_select.vue
@@ -166,6 +166,7 @@ export default {
     :fetch-initial-selection-text="fetchProjectName"
     :block="block"
     clearable
+    v-on="$listeners"
   >
     <template v-if="hasHtmlLabel" #label>
       <span v-safe-html="label"></span>
diff --git a/spec/frontend/vue_shared/components/entity_select/group_select_spec.js b/spec/frontend/vue_shared/components/entity_select/group_select_spec.js
index 83560e367ea43..ae55111656018 100644
--- a/spec/frontend/vue_shared/components/entity_select/group_select_spec.js
+++ b/spec/frontend/vue_shared/components/entity_select/group_select_spec.js
@@ -39,6 +39,8 @@ describe('GroupSelect', () => {
   const findEntitySelect = () => wrapper.findComponent(EntitySelect);
   const findAlert = () => wrapper.findComponent(GlAlert);
 
+  const handleInput = jest.fn();
+
   // Helpers
   const createComponent = ({ props = {} } = {}) => {
     wrapper = shallowMountExtended(GroupSelect, {
@@ -52,6 +54,9 @@ describe('GroupSelect', () => {
         GlAlert,
         EntitySelect,
       },
+      listeners: {
+        input: handleInput,
+      },
     });
   };
   const openListbox = () => findListbox().vm.$emit('shown');
@@ -132,4 +137,11 @@ describe('GroupSelect', () => {
     expect(findAlert().exists()).toBe(true);
     expect(findAlert().text()).toBe(FETCH_GROUPS_ERROR);
   });
+
+  it('forwards events to the parent scope via `v-on="$listeners"`', () => {
+    createComponent();
+    findEntitySelect().vm.$emit('input');
+
+    expect(handleInput).toHaveBeenCalledTimes(1);
+  });
 });
diff --git a/spec/frontend/vue_shared/components/entity_select/project_select_spec.js b/spec/frontend/vue_shared/components/entity_select/project_select_spec.js
index 0a174c98efbe4..9113152c975cc 100644
--- a/spec/frontend/vue_shared/components/entity_select/project_select_spec.js
+++ b/spec/frontend/vue_shared/components/entity_select/project_select_spec.js
@@ -45,6 +45,8 @@ describe('ProjectSelect', () => {
   const findEntitySelect = () => wrapper.findComponent(EntitySelect);
   const findAlert = () => wrapper.findComponent(GlAlert);
 
+  const handleInput = jest.fn();
+
   // Helpers
   const createComponent = ({ props = {} } = {}) => {
     wrapper = mountExtended(ProjectSelect, {
@@ -59,6 +61,9 @@ describe('ProjectSelect', () => {
         GlAlert,
         EntitySelect,
       },
+      listeners: {
+        input: handleInput,
+      },
     });
   };
   const openListbox = () => findListbox().vm.$emit('shown');
@@ -255,4 +260,11 @@ describe('ProjectSelect', () => {
     expect(findAlert().exists()).toBe(true);
     expect(findAlert().text()).toBe(FETCH_PROJECTS_ERROR);
   });
+
+  it('forwards events to the parent scope via `v-on="$listeners"`', () => {
+    createComponent();
+    findEntitySelect().vm.$emit('input');
+
+    expect(handleInput).toHaveBeenCalledTimes(1);
+  });
 });
-- 
GitLab