Commit 2ab68081 authored by Illya Klymov's avatar Illya Klymov

Merge branch '336969-add-empty-state' into 'master'

Add empty state for CI minutes usage quotas

See merge request gitlab-org/gitlab!73681
parents f15b64dd 9252df6a
<script> <script>
import { GlAlert } from '@gitlab/ui';
import { GlAreaChart } from '@gitlab/ui/dist/charts'; import { GlAreaChart } from '@gitlab/ui/dist/charts';
import { USAGE_BY_MONTH, X_AXIS_MONTH_LABEL, X_AXIS_CATEGORY, Y_AXIS_LABEL } from '../constants'; import {
USAGE_BY_MONTH,
X_AXIS_MONTH_LABEL,
X_AXIS_CATEGORY,
Y_AXIS_LABEL,
NO_CI_MINUTES_MSG,
} from '../constants';
export default { export default {
USAGE_BY_MONTH, USAGE_BY_MONTH,
X_AXIS_MONTH_LABEL, X_AXIS_MONTH_LABEL,
X_AXIS_CATEGORY, X_AXIS_CATEGORY,
Y_AXIS_LABEL, Y_AXIS_LABEL,
NO_CI_MINUTES_MSG,
components: { components: {
GlAlert,
GlAreaChart, GlAreaChart,
}, },
props: { props: {
...@@ -46,5 +55,8 @@ export default { ...@@ -46,5 +55,8 @@ export default {
<div> <div>
<h5>{{ $options.USAGE_BY_MONTH }}</h5> <h5>{{ $options.USAGE_BY_MONTH }}</h5>
<gl-area-chart v-if="!isDataEmpty" class="gl-mb-3" :data="chartData" :option="chartOptions" /> <gl-area-chart v-if="!isDataEmpty" class="gl-mb-3" :data="chartData" :option="chartOptions" />
<gl-alert v-else class="gl-mb-5" :dismissible="false">
{{ $options.NO_CI_MINUTES_MSG }}
</gl-alert>
</div> </div>
</template> </template>
<script> <script>
import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { GlAlert, GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { GlColumnChart } from '@gitlab/ui/dist/charts'; import { GlColumnChart } from '@gitlab/ui/dist/charts';
import { keyBy } from 'lodash'; import { keyBy } from 'lodash';
import { __ } from '~/locale'; import { __ } from '~/locale';
...@@ -8,6 +8,7 @@ import { ...@@ -8,6 +8,7 @@ import {
X_AXIS_PROJECT_LABEL, X_AXIS_PROJECT_LABEL,
X_AXIS_CATEGORY, X_AXIS_CATEGORY,
Y_AXIS_LABEL, Y_AXIS_LABEL,
NO_CI_MINUTES_MSG,
} from '../constants'; } from '../constants';
export default { export default {
...@@ -15,6 +16,7 @@ export default { ...@@ -15,6 +16,7 @@ export default {
X_AXIS_PROJECT_LABEL, X_AXIS_PROJECT_LABEL,
X_AXIS_CATEGORY, X_AXIS_CATEGORY,
Y_AXIS_LABEL, Y_AXIS_LABEL,
NO_CI_MINUTES_MSG,
i18n: { i18n: {
january: __('January'), january: __('January'),
february: __('February'), february: __('February'),
...@@ -30,6 +32,7 @@ export default { ...@@ -30,6 +32,7 @@ export default {
december: __('December'), december: __('December'),
}, },
components: { components: {
GlAlert,
GlColumnChart, GlColumnChart,
GlDropdown, GlDropdown,
GlDropdownItem, GlDropdownItem,
...@@ -66,7 +69,7 @@ export default { ...@@ -66,7 +69,7 @@ export default {
return this.minutesUsageData.map((cur) => cur.month); return this.minutesUsageData.map((cur) => cur.month);
}, },
isDataEmpty() { isDataEmpty() {
return this.minutesUsageData.length === 0 && this.selectedMonth.length === 0; return this.minutesUsageData.length === 0 && !this.selectedMonth;
}, },
}, },
watch: { watch: {
...@@ -94,8 +97,9 @@ export default { ...@@ -94,8 +97,9 @@ export default {
</script> </script>
<template> <template>
<div> <div>
<div class="gl-display-flex gl-my-3"> <div class="gl-display-flex gl-mt-3" :class="{ 'gl-mb-3': !isDataEmpty }">
<h5 class="gl-flex-grow-1">{{ $options.USAGE_BY_PROJECT }}</h5> <h5 class="gl-flex-grow-1">{{ $options.USAGE_BY_PROJECT }}</h5>
<gl-dropdown v-if="!isDataEmpty" :text="selectedMonth" data-testid="project-month-dropdown"> <gl-dropdown v-if="!isDataEmpty" :text="selectedMonth" data-testid="project-month-dropdown">
<gl-dropdown-item <gl-dropdown-item
v-for="(monthName, index) in months" v-for="(monthName, index) in months"
...@@ -117,5 +121,8 @@ export default { ...@@ -117,5 +121,8 @@ export default {
:x-axis-title="$options.X_AXIS_PROJECT_LABEL" :x-axis-title="$options.X_AXIS_PROJECT_LABEL"
:x-axis-type="$options.X_AXIS_CATEGORY" :x-axis-type="$options.X_AXIS_CATEGORY"
/> />
<gl-alert v-else class="gl-mb-5" :dismissible="false">
{{ $options.NO_CI_MINUTES_MSG }}
</gl-alert>
</div> </div>
</template> </template>
...@@ -6,5 +6,6 @@ export const USAGE_BY_PROJECT = s__('UsageQuota|CI minutes usage by project'); ...@@ -6,5 +6,6 @@ export const USAGE_BY_PROJECT = s__('UsageQuota|CI minutes usage by project');
export const X_AXIS_MONTH_LABEL = __('Month'); export const X_AXIS_MONTH_LABEL = __('Month');
export const X_AXIS_PROJECT_LABEL = __('Projects'); export const X_AXIS_PROJECT_LABEL = __('Projects');
export const Y_AXIS_LABEL = __('Minutes'); export const Y_AXIS_LABEL = __('Minutes');
export const NO_CI_MINUTES_MSG = s__('UsageQuota|No CI minutes usage data available.');
export const X_AXIS_CATEGORY = 'category'; export const X_AXIS_CATEGORY = 'category';
import { GlAlert } from '@gitlab/ui';
import { GlAreaChart } from '@gitlab/ui/dist/charts'; import { GlAreaChart } from '@gitlab/ui/dist/charts';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import MinutesUsageMonthChart from 'ee/ci_minutes_usage/components/minutes_usage_month_chart.vue'; import MinutesUsageMonthChart from 'ee/ci_minutes_usage/components/minutes_usage_month_chart.vue';
import { ciMinutesUsageMockData } from '../mock_data'; import { ciMinutesUsageMockData } from '../mock_data';
const defaultProps = {
minutesUsageData: ciMinutesUsageMockData.data.ciMinutesUsage.nodes.map((cur) => [
cur.month,
cur.minutes,
]),
};
describe('Minutes usage by month chart component', () => { describe('Minutes usage by month chart component', () => {
let wrapper; let wrapper;
const findAreaChart = () => wrapper.findComponent(GlAreaChart); const findAreaChart = () => wrapper.findComponent(GlAreaChart);
const findAlert = () => wrapper.findComponent(GlAlert);
const createComponent = () => { const createComponent = (props = {}) => {
return shallowMount(MinutesUsageMonthChart, { wrapper = shallowMount(MinutesUsageMonthChart, {
propsData: { propsData: {
minutesUsageData: ciMinutesUsageMockData.data.ciMinutesUsage.nodes.map((cur) => [ ...defaultProps,
cur.month, ...props,
cur.minutes,
]),
}, },
}); });
}; };
beforeEach(() => {
wrapper = createComponent();
});
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
}); });
it('renders an area chart component', () => { it('renders an area chart component', () => {
createComponent();
expect(findAreaChart().exists()).toBe(true); expect(findAreaChart().exists()).toBe(true);
expect(findAlert().exists()).toBe(false);
});
it('renders an alert when no data is available', () => {
createComponent({ minutesUsageData: [] });
expect(findAlert().exists()).toBe(true);
}); });
}); });
import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { GlAlert, GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { GlColumnChart } from '@gitlab/ui/dist/charts'; import { GlColumnChart } from '@gitlab/ui/dist/charts';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import MinutesUsageProjectChart from 'ee/ci_minutes_usage/components/minutes_usage_project_chart.vue'; import MinutesUsageProjectChart from 'ee/ci_minutes_usage/components/minutes_usage_project_chart.vue';
import { ciMinutesUsageMockData } from '../mock_data'; import { ciMinutesUsageMockData } from '../mock_data';
const defaultProps = { minutesUsageData: ciMinutesUsageMockData.data.ciMinutesUsage.nodes };
describe('Minutes usage by project chart component', () => { describe('Minutes usage by project chart component', () => {
let wrapper; let wrapper;
const findColumnChart = () => wrapper.findComponent(GlColumnChart); const findColumnChart = () => wrapper.findComponent(GlColumnChart);
const findDropdown = () => wrapper.findComponent(GlDropdown); const findDropdown = () => wrapper.findComponent(GlDropdown);
const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem); const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
const findAlert = () => wrapper.findComponent(GlAlert);
const createComponent = () => { const createComponent = (props = {}) => {
return shallowMount(MinutesUsageProjectChart, { wrapper = shallowMount(MinutesUsageProjectChart, {
propsData: { propsData: {
minutesUsageData: ciMinutesUsageMockData.data.ciMinutesUsage.nodes, ...defaultProps,
...props,
}, },
}); });
}; };
beforeEach(() => {
wrapper = createComponent();
});
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
}); });
it('renders a column chart component with axis legends', () => { describe('with CI minutes data', () => {
expect(findColumnChart().exists()).toBe(true); beforeEach(() => {
expect(findColumnChart().props('xAxisTitle')).toBe('Projects'); createComponent();
expect(findColumnChart().props('yAxisTitle')).toBe('Minutes'); });
});
it('renders a column chart component with axis legends', () => {
expect(findColumnChart().exists()).toBe(true);
expect(findColumnChart().props('xAxisTitle')).toBe('Projects');
expect(findColumnChart().props('yAxisTitle')).toBe('Minutes');
expect(findAlert().exists()).toBe(false);
});
it('renders a dropdown component', () => {
expect(findDropdown().exists()).toBe(true);
expect(findDropdown().props('text')).toBe(
ciMinutesUsageMockData.data.ciMinutesUsage.nodes[0].month,
);
expect(findAlert().exists()).toBe(false);
});
it('renders a dropdown component', () => { it('renders the same amount of dropdown components as the backend response', () => {
expect(findDropdown().exists()).toBe(true); expect(findAllDropdownItems().length).toBe(
expect(findDropdown().props('text')).toBe( ciMinutesUsageMockData.data.ciMinutesUsage.nodes.length,
ciMinutesUsageMockData.data.ciMinutesUsage.nodes[0].month, );
); });
}); });
it('renders the same amount of dropdown components as the backend response', () => { describe('without CI minutes data', () => {
expect(findAllDropdownItems().length).toBe( it('renders an alert when no data is available', () => {
ciMinutesUsageMockData.data.ciMinutesUsage.nodes.length, createComponent({ minutesUsageData: [] });
);
expect(findAlert().exists()).toBe(true);
});
}); });
}); });
...@@ -37021,6 +37021,9 @@ msgstr "" ...@@ -37021,6 +37021,9 @@ msgstr ""
msgid "UsageQuota|Learn more about usage quotas" msgid "UsageQuota|Learn more about usage quotas"
msgstr "" msgstr ""
msgid "UsageQuota|No CI minutes usage data available."
msgstr ""
msgid "UsageQuota|Packages" msgid "UsageQuota|Packages"
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