Skip to content

Commit

Permalink
Make assistant settings form fill the modal (#900)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
nsarrazin and gary149 committed Mar 7, 2024
1 parent 8e839b8 commit 315e56b
Show file tree
Hide file tree
Showing 16 changed files with 157 additions and 131 deletions.
37 changes: 19 additions & 18 deletions src/lib/components/AssistantSettings.svelte
Expand Up @@ -8,8 +8,8 @@
import { base } from "$app/paths";
import CarbonPen from "~icons/carbon/pen";
import CarbonUpload from "~icons/carbon/upload";
import { useSettingsStore } from "$lib/stores/settings";
import IconLoading from "./icons/IconLoading.svelte";
type ActionData = {
error: boolean;
Expand Down Expand Up @@ -75,7 +75,7 @@

<form
method="POST"
class="flex h-full flex-col"
class="flex h-full flex-col overflow-y-auto p-4 md:p-8"
enctype="multipart/form-data"
use:enhance={async ({ formData }) => {
loading = true;
Expand Down Expand Up @@ -110,7 +110,9 @@
}}
>
{#if assistant}
<h2 class="text-xl font-semibold">Edit assistant ({assistant?.name ?? ""})</h2>
<h2 class="text-xl font-semibold">
Edit {assistant?.name ?? "assistant"}
</h2>
<p class="mb-6 text-sm text-gray-500">
Modifying an existing assistant will propagate those changes to all users.
</p>
Expand All @@ -123,10 +125,10 @@
</p>
{/if}

<div class="mx-1 grid flex-1 grid-cols-2 gap-4 max-sm:grid-cols-1">
<div class="grid h-full w-full flex-1 grid-cols-2 gap-6 text-sm max-sm:grid-cols-1">
<div class="flex flex-col gap-4">
<div>
<span class="mb-1 block pb-2 text-sm font-semibold">Avatar</span>
<div class="mb-1 block pb-2 text-sm font-semibold">Avatar</div>
<input
type="file"
accept="image/*"
Expand Down Expand Up @@ -185,7 +187,7 @@
</div>

<label>
<span class="mb-1 text-sm font-semibold">Name</span>
<div class="mb-1 font-semibold">Name</div>
<input
name="name"
class="w-full rounded-lg border-2 border-gray-200 bg-gray-100 p-2"
Expand All @@ -196,18 +198,18 @@
</label>

<label>
<span class="mb-1 text-sm font-semibold">Description</span>
<div class="mb-1 font-semibold">Description</div>
<textarea
name="description"
class="w-full rounded-lg border-2 border-gray-200 bg-gray-100 p-2"
class="h-15 w-full rounded-lg border-2 border-gray-200 bg-gray-100 p-2"
placeholder="He knows everything about python"
value={assistant?.description ?? ""}
/>
<p class="text-xs text-red-500">{getError("description", form)}</p>
</label>

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

<label>
<span class="mb-1 text-sm font-semibold">User start messages</span>
<div class="flex flex-col gap-2 md:max-h-32">
<div class="mb-1 font-semibold">User start messages</div>
<div class="flex flex-col gap-2">
<input
name="exampleInput1"
bind:value={inputMessage1}
Expand Down Expand Up @@ -256,7 +258,7 @@
</div>

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

<div class="mt-5 flex justify-end gap-2">
<div class="mt-6 flex justify-end gap-2">
<a
href={assistant ? `${base}/settings/assistants/${assistant?._id}` : `${base}/settings`}
class="rounded-full bg-gray-200 px-8 py-2 font-semibold text-gray-600">Cancel</a
class="flex items-center justify-center rounded-full bg-gray-200 px-5 py-2 font-semibold text-gray-600"
>
Cancel
</a>
<button
type="submit"
disabled={loading}
aria-disabled={loading}
class="rounded-full bg-black px-8 py-2 font-semibold md:px-20"
class="flex items-center justify-center rounded-full bg-black px-8 py-2 font-semibold"
class:bg-gray-200={loading}
class:text-gray-600={loading}
class:text-white={!loading}
>
{assistant ? "Save" : "Create"}
{#if loading}
<IconLoading classNames="ml-2 h-min" />
{/if}
</button>
</div>
</form>
135 changes: 135 additions & 0 deletions src/routes/settings/(nav)/+layout.svelte
@@ -0,0 +1,135 @@
<script lang="ts">
import { onMount } from "svelte";
import { base } from "$app/paths";
import { afterNavigate, goto } from "$app/navigation";
import { page } from "$app/stores";
import { useSettingsStore } from "$lib/stores/settings";
import CarbonClose from "~icons/carbon/close";
import CarbonArrowUpRight from "~icons/carbon/ArrowUpRight";
import CarbonAdd from "~icons/carbon/add";
import UserIcon from "~icons/carbon/user";
import type { LayoutData } from "../$types";
export let data: LayoutData;
let previousPage: string = base;
let assistantsSection: HTMLHeadingElement;
onMount(() => {
if ($page.params?.assistantId) {
assistantsSection.scrollIntoView();
}
});
afterNavigate(({ from }) => {
if (!from?.url.pathname.includes("settings")) {
previousPage = from?.url.toString() || previousPage;
}
});
const settings = useSettingsStore();
</script>

<div
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"
>
<div class="col-span-1 mb-4 flex items-center justify-between md:col-span-3">
<h2 class="text-xl font-bold">Settings</h2>
<button
class="btn rounded-lg"
on:click={() => {
goto(previousPage);
}}
>
<CarbonClose class="text-xl text-gray-900 hover:text-black" />
</button>
</div>
<div
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"
>
<h3 class="pb-3 pl-3 pt-2 text-[.8rem] text-gray-800 sm:pl-1">Models</h3>

{#each data.models.filter((el) => !el.unlisted) as model}
<a
href="{base}/settings/{model.id}"
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
{model.id === $page.params.model ? '!bg-gray-100 !text-gray-800' : ''}"
>
<div class="truncate">{model.displayName}</div>
{#if model.id === $settings.activeModel}
<div
class="ml-auto rounded-lg bg-black px-2 py-1.5 text-xs font-semibold leading-none text-white"
>
Active
</div>
{/if}
</a>
{/each}
<!-- if its huggingchat, the number of assistants owned by the user must be non-zero to show the UI -->
{#if data.enableAssistants}
<h3 bind:this={assistantsSection} class="pb-3 pl-3 pt-5 text-[.8rem] text-gray-800 sm:pl-1">
Assistants
</h3>
{#if !data.loginEnabled || (data.loginEnabled && !!data.user)}
<a
href="{base}/settings/assistants/new"
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
{$page.url.pathname === `${base}/settings/assistants/new` ? '!bg-gray-100 !text-gray-800' : ''}"
>
<CarbonAdd />
<div class="truncate">Create new assistant</div>
</a>
{/if}
{#each data.assistants as assistant}
<a
href="{base}/settings/assistants/{assistant._id.toString()}"
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
{assistant._id.toString() === $page.params.assistantId ? '!bg-gray-100 !text-gray-800' : ''}"
>
{#if assistant.avatar}
<img
src="{base}/settings/assistants/{assistant._id.toString()}/avatar.jpg?hash={assistant.avatar}"
alt="Avatar"
class="h-6 w-6 rounded-full object-cover"
/>
{:else}
<div
class="flex size-6 items-center justify-center rounded-full bg-gray-300 font-bold uppercase text-gray-500"
>
{assistant.name[0]}
</div>
{/if}
<div class="truncate">{assistant.name}</div>
{#if assistant._id.toString() === $settings.activeModel}
<div
class="ml-auto rounded-lg bg-black px-2 py-1.5 text-xs font-semibold leading-none text-white"
>
Active
</div>
{/if}
</a>
{/each}
<a
href="{base}/assistants"
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"
><CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs " />
<div class="truncate">Browse Assistants</div>
</a>
{/if}

<a
href="{base}/settings"
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
{$page.url.pathname === `${base}/settings` ? '!bg-gray-100 !text-gray-800' : ''}"
>
<UserIcon class="text-sm" />
Application Settings
</a>
</div>
<div
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"
>
<slot />
</div>
</div>
File renamed without changes.
File renamed without changes.
File renamed without changes.
Expand Up @@ -4,7 +4,7 @@ import { redirect } from "@sveltejs/kit";
export async function load({ parent, params }) {
const data = await parent();

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

if (!model || model.unlisted) {
throw redirect(302, `${base}/settings`);
Expand Down
File renamed without changes.
File renamed without changes.

0 comments on commit 315e56b

Please sign in to comment.