Commit 039b1145 authored by David Barr's avatar David Barr

Add default branch to Pipelines page filter if no search term provided

Make the default branch name appear at the top of the dropdown list
when using the branch name filter on the Pipelines page with no
search term.

Changelog: added
parent 3e060e01
......@@ -98,6 +98,11 @@ export default {
type: String,
required: true,
},
defaultBranchName: {
type: String,
required: false,
default: null,
},
params: {
type: Object,
required: true,
......@@ -347,6 +352,7 @@ export default {
<pipelines-filtered-search
class="gl-display-flex gl-flex-grow-1 gl-mr-4"
:project-id="projectId"
:default-branch-name="defaultBranchName"
:params="validatedParams"
@filterPipelines="filterPipelines"
/>
......
......@@ -24,6 +24,11 @@ export default {
type: String,
required: true,
},
defaultBranchName: {
type: String,
required: false,
default: null,
},
params: {
type: Object,
required: true,
......@@ -57,6 +62,7 @@ export default {
token: PipelineBranchNameToken,
operators: OPERATOR_IS_ONLY,
projectId: this.projectId,
defaultBranchName: this.defaultBranchName,
disabled: this.selectedTypes.includes(this.$options.tagType),
},
{
......
......@@ -35,6 +35,13 @@ export default {
Api.branches(this.config.projectId, searchterm)
.then(({ data }) => {
this.branches = data.map((branch) => branch.name);
if (!searchterm && this.config.defaultBranchName) {
// Shift the default branch to the top of the list
this.branches = this.branches.filter(
(branch) => branch !== this.config.defaultBranchName,
);
this.branches.unshift(this.config.defaultBranchName);
}
this.loading = false;
})
.catch((err) => {
......
......@@ -36,6 +36,7 @@ export const initPipelinesIndex = (selector = '#pipelines-list-vue') => {
ciLintPath,
resetCachePath,
projectId,
defaultBranchName,
params,
ciRunnerSettingsPath,
anyRunnersAvailable,
......@@ -75,6 +76,7 @@ export const initPipelinesIndex = (selector = '#pipelines-list-vue') => {
ciLintPath,
resetCachePath,
projectId,
defaultBranchName,
params: JSON.parse(params),
ciRunnerSettingsPath,
anyRunnersAvailable: parseBoolean(anyRunnersAvailable),
......
......@@ -84,6 +84,7 @@ module Ci
data = {
endpoint: list_url,
project_id: project.id,
default_branch_name: project.default_branch,
params: params.to_json,
artifacts_endpoint: downloadable_artifacts_project_pipeline_path(project, artifacts_endpoint_placeholder, format: :json),
artifacts_endpoint_placeholder: artifacts_endpoint_placeholder,
......
......@@ -27,6 +27,7 @@ describe('Pipelines filtered search', () => {
wrapper = mount(PipelinesFilteredSearch, {
propsData: {
projectId: '21',
defaultBranchName: 'main',
params,
},
attachTo: document.body,
......@@ -69,6 +70,7 @@ describe('Pipelines filtered search', () => {
title: 'Branch name',
unique: true,
projectId: '21',
defaultBranchName: 'main',
operators: OPERATOR_IS_ONLY,
});
......
......@@ -27,6 +27,7 @@ jest.mock('~/flash');
const mockProjectPath = 'twitter/flight';
const mockProjectId = '21';
const mockDefaultBranchName = 'main';
const mockPipelinesEndpoint = `/${mockProjectPath}/pipelines.json`;
const mockPipelinesIds = mockPipelinesResponse.pipelines.map(({ id }) => id);
const mockPipelineWithStages = mockPipelinesResponse.pipelines.find(
......@@ -85,6 +86,7 @@ describe('Pipelines', () => {
propsData: {
store: new Store(),
projectId: mockProjectId,
defaultBranchName: mockDefaultBranchName,
endpoint: mockPipelinesEndpoint,
params: {},
...props,
......
import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlLoadingIcon } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMount } from '@vue/test-utils';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
import PipelineBranchNameToken from '~/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue';
import { branches, mockBranchesAfterMap } from '../mock_data';
......@@ -10,6 +12,8 @@ describe('Pipeline Branch Name Token', () => {
const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
const getBranchSuggestions = () =>
findAllFilteredSearchSuggestions().wrappers.map((w) => w.text());
const stubs = {
GlFilteredSearchToken: {
......@@ -24,6 +28,7 @@ describe('Pipeline Branch Name Token', () => {
title: 'Branch name',
unique: true,
projectId: '21',
defaultBranchName: null,
disabled: false,
},
value: {
......@@ -31,6 +36,19 @@ describe('Pipeline Branch Name Token', () => {
},
};
const optionsWithDefaultBranchName = (options) => {
return {
propsData: {
...defaultProps,
config: {
...defaultProps.config,
defaultBranchName: 'main',
},
},
...options,
};
};
const createComponent = (options, data) => {
wrapper = shallowMount(PipelineBranchNameToken, {
propsData: {
......@@ -94,5 +112,34 @@ describe('Pipeline Branch Name Token', () => {
expect(findAllFilteredSearchSuggestions()).toHaveLength(mockBranches.length);
});
it('shows the default branch first if no branch was searched for', async () => {
const mockBranches = [{ name: 'branch-1' }];
jest.spyOn(Api, 'branches').mockResolvedValue({ data: mockBranches });
createComponent(optionsWithDefaultBranchName({ stubs }), { loading: false });
await nextTick();
expect(getBranchSuggestions()).toEqual(['main', 'branch-1']);
});
it('does not show the default branch if a search term was provided', async () => {
const mockBranches = [{ name: 'branch-1' }];
jest.spyOn(Api, 'branches').mockResolvedValue({ data: mockBranches });
createComponent(optionsWithDefaultBranchName(), { loading: false });
findFilteredSearchToken().vm.$emit('input', { data: 'branch-1' });
await waitForPromises();
expect(getBranchSuggestions()).toEqual(['branch-1']);
});
it('shows the default branch only once if it appears in the results', async () => {
const mockBranches = [{ name: 'main' }];
jest.spyOn(Api, 'branches').mockResolvedValue({ data: mockBranches });
createComponent(optionsWithDefaultBranchName({ stubs }), { loading: false });
await nextTick();
expect(getBranchSuggestions()).toEqual(['main']);
});
});
});
......@@ -106,6 +106,7 @@ RSpec.describe Ci::PipelinesHelper do
it 'has the expected keys' do
expect(subject.keys).to match_array([:endpoint,
:project_id,
:default_branch_name,
:params,
:artifacts_endpoint,
:artifacts_endpoint_placeholder,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment