Skip to content

Commit

Permalink
Merge pull request #44 from 2405-team3/feat/ui-styling-and-tweaks
Browse files Browse the repository at this point in the history
Feat/UI styling and tweaks
  • Loading branch information
yg-lim authored Aug 10, 2024
2 parents 8b4883a + b1f9af7 commit ff384b9
Show file tree
Hide file tree
Showing 18 changed files with 573 additions and 238 deletions.
2 changes: 1 addition & 1 deletion ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function App() {
return (
<QueryClientProvider client={queryClient}>
<Navigation />
<main className="ml-72 p-12">
<main className="ml-60 p-6">
<Router>
<Switch>
<Route path="/knowledge-bases" component={PageKnowledgeBases} />
Expand Down
125 changes: 48 additions & 77 deletions ui/src/components/ChatbotConfiguration.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { useEffect, useState } from "react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { useMutation, useQuery } from "@tanstack/react-query";
import { useMutation } from "@tanstack/react-query";

import { zodResolver } from "@hookform/resolvers/zod";

import { clientPipelineConfigSchema } from "../services/chatbot-service";
import {
knowledgeBaseService,
ServerKnowledgeBaseConfig,
} from "../services/knowledge-base-service";
clientPipelineConfigSchema,
ServerPipelineConfig,
} from "../services/chatbot-service";
import { chatbotService } from "../services/chatbot-service";
import { ClientPipelineConfig } from "../services/chatbot-service";

Expand All @@ -24,67 +23,47 @@ import { ColbertRerankField } from "./form_fields/ColbertRerankField";
import { LongContextReorderField } from "./form_fields/LongContextReorderField";
import { PromptField } from "./form_fields/PromptField";

import { ServerKnowledgeBaseConfig } from "../services/knowledge-base-service";
import { RotateCw } from "lucide-react";

interface ChatbotConfigurationProps {
id: string;
chatbot: ServerPipelineConfig;
knowledgeBases: ServerKnowledgeBaseConfig[];
}

export function ChatbotConfiguration({ id }: ChatbotConfigurationProps) {
const mutation = useMutation({
export function ChatbotConfiguration({
chatbot,
knowledgeBases,
}: ChatbotConfigurationProps) {
const { mutate, isPending } = useMutation({
mutationFn: (data: ClientPipelineConfig) =>
chatbotService.updateChatbot(id, data),
});

const {
data: knowledgeBases,
isLoading: isKnowledgeBasesLoading,
error: knowledgeBasesError,
} = useQuery<ServerKnowledgeBaseConfig[]>({
queryKey: ["knowledgeBases"],
queryFn: knowledgeBaseService.fetchKnowledgeBases,
chatbotService.updateChatbot(chatbot.id, data),
});

const {
data: chatbot,
isLoading: isChatbotLoading,
error: chatbotError,
} = useQuery({
queryKey: ["chatbot", id],
queryFn: () => chatbotService.fetchChatbotById(id),
});

const [displayCutoff, setDisplayCutoff] = useState(false);
const [displayTopN, setDisplayTopN] = useState(false);

const form = useForm<ClientPipelineConfig>({
resolver: zodResolver(clientPipelineConfigSchema),
});

useEffect(() => {
if (chatbot && !isChatbotLoading) {
if (chatbot) {
form.reset(chatbot);
setDisplayCutoff(!!chatbot.similarity?.on);
setDisplayTopN(!!chatbot.colbert_rerank?.on);
}
}, [chatbot, isChatbotLoading, form]);
}, [chatbot, form]);

const handleSubmit = form.handleSubmit(
(data) => {
mutation.mutate(data);
},
(errors) => {
console.error("Form submission failed. Errors:", errors);
}
);

if (isKnowledgeBasesLoading || isChatbotLoading) return <div>Loading...</div>;
if (knowledgeBasesError) return <div>Error loading knowledge bases</div>;
if (chatbotError) return <div>Error loading chatbot</div>;
const handleSubmit = form.handleSubmit((data) => {
mutate(data);
});

if (knowledgeBases && chatbot) {
return (
<Card className="h-full flex flex-col px-6">
<header className="flex justify-between items-baseline">
<Typography variant="h4">Configuration</Typography>
return (
<Card className="h-full flex flex-col px-6">
<header className="flex justify-between items-baseline">
<Typography variant="h4">Configuration</Typography>
{isPending ? (
<Button disabled>
<RotateCw className="w-4 h-4 mr-2 animate-spin" />
Saving...
</Button>
) : (
<Button
type="submit"
onClick={(e) => {
Expand All @@ -94,29 +73,21 @@ export function ChatbotConfiguration({ id }: ChatbotConfigurationProps) {
>
Save
</Button>
</header>
<Form {...form}>
<form className="space-y-8 mb-8">
<KnowledgeBasesDropdownField
control={form.control}
knowledgeBases={knowledgeBases}
/>
<GenerativeModelField control={form.control} />
<SimilaritySearchField
control={form.control}
displayCutoff={displayCutoff}
setDisplayCutoff={setDisplayCutoff}
/>
<ColbertRerankField
control={form.control}
displayTopN={displayTopN}
setDisplayTopN={setDisplayTopN}
/>
<LongContextReorderField control={form.control} />
<PromptField control={form.control} />
</form>
</Form>
</Card>
);
}
)}
</header>
<Form {...form}>
<form className="space-y-8 mb-8">
<KnowledgeBasesDropdownField
control={form.control}
knowledgeBases={knowledgeBases}
/>
<GenerativeModelField control={form.control} />
<SimilaritySearchField control={form.control} />
<ColbertRerankField control={form.control} />
<LongContextReorderField control={form.control} />
<PromptField control={form.control} />
</form>
</Form>
</Card>
);
}
23 changes: 20 additions & 3 deletions ui/src/components/ModalKnowledgeBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ import {
ClientKnowledgeBaseConfig,
clientKnowledgeBaseConfigSchema,
knowledgeBaseService,
ServerKnowledgeBaseConfig,
} from "@/services/knowledge-base-service";
import { zodResolver } from "@hookform/resolvers/zod";
import { RefreshCw } from "lucide-react";
import { useLocation } from "wouter";

interface ModalKnowledgeBaseProps {
setModalVisible: Dispatch<SetStateAction<boolean>>;
Expand All @@ -51,9 +54,16 @@ export function ModalKnowledgeBase({
},
});

const mutation = useMutation({
const [, setLocation] = useLocation();

const { mutate, isPending } = useMutation({
mutationFn: (data: ClientKnowledgeBaseConfig) =>
knowledgeBaseService.createKnowledgeBase(data),

onSuccess: (data: ServerKnowledgeBaseConfig) => {
setModalVisible(false);
setLocation(`/knowledge-bases/${data.id}`);
},
});

function handleCancelClick() {
Expand All @@ -64,7 +74,7 @@ export function ModalKnowledgeBase({
(data) => {
console.log(form.getValues());
console.log(data);
mutation.mutate(data);
mutate(data);
},
(error) => {
console.log(error);
Expand Down Expand Up @@ -411,7 +421,14 @@ export function ModalKnowledgeBase({
<Button variant="outline" onClick={handleCancelClick}>
Cancel
</Button>
<Button type="submit">Create</Button>
{isPending ? (
<Button disabled>
<RefreshCw className="mr-2 h-4 w-4 animate-spin" />
Creating...
</Button>
) : (
<Button type="submit">Create</Button>
)}
</div>
</form>
</Form>
Expand Down
78 changes: 51 additions & 27 deletions ui/src/components/Navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,60 @@
import Logo from "../assets/paisley-logo-icon.svg";
import { Link } from "wouter";
import { NavigationLink } from "./NavigationLink";

const PRIMARY_NAV_LINKS = [
{ href: "/dashboard", text: "Dashboard" },
{ href: "/knowledge-bases", text: "Knowledge Bases" },
{ href: "/chatbots", text: "Chatbots" },
{ href: "/evaluations", text: "Evaluations" },
];

const SECONDARY_NAV_LINKS = [
{ href: "/api-keys", text: "API Keys" },
{ href: "/settings", text: "Settings" },
];
import { Typography } from "./Typography";
import {
LayoutDashboard,
BookOpenText,
BotMessageSquare,
ChartCandlestick,
KeyRound,
Settings,
} from "lucide-react";

export function Navigation() {
return (
<div className="flex flex-col justify-between fixed h-full w-72 bg-white z-10 px-12 py-8 border-r-2">
<nav>
<img src={Logo} alt="Paisley Logo" className="size-12" />
{PRIMARY_NAV_LINKS.map((link) => (
<Link key={link.href} href={link.href}>
<NavigationLink>{link.text}</NavigationLink>
</Link>
))}
<div className="flex flex-col justify-start gap-8 fixed h-full w-60 bg-white z-10 p-6 border-r">
<div className="flex items-center gap-3 pb-5 border-b">
<img src={Logo} alt="Paisley Logo" className="size-8" />
<Typography className="text-xl font-semibold font-inter">
Paisley
</Typography>
</div>
<nav className="flex flex-col gap-2">
<Typography variant="muted" className="px-2">
Menu
</Typography>
<NavigationLink href="/dashboard">
<LayoutDashboard />
<p className="text-base">Dashboard</p>
</NavigationLink>
<NavigationLink
href="/knowledge-bases"
activePattern={/\/knowledge-bases/}
>
<BookOpenText />
<p className="text-base">Knowledge Bases</p>
</NavigationLink>
<NavigationLink href="/chatbots" activePattern={/\/chatbots/}>
<BotMessageSquare />
<p className="text-base">Chatbots</p>
</NavigationLink>
<NavigationLink href="/evaluations">
<ChartCandlestick />
<p className="text-base">Evaluations</p>
</NavigationLink>
</nav>
<nav>
{SECONDARY_NAV_LINKS.map((link) => (
<Link key={link.href} href={link.href}>
<NavigationLink>{link.text}</NavigationLink>
</Link>
))}
<nav className="flex flex-col gap-2">
<Typography variant="muted" className="px-2">
Account
</Typography>
<NavigationLink href="/api-keys">
<KeyRound />
<p className="text-base">API Keys</p>
</NavigationLink>
<NavigationLink href="/settings">
<Settings />
<p className="text-base">Settings</p>
</NavigationLink>
</nav>
</div>
);
Expand Down
31 changes: 27 additions & 4 deletions ui/src/components/NavigationLink.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
export function NavigationLink({ children }: { children: React.ReactNode }) {
import { Link, useLocation } from "wouter";
import { ReactNode } from "react";

interface NavigationLinkProps {
href: string;
children: ReactNode;
activePattern?: RegExp;
}

export function NavigationLink({
href,
children,
activePattern,
}: NavigationLinkProps) {
const [location] = useLocation();
const isActive = activePattern
? activePattern.test(location)
: location === href;

return (
<div className="my-4">
<p className="px-4 py-2 border rounded-lg">{children}</p>
</div>
<Link
href={href}
className={`flex items-center gap-2 px-2 py-2 rounded-md hover:bg-gray-100 ${
isActive ? "bg-gray-100 text-blue-600" : "text-gray-700"
}`}
>
{children}
</Link>
);
}
16 changes: 11 additions & 5 deletions ui/src/components/Typography.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { cn } from "@/lib/utils";

interface TypographyProps {
variant:
variant?:
| "h1"
| "h2"
| "h3"
Expand Down Expand Up @@ -37,15 +37,21 @@ export function Typography({ variant, children, className }: TypographyProps) {

if (variant === "p") {
Component = "p";
} else if (variant.startsWith("h")) {
} else if (variant?.startsWith("h")) {
Component = variant as keyof React.JSX.IntrinsicElements;
} else {
Component = "div";
}

if (variant) {
return (
<Component className={cn(baseStyles, variantStyles[variant], className)}>
{children}
</Component>
);
}

return (
<Component className={cn(baseStyles, variantStyles[variant], className)}>
{children}
</Component>
<Component className={cn(baseStyles, className)}>{children}</Component>
);
}
Loading

0 comments on commit ff384b9

Please sign in to comment.