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:
authorNathan Friend <nfriend@gitlab.com>2019-03-12 19:35:55 +0300
committermfluharty <mfluharty@gitlab.com>2019-04-03 08:58:01 +0300
commit06b88af04657be961a4da97a586706fb99eb6a27 (patch)
treee574c1a39cdc6ca75a734c8256604baa698aa447 /app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue
parent645303c7e71d554c3ee1a338730d8b779c47acc1 (diff)
Add reusable project_selector component
This commit adds a resuable UI component that allows a user to search for a project name, shows the search results, and allows the user to select one or more projects. This component communicates with its parent using props and events. This component was originally created for use in the EE-specific "Operations Dashboard" page, but it is applicable for CE use cases as well, and so was added as a CE shared component. In addition, some logic was extracted from the frequent_items_list_item component into shared filters to avoid logic duplication.
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue')
-rw-r--r--app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue103
1 files changed, 103 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue b/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue
new file mode 100644
index 00000000000..bb17a9b331e
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue
@@ -0,0 +1,103 @@
+<script>
+import _ from 'underscore';
+import { GlLoadingIcon } from '@gitlab/ui';
+import ProjectListItem from './project_list_item.vue';
+
+const SEARCH_INPUT_TIMEOUT_MS = 500;
+
+export default {
+ name: 'ProjectSelector',
+ components: {
+ GlLoadingIcon,
+ ProjectListItem,
+ },
+ props: {
+ projectSearchResults: {
+ type: Array,
+ required: true,
+ },
+ selectedProjects: {
+ type: Array,
+ required: true,
+ },
+ showNoResultsMessage: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ showMinimumSearchQueryMessage: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ showLoadingIndicator: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ showSearchErrorMessage: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ data() {
+ return {
+ searchQuery: '',
+ };
+ },
+ methods: {
+ projectClicked(project) {
+ this.$emit('projectClicked', project);
+ },
+ isSelected(project) {
+ return Boolean(_.findWhere(this.selectedProjects, { id: project.id }));
+ },
+ focusSearchInput() {
+ this.$refs.searchInput.focus();
+ },
+ onInput: _.debounce(function debouncedOnInput(e) {
+ this.$emit('searched', e.target.value);
+ }, SEARCH_INPUT_TIMEOUT_MS),
+ },
+};
+</script>
+<template>
+ <div>
+ <input
+ ref="searchInput"
+ v-model="searchQuery"
+ :placeholder="__('Search your projects')"
+ type="search"
+ class="form-control mb-3 js-project-selector-input"
+ autofocus
+ @input="onInput"
+ />
+ <div class="d-flex flex-column">
+ <gl-loading-icon v-if="showLoadingIndicator" :size="2" class="py-2 px-4" />
+ <div v-if="!showLoadingIndicator" class="d-flex flex-column">
+ <project-list-item
+ v-for="project in projectSearchResults"
+ :key="project.id"
+ :selected="isSelected(project)"
+ :project="project"
+ :matcher="searchQuery"
+ class="js-project-list-item"
+ @click="projectClicked(project)"
+ />
+ </div>
+ <div v-if="showNoResultsMessage" class="text-muted ml-2 js-no-results-message">
+ {{ __('Sorry, no projects matched your search') }}
+ </div>
+ <div
+ v-if="showMinimumSearchQueryMessage"
+ class="text-muted ml-2 js-minimum-search-query-message"
+ >
+ {{ __('Enter at least three characters to search') }}
+ </div>
+ <div v-if="showSearchErrorMessage" class="text-danger ml-2 js-search-error-message">
+ {{ __('Something went wrong, unable to search projects') }}
+ </div>
+ </div>
+ </div>
+</template>