diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-19 10:33:21 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-19 10:33:21 +0300 |
commit | 36a59d088eca61b834191dacea009677a96c052f (patch) | |
tree | e4f33972dab5d8ef79e3944a9f403035fceea43f /app/assets/javascripts/analytics | |
parent | a1761f15ec2cae7c7f7bbda39a75494add0dfd6f (diff) |
Add latest changes from gitlab-org/gitlab@15-0-stable-eev15.0.0-rc42
Diffstat (limited to 'app/assets/javascripts/analytics')
4 files changed, 119 insertions, 28 deletions
diff --git a/app/assets/javascripts/analytics/shared/components/projects_dropdown_filter.vue b/app/assets/javascripts/analytics/shared/components/projects_dropdown_filter.vue index b2b033de75d..b151e1605da 100644 --- a/app/assets/javascripts/analytics/shared/components/projects_dropdown_filter.vue +++ b/app/assets/javascripts/analytics/shared/components/projects_dropdown_filter.vue @@ -7,6 +7,7 @@ import { GlDropdownSectionHeader, GlDropdownItem, GlSearchBoxByType, + GlTruncate, } from '@gitlab/ui'; import { debounce } from 'lodash'; import { filterBySearchTerm } from '~/analytics/shared/utils'; @@ -28,6 +29,7 @@ export default { GlDropdownSectionHeader, GlDropdownItem, GlSearchBoxByType, + GlTruncate, }, props: { groupId: { @@ -212,30 +214,29 @@ export default { <gl-dropdown ref="projectsDropdown" class="dropdown dropdown-projects" - toggle-class="gl-shadow-none" + toggle-class="gl-shadow-none gl-mb-0" :loading="loadingDefaultProjects" :show-clear-all="hasSelectedProjects" show-highlighted-items-title highlighted-items-title-class="gl-p-3" + block @clear-all.stop="onClearAll" @hide="onHide" > <template #button-content> - <gl-loading-icon v-if="loadingDefaultProjects" class="gl-mr-2" /> - <div class="gl-display-flex gl-flex-grow-1"> - <gl-avatar - v-if="isOnlyOneProjectSelected" - :src="selectedProjects[0].avatarUrl" - :entity-id="getEntityId(selectedProjects[0])" - :entity-name="selectedProjects[0].name" - :size="16" - :shape="$options.AVATAR_SHAPE_OPTION_RECT" - :alt="selectedProjects[0].name" - class="gl-display-inline-flex gl-vertical-align-middle gl-mr-2" - /> - {{ selectedProjectsLabel }} - </div> - <gl-icon class="gl-ml-2" name="chevron-down" /> + <gl-loading-icon v-if="loadingDefaultProjects" class="gl-mr-2 gl-flex-shrink-0" /> + <gl-avatar + v-if="isOnlyOneProjectSelected" + :src="selectedProjects[0].avatarUrl" + :entity-id="getEntityId(selectedProjects[0])" + :entity-name="selectedProjects[0].name" + :size="16" + :shape="$options.AVATAR_SHAPE_OPTION_RECT" + :alt="selectedProjects[0].name" + class="gl-display-inline-flex gl-vertical-align-middle gl-mr-2 gl-flex-shrink-0" + /> + <gl-truncate :text="selectedProjectsLabel" class="gl-min-w-0 gl-flex-grow-1" /> + <gl-icon class="gl-ml-2 gl-flex-shrink-0" name="chevron-down" /> </template> <template #header> <gl-dropdown-section-header>{{ __('Projects') }}</gl-dropdown-section-header> diff --git a/app/assets/javascripts/analytics/shared/components/value_stream_metrics.vue b/app/assets/javascripts/analytics/shared/components/value_stream_metrics.vue index 1a3544e7677..6ac1bce4032 100644 --- a/app/assets/javascripts/analytics/shared/components/value_stream_metrics.vue +++ b/app/assets/javascripts/analytics/shared/components/value_stream_metrics.vue @@ -1,6 +1,6 @@ <script> import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui'; -import { flatten, isEqual } from 'lodash'; +import { flatten, isEqual, keyBy } from 'lodash'; import createFlash from '~/flash'; import { sprintf, s__ } from '~/locale'; import { METRICS_POPOVER_CONTENT } from '../constants'; @@ -28,6 +28,23 @@ const fetchMetricsData = (reqs = [], path, params) => { ); }; +const extractMetricsGroupData = (keyList = [], data = []) => { + if (!keyList.length || !data.length) return []; + const kv = keyBy(data, 'identifier'); + return keyList.map((id) => kv[id] || null).filter((obj) => Boolean(obj)); +}; + +const groupRawMetrics = (groups = [], rawData = []) => { + return groups.map((curr) => { + const { keys, ...rest } = curr; + return { + data: extractMetricsGroupData(keys, rawData), + keys, + ...rest, + }; + }); +}; + export default { name: 'ValueStreamMetrics', components: { @@ -52,13 +69,24 @@ export default { required: false, default: null, }, + groupBy: { + type: Array, + required: false, + default: () => [], + }, }, data() { return { metrics: [], + groupedMetrics: [], isLoading: false, }; }, + computed: { + hasGroupedMetrics() { + return Boolean(this.groupBy.length); + }, + }, watch: { requestParams(newVal, oldVal) { if (!isEqual(newVal, oldVal)) { @@ -76,6 +104,11 @@ export default { return fetchMetricsData(this.requests, this.requestPath, this.requestParams) .then((data) => { this.metrics = this.filterFn ? this.filterFn(data) : data; + + if (this.hasGroupedMetrics) { + this.groupedMetrics = groupRawMetrics(this.groupBy, this.metrics); + } + this.isLoading = false; }) .catch(() => { @@ -86,14 +119,35 @@ export default { }; </script> <template> - <div class="gl-display-flex gl-flex-wrap" data-testid="vsa-metrics"> + <div class="gl-display-flex gl-mt-6" data-testid="vsa-metrics"> <gl-skeleton-loading v-if="isLoading" class="gl-h-auto gl-py-3 gl-pr-9 gl-my-6" /> - <metric-tile - v-for="metric in metrics" - v-show="!isLoading" - :key="metric.identifier" - :metric="metric" - class="gl-my-6 gl-pr-9" - /> + <template v-else> + <div v-if="hasGroupedMetrics" class="gl-flex-direction-column"> + <div + v-for="group in groupedMetrics" + :key="group.key" + class="gl-mb-7" + data-testid="vsa-metrics-group" + > + <h4 class="gl-my-0">{{ group.title }}</h4> + <div class="gl-display-flex gl-flex-wrap"> + <metric-tile + v-for="metric in group.data" + :key="metric.identifier" + :metric="metric" + class="gl-mt-5 gl-pr-10" + /> + </div> + </div> + </div> + <div v-else class="gl-display-flex gl-flex-wrap gl-mb-7"> + <metric-tile + v-for="metric in metrics" + :key="metric.identifier" + :metric="metric" + class="gl-mt-5 gl-pr-10" + /> + </div> + </template> </div> </template> diff --git a/app/assets/javascripts/analytics/shared/constants.js b/app/assets/javascripts/analytics/shared/constants.js index 2ac144ceb5e..38d05552783 100644 --- a/app/assets/javascripts/analytics/shared/constants.js +++ b/app/assets/javascripts/analytics/shared/constants.js @@ -55,4 +55,40 @@ export const METRICS_POPOVER_CONTENT = { commits: { description: s__('ValueStreamAnalytics|Number of commits pushed to the default branch'), }, + 'time-to-restore-service': { + description: s__( + 'ValueStreamAnalytics|Median time an incident was open on a production environment in the given time period.', + ), + }, + time_to_restore_service: { + description: s__( + 'ValueStreamAnalytics|Median time an incident was open on a production environment in the given time period.', + ), + }, + 'change-failure-rate': { + description: s__( + 'ValueStreamAnalytics|Percentage of deployments that cause an incident in production.', + ), + }, + change_failure_rate: { + description: s__( + 'ValueStreamAnalytics|Percentage of deployments that cause an incident in production.', + ), + }, }; + +const KEY_METRICS_TITLE = s__('ValueStreamAnalytics|Key metrics'); +const KEY_METRICS_KEYS = ['lead_time', 'cycle_time', 'issues', 'commits', 'deploys']; + +const DORA_METRICS_TITLE = s__('ValueStreamAnalytics|DORA metrics'); +const DORA_METRICS_KEYS = [ + 'deployment_frequency', + 'lead_time_for_changes', + 'time_to_restore_service', + 'change_failure_rate', +]; + +export const VSA_METRICS_GROUPS = [ + { key: 'key_metrics', title: KEY_METRICS_TITLE, keys: KEY_METRICS_KEYS }, + { key: 'dora_metrics', title: DORA_METRICS_TITLE, keys: DORA_METRICS_KEYS }, +]; diff --git a/app/assets/javascripts/analytics/usage_trends/components/users_chart.vue b/app/assets/javascripts/analytics/usage_trends/components/users_chart.vue index 09dfcddcb73..dfe94aeb884 100644 --- a/app/assets/javascripts/analytics/usage_trends/components/users_chart.vue +++ b/app/assets/javascripts/analytics/usage_trends/components/users_chart.vue @@ -122,7 +122,7 @@ export default { <div> <h3>{{ $options.i18n.yAxisTitle }}</h3> <gl-alert v-if="loadingError" variant="danger" :dismissible="false" class="gl-mt-3"> - {{ this.$options.i18n.loadUserChartError }} + {{ $options.i18n.loadUserChartError }} </gl-alert> <chart-skeleton-loader v-else-if="isLoading" /> <gl-alert v-else-if="!chartUserData.length" variant="info" :dismissible="false" class="gl-mt-3"> @@ -132,12 +132,12 @@ export default { v-else :option="options" :include-legend-avg-max="true" - :data="[ + :data="/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ [ { name: $options.i18n.yAxisTitle, data: chartUserData, }, - ]" + ] /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */" /> </div> </template> |