import React, { useState, useEffect, useRef } from 'react'; import { runMethod } from '../socket'; import { Button, InputGroup, Form, Collapse } from 'react-bootstrap'; import { DocStringComponent } from './DocStringComponent'; import { getIdFromFullAccessPath } from '../utils/stringUtils'; interface MethodProps { name: string; parentPath: string; parameters: Record; docString?: string; hideOutput?: boolean; addNotification: (message: string) => void; } export const MethodComponent = React.memo((props: MethodProps) => { const { name, parentPath, docString, addNotification } = props; const renderCount = useRef(0); const [hideOutput, setHideOutput] = useState(false); // Add a new state variable to hold the list of function calls const [functionCalls, setFunctionCalls] = useState([]); const id = getIdFromFullAccessPath(parentPath.concat('.' + name)); useEffect(() => { renderCount.current++; if (props.hideOutput !== undefined) { setHideOutput(props.hideOutput); } }); const triggerNotification = (args: Record) => { const argsString = Object.entries(args) .map(([key, value]) => `${key}: "${value}"`) .join(', '); let message = `Method ${parentPath}.${name} was triggered`; if (argsString === '') { message += '.'; } else { message += ` with arguments {${argsString}}.`; } addNotification(message); }; const execute = async (event: React.FormEvent) => { event.preventDefault(); const kwargs = {}; Object.keys(props.parameters).forEach( (name) => (kwargs[name] = event.target[name].value) ); runMethod(name, parentPath, kwargs, (ack) => { // Update the functionCalls state with the new call if we get an acknowledge msg if (ack !== undefined) { setFunctionCalls((prevCalls) => [ ...prevCalls, { name, args: kwargs, result: ack } ]); } }); triggerNotification(kwargs); }; const args = Object.entries(props.parameters).map(([name, type], index) => { const form_name = `${name} (${type})`; return ( {form_name} ); }); return (
{process.env.NODE_ENV === 'development' && (

Render count: {renderCount.current}

)}
setHideOutput(!hideOutput)} style={{ cursor: 'pointer' }}> Function: {name}
{args}
{functionCalls.map((call, index) => (
{Object.entries(call.args) .map(([key, val]) => `${key}=${JSON.stringify(val)}`) .join(', ') + ' => ' + JSON.stringify(call.result)}
))}
); });