Просмотр исходного кода

react-panel: Add CopyToClipboard-component and separate QueryInspector to its own component from QueriesTab

Johannes Schill 7 лет назад
Родитель
Сommit
8254086ecb

+ 67 - 0
public/app/core/components/CopyToClipboard/CopyToClipboard.tsx

@@ -0,0 +1,67 @@
+import React, { PureComponent } from 'react';
+import ClipboardJS from 'clipboard';
+
+interface Props {
+  text: () => string;
+  elType?: string;
+  onSuccess?: (evt: any) => void;
+  onError?: (evt: any) => void;
+  className?: string;
+  children?: JSX.Element | string;
+}
+
+export class CopyToClipboard extends PureComponent<Props> {
+  clipboardjs: any;
+  myRef: any;
+
+  constructor(props) {
+    super(props);
+    this.myRef = React.createRef();
+  }
+
+  componentDidMount() {
+    const { text, onSuccess, onError } = this.props;
+
+    this.clipboardjs = new ClipboardJS(this.myRef.current, {
+      text: text,
+    });
+
+    if (onSuccess) {
+      this.clipboardjs.on('success', evt => {
+        evt.clearSelection();
+        onSuccess(evt);
+      });
+    }
+
+    if (onError) {
+      this.clipboardjs.on('error', evt => {
+        console.error('Action:', evt.action);
+        console.error('Trigger:', evt.trigger);
+        onError(evt);
+      });
+    }
+  }
+
+  componentWillUnmount() {
+    if (this.clipboardjs) {
+      this.clipboardjs.destroy();
+    }
+  }
+
+  getElementType = () => {
+    return this.props.elType || 'button';
+  };
+
+  render() {
+    const { elType, text, children, onError, onSuccess, ...restProps } = this.props;
+
+    return React.createElement(
+      this.getElementType(),
+      {
+        ref: this.myRef,
+        ...restProps,
+      },
+      this.props.children
+    );
+  }
+}

+ 6 - 2
public/app/core/components/JSONFormatter/JSONFormatter.tsx

@@ -7,6 +7,7 @@ interface Props {
   json: {};
   config?: any;
   open?: number;
+  onDidRender?: (formattedJson: any) => void;
 }
 
 export class JSONFormatter extends PureComponent<Props> {
@@ -16,7 +17,6 @@ export class JSONFormatter extends PureComponent<Props> {
     open: 3,
     config: {
       animateOpen: true,
-      theme: 'dark',
     },
   };
 
@@ -29,7 +29,7 @@ export class JSONFormatter extends PureComponent<Props> {
   }
 
   renderJson = () => {
-    const { json, config, open } = this.props;
+    const { json, config, open, onDidRender } = this.props;
     const wrapperEl = this.wrapperRef.current;
     const formatter = new JsonExplorer(json, open, config);
     const hasChildren: boolean = wrapperEl.hasChildNodes();
@@ -38,6 +38,10 @@ export class JSONFormatter extends PureComponent<Props> {
     } else {
       wrapperEl.appendChild(formatter.render());
     }
+
+    if (onDidRender) {
+      onDidRender(formatter.json);
+    }
   };
 
   render() {

+ 6 - 2
public/app/features/dashboard/dashgrid/QueriesTab.tsx

@@ -3,11 +3,11 @@ import DataSourceOption from './DataSourceOption';
 import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
 import { EditorTabBody } from './EditorTabBody';
 import { DataSourcePicker } from './DataSourcePicker';
-import { JSONFormatter } from 'app/core/components/JSONFormatter/JSONFormatter';
 import { PanelModel } from '../panel_model';
 import { DashboardModel } from '../dashboard_model';
 import './../../panel/metrics_tab';
 import config from 'app/core/config';
+import { QueryInspector } from './QueryInspector';
 
 // Services
 import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
@@ -298,7 +298,11 @@ export class QueriesTab extends PureComponent<Props, State> {
 
   renderQueryInspector = () => {
     const { response, isLoading } = this.state.dsQuery;
-    return isLoading ? <LoadingPlaceholder text="Loading query inspector..." /> : <JSONFormatter json={response} />;
+    return isLoading ? (
+      <LoadingPlaceholder text="Loading query inspector..." />
+    ) : (
+      <QueryInspector response={response} />
+    );
   };
 
   renderHelp = () => {

+ 61 - 0
public/app/features/dashboard/dashgrid/QueryInspector.tsx

@@ -0,0 +1,61 @@
+import React, { PureComponent } from 'react';
+import { JSONFormatter } from 'app/core/components/JSONFormatter/JSONFormatter';
+import appEvents from 'app/core/app_events';
+import { CopyToClipboard } from 'app/core/components/CopyToClipboard/CopyToClipboard';
+
+interface Props {
+  response: any;
+}
+
+export class QueryInspector extends PureComponent<Props> {
+  formattedJson: any;
+  clipboard: any;
+
+  constructor(props) {
+    super(props);
+  }
+
+  setFormattedJson = formattedJson => {
+    this.formattedJson = formattedJson;
+  };
+
+  getTextForClipboard = () => {
+    return JSON.stringify(this.formattedJson, null, 2);
+  };
+
+  onClipboardSuccess = () => {
+    appEvents.emit('alert-success', ['Content copied to clipboard']);
+  };
+
+  render() {
+    const { response } = this.props;
+    return (
+      <>
+        {/* <div className="query-troubleshooter__header">
+        <a className="pointer" ng-click="ctrl.toggleMocking()">Mock Response</a>
+        <a className="pointer" ng-click="ctrl.toggleExpand()" ng-hide="ctrl.allNodesExpanded">
+        <i className="fa fa-plus-square-o"></i> Expand All
+        </a>
+        <a className="pointer ng-hide" ng-click="ctrl.toggleExpand()" ng-show="ctrl.allNodesExpanded">
+        <i className="fa fa-minus-square-o"></i> Collapse All
+        </a>
+        <a className="pointer ng-isolate-scope" clipboard-button="ctrl.getClipboardText()"><i className="fa fa-clipboard"></i> Copy to Clipboard</a>
+
+        </div> */}
+        {/* <button onClick={this.copyToClipboard}>Copy</button>
+        <button ref={this.copyButtonRef}>Copy2</button> */}
+
+        <CopyToClipboard
+          className="btn btn-transparent"
+          text={this.getTextForClipboard}
+          onSuccess={this.onClipboardSuccess}
+        >
+          <>
+            <i className="fa fa-clipboard" /> Copy to Clipboard
+          </>
+        </CopyToClipboard>
+        <JSONFormatter json={response} onDidRender={this.setFormattedJson} />
+      </>
+    );
+  }
+}