mirror of https://github.com/grafana/grafana
Dashboard: Add dashboard validation warning to save drawer (#55732)
* add api route for validating a dashboard json * add feature flag for showDashboardValidationWarnings * tidy up * comments and messages * swagger specs * fix typo * more swagger * tests! * tidy test a little bit * no more ioutil * api will return different status code depending on validation error * clean up * handle 4xx errors * remove console.log * fix backend tests * tidy up * Swagger: Exclude alpha endpoints Co-authored-by: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com>pull/57002/head
parent
e4b1347ca5
commit
2e16d5499e
@ -0,0 +1,80 @@ |
|||||||
|
import { css } from '@emotion/css'; |
||||||
|
import React from 'react'; |
||||||
|
import { useAsync } from 'react-use'; |
||||||
|
|
||||||
|
import { GrafanaTheme2 } from '@grafana/data'; |
||||||
|
import { FetchError } from '@grafana/runtime'; |
||||||
|
import { Alert, useStyles2 } from '@grafana/ui'; |
||||||
|
import { backendSrv } from 'app/core/services/backend_srv'; |
||||||
|
|
||||||
|
import { DashboardModel } from '../../state'; |
||||||
|
|
||||||
|
interface DashboardValidationProps { |
||||||
|
dashboard: DashboardModel; |
||||||
|
} |
||||||
|
|
||||||
|
type ValidationResponse = Awaited<ReturnType<typeof backendSrv.validateDashboard>>; |
||||||
|
|
||||||
|
function DashboardValidation({ dashboard }: DashboardValidationProps) { |
||||||
|
const styles = useStyles2(getStyles); |
||||||
|
const { loading, value, error } = useAsync(async () => { |
||||||
|
const saveModel = dashboard.getSaveModelClone(); |
||||||
|
const respPromise = backendSrv |
||||||
|
.validateDashboard(saveModel) |
||||||
|
// API returns schema validation errors in 4xx range, so resolve them rather than throwing
|
||||||
|
.catch((err: FetchError<ValidationResponse>) => { |
||||||
|
if (err.status >= 500) { |
||||||
|
throw err; |
||||||
|
} |
||||||
|
|
||||||
|
return err.data; |
||||||
|
}); |
||||||
|
|
||||||
|
return respPromise; |
||||||
|
}, [dashboard]); |
||||||
|
|
||||||
|
let alert: React.ReactNode; |
||||||
|
|
||||||
|
if (loading) { |
||||||
|
alert = <Alert severity="info" title="Checking dashboard validity" />; |
||||||
|
} else if (value) { |
||||||
|
if (!value.isValid) { |
||||||
|
alert = ( |
||||||
|
<Alert severity="warning" title="Dashboard failed schema validation"> |
||||||
|
<p> |
||||||
|
Validation is provided for development purposes and should be safe to ignore. If you are a Grafana |
||||||
|
developer, consider checking and updating the dashboard schema |
||||||
|
</p> |
||||||
|
<div className={styles.error}>{value.message}</div> |
||||||
|
</Alert> |
||||||
|
); |
||||||
|
} |
||||||
|
} else { |
||||||
|
const errorMessage = error?.message ?? 'Unknown error'; |
||||||
|
alert = ( |
||||||
|
<Alert severity="info" title="Error checking dashboard validity"> |
||||||
|
<p className={styles.error}>{errorMessage}</p> |
||||||
|
</Alert> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
if (alert) { |
||||||
|
return <div className={styles.root}>{alert}</div>; |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
const getStyles = (theme: GrafanaTheme2) => ({ |
||||||
|
root: css({ |
||||||
|
marginTop: theme.spacing(1), |
||||||
|
}), |
||||||
|
error: css({ |
||||||
|
fontFamily: theme.typography.fontFamilyMonospace, |
||||||
|
whiteSpace: 'pre-wrap', |
||||||
|
overflowX: 'auto', |
||||||
|
maxWidth: '100%', |
||||||
|
}), |
||||||
|
}); |
||||||
|
|
||||||
|
export default DashboardValidation; |
Loading…
Reference in new issue