feat: use the permission page in bottom menu (#2218)
This commit is contained in:
@@ -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>
|
||||||
</div>
|
</div>
|
||||||
{isGoosehintsModalOpen && (
|
{isGoosehintsModalOpen && (
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useModel } from './settings/models/ModelContext';
|
|||||||
import { Sliders } from 'lucide-react';
|
import { Sliders } from 'lucide-react';
|
||||||
import { ModelRadioList } from './settings/models/ModelRadioList';
|
import { ModelRadioList } from './settings/models/ModelRadioList';
|
||||||
import { Document, ChevronUp, ChevronDown } from './icons';
|
import { Document, ChevronUp, ChevronDown } from './icons';
|
||||||
import type { View } from '../App';
|
import type { View, ViewOptions } from '../App';
|
||||||
import { settingsV2Enabled } from '../flags';
|
import { settingsV2Enabled } from '../flags';
|
||||||
import { BottomMenuModeSelection } from './BottomMenuModeSelection';
|
import { BottomMenuModeSelection } from './BottomMenuModeSelection';
|
||||||
import ModelsBottomBar from './settings_v2/models/bottom_bar/ModelsBottomBar';
|
import ModelsBottomBar from './settings_v2/models/bottom_bar/ModelsBottomBar';
|
||||||
@@ -13,7 +13,7 @@ export default function BottomMenu({
|
|||||||
setView,
|
setView,
|
||||||
}: {
|
}: {
|
||||||
hasMessages: boolean;
|
hasMessages: boolean;
|
||||||
setView: (view: View) => void;
|
setView: (view: View, viewOptions?: ViewOptions) => void;
|
||||||
}) {
|
}) {
|
||||||
const [isModelMenuOpen, setIsModelMenuOpen] = useState(false);
|
const [isModelMenuOpen, setIsModelMenuOpen] = useState(false);
|
||||||
const { currentModel } = useModel();
|
const { currentModel } = useModel();
|
||||||
@@ -74,7 +74,7 @@ export default function BottomMenu({
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
{/* Goose Mode Selector Dropdown */}
|
{/* Goose Mode Selector Dropdown */}
|
||||||
<BottomMenuModeSelection />
|
<BottomMenuModeSelection setView={setView} />
|
||||||
|
|
||||||
{/* Right-side section with ToolCount and Model Selector together */}
|
{/* Right-side section with ToolCount and Model Selector together */}
|
||||||
<div className="flex items-center mr-4 space-x-1">
|
<div className="flex items-center mr-4 space-x-1">
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
||||||
import { getApiUrl, getSecretKey } from '../config';
|
import { getApiUrl, getSecretKey } from '../config';
|
||||||
import { ChevronDown, ChevronUp } from './icons';
|
import { ChevronDown, ChevronUp } from './icons';
|
||||||
import {
|
import { all_goose_modes, ModeSelectionItem } from './settings_v2/mode/ModeSelectionItem';
|
||||||
all_goose_modes,
|
|
||||||
filterGooseModes,
|
|
||||||
ModeSelectionItem,
|
|
||||||
} from './settings/basic/ModeSelectionItem';
|
|
||||||
import { useConfig } from './ConfigContext';
|
import { useConfig } from './ConfigContext';
|
||||||
import { settingsV2Enabled } from '../flags';
|
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 [isGooseModeMenuOpen, setIsGooseModeMenuOpen] = useState(false);
|
||||||
const [gooseMode, setGooseMode] = useState('auto');
|
const [gooseMode, setGooseMode] = useState('auto');
|
||||||
const [previousApproveModel, setPreviousApproveModel] = useState('');
|
|
||||||
const gooseModeDropdownRef = useRef<HTMLDivElement>(null);
|
const gooseModeDropdownRef = useRef<HTMLDivElement>(null);
|
||||||
const { read, upsert } = useConfig();
|
const { read, upsert } = useConfig();
|
||||||
|
|
||||||
@@ -105,20 +105,14 @@ export const BottomMenuModeSelection = () => {
|
|||||||
console.error('Store response error:', errorText);
|
console.error('Store response error:', errorText);
|
||||||
throw new Error(`Failed to store new goose mode: ${newMode}`);
|
throw new Error(`Failed to store new goose mode: ${newMode}`);
|
||||||
}
|
}
|
||||||
if (gooseMode.includes('approve')) {
|
|
||||||
setPreviousApproveModel(gooseMode);
|
|
||||||
}
|
|
||||||
setGooseMode(newMode);
|
setGooseMode(newMode);
|
||||||
} else {
|
} else {
|
||||||
await upsert('GOOSE_MODE', newMode, false);
|
await upsert('GOOSE_MODE', newMode, false);
|
||||||
if (gooseMode.includes('approve')) {
|
|
||||||
setPreviousApproveModel(gooseMode);
|
|
||||||
}
|
|
||||||
setGooseMode(newMode);
|
setGooseMode(newMode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function getValueByKey(key) {
|
function getValueByKey(key: string) {
|
||||||
const mode = all_goose_modes.find((mode) => mode.key === key);
|
const mode = all_goose_modes.find((mode) => mode.key === key);
|
||||||
return mode ? mode.label : 'auto';
|
return mode ? mode.label : 'auto';
|
||||||
}
|
}
|
||||||
@@ -139,15 +133,17 @@ export const BottomMenuModeSelection = () => {
|
|||||||
|
|
||||||
{/* Dropdown Menu */}
|
{/* Dropdown Menu */}
|
||||||
{isGooseModeMenuOpen && (
|
{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>
|
<div>
|
||||||
{filterGooseModes(gooseMode, all_goose_modes, previousApproveModel).map((mode) => (
|
{all_goose_modes.map((mode) => (
|
||||||
<ModeSelectionItem
|
<ModeSelectionItem
|
||||||
key={mode.key}
|
key={mode.key}
|
||||||
mode={mode}
|
mode={mode}
|
||||||
currentMode={gooseMode}
|
currentMode={gooseMode}
|
||||||
showDescription={false}
|
showDescription={false}
|
||||||
isApproveModeConfigure={false}
|
isApproveModeConfigure={false}
|
||||||
|
parentView="chat"
|
||||||
|
setView={setView}
|
||||||
handleModeChange={handleModeChange}
|
handleModeChange={handleModeChange}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ScrollArea } from '../ui/scroll-area';
|
import { ScrollArea } from '../ui/scroll-area';
|
||||||
import BackButton from '../ui/BackButton';
|
import BackButton from '../ui/BackButton';
|
||||||
import type { View } from '../../App';
|
import type { View, ViewOptions } from '../../App';
|
||||||
import ExtensionsSection from './extensions/ExtensionsSection';
|
import ExtensionsSection from './extensions/ExtensionsSection';
|
||||||
import ModelsSection from './models/ModelsSection';
|
import ModelsSection from './models/ModelsSection';
|
||||||
import { ModeSection } from './mode/ModeSection';
|
import { ModeSection } from './mode/ModeSection';
|
||||||
@@ -18,7 +18,7 @@ export default function SettingsView({
|
|||||||
viewOptions,
|
viewOptions,
|
||||||
}: {
|
}: {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
setView: (view: View) => void;
|
setView: (view: View, viewOptions?: ViewOptions) => void;
|
||||||
viewOptions: SettingsViewOptions;
|
viewOptions: SettingsViewOptions;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { getApiUrl, getSecretKey } from '../../../config';
|
import { getApiUrl, getSecretKey } from '../../../config';
|
||||||
import { all_goose_modes, ModeSelectionItem } from './ModeSelectionItem';
|
import { all_goose_modes, ModeSelectionItem } from './ModeSelectionItem';
|
||||||
import { View } from '../../../App';
|
import { View, ViewOptions } from '../../../App';
|
||||||
|
|
||||||
interface ModeSectionProps {
|
interface ModeSectionProps {
|
||||||
setView: (view: View) => void;
|
setView: (view: View, viewOptions?: ViewOptions) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ModeSection = ({ setView }: ModeSectionProps) => {
|
export const ModeSection = ({ setView }: ModeSectionProps) => {
|
||||||
@@ -74,6 +74,7 @@ export const ModeSection = ({ setView }: ModeSectionProps) => {
|
|||||||
currentMode={currentMode}
|
currentMode={currentMode}
|
||||||
showDescription={true}
|
showDescription={true}
|
||||||
isApproveModeConfigure={false}
|
isApproveModeConfigure={false}
|
||||||
|
parentView="settings"
|
||||||
setView={setView}
|
setView={setView}
|
||||||
handleModeChange={handleModeChange}
|
handleModeChange={handleModeChange}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Gear } from '../../icons';
|
import { Gear } from '../../icons';
|
||||||
import { ConfigureApproveMode } from './ConfigureApproveMode';
|
import { ConfigureApproveMode } from './ConfigureApproveMode';
|
||||||
import { View } from '../../../App';
|
import { View, ViewOptions } from '../../../App';
|
||||||
|
|
||||||
export interface GooseMode {
|
export interface GooseMode {
|
||||||
key: string;
|
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 {
|
interface ModeSelectionItemProps {
|
||||||
currentMode: string;
|
currentMode: string;
|
||||||
mode: GooseMode;
|
mode: GooseMode;
|
||||||
showDescription: boolean;
|
showDescription: boolean;
|
||||||
isApproveModeConfigure: boolean;
|
isApproveModeConfigure: boolean;
|
||||||
setView: (view: View) => void;
|
parentView: View;
|
||||||
|
setView: (view: View, viewOptions?: ViewOptions) => void;
|
||||||
handleModeChange: (newMode: string) => void;
|
handleModeChange: (newMode: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,6 +47,7 @@ export function ModeSelectionItem({
|
|||||||
mode,
|
mode,
|
||||||
showDescription,
|
showDescription,
|
||||||
isApproveModeConfigure,
|
isApproveModeConfigure,
|
||||||
|
parentView,
|
||||||
setView,
|
setView,
|
||||||
handleModeChange,
|
handleModeChange,
|
||||||
}: ModeSelectionItemProps) {
|
}: ModeSelectionItemProps) {
|
||||||
@@ -112,7 +79,9 @@ export function ModeSelectionItem({
|
|||||||
{!isApproveModeConfigure && (mode.key == 'approve' || mode.key == 'smart_approve') && (
|
{!isApproveModeConfigure && (mode.key == 'approve' || mode.key == 'smart_approve') && (
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setView('permission');
|
setView('permission', {
|
||||||
|
parentView,
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Gear className="w-5 h-5 text-textSubtle hover:text-textStandard" />
|
<Gear className="w-5 h-5 text-textSubtle hover:text-textStandard" />
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ function RuleItem({ title, description }: { title: string; description: string }
|
|||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
|
||||||
const handleModalClose = () => {
|
const handleModalClose = () => {
|
||||||
console.log('close modal');
|
|
||||||
setIsModalOpen(false);
|
setIsModalOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user