Commit 87444fb6 authored by Filipa Lacerda's avatar Filipa Lacerda

Adds pagination to pipelines table in merge request page

parent fc892db6
......@@ -2,9 +2,15 @@
import PipelinesService from '../../pipelines/services/pipelines_service';
import PipelineStore from '../../pipelines/stores/pipelines_store';
import pipelinesMixin from '../../pipelines/mixins/pipelines';
import TablePagination from '../../vue_shared/components/table_pagination.vue';
import { getParameterByName } from '../../lib/utils/common_utils';
import CIPaginationMixin from '../../vue_shared/mixins/ci_pagination_api_mixin';
export default {
mixins: [pipelinesMixin],
components: {
TablePagination,
},
mixins: [pipelinesMixin, CIPaginationMixin],
props: {
endpoint: {
type: String,
......@@ -35,6 +41,8 @@ export default {
return {
store,
state: store.state,
page: getParameterByName('page') || '1',
requestData: {},
};
},
......@@ -48,11 +56,14 @@ export default {
},
created() {
this.service = new PipelinesService(this.endpoint);
this.requestData = { page: this.page };
},
methods: {
successCallback(resp) {
// depending of the endpoint the response can either bring a `pipelines` key or not.
const pipelines = resp.data.pipelines || resp.data;
this.store.storePagination(resp.headers);
this.setCommonData(pipelines);
const updatePipelinesEvent = new CustomEvent('update-pipelines-count', {
......@@ -97,5 +108,11 @@ export default {
:view-type="viewType"
/>
</div>
<table-pagination
v-if="shouldRenderPagination"
:change="onChangePage"
:page-info="state.pageInfo"
/>
</div>
</template>
......@@ -155,14 +155,6 @@ export default {
);
},
shouldRenderPagination() {
return (
!this.isLoading &&
this.state.pipelines.length &&
this.state.pageInfo.total > this.state.pageInfo.perPage
);
},
emptyTabMessage() {
const { scopes } = this.$options;
const possibleScopes = [scopes.pending, scopes.running, scopes.finished];
......@@ -232,36 +224,6 @@ export default {
this.setCommonData(resp.data.pipelines);
}
},
/**
* Handles URL and query parameter changes.
* When the user uses the pagination or the tabs,
* - update URL
* - Make API request to the server with new parameters
* - Update the polling function
* - Update the internal state
*/
updateContent(parameters) {
this.updateInternalState(parameters);
// fetch new data
return this.service
.getPipelines(this.requestData)
.then(response => {
this.isLoading = false;
this.successCallback(response);
// restart polling
this.poll.restart({ data: this.requestData });
})
.catch(() => {
this.isLoading = false;
this.errorCallback();
// restart polling
this.poll.restart({ data: this.requestData });
});
},
handleResetRunnersCache(endpoint) {
this.isResetCacheButtonLoading = true;
......
......@@ -23,6 +23,15 @@ export default {
hasMadeRequest: false,
};
},
computed: {
shouldRenderPagination() {
return (
!this.isLoading &&
this.state.pipelines.length &&
this.state.pageInfo.total > this.state.pageInfo.perPage
);
},
},
beforeMount() {
this.poll = new Poll({
resource: this.service,
......@@ -65,6 +74,35 @@ export default {
this.poll.stop();
},
methods: {
/**
* Handles URL and query parameter changes.
* When the user uses the pagination or the tabs,
* - update URL
* - Make API request to the server with new parameters
* - Update the polling function
* - Update the internal state
*/
updateContent(parameters) {
this.updateInternalState(parameters);
// fetch new data
return this.service
.getPipelines(this.requestData)
.then(response => {
this.isLoading = false;
this.successCallback(response);
// restart polling
this.poll.restart({ data: this.requestData });
})
.catch(() => {
this.isLoading = false;
this.errorCallback();
// restart polling
this.poll.restart({ data: this.requestData });
});
},
updateTable() {
// Cancel ongoing request
if (this.isMakingRequest) {
......
......@@ -14,7 +14,14 @@ export default {
onChangePage(page) {
/* URLS parameters are strings, we need to parse to match types */
this.updateContent({ scope: this.scope, page: Number(page).toString() });
const params = {
page: Number(page).toString(),
};
if (this.scope) {
params.scope = this.scope;
}
this.updateContent(params);
},
updateInternalState(parameters) {
......
......@@ -43,7 +43,7 @@ class Projects::CommitController < Projects::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def pipelines
@pipelines = @commit.pipelines.order(id: :desc)
@pipelines = @pipelines.where(ref: params[:ref]) if params[:ref]
@pipelines = @pipelines.where(ref: params[:ref]).page(params[:page]).per(30) if params[:ref]
respond_to do |format|
format.html
......@@ -53,6 +53,7 @@ class Projects::CommitController < Projects::ApplicationController
render json: {
pipelines: PipelineSerializer
.new(project: @project, current_user: @current_user)
.with_pagination(request, response)
.represent(@pipelines),
count: {
all: @pipelines.count
......
......@@ -84,13 +84,14 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
def pipelines
@pipelines = @merge_request.all_pipelines
@pipelines = @merge_request.all_pipelines.page(params[:page]).per(30)
Gitlab::PollingInterval.set_header(response, interval: 10_000)
render json: {
pipelines: PipelineSerializer
.new(project: @project, current_user: @current_user)
.with_pagination(request, response)
.represent(@pipelines),
count: {
all: @pipelines.count
......
---
title: Adds pagination to pipelines table in merge request page
merge_request:
author:
type: performance
......@@ -356,6 +356,7 @@ describe Projects::CommitController do
expect(response).to be_ok
expect(JSON.parse(response.body)['pipelines']).not_to be_empty
expect(JSON.parse(response.body)['count']['all']).to eq 1
expect(response).to include_pagination_headers
end
end
end
......
......@@ -563,6 +563,7 @@ describe Projects::MergeRequestsController do
it 'responds with serialized pipelines' do
expect(json_response['pipelines']).not_to be_empty
expect(json_response['count']['all']).to eq 1
expect(response).to include_pagination_headers
end
end
......
......@@ -72,6 +72,29 @@ describe('Pipelines table in Commits and Merge requests', function() {
done();
}, 0);
});
describe('with pagination', () => {
it('should make an API request when using pagination', done => {
setTimeout(() => {
spyOn(vm, 'updateContent');
vm.store.state.pageInfo = {
page: 1,
total: 10,
perPage: 2,
nextPage: 2,
totalPages: 5,
};
vm.$nextTick(() => {
vm.$el.querySelector('.js-next-button a').click();
expect(vm.updateContent).toHaveBeenCalledWith({ page: '2' });
done();
});
});
});
});
});
describe('pipeline badge counts', () => {
......
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