Add custom metrics form to dashboard
Use existing form to allow users to add custom metrics via the dashboard
This commit is contained in:
parent
f6ca3b1ad9
commit
78d3f94cee
|
@ -1,5 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlButton, GlDropdown, GlDropdownItem, GlLink } from '@gitlab/ui';
|
import {
|
||||||
|
GlButton,
|
||||||
|
GlDropdown,
|
||||||
|
GlDropdownItem,
|
||||||
|
GlModal,
|
||||||
|
GlModalDirective,
|
||||||
|
GlLink,
|
||||||
|
} from '@gitlab/ui';
|
||||||
import _ from 'underscore';
|
import _ from 'underscore';
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import Icon from '~/vue_shared/components/icon.vue';
|
import Icon from '~/vue_shared/components/icon.vue';
|
||||||
|
@ -27,8 +34,11 @@ export default {
|
||||||
GlDropdown,
|
GlDropdown,
|
||||||
GlDropdownItem,
|
GlDropdownItem,
|
||||||
GlLink,
|
GlLink,
|
||||||
|
GlModal,
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
GlModalDirective,
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
externalDashboardPath: {
|
externalDashboardPath: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -102,6 +112,19 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
customMetricsAvailable: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
customMetricsPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
validateQueryPath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -111,8 +134,14 @@ export default {
|
||||||
elWidth: 0,
|
elWidth: 0,
|
||||||
selectedTimeWindow: '',
|
selectedTimeWindow: '',
|
||||||
selectedTimeWindowKey: '',
|
selectedTimeWindowKey: '',
|
||||||
|
formIsValid: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
canAddMetrics() {
|
||||||
|
return this.customMetricsAvailable && this.customMetricsPath.length;
|
||||||
|
},
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
this.service = new MonitoringService({
|
this.service = new MonitoringService({
|
||||||
metricsEndpoint: this.metricsEndpoint,
|
metricsEndpoint: this.metricsEndpoint,
|
||||||
|
@ -193,11 +222,20 @@ export default {
|
||||||
this.state = 'unableToConnect';
|
this.state = 'unableToConnect';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
hideAddMetricModal() {
|
||||||
|
this.$refs.addMetricModal.hide();
|
||||||
|
},
|
||||||
onSidebarMutation() {
|
onSidebarMutation() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.elWidth = this.$el.clientWidth;
|
this.elWidth = this.$el.clientWidth;
|
||||||
}, sidebarAnimationDuration);
|
}, sidebarAnimationDuration);
|
||||||
},
|
},
|
||||||
|
setFormValidity(isValid) {
|
||||||
|
this.formIsValid = isValid;
|
||||||
|
},
|
||||||
|
submitCustomMetricsForm() {
|
||||||
|
this.$refs.customMetricsForm.submit();
|
||||||
|
},
|
||||||
activeTimeWindow(key) {
|
activeTimeWindow(key) {
|
||||||
return this.timeWindows[key] === this.selectedTimeWindow;
|
return this.timeWindows[key] === this.selectedTimeWindow;
|
||||||
},
|
},
|
||||||
|
@ -205,11 +243,16 @@ export default {
|
||||||
return `?time_window=${key}`;
|
return `?time_window=${key}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
addMetric: {
|
||||||
|
title: s__('Metrics|Add metric'),
|
||||||
|
modalId: 'add-metric',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="!showEmptyState" class="prometheus-graphs prepend-top-default">
|
<div v-if="!showEmptyState" class="prometheus-graphs">
|
||||||
|
<div class="gl-p-3 border-bottom bg-gray-light d-flex justify-content-between">
|
||||||
<div
|
<div
|
||||||
v-if="environmentsEndpoint"
|
v-if="environmentsEndpoint"
|
||||||
class="dropdowns d-flex align-items-center justify-content-between"
|
class="dropdowns d-flex align-items-center justify-content-between"
|
||||||
|
@ -225,7 +268,6 @@ export default {
|
||||||
<gl-dropdown-item
|
<gl-dropdown-item
|
||||||
v-for="environment in store.environmentsData"
|
v-for="environment in store.environmentsData"
|
||||||
:key="environment.id"
|
:key="environment.id"
|
||||||
:href="environment.metrics_path"
|
|
||||||
:active="environment.name === currentEnvironmentName"
|
:active="environment.name === currentEnvironmentName"
|
||||||
active-class="is-active"
|
active-class="is-active"
|
||||||
>{{ environment.name }}</gl-dropdown-item
|
>{{ environment.name }}</gl-dropdown-item
|
||||||
|
@ -247,9 +289,44 @@ export default {
|
||||||
>
|
>
|
||||||
</gl-dropdown>
|
</gl-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex">
|
||||||
|
<div v-if="isEE && canAddMetrics">
|
||||||
|
<gl-button
|
||||||
|
v-gl-modal-directive="$options.addMetric.modalId"
|
||||||
|
class="js-add-metric-button text-success border-success"
|
||||||
|
>
|
||||||
|
{{ $options.addMetric.title }}
|
||||||
|
</gl-button>
|
||||||
|
<gl-modal
|
||||||
|
ref="addMetricModal"
|
||||||
|
:modal-id="$options.addMetric.modalId"
|
||||||
|
:title="$options.addMetric.title"
|
||||||
|
>
|
||||||
|
<form ref="customMetricsForm" :action="customMetricsPath" method="post">
|
||||||
|
<custom-metrics-form-fields
|
||||||
|
:validate-query-path="validateQueryPath"
|
||||||
|
form-operation="post"
|
||||||
|
@formValidation="setFormValidity"
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
<div slot="modal-footer">
|
||||||
|
<gl-button @click="hideAddMetricModal">
|
||||||
|
{{ __('Cancel') }}
|
||||||
|
</gl-button>
|
||||||
|
<gl-button
|
||||||
|
:disabled="!formIsValid"
|
||||||
|
variant="success"
|
||||||
|
@click="submitCustomMetricsForm"
|
||||||
|
>
|
||||||
|
{{ __('Save changes') }}
|
||||||
|
</gl-button>
|
||||||
|
</div>
|
||||||
|
</gl-modal>
|
||||||
|
</div>
|
||||||
<gl-button
|
<gl-button
|
||||||
v-if="externalDashboardPath.length"
|
v-if="externalDashboardPath.length"
|
||||||
class="js-external-dashboard-link"
|
class="js-external-dashboard-link prepend-left-8"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
:href="externalDashboardPath"
|
:href="externalDashboardPath"
|
||||||
>
|
>
|
||||||
|
@ -257,6 +334,7 @@ export default {
|
||||||
<icon name="external-link" />
|
<icon name="external-link" />
|
||||||
</gl-button>
|
</gl-button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<graph-group
|
<graph-group
|
||||||
v-for="(groupData, index) in store.groups"
|
v-for="(groupData, index) in store.groups"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
|
|
@ -48,6 +48,10 @@
|
||||||
color: $brand-info;
|
color: $brand-info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-gray-light {
|
||||||
|
background-color: $gray-light;
|
||||||
|
}
|
||||||
|
|
||||||
.text-break-word {
|
.text-break-word {
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
@ -446,19 +450,13 @@ img.emoji {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** COMMON SPACING CLASSES **/
|
/** COMMON SPACING CLASSES **/
|
||||||
.gl-pl-0 { padding-left: 0; }
|
@each $index, $padding in $spacing-scale {
|
||||||
.gl-pl-1 { padding-left: #{0.5 * $grid-size}; }
|
#{'.gl-p-#{$index}'} { padding: $padding; }
|
||||||
.gl-pl-2 { padding-left: $grid-size; }
|
#{'.gl-pl-#{$index}'} { padding-left: $padding; }
|
||||||
.gl-pl-3 { padding-left: #{2 * $grid-size}; }
|
#{'.gl-pr-#{$index}'} { padding-right: $padding; }
|
||||||
.gl-pl-4 { padding-left: #{3 * $grid-size}; }
|
#{'.gl-pt-#{$index}'} { padding-top: $padding; }
|
||||||
.gl-pl-5 { padding-left: #{4 * $grid-size}; }
|
#{'.gl-pb-#{$index}'} { padding-bottom: $padding; }
|
||||||
|
}
|
||||||
.gl-pr-0 { padding-right: 0; }
|
|
||||||
.gl-pr-1 { padding-right: #{0.5 * $grid-size}; }
|
|
||||||
.gl-pr-2 { padding-right: $grid-size; }
|
|
||||||
.gl-pr-3 { padding-right: #{2 * $grid-size}; }
|
|
||||||
.gl-pr-4 { padding-right: #{3 * $grid-size}; }
|
|
||||||
.gl-pr-5 { padding-right: #{4 * $grid-size}; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes browser specific clear icon from input fields in
|
* Removes browser specific clear icon from input fields in
|
||||||
|
|
|
@ -11,6 +11,14 @@ $default-transition-duration: 0.15s;
|
||||||
$contextual-sidebar-width: 220px;
|
$contextual-sidebar-width: 220px;
|
||||||
$contextual-sidebar-collapsed-width: 50px;
|
$contextual-sidebar-collapsed-width: 50px;
|
||||||
$toggle-sidebar-height: 48px;
|
$toggle-sidebar-height: 48px;
|
||||||
|
$spacing-scale: (
|
||||||
|
0: 0,
|
||||||
|
1: #{0.5 * $grid-size},
|
||||||
|
2: $grid-size,
|
||||||
|
3: #{2 * $grid-size},
|
||||||
|
4: #{3 * $grid-size},
|
||||||
|
5: #{4 * $grid-size}
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Color schema
|
* Color schema
|
||||||
|
|
|
@ -5911,6 +5911,9 @@ msgstr ""
|
||||||
msgid "Metrics for environment"
|
msgid "Metrics for environment"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Metrics|Add metric"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Metrics|Check out the CI/CD documentation on deploying to an environment"
|
msgid "Metrics|Check out the CI/CD documentation on deploying to an environment"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,9 @@ const propsData = {
|
||||||
emptyUnableToConnectSvgPath: '/path/to/unable-to-connect.svg',
|
emptyUnableToConnectSvgPath: '/path/to/unable-to-connect.svg',
|
||||||
environmentsEndpoint: '/root/hello-prometheus/environments/35',
|
environmentsEndpoint: '/root/hello-prometheus/environments/35',
|
||||||
currentEnvironmentName: 'production',
|
currentEnvironmentName: 'production',
|
||||||
|
customMetricsAvailable: false,
|
||||||
|
customMetricsPath: '',
|
||||||
|
validateQueryPath: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default propsData;
|
export default propsData;
|
||||||
|
@ -163,7 +166,7 @@ describe('Dashboard', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the environments dropdown with a single is-active element', done => {
|
it('renders the environments dropdown with a single active element', done => {
|
||||||
const component = new DashboardComponent({
|
const component = new DashboardComponent({
|
||||||
el: document.querySelector('.prometheus-graphs'),
|
el: document.querySelector('.prometheus-graphs'),
|
||||||
propsData: {
|
propsData: {
|
||||||
|
@ -178,7 +181,7 @@ describe('Dashboard', () => {
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const dropdownItems = component.$el.querySelectorAll(
|
const dropdownItems = component.$el.querySelectorAll(
|
||||||
'.js-environments-dropdown .dropdown-item.is-active',
|
'.js-environments-dropdown .dropdown-item[active="true"]',
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(dropdownItems.length).toEqual(1);
|
expect(dropdownItems.length).toEqual(1);
|
||||||
|
|
Loading…
Reference in New Issue