fix: request logs

This commit is contained in:
2025-12-07 14:16:25 +08:00
parent 9a82ecedac
commit 2a6a3a739c
2 changed files with 36 additions and 20 deletions

View File

@@ -61,7 +61,7 @@ interface RequestDetailsProps {
const RequestDetails: Component<RequestDetailsProps> = (props) => { const RequestDetails: Component<RequestDetailsProps> = (props) => {
return ( return (
<Modal> <Modal>
<ModalContent class="max-w-3xl h-auto max-h-[90vh]"> <ModalContent class="max-w-3xl h-auto max-h-[90vh] flex flex-col">
<CardHeader> <CardHeader>
<h3 class="text-lg font-medium text-gray-900">Request Details</h3> <h3 class="text-lg font-medium text-gray-900">Request Details</h3>
<p class="text-sm text-gray-500"> <p class="text-sm text-gray-500">
@@ -69,7 +69,7 @@ const RequestDetails: Component<RequestDetailsProps> = (props) => {
</p> </p>
</CardHeader> </CardHeader>
<CardContent class="max-h-[70vh] overflow-y-auto"> <CardContent class="flex-1 overflow-y-auto min-h-0">
<div class="grid grid-cols-1 gap-4"> <div class="grid grid-cols-1 gap-4">
<div> <div>
<h4 class="font-semibold mb-2">Request</h4> <h4 class="font-semibold mb-2">Request</h4>

View File

@@ -1,6 +1,7 @@
import { Component, createMemo, createResource, createSignal, For, Show } from "solid-js"; import { Component, createMemo, createResource, createSignal, For, Show } from "solid-js";
import { logsApi } from "../api/client"; import { logsApi } from "../api/client";
import type { RequestLog as RequestLogType } from "../types"; import type { RequestLog as RequestLogType } from "../types";
import { Button } from "./ui/Button";
import { Card } from "./ui/Card"; import { Card } from "./ui/Card";
import { Input } from "./ui/Input"; import { Input } from "./ui/Input";
import { Select } from "./ui/Select"; import { Select } from "./ui/Select";
@@ -8,22 +9,29 @@ import RequestDetails from "./RequestDetails";
const RequestLog: Component = () => { const RequestLog: Component = () => {
const [search, setSearch] = createSignal(""); const [search, setSearch] = createSignal("");
const [inputValue, setInputValue] = createSignal("");
const [method, setMethod] = createSignal(""); const [method, setMethod] = createSignal("");
const [selectedLog, setSelectedLog] = createSignal<RequestLogType | null>(null); const [selectedLog, setSelectedLog] = createSignal<RequestLogType | null>(null);
const [logs] = createResource( let debounceTimer: number;
const handleInput = (e: { currentTarget: { value: string } }) => {
const value = e.currentTarget.value;
setInputValue(value);
clearTimeout(debounceTimer);
debounceTimer = window.setTimeout(() => setSearch(value), 300);
};
const [logs, { refetch: refetchLogs }] = createResource(
() => ({ search: search(), method: method() }), () => ({ search: search(), method: method() }),
async (filters) => { async (filters) => {
// Solid's createResource refetches when the source accessor changes.
// We can add a debounce here if we want to avoid too many requests.
return logsApi.list(filters); return logsApi.list(filters);
}, },
); );
const [allLogs] = createResource(async () => {
return await logsApi.list();
});
const methods = createMemo(() => { const methods = createMemo(() => {
if (!logs()) return []; return allLogs.loading ? [] : [...new Set(allLogs()!.map((log) => log.method))];
const allMethods = logs()!.map((log) => log.method);
return [...new Set(allMethods)];
}); });
const handleLogClick = (log: RequestLogType) => { const handleLogClick = (log: RequestLogType) => {
@@ -41,24 +49,32 @@ const RequestLog: Component = () => {
return ( return (
<> <>
<div class="space-y-4"> <div class="space-y-4">
<h2 class="text-2xl font-semibold">Request Log</h2> <div class="flex items-center justify-between">
<h2 class="text-2xl font-semibold">
Request Log
<Show when={logs() && !logs.loading && !allLogs.loading}>
<span class="text-gray-500 text-base ml-2">
({logs()?.length} of {allLogs()?.length} logs)
</span>
</Show>
</h2>
<Button onClick={() => refetchLogs()} variant="secondary">
Refresh
</Button>
</div>
<Card> <Card>
<div class="p-4 flex items-center space-x-4 bg-gray-50 border-b"> <div class="p-4 flex flex-col sm:flex-row items-center space-y-4 sm:space-x-4 sm:space-y-0 bg-gray-50 border-b">
<div class="flex-1"> <div class="flex-1 w-full">
<Input <Input
type="text" type="text"
placeholder="Search in request/response..." placeholder="Search in request/response..."
value={search()} value={inputValue()}
onInput={(e) => setSearch(e.currentTarget.value)} onInput={handleInput}
/> />
</div> </div>
<div> <div class="w-full sm:w-1/4">
<Select <Select value={method()} onChange={(e) => setMethod(e.currentTarget.value)} class="w-full">
value={method()}
onChange={(e) => setMethod(e.currentTarget.value)}
class="min-w-[200px]"
>
<option value="">All Methods</option> <option value="">All Methods</option>
<For each={methods()}>{(m) => <option value={m}>{m}</option>}</For> <For each={methods()}>{(m) => <option value={m}>{m}</option>}</For>
</Select> </Select>