Merge branch 'feat/onboarding' of github.com:langflow-ai/openrag into feat/onboarding
This commit is contained in:
commit
facbb76171
17 changed files with 522 additions and 105 deletions
26
frontend/components/label-input.tsx
Normal file
26
frontend/components/label-input.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { LabelWrapper } from "./label-wrapper";
|
||||
import { Input } from "./ui/input";
|
||||
|
||||
export function LabelInput({
|
||||
label,
|
||||
helperText,
|
||||
id,
|
||||
required,
|
||||
...props
|
||||
}: {
|
||||
label: string;
|
||||
helperText: string;
|
||||
id: string;
|
||||
required: boolean;
|
||||
} & React.InputHTMLAttributes<HTMLInputElement>) {
|
||||
return (
|
||||
<LabelWrapper
|
||||
label={label}
|
||||
helperText={helperText}
|
||||
id={id}
|
||||
required={required}
|
||||
>
|
||||
<Input id={id} {...props} />
|
||||
</LabelWrapper>
|
||||
);
|
||||
}
|
||||
43
frontend/components/label-wrapper.tsx
Normal file
43
frontend/components/label-wrapper.tsx
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { Info } from "lucide-react";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Input } from "./ui/input";
|
||||
import { Label } from "./ui/label";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
|
||||
|
||||
export function LabelWrapper({
|
||||
label,
|
||||
helperText,
|
||||
id,
|
||||
required,
|
||||
children,
|
||||
}: {
|
||||
label: string;
|
||||
helperText: string;
|
||||
id: string;
|
||||
required: boolean;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<Label
|
||||
htmlFor={id}
|
||||
className="text-mmd font-medium flex items-center gap-1"
|
||||
>
|
||||
{label}
|
||||
{required && <span className="text-red-500">*</span>}
|
||||
{helperText && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<Info className="w-3.5 h-3.5 text-muted-foreground" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{helperText}</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Label>
|
||||
<div className="relative">{children}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -9,10 +9,10 @@ export default function OllamaLogo(props: React.SVGProps<SVGSVGElement>) {
|
|||
{...props}
|
||||
>
|
||||
<title>Ollama Logo</title>
|
||||
<g clip-path="url(#clip0_2060_5748)">
|
||||
<g clipPath="url(#clip0_2060_5748)">
|
||||
<path
|
||||
d="M4.67944 0.0576172C4.94223 -0.0366808 5.15143 -0.016476 5.44116 0.125C5.91976 0.37441 6.25025 1.04885 6.49292 2.2959L6.51929 2.44434L6.88354 2.28223C7.86769 1.85082 8.64306 1.88458 9.86987 2.42383C9.91704 2.45078 9.96389 2.39703 9.98413 2.30273C10.1931 1.22439 10.4493 0.610811 10.8132 0.293945C11.4266 -0.245299 12.1553 -0.0230936 12.5867 0.826172C12.89 1.4395 13.0042 2.12721 12.9773 3.23242L12.9568 4.19043L13.3484 4.60156C14.3255 5.62615 14.5614 7.35153 13.8943 8.58496L13.7253 8.89551L13.8601 9.21191C14.3522 10.3511 14.3324 11.8345 13.8201 12.7715L13.6443 13.0947L13.7859 13.4248C13.8668 13.6068 13.9613 13.9039 14.0017 14.0859C14.096 14.5041 14.1029 15.5757 14.0085 15.8184C13.9413 15.9932 13.914 16 13.4968 16C13.0047 16 13.0248 16.0266 13.1394 15.4199C13.2404 14.8672 13.1258 14.1526 12.8562 13.627C12.6069 13.1554 12.5998 12.9263 12.822 12.6299C13.1388 12.1985 13.2811 11.7128 13.2878 11.0117C13.2946 10.3175 13.193 9.93275 12.8425 9.25195C12.6405 8.8545 12.6476 8.65255 12.8767 8.46387C12.9308 8.41627 13.0581 8.19361 13.1658 7.95801C13.3208 7.60752 13.3551 7.45259 13.3484 7.00098C13.3484 6.0101 12.8757 5.20837 12.0466 4.75C11.6626 4.54113 11.5548 4.51358 11.1033 4.50684C10.8277 4.50683 10.5589 4.48001 10.5173 4.45312C10.4701 4.42616 10.3826 4.28423 10.3152 4.14941C10.1399 3.78545 9.70125 3.3748 9.24292 3.15234C8.8925 2.98387 8.77115 2.95607 8.23901 2.95605C7.72001 2.95605 7.57805 2.98366 7.2478 3.13867C6.76921 3.36112 6.32405 3.76538 6.12183 4.16309C6.0411 4.33126 5.95367 4.47222 5.92651 4.47949C5.89955 4.47949 5.65013 4.49316 5.37378 4.49316C4.71996 4.50664 4.23428 4.73581 3.76245 5.24805C3.2906 5.76708 3.12183 6.23255 3.12183 7.00098C3.11509 7.49291 3.14912 7.67504 3.2771 7.95801C3.35791 8.14657 3.49295 8.36207 3.56714 8.42969C3.82995 8.66555 3.8433 8.84102 3.63452 9.25195C3.28401 9.93275 3.18248 10.3175 3.18921 11.0117C3.19595 11.7128 3.33821 12.1985 3.65503 12.6299C3.87723 12.9263 3.87012 13.1553 3.62085 13.627C3.35128 14.1526 3.23666 14.8672 3.33765 15.4199C3.4522 16.0264 3.4728 16 2.9812 16C2.56356 16 2.53581 15.9933 2.46851 15.8184C2.37416 15.5757 2.38103 14.5041 2.47534 14.0859C2.51579 13.9039 2.61027 13.6068 2.69116 13.4248L2.83276 13.0947L2.65698 12.7715C2.38735 12.2861 2.26636 11.7329 2.26636 11.0049C2.26638 10.3377 2.37415 9.78507 2.60327 9.23242L2.73804 8.93555L2.50854 8.4707C1.88172 7.2103 2.13128 5.64639 3.12866 4.60156L3.52026 4.19043L3.49976 3.23242C3.47284 2.134 3.58712 1.43967 3.89038 0.839844C4.11957 0.38821 4.32892 0.178952 4.67944 0.0576172ZM7.38257 6.82617C7.90159 6.65092 8.75736 6.68461 9.29663 6.89355C9.81567 7.09578 10.3687 7.6012 10.5642 8.05957C10.7798 8.56509 10.7389 9.21173 10.4558 9.60938C9.97728 10.2968 9.39813 10.54 8.23901 10.54C7.36289 10.54 6.92444 10.4319 6.50659 10.1152C6.02804 9.75127 5.82548 9.39406 5.79175 8.88184C5.75804 8.33583 5.89952 7.93082 6.27026 7.52637C6.60046 7.16927 6.89062 6.98791 7.38257 6.82617ZM8.3396 7.33105C6.70163 7.24348 5.71788 8.83467 6.91772 9.64355C7.2479 9.86583 7.55167 9.93359 8.23901 9.93359C8.926 9.93356 9.22924 9.86576 9.55933 9.64355C10.4221 9.06388 10.2001 7.97864 9.11499 7.5C8.91951 7.41237 8.60249 7.34454 8.3396 7.33105ZM7.78687 8.1875C7.92842 8.09987 7.92187 8.09977 8.0769 8.18066C8.16448 8.23451 8.24529 8.22781 8.3396 8.18066C8.42038 8.14028 8.54167 8.12638 8.60913 8.14648C8.79113 8.20715 8.79113 8.55123 8.60913 8.65234C8.50812 8.70625 8.4744 8.79402 8.47437 8.98926C8.47437 9.21824 8.44763 9.26611 8.3064 9.2998C8.06383 9.36045 7.91564 9.21222 7.96265 8.96973C7.99635 8.81469 7.96856 8.74652 7.83374 8.63867C7.63866 8.4837 7.61855 8.28183 7.78687 8.1875ZM5.17847 6.83203C5.38052 6.83207 5.46861 6.8794 5.61011 7.04785C5.82577 7.30397 5.80544 7.57425 5.53589 7.85059C5.32028 8.07294 5.20535 8.10625 4.91577 8.03223C4.59221 7.9446 4.45683 7.60726 4.59839 7.25C4.65906 7.11525 4.75359 6.96024 4.81421 6.91309C4.87498 6.87267 5.04374 6.83203 5.17847 6.83203ZM11.2849 6.83203C11.6152 6.83203 11.7438 6.92049 11.8718 7.2373C12.0199 7.61448 11.8921 7.94442 11.5623 8.03223C11.2724 8.10638 11.1569 8.07303 10.9412 7.85059C10.6716 7.57425 10.6522 7.30397 10.8679 7.04785C11.0092 6.87983 11.1034 6.83211 11.2849 6.83203ZM4.96948 0.900391C4.86841 0.900391 4.63911 1.3317 4.54468 1.71582C4.40989 2.22801 4.34238 2.98992 4.39624 3.3877L4.44312 3.71777L4.6521 3.66406C4.77343 3.63036 5.01688 3.59063 5.19214 3.57715C5.374 3.56362 5.54908 3.50897 5.58276 3.45508C5.74422 3.21839 5.48102 1.66887 5.198 1.19043C5.10386 1.02909 5.00338 0.900927 4.96948 0.900391ZM11.5076 0.900391C11.3928 0.901308 11.1096 1.48104 11.0085 1.91211C10.8739 2.50484 10.8137 3.33956 10.8943 3.45508C10.928 3.50896 11.1031 3.56361 11.2849 3.57715C11.4602 3.59063 11.7036 3.63036 11.825 3.66406L12.0339 3.71777L12.0808 3.3877C12.1684 2.73379 11.9725 1.56114 11.7029 1.12305C11.6287 1.0018 11.5345 0.900391 11.5076 0.900391Z"
|
||||
fill="#A1A1AA"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
|
|
|
|||
|
|
@ -1,52 +1,73 @@
|
|||
import * as React from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"rounded-lg border border-border bg-card text-card-foreground shadow-sm",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
);
|
||||
const Card = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"rounded-lg border border-border bg-card text-card-foreground shadow-sm",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn("flex flex-col space-y-1.5 p-4", className)} {...props} />
|
||||
)
|
||||
);
|
||||
const CardHeader = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("flex flex-col space-y-1.5 p-5", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
const CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<h3
|
||||
ref={ref}
|
||||
className={cn("text-base font-semibold leading-tight tracking-tight", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
);
|
||||
const CardTitle = React.forwardRef<
|
||||
HTMLParagraphElement,
|
||||
React.HTMLAttributes<HTMLHeadingElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<h3
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"text-base font-semibold leading-tight tracking-tight",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
const CardDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
|
||||
)
|
||||
);
|
||||
const CardDescription = React.forwardRef<
|
||||
HTMLParagraphElement,
|
||||
React.HTMLAttributes<HTMLParagraphElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("text-sm text-muted-foreground", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn("p-4 pt-0", className)} {...props} />
|
||||
)
|
||||
);
|
||||
const CardContent = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn("p-5 pt-0", className)} {...props} />
|
||||
));
|
||||
|
||||
const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn("flex items-center p-4 pt-0", className)} {...props} />
|
||||
)
|
||||
);
|
||||
const CardFooter = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("flex items-center p-4 pt-0", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
Card.displayName = "Card";
|
||||
CardHeader.displayName = "CardHeader";
|
||||
|
|
@ -55,4 +76,11 @@ CardDescription.displayName = "CardDescription";
|
|||
CardContent.displayName = "CardContent";
|
||||
CardFooter.displayName = "CardFooter";
|
||||
|
||||
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
|
||||
export {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,15 +1,32 @@
|
|||
import * as React from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
export interface InputProps
|
||||
extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
icon?: React.ReactNode;
|
||||
inputClassName?: string;
|
||||
}
|
||||
|
||||
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
({ className, inputClassName, icon, type, placeholder, ...props }, ref) => {
|
||||
const [hasValue, setHasValue] = React.useState(
|
||||
Boolean(props.value || props.defaultValue),
|
||||
);
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setHasValue(e.target.value.length > 0);
|
||||
if (props.onChange) {
|
||||
props.onChange(e);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<label className={cn("relative block h-fit w-full text-sm", icon ? className : "")}>
|
||||
<label
|
||||
className={cn(
|
||||
"relative block h-fit w-full text-xs",
|
||||
icon ? className : "",
|
||||
)}
|
||||
>
|
||||
{icon && (
|
||||
<div className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 transform text-muted-foreground">
|
||||
{icon}
|
||||
|
|
@ -26,12 +43,13 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<span
|
||||
className={cn(
|
||||
"pointer-events-none absolute top-1/2 -translate-y-1/2 pl-px text-placeholder-foreground font-mono",
|
||||
icon ? "left-9" : "left-3",
|
||||
props.value && "hidden",
|
||||
hasValue && "hidden",
|
||||
)}
|
||||
>
|
||||
{placeholder}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ const TabsContent = React.forwardRef<
|
|||
<TabsPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"mt-2 space-y-5 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
30
frontend/components/ui/tooltip.tsx
Normal file
30
frontend/components/ui/tooltip.tsx
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
"use client";
|
||||
|
||||
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const TooltipProvider = TooltipPrimitive.Provider;
|
||||
|
||||
const Tooltip = TooltipPrimitive.Root;
|
||||
|
||||
const TooltipTrigger = TooltipPrimitive.Trigger;
|
||||
|
||||
const TooltipContent = React.forwardRef<
|
||||
React.ElementRef<typeof TooltipPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
|
||||
>(({ className, sideOffset = 4, ...props }, ref) => (
|
||||
<TooltipPrimitive.Content
|
||||
ref={ref}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-tooltip-content-transform-origin]",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
||||
|
||||
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
||||
35
frontend/package-lock.json
generated
35
frontend/package-lock.json
generated
|
|
@ -23,6 +23,7 @@
|
|||
"@radix-ui/react-slot": "^1.2.3",
|
||||
"@radix-ui/react-switch": "^1.2.5",
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@tanstack/react-query": "^5.86.0",
|
||||
|
|
@ -1968,6 +1969,40 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-tooltip": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz",
|
||||
"integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.3",
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
"@radix-ui/react-context": "1.1.2",
|
||||
"@radix-ui/react-dismissable-layer": "1.1.11",
|
||||
"@radix-ui/react-id": "1.1.1",
|
||||
"@radix-ui/react-popper": "1.2.8",
|
||||
"@radix-ui/react-portal": "1.1.9",
|
||||
"@radix-ui/react-presence": "1.1.5",
|
||||
"@radix-ui/react-primitive": "2.1.3",
|
||||
"@radix-ui/react-slot": "1.2.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.2.2",
|
||||
"@radix-ui/react-visually-hidden": "1.2.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-use-callback-ref": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
"@radix-ui/react-slot": "^1.2.3",
|
||||
"@radix-ui/react-switch": "^1.2.5",
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@tanstack/react-query": "^5.86.0",
|
||||
|
|
|
|||
|
|
@ -4,18 +4,18 @@ import {
|
|||
useQueryClient,
|
||||
} from "@tanstack/react-query";
|
||||
|
||||
interface AgentSettings {
|
||||
export interface AgentSettings {
|
||||
llm_model?: string;
|
||||
system_prompt?: string;
|
||||
}
|
||||
|
||||
interface IngestSettings {
|
||||
export interface IngestSettings {
|
||||
embedding_model?: string;
|
||||
chunk_size?: number;
|
||||
chunk_overlap?: number;
|
||||
}
|
||||
|
||||
interface Settings {
|
||||
export interface Settings {
|
||||
flow_id?: string;
|
||||
ingest_flow_id?: string;
|
||||
langflow_edit_url?: string;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
import type { Metadata } from "next";
|
||||
import { Inter, JetBrains_Mono, Chivo } from "next/font/google";
|
||||
import { Chivo, Inter, JetBrains_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import { ThemeProvider } from "@/components/theme-provider";
|
||||
import { AuthProvider } from "@/contexts/auth-context";
|
||||
import { TaskProvider } from "@/contexts/task-context";
|
||||
import { KnowledgeFilterProvider } from "@/contexts/knowledge-filter-context";
|
||||
import { ChatProvider } from "@/contexts/chat-context";
|
||||
import { LayoutWrapper } from "@/components/layout-wrapper";
|
||||
import { ThemeProvider } from "@/components/theme-provider";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { AuthProvider } from "@/contexts/auth-context";
|
||||
import { ChatProvider } from "@/contexts/chat-context";
|
||||
import { KnowledgeFilterProvider } from "@/contexts/knowledge-filter-context";
|
||||
import { TaskProvider } from "@/contexts/task-context";
|
||||
import Providers from "./providers";
|
||||
|
||||
const inter = Inter({
|
||||
|
|
@ -46,15 +47,17 @@ export default function RootLayout({
|
|||
disableTransitionOnChange
|
||||
>
|
||||
<Providers>
|
||||
<AuthProvider>
|
||||
<TaskProvider>
|
||||
<KnowledgeFilterProvider>
|
||||
<ChatProvider>
|
||||
<LayoutWrapper>{children}</LayoutWrapper>
|
||||
</ChatProvider>
|
||||
</KnowledgeFilterProvider>
|
||||
</TaskProvider>
|
||||
</AuthProvider>
|
||||
<TooltipProvider>
|
||||
<AuthProvider>
|
||||
<TaskProvider>
|
||||
<KnowledgeFilterProvider>
|
||||
<ChatProvider>
|
||||
<LayoutWrapper>{children}</LayoutWrapper>
|
||||
</ChatProvider>
|
||||
</KnowledgeFilterProvider>
|
||||
</TaskProvider>
|
||||
</AuthProvider>
|
||||
</TooltipProvider>
|
||||
</Providers>
|
||||
</ThemeProvider>
|
||||
<Toaster />
|
||||
|
|
|
|||
38
frontend/src/app/onboarding/ibm-onboarding.tsx
Normal file
38
frontend/src/app/onboarding/ibm-onboarding.tsx
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { LabelInput } from "@/components/label-input";
|
||||
import type { Settings } from "../api/queries/useGetSettingsQuery";
|
||||
import { AdvancedOnboarding } from "./advanced";
|
||||
|
||||
export function IBMOnboarding({
|
||||
settings,
|
||||
setSettings,
|
||||
}: {
|
||||
settings: Settings;
|
||||
setSettings: (settings: Settings) => void;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<LabelInput
|
||||
label="watsonx.ai API Endpoint"
|
||||
helperText="The API endpoint for your watsonx.ai account."
|
||||
id="api-endpoint"
|
||||
required
|
||||
placeholder="https://..."
|
||||
/>
|
||||
<LabelInput
|
||||
label="IBM API key"
|
||||
helperText="The API key for your watsonx.ai account."
|
||||
id="api-key"
|
||||
required
|
||||
placeholder="sk-..."
|
||||
/>
|
||||
<LabelInput
|
||||
label="IBM Project ID"
|
||||
helperText="The project ID for your watsonx.ai account."
|
||||
id="project-id"
|
||||
required
|
||||
placeholder="..."
|
||||
/>
|
||||
<AdvancedOnboarding modelProvider="watsonx" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
100
frontend/src/app/onboarding/model-selector.tsx
Normal file
100
frontend/src/app/onboarding/model-selector.tsx
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
} from "@/components/ui/command";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export function ModelSelector({
|
||||
options,
|
||||
value,
|
||||
onValueChange,
|
||||
icon,
|
||||
}: {
|
||||
options: {
|
||||
value: string;
|
||||
label: string;
|
||||
default?: boolean;
|
||||
}[];
|
||||
value: string;
|
||||
icon?: React.ReactNode;
|
||||
onValueChange: (value: string) => void;
|
||||
}) {
|
||||
const [open, setOpen] = useState(false);
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={open}
|
||||
className="w-full gap-2 justify-between"
|
||||
>
|
||||
{value ? (
|
||||
<div className="flex items-center gap-2 font-normal text-sm">
|
||||
<div className="w-4 h-4">{icon}</div>
|
||||
{options.find((framework) => framework.value === value)?.label}
|
||||
{options.find((framework) => framework.value === value)
|
||||
?.default && (
|
||||
<span className="text-xs text-foreground p-1 rounded-md bg-muted">
|
||||
Default
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
"Select model..."
|
||||
)}
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="start" className="w-[400px] p-0">
|
||||
<Command>
|
||||
<CommandInput placeholder="Search model..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>No model found.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{options.map((option) => (
|
||||
<CommandItem
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
onSelect={(currentValue) => {
|
||||
if (currentValue !== value) {
|
||||
onValueChange(currentValue);
|
||||
}
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
"mr-2 h-4 w-4",
|
||||
value === option.value ? "opacity-100" : "opacity-0",
|
||||
)}
|
||||
/>
|
||||
<div className="flex items-center gap-2">
|
||||
{option.label}
|
||||
{option.default && (
|
||||
<span className="text-xs text-foreground p-1 rounded-md bg-muted">
|
||||
Default
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
53
frontend/src/app/onboarding/ollama-onboarding.tsx
Normal file
53
frontend/src/app/onboarding/ollama-onboarding.tsx
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { useState } from "react";
|
||||
import { LabelInput } from "@/components/label-input";
|
||||
import { LabelWrapper } from "@/components/label-wrapper";
|
||||
import OllamaLogo from "@/components/logo/ollama-logo";
|
||||
import type { Settings } from "../api/queries/useGetSettingsQuery";
|
||||
import { AdvancedOnboarding } from "./advanced";
|
||||
import { ModelSelector } from "./model-selector";
|
||||
|
||||
export function OllamaOnboarding({
|
||||
settings,
|
||||
setSettings,
|
||||
}: {
|
||||
settings: Settings;
|
||||
setSettings: (settings: Settings) => void;
|
||||
}) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [value, setValue] = useState("");
|
||||
const frameworks = [
|
||||
{ value: "gpt-oss", label: "gpt-oss", default: true },
|
||||
{ value: "llama3.1", label: "llama3.1" },
|
||||
{ value: "llama3.2", label: "llama3.2" },
|
||||
{ value: "llama3.3", label: "llama3.3" },
|
||||
{ value: "llama3.4", label: "llama3.4" },
|
||||
{ value: "llama3.5", label: "llama3.5" },
|
||||
];
|
||||
return (
|
||||
<>
|
||||
<LabelInput
|
||||
label="Ollama Endpoint"
|
||||
helperText="The endpoint for your Ollama server."
|
||||
id="api-endpoint"
|
||||
required
|
||||
placeholder="http://..."
|
||||
/>
|
||||
|
||||
<LabelWrapper
|
||||
label="Embedding Model"
|
||||
helperText="The embedding model for your Ollama server."
|
||||
id="embedding-model"
|
||||
required={true}
|
||||
>
|
||||
<ModelSelector
|
||||
options={frameworks}
|
||||
icon={<OllamaLogo className="w-4 h-4" />}
|
||||
value={value}
|
||||
onValueChange={setValue}
|
||||
/>
|
||||
</LabelWrapper>
|
||||
|
||||
<AdvancedOnboarding modelProvider="ollama" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
24
frontend/src/app/onboarding/openai-onboarding.tsx
Normal file
24
frontend/src/app/onboarding/openai-onboarding.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { LabelInput } from "@/components/label-input";
|
||||
import type { Settings } from "../api/queries/useGetSettingsQuery";
|
||||
import { AdvancedOnboarding } from "./advanced";
|
||||
|
||||
export function OpenAIOnboarding({
|
||||
settings,
|
||||
setSettings,
|
||||
}: {
|
||||
settings: Settings;
|
||||
setSettings: (settings: Settings) => void;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<LabelInput
|
||||
label="OpenAI API key"
|
||||
helperText="The API key for your OpenAI account."
|
||||
id="api-key"
|
||||
required
|
||||
placeholder="sk-..."
|
||||
/>
|
||||
<AdvancedOnboarding modelProvider="openai" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
import { Suspense, useState } from "react";
|
||||
import { useUpdateFlowSettingMutation } from "@/app/api/mutations/useUpdateFlowSettingMutation";
|
||||
import { useGetSettingsQuery } from "@/app/api/queries/useGetSettingsQuery";
|
||||
import {
|
||||
type Settings,
|
||||
useGetSettingsQuery,
|
||||
} from "@/app/api/queries/useGetSettingsQuery";
|
||||
import { LabelInput } from "@/components/label-input";
|
||||
import IBMLogo from "@/components/logo/ibm-logo";
|
||||
import OllamaLogo from "@/components/logo/ollama-logo";
|
||||
import OpenAILogo from "@/components/logo/openai-logo";
|
||||
|
|
@ -11,16 +15,21 @@ import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
|||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { useAuth } from "@/contexts/auth-context";
|
||||
import { AdvancedOnboarding } from "./advanced";
|
||||
import { IBMOnboarding } from "./ibm-onboarding";
|
||||
import { OllamaOnboarding } from "./ollama-onboarding";
|
||||
import { OpenAIOnboarding } from "./openai-onboarding";
|
||||
|
||||
function OnboardingPage() {
|
||||
const { isAuthenticated } = useAuth();
|
||||
|
||||
const [modelProvider, setModelProvider] = useState<string>("openai");
|
||||
// Fetch settings using React Query
|
||||
const { data: settings = {} } = useGetSettingsQuery({
|
||||
const { data: settingsDb = {} } = useGetSettingsQuery({
|
||||
enabled: isAuthenticated,
|
||||
});
|
||||
|
||||
const [settings, setSettings] = useState<Settings>(settingsDb);
|
||||
|
||||
// Mutations
|
||||
const updateFlowSettingMutation = useUpdateFlowSettingMutation({
|
||||
onSuccess: () => {
|
||||
|
|
@ -40,43 +49,51 @@ function OnboardingPage() {
|
|||
backgroundPosition: "center",
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-col items-center justify-center gap-4">
|
||||
<h1 className="text-2xl font-medium font-chivo">
|
||||
Configure your models
|
||||
</h1>
|
||||
<p className="text-sm text-muted-foreground">[description of task]</p>
|
||||
<div className="flex flex-col items-center gap-5 min-h-[480px] w-full">
|
||||
<div className="flex flex-col items-center justify-center gap-4">
|
||||
<h1 className="text-2xl font-medium font-chivo">
|
||||
Configure your models
|
||||
</h1>
|
||||
<p className="text-sm text-muted-foreground">[description of task]</p>
|
||||
</div>
|
||||
<Card className="w-full max-w-[580px]">
|
||||
<Tabs defaultValue={modelProvider} onValueChange={setModelProvider}>
|
||||
<CardHeader>
|
||||
<TabsList>
|
||||
<TabsTrigger value="openai">
|
||||
<OpenAILogo className="w-4 h-4" />
|
||||
OpenAI
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="watsonx">
|
||||
<IBMLogo className="w-4 h-4" />
|
||||
IBM
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="ollama">
|
||||
<OllamaLogo className="w-4 h-4" />
|
||||
Ollama
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<TabsContent value="openai">
|
||||
<OpenAIOnboarding
|
||||
settings={settings}
|
||||
setSettings={setSettings}
|
||||
/>
|
||||
</TabsContent>
|
||||
<TabsContent value="watsonx">
|
||||
<IBMOnboarding settings={settings} setSettings={setSettings} />
|
||||
</TabsContent>
|
||||
<TabsContent value="ollama">
|
||||
<OllamaOnboarding
|
||||
settings={settings}
|
||||
setSettings={setSettings}
|
||||
/>
|
||||
</TabsContent>
|
||||
</CardContent>
|
||||
</Tabs>
|
||||
</Card>
|
||||
</div>
|
||||
<Card className="w-full max-w-[580px]">
|
||||
<Tabs defaultValue={modelProvider} onValueChange={setModelProvider}>
|
||||
<CardHeader>
|
||||
<TabsList>
|
||||
<TabsTrigger value="openai">
|
||||
<OpenAILogo className="w-4 h-4" />
|
||||
OpenAI
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="watsonx">
|
||||
<IBMLogo className="w-4 h-4" />
|
||||
IBM
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="ollama">
|
||||
<OllamaLogo className="w-4 h-4" />
|
||||
Ollama
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<TabsContent value="openai">
|
||||
<AdvancedOnboarding modelProvider={modelProvider} />
|
||||
</TabsContent>
|
||||
<TabsContent value="watsonx">
|
||||
<AdvancedOnboarding modelProvider={modelProvider} />
|
||||
</TabsContent>
|
||||
<TabsContent value="ollama">
|
||||
<AdvancedOnboarding modelProvider={modelProvider} />
|
||||
</TabsContent>
|
||||
</CardContent>
|
||||
</Tabs>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,8 +184,9 @@ const config = {
|
|||
".primary-input": {
|
||||
display: "block",
|
||||
width: "100%",
|
||||
height: "40px",
|
||||
borderRadius: "0.375rem",
|
||||
border: "1px solid hsl(var(--border))",
|
||||
border: "1px solid hsl(var(--input))",
|
||||
backgroundColor: "hsl(var(--background))",
|
||||
paddingLeft: "0.75rem",
|
||||
paddingRight: "0.75rem",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue