mirror of
https://github.com/open-webui/open-webui
synced 2025-06-23 02:16:52 +00:00
feat: pinned models
This commit is contained in:
parent
3448362e00
commit
a64667ca8d
@ -25,6 +25,24 @@
|
|||||||
toast.success($i18n.t('Default model updated'));
|
toast.success($i18n.t('Default model updated'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const pinModelHandler = async (modelId) => {
|
||||||
|
let pinnedModels = $settings?.pinnedModels ?? [];
|
||||||
|
|
||||||
|
if (pinnedModels.includes(modelId)) {
|
||||||
|
pinnedModels = pinnedModels.filter((id) => id !== modelId);
|
||||||
|
} else {
|
||||||
|
pinnedModels = [...new Set([...pinnedModels, modelId])];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pinnedModels.length > 5) {
|
||||||
|
toast.error($i18n.t('You can only pin up to 5 models.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.set({ ...$settings, pinnedModels: pinnedModels });
|
||||||
|
await updateUserSettings(localStorage.token, { ui: $settings });
|
||||||
|
};
|
||||||
|
|
||||||
$: if (selectedModels.length > 0 && $models.length > 0) {
|
$: if (selectedModels.length > 0 && $models.length > 0) {
|
||||||
selectedModels = selectedModels.map((model) =>
|
selectedModels = selectedModels.map((model) =>
|
||||||
$models.map((m) => m.id).includes(model) ? model : ''
|
$models.map((m) => m.id).includes(model) ? model : ''
|
||||||
@ -49,6 +67,7 @@
|
|||||||
? ($user?.permissions?.chat?.temporary ?? true) &&
|
? ($user?.permissions?.chat?.temporary ?? true) &&
|
||||||
!($user?.permissions?.chat?.temporary_enforced ?? false)
|
!($user?.permissions?.chat?.temporary_enforced ?? false)
|
||||||
: true}
|
: true}
|
||||||
|
{pinModelHandler}
|
||||||
bind:value={selectedModel}
|
bind:value={selectedModel}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
import { getContext, tick } from 'svelte';
|
import { getContext, tick } from 'svelte';
|
||||||
import dayjs from '$lib/dayjs';
|
import dayjs from '$lib/dayjs';
|
||||||
|
|
||||||
import { mobile, pinnedModels, user } from '$lib/stores';
|
import { mobile, settings, user } from '$lib/stores';
|
||||||
|
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
import { copyToClipboard, sanitizeResponseContent } from '$lib/utils';
|
import { copyToClipboard, sanitizeResponseContent } from '$lib/utils';
|
||||||
@ -22,6 +22,8 @@
|
|||||||
export let value: string = '';
|
export let value: string = '';
|
||||||
|
|
||||||
export let unloadModelHandler: (modelValue: string) => void = () => {};
|
export let unloadModelHandler: (modelValue: string) => void = () => {};
|
||||||
|
export let pinModelHandler: (modelValue: string) => void = () => {};
|
||||||
|
|
||||||
export let onClick: () => void = () => {};
|
export let onClick: () => void = () => {};
|
||||||
|
|
||||||
const copyLinkHandler = async (model) => {
|
const copyLinkHandler = async (model) => {
|
||||||
@ -236,13 +238,7 @@
|
|||||||
<ModelItemMenu
|
<ModelItemMenu
|
||||||
bind:show={showMenu}
|
bind:show={showMenu}
|
||||||
model={item.model}
|
model={item.model}
|
||||||
toggleSidebarHandler={() => {
|
{pinModelHandler}
|
||||||
if ($pinnedModels.includes(item.model.id)) {
|
|
||||||
pinnedModels.set($pinnedModels.filter((id) => id !== item.model.id));
|
|
||||||
} else {
|
|
||||||
pinnedModels.set([...new Set([...$pinnedModels, item.model.id])]);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
copyLinkHandler={() => {
|
copyLinkHandler={() => {
|
||||||
copyLinkHandler(item.model);
|
copyLinkHandler(item.model);
|
||||||
}}
|
}}
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
import Link from '$lib/components/icons/Link.svelte';
|
import Link from '$lib/components/icons/Link.svelte';
|
||||||
import Eye from '$lib/components/icons/Eye.svelte';
|
import Eye from '$lib/components/icons/Eye.svelte';
|
||||||
import EyeSlash from '$lib/components/icons/EyeSlash.svelte';
|
import EyeSlash from '$lib/components/icons/EyeSlash.svelte';
|
||||||
import { pinnedModels } from '$lib/stores';
|
import { settings } from '$lib/stores';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
export let show = false;
|
export let show = false;
|
||||||
export let model;
|
export let model;
|
||||||
|
|
||||||
export let toggleSidebarHandler: Function = () => {};
|
export let pinModelHandler: (modelId: string) => void = () => {};
|
||||||
export let copyLinkHandler: Function = () => {};
|
export let copyLinkHandler: Function = () => {};
|
||||||
|
|
||||||
export let onClose: Function = () => {};
|
export let onClose: Function = () => {};
|
||||||
@ -52,18 +52,18 @@
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
toggleSidebarHandler();
|
pinModelHandler(model?.id);
|
||||||
show = false;
|
show = false;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{#if ($pinnedModels ?? []).includes(model?.id)}
|
{#if ($settings?.pinnedModels ?? []).includes(model?.id)}
|
||||||
<EyeSlash />
|
<EyeSlash />
|
||||||
{:else}
|
{:else}
|
||||||
<Eye />
|
<Eye />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
{#if ($pinnedModels ?? []).includes(model?.id)}
|
{#if ($settings?.pinnedModels ?? []).includes(model?.id)}
|
||||||
{$i18n.t('Hide from Sidebar')}
|
{$i18n.t('Hide from Sidebar')}
|
||||||
{:else}
|
{:else}
|
||||||
{$i18n.t('Keep in Sidebar')}
|
{$i18n.t('Keep in Sidebar')}
|
||||||
|
@ -57,6 +57,8 @@
|
|||||||
export let className = 'w-[32rem]';
|
export let className = 'w-[32rem]';
|
||||||
export let triggerClassName = 'text-lg';
|
export let triggerClassName = 'text-lg';
|
||||||
|
|
||||||
|
export let pinModelHandler: (modelId: string) => void = () => {};
|
||||||
|
|
||||||
let tagsContainerElement;
|
let tagsContainerElement;
|
||||||
|
|
||||||
let show = false;
|
let show = false;
|
||||||
@ -500,6 +502,7 @@
|
|||||||
{item}
|
{item}
|
||||||
{index}
|
{index}
|
||||||
{value}
|
{value}
|
||||||
|
{pinModelHandler}
|
||||||
{unloadModelHandler}
|
{unloadModelHandler}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
value = item.value;
|
value = item.value;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
socket,
|
socket,
|
||||||
config,
|
config,
|
||||||
isApp,
|
isApp,
|
||||||
pinnedModels,
|
|
||||||
models
|
models
|
||||||
} from '$lib/stores';
|
} from '$lib/stores';
|
||||||
import { onMount, getContext, tick, onDestroy } from 'svelte';
|
import { onMount, getContext, tick, onDestroy } from 'svelte';
|
||||||
@ -646,9 +645,9 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if ($pinnedModels ?? []).length > 0}
|
{#if ($settings?.pinnedModels ?? []).length > 0}
|
||||||
<div class="pt-1.5">
|
<div class="pt-1.5">
|
||||||
{#each $pinnedModels as modelId (modelId)}
|
{#each $settings.pinnedModels as modelId (modelId)}
|
||||||
{@const model = $models.find((model) => model.id === modelId)}
|
{@const model = $models.find((model) => model.id === modelId)}
|
||||||
<div class="px-1.5 flex justify-center text-gray-800 dark:text-gray-200">
|
<div class="px-1.5 flex justify-center text-gray-800 dark:text-gray-200">
|
||||||
<a
|
<a
|
||||||
|
@ -52,7 +52,6 @@ export const pinnedChats = writable([]);
|
|||||||
export const tags = writable([]);
|
export const tags = writable([]);
|
||||||
|
|
||||||
export const models: Writable<Model[]> = writable([]);
|
export const models: Writable<Model[]> = writable([]);
|
||||||
export const pinnedModels = writable([]);
|
|
||||||
|
|
||||||
export const prompts: Writable<null | Prompt[]> = writable(null);
|
export const prompts: Writable<null | Prompt[]> = writable(null);
|
||||||
export const knowledge: Writable<null | Document[]> = writable(null);
|
export const knowledge: Writable<null | Document[]> = writable(null);
|
||||||
|
Loading…
Reference in New Issue
Block a user