Commit 4d8ebc79 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '197879-add-time-picker-in-logs-time' into 'master'

Add time picker to logs page

Closes #197879

See merge request gitlab-org/gitlab!23837
parents ea067014 50c50a8f
...@@ -149,7 +149,13 @@ export default { ...@@ -149,7 +149,13 @@ export default {
}; };
</script> </script>
<template> <template>
<gl-dropdown :text="timeWindowText" class="date-time-picker" menu-class="date-time-picker-menu"> <gl-dropdown
:text="timeWindowText"
class="date-time-picker"
menu-class="date-time-picker-menu"
v-bind="$attrs"
toggle-class="w-100 text-truncate"
>
<div class="d-flex justify-content-between gl-p-2"> <div class="d-flex justify-content-between gl-p-2">
<gl-form-group <gl-form-group
:label="__('Custom range')" :label="__('Custom range')"
......
<script> <script>
import { mapActions, mapState, mapGetters } from 'vuex'; import { mapActions, mapState, mapGetters } from 'vuex';
import { GlDropdown, GlDropdownItem, GlFormGroup, GlSearchBoxByClick, GlAlert } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem, GlFormGroup, GlSearchBoxByClick, GlAlert } from '@gitlab/ui';
import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import { scrollDown } from '~/lib/utils/scroll_utils'; import { scrollDown } from '~/lib/utils/scroll_utils';
import LogControlButtons from './log_control_buttons.vue'; import LogControlButtons from './log_control_buttons.vue';
import { timeRanges, defaultTimeRange } from '~/monitoring/constants';
export default { export default {
components: { components: {
GlAlert, GlAlert,
...@@ -11,6 +14,7 @@ export default { ...@@ -11,6 +14,7 @@ export default {
GlDropdownItem, GlDropdownItem,
GlFormGroup, GlFormGroup,
GlSearchBoxByClick, GlSearchBoxByClick,
DateTimePicker,
LogControlButtons, LogControlButtons,
}, },
props: { props: {
...@@ -37,12 +41,24 @@ export default { ...@@ -37,12 +41,24 @@ export default {
data() { data() {
return { return {
searchQuery: '', searchQuery: '',
selectedTimeRange: defaultTimeRange,
timeRanges,
isElasticStackCalloutDismissed: false, isElasticStackCalloutDismissed: false,
}; };
}, },
computed: { computed: {
...mapState('environmentLogs', ['environments', 'timeWindow', 'logs', 'pods']), ...mapState('environmentLogs', ['environments', 'timeRange', 'logs', 'pods']),
...mapGetters('environmentLogs', ['trace']), ...mapGetters('environmentLogs', ['trace']),
timeRangeModel: {
get() {
return this.timeRange.current;
},
set(val) {
this.setTimeRange(val);
},
},
showLoader() { showLoader() {
return this.logs.isLoading || !this.logs.isComplete; return this.logs.isLoading || !this.logs.isComplete;
}, },
...@@ -85,7 +101,7 @@ export default { ...@@ -85,7 +101,7 @@ export default {
...mapActions('environmentLogs', [ ...mapActions('environmentLogs', [
'setInitData', 'setInitData',
'setSearch', 'setSearch',
'setTimeWindow', 'setTimeRange',
'showPodLogs', 'showPodLogs',
'showEnvironment', 'showEnvironment',
'fetchEnvironments', 'fetchEnvironments',
...@@ -166,22 +182,13 @@ export default { ...@@ -166,22 +182,13 @@ export default {
label-for="time-window-dropdown" label-for="time-window-dropdown"
class="col-3 px-1" class="col-3 px-1"
> >
<gl-dropdown <date-time-picker
id="time-window-dropdown" ref="dateTimePicker"
ref="time-window-dropdown" v-model="timeRangeModel"
class="w-100 gl-h-32"
:disabled="disableAdvancedControls" :disabled="disableAdvancedControls"
:text="timeWindow.options[timeWindow.current].label" :options="timeRanges"
class="d-flex gl-h-32" />
toggle-class="dropdown-menu-toggle"
>
<gl-dropdown-item
v-for="(option, key) in timeWindow.options"
:key="key"
@click="setTimeWindow(key)"
>
{{ option.label }}
</gl-dropdown-item>
</gl-dropdown>
</gl-form-group> </gl-form-group>
<gl-form-group <gl-form-group
id="search-fg" id="search-fg"
......
import { __ } from '~/locale';
export const defaultTimeWindow = 'oneHour';
export const timeWindows = {
oneHour: {
label: __('1 hour'),
seconds: 60 * 60,
},
fourHours: {
label: __('4 hours'),
seconds: 60 * 60 * 4,
},
oneDay: {
label: __('1 day'),
seconds: 60 * 60 * 24,
},
twoDays: {
label: __('2 days'),
seconds: 60 * 60 * 24 * 3,
},
pastWeek: {
label: __('Past week'),
seconds: 60 * 60 * 24 * 7,
},
twoWeeks: {
label: __('2 weeks'),
seconds: 60 * 60 * 24 * 15,
},
};
...@@ -4,10 +4,17 @@ import httpStatusCodes from '~/lib/utils/http_status'; ...@@ -4,10 +4,17 @@ import httpStatusCodes from '~/lib/utils/http_status';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import flash from '~/flash'; import flash from '~/flash';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { convertToFixedRange } from '~/lib/utils/datetime_range';
import * as types from './mutation_types'; import * as types from './mutation_types';
import { getTimeRange } from '../utils'; const flashTimeRangeWarning = () => {
import { timeWindows } from '../constants'; flash(s__('Metrics|Invalid time range, please verify.'), 'warning');
};
const flashLogsError = () => {
flash(s__('Metrics|There was an error fetching the logs, please try again'));
};
const requestLogsUntilData = params => const requestLogsUntilData = params =>
backOff((next, stop) => { backOff((next, stop) => {
...@@ -39,8 +46,8 @@ export const setSearch = ({ dispatch, commit }, searchQuery) => { ...@@ -39,8 +46,8 @@ export const setSearch = ({ dispatch, commit }, searchQuery) => {
dispatch('fetchLogs'); dispatch('fetchLogs');
}; };
export const setTimeWindow = ({ dispatch, commit }, timeWindowKey) => { export const setTimeRange = ({ dispatch, commit }, timeRange) => {
commit(types.SET_TIME_WINDOW, timeWindowKey); commit(types.SET_TIME_RANGE, timeRange);
dispatch('fetchLogs'); dispatch('fetchLogs');
}; };
...@@ -72,12 +79,14 @@ export const fetchLogs = ({ commit, state }) => { ...@@ -72,12 +79,14 @@ export const fetchLogs = ({ commit, state }) => {
search: state.search, search: state.search,
}; };
if (state.timeWindow.current) { if (state.timeRange.current) {
const { current } = state.timeWindow; try {
const { start, end } = getTimeRange(timeWindows[current].seconds); const { start, end } = convertToFixedRange(state.timeRange.current);
params.start = start;
params.start = start; params.end = end;
params.end = end; } catch {
flashTimeRangeWarning();
}
} }
commit(types.REQUEST_PODS_DATA); commit(types.REQUEST_PODS_DATA);
...@@ -94,7 +103,7 @@ export const fetchLogs = ({ commit, state }) => { ...@@ -94,7 +103,7 @@ export const fetchLogs = ({ commit, state }) => {
.catch(() => { .catch(() => {
commit(types.RECEIVE_PODS_DATA_ERROR); commit(types.RECEIVE_PODS_DATA_ERROR);
commit(types.RECEIVE_LOGS_DATA_ERROR); commit(types.RECEIVE_LOGS_DATA_ERROR);
flash(s__('Metrics|There was an error fetching the logs, please try again')); flashLogsError();
}); });
}; };
......
export const SET_PROJECT_ENVIRONMENT = 'SET_PROJECT_ENVIRONMENT'; export const SET_PROJECT_ENVIRONMENT = 'SET_PROJECT_ENVIRONMENT';
export const SET_SEARCH = 'SET_SEARCH'; export const SET_SEARCH = 'SET_SEARCH';
export const SET_TIME_WINDOW = 'SET_TIME_WINDOW'; export const SET_TIME_RANGE = 'SET_TIME_RANGE';
export const SET_CURRENT_POD_NAME = 'SET_CURRENT_POD_NAME';
export const REQUEST_ENVIRONMENTS_DATA = 'REQUEST_ENVIRONMENTS_DATA'; export const REQUEST_ENVIRONMENTS_DATA = 'REQUEST_ENVIRONMENTS_DATA';
export const RECEIVE_ENVIRONMENTS_DATA_SUCCESS = 'RECEIVE_ENVIRONMENTS_DATA_SUCCESS'; export const RECEIVE_ENVIRONMENTS_DATA_SUCCESS = 'RECEIVE_ENVIRONMENTS_DATA_SUCCESS';
...@@ -10,7 +11,6 @@ export const REQUEST_LOGS_DATA = 'REQUEST_LOGS_DATA'; ...@@ -10,7 +11,6 @@ export const REQUEST_LOGS_DATA = 'REQUEST_LOGS_DATA';
export const RECEIVE_LOGS_DATA_SUCCESS = 'RECEIVE_LOGS_DATA_SUCCESS'; export const RECEIVE_LOGS_DATA_SUCCESS = 'RECEIVE_LOGS_DATA_SUCCESS';
export const RECEIVE_LOGS_DATA_ERROR = 'RECEIVE_LOGS_DATA_ERROR'; export const RECEIVE_LOGS_DATA_ERROR = 'RECEIVE_LOGS_DATA_ERROR';
export const SET_CURRENT_POD_NAME = 'SET_CURRENT_POD_NAME';
export const REQUEST_PODS_DATA = 'REQUEST_PODS_DATA'; export const REQUEST_PODS_DATA = 'REQUEST_PODS_DATA';
export const RECEIVE_PODS_DATA_SUCCESS = 'RECEIVE_PODS_DATA_SUCCESS'; export const RECEIVE_PODS_DATA_SUCCESS = 'RECEIVE_PODS_DATA_SUCCESS';
export const RECEIVE_PODS_DATA_ERROR = 'RECEIVE_PODS_DATA_ERROR'; export const RECEIVE_PODS_DATA_ERROR = 'RECEIVE_PODS_DATA_ERROR';
...@@ -7,8 +7,8 @@ export default { ...@@ -7,8 +7,8 @@ export default {
}, },
/** Time Range data */ /** Time Range data */
[types.SET_TIME_WINDOW](state, timeWindowKey) { [types.SET_TIME_RANGE](state, timeRange) {
state.timeWindow.current = timeWindowKey; state.timeRange.current = timeRange;
}, },
/** Environments data */ /** Environments data */
......
import { defaultTimeWindow, timeWindows } from '../constants'; import { timeRanges, defaultTimeRange } from '~/monitoring/constants';
export default () => ({ export default () => ({
/** /**
...@@ -9,9 +9,9 @@ export default () => ({ ...@@ -9,9 +9,9 @@ export default () => ({
/** /**
* Time range (Show last) * Time range (Show last)
*/ */
timeWindow: { timeRange: {
options: { ...timeWindows }, options: timeRanges,
current: defaultTimeWindow, current: defaultTimeRange,
}, },
/** /**
......
...@@ -18,10 +18,6 @@ ...@@ -18,10 +18,6 @@
} }
} }
.dropdown-menu {
width: 300px;
}
.controllers { .controllers {
@include build-controllers(16px, flex-end, true, 2); @include build-controllers(16px, flex-end, true, 2);
} }
......
---
title: Add time picker to logs page
merge_request: 23837
author:
type: added
import Vue from 'vue'; import Vue from 'vue';
import { GlDropdown, GlDropdownItem, GlSearchBoxByClick } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem, GlSearchBoxByClick } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import EnvironmentLogs from 'ee/logs/components/environment_logs.vue'; import EnvironmentLogs from 'ee/logs/components/environment_logs.vue';
import { createStore } from 'ee/logs/stores'; import { createStore } from 'ee/logs/stores';
...@@ -42,7 +43,7 @@ describe('EnvironmentLogs', () => { ...@@ -42,7 +43,7 @@ describe('EnvironmentLogs', () => {
const findEnvironmentsDropdown = () => wrapper.find('.js-environments-dropdown'); const findEnvironmentsDropdown = () => wrapper.find('.js-environments-dropdown');
const findPodsDropdown = () => wrapper.find('.js-pods-dropdown'); const findPodsDropdown = () => wrapper.find('.js-pods-dropdown');
const findSearchBar = () => wrapper.find('.js-logs-search'); const findSearchBar = () => wrapper.find('.js-logs-search');
const findTimeWindowDropdown = () => wrapper.find({ ref: 'time-window-dropdown' }); const findTimeRangePicker = () => wrapper.find({ ref: 'dateTimePicker' });
const findLogControlButtons = () => wrapper.find({ name: 'log-control-buttons-stub' }); const findLogControlButtons = () => wrapper.find({ name: 'log-control-buttons-stub' });
const findLogTrace = () => wrapper.find('.js-log-trace'); const findLogTrace = () => wrapper.find('.js-log-trace');
...@@ -116,8 +117,8 @@ describe('EnvironmentLogs', () => { ...@@ -116,8 +117,8 @@ describe('EnvironmentLogs', () => {
expect(findSearchBar().exists()).toBe(true); expect(findSearchBar().exists()).toBe(true);
expect(findSearchBar().is(GlSearchBoxByClick)).toBe(true); expect(findSearchBar().is(GlSearchBoxByClick)).toBe(true);
expect(findTimeWindowDropdown().exists()).toBe(true); expect(findTimeRangePicker().exists()).toBe(true);
expect(findTimeWindowDropdown().is(GlDropdown)).toBe(true); expect(findTimeRangePicker().is(DateTimePicker)).toBe(true);
// log trace // log trace
expect(findLogTrace().isEmpty()).toBe(false); expect(findLogTrace().isEmpty()).toBe(false);
...@@ -169,7 +170,7 @@ describe('EnvironmentLogs', () => { ...@@ -169,7 +170,7 @@ describe('EnvironmentLogs', () => {
}); });
it('displays a disabled time window dropdown', () => { it('displays a disabled time window dropdown', () => {
expect(findTimeWindowDropdown().attributes('disabled')).toBe('true'); expect(findTimeRangePicker().attributes('disabled')).toBe('true');
}); });
it('does not update buttons state', () => { it('does not update buttons state', () => {
...@@ -207,7 +208,7 @@ describe('EnvironmentLogs', () => { ...@@ -207,7 +208,7 @@ describe('EnvironmentLogs', () => {
it('displays a disabled search bar and time window dropdown', () => { it('displays a disabled search bar and time window dropdown', () => {
expect(findSearchBar().exists()).toBe(true); expect(findSearchBar().exists()).toBe(true);
expect(findSearchBar().attributes('disabled')).toBe('true'); expect(findSearchBar().attributes('disabled')).toBe('true');
expect(findTimeWindowDropdown().attributes('disabled')).toBe('true'); expect(findTimeRangePicker().attributes('disabled')).toBe('true');
}); });
}); });
...@@ -234,7 +235,7 @@ describe('EnvironmentLogs', () => { ...@@ -234,7 +235,7 @@ describe('EnvironmentLogs', () => {
}); });
it('displays an enabled time window dropdown', () => { it('displays an enabled time window dropdown', () => {
expect(findTimeWindowDropdown().attributes('disabled')).toBeFalsy(); expect(findTimeRangePicker().attributes('disabled')).toBeFalsy();
}); });
it('populates environments dropdown', () => { it('populates environments dropdown', () => {
......
...@@ -119,12 +119,19 @@ describe('Logs Store Mutations', () => { ...@@ -119,12 +119,19 @@ describe('Logs Store Mutations', () => {
}); });
}); });
describe('SET_TIME_WINDOW', () => { describe('SET_TIME_RANGE', () => {
it('sets a time window Key', () => { it('sets a default range', () => {
const mockKey = 'fourHours'; expect(state.timeRange.current).toEqual(expect.any(Object));
mutations[types.SET_TIME_WINDOW](state, mockKey); });
it('sets a time range', () => {
const mockRange = {
start: '2020-01-10T18:00:00.000Z',
end: '2020-01-10T10:00:00.000Z',
};
mutations[types.SET_TIME_RANGE](state, mockRange);
expect(state.timeWindow.current).toEqual(mockKey); expect(state.timeRange.current).toEqual(mockRange);
}); });
}); });
......
...@@ -649,9 +649,6 @@ msgstr "" ...@@ -649,9 +649,6 @@ msgstr ""
msgid "1st contribution!" msgid "1st contribution!"
msgstr "" msgstr ""
msgid "2 days"
msgstr ""
msgid "2 weeks" msgid "2 weeks"
msgstr "" msgstr ""
...@@ -682,9 +679,6 @@ msgstr "" ...@@ -682,9 +679,6 @@ msgstr ""
msgid "30+ contributions" msgid "30+ contributions"
msgstr "" msgstr ""
msgid "4 hours"
msgstr ""
msgid "403|Please contact your GitLab administrator to get permission." msgid "403|Please contact your GitLab administrator to get permission."
msgstr "" msgstr ""
...@@ -11991,6 +11985,9 @@ msgstr "" ...@@ -11991,6 +11985,9 @@ msgstr ""
msgid "Metrics|For grouping similar metrics" msgid "Metrics|For grouping similar metrics"
msgstr "" msgstr ""
msgid "Metrics|Invalid time range, please verify."
msgstr ""
msgid "Metrics|Label of the y-axis (usually the unit). The x-axis always represents time." msgid "Metrics|Label of the y-axis (usually the unit). The x-axis always represents time."
msgstr "" msgstr ""
...@@ -13362,9 +13359,6 @@ msgstr "" ...@@ -13362,9 +13359,6 @@ msgstr ""
msgid "Past due" msgid "Past due"
msgstr "" msgstr ""
msgid "Past week"
msgstr ""
msgid "Paste a machine public key here. Read more about how to generate it %{link_start}here%{link_end}" msgid "Paste a machine public key here. Read more about how to generate it %{link_start}here%{link_end}"
msgstr "" msgstr ""
......
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