mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
* Chore: Fix TypeScript strict errors with components using connect * Chore: More TypeScript fixes * Chore: Update strict check values * Still need to export these types... * Declare connector at the top of the file * Careful with find and replace...
269 lines
7.6 KiB
TypeScript
269 lines
7.6 KiB
TypeScript
// Libaries
|
|
import React, { PureComponent, FC, ReactNode } from 'react';
|
|
import { connect, ConnectedProps } from 'react-redux';
|
|
// Utils & Services
|
|
import { playlistSrv } from 'app/features/playlist/PlaylistSrv';
|
|
// Components
|
|
import { DashNavButton } from './DashNavButton';
|
|
import { DashNavTimeControls } from './DashNavTimeControls';
|
|
import { ButtonGroup, ModalsController, ToolbarButton, PageToolbar } from '@grafana/ui';
|
|
import { locationUtil, textUtil } from '@grafana/data';
|
|
// State
|
|
import { updateTimeZoneForSession } from 'app/features/profile/state/reducers';
|
|
// Types
|
|
import { DashboardModel } from '../../state';
|
|
import { KioskMode } from 'app/types';
|
|
import { ShareModal } from 'app/features/dashboard/components/ShareModal';
|
|
import { SaveDashboardModalProxy } from 'app/features/dashboard/components/SaveDashboard/SaveDashboardModalProxy';
|
|
import { locationService } from '@grafana/runtime';
|
|
import { toggleKioskMode } from 'app/core/navigation/kiosk';
|
|
import { getDashboardSrv } from '../../services/DashboardSrv';
|
|
|
|
const mapDispatchToProps = {
|
|
updateTimeZoneForSession,
|
|
};
|
|
|
|
const connector = connect(null, mapDispatchToProps);
|
|
|
|
export interface OwnProps {
|
|
dashboard: DashboardModel;
|
|
isFullscreen: boolean;
|
|
kioskMode: KioskMode;
|
|
hideTimePicker: boolean;
|
|
folderTitle?: string;
|
|
title: string;
|
|
onAddPanel: () => void;
|
|
}
|
|
|
|
interface DashNavButtonModel {
|
|
show: (props: Props) => boolean;
|
|
component: FC<Partial<Props>>;
|
|
index?: number | 'end';
|
|
}
|
|
|
|
const customLeftActions: DashNavButtonModel[] = [];
|
|
const customRightActions: DashNavButtonModel[] = [];
|
|
|
|
export function addCustomLeftAction(content: DashNavButtonModel) {
|
|
customLeftActions.push(content);
|
|
}
|
|
|
|
export function addCustomRightAction(content: DashNavButtonModel) {
|
|
customRightActions.push(content);
|
|
}
|
|
|
|
type Props = OwnProps & ConnectedProps<typeof connector>;
|
|
|
|
class DashNav extends PureComponent<Props> {
|
|
constructor(props: Props) {
|
|
super(props);
|
|
}
|
|
|
|
onClose = () => {
|
|
locationService.partial({ viewPanel: null });
|
|
};
|
|
|
|
onToggleTVMode = () => {
|
|
toggleKioskMode();
|
|
};
|
|
|
|
onOpenSettings = () => {
|
|
locationService.partial({ editview: 'settings' });
|
|
};
|
|
|
|
onStarDashboard = () => {
|
|
const { dashboard } = this.props;
|
|
const dashboardSrv = getDashboardSrv();
|
|
|
|
dashboardSrv.starDashboard(dashboard.id, dashboard.meta.isStarred).then((newState: any) => {
|
|
dashboard.meta.isStarred = newState;
|
|
this.forceUpdate();
|
|
});
|
|
};
|
|
|
|
onPlaylistPrev = () => {
|
|
playlistSrv.prev();
|
|
};
|
|
|
|
onPlaylistNext = () => {
|
|
playlistSrv.next();
|
|
};
|
|
|
|
onPlaylistStop = () => {
|
|
playlistSrv.stop();
|
|
this.forceUpdate();
|
|
};
|
|
|
|
addCustomContent(actions: DashNavButtonModel[], buttons: ReactNode[]) {
|
|
actions.map((action, index) => {
|
|
const Component = action.component;
|
|
const element = <Component {...this.props} key={`button-custom-${index}`} />;
|
|
typeof action.index === 'number' ? buttons.splice(action.index, 0, element) : buttons.push(element);
|
|
});
|
|
}
|
|
|
|
isPlaylistRunning() {
|
|
return playlistSrv.isPlaying;
|
|
}
|
|
|
|
renderLeftActionsButton() {
|
|
const { dashboard, kioskMode } = this.props;
|
|
const { canStar, canShare, isStarred } = dashboard.meta;
|
|
const buttons: ReactNode[] = [];
|
|
|
|
if (kioskMode !== KioskMode.Off || this.isPlaylistRunning()) {
|
|
return [];
|
|
}
|
|
|
|
if (canStar) {
|
|
let desc = isStarred ? 'Unmark as favorite' : 'Mark as favorite';
|
|
buttons.push(
|
|
<DashNavButton
|
|
tooltip={desc}
|
|
icon={isStarred ? 'favorite' : 'star'}
|
|
iconType={isStarred ? 'mono' : 'default'}
|
|
iconSize="lg"
|
|
onClick={this.onStarDashboard}
|
|
key="button-star"
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (canShare) {
|
|
let desc = 'Share dashboard or panel';
|
|
buttons.push(
|
|
<ModalsController key="button-share">
|
|
{({ showModal, hideModal }) => (
|
|
<DashNavButton
|
|
tooltip={desc}
|
|
icon="share-alt"
|
|
iconSize="lg"
|
|
onClick={() => {
|
|
showModal(ShareModal, {
|
|
dashboard,
|
|
onDismiss: hideModal,
|
|
});
|
|
}}
|
|
/>
|
|
)}
|
|
</ModalsController>
|
|
);
|
|
}
|
|
|
|
this.addCustomContent(customLeftActions, buttons);
|
|
return buttons;
|
|
}
|
|
|
|
renderPlaylistControls() {
|
|
return (
|
|
<ButtonGroup key="playlist-buttons">
|
|
<ToolbarButton tooltip="Go to previous dashboard" icon="backward" onClick={this.onPlaylistPrev} narrow />
|
|
<ToolbarButton onClick={this.onPlaylistStop}>Stop playlist</ToolbarButton>
|
|
<ToolbarButton tooltip="Go to next dashboard" icon="forward" onClick={this.onPlaylistNext} narrow />
|
|
</ButtonGroup>
|
|
);
|
|
}
|
|
|
|
renderTimeControls() {
|
|
const { dashboard, updateTimeZoneForSession, hideTimePicker } = this.props;
|
|
|
|
if (hideTimePicker) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<DashNavTimeControls dashboard={dashboard} onChangeTimeZone={updateTimeZoneForSession} key="time-controls" />
|
|
);
|
|
}
|
|
|
|
renderRightActionsButton() {
|
|
const { dashboard, onAddPanel, isFullscreen, kioskMode } = this.props;
|
|
const { canEdit, showSettings } = dashboard.meta;
|
|
const { snapshot } = dashboard;
|
|
const snapshotUrl = snapshot && snapshot.originalUrl;
|
|
const buttons: ReactNode[] = [];
|
|
const tvButton = (
|
|
<ToolbarButton tooltip="Cycle view mode" icon="monitor" onClick={this.onToggleTVMode} key="tv-button" />
|
|
);
|
|
|
|
if (this.isPlaylistRunning()) {
|
|
return [this.renderPlaylistControls(), this.renderTimeControls()];
|
|
}
|
|
|
|
if (kioskMode === KioskMode.TV) {
|
|
return [this.renderTimeControls(), tvButton];
|
|
}
|
|
|
|
if (canEdit && !isFullscreen) {
|
|
buttons.push(<ToolbarButton tooltip="Add panel" icon="panel-add" onClick={onAddPanel} key="button-panel-add" />);
|
|
buttons.push(
|
|
<ModalsController key="button-save">
|
|
{({ showModal, hideModal }) => (
|
|
<ToolbarButton
|
|
tooltip="Save dashboard"
|
|
icon="save"
|
|
onClick={() => {
|
|
showModal(SaveDashboardModalProxy, {
|
|
dashboard,
|
|
onDismiss: hideModal,
|
|
});
|
|
}}
|
|
/>
|
|
)}
|
|
</ModalsController>
|
|
);
|
|
}
|
|
|
|
if (snapshotUrl) {
|
|
buttons.push(
|
|
<ToolbarButton
|
|
tooltip="Open original dashboard"
|
|
onClick={() => this.gotoSnapshotOrigin(snapshotUrl)}
|
|
icon="link"
|
|
key="button-snapshot"
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (showSettings) {
|
|
buttons.push(
|
|
<ToolbarButton tooltip="Dashboard settings" icon="cog" onClick={this.onOpenSettings} key="button-settings" />
|
|
);
|
|
}
|
|
|
|
this.addCustomContent(customRightActions, buttons);
|
|
|
|
buttons.push(this.renderTimeControls());
|
|
buttons.push(tvButton);
|
|
return buttons;
|
|
}
|
|
|
|
gotoSnapshotOrigin(snapshotUrl: string) {
|
|
window.location.href = textUtil.sanitizeUrl(snapshotUrl);
|
|
}
|
|
|
|
render() {
|
|
const { isFullscreen, title, folderTitle } = this.props;
|
|
const onGoBack = isFullscreen ? this.onClose : undefined;
|
|
|
|
const titleHref = locationUtil.updateSearchParams(window.location.href, '?search=open');
|
|
const parentHref = locationUtil.updateSearchParams(window.location.href, '?search=open&folder=current');
|
|
|
|
return (
|
|
<PageToolbar
|
|
pageIcon={isFullscreen ? undefined : 'apps'}
|
|
title={title}
|
|
parent={folderTitle}
|
|
titleHref={titleHref}
|
|
parentHref={parentHref}
|
|
onGoBack={onGoBack}
|
|
leftItems={this.renderLeftActionsButton()}
|
|
>
|
|
{this.renderRightActionsButton()}
|
|
</PageToolbar>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default connector(DashNav);
|