Add ability to export a dashboard as a json file with chronografVersion
parent
394e2b5569
commit
03528ffa3c
|
@ -1,3 +1,5 @@
|
|||
import _ from 'lodash'
|
||||
|
||||
import {
|
||||
getDashboards as getDashboardsAJAX,
|
||||
updateDashboard as updateDashboardAJAX,
|
||||
|
@ -7,6 +9,7 @@ import {
|
|||
deleteDashboardCell as deleteDashboardCellAJAX,
|
||||
runTemplateVariableQuery,
|
||||
} from 'src/dashboards/apis'
|
||||
import {getMe} from 'src/shared/apis/auth'
|
||||
|
||||
import {notify} from 'shared/actions/notifications'
|
||||
import {errorThrown} from 'shared/actions/errors'
|
||||
|
@ -220,6 +223,16 @@ export const getDashboardsAsync = () => async dispatch => {
|
|||
}
|
||||
}
|
||||
|
||||
export const getChronografVersion = () => async () => {
|
||||
try {
|
||||
const results = await getMe()
|
||||
const version = _.get(results, 'headers.x-chronograf-version')
|
||||
return version
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
const removeUnselectedTemplateValues = dashboard => {
|
||||
const templates = dashboard.templates.map(template => {
|
||||
if (template.type === 'csv') {
|
||||
|
|
|
@ -28,6 +28,7 @@ class DashboardsPageContents extends Component {
|
|||
onDeleteDashboard,
|
||||
onCreateDashboard,
|
||||
onCloneDashboard,
|
||||
onExportDashboard,
|
||||
dashboardLink,
|
||||
} = this.props
|
||||
const {searchTerm} = this.state
|
||||
|
@ -73,6 +74,7 @@ class DashboardsPageContents extends Component {
|
|||
onDeleteDashboard={onDeleteDashboard}
|
||||
onCreateDashboard={onCreateDashboard}
|
||||
onCloneDashboard={onCloneDashboard}
|
||||
onExportDashboard={onExportDashboard}
|
||||
dashboardLink={dashboardLink}
|
||||
/>
|
||||
</div>
|
||||
|
@ -92,6 +94,7 @@ DashboardsPageContents.propTypes = {
|
|||
onDeleteDashboard: func.isRequired,
|
||||
onCreateDashboard: func.isRequired,
|
||||
onCloneDashboard: func.isRequired,
|
||||
onExportDashboard: func.isRequired,
|
||||
dashboardLink: string.isRequired,
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ interface Props {
|
|||
onCloneDashboard: (
|
||||
dashboard: Dashboard
|
||||
) => (event: MouseEvent<HTMLButtonElement>) => void
|
||||
onExportDashboard: (dashboard: Dashboard) => () => void
|
||||
dashboardLink: string
|
||||
}
|
||||
|
||||
|
@ -24,6 +25,7 @@ class DashboardsTable extends PureComponent<Props> {
|
|||
dashboardLink,
|
||||
onCloneDashboard,
|
||||
onDeleteDashboard,
|
||||
onExportDashboard,
|
||||
} = this.props
|
||||
|
||||
if (!dashboards.length) {
|
||||
|
@ -63,6 +65,12 @@ class DashboardsTable extends PureComponent<Props> {
|
|||
replaceWithIfNotAuthorized={<td />}
|
||||
>
|
||||
<td className="text-right">
|
||||
<button
|
||||
className="btn btn-xs btn-default table--show-on-row-hover"
|
||||
onClick={onExportDashboard(dashboard)}
|
||||
>
|
||||
<span className="icon export" />Export
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-xs btn-default table--show-on-row-hover"
|
||||
onClick={onCloneDashboard(dashboard)}
|
||||
|
|
|
@ -3,12 +3,17 @@ import PropTypes from 'prop-types'
|
|||
import {withRouter} from 'react-router'
|
||||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
import download from 'src/external/download'
|
||||
|
||||
import DashboardsHeader from 'src/dashboards/components/DashboardsHeader'
|
||||
import DashboardsContents from 'src/dashboards/components/DashboardsPageContents'
|
||||
|
||||
import {createDashboard} from 'src/dashboards/apis'
|
||||
import {getDashboardsAsync, deleteDashboardAsync} from 'src/dashboards/actions'
|
||||
import {
|
||||
getDashboardsAsync,
|
||||
deleteDashboardAsync,
|
||||
getChronografVersion,
|
||||
} from 'src/dashboards/actions'
|
||||
|
||||
import {NEW_DASHBOARD} from 'src/dashboards/constants'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
@ -44,6 +49,22 @@ class DashboardsPage extends Component {
|
|||
this.props.handleDeleteDashboard(dashboard)
|
||||
}
|
||||
|
||||
handleExportDashboard = dashboard => async () => {
|
||||
const dashboardForDownload = await this.modifyDashboardForDownload(
|
||||
dashboard
|
||||
)
|
||||
download(
|
||||
JSON.stringify(dashboardForDownload),
|
||||
`${dashboard.name}.json`,
|
||||
'text/plain'
|
||||
)
|
||||
}
|
||||
|
||||
modifyDashboardForDownload = async dashboard => {
|
||||
const version = await this.props.handleGetChronografVersion()
|
||||
return {chronografVersion: version, dashboard}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {dashboards} = this.props
|
||||
const dashboardLink = `/sources/${this.props.source.id}`
|
||||
|
@ -57,6 +78,7 @@ class DashboardsPage extends Component {
|
|||
onDeleteDashboard={this.handleDeleteDashboard}
|
||||
onCreateDashboard={this.handleCreateDashboard}
|
||||
onCloneDashboard={this.handleCloneDashboard}
|
||||
onExportDashboard={this.handleExportDashboard}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -79,6 +101,7 @@ DashboardsPage.propTypes = {
|
|||
push: func.isRequired,
|
||||
}).isRequired,
|
||||
handleGetDashboards: func.isRequired,
|
||||
handleGetChronografVersion: func.isRequired,
|
||||
handleDeleteDashboard: func.isRequired,
|
||||
dashboards: arrayOf(shape()),
|
||||
}
|
||||
|
@ -91,6 +114,10 @@ const mapStateToProps = ({dashboardUI: {dashboards, dashboard}}) => ({
|
|||
const mapDispatchToProps = dispatch => ({
|
||||
handleGetDashboards: bindActionCreators(getDashboardsAsync, dispatch),
|
||||
handleDeleteDashboard: bindActionCreators(deleteDashboardAsync, dispatch),
|
||||
handleGetChronografVersion: bindActionCreators(
|
||||
getChronografVersion,
|
||||
dispatch
|
||||
),
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(
|
||||
|
|
Loading…
Reference in New Issue