"...lm-evaluation-harness.git" did not exist on "db97d7f8a406186d257955049046e92ee9a426cd"
SettingsModal.svelte 11.1 KB
Newer Older
Timothy J. Baek's avatar
Timothy J. Baek committed
1
<script lang="ts">
2
	import { getContext } from 'svelte';
Jannik Streidl's avatar
Jannik Streidl committed
3
	import { toast } from 'svelte-sonner';
Timothy J. Baek's avatar
Timothy J. Baek committed
4
	import { models, settings, user } from '$lib/stores';
5

Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
6
	import { getModels as _getModels } from '$lib/apis';
Timothy J. Baek's avatar
Timothy J. Baek committed
7
8

	import Modal from '../common/Modal.svelte';
9
	import Account from './Settings/Account.svelte';
Timothy J. Baek's avatar
Timothy J. Baek committed
10
11
12
13
	import About from './Settings/About.svelte';
	import Models from './Settings/Models.svelte';
	import General from './Settings/General.svelte';
	import Interface from './Settings/Interface.svelte';
Timothy J. Baek's avatar
Timothy J. Baek committed
14
	import Audio from './Settings/Audio.svelte';
Timothy J. Baek's avatar
Timothy J. Baek committed
15
	import Chats from './Settings/Chats.svelte';
16
	import Connections from './Settings/Connections.svelte';
17
18
	import User from '../icons/User.svelte';
	import Personalization from './Settings/Personalization.svelte';
19
	import { updateUserSettings } from '$lib/apis/users';
20

21
22
	const i18n = getContext('i18n');

Timothy J. Baek's avatar
Timothy J. Baek committed
23
	export let show = false;
24
25
26
27

	const saveSettings = async (updated) => {
		console.log(updated);
		await settings.set({ ...$settings, ...updated });
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
28
		await models.set(await getModels());
29
		await updateUserSettings(localStorage.token, { ui: $settings });
30
	};
31

Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
32
33
	const getModels = async () => {
		return await _getModels(localStorage.token);
34
35
	};

36
	let selectedTab = 'general';
Timothy J. Baek's avatar
Timothy J. Baek committed
37
38
39
</script>

<Modal bind:show>
Timothy J. Baek's avatar
Timothy J. Baek committed
40
	<div class="text-gray-700 dark:text-gray-100">
Timothy J. Baek's avatar
Timothy J. Baek committed
41
		<div class=" flex justify-between dark:text-gray-300 px-5 pt-4 pb-1">
42
			<div class=" text-lg font-medium self-center">{$i18n.t('Settings')}</div>
Timothy J. Baek's avatar
Timothy J. Baek committed
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
			<button
				class="self-center"
				on:click={() => {
					show = false;
				}}
			>
				<svg
					xmlns="http://www.w3.org/2000/svg"
					viewBox="0 0 20 20"
					fill="currentColor"
					class="w-5 h-5"
				>
					<path
						d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"
					/>
				</svg>
			</button>
		</div>

Timothy J. Baek's avatar
Timothy J. Baek committed
62
63
		<div class="flex flex-col md:flex-row w-full p-4 md:space-x-4">
			<div
Timothy J. Baek's avatar
Timothy J. Baek committed
64
				class="tabs flex flex-row overflow-x-auto space-x-1 md:space-x-0 md:space-y-1 md:flex-col flex-1 md:flex-none md:w-40 dark:text-gray-200 text-xs text-left mb-3 md:mb-0"
Timothy J. Baek's avatar
Timothy J. Baek committed
65
66
			>
				<button
67
					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
Timothy J. Baek's avatar
Timothy J. Baek committed
68
					'general'
Timothy J. Baek's avatar
Timothy J. Baek committed
69
70
						? 'bg-gray-200 dark:bg-gray-700'
						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
Timothy J. Baek's avatar
Timothy J. Baek committed
71
					on:click={() => {
72
						selectedTab = 'general';
Timothy J. Baek's avatar
Timothy J. Baek committed
73
					}}
Timothy J. Baek's avatar
Timothy J. Baek committed
74
				>
