mirror of
https://github.com/open-webui/open-webui
synced 2025-05-21 13:36:35 +00:00
refac: folder
This commit is contained in:
parent
73a251fc49
commit
b01f9e8ec3
@ -1,4 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { getContext, createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
$: dispatch('change', open);
|
||||||
|
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
import { quintOut } from 'svelte/easing';
|
import { quintOut } from 'svelte/easing';
|
||||||
|
|
||||||
|
56
src/lib/components/common/Folder.svelte
Normal file
56
src/lib/components/common/Folder.svelte
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<script>
|
||||||
|
import { getContext, createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
|
const i18n = getContext('i18n');
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
import ChevronDown from '../icons/ChevronDown.svelte';
|
||||||
|
import ChevronRight from '../icons/ChevronRight.svelte';
|
||||||
|
import Collapsible from './Collapsible.svelte';
|
||||||
|
|
||||||
|
export let open = true;
|
||||||
|
export let name = '';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Collapsible
|
||||||
|
bind:open
|
||||||
|
className="w-full"
|
||||||
|
buttonClassName="w-full"
|
||||||
|
on:change={(e) => {
|
||||||
|
dispatch('change', e.detail);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
|
<div
|
||||||
|
class="mx-2 w-full"
|
||||||
|
on:dragenter={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
on:drop={(e) => {
|
||||||
|
console.log('Dropped on the Button');
|
||||||
|
}}
|
||||||
|
on:dragleave={(e) => {}}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="w-full py-1 px-1.5 rounded-md flex items-center gap-1 text-xs text-gray-500 dark:text-gray-500 font-medium hover:bg-gray-100 dark:hover:bg-gray-900 transition"
|
||||||
|
>
|
||||||
|
<div class="text-gray-300">
|
||||||
|
{#if open}
|
||||||
|
<ChevronDown className=" size-3" strokeWidth="2.5" />
|
||||||
|
{:else}
|
||||||
|
<ChevronRight className=" size-3" strokeWidth="2.5" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="translate-y-[0.5px]">
|
||||||
|
{name}
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div slot="content">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</Collapsible>
|
||||||
|
</div>
|
@ -53,6 +53,7 @@
|
|||||||
import ChevronUp from '../icons/ChevronUp.svelte';
|
import ChevronUp from '../icons/ChevronUp.svelte';
|
||||||
import ChevronRight from '../icons/ChevronRight.svelte';
|
import ChevronRight from '../icons/ChevronRight.svelte';
|
||||||
import Collapsible from '../common/Collapsible.svelte';
|
import Collapsible from '../common/Collapsible.svelte';
|
||||||
|
import Folder from '../common/Folder.svelte';
|
||||||
|
|
||||||
const BREAKPOINT = 768;
|
const BREAKPOINT = 768;
|
||||||
|
|
||||||
@ -517,61 +518,42 @@
|
|||||||
|
|
||||||
{#if !search && $pinnedChats.length > 0}
|
{#if !search && $pinnedChats.length > 0}
|
||||||
<div class=" pb-2 flex flex-col space-y-1">
|
<div class=" pb-2 flex flex-col space-y-1">
|
||||||
<div class="">
|
<Folder
|
||||||
<Collapsible className="w-full" buttonClassName="w-full">
|
bind:open={showPinnedChat}
|
||||||
<div class="px-2 w-full">
|
on:change={(e) => {
|
||||||
<button
|
localStorage.setItem('showPinnedChat', e.detail);
|
||||||
class="w-full py-1 px-1.5 rounded-md flex items-center gap-1 text-xs text-gray-500 dark:text-gray-500 font-medium hover:bg-gray-100 dark:hover:bg-gray-900 transition"
|
console.log(e.detail);
|
||||||
on:click={() => {
|
}}
|
||||||
showPinnedChat = !showPinnedChat;
|
name={$i18n.t('Pinned')}
|
||||||
localStorage.setItem('showPinnedChat', showPinnedChat);
|
>
|
||||||
|
<div class="pl-2 mt-1 flex flex-col overflow-y-auto scrollbar-hidden">
|
||||||
|
{#each $pinnedChats as chat, idx}
|
||||||
|
<ChatItem
|
||||||
|
{chat}
|
||||||
|
{shiftKey}
|
||||||
|
selected={selectedChatId === chat.id}
|
||||||
|
on:select={() => {
|
||||||
|
selectedChatId = chat.id;
|
||||||
}}
|
}}
|
||||||
>
|
on:unselect={() => {
|
||||||
<div class="text-gray-300">
|
selectedChatId = null;
|
||||||
{#if showPinnedChat}
|
}}
|
||||||
<ChevronDown className=" size-3" strokeWidth="2.5" />
|
on:delete={(e) => {
|
||||||
{:else}
|
if ((e?.detail ?? '') === 'shift') {
|
||||||
<ChevronRight className=" text-gra size-3" strokeWidth="2.5" />
|
deleteChatHandler(chat.id);
|
||||||
{/if}
|
} else {
|
||||||
</div>
|
deleteChat = chat;
|
||||||
|
showDeleteConfirm = true;
|
||||||
<div class=" translate-y-[0.5px]">
|
}
|
||||||
{$i18n.t('Pinned')}
|
}}
|
||||||
</div>
|
on:tag={(e) => {
|
||||||
</button>
|
const { type, name } = e.detail;
|
||||||
</div>
|
tagEventHandler(type, name, chat.id);
|
||||||
|
}}
|
||||||
<div slot="content">
|
/>
|
||||||
<div class="pl-2 mt-1 flex flex-col overflow-y-auto scrollbar-hidden">
|
{/each}
|
||||||
{#each $pinnedChats as chat, idx}
|
</div>
|
||||||
<ChatItem
|
</Folder>
|
||||||
{chat}
|
|
||||||
{shiftKey}
|
|
||||||
selected={selectedChatId === chat.id}
|
|
||||||
on:select={() => {
|
|
||||||
selectedChatId = chat.id;
|
|
||||||
}}
|
|
||||||
on:unselect={() => {
|
|
||||||
selectedChatId = null;
|
|
||||||
}}
|
|
||||||
on:delete={(e) => {
|
|
||||||
if ((e?.detail ?? '') === 'shift') {
|
|
||||||
deleteChatHandler(chat.id);
|
|
||||||
} else {
|
|
||||||
deleteChat = chat;
|
|
||||||
showDeleteConfirm = true;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
on:tag={(e) => {
|
|
||||||
const { type, name } = e.detail;
|
|
||||||
tagEventHandler(type, name, chat.id);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Collapsible>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
@ -98,10 +98,10 @@
|
|||||||
let y = 0;
|
let y = 0;
|
||||||
|
|
||||||
const dragImage = new Image();
|
const dragImage = new Image();
|
||||||
dragImage.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';
|
dragImage.src =
|
||||||
|
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
|
||||||
|
|
||||||
const onDragStart = (event) => {
|
const onDragStart = (event) => {
|
||||||
console.log('Dragging started:', event.target);
|
|
||||||
event.dataTransfer.setDragImage(dragImage, 0, 0);
|
event.dataTransfer.setDragImage(dragImage, 0, 0);
|
||||||
|
|
||||||
drag = true;
|
drag = true;
|
||||||
@ -114,7 +114,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onDragEnd = (event) => {
|
const onDragEnd = (event) => {
|
||||||
console.log('Dragging ended:', event.target);
|
|
||||||
drag = false;
|
drag = false;
|
||||||
itemElement.style.opacity = '1'; // Reset visual cue after drag
|
itemElement.style.opacity = '1'; // Reset visual cue after drag
|
||||||
};
|
};
|
||||||
@ -143,9 +142,9 @@
|
|||||||
|
|
||||||
{#if drag && x && y}
|
{#if drag && x && y}
|
||||||
<DragGhost {x} {y}>
|
<DragGhost {x} {y}>
|
||||||
<div class=" bg-black/50 backdrop-blur-2xl px-2 py-1 rounded-lg">
|
<div class=" bg-black/80 backdrop-blur-2xl px-2 py-1 rounded-lg">
|
||||||
<div>
|
<div>
|
||||||
<div class=" text-xs text-gray-500">
|
<div class=" text-xs text-white">
|
||||||
{chat.title}
|
{chat.title}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -51,10 +51,6 @@
|
|||||||
const chatSearch = document.getElementById('chat-search');
|
const chatSearch = document.getElementById('chat-search');
|
||||||
|
|
||||||
if (!searchContainer.contains(e.target) && !chatSearch.contains(e.target)) {
|
if (!searchContainer.contains(e.target) && !chatSearch.contains(e.target)) {
|
||||||
console.log(
|
|
||||||
e.target.id,
|
|
||||||
e.target.id.startsWith('search-tag-') || e.target.id.startsWith('search-option-')
|
|
||||||
);
|
|
||||||
if (e.target.id.startsWith('search-tag-') || e.target.id.startsWith('search-option-')) {
|
if (e.target.id.startsWith('search-tag-') || e.target.id.startsWith('search-option-')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user