debian-mirror-gitlab/app/assets/javascripts/alert_management/components/alert_details.vue

375 lines
12 KiB
Vue
Raw Normal View History

2020-05-24 23:13:21 +05:30
<script>
import {
GlAlert,
2020-06-23 00:09:42 +05:30
GlBadge,
2020-05-24 23:13:21 +05:30
GlIcon,
2021-01-03 14:25:43 +05:30
GlLink,
2020-05-24 23:13:21 +05:30
GlLoadingIcon,
GlSprintf,
GlTabs,
GlTab,
GlButton,
2021-01-03 14:25:43 +05:30
GlSafeHtmlDirective,
2020-05-24 23:13:21 +05:30
} from '@gitlab/ui';
2021-01-03 14:25:43 +05:30
import * as Sentry from '~/sentry/wrapper';
2020-05-24 23:13:21 +05:30
import { s__ } from '~/locale';
2020-07-28 23:09:34 +05:30
import alertQuery from '../graphql/queries/details.query.graphql';
import sidebarStatusQuery from '../graphql/queries/sidebar_status.query.graphql';
2020-05-24 23:13:21 +05:30
import { fetchPolicies } from '~/lib/graphql';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
2020-06-23 00:09:42 +05:30
import highlightCurrentUser from '~/behaviors/markdown/highlight_current_user';
import initUserPopovers from '~/user_popovers';
import { ALERTS_SEVERITY_LABELS, trackAlertsDetailsViewsOptions } from '../constants';
2020-07-28 23:09:34 +05:30
import createIssueMutation from '../graphql/mutations/create_issue_from_alert.mutation.graphql';
import toggleSidebarStatusMutation from '../graphql/mutations/toggle_sidebar_status.mutation.graphql';
2020-06-23 00:09:42 +05:30
import { visitUrl, joinPaths } from '~/lib/utils/url_utility';
import Tracking from '~/tracking';
import { toggleContainerClasses } from '~/lib/utils/dom_utils';
import SystemNote from './system_notes/system_note.vue';
import AlertSidebar from './alert_sidebar.vue';
2020-07-28 23:09:34 +05:30
import AlertMetrics from './alert_metrics.vue';
2020-11-24 15:15:51 +05:30
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
2021-01-03 14:25:43 +05:30
import AlertSummaryRow from './alert_summary_row.vue';
2020-06-23 00:09:42 +05:30
const containerEl = document.querySelector('.page-with-contextual-sidebar');
2020-05-24 23:13:21 +05:30
export default {
i18n: {
errorMsg: s__(
'AlertManagement|There was an error displaying the alert. Please refresh the page to try again.',
),
reportedAt: s__('AlertManagement|Reported %{when}'),
reportedAtWithTool: s__('AlertManagement|Reported %{when} by %{tool}'),
},
2021-01-03 14:25:43 +05:30
directives: {
SafeHtml: GlSafeHtmlDirective,
},
2020-05-24 23:13:21 +05:30
severityLabels: ALERTS_SEVERITY_LABELS,
2020-10-24 23:57:45 +05:30
tabsConfig: [
{
id: 'overview',
title: s__('AlertManagement|Alert details'),
},
{
id: 'metrics',
title: s__('AlertManagement|Metrics'),
},
2020-11-24 15:15:51 +05:30
{
id: 'activity',
title: s__('AlertManagement|Activity feed'),
},
2020-10-24 23:57:45 +05:30
],
2020-05-24 23:13:21 +05:30
components: {
2020-11-24 15:15:51 +05:30
AlertDetailsTable,
2021-01-03 14:25:43 +05:30
AlertSummaryRow,
2020-06-23 00:09:42 +05:30
GlBadge,
2020-05-24 23:13:21 +05:30
GlAlert,
GlIcon,
2021-01-03 14:25:43 +05:30
GlLink,
2020-05-24 23:13:21 +05:30
GlLoadingIcon,
GlSprintf,
GlTab,
GlTabs,
GlButton,
TimeAgoTooltip,
2020-06-23 00:09:42 +05:30
AlertSidebar,
SystemNote,
2020-07-28 23:09:34 +05:30
AlertMetrics,
2020-05-24 23:13:21 +05:30
},
2020-07-28 23:09:34 +05:30
inject: {
projectPath: {
default: '',
},
2020-05-24 23:13:21 +05:30
alertId: {
2020-07-28 23:09:34 +05:30
default: '',
2020-05-24 23:13:21 +05:30
},
2020-07-28 23:09:34 +05:30
projectId: {
default: '',
2020-05-24 23:13:21 +05:30
},
2020-06-23 00:09:42 +05:30
projectIssuesPath: {
2020-07-28 23:09:34 +05:30
default: '',
2020-05-24 23:13:21 +05:30
},
},
apollo: {
alert: {
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
2020-07-28 23:09:34 +05:30
query: alertQuery,
2020-05-24 23:13:21 +05:30
variables() {
return {
fullPath: this.projectPath,
alertId: this.alertId,
};
},
update(data) {
return data?.project?.alertManagementAlerts?.nodes?.[0] ?? null;
},
error(error) {
this.errored = true;
Sentry.captureException(error);
},
},
2020-07-28 23:09:34 +05:30
sidebarStatus: {
query: sidebarStatusQuery,
},
2020-05-24 23:13:21 +05:30
},
data() {
2020-06-23 00:09:42 +05:30
return {
alert: null,
errored: false,
2020-07-28 23:09:34 +05:30
sidebarStatus: false,
2020-06-23 00:09:42 +05:30
isErrorDismissed: false,
2020-10-24 23:57:45 +05:30
createIncidentError: '',
incidentCreationInProgress: false,
2020-06-23 00:09:42 +05:30
sidebarErrorMessage: '',
};
2020-05-24 23:13:21 +05:30
},
computed: {
loading() {
return this.$apollo.queries.alert.loading;
},
reportedAtMessage() {
return this.alert?.monitoringTool
? this.$options.i18n.reportedAtWithTool
: this.$options.i18n.reportedAt;
},
showErrorMsg() {
return this.errored && !this.isErrorDismissed;
},
2020-10-24 23:57:45 +05:30
activeTab() {
return this.$route.params.tabId || this.$options.tabsConfig[0].id;
},
currentTabIndex: {
get() {
return this.$options.tabsConfig.findIndex(tab => tab.id === this.activeTab);
},
set(tabIdx) {
const tabId = this.$options.tabsConfig[tabIdx].id;
this.$router.replace({ name: 'tab', params: { tabId } });
},
},
2021-01-03 14:25:43 +05:30
environmentName() {
2021-01-29 00:20:46 +05:30
return this.alert?.environment?.name;
2021-01-03 14:25:43 +05:30
},
environmentPath() {
2021-01-29 00:20:46 +05:30
return this.alert?.environment?.path;
2021-01-03 14:25:43 +05:30
},
2020-05-24 23:13:21 +05:30
},
2020-06-23 00:09:42 +05:30
mounted() {
this.trackPageViews();
toggleContainerClasses(containerEl, {
'issuable-bulk-update-sidebar': true,
'right-sidebar-expanded': true,
});
},
updated() {
this.$nextTick(() => {
highlightCurrentUser(this.$el.querySelectorAll('.gfm-project_member'));
initUserPopovers(this.$el.querySelectorAll('.js-user-link'));
});
},
2020-05-24 23:13:21 +05:30
methods: {
dismissError() {
this.isErrorDismissed = true;
2020-06-23 00:09:42 +05:30
this.sidebarErrorMessage = '';
2020-05-24 23:13:21 +05:30
},
2020-06-23 00:09:42 +05:30
toggleSidebar() {
2020-07-28 23:09:34 +05:30
this.$apollo.mutate({ mutation: toggleSidebarStatusMutation });
2020-06-23 00:09:42 +05:30
toggleContainerClasses(containerEl, {
2020-07-28 23:09:34 +05:30
'right-sidebar-collapsed': !this.sidebarStatus,
'right-sidebar-expanded': this.sidebarStatus,
2020-06-23 00:09:42 +05:30
});
},
handleAlertSidebarError(errorMessage) {
this.errored = true;
this.sidebarErrorMessage = errorMessage;
},
2020-10-24 23:57:45 +05:30
createIncident() {
this.incidentCreationInProgress = true;
2020-06-23 00:09:42 +05:30
2020-05-24 23:13:21 +05:30
this.$apollo
.mutate({
2020-07-28 23:09:34 +05:30
mutation: createIssueMutation,
2020-05-24 23:13:21 +05:30
variables: {
2020-06-23 00:09:42 +05:30
iid: this.alert.iid,
2020-05-24 23:13:21 +05:30
projectPath: this.projectPath,
},
})
2020-06-23 00:09:42 +05:30
.then(({ data: { createAlertIssue: { errors, issue } } }) => {
if (errors?.length) {
2020-10-24 23:57:45 +05:30
[this.createIncidentError] = errors;
this.incidentCreationInProgress = false;
2020-06-23 00:09:42 +05:30
} else if (issue) {
2020-10-24 23:57:45 +05:30
visitUrl(this.incidentPath(issue.iid));
2020-06-23 00:09:42 +05:30
}
})
.catch(error => {
2020-10-24 23:57:45 +05:30
this.createIncidentError = error;
this.incidentCreationInProgress = false;
2020-05-24 23:13:21 +05:30
});
},
2020-10-24 23:57:45 +05:30
incidentPath(issueId) {
2020-06-23 00:09:42 +05:30
return joinPaths(this.projectIssuesPath, issueId);
},
trackPageViews() {
const { category, action } = trackAlertsDetailsViewsOptions;
Tracking.event(category, action);
},
2020-05-24 23:13:21 +05:30
},
};
</script>
2020-06-23 00:09:42 +05:30
2020-05-24 23:13:21 +05:30
<template>
<div>
<gl-alert v-if="showErrorMsg" variant="danger" @dismiss="dismissError">
2021-01-03 14:25:43 +05:30
<p v-safe-html="sidebarErrorMessage || $options.i18n.errorMsg"></p>
2020-06-23 00:09:42 +05:30
</gl-alert>
<gl-alert
2020-10-24 23:57:45 +05:30
v-if="createIncidentError"
2020-06-23 00:09:42 +05:30
variant="danger"
2020-10-24 23:57:45 +05:30
data-testid="incidentCreationError"
@dismiss="createIncidentError = null"
2020-06-23 00:09:42 +05:30
>
2020-10-24 23:57:45 +05:30
{{ createIncidentError }}
2020-05-24 23:13:21 +05:30
</gl-alert>
<div v-if="loading"><gl-loading-icon size="lg" class="gl-mt-5" /></div>
2020-06-23 00:09:42 +05:30
<div
v-if="alert"
class="alert-management-details gl-relative"
2020-07-28 23:09:34 +05:30
:class="{ 'pr-sm-8': sidebarStatus }"
2020-06-23 00:09:42 +05:30
>
2020-05-24 23:13:21 +05:30
<div
2020-10-24 23:57:45 +05:30
class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-px-1 py-3 py-md-4 gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid gl-flex-direction-column gl-sm-flex-direction-row"
2020-05-24 23:13:21 +05:30
>
2020-10-24 23:57:45 +05:30
<div data-testid="alert-header">
<gl-badge class="gl-mr-3">
<strong>{{ s__('AlertManagement|Alert') }}</strong>
</gl-badge>
2020-06-23 00:09:42 +05:30
<span>
<gl-sprintf :message="reportedAtMessage">
<template #when>
<time-ago-tooltip :time="alert.createdAt" />
</template>
<template #tool>{{ alert.monitoringTool }}</template>
</gl-sprintf>
</span>
2020-05-24 23:13:21 +05:30
</div>
<gl-button
2020-06-23 00:09:42 +05:30
v-if="alert.issueIid"
2020-10-24 23:57:45 +05:30
class="gl-mt-3 mt-sm-0 align-self-center align-self-sm-baseline alert-details-incident-button"
data-testid="viewIncidentBtn"
:href="incidentPath(alert.issueIid)"
2020-06-23 00:09:42 +05:30
category="primary"
variant="success"
>
2020-10-24 23:57:45 +05:30
{{ s__('AlertManagement|View incident') }}
2020-06-23 00:09:42 +05:30
</gl-button>
<gl-button
v-else
2020-10-24 23:57:45 +05:30
class="gl-mt-3 mt-sm-0 align-self-center align-self-sm-baseline alert-details-incident-button"
data-testid="createIncidentBtn"
:loading="incidentCreationInProgress"
2020-05-24 23:13:21 +05:30
category="primary"
variant="success"
2020-10-24 23:57:45 +05:30
@click="createIncident()"
2020-05-24 23:13:21 +05:30
>
2020-10-24 23:57:45 +05:30
{{ s__('AlertManagement|Create incident') }}
2020-05-24 23:13:21 +05:30
</gl-button>
2020-06-23 00:09:42 +05:30
<gl-button
:aria-label="__('Toggle sidebar')"
category="primary"
variant="default"
class="d-sm-none gl-absolute toggle-sidebar-mobile-button"
type="button"
2021-01-03 14:25:43 +05:30
icon="chevron-double-lg-left"
2020-06-23 00:09:42 +05:30
@click="toggleSidebar"
2021-01-03 14:25:43 +05:30
/>
2020-05-24 23:13:21 +05:30
</div>
<div
v-if="alert"
class="gl-display-flex gl-justify-content-space-between gl-align-items-center"
>
<h2 data-testid="title">{{ alert.title }}</h2>
</div>
2020-10-24 23:57:45 +05:30
<gl-tabs v-if="alert" v-model="currentTabIndex" data-testid="alertDetailsTabs">
<gl-tab :data-testid="$options.tabsConfig[0].id" :title="$options.tabsConfig[0].title">
2021-01-03 14:25:43 +05:30
<alert-summary-row v-if="alert.severity" :label="`${s__('AlertManagement|Severity')}:`">
<span data-testid="severity">
<gl-icon
class="gl-vertical-align-middle"
:size="12"
:name="`severity-${alert.severity.toLowerCase()}`"
:class="`icon-${alert.severity.toLowerCase()}`"
/>
2020-06-23 00:09:42 +05:30
{{ $options.severityLabels[alert.severity] }}
2021-01-03 14:25:43 +05:30
</span>
</alert-summary-row>
<alert-summary-row
v-if="environmentName"
:label="`${s__('AlertManagement|Environment')}:`"
>
<gl-link
v-if="environmentPath"
class="gl-display-inline-block"
data-testid="environmentPath"
:href="environmentPath"
>
{{ environmentName }}
</gl-link>
<span v-else data-testid="environmentName">{{ environmentName }}</span>
</alert-summary-row>
<alert-summary-row
v-if="alert.startedAt"
:label="`${s__('AlertManagement|Start time')}:`"
>
<time-ago-tooltip data-testid="startTimeItem" :time="alert.startedAt" />
</alert-summary-row>
<alert-summary-row
v-if="alert.eventCount"
:label="`${s__('AlertManagement|Events')}:`"
data-testid="eventCount"
>
{{ alert.eventCount }}
</alert-summary-row>
<alert-summary-row
v-if="alert.monitoringTool"
:label="`${s__('AlertManagement|Tool')}:`"
data-testid="monitoringTool"
>
{{ alert.monitoringTool }}
</alert-summary-row>
<alert-summary-row
v-if="alert.service"
:label="`${s__('AlertManagement|Service')}:`"
data-testid="service"
>
{{ alert.service }}
</alert-summary-row>
<alert-summary-row
v-if="alert.runbook"
:label="`${s__('AlertManagement|Runbook')}:`"
data-testid="runbook"
>
{{ alert.runbook }}
</alert-summary-row>
2020-11-24 15:15:51 +05:30
<alert-details-table :alert="alert" :loading="loading" />
2020-05-24 23:13:21 +05:30
</gl-tab>
2020-10-24 23:57:45 +05:30
<gl-tab :data-testid="$options.tabsConfig[1].id" :title="$options.tabsConfig[1].title">
2020-11-24 15:15:51 +05:30
<alert-metrics :dashboard-url="alert.metricsDashboardUrl" />
2020-05-24 23:13:21 +05:30
</gl-tab>
2020-10-24 23:57:45 +05:30
<gl-tab :data-testid="$options.tabsConfig[2].id" :title="$options.tabsConfig[2].title">
2020-11-24 15:15:51 +05:30
<div v-if="alert.notes.nodes.length > 0" class="issuable-discussion">
<ul class="notes main-notes-list timeline">
<system-note v-for="note in alert.notes.nodes" :key="note.id" :note="note" />
</ul>
</div>
2020-07-28 23:09:34 +05:30
</gl-tab>
2020-05-24 23:13:21 +05:30
</gl-tabs>
2020-06-23 00:09:42 +05:30
<alert-sidebar
:alert="alert"
@toggle-sidebar="toggleSidebar"
2020-07-28 23:09:34 +05:30
@alert-error="handleAlertSidebarError"
2020-06-23 00:09:42 +05:30
/>
2020-05-24 23:13:21 +05:30
</div>
</div>
</template>