메뉴, dialog 정리

This commit is contained in:
현성필
2025-01-27 10:08:32 +09:00
parent e410aa3e92
commit bb4618a333
5 changed files with 148 additions and 139 deletions
+49 -30
View File
@@ -3,6 +3,7 @@ import {APIProvider, useAPI} from './providers/APIProvider';
import {LoadTestProvider} from './providers/LoadTestProvider'; import {LoadTestProvider} from './providers/LoadTestProvider';
import APITester from './components/APITester'; import APITester from './components/APITester';
import LoadTestManager from './components/LoadTestManager'; import LoadTestManager from './components/LoadTestManager';
import DialogManager from './components/DialogManager';
import {monacoConfig} from '@/config/monaco.js'; import {monacoConfig} from '@/config/monaco.js';
import LoginDialog from '@/components/LoginDialog.jsx'; import LoginDialog from '@/components/LoginDialog.jsx';
import {Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarTrigger} from '@/components/ui/menubar.jsx'; import {Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarTrigger} from '@/components/ui/menubar.jsx';
@@ -88,39 +89,46 @@ const MenuItem = ({item, onMenuClick}) => {
); );
}; };
const handleMenuClick = async (action) => {
// Handle menu item clicks
console.log('Menu action:', action);
switch (action) {
case 'request-add':
setShowAddApi(true);
break;
case 'collection-add':
setShowAddCollection(true);
break;
case 'scenario-add':
setShowAddScenario(true);
break;
case 'variables-show':
setShowVariableModal(true);
break;
case 'logout':
const success = await handleLogout();
if (success) {
window.location.href = "/actionLogout.do";
}
break;
case 'change-password':
// Handle password change
break;
// Add other cases as needed
}
};
const AppContent = ({ options, showLogin, setShowLogin }) => { const AppContent = ({ options, showLogin, setShowLogin }) => {
const { isAuthenticated, setIsAuthenticated } = useAPI(); const { isAuthenticated, setIsAuthenticated, handleLogout } = useAPI();
const [isInitialized, setIsInitialized] = useState(false); const [isInitialized, setIsInitialized] = useState(false);
const [dialogState, setDialogState] = useState({
showAddApi: false,
showAddCollection: false,
showAddScenario: false,
showVariableModal: false
});
const handleMenuClick = async (action) => {
console.log('Menu action:', action);
switch (action) {
case 'request-add':
setDialogState(prev => ({ ...prev, showAddApi: true }));
break;
case 'collection-add':
setDialogState(prev => ({ ...prev, showAddCollection: true }));
break;
case 'scenario-add':
setDialogState(prev => ({ ...prev, showAddScenario: true }));
break;
case 'variables-show':
setDialogState(prev => ({ ...prev, showVariableModal: true }));
break;
case 'logout':
const success = await handleLogout();
if (success) {
window.location.href = "/actionLogout.do";
}
break;
case 'change-password':
// Handle password change
break;
// Add other cases as needed
}
};
const checkAuth = async () => { const checkAuth = async () => {
try { try {
@@ -151,6 +159,10 @@ const AppContent = ({ options, showLogin, setShowLogin }) => {
} }
}, [isInitialized]); }, [isInitialized]);
const handleDialogChange = (dialogName, isOpen) => {
setDialogState(prev => ({ ...prev, [dialogName]: isOpen }));
};
if (!isAuthenticated) { if (!isAuthenticated) {
return <LoginDialog open={showLogin} onOpenChange={setShowLogin} />; return <LoginDialog open={showLogin} onOpenChange={setShowLogin} />;
} }
@@ -187,6 +199,13 @@ const AppContent = ({ options, showLogin, setShowLogin }) => {
</Menubar> </Menubar>
</div> </div>
</div> </div>
<DialogManager
showAddApi={dialogState.showAddApi}
showAddCollection={dialogState.showAddCollection}
showAddScenario={dialogState.showAddScenario}
showVariableModal={dialogState.showVariableModal}
onDialogChange={handleDialogChange}
/>
{options.type === 'api' ? ( {options.type === 'api' ? (
<APITester /> <APITester />
) : ( ) : (
-61
View File
@@ -1,82 +1,21 @@
import React, {useState} from 'react'; import React, {useState} from 'react';
import MainContentArea from '@/components/MainContentArea.jsx'; import MainContentArea from '@/components/MainContentArea.jsx';
import {useAPI} from '@/providers/APIProvider.jsx';
import AddCollectionDialog from '@/components/api-tester/AddCollectionDialog.jsx';
import AddAPIDialog from '@/components/api-tester/AddAPIDialog.jsx';
import AddScenarioDialog from '@/components/api-tester/AddScenarioDialog.jsx';
import {useLoadTest} from '@/providers/LoadTestProvider.jsx';
import VariableModal from '@/components/api-tester/VariableModal.jsx';
const APITester = () => { const APITester = () => {
// API 모드와 시나리오 모드 상태를 관리 // API 모드와 시나리오 모드 상태를 관리
const [isApiMode, setIsApiMode] = useState(true); const [isApiMode, setIsApiMode] = useState(true);
const [showAddCollection, setShowAddCollection] = useState(false);
const [showAddApi, setShowAddApi] = useState(false);
const [showAddScenario, setShowAddScenario] = useState(false);
const [showVariableModal, setShowVariableModal] = useState(false);
const { handleLogout, createCollection, createAPIRequest } = useAPI();
const {createScenario} = useLoadTest();
// 모드 전환 핸들러 // 모드 전환 핸들러
const toggleMode = () => { const toggleMode = () => {
setIsApiMode((prevMode) => !prevMode); setIsApiMode((prevMode) => !prevMode);
}; };
const handleAddCollection = async (name) => {
try {
await createCollection(name);
return true;
} catch (error) {
throw new Error('컬렉션 생성에 실패했습니다');
}
};
const handleAddApi = async (collectionId, apiData) => {
try {
await createAPIRequest(collectionId, apiData);
return true;
} catch (error) {
console.error('Failed to create API:', error);
return false;
}
};
const handleAddScenario = async (name) => {
try {
await createScenario(name);
return true;
} catch (error) {
console.error('시나리오 생성에 실패했습니다.');
}
}
return ( return (
<div className="flex flex-col h-screen"> <div className="flex flex-col h-screen">
{/* Main content area with top padding for menubar */} {/* Main content area with top padding for menubar */}
<div className="flex-1 pt-14"> <div className="flex-1 pt-14">
<MainContentArea isApiMode={isApiMode} toggleMode={toggleMode}/> <MainContentArea isApiMode={isApiMode} toggleMode={toggleMode}/>
</div> </div>
<AddCollectionDialog
open={showAddCollection}
onOpenChange={setShowAddCollection}
onSubmit={handleAddCollection}
/>
{/* Add these at the bottom of your return statement */}
<AddAPIDialog
open={showAddApi}
onOpenChange={setShowAddApi}
onSubmit={handleAddApi}
/>
<AddScenarioDialog
open={showAddScenario}
onOpenChange={setShowAddScenario}
onSubmit={handleAddScenario}
/>
<VariableModal
open={showVariableModal}
onOpenChange={setShowVariableModal}
/>
</div> </div>
); );
}; };
@@ -0,0 +1,72 @@
import AddAPIDialog from '@/components/api-tester/AddAPIDialog.jsx';
import React from 'react';
import AddCollectionDialog from '@/components/api-tester/AddCollectionDialog.jsx';
import AddScenarioDialog from '@/components/api-tester/AddScenarioDialog.jsx';
import VariableModal from '@/components/api-tester/VariableModal.jsx';
import {useLoadTest} from '@/providers/LoadTestProvider.jsx';
import {useAPI} from '@/providers/APIProvider.jsx';
const DialogManager = ({
showAddApi,
showAddCollection,
showAddScenario,
showVariableModal,
onDialogChange
}) => {
const {createCollection, createAPIRequest} = useAPI();
const {createScenario} = useLoadTest();
const handleAddCollection = async (name) => {
try {
await createCollection(name);
return true;
} catch (error) {
throw new Error('컬렉션 생성에 실패했습니다');
}
};
const handleAddApi = async (collectionId, apiData) => {
try {
await createAPIRequest(collectionId, apiData);
return true;
} catch (error) {
console.error('Failed to create API:', error);
return false;
}
};
const handleAddScenario = async (name) => {
try {
await createScenario(name);
return true;
} catch (error) {
console.error('시나리오 생성에 실패했습니다.');
}
}
return <>
<AddCollectionDialog
open={showAddCollection}
onOpenChange={(isOpen) => onDialogChange('showAddCollection', isOpen)}
onSubmit={handleAddCollection}
/>
{/* Add these at the bottom of your return statement */}
<AddAPIDialog
open={showAddApi}
onOpenChange={(isOpen) => onDialogChange('showAddApi', isOpen)}
onSubmit={handleAddApi}
/>
<AddScenarioDialog
open={showAddScenario}
onOpenChange={(isOpen) => onDialogChange('showAddScenario', isOpen)}
onSubmit={handleAddScenario}
/>
<VariableModal
open={showVariableModal}
onOpenChange={(isOpen) => onDialogChange('showVariableModal', isOpen)}
/>
</>;
}
export default DialogManager;
@@ -32,7 +32,6 @@ const APINavigation = ({
const [apiToRename, setApiToRename] = useState(null); const [apiToRename, setApiToRename] = useState(null);
const [renameApiDialogOpen, setRenameApiDialogOpen] = useState(false); const [renameApiDialogOpen, setRenameApiDialogOpen] = useState(false);
// API Context // API Context
const { const {
collections, collections,
@@ -61,16 +60,18 @@ const APINavigation = ({
const handleApiAction = { const handleApiAction = {
open: (collectionId, apiId) => { open: (collectionId, apiId) => {
if (onApiSelect) onApiSelect(collectionId, apiId); if (onApiSelect) {
onApiSelect(collectionId, apiId);
}
}, },
delete: async (collectionId, apiId) => { delete: async (collectionId, apiId) => {
setApiToDelete({ collectionId, apiId }); setApiToDelete({collectionId, apiId});
}, },
rename: (collectionId, apiId) => { rename: (collectionId, apiId) => {
const collection = collections.find(c => c.id === collectionId); const collection = collections.find(c => c.id === collectionId);
const api = collection?.apis?.find(a => a.id === apiId); const api = collection?.apis?.find(a => a.id === apiId);
if (api) { if (api) {
setApiToRename({ ...api, collectionId }); setApiToRename({...api, collectionId});
setRenameApiDialogOpen(true); setRenameApiDialogOpen(true);
} }
} }
@@ -250,22 +251,19 @@ const APINavigation = ({
}; };
return ( return (
<> <Sidebar side={side} className="py-16">
<Sidebar side={side} className="py-16"> {side === 'left' && (
{side === 'left' && ( <SidebarHeader>
<SidebarHeader> <Button
<Button variant="outline"
variant="outline" className="w-full"
className="w-full" onClick={onToggleMode}
onClick={onToggleMode} >
> {isApiMode ? 'Switch to Scenario Mode' : 'Switch to API Mode'}
{isApiMode ? 'Switch to Scenario Mode' : 'Switch to API Mode'} </Button>
</Button> </SidebarHeader>
</SidebarHeader> )}
)} {renderContent()}
{renderContent()}
</Sidebar>
<DeleteCollectionDialog <DeleteCollectionDialog
open={deleteDialogOpen} open={deleteDialogOpen}
onOpenChange={setDeleteDialogOpen} onOpenChange={setDeleteDialogOpen}
@@ -279,8 +277,6 @@ const APINavigation = ({
onSubmit={handleRenameConfirm} onSubmit={handleRenameConfirm}
collection={collectionToRename} collection={collectionToRename}
/> />
<DeleteAPIDialog <DeleteAPIDialog
open={!!apiToDelete} open={!!apiToDelete}
onOpenChange={(open) => !open && setApiToDelete(null)} onOpenChange={(open) => !open && setApiToDelete(null)}
@@ -293,14 +289,13 @@ const APINavigation = ({
onSubmit={handleAddApi} onSubmit={handleAddApi}
selectedCollection={collections.find(c => c.id === selectedCollection)} selectedCollection={collections.find(c => c.id === selectedCollection)}
/> />
<RenameAPIDialog <RenameAPIDialog
open={renameApiDialogOpen} open={renameApiDialogOpen}
onOpenChange={setRenameApiDialogOpen} onOpenChange={setRenameApiDialogOpen}
onSubmit={handleRenameApi} onSubmit={handleRenameApi}
api={apiToRename} api={apiToRename}
/> />
</> </Sidebar>
); );
}; };
@@ -1,28 +1,12 @@
import React, {useEffect, useState} from 'react'; import React, {useEffect, useState} from 'react';
import { FileText, MoreHorizontal } from 'lucide-react'; import {FileText, MoreHorizontal} from 'lucide-react';
import { import {Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem} from '@/components/ui/sidebar';
Sidebar, import {ScrollArea} from '@/components/ui/scroll-area';
SidebarContent, import {Alert, AlertDescription} from '@/components/ui/alert';
SidebarGroup, import {DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger} from '@/components/ui/dropdown-menu';
SidebarGroupLabel, import {Tooltip, TooltipContent, TooltipTrigger} from '@/components/ui/tooltip';
SidebarMenu, import {Button} from '@/components/ui/button';
SidebarMenuItem, import {useLoadTest} from '@/providers/LoadTestProvider';
SidebarMenuButton,
SidebarMenuAction, SidebarHeader,
} from '@/components/ui/sidebar';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Alert, AlertDescription } from '@/components/ui/alert';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from '@/components/ui/dropdown-menu';
import { Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip';
import { Button } from '@/components/ui/button';
import { useLoadTest } from '@/providers/LoadTestProvider';
import { SidebarProvider } from '@/components/ui/sidebar';
import DeleteScenarioDialog from '@/components/api-tester/DeleteScenarioDialog.jsx'; import DeleteScenarioDialog from '@/components/api-tester/DeleteScenarioDialog.jsx';
const ScenarioDropdownMenu = ({ onOpen, onRename, onDelete }) => ( const ScenarioDropdownMenu = ({ onOpen, onRename, onDelete }) => (