Commit 91d1c713 authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch '327658-namespace-filter-works-only-after-3-characters' into 'master'

Jira Connect: show all namespaces when search term length < 3

See merge request gitlab-org/gitlab!61099
parents 42ef9329 c98ebffc
<script> <script>
import { GlLoadingIcon, GlPagination, GlAlert, GlSearchBoxByType } from '@gitlab/ui'; import { GlLoadingIcon, GlPagination, GlAlert, GlSearchBoxByType } from '@gitlab/ui';
import { fetchGroups } from '~/jira_connect/api'; import { fetchGroups } from '~/jira_connect/api';
import { DEFAULT_GROUPS_PER_PAGE } from '~/jira_connect/constants'; import { DEFAULT_GROUPS_PER_PAGE, MINIMUM_SEARCH_TERM_LENGTH } from '~/jira_connect/constants';
import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils'; import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import GroupsListItem from './groups_list_item.vue'; import GroupsListItem from './groups_list_item.vue';
...@@ -27,6 +27,7 @@ export default { ...@@ -27,6 +27,7 @@ export default {
page: 1, page: 1,
totalItems: 0, totalItems: 0,
errorMessage: null, errorMessage: null,
searchTerm: '',
}; };
}, },
computed: { computed: {
...@@ -40,13 +41,17 @@ export default { ...@@ -40,13 +41,17 @@ export default {
}); });
}, },
methods: { methods: {
loadGroups({ searchTerm } = {}) { loadGroups() {
this.isLoadingMore = true; // fetchGroups returns no results for search terms 0 < {length} < 3.
// The desired UX is to return the unfiltered results for searches {length} < 3.
// Here, we set the search to an empty string if {length} < 3
const search = this.searchTerm?.length < MINIMUM_SEARCH_TERM_LENGTH ? '' : this.searchTerm;
this.isLoadingMore = true;
return fetchGroups(this.groupsPath, { return fetchGroups(this.groupsPath, {
page: this.page, page: this.page,
perPage: this.$options.DEFAULT_GROUPS_PER_PAGE, perPage: this.$options.DEFAULT_GROUPS_PER_PAGE,
search: searchTerm, search,
}) })
.then((response) => { .then((response) => {
const { page, total } = parseIntPagination(normalizeHeaders(response.headers)); const { page, total } = parseIntPagination(normalizeHeaders(response.headers));
...@@ -62,7 +67,11 @@ export default { ...@@ -62,7 +67,11 @@ export default {
}); });
}, },
onGroupSearch(searchTerm) { onGroupSearch(searchTerm) {
return this.loadGroups({ searchTerm }); // keep a copy of the search term for pagination
this.searchTerm = searchTerm;
// reset the current page
this.page = 1;
return this.loadGroups();
}, },
}, },
DEFAULT_GROUPS_PER_PAGE, DEFAULT_GROUPS_PER_PAGE,
......
export const DEFAULT_GROUPS_PER_PAGE = 10; export const DEFAULT_GROUPS_PER_PAGE = 10;
export const ALERT_LOCALSTORAGE_KEY = 'gitlab_alert'; export const ALERT_LOCALSTORAGE_KEY = 'gitlab_alert';
export const MINIMUM_SEARCH_TERM_LENGTH = 3;
---
title: Require 3 or more characters in search term when searching groups in Jira Connect
app
merge_request: 61099
author:
type: changed
...@@ -143,14 +143,14 @@ describe('GroupsList', () => { ...@@ -143,14 +143,14 @@ describe('GroupsList', () => {
}); });
it('calls `fetchGroups` with search term', () => { it('calls `fetchGroups` with search term', () => {
expect(fetchGroups).toHaveBeenCalledWith(mockGroupsPath, { expect(fetchGroups).toHaveBeenLastCalledWith(mockGroupsPath, {
page: 1, page: 1,
perPage: 10, perPage: DEFAULT_GROUPS_PER_PAGE,
search: mockSearchTeam, search: mockSearchTeam,
}); });
}); });
it('disables GroupListItems', async () => { it('disables GroupListItems', () => {
findAllItems().wrappers.forEach((groupListItem) => { findAllItems().wrappers.forEach((groupListItem) => {
expect(groupListItem.props('disabled')).toBe(true); expect(groupListItem.props('disabled')).toBe(true);
}); });
...@@ -178,6 +178,73 @@ describe('GroupsList', () => { ...@@ -178,6 +178,73 @@ describe('GroupsList', () => {
expect(findFirstItem().props('group')).toBe(mockGroup1); expect(findFirstItem().props('group')).toBe(mockGroup1);
}); });
}); });
it.each`
userSearchTerm | finalSearchTerm
${'gitl'} | ${'gitl'}
${'git'} | ${'git'}
${'gi'} | ${''}
${'g'} | ${''}
${''} | ${''}
${undefined} | ${undefined}
`(
'searches for "$finalSearchTerm" when user enters "$userSearchTerm"',
async ({ userSearchTerm, finalSearchTerm }) => {
fetchGroups.mockResolvedValue({
data: [mockGroup1],
headers: { 'X-PAGE': 1, 'X-TOTAL': 1 },
});
createComponent();
await waitForPromises();
const searchBox = findSearchBox();
searchBox.vm.$emit('input', userSearchTerm);
expect(fetchGroups).toHaveBeenLastCalledWith(mockGroupsPath, {
page: 1,
perPage: DEFAULT_GROUPS_PER_PAGE,
search: finalSearchTerm,
});
},
);
});
describe('when page=2', () => {
beforeEach(async () => {
const totalItems = DEFAULT_GROUPS_PER_PAGE + 1;
const mockGroups = createMockGroups(totalItems);
fetchGroups.mockResolvedValue({
headers: { 'X-TOTAL': totalItems, 'X-PAGE': 1 },
data: mockGroups,
});
createComponent();
await waitForPromises();
const paginationEl = findPagination();
paginationEl.vm.$emit('input', 2);
});
it('should load results for page 2', () => {
expect(fetchGroups).toHaveBeenLastCalledWith(mockGroupsPath, {
page: 2,
perPage: DEFAULT_GROUPS_PER_PAGE,
search: '',
});
});
it('resets page to 1 on search `input` event', () => {
const mockSearchTerm = 'gitlab';
const searchBox = findSearchBox();
searchBox.vm.$emit('input', mockSearchTerm);
expect(fetchGroups).toHaveBeenLastCalledWith(mockGroupsPath, {
page: 1,
perPage: DEFAULT_GROUPS_PER_PAGE,
search: mockSearchTerm,
});
});
}); });
}); });
...@@ -195,7 +262,6 @@ describe('GroupsList', () => { ...@@ -195,7 +262,6 @@ describe('GroupsList', () => {
data: mockGroups, data: mockGroups,
}); });
createComponent(); createComponent();
await waitForPromises(); await waitForPromises();
const paginationEl = findPagination(); const paginationEl = findPagination();
...@@ -218,13 +284,14 @@ describe('GroupsList', () => { ...@@ -218,13 +284,14 @@ describe('GroupsList', () => {
await waitForPromises(); await waitForPromises();
}); });
it('executes `fetchGroups` with correct arguments', async () => { it('executes `fetchGroups` with correct arguments', () => {
const paginationEl = findPagination(); const paginationEl = findPagination();
paginationEl.vm.$emit('input', 2); paginationEl.vm.$emit('input', 2);
expect(fetchGroups).toHaveBeenCalledWith(mockGroupsPath, { expect(fetchGroups).toHaveBeenLastCalledWith(mockGroupsPath, {
page: 2, page: 2,
perPage: 10, perPage: DEFAULT_GROUPS_PER_PAGE,
search: '',
}); });
}); });
}); });
......
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