fix(ui): push log sort toggle server-side

Reversing logStream.items client-side breaks across infinite-scroll
pages. Passing sort='asc'/'desc' into the query key and URL triggers
a fresh first-page fetch in the selected order.
This commit is contained in:
hsiegeln
2026-04-17 13:19:29 +02:00
parent 6d3956935d
commit a2d55f7075
3 changed files with 10 additions and 7 deletions

View File

@@ -165,6 +165,7 @@ export interface UseInfiniteApplicationLogsArgs {
sources?: string[]; // multi-select, server-side OR sources?: string[]; // multi-select, server-side OR
levels?: string[]; // multi-select, server-side OR levels?: string[]; // multi-select, server-side OR
exchangeId?: string; exchangeId?: string;
sort?: 'asc' | 'desc';
isAtTop: boolean; isAtTop: boolean;
pageSize?: number; pageSize?: number;
} }
@@ -189,6 +190,7 @@ export function useInfiniteApplicationLogs(
const sourcesParam = sortedSources.join(','); const sourcesParam = sortedSources.join(',');
const levelsParam = sortedLevels.join(','); const levelsParam = sortedLevels.join(',');
const pageSize = args.pageSize ?? 100; const pageSize = args.pageSize ?? 100;
const sort = args.sort ?? 'desc';
return useInfiniteStream<LogEntryResponse>({ return useInfiniteStream<LogEntryResponse>({
queryKey: [ queryKey: [
@@ -202,6 +204,7 @@ export function useInfiniteApplicationLogs(
fromIso ?? '', fromIso ?? '',
toIso ?? '', toIso ?? '',
pageSize, pageSize,
sort,
], ],
enabled: !!args.application && !!selectedEnv, enabled: !!args.application && !!selectedEnv,
isAtTop: args.isAtTop, isAtTop: args.isAtTop,
@@ -217,7 +220,7 @@ export function useInfiniteApplicationLogs(
if (toIso) qp.set('to', toIso); if (toIso) qp.set('to', toIso);
if (cursor) qp.set('cursor', cursor); if (cursor) qp.set('cursor', cursor);
qp.set('limit', String(pageSize)); qp.set('limit', String(pageSize));
qp.set('sort', 'desc'); qp.set('sort', sort);
const res = await fetch( const res = await fetch(
`${config.apiBaseUrl}/environments/${encodeURIComponent(selectedEnv ?? '')}/logs?${qp}`, `${config.apiBaseUrl}/environments/${encodeURIComponent(selectedEnv ?? '')}/logs?${qp}`,

View File

@@ -312,17 +312,17 @@ export default function AgentHealth() {
application: appId, application: appId,
sources: [...logSources], sources: [...logSources],
levels: [...logLevels], levels: [...logLevels],
sort: logSortAsc ? 'asc' : 'desc',
isAtTop: isLogAtTop, isAtTop: isLogAtTop,
}); });
const logEntries = useMemo<LogEntry[]>(() => { const logEntries = useMemo<LogEntry[]>(() => {
const mapped = logStream.items.map((l) => ({ return logStream.items.map((l) => ({
timestamp: l.timestamp ?? '', timestamp: l.timestamp ?? '',
level: mapLogLevel(l.level), level: mapLogLevel(l.level),
message: l.message ?? '', message: l.message ?? '',
source: l.source ?? undefined, source: l.source ?? undefined,
})); }));
return logSortAsc ? mapped.toReversed() : mapped; }, [logStream.items]);
}, [logStream.items, logSortAsc]);
const logSearchLower = logSearch.toLowerCase(); const logSearchLower = logSearch.toLowerCase();
const filteredLogs = logSearchLower const filteredLogs = logSearchLower
? logEntries.filter((l) => l.message.toLowerCase().includes(logSearchLower)) ? logEntries.filter((l) => l.message.toLowerCase().includes(logSearchLower))

View File

@@ -141,17 +141,17 @@ export default function AgentInstance() {
agentId: instanceId, agentId: instanceId,
sources: [...logSources], sources: [...logSources],
levels: [...logLevels], levels: [...logLevels],
sort: logSortAsc ? 'asc' : 'desc',
isAtTop: isLogAtTop, isAtTop: isLogAtTop,
}); });
const logEntries = useMemo<LogEntry[]>(() => { const logEntries = useMemo<LogEntry[]>(() => {
const mapped = logStream.items.map((l) => ({ return logStream.items.map((l) => ({
timestamp: l.timestamp ?? '', timestamp: l.timestamp ?? '',
level: mapLogLevel(l.level), level: mapLogLevel(l.level),
message: l.message ?? '', message: l.message ?? '',
source: l.source ?? undefined, source: l.source ?? undefined,
})); }));
return logSortAsc ? mapped.toReversed() : mapped; }, [logStream.items]);
}, [logStream.items, logSortAsc]);
const searchLower = logSearch.toLowerCase(); const searchLower = logSearch.toLowerCase();
const filteredLogs = searchLower const filteredLogs = searchLower
? logEntries.filter((l) => l.message.toLowerCase().includes(searchLower)) ? logEntries.filter((l) => l.message.toLowerCase().includes(searchLower))