|
@@ -1,132 +1,113 @@
|
|
|
<script lang="ts">
|
|
<script lang="ts">
|
|
|
|
|
+ import * as Resizable from "$lib/components/ui/resizable/index";
|
|
|
import * as Sidebar from "$lib/components/ui/sidebar/index.js";
|
|
import * as Sidebar from "$lib/components/ui/sidebar/index.js";
|
|
|
- import AppSidebar from "$lib/components/Sidebar.svelte";
|
|
|
|
|
import { toggleMode } from "mode-watcher";
|
|
import { toggleMode } from "mode-watcher";
|
|
|
import { Button } from "$lib/components/ui/button";
|
|
import { Button } from "$lib/components/ui/button";
|
|
|
import { SunIcon, MoonIcon, Lock } from "@lucide/svelte";
|
|
import { SunIcon, MoonIcon, Lock } from "@lucide/svelte";
|
|
|
import WorkspaceEntry from "$lib/components/WorkspaceEntry.svelte";
|
|
import WorkspaceEntry from "$lib/components/WorkspaceEntry.svelte";
|
|
|
|
|
+ import { state as _state } from "$lib/state.svelte";
|
|
|
import {
|
|
import {
|
|
|
- state as _state,
|
|
|
|
|
- createEnvironment,
|
|
|
|
|
- selectEnvironment,
|
|
|
|
|
|
|
+ listWorkspaces,
|
|
|
|
|
+ loadWorkspace,
|
|
|
|
|
+ selectEntry,
|
|
|
} from "$lib/state.svelte";
|
|
} from "$lib/state.svelte";
|
|
|
import { SlidersHorizontal } from "@lucide/svelte";
|
|
import { SlidersHorizontal } from "@lucide/svelte";
|
|
|
import Environment from "$lib/components/Environment.svelte";
|
|
import Environment from "$lib/components/Environment.svelte";
|
|
|
- import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index";
|
|
|
|
|
import Auth from "$lib/components/Auth.svelte";
|
|
import Auth from "$lib/components/Auth.svelte";
|
|
|
- import { Input } from "$lib/components/ui/input";
|
|
|
|
|
|
|
+ import type { Workspace } from "$lib/types";
|
|
|
|
|
+ import { onMount } from "svelte";
|
|
|
|
|
+ import { getSetting } from "$lib/settings.svelte";
|
|
|
|
|
+ import Header from "$lib/components/Header.svelte";
|
|
|
|
|
+ import AppSidebar from "$lib/components/Sidebar.svelte";
|
|
|
|
|
|
|
|
- let displayModal: "env" | "auth" | null = $state(null);
|
|
|
|
|
- let addEnvInput = $state("");
|
|
|
|
|
-</script>
|
|
|
|
|
|
|
+ let sidePane: Resizable.Pane;
|
|
|
|
|
+ let mainPane: Resizable.Pane;
|
|
|
|
|
|
|
|
-<Sidebar.Provider>
|
|
|
|
|
- <AppSidebar onSelect={() => (displayModal = null)} />
|
|
|
|
|
|
|
+ let displayModal: "env" | "auth" | null = $state(null);
|
|
|
|
|
|
|
|
- <main class="w-full p-4 space-y-4">
|
|
|
|
|
- <header class="flex items-center w-full border-b pb-2">
|
|
|
|
|
- <p class="w-full">{_state.workspace?.name ?? "-"}</p>
|
|
|
|
|
- <p class="text-center mr-2">Environment:</p>
|
|
|
|
|
- <DropdownMenu.Root>
|
|
|
|
|
- <DropdownMenu.Trigger>
|
|
|
|
|
- {#snippet child({ props })}
|
|
|
|
|
- <div class="flex justify-center w-1/8">
|
|
|
|
|
- <!-- Workspace name -->
|
|
|
|
|
- <Sidebar.MenuButton
|
|
|
|
|
- class="flex justify-center"
|
|
|
|
|
- {...props}
|
|
|
|
|
- variant="outline"
|
|
|
|
|
- >
|
|
|
|
|
- {_state.environment?.name || "-"}
|
|
|
|
|
- </Sidebar.MenuButton>
|
|
|
|
|
- </div>
|
|
|
|
|
- {/snippet}
|
|
|
|
|
- </DropdownMenu.Trigger>
|
|
|
|
|
|
|
+ let workspaces: Workspace[] = $state([]);
|
|
|
|
|
|
|
|
- <DropdownMenu.Content align="center">
|
|
|
|
|
- <DropdownMenu.Label>New environment</DropdownMenu.Label>
|
|
|
|
|
- <form
|
|
|
|
|
- class="flex w-full max-w-sm items-center gap-2"
|
|
|
|
|
- onsubmit={(e) => {
|
|
|
|
|
- e.preventDefault();
|
|
|
|
|
- if (addEnvInput.length > 0 && _state.workspace) {
|
|
|
|
|
- createEnvironment(_state.workspace.id, addEnvInput);
|
|
|
|
|
- addEnvInput = "";
|
|
|
|
|
- }
|
|
|
|
|
- }}
|
|
|
|
|
- >
|
|
|
|
|
- <Input
|
|
|
|
|
- type="text"
|
|
|
|
|
- placeholder="My environment"
|
|
|
|
|
- bind:value={addEnvInput}
|
|
|
|
|
- />
|
|
|
|
|
- <Button type="submit" variant="outline">+</Button>
|
|
|
|
|
- </form>
|
|
|
|
|
|
|
+ onMount(async () => {
|
|
|
|
|
+ workspaces = await listWorkspaces();
|
|
|
|
|
+ const lastEntry = await getSetting("lastEntry");
|
|
|
|
|
+ if (lastEntry) {
|
|
|
|
|
+ const ws = workspaces.find((w) => w.id === lastEntry.workspace_id);
|
|
|
|
|
+ if (!ws) {
|
|
|
|
|
+ console.error("workspace for last entry not found", lastEntry);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ await loadWorkspace(ws);
|
|
|
|
|
+ selectEntry(lastEntry.id);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+</script>
|
|
|
|
|
|
|
|
- <DropdownMenu.Separator />
|
|
|
|
|
|
|
+<Sidebar.Provider style="--sidebar-width: 3.5rem">
|
|
|
|
|
+ <div class="w-full">
|
|
|
|
|
+ <Resizable.PaneGroup direction="horizontal">
|
|
|
|
|
+ <Resizable.Pane bind:this={sidePane} defaultSize={15}>
|
|
|
|
|
+ <AppSidebar onSelect={() => (displayModal = null)} />
|
|
|
|
|
+ </Resizable.Pane>
|
|
|
|
|
|
|
|
- <DropdownMenu.Item onSelect={() => selectEnvironment(null)}
|
|
|
|
|
- >- {_state.environment === null ? " ✓" : ""}</DropdownMenu.Item
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <Resizable.Handle
|
|
|
|
|
+ class="p-0.5"
|
|
|
|
|
+ ondblclick={() => {
|
|
|
|
|
+ sidePane.resize(15);
|
|
|
|
|
+ mainPane.resize(85);
|
|
|
|
|
+ }}
|
|
|
|
|
+ />
|
|
|
|
|
|
|
|
- {#each _state.environments as env}
|
|
|
|
|
- <DropdownMenu.Item onSelect={() => selectEnvironment(env.id)}
|
|
|
|
|
- >{env.name}{_state.environment?.id === env.id
|
|
|
|
|
- ? " ✓"
|
|
|
|
|
- : ""}</DropdownMenu.Item
|
|
|
|
|
- >
|
|
|
|
|
- {/each}
|
|
|
|
|
- </DropdownMenu.Content>
|
|
|
|
|
- </DropdownMenu.Root>
|
|
|
|
|
- </header>
|
|
|
|
|
- {#if displayModal === "env"}
|
|
|
|
|
- <Environment />
|
|
|
|
|
- {:else if displayModal === "auth"}
|
|
|
|
|
- <Auth />
|
|
|
|
|
- {:else if _state.entry}
|
|
|
|
|
- <WorkspaceEntry />
|
|
|
|
|
- {:else}{/if}
|
|
|
|
|
- </main>
|
|
|
|
|
|
|
+ <Resizable.Pane bind:this={mainPane} defaultSize={85}>
|
|
|
|
|
+ <main class="w-full h-full p-4 space-y-4">
|
|
|
|
|
+ <Header {workspaces} />
|
|
|
|
|
+ {#if displayModal === "env"}
|
|
|
|
|
+ <Environment />
|
|
|
|
|
+ {:else if displayModal === "auth"}
|
|
|
|
|
+ <Auth />
|
|
|
|
|
+ {:else if _state.entry}
|
|
|
|
|
+ <WorkspaceEntry />
|
|
|
|
|
+ {:else}{/if}
|
|
|
|
|
+ </main>
|
|
|
|
|
+ </Resizable.Pane>
|
|
|
|
|
+ </Resizable.PaneGroup>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
- <Sidebar.Provider style="--sidebar-width: 3.5rem">
|
|
|
|
|
- <Sidebar.Root fixed={false} variant="floating" side="right">
|
|
|
|
|
- <Sidebar.Menu class="items-center">
|
|
|
|
|
- <Sidebar.MenuItem class="pt-2">
|
|
|
|
|
- <Button onclick={toggleMode} variant="ghost" size="icon-sm">
|
|
|
|
|
- <SunIcon
|
|
|
|
|
- class="h-1 w-1 scale-100 rotate-0 transition-all! dark:scale-0 dark:-rotate-90"
|
|
|
|
|
- />
|
|
|
|
|
- <MoonIcon
|
|
|
|
|
- class="absolute h-1 w-1 scale-0 rotate-90 transition-all! dark:scale-100 dark:rotate-0"
|
|
|
|
|
- />
|
|
|
|
|
- <span class="sr-only">Toggle theme</span>
|
|
|
|
|
- </Button>
|
|
|
|
|
- </Sidebar.MenuItem>
|
|
|
|
|
|
|
+ <Sidebar.Root fixed={false} variant="floating" side="right">
|
|
|
|
|
+ <Sidebar.Menu class="items-center">
|
|
|
|
|
+ <Sidebar.MenuItem class="pt-2">
|
|
|
|
|
+ <Button onclick={toggleMode} variant="ghost" size="icon-sm">
|
|
|
|
|
+ <SunIcon
|
|
|
|
|
+ class="h-1 w-1 scale-100 rotate-0 transition-all! dark:scale-0 dark:-rotate-90"
|
|
|
|
|
+ />
|
|
|
|
|
+ <MoonIcon
|
|
|
|
|
+ class="absolute h-1 w-1 scale-0 rotate-90 transition-all! dark:scale-100 dark:rotate-0"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span class="sr-only">Toggle theme</span>
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </Sidebar.MenuItem>
|
|
|
|
|
|
|
|
- <Sidebar.MenuItem class="pt-2">
|
|
|
|
|
- <Button
|
|
|
|
|
- onclick={() =>
|
|
|
|
|
- (displayModal = displayModal === "env" ? null : "env")}
|
|
|
|
|
- variant={displayModal === "env" ? "default" : "ghost"}
|
|
|
|
|
- size="icon-sm"
|
|
|
|
|
- >
|
|
|
|
|
- <SlidersHorizontal />
|
|
|
|
|
- <span class="sr-only">Display environment</span>
|
|
|
|
|
- </Button>
|
|
|
|
|
- </Sidebar.MenuItem>
|
|
|
|
|
|
|
+ <Sidebar.MenuItem class="pt-2">
|
|
|
|
|
+ <Button
|
|
|
|
|
+ onclick={() => (displayModal = displayModal === "env" ? null : "env")}
|
|
|
|
|
+ variant={displayModal === "env" ? "default" : "ghost"}
|
|
|
|
|
+ size="icon-sm"
|
|
|
|
|
+ >
|
|
|
|
|
+ <SlidersHorizontal />
|
|
|
|
|
+ <span class="sr-only">Display environment</span>
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </Sidebar.MenuItem>
|
|
|
|
|
|
|
|
- <Sidebar.MenuItem class="pt-2">
|
|
|
|
|
- <Button
|
|
|
|
|
- onclick={() =>
|
|
|
|
|
- (displayModal = displayModal === "auth" ? null : "auth")}
|
|
|
|
|
- variant={displayModal === "auth" ? "default" : "ghost"}
|
|
|
|
|
- size="icon-sm"
|
|
|
|
|
- >
|
|
|
|
|
- <Lock />
|
|
|
|
|
- <span class="sr-only">Display auth</span>
|
|
|
|
|
- </Button>
|
|
|
|
|
- </Sidebar.MenuItem>
|
|
|
|
|
- </Sidebar.Menu>
|
|
|
|
|
- </Sidebar.Root>
|
|
|
|
|
- </Sidebar.Provider>
|
|
|
|
|
|
|
+ <Sidebar.MenuItem class="pt-2">
|
|
|
|
|
+ <Button
|
|
|
|
|
+ onclick={() =>
|
|
|
|
|
+ (displayModal = displayModal === "auth" ? null : "auth")}
|
|
|
|
|
+ variant={displayModal === "auth" ? "default" : "ghost"}
|
|
|
|
|
+ size="icon-sm"
|
|
|
|
|
+ >
|
|
|
|
|
+ <Lock />
|
|
|
|
|
+ <span class="sr-only">Display auth</span>
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </Sidebar.MenuItem>
|
|
|
|
|
+ </Sidebar.Menu>
|
|
|
|
|
+ </Sidebar.Root>
|
|
|
</Sidebar.Provider>
|
|
</Sidebar.Provider>
|