From dc21e0dd789cb23e895de6346ab60890a8790885 Mon Sep 17 00:00:00 2001 From: Tamika Tannis Date: Sat, 2 Jun 2018 11:08:43 -0700 Subject: [PATCH] URL shortner for dashboards (#4760) * 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 --- .../components/URLShortLinkButton_spec.jsx | 8 +++---- .../components/URLShortLinkButton.jsx | 24 ++++++++++++------- .../src/dashboard/components/Header.jsx | 7 ++++++ .../components/ExploreActionButtons.jsx | 11 ++++++--- superset/views/core.py | 5 ++-- tests/core_tests.py | 3 ++- 6 files changed, 38 insertions(+), 20 deletions(-) rename superset/assets/spec/javascripts/{explore => }/components/URLShortLinkButton_spec.jsx (76%) rename superset/assets/src/{explore => }/components/URLShortLinkButton.jsx (65%) diff --git a/superset/assets/spec/javascripts/explore/components/URLShortLinkButton_spec.jsx b/superset/assets/spec/javascripts/components/URLShortLinkButton_spec.jsx similarity index 76% rename from superset/assets/spec/javascripts/explore/components/URLShortLinkButton_spec.jsx rename to superset/assets/spec/javascripts/components/URLShortLinkButton_spec.jsx index 986daaa43..98e6e2cf6 100644 --- a/superset/assets/spec/javascripts/explore/components/URLShortLinkButton_spec.jsx +++ b/superset/assets/spec/javascripts/components/URLShortLinkButton_spec.jsx @@ -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', () => { diff --git a/superset/assets/src/explore/components/URLShortLinkButton.jsx b/superset/assets/src/components/URLShortLinkButton.jsx similarity index 65% rename from superset/assets/src/explore/components/URLShortLinkButton.jsx rename to superset/assets/src/components/URLShortLinkButton.jsx index 223852477..aa9ae96ef 100644 --- a/superset/assets/src/explore/components/URLShortLinkButton.jsx +++ b/superset/assets/src/components/URLShortLinkButton.jsx @@ -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 { @@ -25,12 +26,11 @@ 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 ( } />    - + @@ -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; diff --git a/superset/assets/src/dashboard/components/Header.jsx b/superset/assets/src/dashboard/components/Header.jsx index 52d3024ff..eabd3f4c0 100644 --- a/superset/assets/src/dashboard/components/Header.jsx +++ b/superset/assets/src/dashboard/components/Header.jsx @@ -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'; @@ -92,6 +93,12 @@ class Header extends React.PureComponent {
+ + + {this.renderEditButton()} {latestQueryFormData && - } + + } {latestQueryFormData && } diff --git a/superset/views/core.py b/superset/views/core.py index b4a1689a9..14380c50a 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -745,13 +745,12 @@ class R(BaseSupersetView): @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/') diff --git a/tests/core_tests.py b/tests/core_tests.py index 34d8a6467..dd6e3d891 100644 --- a/tests/core_tests.py +++ b/tests/core_tests.py @@ -13,6 +13,7 @@ import json import logging import os import random +import re import string import unittest @@ -377,7 +378,7 @@ class CoreTests(SupersetTestCase): '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()