mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
parent
5a59d32c00
commit
35fe9cfe2d
3 changed files with 32 additions and 23 deletions
5
.changeset/metal-trainers-sniff.md
Normal file
5
.changeset/metal-trainers-sniff.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@hyperdx/app": patch
|
||||
---
|
||||
|
||||
fix default order by generated for advanced table sorting keys
|
||||
|
|
@ -498,16 +498,23 @@ function useSearchedConfigToChartConfig({
|
|||
]);
|
||||
}
|
||||
|
||||
function optimizeOrderBy(
|
||||
function optimizeDefaultOrderBy(
|
||||
timestampExpr: string,
|
||||
orderBy: string,
|
||||
sortingKey: string,
|
||||
sortingKey: string | undefined,
|
||||
) {
|
||||
const defaultModifier = 'DESC';
|
||||
const fallbackOrderByItems = [
|
||||
getFirstTimestampValueExpression(timestampExpr ?? ''),
|
||||
defaultModifier,
|
||||
];
|
||||
const fallbackOrderBy = fallbackOrderByItems.join(' ');
|
||||
if (!sortingKey) return fallbackOrderBy;
|
||||
|
||||
const sortKeys = sortingKey.split(',').map(key => key.trim());
|
||||
const timestampExprIdx = sortKeys.findIndex(v => v === timestampExpr);
|
||||
if (timestampExprIdx <= 0) return orderBy;
|
||||
const orderByArr = [orderBy];
|
||||
if (timestampExprIdx <= 0) return fallbackOrderBy;
|
||||
|
||||
const orderByArr = [fallbackOrderByItems[0]];
|
||||
for (let i = 0; i < timestampExprIdx; i++) {
|
||||
const sortKey = sortKeys[i];
|
||||
if (sortKey.includes('toStartOf') && sortKey.includes(timestampExpr)) {
|
||||
|
|
@ -515,7 +522,7 @@ function optimizeOrderBy(
|
|||
}
|
||||
}
|
||||
|
||||
const newOrderBy = orderByArr.reverse().join(', ');
|
||||
const newOrderBy = `(${orderByArr.reverse().join(', ')}) ${defaultModifier}`;
|
||||
return newOrderBy;
|
||||
}
|
||||
|
||||
|
|
@ -524,17 +531,14 @@ export function useDefaultOrderBy(sourceID: string | undefined | null) {
|
|||
const { data: tableMetadata } = useTableMetadata(tcFromSource(source));
|
||||
|
||||
// When source changes, make sure select and orderby fields are set to default
|
||||
return useMemo(() => {
|
||||
const fallbackOrderBy = `${getFirstTimestampValueExpression(
|
||||
source?.timestampValueExpression ?? '',
|
||||
)} DESC`;
|
||||
if (!tableMetadata) return fallbackOrderBy;
|
||||
return optimizeOrderBy(
|
||||
source?.timestampValueExpression ?? '',
|
||||
fallbackOrderBy,
|
||||
tableMetadata.sorting_key,
|
||||
);
|
||||
}, [source, tableMetadata]);
|
||||
return useMemo(
|
||||
() =>
|
||||
optimizeDefaultOrderBy(
|
||||
source?.timestampValueExpression ?? '',
|
||||
tableMetadata?.sorting_key,
|
||||
),
|
||||
[source, tableMetadata],
|
||||
);
|
||||
}
|
||||
|
||||
// This is outside as it needs to be a stable reference
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ describe('useDefaultOrderBy', () => {
|
|||
|
||||
const { result } = renderHook(() => useDefaultOrderBy('source-id'));
|
||||
|
||||
expect(result.current).toBe('undefined DESC');
|
||||
expect(result.current).toBe(' DESC');
|
||||
});
|
||||
|
||||
it('should return optimized order by when Timestamp is not first in sorting key', () => {
|
||||
|
|
@ -83,7 +83,7 @@ describe('useDefaultOrderBy', () => {
|
|||
|
||||
const { result } = renderHook(() => useDefaultOrderBy('source-id'));
|
||||
|
||||
expect(result.current).toBe('toStartOfHour(Timestamp), Timestamp DESC');
|
||||
expect(result.current).toBe('(toStartOfHour(Timestamp), Timestamp) DESC');
|
||||
});
|
||||
|
||||
it('should return fallback when Timestamp is first in sorting key', () => {
|
||||
|
|
@ -135,7 +135,7 @@ describe('useDefaultOrderBy', () => {
|
|||
|
||||
const { result } = renderHook(() => useDefaultOrderBy('source-id'));
|
||||
|
||||
expect(result.current).toBe('toStartOfHour(Timestamp), Timestamp DESC');
|
||||
expect(result.current).toBe('(toStartOfHour(Timestamp), Timestamp) DESC');
|
||||
});
|
||||
|
||||
it('should handle null source ungracefully', () => {
|
||||
|
|
@ -153,7 +153,7 @@ describe('useDefaultOrderBy', () => {
|
|||
|
||||
const { result } = renderHook(() => useDefaultOrderBy(null));
|
||||
|
||||
expect(result.current).toBe('undefined DESC');
|
||||
expect(result.current).toBe(' DESC');
|
||||
});
|
||||
|
||||
it('should handle undefined sourceID ungracefully', () => {
|
||||
|
|
@ -171,7 +171,7 @@ describe('useDefaultOrderBy', () => {
|
|||
|
||||
const { result } = renderHook(() => useDefaultOrderBy(undefined));
|
||||
|
||||
expect(result.current).toBe('undefined DESC');
|
||||
expect(result.current).toBe(' DESC');
|
||||
});
|
||||
|
||||
it('should handle complex Timestamp expressions', () => {
|
||||
|
|
@ -199,7 +199,7 @@ describe('useDefaultOrderBy', () => {
|
|||
const { result } = renderHook(() => useDefaultOrderBy('source-id'));
|
||||
|
||||
expect(result.current).toBe(
|
||||
'toStartOfHour(toDateTime(timestamp_ms / 1000)), toDateTime(timestamp_ms / 1000) DESC',
|
||||
'(toStartOfHour(toDateTime(timestamp_ms / 1000)), toDateTime(timestamp_ms / 1000)) DESC',
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue