diff --git a/ui/src/dashboards/constants/index.ts b/ui/src/dashboards/constants/index.ts index 1997542b3..f6da8cfc0 100644 --- a/ui/src/dashboards/constants/index.ts +++ b/ui/src/dashboards/constants/index.ts @@ -109,11 +109,17 @@ type NewDefaultDashboard = Pick< } > export const DEFAULT_DASHBOARD_NAME = 'Name This Dashboard' + export const NEW_DASHBOARD: NewDefaultDashboard = { name: DEFAULT_DASHBOARD_NAME, cells: [NEW_DEFAULT_DASHBOARD_CELL], } +export const NEW_EMPTY_DASHBOARD: NewDefaultDashboard = { + name: DEFAULT_DASHBOARD_NAME, + cells: [], +} + export const TYPE_QUERY_CONFIG: string = 'queryConfig' export const TYPE_SHIFTED: string = 'shifted queryConfig' export const TYPE_FLUX: string = 'flux' diff --git a/ui/src/dashboards/utils/notes.ts b/ui/src/dashboards/utils/notes.ts index 1004e9731..7efa513c7 100644 --- a/ui/src/dashboards/utils/notes.ts +++ b/ui/src/dashboards/utils/notes.ts @@ -1,3 +1,6 @@ export const humanizeNote = (text: string): string => { - return text.replace(/>/g, '>').replace(/'/g, "'") + if (text) { + return text.replace(/>/g, '>').replace(/'/g, "'") + } + return '' } diff --git a/ui/src/data_explorer/components/SendToDashboardOverlay.tsx b/ui/src/data_explorer/components/SendToDashboardOverlay.tsx index 487803954..e1597cb2c 100644 --- a/ui/src/data_explorer/components/SendToDashboardOverlay.tsx +++ b/ui/src/data_explorer/components/SendToDashboardOverlay.tsx @@ -1,5 +1,6 @@ // Libraries import React, {PureComponent} from 'react' +import _ from 'lodash' // Utils import {getNewDashboardCell} from 'src/dashboards/utils/cellGetters' @@ -20,10 +21,14 @@ import { // Constants import {STATIC_LEGEND} from 'src/dashboards/constants/cellEditor' +import {NEW_EMPTY_DASHBOARD} from 'src/dashboards/constants' // Actions import {addDashboardCellAsync} from 'src/dashboards/actions' +// APIs +import {createDashboard} from 'src/dashboards/apis' + // Types import {QueryConfig, Dashboard, Source, Service, Cell} from 'src/types' import {getDeep} from 'src/utils/wrappers' @@ -48,6 +53,8 @@ interface State { name: string } +const NEW_DASHBOARD_ID = 'new' + class SendToDashboardOverlay extends PureComponent { constructor(props) { super(props) @@ -114,7 +121,8 @@ class SendToDashboardOverlay extends PureComponent { id: d.id.toString(), name: d.name, })) - return simpleArray.map(dashboard => { + + const items = simpleArray.map(dashboard => { return ( { ) }) + + const newDashboardItem = ( + + Send to a New Dashboard + + ) + + const divider = + + return [newDashboardItem, divider, ...items] } private get hasQuery(): boolean { @@ -163,12 +185,12 @@ class SendToDashboardOverlay extends PureComponent { return ComponentStatus.Default } - private handleSelect = (updatedSelection: string[]) => { - this.setState({selectedIDs: updatedSelection}) + private handleSelect = async (selectedIDs: string[]) => { + this.setState({selectedIDs}) } private sendToDashboard = async () => { - const {name} = this.state + const {name, selectedIDs} = this.state const { queryConfig, script, @@ -211,8 +233,16 @@ class SendToDashboardOverlay extends PureComponent { const legend = isStaticLegend ? STATIC_LEGEND : {} + let selectedDashboards = this.selectedDashboards + + if (_.includes(selectedIDs, NEW_DASHBOARD_ID)) { + const {data} = await createDashboard(NEW_EMPTY_DASHBOARD) + const newDashboard: Dashboard = data + selectedDashboards = [...selectedDashboards, newDashboard] + } + await Promise.all( - this.selectedDashboards.map(dashboard => { + selectedDashboards.map(dashboard => { const emptyCell = getNewDashboardCell(dashboard) const newCell: Partial = { ...emptyCell, diff --git a/ui/src/data_explorer/containers/DataExplorer.tsx b/ui/src/data_explorer/containers/DataExplorer.tsx index f2fa521d7..d7acecc0d 100644 --- a/ui/src/data_explorer/containers/DataExplorer.tsx +++ b/ui/src/data_explorer/containers/DataExplorer.tsx @@ -148,7 +148,13 @@ export class DataExplorer extends PureComponent { } public async componentDidMount() { - const {loadDE, timeRange, autoRefresh, queryDrafts} = this.props + const { + loadDE, + timeRange, + autoRefresh, + queryDrafts, + handleGetDashboards, + } = this.props const {query, script} = this.queryString GlobalAutoRefresher.poll(autoRefresh) @@ -173,7 +179,7 @@ export class DataExplorer extends PureComponent { await this.createNewQueryDraft() } - await this.getDashboards() + await handleGetDashboards() this.fetchFluxServices() } @@ -502,14 +508,6 @@ export class DataExplorer extends PureComponent { loadDE([queryDraft], timeRange) } - private async getDashboards() { - const {dashboards, handleGetDashboards} = this.props - - if (!_.isEmpty(dashboards)) { - await handleGetDashboards() - } - } - private get activeScript(): string { const {script} = this.queryString if (script) {