Commit 39e416cf authored by Nick Kipling's avatar Nick Kipling

Adds filter by name to packages list

Created new packages_filter component
Added logic to trigger filter from api
Updated Vuex store to support new parameter
Added tests
Updated pot
parent b67ee058
---
title: Adds filter by name to the packages list
merge_request: 27586
author:
type: added
<script>
import { GlSearchBoxByClick } from '@gitlab/ui';
import { mapActions } from 'vuex';
export default {
components: {
GlSearchBoxByClick,
},
methods: {
...mapActions(['setFilter']),
onInput(query) {
this.setFilter(query);
},
onSubmit() {
this.$emit('filter');
},
},
};
</script>
<template>
<gl-search-box-by-click
:placeholder="s__('PackageRegistry|Filter by name')"
@submit="onSubmit"
@input="onInput"
/>
</template>
......@@ -2,6 +2,7 @@
import { mapActions, mapState } from 'vuex';
import { GlEmptyState, GlTab, GlTabs } from '@gitlab/ui';
import { s__, sprintf } from '~/locale';
import PackageFilter from './packages_filter.vue';
import PackageList from './packages_list.vue';
import PackageSort from './packages_sort.vue';
import { PACKAGE_REGISTRY_TABS } from '../constants';
......@@ -11,6 +12,7 @@ export default {
GlEmptyState,
GlTab,
GlTabs,
PackageFilter,
PackageList,
PackageSort,
},
......@@ -70,7 +72,8 @@ export default {
<template>
<gl-tabs @input="tabChanged">
<template #tabs-end>
<div class="align-self-center ml-auto">
<div class="d-flex align-self-center ml-auto">
<package-filter class="mr-1" @filter="requestPackagesList" />
<package-sort @sort:changed="requestPackagesList" />
</div>
</template>
......
......@@ -15,6 +15,7 @@ export const setInitialState = ({ commit }, data) => commit(types.SET_INITIAL_ST
export const setLoading = ({ commit }, data) => commit(types.SET_MAIN_LOADING, data);
export const setSorting = ({ commit }, data) => commit(types.SET_SORTING, data);
export const setSelectedType = ({ commit }, data) => commit(types.SET_SELECTED_TYPE, data);
export const setFilter = ({ commit }, data) => commit(types.SET_FILTER, data);
export const receivePackagesListSuccess = ({ commit }, { data, headers }) => {
commit(types.SET_PACKAGE_LIST_SUCCESS, data);
......@@ -26,12 +27,17 @@ export const requestPackagesList = ({ dispatch, state }, params = {}) => {
const { page = DEFAULT_PAGE, per_page = DEFAULT_PAGE_SIZE } = params;
const { sort, orderBy } = state.sorting;
const type = state.selectedType?.type?.toLowerCase();
const packageType = { package_type: type };
const nameFilter = state.filterQuery?.toLowerCase();
const packageName = { package_name: nameFilter };
const apiMethod = state.config.isGroupPage ? 'groupPackages' : 'projectPackages';
return Api[apiMethod](state.config.resourceId, {
params: { page, per_page, sort, order_by: orderBy, ...packageType },
params: { page, per_page, sort, order_by: orderBy, ...packageType, ...packageName },
})
.then(({ data, headers }) => {
dispatch('receivePackagesListSuccess', { data, headers });
......
......@@ -5,3 +5,4 @@ export const SET_PAGINATION = 'SET_PAGINATION';
export const SET_MAIN_LOADING = 'SET_MAIN_LOADING';
export const SET_SORTING = 'SET_SORTING';
export const SET_SELECTED_TYPE = 'SET_SELECTED_TYPE';
export const SET_FILTER = 'SET_FILTER';
......@@ -30,4 +30,8 @@ export default {
[types.SET_SELECTED_TYPE](state, type) {
state.selectedType = type;
},
[types.SET_FILTER](state, query) {
state.filterQuery = query;
},
};
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`packages_filter renders 1`] = `
<gl-search-box-by-click-stub
clearbuttontitle="Clear"
clearrecentsearchestext="Clear recent searches"
closebuttontitle="Close"
norecentsearchestext="You don't have any recent searches"
placeholder="Filter by name"
recentsearchesheader="Recent searches"
value=""
/>
`;
......@@ -350,8 +350,12 @@ exports[`packages_list_app renders 1`] = `
</template>
<template>
<div
class="align-self-center ml-auto"
class="d-flex align-self-center ml-auto"
>
<package-filter-stub
class="mr-1"
/>
<package-sort-stub />
</div>
</template>
......
import Vuex from 'vuex';
import { GlSearchBoxByClick } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import PackagesFilter from 'ee/packages/list/components/packages_filter.vue';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('packages_filter', () => {
let wrapper;
let store;
const findGlSearchBox = () => wrapper.find(GlSearchBoxByClick);
const mountComponent = () => {
store = new Vuex.Store();
store.dispatch = jest.fn();
wrapper = shallowMount(PackagesFilter, {
localVue,
store,
});
};
beforeEach(mountComponent);
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('renders', () => {
expect(wrapper.element).toMatchSnapshot();
});
describe('emits events', () => {
it('sets the filter value in the store on input', () => {
const searchString = 'foo';
findGlSearchBox().vm.$emit('input', searchString);
expect(store.dispatch).toHaveBeenCalledWith('setFilter', searchString);
});
it('emits the filter event when search box is submitted', () => {
findGlSearchBox().vm.$emit('submit');
expect(wrapper.emitted('filter')).toBeTruthy();
});
});
});
......@@ -228,4 +228,17 @@ describe('Actions Package list store', () => {
);
});
});
describe('setFilter', () => {
it('should commit SET_FILTER', done => {
testAction(
actions.setFilter,
'foo',
null,
[{ type: types.SET_FILTER, payload: 'foo' }],
[],
done,
);
});
});
});
......@@ -84,4 +84,11 @@ describe('Mutations Registry Store', () => {
expect(mockState.selectedType).toEqual({ type: 'maven' });
});
});
describe('SET_FILTER', () => {
it('should set the filter query', () => {
mutations[types.SET_FILTER](mockState, 'foo');
expect(mockState.filterQuery).toEqual('foo');
});
});
});
......@@ -13966,6 +13966,9 @@ msgstr ""
msgid "PackageRegistry|Delete package"
msgstr ""
msgid "PackageRegistry|Filter by name"
msgstr ""
msgid "PackageRegistry|For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}."
msgstr ""
......
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