From 6a35203faddc4d8872aa673b49c1a3c4f18a60d9 Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 10 Jul 2018 13:57:31 -0700 Subject: [PATCH 01/33] Introduce time window dropdown and actions Co-authored-by: Alex Paxton Co-authored-by: Daniel Campbell --- ui/src/logs/actions/index.ts | 28 ++++++++++++++++ ui/src/logs/components/LogViewerHeader.tsx | 14 +++++++- .../WindowSelectorDropdown.tsx | 33 +++++++++++++++++++ ui/src/logs/constants/index.ts | 7 ++++ ui/src/logs/containers/LogsPage.tsx | 13 ++++++++ ui/src/logs/reducers/index.ts | 5 ++- ui/src/types/logs.ts | 1 + ui/test/logs/reducers/logs.test.ts | 10 ++++++ 8 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 ui/src/logs/components/window_selector_dropdown/WindowSelectorDropdown.tsx create mode 100644 ui/test/logs/reducers/logs.test.ts diff --git a/ui/src/logs/actions/index.ts b/ui/src/logs/actions/index.ts index b7fbb04470..15b7c343c6 100644 --- a/ui/src/logs/actions/index.ts +++ b/ui/src/logs/actions/index.ts @@ -47,6 +47,7 @@ export enum ActionTypes { SetSource = 'LOGS_SET_SOURCE', SetNamespaces = 'LOGS_SET_NAMESPACES', SetTimeRange = 'LOGS_SET_TIMERANGE', + SetTimeWindow = 'LOGS_SET_TIMEWINDOW', SetNamespace = 'LOGS_SET_NAMESPACE', SetHistogramQueryConfig = 'LOGS_SET_HISTOGRAM_QUERY_CONFIG', SetHistogramData = 'LOGS_SET_HISTOGRAM_DATA', @@ -128,6 +129,13 @@ interface SetTimeRangeAction { } } +interface SetTimeWindowAction { + type: ActionTypes.SetTimeWindow + payload: { + timeWindow: string + } +} + interface SetHistogramQueryConfig { type: ActionTypes.SetHistogramQueryConfig payload: { @@ -181,6 +189,7 @@ export type Action = | SetSourceAction | SetNamespacesAction | SetTimeRangeAction + | SetTimeWindowAction | SetNamespaceAction | SetHistogramQueryConfig | SetHistogramData @@ -242,6 +251,11 @@ const setHistogramData = (data): SetHistogramData => ({ payload: {data}, }) +export const setTimeWindow = (timeWindow: string): SetTimeWindowAction => ({ + type: ActionTypes.SetTimeWindow, + payload: {timeWindow}, +}) + export const executeHistogramQueryAsync = () => async ( dispatch, getState: GetState @@ -458,6 +472,20 @@ export const setTimeRangeAsync = (timeRange: TimeRange) => async ( dispatch(setTableQueryConfigAsync()) } +export const setTimeWindowAsync = (timeWindow: string) => async ( + dispatch +): Promise => { + console.log(timeWindow) + dispatch({ + type: ActionTypes.SetTimeWindow, + payload: { + timeWindow, + }, + }) + dispatch(setHistogramQueryConfigAsync()) + dispatch(setTableQueryConfigAsync()) +} + export const populateNamespacesAsync = ( proxyLink: string, source: Source = null diff --git a/ui/src/logs/components/LogViewerHeader.tsx b/ui/src/logs/components/LogViewerHeader.tsx index 18d3d5fd8e..ff7939e4d7 100644 --- a/ui/src/logs/components/LogViewerHeader.tsx +++ b/ui/src/logs/components/LogViewerHeader.tsx @@ -7,6 +7,7 @@ import Dropdown from 'src/shared/components/Dropdown' import PageHeader from 'src/reusable_ui/components/page_layout/PageHeader' import PageHeaderTitle from 'src/reusable_ui/components/page_layout/PageHeaderTitle' import TimeRangeDropdown from 'src/logs/components/TimeRangeDropdown' +import WindowSelectorDropdown from 'src/logs/components/window_selector_dropdown/WindowSelectorDropdown' import Authorized, {EDITOR_ROLE} from 'src/auth/Authorized' import {TimeRange} from 'src/types' @@ -27,6 +28,8 @@ interface Props { onChooseTimerange: (timeRange: TimeRange) => void onChangeLiveUpdatingStatus: () => void onShowOptionsOverlay: () => void + timeWindow: string + onChangeTimeWindow: (timeWindow: string) => void } class LogViewerHeader extends PureComponent { @@ -50,7 +53,12 @@ class LogViewerHeader extends PureComponent { } private get optionsComponents(): JSX.Element { - const {timeRange, onShowOptionsOverlay} = this.props + const { + timeRange, + onShowOptionsOverlay, + timeWindow, + onChangeTimeWindow, + } = this.props return ( <> @@ -67,6 +75,10 @@ class LogViewerHeader extends PureComponent { selected={this.selectedNamespace} onChoose={this.handleChooseNamespace} /> + void + selectedTimeWindow: string +} + +class WindowSelectorDropdown extends Component { + public render() { + const {selectedTimeWindow} = this.props + + return ( + + ) + } + + public handleChoose = time => { + const {onChangeWindow} = this.props + const {text} = time + + onChangeWindow(text) + } +} + +export default WindowSelectorDropdown diff --git a/ui/src/logs/constants/index.ts b/ui/src/logs/constants/index.ts index 5e443a64fa..3406487060 100644 --- a/ui/src/logs/constants/index.ts +++ b/ui/src/logs/constants/index.ts @@ -145,3 +145,10 @@ export enum EncodingVisibilityOptions { visible = 'visible', hidden = 'hidden', } + +export const TIME_RANGE_VALUES = [ + {text: '1m'}, + {text: '5m'}, + {text: '10m'}, + {text: '15m'}, +] diff --git a/ui/src/logs/containers/LogsPage.tsx b/ui/src/logs/containers/LogsPage.tsx index 9733bbdf51..b9fb744da4 100644 --- a/ui/src/logs/containers/LogsPage.tsx +++ b/ui/src/logs/containers/LogsPage.tsx @@ -7,6 +7,7 @@ import {AutoSizer} from 'react-virtualized' import { getSourceAndPopulateNamespacesAsync, setTimeRangeAsync, + setTimeWindowAsync, setNamespaceAsync, executeQueriesAsync, changeZoomAsync, @@ -58,6 +59,7 @@ interface Props { getSource: (sourceID: string) => void getSources: () => void setTimeRangeAsync: (timeRange: TimeRange) => void + setTimeWindowAsync: (timeWindow: string) => void setNamespaceAsync: (namespace: Namespace) => void changeZoomAsync: (timeRange: TimeRange) => void executeQueriesAsync: () => void @@ -69,6 +71,7 @@ interface Props { getConfig: (url: string) => Promise updateConfig: (url: string, config: LogConfig) => Promise timeRange: TimeRange + timeWindow: string histogramData: HistogramData tableData: TableData searchTerm: string @@ -255,12 +258,15 @@ class LogsPage extends PureComponent { currentNamespaces, currentNamespace, timeRange, + timeWindow, } = this.props const {liveUpdating} = this.state return ( { this.fetchNewDataset() } + private handleChooseTimeWindow = (timeWindow: string) => { + this.props.setTimeWindowAsync(timeWindow) + } + private handleChooseSource = (sourceID: string) => { this.props.getSource(sourceID) } @@ -399,6 +409,7 @@ const mapStateToProps = ({ currentSource, currentNamespaces, timeRange, + timeWindow, currentNamespace, histogramData, tableData, @@ -412,6 +423,7 @@ const mapStateToProps = ({ currentSource, currentNamespaces, timeRange, + timeWindow, currentNamespace, histogramData, tableData, @@ -426,6 +438,7 @@ const mapDispatchToProps = { getSource: getSourceAndPopulateNamespacesAsync, getSources: getSourcesAsync, setTimeRangeAsync, + setTimeWindowAsync, setNamespaceAsync, executeQueriesAsync, changeZoomAsync, diff --git a/ui/src/logs/reducers/index.ts b/ui/src/logs/reducers/index.ts index bbc03f405f..a1565a21dd 100644 --- a/ui/src/logs/reducers/index.ts +++ b/ui/src/logs/reducers/index.ts @@ -15,10 +15,11 @@ import { import {SeverityFormatOptions} from 'src/logs/constants' import {LogsState} from 'src/types/logs' -const defaultState: LogsState = { +export const defaultState: LogsState = { currentSource: null, currentNamespaces: [], timeRange: {lower: 'now() - 1m', upper: null}, + timeWindow: '1m', currentNamespace: null, histogramQueryConfig: null, tableQueryConfig: null, @@ -119,6 +120,8 @@ export default (state: LogsState = defaultState, action: Action) => { return {...state, currentNamespaces: action.payload.namespaces} case ActionTypes.SetTimeRange: return {...state, timeRange: action.payload.timeRange} + case ActionTypes.SetTimeWindow: + return {...state, timeWindow: action.payload.timeWindow} case ActionTypes.SetNamespace: return {...state, currentNamespace: action.payload.namespace} case ActionTypes.SetHistogramQueryConfig: diff --git a/ui/src/types/logs.ts b/ui/src/types/logs.ts index 9e2694c364..7f59d32582 100644 --- a/ui/src/types/logs.ts +++ b/ui/src/types/logs.ts @@ -20,6 +20,7 @@ export interface LogsState { currentNamespaces: Namespace[] currentNamespace: Namespace | null timeRange: TimeRange + timeWindow: string histogramQueryConfig: QueryConfig | null histogramData: object[] tableQueryConfig: QueryConfig | null diff --git a/ui/test/logs/reducers/logs.test.ts b/ui/test/logs/reducers/logs.test.ts new file mode 100644 index 0000000000..3dba5c6f46 --- /dev/null +++ b/ui/test/logs/reducers/logs.test.ts @@ -0,0 +1,10 @@ +import reducer, {defaultState} from 'src/logs/reducers' +import {setTimeWindow} from 'src/logs/actions' + +describe('Logs.Reducers', () => { + it('can set a time window', () => { + const expected = '1h' + const actual = reducer(defaultState, setTimeWindow(expected)) + expect(actual.timeWindow).toBe(expected) + }) +}) From ff0b3ce15f4134591b82492004ddb0ab5a9eede4 Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 10 Jul 2018 16:25:37 -0700 Subject: [PATCH 02/33] Separate time and window Co-authored-by: Alex Paxton Co-authored-by: Daniel Campbell --- ui/src/logs/actions/index.ts | 15 +- ui/src/logs/components/LogViewerHeader.tsx | 19 +- ui/src/logs/components/TimeRangeDropdown.tsx | 188 ++---------------- .../WindowSelectorDropdown.tsx | 19 +- ui/src/logs/constants/index.ts | 8 +- ui/src/logs/containers/LogsPage.tsx | 52 ++++- ui/src/logs/reducers/index.ts | 8 +- ui/src/types/logs.ts | 15 +- 8 files changed, 109 insertions(+), 215 deletions(-) diff --git a/ui/src/logs/actions/index.ts b/ui/src/logs/actions/index.ts index 15b7c343c6..bc64f74ca9 100644 --- a/ui/src/logs/actions/index.ts +++ b/ui/src/logs/actions/index.ts @@ -21,7 +21,13 @@ import { // getLogConfig as getLogConfigAJAX, // updateLogConfig as updateLogConfigAJAX, } from 'src/logs/api' -import {LogsState, Filter, TableData, LogConfig} from 'src/types/logs' +import { + LogsState, + Filter, + TableData, + LogConfig, + TimeWindow, +} from 'src/types/logs' const defaultTableData: TableData = { columns: [ @@ -132,7 +138,7 @@ interface SetTimeRangeAction { interface SetTimeWindowAction { type: ActionTypes.SetTimeWindow payload: { - timeWindow: string + timeWindow: TimeWindow } } @@ -251,7 +257,7 @@ const setHistogramData = (data): SetHistogramData => ({ payload: {data}, }) -export const setTimeWindow = (timeWindow: string): SetTimeWindowAction => ({ +export const setTimeWindow = (timeWindow: TimeWindow): SetTimeWindowAction => ({ type: ActionTypes.SetTimeWindow, payload: {timeWindow}, }) @@ -472,10 +478,9 @@ export const setTimeRangeAsync = (timeRange: TimeRange) => async ( dispatch(setTableQueryConfigAsync()) } -export const setTimeWindowAsync = (timeWindow: string) => async ( +export const setTimeWindowAsync = (timeWindow: TimeWindow) => async ( dispatch ): Promise => { - console.log(timeWindow) dispatch({ type: ActionTypes.SetTimeWindow, payload: { diff --git a/ui/src/logs/components/LogViewerHeader.tsx b/ui/src/logs/components/LogViewerHeader.tsx index ff7939e4d7..d0c9647c79 100644 --- a/ui/src/logs/components/LogViewerHeader.tsx +++ b/ui/src/logs/components/LogViewerHeader.tsx @@ -9,7 +9,7 @@ import PageHeaderTitle from 'src/reusable_ui/components/page_layout/PageHeaderTi import TimeRangeDropdown from 'src/logs/components/TimeRangeDropdown' import WindowSelectorDropdown from 'src/logs/components/window_selector_dropdown/WindowSelectorDropdown' import Authorized, {EDITOR_ROLE} from 'src/auth/Authorized' -import {TimeRange} from 'src/types' +import {TimeWindow, TimeWindowOption} from 'src/types/logs' interface SourceItem { id: string @@ -21,15 +21,14 @@ interface Props { availableSources: Source[] currentSource: Source | null currentNamespaces: Namespace[] - timeRange: TimeRange liveUpdating: boolean onChooseSource: (sourceID: string) => void onChooseNamespace: (namespace: Namespace) => void - onChooseTimerange: (timeRange: TimeRange) => void + onChooseTime: (time: string) => void onChangeLiveUpdatingStatus: () => void onShowOptionsOverlay: () => void - timeWindow: string - onChangeTimeWindow: (timeWindow: string) => void + timeWindow: TimeWindow + onChangeTimeWindow: (timeWindow: TimeWindowOption) => void } class LogViewerHeader extends PureComponent { @@ -54,10 +53,10 @@ class LogViewerHeader extends PureComponent { private get optionsComponents(): JSX.Element { const { - timeRange, onShowOptionsOverlay, timeWindow, onChangeTimeWindow, + onChooseTime, } = this.props return ( @@ -80,8 +79,8 @@ class LogViewerHeader extends PureComponent { onChangeWindow={onChangeTimeWindow} />