mirror of
https://github.com/open-webui/open-webui
synced 2025-01-01 08:42:14 +00:00
refac: sidebar styling
This commit is contained in:
parent
24c3f7a664
commit
27d2fbbe33
@ -1,4 +1,4 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { getContext, createEventDispatcher, onMount, onDestroy } from 'svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
@ -7,12 +7,15 @@
|
||||
import ChevronDown from '../icons/ChevronDown.svelte';
|
||||
import ChevronRight from '../icons/ChevronRight.svelte';
|
||||
import Collapsible from './Collapsible.svelte';
|
||||
import Tooltip from './Tooltip.svelte';
|
||||
import Plus from '../icons/Plus.svelte';
|
||||
|
||||
export let open = true;
|
||||
|
||||
export let id = '';
|
||||
export let name = '';
|
||||
export let collapsible = true;
|
||||
export let onCreateFolder: null | Function = null;
|
||||
|
||||
export let className = '';
|
||||
|
||||
@ -113,10 +116,10 @@
|
||||
}}
|
||||
>
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div class="w-full">
|
||||
<button
|
||||
class="w-full py-1.5 px-2 rounded-md flex items-center gap-1.5 text-xs text-gray-500 dark:text-gray-500 font-medium hover:bg-gray-100 dark:hover:bg-gray-900 transition"
|
||||
<div
|
||||
class="w-full group rounded-md relative flex items-center justify-between hover:bg-gray-100 dark:hover:bg-gray-900 text-gray-500 dark:text-gray-500 transition"
|
||||
>
|
||||
<button class="w-full py-1.5 pl-2 flex items-center gap-1.5 text-xs font-medium">
|
||||
<div class="text-gray-300 dark:text-gray-600">
|
||||
{#if open}
|
||||
<ChevronDown className=" size-3" strokeWidth="2.5" />
|
||||
@ -129,6 +132,25 @@
|
||||
{name}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{#if onCreateFolder}
|
||||
<button
|
||||
class="absolute z-10 right-2 self-center flex items-center"
|
||||
on:pointerup={(e) => {
|
||||
e.stopPropagation();
|
||||
onCreateFolder();
|
||||
}}
|
||||
>
|
||||
<Tooltip content={$i18n.t('New folder')}>
|
||||
<button
|
||||
class="p-0.5 dark:hover:bg-gray-850 rounded-lg touch-auto"
|
||||
on:click={(e) => {}}
|
||||
>
|
||||
<Plus className=" size-3" strokeWidth="2.5" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div slot="content" class="w-full">
|
||||
|
@ -519,25 +519,66 @@
|
||||
on:input={searchDebounceHandler}
|
||||
placeholder={$i18n.t('Search')}
|
||||
/>
|
||||
|
||||
<div class="absolute z-40 right-3.5 top-1">
|
||||
<Tooltip content={$i18n.t('New folder')}>
|
||||
<button
|
||||
class="p-1 rounded-lg bg-gray-50 hover:bg-gray-100 dark:bg-gray-950 dark:hover:bg-gray-900 transition"
|
||||
on:click={() => {
|
||||
createFolder();
|
||||
}}
|
||||
>
|
||||
<Plus />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="relative flex flex-col flex-1 overflow-y-auto {$temporaryChatEnabled
|
||||
? 'opacity-20'
|
||||
: ''}"
|
||||
>
|
||||
<Folder
|
||||
collapsible={!search}
|
||||
className="px-2 mt-0.5"
|
||||
name={$i18n.t('Chats')}
|
||||
onCreateFolder={createFolder}
|
||||
on:import={(e) => {
|
||||
importChatHandler(e.detail);
|
||||
}}
|
||||
on:drop={async (e) => {
|
||||
const { type, id, item } = e.detail;
|
||||
|
||||
if (type === 'chat') {
|
||||
let chat = await getChatById(localStorage.token, id).catch((error) => {
|
||||
return null;
|
||||
});
|
||||
if (!chat && item) {
|
||||
chat = await importChat(localStorage.token, item.chat, item?.meta ?? {});
|
||||
}
|
||||
|
||||
if (chat) {
|
||||
console.log(chat);
|
||||
if (chat.folder_id) {
|
||||
const res = await updateChatFolderIdById(localStorage.token, chat.id, null).catch(
|
||||
(error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (chat.pinned) {
|
||||
const res = await toggleChatPinnedStatusById(localStorage.token, chat, id);
|
||||
}
|
||||
|
||||
initChatList();
|
||||
}
|
||||
} else if (type === 'folder') {
|
||||
if (folders[id].parent_id === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await updateFolderParentIdById(localStorage.token, id, null).catch(
|
||||
(error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
if (res) {
|
||||
await initFolders();
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
{#if $temporaryChatEnabled}
|
||||
<div class="absolute z-40 w-full h-full flex justify-center"></div>
|
||||
@ -546,7 +587,7 @@
|
||||
{#if !search && $pinnedChats.length > 0}
|
||||
<div class="flex flex-col space-y-1 rounded-xl">
|
||||
<Folder
|
||||
className="px-2"
|
||||
className="pl-1"
|
||||
bind:open={showPinnedChat}
|
||||
on:change={(e) => {
|
||||
localStorage.setItem('showPinnedChat', e.detail);
|
||||
@ -636,59 +677,6 @@
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<Folder
|
||||
collapsible={!search}
|
||||
className="px-2 mt-0.5"
|
||||
name={$i18n.t('All chats')}
|
||||
on:import={(e) => {
|
||||
importChatHandler(e.detail);
|
||||
}}
|
||||
on:drop={async (e) => {
|
||||
const { type, id, item } = e.detail;
|
||||
|
||||
if (type === 'chat') {
|
||||
let chat = await getChatById(localStorage.token, id).catch((error) => {
|
||||
return null;
|
||||
});
|
||||
if (!chat && item) {
|
||||
chat = await importChat(localStorage.token, item.chat, item?.meta ?? {});
|
||||
}
|
||||
|
||||
if (chat) {
|
||||
console.log(chat);
|
||||
if (chat.folder_id) {
|
||||
const res = await updateChatFolderIdById(localStorage.token, chat.id, null).catch(
|
||||
(error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (chat.pinned) {
|
||||
const res = await toggleChatPinnedStatusById(localStorage.token, chat, id);
|
||||
}
|
||||
|
||||
initChatList();
|
||||
}
|
||||
} else if (type === 'folder') {
|
||||
if (folders[id].parent_id === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await updateFolderParentIdById(localStorage.token, id, null).catch(
|
||||
(error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
if (res) {
|
||||
await initFolders();
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div class="pt-1.5">
|
||||
{#if $chats}
|
||||
{#each $chats as chat, idx}
|
||||
@ -766,8 +754,8 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</Folder>
|
||||
</div>
|
||||
</Folder>
|
||||
</div>
|
||||
|
||||
<div class="px-2">
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
{#each folderList as folderId (folderId)}
|
||||
<RecursiveFolder
|
||||
className="px-2"
|
||||
className="pl-1"
|
||||
{folders}
|
||||
{folderId}
|
||||
on:import={(e) => {
|
||||
|
Loading…
Reference in New Issue
Block a user