Commit 371d4f7e authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch '324287-vsa-fe-add-additional-information-to-stage-popovers' into 'master'

Add additional information to stage popovers in group level VSA

See merge request gitlab-org/gitlab!59606
parents 1a85ce88 f01d1b45
...@@ -5,6 +5,7 @@ import { ...@@ -5,6 +5,7 @@ import {
GlDeprecatedSkeletonLoading as GlSkeletonLoading, GlDeprecatedSkeletonLoading as GlSkeletonLoading,
GlSafeHtmlDirective as SafeHtml, GlSafeHtmlDirective as SafeHtml,
} from '@gitlab/ui'; } from '@gitlab/ui';
import { OVERVIEW_STAGE_ID } from '../constants';
export default { export default {
name: 'PathNavigation', name: 'PathNavigation',
...@@ -33,8 +34,8 @@ export default { ...@@ -33,8 +34,8 @@ export default {
}, },
}, },
methods: { methods: {
showPopover({ startEventHtmlDescription, endEventHtmlDescription }) { showPopover({ id }) {
return startEventHtmlDescription || endEventHtmlDescription; return id && id !== OVERVIEW_STAGE_ID;
}, },
}, },
popoverOptions: { popoverOptions: {
...@@ -51,24 +52,41 @@ export default { ...@@ -51,24 +52,41 @@ export default {
v-if="showPopover(pathItem)" v-if="showPopover(pathItem)"
v-bind="$options.popoverOptions" v-bind="$options.popoverOptions"
:target="pathId" :target="pathId"
:css-classes="['stage-item-popover']"
data-testid="stage-item-popover" data-testid="stage-item-popover"
> >
<template #title>{{ pathItem.title }}</template> <template #title>{{ pathItem.title }}</template>
<div class="gl-display-table"> <div class="gl-px-4">
<div v-if="pathItem.startEventHtmlDescription" class="gl-display-table-row"> <div class="gl-display-flex gl-justify-content-space-between">
<div class="gl-display-table-cell gl-pr-4 gl-pb-4"> <div class="gl-pr-4 gl-pb-4">
{{ s__('ValueStreamEvent|Stage time (median)') }}
</div>
<div class="gl-pb-4 gl-font-weight-bold">{{ pathItem.metric }}</div>
</div>
</div>
<div class="gl-px-4 gl-pt-4 gl-border-t-1 gl-border-t-solid gl-border-gray-50">
<div
v-if="pathItem.startEventHtmlDescription"
class="gl-display-flex gl-flex-direction-row"
>
<div class="gl-display-flex gl-flex-direction-column gl-pr-4 gl-pb-4 metric-label">
{{ s__('ValueStreamEvent|Start') }} {{ s__('ValueStreamEvent|Start') }}
</div> </div>
<div <div
v-safe-html="pathItem.startEventHtmlDescription" v-safe-html="pathItem.startEventHtmlDescription"
class="gl-display-table-cell gl-pb-4 stage-event-description" class="gl-display-flex gl-flex-direction-column gl-pb-4 stage-event-description"
></div> ></div>
</div> </div>
<div v-if="pathItem.endEventHtmlDescription" class="gl-display-table-row"> <div
<div class="gl-display-table-cell gl-pr-4">{{ s__('ValueStreamEvent|Stop') }}</div> v-if="pathItem.endEventHtmlDescription"
class="gl-display-flex gl-flex-direction-row"
>
<div class="gl-display-flex gl-flex-direction-column gl-pr-4 metric-label">
{{ s__('ValueStreamEvent|Stop') }}
</div>
<div <div
v-safe-html="pathItem.endEventHtmlDescription" v-safe-html="pathItem.endEventHtmlDescription"
class="gl-display-table-cell stage-event-description" class="gl-display-flex gl-flex-direction-column stage-event-description"
></div> ></div>
</div> </div>
</div> </div>
......
...@@ -40,6 +40,17 @@ ...@@ -40,6 +40,17 @@
// Since backend wraps event description in a paragraph // Since backend wraps event description in a paragraph
// we need to remove common styles, i.e., spacing // we need to remove common styles, i.e., spacing
.stage-event-description p { .stage-item-popover {
margin: 0 !important; .stage-event-description p {
margin: 0 !important;
}
.popover-body {
padding-left: 0 !important;
padding-right: 0 !important;
}
.metric-label {
flex: 0 0 20%;
}
} }
---
title: Add stage time to path popovers in group level VSA
merge_request: 59606
author:
type: added
...@@ -70,13 +70,35 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot ...@@ -70,13 +70,35 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot
> >
<div <div
class="gl-display-table" class="gl-px-4"
> >
<div <div
class="gl-display-table-row" class="gl-display-flex gl-justify-content-space-between"
> >
<div <div
class="gl-display-table-cell gl-pr-4 gl-pb-4" class="gl-pr-4 gl-pb-4"
>
Stage time (median)
</div>
<div
class="gl-pb-4 gl-font-weight-bold"
>
</div>
</div>
</div>
<div
class="gl-px-4 gl-pt-4 gl-border-t-1 gl-border-t-solid gl-border-gray-50"
>
<div
class="gl-display-flex gl-flex-direction-row"
>
<div
class="gl-display-flex gl-flex-direction-column gl-pr-4 gl-pb-4 metric-label"
> >
Start Start
...@@ -84,7 +106,7 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot ...@@ -84,7 +106,7 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot
</div> </div>
<div <div
class="gl-display-table-cell gl-pb-4 stage-event-description" class="gl-display-flex gl-flex-direction-column gl-pb-4 stage-event-description"
> >
<p <p
data-sourcepos="1:1-1:13" data-sourcepos="1:1-1:13"
...@@ -96,16 +118,18 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot ...@@ -96,16 +118,18 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot
</div> </div>
<div <div
class="gl-display-table-row" class="gl-display-flex gl-flex-direction-row"
> >
<div <div
class="gl-display-table-cell gl-pr-4" class="gl-display-flex gl-flex-direction-column gl-pr-4 metric-label"
> >
Stop
Stop
</div> </div>
<div <div
class="gl-display-table-cell stage-event-description" class="gl-display-flex gl-flex-direction-column stage-event-description"
> >
<p <p
data-sourcepos="1:1-1:71" data-sourcepos="1:1-1:71"
...@@ -138,13 +162,35 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot ...@@ -138,13 +162,35 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot
> >
<div <div
class="gl-display-table" class="gl-px-4"
> >
<div <div
class="gl-display-table-row" class="gl-display-flex gl-justify-content-space-between"
> >
<div <div
class="gl-display-table-cell gl-pr-4 gl-pb-4" class="gl-pr-4 gl-pb-4"
>
Stage time (median)
</div>
<div
class="gl-pb-4 gl-font-weight-bold"
>
</div>
</div>
</div>
<div
class="gl-px-4 gl-pt-4 gl-border-t-1 gl-border-t-solid gl-border-gray-50"
>
<div
class="gl-display-flex gl-flex-direction-row"
>
<div
class="gl-display-flex gl-flex-direction-column gl-pr-4 gl-pb-4 metric-label"
> >
Start Start
...@@ -152,7 +198,7 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot ...@@ -152,7 +198,7 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot
</div> </div>
<div <div
class="gl-display-table-cell gl-pb-4 stage-event-description" class="gl-display-flex gl-flex-direction-column gl-pb-4 stage-event-description"
> >
<p <p
data-sourcepos="1:1-1:71" data-sourcepos="1:1-1:71"
...@@ -164,16 +210,18 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot ...@@ -164,16 +210,18 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot
</div> </div>
<div <div
class="gl-display-table-row" class="gl-display-flex gl-flex-direction-row"
> >
<div <div
class="gl-display-table-cell gl-pr-4" class="gl-display-flex gl-flex-direction-column gl-pr-4 metric-label"
> >
Stop
Stop
</div> </div>
<div <div
class="gl-display-table-cell stage-event-description" class="gl-display-flex gl-flex-direction-column stage-event-description"
> >
<p <p
data-sourcepos="1:1-1:33" data-sourcepos="1:1-1:33"
...@@ -206,13 +254,35 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot ...@@ -206,13 +254,35 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot
> >
<div <div
class="gl-display-table" class="gl-px-4"
>
<div
class="gl-display-flex gl-justify-content-space-between"
>
<div
class="gl-pr-4 gl-pb-4"
>
Stage time (median)
</div>
<div
class="gl-pb-4 gl-font-weight-bold"
>
</div>
</div>
</div>
<div
class="gl-px-4 gl-pt-4 gl-border-t-1 gl-border-t-solid gl-border-gray-50"
> >
<div <div
class="gl-display-table-row" class="gl-display-flex gl-flex-direction-row"
> >
<div <div
class="gl-display-table-cell gl-pr-4 gl-pb-4" class="gl-display-flex gl-flex-direction-column gl-pr-4 gl-pb-4 metric-label"
> >
Start Start
...@@ -220,7 +290,7 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot ...@@ -220,7 +290,7 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot
</div> </div>
<div <div
class="gl-display-table-cell gl-pb-4 stage-event-description" class="gl-display-flex gl-flex-direction-column gl-pb-4 stage-event-description"
> >
<p <p
data-sourcepos="1:1-1:33" data-sourcepos="1:1-1:33"
...@@ -232,16 +302,18 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot ...@@ -232,16 +302,18 @@ exports[`PathNavigation displays correctly loading is false matches the snapshot
</div> </div>
<div <div
class="gl-display-table-row" class="gl-display-flex gl-flex-direction-row"
> >
<div <div
class="gl-display-table-cell gl-pr-4" class="gl-display-flex gl-flex-direction-column gl-pr-4 metric-label"
> >
Stop
Stop
</div> </div>
<div <div
class="gl-display-table-cell stage-event-description" class="gl-display-flex gl-flex-direction-column stage-event-description"
> >
<p <p
data-sourcepos="1:1-1:21" data-sourcepos="1:1-1:21"
......
...@@ -17,12 +17,16 @@ describe('PathNavigation', () => { ...@@ -17,12 +17,16 @@ describe('PathNavigation', () => {
}); });
}; };
const pathNavigationItems = () => { const pathNavigationTitles = () => {
return wrapper.findAll('.gl-path-button'); return wrapper.findAll('.gl-path-button');
}; };
const pathNavigationItems = () => {
return wrapper.findAll('.gl-path-nav-list-item');
};
const clickItemAt = (index) => { const clickItemAt = (index) => {
pathNavigationItems().at(index).trigger('click'); pathNavigationTitles().at(index).trigger('click');
}; };
beforeEach(() => { beforeEach(() => {
...@@ -62,21 +66,20 @@ describe('PathNavigation', () => { ...@@ -62,21 +66,20 @@ describe('PathNavigation', () => {
}); });
describe('popovers', () => { describe('popovers', () => {
const modifiedStages = [
...transformedStagePathData.slice(0, 3),
{
...transformedStagePathData[3],
startEventHtmlDescription: null,
endEventHtmlDescription: null,
},
];
beforeEach(() => { beforeEach(() => {
wrapper = createComponent({ stages: modifiedStages }); wrapper = createComponent({ stages: transformedStagePathData });
}); });
it('renders popovers only for stages with either a start event and/or and end event', () => { it('renders popovers for all stages except for the overview stage', () => {
expect(wrapper.findAll('[data-testid="stage-item-popover"]')).toHaveLength(2); const pathItemContent = pathNavigationItems().wrappers;
const [overviewStage, ...popoverStages] = pathItemContent;
expect(overviewStage.text()).toContain('Overview');
expect(overviewStage.find('[data-testid="stage-item-popover"]').exists()).toBe(false);
popoverStages.forEach((stage) => {
expect(stage.find('[data-testid="stage-item-popover"]').exists()).toBe(true);
});
}); });
it('shows the sanitized start event description for the first stage item', () => { it('shows the sanitized start event description for the first stage item', () => {
...@@ -91,6 +94,11 @@ describe('PathNavigation', () => { ...@@ -91,6 +94,11 @@ describe('PathNavigation', () => {
'Issue first associated with a milestone or issue first added to a board'; 'Issue first associated with a milestone or issue first added to a board';
expect(firstPopover.text()).toContain(expectedStartEventDescription); expect(firstPopover.text()).toContain(expectedStartEventDescription);
}); });
it('shows the median stage time for the first stage item', () => {
const firstPopover = wrapper.findAll('[data-testid="stage-item-popover"]').at(0);
expect(firstPopover.text()).toContain('Stage time (median)');
});
}); });
}); });
......
...@@ -34602,6 +34602,9 @@ msgstr "" ...@@ -34602,6 +34602,9 @@ msgstr ""
msgid "ValueStreamAnalytics|Median time from issue created to issue closed." msgid "ValueStreamAnalytics|Median time from issue created to issue closed."
msgstr "" msgstr ""
msgid "ValueStreamEvent|Stage time (median)"
msgstr ""
msgid "ValueStreamEvent|Start" msgid "ValueStreamEvent|Start"
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