debian-mirror-gitlab/app/assets/javascripts/monitoring/components/dashboard.vue

285 lines
7.9 KiB
Vue
Raw Normal View History

2018-03-17 18:26:18 +05:30
<script>
2019-05-18 00:54:41 +05:30
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import _ from 'underscore';
2018-11-08 19:23:39 +05:30
import { s__ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
2019-05-18 00:54:41 +05:30
import '~/vue_shared/mixins/is_ee';
2018-05-09 12:01:36 +05:30
import Flash from '../../flash';
import MonitoringService from '../services/monitoring_service';
2019-02-15 15:39:39 +05:30
import MonitorAreaChart from './charts/area.vue';
2018-05-09 12:01:36 +05:30
import GraphGroup from './graph_group.vue';
import EmptyState from './empty_state.vue';
import MonitoringStore from '../stores/monitoring_store';
2019-05-18 00:54:41 +05:30
import { timeWindows } from '../constants';
import { getTimeDiff } from '../utils';
2019-03-02 22:35:43 +05:30
const sidebarAnimationDuration = 150;
let sidebarMutationObserver;
2018-03-17 18:26:18 +05:30
2018-05-09 12:01:36 +05:30
export default {
components: {
2019-02-15 15:39:39 +05:30
MonitorAreaChart,
2018-05-09 12:01:36 +05:30
GraphGroup,
EmptyState,
2018-11-08 19:23:39 +05:30
Icon,
2019-05-18 00:54:41 +05:30
GlDropdown,
GlDropdownItem,
2018-05-09 12:01:36 +05:30
},
2019-05-18 00:54:41 +05:30
2018-05-09 12:01:36 +05:30
props: {
hasMetrics: {
type: Boolean,
required: false,
default: true,
2018-03-17 18:26:18 +05:30
},
2018-05-09 12:01:36 +05:30
showPanels: {
type: Boolean,
required: false,
default: true,
2018-03-17 18:26:18 +05:30
},
2018-05-09 12:01:36 +05:30
documentationPath: {
type: String,
required: true,
2018-03-17 18:26:18 +05:30
},
2018-05-09 12:01:36 +05:30
settingsPath: {
type: String,
required: true,
},
clustersPath: {
type: String,
required: true,
},
tagsPath: {
type: String,
required: true,
},
projectPath: {
type: String,
required: true,
},
metricsEndpoint: {
type: String,
required: true,
},
deploymentEndpoint: {
type: String,
required: false,
default: null,
},
emptyGettingStartedSvgPath: {
type: String,
required: true,
},
emptyLoadingSvgPath: {
type: String,
required: true,
},
emptyNoDataSvgPath: {
type: String,
required: true,
},
emptyUnableToConnectSvgPath: {
type: String,
required: true,
},
2018-11-08 19:23:39 +05:30
environmentsEndpoint: {
type: String,
required: true,
},
currentEnvironmentName: {
type: String,
required: true,
},
2019-05-18 00:54:41 +05:30
showTimeWindowDropdown: {
type: Boolean,
required: true,
},
2018-05-09 12:01:36 +05:30
},
data() {
return {
store: new MonitoringStore(),
state: 'gettingStarted',
showEmptyState: true,
2018-12-05 23:21:45 +05:30
elWidth: 0,
2019-05-18 00:54:41 +05:30
selectedTimeWindow: '',
2018-05-09 12:01:36 +05:30
};
},
created() {
this.service = new MonitoringService({
metricsEndpoint: this.metricsEndpoint,
deploymentEndpoint: this.deploymentEndpoint,
2018-11-08 19:23:39 +05:30
environmentsEndpoint: this.environmentsEndpoint,
2018-05-09 12:01:36 +05:30
});
2019-05-18 00:54:41 +05:30
this.timeWindows = timeWindows;
this.selectedTimeWindow = this.timeWindows.eightHours;
2018-05-09 12:01:36 +05:30
},
beforeDestroy() {
2019-03-02 22:35:43 +05:30
if (sidebarMutationObserver) {
sidebarMutationObserver.disconnect();
}
2018-05-09 12:01:36 +05:30
},
mounted() {
2019-05-18 00:54:41 +05:30
this.servicePromises = [
this.service
.getGraphsData()
.then(data => this.store.storeMetrics(data))
.catch(() => Flash(s__('Metrics|There was an error while retrieving metrics'))),
this.service
.getDeploymentData()
.then(data => this.store.storeDeploymentData(data))
.catch(() => Flash(s__('Metrics|There was an error getting deployment information.'))),
];
2018-05-09 12:01:36 +05:30
if (!this.hasMetrics) {
this.state = 'gettingStarted';
} else {
2019-05-18 00:54:41 +05:30
if (this.environmentsEndpoint) {
this.servicePromises.push(
this.service
.getEnvironmentsData()
.then(data => this.store.storeEnvironmentsData(data))
.catch(() =>
Flash(s__('Metrics|There was an error getting environments information.')),
),
);
}
2018-05-09 12:01:36 +05:30
this.getGraphsData();
2019-03-02 22:35:43 +05:30
sidebarMutationObserver = new MutationObserver(this.onSidebarMutation);
sidebarMutationObserver.observe(document.querySelector('.layout-page'), {
attributes: true,
childList: false,
subtree: false,
});
2018-05-09 12:01:36 +05:30
}
},
methods: {
2019-05-18 00:54:41 +05:30
getGraphAlerts(queries) {
if (!this.allAlerts) return {};
const metricIdsForChart = queries.map(q => q.metricId);
return _.pick(this.allAlerts, alert => metricIdsForChart.includes(alert.metricId));
},
getGraphAlertValues(queries) {
return Object.values(this.getGraphAlerts(queries));
2019-02-15 15:39:39 +05:30
},
2018-05-09 12:01:36 +05:30
getGraphsData() {
this.state = 'loading';
2019-05-18 00:54:41 +05:30
Promise.all(this.servicePromises)
2018-05-09 12:01:36 +05:30
.then(() => {
if (this.store.groups.length < 1) {
this.state = 'noData';
return;
}
2018-12-13 13:39:08 +05:30
2018-05-09 12:01:36 +05:30
this.showEmptyState = false;
})
.catch(() => {
this.state = 'unableToConnect';
});
},
2019-05-18 00:54:41 +05:30
getGraphsDataWithTime(timeFrame) {
this.state = 'loading';
this.showEmptyState = true;
this.service
.getGraphsData(getTimeDiff(this.timeWindows[timeFrame]))
.then(data => {
this.store.storeMetrics(data);
this.selectedTimeWindow = this.timeWindows[timeFrame];
})
.catch(() => {
Flash(s__('Metrics|Not enough data to display'));
})
.finally(() => {
this.showEmptyState = false;
});
},
2019-03-02 22:35:43 +05:30
onSidebarMutation() {
setTimeout(() => {
this.elWidth = this.$el.clientWidth;
}, sidebarAnimationDuration);
2018-03-17 18:26:18 +05:30
},
2019-05-18 00:54:41 +05:30
activeTimeWindow(key) {
return this.timeWindows[key] === this.selectedTimeWindow;
},
2018-05-09 12:01:36 +05:30
},
};
2018-03-17 18:26:18 +05:30
</script>
<template>
2019-03-02 22:35:43 +05:30
<div v-if="!showEmptyState" class="prometheus-graphs prepend-top-default">
2019-05-18 00:54:41 +05:30
<div
v-if="environmentsEndpoint"
class="dropdowns d-flex align-items-center justify-content-between"
>
<div class="d-flex align-items-center">
<strong>{{ s__('Metrics|Environment') }}</strong>
<gl-dropdown
class="prepend-left-10 js-environments-dropdown"
toggle-class="dropdown-menu-toggle"
:text="currentEnvironmentName"
:disabled="store.environmentsData.length === 0"
>
<gl-dropdown-item
v-for="environment in store.environmentsData"
:key="environment.id"
:href="environment.metrics_path"
:active="environment.name === currentEnvironmentName"
active-class="is-active"
>{{ environment.name }}</gl-dropdown-item
>
</gl-dropdown>
</div>
<div v-if="showTimeWindowDropdown" class="d-flex align-items-center">
<strong>{{ s__('Metrics|Show last') }}</strong>
<gl-dropdown
class="prepend-left-10 js-time-window-dropdown"
toggle-class="dropdown-menu-toggle"
:text="selectedTimeWindow"
2018-12-13 13:39:08 +05:30
>
2019-05-18 00:54:41 +05:30
<gl-dropdown-item
v-for="(value, key) in timeWindows"
:key="key"
:active="activeTimeWindow(key)"
@click="getGraphsDataWithTime(key)"
>{{ value }}</gl-dropdown-item
>
</gl-dropdown>
2018-11-08 19:23:39 +05:30
</div>
</div>
2018-03-17 18:26:18 +05:30
<graph-group
v-for="(groupData, index) in store.groups"
:key="index"
:name="groupData.group"
2018-03-27 19:54:05 +05:30
:show-panels="showPanels"
2018-03-17 18:26:18 +05:30
>
2019-03-02 22:35:43 +05:30
<monitor-area-chart
2018-12-05 23:21:45 +05:30
v-for="(graphData, graphIndex) in groupData.metrics"
:key="graphIndex"
2018-03-17 18:26:18 +05:30
:graph-data="graphData"
:deployment-data="store.deploymentData"
2019-05-18 00:54:41 +05:30
:thresholds="getGraphAlertValues(graphData.queries)"
2019-03-02 22:35:43 +05:30
:container-width="elWidth"
2019-02-15 15:39:39 +05:30
group-id="monitor-area-chart"
2019-05-18 00:54:41 +05:30
>
<alert-widget
v-if="isEE && prometheusAlertsAvailable && alertsEndpoint && graphData"
:alerts-endpoint="alertsEndpoint"
:relevant-queries="graphData.queries"
:alerts-to-manage="getGraphAlerts(graphData.queries)"
@setAlerts="setAlerts"
/>
</monitor-area-chart>
2018-03-17 18:26:18 +05:30
</graph-group>
</div>
<empty-state
v-else
:selected-state="state"
:documentation-path="documentationPath"
:settings-path="settingsPath"
:clusters-path="clustersPath"
:empty-getting-started-svg-path="emptyGettingStartedSvgPath"
:empty-loading-svg-path="emptyLoadingSvgPath"
2018-05-09 12:01:36 +05:30
:empty-no-data-svg-path="emptyNoDataSvgPath"
2018-03-17 18:26:18 +05:30
:empty-unable-to-connect-svg-path="emptyUnableToConnectSvgPath"
/>
</template>