Skip to content

Commit

Permalink
URL shortner for dashboards (#4760)
Browse files Browse the repository at this point in the history
* Added support for URLShortLinkButton to work for the dashboard case

* Fix lint errors and test

* Change references to 'slice' to 'chart'.

* Add unit tests to improve coverage

* Fixing lint errors

* Refactor to make URLShortLink more generic. Remove history modification code, redirect should be handling this.

* Remove history modification code, redirect should be handling this

* Generate a shorter link without the directory, and delegate default linked to the contents of window.location

* Fix lint errors

* Fix test_shortner test to check for new pattern

* Remove usage of addHistory to manipulate explore shortlink redirection

* Address build failure and using better practices for shortlink defaults

* Fixing alphabetical order

* More syntax mistakes

* Revert explore view history changes

* Fix use of component props, & rebase
  • Loading branch information
ttannis authored and hughhhh committed Jun 2, 2018
1 parent cc0942a commit dc21e0d
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { describe, it } from 'mocha';
import { shallow } from 'enzyme';

import { OverlayTrigger } from 'react-bootstrap';
import URLShortLinkButton from '../../../../src/explore/components/URLShortLinkButton';
import URLShortLinkButton from '../../../src/components/URLShortLinkButton';

describe('URLShortLinkButton', () => {
const defaultProps = {
slice: {
querystring: () => 'query string',
},
url: 'mockURL',
emailSubject: 'Mock Subject',
emailContent: 'mock content',
};

it('renders', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Popover, OverlayTrigger } from 'react-bootstrap';
import CopyToClipboard from './../../components/CopyToClipboard';
import { getShortUrl } from '../../utils/common';
import { getExploreLongUrl } from '../exploreUtils';
import { t } from '../../locales';
import CopyToClipboard from './CopyToClipboard';
import { getShortUrl } from '../utils/common';
import { t } from '../locales';

const propTypes = {
latestQueryFormData: PropTypes.object.isRequired,
url: PropTypes.string,
emailSubject: PropTypes.string,
emailContent: PropTypes.string,
};

export default class URLShortLinkButton extends React.Component {
Expand All @@ -25,20 +26,19 @@ export default class URLShortLinkButton extends React.Component {
}

getCopyUrl() {
const longUrl = getExploreLongUrl(this.props.latestQueryFormData);
getShortUrl(longUrl, this.onShortUrlSuccess.bind(this));
getShortUrl(this.props.url, this.onShortUrlSuccess.bind(this));
}

renderPopover() {
const emailBody = t('Check out this chart: %s', this.state.shortUrl);
const emailBody = t('%s%s', this.props.emailContent, this.state.shortUrl);
return (
<Popover id="shorturl-popover">
<CopyToClipboard
text={this.state.shortUrl}
copyNode={<i className="fa fa-clipboard" title={t('Copy to clipboard')} />}
/>
&nbsp;&nbsp;
<a href={`mailto:?Subject=Superset%20Slice%20&Body=${emailBody}`}>
<a href={`mailto:?Subject=${this.props.emailSubject}%20&Body=${emailBody}`}>
<i className="fa fa-envelope" />
</a>
</Popover>
Expand All @@ -62,4 +62,10 @@ export default class URLShortLinkButton extends React.Component {
}
}

URLShortLinkButton.defaultProps = {
url: window.location.href.substring(window.location.origin.length),
emailSubject: '',
emailContent: '',
};

URLShortLinkButton.propTypes = propTypes;
7 changes: 7 additions & 0 deletions superset/assets/src/dashboard/components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Controls from './Controls';
import EditableTitle from '../../components/EditableTitle';
import Button from '../../components/Button';
import FaveStar from '../../components/FaveStar';
import URLShortLinkButton from '../../components/URLShortLinkButton';
import InfoTooltipWithTrigger from '../../components/InfoTooltipWithTrigger';
import { t } from '../../locales';

Expand Down Expand Up @@ -92,6 +93,12 @@ class Header extends React.PureComponent {
</h1>
</div>
<div className="pull-right" style={{ marginTop: '35px' }}>
<span className="m-r-5">
<URLShortLinkButton
emailSubject="Superset Dashboard"
emailContent="Check out this dashboard: "
/>
</span>
{this.renderEditButton()}
<Controls
dashboard={dashboard}
Expand Down
11 changes: 8 additions & 3 deletions superset/assets/src/explore/components/ExploreActionButtons.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import URLShortLinkButton from './URLShortLinkButton';
import URLShortLinkButton from '../../components/URLShortLinkButton';
import EmbedCodeButton from './EmbedCodeButton';
import DisplayQueryButton from './DisplayQueryButton';
import { t } from '../../locales';
import { exportChart } from '../exploreUtils';
import { exportChart, getExploreLongUrl } from '../exploreUtils';

const propTypes = {
canDownload: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]).isRequired,
Expand All @@ -25,7 +25,12 @@ export default function ExploreActionButtons({
return (
<div className="btn-group results" role="group">
{latestQueryFormData &&
<URLShortLinkButton latestQueryFormData={latestQueryFormData} />}
<URLShortLinkButton
url={getExploreLongUrl(latestQueryFormData)}
emailSubject="Superset Chart"
emailContent="Check out this chart: "
/>
}

{latestQueryFormData &&
<EmbedCodeButton latestQueryFormData={latestQueryFormData} />}
Expand Down
5 changes: 2 additions & 3 deletions superset/views/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -745,13 +745,12 @@ def index(self, url_id):
@expose('/shortner/', methods=['POST', 'GET'])
def shortner(self):
url = request.form.get('data')
directory = url.split('?')[0][2:]
obj = models.Url(url=url)
db.session.add(obj)
db.session.commit()
return Response(
'{scheme}://{request.headers[Host]}/{directory}?r={obj.id}'.format(
scheme=request.scheme, request=request, directory=directory, obj=obj),
'{scheme}://{request.headers[Host]}/r/{obj.id}'.format(
scheme=request.scheme, request=request, obj=obj),
mimetype='text/plain')

@expose('/msg/')
Expand Down
3 changes: 2 additions & 1 deletion tests/core_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import logging
import os
import random
import re
import string
import unittest

Expand Down Expand Up @@ -377,7 +378,7 @@ def test_shortner(self):
'previous_viz_type=sankey'
)
resp = self.client.post('/r/shortner/', data=dict(data=data))
assert '?r=' in resp.data.decode('utf-8')
assert re.search(r'\/r\/[0-9]+', resp.data.decode('utf-8'))

def test_kv(self):
self.logout()
Expand Down

0 comments on commit dc21e0d

Please sign in to comment.