Commit 63f7d087 authored by Miguel Rincon's avatar Miguel Rincon

Add timezone setting to metrics dashboards

Add new component to hold the form group and select to allow timezone
selection.
parent d5ebfff7
<script>
import { s__ } from '~/locale';
import { mapState, mapActions } from 'vuex';
import { GlFormGroup, GlFormSelect } from '@gitlab/ui';
import { timezones } from '~/monitoring/format_date';
export default {
components: {
GlFormGroup,
GlFormSelect,
},
computed: {
...mapState(['dashboardTimezone']),
dashboardTimezoneModel: {
get() {
return this.dashboardTimezone.selected;
},
set(selected) {
this.setDashboardTimezone(selected);
},
},
options() {
return [
{
value: timezones.LOCAL,
text: s__("MetricsSettings|User's local timezone"),
},
{
value: timezones.UTC,
text: s__('MetricsSettings|UTC (Coordinated Universal Time)'),
},
];
},
},
methods: {
...mapActions(['setDashboardTimezone']),
},
};
</script>
<template>
<gl-form-group
:label="s__('MetricsSettings|Dashboard timezone')"
label-for="dashboard-timezone-setting"
>
<template #description>
{{
s__(
"MetricsSettings|Choose whether to display dashboard metrics in UTC or the user's local timezone.",
)
}}
</template>
<gl-form-select
id="dashboard-timezone-setting"
v-model="dashboardTimezoneModel"
:options="options"
/>
</gl-form-group>
</template>
...@@ -2,12 +2,14 @@ ...@@ -2,12 +2,14 @@
import { mapState, mapActions } from 'vuex'; import { mapState, mapActions } from 'vuex';
import { GlDeprecatedButton, GlLink } from '@gitlab/ui'; import { GlDeprecatedButton, GlLink } from '@gitlab/ui';
import ExternalDashboard from './form_group/external_dashboard.vue'; import ExternalDashboard from './form_group/external_dashboard.vue';
import DashboardTimezone from './form_group/dashboard_timezone.vue';
export default { export default {
components: { components: {
GlDeprecatedButton, GlDeprecatedButton,
GlLink, GlLink,
ExternalDashboard, ExternalDashboard,
DashboardTimezone,
}, },
computed: { computed: {
...mapState(['helpPage']), ...mapState(['helpPage']),
...@@ -40,6 +42,7 @@ export default { ...@@ -40,6 +42,7 @@ export default {
</div> </div>
<div class="settings-content"> <div class="settings-content">
<form> <form>
<dashboard-timezone />
<external-dashboard /> <external-dashboard />
<gl-deprecated-button variant="success" @click="saveChanges"> <gl-deprecated-button variant="success" @click="saveChanges">
{{ __('Save Changes') }} {{ __('Save Changes') }}
......
...@@ -7,11 +7,15 @@ import * as mutationTypes from './mutation_types'; ...@@ -7,11 +7,15 @@ 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 setDashboardTimezone = ({ commit }, selected) =>
commit(mutationTypes.SET_DASHBOARD_TIMEZONE, selected);
export const saveChanges = ({ state, dispatch }) => export const saveChanges = ({ state, dispatch }) =>
axios axios
.patch(state.operationsSettingsEndpoint, { .patch(state.operationsSettingsEndpoint, {
project: { project: {
metrics_setting_attributes: { metrics_setting_attributes: {
dashboard_timezone: state.dashboardTimezone.selected,
external_dashboard_url: state.externalDashboard.url, external_dashboard_url: state.externalDashboard.url,
}, },
}, },
......
/* eslint-disable import/prefer-default-export */
export const SET_EXTERNAL_DASHBOARD_URL = 'SET_EXTERNAL_DASHBOARD_URL'; export const SET_EXTERNAL_DASHBOARD_URL = 'SET_EXTERNAL_DASHBOARD_URL';
export const SET_DASHBOARD_TIMEZONE = 'SET_DASHBOARD_TIMEZONE';
...@@ -4,4 +4,7 @@ export default { ...@@ -4,4 +4,7 @@ export default {
[types.SET_EXTERNAL_DASHBOARD_URL](state, url) { [types.SET_EXTERNAL_DASHBOARD_URL](state, url) {
state.externalDashboard.url = url; state.externalDashboard.url = url;
}, },
[types.SET_DASHBOARD_TIMEZONE](state, selected) {
state.dashboardTimezone.selected = selected;
},
}; };
...@@ -5,4 +5,8 @@ export default (initialState = {}) => ({ ...@@ -5,4 +5,8 @@ export default (initialState = {}) => ({
url: initialState.externalDashboardUrl, url: initialState.externalDashboardUrl,
helpPage: initialState.externalDashboardHelpPage, helpPage: initialState.externalDashboardHelpPage,
}, },
dashboardTimezone: {
selected: initialState.dashboardTimezoneSetting,
helpPage: initialState.dashboardTimezoneHelpPage,
},
}); });
---
title: Display dates on metrics dashboards in UTC time zone
merge_request: 32746
author:
type: added
...@@ -13967,6 +13967,12 @@ msgstr "" ...@@ -13967,6 +13967,12 @@ msgstr ""
msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard." msgid "MetricsSettings|Add a button to the metrics dashboard linking directly to your existing external dashboard."
msgstr "" msgstr ""
msgid "MetricsSettings|Choose whether to display dashboard metrics in UTC or the user's local timezone."
msgstr ""
msgid "MetricsSettings|Dashboard timezone"
msgstr ""
msgid "MetricsSettings|External dashboard URL" msgid "MetricsSettings|External dashboard URL"
msgstr "" msgstr ""
...@@ -13976,6 +13982,12 @@ msgstr "" ...@@ -13976,6 +13982,12 @@ msgstr ""
msgid "MetricsSettings|Metrics Dashboard" msgid "MetricsSettings|Metrics Dashboard"
msgstr "" msgstr ""
msgid "MetricsSettings|UTC (Coordinated Universal Time)"
msgstr ""
msgid "MetricsSettings|User's local timezone"
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, GlFormSelect } from '@gitlab/ui';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import MetricsSettings from '~/operation_settings/components/metrics_settings.vue'; import MetricsSettings from '~/operation_settings/components/metrics_settings.vue';
import ExternalDashboard from '~/operation_settings/components/form_group/external_dashboard.vue'; import ExternalDashboard from '~/operation_settings/components/form_group/external_dashboard.vue';
import DashboardTimezone from '~/operation_settings/components/form_group/dashboard_timezone.vue';
import { timezones } from '~/monitoring/format_date';
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';
...@@ -18,6 +21,8 @@ describe('operation settings external dashboard component', () => { ...@@ -18,6 +21,8 @@ describe('operation settings external dashboard component', () => {
const helpPage = `${TEST_HOST}/help/metrics/page/path`; 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 externalDashboardHelpPage = `${TEST_HOST}/help/external/page/path`; const externalDashboardHelpPage = `${TEST_HOST}/help/external/page/path`;
const dashboardTimezoneSetting = timezones.LOCAL;
const dashboardTimezoneHelpPage = `${TEST_HOST}/help/timezone/page/path`;
const mountComponent = (shallow = true) => { const mountComponent = (shallow = true) => {
const config = [ const config = [
...@@ -28,9 +33,12 @@ describe('operation settings external dashboard component', () => { ...@@ -28,9 +33,12 @@ describe('operation settings external dashboard component', () => {
helpPage, helpPage,
externalDashboardUrl, externalDashboardUrl,
externalDashboardHelpPage, externalDashboardHelpPage,
dashboardTimezoneSetting,
dashboardTimezoneHelpPage,
}), }),
stubs: { stubs: {
ExternalDashboard, ExternalDashboard,
DashboardTimezone,
}, },
}, },
]; ];
...@@ -84,38 +92,74 @@ describe('operation settings external dashboard component', () => { ...@@ -84,38 +92,74 @@ describe('operation settings external dashboard component', () => {
}); });
describe('form', () => { describe('form', () => {
describe('input label', () => { describe('dashboard timezone', () => {
let formGroup; describe('field label', () => {
let formGroup;
beforeEach(() => {
mountComponent(false); beforeEach(() => {
formGroup = wrapper.find(ExternalDashboard).find(GlFormGroup); mountComponent(false);
formGroup = wrapper.find(DashboardTimezone).find(GlFormGroup);
});
it('uses label text', () => {
expect(formGroup.find('label').text()).toBe('Dashboard timezone');
});
it('uses description text', () => {
const description = formGroup.find('small');
expect(description.text()).not.toBeFalsy();
});
}); });
it('uses label text', () => { describe('select field', () => {
expect(formGroup.find('label').text()).toBe('External dashboard URL'); let select;
});
beforeEach(() => {
mountComponent();
select = wrapper.find(DashboardTimezone).find(GlFormSelect);
});
it('uses description text', () => { it('defaults to externalDashboardUrl', () => {
const description = formGroup.find('small'); expect(select.attributes('value')).toBe(dashboardTimezoneSetting);
expect(description.find('a').attributes('href')).toBe(externalDashboardHelpPage); });
}); });
}); });
describe('input field', () => { describe('external dashboard', () => {
let input; describe('input label', () => {
let formGroup;
beforeEach(() => { beforeEach(() => {
mountComponent(); mountComponent(false);
input = wrapper.find(GlFormInput); formGroup = wrapper.find(ExternalDashboard).find(GlFormGroup);
}); });
it('uses label text', () => {
expect(formGroup.find('label').text()).toBe('External dashboard URL');
});
it('defaults to externalDashboardUrl', () => { it('uses description text', () => {
expect(input.attributes().value).toBe(externalDashboardUrl); const description = formGroup.find('small');
expect(description.find('a').attributes('href')).toBe(externalDashboardHelpPage);
});
}); });
it('uses a placeholder', () => { describe('input field', () => {
expect(input.attributes().placeholder).toBe('https://my-org.gitlab.io/my-dashboards'); let input;
beforeEach(() => {
mountComponent();
input = wrapper.find(ExternalDashboard).find(GlFormInput);
});
it('defaults to externalDashboardUrl', () => {
expect(input.attributes().value).toBeTruthy();
expect(input.attributes().value).toBe(externalDashboardUrl);
});
it('uses a placeholder', () => {
expect(input.attributes().placeholder).toBe('https://my-org.gitlab.io/my-dashboards');
});
}); });
}); });
...@@ -128,6 +172,7 @@ describe('operation settings external dashboard component', () => { ...@@ -128,6 +172,7 @@ describe('operation settings external dashboard component', () => {
{ {
project: { project: {
metrics_setting_attributes: { metrics_setting_attributes: {
dashboard_timezone: dashboardTimezoneSetting,
external_dashboard_url: externalDashboardUrl, external_dashboard_url: externalDashboardUrl,
}, },
}, },
......
import mutations from '~/operation_settings/store/mutations'; import mutations from '~/operation_settings/store/mutations';
import createState from '~/operation_settings/store/state'; import createState from '~/operation_settings/store/state';
import { timezones } from '~/monitoring/format_date';
describe('operation settings mutations', () => { describe('operation settings mutations', () => {
let localState; let localState;
...@@ -16,4 +17,13 @@ describe('operation settings mutations', () => { ...@@ -16,4 +17,13 @@ describe('operation settings mutations', () => {
expect(localState.externalDashboard.url).toBe(mockUrl); expect(localState.externalDashboard.url).toBe(mockUrl);
}); });
}); });
describe('SET_DASHBOARD_TIMEZONE', () => {
it('sets dashboardTimezoneSetting', () => {
mutations.SET_DASHBOARD_TIMEZONE(localState, timezones.LOCAL);
expect(localState.dashboardTimezone.selected).not.toBeUndefined();
expect(localState.dashboardTimezone.selected).toBe(timezones.LOCAL);
});
});
}); });
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