Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
72354e06
Unverified
Commit
72354e06
authored
Jun 01, 2024
by
Timothy Jaeryang Baek
Committed by
GitHub
Jun 01, 2024
Browse files
Merge pull request #2476 from open-webui/dev
0.2.0
parents
36e2a5e6
207e2503
Changes
206
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
501 additions
and
88 deletions
+501
-88
src/lib/components/chat/SettingsModal.svelte
src/lib/components/chat/SettingsModal.svelte
+3
-2
src/lib/components/chat/ShareChatModal.svelte
src/lib/components/chat/ShareChatModal.svelte
+14
-14
src/lib/components/common/Banner.svelte
src/lib/components/common/Banner.svelte
+125
-0
src/lib/components/common/Checkbox.svelte
src/lib/components/common/Checkbox.svelte
+1
-0
src/lib/components/common/Dropdown.svelte
src/lib/components/common/Dropdown.svelte
+2
-0
src/lib/components/common/Image.svelte
src/lib/components/common/Image.svelte
+1
-1
src/lib/components/common/Spinner.svelte
src/lib/components/common/Spinner.svelte
+3
-3
src/lib/components/common/Tags.svelte
src/lib/components/common/Tags.svelte
+1
-1
src/lib/components/common/Tags/TagInput.svelte
src/lib/components/common/Tags/TagInput.svelte
+20
-18
src/lib/components/common/Tags/TagList.svelte
src/lib/components/common/Tags/TagList.svelte
+4
-3
src/lib/components/common/Tooltip.svelte
src/lib/components/common/Tooltip.svelte
+2
-1
src/lib/components/documents/Settings/WebParams.svelte
src/lib/components/documents/Settings/WebParams.svelte
+223
-40
src/lib/components/documents/SettingsModal.svelte
src/lib/components/documents/SettingsModal.svelte
+7
-2
src/lib/components/icons/ChevronUp.svelte
src/lib/components/icons/ChevronUp.svelte
+15
-0
src/lib/components/icons/DocumentArrowUpSolid.svelte
src/lib/components/icons/DocumentArrowUpSolid.svelte
+14
-0
src/lib/components/icons/DocumentDuplicate.svelte
src/lib/components/icons/DocumentDuplicate.svelte
+19
-0
src/lib/components/icons/EllipsisHorizontal.svelte
src/lib/components/icons/EllipsisHorizontal.svelte
+19
-0
src/lib/components/icons/GlobeAltSolid.svelte
src/lib/components/icons/GlobeAltSolid.svelte
+9
-0
src/lib/components/layout/Navbar.svelte
src/lib/components/layout/Navbar.svelte
+0
-1
src/lib/components/layout/Sidebar.svelte
src/lib/components/layout/Sidebar.svelte
+19
-2
No files found.
src/lib/components/chat/SettingsModal.svelte
View file @
72354e06
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
import { toast } from 'svelte-sonner';
import { toast } from 'svelte-sonner';
import { models, settings, user } from '$lib/stores';
import { models, settings, user } from '$lib/stores';
import { getModels as _getModels } from '$lib/
util
s';
import { getModels as _getModels } from '$lib/
api
s';
import Modal from '../common/Modal.svelte';
import Modal from '../common/Modal.svelte';
import Account from './Settings/Account.svelte';
import Account from './Settings/Account.svelte';
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
import Images from './Settings/Images.svelte';
import Images from './Settings/Images.svelte';
import User from '../icons/User.svelte';
import User from '../icons/User.svelte';
import Personalization from './Settings/Personalization.svelte';
import Personalization from './Settings/Personalization.svelte';
import { updateUserSettings } from '$lib/apis/users';
const i18n = getContext('i18n');
const i18n = getContext('i18n');
...
@@ -26,7 +27,7 @@
...
@@ -26,7 +27,7 @@
console.log(updated);
console.log(updated);
await settings.set({ ...$settings, ...updated });
await settings.set({ ...$settings, ...updated });
await models.set(await getModels());
await models.set(await getModels());
localStorage.setItem('settings', JSON.stringify(
$settings
)
);
await updateUserSettings(localStorage.token, { ui:
$settings
}
);
};
};
const getModels = async () => {
const getModels = async () => {
...
...
src/lib/components/chat/ShareChatModal.svelte
View file @
72354e06
<script lang="ts">
<script lang="ts">
import { getContext, onMount } from 'svelte';
import { getContext, onMount } from 'svelte';
import { models, config } from '$lib/stores';
import { toast } from 'svelte-sonner';
import { toast } from 'svelte-sonner';
import { deleteSharedChatById, getChatById, shareChatById } from '$lib/apis/chats';
import { deleteSharedChatById, getChatById, shareChatById } from '$lib/apis/chats';
import { modelfiles } from '$lib/stores';
import { copyToClipboard } from '$lib/utils';
import { copyToClipboard } from '$lib/utils';
import Modal from '../common/Modal.svelte';
import Modal from '../common/Modal.svelte';
...
@@ -43,9 +43,7 @@
...
@@ -43,9 +43,7 @@
tab.postMessage(
tab.postMessage(
JSON.stringify({
JSON.stringify({
chat: _chat,
chat: _chat,
modelfiles: $modelfiles.filter((modelfile) =>
models: $models.filter((m) => _chat.models.includes(m.id))
_chat.models.includes(modelfile.tagName)
)
}),
}),
'*'
'*'
);
);
...
@@ -136,16 +134,18 @@
...
@@ -136,16 +134,18 @@
<div class="flex justify-end">
<div class="flex justify-end">
<div class="flex flex-col items-end space-x-1 mt-1.5">
<div class="flex flex-col items-end space-x-1 mt-1.5">
<div class="flex gap-1">
<div class="flex gap-1">
<button
{#if $config?.features.enable_community_sharing}
class=" self-center px-3.5 py-2 rounded-xl text-sm font-medium bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-white"
<button
type="button"
class=" self-center px-3.5 py-2 rounded-xl text-sm font-medium bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-white"
on:click={() => {
type="button"
shareChat();
on:click={() => {
show = false;
shareChat();
}}
show = false;
>
}}
{$i18n.t('Share to OpenWebUI Community')}
>
</button>
{$i18n.t('Share to OpenWebUI Community')}
</button>
{/if}
<button
<button
class=" self-center flex items-center gap-1 px-3.5 py-2 rounded-xl text-sm font-medium bg-emerald-600 hover:bg-emerald-500 text-white"
class=" self-center flex items-center gap-1 px-3.5 py-2 rounded-xl text-sm font-medium bg-emerald-600 hover:bg-emerald-500 text-white"
...
...
src/lib/components/common/Banner.svelte
0 → 100644
View file @
72354e06
<script lang="ts">
import type { Banner } from '$lib/types';
import { onMount, createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
const dispatch = createEventDispatcher();
export let banner: Banner = {
id: '',
type: 'info',
title: '',
content: '',
url: '',
dismissable: true,
timestamp: Math.floor(Date.now() / 1000)
};
export let dismissed = false;
let mounted = false;
const classNames: Record<string, string> = {
info: 'bg-blue-500/20 text-blue-700 dark:text-blue-200 ',
success: 'bg-green-500/20 text-green-700 dark:text-green-200',
warning: 'bg-yellow-500/20 text-yellow-700 dark:text-yellow-200',
error: 'bg-red-500/20 text-red-700 dark:text-red-200'
};
const dismiss = (id) => {
dismissed = true;
dispatch('dismiss', id);
};
onMount(() => {
mounted = true;
});
</script>
{#if !dismissed}
{#if mounted}
<div
class=" top-0 left-0 right-0 p-2 mx-4 px-3 flex justify-center items-center relative rounded-xl border border-gray-50 dark:border-gray-850 text-gray-800 dark:text-gary-100 bg-white dark:bg-gray-900 backdrop-blur-xl z-40"
transition:fade={{ delay: 100, duration: 300 }}
>
<div class=" flex flex-col md:flex-row md:items-center flex-1 text-sm w-fit gap-1.5">
<div class="flex justify-between self-start">
<div
class=" text-xs font-black {classNames[banner.type] ??
classNames['info']} w-fit px-2 rounded uppercase line-clamp-1 mr-0.5"
>
{banner.type}
</div>
{#if banner.url}
<div class="flex md:hidden group w-fit md:items-center">
<a
class="text-gray-700 dark:text-white text-xs font-bold underline"
href="/assets/files/whitepaper.pdf"
target="_blank">Learn More</a
>
<div
class=" ml-1 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-white"
>
<!-- -->
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M4.22 11.78a.75.75 0 0 1 0-1.06L9.44 5.5H5.75a.75.75 0 0 1 0-1.5h5.5a.75.75 0 0 1 .75.75v5.5a.75.75 0 0 1-1.5 0V6.56l-5.22 5.22a.75.75 0 0 1-1.06 0Z"
clip-rule="evenodd"
/>
</svg>
</div>
</div>
{/if}
</div>
<div class="flex-1 text-xs text-gray-700 dark:text-white">
{banner.content}
</div>
</div>
{#if banner.url}
<div class="hidden md:flex group w-fit md:items-center">
<a
class="text-gray-700 dark:text-white text-xs font-bold underline"
href="/"
target="_blank">Learn More</a
>
<div class=" ml-1 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-white">
<!-- -->
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="size-4"
>
<path
fill-rule="evenodd"
d="M4.22 11.78a.75.75 0 0 1 0-1.06L9.44 5.5H5.75a.75.75 0 0 1 0-1.5h5.5a.75.75 0 0 1 .75.75v5.5a.75.75 0 0 1-1.5 0V6.56l-5.22 5.22a.75.75 0 0 1-1.06 0Z"
clip-rule="evenodd"
/>
</svg>
</div>
</div>
{/if}
<div class="flex self-start">
{#if banner.dismissible}
<button
on:click={() => {
dismiss(banner.id);
}}
class=" -mt-[3px] ml-1.5 mr-1 text-gray-400 dark:hover:text-white h-1">×</button
>
{/if}
</div>
</div>
{/if}
{/if}
src/lib/components/common/Checkbox.svelte
View file @
72354e06
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
dispatch('change', _state);
dispatch('change', _state);
}
}
}}
}}
type="button"
>
>
<div class="top-0 left-0 absolute w-full flex justify-center">
<div class="top-0 left-0 absolute w-full flex justify-center">
{#if _state === 'checked'}
{#if _state === 'checked'}
...
...
src/lib/components/common/Dropdown.svelte
View file @
72354e06
...
@@ -10,9 +10,11 @@
...
@@ -10,9 +10,11 @@
<DropdownMenu.Root
<DropdownMenu.Root
bind:open={show}
bind:open={show}
closeFocus={false}
onOpenChange={(state) => {
onOpenChange={(state) => {
dispatch('change', state);
dispatch('change', state);
}}
}}
typeahead={false}
>
>
<DropdownMenu.Trigger>
<DropdownMenu.Trigger>
<slot />
<slot />
...
...
src/lib/components/common/Image.svelte
View file @
72354e06
...
@@ -19,5 +19,5 @@
...
@@ -19,5 +19,5 @@
showImagePreview = true;
showImagePreview = true;
}}
}}
>
>
<img src={_src} {alt} class=" max-h-96 rounded-lg" draggable="false" />
<img src={_src} {alt} class=" max-h-96 rounded-lg" draggable="false"
data-cy="image"
/>
</button>
</button>
src/lib/components/common/Spinner.svelte
View file @
72354e06
<script lang="ts">
<script lang="ts">
export let className: string = '';
export let className: string = '
size-5
';
</script>
</script>
<div class="flex justify-center text-center
{className}
">
<div class="flex justify-center text-center">
<svg class=
"size-5"
viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg"
<svg class=
{className}
viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg"
><style>
><style>
.spinner_ajPY {
.spinner_ajPY {
transform-origin: center;
transform-origin: center;
...
...
src/lib/components/common/Tags.svelte
View file @
72354e06
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
export let addTag: Function;
export let addTag: Function;
</script>
</script>
<div class="flex flex-row flex-wrap gap-
0.5
line-clamp-1">
<div class="flex flex-row flex-wrap gap-
1
line-clamp-1">
<TagList
<TagList
{tags}
{tags}
on:delete={(e) => {
on:delete={(e) => {
...
...
src/lib/components/common/Tags/TagInput.svelte
View file @
72354e06
...
@@ -22,26 +22,12 @@
...
@@ -22,26 +22,12 @@
};
};
</script>
</script>
<div class="flex
space-x-1 pl-1.5
">
<div class="flex
{showTagInput ? 'flex-row-reverse' : ''}
">
{#if showTagInput}
{#if showTagInput}
<div class="flex items-center">
<div class="flex items-center">
<button type="button" on:click={addTagHandler}>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-3 h-3"
>
<path
fill-rule="evenodd"
d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z"
clip-rule="evenodd"
/>
</svg>
</button>
<input
<input
bind:value={tagName}
bind:value={tagName}
class=" p
l
-2 cursor-pointer self-center text-xs h-fit bg-transparent outline-none line-clamp-1 w-[5.5rem]"
class=" p
x
-2 cursor-pointer self-center text-xs h-fit bg-transparent outline-none line-clamp-1 w-[5.5rem]"
placeholder={$i18n.t('Add a tag')}
placeholder={$i18n.t('Add a tag')}
list="tagOptions"
list="tagOptions"
on:keydown={(event) => {
on:keydown={(event) => {
...
@@ -55,11 +41,27 @@
...
@@ -55,11 +41,27 @@
<option value={tag.name} />
<option value={tag.name} />
{/each}
{/each}
</datalist>
</datalist>
<button type="button" on:click={addTagHandler}>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
stroke-width="2"
class="w-3 h-3"
>
<path
fill-rule="evenodd"
d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
</div>
{/if}
{/if}
<button
<button
class=" cursor-pointer self-center p-0.5
space-x-1
flex h-fit items-center dark:hover:bg-gray-700 rounded-full transition border dark:border-gray-600 border-dashed"
class=" cursor-pointer self-center p-0.5 flex h-fit items-center dark:hover:bg-gray-700 rounded-full transition border dark:border-gray-600 border-dashed"
type="button"
type="button"
on:click={() => {
on:click={() => {
showTagInput = !showTagInput;
showTagInput = !showTagInput;
...
@@ -80,6 +82,6 @@
...
@@ -80,6 +82,6 @@
</button>
</button>
{#if label && !showTagInput}
{#if label && !showTagInput}
<span class="text-xs pl-
1.5
self-center">{label}</span>
<span class="text-xs pl-
2
self-center">{label}</span>
{/if}
{/if}
</div>
</div>
src/lib/components/common/Tags/TagList.svelte
View file @
72354e06
...
@@ -7,22 +7,23 @@
...
@@ -7,22 +7,23 @@
{#each tags as tag}
{#each tags as tag}
<div
<div
class="px-2 py-0.5
space-x-1 flex
h-fit items-center rounded-full transition border dark:border-gray-800 dark:text-white"
class="px-2 py-
[
0.5
px] gap-0.5 flex justify-between
h-fit items-center rounded-full transition border dark:border-gray-800 dark:text-white"
>
>
<div class=" text-[0.7rem] font-medium self-center line-clamp-1">
<div class=" text-[0.7rem] font-medium self-center line-clamp-1">
{tag.name}
{tag.name}
</div>
</div>
<button
<button
class="
m-auto
self-center cursor-pointer"
class="
h-full flex
self-center cursor-pointer"
on:click={() => {
on:click={() => {
dispatch('delete', tag.name);
dispatch('delete', tag.name);
}}
}}
type="button"
>
>
<svg
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
viewBox="0 0 16 16"
fill="currentColor"
fill="currentColor"
class="
w-3 h-3
"
class="
size-3 m-auto self-center translate-y-[0.3px] translate-x-[3px]
"
>
>
<path
<path
d="M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z"
d="M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z"
...
...
src/lib/components/common/Tooltip.svelte
View file @
72354e06
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
export let placement = 'top';
export let placement = 'top';
export let content = `I'm a tooltip!`;
export let content = `I'm a tooltip!`;
export let touch = true;
export let touch = true;
export let className = 'flex';
let tooltipElement;
let tooltipElement;
let tooltipInstance;
let tooltipInstance;
...
@@ -29,6 +30,6 @@
...
@@ -29,6 +30,6 @@
});
});
</script>
</script>
<div bind:this={tooltipElement} aria-label={content} class=
"flex"
>
<div bind:this={tooltipElement} aria-label={content} class=
{className}
>
<slot />
<slot />
</div>
</div>
src/lib/components/documents/Settings/WebParams.svelte
View file @
72354e06
<script lang="ts">
<script lang="ts">
import { getRAGConfig, updateRAGConfig } from '$lib/apis/rag';
import { getRAGConfig, updateRAGConfig } from '$lib/apis/rag';
import Switch from '$lib/components/common/Switch.svelte';
import { documents, models } from '$lib/stores';
import { documents, models } from '$lib/stores';
import { onMount, getContext } from 'svelte';
import { onMount, getContext } from 'svelte';
...
@@ -9,14 +10,15 @@
...
@@ -9,14 +10,15 @@
export let saveHandler: Function;
export let saveHandler: Function;
let webLoaderSSLVerification = true;
let webConfig = null;
let webSearchEngines = ['searxng', 'google_pse', 'brave', 'serpstack', 'serper'];
let youtubeLanguage = 'en';
let youtubeLanguage = 'en';
let youtubeTranslation = null;
let youtubeTranslation = null;
const submitHandler = async () => {
const submitHandler = async () => {
const res = await updateRAGConfig(localStorage.token, {
const res = await updateRAGConfig(localStorage.token, {
web
_loader_ssl_verification: webLoaderSSLVerification
,
web
: webConfig
,
youtube: {
youtube: {
language: youtubeLanguage.split(',').map((lang) => lang.trim()),
language: youtubeLanguage.split(',').map((lang) => lang.trim()),
translation: youtubeTranslation
translation: youtubeTranslation
...
@@ -28,7 +30,8 @@
...
@@ -28,7 +30,8 @@
const res = await getRAGConfig(localStorage.token);
const res = await getRAGConfig(localStorage.token);
if (res) {
if (res) {
webLoaderSSLVerification = res.web_loader_ssl_verification;
webConfig = res.web;
youtubeLanguage = res.youtube.language.join(',');
youtubeLanguage = res.youtube.language.join(',');
youtubeTranslation = res.youtube.translation;
youtubeTranslation = res.youtube.translation;
}
}
...
@@ -37,59 +40,239 @@
...
@@ -37,59 +40,239 @@
<form
<form
class="flex flex-col h-full justify-between space-y-3 text-sm"
class="flex flex-col h-full justify-between space-y-3 text-sm"
on:submit|preventDefault={() => {
on:submit|preventDefault={
async
() => {
submitHandler();
await
submitHandler();
saveHandler();
saveHandler();
}}
}}
>
>
<div class=" space-y-3 pr-1.5 overflow-y-scroll h-full max-h-[22rem]">
<div class=" space-y-3 pr-1.5 overflow-y-scroll h-full max-h-[22rem]">
<div>
{#if webConfig}
<div class=" mb-1 text-sm font-medium">
{$i18n.t('Web Loader Settings')}
</div>
<div>
<div>
<div class=" mb-1 text-sm font-medium">
{$i18n.t('Web Search')}
</div>
<div>
<div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Enable Web Search')}
</div>
<Switch bind:state={webConfig.search.enabled} />
</div>
</div>
<div class=" py-0.5 flex w-full justify-between">
<div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">
<div class=" self-center text-xs font-medium">{$i18n.t('Web Search Engine')}</div>
{$i18n.t('Bypass SSL verification for Websites')}
<div class="flex items-center relative">
<select
class="dark:bg-gray-900 w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-right"
bind:value={webConfig.search.engine}
placeholder="Select a engine"
required
>
<option disabled selected value="">Select a engine</option>
{#each webSearchEngines as engine}
<option value={engine}>{engine}</option>
{/each}
</select>
</div>
</div>
</div>
{#if webConfig.search.engine !== ''}
<div class="mt-1.5">
{#if webConfig.search.engine === 'searxng'}
<div>
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Searxng Query URL')}
</div>
<div class="flex w-full">
<div class="flex-1">
<input
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
type="text"
placeholder={$i18n.t('Enter Searxng Query URL')}
bind:value={webConfig.search.searxng_query_url}
autocomplete="off"
/>
</div>
</div>
</div>
{:else if webConfig.search.engine === 'google_pse'}
<div>
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Google PSE API Key')}
</div>
<div class="flex w-full">
<div class="flex-1">
<input
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
type="text"
placeholder={$i18n.t('Enter Google PSE API Key')}
bind:value={webConfig.search.google_pse_api_key}
autocomplete="off"
/>
</div>
</div>
</div>
<div class="mt-1.5">
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Google PSE Engine Id')}
</div>
<button
<div class="flex w-full">
class="p-1 px-3 text-xs flex rounded transition"
<div class="flex-1">
on:click={() => {
<input
webLoaderSSLVerification = !webLoaderSSLVerification;
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
submitHandler();
type="text"
}}
placeholder={$i18n.t('Enter Google PSE Engine Id')}
type="button"
bind:value={webConfig.search.google_pse_engine_id}
>
autocomplete="off"
{#if webLoaderSSLVerification === true}
/>
<span class="ml-2 self-center">{$i18n.t('On')}</span>
</div>
{:else}
</div>
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
</div>
{:else if webConfig.search.engine === 'brave'}
<div>
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Brave Search API Key')}
</div>
<div class="flex w-full">
<div class="flex-1">
<input
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
type="text"
placeholder={$i18n.t('Enter Brave Search API Key')}
bind:value={webConfig.search.brave_search_api_key}
autocomplete="off"
/>
</div>
</div>
</div>
{:else if webConfig.search.engine === 'serpstack'}
<div>
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Serpstack API Key')}
</div>
<div class="flex w-full">
<div class="flex-1">
<input
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
type="text"
placeholder={$i18n.t('Enter Serpstack API Key')}
bind:value={webConfig.search.serpstack_api_key}
autocomplete="off"
/>
</div>
</div>
</div>
{:else if webConfig.search.engine === 'serper'}
<div>
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Serper API Key')}
</div>
<div class="flex w-full">
<div class="flex-1">
<input
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
type="text"
placeholder={$i18n.t('Enter Serper API Key')}
bind:value={webConfig.search.serper_api_key}
autocomplete="off"
/>
</div>
</div>
</div>
{/if}
{/if}
</button>
</div>
</div>
{/if}
</div>
{#if webConfig.search.enabled}
<div class="mt-2 flex gap-2 mb-1">
<div class="w-full">
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Search Result Count')}
</div>
<input
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
placeholder={$i18n.t('Search Result Count')}
bind:value={webConfig.search.result_count}
required
/>
</div>
<div class=" mt-2 mb-1 text-sm font-medium">
<div class="w-full">
{$i18n.t('Youtube Loader Settings')}
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Concurrent Requests')}
</div>
<input
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
placeholder={$i18n.t('Concurrent Requests')}
bind:value={webConfig.search.concurrent_requests}
required
/>
</div>
</div>
{/if}
</div>
</div>
<hr class=" dark:border-gray-850 my-2" />
<div>
<div>
<div class=" py-0.5 flex w-full justify-between">
<div class=" mb-1 text-sm font-medium">
<div class=" w-20 text-xs font-medium self-center">{$i18n.t('Language')}</div>
{$i18n.t('Web Loader Settings')}
<div class=" flex-1 self-center">
</div>
<input
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
<div>
type="text"
<div class=" py-0.5 flex w-full justify-between">
placeholder={$i18n.t('Enter language codes')}
<div class=" self-center text-xs font-medium">
bind:value={youtubeLanguage}
{$i18n.t('Bypass SSL verification for Websites')}
autocomplete="off"
</div>
/>
<button
class="p-1 px-3 text-xs flex rounded transition"
on:click={() => {
webConfig.ssl_verification = !webConfig.ssl_verification;
submitHandler();
}}
type="button"
>
{#if webConfig.ssl_verification === true}
<span class="ml-2 self-center">{$i18n.t('On')}</span>
{:else}
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
{/if}
</button>
</div>
</div>
<div class=" mt-2 mb-1 text-sm font-medium">
{$i18n.t('Youtube Loader Settings')}
</div>
<div>
<div class=" py-0.5 flex w-full justify-between">
<div class=" w-20 text-xs font-medium self-center">{$i18n.t('Language')}</div>
<div class=" flex-1 self-center">
<input
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
type="text"
placeholder={$i18n.t('Enter language codes')}
bind:value={youtubeLanguage}
autocomplete="off"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{/if}
</div>
</div>
<div class="flex justify-end pt-3 text-sm font-medium">
<div class="flex justify-end pt-3 text-sm font-medium">
<button
<button
...
...
src/lib/components/documents/SettingsModal.svelte
View file @
72354e06
<script>
<script>
import { getContext } from 'svelte';
import { getContext
, tick
} from 'svelte';
import Modal from '../common/Modal.svelte';
import Modal from '../common/Modal.svelte';
import General from './Settings/General.svelte';
import General from './Settings/General.svelte';
import ChunkParams from './Settings/ChunkParams.svelte';
import ChunkParams from './Settings/ChunkParams.svelte';
import QueryParams from './Settings/QueryParams.svelte';
import QueryParams from './Settings/QueryParams.svelte';
import WebParams from './Settings/WebParams.svelte';
import WebParams from './Settings/WebParams.svelte';
import { toast } from 'svelte-sonner';
import { toast } from 'svelte-sonner';
import { config } from '$lib/stores';
import { getBackendConfig } from '$lib/apis';
const i18n = getContext('i18n');
const i18n = getContext('i18n');
...
@@ -171,8 +173,11 @@
...
@@ -171,8 +173,11 @@
/>
/>
{:else if selectedTab === 'web'}
{:else if selectedTab === 'web'}
<WebParams
<WebParams
saveHandler={() => {
saveHandler={
async
() => {
toast.success($i18n.t('Settings saved successfully!'));
toast.success($i18n.t('Settings saved successfully!'));
await tick();
await config.set(await getBackendConfig());
}}
}}
/>
/>
{/if}
{/if}
...
...
src/lib/components/icons/ChevronUp.svelte
0 → 100644
View file @
72354e06
<script lang="ts">
export let className = 'w-4 h-4';
export let strokeWidth = '1.5';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width={strokeWidth}
stroke="currentColor"
class={className}
>
<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 15.75 7.5-7.5 7.5 7.5" />
</svg>
src/lib/components/icons/DocumentArrowUpSolid.svelte
0 → 100644
View file @
72354e06
<script lang="ts">
export let className = 'size-4';
</script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class={className}>
<path
fill-rule="evenodd"
d="M5.625 1.5H9a3.75 3.75 0 0 1 3.75 3.75v1.875c0 1.036.84 1.875 1.875 1.875H16.5a3.75 3.75 0 0 1 3.75 3.75v7.875c0 1.035-.84 1.875-1.875 1.875H5.625a1.875 1.875 0 0 1-1.875-1.875V3.375c0-1.036.84-1.875 1.875-1.875Zm6.905 9.97a.75.75 0 0 0-1.06 0l-3 3a.75.75 0 1 0 1.06 1.06l1.72-1.72V18a.75.75 0 0 0 1.5 0v-4.19l1.72 1.72a.75.75 0 1 0 1.06-1.06l-3-3Z"
clip-rule="evenodd"
/>
<path
d="M14.25 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 16.5 7.5h-1.875a.375.375 0 0 1-.375-.375V5.25Z"
/>
</svg>
src/lib/components/icons/DocumentDuplicate.svelte
0 → 100644
View file @
72354e06
<script lang="ts">
export let className = 'w-4 h-4';
export let strokeWidth = '1.5';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width={strokeWidth}
stroke="currentColor"
class={className}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
/>
</svg>
src/lib/components/icons/EllipsisHorizontal.svelte
0 → 100644
View file @
72354e06
<script lang="ts">
export let className = 'w-4 h-4';
export let strokeWidth = '1.5';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width={strokeWidth}
stroke="currentColor"
class={className}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M6.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM12.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM18.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z"
/>
</svg>
src/lib/components/icons/GlobeAltSolid.svelte
0 → 100644
View file @
72354e06
<script lang="ts">
export let className = 'size-4';
</script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class={className}>
<path
d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z"
/>
</svg>
src/lib/components/layout/Navbar.svelte
View file @
72354e06
...
@@ -6,7 +6,6 @@
...
@@ -6,7 +6,6 @@
WEBUI_NAME,
WEBUI_NAME,
chatId,
chatId,
mobile,
mobile,
modelfiles,
settings,
settings,
showArchivedChats,
showArchivedChats,
showSettings,
showSettings,
...
...
src/lib/components/layout/Sidebar.svelte
View file @
72354e06
...
@@ -22,7 +22,8 @@
...
@@ -22,7 +22,8 @@
getChatListByTagName,
getChatListByTagName,
updateChatById,
updateChatById,
getAllChatTags,
getAllChatTags,
archiveChatById
archiveChatById,
cloneChatById
} from '$lib/apis/chats';
} from '$lib/apis/chats';
import { toast } from 'svelte-sonner';
import { toast } from 'svelte-sonner';
import { fade, slide } from 'svelte/transition';
import { fade, slide } from 'svelte/transition';
...
@@ -33,6 +34,7 @@
...
@@ -33,6 +34,7 @@
import ArchiveBox from '../icons/ArchiveBox.svelte';
import ArchiveBox from '../icons/ArchiveBox.svelte';
import ArchivedChatsModal from './Sidebar/ArchivedChatsModal.svelte';
import ArchivedChatsModal from './Sidebar/ArchivedChatsModal.svelte';
import UserMenu from './Sidebar/UserMenu.svelte';
import UserMenu from './Sidebar/UserMenu.svelte';
import { updateUserSettings } from '$lib/apis/users';
const BREAKPOINT = 768;
const BREAKPOINT = 768;
...
@@ -181,9 +183,21 @@
...
@@ -181,9 +183,21 @@
}
}
};
};
const cloneChatHandler = async (id) => {
const res = await cloneChatById(localStorage.token, id).catch((error) => {
toast.error(error);
return null;
});
if (res) {
goto(`/c/${res.id}`);
await chats.set(await getChatList(localStorage.token));
}
};
const saveSettings = async (updated) => {
const saveSettings = async (updated) => {
await settings.set({ ...$settings, ...updated });
await settings.set({ ...$settings, ...updated });
localStorage.setItem('settings', JSON.stringify(
$settings
)
);
await updateUserSettings(localStorage.token, { ui:
$settings
}
);
location.href = '/';
location.href = '/';
};
};
...
@@ -600,6 +614,9 @@
...
@@ -600,6 +614,9 @@
<div class="flex self-center space-x-1 z-10">
<div class="flex self-center space-x-1 z-10">
<ChatMenu
<ChatMenu
chatId={chat.id}
chatId={chat.id}
cloneChatHandler={() => {
cloneChatHandler(chat.id);
}}
shareHandler={() => {
shareHandler={() => {
shareChatId = selectedChatId;
shareChatId = selectedChatId;
showShareChatModal = true;
showShareChatModal = true;
...
...
Prev
1
…
3
4
5
6
7
8
9
10
11
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment