summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/groups
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-12-20 14:22:11 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-12-20 14:22:11 +0000
commit0c872e02b2c822e3397515ec324051ff540f0cd5 (patch)
treece2fb6ce7030e4dad0f4118d21ab6453e5938cdd /app/assets/javascripts/groups
parentf7e05a6853b12f02911494c4b3fe53d9540d74fc (diff)
downloadgitlab-ce-0c872e02b2c822e3397515ec324051ff540f0cd5.tar.gz
Add latest changes from gitlab-org/gitlab@15-7-stable-eev15.7.0-rc42
Diffstat (limited to 'app/assets/javascripts/groups')
-rw-r--r--app/assets/javascripts/groups/components/app.vue75
-rw-r--r--app/assets/javascripts/groups/components/empty_states/archived_projects_empty_state.vue21
-rw-r--r--app/assets/javascripts/groups/components/empty_states/shared_projects_empty_state.vue21
-rw-r--r--app/assets/javascripts/groups/components/empty_states/subgroups_and_projects_empty_state.vue (renamed from app/assets/javascripts/groups/components/empty_state.vue)1
-rw-r--r--app/assets/javascripts/groups/components/group_item.vue12
-rw-r--r--app/assets/javascripts/groups/components/group_name_and_path.vue2
-rw-r--r--app/assets/javascripts/groups/components/groups.vue23
-rw-r--r--app/assets/javascripts/groups/components/overview_tabs.vue35
-rw-r--r--app/assets/javascripts/groups/components/transfer_group_form.vue1
9 files changed, 101 insertions, 90 deletions
diff --git a/app/assets/javascripts/groups/components/app.vue b/app/assets/javascripts/groups/components/app.vue
index 15f5a3518a5..46d5341ea97 100644
--- a/app/assets/javascripts/groups/components/app.vue
+++ b/app/assets/javascripts/groups/components/app.vue
@@ -1,21 +1,25 @@
<script>
-import { GlLoadingIcon, GlModal } from '@gitlab/ui';
+import { GlLoadingIcon, GlModal, GlEmptyState } from '@gitlab/ui';
import { createAlert } from '~/flash';
import { mergeUrlParams, getParameterByName } from '~/lib/utils/url_utility';
-import { HIDDEN_CLASS } from '~/lib/utils/constants';
import { __, s__, sprintf } from '~/locale';
-import { COMMON_STR, CONTENT_LIST_CLASS } from '../constants';
+import { COMMON_STR } from '../constants';
import eventHub from '../event_hub';
import GroupsComponent from './groups.vue';
-import EmptyState from './empty_state.vue';
export default {
+ i18n: {
+ searchEmptyState: {
+ title: __('No results found'),
+ description: __('Edit your search and try again'),
+ },
+ },
components: {
GroupsComponent,
GlModal,
GlLoadingIcon,
- EmptyState,
+ GlEmptyState,
},
props: {
action: {
@@ -40,20 +44,14 @@ export default {
type: Boolean,
required: true,
},
- renderEmptyState: {
- type: Boolean,
- required: false,
- default: false,
- },
},
data() {
return {
isModalVisible: false,
isLoading: true,
- isSearchEmpty: false,
+ fromSearch: false,
targetGroup: null,
targetParentGroup: null,
- showEmptyState: false,
};
},
computed: {
@@ -79,6 +77,9 @@ export default {
groups() {
return this.store.getGroups();
},
+ hasGroups() {
+ return this.groups && this.groups.length > 0;
+ },
pageInfo() {
return this.store.getPaginationInfo();
},
@@ -231,47 +232,17 @@ export default {
this.targetGroup.isBeingRemoved = false;
});
},
- showLegacyEmptyState() {
- const { containerEl } = this;
-
- if (!containerEl) return;
-
- 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) {
- const hasGroups = groups && groups.length > 0;
-
- if (this.renderEmptyState) {
- this.isSearchEmpty = fromSearch && !hasGroups;
- } else {
- this.isSearchEmpty = !hasGroups;
- }
+ this.fromSearch = fromSearch;
if (fromSearch) {
this.store.setSearchedGroups(groups);
} else {
this.store.setGroups(groups);
}
-
- if (this.action && !hasGroups && !fromSearch) {
- if (this.renderEmptyState) {
- this.showEmptyState = true;
- } else {
- this.showLegacyEmptyState();
- }
- }
},
},
};
@@ -285,14 +256,16 @@ export default {
size="lg"
class="loading-animation prepend-top-20"
/>
- <groups-component
- v-else
- :groups="groups"
- :search-empty="isSearchEmpty"
- :page-info="pageInfo"
- :action="action"
- />
- <empty-state v-if="showEmptyState" />
+ <template v-else>
+ <groups-component v-if="hasGroups" :groups="groups" :page-info="pageInfo" :action="action" />
+ <gl-empty-state
+ v-else-if="fromSearch"
+ :title="$options.i18n.searchEmptyState.title"
+ :description="$options.i18n.searchEmptyState.description"
+ data-testid="search-empty-state"
+ />
+ <slot v-else name="empty-state"></slot>
+ </template>
<gl-modal
modal-id="leave-group-modal"
:visible="isModalVisible"
diff --git a/app/assets/javascripts/groups/components/empty_states/archived_projects_empty_state.vue b/app/assets/javascripts/groups/components/empty_states/archived_projects_empty_state.vue
new file mode 100644
index 00000000000..535758750f9
--- /dev/null
+++ b/app/assets/javascripts/groups/components/empty_states/archived_projects_empty_state.vue
@@ -0,0 +1,21 @@
+<script>
+import { GlEmptyState } from '@gitlab/ui';
+
+import { s__ } from '~/locale';
+
+export default {
+ components: { GlEmptyState },
+ i18n: {
+ title: s__('GroupsEmptyState|No archived projects.'),
+ },
+ inject: ['newProjectIllustration'],
+};
+</script>
+
+<template>
+ <gl-empty-state
+ :title="$options.i18n.title"
+ :svg-path="newProjectIllustration"
+ :svg-height="100"
+ />
+</template>
diff --git a/app/assets/javascripts/groups/components/empty_states/shared_projects_empty_state.vue b/app/assets/javascripts/groups/components/empty_states/shared_projects_empty_state.vue
new file mode 100644
index 00000000000..7223321bf3e
--- /dev/null
+++ b/app/assets/javascripts/groups/components/empty_states/shared_projects_empty_state.vue
@@ -0,0 +1,21 @@
+<script>
+import { GlEmptyState } from '@gitlab/ui';
+
+import { s__ } from '~/locale';
+
+export default {
+ components: { GlEmptyState },
+ i18n: {
+ title: s__('GroupsEmptyState|No shared projects.'),
+ },
+ inject: ['newProjectIllustration'],
+};
+</script>
+
+<template>
+ <gl-empty-state
+ :title="$options.i18n.title"
+ :svg-path="newProjectIllustration"
+ :svg-height="100"
+ />
+</template>
diff --git a/app/assets/javascripts/groups/components/empty_state.vue b/app/assets/javascripts/groups/components/empty_states/subgroups_and_projects_empty_state.vue
index 4219b52737d..955cb1ca63e 100644
--- a/app/assets/javascripts/groups/components/empty_state.vue
+++ b/app/assets/javascripts/groups/components/empty_states/subgroups_and_projects_empty_state.vue
@@ -83,7 +83,6 @@ export default {
</div>
<gl-empty-state
v-else
- class="gl-mt-5"
:title="$options.i18n.withoutLinks.title"
:svg-path="emptySubgroupIllustration"
:description="$options.i18n.withoutLinks.description"
diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue
index 961af800971..d9781ef9c84 100644
--- a/app/assets/javascripts/groups/components/group_item.vue
+++ b/app/assets/javascripts/groups/components/group_item.vue
@@ -9,8 +9,8 @@ import {
GlPopover,
GlLink,
GlTooltipDirective,
- GlSafeHtmlDirective,
} from '@gitlab/ui';
+import SafeHtml from '~/vue_shared/directives/safe_html';
import { visitUrl } from '~/lib/utils/url_utility';
import UserAccessRoleBadge from '~/vue_shared/components/user_access_role_badge.vue';
import { AVATAR_SHAPE_OPTION_RECT } from '~/vue_shared/constants';
@@ -29,7 +29,7 @@ import ItemTypeIcon from './item_type_icon.vue';
export default {
directives: {
GlTooltip: GlTooltipDirective,
- SafeHtml: GlSafeHtmlDirective,
+ SafeHtml,
},
components: {
GlAvatar,
@@ -200,11 +200,9 @@ export default {
class="no-expand gl-mr-3 gl-text-gray-900!"
:itemprop="microdata.nameItemprop"
>
- {{
- // ending bracket must be by closing tag to prevent
- // link hover text-decoration from over-extending
- group.name
- }}
+ <!-- ending bracket must be by closing tag to prevent -->
+ <!-- link hover text-decoration from over-extending -->
+ {{ group.name }}
</a>
<gl-icon
v-gl-tooltip.hover.bottom
diff --git a/app/assets/javascripts/groups/components/group_name_and_path.vue b/app/assets/javascripts/groups/components/group_name_and_path.vue
index 9a1ea2f1812..5f997ecc7ba 100644
--- a/app/assets/javascripts/groups/components/group_name_and_path.vue
+++ b/app/assets/javascripts/groups/components/group_name_and_path.vue
@@ -59,7 +59,7 @@ export default {
learnMore: s__('Groups|Learn more'),
},
inputSize: { md: 'lg' },
- changingGroupPathHelpPagePath: helpPagePath('user/group/index', {
+ changingGroupPathHelpPagePath: helpPagePath('user/group/manage', {
anchor: 'change-a-groups-path',
}),
mattermostDataBindName: 'create_chat_team',
diff --git a/app/assets/javascripts/groups/components/groups.vue b/app/assets/javascripts/groups/components/groups.vue
index 43aa0753082..5075be62214 100644
--- a/app/assets/javascripts/groups/components/groups.vue
+++ b/app/assets/javascripts/groups/components/groups.vue
@@ -1,5 +1,4 @@
<script>
-import { GlEmptyState } from '@gitlab/ui';
import PaginationLinks from '~/vue_shared/components/pagination_links.vue';
import { getParameterByName } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
@@ -12,7 +11,6 @@ export default {
},
components: {
PaginationLinks,
- GlEmptyState,
},
props: {
groups: {
@@ -23,10 +21,6 @@ export default {
type: Object,
required: true,
},
- searchEmpty: {
- type: Boolean,
- required: true,
- },
action: {
type: String,
required: false,
@@ -46,18 +40,11 @@ export default {
<template>
<div class="groups-list-tree-container" data-qa-selector="groups_list_tree_container">
- <gl-empty-state
- v-if="searchEmpty"
- :title="$options.i18n.emptyStateTitle"
- :description="$options.i18n.emptyStateDescription"
+ <group-folder :groups="groups" :action="action" />
+ <pagination-links
+ :change="change"
+ :page-info="pageInfo"
+ class="d-flex justify-content-center gl-mt-3"
/>
- <template v-else>
- <group-folder :groups="groups" :action="action" />
- <pagination-links
- :change="change"
- :page-info="pageInfo"
- class="d-flex justify-content-center gl-mt-3"
- />
- </template>
</div>
</template>
diff --git a/app/assets/javascripts/groups/components/overview_tabs.vue b/app/assets/javascripts/groups/components/overview_tabs.vue
index 46ab30367a0..79a2e11b0bb 100644
--- a/app/assets/javascripts/groups/components/overview_tabs.vue
+++ b/app/assets/javascripts/groups/components/overview_tabs.vue
@@ -13,19 +13,32 @@ import {
} from '../constants';
import eventHub from '../event_hub';
import GroupsApp from './app.vue';
+import SubgroupsAndProjectsEmptyState from './empty_states/subgroups_and_projects_empty_state.vue';
+import SharedProjectsEmptyState from './empty_states/shared_projects_empty_state.vue';
+import ArchivedProjectsEmptyState from './empty_states/archived_projects_empty_state.vue';
const [SORTING_ITEM_NAME] = OVERVIEW_TABS_SORTING_ITEMS;
const MIN_SEARCH_LENGTH = 3;
export default {
- components: { GlTabs, GlTab, GroupsApp, GlSearchBoxByType, GlSorting, GlSortingItem },
+ components: {
+ GlTabs,
+ GlTab,
+ GroupsApp,
+ GlSearchBoxByType,
+ GlSorting,
+ GlSortingItem,
+ SubgroupsAndProjectsEmptyState,
+ SharedProjectsEmptyState,
+ ArchivedProjectsEmptyState,
+ },
inject: ['endpoints', 'initialSort'],
data() {
const tabs = [
{
title: this.$options.i18n[ACTIVE_TAB_SUBGROUPS_AND_PROJECTS],
key: ACTIVE_TAB_SUBGROUPS_AND_PROJECTS,
- renderEmptyState: true,
+ emptyStateComponent: SubgroupsAndProjectsEmptyState,
lazy: this.$route.name !== ACTIVE_TAB_SUBGROUPS_AND_PROJECTS,
service: new GroupsService(this.endpoints[ACTIVE_TAB_SUBGROUPS_AND_PROJECTS]),
store: new GroupsStore({ showSchemaMarkup: true }),
@@ -33,7 +46,7 @@ export default {
{
title: this.$options.i18n[ACTIVE_TAB_SHARED],
key: ACTIVE_TAB_SHARED,
- renderEmptyState: false,
+ emptyStateComponent: SharedProjectsEmptyState,
lazy: this.$route.name !== ACTIVE_TAB_SHARED,
service: new GroupsService(this.endpoints[ACTIVE_TAB_SHARED]),
store: new GroupsStore(),
@@ -41,7 +54,7 @@ export default {
{
title: this.$options.i18n[ACTIVE_TAB_ARCHIVED],
key: ACTIVE_TAB_ARCHIVED,
- renderEmptyState: false,
+ emptyStateComponent: ArchivedProjectsEmptyState,
lazy: this.$route.name !== ACTIVE_TAB_ARCHIVED,
service: new GroupsService(this.endpoints[ACTIVE_TAB_ARCHIVED]),
store: new GroupsStore(),
@@ -158,18 +171,16 @@ export default {
<template>
<gl-tabs content-class="gl-pt-0" :value="activeTabIndex" @input="handleTabInput">
<gl-tab
- v-for="{ key, title, renderEmptyState, lazy, service, store } in tabs"
+ v-for="{ key, title, emptyStateComponent, lazy, service, store } in tabs"
:key="key"
:title="title"
:lazy="lazy"
>
- <groups-app
- :action="key"
- :service="service"
- :store="store"
- :hide-projects="false"
- :render-empty-state="renderEmptyState"
- />
+ <groups-app :action="key" :service="service" :store="store" :hide-projects="false">
+ <template v-if="emptyStateComponent" #empty-state>
+ <component :is="emptyStateComponent" />
+ </template>
+ </groups-app>
</gl-tab>
<template #tabs-end>
<li class="gl-flex-grow-1 gl-align-self-center gl-w-full gl-lg-w-auto gl-py-2">
diff --git a/app/assets/javascripts/groups/components/transfer_group_form.vue b/app/assets/javascripts/groups/components/transfer_group_form.vue
index 15a193f7cb8..3da417ebf0a 100644
--- a/app/assets/javascripts/groups/components/transfer_group_form.vue
+++ b/app/assets/javascripts/groups/components/transfer_group_form.vue
@@ -73,6 +73,7 @@ export default {
:disabled="disableSubmitButton"
:phrase="confirmationPhrase"
:button-text="confirmButtonText"
+ button-qa-selector="transfer_group_button"
@confirm="$emit('confirm')"
/>
</div>