styles: settings v2 (#2103)

This commit is contained in:
Nahiyan Khan
2025-04-09 10:09:00 -04:00
committed by GitHub
parent 2c483a8146
commit 4b86900f47
23 changed files with 154 additions and 153 deletions
@@ -113,11 +113,11 @@ export default function ExtensionsSection() {
};
return (
<section id="extensions">
<div className="flex justify-between items-center mb-6 px-8">
<h1 className="text-3xl font-medium text-textStandard">Extensions</h1>
<section id="extensions" className="px-8">
<div className="flex justify-between items-center mb-2">
<h2 className="text-xl font-medium text-textStandard">Extensions</h2>
</div>
<div className="px-8">
<div className="border-b border-borderSubtle pb-8">
<p className="text-sm text-textStandard mb-6">
These extensions use the Model Context Protocol (MCP). They can expand Goose's
capabilities using three main components: Prompts, Resources, and Tools.
@@ -131,46 +131,46 @@ export default function ExtensionsSection() {
<div className="flex gap-4 pt-4 w-full">
<Button
className="flex items-center gap-2 flex-1 justify-center text-white dark:text-textSubtle bg-black dark:bg-white hover:bg-subtle"
className="flex items-center gap-2 justify-center text-white dark:text-textSubtle bg-bgAppInverse hover:bg-bgStandardInverse [&>svg]:!size-4"
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 bg-white dark:bg-black hover:bg-subtle dark:border dark:border-gray-500 dark:hover:border-gray-400"
className="flex items-center gap-2 justify-center text-textStandard bg-bgApp border border-borderSubtle hover:border-borderProminent hover:bg-bgApp [&>svg]:!size-4"
onClick={() => window.open('https://block.github.io/goose/v1/extensions/', '_blank')}
>
<GPSIcon size={18} />
Visit Extensions
<GPSIcon size={12} />
Browse extensions
</Button>
</div>
{/* Modal for updating an existing extension */}
{isModalOpen && selectedExtension && (
<ExtensionModal
title="Update Extension"
initialData={extensionToFormData(selectedExtension)}
onClose={handleModalClose}
onSubmit={handleUpdateExtension}
onDelete={handleDeleteExtension}
submitLabel="Save Changes"
modalType={'edit'}
/>
)}
{/* Modal for adding a new extension */}
{isAddModalOpen && (
<ExtensionModal
title="Add custom extension"
initialData={getDefaultFormData()}
onClose={handleModalClose}
onSubmit={handleAddExtension}
submitLabel="Add Extension"
modalType={'add'}
/>
)}
</div>
{/* Modal for updating an existing extension */}
{isModalOpen && selectedExtension && (
<ExtensionModal
title="Update Extension"
initialData={extensionToFormData(selectedExtension)}
onClose={handleModalClose}
onSubmit={handleUpdateExtension}
onDelete={handleDeleteExtension}
submitLabel="Save Changes"
modalType={'edit'}
/>
)}
{/* Modal for adding a new extension */}
{isAddModalOpen && (
<ExtensionModal
title="Add New Extension"
initialData={getDefaultFormData()}
onClose={handleModalClose}
onSubmit={handleAddExtension}
submitLabel="Add Extension"
modalType={'add'}
/>
)}
</section>
);
}
@@ -74,7 +74,7 @@ export default function EnvVarsSection({
<label className="text-sm font-medium text-textStandard mb-2 block">
Environment Variables
</label>
<p className="text-xs text-textSubtle mb-2">
<p className="text-xs text-textSubtle mb-4">
Add key-value pairs for environment variables. Click the "+" button to add after filling
both fields.
</p>
@@ -89,7 +89,7 @@ export default function EnvVarsSection({
onChange={(e) => onChange(index, 'key', e.target.value)}
placeholder="Variable name"
className={cn(
'w-full border-borderSubtle text-textStandard',
'w-full text-textStandard border-borderSubtle hover:border-borderStandard',
isFieldInvalid(index, 'key') && 'border-red-500 focus:border-red-500'
)}
/>
@@ -100,7 +100,7 @@ export default function EnvVarsSection({
onChange={(e) => onChange(index, 'value', e.target.value)}
placeholder="Value"
className={cn(
'w-full border-borderSubtle text-textStandard',
'w-full text-textStandard border-borderSubtle hover:border-borderStandard',
isFieldInvalid(index, 'value') && 'border-red-500 focus:border-red-500'
)}
/>
@@ -124,7 +124,7 @@ export default function EnvVarsSection({
}}
placeholder="Variable name"
className={cn(
'w-full border-borderStandard text-textStandard',
'w-full text-textStandard border-borderSubtle hover:border-borderStandard',
invalidFields.key && 'border-red-500 focus:border-red-500'
)}
/>
@@ -136,16 +136,16 @@ export default function EnvVarsSection({
}}
placeholder="Value"
className={cn(
'w-full border-borderStandard text-textStandard',
'w-full text-textStandard border-borderSubtle hover:border-borderStandard',
invalidFields.value && 'border-red-500 focus:border-red-500'
)}
/>
<Button
onClick={handleAdd}
variant="ghost"
className="flex items-center justify-start gap-1 px-2 pr-4 text-s font-medium rounded-full dark:bg-slate-400 dark:text-gray-300 bg-gray-300 dark:bg-slate text-slate-400 dark:hover:bg-slate-300 hover:bg-gray-500 hover:text-white dark:hover:text-gray-900 transition-colors min-w-[60px] h-9"
className="flex items-center justify-start gap-1 px-2 pr-4 text-sm rounded-full text-textStandard bg-bgApp border border-borderSubtle hover:border-borderStandard transition-colors min-w-[60px] h-9 [&>svg]:!size-4"
>
<Plus className="h-3 w-3" /> Add
<Plus /> Add
</Button>
</div>
{validationError && <div className="mt-2 text-red-500 text-sm">{validationError}</div>}
@@ -1,5 +1,5 @@
import { Input } from '../../../ui/input';
import Select from 'react-select';
import { Select } from '../../../ui/Select';
import React, { useState } from 'react';
interface ExtensionInfoFieldsProps {
@@ -131,7 +131,7 @@ export default function ExtensionModal({
<>
<div className="w-full px-6 py-4 bg-red-900/20 border-t border-red-500/30">
<p className="text-red-400 text-sm mb-2">
Are you sure you want to delete "{formData.name}"? This action cannot be undone.
Are you sure you want to remove "{formData.name}"? This action cannot be undone.
</p>
</div>
<Button
@@ -143,7 +143,7 @@ export default function ExtensionModal({
}}
className="w-full h-[60px] rounded-none border-b border-borderSubtle bg-transparent hover:bg-red-900/20 text-red-500 font-medium text-md"
>
<Trash2 className="h-4 w-4 mr-2" /> Confirm Delete
<Trash2 className="h-4 w-4 mr-2" /> Confirm removal
</Button>
<Button
onClick={() => setShowDeleteConfirmation(false)}
@@ -159,9 +159,9 @@ export default function ExtensionModal({
{modalType === 'edit' && onDelete && (
<Button
onClick={() => setShowDeleteConfirmation(true)}
className="w-full h-[60px] rounded-none border-b border-borderSubtle bg-transparent hover:bg-bgSubtle text-red-500 font-medium text-md"
className="w-full h-[60px] rounded-none border-b border-borderSubtle bg-transparent hover:bg-bgSubtle text-red-500 font-medium text-md [&>svg]:!size-4"
>
<Trash2 className="h-4 w-4 mr-2" /> Delete Extension
<Trash2 className="h-4 w-4 mr-2" /> Remove extension
</Button>
)}
<Button
@@ -29,25 +29,20 @@ export default function ExtensionTimeoutField({
return (
<div className="flex flex-col gap-4 mb-6">
{/* Row with Timeout and timeout input side by side */}
<div className="flex justify-between gap-4">
<div className="flex flex-col">
<div className="flex-1">
<label className="text-sm font-medium mb-2 block text-textStandard">Timeout</label>
</div>
{/* Type Dropdown */}
<div className="w-[200px]">
<div className="relative">
<Input
value={timeout}
onChange={(e) => onChange('timeout', e.target.value)}
defaultValue={300}
className={`${!submitAttempted || isTimeoutValid() ? 'border-borderSubtle' : 'border-red-500'} text-textStandard focus:border-borderStandard`}
/>
{submitAttempted && !isTimeoutValid() && (
<div className="absolute text-xs text-red-500 mt-1">Timeout </div>
)}
</div>
</div>
<Input
value={timeout}
onChange={(e) => onChange('timeout', e.target.value)}
defaultValue={300}
className={`${!submitAttempted || isTimeoutValid() ? 'border-borderSubtle' : 'border-red-500'} text-textStandard focus:border-borderStandard`}
/>
{submitAttempted && !isTimeoutValid() && (
<div className="absolute text-xs text-red-500 mt-1">Timeout </div>
)}
</div>
</div>
);
@@ -57,27 +57,34 @@ export default function ExtensionItem({ extension, onToggle, onConfigure }: Exte
};
return (
<div className="rounded-lg border border-borderSubtle p-4 mb-2">
<div className="flex items-center justify-between mb-2">
<h3 className="font-medium text-textStandard">{getFriendlyTitle(extension)}</h3>
<div className="flex items-center gap-2">
{/* Only show config button for non-builtin extensions */}
{extension.type !== 'builtin' && (
<button
className="text-textSubtle hover:text-textStandard"
onClick={() => onConfigure(extension)}
>
<Gear className="h-4 w-4" />
</button>
)}
<Switch
checked={(isToggling && visuallyEnabled) || extension.enabled}
onCheckedChange={() => handleToggle(extension)}
variant="mono"
/>
</div>
<div
className="flex justify-between rounded-lg transition-colors border border-borderSubtle p-4 pt-3 hover:border-borderProminent hover:cursor-pointer"
onClick={() => handleToggle(extension)}
>
<div className="flex flex-col w-max-[90%]">
<h3 className="text-textStandard">{getFriendlyTitle(extension)}</h3>
<p className="text-xs text-textSubtle">{renderFormattedSubtitle()}</p>
</div>
<div
className="flex items-center justify-end gap-2 w-max-[10%]"
onClick={(e) => e.stopPropagation()}
>
{/* Only show config button for non-builtin extensions */}
{extension.type !== 'builtin' && (
<button
className="text-textSubtle hover:text-textStandard"
onClick={() => onConfigure(extension)}
>
<Gear className="h-4 w-4" />
</button>
)}
<Switch
checked={(isToggling && visuallyEnabled) || extension.enabled}
onCheckedChange={() => handleToggle(extension)}
variant="mono"
/>
</div>
<p className="text-sm text-textSubtle">{renderFormattedSubtitle()}</p>
</div>
);
}
@@ -13,7 +13,7 @@ interface ExtensionListProps {
export default function ExtensionList({ extensions, onToggle, onConfigure }: ExtensionListProps) {
return (
<div className="grid grid-cols-2 gap-6">
<div className="grid grid-cols-2 gap-2 mb-2">
{extensions.map((extension) => (
<ExtensionItem
key={extension.name}