Commit 61506593 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '216078-child-epic-icon-visible-on-roadmap-for-premium-accounts' into 'master'

Hide child epic icon on Roadmap for Premium accounts

See merge request gitlab-org/gitlab!31250
parents 39d4fbe8 a6f5aa3a
<script> <script>
import { mapState } from 'vuex';
import { GlButton, GlIcon, GlLoadingIcon, GlTooltip } from '@gitlab/ui'; import { GlButton, GlIcon, GlLoadingIcon, GlTooltip } from '@gitlab/ui';
import { __, n__ } from '~/locale'; import { __, n__ } from '~/locale';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
...@@ -43,6 +44,7 @@ export default { ...@@ -43,6 +44,7 @@ export default {
}, },
}, },
computed: { computed: {
...mapState(['allowSubEpics']),
itemId() { itemId() {
return this.epic.id; return this.epic.id;
}, },
...@@ -154,6 +156,7 @@ export default { ...@@ -154,6 +156,7 @@ export default {
<p class="epic-timeframe" :title="timeframeString">{{ timeframeString }}</p> <p class="epic-timeframe" :title="timeframeString">{{ timeframeString }}</p>
</div> </div>
</div> </div>
<template v-if="allowSubEpics">
<div ref="childEpicsCount" class="d-flex text-secondary text-nowrap"> <div ref="childEpicsCount" class="d-flex text-secondary text-nowrap">
<gl-icon name="epic" class="align-text-bottom mr-1" aria-hidden="true" /> <gl-icon name="epic" class="align-text-bottom mr-1" aria-hidden="true" />
<p class="m-0" :aria-label="childEpicsCountText">{{ childEpicsCount }}</p> <p class="m-0" :aria-label="childEpicsCountText">{{ childEpicsCount }}</p>
...@@ -162,6 +165,7 @@ export default { ...@@ -162,6 +165,7 @@ export default {
<span :class="{ bold: hasFiltersApplied }">{{ childEpicsCountText }}</span> <span :class="{ bold: hasFiltersApplied }">{{ childEpicsCountText }}</span>
<span v-if="hasFiltersApplied" class="d-block">{{ childEpicsSearchText }}</span> <span v-if="hasFiltersApplied" class="d-block">{{ childEpicsSearchText }}</span>
</gl-tooltip> </gl-tooltip>
</template>
</div> </div>
</div> </div>
</template> </template>
...@@ -78,6 +78,7 @@ export default () => { ...@@ -78,6 +78,7 @@ export default () => {
return { return {
emptyStateIllustrationPath: dataset.emptyStateIllustration, emptyStateIllustrationPath: dataset.emptyStateIllustration,
hasFiltersApplied: parseBoolean(dataset.hasFiltersApplied), hasFiltersApplied: parseBoolean(dataset.hasFiltersApplied),
allowSubEpics: parseBoolean(dataset.allowSubEpics),
defaultInnerHeight: Number(dataset.innerHeight), defaultInnerHeight: Number(dataset.innerHeight),
isChildEpics: parseBoolean(dataset.childEpics), isChildEpics: parseBoolean(dataset.childEpics),
currentGroupId: parseInt(dataset.groupId, 0), currentGroupId: parseInt(dataset.groupId, 0),
...@@ -109,6 +110,7 @@ export default () => { ...@@ -109,6 +110,7 @@ export default () => {
initialEpicsPath: this.initialEpicsPath, initialEpicsPath: this.initialEpicsPath,
defaultInnerHeight: this.defaultInnerHeight, defaultInnerHeight: this.defaultInnerHeight,
isChildEpics: this.isChildEpics, isChildEpics: this.isChildEpics,
allowSubEpics: this.allowSubEpics,
}); });
}, },
methods: { methods: {
......
...@@ -33,4 +33,5 @@ export default () => ({ ...@@ -33,4 +33,5 @@ export default () => ({
milestonesFetchInProgress: false, milestonesFetchInProgress: false,
milestonesFetchFailure: false, milestonesFetchFailure: false,
milestonesFetchResultEmpty: false, milestonesFetchResultEmpty: false,
allowSubEpics: false,
}); });
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
- @content_class = "group-epics-roadmap" - @content_class = "group-epics-roadmap"
- breadcrumb_title _("Epics Roadmap") - breadcrumb_title _("Epics Roadmap")
- epics_limit_feature = 'epics_limit_warning_dismissed' - epics_limit_feature = 'epics_limit_warning_dismissed'
- sub_epics_feature_available = @group.feature_available?(:subepics)
- allow_sub_epics = sub_epics_feature_available ? 'true' : 'false'
- has_filters_applied = params[:label_name].present? || params[:author_username].present? || params[:search].present? - has_filters_applied = params[:label_name].present? || params[:author_username].present? || params[:search].present?
...@@ -21,7 +23,7 @@ ...@@ -21,7 +23,7 @@
%a.btn.btn-outline-warning#js-learn-more{ "href" => "https://docs.gitlab.com/ee/user/group/roadmap/" } %a.btn.btn-outline-warning#js-learn-more{ "href" => "https://docs.gitlab.com/ee/user/group/roadmap/" }
= _("Learn more") = _("Learn more")
#js-roadmap{ data: { epics_path: group_epics_path(@group, format: :json), group_id: @group.id, full_path: @group.full_path, empty_state_illustration: image_path('illustrations/epics/roadmap.svg'), has_filters_applied: "#{has_filters_applied}", new_epic_endpoint: group_epics_path(@group), preset_type: roadmap_layout, epics_state: @epics_state, sorted_by: @sort } } #js-roadmap{ data: { epics_path: group_epics_path(@group, format: :json), group_id: @group.id, full_path: @group.full_path, empty_state_illustration: image_path('illustrations/epics/roadmap.svg'), has_filters_applied: "#{has_filters_applied}", new_epic_endpoint: group_epics_path(@group), preset_type: roadmap_layout, epics_state: @epics_state, sorted_by: @sort, allow_sub_epics: allow_sub_epics } }
- else - else
= render 'shared/empty_states/roadmap' = render 'shared/empty_states/roadmap'
---
title: Hide child epic icon on Roadmap for accounts without child epics support
merge_request: 31250
author:
type: fixed
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import createStore from 'ee/roadmap/store';
import EpicItem from 'ee/roadmap/components/epic_item.vue'; import EpicItem from 'ee/roadmap/components/epic_item.vue';
import EpicItemContainer from 'ee/roadmap/components/epic_item_container.vue'; import EpicItemContainer from 'ee/roadmap/components/epic_item_container.vue';
...@@ -13,6 +14,8 @@ import { ...@@ -13,6 +14,8 @@ import {
mockFormattedChildEpic1, mockFormattedChildEpic1,
} from 'ee_jest/roadmap/mock_data'; } from 'ee_jest/roadmap/mock_data';
let store;
const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate);
const createComponent = ({ const createComponent = ({
...@@ -26,6 +29,7 @@ const createComponent = ({ ...@@ -26,6 +29,7 @@ const createComponent = ({
hasFiltersApplied = false, hasFiltersApplied = false,
} = {}) => { } = {}) => {
return mount(EpicItemContainer, { return mount(EpicItemContainer, {
store,
stubs: { stubs: {
'epic-item': EpicItem, 'epic-item': EpicItem,
}, },
...@@ -46,6 +50,7 @@ describe('EpicItemContainer', () => { ...@@ -46,6 +50,7 @@ describe('EpicItemContainer', () => {
let wrapper; let wrapper;
beforeEach(() => { beforeEach(() => {
store = createStore();
wrapper = createComponent(); wrapper = createComponent();
}); });
......
import { GlButton, GlIcon, GlTooltip } from '@gitlab/ui'; import { GlButton, GlIcon, GlTooltip } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import createStore from 'ee/roadmap/store';
import EpicItemDetails from 'ee/roadmap/components/epic_item_details.vue'; import EpicItemDetails from 'ee/roadmap/components/epic_item_details.vue';
import eventHub from 'ee/roadmap/event_hub'; import eventHub from 'ee/roadmap/event_hub';
import { import {
...@@ -9,6 +10,8 @@ import { ...@@ -9,6 +10,8 @@ import {
mockFormattedChildEpic1, mockFormattedChildEpic1,
} from 'ee_jest/roadmap/mock_data'; } from 'ee_jest/roadmap/mock_data';
let store;
const createComponent = ({ const createComponent = ({
epic = mockFormattedEpic, epic = mockFormattedEpic,
currentGroupId = mockGroupId, currentGroupId = mockGroupId,
...@@ -19,6 +22,7 @@ const createComponent = ({ ...@@ -19,6 +22,7 @@ const createComponent = ({
isChildrenEmpty = false, isChildrenEmpty = false,
} = {}) => { } = {}) => {
return shallowMount(EpicItemDetails, { return shallowMount(EpicItemDetails, {
store,
propsData: { propsData: {
epic, epic,
currentGroupId, currentGroupId,
...@@ -43,6 +47,7 @@ describe('EpicItemDetails', () => { ...@@ -43,6 +47,7 @@ describe('EpicItemDetails', () => {
let wrapper; let wrapper;
beforeEach(() => { beforeEach(() => {
store = createStore();
wrapper = createComponent(); wrapper = createComponent();
}); });
...@@ -131,6 +136,10 @@ describe('EpicItemDetails', () => { ...@@ -131,6 +136,10 @@ describe('EpicItemDetails', () => {
}); });
describe('epic', () => { describe('epic', () => {
beforeEach(() => {
store.state.allowSubEpics = true;
});
describe('expand icon', () => { describe('expand icon', () => {
it('is hidden when epic has no child epics', () => { it('is hidden when epic has no child epics', () => {
const epic = { const epic = {
...@@ -325,6 +334,12 @@ describe('EpicItemDetails', () => { ...@@ -325,6 +334,12 @@ describe('EpicItemDetails', () => {
'1 child epic Some child epics may be hidden due to applied filters', '1 child epic Some child epics may be hidden due to applied filters',
); );
}); });
it('does not render if the user license does not support child epics', () => {
store.state.allowSubEpics = false;
wrapper = createComponent();
expect(getChildEpicsCount(wrapper).exists()).toBe(false);
});
}); });
}); });
}); });
...@@ -2,6 +2,7 @@ import { mount } from '@vue/test-utils'; ...@@ -2,6 +2,7 @@ import { mount } from '@vue/test-utils';
import { delay } from 'lodash'; import { delay } from 'lodash';
import createStore from 'ee/roadmap/store';
import EpicItemComponent from 'ee/roadmap/components/epic_item.vue'; import EpicItemComponent from 'ee/roadmap/components/epic_item.vue';
import EpicItemContainer from 'ee/roadmap/components/epic_item_container.vue'; import EpicItemContainer from 'ee/roadmap/components/epic_item_container.vue';
...@@ -24,6 +25,8 @@ jest.mock('lodash/delay', () => ...@@ -24,6 +25,8 @@ jest.mock('lodash/delay', () =>
}), }),
); );
let store;
const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate);
const createComponent = ({ const createComponent = ({
...@@ -37,6 +40,7 @@ const createComponent = ({ ...@@ -37,6 +40,7 @@ const createComponent = ({
hasFiltersApplied = false, hasFiltersApplied = false,
}) => { }) => {
return mount(EpicItemComponent, { return mount(EpicItemComponent, {
store,
stubs: { stubs: {
'epic-item-container': EpicItemContainer, 'epic-item-container': EpicItemContainer,
'epic-item': EpicItemComponent, 'epic-item': EpicItemComponent,
...@@ -58,6 +62,7 @@ describe('EpicItemComponent', () => { ...@@ -58,6 +62,7 @@ describe('EpicItemComponent', () => {
let wrapper; let wrapper;
beforeEach(() => { beforeEach(() => {
store = createStore();
wrapper = createComponent({}); wrapper = createComponent({});
}); });
......
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