mirror of
https://github.com/apache/superset.git
synced 2024-09-18 19:49:37 -04:00
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:
parent
604e30b3f0
commit
d568999592
@ -31,6 +31,7 @@ const mockedProps = {
|
|||||||
subtitle: 'Error subtitle',
|
subtitle: 'Error subtitle',
|
||||||
title: 'Error title',
|
title: 'Error title',
|
||||||
source: 'dashboard' as ErrorSource,
|
source: 'dashboard' as ErrorSource,
|
||||||
|
description: 'we are unable to connect db.',
|
||||||
};
|
};
|
||||||
|
|
||||||
test('should render', () => {
|
test('should render', () => {
|
||||||
@ -63,6 +64,11 @@ test('should render the error title', () => {
|
|||||||
expect(screen.getByText('Error title')).toBeInTheDocument();
|
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', () => {
|
test('should render the error subtitle', () => {
|
||||||
render(<ErrorAlert {...mockedProps} />, { useRedux: true });
|
render(<ErrorAlert {...mockedProps} />, { useRedux: true });
|
||||||
const button = screen.getByText('See more');
|
const button = screen.getByText('See more');
|
||||||
|
@ -87,6 +87,7 @@ interface ErrorAlertProps {
|
|||||||
source?: ErrorSource;
|
source?: ErrorSource;
|
||||||
subtitle: ReactNode;
|
subtitle: ReactNode;
|
||||||
title: ReactNode;
|
title: ReactNode;
|
||||||
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ErrorAlert({
|
export default function ErrorAlert({
|
||||||
@ -96,6 +97,7 @@ export default function ErrorAlert({
|
|||||||
source = 'dashboard',
|
source = 'dashboard',
|
||||||
subtitle,
|
subtitle,
|
||||||
title,
|
title,
|
||||||
|
description,
|
||||||
}: ErrorAlertProps) {
|
}: ErrorAlertProps) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
@ -116,6 +118,20 @@ export default function ErrorAlert({
|
|||||||
)}
|
)}
|
||||||
<strong>{title}</strong>
|
<strong>{title}</strong>
|
||||||
</LeftSideContent>
|
</LeftSideContent>
|
||||||
|
{!isExpandable && !description && (
|
||||||
|
<span
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
className="link"
|
||||||
|
onClick={() => setIsModalOpen(true)}
|
||||||
|
>
|
||||||
|
{t('See more')}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{description && (
|
||||||
|
<div className="error-body">
|
||||||
|
<p>{description}</p>
|
||||||
{!isExpandable && (
|
{!isExpandable && (
|
||||||
<span
|
<span
|
||||||
role="button"
|
role="button"
|
||||||
@ -127,6 +143,7 @@ export default function ErrorAlert({
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
{isExpandable ? (
|
{isExpandable ? (
|
||||||
<div className="error-body">
|
<div className="error-body">
|
||||||
<p>{subtitle}</p>
|
<p>{subtitle}</p>
|
||||||
|
@ -32,6 +32,7 @@ type Props = {
|
|||||||
copyText?: string;
|
copyText?: string;
|
||||||
stackTrace?: string;
|
stackTrace?: string;
|
||||||
source?: ErrorSource;
|
source?: ErrorSource;
|
||||||
|
description?: string;
|
||||||
errorMitigationFunction?: () => void;
|
errorMitigationFunction?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -43,6 +44,7 @@ export default function ErrorMessageWithStackTrace({
|
|||||||
link,
|
link,
|
||||||
stackTrace,
|
stackTrace,
|
||||||
source,
|
source,
|
||||||
|
description,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
// Check if a custom error message component was registered for this message
|
// Check if a custom error message component was registered for this message
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -66,6 +68,7 @@ export default function ErrorMessageWithStackTrace({
|
|||||||
title={title}
|
title={title}
|
||||||
subtitle={subtitle}
|
subtitle={subtitle}
|
||||||
copyText={copyText}
|
copyText={copyText}
|
||||||
|
description={description}
|
||||||
source={source}
|
source={source}
|
||||||
body={
|
body={
|
||||||
link || stackTrace ? (
|
link || stackTrace ? (
|
||||||
|
@ -42,6 +42,7 @@ import IconButton from 'src/components/IconButton';
|
|||||||
import InfoTooltip from 'src/components/InfoTooltip';
|
import InfoTooltip from 'src/components/InfoTooltip';
|
||||||
import withToasts from 'src/components/MessageToasts/withToasts';
|
import withToasts from 'src/components/MessageToasts/withToasts';
|
||||||
import ValidatedInput from 'src/components/Form/LabeledErrorBoundInput';
|
import ValidatedInput from 'src/components/Form/LabeledErrorBoundInput';
|
||||||
|
import ErrorMessageWithStackTrace from 'src/components/ErrorMessage/ErrorMessageWithStackTrace';
|
||||||
import ErrorAlert from 'src/components/ImportModal/ErrorAlert';
|
import ErrorAlert from 'src/components/ImportModal/ErrorAlert';
|
||||||
import {
|
import {
|
||||||
testDatabaseConnection,
|
testDatabaseConnection,
|
||||||
@ -64,7 +65,6 @@ import ExtraOptions from './ExtraOptions';
|
|||||||
import SqlAlchemyForm from './SqlAlchemyForm';
|
import SqlAlchemyForm from './SqlAlchemyForm';
|
||||||
import DatabaseConnectionForm from './DatabaseConnectionForm';
|
import DatabaseConnectionForm from './DatabaseConnectionForm';
|
||||||
import {
|
import {
|
||||||
antDErrorAlertStyles,
|
|
||||||
antDAlertStyles,
|
antDAlertStyles,
|
||||||
antdWarningAlertStyles,
|
antdWarningAlertStyles,
|
||||||
StyledAlertMargin,
|
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 {
|
interface DatabaseModalProps {
|
||||||
addDangerToast: (msg: string) => void;
|
addDangerToast: (msg: string) => void;
|
||||||
addSuccessToast: (msg: string) => void;
|
addSuccessToast: (msg: string) => void;
|
||||||
@ -475,7 +481,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
|||||||
)?.parameters !== undefined;
|
)?.parameters !== undefined;
|
||||||
const showDBError = validationErrors || dbErrors;
|
const showDBError = validationErrors || dbErrors;
|
||||||
const isEmpty = (data?: Object | null) =>
|
const isEmpty = (data?: Object | null) =>
|
||||||
data && Object.keys(data).length === 0;
|
!data || (data && Object.keys(data).length === 0);
|
||||||
|
|
||||||
const dbModel: DatabaseForm =
|
const dbModel: DatabaseForm =
|
||||||
availableDbs?.databases?.find(
|
availableDbs?.databases?.find(
|
||||||
@ -1126,22 +1132,24 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
|||||||
// eslint-disable-next-line consistent-return
|
// eslint-disable-next-line consistent-return
|
||||||
const errorAlert = () => {
|
const errorAlert = () => {
|
||||||
let alertErrors: string[] = [];
|
let alertErrors: string[] = [];
|
||||||
if (isEmpty(dbErrors) === false) {
|
if (!isEmpty(dbErrors)) {
|
||||||
alertErrors = typeof dbErrors === 'object' ? Object.values(dbErrors) : [];
|
alertErrors = typeof dbErrors === 'object' ? Object.values(dbErrors) : [];
|
||||||
} else if (db?.engine === Engines.Snowflake) {
|
} else if (!isEmpty(validationErrors)) {
|
||||||
alertErrors =
|
alertErrors =
|
||||||
validationErrors?.error_type === 'GENERIC_DB_ENGINE_ERROR'
|
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) {
|
if (alertErrors.length) {
|
||||||
return (
|
return (
|
||||||
<Alert
|
<ErrorMessageWithStackTrace
|
||||||
type="error"
|
title={t('Database Creation Error')}
|
||||||
css={(theme: SupersetTheme) => antDErrorAlertStyles(theme)}
|
|
||||||
message={t('Database Creation Error')}
|
|
||||||
description={t(alertErrors[0])}
|
description={t(alertErrors[0])}
|
||||||
|
subtitle={t(validationErrors?.description)}
|
||||||
|
copyText={t(validationErrors?.description)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1480,7 +1488,9 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
|||||||
onChange(ActionType.extraEditorChange, payload);
|
onChange(ActionType.extraEditorChange, payload);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{showDBError && errorAlert()}
|
{showDBError && (
|
||||||
|
<ErrorAlertContainer>{errorAlert()}</ErrorAlertContainer>
|
||||||
|
)}
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
</TabsStyled>
|
</TabsStyled>
|
||||||
</Modal>
|
</Modal>
|
||||||
@ -1641,7 +1651,9 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* Step 2 */}
|
{/* Step 2 */}
|
||||||
{showDBError && errorAlert()}
|
{showDBError && (
|
||||||
|
<ErrorAlertContainer>{errorAlert()}</ErrorAlertContainer>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
Loading…
Reference in New Issue
Block a user