github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/ui/dashboard/src/components/dashboards/layout/Panel/index.tsx (about)

     1  import PanelStatus from "./PanelStatus";
     2  import PanelControls from "./PanelControls";
     3  import PanelInformation from "./PanelInformation";
     4  import PanelProgress from "./PanelProgress";
     5  import PanelTitle from "../../titles/PanelTitle";
     6  import Placeholder from "../../Placeholder";
     7  import { BaseChartProps } from "../../charts/types";
     8  import { CardProps } from "../../Card";
     9  import { classNames } from "../../../../utils/styles";
    10  import { DashboardPanelType, PanelDefinition } from "../../../../types";
    11  import { FlowProps } from "../../flows/types";
    12  import { getResponsivePanelWidthClass } from "../../../../utils/layout";
    13  import { GraphProps } from "../../graphs/types";
    14  import { HierarchyProps } from "../../hierarchies/types";
    15  import { ImageProps } from "../../Image";
    16  import { InputProps } from "../../inputs/types";
    17  import { memo, useState } from "react";
    18  import { PanelProvider, usePanel } from "../../../../hooks/usePanel";
    19  import { ReactNode } from "react";
    20  import { registerComponent } from "../../index";
    21  import { TableProps } from "../../Table";
    22  import { TextProps } from "../../Text";
    23  import { useDashboard } from "../../../../hooks/useDashboard";
    24  
    25  type PanelProps = {
    26    children: ReactNode;
    27    className?: string;
    28    definition:
    29      | BaseChartProps
    30      | CardProps
    31      | FlowProps
    32      | GraphProps
    33      | HierarchyProps
    34      | ImageProps
    35      | InputProps
    36      | PanelDefinition
    37      | TableProps
    38      | TextProps;
    39    parentType: DashboardPanelType;
    40    showControls?: boolean;
    41    showPanelError?: boolean;
    42    showPanelStatus?: boolean;
    43    forceBackground?: boolean;
    44  };
    45  
    46  const Panel = ({
    47    children,
    48    className,
    49    definition,
    50    showControls = true,
    51    showPanelError = true,
    52    showPanelStatus = true,
    53    forceBackground = false,
    54  }: PanelProps) => {
    55    const { selectedPanel } = useDashboard();
    56    const {
    57      inputPanelsAwaitingValue,
    58      panelControls,
    59      showPanelControls,
    60      setShowPanelControls,
    61    } = usePanel();
    62    const [referenceElement, setReferenceElement] = useState(null);
    63    const baseStyles = classNames(
    64      "relative col-span-12",
    65      getResponsivePanelWidthClass(definition.width),
    66      "overflow-auto"
    67    );
    68  
    69    if (inputPanelsAwaitingValue.length > 0) {
    70      return null;
    71    }
    72  
    73    const PlaceholderComponent = Placeholder.component;
    74  
    75    const shouldShowLoader =
    76      showPanelStatus &&
    77      definition.status !== "cancelled" &&
    78      definition.status !== "error" &&
    79      definition.status !== "complete";
    80  
    81    const showPanelContents =
    82      !definition.error || (definition.error && !showPanelError);
    83  
    84    return (
    85      <div
    86        // @ts-ignore
    87        ref={setReferenceElement}
    88        id={definition.name}
    89        className={baseStyles}
    90        onMouseEnter={showControls ? () => setShowPanelControls(true) : undefined}
    91        onMouseLeave={() => setShowPanelControls(false)}
    92      >
    93        <section
    94          aria-labelledby={
    95            definition.title ? `${definition.name}-title` : undefined
    96          }
    97          className={classNames(
    98            "col-span-12 m-0.5",
    99            forceBackground ||
   100              (definition.panel_type !== "image" &&
   101                definition.panel_type !== "card" &&
   102                definition.panel_type !== "input") ||
   103              ((definition.panel_type === "image" ||
   104                definition.panel_type === "card" ||
   105                definition.panel_type === "input") &&
   106                definition.display_type === "table")
   107              ? "bg-dashboard-panel print:bg-white shadow-sm rounded-md"
   108              : null
   109          )}
   110        >
   111          {showPanelControls && (
   112            <PanelControls
   113              referenceElement={referenceElement}
   114              controls={panelControls}
   115            />
   116          )}
   117          {definition.title && (
   118            <div
   119              className={classNames(
   120                definition.panel_type === "input" &&
   121                  definition.display_type !== "table" &&
   122                  !forceBackground
   123                  ? "pl-0 pr-2 sm:pr-4 py-2"
   124                  : "px-4 py-4"
   125              )}
   126            >
   127              <PanelTitle name={definition.name} title={definition.title} />
   128            </div>
   129          )}
   130  
   131          <div
   132            className={classNames(
   133              "relative",
   134              definition.title &&
   135                ((definition.panel_type !== "input" &&
   136                  // @ts-ignore
   137                  definition.status !== "complete") ||
   138                  (definition.panel_type !== "input" &&
   139                    definition.panel_type !== "table") ||
   140                  (definition.panel_type === "table" &&
   141                    definition.display_type === "line"))
   142                ? "border-t border-divide"
   143                : null,
   144              selectedPanel ||
   145                (definition.panel_type === "table" &&
   146                  definition.display_type !== "line") ||
   147                definition.display_type === "table"
   148                ? "overflow-x-auto"
   149                : "overflow-x-hidden",
   150              className
   151            )}
   152          >
   153            <PanelProgress className={definition.title ? null : "rounded-t-md"} />
   154            <PanelInformation />
   155            <PlaceholderComponent
   156              animate={definition.status === "running"}
   157              ready={!shouldShowLoader}
   158            >
   159              <>
   160                {((showPanelError && definition.status === "error") ||
   161                  showPanelStatus) && (
   162                  <PanelStatus
   163                    definition={definition as PanelDefinition}
   164                    showPanelError={showPanelError}
   165                  />
   166                )}
   167                {showPanelContents && children}
   168              </>
   169            </PlaceholderComponent>
   170          </div>
   171        </section>
   172      </div>
   173    );
   174  };
   175  
   176  const PanelWrapper = memo((props: PanelProps) => {
   177    const { children, ...rest } = props;
   178    return (
   179      <PanelProvider
   180        definition={props.definition}
   181        parentType={props.parentType}
   182        showControls={props.showControls}
   183      >
   184        <Panel {...rest}>{children}</Panel>
   185      </PanelProvider>
   186    );
   187  });
   188  
   189  registerComponent("panel", PanelWrapper);
   190  
   191  export default PanelWrapper;