diff --git a/frontend/src/components/MethodComponent.tsx b/frontend/src/components/MethodComponent.tsx index 4161e8d..c9702a5 100644 --- a/frontend/src/components/MethodComponent.tsx +++ b/frontend/src/components/MethodComponent.tsx @@ -1,11 +1,13 @@ -import React, { useContext, useEffect, useRef, useState } from 'react'; -import { WebSettingsContext } from '../WebSettings'; +import React, { useEffect, useRef, useState } from 'react'; import { runMethod } from '../socket'; -import { Button, InputGroup, Form, Collapse } from 'react-bootstrap'; +import { Button, Form, Card } from 'react-bootstrap'; import { DocStringComponent } from './DocStringComponent'; -import { getIdFromFullAccessPath } from '../utils/stringUtils'; import { LevelName } from './NotificationsComponent'; -import { GenericComponent, SerializedValue } from './GenericComponent'; +import { SerializedValue } from './GenericComponent'; +import { FloatObject, NumberComponent, QuantityObject } from './NumberComponent'; +import { StringComponent } from './StringComponent'; +import { ColouredEnumComponent } from './ColouredEnumComponent'; +import { EnumComponent } from './EnumComponent'; type MethodProps = { name: string; @@ -14,36 +16,23 @@ type MethodProps = { docString?: string; hideOutput?: boolean; addNotification: (message: string, levelname?: LevelName) => void; + displayName: string; + id: string; }; export const MethodComponent = React.memo((props: MethodProps) => { - const { name, parentPath, docString, addNotification } = props; + const { name, parentPath, docString, addNotification, displayName, id } = 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 fullAccessPath = [parentPath, name].filter((element) => element).join('.'); - const id = getIdFromFullAccessPath(fullAccessPath); - const webSettings = useContext(WebSettingsContext); - let displayName = name; - - if (webSettings[fullAccessPath] && webSettings[fullAccessPath].displayName) { - displayName = webSettings[fullAccessPath].displayName; - } - - 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`; + let message = `Method ${fullAccessPath} was triggered`; if (argsString === '') { message += '.'; @@ -55,11 +44,10 @@ export const MethodComponent = React.memo((props: MethodProps) => { const execute = async (event: React.FormEvent) => { event.preventDefault(); - const kwargs = {}; - Object.keys(props.parameters).forEach( - (name) => (kwargs[name] = event.target[name].value) - ); + 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) { @@ -73,14 +61,109 @@ export const MethodComponent = React.memo((props: MethodProps) => { triggerNotification(kwargs); }; - const args = Object.entries(props.parameters).map(([name, type], index) => { - const form_name = `${name} (${type})`; - return ( - - {form_name} - - - ); + const args = Object.entries(props.parameters).map(([name, serializedValue]) => { + if (serializedValue.type == 'float' || serializedValue.type == 'int') { + return ( + {}} + id={id + '.' + name} + /> + ); + } else if (serializedValue.type == 'Quantity') { + return ( + {}} + id={id + '.' + name} + /> + ); + } else if (serializedValue.type == 'str') { + return ( + {}} + id={id + '.' + name} + /> + ); + } else if (serializedValue.type == 'Enum') { + return ( + {}} + enumDict={serializedValue.enum} + displayName={name} + id={id + '.' + name} + /> + ); + } else if (serializedValue.type == 'ColouredEnum') { + return ( + {}} + enumDict={serializedValue.enum} + displayName={name} + id={id + '.' + name} + /> + ); + } + }); + + // Content conditionally rendered based on args + const formContent = ( +
+ {args} + +
+ ); + + const outputContent = ( +
+ {functionCalls.map((call, index) => ( +
+
+ {Object.entries(call.args) + .map(([key, val]) => `${key}=${JSON.stringify(val)}`) + .join(', ') + + ' => ' + + JSON.stringify(call.result)} +
+
+ ))} +
+ ); + + useEffect(() => { + renderCount.current++; }); return ( @@ -88,32 +171,16 @@ export const MethodComponent = React.memo((props: MethodProps) => { {process.env.NODE_ENV === 'development' && (
Render count: {renderCount.current}
)} -
setHideOutput(!hideOutput)} style={{ cursor: 'pointer' }}> - Function: {displayName} -
-
- {args} - -
- - -
- {functionCalls.map((call, index) => ( -
-
- {Object.entries(call.args) - .map(([key, val]) => `${key}=${JSON.stringify(val)}`) - .join(', ') + - ' => ' + - JSON.stringify(call.result)} -
-
- ))} -
-
+ {args.length > 0 ? ( + + + {formContent} + {outputContent} + + + ) : ( +
{formContent}
+ )} ); });