Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 9 additions & 28 deletions ui/desktop/src/components/BottomMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { Document, ChevronUp, ChevronDown } from './icons';
import type { View } from '../App';
import { BottomMenuModeSelection } from './BottomMenuModeSelection';
import { RadioInput } from './ui/RadioInput';

export default function BottomMenu({
hasMessages,
Expand All @@ -16,7 +17,7 @@
}) {
const [isModelMenuOpen, setIsModelMenuOpen] = useState(false);
const { currentModel } = useModel();
const { recentModels } = useRecentModels(); // Get recent models

Check warning on line 20 in ui/desktop/src/components/BottomMenu.tsx

View workflow job for this annotation

GitHub Actions / Lint Electron Desktop App

'recentModels' is assigned a value but never used. Allowed unused vars must match /^_/u
const dropdownRef = useRef<HTMLDivElement>(null);

// Add effect to handle clicks outside
Expand Down Expand Up @@ -96,34 +97,14 @@
<div className="">
<ModelRadioList
className="divide-y divide-borderSubtle"
renderItem={({ model, isSelected, onSelect }) => (
<label key={model.alias ?? model.name} className="block cursor-pointer">
<div
className="flex items-center justify-between p-2 text-textStandard hover:bg-bgSubtle transition-colors"
onClick={onSelect}
>
<div>
<p className="text-sm ">{model.alias ?? model.name}</p>
<p className="text-xs text-textSubtle">{model.subtext ?? model.provider}</p>
</div>
<div className="relative">
<input
type="radio"
name="recentModels"
value={model.name}
checked={isSelected}
onChange={onSelect}
className="peer sr-only"
/>
<div
className="h-4 w-4 rounded-full border border-gray-400 dark:border-gray-500
peer-checked:border-[6px] peer-checked:border-black dark:peer-checked:border-white
peer-checked:bg-white dark:peer-checked:bg-black
transition-all duration-200 ease-in-out"
></div>
</div>
</div>
</label>
RenderItem={({ model, isSelected, onSelect }) => (
<RadioInput
label={model.alias ?? model.name}
description={model.subtext ?? model.provider}
value={model.name}
isChecked={isSelected}
onClick={onSelect}
/>
)}
/>
<div
Expand Down
2 changes: 1 addition & 1 deletion ui/desktop/src/components/BottomMenuModeSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export const BottomMenuModeSelection = () => {
{/* Dropdown Menu */}
{isGooseModeMenuOpen && (
<div className="absolute bottom-[24px] right-0 w-[240px] bg-bgApp rounded-lg border border-borderSubtle">
<div>
<div className="divide-y divide-borderSubtle">
{filterGooseModes(gooseMode, all_goose_modes, previousApproveModel).map((mode) => (
<ModeSelectionItem
key={mode.key}
Expand Down
81 changes: 31 additions & 50 deletions ui/desktop/src/components/settings/basic/ModeSelectionItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import { Gear } from '../../icons';
import { ConfigureApproveMode } from './ConfigureApproveMode';
import { RadioInput } from '../../ui/RadioInput';

export interface GooseMode {
key: string;
Expand Down Expand Up @@ -66,6 +67,17 @@ export function filterGooseModes(
});
}

const ConfigureButton = ({ onClick }) => (
<button
onClick={(event) => {
event.stopPropagation();
onClick();
}}
>
<Gear className="w-5 h-5 text-textSubtle hover:text-textStandard" />
</button>
);

interface ModeSelectionItemProps {
currentMode: string;
mode: GooseMode;
Expand All @@ -88,60 +100,29 @@ export function ModeSelectionItem({
setChecked(currentMode === mode.key);
}, [currentMode, mode.key]);

const showConfigure =
!isApproveModeConfigure && (mode.key == 'approve' || mode.key == 'smart_approve');

return (
<div>
<div
className="flex items-center justify-between p-2 text-textStandard hover:bg-bgSubtle transition-colors"
<RadioInput
label={mode.label}
description={showDescription ? mode.description : null}
Accessory={() =>
showConfigure ? <ConfigureButton onClick={() => setIsDislogOpen(true)} /> : null
}
isChecked={checked}
onClick={() => handleModeChange(mode.key)}
>
<div>
<h3 className="text-sm font-semibold text-textStandard dark:text-gray-200">
{mode.label}
</h3>
{showDescription && (
<p className="text-xs text-textSubtle dark:text-gray-400 mt-[2px]">
{mode.description}
</p>
)}
</div>
<div className="relative flex items-center gap-3">
{!isApproveModeConfigure && (mode.key == 'approve' || mode.key == 'smart_approve') && (
<button
onClick={() => {
setIsDislogOpen(true);
}}
>
<Gear className="w-5 h-5 text-textSubtle hover:text-textStandard" />
</button>
)}
<input
type="radio"
name="modes"
value={mode.key}
checked={checked}
onChange={() => handleModeChange(mode.key)}
className="peer sr-only"
/>
<div
className="h-5 w-5 rounded-full border border-gray-400 dark:border-gray-500
peer-checked:border-[6px] peer-checked:border-black dark:peer-checked:border-white
peer-checked:bg-white dark:peer-checked:bg-black
transition-all duration-200 ease-in-out"
></div>
</div>
</div>
value={mode.key}
/>
<div>
<div>
{isDislogOpen ? (
<ConfigureApproveMode
onClose={() => {
setIsDislogOpen(false);
}}
handleModeChange={handleModeChange}
currentMode={currentMode}
/>
) : null}
</div>
{isDislogOpen ? (
<ConfigureApproveMode
onClose={() => setIsDislogOpen(false)}
handleModeChange={handleModeChange}
currentMode={currentMode}
/>
) : null}
</div>
</div>
);
Expand Down
23 changes: 10 additions & 13 deletions ui/desktop/src/components/settings/models/ModelRadioList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import { useHandleModelSelection } from './utils';
import type { View } from '@/src/App';

interface ModelRadioListProps {
renderItem: (props: {
model: Model;
isSelected: boolean;
onSelect: () => void;
}) => React.ReactNode;
RenderItem: React.FC<{ model: Model; isSelected: boolean; onSelect: () => void }>;
className?: string;
}

Expand All @@ -29,7 +25,7 @@ export function SeeMoreModelsButtons({ setView }: { setView: (view: View) => voi
);
}

export function ModelRadioList({ renderItem, className = '' }: ModelRadioListProps) {
export function ModelRadioList({ RenderItem, className = '' }: ModelRadioListProps) {
const { recentModels } = useRecentModels();
const { currentModel } = useModel();
const handleModelSelection = useHandleModelSelection();
Expand All @@ -53,13 +49,14 @@ export function ModelRadioList({ renderItem, className = '' }: ModelRadioListPro

return (
<div className={className}>
{recentModels.map((model) =>
renderItem({
model,
isSelected: selectedModel === model.name,
onSelect: () => handleRadioChange(model),
})
)}
{recentModels.map((model) => (
<RenderItem
key={model.name}
model={model}
isSelected={selectedModel === model.name}
onSelect={() => handleRadioChange(model)}
/>
))}
</div>
);
}
2 changes: 1 addition & 1 deletion ui/desktop/src/components/settings/models/RecentModels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export function RecentModelsRadio({ setView }: { setView: (view: View) => void }
<div className="px-8">
<div className="space-y-2">
<ModelRadioList
renderItem={({ model, isSelected, onSelect }) => (
RenderItem={({ model, isSelected, onSelect }) => (
<label key={model.name} className="flex items-center py-2 cursor-pointer">
<div className="relative mr-4">
<input
Expand Down
49 changes: 49 additions & 0 deletions ui/desktop/src/components/ui/RadioInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';

export interface RadioInputProps {
label: string;
description: string | null;
Accessory?: React.FC;
value: string;
isChecked: boolean;
onClick: () => void;
}
export const RadioInput = ({
label,
description,
Accessory,
value,
isChecked,
onClick,
}: RadioInputProps) => {
return (
<div className="block cursor-pointer" onClick={onClick}>
<div
className="flex items-center justify-between p-2 text-textStandard hover:bg-bgSubtle transition-colors"
onClick={onClick}
>
<div>
<p className="text-sm ">{label}</p>
<p className="text-xs text-textSubtle">{description}</p>
</div>
<div className="relative flex items-center gap-3">
{Accessory ? <Accessory /> : null}
<input
type="radio"
name="recentModels"
value={value}
checked={isChecked}
onChange={onClick}
className="peer sr-only"
/>
<div
className="h-4 w-4 rounded-full border border-gray-400 dark:border-gray-500
peer-checked:border-[6px] peer-checked:border-black dark:peer-checked:border-white
peer-checked:bg-white dark:peer-checked:bg-black
transition-all duration-200 ease-in-out"
></div>
</div>
</div>
</div>
);
};
Loading