feat: refactor error components and add database issue code (#10473)

* feat: refactor error components and add database issue code

* Apply suggestions from code review

Co-authored-by: John Bodley <4567245+john-bodley@users.noreply.github.com>

Co-authored-by: John Bodley <4567245+john-bodley@users.noreply.github.com>
This commit is contained in:
Erik Ritter
2020-08-06 13:22:24 -07:00
committed by GitHub
parent 62b873e3da
commit 2055ecc1ba
35 changed files with 384 additions and 185 deletions

View File

@@ -16,73 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
import React, { useState } from 'react';
import { Modal } from 'react-bootstrap';
import { styled, supersetTheme } from '@superset-ui/style';
import React from 'react';
import { t, tn } from '@superset-ui/translation';
import { noOp } from 'src/utils/common';
import Button from 'src/views/CRUD/dataset/Button';
import Icon from '../Icon';
import { ErrorMessageComponentProps } from './types';
import CopyToClipboard from '../CopyToClipboard';
import IssueCode from './IssueCode';
const ErrorAlert = styled.div`
align-items: center;
background-color: ${({ theme }) => theme.colors.error.light2};
border-radius: ${({ theme }) => theme.borderRadius}px;
border: 1px solid ${({ theme }) => theme.colors.error.base};
color: ${({ theme }) => theme.colors.error.dark2};
padding: ${({ theme }) => 2 * theme.gridUnit}px;
width: 100%;
.top-row {
display: flex;
justify-content: space-between;
}
.error-body {
padding-top: ${({ theme }) => theme.gridUnit}px;
padding-left: ${({ theme }) => 8 * theme.gridUnit}px;
}
.icon {
margin-right: ${({ theme }) => 2 * theme.gridUnit}px;
}
.link {
color: ${({ theme }) => theme.colors.error.dark2};
text-decoration: underline;
}
`;
const ErrorModal = styled(Modal)`
color: ${({ theme }) => theme.colors.error.dark2};
.icon {
margin-right: ${({ theme }) => 2 * theme.gridUnit}px;
}
.header {
align-items: center;
background-color: ${({ theme }) => theme.colors.error.light2};
display: flex;
justify-content: space-between;
font-size: ${({ theme }) => theme.typography.sizes.l}px;
// Remove clearfix hack as Superset is only used on modern browsers
::before,
::after {
content: unset;
}
}
`;
const LeftSideContent = styled.div`
align-items: center;
display: flex;
`;
import ErrorAlert from './ErrorAlert';
interface TimeoutErrorExtra {
issue_codes: {
@@ -97,21 +36,14 @@ function TimeoutErrorMessage({
error,
source,
}: ErrorMessageComponentProps<TimeoutErrorExtra>) {
const [isModalOpen, setIsModalOpen] = useState(false);
const [isMessageExpanded, setIsMessageExpanded] = useState(false);
const { extra } = error;
const { extra, level } = error;
const isVisualization = (['dashboard', 'explore'] as (
| string
| undefined
)[]).includes(source);
const isExpandable = (['explore', 'sqllab'] as (
| string
| undefined
)[]).includes(source);
const title = isVisualization
const subtitle = isVisualization
? tn(
'Were having trouble loading this visualization. Queries are set to timeout after %s second.',
'Were having trouble loading this visualization. Queries are set to timeout after %s seconds.',
@@ -125,7 +57,7 @@ function TimeoutErrorMessage({
extra.timeout,
);
const message = (
const body = (
<>
<p>
{t('This may be triggered by:')}
@@ -157,91 +89,19 @@ function TimeoutErrorMessage({
</>
);
const copyText = `${title}
const copyText = `${subtitle}
${t('This may be triggered by:')}
${extra.issue_codes.map(issueCode => issueCode.message).join('\n')}`;
return (
<ErrorAlert>
<div className="top-row">
<LeftSideContent>
<Icon
className="icon"
name="error"
color={supersetTheme.colors.error.base}
/>
<strong>{t('Timeout Error')}</strong>
</LeftSideContent>
{!isExpandable && (
<a href="#" className="link" onClick={() => setIsModalOpen(true)}>
{t('See More')}
</a>
)}
</div>
{isExpandable ? (
<div className="error-body">
<p>{title}</p>
{!isMessageExpanded && (
<a
href="#"
className="link"
onClick={() => setIsMessageExpanded(true)}
>
{t('See More')}
</a>
)}
{isMessageExpanded && (
<>
<br />
{message}
<a
href="#"
className="link"
onClick={() => setIsMessageExpanded(false)}
>
{t('See Less')}
</a>
</>
)}
</div>
) : (
<ErrorModal show={isModalOpen} onHide={() => setIsModalOpen(false)}>
<Modal.Header className="header">
<LeftSideContent>
<Icon
className="icon"
name="error"
color={supersetTheme.colors.error.base}
/>
<div className="title">{t('Timeout Error')}</div>
</LeftSideContent>
<span
role="button"
tabIndex={0}
onClick={() => setIsModalOpen(false)}
>
<Icon name="close" />
</span>
</Modal.Header>
<Modal.Body>
<p>{title}</p>
<br />
{message}
</Modal.Body>
<Modal.Footer>
<CopyToClipboard
text={copyText}
shouldShowText={false}
wrapped={false}
copyNode={<Button onClick={noOp}>{t('Copy Message')}</Button>}
/>
<Button bsStyle="primary" onClick={() => setIsModalOpen(false)}>
{t('Close')}
</Button>
</Modal.Footer>
</ErrorModal>
)}
</ErrorAlert>
<ErrorAlert
title={t('Timeout Error')}
subtitle={subtitle}
level={level}
source={source}
copyText={copyText}
body={body}
/>
);
}