({
selectedNode,
onClose,
onUpdateNode,
workflowId: workflowIdProp,
workflowSchedules,
schedulesLoading,
scheduleError,
onScheduleCreate,
onScheduleEdit,
onScheduleAction,
onScheduleDelete,
onViewSchedules,
}: ConfigPanelProps)
| 284 | * Shows component information and allows editing node parameters |
| 285 | */ |
| 286 | export function ConfigPanel({ |
| 287 | selectedNode, |
| 288 | onClose, |
| 289 | onUpdateNode, |
| 290 | workflowId: workflowIdProp, |
| 291 | workflowSchedules, |
| 292 | schedulesLoading, |
| 293 | scheduleError, |
| 294 | onScheduleCreate, |
| 295 | onScheduleEdit, |
| 296 | onScheduleAction, |
| 297 | onScheduleDelete, |
| 298 | onViewSchedules, |
| 299 | }: ConfigPanelProps) { |
| 300 | const isMobile = useIsMobile(); |
| 301 | const { getComponent, loading } = useComponentStore(); |
| 302 | const { getEdges, getNodes } = useReactFlow(); |
| 303 | const fallbackWorkflowId = useWorkflowStore((state) => state.metadata.id); |
| 304 | const workflowId = workflowIdProp ?? fallbackWorkflowId; |
| 305 | const navigate = useNavigate(); |
| 306 | const schedulesContext = useOptionalWorkflowSchedulesContext(); |
| 307 | |
| 308 | // Get API key for curl command |
| 309 | |
| 310 | const lastCreatedKey = useApiKeyStore((state) => state.lastCreatedKey); |
| 311 | const fetchApiKeys = useApiKeyStore((state) => state.fetchApiKeys); |
| 312 | |
| 313 | // Fetch API keys on mount if not already loaded |
| 314 | useEffect(() => { |
| 315 | fetchApiKeys().catch(console.error); |
| 316 | }, [fetchApiKeys]); |
| 317 | |
| 318 | // Use lastCreatedKey (full key) if available, otherwise null (will show placeholder) |
| 319 | const activeApiKey = lastCreatedKey || null; |
| 320 | |
| 321 | // Fixed width on desktop, full width on mobile |
| 322 | const effectiveWidth = isMobile ? '100%' : PANEL_WIDTH; |
| 323 | |
| 324 | const handleParamValueChange = (paramId: string, value: any) => { |
| 325 | if (!selectedNode || !onUpdateNode) return; |
| 326 | |
| 327 | const nodeData: FrontendNodeData = selectedNode.data; |
| 328 | const config = nodeData.config || { params: {}, inputOverrides: {} }; |
| 329 | |
| 330 | let updatedParams = { |
| 331 | ...(config.params ?? {}), |
| 332 | }; |
| 333 | |
| 334 | if (value === undefined) { |
| 335 | const { [paramId]: _removed, ...rest } = updatedParams; |
| 336 | updatedParams = rest; |
| 337 | } else { |
| 338 | updatedParams[paramId] = value; |
| 339 | } |
| 340 | |
| 341 | onUpdateNode(selectedNode.id, { |
| 342 | config: { |
| 343 | ...config, |
nothing calls this directly
no test coverage detected