import React, { PureComponent } from 'react'; import { Spinner, HorizontalGroup } from '@grafana/ui'; import { DashboardModel } from '../../state/DashboardModel'; import { historySrv, RevisionsModel, VersionHistoryTable, VersionHistoryHeader, VersionsHistoryButtons, VersionHistoryComparison, } from '../VersionHistory'; interface Props { dashboard: DashboardModel; } type State = { isLoading: boolean; isAppending: boolean; versions: DecoratedRevisionModel[]; viewMode: 'list' | 'compare'; diffData: { lhs: any; rhs: any }; newInfo?: DecoratedRevisionModel; baseInfo?: DecoratedRevisionModel; isNewLatest: boolean; }; export type DecoratedRevisionModel = RevisionsModel & { createdDateString: string; ageString: string; }; export const VERSIONS_FETCH_LIMIT = 10; export class VersionsSettings extends PureComponent { limit: number; start: number; constructor(props: Props) { super(props); this.limit = VERSIONS_FETCH_LIMIT; this.start = 0; this.state = { isAppending: true, isLoading: true, versions: [], viewMode: 'list', isNewLatest: false, diffData: { lhs: {}, rhs: {}, }, }; } componentDidMount() { this.getVersions(); } getVersions = (append = false) => { this.setState({ isAppending: append }); historySrv .getHistoryList(this.props.dashboard, { limit: this.limit, start: this.start }) .then((res) => { this.setState({ isLoading: false, versions: [...this.state.versions, ...this.decorateVersions(res)], }); this.start += this.limit; }) .catch((err) => console.log(err)) .finally(() => this.setState({ isAppending: false })); }; getDiff = async () => { const selectedVersions = this.state.versions.filter((version) => version.checked); const [newInfo, baseInfo] = selectedVersions; const isNewLatest = newInfo.version === this.props.dashboard.version; this.setState({ isLoading: true, }); const lhs = await historySrv.getDashboardVersion(this.props.dashboard.id, baseInfo.version); const rhs = await historySrv.getDashboardVersion(this.props.dashboard.id, newInfo.version); this.setState({ baseInfo, isLoading: false, isNewLatest, newInfo, viewMode: 'compare', diffData: { lhs: lhs.data, rhs: rhs.data, }, }); }; decorateVersions = (versions: RevisionsModel[]) => versions.map((version) => ({ ...version, createdDateString: this.props.dashboard.formatDate(version.created), ageString: this.props.dashboard.getRelativeTime(version.created), checked: false, })); isLastPage() { return this.state.versions.find((rev) => rev.version === 1); } onCheck = (ev: React.FormEvent, versionId: number) => { this.setState({ versions: this.state.versions.map((version) => version.id === versionId ? { ...version, checked: ev.currentTarget.checked } : version ), }); }; reset = () => { this.setState({ baseInfo: undefined, diffData: { lhs: {}, rhs: {}, }, isNewLatest: false, newInfo: undefined, versions: this.state.versions.map((version) => ({ ...version, checked: false })), viewMode: 'list', }); }; render() { const { versions, viewMode, baseInfo, newInfo, isNewLatest, isLoading, diffData } = this.state; const canCompare = versions.filter((version) => version.checked).length === 2; const showButtons = versions.length > 1; const hasMore = versions.length >= this.limit; if (viewMode === 'compare') { return (
{isLoading ? ( ) : ( )}
); } return (
{isLoading ? ( ) : ( )} {this.state.isAppending && } {showButtons && ( )}
); } } const VersionsHistorySpinner = ({ msg }: { msg: string }) => ( {msg} );