Commit 91dffb00 authored by Simon Knox's avatar Simon Knox

Merge branch '351853-vsa-add-empty-state-fe' into 'master'

Add VSA empty state component to base component

See merge request gitlab-org/gitlab!83712
parents 27484c9c d9acf737
......@@ -15,6 +15,7 @@ import { METRICS_REQUESTS } from '../constants';
import DurationChart from './duration_chart.vue';
import TypeOfWorkCharts from './type_of_work_charts.vue';
import ValueStreamAggregationStatus from './value_stream_aggregation_status.vue';
import ValueStreamEmptyState from './value_stream_empty_state.vue';
import ValueStreamSelect from './value_stream_select.vue';
export default {
......@@ -26,6 +27,7 @@ export default {
StageTable,
PathNavigation,
ValueStreamAggregationStatus,
ValueStreamEmptyState,
ValueStreamFilters,
ValueStreamMetrics,
ValueStreamSelect,
......@@ -74,9 +76,10 @@ export default {
'pathNavigationData',
'isOverviewStageSelected',
'selectedStageCount',
'hasValueStreams',
]),
shouldRenderEmptyState() {
return !this.currentGroup && !this.isLoading;
return this.isLoadingValueStreams || !this.hasValueStreams;
},
shouldDisplayFilters() {
return !this.errorCode && !this.hasNoAccessError;
......@@ -198,24 +201,25 @@ export default {
</script>
<template>
<div>
<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>
<div class="gl-display-flex gl-flex-direction-row gl-align-items-center gl-mt-0 gl-sm-mt-5">
<value-stream-aggregation-status v-if="isAggregationStatusAvailable" :data="aggregation" />
<value-stream-select v-if="shouldDisplayCreateMultipleValueStreams" />
</div>
</div>
<gl-empty-state
<value-stream-empty-state
v-if="shouldRenderEmptyState"
:title="__('Value Stream Analytics can help you determine your team’s velocity')"
:description="
__('Filter parameters are not valid. Make sure that the end date is after the start date.')
"
:svg-path="emptyStateSvgPath"
:is-loading="isLoadingValueStreams"
:empty-state-svg-path="emptyStateSvgPath"
:has-date-range-error="!hasDateRangeSet"
/>
<div v-else class="gl-max-w-full">
<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>
<div class="gl-display-flex gl-flex-direction-row gl-align-items-center gl-mt-0 gl-sm-mt-5">
<value-stream-aggregation-status
v-if="isAggregationStatusAvailable"
:data="aggregation"
/>
<value-stream-select v-if="shouldDisplayCreateMultipleValueStreams" />
</div>
</div>
<path-navigation
v-if="selectedStageReady"
data-testid="vsa-path-navigation"
......
......@@ -76,6 +76,7 @@ export default {
:svg-path="emptyStateSvgPath"
:title="title"
:description="description"
data-testid="vsa-empty-state"
>
<template v-if="!hasDateRangeError" #actions>
<gl-button
......
......@@ -13,6 +13,8 @@ import { DEFAULT_VALUE_STREAM_ID, OVERVIEW_STAGE_CONFIG } from '../constants';
export const hasNoAccessError = (state) => state.errorCode === httpStatus.FORBIDDEN;
export const hasValueStreams = ({ valueStreams }) => Boolean(valueStreams?.length);
export const currentValueStreamId = ({ selectedValueStream }) =>
selectedValueStream?.id || DEFAULT_VALUE_STREAM_ID;
......
......@@ -9,6 +9,7 @@ import DurationChart from 'ee/analytics/cycle_analytics/components/duration_char
import TypeOfWorkCharts from 'ee/analytics/cycle_analytics/components/type_of_work_charts.vue';
import ValueStreamSelect from 'ee/analytics/cycle_analytics/components/value_stream_select.vue';
import ValueStreamAggregationStatus from 'ee/analytics/cycle_analytics/components/value_stream_aggregation_status.vue';
import ValueStreamEmptyState from 'ee/analytics/cycle_analytics/components/value_stream_empty_state.vue';
import createStore from 'ee/analytics/cycle_analytics/store';
import waitForPromises from 'helpers/wait_for_promises';
import {
......@@ -195,11 +196,12 @@ describe('EE Value Stream Analytics component', () => {
expect(wrapper.findComponent(ValueStreamSelect).exists()).toBe(flag);
};
describe('without a group', () => {
describe('with no value streams', () => {
beforeEach(async () => {
const { group, ...stateWithoutGroup } = initialCycleAnalyticsState;
mock = new MockAdapter(axios);
wrapper = await createComponent({ initialState: stateWithoutGroup });
wrapper = await createComponent({
initialState: { ...initialCycleAnalyticsState, valueStreams: [] },
});
});
afterEach(() => {
......@@ -209,10 +211,10 @@ describe('EE Value Stream Analytics component', () => {
});
it('displays an empty state', () => {
const emptyState = wrapper.findComponent(GlEmptyState);
const emptyState = wrapper.findComponent(ValueStreamEmptyState);
expect(emptyState.exists()).toBe(true);
expect(emptyState.props('svgPath')).toBe(emptyStateSvgPath);
expect(emptyState.props('emptyStateSvgPath')).toBe(emptyStateSvgPath);
});
it('does not display the metrics cards', () => {
......
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