passing fullAccessPath instead of parentPath and name

This commit is contained in:
Mose Müller 2024-03-27 10:01:04 +01:00
parent 1a01222cb3
commit ff3a509132
12 changed files with 42 additions and 118 deletions

View File

@ -188,8 +188,6 @@ const App = () => {
<div className="App navbarOffset"> <div className="App navbarOffset">
<WebSettingsContext.Provider value={webSettings}> <WebSettingsContext.Provider value={webSettings}>
<GenericComponent <GenericComponent
name=""
parentPath=""
attribute={state as SerializedValue} attribute={state as SerializedValue}
isInstantUpdate={isInstantUpdate} isInstantUpdate={isInstantUpdate}
addNotification={addNotification} addNotification={addNotification}

View File

@ -5,8 +5,7 @@ import { DocStringComponent } from './DocStringComponent';
import { LevelName } from './NotificationsComponent'; import { LevelName } from './NotificationsComponent';
type AsyncMethodProps = { type AsyncMethodProps = {
name: string; fullAccessPath: string;
parentPath: string;
value: 'RUNNING' | null; value: 'RUNNING' | null;
docString?: string; docString?: string;
hideOutput?: boolean; hideOutput?: boolean;
@ -18,8 +17,7 @@ type AsyncMethodProps = {
export const AsyncMethodComponent = React.memo((props: AsyncMethodProps) => { export const AsyncMethodComponent = React.memo((props: AsyncMethodProps) => {
const { const {
name, fullAccessPath,
parentPath,
docString, docString,
value: runningTask, value: runningTask,
addNotification, addNotification,
@ -34,7 +32,8 @@ export const AsyncMethodComponent = React.memo((props: AsyncMethodProps) => {
const renderCount = useRef(0); const renderCount = useRef(0);
const formRef = useRef(null); const formRef = useRef(null);
const fullAccessPath = [parentPath, name].filter((element) => element).join('.'); const name = fullAccessPath.split('.').at(-1);
const parentPath = fullAccessPath.slice(0, -(name.length + 1));
useEffect(() => { useEffect(() => {
renderCount.current++; renderCount.current++;

View File

@ -4,8 +4,7 @@ import { DocStringComponent } from './DocStringComponent';
import { LevelName } from './NotificationsComponent'; import { LevelName } from './NotificationsComponent';
type ButtonComponentProps = { type ButtonComponentProps = {
name: string; fullAccessPath: string;
parentPath?: string;
value: boolean; value: boolean;
readOnly: boolean; readOnly: boolean;
docString: string; docString: string;
@ -24,6 +23,7 @@ type ButtonComponentProps = {
export const ButtonComponent = React.memo((props: ButtonComponentProps) => { export const ButtonComponent = React.memo((props: ButtonComponentProps) => {
const { const {
value, value,
fullAccessPath,
readOnly, readOnly,
docString, docString,
addNotification, addNotification,
@ -32,9 +32,6 @@ export const ButtonComponent = React.memo((props: ButtonComponentProps) => {
id id
} = props; } = props;
// const buttonName = props.mapping ? (value ? props.mapping[0] : props.mapping[1]) : name; // const buttonName = props.mapping ? (value ? props.mapping[0] : props.mapping[1]) : name;
const fullAccessPath = [props.parentPath, props.name]
.filter((element) => element)
.join('.');
const renderCount = useRef(0); const renderCount = useRef(0);

View File

@ -6,9 +6,7 @@ import { SerializedValue, GenericComponent } from './GenericComponent';
import { LevelName } from './NotificationsComponent'; import { LevelName } from './NotificationsComponent';
type DataServiceProps = { type DataServiceProps = {
name: string;
props: DataServiceJSON; props: DataServiceJSON;
parentPath?: string;
isInstantUpdate: boolean; isInstantUpdate: boolean;
addNotification: (message: string, levelname?: LevelName) => void; addNotification: (message: string, levelname?: LevelName) => void;
displayName: string; displayName: string;
@ -18,17 +16,8 @@ type DataServiceProps = {
export type DataServiceJSON = Record<string, SerializedValue>; export type DataServiceJSON = Record<string, SerializedValue>;
export const DataServiceComponent = React.memo( export const DataServiceComponent = React.memo(
({ ({ props, isInstantUpdate, addNotification, displayName, id }: DataServiceProps) => {
name,
props,
parentPath = undefined,
isInstantUpdate,
addNotification,
displayName,
id
}: DataServiceProps) => {
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
const fullAccessPath = [parentPath, name].filter((element) => element).join('.');
if (displayName !== '') { if (displayName !== '') {
return ( return (
@ -43,8 +32,6 @@ export const DataServiceComponent = React.memo(
<GenericComponent <GenericComponent
key={key} key={key}
attribute={value} attribute={value}
name={key}
parentPath={fullAccessPath}
isInstantUpdate={isInstantUpdate} isInstantUpdate={isInstantUpdate}
addNotification={addNotification} addNotification={addNotification}
/> />
@ -61,8 +48,6 @@ export const DataServiceComponent = React.memo(
<GenericComponent <GenericComponent
key={key} key={key}
attribute={value} attribute={value}
name={key}
parentPath={fullAccessPath}
isInstantUpdate={isInstantUpdate} isInstantUpdate={isInstantUpdate}
addNotification={addNotification} addNotification={addNotification}
/> />

View File

@ -4,9 +4,8 @@ import { DataServiceComponent, DataServiceJSON } from './DataServiceComponent';
import { MethodComponent } from './MethodComponent'; import { MethodComponent } from './MethodComponent';
type DeviceConnectionProps = { type DeviceConnectionProps = {
name: string; fullAccessPath: string;
props: DataServiceJSON; props: DataServiceJSON;
parentPath: string;
isInstantUpdate: boolean; isInstantUpdate: boolean;
addNotification: (message: string, levelname?: LevelName) => void; addNotification: (message: string, levelname?: LevelName) => void;
displayName: string; displayName: string;
@ -15,9 +14,8 @@ type DeviceConnectionProps = {
export const DeviceConnectionComponent = React.memo( export const DeviceConnectionComponent = React.memo(
({ ({
name, fullAccessPath,
props, props,
parentPath,
isInstantUpdate, isInstantUpdate,
addNotification, addNotification,
displayName, displayName,
@ -26,8 +24,6 @@ export const DeviceConnectionComponent = React.memo(
const { connected, connect, ...updatedProps } = props; const { connected, connect, ...updatedProps } = props;
const connectedVal = connected.value; const connectedVal = connected.value;
const fullAccessPath = [parentPath, name].filter((element) => element).join('.');
return ( return (
<div className="deviceConnectionComponent" id={id}> <div className="deviceConnectionComponent" id={id}>
{!connectedVal && ( {!connectedVal && (
@ -36,8 +32,7 @@ export const DeviceConnectionComponent = React.memo(
{displayName != '' ? displayName : 'Device'} is currently not available! {displayName != '' ? displayName : 'Device'} is currently not available!
</div> </div>
<MethodComponent <MethodComponent
name="connect" fullAccessPath={`${fullAccessPath}.connect`}
parentPath={fullAccessPath}
docString={connect.doc} docString={connect.doc}
addNotification={addNotification} addNotification={addNotification}
displayName={'reconnect'} displayName={'reconnect'}
@ -47,9 +42,7 @@ export const DeviceConnectionComponent = React.memo(
</div> </div>
)} )}
<DataServiceComponent <DataServiceComponent
name={name}
props={updatedProps} props={updatedProps}
parentPath={parentPath}
isInstantUpdate={isInstantUpdate} isInstantUpdate={isInstantUpdate}
addNotification={addNotification} addNotification={addNotification}
displayName={displayName} displayName={displayName}

View File

@ -45,24 +45,16 @@ export type SerializedValue = {
}; };
type GenericComponentProps = { type GenericComponentProps = {
attribute: SerializedValue; attribute: SerializedValue;
name: string;
parentPath: string;
isInstantUpdate: boolean; isInstantUpdate: boolean;
addNotification: (message: string, levelname?: LevelName) => void; addNotification: (message: string, levelname?: LevelName) => void;
}; };
export const GenericComponent = React.memo( export const GenericComponent = React.memo(
({ ({ attribute, isInstantUpdate, addNotification }: GenericComponentProps) => {
attribute, const { full_access_path: fullAccessPath } = attribute;
name,
parentPath,
isInstantUpdate,
addNotification
}: GenericComponentProps) => {
const fullAccessPath = [parentPath, name].filter((element) => element).join('.');
const id = getIdFromFullAccessPath(fullAccessPath); const id = getIdFromFullAccessPath(fullAccessPath);
const webSettings = useContext(WebSettingsContext); const webSettings = useContext(WebSettingsContext);
let displayName = name; let displayName = fullAccessPath.split('.').at(-1);
if (webSettings[fullAccessPath]) { if (webSettings[fullAccessPath]) {
if (webSettings[fullAccessPath].display === false) { if (webSettings[fullAccessPath].display === false) {
@ -83,8 +75,7 @@ export const GenericComponent = React.memo(
if (attribute.type === 'bool') { if (attribute.type === 'bool') {
return ( return (
<ButtonComponent <ButtonComponent
name={name} fullAccessPath={fullAccessPath}
parentPath={parentPath}
docString={attribute.doc} docString={attribute.doc}
readOnly={attribute.readonly} readOnly={attribute.readonly}
value={Boolean(attribute.value)} value={Boolean(attribute.value)}
@ -97,9 +88,8 @@ export const GenericComponent = React.memo(
} else if (attribute.type === 'float' || attribute.type === 'int') { } else if (attribute.type === 'float' || attribute.type === 'int') {
return ( return (
<NumberComponent <NumberComponent
name={name}
type={attribute.type} type={attribute.type}
parentPath={parentPath} fullAccessPath={fullAccessPath}
docString={attribute.doc} docString={attribute.doc}
readOnly={attribute.readonly} readOnly={attribute.readonly}
value={Number(attribute.value)} value={Number(attribute.value)}
@ -113,9 +103,8 @@ export const GenericComponent = React.memo(
} else if (attribute.type === 'Quantity') { } else if (attribute.type === 'Quantity') {
return ( return (
<NumberComponent <NumberComponent
name={name}
type="float" type="float"
parentPath={parentPath} fullAccessPath={fullAccessPath}
docString={attribute.doc} docString={attribute.doc}
readOnly={attribute.readonly} readOnly={attribute.readonly}
value={Number(attribute.value['magnitude'])} value={Number(attribute.value['magnitude'])}
@ -130,8 +119,7 @@ export const GenericComponent = React.memo(
} else if (attribute.type === 'NumberSlider') { } else if (attribute.type === 'NumberSlider') {
return ( return (
<SliderComponent <SliderComponent
name={name} fullAccessPath={fullAccessPath}
parentPath={parentPath}
docString={attribute.value['value'].doc} docString={attribute.value['value'].doc}
readOnly={attribute.readonly} readOnly={attribute.readonly}
value={attribute.value['value']} value={attribute.value['value']}
@ -148,8 +136,7 @@ export const GenericComponent = React.memo(
} else if (attribute.type === 'Enum') { } else if (attribute.type === 'Enum') {
return ( return (
<EnumComponent <EnumComponent
name={name} fullAccessPath={fullAccessPath}
parentPath={parentPath}
docString={attribute.doc} docString={attribute.doc}
value={String(attribute.value)} value={String(attribute.value)}
readOnly={attribute.readonly} readOnly={attribute.readonly}
@ -164,8 +151,7 @@ export const GenericComponent = React.memo(
if (!attribute.async) { if (!attribute.async) {
return ( return (
<MethodComponent <MethodComponent
name={name} fullAccessPath={fullAccessPath}
parentPath={parentPath}
docString={attribute.doc} docString={attribute.doc}
addNotification={addNotification} addNotification={addNotification}
displayName={displayName} displayName={displayName}
@ -176,10 +162,9 @@ export const GenericComponent = React.memo(
} else { } else {
return ( return (
<AsyncMethodComponent <AsyncMethodComponent
name={name} fullAccessPath={fullAccessPath}
parentPath={parentPath}
docString={attribute.doc} docString={attribute.doc}
value={attribute.value as Record<string, string>} value={attribute.value as 'RUNNING' | null}
addNotification={addNotification} addNotification={addNotification}
displayName={displayName} displayName={displayName}
id={id} id={id}
@ -190,11 +175,10 @@ export const GenericComponent = React.memo(
} else if (attribute.type === 'str') { } else if (attribute.type === 'str') {
return ( return (
<StringComponent <StringComponent
name={name} fullAccessPath={fullAccessPath}
value={attribute.value as string} value={attribute.value as string}
readOnly={attribute.readonly} readOnly={attribute.readonly}
docString={attribute.doc} docString={attribute.doc}
parentPath={parentPath}
isInstantUpdate={isInstantUpdate} isInstantUpdate={isInstantUpdate}
addNotification={addNotification} addNotification={addNotification}
changeCallback={changeCallback} changeCallback={changeCallback}
@ -205,9 +189,7 @@ export const GenericComponent = React.memo(
} else if (attribute.type === 'DataService') { } else if (attribute.type === 'DataService') {
return ( return (
<DataServiceComponent <DataServiceComponent
name={name}
props={attribute.value as DataServiceJSON} props={attribute.value as DataServiceJSON}
parentPath={parentPath}
isInstantUpdate={isInstantUpdate} isInstantUpdate={isInstantUpdate}
addNotification={addNotification} addNotification={addNotification}
displayName={displayName} displayName={displayName}
@ -217,9 +199,8 @@ export const GenericComponent = React.memo(
} else if (attribute.type === 'DeviceConnection') { } else if (attribute.type === 'DeviceConnection') {
return ( return (
<DeviceConnectionComponent <DeviceConnectionComponent
name={name} fullAccessPath={fullAccessPath}
props={attribute.value as DataServiceJSON} props={attribute.value as DataServiceJSON}
parentPath={parentPath}
isInstantUpdate={isInstantUpdate} isInstantUpdate={isInstantUpdate}
addNotification={addNotification} addNotification={addNotification}
displayName={displayName} displayName={displayName}
@ -229,10 +210,8 @@ export const GenericComponent = React.memo(
} else if (attribute.type === 'list') { } else if (attribute.type === 'list') {
return ( return (
<ListComponent <ListComponent
name={name}
value={attribute.value as SerializedValue[]} value={attribute.value as SerializedValue[]}
docString={attribute.doc} docString={attribute.doc}
parentPath={parentPath}
isInstantUpdate={isInstantUpdate} isInstantUpdate={isInstantUpdate}
addNotification={addNotification} addNotification={addNotification}
id={id} id={id}
@ -241,8 +220,7 @@ export const GenericComponent = React.memo(
} else if (attribute.type === 'Image') { } else if (attribute.type === 'Image') {
return ( return (
<ImageComponent <ImageComponent
name={name} fullAccessPath={fullAccessPath}
parentPath={parentPath}
docString={attribute.value['value'].doc} docString={attribute.value['value'].doc}
displayName={displayName} displayName={displayName}
id={id} id={id}
@ -255,20 +233,15 @@ export const GenericComponent = React.memo(
} else if (attribute.type === 'ColouredEnum') { } else if (attribute.type === 'ColouredEnum') {
return ( return (
<ColouredEnumComponent <ColouredEnumComponent
name={name} attribute={attribute}
parentPath={parentPath}
docString={attribute.doc}
value={String(attribute.value)}
readOnly={attribute.readonly}
enumDict={attribute.enum}
addNotification={addNotification} addNotification={addNotification}
changeCallback={changeCallback}
displayName={displayName} displayName={displayName}
id={id} id={id}
changeCallback={changeCallback}
/> />
); );
} else { } else {
return <div key={name}>{name}</div>; return <div key={fullAccessPath}>{fullAccessPath}</div>;
} }
} }
); );

View File

@ -5,8 +5,7 @@ import { ChevronDown, ChevronRight } from 'react-bootstrap-icons';
import { LevelName } from './NotificationsComponent'; import { LevelName } from './NotificationsComponent';
type ImageComponentProps = { type ImageComponentProps = {
name: string; fullAccessPath: string;
parentPath: string;
value: string; value: string;
docString: string; docString: string;
format: string; format: string;
@ -16,13 +15,11 @@ type ImageComponentProps = {
}; };
export const ImageComponent = React.memo((props: ImageComponentProps) => { export const ImageComponent = React.memo((props: ImageComponentProps) => {
const { value, docString, format, addNotification, displayName, id } = props; const { fullAccessPath, value, docString, format, addNotification, displayName, id } =
props;
const renderCount = useRef(0); const renderCount = useRef(0);
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
const fullAccessPath = [props.parentPath, props.name]
.filter((element) => element)
.join('.');
useEffect(() => { useEffect(() => {
renderCount.current++; renderCount.current++;

View File

@ -4,8 +4,6 @@ import { SerializedValue, GenericComponent } from './GenericComponent';
import { LevelName } from './NotificationsComponent'; import { LevelName } from './NotificationsComponent';
type ListComponentProps = { type ListComponentProps = {
name: string;
parentPath?: string;
value: SerializedValue[]; value: SerializedValue[];
docString: string; docString: string;
isInstantUpdate: boolean; isInstantUpdate: boolean;
@ -14,8 +12,7 @@ type ListComponentProps = {
}; };
export const ListComponent = React.memo((props: ListComponentProps) => { export const ListComponent = React.memo((props: ListComponentProps) => {
const { name, parentPath, value, docString, isInstantUpdate, addNotification, id } = const { value, docString, isInstantUpdate, addNotification, id } = props;
props;
const renderCount = useRef(0); const renderCount = useRef(0);
@ -34,8 +31,6 @@ export const ListComponent = React.memo((props: ListComponentProps) => {
<GenericComponent <GenericComponent
key={`${name}[${index}]`} key={`${name}[${index}]`}
attribute={item} attribute={item}
name={`${name}[${index}]`}
parentPath={parentPath}
isInstantUpdate={isInstantUpdate} isInstantUpdate={isInstantUpdate}
addNotification={addNotification} addNotification={addNotification}
/> />

View File

@ -5,8 +5,7 @@ import { DocStringComponent } from './DocStringComponent';
import { LevelName } from './NotificationsComponent'; import { LevelName } from './NotificationsComponent';
type MethodProps = { type MethodProps = {
name: string; fullAccessPath: string;
parentPath: string;
docString?: string; docString?: string;
addNotification: (message: string, levelname?: LevelName) => void; addNotification: (message: string, levelname?: LevelName) => void;
displayName: string; displayName: string;
@ -15,7 +14,7 @@ type MethodProps = {
}; };
export const MethodComponent = React.memo((props: MethodProps) => { export const MethodComponent = React.memo((props: MethodProps) => {
const { name, parentPath, docString, addNotification, displayName, id } = props; const { fullAccessPath, docString, addNotification, displayName, id } = props;
// Conditional rendering based on the 'render' prop. // Conditional rendering based on the 'render' prop.
if (!props.render) { if (!props.render) {
@ -24,7 +23,6 @@ export const MethodComponent = React.memo((props: MethodProps) => {
const renderCount = useRef(0); const renderCount = useRef(0);
const formRef = useRef(null); const formRef = useRef(null);
const fullAccessPath = [parentPath, name].filter((element) => element).join('.');
const triggerNotification = () => { const triggerNotification = () => {
const message = `Method ${fullAccessPath} was triggered.`; const message = `Method ${fullAccessPath} was triggered.`;

View File

@ -30,9 +30,8 @@ export type FloatObject = {
export type NumberObject = IntObject | FloatObject | QuantityObject; export type NumberObject = IntObject | FloatObject | QuantityObject;
type NumberComponentProps = { type NumberComponentProps = {
name: string;
type: 'float' | 'int'; type: 'float' | 'int';
parentPath?: string; fullAccessPath: string;
value: number; value: number;
readOnly: boolean; readOnly: boolean;
docString: string; docString: string;
@ -161,7 +160,7 @@ const handleNumericKey = (
export const NumberComponent = React.memo((props: NumberComponentProps) => { export const NumberComponent = React.memo((props: NumberComponentProps) => {
const { const {
name, fullAccessPath,
value, value,
readOnly, readOnly,
type, type,
@ -179,9 +178,7 @@ export const NumberComponent = React.memo((props: NumberComponentProps) => {
// Create a state for the input string // Create a state for the input string
const [inputString, setInputString] = useState(value.toString()); const [inputString, setInputString] = useState(value.toString());
const renderCount = useRef(0); const renderCount = useRef(0);
const fullAccessPath = [props.parentPath, props.name] const name = fullAccessPath.split('.').at(-1);
.filter((element) => element)
.join('.');
const handleKeyDown = (event) => { const handleKeyDown = (event) => {
const { key, target } = event; const { key, target } = event;

View File

@ -6,10 +6,9 @@ import { NumberComponent, NumberObject } from './NumberComponent';
import { LevelName } from './NotificationsComponent'; import { LevelName } from './NotificationsComponent';
type SliderComponentProps = { type SliderComponentProps = {
name: string; fullAccessPath: string;
min: NumberObject; min: NumberObject;
max: NumberObject; max: NumberObject;
parentPath?: string;
value: NumberObject; value: NumberObject;
readOnly: boolean; readOnly: boolean;
docString: string; docString: string;
@ -30,8 +29,7 @@ export const SliderComponent = React.memo((props: SliderComponentProps) => {
const renderCount = useRef(0); const renderCount = useRef(0);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const { const {
name, fullAccessPath,
parentPath,
value, value,
min, min,
max, max,
@ -43,7 +41,6 @@ export const SliderComponent = React.memo((props: SliderComponentProps) => {
displayName, displayName,
id id
} = props; } = props;
const fullAccessPath = [parentPath, name].filter((element) => element).join('.');
useEffect(() => { useEffect(() => {
renderCount.current++; renderCount.current++;
@ -133,8 +130,7 @@ export const SliderComponent = React.memo((props: SliderComponentProps) => {
<Col xs="3" xl> <Col xs="3" xl>
<NumberComponent <NumberComponent
isInstantUpdate={isInstantUpdate} isInstantUpdate={isInstantUpdate}
parentPath={parentPath} fullAccessPath={`${fullAccessPath}.value`}
name={`${name}.value`}
docString="" docString=""
readOnly={valueReadOnly} readOnly={valueReadOnly}
type="float" type="float"

View File

@ -7,8 +7,7 @@ import { LevelName } from './NotificationsComponent';
// TODO: add button functionality // TODO: add button functionality
type StringComponentProps = { type StringComponentProps = {
name: string; fullAccessPath: string;
parentPath?: string;
value: string; value: string;
readOnly: boolean; readOnly: boolean;
docString: string; docString: string;
@ -26,7 +25,7 @@ type StringComponentProps = {
export const StringComponent = React.memo((props: StringComponentProps) => { export const StringComponent = React.memo((props: StringComponentProps) => {
const { const {
name, fullAccessPath,
readOnly, readOnly,
docString, docString,
isInstantUpdate, isInstantUpdate,
@ -38,9 +37,6 @@ export const StringComponent = React.memo((props: StringComponentProps) => {
const renderCount = useRef(0); const renderCount = useRef(0);
const [inputString, setInputString] = useState(props.value); const [inputString, setInputString] = useState(props.value);
const fullAccessPath = [props.parentPath, props.name]
.filter((element) => element)
.join('.');
useEffect(() => { useEffect(() => {
renderCount.current++; renderCount.current++;
@ -86,7 +82,7 @@ export const StringComponent = React.memo((props: StringComponentProps) => {
</InputGroup.Text> </InputGroup.Text>
<Form.Control <Form.Control
type="text" type="text"
name={name} name={fullAccessPath}
value={inputString} value={inputString}
disabled={readOnly} disabled={readOnly}
onChange={handleChange} onChange={handleChange}