enh: load tool by url

This commit is contained in:
Timothy Jaeryang Baek
2025-05-29 02:08:54 +04:00
parent 4461122a0e
commit 85a384fab5
6 changed files with 244 additions and 12 deletions
+41 -6
View File
@@ -10,6 +10,7 @@
import { goto } from '$app/navigation';
import {
createNewTool,
loadToolByUrl,
deleteToolById,
exportTools,
getToolById,
@@ -32,6 +33,8 @@
import Spinner from '../common/Spinner.svelte';
import { capitalizeFirstLetter } from '$lib/utils';
import XMark from '../icons/XMark.svelte';
import AddToolMenu from './Tools/AddToolMenu.svelte';
import ImportModal from '../ImportModal.svelte';
const i18n = getContext('i18n');
@@ -53,6 +56,8 @@
let tools = [];
let filteredItems = [];
let showImportModal = false;
$: filteredItems = tools.filter((t) => {
if (query === '') return true;
const lowerQuery = query.toLowerCase();
@@ -173,6 +178,19 @@
</title>
</svelte:head>
<ImportModal
bind:show={showImportModal}
onImport={(tool) => {
sessionStorage.tool = JSON.stringify({
...tool
});
goto('/workspace/tools/create');
}}
loadUrlHandler={async (url) => {
return await loadToolByUrl(localStorage.token, url);
}}
/>
{#if loaded}
<div class="flex flex-col gap-1 my-1.5">
<div class="flex justify-between items-center">
@@ -210,12 +228,29 @@
</div>
<div>
<a
class=" px-2 py-2 rounded-xl hover:bg-gray-700/10 dark:hover:bg-gray-100/10 dark:text-gray-300 dark:hover:text-white transition font-medium text-sm flex items-center space-x-1"
href="/workspace/tools/create"
>
<Plus className="size-3.5" />
</a>
{#if $user?.role === 'admin'}
<AddToolMenu
createHandler={() => {
goto('/workspace/tools/create');
}}
importFromLinkHandler={() => {
showImportModal = true;
}}
>
<div
class=" px-2 py-2 rounded-xl hover:bg-gray-700/10 dark:hover:bg-gray-100/10 dark:text-gray-300 dark:hover:text-white transition font-medium text-sm flex items-center space-x-1"
>
<Plus className="size-3.5" />
</div>
</AddToolMenu>
{:else}
<a
class=" px-2 py-2 rounded-xl hover:bg-gray-700/10 dark:hover:bg-gray-100/10 dark:text-gray-300 dark:hover:text-white transition font-medium text-sm flex items-center space-x-1"
href="/workspace/tools/create"
>
<Plus className="size-3.5" />
</a>
{/if}
</div>
</div>
</div>
@@ -0,0 +1,77 @@
<script lang="ts">
import { DropdownMenu } from 'bits-ui';
import { flyAndScale } from '$lib/utils/transitions';
import { getContext } from 'svelte';
import Dropdown from '$lib/components/common/Dropdown.svelte';
import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
import Tooltip from '$lib/components/common/Tooltip.svelte';
import Share from '$lib/components/icons/Share.svelte';
import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
import Switch from '$lib/components/common/Switch.svelte';
import GlobeAlt from '$lib/components/icons/GlobeAlt.svelte';
import Github from '$lib/components/icons/Github.svelte';
import Plus from '$lib/components/icons/Plus.svelte';
import Pencil from '$lib/components/icons/Pencil.svelte';
import PencilSolid from '$lib/components/icons/PencilSolid.svelte';
import Link from '$lib/components/icons/Link.svelte';
const i18n = getContext('i18n');
export let createHandler: Function;
export let importFromLinkHandler: Function;
export let onClose: Function = () => {};
let show = false;
</script>
<Dropdown
bind:show
on:change={(e) => {
if (e.detail === false) {
onClose();
}
}}
>
<Tooltip content={$i18n.t('Create')}>
<slot />
</Tooltip>
<div slot="content">
<DropdownMenu.Content
class="w-full max-w-[190px] text-sm rounded-xl px-1 py-1.5 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg font-primary"
sideOffset={-2}
side="bottom"
align="start"
transition={flyAndScale}
>
<button
class="flex rounded-md py-1.5 px-3 w-full hover:bg-gray-50 dark:hover:bg-gray-800 transition"
on:click={async () => {
createHandler();
show = false;
}}
>
<div class=" self-center mr-2">
<PencilSolid />
</div>
<div class=" self-center truncate">{$i18n.t('New Tool')}</div>
</button>
<button
class="flex rounded-md py-1.5 px-3 w-full hover:bg-gray-50 dark:hover:bg-gray-800 transition"
on:click={async () => {
importFromLinkHandler();
show = false;
}}
>
<div class=" self-center mr-2">
<Link />
</div>
<div class=" self-center truncate">{$i18n.t('Import From Link')}</div>
</button>
</DropdownMenu.Content>
</div>
</Dropdown>