hughhhh closed pull request #6461: Add copy to clipboard buttons in explore and 
sqllab
URL: https://github.com/apache/incubator-superset/pull/6461
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/superset/assets/spec/javascripts/utils/common_spec.jsx 
b/superset/assets/spec/javascripts/utils/common_spec.jsx
index b6fc39fd42..eabb69e860 100644
--- a/superset/assets/spec/javascripts/utils/common_spec.jsx
+++ b/superset/assets/spec/javascripts/utils/common_spec.jsx
@@ -1,4 +1,4 @@
-import { isTruthy, optionFromValue } from '../../../src/utils/common';
+import { isTruthy, optionFromValue, prepareCopyToClipboardTabularData } from 
'../../../src/utils/common';
 
 describe('utils/common', () => {
   describe('isTruthy', () => {
@@ -48,4 +48,17 @@ describe('utils/common', () => {
       expect(optionFromValue(5)).toEqual({ value: 5, label: '5' });
     });
   });
+  describe('prepareCopyToClipboardTabularData', () => {
+    it('converts empty array', () => {
+      const array = [];
+      expect(prepareCopyToClipboardTabularData(array)).toEqual('');
+    });
+    it('converts non empty array', () => {
+      const array = [
+          { column1: 'lorem', column2: 'ipsum' },
+          { column1: 'dolor', column2: 'sit', column3: 'amet' },
+      ];
+      
expect(prepareCopyToClipboardTabularData(array)).toEqual('lorem\tipsum\ndolor\tsit\tamet\n');
+    });
+  });
 });
diff --git a/superset/assets/src/SqlLab/components/ResultSet.jsx 
b/superset/assets/src/SqlLab/components/ResultSet.jsx
index c7c10cd586..a9416d4140 100644
--- a/superset/assets/src/SqlLab/components/ResultSet.jsx
+++ b/superset/assets/src/SqlLab/components/ResultSet.jsx
@@ -9,6 +9,8 @@ import ExploreResultsButton from './ExploreResultsButton';
 import HighlightedSql from './HighlightedSql';
 import FilterableTable from '../../components/FilterableTable/FilterableTable';
 import QueryStateLabel from './QueryStateLabel';
+import CopyToClipboard from '../../components/CopyToClipboard';
+import { prepareCopyToClipboardTabularData } from '../../utils/common';
 
 const propTypes = {
   actions: PropTypes.object,
@@ -112,6 +114,16 @@ export default class ResultSet extends React.PureComponent 
{
                   <Button bsSize="small" href={'/superset/csv/' + 
this.props.query.id}>
                     <i className="fa fa-file-text-o" /> {t('.CSV')}
                   </Button>}
+
+                <CopyToClipboard
+                  
text={prepareCopyToClipboardTabularData(this.props.query.results.data)}
+                  wrapped={false}
+                  copyNode={
+                    <Button bsSize="small">
+                      <i className="fa fa-clipboard" /> {t('Clipboard')}
+                    </Button>
+                  }
+                />
               </ButtonGroup>
             </div>
             <div className="pull-right">
diff --git a/superset/assets/src/components/CopyToClipboard.jsx 
b/superset/assets/src/components/CopyToClipboard.jsx
index 199e8d430f..433ebcf0c7 100644
--- a/superset/assets/src/components/CopyToClipboard.jsx
+++ b/superset/assets/src/components/CopyToClipboard.jsx
@@ -10,6 +10,7 @@ const propTypes = {
   shouldShowText: PropTypes.bool,
   text: PropTypes.string,
   inMenu: PropTypes.bool,
+  wrapped: PropTypes.bool,
   tooltipText: PropTypes.string,
 };
 
@@ -18,6 +19,7 @@ const defaultProps = {
   onCopyEnd: () => {},
   shouldShowText: true,
   inMenu: false,
+  wrapped: true,
   tooltipText: t('Copy to clipboard'),
 };
 
@@ -94,6 +96,23 @@ export default class CopyToClipboard extends React.Component 
{
     return this.props.tooltipText;
   }
 
+  renderNotWrapped() {
+    const { copyNode } = this.props;
+    return (
+      <OverlayTrigger
+        placement="top"
+        style={{ cursor: 'pointer' }}
+        overlay={this.renderTooltip()}
+        trigger={['hover']}
+        bsStyle="link"
+        onClick={this.onClick}
+        onMouseOut={this.onMouseOut}
+      >
+        {copyNode}
+      </OverlayTrigger>
+    );
+  }
+
   renderLink() {
     return (
       <span>
@@ -139,7 +158,11 @@ export default class CopyToClipboard extends 
React.Component {
   }
 
   render() {
-    return this.props.inMenu ? this.renderInMenu() : this.renderLink();
+    const { wrapped, inMenu } = this.props;
+    if (!wrapped) {
+      return this.renderNotWrapped();
+    }
+    return inMenu ? this.renderInMenu() : this.renderLink();
   }
 }
 
diff --git a/superset/assets/src/explore/components/DisplayQueryButton.jsx 
b/superset/assets/src/explore/components/DisplayQueryButton.jsx
index 042ca24d83..1497e50892 100644
--- a/superset/assets/src/explore/components/DisplayQueryButton.jsx
+++ b/superset/assets/src/explore/components/DisplayQueryButton.jsx
@@ -19,6 +19,7 @@ import Loading from '../../components/Loading';
 import ModalTrigger from './../../components/ModalTrigger';
 import Button from '../../components/Button';
 import RowCountLabel from './RowCountLabel';
+import { prepareCopyToClipboardTabularData } from '../../utils/common';
 
 registerLanguage('markdown', markdownSyntax);
 registerLanguage('html', htmlSyntax);
@@ -130,6 +131,15 @@ export default class DisplayQueryButton extends 
React.PureComponent {
         <Row>
           <Col md={9}>
             <RowCountLabel rowcount={data.length} suffix={t('rows retrieved')} 
/>
+            <CopyToClipboard
+              text={prepareCopyToClipboardTabularData(data)}
+              wrapped={false}
+              copyNode={
+                <Button style={{ padding: '2px 10px', fontSize: '11px' }}>
+                  <i className="fa fa-clipboard" />
+                </Button>
+              }
+            />
           </Col>
           <Col md={3}>
             <FormControl
diff --git a/superset/assets/src/utils/common.js 
b/superset/assets/src/utils/common.js
index 93870c2a8a..89b72e8128 100644
--- a/superset/assets/src/utils/common.js
+++ b/superset/assets/src/utils/common.js
@@ -100,3 +100,11 @@ export function optionFromValue(opt) {
   // From a list of options, handles special values & labels
   return { value: optionValue(opt), label: optionLabel(opt) };
 }
+
+export function prepareCopyToClipboardTabularData(data) {
+  let result = '';
+  for (let i = 0; i < data.length; ++i) {
+    result += Object.values(data[i]).join('\t') + '\n';
+  }
+  return result;
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to