Spaces:
Runtime error
Runtime error
File size: 3,868 Bytes
654f56a 9b4caaa 3df1e9f af10150 7450ebd 64cfbce aac02fe b2170a7 b1426d3 f77d645 7450ebd 6a8491a af10150 6a8491a 9b4caaa 654f56a af10150 9b4caaa af10150 9b4caaa af10150 654f56a aac02fe 53e0cfa 9b4caaa aac02fe 654f56a aac02fe 654f56a af10150 654f56a aac02fe 654f56a 9b4caaa 654f56a 64cfbce 654f56a f77d645 cf47645 7450ebd cf47645 aac02fe 654f56a af10150 9b4caaa af10150 7450ebd af10150 6a8491a aac02fe 6a8491a 7450ebd aac02fe af10150 aac02fe 11e0dcc aac02fe af10150 aac02fe 6a8491a af10150 aac02fe 654f56a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
<script lang="ts">
import { session } from "$lib/state/session.svelte.js";
import { cn } from "$lib/utils/cn.js";
import { Select } from "melt/builders";
import IconHistory from "~icons/carbon/recently-viewed";
import IconCaret from "~icons/carbon/chevron-down";
import IconCross from "~icons/carbon/close";
import IconEdit from "~icons/carbon/edit";
import IconSave from "~icons/carbon/save";
import IconDelete from "~icons/carbon/trash-can";
import { prompt } from "../prompts.svelte";
import Tooltip from "../tooltip.svelte";
import CheckpointsMenu from "./checkpoints-menu.svelte";
import { checkpoints } from "$lib/state/checkpoints.svelte";
interface Props {
class?: string;
}
let { class: classNames = "" }: Props = $props();
const isDefault = $derived(session.$.activeProjectId === "default");
const select = new Select({
value: () => session.$.activeProjectId,
onValueChange(v) {
if (v) session.$.activeProjectId = v;
},
sameWidth: true,
});
async function saveProject() {
session.saveProject((await prompt("Set project name")) || "Project #" + (session.$.projects.length + 1));
}
</script>
<div class={cn("flex w-full items-stretch gap-2 ", classNames)}>
<button
{...select.trigger}
class={cn(
"relative flex grow items-center justify-between gap-6 overflow-hidden rounded-lg border bg-gray-100/80 px-3 py-1.5 leading-tight whitespace-nowrap shadow-sm",
"hover:brightness-95 dark:border-gray-700 dark:bg-gray-800 dark:hover:brightness-110"
)}
>
<div class="flex items-center gap-1 text-sm">
{session.project.name}
</div>
<div
class="absolute right-2 grid size-4 flex-none place-items-center rounded-sm bg-gray-100 text-xs dark:bg-gray-600"
>
<IconCaret />
</div>
</button>
<div class="flex items-center gap-2">
<CheckpointsMenu />
{#if isDefault}
<Tooltip>
{#snippet trigger(tooltip)}
<button class="btn size-[32px] p-0" {...tooltip.trigger} onclick={saveProject}>
<IconSave />
</button>
{/snippet}
Save to Project
</Tooltip>
{:else}
<Tooltip>
{#snippet trigger(tooltip)}
<button
class="btn size-[32px] p-0"
{...tooltip.trigger}
onclick={() => (session.$.activeProjectId = "default")}
>
<IconCross />
</button>
{/snippet}
Close project
</Tooltip>
{/if}
</div>
</div>
<div {...select.content} class="rounded-lg border bg-gray-100 dark:border-gray-700 dark:bg-gray-800">
{#each session.$.projects as { name, id } (id)}
{@const option = select.getOption(id)}
{@const hasCheckpoints = checkpoints.for(id).length > 0}
<div {...option} class="group block w-full p-1 text-sm dark:text-white">
<div
class="flex items-center gap-2 rounded-md py-1.5 pr-1 pl-2 group-data-[highlighted]:bg-gray-200 dark:group-data-[highlighted]:bg-gray-700"
>
<div class="flex items-center gap-2">
{name}
{#if hasCheckpoints}
<div
class="text-3xs grid aspect-square place-items-center rounded bg-yellow-400/25 p-0.5 text-yellow-400"
aria-label="Project has checkpoints"
>
<IconHistory />
</div>
{/if}
</div>
{#if id !== "default"}
<div class="ml-auto flex items-center gap-1">
<button
class="grid place-items-center rounded-md p-1 text-xs hover:bg-gray-300 dark:hover:bg-gray-600"
onclick={async e => {
e.stopPropagation();
session.updateProject(id, { name: (await prompt("Edit project name", name)) || name });
}}
>
<IconEdit />
</button>
<button
class="grid place-items-center rounded-md p-1 text-xs hover:bg-gray-300 dark:hover:bg-gray-600"
onclick={e => {
e.stopPropagation();
session.deleteProject(id);
}}
>
<IconDelete />
</button>
</div>
{/if}
</div>
</div>
{/each}
</div>
|