Browse Source

refac: reactive user settings

Timothy Jaeryang Baek 1 month ago
parent
commit
f91da291d9

+ 4 - 1
src/lib/components/admin/Settings/Connections.svelte

@@ -6,7 +6,7 @@
 
 	import { getOllamaConfig, updateOllamaConfig } from '$lib/apis/ollama';
 	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 { config, models, settings, user } from '$lib/stores';
@@ -114,6 +114,7 @@
 		if (res) {
 			toast.success($i18n.t('Connections settings updated'));
 			await models.set(await getModels());
+			await config.set(await getBackendConfig());
 		}
 	};
 
@@ -198,6 +199,8 @@
 		updateOllamaHandler();
 
 		dispatch('save');
+
+		await config.set(await getBackendConfig());
 	};
 </script>
 

+ 83 - 60
src/lib/components/chat/SettingsModal.svelte

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