mirror of
https://github.com/aljazceru/goose.git
synced 2026-02-11 17:44:24 +01:00
ui: tweaks to settings v2 (#1731)
This commit is contained in:
@@ -101,12 +101,12 @@ export default function SettingsView({
|
||||
))}
|
||||
</div>
|
||||
<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" />
|
||||
Add Model
|
||||
</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={() => {
|
||||
setView('ConfigureProviders');
|
||||
}}
|
||||
|
||||
@@ -118,14 +118,14 @@ export default function ExtensionsSection() {
|
||||
|
||||
<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"
|
||||
className="flex items-center gap-2 flex-1 justify-center text-textSubtle bg-black dark:bg-white hover:bg-subtle"
|
||||
onClick={() => setIsAddModalOpen(true)}
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
Add custom extension
|
||||
</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')}
|
||||
>
|
||||
<GPSIcon size={18} />
|
||||
|
||||
@@ -5,6 +5,7 @@ import ProviderGrid from './ProviderGrid';
|
||||
import { useConfig } from '../../ConfigContext';
|
||||
import { ProviderDetails } from '../../../api/types.gen';
|
||||
import { useAgent } from '../../../agent/UpdateAgent';
|
||||
import WelcomeGooseLogo from '../../WelcomeGooseLogo';
|
||||
|
||||
interface ProviderSettingsProps {
|
||||
onClose: () => void;
|
||||
@@ -81,21 +82,29 @@ export default function ProviderSettings({ onClose, isOnboarding }: ProviderSett
|
||||
return (
|
||||
<div className="h-screen w-full">
|
||||
<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">
|
||||
<div className="px-8 pt-6 pb-4">
|
||||
{/* Only show back button if not in onboarding mode */}
|
||||
{!isOnboarding && <BackButton onClick={onClose} />}
|
||||
<h1 className="text-3xl font-medium text-textStandard mt-1">
|
||||
{isOnboarding ? 'Select a Provider' : 'Configure'}
|
||||
{isOnboarding ? 'Configure your providers' : 'Provider Configuration Settings'}
|
||||
</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 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 */}
|
||||
<div className="max-w-5xl pt-4 px-8">
|
||||
<div className="relative z-10">
|
||||
|
||||
@@ -20,7 +20,7 @@ const customFormsMap = {
|
||||
};
|
||||
|
||||
export default function ProviderConfigurationModal() {
|
||||
const { upsert, getProviders } = useConfig();
|
||||
const { upsert } = useConfig();
|
||||
const { isOpen, currentProvider, modalProps, closeModal } = useProviderModal();
|
||||
const [configValues, setConfigValues] = useState({});
|
||||
|
||||
@@ -63,7 +63,10 @@ export default function ProviderConfigurationModal() {
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal onClose={closeModal}>
|
||||
<Modal
|
||||
onClose={closeModal}
|
||||
footer={<ProviderSetupActions onCancel={handleCancel} onSubmit={handleSubmitForm} />}
|
||||
>
|
||||
<div className="space-y-1">
|
||||
{/* Logo area - centered above title */}
|
||||
<ProviderLogo providerName={currentProvider.name} />
|
||||
@@ -82,7 +85,6 @@ export default function ProviderConfigurationModal() {
|
||||
{currentProvider.metadata.config_keys && currentProvider.metadata.config_keys.length > 0 && (
|
||||
<SecureStorageNotice />
|
||||
)}
|
||||
<ProviderSetupActions onCancel={handleCancel} onSubmit={handleSubmitForm} />
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ interface ProviderSetupActionsProps {
|
||||
*/
|
||||
export default function ProviderSetupActions({ onCancel, onSubmit }: ProviderSetupActionsProps) {
|
||||
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 */}
|
||||
<Button
|
||||
type="submit"
|
||||
|
||||
@@ -14,8 +14,8 @@ export function SecureStorageNotice({
|
||||
message = 'Keys are stored securely in the keychain',
|
||||
}) {
|
||||
return (
|
||||
<div className={`flex items-start mt-2 text-gray-600 dark:text-gray-300 ${className}`}>
|
||||
<Lock className="w-5 h-5 mt-1" />
|
||||
<div className={`flex items-center mt-2 text-gray-600 dark:text-gray-300 ${className}`}>
|
||||
<Lock className="w-5 h-5" />
|
||||
<span className="text-sm font-light ml-2">{message}</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -3,6 +3,8 @@ import React from 'react';
|
||||
interface CardContainerProps {
|
||||
header: React.ReactNode;
|
||||
body: React.ReactNode;
|
||||
onClick: () => void;
|
||||
grayedOut: boolean;
|
||||
}
|
||||
|
||||
function GlowingRing() {
|
||||
@@ -24,11 +26,29 @@ function HeaderContainer({ children }: HeaderContainerProps) {
|
||||
return <div>{children}</div>;
|
||||
}
|
||||
|
||||
export default function CardContainer({ header, body }: CardContainerProps) {
|
||||
export default function CardContainer({
|
||||
header,
|
||||
body,
|
||||
onClick,
|
||||
grayedOut = false,
|
||||
}: CardContainerProps) {
|
||||
return (
|
||||
<div className="relative h-full p-[2px] overflow-hidden rounded-[9px] group/card bg-borderSubtle hover:bg-transparent hover:duration-300">
|
||||
<GlowingRing />
|
||||
<div className="relative bg-bgApp rounded-lg p-3 transition-all duration-200 h-[160px] flex flex-col justify-between hover:border-borderStandard">
|
||||
<div
|
||||
className={`relative h-full p-[2px] overflow-hidden rounded-[9px] group/card bg-borderSubtle ${
|
||||
!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>
|
||||
{body}
|
||||
</div>
|
||||
|
||||
@@ -24,14 +24,20 @@ export const ProviderCard = memo(function ProviderCard({
|
||||
// Instead of useEffect for logging, use useMemo to memoize the metadata
|
||||
const metadata = useMemo(() => providerMetadata, [provider]);
|
||||
|
||||
// Remove the logging completely
|
||||
|
||||
if (!metadata) {
|
||||
return <div>ProviderCard error: No metadata provided</div>;
|
||||
}
|
||||
|
||||
const handleCardClick = () => {
|
||||
if (!isOnboarding) {
|
||||
onConfigure();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<CardContainer
|
||||
grayedOut={!provider.is_configured && isOnboarding} // onboarding page will have grayed out cards if not configured
|
||||
onClick={handleCardClick}
|
||||
header={
|
||||
<CardHeader
|
||||
name={metadata.display_name || provider?.name || 'Unknown Provider'}
|
||||
|
||||
@@ -34,7 +34,7 @@ export default function DefaultCardButtons({
|
||||
{/*Set up an unconfigured provider */}
|
||||
{!provider.is_configured && (
|
||||
<ConfigureSettingsButton
|
||||
tooltip={getDefaultTooltipMessages(provider.name, 'add')}
|
||||
tooltip={getDefaultTooltipMessages(provider.metadata.display_name, 'add')}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onConfigure(provider);
|
||||
@@ -44,7 +44,7 @@ export default function DefaultCardButtons({
|
||||
{/*show edit tooltip instead when hovering over button for configured providers*/}
|
||||
{provider.is_configured && !isOnboardingPage && (
|
||||
<ConfigureSettingsButton
|
||||
tooltip={getDefaultTooltipMessages(provider.name, 'edit')}
|
||||
tooltip={getDefaultTooltipMessages(provider.metadata.display_name, 'edit')}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onConfigure(provider);
|
||||
@@ -54,6 +54,7 @@ export default function DefaultCardButtons({
|
||||
{/*show Launch button for configured providers on onboarding page*/}
|
||||
{provider.is_configured && isOnboardingPage && (
|
||||
<RocketButton
|
||||
tooltip={'Get started with goose!'}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onLaunch(provider);
|
||||
|
||||
Reference in New Issue
Block a user