mirror of
https://github.com/aljazceru/goose.git
synced 2026-01-30 11:44:38 +01:00
feat: update extensions cards (#2174)
This commit is contained in:
@@ -37,7 +37,20 @@ export default function ExtensionsSection({ deepLinkConfig, showEnvVars }: Exten
|
||||
const fetchExtensions = useCallback(async () => {
|
||||
const extensionsList = await getExtensions(true); // Force refresh
|
||||
// Sort extensions by name to maintain consistent order
|
||||
const sortedExtensions = [...extensionsList].sort((a, b) => a.name.localeCompare(b.name));
|
||||
const sortedExtensions = [...extensionsList].sort((a, b) => {
|
||||
// First sort by builtin
|
||||
if (a.type === 'builtin' && b.type !== 'builtin') return -1;
|
||||
if (a.type !== 'builtin' && b.type === 'builtin') return 1;
|
||||
|
||||
// Then sort by bundled (handle null/undefined cases)
|
||||
const aBundled = a.bundled === true;
|
||||
const bBundled = b.bundled === true;
|
||||
if (aBundled && !bBundled) return -1;
|
||||
if (!aBundled && bBundled) return 1;
|
||||
|
||||
// Finally sort alphabetically within each group
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
setExtensions(sortedExtensions);
|
||||
}, [getExtensions]);
|
||||
|
||||
|
||||
@@ -46,14 +46,15 @@ export default function ExtensionItem({ extension, onToggle, onConfigure }: Exte
|
||||
}
|
||||
}, [extension.enabled, isToggling]);
|
||||
|
||||
const renderFormattedSubtitle = () => {
|
||||
const subtitle = getSubtitle(extension);
|
||||
return subtitle.split('\n').map((part, index) => (
|
||||
<React.Fragment key={index}>
|
||||
{index === 0 ? part : <span className="font-mono text-xs">{part}</span>}
|
||||
{index < subtitle.split('\n').length - 1 && <br />}
|
||||
</React.Fragment>
|
||||
));
|
||||
const renderSubtitle = () => {
|
||||
const { description, command } = getSubtitle(extension);
|
||||
return (
|
||||
<>
|
||||
{description && <span>{description}</span>}
|
||||
{description && command && <br />}
|
||||
{command && <span className="font-mono text-xs">{command}</span>}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// Bundled extensions and builtins are not editable
|
||||
@@ -67,7 +68,7 @@ export default function ExtensionItem({ extension, onToggle, onConfigure }: Exte
|
||||
>
|
||||
<div className="flex flex-col w-max-[90%]">
|
||||
<h3 className="text-textStandard">{getFriendlyTitle(extension)}</h3>
|
||||
<p className="text-xs text-textSubtle">{renderFormattedSubtitle()}</p>
|
||||
<p className="text-xs text-textSubtle">{renderSubtitle()}</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
||||
@@ -25,6 +25,7 @@ export default function ExtensionList({ extensions, onToggle, onConfigure }: Ext
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
// Helper function to get a friendly title from extension name
|
||||
export function getFriendlyTitle(extension: FixedExtensionEntry): string {
|
||||
@@ -46,23 +47,46 @@ export function getFriendlyTitle(extension: FixedExtensionEntry): string {
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
export interface SubtitleParts {
|
||||
description: string | null;
|
||||
command: string | null;
|
||||
}
|
||||
|
||||
// Helper function to get a subtitle based on extension type and configuration
|
||||
export function getSubtitle(config: ExtensionConfig): string {
|
||||
export function getSubtitle(config: ExtensionConfig): SubtitleParts {
|
||||
if (config.type === 'builtin') {
|
||||
// Find matching extension in the data
|
||||
const extensionData = builtInExtensionsData.find((ext) => ext.name === config.name);
|
||||
if (extensionData?.description) {
|
||||
return extensionData.description;
|
||||
}
|
||||
return 'Built-in extension';
|
||||
const extensionData = builtInExtensionsData.find(
|
||||
(ext) =>
|
||||
ext.name.toLowerCase().replace(/\s+/g, '') === config.name.toLowerCase().replace(/\s+/g, '')
|
||||
);
|
||||
return {
|
||||
description: extensionData?.description || 'Built-in extension',
|
||||
command: null,
|
||||
};
|
||||
}
|
||||
|
||||
if (config.type === 'stdio') {
|
||||
// remove shims for displaying
|
||||
const full_command = combineCmdAndArgs(removeShims(config.cmd), config.args);
|
||||
return `STDIO extension${config.description ? `: ${config.description}` : ''}${full_command ? `\n${full_command}` : ''}`;
|
||||
// Only include command if it exists
|
||||
const full_command = config.cmd
|
||||
? combineCmdAndArgs(removeShims(config.cmd), config.args)
|
||||
: null;
|
||||
return {
|
||||
description: config.description || null,
|
||||
command: full_command,
|
||||
};
|
||||
}
|
||||
|
||||
if (config.type === 'sse') {
|
||||
return `SSE extension${config.description ? `: ${config.description}` : ''}${config.uri ? ` (${config.uri})` : ''}`;
|
||||
const description = config.description
|
||||
? `SSE extension: ${config.description}`
|
||||
: 'SSE extension';
|
||||
const command = config.uri || null;
|
||||
return { description, command };
|
||||
}
|
||||
return `Unknown type of extension`;
|
||||
|
||||
return {
|
||||
description: 'Unknown type of extension',
|
||||
command: null,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user