import React, { PureComponent } from 'react'; import { cx, css } from '@emotion/css'; import { GrafanaTheme, SelectableValue } from '@grafana/data'; import { Button, Spinner, Modal, Select, stylesFactory, withTheme, Themeable } from '@grafana/ui'; import { ZBXScript, APIExecuteScriptResponse } from '../../datasource/zabbix/connectors/zabbix_api/types'; import { FAIcon } from '../../components'; interface Props extends Themeable { getScripts(): Promise; onSubmit(data?: ExecScriptData): Promise | any; onDismiss?(): void; } interface State { selectedScript: SelectableValue; scriptOptions: Array>; script: ZBXScript; error: boolean; errorMessage: string | JSX.Element; result: string | JSX.Element; selectError: string; loading: boolean; } export interface ExecScriptData { scriptid: string; } export class ExecScriptModalUnthemed extends PureComponent { scripts: ZBXScript[]; constructor(props) { super(props); this.state = { error: false, errorMessage: '', selectError: '', selectedScript: null, result: '', loading: false, scriptOptions: [], script: null, }; } async componentDidMount() { const scripts = await this.props.getScripts(); this.scripts = scripts; const scriptOptions: Array> = scripts.map((s) => { return { value: s.scriptid, label: s.name, description: s.description || s.command, }; }); const selectedScript = scriptOptions?.length ? scriptOptions[0] : null; const script = scripts.find((s) => selectedScript.value === s.scriptid); this.setState({ scriptOptions, selectedScript, script }); } onChangeSelectedScript = (v: SelectableValue) => { const script = this.scripts.find((s) => v.value === s.scriptid); this.setState({ selectedScript: v, script, errorMessage: '', loading: false, result: '' }); }; dismiss = () => { this.setState({ selectedScript: null, error: false, errorMessage: '', selectError: '', loading: false }); this.props.onDismiss(); }; submit = () => { const { selectedScript } = this.state; if (!selectedScript) { return this.setState({ selectError: 'Select a script to execute.', }); } this.setState({ errorMessage: '', loading: true, result: '' }); const data: ExecScriptData = { scriptid: selectedScript.value, }; this.props .onSubmit(data) .then((result: APIExecuteScriptResponse) => { const message = this.formatResult(result?.value || ''); if (result?.response === 'success') { this.setState({ result: message, loading: false }); } else { this.setState({ error: true, errorMessage: message, loading: false }); } }) .catch((err) => { let errorMessage = err.data?.message || err.data?.error || err.data || err.statusText || ''; errorMessage = this.formatResult(errorMessage); this.setState({ error: true, loading: false, errorMessage, }); }); }; formatResult = (result: string) => { const formatted = result.split('\n').map((p, i) => { return

{p}

; }); return <>{formatted}; }; render() { const { theme } = this.props; const { scriptOptions, selectedScript, script, result, selectError, errorMessage, error } = this.state; const styles = getStyles(theme); const modalClass = cx(styles.modal); const modalTitleClass = cx(styles.modalHeaderTitle); const selectErrorClass = cx('gf-form-hint-text', styles.inputError); const scriptCommandContainerClass = cx('gf-form', styles.scriptCommandContainer); const scriptCommandClass = cx('gf-form-hint-text', styles.scriptCommand); return ( {this.state.loading ? : } Execute script } >