|
|
@@ -10,7 +10,7 @@
|
|
|
import type { EditorView } from "codemirror";
|
|
|
import { onMount } from "svelte";
|
|
|
|
|
|
- let response = $derived(_state.responses[_state.entry!!.id]);
|
|
|
+ let result = $derived(_state.responses[_state.entry!!.id]);
|
|
|
let wrap = $state(ls.WRAP_RESPONSE.get());
|
|
|
|
|
|
let view: EditorView;
|
|
|
@@ -25,15 +25,26 @@
|
|
|
});
|
|
|
|
|
|
$effect(() => {
|
|
|
- if (
|
|
|
- response.body != null &&
|
|
|
- response.body.content !== view.state.doc.toString()
|
|
|
- ) {
|
|
|
- setContent(view, response.body.content, response.body.type);
|
|
|
+ if (result.type === "Err") {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (result.type == "Ok" && result.data.response.body != null) {
|
|
|
+ setContent(
|
|
|
+ view,
|
|
|
+ result.data.response.body.content,
|
|
|
+ result.data.response.body.type,
|
|
|
+ );
|
|
|
}
|
|
|
});
|
|
|
|
|
|
let borderColor = $derived.by(() => {
|
|
|
+ if (result.type === "Err") {
|
|
|
+ return "border-red-900";
|
|
|
+ }
|
|
|
+
|
|
|
+ const response = result.data.response;
|
|
|
+
|
|
|
if (response.status >= 200 && response.status < 300)
|
|
|
return "border-green-900";
|
|
|
if (response.status >= 400 && response.status < 500)
|
|
|
@@ -42,6 +53,12 @@
|
|
|
});
|
|
|
|
|
|
let dotColor = $derived.by(() => {
|
|
|
+ if (result.type === "Err") {
|
|
|
+ return "red";
|
|
|
+ }
|
|
|
+
|
|
|
+ const response = result.data.response;
|
|
|
+
|
|
|
if (response.status >= 200 && response.status < 300) return "green";
|
|
|
if (response.status >= 400 && response.status < 500) return "orange";
|
|
|
if (response.status >= 500) return "red";
|
|
|
@@ -49,21 +66,36 @@
|
|
|
</script>
|
|
|
|
|
|
<Tabs.Root value="body" class="min-h-0">
|
|
|
- <header class="flex items-center w-full py-2 gap-4 border-b">
|
|
|
- <Badge variant="outline" class={`h-4 rounded-sm ${borderColor}`}>
|
|
|
+ <header class="flex items-center w-full py-2 gap-2 border-b">
|
|
|
+ <!-- STATUS BADGE -->
|
|
|
+
|
|
|
+ <Badge variant="outline" class={`rounded-sm ${borderColor}`}>
|
|
|
<Dot strokeWidth={5} color={dotColor} />
|
|
|
- {response.status}
|
|
|
+ {#if result.type === "Ok"}
|
|
|
+ {result.data.response.status}
|
|
|
+ {:else}
|
|
|
+ ERROR
|
|
|
+ {/if}
|
|
|
+ </Badge>
|
|
|
+
|
|
|
+ <Badge variant="outline" class={`rounded-sm`}>
|
|
|
+ {result.data.duration}ms
|
|
|
</Badge>
|
|
|
|
|
|
- <Tabs.List class="h-6">
|
|
|
- <Tabs.Trigger class="text-xs" value="body">Body</Tabs.Trigger>
|
|
|
- <Tabs.Trigger class="text-xs" value="headers">Headers</Tabs.Trigger>
|
|
|
- </Tabs.List>
|
|
|
+ {#if result.type === "Ok"}
|
|
|
+ <Tabs.List>
|
|
|
+ <Tabs.Trigger class="text-xs" value="body">Body</Tabs.Trigger>
|
|
|
+ <Tabs.Trigger class="text-xs" value="headers">Headers</Tabs.Trigger>
|
|
|
+ </Tabs.List>
|
|
|
+
|
|
|
+ <!-- RESPONSE UTILS -->
|
|
|
|
|
|
- <Tabs.Content value="body" class="flex items-center">
|
|
|
- <div class="flex items-center gap-1">
|
|
|
+ <Tabs.Content
|
|
|
+ value="body"
|
|
|
+ class="flex justify-end w-full items-center gap-1"
|
|
|
+ >
|
|
|
<Button
|
|
|
- class="h-6 p-1"
|
|
|
+ class="p-1"
|
|
|
variant={wrap ? "default" : "outline"}
|
|
|
onclick={handleToggleWrap}
|
|
|
size="icon-sm"
|
|
|
@@ -71,73 +103,32 @@
|
|
|
<TextWrap />
|
|
|
</Button>
|
|
|
<Button
|
|
|
- class="h-6 p-1"
|
|
|
+ class="p-1"
|
|
|
onclick={() => copyContent(view)}
|
|
|
variant="outline"
|
|
|
size="icon-sm"
|
|
|
>
|
|
|
<Clipboard />
|
|
|
</Button>
|
|
|
- </div>
|
|
|
- </Tabs.Content>
|
|
|
+ </Tabs.Content>
|
|
|
+ {/if}
|
|
|
</header>
|
|
|
|
|
|
- <Tabs.Content value="body" class="flex-1 min-h-0 overflow-auto">
|
|
|
- {#if response.body != null}
|
|
|
- <!-- EDITOR -->
|
|
|
-
|
|
|
- <div id="response-view"></div>
|
|
|
+ <Tabs.Content value="body" class="overflow-scroll h-[90%]">
|
|
|
+ {#if result.type === "Err"}
|
|
|
+ {result.data.message}
|
|
|
{/if}
|
|
|
+ <div id="response-view" class:hidden={result.type === "Err"}></div>
|
|
|
</Tabs.Content>
|
|
|
|
|
|
- <Tabs.Content value="headers" class="flex-1 overflow-auto">
|
|
|
- <div class="grid grid-cols-2" id="header-tab">
|
|
|
- {#each response.headers as [name, value]}
|
|
|
- <p>{name}</p>
|
|
|
- <p class="wrap-anywhere">{value}</p>
|
|
|
- {/each}
|
|
|
- </div>
|
|
|
- </Tabs.Content>
|
|
|
+ {#if result.type === "Ok"}
|
|
|
+ <Tabs.Content value="headers" class="flex-1">
|
|
|
+ <div class="grid grid-cols-2">
|
|
|
+ {#each result.data.response.headers as [name, value]}
|
|
|
+ <p>{name}</p>
|
|
|
+ <p class="wrap-anywhere">{value}</p>
|
|
|
+ {/each}
|
|
|
+ </div>
|
|
|
+ </Tabs.Content>
|
|
|
+ {/if}
|
|
|
</Tabs.Root>
|
|
|
-
|
|
|
-<style>
|
|
|
- #header-tab {
|
|
|
- padding-bottom: 8rem;
|
|
|
- }
|
|
|
-
|
|
|
- @media (min-height: 400px) {
|
|
|
- #header-tab {
|
|
|
- padding-bottom: 7rem;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @media (min-height: 600px) {
|
|
|
- #header-tab {
|
|
|
- padding-bottom: 6rem;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @media (min-height: 800px) {
|
|
|
- #header-tab {
|
|
|
- padding-bottom: 5rem;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @media (min-height: 900px) {
|
|
|
- #header-tab {
|
|
|
- padding-bottom: 4rem;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @media (min-height: 1000px) {
|
|
|
- #header-tab {
|
|
|
- padding-bottom: 3rem;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @media (min-height: 1200px) {
|
|
|
- #header-tab {
|
|
|
- padding-bottom: 2rem;
|
|
|
- }
|
|
|
- }
|
|
|
-</style>
|