|
@@ -15,17 +15,15 @@
|
|
|
} from "$lib/state.svelte";
|
|
} from "$lib/state.svelte";
|
|
|
import { Button } from "$lib/components/ui/button";
|
|
import { Button } from "$lib/components/ui/button";
|
|
|
import { Input } from "$lib/components/ui/input";
|
|
import { Input } from "$lib/components/ui/input";
|
|
|
- import * as Accordion from "$lib/components/ui/accordion";
|
|
|
|
|
import * as Tabs from "$lib/components/ui/tabs";
|
|
import * as Tabs from "$lib/components/ui/tabs";
|
|
|
- import type { UrlError } from "$lib/types";
|
|
|
|
|
|
|
+ import type { UrlError, WorkspaceEntry } from "$lib/types";
|
|
|
import Editable from "./Editable.svelte";
|
|
import Editable from "./Editable.svelte";
|
|
|
import Highlight, { LineNumbers } from "svelte-highlight";
|
|
import Highlight, { LineNumbers } from "svelte-highlight";
|
|
|
import json from "svelte-highlight/languages/json";
|
|
import json from "svelte-highlight/languages/json";
|
|
|
import { atelierForest } from "svelte-highlight/styles";
|
|
import { atelierForest } from "svelte-highlight/styles";
|
|
|
- import { Loader, PlusIcon, TrashIcon } from "@lucide/svelte";
|
|
|
|
|
|
|
+ import { Loader, PlusIcon, Trash } from "@lucide/svelte";
|
|
|
import CodeMirror from "./CodeMirror.svelte";
|
|
import CodeMirror from "./CodeMirror.svelte";
|
|
|
import * as Resizable from "$lib/components/ui/resizable/index";
|
|
import * as Resizable from "$lib/components/ui/resizable/index";
|
|
|
- import Auth from "./Auth.svelte";
|
|
|
|
|
import AuthParams from "./AuthParams.svelte";
|
|
import AuthParams from "./AuthParams.svelte";
|
|
|
import Checkbox from "./ui/checkbox/checkbox.svelte";
|
|
import Checkbox from "./ui/checkbox/checkbox.svelte";
|
|
|
|
|
|
|
@@ -34,12 +32,36 @@
|
|
|
let isSending = $state(false);
|
|
let isSending = $state(false);
|
|
|
let response: any = $state();
|
|
let response: any = $state();
|
|
|
|
|
|
|
|
|
|
+ const parentAuth = $derived.by(() => {
|
|
|
|
|
+ let parentId = _state.entry!!.parent_id;
|
|
|
|
|
+
|
|
|
|
|
+ while (parentId != null) {
|
|
|
|
|
+ const parent = _state.indexes[parentId];
|
|
|
|
|
+
|
|
|
|
|
+ if (!parent) {
|
|
|
|
|
+ console.warn("Parent index is null", parentId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (parent.auth_inherit) {
|
|
|
|
|
+ parentId = parent.id;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (parent.auth == null) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return _state.auth.find((a) => a.id === parent.auth) ?? null;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
const referenceChain = $derived.by(() => {
|
|
const referenceChain = $derived.by(() => {
|
|
|
const parents = [];
|
|
const parents = [];
|
|
|
|
|
|
|
|
let parent = _state.entry!!.parent_id;
|
|
let parent = _state.entry!!.parent_id;
|
|
|
|
|
|
|
|
- while (parent !== null) {
|
|
|
|
|
|
|
+ while (parent != null) {
|
|
|
parents.push(_state.indexes[parent]);
|
|
parents.push(_state.indexes[parent]);
|
|
|
parent = _state.indexes[parent].parent_id;
|
|
parent = _state.indexes[parent].parent_id;
|
|
|
}
|
|
}
|
|
@@ -126,14 +148,6 @@
|
|
|
|
|
|
|
|
return url;
|
|
return url;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- function resolveAuthName() {
|
|
|
|
|
- if (_state.entry.auth !== null) {
|
|
|
|
|
- return _state.auth.find((a) => a.id === _state.entry.auth).name;
|
|
|
|
|
- } else {
|
|
|
|
|
- return "None";
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<svelte:head>
|
|
<svelte:head>
|
|
@@ -144,10 +158,14 @@
|
|
|
<!-- ENTRY PATH -->
|
|
<!-- ENTRY PATH -->
|
|
|
<div class="h-8 flex items-center">
|
|
<div class="h-8 flex items-center">
|
|
|
{#each referenceChain as ref}
|
|
{#each referenceChain as ref}
|
|
|
- <Button onclick={() => selectEntry(ref.id)} variant="ghost">
|
|
|
|
|
|
|
+ <Button
|
|
|
|
|
+ class="p-0 h-fit cursor-pointer"
|
|
|
|
|
+ onclick={() => selectEntry(ref.id)}
|
|
|
|
|
+ variant="ghost"
|
|
|
|
|
+ >
|
|
|
{ref.name || ref.type + "(" + ref.id + ")"}
|
|
{ref.name || ref.type + "(" + ref.id + ")"}
|
|
|
</Button>
|
|
</Button>
|
|
|
- <p>/</p>
|
|
|
|
|
|
|
+ <p class="pl-1 pr-1">/</p>
|
|
|
{/each}
|
|
{/each}
|
|
|
<Editable
|
|
<Editable
|
|
|
bind:value={_state.entry!!.name}
|
|
bind:value={_state.entry!!.name}
|
|
@@ -164,28 +182,72 @@
|
|
|
</div>
|
|
</div>
|
|
|
{/snippet}
|
|
{/snippet}
|
|
|
|
|
|
|
|
-{#if _state.entry?.type === "Collection"}
|
|
|
|
|
- <!-- COLLECTION VIEW -->
|
|
|
|
|
|
|
+{#snippet authParams(
|
|
|
|
|
+ entry: WorkspaceEntry & { auth: number | null; auth_inherit: boolean },
|
|
|
|
|
+)}
|
|
|
|
|
+ <div class="w-full p-4 pl-2">
|
|
|
|
|
+ <Select.Root
|
|
|
|
|
+ type="single"
|
|
|
|
|
+ value={entry.auth_inherit ? "inherit" : (entry.auth?.toString() ?? "-")}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Select.Trigger class="w-64">
|
|
|
|
|
+ {#if entry.auth != null && !entry.auth_inherit}
|
|
|
|
|
+ {_state.auth.find((a) => a.id === entry.auth)?.name}
|
|
|
|
|
+ {:else if entry.auth_inherit}
|
|
|
|
|
+ Inherit ({parentAuth?.name})
|
|
|
|
|
+ {:else}
|
|
|
|
|
+ -
|
|
|
|
|
+ {/if}
|
|
|
|
|
+ </Select.Trigger>
|
|
|
|
|
|
|
|
- {@render entryPath()}
|
|
|
|
|
- <section class="space-y-4">
|
|
|
|
|
- <h1 class="text-xl font-semibold">{_state.entry.name}</h1>
|
|
|
|
|
|
|
+ <Select.Content>
|
|
|
|
|
+ <Select.Item onclick={() => setEntryAuth(null, false)} value="-">
|
|
|
|
|
+ -
|
|
|
|
|
+ </Select.Item>
|
|
|
|
|
|
|
|
- <div class="rounded-md p-4 space-y-2">
|
|
|
|
|
- <h2 class="font-medium">Variables</h2>
|
|
|
|
|
|
|
+ {#if entry.parent_id != null}
|
|
|
|
|
+ <Select.Item onclick={() => setEntryAuth(null, true)} value="inherit">
|
|
|
|
|
+ Inherit ({parentAuth?.name})
|
|
|
|
|
+ </Select.Item>
|
|
|
|
|
+ {/if}
|
|
|
|
|
|
|
|
- <div class="grid grid-cols-3 gap-2 text-sm">
|
|
|
|
|
- <div class="font-medium text-muted-foreground">Key</div>
|
|
|
|
|
- <div class="font-medium text-muted-foreground col-span-2">Value</div>
|
|
|
|
|
|
|
+ <Select.Separator />
|
|
|
|
|
|
|
|
- <div>baseUrl</div>
|
|
|
|
|
- <div class="col-span-2">https://api.example.com</div>
|
|
|
|
|
|
|
+ {#each _state.auth as auth}
|
|
|
|
|
+ <Select.Item
|
|
|
|
|
+ onclick={() => setEntryAuth(auth.id, false)}
|
|
|
|
|
+ value={auth.id.toString()}
|
|
|
|
|
+ >
|
|
|
|
|
+ {auth.name}
|
|
|
|
|
+ </Select.Item>
|
|
|
|
|
+ {/each}
|
|
|
|
|
+ </Select.Content>
|
|
|
|
|
+ </Select.Root>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
- <div>token</div>
|
|
|
|
|
- <div class="col-span-2">••••••••</div>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ {#if entry.auth_inherit && parentAuth}
|
|
|
|
|
+ <div class="opacity-75 p-4">
|
|
|
|
|
+ <AuthParams auth={parentAuth} readonly={true} />
|
|
|
</div>
|
|
</div>
|
|
|
- </section>
|
|
|
|
|
|
|
+ {:else if entry.auth}
|
|
|
|
|
+ <div class="opacity-75 p-4">
|
|
|
|
|
+ <AuthParams
|
|
|
|
|
+ auth={_state.auth.find((a) => a.id === entry.auth)!!}
|
|
|
|
|
+ readonly={true}
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ {/if}
|
|
|
|
|
+{/snippet}
|
|
|
|
|
+
|
|
|
|
|
+{#if _state.entry?.type === "Collection"}
|
|
|
|
|
+ <!-- COLLECTION VIEW -->
|
|
|
|
|
+
|
|
|
|
|
+ {@render entryPath()}
|
|
|
|
|
+
|
|
|
|
|
+ <div class="flex flex-wrap p-2 border">
|
|
|
|
|
+ <h2 class="pb-2 w-full border-b">Auth</h2>
|
|
|
|
|
+ {@render authParams(_state.entry!!)}
|
|
|
|
|
+ </div>
|
|
|
{:else if _state.entry?.type === "Request"}
|
|
{:else if _state.entry?.type === "Request"}
|
|
|
<!-- REQUEST WORK AREA -->
|
|
<!-- REQUEST WORK AREA -->
|
|
|
|
|
|
|
@@ -301,7 +363,7 @@
|
|
|
updateHeader(header.id, header.name, header.value)}
|
|
updateHeader(header.id, header.name, header.value)}
|
|
|
/>
|
|
/>
|
|
|
|
|
|
|
|
- <TrashIcon
|
|
|
|
|
|
|
+ <Trash
|
|
|
class="h-4 w-4 cursor-pointer text-muted-foreground hover:text-destructive"
|
|
class="h-4 w-4 cursor-pointer text-muted-foreground hover:text-destructive"
|
|
|
onclick={() => deleteHeader(header.id)}
|
|
onclick={() => deleteHeader(header.id)}
|
|
|
/>
|
|
/>
|
|
@@ -358,49 +420,10 @@
|
|
|
</Tabs.Root>
|
|
</Tabs.Root>
|
|
|
</Tabs.Content>
|
|
</Tabs.Content>
|
|
|
|
|
|
|
|
- <Tabs.Content value="auth" class="space-y-4">
|
|
|
|
|
- <div class="flex items-center">
|
|
|
|
|
- <p class="mr-2">Inherit</p>
|
|
|
|
|
- <Checkbox
|
|
|
|
|
- checked={_state.entry.auth_inherit}
|
|
|
|
|
- onCheckedChange={(v) => setEntryAuth(_state.entry.auth, v)}
|
|
|
|
|
- />
|
|
|
|
|
- </div>
|
|
|
|
|
- <div
|
|
|
|
|
- class="transition-opacity"
|
|
|
|
|
- class:opacity-50={_state.entry.auth_inherit}
|
|
|
|
|
- class:pointer-events-none={_state.entry.auth_inherit}
|
|
|
|
|
- >
|
|
|
|
|
- <Select.Root type="single" value={resolveAuthName()}>
|
|
|
|
|
- <Select.Trigger class="w-64">
|
|
|
|
|
- {resolveAuthName()}
|
|
|
|
|
- </Select.Trigger>
|
|
|
|
|
-
|
|
|
|
|
- <Select.Content>
|
|
|
|
|
- <Select.Item
|
|
|
|
|
- onclick={() => setEntryAuth(null, null)}
|
|
|
|
|
- value={"None"}
|
|
|
|
|
- >
|
|
|
|
|
- None
|
|
|
|
|
- </Select.Item>
|
|
|
|
|
- {#each _state.auth as auth}
|
|
|
|
|
- <Select.Item
|
|
|
|
|
- onclick={() => setEntryAuth(auth.id, null)}
|
|
|
|
|
- value={auth.name}
|
|
|
|
|
- >
|
|
|
|
|
- {auth.name}
|
|
|
|
|
- </Select.Item>
|
|
|
|
|
- {/each}
|
|
|
|
|
- </Select.Content>
|
|
|
|
|
- </Select.Root>
|
|
|
|
|
|
|
+ <!-- ================= AUTH ================= -->
|
|
|
|
|
|
|
|
- {#if _state.entry.auth}
|
|
|
|
|
- <AuthParams
|
|
|
|
|
- auth={_state.auth.find((a) => a.id === _state.entry.auth)!!}
|
|
|
|
|
- readonly={true}
|
|
|
|
|
- />
|
|
|
|
|
- {/if}
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <Tabs.Content value="auth" class="space-y-4">
|
|
|
|
|
+ {@render authParams(_state.entry!!)}
|
|
|
</Tabs.Content>
|
|
</Tabs.Content>
|
|
|
</div>
|
|
</div>
|
|
|
</Tabs.Root>
|
|
</Tabs.Root>
|