메뉴, dialog 정리
This commit is contained in:
+49
-30
@@ -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 />
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -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 }) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user