diff --git a/frontend/src/metabase/components/ErrorDetails.jsx b/frontend/src/metabase/components/ErrorDetails.jsx deleted file mode 100644 index 88aaa18342e22397bf9a9472a593b2054bf9295d..0000000000000000000000000000000000000000 --- a/frontend/src/metabase/components/ErrorDetails.jsx +++ /dev/null @@ -1,43 +0,0 @@ -/* eslint-disable react/prop-types */ -import React from "react"; -import { t } from "ttag"; -import cx from "classnames"; - -export default class ErrorDetails extends React.Component { - state = { - showError: false, - }; - render() { - const { details, centered, className } = this.props; - if (!details) { - return null; - } - return ( - <div className={className}> - <div className={centered ? "text-centered" : "text-left"}> - <a - onClick={() => this.setState({ showError: true })} - className="link cursor-pointer" - >{t`Show error details`}</a> - </div> - <div - style={{ display: this.state.showError ? "inherit" : "none" }} - className={cx("pt3", centered ? "text-centered" : "text-left")} - > - <h2>{t`Here's the full error message`}</h2> - <div - style={{ fontFamily: "monospace" }} - className="QueryError2-detailBody bordered rounded bg-light text-bold p2 mt1" - > - {/* ensure we don't try to render anything except a string */} - {typeof details === "string" - ? details - : typeof details.message === "string" - ? details.message - : String(details)} - </div> - </div> - </div> - ); - } -} diff --git a/frontend/src/metabase/components/ErrorDetails/ErrorDetails.tsx b/frontend/src/metabase/components/ErrorDetails/ErrorDetails.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2dcbdef97b9e310fed2defa5efdc8cf691d4a78f --- /dev/null +++ b/frontend/src/metabase/components/ErrorDetails/ErrorDetails.tsx @@ -0,0 +1,48 @@ +import React, { useState } from "react"; +import { t } from "ttag"; +import cx from "classnames"; + +import { ErrorDetailsProps } from "./types"; + +export default function ErrorDetails({ + details, + centered, + className, +}: ErrorDetailsProps) { + const [showError, setShowError] = useState(false); + + if (!details) { + return null; + } + + function toggleShowError() { + setShowError(showError => !showError); + } + + return ( + <div className={className}> + <div className={centered ? "text-centered" : "text-left"}> + <a onClick={toggleShowError} className="link cursor-pointer"> + {showError ? t`Hide error details` : t`Show error details`} + </a> + </div> + <div + style={{ display: showError ? "inherit" : "none" }} + className={cx("pt3", centered ? "text-centered" : "text-left")} + > + <h2>{t`Here's the full error message`}</h2> + <div + style={{ fontFamily: "monospace" }} + className="QueryError2-detailBody bordered rounded bg-light text-bold p2 mt1" + > + {/* ensure we don't try to render anything except a string */} + {typeof details === "string" + ? details + : typeof details.message === "string" + ? details.message + : String(details)} + </div> + </div> + </div> + ); +} diff --git a/frontend/src/metabase/components/ErrorDetails/index.ts b/frontend/src/metabase/components/ErrorDetails/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..d0b6d4f260e18ac8072eb0460e7f316266adf057 --- /dev/null +++ b/frontend/src/metabase/components/ErrorDetails/index.ts @@ -0,0 +1 @@ +export { default } from "./ErrorDetails"; diff --git a/frontend/src/metabase/components/ErrorDetails/types.ts b/frontend/src/metabase/components/ErrorDetails/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..3f0133559f63dbd99370a1f62ff94d1f38297a47 --- /dev/null +++ b/frontend/src/metabase/components/ErrorDetails/types.ts @@ -0,0 +1,5 @@ +export interface ErrorDetailsProps { + details: string | Record<string, any>; + centered?: boolean; + className?: string; +} diff --git a/frontend/src/metabase/containers/ErrorPages.jsx b/frontend/src/metabase/containers/ErrorPages.jsx index 8acb299b761f5dc1982b097d8b5a604cae9fb03d..903cdb50c724b444a0fc189e05a945024f6c37d2 100644 --- a/frontend/src/metabase/containers/ErrorPages.jsx +++ b/frontend/src/metabase/containers/ErrorPages.jsx @@ -6,7 +6,7 @@ import fitViewport from "metabase/hoc/FitViewPort"; import Icon from "metabase/components/Icon"; import EmptyState from "metabase/components/EmptyState"; -import ErrorDetails from "metabase/components/ErrorDetails"; +import ErrorDetails from "metabase/components/ErrorDetails/ErrorDetails"; import NoResults from "assets/img/no_results.svg"; import { ErrorPageRoot } from "./ErrorPages.styled"; diff --git a/frontend/src/metabase/query_builder/components/VisualizationError.jsx b/frontend/src/metabase/query_builder/components/VisualizationError.jsx index 1e66758515cd3c2ae4c19bea1586a7f66f79cd8f..760c11731724e154958e27b7af7335a54b1e04f1 100644 --- a/frontend/src/metabase/query_builder/components/VisualizationError.jsx +++ b/frontend/src/metabase/query_builder/components/VisualizationError.jsx @@ -8,7 +8,7 @@ import cx from "classnames"; import MetabaseSettings from "metabase/lib/settings"; import ErrorMessage from "metabase/components/ErrorMessage"; -import ErrorDetails from "metabase/components/ErrorDetails"; +import ErrorDetails from "metabase/components/ErrorDetails/ErrorDetails"; import { QueryError, QueryErrorIcon,