import React, { useLayoutEffect, useRef, useState } from 'react'; import { WhereWhatPair } from "maxun-core"; import { Box, Button, IconButton, MenuItem, Stack, TextField, Tooltip, Typography } from "@mui/material"; import { Close, KeyboardArrowDown, KeyboardArrowUp } from "@mui/icons-material"; import TreeView from '@mui/lab/TreeView'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import TreeItem from '@mui/lab/TreeItem'; import { AddButton } from "../atoms/buttons/AddButton"; import { WarningText } from "../atoms/texts"; import NotificationImportantIcon from '@mui/icons-material/NotificationImportant'; import { RemoveButton } from "../atoms/buttons/RemoveButton"; import { AddWhereCondModal } from "./AddWhereCondModal"; import { UpdatePair } from "../../api/workflow"; import { useSocketStore } from "../../context/socket"; import { AddWhatCondModal } from "./AddWhatCondModal"; interface PairDetailProps { pair: WhereWhatPair | null; index: number; } export const PairDetail = ({ pair, index }: PairDetailProps) => { const [pairIsSelected, setPairIsSelected] = useState(false); const [collapseWhere, setCollapseWhere] = useState(true); const [collapseWhat, setCollapseWhat] = useState(true); const [rerender, setRerender] = useState(false); const [expanded, setExpanded] = React.useState( pair ? Object.keys(pair.where).map((key, index) => `${key}-${index}`) : [] ); const [addWhereCondOpen, setAddWhereCondOpen] = useState(false); const [addWhatCondOpen, setAddWhatCondOpen] = useState(false); const { socket } = useSocketStore(); const handleCollapseWhere = () => { setCollapseWhere(!collapseWhere); } const handleCollapseWhat = () => { setCollapseWhat(!collapseWhat); } const handleToggle = (event: React.SyntheticEvent, nodeIds: string[]) => { setExpanded(nodeIds); }; useLayoutEffect(() => { if (pair) { setPairIsSelected(true); } }, [pair]) const handleChangeValue = (value: any, where: boolean, keys: (string|number)[]) => { // a moving reference to internal objects within pair.where or pair.what let schema: any = where ? pair?.where : pair?.what; const length = keys.length; for(let i = 0; i < length-1; i++) { const elem = keys[i]; if( !schema[elem] ) schema[elem] = {} schema = schema[elem]; } schema[keys[length-1]] = value; if (pair && socket) { socket.emit('updatePair', {index: index-1, pair: pair}); } setRerender(!rerender); } const DisplayValueContent = (value: any, keys: (string|number)[], where: boolean = true) => { switch (typeof(value)) { case 'string': return { try { const obj = JSON.parse(e.target.value); handleChangeValue(obj, where, keys); } catch (error) { const num = Number(e.target.value); if (!isNaN(num)) { handleChangeValue(num, where, keys); } handleChangeValue(e.target.value, where, keys) } }} defaultValue={value} key={`text-field-${keys.join('-')}-${where}`} /> case 'number': return handleChangeValue(Number(e.target.value), where, keys)} defaultValue={value} key={`text-field-${keys.join('-')}-${where}`} /> case 'object': if (value) { if (Array.isArray(value)) { return ( { value.map((element, index) => { return DisplayValueContent(element, [...keys, index], where); }) } { let prevValue:any = where ? pair?.where : pair?.what; for (const key of keys) { prevValue = prevValue[key]; } handleChangeValue([...prevValue, ''], where, keys); setRerender(!rerender); }} hoverEffect={false}/> { let prevValue:any = where ? pair?.where : pair?.what; for (const key of keys) { prevValue = prevValue[key]; } prevValue.splice(-1); handleChangeValue(prevValue, where, keys); setRerender(!rerender); }}/> ) } else { return ( } defaultExpandIcon={} sx={{ flexGrow: 1, overflowY: 'auto' }} key={`tree-view-nested-${keys.join('-')}-${where}`} > { Object.keys(value).map((key2, index) => { return ( { DisplayValueContent(value[key2], [...keys, key2], where) } ) }) } ) } } break; default: return null; } } return ( { pair && setAddWhatCondOpen(false)} pair={pair} index={index}/> setAddWhereCondOpen(false)} pair={pair} index={index}/> } { pairIsSelected ? (
Pair number: {index} { if (pair && socket) { socket.emit('updatePair', {index: index-1, pair: pair}); pair.id = e.target.value; } }} value={pair ? pair.id ? pair.id : '' : ''} /> Where
{ setAddWhereCondOpen(true); }} style={{color:'rgba(0, 0, 0, 0.54)', background:'transparent'}}/>
{(collapseWhere && pair && pair.where) ? { Object.keys(pair.where).map((key, index) => { return ( } defaultExpandIcon={} sx={{ flexGrow: 1, overflowY: 'auto' }} onNodeToggle={handleToggle} key={`tree-view-${key}-${index}`} > { // @ts-ignore DisplayValueContent(pair.where[key], [key]) } ); })} : null } What
{ setAddWhatCondOpen(true); }} style={{color:'rgba(0, 0, 0, 0.54)', background:'transparent'}}/>
{(collapseWhat && pair && pair.what) ?( { Object.keys(pair.what).map((key, index) => { return ( } defaultExpandIcon={} sx={{ flexGrow: 1, overflowY: 'auto' }} key={`tree-view-2-${key}-${index}`} > { // @ts-ignore DisplayValueContent(pair.what[key], [key], false) }
{ //@ts-ignore pair.what.splice(key, 1); setRerender(!rerender); }}/>
); })}
) : null }
) : No pair from the left side panel was selected. }
); } interface CollapseButtonProps { handleClick: () => void; isCollapsed?: boolean; } const CollapseButton = ({handleClick, isCollapsed } : CollapseButtonProps) => { return ( { isCollapsed ? : } ); } const CloseButton = ({handleClick } : CollapseButtonProps) => { return ( ); }