File size: 4,792 Bytes
faa93d9 b8228c1 e1f5db2 faa93d9 633622f 7d7a53f faa93d9 21b8785 faa93d9 21b8785 faa93d9 21b8785 e1f5db2 21b8785 33592b9 b8228c1 e1f5db2 b8228c1 33592b9 b8228c1 e1f5db2 b8228c1 e1f5db2 faa93d9 21b8785 faa93d9 33592b9 faa93d9 31daf3d faa93d9 2395552 faa93d9 33592b9 21b8785 33592b9 faa93d9 e1f5db2 b8228c1 e1f5db2 b8228c1 faa93d9 b8228c1 21b8785 b8228c1 21b8785 b8228c1 633622f faa93d9 9a734a8 | 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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | <script lang="ts">
import { base } from "$app/paths";
import { page } from "$app/state";
import { clickOutside } from "$lib/actions/clickOutside";
import { useSettingsStore } from "$lib/stores/settings";
import type { ToolFront } from "$lib/types/Tool";
import IconTool from "./icons/IconTool.svelte";
import CarbonInformation from "~icons/carbon/information";
import CarbonGlobe from "~icons/carbon/earth-filled";
import { usePublicConfig } from "$lib/utils/PublicConfig.svelte";
const publicConfig = usePublicConfig();
interface Props {
loading?: boolean;
}
let { loading = false }: Props = $props();
const settings = useSettingsStore();
let detailsEl: HTMLDetailsElement | undefined = $state();
// active tools are all the checked tools, either from settings or on by default
let activeToolCount = $derived(
page.data.tools.filter(
(tool: ToolFront) =>
// community tools are always on by default
tool.type === "community" || $settings?.tools?.includes(tool._id)
).length
);
async function setAllTools(value: boolean) {
const configToolsIds = page.data.tools
.filter((t: ToolFront) => t.type === "config")
.map((t: ToolFront) => t._id);
if (value) {
await settings.instantSet({
tools: Array.from(new Set([...configToolsIds, ...($settings?.tools ?? [])])),
});
} else {
await settings.instantSet({
tools: [],
});
}
}
let allToolsEnabled = $derived(activeToolCount === page.data.tools.length);
let tools = $derived(page.data.tools);
</script>
<details
class="group relative bottom-0 h-full min-h-8"
bind:this={detailsEl}
use:clickOutside={() => {
if (detailsEl?.hasAttribute("open")) {
detailsEl.removeAttribute("open");
}
}}
>
<summary
class="absolute bottom-0 flex h-8
cursor-pointer select-none items-center gap-1 rounded-lg border bg-white px-2 py-1.5 shadow-sm hover:shadow-none dark:border-gray-800 dark:bg-gray-900"
>
<IconTool classNames="dark:text-purple-600" />
Tools
<span class="text-gray-400 dark:text-gray-500"> ({activeToolCount}) </span>
</summary>
<div
class="absolute bottom-10 h-max w-max select-none items-center gap-1 rounded-lg border bg-white p-0.5 shadow-sm dark:border-gray-800 dark:bg-gray-900"
>
<div class="grid grid-cols-2 gap-x-6 gap-y-1 p-3">
<div class="col-span-2 flex items-center gap-1.5 text-sm text-gray-500">
Available tools
{#if publicConfig.isHuggingChat}
<a
href="https://huggingface.co/spaces/huggingchat/chat-ui/discussions/470"
target="_blank"
class="hover:brightness-0 dark:hover:brightness-200"
><CarbonInformation class="text-xs" /></a
>
{/if}
<button
class="ml-auto text-xs underline"
onclick={(e) => {
e.stopPropagation();
setAllTools(!allToolsEnabled);
}}
>
{#if allToolsEnabled}
Disable all
{:else}
Enable all
{/if}
</button>
</div>
{#if page.data.enableCommunityTools}
<a
href="{base}/tools"
class="col-span-2 my-1 h-fit w-fit items-center justify-center rounded-full bg-purple-500/20 px-2.5 py-1.5 text-sm hover:bg-purple-500/30"
>
<span class="mr-1 rounded-full bg-purple-700 px-1.5 py-1 text-xs font-bold uppercase">
new
</span>
Browse community tools ({page.data.communityToolCount ?? 0})
</a>
{/if}
{#each tools as tool}
{@const isChecked = $settings?.tools?.includes(tool._id)}
<div class="flex items-center gap-1.5">
{#if tool.type === "community"}
<input
type="checkbox"
id={tool._id}
checked={true}
class="rounded-xs font-semibold accent-purple-500 hover:accent-purple-600"
onclick={async (e) => {
e.preventDefault();
e.stopPropagation();
await settings.instantSet({
tools: $settings?.tools?.filter((t) => t !== tool._id) ?? [],
});
}}
/>
{:else}
<input
type="checkbox"
id={tool._id}
checked={isChecked}
disabled={loading}
onclick={async (e) => {
e.preventDefault();
e.stopPropagation();
if (isChecked) {
await settings.instantSet({
tools: ($settings?.tools ?? []).filter((t) => t !== tool._id),
});
} else {
await settings.instantSet({
tools: [...($settings?.tools ?? []), tool._id],
});
}
}}
/>
{/if}
<label class="cursor-pointer" for={tool._id}>{tool.displayName}</label>
{#if tool.type === "community"}
<a href="{base}/tools/{tool._id}" class="text-purple-600 hover:text-purple-700">
<CarbonGlobe />
</a>
{/if}
</div>
{/each}
</div>
</div>
</details>
<style>
details summary::-webkit-details-marker {
display: none;
}
</style>
|