debian-mirror-gitlab/app/assets/javascripts/invite_members/components/group_select.vue

158 lines
3.8 KiB
Vue
Raw Normal View History

2021-04-17 20:07:23 +05:30
<script>
2021-09-04 01:27:46 +05:30
import {
GlAvatarLabeled,
GlDropdown,
GlDropdownItem,
GlDropdownText,
GlSearchBoxByType,
} from '@gitlab/ui';
2021-04-17 20:07:23 +05:30
import { debounce } from 'lodash';
import { s__ } from '~/locale';
2021-09-04 01:27:46 +05:30
import { getGroups, getDescendentGroups } from '~/rest_api';
import { SEARCH_DELAY, GROUP_FILTERS } from '../constants';
2021-04-17 20:07:23 +05:30
export default {
name: 'GroupSelect',
components: {
2021-09-04 01:27:46 +05:30
GlAvatarLabeled,
2021-04-17 20:07:23 +05:30
GlDropdown,
GlDropdownItem,
GlDropdownText,
GlSearchBoxByType,
},
model: {
prop: 'selectedGroup',
},
2021-09-04 01:27:46 +05:30
props: {
2022-04-04 11:22:00 +05:30
accessLevels: {
type: Object,
required: true,
},
2021-09-04 01:27:46 +05:30
groupsFilter: {
type: String,
required: false,
default: GROUP_FILTERS.ALL,
},
parentGroupId: {
type: Number,
required: false,
default: null,
},
2022-04-04 11:22:00 +05:30
invalidGroups: {
type: Array,
required: true,
},
2021-09-04 01:27:46 +05:30
},
2021-04-17 20:07:23 +05:30
data() {
return {
isFetching: false,
groups: [],
selectedGroup: {},
searchTerm: '',
};
},
computed: {
selectedGroupName() {
return this.selectedGroup.name || this.$options.i18n.dropdownText;
},
isFetchResultEmpty() {
return this.groups.length === 0;
},
2022-04-04 11:22:00 +05:30
defaultFetchOptions() {
return {
exclude_internal: true,
active: true,
min_access_level: this.accessLevels.Guest,
};
},
2021-04-17 20:07:23 +05:30
},
watch: {
searchTerm() {
this.retrieveGroups();
},
},
mounted() {
this.retrieveGroups();
},
methods: {
retrieveGroups: debounce(function debouncedRetrieveGroups() {
this.isFetching = true;
2021-09-04 01:27:46 +05:30
return this.fetchGroups()
2021-04-17 20:07:23 +05:30
.then((response) => {
2022-04-04 11:22:00 +05:30
this.groups = this.processGroups(response);
2021-04-17 20:07:23 +05:30
this.isFetching = false;
})
.catch(() => {
this.isFetching = false;
});
}, SEARCH_DELAY),
2022-04-04 11:22:00 +05:30
processGroups(response) {
const rawGroups = response.map((group) => ({
id: group.id,
name: group.full_name,
path: group.path,
avatarUrl: group.avatar_url,
}));
return this.filterOutInvalidGroups(rawGroups);
},
filterOutInvalidGroups(groups) {
return groups.filter((group) => this.invalidGroups.indexOf(group.id) === -1);
},
2021-04-17 20:07:23 +05:30
selectGroup(group) {
this.selectedGroup = group;
this.$emit('input', this.selectedGroup);
},
2021-09-04 01:27:46 +05:30
fetchGroups() {
switch (this.groupsFilter) {
case GROUP_FILTERS.DESCENDANT_GROUPS:
2022-04-04 11:22:00 +05:30
return getDescendentGroups(this.parentGroupId, this.searchTerm, this.defaultFetchOptions);
2021-09-04 01:27:46 +05:30
default:
2022-04-04 11:22:00 +05:30
return getGroups(this.searchTerm, this.defaultFetchOptions);
2021-09-04 01:27:46 +05:30
}
},
2021-04-17 20:07:23 +05:30
},
i18n: {
dropdownText: s__('GroupSelect|Select a group'),
searchPlaceholder: s__('GroupSelect|Search groups'),
emptySearchResult: s__('GroupSelect|No matching results'),
},
};
</script>
<template>
<div>
<gl-dropdown
data-testid="group-select-dropdown"
:text="selectedGroupName"
block
2021-10-27 15:23:28 +05:30
toggle-class="gl-mb-2"
2021-04-17 20:07:23 +05:30
menu-class="gl-w-full!"
>
<gl-search-box-by-type
2021-09-04 01:27:46 +05:30
v-model="searchTerm"
2021-04-17 20:07:23 +05:30
:is-loading="isFetching"
:placeholder="$options.i18n.searchPlaceholder"
data-qa-selector="group_select_dropdown_search_field"
/>
<gl-dropdown-item
v-for="group in groups"
:key="group.id"
:name="group.name"
@click="selectGroup(group)"
>
2021-09-04 01:27:46 +05:30
<gl-avatar-labeled
:label="group.name"
:src="group.avatarUrl"
:entity-id="group.id"
:entity-name="group.name"
:size="32"
/>
2021-04-17 20:07:23 +05:30
</gl-dropdown-item>
<gl-dropdown-text v-if="isFetchResultEmpty && !isFetching" data-testid="empty-result-message">
<span class="gl-text-gray-500">{{ $options.i18n.emptySearchResult }}</span>
</gl-dropdown-text>
</gl-dropdown>
</div>
</template>