From 5b74a1aebcc1712316b8269c415e83e9d59750d5 Mon Sep 17 00:00:00 2001 From: Dennis Tang Date: Fri, 7 Sep 2018 06:09:13 +0000 Subject: [PATCH] Resolve "Improve handling of projects shared with a group" --- .../javascripts/groups/components/app.vue | 78 ++++++---- .../groups/components/group_folder.vue | 7 +- .../groups/components/group_item.vue | 14 +- .../javascripts/groups/components/groups.vue | 68 +++++---- .../groups/components/item_actions.vue | 7 +- app/assets/javascripts/groups/constants.js | 24 +++- .../groups/groups_filterable_list.js | 62 ++++++-- app/assets/javascripts/groups/index.js | 31 +++- .../javascripts/lib/utils/url_utility.js | 4 +- .../pages/dashboard/groups/index/index.js | 4 +- .../pages/groups/show/group_tabs.js | 136 ++++++++++++++++++ .../javascripts/pages/groups/show/index.js | 12 +- app/assets/stylesheets/pages/groups.scss | 54 +++---- app/controllers/groups_controller.rb | 8 +- app/finders/group_descendants_finder.rb | 2 +- app/views/groups/_archived_projects.html.haml | 8 ++ app/views/groups/_children.html.haml | 4 - app/views/groups/_shared_projects.html.haml | 8 ++ .../groups/_subgroups_and_projects.html.haml | 8 ++ app/views/groups/show.html.haml | 37 +++-- ...html.haml => _new_project_group.html.haml} | 12 +- .../projects/project_members/index.html.haml | 16 +-- .../shared/groups/_empty_state.html.haml | 7 +- .../shared/groups/_search_form.html.haml | 4 +- ...ndling-of-projects-shared-with-a-group.yml | 5 + config/routes/group.rb | 3 + locale/gitlab.pot | 43 +++++- qa/qa/page/component/groups_filter.rb | 4 +- qa/qa/page/dashboard/groups.rb | 5 + qa/qa/page/group/show.rb | 4 +- spec/controllers/groups_controller_spec.rb | 8 -- ...ith_group_spec.rb => invite_group_spec.rb} | 38 ++--- .../settings/user_manages_group_links_spec.rb | 6 +- spec/finders/group_descendants_finder_spec.rb | 9 ++ .../javascripts/groups/components/app_spec.js | 102 +++++++------ 35 files changed, 593 insertions(+), 249 deletions(-) create mode 100644 app/assets/javascripts/pages/groups/show/group_tabs.js create mode 100644 app/views/groups/_archived_projects.html.haml delete mode 100644 app/views/groups/_children.html.haml create mode 100644 app/views/groups/_shared_projects.html.haml create mode 100644 app/views/groups/_subgroups_and_projects.html.haml rename app/views/projects/project_members/{_new_shared_group.html.haml => _new_project_group.html.haml} (59%) create mode 100644 changelogs/unreleased/44005-improve-handling-of-projects-shared-with-a-group.yml rename spec/features/projects/members/{share_with_group_spec.rb => invite_group_spec.rb} (81%) diff --git a/app/assets/javascripts/groups/components/app.vue b/app/assets/javascripts/groups/components/app.vue index b0765747a36..69f192ac75e 100644 --- a/app/assets/javascripts/groups/components/app.vue +++ b/app/assets/javascripts/groups/components/app.vue @@ -2,14 +2,15 @@ /* global Flash */ import $ from 'jquery'; -import { s__ } from '~/locale'; +import { s__, sprintf } from '~/locale'; import loadingIcon from '~/vue_shared/components/loading_icon.vue'; import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue'; +import { HIDDEN_CLASS } from '~/lib/utils/constants'; import { getParameterByName } from '~/lib/utils/common_utils'; import { mergeUrlParams } from '~/lib/utils/url_utility'; import eventHub from '../event_hub'; -import { COMMON_STR } from '../constants'; +import { COMMON_STR, CONTENT_LIST_CLASS } from '../constants'; import groupsComponent from './groups.vue'; export default { @@ -19,6 +20,16 @@ export default { groupsComponent, }, props: { + action: { + type: String, + required: false, + default: '', + }, + containerId: { + type: String, + required: false, + default: '', + }, store: { type: Object, required: true, @@ -56,31 +67,28 @@ export default { ? COMMON_STR.GROUP_SEARCH_EMPTY : COMMON_STR.GROUP_PROJECT_SEARCH_EMPTY; - eventHub.$on('fetchPage', this.fetchPage); - eventHub.$on('toggleChildren', this.toggleChildren); - eventHub.$on('showLeaveGroupModal', this.showLeaveGroupModal); - eventHub.$on('updatePagination', this.updatePagination); - eventHub.$on('updateGroups', this.updateGroups); + eventHub.$on(`${this.action}fetchPage`, this.fetchPage); + eventHub.$on(`${this.action}toggleChildren`, this.toggleChildren); + eventHub.$on(`${this.action}showLeaveGroupModal`, this.showLeaveGroupModal); + eventHub.$on(`${this.action}updatePagination`, this.updatePagination); + eventHub.$on(`${this.action}updateGroups`, this.updateGroups); }, mounted() { this.fetchAllGroups(); + + if (this.containerId) { + this.containerEl = document.getElementById(this.containerId); + } }, beforeDestroy() { - eventHub.$off('fetchPage', this.fetchPage); - eventHub.$off('toggleChildren', this.toggleChildren); - eventHub.$off('showLeaveGroupModal', this.showLeaveGroupModal); - eventHub.$off('updatePagination', this.updatePagination); - eventHub.$off('updateGroups', this.updateGroups); + eventHub.$off(`${this.action}fetchPage`, this.fetchPage); + eventHub.$off(`${this.action}toggleChildren`, this.toggleChildren); + eventHub.$off(`${this.action}showLeaveGroupModal`, this.showLeaveGroupModal); + eventHub.$off(`${this.action}updatePagination`, this.updatePagination); + eventHub.$off(`${this.action}updateGroups`, this.updateGroups); }, methods: { - fetchGroups({ - parentId, - page, - filterGroupsBy, - sortBy, - archived, - updatePagination, - }) { + fetchGroups({ parentId, page, filterGroupsBy, sortBy, archived, updatePagination }) { return this.service .getGroups(parentId, page, filterGroupsBy, sortBy, archived) .then(res => { @@ -165,13 +173,13 @@ export default { } }, showLeaveGroupModal(group, parentGroup) { + const { fullName } = group; this.targetGroup = group; this.targetParentGroup = parentGroup; this.showModal = true; - this.groupLeaveConfirmationMessage = s__( - `GroupsTree|Are you sure you want to leave the "${ - group.fullName - }" group?`, + this.groupLeaveConfirmationMessage = sprintf( + s__('GroupsTree|Are you sure you want to leave the "%{fullName}" group?'), + { fullName }, ); }, hideLeaveGroupModal() { @@ -197,16 +205,35 @@ export default { this.targetGroup.isBeingRemoved = false; }); }, + showEmptyState() { + const { containerEl } = this; + const contentListEl = containerEl.querySelector(CONTENT_LIST_CLASS); + const emptyStateEl = containerEl.querySelector('.empty-state'); + + if (contentListEl) { + contentListEl.remove(); + } + + if (emptyStateEl) { + emptyStateEl.classList.remove(HIDDEN_CLASS); + } + }, updatePagination(headers) { this.store.setPaginationInfo(headers); }, updateGroups(groups, fromSearch) { - this.isSearchEmpty = groups ? groups.length === 0 : false; + const hasGroups = groups && groups.length > 0; + this.isSearchEmpty = !hasGroups; + if (fromSearch) { this.store.setSearchedGroups(groups); } else { this.store.setGroups(groups); } + + if (this.action && !hasGroups && !fromSearch) { + this.showEmptyState(); + } }, }, }; @@ -226,6 +253,7 @@ export default { :search-empty="isSearchEmpty" :search-empty-message="searchEmptyMessage" :page-info="pageInfo" + :action="action" /> ([]), + default: '', }, }, computed: { @@ -37,6 +41,7 @@ export default { :key="index" :group="group" :parent-group="parentGroup" + :action="action" />
  • diff --git a/app/assets/javascripts/groups/components/groups.vue b/app/assets/javascripts/groups/components/groups.vue index 73ae928b0d9..a1beb222950 100644 --- a/app/assets/javascripts/groups/components/groups.vue +++ b/app/assets/javascripts/groups/components/groups.vue @@ -1,39 +1,44 @@