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;