diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 19:05:49 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 19:05:49 +0300 |
commit | 43a25d93ebdabea52f99b05e15b06250cd8f07d7 (patch) | |
tree | dceebdc68925362117480a5d672bcff122fb625b /app/assets/javascripts/analytics/shared | |
parent | 20c84b99005abd1c82101dfeff264ac50d2df211 (diff) |
Add latest changes from gitlab-org/gitlab@16-0-stable-eev16.0.0-rc42
Diffstat (limited to 'app/assets/javascripts/analytics/shared')
6 files changed, 112 insertions, 21 deletions
diff --git a/app/assets/javascripts/analytics/shared/components/metric_tile.vue b/app/assets/javascripts/analytics/shared/components/metric_tile.vue index 845a3386f6c..54dbe329c7a 100644 --- a/app/assets/javascripts/analytics/shared/components/metric_tile.vue +++ b/app/assets/javascripts/analytics/shared/components/metric_tile.vue @@ -1,6 +1,6 @@ <script> import { GlSingleStat } from '@gitlab/ui/dist/charts'; -import { redirectTo } from '~/lib/utils/url_utility'; +import { redirectTo } from '~/lib/utils/url_utility'; // eslint-disable-line import/no-deprecated import MetricPopover from './metric_popover.vue'; export default { @@ -27,7 +27,7 @@ export default { methods: { clickHandler({ links }) { if (this.hasLinks) { - redirectTo(links[0].url); + redirectTo(links[0].url); // eslint-disable-line import/no-deprecated } }, }, 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 5bb60d91f1e..98193de4a12 100644 --- a/app/assets/javascripts/analytics/shared/components/projects_dropdown_filter.vue +++ b/app/assets/javascripts/analytics/shared/components/projects_dropdown_filter.vue @@ -32,11 +32,6 @@ export default { GlTruncate, }, props: { - groupId: { - type: Number, - required: false, - default: null, - }, groupNamespace: { type: String, required: true, 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 cc7b554f32c..3082897af76 100644 --- a/app/assets/javascripts/analytics/shared/components/value_stream_metrics.vue +++ b/app/assets/javascripts/analytics/shared/components/value_stream_metrics.vue @@ -1,9 +1,10 @@ <script> import { GlSkeletonLoader } from '@gitlab/ui'; import { isEqual, keyBy } from 'lodash'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import { sprintf, s__ } from '~/locale'; import { fetchMetricsData, removeFlash } from '../utils'; +import ValueStreamsDashboardLink from './value_streams_dashboard_link.vue'; import MetricTile from './metric_tile.vue'; const extractMetricsGroupData = (keyList = [], data = []) => { @@ -28,6 +29,7 @@ export default { components: { GlSkeletonLoader, MetricTile, + ValueStreamsDashboardLink, }, props: { requestPath: { @@ -52,6 +54,11 @@ export default { required: false, default: () => [], }, + dashboardsPath: { + type: String, + required: false, + default: null, + }, }, data() { return { @@ -76,6 +83,10 @@ export default { this.fetchData(); }, methods: { + shouldDisplayDashboardLink(index) { + // When we have groups of metrics, we should only display the link for the first group + return index === 0 && this.dashboardsPath; + }, fetchData() { removeFlash(); this.isLoading = true; @@ -110,7 +121,7 @@ export default { <template v-else> <div v-if="hasGroupedMetrics" class="gl-flex-direction-column"> <div - v-for="group in groupedMetrics" + v-for="(group, groupIndex) in groupedMetrics" :key="group.key" class="gl-mb-7" data-testid="vsa-metrics-group" @@ -123,6 +134,11 @@ export default { :metric="metric" class="gl-mt-5 gl-pr-10" /> + <value-streams-dashboard-link + v-if="shouldDisplayDashboardLink(groupIndex)" + class="gl-mt-5" + :request-path="dashboardsPath" + /> </div> </div> </div> diff --git a/app/assets/javascripts/analytics/shared/components/value_streams_dashboard_link.vue b/app/assets/javascripts/analytics/shared/components/value_streams_dashboard_link.vue new file mode 100644 index 00000000000..6c79c8af54a --- /dev/null +++ b/app/assets/javascripts/analytics/shared/components/value_streams_dashboard_link.vue @@ -0,0 +1,31 @@ +<script> +import { GlIcon, GlLink } from '@gitlab/ui'; +import { __ } from '~/locale'; + +export default { + name: 'ValueStreamsDashboardLink', + components: { GlIcon, GlLink }, + props: { + requestPath: { + type: String, + required: true, + }, + }, + i18n: { + title: __('Related'), + // eslint-disable-next-line @gitlab/require-valid-i18n-helpers + linkText: __('Value Streams Dashboard | DORA'), + }, +}; +</script> +<template> + <div class="gl-display-flex gl-flex-direction-column" data-testid="vsd-link"> + <div class="gl-display-flex gl-mb-2"> + <span>{{ $options.i18n.title }}</span> + </div> + <div class="gl-display-flex gl-align-items-baseline"> + <gl-link :href="requestPath">{{ $options.i18n.linkText }}</gl-link + > <gl-icon name="dashboard" /> + </div> + </div> +</template> diff --git a/app/assets/javascripts/analytics/shared/constants.js b/app/assets/javascripts/analytics/shared/constants.js index 7ced658f483..c98cf90f406 100644 --- a/app/assets/javascripts/analytics/shared/constants.js +++ b/app/assets/javascripts/analytics/shared/constants.js @@ -30,18 +30,21 @@ export const DORA_METRICS = { CHANGE_FAILURE_RATE: 'change_failure_rate', }; -export const VSA_METRICS_GROUPS = [ - { - key: 'key_metrics', - title: s__('ValueStreamAnalytics|Key metrics'), - keys: Object.values(KEY_METRICS), - }, - { - key: 'dora_metrics', - title: s__('ValueStreamAnalytics|DORA metrics'), - keys: Object.values(DORA_METRICS), - }, -]; +const VSA_FLOW_METRICS_GROUP = { + key: 'key_metrics', + title: s__('ValueStreamAnalytics|Key metrics'), + keys: Object.values(KEY_METRICS), +}; + +export const VSA_METRICS_GROUPS = [VSA_FLOW_METRICS_GROUP]; + +export const VULNERABILITY_CRITICAL_TYPE = 'vulnerability_critical'; +export const VULNERABILITY_HIGH_TYPE = 'vulnerability_high'; + +export const VULNERABILITY_METRICS = { + CRITICAL: VULNERABILITY_CRITICAL_TYPE, + HIGH: VULNERABILITY_HIGH_TYPE, +}; export const METRIC_TOOLTIPS = { [DORA_METRICS.DEPLOYMENT_FREQUENCY]: { @@ -106,6 +109,18 @@ export const METRIC_TOOLTIPS = { projectLink: '-/analytics/merge_request_analytics', docsLink: helpPagePath('user/analytics/merge_request_analytics'), }, + [VULNERABILITY_METRICS.CRITICAL]: { + description: s__('ValueStreamAnalytics|Critical vulnerabilities over time.'), + groupLink: '-/security/vulnerabilities', + projectLink: '-/security/vulnerability_report', + docsLink: helpPagePath('user/application_security/vulnerability_report/index'), + }, + [VULNERABILITY_METRICS.HIGH]: { + description: s__('ValueStreamAnalytics|High vulnerabilities over time.'), + groupLink: '-/security/vulnerabilities', + projectLink: '-/security/vulnerability_report', + docsLink: helpPagePath('user/application_security/vulnerability_report/index'), + }, }; // TODO: Remove this once the migration to METRIC_TOOLTIPS is complete diff --git a/app/assets/javascripts/analytics/shared/utils.js b/app/assets/javascripts/analytics/shared/utils.js index aafbf642766..8d7e8546626 100644 --- a/app/assets/javascripts/analytics/shared/utils.js +++ b/app/assets/javascripts/analytics/shared/utils.js @@ -1,6 +1,7 @@ import { flatten } from 'lodash'; import dateFormat from '~/lib/dateformat'; import { slugify } from '~/lib/utils/text_utility'; +import { joinPaths } from '~/lib/utils/url_utility'; import { urlQueryToFilter } from '~/vue_shared/components/filtered_search_bar/filtered_search_utils'; import { dateFormats, METRICS_POPOVER_CONTENT } from './constants'; @@ -119,3 +120,36 @@ export const fetchMetricsData = (requests = [], requestPath, params) => { prepareTimeMetricsData(flatten(responses), METRICS_POPOVER_CONTENT), ); }; + +/** + * Generates a URL link to the VSD dashboard based on the group + * and project paths passed into the method. + * + * @param {String} groupPath - Path of the specified group + * @param {Array} projectPaths - Array of project paths to include in the `query` parameter + * @returns a URL or blank string if there is no groupPath set + */ +export const generateValueStreamsDashboardLink = (namespacePath, projectPaths = []) => { + if (namespacePath.length) { + const query = projectPaths.length ? `?query=${projectPaths.join(',')}` : ''; + const dashboardsSlug = '/-/analytics/dashboards/value_streams_dashboard'; + const segments = [gon.relative_url_root || '', '/', namespacePath, dashboardsSlug]; + return joinPaths(...segments).concat(query); + } + return ''; +}; + +/** + * Extracts the relevant feature and license flags needed for VSA + * + * @param {Object} gon the global `window.gon` object populated when the page loads + * @returns an object containing the extracted feature flags and their boolean status + */ +export const extractVSAFeaturesFromGON = () => ({ + // licensed feature toggles + cycleAnalyticsForGroups: Boolean(gon?.licensed_features?.cycleAnalyticsForGroups), + cycleAnalyticsForProjects: Boolean(gon?.licensed_features?.cycleAnalyticsForProjects), + groupLevelAnalyticsDashboard: Boolean(gon?.licensed_features?.groupLevelAnalyticsDashboard), + // feature flags + vsaGroupAndProjectParity: Boolean(gon?.features?.vsaGroupAndProjectParity), +}); |