From 5b74a1aebcc1712316b8269c415e83e9d59750d5 Mon Sep 17 00:00:00 2001 From: Dennis Tang Date: Fri, 7 Sep 2018 06:09:13 +0000 Subject: Resolve "Improve handling of projects shared with a group" --- .../pages/dashboard/groups/index/index.js | 4 +- .../javascripts/pages/groups/show/group_tabs.js | 136 +++++++++++++++++++++ app/assets/javascripts/pages/groups/show/index.js | 12 +- 3 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 app/assets/javascripts/pages/groups/show/group_tabs.js (limited to 'app/assets/javascripts/pages') diff --git a/app/assets/javascripts/pages/dashboard/groups/index/index.js b/app/assets/javascripts/pages/dashboard/groups/index/index.js index 79987642796..b9277106a71 100644 --- a/app/assets/javascripts/pages/dashboard/groups/index/index.js +++ b/app/assets/javascripts/pages/dashboard/groups/index/index.js @@ -1,3 +1,5 @@ import initGroupsList from '~/groups'; -document.addEventListener('DOMContentLoaded', initGroupsList); +document.addEventListener('DOMContentLoaded', () => { + initGroupsList(); +}); diff --git a/app/assets/javascripts/pages/groups/show/group_tabs.js b/app/assets/javascripts/pages/groups/show/group_tabs.js new file mode 100644 index 00000000000..c6fe61d2bd9 --- /dev/null +++ b/app/assets/javascripts/pages/groups/show/group_tabs.js @@ -0,0 +1,136 @@ +import $ from 'jquery'; +import { removeParams } from '~/lib/utils/url_utility'; +import createGroupTree from '~/groups'; +import { + ACTIVE_TAB_SUBGROUPS_AND_PROJECTS, + ACTIVE_TAB_SHARED, + ACTIVE_TAB_ARCHIVED, + CONTENT_LIST_CLASS, + GROUPS_LIST_HOLDER_CLASS, + GROUPS_FILTER_FORM_CLASS, +} from '~/groups/constants'; +import UserTabs from '~/pages/users/user_tabs'; +import GroupFilterableList from '~/groups/groups_filterable_list'; + +export default class GroupTabs extends UserTabs { + constructor({ defaultAction = 'subgroups_and_projects', action, parentEl }) { + super({ defaultAction, action, parentEl }); + } + + bindEvents() { + this.$parentEl + .off('shown.bs.tab', '.nav-links a[data-toggle="tab"]') + .on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', event => this.tabShown(event)); + } + + tabShown(event) { + const $target = $(event.target); + const action = $target.data('action') || $target.data('targetSection'); + const source = $target.attr('href') || $target.data('targetPath'); + + document.querySelector(GROUPS_FILTER_FORM_CLASS).action = source; + + this.setTab(action); + return this.setCurrentAction(source); + } + + setTab(action) { + const loadableActions = [ + ACTIVE_TAB_SUBGROUPS_AND_PROJECTS, + ACTIVE_TAB_SHARED, + ACTIVE_TAB_ARCHIVED, + ]; + this.enableSearchBar(action); + this.action = action; + + if (this.loaded[action]) { + return; + } + + if (loadableActions.includes(action)) { + this.cleanFilterState(); + this.loadTab(action); + } + } + + loadTab(action) { + const elId = `js-groups-${action}-tree`; + const endpoint = this.getEndpoint(action); + + this.toggleLoading(true); + + createGroupTree(elId, endpoint, action); + this.loaded[action] = true; + + this.toggleLoading(false); + } + + getEndpoint(action) { + const { endpointsDefault, endpointsShared } = this.$parentEl.data(); + let endpoint; + + switch (action) { + case ACTIVE_TAB_ARCHIVED: + endpoint = `${endpointsDefault}?archived=only`; + break; + case ACTIVE_TAB_SHARED: + endpoint = endpointsShared; + break; + default: + // ACTIVE_TAB_SUBGROUPS_AND_PROJECTS + endpoint = endpointsDefault; + break; + } + + return endpoint; + } + + enableSearchBar(action) { + const containerEl = document.getElementById(action); + const form = document.querySelector(GROUPS_FILTER_FORM_CLASS); + const filter = form.querySelector('.js-groups-list-filter'); + const holder = containerEl.querySelector(GROUPS_LIST_HOLDER_CLASS); + const dataEl = containerEl.querySelector(CONTENT_LIST_CLASS); + const endpoint = this.getEndpoint(action); + + if (!dataEl) { + return; + } + + const { dataset } = dataEl; + const opts = { + form, + filter, + holder, + filterEndpoint: endpoint || dataset.endpoint, + pagePath: null, + dropdownSel: '.js-group-filter-dropdown-wrap', + filterInputField: 'filter', + action, + }; + + if (!this.loaded[action]) { + const filterableList = new GroupFilterableList(opts); + filterableList.initSearch(); + } + } + + cleanFilterState() { + const values = Object.values(this.loaded); + const loadedTabs = values.filter(e => e === true); + + if (!loadedTabs.length) { + return; + } + + const newState = removeParams(['page'], window.location.search); + + window.history.replaceState( + { + url: newState, + }, + document.title, + newState, + ); + } +} diff --git a/app/assets/javascripts/pages/groups/show/index.js b/app/assets/javascripts/pages/groups/show/index.js index d7b35d2b26b..5b8c2ae7e81 100644 --- a/app/assets/javascripts/pages/groups/show/index.js +++ b/app/assets/javascripts/pages/groups/show/index.js @@ -1,14 +1,22 @@ /* eslint-disable no-new */ +import { getPagePath } from '~/lib/utils/common_utils'; +import { ACTIVE_TAB_SHARED, ACTIVE_TAB_ARCHIVED } from '~/groups/constants'; import NewGroupChild from '~/groups/new_group_child'; import notificationsDropdown from '~/notifications_dropdown'; import NotificationsForm from '~/notifications_form'; import ProjectsList from '~/projects_list'; import ShortcutsNavigation from '~/shortcuts_navigation'; -import initGroupsList from '~/groups'; +import GroupTabs from './group_tabs'; document.addEventListener('DOMContentLoaded', () => { const newGroupChildWrapper = document.querySelector('.js-new-project-subgroup'); + const loadableActions = [ACTIVE_TAB_SHARED, ACTIVE_TAB_ARCHIVED]; + const paths = window.location.pathname.split('/'); + const subpath = paths[paths.length - 1]; + const action = loadableActions.includes(subpath) ? subpath : getPagePath(1); + + new GroupTabs({ parentEl: '.groups-listing', action }); new ShortcutsNavigation(); new NotificationsForm(); notificationsDropdown(); @@ -17,6 +25,4 @@ document.addEventListener('DOMContentLoaded', () => { if (newGroupChildWrapper) { new NewGroupChild(newGroupChildWrapper); } - - initGroupsList(); }); -- cgit v1.2.1