ui: tweaks to settings v2 (#1731)

This commit is contained in:
Lily Delalande
2025-03-17 17:59:11 -07:00
committed by GitHub
parent 952e0d22c0
commit ab96e041bb
9 changed files with 61 additions and 23 deletions
@@ -101,12 +101,12 @@ export default function SettingsView({
))} ))}
</div> </div>
<div className="flex gap-4 pt-4 w-full"> <div className="flex gap-4 pt-4 w-full">
<Button className="flex items-center gap-2 flex-1 justify-center bg-[#393838] hover:bg-subtle"> <Button className="flex items-center gap-2 flex-1 justify-center text-textSubtle bg-black dark:bg-white hover:bg-subtle">
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
Add Model Add Model
</Button> </Button>
<Button <Button
className="flex items-center gap-2 flex-1 justify-center text-textSubtle border-standard bg-grey-60 hover:bg-subtle" className="flex items-center gap-2 flex-1 justify-center text-textSubtle bg-white dark:bg-black hover:bg-subtle dark:border dark:border-gray-500 dark:hover:border-gray-400"
onClick={() => { onClick={() => {
setView('ConfigureProviders'); setView('ConfigureProviders');
}} }}
@@ -118,14 +118,14 @@ export default function ExtensionsSection() {
<div className="flex gap-4 pt-4 w-full"> <div className="flex gap-4 pt-4 w-full">
<Button <Button
className="flex items-center gap-2 flex-1 justify-center bg-[#393838] hover:bg-subtle" className="flex items-center gap-2 flex-1 justify-center text-textSubtle bg-black dark:bg-white hover:bg-subtle"
onClick={() => setIsAddModalOpen(true)} onClick={() => setIsAddModalOpen(true)}
> >
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
Add custom extension Add custom extension
</Button> </Button>
<Button <Button
className="flex items-center gap-2 flex-1 justify-center text-textSubtle border-standard bg-grey-60 hover:bg-subtle" className="flex items-center gap-2 flex-1 justify-center text-textSubtle bg-white dark:bg-black hover:bg-subtle dark:border dark:border-gray-500 dark:hover:border-gray-400"
onClick={() => window.open('https://block.github.io/goose/v1/extensions/', '_blank')} onClick={() => window.open('https://block.github.io/goose/v1/extensions/', '_blank')}
> >
<GPSIcon size={18} /> <GPSIcon size={18} />
@@ -5,6 +5,7 @@ import ProviderGrid from './ProviderGrid';
import { useConfig } from '../../ConfigContext'; import { useConfig } from '../../ConfigContext';
import { ProviderDetails } from '../../../api/types.gen'; import { ProviderDetails } from '../../../api/types.gen';
import { useAgent } from '../../../agent/UpdateAgent'; import { useAgent } from '../../../agent/UpdateAgent';
import WelcomeGooseLogo from '../../WelcomeGooseLogo';
interface ProviderSettingsProps { interface ProviderSettingsProps {
onClose: () => void; onClose: () => void;
@@ -81,21 +82,29 @@ export default function ProviderSettings({ onClose, isOnboarding }: ProviderSett
return ( return (
<div className="h-screen w-full"> <div className="h-screen w-full">
<div className="relative flex items-center h-[36px] w-full bg-bgSubtle"></div> <div className="relative flex items-center h-[36px] w-full bg-bgSubtle"></div>
{isOnboarding && (
<div className="group/logo">
<WelcomeGooseLogo className="h-16 w-16 md:h-20 md:w-20 text-black dark:text-white" />
</div>
)}
<ScrollArea className="h-full w-full"> <ScrollArea className="h-full w-full">
<div className="px-8 pt-6 pb-4"> <div className="px-8 pt-6 pb-4">
{/* Only show back button if not in onboarding mode */} {/* Only show back button if not in onboarding mode */}
{!isOnboarding && <BackButton onClick={onClose} />} {!isOnboarding && <BackButton onClick={onClose} />}
<h1 className="text-3xl font-medium text-textStandard mt-1"> <h1 className="text-3xl font-medium text-textStandard mt-1">
{isOnboarding ? 'Select a Provider' : 'Configure'} {isOnboarding ? 'Configure your providers' : 'Provider Configuration Settings'}
</h1> </h1>
{isOnboarding && (
<p className="text-s text-textSubtle max-w-2xl pt-2">
Select an AI model provider to get started with goose. Youll need to use API keys
generated by each provider which will be encrypted and stored locally. You can change
your provider at any time in settings.
</p>
)}
</div> </div>
<div className="py-8 pt-[20px]"> <div className="py-8 pt-[20px]">
<div className="flex justify-between items-center mb-6 border-b border-borderSubtle px-8">
<h2 className="text-xl font-medium text-textStandard">Providers</h2>
</div>
{/* Content Area */} {/* Content Area */}
<div className="max-w-5xl pt-4 px-8"> <div className="max-w-5xl pt-4 px-8">
<div className="relative z-10"> <div className="relative z-10">
@@ -20,7 +20,7 @@ const customFormsMap = {
}; };
export default function ProviderConfigurationModal() { export default function ProviderConfigurationModal() {
const { upsert, getProviders } = useConfig(); const { upsert } = useConfig();
const { isOpen, currentProvider, modalProps, closeModal } = useProviderModal(); const { isOpen, currentProvider, modalProps, closeModal } = useProviderModal();
const [configValues, setConfigValues] = useState({}); const [configValues, setConfigValues] = useState({});
@@ -63,7 +63,10 @@ export default function ProviderConfigurationModal() {
}; };
return ( return (
<Modal onClose={closeModal}> <Modal
onClose={closeModal}
footer={<ProviderSetupActions onCancel={handleCancel} onSubmit={handleSubmitForm} />}
>
<div className="space-y-1"> <div className="space-y-1">
{/* Logo area - centered above title */} {/* Logo area - centered above title */}
<ProviderLogo providerName={currentProvider.name} /> <ProviderLogo providerName={currentProvider.name} />
@@ -82,7 +85,6 @@ export default function ProviderConfigurationModal() {
{currentProvider.metadata.config_keys && currentProvider.metadata.config_keys.length > 0 && ( {currentProvider.metadata.config_keys && currentProvider.metadata.config_keys.length > 0 && (
<SecureStorageNotice /> <SecureStorageNotice />
)} )}
<ProviderSetupActions onCancel={handleCancel} onSubmit={handleSubmitForm} />
</Modal> </Modal>
); );
} }
@@ -12,7 +12,7 @@ interface ProviderSetupActionsProps {
*/ */
export default function ProviderSetupActions({ onCancel, onSubmit }: ProviderSetupActionsProps) { export default function ProviderSetupActions({ onCancel, onSubmit }: ProviderSetupActionsProps) {
return ( return (
<div className="mt-8 -ml-8 -mr-8"> <div className="-ml-8 -mr-8">
{/* We rely on the <form> "onSubmit" for the actual Submit logic */} {/* We rely on the <form> "onSubmit" for the actual Submit logic */}
<Button <Button
type="submit" type="submit"
@@ -14,8 +14,8 @@ export function SecureStorageNotice({
message = 'Keys are stored securely in the keychain', message = 'Keys are stored securely in the keychain',
}) { }) {
return ( return (
<div className={`flex items-start mt-2 text-gray-600 dark:text-gray-300 ${className}`}> <div className={`flex items-center mt-2 text-gray-600 dark:text-gray-300 ${className}`}>
<Lock className="w-5 h-5 mt-1" /> <Lock className="w-5 h-5" />
<span className="text-sm font-light ml-2">{message}</span> <span className="text-sm font-light ml-2">{message}</span>
</div> </div>
); );
@@ -3,6 +3,8 @@ import React from 'react';
interface CardContainerProps { interface CardContainerProps {
header: React.ReactNode; header: React.ReactNode;
body: React.ReactNode; body: React.ReactNode;
onClick: () => void;
grayedOut: boolean;
} }
function GlowingRing() { function GlowingRing() {
@@ -24,11 +26,29 @@ function HeaderContainer({ children }: HeaderContainerProps) {
return <div>{children}</div>; return <div>{children}</div>;
} }
export default function CardContainer({ header, body }: CardContainerProps) { export default function CardContainer({
header,
body,
onClick,
grayedOut = false,
}: CardContainerProps) {
return ( return (
<div className="relative h-full p-[2px] overflow-hidden rounded-[9px] group/card bg-borderSubtle hover:bg-transparent hover:duration-300"> <div
<GlowingRing /> className={`relative h-full p-[2px] overflow-hidden rounded-[9px] group/card bg-borderSubtle ${
<div className="relative bg-bgApp rounded-lg p-3 transition-all duration-200 h-[160px] flex flex-col justify-between hover:border-borderStandard"> !grayedOut ? 'hover:bg-transparent hover:duration-300' : ''
}`}
onClick={!grayedOut ? onClick : undefined}
style={{
cursor: !grayedOut && onClick ? 'pointer' : 'default',
opacity: !grayedOut ? '1' : '0.5',
}}
>
{!grayedOut && <GlowingRing />}
<div
className={`relative bg-bgApp rounded-lg p-3 transition-all duration-200 h-[160px] flex flex-col justify-between ${
!grayedOut ? 'hover:border-borderStandard' : ''
}`}
>
<HeaderContainer>{header}</HeaderContainer> <HeaderContainer>{header}</HeaderContainer>
{body} {body}
</div> </div>
@@ -24,14 +24,20 @@ export const ProviderCard = memo(function ProviderCard({
// Instead of useEffect for logging, use useMemo to memoize the metadata // Instead of useEffect for logging, use useMemo to memoize the metadata
const metadata = useMemo(() => providerMetadata, [provider]); const metadata = useMemo(() => providerMetadata, [provider]);
// Remove the logging completely
if (!metadata) { if (!metadata) {
return <div>ProviderCard error: No metadata provided</div>; return <div>ProviderCard error: No metadata provided</div>;
} }
const handleCardClick = () => {
if (!isOnboarding) {
onConfigure();
}
};
return ( return (
<CardContainer <CardContainer
grayedOut={!provider.is_configured && isOnboarding} // onboarding page will have grayed out cards if not configured
onClick={handleCardClick}
header={ header={
<CardHeader <CardHeader
name={metadata.display_name || provider?.name || 'Unknown Provider'} name={metadata.display_name || provider?.name || 'Unknown Provider'}
@@ -34,7 +34,7 @@ export default function DefaultCardButtons({
{/*Set up an unconfigured provider */} {/*Set up an unconfigured provider */}
{!provider.is_configured && ( {!provider.is_configured && (
<ConfigureSettingsButton <ConfigureSettingsButton
tooltip={getDefaultTooltipMessages(provider.name, 'add')} tooltip={getDefaultTooltipMessages(provider.metadata.display_name, 'add')}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
onConfigure(provider); onConfigure(provider);
@@ -44,7 +44,7 @@ export default function DefaultCardButtons({
{/*show edit tooltip instead when hovering over button for configured providers*/} {/*show edit tooltip instead when hovering over button for configured providers*/}
{provider.is_configured && !isOnboardingPage && ( {provider.is_configured && !isOnboardingPage && (
<ConfigureSettingsButton <ConfigureSettingsButton
tooltip={getDefaultTooltipMessages(provider.name, 'edit')} tooltip={getDefaultTooltipMessages(provider.metadata.display_name, 'edit')}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
onConfigure(provider); onConfigure(provider);
@@ -54,6 +54,7 @@ export default function DefaultCardButtons({
{/*show Launch button for configured providers on onboarding page*/} {/*show Launch button for configured providers on onboarding page*/}
{provider.is_configured && isOnboardingPage && ( {provider.is_configured && isOnboardingPage && (
<RocketButton <RocketButton
tooltip={'Get started with goose!'}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
onLaunch(provider); onLaunch(provider);