Files
cameleer-server/ui/src/pages/executions/use-execution-search.ts
hsiegeln 50bb22d6f6
All checks were successful
CI / build (push) Successful in 1m8s
CI / docker (push) Successful in 51s
CI / deploy (push) Successful in 29s
Add OIDC logout, fix OpenAPI schema types, expose end_session_endpoint
Backend:
- Expose end_session_endpoint from OIDC provider metadata in /auth/oidc/config
- Add getEndSessionEndpoint() to OidcTokenExchanger

Frontend:
- On OIDC logout, redirect to provider's end_session_endpoint to clear SSO session
- Strip /api/v1 prefix from OpenAPI paths to match client baseUrl convention
- Add schema-types.ts with convenience type re-exports from generated schema
- Fix all type imports to use schema-types instead of raw generated schema
- Fix optional field access (processors, children, duration) with proper typing
- Fix AgentInstance.state → status field name

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 14:43:18 +01:00

108 lines
3.2 KiB
TypeScript

import { create } from 'zustand';
import type { SearchRequest } from '../../api/schema-types';
function todayMidnight(): string {
const d = new Date();
d.setHours(0, 0, 0, 0);
// Format as datetime-local value: YYYY-MM-DDTHH:mm
const pad = (n: number) => n.toString().padStart(2, '0');
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T00:00`;
}
interface ExecutionSearchState {
status: string[];
timeFrom: string;
timeTo: string;
durationMin: number | null;
durationMax: number | null;
text: string;
routeId: string;
agentId: string;
processorType: string;
live: boolean;
offset: number;
limit: number;
toggleLive: () => void;
setStatus: (statuses: string[]) => void;
toggleStatus: (s: string) => void;
setTimeFrom: (v: string) => void;
setTimeTo: (v: string) => void;
setDurationMin: (v: number | null) => void;
setDurationMax: (v: number | null) => void;
setText: (v: string) => void;
setRouteId: (v: string) => void;
setAgentId: (v: string) => void;
setProcessorType: (v: string) => void;
setOffset: (v: number) => void;
clearAll: () => void;
toSearchRequest: () => SearchRequest;
}
export const useExecutionSearch = create<ExecutionSearchState>((set, get) => ({
status: ['COMPLETED', 'FAILED'],
timeFrom: todayMidnight(),
timeTo: '',
durationMin: null,
durationMax: null,
text: '',
routeId: '',
agentId: '',
processorType: '',
live: true,
offset: 0,
limit: 25,
toggleLive: () => set((state) => ({ live: !state.live })),
setStatus: (statuses) => set({ status: statuses, offset: 0 }),
toggleStatus: (s) =>
set((state) => ({
status: state.status.includes(s)
? state.status.filter((x) => x !== s)
: [...state.status, s],
offset: 0,
})),
setTimeFrom: (v) => set({ timeFrom: v, offset: 0 }),
setTimeTo: (v) => set({ timeTo: v, offset: 0 }),
setDurationMin: (v) => set({ durationMin: v, offset: 0 }),
setDurationMax: (v) => set({ durationMax: v, offset: 0 }),
setText: (v) => set({ text: v, offset: 0 }),
setRouteId: (v) => set({ routeId: v, offset: 0 }),
setAgentId: (v) => set({ agentId: v, offset: 0 }),
setProcessorType: (v) => set({ processorType: v, offset: 0 }),
setOffset: (v) => set({ offset: v }),
clearAll: () =>
set({
status: ['COMPLETED', 'FAILED', 'RUNNING'],
timeFrom: todayMidnight(),
timeTo: '',
durationMin: null,
durationMax: null,
text: '',
routeId: '',
agentId: '',
processorType: '',
offset: 0,
}),
toSearchRequest: (): SearchRequest => {
const s = get();
const statusStr = s.status.length > 0 && s.status.length < 3
? s.status.join(',')
: undefined;
return {
status: statusStr ?? undefined,
timeFrom: s.timeFrom ? new Date(s.timeFrom).toISOString() : undefined,
timeTo: s.timeTo ? new Date(s.timeTo).toISOString() : undefined,
durationMin: s.durationMin ?? undefined,
durationMax: s.durationMax ?? undefined,
text: s.text || undefined,
routeId: s.routeId || undefined,
agentId: s.agentId || undefined,
processorType: s.processorType || undefined,
offset: s.offset,
limit: s.limit,
};
},
}));