Skip to content

Commit 315e56b

Browse files
nsarrazingary149
andauthored
Make assistant settings form fill the modal (#900)
* Make assistant settings form fill the modal * tweaks * Use layout groups instead of parsing the url * fix console error & overflows * scroll on dialog instead --------- Co-authored-by: Victor Mustar <[email protected]>
1 parent 8e839b8 commit 315e56b

File tree

16 files changed

+157
-131
lines changed

16 files changed

+157
-131
lines changed

src/lib/components/AssistantSettings.svelte

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
import { base } from "$app/paths";
99
import CarbonPen from "~icons/carbon/pen";
1010
import CarbonUpload from "~icons/carbon/upload";
11+
1112
import { useSettingsStore } from "$lib/stores/settings";
12-
import IconLoading from "./icons/IconLoading.svelte";
1313
1414
type ActionData = {
1515
error: boolean;
@@ -75,7 +75,7 @@
7575

7676
<form
7777
method="POST"
78-
class="flex h-full flex-col"
78+
class="flex h-full flex-col overflow-y-auto p-4 md:p-8"
7979
enctype="multipart/form-data"
8080
use:enhance={async ({ formData }) => {
8181
loading = true;
@@ -110,7 +110,9 @@
110110
}}
111111
>
112112
{#if assistant}
113-
<h2 class="text-xl font-semibold">Edit assistant ({assistant?.name ?? ""})</h2>
113+
<h2 class="text-xl font-semibold">
114+
Edit {assistant?.name ?? "assistant"}
115+
</h2>
114116
<p class="mb-6 text-sm text-gray-500">
115117
Modifying an existing assistant will propagate those changes to all users.
116118
</p>
@@ -123,10 +125,10 @@
123125
</p>
124126
{/if}
125127

126-
<div class="mx-1 grid flex-1 grid-cols-2 gap-4 max-sm:grid-cols-1">
128+
<div class="grid h-full w-full flex-1 grid-cols-2 gap-6 text-sm max-sm:grid-cols-1">
127129
<div class="flex flex-col gap-4">
128130
<div>
129-
<span class="mb-1 block pb-2 text-sm font-semibold">Avatar</span>
131+
<div class="mb-1 block pb-2 text-sm font-semibold">Avatar</div>
130132
<input
131133
type="file"
132134
accept="image/*"
@@ -185,7 +187,7 @@
185187
</div>
186188

187189
<label>
188-
<span class="mb-1 text-sm font-semibold">Name</span>
190+
<div class="mb-1 font-semibold">Name</div>
189191
<input
190192
name="name"
191193
class="w-full rounded-lg border-2 border-gray-200 bg-gray-100 p-2"
@@ -196,18 +198,18 @@
196198
</label>
197199

198200
<label>
199-
<span class="mb-1 text-sm font-semibold">Description</span>
201+
<div class="mb-1 font-semibold">Description</div>
200202
<textarea
201203
name="description"
202-
class="w-full rounded-lg border-2 border-gray-200 bg-gray-100 p-2"
204+
class="h-15 w-full rounded-lg border-2 border-gray-200 bg-gray-100 p-2"
203205
placeholder="He knows everything about python"
204206
value={assistant?.description ?? ""}
205207
/>
206208
<p class="text-xs text-red-500">{getError("description", form)}</p>
207209
</label>
208210

209211
<label>
210-
<span class="mb-1 text-sm font-semibold">Model</span>
212+
<div class="mb-1 font-semibold">Model</div>
211213
<select name="modelId" class="w-full rounded-lg border-2 border-gray-200 bg-gray-100 p-2">
212214
{#each models.filter((model) => !model.unlisted) as model}
213215
<option
@@ -222,8 +224,8 @@
222224
</label>
223225

224226
<label>
225-
<span class="mb-1 text-sm font-semibold">User start messages</span>
226-
<div class="flex flex-col gap-2 md:max-h-32">
227+
<div class="mb-1 font-semibold">User start messages</div>
228+
<div class="flex flex-col gap-2">
227229
<input
228230
name="exampleInput1"
229231
bind:value={inputMessage1}
@@ -256,7 +258,7 @@
256258
</div>
257259

258260
<label class="flex flex-col">
259-
<span class="mb-1 text-sm font-semibold"> Instructions (system prompt) </span>
261+
<div class="mb-1 text-sm font-semibold">Instructions (system prompt)</div>
260262
<textarea
261263
name="preprompt"
262264
class="min-h-[8lh] flex-1 rounded-lg border-2 border-gray-200 bg-gray-100 p-2 text-sm"
@@ -267,24 +269,23 @@
267269
</label>
268270
</div>
269271

270-
<div class="mt-5 flex justify-end gap-2">
272+
<div class="mt-6 flex justify-end gap-2">
271273
<a
272274
href={assistant ? `${base}/settings/assistants/${assistant?._id}` : `${base}/settings`}
273-
class="rounded-full bg-gray-200 px-8 py-2 font-semibold text-gray-600">Cancel</a
275+
class="flex items-center justify-center rounded-full bg-gray-200 px-5 py-2 font-semibold text-gray-600"
274276
>
277+
Cancel
278+
</a>
275279
<button
276280
type="submit"
277281
disabled={loading}
278282
aria-disabled={loading}
279-
class="rounded-full bg-black px-8 py-2 font-semibold md:px-20"
283+
class="flex items-center justify-center rounded-full bg-black px-8 py-2 font-semibold"
280284
class:bg-gray-200={loading}
281285
class:text-gray-600={loading}
282286
class:text-white={!loading}
283287
>
284288
{assistant ? "Save" : "Create"}
285-
{#if loading}
286-
<IconLoading classNames="ml-2 h-min" />
287-
{/if}
288289
</button>
289290
</div>
290291
</form>
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<script lang="ts">
2+
import { onMount } from "svelte";
3+
import { base } from "$app/paths";
4+
import { afterNavigate, goto } from "$app/navigation";
5+
import { page } from "$app/stores";
6+
import { useSettingsStore } from "$lib/stores/settings";
7+
import CarbonClose from "~icons/carbon/close";
8+
import CarbonArrowUpRight from "~icons/carbon/ArrowUpRight";
9+
import CarbonAdd from "~icons/carbon/add";
10+
11+
import UserIcon from "~icons/carbon/user";
12+
import type { LayoutData } from "../$types";
13+
14+
export let data: LayoutData;
15+
16+
let previousPage: string = base;
17+
let assistantsSection: HTMLHeadingElement;
18+
19+
onMount(() => {
20+
if ($page.params?.assistantId) {
21+
assistantsSection.scrollIntoView();
22+
}
23+
});
24+
25+
afterNavigate(({ from }) => {
26+
if (!from?.url.pathname.includes("settings")) {
27+
previousPage = from?.url.toString() || previousPage;
28+
}
29+
});
30+
31+
const settings = useSettingsStore();
32+
</script>
33+
34+
<div
35+
class="grid h-full w-full grid-cols-1 grid-rows-[auto,1fr] content-start gap-x-8 overflow-hidden p-4 md:grid-cols-3 md:grid-rows-[auto,1fr] md:p-8"
36+
>
37+
<div class="col-span-1 mb-4 flex items-center justify-between md:col-span-3">
38+
<h2 class="text-xl font-bold">Settings</h2>
39+
<button
40+
class="btn rounded-lg"
41+
on:click={() => {
42+
goto(previousPage);
43+
}}
44+
>
45+
<CarbonClose class="text-xl text-gray-900 hover:text-black" />
46+
</button>
47+
</div>
48+
<div
49+
class="col-span-1 flex flex-col overflow-y-auto whitespace-nowrap max-md:-mx-4 max-md:h-[245px] max-md:border max-md:border-b-2 md:pr-6"
50+
>
51+
<h3 class="pb-3 pl-3 pt-2 text-[.8rem] text-gray-800 sm:pl-1">Models</h3>
52+
53+
{#each data.models.filter((el) => !el.unlisted) as model}
54+
<a
55+
href="{base}/settings/{model.id}"
56+
class="group flex h-10 flex-none items-center gap-2 pl-3 pr-2 text-sm text-gray-500 hover:bg-gray-100 md:rounded-xl
57+
{model.id === $page.params.model ? '!bg-gray-100 !text-gray-800' : ''}"
58+
>
59+
<div class="truncate">{model.displayName}</div>
60+
{#if model.id === $settings.activeModel}
61+
<div
62+
class="ml-auto rounded-lg bg-black px-2 py-1.5 text-xs font-semibold leading-none text-white"
63+
>
64+
Active
65+
</div>
66+
{/if}
67+
</a>
68+
{/each}
69+
<!-- if its huggingchat, the number of assistants owned by the user must be non-zero to show the UI -->
70+
{#if data.enableAssistants}
71+
<h3 bind:this={assistantsSection} class="pb-3 pl-3 pt-5 text-[.8rem] text-gray-800 sm:pl-1">
72+
Assistants
73+
</h3>
74+
{#if !data.loginEnabled || (data.loginEnabled && !!data.user)}
75+
<a
76+
href="{base}/settings/assistants/new"
77+
class="group flex h-10 flex-none items-center gap-2 pl-3 pr-2 text-sm text-gray-500 hover:bg-gray-100 md:rounded-xl
78+
{$page.url.pathname === `${base}/settings/assistants/new` ? '!bg-gray-100 !text-gray-800' : ''}"
79+
>
80+
<CarbonAdd />
81+
<div class="truncate">Create new assistant</div>
82+
</a>
83+
{/if}
84+
{#each data.assistants as assistant}
85+
<a
86+
href="{base}/settings/assistants/{assistant._id.toString()}"
87+
class="group flex h-10 flex-none items-center gap-2 pl-2 pr-2 text-sm text-gray-500 hover:bg-gray-100 md:rounded-xl
88+
{assistant._id.toString() === $page.params.assistantId ? '!bg-gray-100 !text-gray-800' : ''}"
89+
>
90+
{#if assistant.avatar}
91+
<img
92+
src="{base}/settings/assistants/{assistant._id.toString()}/avatar.jpg?hash={assistant.avatar}"
93+
alt="Avatar"
94+
class="h-6 w-6 rounded-full object-cover"
95+
/>
96+
{:else}
97+
<div
98+
class="flex size-6 items-center justify-center rounded-full bg-gray-300 font-bold uppercase text-gray-500"
99+
>
100+
{assistant.name[0]}
101+
</div>
102+
{/if}
103+
<div class="truncate">{assistant.name}</div>
104+
{#if assistant._id.toString() === $settings.activeModel}
105+
<div
106+
class="ml-auto rounded-lg bg-black px-2 py-1.5 text-xs font-semibold leading-none text-white"
107+
>
108+
Active
109+
</div>
110+
{/if}
111+
</a>
112+
{/each}
113+
<a
114+
href="{base}/assistants"
115+
class="group flex h-10 flex-none items-center gap-2 pl-3 pr-2 text-sm text-gray-500 hover:bg-gray-100 md:rounded-xl"
116+
><CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs " />
117+
<div class="truncate">Browse Assistants</div>
118+
</a>
119+
{/if}
120+
121+
<a
122+
href="{base}/settings"
123+
class="group mt-auto flex h-10 flex-none items-center gap-2 pl-3 pr-2 text-sm text-gray-500 hover:bg-gray-100 max-md:order-first md:rounded-xl
124+
{$page.url.pathname === `${base}/settings` ? '!bg-gray-100 !text-gray-800' : ''}"
125+
>
126+
<UserIcon class="text-sm" />
127+
Application Settings
128+
</a>
129+
</div>
130+
<div
131+
class="col-span-1 w-full overflow-y-auto overflow-x-clip px-1 max-md:pt-4 md:col-span-2 md:row-span-2"
132+
>
133+
<slot />
134+
</div>
135+
</div>
File renamed without changes.

src/routes/settings/[...model]/+page.ts renamed to src/routes/settings/(nav)/[...model]/+page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { redirect } from "@sveltejs/kit";
44
export async function load({ parent, params }) {
55
const data = await parent();
66

7-
const model = data.models.find(({ id }) => id === params.model);
7+
const model = data.models.find((m: { id: string }) => m.id === params.model);
88

99
if (!model || model.unlisted) {
1010
throw redirect(302, `${base}/settings`);

0 commit comments

Comments
 (0)