mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
Adding time query to dashboard and fixing edge cases
This commit is contained in:
parent
2e5883c684
commit
cf488a7fa8
5 changed files with 185 additions and 43 deletions
3
packages/app/global-setup.js
Normal file
3
packages/app/global-setup.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = async () => {
|
||||
process.env.TZ = 'America/New_York';
|
||||
};
|
||||
|
|
@ -2,7 +2,7 @@ module.exports = {
|
|||
preset: 'ts-jest/presets/js-with-ts',
|
||||
testEnvironment: '@deploysentinel/jest-rtl-debugger/environment',
|
||||
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
|
||||
globalSetup: '@deploysentinel/jest-rtl-debugger/globalSetup',
|
||||
globalSetup: '<rootDir>/global-setup.js',
|
||||
roots: ['<rootDir>/src'],
|
||||
transform: {
|
||||
'^.+\\.tsx?$': 'ts-jest',
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import TabBar from './TabBar';
|
|||
import HDXHistogramChart from './HDXHistogramChart';
|
||||
import api from './api';
|
||||
import { LogTableWithSidePanel } from './LogTableWithSidePanel';
|
||||
import { parseTimeQuery, useTimeQuery } from './timeQuery';
|
||||
import { parseTimeQuery, useNewTimeQuery, useTimeQuery } from './timeQuery';
|
||||
import {
|
||||
EditSearchChartForm,
|
||||
EditMarkdownChartForm,
|
||||
|
|
@ -535,7 +535,7 @@ function DashboardFilter({
|
|||
}
|
||||
|
||||
// TODO: This is a hack to set the default time range
|
||||
const defaultTimeRange = parseTimeQuery('Past 1h', false);
|
||||
const defaultTimeRange = parseTimeQuery('Past 1h', false) as [Date, Date];
|
||||
export default function DashboardPage() {
|
||||
const { data: dashboardsData, isLoading: isDashboardsLoading } =
|
||||
api.useDashboards();
|
||||
|
|
@ -622,19 +622,17 @@ export default function DashboardPage() {
|
|||
|
||||
const [editedChart, setEditedChart] = useState<undefined | Chart>();
|
||||
|
||||
const {
|
||||
searchedTimeRange,
|
||||
displayedTimeInputValue,
|
||||
setDisplayedTimeInputValue,
|
||||
onSearch,
|
||||
} = useTimeQuery({
|
||||
isUTC: false,
|
||||
defaultValue: 'Past 1h',
|
||||
defaultTimeRange: [
|
||||
defaultTimeRange?.[0]?.getTime() ?? -1,
|
||||
defaultTimeRange?.[1]?.getTime() ?? -1,
|
||||
],
|
||||
});
|
||||
const { searchedTimeRange, displayedTimeInputValue, onSearch } =
|
||||
useNewTimeQuery({
|
||||
isUTC: false,
|
||||
initialDisplayValue: 'Past 1h',
|
||||
initialTimeRange: defaultTimeRange,
|
||||
});
|
||||
|
||||
const [input, setInput] = useState<string>(displayedTimeInputValue);
|
||||
useEffect(() => {
|
||||
setInput(displayedTimeInputValue);
|
||||
}, [displayedTimeInputValue]);
|
||||
|
||||
const onAddChart = () => {
|
||||
setEditedChart({
|
||||
|
|
@ -766,13 +764,13 @@ export default function DashboardPage() {
|
|||
className="d-flex align-items-center"
|
||||
onSubmit={e => {
|
||||
e.preventDefault();
|
||||
onSearch(displayedTimeInputValue);
|
||||
onSearch(input);
|
||||
}}
|
||||
style={{ height: 33 }}
|
||||
>
|
||||
<SearchTimeRangePicker
|
||||
inputValue={displayedTimeInputValue}
|
||||
setInputValue={setDisplayedTimeInputValue}
|
||||
inputValue={input}
|
||||
setInputValue={setInput}
|
||||
onSearch={range => {
|
||||
onSearch(range);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -106,7 +106,18 @@ describe('useTimeQuery tests', () => {
|
|||
const timeQueryRef = React.createRef<UseTimeQueryReturnType>();
|
||||
testRouter.replace('/search?tq=Last+4H');
|
||||
|
||||
render(
|
||||
const { rerender } = render(
|
||||
<TestWrapper>
|
||||
<TestComponent
|
||||
isUTC={false}
|
||||
initialTimeRange={getLiveTailTimeRange()}
|
||||
ref={timeQueryRef}
|
||||
/>
|
||||
</TestWrapper>,
|
||||
);
|
||||
jest.runAllTimers();
|
||||
|
||||
rerender(
|
||||
<TestWrapper>
|
||||
<TestComponent
|
||||
isUTC={false}
|
||||
|
|
@ -129,6 +140,125 @@ describe('useTimeQuery tests', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('browser navigation of from/to qparmas updates the searched time range', async () => {
|
||||
const timeQueryRef = React.createRef<UseTimeQueryReturnType>();
|
||||
testRouter.setIsReady(false);
|
||||
testRouter.replace('/search');
|
||||
|
||||
const result = render(
|
||||
<TestWrapper>
|
||||
<TestComponent
|
||||
initialDisplayValue="Past 1h"
|
||||
isUTC={false}
|
||||
initialTimeRange={getLiveTailTimeRange()}
|
||||
ref={timeQueryRef}
|
||||
/>
|
||||
</TestWrapper>,
|
||||
);
|
||||
jest.runAllTimers();
|
||||
|
||||
testRouter.setIsReady(true);
|
||||
|
||||
result.rerender(
|
||||
<TestWrapper>
|
||||
<TestComponent
|
||||
initialDisplayValue="Past 1h"
|
||||
isUTC={false}
|
||||
initialTimeRange={getLiveTailTimeRange()}
|
||||
ref={timeQueryRef}
|
||||
/>
|
||||
</TestWrapper>,
|
||||
);
|
||||
|
||||
expect(timeQueryRef.current?.displayedTimeInputValue).toMatchInlineSnapshot(
|
||||
`"Past 1h"`,
|
||||
);
|
||||
expect(timeQueryRef.current?.searchedTimeRange).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
2023-10-03T15:45:00.000Z,
|
||||
2023-10-03T16:00:00.000Z,
|
||||
]
|
||||
`);
|
||||
|
||||
// 10/03/23 from 04:00am EDT to 08:00am EDT
|
||||
testRouter.replace('/search?from=1696320000000&to=1696334400000');
|
||||
|
||||
result.rerender(
|
||||
<TestWrapper>
|
||||
<TestComponent
|
||||
initialDisplayValue="Past 1h"
|
||||
isUTC={false}
|
||||
initialTimeRange={getLiveTailTimeRange()}
|
||||
ref={timeQueryRef}
|
||||
/>
|
||||
</TestWrapper>,
|
||||
);
|
||||
|
||||
result.rerender(
|
||||
<TestWrapper>
|
||||
<TestComponent
|
||||
initialDisplayValue="Past 1h"
|
||||
isUTC={false}
|
||||
initialTimeRange={getLiveTailTimeRange()}
|
||||
ref={timeQueryRef}
|
||||
/>
|
||||
</TestWrapper>,
|
||||
);
|
||||
|
||||
expect(timeQueryRef.current?.displayedTimeInputValue).toMatchInlineSnapshot(
|
||||
`"Oct 3 04:00:00 - Oct 3 08:00:00"`,
|
||||
);
|
||||
expect(timeQueryRef.current?.searchedTimeRange).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
2023-10-03T08:00:00.000Z,
|
||||
2023-10-03T12:00:00.000Z,
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('overrides initial value with async updated `from` and `to` params', async () => {
|
||||
const timeQueryRef = React.createRef<UseTimeQueryReturnType>();
|
||||
// 10/03/23 from 04:00am EDT to 08:00am EDT
|
||||
testRouter.setIsReady(false);
|
||||
testRouter.replace('/search');
|
||||
|
||||
const result = render(
|
||||
<TestWrapper>
|
||||
<TestComponent
|
||||
initialDisplayValue="Past 1h"
|
||||
isUTC={false}
|
||||
initialTimeRange={getLiveTailTimeRange()}
|
||||
ref={timeQueryRef}
|
||||
/>
|
||||
</TestWrapper>,
|
||||
);
|
||||
jest.runAllTimers();
|
||||
|
||||
testRouter.replace('/search?from=1696320000000&to=1696334400000');
|
||||
testRouter.setIsReady(true);
|
||||
|
||||
result.rerender(
|
||||
<TestWrapper>
|
||||
<TestComponent
|
||||
initialDisplayValue="Past 1h"
|
||||
isUTC={false}
|
||||
initialTimeRange={getLiveTailTimeRange()}
|
||||
ref={timeQueryRef}
|
||||
/>
|
||||
</TestWrapper>,
|
||||
);
|
||||
|
||||
expect(timeQueryRef.current?.displayedTimeInputValue).toMatchInlineSnapshot(
|
||||
`"Oct 3 04:00:00 - Oct 3 08:00:00"`,
|
||||
);
|
||||
expect(timeQueryRef.current?.searchedTimeRange).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
2023-10-03T08:00:00.000Z,
|
||||
2023-10-03T12:00:00.000Z,
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('accepts `from` and `to` url params', async () => {
|
||||
const timeQueryRef = React.createRef<UseTimeQueryReturnType>();
|
||||
// 10/03/23 from 04:00am EDT to 08:00am EDT
|
||||
|
|
@ -178,7 +308,18 @@ describe('useTimeQuery tests', () => {
|
|||
'/search?from=1696320000000&to=1696334400000&tq=Past+1h',
|
||||
);
|
||||
|
||||
render(
|
||||
const result = render(
|
||||
<TestWrapper>
|
||||
<TestComponent
|
||||
isUTC={false}
|
||||
initialTimeRange={getLiveTailTimeRange()}
|
||||
ref={timeQueryRef}
|
||||
/>
|
||||
</TestWrapper>,
|
||||
);
|
||||
jest.runAllTimers();
|
||||
|
||||
result.rerender(
|
||||
<TestWrapper>
|
||||
<TestComponent
|
||||
isUTC={false}
|
||||
|
|
|
|||
|
|
@ -459,45 +459,45 @@ export function useNewTimeQuery({
|
|||
},
|
||||
);
|
||||
|
||||
const initialFrom = useRef(from);
|
||||
const initialTo = useRef(to);
|
||||
const initialInputTimeQuery = useRef(inputTimeQuery);
|
||||
const initializedTimeRange = useRef(false);
|
||||
|
||||
const onSearch = useCallback(
|
||||
(timeQuery: string) => {
|
||||
const [start, end] = parseTimeQuery(timeQuery, isUTC);
|
||||
// TODO: Add validation UI
|
||||
if (start != null && end != null) {
|
||||
setSearchedTimeRange([start, end]);
|
||||
setTimeRangeQuery({ from: start.getTime(), to: end.getTime() });
|
||||
const dateRangeStr = dateRangeToString([start, end], isUTC);
|
||||
setDisplayedTimeInputValue(dateRangeStr);
|
||||
}
|
||||
},
|
||||
[isUTC, setTimeRangeQuery, setDisplayedTimeInputValue],
|
||||
[isUTC, setTimeRangeQuery],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// On mount, we check if there is a `from` and `to` that we should use
|
||||
// and if there isn't an inputTimeQuery
|
||||
if (
|
||||
initialFrom.current &&
|
||||
initialTo.current &&
|
||||
!initialInputTimeQuery.current &&
|
||||
!initializedTimeRange.current
|
||||
) {
|
||||
initializedTimeRange.current = true;
|
||||
const start = new Date(initialFrom.current);
|
||||
const end = new Date(initialTo.current);
|
||||
if (from != null && to != null && inputTimeQuery == null && isReady) {
|
||||
const start = new Date(from);
|
||||
const end = new Date(to);
|
||||
if (isValid(start) && isValid(end)) {
|
||||
setSearchedTimeRange([start, end]);
|
||||
setTimeRangeQuery({ from: start.getTime(), to: end.getTime() });
|
||||
const dateRangeStr = dateRangeToString([start, end], isUTC);
|
||||
setDisplayedTimeInputValue(dateRangeStr);
|
||||
}
|
||||
} else if (
|
||||
from == null &&
|
||||
to == null &&
|
||||
inputTimeQuery == null &&
|
||||
isReady
|
||||
) {
|
||||
setSearchedTimeRange(initialTimeRange);
|
||||
const dateRangeStr = dateRangeToString(initialTimeRange, isUTC);
|
||||
setDisplayedTimeInputValue(initialDisplayValue ?? dateRangeStr);
|
||||
}
|
||||
}, [isUTC, setTimeRangeQuery]);
|
||||
}, [
|
||||
isReady,
|
||||
inputTimeQuery,
|
||||
isUTC,
|
||||
from,
|
||||
to,
|
||||
initialDisplayValue,
|
||||
initialTimeRange,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
// If there is a `tq` param passed in, use it to set the time range and
|
||||
|
|
|
|||
Loading…
Reference in a new issue