Timothy J. Baek's avatar
Timothy J. Baek committed
75
76
77
78
79
80
81
82
83
84
85
86
87
88
					<div class=" self-center mr-2">
						<svg
							xmlns="http://www.w3.org/2000/svg"
							viewBox="0 0 20 20"
							fill="currentColor"
							class="w-4 h-4"
						>
							<path
								fill-rule="evenodd"
								d="M8.34 1.804A1 1 0 019.32 1h1.36a1 1 0 01.98.804l.295 1.473c.497.144.971.342 1.416.587l1.25-.834a1 1 0 011.262.125l.962.962a1 1 0 01.125 1.262l-.834 1.25c.245.445.443.919.587 1.416l1.473.294a1 1 0 01.804.98v1.361a1 1 0 01-.804.98l-1.473.295a6.95 6.95 0 01-.587 1.416l.834 1.25a1 1 0 01-.125 1.262l-.962.962a1 1 0 01-1.262.125l-1.25-.834a6.953 6.953 0 01-1.416.587l-.294 1.473a1 1 0 01-.98.804H9.32a1 1 0 01-.98-.804l-.295-1.473a6.957 6.957 0 01-1.416-.587l-1.25.834a1 1 0 01-1.262-.125l-.962-.962a1 1 0 01-.125-1.262l.834-1.25a6.957 6.957 0 01-.587-1.416l-1.473-.294A1 1 0 011 10.68V9.32a1 1 0 01.804-.98l1.473-.295c.144-.497.342-.971.587-1.416l-.834-1.25a1 1 0 01.125-1.262l.962-.962A1 1 0 015.38 3.03l1.25.834a6.957 6.957 0 011.416-.587l.294-1.473zM13 10a3 3 0 11-6 0 3 3 0 016 0z"
								clip-rule="evenodd"
							/>
						</svg>
					</div>
89
					<div class=" self-center">{$i18n.t('General')}</div>
Timothy J. Baek's avatar
Timothy J. Baek committed
90
91
				</button>

