Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-12-23 12:10:13 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-12-23 12:10:13 +0300
commit65fdda8d39a9af414dbe5aa3a385b9bcba00960b (patch)
tree8cdac4fe05966ae74301044522ad5be1e7087ed1 /app/assets/javascripts/boards
parentde64b03b15fb40a3fc2f1897e8e4f6be50fd4403 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/boards')
-rw-r--r--app/assets/javascripts/boards/components/project_select.vue195
1 files changed, 112 insertions, 83 deletions
diff --git a/app/assets/javascripts/boards/components/project_select.vue b/app/assets/javascripts/boards/components/project_select.vue
index 9c90938fc52..f152d708f2b 100644
--- a/app/assets/javascripts/boards/components/project_select.vue
+++ b/app/assets/javascripts/boards/components/project_select.vue
@@ -1,19 +1,37 @@
<script>
-import $ from 'jquery';
-import { escape } from 'lodash';
-import { GlLoadingIcon, GlIcon } from '@gitlab/ui';
-import { __ } from '~/locale';
+import {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownText,
+ GlSearchBoxByType,
+ GlLoadingIcon,
+} from '@gitlab/ui';
import eventHub from '../eventhub';
+import { s__ } from '~/locale';
import Api from '../../api';
import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants';
-import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
import { ListType } from '../constants';
export default {
- name: 'BoardProjectSelect',
+ name: 'ProjectSelect',
+ i18n: {
+ headerTitle: s__(`BoardNewIssue|Projects`),
+ dropdownText: s__(`BoardNewIssue|Select a project`),
+ searchPlaceholder: s__(`BoardNewIssue|Search projects`),
+ emptySearchResult: s__(`BoardNewIssue|No matching results`),
+ },
+ defaultFetchOptions: {
+ with_issues_enabled: true,
+ with_shared: false,
+ include_subgroups: true,
+ order_by: 'similarity',
+ },
components: {
- GlIcon,
GlLoadingIcon,
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownText,
+ GlSearchBoxByType,
},
props: {
list: {
@@ -24,97 +42,108 @@ export default {
inject: ['groupId'],
data() {
return {
- loading: true,
+ initialLoading: true,
+ isFetching: false,
+ projects: [],
selectedProject: {},
+ searchTerm: '',
};
},
computed: {
selectedProjectName() {
- return this.selectedProject.name || __('Select a project');
+ return this.selectedProject.name || this.$options.i18n.dropdownText;
+ },
+ fetchOptions() {
+ const additionalAttrs = {};
+ if (this.list.type && this.list.type !== ListType.backlog) {
+ additionalAttrs.min_access_level = featureAccessLevel.EVERYONE;
+ }
+
+ return {
+ ...this.$options.defaultFetchOptions,
+ ...additionalAttrs,
+ };
+ },
+ isFetchResultEmpty() {
+ return this.projects.length === 0;
},
},
- mounted() {
- initDeprecatedJQueryDropdown($(this.$refs.projectsDropdown), {
- filterable: true,
- filterRemote: true,
- search: {
- fields: ['name_with_namespace'],
- },
- clicked: ({ $el, e }) => {
- e.preventDefault();
- this.selectedProject = {
- id: $el.data('project-id'),
- name: $el.data('project-name'),
- path: $el.data('project-path'),
- };
- eventHub.$emit('setSelectedProject', this.selectedProject);
- },
- selectable: true,
- data: (term, callback) => {
- this.loading = true;
- const additionalAttrs = {};
+ watch: {
+ searchTerm() {
+ this.fetchProjects();
+ },
+ },
+ async mounted() {
+ await this.fetchProjects();
- if ((this.list.type || this.list.listType) !== ListType.backlog) {
- additionalAttrs.min_access_level = featureAccessLevel.EVERYONE;
- }
+ this.initialLoading = false;
+ },
+ methods: {
+ async fetchProjects() {
+ this.isFetching = true;
+ try {
+ const projects = await Api.groupProjects(this.groupId, this.searchTerm, this.fetchOptions);
- return Api.groupProjects(
- this.groupId,
- term,
- {
- with_issues_enabled: true,
- with_shared: false,
- include_subgroups: true,
- order_by: 'similarity',
- ...additionalAttrs,
- },
- projects => {
- this.loading = false;
- callback(projects);
- },
- );
- },
- renderRow(project) {
- return `
- <li>
- <a href='#' class='dropdown-menu-link'
- data-project-id="${project.id}"
- data-project-name="${project.name}"
- data-project-name-with-namespace="${project.name_with_namespace}"
- data-project-path="${project.path_with_namespace}"
- >
- ${escape(project.name_with_namespace)}
- </a>
- </li>
- `;
- },
- text: project => project.name_with_namespace,
- });
+ this.projects = projects.map(project => {
+ return {
+ id: project.id,
+ name: project.name,
+ namespacedName: project.name_with_namespace,
+ path: project.path_with_namespace,
+ };
+ });
+ } catch (err) {
+ /* Handled in Api.groupProjects */
+ } finally {
+ this.isFetching = false;
+ }
+ },
+ selectProject(projectId) {
+ this.selectedProject = this.projects.find(project => project.id === projectId);
+
+ /*
+ TODO Remove eventhub, use Vuex for BoardNewIssue and GraphQL for BoardNewIssueNew
+ https://gitlab.com/gitlab-org/gitlab/-/issues/276173
+ */
+ eventHub.$emit('setSelectedProject', this.selectedProject);
+ },
},
};
</script>
<template>
<div>
- <label class="label-bold gl-mt-3">{{ __('Project') }}</label>
- <div ref="projectsDropdown" class="dropdown dropdown-projects">
- <button
- class="dropdown-menu-toggle wide"
- type="button"
- data-toggle="dropdown"
- aria-expanded="false"
+ <label class="gl-font-weight-bold gl-mt-3" data-testid="header-label">{{
+ $options.i18n.headerTitle
+ }}</label>
+ <gl-dropdown
+ data-testid="project-select-dropdown"
+ :text="selectedProjectName"
+ :header-text="$options.i18n.headerTitle"
+ block
+ menu-class="gl-w-full!"
+ :loading="initialLoading"
+ >
+ <gl-search-box-by-type
+ v-model.trim="searchTerm"
+ debounce="250"
+ :placeholder="$options.i18n.searchPlaceholder"
+ />
+ <gl-dropdown-item
+ v-for="project in projects"
+ v-show="!isFetching"
+ :key="project.id"
+ :name="project.name"
+ @click="selectProject(project.id)"
>
- {{ selectedProjectName }} <gl-icon name="chevron-down" class="dropdown-menu-toggle-icon" />
- </button>
- <div class="dropdown-menu dropdown-menu-selectable dropdown-menu-full-width">
- <div class="dropdown-title">{{ __('Projects') }}</div>
- <div class="dropdown-input">
- <input class="dropdown-input-field" type="search" :placeholder="__('Search projects')" />
- <gl-icon name="search" class="dropdown-input-search" data-hidden="true" />
- </div>
- <div class="dropdown-content"></div>
- <div class="dropdown-loading"><gl-loading-icon /></div>
- </div>
- </div>
+ {{ project.namespacedName }}
+ </gl-dropdown-item>
+ <gl-dropdown-text v-show="isFetching" data-testid="dropdown-text-loading-icon">
+ <gl-loading-icon class="gl-mx-auto" />
+ </gl-dropdown-text>
+ <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>