feat: use the permission page in bottom menu (#2218)

This commit is contained in:
Yingjie He
2025-04-16 14:51:01 -07:00
committed by GitHub
parent ec53e39347
commit 48a8f5a704
7 changed files with 34 additions and 65 deletions

View File

@@ -781,7 +781,11 @@ export default function App() {
}}
/>
)}
{view === 'permission' && <PermissionSettingsView onClose={() => setView('settings')} />}
{view === 'permission' && (
<PermissionSettingsView
onClose={() => setView((viewOptions as { parentView: View }).parentView)}
/>
)}
</div>
</div>
{isGoosehintsModalOpen && (

View File

@@ -3,7 +3,7 @@ import { useModel } from './settings/models/ModelContext';
import { Sliders } from 'lucide-react';
import { ModelRadioList } from './settings/models/ModelRadioList';
import { Document, ChevronUp, ChevronDown } from './icons';
import type { View } from '../App';
import type { View, ViewOptions } from '../App';
import { settingsV2Enabled } from '../flags';
import { BottomMenuModeSelection } from './BottomMenuModeSelection';
import ModelsBottomBar from './settings_v2/models/bottom_bar/ModelsBottomBar';
@@ -13,7 +13,7 @@ export default function BottomMenu({
setView,
}: {
hasMessages: boolean;
setView: (view: View) => void;
setView: (view: View, viewOptions?: ViewOptions) => void;
}) {
const [isModelMenuOpen, setIsModelMenuOpen] = useState(false);
const { currentModel } = useModel();
@@ -74,7 +74,7 @@ export default function BottomMenu({
</span>
{/* Goose Mode Selector Dropdown */}
<BottomMenuModeSelection />
<BottomMenuModeSelection setView={setView} />
{/* Right-side section with ToolCount and Model Selector together */}
<div className="flex items-center mr-4 space-x-1">

View File

@@ -1,18 +1,18 @@
import React, { useEffect, useRef, useState, useCallback } from 'react';
import { getApiUrl, getSecretKey } from '../config';
import { ChevronDown, ChevronUp } from './icons';
import {
all_goose_modes,
filterGooseModes,
ModeSelectionItem,
} from './settings/basic/ModeSelectionItem';
import { all_goose_modes, ModeSelectionItem } from './settings_v2/mode/ModeSelectionItem';
import { useConfig } from './ConfigContext';
import { settingsV2Enabled } from '../flags';
import { View, ViewOptions } from '../App';
export const BottomMenuModeSelection = () => {
interface BottomMenuModeSelectionProps {
setView: (view: View, viewOptions?: ViewOptions) => void;
}
export const BottomMenuModeSelection = ({ setView }: BottomMenuModeSelectionProps) => {
const [isGooseModeMenuOpen, setIsGooseModeMenuOpen] = useState(false);
const [gooseMode, setGooseMode] = useState('auto');
const [previousApproveModel, setPreviousApproveModel] = useState('');
const gooseModeDropdownRef = useRef<HTMLDivElement>(null);
const { read, upsert } = useConfig();
@@ -105,20 +105,14 @@ export const BottomMenuModeSelection = () => {
console.error('Store response error:', errorText);
throw new Error(`Failed to store new goose mode: ${newMode}`);
}
if (gooseMode.includes('approve')) {
setPreviousApproveModel(gooseMode);
}
setGooseMode(newMode);
} else {
await upsert('GOOSE_MODE', newMode, false);
if (gooseMode.includes('approve')) {
setPreviousApproveModel(gooseMode);
}
setGooseMode(newMode);
}
};
function getValueByKey(key) {
function getValueByKey(key: string) {
const mode = all_goose_modes.find((mode) => mode.key === key);
return mode ? mode.label : 'auto';
}
@@ -139,15 +133,17 @@ export const BottomMenuModeSelection = () => {
{/* Dropdown Menu */}
{isGooseModeMenuOpen && (
<div className="absolute bottom-[24px] right-0 w-[240px] bg-bgApp rounded-lg border border-borderSubtle">
<div className="absolute bottom-[24px] pl-4 pt-2 right-0 w-[240px] bg-bgApp rounded-lg border border-borderSubtle">
<div>
{filterGooseModes(gooseMode, all_goose_modes, previousApproveModel).map((mode) => (
{all_goose_modes.map((mode) => (
<ModeSelectionItem
key={mode.key}
mode={mode}
currentMode={gooseMode}
showDescription={false}
isApproveModeConfigure={false}
parentView="chat"
setView={setView}
handleModeChange={handleModeChange}
/>
))}

View File

@@ -1,6 +1,6 @@
import { ScrollArea } from '../ui/scroll-area';
import BackButton from '../ui/BackButton';
import type { View } from '../../App';
import type { View, ViewOptions } from '../../App';
import ExtensionsSection from './extensions/ExtensionsSection';
import ModelsSection from './models/ModelsSection';
import { ModeSection } from './mode/ModeSection';
@@ -18,7 +18,7 @@ export default function SettingsView({
viewOptions,
}: {
onClose: () => void;
setView: (view: View) => void;
setView: (view: View, viewOptions?: ViewOptions) => void;
viewOptions: SettingsViewOptions;
}) {
return (

View File

@@ -1,10 +1,10 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { getApiUrl, getSecretKey } from '../../../config';
import { all_goose_modes, ModeSelectionItem } from './ModeSelectionItem';
import { View } from '../../../App';
import { View, ViewOptions } from '../../../App';
interface ModeSectionProps {
setView: (view: View) => void;
setView: (view: View, viewOptions?: ViewOptions) => void;
}
export const ModeSection = ({ setView }: ModeSectionProps) => {
@@ -74,6 +74,7 @@ export const ModeSection = ({ setView }: ModeSectionProps) => {
currentMode={currentMode}
showDescription={true}
isApproveModeConfigure={false}
parentView="settings"
setView={setView}
handleModeChange={handleModeChange}
/>

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { Gear } from '../../icons';
import { ConfigureApproveMode } from './ConfigureApproveMode';
import { View } from '../../../App';
import { View, ViewOptions } from '../../../App';
export interface GooseMode {
key: string;
@@ -32,47 +32,13 @@ export const all_goose_modes: GooseMode[] = [
},
];
export function filterGooseModes(
currentMode: string,
modes: GooseMode[],
previousApproveMode: string
) {
return modes.filter((mode) => {
const approveList = ['approve', 'smart_approve'];
const nonApproveList = ['auto', 'chat'];
// Always keep 'auto' and 'chat'
if (nonApproveList.includes(mode.key)) {
return true;
}
// If current mode is non approve mode, we display write approve by default.
if (nonApproveList.includes(currentMode) && !previousApproveMode) {
return mode.key === 'smart_approve';
}
// Always include the current and previou approve mode
if (mode.key === currentMode) {
return true;
}
// Current mode and previous approve mode cannot exist at the same time.
if (approveList.includes(currentMode) && approveList.includes(previousApproveMode)) {
return false;
}
if (mode.key === previousApproveMode) {
return true;
}
return false;
});
}
interface ModeSelectionItemProps {
currentMode: string;
mode: GooseMode;
showDescription: boolean;
isApproveModeConfigure: boolean;
setView: (view: View) => void;
parentView: View;
setView: (view: View, viewOptions?: ViewOptions) => void;
handleModeChange: (newMode: string) => void;
}
@@ -81,6 +47,7 @@ export function ModeSelectionItem({
mode,
showDescription,
isApproveModeConfigure,
parentView,
setView,
handleModeChange,
}: ModeSelectionItemProps) {
@@ -112,7 +79,9 @@ export function ModeSelectionItem({
{!isApproveModeConfigure && (mode.key == 'approve' || mode.key == 'smart_approve') && (
<button
onClick={() => {
setView('permission');
setView('permission', {
parentView,
});
}}
>
<Gear className="w-5 h-5 text-textSubtle hover:text-textStandard" />

View File

@@ -9,7 +9,6 @@ function RuleItem({ title, description }: { title: string; description: string }
const [isModalOpen, setIsModalOpen] = useState(false);
const handleModalClose = () => {
console.log('close modal');
setIsModalOpen(false);
};