From b3671af5d76a749dfd941b17edcf04cde7138b1b Mon Sep 17 00:00:00 2001 From: Swifty Date: Fri, 23 May 2025 21:40:53 +0100 Subject: [PATCH] fix(frontend): default missing provider icon --- autogpt_platform/common/providers.json | 154 ++++++++++++++++++ .../profile/(user)/integrations/page.tsx | 30 ++-- .../integrations/credentials-input.tsx | 59 +------ .../integrations/credentials-provider.tsx | 46 +----- .../src/lib/autogpt-server-api/types.ts | 44 +---- .../frontend/src/lib/provider-meta.ts | 60 +++++++ 6 files changed, 241 insertions(+), 152 deletions(-) create mode 100644 autogpt_platform/common/providers.json create mode 100644 autogpt_platform/frontend/src/lib/provider-meta.ts diff --git a/autogpt_platform/common/providers.json b/autogpt_platform/common/providers.json new file mode 100644 index 0000000000..8d5d526f61 --- /dev/null +++ b/autogpt_platform/common/providers.json @@ -0,0 +1,154 @@ +[ + { + "id": "anthropic", + "display_name": "Anthropic" + }, + { + "id": "apollo", + "display_name": "Apollo" + }, + { + "id": "discord", + "display_name": "Discord", + "icon": "FaDiscord" + }, + { + "id": "d_id", + "display_name": "D-ID" + }, + { + "id": "e2b", + "display_name": "E2B" + }, + { + "id": "exa", + "display_name": "Exa" + }, + { + "id": "fal", + "display_name": "FAL" + }, + { + "id": "github", + "display_name": "GitHub", + "icon": "FaGithub" + }, + { + "id": "google", + "display_name": "Google", + "icon": "FaGoogle" + }, + { + "id": "google_maps", + "display_name": "Google Maps", + "icon": "FaGoogle" + }, + { + "id": "groq", + "display_name": "Groq" + }, + { + "id": "hubspot", + "display_name": "Hubspot", + "icon": "FaHubspot" + }, + { + "id": "ideogram", + "display_name": "Ideogram" + }, + { + "id": "jina", + "display_name": "Jina" + }, + { + "id": "linear", + "display_name": "Linear" + }, + { + "id": "medium", + "display_name": "Medium", + "icon": "FaMedium" + }, + { + "id": "mem0", + "display_name": "Mem0" + }, + { + "id": "notion", + "display_name": "Notion", + "icon": "NotionLogoIcon" + }, + { + "id": "nvidia", + "display_name": "Nvidia" + }, + { + "id": "ollama", + "display_name": "Ollama" + }, + { + "id": "openai", + "display_name": "OpenAI" + }, + { + "id": "openweathermap", + "display_name": "OpenWeatherMap" + }, + { + "id": "open_router", + "display_name": "Open Router" + }, + { + "id": "llama_api", + "display_name": "Llama API" + }, + { + "id": "pinecone", + "display_name": "Pinecone" + }, + { + "id": "screenshotone", + "display_name": "ScreenshotOne" + }, + { + "id": "slant3d", + "display_name": "Slant3D" + }, + { + "id": "smartlead", + "display_name": "SmartLead" + }, + { + "id": "smtp", + "display_name": "SMTP" + }, + { + "id": "reddit", + "display_name": "Reddit" + }, + { + "id": "replicate", + "display_name": "Replicate" + }, + { + "id": "revid", + "display_name": "Rev.ID" + }, + { + "id": "twitter", + "display_name": "Twitter", + "icon": "FaTwitter" + }, + { + "id": "todoist", + "display_name": "Todoist" + }, + { + "id": "unreal_speech", + "display_name": "Unreal Speech" + }, + { + "id": "zerobounce", + "display_name": "ZeroBounce" + } +] diff --git a/autogpt_platform/frontend/src/app/(platform)/profile/(user)/integrations/page.tsx b/autogpt_platform/frontend/src/app/(platform)/profile/(user)/integrations/page.tsx index 710ee10592..1610da0ad9 100644 --- a/autogpt_platform/frontend/src/app/(platform)/profile/(user)/integrations/page.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/profile/(user)/integrations/page.tsx @@ -5,7 +5,7 @@ import { useCallback, useContext, useMemo, useState } from "react"; import { useToast } from "@/components/ui/use-toast"; import { IconKey, IconUser } from "@/components/ui/icons"; import { Trash2Icon } from "lucide-react"; -import { providerIcons } from "@/components/integrations/credentials-input"; +import { providerIcons } from "@/lib/provider-meta"; import { CredentialsProvidersContext } from "@/components/integrations/credentials-provider"; import { Table, @@ -133,19 +133,21 @@ export default function PrivatePage() { const allCredentials = providers ? Object.values(providers).flatMap((provider) => - provider.savedCredentials - .filter((cred) => !hiddenCredentials.includes(cred.id)) - .map((credentials) => ({ - ...credentials, - provider: provider.provider, - providerName: provider.providerName, - ProviderIcon: providerIcons[provider.provider], - TypeIcon: { - oauth2: IconUser, - api_key: IconKey, - user_password: IconKey, - }[credentials.type], - })), + provider + ? provider.savedCredentials + .filter((cred) => !hiddenCredentials.includes(cred.id)) + .map((credentials) => ({ + ...credentials, + provider: provider.provider, + providerName: provider.providerName, + ProviderIcon: providerIcons[provider.provider], + TypeIcon: { + oauth2: IconUser, + api_key: IconKey, + user_password: IconKey, + }[credentials.type], + })) + : [], ) : []; diff --git a/autogpt_platform/frontend/src/components/integrations/credentials-input.tsx b/autogpt_platform/frontend/src/components/integrations/credentials-input.tsx index 83e337efe9..2d5ed086b6 100644 --- a/autogpt_platform/frontend/src/components/integrations/credentials-input.tsx +++ b/autogpt_platform/frontend/src/components/integrations/credentials-input.tsx @@ -7,20 +7,10 @@ import { Button } from "@/components/ui/button"; import SchemaTooltip from "@/components/SchemaTooltip"; import useCredentials from "@/hooks/useCredentials"; import { zodResolver } from "@hookform/resolvers/zod"; -import { NotionLogoIcon } from "@radix-ui/react-icons"; -import { - FaDiscord, - FaGithub, - FaTwitter, - FaGoogle, - FaMedium, - FaKey, - FaHubspot, -} from "react-icons/fa"; + import { BlockIOCredentialsSubSchema, CredentialsMetaInput, - CredentialsProviderName, } from "@/lib/autogpt-server-api/types"; import { IconKey, IconKeyPlus, IconUserPlus } from "@/components/ui/icons"; import { @@ -48,52 +38,7 @@ import { SelectValue, } from "@/components/ui/select"; import { useBackendAPI } from "@/lib/autogpt-server-api/context"; - -const fallbackIcon = FaKey; - -// --8<-- [start:ProviderIconsEmbed] -export const providerIcons: Record< - CredentialsProviderName, - React.FC<{ className?: string }> -> = { - anthropic: fallbackIcon, - apollo: fallbackIcon, - e2b: fallbackIcon, - github: FaGithub, - google: FaGoogle, - groq: fallbackIcon, - notion: NotionLogoIcon, - nvidia: fallbackIcon, - discord: FaDiscord, - d_id: fallbackIcon, - google_maps: FaGoogle, - jina: fallbackIcon, - ideogram: fallbackIcon, - linear: fallbackIcon, - medium: FaMedium, - mem0: fallbackIcon, - ollama: fallbackIcon, - openai: fallbackIcon, - openweathermap: fallbackIcon, - open_router: fallbackIcon, - llama_api: fallbackIcon, - pinecone: fallbackIcon, - slant3d: fallbackIcon, - screenshotone: fallbackIcon, - smtp: fallbackIcon, - replicate: fallbackIcon, - reddit: fallbackIcon, - fal: fallbackIcon, - revid: fallbackIcon, - twitter: FaTwitter, - unreal_speech: fallbackIcon, - exa: fallbackIcon, - hubspot: FaHubspot, - smartlead: fallbackIcon, - todoist: fallbackIcon, - zerobounce: fallbackIcon, -}; -// --8<-- [end:ProviderIconsEmbed] +import { providerIcons, CredentialsProviderName } from "@/lib/provider-meta"; export type OAuthPopupResultMessage = { message_type: "oauth_popup_result" } & ( | { diff --git a/autogpt_platform/frontend/src/components/integrations/credentials-provider.tsx b/autogpt_platform/frontend/src/components/integrations/credentials-provider.tsx index d31cda8530..61407dca16 100644 --- a/autogpt_platform/frontend/src/components/integrations/credentials-provider.tsx +++ b/autogpt_platform/frontend/src/components/integrations/credentials-provider.tsx @@ -3,10 +3,13 @@ import { CredentialsDeleteNeedConfirmationResponse, CredentialsDeleteResponse, CredentialsMetaResponse, - CredentialsProviderName, - PROVIDER_NAMES, UserPasswordCredentials, } from "@/lib/autogpt-server-api"; +import { + CredentialsProviderName, + providerDisplayNames, + PROVIDER_NAMES, +} from "@/lib/provider-meta"; import { useBackendAPI } from "@/lib/autogpt-server-api/context"; import { createContext, useCallback, useEffect, useState } from "react"; @@ -16,44 +19,7 @@ const CREDENTIALS_PROVIDER_NAMES = Object.values( ) as CredentialsProviderName[]; // --8<-- [start:CredentialsProviderNames] -const providerDisplayNames: Record = { - anthropic: "Anthropic", - apollo: "Apollo", - discord: "Discord", - d_id: "D-ID", - e2b: "E2B", - exa: "Exa", - fal: "FAL", - github: "GitHub", - google: "Google", - google_maps: "Google Maps", - groq: "Groq", - hubspot: "Hubspot", - ideogram: "Ideogram", - jina: "Jina", - linear: "Linear", - medium: "Medium", - mem0: "Mem0", - notion: "Notion", - nvidia: "Nvidia", - ollama: "Ollama", - openai: "OpenAI", - openweathermap: "OpenWeatherMap", - open_router: "Open Router", - llama_api: "Llama API", - pinecone: "Pinecone", - screenshotone: "ScreenshotOne", - slant3d: "Slant3D", - smartlead: "SmartLead", - smtp: "SMTP", - reddit: "Reddit", - replicate: "Replicate", - revid: "Rev.ID", - twitter: "Twitter", - todoist: "Todoist", - unreal_speech: "Unreal Speech", - zerobounce: "ZeroBounce", -} as const; +// Re-exported from the shared provider metadata // --8<-- [end:CredentialsProviderNames] type APIKeyCredentialsCreatable = Omit< diff --git a/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts b/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts index 1aec142578..640273afb4 100644 --- a/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts +++ b/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts @@ -148,49 +148,11 @@ export type Credentials = | UserPasswordCredentials; // --8<-- [start:BlockIOCredentialsSubSchema] -export const PROVIDER_NAMES = { - ANTHROPIC: "anthropic", - APOLLO: "apollo", - D_ID: "d_id", - DISCORD: "discord", - E2B: "e2b", - EXA: "exa", - FAL: "fal", - GITHUB: "github", - GOOGLE: "google", - GOOGLE_MAPS: "google_maps", - GROQ: "groq", - HUBSPOT: "hubspot", - IDEOGRAM: "ideogram", - JINA: "jina", - LINEAR: "linear", - MEDIUM: "medium", - MEM0: "mem0", - NOTION: "notion", - NVIDIA: "nvidia", - OLLAMA: "ollama", - OPENAI: "openai", - OPENWEATHERMAP: "openweathermap", - OPEN_ROUTER: "open_router", - LLAMA_API: "llama_api", - PINECONE: "pinecone", - SCREENSHOTONE: "screenshotone", - SLANT3D: "slant3d", - SMARTLEAD: "smartlead", - SMTP: "smtp", - TWITTER: "twitter", - REPLICATE: "replicate", - REDDIT: "reddit", - REVID: "revid", - UNREAL_SPEECH: "unreal_speech", - TODOIST: "todoist", - ZEROBOUNCE: "zerobounce", -} as const; +import type { CredentialsProviderName } from "../provider-meta"; +export { PROVIDER_NAMES } from "../provider-meta"; +export type { CredentialsProviderName }; // --8<-- [end:BlockIOCredentialsSubSchema] -export type CredentialsProviderName = - (typeof PROVIDER_NAMES)[keyof typeof PROVIDER_NAMES]; - export type BlockIOCredentialsSubSchema = BlockIOObjectSubSchema & { /* Mirror of backend/data/model.py:CredentialsFieldSchemaExtra */ credentials_provider: CredentialsProviderName[]; diff --git a/autogpt_platform/frontend/src/lib/provider-meta.ts b/autogpt_platform/frontend/src/lib/provider-meta.ts new file mode 100644 index 0000000000..418ff5b86e --- /dev/null +++ b/autogpt_platform/frontend/src/lib/provider-meta.ts @@ -0,0 +1,60 @@ +import providers from "../../../common/providers.json"; +import { + FaGithub, + FaGoogle, + FaDiscord, + FaMedium, + FaHubspot, + FaTwitter, + FaKey, +} from "react-icons/fa"; +import { NotionLogoIcon } from "@radix-ui/react-icons"; +import type { FC } from "react"; + +export type ProviderMeta = { + id: string; + display_name: string; + icon?: string; +}; +export const providersList = providers as ProviderMeta[]; + +export const PROVIDER_NAMES = providersList.reduce( + (acc, p) => { + (acc as any)[p.id.toUpperCase()] = p.id; + return acc; + }, + {} as Record, +) as { + [K in keyof any]: string; +}; +export type CredentialsProviderName = (typeof providersList)[number]["id"]; + +const fallbackIcon = FaKey; +const iconMap: Record> = { + FaGithub, + FaGoogle, + FaDiscord, + FaMedium, + FaHubspot, + FaTwitter, + NotionLogoIcon, + fallbackIcon, +}; + +export const providerIcons = providersList.reduce( + (acc, p) => { + acc[p.id as CredentialsProviderName] = p.icon + ? iconMap[p.icon] || fallbackIcon + : fallbackIcon; + return acc; + }, + {} as Record>, +); + +export const providerDisplayNames = providersList.reduce( + (acc, p) => { + acc[p.id as CredentialsProviderName] = p.display_name; + return acc; + }, + {} as Record, +);