1
1
<script >
2
- import {
3
- GlAvatarLabeled ,
4
- GlDropdown ,
5
- GlDropdownItem ,
6
- GlDropdownText ,
7
- GlSearchBoxByType ,
8
- } from ' @gitlab/ui' ;
2
+ import { GlAvatarLabeled , GlCollapsibleListbox } from ' @gitlab/ui' ;
9
3
import { debounce } from ' lodash' ;
10
4
import { convertObjectPropsToCamelCase } from ' ~/lib/utils/common_utils' ;
11
5
import { s__ } from ' ~/locale' ;
12
6
import { getProjects } from ' ~/rest_api' ;
13
7
import { SEARCH_DELAY , GROUP_FILTERS } from ' ../constants' ;
14
8
9
+ // We can have GlCollapsibleListbox dropdown panel with full
10
+ // width once we implement
11
+ // https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2133
12
+ // https://gitlab.com/gitlab-org/gitlab/-/issues/390411
15
13
export default {
16
14
name: ' ProjectSelect' ,
17
15
components: {
18
16
GlAvatarLabeled,
19
- GlDropdown,
20
- GlDropdownItem,
21
- GlDropdownText,
22
- GlSearchBoxByType,
17
+ GlCollapsibleListbox,
23
18
},
24
19
model: {
25
- prop: ' selectedProject ' ,
20
+ prop: ' selectedProjectId ' ,
26
21
},
27
22
props: {
28
23
groupsFilter: {
@@ -41,18 +36,21 @@ export default {
41
36
return {
42
37
isFetching: false ,
43
38
projects: [],
44
- selectedProject : {} ,
39
+ selectedProjectId : ' ' ,
45
40
searchTerm: ' ' ,
46
41
errorMessage: ' ' ,
47
42
};
48
43
},
49
44
computed: {
50
45
selectedProjectName () {
51
- return this .selectedProject .name || this .$options .i18n .dropdownText ;
46
+ return this .selectedProject .nameWithNamespace || this .$options .i18n .dropdownText ;
52
47
},
53
48
isFetchResultEmpty () {
54
49
return this .projects .length === 0 && ! this .isFetching ;
55
50
},
51
+ selectedProject () {
52
+ return this .projects .find ((prj ) => prj .id === this .selectedProjectId ) || {};
53
+ },
56
54
},
57
55
watch: {
58
56
searchTerm () {
@@ -70,10 +68,14 @@ export default {
70
68
.then ((response ) => {
71
69
this .projects = response .data .map ((project ) => ({
72
70
... convertObjectPropsToCamelCase (project),
73
- name: project .name_with_namespace ,
71
+ text: project .name_with_namespace ,
72
+ value: project .id ,
74
73
}));
75
74
})
76
75
.catch (() => {
76
+ // To be displayed in GlCollapsibleListbox once we implement
77
+ // https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2132
78
+ // https://gitlab.com/gitlab-org/gitlab/-/issues/389974
77
79
this .errorMessage = this .$options .i18n .errorFetchingProjects ;
78
80
})
79
81
.finally (() => {
@@ -83,9 +85,7 @@ export default {
83
85
fetchProjects () {
84
86
return getProjects (this .searchTerm , this .$options .defaultFetchOptions );
85
87
},
86
- selectProject (project ) {
87
- this .selectedProject = project;
88
-
88
+ selectProject () {
89
89
this .$emit (' input' , this .selectedProject );
90
90
},
91
91
},
@@ -104,40 +104,28 @@ export default {
104
104
};
105
105
</script >
106
106
<template >
107
- <div >
108
- <gl-dropdown
109
- data-testid =" project-select-dropdown"
110
- :text =" selectedProjectName"
111
- toggle-class =" gl-mb-2"
112
- block
113
- menu-class =" gl-w-full!"
114
- >
115
- <gl-search-box-by-type
116
- v-model =" searchTerm"
117
- :is-loading =" isFetching"
118
- :placeholder =" $options.i18n.searchPlaceholder"
119
- data-qa-selector =" project_select_dropdown_search_field"
107
+ <gl-collapsible-listbox
108
+ v-model =" selectedProjectId"
109
+ searchable
110
+ :items =" projects"
111
+ :searching =" isFetching"
112
+ :toggle-text =" selectedProjectName"
113
+ :search-placeholder =" $options.i18n.searchPlaceholder"
114
+ :no-results-text =" $options.i18n.emptySearchResult"
115
+ data-testid =" project-select-dropdown"
116
+ data-qa-selector =" project_select_dropdown"
117
+ class =" gl-collapsible-listbox-w-full"
118
+ @search =" searchTerm = $event"
119
+ @select =" selectProject"
120
+ >
121
+ <template #list-item =" { item } " >
122
+ <gl-avatar-labeled
123
+ :label =" item.text"
124
+ :src =" item.avatarUrl"
125
+ :entity-id =" item.id"
126
+ :entity-name =" item.name"
127
+ :size =" 32"
120
128
/>
121
- <gl-dropdown-item
122
- v-for =" project in projects"
123
- :key =" project.id"
124
- :name =" project.name"
125
- @click =" selectProject(project)"
126
- >
127
- <gl-avatar-labeled
128
- :label =" project.name"
129
- :src =" project.avatarUrl"
130
- :entity-id =" project.id"
131
- :entity-name =" project.name"
132
- :size =" 32"
133
- />
134
- </gl-dropdown-item >
135
- <gl-dropdown-text v-if =" errorMessage" data-testid =" error-message" >
136
- <span class =" gl-text-gray-500" >{{ errorMessage }}</span >
137
- </gl-dropdown-text >
138
- <gl-dropdown-text v-else-if =" isFetchResultEmpty" data-testid =" empty-result-message" >
139
- <span class =" gl-text-gray-500" >{{ $options.i18n.emptySearchResult }}</span >
140
- </gl-dropdown-text >
141
- </gl-dropdown >
142
- </div >
129
+ </template >
130
+ </gl-collapsible-listbox >
143
131
</template >
0 commit comments