Commit 1402f830 authored by Brandon Labuschagne's avatar Brandon Labuschagne

Ensure that GlSingleStat animates

This commit ensures that the GlSingleStat component
is only mounted once for VSA and MR analytics in order
to allow the component to listen for changes and
animate accordingly.

Changelog: fixed
parent 5f4df28b
...@@ -91,24 +91,20 @@ export default { ...@@ -91,24 +91,20 @@ export default {
</script> </script>
<template> <template>
<div class="gl-display-flex gl-flex-wrap" data-testid="vsa-time-metrics"> <div class="gl-display-flex gl-flex-wrap" data-testid="vsa-time-metrics">
<div v-if="isLoading" class="gl-h-auto gl-py-3 gl-pr-9 gl-my-6"> <gl-skeleton-loading v-if="isLoading" class="gl-h-auto gl-py-3 gl-pr-9 gl-my-6" />
<gl-skeleton-loading /> <div v-for="metric in metrics" v-show="!isLoading" :key="metric.key" class="gl-my-6 gl-pr-9">
<gl-single-stat
:id="metric.key"
:value="`${metric.value}`"
:title="metric.label"
:unit="metric.unit || ''"
:should-animate="true"
:animation-decimal-places="1"
:class="{ 'gl-hover-cursor-pointer': hasLinks(metric.links) }"
tabindex="0"
@click="clickHandler(metric)"
/>
<metric-popover :metric="metric" :target="metric.key" />
</div> </div>
<template v-else>
<div v-for="metric in metrics" :key="metric.key" class="gl-my-6 gl-pr-9">
<gl-single-stat
:id="metric.key"
:value="`${metric.value}`"
:title="metric.label"
:unit="metric.unit || ''"
:should-animate="true"
:animation-decimal-places="1"
:class="{ 'gl-hover-cursor-pointer': hasLinks(metric.links) }"
tabindex="0"
@click="clickHandler(metric)"
/>
<metric-popover :metric="metric" :target="metric.key" />
</div>
</template>
</div> </div>
</template> </template>
...@@ -28,7 +28,7 @@ export default { ...@@ -28,7 +28,7 @@ export default {
<div v-for="stat in stats" :key="stat.title"> <div v-for="stat in stats" :key="stat.title">
<gl-skeleton-loader v-if="isLoading" :height="$options.loaderHeight" /> <gl-skeleton-loader v-if="isLoading" :height="$options.loaderHeight" />
<gl-single-stat <gl-single-stat
v-else v-show="!isLoading"
:value="stat.value" :value="stat.value"
:title="stat.title" :title="stat.title"
:unit="stat.unit" :unit="stat.unit"
......
...@@ -16,17 +16,27 @@ describe('ThroughputStats', () => { ...@@ -16,17 +16,27 @@ describe('ThroughputStats', () => {
}); });
}; };
afterEach(() => {
wrapper.destroy();
});
describe('default behaviour', () => { describe('default behaviour', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createWrapper(); wrapper = createWrapper();
}); });
it('displays a GlSingleStat component for each stat entry', () => { it('displays a GlSingleStat component for each stat entry', () => {
expect(wrapper.findAll(GlSingleStat)).toHaveLength(stats.length); const components = wrapper.findAllComponents(GlSingleStat);
expect(components).toHaveLength(stats.length);
stats.forEach((stat, index) => {
expect(components.at(index).isVisible()).toBe(true);
});
}); });
it('passes the GlSingleStat the correct props', () => { it('passes the GlSingleStat the correct props', () => {
const component = wrapper.findAll(GlSingleStat).at(0); const component = wrapper.findAllComponents(GlSingleStat).at(0);
const { title, unit, value } = stats[0]; const { title, unit, value } = stats[0];
expect(component.props('title')).toBe(title); expect(component.props('title')).toBe(title);
...@@ -35,7 +45,7 @@ describe('ThroughputStats', () => { ...@@ -35,7 +45,7 @@ describe('ThroughputStats', () => {
}); });
it('does not display any GlSkeletonLoader components', () => { it('does not display any GlSkeletonLoader components', () => {
expect(wrapper.findAll(GlSkeletonLoader)).toHaveLength(0); expect(wrapper.findAllComponents(GlSkeletonLoader)).toHaveLength(0);
}); });
}); });
...@@ -45,11 +55,17 @@ describe('ThroughputStats', () => { ...@@ -45,11 +55,17 @@ describe('ThroughputStats', () => {
}); });
it('displays a GlSkeletonLoader component for each stat entry', () => { it('displays a GlSkeletonLoader component for each stat entry', () => {
expect(wrapper.findAll(GlSkeletonLoader)).toHaveLength(stats.length); expect(wrapper.findAllComponents(GlSkeletonLoader)).toHaveLength(stats.length);
}); });
it('does not display any GlSingleStat components', () => { it('hides all GlSingleStat components', () => {
expect(wrapper.findAll(GlSingleStat)).toHaveLength(0); const components = wrapper.findAllComponents(GlSingleStat);
expect(components).toHaveLength(stats.length);
stats.forEach((stat, index) => {
expect(components.at(index).isVisible()).toBe(false);
});
}); });
}); });
}); });
...@@ -46,7 +46,6 @@ describe('ValueStreamMetrics', () => { ...@@ -46,7 +46,6 @@ describe('ValueStreamMetrics', () => {
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null;
}); });
describe('with successful requests', () => { describe('with successful requests', () => {
...@@ -58,7 +57,23 @@ describe('ValueStreamMetrics', () => { ...@@ -58,7 +57,23 @@ describe('ValueStreamMetrics', () => {
it('will display a loader with pending requests', async () => { it('will display a loader with pending requests', async () => {
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(wrapper.find(GlSkeletonLoading).exists()).toBe(true); expect(wrapper.findComponent(GlSkeletonLoading).exists()).toBe(true);
});
it('renders hidden GlSingleStat components for each metric', async () => {
await waitForPromises();
wrapper.setData({ isLoading: true });
await wrapper.vm.$nextTick();
const components = findMetrics();
expect(components).toHaveLength(metricsData.length);
metricsData.forEach((metric, index) => {
expect(components.at(index).isVisible()).toBe(false);
});
}); });
describe('with data loaded', () => { describe('with data loaded', () => {
...@@ -80,6 +95,7 @@ describe('ValueStreamMetrics', () => { ...@@ -80,6 +95,7 @@ describe('ValueStreamMetrics', () => {
it(`renders a single stat component for "${title}" with value and unit`, () => { it(`renders a single stat component for "${title}" with value and unit`, () => {
const metric = findMetrics().at(index); const metric = findMetrics().at(index);
expect(metric.props()).toMatchObject({ value, title, unit: unit ?? '' }); expect(metric.props()).toMatchObject({ value, title, unit: unit ?? '' });
expect(metric.isVisible()).toBe(true);
}); });
it(`${ it(`${
......
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