+page.svelte 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <script lang="ts">
  2. import * as Resizable from "$lib/components/ui/resizable/index";
  3. import * as Sidebar from "$lib/components/ui/sidebar/index.js";
  4. import { toggleMode } from "mode-watcher";
  5. import { Button } from "$lib/components/ui/button";
  6. import { SunIcon, MoonIcon, Lock } from "@lucide/svelte";
  7. import WorkspaceEntry from "$lib/components/WorkspaceEntry.svelte";
  8. import { state as _state } from "$lib/state.svelte";
  9. import {
  10. listWorkspaces,
  11. loadWorkspace,
  12. selectEntry,
  13. } from "$lib/state.svelte";
  14. import { SlidersHorizontal } from "@lucide/svelte";
  15. import Environment from "$lib/components/Environment.svelte";
  16. import Auth from "$lib/components/Auth.svelte";
  17. import type { Workspace } from "$lib/types";
  18. import { onMount } from "svelte";
  19. import { getSetting } from "$lib/settings.svelte";
  20. import Header from "$lib/components/Header.svelte";
  21. import AppSidebar from "$lib/components/Sidebar.svelte";
  22. let sidePane: Resizable.Pane;
  23. let mainPane: Resizable.Pane;
  24. let displayModal: "env" | "auth" | null = $state(null);
  25. let workspaces: Workspace[] = $state([]);
  26. onMount(async () => {
  27. workspaces = await listWorkspaces();
  28. const lastEntry = await getSetting("lastEntry");
  29. if (lastEntry) {
  30. const ws = workspaces.find((w) => w.id === lastEntry.workspace_id);
  31. if (!ws) {
  32. console.error("workspace for last entry not found", lastEntry);
  33. return;
  34. }
  35. await loadWorkspace(ws);
  36. selectEntry(lastEntry.id);
  37. }
  38. });
  39. </script>
  40. <Resizable.PaneGroup direction="horizontal">
  41. <Resizable.Pane bind:this={sidePane} defaultSize={15}>
  42. <AppSidebar onSelect={() => (displayModal = null)} />
  43. </Resizable.Pane>
  44. <Resizable.Handle
  45. class="p-0.5"
  46. ondblclick={() => {
  47. sidePane.resize(15);
  48. mainPane.resize(85);
  49. }}
  50. />
  51. <Resizable.Pane bind:this={mainPane} defaultSize={85}>
  52. <main class="w-full h-full p-4 space-y-4">
  53. <Header {workspaces} />
  54. {#if displayModal === "env"}
  55. <Environment />
  56. {:else if displayModal === "auth"}
  57. <Auth />
  58. {:else if _state.entry}
  59. <WorkspaceEntry />
  60. {:else}{/if}
  61. </main>
  62. </Resizable.Pane>
  63. </Resizable.PaneGroup>
  64. <Sidebar.Menu class="bg-sidebar rounded-xl p-1 my-2 mr-2 w-fit items-center">
  65. <Sidebar.MenuItem class="pt-2">
  66. <Button onclick={toggleMode} variant="ghost" size="icon-sm">
  67. <SunIcon
  68. class="h-1 w-1 scale-100 rotate-0 transition-all! dark:scale-0 dark:-rotate-90"
  69. />
  70. <MoonIcon
  71. class="absolute h-1 w-1 scale-0 rotate-90 transition-all! dark:scale-100 dark:rotate-0"
  72. />
  73. <span class="sr-only">Toggle theme</span>
  74. </Button>
  75. </Sidebar.MenuItem>
  76. <Sidebar.MenuItem class="pt-2">
  77. <Button
  78. onclick={() => (displayModal = displayModal === "env" ? null : "env")}
  79. variant={displayModal === "env" ? "default" : "ghost"}
  80. size="icon-sm"
  81. >
  82. <SlidersHorizontal />
  83. <span class="sr-only">Display environment</span>
  84. </Button>
  85. </Sidebar.MenuItem>
  86. <Sidebar.MenuItem class="pt-2">
  87. <Button
  88. onclick={() => (displayModal = displayModal === "auth" ? null : "auth")}
  89. variant={displayModal === "auth" ? "default" : "ghost"}
  90. size="icon-sm"
  91. >
  92. <Lock />
  93. <span class="sr-only">Display auth</span>
  94. </Button>
  95. </Sidebar.MenuItem>
  96. </Sidebar.Menu>