Commit da15ef7e authored by Alfredo Sumaran's avatar Alfredo Sumaran

Keep tree sorted as it comes from server

parent d1990f65
...@@ -39,6 +39,7 @@ export default class GroupsStore { ...@@ -39,6 +39,7 @@ export default class GroupsStore {
this.state.pageInfo = paginationInfo; this.state.pageInfo = paginationInfo;
} }
// Here be dragons
buildTree(rawGroups, parentGroup) { buildTree(rawGroups, parentGroup) {
const groups = this.decorateGroups(rawGroups); const groups = this.decorateGroups(rawGroups);
const tree = {}; const tree = {};
...@@ -47,8 +48,8 @@ export default class GroupsStore { ...@@ -47,8 +48,8 @@ export default class GroupsStore {
// Map groups to an object // Map groups to an object
groups.map((group) => { groups.map((group) => {
mappedGroups[group.id] = group; mappedGroups[`id${group.id}`] = group;
mappedGroups[group.id].subGroups = {}; mappedGroups[`id${group.id}`].subGroups = {};
return group; return group;
}); });
...@@ -56,20 +57,25 @@ export default class GroupsStore { ...@@ -56,20 +57,25 @@ export default class GroupsStore {
const currentGroup = mappedGroups[key]; const currentGroup = mappedGroups[key];
if (currentGroup.parentId) { if (currentGroup.parentId) {
// If the group is not at the root level, add it to its parent array of subGroups. // If the group is not at the root level, add it to its parent array of subGroups.
const findParentGroup = mappedGroups[currentGroup.parentId]; const findParentGroup = mappedGroups[`id${currentGroup.parentId}`];
if (findParentGroup) { if (findParentGroup) {
mappedGroups[currentGroup.parentId].subGroups[currentGroup.id] = currentGroup; mappedGroups[`id${currentGroup.parentId}`].subGroups[`id${currentGroup.id}`] = currentGroup;
mappedGroups[currentGroup.parentId].isOpen = true; // Expand group if it has subgroups mappedGroups[`id${currentGroup.parentId}`].isOpen = true; // Expand group if it has subgroups
} else if (parentGroup && parentGroup.id === currentGroup.parentId) { } else if (parentGroup && parentGroup.id === currentGroup.parentId) {
tree[currentGroup.id] = currentGroup; tree[`id${currentGroup.id}`] = currentGroup;
} else { } else {
// Means the groups hast no direct parent. // No parent found. We save it for later processing.
// Save for later processing, we will add them to its corresponding base group // We should put it inside a group where it's contained.
// e.g. If this group is `one / two / three` we are going to put it inside `one`
orphans.push(currentGroup); orphans.push(currentGroup);
// Add
// Lo metemos a tree para conservar el orden original
tree[`id${currentGroup.id}`] = currentGroup;
} }
} else { } else {
// If the group is at the root level, add it to first level elements array. // If the group is at the top level, add it to first level elements array.
tree[currentGroup.id] = currentGroup; tree[`id${currentGroup.id}`] = currentGroup;
} }
return key; return key;
...@@ -83,11 +89,24 @@ export default class GroupsStore { ...@@ -83,11 +89,24 @@ export default class GroupsStore {
Object.keys(tree).map((key) => { Object.keys(tree).map((key) => {
const group = tree[key]; const group = tree[key];
if (currentOrphan.fullPath.lastIndexOf(group.fullPath) === 0) {
if (
// Make sure `group` exists since it can be deleted below
group &&
currentOrphan.fullPath.lastIndexOf(group.fullPath) === 0 &&
// Make sure is not the same we are not comparing the same group.
// If we don't do this it will cause and infinite loop when rendering on vue
currentOrphan.id !== group.id
) {
group.subGroups[currentOrphan.id] = currentOrphan; group.subGroups[currentOrphan.id] = currentOrphan;
group.isOpen = true; group.isOpen = true;
currentOrphan.isOrphan = true; currentOrphan.isOrphan = true;
found = true; found = true;
// Delete if group was put at the top level. If not the group will be displayed twice.
if (tree[`id${currentOrphan.id}`]) {
delete tree[`id${currentOrphan.id}`];
}
} }
return key; return key;
...@@ -95,7 +114,8 @@ export default class GroupsStore { ...@@ -95,7 +114,8 @@ export default class GroupsStore {
if (!found) { if (!found) {
currentOrphan.isOrphan = true; currentOrphan.isOrphan = true;
tree[currentOrphan.id] = currentOrphan;
tree[`id${currentOrphan.id}`] = currentOrphan;
} }
return orphan; return orphan;
...@@ -139,7 +159,7 @@ export default class GroupsStore { ...@@ -139,7 +159,7 @@ export default class GroupsStore {
// eslint-disable-next-line class-methods-use-this // eslint-disable-next-line class-methods-use-this
removeGroup(group, collection) { removeGroup(group, collection) {
Vue.delete(collection, group.id); Vue.delete(collection, `id${group.id}`);
} }
// eslint-disable-next-line class-methods-use-this // eslint-disable-next-line class-methods-use-this
......
import Vue from 'vue'; import Vue from 'vue';
import eventHub from '~/groups/event_hub';
import groupFolderComponent from '~/groups/components/group_folder.vue'; import groupFolderComponent from '~/groups/components/group_folder.vue';
import groupItemComponent from '~/groups/components/group_item.vue'; import groupItemComponent from '~/groups/components/group_item.vue';
import groupsComponent from '~/groups/components/groups.vue'; import groupsComponent from '~/groups/components/groups.vue';
...@@ -46,6 +47,12 @@ describe('Groups Component', () => { ...@@ -46,6 +47,12 @@ describe('Groups Component', () => {
expect(component.$el.querySelector('#group-1120')).toBeDefined(); expect(component.$el.querySelector('#group-1120')).toBeDefined();
}); });
it('should respect the order of groups', () => {
const wrap = component.$el.querySelector('.groups-list-tree-container > .group-list-tree');
expect(wrap.querySelector('.group-row:nth-child(1)').id).toBe('group-12');
expect(wrap.querySelector('.group-row:nth-child(2)').id).toBe('group-1119');
});
it('should render group and its subgroup', () => { it('should render group and its subgroup', () => {
const lists = component.$el.querySelectorAll('.group-list-tree'); const lists = component.$el.querySelectorAll('.group-list-tree');
...@@ -54,11 +61,26 @@ describe('Groups Component', () => { ...@@ -54,11 +61,26 @@ describe('Groups Component', () => {
expect(lists[0].querySelector('#group-1119').classList.contains('is-open')).toBe(true); expect(lists[0].querySelector('#group-1119').classList.contains('is-open')).toBe(true);
expect(lists[0].querySelector('#group-1119').classList.contains('has-subgroups')).toBe(true); expect(lists[0].querySelector('#group-1119').classList.contains('has-subgroups')).toBe(true);
expect(lists[2].querySelector('#group-1120').textContent).toContain(groups[1119].subGroups[1120].name); expect(lists[2].querySelector('#group-1120').textContent).toContain(groups.id1119.subGroups.id1120.name);
}); });
it('should remove prefix of parent group', () => { it('should remove prefix of parent group', () => {
expect(component.$el.querySelector('#group-12 #group-1128 .title').textContent).toContain('level2 / level3 / level4'); expect(component.$el.querySelector('#group-12 #group-1128 .title').textContent).toContain('level2 / level3 / level4');
}); });
it('should remove the group after leaving the group', (done) => {
spyOn(window, 'confirm').and.returnValue(true);
eventHub.$on('leaveGroup', (group, collection) => {
store.removeGroup(group, collection);
});
component.$el.querySelector('#group-12 .leave-group').click();
Vue.nextTick(() => {
expect(component.$el.querySelector('#group-12')).toBeNull();
done();
});
});
}); });
}); });
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