API 클라이언트 수정

This commit is contained in:
현성필
2025-01-25 11:10:57 +09:00
parent 985a2c3039
commit 54c5633654
3 changed files with 156 additions and 145 deletions
@@ -154,6 +154,7 @@ const ScenarioMode = ({
onToggleMode, onToggleMode,
}) => { }) => {
let handleApiSelect = () => {};
return ( return (
<div className="scenario-mode flex flex-1 h-[calc(100vh-57px)]"> <div className="scenario-mode flex flex-1 h-[calc(100vh-57px)]">
<div className="navigation-sidebar min-w-[200px] border-r bg-gray-100"> <div className="navigation-sidebar min-w-[200px] border-r bg-gray-100">
@@ -29,14 +29,14 @@ const ScenarioMenuBar = ({ onSave, onStepRun, onFullRun, onPause, onReset }) =>
<Play className="h-4 w-4 mr-2" /> <Play className="h-4 w-4 mr-2" />
전체 실행 전체 실행
</Button> </Button>
<Button {/*<Button*/}
variant="outline" {/* variant="outline"*/}
size="sm" {/* size="sm"*/}
onClick={onPause} {/* onClick={onPause}*/}
> {/*>*/}
<Pause className="h-4 w-4 mr-2" /> {/* <Pause className="h-4 w-4 mr-2" />*/}
일시 정지 {/* 일시 정지*/}
</Button> {/*</Button>*/}
<Button <Button
variant="outline" variant="outline"
size="sm" size="sm"
@@ -2,7 +2,7 @@ import React, {useState} from 'react';
import {Button} from '@/components/ui/button'; import {Button} from '@/components/ui/button';
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from '@/components/ui/select'; import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from '@/components/ui/select';
import {Input} from '@/components/ui/input'; import {Input} from '@/components/ui/input';
import {Tabs, TabsList, TabsTrigger} from '@/components/ui/tabs'; import {Tabs, TabsContent, TabsList, TabsTrigger} from '@/components/ui/tabs';
import {Label} from '@/components/ui/label'; import {Label} from '@/components/ui/label';
import EditableInput from '../shared/EditableInput'; import EditableInput from '../shared/EditableInput';
import PropertyTable from '../shared/PropertyTable'; import PropertyTable from '../shared/PropertyTable';
@@ -18,7 +18,7 @@ const HTTP_METHODS = [
]; ];
export const HTTPClientView = ({model, index}) => { export const HTTPClientView = ({model, index}) => {
const { getServer } = useAPI(); const {getServer} = useAPI();
const [currentModel, setCurrentModel] = useState(model); const [currentModel, setCurrentModel] = useState(model);
const [basePath, setBasePath] = useState(''); const [basePath, setBasePath] = useState('');
const [currentTab, setCurrentTab] = useState('body'); const [currentTab, setCurrentTab] = useState('body');
@@ -121,9 +121,9 @@ export const HTTPClientView = ({model, index}) => {
); );
return ( return (
<div className="flex flex-col h-full p-4 space-y-4"> <div className="flex flex-col h-full p-4 gap-4">
{/* Request Header Section */} {/* Request Header Section */}
<div className="flex items-center space-x-2"> <div className="flex items-center gap-2">
<div> <div>
<span>{currentModel.collectionName}</span> <span>{currentModel.collectionName}</span>
{' > '} {' > '}
@@ -132,7 +132,7 @@ export const HTTPClientView = ({model, index}) => {
</div> </div>
{/* Request Controls */} {/* Request Controls */}
<div className="flex items-center space-x-2"> <div className="flex items-center gap-2">
<Select <Select
value={currentModel.method} value={currentModel.method}
onValueChange={(value) => setCurrentModel(prev => ({...prev, method: value}))} onValueChange={(value) => setCurrentModel(prev => ({...prev, method: value}))}
@@ -166,8 +166,11 @@ export const HTTPClientView = ({model, index}) => {
<Button variant="secondary">Save</Button> <Button variant="secondary">Save</Button>
</div> </div>
{/* Request/Response Tabs */} {/* Request/Response Container */}
<Tabs value={currentTab} onValueChange={setCurrentTab}> <div className="flex flex-col gap-4 flex-1 min-h-0">
{/* Request Section */}
<div className="flex-1 min-h-0">
<Tabs value={currentTab} onValueChange={setCurrentTab} className="flex flex-col h-full">
<TabsList> <TabsList>
<TabsTrigger value="body">Body</TabsTrigger> <TabsTrigger value="body">Body</TabsTrigger>
<TabsTrigger value="params">Params</TabsTrigger> <TabsTrigger value="params">Params</TabsTrigger>
@@ -176,9 +179,10 @@ export const HTTPClientView = ({model, index}) => {
<TabsTrigger value="post-request">Post-Request</TabsTrigger> <TabsTrigger value="post-request">Post-Request</TabsTrigger>
</TabsList> </TabsList>
<div className="mt-2"> <div className="flex-1 min-h-0 mt-2">
{/* Body Tab Content */} {/* Body Tab Content */}
<div style={{ display: currentTab === 'body' ? 'block' : 'none' }}> <TabsContent value="body" className="h-full m-0">
<div className="flex flex-col h-full gap-2">
<Select <Select
value={currentModel.contentType} value={currentModel.contentType}
// onValueChange={(value) => setCurrentModel(prev => ({ ...prev, contentType: value }))} // onValueChange={(value) => setCurrentModel(prev => ({ ...prev, contentType: value }))}
@@ -195,7 +199,7 @@ export const HTTPClientView = ({model, index}) => {
}} }}
> >
<SelectTrigger> <SelectTrigger>
<SelectValue placeholder="Content Type" /> <SelectValue placeholder="Content Type"/>
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="json">JSON</SelectItem> <SelectItem value="json">JSON</SelectItem>
@@ -203,6 +207,7 @@ export const HTTPClientView = ({model, index}) => {
<SelectItem value="plaintext">Text/Plain</SelectItem> <SelectItem value="plaintext">Text/Plain</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
<div className="h-full">
<MonacoEditor <MonacoEditor
id={`request-body-${model.id}`} id={`request-body-${model.id}`}
value={currentModel.requestBody} value={currentModel.requestBody}
@@ -215,99 +220,104 @@ export const HTTPClientView = ({model, index}) => {
requestBody: newValue requestBody: newValue
})); }));
}} }}
height="64" height="full"
/> />
</div> </div>
</div>
</TabsContent>
{/* Params Tab Content */} <TabsContent value="params" className="h-full m-0">
<div style={{ display: currentTab === 'params' ? 'block' : 'none' }}>
<PropertyTable <PropertyTable
properties={currentModel.queryParams} properties={currentModel.queryParams}
onChange={handlePathChange} onChange={handlePathChange}
/> />
</div> </TabsContent>
{/* Headers Tab Content */} {/* Headers Tab Content */}
<div style={{ display: currentTab === 'headers' ? 'block' : 'none' }}> <TabsContent value="headers" className="h-full m-0">
<PropertyTable <PropertyTable
properties={currentModel.headers} properties={currentModel.headers}
onChange={handleHeadersChange} onChange={handleHeadersChange}
/> />
</div> </TabsContent>
<TabsContent value="pre-request" className="h-full m-0">
{/* Pre-Request Tab Content */}
<div style={{ display: currentTab === 'pre-request' ? 'block' : 'none' }} className="flex">
<div className="flex-1">
<MonacoEditor <MonacoEditor
id={`pre-request-${model.id}`} id={`pre-request-${model.id}`}
value={editorContents.preRequestScript} value={editorContents.preRequestScript}
language="javascript" language="javascript"
onChange={(value) => { onChange={(value) => {
setEditorContents(prev => ({ ...prev, preRequestScript: value })); setEditorContents(prev => ({...prev, preRequestScript: value}));
setCurrentModel(prev => ({ ...prev, preRequestScript: value })); setCurrentModel(prev => ({...prev, preRequestScript: value}));
}} }}
height="full"
/> />
</div> </TabsContent>
</div>
{/* Post-Request Tab Content */} {/* Post-Request Tab Content */}
<div style={{ display: currentTab === 'post-request' ? 'block' : 'none' }} className="flex"> <TabsContent value="post-request" className="h-full m-0">
<div>
<MonacoEditor <MonacoEditor
id={`post-request-${model.id}`} id={`post-request-${model.id}`}
value={editorContents.postRequestScript} value={editorContents.postRequestScript}
language="javascript" language="javascript"
onChange={(value) => { onChange={(value) => {
setEditorContents(prev => ({ ...prev, postRequestScript: value })); setEditorContents(prev => ({...prev, postRequestScript: value}));
setCurrentModel(prev => ({ ...prev, postRequestScript: value })); setCurrentModel(prev => ({...prev, postRequestScript: value}));
}} }}
height="full"
/> />
</div> </TabsContent>
</div>
</div> </div>
</Tabs> </Tabs>
</div>
{/* Response Section */} {/* Response Section */}
<div className="flex-1"> <div className="flex-1 min-h-0">
<div className="flex items-center space-x-2 mb-2"> <div className="flex items-center gap-2 mb-2">
<span>Response</span> <span>Response</span>
<span className="text-sm text-gray-500">{responseData.status}</span> <span className="text-sm text-gray-500">{responseData.status}</span>
<span className="text-sm text-gray-500">{responseData.time}</span> <span className="text-sm text-gray-500">{responseData.time}</span>
<span className="text-sm text-gray-500">{responseData.size}</span> <span className="text-sm text-gray-500">{responseData.size}</span>
</div> </div>
<Tabs value={currentResponseTab} onValueChange={setCurrentResponseTab}> <Tabs value={currentResponseTab} onValueChange={setCurrentResponseTab} className="flex flex-col h-[calc(100%-2rem)]">
<TabsList> <TabsList>
<TabsTrigger value="response-body">Body</TabsTrigger> <TabsTrigger value="response-body">Body</TabsTrigger>
<TabsTrigger value="response-headers">Headers</TabsTrigger> <TabsTrigger value="response-headers">Headers</TabsTrigger>
<TabsTrigger value="console">Console</TabsTrigger> <TabsTrigger value="console">Console</TabsTrigger>
</TabsList> </TabsList>
<div className="mt-2"> <div className="flex-1 min-h-0 mt-2">
<div style={{display: currentResponseTab === 'response-body' ? 'block' : 'none'}}> <TabsContent value="response-body" className="h-full m-0">
<MonacoEditor <MonacoEditor
id={`response-body-${model.id}`} id={`response-body-${model.id}`}
value={editorContents.responseBody} value={editorContents.responseBody}
readOnly={true} readOnly={true}
onChange={() => {}} // Read-only, so no onChange needed height="full"
/> />
</div> </TabsContent>
<div style={{display: currentResponseTab === 'response-headers' ? 'block' : 'none'}}> <TabsContent value="response-headers" className="h-full m-0">
{renderResponseHeaders()} {renderResponseHeaders()}
</div> </TabsContent>
<div style={{display: currentResponseTab === 'console' ? 'block' : 'none'}}> <TabsContent value="console" className="h-full m-0">
<MonacoEditor <MonacoEditor
id={`console-${model.id}`} id={`console-${model.id}`}
value={editorContents.console} value={editorContents.console}
language="plaintext" language="plaintext"
readOnly={true} readOnly={true}
height="full"
/> />
</div> </TabsContent>
</div> </div>
</Tabs> </Tabs>
</div> </div>
</div> </div>
</div>
); );
}; };