2019-07-10 17:12:46 -04:00
|
|
|
<script>
|
|
|
|
import { mapState } from 'vuex';
|
2020-01-24 04:08:32 -05:00
|
|
|
import { pickBy } from 'lodash';
|
2020-02-07 07:09:13 -05:00
|
|
|
import invalidUrl from '~/lib/utils/invalid_url';
|
2019-08-14 18:57:33 -04:00
|
|
|
import {
|
2020-02-20 10:08:44 -05:00
|
|
|
GlResizeObserverDirective,
|
2020-04-21 11:21:10 -04:00
|
|
|
GlIcon,
|
2020-04-14 08:09:26 -04:00
|
|
|
GlLoadingIcon,
|
2020-05-27 02:08:13 -04:00
|
|
|
GlNewDropdown as GlDropdown,
|
|
|
|
GlNewDropdownItem as GlDropdownItem,
|
|
|
|
GlNewDropdownDivider as GlDropdownDivider,
|
2019-08-14 18:57:33 -04:00
|
|
|
GlModal,
|
|
|
|
GlModalDirective,
|
2020-02-20 10:08:44 -05:00
|
|
|
GlTooltip,
|
2019-08-14 18:57:33 -04:00
|
|
|
GlTooltipDirective,
|
|
|
|
} from '@gitlab/ui';
|
2020-03-11 17:09:19 -04:00
|
|
|
import { __, n__ } from '~/locale';
|
2020-04-21 11:21:10 -04:00
|
|
|
import { panelTypes } from '../constants';
|
|
|
|
|
|
|
|
import MonitorEmptyChart from './charts/empty_chart.vue';
|
2019-08-16 18:30:05 -04:00
|
|
|
import MonitorTimeSeriesChart from './charts/time_series.vue';
|
2019-10-30 11:14:17 -04:00
|
|
|
import MonitorAnomalyChart from './charts/anomaly.vue';
|
2019-07-10 17:12:46 -04:00
|
|
|
import MonitorSingleStatChart from './charts/single_stat.vue';
|
2019-10-31 20:06:02 -04:00
|
|
|
import MonitorHeatmapChart from './charts/heatmap.vue';
|
2020-01-30 22:08:58 -05:00
|
|
|
import MonitorColumnChart from './charts/column.vue';
|
2020-03-27 08:07:43 -04:00
|
|
|
import MonitorBarChart from './charts/bar.vue';
|
2020-02-05 07:09:15 -05:00
|
|
|
import MonitorStackedColumnChart from './charts/stacked_column.vue';
|
2020-04-21 11:21:10 -04:00
|
|
|
|
2019-10-17 20:07:45 -04:00
|
|
|
import TrackEventDirective from '~/vue_shared/directives/track_event';
|
2020-04-22 17:10:00 -04:00
|
|
|
import AlertWidget from './alert_widget.vue';
|
2020-02-07 07:09:13 -05:00
|
|
|
import { timeRangeToUrl, downloadCSVOptions, generateLinkToChartOptions } from '../utils';
|
2020-05-27 02:08:13 -04:00
|
|
|
import { isSafeURL } from '~/lib/utils/url_utility';
|
2019-07-10 17:12:46 -04:00
|
|
|
|
2020-03-26 05:07:52 -04:00
|
|
|
const events = {
|
|
|
|
timeRangeZoom: 'timerangezoom',
|
2020-04-23 17:09:31 -04:00
|
|
|
expand: 'expand',
|
2020-03-26 05:07:52 -04:00
|
|
|
};
|
|
|
|
|
2019-07-10 17:12:46 -04:00
|
|
|
export default {
|
|
|
|
components: {
|
2020-04-21 11:21:10 -04:00
|
|
|
MonitorEmptyChart,
|
2020-04-22 17:10:00 -04:00
|
|
|
AlertWidget,
|
2020-04-21 11:21:10 -04:00
|
|
|
GlIcon,
|
2020-04-14 08:09:26 -04:00
|
|
|
GlLoadingIcon,
|
2020-02-20 10:08:44 -05:00
|
|
|
GlTooltip,
|
2019-08-06 07:48:09 -04:00
|
|
|
GlDropdown,
|
|
|
|
GlDropdownItem,
|
2020-05-27 02:08:13 -04:00
|
|
|
GlDropdownDivider,
|
2019-08-06 07:48:09 -04:00
|
|
|
GlModal,
|
|
|
|
},
|
|
|
|
directives: {
|
2020-02-20 10:08:44 -05:00
|
|
|
GlResizeObserver: GlResizeObserverDirective,
|
2019-08-06 07:48:09 -04:00
|
|
|
GlModal: GlModalDirective,
|
2019-08-14 18:57:33 -04:00
|
|
|
GlTooltip: GlTooltipDirective,
|
2019-10-17 20:07:45 -04:00
|
|
|
TrackEvent: TrackEventDirective,
|
2019-07-10 17:12:46 -04:00
|
|
|
},
|
|
|
|
props: {
|
2019-08-16 12:21:46 -04:00
|
|
|
clipboardText: {
|
|
|
|
type: String,
|
2019-12-13 19:08:27 -05:00
|
|
|
required: false,
|
|
|
|
default: '',
|
2019-08-16 12:21:46 -04:00
|
|
|
},
|
2019-07-10 17:12:46 -04:00
|
|
|
graphData: {
|
|
|
|
type: Object,
|
2020-04-29 11:09:58 -04:00
|
|
|
required: false,
|
|
|
|
default: null,
|
2019-07-10 17:12:46 -04:00
|
|
|
},
|
2019-12-05 19:07:48 -05:00
|
|
|
groupId: {
|
|
|
|
type: String,
|
|
|
|
required: false,
|
2020-04-21 11:21:10 -04:00
|
|
|
default: 'dashboard-panel',
|
2019-12-05 19:07:48 -05:00
|
|
|
},
|
2020-03-31 05:08:16 -04:00
|
|
|
namespace: {
|
|
|
|
type: String,
|
|
|
|
required: false,
|
|
|
|
default: 'monitoringDashboard',
|
|
|
|
},
|
2020-04-22 17:10:00 -04:00
|
|
|
alertsEndpoint: {
|
|
|
|
type: String,
|
|
|
|
required: false,
|
|
|
|
default: null,
|
|
|
|
},
|
|
|
|
prometheusAlertsAvailable: {
|
|
|
|
type: Boolean,
|
|
|
|
required: false,
|
|
|
|
default: false,
|
|
|
|
},
|
2020-04-30 17:09:47 -04:00
|
|
|
settingsPath: {
|
|
|
|
type: String,
|
|
|
|
required: false,
|
|
|
|
default: null,
|
|
|
|
},
|
2019-07-10 17:12:46 -04:00
|
|
|
},
|
2020-02-07 07:09:13 -05:00
|
|
|
data() {
|
|
|
|
return {
|
2020-02-20 10:08:44 -05:00
|
|
|
showTitleTooltip: false,
|
2020-02-07 07:09:13 -05:00
|
|
|
zoomedTimeRange: null,
|
2020-04-22 17:10:00 -04:00
|
|
|
allAlerts: {},
|
2020-04-23 17:09:31 -04:00
|
|
|
expandBtnAvailable: Boolean(this.$listeners[events.expand]),
|
2020-02-07 07:09:13 -05:00
|
|
|
};
|
|
|
|
},
|
2019-07-10 17:12:46 -04:00
|
|
|
computed: {
|
2020-03-31 05:08:16 -04:00
|
|
|
// Use functions to support dynamic namespaces in mapXXX helpers. Pattern described
|
|
|
|
// in https://github.com/vuejs/vuex/issues/863#issuecomment-329510765
|
|
|
|
...mapState({
|
|
|
|
deploymentData(state) {
|
|
|
|
return state[this.namespace].deploymentData;
|
|
|
|
},
|
2020-04-14 11:09:44 -04:00
|
|
|
annotations(state) {
|
|
|
|
return state[this.namespace].annotations;
|
|
|
|
},
|
2020-03-31 05:08:16 -04:00
|
|
|
projectPath(state) {
|
|
|
|
return state[this.namespace].projectPath;
|
|
|
|
},
|
|
|
|
logsPath(state) {
|
|
|
|
return state[this.namespace].logsPath;
|
|
|
|
},
|
|
|
|
timeRange(state) {
|
|
|
|
return state[this.namespace].timeRange;
|
|
|
|
},
|
2020-04-22 17:10:00 -04:00
|
|
|
metricsSavedToDb(state, getters) {
|
|
|
|
return getters[`${this.namespace}/metricsSavedToDb`];
|
|
|
|
},
|
2020-05-27 02:08:13 -04:00
|
|
|
selectedDashboard(state, getters) {
|
|
|
|
return getters[`${this.namespace}/selectedDashboard`];
|
|
|
|
},
|
2020-03-31 05:08:16 -04:00
|
|
|
}),
|
2020-02-20 10:08:44 -05:00
|
|
|
title() {
|
2020-04-29 11:09:58 -04:00
|
|
|
return this.graphData?.title || '';
|
2020-02-20 10:08:44 -05:00
|
|
|
},
|
2020-04-14 08:09:26 -04:00
|
|
|
graphDataHasResult() {
|
2020-04-29 11:09:58 -04:00
|
|
|
return this.graphData?.metrics?.[0]?.result?.length > 0;
|
2019-07-23 23:18:57 -04:00
|
|
|
},
|
2020-04-14 08:09:26 -04:00
|
|
|
graphDataIsLoading() {
|
2020-04-29 11:09:58 -04:00
|
|
|
const metrics = this.graphData?.metrics || [];
|
2020-04-14 08:09:26 -04:00
|
|
|
return metrics.some(({ loading }) => loading);
|
|
|
|
},
|
2020-02-07 07:09:13 -05:00
|
|
|
logsPathWithTimeRange() {
|
|
|
|
const timeRange = this.zoomedTimeRange || this.timeRange;
|
|
|
|
|
|
|
|
if (this.logsPath && this.logsPath !== invalidUrl && timeRange) {
|
|
|
|
return timeRangeToUrl(timeRange, this.logsPath);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
2019-08-14 18:57:33 -04:00
|
|
|
csvText() {
|
2020-04-29 11:09:58 -04:00
|
|
|
const chartData = this.graphData?.metrics[0].result[0].values || [];
|
2019-08-14 18:57:33 -04:00
|
|
|
const yLabel = this.graphData.y_label;
|
2020-03-18 11:09:45 -04:00
|
|
|
const header = `timestamp,${yLabel}\r\n`; // eslint-disable-line @gitlab/require-i18n-strings
|
2019-08-14 18:57:33 -04:00
|
|
|
return chartData.reduce((csv, data) => {
|
|
|
|
const row = data.join(',');
|
|
|
|
return `${csv}${row}\r\n`;
|
|
|
|
}, header);
|
|
|
|
},
|
|
|
|
downloadCsv() {
|
|
|
|
const data = new Blob([this.csvText], { type: 'text/plain' });
|
|
|
|
return window.URL.createObjectURL(data);
|
|
|
|
},
|
2020-04-23 17:09:31 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A chart is "basic" if it doesn't support
|
|
|
|
* the same features as the TimeSeries based components
|
|
|
|
* such as "annotations".
|
|
|
|
*
|
|
|
|
* @returns Vue Component wrapping a basic visualization
|
|
|
|
*/
|
|
|
|
basicChartComponent() {
|
|
|
|
if (this.isPanelType(panelTypes.SINGLE_STAT)) {
|
|
|
|
return MonitorSingleStatChart;
|
|
|
|
}
|
|
|
|
if (this.isPanelType(panelTypes.HEATMAP)) {
|
|
|
|
return MonitorHeatmapChart;
|
|
|
|
}
|
|
|
|
if (this.isPanelType(panelTypes.BAR)) {
|
|
|
|
return MonitorBarChart;
|
|
|
|
}
|
|
|
|
if (this.isPanelType(panelTypes.COLUMN)) {
|
|
|
|
return MonitorColumnChart;
|
|
|
|
}
|
|
|
|
if (this.isPanelType(panelTypes.STACKED_COLUMN)) {
|
|
|
|
return MonitorStackedColumnChart;
|
|
|
|
}
|
|
|
|
if (this.isPanelType(panelTypes.ANOMALY_CHART)) {
|
|
|
|
return MonitorAnomalyChart;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* In monitoring, Time Series charts typically support
|
|
|
|
* a larger feature set like "annotations", "deployment
|
|
|
|
* data", alert "thresholds" and "datazoom".
|
|
|
|
*
|
|
|
|
* This is intentional as Time Series are more frequently
|
|
|
|
* used.
|
|
|
|
*
|
|
|
|
* @returns Vue Component wrapping a time series visualization,
|
|
|
|
* Area Charts are rendered by default.
|
|
|
|
*/
|
|
|
|
timeSeriesChartComponent() {
|
2020-04-21 11:21:10 -04:00
|
|
|
if (this.isPanelType(panelTypes.ANOMALY_CHART)) {
|
2019-10-30 11:14:17 -04:00
|
|
|
return MonitorAnomalyChart;
|
|
|
|
}
|
|
|
|
return MonitorTimeSeriesChart;
|
|
|
|
},
|
2020-02-20 10:08:44 -05:00
|
|
|
isContextualMenuShown() {
|
2020-04-23 17:09:31 -04:00
|
|
|
return Boolean(this.graphDataHasResult && !this.basicChartComponent);
|
2020-02-20 10:08:44 -05:00
|
|
|
},
|
2020-03-11 17:09:19 -04:00
|
|
|
editCustomMetricLink() {
|
2020-04-30 17:09:47 -04:00
|
|
|
if (this.graphData.metrics.length > 1) {
|
|
|
|
return this.settingsPath;
|
|
|
|
}
|
2020-03-11 17:09:19 -04:00
|
|
|
return this.graphData?.metrics[0].edit_path;
|
|
|
|
},
|
|
|
|
editCustomMetricLinkText() {
|
|
|
|
return n__('Metrics|Edit metric', 'Metrics|Edit metrics', this.graphData.metrics.length);
|
|
|
|
},
|
2020-04-22 17:10:00 -04:00
|
|
|
hasMetricsInDb() {
|
|
|
|
const { metrics = [] } = this.graphData;
|
|
|
|
return metrics.some(({ metricId }) => this.metricsSavedToDb.includes(metricId));
|
|
|
|
},
|
|
|
|
alertWidgetAvailable() {
|
|
|
|
return (
|
|
|
|
this.prometheusAlertsAvailable &&
|
|
|
|
this.alertsEndpoint &&
|
|
|
|
this.graphData &&
|
|
|
|
this.hasMetricsInDb
|
|
|
|
);
|
|
|
|
},
|
2020-02-20 10:08:44 -05:00
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
this.refreshTitleTooltip();
|
2019-07-10 17:12:46 -04:00
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
getGraphAlerts(queries) {
|
|
|
|
if (!this.allAlerts) return {};
|
|
|
|
const metricIdsForChart = queries.map(q => q.metricId);
|
2020-01-24 04:08:32 -05:00
|
|
|
return pickBy(this.allAlerts, alert => metricIdsForChart.includes(alert.metricId));
|
2019-07-10 17:12:46 -04:00
|
|
|
},
|
|
|
|
getGraphAlertValues(queries) {
|
|
|
|
return Object.values(this.getGraphAlerts(queries));
|
|
|
|
},
|
|
|
|
isPanelType(type) {
|
2020-04-29 11:09:58 -04:00
|
|
|
return this.graphData?.type === type;
|
2019-07-10 17:12:46 -04:00
|
|
|
},
|
2019-08-16 12:21:46 -04:00
|
|
|
showToast() {
|
2019-10-09 08:06:13 -04:00
|
|
|
this.$toast.show(__('Link copied'));
|
2019-08-16 12:21:46 -04:00
|
|
|
},
|
2020-02-20 10:08:44 -05:00
|
|
|
refreshTitleTooltip() {
|
|
|
|
const { graphTitle } = this.$refs;
|
|
|
|
this.showTitleTooltip =
|
|
|
|
Boolean(graphTitle) && graphTitle.scrollWidth > graphTitle.offsetWidth;
|
|
|
|
},
|
|
|
|
|
2019-10-17 20:07:45 -04:00
|
|
|
downloadCSVOptions,
|
|
|
|
generateLinkToChartOptions,
|
2020-02-07 07:09:13 -05:00
|
|
|
|
2020-02-20 10:08:44 -05:00
|
|
|
onResize() {
|
|
|
|
this.refreshTitleTooltip();
|
|
|
|
},
|
2020-02-07 07:09:13 -05:00
|
|
|
onDatazoom({ start, end }) {
|
|
|
|
this.zoomedTimeRange = { start, end };
|
2020-03-26 05:07:52 -04:00
|
|
|
this.$emit(events.timeRangeZoom, { start, end });
|
2020-02-07 07:09:13 -05:00
|
|
|
},
|
2020-04-23 17:09:31 -04:00
|
|
|
onExpand() {
|
|
|
|
this.$emit(events.expand);
|
|
|
|
},
|
2020-04-22 17:10:00 -04:00
|
|
|
setAlerts(alertPath, alertAttributes) {
|
|
|
|
if (alertAttributes) {
|
|
|
|
this.$set(this.allAlerts, alertPath, alertAttributes);
|
|
|
|
} else {
|
|
|
|
this.$delete(this.allAlerts, alertPath);
|
|
|
|
}
|
|
|
|
},
|
2020-05-27 02:08:13 -04:00
|
|
|
safeUrl(url) {
|
|
|
|
return isSafeURL(url) ? url : '#';
|
|
|
|
},
|
2019-07-10 17:12:46 -04:00
|
|
|
},
|
2020-04-21 11:21:10 -04:00
|
|
|
panelTypes,
|
2019-07-10 17:12:46 -04:00
|
|
|
};
|
|
|
|
</script>
|
|
|
|
<template>
|
2020-02-20 10:08:44 -05:00
|
|
|
<div v-gl-resize-observer="onResize" class="prometheus-graph">
|
2020-04-14 08:09:26 -04:00
|
|
|
<div class="d-flex align-items-center mr-3">
|
2020-04-23 17:09:31 -04:00
|
|
|
<slot name="topLeft"></slot>
|
2020-02-20 10:08:44 -05:00
|
|
|
<h5
|
|
|
|
ref="graphTitle"
|
2020-04-30 11:09:46 -04:00
|
|
|
class="prometheus-graph-title gl-font-lg font-weight-bold text-truncate append-right-8"
|
2020-05-25 05:08:30 -04:00
|
|
|
tabindex="0"
|
2019-08-06 07:48:09 -04:00
|
|
|
>
|
2020-02-20 10:08:44 -05:00
|
|
|
{{ title }}
|
|
|
|
</h5>
|
|
|
|
<gl-tooltip :target="() => $refs.graphTitle" :disabled="!showTitleTooltip">
|
|
|
|
{{ title }}
|
|
|
|
</gl-tooltip>
|
2020-04-14 08:09:26 -04:00
|
|
|
<alert-widget
|
|
|
|
v-if="isContextualMenuShown && alertWidgetAvailable"
|
|
|
|
class="mx-1"
|
2020-04-23 17:09:31 -04:00
|
|
|
:modal-id="`alert-modal-${graphData.id}`"
|
2020-04-14 08:09:26 -04:00
|
|
|
:alerts-endpoint="alertsEndpoint"
|
|
|
|
:relevant-queries="graphData.metrics"
|
|
|
|
:alerts-to-manage="getGraphAlerts(graphData.metrics)"
|
|
|
|
@setAlerts="setAlerts"
|
|
|
|
/>
|
|
|
|
<div class="flex-grow-1"></div>
|
|
|
|
<div v-if="graphDataIsLoading" class="mx-1 mt-1">
|
|
|
|
<gl-loading-icon />
|
|
|
|
</div>
|
2020-02-20 10:08:44 -05:00
|
|
|
<div
|
|
|
|
v-if="isContextualMenuShown"
|
2020-04-21 11:21:10 -04:00
|
|
|
ref="contextualMenu"
|
2020-02-20 10:08:44 -05:00
|
|
|
data-qa-selector="prometheus_graph_widgets"
|
|
|
|
>
|
|
|
|
<div class="d-flex align-items-center">
|
|
|
|
<gl-dropdown
|
|
|
|
v-gl-tooltip
|
2020-05-27 02:08:13 -04:00
|
|
|
toggle-class="shadow-none border-0"
|
2020-02-20 10:08:44 -05:00
|
|
|
data-qa-selector="prometheus_widgets_dropdown"
|
|
|
|
right
|
|
|
|
:title="__('More actions')"
|
|
|
|
>
|
|
|
|
<template slot="button-content">
|
2020-05-27 02:08:13 -04:00
|
|
|
<gl-icon name="ellipsis_v" class="dropdown-icon text-secondary" />
|
2020-02-20 10:08:44 -05:00
|
|
|
</template>
|
2020-05-11 11:09:37 -04:00
|
|
|
<gl-dropdown-item
|
|
|
|
v-if="expandBtnAvailable"
|
|
|
|
ref="expandBtn"
|
|
|
|
:href="clipboardText"
|
|
|
|
@click.prevent="onExpand"
|
|
|
|
>
|
2020-04-23 17:09:31 -04:00
|
|
|
{{ s__('Metrics|Expand panel') }}
|
|
|
|
</gl-dropdown-item>
|
2020-03-11 17:09:19 -04:00
|
|
|
<gl-dropdown-item
|
|
|
|
v-if="editCustomMetricLink"
|
|
|
|
ref="editMetricLink"
|
|
|
|
:href="editCustomMetricLink"
|
|
|
|
>
|
|
|
|
{{ editCustomMetricLinkText }}
|
|
|
|
</gl-dropdown-item>
|
2020-02-20 10:08:44 -05:00
|
|
|
<gl-dropdown-item
|
|
|
|
v-if="logsPathWithTimeRange"
|
|
|
|
ref="viewLogsLink"
|
|
|
|
:href="logsPathWithTimeRange"
|
|
|
|
>
|
|
|
|
{{ s__('Metrics|View logs') }}
|
|
|
|
</gl-dropdown-item>
|
2020-02-07 07:09:13 -05:00
|
|
|
|
2020-02-20 10:08:44 -05:00
|
|
|
<gl-dropdown-item
|
|
|
|
v-if="csvText"
|
|
|
|
ref="downloadCsvLink"
|
|
|
|
v-track-event="downloadCSVOptions(title)"
|
|
|
|
:href="downloadCsv"
|
|
|
|
download="chart_metrics.csv"
|
|
|
|
>
|
|
|
|
{{ __('Download CSV') }}
|
|
|
|
</gl-dropdown-item>
|
|
|
|
<gl-dropdown-item
|
|
|
|
v-if="clipboardText"
|
|
|
|
ref="copyChartLink"
|
|
|
|
v-track-event="generateLinkToChartOptions(clipboardText)"
|
|
|
|
:data-clipboard-text="clipboardText"
|
2020-05-08 14:09:55 -04:00
|
|
|
data-qa-selector="generate_chart_link_menu_item"
|
2020-02-20 10:08:44 -05:00
|
|
|
@click="showToast(clipboardText)"
|
|
|
|
>
|
2020-03-31 17:08:05 -04:00
|
|
|
{{ __('Copy link to chart') }}
|
2020-02-20 10:08:44 -05:00
|
|
|
</gl-dropdown-item>
|
|
|
|
<gl-dropdown-item
|
|
|
|
v-if="alertWidgetAvailable"
|
2020-04-23 17:09:31 -04:00
|
|
|
v-gl-modal="`alert-modal-${graphData.id}`"
|
2020-02-20 10:08:44 -05:00
|
|
|
data-qa-selector="alert_widget_menu_item"
|
|
|
|
>
|
|
|
|
{{ __('Alerts') }}
|
|
|
|
</gl-dropdown-item>
|
2020-05-27 02:08:13 -04:00
|
|
|
|
|
|
|
<template v-if="graphData.links.length">
|
|
|
|
<gl-dropdown-divider />
|
|
|
|
<gl-dropdown-item
|
|
|
|
v-for="(link, index) in graphData.links"
|
|
|
|
:key="index"
|
|
|
|
:href="safeUrl(link.url)"
|
|
|
|
class="text-break"
|
|
|
|
>{{ link.title }}</gl-dropdown-item
|
|
|
|
>
|
|
|
|
</template>
|
|
|
|
<template v-if="selectedDashboard && selectedDashboard.can_edit">
|
|
|
|
<gl-dropdown-divider />
|
|
|
|
<gl-dropdown-item ref="manageLinksItem" :href="selectedDashboard.project_blob_path">{{
|
|
|
|
s__('Metrics|Manage chart links')
|
|
|
|
}}</gl-dropdown-item>
|
|
|
|
</template>
|
2020-02-20 10:08:44 -05:00
|
|
|
</gl-dropdown>
|
|
|
|
</div>
|
|
|
|
</div>
|
2019-08-06 07:48:09 -04:00
|
|
|
</div>
|
2020-02-20 10:08:44 -05:00
|
|
|
|
2020-04-23 17:09:31 -04:00
|
|
|
<monitor-empty-chart v-if="!graphDataHasResult" />
|
|
|
|
<component
|
|
|
|
:is="basicChartComponent"
|
|
|
|
v-else-if="basicChartComponent"
|
2020-02-20 10:08:44 -05:00
|
|
|
:graph-data="graphData"
|
2020-04-23 17:09:31 -04:00
|
|
|
v-bind="$attrs"
|
|
|
|
v-on="$listeners"
|
2020-02-20 10:08:44 -05:00
|
|
|
/>
|
|
|
|
<component
|
2020-04-23 17:09:31 -04:00
|
|
|
:is="timeSeriesChartComponent"
|
|
|
|
v-else
|
|
|
|
ref="timeSeriesChart"
|
2020-02-20 10:08:44 -05:00
|
|
|
:graph-data="graphData"
|
|
|
|
:deployment-data="deploymentData"
|
2020-04-14 11:09:44 -04:00
|
|
|
:annotations="annotations"
|
2020-02-20 10:08:44 -05:00
|
|
|
:project-path="projectPath"
|
|
|
|
:thresholds="getGraphAlertValues(graphData.metrics)"
|
|
|
|
:group-id="groupId"
|
2020-04-23 17:09:31 -04:00
|
|
|
v-bind="$attrs"
|
|
|
|
v-on="$listeners"
|
2020-02-20 10:08:44 -05:00
|
|
|
@datazoom="onDatazoom"
|
|
|
|
/>
|
|
|
|
</div>
|
2019-07-10 17:12:46 -04:00
|
|
|
</template>
|