From 7439b8199e6c9afeed2e96693d4c921c87f98ed2 Mon Sep 17 00:00:00 2001 From: Lily Delalande <119957291+lily-de@users.noreply.github.com> Date: Fri, 28 Feb 2025 21:04:50 -0500 Subject: [PATCH] ui: providers new design (#1446) --- ui/desktop/image.d.ts | 5 + ui/desktop/openapi.json | 2 +- ui/desktop/src/App.tsx | 2 +- .../providers/providers/ProviderGrid.tsx | 47 ---- .../providers/providers/ProviderRegistry.tsx | 242 ------------------ .../interfaces/ConfigurationCallbacks.tsx | 7 - .../modals/ProviderConfiguationModal.tsx | 41 --- .../ProviderSetupForm.tsx | 50 ---- .../ProviderSetupHeader.tsx | 16 -- .../actions/DefaultProviderActions.tsx | 67 ----- .../subcomponents/actions/OllamaActions.tsx | 87 ------- .../settings_v2/providers/ProviderGrid.tsx | 74 ++++++ .../providers/ProviderRegistry.tsx | 199 ++++++++++++++ .../providers/ProviderSettingsPage.tsx} | 6 +- .../callbacks/AddProviderParameters.tsx | 0 .../providers/callbacks/CallbackRegistry.tsx | 0 .../callbacks/DeleteProviderParameters.tsx | 0 .../callbacks/RefreshActiveProviders.tsx | 0 .../providers/callbacks/ShowModal.tsx | 0 .../callbacks/UpdateProviderParameters.tsx | 0 .../providers/interfaces/ButtonCallbacks.tsx | 6 + .../interfaces/ConfigurationAction.tsx | 0 .../providers/interfaces/OllamaMetadata.tsx | 0 .../providers/interfaces/ParameterSchema.ts | 0 .../providers/interfaces/ProviderDetails.tsx | 10 +- .../providers/interfaces/ProviderState.tsx | 0 .../modal/ProviderConfiguationModal.tsx | 84 ++++++ .../providers/modal/ProviderModalProvider.tsx | 46 ++++ .../settings_v2/providers/modal/constants.tsx | 1 + .../ProviderConfigurationModalProps.tsx | 0 .../interfaces/ProviderSetupFormProps.tsx | 4 +- .../modal/subcomponents/ProviderLogo.tsx | 33 +++ .../subcomponents}/ProviderSetupActions.tsx | 8 +- .../subcomponents/ProviderSetupHeader.tsx | 29 +++ .../subcomponents}/ProviderSetupOverlay.tsx | 5 +- .../forms/DefaultProviderSetupForm.tsx | 45 ++++ .../modal/subcomponents/icons/anthropic.png | Bin 0 -> 1203 bytes .../subcomponents/icons/anthropic@2x.png | Bin 0 -> 2280 bytes .../subcomponents/icons/anthropic@3x.png | Bin 0 -> 3303 bytes .../modal/subcomponents/icons/databricks.png | Bin 0 -> 1574 bytes .../subcomponents/icons/databricks@2x.png | Bin 0 -> 3444 bytes .../subcomponents/icons/databricks@3x.png | Bin 0 -> 5109 bytes .../modal/subcomponents/icons/google.png | Bin 0 -> 1306 bytes .../modal/subcomponents/icons/google@2x.png | Bin 0 -> 2487 bytes .../modal/subcomponents/icons/google@3x.png | Bin 0 -> 3650 bytes .../modal/subcomponents/icons/groq.png | Bin 0 -> 1223 bytes .../modal/subcomponents/icons/groq@2x.png | Bin 0 -> 2359 bytes .../modal/subcomponents/icons/groq@3x.png | Bin 0 -> 3379 bytes .../modal/subcomponents/icons/ollama.png | Bin 0 -> 1330 bytes .../modal/subcomponents/icons/ollama@2x.png | Bin 0 -> 2858 bytes .../modal/subcomponents/icons/ollama@3x.png | Bin 0 -> 4262 bytes .../modal/subcomponents/icons/openai.png | Bin 0 -> 1272 bytes .../modal/subcomponents/icons/openai.svg | 3 + .../modal/subcomponents/icons/openai@2x.png | Bin 0 -> 2508 bytes .../modal/subcomponents/icons/openai@3x.png | Bin 0 -> 3596 bytes .../modal/subcomponents/icons/openrouter.png | Bin 0 -> 1222 bytes .../subcomponents/icons/openrouter@2x.png | Bin 0 -> 2304 bytes .../subcomponents/icons/openrouter@3x.png | Bin 0 -> 3347 bytes .../providers/parameters/UpdateSecrets.tsx | 0 .../providers/state/ActiveKeysContext.tsx | 0 .../providers/state/types.ts | 0 .../providers/state/utils.tsx | 0 .../providers/subcomponents/CardActions.tsx | 0 .../providers/subcomponents/CardBody.tsx | 3 +- .../providers/subcomponents/CardContainer.tsx | 0 .../providers/subcomponents/CardHeader.tsx | 4 +- .../providers/subcomponents/ProviderCard.tsx | 9 +- .../subcomponents/buttons/CardButtons.tsx} | 67 +++-- .../buttons/DefaultCardButtons.tsx | 77 ++++++ .../subcomponents/buttons}/TooltipWrapper.tsx | 7 +- .../subcomponents/utils/StringUtils.tsx | 0 71 files changed, 682 insertions(+), 604 deletions(-) create mode 100644 ui/desktop/image.d.ts delete mode 100644 ui/desktop/src/components/settings/providers/providers/ProviderGrid.tsx delete mode 100644 ui/desktop/src/components/settings/providers/providers/ProviderRegistry.tsx delete mode 100644 ui/desktop/src/components/settings/providers/providers/interfaces/ConfigurationCallbacks.tsx delete mode 100644 ui/desktop/src/components/settings/providers/providers/modals/ProviderConfiguationModal.tsx delete mode 100644 ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupForm.tsx delete mode 100644 ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupHeader.tsx delete mode 100644 ui/desktop/src/components/settings/providers/providers/subcomponents/actions/DefaultProviderActions.tsx delete mode 100644 ui/desktop/src/components/settings/providers/providers/subcomponents/actions/OllamaActions.tsx create mode 100644 ui/desktop/src/components/settings_v2/providers/ProviderGrid.tsx create mode 100644 ui/desktop/src/components/settings_v2/providers/ProviderRegistry.tsx rename ui/desktop/src/components/{settings/providers/providers/NewProviderSettingsPage.tsx => settings_v2/providers/ProviderSettingsPage.tsx} (90%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/callbacks/AddProviderParameters.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/callbacks/CallbackRegistry.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/callbacks/DeleteProviderParameters.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/callbacks/RefreshActiveProviders.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/callbacks/ShowModal.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/callbacks/UpdateProviderParameters.tsx (100%) create mode 100644 ui/desktop/src/components/settings_v2/providers/interfaces/ButtonCallbacks.tsx rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/interfaces/ConfigurationAction.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/interfaces/OllamaMetadata.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/interfaces/ParameterSchema.ts (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/interfaces/ProviderDetails.tsx (55%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/interfaces/ProviderState.tsx (100%) create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/ProviderConfiguationModal.tsx create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/ProviderModalProvider.tsx create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/constants.tsx rename ui/desktop/src/components/{settings/providers/providers/modals => settings_v2/providers/modal}/interfaces/ProviderConfigurationModalProps.tsx (100%) rename ui/desktop/src/components/{settings/providers/providers/modals => settings_v2/providers/modal}/interfaces/ProviderSetupFormProps.tsx (72%) create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderLogo.tsx rename ui/desktop/src/components/{settings/providers/providers/modals/configuration_modal_subcomponents => settings_v2/providers/modal/subcomponents}/ProviderSetupActions.tsx (75%) create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderSetupHeader.tsx rename ui/desktop/src/components/{settings/providers/providers/modals/configuration_modal_subcomponents => settings_v2/providers/modal/subcomponents}/ProviderSetupOverlay.tsx (60%) create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/forms/DefaultProviderSetupForm.tsx create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/anthropic.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/anthropic@2x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/anthropic@3x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/databricks.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/databricks@2x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/databricks@3x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/google.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/google@2x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/google@3x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/groq.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/groq@2x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/groq@3x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/ollama.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/ollama@2x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/ollama@3x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openai.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openai.svg create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openai@2x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openai@3x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openrouter.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openrouter@2x.png create mode 100644 ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openrouter@3x.png rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/parameters/UpdateSecrets.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/state/ActiveKeysContext.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/state/types.ts (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/state/utils.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/subcomponents/CardActions.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/subcomponents/CardBody.tsx (75%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/subcomponents/CardContainer.tsx (100%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/subcomponents/CardHeader.tsx (91%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/subcomponents/ProviderCard.tsx (79%) rename ui/desktop/src/components/{settings/providers/providers/subcomponents/actions/ActionButtons.tsx => settings_v2/providers/subcomponents/buttons/CardButtons.tsx} (64%) create mode 100644 ui/desktop/src/components/settings_v2/providers/subcomponents/buttons/DefaultCardButtons.tsx rename ui/desktop/src/components/{settings/providers/providers/subcomponents/actions => settings_v2/providers/subcomponents/buttons}/TooltipWrapper.tsx (88%) rename ui/desktop/src/components/{settings/providers => settings_v2}/providers/subcomponents/utils/StringUtils.tsx (100%) diff --git a/ui/desktop/image.d.ts b/ui/desktop/image.d.ts new file mode 100644 index 00000000..bde75ecc --- /dev/null +++ b/ui/desktop/image.d.ts @@ -0,0 +1,5 @@ +declare module '*.png'; +declare module '*.jpg'; +declare module '*.jpeg'; +declare module '*.svg'; +declare module '*.gif'; \ No newline at end of file diff --git a/ui/desktop/openapi.json b/ui/desktop/openapi.json index fae01de5..0cd35edb 100644 --- a/ui/desktop/openapi.json +++ b/ui/desktop/openapi.json @@ -10,7 +10,7 @@ "license": { "name": "Apache-2.0" }, - "version": "1.0.9" + "version": "1.0.10" }, "paths": { "/config": { diff --git a/ui/desktop/src/App.tsx b/ui/desktop/src/App.tsx index bef7f792..634263c4 100644 --- a/ui/desktop/src/App.tsx +++ b/ui/desktop/src/App.tsx @@ -17,7 +17,7 @@ import SettingsView, { type SettingsViewOptions } from './components/settings/Se import SettingsViewV2 from './components/settings_v2/SettingsView'; import MoreModelsView from './components/settings/models/MoreModelsView'; import ConfigureProvidersView from './components/settings/providers/ConfigureProvidersView'; -import ProviderSettings from './components/settings/providers/providers/NewProviderSettingsPage'; +import ProviderSettings from './components/settings_v2/providers/ProviderSettingsPage'; import 'react-toastify/dist/ReactToastify.css'; diff --git a/ui/desktop/src/components/settings/providers/providers/ProviderGrid.tsx b/ui/desktop/src/components/settings/providers/providers/ProviderGrid.tsx deleted file mode 100644 index 3f9cdd85..00000000 --- a/ui/desktop/src/components/settings/providers/providers/ProviderGrid.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react'; -import { ProviderCard } from './subcomponents/ProviderCard'; -import ProviderState from './interfaces/ProviderState'; -import OnShowModal from './callbacks/ShowModal'; -import OnAdd from './callbacks/AddProviderParameters'; -import OnDelete from './callbacks/DeleteProviderParameters'; -import OnShowSettings from './callbacks/UpdateProviderParameters'; -import OnRefresh from './callbacks/RefreshActiveProviders'; -import DefaultProviderActions from './subcomponents/actions/DefaultProviderActions'; - -function GridLayout({ children }: { children: React.ReactNode }) { - return ( -
- {children} -
- ); -} - -function ProviderCards({ providers }: { providers: ProviderState[] }) { - const providerCallbacks = { - onShowModal: OnShowModal, - onAdd: OnAdd, - onDelete: OnDelete, - onShowSettings: OnShowSettings, - onRefresh: OnRefresh, - }; - return ( - <> - {providers.map((provider) => ( - - ))} - - ); -} - -export default function ProviderGrid({ providers }: { providers: ProviderState[] }) { - console.log('got these providers', providers); - return ( - - - - ); -} diff --git a/ui/desktop/src/components/settings/providers/providers/ProviderRegistry.tsx b/ui/desktop/src/components/settings/providers/providers/ProviderRegistry.tsx deleted file mode 100644 index 3a0f7a57..00000000 --- a/ui/desktop/src/components/settings/providers/providers/ProviderRegistry.tsx +++ /dev/null @@ -1,242 +0,0 @@ -import React from 'react'; -import ProviderDetails from './interfaces/ProviderDetails'; -import DefaultProviderActions from './subcomponents/actions/DefaultProviderActions'; -import OllamaActions from './subcomponents/actions/OllamaActions'; - -export interface ProviderRegistry { - name: string; - details: ProviderDetails; -} - -export const PROVIDER_REGISTRY: ProviderRegistry[] = [ - { - name: 'OpenAI', - details: { - id: 'openai', - name: 'OpenAI', - description: 'Access GPT-4, GPT-3.5 Turbo, and other OpenAI models', - parameters: [ - { - name: 'OPENAI_API_KEY', - is_secret: true, - }, - ], - getActions: (provider, callbacks) => { - const { onAdd, onDelete, onShowSettings } = callbacks || {}; - return [ - { - id: 'default-provider-actions', - renderButton: () => ( - - ), - }, - ]; - }, - }, - }, - { - name: 'Anthropic', - details: { - id: 'anthropic', - name: 'Anthropic', - description: 'Access Claude and other Anthropic models', - parameters: [ - { - name: 'ANTHROPIC_API_KEY', - is_secret: true, - }, - ], - getActions: (provider, callbacks) => { - const { onAdd, onDelete, onShowSettings } = callbacks || {}; - return [ - { - id: 'default-provider-actions', - renderButton: () => ( - - ), - }, - ]; - }, - }, - }, - { - name: 'Google', - details: { - id: 'google', - name: 'Google', - description: 'Access Gemini and other Google AI models', - parameters: [ - { - name: 'GOOGLE_API_KEY', - is_secret: true, - }, - ], - getActions: (provider, callbacks) => { - const { onAdd, onDelete, onShowSettings } = callbacks || {}; - return [ - { - id: 'default-provider-actions', - renderButton: () => ( - - ), - }, - ]; - }, - }, - }, - { - name: 'Groq', - details: { - id: 'groq', - name: 'Groq', - description: 'Access Mixtral and other Groq-hosted models', - parameters: [ - { - name: 'GROQ_API_KEY', - is_secret: true, - }, - ], - getActions: (provider, callbacks) => { - const { onAdd, onDelete, onShowSettings } = callbacks || {}; - return [ - { - id: 'default-provider-actions', - renderButton: () => ( - - ), - }, - ]; - }, - }, - }, - { - name: 'Databricks', - details: { - id: 'databricks', - name: 'Databricks', - description: 'Access models hosted on your Databricks instance', - parameters: [ - { - name: 'DATABRICKS_HOST', - is_secret: false, - }, - ], - getActions: (provider, callbacks) => { - const { onAdd, onDelete, onShowSettings } = callbacks || {}; - return [ - { - id: 'default-provider-actions', - renderButton: () => ( - - ), - }, - ]; - }, - }, - }, - { - name: 'OpenRouter', - details: { - id: 'openrouter', - name: 'OpenRouter', - description: 'Access a variety of AI models through OpenRouter', - parameters: [ - { - name: 'OPENROUTER_API_KEY', - is_secret: true, - }, - ], - getActions: (provider, callbacks) => { - const { onAdd, onDelete, onShowSettings } = callbacks || {}; - return [ - { - id: 'default-provider-actions', - renderButton: () => ( - - ), - }, - ]; - }, - }, - }, - { - name: 'Ollama', - details: { - id: 'ollama', - name: 'Ollama', - description: 'Run and use open-source models locally', - parameters: [ - { - name: 'OLLAMA_HOST', - is_secret: false, - }, - ], - getActions: (provider, callbacks) => { - const { onAdd, onDelete, onRefresh, onShowSettings } = callbacks || {}; - return [ - { - id: 'ollama-actions', - renderButton: () => ( - - ), - }, - ]; - }, - }, - }, -]; - -// const ACTION_IMPLEMENTATIONS = { -// 'default': (provider, callbacks) => [{ -// id: 'default-provider-actions', -// renderButton: () => -// }], -// -// 'ollama': (provider, callbacks) => [{ -// id: 'ollama-actions', -// renderButton: () => -// }] -// }; diff --git a/ui/desktop/src/components/settings/providers/providers/interfaces/ConfigurationCallbacks.tsx b/ui/desktop/src/components/settings/providers/providers/interfaces/ConfigurationCallbacks.tsx deleted file mode 100644 index 145cf0d3..00000000 --- a/ui/desktop/src/components/settings/providers/providers/interfaces/ConfigurationCallbacks.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default interface ProviderCallbacks { - onShowModal?: () => void; - onAdd?: () => void; - onDelete?: () => void; - onShowSettings?: () => void; - onRefresh?: () => void; -} diff --git a/ui/desktop/src/components/settings/providers/providers/modals/ProviderConfiguationModal.tsx b/ui/desktop/src/components/settings/providers/providers/modals/ProviderConfiguationModal.tsx deleted file mode 100644 index 87134e32..00000000 --- a/ui/desktop/src/components/settings/providers/providers/modals/ProviderConfiguationModal.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import { Card } from '../../../../ui/card'; -import ProviderSetupOverlay from './configuration_modal_subcomponents/ProviderSetupOverlay'; -import ProviderSetupHeader from './configuration_modal_subcomponents/ProviderSetupHeader'; -import ProviderSetupForm from './configuration_modal_subcomponents/ProviderSetupForm'; -import ProviderSetupActions from './configuration_modal_subcomponents/ProviderSetupActions'; -import ProviderConfiguationModalProps from './interfaces/ProviderConfigurationModalProps'; - -export default function ProviderConfigurationModal({ - provider, - title, - onSubmit, - onCancel, -}: ProviderConfiguationModalProps) { - const [configValues, setConfigValues] = React.useState<{ [key: string]: string }>({}); - const headerText = title || `Setup ${provider}`; - - const handleSubmitForm = (e: React.FormEvent) => { - e.preventDefault(); - onSubmit(configValues); - }; - - return ( - - -
- - - - - -
-
-
- ); -} diff --git a/ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupForm.tsx b/ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupForm.tsx deleted file mode 100644 index d9ffa384..00000000 --- a/ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupForm.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react'; -import { Input } from '../../../../../ui/input'; -import { Lock } from 'lucide-react'; -import { isSecretKey } from '../../../../api_keys/utils'; -import ProviderSetupFormProps from '../interfaces/ProviderSetupFormProps'; -import ParameterSchema from '../../interfaces/ParameterSchema'; - -/** - * Renders the form with required input fields and the "lock" info row. - * The submit/cancel buttons are in a separate ProviderSetupActions component. - */ -export default function ProviderSetupForm({ - configValues, - setConfigValues, - onSubmit, - provider, -}: ProviderSetupFormProps) { - const parameters: ParameterSchema[] = provider.parameters; - return ( -
-
- {parameters.map((parameter) => ( -
- - setConfigValues((prev) => ({ - ...prev, - [parameter.name]: e.target.value, - })) - } - placeholder={parameter.name} - className="w-full h-14 px-4 font-regular rounded-lg border shadow-none border-gray-300 bg-white text-lg placeholder:text-gray-400 font-regular text-gray-900" - required - /> -
- ))} -
- - - Your configuration values will be stored securely in the keychain and used only for - making requests to {provider.name}. - -
-
- {/* The action buttons are not in this form; they're in ProviderSetupActions. */} -
- ); -} diff --git a/ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupHeader.tsx b/ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupHeader.tsx deleted file mode 100644 index 21bd1a70..00000000 --- a/ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupHeader.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; - -interface ProviderSetupHeaderProps { - headerText: string; -} - -/** - * Renders the header (title) for the modal. - */ -export default function ProviderSetupHeader({ headerText }: ProviderSetupHeaderProps) { - return ( -
-

{headerText}

-
- ); -} diff --git a/ui/desktop/src/components/settings/providers/providers/subcomponents/actions/DefaultProviderActions.tsx b/ui/desktop/src/components/settings/providers/providers/subcomponents/actions/DefaultProviderActions.tsx deleted file mode 100644 index dff612ca..00000000 --- a/ui/desktop/src/components/settings/providers/providers/subcomponents/actions/DefaultProviderActions.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import React from 'react'; -import { AddButton, DeleteButton, GearSettingsButton } from './ActionButtons'; - -interface ProviderActionsProps { - name: string; - isConfigured: boolean; - onAdd?: () => void; - onConfigure?: () => void; - onDelete?: () => void; - onShowSettings?: () => void; -} - -function getDefaultTooltipMessages(name: string, actionType: string) { - switch (actionType) { - case 'add': - return `Configure ${name} settings`; - case 'edit': - return `Edit ${name} settings`; - case 'delete': - return `Delete ${name} settings`; - default: - return null; - } -} - -export default function DefaultProviderActions({ - name, - isConfigured, - onAdd, - onDelete, - onShowSettings, -}: ProviderActionsProps) { - return ( - <> - {/*Set up an unconfigured provider */} - {!isConfigured && ( - { - e.stopPropagation(); - onAdd?.(); - }} - /> - )} - {/*Edit settings of configured provider*/} - {isConfigured && ( - { - e.stopPropagation(); - onShowSettings?.(); - }} - /> - )} - {/*Delete configuration*/} - {isConfigured && ( - { - e.stopPropagation(); - onDelete?.(); - }} - /> - )} - - ); -} diff --git a/ui/desktop/src/components/settings/providers/providers/subcomponents/actions/OllamaActions.tsx b/ui/desktop/src/components/settings/providers/providers/subcomponents/actions/OllamaActions.tsx deleted file mode 100644 index 876620b2..00000000 --- a/ui/desktop/src/components/settings/providers/providers/subcomponents/actions/OllamaActions.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import React from 'react'; -import { AddButton, DeleteButton, GearSettingsButton, RefreshButton } from './ActionButtons'; -import OllamaMetadata from '../../interfaces/OllamaMetadata'; - -interface OllamaActionsProps { - isConfigured: boolean; - ollamaMetadata: OllamaMetadata; - onRefresh?: (e: React.MouseEvent) => void; - onAdd?: () => void; - onDelete?: () => void; - onShowSettings?: () => void; -} - -export default function OllamaActions({ - isConfigured, - ollamaMetadata, - onRefresh, - onAdd, - onDelete, - onShowSettings, -}: OllamaActionsProps) { - const showHostDeleteButton = isConfigured && ollamaMetadata.location === 'host' && !onDelete; - - const showRefreshButton = !isConfigured && onRefresh; - - // add host url to overwrite the app url OR if not configured at all yet - const showAddHostUrlButton = - (isConfigured && ollamaMetadata.location === 'app' && onAdd) || (!isConfigured && onAdd); - - const showHostUrlSettingsButton = - isConfigured && ollamaMetadata.location === 'host' && onShowSettings; - - // We’ll figure out which buttons to render: - - // 1) Refresh button if not configured - // 2) If configured via app => show "plus" to switch to host config - // 3) If configured via host => show "X" to remove the host and "gear" to edit - - return ( - // TODO: is this the right class name? -
- {/* (1) Refresh button if not configured */} - {showRefreshButton && ( - { - e.stopPropagation(); - onRefresh?.(e); - }} - > - )} - - {/* (2) If configured location = 'app', show a plus button to switch / set host */} - {showAddHostUrlButton && ( - { - e.stopPropagation(); - onAdd?.(); - }} - > - )} - - {/* (3) If configured location = 'host', show an X to delete or revert config */} - {showHostDeleteButton && ( - { - e.stopPropagation(); - onDelete?.(); - }} - > - )} - - {/* (4) If configured location = 'host', show a gear to view and edit config */} - {showHostUrlSettingsButton && ( - { - e.stopPropagation(); - onShowSettings?.(); - }} - > - )} -
- ); -} diff --git a/ui/desktop/src/components/settings_v2/providers/ProviderGrid.tsx b/ui/desktop/src/components/settings_v2/providers/ProviderGrid.tsx new file mode 100644 index 00000000..25424bda --- /dev/null +++ b/ui/desktop/src/components/settings_v2/providers/ProviderGrid.tsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { ProviderCard } from './subcomponents/ProviderCard'; +import ProviderState from './interfaces/ProviderState'; +import OnRefresh from './callbacks/RefreshActiveProviders'; +import { ProviderModalProvider, useProviderModal } from './modal/ProviderModalProvider'; +import ProviderConfigurationModal from './modal/ProviderConfiguationModal'; + +function GridLayout({ children }: { children: React.ReactNode }) { + return ( +
+ {children} +
+ ); +} + +function ProviderCards({ + providers, + isOnboarding, +}: { + providers: ProviderState[]; + isOnboarding: boolean; +}) { + const { openModal } = useProviderModal(); + + // Define the callbacks for provider actions + const providerCallbacks = { + // Replace your OnShowSettings with the modal opener + onConfigure: (provider: ProviderState) => { + console.log('Configure button clicked for:', provider.name); + openModal(provider, { + onSubmit: (values: any) => { + console.log(`Configuring ${provider.name}:`, values); + // Your logic to save the configuration + }, + formProps: {}, + }); + console.log('openModal called'); // Check if this executes + }, + onLaunch: (provider: ProviderState) => { + OnRefresh(); + }, + }; + + return ( + <> + {providers.map((provider) => ( + + ))} + + ); +} + +export default function ProviderGrid({ + providers, + isOnboarding, +}: { + providers: ProviderState[]; + isOnboarding: boolean; +}) { + console.log('(1) Provider Grid -- is this the onboarding page?', isOnboarding); + return ( + + + + {/* This is missing! */} + + + ); +} diff --git a/ui/desktop/src/components/settings_v2/providers/ProviderRegistry.tsx b/ui/desktop/src/components/settings_v2/providers/ProviderRegistry.tsx new file mode 100644 index 00000000..2cb4c1a8 --- /dev/null +++ b/ui/desktop/src/components/settings_v2/providers/ProviderRegistry.tsx @@ -0,0 +1,199 @@ +import React from 'react'; +import ProviderDetails from './interfaces/ProviderDetails'; +import DefaultCardButtons from './subcomponents/buttons/DefaultCardButtons'; +import ButtonCallbacks from '@/src/components/settings_v2/providers/interfaces/ButtonCallbacks'; +import ProviderState from '@/src/components/settings_v2/providers/interfaces/ProviderState'; + +// Helper function to generate default actions for most providers +const getDefaultButtons = ( + provider: ProviderState, + callbacks: ButtonCallbacks, + isOnboardingPage +) => { + return [ + { + id: 'default-buttons', + renderButton: () => ( + + ), + }, + ]; +}; + +export interface ProviderRegistry { + name: string; + details: ProviderDetails; +} + +/** + * Provider Registry System + * ======================== + * + * This registry defines all available providers and how they behave in the UI. + * It works with a dynamic modal system to create a flexible, extensible architecture + * for managing provider configurations. + * + * How the System Works: + * -------------------- + * + * 1. Provider Definition: + * Each provider entry in the registry defines its core properties: + * - Basic info (id, name, description) + * - Parameters needed for configuration + * - Optional custom form component + * - Action buttons that appear on provider cards + * + * 2. Two-Level Configuration: + * a) Provider Card UI - What buttons appear on each provider card + * - Controlled by the provider's getActions() function + * - Most providers use default buttons (configure/launch) + * - Can be customized for special providers + * + * b) Modal Content - What form appears in the configuration modal + * - A single modal component exists in the app + * - Content changes dynamically based on the provider being configured + * - If provider has CustomForm property, that component is rendered + * - Otherwise, DefaultProviderForm renders based on parameters array + * + * 3. Modal Flow: + * - User clicks Configure button on a provider card + * - Button handler calls openModal() with the provider object + * - Modal context stores the current provider and opens the modal + * - ProviderConfigModal checks for CustomForm on the current provider + * - Appropriate form is rendered with provider data passed as props + * + * Adding a New Provider: + * --------------------- + * + * For a standard provider with simple configuration: + * - Define parameters array with all required fields + * - Use the default getActions function + * - No need to specify a CustomForm + * + * For a provider needing custom configuration: + * - Define parameters array (even if just for documentation) + * - Create a custom form component and assign to CustomForm property + * - Use the default or custom getActions function + * + * This architecture centralizes provider definitions while allowing + * flexibility for special cases, keeping the codebase maintainable. + */ + +export const PROVIDER_REGISTRY: ProviderRegistry[] = [ + { + name: 'OpenAI', + details: { + id: 'openai', + name: 'OpenAI', + description: 'Access GPT-4, GPT-3.5 Turbo, and other OpenAI models', + parameters: [ + { + name: 'OPENAI_API_KEY', + is_secret: true, + }, + ], + getActions: (provider, callbacks, isOnboardingPage) => + getDefaultButtons(provider, callbacks, isOnboardingPage), + }, + }, + { + name: 'Anthropic', + details: { + id: 'anthropic', + name: 'Anthropic', + description: 'Access Claude and other Anthropic models', + parameters: [ + { + name: 'ANTHROPIC_API_KEY', + is_secret: true, + }, + ], + getActions: (provider, callbacks, isOnboardingPage) => + getDefaultButtons(provider, callbacks, isOnboardingPage), + }, + }, + { + name: 'Google', + details: { + id: 'google', + name: 'Google', + description: 'Access Gemini and other Google AI models', + parameters: [ + { + name: 'GOOGLE_API_KEY', + is_secret: true, + }, + ], + getActions: (provider, callbacks, isOnboardingPage) => + getDefaultButtons(provider, callbacks, isOnboardingPage), + }, + }, + { + name: 'Groq', + details: { + id: 'groq', + name: 'Groq', + description: 'Access Mixtral and other Groq-hosted models', + parameters: [ + { + name: 'GROQ_API_KEY', + is_secret: true, + }, + ], + getActions: (provider, callbacks, isOnboardingPage) => + getDefaultButtons(provider, callbacks, isOnboardingPage), + }, + }, + { + name: 'Databricks', + details: { + id: 'databricks', + name: 'Databricks', + description: 'Access models hosted on your Databricks instance', + parameters: [ + { + name: 'DATABRICKS_HOST', + is_secret: false, + }, + ], + getActions: (provider, callbacks, isOnboardingPage) => + getDefaultButtons(provider, callbacks, isOnboardingPage), + }, + }, + { + name: 'OpenRouter', + details: { + id: 'openrouter', + name: 'OpenRouter', + description: 'Access a variety of AI models through OpenRouter', + parameters: [ + { + name: 'OPENROUTER_API_KEY', + is_secret: true, + }, + ], + getActions: (provider, callbacks, isOnboardingPage) => + getDefaultButtons(provider, callbacks, isOnboardingPage), + }, + }, + { + name: 'Ollama', + details: { + id: 'ollama', + name: 'Ollama', + description: 'Run and use open-source models locally', + parameters: [ + { + name: 'OLLAMA_HOST', + is_secret: false, + }, + ], + getActions: (provider, callbacks, isOnboardingPage) => + getDefaultButtons(provider, callbacks, isOnboardingPage), + }, + }, +]; diff --git a/ui/desktop/src/components/settings/providers/providers/NewProviderSettingsPage.tsx b/ui/desktop/src/components/settings_v2/providers/ProviderSettingsPage.tsx similarity index 90% rename from ui/desktop/src/components/settings/providers/providers/NewProviderSettingsPage.tsx rename to ui/desktop/src/components/settings_v2/providers/ProviderSettingsPage.tsx index 8cd41870..cabf5753 100644 --- a/ui/desktop/src/components/settings/providers/providers/NewProviderSettingsPage.tsx +++ b/ui/desktop/src/components/settings_v2/providers/ProviderSettingsPage.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { ScrollArea } from '../../../ui/scroll-area'; -import BackButton from '../../../ui/BackButton'; +import { ScrollArea } from '../../ui/scroll-area'; +import BackButton from '../../ui/BackButton'; import ProviderGrid from './ProviderGrid'; import ProviderState from './interfaces/ProviderState'; @@ -68,7 +68,7 @@ export default function ProviderSettings({ onClose }: { onClose: () => void }) { {/* Content Area */}
- +
diff --git a/ui/desktop/src/components/settings/providers/providers/callbacks/AddProviderParameters.tsx b/ui/desktop/src/components/settings_v2/providers/callbacks/AddProviderParameters.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/callbacks/AddProviderParameters.tsx rename to ui/desktop/src/components/settings_v2/providers/callbacks/AddProviderParameters.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/callbacks/CallbackRegistry.tsx b/ui/desktop/src/components/settings_v2/providers/callbacks/CallbackRegistry.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/callbacks/CallbackRegistry.tsx rename to ui/desktop/src/components/settings_v2/providers/callbacks/CallbackRegistry.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/callbacks/DeleteProviderParameters.tsx b/ui/desktop/src/components/settings_v2/providers/callbacks/DeleteProviderParameters.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/callbacks/DeleteProviderParameters.tsx rename to ui/desktop/src/components/settings_v2/providers/callbacks/DeleteProviderParameters.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/callbacks/RefreshActiveProviders.tsx b/ui/desktop/src/components/settings_v2/providers/callbacks/RefreshActiveProviders.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/callbacks/RefreshActiveProviders.tsx rename to ui/desktop/src/components/settings_v2/providers/callbacks/RefreshActiveProviders.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/callbacks/ShowModal.tsx b/ui/desktop/src/components/settings_v2/providers/callbacks/ShowModal.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/callbacks/ShowModal.tsx rename to ui/desktop/src/components/settings_v2/providers/callbacks/ShowModal.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/callbacks/UpdateProviderParameters.tsx b/ui/desktop/src/components/settings_v2/providers/callbacks/UpdateProviderParameters.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/callbacks/UpdateProviderParameters.tsx rename to ui/desktop/src/components/settings_v2/providers/callbacks/UpdateProviderParameters.tsx diff --git a/ui/desktop/src/components/settings_v2/providers/interfaces/ButtonCallbacks.tsx b/ui/desktop/src/components/settings_v2/providers/interfaces/ButtonCallbacks.tsx new file mode 100644 index 00000000..74ef05e6 --- /dev/null +++ b/ui/desktop/src/components/settings_v2/providers/interfaces/ButtonCallbacks.tsx @@ -0,0 +1,6 @@ +import ProviderState from '../interfaces/ProviderState'; + +export default interface ButtonCallbacks { + onConfigure?: (provider: ProviderState) => void; + onLaunch?: (provider: ProviderState) => void; +} diff --git a/ui/desktop/src/components/settings/providers/providers/interfaces/ConfigurationAction.tsx b/ui/desktop/src/components/settings_v2/providers/interfaces/ConfigurationAction.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/interfaces/ConfigurationAction.tsx rename to ui/desktop/src/components/settings_v2/providers/interfaces/ConfigurationAction.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/interfaces/OllamaMetadata.tsx b/ui/desktop/src/components/settings_v2/providers/interfaces/OllamaMetadata.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/interfaces/OllamaMetadata.tsx rename to ui/desktop/src/components/settings_v2/providers/interfaces/OllamaMetadata.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/interfaces/ParameterSchema.ts b/ui/desktop/src/components/settings_v2/providers/interfaces/ParameterSchema.ts similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/interfaces/ParameterSchema.ts rename to ui/desktop/src/components/settings_v2/providers/interfaces/ParameterSchema.ts diff --git a/ui/desktop/src/components/settings/providers/providers/interfaces/ProviderDetails.tsx b/ui/desktop/src/components/settings_v2/providers/interfaces/ProviderDetails.tsx similarity index 55% rename from ui/desktop/src/components/settings/providers/providers/interfaces/ProviderDetails.tsx rename to ui/desktop/src/components/settings_v2/providers/interfaces/ProviderDetails.tsx index 7b0f088c..6523b74c 100644 --- a/ui/desktop/src/components/settings/providers/providers/interfaces/ProviderDetails.tsx +++ b/ui/desktop/src/components/settings_v2/providers/interfaces/ProviderDetails.tsx @@ -1,8 +1,8 @@ // metadata and action builder import ProviderState from './ProviderState'; import ConfigurationAction from './ConfigurationAction'; -import ParameterSchema from '../parameters/interfaces/ParameterSchema'; -import ProviderCallbacks from './ConfigurationCallbacks'; +import ParameterSchema from '../interfaces/ParameterSchema'; +import ButtonCallbacks from './ButtonCallbacks'; export default interface ProviderDetails { id: string; @@ -10,5 +10,9 @@ export default interface ProviderDetails { description: string; parameters: ParameterSchema[]; getTags?: (name: string) => string[]; - getActions?: (provider: ProviderState, callbacks: ProviderCallbacks) => ConfigurationAction[]; + getActions?: ( + provider: ProviderState, + callbacks: ButtonCallbacks, + isOnboardingPage: boolean + ) => ConfigurationAction[]; } diff --git a/ui/desktop/src/components/settings/providers/providers/interfaces/ProviderState.tsx b/ui/desktop/src/components/settings_v2/providers/interfaces/ProviderState.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/interfaces/ProviderState.tsx rename to ui/desktop/src/components/settings_v2/providers/interfaces/ProviderState.tsx diff --git a/ui/desktop/src/components/settings_v2/providers/modal/ProviderConfiguationModal.tsx b/ui/desktop/src/components/settings_v2/providers/modal/ProviderConfiguationModal.tsx new file mode 100644 index 00000000..693a0cb1 --- /dev/null +++ b/ui/desktop/src/components/settings_v2/providers/modal/ProviderConfiguationModal.tsx @@ -0,0 +1,84 @@ +import React, { useEffect, useState } from 'react'; +import ProviderSetupOverlay from './subcomponents/ProviderSetupOverlay'; +import ProviderSetupHeader from './subcomponents/ProviderSetupHeader'; +import DefaultProviderSetupForm from './subcomponents/forms/DefaultProviderSetupForm'; +import ProviderSetupActions from './subcomponents/ProviderSetupActions'; +import ProviderLogo from './subcomponents/ProviderLogo'; +import ProviderConfiguationModalProps from './interfaces/ProviderConfigurationModalProps'; +import { useProviderModal } from './ProviderModalProvider'; +import { toast } from 'react-toastify'; + +export default function ProviderConfigurationModal() { + const { isOpen, currentProvider, modalProps, closeModal } = useProviderModal(); + console.log('currentProvider', currentProvider); + const [configValues, setConfigValues] = useState({}); + + // Reset form values when provider changes + useEffect(() => { + if (currentProvider) { + // Initialize form with default values + const initialValues = {}; + if (currentProvider.parameters) { + currentProvider.parameters.forEach((param) => { + initialValues[param.name] = param.defaultValue || ''; + }); + } + setConfigValues(initialValues); + } else { + setConfigValues({}); + } + }, [currentProvider]); + + if (!isOpen || !currentProvider) return null; + + const headerText = `Configure ${currentProvider.name}`; + const descriptionText = `Add your generated api keys for this provider to integrate into Goose`; + + // Use custom form component if provider specifies one, otherwise use default + const FormComponent = currentProvider.CustomForm || DefaultProviderSetupForm; + + const handleSubmitForm = (e) => { + e.preventDefault(); + + // Use custom submit handler if provided in modalProps + if (modalProps.onSubmit) { + modalProps.onSubmit(configValues); + } else { + // Default submit behavior + toast('Submitted configuration!'); + } + + closeModal(); + }; + + const handleCancel = () => { + // Use custom cancel handler if provided + if (modalProps.onCancel) { + modalProps.onCancel(); + } + + closeModal(); + }; + + return ( + +
+ {/* Logo area - centered above title */} + + {/* Title and some information - centered */} + +
+ + {/* Contains information used to set up each provider */} + + + +
+ ); +} diff --git a/ui/desktop/src/components/settings_v2/providers/modal/ProviderModalProvider.tsx b/ui/desktop/src/components/settings_v2/providers/modal/ProviderModalProvider.tsx new file mode 100644 index 00000000..bbff2449 --- /dev/null +++ b/ui/desktop/src/components/settings_v2/providers/modal/ProviderModalProvider.tsx @@ -0,0 +1,46 @@ +import React, { createContext, useContext, useState } from 'react'; + +const ProviderModalContext = createContext({ + isOpen: false, + currentProvider: null, + modalProps: {}, + openModal: (provider, additionalProps) => {}, + closeModal: () => {}, +}); + +export const useProviderModal = () => useContext(ProviderModalContext); + +export const ProviderModalProvider = ({ children }) => { + const [isOpen, setIsOpen] = useState(false); + const [currentProvider, setCurrentProvider] = useState(null); + const [modalProps, setModalProps] = useState({}); + + const openModal = (provider, additionalProps = {}) => { + setCurrentProvider(provider); + setModalProps(additionalProps); + setIsOpen(true); + }; + + const closeModal = () => { + setIsOpen(false); + // Use a small timeout to prevent UI flicker + setTimeout(() => { + setCurrentProvider(null); + setModalProps({}); + }, 200); + }; + + return ( + + {children} + + ); +}; diff --git a/ui/desktop/src/components/settings_v2/providers/modal/constants.tsx b/ui/desktop/src/components/settings_v2/providers/modal/constants.tsx new file mode 100644 index 00000000..09315b72 --- /dev/null +++ b/ui/desktop/src/components/settings_v2/providers/modal/constants.tsx @@ -0,0 +1 @@ +export const QUICKSTART_GUIDE_URL = 'https://block.github.io/goose/docs/quickstart'; diff --git a/ui/desktop/src/components/settings/providers/providers/modals/interfaces/ProviderConfigurationModalProps.tsx b/ui/desktop/src/components/settings_v2/providers/modal/interfaces/ProviderConfigurationModalProps.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/modals/interfaces/ProviderConfigurationModalProps.tsx rename to ui/desktop/src/components/settings_v2/providers/modal/interfaces/ProviderConfigurationModalProps.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/modals/interfaces/ProviderSetupFormProps.tsx b/ui/desktop/src/components/settings_v2/providers/modal/interfaces/ProviderSetupFormProps.tsx similarity index 72% rename from ui/desktop/src/components/settings/providers/providers/modals/interfaces/ProviderSetupFormProps.tsx rename to ui/desktop/src/components/settings_v2/providers/modal/interfaces/ProviderSetupFormProps.tsx index a2b16fa1..c2b3c79d 100644 --- a/ui/desktop/src/components/settings/providers/providers/modals/interfaces/ProviderSetupFormProps.tsx +++ b/ui/desktop/src/components/settings_v2/providers/modal/interfaces/ProviderSetupFormProps.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import ProviderDetails from '../../interfaces/ProviderDetails'; +import ProviderState from '../../interfaces/ProviderState'; export default interface ProviderSetupFormProps { configValues: { [key: string]: string }; setConfigValues: React.Dispatch>; onSubmit: (e: React.FormEvent) => void; - provider: ProviderDetails; + provider: ProviderState; } diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderLogo.tsx b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderLogo.tsx new file mode 100644 index 00000000..df947e26 --- /dev/null +++ b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderLogo.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import OpenAILogo from './icons/openai@3x.png'; +import AnthropicLogo from './icons/anthropic@3x.png'; +import GoogleLogo from './icons/google@3x.png'; +import GroqLogo from './icons/groq@3x.png'; +import OllamaLogo from './icons/ollama@3x.png'; +import DatabricksLogo from './icons/databricks@3x.png'; +import OpenRouterLogo from './icons/openrouter@3x.png'; + +// Map provider names to their logos +const providerLogos = { + openai: OpenAILogo, + anthropic: AnthropicLogo, + google: GoogleLogo, + groq: GroqLogo, + ollama: OllamaLogo, + databricks: DatabricksLogo, + openrouter: OpenRouterLogo, +}; + +export default function ProviderLogo({ providerName }) { + // Convert provider name to lowercase and fetch the logo + const logoKey = providerName.toLowerCase(); + const logo = providerLogos[logoKey] || OpenAILogo; // TODO: need default icon + + return ( +
+
+ {`${providerName} +
+
+ ); +} diff --git a/ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupActions.tsx b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderSetupActions.tsx similarity index 75% rename from ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupActions.tsx rename to ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderSetupActions.tsx index 94de8f75..e8cbef78 100644 --- a/ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupActions.tsx +++ b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderSetupActions.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Button } from '../../../../../ui/button'; +import { Button } from '../../../../ui/button'; interface ProviderSetupActionsProps { onCancel: () => void; @@ -7,16 +7,16 @@ interface ProviderSetupActionsProps { /** * Renders the "Submit" and "Cancel" buttons at the bottom. - * Notice we rely on the parent's `onSubmit` in the form, so we only handle Cancel here. + * Updated to match the design from screenshots. */ export default function ProviderSetupActions({ onCancel }: ProviderSetupActionsProps) { return ( -
+
{/* We rely on the
"onSubmit" for the actual Submit logic */} diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderSetupHeader.tsx b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderSetupHeader.tsx new file mode 100644 index 00000000..9c2b9a9a --- /dev/null +++ b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderSetupHeader.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { ExternalLink } from 'lucide-react'; +import { QUICKSTART_GUIDE_URL } from '../constants'; + +interface ProviderSetupHeaderProps { + title: string; + body: string; +} + +/** + * Renders the header (title + description + link to guide) for the modal. + */ +export default function ProviderSetupHeader({ title, body }: ProviderSetupHeaderProps) { + return ( +
+

{title}

+
{body}
+ + + View quick start guide + +
+ ); +} diff --git a/ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupOverlay.tsx b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderSetupOverlay.tsx similarity index 60% rename from ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupOverlay.tsx rename to ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderSetupOverlay.tsx index ff127d97..a2c74f5f 100644 --- a/ui/desktop/src/components/settings/providers/providers/modals/configuration_modal_subcomponents/ProviderSetupOverlay.tsx +++ b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/ProviderSetupOverlay.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { Card } from '../../../../ui/card'; interface ProviderSetupOverlayProps { children: React.ReactNode; @@ -10,7 +11,9 @@ interface ProviderSetupOverlayProps { export default function ProviderSetupOverlay({ children }: ProviderSetupOverlayProps) { return (
- {children} + +
{children}
+
); } diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/forms/DefaultProviderSetupForm.tsx b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/forms/DefaultProviderSetupForm.tsx new file mode 100644 index 00000000..bd0212f9 --- /dev/null +++ b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/forms/DefaultProviderSetupForm.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { Input } from '../../../../../ui/input'; +import { Lock } from 'lucide-react'; +import ProviderSetupFormProps from '../../interfaces/ProviderSetupFormProps'; +import ParameterSchema from '../../../interfaces/ParameterSchema'; +import { PROVIDER_REGISTRY } from '../../../ProviderRegistry'; + +export default function DefaultProviderSetupForm({ + configValues, + setConfigValues, + onSubmit, + provider, +}: ProviderSetupFormProps) { + const providerEntry = PROVIDER_REGISTRY.find((p) => p.name === provider.name); + const parameters: ParameterSchema[] = providerEntry.details.parameters; + + return ( + +
+ {parameters.map((parameter) => ( +
+ + setConfigValues((prev) => ({ + ...prev, + [parameter.name]: e.target.value, + })) + } + placeholder={parameter.name.replace(/_/g, ' ')} + className="w-full h-14 px-4 font-regular rounded-lg border shadow-none border-gray-300 bg-white text-lg placeholder:text-gray-400 font-regular text-gray-900" + required + /> +
+ ))} + +
+ + Keys are stored in a secure .env file +
+
+
+ ); +} diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/anthropic.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/anthropic.png new file mode 100644 index 0000000000000000000000000000000000000000..28e3ec5a0c08270b61a3b1594bff9066d5e2542f GIT binary patch literal 1203 zcmV;k1WfyhP){)4b+Fks>O&32C(Zcfs60p^z5G*cl(^3#Xs-8nVp&SP!@Q--detxY<@QQ zUN%GNV%fIKw#OEZMxz$F#6y~}KnQxx_Qn>cOPK8wiw=<{8H=?=zGHhy_k+bYp(8pY zv8)r394B{?ybFu%X(r{7R;(S(Rf^T+Lo?2TC(?Czl3>6o17@O+YD1CYzoq=uX(~((qUro0%D|55F%>3QPdtU=M7EI9 ze;XNHN9=QQNiZ0sy}dnY4Gj(Q-ptI5Y)8K=c!8fHdzojDOGZaWsj{+CT3cJ2ytlf# zD%%GJ1}F0ex2h%1CbFyKj@=H}*PpYHB%%7R*mHOK{6kg0VzHZ~@GwG7Npib~mX;Rscw#TWwY4=`US5_d#~^c3etLQ;$^k%V76Z)>v91=>BO@cy-`Lm?S2g9G zot@HGqpL<;7Z0cNhBT?GtE0`$P2r!MoRHt|7k+tpIUOAx2_I2LJFcarrF3v`AWNX5 zqeDhpgHRERSxx|+7P zw}p=sBDFU+iQ^N3Fr7L5oRlLY7=SJZ+GCW#*Gzj44-ZR!eSJNtPyhjH%6ocxgnxZ~ zO^b_*vR`X!D`g0liP2*GaCF0z!5ZQ4@Q@}aCxySVvXZv%)YOy|9En6^dngp5%gamQ zYYebY_;D8BSkJzr!o`QZm^06YNOM-mAt7heD7NCfI=bSm?_YMGQQ^_W@-I(+gkp+Ke!AL=_jyqLevCz-SZlpY)Wx-!rFlySQ+<=q^Qwar+(mlcIf&-J;l=ao3GNm46AOoPUtR RDVzWR002ovPDHLkV1nebJ*xl! literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/anthropic@2x.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/anthropic@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..fb0af21ac994d014999ac09c5519bcf862701141 GIT binary patch literal 2280 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 literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/databricks.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/databricks.png new file mode 100644 index 0000000000000000000000000000000000000000..7c1e54391f1cc96cc6c363157437cbdca5853e0c GIT binary patch literal 1574 zcmV+>2HE+EP)va&{_Sy!x0dH^bBlKaS z;X{Luy=fSorr5M$rO`pdGCDeHgH9Nr2qMUYLTNnG$f?3YBb7*}KoKh@tC9RpBLu4h z8;x)k(kmiMJXuLI^eMRH_gJ(nlj^0%tv7 z^78WXo}QjAcQs*AvKrAE%#G~zfG-g?65)cyE-oOufkYiR;!5EKWNBhDefVNy!3vKN z;U?#ka{^3@`XBf+FiPVu=PcpjIM9~=5&j%-CQ5cb;o)=~hK=)6S1^%?CdU^ctEn0S zH?d{Q7Ce9c9JRHzxOM9mRtaH_1BbG1FaODtC(+#8j8msh;mw;jICJIFmhb6vRtSHuGESN*3{HUAPo->Lk|ufJc#%2 z-yM8zzKl{KnZBqSu@{Q2{^efu_c?b@YcDyzc2TTxK~lgR`{7?sJge;z%0RD8Co zstUou!OPlg+qMmlA3uiGYQ^Twn{n*eF$@k4LJ>YpR;i%AfB!y4Mn>@9!2?{lZ~+%D zUX&Dd<;s;s=W{A+XlTIc)2C%{P}=QwQCS(}vv!q1QEBh(?X?r>*>m^q-IH^9d3pB3 zhY!oSvuDrR>+0(4q^6zRW_IqACr{*mq^GCb6@NR~L-po5J3Ddd(k0xuaRcq`?V?}n12vrzVHw4~FnIMCg{`KqE zXliQ0=g*%df9~D8SJGK^bv4Gu#>BtPW;1s0-i>F^o`KXBTPB>7lLH0(WMxNHEVgdl zipIu9QPQDkOG}I7-RS6OY}&L5`T6ctN^L-1z7=v9~nLOW!4hY#_Di#iP zSkb7cC{Wa6=gyr%`r5T?;;}oXc9%3JkjEuygLx+TDX=&-~HI95%l^5^r+qXhk2U5uX<}6u_ zFh4DPhfX+ZRxY$NGBOYv8Y;Q<>C>lk3UVDd;CRBF|0vEyxLfU_yLa#6`t|Fe?G%ZL ziBbo+0q!!I9be{?)%Db{Mv$ii=M!@}G8Earxf4Q%0oYh@hVmmmb9UDS?IUj45MfS& z8`(k%CRLl}pIo$yNQBFXFfYM+wL6`0lZa+7cEM$TmI(hM!tB!~tPgm}gIy72crIm4 zge{s6vrBkk?O>zfx7gAxy=;z#iR8%F2HR`z!rW@=`u9)iyJ Y52M|KK5gm1&Hw-a07*qoM6N<$g2BK3p#T5? literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/databricks@2x.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/databricks@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..03bc9a11d483f34e3df602f07a3ac9065df0e8db GIT binary patch literal 3444 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 XXEPi;Cv*2m00000NkvXXu0mjfdi9P7 literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/google.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/google.png new file mode 100644 index 0000000000000000000000000000000000000000..1469fb1b1e8dd10c4d6925685b3f7ba782faf6e1 GIT binary patch literal 1306 zcmV+#1?BpQP)O5RrVuw%h>wC>8iSQZuj4}&b{~CTPECt zjhXkB7SC%0rfjJ4#CaFM;#6CPp3Dy{h^ym9%^w3FbDa1Q2BH%O;MhyUR1 zIFY~_8ylN^c6RnpD2Je86`}t^+p{CVa}q3(;LpKs28ew`p*}33S~x%~Iew(Wb388G z!X6U*MO~=rU`nt5fTw|*tUx_VMEOpX$Nv^j2Ofz&stf!rOJezk4F*U|Ohj>UG4k^A zkd~H)o0}W#?d`$obYgmX8mFhHxCcB2JN#mmR^5akadB~IYHC7#eLYfBQ-k_=JRWp) zbzx{|2*=0AFaYNhFV$i>PTz=pLrzW(Mn*=EnVG4}e{*va6%`fO+1Y^s~-oJ4kZwx)c3ejbB^gIHQxLUeSr z{D&GF8)30nu)e;Iva&KcBn;xBmd%ca;JjZ`Q=<{eE!N!J47=Tq+uK`zId`n#;bGL) z)?$2o{60b%iTf3|EGH_JdTJykC1GJ6+`Ut*xMbRaI3m znZoDw9OJXIvk)Ol$T>>uesy&Pqr}9-KolXdySuxZYo1<>Vq|n+u`a#N%gf7}>$Kj7)tXObjorrOKPORTJ{KoAfAlI|#)5Nr}I#yu4hVM(5_{0{pp?vCz)WPECjF?(W9w z>M8_z$CH8$ck;$?aHcggGlPtb3{Cms;v#x_da%8{jf;y5y zGn2C1J`$=3ERkB}3Sjg1Z6bq)>=P+3`N zL@4u#KYU&JGX&uuwOXxcX=w>N6LAOY@9#%ZQIR}78^pmMzT}%jfmaHKwud-vWHFo$ z@=#?qn{jw}h_$sfOiWDR=twBa?qa9Lc5pUU$;AeQ;Eu>e}s$cFF z2Hiy@!GDuregu))?o{)dgboF}5psW)1ph^XIi{_M4E)Gng%Zk`!__9i4kd;;Bx3P! zxX4}vd-Q6;ie;1-{)0|Aj(>JoaBIGU_tAg-k+aaNB^uhSbod?j4-FQ{^Zf^r_hQ2D z!5C#Dubqr@JxQRd1KvEu?iO6yGKR#eQG{FY{S9N1>Ndx_3*MR0X+)r!Z-R%#E3QmN Q?EnA(07*qoM6N<$f?ok}WdHyG literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/google@2x.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/google@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9aeffe075405cca85ad13d377262141620918522 GIT binary patch literal 2487 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 Bq67c{ literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/google@3x.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/google@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..0b218240acb998407c037cab629093ef68a1dede GIT binary patch literal 3650 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 UkFG!HF#rGn07*qoM6N<$g29UAZ~y=R literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/groq.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/groq.png new file mode 100644 index 0000000000000000000000000000000000000000..6f91335b10dac3fb148beffe4a317b42aadb0c73 GIT binary patch literal 1223 zcmV;&1UUPNP)<%Lru@vQJvoiQtjguo?f7 zC}jUfpNyDbB$S>0gS|6e7KJ9ID z(qIEDbV&aY9@$=4!0Yv5c6JtfdwU230ysTA#r*s{nwy(pk+*tuMd{LVbq^A76elMq z;dZ;@`fP7+qrSc#hlhudgqP$#U95CXHswiZ`c zSCD|T27edTfM(r0NKCBm?rzl7)QB-hx2dTKOG`^a*viTZMn^~CbUIN{QGuMC9MH_h z>gp;aAc?LShm{o2qq@JppD+y;78X!eR)+KQa}*aBLy|6@U>-U9E{{DVcR#u|Cyc`V;4Ja)w z6{TxqV*~g1_o7NHFE7I`SZolIJUl$0rKJU9V`D-zN4Tx6&G?>ct&L(;P6HJdxVX4L zU0oeIJ3ECqF8t9r9HyW6W1(_nr8gbInVy~&7K@US5@URPd<;nf99dh$CW5O4!#TXO zvja)|PVNwB;DbdP8yh1Q3MM^09RmXc#!5FeH3bX!^sb8^w}&7JH#9vxJtA_8i;Gxa zUl+HYyDUXfgio^mA(>E$X|-OuCLsApL){Px3k$`VBiP>F{>aDg_oKD76&85Ue?%3h z8GJ)O`UefmV3NDLJIu|^;o#r^nVFfQ6--S{6-(^e+8PE22hr8lCELd`Dn-@H1EZ#B zt>QXtcwpoRpPilI`uZ9+;3csWJTTTr-eaQZ{sy^i%m_G&9B~^kqRK?~2K>aJ;@6=% z{6mCTt&FjQ^b%|%kM?aJbzPc+7cUF%iuXmIjM>vs{(hzW{f5x{g6HNv3H>Y97jYX< z66`0z0UEx>^X+{N#}mpVZHKgy_6d=1VeE$I2>;k6w;k7f#4 lW|Rw0QkBea_9b03-vK#gl2{bZ>)ZeU002ovPDHLkV1iE!Ex7;y literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/groq@2x.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/groq@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8e1560b0e8b58dd632d432df7d5a4043ce089f00 GIT binary patch literal 2359 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 dWeXUM{{ioCGb2Y|002ovPDHLkV1jHAUfBQu literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/groq@3x.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/groq@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..da191305bfc5f204df0ca1b2f15420074d992192 GIT binary patch literal 3379 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 oG*igj7k^Gtm26S(M>=_`c%R9KT$ zW{}ewYm)V7dvPA4^DdO{P&A|dd0vKUK+6?)o4vrrtVRJ_p0Vu39Y zR<}?HI-QC)8d)T8*o76EqRVGeWV?KzXyQl`0&5f|%2Aj=w~vpH&l0EU;)th`1&m<2 z`2W+FFJDem7zm5S3Q_H%fv6?PN_&{|}YDcr{RLoe{s{1xww!b*X97rW7GE^mO0AT~x4;6cQU7OFMV& zq%&vE(DCEPY4hgIRG~tJfPTijdGqMry?b=y#tquIaU<2JQG*l%QB%zq3b_J35>T39 zty;B;MvoqCJZ{&n9ew-ujV@fc;Me=djvY%&mo7CP!}6YYId|?HU+dMY7q=BFR-`Unx^S1r(Wg%z zs#U8NKi9i=Z*FhiylGhH)vH&zg~dmJiSi`Q-9=T@u3ekkmoHx$*Yfl8xlK$=q-D#N z(fIM>*=M@4XU`sL+_*8H-??+gxc=wNR( z4Xs$Qf?Bq0$panyDUPXAr_!TGkBrw6J}vZ~4C>kFxeofb}U#AFg znG*zIx$yorQpAuULukj29ejTO{(Tl0T{|4Woow5-jhZ!U#*c>&AI|BrV%ADwf0H6G zs>2%L8*ksfP07j09K(haWN?QL9pb10mW=lIZ)G15WXI|efii{;9cpAtdym;{7dHd09c{{6W{*Efeu;pW=4Yjo+7v#>vC&>&Jw&5)OI21<(- zEx0{@{=DDsL9pMtb!$#-%aBNZ>90g=$Wfcm~MvNH2etYra#f5$*q5>cz1%+@Nt5jH-6jZ5F#kf|# zetlZ7U;&?_XuWUWJ}&>wojaEcGh4TAWpPmnOGrrIuDyT%e$L8J5t}t@7PV>9hHJT- zHf=J};!2e&ar^o6XHrcZDF)Riq^PjQ)vH(YH3ai0zCbisV@5^>i@JOFZbMu%C~U7= zw~pq_nZs!>tQo@MXGl>2+y{t2U6x|>a$znhB0W8w>!tvuJvo3O3$xj5EDnNtq@?hT zXz?Xr&_f*og5ou(55P~O2XyP!jo*tT1IYqFdCK1*RKI@xIJQNMDnl^|L`IkeKa2s(9jJ6+ z3LI8%o{3O|CWXC0iiDL5Mtu1__)TYvKA*_BO zj}$O*qB8)2HOc%woFFVi`4Eg8Ig%7|K%Tf3VHT0aAiYG15A5B$m#hK_2*7NuTq9;N znt9WnLc;26J1unw2=*m%WuO)0<^Ab=ty;Ar1vtzP+?5U2l7-0l6;&xKEBkU<2B2=B zfI_|9ov>IcZ<*D~N)+NuD^~<6z7Ju$>rKl=gw+Qz%dGawl`Hh=(M@S8qg9WJ+#33$+8wHzzrq^@`j)`=GAxaDNTFEdV@uE z-I~M~K`n~YCm+!*G%DR-kP28-5YkrCrF=kJEA*UBK@!q3PTl9iaxJalDhAd$BNS0V z$h*paagrmF2;2{^>d%~5h4iO66e3~Uu3w0oC&a}RI(^b07*qo IM6N<$f{waH$^ZZW literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/ollama@3x.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/ollama@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..7195cccc36b33cedc6faa002d4238192af831d5a GIT binary patch literal 4262 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 IM6N<$g2k2G^Z)<= literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openai.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openai.png new file mode 100644 index 0000000000000000000000000000000000000000..a42ae9e48bf92aa8fdcabbcbdbe1cad744c2afa4 GIT binary patch literal 1272 zcmV-5)^65gLUMZ6PE|M?#?;ga&N*Q6U9CIx!(&r-p!bo`gax zAyAl5xbhEhP|@N0ncKN6%Pn^^9N?3@Ec-IUKJ(1`zB4tJDE6th%OjMX~x@JOH7MjSV?DIg#b%WjQ)JGCs(IrKKe^ zn1h1@+1%U|Pp~9UTC(0X6&3gQ_hoQ!u%zu&0X*Vku!C^$7WB?AKkM#XG4Ym^4G8y+4uv(VYuS@zcmA|clhg+Soa6V-Sq zgn1~|)6-*Aw&YO|C3|~&O&{8fkB=KwA?<-Y36^u|ftq7uV=^)_A~Q2HWk1urwzg)7 z?(FQC0c~$@8>JZp{QzxH-UC@@vOI_fVo9JHYC{f1nQm--eO(q87mYuY$(V5QKn}7_ zivVPJcqO1XilREiS65dJF=l}HMR7`+W4v12cP2|5rYRE-0|;}qH5cH+h-(Jzh~S>C zzr66(917jt-O}9LEL&S!q^NnQuHR+=C`LWCfD{VjBX$oD4^5T8Pne|5P#PM<5wo+i zCT_`Slq2gQOb8@bEPIdQ45p=}#oR-fgmeXDi!L1?h=SA8(-)?fn1ld6$Wz+Vvi|h+ z)F;V8$cEww6oa76e3FV-#%BpL1M$)p2W5;w`;c`$bb#3T`MFUOf+$E$#fW8_`IV*` zqO^C7SH)f?+R+@l^deaxVwYJ!!a$IL*u4R57z{DW3;<^3D%G#RPy;&z{iWd2i`^AO zAZ?QfLc}4liV@c+Y_lI@FbvRxC@9!n7q8oME$1D96>)r}fglfO`rF#t${CJ=lqf>M?zHg7L&gK|_)$JLP<7wv<)vH$cGGQ%5(*>| z8*pOT6QQd5C`mTZ%TM{YUKqiUl3n4K@~b#!OuF>`FMh|EHw9E3vNy@)mQV=g-$7UW z<^tKMjM2bp3BDm*I=8*Fk%<}%$=!le@yVpK;`yw`?=OwtKT`T$aNBsNL@U0er5+|L z;aw%n8u?gm@9b+njVP%4O(802U&Zka*b(FiG5Y4JMpcjLDQRl+ocqhol(mA|6D9hk zT0_^bHG!1QZlBBbQIL|Fg<3l}e+L5*>AaLk=N-C+YM<0Tx{$Q+A{$4vAI?P + + diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openai@2x.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openai@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..69306a71c6473f6f3357312d8a887db8b2bd456a GIT binary patch literal 2508 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 literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openrouter@2x.png b/ui/desktop/src/components/settings_v2/providers/modal/subcomponents/icons/openrouter@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9e4ab432cdc107acafab24778ba9c1d37b381090 GIT binary patch literal 2304 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 literal 0 HcmV?d00001 diff --git a/ui/desktop/src/components/settings/providers/providers/parameters/UpdateSecrets.tsx b/ui/desktop/src/components/settings_v2/providers/parameters/UpdateSecrets.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/parameters/UpdateSecrets.tsx rename to ui/desktop/src/components/settings_v2/providers/parameters/UpdateSecrets.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/state/ActiveKeysContext.tsx b/ui/desktop/src/components/settings_v2/providers/state/ActiveKeysContext.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/state/ActiveKeysContext.tsx rename to ui/desktop/src/components/settings_v2/providers/state/ActiveKeysContext.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/state/types.ts b/ui/desktop/src/components/settings_v2/providers/state/types.ts similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/state/types.ts rename to ui/desktop/src/components/settings_v2/providers/state/types.ts diff --git a/ui/desktop/src/components/settings/providers/providers/state/utils.tsx b/ui/desktop/src/components/settings_v2/providers/state/utils.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/state/utils.tsx rename to ui/desktop/src/components/settings_v2/providers/state/utils.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/subcomponents/CardActions.tsx b/ui/desktop/src/components/settings_v2/providers/subcomponents/CardActions.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/subcomponents/CardActions.tsx rename to ui/desktop/src/components/settings_v2/providers/subcomponents/CardActions.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/subcomponents/CardBody.tsx b/ui/desktop/src/components/settings_v2/providers/subcomponents/CardBody.tsx similarity index 75% rename from ui/desktop/src/components/settings/providers/providers/subcomponents/CardBody.tsx rename to ui/desktop/src/components/settings_v2/providers/subcomponents/CardBody.tsx index 343b4d19..38437e8e 100644 --- a/ui/desktop/src/components/settings/providers/providers/subcomponents/CardBody.tsx +++ b/ui/desktop/src/components/settings_v2/providers/subcomponents/CardBody.tsx @@ -7,9 +7,8 @@ interface CardBodyProps { } export default function CardBody({ actions }: CardBodyProps) { - console.log('in card body'); return ( -
+
); diff --git a/ui/desktop/src/components/settings/providers/providers/subcomponents/CardContainer.tsx b/ui/desktop/src/components/settings_v2/providers/subcomponents/CardContainer.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/subcomponents/CardContainer.tsx rename to ui/desktop/src/components/settings_v2/providers/subcomponents/CardContainer.tsx diff --git a/ui/desktop/src/components/settings/providers/providers/subcomponents/CardHeader.tsx b/ui/desktop/src/components/settings_v2/providers/subcomponents/CardHeader.tsx similarity index 91% rename from ui/desktop/src/components/settings/providers/providers/subcomponents/CardHeader.tsx rename to ui/desktop/src/components/settings_v2/providers/subcomponents/CardHeader.tsx index 82d347a7..852eeaa5 100644 --- a/ui/desktop/src/components/settings/providers/providers/subcomponents/CardHeader.tsx +++ b/ui/desktop/src/components/settings_v2/providers/subcomponents/CardHeader.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { ExclamationButton, GreenCheckButton } from './actions/ActionButtons'; +import { ExclamationButton, GreenCheckButton } from './buttons/CardButtons'; import { ConfiguredProviderTooltipMessage, OllamaNotConfiguredTooltipMessage, @@ -28,7 +28,7 @@ function ProviderNameAndStatus({ name, isConfigured }: ProviderNameAndStatusProp const ollamaNotConfigured = !isConfigured && name === 'Ollama'; return ( -
+
{/* Configured state: Green check */} diff --git a/ui/desktop/src/components/settings/providers/providers/subcomponents/ProviderCard.tsx b/ui/desktop/src/components/settings_v2/providers/subcomponents/ProviderCard.tsx similarity index 79% rename from ui/desktop/src/components/settings/providers/providers/subcomponents/ProviderCard.tsx rename to ui/desktop/src/components/settings_v2/providers/subcomponents/ProviderCard.tsx index fb1a8c3b..e89ebca8 100644 --- a/ui/desktop/src/components/settings/providers/providers/subcomponents/ProviderCard.tsx +++ b/ui/desktop/src/components/settings_v2/providers/subcomponents/ProviderCard.tsx @@ -3,15 +3,16 @@ import CardContainer from './CardContainer'; import CardHeader from './CardHeader'; import ProviderState from '../interfaces/ProviderState'; import CardBody from './CardBody'; -import ProviderCallbacks from '../interfaces/ConfigurationCallbacks'; +import ButtonCallbacks from '../interfaces/ButtonCallbacks'; import { PROVIDER_REGISTRY } from '../ProviderRegistry'; interface ProviderCardProps { provider: ProviderState; - providerCallbacks: ProviderCallbacks; + buttonCallbacks: ButtonCallbacks; + isOnboarding: boolean; } -export function ProviderCard({ provider, providerCallbacks }: ProviderCardProps) { +export function ProviderCard({ provider, buttonCallbacks, isOnboarding }: ProviderCardProps) { const providerEntry = PROVIDER_REGISTRY.find((p) => p.name === provider.name); // Add safety check @@ -29,7 +30,7 @@ export function ProviderCard({ provider, providerCallbacks }: ProviderCardProps) console.log('provider details', providerDetails); try { - const actions = providerDetails.getActions(provider, providerCallbacks); + const actions = providerDetails.getActions(provider, buttonCallbacks, isOnboarding); return ( { /** Icon component to render, e.g. `RefreshCw` from lucide-react */ @@ -11,11 +11,15 @@ interface ActionButtonProps extends React.ComponentProps { tooltip?: React.ReactNode; /** Additional classes for styling. */ className?: string; + /** Text to display next to the icon */ + text?: string; + /** Additional class for the icon specifically */ + iconClassName?: string; } -// className is the styling for the ); @@ -62,17 +79,14 @@ export function GreenCheckButton({ icon={Check} tooltip={tooltip} className={` - bg-green-100 - dark:bg-green-900/30 text-green-600 dark:text-green-500 - hover:bg-green-100 hover:text-green-600 border-none shadow-none w-5 h-5 cursor-default - ${className} // Removed the nullish coalescing operator as default is provided + ${className} `} onClick={() => {}} {...props} @@ -84,8 +98,17 @@ export function ExclamationButton({ tooltip, className, ...props }: ActionButton return {}} {...props} />; } -export function GearSettingsButton({ tooltip, className, ...props }: ActionButtonProps) { - return ; +export function ConfigureSettingsButton({ tooltip, className, ...props }: ActionButtonProps) { + return ( + + ); } export function AddButton({ tooltip, className, ...props }: ActionButtonProps) { @@ -101,5 +124,13 @@ export function RefreshButton({ tooltip, className, ...props }: ActionButtonProp } export function RocketButton({ tooltip, className, ...props }: ActionButtonProps) { - return ; + return ( + + ); } diff --git a/ui/desktop/src/components/settings_v2/providers/subcomponents/buttons/DefaultCardButtons.tsx b/ui/desktop/src/components/settings_v2/providers/subcomponents/buttons/DefaultCardButtons.tsx new file mode 100644 index 00000000..2f5ace8d --- /dev/null +++ b/ui/desktop/src/components/settings_v2/providers/subcomponents/buttons/DefaultCardButtons.tsx @@ -0,0 +1,77 @@ +import React from 'react'; +import { ConfigureSettingsButton, RocketButton } from './CardButtons'; +import ButtonCallbacks from '../../interfaces/ButtonCallbacks'; +import ProviderState from '@/src/components/settings_v2/providers/interfaces/ProviderState'; + +// can define other optional callbacks as needed +interface CardButtonsProps { + provider: ProviderState; + isOnboardingPage?: boolean; + callbacks: ButtonCallbacks; // things like onConfigure, onDelete +} + +function getDefaultTooltipMessages(name: string, actionType: string) { + switch (actionType) { + case 'add': + return `Configure ${name} settings`; + case 'edit': + return `Edit ${name} settings`; + case 'delete': + return `Delete ${name} settings`; + default: + return null; + } +} + +/// This defines a group of buttons that will appear on the card +/// Controlled by if a provider is configured and which version of the grid page we're on (onboarding vs settings page) +/// This is the default button group +/// +/// Settings page: +/// - show configure button +/// Onboarding page: +/// - show configure button if NOT configured +/// - show rocket launch button if configured +/// +/// We inject what will happen if we click on a button via on +/// - onConfigure: pop open a modal -- modal is configured dynamically +/// - onLaunch: continue to chat window +export default function DefaultCardButtons({ + provider, + isOnboardingPage, + callbacks, +}: CardButtonsProps) { + return ( + <> + {/*Set up an unconfigured provider */} + {!provider.isConfigured && ( + { + e.stopPropagation(); + callbacks.onConfigure(provider); + }} + /> + )} + {/*show edit tooltip instead when hovering over button for configured providers*/} + {provider.isConfigured && !isOnboardingPage && ( + { + e.stopPropagation(); + callbacks.onConfigure(provider); + }} + /> + )} + {/*show Launch button for configured providers on onboarding page*/} + {provider.isConfigured && isOnboardingPage && ( + { + e.stopPropagation(); + callbacks.onLaunch(provider); + }} + /> + )} + + ); +} diff --git a/ui/desktop/src/components/settings/providers/providers/subcomponents/actions/TooltipWrapper.tsx b/ui/desktop/src/components/settings_v2/providers/subcomponents/buttons/TooltipWrapper.tsx similarity index 88% rename from ui/desktop/src/components/settings/providers/providers/subcomponents/actions/TooltipWrapper.tsx rename to ui/desktop/src/components/settings_v2/providers/subcomponents/buttons/TooltipWrapper.tsx index ca291ad9..0986fd7d 100644 --- a/ui/desktop/src/components/settings/providers/providers/subcomponents/actions/TooltipWrapper.tsx +++ b/ui/desktop/src/components/settings_v2/providers/subcomponents/buttons/TooltipWrapper.tsx @@ -1,11 +1,6 @@ // TooltipWrapper.tsx import React from 'react'; -import { - Tooltip, - TooltipTrigger, - TooltipContent, - TooltipProvider, -} from '../../../../../ui/Tooltip'; +import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '../../../../ui/Tooltip'; import { Portal } from '@radix-ui/react-portal'; interface TooltipWrapperProps { diff --git a/ui/desktop/src/components/settings/providers/providers/subcomponents/utils/StringUtils.tsx b/ui/desktop/src/components/settings_v2/providers/subcomponents/utils/StringUtils.tsx similarity index 100% rename from ui/desktop/src/components/settings/providers/providers/subcomponents/utils/StringUtils.tsx rename to ui/desktop/src/components/settings_v2/providers/subcomponents/utils/StringUtils.tsx