import { styled } from '@mui/material/styles'; import React from 'react'; import _ from 'lodash'; import ArrowRightAltIcon from '@mui/icons-material/ArrowRightAlt'; import FiberManualRecordIcon from '@mui/icons-material/FiberManualRecord'; import HTMLReactParse from 'html-react-parser'; import PropTypes from 'prop-types'; import gettext from 'sources/gettext'; import Table from '../components/Table'; const StyledTable = styled(Table)(({theme}) => ({ '& .Analysis-collapsible': { cursor: 'pointer', }, '& .Analysis-collapseParent': { borderBottom: '2px dashed '+theme.palette.primary.main, }, '& .Analysis-textRight': { textAlign: 'right', }, '& .Analysis-level2': { backgroundColor: theme.otherVars.explain.sev2.bg, color: theme.otherVars.explain.sev2.color, }, '& .Analysis-level3': { backgroundColor: theme.otherVars.explain.sev3.bg, color: theme.otherVars.explain.sev3.color, }, '& .Analysis-level4': { backgroundColor: theme.otherVars.explain.sev4.bg, color: theme.otherVars.explain.sev4.color, }, '& .Analysis-header': { border: 'none', background: 'none', color :theme.palette.text.primary } })); function getRowClassname(data, collapseParent) { let className = []; if(data['Plans']?.length > 0) { className.push('Analysis-collapsible'); } if(collapseParent) { className.push('Analysis-collapseParent'); } return className; } function NodeText({displayText, extraInfo}) { return ( <> {displayText} {extraInfo?.length > 0 && } ); } NodeText.propTypes = { displayText: PropTypes.string, extraInfo: PropTypes.array, }; function ExplainRow({row, show, activeExId, setActiveExId, collapsedExId, toggleCollapseExId}) { let data = row['data']; const exId = `pga_ex_${data['level'].join('_')}`; const parentExId = `pga_ex_${data['parent_node']}`; const collapsed = collapsedExId.findIndex((v)=>parentExId.startsWith(v)) > -1; const className = getRowClassname(data, collapsedExId.indexOf(exId) > -1); let onRowClick = (e)=>{ toggleCollapseExId(e.currentTarget.getAttribute('data-ex-id'), data['Plans']?.length); }; return ( {setActiveExId(e.currentTarget.getAttribute('data-ex-id'));}} onMouseLeave={()=>{setActiveExId(null);}} className={className} data-parent={parentExId} data-ex-id={`pga_ex_${data['level'].join('_')}`} style={collapsed ? {display: 'none'} : {}} onClick={onRowClick}> {data['_serial']}. {data['exclusive'] && (data['exclusive']+' ms')} {data['inclusive'] && (data['inclusive']+' ms')} {!_.isUndefined(data['rowsx_flag']) && (data['rowsx_direction'] == 'positive' ? <>↑ : <>↓) } {data['rowsx']} {data['Actual Rows']} {data['Plan Rows']} {data['Actual Loops']} ); } ExplainRow.propTypes = { row: PropTypes.shape({ data: PropTypes.shape({ Plans: PropTypes.array, level: PropTypes.array, _serial: PropTypes.number, parent_node: PropTypes.string, exclusive: PropTypes.number, exclusive_flag: PropTypes.string, inclusive: PropTypes.number, inclusive_flag: PropTypes.string, rowsx_direction: PropTypes.string, rowsx: PropTypes.number, rowsx_flag: PropTypes.oneOfType([PropTypes.number,PropTypes.string]), 'Actual Rows': PropTypes.number, 'Plan Rows': PropTypes.number, 'Actual Loops': PropTypes.number, }), node_extra_info: PropTypes.array, display_text: PropTypes.string, tooltip_text: PropTypes.string, }), show: PropTypes.shape({ show_timings: PropTypes.bool, show_rowsx: PropTypes.bool, show_rows: PropTypes.bool, show_plan_rows: PropTypes.bool, }), activeExId: PropTypes.string, setActiveExId: PropTypes.func, collapsedExId: PropTypes.array, toggleCollapseExId: PropTypes.func, }; export default function Analysis({explainTable}) { const [activeExId, setActiveExId] = React.useState(); const [collapsedExId, setCollapsedExId] = React.useState([]); const toggleCollapseExId = (exId, hasPlans=true)=>{ if(hasPlans) { setCollapsedExId((prev)=>{ if(prev.indexOf(exId) > -1) { return prev.filter((v)=>v!=exId); } return [...prev, exId]; }); } }; return ( {_.sortBy(explainTable.rows,(r)=>r['data']['_serial']).map((row)=>{ return ; })} ); } Analysis.propTypes = { explainTable: PropTypes.object, };