summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorAlfredo Sumaran <alfredo@gitlab.com>2017-05-23 18:01:47 -0500
committerAlfredo Sumaran <alfredo@gitlab.com>2017-05-23 18:02:10 -0500
commit5eb885e5bb0a0f30d94e60f0fe51a4a63a983f98 (patch)
treecaf1f86a4ce1bd3742712940a85e41b2b3fdf8fc /app
parent04917d0545a10c9a6ef580d19a55e542dd79a8d7 (diff)
downloadgitlab-ce-5eb885e5bb0a0f30d94e60f0fe51a4a63a983f98.tar.gz
Build tree from server response
[ci skip]
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/groups/components/group_folder.vue4
-rw-r--r--app/assets/javascripts/groups/components/group_item.vue4
-rw-r--r--app/assets/javascripts/groups/components/groups.vue2
-rw-r--r--app/assets/javascripts/groups/services/groups_service.js6
-rw-r--r--app/assets/javascripts/groups/stores/groups_store.js75
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: {},
};
}