92
93
94
				{#if $user?.role === 'admin'}
					<button
						class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
95
						'connections'
96
97
98
							? 'bg-gray-200 dark:bg-gray-700'
							: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
						on:click={() => {
99
							selectedTab = 'connections';
100
101
102
103
104
						}}
					>
						<div class=" self-center mr-2">
							<svg
								xmlns="http://www.w3.org/2000/svg"
Timothy J. Baek's avatar
Timothy J. Baek committed
105
								viewBox="0 0 16 16"
106
107
108
109
								fill="currentColor"
								class="w-4 h-4"
							>
								<path
Timothy J. Baek's avatar
Timothy J. Baek committed
110
									d="M1 9.5A3.5 3.5 0 0 0 4.5 13H12a3 3 0 0 0 .917-5.857 2.503 2.503 0 0 0-3.198-3.019 3.5 3.5 0 0 0-6.628 2.171A3.5 3.5 0 0 0 1 9.5Z"
111
112
113
								/>
							</svg>
						</div>
114
						<div class=" self-center">{$i18n.t('Connections')}</div>
115
					</button>
116
				{/if}
117

118
				<button
119
					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
Timothy J. Baek's avatar
Timothy J. Baek committed
120
					'interface'
Timothy J. Baek's avatar
Timothy J. Baek committed
121
122
						? 'bg-gray-200 dark:bg-gray-700'
						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
123
					on:click={() => {
Timothy J. Baek's avatar
Timothy J. Baek committed
124
						selectedTab = 'interface';
125
126
127
128
129
					}}
				>
					<div class=" self-center mr-2">
						<svg
							xmlns="http://www.w3.org/2000/svg"
Timothy J. Baek's avatar
Timothy J. Baek committed
130
							viewBox="0 0 16 16"
131
132
133
134
							fill="currentColor"
							class="w-4 h-4"
						>
							<path
Timothy J. Baek's avatar
Timothy J. Baek committed
135
								fill-rule="evenodd"
Timothy J. Baek's avatar
Timothy J. Baek committed
136
								d="M2 4.25A2.25 2.25 0 0 1 4.25 2h7.5A2.25 2.25 0 0 1 14 4.25v5.5A2.25 2.25 0 0 1 11.75 12h-1.312c.1.128.21.248.328.36a.75.75 0 0 1 .234.545v.345a.75.75 0 0 1-.75.75h-4.5a.75.75 0 0 1-.75-.75v-.345a.75.75 0 0 1 .234-.545c.118-.111.228-.232.328-.36H4.25A2.25 2.25 0 0 1 2 9.75v-5.5Zm2.25-.75a.75.75 0 0 0-.75.75v4.5c0 .414.336.75.75.75h7.5a.75.75 0 0 0 .75-.75v-4.5a.75.75 0 0 0-.75-.75h-7.5Z"
Timothy J. Baek's avatar
Timothy J. Baek committed
137
138
139
140
								clip-rule="evenodd"
							/>
						</svg>
					</div>
141
					<div class=" self-center">{$i18n.t('Interface')}</div>
Timothy J. Baek's avatar
Timothy J. Baek committed
142
143
				</button>

Timothy J. Baek's avatar
Timothy J. Baek committed
144
145
				<button
					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
146
					'personalization'
Timothy J. Baek's avatar
Timothy J. Baek committed
147
148
149
						? 'bg-gray-200 dark:bg-gray-700'
						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
					on:click={() => {
150
						selectedTab = 'personalization';
Timothy J. Baek's avatar
Timothy J. Baek committed
151
152
153
					}}
				>
					<div class=" self-center mr-2">
154
						<User />
Timothy J. Baek's avatar
Timothy J. Baek committed
155
					</div>
156
					<div class=" self-center">{$i18n.t('Personalization')}</div>
Timothy J. Baek's avatar
Timothy J. Baek committed
157
158
				</button>

Timothy J. Baek's avatar
Timothy J. Baek committed
159
160
				<button
					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
Timothy J. Baek's avatar
Timothy J. Baek committed
161
					'audio'
Timothy J. Baek's avatar
Timothy J. Baek committed
162
163
164
						? 'bg-gray-200 dark:bg-gray-700'
						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
					on:click={() => {
Timothy J. Baek's avatar
Timothy J. Baek committed
165
						selectedTab = 'audio';
Timothy J. Baek's avatar
Timothy J. Baek committed
166
167
168
169
170
171
172
173
174
175
176
177
178
179
					}}
				>
					<div class=" self-center mr-2">
						<svg
							xmlns="http://www.w3.org/2000/svg"
							viewBox="0 0 16 16"
							fill="currentColor"
							class="w-4 h-4"
						>
							<path
								d="M7.557 2.066A.75.75 0 0 1 8 2.75v10.5a.75.75 0 0 1-1.248.56L3.59 11H2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h1.59l3.162-2.81a.75.75 0 0 1 .805-.124ZM12.95 3.05a.75.75 0 1 0-1.06 1.06 5.5 5.5 0 0 1 0 7.78.75.75 0 1 0 1.06 1.06 7 7 0 0 0 0-9.9Z"
							/>
							<path
								d="M10.828 5.172a.75.75 0 1 0-1.06 1.06 2.5 2.5 0 0 1 0 3.536.75.75 0 1 0 1.06 1.06 4 4 0 0 0 0-5.656Z"
180
181
182
							/>
						</svg>
					</div>
183
					<div class=" self-center">{$i18n.t('Audio')}</div>
184
				</button>
Timothy J. Baek's avatar
Timothy J. Baek committed
185

186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
				<button
					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
					'chats'
						? 'bg-gray-200 dark:bg-gray-700'
						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
					on:click={() => {
						selectedTab = 'chats';
					}}
				>
					<div class=" self-center mr-2">
						<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="M8 2C4.262 2 1 4.57 1 8c0 1.86.98 3.486 2.455 4.566a3.472 3.472 0 0 1-.469 1.26.75.75 0 0 0 .713 1.14 6.961 6.961 0 0 0 3.06-1.06c.403.062.818.094 1.241.094 3.738 0 7-2.57 7-6s-3.262-6-7-6ZM5 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2Zm7-1a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM8 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"
								clip-rule="evenodd"
							/>
						</svg>
					</div>
209
					<div class=" self-center">{$i18n.t('Chats')}</div>
210
211
				</button>

Timothy J. Baek's avatar
Timothy J. Baek committed
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
				<button
					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
					'account'
						? 'bg-gray-200 dark:bg-gray-700'
						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
					on:click={() => {
						selectedTab = 'account';
					}}
				>
					<div class=" self-center mr-2">
						<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="M15 8A7 7 0 1 1 1 8a7 7 0 0 1 14 0Zm-5-2a2 2 0 1 1-4 0 2 2 0 0 1 4 0ZM8 9c-1.825 0-3.422.977-4.295 2.437A5.49 5.49 0 0 0 8 13.5a5.49 5.49 0 0 0 4.294-2.063A4.997 4.997 0 0 0 8 9Z"
								clip-rule="evenodd"
							/>
						</svg>
					</div>
235
					<div class=" self-center">{$i18n.t('Account')}</div>
Timothy J. Baek's avatar
Timothy J. Baek committed
236
237
				</button>

Timothy J. Baek's avatar
Timothy J. Baek committed
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
				<button
					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
					'about'
						? 'bg-gray-200 dark:bg-gray-700'
						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
					on:click={() => {
						selectedTab = 'about';
					}}
				>
					<div class=" self-center mr-2">
						<svg
							xmlns="http://www.w3.org/2000/svg"
							viewBox="0 0 20 20"
							fill="currentColor"
							class="w-4 h-4"
						>
							<path
								fill-rule="evenodd"
								d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z"
								clip-rule="evenodd"
							/>
						</svg>
					</div>
261
					<div class=" self-center">{$i18n.t('About')}</div>
Timothy J. Baek's avatar
Timothy J. Baek committed
262
				</button>
Timothy J. Baek's avatar
Timothy J. Baek committed
263
			</div>
Timothy J. Baek's avatar
Timothy J. Baek committed
264
			<div class="flex-1 md:min-h-[28rem]">
265
				{#if selectedTab === 'general'}
Timothy J. Baek's avatar
Timothy J. Baek committed
266
					<General
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
267
						{getModels}
Timothy J. Baek's avatar
Timothy J. Baek committed
268
269
						{saveSettings}
						on:save={() => {
270
							toast.success($i18n.t('Settings saved successfully!'));
Timothy J. Baek's avatar
Timothy J. Baek committed
271
272
						}}
					/>
273
274
				{:else if selectedTab === 'connections'}
					<Connections
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
275
						{getModels}
Timothy J. Baek's avatar
Timothy J. Baek committed
276
						on:save={() => {
277
							toast.success($i18n.t('Settings saved successfully!'));
278
						}}
Timothy J. Baek's avatar
Timothy J. Baek committed
279
					/>
280
				{:else if selectedTab === 'interface'}
Timothy J. Baek's avatar
Timothy J. Baek committed
281
					<Interface
Timothy J. Baek's avatar
Timothy J. Baek committed
282
						{saveSettings}
Timothy J. Baek's avatar
Timothy J. Baek committed
283
						on:save={() => {
284
							toast.success($i18n.t('Settings saved successfully!'));
285
						}}
Timothy J. Baek's avatar
Timothy J. Baek committed
286
					/>
287
288
289
290
291
292
293
				{:else if selectedTab === 'personalization'}
					<Personalization
						{saveSettings}
						on:save={() => {
							toast.success($i18n.t('Settings saved successfully!'));
						}}
					/>
Timothy J. Baek's avatar
Timothy J. Baek committed
294
295
				{:else if selectedTab === 'audio'}
					<Audio
Timothy J. Baek's avatar
Timothy J. Baek committed
296
297
						{saveSettings}
						on:save={() => {
298
							toast.success($i18n.t('Settings saved successfully!'));
Timothy J. Baek's avatar
Timothy J. Baek committed
299
						}}
Timothy J. Baek's avatar
Timothy J. Baek committed
300
					/>
301
				{:else if selectedTab === 'chats'}
Timothy J. Baek's avatar
Timothy J. Baek committed
302
					<Chats {saveSettings} />
303
				{:else if selectedTab === 'account'}
304
305
					<Account
						saveHandler={() => {
306
							toast.success($i18n.t('Settings saved successfully!'));
307
						}}
308
					/>
Timothy J. Baek's avatar
Timothy J. Baek committed
309
				{:else if selectedTab === 'about'}
Timothy J. Baek's avatar
Timothy J. Baek committed
310
					<About />
Timothy J. Baek's avatar
Timothy J. Baek committed
311
312
				{/if}
			</div>
Timothy J. Baek's avatar
Timothy J. Baek committed
313
		</div>
Timothy J. Baek's avatar
Timothy J. Baek committed
314
315
	</div>
</Modal>
316
317
318
319
320
321
322
323
324

<style>
	input::-webkit-outer-spin-button,
	input::-webkit-inner-spin-button {
		/* display: none; <- Crashes Chrome on hover */
		-webkit-appearance: none;
		margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
	}

325
326
327
328
329
330
331
332
333
	.tabs::-webkit-scrollbar {
		display: none; /* for Chrome, Safari and Opera */
	}

	.tabs {
		-ms-overflow-style: none; /* IE and Edge */
		scrollbar-width: none; /* Firefox */
	}

334
335
336
337
	input[type='number'] {
		-moz-appearance: textfield; /* Firefox */
	}
</style>