diff options
author | Alfredo Sumaran <alfredo@gitlab.com> | 2017-05-23 18:01:47 -0500 |
---|---|---|
committer | Alfredo Sumaran <alfredo@gitlab.com> | 2017-05-23 18:02:10 -0500 |
commit | 5eb885e5bb0a0f30d94e60f0fe51a4a63a983f98 (patch) | |
tree | caf1f86a4ce1bd3742712940a85e41b2b3fdf8fc /app | |
parent | 04917d0545a10c9a6ef580d19a55e542dd79a8d7 (diff) | |
download | gitlab-ce-5eb885e5bb0a0f30d94e60f0fe51a4a63a983f98.tar.gz |
Build tree from server response
[ci skip]
Diffstat (limited to 'app')
5 files changed, 78 insertions, 13 deletions
diff --git a/app/assets/javascripts/groups/components/group_folder.vue b/app/assets/javascripts/groups/components/group_folder.vue index 57220e51a04..b393a922ad7 100644 --- a/app/assets/javascripts/groups/components/group_folder.vue +++ b/app/assets/javascripts/groups/components/group_folder.vue @@ -2,13 +2,13 @@ export default { props: { groups: { - type: Array, + type: Object, required: true, }, }, computed: { hasGroups() { - return this.groups.length > 0; + return Object.keys(this.groups).length > 0; }, }, }; diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue index f84eb285e0d..6d50f44f7dd 100644 --- a/app/assets/javascripts/groups/components/group_item.vue +++ b/app/assets/javascripts/groups/components/group_item.vue @@ -29,7 +29,7 @@ export default { }; }, isExpandable() { - return this.group.subGroups.length > 0; + return Object.keys(this.group.subGroups).length > 0; }, }, }; @@ -92,7 +92,7 @@ export default { </div> <div class="title"> - <a :href="group.webUrl">{{group.fullName}}</a> + <a :href="group.webUrl">{{group.isOrphan ? group.fullName : group.name}}</a> </div> <div class="description"> diff --git a/app/assets/javascripts/groups/components/groups.vue b/app/assets/javascripts/groups/components/groups.vue index 685392e16a9..6ddf54275d9 100644 --- a/app/assets/javascripts/groups/components/groups.vue +++ b/app/assets/javascripts/groups/components/groups.vue @@ -7,7 +7,7 @@ export default { }, props: { groups: { - type: Array, + type: Object, required: true, }, pageInfo: { diff --git a/app/assets/javascripts/groups/services/groups_service.js b/app/assets/javascripts/groups/services/groups_service.js index c9c0ae6204a..ea0499779ed 100644 --- a/app/assets/javascripts/groups/services/groups_service.js +++ b/app/assets/javascripts/groups/services/groups_service.js @@ -13,11 +13,9 @@ export default class GroupsService { if (parentId) { data.parent_id = parentId; - } else { // Do not send this param for sub groups - if (page) { - data.page = page; - } + } else if (page) { + data.page = page; } return this.groups.get(data); diff --git a/app/assets/javascripts/groups/stores/groups_store.js b/app/assets/javascripts/groups/stores/groups_store.js index 4b5de80e3b2..c7084f1389c 100644 --- a/app/assets/javascripts/groups/stores/groups_store.js +++ b/app/assets/javascripts/groups/stores/groups_store.js @@ -1,7 +1,7 @@ export default class GroupsStore { constructor() { this.state = {}; - this.state.groups = []; + this.state.groups = {}; this.state.pageInfo = {}; return this; @@ -11,9 +11,9 @@ export default class GroupsStore { const parentGroup = parent; if (parentGroup) { - parentGroup.subGroups = this.decorateGroups(rawGroups); + parentGroup.subGroups = this.buildTree(rawGroups); } else { - this.state.groups = this.decorateGroups(rawGroups); + this.state.groups = this.buildTree(rawGroups); } return rawGroups; @@ -32,6 +32,70 @@ export default class GroupsStore { this.state.pageInfo = paginationInfo; } + buildTree(rawGroups) { + const groups = this.decorateGroups(rawGroups); + const tree = {}; + const mappedGroups = {}; + const orphans = []; + + // Map groups to an object + for (let i = 0, len = groups.length; i < len; i += 1) { + const group = groups[i]; + mappedGroups[group.id] = group; + mappedGroups[group.id].subGroups = {}; + } + + Object.keys(mappedGroups).map((key) => { + const currentGroup = mappedGroups[key]; + // If the group is not at the root level, add it to its parent array of subGroups. + const parentGroup = mappedGroups[currentGroup.parentId]; + if (currentGroup.parentId) { + if (parentGroup) { + mappedGroups[currentGroup.parentId].subGroups[currentGroup.id] = currentGroup; + mappedGroups[currentGroup.parentId].isOpen = true; // Expand group if it has subgroups + } else { + // Means the groups hast no direct parent. + // Save for later processing, we will add them to its corresponding base group + orphans.push(currentGroup); + } + } else { + // If the group is at the root level, add it to first level elements array. + tree[currentGroup.id] = currentGroup; + } + + return key; + }); + + // Hopefully this array will be empty for most cases + if (orphans.length) { + orphans.map((orphan) => { + let found = false; + const currentOrphan = orphan; + + Object.keys(tree).map((key) => { + const group = tree[key]; + if (currentOrphan.fullPath.lastIndexOf(group.fullPath) === 0) { + group.subGroups[currentOrphan.id] = currentOrphan; + group.isOpen = true; + currentOrphan.isOrphan = true; + found = true; + } + + return key; + }); + + if (!found) { + currentOrphan.isOrphan = true; + tree[currentOrphan.id] = currentOrphan; + } + + return orphan; + }); + } + + return tree; + } + decorateGroups(rawGroups) { this.groups = rawGroups.map(GroupsStore.decorateGroup); return this.groups; @@ -41,14 +105,17 @@ export default class GroupsStore { return { id: rawGroup.id, fullName: rawGroup.full_name, + fullPath: rawGroup.full_path, + name: rawGroup.name, description: rawGroup.description, webUrl: rawGroup.web_url, parentId: rawGroup.parent_id, visibility: rawGroup.visibility, isOpen: false, + isOrphan: false, numberProjects: 10, numberMembers: 10, - subGroups: [], + subGroups: {}, }; } |