Commit 4a7cdcbf authored by Miguel Rincon's avatar Miguel Rincon

Make operations/metrics settings extensible

As metrics dashboard will have a timezone selection, the metrics
settings should become more general, so they can fit more fields
and configuration.

The form title and structure has been updated to prepare for more
fields. Most of the changes are internal.
parent 2eb346c7
<script>
import { mapState, mapActions } from 'vuex';
import { GlLink, GlFormGroup, GlFormInput } from '@gitlab/ui';
export default {
components: {
GlLink,
GlFormGroup,
GlFormInput,
},
computed: {
...mapState(['externalDashboard']),
userDashboardUrl: {
get() {
return this.externalDashboard.url;
},
set(url) {
this.setExternalDashboardUrl(url);
},
},
},
methods: {
...mapActions(['setExternalDashboardUrl']),
},
};
</script>
<template>
<gl-form-group
:label="s__('MetricsSettings|External dashboard URL')"
label-for="external-dashboard-url"
>
<template #description>
{{
s__(
'MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard.',
)
}}
<gl-link :href="externalDashboard.helpPage">{{ __('Learn more') }}</gl-link>
</template>
<!-- placeholder with a url is a false positive -->
<!-- eslint-disable @gitlab/vue-require-i18n-attribute-strings -->
<gl-form-input
id="external-dashboard-url"
v-model="userDashboardUrl"
placeholder="https://my-org.gitlab.io/my-dashboards"
/>
<!-- eslint-enable @gitlab/vue-require-i18n-attribute-strings -->
</gl-form-group>
</template>
<script> <script>
import { mapState, mapActions } from 'vuex'; import { mapState, mapActions } from 'vuex';
import { GlDeprecatedButton, GlFormGroup, GlFormInput, GlLink } from '@gitlab/ui'; import { GlDeprecatedButton, GlLink } from '@gitlab/ui';
import ExternalDashboard from './form_group/external_dashboard.vue';
export default { export default {
components: { components: {
GlDeprecatedButton, GlDeprecatedButton,
GlFormGroup,
GlFormInput,
GlLink, GlLink,
ExternalDashboard,
}, },
computed: { computed: {
...mapState([ ...mapState(['helpPage']),
'externalDashboardHelpPagePath',
'externalDashboardUrl',
'operationsSettingsEndpoint',
]),
userDashboardUrl: { userDashboardUrl: {
get() { get() {
return this.externalDashboardUrl; return this.externalDashboard.url;
}, },
set(url) { set(url) {
this.setExternalDashboardUrl(url); this.setExternalDashboardUrl(url);
...@@ -25,7 +21,7 @@ export default { ...@@ -25,7 +21,7 @@ export default {
}, },
}, },
methods: { methods: {
...mapActions(['setExternalDashboardUrl', 'updateExternalDashboardUrl']), ...mapActions(['saveChanges']),
}, },
}; };
</script> </script>
...@@ -34,36 +30,18 @@ export default { ...@@ -34,36 +30,18 @@ export default {
<section class="settings no-animate"> <section class="settings no-animate">
<div class="settings-header"> <div class="settings-header">
<h3 class="js-section-header h4"> <h3 class="js-section-header h4">
{{ s__('ExternalMetrics|External Dashboard') }} {{ s__('MetricsSettings|Metrics Dashboard') }}
</h3> </h3>
<gl-deprecated-button class="js-settings-toggle">{{ __('Expand') }}</gl-deprecated-button> <gl-deprecated-button class="js-settings-toggle">{{ __('Expand') }}</gl-deprecated-button>
<p class="js-section-sub-header"> <p class="js-section-sub-header">
{{ {{ s__('MetricsSettings|Manage Metrics Dashboard settings.') }}
s__( <gl-link :href="helpPage">{{ __('Learn more') }}</gl-link>
'ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards.',
)
}}
<gl-link :href="externalDashboardHelpPagePath">{{ __('Learn more') }}</gl-link>
</p> </p>
</div> </div>
<div class="settings-content"> <div class="settings-content">
<form> <form>
<gl-form-group <external-dashboard />
:label="s__('ExternalMetrics|Full dashboard URL')" <gl-deprecated-button variant="success" @click="saveChanges">
label-for="full-dashboard-url"
:description="s__('ExternalMetrics|Enter the URL of the dashboard you want to link to')"
>
<!-- placeholder with a url is a false positive -->
<!-- eslint-disable @gitlab/vue-require-i18n-attribute-strings -->
<gl-form-input
id="full-dashboard-url"
v-model="userDashboardUrl"
placeholder="https://my-org.gitlab.io/my-dashboards"
@keydown.enter.native.prevent="updateExternalDashboardUrl"
/>
<!-- eslint-enable @gitlab/vue-require-i18n-attribute-strings -->
</gl-form-group>
<gl-deprecated-button variant="success" @click="updateExternalDashboardUrl">
{{ __('Save Changes') }} {{ __('Save Changes') }}
</gl-deprecated-button> </gl-deprecated-button>
</form> </form>
......
import Vue from 'vue'; import Vue from 'vue';
import store from './store'; import store from './store';
import ExternalDashboardForm from './components/external_dashboard.vue'; import MetricsSettingsForm from './components/metrics_settings.vue';
export default () => { export default () => {
const el = document.querySelector('.js-operation-settings'); const el = document.querySelector('.js-operation-settings');
...@@ -9,7 +9,7 @@ export default () => { ...@@ -9,7 +9,7 @@ export default () => {
el, el,
store: store(el.dataset), store: store(el.dataset),
render(createElement) { render(createElement) {
return createElement(ExternalDashboardForm); return createElement(MetricsSettingsForm);
}, },
}); });
}; };
...@@ -7,19 +7,19 @@ import * as mutationTypes from './mutation_types'; ...@@ -7,19 +7,19 @@ import * as mutationTypes from './mutation_types';
export const setExternalDashboardUrl = ({ commit }, url) => export const setExternalDashboardUrl = ({ commit }, url) =>
commit(mutationTypes.SET_EXTERNAL_DASHBOARD_URL, url); commit(mutationTypes.SET_EXTERNAL_DASHBOARD_URL, url);
export const updateExternalDashboardUrl = ({ state, dispatch }) => export const saveChanges = ({ state, dispatch }) =>
axios axios
.patch(state.operationsSettingsEndpoint, { .patch(state.operationsSettingsEndpoint, {
project: { project: {
metrics_setting_attributes: { metrics_setting_attributes: {
external_dashboard_url: state.externalDashboardUrl, external_dashboard_url: state.externalDashboard.url,
}, },
}, },
}) })
.then(() => dispatch('receiveExternalDashboardUpdateSuccess')) .then(() => dispatch('receiveSaveChangesSuccess'))
.catch(error => dispatch('receiveExternalDashboardUpdateError', error)); .catch(error => dispatch('receiveSaveChangesError', error));
export const receiveExternalDashboardUpdateSuccess = () => { export const receiveSaveChangesSuccess = () => {
/** /**
* The operations_controller currently handles successful requests * The operations_controller currently handles successful requests
* by creating a flash banner messsage to notify the user. * by creating a flash banner messsage to notify the user.
...@@ -27,8 +27,8 @@ export const receiveExternalDashboardUpdateSuccess = () => { ...@@ -27,8 +27,8 @@ export const receiveExternalDashboardUpdateSuccess = () => {
refreshCurrentPage(); refreshCurrentPage();
}; };
export const receiveExternalDashboardUpdateError = (_, error) => { export const receiveSaveChangesError = (_, error) => {
const { response } = error; const { response = {} } = error;
const message = response.data && response.data.message ? response.data.message : ''; const message = response.data && response.data.message ? response.data.message : '';
createFlash(`${__('There was an error saving your changes.')} ${message}`, 'alert'); createFlash(`${__('There was an error saving your changes.')} ${message}`, 'alert');
......
...@@ -2,6 +2,6 @@ import * as types from './mutation_types'; ...@@ -2,6 +2,6 @@ import * as types from './mutation_types';
export default { export default {
[types.SET_EXTERNAL_DASHBOARD_URL](state, url) { [types.SET_EXTERNAL_DASHBOARD_URL](state, url) {
state.externalDashboardUrl = url; state.externalDashboard.url = url;
}, },
}; };
export default (initialState = {}) => ({ export default (initialState = {}) => ({
externalDashboardUrl: initialState.externalDashboardUrl || '',
operationsSettingsEndpoint: initialState.operationsSettingsEndpoint, operationsSettingsEndpoint: initialState.operationsSettingsEndpoint,
externalDashboardHelpPagePath: initialState.externalDashboardHelpPagePath, helpPage: initialState.helpPage,
externalDashboard: {
url: initialState.externalDashboardUrl,
helpPage: initialState.externalDashboardHelpPage,
},
}); });
.js-operation-settings{ data: { operations_settings_endpoint: project_settings_operations_path(@project), .js-operation-settings{ data: { operations_settings_endpoint: project_settings_operations_path(@project),
help_page: help_page_path('user/project/integrations/prometheus'),
external_dashboard: { url: metrics_external_dashboard_url, external_dashboard: { url: metrics_external_dashboard_url,
help_page_path: help_page_path('user/project/operations/linking_to_an_external_dashboard') } } } help_page: help_page_path('user/project/operations/linking_to_an_external_dashboard'),
} } }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
= render 'projects/settings/operations/incidents' = render 'projects/settings/operations/incidents'
= render 'projects/settings/operations/error_tracking' = render 'projects/settings/operations/error_tracking'
= render 'projects/settings/operations/prometheus', service: prometheus_service if Feature.enabled?(:settings_operations_prometheus_service) = render 'projects/settings/operations/prometheus', service: prometheus_service if Feature.enabled?(:settings_operations_prometheus_service)
= render 'projects/settings/operations/external_dashboard' = render 'projects/settings/operations/metrics_dashboard'
= render 'projects/settings/operations/grafana_integration' = render 'projects/settings/operations/grafana_integration'
= render_if_exists 'projects/settings/operations/tracing' = render_if_exists 'projects/settings/operations/tracing'
= render_if_exists 'projects/settings/operations/status_page' = render_if_exists 'projects/settings/operations/status_page'
---
title: Update operations metrics settings title and description to make them general
merge_request: 32494
author:
type: changed
...@@ -9100,18 +9100,6 @@ msgstr "" ...@@ -9100,18 +9100,6 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used." msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr "" msgstr ""
msgid "ExternalMetrics|Add a button to the metrics dashboard linking directly to your existing external dashboards."
msgstr ""
msgid "ExternalMetrics|Enter the URL of the dashboard you want to link to"
msgstr ""
msgid "ExternalMetrics|External Dashboard"
msgstr ""
msgid "ExternalMetrics|Full dashboard URL"
msgstr ""
msgid "ExternalWikiService|External Wiki" msgid "ExternalWikiService|External Wiki"
msgstr "" msgstr ""
...@@ -13708,6 +13696,18 @@ msgstr "" ...@@ -13708,6 +13696,18 @@ msgstr ""
msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard" msgid "Metrics::UsersStarredDashboards|You are not authorized to add star to this dashboard"
msgstr "" msgstr ""
msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
msgstr ""
msgid "MetricsSettings|External dashboard URL"
msgstr ""
msgid "MetricsSettings|Manage Metrics Dashboard settings."
msgstr ""
msgid "MetricsSettings|Metrics Dashboard"
msgstr ""
msgid "Metrics|Add metric" msgid "Metrics|Add metric"
msgstr "" msgstr ""
......
import { mount, shallowMount } from '@vue/test-utils'; import { mount, shallowMount } from '@vue/test-utils';
import { GlDeprecatedButton, GlLink, GlFormGroup, GlFormInput } from '@gitlab/ui'; import { GlDeprecatedButton, GlLink, GlFormGroup, GlFormInput } from '@gitlab/ui';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import ExternalDashboard from '~/operation_settings/components/external_dashboard.vue'; import MetricsSettings from '~/operation_settings/components/metrics_settings.vue';
import ExternalDashboard from '~/operation_settings/components/form_group/external_dashboard.vue';
import store from '~/operation_settings/store'; import store from '~/operation_settings/store';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { refreshCurrentPage } from '~/lib/utils/url_utility'; import { refreshCurrentPage } from '~/lib/utils/url_utility';
...@@ -12,18 +13,25 @@ jest.mock('~/flash'); ...@@ -12,18 +13,25 @@ jest.mock('~/flash');
describe('operation settings external dashboard component', () => { describe('operation settings external dashboard component', () => {
let wrapper; let wrapper;
const operationsSettingsEndpoint = `${TEST_HOST}/mock/ops/settings/endpoint`; const operationsSettingsEndpoint = `${TEST_HOST}/mock/ops/settings/endpoint`;
const helpPage = `${TEST_HOST}/help/metrics/page/path`;
const externalDashboardUrl = `http://mock-external-domain.com/external/dashboard/url`; const externalDashboardUrl = `http://mock-external-domain.com/external/dashboard/url`;
const externalDashboardHelpPagePath = `${TEST_HOST}/help/page/path`; const externalDashboardHelpPage = `${TEST_HOST}/help/external/page/path`;
const mountComponent = (shallow = true) => { const mountComponent = (shallow = true) => {
const config = [ const config = [
ExternalDashboard, MetricsSettings,
{ {
store: store({ store: store({
operationsSettingsEndpoint, operationsSettingsEndpoint,
helpPage,
externalDashboardUrl, externalDashboardUrl,
externalDashboardHelpPagePath, externalDashboardHelpPage,
}), }),
stubs: {
ExternalDashboard,
},
}, },
]; ];
wrapper = shallow ? shallowMount(...config) : mount(...config); wrapper = shallow ? shallowMount(...config) : mount(...config);
...@@ -44,7 +52,7 @@ describe('operation settings external dashboard component', () => { ...@@ -44,7 +52,7 @@ describe('operation settings external dashboard component', () => {
it('renders header text', () => { it('renders header text', () => {
mountComponent(); mountComponent();
expect(wrapper.find('.js-section-header').text()).toBe('External Dashboard'); expect(wrapper.find('.js-section-header').text()).toBe('Metrics Dashboard');
}); });
describe('expand/collapse button', () => { describe('expand/collapse button', () => {
...@@ -64,16 +72,14 @@ describe('operation settings external dashboard component', () => { ...@@ -64,16 +72,14 @@ describe('operation settings external dashboard component', () => {
}); });
it('renders descriptive text', () => { it('renders descriptive text', () => {
expect(subHeader.text()).toContain( expect(subHeader.text()).toContain('Manage Metrics Dashboard settings.');
'Add a button to the metrics dashboard linking directly to your existing external dashboards.',
);
}); });
it('renders help page link', () => { it('renders help page link', () => {
const link = subHeader.find(GlLink); const link = subHeader.find(GlLink);
expect(link.text()).toBe('Learn more'); expect(link.text()).toBe('Learn more');
expect(link.attributes().href).toBe(externalDashboardHelpPagePath); expect(link.attributes().href).toBe(helpPage);
}); });
}); });
...@@ -82,18 +88,17 @@ describe('operation settings external dashboard component', () => { ...@@ -82,18 +88,17 @@ describe('operation settings external dashboard component', () => {
let formGroup; let formGroup;
beforeEach(() => { beforeEach(() => {
mountComponent(); mountComponent(false);
formGroup = wrapper.find(GlFormGroup); formGroup = wrapper.find(ExternalDashboard).find(GlFormGroup);
}); });
it('uses label text', () => { it('uses label text', () => {
expect(formGroup.attributes().label).toBe('Full dashboard URL'); expect(formGroup.find('label').text()).toBe('External dashboard URL');
}); });
it('uses description text', () => { it('uses description text', () => {
expect(formGroup.attributes().description).toBe( const description = formGroup.find('small');
'Enter the URL of the dashboard you want to link to', expect(description.find('a').attributes('href')).toBe(externalDashboardHelpPage);
);
}); });
}); });
......
...@@ -13,7 +13,7 @@ describe('operation settings mutations', () => { ...@@ -13,7 +13,7 @@ describe('operation settings mutations', () => {
const mockUrl = 'mockUrl'; const mockUrl = 'mockUrl';
mutations.SET_EXTERNAL_DASHBOARD_URL(localState, mockUrl); mutations.SET_EXTERNAL_DASHBOARD_URL(localState, mockUrl);
expect(localState.externalDashboardUrl).toBe(mockUrl); expect(localState.externalDashboard.url).toBe(mockUrl);
}); });
}); });
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment