Commit 02b58e50 authored by Emily Ring's avatar Emily Ring Committed by Ezekiel Kigbo

Add pagination to agent cluster list

Add pagination to clusters_list vue
Update associated tests
parent 71c1db7a
<script>
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
import { GlAlert, GlKeysetPagination, GlLoadingIcon } from '@gitlab/ui';
import AgentEmptyState from './agent_empty_state.vue';
import AgentTable from './agent_table.vue';
import getAgentsQuery from '../graphql/queries/get_agents.query.graphql';
import { MAX_LIST_COUNT } from '../constants';
export default {
apollo: {
......@@ -12,13 +13,12 @@ export default {
return {
defaultBranchName: this.defaultBranchName,
projectPath: this.projectPath,
...this.cursor,
};
},
update: (data) => {
return {
list: data?.project?.clusterAgents?.nodes,
folders: data?.project?.repository?.tree?.trees?.nodes,
};
update(data) {
this.updateTreeList(data);
return data;
},
},
},
......@@ -26,6 +26,7 @@ export default {
AgentEmptyState,
AgentTable,
GlAlert,
GlKeysetPagination,
GlLoadingIcon,
},
props: {
......@@ -43,23 +44,67 @@ export default {
type: String,
},
},
data() {
return {
cursor: {
first: MAX_LIST_COUNT,
last: null,
},
folderList: {},
};
},
computed: {
isLoading() {
return this.$apollo.queries.agents.loading;
},
agentList() {
let list = this.agents?.list;
const configFolders = this.agents?.folders;
let list = this.agents?.project?.clusterAgents?.nodes;
if (list && configFolders) {
if (list) {
list = list.map((agent) => {
const configFolder = configFolders.find(({ name }) => name === agent.name);
const configFolder = this.folderList[agent.name];
return { ...agent, configFolder };
});
}
return list;
},
agentPageInfo() {
return this.agents?.project?.clusterAgents?.pageInfo || {};
},
isLoading() {
return this.$apollo.queries.agents.loading;
},
showPagination() {
return this.agentPageInfo.hasPreviousPage || this.agentPageInfo.hasNextPage;
},
treePageInfo() {
return this.agents?.project?.repository?.tree?.trees?.pageInfo || {};
},
},
methods: {
nextPage() {
this.cursor = {
first: MAX_LIST_COUNT,
last: null,
afterAgent: this.agentPageInfo.endCursor,
afterTree: this.treePageInfo.endCursor,
};
},
prevPage() {
this.cursor = {
first: null,
last: MAX_LIST_COUNT,
beforeAgent: this.agentPageInfo.startCursor,
beforeTree: this.treePageInfo.endCursor,
};
},
updateTreeList(data) {
const configFolders = data?.project?.repository?.tree?.trees?.nodes;
if (configFolders) {
configFolders.forEach((folder) => {
this.folderList[folder.name] = folder;
});
}
},
},
};
</script>
......@@ -68,7 +113,13 @@ export default {
<gl-loading-icon v-if="isLoading" size="md" class="gl-mt-3" />
<section v-else-if="agentList" class="gl-mt-3">
<AgentTable v-if="agentList.length" :agents="agentList" />
<div v-if="agentList.length">
<AgentTable :agents="agentList" />
<div v-if="showPagination" class="gl-display-flex gl-justify-content-center gl-mt-5">
<gl-keyset-pagination v-bind="agentPageInfo" @prev="prevPage" @next="nextPage" />
</div>
</div>
<AgentEmptyState v-else :image="emptyStateImage" />
</section>
......
query getAgents($defaultBranchName: String!, $projectPath: ID!) {
#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
query getAgents(
$defaultBranchName: String!
$projectPath: ID!
$first: Int
$last: Int
$afterAgent: String
$afterTree: String
$beforeAgent: String
$beforeTree: String
) {
project(fullPath: $projectPath) {
clusterAgents {
clusterAgents(first: $first, last: $last, before: $beforeAgent, after: $afterAgent) {
nodes {
id
name
}
pageInfo {
...PageInfo
}
}
repository {
tree(path: ".gitlab/agents", ref: $defaultBranchName) {
trees {
trees(first: $first, last: $last, after: $afterTree, before: $beforeTree) {
nodes {
name
path
webPath
}
pageInfo {
...PageInfo
}
}
}
}
......
import Agents from './components/agents.vue';
import createDefaultClient from '~/lib/graphql';
import getAgentsQuery from './graphql/queries/get_agents.query.graphql';
export default (Vue, VueApollo) => {
const el = document.querySelector('#js-cluster-agents-list');
......@@ -11,31 +10,6 @@ export default (Vue, VueApollo) => {
const defaultClient = createDefaultClient();
defaultClient.cache.writeQuery({
query: getAgentsQuery,
/* eslint-disable @gitlab/require-i18n-strings */
data: {
project: {
__typename: 'Project',
clusterAgents: {
__typename: 'ClusterAgents',
nodes: [],
},
repository: {
__typename: 'Repository',
tree: {
__typename: 'Tree',
trees: {
__typename: 'Trees',
nodes: [],
},
},
},
},
},
});
const { emptyStateImage, defaultBranchName, projectPath } = el.dataset;
return new Vue({
......
---
title: Add Pagination to Agent Cluster List
merge_request: 50713
author:
type: changed
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
import { GlAlert, GlKeysetPagination, GlLoadingIcon } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import AgentEmptyState from 'ee/clusters_list/components/agent_empty_state.vue';
......@@ -19,12 +19,12 @@ describe('Agents', () => {
projectPath: 'path/to/project',
};
const createWrapper = ({ agents }) => {
const createWrapper = ({ agents = [], pageInfo = null, trees = [] }) => {
const apolloQueryResponse = {
data: {
project: {
clusterAgents: { nodes: agents },
repository: { tree: { trees: { nodes: [] } } },
clusterAgents: { nodes: agents, pageInfo },
repository: { tree: { trees: { nodes: trees, pageInfo } } },
},
},
};
......@@ -42,6 +42,10 @@ describe('Agents', () => {
return wrapper.vm.$nextTick();
};
const findAgentTable = () => wrapper.find(AgentTable);
const findEmptyState = () => wrapper.find(AgentEmptyState);
const findPaginationButtons = () => wrapper.find(GlKeysetPagination);
afterEach(() => {
if (wrapper) {
wrapper.destroy();
......@@ -61,13 +65,64 @@ describe('Agents', () => {
},
];
const trees = [
{
name: 'agent-2',
path: '.gitlab/agents/agent-2',
webPath: '/project/path/.gitlab/agents/agent-2',
},
];
beforeEach(() => {
return createWrapper({ agents });
return createWrapper({ agents, trees });
});
it('should render agent table', () => {
expect(wrapper.find(AgentTable).exists()).toBe(true);
expect(wrapper.find(AgentEmptyState).exists()).toBe(false);
expect(findAgentTable().exists()).toBe(true);
expect(findEmptyState().exists()).toBe(false);
});
it('should pass agent and folder info to table component', () => {
expect(findAgentTable().props('agents')).toEqual([
{ id: '1', name: 'agent-1', configFolder: undefined },
{
id: '2',
name: 'agent-2',
configFolder: {
name: 'agent-2',
path: '.gitlab/agents/agent-2',
webPath: '/project/path/.gitlab/agents/agent-2',
},
},
]);
});
it('should not render pagination buttons when there are no additional pages', () => {
expect(findPaginationButtons().exists()).toBe(false);
});
describe('when the list has additional pages', () => {
const pageInfo = {
hasNextPage: true,
hasPreviousPage: false,
startCursor: 'prev',
endCursor: 'next',
};
beforeEach(() => {
return createWrapper({
agents,
pageInfo,
});
});
it('should render pagination buttons', () => {
expect(findPaginationButtons().exists()).toBe(true);
});
it('should pass pageInfo to the pagination component', () => {
expect(findPaginationButtons().props()).toMatchObject(pageInfo);
});
});
});
......@@ -77,8 +132,8 @@ describe('Agents', () => {
});
it('should render empty state', () => {
expect(wrapper.find(AgentTable).exists()).toBe(false);
expect(wrapper.find(AgentEmptyState).exists()).toBe(true);
expect(findAgentTable().exists()).toBe(false);
expect(findEmptyState().exists()).toBe(true);
});
});
......
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