Commit ac1f366c authored by Enrique Alcántara's avatar Enrique Alcántara

Merge branch '229842-merge-request-analytics-paginate-data-table' into 'master'

Merge Request Analytics: Paginate data table

See merge request gitlab-org/gitlab!42806
parents 9d18fb55 287480ad
import { __ } from '~/locale'; import { __ } from '~/locale';
export const DEFAULT_NUMBER_OF_DAYS = 365; export const DEFAULT_NUMBER_OF_DAYS = 365;
export const MAX_RECORDS = 100; export const PER_PAGE = 20;
export const ASSIGNEES_VISIBLE = 2; export const ASSIGNEES_VISIBLE = 2;
export const AVATAR_SIZE = 24; export const AVATAR_SIZE = 24;
......
query( #import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
query getThroughputTableData(
$fullPath: ID! $fullPath: ID!
$startDate: Time! $startDate: Time!
$endDate: Time! $endDate: Time!
$limit: Int!
$labels: [String!] $labels: [String!]
$authorUsername: String $authorUsername: String
$assigneeUsername: String $assigneeUsername: String
$milestoneTitle: String $milestoneTitle: String
$sourceBranches: [String!] $sourceBranches: [String!]
$targetBranches: [String!] $targetBranches: [String!]
$firstPageSize: Int
$lastPageSize: Int
$prevPageCursor: String = ""
$nextPageCursor: String = ""
) { ) {
project(fullPath: $fullPath) { project(fullPath: $fullPath) {
mergeRequests( mergeRequests(
first: $limit first: $firstPageSize
last: $lastPageSize
after: $nextPageCursor
before: $prevPageCursor
mergedAfter: $startDate mergedAfter: $startDate
mergedBefore: $endDate mergedBefore: $endDate
sort: MERGED_AT_DESC sort: MERGED_AT_DESC
...@@ -23,6 +31,9 @@ query( ...@@ -23,6 +31,9 @@ query(
sourceBranches: $sourceBranches sourceBranches: $sourceBranches
targetBranches: $targetBranches targetBranches: $targetBranches
) { ) {
pageInfo {
...PageInfo
}
nodes { nodes {
iid iid
title title
......
import Vuex from 'vuex'; import Vuex from 'vuex';
import { mount, shallowMount, createLocalVue } from '@vue/test-utils'; import { mount, shallowMount, createLocalVue } from '@vue/test-utils';
import { GlAlert, GlLoadingIcon, GlTable, GlIcon, GlAvatarsInline } from '@gitlab/ui'; import { GlAlert, GlLoadingIcon, GlTable, GlIcon, GlAvatarsInline, GlPagination } from '@gitlab/ui';
import store from 'ee/analytics/merge_request_analytics/store'; import store from 'ee/analytics/merge_request_analytics/store';
import ThroughputTable from 'ee/analytics/merge_request_analytics/components/throughput_table.vue'; import ThroughputTable from 'ee/analytics/merge_request_analytics/components/throughput_table.vue';
import { import {
...@@ -13,6 +13,7 @@ import { ...@@ -13,6 +13,7 @@ import {
endDate, endDate,
fullPath, fullPath,
throughputTableHeaders, throughputTableHeaders,
pageInfo,
} from '../mock_data'; } from '../mock_data';
const localVue = createLocalVue(); const localVue = createLocalVue();
...@@ -58,12 +59,10 @@ describe('ThroughputTable', () => { ...@@ -58,12 +59,10 @@ describe('ThroughputTable', () => {
const additionalData = data => { const additionalData = data => {
wrapper.setData({ wrapper.setData({
throughputTableData: [ throughputTableData: {
{ list: [{ ...throughputTableData[0], ...data }],
...throughputTableData[0], pageInfo,
...data, },
},
],
}); });
}; };
...@@ -77,6 +76,18 @@ describe('ThroughputTable', () => { ...@@ -77,6 +76,18 @@ describe('ThroughputTable', () => {
const findColSubComponent = (colTestId, childComponent) => const findColSubComponent = (colTestId, childComponent) =>
findCol(colTestId).find(childComponent); findCol(colTestId).find(childComponent);
const findPagination = () => wrapper.find(GlPagination);
const findPrevious = () =>
findPagination()
.findAll('.page-item')
.at(0);
const findNext = () =>
findPagination()
.findAll('.page-item')
.at(1);
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null; wrapper = null;
...@@ -101,6 +112,10 @@ describe('ThroughputTable', () => { ...@@ -101,6 +112,10 @@ describe('ThroughputTable', () => {
it('does not display the table', () => { it('does not display the table', () => {
displaysComponent(GlTable, false); displaysComponent(GlTable, false);
}); });
it('does not display the pagination', () => {
displaysComponent(GlPagination, false);
});
}); });
describe('while loading', () => { describe('while loading', () => {
...@@ -132,7 +147,12 @@ describe('ThroughputTable', () => { ...@@ -132,7 +147,12 @@ describe('ThroughputTable', () => {
describe('with data', () => { describe('with data', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createComponent({ func: mount }); wrapper = createComponent({ func: mount });
wrapper.setData({ throughputTableData }); wrapper.setData({
throughputTableData: {
list: throughputTableData,
pageInfo,
},
});
}); });
it('displays the table', () => { it('displays the table', () => {
...@@ -147,6 +167,10 @@ describe('ThroughputTable', () => { ...@@ -147,6 +167,10 @@ describe('ThroughputTable', () => {
displaysComponent(GlAlert, false); displaysComponent(GlAlert, false);
}); });
it('displays the pagination', () => {
displaysComponent(GlPagination, true);
});
describe('table fields', () => { describe('table fields', () => {
it('displays the correct table headers', () => { it('displays the correct table headers', () => {
const headers = findTable().findAll(`[data-testid="${TEST_IDS.TABLE_HEADERS}"]`); const headers = findTable().findAll(`[data-testid="${TEST_IDS.TABLE_HEADERS}"]`);
...@@ -350,6 +374,60 @@ describe('ThroughputTable', () => { ...@@ -350,6 +374,60 @@ describe('ThroughputTable', () => {
}); });
}); });
describe('pagination', () => {
beforeEach(() => {
wrapper = createComponent({ func: mount });
wrapper.setData({
throughputTableData: {
list: throughputTableData,
pageInfo,
},
});
});
it('disables the prev button on the first page', () => {
expect(findPrevious().classes()).toContain('disabled');
expect(findNext().classes()).not.toContain('disabled');
});
it('disables the next button on the last page', async () => {
wrapper.setData({
pagination: {
currentPage: 3,
},
throughputTableData: {
pageInfo: {
hasNextPage: false,
},
},
});
await wrapper.vm.$nextTick();
expect(findPrevious().classes()).not.toContain('disabled');
expect(findNext().classes()).toContain('disabled');
});
it('shows the prev and next buttons on middle pages', async () => {
wrapper.setData({
pagination: {
currentPage: 2,
},
throughputTableData: {
pageInfo: {
hasNextPage: true,
hasPrevPage: true,
},
},
});
await wrapper.vm.$nextTick();
expect(findPrevious().classes()).not.toContain('disabled');
expect(findNext().classes()).not.toContain('disabled');
});
});
describe('with errors', () => { describe('with errors', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createComponent(); wrapper = createComponent();
......
...@@ -57,6 +57,13 @@ export const throughputTableHeaders = [ ...@@ -57,6 +57,13 @@ export const throughputTableHeaders = [
'Assignees', 'Assignees',
]; ];
export const pageInfo = {
hasNextPage: true,
hasPreviousPage: false,
startCursor: 'abc',
endCursor: 'bcd',
};
export const throughputTableData = [ export const throughputTableData = [
{ {
iid: '1', iid: '1',
......
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