import omitBy from 'lodash/omitBy'; import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; import { hot } from 'react-hot-loader'; import memoizeOne from 'memoize-one'; import classNames from 'classnames'; import { css } from 'emotion'; import { ExploreId, ExploreItemState, ExploreMode } from 'app/types/explore'; import { DataSourceSelectItem, ToggleButtonGroup, ToggleButton, DataQuery, Tooltip, ButtonSelect, SetInterval, } from '@grafana/ui'; import { RawTimeRange, TimeZone, TimeRange, SelectableValue } from '@grafana/data'; import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker'; import { StoreState } from 'app/types/store'; import { changeDatasource, clearQueries, splitClose, runQueries, splitOpen, changeRefreshInterval, changeMode, clearOrigin, } from './state/actions'; import { updateLocation } from 'app/core/actions'; import { getTimeZone } from '../profile/state/selectors'; import { getDashboardSrv } from '../dashboard/services/DashboardSrv'; import kbn from '../../core/utils/kbn'; import { ExploreTimeControls } from './ExploreTimeControls'; import { LiveTailButton } from './LiveTailButton'; import { ResponsiveButton } from './ResponsiveButton'; import { RunButton } from './RunButton'; import { LiveTailControls } from './useLiveTailControls'; const getStyles = memoizeOne(() => { return { liveTailButtons: css` margin-left: 10px; `, }; }); interface OwnProps { exploreId: ExploreId; onChangeTime: (range: RawTimeRange, changedByScanner?: boolean) => void; } interface StateProps { datasourceMissing: boolean; exploreDatasources: DataSourceSelectItem[]; loading: boolean; range: TimeRange; timeZone: TimeZone; selectedDatasource: DataSourceSelectItem; splitted: boolean; refreshInterval: string; supportedModeOptions: Array>; selectedModeOption: SelectableValue; hasLiveOption: boolean; isLive: boolean; isPaused: boolean; originPanelId: number; queries: DataQuery[]; } interface DispatchProps { changeDatasource: typeof changeDatasource; clearAll: typeof clearQueries; runQueries: typeof runQueries; closeSplit: typeof splitClose; split: typeof splitOpen; changeRefreshInterval: typeof changeRefreshInterval; changeMode: typeof changeMode; clearOrigin: typeof clearOrigin; updateLocation: typeof updateLocation; } type Props = StateProps & DispatchProps & OwnProps; export class UnConnectedExploreToolbar extends PureComponent { constructor(props: Props) { super(props); } onChangeDatasource = async (option: { value: any }) => { this.props.changeDatasource(this.props.exploreId, option.value); }; onClearAll = () => { this.props.clearAll(this.props.exploreId); }; onRunQuery = () => { return this.props.runQueries(this.props.exploreId); }; onChangeRefreshInterval = (item: string) => { const { changeRefreshInterval, exploreId } = this.props; changeRefreshInterval(exploreId, item); }; onModeChange = (mode: ExploreMode) => { const { changeMode, exploreId } = this.props; changeMode(exploreId, mode); }; returnToPanel = async ({ withChanges = false } = {}) => { const { originPanelId } = this.props; const dashboardSrv = getDashboardSrv(); const dash = dashboardSrv.getCurrent(); const titleSlug = kbn.slugifyForUrl(dash.title); if (!withChanges) { this.props.clearOrigin(); } const dashViewOptions = { fullscreen: withChanges || dash.meta.fullscreen, edit: withChanges || dash.meta.isEditing, }; this.props.updateLocation({ path: `/d/${dash.uid}/:${titleSlug}`, query: { ...omitBy(dashViewOptions, v => !v), panelId: originPanelId, }, }); }; render() { const { datasourceMissing, exploreDatasources, closeSplit, exploreId, loading, range, timeZone, selectedDatasource, splitted, refreshInterval, onChangeTime, split, supportedModeOptions, selectedModeOption, hasLiveOption, isLive, isPaused, originPanelId, } = this.props; const styles = getStyles(); const originDashboardIsEditable = Number.isInteger(originPanelId); const panelReturnClasses = classNames('btn', 'navbar-button', { 'btn--radius-right-0': originDashboardIsEditable, 'navbar-button navbar-button--border-right-0': originDashboardIsEditable, }); return (
{exploreId === 'left' && ( Explore )}
{splitted && ( closeSplit(exploreId)}> )}
{!datasourceMissing ? (
{supportedModeOptions.length > 1 ? (
{'Metrics'} {'Logs'}
) : null}
) : null} {Number.isInteger(originPanelId) && !splitted && (
{originDashboardIsEditable && ( this.returnToPanel({ withChanges: true })} maxMenuHeight={380} /> )}
)} {exploreId === 'left' && !splitted ? (
) : null} {!isLive && (
)}
{refreshInterval && }
{hasLiveOption && (
{controls => ( )}
)}
); } } const getModeOptionsMemoized = memoizeOne( ( supportedModes: ExploreMode[], mode: ExploreMode ): [Array>, SelectableValue] => { const supportedModeOptions: Array> = []; let selectedModeOption = null; for (const supportedMode of supportedModes) { switch (supportedMode) { case ExploreMode.Metrics: const option1 = { value: ExploreMode.Metrics, label: ExploreMode.Metrics, }; supportedModeOptions.push(option1); if (mode === ExploreMode.Metrics) { selectedModeOption = option1; } break; case ExploreMode.Logs: const option2 = { value: ExploreMode.Logs, label: ExploreMode.Logs, }; supportedModeOptions.push(option2); if (mode === ExploreMode.Logs) { selectedModeOption = option2; } break; } } return [supportedModeOptions, selectedModeOption]; } ); const mapStateToProps = (state: StoreState, { exploreId }: OwnProps): StateProps => { const splitted = state.explore.split; const exploreItem: ExploreItemState = state.explore[exploreId]; const { datasourceInstance, datasourceMissing, exploreDatasources, range, refreshInterval, loading, supportedModes, mode, isLive, isPaused, originPanelId, queries, } = exploreItem; const selectedDatasource = datasourceInstance ? exploreDatasources.find(datasource => datasource.name === datasourceInstance.name) : undefined; const hasLiveOption = datasourceInstance && datasourceInstance.meta && datasourceInstance.meta.streaming ? true : false; const [supportedModeOptions, selectedModeOption] = getModeOptionsMemoized(supportedModes, mode); return { datasourceMissing, exploreDatasources, loading, range, timeZone: getTimeZone(state.user), selectedDatasource, splitted, refreshInterval, supportedModeOptions, selectedModeOption, hasLiveOption, isLive, isPaused, originPanelId, queries, }; }; const mapDispatchToProps: DispatchProps = { changeDatasource, updateLocation, changeRefreshInterval, clearAll: clearQueries, runQueries, closeSplit: splitClose, split: splitOpen, changeMode: changeMode, clearOrigin, }; export const ExploreToolbar = hot(module)( connect( mapStateToProps, mapDispatchToProps )(UnConnectedExploreToolbar) );