refac: reactive user settings

This commit is contained in:
Timothy Jaeryang Baek 2025-08-12 03:48:04 +04:00
parent 62506b1955
commit f91da291d9
2 changed files with 87 additions and 61 deletions

View file

@ -6,7 +6,7 @@
import { getOllamaConfig, updateOllamaConfig } from '$lib/apis/ollama'; import { getOllamaConfig, updateOllamaConfig } from '$lib/apis/ollama';
import { getOpenAIConfig, updateOpenAIConfig, getOpenAIModels } from '$lib/apis/openai'; import { getOpenAIConfig, updateOpenAIConfig, getOpenAIModels } from '$lib/apis/openai';
import { getModels as _getModels } from '$lib/apis'; import { getModels as _getModels, getBackendConfig } from '$lib/apis';
import { getConnectionsConfig, setConnectionsConfig } from '$lib/apis/configs'; import { getConnectionsConfig, setConnectionsConfig } from '$lib/apis/configs';
import { config, models, settings, user } from '$lib/stores'; import { config, models, settings, user } from '$lib/stores';
@ -114,6 +114,7 @@
if (res) { if (res) {
toast.success($i18n.t('Connections settings updated')); toast.success($i18n.t('Connections settings updated'));
await models.set(await getModels()); await models.set(await getModels());
await config.set(await getBackendConfig());
} }
}; };
@ -198,6 +199,8 @@
updateOllamaHandler(); updateOllamaHandler();
dispatch('save'); dispatch('save');
await config.set(await getBackendConfig());
}; };
</script> </script>

View file

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { getContext, tick } from 'svelte'; import { getContext, onMount, tick } from 'svelte';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { config, models, settings, user } from '$lib/stores'; import { config, models, settings, user } from '$lib/stores';
import { updateUserSettings } from '$lib/apis/users'; import { updateUserSettings } from '$lib/apis/users';
@ -24,13 +24,19 @@
export let show = false; export let show = false;
$: if (show) {
addScrollListener();
} else {
removeScrollListener();
}
interface SettingsTab { interface SettingsTab {
id: string; id: string;
title: string; title: string;
keywords: string[]; keywords: string[];
} }
const searchData: SettingsTab[] = [ const allSettings: SettingsTab[] = [
{ {
id: 'general', id: 'general',
title: 'General', title: 'General',
@ -191,9 +197,6 @@
'web search in chat' 'web search in chat'
] ]
}, },
...($user?.role === 'admin' ||
($user?.role === 'user' && $config?.features?.enable_direct_connections)
? [
{ {
id: 'connections', id: 'connections',
title: 'Connections', title: 'Connections',
@ -206,13 +209,7 @@
'managedirectconnections', 'managedirectconnections',
'settings' 'settings'
] ]
} },
]
: []),
...($user?.role === 'admin' ||
($user?.role === 'user' && $user?.permissions?.features?.direct_tool_servers)
? [
{ {
id: 'tools', id: 'tools',
title: 'Tools', title: 'Tools',
@ -225,9 +222,7 @@
'managetoolservers', 'managetoolservers',
'settings' 'settings'
] ]
} },
]
: []),
{ {
id: 'personalization', id: 'personalization',
@ -464,28 +459,52 @@
} }
]; ];
let availableSettings = [];
let filteredSettings = [];
let search = ''; let search = '';
let visibleTabs = searchData.map((tab) => tab.id);
let searchDebounceTimeout; let searchDebounceTimeout;
const searchSettings = (query: string): string[] => { const getAvailableSettings = () => {
const lowerCaseQuery = query.toLowerCase().trim(); return allSettings.filter((tab) => {
return searchData if (tab.id === 'connections') {
.filter( return $config?.features?.enable_direct_connections;
(tab) => }
tab.title.toLowerCase().includes(lowerCaseQuery) ||
tab.keywords.some((keyword) => keyword.includes(lowerCaseQuery)) if (tab.id === 'tools') {
) return (
$user?.role === 'admin' ||
($user?.role === 'user' && $user?.permissions?.features?.direct_tool_servers)
);
}
return true;
});
};
const setFilteredSettings = () => {
filteredSettings = availableSettings
.filter((tab) => {
return (
search === '' ||
tab.title.toLowerCase().includes(search.toLowerCase().trim()) ||
tab.keywords.some((keyword) => keyword.includes(search.toLowerCase().trim()))
);
})
.map((tab) => tab.id); .map((tab) => tab.id);
if (filteredSettings.length > 0 && !filteredSettings.includes(selectedTab)) {
selectedTab = filteredSettings[0];
}
}; };
const searchDebounceHandler = () => { const searchDebounceHandler = () => {
if (searchDebounceTimeout) {
clearTimeout(searchDebounceTimeout); clearTimeout(searchDebounceTimeout);
searchDebounceTimeout = setTimeout(() => {
visibleTabs = searchSettings(search);
if (visibleTabs.length > 0 && !visibleTabs.includes(selectedTab)) {
selectedTab = visibleTabs[0];
} }
searchDebounceTimeout = setTimeout(() => {
setFilteredSettings();
}, 100); }, 100);
}; };
@ -530,11 +549,15 @@
} }
}; };
$: if (show) { onMount(() => {
addScrollListener(); availableSettings = getAvailableSettings();
} else { setFilteredSettings();
removeScrollListener();
} config.subscribe((configData) => {
availableSettings = getAvailableSettings();
setFilteredSettings();
});
});
</script> </script>
<Modal size="lg" bind:show> <Modal size="lg" bind:show>
@ -575,8 +598,8 @@
placeholder={$i18n.t('Search')} placeholder={$i18n.t('Search')}
/> />
</div> </div>
{#if visibleTabs.length > 0} {#if filteredSettings.length > 0}
{#each visibleTabs as tabId (tabId)} {#each filteredSettings as tabId (tabId)}
{#if tabId === 'general'} {#if tabId === 'general'}
<button <button
role="tab" role="tab"