ui: tweaks to settings v2 (#1731)
This commit is contained in:
@@ -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. You’ll 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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -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"
|
||||||
|
|||||||
+2
-2
@@ -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'}
|
||||||
|
|||||||
+3
-2
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user