1
0
Timothy Jaeryang Baek 1 өдөр өмнө
parent
commit
2c59a28860

+ 5 - 1
src/lib/components/admin/Users/UserList/EditUserModal.svelte

@@ -87,7 +87,11 @@
 					<div class=" px-5 pt-3 pb-5 w-full">
 						<div class="flex self-center w-full">
 							<div class=" self-start h-full mr-6">
-								<UserProfileImage bind:profileImageUrl={_user.profile_image_url} user={_user} />
+								<UserProfileImage
+									imageClassName="size-14"
+									bind:profileImageUrl={_user.profile_image_url}
+									user={_user}
+								/>
 							</div>
 
 							<div class=" flex-1">

+ 3 - 1
src/lib/components/chat/Settings/Account/UserProfileImage.svelte

@@ -12,6 +12,8 @@
 	export let profileImageUrl;
 	export let user = null;
 
+	export let imageClassName = 'size-14 md:size-18';
+
 	let profileImageInputElement;
 </script>
 
@@ -89,7 +91,7 @@
 			<img
 				src={profileImageUrl !== '' ? profileImageUrl : generateInitialsImage(user?.name)}
 				alt="profile"
-				class=" rounded-full size-14 md:size-18 object-cover"
+				class=" rounded-full {imageClassName} object-cover"
 			/>
 
 			<div class="absolute bottom-0 right-0 opacity-0 group-hover:opacity-100 transition">

+ 92 - 125
src/lib/components/workspace/Models.svelte

@@ -233,17 +233,102 @@
 	/>
 
 	<div class="flex flex-col gap-1 mt-1.5">
+		<input
+			id="models-import-input"
+			bind:this={modelsImportInputElement}
+			bind:files={importFiles}
+			type="file"
+			accept=".json"
+			hidden
+			on:change={() => {
+				console.log(importFiles);
+
+				let reader = new FileReader();
+				reader.onload = async (event) => {
+					let savedModels = JSON.parse(event.target.result);
+					console.log(savedModels);
+
+					for (const model of savedModels) {
+						if (model?.info ?? false) {
+							if ($_models.find((m) => m.id === model.id)) {
+								await updateModelById(localStorage.token, model.id, model.info).catch((error) => {
+									return null;
+								});
+							} else {
+								await createNewModel(localStorage.token, model.info).catch((error) => {
+									return null;
+								});
+							}
+						} else {
+							if (model?.id && model?.name) {
+								await createNewModel(localStorage.token, model).catch((error) => {
+									return null;
+								});
+							}
+						}
+					}
+
+					await _models.set(
+						await getModels(
+							localStorage.token,
+							$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
+						)
+					);
+					models = await getWorkspaceModels(localStorage.token);
+				};
+
+				reader.readAsText(importFiles[0]);
+			}}
+		/>
 		<div class="flex justify-between items-center">
