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

     1  import ErrorMessage from "../../../ErrorMessage";
     2  import Icon from "../../../Icon";
     3  import LoadingIndicator from "../../LoadingIndicator";
     4  import usePanelDependenciesStatus from "../../../../hooks/usePanelDependenciesStatus";
     5  import { classNames } from "../../../../utils/styles";
     6  import { HashLink } from "react-router-hash-link";
     7  import { InputProperties } from "../../inputs/types";
     8  import { PanelDefinition } from "../../../../types";
     9  import { ReactNode } from "react";
    10  import { useLocation } from "react-router-dom";
    11  
    12  type PanelStatusProps = PanelStatusBaseProps & {
    13    definition: PanelDefinition;
    14    showPanelError: boolean;
    15  };
    16  
    17  type PanelStatusBaseProps = {
    18    definition: PanelDefinition;
    19  };
    20  
    21  type BasePanelStatusProps = {
    22    children: ReactNode;
    23    className?: string;
    24    definition: PanelDefinition;
    25  };
    26  
    27  const BasePanelStatus = ({
    28    children,
    29    className,
    30    definition,
    31  }: BasePanelStatusProps) => (
    32    <div
    33      className={classNames(
    34        className,
    35        "w-full h-full p-4 break-keep rounded-md",
    36        !!definition.title ? "rounded-t-none" : null
    37      )}
    38    >
    39      {children}
    40    </div>
    41  );
    42  
    43  const PanelInitialized = ({ definition }: PanelStatusBaseProps) => {
    44    return (
    45      <BasePanelStatus definition={definition}>
    46        <div className="flex items-center space-x-1">
    47          <LoadingIndicator className="w-3.5 h-3.5 text-foreground-light shrink-0" />
    48          <span className="block truncate">Initialized...</span>
    49        </div>
    50      </BasePanelStatus>
    51    );
    52  };
    53  
    54  const PanelBlocked = ({ definition }) => {
    55    const panelDependenciesStatus = usePanelDependenciesStatus();
    56    const location = useLocation();
    57    return (
    58      <BasePanelStatus definition={definition}>
    59        <div className="flex items-center space-x-1">
    60          {panelDependenciesStatus.inputsAwaitingValue.length > 0 && (
    61            <>
    62              <Icon
    63                className="w-3.5 h-3.5 text-foreground-light shrink-0"
    64                icon="block"
    65              />
    66              <span className="block truncate">
    67                Awaiting input:{" "}
    68                <HashLink
    69                  className="text-link"
    70                  to={`${location.pathname}${
    71                    location.search ? location.search : ""
    72                  }#${panelDependenciesStatus.inputsAwaitingValue[0].name}`}
    73                >
    74                  {panelDependenciesStatus.inputsAwaitingValue[0].title ||
    75                    (
    76                      panelDependenciesStatus.inputsAwaitingValue[0]
    77                        .properties as InputProperties
    78                    ).unqualified_name}
    79                </HashLink>
    80              </span>
    81            </>
    82          )}
    83          {panelDependenciesStatus.inputsAwaitingValue.length === 0 &&
    84            panelDependenciesStatus.total === 0 && (
    85              <>
    86                <LoadingIndicator className="w-3.5 h-3.5 text-foreground-light shrink-0" />
    87                <span className="block truncate">Loading...</span>
    88              </>
    89            )}
    90          {panelDependenciesStatus.inputsAwaitingValue.length === 0 &&
    91            panelDependenciesStatus.total > 0 && (
    92              <>
    93                <LoadingIndicator className="w-3.5 h-3.5 text-foreground-light shrink-0" />
    94                <span className="block truncate">
    95                  Loading{" "}
    96                  {panelDependenciesStatus.status.complete.total +
    97                    panelDependenciesStatus.status.running.total +
    98                    1}{" "}
    99                  of {panelDependenciesStatus.total + 1}...
   100                </span>
   101              </>
   102            )}
   103        </div>
   104      </BasePanelStatus>
   105    );
   106  };
   107  
   108  const PanelRunning = ({ definition }) => {
   109    const panelDependenciesStatus = usePanelDependenciesStatus();
   110    return (
   111      <BasePanelStatus definition={definition}>
   112        <div className="flex items-center space-x-1">
   113          {panelDependenciesStatus.inputsAwaitingValue.length === 0 &&
   114            panelDependenciesStatus.total === 0 && (
   115              <>
   116                <LoadingIndicator className="w-3.5 h-3.5 text-foreground-light shrink-0" />
   117                <span className="block truncate">Loading...</span>
   118              </>
   119            )}
   120          {panelDependenciesStatus.inputsAwaitingValue.length === 0 &&
   121            panelDependenciesStatus.total > 0 && (
   122              <>
   123                <LoadingIndicator className="w-3.5 h-3.5 text-foreground-light shrink-0" />
   124                <span className="block truncate">
   125                  Loading{" "}
   126                  {panelDependenciesStatus.status.complete.total +
   127                    panelDependenciesStatus.status.running.total +
   128                    1}{" "}
   129                  of {panelDependenciesStatus.total + 1}...
   130                </span>
   131              </>
   132            )}
   133        </div>
   134      </BasePanelStatus>
   135    );
   136  };
   137  
   138  const PanelCancelled = ({ definition }) => {
   139    return (
   140      <BasePanelStatus definition={definition}>
   141        <div className="flex items-center space-x-1">
   142          <Icon
   143            className="w-3.5 h-3.5 text-foreground-light shrink-0"
   144            icon="cancel"
   145          />
   146          <span className="block truncate">Cancelled</span>
   147        </div>
   148      </BasePanelStatus>
   149    );
   150  };
   151  
   152  const PanelError = ({ definition }) => {
   153    return (
   154      <BasePanelStatus
   155        className="bg-alert-light border-alert text-foreground"
   156        definition={definition}
   157      >
   158        <div className="flex items-center space-x-1">
   159          <Icon
   160            className="w-3.5 h-3.5 text-alert shrink-0"
   161            icon="materialsymbols-solid:error"
   162          />
   163          <span className="block truncate">Error</span>
   164        </div>
   165        <span className="block">
   166          <ErrorMessage error={definition.error} />
   167        </span>
   168      </BasePanelStatus>
   169    );
   170  };
   171  
   172  const PanelStatus = ({ definition, showPanelError }: PanelStatusProps) => (
   173    <>
   174      {definition.status === "initialized" && (
   175        <PanelInitialized definition={definition} />
   176      )}
   177      {definition.status === "blocked" && (
   178        <PanelBlocked definition={definition} />
   179      )}
   180      {definition.status === "running" && (
   181        <PanelRunning definition={definition} />
   182      )}
   183      {definition.status === "cancelled" && (
   184        <PanelCancelled definition={definition} />
   185      )}
   186      {definition.status === "error" && showPanelError && (
   187        <PanelError definition={definition} />
   188      )}
   189    </>
   190  );
   191  
   192  export default PanelStatus;