mirror of
https://github.com/langchain-ai/content-writer.git
synced 2026-07-01 21:34:17 -04:00
improve dropdown
This commit is contained in:
+8
-2
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
import { WelcomeDialog } from "@/components/WelcomeDialog";
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ASSISTANT_ID_COOKIE } from "@/constants";
|
||||
import { getCookie, setCookie } from "@/lib/cookies";
|
||||
import { useRules } from "@/hooks/useRules";
|
||||
@@ -12,6 +12,9 @@ import { useUser } from "@/hooks/useUser";
|
||||
import { AssistantsDropdown } from "@/components/AssistantsDropdown";
|
||||
|
||||
export default function Home() {
|
||||
const [refreshAssistants, setRefreshAssistants] = useState<
|
||||
() => Promise<void>
|
||||
>(() => () => Promise.resolve());
|
||||
const { userId } = useUser();
|
||||
const {
|
||||
createAssistant,
|
||||
@@ -22,7 +25,7 @@ export default function Home() {
|
||||
isGetAssistantsLoading,
|
||||
getAssistantsByUserId,
|
||||
updateAssistantMetadata,
|
||||
} = useGraph({ userId });
|
||||
} = useGraph({ userId, refreshAssistants });
|
||||
const {
|
||||
setSystemRules,
|
||||
systemRules,
|
||||
@@ -40,6 +43,9 @@ export default function Home() {
|
||||
getAssistantsByUserId={getAssistantsByUserId}
|
||||
setAssistantId={setAssistantId}
|
||||
userId={userId}
|
||||
onAssistantUpdate={(callback: () => Promise<void>) =>
|
||||
setRefreshAssistants(() => callback)
|
||||
}
|
||||
/>
|
||||
<GeneratedRulesDialog userRules={userRules} />
|
||||
<SystemRulesDialog
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type Assistant } from "@langchain/langgraph-sdk";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Loader } from "lucide-react";
|
||||
import {
|
||||
@@ -14,6 +14,25 @@ import {
|
||||
import { Button } from "./ui/button";
|
||||
import { NewAssistantDialog } from "./NewAssistantDialog";
|
||||
|
||||
/**
|
||||
* ISSUE:
|
||||
* assistant is generated on page load if not already present.
|
||||
* user goes through onboarding flow, creates a new assistant.
|
||||
* this updates the assistant, but the dropdown still only has the old assistant (which doesnt have a name set)
|
||||
* need some sort of callback to trigger a new request when update assistant is called, that will trigger a re-request here.
|
||||
*/
|
||||
|
||||
async function getAssistantsByUserId(
|
||||
userId: string,
|
||||
fields: {
|
||||
getAssistantsByUserId: (userId: string) => Promise<Assistant[]>;
|
||||
setAssistants: (assistants: Assistant[]) => void;
|
||||
}
|
||||
) {
|
||||
const assistants = await fields.getAssistantsByUserId(userId);
|
||||
fields.setAssistants(assistants);
|
||||
}
|
||||
|
||||
export interface AssistantsDropdownProps {
|
||||
selectedAssistantId: string | undefined;
|
||||
isGetAssistantsLoading: boolean;
|
||||
@@ -29,6 +48,7 @@ export interface AssistantsDropdownProps {
|
||||
overrideExisting?: boolean;
|
||||
}
|
||||
) => Promise<Assistant | undefined>;
|
||||
onAssistantUpdate: (callback: () => Promise<void>) => void;
|
||||
}
|
||||
|
||||
export function AssistantsDropdown(props: AssistantsDropdownProps) {
|
||||
@@ -37,28 +57,34 @@ export function AssistantsDropdown(props: AssistantsDropdownProps) {
|
||||
null
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.userId || !props.selectedAssistantId || assistants.length > 0)
|
||||
return;
|
||||
const fetchAssistants = useCallback(async () => {
|
||||
if (!props.userId || !props.selectedAssistantId) return;
|
||||
let assistants = await props.getAssistantsByUserId(props.userId);
|
||||
if (props.selectedAssistantId) {
|
||||
const currentSelectedAssistant = assistants.find(
|
||||
(a) => a.assistant_id === props.selectedAssistantId
|
||||
);
|
||||
|
||||
props.getAssistantsByUserId(props.userId).then((a) => {
|
||||
if (!a.length) {
|
||||
return [];
|
||||
if (currentSelectedAssistant) {
|
||||
const otherAssistants = assistants.filter(
|
||||
(a) => a.assistant_id !== props.selectedAssistantId
|
||||
);
|
||||
assistants = [currentSelectedAssistant, ...otherAssistants];
|
||||
setSelectedAssistant(currentSelectedAssistant);
|
||||
}
|
||||
const selectedAssistant = a.find(
|
||||
(assistant) => assistant.assistant_id === props.selectedAssistantId
|
||||
);
|
||||
if (!selectedAssistant) {
|
||||
return a;
|
||||
}
|
||||
setSelectedAssistant(selectedAssistant);
|
||||
const otherAssistants = a.filter(
|
||||
(assistant) => assistant.assistant_id !== props.selectedAssistantId
|
||||
);
|
||||
setAssistants([selectedAssistant, ...otherAssistants]);
|
||||
});
|
||||
}
|
||||
setAssistants(assistants);
|
||||
}, [props.userId, props.selectedAssistantId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.userId || assistants.length > 0) return;
|
||||
void fetchAssistants();
|
||||
}, [props.userId, props.selectedAssistantId, assistants.length]);
|
||||
|
||||
useEffect(() => {
|
||||
props.onAssistantUpdate(fetchAssistants);
|
||||
}, [props.onAssistantUpdate]);
|
||||
|
||||
const handleChangeAssistant = (assistantId: string) => {
|
||||
if (assistantId === props.selectedAssistantId) return;
|
||||
|
||||
@@ -67,15 +93,15 @@ export function AssistantsDropdown(props: AssistantsDropdownProps) {
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
const dropdownLabel = selectedAssistant
|
||||
? (selectedAssistant.metadata?.assistantName as string)
|
||||
: "Select assistant";
|
||||
|
||||
return (
|
||||
<div className="fixed top-4 left-4 z-50">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline">{dropdownLabel}</Button>
|
||||
<Button variant="outline">
|
||||
{selectedAssistant?.metadata?.assistantName
|
||||
? (selectedAssistant.metadata.assistantName as string)
|
||||
: "Select assistant"}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="min-w-64 ml-4">
|
||||
<DropdownMenuLabel>Assistants</DropdownMenuLabel>
|
||||
@@ -103,10 +129,7 @@ export function AssistantsDropdown(props: AssistantsDropdownProps) {
|
||||
<DropdownMenuRadioItem
|
||||
key={assistant.assistant_id}
|
||||
value={assistant.assistant_id}
|
||||
className={cn(
|
||||
"py-2 cursor-pointer",
|
||||
isSelected && "bg-gray-100"
|
||||
)}
|
||||
className={cn("py-2 cursor-pointer")}
|
||||
>
|
||||
<div className="flex flex-col">
|
||||
<p className="text-sm text-gray-800">{assistantName}</p>
|
||||
|
||||
@@ -11,7 +11,8 @@ export interface GraphInput {
|
||||
}
|
||||
|
||||
export interface UseGraphInput {
|
||||
userId?: string;
|
||||
userId: string | undefined;
|
||||
refreshAssistants: () => void;
|
||||
}
|
||||
|
||||
export function useGraph(input: UseGraphInput) {
|
||||
@@ -142,6 +143,7 @@ export function useGraph(input: UseGraphInput) {
|
||||
const updateAssistant = (assistantId: string) => {
|
||||
setAssistantId(assistantId);
|
||||
setCookie(ASSISTANT_ID_COOKIE, assistantId);
|
||||
input.refreshAssistants();
|
||||
};
|
||||
|
||||
const updateAssistantMetadata = async (
|
||||
@@ -155,6 +157,7 @@ export function useGraph(input: UseGraphInput) {
|
||||
assistantId,
|
||||
fields
|
||||
);
|
||||
input.refreshAssistants();
|
||||
return updatedAssistant;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user