Commit 9bc13613 authored by Olena Horal-Koretska's avatar Olena Horal-Koretska

Merge branch '338395-sync-pagination-params-to-url-integration-overrides' into 'master'

Integration overrides: sync page to URL params

See merge request gitlab-org/gitlab!75317
parents 71eb80a6 8089a2fe
......@@ -6,8 +6,12 @@ import { DEFAULT_PER_PAGE } from '~/api';
import { fetchOverrides } from '~/integrations/overrides/api';
import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
import { truncateNamespace } from '~/lib/utils/text_utility';
import { getParameterByName } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale';
import ProjectAvatar from '~/vue_shared/components/project_avatar.vue';
import UrlSync from '~/vue_shared/components/url_sync.vue';
const DEFAULT_PAGE = 1;
export default {
name: 'IntegrationOverrides',
......@@ -18,6 +22,7 @@ export default {
GlTable,
GlAlert,
ProjectAvatar,
UrlSync,
},
props: {
overridesPath: {
......@@ -35,7 +40,7 @@ export default {
return {
isLoading: true,
overrides: [],
page: 1,
page: DEFAULT_PAGE,
totalItems: 0,
errorMessage: null,
};
......@@ -44,12 +49,21 @@ export default {
showPagination() {
return this.totalItems > this.$options.DEFAULT_PER_PAGE && this.overrides.length > 0;
},
query() {
return {
page: this.page,
};
},
},
mounted() {
this.loadOverrides();
created() {
const initialPage = this.getInitialPage();
this.loadOverrides(initialPage);
},
methods: {
loadOverrides(page = this.page) {
getInitialPage() {
return getParameterByName('page') ?? DEFAULT_PAGE;
},
loadOverrides(page) {
this.isLoading = true;
this.errorMessage = null;
......@@ -119,14 +133,16 @@ export default {
</template>
</gl-table>
<div class="gl-display-flex gl-justify-content-center gl-mt-5">
<gl-pagination
v-if="showPagination"
:per-page="$options.DEFAULT_PER_PAGE"
:total-items="totalItems"
:value="page"
:disabled="isLoading"
@input="loadOverrides"
/>
<template v-if="showPagination">
<gl-pagination
:per-page="$options.DEFAULT_PER_PAGE"
:total-items="totalItems"
:value="page"
:disabled="isLoading"
@input="loadOverrides"
/>
<url-sync :query="query" />
</template>
</div>
</div>
</template>
......@@ -8,6 +8,7 @@ import IntegrationOverrides from '~/integrations/overrides/components/integratio
import axios from '~/lib/utils/axios_utils';
import httpStatus from '~/lib/utils/http_status';
import ProjectAvatar from '~/vue_shared/components/project_avatar.vue';
import UrlSync from '~/vue_shared/components/url_sync.vue';
const mockOverrides = Array(DEFAULT_PER_PAGE * 3)
.fill(1)
......@@ -26,9 +27,10 @@ describe('IntegrationOverrides', () => {
overridesPath: 'mock/overrides',
};
const createComponent = ({ mountFn = shallowMount } = {}) => {
const createComponent = ({ mountFn = shallowMount, stubs } = {}) => {
wrapper = mountFn(IntegrationOverrides, {
propsData: defaultProps,
stubs,
});
};
......@@ -127,27 +129,58 @@ describe('IntegrationOverrides', () => {
});
describe('pagination', () => {
it('triggers fetch when `input` event is emitted', async () => {
createComponent();
jest.spyOn(axios, 'get');
await waitForPromises();
describe('when total items does not exceed the page limit', () => {
it('does not render', async () => {
mockAxios.onGet(defaultProps.overridesPath).reply(httpStatus.OK, [mockOverrides[0]], {
'X-TOTAL': DEFAULT_PER_PAGE - 1,
'X-PAGE': 1,
});
createComponent();
// wait for initial load
await waitForPromises();
await findPagination().vm.$emit('input', 2);
expect(axios.get).toHaveBeenCalledWith(defaultProps.overridesPath, {
params: { page: 2, per_page: DEFAULT_PER_PAGE },
expect(findPagination().exists()).toBe(false);
});
});
it('does not render with <=1 page', async () => {
mockAxios.onGet(defaultProps.overridesPath).reply(httpStatus.OK, [mockOverrides[0]], {
'X-TOTAL': 1,
'X-PAGE': 1,
describe('when total items exceeds the page limit', () => {
const mockPage = 2;
beforeEach(async () => {
createComponent({ stubs: { UrlSync } });
mockAxios.onGet(defaultProps.overridesPath).reply(httpStatus.OK, [mockOverrides[0]], {
'X-TOTAL': DEFAULT_PER_PAGE * 2,
'X-PAGE': mockPage,
});
// wait for initial load
await waitForPromises();
});
createComponent();
await waitForPromises();
it('renders', () => {
expect(findPagination().exists()).toBe(true);
});
expect(findPagination().exists()).toBe(false);
describe('when navigating to a page', () => {
beforeEach(async () => {
jest.spyOn(axios, 'get');
// trigger a page change
await findPagination().vm.$emit('input', mockPage);
});
it('performs GET request with correct params', () => {
expect(axios.get).toHaveBeenCalledWith(defaultProps.overridesPath, {
params: { page: mockPage, per_page: DEFAULT_PER_PAGE },
});
});
it('updates `page` URL parameter', () => {
expect(window.location.search).toBe(`?page=${mockPage}`);
});
});
});
});
});
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