menubar 위치 이동
This commit is contained in:
@@ -5,6 +5,7 @@ import APITester from './components/APITester';
|
||||
import LoadTestManager from './components/LoadTestManager';
|
||||
import {monacoConfig} from '@/config/monaco.js';
|
||||
import LoginDialog from '@/components/LoginDialog.jsx';
|
||||
import {Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarTrigger} from '@/components/ui/menubar.jsx';
|
||||
|
||||
window.MonacoEnvironment = monacoConfig;
|
||||
|
||||
@@ -18,6 +19,104 @@ const App = ({ options = { type: 'api', contextPath: '/' } }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const menuConfig = [
|
||||
{
|
||||
id: 'response',
|
||||
label: '응답관리',
|
||||
items: [
|
||||
{id: 'response-list', label: '응답목록', action: 'response-list'},
|
||||
{id: 'response-add', label: '응답추가', action: 'response-add'}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'request',
|
||||
label: '요청관리',
|
||||
items: [
|
||||
{id: 'collection-add', label: '컬렉션 추가', action: 'collection-add'},
|
||||
{id: 'request-add', label: '요청 추가', action: 'request-add'},
|
||||
{id: 'scenario-add', label: '시나리오 추가', action: 'scenario-add'},
|
||||
{id: 'variables-show', label: '변수 보기', action: 'variables-show'},
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'queue',
|
||||
label: '큐관리',
|
||||
items: [
|
||||
{id: 'queue-status', label: '큐상태', action: 'queue-status'},
|
||||
{id: 'queue-settings', label: '큐설정', action: 'queue-settings'}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'loadtest',
|
||||
label: '부하테스트',
|
||||
items: [
|
||||
{id: 'load-test-new', label: '새 테스트', action: 'load-test-new'},
|
||||
{id: 'load-test-history', label: '테스트 이력', action: 'load-test-history'},
|
||||
{id: 'load-test-reports', label: '결과 리포트', action: 'load-test-reports'}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'system',
|
||||
label: '시스템관리',
|
||||
items: [
|
||||
{id: 'system-settings', label: '시스템설정', action: 'system-settings'},
|
||||
{id: 'user-management', label: '사용자관리', action: 'user-management'},
|
||||
{type: 'separator'},
|
||||
{id: 'system-logs', label: '시스템로그', action: 'system-logs'}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'account',
|
||||
label: '계정',
|
||||
items: [
|
||||
{id: 'change-password', label: '비밀번호변경', action: 'change-password'},
|
||||
{type: 'separator'},
|
||||
{id: 'logout', label: '로그아웃', action: 'logout'}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const MenuItem = ({item, onMenuClick}) => {
|
||||
if (item.type === 'separator') {
|
||||
return <MenubarSeparator/>;
|
||||
}
|
||||
|
||||
return (
|
||||
<MenubarItem onClick={() => onMenuClick(item.action)}>
|
||||
{item.label}
|
||||
</MenubarItem>
|
||||
);
|
||||
};
|
||||
|
||||
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 { isAuthenticated, setIsAuthenticated } = useAPI();
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
@@ -59,6 +158,35 @@ const AppContent = ({ options, showLogin, setShowLogin }) => {
|
||||
return (
|
||||
<LoadTestProvider contextPath={options.contextPath}>
|
||||
<div className="flex flex-col h-screen bg-background">
|
||||
<div className="fixed top-0 left-0 right-0 z-50 bg-background border-b">
|
||||
<div className="flex items-center h-14">
|
||||
<div className="px-4 py-2 border-r h-full flex items-center">
|
||||
<img
|
||||
src="/img/logo.png"
|
||||
alt="testmaster"
|
||||
className="h-8 w-auto"
|
||||
/>
|
||||
</div>
|
||||
<Menubar className="border-none flex-1">
|
||||
{menuConfig.map((menu) => (
|
||||
<MenubarMenu key={menu.id}>
|
||||
<MenubarTrigger className="font-bold">
|
||||
{menu.label}
|
||||
</MenubarTrigger>
|
||||
<MenubarContent>
|
||||
{menu.items.map((item, index) => (
|
||||
<MenuItem
|
||||
key={item.id || `separator-${index}`}
|
||||
item={item}
|
||||
onMenuClick={handleMenuClick}
|
||||
/>
|
||||
))}
|
||||
</MenubarContent>
|
||||
</MenubarMenu>
|
||||
))}
|
||||
</Menubar>
|
||||
</div>
|
||||
</div>
|
||||
{options.type === 'api' ? (
|
||||
<APITester />
|
||||
) : (
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, {useState} from 'react';
|
||||
import {Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarTrigger} from '@/components/ui/menubar';
|
||||
import MainContentArea from '@/components/MainContentArea.jsx';
|
||||
import {useAPI} from '@/providers/APIProvider.jsx';
|
||||
import AddCollectionDialog from '@/components/api-tester/AddCollectionDialog.jsx';
|
||||
@@ -8,75 +7,6 @@ import AddScenarioDialog from '@/components/api-tester/AddScenarioDialog.jsx';
|
||||
import {useLoadTest} from '@/providers/LoadTestProvider.jsx';
|
||||
import VariableModal from '@/components/api-tester/VariableModal.jsx';
|
||||
|
||||
const menuConfig = [
|
||||
{
|
||||
id: 'response',
|
||||
label: '응답관리',
|
||||
items: [
|
||||
{id: 'response-list', label: '응답목록', action: 'response-list'},
|
||||
{id: 'response-add', label: '응답추가', action: 'response-add'}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'request',
|
||||
label: '요청관리',
|
||||
items: [
|
||||
{id: 'collection-add', label: '컬렉션 추가', action: 'collection-add'},
|
||||
{id: 'request-add', label: '요청 추가', action: 'request-add'},
|
||||
{id: 'scenario-add', label: '시나리오 추가', action: 'scenario-add'},
|
||||
{id: 'variables-show', label: '변수 보기', action: 'variables-show'},
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'queue',
|
||||
label: '큐관리',
|
||||
items: [
|
||||
{id: 'queue-status', label: '큐상태', action: 'queue-status'},
|
||||
{id: 'queue-settings', label: '큐설정', action: 'queue-settings'}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'loadtest',
|
||||
label: '부하테스트',
|
||||
items: [
|
||||
{id: 'load-test-new', label: '새 테스트', action: 'load-test-new'},
|
||||
{id: 'load-test-history', label: '테스트 이력', action: 'load-test-history'},
|
||||
{id: 'load-test-reports', label: '결과 리포트', action: 'load-test-reports'}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'system',
|
||||
label: '시스템관리',
|
||||
items: [
|
||||
{id: 'system-settings', label: '시스템설정', action: 'system-settings'},
|
||||
{id: 'user-management', label: '사용자관리', action: 'user-management'},
|
||||
{type: 'separator'},
|
||||
{id: 'system-logs', label: '시스템로그', action: 'system-logs'}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'account',
|
||||
label: '계정',
|
||||
items: [
|
||||
{id: 'change-password', label: '비밀번호변경', action: 'change-password'},
|
||||
{type: 'separator'},
|
||||
{id: 'logout', label: '로그아웃', action: 'logout'}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const MenuItem = ({item, onMenuClick}) => {
|
||||
if (item.type === 'separator') {
|
||||
return <MenubarSeparator/>;
|
||||
}
|
||||
|
||||
return (
|
||||
<MenubarItem onClick={() => onMenuClick(item.action)}>
|
||||
{item.label}
|
||||
</MenubarItem>
|
||||
);
|
||||
};
|
||||
|
||||
const APITester = () => {
|
||||
// API 모드와 시나리오 모드 상태를 관리
|
||||
const [isApiMode, setIsApiMode] = useState(true);
|
||||
@@ -120,68 +50,8 @@ const APITester = () => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-screen">
|
||||
{/* Fixed Menubar */}
|
||||
<div className="fixed top-0 left-0 right-0 z-50 bg-background border-b">
|
||||
<div className="flex items-center h-14">
|
||||
<div className="px-4 py-2 border-r h-full flex items-center">
|
||||
<img
|
||||
src="/img/logo.png"
|
||||
alt="testmaster"
|
||||
className="h-8 w-auto"
|
||||
/>
|
||||
</div>
|
||||
<Menubar className="border-none flex-1">
|
||||
{menuConfig.map((menu) => (
|
||||
<MenubarMenu key={menu.id}>
|
||||
<MenubarTrigger className="font-bold">
|
||||
{menu.label}
|
||||
</MenubarTrigger>
|
||||
<MenubarContent>
|
||||
{menu.items.map((item, index) => (
|
||||
<MenuItem
|
||||
key={item.id || `separator-${index}`}
|
||||
item={item}
|
||||
onMenuClick={handleMenuClick}
|
||||
/>
|
||||
))}
|
||||
</MenubarContent>
|
||||
</MenubarMenu>
|
||||
))}
|
||||
</Menubar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main content area with top padding for menubar */}
|
||||
<div className="flex-1 pt-14">
|
||||
|
||||
@@ -19,11 +19,10 @@ const MainContentArea = ({isApiMode, toggleMode}) => {
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||
}, [toggleMode]);
|
||||
|
||||
|
||||
return (
|
||||
<div className="h-[calc(100vh-57px)] w-full overflow-hidden">
|
||||
{isApiMode ? (
|
||||
@@ -107,7 +106,7 @@ const APIMode = ({
|
||||
collectionName: collection.name,
|
||||
server: api.server || null,
|
||||
description: api.description || '',
|
||||
layout: api.layout || {},
|
||||
layout: api.layout || {}
|
||||
};
|
||||
|
||||
const existingIndex = apiRequests.findIndex(
|
||||
@@ -132,35 +131,35 @@ const APIMode = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<SidebarProvider cookieName="sidebar-right:state" shortcut="/">
|
||||
<div className="api-mode flex flex-1 h-[calc(100vh-57px)]">
|
||||
<div className="navigation-sidebar min-w-[0px] border-r bg-gray-100">
|
||||
<APINavigation
|
||||
contextPath="/"
|
||||
collections={collections} // Pass collections to APINavigation
|
||||
side="left"
|
||||
onApiSelect={handleOpenApi}
|
||||
onNewCollection={() => {
|
||||
// Handle new collection creation
|
||||
}}
|
||||
isApiMode={isApiMode}
|
||||
onToggleMode={onToggleMode}
|
||||
/>
|
||||
<SidebarProvider cookieName="sidebar-right:state" shortcut="/">
|
||||
<div className="api-mode flex flex-1 h-[calc(100vh-57px)]">
|
||||
<div className="navigation-sidebar min-w-[0px] border-r bg-gray-100">
|
||||
<APINavigation
|
||||
contextPath="/"
|
||||
collections={collections} // Pass collections to APINavigation
|
||||
side="left"
|
||||
onApiSelect={handleOpenApi}
|
||||
onNewCollection={() => {
|
||||
// Handle new collection creation
|
||||
}}
|
||||
isApiMode={isApiMode}
|
||||
onToggleMode={onToggleMode}
|
||||
/>
|
||||
</div>
|
||||
<div className="editor flex-1 h-[calc(100vh-57px)] overflow-hidden">
|
||||
{apiRequests.length === 0 ? (
|
||||
renderFallback() // Render fallback when no tabs exist
|
||||
) : (
|
||||
<APITabs
|
||||
apiRequests={apiRequests}
|
||||
currentIndex={currentIndex}
|
||||
onTabChange={handleTabChange}
|
||||
onCloseTab={handleCloseTab}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="editor flex-1 h-[calc(100vh-57px)] overflow-hidden">
|
||||
{apiRequests.length === 0 ? (
|
||||
renderFallback() // Render fallback when no tabs exist
|
||||
) : (
|
||||
<APITabs
|
||||
apiRequests={apiRequests}
|
||||
currentIndex={currentIndex}
|
||||
onTabChange={handleTabChange}
|
||||
onCloseTab={handleCloseTab}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
</SidebarProvider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user