summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/jira_connect/branches
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 09:55:51 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 09:55:51 +0000
commite8d2c2579383897a1dd7f9debd359abe8ae8373d (patch)
treec42be41678c2586d49a75cabce89322082698334 /app/assets/javascripts/jira_connect/branches
parentfc845b37ec3a90aaa719975f607740c22ba6a113 (diff)
downloadgitlab-ce-e8d2c2579383897a1dd7f9debd359abe8ae8373d.tar.gz
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'app/assets/javascripts/jira_connect/branches')
-rw-r--r--app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue95
-rw-r--r--app/assets/javascripts/jira_connect/branches/components/source_branch_dropdown.vue134
-rw-r--r--app/assets/javascripts/jira_connect/branches/constants.js2
-rw-r--r--app/assets/javascripts/jira_connect/branches/graphql/queries/get_project.query.graphql17
-rw-r--r--app/assets/javascripts/jira_connect/branches/graphql/queries/get_projects.query.graphql34
5 files changed, 282 insertions, 0 deletions
diff --git a/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue b/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue
new file mode 100644
index 00000000000..c1f57be7f97
--- /dev/null
+++ b/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue
@@ -0,0 +1,95 @@
+<script>
+import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui';
+import { __ } from '~/locale';
+import { PROJECTS_PER_PAGE } from '../constants';
+import getProjectsQuery from '../graphql/queries/get_projects.query.graphql';
+
+export default {
+ PROJECTS_PER_PAGE,
+ projectQueryPageInfo: {
+ endCursor: '',
+ },
+ components: {
+ GlDropdown,
+ GlDropdownItem,
+ GlSearchBoxByType,
+ GlLoadingIcon,
+ },
+ props: {
+ selectedProject: {
+ type: Object,
+ required: false,
+ default: null,
+ },
+ },
+ data() {
+ return {
+ initialProjectsLoading: true,
+ projectSearchQuery: '',
+ };
+ },
+ apollo: {
+ projects: {
+ query: getProjectsQuery,
+ variables() {
+ return {
+ search: this.projectSearchQuery,
+ first: this.$options.PROJECTS_PER_PAGE,
+ after: this.$options.projectQueryPageInfo.endCursor,
+ searchNamespaces: true,
+ sort: 'similarity',
+ };
+ },
+ update(data) {
+ return data?.projects?.nodes.filter((project) => !project.repository.empty) ?? [];
+ },
+ result() {
+ this.initialProjectsLoading = false;
+ },
+ error() {
+ this.onError({ message: __('Failed to load projects') });
+ },
+ },
+ },
+ computed: {
+ projectsLoading() {
+ return Boolean(this.$apollo.queries.projects.loading);
+ },
+ projectDropdownText() {
+ return this.selectedProject?.nameWithNamespace || __('Select a project');
+ },
+ },
+ methods: {
+ async onProjectSelect(project) {
+ this.$emit('change', project);
+ },
+ onError({ message } = {}) {
+ this.$emit('error', { message });
+ },
+ isProjectSelected(project) {
+ return project.id === this.selectedProject?.id;
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-dropdown :text="projectDropdownText" :loading="initialProjectsLoading">
+ <template #header>
+ <gl-search-box-by-type v-model.trim="projectSearchQuery" :debounce="250" />
+ </template>
+
+ <gl-loading-icon v-show="projectsLoading" />
+ <template v-if="!projectsLoading">
+ <gl-dropdown-item
+ v-for="project in projects"
+ :key="project.id"
+ is-check-item
+ :is-checked="isProjectSelected(project)"
+ @click="onProjectSelect(project)"
+ >
+ {{ project.nameWithNamespace }}
+ </gl-dropdown-item>
+ </template>
+ </gl-dropdown>
+</template>
diff --git a/app/assets/javascripts/jira_connect/branches/components/source_branch_dropdown.vue b/app/assets/javascripts/jira_connect/branches/components/source_branch_dropdown.vue
new file mode 100644
index 00000000000..0e2d8821f36
--- /dev/null
+++ b/app/assets/javascripts/jira_connect/branches/components/source_branch_dropdown.vue
@@ -0,0 +1,134 @@
+<script>
+import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui';
+import { __ } from '~/locale';
+import { BRANCHES_PER_PAGE } from '../constants';
+import getProjectQuery from '../graphql/queries/get_project.query.graphql';
+
+export default {
+ BRANCHES_PER_PAGE,
+ components: {
+ GlDropdown,
+ GlDropdownItem,
+ GlSearchBoxByType,
+ GlLoadingIcon,
+ },
+ props: {
+ selectedProject: {
+ type: Object,
+ required: false,
+ default: null,
+ },
+ selectedBranchName: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ },
+ data() {
+ return {
+ sourceBranchSearchQuery: '',
+ initialSourceBranchNamesLoading: false,
+ sourceBranchNamesLoading: false,
+ sourceBranchNames: [],
+ };
+ },
+ computed: {
+ hasSelectedProject() {
+ return Boolean(this.selectedProject);
+ },
+ hasSelectedSourceBranch() {
+ return Boolean(this.selectedBranchName);
+ },
+ branchDropdownText() {
+ return this.selectedBranchName || __('Select a branch');
+ },
+ },
+ watch: {
+ selectedProject: {
+ immediate: true,
+ async handler(selectedProject) {
+ if (!selectedProject) return;
+
+ this.initialSourceBranchNamesLoading = true;
+ await this.fetchSourceBranchNames({ projectPath: selectedProject.fullPath });
+ this.initialSourceBranchNamesLoading = false;
+ },
+ },
+ },
+ methods: {
+ onSourceBranchSelect(branchName) {
+ this.$emit('change', branchName);
+ },
+ onSourceBranchSearchQuery(branchSearchQuery) {
+ this.branchSearchQuery = branchSearchQuery;
+ this.fetchSourceBranchNames({
+ projectPath: this.selectedProject.fullPath,
+ searchPattern: this.branchSearchQuery,
+ });
+ },
+ onError({ message } = {}) {
+ this.$emit('error', { message });
+ },
+ async fetchSourceBranchNames({ projectPath, searchPattern } = {}) {
+ this.sourceBranchNamesLoading = true;
+ try {
+ const { data } = await this.$apollo.query({
+ query: getProjectQuery,
+ variables: {
+ projectPath,
+ branchNamesLimit: this.$options.BRANCHES_PER_PAGE,
+ branchNamesOffset: 0,
+ branchNamesSearchPattern: searchPattern ? `*${searchPattern}*` : '*',
+ },
+ });
+
+ const { branchNames, rootRef } = data?.project.repository || {};
+ this.sourceBranchNames = branchNames || [];
+
+ // Use root ref as the default selection
+ if (rootRef && !this.hasSelectedSourceBranch) {
+ this.onSourceBranchSelect(rootRef);
+ }
+ } catch (err) {
+ this.onError({
+ message: __('Something went wrong while fetching source branches.'),
+ });
+ } finally {
+ this.sourceBranchNamesLoading = false;
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-dropdown
+ :text="branchDropdownText"
+ :loading="initialSourceBranchNamesLoading"
+ :disabled="!hasSelectedProject"
+ :class="{ 'gl-font-monospace': hasSelectedSourceBranch }"
+ >
+ <template #header>
+ <gl-search-box-by-type
+ :debounce="250"
+ :value="sourceBranchSearchQuery"
+ @input="onSourceBranchSearchQuery"
+ />
+ </template>
+
+ <gl-loading-icon v-show="sourceBranchNamesLoading" />
+ <template v-if="!sourceBranchNamesLoading">
+ <gl-dropdown-item
+ v-for="branchName in sourceBranchNames"
+ v-show="!sourceBranchNamesLoading"
+ :key="branchName"
+ :is-checked="branchName === selectedBranchName"
+ is-check-item
+ class="gl-font-monospace"
+ @click="onSourceBranchSelect(branchName)"
+ >
+ {{ branchName }}
+ </gl-dropdown-item>
+ </template>
+ </gl-dropdown>
+</template>
diff --git a/app/assets/javascripts/jira_connect/branches/constants.js b/app/assets/javascripts/jira_connect/branches/constants.js
new file mode 100644
index 00000000000..987c8d356b4
--- /dev/null
+++ b/app/assets/javascripts/jira_connect/branches/constants.js
@@ -0,0 +1,2 @@
+export const BRANCHES_PER_PAGE = 20;
+export const PROJECTS_PER_PAGE = 20;
diff --git a/app/assets/javascripts/jira_connect/branches/graphql/queries/get_project.query.graphql b/app/assets/javascripts/jira_connect/branches/graphql/queries/get_project.query.graphql
new file mode 100644
index 00000000000..f3428e816d7
--- /dev/null
+++ b/app/assets/javascripts/jira_connect/branches/graphql/queries/get_project.query.graphql
@@ -0,0 +1,17 @@
+query getProject(
+ $projectPath: ID!
+ $branchNamesLimit: Int!
+ $branchNamesOffset: Int!
+ $branchNamesSearchPattern: String!
+) {
+ project(fullPath: $projectPath) {
+ repository {
+ branchNames(
+ limit: $branchNamesLimit
+ offset: $branchNamesOffset
+ searchPattern: $branchNamesSearchPattern
+ )
+ rootRef
+ }
+ }
+}
diff --git a/app/assets/javascripts/jira_connect/branches/graphql/queries/get_projects.query.graphql b/app/assets/javascripts/jira_connect/branches/graphql/queries/get_projects.query.graphql
new file mode 100644
index 00000000000..e768154e210
--- /dev/null
+++ b/app/assets/javascripts/jira_connect/branches/graphql/queries/get_projects.query.graphql
@@ -0,0 +1,34 @@
+#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
+
+query getProjects(
+ $search: String!
+ $after: String = ""
+ $first: Int!
+ $searchNamespaces: Boolean = false
+ $sort: String
+ $membership: Boolean = true
+) {
+ projects(
+ search: $search
+ after: $after
+ first: $first
+ membership: $membership
+ searchNamespaces: $searchNamespaces
+ sort: $sort
+ ) {
+ nodes {
+ id
+ name
+ nameWithNamespace
+ fullPath
+ avatarUrl
+ path
+ repository {
+ empty
+ }
+ }
+ pageInfo {
+ ...PageInfo
+ }
+ }
+}