Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
0637a9b
WIP
betodealmeida Jul 18, 2018
90be846
Merge branch 'master' of github.com:apache/incubator-superset into ta…
betodealmeida Jul 26, 2018
3eb8d80
Missing update
betodealmeida Jul 30, 2018
b72066d
Refactor tag component
betodealmeida Jul 30, 2018
01e0616
Decouple tag component from app
betodealmeida Jul 30, 2018
0bc67f6
Working on hooks
betodealmeida Jul 30, 2018
ab8a039
Ready for review
betodealmeida Jul 30, 2018
9516c9e
Minor adjustments
betodealmeida Jul 30, 2018
a64878e
Small fixes
betodealmeida Jul 30, 2018
806e363
Fixing lint and addressing issues
betodealmeida Jul 31, 2018
7f8df3f
Fix import order
betodealmeida Jul 31, 2018
caaeff1
Add polyfills
betodealmeida Jul 31, 2018
4c2ddd5
Fix polyfills
betodealmeida Jul 31, 2018
a5e9e3e
Fix pylint, javascript and mysql
betodealmeida Jul 31, 2018
ea3fc3b
Fix pylint and mysql
betodealmeida Jul 31, 2018
dd3e6cc
Fix javascript lint
betodealmeida Jul 31, 2018
cace713
Fix another unit test
betodealmeida Jul 31, 2018
fedd2d2
Fix javascript tests
betodealmeida Aug 1, 2018
b2ea51e
Fix for MySQL
betodealmeida Aug 1, 2018
c5fc98f
Tag search
betodealmeida Aug 1, 2018
0e1442c
Address comments
betodealmeida Aug 3, 2018
9e0531c
Fix conflict
betodealmeida Aug 3, 2018
dd27890
Merge branch 'master' into tagging_system
betodealmeida Aug 3, 2018
3f04ff8
Fix liny
betodealmeida Aug 3, 2018
c281d28
Merge branch 'tagging_system' of github.com:lyft/incubator-superset i…
betodealmeida Aug 3, 2018
3d67e87
Update constants.js
Aug 3, 2018
1d17894
Fix conflict
betodealmeida Aug 3, 2018
c3f4052
Merge branch 'tagging_system' of github.com:lyft/incubator-superset i…
betodealmeida Aug 3, 2018
b54cf15
Merge heads, remove dep
betodealmeida Aug 3, 2018
72a5193
Move CSRF token to function
betodealmeida Aug 3, 2018
69e74ff
Remove dep
betodealmeida Aug 6, 2018
3acb018
Working on comments
betodealmeida Aug 7, 2018
95daf30
Fix merge
betodealmeida Aug 7, 2018
ca4e555
Small fixes
betodealmeida Aug 7, 2018
dc2055f
Fix CSS
betodealmeida Aug 7, 2018
50c8fbf
Fix unit test
betodealmeida Aug 7, 2018
980cba3
Fix merge conflict
betodealmeida Aug 8, 2018
9b6c1f9
Use uri.js, fix SQL Lab redirect
betodealmeida Aug 8, 2018
b708540
Migration script heads
betodealmeida Aug 8, 2018
04e3478
Default tag search to owned content
betodealmeida Aug 13, 2018
533a9c8
Simplify tag options
betodealmeida Aug 13, 2018
358bddc
Rebase and fix conflict
betodealmeida Sep 14, 2018
e35d053
Remove ObjectTags input
betodealmeida Sep 14, 2018
a0df8d5
Merge heads in alembic
betodealmeida Sep 14, 2018
05319ef
Fix unit test
betodealmeida Sep 16, 2018
234e309
Merge
betodealmeida Jan 24, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion superset/assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
"react-split-pane": "^0.1.66",
"react-sticky": "^6.0.2",
"react-syntax-highlighter": "^7.0.4",
"react-tag-autocomplete": "^5.5.1",
"react-virtualized": "9.19.1",
"react-virtualized-select": "^3.1.3",
"reactable-arc": "0.14.42",
Expand All @@ -131,7 +132,8 @@
"supercluster": "^4.1.1",
"underscore": "^1.8.3",
"urijs": "^1.18.10",
"viewport-mercator-project": "^5.0.0"
"viewport-mercator-project": "^5.0.0",
"whatwg-fetch": "^2.0.4"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would ❤️ approval from @williaster and/or @graceguo-supercat on this import as a preferred method to eventually replace jQuery in the codebase

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah we should definitely be using fetch over jquery 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant was not jquery vs fetch, but npm's fetch package vs whatwg-fetch which are different things. I have no opposition with either but should make a conscious decision.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh I see, whatwg-fetch has 2.7M weekly downloads whereas fetch has 12k, so I'd prob say the former?

},
"devDependencies": {
"@babel/cli": "^7.2.3",
Expand Down
6 changes: 3 additions & 3 deletions superset/assets/spec/javascripts/welcome/Welcome_spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ describe('Welcome', () => {
});
it('renders 4 Tab, Panel, and Row components', () => {
const wrapper = shallow(<Welcome {...mockedProps} />);
expect(wrapper.find(Tab)).toHaveLength(3);
expect(wrapper.find(Panel)).toHaveLength(3);
expect(wrapper.find(Row)).toHaveLength(3);
expect(wrapper.find(Tab)).toHaveLength(4);
expect(wrapper.find(Panel)).toHaveLength(4);
expect(wrapper.find(Row)).toHaveLength(5);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ export default class TemplateParamsEditor extends React.Component {
Assign a set of parameters as <code>JSON</code> below
(example: <code>{'{"my_table": "foo"}'}</code>),
and they become available
in your SQL (example: <code>SELECT * FROM {'{{ my_table }}'} </code>)
by using&nbsp;
in your SQL (example: <code>SELECT * FROM {'{{ my_table }}'}</code>)
by using
{' '}
<a
href="http://superset.apache.org/sqllab.html#templating-with-jinja"
target="_blank"
Expand Down
195 changes: 195 additions & 0 deletions superset/assets/src/components/ObjectTags.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/**
* <div class="react-tags">
* <div class="react-tags__selected">
* <button class="react-tags__selected-tag">
* <span class="react-tags__selected-tag-name" />
* </button>
* </div>
* <div class="react-tags__search">
* <div class="react-tags__search-input">
* <input />
* <div />
* </div>
* <div class="react-tags__suggestions">
* <ul>
* <li class="is-active">
* <mark />
* </li>
* <li class="is-disabled">
* <mark />
* </li>
* </ul>
* </div>
* </div>
*/
.react-tags {
position: relative;
display: inline-block;
padding: 1px 0 0 1px;
margin: 0 10px;
border: 1px solid #F5F5F5;
border-radius: 1px;

/* shared font styles */
font-size: 12px;
line-height: 1.2;

/* clicking anywhere will focus the input */
cursor: text;
}

.react-tags-rw {
display: inline-block;
margin: 0 10px;
font-size: 12px;
line-height: 1.2;
}

.react-tags.is-focused {
border-color: #F0F0F0;
}

.react-tags__selected {
display: inline;
}

.react-tags__selected-tag {
display: inline-block;
box-sizing: border-box;
margin: 0;
padding: 6px 8px;
border: 1px solid #F5F5F5;
border-radius: 2px;
background: #F1F1F1;

/* match the font styles */
font-size: inherit;
line-height: inherit;
}

.react-tags__selected-tag:after {
content: '\2715';
color: #AAA;
margin-left: 8px;
}

.react-tags__selected-tag:hover,
.react-tags__selected-tag:focus {
border-color: #B1B1B1;
}

.react-tags__search {
display: inline-block;

/* match tag layout */
padding: 7px 2px;
margin-bottom: 0;

/* prevent autoresize overflowing the container */
max-width: 100%;
}

@media screen and (min-width: 30em) {

.react-tags__search {
/* this will become the offsetParent for suggestions */
position: relative;
}

}

.react-tags__search input {
/* prevent autoresize overflowing the container */
max-width: 100%;

/* remove styles and layout from this element */
margin: 0;
margin-left: 2px;
padding: 0;
border: 0;
outline: none;

/* match the font styles */
font-size: inherit;
line-height: inherit;
}

.react-tags__search input::-ms-clear {
display: none;
}

.react-tags__suggestions {
position: absolute;
top: 100%;
left: 0;
width: 100%;
z-index: 9999;
}

@media screen and (min-width: 30em) {

.react-tags__suggestions {
width: 240px;
}

}

.react-tags__suggestions ul {
margin: 4px -1px;
padding: 0;
list-style: none;
background: white;
border: 1px solid #D1D1D1;
border-radius: 2px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

.react-tags__suggestions li {
border-bottom: 1px solid #ddd;
padding: 6px 8px;
}

.react-tags__suggestions li mark {
text-decoration: underline;
background: none;
font-weight: 600;
}

.react-tags__suggestions li:hover {
cursor: pointer;
background: #eee;
}

.react-tags__suggestions li.is-active {
background: #b7cfe0;
}

.react-tags__suggestions li.is-disabled {
opacity: 0.5;
cursor: auto;
}

.react-tags span.label {
margin-left: 5px;
padding: 0.3em 0.6em 0.3em;
}

.react-tags a.deco-none {
color: inherit;
text-decoration:none;
}

.react-tags-rw span.label {
margin-left: 5px;
}

.react-tags-rw a.deco-none {
color: inherit;
text-decoration:none;
}

.react-tags span.glyphicon {
cursor: pointer;
margin-left: 3px;
top: 2px;
}
126 changes: 126 additions & 0 deletions superset/assets/src/components/ObjectTags.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import React from 'react';
import PropTypes from 'prop-types';
import ReactTags from 'react-tag-autocomplete';
import { Glyphicon, Label } from 'react-bootstrap';
import TooltipWrapper from './TooltipWrapper';

import './ObjectTags.css';

import { t } from '../locales';

const propTypes = {
fetchTags: PropTypes.func,
fetchSuggestions: PropTypes.func,
deleteTag: PropTypes.func,
addTag: PropTypes.func,
editable: PropTypes.bool,
onChange: PropTypes.func,
};

const defaultProps = {
fetchTags: (callback) => { callback([]); },
fetchSuggestions: (callback) => { callback([]); },
deleteTag: (tag, callback) => { callback(); },
addTag: (tag, callback) => { callback(); },
editable: true,
onChange: () => {},
};

export default class ObjectTags extends React.Component {

constructor(props) {
super(props);
this.state = {
tags: [],
suggestions: [],
};

this.handleDelete = this.handleDelete.bind(this);
this.handleAddition = this.handleAddition.bind(this);
}

componentDidMount() {
this.props.fetchTags(tags => this.setState({ tags }));
this.props.fetchSuggestions(suggestions => this.setState({ suggestions }));
}

handleDelete(i) {
const tags = this.state.tags.slice(0);
const tag = tags.splice(i, 1)[0].name;
this.props.deleteTag(tag, () => this.setState({ tags }));
this.props.onChange(tags);
}

handleAddition(tag) {
const tags = [...this.state.tags, tag];
this.props.addTag(tag.name, () => this.setState({ tags }));
this.props.onChange(tags);
}

renderEditableTags() {
const Tag = props => (
<Label bsStyle="info">
<a
href={`/superset/welcome?tags=${props.tag.name}#tags`}
className="deco-none"
>
{props.tag.name}
</a>
<TooltipWrapper
label="remove"
tooltip={t('Click to remove tag')}
>
<Glyphicon onClick={props.onDelete} glyph="remove" />
</TooltipWrapper>
</Label>
);
const {
fetchTags,
fetchSuggestions,
deleteTag,
addTag,
editable,
onChange,
...rest
} = this.props;
return (
<ReactTags
{...rest}
tags={this.state.tags}
suggestions={this.state.suggestions}
handleDelete={this.handleDelete}
handleAddition={this.handleAddition}
allowNew
placeHolder={t('Add new tag')}
tagComponent={Tag}
/>
);
}

renderReadOnlyTags() {
return (
<div className="react-tags-rw">
{this.state.tags.map(tag => (
<Label bsStyle="info">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs a key prop as explained here.

<a
href={`/superset/welcome?tags=${tag.name}#tags`}
className="deco-none"
>
{tag.name}
</a>
</Label>
))}
</div>
);
}

render() {
if (this.props.editable) {
return this.renderEditableTags();
}
return this.renderReadOnlyTags();
}
}

ObjectTags.propTypes = propTypes;
ObjectTags.defaultProps = defaultProps;
11 changes: 11 additions & 0 deletions superset/assets/src/dashboard/components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import EditableTitle from '../../components/EditableTitle';
import Button from '../../components/Button';
import FaveStar from '../../components/FaveStar';
import UndoRedoKeylisteners from './UndoRedoKeylisteners';
import { addTag, deleteTag, fetchSuggestions, fetchTags } from '../../tags';

import { chartPropShape } from '../util/propShapes';
import {
Expand Down Expand Up @@ -89,6 +90,16 @@ class Header extends React.PureComponent {
this.toggleEditMode = this.toggleEditMode.bind(this);
this.forceRefresh = this.forceRefresh.bind(this);
this.overwriteDashboard = this.overwriteDashboard.bind(this);

const tagOptions = {
objectType: 'dashboard',
objectId: props.dashboardInfo.id,
includeTypes: false,
};
this.fetchTags = fetchTags.bind(this, tagOptions);
this.fetchSuggestions = fetchSuggestions.bind(this, tagOptions);
this.deleteTag = deleteTag.bind(this, tagOptions);
this.addTag = addTag.bind(this, tagOptions);
}

componentWillReceiveProps(nextProps) {
Expand Down
Loading