summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfredo Sumaran <alfredo@gitlab.com>2017-06-06 09:01:42 -0500
committerAlfredo Sumaran <alfredo@gitlab.com>2017-06-06 09:01:42 -0500
commitd8403ec18f771c28eb566dc3ce6dc08bffd2db22 (patch)
tree17760f837a3b35d03026a0943f85be4320fc2a42
parent657bc805a4bfee516942a3765eef0a508891a5d7 (diff)
downloadgitlab-ce-d8403ec18f771c28eb566dc3ce6dc08bffd2db22.tar.gz
Minor visual adjustments
-rw-r--r--app/assets/javascripts/groups/components/group_folder.vue2
-rw-r--r--app/assets/javascripts/groups/components/group_item.vue9
-rw-r--r--app/assets/javascripts/groups/index.js63
-rw-r--r--app/assets/javascripts/groups/stores/groups_store.js7
-rw-r--r--app/assets/stylesheets/framework/lists.scss7
-rw-r--r--app/controllers/concerns/membership_actions.rb2
-rw-r--r--app/views/dashboard/groups/_groups.html.haml8
-rw-r--r--spec/javascripts/groups/group_item_spec.js2
-rw-r--r--spec/javascripts/groups/groups_spec.js2
9 files changed, 80 insertions, 22 deletions
diff --git a/app/assets/javascripts/groups/components/group_folder.vue b/app/assets/javascripts/groups/components/group_folder.vue
index dcf6f10e1ca..cd47f6b0047 100644
--- a/app/assets/javascripts/groups/components/group_folder.vue
+++ b/app/assets/javascripts/groups/components/group_folder.vue
@@ -15,6 +15,6 @@ export default {
<template>
<ul class="content-list group-list-tree">
- <group-item v-for="(group, index) in groups" :key="index" :group="group" :baseGroup="baseGroup" />
+ <group-item v-for="(group, index) in groups" :key="index" :group="group" :base-group="baseGroup" :collection="groups" />
</ul>
</template>
diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue
index 2013469f9e6..c4b0325fb09 100644
--- a/app/assets/javascripts/groups/components/group_item.vue
+++ b/app/assets/javascripts/groups/components/group_item.vue
@@ -12,6 +12,11 @@ export default {
required: false,
default: () => ({}),
},
+ collection: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
},
methods: {
onClickRowGroup(e) {
@@ -35,7 +40,7 @@ export default {
}
},
leaveGroup() {
- eventHub.$emit('leaveGroup', this.group.leavePath);
+ eventHub.$emit('leaveGroup', this.group, this.collection);
},
},
computed: {
@@ -63,7 +68,7 @@ export default {
if (this.group.isOrphan) {
// check if current group is baseGroup
- if (Object.keys(this.baseGroup).length > 0) {
+ if (Object.keys(this.baseGroup).length > 0 && this.baseGroup !== this.group) {
// Remove baseGroup prefix from our current group.fullName. e.g:
// baseGroup.fullName: `level1`
// group.fullName: `level1 / level2 / level3`
diff --git a/app/assets/javascripts/groups/index.js b/app/assets/javascripts/groups/index.js
index 9c2e37dd5f1..4e2cb88eb4e 100644
--- a/app/assets/javascripts/groups/index.js
+++ b/app/assets/javascripts/groups/index.js
@@ -1,3 +1,5 @@
+/* global Flash */
+
import Vue from 'vue';
import GroupFilterableList from './groups_filterable_list';
import GroupsComponent from './components/groups.vue';
@@ -29,9 +31,16 @@ document.addEventListener('DOMContentLoaded', () => {
return {
store: this.store,
+ isLoading: true,
state: this.store.state,
+ loading: true,
};
},
+ computed: {
+ isEmpty() {
+ return Object.keys(this.state.groups).length === 0;
+ },
+ },
methods: {
fetchGroups(parentGroup) {
let parentId = null;
@@ -43,6 +52,8 @@ document.addEventListener('DOMContentLoaded', () => {
let filterGroups = null;
let filterGroupsParam = null;
+ this.isLoading = true;
+
if (parentGroup) {
parentId = parentGroup.id;
}
@@ -66,22 +77,26 @@ document.addEventListener('DOMContentLoaded', () => {
getGroups.then((response) => {
this.updateGroups(response.json(), parentGroup);
})
- .catch(() => {
- // TODO: Handle error
- });
+ .finally(() => {
+ this.isLoading = false;
+ })
+ .catch(this.handleErrorResponse);
return getGroups;
},
fetchPage(page, filterGroups, sort) {
+ this.isLoading = true;
+
this.service.getGroups(null, page, filterGroups, sort)
.then((response) => {
this.updateGroups(response.json());
this.updatePagination(response.headers);
$.scrollTo(0);
})
- .catch(() => {
- // TODO: Handle error
- });
+ .finally(() => {
+ this.isLoading = false;
+ })
+ .catch(this.handleErrorResponse);
},
toggleSubGroups(parentGroup = null) {
if (!parentGroup.isOpen) {
@@ -91,13 +106,26 @@ document.addEventListener('DOMContentLoaded', () => {
GroupsStore.toggleSubGroups(parentGroup);
},
- leaveGroup(endpoint) {
- this.service.leaveGroup(endpoint)
- .then(() => {
- // TODO: Refresh?
+ leaveGroup(group, collection) {
+ this.service.leaveGroup(group.leavePath)
+ .then((response) => {
+ this.store.removeGroup(group, collection);
+
+ // eslint-disable-next-line no-new
+ new Flash(response.json().notice, 'notice');
+ })
+ .finally(() => {
+ $.scrollTo(0);
})
- .catch(() => {
- // TODO: Handle error
+ .catch((response) => {
+ let message = 'An error occurred. Please try again.';
+
+ if (response.status === 403) {
+ message = 'Failed to leave the group. Please make sure you are not the only owner';
+ }
+
+ // eslint-disable-next-line no-new
+ new Flash(message);
});
},
updateGroups(groups, parentGroup) {
@@ -106,6 +134,10 @@ document.addEventListener('DOMContentLoaded', () => {
updatePagination(headers) {
this.store.storePagination(headers);
},
+ handleErrorResponse() {
+ // eslint-disable-next-line no-new
+ new Flash('An error occurred. Please try again.');
+ },
},
beforeMount() {
let groupFilterList = null;
@@ -135,9 +167,10 @@ document.addEventListener('DOMContentLoaded', () => {
.then((response) => {
this.updatePagination(response.headers);
})
- .catch(() => {
- // TODO: Handle error
- });
+ .finally(() => {
+ this.isLoading = false;
+ })
+ .catch(this.handleErrorResponse);
},
});
});
diff --git a/app/assets/javascripts/groups/stores/groups_store.js b/app/assets/javascripts/groups/stores/groups_store.js
index d8353a92881..0493cee2fa8 100644
--- a/app/assets/javascripts/groups/stores/groups_store.js
+++ b/app/assets/javascripts/groups/stores/groups_store.js
@@ -1,3 +1,5 @@
+import Vue from 'vue';
+
export default class GroupsStore {
constructor() {
this.state = {};
@@ -132,6 +134,11 @@ export default class GroupsStore {
}
// eslint-disable-next-line class-methods-use-this
+ removeGroup(group, collection) {
+ Vue.delete(collection, group.id);
+ }
+
+ // eslint-disable-next-line class-methods-use-this
static toggleSubGroups(toggleGroup) {
const group = toggleGroup;
group.isOpen = !group.isOpen;
diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss
index 6d262a63d81..7529538b4a7 100644
--- a/app/assets/stylesheets/framework/lists.scss
+++ b/app/assets/stylesheets/framework/lists.scss
@@ -342,3 +342,10 @@ ul.indent-list {
}
}
}
+
+.js-groups-list-holder {
+ .groups-list-loading {
+ font-size: 34px;
+ text-align: center;
+ }
+}
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index f55f03972a9..19fd4e6e2a9 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -57,7 +57,7 @@ module MembershipActions
redirect_to redirect_path, notice: notice
end
- format.json { head :ok }
+ format.json { render json: { notice: notice } }
end
end
diff --git a/app/views/dashboard/groups/_groups.html.haml b/app/views/dashboard/groups/_groups.html.haml
index b72b04479de..ba7e0c21348 100644
--- a/app/views/dashboard/groups/_groups.html.haml
+++ b/app/views/dashboard/groups/_groups.html.haml
@@ -1,3 +1,9 @@
.js-groups-list-holder
#dashboard-group-app{ data: { endpoint: dashboard_groups_path(format: :json), path: dashboard_groups_path } }
- %groups-component{ ':groups' => 'state.groups', ':page-info' => 'state.pageInfo' }
+ .groups-list-loading
+ = icon('spinner spin', 'v-show' => 'isLoading')
+ %template{ 'v-if' => '!isLoading && isEmpty' }
+ %div{ 'v-cloak' => true }
+ = render 'empty_state'
+ %template{ 'v-else-if' => '!isLoading && !isEmpty'}
+ %groups-component{ ':groups' => 'state.groups', ':page-info' => 'state.pageInfo' }
diff --git a/spec/javascripts/groups/group_item_spec.js b/spec/javascripts/groups/group_item_spec.js
index 609c45250f1..47af735f4b4 100644
--- a/spec/javascripts/groups/group_item_spec.js
+++ b/spec/javascripts/groups/group_item_spec.js
@@ -3,7 +3,7 @@ import groupItemComponent from '~/groups/components/group_item.vue';
import GroupsStore from '~/groups/stores/groups_store';
import { group1 } from './mock_data';
-describe('Groups Component', () => {
+fdescribe('Groups Component', () => {
let GroupItemComponent;
let component;
let store;
diff --git a/spec/javascripts/groups/groups_spec.js b/spec/javascripts/groups/groups_spec.js
index d1f900df3d8..dc144914c60 100644
--- a/spec/javascripts/groups/groups_spec.js
+++ b/spec/javascripts/groups/groups_spec.js
@@ -5,7 +5,7 @@ import groupsComponent from '~/groups/components/groups.vue';
import GroupsStore from '~/groups/stores/groups_store';
import { groupsData } from './mock_data';
-describe('Groups Component', () => {
+fdescribe('Groups Component', () => {
let GroupsComponent;
let store;
let component;