mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-13 07:29:05 +08:00
fix[logs][FE]: live tail is fixed (#1759)
* fix: live tail is fixed * fix: graph state is updated * chore: step size is updated * chore: xaxis config is updated * chore: isDisabled state is updated for top navigation * chore: selected interval is updated in the reducer * fix: build is fixed * chore: xAxis config is updated Co-authored-by: Pranay Prateek <pranay@signoz.io> Co-authored-by: Ankit Nayan <ankit@signoz.io>
This commit is contained in:
parent
d06d41af87
commit
6c9036fbf4
@ -4,9 +4,6 @@ import { useSelector } from 'react-redux';
|
|||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
|
|
||||||
interface ITimeUnit {
|
|
||||||
[key: string]: TimeUnit;
|
|
||||||
}
|
|
||||||
interface IAxisTimeUintConfig {
|
interface IAxisTimeUintConfig {
|
||||||
unitName: TimeUnit;
|
unitName: TimeUnit;
|
||||||
multiplier: number;
|
multiplier: number;
|
||||||
@ -22,7 +19,7 @@ export interface ITimeRange {
|
|||||||
maxTime: number | null;
|
maxTime: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TIME_UNITS: ITimeUnit = {
|
export const TIME_UNITS: Record<TimeUnit, TimeUnit> = {
|
||||||
millisecond: 'millisecond',
|
millisecond: 'millisecond',
|
||||||
second: 'second',
|
second: 'second',
|
||||||
minute: 'minute',
|
minute: 'minute',
|
||||||
@ -31,6 +28,7 @@ export const TIME_UNITS: ITimeUnit = {
|
|||||||
week: 'week',
|
week: 'week',
|
||||||
month: 'month',
|
month: 'month',
|
||||||
year: 'year',
|
year: 'year',
|
||||||
|
quarter: 'quarter',
|
||||||
};
|
};
|
||||||
|
|
||||||
const TIME_UNITS_CONFIG: IAxisTimeUintConfig[] = [
|
const TIME_UNITS_CONFIG: IAxisTimeUintConfig[] = [
|
||||||
@ -93,6 +91,7 @@ export const convertTimeRange = (
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
unitName: relevantTimeUnit.unitName,
|
unitName: relevantTimeUnit.unitName,
|
||||||
stepSize: Math.floor(stepSize) || 1,
|
stepSize: Math.floor(stepSize) || 1,
|
||||||
|
@ -11,6 +11,7 @@ import { throttle } from 'lodash-es';
|
|||||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
|
import { UPDATE_AUTO_REFRESH_DISABLED } from 'types/actions/globalTime';
|
||||||
import {
|
import {
|
||||||
FLUSH_LOGS,
|
FLUSH_LOGS,
|
||||||
PUSH_LIVE_TAIL_EVENT,
|
PUSH_LIVE_TAIL_EVENT,
|
||||||
@ -19,6 +20,7 @@ import {
|
|||||||
} from 'types/actions/logs';
|
} from 'types/actions/logs';
|
||||||
import { TLogsLiveTailState } from 'types/api/logs/liveTail';
|
import { TLogsLiveTailState } from 'types/api/logs/liveTail';
|
||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
import { ILogsReducer } from 'types/reducer/logs';
|
import { ILogsReducer } from 'types/reducer/logs';
|
||||||
|
|
||||||
import { TIME_PICKER_OPTIONS } from './config';
|
import { TIME_PICKER_OPTIONS } from './config';
|
||||||
@ -34,12 +36,20 @@ function LogLiveTail(): JSX.Element {
|
|||||||
logs,
|
logs,
|
||||||
} = useSelector<AppState, ILogsReducer>((state) => state.logs);
|
} = useSelector<AppState, ILogsReducer>((state) => state.logs);
|
||||||
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||||
|
const { selectedAutoRefreshInterval } = useSelector<AppState, GlobalReducer>(
|
||||||
|
(state) => state.globalTime,
|
||||||
|
);
|
||||||
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const handleLiveTail = (toggleState: TLogsLiveTailState): void => {
|
const handleLiveTail = (toggleState: TLogsLiveTailState): void => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: TOGGLE_LIVE_TAIL,
|
type: TOGGLE_LIVE_TAIL,
|
||||||
payload: toggleState,
|
payload: toggleState,
|
||||||
});
|
});
|
||||||
|
dispatch({
|
||||||
|
type: UPDATE_AUTO_REFRESH_DISABLED,
|
||||||
|
payload: toggleState === 'PLAYING',
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const batchedEventsRef = useRef<Record<string, unknown>[]>([]);
|
const batchedEventsRef = useRef<Record<string, unknown>[]>([]);
|
||||||
@ -131,6 +141,10 @@ function LogLiveTail(): JSX.Element {
|
|||||||
[dispatch, liveTail, liveTailStartRange],
|
[dispatch, liveTail, liveTailStartRange],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isDisabled = useMemo(() => selectedAutoRefreshInterval?.length > 0, [
|
||||||
|
selectedAutoRefreshInterval,
|
||||||
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TimePickerCard>
|
<TimePickerCard>
|
||||||
<Space size={0} align="center">
|
<Space size={0} align="center">
|
||||||
@ -149,6 +163,7 @@ function LogLiveTail(): JSX.Element {
|
|||||||
type="primary"
|
type="primary"
|
||||||
onClick={handleLiveTailStart}
|
onClick={handleLiveTailStart}
|
||||||
title="Start live tail"
|
title="Start live tail"
|
||||||
|
disabled={isDisabled}
|
||||||
>
|
>
|
||||||
Go Live <PlayCircleOutlined />
|
Go Live <PlayCircleOutlined />
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -31,6 +31,7 @@ function LogsAggregate({ getLogsAggregate }: LogsAggregateProps): JSX.Element {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const reFetchIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
const reFetchIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
switch (liveTail) {
|
switch (liveTail) {
|
||||||
case 'STOPPED': {
|
case 'STOPPED': {
|
||||||
@ -38,18 +39,6 @@ function LogsAggregate({ getLogsAggregate }: LogsAggregateProps): JSX.Element {
|
|||||||
clearInterval(reFetchIntervalRef.current);
|
clearInterval(reFetchIntervalRef.current);
|
||||||
}
|
}
|
||||||
reFetchIntervalRef.current = null;
|
reFetchIntervalRef.current = null;
|
||||||
// getLogsAggregate({
|
|
||||||
// timestampStart: minTime,
|
|
||||||
// timestampEnd: maxTime,
|
|
||||||
// step: getStep({
|
|
||||||
// start: minTime,
|
|
||||||
// end: maxTime,
|
|
||||||
// inputFormat: 'ns',
|
|
||||||
// }),
|
|
||||||
// q: queryString,
|
|
||||||
// ...(idStart ? { idGt: idStart } : {}),
|
|
||||||
// ...(idEnd ? { idLt: idEnd } : {}),
|
|
||||||
// });
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +95,7 @@ function LogsAggregate({ getLogsAggregate }: LogsAggregateProps): JSX.Element {
|
|||||||
}}
|
}}
|
||||||
type="bar"
|
type="bar"
|
||||||
containerHeight="100%"
|
containerHeight="100%"
|
||||||
animate={false}
|
animate
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -21,7 +21,7 @@ import { v4 } from 'uuid';
|
|||||||
|
|
||||||
import { SearchFieldsProps } from '..';
|
import { SearchFieldsProps } from '..';
|
||||||
import FieldKey from '../FieldKey';
|
import FieldKey from '../FieldKey';
|
||||||
import { QueryConditionContainer, QueryFieldContainer } from '../styles';
|
import { QueryFieldContainer } from '../styles';
|
||||||
import { createParsedQueryStructure } from '../utils';
|
import { createParsedQueryStructure } from '../utils';
|
||||||
import { Container, QueryWrapper } from './styles';
|
import { Container, QueryWrapper } from './styles';
|
||||||
import { hashCode, parseQuery } from './utils';
|
import { hashCode, parseQuery } from './utils';
|
||||||
@ -32,33 +32,27 @@ function QueryConditionField({
|
|||||||
query,
|
query,
|
||||||
queryIndex,
|
queryIndex,
|
||||||
onUpdate,
|
onUpdate,
|
||||||
style,
|
|
||||||
}: QueryConditionFieldProps): JSX.Element {
|
}: QueryConditionFieldProps): JSX.Element {
|
||||||
|
const allOptions = Object.values(ConditionalOperators);
|
||||||
return (
|
return (
|
||||||
<QueryConditionContainer style={{ ...style }}>
|
<Select
|
||||||
<Select
|
defaultValue={
|
||||||
defaultValue={
|
(query as any).value &&
|
||||||
(query as any).value &&
|
(((query as any)?.value as any) as string).toUpperCase()
|
||||||
(((query as any)?.value as any) as string).toUpperCase()
|
}
|
||||||
}
|
onChange={(e): void => {
|
||||||
onChange={(e): void => {
|
onUpdate({ ...query, value: e }, queryIndex);
|
||||||
onUpdate({ ...query, value: e }, queryIndex);
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{allOptions.map((cond) => (
|
||||||
{Object.values(ConditionalOperators).map((cond) => (
|
<Option key={cond} value={cond} label={cond}>
|
||||||
<Option key={cond} value={cond} label={cond}>
|
{cond}
|
||||||
{cond}
|
</Option>
|
||||||
</Option>
|
))}
|
||||||
))}
|
</Select>
|
||||||
</Select>
|
|
||||||
</QueryConditionContainer>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryConditionField.defaultProps = {
|
|
||||||
style: undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
interface QueryFieldProps {
|
interface QueryFieldProps {
|
||||||
query: Query;
|
query: Query;
|
||||||
queryIndex: number;
|
queryIndex: number;
|
||||||
@ -174,7 +168,6 @@ interface QueryConditionFieldProps {
|
|||||||
query: { value: string | string[]; type: string }[];
|
query: { value: string | string[]; type: string }[];
|
||||||
queryIndex: number;
|
queryIndex: number;
|
||||||
onUpdate: (arg0: unknown, arg1: number) => void;
|
onUpdate: (arg0: unknown, arg1: number) => void;
|
||||||
style?: React.CSSProperties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Query = { value: string | string[]; type: string }[];
|
export type Query = { value: string | string[]; type: string }[];
|
||||||
@ -233,12 +226,13 @@ function QueryBuilder({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QueryConditionField
|
<div key={keyPrefix + idx}>
|
||||||
key={keyPrefix + idx}
|
<QueryConditionField
|
||||||
query={query}
|
query={query}
|
||||||
queryIndex={idx}
|
queryIndex={idx}
|
||||||
onUpdate={handleUpdate as never}
|
onUpdate={handleUpdate as never}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -14,8 +14,3 @@ export const QueryFieldContainer = styled.div`
|
|||||||
background: ${blue[6]};
|
background: ${blue[6]};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const QueryConditionContainer = styled.div`
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
`;
|
|
||||||
|
@ -104,7 +104,8 @@ function SearchFilter({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
handleSearch(urlQueryString || '');
|
handleSearch(urlQueryString || '');
|
||||||
}, [handleSearch, urlQueryString]);
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [urlQueryString, maxTime, minTime]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
|
@ -22,19 +22,28 @@ import { useInterval } from 'react-use';
|
|||||||
import { Dispatch } from 'redux';
|
import { Dispatch } from 'redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import AppActions from 'types/actions';
|
import AppActions from 'types/actions';
|
||||||
import { UPDATE_TIME_INTERVAL } from 'types/actions/globalTime';
|
import {
|
||||||
|
UPDATE_AUTO_REFRESH_INTERVAL,
|
||||||
|
UPDATE_TIME_INTERVAL,
|
||||||
|
} from 'types/actions/globalTime';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
|
|
||||||
import { options } from './config';
|
import { options } from './config';
|
||||||
import { ButtonContainer, Container } from './styles';
|
import { ButtonContainer, Container } from './styles';
|
||||||
|
|
||||||
function AutoRefresh({ disabled = false }: AutoRefreshProps): JSX.Element {
|
function AutoRefresh({ disabled = false }: AutoRefreshProps): JSX.Element {
|
||||||
const { minTime: initialMinTime, selectedTime } = useSelector<
|
const {
|
||||||
AppState,
|
minTime: initialMinTime,
|
||||||
GlobalReducer
|
selectedTime,
|
||||||
>((state) => state.globalTime);
|
isAutoRefreshDisabled,
|
||||||
|
} = useSelector<AppState, GlobalReducer>((state) => state.globalTime);
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
|
const isDisabled = useMemo(() => disabled || isAutoRefreshDisabled, [
|
||||||
|
isAutoRefreshDisabled,
|
||||||
|
disabled,
|
||||||
|
]);
|
||||||
|
|
||||||
const localStorageData = JSON.parse(get(DASHBOARD_TIME_IN_DURATION) || '{}');
|
const localStorageData = JSON.parse(get(DASHBOARD_TIME_IN_DURATION) || '{}');
|
||||||
|
|
||||||
const localStorageValue = useMemo(() => localStorageData[pathname], [
|
const localStorageValue = useMemo(() => localStorageData[pathname], [
|
||||||
@ -46,13 +55,19 @@ function AutoRefresh({ disabled = false }: AutoRefreshProps): JSX.Element {
|
|||||||
Boolean(localStorageValue),
|
Boolean(localStorageValue),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const dispatch = useDispatch<Dispatch<AppActions>>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsAutoRefreshfreshEnabled(Boolean(localStorageValue));
|
const isAutoRefreshEnabled = Boolean(localStorageValue);
|
||||||
}, [localStorageValue]);
|
dispatch({
|
||||||
|
type: UPDATE_AUTO_REFRESH_INTERVAL,
|
||||||
|
payload: localStorageValue,
|
||||||
|
});
|
||||||
|
setIsAutoRefreshfreshEnabled(isAutoRefreshEnabled);
|
||||||
|
}, [localStorageValue, dispatch]);
|
||||||
|
|
||||||
const params = useUrlQuery();
|
const params = useUrlQuery();
|
||||||
|
|
||||||
const dispatch = useDispatch<Dispatch<AppActions>>();
|
|
||||||
const [selectedOption, setSelectedOption] = useState<string>(
|
const [selectedOption, setSelectedOption] = useState<string>(
|
||||||
localStorageValue || options[0].key,
|
localStorageValue || options[0].key,
|
||||||
);
|
);
|
||||||
@ -69,7 +84,7 @@ function AutoRefresh({ disabled = false }: AutoRefreshProps): JSX.Element {
|
|||||||
useInterval(() => {
|
useInterval(() => {
|
||||||
const selectedValue = getOption?.value;
|
const selectedValue = getOption?.value;
|
||||||
|
|
||||||
if (disabled || !isAutoRefreshEnabled) {
|
if (isDisabled || !isAutoRefreshEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,21 +140,23 @@ function AutoRefresh({ disabled = false }: AutoRefreshProps): JSX.Element {
|
|||||||
<Checkbox
|
<Checkbox
|
||||||
onChange={onChangeAutoRefreshHandler}
|
onChange={onChangeAutoRefreshHandler}
|
||||||
checked={isAutoRefreshEnabled}
|
checked={isAutoRefreshEnabled}
|
||||||
disabled={disabled}
|
disabled={isDisabled}
|
||||||
>
|
>
|
||||||
Auto Refresh
|
Auto Refresh
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<Typography.Paragraph>Refresh Interval</Typography.Paragraph>
|
<Typography.Paragraph disabled={isDisabled}>
|
||||||
|
Refresh Interval
|
||||||
|
</Typography.Paragraph>
|
||||||
|
|
||||||
<Radio.Group onChange={onChangeHandler} value={selectedOption}>
|
<Radio.Group onChange={onChangeHandler} value={selectedOption}>
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
{options
|
{options
|
||||||
.filter((e) => e.label !== 'off')
|
.filter((e) => e.label !== 'off')
|
||||||
.map((option) => (
|
.map((option) => (
|
||||||
<Radio key={option.key} value={option.key}>
|
<Radio disabled={isDisabled} key={option.key} value={option.key}>
|
||||||
{option.label}
|
{option.label}
|
||||||
</Radio>
|
</Radio>
|
||||||
))}
|
))}
|
||||||
|
@ -2,6 +2,8 @@ import { getDefaultOption } from 'container/TopNav/DateTimeSelection/config';
|
|||||||
import {
|
import {
|
||||||
GLOBAL_TIME_LOADING_START,
|
GLOBAL_TIME_LOADING_START,
|
||||||
GlobalTimeAction,
|
GlobalTimeAction,
|
||||||
|
UPDATE_AUTO_REFRESH_DISABLED,
|
||||||
|
UPDATE_AUTO_REFRESH_INTERVAL,
|
||||||
UPDATE_TIME_INTERVAL,
|
UPDATE_TIME_INTERVAL,
|
||||||
} from 'types/actions/globalTime';
|
} from 'types/actions/globalTime';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
@ -13,6 +15,8 @@ const intitalState: GlobalReducer = {
|
|||||||
selectedTime: getDefaultOption(
|
selectedTime: getDefaultOption(
|
||||||
typeof window !== 'undefined' ? window?.location?.pathname : '',
|
typeof window !== 'undefined' ? window?.location?.pathname : '',
|
||||||
),
|
),
|
||||||
|
isAutoRefreshDisabled: false,
|
||||||
|
selectedAutoRefreshInterval: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
const globalTimeReducer = (
|
const globalTimeReducer = (
|
||||||
@ -35,6 +39,20 @@ const globalTimeReducer = (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case UPDATE_AUTO_REFRESH_DISABLED: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isAutoRefreshDisabled: action.payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
case UPDATE_AUTO_REFRESH_INTERVAL: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
selectedAutoRefreshInterval: action.payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,6 @@ export const LogsReducer = (
|
|||||||
}${action.payload}`;
|
}${action.payload}`;
|
||||||
|
|
||||||
const updatedParsedQuery = parseQuery(updatedQueryString);
|
const updatedParsedQuery = parseQuery(updatedQueryString);
|
||||||
console.log({ updatedParsedQuery, updatedQueryString, action });
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
searchFilter: {
|
searchFilter: {
|
||||||
|
@ -2,6 +2,8 @@ import { Time } from 'container/TopNav/DateTimeSelection/config';
|
|||||||
|
|
||||||
export const UPDATE_TIME_INTERVAL = 'UPDATE_TIME_INTERVAL';
|
export const UPDATE_TIME_INTERVAL = 'UPDATE_TIME_INTERVAL';
|
||||||
export const GLOBAL_TIME_LOADING_START = 'GLOBAL_TIME_LOADING_START';
|
export const GLOBAL_TIME_LOADING_START = 'GLOBAL_TIME_LOADING_START';
|
||||||
|
export const UPDATE_AUTO_REFRESH_DISABLED = 'UPDATE_AUTO_REFRESH_DISABLED';
|
||||||
|
export const UPDATE_AUTO_REFRESH_INTERVAL = 'UPDATE_AUTO_REFRESH_INTERVAL';
|
||||||
|
|
||||||
export type GlobalTime = {
|
export type GlobalTime = {
|
||||||
maxTime: number;
|
maxTime: number;
|
||||||
@ -17,8 +19,22 @@ interface UpdateTimeInterval {
|
|||||||
payload: UpdateTime;
|
payload: UpdateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface UpdateAutoRefreshDisabled {
|
||||||
|
type: typeof UPDATE_AUTO_REFRESH_DISABLED;
|
||||||
|
payload: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
interface GlobalTimeLoading {
|
interface GlobalTimeLoading {
|
||||||
type: typeof GLOBAL_TIME_LOADING_START;
|
type: typeof GLOBAL_TIME_LOADING_START;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GlobalTimeAction = UpdateTimeInterval | GlobalTimeLoading;
|
interface UpdateAutoRefreshInterval {
|
||||||
|
type: typeof UPDATE_AUTO_REFRESH_INTERVAL;
|
||||||
|
payload: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type GlobalTimeAction =
|
||||||
|
| UpdateTimeInterval
|
||||||
|
| GlobalTimeLoading
|
||||||
|
| UpdateAutoRefreshDisabled
|
||||||
|
| UpdateAutoRefreshInterval;
|
||||||
|
@ -6,4 +6,6 @@ export interface GlobalReducer {
|
|||||||
minTime: GlobalTime['minTime'];
|
minTime: GlobalTime['minTime'];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
selectedTime: Time;
|
selectedTime: Time;
|
||||||
|
isAutoRefreshDisabled: boolean;
|
||||||
|
selectedAutoRefreshInterval: string;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user