fix: refresh buttons use "now" as to-date for queries
All checks were successful
CI / build (push) Successful in 56s
CI / cleanup-branch (push) Has been skipped
CI / docker (push) Successful in 47s
CI / deploy (push) Successful in 41s
CI / deploy-feature (push) Has been skipped

Instead of calling refetch() with stale time params, the refresh
buttons now set a toOverride state to new Date().toISOString(). This
flows into the query key, triggering a fresh fetch with the current
time as the upper bound. Both useApplicationLogs and useAgentEvents
hooks accept an optional toOverride parameter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-25 22:41:00 +01:00
parent 6a24dd01e9
commit d57249906a
4 changed files with 16 additions and 11 deletions

View File

@@ -19,15 +19,16 @@ export function useAgents(status?: string, application?: string) {
});
}
export function useAgentEvents(appId?: string, agentId?: string, limit = 50) {
export function useAgentEvents(appId?: string, agentId?: string, limit = 50, toOverride?: string) {
const refetchInterval = useRefreshInterval(15_000);
return useQuery({
queryKey: ['agents', 'events', appId, agentId, limit],
queryKey: ['agents', 'events', appId, agentId, limit, toOverride],
queryFn: async () => {
const token = useAuthStore.getState().accessToken;
const params = new URLSearchParams();
if (appId) params.set('appId', appId);
if (agentId) params.set('agentId', agentId);
if (toOverride) params.set('to', toOverride);
params.set('limit', String(limit));
const res = await fetch(`${config.apiBaseUrl}/agents/events-log?${params}`, {
headers: {

View File

@@ -16,20 +16,21 @@ export interface LogEntryResponse {
export function useApplicationLogs(
application?: string,
agentId?: string,
options?: { limit?: number },
options?: { limit?: number; toOverride?: string },
) {
const refetchInterval = useRefreshInterval(15_000);
const { timeRange } = useGlobalFilters();
const to = options?.toOverride ?? timeRange.end.toISOString();
return useQuery({
queryKey: ['logs', application, agentId, timeRange.start.toISOString(), timeRange.end.toISOString(), options?.limit],
queryKey: ['logs', application, agentId, timeRange.start.toISOString(), to, options?.limit],
queryFn: async () => {
const token = useAuthStore.getState().accessToken;
const params = new URLSearchParams();
params.set('application', application!);
if (agentId) params.set('agentId', agentId);
params.set('from', timeRange.start.toISOString());
params.set('to', timeRange.end.toISOString());
params.set('to', to);
if (options?.limit) params.set('limit', String(options.limit));
const res = await fetch(`${config.apiBaseUrl}/logs?${params}`, {
headers: {

View File

@@ -223,8 +223,9 @@ function AgentPerformanceContent({ agent }: { agent: AgentInstance }) {
export default function AgentHealth() {
const { appId } = useParams();
const { data: agents } = useAgents(undefined, appId);
const { data: events, refetch: refetchEvents } = useAgentEvents(appId);
const [eventSortAsc, setEventSortAsc] = useState(false);
const [eventRefreshTo, setEventRefreshTo] = useState<string | undefined>();
const { data: events } = useAgentEvents(appId, undefined, 50, eventRefreshTo);
const [selectedInstance, setSelectedInstance] = useState<AgentInstance | null>(null);
const [panelOpen, setPanelOpen] = useState(false);
@@ -509,7 +510,7 @@ export default function AgentHealth() {
<button className={styles.sortBtn} onClick={() => setEventSortAsc((v) => !v)} title={eventSortAsc ? 'Oldest first' : 'Newest first'}>
{eventSortAsc ? '\u2191' : '\u2193'}
</button>
<button className={styles.refreshBtn} onClick={() => refetchEvents()} title="Refresh">
<button className={styles.refreshBtn} onClick={() => setEventRefreshTo(new Date().toISOString())} title="Refresh">
&#x21bb;
</button>
</div>

View File

@@ -35,11 +35,13 @@ export default function AgentInstance() {
const [logLevels, setLogLevels] = useState<Set<string>>(new Set());
const [logSortAsc, setLogSortAsc] = useState(false);
const [eventSortAsc, setEventSortAsc] = useState(false);
const [logRefreshTo, setLogRefreshTo] = useState<string | undefined>();
const [eventRefreshTo, setEventRefreshTo] = useState<string | undefined>();
const timeFrom = timeRange.start.toISOString();
const timeTo = timeRange.end.toISOString();
const { data: agents, isLoading } = useAgents(undefined, appId);
const { data: events, refetch: refetchEvents } = useAgentEvents(appId, instanceId);
const { data: events } = useAgentEvents(appId, instanceId, 50, eventRefreshTo);
const { data: timeseries } = useStatsTimeseries(timeFrom, timeTo, undefined, appId);
const agent = useMemo(
@@ -137,7 +139,7 @@ export default function AgentInstance() {
);
// Application logs from OpenSearch
const { data: rawLogs, refetch: refetchLogs } = useApplicationLogs(appId, instanceId);
const { data: rawLogs } = useApplicationLogs(appId, instanceId, { toOverride: logRefreshTo });
const logEntries = useMemo<LogEntry[]>(() => {
const mapped = (rawLogs || []).map((l) => ({
timestamp: l.timestamp ?? '',
@@ -402,7 +404,7 @@ export default function AgentInstance() {
<button className={styles.sortBtn} onClick={() => setLogSortAsc((v) => !v)} title={logSortAsc ? 'Oldest first' : 'Newest first'}>
{logSortAsc ? '\u2191' : '\u2193'}
</button>
<button className={styles.refreshBtn} onClick={() => refetchLogs()} title="Refresh">
<button className={styles.refreshBtn} onClick={() => setLogRefreshTo(new Date().toISOString())} title="Refresh">
&#x21bb;
</button>
</div>
@@ -452,7 +454,7 @@ export default function AgentInstance() {
<button className={styles.sortBtn} onClick={() => setEventSortAsc((v) => !v)} title={eventSortAsc ? 'Oldest first' : 'Newest first'}>
{eventSortAsc ? '\u2191' : '\u2193'}
</button>
<button className={styles.refreshBtn} onClick={() => refetchEvents()} title="Refresh">
<button className={styles.refreshBtn} onClick={() => setEventRefreshTo(new Date().toISOString())} title="Refresh">
&#x21bb;
</button>
</div>