Commit 595afed2 authored by Filipa Lacerda's avatar Filipa Lacerda

Integrates pagination component with API

Adds pagination tests

Remove misplaced comment

Fix broken store test
parent fb359808
......@@ -59,6 +59,7 @@ module.exports = Vue.component('environment-component', {
canCreateEnvironmentParsed() {
return this.$options.convertPermissionToBoolean(this.canCreateEnvironment);
},
},
/**
......@@ -68,6 +69,7 @@ module.exports = Vue.component('environment-component', {
created() {
const scope = this.$options.getQueryParameter('scope') || this.visibility;
const pageNumber = this.$options.getQueryParameter('page') || this.pageNumber;
const endpoint = `${this.endpoint}?scope=${scope}&page=${pageNumber}`;
const service = new EnvironmentsService(endpoint);
......@@ -75,14 +77,15 @@ module.exports = Vue.component('environment-component', {
this.isLoading = true;
return service.all()
.then((resp) => {
debugger;
return resp.json();
})
.then((json) => {
this.store.storeAvailableCount(json.available_count);
this.store.storeStoppedCount(json.stopped_count);
this.store.storeEnvironments(json.environments);
.then(resp => ({
headers: resp.headers,
body: resp.json(),
}))
.then((response) => {
this.store.storeAvailableCount(response.body.available_count);
this.store.storeStoppedCount(response.body.stopped_count);
this.store.storeEnvironments(response.body.environments);
this.store.storePagination(response.headers);
})
.then(() => {
this.isLoading = false;
......@@ -122,8 +125,14 @@ module.exports = Vue.component('environment-component', {
return this.store.toggleFolder(model.name);
},
changePage(pageNumber, scope) {
gl.utils.visitUrl(`?scope=${scope}&p=${pageNumber}`);
/**
* Will change the page number and update the URL.
*
* @param {Number} pageNumber desired page to go to.
*/
changePage(pageNumber) {
const param = window.location.search.replace(/page=\d/g, `page=${pageNumber}`);
gl.utils.visitUrl(param);
},
},
......@@ -131,7 +140,7 @@ module.exports = Vue.component('environment-component', {
<div :class="cssContainerClass">
<div class="top-area">
<ul v-if="!isLoading" class="nav-links">
<li v-bind:class="{ 'active': scope === undefined }">
<li v-bind:class="{ 'active': scope === undefined || scope === 'available' }">
<a :href="projectEnvironmentsPath">
Available
<span class="badge js-available-environments-count">
......@@ -207,11 +216,9 @@ module.exports = Vue.component('environment-component', {
</tbody>
</table>
<table-pagination v-if="!isLoading && state.environments.length"
:pagenum="1"
:count="2"
<table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1"
:change="changePage"
:pageInfo="paginationInformation">
:pageInfo="state.paginationInformation">
</table-pagination>
</div>
</div>
......
......@@ -355,6 +355,11 @@ module.exports = Vue.component('environment-item', {
!this.$options.isObjectEmpty(this.model.latest.last_deployment.deployable);
},
/**
* Verifies the presence of all the keys needed to render the buil_path.
*
* @return {String}
*/
buildPath(){
return this.model.latest &&
this.model.latest.last_deployment &&
......@@ -363,8 +368,17 @@ module.exports = Vue.component('environment-item', {
'';
},
/**
* Verifies the presence of all the keys needed to render the external_url.
*
* @return {String}
*/
externalURL() {
return this.model.latest && this.model.latest.external_url || '';
if (this.model.latest && this.model.latest.external_url) {
return this.model.latest.external_url;
}
return '';
},
/**
......
......@@ -44,13 +44,17 @@ class EnvironmentsStore {
}
storePagination(pagination = {}) {
const normalizedHeaders = gl.utils.normalizedHeaders(pagination);
const normalizedHeaders = gl.utils.normalizeHeaders(pagination);
const paginationInformation = {
perPage: parseInt(normalizedHeaders['X-PER-PAGE'], 10),
page: parseInt(normalizedHeaders['X-PAGE'], 10),
total: parseInt(normalizedHeaders['X-TOTAL'], 10),
totalPages: parseInt(normalizedHeaders['X-TOTAL-PAGES'], 10),
nextPage: parseInt(normalizedHeaders['X-NEXT-PAGE'], 10),
previousPage: parseInt(normalizedHeaders['X-PREV-PAGE'], 10),
};
this.paginationInformation = paginationInformation;
this.state.paginationInformation = paginationInformation;
return paginationInformation;
}
......
......@@ -36,6 +36,7 @@ require('../vue_shared/components/pipelines_table');
},
methods: {
change(pagenum, apiScope) {
if (!apiScope) apiScope = 'all';
gl.utils.visitUrl(`?scope=${apiScope}&p=${pagenum}`);
},
},
......
......@@ -57,9 +57,7 @@ window.Vue = require('vue');
},
methods: {
changePage(e) {
let apiScope = gl.utils.getParameterByName('scope');
if (!apiScope) apiScope = 'all';
const apiScope = gl.utils.getParameterByName('scope');
const text = e.target.innerText;
const { totalPages, nextPage, previousPage } = this.pageInfo;
......
......@@ -49,7 +49,7 @@ describe('Environment', () => {
});
});
describe('with environments', () => {
describe('with paginated environments', () => {
const environmentsResponseInterceptor = (request, next) => {
next(request.respondWith(JSON.stringify({
environments: [environment],
......@@ -57,11 +57,22 @@ describe('Environment', () => {
available_count: 0,
}), {
status: 200,
headers: {
'X-Next-Page': '2',
'X-Page': '1',
'X-Per-Page': '1',
'X-Prev-Page': '',
'X-Total': '37',
'X-Total-Pages': '2',
},
}));
};
beforeEach(() => {
Vue.http.interceptors.push(environmentsResponseInterceptor);
component = new EnvironmentsComponent({
el: document.querySelector('#environments-list-view'),
});
});
afterEach(() => {
......@@ -71,10 +82,6 @@ describe('Environment', () => {
});
it('should render a table with environments', (done) => {
component = new EnvironmentsComponent({
el: document.querySelector('#environments-list-view'),
});
setTimeout(() => {
expect(
component.$el.querySelectorAll('table tbody tr').length,
......@@ -82,6 +89,17 @@ describe('Environment', () => {
done();
}, 0);
});
describe('pagination', () => {
it('should render pagination', (done) => {
setTimeout(() => {
expect(
component.$el.querySelectorAll('.gl-pagination li').length,
).toEqual(5);
done();
}, 0);
});
});
});
});
......
......@@ -10,24 +10,48 @@ const { environmentsList } = require('./mock_data');
});
it('should start with a blank state', () => {
expect(store.state.environments.length).toBe(0);
expect(store.state.stoppedCounter).toBe(0);
expect(store.state.availableCounter).toBe(0);
expect(store.state.environments.length).toEqual(0);
expect(store.state.stoppedCounter).toEqual(0);
expect(store.state.availableCounter).toEqual(0);
expect(store.state.paginationInformation).toEqual({});
});
it('should store environments', () => {
store.storeEnvironments(environmentsList);
expect(store.state.environments.length).toBe(environmentsList.length);
expect(store.state.environments.length).toEqual(environmentsList.length);
});
it('should store available count', () => {
store.storeAvailableCount(2);
expect(store.state.availableCounter).toBe(2);
expect(store.state.availableCounter).toEqual(2);
});
it('should store stopped count', () => {
store.storeStoppedCount(2);
expect(store.state.stoppedCounter).toBe(2);
expect(store.state.stoppedCounter).toEqual(2);
});
it('should store pagination information', () => {
const pagination = {
'X-nExt-pAge': '2',
'X-page': '1',
'X-Per-Page': '1',
'X-Prev-Page': '2',
'X-TOTAL': '37',
'X-Total-Pages': '2',
};
const expectedResult = {
perPage: 1,
page: 1,
total: 37,
totalPages: 2,
nextPage: 2,
previousPage: 2,
};
store.storePagination(pagination);
expect(store.state.paginationInformation).toEqual(expectedResult);
});
});
})();
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