refac: styling

This commit is contained in:
Timothy Jaeryang Baek
2025-11-30 03:47:34 -05:00
parent e65d92fc6f
commit 9d39b9b42c
13 changed files with 409 additions and 339 deletions
@@ -23,6 +23,8 @@
import DefaultFiltersSelector from './DefaultFiltersSelector.svelte';
import DefaultFeatures from './DefaultFeatures.svelte';
import PromptSuggestions from './PromptSuggestions.svelte';
import AccessControlModal from '../common/AccessControlModal.svelte';
import LockClosed from '$lib/components/icons/LockClosed.svelte';
const i18n = getContext('i18n');
@@ -42,6 +44,7 @@
let showAdvanced = false;
let showPreview = false;
let showAccessControlModal = false;
let loaded = false;
@@ -317,6 +320,14 @@
</script>
{#if loaded}
<AccessControlModal
bind:show={showAccessControlModal}
bind:accessControl
accessRoles={['read', 'write']}
share={$user?.permissions?.sharing?.models || $user?.role === 'admin'}
sharePublic={$user?.permissions?.sharing?.public_models || $user?.role === 'admin'}
/>
{#if onBack}
<button
class="flex space-x-1"
@@ -434,13 +445,13 @@
<img
src={info.meta.profile_image_url}
alt="model profile"
class="rounded-xl size-72 md:size-60 object-cover shrink-0"
class="rounded-xl sm:size-60 size-max object-cover shrink-0"
/>
{:else}
<img
src="{WEBUI_BASE_URL}/static/favicon.png"
alt="model profile"
class=" rounded-xl size-72 md:size-60 object-cover shrink-0"
class=" rounded-xl sm:size-60 size-max object-cover shrink-0"
/>
{/if}
@@ -485,124 +496,139 @@
</div>
<div class="w-full">
<div class="mt-2 my-2 flex flex-col">
<div class="flex-1">
<div>
<input
class="text-3xl font-medium w-full bg-transparent outline-hidden"
placeholder={$i18n.t('Model Name')}
bind:value={name}
required
/>
<div class="flex flex-col">
<div class="flex justify-between items-start my-2">
<div class=" flex flex-col">
<div class="flex-1">
<div>
<input
class="text-4xl font-medium w-full bg-transparent outline-hidden"
placeholder={$i18n.t('Model Name')}
bind:value={name}
required
/>
</div>
</div>
<div class="flex-1">
<div>
<input
class="text-xs w-full bg-transparent outline-hidden"
placeholder={$i18n.t('Model ID')}
bind:value={id}
disabled={edit}
required
/>
</div>
</div>
</div>
</div>
<div class="flex-1">
<div>
<input
class="text-xs w-full bg-transparent text-gray-500 outline-hidden"
placeholder={$i18n.t('Model ID')}
bind:value={id}
disabled={edit}
required
/>
</div>
</div>
</div>
{#if preset}
<div class="my-1">
<div class=" text-sm font-medium mb-1">{$i18n.t('Base Model (From)')}</div>
<div>
<select
class="text-sm w-full bg-transparent outline-hidden"
placeholder={$i18n.t('Select a base model (e.g. llama3, gpt-4o)')}
bind:value={info.base_model_id}
on:change={(e) => {
addUsage(e.target.value);
<button
class="bg-gray-50 hover:bg-gray-100 text-black dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-white transition px-2 py-1 rounded-full flex gap-1 items-center"
type="button"
on:click={() => {
showAccessControlModal = true;
}}
required
>
<option value={null} class=" text-gray-900"
>{$i18n.t('Select a base model')}</option
>
{#each $models.filter((m) => (model ? m.id !== model.id : true) && !m?.preset && m?.owned_by !== 'arena' && !(m?.direct ?? false)) as model}
<option value={model.id} class=" text-gray-900">{model.name}</option>
{/each}
</select>
<LockClosed strokeWidth="2.5" className="size-3.5" />
<div class="text-sm font-medium shrink-0">
{$i18n.t('Access')}
</div>
</button>
</div>
</div>
{/if}
<div class="my-1">
<div class="mb-1 flex w-full justify-between items-center">
<div class=" self-center text-sm font-medium">{$i18n.t('Description')}</div>
{#if preset}
<div class="mb-1">
<div class=" text-xs font-medium mb-1 text-gray-500">
{$i18n.t('Base Model (From)')}
</div>
<button
class="p-1 text-xs flex rounded-sm transition"
type="button"
aria-pressed={enableDescription ? 'true' : 'false'}
aria-label={enableDescription
? $i18n.t('Custom description enabled')
: $i18n.t('Default description enabled')}
on:click={() => {
enableDescription = !enableDescription;
}}
>
{#if !enableDescription}
<span class="ml-2 self-center">{$i18n.t('Default')}</span>
{:else}
<span class="ml-2 self-center">{$i18n.t('Custom')}</span>
{/if}
</button>
</div>
{#if enableDescription}
<Textarea
className=" text-sm w-full bg-transparent outline-hidden resize-none overflow-y-hidden "
placeholder={$i18n.t('Add a short description about what this model does')}
bind:value={info.meta.description}
/>
<div>
<select
class="text-sm w-full bg-transparent outline-hidden"
placeholder={$i18n.t('Select a base model (e.g. llama3, gpt-4o)')}
bind:value={info.base_model_id}
on:change={(e) => {
addUsage(e.target.value);
}}
required
>
<option value={null} class=" text-gray-900"
>{$i18n.t('Select a base model')}</option
>
{#each $models.filter((m) => (model ? m.id !== model.id : true) && !m?.preset && m?.owned_by !== 'arena' && !(m?.direct ?? false)) as model}
<option value={model.id} class=" text-gray-900">{model.name}</option>
{/each}
</select>
</div>
</div>
{/if}
</div>
<div class=" mt-2 my-1">
<div class="">
<Tags
tags={info?.meta?.tags ?? []}
on:delete={(e) => {
const tagName = e.detail;
info.meta.tags = info.meta.tags.filter((tag) => tag.name !== tagName);
}}
on:add={(e) => {
const tagName = e.detail;
if (!(info?.meta?.tags ?? null)) {
info.meta.tags = [{ name: tagName }];
} else {
info.meta.tags = [...info.meta.tags, { name: tagName }];
}
}}
/>
<div class="mb-1">
<div class="mb-1 flex w-full justify-between items-center">
<div class=" self-center text-xs font-medium text-gray-500">
{$i18n.t('Description')}
</div>
<button
class="p-1 text-xs flex rounded-sm transition"
type="button"
aria-pressed={enableDescription ? 'true' : 'false'}
aria-label={enableDescription
? $i18n.t('Custom description enabled')
: $i18n.t('Default description enabled')}
on:click={() => {
enableDescription = !enableDescription;
}}
>
{#if !enableDescription}
<span class="ml-2 self-center">{$i18n.t('Default')}</span>
{:else}
<span class="ml-2 self-center">{$i18n.t('Custom')}</span>
{/if}
</button>
</div>
{#if enableDescription}
<Textarea
className=" text-sm w-full bg-transparent outline-hidden resize-none overflow-y-hidden "
placeholder={$i18n.t('Add a short description about what this model does')}
bind:value={info.meta.description}
/>
{/if}
</div>
<div class="w-full mb-1 max-w-full">
<div class="">
<Tags
tags={info?.meta?.tags ?? []}
on:delete={(e) => {
const tagName = e.detail;
info.meta.tags = info.meta.tags.filter((tag) => tag.name !== tagName);
}}
on:add={(e) => {
const tagName = e.detail;
if (!(info?.meta?.tags ?? null)) {
info.meta.tags = [{ name: tagName }];
} else {
info.meta.tags = [...info.meta.tags, { name: tagName }];
}
}}
/>
</div>
</div>
</div>
<div class="my-2">
<div class="px-4 py-3 bg-gray-50 dark:bg-gray-950 rounded-3xl">
<AccessControl
bind:accessControl
accessRoles={['read', 'write']}
share={$user?.permissions?.sharing?.models || $user?.role === 'admin'}
sharePublic={$user?.permissions?.sharing?.public_models || $user?.role === 'admin'}
/>
</div>
</div>
<hr class=" border-gray-100 dark:border-gray-850 my-1.5" />
<hr class=" border-gray-100/30 dark:border-gray-850/30 my-2" />
<div class="my-2">
<div class="flex w-full justify-between">
<div class=" self-center text-sm font-medium">{$i18n.t('Model Params')}</div>
<div class=" self-center text-xs font-medium text-gray-500">
{$i18n.t('Model Params')}
</div>
</div>
<div class="mt-2">
@@ -648,12 +674,12 @@
</div>
</div>
<hr class=" border-gray-100 dark:border-gray-850 my-2" />
<hr class=" border-gray-100/30 dark:border-gray-850/30 my-2" />
<div class="my-2">
<div class="flex w-full justify-between items-center">
<div class="flex w-full justify-between items-center">
<div class=" self-center text-sm font-medium">
<div class=" self-center text-xs font-medium text-gray-500">
{$i18n.t('Prompts')}
</div>
@@ -682,8 +708,6 @@
{/if}
</div>
<hr class=" border-gray-100 dark:border-gray-850 my-1.5" />
<div class="my-2">
<Knowledge bind:selectedItems={knowledge} />
</div>
@@ -743,7 +767,33 @@
{/if}
{/if}
<div class="my-2 text-gray-300 dark:text-gray-700">
<hr class=" border-gray-100/30 dark:border-gray-850/30 my-2" />
<div class="my-2 flex justify-end">
<button
class=" text-sm px-3 py-2 transition rounded-lg {loading
? ' cursor-not-allowed bg-black hover:bg-gray-900 text-white dark:bg-white dark:hover:bg-gray-100 dark:text-black'
: 'bg-black hover:bg-gray-900 text-white dark:bg-white dark:hover:bg-gray-100 dark:text-black'} flex w-full justify-center"
type="submit"
disabled={loading}
>
<div class=" self-center font-medium">
{#if edit}
{$i18n.t('Save & Update')}
{:else}
{$i18n.t('Save & Create')}
{/if}
</div>
{#if loading}
<div class="ml-1.5 self-center">
<Spinner />
</div>
{/if}
</button>
</div>
<div class="my-2 text-gray-300 dark:text-gray-700 pb-20">
<div class="flex w-full justify-between mb-2">
<div class=" self-center text-sm font-medium">{$i18n.t('JSON Preview')}</div>
@@ -774,30 +824,6 @@
</div>
{/if}
</div>
<div class="my-2 flex justify-end pb-20">
<button
class=" text-sm px-3 py-2 transition rounded-lg {loading
? ' cursor-not-allowed bg-black hover:bg-gray-900 text-white dark:bg-white dark:hover:bg-gray-100 dark:text-black'
: 'bg-black hover:bg-gray-900 text-white dark:bg-white dark:hover:bg-gray-100 dark:text-black'} flex w-full justify-center"
type="submit"
disabled={loading}
>
<div class=" self-center font-medium">
{#if edit}
{$i18n.t('Save & Update')}
{:else}
{$i18n.t('Save & Create')}
{/if}
</div>
{#if loading}
<div class="ml-1.5 self-center">
<Spinner />
</div>
{/if}
</button>
</div>
</div>
</form>
{/if}