github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/ui/dashboard/src/components/dashboards/layout/Panel/PanelProgress.tsx (about) 1 import { classNames } from "../../../../utils/styles"; 2 import { DashboardDataModeLive } from "../../../../types"; 3 import { getNodeAndEdgeDataFormat } from "../../common/useNodeAndEdgeData"; 4 import { NodeAndEdgeProperties } from "../../common/types"; 5 import { useDashboard } from "../../../../hooks/useDashboard"; 6 import { useMemo } from "react"; 7 import { usePanel } from "../../../../hooks/usePanel"; 8 9 const PanelProgress = ({ className }) => { 10 const { definition } = usePanel(); 11 const { dataMode, panelsMap } = useDashboard(); 12 13 const showProgress = useMemo( 14 () => 15 !definition.error && 16 (definition.panel_type === "flow" || 17 definition.panel_type === "graph" || 18 definition.panel_type === "hierarchy") && 19 getNodeAndEdgeDataFormat( 20 definition.properties as NodeAndEdgeProperties 21 ) === "NODE_AND_EDGE", 22 [definition] 23 ); 24 25 const progress = useMemo(() => { 26 if (!showProgress) { 27 return 100; 28 } 29 30 if (definition.status === "complete") { 31 return 100; 32 } 33 34 const nodeAndEdgeProperties = 35 definition?.properties as NodeAndEdgeProperties; 36 const nodes: string[] = nodeAndEdgeProperties?.nodes || []; 37 const edges: string[] = nodeAndEdgeProperties?.edges || []; 38 39 if (nodes.length === 0 && edges.length === 0) { 40 return 100; 41 } 42 43 const dependencyPanels = {}; 44 45 let totalThings = nodes.length + edges.length; 46 let totalComplete = 0; 47 let totalError = 0; 48 for (const panelName of [...nodes, ...edges]) { 49 const panel = panelsMap[panelName]; 50 if (!panel) { 51 continue; 52 } 53 54 for (const dependency of panel.dependencies || []) { 55 if (dependencyPanels[dependency]) { 56 continue; 57 } 58 const dependencyPanel = panelsMap[dependency]; 59 if (!dependencyPanel) { 60 continue; 61 } 62 dependencyPanels[dependency] = dependencyPanel; 63 if (dependencyPanel.status === "error") { 64 totalError += 1; 65 } else if (dependencyPanel.status === "complete") { 66 totalComplete += 1; 67 } 68 } 69 70 if (panel.status === "error") { 71 totalError += 1; 72 } else if (panel.status === "complete") { 73 totalComplete += 1; 74 } 75 } 76 77 totalThings += Object.keys(dependencyPanels).length; 78 79 return Math.min( 80 Math.ceil(((totalError + totalComplete) / totalThings) * 100), 81 100 82 ); 83 }, [definition, panelsMap, showProgress]); 84 85 // We only show a progress indicator in live mode 86 if (dataMode !== DashboardDataModeLive) { 87 return null; 88 } 89 90 return showProgress ? ( 91 <div 92 className={classNames( 93 className, 94 "w-full h-[4px] bg-dashboard-panel print:hidden" 95 )} 96 > 97 {progress < 100 && ( 98 <div 99 className="h-full bg-dashboard" 100 style={{ width: `${progress}%` }} 101 /> 102 )} 103 </div> 104 ) : null; 105 }; 106 107 export default PanelProgress;