Commit b64555d3 authored by Filipa Lacerda's avatar Filipa Lacerda

Adds show all button

parent adec9194
...@@ -78,11 +78,11 @@ export default Vue.component('environment-component', { ...@@ -78,11 +78,11 @@ export default Vue.component('environment-component', {
}, },
methods: { methods: {
toggleFolder(folder) { toggleFolder(folder, folderUrl) {
this.store.toggleFolder(folder); this.store.toggleFolder(folder);
if (!folder.isOpen) { if (!folder.isOpen) {
this.fetchChildEnvironments(folder); this.fetchChildEnvironments(folder, folderUrl);
} }
}, },
...@@ -125,14 +125,13 @@ export default Vue.component('environment-component', { ...@@ -125,14 +125,13 @@ export default Vue.component('environment-component', {
}); });
}, },
fetchChildEnvironments(folder) { fetchChildEnvironments(folder, folderUrl) {
this.isLoadingFolderContent = true; this.isLoadingFolderContent = true;
this.service.getFolderContent(folder.folderName) this.service.getFolderContent(folderUrl)
.then(resp => resp.json()) .then(resp => resp.json())
.then((response) => { .then((response) => {
console.log(response); this.store.setfolderContent(folder, response.environments);
this.store.folderContent(folder, response.environments);
}) })
.then(() => { .then(() => {
this.isLoadingFolderContent = false; this.isLoadingFolderContent = false;
...@@ -204,7 +203,8 @@ export default Vue.component('environment-component', { ...@@ -204,7 +203,8 @@ export default Vue.component('environment-component', {
:environments="state.environments" :environments="state.environments"
:can-create-deployment="canCreateDeploymentParsed" :can-create-deployment="canCreateDeploymentParsed"
:can-read-environment="canReadEnvironmentParsed" :can-read-environment="canReadEnvironmentParsed"
:service="service"/> :service="service"
:is-loading-folder-content="isLoadingFolderContent" />
</div> </div>
<table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1" <table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1"
......
...@@ -392,6 +392,15 @@ export default { ...@@ -392,6 +392,15 @@ export default {
return ''; return '';
}, },
/**
* Constructs folder URL based on the current location and the folder id.
*
* @return {String}
*/
folderUrl() {
return `${window.location.pathname}/folders/${this.model.folderName}`;
},
}, },
/** /**
...@@ -411,12 +420,12 @@ export default { ...@@ -411,12 +420,12 @@ export default {
methods: { methods: {
onClickFolder() { onClickFolder() {
eventHub.$emit('toggleFolder', this.model); eventHub.$emit('toggleFolder', this.model, this.folderUrl);
}, },
}, },
template: ` template: `
<tr> <tr :class="{ 'child-row': model.isChildren }">
<td> <td>
<a v-if="!model.isFolder" <a v-if="!model.isFolder"
class="environment-name" class="environment-name"
......
...@@ -31,6 +31,18 @@ export default { ...@@ -31,6 +31,18 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
isLoadingFolderContent: {
type: Boolean,
required: false,
default: false,
},
},
methods: {
folderUrl(model) {
return `${window.location.pathname}/folders/${model.folderName}`;
},
}, },
template: ` template: `
...@@ -54,13 +66,30 @@ export default { ...@@ -54,13 +66,30 @@ export default {
:can-read-environment="canReadEnvironment" :can-read-environment="canReadEnvironment"
:service="service"></tr> :service="service"></tr>
<tr v-if="model.isFolder && model.isOpen && model.children && model.children.length > 0" <template v-if="model.isFolder && model.isOpen && model.children && model.children.length > 0">
is="environment-item" <tr v-if="isLoadingFolderContent">
v-for="children in model.children" <td colspan="6" class="text-center">
:model="children" <i class="fa fa-spin fa-spinner" aria-hidden="true"/>
:can-create-deployment="canCreateDeploymentParsed" </td>
:can-read-environment="canReadEnvironmentParsed" </tr>
:service="service"></tr>
<tr v-if="!isLoadingFolderContent"
is="environment-item"
v-for="children in model.children"
:model="children"
:can-create-deployment="canCreateDeployment"
:can-read-environment="canReadEnvironment"
:service="service"></tr>
<tr v-if="!isLoadingFolderContent">
<td colspan="6" class="text-center">
<a :href="folderUrl(model)" class="btn btn-default">
Show all
</a>
</td>
</tr>
</template>
</template> </template>
</tbody> </tbody>
</table> </table>
......
...@@ -6,14 +6,7 @@ Vue.use(VueResource); ...@@ -6,14 +6,7 @@ Vue.use(VueResource);
export default class EnvironmentsService { export default class EnvironmentsService {
constructor(endpoint) { constructor(endpoint) {
/** this.environments = Vue.resource(endpoint);
* FIX ME: This should be sent by backend.
*/
const customActions = {
folderContent: { method: 'GET', url: `${window.location.pathname}/folders{/name}?perPage=2` },
};
this.environments = Vue.resource(endpoint, {}, customActions);
} }
get(scope, page) { get(scope, page) {
...@@ -24,8 +17,7 @@ export default class EnvironmentsService { ...@@ -24,8 +17,7 @@ export default class EnvironmentsService {
return Vue.http.post(endpoint, {}, { emulateJSON: true }); return Vue.http.post(endpoint, {}, { emulateJSON: true });
} }
getFolderContent(folderName) { getFolderContent(folderUrl) {
debugger return Vue.http.get(`${folderUrl}.json?per_page=3`);
return this.environments.folderContent({ name: folderName });
} }
} }
...@@ -92,23 +92,53 @@ export default class EnvironmentsStore { ...@@ -92,23 +92,53 @@ export default class EnvironmentsStore {
} }
/** /**
* Toggles folder open property given the given folder. * Toggles folder open property for the given folder.
* *
* @param {String} envType * @param {Object} folder
* @return {Array} * @return {Array}
*/ */
toggleFolder(folder) { toggleFolder(folder) {
return this.updateFolder(folder, 'isOpen', !folder.isOpen); return this.updateFolder(folder, 'isOpen', !folder.isOpen);
} }
folderContent(folder, environments) { /**
debugger; * Updates the folder with the received environments.
return this.updateFolder(folder, 'children', environments); *
*
* @param {Object} folder Folder to update
* @param {Array} environments Received environments
* @return {Object}
*/
setfolderContent(folder, environments) {
const updatedEnvironments = environments.map((env) => {
let updated = env;
if (env.latest) {
updated = Object.assign({}, env, env.latest);
delete updated.latest;
} else {
updated = env;
}
updated.isChildren = true;
return updated;
});
return this.updateFolder(folder, 'children', updatedEnvironments);
} }
/**
* Given a folder a prop and a new value updates the correct folder.
*
* @param {Object} folder
* @param {String} prop
* @param {String|Boolean|Object|Array} newValue
* @return {Array}
*/
updateFolder(folder, prop, newValue) { updateFolder(folder, prop, newValue) {
const environments = this.state.environments; const environments = this.state.environments;
debugger;
const updatedEnvironments = environments.map((env) => { const updatedEnvironments = environments.map((env) => {
const updateEnv = Object.assign({}, env); const updateEnv = Object.assign({}, env);
if (env.isFolder && env.id === folder.id) { if (env.isFolder && env.id === folder.id) {
...@@ -117,10 +147,10 @@ export default class EnvironmentsStore { ...@@ -117,10 +147,10 @@ export default class EnvironmentsStore {
return updateEnv; return updateEnv;
}); });
debugger;
console.log(updatedEnvironments);
this.state.environments = updatedEnvironments; this.state.environments = updatedEnvironments;
return updatedEnvironments;
} }
} }
...@@ -54,6 +54,14 @@ ...@@ -54,6 +54,14 @@
} }
} }
.child-row td:first-child a {
margin-left: 17px;
}
.environments-show-all {
text-align: center;
}
.btn-group { .btn-group {
> a { > a {
......
---
title: Add back expandable folder behavior
merge_request:
author:
import Vue from 'vue'; import Vue from 'vue';
import '~/flash'; import '~/flash';
import EnvironmentsComponent from '~/environments/components/environment'; import EnvironmentsComponent from '~/environments/components/environment';
import { environment } from './mock_data'; import { environment, folder } from './mock_data';
describe('Environment', () => { describe('Environment', () => {
preloadFixtures('static/environments/environments.html.raw'); preloadFixtures('static/environments/environments.html.raw');
...@@ -175,4 +175,101 @@ describe('Environment', () => { ...@@ -175,4 +175,101 @@ describe('Environment', () => {
}, 0); }, 0);
}); });
}); });
describe('expandable folders', () => {
const environmentsResponseInterceptor = (request, next) => {
next(request.respondWith(JSON.stringify({
environments: [folder],
stopped_count: 0,
available_count: 1,
}), {
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(() => {
Vue.http.interceptors = _.without(
Vue.http.interceptors, environmentsResponseInterceptor,
);
});
it('should open a closed folder', (done) => {
setTimeout(() => {
component.$el.querySelector('.folder-name').click();
Vue.nextTick(() => {
expect(
component.$el.querySelector('.folder-icon i.fa-caret-right').getAttribute('style'),
).toContain('display: none');
expect(
component.$el.querySelector('.folder-icon i.fa-caret-down').getAttribute('style'),
).not.toContain('display: none');
done();
});
});
});
it('should close an opened folder', (done) => {
setTimeout(() => {
// open folder
component.$el.querySelector('.folder-name').click();
Vue.nextTick(() => {
// close folder
component.$el.querySelector('.folder-name').click();
Vue.nextTick(() => {
expect(
component.$el.querySelector('.folder-icon i.fa-caret-down').getAttribute('style'),
).toContain('display: none');
expect(
component.$el.querySelector('.folder-icon i.fa-caret-right').getAttribute('style'),
).not.toContain('display: none');
done();
});
});
});
});
it('should show children environments and a button to show all environments', (done) => {
setTimeout(() => {
// open folder
component.$el.querySelector('.folder-name').click();
Vue.nextTick(() => {
const folderInterceptor = (request, next) => {
next(request.respondWith(JSON.stringify({
environments: [environment],
}), { status: 200 }));
};
Vue.http.interceptors.push(folderInterceptor);
// wait for next async request
setTimeout(() => {
expect(component.$el.querySelectorAll('.child-row').length).toEqual(1);
expect(component.$el.querySelector('td.text-center > a.btn').textContent).toContain('Show all');
Vue.http.interceptors = _.without(Vue.http.interceptors, folderInterceptor);
done();
});
});
});
});
});
}); });
import Store from '~/environments/stores/environments_store'; import Store from '~/environments/stores/environments_store';
import { environmentsList, serverData } from './mock_data'; import { environmentsList, serverData } from './mock_data';
(() => { describe('Store', () => {
describe('Store', () => { let store;
let store;
beforeEach(() => { beforeEach(() => {
store = new Store(); store = new Store();
}); });
it('should start with a blank state', () => { it('should start with a blank state', () => {
expect(store.state.environments.length).toEqual(0); expect(store.state.environments.length).toEqual(0);
expect(store.state.stoppedCounter).toEqual(0); expect(store.state.stoppedCounter).toEqual(0);
expect(store.state.availableCounter).toEqual(0); expect(store.state.availableCounter).toEqual(0);
expect(store.state.paginationInformation).toEqual({}); expect(store.state.paginationInformation).toEqual({});
}); });
it('should store environments', () => {
store.storeEnvironments(serverData);
expect(store.state.environments.length).toEqual(serverData.length);
expect(store.state.environments[0]).toEqual(environmentsList[0]);
});
it('should store available count', () => {
store.storeAvailableCount(2);
expect(store.state.availableCounter).toEqual(2);
});
it('should store stopped count', () => {
store.storeStoppedCount(2);
expect(store.state.stoppedCounter).toEqual(2);
});
it('should store environments', () => { 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.setPagination(pagination);
expect(store.state.paginationInformation).toEqual(expectedResult);
});
describe('toggleFolder', () => {
it('should toggle folder', () => {
store.storeEnvironments(serverData); store.storeEnvironments(serverData);
expect(store.state.environments.length).toEqual(serverData.length);
expect(store.state.environments[0]).toEqual(environmentsList[0]);
});
it('should store available count', () => { store.toggleFolder(store.state.environments[1]);
store.storeAvailableCount(2); expect(store.state.environments[1].isOpen).toEqual(true);
expect(store.state.availableCounter).toEqual(2);
});
it('should store stopped count', () => { store.toggleFolder(store.state.environments[1]);
store.storeStoppedCount(2); expect(store.state.environments[1].isOpen).toEqual(false);
expect(store.state.stoppedCounter).toEqual(2);
}); });
});
describe('setfolderContent', () => {
it('should store folder content', () => {
store.storeEnvironments(serverData);
store.setfolderContent(store.state.environments[1], serverData);
it('should store pagination information', () => { expect(store.state.environments[1].children.length).toEqual(serverData.length);
const pagination = { expect(store.state.environments[1].children[0].isChildren).toEqual(true);
'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.setPagination(pagination);
expect(store.state.paginationInformation).toEqual(expectedResult);
}); });
}); });
})(); });
...@@ -84,3 +84,19 @@ export const environment = { ...@@ -84,3 +84,19 @@ export const environment = {
updated_at: '2017-01-31T10:53:46.894Z', updated_at: '2017-01-31T10:53:46.894Z',
}, },
}; };
export const folder = {
folderName: 'build',
size: 5,
id: 12,
name: 'build/update-README',
state: 'available',
external_url: null,
environment_type: 'build',
last_deployment: null,
'stop_action?': false,
environment_path: '/root/review-app/environments/12',
stop_path: '/root/review-app/environments/12/stop',
created_at: '2017-02-01T19:42:18.400Z',
updated_at: '2017-02-01T19:42:18.400Z',
};
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