Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-11-18 16:16:36 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-11-18 16:16:36 +0300
commit311b0269b4eb9839fa63f80c8d7a58f32b8138a0 (patch)
tree07e7870bca8aed6d61fdcc810731c50d2c40af47 /app/assets/javascripts/analytics/devops_reports
parent27909cef6c4170ed9205afa7426b8d3de47cbb0c (diff)
Add latest changes from gitlab-org/gitlab@14-5-stable-eev14.5.0-rc42
Diffstat (limited to 'app/assets/javascripts/analytics/devops_reports')
-rw-r--r--app/assets/javascripts/analytics/devops_reports/components/devops_score.vue114
-rw-r--r--app/assets/javascripts/analytics/devops_reports/components/devops_score_callout.vue55
-rw-r--r--app/assets/javascripts/analytics/devops_reports/components/service_ping_disabled.vue52
-rw-r--r--app/assets/javascripts/analytics/devops_reports/constants.js11
-rw-r--r--app/assets/javascripts/analytics/devops_reports/devops_score.js22
-rw-r--r--app/assets/javascripts/analytics/devops_reports/devops_score_disabled_service_ping.js27
6 files changed, 281 insertions, 0 deletions
diff --git a/app/assets/javascripts/analytics/devops_reports/components/devops_score.vue b/app/assets/javascripts/analytics/devops_reports/components/devops_score.vue
new file mode 100644
index 00000000000..238081cc3c0
--- /dev/null
+++ b/app/assets/javascripts/analytics/devops_reports/components/devops_score.vue
@@ -0,0 +1,114 @@
+<script>
+import { GlBadge, GlTable, GlLink, GlEmptyState } from '@gitlab/ui';
+import { GlSingleStat } from '@gitlab/ui/dist/charts';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import { sprintf, s__ } from '~/locale';
+import DevopsScoreCallout from './devops_score_callout.vue';
+
+const defaultHeaderAttrs = {
+ thClass: 'gl-bg-white!',
+ thAttr: { 'data-testid': 'header' },
+};
+
+export default {
+ components: {
+ GlBadge,
+ GlTable,
+ GlSingleStat,
+ GlLink,
+ GlEmptyState,
+ DevopsScoreCallout,
+ },
+ inject: {
+ devopsScoreMetrics: {
+ default: null,
+ },
+ noDataImagePath: {
+ default: '',
+ },
+ },
+ computed: {
+ titleHelperText() {
+ return sprintf(
+ s__(
+ 'DevopsReport|DevOps score metrics are based on usage over the last 30 days. Last updated: %{timestamp}.',
+ ),
+ { timestamp: this.devopsScoreMetrics.createdAt },
+ );
+ },
+ isEmpty() {
+ return this.devopsScoreMetrics.averageScore === undefined;
+ },
+ },
+ devopsReportDocsPath: helpPagePath('user/admin_area/analytics/dev_ops_report'),
+ tableHeaderFields: [
+ {
+ key: 'title',
+ label: '',
+ ...defaultHeaderAttrs,
+ },
+ {
+ key: 'usage',
+ label: s__('DevopsReport|Your usage'),
+ ...defaultHeaderAttrs,
+ },
+ {
+ key: 'leadInstance',
+ label: s__('DevopsReport|Leader usage'),
+ ...defaultHeaderAttrs,
+ },
+ {
+ key: 'score',
+ label: s__('DevopsReport|Score'),
+ ...defaultHeaderAttrs,
+ },
+ ],
+};
+</script>
+<template>
+ <div data-testid="devops-score-container">
+ <devops-score-callout />
+ <gl-empty-state
+ v-if="isEmpty"
+ :title="__('Data is still calculating...')"
+ :svg-path="noDataImagePath"
+ >
+ <template #description>
+ <p class="gl-mb-0">{{ __('It may be several days before you see feature usage data.') }}</p>
+ <gl-link :href="$options.devopsReportDocsPath">{{
+ __('See example DevOps Score page in our documentation.')
+ }}</gl-link>
+ </template>
+ </gl-empty-state>
+ <div v-else data-testid="devops-score-app">
+ <div class="gl-text-gray-400 gl-my-4" data-testid="devops-score-note-text">
+ {{ titleHelperText }}
+ </div>
+ <gl-single-stat
+ unit="%"
+ size="sm"
+ :title="s__('DevopsReport|Your score')"
+ :should-animate="true"
+ :value="devopsScoreMetrics.averageScore.value"
+ :meta-icon="devopsScoreMetrics.averageScore.scoreLevel.icon"
+ :meta-text="devopsScoreMetrics.averageScore.scoreLevel.label"
+ :variant="devopsScoreMetrics.averageScore.scoreLevel.variant"
+ />
+ <gl-table
+ :fields="$options.tableHeaderFields"
+ :items="devopsScoreMetrics.cards"
+ thead-class="gl-border-t-0 gl-border-b-solid gl-border-b-1 gl-border-b-gray-100"
+ stacked="sm"
+ >
+ <template #cell(usage)="{ item }">
+ <div data-testid="usageCol">
+ <span>{{ item.usage }}</span>
+ <gl-badge :variant="item.scoreLevel.variant" size="sm" class="gl-ml-1">{{
+ item.scoreLevel.label
+ }}</gl-badge>
+ </div>
+ </template>
+ </gl-table>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/analytics/devops_reports/components/devops_score_callout.vue b/app/assets/javascripts/analytics/devops_reports/components/devops_score_callout.vue
new file mode 100644
index 00000000000..e594b4e360a
--- /dev/null
+++ b/app/assets/javascripts/analytics/devops_reports/components/devops_score_callout.vue
@@ -0,0 +1,55 @@
+<script>
+import { GlBanner } from '@gitlab/ui';
+import { parseBoolean, getCookie, setCookie } from '~/lib/utils/common_utils';
+import {
+ INTRO_COOKIE_KEY,
+ INTRO_BANNER_TITLE,
+ INTRO_BANNER_BODY,
+ INTRO_BANNER_ACTION_TEXT,
+} from '../constants';
+
+export default {
+ name: 'DevopsScoreCallout',
+ components: {
+ GlBanner,
+ },
+ inject: {
+ devopsReportDocsPath: {
+ default: '',
+ },
+ devopsScoreIntroImagePath: {
+ default: '',
+ },
+ },
+ data() {
+ return {
+ bannerDismissed: parseBoolean(getCookie(INTRO_COOKIE_KEY)),
+ };
+ },
+ i18n: {
+ title: INTRO_BANNER_TITLE,
+ body: INTRO_BANNER_BODY,
+ action: INTRO_BANNER_ACTION_TEXT,
+ },
+ methods: {
+ dismissBanner() {
+ setCookie(INTRO_COOKIE_KEY, 'true');
+ this.bannerDismissed = true;
+ },
+ },
+};
+</script>
+<template>
+ <gl-banner
+ v-if="!bannerDismissed"
+ class="gl-mt-3"
+ variant="introduction"
+ :title="$options.i18n.title"
+ :button-text="$options.i18n.action"
+ :button-link="devopsReportDocsPath"
+ :svg-path="devopsScoreIntroImagePath"
+ @close="dismissBanner"
+ >
+ <p>{{ $options.i18n.body }}</p>
+ </gl-banner>
+</template>
diff --git a/app/assets/javascripts/analytics/devops_reports/components/service_ping_disabled.vue b/app/assets/javascripts/analytics/devops_reports/components/service_ping_disabled.vue
new file mode 100644
index 00000000000..400326e41e1
--- /dev/null
+++ b/app/assets/javascripts/analytics/devops_reports/components/service_ping_disabled.vue
@@ -0,0 +1,52 @@
+<script>
+import { GlEmptyState, GlSprintf, GlLink, GlButton } from '@gitlab/ui';
+import { helpPagePath } from '~/helpers/help_page_helper';
+
+export default {
+ components: {
+ GlEmptyState,
+ GlSprintf,
+ GlLink,
+ GlButton,
+ },
+ inject: {
+ isAdmin: {
+ default: false,
+ },
+ svgPath: {
+ default: '',
+ },
+ primaryButtonPath: {
+ default: '',
+ },
+ },
+ docsLink: helpPagePath('development/service_ping/index.md'),
+};
+</script>
+<template>
+ <gl-empty-state :title="s__('ServicePing|Service ping is off')" :svg-path="svgPath">
+ <template #description>
+ <gl-sprintf
+ v-if="!isAdmin"
+ :message="
+ s__(
+ 'ServicePing|To view instance-level analytics, ask an admin to turn on %{docLinkStart}service ping%{docLinkEnd}.',
+ )
+ "
+ >
+ <template #docLink="{ content }">
+ <gl-link :href="$options.docsLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ <template v-else>
+ <p>
+ {{ s__('ServicePing|Turn on service ping to review instance-level analytics.') }}
+ </p>
+
+ <gl-button category="primary" variant="success" :href="primaryButtonPath">
+ {{ s__('ServicePing|Turn on service ping') }}
+ </gl-button>
+ </template>
+ </template>
+ </gl-empty-state>
+</template>
diff --git a/app/assets/javascripts/analytics/devops_reports/constants.js b/app/assets/javascripts/analytics/devops_reports/constants.js
new file mode 100644
index 00000000000..6091fcb5724
--- /dev/null
+++ b/app/assets/javascripts/analytics/devops_reports/constants.js
@@ -0,0 +1,11 @@
+import { __ } from '~/locale';
+
+export const INTRO_COOKIE_KEY = 'dev_ops_report_intro_callout_dismissed';
+
+export const INTRO_BANNER_TITLE = __('Introducing Your DevOps Reports');
+
+export const INTRO_BANNER_BODY = __(
+ 'Your DevOps Reports give an overview of how you are using GitLab from a feature perspective. Use them to view how you compare with other organizations, and how your teams compare against each other.',
+);
+
+export const INTRO_BANNER_ACTION_TEXT = __('Read more');
diff --git a/app/assets/javascripts/analytics/devops_reports/devops_score.js b/app/assets/javascripts/analytics/devops_reports/devops_score.js
new file mode 100644
index 00000000000..0bf98b65ed5
--- /dev/null
+++ b/app/assets/javascripts/analytics/devops_reports/devops_score.js
@@ -0,0 +1,22 @@
+import Vue from 'vue';
+import DevopsScore from './components/devops_score.vue';
+
+export default () => {
+ const el = document.getElementById('js-devops-score');
+
+ if (!el) return false;
+
+ const { devopsScoreMetrics, noDataImagePath, devopsScoreIntroImagePath } = el.dataset;
+
+ return new Vue({
+ el,
+ provide: {
+ devopsScoreMetrics: JSON.parse(devopsScoreMetrics),
+ noDataImagePath,
+ devopsScoreIntroImagePath,
+ },
+ render(h) {
+ return h(DevopsScore);
+ },
+ });
+};
diff --git a/app/assets/javascripts/analytics/devops_reports/devops_score_disabled_service_ping.js b/app/assets/javascripts/analytics/devops_reports/devops_score_disabled_service_ping.js
new file mode 100644
index 00000000000..eb2992422a4
--- /dev/null
+++ b/app/assets/javascripts/analytics/devops_reports/devops_score_disabled_service_ping.js
@@ -0,0 +1,27 @@
+import Vue from 'vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import UserCallout from '~/user_callout';
+import ServicePingDisabled from './components/service_ping_disabled.vue';
+
+export default () => {
+ // eslint-disable-next-line no-new
+ new UserCallout();
+
+ const emptyStateContainer = document.getElementById('js-devops-service-ping-disabled');
+
+ if (!emptyStateContainer) return false;
+
+ const { isAdmin, emptyStateSvgPath, enableServicePingPath } = emptyStateContainer.dataset;
+
+ return new Vue({
+ el: emptyStateContainer,
+ provide: {
+ isAdmin: parseBoolean(isAdmin),
+ svgPath: emptyStateSvgPath,
+ primaryButtonPath: enableServicePingPath,
+ },
+ render(h) {
+ return h(ServicePingDisabled);
+ },
+ });
+};