Commit 66ca03db authored by Martin Wortschack's avatar Martin Wortschack

Merge branch '221202-boilerplate-create-new-value-stream' into 'master'

Boilerplate - Create new value stream MVC

See merge request gitlab-org/gitlab!35822
parents 2b06da87 2c7b3384
<script> <script>
import { GlEmptyState, GlLoadingIcon } from '@gitlab/ui'; import { GlEmptyState, GlLoadingIcon, GlButton } from '@gitlab/ui';
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import { mapActions, mapState, mapGetters } from 'vuex'; import { mapActions, mapState, mapGetters } from 'vuex';
import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants'; import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants';
import { PROJECTS_PER_PAGE, STAGE_ACTIONS } from '../constants'; import { PROJECTS_PER_PAGE, STAGE_ACTIONS } from '../constants';
...@@ -25,6 +26,7 @@ export default { ...@@ -25,6 +26,7 @@ export default {
components: { components: {
DateRange, DateRange,
DurationChart, DurationChart,
GlButton,
GlLoadingIcon, GlLoadingIcon,
GlEmptyState, GlEmptyState,
GroupsDropdownFilter, GroupsDropdownFilter,
...@@ -111,9 +113,15 @@ export default { ...@@ -111,9 +113,15 @@ export default {
// https://gitlab.com/gitlab-org/gitlab/-/issues/223735 // https://gitlab.com/gitlab-org/gitlab/-/issues/223735
return this.featureFlags.hasFilterBar && this.currentGroupPath; return this.featureFlags.hasFilterBar && this.currentGroupPath;
}, },
shouldDisplayCreateMultipleValueStreams() {
return Boolean(this.featureFlags.hasCreateMultipleValueStreams);
},
isLoadingTypeOfWork() { isLoadingTypeOfWork() {
return this.isLoadingTasksByTypeChartTopLabels || this.isLoadingTasksByTypeChart; return this.isLoadingTasksByTypeChartTopLabels || this.isLoadingTasksByTypeChart;
}, },
isXSBreakpoint() {
return bp.getBreakpointSize() === 'xs';
},
hasDateRangeSet() { hasDateRangeSet() {
return this.startDate && this.endDate; return this.startDate && this.endDate;
}, },
...@@ -190,6 +198,9 @@ export default { ...@@ -190,6 +198,9 @@ export default {
onStageReorder(data) { onStageReorder(data) {
this.reorderStage(data); this.reorderStage(data);
}, },
onCreateValueStream() {
// stub handler - to be implemented in a follow up
},
}, },
multiProjectSelect: true, multiProjectSelect: true,
dateOptions: [7, 30, 90], dateOptions: [7, 30, 90],
...@@ -208,8 +219,22 @@ export default { ...@@ -208,8 +219,22 @@ export default {
</script> </script>
<template> <template>
<div> <div>
<div class="mb-3"> <div
class="gl-mb-3 gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row gl-justify-content-space-between"
>
<h3>{{ __('Value Stream Analytics') }}</h3> <h3>{{ __('Value Stream Analytics') }}</h3>
<div
v-if="shouldDisplayCreateMultipleValueStreams"
class="gl-align-self-center"
:class="{
'gl-w-full': isXSBreakpoint,
'gl-mt-5': !isXSBreakpoint,
}"
>
<gl-button data-testid="create-value-stream" @click="onCreateValueStream">{{
__('Create new value stream')
}}</gl-button>
</div>
</div> </div>
<div class="mw-100"> <div class="mw-100">
<div class="mt-3 py-2 px-3 bg-gray-light border-top border-bottom"> <div class="mt-3 py-2 px-3 bg-gray-light border-top border-bottom">
......
...@@ -14,11 +14,18 @@ export default () => { ...@@ -14,11 +14,18 @@ export default () => {
cycleAnalyticsScatterplotMedianEnabled: hasDurationChartMedian = false, cycleAnalyticsScatterplotMedianEnabled: hasDurationChartMedian = false,
valueStreamAnalyticsPathNavigation: hasPathNavigation = false, valueStreamAnalyticsPathNavigation: hasPathNavigation = false,
valueStreamAnalyticsFilterBar: hasFilterBar = false, valueStreamAnalyticsFilterBar: hasFilterBar = false,
valueStreamAnalyticsCreateMultipleValueStreams: hasCreateMultipleValueStreams = false,
} = gon?.features; } = gon?.features;
store.dispatch('initializeCycleAnalytics', { store.dispatch('initializeCycleAnalytics', {
...initialData, ...initialData,
featureFlags: { hasDurationChart, hasDurationChartMedian, hasPathNavigation, hasFilterBar }, featureFlags: {
hasDurationChart,
hasDurationChartMedian,
hasPathNavigation,
hasFilterBar,
hasCreateMultipleValueStreams,
},
}); });
return new Vue({ return new Vue({
......
...@@ -16,6 +16,7 @@ class Analytics::CycleAnalyticsController < Analytics::ApplicationController ...@@ -16,6 +16,7 @@ class Analytics::CycleAnalyticsController < Analytics::ApplicationController
push_frontend_feature_flag(:cycle_analytics_scatterplot_median_enabled, default_enabled: true) push_frontend_feature_flag(:cycle_analytics_scatterplot_median_enabled, default_enabled: true)
push_frontend_feature_flag(:value_stream_analytics_path_navigation, @group) push_frontend_feature_flag(:value_stream_analytics_path_navigation, @group)
push_frontend_feature_flag(:value_stream_analytics_filter_bar, @group) push_frontend_feature_flag(:value_stream_analytics_filter_bar, @group)
push_frontend_feature_flag(:value_stream_analytics_create_multiple_value_streams, @group)
end end
private private
......
...@@ -48,4 +48,16 @@ RSpec.describe 'Group value stream analytics' do ...@@ -48,4 +48,16 @@ RSpec.describe 'Group value stream analytics' do
expect(page).to have_pushed_frontend_feature_flags(valueStreamAnalyticsFilterBar: false) expect(page).to have_pushed_frontend_feature_flags(valueStreamAnalyticsFilterBar: false)
end end
end end
context 'when `value_stream_analytics_create_multiple_value_streams` is disabled for a group' do
before do
stub_feature_flags(value_stream_analytics_create_multiple_value_streams: false, thing: group)
end
it 'pushes disabled feature flag to the frontend' do
visit group_analytics_cycle_analytics_path(group)
expect(page).to have_pushed_frontend_feature_flags(valueStreamAnalyticsCreateMultipleValueStreams: false)
end
end
end end
...@@ -51,6 +51,7 @@ const defaultFeatureFlags = { ...@@ -51,6 +51,7 @@ const defaultFeatureFlags = {
hasDurationChartMedian: true, hasDurationChartMedian: true,
hasPathNavigation: false, hasPathNavigation: false,
hasFilterBar: false, hasFilterBar: false,
hasCreateMultipleValueStreams: false,
}; };
const initialCycleAnalyticsState = { const initialCycleAnalyticsState = {
...@@ -169,6 +170,10 @@ describe('Cycle Analytics component', () => { ...@@ -169,6 +170,10 @@ describe('Cycle Analytics component', () => {
expect(wrapper.find(FilterBar).exists()).toBe(flag); expect(wrapper.find(FilterBar).exists()).toBe(flag);
}; };
const displaysCreateValueStream = flag => {
expect(wrapper.find('[data-testid="create-value-stream"]').exists()).toBe(flag);
};
beforeEach(() => { beforeEach(() => {
mock = new MockAdapter(axios); mock = new MockAdapter(axios);
wrapper = createComponent({ wrapper = createComponent({
...@@ -232,6 +237,9 @@ describe('Cycle Analytics component', () => { ...@@ -232,6 +237,9 @@ describe('Cycle Analytics component', () => {
it('does not display the path navigation', () => { it('does not display the path navigation', () => {
displaysPathNavigation(false); displaysPathNavigation(false);
}); });
it('does not display the create multiple value streams button', () => {
displaysCreateValueStream(false);
});
describe('hideGroupDropDown = true', () => { describe('hideGroupDropDown = true', () => {
beforeEach(() => { beforeEach(() => {
...@@ -247,6 +255,21 @@ describe('Cycle Analytics component', () => { ...@@ -247,6 +255,21 @@ describe('Cycle Analytics component', () => {
expect(wrapper.find(GroupsDropdownFilter).exists()).toBe(false); expect(wrapper.find(GroupsDropdownFilter).exists()).toBe(false);
}); });
}); });
describe('hasCreateMultipleValueStreams = true', () => {
beforeEach(() => {
mock = new MockAdapter(axios);
wrapper = createComponent({
featureFlags: {
hasCreateMultipleValueStreams: true,
},
});
});
it('displays the create multiple value streams button', () => {
displaysCreateValueStream(true);
});
});
}); });
describe('after a filter has been selected', () => { describe('after a filter has been selected', () => {
......
...@@ -6821,6 +6821,9 @@ msgstr "" ...@@ -6821,6 +6821,9 @@ msgstr ""
msgid "Create new label" msgid "Create new label"
msgstr "" msgstr ""
msgid "Create new value stream"
msgstr ""
msgid "Create new..." msgid "Create new..."
msgstr "" msgstr ""
......
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