Skip to content
This repository was archived by the owner on Mar 18, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/app/_common/components/nodeHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useState, useEffect, useCallback } from 'react';
import {
getNodes as apiGetNodes,
exportNodes as apiExportNodes,
refreshNodes as apiRefreshNodes
} from '@/app/api/nodeAPI';
import { toast } from 'react-hot-toast';

Expand Down Expand Up @@ -86,7 +87,7 @@ export const useNodes = (): UseNodesReturn => {
setIsLoading(true);
setError(null);
try {
const data = await apiExportNodes();
const data = await apiRefreshNodes();
setNodes(data as NodeCategory[]);
toast.success('노드 목록 새로고침 완료!');
} catch (err: any) {
Expand Down
155 changes: 0 additions & 155 deletions src/app/api/chatAPI.js

This file was deleted.

23 changes: 23 additions & 0 deletions src/app/api/nodeAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,26 @@ export const exportNodes = async () => {
throw error;
}
};

/**
* @returns {Promise<Array<Object>>} 노드 객체의 배열을 반환하는 프로미스
* @throws {Error} API 요청이 실패하면 에러를 발생시킵니다.
*/
export const refreshNodes = async () => {
try {
const response = await fetch(`${API_BASE_URL}/api/node/refresh`);

if (!response.ok) {
const errorData = await response.json();
throw new Error(
errorData.detail || `HTTP error! status: ${response.status}`,
);
}

// force_refresh 후, 최신 노드 리스트를 다시 불러옵니다.
return await getNodes();
} catch (error) {
devLog.error('Failed to get nodes:', error);
throw error; // 에러를 호출한 쪽으로 다시 던져서 UI에서 처리할 수 있도록 합니다.
}
};
17 changes: 9 additions & 8 deletions src/app/api/workflowAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ export const deleteWorkflowIOLogs = async (workflowName, workflowId, interaction
* @param {string} workflowName - 워크플로우 이름 (.json 확장자 제외)
* @param {string} workflowId - 워크플로우 ID
* @param {string} inputData - 실행에 사용할 입력 데이터 (선택사항)
* @param {string|null} [params.selectedCollection] - Optional selected collection
* @returns {Promise<Object>} 실행 결과를 포함하는 프로미스
* @throws {Error} API 요청이 실패하면 에러를 발생시킵니다.
*/
Expand All @@ -354,30 +355,30 @@ export const executeWorkflowById = async (
workflowId,
inputData = '',
interaction_id = 'default',
selectedCollection = null,
) => {
try {
const body = {
const requestBody = {
workflow_name: workflowName,
workflow_id: workflowId,
input_data: inputData || '',
interaction_id: interaction_id || 'default',
};
const response = await fetch(
`${API_BASE_URL}/api/workflow/execute/based_id`,
{
if (selectedCollection) {
requestBody.selected_collection = selectedCollection;
}
const response = await fetch(`${API_BASE_URL}/api/workflow/execute/based_id`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
body: JSON.stringify(requestBody),
},
);

if (!response.ok) {
const errorData = await response.json();
throw new Error(
errorData.detail || `HTTP error! status: ${response.status}`,
);
throw new Error(errorData.detail || `HTTP error! status: ${response.status}`);
}

const result = await response.json();
Expand Down
54 changes: 50 additions & 4 deletions src/app/canvas/components/Node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,13 @@ const Node: React.FC<NodeProps> = ({
{param.options && param.options.length > 0 ? (
<select
value={param.value}
onChange={(e) => handleParamValueChange(e, param.id)}
onChange={(e) => {
devLog.log('=== Select Parameter Change ===');
devLog.log('Parameter:', param.name, 'Previous value:', param.value, 'New value:', e.target.value);
devLog.log('Available options:', param.options);
handleParamValueChange(e, param.id);
devLog.log('=== Select Parameter Change Complete ===');
}}
onMouseDown={(e) => {
devLog.log('select onMouseDown');
e.stopPropagation();
Expand All @@ -102,15 +108,15 @@ const Node: React.FC<NodeProps> = ({
e.stopPropagation();
}}
onFocus={(e) => {
devLog.log('select onFocus');
devLog.log('select onFocus - Parameter:', param.name, 'Current value:', param.value);
e.stopPropagation();
// Clear node selection when editing parameter
if (onClearSelection) {
onClearSelection();
}
}}
onBlur={(e) => {
devLog.log('select onBlur');
devLog.log('select onBlur - Parameter:', param.name, 'Final value:', e.target.value);
e.stopPropagation();
}}
onKeyDown={(e) => {
Expand All @@ -119,12 +125,52 @@ const Node: React.FC<NodeProps> = ({
}}
className={`${styles.paramSelect} paramSelect`}
>
<option value="" disabled>-- Select --</option>
Copy link

Copilot AI Jul 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default placeholder option is duplicated in both the regular select (line 128) and boolean select (line 170). Consider extracting this into a constant or component to maintain consistency.

Suggested change
<option value="" disabled>-- Select --</option>
<PlaceholderOption />

Copilot uses AI. Check for mistakes.
{param.options.map((option, index) => (
<option key={index} value={option.value}>
{option.label || option.value}
</option>
))}
</select>
) : param.type === 'BOOL' ? (
<select
value={param.value}
onChange={(e) => {
devLog.log('=== Boolean Parameter Change ===');
devLog.log('Parameter:', param.name, 'Previous value:', param.value, 'New value:', e.target.value);
handleParamValueChange(e, param.id);
devLog.log('=== Boolean Parameter Change Complete ===');
}}
onMouseDown={(e) => {
devLog.log('boolean select onMouseDown');
e.stopPropagation();
}}
onClick={(e) => {
devLog.log('boolean select onClick');
e.stopPropagation();
}}
onFocus={(e) => {
devLog.log('boolean select onFocus - Parameter:', param.name, 'Current value:', param.value);
e.stopPropagation();
// Clear node selection when editing parameter
if (onClearSelection) {
onClearSelection();
}
}}
onBlur={(e) => {
devLog.log('boolean select onBlur - Parameter:', param.name, 'Final value:', e.target.value);
e.stopPropagation();
}}
onKeyDown={(e) => {
// Prevent keyboard event propagation
e.stopPropagation();
}}
className={`${styles.paramSelect} paramSelect`}
>
<option value="" disabled>-- Select --</option>
<option value="true">True</option>
<option value="false">False</option>
</select>
) : (
<input
type={typeof param.value === 'number' ? 'number' : 'text'}
Expand Down Expand Up @@ -359,4 +405,4 @@ const Node: React.FC<NodeProps> = ({
);
};

export default memo(Node);
export default memo(Node);
Loading
Loading