diff options
Diffstat (limited to 'app/assets/javascripts/analytics/devops_reports/components')
3 files changed, 221 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> |