Commit d8403ec1 authored by Alfredo Sumaran's avatar Alfredo Sumaran

Minor visual adjustments

parent 657bc805
...@@ -15,6 +15,6 @@ export default { ...@@ -15,6 +15,6 @@ export default {
<template> <template>
<ul class="content-list group-list-tree"> <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> </ul>
</template> </template>
...@@ -12,6 +12,11 @@ export default { ...@@ -12,6 +12,11 @@ export default {
required: false, required: false,
default: () => ({}), default: () => ({}),
}, },
collection: {
type: Object,
required: false,
default: () => ({}),
},
}, },
methods: { methods: {
onClickRowGroup(e) { onClickRowGroup(e) {
...@@ -35,7 +40,7 @@ export default { ...@@ -35,7 +40,7 @@ export default {
} }
}, },
leaveGroup() { leaveGroup() {
eventHub.$emit('leaveGroup', this.group.leavePath); eventHub.$emit('leaveGroup', this.group, this.collection);
}, },
}, },
computed: { computed: {
...@@ -63,7 +68,7 @@ export default { ...@@ -63,7 +68,7 @@ export default {
if (this.group.isOrphan) { if (this.group.isOrphan) {
// check if current group is baseGroup // 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: // Remove baseGroup prefix from our current group.fullName. e.g:
// baseGroup.fullName: `level1` // baseGroup.fullName: `level1`
// group.fullName: `level1 / level2 / level3` // group.fullName: `level1 / level2 / level3`
......
/* global Flash */
import Vue from 'vue'; import Vue from 'vue';
import GroupFilterableList from './groups_filterable_list'; import GroupFilterableList from './groups_filterable_list';
import GroupsComponent from './components/groups.vue'; import GroupsComponent from './components/groups.vue';
...@@ -29,9 +31,16 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -29,9 +31,16 @@ document.addEventListener('DOMContentLoaded', () => {
return { return {
store: this.store, store: this.store,
isLoading: true,
state: this.store.state, state: this.store.state,
loading: true,
}; };
}, },
computed: {
isEmpty() {
return Object.keys(this.state.groups).length === 0;
},
},
methods: { methods: {
fetchGroups(parentGroup) { fetchGroups(parentGroup) {
let parentId = null; let parentId = null;
...@@ -43,6 +52,8 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -43,6 +52,8 @@ document.addEventListener('DOMContentLoaded', () => {
let filterGroups = null; let filterGroups = null;
let filterGroupsParam = null; let filterGroupsParam = null;
this.isLoading = true;
if (parentGroup) { if (parentGroup) {
parentId = parentGroup.id; parentId = parentGroup.id;
} }
...@@ -66,22 +77,26 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -66,22 +77,26 @@ document.addEventListener('DOMContentLoaded', () => {
getGroups.then((response) => { getGroups.then((response) => {
this.updateGroups(response.json(), parentGroup); this.updateGroups(response.json(), parentGroup);
}) })
.catch(() => { .finally(() => {
// TODO: Handle error this.isLoading = false;
}); })
.catch(this.handleErrorResponse);
return getGroups; return getGroups;
}, },
fetchPage(page, filterGroups, sort) { fetchPage(page, filterGroups, sort) {
this.isLoading = true;
this.service.getGroups(null, page, filterGroups, sort) this.service.getGroups(null, page, filterGroups, sort)
.then((response) => { .then((response) => {
this.updateGroups(response.json()); this.updateGroups(response.json());
this.updatePagination(response.headers); this.updatePagination(response.headers);
$.scrollTo(0); $.scrollTo(0);
}) })
.catch(() => { .finally(() => {
// TODO: Handle error this.isLoading = false;
}); })
.catch(this.handleErrorResponse);
}, },
toggleSubGroups(parentGroup = null) { toggleSubGroups(parentGroup = null) {
if (!parentGroup.isOpen) { if (!parentGroup.isOpen) {
...@@ -91,13 +106,26 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -91,13 +106,26 @@ document.addEventListener('DOMContentLoaded', () => {
GroupsStore.toggleSubGroups(parentGroup); GroupsStore.toggleSubGroups(parentGroup);
}, },
leaveGroup(endpoint) { leaveGroup(group, collection) {
this.service.leaveGroup(endpoint) this.service.leaveGroup(group.leavePath)
.then(() => { .then((response) => {
// TODO: Refresh? this.store.removeGroup(group, collection);
// eslint-disable-next-line no-new
new Flash(response.json().notice, 'notice');
})
.finally(() => {
$.scrollTo(0);
}) })
.catch(() => { .catch((response) => {
// TODO: Handle error 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) { updateGroups(groups, parentGroup) {
...@@ -106,6 +134,10 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -106,6 +134,10 @@ document.addEventListener('DOMContentLoaded', () => {
updatePagination(headers) { updatePagination(headers) {
this.store.storePagination(headers); this.store.storePagination(headers);
}, },
handleErrorResponse() {
// eslint-disable-next-line no-new
new Flash('An error occurred. Please try again.');
},
}, },
beforeMount() { beforeMount() {
let groupFilterList = null; let groupFilterList = null;
...@@ -135,9 +167,10 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -135,9 +167,10 @@ document.addEventListener('DOMContentLoaded', () => {
.then((response) => { .then((response) => {
this.updatePagination(response.headers); this.updatePagination(response.headers);
}) })
.catch(() => { .finally(() => {
// TODO: Handle error this.isLoading = false;
}); })
.catch(this.handleErrorResponse);
}, },
}); });
}); });
import Vue from 'vue';
export default class GroupsStore { export default class GroupsStore {
constructor() { constructor() {
this.state = {}; this.state = {};
...@@ -131,6 +133,11 @@ export default class GroupsStore { ...@@ -131,6 +133,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 // eslint-disable-next-line class-methods-use-this
static toggleSubGroups(toggleGroup) { static toggleSubGroups(toggleGroup) {
const group = toggleGroup; const group = toggleGroup;
......
...@@ -342,3 +342,10 @@ ul.indent-list { ...@@ -342,3 +342,10 @@ ul.indent-list {
} }
} }
} }
.js-groups-list-holder {
.groups-list-loading {
font-size: 34px;
text-align: center;
}
}
...@@ -57,7 +57,7 @@ module MembershipActions ...@@ -57,7 +57,7 @@ module MembershipActions
redirect_to redirect_path, notice: notice redirect_to redirect_path, notice: notice
end end
format.json { head :ok } format.json { render json: { notice: notice } }
end end
end end
......
.js-groups-list-holder .js-groups-list-holder
#dashboard-group-app{ data: { endpoint: dashboard_groups_path(format: :json), path: dashboard_groups_path } } #dashboard-group-app{ data: { endpoint: dashboard_groups_path(format: :json), path: dashboard_groups_path } }
.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' } %groups-component{ ':groups' => 'state.groups', ':page-info' => 'state.pageInfo' }
...@@ -3,7 +3,7 @@ import groupItemComponent from '~/groups/components/group_item.vue'; ...@@ -3,7 +3,7 @@ import groupItemComponent from '~/groups/components/group_item.vue';
import GroupsStore from '~/groups/stores/groups_store'; import GroupsStore from '~/groups/stores/groups_store';
import { group1 } from './mock_data'; import { group1 } from './mock_data';
describe('Groups Component', () => { fdescribe('Groups Component', () => {
let GroupItemComponent; let GroupItemComponent;
let component; let component;
let store; let store;
......
...@@ -5,7 +5,7 @@ import groupsComponent from '~/groups/components/groups.vue'; ...@@ -5,7 +5,7 @@ import groupsComponent from '~/groups/components/groups.vue';
import GroupsStore from '~/groups/stores/groups_store'; import GroupsStore from '~/groups/stores/groups_store';
import { groupsData } from './mock_data'; import { groupsData } from './mock_data';
describe('Groups Component', () => { fdescribe('Groups Component', () => {
let GroupsComponent; let GroupsComponent;
let store; let store;
let component; let component;
......
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