mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-29 20:20:57 +00:00
fix extension ui
This commit is contained in:
parent
15b5bc3bfc
commit
597ce85335
5 changed files with 20 additions and 49 deletions
|
|
@ -22,6 +22,7 @@ import type { Extension, Config } from '@qwen-code/qwen-code-core';
|
|||
import { SettingScope, createDebugLogger } from '@qwen-code/qwen-code-core';
|
||||
import { ExtensionUpdateState } from '../../state/extensions.js';
|
||||
import { getErrorMessage } from '../../../utils/errors.js';
|
||||
import { useTerminalSize } from '../../hooks/useTerminalSize.js';
|
||||
|
||||
interface ExtensionsManagerDialogProps {
|
||||
onClose: () => void;
|
||||
|
|
@ -46,6 +47,8 @@ export function ExtensionsManagerDialog({
|
|||
const [updateError, setUpdateError] = useState<string | null>(null);
|
||||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const { columns } = useTerminalSize();
|
||||
const boxWidth = columns - 4;
|
||||
|
||||
// Load extensions
|
||||
const loadExtensions = useCallback(async () => {
|
||||
|
|
@ -362,10 +365,10 @@ export function ExtensionsManagerDialog({
|
|||
const currentStep = getCurrentStep();
|
||||
const getNavigationInstructions = () => {
|
||||
if (currentStep === MANAGEMENT_STEPS.EXTENSION_LIST) {
|
||||
if (extensions.length === 0) {
|
||||
if (extensions.length === 0 || successMessage) {
|
||||
return t('Esc to close');
|
||||
}
|
||||
return t('Enter to select, ↑↓ to navigate, Esc to close');
|
||||
return t('↑↓ to navigate · Enter to select · Esc to close');
|
||||
}
|
||||
|
||||
if (currentStep === MANAGEMENT_STEPS.EXTENSION_DETAIL) {
|
||||
|
|
@ -373,14 +376,14 @@ export function ExtensionsManagerDialog({
|
|||
}
|
||||
|
||||
if (currentStep === MANAGEMENT_STEPS.UNINSTALL_CONFIRMATION) {
|
||||
return t('Y/Enter to confirm, N/Esc to cancel');
|
||||
return t('Y/Enter to confirm · N/Esc to cancel');
|
||||
}
|
||||
|
||||
if (currentStep === MANAGEMENT_STEPS.UPDATE_PROGRESS) {
|
||||
return updateInProgress ? t('Updating...') : '';
|
||||
}
|
||||
|
||||
return t('Enter to select, ↑↓ to navigate, Esc to go back');
|
||||
return t('↑↓ to navigate · Enter to select · Esc to go back');
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -388,7 +391,7 @@ export function ExtensionsManagerDialog({
|
|||
<Text color={theme.text.secondary}>{getNavigationInstructions()}</Text>
|
||||
</Box>
|
||||
);
|
||||
}, [getCurrentStep, extensions.length, updateInProgress]);
|
||||
}, [getCurrentStep, extensions.length, updateInProgress, successMessage]);
|
||||
|
||||
const renderStepContent = useCallback(() => {
|
||||
const currentStep = getCurrentStep();
|
||||
|
|
@ -435,7 +438,6 @@ export function ExtensionsManagerDialog({
|
|||
selectedExtension={selectedExtension}
|
||||
hasUpdateAvailable={hasUpdateAvailable}
|
||||
onNavigateToStep={handleNavigateToStep}
|
||||
onNavigateBack={handleNavigateBack}
|
||||
onActionSelect={handleActionSelect}
|
||||
/>
|
||||
);
|
||||
|
|
@ -447,7 +449,6 @@ export function ExtensionsManagerDialog({
|
|||
selectedExtension={selectedExtension}
|
||||
mode="disable"
|
||||
onScopeSelect={handleDisableExtension}
|
||||
onNavigateBack={handleNavigateBack}
|
||||
/>
|
||||
);
|
||||
case MANAGEMENT_STEPS.ENABLE_SCOPE_SELECT:
|
||||
|
|
@ -456,7 +457,6 @@ export function ExtensionsManagerDialog({
|
|||
selectedExtension={selectedExtension}
|
||||
mode="enable"
|
||||
onScopeSelect={handleEnableExtension}
|
||||
onNavigateBack={handleNavigateBack}
|
||||
/>
|
||||
);
|
||||
case MANAGEMENT_STEPS.UNINSTALL_CONFIRMATION:
|
||||
|
|
@ -508,13 +508,14 @@ export function ExtensionsManagerDialog({
|
|||
]);
|
||||
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Box flexDirection="column" width={boxWidth}>
|
||||
<Box
|
||||
borderStyle="single"
|
||||
borderColor={theme.border.default}
|
||||
flexDirection="column"
|
||||
padding={1}
|
||||
width="100%"
|
||||
paddingLeft={1}
|
||||
paddingRight={1}
|
||||
width={boxWidth}
|
||||
gap={1}
|
||||
>
|
||||
{renderStepHeader()}
|
||||
|
|
|
|||
|
|
@ -15,14 +15,12 @@ interface ActionSelectionStepProps {
|
|||
selectedExtension: Extension | null;
|
||||
hasUpdateAvailable: boolean;
|
||||
onNavigateToStep: (step: string) => void;
|
||||
onNavigateBack: () => void;
|
||||
onActionSelect: (action: ExtensionAction) => void;
|
||||
}
|
||||
|
||||
export const ActionSelectionStep = ({
|
||||
selectedExtension,
|
||||
hasUpdateAvailable,
|
||||
onNavigateBack,
|
||||
onActionSelect,
|
||||
}: ActionSelectionStepProps) => {
|
||||
const [selectedAction, setSelectedAction] = useState<ExtensionAction | null>(
|
||||
|
|
@ -78,23 +76,11 @@ export const ActionSelectionStep = ({
|
|||
},
|
||||
value: 'uninstall' as const,
|
||||
},
|
||||
{
|
||||
key: 'back',
|
||||
get label() {
|
||||
return t('Back');
|
||||
},
|
||||
value: 'back' as const,
|
||||
},
|
||||
];
|
||||
return allActions;
|
||||
}, [hasUpdateAvailable, isActive]);
|
||||
|
||||
const handleActionSelect = (value: ExtensionAction) => {
|
||||
if (value === 'back') {
|
||||
onNavigateBack();
|
||||
return;
|
||||
}
|
||||
|
||||
setSelectedAction(value);
|
||||
onActionSelect(value);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -160,18 +160,18 @@ export const ExtensionListStep = ({
|
|||
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Box flexDirection="column" marginBottom={1}>
|
||||
{extensions.map((extension, index) =>
|
||||
renderExtensionItem(extension, index, index === selectedIndex),
|
||||
)}
|
||||
</Box>
|
||||
<Box marginTop={1}>
|
||||
<Box marginBottom={1}>
|
||||
<Text color={theme.text.secondary}>
|
||||
{t('{{count}} extensions installed', {
|
||||
count: extensions.length.toString(),
|
||||
})}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box flexDirection="column">
|
||||
{extensions.map((extension, index) =>
|
||||
renderExtensionItem(extension, index, index === selectedIndex),
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,14 +14,12 @@ interface ScopeSelectStepProps {
|
|||
selectedExtension: Extension | null;
|
||||
mode: 'disable' | 'enable';
|
||||
onScopeSelect: (scope: 'user' | 'workspace') => void;
|
||||
onNavigateBack: () => void;
|
||||
}
|
||||
|
||||
export function ScopeSelectStep({
|
||||
selectedExtension,
|
||||
mode,
|
||||
onScopeSelect,
|
||||
onNavigateBack,
|
||||
}: ScopeSelectStepProps) {
|
||||
const scopeItems = [
|
||||
{
|
||||
|
|
@ -38,20 +36,9 @@ export function ScopeSelectStep({
|
|||
},
|
||||
value: 'workspace' as const,
|
||||
},
|
||||
{
|
||||
key: 'back',
|
||||
get label() {
|
||||
return t('Back');
|
||||
},
|
||||
value: 'back' as const,
|
||||
},
|
||||
];
|
||||
|
||||
const handleSelect = (value: 'user' | 'workspace' | 'back') => {
|
||||
if (value === 'back') {
|
||||
onNavigateBack();
|
||||
return;
|
||||
}
|
||||
const handleSelect = (value: 'user' | 'workspace') => {
|
||||
onScopeSelect(value);
|
||||
};
|
||||
|
||||
|
|
@ -71,7 +58,7 @@ export function ScopeSelectStep({
|
|||
return (
|
||||
<Box flexDirection="column" gap={1}>
|
||||
<Text color={theme.text.primary}>{title}</Text>
|
||||
<Box marginTop={1}>
|
||||
<Box>
|
||||
<RadioButtonSelect
|
||||
items={scopeItems}
|
||||
onSelect={handleSelect}
|
||||
|
|
|
|||
|
|
@ -60,9 +60,6 @@ export function UninstallConfirmStep({
|
|||
<Text color={theme.text.secondary}>
|
||||
{t('This action cannot be undone.')}
|
||||
</Text>
|
||||
<Box marginTop={1}>
|
||||
<Text>{t('Press Y/Enter to confirm, N/Esc to cancel')}</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue