Crawler: use existing render service to generate dashboard thumbnails (#43515)

Co-authored-by: Artur Wierzbicki <artur@arturwierzbicki.com>
This commit is contained in:
Ryan McKinley
2022-01-10 08:21:35 -08:00
committed by GitHub
parent cc9e70be5c
commit b404aae9c3
12 changed files with 475 additions and 134 deletions

View File

@@ -0,0 +1,61 @@
import React, { useState } from 'react';
import { css } from '@emotion/css';
import { Button, CodeEditor, Modal, useTheme2 } from '@grafana/ui';
import { GrafanaTheme2 } from '@grafana/data';
import { getBackendSrv, config } from '@grafana/runtime';
export const CrawlerStartButton = () => {
const styles = getStyles(useTheme2());
const [open, setOpen] = useState(false);
const [body, setBody] = useState({
mode: 'thumbs',
theme: config.theme2.isLight ? 'light' : 'dark',
});
const onDismiss = () => setOpen(false);
const doStart = () => {
getBackendSrv()
.post('/api/admin/crawler/start', body)
.then((v) => {
console.log('GOT', v);
onDismiss();
});
};
return (
<>
<Modal title={'Start crawler'} isOpen={open} onDismiss={onDismiss}>
<div className={styles.wrap}>
<CodeEditor
height={200}
value={JSON.stringify(body, null, 2) ?? ''}
showLineNumbers={false}
readOnly={false}
language="json"
showMiniMap={false}
onBlur={(text: string) => {
setBody(JSON.parse(text)); // force JSON?
}}
/>
</div>
<Modal.ButtonRow>
<Button onClick={doStart}>Start</Button>
<Button variant="secondary" onClick={onDismiss}>
Cancel
</Button>
</Modal.ButtonRow>
</Modal>
<Button onClick={() => setOpen(true)} variant="primary">
Start
</Button>
</>
);
};
const getStyles = (theme: GrafanaTheme2) => {
return {
wrap: css`
border: 2px solid #111;
`,
};
};

View File

@@ -0,0 +1,79 @@
import React, { useEffect, useState } from 'react';
import { css } from '@emotion/css';
import { Button, useTheme2 } from '@grafana/ui';
import { GrafanaTheme2, isLiveChannelMessageEvent, isLiveChannelStatusEvent, LiveChannelScope } from '@grafana/data';
import { getBackendSrv, getGrafanaLiveSrv } from '@grafana/runtime';
import { CrawlerStartButton } from './CrawlerStartButton';
interface CrawlerStatusMessage {
state: string;
started: string;
finished: string;
complete: number;
queue: number;
last: string;
}
export const CrawlerStatus = () => {
const styles = getStyles(useTheme2());
const [status, setStatus] = useState<CrawlerStatusMessage>();
useEffect(() => {
const subscription = getGrafanaLiveSrv()
.getStream<CrawlerStatusMessage>({
scope: LiveChannelScope.Grafana,
namespace: 'broadcast',
path: 'crawler',
})
.subscribe({
next: (evt) => {
if (isLiveChannelMessageEvent(evt)) {
setStatus(evt.message);
} else if (isLiveChannelStatusEvent(evt)) {
setStatus(evt.message);
}
},
});
return () => {
subscription.unsubscribe();
};
}, []);
if (!status) {
return (
<div className={styles.wrap}>
No status (never run)
<br />
<CrawlerStartButton />
</div>
);
}
return (
<div className={styles.wrap}>
<pre>{JSON.stringify(status, null, 2)}</pre>
{status.state !== 'running' && <CrawlerStartButton />}
{status.state !== 'stopped' && (
<Button
variant="secondary"
onClick={() => {
getBackendSrv().post('/api/admin/crawler/stop');
}}
>
Stop
</Button>
)}
</div>
);
};
const getStyles = (theme: GrafanaTheme2) => {
return {
wrap: css`
border: 4px solid red;
`,
running: css`
border: 4px solid green;
`,
};
};

View File

@@ -6,6 +6,8 @@ import { AccessControlAction } from 'app/types';
import { getServerStats, ServerStat } from './state/apis';
import { contextSrv } from '../../core/services/context_srv';
import { Loader } from '../plugins/admin/components/Loader';
import { config } from '@grafana/runtime';
import { CrawlerStatus } from './CrawlerStatus';
export const ServerStats = () => {
const [stats, setStats] = useState<ServerStat | null>(null);
@@ -84,6 +86,8 @@ export const ServerStats = () => {
) : (
<p className={styles.notFound}>No stats found.</p>
)}
{config.featureToggles.dashboardPreviews && <CrawlerStatus />}
</>
);
};