mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
Merge branch 'redesigning-block-menu' into kpczerwinski/secrt-1320-backend-update
This commit is contained in:
@@ -43,7 +43,7 @@ const Block: BlockComponent = ({
|
||||
"line-clamp-1 font-sans text-xs font-normal leading-5 text-zinc-500 group-disabled:text-zinc-400",
|
||||
)}
|
||||
>
|
||||
{description}
|
||||
{description && highlightText(description, highlightedText)}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -71,9 +71,9 @@ const BlockMenuSearchBar: React.FC<BlockMenuSearchBarProps> = ({
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={handleClear}
|
||||
className="h-6 w-6 p-0 hover:bg-zinc-100"
|
||||
className="p-0 hover:bg-transparent"
|
||||
>
|
||||
<X className="h-4 w-4 text-zinc-500" />
|
||||
<X className="h-6 w-6 text-zinc-700" strokeWidth={2} />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -45,7 +45,7 @@ const ErrorState: React.FC<ErrorStateProps> = ({
|
||||
variant="default"
|
||||
size="sm"
|
||||
onClick={onRetry}
|
||||
className="mt-2 h-7 text-xs"
|
||||
className="mt-2 h-7 bg-zinc-800 text-xs"
|
||||
>
|
||||
<RefreshCw className="mr-1 h-3 w-3" />
|
||||
{retryLabel}
|
||||
|
||||
@@ -73,7 +73,7 @@ const IntegrationBlock: IntegrationBlockComponent = ({
|
||||
"line-clamp-1 font-sans text-xs font-normal leading-5 text-zinc-500 group-disabled:text-zinc-400",
|
||||
)}
|
||||
>
|
||||
{description}
|
||||
{description && highlightText(description, highlightedText)}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { beautifyString, cn } from "@/lib/utils";
|
||||
import Image from "next/image";
|
||||
import React, { ButtonHTMLAttributes } from "react";
|
||||
|
||||
@@ -39,8 +39,8 @@ const IntegrationChip: IntegrationChipComponent = ({
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<span className="font-sans text-sm font-normal leading-[1.375rem] text-zinc-800">
|
||||
{name}
|
||||
<span className="truncate font-sans text-sm font-normal leading-[1.375rem] text-zinc-800">
|
||||
{name && beautifyString(name)}
|
||||
</span>
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Plus } from "lucide-react";
|
||||
import { ExternalLink, Plus } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import React, { ButtonHTMLAttributes } from "react";
|
||||
import { highlightText } from "./IntegrationBlock";
|
||||
import Link from "next/link";
|
||||
|
||||
interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
title?: string;
|
||||
@@ -12,6 +13,7 @@ interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
number_of_runs?: number;
|
||||
image_url?: string;
|
||||
highlightedText?: string;
|
||||
slug: string;
|
||||
}
|
||||
|
||||
interface MarketplaceAgentBlockComponent extends React.FC<Props> {
|
||||
@@ -25,6 +27,7 @@ const MarketplaceAgentBlock: MarketplaceAgentBlockComponent = ({
|
||||
number_of_runs,
|
||||
className,
|
||||
highlightedText,
|
||||
slug,
|
||||
...rest
|
||||
}) => {
|
||||
return (
|
||||
@@ -58,7 +61,7 @@ const MarketplaceAgentBlock: MarketplaceAgentBlockComponent = ({
|
||||
<div className="flex items-center space-x-2.5">
|
||||
<span
|
||||
className={cn(
|
||||
"line-clamp-1 font-sans text-xs font-normal leading-5 text-zinc-500 group-disabled:text-zinc-400",
|
||||
"truncate font-sans text-xs font-normal leading-5 text-zinc-500 group-disabled:text-zinc-400",
|
||||
)}
|
||||
>
|
||||
By {creator_name}
|
||||
@@ -68,11 +71,21 @@ const MarketplaceAgentBlock: MarketplaceAgentBlockComponent = ({
|
||||
|
||||
<span
|
||||
className={cn(
|
||||
"line-clamp-1 font-sans text-xs font-normal leading-5 text-zinc-500 group-disabled:text-zinc-400",
|
||||
"truncate font-sans text-xs font-normal leading-5 text-zinc-500 group-disabled:text-zinc-400",
|
||||
)}
|
||||
>
|
||||
{number_of_runs} runs
|
||||
</span>
|
||||
<span className="font-sans text-zinc-400">•</span>
|
||||
<Link
|
||||
href={`/marketplace/agent/${creator_name}/${slug}`}
|
||||
className="flex gap-0.5 truncate"
|
||||
>
|
||||
<span className="font-sans text-xs leading-5 text-blue-700 underline">
|
||||
Agent page
|
||||
</span>
|
||||
<ExternalLink className="h-4 w-4 text-blue-700" strokeWidth={1} />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, Fragment } from "react";
|
||||
import React, { useState, useEffect, Fragment, useCallback } from "react";
|
||||
import Block from "../Block";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
@@ -7,6 +7,7 @@ import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
import { BlockCategoryResponse } from "@/lib/autogpt-server-api";
|
||||
import { useBlockMenuContext } from "../block-menu-provider";
|
||||
import ErrorState from "../ErrorState";
|
||||
import { beautifyString } from "@/lib/utils";
|
||||
|
||||
const AllBlocksContent: React.FC = () => {
|
||||
const { addNode } = useBlockMenuContext();
|
||||
@@ -19,7 +20,7 @@ const AllBlocksContent: React.FC = () => {
|
||||
|
||||
const api = useBackendAPI();
|
||||
|
||||
const fetchBlocks = async () => {
|
||||
const fetchBlocks = useCallback(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
@@ -33,11 +34,11 @@ const AllBlocksContent: React.FC = () => {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
}, [api]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchBlocks();
|
||||
}, [api]);
|
||||
}, [api, fetchBlocks]);
|
||||
|
||||
const fetchMoreBlockOfACategory = async (category: string) => {
|
||||
try {
|
||||
@@ -65,19 +66,21 @@ const AllBlocksContent: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
if (!loading) {
|
||||
return (
|
||||
<div className="w-full space-y-3 p-4">
|
||||
{[0, 1, 3].map((categoryIndex) => (
|
||||
<Fragment key={categoryIndex}>
|
||||
{categoryIndex > 0 && (
|
||||
<Skeleton className="my-4 h-[1px] w-full text-zinc-100" />
|
||||
)}
|
||||
{[0, 1, 2].map((blockIndex) => (
|
||||
<Block.Skeleton key={`${categoryIndex}-${blockIndex}`} />
|
||||
))}
|
||||
</Fragment>
|
||||
))}
|
||||
<div className="scrollbar-thumb-rounded h-full overflow-y-auto pt-4 transition-all duration-200 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-transparent hover:scrollbar-thumb-zinc-200">
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
{[0, 1, 3].map((categoryIndex) => (
|
||||
<Fragment key={categoryIndex}>
|
||||
{categoryIndex > 0 && (
|
||||
<Skeleton className="my-4 h-[1px] w-full text-zinc-100" />
|
||||
)}
|
||||
{[0, 1, 2].map((blockIndex) => (
|
||||
<Block.Skeleton key={`${categoryIndex}-${blockIndex}`} />
|
||||
))}
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -107,7 +110,7 @@ const AllBlocksContent: React.FC = () => {
|
||||
<div className="space-y-2.5">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="font-sans text-sm font-medium leading-[1.375rem] text-zinc-800">
|
||||
{category.name}
|
||||
{category.name && beautifyString(category.name)}
|
||||
</p>
|
||||
<span className="rounded-full bg-zinc-100 px-[0.375rem] font-sans text-sm leading-[1.375rem] text-zinc-600">
|
||||
{category.total_blocks}
|
||||
|
||||
@@ -6,7 +6,6 @@ const BlockMenuSidebar: React.FC = ({}) => {
|
||||
const { defaultState, setDefaultState, setIntegration } =
|
||||
useBlockMenuContext();
|
||||
|
||||
// TEMPORARY FETCHING
|
||||
const topLevelMenuItems = [
|
||||
{
|
||||
name: "Suggestion",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import React, { useState, useEffect, Fragment } from "react";
|
||||
import React, { useState, useEffect, Fragment, useCallback } from "react";
|
||||
import IntegrationBlock from "../IntegrationBlock";
|
||||
import { useBlockMenuContext } from "../block-menu-provider";
|
||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
@@ -15,7 +15,7 @@ const IntegrationBlocks: React.FC = ({}) => {
|
||||
|
||||
const api = useBackendAPI();
|
||||
|
||||
const fetchBlocks = async () => {
|
||||
const fetchBlocks = useCallback(async () => {
|
||||
if (integration) {
|
||||
try {
|
||||
setLoading(true);
|
||||
@@ -33,11 +33,11 @@ const IntegrationBlocks: React.FC = ({}) => {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
}, [api, integration]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchBlocks();
|
||||
}, [api, integration]);
|
||||
}, [api, integration, fetchBlocks]);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
|
||||
@@ -19,10 +19,15 @@ const MarketplaceAgentsContent: React.FC = () => {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="w-full space-y-3 p-4">
|
||||
{[0, 1, 2, 3, 4].map((index) => (
|
||||
<MarketplaceAgentBlock.Skeleton key={index} />
|
||||
))}
|
||||
<div
|
||||
ref={scrollRef}
|
||||
className="scrollbar-thumb-rounded h-full overflow-y-auto pt-4 transition-all duration-200 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-transparent hover:scrollbar-thumb-zinc-200"
|
||||
>
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
{[0, 1, 2, 3, 4].map((index) => (
|
||||
<MarketplaceAgentBlock.Skeleton key={index} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -48,6 +53,7 @@ const MarketplaceAgentsContent: React.FC = () => {
|
||||
{agents.map((agent) => (
|
||||
<MarketplaceAgentBlock
|
||||
key={agent.slug}
|
||||
slug={agent.slug}
|
||||
title={agent.agent_name}
|
||||
image_url={agent.agent_image}
|
||||
creator_name={agent.creator}
|
||||
|
||||
@@ -19,10 +19,15 @@ const MyAgentsContent: React.FC = () => {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="w-full space-y-3 p-4">
|
||||
{[0, 1, 2, 3, 4].map((index) => (
|
||||
<UGCAgentBlock.Skeleton key={index} />
|
||||
))}
|
||||
<div
|
||||
ref={scrollRef}
|
||||
className="scrollbar-thumb-rounded h-full overflow-y-auto pt-4 transition-all duration-200 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-transparent hover:scrollbar-thumb-zinc-200"
|
||||
>
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
{[0, 1, 2, 3, 4].map((index) => (
|
||||
<UGCAgentBlock.Skeleton key={index} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -27,26 +27,9 @@ const PaginatedBlocksContent: React.FC<PaginatedBlocksContentProps> = ({
|
||||
pageSize,
|
||||
});
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="w-full space-y-3 p-4">
|
||||
{[0, 1, 3].map((categoryIndex) => (
|
||||
<Fragment key={categoryIndex}>
|
||||
{categoryIndex > 0 && (
|
||||
<div className="my-4 h-[1px] w-full bg-zinc-100" />
|
||||
)}
|
||||
{[0, 1, 2].map((blockIndex) => (
|
||||
<Block.Skeleton key={`${categoryIndex}-${blockIndex}`} />
|
||||
))}
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="w-full px-4 pb-4">
|
||||
<div className="h-full w-full px-4 pb-4">
|
||||
<ErrorState
|
||||
title="Failed to load blocks"
|
||||
error={error}
|
||||
|
||||
@@ -21,10 +21,15 @@ const PaginatedIntegrationList: React.FC = () => {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="w-full space-y-3 p-4">
|
||||
{[0, 1, 3].map((integrationIndex) => (
|
||||
<Integration.Skeleton key={integrationIndex} />
|
||||
))}
|
||||
<div
|
||||
ref={scrollRef}
|
||||
className="scrollbar-thumb-rounded h-full overflow-y-auto pt-4 transition-all duration-200 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-transparent hover:scrollbar-thumb-zinc-200"
|
||||
>
|
||||
<div className="w-full space-y-3 px-4 pb-4">
|
||||
{[0, 1, 3, 4, 5].map((integrationIndex) => (
|
||||
<Integration.Skeleton key={integrationIndex} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import SearchHistoryChip from "../SearchHistoryChip";
|
||||
import IntegrationChip from "../IntegrationChip";
|
||||
import Block from "../Block";
|
||||
@@ -21,7 +21,7 @@ const SuggestionContent: React.FC = () => {
|
||||
|
||||
const api = useBackendAPI();
|
||||
|
||||
const fetchSuggestions = async () => {
|
||||
const fetchSuggestions = useCallback(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
@@ -35,11 +35,11 @@ const SuggestionContent: React.FC = () => {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
}, [api]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchSuggestions();
|
||||
}, [api]);
|
||||
}, [api, fetchSuggestions]);
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
@@ -57,7 +57,7 @@ const SuggestionContent: React.FC = () => {
|
||||
<div className="scrollbar-thumb-rounded h-full overflow-y-auto pt-4 transition-all duration-200 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-transparent hover:scrollbar-thumb-zinc-200">
|
||||
<div className="w-full space-y-6 pb-4">
|
||||
{/* Recent Searches */}
|
||||
<div className="-mb-2 space-y-2.5">
|
||||
{/* <div className="-mb-2 space-y-2.5">
|
||||
<p className="px-4 font-sans text-sm font-medium leading-[1.375rem] text-zinc-800">
|
||||
Recent searches
|
||||
</p>
|
||||
@@ -98,7 +98,7 @@ const SuggestionContent: React.FC = () => {
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
{/* Integrations */}
|
||||
<div className="space-y-2.5 px-4">
|
||||
|
||||
@@ -15,7 +15,7 @@ const BlockMenuSearch: React.FC = ({}) => {
|
||||
} = useBlockMenuContext();
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [hasMore, setHasMore] = useState<boolean>(true);
|
||||
const [page, setPage] = useState<number>(0);
|
||||
const [page, setPage] = useState<number>(1);
|
||||
const [loadingMore, setLoadingMore] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
@@ -59,8 +59,10 @@ const BlockMenuSearch: React.FC = ({}) => {
|
||||
setCategoryCounts(response.total_items);
|
||||
|
||||
if (isLoadMore) {
|
||||
console.log("search list : ", response.items);
|
||||
setSearchData((prev) => [...prev, ...response.items]);
|
||||
} else {
|
||||
console.log("initial list : ", response.items);
|
||||
setSearchData(response.items);
|
||||
}
|
||||
|
||||
@@ -74,7 +76,7 @@ const BlockMenuSearch: React.FC = ({}) => {
|
||||
: "Failed to load search results",
|
||||
);
|
||||
if (!isLoadMore) {
|
||||
setPage(0);
|
||||
setPage(1);
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
@@ -113,14 +115,14 @@ const BlockMenuSearch: React.FC = ({}) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (searchQuery) {
|
||||
setPage(0);
|
||||
setPage(1);
|
||||
setHasMore(true);
|
||||
setError(null);
|
||||
fetchSearchData(0, false);
|
||||
fetchSearchData(1, false);
|
||||
} else {
|
||||
setSearchData([]);
|
||||
setError(null);
|
||||
setPage(0);
|
||||
setPage(1);
|
||||
setHasMore(true);
|
||||
}
|
||||
}, [searchQuery, searchId, filters, fetchSearchData, setSearchData]);
|
||||
@@ -137,9 +139,9 @@ const BlockMenuSearch: React.FC = ({}) => {
|
||||
hasMore={hasMore}
|
||||
error={error}
|
||||
onRetry={() => {
|
||||
setPage(0);
|
||||
setPage(1);
|
||||
setError(null);
|
||||
fetchSearchData(0, false);
|
||||
fetchSearchData(1, false);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -94,6 +94,7 @@ const SearchList: React.FC<SearchListProps> = ({
|
||||
return (
|
||||
<MarketplaceAgentBlock
|
||||
key={index}
|
||||
slug={item.slug}
|
||||
highlightedText={searchQuery}
|
||||
title={item.agent_name}
|
||||
image_url={item.agent_image}
|
||||
|
||||
Reference in New Issue
Block a user