mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-12 04:15:25 +00:00
refac
This commit is contained in:
parent
3ed0a6d11f
commit
eadec9e86e
6 changed files with 397 additions and 305 deletions
|
|
@ -1,13 +1,12 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { DropdownMenu } from 'bits-ui';
|
import { DropdownMenu } from 'bits-ui';
|
||||||
import { flyAndScale } from '$lib/utils/transitions';
|
|
||||||
import { getContext, onMount, tick } from 'svelte';
|
import { getContext, onMount, tick } from 'svelte';
|
||||||
|
import { fly } from 'svelte/transition';
|
||||||
|
import { flyAndScale } from '$lib/utils/transitions';
|
||||||
|
|
||||||
import { config, user, tools as _tools, mobile, knowledge, chats } from '$lib/stores';
|
import { config, user, tools as _tools, mobile, knowledge, chats } from '$lib/stores';
|
||||||
import { createPicker } from '$lib/utils/google-drive-picker';
|
import { createPicker } from '$lib/utils/google-drive-picker';
|
||||||
|
|
||||||
import { getTools } from '$lib/apis/tools';
|
|
||||||
|
|
||||||
import Dropdown from '$lib/components/common/Dropdown.svelte';
|
import Dropdown from '$lib/components/common/Dropdown.svelte';
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
import DocumentArrowUp from '$lib/components/icons/DocumentArrowUp.svelte';
|
import DocumentArrowUp from '$lib/components/icons/DocumentArrowUp.svelte';
|
||||||
|
|
@ -19,6 +18,12 @@
|
||||||
import Agile from '$lib/components/icons/Agile.svelte';
|
import Agile from '$lib/components/icons/Agile.svelte';
|
||||||
import ClockRotateRight from '$lib/components/icons/ClockRotateRight.svelte';
|
import ClockRotateRight from '$lib/components/icons/ClockRotateRight.svelte';
|
||||||
import Database from '$lib/components/icons/Database.svelte';
|
import Database from '$lib/components/icons/Database.svelte';
|
||||||
|
import ChevronRight from '$lib/components/icons/ChevronRight.svelte';
|
||||||
|
import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte';
|
||||||
|
import PageEdit from '$lib/components/icons/PageEdit.svelte';
|
||||||
|
import Chats from './InputMenu/Chats.svelte';
|
||||||
|
import Notes from './InputMenu/Notes.svelte';
|
||||||
|
import Knowledge from './InputMenu/Knowledge.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
|
|
@ -37,6 +42,7 @@
|
||||||
export let onClose: Function;
|
export let onClose: Function;
|
||||||
|
|
||||||
let show = false;
|
let show = false;
|
||||||
|
let tab = '';
|
||||||
|
|
||||||
let fileUploadEnabled = true;
|
let fileUploadEnabled = true;
|
||||||
$: fileUploadEnabled =
|
$: fileUploadEnabled =
|
||||||
|
|
@ -81,13 +87,15 @@
|
||||||
|
|
||||||
<div slot="content">
|
<div slot="content">
|
||||||
<DropdownMenu.Content
|
<DropdownMenu.Content
|
||||||
class="w-full max-w-[240px] rounded-2xl px-1 py-1 border border-gray-100 dark:border-gray-800 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg transition"
|
class="w-full max-w-[240px] rounded-2xl px-1 py-1 border border-gray-100 dark:border-gray-800 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg max-h-72 overflow-y-auto overflow-x-hidden scrollbar-thin transition"
|
||||||
sideOffset={4}
|
sideOffset={4}
|
||||||
alignOffset={-6}
|
alignOffset={-6}
|
||||||
side="bottom"
|
side="bottom"
|
||||||
align="start"
|
align="start"
|
||||||
transition={flyAndScale}
|
transition={flyAndScale}
|
||||||
>
|
>
|
||||||
|
{#if tab === ''}
|
||||||
|
<div in:fly={{ x: -20, duration: 150 }}>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content={fileUploadCapableModels.length !== selectedModels.length
|
content={fileUploadCapableModels.length !== selectedModels.length
|
||||||
? $i18n.t('Model(s) do not support file upload')
|
? $i18n.t('Model(s) do not support file upload')
|
||||||
|
|
@ -152,27 +160,26 @@
|
||||||
: ''}
|
: ''}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
<DropdownMenu.Item
|
<button
|
||||||
class="flex gap-2 items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled
|
class="flex gap-2 w-full items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled
|
||||||
? 'opacity-50'
|
? 'opacity-50'
|
||||||
: ''}"
|
: ''}"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
if (fileUploadEnabled) {
|
tab = 'notes';
|
||||||
if (!detectMobile()) {
|
|
||||||
screenCaptureHandler();
|
|
||||||
} else {
|
|
||||||
const cameraInputElement = document.getElementById('camera-input');
|
|
||||||
|
|
||||||
if (cameraInputElement) {
|
|
||||||
cameraInputElement.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Note />
|
<PageEdit />
|
||||||
<div class=" line-clamp-1">{$i18n.t('Attach Notes')}</div>
|
|
||||||
</DropdownMenu.Item>
|
<div class="flex items-center w-full justify-between">
|
||||||
|
<div class=" line-clamp-1">
|
||||||
|
{$i18n.t('Attach Notes')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-gray-500">
|
||||||
|
<ChevronRight />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
@ -184,27 +191,26 @@
|
||||||
: ''}
|
: ''}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
<DropdownMenu.Item
|
<button
|
||||||
class="flex gap-2 items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled
|
class="flex gap-2 w-full items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled
|
||||||
? 'opacity-50'
|
? 'opacity-50'
|
||||||
: ''}"
|
: ''}"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
if (fileUploadEnabled) {
|
tab = 'knowledge';
|
||||||
if (!detectMobile()) {
|
|
||||||
screenCaptureHandler();
|
|
||||||
} else {
|
|
||||||
const cameraInputElement = document.getElementById('camera-input');
|
|
||||||
|
|
||||||
if (cameraInputElement) {
|
|
||||||
cameraInputElement.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Database />
|
<Database />
|
||||||
<div class=" line-clamp-1">{$i18n.t('Attach Knowledge')}</div>
|
|
||||||
</DropdownMenu.Item>
|
<div class="flex items-center w-full justify-between">
|
||||||
|
<div class=" line-clamp-1">
|
||||||
|
{$i18n.t('Attach Knowledge')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-gray-500">
|
||||||
|
<ChevronRight />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
{#if ($chats ?? []).length > 0}
|
{#if ($chats ?? []).length > 0}
|
||||||
|
|
@ -216,27 +222,26 @@
|
||||||
: ''}
|
: ''}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
<DropdownMenu.Item
|
<button
|
||||||
class="flex gap-2 items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled
|
class="flex gap-2 w-full items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled
|
||||||
? 'opacity-50'
|
? 'opacity-50'
|
||||||
: ''}"
|
: ''}"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
if (fileUploadEnabled) {
|
tab = 'chats';
|
||||||
if (!detectMobile()) {
|
|
||||||
screenCaptureHandler();
|
|
||||||
} else {
|
|
||||||
const cameraInputElement = document.getElementById('camera-input');
|
|
||||||
|
|
||||||
if (cameraInputElement) {
|
|
||||||
cameraInputElement.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ClockRotateRight />
|
<ClockRotateRight />
|
||||||
<div class=" line-clamp-1">{$i18n.t('Reference Chats')}</div>
|
|
||||||
</DropdownMenu.Item>
|
<div class="flex items-center w-full justify-between">
|
||||||
|
<div class=" line-clamp-1">
|
||||||
|
{$i18n.t('Reference Chats')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-gray-500">
|
||||||
|
<ChevronRight />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
@ -399,6 +404,65 @@
|
||||||
</DropdownMenu.Sub>
|
</DropdownMenu.Sub>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
|
{:else if tab === 'knowledge'}
|
||||||
|
<div in:fly={{ x: 20, duration: 150 }}>
|
||||||
|
<button
|
||||||
|
class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800"
|
||||||
|
on:click={() => {
|
||||||
|
tab = '';
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ChevronLeft />
|
||||||
|
|
||||||
|
<div class="flex items-center w-full justify-between">
|
||||||
|
<div>
|
||||||
|
{$i18n.t('Knowledge')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Knowledge />
|
||||||
|
</div>
|
||||||
|
{:else if tab === 'notes'}
|
||||||
|
<div in:fly={{ x: 20, duration: 150 }}>
|
||||||
|
<button
|
||||||
|
class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800"
|
||||||
|
on:click={() => {
|
||||||
|
tab = '';
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ChevronLeft />
|
||||||
|
|
||||||
|
<div class="flex items-center w-full justify-between">
|
||||||
|
<div>
|
||||||
|
{$i18n.t('Notes')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Notes />
|
||||||
|
</div>
|
||||||
|
{:else if tab === 'chats'}
|
||||||
|
<div in:fly={{ x: 20, duration: 150 }}>
|
||||||
|
<button
|
||||||
|
class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800"
|
||||||
|
on:click={() => {
|
||||||
|
tab = '';
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ChevronLeft />
|
||||||
|
|
||||||
|
<div class="flex items-center w-full justify-between">
|
||||||
|
<div>
|
||||||
|
{$i18n.t('Chats')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Chats />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</DropdownMenu.Content>
|
</DropdownMenu.Content>
|
||||||
</div>
|
</div>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { DropdownMenu } from 'bits-ui';
|
import { DropdownMenu } from 'bits-ui';
|
||||||
import { flyAndScale } from '$lib/utils/transitions';
|
|
||||||
import { getContext, onMount, tick } from 'svelte';
|
import { getContext, onMount, tick } from 'svelte';
|
||||||
|
import { fly } from 'svelte/transition';
|
||||||
|
import { flyAndScale } from '$lib/utils/transitions';
|
||||||
|
|
||||||
import { config, user, tools as _tools, mobile, settings } from '$lib/stores';
|
import { config, user, tools as _tools, mobile, settings } from '$lib/stores';
|
||||||
|
|
||||||
|
|
@ -18,7 +19,6 @@
|
||||||
import Terminal from '$lib/components/icons/Terminal.svelte';
|
import Terminal from '$lib/components/icons/Terminal.svelte';
|
||||||
import ChevronRight from '$lib/components/icons/ChevronRight.svelte';
|
import ChevronRight from '$lib/components/icons/ChevronRight.svelte';
|
||||||
import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte';
|
import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte';
|
||||||
import { crossfade, fade, fly, slide } from 'svelte/transition';
|
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@
|
||||||
<Wrench />
|
<Wrench />
|
||||||
|
|
||||||
<div class="flex items-center w-full justify-between">
|
<div class="flex items-center w-full justify-between">
|
||||||
<div>
|
<div class=" line-clamp-1">
|
||||||
{$i18n.t('Tools')}
|
{$i18n.t('Tools')}
|
||||||
<span class="ml-0.5 text-gray-500">{Object.keys(tools).length}</span>
|
<span class="ml-0.5 text-gray-500">{Object.keys(tools).length}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
28
src/lib/components/icons/PageEdit.svelte
Normal file
28
src/lib/components/icons/PageEdit.svelte
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let className = 'w-4 h-4';
|
||||||
|
export let strokeWidth = '1.5';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
class={className}
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
stroke-width={strokeWidth}
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
><path
|
||||||
|
d="M20 12V5.74853C20 5.5894 19.9368 5.43679 19.8243 5.32426L16.6757 2.17574C16.5632 2.06321 16.4106 2 16.2515 2H4.6C4.26863 2 4 2.26863 4 2.6V21.4C4 21.7314 4.26863 22 4.6 22H11"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
></path><path d="M8 10H16M8 6H12M8 14H11" stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
></path><path
|
||||||
|
d="M17.9541 16.9394L18.9541 15.9394C19.392 15.5015 20.102 15.5015 20.5399 15.9394V15.9394C20.9778 16.3773 20.9778 17.0873 20.5399 17.5252L19.5399 18.5252M17.9541 16.9394L14.963 19.9305C14.8131 20.0804 14.7147 20.2741 14.6821 20.4835L14.4394 22.0399L15.9957 21.7973C16.2052 21.7646 16.3988 21.6662 16.5487 21.5163L19.5399 18.5252M17.9541 16.9394L19.5399 18.5252"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
></path><path
|
||||||
|
d="M16 2V5.4C16 5.73137 16.2686 6 16.6 6H20"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
></path></svg
|
||||||
|
>
|
||||||
Loading…
Reference in a new issue