From 9b58a086b63b1943cabc67ec42730273211a0af8 Mon Sep 17 00:00:00 2001 From: MananTank Date: Fri, 13 Dec 2024 20:08:49 +0000 Subject: [PATCH] [Dashboard] Nebula - Update context filters + Add OG image (#5736) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem solved DASH-615 --- ## PR-Codex overview This PR primarily focuses on enhancing the context filter functionality within the application by introducing support for `walletAddresses`, updating related types, and modifying components to accommodate these changes. ### Detailed summary - Added `walletAddresses` to various types and API parameters. - Updated `SessionContextFilter` to include `wallet_addresses`. - Modified `ChatPageContent` to handle and display `walletAddresses`. - Enhanced `ContextFiltersButton` to show wallet address badges. - Updated form handling to include validation for `walletAddresses`. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` --- .../src/app/nebula-app/(app)/api/chat.ts | 1 + .../src/app/nebula-app/(app)/api/session.ts | 2 + .../src/app/nebula-app/(app)/api/types.ts | 16 +-- .../(app)/components/ChatPageContent.tsx | 46 ++++++- .../components/ContextFilters.stories.tsx | 58 ++++++++- .../(app)/components/ContextFilters.tsx | 120 +++++++++++++----- .../src/app/nebula-app/opengraph-image.png | Bin 0 -> 33810 bytes 7 files changed, 195 insertions(+), 48 deletions(-) create mode 100644 apps/dashboard/src/app/nebula-app/opengraph-image.png diff --git a/apps/dashboard/src/app/nebula-app/(app)/api/chat.ts b/apps/dashboard/src/app/nebula-app/(app)/api/chat.ts index 1135e87c3f9..262103605e9 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/api/chat.ts +++ b/apps/dashboard/src/app/nebula-app/(app)/api/chat.ts @@ -7,6 +7,7 @@ import type { ExecuteConfig } from "./types"; export type ContextFilters = { chainIds?: string[]; contractAddresses?: string[]; + walletAddresses?: string[]; }; export async function promptNebula(params: { diff --git a/apps/dashboard/src/app/nebula-app/(app)/api/session.ts b/apps/dashboard/src/app/nebula-app/(app)/api/session.ts index c4cadb128ee..12052c24810 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/api/session.ts +++ b/apps/dashboard/src/app/nebula-app/(app)/api/session.ts @@ -27,6 +27,7 @@ export async function createSession(params: { body.context_filter = { chain_ids: params.contextFilters.chainIds || [], contract_addresses: params.contextFilters.contractAddresses || [], + wallet_addresses: params.contextFilters.walletAddresses || [], }; } @@ -62,6 +63,7 @@ export async function updateSession(params: { body.context_filter = { chain_ids: params.contextFilters.chainIds || [], contract_addresses: params.contextFilters.contractAddresses || [], + wallet_addresses: params.contextFilters.walletAddresses || [], }; } diff --git a/apps/dashboard/src/app/nebula-app/(app)/api/types.ts b/apps/dashboard/src/app/nebula-app/(app)/api/types.ts index 638d40ecb01..315d1ffbd37 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/api/types.ts +++ b/apps/dashboard/src/app/nebula-app/(app)/api/types.ts @@ -19,6 +19,12 @@ type ClientConfig = { export type ExecuteConfig = EngineConfig | SessionKeyConfig | ClientConfig; +type SessionContextFilter = { + chain_ids: string[] | null; + contract_addresses: string[] | null; + wallet_addresses: string[] | null; +}; + export type SessionInfo = { id: string; account_id: string; @@ -37,10 +43,7 @@ export type SessionInfo = { archived_at: string | null; title: string | null; is_public: boolean | null; - context_filter: { - chain_ids: string[]; - contract_addresses: string[]; - } | null; + context_filter: SessionContextFilter | null; // memory // action: array | null; <-- type of this is not available on https://nebula-api.thirdweb-dev.com/docs#/default/get_session_session__session_id__get }; @@ -50,10 +53,7 @@ export type UpdatedSessionInfo = { modal_name: string; account_id: string; execute_config: ExecuteConfig | null; - context_filter: { - chain_ids: string[]; - contract_addresses: string[]; - } | null; + context_filter: SessionContextFilter | null; }; export type DeletedSessionInfo = { diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx index 92dc3e64aef..498c7eddb09 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx @@ -5,7 +5,8 @@ import { ScrollShadow } from "@/components/ui/ScrollShadow/ScrollShadow"; import { useThirdwebClient } from "@/constants/thirdweb.client"; import type { Account } from "@3rdweb-sdk/react/hooks/useApi"; import { useMutation } from "@tanstack/react-query"; -import { useEffect, useRef, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; +import { useActiveAccount } from "thirdweb/react"; import { type ContextFilters, promptNebula } from "../api/chat"; import { createSession, updateSession } from "../api/session"; import type { ExecuteConfig, SessionInfo } from "../api/types"; @@ -22,6 +23,7 @@ export function ChatPageContent(props: { type: "landing" | "new-chat"; account: Account; }) { + const address = useActiveAccount()?.address; const client = useThirdwebClient(); const [userHasSubmittedMessage, setUserHasSubmittedMessage] = useState(false); const [messages, setMessages] = useState>(() => { @@ -36,17 +38,47 @@ export function ChatPageContent(props: { }); const [_config, setConfig] = useState(); - const [contextFilters, setContextFilters] = useState< + const [hasUserUpdatedContextFilters, setHasUserUpdatedContextFilters] = + useState(false); + + const [_contextFilters, _setContextFilters] = useState< ContextFilters | undefined >(() => { const contextFilterRes = props.session?.context_filter; - if (contextFilterRes) { + const value: ContextFilters = { + chainIds: contextFilterRes?.chain_ids || undefined, + contractAddresses: contextFilterRes?.contract_addresses || undefined, + walletAddresses: contextFilterRes?.wallet_addresses || undefined, + }; + + return value; + }); + + function setContextFilters(filters: ContextFilters | undefined) { + _setContextFilters(filters); + setHasUserUpdatedContextFilters(true); + } + + const isNewSession = !props.session; + + // if this is a new session, user has not manually updated context filters + // and no wallet address is set in context filters, add the current wallet address + const contextFilters = useMemo(() => { + if ( + isNewSession && + !hasUserUpdatedContextFilters && + address && + (!_contextFilters?.walletAddresses || + _contextFilters.walletAddresses.length === 0) + ) { return { - chainIds: contextFilterRes.chain_ids, - contractAddresses: contextFilterRes.contract_addresses, + ..._contextFilters, + walletAddresses: [address], }; } - }); + + return _contextFilters; + }, [_contextFilters, address, isNewSession, hasUserUpdatedContextFilters]); const config = _config || { mode: "client", @@ -293,7 +325,7 @@ export function ChatPageContent(props: { return (
-
+
+
+ + + + + + + + + + +
diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx index 29af4ac1184..d2f9852fbfe 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx @@ -1,6 +1,7 @@ "use client"; import { Spinner } from "@/components/ui/Spinner/Spinner"; +import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Dialog, @@ -42,14 +43,46 @@ export default function ContextFiltersButton(props: { mutationFn: props.updateContextFilters, }); + const chainIds = props.contextFilters?.chainIds; + const contractAddresses = props.contextFilters?.contractAddresses; + const walletAddresses = props.contextFilters?.walletAddresses; + return ( - @@ -74,6 +107,18 @@ export default function ContextFiltersButton(props: { ); } +const commaSeparateListOfAddresses = z.string().refine( + (s) => { + if (s.trim() === "") { + return true; + } + return s.split(",").every((s) => isAddress(s.trim())); + }, + { + message: "Must be a comma-separated list of valid addresses", + }, +); + const formSchema = z.object({ chainIds: z.string().refine( (s) => { @@ -89,18 +134,8 @@ const formSchema = z.object({ message: "Chain IDs must be a comma-separated list of integers", }, ), - contractAddresses: z.string().refine( - (s) => { - if (s.trim() === "") { - return true; - } - return s.trim().split(",").every(isAddress); - }, - { - message: - "Contract addresses must be a comma-separated list of valid addresses", - }, - ), + contractAddresses: commaSeparateListOfAddresses, + walletAddresses: commaSeparateListOfAddresses, }); function ContextFilterDialogContent(props: { @@ -117,25 +152,31 @@ function ContextFilterDialogContent(props: { contractAddresses: props.contextFilters?.contractAddresses ? props.contextFilters.contractAddresses.join(",") : "", + walletAddresses: props.contextFilters?.walletAddresses + ? props.contextFilters.walletAddresses.join(",") + : "", }, reValidateMode: "onChange", }); function onSubmit(values: z.infer) { - const { chainIds, contractAddresses } = values; - const chainIdsArray = chainIds.trim().split(",").filter(Boolean); + const { chainIds, contractAddresses, walletAddresses } = values; + + const chainIdsArray = chainIds.split(",").filter((id) => id.trim()); + const contractAddressesArray = contractAddresses - .trim() .split(",") - .filter(Boolean); - if (chainIdsArray.length === 0 && contractAddressesArray.length === 0) { - props.updateFilters(undefined); - } else { - props.updateFilters({ - chainIds: chainIdsArray, - contractAddresses: contractAddressesArray, - }); - } + .filter((v) => v.trim()); + + const walletAddressesArray = walletAddresses + .split(",") + .filter((v) => v.trim()); + + props.updateFilters({ + chainIds: chainIdsArray, + contractAddresses: contractAddressesArray, + walletAddresses: walletAddressesArray, + }); } return ( @@ -195,6 +236,27 @@ function ContextFilterDialogContent(props: { )} /> + + ( + + Wallet Addresses + + + + + Comma separated list of wallet addresses + + + + )} + />
diff --git a/apps/dashboard/src/app/nebula-app/opengraph-image.png b/apps/dashboard/src/app/nebula-app/opengraph-image.png new file mode 100644 index 0000000000000000000000000000000000000000..6c632879f474cb0a1641b53fecebb5bf25d95456 GIT binary patch literal 33810 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 literal 0 HcmV?d00001