fix(database): make to display validation error msg when all cases (#20095)

* fix(database): make to display validation error msg when all cases

* fix(db): make to update the alert error condition

* fix(db): make to add error detail display

* fix(db): make to update error alert display by superset error style guide.

* fix(db): make to style modal header title with h4

* fix(db): make to place see more on bottom instead of top

* fix(db): make to fix shortly

* fix(db): make to fix lint issue

Co-authored-by: Evan Rusackas <evan@preset.io>
This commit is contained in:
smileydev 2022-08-24 13:29:22 -04:00 committed by GitHub
parent 604e30b3f0
commit d568999592
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 12 deletions

View File

@ -31,6 +31,7 @@ const mockedProps = {
subtitle: 'Error subtitle',
title: 'Error title',
source: 'dashboard' as ErrorSource,
description: 'we are unable to connect db.',
};
test('should render', () => {
@ -63,6 +64,11 @@ test('should render the error title', () => {
expect(screen.getByText('Error title')).toBeInTheDocument();
});
test('should render the error description', () => {
render(<ErrorAlert {...mockedProps} />, { useRedux: true });
expect(screen.getByText('we are unable to connect db.')).toBeInTheDocument();
});
test('should render the error subtitle', () => {
render(<ErrorAlert {...mockedProps} />, { useRedux: true });
const button = screen.getByText('See more');

View File

@ -87,6 +87,7 @@ interface ErrorAlertProps {
source?: ErrorSource;
subtitle: ReactNode;
title: ReactNode;
description?: string;
}
export default function ErrorAlert({
@ -96,6 +97,7 @@ export default function ErrorAlert({
source = 'dashboard',
subtitle,
title,
description,
}: ErrorAlertProps) {
const theme = useTheme();
@ -116,7 +118,7 @@ export default function ErrorAlert({
)}
<strong>{title}</strong>
</LeftSideContent>
{!isExpandable && (
{!isExpandable && !description && (
<span
role="button"
tabIndex={0}
@ -127,6 +129,21 @@ export default function ErrorAlert({
</span>
)}
</div>
{description && (
<div className="error-body">
<p>{description}</p>
{!isExpandable && (
<span
role="button"
tabIndex={0}
className="link"
onClick={() => setIsModalOpen(true)}
>
{t('See more')}
</span>
)}
</div>
)}
{isExpandable ? (
<div className="error-body">
<p>{subtitle}</p>

View File

@ -32,6 +32,7 @@ type Props = {
copyText?: string;
stackTrace?: string;
source?: ErrorSource;
description?: string;
errorMitigationFunction?: () => void;
};
@ -43,6 +44,7 @@ export default function ErrorMessageWithStackTrace({
link,
stackTrace,
source,
description,
}: Props) {
// Check if a custom error message component was registered for this message
if (error) {
@ -66,6 +68,7 @@ export default function ErrorMessageWithStackTrace({
title={title}
subtitle={subtitle}
copyText={copyText}
description={description}
source={source}
body={
link || stackTrace ? (

View File

@ -42,6 +42,7 @@ import IconButton from 'src/components/IconButton';
import InfoTooltip from 'src/components/InfoTooltip';
import withToasts from 'src/components/MessageToasts/withToasts';
import ValidatedInput from 'src/components/Form/LabeledErrorBoundInput';
import ErrorMessageWithStackTrace from 'src/components/ErrorMessage/ErrorMessageWithStackTrace';
import ErrorAlert from 'src/components/ImportModal/ErrorAlert';
import {
testDatabaseConnection,
@ -64,7 +65,6 @@ import ExtraOptions from './ExtraOptions';
import SqlAlchemyForm from './SqlAlchemyForm';
import DatabaseConnectionForm from './DatabaseConnectionForm';
import {
antDErrorAlertStyles,
antDAlertStyles,
antdWarningAlertStyles,
StyledAlertMargin,
@ -116,6 +116,12 @@ const TabsStyled = styled(Tabs)`
}
`;
const ErrorAlertContainer = styled.div`
${({ theme }) => `
margin: ${theme.gridUnit * 8}px ${theme.gridUnit * 4}px;
`};
`;
interface DatabaseModalProps {
addDangerToast: (msg: string) => void;
addSuccessToast: (msg: string) => void;
@ -475,7 +481,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
)?.parameters !== undefined;
const showDBError = validationErrors || dbErrors;
const isEmpty = (data?: Object | null) =>
data && Object.keys(data).length === 0;
!data || (data && Object.keys(data).length === 0);
const dbModel: DatabaseForm =
availableDbs?.databases?.find(
@ -1126,22 +1132,24 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
// eslint-disable-next-line consistent-return
const errorAlert = () => {
let alertErrors: string[] = [];
if (isEmpty(dbErrors) === false) {
if (!isEmpty(dbErrors)) {
alertErrors = typeof dbErrors === 'object' ? Object.values(dbErrors) : [];
} else if (db?.engine === Engines.Snowflake) {
} else if (!isEmpty(validationErrors)) {
alertErrors =
validationErrors?.error_type === 'GENERIC_DB_ENGINE_ERROR'
? [validationErrors?.description]
? [
'We are unable to connect to your database. Click "See more" for database-provided information that may help troubleshoot the issue.',
]
: [];
}
if (alertErrors.length) {
return (
<Alert
type="error"
css={(theme: SupersetTheme) => antDErrorAlertStyles(theme)}
message={t('Database Creation Error')}
<ErrorMessageWithStackTrace
title={t('Database Creation Error')}
description={t(alertErrors[0])}
subtitle={t(validationErrors?.description)}
copyText={t(validationErrors?.description)}
/>
);
}
@ -1480,7 +1488,9 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
onChange(ActionType.extraEditorChange, payload);
}}
/>
{showDBError && errorAlert()}
{showDBError && (
<ErrorAlertContainer>{errorAlert()}</ErrorAlertContainer>
)}
</Tabs.TabPane>
</TabsStyled>
</Modal>
@ -1641,7 +1651,9 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
)}
</div>
{/* Step 2 */}
{showDBError && errorAlert()}
{showDBError && (
<ErrorAlertContainer>{errorAlert()}</ErrorAlertContainer>
)}
</>
))}
</>