refac
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import DOMPurify from 'dompurify';
|
import DOMPurify from 'dompurify';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
import { getVersionUpdates, getWebhookUrl, updateWebhookUrl } from '$lib/apis';
|
import { getBackendConfig, getVersionUpdates, getWebhookUrl, updateWebhookUrl } from '$lib/apis';
|
||||||
import {
|
import {
|
||||||
getAdminConfig,
|
getAdminConfig,
|
||||||
getLdapConfig,
|
getLdapConfig,
|
||||||
@@ -10,16 +11,19 @@
|
|||||||
updateLdapConfig,
|
updateLdapConfig,
|
||||||
updateLdapServer
|
updateLdapServer
|
||||||
} from '$lib/apis/auths';
|
} from '$lib/apis/auths';
|
||||||
|
import { getBanners, setBanners } from '$lib/apis/configs';
|
||||||
import { getGroups } from '$lib/apis/groups';
|
import { getGroups } from '$lib/apis/groups';
|
||||||
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
|
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
|
||||||
import Switch from '$lib/components/common/Switch.svelte';
|
import Switch from '$lib/components/common/Switch.svelte';
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
import { WEBUI_BUILD_HASH, WEBUI_VERSION } from '$lib/constants';
|
import { WEBUI_BUILD_HASH, WEBUI_VERSION } from '$lib/constants';
|
||||||
import { config, showChangelog } from '$lib/stores';
|
import { banners as _banners, config, showChangelog } from '$lib/stores';
|
||||||
|
import type { Banner } from '$lib/types';
|
||||||
import { compareVersion } from '$lib/utils';
|
import { compareVersion } from '$lib/utils';
|
||||||
import { onMount, getContext } from 'svelte';
|
import { onMount, getContext } from 'svelte';
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import Textarea from '$lib/components/common/Textarea.svelte';
|
import Textarea from '$lib/components/common/Textarea.svelte';
|
||||||
|
import Banners from './Interface/Banners.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
@@ -35,6 +39,8 @@
|
|||||||
let webhookUrl = '';
|
let webhookUrl = '';
|
||||||
let groups = [];
|
let groups = [];
|
||||||
|
|
||||||
|
let banners: Banner[] = [];
|
||||||
|
|
||||||
// LDAP
|
// LDAP
|
||||||
let ENABLE_LDAP = false;
|
let ENABLE_LDAP = false;
|
||||||
let LDAP_SERVER = {
|
let LDAP_SERVER = {
|
||||||
@@ -78,12 +84,20 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateBanners = async () => {
|
||||||
|
_banners.set(await setBanners(localStorage.token, banners));
|
||||||
|
};
|
||||||
|
|
||||||
const updateHandler = async () => {
|
const updateHandler = async () => {
|
||||||
webhookUrl = await updateWebhookUrl(localStorage.token, webhookUrl);
|
webhookUrl = await updateWebhookUrl(localStorage.token, webhookUrl);
|
||||||
const res = await updateAdminConfig(localStorage.token, adminConfig);
|
const res = await updateAdminConfig(localStorage.token, adminConfig);
|
||||||
await updateLdapConfig(localStorage.token, ENABLE_LDAP);
|
await updateLdapConfig(localStorage.token, ENABLE_LDAP);
|
||||||
await updateLdapServerHandler();
|
await updateLdapServerHandler();
|
||||||
|
|
||||||
|
await updateBanners();
|
||||||
|
|
||||||
|
await config.set(await getBackendConfig());
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
saveHandler();
|
saveHandler();
|
||||||
} else {
|
} else {
|
||||||
@@ -114,6 +128,8 @@
|
|||||||
|
|
||||||
const ldapConfig = await getLdapConfig(localStorage.token);
|
const ldapConfig = await getLdapConfig(localStorage.token);
|
||||||
ENABLE_LDAP = ldapConfig.ENABLE_LDAP;
|
ENABLE_LDAP = ldapConfig.ENABLE_LDAP;
|
||||||
|
|
||||||
|
banners = await getBanners(localStorage.token);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -811,6 +827,53 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3.5">
|
||||||
|
<div class=" mt-0.5 mb-2.5 text-base font-medium">{$i18n.t('UI')}</div>
|
||||||
|
|
||||||
|
<hr class=" border-gray-100/30 dark:border-gray-850/30 my-2" />
|
||||||
|
|
||||||
|
<div class="mb-2.5">
|
||||||
|
<div class="flex w-full justify-between">
|
||||||
|
<div class=" self-center text-xs">
|
||||||
|
{$i18n.t('Banners')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="p-1 px-3 text-xs flex rounded-sm transition"
|
||||||
|
type="button"
|
||||||
|
on:click={() => {
|
||||||
|
if (banners.length === 0 || banners.at(-1).content !== '') {
|
||||||
|
banners = [
|
||||||
|
...banners,
|
||||||
|
{
|
||||||
|
id: uuidv4(),
|
||||||
|
type: '',
|
||||||
|
title: '',
|
||||||
|
content: '',
|
||||||
|
dismissible: true,
|
||||||
|
timestamp: Math.floor(Date.now() / 1000)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
class="w-4 h-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Banners bind:banners />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,27 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import fileSaver from 'file-saver';
|
import { getModels, getTaskConfig, updateTaskConfig } from '$lib/apis';
|
||||||
const { saveAs } = fileSaver;
|
import { config, settings } from '$lib/stores';
|
||||||
|
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
import { toast } from 'svelte-sonner';
|
|
||||||
|
|
||||||
import { getBackendConfig, getModels, getTaskConfig, updateTaskConfig } from '$lib/apis';
|
|
||||||
import { setDefaultPromptSuggestions } from '$lib/apis/configs';
|
|
||||||
import { config, settings, user } from '$lib/stores';
|
|
||||||
import { createEventDispatcher, onMount, getContext } from 'svelte';
|
import { createEventDispatcher, onMount, getContext } from 'svelte';
|
||||||
|
|
||||||
import { banners as _banners } from '$lib/stores';
|
|
||||||
import type { Banner } from '$lib/types';
|
|
||||||
|
|
||||||
import { getBaseModels } from '$lib/apis/models';
|
import { getBaseModels } from '$lib/apis/models';
|
||||||
import { getBanners, setBanners } from '$lib/apis/configs';
|
|
||||||
|
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
import Switch from '$lib/components/common/Switch.svelte';
|
import Switch from '$lib/components/common/Switch.svelte';
|
||||||
import Textarea from '$lib/components/common/Textarea.svelte';
|
import Textarea from '$lib/components/common/Textarea.svelte';
|
||||||
import Spinner from '$lib/components/common/Spinner.svelte';
|
import Spinner from '$lib/components/common/Spinner.svelte';
|
||||||
import Banners from './Interface/Banners.svelte';
|
|
||||||
import PromptSuggestions from '$lib/components/workspace/Models/PromptSuggestions.svelte';
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
@@ -46,22 +33,10 @@
|
|||||||
VOICE_MODE_PROMPT_TEMPLATE: ''
|
VOICE_MODE_PROMPT_TEMPLATE: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
let promptSuggestions = [];
|
|
||||||
let banners: Banner[] = [];
|
|
||||||
|
|
||||||
const updateInterfaceHandler = async () => {
|
const updateInterfaceHandler = async () => {
|
||||||
taskConfig = await updateTaskConfig(localStorage.token, taskConfig);
|
taskConfig = await updateTaskConfig(localStorage.token, taskConfig);
|
||||||
|
|
||||||
promptSuggestions = promptSuggestions.filter((p) => p.content !== '');
|
|
||||||
promptSuggestions = await setDefaultPromptSuggestions(localStorage.token, promptSuggestions);
|
|
||||||
await updateBanners();
|
|
||||||
|
|
||||||
await config.set(await getBackendConfig());
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateBanners = async () => {
|
|
||||||
_banners.set(await setBanners(localStorage.token, banners));
|
|
||||||
};
|
|
||||||
|
|
||||||
let workspaceModels = null;
|
let workspaceModels = null;
|
||||||
let baseModels = null;
|
let baseModels = null;
|
||||||
@@ -70,8 +45,6 @@
|
|||||||
|
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
taskConfig = await getTaskConfig(localStorage.token);
|
taskConfig = await getTaskConfig(localStorage.token);
|
||||||
promptSuggestions = $config?.default_prompt_suggestions ?? [];
|
|
||||||
banners = await getBanners(localStorage.token);
|
|
||||||
|
|
||||||
workspaceModels = await getBaseModels(localStorage.token);
|
workspaceModels = await getBaseModels(localStorage.token);
|
||||||
baseModels = await getModels(localStorage.token, null, false);
|
baseModels = await getModels(localStorage.token, null, false);
|
||||||
@@ -435,63 +408,6 @@
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3.5">
|
|
||||||
<div class=" mt-0.5 mb-2.5 text-base font-medium">{$i18n.t('UI')}</div>
|
|
||||||
|
|
||||||
<hr class=" border-gray-100/30 dark:border-gray-850/30 my-2" />
|
|
||||||
|
|
||||||
<div class="mb-2.5">
|
|
||||||
<div class="flex w-full justify-between">
|
|
||||||
<div class=" self-center text-xs">
|
|
||||||
{$i18n.t('Banners')}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="p-1 px-3 text-xs flex rounded-sm transition"
|
|
||||||
type="button"
|
|
||||||
on:click={() => {
|
|
||||||
if (banners.length === 0 || banners.at(-1).content !== '') {
|
|
||||||
banners = [
|
|
||||||
...banners,
|
|
||||||
{
|
|
||||||
id: uuidv4(),
|
|
||||||
type: '',
|
|
||||||
title: '',
|
|
||||||
content: '',
|
|
||||||
dismissible: true,
|
|
||||||
timestamp: Math.floor(Date.now() / 1000)
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="currentColor"
|
|
||||||
class="w-4 h-4"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Banners bind:banners />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if $user?.role === 'admin'}
|
|
||||||
<PromptSuggestions bind:promptSuggestions />
|
|
||||||
|
|
||||||
{#if promptSuggestions.length > 0}
|
|
||||||
<div class="text-xs text-left w-full mt-2">
|
|
||||||
{$i18n.t('Adjusting these settings will apply changes universally to all users.')}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end text-sm font-medium">
|
<div class="flex justify-end text-sm font-medium">
|
||||||
|
|||||||
@@ -537,8 +537,9 @@
|
|||||||
className=" w-fit"
|
className=" w-fit"
|
||||||
placement="top-start"
|
placement="top-start"
|
||||||
>
|
>
|
||||||
<div class="font-medium line-clamp-1 flex items-center gap-1.5">
|
<div class="font-medium line-clamp-1 flex items-center gap-2">
|
||||||
{model.name}
|
{model.name}
|
||||||
|
|
||||||
<Badge
|
<Badge
|
||||||
type={(model?.access_grants ?? []).some(
|
type={(model?.access_grants ?? []).some(
|
||||||
(g) =>
|
(g) =>
|
||||||
@@ -559,7 +560,9 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1 text-gray-500">
|
<div
|
||||||
|
class=" text-xs overflow-hidden text-ellipsis line-clamp-1 flex items-center gap-1 text-gray-500"
|
||||||
|
>
|
||||||
<span class=" line-clamp-1">
|
<span class=" line-clamp-1">
|
||||||
{!!model?.meta?.description
|
{!!model?.meta?.description
|
||||||
? model?.meta?.description
|
? model?.meta?.description
|
||||||
|
|||||||
@@ -5,10 +5,11 @@
|
|||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
import { models } from '$lib/stores';
|
import { models, config as _config } from '$lib/stores';
|
||||||
import { DEFAULT_CAPABILITIES } from '$lib/constants';
|
import { DEFAULT_CAPABILITIES } from '$lib/constants';
|
||||||
import { deleteAllModels } from '$lib/apis/models';
|
import { deleteAllModels } from '$lib/apis/models';
|
||||||
import { getModelsConfig, setModelsConfig } from '$lib/apis/configs';
|
import { getModelsConfig, setModelsConfig, setDefaultPromptSuggestions } from '$lib/apis/configs';
|
||||||
|
import { getBackendConfig } from '$lib/apis';
|
||||||
|
|
||||||
import Modal from '$lib/components/common/Modal.svelte';
|
import Modal from '$lib/components/common/Modal.svelte';
|
||||||
import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
|
import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
|
||||||
@@ -27,6 +28,7 @@
|
|||||||
import Capabilities from '$lib/components/workspace/Models/Capabilities.svelte';
|
import Capabilities from '$lib/components/workspace/Models/Capabilities.svelte';
|
||||||
import DefaultFeatures from '$lib/components/workspace/Models/DefaultFeatures.svelte';
|
import DefaultFeatures from '$lib/components/workspace/Models/DefaultFeatures.svelte';
|
||||||
import BuiltinTools from '$lib/components/workspace/Models/BuiltinTools.svelte';
|
import BuiltinTools from '$lib/components/workspace/Models/BuiltinTools.svelte';
|
||||||
|
import PromptSuggestions from '$lib/components/workspace/Models/PromptSuggestions.svelte';
|
||||||
|
|
||||||
import AdjustmentsHorizontal from '$lib/components/icons/AdjustmentsHorizontal.svelte';
|
import AdjustmentsHorizontal from '$lib/components/icons/AdjustmentsHorizontal.svelte';
|
||||||
import Eye from '$lib/components/icons/Eye.svelte';
|
import Eye from '$lib/components/icons/Eye.svelte';
|
||||||
@@ -53,11 +55,13 @@
|
|||||||
let showResetModal = false;
|
let showResetModal = false;
|
||||||
let showDefaultCapabilities = false;
|
let showDefaultCapabilities = false;
|
||||||
let showDefaultParams = false;
|
let showDefaultParams = false;
|
||||||
|
let showDefaultPromptSuggestions = false;
|
||||||
|
|
||||||
let defaultCapabilities = {};
|
let defaultCapabilities = {};
|
||||||
let defaultFeatureIds = [];
|
let defaultFeatureIds = [];
|
||||||
let defaultParams = {};
|
let defaultParams = {};
|
||||||
let builtinTools = {};
|
let builtinTools = {};
|
||||||
|
let promptSuggestions = [];
|
||||||
|
|
||||||
$: if (show) {
|
$: if (show) {
|
||||||
init();
|
init();
|
||||||
@@ -104,6 +108,8 @@
|
|||||||
builtinTools = {};
|
builtinTools = {};
|
||||||
}
|
}
|
||||||
defaultParams = config?.DEFAULT_MODEL_PARAMS ?? {};
|
defaultParams = config?.DEFAULT_MODEL_PARAMS ?? {};
|
||||||
|
|
||||||
|
promptSuggestions = $_config?.default_prompt_suggestions ?? [];
|
||||||
};
|
};
|
||||||
const submitHandler = async () => {
|
const submitHandler = async () => {
|
||||||
loading = true;
|
loading = true;
|
||||||
@@ -125,6 +131,10 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
promptSuggestions = promptSuggestions.filter((p) => p.content !== '');
|
||||||
|
promptSuggestions = await setDefaultPromptSuggestions(localStorage.token, promptSuggestions);
|
||||||
|
await _config.set(await getBackendConfig());
|
||||||
|
|
||||||
toast.success($i18n.t('Models configuration saved successfully'));
|
toast.success($i18n.t('Models configuration saved successfully'));
|
||||||
initHandler();
|
initHandler();
|
||||||
show = false;
|
show = false;
|
||||||
@@ -241,6 +251,43 @@
|
|||||||
|
|
||||||
<hr class=" border-gray-50 dark:border-gray-800/10 my-2.5 w-full" />
|
<hr class=" border-gray-50 dark:border-gray-800/10 my-2.5 w-full" />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="flex w-full justify-between items-center"
|
||||||
|
type="button"
|
||||||
|
on:click={() => {
|
||||||
|
showDefaultPromptSuggestions = !showDefaultPromptSuggestions;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div class="text-xs text-gray-500 font-medium">
|
||||||
|
{$i18n.t('Prompt Suggestions')}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{#if showDefaultPromptSuggestions}
|
||||||
|
<ChevronUp className="size-3" />
|
||||||
|
{:else}
|
||||||
|
<ChevronDown className="size-3" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{#if showDefaultPromptSuggestions}
|
||||||
|
<div class="mt-2">
|
||||||
|
<PromptSuggestions bind:promptSuggestions />
|
||||||
|
|
||||||
|
{#if promptSuggestions.length > 0}
|
||||||
|
<div class="text-xs text-left w-full mt-2 text-gray-500">
|
||||||
|
{$i18n.t(
|
||||||
|
'Adjusting these settings will apply changes universally to all users.'
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class=" border-gray-50 dark:border-gray-800/10 my-2.5 w-full" />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
class="flex w-full justify-between items-center"
|
class="flex w-full justify-between items-center"
|
||||||
@@ -369,7 +416,6 @@
|
|||||||
<ModelList bind:modelIds />
|
<ModelList bind:modelIds />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
class=" text-xs font-medium {classNames[type] ??
|
class=" text-xs font-medium {classNames[type] ??
|
||||||
classNames['info']} w-fit px-1.5 py-[1px] rounded-lg uppercase line-clamp-1 mr-0.5"
|
classNames['info']} w-fit px-[5px] rounded uppercase line-clamp-1 mr-0.5"
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user