diff --git a/packages/webui/src/components/ui/QueryParams.test.tsx b/packages/webui/src/components/ui/QueryParams.test.tsx
index d8aab57..1078147 100644
--- a/packages/webui/src/components/ui/QueryParams.test.tsx
+++ b/packages/webui/src/components/ui/QueryParams.test.tsx
@@ -28,21 +28,7 @@ describe('QueryParams', () => {
render(
);
});
- it('should pass `label` "Query params" to KeyValueList component', () => {
- const trace = {} as Trace;
- render(
);
-
- expect(mockKeyValueListComponent).lastCalledWith(expect.objectContaining({ label: 'Query params' }));
- });
-
- it('should pass empty `keyValuePairs` if trace has no query params', () => {
- const trace = {} as Trace;
- render(
);
-
- expect(mockKeyValueListComponent).lastCalledWith(expect.objectContaining({ keyValuePairs: [] }));
- });
-
- it('should pass trace query params as `keyValuePairs`', () => {
+ it('should pass trace query params as `values`', () => {
const trace = {
http: {
path: '/page?foo=bar&baz=qux',
@@ -52,7 +38,7 @@ describe('QueryParams', () => {
expect(mockKeyValueListComponent).lastCalledWith(
expect.objectContaining({
- keyValuePairs: [
+ values: [
['foo', 'bar'],
['baz', 'qux'],
],
diff --git a/packages/webui/src/components/ui/QueryParams.tsx b/packages/webui/src/components/ui/QueryParams.tsx
index 40f5d5b..98e18dd 100644
--- a/packages/webui/src/components/ui/QueryParams.tsx
+++ b/packages/webui/src/components/ui/QueryParams.tsx
@@ -1,14 +1,21 @@
import KeyValueList from '@/components/KeyValueList';
+import Section from '@/components/Section';
import { Trace } from '@/types';
import { pathAndQuery } from '@/utils';
export default function QueryParams({ trace }: { trace: Trace }) {
const [, qs] = pathAndQuery(trace);
+ if (!qs) return null;
+
const urlSearchParams = new URLSearchParams(qs);
- const queryParams: [string, string | null][] = [];
+ const queryParams: [string, string][] = [];
urlSearchParams.forEach((value, key) => {
queryParams.push([key, value]);
});
- return
;
+ return (
+
+ );
}
diff --git a/packages/webui/src/components/ui/RequestHeaders.test.tsx b/packages/webui/src/components/ui/RequestHeaders.test.tsx
index 7d55e59..14a22d0 100644
--- a/packages/webui/src/components/ui/RequestHeaders.test.tsx
+++ b/packages/webui/src/components/ui/RequestHeaders.test.tsx
@@ -36,20 +36,6 @@ describe('RequestHeaders', () => {
expect(container).toBeEmptyDOMElement();
});
- it('should pass `label` "Headers" to KeyValueList component', () => {
- const trace = {
- http: {
- requestHeaders: {
- foo: 'bar',
- baz: 'qux',
- } as Record
,
- },
- } as Trace;
- render();
-
- expect(mockKeyValueListComponent).lastCalledWith(expect.objectContaining({ label: 'Headers' }));
- });
-
it('should pass trace request headers as `keyValuePairs`', () => {
const trace = {
http: {
@@ -63,7 +49,7 @@ describe('RequestHeaders', () => {
expect(mockKeyValueListComponent).lastCalledWith(
expect.objectContaining({
- keyValuePairs: [
+ values: [
['foo', 'bar'],
['baz', 'qux'],
],
@@ -71,7 +57,7 @@ describe('RequestHeaders', () => {
);
});
- it('should pass Authorizatin component for "authorization" header`', () => {
+ it('should pass Authorization component for "authorization" header`', () => {
const trace = {
http: {
requestHeaders: {
@@ -81,7 +67,7 @@ describe('RequestHeaders', () => {
} as Trace;
render();
- const [key, value] = mockKeyValueListComponent.mock.lastCall[0].keyValuePairs[0];
+ const [key, value] = mockKeyValueListComponent.mock.lastCall[0].values[0];
expect(key).toEqual('authorization');
expect(value.type).toEqual(Authorization);
expect(value.props).toEqual({ value: 'some_auth_token' });
diff --git a/packages/webui/src/components/ui/RequestHeaders.tsx b/packages/webui/src/components/ui/RequestHeaders.tsx
index d11363c..a46047e 100644
--- a/packages/webui/src/components/ui/RequestHeaders.tsx
+++ b/packages/webui/src/components/ui/RequestHeaders.tsx
@@ -10,5 +10,5 @@ export default function RequestHeaders({ trace }: { trace: Trace }) {
const headers = cloneHeaders(requestHeaders) as Record;
if (headers.authorization) headers.authorization = ;
- return ;
+ return ;
}
diff --git a/packages/webui/src/components/ui/ResponseHeaders.test.tsx b/packages/webui/src/components/ui/ResponseHeaders.test.tsx
index c40afae..369cfd7 100644
--- a/packages/webui/src/components/ui/ResponseHeaders.test.tsx
+++ b/packages/webui/src/components/ui/ResponseHeaders.test.tsx
@@ -36,20 +36,6 @@ describe('ResponseHeaders', () => {
expect(container).toBeEmptyDOMElement();
});
- it('should pass `label` "Headers" to KeyValueList component', () => {
- const trace = {
- http: {
- responseHeaders: {
- foo: 'bar',
- baz: 'qux',
- } as Record,
- },
- } as Trace;
- render();
-
- expect(mockKeyValueListComponent).lastCalledWith(expect.objectContaining({ label: 'Headers' }));
- });
-
it('should pass trace request headers as `keyValuePairs`', () => {
const trace = {
http: {
@@ -63,7 +49,7 @@ describe('ResponseHeaders', () => {
expect(mockKeyValueListComponent).lastCalledWith(
expect.objectContaining({
- keyValuePairs: [
+ values: [
['foo', 'bar'],
['baz', 'qux'],
],
@@ -71,7 +57,7 @@ describe('ResponseHeaders', () => {
);
});
- it('should pass Authorizatin component for "authorization" header`', () => {
+ it('should pass Authorization component for "authorization" header`', () => {
const trace = {
http: {
responseHeaders: {
@@ -81,7 +67,7 @@ describe('ResponseHeaders', () => {
} as Trace;
render();
- const [key, value] = mockKeyValueListComponent.mock.lastCall[0].keyValuePairs[0];
+ const [key, value] = mockKeyValueListComponent.mock.lastCall[0].values[0];
expect(key).toEqual('authorization');
expect(value.type).toEqual(Authorization);
expect(value.props).toEqual({ value: 'some_auth_token' });
diff --git a/packages/webui/src/components/ui/ResponseHeaders.tsx b/packages/webui/src/components/ui/ResponseHeaders.tsx
index 2b14ec4..8b0eeee 100644
--- a/packages/webui/src/components/ui/ResponseHeaders.tsx
+++ b/packages/webui/src/components/ui/ResponseHeaders.tsx
@@ -10,5 +10,5 @@ export default function ResponseHeaders({ trace }: { trace: Trace }) {
const headers = cloneHeaders(responseHeaders) as Record;
if (headers.authorization) headers.authorization = ;
- return ;
+ return ;
}
diff --git a/packages/webui/src/components/ui/Tabs.tsx b/packages/webui/src/components/ui/Tabs.tsx
index 6186663..7b2a452 100644
--- a/packages/webui/src/components/ui/Tabs.tsx
+++ b/packages/webui/src/components/ui/Tabs.tsx
@@ -3,8 +3,8 @@ import { tw } from '@/utils';
export function TabList({ children }: { children: React.ReactNode }) {
return (
-
-
+
);
}
diff --git a/packages/webui/src/components/ui/TraceDetail.test.tsx b/packages/webui/src/components/ui/TraceDetail.test.tsx
index 022e079..e83c0d8 100644
--- a/packages/webui/src/components/ui/TraceDetail.test.tsx
+++ b/packages/webui/src/components/ui/TraceDetail.test.tsx
@@ -16,6 +16,9 @@ import { Trace } from '@/types';
import TraceDetail from './TraceDetail';
jest.mock('@/components', () => ({
+ Badge: function ({ children }: any) {
+ return <>Mock Badge component: {children}>;
+ },
Code: function ({ children }: any) {
return <>Mock Code component: {children}>;
},
@@ -119,7 +122,7 @@ describe('TraceDetail', () => {
cleanup();
});
- it('should render without error', () => {
+ fit('should render without error', () => {
render(
);
});
diff --git a/packages/webui/src/components/ui/TraceDetail.tsx b/packages/webui/src/components/ui/TraceDetail.tsx
index ae3efe9..e7c9259 100644
--- a/packages/webui/src/components/ui/TraceDetail.tsx
+++ b/packages/webui/src/components/ui/TraceDetail.tsx
@@ -2,7 +2,18 @@ import { HttpRequestState } from '@envyjs/core';
import { X } from 'lucide-react';
import { useCallback, useEffect, useRef } from 'react';
-import { Code, DateTime, Field, Fields, IconButton, JsonDisplay, Loading, Section, XmlDisplay } from '@/components';
+import {
+ Badge,
+ Code,
+ DateTime,
+ Field,
+ Fields,
+ IconButton,
+ JsonDisplay,
+ Loading,
+ Section,
+ XmlDisplay,
+} from '@/components';
import useApplication from '@/hooks/useApplication';
import {
RequestDetailsComponent,
@@ -80,53 +91,39 @@ export default function TraceDetail() {
const [path] = pathAndQuery(trace);
const requestBody = getRequestBody(trace);
const responseBody = getResponseBody(trace);
-
- function statusCodeStyle(code: number) {
- let style = 'bg-transparent';
- if (code >= 500) style = 'bg-purple-500';
- else if (code >= 400) style = 'bg-red-500';
- else if (code >= 300) style = 'bg-yellow-500';
- else if (code >= 200) style = 'bg-green-500';
- else if (code === -1) style = 'bg-gray-500';
- return `inline-block rounded-full h-3 w-3 ${style}`;
- }
+ const httpStatusLabel = `${statusCode && statusCode > -1 ? statusCode : ''} ${statusMessage}`;
return (
-
-
-
-
-
-
-
-
-
-
-
- {method}
-
-
-
- clearSelectedTrace()} data-test-id="close-trace" />
-
-
-
- {url}
-
-
-
- Sent from {serviceName}
-
+
+
+
+
+
+
+
{method}
+ {statusCode && (
+
+ {httpStatusLabel}
+
+ )}
+
{serviceName}
+
+
+
+ clearSelectedTrace()}
+ size="small"
+ border="ghost"
+ data-test-id="close-trace"
+ />
- {responseComplete && statusCode && (
-
-
- {`${statusCode > -1 ? statusCode : ''} ${statusMessage}`}
-
- )}
+
+ {url}
+
@@ -137,7 +134,7 @@ export default function TraceDetail() {
-
+
@@ -148,13 +145,17 @@ export default function TraceDetail() {
{path}
-
-
-
-
+
+
+
+
+
+
{responseComplete && duration ? (
<>
@@ -165,27 +166,10 @@ export default function TraceDetail() {
{statusCode && statusCode > -1 ? statusCode : ''} {statusMessage}
-
+
{numberFormat(duration)}ms
- {trace.http?.timingsBlockedByCors && (
-
-
- Disabled by CORS policy
-
-
- )}
- {trace.http?.timings && (
-
-
-
- )}
>
@@ -196,6 +180,34 @@ export default function TraceDetail() {
)}
+
+ {responseComplete && duration && (
+ <>
+
+
+
+ {trace.http?.timingsBlockedByCors && (
+
+ )}
+ {trace.http?.timings && (
+
+
+
+ )}
+
+ >
+ )}
@@ -215,3 +227,12 @@ export default function TraceDetail() {
);
}
+
+function statusCodeStyle(code: number) {
+ let style = 'bg-gray-500';
+ if (code >= 500) style = 'bg-purple-500';
+ else if (code >= 400) style = 'bg-red-500';
+ else if (code >= 300) style = 'bg-yellow-500';
+ else if (code >= 200) style = 'bg-green-500';
+ return style;
+}
diff --git a/packages/webui/src/components/ui/TraceList.test.tsx b/packages/webui/src/components/ui/TraceList.test.tsx
index 674c95d..950b2d2 100644
--- a/packages/webui/src/components/ui/TraceList.test.tsx
+++ b/packages/webui/src/components/ui/TraceList.test.tsx
@@ -282,7 +282,7 @@ describe('TraceList', () => {
const { getByTestId } = render();
const traceRow = getByTestId('trace');
- const methodData = within(traceRow).getByTestId('column-data-duration');
+ const methodData = within(traceRow).getByTestId('column-data-time');
expect(methodData).toHaveTextContent('Mock Loading component');
});
@@ -301,7 +301,7 @@ describe('TraceList', () => {
const { getByTestId } = render();
const traceRow = getByTestId('trace');
- const methodData = within(traceRow).getByTestId('column-data-duration');
+ const methodData = within(traceRow).getByTestId('column-data-time');
expect(methodData).toHaveTextContent('1.23s');
});
@@ -320,7 +320,7 @@ describe('TraceList', () => {
const { getByTestId } = render();
const traceRow = getByTestId('trace');
- const methodData = within(traceRow).getByTestId('column-data-duration');
+ const methodData = within(traceRow).getByTestId('column-data-time');
expect(methodData).toHaveTextContent('1.24s');
});
diff --git a/packages/webui/src/components/ui/TraceList.tsx b/packages/webui/src/components/ui/TraceList.tsx
index 34cdfb8..4f3cc4d 100644
--- a/packages/webui/src/components/ui/TraceList.tsx
+++ b/packages/webui/src/components/ui/TraceList.tsx
@@ -50,7 +50,7 @@ function getRequestDuration(trace: Trace) {
const columns: [string, (x: Trace) => string | number | React.ReactNode, string, (x: Trace) => string][] = [
['Method', getMethodAndStatus, 'w-[40px] md:w-[125px] overflow-hidden text-center', pillStyle],
['Request', getRequestURI, '', () => 'whitespace-nowrap overflow-hidden overflow-ellipsis'],
- ['Duration', getRequestDuration, 'text-right', () => 'text-sm'],
+ ['Time', getRequestDuration, 'text-right w-[65px]', () => 'text-sm'],
];
type TraceListProps = React.HTMLAttributes & {
diff --git a/packages/webui/src/styles/base.css b/packages/webui/src/styles/base.css
index d8ffec7..3c6c710 100644
--- a/packages/webui/src/styles/base.css
+++ b/packages/webui/src/styles/base.css
@@ -87,7 +87,7 @@ input[type='search']::-webkit-search-results-decoration {
*/
.p-default {
- @apply py-4 px-6;
+ @apply py-4 px-3;
}
.m-default {