connection integration list and blocks
BIN
autogpt_platform/frontend/public/integrations/anthropic.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
autogpt_platform/frontend/public/integrations/apollo.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
autogpt_platform/frontend/public/integrations/d_id.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
autogpt_platform/frontend/public/integrations/e2b.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
autogpt_platform/frontend/public/integrations/exa.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
autogpt_platform/frontend/public/integrations/fal.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
autogpt_platform/frontend/public/integrations/google_maps.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
autogpt_platform/frontend/public/integrations/groq.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
autogpt_platform/frontend/public/integrations/ideogram.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
autogpt_platform/frontend/public/integrations/jina.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
autogpt_platform/frontend/public/integrations/llama_api.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
autogpt_platform/frontend/public/integrations/nvidia.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
autogpt_platform/frontend/public/integrations/ollama.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
autogpt_platform/frontend/public/integrations/open_router.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
autogpt_platform/frontend/public/integrations/openai.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
autogpt_platform/frontend/public/integrations/replicate.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
autogpt_platform/frontend/public/integrations/revid.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
autogpt_platform/frontend/public/integrations/screenshotone.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
autogpt_platform/frontend/public/integrations/slant3d.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
autogpt_platform/frontend/public/integrations/smartlead.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
autogpt_platform/frontend/public/integrations/twitter.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
BIN
autogpt_platform/frontend/public/integrations/zerobounce.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
@@ -32,13 +32,14 @@ const Integration: IntegrationComponent = ({
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<div className="relative h-[2.625rem] w-[2.625rem] rounded-[0.5rem] bg-white">
|
||||
<div className="relative h-[2.625rem] w-[2.625rem] overflow-hidden rounded-[0.5rem] bg-white">
|
||||
{icon_url && (
|
||||
// TODO : handle fallback
|
||||
<Image
|
||||
src={icon_url}
|
||||
alt="integration-icon"
|
||||
fill
|
||||
className="w-full object-contain group-disabled:opacity-50"
|
||||
className="w-full rounded-[0.5rem] object-contain group-disabled:opacity-50"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { Block } from "@/lib/autogpt-server-api";
|
||||
import { Block, CredentialsProviderName } from "@/lib/autogpt-server-api";
|
||||
import { createContext, ReactNode, useContext, useState } from "react";
|
||||
|
||||
interface BaseSearchItem {
|
||||
@@ -82,8 +82,10 @@ export interface Filters {
|
||||
interface BlockMenuContextType {
|
||||
defaultState: DefaultStateType;
|
||||
setDefaultState: React.Dispatch<React.SetStateAction<DefaultStateType>>;
|
||||
integration: string;
|
||||
setIntegration: React.Dispatch<React.SetStateAction<string>>;
|
||||
integration: CredentialsProviderName | null;
|
||||
setIntegration: React.Dispatch<
|
||||
React.SetStateAction<CredentialsProviderName | null>
|
||||
>;
|
||||
searchQuery: string;
|
||||
setSearchQuery: React.Dispatch<React.SetStateAction<string>>;
|
||||
filters: Filters;
|
||||
@@ -120,7 +122,8 @@ export function BlockMenuStateProvider({
|
||||
}: BlockMenuStateProviderProps) {
|
||||
const [defaultState, setDefaultState] =
|
||||
useState<DefaultStateType>("suggestion");
|
||||
const [integration, setIntegration] = useState("");
|
||||
const [integration, setIntegration] =
|
||||
useState<CredentialsProviderName | null>(null);
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [filters, setFilters] = useState<Filters>({
|
||||
categories: {
|
||||
|
||||
@@ -43,7 +43,7 @@ const BlockMenuSidebar: React.FC = ({}) => {
|
||||
type: "integrations",
|
||||
number: 24,
|
||||
onClick: () => {
|
||||
setIntegration("");
|
||||
setIntegration(null);
|
||||
setDefaultState("integrations");
|
||||
},
|
||||
},
|
||||
|
||||
@@ -6,36 +6,28 @@ import {
|
||||
integrationsListData,
|
||||
} from "../../testing_data";
|
||||
import { useBlockMenuContext } from "../block-menu-provider";
|
||||
|
||||
export interface IntegrationBlockData {
|
||||
title: string;
|
||||
description: string;
|
||||
icon_url: string;
|
||||
}
|
||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
import { Block } from "@/lib/autogpt-server-api";
|
||||
|
||||
const IntegrationBlocks: React.FC = ({}) => {
|
||||
const { integration, setIntegration } = useBlockMenuContext();
|
||||
const [blocks, setBlocks] = useState<IntegrationBlockData[]>([]);
|
||||
const { integration, setIntegration, addNode } = useBlockMenuContext();
|
||||
const [blocks, setBlocks] = useState<Block[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
|
||||
// TEMPORARY FETCHING
|
||||
useEffect(() => {
|
||||
if (integration) {
|
||||
setIsLoading(true);
|
||||
setTimeout(() => {
|
||||
const foundBlocks = integrationBlocksData[integration] || [];
|
||||
setBlocks(foundBlocks);
|
||||
setIsLoading(false);
|
||||
}, 800);
|
||||
}
|
||||
}, [integration]);
|
||||
const api = useBackendAPI();
|
||||
|
||||
const getBlockCount = (): number => {
|
||||
const integrationData = integrationsListData.find(
|
||||
(item) => item.title === integration,
|
||||
);
|
||||
return integrationData?.number_of_blocks || 0;
|
||||
};
|
||||
useEffect(() => {
|
||||
const fetchBlocks = async () => {
|
||||
if (integration) {
|
||||
setIsLoading(true);
|
||||
const response = await api.getBuilderBlocks({ provider: integration });
|
||||
setBlocks(response.blocks);
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchBlocks();
|
||||
}, [api, integration]);
|
||||
|
||||
return (
|
||||
<div className="space-y-2.5">
|
||||
@@ -45,7 +37,7 @@ const IntegrationBlocks: React.FC = ({}) => {
|
||||
variant={"link"}
|
||||
className="p-0 font-sans text-sm font-medium leading-[1.375rem] text-zinc-800"
|
||||
onClick={() => {
|
||||
setIntegration("");
|
||||
setIntegration(null);
|
||||
}}
|
||||
>
|
||||
Integrations
|
||||
@@ -58,7 +50,7 @@ const IntegrationBlocks: React.FC = ({}) => {
|
||||
</p>
|
||||
</div>
|
||||
<span className="flex h-[1.375rem] w-[1.6875rem] items-center justify-center rounded-[1.25rem] bg-[#f0f0f0] p-1.5 font-sans text-sm leading-[1.375rem] text-zinc-500 group-disabled:text-zinc-400">
|
||||
{getBlockCount()}
|
||||
{blocks.length}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -75,9 +67,17 @@ const IntegrationBlocks: React.FC = ({}) => {
|
||||
{blocks.map((block, index) => (
|
||||
<IntegrationBlock
|
||||
key={index}
|
||||
title={block.title}
|
||||
title={block.name}
|
||||
description={block.description}
|
||||
icon_url={block.icon_url}
|
||||
icon_url={`/integrations/${integration}.png`}
|
||||
onClick={() => {
|
||||
addNode(
|
||||
block.id,
|
||||
block.name,
|
||||
block.hardcodedValues || {},
|
||||
block,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,28 +1,23 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Integration from "../Integration";
|
||||
import { integrationsListData } from "../../testing_data";
|
||||
import { useBlockMenuContext } from "../block-menu-provider";
|
||||
|
||||
export interface IntegrationData {
|
||||
title: string;
|
||||
icon_url: string;
|
||||
description: string;
|
||||
number_of_blocks: number;
|
||||
}
|
||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
import { Provider } from "@/lib/autogpt-server-api";
|
||||
|
||||
const IntegrationList: React.FC = ({}) => {
|
||||
const { setIntegration } = useBlockMenuContext();
|
||||
const [integrations, setIntegrations] = useState<IntegrationData[]>([]);
|
||||
const [integrations, setIntegrations] = useState<Provider[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
|
||||
// TEMPORARY FETCHING
|
||||
const api = useBackendAPI();
|
||||
|
||||
useEffect(() => {
|
||||
const fetchIntegrations = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
|
||||
setIntegrations(integrationsListData);
|
||||
// Some integrations are missing, like twitter or todoist or more
|
||||
const providers = await api.getProviders();
|
||||
setIntegrations(providers.providers);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch integrations:", error);
|
||||
} finally {
|
||||
@@ -31,7 +26,7 @@ const IntegrationList: React.FC = ({}) => {
|
||||
};
|
||||
|
||||
fetchIntegrations();
|
||||
}, []);
|
||||
}, [api]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -50,11 +45,11 @@ const IntegrationList: React.FC = ({}) => {
|
||||
{integrations.map((integration, index) => (
|
||||
<Integration
|
||||
key={index}
|
||||
title={integration.title}
|
||||
icon_url={integration.icon_url}
|
||||
title={integration.name}
|
||||
icon_url={`/integrations/${integration.name}.png`}
|
||||
description={integration.description}
|
||||
number_of_blocks={integration.number_of_blocks}
|
||||
onClick={() => setIntegration(integration.title)}
|
||||
number_of_blocks={integration.integration_count}
|
||||
onClick={() => setIntegration(integration.name)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@ const IntegrationsContent: React.FC = () => {
|
||||
return (
|
||||
<div className="scrollbar-thumb-rounded h-full overflow-y-auto pt-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200">
|
||||
<div className="w-full px-4 pb-4">
|
||||
{integration == "" ? <IntegrationList /> : <IntegrationBlocks />}
|
||||
{!integration ? <IntegrationList /> : <IntegrationBlocks />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -3,7 +3,10 @@ import SearchHistoryChip from "../SearchHistoryChip";
|
||||
import IntegrationChip from "../IntegrationChip";
|
||||
import Block from "../Block";
|
||||
import { useBlockMenuContext } from "../block-menu-provider";
|
||||
import { SuggestionsResponse } from "@/lib/autogpt-server-api";
|
||||
import {
|
||||
CredentialsProviderName,
|
||||
SuggestionsResponse,
|
||||
} from "@/lib/autogpt-server-api";
|
||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
|
||||
const SuggestionContent: React.FC = () => {
|
||||
@@ -16,7 +19,6 @@ const SuggestionContent: React.FC = () => {
|
||||
|
||||
const api = useBackendAPI();
|
||||
|
||||
// TEMPORARY FETCHING
|
||||
useEffect(() => {
|
||||
const fetchSuggestions = async () => {
|
||||
try {
|
||||
@@ -33,7 +35,7 @@ const SuggestionContent: React.FC = () => {
|
||||
};
|
||||
|
||||
fetchSuggestions();
|
||||
}, []);
|
||||
}, [api]);
|
||||
|
||||
return (
|
||||
<div className="scrollbar-thumb-rounded h-full overflow-y-auto pt-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-zinc-200">
|
||||
@@ -78,7 +80,7 @@ const SuggestionContent: React.FC = () => {
|
||||
name={provider}
|
||||
onClick={() => {
|
||||
setDefaultState("integrations");
|
||||
setIntegration(provider);
|
||||
setIntegration(provider as CredentialsProviderName);
|
||||
}}
|
||||
/>
|
||||
))
|
||||
|
||||