diff options
Diffstat (limited to 'app/assets/javascripts/groups/components')
5 files changed, 126 insertions, 68 deletions
diff --git a/app/assets/javascripts/groups/components/app.vue b/app/assets/javascripts/groups/components/app.vue index cd5521c599e..0bd7371d39b 100644 --- a/app/assets/javascripts/groups/components/app.vue +++ b/app/assets/javascripts/groups/components/app.vue @@ -17,11 +17,6 @@ export default { GlLoadingIcon, EmptyState, }, - inject: { - renderEmptyState: { - default: false, - }, - }, props: { action: { type: String, @@ -45,6 +40,11 @@ export default { type: Boolean, required: true, }, + renderEmptyState: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { @@ -224,6 +224,9 @@ export default { }, showLegacyEmptyState() { const { containerEl } = this; + + if (!containerEl) return; + const contentListEl = containerEl.querySelector(CONTENT_LIST_CLASS); const emptyStateEl = containerEl.querySelector('.empty-state'); diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue index 2f182b86d2c..961af800971 100644 --- a/app/assets/javascripts/groups/components/group_item.vue +++ b/app/assets/javascripts/groups/components/group_item.vue @@ -16,15 +16,15 @@ import UserAccessRoleBadge from '~/vue_shared/components/user_access_role_badge. import { AVATAR_SHAPE_OPTION_RECT } from '~/vue_shared/constants'; import { helpPagePath } from '~/helpers/help_page_helper'; import { __ } from '~/locale'; -import { VISIBILITY_LEVELS_ENUM } from '~/visibility_level/constants'; +import { VISIBILITY_LEVELS_STRING_TO_INTEGER } from '~/visibility_level/constants'; import { VISIBILITY_TYPE_ICON, GROUP_VISIBILITY_TYPE, ITEM_TYPE } from '../constants'; import eventHub from '../event_hub'; -import itemActions from './item_actions.vue'; -import itemCaret from './item_caret.vue'; -import itemStats from './item_stats.vue'; -import itemTypeIcon from './item_type_icon.vue'; +import ItemActions from './item_actions.vue'; +import ItemCaret from './item_caret.vue'; +import ItemStats from './item_stats.vue'; +import ItemTypeIcon from './item_type_icon.vue'; export default { directives: { @@ -41,10 +41,10 @@ export default { GlPopover, GlLink, UserAccessRoleBadge, - itemCaret, - itemTypeIcon, - itemActions, - itemStats, + ItemCaret, + ItemTypeIcon, + ItemActions, + ItemStats, }, inject: ['currentGroupVisibility'], props: { @@ -111,8 +111,8 @@ export default { shouldShowVisibilityWarning() { return ( this.action === 'shared' && - VISIBILITY_LEVELS_ENUM[this.group.visibility] > - VISIBILITY_LEVELS_ENUM[this.currentGroupVisibility] + VISIBILITY_LEVELS_STRING_TO_INTEGER[this.group.visibility] > + VISIBILITY_LEVELS_STRING_TO_INTEGER[this.currentGroupVisibility] ); }, }, diff --git a/app/assets/javascripts/groups/components/item_stats.vue b/app/assets/javascripts/groups/components/item_stats.vue index 2aa812250a0..a4c163b0a81 100644 --- a/app/assets/javascripts/groups/components/item_stats.vue +++ b/app/assets/javascripts/groups/components/item_stats.vue @@ -1,19 +1,19 @@ <script> import { GlBadge } from '@gitlab/ui'; import isProjectPendingRemoval from 'ee_else_ce/groups/mixins/is_project_pending_removal'; -import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; +import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import { ITEM_TYPE, VISIBILITY_TYPE_ICON, GROUP_VISIBILITY_TYPE, PROJECT_VISIBILITY_TYPE, } from '../constants'; -import itemStatsValue from './item_stats_value.vue'; +import ItemStatsValue from './item_stats_value.vue'; export default { components: { - timeAgoTooltip, - itemStatsValue, + TimeAgoTooltip, + ItemStatsValue, GlBadge, }, mixins: [isProjectPendingRemoval], diff --git a/app/assets/javascripts/groups/components/overview_tabs.vue b/app/assets/javascripts/groups/components/overview_tabs.vue new file mode 100644 index 00000000000..325e42af0f8 --- /dev/null +++ b/app/assets/javascripts/groups/components/overview_tabs.vue @@ -0,0 +1,103 @@ +<script> +import { GlTabs, GlTab } from '@gitlab/ui'; +import { isString } from 'lodash'; +import { __ } from '~/locale'; +import GroupsStore from '../store/groups_store'; +import GroupsService from '../service/groups_service'; +import { + ACTIVE_TAB_SUBGROUPS_AND_PROJECTS, + ACTIVE_TAB_SHARED, + ACTIVE_TAB_ARCHIVED, +} from '../constants'; +import GroupsApp from './app.vue'; + +export default { + components: { GlTabs, GlTab, GroupsApp }, + inject: ['endpoints'], + data() { + return { + tabs: [ + { + title: this.$options.i18n[ACTIVE_TAB_SUBGROUPS_AND_PROJECTS], + key: ACTIVE_TAB_SUBGROUPS_AND_PROJECTS, + renderEmptyState: true, + lazy: false, + service: new GroupsService(this.endpoints[ACTIVE_TAB_SUBGROUPS_AND_PROJECTS]), + store: new GroupsStore({ showSchemaMarkup: true }), + }, + { + title: this.$options.i18n[ACTIVE_TAB_SHARED], + key: ACTIVE_TAB_SHARED, + renderEmptyState: false, + lazy: true, + service: new GroupsService(this.endpoints[ACTIVE_TAB_SHARED]), + store: new GroupsStore(), + }, + { + title: this.$options.i18n[ACTIVE_TAB_ARCHIVED], + key: ACTIVE_TAB_ARCHIVED, + renderEmptyState: false, + lazy: true, + service: new GroupsService(this.endpoints[ACTIVE_TAB_ARCHIVED]), + store: new GroupsStore(), + }, + ], + activeTabIndex: 0, + }; + }, + mounted() { + const activeTabIndex = this.tabs.findIndex((tab) => tab.key === this.$route.name); + + if (activeTabIndex === -1) { + return; + } + + this.activeTabIndex = activeTabIndex; + }, + methods: { + handleTabInput(tabIndex) { + if (tabIndex === this.activeTabIndex) { + return; + } + + this.activeTabIndex = tabIndex; + + const tab = this.tabs[tabIndex]; + tab.lazy = false; + + // Vue router will convert `/` to `%2F` if you pass a string as a param + // If you pass an array as a param it will concatenate them with a `/` + // This makes sure we are always passing an array for the group param + const groupParam = isString(this.$route.params.group) + ? this.$route.params.group.split('/') + : this.$route.params.group; + + this.$router.push({ name: tab.key, params: { group: groupParam } }); + }, + }, + i18n: { + [ACTIVE_TAB_SUBGROUPS_AND_PROJECTS]: __('Subgroups and projects'), + [ACTIVE_TAB_SHARED]: __('Shared projects'), + [ACTIVE_TAB_ARCHIVED]: __('Archived projects'), + }, +}; +</script> + +<template> + <gl-tabs content-class="gl-pt-0" :value="activeTabIndex" @input="handleTabInput"> + <gl-tab + v-for="{ key, title, renderEmptyState, 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" + /> + </gl-tab> + </gl-tabs> +</template> diff --git a/app/assets/javascripts/groups/components/visibility_level_dropdown.vue b/app/assets/javascripts/groups/components/visibility_level_dropdown.vue deleted file mode 100644 index 0933045fc38..00000000000 --- a/app/assets/javascripts/groups/components/visibility_level_dropdown.vue +++ /dev/null @@ -1,48 +0,0 @@ -<script> -import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; - -export default { - components: { - GlDropdown, - GlDropdownItem, - }, - props: { - visibilityLevelOptions: { - type: Array, - required: true, - }, - defaultLevel: { - type: Number, - required: true, - }, - }, - data() { - return { - selectedOption: this.getDefaultOption(), - }; - }, - methods: { - getDefaultOption() { - return this.visibilityLevelOptions.find((option) => option.level === this.defaultLevel); - }, - onClick(option) { - this.selectedOption = option; - }, - }, -}; -</script> -<template> - <div> - <input type="hidden" name="group[visibility_level]" :value="selectedOption.level" /> - <gl-dropdown :text="selectedOption.label" class="gl-w-full" menu-class="gl-w-full! gl-mb-0"> - <gl-dropdown-item - v-for="option in visibilityLevelOptions" - :key="option.level" - :secondary-text="option.description" - @click="onClick(option)" - > - <div class="gl-font-weight-bold gl-mb-1">{{ option.label }}</div> - </gl-dropdown-item> - </gl-dropdown> - </div> -</template> |