-			<div class="flex items-center md:self-center text-xl font-medium px-0.5">
-				{$i18n.t('Models')}
-				<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-50 dark:bg-gray-850" />
-				<span class="text-lg font-medium text-gray-500 dark:text-gray-300"
-					>{filteredModels.length}</span
+			<div class="flex items-center md:self-center text-xl font-medium px-0.5 gap-2 shrink-0">
+				<div>
+					{$i18n.t('Models')}
+				</div>
+
+				<div class="text-lg font-medium text-gray-500 dark:text-gray-500">
+					{filteredModels.length}
+				</div>
+			</div>
+
+			<div class="flex w-full justify-end gap-1.5">
+				{#if $user?.role === 'admin'}
+					<button
+						class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-200 transition"
+						on:click={() => {
+							modelsImportInputElement.click();
+						}}
+					>
+						<div class=" self-center font-medium line-clamp-1">
+							{$i18n.t('Import')}
+						</div>
+					</button>
+
+					{#if models.length}
+						<button
+							class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-200 transition"
+							on:click={async () => {
+								downloadModels(models);
+							}}
+						>
+							<div class=" self-center font-medium line-clamp-1">
+								{$i18n.t('Export')}
+							</div>
+						</button>
+					{/if}
+				{/if}
+				<a
+					class=" px-2 py-1 rounded-xl bg-black text-white dark:bg-white dark:text-black transition font-medium text-sm flex items-center"
+					href="/workspace/models/create"
 				>
+					<Plus className="size-3" strokeWidth="2.5" />
+
+					<div class=" hidden md:block md:ml-1 text-xs">{$i18n.t('New Model')}</div>
+				</a>
 			</div>
 		</div>
 
-		<div class=" flex flex-1 items-center w-full space-x-2">
+		<div class=" flex flex-1 items-center w-full space-x-2 py-0.5">
 			<div class="flex flex-1 items-center">
 				<div class=" self-center ml-1 mr-3">
 					<Search className="size-3.5" />
@@ -267,21 +352,12 @@
 					</div>
 				{/if}
 			</div>
-
-			<div>
-				<a
-					class=" px-2 py-2 rounded-xl hover:bg-gray-700/10 dark:hover:bg-gray-100/10 dark:text-gray-300 dark:hover:text-white transition font-medium text-sm flex items-center space-x-1"
-					href="/workspace/models/create"
-				>
-					<Plus className="size-3.5" />
-				</a>
-			</div>
 		</div>
 	</div>
 
 	{#if tags.length > 0}
 		<div
-			class=" flex w-full bg-transparent overflow-x-auto scrollbar-none"
+			class=" flex w-full bg-transparent overflow-x-auto scrollbar-none -mx-2"
 			on:wheel={(e) => {
 				if (e.deltaY !== 0) {
 					e.preventDefault();
@@ -494,115 +570,6 @@
 		{/each}
 	</div>
 
-	{#if $user?.role === 'admin'}
-		<div class=" flex justify-end w-full mb-3">
-			<div class="flex space-x-1">
-				<input
-					id="models-import-input"
-					bind:this={modelsImportInputElement}
-					bind:files={importFiles}
-					type="file"
-					accept=".json"
-					hidden
-					on:change={() => {
-						console.log(importFiles);
-
-						let reader = new FileReader();
-						reader.onload = async (event) => {
-							let savedModels = JSON.parse(event.target.result);
-							console.log(savedModels);
-
-							for (const model of savedModels) {
-								if (model?.info ?? false) {
-									if ($_models.find((m) => m.id === model.id)) {
-										await updateModelById(localStorage.token, model.id, model.info).catch(
-											(error) => {
-												return null;
-											}
-										);
-									} else {
-										await createNewModel(localStorage.token, model.info).catch((error) => {
-											return null;
-										});
-									}
-								} else {
-									if (model?.id && model?.name) {
-										await createNewModel(localStorage.token, model).catch((error) => {
-											return null;
-										});
-									}
-								}
-							}
-
-							await _models.set(
-								await getModels(
-									localStorage.token,
-									$config?.features?.enable_direct_connections &&
-										($settings?.directConnections ?? null)
-								)
-							);
-							models = await getWorkspaceModels(localStorage.token);
-						};
-
-						reader.readAsText(importFiles[0]);
-					}}
-				/>
-
-				<button
-					class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-200 transition"
-					on:click={() => {
-						modelsImportInputElement.click();
-					}}
-				>
-					<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Import Models')}</div>
-
-					<div class=" self-center">
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							viewBox="0 0 16 16"
-							fill="currentColor"
-							class="w-3.5 h-3.5"
-						>
-							<path
-								fill-rule="evenodd"
-								d="M4 2a1.5 1.5 0 0 0-1.5 1.5v9A1.5 1.5 0 0 0 4 14h8a1.5 1.5 0 0 0 1.5-1.5V6.621a1.5 1.5 0 0 0-.44-1.06L9.94 2.439A1.5 1.5 0 0 0 8.878 2H4Zm4 9.5a.75.75 0 0 1-.75-.75V8.06l-.72.72a.75.75 0 0 1-1.06-1.06l2-2a.75.75 0 0 1 1.06 0l2 2a.75.75 0 1 1-1.06 1.06l-.72-.72v2.69a.75.75 0 0 1-.75.75Z"
-								clip-rule="evenodd"
-							/>
-						</svg>
-					</div>
-				</button>
-
-				{#if models.length}
-					<button
-						class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-200 transition"
-						on:click={async () => {
-							downloadModels(models);
-						}}
-					>
-						<div class=" self-center mr-2 font-medium line-clamp-1">
-							{$i18n.t('Export Models')} ({models.length})
-						</div>
-
-						<div class=" self-center">
-							<svg
-								xmlns="http://www.w3.org/2000/svg"
-								viewBox="0 0 16 16"
-								fill="currentColor"
-								class="w-3.5 h-3.5"
-							>
-								<path
-									fill-rule="evenodd"
-									d="M4 2a1.5 1.5 0 0 0-1.5 1.5v9A1.5 1.5 0 0 0 4 14h8a1.5 1.5 0 0 0 1.5-1.5V6.621a1.5 1.5 0 0 0-.44-1.06L9.94 2.439A1.5 1.5 0 0 0 8.878 2H4Zm4 3.5a.75.75 0 0 1 .75.75v2.69l.72-.72a.75.75 0 1 1 1.06 1.06l-2 2a.75.75 0 0 1-1.06 0l-2-2a.75.75 0 0 1 1.06-1.06l.72.72V6.25A.75.75 0 0 1 8 5.5Z"
-									clip-rule="evenodd"
-								/>
-							</svg>
-						</div>
-					</button>
-				{/if}
-			</div>
-		</div>
-	{/if}
-
 	{#if $config?.features.enable_community_sharing}
 		<div class=" my-16">
 			<div class=" text-xl font-medium mb-1 line-clamp-1">