You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by cc...@apache.org on 2018/06/22 00:54:22 UTC
[incubator-superset] 07/26: [dashboard builder] improve perf (#4855)
This is an automated email from the ASF dual-hosted git repository.
ccwilliams pushed a commit to branch dashboard-builder
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
commit 22052040dc588739b460f4d07760d2a875171c56
Author: Chris Williams <wi...@users.noreply.github.com>
AuthorDate: Tue Apr 24 11:07:23 2018 -0700
[dashboard builder] improve perf (#4855)
* address major perf + css issues
[dashboard builder] fix dashboard filters and some css
[dashboard builder] use VIZ_TYPES, move stricter .eslintrc to dashboard/, more css fixes
[builder] delete GridCell and GridLayout, remove some unused css. fix broken tabs.
* [builder] fix errors post-rebase
* [builder] add support for custom DragDroppable drag layer and add AddSliceDragPreview
* [AddSliceDragPreview] fix type check
* [dashboard builder] add prettier and update all files
* [dashboard builder] merge v2/ directory int dashboard/
* [dashboard builder] move component/*Container => containers/*
---
superset/assets/images/loading.gif | Bin 16671 -> 1945878 bytes
superset/assets/package.json | 5 +-
superset/assets/src/chart/Chart.jsx | 80 +-
superset/assets/src/chart/ChartContainer.jsx | 22 +-
superset/assets/src/chart/chartReducer.js | 5 +-
superset/assets/src/components/Loading.jsx | 3 +
superset/assets/src/dashboard/{v2 => }/.eslintrc | 6 +-
superset/assets/src/dashboard/.prettierrc | 4 +
.../dashboard/{v2 => }/actions/dashboardLayout.js | 59 +-
.../assets/src/dashboard/actions/dashboardState.js | 58 +-
.../assets/src/dashboard/actions/datasources.js | 3 +-
.../dashboard/{v2 => }/actions/messageToasts.js | 13 +-
.../assets/src/dashboard/actions/sliceEntities.js | 15 +-
.../src/dashboard/components/ActionMenuItem.jsx | 40 +-
.../src/dashboard/components/AddSliceCard.jsx | 59 +
.../{v2 => }/components/BuilderComponentPane.jsx | 15 +-
.../assets/src/dashboard/components/CodeModal.jsx | 10 +-
.../assets/src/dashboard/components/Controls.jsx | 123 +-
.../assets/src/dashboard/components/CssEditor.jsx | 11 +-
.../assets/src/dashboard/components/Dashboard.jsx | 240 +-
.../{v2 => }/components/DashboardBuilder.jsx | 39 +-
.../dashboard/components/DashboardContainer.jsx | 51 -
.../{v2 => }/components/DashboardGrid.jsx | 106 +-
.../{v2 => }/components/DeleteComponentButton.jsx | 7 +-
.../assets/src/dashboard/components/GridCell.jsx | 158 -
.../assets/src/dashboard/components/GridLayout.jsx | 156 -
.../assets/src/dashboard/components/Header.jsx | 117 +-
.../dashboard/{v2 => }/components/IconButton.jsx | 0
.../dashboard/components/RefreshIntervalModal.jsx | 4 +-
.../assets/src/dashboard/components/SaveModal.jsx | 63 +-
.../assets/src/dashboard/components/SliceAdder.jsx | 125 +-
.../dashboard/components/SliceAdderContainer.jsx | 25 -
.../src/dashboard/components/SliceHeader.jsx | 102 +-
.../dashboard/components/SliceHeaderControls.jsx | 29 +-
.../src/dashboard/{v2 => }/components/Toast.jsx | 11 +-
.../{v2 => }/components/ToastPresenter.jsx | 9 +-
.../components/dnd/AddSliceDragPreview.jsx | 70 +
.../{v2 => }/components/dnd/DragDroppable.jsx | 52 +-
.../{v2 => }/components/dnd/DragHandle.jsx | 8 +-
.../{v2 => }/components/dnd/dragDroppableConfig.js | 12 +-
.../{v2 => }/components/dnd/handleDrop.js | 22 +-
.../{v2 => }/components/dnd/handleHover.js | 0
.../dashboard/components/gridComponents/Chart.jsx | 233 ++
.../components/gridComponents/ChartHolder.jsx | 63 +-
.../{v2 => }/components/gridComponents/Column.jsx | 55 +-
.../{v2 => }/components/gridComponents/Divider.jsx | 5 +-
.../{v2 => }/components/gridComponents/Header.jsx | 18 +-
.../{v2 => }/components/gridComponents/Row.jsx | 48 +-
.../{v2 => }/components/gridComponents/Tab.jsx | 26 +-
.../{v2 => }/components/gridComponents/Tabs.jsx | 61 +-
.../{v2 => }/components/gridComponents/index.js | 2 -
.../gridComponents/new/DraggableNewComponent.jsx | 5 +-
.../components/gridComponents/new/NewColumn.jsx | 16 +
.../components/gridComponents/new/NewDivider.jsx | 16 +
.../components/gridComponents/new/NewHeader.jsx | 16 +
.../components/gridComponents/new/NewRow.jsx | 16 +
.../components/gridComponents/new/NewTabs.jsx | 16 +
.../components/menu/BackgroundStyleDropdown.jsx | 0
.../{v2 => }/components/menu/HoverMenu.jsx | 0
.../{v2 => }/components/menu/PopoverDropdown.jsx | 4 +-
.../{v2 => }/components/menu/WithPopoverMenu.jsx | 22 +-
.../components/resizable/ResizableContainer.jsx | 72 +-
.../components/resizable/ResizableHandle.jsx | 12 +-
superset/assets/src/dashboard/containers/Chart.jsx | 59 +
.../assets/src/dashboard/containers/Dashboard.jsx | 49 +
.../{v2 => }/containers/DashboardBuilder.jsx | 18 +-
.../{v2 => }/containers/DashboardComponent.jsx | 44 +-
.../{v2 => }/containers/DashboardGrid.jsx | 16 +-
.../{v2 => }/containers/DashboardHeader.jsx | 48 +-
.../{v2 => }/containers/ToastPresenter.jsx | 0
.../{v2 => }/fixtures/emptyDashboardLayout.js | 4 +-
superset/assets/src/dashboard/index.jsx | 7 +-
.../dashboard/{v2 => }/reducers/dashboardLayout.js | 80 +-
.../src/dashboard/reducers/dashboardState.js | 25 +-
.../assets/src/dashboard/reducers/datasources.js | 9 +-
.../src/dashboard/reducers/getInitialState.js | 26 +-
superset/assets/src/dashboard/reducers/index.js | 12 +-
.../dashboard/{v2 => }/reducers/messageToasts.js | 4 +-
.../assets/src/dashboard/reducers/sliceEntities.js | 10 +-
.../dashboard/reducers/undoableDashboardLayout.js | 27 +
.../{v2 => }/stylesheets/builder-sidepane.less | 28 +-
.../dashboard/{v2 => }/stylesheets/builder.less | 23 +-
.../dashboard/{v2 => }/stylesheets/buttons.less | 0
.../dashboard/stylesheets/components/chart.less | 69 +
.../{v2 => }/stylesheets/components/column.less | 19 +-
.../{v2 => }/stylesheets/components/divider.less | 0
.../{v2 => }/stylesheets/components/header.less | 5 +-
.../{v2 => }/stylesheets/components/index.less | 0
.../stylesheets/components/new-component.less | 0
.../{v2 => }/stylesheets/components/row.less | 19 +-
.../{v2 => }/stylesheets/components/tabs.less | 0
.../src/dashboard/stylesheets/dashboard.less | 104 +
.../src/dashboard/{v2 => }/stylesheets/dnd.less | 2 +-
.../src/dashboard/{v2 => }/stylesheets/grid.less | 14 +-
.../dashboard/{v2 => }/stylesheets/hover-menu.less | 0
.../src/dashboard/{v2 => }/stylesheets/index.less | 2 +
.../{v2 => }/stylesheets/popover-menu.less | 0
.../dashboard/{v2 => }/stylesheets/resizable.less | 26 +-
.../src/dashboard/{v2 => }/stylesheets/toast.less | 5 +-
.../dashboard/{v2 => }/stylesheets/variables.less | 0
.../src/dashboard/util/backgroundStyleOptions.js | 15 +
.../util/charts/getEffectiveExtraFilters.js | 42 +
.../util/charts/getFormDataWithExtraFilters.js | 42 +
.../src/dashboard/util/componentIsResizable.js | 5 +
.../src/dashboard/{v2 => }/util/componentTypes.js | 0
.../src/dashboard/{v2 => }/util/constants.js | 0
.../assets/src/dashboard/util/dashboardHelper.js | 9 -
.../src/dashboard/util/dashboardLayoutConverter.js | 93 +-
.../src/dashboard/{v2 => }/util/dnd-reorder.js | 12 +-
.../dashboard/{v2 => }/util/dropOverflowsParent.js | 26 +-
.../src/dashboard/{v2 => }/util/findParentId.js | 6 +-
.../src/dashboard/util/getChartIdsFromLayout.js | 8 +
.../src/dashboard/{v2 => }/util/getChildWidth.js | 6 +-
.../src/dashboard/{v2 => }/util/getDropPosition.js | 26 +-
.../dashboard/{v2 => }/util/headerStyleOptions.js | 2 +-
.../src/dashboard/{v2 => }/util/isValidChild.js | 28 +-
.../dashboard/{v2 => }/util/newComponentFactory.js | 10 +-
.../dashboard/{v2 => }/util/newEntitiesFromDrop.js | 14 +-
.../src/dashboard/{v2 => }/util/propShapes.jsx | 20 +-
.../src/dashboard/{v2 => }/util/resizableConfig.js | 0
.../{v2 => }/util/shouldWrapChildInRow.js | 0
.../assets/src/dashboard/v2/actions/editMode.js | 9 -
.../src/dashboard/v2/components/Dashboard.jsx | 30 -
.../dashboard/v2/components/DashboardHeader.jsx | 99 -
.../dashboard/v2/components/StaticDashboard.jsx | 19 -
.../v2/components/gridComponents/new/NewChart.jsx | 24 -
.../v2/components/gridComponents/new/NewColumn.jsx | 24 -
.../components/gridComponents/new/NewDivider.jsx | 24 -
.../v2/components/gridComponents/new/NewHeader.jsx | 24 -
.../v2/components/gridComponents/new/NewRow.jsx | 23 -
.../v2/components/gridComponents/new/NewTabs.jsx | 24 -
.../assets/src/dashboard/v2/reducers/editMode.js | 11 -
superset/assets/src/dashboard/v2/reducers/index.js | 8 -
.../dashboard/v2/stylesheets/components/chart.less | 20 -
.../dashboard/v2/util/backgroundStyleOptions.js | 7 -
.../src/dashboard/v2/util/componentIsResizable.js | 13 -
.../src/explore/components/ExploreChartHeader.jsx | 2 +-
.../src/explore/components/ExploreChartPanel.jsx | 15 +-
.../explore/components/ExploreViewContainer.jsx | 2 +-
superset/assets/stylesheets/dashboard.less | 156 -
superset/assets/stylesheets/superset.less | 2 +-
superset/assets/stylesheets/welcome.css | 2 +-
superset/assets/yarn.lock | 3248 ++++----------------
superset/templates/superset/dashboard.html | 7 +-
superset/views/core.py | 2 +-
145 files changed, 2943 insertions(+), 4613 deletions(-)
diff --git a/superset/assets/images/loading.gif b/superset/assets/images/loading.gif
index 01ae393..ae5cbdd 100644
Binary files a/superset/assets/images/loading.gif and b/superset/assets/images/loading.gif differ
diff --git a/superset/assets/package.json b/superset/assets/package.json
index d20dad7..ab440f0 100644
--- a/superset/assets/package.json
+++ b/superset/assets/package.json
@@ -114,7 +114,7 @@
"redux": "^3.5.2",
"redux-localstorage": "^0.4.1",
"redux-thunk": "^2.1.0",
- "redux-undo": "^0.6.1",
+ "redux-undo": "^1.0.0-beta9-9-7",
"shortid": "^2.2.6",
"sprintf-js": "^1.1.1",
"srcdoc-polyfill": "^1.0.0",
@@ -138,8 +138,10 @@
"enzyme": "^2.0.0",
"eslint": "^4.19.0",
"eslint-config-airbnb": "^15.0.1",
+ "eslint-config-prettier": "^2.9.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
+ "eslint-plugin-prettier": "^2.6.0",
"eslint-plugin-react": "^7.0.1",
"exports-loader": "^0.7.0",
"extract-text-webpack-plugin": "3.0.2",
@@ -154,6 +156,7 @@
"less-loader": "^4.0.3",
"mocha": "^3.2.0",
"npm-check-updates": "^2.14.0",
+ "prettier": "^1.12.1",
"react-addons-test-utils": "^15.6.2",
"react-test-renderer": "^15.6.2",
"redux-mock-store": "^1.2.3",
diff --git a/superset/assets/src/chart/Chart.jsx b/superset/assets/src/chart/Chart.jsx
index e9f7c63..4a471e8 100644
--- a/superset/assets/src/chart/Chart.jsx
+++ b/superset/assets/src/chart/Chart.jsx
@@ -73,10 +73,16 @@ class Chart extends React.PureComponent {
componentDidMount() {
if (this.props.triggerQuery) {
- this.props.actions.runQuery(this.props.formData, false,
+ const { formData } = this.props;
+ this.props.actions.runQuery(
+ formData,
+ false,
this.props.timeout,
this.props.chartId,
);
+ } else {
+ // when drag/dropping in a dashboard, a chart may be unmounted/remounted but still have data
+ this.renderViz();
}
}
@@ -89,14 +95,16 @@ class Chart extends React.PureComponent {
}
componentDidUpdate(prevProps) {
- if (this.props.queryResponse &&
+ if (
+ this.props.queryResponse &&
['success', 'rendered'].indexOf(this.props.chartStatus) > -1 &&
!this.props.queryResponse.error && (
- prevProps.annotationData !== this.props.annotationData ||
- prevProps.queryResponse !== this.props.queryResponse ||
- prevProps.height !== this.props.height ||
- prevProps.width !== this.props.width ||
- prevProps.lastRendered !== this.props.lastRendered)
+ prevProps.annotationData !== this.props.annotationData ||
+ prevProps.queryResponse !== this.props.queryResponse ||
+ prevProps.height !== this.props.height ||
+ prevProps.width !== this.props.width ||
+ prevProps.lastRendered !== this.props.lastRendered
+ )
) {
this.renderViz();
}
@@ -123,7 +131,8 @@ class Chart extends React.PureComponent {
}
width() {
- return this.props.width || this.container.el.offsetWidth;
+ return this.props.width ||
+ (this.container && this.container.el && this.container.el.offsetWidth);
}
headerHeight() {
@@ -131,7 +140,8 @@ class Chart extends React.PureComponent {
}
height() {
- return this.props.height || this.container.el.offsetHeight;
+ return this.props.height
+ || (this.container && this.container.el && this.container.el.offsetHeight);
}
d3format(col, number) {
@@ -159,7 +169,6 @@ class Chart extends React.PureComponent {
renderTooltip() {
if (this.state.tooltip) {
- /* eslint-disable react/no-danger */
return (
<Tooltip
className="chart-tooltip"
@@ -169,52 +178,55 @@ class Chart extends React.PureComponent {
positionLeft={this.state.tooltip.x + 30}
arrowOffsetTop={10}
>
- <div dangerouslySetInnerHTML={{ __html: this.state.tooltip.content }} />
+ <div // eslint-disable-next-line react/no-danger
+ dangerouslySetInnerHTML={{ __html: this.state.tooltip.content }}
+ />
</Tooltip>
);
- /* eslint-enable react/no-danger */
}
return null;
}
renderViz() {
- const viz = visMap[this.props.vizType];
- const fd = this.props.formData;
- const qr = this.props.queryResponse;
+ const { vizType, formData, queryResponse, setControlValue, chartId, chartStatus } = this.props;
+ const visRenderer = visMap[vizType];
const renderStart = Logger.getTimestamp();
try {
// Executing user-defined data mutator function
- if (fd.js_data) {
- qr.data = sandboxedEval(fd.js_data)(qr.data);
+ if (formData.js_data) {
+ queryResponse.data = sandboxedEval(formData.js_data)(queryResponse.data);
+ }
+ visRenderer(this, queryResponse, setControlValue);
+ if (chartStatus !== 'rendered') {
+ this.props.actions.chartRenderingSucceeded(chartId);
}
- // [re]rendering the visualization
- viz(this, qr, this.props.setControlValue);
Logger.append(LOG_ACTIONS_RENDER_EVENT, {
- label: 'slice_' + this.props.chartId,
- vis_type: this.props.vizType,
+ label: 'slice_' + chartId,
+ vis_type: vizType,
start_offset: renderStart,
duration: Logger.getTimestamp() - renderStart,
});
- this.props.actions.chartRenderingSucceeded(this.props.chartId);
+ this.props.actions.chartRenderingSucceeded(chartId);
} catch (e) {
- this.props.actions.chartRenderingFailed(e, this.props.chartId);
+ console.error(e); // eslint-disable-line no-console
+ this.props.actions.chartRenderingFailed(e, chartId);
}
}
render() {
const isLoading = this.props.chartStatus === 'loading';
+
+ // this allows <Loading /> to be positioned in the middle of the chart
+ const containerStyles = isLoading ? { height: this.height(), width: this.width() } : null;
return (
- <div className={`${isLoading ? 'is-loading' : ''}`}>
+ <div className={`chart-container ${isLoading ? 'is-loading' : ''}`} style={containerStyles}>
{this.renderTooltip()}
- {isLoading &&
- <Loading size={25} />
- }
+ {isLoading && <Loading size={75} />}
{this.props.chartAlert &&
- <StackTraceMessage
- message={this.props.chartAlert}
- queryResponse={this.props.queryResponse}
- />
- }
+ <StackTraceMessage
+ message={this.props.chartAlert}
+ queryResponse={this.props.queryResponse}
+ />}
{!isLoading &&
!this.props.chartAlert &&
@@ -226,8 +238,8 @@ class Chart extends React.PureComponent {
width={this.width()}
onQuery={this.props.onQuery}
onDismiss={this.props.onDismissRefreshOverlay}
- />
- }
+ />}
+
{!isLoading && !this.props.chartAlert &&
<ChartBody
containerId={this.containerId}
diff --git a/superset/assets/src/chart/ChartContainer.jsx b/superset/assets/src/chart/ChartContainer.jsx
index e3cb1f9..b66fe5d 100644
--- a/superset/assets/src/chart/ChartContainer.jsx
+++ b/superset/assets/src/chart/ChartContainer.jsx
@@ -1,29 +1,13 @@
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
-import * as Actions from './chartAction';
+import * as actions from './chartAction';
import Chart from './Chart';
-function mapStateToProps({ charts }, ownProps) {
- const chart = charts[ownProps.chartId];
- return {
- annotationData: chart.annotationData,
- chartAlert: chart.chartAlert,
- chartStatus: chart.chartStatus,
- chartUpdateEndTime: chart.chartUpdateEndTime,
- chartUpdateStartTime: chart.chartUpdateStartTime,
- latestQueryFormData: chart.latestQueryFormData,
- lastRendered: chart.lastRendered,
- queryResponse: chart.queryResponse,
- queryRequest: chart.queryRequest,
- triggerQuery: chart.triggerQuery,
- };
-}
-
function mapDispatchToProps(dispatch) {
return {
- actions: bindActionCreators(Actions, dispatch),
+ actions: bindActionCreators(actions, dispatch),
};
}
-export default connect(mapStateToProps, mapDispatchToProps)(Chart);
+export default connect(null, mapDispatchToProps)(Chart);
diff --git a/superset/assets/src/chart/chartReducer.js b/superset/assets/src/chart/chartReducer.js
index d57959a..ea8de8b 100644
--- a/superset/assets/src/chart/chartReducer.js
+++ b/superset/assets/src/chart/chartReducer.js
@@ -142,7 +142,10 @@ export default function chartReducer(charts = {}, action) {
}
if (action.type in actionHandlers) {
- return { ...charts, [action.key]: actionHandlers[action.type](charts[action.key], action) };
+ return {
+ ...charts,
+ [action.key]: actionHandlers[action.type](charts[action.key], action),
+ };
}
return charts;
diff --git a/superset/assets/src/components/Loading.jsx b/superset/assets/src/components/Loading.jsx
index 416e770..810c581 100644
--- a/superset/assets/src/components/Loading.jsx
+++ b/superset/assets/src/components/Loading.jsx
@@ -20,6 +20,9 @@ export default function Loading(props) {
padding: 0,
margin: 0,
position: 'absolute',
+ left: '50%',
+ top: '50%',
+ transform: 'translate(-50%, -60%)',
}}
/>
);
diff --git a/superset/assets/src/dashboard/v2/.eslintrc b/superset/assets/src/dashboard/.eslintrc
similarity index 84%
rename from superset/assets/src/dashboard/v2/.eslintrc
rename to superset/assets/src/dashboard/.eslintrc
index 70efc15..a3f86e3 100644
--- a/superset/assets/src/dashboard/v2/.eslintrc
+++ b/superset/assets/src/dashboard/.eslintrc
@@ -1,4 +1,6 @@
{
+ "extends": "prettier",
+ "plugins": ["prettier"],
"rules": {
"prefer-template": 2,
"new-cap": 2,
@@ -12,7 +14,7 @@
"jsx-a11y/anchor-has-content": 2,
"react/require-default-props": 2,
"no-plusplus": 2,
- "no-mixed-operators": 2,
+ "no-mixed-operators": 0,
"no-continue": 2,
"no-bitwise": 2,
"no-undef": 2,
@@ -25,5 +27,7 @@
"import/prefer-default-export": 2,
"react/no-unescaped-entities": 2,
"react/no-string-refs": 2,
+ "react/jsx-indent": 0,
+ "prettier/prettier": "error"
}
}
diff --git a/superset/assets/src/dashboard/.prettierrc b/superset/assets/src/dashboard/.prettierrc
new file mode 100644
index 0000000..a20502b
--- /dev/null
+++ b/superset/assets/src/dashboard/.prettierrc
@@ -0,0 +1,4 @@
+{
+ "singleQuote": true,
+ "trailingComma": "all"
+}
diff --git a/superset/assets/src/dashboard/v2/actions/dashboardLayout.js b/superset/assets/src/dashboard/actions/dashboardLayout.js
similarity index 73%
rename from superset/assets/src/dashboard/v2/actions/dashboardLayout.js
rename to superset/assets/src/dashboard/actions/dashboardLayout.js
index b6d41c4..5a04de5 100644
--- a/superset/assets/src/dashboard/v2/actions/dashboardLayout.js
+++ b/superset/assets/src/dashboard/actions/dashboardLayout.js
@@ -1,6 +1,11 @@
import { addInfoToast } from './messageToasts';
+import { setUnsavedChanges } from './dashboardState';
import { CHART_TYPE, MARKDOWN_TYPE, TABS_TYPE } from '../util/componentTypes';
-import { DASHBOARD_ROOT_ID, NEW_COMPONENTS_SOURCE_ID } from '../util/constants';
+import {
+ DASHBOARD_ROOT_ID,
+ NEW_COMPONENTS_SOURCE_ID,
+ GRID_MIN_COLUMN_COUNT,
+} from '../util/constants';
import dropOverflowsParent from '../util/dropOverflowsParent';
import findParentId from '../util/findParentId';
@@ -62,12 +67,10 @@ export function resizeComponent({ id, width, height }) {
const { dashboardLayout: undoableLayout } = getState();
const { present: dashboard } = undoableLayout;
const component = dashboard[id];
-
- if (
- component &&
- (component.meta.width !== width || component.meta.height !== height)
- ) {
- // update the size of this component + any resizable children
+ const widthChanged = width && component.meta.width !== width;
+ const heightChanged = height && component.meta.height !== height;
+ if (component && (widthChanged || heightChanged)) {
+ // update the size of this component
const updatedComponents = {
[id]: {
...component,
@@ -79,14 +82,16 @@ export function resizeComponent({ id, width, height }) {
},
};
- component.children.forEach((childId) => {
+ // set any resizable children to have a minimum width so that
+ // the chances that they are validly movable to future containers is maximized
+ component.children.forEach(childId => {
const child = dashboard[childId];
if ([CHART_TYPE, MARKDOWN_TYPE].includes(child.type)) {
updatedComponents[childId] = {
...child,
meta: {
...child.meta,
- width: width || child.meta.width,
+ width: GRID_MIN_COLUMN_COUNT,
height: height || child.meta.height,
},
};
@@ -94,6 +99,7 @@ export function resizeComponent({ id, width, height }) {
});
dispatch(updateComponents(updatedComponents));
+ dispatch(setUnsavedChanges(true));
}
};
}
@@ -112,13 +118,18 @@ export function moveComponent(dropResult) {
export const HANDLE_COMPONENT_DROP = 'HANDLE_COMPONENT_DROP';
export function handleComponentDrop(dropResult) {
return (dispatch, getState) => {
- const overflowsParent = dropOverflowsParent(dropResult, getState().dashboardLayout.present);
+ const overflowsParent = dropOverflowsParent(
+ dropResult,
+ getState().dashboardLayout.present,
+ );
if (overflowsParent) {
- return dispatch(addInfoToast(
- `Parent does not have enough space for this component.
+ return dispatch(
+ addInfoToast(
+ `Parent does not have enough space for this component.
Try decreasing its width or add it to a new row.`,
- ));
+ ),
+ );
}
const { source, destination } = dropResult;
@@ -130,12 +141,10 @@ export function handleComponentDrop(dropResult) {
} else if (destination && isNewComponent) {
dispatch(createComponent(dropResult));
} else if (
- destination
- && source
- && !( // ensure it has moved
- destination.id === source.id
- && destination.index === source.index
- )
+ destination &&
+ source &&
+ !// ensure it has moved
+ (destination.id === source.id && destination.index === source.index)
) {
dispatch(moveComponent(dropResult));
}
@@ -146,12 +155,20 @@ export function handleComponentDrop(dropResult) {
const { present: layout } = undoableLayout;
const sourceComponent = layout[source.id];
- if (sourceComponent.type === TABS_TYPE && sourceComponent.children.length === 0) {
- const parentId = findParentId({ childId: source.id, components: layout });
+ if (
+ sourceComponent.type === TABS_TYPE &&
+ sourceComponent.children.length === 0
+ ) {
+ const parentId = findParentId({
+ childId: source.id,
+ components: layout,
+ });
dispatch(deleteComponent(source.id, parentId));
}
}
+ dispatch(setUnsavedChanges(true));
+
return null;
};
}
diff --git a/superset/assets/src/dashboard/actions/dashboardState.js b/superset/assets/src/dashboard/actions/dashboardState.js
index 2262729..d80ec83 100644
--- a/superset/assets/src/dashboard/actions/dashboardState.js
+++ b/superset/assets/src/dashboard/actions/dashboardState.js
@@ -6,6 +6,11 @@ import { chart as initChart } from '../../chart/chartReducer';
import { fetchDatasourceMetadata } from '../../dashboard/actions/datasources';
import { applyDefaultFormData } from '../../explore/stores/store';
+export const SET_UNSAVED_CHANGES = 'SET_UNSAVED_CHANGES';
+export function setUnsavedChanges(hasUnsavedChanges) {
+ return { type: SET_UNSAVED_CHANGES, payload: { hasUnsavedChanges } };
+}
+
export const ADD_FILTER = 'ADD_FILTER';
export function addFilter(chart, col, vals, merge = true, refresh = true) {
return { type: ADD_FILTER, chart, col, vals, merge, refresh };
@@ -39,20 +44,19 @@ export function toggleFaveStar(isStarred) {
export const FETCH_FAVE_STAR = 'FETCH_FAVE_STAR';
export function fetchFaveStar(id) {
- return function (dispatch) {
+ return function fetchFaveStarThunk(dispatch) {
const url = `${FAVESTAR_BASE_URL}/${id}/count`;
- return $.get(url)
- .done((data) => {
- if (data.count > 0) {
- dispatch(toggleFaveStar(true));
- }
- });
+ return $.get(url).done(data => {
+ if (data.count > 0) {
+ dispatch(toggleFaveStar(true));
+ }
+ });
};
}
export const SAVE_FAVE_STAR = 'SAVE_FAVE_STAR';
export function saveFaveStar(id, isStarred) {
- return function (dispatch) {
+ return function saveFaveStarThunk(dispatch) {
const urlSuffix = isStarred ? 'unselect' : 'select';
const url = `${FAVESTAR_BASE_URL}/${id}/${urlSuffix}/`;
$.get(url);
@@ -82,21 +86,29 @@ export function onSave() {
export function fetchCharts(chartList = [], force = false, interval = 0) {
return (dispatch, getState) => {
- const timeout = getState().dashboardInfo.common.conf.SUPERSET_WEBSERVER_TIMEOUT;
+ const timeout = getState().dashboardInfo.common.conf
+ .SUPERSET_WEBSERVER_TIMEOUT;
if (!interval) {
- chartList.forEach(chart => (dispatch(refreshChart(chart, force, timeout))));
+ chartList.forEach(chart => dispatch(refreshChart(chart, force, timeout)));
return;
}
const { metadata: meta } = getState().dashboardInfo;
const refreshTime = Math.max(interval, meta.stagger_time || 5000); // default 5 seconds
if (typeof meta.stagger_refresh !== 'boolean') {
- meta.stagger_refresh = meta.stagger_refresh === undefined ?
- true : meta.stagger_refresh === 'true';
+ meta.stagger_refresh =
+ meta.stagger_refresh === undefined
+ ? true
+ : meta.stagger_refresh === 'true';
}
- const delay = meta.stagger_refresh ? refreshTime / (chartList.length - 1) : 0;
+ const delay = meta.stagger_refresh
+ ? refreshTime / (chartList.length - 1)
+ : 0;
chartList.forEach((chart, i) => {
- setTimeout(() => dispatch(refreshChart(chart, force, timeout)), delay * i);
+ setTimeout(
+ () => dispatch(refreshChart(chart, force, timeout)),
+ delay * i,
+ );
});
};
}
@@ -116,9 +128,9 @@ export function startPeriodicRender(interval) {
const { metadata } = getState().dashboardInfo;
const immune = metadata.timed_refresh_immune_slices || [];
const refreshAll = () => {
- const affected =
- Object.values(getState().charts)
- .filter(chart => immune.indexOf(chart.id) === -1);
+ const affected = Object.values(getState().charts).filter(
+ chart => immune.indexOf(chart.id) === -1,
+ );
return dispatch(fetchCharts(affected, true, interval * 0.2));
};
const fetchAndRender = () => {
@@ -149,17 +161,15 @@ export function addSliceToDashboard(id) {
formData: applyDefaultFormData(form_data),
};
- return Promise
- .all([
- dispatch(addChart(newChart, id)),
- dispatch(fetchDatasourceMetadata(form_data.datasource)),
- ])
- .then(() => dispatch(addSlice(selectedSlice)));
+ return Promise.all([
+ dispatch(addChart(newChart, id)),
+ dispatch(fetchDatasourceMetadata(form_data.datasource)),
+ ]).then(() => dispatch(addSlice(selectedSlice)));
};
}
export function removeSliceFromDashboard(chart) {
- return (dispatch) => {
+ return dispatch => {
dispatch(removeSlice(chart.id));
dispatch(removeChart(chart.id));
};
diff --git a/superset/assets/src/dashboard/actions/datasources.js b/superset/assets/src/dashboard/actions/datasources.js
index a00bb17..d97296e 100644
--- a/superset/assets/src/dashboard/actions/datasources.js
+++ b/superset/assets/src/dashboard/actions/datasources.js
@@ -29,7 +29,8 @@ export function fetchDatasourceMetadata(key) {
type: 'GET',
url,
success: data => dispatch(setDatasource(data, key)),
- error: error => dispatch(fetchDatasourceFailed(error.responseJSON.error, key)),
+ error: error =>
+ dispatch(fetchDatasourceFailed(error.responseJSON.error, key)),
});
};
}
diff --git a/superset/assets/src/dashboard/v2/actions/messageToasts.js b/superset/assets/src/dashboard/actions/messageToasts.js
similarity index 85%
rename from superset/assets/src/dashboard/v2/actions/messageToasts.js
rename to superset/assets/src/dashboard/actions/messageToasts.js
index 2ebc06c..367b36f 100644
--- a/superset/assets/src/dashboard/v2/actions/messageToasts.js
+++ b/superset/assets/src/dashboard/actions/messageToasts.js
@@ -1,7 +1,16 @@
-import { INFO_TOAST, SUCCESS_TOAST, WARNING_TOAST, DANGER_TOAST } from '../util/constants';
+import {
+ INFO_TOAST,
+ SUCCESS_TOAST,
+ WARNING_TOAST,
+ DANGER_TOAST,
+} from '../util/constants';
function getToastUuid(type) {
- return `${Math.random().toString(16).slice(2)}-${type}-${Math.random().toString(16).slice(2)}`;
+ return `${Math.random()
+ .toString(16)
+ .slice(2)}-${type}-${Math.random()
+ .toString(16)
+ .slice(2)}`;
}
export const ADD_TOAST = 'ADD_TOAST';
diff --git a/superset/assets/src/dashboard/actions/sliceEntities.js b/superset/assets/src/dashboard/actions/sliceEntities.js
index 3a1b1dc..6922753 100644
--- a/superset/assets/src/dashboard/actions/sliceEntities.js
+++ b/superset/assets/src/dashboard/actions/sliceEntities.js
@@ -9,16 +9,15 @@ export function updateSliceName(key, sliceName) {
export function saveSliceName(slice, sliceName) {
const oldName = slice.slice_name;
- return (dispatch) => {
+ return dispatch => {
const sliceParams = {};
sliceParams.slice_id = slice.slice_id;
sliceParams.action = 'overwrite';
sliceParams.slice_name = sliceName;
- const url = slice.slice_url + '&' +
- Object.keys(sliceParams)
- .map(key => (key + '=' + sliceParams[key]))
- .join('&');
+ const url = `${slice.slice_url}&${Object.keys(sliceParams)
+ .map(key => `${key}=${sliceParams[key]}`)
+ .join('&')}`;
const key = slice.slice_id;
return $.ajax({
url,
@@ -54,7 +53,7 @@ export function fetchAllSlicesFailed(error) {
export function fetchAllSlices(userId) {
return (dispatch, getState) => {
- const { sliceEntities } = getState();
+ const { sliceEntities } = getState();
if (sliceEntities.lastUpdated === 0) {
dispatch(fetchAllSlicesStarted());
@@ -62,9 +61,9 @@ export function fetchAllSlices(userId) {
return $.ajax({
url: uri,
type: 'GET',
- success: (response) => {
+ success: response => {
const slices = {};
- response.result.forEach((slice) => {
+ response.result.forEach(slice => {
const form_data = JSON.parse(slice.params);
slices[slice.id] = {
slice_id: slice.id,
diff --git a/superset/assets/src/dashboard/components/ActionMenuItem.jsx b/superset/assets/src/dashboard/components/ActionMenuItem.jsx
index aaae4df..a0ecb78 100644
--- a/superset/assets/src/dashboard/components/ActionMenuItem.jsx
+++ b/superset/assets/src/dashboard/components/ActionMenuItem.jsx
@@ -7,9 +7,7 @@ import InfoTooltipWithTrigger from '../../components/InfoTooltipWithTrigger';
export function MenuItemContent({ faIcon, text, tooltip, children }) {
return (
<span>
- {faIcon &&
- <i className={`fa fa-${faIcon}`}> </i>
- }
+ {faIcon && <i className={`fa fa-${faIcon}`}> </i>}
{text} {''}
<InfoTooltipWithTrigger
tooltip={tooltip}
@@ -20,6 +18,7 @@ export function MenuItemContent({ faIcon, text, tooltip, children }) {
</span>
);
}
+
MenuItemContent.propTypes = {
faIcon: PropTypes.string,
text: PropTypes.string,
@@ -27,19 +26,40 @@ MenuItemContent.propTypes = {
children: PropTypes.node,
};
-export function ActionMenuItem(props) {
+MenuItemContent.defaultProps = {
+ faIcon: '',
+ text: '',
+ tooltip: null,
+ children: null,
+};
+
+export function ActionMenuItem({
+ onClick,
+ href,
+ target,
+ text,
+ tooltip,
+ children,
+ faIcon,
+}) {
return (
- <MenuItem
- onClick={props.onClick}
- href={props.href}
- target={props.target}
- >
- <MenuItemContent {...props} />
+ <MenuItem onClick={onClick} href={href} target={target}>
+ <MenuItemContent faIcon={faIcon} text={text} tooltip={tooltip}>
+ {children}
+ </MenuItemContent>
</MenuItem>
);
}
+
ActionMenuItem.propTypes = {
onClick: PropTypes.func,
href: PropTypes.string,
target: PropTypes.string,
+ ...MenuItemContent.propTypes,
+};
+
+ActionMenuItem.defaultProps = {
+ onClick() {},
+ href: null,
+ target: null,
};
diff --git a/superset/assets/src/dashboard/components/AddSliceCard.jsx b/superset/assets/src/dashboard/components/AddSliceCard.jsx
new file mode 100644
index 0000000..7fd9ba4
--- /dev/null
+++ b/superset/assets/src/dashboard/components/AddSliceCard.jsx
@@ -0,0 +1,59 @@
+import cx from 'classnames';
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const propTypes = {
+ datasourceLink: PropTypes.string,
+ innerRef: PropTypes.func,
+ isSelected: PropTypes.bool,
+ lastModified: PropTypes.string.isRequired,
+ sliceName: PropTypes.string.isRequired,
+ style: PropTypes.object,
+ visType: PropTypes.string.isRequired,
+};
+
+const defaultProps = {
+ datasourceLink: '—',
+ innerRef: null,
+ isSelected: false,
+ style: null,
+};
+
+function AddSliceCard({
+ datasourceLink,
+ innerRef,
+ isSelected,
+ lastModified,
+ sliceName,
+ style,
+ visType,
+}) {
+ return (
+ <div ref={innerRef} className="chart-card-container" style={style}>
+ <div className={cx('chart-card', isSelected && 'is-selected')}>
+ <div className="card-title">{sliceName}</div>
+ <div className="card-body">
+ <div className="item">
+ <span>Modified </span>
+ <span>{lastModified}</span>
+ </div>
+ <div className="item">
+ <span>Visualization </span>
+ <span>{visType}</span>
+ </div>
+ <div className="item">
+ <span>Data source </span>
+ <span // eslint-disable-next-line react/no-danger
+ dangerouslySetInnerHTML={{ __html: datasourceLink }}
+ />
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+}
+
+AddSliceCard.propTypes = propTypes;
+AddSliceCard.defaultProps = defaultProps;
+
+export default AddSliceCard;
diff --git a/superset/assets/src/dashboard/v2/components/BuilderComponentPane.jsx b/superset/assets/src/dashboard/components/BuilderComponentPane.jsx
similarity index 85%
rename from superset/assets/src/dashboard/v2/components/BuilderComponentPane.jsx
rename to superset/assets/src/dashboard/components/BuilderComponentPane.jsx
index f9a37cc..e5bc74c 100644
--- a/superset/assets/src/dashboard/v2/components/BuilderComponentPane.jsx
+++ b/superset/assets/src/dashboard/components/BuilderComponentPane.jsx
@@ -6,9 +6,7 @@ import NewDivider from './gridComponents/new/NewDivider';
import NewHeader from './gridComponents/new/NewHeader';
import NewRow from './gridComponents/new/NewRow';
import NewTabs from './gridComponents/new/NewTabs';
-import SliceAdderContainer from '../../../dashboard/components/SliceAdderContainer';
-
-import '../stylesheets/builder-sidepane.less';
+import SliceAdderContainer from '../containers/SliceAdder';
class BuilderComponentPane extends React.PureComponent {
constructor(props) {
@@ -32,9 +30,13 @@ class BuilderComponentPane extends React.PureComponent {
<div className="dashboard-builder-sidepane">
<div className="dashboard-builder-sidepane-header">
Insert components
- {this.state.showSlices &&
- <i className="fa fa-times close trigger" onClick={this.closeSlicesPane} role="none" />
- }
+ {this.state.showSlices && (
+ <i
+ className="fa fa-times close trigger"
+ onClick={this.closeSlicesPane}
+ role="none"
+ />
+ )}
</div>
<div className="component-layer">
@@ -52,7 +54,6 @@ class BuilderComponentPane extends React.PureComponent {
<NewHeader />
<NewDivider />
-
<NewTabs />
<NewRow />
<NewColumn />
diff --git a/superset/assets/src/dashboard/components/CodeModal.jsx b/superset/assets/src/dashboard/components/CodeModal.jsx
index 0e84ad1..cc0c9f2 100644
--- a/superset/assets/src/dashboard/components/CodeModal.jsx
+++ b/superset/assets/src/dashboard/components/CodeModal.jsx
@@ -12,13 +12,16 @@ const propTypes = {
const defaultProps = {
codeCallback: () => {},
+ code: '',
};
export default class CodeModal extends React.PureComponent {
constructor(props) {
super(props);
this.state = { code: props.code };
+ this.beforeOpen = this.beforeOpen.bind(this);
}
+
beforeOpen() {
let code = this.props.code;
if (!code && this.props.codeCallback) {
@@ -26,18 +29,17 @@ export default class CodeModal extends React.PureComponent {
}
this.setState({ code });
}
+
render() {
return (
<ModalTrigger
triggerNode={this.props.triggerNode}
isButton
- beforeOpen={this.beforeOpen.bind(this)}
+ beforeOpen={this.beforeOpen}
modalTitle={t('Active Dashboard Filters')}
modalBody={
<div className="CodeModal">
- <pre>
- {this.state.code}
- </pre>
+ <pre>{this.state.code}</pre>
</div>
}
/>
diff --git a/superset/assets/src/dashboard/components/Controls.jsx b/superset/assets/src/dashboard/components/Controls.jsx
index 8755e8f..06b4f7f 100644
--- a/superset/assets/src/dashboard/components/Controls.jsx
+++ b/superset/assets/src/dashboard/components/Controls.jsx
@@ -1,3 +1,4 @@
+/* global window */
import React from 'react';
import PropTypes from 'prop-types';
import $ from 'jquery';
@@ -8,6 +9,24 @@ import SaveModal from './SaveModal';
import { ActionMenuItem, MenuItemContent } from './ActionMenuItem';
import { t } from '../../locales';
+function updateDom(css) {
+ const className = 'CssEditor-css';
+ const head = document.head || document.getElementsByTagName('head')[0];
+ let style = document.querySelector(`.${className}`);
+
+ if (!style) {
+ style = document.createElement('style');
+ style.className = className;
+ style.type = 'text/css';
+ head.appendChild(style);
+ }
+ if (style.styleSheet) {
+ style.styleSheet.cssText = css;
+ } else {
+ style.innerHTML = css;
+ }
+}
+
const propTypes = {
dashboardInfo: PropTypes.object.isRequired,
dashboardTitle: PropTypes.string.isRequired,
@@ -15,13 +34,18 @@ const propTypes = {
filters: PropTypes.object.isRequired,
expandedSlices: PropTypes.object.isRequired,
slices: PropTypes.array,
- onSave: PropTypes.func,
- onChange: PropTypes.func,
- forceRefreshAllCharts: PropTypes.func,
- startPeriodicRender: PropTypes.func,
+ onSave: PropTypes.func.isRequired,
+ onChange: PropTypes.func.isRequired,
+ forceRefreshAllCharts: PropTypes.func.isRequired,
+ startPeriodicRender: PropTypes.func.isRequired,
editMode: PropTypes.bool,
};
+const defaultProps = {
+ editMode: false,
+ slices: [],
+};
+
class Controls extends React.PureComponent {
constructor(props) {
super(props);
@@ -29,13 +53,12 @@ class Controls extends React.PureComponent {
css: '',
cssTemplates: [],
};
- this.toggleModal = this.toggleModal.bind(this);
- this.updateDom = this.updateDom.bind(this);
}
+
componentWillMount() {
- this.updateDom(this.state.css);
+ updateDom(this.state.css);
- $.get('/csstemplateasyncmodelview/api/read', (data) => {
+ $.get('/csstemplateasyncmodelview/api/read', data => {
const cssTemplates = data.result.map(row => ({
value: row.template_name,
css: row.css,
@@ -44,57 +67,48 @@ class Controls extends React.PureComponent {
this.setState({ cssTemplates });
});
}
- toggleModal(modal) {
- let currentModal;
- if (modal !== this.state.currentModal) {
- currentModal = modal;
- }
- this.setState({ currentModal });
- }
+
changeCss(css) {
this.setState({ css }, () => {
- this.updateDom(css);
+ updateDom(css);
});
this.props.onChange();
}
- updateDom(css) {
- const className = 'CssEditor-css';
- const head = document.head || document.getElementsByTagName('head')[0];
- let style = document.querySelector('.' + className);
- if (!style) {
- style = document.createElement('style');
- style.className = className;
- style.type = 'text/css';
- head.appendChild(style);
- }
- if (style.styleSheet) {
- style.styleSheet.cssText = css;
- } else {
- style.innerHTML = css;
- }
- }
render() {
- const { dashboardTitle, layout, filters, expandedSlices,
- startPeriodicRender, forceRefreshAllCharts, onSave,
- editMode } = this.props;
+ const {
+ dashboardTitle,
+ layout,
+ filters,
+ expandedSlices,
+ startPeriodicRender,
+ forceRefreshAllCharts,
+ onSave,
+ editMode,
+ } = this.props;
+
const emailBody = t('Checkout this dashboard: %s', window.location.href);
- const emailLink = 'mailto:?Subject=Superset%20Dashboard%20'
- + `${dashboardTitle}&Body=${emailBody}`;
- let saveText = t('Save as');
- if (editMode) {
- saveText = t('Save');
- }
+ const emailLink =
+ 'mailto:?Subject=Superset%20Dashboard%20' +
+ `${dashboardTitle}&Body=${emailBody}`;
+
return (
<span>
- <DropdownButton title="Actions" bsSize="small" id="bg-nested-dropdown" pullRight>
+ <DropdownButton
+ title="Actions"
+ bsSize="small"
+ id="bg-nested-dropdown"
+ pullRight
+ >
<ActionMenuItem
text={t('Force Refresh')}
tooltip={t('Force refresh the whole dashboard')}
onClick={forceRefreshAllCharts}
/>
<RefreshIntervalModal
- onChange={refreshInterval => startPeriodicRender(refreshInterval * 1000)}
+ onChange={refreshInterval =>
+ startPeriodicRender(refreshInterval * 1000)
+ }
triggerNode={
<MenuItemContent
text={t('Set autorefresh')}
@@ -112,30 +126,39 @@ class Controls extends React.PureComponent {
css={this.state.css}
triggerNode={
<MenuItemContent
- text={saveText}
+ text={editMode ? t('Save') : t('Save as')}
tooltip={t('Save the dashboard')}
/>
}
+ isMenuItem
/>
- {editMode &&
+ {editMode && (
<ActionMenuItem
text={t('Edit properties')}
tooltip={t("Edit the dashboards's properties")}
- onClick={() => { window.location = `/dashboardmodelview/edit/${this.props.dashboardInfo.id}`; }}
+ onClick={() => {
+ window.location = `/dashboardmodelview/edit/${
+ this.props.dashboardInfo.id
+ }`;
+ }}
/>
- }
- {editMode &&
+ )}
+ {editMode && (
<ActionMenuItem
text={t('Email')}
tooltip={t('Email a link to this dashboard')}
- onClick={() => { window.location = emailLink; }}
+ onClick={() => {
+ window.location = emailLink;
+ }}
/>
- }
+ )}
</DropdownButton>
</span>
);
}
}
+
Controls.propTypes = propTypes;
+Controls.defaultProps = defaultProps;
export default Controls;
diff --git a/superset/assets/src/dashboard/components/CssEditor.jsx b/superset/assets/src/dashboard/components/CssEditor.jsx
index 5abf5f8..45ef86d 100644
--- a/superset/assets/src/dashboard/components/CssEditor.jsx
+++ b/superset/assets/src/dashboard/components/CssEditor.jsx
@@ -29,15 +29,20 @@ class CssEditor extends React.PureComponent {
css: props.initialCss,
cssTemplateOptions: [],
};
+ this.changeCss = this.changeCss.bind(this);
+ this.changeCssTemplate = this.changeCssTemplate.bind(this);
}
+
changeCss(css) {
this.setState({ css }, () => {
this.props.onChange(css);
});
}
+
changeCssTemplate(opt) {
this.changeCss(opt.css);
}
+
renderTemplateSelector() {
if (this.props.templates) {
return (
@@ -46,13 +51,14 @@ class CssEditor extends React.PureComponent {
<Select
options={this.props.templates}
placeholder={t('Load a CSS template')}
- onChange={this.changeCssTemplate.bind(this)}
+ onChange={this.changeCssTemplate}
/>
</div>
);
}
return null;
}
+
render() {
return (
<ModalTrigger
@@ -70,7 +76,7 @@ class CssEditor extends React.PureComponent {
theme="github"
minLines={8}
maxLines={30}
- onChange={this.changeCss.bind(this)}
+ onChange={this.changeCss}
height="200px"
width="100%"
editorProps={{ $blockScrolling: true }}
@@ -85,6 +91,7 @@ class CssEditor extends React.PureComponent {
);
}
}
+
CssEditor.propTypes = propTypes;
CssEditor.defaultProps = defaultProps;
diff --git a/superset/assets/src/dashboard/components/Dashboard.jsx b/superset/assets/src/dashboard/components/Dashboard.jsx
index 939476c..2d85ebf 100644
--- a/superset/assets/src/dashboard/components/Dashboard.jsx
+++ b/superset/assets/src/dashboard/components/Dashboard.jsx
@@ -1,26 +1,36 @@
+/* global window */
import React from 'react';
import PropTypes from 'prop-types';
import AlertsWrapper from '../../components/AlertsWrapper';
-import GridLayout from './GridLayout';
+import getChartIdsFromLayout from '../util/getChartIdsFromLayout';
+import DashboardBuilder from '../containers/DashboardBuilder';
import {
chartPropShape,
slicePropShape,
dashboardInfoPropShape,
dashboardStatePropShape,
-} from '../v2/util/propShapes';
-import { exportChart } from '../../explore/exploreUtils';
+} from '../util/propShapes';
import { areObjectsEqual } from '../../reduxUtils';
-import { getChartIdsFromLayout } from '../util/dashboardHelper';
-import { Logger, ActionLog, LOG_ACTIONS_PAGE_LOAD,
- LOG_ACTIONS_LOAD_EVENT, LOG_ACTIONS_RENDER_EVENT } from '../../logger';
+import getFormDataWithExtraFilters from '../util/charts/getFormDataWithExtraFilters';
+import {
+ Logger,
+ ActionLog,
+ LOG_ACTIONS_PAGE_LOAD,
+ LOG_ACTIONS_LOAD_EVENT,
+ LOG_ACTIONS_RENDER_EVENT,
+} from '../../logger';
import { t } from '../../locales';
-import '../../../stylesheets/dashboard.less';
-import '../v2/stylesheets/index.less';
+import '../stylesheets/index.less';
const propTypes = {
- actions: PropTypes.object.isRequired,
+ actions: PropTypes.shape({
+ addSliceToDashboard: PropTypes.func.isRequired,
+ onChange: PropTypes.func.isRequired,
+ removeSliceFromDashboard: PropTypes.func.isRequired,
+ runQuery: PropTypes.func.isRequired,
+ }).isRequired,
dashboardInfo: dashboardInfoPropShape.isRequired,
dashboardState: dashboardStatePropShape.isRequired,
charts: PropTypes.objectOf(chartPropShape).isRequired,
@@ -40,6 +50,20 @@ const defaultProps = {
};
class Dashboard extends React.PureComponent {
+ static onBeforeUnload(hasChanged) {
+ if (hasChanged) {
+ window.addEventListener('beforeunload', Dashboard.unload);
+ } else {
+ window.removeEventListener('beforeunload', Dashboard.unload);
+ }
+ }
+
+ static unload() {
+ const message = t('You have unsaved changes.');
+ window.event.returnValue = message; // Gecko + IE
+ return message; // Gecko + Webkit, Safari, Chrome etc.
+ }
+
constructor(props) {
super(props);
@@ -52,31 +76,15 @@ class Dashboard extends React.PureComponent {
eventNames: [LOG_ACTIONS_LOAD_EVENT, LOG_ACTIONS_RENDER_EVENT],
});
Logger.start(this.loadingLog);
-
- this.rerenderCharts = this.rerenderCharts.bind(this);
- this.getFilters = this.getFilters.bind(this);
- this.refreshExcept = this.refreshExcept.bind(this);
- this.getFormDataExtra = this.getFormDataExtra.bind(this);
- this.exploreChart = this.exploreChart.bind(this);
- this.exportCSV = this.exportCSV.bind(this);
-
- this.props.actions.saveSliceName = this.props.actions.saveSliceName.bind(this);
- this.props.actions.removeSliceFromDashboard =
- this.props.actions.removeSliceFromDashboard.bind(this);
- this.props.actions.toggleExpandSlice =
- this.props.actions.toggleExpandSlice.bind(this);
- this.props.actions.addFilter = this.props.actions.addFilter.bind(this);
- this.props.actions.removeFilter = this.props.actions.removeFilter.bind(this);
- }
-
- componentDidMount() {
- window.addEventListener('resize', this.rerenderCharts);
}
componentWillReceiveProps(nextProps) {
- if (this.firstLoad &&
- Object.values(nextProps.charts)
- .every(chart => (['rendered', 'failed', 'stopped'].indexOf(chart.chartStatus) > -1))
+ if (
+ this.firstLoad &&
+ Object.values(nextProps.charts).every(
+ chart =>
+ ['rendered', 'failed', 'stopped'].indexOf(chart.chartStatus) > -1,
+ )
) {
Logger.end(this.loadingLog);
this.firstLoad = false;
@@ -86,13 +94,19 @@ class Dashboard extends React.PureComponent {
const nextChartIds = getChartIdsFromLayout(nextProps.layout);
if (currentChartIds.length < nextChartIds.length) {
// adding new chart
- const newChartId = nextChartIds.find(key => (currentChartIds.indexOf(key) === -1));
+ const newChartId = nextChartIds.find(
+ key => currentChartIds.indexOf(key) === -1,
+ );
this.props.actions.addSliceToDashboard(newChartId);
this.props.actions.onChange();
} else if (currentChartIds.length > nextChartIds.length) {
// remove chart
- const removedChartId = currentChartIds.find(key => (nextChartIds.indexOf(key) === -1));
- this.props.actions.removeSliceFromDashboard(this.props.charts[removedChartId]);
+ const removedChartId = currentChartIds.find(
+ key => nextChartIds.indexOf(key) === -1,
+ );
+ this.props.actions.removeSliceFromDashboard(
+ this.props.charts[removedChartId],
+ );
this.props.actions.onChange();
}
}
@@ -101,11 +115,15 @@ class Dashboard extends React.PureComponent {
const { refresh, filters, hasUnsavedChanges } = this.props.dashboardState;
if (refresh) {
let changedFilterKey;
- const prevFiltersKeySet = new Set(Object.keys(prevProps.dashboardState.filters));
- Object.keys(filters).some((key) => {
+ const prevFiltersKeySet = new Set(
+ Object.keys(prevProps.dashboardState.filters),
+ );
+ Object.keys(filters).some(key => {
prevFiltersKeySet.delete(key);
- if (prevProps.dashboardState.filters[key] === undefined ||
- !areObjectsEqual(prevProps.dashboardState.filters[key], filters[key])) {
+ if (
+ prevProps.dashboardState.filters[key] === undefined ||
+ !areObjectsEqual(prevProps.dashboardState.filters[key], filters[key])
+ ) {
changedFilterKey = key;
return true;
}
@@ -118,21 +136,9 @@ class Dashboard extends React.PureComponent {
}
if (hasUnsavedChanges) {
- this.onBeforeUnload(true);
- } else {
- this.onBeforeUnload(false);
- }
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this.rerenderCharts);
- }
-
- onBeforeUnload(hasChanged) {
- if (hasChanged) {
- window.addEventListener('beforeunload', this.unload);
+ Dashboard.onBeforeUnload(true);
} else {
- window.removeEventListener('beforeunload', this.unload);
+ Dashboard.onBeforeUnload(false);
}
}
@@ -141,131 +147,37 @@ class Dashboard extends React.PureComponent {
return Object.values(this.props.charts);
}
- getFormDataExtra(chart) {
- const extraFilters = this.effectiveExtraFilters(chart.id);
- const formDataExtra = {
- ...chart.formData,
- extra_filters: extraFilters,
- };
- return formDataExtra;
- }
-
- getFilters(sliceId) {
- return this.props.dashboardState.filters[sliceId];
- }
-
- unload() {
- const message = t('You have unsaved changes.');
- window.event.returnValue = message; // Gecko + IE
- return message; // Gecko + Webkit, Safari, Chrome etc.
- }
-
- effectiveExtraFilters(sliceId) {
- const metadata = this.props.dashboardInfo.metadata;
- const filters = this.props.dashboardState.filters;
- const f = [];
- const immuneSlices = metadata.filter_immune_slices || [];
- if (sliceId && immuneSlices.includes(sliceId)) {
- // The slice is immune to dashboard filters
- return f;
- }
-
- // Building a list of fields the slice is immune to filters on
- let immuneToFields = [];
- if (
- sliceId &&
- metadata.filter_immune_slice_fields &&
- metadata.filter_immune_slice_fields[sliceId]) {
- immuneToFields = metadata.filter_immune_slice_fields[sliceId];
- }
- for (const filteringSliceId in filters) {
- if (filteringSliceId === sliceId.toString()) {
- // Filters applied by the slice don't apply to itself
- continue;
- }
- for (const field in filters[filteringSliceId]) {
- if (!immuneToFields.includes(field)) {
- f.push({
- col: field,
- op: 'in',
- val: filters[filteringSliceId][field],
- });
- }
- }
- }
- return f;
- }
-
refreshExcept(filterKey) {
const immune = this.props.dashboardInfo.metadata.filter_immune_slices || [];
let charts = this.getAllCharts();
if (filterKey) {
charts = charts.filter(
- chart => (String(chart.id) !== filterKey && immune.indexOf(chart.id) === -1),
+ chart =>
+ String(chart.id) !== filterKey && immune.indexOf(chart.id) === -1,
);
}
- charts.forEach((chart) => {
- const updatedFormData = this.getFormDataExtra(chart);
- this.props.actions.runQuery(updatedFormData, false, this.props.timeout, chart.id);
- });
- }
-
- exploreChart(chartId) {
- const chart = this.props.charts[chartId];
- const formData = this.getFormDataExtra(chart);
- exportChart(formData);
- }
-
- exportCSV(chartId) {
- const chart = this.props.charts[chartId];
- const formData = this.getFormDataExtra(chart);
- exportChart(formData, 'csv');
- }
+ charts.forEach(chart => {
+ const updatedFormData = getFormDataWithExtraFilters({
+ chart,
+ dashboardMetadata: this.props.dashboardInfo.metadata,
+ filters: this.props.dashboardState.filters,
+ sliceId: chart.id,
+ });
- // re-render chart without fetch
- rerenderCharts() {
- this.getAllCharts().forEach((chart) => {
- setTimeout(() => {
- this.props.actions.renderTriggered(new Date().getTime(), chart.id);
- }, 50);
+ this.props.actions.runQuery(
+ updatedFormData,
+ false,
+ this.props.timeout,
+ chart.id,
+ );
});
}
render() {
- const {
- expandedSlices = {}, filters, sliceIds,
- editMode, showBuilderPane,
- } = this.props.dashboardState;
-
return (
- <div id="dashboard-container">
- <div>
- <AlertsWrapper initMessages={this.props.initMessages} />
- </div>
- <GridLayout
- dashboardInfo={this.props.dashboardInfo}
- layout={this.props.layout}
- datasources={this.props.datasources}
- slices={this.props.slices}
- sliceIds={sliceIds}
- expandedSlices={expandedSlices}
- filters={filters}
- charts={this.props.charts}
- timeout={this.props.timeout}
- onChange={this.onChange}
- rerenderCharts={this.rerenderCharts}
- getFormDataExtra={this.getFormDataExtra}
- exploreChart={this.exploreChart}
- exportCSV={this.exportCSV}
- refreshChart={this.props.actions.refreshChart}
- saveSliceName={this.props.actions.saveSliceName}
- toggleExpandSlice={this.props.actions.toggleExpandSlice}
- addFilter={this.props.actions.addFilter}
- getFilters={this.getFilters}
- removeFilter={this.props.actions.removeFilter}
- editMode={editMode}
- showBuilderPane={showBuilderPane}
- />
+ <div>
+ <AlertsWrapper initMessages={this.props.initMessages} />
+ <DashboardBuilder />
</div>
);
}
diff --git a/superset/assets/src/dashboard/v2/components/DashboardBuilder.jsx b/superset/assets/src/dashboard/components/DashboardBuilder.jsx
similarity index 81%
rename from superset/assets/src/dashboard/v2/components/DashboardBuilder.jsx
rename to superset/assets/src/dashboard/components/DashboardBuilder.jsx
index f3f5867..79eb35d 100644
--- a/superset/assets/src/dashboard/v2/components/DashboardBuilder.jsx
+++ b/superset/assets/src/dashboard/components/DashboardBuilder.jsx
@@ -20,8 +20,6 @@ import {
} from '../util/constants';
const propTypes = {
- cells: PropTypes.object.isRequired,
-
// redux
dashboardLayout: PropTypes.object.isRequired,
deleteTopLevelTabs: PropTypes.func.isRequired,
@@ -37,8 +35,10 @@ const defaultProps = {
class DashboardBuilder extends React.Component {
static shouldFocusTabs(event, container) {
// don't focus the tabs when we click on a tab
- return event.target.tagName === 'UL' || (
- /icon-button/.test(event.target.className) && container.contains(event.target)
+ return (
+ event.target.tagName === 'UL' ||
+ (/icon-button/.test(event.target.className) &&
+ container.contains(event.target))
);
}
@@ -56,19 +56,27 @@ class DashboardBuilder extends React.Component {
render() {
const { tabIndex } = this.state;
- const { handleComponentDrop, dashboardLayout, deleteTopLevelTabs, editMode } = this.props;
+ const {
+ handleComponentDrop,
+ dashboardLayout,
+ deleteTopLevelTabs,
+ editMode,
+ } = this.props;
const dashboardRoot = dashboardLayout[DASHBOARD_ROOT_ID];
const rootChildId = dashboardRoot.children[0];
- const topLevelTabs = rootChildId !== DASHBOARD_GRID_ID && dashboardLayout[rootChildId];
+ const topLevelTabs =
+ rootChildId !== DASHBOARD_GRID_ID && dashboardLayout[rootChildId];
const gridComponentId = topLevelTabs
- ? topLevelTabs.children[Math.min(topLevelTabs.children.length - 1, tabIndex)]
+ ? topLevelTabs.children[
+ Math.min(topLevelTabs.children.length - 1, tabIndex)
+ ]
: DASHBOARD_GRID_ID;
const gridComponent = dashboardLayout[gridComponentId];
return (
- <div className={cx('dashboard-v2', editMode && 'dashboard-v2--editing')}>
+ <div className={cx('dashboard', editMode && 'dashboard--editing')}>
{topLevelTabs || !editMode ? ( // you cannot drop on/displace tabs if they already exist
<DashboardHeader />
) : (
@@ -87,9 +95,10 @@ class DashboardBuilder extends React.Component {
{dropIndicatorProps && <div {...dropIndicatorProps} />}
</div>
)}
- </DragDroppable>)}
+ </DragDroppable>
+ )}
- {topLevelTabs &&
+ {topLevelTabs && (
<WithPopoverMenu
shouldFocus={DashboardBuilder.shouldFocusTabs}
menuItems={[
@@ -108,19 +117,17 @@ class DashboardBuilder extends React.Component {
index={0}
renderTabContent={false}
onChangeTab={this.handleChangeTab}
- cells={this.props.cells}
/>
- </WithPopoverMenu>}
+ </WithPopoverMenu>
+ )}
<div className="dashboard-content">
<DashboardGrid
gridComponent={gridComponent}
depth={DASHBOARD_ROOT_DEPTH + 1}
- cells={this.props.cells}
/>
- {this.props.editMode && this.props.showBuilderPane &&
- <BuilderComponentPane />
- }
+ {this.props.editMode &&
+ this.props.showBuilderPane && <BuilderComponentPane />}
</div>
<ToastPresenter />
</div>
diff --git a/superset/assets/src/dashboard/components/DashboardContainer.jsx b/superset/assets/src/dashboard/components/DashboardContainer.jsx
deleted file mode 100644
index 31fe035..0000000
--- a/superset/assets/src/dashboard/components/DashboardContainer.jsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { bindActionCreators } from 'redux';
-import { connect } from 'react-redux';
-
-import {
- toggleExpandSlice,
- addFilter,
- removeFilter,
- addSliceToDashboard,
- removeSliceFromDashboard,
- onChange,
-} from '../actions/dashboardState';
-import { saveSliceName } from '../actions/sliceEntities';
-import { refreshChart, runQuery, renderTriggered } from '../../chart/chartAction';
-import Dashboard from './Dashboard';
-
-function mapStateToProps({ datasources, sliceEntities, charts,
- dashboardInfo, dashboardState,
- dashboardLayout, impressionId }) {
- return {
- initMessages: dashboardInfo.common.flash_messages,
- timeout: dashboardInfo.common.conf.SUPERSET_WEBSERVER_TIMEOUT,
- userId: dashboardInfo.userId,
- dashboardInfo,
- dashboardState,
- charts,
- datasources,
- slices: sliceEntities.slices,
- layout: dashboardLayout.present,
- impressionId,
- };
-}
-
-function mapDispatchToProps(dispatch) {
- const actions = {
- refreshChart,
- runQuery,
- renderTriggered,
- saveSliceName,
- toggleExpandSlice,
- addFilter,
- removeFilter,
- addSliceToDashboard,
- removeSliceFromDashboard,
- onChange,
- };
- return {
- actions: bindActionCreators(actions, dispatch),
- };
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(Dashboard);
diff --git a/superset/assets/src/dashboard/v2/components/DashboardGrid.jsx b/superset/assets/src/dashboard/components/DashboardGrid.jsx
similarity index 57%
rename from superset/assets/src/dashboard/v2/components/DashboardGrid.jsx
rename to superset/assets/src/dashboard/components/DashboardGrid.jsx
index 2aa82af..3e6fc0c 100644
--- a/superset/assets/src/dashboard/v2/components/DashboardGrid.jsx
+++ b/superset/assets/src/dashboard/components/DashboardGrid.jsx
@@ -1,15 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
+// ParentSize uses resize observer so the dashboard will update size
+// when its container size changes, due to e.g., builder side panel opening
import ParentSize from '@vx/responsive/build/components/ParentSize';
import { componentShape } from '../util/propShapes';
import DashboardComponent from '../containers/DashboardComponent';
import DragDroppable from './dnd/DragDroppable';
-import {
- GRID_GUTTER_SIZE,
- GRID_COLUMN_COUNT,
-} from '../util/constants';
+import { GRID_GUTTER_SIZE, GRID_COLUMN_COUNT } from '../util/constants';
const propTypes = {
depth: PropTypes.number.isRequired,
@@ -19,8 +18,7 @@ const propTypes = {
resizeComponent: PropTypes.func.isRequired,
};
-const defaultProps = {
-};
+const defaultProps = {};
class DashboardGrid extends React.PureComponent {
constructor(props) {
@@ -34,15 +32,24 @@ class DashboardGrid extends React.PureComponent {
this.handleResize = this.handleResize.bind(this);
this.handleResizeStop = this.handleResizeStop.bind(this);
this.getRowGuidePosition = this.getRowGuidePosition.bind(this);
+ this.setGridRef = this.setGridRef.bind(this);
}
getRowGuidePosition(resizeRef) {
if (resizeRef && this.grid) {
- return resizeRef.getBoundingClientRect().bottom - this.grid.getBoundingClientRect().top - 1;
+ return (
+ resizeRef.getBoundingClientRect().bottom -
+ this.grid.getBoundingClientRect().top -
+ 1
+ );
}
return null;
}
+ setGridRef(ref) {
+ this.grid = ref;
+ }
+
handleResizeStart({ ref, direction }) {
let rowGuideTop = null;
if (direction === 'bottom' || direction === 'bottomRight') {
@@ -71,19 +78,36 @@ class DashboardGrid extends React.PureComponent {
}
render() {
- const { gridComponent, handleComponentDrop, depth, editMode, cells } = this.props;
+ const { gridComponent, handleComponentDrop, depth, editMode } = this.props;
const { isResizing, rowGuideTop } = this.state;
return (
- <div className="grid-container" ref={(ref) => { this.grid = ref; }}>
+ <div className="grid-container" ref={this.setGridRef}>
<ParentSize>
{({ width }) => {
- // account for (COLUMN_COUNT - 1) gutters
- const columnPlusGutterWidth = (width + GRID_GUTTER_SIZE) / GRID_COLUMN_COUNT;
+ const columnPlusGutterWidth =
+ (width + GRID_GUTTER_SIZE) / GRID_COLUMN_COUNT;
const columnWidth = columnPlusGutterWidth - GRID_GUTTER_SIZE;
-
return width < 50 ? null : (
<div className="grid-content">
+ {editMode && (
+ <DragDroppable
+ component={gridComponent}
+ depth={depth}
+ parentComponent={null}
+ index={0}
+ orientation="column"
+ onDrop={handleComponentDrop}
+ editMode
+ >
+ {({ dropIndicatorProps }) =>
+ dropIndicatorProps && (
+ <div className="drop-indicator drop-indicator--bottom" />
+ )
+ }
+ </DragDroppable>
+ )}
+
{gridComponent.children.map((id, index) => (
<DashboardComponent
key={id}
@@ -93,7 +117,6 @@ class DashboardGrid extends React.PureComponent {
index={index}
availableColumnCount={GRID_COLUMN_COUNT}
columnWidth={columnWidth}
- cells={cells}
onResizeStart={this.handleResizeStart}
onResize={this.handleResize}
onResizeStop={this.handleResizeStop}
@@ -101,7 +124,7 @@ class DashboardGrid extends React.PureComponent {
))}
{/* render an empty drop target */}
- {editMode &&
+ {editMode && (
<DragDroppable
component={gridComponent}
depth={depth}
@@ -112,29 +135,38 @@ class DashboardGrid extends React.PureComponent {
className="empty-grid-droptarget"
editMode
>
- {({ dropIndicatorProps }) => dropIndicatorProps &&
- <div className="drop-indicator drop-indicator--top" />}
- </DragDroppable>}
-
- {isResizing && Array(GRID_COLUMN_COUNT).fill(null).map((_, i) => (
- <div
- key={`grid-column-${i}`}
- className="grid-column-guide"
- style={{
- left: (i * GRID_GUTTER_SIZE) + (i * columnWidth),
- width: columnWidth,
- }}
- />
- ))}
-
- {isResizing && rowGuideTop &&
- <div
- className="grid-row-guide"
- style={{
- top: rowGuideTop,
- width,
- }}
- />}
+ {({ dropIndicatorProps }) =>
+ dropIndicatorProps && (
+ <div className="drop-indicator drop-indicator--top" />
+ )
+ }
+ </DragDroppable>
+ )}
+
+ {isResizing &&
+ Array(GRID_COLUMN_COUNT)
+ .fill(null)
+ .map((_, i) => (
+ <div
+ key={`grid-column-${i}`}
+ className="grid-column-guide"
+ style={{
+ left: i * GRID_GUTTER_SIZE + i * columnWidth,
+ width: columnWidth,
+ }}
+ />
+ ))}
+
+ {isResizing &&
+ rowGuideTop && (
+ <div
+ className="grid-row-guide"
+ style={{
+ top: rowGuideTop,
+ width,
+ }}
+ />
+ )}
</div>
);
}}
diff --git a/superset/assets/src/dashboard/v2/components/DeleteComponentButton.jsx b/superset/assets/src/dashboard/components/DeleteComponentButton.jsx
similarity index 78%
rename from superset/assets/src/dashboard/v2/components/DeleteComponentButton.jsx
rename to superset/assets/src/dashboard/components/DeleteComponentButton.jsx
index 18efff4..8470947 100644
--- a/superset/assets/src/dashboard/v2/components/DeleteComponentButton.jsx
+++ b/superset/assets/src/dashboard/components/DeleteComponentButton.jsx
@@ -7,15 +7,12 @@ const propTypes = {
onDelete: PropTypes.func.isRequired,
};
-const defaultProps = {
-};
+const defaultProps = {};
export default class DeleteComponentButton extends React.PureComponent {
render() {
const { onDelete } = this.props;
- return (
- <IconButton onClick={onDelete} className="fa fa-trash" />
- );
+ return <IconButton onClick={onDelete} className="fa fa-trash" />;
}
}
diff --git a/superset/assets/src/dashboard/components/GridCell.jsx b/superset/assets/src/dashboard/components/GridCell.jsx
deleted file mode 100644
index 3273272..0000000
--- a/superset/assets/src/dashboard/components/GridCell.jsx
+++ /dev/null
@@ -1,158 +0,0 @@
-/* eslint-disable react/no-danger */
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import SliceHeader from './SliceHeader';
-import ChartContainer from '../../chart/ChartContainer';
-import { chartPropShape, slicePropShape } from '../v2/util/propShapes';
-
-const propTypes = {
- timeout: PropTypes.number,
- datasource: PropTypes.object,
- isLoading: PropTypes.bool,
- isCached: PropTypes.bool,
- cachedDttm: PropTypes.string,
- isExpanded: PropTypes.bool,
- widgetHeight: PropTypes.number,
- widgetWidth: PropTypes.number,
- slice: slicePropShape.isRequired,
- chart: chartPropShape.isRequired,
- formData: PropTypes.object,
- filters: PropTypes.object,
- refreshChart: PropTypes.func,
- updateSliceName: PropTypes.func,
- toggleExpandSlice: PropTypes.func,
- exploreChart: PropTypes.func,
- exportCSV: PropTypes.func,
- addFilter: PropTypes.func,
- getFilters: PropTypes.func,
- removeFilter: PropTypes.func,
- editMode: PropTypes.bool,
- annotationQuery: PropTypes.object,
-};
-
-const defaultProps = {
- refreshChart: () => ({}),
- updateSliceName: () => ({}),
- toggleExpandSlice: () => ({}),
- exploreChart: () => ({}),
- exportCSV: () => ({}),
- addFilter: () => ({}),
- getFilters: () => ({}),
- removeFilter: () => ({}),
- editMode: false,
-};
-
-class GridCell extends React.PureComponent {
- constructor(props) {
- super(props);
-
- const sliceId = this.props.slice.slice_id;
- this.forceRefresh = this.forceRefresh.bind(this);
- this.addFilter = this.props.addFilter.bind(this, this.props.chart);
- this.getFilters = this.props.getFilters.bind(this, sliceId);
- this.removeFilter = this.props.removeFilter.bind(this, sliceId);
- }
-
- getDescriptionId(slice) {
- return 'description_' + slice.slice_id;
- }
-
- getHeaderId(slice) {
- return 'header_' + slice.slice_id;
- }
-
- width() {
- return this.props.widgetWidth - 32;
- }
-
- height(slice) {
- const widgetHeight = this.props.widgetHeight;
- const headerHeight = this.headerHeight(slice);
- const descriptionId = this.getDescriptionId(slice);
- let descriptionHeight = 0;
- if (this.props.isExpanded && this.refs[descriptionId]) {
- descriptionHeight = this.refs[descriptionId].offsetHeight + 10;
- }
-
- return widgetHeight - headerHeight - descriptionHeight - 32;
- }
-
- headerHeight(slice) {
- const headerId = this.getHeaderId(slice);
- return this.refs[headerId] ? this.refs[headerId].offsetHeight : 30;
- }
-
- forceRefresh() {
- return this.props.refreshChart(this.props.chart, true, this.props.timeout);
- }
-
- render() {
- const {
- isExpanded, isLoading, isCached, cachedDttm,
- updateSliceName, toggleExpandSlice,
- chart, slice, datasource, formData, timeout, annotationQuery,
- exploreChart, exportCSV, editMode,
- } = this.props;
-
- return (
- <div
- className={isLoading ? 'slice-cell-highlight' : 'slice-cell'}
- id={`${slice.slice_id}-cell`}
- >
- <div ref={this.getHeaderId(slice)}>
- <SliceHeader
- slice={slice}
- isExpanded={isExpanded}
- isCached={isCached}
- cachedDttm={cachedDttm}
- updateSliceName={updateSliceName}
- toggleExpandSlice={toggleExpandSlice}
- forceRefresh={this.forceRefresh}
- editMode={editMode}
- annotationQuery={annotationQuery}
- exploreChart={exploreChart}
- exportCSV={exportCSV}
- />
- </div>
- {
- /* This usage of dangerouslySetInnerHTML is safe since it is being used to render
- markdown that is sanitized with bleach. See:
- https://github.com/apache/incubator-superset/pull/4390
- and
- https://github.com/apache/incubator-superset/commit/b6fcc22d5a2cb7a5e92599ed5795a0169385a825 */}
- <div
- className="slice_description bs-callout bs-callout-default"
- style={isExpanded ? {} : { display: 'none' }}
- ref={this.getDescriptionId(slice)}
- dangerouslySetInnerHTML={{ __html: slice.description_markeddown }}
- />
- <div
- className="chart-container"
- style={{ width: this.width(), height: this.height(slice) }}
- >
- <input type="hidden" value="false" />
- <ChartContainer
- containerId={`slice-container-${slice.slice_id}`}
- chartId={chart.id}
- datasource={datasource}
- formData={formData}
- headerHeight={this.headerHeight(slice)}
- height={this.height(slice)}
- width={this.width()}
- timeout={timeout}
- vizType={slice.viz_type}
- addFilter={this.addFilter}
- getFilters={this.getFilters}
- removeFilter={this.removeFilter}
- />
- </div>
- </div>
- );
- }
-}
-
-GridCell.propTypes = propTypes;
-GridCell.defaultProps = defaultProps;
-
-export default GridCell;
diff --git a/superset/assets/src/dashboard/components/GridLayout.jsx b/superset/assets/src/dashboard/components/GridLayout.jsx
deleted file mode 100644
index fd561e2..0000000
--- a/superset/assets/src/dashboard/components/GridLayout.jsx
+++ /dev/null
@@ -1,156 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import cx from 'classnames';
-
-import GridCell from './GridCell';
-import { slicePropShape, chartPropShape } from '../v2/util/propShapes';
-import DashboardBuilder from '../v2/containers/DashboardBuilder';
-
-const propTypes = {
- dashboardInfo: PropTypes.shape().isRequired,
- layout: PropTypes.object.isRequired,
- datasources: PropTypes.object,
- charts: PropTypes.objectOf(chartPropShape).isRequired,
- slices: PropTypes.objectOf(slicePropShape).isRequired,
- expandedSlices: PropTypes.object.isRequired,
- sliceIds: PropTypes.object.isRequired,
- filters: PropTypes.object,
- timeout: PropTypes.number,
- onChange: PropTypes.func,
- rerenderCharts: PropTypes.func,
- getFormDataExtra: PropTypes.func,
- exploreChart: PropTypes.func,
- exportCSV: PropTypes.func,
- refreshChart: PropTypes.func,
- saveSliceName: PropTypes.func,
- toggleExpandSlice: PropTypes.func,
- addFilter: PropTypes.func,
- getFilters: PropTypes.func,
- removeFilter: PropTypes.func,
- editMode: PropTypes.bool.isRequired,
- showBuilderPane: PropTypes.bool.isRequired,
-};
-
-const defaultProps = {
- expandedSlices: {},
- filters: {},
- timeout: 60,
- onChange: () => ({}),
- getFormDataExtra: () => ({}),
- exploreChart: () => ({}),
- exportCSV: () => ({}),
- refreshChart: () => ({}),
- saveSliceName: () => ({}),
- toggleExpandSlice: () => ({}),
- addFilter: () => ({}),
- getFilters: () => ({}),
- removeFilter: () => ({}),
-};
-
-class GridLayout extends React.Component {
- constructor(props) {
- super(props);
-
- this.updateSliceName = this.props.dashboardInfo.dash_edit_perm ?
- this.updateSliceName.bind(this) : null;
- }
-
- componentDidUpdate(prevProps) {
- if (prevProps.editMode !== this.props.editMode ||
- prevProps.showBuilderPane !== this.props.showBuilderPane) {
- this.props.rerenderCharts();
- }
- }
-
- getWidgetId(sliceId) {
- return 'widget_' + sliceId;
- }
-
- getWidgetHeight(sliceId) {
- const widgetId = this.getWidgetId(sliceId);
- if (!widgetId || !this.refs[widgetId]) {
- return 400;
- }
- return this.refs[widgetId].parentNode.clientHeight;
- }
-
- getWidgetWidth(sliceId) {
- const widgetId = this.getWidgetId(sliceId);
- if (!widgetId || !this.refs[widgetId]) {
- return 400;
- }
- return this.refs[widgetId].parentNode.clientWidth;
- }
-
- updateSliceName(sliceId, sliceName) {
- const key = sliceId;
- const currentSlice = this.props.slices[key];
- if (!currentSlice || currentSlice.slice_name === sliceName) {
- return;
- }
-
- this.props.saveSliceName(currentSlice, sliceName);
- }
-
- isExpanded(sliceId) {
- return this.props.expandedSlices[sliceId];
- }
-
- render() {
- const cells = {};
- this.props.sliceIds.forEach((sliceId) => {
- const key = sliceId;
- const currentChart = this.props.charts[key];
- const currentSlice = this.props.slices[key];
- if (currentChart) {
- const currentDatasource = this.props.datasources[currentChart.form_data.datasource];
- const queryResponse = currentChart.queryResponse || {};
- cells[key] = (
- <div
- id={key}
- key={sliceId}
- className={cx('widget', `${currentSlice.viz_type}`, { 'is-edit': this.props.editMode })}
- ref={this.getWidgetId(sliceId)}
- >
- <GridCell
- slice={currentSlice}
- chart={currentChart}
- datasource={currentDatasource}
- filters={this.props.filters}
- formData={this.props.getFormDataExtra(currentChart)}
- timeout={this.props.timeout}
- widgetHeight={this.getWidgetHeight(sliceId)}
- widgetWidth={this.getWidgetWidth(sliceId)}
- exploreChart={this.props.exploreChart}
- exportCSV={this.props.exportCSV}
- isExpanded={!!this.isExpanded(sliceId)}
- isLoading={currentChart.chartStatus === 'loading'}
- isCached={queryResponse.is_cached}
- cachedDttm={queryResponse.cached_dttm}
- toggleExpandSlice={this.props.toggleExpandSlice}
- refreshChart={this.props.refreshChart}
- updateSliceName={this.updateSliceName}
- addFilter={this.props.addFilter}
- getFilters={this.props.getFilters}
- removeFilter={this.props.removeFilter}
- editMode={this.props.editMode}
- annotationQuery={currentChart.annotationQuery}
- annotationError={currentChart.annotationError}
- />
- </div>
- );
- }
- });
-
- return (
- <DashboardBuilder
- cells={cells}
- />
- );
- }
-}
-
-GridLayout.propTypes = propTypes;
-GridLayout.defaultProps = defaultProps;
-
-export default GridLayout;
diff --git a/superset/assets/src/dashboard/components/Header.jsx b/superset/assets/src/dashboard/components/Header.jsx
index f533506..242102e 100644
--- a/superset/assets/src/dashboard/components/Header.jsx
+++ b/superset/assets/src/dashboard/components/Header.jsx
@@ -6,8 +6,9 @@ import Controls from './Controls';
import EditableTitle from '../../components/EditableTitle';
import Button from '../../components/Button';
import FaveStar from '../../components/FaveStar';
-import InfoTooltipWithTrigger from '../../components/InfoTooltipWithTrigger';
-import { chartPropShape } from '../v2/util/propShapes';
+// import InfoTooltipWithTrigger from '../../components/InfoTooltipWithTrigger';
+import SaveModal from './SaveModal';
+import { chartPropShape } from '../util/propShapes';
import { t } from '../../locales';
const propTypes = {
@@ -20,9 +21,9 @@ const propTypes = {
isStarred: PropTypes.bool.isRequired,
onSave: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
- fetchFaveStar: PropTypes.func,
+ fetchFaveStar: PropTypes.func.isRequired,
fetchCharts: PropTypes.func.isRequired,
- saveFaveStar: PropTypes.func,
+ saveFaveStar: PropTypes.func.isRequired,
startPeriodicRender: PropTypes.func.isRequired,
updateDashboardTitle: PropTypes.func.isRequired,
editMode: PropTypes.bool.isRequired,
@@ -41,13 +42,16 @@ const propTypes = {
class Header extends React.PureComponent {
constructor(props) {
super(props);
+
this.handleChangeText = this.handleChangeText.bind(this);
this.toggleEditMode = this.toggleEditMode.bind(this);
this.forceRefresh = this.forceRefresh.bind(this);
}
+
forceRefresh() {
return this.props.fetchCharts(Object.values(this.props.charts), true);
}
+
handleChangeText(nextText) {
const { updateDashboardTitle, onChange } = this.props;
if (nextText && this.props.dashboardTitle !== nextText) {
@@ -55,45 +59,11 @@ class Header extends React.PureComponent {
onChange();
}
}
+
toggleEditMode() {
this.props.setEditMode(!this.props.editMode);
}
- renderUnsaved() {
- if (!this.props.hasUnsavedChanges) {
- return null;
- }
- return (
- <InfoTooltipWithTrigger
- label="unsaved"
- tooltip={t('Unsaved changes')}
- icon="exclamation-triangle"
- className="text-danger m-r-5"
- placement="top"
- />
- );
- }
- renderInsertButton() {
- if (!this.props.editMode) {
- return null;
- }
- const btnText = this.props.showBuilderPane ? t('Hide builder pane') : t('Insert components');
- return (
- <Button bsSize="small" onClick={this.props.toggleBuilderPane}>
- {btnText}
- </Button>
- );
- }
- renderEditButton() {
- if (!this.props.dashboardInfo.dash_save_perm) {
- return null;
- }
- const btnText = this.props.editMode ? t('Switch to View Mode') : t('Edit Dashboard');
- return (
- <Button bsSize="small" onClick={this.toggleEditMode}>
- {btnText}
- </Button>
- );
- }
+
render() {
const {
dashboardTitle,
@@ -107,8 +77,13 @@ class Header extends React.PureComponent {
onChange,
onSave,
editMode,
+ showBuilderPane,
+ dashboardInfo,
+ hasUnsavedChanges,
} = this.props;
+ const userCanEdit = dashboardInfo.dash_save_perm;
+
return (
<div className="dashboard-header">
<div className="dashboard-component-header header-large">
@@ -126,19 +101,58 @@ class Header extends React.PureComponent {
isStarred={this.props.isStarred}
/>
</span>
- {this.renderUnsaved()}
</div>
<ButtonToolbar>
- <ButtonGroup>
- <Button bsSize="small" onClick={onUndo} disabled={!canUndo}>
- Undo
- </Button>
- <Button bsSize="small" onClick={onRedo} disabled={!canRedo}>
- Redo
- </Button>
- {this.renderInsertButton()}
- {this.renderEditButton()}
- </ButtonGroup>
+ {userCanEdit && (
+ <ButtonGroup>
+ {editMode && (
+ <Button bsSize="small" onClick={onUndo} disabled={!canUndo}>
+ Undo
+ </Button>
+ )}
+
+ {editMode && (
+ <Button bsSize="small" onClick={onRedo} disabled={!canRedo}>
+ Redo
+ </Button>
+ )}
+
+ {editMode && (
+ <Button bsSize="small" onClick={this.props.toggleBuilderPane}>
+ {showBuilderPane
+ ? t('Hide builder pane')
+ : t('Insert components')}
+ </Button>
+ )}
+
+ {!hasUnsavedChanges ? (
+ <Button
+ bsSize="small"
+ onClick={this.toggleEditMode}
+ bsStyle={editMode ? undefined : 'primary'}
+ >
+ {editMode ? t('Switch to View Mode') : t('Edit Dashboard')}
+ </Button>
+ ) : (
+ <SaveModal
+ dashboardId={this.props.dashboardInfo.id}
+ dashboardTitle={dashboardTitle}
+ layout={layout}
+ filters={filters}
+ expandedSlices={expandedSlices}
+ onSave={onSave}
+ // @TODO need to figure out css
+ css=""
+ triggerNode={
+ <Button bsStyle="primary" bsSize="small">
+ {t('Save changes')}
+ </Button>
+ }
+ />
+ )}
+ </ButtonGroup>
+ )}
+
<Controls
dashboardInfo={this.props.dashboardInfo}
dashboardTitle={dashboardTitle}
@@ -156,6 +170,7 @@ class Header extends React.PureComponent {
);
}
}
+
Header.propTypes = propTypes;
export default Header;
diff --git a/superset/assets/src/dashboard/v2/components/IconButton.jsx b/superset/assets/src/dashboard/components/IconButton.jsx
similarity index 100%
rename from superset/assets/src/dashboard/v2/components/IconButton.jsx
rename to superset/assets/src/dashboard/components/IconButton.jsx
diff --git a/superset/assets/src/dashboard/components/RefreshIntervalModal.jsx b/superset/assets/src/dashboard/components/RefreshIntervalModal.jsx
index c2a5637..1ed4f82 100644
--- a/superset/assets/src/dashboard/components/RefreshIntervalModal.jsx
+++ b/superset/assets/src/dashboard/components/RefreshIntervalModal.jsx
@@ -16,7 +16,7 @@ const defaultProps = {
};
const options = [
- [0, t('Don\'t refresh')],
+ [0, t("Don't refresh")],
[10, t('10 seconds')],
[30, t('30 seconds')],
[60, t('1 minute')],
@@ -47,7 +47,7 @@ class RefreshIntervalModal extends React.PureComponent {
<Select
options={options}
value={this.state.refreshFrequency}
- onChange={(opt) => {
+ onChange={opt => {
const value = opt ? opt.value : options[0].value;
this.setState({
refreshFrequency: value,
diff --git a/superset/assets/src/dashboard/components/SaveModal.jsx b/superset/assets/src/dashboard/components/SaveModal.jsx
index 2e76bf4..41c6364 100644
--- a/superset/assets/src/dashboard/components/SaveModal.jsx
+++ b/superset/assets/src/dashboard/components/SaveModal.jsx
@@ -1,4 +1,4 @@
-/* global notify */
+/* global notify, window */
import React from 'react';
import PropTypes from 'prop-types';
import $ from 'jquery';
@@ -17,6 +17,11 @@ const propTypes = {
triggerNode: PropTypes.node.isRequired,
filters: PropTypes.object.isRequired,
onSave: PropTypes.func.isRequired,
+ isMenuItem: PropTypes.bool,
+};
+
+const defaultProps = {
+ isMenuItem: false,
};
class SaveModal extends React.PureComponent {
@@ -24,28 +29,38 @@ class SaveModal extends React.PureComponent {
super(props);
this.state = {
saveType: 'overwrite',
- newDashName: props.dashboardTitle + ' [copy]',
+ newDashName: `${props.dashboardTitle} [copy]`,
duplicateSlices: false,
};
this.modal = null;
this.handleSaveTypeChange = this.handleSaveTypeChange.bind(this);
this.handleNameChange = this.handleNameChange.bind(this);
this.saveDashboard = this.saveDashboard.bind(this);
+ this.setModalRef = this.setModalRef.bind(this);
+ this.toggleDuplicateSlices = this.toggleDuplicateSlices.bind(this);
+ }
+
+ setModalRef(ref) {
+ this.modal = ref;
}
+
toggleDuplicateSlices() {
this.setState({ duplicateSlices: !this.state.duplicateSlices });
}
+
handleSaveTypeChange(event) {
this.setState({
saveType: event.target.value,
});
}
+
handleNameChange(event) {
this.setState({
newDashName: event.target.value,
saveType: 'newDashboard',
});
}
+
saveDashboardRequest(data, url, saveType) {
const saveModal = this.modal;
const onSaveDashboard = this.props.onSave;
@@ -67,12 +82,25 @@ class SaveModal extends React.PureComponent {
error(error) {
saveModal.close();
const errorMsg = getAjaxErrorMsg(error);
- notify.error(t('Sorry, there was an error saving this dashboard: ') + errorMsg);
+ notify.error(
+ `${t(
+ 'Sorry, there was an error saving this dashboard: ',
+ )} ${errorMsg}`,
+ );
},
});
}
- saveDashboard(saveType, newDashboardTitle) {
- const { dashboardTitle, layout: positions, expandedSlices, filters, dashboardId } = this.props;
+
+ saveDashboard() {
+ const { saveType, newDashName } = this.state;
+ const {
+ dashboardTitle,
+ layout: positions,
+ expandedSlices,
+ filters,
+ dashboardId,
+ } = this.props;
+
const data = {
positions,
expanded_slices: expandedSlices,
@@ -80,29 +108,27 @@ class SaveModal extends React.PureComponent {
default_filters: JSON.stringify(filters),
duplicate_slices: this.state.duplicateSlices,
};
+
let url = null;
if (saveType === 'overwrite') {
url = `/superset/save_dash/${dashboardId}/`;
this.saveDashboardRequest(data, url, saveType);
} else if (saveType === 'newDashboard') {
- if (!newDashboardTitle) {
- this.modal.close();
- showModal({
- title: t('Error'),
- body: t('You must pick a name for the new dashboard'),
- });
+ if (!newDashName) {
+ notify.error('You must pick a name for the new dashboard');
} else {
- data.dashboard_title = newDashboardTitle;
+ data.dashboard_title = newDashName;
url = `/superset/copy_dash/${dashboardId}/`;
this.saveDashboardRequest(data, url, saveType);
}
}
}
+
render() {
return (
<ModalTrigger
- ref={(modal) => { this.modal = modal; }}
- isMenuItem
+ ref={this.setModalRef}
+ isMenuItem={this.props.isMenuItem}
triggerNode={this.props.triggerNode}
modalTitle={t('Save Dashboard')}
modalBody={
@@ -132,7 +158,7 @@ class SaveModal extends React.PureComponent {
<div className="m-l-25 m-t-5">
<Checkbox
checked={this.state.duplicateSlices}
- onChange={this.toggleDuplicateSlices.bind(this)}
+ onChange={this.toggleDuplicateSlices}
/>
<span className="m-l-5">also copy (duplicate) charts</span>
</div>
@@ -140,10 +166,7 @@ class SaveModal extends React.PureComponent {
}
modalFooter={
<div>
- <Button
- bsStyle="primary"
- onClick={() => { this.saveDashboard(this.state.saveType, this.state.newDashName); }}
- >
+ <Button bsStyle="primary" onClick={this.saveDashboard}>
{t('Save')}
</Button>
</div>
@@ -152,6 +175,8 @@ class SaveModal extends React.PureComponent {
);
}
}
+
SaveModal.propTypes = propTypes;
+SaveModal.defaultProps = defaultProps;
export default SaveModal;
diff --git a/superset/assets/src/dashboard/components/SliceAdder.jsx b/superset/assets/src/dashboard/components/SliceAdder.jsx
index 6477fc4..37ce21f 100644
--- a/superset/assets/src/dashboard/components/SliceAdder.jsx
+++ b/superset/assets/src/dashboard/components/SliceAdder.jsx
@@ -1,14 +1,15 @@
import React from 'react';
import PropTypes from 'prop-types';
-import cx from 'classnames';
import { DropdownButton, MenuItem } from 'react-bootstrap';
import { List } from 'react-virtualized';
import SearchInput, { createFilter } from 'react-search-input';
-import DragDroppable from '../v2/components/dnd/DragDroppable';
-import { CHART_TYPE, NEW_COMPONENT_SOURCE_TYPE } from '../v2/util/componentTypes';
-import { NEW_CHART_ID, NEW_COMPONENTS_SOURCE_ID } from '../v2/util/constants';
-import { slicePropShape } from '../v2/util/propShapes';
+import AddSliceCard from './AddSliceCard';
+import AddSliceDragPreview from './dnd/AddSliceDragPreview';
+import DragDroppable from './dnd/DragDroppable';
+import { CHART_TYPE, NEW_COMPONENT_SOURCE_TYPE } from '../util/componentTypes';
+import { NEW_CHART_ID, NEW_COMPONENTS_SOURCE_ID } from '../util/constants';
+import { slicePropShape } from '../util/propShapes';
const propTypes = {
fetchAllSlices: PropTypes.func.isRequired,
@@ -24,6 +25,7 @@ const propTypes = {
const defaultProps = {
selectedSliceIds: new Set(),
editMode: false,
+ errorMessage: '',
};
const KEYS_TO_FILTERS = ['slice_name', 'viz_type', 'datasource_name'];
@@ -35,12 +37,25 @@ const KEYS_TO_SORT = [
];
class SliceAdder extends React.Component {
+ static sortByComparator(attr) {
+ const desc = attr === 'changed_on' ? -1 : 1;
+
+ return (a, b) => {
+ if (a[attr] < b[attr]) {
+ return -1 * desc;
+ } else if (a[attr] > b[attr]) {
+ return 1 * desc;
+ }
+ return 0;
+ };
+ }
+
constructor(props) {
super(props);
this.state = {
filteredSlices: [],
searchTerm: '',
- sortBy: KEYS_TO_SORT.findIndex(item => (item.key === 'changed_on')),
+ sortBy: KEYS_TO_SORT.findIndex(item => item.key === 'changed_on'),
};
this.rowRenderer = this.rowRenderer.bind(this);
@@ -58,7 +73,9 @@ class SliceAdder extends React.Component {
this.setState({
filteredSlices: Object.values(nextProps.slices)
.filter(createFilter(this.state.searchTerm, KEYS_TO_FILTERS))
- .sort(this.sortByComparator(KEYS_TO_SORT[this.state.sortBy].key)),
+ .sort(
+ SliceAdder.sortByComparator(KEYS_TO_SORT[this.state.sortBy].key),
+ ),
});
}
}
@@ -72,20 +89,7 @@ class SliceAdder extends React.Component {
getFilteredSortedSlices(searchTerm, sortBy) {
return Object.values(this.props.slices)
.filter(createFilter(searchTerm, KEYS_TO_FILTERS))
- .sort(this.sortByComparator(KEYS_TO_SORT[sortBy].key));
- }
-
- sortByComparator(attr) {
- const desc = (attr === 'changed_on') ? -1 : 1;
-
- return (a, b) => {
- if (a[attr] < b[attr]) {
- return -1 * desc;
- } else if (a[attr] > b[attr]) {
- return 1 * desc;
- }
- return 0;
- };
+ .sort(SliceAdder.sortByComparator(KEYS_TO_SORT[sortBy].key));
}
handleKeyPress(ev) {
@@ -99,20 +103,25 @@ class SliceAdder extends React.Component {
searchUpdated(searchTerm) {
this.setState({
searchTerm,
- filteredSlices: this.getFilteredSortedSlices(searchTerm, this.state.sortBy),
+ filteredSlices: this.getFilteredSortedSlices(
+ searchTerm,
+ this.state.sortBy,
+ ),
});
}
handleSelect(sortBy) {
this.setState({
sortBy,
- filteredSlices: this.getFilteredSortedSlices(this.state.searchTerm, sortBy),
+ filteredSlices: this.getFilteredSortedSlices(
+ this.state.searchTerm,
+ sortBy,
+ ),
});
}
rowRenderer({ key, index, style }) {
const cellData = this.state.filteredSlices[index];
- const duration = cellData.modified ? cellData.modified.replace(/<[^>]*>/g, '') : '';
const isSelected = this.props.selectedSliceIds.has(cellData.slice_id);
const type = CHART_TYPE;
const id = NEW_CHART_ID;
@@ -122,38 +131,32 @@ class SliceAdder extends React.Component {
return (
<DragDroppable
+ key={key}
component={{ type, id, meta }}
- parentComponent={{ id: NEW_COMPONENTS_SOURCE_ID, type: NEW_COMPONENT_SOURCE_TYPE }}
- index={0}
+ parentComponent={{
+ id: NEW_COMPONENTS_SOURCE_ID,
+ type: NEW_COMPONENT_SOURCE_TYPE,
+ }}
+ index={index}
depth={0}
disableDragDrop={isSelected}
editMode={this.props.editMode}
+ // we must use a custom drag preview within the List because
+ // it does not seem to work within a fixed-position container
+ useEmptyDragPreview
>
{({ dragSourceRef }) => (
- <div
- ref={dragSourceRef}
- className="chart-card-container"
- key={key}
+ <AddSliceCard
+ innerRef={dragSourceRef}
style={style}
- >
- <div className={cx('chart-card', { 'is-selected': isSelected })}>
- <div className="card-title">{cellData.slice_name}</div>
- <div className="card-body">
- <div className="item">
- <span>Modified </span>
- <span>{duration}</span>
- </div>
- <div className="item">
- <span>Visualization </span>
- <span>{cellData.viz_type}</span>
- </div>
- <div className="item">
- <span>Data source </span>
- <span dangerouslySetInnerHTML={{ __html: cellData.datasource_link }} />
- </div>
- </div>
- </div>
- </div>
+ sliceName={cellData.slice_name}
+ lastModified={
+ cellData.modified ? cellData.modified.replace(/<[^>]*>/g, '') : ''
+ }
+ visType={cellData.viz_type}
+ datasourceLink={cellData.datasource_link}
+ isSelected={isSelected}
+ />
)}
</DragDroppable>
);
@@ -169,7 +172,9 @@ class SliceAdder extends React.Component {
id="slice-adder-sortby"
>
{KEYS_TO_SORT.map((item, index) => (
- <MenuItem key={item.key} eventKey={index}>{item.label}</MenuItem>
+ <MenuItem key={item.key} eventKey={index}>
+ {item.label}
+ </MenuItem>
))}
</DropdownButton>
@@ -179,18 +184,18 @@ class SliceAdder extends React.Component {
/>
</div>
- {this.props.isLoading &&
+ {this.props.isLoading && (
<img
src="/static/assets/images/loading.gif"
className="loading"
alt="loading"
/>
- }
- <div className={this.props.errorMessage ? '' : 'hidden'}>
- {this.props.errorMessage}
- </div>
- <div className={!this.props.isLoading ? '' : 'hidden'}>
- {this.state.filteredSlices.length > 0 &&
+ )}
+
+ {this.props.errorMessage && <div>{this.props.errorMessage}</div>}
+
+ {!this.props.isLoading &&
+ this.state.filteredSlices.length > 0 && (
<List
width={376}
height={500}
@@ -201,8 +206,10 @@ class SliceAdder extends React.Component {
sortBy={this.state.sortBy}
selectedSliceIds={this.props.selectedSliceIds}
/>
- }
- </div>
+ )}
+
+ {/* Drag preview is just a single fixed-position element */}
+ <AddSliceDragPreview slices={this.state.filteredSlices} />
</div>
);
}
diff --git a/superset/assets/src/dashboard/components/SliceAdderContainer.jsx b/superset/assets/src/dashboard/components/SliceAdderContainer.jsx
deleted file mode 100644
index b4f10d9..0000000
--- a/superset/assets/src/dashboard/components/SliceAdderContainer.jsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { bindActionCreators } from 'redux';
-import { connect } from 'react-redux';
-
-import { fetchAllSlices } from '../actions/sliceEntities';
-import SliceAdder from './SliceAdder';
-
-function mapStateToProps({ sliceEntities, dashboardInfo, dashboardState }) {
- return {
- userId: dashboardInfo.userId,
- selectedSliceIds: dashboardState.sliceIds,
- slices: sliceEntities.slices,
- isLoading: sliceEntities.isLoading,
- errorMessage: sliceEntities.errorMessage,
- lastUpdated: sliceEntities.lastUpdated,
- editMode: dashboardState.editMode,
- };
-}
-
-function mapDispatchToProps(dispatch) {
- return bindActionCreators({
- fetchAllSlices
- }, dispatch);
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(SliceAdder);
diff --git a/superset/assets/src/dashboard/components/SliceHeader.jsx b/superset/assets/src/dashboard/components/SliceHeader.jsx
index f126949..bcdaedf 100644
--- a/superset/assets/src/dashboard/components/SliceHeader.jsx
+++ b/superset/assets/src/dashboard/components/SliceHeader.jsx
@@ -7,9 +7,8 @@ import TooltipWrapper from '../../components/TooltipWrapper';
import SliceHeaderControls from './SliceHeaderControls';
const propTypes = {
+ innerRef: PropTypes.func,
slice: PropTypes.object.isRequired,
- supersetCanExplore: PropTypes.bool,
- sliceCanEdit: PropTypes.bool,
isExpanded: PropTypes.bool,
isCached: PropTypes.bool,
cachedDttm: PropTypes.string,
@@ -24,6 +23,7 @@ const propTypes = {
};
const defaultProps = {
+ innerRef: null,
forceRefresh: () => ({}),
removeSlice: () => ({}),
updateSliceName: () => ({}),
@@ -31,6 +31,11 @@ const defaultProps = {
exploreChart: () => ({}),
exportCSV: () => ({}),
editMode: false,
+ annotationQuery: {},
+ annotationError: {},
+ cachedDttm: null,
+ isCached: false,
+ isExpanded: false,
};
class SliceHeader extends React.PureComponent {
@@ -48,55 +53,62 @@ class SliceHeader extends React.PureComponent {
render() {
const {
- slice, isExpanded, isCached, cachedDttm,
- toggleExpandSlice, forceRefresh,
- exploreChart, exportCSV,
+ slice,
+ isExpanded,
+ isCached,
+ cachedDttm,
+ toggleExpandSlice,
+ forceRefresh,
+ exploreChart,
+ exportCSV,
+ innerRef,
} = this.props;
+
const annoationsLoading = t('Annotation layers are still loading.');
const annoationsError = t('One ore more annotation layers failed loading.');
return (
- <div className="row chart-header">
- <div className="col-md-12">
- <div className="header">
- <EditableTitle
- title={slice.slice_name}
- canEdit={!!this.props.updateSliceName && this.props.editMode}
- onSaveTitle={this.onSaveTitle}
- showTooltip={this.props.editMode}
- noPermitTooltip={'You don\'t have the rights to alter this dashboard.'}
- />
- {!!Object.values(this.props.annotationQuery || {}).length &&
- <TooltipWrapper
- label="annotations-loading"
- placement="top"
- tooltip={annoationsLoading}
- >
- <i className="fa fa-refresh warning" />
- </TooltipWrapper>
- }
- {!!Object.values(this.props.annotationError || {}).length &&
- <TooltipWrapper
- label="annoation-errors"
- placement="top"
- tooltip={annoationsError}
- >
- <i className="fa fa-exclamation-circle danger" />
- </TooltipWrapper>
+ <div className="chart-header" ref={innerRef}>
+ <div className="header">
+ <EditableTitle
+ title={slice.slice_name}
+ canEdit={!!this.props.updateSliceName && this.props.editMode}
+ onSaveTitle={this.onSaveTitle}
+ noPermitTooltip={
+ "You don't have the rights to alter this dashboard."
}
- {!this.props.editMode &&
- <SliceHeaderControls
- slice={slice}
- isCached={isCached}
- isExpanded={isExpanded}
- cachedDttm={cachedDttm}
- toggleExpandSlice={toggleExpandSlice}
- forceRefresh={forceRefresh}
- exploreChart={exploreChart}
- exportCSV={exportCSV}
- />
- }
- </div>
+ showTooltip={!!this.props.updateSliceName && this.props.editMode}
+ />
+ {!!Object.values(this.props.annotationQuery).length && (
+ <TooltipWrapper
+ label="annotations-loading"
+ placement="top"
+ tooltip={annoationsLoading}
+ >
+ <i className="fa fa-refresh warning" />
+ </TooltipWrapper>
+ )}
+ {!!Object.values(this.props.annotationError).length && (
+ <TooltipWrapper
+ label="annoation-errors"
+ placement="top"
+ tooltip={annoationsError}
+ >
+ <i className="fa fa-exclamation-circle danger" />
+ </TooltipWrapper>
+ )}
+ {!this.props.editMode && (
+ <SliceHeaderControls
+ slice={slice}
+ isCached={isCached}
+ isExpanded={isExpanded}
+ cachedDttm={cachedDttm}
+ toggleExpandSlice={toggleExpandSlice}
+ forceRefresh={forceRefresh}
+ exploreChart={exploreChart}
+ exportCSV={exportCSV}
+ />
+ )}
</div>
</div>
);
diff --git a/superset/assets/src/dashboard/components/SliceHeaderControls.jsx b/superset/assets/src/dashboard/components/SliceHeaderControls.jsx
index f61e59b..0dae6f8 100644
--- a/superset/assets/src/dashboard/components/SliceHeaderControls.jsx
+++ b/superset/assets/src/dashboard/components/SliceHeaderControls.jsx
@@ -23,14 +23,23 @@ const defaultProps = {
toggleExpandSlice: () => ({}),
exploreChart: () => ({}),
exportCSV: () => ({}),
+ cachedDttm: null,
+ isCached: false,
+ isExpanded: false,
};
class SliceHeaderControls extends React.PureComponent {
constructor(props) {
super(props);
this.exportCSV = this.props.exportCSV.bind(this, this.props.slice.slice_id);
- this.exploreChart = this.props.exploreChart.bind(this, this.props.slice.slice_id);
- this.toggleExpandSlice = this.props.toggleExpandSlice.bind(this, this.props.slice.slice_id);
+ this.exploreChart = this.props.exploreChart.bind(
+ this,
+ this.props.slice.slice_id,
+ );
+ this.toggleExpandSlice = this.props.toggleExpandSlice.bind(
+ this,
+ this.props.slice.slice_id,
+ );
this.toggleControls = this.toggleControls.bind(this);
this.state = {
@@ -48,9 +57,9 @@ class SliceHeaderControls extends React.PureComponent {
const slice = this.props.slice;
const isCached = this.props.isCached;
const cachedWhen = moment.utc(this.props.cachedDttm).fromNow();
- const refreshTooltip = isCached ?
- t('Served from data cached %s . Click to force refresh.', cachedWhen) :
- t('Force refresh data');
+ const refreshTooltip = isCached
+ ? t('Served from data cached %s . Click to force refresh.', cachedWhen)
+ : t('Force refresh data');
// @TODO account for
// dashboard.dashboard.superset_can_explore
@@ -59,7 +68,9 @@ class SliceHeaderControls extends React.PureComponent {
<DropdownButton
title=""
id={`slice_${slice.slice_id}-controls`}
- className={cx('slice-header-controls-trigger', 'fa fa-ellipsis-v', { 'is-cached': isCached })}
+ className={cx('slice-header-controls-trigger', 'fa fa-ellipsis-v', {
+ 'is-cached': isCached,
+ })}
pullRight
noCaret
>
@@ -69,17 +80,17 @@ class SliceHeaderControls extends React.PureComponent {
onClick={this.props.forceRefresh}
/>
- {slice.description &&
+ {slice.description && (
<ActionMenuItem
text={t('Toggle chart description')}
tooltip={t('Toggle chart description')}
onClick={this.toggleExpandSlice}
/>
- }
+ )}
<ActionMenuItem
text={t('Edit chart')}
- tooltip={t('Edit the chart\'s properties')}
+ tooltip={t("Edit the chart's properties")}
href={slice.edit_url}
target="_blank"
/>
diff --git a/superset/assets/src/dashboard/v2/components/Toast.jsx b/superset/assets/src/dashboard/components/Toast.jsx
similarity index 93%
rename from superset/assets/src/dashboard/v2/components/Toast.jsx
rename to superset/assets/src/dashboard/components/Toast.jsx
index 537388d..3c5a3ca 100644
--- a/superset/assets/src/dashboard/v2/components/Toast.jsx
+++ b/superset/assets/src/dashboard/components/Toast.jsx
@@ -4,7 +4,12 @@ import PropTypes from 'prop-types';
import React from 'react';
import { toastShape } from '../util/propShapes';
-import { INFO_TOAST, SUCCESS_TOAST, WARNING_TOAST, DANGER_TOAST } from '../util/constants';
+import {
+ INFO_TOAST,
+ SUCCESS_TOAST,
+ WARNING_TOAST,
+ DANGER_TOAST,
+} from '../util/constants';
const propTypes = {
toast: toastShape.isRequired,
@@ -60,7 +65,9 @@ class Toast extends React.Component {
render() {
const { visible } = this.state;
- const { toast: { toastType, text } } = this.props;
+ const {
+ toast: { toastType, text },
+ } = this.props;
return (
<Alert
diff --git a/superset/assets/src/dashboard/v2/components/ToastPresenter.jsx b/superset/assets/src/dashboard/components/ToastPresenter.jsx
similarity index 81%
rename from superset/assets/src/dashboard/v2/components/ToastPresenter.jsx
rename to superset/assets/src/dashboard/components/ToastPresenter.jsx
index 95a0251..19d44b0 100644
--- a/superset/assets/src/dashboard/v2/components/ToastPresenter.jsx
+++ b/superset/assets/src/dashboard/components/ToastPresenter.jsx
@@ -19,16 +19,13 @@ class ToastPresenter extends React.Component {
const { toasts, removeToast } = this.props;
return (
- toasts.length > 0 &&
+ toasts.length > 0 && (
<div className="toast-presenter">
{toasts.map(toast => (
- <Toast
- key={toast.id}
- toast={toast}
- onCloseToast={removeToast}
- />
+ <Toast key={toast.id} toast={toast} onCloseToast={removeToast} />
))}
</div>
+ )
);
}
}
diff --git a/superset/assets/src/dashboard/components/dnd/AddSliceDragPreview.jsx b/superset/assets/src/dashboard/components/dnd/AddSliceDragPreview.jsx
new file mode 100644
index 0000000..94cab42
--- /dev/null
+++ b/superset/assets/src/dashboard/components/dnd/AddSliceDragPreview.jsx
@@ -0,0 +1,70 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { DragLayer } from 'react-dnd';
+
+import AddSliceCard from '../AddSliceCard';
+import { slicePropShape } from '../../util/propShapes';
+import {
+ NEW_COMPONENT_SOURCE_TYPE,
+ CHART_TYPE,
+} from '../../util/componentTypes';
+
+const propTypes = {
+ dragItem: PropTypes.shape({
+ index: PropTypes.number.isRequired,
+ }),
+ slices: PropTypes.arrayOf(slicePropShape),
+ isDragging: PropTypes.bool.isRequired,
+ currentOffset: PropTypes.shape({
+ x: PropTypes.number.isRequired,
+ y: PropTypes.number.isRequired,
+ }),
+};
+
+const defaultProps = {
+ currentOffset: null,
+ dragItem: null,
+ slices: null,
+};
+
+function AddSliceDragPreview({ dragItem, slices, isDragging, currentOffset }) {
+ if (!isDragging || !currentOffset || !dragItem || !slices) return null;
+
+ const slice = slices[dragItem.index];
+
+ // make sure it's a new component and a chart
+ const shouldRender =
+ slice &&
+ dragItem.parentType === NEW_COMPONENT_SOURCE_TYPE &&
+ dragItem.type === CHART_TYPE;
+
+ return !shouldRender ? null : (
+ <AddSliceCard
+ style={{
+ position: 'fixed',
+ background: 'white',
+ pointerEvents: 'none',
+ top: 0,
+ left: 0,
+ zIndex: 100,
+ transform: `translate(${currentOffset.x}px, ${currentOffset.y}px)`,
+ }}
+ sliceName={slice.slice_name}
+ lastModified={
+ slice.modified ? slice.modified.replace(/<[^>]*>/g, '') : ''
+ }
+ visType={slice.viz_type}
+ datasourceLink={slice.datasource_link}
+ />
+ );
+}
+
+AddSliceDragPreview.propTypes = propTypes;
+AddSliceDragPreview.defaultProps = defaultProps;
+
+// This injects these props into the component
+export default DragLayer(monitor => ({
+ dragItem: monitor.getItem(),
+ currentOffset: monitor.getSourceClientOffset(),
+ isDragging: monitor.isDragging(),
+}))(AddSliceDragPreview);
diff --git a/superset/assets/src/dashboard/v2/components/dnd/DragDroppable.jsx b/superset/assets/src/dashboard/components/dnd/DragDroppable.jsx
similarity index 65%
rename from superset/assets/src/dashboard/v2/components/dnd/DragDroppable.jsx
rename to superset/assets/src/dashboard/components/dnd/DragDroppable.jsx
index 775e092..bfe4973 100644
--- a/superset/assets/src/dashboard/v2/components/dnd/DragDroppable.jsx
+++ b/superset/assets/src/dashboard/components/dnd/DragDroppable.jsx
@@ -1,3 +1,4 @@
+import { getEmptyImage } from 'react-dnd-html5-backend';
import React from 'react';
import PropTypes from 'prop-types';
import { DragSource, DropTarget } from 'react-dnd';
@@ -5,7 +6,12 @@ import cx from 'classnames';
import { componentShape } from '../../util/propShapes';
import { dragConfig, dropConfig } from './dragDroppableConfig';
-import { DROP_TOP, DROP_RIGHT, DROP_BOTTOM, DROP_LEFT } from '../../util/getDropPosition';
+import {
+ DROP_TOP,
+ DROP_RIGHT,
+ DROP_BOTTOM,
+ DROP_LEFT,
+} from '../../util/getDropPosition';
const propTypes = {
children: PropTypes.func,
@@ -19,6 +25,7 @@ const propTypes = {
style: PropTypes.object,
onDrop: PropTypes.func,
editMode: PropTypes.bool.isRequired,
+ useEmptyDragPreview: PropTypes.bool,
// from react-dnd
isDragging: PropTypes.bool.isRequired,
@@ -37,6 +44,7 @@ const defaultProps = {
children() {},
onDrop() {},
orientation: 'row',
+ useEmptyDragPreview: false,
};
class DragDroppable extends React.Component {
@@ -58,7 +66,16 @@ class DragDroppable extends React.Component {
setRef(ref) {
this.ref = ref;
- this.props.dragPreviewRef(ref);
+ // this is needed for a custom drag preview
+ if (this.props.useEmptyDragPreview) {
+ this.props.dragPreviewRef(getEmptyImage(), {
+ // IE fallback: specify that we'd rather screenshot the node
+ // when it already knows it's being dragged so we can hide it with CSS.
+ captureDraggingState: true,
+ });
+ } else {
+ this.props.dragPreviewRef(ref);
+ }
this.props.droppableRef(ref);
}
@@ -74,8 +91,6 @@ class DragDroppable extends React.Component {
editMode,
} = this.props;
- if (!editMode) return children({});
-
const { dropIndicator } = this.state;
return (
@@ -90,18 +105,23 @@ class DragDroppable extends React.Component {
className,
)}
>
- {children({
- dragSourceRef,
- dropIndicatorProps: isDraggingOver && dropIndicator && {
- className: cx(
- 'drop-indicator',
- dropIndicator === DROP_TOP && 'drop-indicator--top',
- dropIndicator === DROP_BOTTOM && 'drop-indicator--bottom',
- dropIndicator === DROP_LEFT && 'drop-indicator--left',
- dropIndicator === DROP_RIGHT && 'drop-indicator--right',
- ),
- },
- })}
+ {children(
+ !editMode
+ ? {}
+ : {
+ dragSourceRef,
+ dropIndicatorProps: isDraggingOver &&
+ dropIndicator && {
+ className: cx(
+ 'drop-indicator',
+ dropIndicator === DROP_TOP && 'drop-indicator--top',
+ dropIndicator === DROP_BOTTOM && 'drop-indicator--bottom',
+ dropIndicator === DROP_LEFT && 'drop-indicator--left',
+ dropIndicator === DROP_RIGHT && 'drop-indicator--right',
+ ),
+ },
+ },
+ )}
</div>
);
}
diff --git a/superset/assets/src/dashboard/v2/components/dnd/DragHandle.jsx b/superset/assets/src/dashboard/components/dnd/DragHandle.jsx
similarity index 82%
rename from superset/assets/src/dashboard/v2/components/dnd/DragHandle.jsx
rename to superset/assets/src/dashboard/components/dnd/DragHandle.jsx
index 36d1e6b..23d7d11 100644
--- a/superset/assets/src/dashboard/v2/components/dnd/DragHandle.jsx
+++ b/superset/assets/src/dashboard/components/dnd/DragHandle.jsx
@@ -26,9 +26,11 @@ export default class DragHandle extends React.PureComponent {
position === 'top' && 'drag-handle--top',
)}
>
- {Array(dotCount).fill(null).map((_, i) => (
- <div key={`handle-dot-${i}`} className="drag-handle-dot" />
- ))}
+ {Array(dotCount)
+ .fill(null)
+ .map((_, i) => (
+ <div key={`handle-dot-${i}`} className="drag-handle-dot" />
+ ))}
</div>
);
}
diff --git a/superset/assets/src/dashboard/v2/components/dnd/dragDroppableConfig.js b/superset/assets/src/dashboard/components/dnd/dragDroppableConfig.js
similarity index 88%
rename from superset/assets/src/dashboard/v2/components/dnd/dragDroppableConfig.js
rename to superset/assets/src/dashboard/components/dnd/dragDroppableConfig.js
index 54ce67e..36c34a0 100644
--- a/superset/assets/src/dashboard/v2/components/dnd/dragDroppableConfig.js
+++ b/superset/assets/src/dashboard/components/dnd/dragDroppableConfig.js
@@ -38,15 +38,11 @@ export const dropConfig = [
{
hover(props, monitor, component) {
if (
- component
- && component.decoratedComponentInstance
- && component.decoratedComponentInstance.mounted
+ component &&
+ component.decoratedComponentInstance &&
+ component.decoratedComponentInstance.mounted
) {
- handleHover(
- props,
- monitor,
- component.decoratedComponentInstance,
- );
+ handleHover(props, monitor, component.decoratedComponentInstance);
}
},
// note:
diff --git a/superset/assets/src/dashboard/v2/components/dnd/handleDrop.js b/superset/assets/src/dashboard/components/dnd/handleDrop.js
similarity index 73%
rename from superset/assets/src/dashboard/v2/components/dnd/handleDrop.js
rename to superset/assets/src/dashboard/components/dnd/handleDrop.js
index 7cb630d..3739b18 100644
--- a/superset/assets/src/dashboard/v2/components/dnd/handleDrop.js
+++ b/superset/assets/src/dashboard/components/dnd/handleDrop.js
@@ -1,4 +1,9 @@
-import getDropPosition, { DROP_TOP, DROP_RIGHT, DROP_BOTTOM, DROP_LEFT } from '../../util/getDropPosition';
+import getDropPosition, {
+ DROP_TOP,
+ DROP_RIGHT,
+ DROP_BOTTOM,
+ DROP_LEFT,
+} from '../../util/getDropPosition';
export default function handleDrop(props, monitor, Component) {
// this may happen due to throttling
@@ -22,9 +27,12 @@ export default function handleDrop(props, monitor, Component) {
const draggingItem = monitor.getItem();
const dropAsChildOrSibling =
- (orientation === 'row' && (dropPosition === DROP_TOP || dropPosition === DROP_BOTTOM)) ||
- (orientation === 'column' && (dropPosition === DROP_LEFT || dropPosition === DROP_RIGHT))
- ? 'sibling' : 'child';
+ (orientation === 'row' &&
+ (dropPosition === DROP_TOP || dropPosition === DROP_BOTTOM)) ||
+ (orientation === 'column' &&
+ (dropPosition === DROP_LEFT || dropPosition === DROP_RIGHT))
+ ? 'sibling'
+ : 'child';
const dropResult = {
source: {
@@ -49,8 +57,10 @@ export default function handleDrop(props, monitor, Component) {
} else {
// if the item is in the same list with a smaller index, you must account for the
// "missing" index upon movement within the list
- const sameParent = parentComponent && draggingItem.parentId === parentComponent.id;
- const sameParentLowerIndex = sameParent && draggingItem.index < componentIndex;
+ const sameParent =
+ parentComponent && draggingItem.parentId === parentComponent.id;
+ const sameParentLowerIndex =
+ sameParent && draggingItem.index < componentIndex;
let nextIndex = sameParentLowerIndex ? componentIndex - 1 : componentIndex;
if (dropPosition === DROP_BOTTOM || dropPosition === DROP_RIGHT) {
diff --git a/superset/assets/src/dashboard/v2/components/dnd/handleHover.js b/superset/assets/src/dashboard/components/dnd/handleHover.js
similarity index 100%
rename from superset/assets/src/dashboard/v2/components/dnd/handleHover.js
rename to superset/assets/src/dashboard/components/dnd/handleHover.js
diff --git a/superset/assets/src/dashboard/components/gridComponents/Chart.jsx b/superset/assets/src/dashboard/components/gridComponents/Chart.jsx
new file mode 100644
index 0000000..54e1536
--- /dev/null
+++ b/superset/assets/src/dashboard/components/gridComponents/Chart.jsx
@@ -0,0 +1,233 @@
+import cx from 'classnames';
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { exportChart } from '../../../explore/exploreUtils';
+import SliceHeader from '../SliceHeader';
+import ChartContainer from '../../../chart/ChartContainer';
+import { chartPropType } from '../../../chart/chartReducer';
+import { slicePropShape } from '../../util/propShapes';
+import { VIZ_TYPES } from '../../../visualizations/main';
+
+const propTypes = {
+ id: PropTypes.number.isRequired,
+ width: PropTypes.number.isRequired,
+ height: PropTypes.number.isRequired,
+
+ // from redux
+ chart: PropTypes.shape(chartPropType).isRequired,
+ formData: PropTypes.object.isRequired,
+ datasource: PropTypes.object.isRequired,
+ slice: slicePropShape.isRequired,
+ timeout: PropTypes.number.isRequired,
+ filters: PropTypes.object.isRequired,
+ refreshChart: PropTypes.func.isRequired,
+ saveSliceName: PropTypes.func.isRequired,
+ toggleExpandSlice: PropTypes.func.isRequired,
+ addFilter: PropTypes.func.isRequired,
+ removeFilter: PropTypes.func.isRequired,
+ editMode: PropTypes.bool.isRequired,
+ isExpanded: PropTypes.bool.isRequired,
+};
+
+// we use state + shouldComponentUpdate() logic to prevent perf-wrecking
+// resizing across all slices on a dashboard on every update
+const RESIZE_TIMEOUT = 350;
+const SHOULD_UPDATE_ON_PROP_CHANGES = Object.keys(propTypes).filter(
+ prop => prop !== 'width' && prop !== 'height',
+);
+const OVERFLOWABLE_VIZ_TYPES = new Set([VIZ_TYPES.filter_box]);
+
+class Chart extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ width: props.width,
+ height: props.height,
+ };
+
+ this.addFilter = this.addFilter.bind(this);
+ this.exploreChart = this.exploreChart.bind(this);
+ this.exportCSV = this.exportCSV.bind(this);
+ this.forceRefresh = this.forceRefresh.bind(this);
+ this.getFilters = this.getFilters.bind(this);
+ this.removeFilter = this.removeFilter.bind(this);
+ this.resize = this.resize.bind(this);
+ this.setDescriptionRef = this.setDescriptionRef.bind(this);
+ this.setHeaderRef = this.setHeaderRef.bind(this);
+ }
+
+ shouldComponentUpdate(nextProps, nextState) {
+ // this logic mostly pertains to chart resizing. we keep a copy of the dimensions in
+ // state so that we can buffer component size updates and only update on the final call
+ // which improves performance significantly
+ if (
+ nextState.width !== this.state.width ||
+ nextState.height !== this.state.height
+ ) {
+ return true;
+ }
+
+ for (let i = 0; i < SHOULD_UPDATE_ON_PROP_CHANGES.length; i += 1) {
+ const prop = SHOULD_UPDATE_ON_PROP_CHANGES[i];
+ if (nextProps[prop] !== this.props[prop]) {
+ return true;
+ }
+ }
+
+ if (
+ nextProps.width !== this.props.width ||
+ nextProps.height !== this.props.height
+ ) {
+ clearTimeout(this.resizeTimeout);
+ this.resizeTimeout = setTimeout(this.resize, RESIZE_TIMEOUT);
+ }
+
+ return false;
+ }
+
+ componentWillUnmount() {
+ clearTimeout(this.resizeTimeout);
+ }
+
+ getFilters() {
+ return this.props.filters;
+ }
+
+ getChartHeight() {
+ const headerHeight = this.getHeaderHeight();
+ const descriptionHeight =
+ this.props.isExpanded && this.descriptionRef
+ ? this.descriptionRef.offsetHeight
+ : 0;
+
+ return this.state.height - headerHeight - descriptionHeight;
+ }
+
+ getHeaderHeight() {
+ return (this.headerRef && this.headerRef.offsetHeight) || 30;
+ }
+
+ setDescriptionRef(ref) {
+ this.descriptionRef = ref;
+ }
+
+ setHeaderRef(ref) {
+ this.headerRef = ref;
+ }
+
+ resize() {
+ const { width, height } = this.props;
+ this.setState(() => ({ width, height }));
+ }
+
+ addFilter(...args) {
+ this.props.addFilter(this.props.chart, ...args);
+ }
+
+ exploreChart() {
+ exportChart(this.props.formData);
+ }
+
+ exportCSV() {
+ exportChart(this.props.formData, 'csv');
+ }
+
+ forceRefresh() {
+ return this.props.refreshChart(this.props.chart, true, this.props.timeout);
+ }
+
+ removeFilter(args) {
+ this.props.removeFilter(this.props.id, ...args);
+ }
+
+ render() {
+ const {
+ id,
+ chart,
+ slice,
+ datasource,
+ isExpanded,
+ editMode,
+ formData,
+ toggleExpandSlice,
+ timeout,
+ } = this.props;
+
+ const { width } = this.state;
+ const { queryResponse } = chart;
+ const isCached = queryResponse && queryResponse.is_cached;
+ const cachedDttm = queryResponse && queryResponse.cached_dttm;
+ const isOverflowable = OVERFLOWABLE_VIZ_TYPES.has(slice && slice.viz_type);
+
+ return (
+ <div
+ className={cx(
+ 'dashboard-chart',
+ isOverflowable && 'dashboard-chart--overflowable',
+ )}
+ >
+ <SliceHeader
+ innerRef={this.setHeaderRef}
+ slice={slice}
+ isExpanded={!!isExpanded}
+ isCached={isCached}
+ cachedDttm={cachedDttm}
+ updateSliceName={this.updateSliceName}
+ toggleExpandSlice={toggleExpandSlice}
+ forceRefresh={this.forceRefresh}
+ editMode={editMode}
+ annotationQuery={chart.annotationQuery}
+ exploreChart={this.exploreChart}
+ exportCSV={this.exportCSV}
+ />
+
+ {/*
+ This usage of dangerouslySetInnerHTML is safe since it is being used to render
+ markdown that is sanitized with bleach. See:
+ https://github.com/apache/incubator-superset/pull/4390
+ and
+ https://github.com/apache/incubator-superset/commit/b6fcc22d5a2cb7a5e92599ed5795a0169385a825
+ */}
+ {isExpanded &&
+ slice.description_markeddown && (
+ <div
+ className="slice_description bs-callout bs-callout-default"
+ ref={this.setDescriptionRef}
+ // eslint-disable-next-line react/no-danger
+ dangerouslySetInnerHTML={{ __html: slice.description_markeddown }}
+ />
+ )}
+
+ <ChartContainer
+ containerId={`slice-container-${id}`}
+ chartId={id}
+ datasource={datasource}
+ formData={formData}
+ headerHeight={this.getHeaderHeight()}
+ height={this.getChartHeight()}
+ width={width}
+ timeout={timeout}
+ vizType={slice.viz_type}
+ addFilter={this.addFilter}
+ getFilters={this.getFilters}
+ removeFilter={this.removeFilter}
+ annotationData={chart.annotationData}
+ chartAlert={chart.chartAlert}
+ chartStatus={chart.chartStatus}
+ chartUpdateEndTime={chart.chartUpdateEndTime}
+ chartUpdateStartTime={chart.chartUpdateStartTime}
+ latestQueryFormData={chart.latestQueryFormData}
+ lastRendered={chart.lastRendered}
+ queryResponse={chart.queryResponse}
+ queryRequest={chart.queryRequest}
+ triggerQuery={chart.triggerQuery}
+ />
+ </div>
+ );
+ }
+}
+
+Chart.propTypes = propTypes;
+
+export default Chart;
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/ChartHolder.jsx b/superset/assets/src/dashboard/components/gridComponents/ChartHolder.jsx
similarity index 68%
rename from superset/assets/src/dashboard/v2/components/gridComponents/ChartHolder.jsx
rename to superset/assets/src/dashboard/components/gridComponents/ChartHolder.jsx
index 2aed4b2..a684230 100644
--- a/superset/assets/src/dashboard/v2/components/gridComponents/ChartHolder.jsx
+++ b/superset/assets/src/dashboard/components/gridComponents/ChartHolder.jsx
@@ -1,15 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
+import Chart from '../../containers/Chart';
import DeleteComponentButton from '../DeleteComponentButton';
import DragDroppable from '../dnd/DragDroppable';
import DragHandle from '../dnd/DragHandle';
import HoverMenu from '../menu/HoverMenu';
import ResizableContainer from '../resizable/ResizableContainer';
-import WithPopoverMenu from '../menu/WithPopoverMenu';
import { componentShape } from '../../util/propShapes';
-import { ROW_TYPE } from '../../util/componentTypes';
-import { GRID_MIN_COLUMN_COUNT, GRID_MIN_ROW_UNITS } from '../../util/constants';
+import { ROW_TYPE, COLUMN_TYPE } from '../../util/componentTypes';
+import {
+ GRID_MIN_COLUMN_COUNT,
+ GRID_MIN_ROW_UNITS,
+ GRID_BASE_UNIT,
+} from '../../util/constants';
+
+const CHART_MARGIN = 32;
const propTypes = {
id: PropTypes.string.isRequired,
@@ -19,7 +25,6 @@ const propTypes = {
index: PropTypes.number.isRequired,
depth: PropTypes.number.isRequired,
editMode: PropTypes.bool.isRequired,
- chart: PropTypes.object.isRequired,
// grid related
availableColumnCount: PropTypes.number.isRequired,
@@ -33,8 +38,7 @@ const propTypes = {
handleComponentDrop: PropTypes.func.isRequired,
};
-const defaultProps = {
-};
+const defaultProps = {};
class ChartHolder extends React.Component {
constructor(props) {
@@ -73,6 +77,12 @@ class ChartHolder extends React.Component {
editMode,
} = this.props;
+ // inherit the size of parent columns
+ const widthMultiple =
+ parentComponent.type === COLUMN_TYPE
+ ? parentComponent.meta.width || GRID_MIN_COLUMN_COUNT
+ : component.meta.width || GRID_MIN_COLUMN_COUNT;
+
return (
<DragDroppable
component={component}
@@ -90,34 +100,37 @@ class ChartHolder extends React.Component {
adjustableWidth={parentComponent.type === ROW_TYPE}
adjustableHeight
widthStep={columnWidth}
- widthMultiple={component.meta.width}
+ widthMultiple={widthMultiple}
+ heightStep={GRID_BASE_UNIT}
heightMultiple={component.meta.height}
minWidthMultiple={GRID_MIN_COLUMN_COUNT}
minHeightMultiple={GRID_MIN_ROW_UNITS}
- maxWidthMultiple={availableColumnCount + (component.meta.width || 0)}
+ maxWidthMultiple={availableColumnCount + widthMultiple}
onResizeStart={onResizeStart}
onResize={onResize}
onResizeStop={onResizeStop}
editMode={editMode}
>
- {editMode &&
- <HoverMenu innerRef={dragSourceRef} position="top">
- <DragHandle position="top" />
- </HoverMenu>}
-
- <WithPopoverMenu
- onChangeFocus={this.handleChangeFocus}
- menuItems={[
- <DeleteComponentButton onDelete={this.handleDeleteComponent} />,
- ]}
- editMode={editMode}
+ <div
+ ref={dragSourceRef}
+ className="dashboard-component dashboard-component-chart-holder"
>
- <div className="dashboard-component dashboard-component-chart">
- {this.props.chart}
- </div>
-
- {dropIndicatorProps && <div {...dropIndicatorProps} />}
- </WithPopoverMenu>
+ <Chart
+ id={component.meta.chartId}
+ width={widthMultiple * columnWidth}
+ height={component.meta.height * GRID_BASE_UNIT - CHART_MARGIN}
+ />
+ {editMode && (
+ <HoverMenu position="top">
+ <DragHandle position="top" />
+ <DeleteComponentButton
+ onDelete={this.handleDeleteComponent}
+ />
+ </HoverMenu>
+ )}
+ </div>
+
+ {dropIndicatorProps && <div {...dropIndicatorProps} />}
</ResizableContainer>
)}
</DragDroppable>
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/Column.jsx b/superset/assets/src/dashboard/components/gridComponents/Column.jsx
similarity index 82%
rename from superset/assets/src/dashboard/v2/components/gridComponents/Column.jsx
rename to superset/assets/src/dashboard/components/gridComponents/Column.jsx
index 490d7bd..a71d732 100644
--- a/superset/assets/src/dashboard/v2/components/gridComponents/Column.jsx
+++ b/superset/assets/src/dashboard/components/gridComponents/Column.jsx
@@ -25,7 +25,6 @@ const propTypes = {
index: PropTypes.number.isRequired,
depth: PropTypes.number.isRequired,
editMode: PropTypes.bool.isRequired,
- cells: PropTypes.object.isRequired,
// grid related
availableColumnCount: PropTypes.number.isRequired,
@@ -41,8 +40,7 @@ const propTypes = {
updateComponents: PropTypes.func.isRequired,
};
-const defaultProps = {
-};
+const defaultProps = {};
class Column extends React.PureComponent {
constructor(props) {
@@ -50,7 +48,10 @@ class Column extends React.PureComponent {
this.state = {
isFocused: false,
};
- this.handleChangeBackground = this.handleUpdateMeta.bind(this, 'background');
+ this.handleChangeBackground = this.handleUpdateMeta.bind(
+ this,
+ 'background',
+ );
this.handleChangeFocus = this.handleChangeFocus.bind(this);
this.handleDeleteComponent = this.handleDeleteComponent.bind(this);
}
@@ -93,12 +94,13 @@ class Column extends React.PureComponent {
onResizeStop,
handleComponentDrop,
editMode,
- cells,
} = this.props;
const columnItems = columnComponent.children || [];
const backgroundStyle = backgroundStyleOptions.find(
- opt => opt.value === (columnComponent.meta.background || BACKGROUND_TRANSPARENT),
+ opt =>
+ opt.value ===
+ (columnComponent.meta.background || BACKGROUND_TRANSPARENT),
);
return (
@@ -119,7 +121,9 @@ class Column extends React.PureComponent {
widthStep={columnWidth}
widthMultiple={columnComponent.meta.width}
minWidthMultiple={minColumnWidth}
- maxWidthMultiple={availableColumnCount + (columnComponent.meta.width || 0)}
+ maxWidthMultiple={
+ availableColumnCount + (columnComponent.meta.width || 0)
+ }
onResizeStart={onResizeStart}
onResize={onResize}
onResizeStop={onResizeStop}
@@ -145,31 +149,33 @@ class Column extends React.PureComponent {
backgroundStyle.className,
)}
>
- {editMode &&
+ {editMode && (
<HoverMenu innerRef={dragSourceRef} position="top">
<DragHandle position="top" />
- <DeleteComponentButton onDelete={this.handleDeleteComponent} />
+ <DeleteComponentButton
+ onDelete={this.handleDeleteComponent}
+ />
<IconButton
onClick={this.handleChangeFocus}
className="fa fa-cog"
/>
- </HoverMenu>}
+ </HoverMenu>
+ )}
{columnItems.map((componentId, itemIndex) => (
- <DashboardComponent
- key={componentId}
- id={componentId}
- parentId={columnComponent.id}
- depth={depth + 1}
- index={itemIndex }
- availableColumnCount={columnComponent.meta.width}
- columnWidth={columnWidth}
- cells={cells}
- onResizeStart={onResizeStart}
- onResize={onResize}
- onResizeStop={onResizeStop}
- />
- ))}
+ <DashboardComponent
+ key={componentId}
+ id={componentId}
+ parentId={columnComponent.id}
+ depth={depth + 1}
+ index={itemIndex}
+ availableColumnCount={columnComponent.meta.width}
+ columnWidth={columnWidth}
+ onResizeStart={onResizeStart}
+ onResize={onResize}
+ onResizeStop={onResizeStop}
+ />
+ ))}
{dropIndicatorProps && <div {...dropIndicatorProps} />}
</div>
@@ -177,7 +183,6 @@ class Column extends React.PureComponent {
</ResizableContainer>
)}
</DragDroppable>
-
);
}
}
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/Divider.jsx b/superset/assets/src/dashboard/components/gridComponents/Divider.jsx
similarity index 96%
rename from superset/assets/src/dashboard/v2/components/gridComponents/Divider.jsx
rename to superset/assets/src/dashboard/components/gridComponents/Divider.jsx
index b3010e9..7c7936d 100644
--- a/superset/assets/src/dashboard/v2/components/gridComponents/Divider.jsx
+++ b/superset/assets/src/dashboard/components/gridComponents/Divider.jsx
@@ -51,10 +51,11 @@ class Divider extends React.PureComponent {
>
{({ dropIndicatorProps, dragSourceRef }) => (
<div ref={dragSourceRef}>
- {editMode &&
+ {editMode && (
<HoverMenu position="left">
<DeleteComponentButton onDelete={this.handleDeleteComponent} />
- </HoverMenu>}
+ </HoverMenu>
+ )}
<div className="dashboard-component dashboard-component-divider" />
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/Header.jsx b/superset/assets/src/dashboard/components/gridComponents/Header.jsx
similarity index 93%
rename from superset/assets/src/dashboard/v2/components/gridComponents/Header.jsx
rename to superset/assets/src/dashboard/components/gridComponents/Header.jsx
index 97945a9..5114a77 100644
--- a/superset/assets/src/dashboard/v2/components/gridComponents/Header.jsx
+++ b/superset/assets/src/dashboard/components/gridComponents/Header.jsx
@@ -4,7 +4,7 @@ import cx from 'classnames';
import DragDroppable from '../dnd/DragDroppable';
import DragHandle from '../dnd/DragHandle';
-import EditableTitle from '../../../../components/EditableTitle';
+import EditableTitle from '../../../components/EditableTitle';
import HoverMenu from '../menu/HoverMenu';
import WithPopoverMenu from '../menu/WithPopoverMenu';
import BackgroundStyleDropdown from '../menu/BackgroundStyleDropdown';
@@ -30,8 +30,7 @@ const propTypes = {
updateComponents: PropTypes.func.isRequired,
};
-const defaultProps = {
-};
+const defaultProps = {};
class Header extends React.PureComponent {
constructor(props) {
@@ -43,7 +42,10 @@ class Header extends React.PureComponent {
this.handleChangeFocus = this.handleChangeFocus.bind(this);
this.handleUpdateMeta = this.handleUpdateMeta.bind(this);
this.handleChangeSize = this.handleUpdateMeta.bind(this, 'headerSize');
- this.handleChangeBackground = this.handleUpdateMeta.bind(this, 'background');
+ this.handleChangeBackground = this.handleUpdateMeta.bind(
+ this,
+ 'background',
+ );
this.handleChangeText = this.handleUpdateMeta.bind(this, 'text');
}
@@ -88,7 +90,8 @@ class Header extends React.PureComponent {
);
const rowStyle = backgroundStyleOptions.find(
- opt => opt.value === (component.meta.background || BACKGROUND_TRANSPARENT),
+ opt =>
+ opt.value === (component.meta.background || BACKGROUND_TRANSPARENT),
);
return (
@@ -104,10 +107,11 @@ class Header extends React.PureComponent {
>
{({ dropIndicatorProps, dragSourceRef }) => (
<div ref={dragSourceRef}>
- {editMode &&
+ {editMode && (
<HoverMenu position="left">
<DragHandle position="left" />
- </HoverMenu>}
+ </HoverMenu>
+ )}
<WithPopoverMenu
onChangeFocus={this.handleChangeFocus}
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/Row.jsx b/superset/assets/src/dashboard/components/gridComponents/Row.jsx
similarity index 82%
rename from superset/assets/src/dashboard/v2/components/gridComponents/Row.jsx
rename to superset/assets/src/dashboard/components/gridComponents/Row.jsx
index 8faaee1..91f200d 100644
--- a/superset/assets/src/dashboard/v2/components/gridComponents/Row.jsx
+++ b/superset/assets/src/dashboard/components/gridComponents/Row.jsx
@@ -23,7 +23,6 @@ const propTypes = {
index: PropTypes.number.isRequired,
depth: PropTypes.number.isRequired,
editMode: PropTypes.bool.isRequired,
- cells: PropTypes.object.isRequired,
// grid related
availableColumnCount: PropTypes.number.isRequired,
@@ -51,7 +50,10 @@ class Row extends React.PureComponent {
};
this.handleDeleteComponent = this.handleDeleteComponent.bind(this);
this.handleUpdateMeta = this.handleUpdateMeta.bind(this);
- this.handleChangeBackground = this.handleUpdateMeta.bind(this, 'background');
+ this.handleChangeBackground = this.handleUpdateMeta.bind(
+ this,
+ 'background',
+ );
this.handleChangeFocus = this.handleChangeFocus.bind(this);
}
@@ -93,13 +95,13 @@ class Row extends React.PureComponent {
onResizeStop,
handleComponentDrop,
editMode,
- cells,
} = this.props;
const rowItems = rowComponent.children || [];
const backgroundStyle = backgroundStyleOptions.find(
- opt => opt.value === (rowComponent.meta.background || BACKGROUND_TRANSPARENT),
+ opt =>
+ opt.value === (rowComponent.meta.background || BACKGROUND_TRANSPARENT),
);
return (
@@ -133,31 +135,35 @@ class Row extends React.PureComponent {
backgroundStyle.className,
)}
>
- {editMode &&
+ {editMode && (
<HoverMenu innerRef={dragSourceRef} position="left">
<DragHandle position="left" />
- <DeleteComponentButton onDelete={this.handleDeleteComponent} />
+ <DeleteComponentButton
+ onDelete={this.handleDeleteComponent}
+ />
<IconButton
onClick={this.handleChangeFocus}
className="fa fa-cog"
/>
- </HoverMenu>}
+ </HoverMenu>
+ )}
{rowItems.map((componentId, itemIndex) => (
-
- <DashboardComponent
- key={componentId}
- id={componentId}
- parentId={rowComponent.id}
- depth={depth + 1}
- index={itemIndex }
- availableColumnCount={availableColumnCount - occupiedColumnCount}
- columnWidth={columnWidth}
- cells={cells}onResizeStart={onResizeStart}
- onResize={onResize}
- onResizeStop={onResizeStop}
- />
- ))}
+ <DashboardComponent
+ key={componentId}
+ id={componentId}
+ parentId={rowComponent.id}
+ depth={depth + 1}
+ index={itemIndex}
+ availableColumnCount={
+ availableColumnCount - occupiedColumnCount
+ }
+ columnWidth={columnWidth}
+ onResizeStart={onResizeStart}
+ onResize={onResize}
+ onResizeStop={onResizeStop}
+ />
+ ))}
{dropIndicatorProps && <div {...dropIndicatorProps} />}
</div>
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/Tab.jsx b/superset/assets/src/dashboard/components/gridComponents/Tab.jsx
similarity index 90%
rename from superset/assets/src/dashboard/v2/components/gridComponents/Tab.jsx
rename to superset/assets/src/dashboard/components/gridComponents/Tab.jsx
index 218c4e7..d73bc0c 100644
--- a/superset/assets/src/dashboard/v2/components/gridComponents/Tab.jsx
+++ b/superset/assets/src/dashboard/components/gridComponents/Tab.jsx
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import DashboardComponent from '../../containers/DashboardComponent';
import DragDroppable from '../dnd/DragDroppable';
-import EditableTitle from '../../../../components/EditableTitle';
+import EditableTitle from '../../../components/EditableTitle';
import DeleteComponentButton from '../DeleteComponentButton';
import WithPopoverMenu from '../menu/WithPopoverMenu';
import { componentShape } from '../../util/propShapes';
@@ -123,13 +123,7 @@ export default class Tab extends React.PureComponent {
renderTab() {
const { isFocused } = this.state;
- const {
- component,
- parentComponent,
- index,
- depth,
- editMode,
- } = this.props;
+ const { component, parentComponent, index, depth, editMode } = this.props;
return (
<DragDroppable
@@ -149,9 +143,15 @@ export default class Tab extends React.PureComponent {
<div className="dragdroppable-tab" ref={dragSourceRef}>
<WithPopoverMenu
onChangeFocus={this.handleChangeFocus}
- menuItems={parentComponent.children.length <= 1 ? [] : [
- <DeleteComponentButton onDelete={this.handleDeleteComponent} />,
- ]}
+ menuItems={
+ parentComponent.children.length <= 1
+ ? []
+ : [
+ <DeleteComponentButton
+ onDelete={this.handleDeleteComponent}
+ />,
+ ]
+ }
editMode={editMode}
>
<EditableTitle
@@ -171,7 +171,9 @@ export default class Tab extends React.PureComponent {
render() {
const { renderType } = this.props;
- return renderType === RENDER_TAB ? this.renderTab() : this.renderTabContent();
+ return renderType === RENDER_TAB
+ ? this.renderTab()
+ : this.renderTabContent();
}
}
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/Tabs.jsx b/superset/assets/src/dashboard/components/gridComponents/Tabs.jsx
similarity index 81%
rename from superset/assets/src/dashboard/v2/components/gridComponents/Tabs.jsx
rename to superset/assets/src/dashboard/components/gridComponents/Tabs.jsx
index 1f5f0c6..585041f 100644
--- a/superset/assets/src/dashboard/v2/components/gridComponents/Tabs.jsx
+++ b/superset/assets/src/dashboard/components/gridComponents/Tabs.jsx
@@ -106,9 +106,10 @@ class Tabs extends React.PureComponent {
// Ensure dropped tab is visible
const { destination } = dropResult;
if (destination) {
- const dropTabIndex = destination.id === component.id
- ? destination.index // dropped ON tabs
- : component.children.indexOf(destination.id); // dropped IN tab
+ const dropTabIndex =
+ destination.id === component.id
+ ? destination.index // dropped ON tabs
+ : component.children.indexOf(destination.id); // dropped IN tab
if (dropTabIndex > -1) {
setTimeout(() => {
@@ -147,13 +148,17 @@ class Tabs extends React.PureComponent {
onDrop={handleComponentDrop}
editMode={editMode}
>
- {({ dropIndicatorProps: tabsDropIndicatorProps, dragSourceRef: tabsDragSourceRef }) => (
+ {({
+ dropIndicatorProps: tabsDropIndicatorProps,
+ dragSourceRef: tabsDragSourceRef,
+ }) => (
<div className="dashboard-component dashboard-component-tabs">
- {editMode &&
+ {editMode && (
<HoverMenu innerRef={tabsDragSourceRef} position="left">
<DragHandle position="left" />
<DeleteComponentButton onDelete={this.handleDeleteComponent} />
- </HoverMenu>}
+ </HoverMenu>
+ )}
<BootstrapTabs
id={tabsComponent.id}
@@ -187,37 +192,39 @@ class Tabs extends React.PureComponent {
render potentially-expensive charts (this also enables lazy loading
their content)
*/}
- {tabIndex === selectedTabIndex && renderTabContent &&
- <DashboardComponent
- id={tabId}
- parentId={tabsComponent.id}
- depth={depth} // see isValidChild.js for why tabs don't increment child depth
- index={tabIndex}
- renderType={RENDER_TAB_CONTENT}
- availableColumnCount={availableColumnCount}
- columnWidth={columnWidth}
- onResizeStart={onResizeStart}
- onResize={onResize}
- onResizeStop={onResizeStop}
- onDropOnTab={this.handleDropOnTab}
- />}
+ {tabIndex === selectedTabIndex &&
+ renderTabContent && (
+ <DashboardComponent
+ id={tabId}
+ parentId={tabsComponent.id}
+ depth={depth} // see isValidChild.js for why tabs don't increment child depth
+ index={tabIndex}
+ renderType={RENDER_TAB_CONTENT}
+ availableColumnCount={availableColumnCount}
+ columnWidth={columnWidth}
+ onResizeStart={onResizeStart}
+ onResize={onResize}
+ onResizeStop={onResizeStop}
+ onDropOnTab={this.handleDropOnTab}
+ />
+ )}
</BootstrapTab>
))}
{editMode &&
- tabIds.length < MAX_TAB_COUNT &&
+ tabIds.length < MAX_TAB_COUNT && (
<BootstrapTab
eventKey={NEW_TAB_INDEX}
title={<div className="fa fa-plus" />}
- />}
-
+ />
+ )}
</BootstrapTabs>
{/* don't indicate that a drop on root is allowed when tabs already exist */}
- {tabsDropIndicatorProps
- && parentComponent.id !== DASHBOARD_ROOT_ID
- && <div {...tabsDropIndicatorProps} />}
-
+ {tabsDropIndicatorProps &&
+ parentComponent.id !== DASHBOARD_ROOT_ID && (
+ <div {...tabsDropIndicatorProps} />
+ )}
</div>
)}
</DragDroppable>
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/index.js b/superset/assets/src/dashboard/components/gridComponents/index.js
similarity index 94%
rename from superset/assets/src/dashboard/v2/components/gridComponents/index.js
rename to superset/assets/src/dashboard/components/gridComponents/index.js
index ef6d13f..016ab03 100644
--- a/superset/assets/src/dashboard/v2/components/gridComponents/index.js
+++ b/superset/assets/src/dashboard/components/gridComponents/index.js
@@ -3,7 +3,6 @@ import {
COLUMN_TYPE,
DIVIDER_TYPE,
HEADER_TYPE,
- INVISIBLE_ROW_TYPE,
ROW_TYPE,
TAB_TYPE,
TABS_TYPE,
@@ -30,7 +29,6 @@ export default {
[COLUMN_TYPE]: Column,
[DIVIDER_TYPE]: Divider,
[HEADER_TYPE]: Header,
- [INVISIBLE_ROW_TYPE]: Row,
[ROW_TYPE]: Row,
[TAB_TYPE]: Tab,
[TABS_TYPE]: Tabs,
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/new/DraggableNewComponent.jsx b/superset/assets/src/dashboard/components/gridComponents/new/DraggableNewComponent.jsx
similarity index 90%
rename from superset/assets/src/dashboard/v2/components/gridComponents/new/DraggableNewComponent.jsx
rename to superset/assets/src/dashboard/components/gridComponents/new/DraggableNewComponent.jsx
index eebd6e0..d579dc1 100644
--- a/superset/assets/src/dashboard/v2/components/gridComponents/new/DraggableNewComponent.jsx
+++ b/superset/assets/src/dashboard/components/gridComponents/new/DraggableNewComponent.jsx
@@ -23,7 +23,10 @@ export default class DraggableNewComponent extends React.PureComponent {
return (
<DragDroppable
component={{ type, id }}
- parentComponent={{ id: NEW_COMPONENTS_SOURCE_ID, type: NEW_COMPONENT_SOURCE_TYPE }}
+ parentComponent={{
+ id: NEW_COMPONENTS_SOURCE_ID,
+ type: NEW_COMPONENT_SOURCE_TYPE,
+ }}
index={0}
depth={0}
editMode
diff --git a/superset/assets/src/dashboard/components/gridComponents/new/NewColumn.jsx b/superset/assets/src/dashboard/components/gridComponents/new/NewColumn.jsx
new file mode 100644
index 0000000..f624e58
--- /dev/null
+++ b/superset/assets/src/dashboard/components/gridComponents/new/NewColumn.jsx
@@ -0,0 +1,16 @@
+import React from 'react';
+
+import { COLUMN_TYPE } from '../../../util/componentTypes';
+import { NEW_COLUMN_ID } from '../../../util/constants';
+import DraggableNewComponent from './DraggableNewComponent';
+
+export default function DraggableNewColumn() {
+ return (
+ <DraggableNewComponent
+ id={NEW_COLUMN_ID}
+ type={COLUMN_TYPE}
+ label="Column"
+ className="fa fa-long-arrow-down"
+ />
+ );
+}
diff --git a/superset/assets/src/dashboard/components/gridComponents/new/NewDivider.jsx b/superset/assets/src/dashboard/components/gridComponents/new/NewDivider.jsx
new file mode 100644
index 0000000..de07a24
--- /dev/null
+++ b/superset/assets/src/dashboard/components/gridComponents/new/NewDivider.jsx
@@ -0,0 +1,16 @@
+import React from 'react';
+
+import { DIVIDER_TYPE } from '../../../util/componentTypes';
+import { NEW_DIVIDER_ID } from '../../../util/constants';
+import DraggableNewComponent from './DraggableNewComponent';
+
+export default function DraggableNewDivider() {
+ return (
+ <DraggableNewComponent
+ id={NEW_DIVIDER_ID}
+ type={DIVIDER_TYPE}
+ label="Divider"
+ className="divider-placeholder"
+ />
+ );
+}
diff --git a/superset/assets/src/dashboard/components/gridComponents/new/NewHeader.jsx b/superset/assets/src/dashboard/components/gridComponents/new/NewHeader.jsx
new file mode 100644
index 0000000..50bd600
--- /dev/null
+++ b/superset/assets/src/dashboard/components/gridComponents/new/NewHeader.jsx
@@ -0,0 +1,16 @@
+import React from 'react';
+
+import { HEADER_TYPE } from '../../../util/componentTypes';
+import { NEW_HEADER_ID } from '../../../util/constants';
+import DraggableNewComponent from './DraggableNewComponent';
+
+export default function DraggableNewHeader() {
+ return (
+ <DraggableNewComponent
+ id={NEW_HEADER_ID}
+ type={HEADER_TYPE}
+ label="Header"
+ className="fa fa-header"
+ />
+ );
+}
diff --git a/superset/assets/src/dashboard/components/gridComponents/new/NewRow.jsx b/superset/assets/src/dashboard/components/gridComponents/new/NewRow.jsx
new file mode 100644
index 0000000..81bdc93
--- /dev/null
+++ b/superset/assets/src/dashboard/components/gridComponents/new/NewRow.jsx
@@ -0,0 +1,16 @@
+import React from 'react';
+
+import { ROW_TYPE } from '../../../util/componentTypes';
+import { NEW_ROW_ID } from '../../../util/constants';
+import DraggableNewComponent from './DraggableNewComponent';
+
+export default function DraggableNewRow() {
+ return (
+ <DraggableNewComponent
+ id={NEW_ROW_ID}
+ type={ROW_TYPE}
+ label="Row"
+ className="fa fa-long-arrow-right"
+ />
+ );
+}
diff --git a/superset/assets/src/dashboard/components/gridComponents/new/NewTabs.jsx b/superset/assets/src/dashboard/components/gridComponents/new/NewTabs.jsx
new file mode 100644
index 0000000..fd9366b
--- /dev/null
+++ b/superset/assets/src/dashboard/components/gridComponents/new/NewTabs.jsx
@@ -0,0 +1,16 @@
+import React from 'react';
+
+import { TABS_TYPE } from '../../../util/componentTypes';
+import { NEW_TABS_ID } from '../../../util/constants';
+import DraggableNewComponent from './DraggableNewComponent';
+
+export default function DraggableNewTabs() {
+ return (
+ <DraggableNewComponent
+ id={NEW_TABS_ID}
+ type={TABS_TYPE}
+ label="Tabs"
+ className="fa fa-window-restore"
+ />
+ );
+}
diff --git a/superset/assets/src/dashboard/v2/components/menu/BackgroundStyleDropdown.jsx b/superset/assets/src/dashboard/components/menu/BackgroundStyleDropdown.jsx
similarity index 100%
rename from superset/assets/src/dashboard/v2/components/menu/BackgroundStyleDropdown.jsx
rename to superset/assets/src/dashboard/components/menu/BackgroundStyleDropdown.jsx
diff --git a/superset/assets/src/dashboard/v2/components/menu/HoverMenu.jsx b/superset/assets/src/dashboard/components/menu/HoverMenu.jsx
similarity index 100%
rename from superset/assets/src/dashboard/v2/components/menu/HoverMenu.jsx
rename to superset/assets/src/dashboard/components/menu/HoverMenu.jsx
diff --git a/superset/assets/src/dashboard/v2/components/menu/PopoverDropdown.jsx b/superset/assets/src/dashboard/components/menu/PopoverDropdown.jsx
similarity index 94%
rename from superset/assets/src/dashboard/v2/components/menu/PopoverDropdown.jsx
rename to superset/assets/src/dashboard/components/menu/PopoverDropdown.jsx
index 6a56eab..4971793 100644
--- a/superset/assets/src/dashboard/v2/components/menu/PopoverDropdown.jsx
+++ b/superset/assets/src/dashboard/components/menu/PopoverDropdown.jsx
@@ -19,7 +19,9 @@ const propTypes = {
const defaultProps = {
renderButton: option => option.label,
- renderOption: option => <div className={option.className}>{option.label}</div>,
+ renderOption: option => (
+ <div className={option.className}>{option.label}</div>
+ ),
};
class PopoverDropdown extends React.PureComponent {
diff --git a/superset/assets/src/dashboard/v2/components/menu/WithPopoverMenu.jsx b/superset/assets/src/dashboard/components/menu/WithPopoverMenu.jsx
similarity index 91%
rename from superset/assets/src/dashboard/v2/components/menu/WithPopoverMenu.jsx
rename to superset/assets/src/dashboard/components/menu/WithPopoverMenu.jsx
index f213442..8a87fca 100644
--- a/superset/assets/src/dashboard/v2/components/menu/WithPopoverMenu.jsx
+++ b/superset/assets/src/dashboard/components/menu/WithPopoverMenu.jsx
@@ -54,12 +54,15 @@ class WithPopoverMenu extends React.PureComponent {
}
handleClick(event) {
- const { onChangeFocus, shouldFocus: shouldFocusFunc, disableClick, editMode } = this.props;
- const shouldFocus = shouldFocusFunc(event, this.container);
-
- if (!editMode) {
+ if (!this.props.editMode) {
return;
}
+ const {
+ onChangeFocus,
+ shouldFocus: shouldFocusFunc,
+ disableClick,
+ } = this.props;
+ const shouldFocus = shouldFocusFunc(event, this.container);
if (!disableClick && shouldFocus && !this.state.isFocused) {
// if not focused, set focus and add a window event listener to capture outside clicks
@@ -97,12 +100,15 @@ class WithPopoverMenu extends React.PureComponent {
{children}
{editMode &&
isFocused &&
- menuItems.length > 0 &&
- <div className="popover-menu" >
+ menuItems.length > 0 && (
+ <div className="popover-menu">
{menuItems.map((node, i) => (
- <div className="menu-item" key={`menu-item-${i}`}>{node}</div>
+ <div className="menu-item" key={`menu-item-${i}`}>
+ {node}
+ </div>
))}
- </div>}
+ </div>
+ )}
</div>
);
}
diff --git a/superset/assets/src/dashboard/v2/components/resizable/ResizableContainer.jsx b/superset/assets/src/dashboard/components/resizable/ResizableContainer.jsx
similarity index 78%
rename from superset/assets/src/dashboard/v2/components/resizable/ResizableContainer.jsx
rename to superset/assets/src/dashboard/components/resizable/ResizableContainer.jsx
index a532ff0..7e09e73 100644
--- a/superset/assets/src/dashboard/v2/components/resizable/ResizableContainer.jsx
+++ b/superset/assets/src/dashboard/components/resizable/ResizableContainer.jsx
@@ -56,7 +56,10 @@ const defaultProps = {
// because columns are not multiples of a single variable (width = n*cols + (n-1) * gutters)
// we snap to the base unit and then snap to _actual_ column multiples on stop
const SNAP_TO_GRID = [GRID_BASE_UNIT, GRID_BASE_UNIT];
-
+const HANDLE_CLASSES = {
+ right: 'resizable-container-handle--right',
+ bottom: 'resizable-container-handle--bottom',
+};
class ResizableContainer extends React.PureComponent {
constructor(props) {
super(props);
@@ -139,29 +142,26 @@ class ResizableContainer extends React.PureComponent {
const size = {
width: adjustableWidth
- ? ((widthStep + gutterWidth) * widthMultiple) - gutterWidth
- : (staticWidthMultiple && staticWidthMultiple * widthStep)
- || staticWidth
- || undefined,
+ ? (widthStep + gutterWidth) * widthMultiple - gutterWidth
+ : (staticWidthMultiple && staticWidthMultiple * widthStep) ||
+ staticWidth ||
+ undefined,
height: adjustableHeight
? heightStep * heightMultiple
- : (staticHeightMultiple && staticHeightMultiple * heightStep)
- || staticHeight
- || undefined,
+ : (staticHeightMultiple && staticHeightMultiple * heightStep) ||
+ staticHeight ||
+ undefined,
};
- if (!editMode) {
- return (
- <div style={{ ...size }}>
- {children}
- </div>
- );
- }
-
let enableConfig = resizableConfig.notAdjustable;
- if (adjustableWidth && adjustableHeight) enableConfig = resizableConfig.widthAndHeight;
- else if (adjustableWidth) enableConfig = resizableConfig.widthOnly;
- else if (adjustableHeight) enableConfig = resizableConfig.heightOnly;
+
+ if (editMode && adjustableWidth && adjustableHeight) {
+ enableConfig = resizableConfig.widthAndHeight;
+ } else if (editMode && adjustableWidth) {
+ enableConfig = resizableConfig.widthOnly;
+ } else if (editMode && adjustableHeight) {
+ enableConfig = resizableConfig.heightOnly;
+ }
const { isResizing } = this.state;
@@ -169,18 +169,27 @@ class ResizableContainer extends React.PureComponent {
<Resizable
enable={enableConfig}
grid={SNAP_TO_GRID}
- minWidth={adjustableWidth
- ? (minWidthMultiple * (widthStep + gutterWidth)) - gutterWidth
- : undefined}
- minHeight={adjustableHeight
- ? (minHeightMultiple * heightStep)
- : undefined}
- maxWidth={adjustableWidth
- ? Math.max(size.width, (maxWidthMultiple * (widthStep + gutterWidth)) - gutterWidth)
- : undefined}
- maxHeight={adjustableHeight
- ? Math.max(size.height, maxHeightMultiple * heightStep)
- : undefined}
+ minWidth={
+ adjustableWidth
+ ? minWidthMultiple * (widthStep + gutterWidth) - gutterWidth
+ : undefined
+ }
+ minHeight={
+ adjustableHeight ? minHeightMultiple * heightStep : undefined
+ }
+ maxWidth={
+ adjustableWidth
+ ? Math.max(
+ size.width,
+ maxWidthMultiple * (widthStep + gutterWidth) - gutterWidth,
+ )
+ : undefined
+ }
+ maxHeight={
+ adjustableHeight
+ ? Math.max(size.height, maxHeightMultiple * heightStep)
+ : undefined
+ }
size={size}
onResizeStart={this.handleResizeStart}
onResize={this.handleResize}
@@ -190,6 +199,7 @@ class ResizableContainer extends React.PureComponent {
'resizable-container',
isResizing && 'resizable-container--resizing',
)}
+ handleClasses={HANDLE_CLASSES}
>
{children}
</Resizable>
diff --git a/superset/assets/src/dashboard/v2/components/resizable/ResizableHandle.jsx b/superset/assets/src/dashboard/components/resizable/ResizableHandle.jsx
similarity index 54%
rename from superset/assets/src/dashboard/v2/components/resizable/ResizableHandle.jsx
rename to superset/assets/src/dashboard/components/resizable/ResizableHandle.jsx
index 9536f6b..b696b26 100644
--- a/superset/assets/src/dashboard/v2/components/resizable/ResizableHandle.jsx
+++ b/superset/assets/src/dashboard/components/resizable/ResizableHandle.jsx
@@ -1,21 +1,15 @@
import React from 'react';
export function BottomRightResizeHandle() {
- return (
- <div className="resize-handle resize-handle--bottom-right" />
- );
+ return <div className="resize-handle resize-handle--bottom-right" />;
}
export function RightResizeHandle() {
- return (
- <div className="resize-handle resize-handle--right" />
- );
+ return <div className="resize-handle resize-handle--right" />;
}
export function BottomResizeHandle() {
- return (
- <div className="resize-handle resize-handle--bottom" />
- );
+ return <div className="resize-handle resize-handle--bottom" />;
}
export default {
diff --git a/superset/assets/src/dashboard/containers/Chart.jsx b/superset/assets/src/dashboard/containers/Chart.jsx
new file mode 100644
index 0000000..470176b
--- /dev/null
+++ b/superset/assets/src/dashboard/containers/Chart.jsx
@@ -0,0 +1,59 @@
+import { bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
+
+import {
+ addFilter,
+ removeFilter,
+ toggleExpandSlice,
+} from '../actions/dashboardState';
+import { refreshChart } from '../../chart/chartAction';
+import getFormDataWithExtraFilters from '../util/charts/getFormDataWithExtraFilters';
+import { saveSliceName } from '../actions/sliceEntities';
+import Chart from '../components/gridComponents/Chart';
+
+function mapStateToProps(
+ {
+ charts: chartQueries,
+ dashboardInfo,
+ dashboardState,
+ datasources,
+ sliceEntities,
+ },
+ ownProps,
+) {
+ const { id } = ownProps;
+ const chart = chartQueries[id];
+ const { filters } = dashboardState;
+
+ return {
+ chart,
+ datasource: datasources[chart.form_data.datasource],
+ slice: sliceEntities.slices[id],
+ timeout: dashboardInfo.common.conf.SUPERSET_WEBSERVER_TIMEOUT,
+ filters,
+ // note: this method caches filters if possible to prevent render cascades
+ formData: getFormDataWithExtraFilters({
+ chart,
+ dashboardMetadata: dashboardInfo.metadata,
+ filters,
+ sliceId: id,
+ }),
+ editMode: dashboardState.editMode,
+ isExpanded: !!dashboardState.expandedSlices[id],
+ };
+}
+
+function mapDispatchToProps(dispatch) {
+ return bindActionCreators(
+ {
+ saveSliceName,
+ toggleExpandSlice,
+ addFilter,
+ refreshChart,
+ removeFilter,
+ },
+ dispatch,
+ );
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(Chart);
diff --git a/superset/assets/src/dashboard/containers/Dashboard.jsx b/superset/assets/src/dashboard/containers/Dashboard.jsx
new file mode 100644
index 0000000..9af0e81
--- /dev/null
+++ b/superset/assets/src/dashboard/containers/Dashboard.jsx
@@ -0,0 +1,49 @@
+import { bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
+
+import {
+ addSliceToDashboard,
+ removeSliceFromDashboard,
+ onChange,
+} from '../actions/dashboardState';
+import { runQuery } from '../../chart/chartAction';
+import Dashboard from '../components/Dashboard';
+
+function mapStateToProps({
+ datasources,
+ sliceEntities,
+ charts,
+ dashboardInfo,
+ dashboardState,
+ dashboardLayout,
+ impressionId,
+}) {
+ return {
+ initMessages: dashboardInfo.common.flash_messages,
+ timeout: dashboardInfo.common.conf.SUPERSET_WEBSERVER_TIMEOUT,
+ userId: dashboardInfo.userId,
+ dashboardInfo,
+ dashboardState,
+ charts,
+ datasources,
+ slices: sliceEntities.slices,
+ layout: dashboardLayout.present,
+ impressionId,
+ };
+}
+
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators(
+ {
+ addSliceToDashboard,
+ onChange,
+ removeSliceFromDashboard,
+ runQuery,
+ },
+ dispatch,
+ ),
+ };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(Dashboard);
diff --git a/superset/assets/src/dashboard/v2/containers/DashboardBuilder.jsx b/superset/assets/src/dashboard/containers/DashboardBuilder.jsx
similarity index 66%
rename from superset/assets/src/dashboard/v2/containers/DashboardBuilder.jsx
rename to superset/assets/src/dashboard/containers/DashboardBuilder.jsx
index 62fc94a..6bece3d 100644
--- a/superset/assets/src/dashboard/v2/containers/DashboardBuilder.jsx
+++ b/superset/assets/src/dashboard/containers/DashboardBuilder.jsx
@@ -7,20 +7,22 @@ import {
handleComponentDrop,
} from '../actions/dashboardLayout';
-function mapStateToProps({ dashboardLayout: undoableLayout, dashboardState: dashboard }, ownProps) {
+function mapStateToProps({ dashboardLayout: undoableLayout, dashboardState }) {
return {
dashboardLayout: undoableLayout.present,
- cells: ownProps.cells,
- editMode: dashboard.editMode,
- showBuilderPane: dashboard.showBuilderPane,
+ editMode: dashboardState.editMode,
+ showBuilderPane: dashboardState.showBuilderPane,
};
}
function mapDispatchToProps(dispatch) {
- return bindActionCreators({
- deleteTopLevelTabs,
- handleComponentDrop,
- }, dispatch);
+ return bindActionCreators(
+ {
+ deleteTopLevelTabs,
+ handleComponentDrop,
+ },
+ dispatch,
+ );
}
export default connect(mapStateToProps, mapDispatchToProps)(DashboardBuilder);
diff --git a/superset/assets/src/dashboard/v2/containers/DashboardComponent.jsx b/superset/assets/src/dashboard/containers/DashboardComponent.jsx
similarity index 73%
rename from superset/assets/src/dashboard/v2/containers/DashboardComponent.jsx
rename to superset/assets/src/dashboard/containers/DashboardComponent.jsx
index 01f7805..650313e 100644
--- a/superset/assets/src/dashboard/v2/containers/DashboardComponent.jsx
+++ b/superset/assets/src/dashboard/containers/DashboardComponent.jsx
@@ -6,7 +6,7 @@ import { connect } from 'react-redux';
import ComponentLookup from '../components/gridComponents';
import getTotalChildWidth from '../util/getChildWidth';
import { componentShape } from '../util/propShapes';
-import { CHART_TYPE, COLUMN_TYPE, ROW_TYPE } from '../util/componentTypes';
+import { COLUMN_TYPE, ROW_TYPE } from '../util/componentTypes';
import { GRID_MIN_COLUMN_COUNT } from '../util/constants';
import {
@@ -25,24 +25,36 @@ const propTypes = {
handleComponentDrop: PropTypes.func.isRequired,
};
-function mapStateToProps({ dashboardLayout: undoableLayout, dashboardState: dashboard }, ownProps) {
+function mapStateToProps(
+ {
+ dashboardLayout: undoableLayout,
+ dashboardState,
+ sliceEntities,
+ charts,
+ datasources,
+ },
+ ownProps,
+) {
const dashboardLayout = undoableLayout.present;
- const { id, parentId, cells } = ownProps;
+ const { id, parentId } = ownProps;
const component = dashboardLayout[id];
const props = {
component,
parentComponent: dashboardLayout[parentId],
- editMode: dashboard.editMode,
+ editMode: dashboardState.editMode,
};
// rows and columns need more data about their child dimensions
// doing this allows us to not pass the entire component lookup to all Components
if (props.component.type === ROW_TYPE) {
- props.occupiedColumnCount = getTotalChildWidth({ id, components: dashboardLayout });
+ props.occupiedColumnCount = getTotalChildWidth({
+ id,
+ components: dashboardLayout,
+ });
} else if (props.component.type === COLUMN_TYPE) {
props.minColumnWidth = GRID_MIN_COLUMN_COUNT;
- component.children.forEach((childId) => {
+ component.children.forEach(childId => {
// rows don't have widths, so find the width of its children
if (dashboardLayout[childId].type === ROW_TYPE) {
props.minColumnWidth = Math.max(
@@ -51,23 +63,21 @@ function mapStateToProps({ dashboardLayout: undoableLayout, dashboardState: dash
);
}
});
- } else if (props.component.type === CHART_TYPE) {
- const chartId = props.component.meta && props.component.meta.chartId;
- if (chartId) {
- props.chart = cells[chartId];
- }
}
return props;
}
function mapDispatchToProps(dispatch) {
- return bindActionCreators({
- createComponent,
- deleteComponent,
- updateComponents,
- handleComponentDrop,
- }, dispatch);
+ return bindActionCreators(
+ {
+ createComponent,
+ deleteComponent,
+ updateComponents,
+ handleComponentDrop,
+ },
+ dispatch,
+ );
}
class DashboardComponent extends React.PureComponent {
diff --git a/superset/assets/src/dashboard/v2/containers/DashboardGrid.jsx b/superset/assets/src/dashboard/containers/DashboardGrid.jsx
similarity index 62%
rename from superset/assets/src/dashboard/v2/containers/DashboardGrid.jsx
rename to superset/assets/src/dashboard/containers/DashboardGrid.jsx
index 2adc390..718b543 100644
--- a/superset/assets/src/dashboard/v2/containers/DashboardGrid.jsx
+++ b/superset/assets/src/dashboard/containers/DashboardGrid.jsx
@@ -7,18 +7,20 @@ import {
resizeComponent,
} from '../actions/dashboardLayout';
-function mapStateToProps({ dashboardState: dashboard }, ownProps) {
+function mapStateToProps({ dashboardState }) {
return {
- editMode: dashboard.editMode,
- cells: ownProps.cells,
+ editMode: dashboardState.editMode,
};
}
function mapDispatchToProps(dispatch) {
- return bindActionCreators({
- handleComponentDrop,
- resizeComponent,
- }, dispatch);
+ return bindActionCreators(
+ {
+ handleComponentDrop,
+ resizeComponent,
+ },
+ dispatch,
+ );
}
export default connect(mapStateToProps, mapDispatchToProps)(DashboardGrid);
diff --git a/superset/assets/src/dashboard/v2/containers/DashboardHeader.jsx b/superset/assets/src/dashboard/containers/DashboardHeader.jsx
similarity index 59%
rename from superset/assets/src/dashboard/v2/containers/DashboardHeader.jsx
rename to superset/assets/src/dashboard/containers/DashboardHeader.jsx
index cc8e944..2b3431a 100644
--- a/superset/assets/src/dashboard/v2/containers/DashboardHeader.jsx
+++ b/superset/assets/src/dashboard/containers/DashboardHeader.jsx
@@ -2,7 +2,7 @@ import { ActionCreators as UndoActionCreators } from 'redux-undo';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
-import DashboardHeader from '../../components/Header';
+import DashboardHeader from '../components/Header';
import {
setEditMode,
toggleBuilderPane,
@@ -13,13 +13,15 @@ import {
updateDashboardTitle,
onChange,
onSave,
-} from '../../actions/dashboardState';
-import {
- handleComponentDrop,
-} from '../actions/dashboardLayout';
+} from '../actions/dashboardState';
+import { handleComponentDrop } from '../actions/dashboardLayout';
-function mapStateToProps({ dashboardLayout: undoableLayout, dashboardState: dashboard,
- dashboardInfo, charts }) {
+function mapStateToProps({
+ dashboardLayout: undoableLayout,
+ dashboardState: dashboard,
+ dashboardInfo,
+ charts,
+}) {
return {
dashboardInfo,
canUndo: undoableLayout.past.length > 0,
@@ -38,21 +40,23 @@ function mapStateToProps({ dashboardLayout: undoableLayout, dashboardState: dash
}
function mapDispatchToProps(dispatch) {
- return bindActionCreators({
- handleComponentDrop,
- onUndo: UndoActionCreators.undo,
- onRedo: UndoActionCreators.redo,
- setEditMode,
- toggleBuilderPane,
- fetchFaveStar,
- saveFaveStar,
- fetchCharts,
- startPeriodicRender,
- updateDashboardTitle,
- onChange,
- onSave,
- }, dispatch);
+ return bindActionCreators(
+ {
+ handleComponentDrop,
+ onUndo: UndoActionCreators.undo,
+ onRedo: UndoActionCreators.redo,
+ setEditMode,
+ toggleBuilderPane,
+ fetchFaveStar,
+ saveFaveStar,
+ fetchCharts,
+ startPeriodicRender,
+ updateDashboardTitle,
+ onChange,
+ onSave,
+ },
+ dispatch,
+ );
}
-
export default connect(mapStateToProps, mapDispatchToProps)(DashboardHeader);
diff --git a/superset/assets/src/dashboard/v2/containers/ToastPresenter.jsx b/superset/assets/src/dashboard/containers/ToastPresenter.jsx
similarity index 100%
rename from superset/assets/src/dashboard/v2/containers/ToastPresenter.jsx
rename to superset/assets/src/dashboard/containers/ToastPresenter.jsx
diff --git a/superset/assets/src/dashboard/v2/fixtures/emptyDashboardLayout.js b/superset/assets/src/dashboard/fixtures/emptyDashboardLayout.js
similarity index 92%
rename from superset/assets/src/dashboard/v2/fixtures/emptyDashboardLayout.js
rename to superset/assets/src/dashboard/fixtures/emptyDashboardLayout.js
index 7816cc2..cee948a 100644
--- a/superset/assets/src/dashboard/v2/fixtures/emptyDashboardLayout.js
+++ b/superset/assets/src/dashboard/fixtures/emptyDashboardLayout.js
@@ -14,9 +14,7 @@ export default {
[DASHBOARD_ROOT_ID]: {
type: DASHBOARD_ROOT_TYPE,
id: DASHBOARD_ROOT_ID,
- children: [
- DASHBOARD_GRID_ID,
- ],
+ children: [DASHBOARD_GRID_ID],
},
[DASHBOARD_GRID_ID]: {
diff --git a/superset/assets/src/dashboard/index.jsx b/superset/assets/src/dashboard/index.jsx
index 9c00f9e..846b82d 100644
--- a/superset/assets/src/dashboard/index.jsx
+++ b/superset/assets/src/dashboard/index.jsx
@@ -7,7 +7,7 @@ import thunk from 'redux-thunk';
import { initEnhancer } from '../reduxUtils';
import { appSetup } from '../common';
import { initJQueryAjax } from '../modules/utils';
-import DashboardContainer from './components/DashboardContainer';
+import DashboardContainer from './containers/Dashboard';
import getInitialState from './reducers/getInitialState';
import rootReducer from './reducers/index';
@@ -19,7 +19,10 @@ const bootstrapData = JSON.parse(appContainer.getAttribute('data-bootstrap'));
const initState = getInitialState(bootstrapData);
const store = createStore(
- rootReducer, initState, compose(applyMiddleware(thunk), initEnhancer(false)));
+ rootReducer,
+ initState,
+ compose(applyMiddleware(thunk), initEnhancer(false)),
+);
ReactDOM.render(
<Provider store={store}>
diff --git a/superset/assets/src/dashboard/v2/reducers/dashboardLayout.js b/superset/assets/src/dashboard/reducers/dashboardLayout.js
similarity index 76%
rename from superset/assets/src/dashboard/v2/reducers/dashboardLayout.js
rename to superset/assets/src/dashboard/reducers/dashboardLayout.js
index 994ac47..573a143 100644
--- a/superset/assets/src/dashboard/v2/reducers/dashboardLayout.js
+++ b/superset/assets/src/dashboard/reducers/dashboardLayout.js
@@ -1,4 +1,9 @@
-import { DASHBOARD_ROOT_ID, DASHBOARD_GRID_ID, NEW_COMPONENTS_SOURCE_ID } from '../util/constants';
+import {
+ DASHBOARD_ROOT_ID,
+ DASHBOARD_GRID_ID,
+ GRID_MIN_COLUMN_COUNT,
+ NEW_COMPONENTS_SOURCE_ID,
+} from '../util/constants';
import newComponentFactory from '../util/newComponentFactory';
import newEntitiesFromDrop from '../util/newEntitiesFromDrop';
import reorderItem from '../util/dnd-reorder';
@@ -23,7 +28,9 @@ import {
const actionHandlers = {
[UPDATE_COMPONENTS](state, action) {
- const { payload: { nextComponents } } = action;
+ const {
+ payload: { nextComponents },
+ } = action;
return {
...state,
...nextComponents,
@@ -31,7 +38,9 @@ const actionHandlers = {
},
[DELETE_COMPONENT](state, action) {
- const { payload: { id, parentId } } = action;
+ const {
+ payload: { id, parentId },
+ } = action;
if (!parentId || !id || !state[id] || !state[parentId]) return state;
@@ -44,10 +53,13 @@ const actionHandlers = {
delete nextComponents[componentId];
const { children = [] } = component;
- children.forEach((childId) => { recursivelyDeleteChildren(childId, componentId); });
+ children.forEach(childId => {
+ recursivelyDeleteChildren(childId, componentId);
+ });
const parent = nextComponents[componentParentId];
- if (parent) { // may have been deleted in another recursion
+ if (parent) {
+ // may have been deleted in another recursion
const componentIndex = (parent.children || []).indexOf(componentId);
if (componentIndex > -1) {
const nextChildren = [...parent.children];
@@ -66,21 +78,28 @@ const actionHandlers = {
},
[CREATE_COMPONENT](state, action) {
- const { payload: { dropResult } } = action;
+ const {
+ payload: { dropResult },
+ } = action;
const { destination, dragging } = dropResult;
const newEntities = newEntitiesFromDrop({ dropResult, components: state });
- // inherit the width of a column parent
- if (destination.type === COLUMN_TYPE && [CHART_TYPE, MARKDOWN_TYPE].includes(dragging.type)) {
+ // if column is a parent, set any resizable children to have a minimum width so that
+ // the chances that they are validly movable to future containers is maximized
+ if (
+ destination.type === COLUMN_TYPE &&
+ [CHART_TYPE, MARKDOWN_TYPE].includes(dragging.type)
+ ) {
const newEntitiesArray = Object.values(newEntities);
- const component = newEntitiesArray.find(entity => entity.type === dragging.type);
- const parentColumn = newEntities[destination.id];
+ const component = newEntitiesArray.find(
+ entity => entity.type === dragging.type,
+ );
newEntities[component.id] = {
...component,
meta: {
...component.meta,
- width: parentColumn.meta.width,
+ width: GRID_MIN_COLUMN_COUNT,
},
};
}
@@ -92,7 +111,9 @@ const actionHandlers = {
},
[MOVE_COMPONENT](state, action) {
- const { payload: { dropResult } } = action;
+ const {
+ payload: { dropResult },
+ } = action;
const { source, destination, dragging } = dropResult;
if (!source || !destination || !dragging) return state;
@@ -119,7 +140,10 @@ const actionHandlers = {
}
// inherit the width of a column parent
- if (destination.type === COLUMN_TYPE && [CHART_TYPE, MARKDOWN_TYPE].includes(dragging.type)) {
+ if (
+ destination.type === COLUMN_TYPE &&
+ [CHART_TYPE, MARKDOWN_TYPE].includes(dragging.type)
+ ) {
const component = nextEntities[dragging.id];
const parentColumn = nextEntities[destination.id];
nextEntities[dragging.id] = {
@@ -138,7 +162,9 @@ const actionHandlers = {
},
[CREATE_TOP_LEVEL_TABS](state, action) {
- const { payload: { dropResult } } = action;
+ const {
+ payload: { dropResult },
+ } = action;
const { source, dragging } = dropResult;
// move children of current root to be children of the dragging tab
@@ -153,7 +179,9 @@ const actionHandlers = {
const draggingTab = state[draggingTabId];
// move all children except the one that is dragging
- const childrenToMove = [...topLevelComponent.children].filter(id => id !== dragging.id);
+ const childrenToMove = [...topLevelComponent.children].filter(
+ id => id !== dragging.id,
+ );
return {
...state,
@@ -167,10 +195,7 @@ const actionHandlers = {
},
[draggingTabId]: {
...draggingTab,
- children: [
- ...draggingTab.children,
- ...childrenToMove,
- ],
+ children: [...draggingTab.children, ...childrenToMove],
},
};
}
@@ -178,12 +203,19 @@ const actionHandlers = {
// create new component
const newEntities = newEntitiesFromDrop({ dropResult, components: state });
const newEntitiesArray = Object.values(newEntities);
- const tabComponent = newEntitiesArray.find(component => component.type === TAB_TYPE);
- const tabsComponent = newEntitiesArray.find(component => component.type === TABS_TYPE);
+ const tabComponent = newEntitiesArray.find(
+ component => component.type === TAB_TYPE,
+ );
+ const tabsComponent = newEntitiesArray.find(
+ component => component.type === TABS_TYPE,
+ );
tabComponent.children = [...topLevelComponent.children];
newEntities[topLevelId] = { ...topLevelComponent, children: [] };
- newEntities[DASHBOARD_ROOT_ID] = { ...rootComponent, children: [tabsComponent.id] };
+ newEntities[DASHBOARD_ROOT_ID] = {
+ ...rootComponent,
+ children: [tabsComponent.id],
+ };
return {
...state,
@@ -201,7 +233,7 @@ const actionHandlers = {
let childrenToMove = [];
const nextEntities = { ...state };
- topLevelTabs.children.forEach((tabId) => {
+ topLevelTabs.children.forEach(tabId => {
const tabComponent = state[tabId];
childrenToMove = [...childrenToMove, ...tabComponent.children];
delete nextEntities[tabId];
@@ -215,7 +247,7 @@ const actionHandlers = {
};
nextEntities[DASHBOARD_GRID_ID] = {
- ...(state[DASHBOARD_GRID_ID]),
+ ...state[DASHBOARD_GRID_ID],
children: childrenToMove,
};
diff --git a/superset/assets/src/dashboard/reducers/dashboardState.js b/superset/assets/src/dashboard/reducers/dashboardState.js
index 84ee58e..7b5a17a 100644
--- a/superset/assets/src/dashboard/reducers/dashboardState.js
+++ b/superset/assets/src/dashboard/reducers/dashboardState.js
@@ -9,13 +9,14 @@ import {
REMOVE_SLICE,
REMOVE_FILTER,
SET_EDIT_MODE,
+ SET_UNSAVED_CHANGES,
TOGGLE_BUILDER_PANE,
TOGGLE_EXPAND_SLICE,
TOGGLE_FAVE_STAR,
UPDATE_DASHBOARD_TITLE,
} from '../actions/dashboardState';
-export default function (state = {}, action) {
+export default function dashboardStateReducer(state = {}, action) {
const actionHandlers = {
[UPDATE_DASHBOARD_TITLE]() {
return { ...state, title: action.title };
@@ -84,15 +85,23 @@ export default function (state = {}, action) {
let filters = state.filters;
const { chart, col, vals, merge, refresh } = action;
const sliceId = chart.id;
- const filterKeys = ['__from', '__to', '__time_col',
- '__time_grain', '__time_origin', '__granularity'];
- if (filterKeys.indexOf(col) >= 0 ||
- action.chart.formData.groupby.indexOf(col) !== -1) {
+ const filterKeys = [
+ '__from',
+ '__to',
+ '__time_col',
+ '__time_grain',
+ '__time_origin',
+ '__granularity',
+ ];
+ if (
+ filterKeys.indexOf(col) >= 0 ||
+ action.chart.formData.groupby.indexOf(col) !== -1
+ ) {
let newFilter = {};
if (!(sliceId in filters)) {
// Straight up set the filters if none existed for the slice
newFilter = { [col]: vals };
- } else if (filters[sliceId] && !(col in filters[sliceId]) || !merge) {
+ } else if ((filters[sliceId] && !(col in filters[sliceId])) || !merge) {
newFilter = { ...filters[sliceId], [col]: vals };
// d3.merge pass in array of arrays while some value form filter components
// from and to filter box require string to be process and return
@@ -119,6 +128,10 @@ export default function (state = {}, action) {
}
return { ...state, filters, refresh };
},
+ [SET_UNSAVED_CHANGES]() {
+ const { hasUnsavedChanges } = action.payload;
+ return { ...state, hasUnsavedChanges };
+ },
};
if (action.type in actionHandlers) {
diff --git a/superset/assets/src/dashboard/reducers/datasources.js b/superset/assets/src/dashboard/reducers/datasources.js
index 4df7507..87f6d09 100644
--- a/superset/assets/src/dashboard/reducers/datasources.js
+++ b/superset/assets/src/dashboard/reducers/datasources.js
@@ -1,8 +1,8 @@
-import * as actions from '../actions/datasources';
+import { SET_DATASOURCE } from '../actions/datasources';
export default function datasourceReducer(datasources = {}, action) {
const actionHandlers = {
- [actions.SET_DATASOURCE]() {
+ [SET_DATASOURCE]() {
return action.datasource;
},
};
@@ -10,7 +10,10 @@ export default function datasourceReducer(datasources = {}, action) {
if (action.type in actionHandlers) {
return {
...datasources,
- [action.key]: actionHandlers[action.type](datasources[action.key], action),
+ [action.key]: actionHandlers[action.type](
+ datasources[action.key],
+ action,
+ ),
};
}
return datasources;
diff --git a/superset/assets/src/dashboard/reducers/getInitialState.js b/superset/assets/src/dashboard/reducers/getInitialState.js
index 1129210..d0b4d7b 100644
--- a/superset/assets/src/dashboard/reducers/getInitialState.js
+++ b/superset/assets/src/dashboard/reducers/getInitialState.js
@@ -7,9 +7,9 @@ import { getParam } from '../../modules/utils';
import { applyDefaultFormData } from '../../explore/stores/store';
import { getColorFromScheme } from '../../modules/colors';
import layoutConverter from '../util/dashboardLayoutConverter';
-import { DASHBOARD_ROOT_ID } from '../v2/util/constants';
+import { DASHBOARD_ROOT_ID } from '../util/constants';
-export default function (bootstrapData) {
+export default function(bootstrapData) {
const { user_id, datasources, common } = bootstrapData;
delete common.locale;
delete common.language_pack;
@@ -18,7 +18,9 @@ export default function (bootstrapData) {
let filters = {};
try {
// allow request parameter overwrite dashboard metadata
- filters = JSON.parse(getParam('preselect_filters') || dashboard.metadata.default_filters);
+ filters = JSON.parse(
+ getParam('preselect_filters') || dashboard.metadata.default_filters,
+ );
} catch (e) {
//
}
@@ -27,9 +29,9 @@ export default function (bootstrapData) {
// the dashboard's JSON metadata
if (dashboard.metadata && dashboard.metadata.label_colors) {
const colorMap = dashboard.metadata.label_colors;
- for (const label in colorMap) {
+ Object.keys(colorMap).forEach(label => {
getColorFromScheme(label, null, colorMap[label]);
- }
+ });
}
// dashboard layout
@@ -52,9 +54,10 @@ export default function (bootstrapData) {
const chartQueries = {};
const slices = {};
const sliceIds = new Set();
- dashboard.slices.forEach((slice) => {
+ dashboard.slices.forEach(slice => {
const key = slice.slice_id;
- chartQueries[key] = { ...chart,
+ chartQueries[key] = {
+ ...chart,
id: key,
form_data: slice.form_data,
formData: applyDefaultFormData(slice.form_data),
@@ -79,13 +82,16 @@ export default function (bootstrapData) {
datasources,
sliceEntities: { ...initSliceEntities, slices, isLoading: false },
charts: chartQueries,
- dashboardInfo: { /* readOnly props */
+ dashboardInfo: {
+ // read-only data
id: dashboard.id,
slug: dashboard.slug,
metadata: {
- filter_immune_slice_fields: dashboard.metadata.filter_immune_slice_fields,
+ filter_immune_slice_fields:
+ dashboard.metadata.filter_immune_slice_fields,
filter_immune_slices: dashboard.metadata.filter_immune_slices,
- timed_refresh_immune_slices: dashboard.metadata.timed_refresh_immune_slices,
+ timed_refresh_immune_slices:
+ dashboard.metadata.timed_refresh_immune_slices,
},
userId: user_id,
dash_edit_perm: dashboard.dash_edit_perm,
diff --git a/superset/assets/src/dashboard/reducers/index.js b/superset/assets/src/dashboard/reducers/index.js
index a2397e0..787cd5f 100644
--- a/superset/assets/src/dashboard/reducers/index.js
+++ b/superset/assets/src/dashboard/reducers/index.js
@@ -4,19 +4,19 @@ import charts from '../../chart/chartReducer';
import dashboardState from './dashboardState';
import datasources from './datasources';
import sliceEntities from './sliceEntities';
-import dashboardLayout from '../v2/reducers/index';
-import messageToasts from '../v2/reducers/messageToasts';
+import dashboardLayout from '../reducers/undoableDashboardLayout';
+import messageToasts from '../reducers/messageToasts';
-const dashboardInfo = (state = {}) => (state);
-const impressionId = (state = '') => (state);
+const dashboardInfo = (state = {}) => state;
+const impressionId = (state = '') => state;
export default combineReducers({
charts,
datasources,
- sliceEntities,
dashboardInfo,
dashboardState,
dashboardLayout,
- messageToasts,
impressionId,
+ messageToasts,
+ sliceEntities,
});
diff --git a/superset/assets/src/dashboard/v2/reducers/messageToasts.js b/superset/assets/src/dashboard/reducers/messageToasts.js
similarity index 87%
rename from superset/assets/src/dashboard/v2/reducers/messageToasts.js
rename to superset/assets/src/dashboard/reducers/messageToasts.js
index 1f5728a..7383ab0 100644
--- a/superset/assets/src/dashboard/v2/reducers/messageToasts.js
+++ b/superset/assets/src/dashboard/reducers/messageToasts.js
@@ -8,7 +8,9 @@ export default function messageToastsReducer(toasts = [], action) {
}
case REMOVE_TOAST: {
- const { payload: { id } } = action;
+ const {
+ payload: { id },
+ } = action;
return [...toasts].filter(toast => toast.id !== id);
}
diff --git a/superset/assets/src/dashboard/reducers/sliceEntities.js b/superset/assets/src/dashboard/reducers/sliceEntities.js
index 61a58f6..c1453f5 100644
--- a/superset/assets/src/dashboard/reducers/sliceEntities.js
+++ b/superset/assets/src/dashboard/reducers/sliceEntities.js
@@ -13,7 +13,10 @@ export const initSliceEntities = {
lastUpdated: 0,
};
-export default function (state = initSliceEntities, action) {
+export default function sliceEntitiesReducer(
+ state = initSliceEntities,
+ action,
+) {
const actionHandlers = {
[UPDATE_SLICE_NAME]() {
const updatedSlice = {
@@ -44,8 +47,9 @@ export default function (state = initSliceEntities, action) {
const respJSON = action.error.responseJSON;
const errorMessage =
t('Sorry, there was an error adding slices to this dashboard: ') +
- (respJSON && respJSON.message) ? respJSON.message :
- error.responseText;
+ (respJSON && respJSON.message)
+ ? respJSON.message
+ : action.error.responseText;
return {
...state,
isLoading: false,
diff --git a/superset/assets/src/dashboard/reducers/undoableDashboardLayout.js b/superset/assets/src/dashboard/reducers/undoableDashboardLayout.js
new file mode 100644
index 0000000..b78c273
--- /dev/null
+++ b/superset/assets/src/dashboard/reducers/undoableDashboardLayout.js
@@ -0,0 +1,27 @@
+import undoable, { includeAction } from 'redux-undo';
+import {
+ UPDATE_COMPONENTS,
+ DELETE_COMPONENT,
+ CREATE_COMPONENT,
+ CREATE_TOP_LEVEL_TABS,
+ DELETE_TOP_LEVEL_TABS,
+ RESIZE_COMPONENT,
+ MOVE_COMPONENT,
+ HANDLE_COMPONENT_DROP,
+} from '../actions/dashboardLayout';
+
+import dashboardLayout from './dashboardLayout';
+
+export default undoable(dashboardLayout, {
+ limit: 15,
+ filter: includeAction([
+ UPDATE_COMPONENTS,
+ DELETE_COMPONENT,
+ CREATE_COMPONENT,
+ CREATE_TOP_LEVEL_TABS,
+ DELETE_TOP_LEVEL_TABS,
+ RESIZE_COMPONENT,
+ MOVE_COMPONENT,
+ HANDLE_COMPONENT_DROP,
+ ]),
+});
diff --git a/superset/assets/src/dashboard/v2/stylesheets/builder-sidepane.less b/superset/assets/src/dashboard/stylesheets/builder-sidepane.less
similarity index 76%
rename from superset/assets/src/dashboard/v2/stylesheets/builder-sidepane.less
rename to superset/assets/src/dashboard/stylesheets/builder-sidepane.less
index d9f1069..bdf342b 100644
--- a/superset/assets/src/dashboard/v2/stylesheets/builder-sidepane.less
+++ b/superset/assets/src/dashboard/stylesheets/builder-sidepane.less
@@ -1,8 +1,21 @@
.dashboard-builder-sidepane {
+ background: white;
+ flex: 0 0 376px;
+ border: 1px solid @gray-light;
+ z-index: 10;
+ position: relative;
+
+ .dashboard-builder-sidepane-header {
+ font-size: 15px;
+ font-weight: 700;
+ border-bottom: 1px solid @gray-light;
+ padding: 14px;
+ }
+
.trigger {
height: 25px;
width: 25px;
- color: #879399;
+ color: @gray;
position: relative;
&.close {
@@ -25,8 +38,8 @@
position: absolute;
width: 2px;
top: 51px;
- right: 1px;
- background: #fff;
+ right: 0;
+ background: white;
transition-property: width;
transition-duration: 1s;
transition-timing-function: ease;
@@ -39,18 +52,17 @@
.chart-card-container {
padding: 16px;
- cursor: move;
.chart-card {
- border: 1px solid #ccc;
+ border: 1px solid @gray-light;
height: 120px;
padding: 16px;
- pointer-events: unset;
+ cursor: move;
}
.chart-card.is-selected {
opacity: 0.45;
- pointer-events: none;
+ cursor: not-allowed;
}
.card-title {
@@ -88,7 +100,7 @@
input {
margin-left: 16px;
width: 169px;
- border: 1px solid #b3b3b3;
+ border: 1px solid @gray;
&:focus {
outline: none;
diff --git a/superset/assets/src/dashboard/v2/stylesheets/builder.less b/superset/assets/src/dashboard/stylesheets/builder.less
similarity index 72%
rename from superset/assets/src/dashboard/v2/stylesheets/builder.less
rename to superset/assets/src/dashboard/stylesheets/builder.less
index 2ff99a4..7c14056 100644
--- a/superset/assets/src/dashboard/v2/stylesheets/builder.less
+++ b/superset/assets/src/dashboard/stylesheets/builder.less
@@ -1,7 +1,7 @@
-.dashboard-v2 {
- //margin-top: -20px;
+.dashboard {
position: relative;
color: @almost-black;
+ margin-top: -20px;
}
.dashboard-header {
@@ -22,12 +22,12 @@
}
/* only top-level tabs have popover, give it more padding to match header + tabs */
-.dashboard-v2 > .with-popover-menu > .popover-menu {
+.dashboard > .with-popover-menu > .popover-menu {
left: 24px;
}
/* drop shadow for top-level tabs only */
-.dashboard-v2 .dashboard-component-tabs {
+.dashboard .dashboard-component-tabs {
box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.1);
padding-left: 8px; /* note this is added to tab-level padding, to match header */
}
@@ -43,21 +43,6 @@
position: relative;
}
-.dashboard-builder-sidepane {
- background: white;
- flex: 0 0 376px;
- border: 1px solid @gray-light;
- z-index: 1;
- position: relative;
-}
-
-.dashboard-builder-sidepane-header {
- font-size: 15px;
- font-weight: 700;
- border-bottom: 1px solid @gray-light;
- padding: 14px;
-}
-
/* @TODO remove upon new theme */
.btn.btn-primary {
background: @almost-black !important;
diff --git a/superset/assets/src/dashboard/v2/stylesheets/buttons.less b/superset/assets/src/dashboard/stylesheets/buttons.less
similarity index 100%
rename from superset/assets/src/dashboard/v2/stylesheets/buttons.less
rename to superset/assets/src/dashboard/stylesheets/buttons.less
diff --git a/superset/assets/src/dashboard/stylesheets/components/chart.less b/superset/assets/src/dashboard/stylesheets/components/chart.less
new file mode 100644
index 0000000..dc366a1
--- /dev/null
+++ b/superset/assets/src/dashboard/stylesheets/components/chart.less
@@ -0,0 +1,69 @@
+.dashboard-component-chart-holder {
+ width: 100%;
+ height: 100%;
+ color: @gray-dark;
+ background-color: white;
+ position: relative;
+ padding: 16px;
+}
+
+.dashboard-chart {
+ overflow: hidden;
+}
+
+.dashboard-chart.dashboard-chart--overflowable {
+ overflow: visible;
+}
+
+.dashboard--editing .dashboard-component-chart-holder:after {
+ content: '';
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0px;
+ left: 0px;
+ z-index: 1;
+ pointer-events: none;
+ border: 1px solid transparent;
+}
+
+.dashboard--editing
+ .resizable-container:hover
+ > .dashboard-component-chart-holder:after,
+.dashboard--editing .dashboard-component-chart-holder:hover:after {
+ border: 1px solid @gray-light;
+}
+
+.dashboard--editing
+ .resizable-container.resizable-container--resizing:hover
+ > .dashboard-component-chart-holder:after {
+ border: 1px solid @indicator-color;
+}
+
+.dashboard--editing
+ .dashboard-component-chart-holder
+ .dashboard-chart
+ .chart-container {
+ cursor: move;
+ opacity: 0.2;
+}
+
+.dashboard--editing
+ .dashboard-component-chart-holder:hover
+ .dashboard-chart
+ .chart-container {
+ opacity: 0.7;
+}
+
+.dashboard--editing
+ .dashboard-component-chart-holder
+ .dashboard-chart
+ .slice_container {
+ /* disable chart interactions in edit mode */
+ pointer-events: none;
+}
+
+.dashboard-chart .chart-header {
+ font-size: 16px;
+ font-weight: bold;
+}
diff --git a/superset/assets/src/dashboard/v2/stylesheets/components/column.less b/superset/assets/src/dashboard/stylesheets/components/column.less
similarity index 60%
rename from superset/assets/src/dashboard/v2/stylesheets/components/column.less
rename to superset/assets/src/dashboard/stylesheets/components/column.less
index 9565112..5fcb442 100644
--- a/superset/assets/src/dashboard/v2/stylesheets/components/column.less
+++ b/superset/assets/src/dashboard/stylesheets/components/column.less
@@ -1,5 +1,6 @@
.grid-column {
width: 100%;
+ position: relative;
}
/* gutters between elements in a column */
@@ -7,20 +8,24 @@
margin-bottom: 16px;
}
-.dashboard-v2--editing .grid-column:after {
- border: 1px dashed transparent;
- content: "";
+.dashboard--editing .grid-column:after {
+ border: 1px solid transparent;
+ content: '';
position: absolute;
width: 100%;
height: 100%;
- top: 1px;
+ top: 0;
left: 0;
z-index: 1;
pointer-events: none;
}
-.dashboard-v2--editing .grid-column:hover:after {
- border: 1px solid @gray-light;
+.dashboard--editing
+ .resizable-container.resizable-container--resizing:hover
+ > .grid-column:after,
+.dashboard--editing .grid-column:hover:after {
+ border: 1px dashed @gray-light;
+ box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.1);
}
.grid-column > .hover-menu--top {
@@ -32,7 +37,7 @@
}
.grid-column--empty:before {
- content: "Empty column";
+ content: 'Empty column';
position: absolute;
top: 0;
left: 0;
diff --git a/superset/assets/src/dashboard/v2/stylesheets/components/divider.less b/superset/assets/src/dashboard/stylesheets/components/divider.less
similarity index 100%
rename from superset/assets/src/dashboard/v2/stylesheets/components/divider.less
rename to superset/assets/src/dashboard/stylesheets/components/divider.less
diff --git a/superset/assets/src/dashboard/v2/stylesheets/components/header.less b/superset/assets/src/dashboard/stylesheets/components/header.less
similarity index 92%
rename from superset/assets/src/dashboard/v2/stylesheets/components/header.less
rename to superset/assets/src/dashboard/stylesheets/components/header.less
index 37c7598..8b93164 100644
--- a/superset/assets/src/dashboard/v2/stylesheets/components/header.less
+++ b/superset/assets/src/dashboard/stylesheets/components/header.less
@@ -11,6 +11,10 @@
width: auto;
}
+.dashboard-header .btn-group button {
+ margin-right: 8px;
+}
+
.dragdroppable-row .dashboard-component-header {
cursor: move;
}
@@ -40,7 +44,6 @@
* grids add margin between items, so don't double pad within columns
* we'll not worry about double padding on top as it can serve as a visual separator
*/
-// .grid-content > :not(:only-child):not(:last-child) .dashboard-component-header,
.grid-column > :not(:only-child):not(:last-child) .dashboard-component-header {
margin-bottom: -16px;
}
diff --git a/superset/assets/src/dashboard/v2/stylesheets/components/index.less b/superset/assets/src/dashboard/stylesheets/components/index.less
similarity index 100%
rename from superset/assets/src/dashboard/v2/stylesheets/components/index.less
rename to superset/assets/src/dashboard/stylesheets/components/index.less
diff --git a/superset/assets/src/dashboard/v2/stylesheets/components/new-component.less b/superset/assets/src/dashboard/stylesheets/components/new-component.less
similarity index 100%
rename from superset/assets/src/dashboard/v2/stylesheets/components/new-component.less
rename to superset/assets/src/dashboard/stylesheets/components/new-component.less
diff --git a/superset/assets/src/dashboard/v2/stylesheets/components/row.less b/superset/assets/src/dashboard/stylesheets/components/row.less
similarity index 66%
rename from superset/assets/src/dashboard/v2/stylesheets/components/row.less
rename to superset/assets/src/dashboard/stylesheets/components/row.less
index 956966d..7df5675 100644
--- a/superset/assets/src/dashboard/v2/stylesheets/components/row.less
+++ b/superset/assets/src/dashboard/stylesheets/components/row.less
@@ -1,7 +1,8 @@
.grid-row {
+ position: relative;
display: flex;
flex-direction: row;
- flex-wrap: wrap;
+ flex-wrap: nowrap;
align-items: flex-start;
width: 100%;
height: fit-content;
@@ -13,20 +14,24 @@
}
/* hover indicator */
-.dashboard-v2--editing .grid-row:after {
+.dashboard--editing .grid-row:after {
border: 1px dashed transparent;
- content: "";
+ content: '';
position: absolute;
width: 100%;
height: 100%;
- top: 1px;
+ top: 0;
left: 0;
z-index: 1;
pointer-events: none;
}
-.dashboard-v2--editing .grid-row:hover:after {
- border: 1px solid @gray-light;
+.dashboard--editing
+ .resizable-container.resizable-container--resizing:hover
+ > .grid-row:after,
+.dashboard--editing .grid-row:hover:after {
+ border: 1px dashed @gray-light;
+ box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.1);
}
.grid-row.grid-row--empty {
@@ -38,7 +43,7 @@
position: absolute;
top: 0;
left: 0;
- content: "Empty row";
+ content: 'Empty row';
display: flex;
align-items: center;
justify-content: center;
diff --git a/superset/assets/src/dashboard/v2/stylesheets/components/tabs.less b/superset/assets/src/dashboard/stylesheets/components/tabs.less
similarity index 100%
rename from superset/assets/src/dashboard/v2/stylesheets/components/tabs.less
rename to superset/assets/src/dashboard/stylesheets/components/tabs.less
diff --git a/superset/assets/src/dashboard/stylesheets/dashboard.less b/superset/assets/src/dashboard/stylesheets/dashboard.less
new file mode 100644
index 0000000..03c804b
--- /dev/null
+++ b/superset/assets/src/dashboard/stylesheets/dashboard.less
@@ -0,0 +1,104 @@
+// @import './less/cosmo/variables.less';
+
+.dashboard .chart-header {
+ position: relative;
+
+ .dropdown.btn-group {
+ position: absolute;
+ right: 0;
+ }
+
+ .dropdown-menu.dropdown-menu-right {
+ right: 7px;
+ top: -3px;
+ }
+}
+
+.slice-header-controls-trigger {
+ border: 0;
+ padding: 0 0 0 20px;
+ background: none;
+ outline: none;
+ box-shadow: none;
+ color: #263238;
+
+ &.is-cached {
+ color: red;
+ }
+
+ &:hover,
+ &:focus {
+ background: none;
+ cursor: pointer;
+ }
+
+ .controls-container.dropdown-menu {
+ top: 0;
+ left: unset;
+ right: 10px;
+
+ &.is-open {
+ display: block;
+ }
+
+ & li {
+ white-space: nowrap;
+ }
+ }
+}
+
+.modal img.loading {
+ width: 50px;
+ margin: 0;
+ position: relative;
+}
+
+.react-bs-container-body {
+ max-height: 400px;
+ overflow-y: auto;
+}
+
+.hidden,
+#pageDropDown {
+ display: none;
+}
+
+.separator .chart-container {
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+}
+
+.dashboard .title {
+ margin: 0 20px;
+}
+
+.dashboard .title .favstar {
+ font-size: 20px;
+ line-height: 1em;
+ position: relative;
+ top: -5px;
+}
+
+.ace_gutter {
+ z-index: 0;
+}
+.ace_content {
+ z-index: 0;
+}
+.ace_scrollbar {
+ z-index: 0;
+}
+.slice_container .alert {
+ margin: 10px;
+}
+
+i.danger {
+ color: red;
+}
+
+i.warning {
+ color: orange;
+}
diff --git a/superset/assets/src/dashboard/v2/stylesheets/dnd.less b/superset/assets/src/dashboard/stylesheets/dnd.less
similarity index 98%
rename from superset/assets/src/dashboard/v2/stylesheets/dnd.less
rename to superset/assets/src/dashboard/stylesheets/dnd.less
index 45a9784..835b62b 100644
--- a/superset/assets/src/dashboard/v2/stylesheets/dnd.less
+++ b/superset/assets/src/dashboard/stylesheets/dnd.less
@@ -12,7 +12,7 @@
/* drop indicators */
.drop-indicator {
- margin: auto;
+ display: block;
background-color: @indicator-color;
position: absolute;
z-index: 10;
diff --git a/superset/assets/src/dashboard/v2/stylesheets/grid.less b/superset/assets/src/dashboard/stylesheets/grid.less
similarity index 68%
rename from superset/assets/src/dashboard/v2/stylesheets/grid.less
rename to superset/assets/src/dashboard/stylesheets/grid.less
index 45b8a42..a12ac97 100644
--- a/superset/assets/src/dashboard/v2/stylesheets/grid.less
+++ b/superset/assets/src/dashboard/stylesheets/grid.less
@@ -1,12 +1,22 @@
.grid-container {
+ min-height: 100%;
position: relative;
margin: 24px;
+ /* without this, the grid will not get smaller upon toggling the builder panel on */
+ min-width: 0;
+ width: 100%;
+}
+
+/* this is the ParentSize wrapper */
+.grid-container > div:first-child {
+ height: inherit !important;
}
.grid-content {
- height: 100%;
+ min-height: 100%;
display: flex;
flex-direction: column;
+ margin-bottom: 100px;
}
/* gutters between rows */
@@ -23,7 +33,7 @@
.grid-column-guide {
position: absolute;
top: 0;
- height: 100%;
+ min-height: 100%;
background-color: rgba(68, 192, 255, 0.05);
pointer-events: none;
box-shadow: inset 0 0 0 1px rgba(68, 192, 255, 0.5);
diff --git a/superset/assets/src/dashboard/v2/stylesheets/hover-menu.less b/superset/assets/src/dashboard/stylesheets/hover-menu.less
similarity index 100%
rename from superset/assets/src/dashboard/v2/stylesheets/hover-menu.less
rename to superset/assets/src/dashboard/stylesheets/hover-menu.less
diff --git a/superset/assets/src/dashboard/v2/stylesheets/index.less b/superset/assets/src/dashboard/stylesheets/index.less
similarity index 81%
rename from superset/assets/src/dashboard/v2/stylesheets/index.less
rename to superset/assets/src/dashboard/stylesheets/index.less
index 49ff5da..b69c7b0 100644
--- a/superset/assets/src/dashboard/v2/stylesheets/index.less
+++ b/superset/assets/src/dashboard/stylesheets/index.less
@@ -1,7 +1,9 @@
@import './variables.less';
@import './builder.less';
+@import './builder-sidepane.less';
@import './buttons.less';
+@import './dashboard.less';
@import './dnd.less';
@import './grid.less';
@import './hover-menu.less';
diff --git a/superset/assets/src/dashboard/v2/stylesheets/popover-menu.less b/superset/assets/src/dashboard/stylesheets/popover-menu.less
similarity index 100%
rename from superset/assets/src/dashboard/v2/stylesheets/popover-menu.less
rename to superset/assets/src/dashboard/stylesheets/popover-menu.less
diff --git a/superset/assets/src/dashboard/v2/stylesheets/resizable.less b/superset/assets/src/dashboard/stylesheets/resizable.less
similarity index 69%
rename from superset/assets/src/dashboard/v2/stylesheets/resizable.less
rename to superset/assets/src/dashboard/stylesheets/resizable.less
index 7bdd5f8..973daab 100644
--- a/superset/assets/src/dashboard/v2/stylesheets/resizable.less
+++ b/superset/assets/src/dashboard/stylesheets/resizable.less
@@ -16,6 +16,7 @@
.resize-handle {
opacity: 0;
+ z-index: 10;
}
.resizable-container:hover .resize-handle,
@@ -35,26 +36,43 @@
height: 8px;
}
+
.resize-handle--right {
width: 2px;
height: 20px;
- right: 2px;
- top: ~"calc(50% - 9px)"; /* escape for .less */
+ right: 4px;
+ top: 50%;
+ transform: translate(0, -50%);
position: absolute;
border-left: 1px solid @gray;
border-right: 1px solid @gray;
}
+.dragdroppable-column .resizable-container-handle--right {
+ /* override the default because the inner column's handle's mouse target is very small */
+ right: -10px !important;
+}
+
+.dragdroppable-column .dragdroppable-column .resizable-container-handle--right {
+ /* override the default because the inner column's handle's mouse target is very small */
+ right: 0px !important;
+}
+
.resize-handle--bottom {
height: 2px;
width: 20px;
- bottom: 2px;
- left: ~"calc(50% - 10px)"; /* escape for .less */
+ bottom: 4px;
+ left: 50%;
+ transform: translate(-50%);
position: absolute;
border-top: 1px solid @gray;
border-bottom: 1px solid @gray;
}
+.resizable-container-handle--bottom {
+ bottom: 0 !important;
+}
+
.resizable-container--resizing > span .resize-handle {
border-color: @indicator-color;
}
diff --git a/superset/assets/src/dashboard/v2/stylesheets/toast.less b/superset/assets/src/dashboard/stylesheets/toast.less
similarity index 91%
rename from superset/assets/src/dashboard/v2/stylesheets/toast.less
rename to superset/assets/src/dashboard/stylesheets/toast.less
index a508637..1d1ebc5 100644
--- a/superset/assets/src/dashboard/v2/stylesheets/toast.less
+++ b/superset/assets/src/dashboard/stylesheets/toast.less
@@ -13,8 +13,7 @@
opacity: 0;
position: relative;
white-space: pre-line;
- box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.15);
- border-radius: 2px;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.35);
will-change: transform, opacity;
transform: translateY(-100%);
transition: transform .3s, opacity .3s;
@@ -38,7 +37,7 @@
position: absolute;
top: 0;
left: 0;
- width: 4px;
+ width: 6px;
height: 100%;
}
diff --git a/superset/assets/src/dashboard/v2/stylesheets/variables.less b/superset/assets/src/dashboard/stylesheets/variables.less
similarity index 100%
rename from superset/assets/src/dashboard/v2/stylesheets/variables.less
rename to superset/assets/src/dashboard/stylesheets/variables.less
diff --git a/superset/assets/src/dashboard/util/backgroundStyleOptions.js b/superset/assets/src/dashboard/util/backgroundStyleOptions.js
new file mode 100644
index 0000000..926e7f1
--- /dev/null
+++ b/superset/assets/src/dashboard/util/backgroundStyleOptions.js
@@ -0,0 +1,15 @@
+import { t } from '../../locales';
+import { BACKGROUND_TRANSPARENT, BACKGROUND_WHITE } from './constants';
+
+export default [
+ {
+ value: BACKGROUND_TRANSPARENT,
+ label: t('Transparent'),
+ className: 'background--transparent',
+ },
+ {
+ value: BACKGROUND_WHITE,
+ label: t('White'),
+ className: 'background--white',
+ },
+];
diff --git a/superset/assets/src/dashboard/util/charts/getEffectiveExtraFilters.js b/superset/assets/src/dashboard/util/charts/getEffectiveExtraFilters.js
new file mode 100644
index 0000000..f48631f
--- /dev/null
+++ b/superset/assets/src/dashboard/util/charts/getEffectiveExtraFilters.js
@@ -0,0 +1,42 @@
+export default function getEffectiveExtraFilters({
+ dashboardMetadata,
+ filters,
+ sliceId,
+}) {
+ const immuneSlices = dashboardMetadata.filter_immune_slices || [];
+
+ const effectiveFilters = [];
+
+ if (sliceId && immuneSlices.includes(sliceId)) {
+ // The slice is immune to dashboard filters
+ return effectiveFilters;
+ }
+
+ // Build a list of fields the slice is immune to filters on
+ let immuneToFields = [];
+ if (
+ sliceId &&
+ dashboardMetadata.filter_immune_slice_fields &&
+ dashboardMetadata.filter_immune_slice_fields[sliceId]
+ ) {
+ immuneToFields = dashboardMetadata.filter_immune_slice_fields[sliceId];
+ }
+
+ Object.keys(filters).forEach(filteringSliceId => {
+ if (filteringSliceId === sliceId.toString()) {
+ // Filters applied by the slice don't apply to itself
+ return;
+ }
+ Object.keys(filters[filteringSliceId]).forEach(field => {
+ if (!immuneToFields.includes(field)) {
+ effectiveFilters.push({
+ col: field,
+ op: 'in',
+ val: filters[filteringSliceId][field],
+ });
+ }
+ });
+ });
+
+ return effectiveFilters;
+}
diff --git a/superset/assets/src/dashboard/util/charts/getFormDataWithExtraFilters.js b/superset/assets/src/dashboard/util/charts/getFormDataWithExtraFilters.js
new file mode 100644
index 0000000..031d90d
--- /dev/null
+++ b/superset/assets/src/dashboard/util/charts/getFormDataWithExtraFilters.js
@@ -0,0 +1,42 @@
+import getEffectiveExtraFilters from './getEffectiveExtraFilters';
+
+// We cache formData objects so that our connected container components don't always trigger
+// render cascades. we cannot leverage the reselect library because our cache size is >1
+const cachedDashboardMetadataByChart = {};
+const cachedFiltersByChart = {};
+const cachedFormdataByChart = {};
+
+export default function getFormDataWithExtraFilters({
+ chart,
+ dashboardMetadata,
+ filters,
+ sliceId,
+}) {
+ // if dashboard metadata + filters have not changed, use cache if possible
+ if (
+ cachedDashboardMetadataByChart[sliceId] &&
+ cachedDashboardMetadataByChart[sliceId] === dashboardMetadata &&
+ cachedFiltersByChart[sliceId] &&
+ cachedFiltersByChart[sliceId] === filters &&
+ cachedFormdataByChart[sliceId]
+ ) {
+ return cachedFormdataByChart[sliceId];
+ }
+
+ const extraFilters = getEffectiveExtraFilters({
+ dashboardMetadata,
+ filters,
+ sliceId,
+ });
+
+ const formData = {
+ ...chart.formData,
+ extra_filters: [...chart.formData.filters, ...extraFilters],
+ };
+
+ cachedDashboardMetadataByChart[sliceId] = dashboardMetadata;
+ cachedFiltersByChart[sliceId] = filters;
+ cachedFormdataByChart[sliceId] = formData;
+
+ return formData;
+}
diff --git a/superset/assets/src/dashboard/util/componentIsResizable.js b/superset/assets/src/dashboard/util/componentIsResizable.js
new file mode 100644
index 0000000..45812d7
--- /dev/null
+++ b/superset/assets/src/dashboard/util/componentIsResizable.js
@@ -0,0 +1,5 @@
+import { COLUMN_TYPE, CHART_TYPE, MARKDOWN_TYPE } from './componentTypes';
+
+export default function componentIsResizable(entity) {
+ return [COLUMN_TYPE, CHART_TYPE, MARKDOWN_TYPE].indexOf(entity.type) > -1;
+}
diff --git a/superset/assets/src/dashboard/v2/util/componentTypes.js b/superset/assets/src/dashboard/util/componentTypes.js
similarity index 100%
rename from superset/assets/src/dashboard/v2/util/componentTypes.js
rename to superset/assets/src/dashboard/util/componentTypes.js
diff --git a/superset/assets/src/dashboard/v2/util/constants.js b/superset/assets/src/dashboard/util/constants.js
similarity index 100%
rename from superset/assets/src/dashboard/v2/util/constants.js
rename to superset/assets/src/dashboard/util/constants.js
diff --git a/superset/assets/src/dashboard/util/dashboardHelper.js b/superset/assets/src/dashboard/util/dashboardHelper.js
deleted file mode 100644
index c9a6021..0000000
--- a/superset/assets/src/dashboard/util/dashboardHelper.js
+++ /dev/null
@@ -1,9 +0,0 @@
-export function getChartIdsFromLayout(layout) {
- return Object.values(layout)
- .reduce((chartIds, value) => {
- if (value && value.meta && value.meta.chartId) {
- chartIds.push(value.meta.chartId);
- }
- return chartIds;
- }, []);
-}
diff --git a/superset/assets/src/dashboard/util/dashboardLayoutConverter.js b/superset/assets/src/dashboard/util/dashboardLayoutConverter.js
index 854ca65..f04b50e 100644
--- a/superset/assets/src/dashboard/util/dashboardLayoutConverter.js
+++ b/superset/assets/src/dashboard/util/dashboardLayoutConverter.js
@@ -8,19 +8,23 @@ import {
DASHBOARD_HEADER_TYPE,
DASHBOARD_ROOT_TYPE,
DASHBOARD_GRID_TYPE,
-} from '../v2/util/componentTypes';
+} from './componentTypes';
import {
DASHBOARD_GRID_ID,
DASHBOARD_HEADER_ID,
DASHBOARD_ROOT_ID,
-} from '../v2/util/constants';
+} from './constants';
const MAX_RECURSIVE_LEVEL = 6;
const GRID_RATIO = 4;
const ROW_HEIGHT = 8;
const generateId = (() => {
let componentId = 1;
- return () => (componentId++);
+ return () => {
+ const id = componentId;
+ componentId += 1;
+ return id;
+ };
})();
/**
@@ -33,7 +37,7 @@ function getBoundary(positions) {
let bottom = 0;
let left = Number.MAX_VALUE;
let right = 1;
- positions.forEach((item) => {
+ positions.forEach(item => {
const { row, col, size_x, size_y } = item;
if (row <= top) top = row;
if (col <= left) left = col;
@@ -50,11 +54,10 @@ function getBoundary(positions) {
}
function getRowContainer() {
- const id = 'DASHBOARD_ROW_TYPE-' + generateId();
return {
version: 'v2',
type: ROW_TYPE,
- id,
+ id: `DASHBOARD_ROW_TYPE-${generateId()}`,
children: [],
meta: {
background: 'BACKGROUND_TRANSPARENT',
@@ -63,11 +66,10 @@ function getRowContainer() {
}
function getColContainer() {
- const id = 'DASHBOARD_COLUMN_TYPE-' + generateId();
return {
version: 'v2',
type: COLUMN_TYPE,
- id,
+ id: `DASHBOARD_COLUMN_TYPE-${generateId()}`,
children: [],
meta: {
background: 'BACKGROUND_TRANSPARENT',
@@ -88,7 +90,7 @@ function getChartHolder(item) {
return {
version: 'v2',
type: CHART_TYPE,
- id: 'DASHBOARD_CHART_TYPE-' + generateId(),
+ id: `DASHBOARD_CHART_TYPE-${generateId()}`,
children: [],
meta: {
width: converted.size_x,
@@ -99,13 +101,31 @@ function getChartHolder(item) {
}
function getChildrenMax(items, attr, layout) {
- return Math.max.apply(null, items.map(child => (layout[child].meta[attr])));
+ return Math.max.apply(null, items.map(child => layout[child].meta[attr]));
}
function getChildrenSum(items, attr, layout) {
- return items.reduce((preValue, child) => (preValue + layout[child].meta[attr]), 0);
+ return items.reduce(
+ (preValue, child) => preValue + layout[child].meta[attr],
+ 0,
+ );
}
+// function getChildrenMax(items, attr, layout) {
+// return Math.max.apply(null, items.map((childId) => {
+// const child = layout[childId];
+// if (child.type === ROW_TYPE && attr === 'width') {
+// // rows don't have widths themselves
+// return getChildrenSum(child.children, attr, layout);
+// } else if (child.type === COLUMN_TYPE && attr === 'height') {
+// // columns don't have heights themselves
+// return getChildrenSum(child.children, attr, layout);
+// }
+//
+// return child.meta[attr];
+// }));
+// }
+
function sortByRowId(item1, item2) {
return item1.row - item2.row;
}
@@ -115,7 +135,8 @@ function sortByColId(item1, item2) {
}
function hasOverlap(positions, xAxis = true) {
- return positions.slice()
+ return positions
+ .slice()
.sort(xAxis ? sortByColId : sortByRowId)
.some((item, index, arr) => {
if (index === arr.length - 1) {
@@ -123,9 +144,9 @@ function hasOverlap(positions, xAxis = true) {
}
if (xAxis) {
- return (item.col + item.size_x) > arr[index + 1].col;
+ return item.col + item.size_x > arr[index + 1].col;
}
- return (item.row + item.size_y) > arr[index + 1].row;
+ return item.row + item.size_y > arr[index + 1].row;
});
}
@@ -158,7 +179,7 @@ function doConvert(positions, level, parent, root) {
const upper = [];
const lower = [];
- const isRowDivider = currentItems.every((item) => {
+ const isRowDivider = currentItems.every(item => {
const { row, size_y } = item;
if (row + size_y <= currentRow) {
lower.push(item);
@@ -174,10 +195,10 @@ function doConvert(positions, level, parent, root) {
currentItems = upper.slice();
layers.push(lower);
}
- currentRow++;
+ currentRow += 1;
}
- layers.forEach((layer) => {
+ layers.forEach(layer => {
if (layer.length === 0) {
return;
}
@@ -196,7 +217,7 @@ function doConvert(positions, level, parent, root) {
currentItems = layer.slice();
if (!hasOverlap(currentItems)) {
- currentItems.sort(sortByColId).forEach((item) => {
+ currentItems.sort(sortByColId).forEach(item => {
const chartHolder = getChartHolder(item);
root[chartHolder.id] = chartHolder;
rowContainer.children.push(chartHolder.id);
@@ -208,7 +229,7 @@ function doConvert(positions, level, parent, root) {
const upper = [];
const lower = [];
- const isColDivider = currentItems.every((item) => {
+ const isColDivider = currentItems.every(item => {
const { col, size_x } = item;
if (col + size_x <= currentCol) {
lower.push(item);
@@ -232,7 +253,7 @@ function doConvert(positions, level, parent, root) {
rowContainer.children.push(colContainer.id);
if (!hasOverlap(lower, false)) {
- lower.sort(sortByRowId).forEach((item) => {
+ lower.sort(sortByRowId).forEach(item => {
const chartHolder = getChartHolder(item);
root[chartHolder.id] = chartHolder;
colContainer.children.push(chartHolder.id);
@@ -242,37 +263,47 @@ function doConvert(positions, level, parent, root) {
}
// add col meta
- colContainer.meta.width = getChildrenMax(colContainer.children, 'width', root);
+ colContainer.meta.width = getChildrenMax(
+ colContainer.children,
+ 'width',
+ root,
+ );
}
currentItems = upper.slice();
}
- currentCol++;
+ currentCol += 1;
}
}
- rowContainer.meta.width = getChildrenSum(rowContainer.children, 'width', root);
+ rowContainer.meta.width = getChildrenSum(
+ rowContainer.children,
+ 'width',
+ root,
+ );
});
}
-export default function (dashboard) {
+export default function(dashboard) {
const positions = [];
// position data clean up. some dashboard didn't have position_json
let { position_json } = dashboard;
const posDict = {};
if (Array.isArray(position_json)) {
- position_json.forEach((position) => {
+ position_json.forEach(position => {
posDict[position.slice_id] = position;
});
} else {
position_json = [];
}
- const lastRowId = Math.max(0, Math.max.apply(null,
- position_json.map(pos => (pos.row + pos.size_y))));
+ const lastRowId = Math.max(
+ 0,
+ Math.max.apply(null, position_json.map(pos => pos.row + pos.size_y)),
+ );
let newSliceCounter = 0;
- dashboard.slices.forEach((slice) => {
+ dashboard.slices.forEach(slice => {
const sliceId = slice.slice_id;
let pos = posDict[sliceId];
if (!pos) {
@@ -284,7 +315,7 @@ export default function (dashboard) {
size_y: 16,
slice_id: String(sliceId),
};
- newSliceCounter++;
+ newSliceCounter += 1;
}
positions.push(pos);
@@ -292,7 +323,6 @@ export default function (dashboard) {
const root = {
[DASHBOARD_ROOT_ID]: {
- version: 'v2',
type: DASHBOARD_ROOT_TYPE,
id: DASHBOARD_ROOT_ID,
children: [DASHBOARD_GRID_ID],
@@ -310,13 +340,12 @@ export default function (dashboard) {
doConvert(positions, 0, root[DASHBOARD_GRID_ID], root);
// remove row's width/height and col's height
- Object.values(root).forEach((item) => {
+ Object.values(root).forEach(item => {
if (ROW_TYPE === item.type) {
const meta = item.meta;
delete meta.width;
}
});
- // console.log(JSON.stringify(root));
return root;
}
diff --git a/superset/assets/src/dashboard/v2/util/dnd-reorder.js b/superset/assets/src/dashboard/util/dnd-reorder.js
similarity index 84%
rename from superset/assets/src/dashboard/v2/util/dnd-reorder.js
rename to superset/assets/src/dashboard/util/dnd-reorder.js
index 9a0dedf..76fb56c 100644
--- a/superset/assets/src/dashboard/v2/util/dnd-reorder.js
+++ b/superset/assets/src/dashboard/util/dnd-reorder.js
@@ -6,22 +6,14 @@ export function reorder(list, startIndex, endIndex) {
return result;
}
-export default function reorderItem({
- entitiesMap,
- source,
- destination,
-}) {
+export default function reorderItem({ entitiesMap, source, destination }) {
const current = [...entitiesMap[source.id].children];
const next = [...entitiesMap[destination.id].children];
const target = current[source.index];
// moving to same list
if (source.id === destination.id) {
- const reordered = reorder(
- current,
- source.index,
- destination.index,
- );
+ const reordered = reorder(current, source.index, destination.index);
const result = {
...entitiesMap,
diff --git a/superset/assets/src/dashboard/v2/util/dropOverflowsParent.js b/superset/assets/src/dashboard/util/dropOverflowsParent.js
similarity index 55%
rename from superset/assets/src/dashboard/v2/util/dropOverflowsParent.js
rename to superset/assets/src/dashboard/util/dropOverflowsParent.js
index 0fd0c4e..bc7195f 100644
--- a/superset/assets/src/dashboard/v2/util/dropOverflowsParent.js
+++ b/superset/assets/src/dashboard/util/dropOverflowsParent.js
@@ -1,23 +1,37 @@
import { COLUMN_TYPE } from '../util/componentTypes';
-import { GRID_COLUMN_COUNT, NEW_COMPONENTS_SOURCE_ID } from './constants';
+import {
+ GRID_COLUMN_COUNT,
+ NEW_COMPONENTS_SOURCE_ID,
+ GRID_MIN_COLUMN_COUNT,
+} from './constants';
import findParentId from './findParentId';
import getChildWidth from './getChildWidth';
import newComponentFactory from './newComponentFactory';
export default function doesChildOverflowParent(dropResult, components) {
const { source, destination, dragging } = dropResult;
- const isNewComponent = source.id === NEW_COMPONENTS_SOURCE_ID;
+ // moving a component within a container should never overflow
+ if (source.id === destination.id) {
+ return false;
+ }
+
+ const isNewComponent = source.id === NEW_COMPONENTS_SOURCE_ID;
const grandparentId = findParentId({ childId: destination.id, components });
- const child = isNewComponent ? newComponentFactory(dragging.type) : components[dragging.id] || {};
+ const child = isNewComponent
+ ? newComponentFactory(dragging.type)
+ : components[dragging.id] || {};
const parent = components[destination.id] || {};
const grandparent = components[grandparentId] || {};
- const grandparentWidth = (grandparent.meta && grandparent.meta.width) || GRID_COLUMN_COUNT;
+ const grandparentWidth =
+ (grandparent.meta && grandparent.meta.width) || GRID_COLUMN_COUNT;
const parentWidth = (parent.meta && parent.meta.width) || grandparentWidth;
- const parentChildWidth = parent.type === COLUMN_TYPE
- ? 0 : getChildWidth({ id: destination.id, components });
+ const parentChildWidth =
+ parent.type === COLUMN_TYPE
+ ? (parent.meta && parent.meta.width) || GRID_MIN_COLUMN_COUNT
+ : getChildWidth({ id: destination.id, components });
const childWidth = (child.meta && child.meta.width) || 0;
return parentWidth - parentChildWidth < childWidth;
diff --git a/superset/assets/src/dashboard/v2/util/findParentId.js b/superset/assets/src/dashboard/util/findParentId.js
similarity index 73%
rename from superset/assets/src/dashboard/v2/util/findParentId.js
rename to superset/assets/src/dashboard/util/findParentId.js
index 0ca15a6..f84b0de 100644
--- a/superset/assets/src/dashboard/v2/util/findParentId.js
+++ b/superset/assets/src/dashboard/util/findParentId.js
@@ -5,7 +5,11 @@ export default function findParentId({ childId, components = {} }) {
for (let i = 0; i < ids.length - 1; i += 1) {
const id = ids[i];
const component = components[id] || {};
- if (id !== childId && component.children && component.children.includes(childId)) {
+ if (
+ id !== childId &&
+ component.children &&
+ component.children.includes(childId)
+ ) {
parentId = id;
break;
}
diff --git a/superset/assets/src/dashboard/util/getChartIdsFromLayout.js b/superset/assets/src/dashboard/util/getChartIdsFromLayout.js
new file mode 100644
index 0000000..f0963c1
--- /dev/null
+++ b/superset/assets/src/dashboard/util/getChartIdsFromLayout.js
@@ -0,0 +1,8 @@
+export default function getChartIdsFromLayout(layout) {
+ return Object.values(layout).reduce((chartIds, value) => {
+ if (value && value.meta && value.meta.chartId) {
+ chartIds.push(value.meta.chartId);
+ }
+ return chartIds;
+ }, []);
+}
diff --git a/superset/assets/src/dashboard/v2/util/getChildWidth.js b/superset/assets/src/dashboard/util/getChildWidth.js
similarity index 55%
rename from superset/assets/src/dashboard/v2/util/getChildWidth.js
rename to superset/assets/src/dashboard/util/getChildWidth.js
index aa32b96..69d2792 100644
--- a/superset/assets/src/dashboard/v2/util/getChildWidth.js
+++ b/superset/assets/src/dashboard/util/getChildWidth.js
@@ -4,9 +4,9 @@ export default function getTotalChildWidth({ id, components }) {
let width = 0;
- (component.children || []).forEach((childId) => {
- const child = components[childId];
- width += child.meta.width || 0;
+ (component.children || []).forEach(childId => {
+ const child = components[childId] || {};
+ width += (child.meta || {}).width || 0;
});
return width;
diff --git a/superset/assets/src/dashboard/v2/util/getDropPosition.js b/superset/assets/src/dashboard/util/getDropPosition.js
similarity index 80%
rename from superset/assets/src/dashboard/v2/util/getDropPosition.js
rename to superset/assets/src/dashboard/util/getDropPosition.js
index 9605db2..2a02702 100644
--- a/superset/assets/src/dashboard/v2/util/getDropPosition.js
+++ b/superset/assets/src/dashboard/util/getDropPosition.js
@@ -8,7 +8,7 @@ export const DROP_LEFT = 'DROP_LEFT';
// this defines how close the mouse must be to the edge of a component to display
// a sibling type drop indicator
-const SIBLING_DROP_THRESHOLD = 15;
+const SIBLING_DROP_THRESHOLD = 20;
export default function getDropPosition(monitor, Component) {
const {
@@ -22,7 +22,11 @@ export default function getDropPosition(monitor, Component) {
const draggingItem = monitor.getItem();
// if dropped self on self, do nothing
- if (!draggingItem || draggingItem.id === component.id || !isDraggingOverShallow) {
+ if (
+ !draggingItem ||
+ draggingItem.id === component.id ||
+ !isDraggingOverShallow
+ ) {
return null;
}
@@ -34,7 +38,8 @@ export default function getDropPosition(monitor, Component) {
const parentType = parentComponent && parentComponent.type;
const parentDepth = // see isValidChild.js for why tabs don't increment child depth
- componentDepth + (parentType === TAB_TYPE || parentType === TABS_TYPE ? 0 : -1);
+ componentDepth +
+ (parentType === TAB_TYPE || parentType === TABS_TYPE ? 0 : -1);
const validSibling = isValidChild({
parentType,
@@ -47,10 +52,13 @@ export default function getDropPosition(monitor, Component) {
}
const hasChildren = (component.children || []).length > 0;
- const childDropOrientation = orientation === 'row' ? 'vertical' : 'horizontal';
- const siblingDropOrientation = orientation === 'row' ? 'horizontal' : 'vertical';
+ const childDropOrientation =
+ orientation === 'row' ? 'vertical' : 'horizontal';
+ const siblingDropOrientation =
+ orientation === 'row' ? 'horizontal' : 'vertical';
- if (validChild && !validSibling) { // easiest case, insert as child
+ if (validChild && !validSibling) {
+ // easiest case, insert as child
if (childDropOrientation === 'vertical') {
return hasChildren ? DROP_RIGHT : DROP_LEFT;
}
@@ -64,10 +72,12 @@ export default function getDropPosition(monitor, Component) {
if (validSibling && !validChild) {
if (siblingDropOrientation === 'vertical') {
const refMiddleX =
- refBoundingRect.left + ((refBoundingRect.right - refBoundingRect.left) / 2);
+ refBoundingRect.left +
+ (refBoundingRect.right - refBoundingRect.left) / 2;
return clientOffset.x < refMiddleX ? DROP_LEFT : DROP_RIGHT;
}
- const refMiddleY = refBoundingRect.top + ((refBoundingRect.bottom - refBoundingRect.top) / 2);
+ const refMiddleY =
+ refBoundingRect.top + (refBoundingRect.bottom - refBoundingRect.top) / 2;
return clientOffset.y < refMiddleY ? DROP_TOP : DROP_BOTTOM;
}
diff --git a/superset/assets/src/dashboard/v2/util/headerStyleOptions.js b/superset/assets/src/dashboard/util/headerStyleOptions.js
similarity index 89%
rename from superset/assets/src/dashboard/v2/util/headerStyleOptions.js
rename to superset/assets/src/dashboard/util/headerStyleOptions.js
index 309d482..7efa040 100644
--- a/superset/assets/src/dashboard/v2/util/headerStyleOptions.js
+++ b/superset/assets/src/dashboard/util/headerStyleOptions.js
@@ -1,4 +1,4 @@
-import { t } from '../../../locales';
+import { t } from '../../locales';
import { SMALL_HEADER, MEDIUM_HEADER, LARGE_HEADER } from './constants';
export default [
diff --git a/superset/assets/src/dashboard/v2/util/isValidChild.js b/superset/assets/src/dashboard/util/isValidChild.js
similarity index 65%
rename from superset/assets/src/dashboard/v2/util/isValidChild.js
rename to superset/assets/src/dashboard/util/isValidChild.js
index 66942f0..d789f45 100644
--- a/superset/assets/src/dashboard/v2/util/isValidChild.js
+++ b/superset/assets/src/dashboard/util/isValidChild.js
@@ -1,19 +1,19 @@
/* eslint max-len: 0 */
/**
- * When determining if a component is a valid child of another component we must consider both
- * - parent + child component types
- * - component depth, or depth of nesting of container components
- *
- * We consider types because some components aren't containers (e.g. a heading) and we consider
- * depth to prevent infinite nesting of container components.
- *
- * The following example container nestings should be valid, which means that some containers
- * don't increase the (depth) of their children, namely tabs and tab:
- * (a) root (0) > grid (1) > row (2) > column (3) > row (4) > non-container (5)
- * (b) root (0) > grid (1) > tabs (2) > tab (2) > row (2) > column (3) > row (4) > non-container (5)
- * (c) root (0) > top-tab (1) > row (2) > column (3) > row (4) > non-container (5)
- * (d) root (0) > top-tab (1) > tabs (2) > tab (2) > row (2) > column (3) > row (4) > non-container (5)
- */
+ * When determining if a component is a valid child of another component we must consider both
+ * - parent + child component types
+ * - component depth, or depth of nesting of container components
+ *
+ * We consider types because some components aren't containers (e.g. a heading) and we consider
+ * depth to prevent infinite nesting of container components.
+ *
+ * The following example container nestings should be valid, which means that some containers
+ * don't increase the (depth) of their children, namely tabs and tab:
+ * (a) root (0) > grid (1) > row (2) > column (3) > row (4) > non-container (5)
+ * (b) root (0) > grid (1) > tabs (2) > tab (2) > row (2) > column (3) > row (4) > non-container (5)
+ * (c) root (0) > top-tab (1) > row (2) > column (3) > row (4) > non-container (5)
+ * (d) root (0) > top-tab (1) > tabs (2) > tab (2) > row (2) > column (3) > row (4) > non-container (5)
+ */
import {
CHART_TYPE,
COLUMN_TYPE,
diff --git a/superset/assets/src/dashboard/v2/util/newComponentFactory.js b/superset/assets/src/dashboard/util/newComponentFactory.js
similarity index 81%
rename from superset/assets/src/dashboard/v2/util/newComponentFactory.js
rename to superset/assets/src/dashboard/util/newComponentFactory.js
index b428ddd..4e2de37 100644
--- a/superset/assets/src/dashboard/v2/util/newComponentFactory.js
+++ b/superset/assets/src/dashboard/util/newComponentFactory.js
@@ -1,3 +1,5 @@
+import shortid from 'shortid';
+
import {
CHART_TYPE,
COLUMN_TYPE,
@@ -9,10 +11,7 @@ import {
TAB_TYPE,
} from './componentTypes';
-import {
- MEDIUM_HEADER,
- BACKGROUND_TRANSPARENT,
-} from './constants';
+import { MEDIUM_HEADER, BACKGROUND_TRANSPARENT } from './constants';
const typeToDefaultMetaData = {
[CHART_TYPE]: { width: 3, height: 30 },
@@ -29,9 +28,8 @@ const typeToDefaultMetaData = {
[TAB_TYPE]: { text: 'New Tab' },
};
-// @TODO this should be replaced by a more robust algorithm
function uuid(type) {
- return `${type}-${Math.random().toString(16)}`;
+ return `${type}-${shortid.generate()}`;
}
export default function entityFactory(type, meta) {
diff --git a/superset/assets/src/dashboard/v2/util/newEntitiesFromDrop.js b/superset/assets/src/dashboard/util/newEntitiesFromDrop.js
similarity index 81%
rename from superset/assets/src/dashboard/v2/util/newEntitiesFromDrop.js
rename to superset/assets/src/dashboard/util/newEntitiesFromDrop.js
index 7cccc5f..7fe7f4e 100644
--- a/superset/assets/src/dashboard/v2/util/newEntitiesFromDrop.js
+++ b/superset/assets/src/dashboard/util/newEntitiesFromDrop.js
@@ -1,11 +1,7 @@
import shouldWrapChildInRow from './shouldWrapChildInRow';
import newComponentFactory from './newComponentFactory';
-import {
- ROW_TYPE,
- TABS_TYPE,
- TAB_TYPE,
-} from './componentTypes';
+import { ROW_TYPE, TABS_TYPE, TAB_TYPE } from './componentTypes';
export default function newEntitiesFromDrop({ dropResult, components }) {
const { dragging, destination } = dropResult;
@@ -15,7 +11,10 @@ export default function newEntitiesFromDrop({ dropResult, components }) {
const dropEntity = components[destination.id];
const dropType = dropEntity.type;
let newDropChild = newComponentFactory(dragType, dragMeta);
- const wrapChildInRow = shouldWrapChildInRow({ parentType: dropType, childType: dragType });
+ const wrapChildInRow = shouldWrapChildInRow({
+ parentType: dropType,
+ childType: dragType,
+ });
const newEntities = {
[newDropChild.id]: newDropChild,
@@ -26,7 +25,8 @@ export default function newEntitiesFromDrop({ dropResult, components }) {
rowWrapper.children = [newDropChild.id];
newEntities[rowWrapper.id] = rowWrapper;
newDropChild = rowWrapper;
- } else if (dragType === TABS_TYPE) { // create a new tab component
+ } else if (dragType === TABS_TYPE) {
+ // create a new tab component
const tabChild = newComponentFactory(TAB_TYPE);
newDropChild.children = [tabChild.id];
newEntities[tabChild.id] = tabChild;
diff --git a/superset/assets/src/dashboard/v2/util/propShapes.jsx b/superset/assets/src/dashboard/util/propShapes.jsx
similarity index 88%
rename from superset/assets/src/dashboard/v2/util/propShapes.jsx
rename to superset/assets/src/dashboard/util/propShapes.jsx
index 388c726..73a10b0 100644
--- a/superset/assets/src/dashboard/v2/util/propShapes.jsx
+++ b/superset/assets/src/dashboard/util/propShapes.jsx
@@ -2,13 +2,16 @@ import PropTypes from 'prop-types';
import componentTypes from './componentTypes';
import backgroundStyleOptions from './backgroundStyleOptions';
import headerStyleOptions from './headerStyleOptions';
-import { INFO_TOAST, SUCCESS_TOAST, WARNING_TOAST, DANGER_TOAST } from './constants';
+import {
+ INFO_TOAST,
+ SUCCESS_TOAST,
+ WARNING_TOAST,
+ DANGER_TOAST,
+} from './constants';
-export const componentShape = PropTypes.shape({ // eslint-disable-line
+export const componentShape = PropTypes.shape({
id: PropTypes.string.isRequired,
- type: PropTypes.oneOf(
- Object.values(componentTypes),
- ).isRequired,
+ type: PropTypes.oneOf(Object.values(componentTypes)).isRequired,
children: PropTypes.arrayOf(PropTypes.string),
meta: PropTypes.shape({
// Dimensions
@@ -25,7 +28,12 @@ export const componentShape = PropTypes.shape({ // eslint-disable-line
export const toastShape = PropTypes.shape({
id: PropTypes.string.isRequired,
- toastType: PropTypes.oneOf([INFO_TOAST, SUCCESS_TOAST, WARNING_TOAST, DANGER_TOAST]).isRequired,
+ toastType: PropTypes.oneOf([
+ INFO_TOAST,
+ SUCCESS_TOAST,
+ WARNING_TOAST,
+ DANGER_TOAST,
+ ]).isRequired,
text: PropTypes.string.isRequired,
});
diff --git a/superset/assets/src/dashboard/v2/util/resizableConfig.js b/superset/assets/src/dashboard/util/resizableConfig.js
similarity index 100%
rename from superset/assets/src/dashboard/v2/util/resizableConfig.js
rename to superset/assets/src/dashboard/util/resizableConfig.js
diff --git a/superset/assets/src/dashboard/v2/util/shouldWrapChildInRow.js b/superset/assets/src/dashboard/util/shouldWrapChildInRow.js
similarity index 100%
rename from superset/assets/src/dashboard/v2/util/shouldWrapChildInRow.js
rename to superset/assets/src/dashboard/util/shouldWrapChildInRow.js
diff --git a/superset/assets/src/dashboard/v2/actions/editMode.js b/superset/assets/src/dashboard/v2/actions/editMode.js
deleted file mode 100644
index 0a849ea..0000000
--- a/superset/assets/src/dashboard/v2/actions/editMode.js
+++ /dev/null
@@ -1,9 +0,0 @@
-export const SET_EDIT_MODE = 'SET_EDIT_MODE';
-export function setEditMode(editMode) {
- return {
- type: SET_EDIT_MODE,
- payload: {
- editMode,
- },
- };
-}
diff --git a/superset/assets/src/dashboard/v2/components/Dashboard.jsx b/superset/assets/src/dashboard/v2/components/Dashboard.jsx
deleted file mode 100644
index ffd1280..0000000
--- a/superset/assets/src/dashboard/v2/components/Dashboard.jsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import DashboardBuilder from '../containers/DashboardBuilder';
-
-import '../stylesheets/index.less';
-
-const propTypes = {
- actions: PropTypes.shape({
- updateDashboardTitle: PropTypes.func.isRequired,
- setEditMode: PropTypes.func.isRequired,
- }),
- editMode: PropTypes.bool,
-};
-
-const defaultProps = {
- editMode: true,
-};
-
-class Dashboard extends React.Component {
- render() {
- // @TODO delete this component?
- return <DashboardBuilder />;
- }
-}
-
-Dashboard.propTypes = propTypes;
-Dashboard.defaultProps = defaultProps;
-
-export default Dashboard;
diff --git a/superset/assets/src/dashboard/v2/components/DashboardHeader.jsx b/superset/assets/src/dashboard/v2/components/DashboardHeader.jsx
deleted file mode 100644
index d3ec7ac..0000000
--- a/superset/assets/src/dashboard/v2/components/DashboardHeader.jsx
+++ /dev/null
@@ -1,99 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { ButtonGroup, ButtonToolbar, DropdownButton, MenuItem } from 'react-bootstrap';
-
-import Button from '../../../components/Button';
-import { componentShape } from '../util/propShapes';
-import EditableTitle from '../../../components/EditableTitle';
-
-const propTypes = {
- editMode: PropTypes.bool.isRequired,
- component: componentShape.isRequired,
-
- // redux
- updateComponents: PropTypes.func.isRequired,
- onUndo: PropTypes.func.isRequired,
- onRedo: PropTypes.func.isRequired,
- canUndo: PropTypes.bool.isRequired,
- canRedo: PropTypes.bool.isRequired,
- setEditMode: PropTypes.func.isRequired,
-};
-
-class DashboardHeader extends React.Component {
- constructor(props) {
- super(props);
- this.handleChangeText = this.handleChangeText.bind(this);
- this.toggleEditMode = this.toggleEditMode.bind(this);
- }
-
- toggleEditMode() {
- this.props.setEditMode(!this.props.editMode);
- }
-
- handleChangeText(nextText) {
- const { updateComponents, component } = this.props;
- if (nextText && component.meta.text !== nextText) {
- updateComponents({
- [component.id]: {
- ...component,
- meta: {
- ...component.meta,
- text: nextText,
- },
- },
- });
- }
- }
-
- render() {
- const { component, onUndo, onRedo, canUndo, canRedo, editMode } = this.props;
-
- return (
- <div className="dashboard-header">
- <div className="dashboard-component-header header-large">
- <EditableTitle
- title={'Test title'}
- onSaveTitle={this.handleChangeText}
- showTooltip={false}
- canEdit={editMode}
- />
- </div>
- <ButtonToolbar>
- <ButtonGroup>
- <Button
- bsSize="small"
- onClick={onUndo}
- disabled={!canUndo}
- >
- Undo
- </Button>
- <Button
- bsSize="small"
- onClick={onRedo}
- disabled={!canRedo}
- >
- Redo
- </Button>
- </ButtonGroup>
-
- <DropdownButton title="Actions" bsSize="small" id="btn-dashboard-actions">
- <MenuItem>Action 1</MenuItem>
- <MenuItem>Action 2</MenuItem>
- <MenuItem>Action 3</MenuItem>
- </DropdownButton>
-
- <Button
- bsStyle="primary"
- onClick={this.toggleEditMode}
- >
- {editMode ? 'Save changes' : 'Edit dashboard'}
- </Button>
- </ButtonToolbar>
- </div>
- );
- }
-}
-
-DashboardHeader.propTypes = propTypes;
-
-export default DashboardHeader;
diff --git a/superset/assets/src/dashboard/v2/components/StaticDashboard.jsx b/superset/assets/src/dashboard/v2/components/StaticDashboard.jsx
deleted file mode 100644
index 4fd2397..0000000
--- a/superset/assets/src/dashboard/v2/components/StaticDashboard.jsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import React from 'react';
-// import PropTypes from 'prop-types';
-
-const propTypes = {
-};
-
-class StaticDashboard extends React.Component {
- render() {
- return (
- <div>
- Static dashboard ...
- </div>
- );
- }
-}
-
-StaticDashboard.propTypes = propTypes;
-
-export default StaticDashboard;
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewChart.jsx b/superset/assets/src/dashboard/v2/components/gridComponents/new/NewChart.jsx
deleted file mode 100644
index 0255755..0000000
--- a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewChart.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react';
-// import PropTypes from 'prop-types';
-
-import { CHART_TYPE } from '../../../util/componentTypes';
-import { NEW_CHART_ID } from '../../../util/constants';
-import DraggableNewComponent from './DraggableNewComponent';
-
-const propTypes = {
-};
-
-export default class DraggableNewChart extends React.PureComponent {
- render() {
- return (
- <DraggableNewComponent
- id={NEW_CHART_ID}
- type={CHART_TYPE}
- label="Chart"
- className="fa fa-area-chart"
- />
- );
- }
-}
-
-DraggableNewChart.propTypes = propTypes;
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewColumn.jsx b/superset/assets/src/dashboard/v2/components/gridComponents/new/NewColumn.jsx
deleted file mode 100644
index 654c60b..0000000
--- a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewColumn.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react';
-// import PropTypes from 'prop-types';
-
-import { COLUMN_TYPE } from '../../../util/componentTypes';
-import { NEW_COLUMN_ID } from '../../../util/constants';
-import DraggableNewComponent from './DraggableNewComponent';
-
-const propTypes = {
-};
-
-export default class DraggableNewColumn extends React.PureComponent {
- render() {
- return (
- <DraggableNewComponent
- id={NEW_COLUMN_ID}
- type={COLUMN_TYPE}
- label="Column"
- className="fa fa-long-arrow-down"
- />
- );
- }
-}
-
-DraggableNewColumn.propTypes = propTypes;
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewDivider.jsx b/superset/assets/src/dashboard/v2/components/gridComponents/new/NewDivider.jsx
deleted file mode 100644
index 5d70041..0000000
--- a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewDivider.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react';
-// import PropTypes from 'prop-types';
-
-import { DIVIDER_TYPE } from '../../../util/componentTypes';
-import { NEW_DIVIDER_ID } from '../../../util/constants';
-import DraggableNewComponent from './DraggableNewComponent';
-
-const propTypes = {
-};
-
-export default class DraggableNewDivider extends React.PureComponent {
- render() {
- return (
- <DraggableNewComponent
- id={NEW_DIVIDER_ID}
- type={DIVIDER_TYPE}
- label="Divider"
- className="divider-placeholder"
- />
- );
- }
-}
-
-DraggableNewDivider.propTypes = propTypes;
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewHeader.jsx b/superset/assets/src/dashboard/v2/components/gridComponents/new/NewHeader.jsx
deleted file mode 100644
index d207a9c..0000000
--- a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewHeader.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react';
-// import PropTypes from 'prop-types';
-
-import { HEADER_TYPE } from '../../../util/componentTypes';
-import { NEW_HEADER_ID } from '../../../util/constants';
-import DraggableNewComponent from './DraggableNewComponent';
-
-const propTypes = {
-};
-
-export default class DraggableNewHeader extends React.Component {
- render() {
- return (
- <DraggableNewComponent
- id={NEW_HEADER_ID}
- type={HEADER_TYPE}
- label="Header"
- className="fa fa-header"
- />
- );
- }
-}
-
-DraggableNewHeader.propTypes = propTypes;
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewRow.jsx b/superset/assets/src/dashboard/v2/components/gridComponents/new/NewRow.jsx
deleted file mode 100644
index 1d9ab10..0000000
--- a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewRow.jsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import React from 'react';
-
-import { ROW_TYPE } from '../../../util/componentTypes';
-import { NEW_ROW_ID } from '../../../util/constants';
-import DraggableNewComponent from './DraggableNewComponent';
-
-const propTypes = {
-};
-
-export default class DraggableNewRow extends React.PureComponent {
- render() {
- return (
- <DraggableNewComponent
- id={NEW_ROW_ID}
- type={ROW_TYPE}
- label="Row"
- className="fa fa-long-arrow-right"
- />
- );
- }
-}
-
-DraggableNewRow.propTypes = propTypes;
diff --git a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewTabs.jsx b/superset/assets/src/dashboard/v2/components/gridComponents/new/NewTabs.jsx
deleted file mode 100644
index a473281..0000000
--- a/superset/assets/src/dashboard/v2/components/gridComponents/new/NewTabs.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react';
-// import PropTypes from 'prop-types';
-
-import { TABS_TYPE } from '../../../util/componentTypes';
-import { NEW_TABS_ID } from '../../../util/constants';
-import DraggableNewComponent from './DraggableNewComponent';
-
-const propTypes = {
-};
-
-export default class DraggableNewTabs extends React.PureComponent {
- render() {
- return (
- <DraggableNewComponent
- id={NEW_TABS_ID}
- type={TABS_TYPE}
- label="Tabs"
- className="fa fa-window-restore"
- />
- );
- }
-}
-
-DraggableNewTabs.propTypes = propTypes;
diff --git a/superset/assets/src/dashboard/v2/reducers/editMode.js b/superset/assets/src/dashboard/v2/reducers/editMode.js
deleted file mode 100644
index b1a1630..0000000
--- a/superset/assets/src/dashboard/v2/reducers/editMode.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { SET_EDIT_MODE } from '../actions/editMode';
-
-export default function editModeReducer(editMode = false, action) {
- switch (action.type) {
- case SET_EDIT_MODE:
- return action.payload.editMode;
-
- default:
- return editMode;
- }
-}
diff --git a/superset/assets/src/dashboard/v2/reducers/index.js b/superset/assets/src/dashboard/v2/reducers/index.js
deleted file mode 100644
index 061255d..0000000
--- a/superset/assets/src/dashboard/v2/reducers/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import undoable, { distinctState } from 'redux-undo';
-
-import dashboardLayout from './dashboardLayout';
-
-export default undoable(dashboardLayout, {
- limit: 15,
- filter: distinctState(),
-});
diff --git a/superset/assets/src/dashboard/v2/stylesheets/components/chart.less b/superset/assets/src/dashboard/v2/stylesheets/components/chart.less
deleted file mode 100644
index ce03797..0000000
--- a/superset/assets/src/dashboard/v2/stylesheets/components/chart.less
+++ /dev/null
@@ -1,20 +0,0 @@
-.dashboard-component-chart {
- width: 100%;
- height: 100%;
- color: @gray-dark;
- background-color: white;
- padding: 16px;
- display: flex;
- align-items: center;
- justify-content: center;
- position: relative;
-}
-
-.dashboard-component-chart .fa {
- //font-size: 100px;
- opacity: 0.3;
-}
-
-.dashboard-v2--editing .dashboard-component-chart:hover {
- box-shadow: inset 0 0 0 1px @gray-light;
-}
diff --git a/superset/assets/src/dashboard/v2/util/backgroundStyleOptions.js b/superset/assets/src/dashboard/v2/util/backgroundStyleOptions.js
deleted file mode 100644
index cda678f..0000000
--- a/superset/assets/src/dashboard/v2/util/backgroundStyleOptions.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import { t } from '../../../locales';
-import { BACKGROUND_TRANSPARENT, BACKGROUND_WHITE } from './constants';
-
-export default [
- { value: BACKGROUND_TRANSPARENT, label: t('Transparent'), className: 'background--transparent' },
- { value: BACKGROUND_WHITE, label: t('White'), className: 'background--white' },
-];
diff --git a/superset/assets/src/dashboard/v2/util/componentIsResizable.js b/superset/assets/src/dashboard/v2/util/componentIsResizable.js
deleted file mode 100644
index c0016f3..0000000
--- a/superset/assets/src/dashboard/v2/util/componentIsResizable.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import {
- COLUMN_TYPE,
- CHART_TYPE,
- MARKDOWN_TYPE,
-} from './componentTypes';
-
-export default function componentIsResizable(entity) {
- return [
- COLUMN_TYPE,
- CHART_TYPE,
- MARKDOWN_TYPE,
- ].indexOf(entity.type) > -1;
-}
diff --git a/superset/assets/src/explore/components/ExploreChartHeader.jsx b/superset/assets/src/explore/components/ExploreChartHeader.jsx
index 19416b0..3825335 100644
--- a/superset/assets/src/explore/components/ExploreChartHeader.jsx
+++ b/superset/assets/src/explore/components/ExploreChartHeader.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { chartPropShape } from '../../dashboard/v2/util/propShapes';
+import { chartPropShape } from '../../dashboard/util/propShapes';
import ExploreActionButtons from './ExploreActionButtons';
import RowCountLabel from './RowCountLabel';
import EditableTitle from '../../components/EditableTitle';
diff --git a/superset/assets/src/explore/components/ExploreChartPanel.jsx b/superset/assets/src/explore/components/ExploreChartPanel.jsx
index 21c6a64..bcda75d 100644
--- a/superset/assets/src/explore/components/ExploreChartPanel.jsx
+++ b/superset/assets/src/explore/components/ExploreChartPanel.jsx
@@ -3,7 +3,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { Panel } from 'react-bootstrap';
-import { chartPropShape } from '../../dashboard/v2/util/propShapes';
+import { chartPropShape } from '../../dashboard/util/propShapes';
import ChartContainer from '../../chart/ChartContainer';
import ExploreChartHeader from './ExploreChartHeader';
@@ -38,14 +38,15 @@ class ExploreChartPanel extends React.PureComponent {
}
renderChart() {
+ const { chart } = this.props;
return (
<ChartContainer
+ chartId={chart.id}
containerId={this.props.containerId}
datasource={this.props.datasource}
formData={this.props.form_data}
height={this.getHeight()}
slice={this.props.slice}
- chartId={this.props.chart.id}
setControlValue={this.props.actions.setControlValue}
timeout={this.props.timeout}
vizType={this.props.vizType}
@@ -53,6 +54,16 @@ class ExploreChartPanel extends React.PureComponent {
errorMessage={this.props.errorMessage}
onQuery={this.props.onQuery}
onDismissRefreshOverlay={this.props.onDismissRefreshOverlay}
+ annotationData={chart.annotationData}
+ chartAlert={chart.chartAlert}
+ chartStatus={chart.chartStatus}
+ chartUpdateEndTime={chart.chartUpdateEndTime}
+ chartUpdateStartTime={chart.chartUpdateStartTime}
+ latestQueryFormData={chart.latestQueryFormData}
+ lastRendered={chart.lastRendered}
+ queryResponse={chart.queryResponse}
+ queryRequest={chart.queryRequest}
+ triggerQuery={chart.triggerQuery}
/>
);
}
diff --git a/superset/assets/src/explore/components/ExploreViewContainer.jsx b/superset/assets/src/explore/components/ExploreViewContainer.jsx
index 3e761eb..a648464 100644
--- a/superset/assets/src/explore/components/ExploreViewContainer.jsx
+++ b/superset/assets/src/explore/components/ExploreViewContainer.jsx
@@ -11,7 +11,7 @@ import QueryAndSaveBtns from './QueryAndSaveBtns';
import { getExploreUrlAndPayload, getExploreLongUrl } from '../exploreUtils';
import { areObjectsEqual } from '../../reduxUtils';
import { getFormDataFromControls } from '../store';
-import { chartPropShape } from '../../dashboard/v2/util/propShapes';
+import { chartPropShape } from '../../dashboard/util/propShapes';
import * as exploreActions from '../actions/exploreActions';
import * as saveModalActions from '../actions/saveModalActions';
import * as chartActions from '../../chart/chartAction';
diff --git a/superset/assets/stylesheets/dashboard.less b/superset/assets/stylesheets/dashboard.less
deleted file mode 100644
index b812a42..0000000
--- a/superset/assets/stylesheets/dashboard.less
+++ /dev/null
@@ -1,156 +0,0 @@
-@import "./less/cosmo/variables.less";
-
-.dashboard a i {
- cursor: pointer;
-}
-.dashboard i.drag {
- cursor: move !important;
-}
-.dashboard .slice-grid .preview-holder {
- z-index: 1;
- position: absolute;
- background-color: #AAA;
- border-color: #AAA;
- opacity: 0.3;
-}
-.dashboard .widget {
- position: absolute;
- top: 16px;
- left: 16px;
- box-shadow: none;
- background-color: transparent;
- overflow: visible;
-}
-.dashboard .chart-header {
- .dropdown.btn-group {
- position: absolute;
- top: 0;
- right: 0;
- }
-
- .dropdown-menu.dropdown-menu-right {
- right: 7px;
- top: -3px
- }
-}
-
-.slice-header-controls-trigger {
- border: 0;
- padding: 0 0 0 20px;
- background: none;
- outline: none;
- box-shadow: none;
- color: #263238;
-
- &.is-cached {
- color: red;
- }
-
- &:hover, &:focus {
- background: none;
- cursor: pointer;
- }
-
- .controls-container.dropdown-menu {
- top: 0;
- left: unset;
- right: 10px;
-
- &.is-open {
- display: block;
- }
-
- & li {
- white-space: nowrap;
- }
- }
-}
-.slice-grid .slice_container {
- background-color: #fff;
-}
-
-.dashboard .slice-grid .dragging,
-.dashboard .slice-grid .resizing {
- opacity: 0.5;
-}
-.dashboard img.loading {
- width: 20px;
- margin: 5px;
- position: absolute;
-}
-
-.dashboard .slice_title {
- text-align: center;
- font-weight: bold;
- font-size: 14px;
- padding: 5px;
-}
-.dashboard div.slice_content {
- width: 100%;
- height: 100%;
-}
-
-.modal img.loading {
- width: 50px;
- margin: 0;
- position: relative;
-}
-
-.react-bs-container-body {
- max-height: 400px;
- overflow-y: auto;
-}
-
-.hidden, #pageDropDown {
- display: none;
-}
-
-.slice-cell {
- box-shadow: 0px 0px 20px 5px rgba(0,0,0,0);
- transition: box-shadow 1s ease-in;
-
- .dropdown,
- .dropdown-menu {
- .fa {
- font-size: 14px;
- }
- }
-}
-
-.slice-cell-highlight {
- box-shadow: 0px 0px 20px 5px rgba(0,0,0,0.2);
- height: 100%;
-}
-
-.slice-cell .editable-title input[type="button"] {
- font-weight: bold;
-}
-
-.chart-container {
- box-sizing: border-box;
-}
-
-.chart-header .header {
- font-size: 16px;
- margin: 0 -10px;
-}
-.ace_gutter {
- z-index: 0;
-}
-.ace_content {
- z-index: 0;
-}
-.ace_scrollbar {
- z-index: 0;
-}
-.slice_container .alert {
- margin: 10px;
-}
-
-i.danger {
- color: red;
-}
-
-i.warning {
- color: orange;
-}
diff --git a/superset/assets/stylesheets/superset.less b/superset/assets/stylesheets/superset.less
index 6987544..d756551 100644
--- a/superset/assets/stylesheets/superset.less
+++ b/superset/assets/stylesheets/superset.less
@@ -141,7 +141,7 @@ div.navbar {
img.loading {
width: 40px;
position: relative;
- z-index: 10;
+ z-index: 1;
margin: 10px;
}
img.viz-thumb-option {
diff --git a/superset/assets/stylesheets/welcome.css b/superset/assets/stylesheets/welcome.css
index 8e2496e..1f72852 100644
--- a/superset/assets/stylesheets/welcome.css
+++ b/superset/assets/stylesheets/welcome.css
@@ -3,7 +3,7 @@
}
img.loading {
- width: 25px;
+ width: 25px;
}
.welcome table {
diff --git a/superset/assets/yarn.lock b/superset/assets/yarn.lock
index d3efc78..77ca84d 100644
--- a/superset/assets/yarn.lock
+++ b/superset/assets/yarn.lock
@@ -2,27 +2,27 @@
# yarn lockfile v1
-"@data-ui/event-flow@^0.0.54":
- version "0.0.54"
- resolved "https://registry.yarnpkg.com/@data-ui/event-flow/-/event-flow-0.0.54.tgz#bb03e1fd2b5634248655b8df9d3c6c38a747e65e"
- dependencies:
- "@data-ui/forms" "0.0.50"
- "@data-ui/radial-chart" "0.0.54"
- "@data-ui/theme" "0.0.48"
- "@vx/axis" "0.0.140"
- "@vx/bounds" "0.0.140"
- "@vx/clip-path" "0.0.140"
- "@vx/glyph" "0.0.140"
- "@vx/gradient" "0.0.140"
- "@vx/grid" "0.0.140"
- "@vx/group" "0.0.140"
- "@vx/legend" "0.0.140"
- "@vx/pattern" "0.0.140"
- "@vx/point" "0.0.136"
- "@vx/responsive" "0.0.140"
- "@vx/scale" "0.0.140"
- "@vx/shape" "0.0.140"
- "@vx/tooltip" "0.0.140"
+"@data-ui/event-flow@^0.0.8":
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/@data-ui/event-flow/-/event-flow-0.0.8.tgz#237ef225e3085fae9e47bbb1ae11b6fab27eaede"
+ dependencies:
+ "@data-ui/forms" "0.0.4"
+ "@data-ui/radial-chart" "0.0.8"
+ "@data-ui/theme" "0.0.9"
+ "@vx/axis" "0.0.120"
+ "@vx/bounds" "0.0.129"
+ "@vx/clip-path" "0.0.126"
+ "@vx/glyph" "0.0.126"
+ "@vx/gradient" "0.0.120"
+ "@vx/grid" "0.0.120"
+ "@vx/group" "0.0.120"
+ "@vx/legend" "0.0.121"
+ "@vx/pattern" "0.0.120"
+ "@vx/point" "0.0.112"
+ "@vx/responsive" "0.0.120"
+ "@vx/scale" "0.0.121"
+ "@vx/shape" "0.0.120"
+ "@vx/tooltip" "0.0.126"
aphrodite "^1.2.0"
d3-array "^1.2.0"
d3-format "^1.2.0"
@@ -35,29 +35,28 @@
react-with-styles-interface-aphrodite "^1.2.0"
recompose "^0.23.5"
-"@data-ui/forms@0.0.50":
- version "0.0.50"
- resolved "https://registry.yarnpkg.com/@data-ui/forms/-/forms-0.0.50.tgz#c55a699ee4b7cf44ff263d30784299c38d939932"
+"@data-ui/forms@0.0.4":
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/@data-ui/forms/-/forms-0.0.4.tgz#3c1efc55904289e4bffc6536c5f89b3b18f39e4d"
dependencies:
prop-types "^15.5.10"
react-select "^1.0.0-rc.5"
-"@data-ui/radial-chart@0.0.54":
- version "0.0.54"
- resolved "https://registry.yarnpkg.com/@data-ui/radial-chart/-/radial-chart-0.0.54.tgz#0d28b07681d9b6027d9ac23b729241827d513001"
- dependencies:
- "@data-ui/shared" "0.0.54"
- "@data-ui/theme" "0.0.48"
- "@vx/event" "0.0.140"
- "@vx/group" "0.0.140"
- "@vx/scale" "0.0.140"
- "@vx/shape" "0.0.140"
- "@vx/tooltip" "0.0.140"
+"@data-ui/radial-chart@0.0.8":
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/@data-ui/radial-chart/-/radial-chart-0.0.8.tgz#44c0d789a3981c0e9e90f9dbb5e0cbaaafcea09d"
+ dependencies:
+ "@data-ui/theme" "0.0.9"
+ "@vx/event" "0.0.127"
+ "@vx/group" "0.0.127"
+ "@vx/scale" "0.0.127"
+ "@vx/shape" "0.0.131"
+ "@vx/tooltip" "0.0.134"
prop-types "^15.5.10"
-"@data-ui/shared@0.0.54":
- version "0.0.54"
- resolved "https://registry.yarnpkg.com/@data-ui/shared/-/shared-0.0.54.tgz#2fb0d6dee90dac20bf8f3c2913c6850a8223d59b"
+"@data-ui/shared@0.0.49":
+ version "0.0.49"
+ resolved "https://registry.yarnpkg.com/@data-ui/shared/-/shared-0.0.49.tgz#cea1fff1434e54a2dcc2d5f9612300738a466a19"
dependencies:
"@data-ui/theme" "0.0.48"
"@vx/event" "0.0.143"
@@ -67,11 +66,11 @@
d3-array "^1.2.1"
prop-types "^15.5.10"
-"@data-ui/sparkline@^0.0.54":
- version "0.0.54"
- resolved "https://registry.yarnpkg.com/@data-ui/sparkline/-/sparkline-0.0.54.tgz#ce3d166d9e0b239a0ba02f3894cb9e8c84171cef"
+"@data-ui/sparkline@^0.0.49":
+ version "0.0.49"
+ resolved "https://registry.yarnpkg.com/@data-ui/sparkline/-/sparkline-0.0.49.tgz#5ae28769289af7f8a1bffc6b2ac5299f1fb9e846"
dependencies:
- "@data-ui/shared" "0.0.54"
+ "@data-ui/shared" "0.0.49"
"@data-ui/theme" "0.0.8"
"@vx/axis" "0.0.140"
"@vx/curve" "0.0.140"
@@ -95,6 +94,10 @@
version "0.0.8"
resolved "https://registry.yarnpkg.com/@data-ui/theme/-/theme-0.0.8.tgz#3116723d04b99f65c7750f81a500e9608b4837c3"
+"@data-ui/theme@0.0.9":
+ version "0.0.9"
+ resolved "https://registry.yarnpkg.com/@data-ui/theme/-/theme-0.0.9.tgz#a9d66b20d74018009c129eed4326ca4ef3b83127"
+
"@mapbox/geojson-area@0.2.2":
version "0.2.2"
resolved "https://registry.yarnpkg.com/@mapbox/geojson-area/-/geojson-area-0.2.2.tgz#18d7814aa36bf23fbbcc379f8e26a22927debf10"
@@ -105,13 +108,9 @@
version "0.0.1"
resolved "https://registry.yarnpkg.com/@mapbox/gl-matrix/-/gl-matrix-0.0.1.tgz#e5126aab4d64c36b81c7a97d0ae0dddde5773d2b"
-"@mapbox/jsonlint-lines-primitives@^2.0.1":
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.1.tgz#bc4c1593e2ec2371e2771c518068d6eab8eeae58"
-
-"@mapbox/mapbox-gl-supported@^1.3.1":
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.3.1.tgz#81bd3a5e3cfdc40047608656ee9b519e02216bf1"
+"@mapbox/mapbox-gl-supported@^1.3.0":
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.3.0.tgz#89daee16845400ea1c76e084bdfab2971e552a9c"
"@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0":
version "0.1.0"
@@ -135,42 +134,22 @@
dependencies:
"@mapbox/point-geometry" "~0.1.0"
-"@mapbox/vector-tile@^1.3.1":
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz#d3a74c90402d06e89ec66de49ec817ff53409666"
- dependencies:
- "@mapbox/point-geometry" "~0.1.0"
-
"@mapbox/whoots-js@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.0.0.tgz#c1de4293081424da3ac30c23afa850af1019bb54"
-"@mrmlnc/readdir-enhanced@^2.2.1":
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
- dependencies:
- call-me-maybe "^1.0.1"
- glob-to-regexp "^0.3.0"
-
-"@nodelib/fs.stat@^1.0.1":
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.0.tgz#50c1e2260ac0ed9439a181de3725a0168d59c48a"
-
-"@samverschueren/stream-to-observable@^0.3.0":
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
- dependencies:
- any-observable "^0.3.0"
-
-"@sindresorhus/is@^0.7.0":
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
+"@types/react@>=15":
+ version "16.0.12"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-16.0.12.tgz#63f460337e83b24549db744aa2f033121d6d55db"
-"@sinonjs/formatio@^2.0.0":
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2"
+"@vx/axis@0.0.120":
+ version "0.0.120"
+ resolved "https://registry.yarnpkg.com/@vx/axis/-/axis-0.0.120.tgz#5dd5841d03e992990491b20ce918b242f9061d4e"
dependencies:
- samsam "1.3.0"
+ "@vx/group" "0.0.120"
+ "@vx/point" "0.0.112"
+ "@vx/shape" "0.0.120"
+ classnames "^2.2.5"
"@vx/axis@0.0.140":
version "0.0.140"
@@ -182,11 +161,12 @@
classnames "^2.2.5"
prop-types "15.5.10"
-"@vx/bounds@0.0.140":
- version "0.0.140"
- resolved "https://registry.yarnpkg.com/@vx/bounds/-/bounds-0.0.140.tgz#4ede9766aabb41b791a4fbf4c27fcc19ed83f910"
+"@vx/bounds@0.0.129":
+ version "0.0.129"
+ resolved "https://registry.yarnpkg.com/@vx/bounds/-/bounds-0.0.129.tgz#7ecbdfaa3f5041e3f87c851bf4981547e2d19ffe"
dependencies:
prop-types "^15.5.10"
+ react-dom "^15.0.0 || 15.x"
"@vx/bounds@0.0.147":
version "0.0.147"
@@ -194,9 +174,21 @@
dependencies:
prop-types "^15.5.10"
-"@vx/clip-path@0.0.140":
- version "0.0.140"
- resolved "https://registry.yarnpkg.com/@vx/clip-path/-/clip-path-0.0.140.tgz#b2623d004dd5c3c8a6afe8d060de59df51472d94"
+"@vx/clip-path@0.0.126":
+ version "0.0.126"
+ resolved "https://registry.yarnpkg.com/@vx/clip-path/-/clip-path-0.0.126.tgz#58f595dbd5b7fbb27f6a98bac9885a3d701e976e"
+
+"@vx/curve@0.0.112":
+ version "0.0.112"
+ resolved "https://registry.yarnpkg.com/@vx/curve/-/curve-0.0.112.tgz#8e4880a7ae8902bbd5b337ad1b0719bdfb28df3d"
+ dependencies:
+ d3-shape "^1.0.6"
+
+"@vx/curve@0.0.127":
+ version "0.0.127"
+ resolved "https://registry.yarnpkg.com/@vx/curve/-/curve-0.0.127.tgz#f05ea9871a97e1e1d59129b847f216751ffb31c3"
+ dependencies:
+ d3-shape "^1.0.6"
"@vx/curve@0.0.140":
version "0.0.140"
@@ -210,11 +202,11 @@
dependencies:
d3-shape "^1.0.6"
-"@vx/event@0.0.140":
- version "0.0.140"
- resolved "https://registry.yarnpkg.com/@vx/event/-/event-0.0.140.tgz#658ec4de92cd61df40b883296168d4e0824015bf"
+"@vx/event@0.0.127":
+ version "0.0.127"
+ resolved "https://registry.yarnpkg.com/@vx/event/-/event-0.0.127.tgz#8b0079a63cf0aeefd884123dd99ee18efef0af69"
dependencies:
- "@vx/point" "0.0.136"
+ "@vx/point" "0.0.127"
"@vx/event@0.0.143":
version "0.0.143"
@@ -222,6 +214,14 @@
dependencies:
"@vx/point" "0.0.143"
+"@vx/glyph@0.0.126":
+ version "0.0.126"
+ resolved "https://registry.yarnpkg.com/@vx/glyph/-/glyph-0.0.126.tgz#9ebf0924aa15098b6e4b8c44bfbdfbb8c8a2c658"
+ dependencies:
+ "@vx/group" "0.0.126"
+ classnames "^2.2.5"
+ d3-shape "^1.2.0"
+
"@vx/glyph@0.0.140":
version "0.0.140"
resolved "https://registry.yarnpkg.com/@vx/glyph/-/glyph-0.0.140.tgz#f8323f82aee22192b675bef25789bbb7d74691ba"
@@ -230,6 +230,12 @@
classnames "^2.2.5"
d3-shape "^1.2.0"
+"@vx/gradient@0.0.120":
+ version "0.0.120"
+ resolved "https://registry.yarnpkg.com/@vx/gradient/-/gradient-0.0.120.tgz#eeac03390d543bcba354d5d5de169ec5f1945c2d"
+ dependencies:
+ classnames "^2.2.5"
+
"@vx/gradient@0.0.140":
version "0.0.140"
resolved "https://registry.yarnpkg.com/@vx/gradient/-/gradient-0.0.140.tgz#56b421016cbae0dcb00190cfffb9e860a28febf4"
@@ -237,13 +243,31 @@
classnames "^2.2.5"
prop-types "^15.5.7"
-"@vx/grid@0.0.140":
- version "0.0.140"
- resolved "https://registry.yarnpkg.com/@vx/grid/-/grid-0.0.140.tgz#9dfd3071bc5d90d4b457dd55d7f795699233b230"
+"@vx/grid@0.0.120":
+ version "0.0.120"
+ resolved "https://registry.yarnpkg.com/@vx/grid/-/grid-0.0.120.tgz#3471d5cc8a4bef32082ff476ef73fc04db29335e"
+ dependencies:
+ "@vx/group" "0.0.120"
+ "@vx/point" "0.0.112"
+ "@vx/shape" "0.0.120"
+ classnames "^2.2.5"
+
+"@vx/group@0.0.120":
+ version "0.0.120"
+ resolved "https://registry.yarnpkg.com/@vx/group/-/group-0.0.120.tgz#0cc8bc8f40e371585c8c523d98c41cc62684aab9"
+ dependencies:
+ classnames "^2.2.5"
+
+"@vx/group@0.0.126":
+ version "0.0.126"
+ resolved "https://registry.yarnpkg.com/@vx/group/-/group-0.0.126.tgz#5610ce74d0f118db28287806315ae479f313479c"
+ dependencies:
+ classnames "^2.2.5"
+
+"@vx/group@0.0.127":
+ version "0.0.127"
+ resolved "https://registry.yarnpkg.com/@vx/group/-/group-0.0.127.tgz#d607c957119cdb787aa709818532f40e7e04eb8f"
dependencies:
- "@vx/group" "0.0.140"
- "@vx/point" "0.0.136"
- "@vx/shape" "0.0.140"
classnames "^2.2.5"
"@vx/group@0.0.140":
@@ -258,11 +282,18 @@
dependencies:
classnames "^2.2.5"
-"@vx/legend@0.0.140":
- version "0.0.140"
- resolved "https://registry.yarnpkg.com/@vx/legend/-/legend-0.0.140.tgz#4062c27d6bc9c4d607309d77eff12b844727ae99"
+"@vx/legend@0.0.121":
+ version "0.0.121"
+ resolved "https://registry.yarnpkg.com/@vx/legend/-/legend-0.0.121.tgz#0c8cd6860f45af6cbc524ec6526256d2951cca34"
+ dependencies:
+ "@vx/group" "0.0.120"
+ classnames "^2.2.5"
+ prop-types "^15.5.10"
+
+"@vx/pattern@0.0.120":
+ version "0.0.120"
+ resolved "https://registry.yarnpkg.com/@vx/pattern/-/pattern-0.0.120.tgz#cff57b6279c9d6b097a20df3562b8b81c17bdb35"
dependencies:
- "@vx/group" "0.0.140"
classnames "^2.2.5"
prop-types "^15.5.10"
@@ -273,6 +304,14 @@
classnames "^2.2.5"
prop-types "^15.5.10"
+"@vx/point@0.0.112":
+ version "0.0.112"
+ resolved "https://registry.yarnpkg.com/@vx/point/-/point-0.0.112.tgz#cd5b0740268bb432550902ad5e00261bad641cef"
+
+"@vx/point@0.0.127":
+ version "0.0.127"
+ resolved "https://registry.yarnpkg.com/@vx/point/-/point-0.0.127.tgz#51ef7f648488feed758a6ec1cc8c71319602e3e7"
+
"@vx/point@0.0.136":
version "0.0.136"
resolved "https://registry.yarnpkg.com/@vx/point/-/point-0.0.136.tgz#93b325b4b95c9d5b96df740f4204017f57396559"
@@ -281,18 +320,65 @@
version "0.0.143"
resolved "https://registry.yarnpkg.com/@vx/point/-/point-0.0.143.tgz#7b6dfa611175ee1b74e3c392072589a79dadf265"
+"@vx/responsive@0.0.120":
+ version "0.0.120"
+ resolved "https://registry.yarnpkg.com/@vx/responsive/-/responsive-0.0.120.tgz#31c021f213796570787cdd2d2ddb90c4c9444e39"
+ dependencies:
+ lodash "^4.0.8"
+
"@vx/responsive@0.0.140":
version "0.0.140"
resolved "https://registry.yarnpkg.com/@vx/responsive/-/responsive-0.0.140.tgz#c73ec68b9e89a181605f1ac9ecc09f35216779a8"
dependencies:
lodash "^4.0.8"
+"@vx/responsive@0.0.153":
+ version "0.0.153"
+ resolved "https://registry.yarnpkg.com/@vx/responsive/-/responsive-0.0.153.tgz#2ce7e819341d2e59ff4151b40e5792aea460e202"
+ dependencies:
+ lodash "^4.0.8"
+ resize-observer-polyfill "1.5.0"
+
+"@vx/scale@0.0.121":
+ version "0.0.121"
+ resolved "https://registry.yarnpkg.com/@vx/scale/-/scale-0.0.121.tgz#5f49ea2060469ded0bf0e3ef5a5bb1416b81180e"
+ dependencies:
+ d3-scale "^1.0.5"
+
+"@vx/scale@0.0.127":
+ version "0.0.127"
+ resolved "https://registry.yarnpkg.com/@vx/scale/-/scale-0.0.127.tgz#2f81530c89b1ad837be387aaccebedd507f16549"
+ dependencies:
+ d3-scale "^1.0.5"
+
"@vx/scale@0.0.140":
version "0.0.140"
resolved "https://registry.yarnpkg.com/@vx/scale/-/scale-0.0.140.tgz#1eb087d11d0000b250c2cdc4061b9e2212edb10d"
dependencies:
d3-scale "^1.0.5"
+"@vx/shape@0.0.120":
+ version "0.0.120"
+ resolved "https://registry.yarnpkg.com/@vx/shape/-/shape-0.0.120.tgz#53d5457ec58e298bed507baff015fed2507ac741"
+ dependencies:
+ "@vx/curve" "0.0.112"
+ "@vx/group" "0.0.120"
+ "@vx/point" "0.0.112"
+ classnames "^2.2.5"
+ d3-shape "^1.2.0"
+ prop-types "^15.5.10"
+
+"@vx/shape@0.0.131":
+ version "0.0.131"
+ resolved "https://registry.yarnpkg.com/@vx/shape/-/shape-0.0.131.tgz#38585e93319c9f958d317485b0b6520ff295f179"
+ dependencies:
+ "@vx/curve" "0.0.127"
+ "@vx/group" "0.0.127"
+ "@vx/point" "0.0.127"
+ classnames "^2.2.5"
+ d3-shape "^1.2.0"
+ prop-types "^15.5.10"
+
"@vx/shape@0.0.140":
version "0.0.140"
resolved "https://registry.yarnpkg.com/@vx/shape/-/shape-0.0.140.tgz#6a282d5fdf3a5752b6e938bb3debe983e89ff6d3"
@@ -315,11 +401,19 @@
d3-shape "^1.2.0"
prop-types "^15.5.10"
-"@vx/tooltip@0.0.140":
- version "0.0.140"
- resolved "https://registry.yarnpkg.com/@vx/tooltip/-/tooltip-0.0.140.tgz#c5c8306272877c1bbd4e8b478ea5291f1019ffe3"
+"@vx/tooltip@0.0.126":
+ version "0.0.126"
+ resolved "https://registry.yarnpkg.com/@vx/tooltip/-/tooltip-0.0.126.tgz#bcbd48bddf614585b11dff4d5b75ba35a42df68c"
dependencies:
- "@vx/bounds" "0.0.140"
+ classnames "^2.2.5"
+ prop-types "^15.5.10"
+ recompose "^0.23.5"
+
+"@vx/tooltip@0.0.134":
+ version "0.0.134"
+ resolved "https://registry.yarnpkg.com/@vx/tooltip/-/tooltip-0.0.134.tgz#8337f0876a98b3eec8e9636b4694126789eba60c"
+ dependencies:
+ "@vx/bounds" "0.0.129"
classnames "^2.2.5"
prop-types "^15.5.10"
@@ -332,12 +426,16 @@
prop-types "^15.5.10"
JSONStream@^1.3.2:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.3.tgz#27b4b8fbbfeab4e71bcf551e7f27be8d952239bf"
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea"
dependencies:
jsonparse "^1.2.0"
through ">=2.2.7 <3"
+"JSV@>= 4.0.x":
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57"
+
abab@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
@@ -390,26 +488,26 @@ acorn@^5.5.0:
version "5.5.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9"
-agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0:
+agent-base@4, agent-base@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.0.tgz#9838b5c3392b962bad031e6a4c5e1024abec45ce"
dependencies:
es6-promisify "^5.0.0"
-agentkeepalive@^3.3.0, agentkeepalive@^3.4.1:
+agentkeepalive@^3.3.0:
version "3.4.1"
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.4.1.tgz#aa95aebc3a749bca5ed53e3880a09f5235b48f0c"
dependencies:
humanize-ms "^1.2.1"
+ajv-keywords@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.0.tgz#a296e17f7bfae7c1ce4f7e0de53d29cb32162df0"
+
ajv-keywords@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
-ajv-keywords@^3.1.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a"
-
ajv@^4.9.1:
version "4.11.8"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
@@ -417,7 +515,7 @@ ajv@^4.9.1:
co "^4.6.0"
json-stable-stringify "^1.0.1"
-ajv@^5.0.0, ajv@^5.1.0:
+ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5:
version "5.2.3"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.3.tgz#c06f598778c44c6b161abafe3466b81ad1814ed2"
dependencies:
@@ -435,15 +533,6 @@ ajv@^5.2.3, ajv@^5.3.0:
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
-ajv@^6.1.0:
- version "6.5.0"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.0.tgz#4c8affdf80887d8f132c9c52ab8a2dc4d0b7b24c"
- dependencies:
- fast-deep-equal "^2.0.1"
- fast-json-stable-stringify "^2.0.0"
- json-schema-traverse "^0.3.0"
- uri-js "^4.2.1"
-
align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
@@ -466,7 +555,7 @@ ansi-align@^2.0.0:
dependencies:
string-width "^2.0.0"
-ansi-escapes@^1.0.0, ansi-escapes@^1.1.0, ansi-escapes@^1.3.0:
+ansi-escapes@^1.1.0, ansi-escapes@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
@@ -514,10 +603,6 @@ ansistyles@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539"
-any-observable@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b"
-
anymatch@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
@@ -525,13 +610,6 @@ anymatch@^1.3.0:
micromatch "^2.1.5"
normalize-path "^2.0.0"
-anymatch@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
- dependencies:
- micromatch "^3.1.4"
- normalize-path "^2.1.1"
-
aphrodite@^1.2.0:
version "1.2.4"
resolved "https://registry.yarnpkg.com/aphrodite/-/aphrodite-1.2.4.tgz#5dc1622aa6f1b02c775e1f1ed850df08839e203c"
@@ -594,22 +672,10 @@ arr-diff@^2.0.0:
dependencies:
arr-flatten "^1.0.1"
-arr-diff@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
-
-arr-flatten@^1.0.1, arr-flatten@^1.1.0:
+arr-flatten@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
-arr-union@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
-
-array-differ@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031"
-
array-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
@@ -646,15 +712,11 @@ array-unique@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
-array-unique@^0.3.2:
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
-
-arrify@^1.0.0, arrify@^1.0.1:
+arrify@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
-asap@^2.0.0, asap@^2.0.3, asap@~2.0.3, asap@~2.0.5:
+asap@^2.0.0, asap@^2.0.3, asap@^2.0.6, asap@~2.0.3, asap@~2.0.5:
version "2.0.6"
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
@@ -696,37 +758,19 @@ assertion-error@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c"
-assign-symbols@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
-
ast-types-flow@0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
-ast-types@0.10.1:
- version "0.10.1"
- resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.10.1.tgz#f52fca9715579a14f841d67d7f8d25432ab6a3dd"
-
-ast-types@0.11.3:
- version "0.11.3"
- resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.3.tgz#c20757fe72ee71278ea0ff3d87e5c2ca30d9edf8"
-
async-each@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
-async@1.x, async@^1.4.0, async@^1.5.0, async@~1.5:
+async@1.x, async@^1.4.0, async@~1.5:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
-async@^2.1.2, async@^2.6.0:
- version "2.6.1"
- resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
- dependencies:
- lodash "^4.17.10"
-
-async@^2.1.4, async@^2.4.1:
+async@^2.1.2, async@^2.1.4, async@^2.4.1:
version "2.5.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d"
dependencies:
@@ -744,10 +788,6 @@ asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
-atob@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a"
-
autoprefixer@^6.3.1:
version "6.7.7"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014"
@@ -847,14 +887,6 @@ babel-generator@^6.18.0, babel-generator@^6.26.0:
source-map "^0.5.6"
trim-right "^1.0.1"
-babel-helper-bindify-decorators@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330"
- dependencies:
- babel-runtime "^6.22.0"
- babel-traverse "^6.24.1"
- babel-types "^6.24.1"
-
babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664"
@@ -897,15 +929,6 @@ babel-helper-explode-assignable-expression@^6.24.1:
babel-traverse "^6.24.1"
babel-types "^6.24.1"
-babel-helper-explode-class@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb"
- dependencies:
- babel-helper-bindify-decorators "^6.24.1"
- babel-runtime "^6.22.0"
- babel-traverse "^6.24.1"
- babel-types "^6.24.1"
-
babel-helper-function-name@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
@@ -1025,34 +1048,10 @@ babel-plugin-syntax-async-functions@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
-babel-plugin-syntax-async-generators@^6.5.0:
- version "6.13.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a"
-
-babel-plugin-syntax-class-constructor-call@^6.18.0:
- version "6.18.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416"
-
-babel-plugin-syntax-class-properties@^6.8.0:
- version "6.13.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
-
-babel-plugin-syntax-decorators@^6.13.0:
- version "6.13.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b"
-
-babel-plugin-syntax-dynamic-import@^6.18.0:
- version "6.18.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da"
-
babel-plugin-syntax-exponentiation-operator@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de"
-babel-plugin-syntax-export-extensions@^6.8.0:
- version "6.13.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721"
-
babel-plugin-syntax-flow@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"
@@ -1069,15 +1068,7 @@ babel-plugin-syntax-trailing-function-commas@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3"
-babel-plugin-transform-async-generator-functions@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db"
- dependencies:
- babel-helper-remap-async-to-generator "^6.24.1"
- babel-plugin-syntax-async-generators "^6.5.0"
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1:
+babel-plugin-transform-async-to-generator@^6.22.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761"
dependencies:
@@ -1085,33 +1076,6 @@ babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-
babel-plugin-syntax-async-functions "^6.8.0"
babel-runtime "^6.22.0"
-babel-plugin-transform-class-constructor-call@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz#80dc285505ac067dcb8d6c65e2f6f11ab7765ef9"
- dependencies:
- babel-plugin-syntax-class-constructor-call "^6.18.0"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
-
-babel-plugin-transform-class-properties@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac"
- dependencies:
- babel-helper-function-name "^6.24.1"
- babel-plugin-syntax-class-properties "^6.8.0"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
-
-babel-plugin-transform-decorators@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d"
- dependencies:
- babel-helper-explode-class "^6.24.1"
- babel-plugin-syntax-decorators "^6.13.0"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
- babel-types "^6.24.1"
-
babel-plugin-transform-es2015-arrow-functions@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221"
@@ -1124,7 +1088,7 @@ babel-plugin-transform-es2015-block-scoped-functions@^6.22.0:
dependencies:
babel-runtime "^6.22.0"
-babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es2015-block-scoping@^6.24.1:
+babel-plugin-transform-es2015-block-scoping@^6.23.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f"
dependencies:
@@ -1134,7 +1098,7 @@ babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es20
babel-types "^6.26.0"
lodash "^4.17.4"
-babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-classes@^6.24.1:
+babel-plugin-transform-es2015-classes@^6.23.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db"
dependencies:
@@ -1148,33 +1112,33 @@ babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-cla
babel-traverse "^6.24.1"
babel-types "^6.24.1"
-babel-plugin-transform-es2015-computed-properties@^6.22.0, babel-plugin-transform-es2015-computed-properties@^6.24.1:
+babel-plugin-transform-es2015-computed-properties@^6.22.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3"
dependencies:
babel-runtime "^6.22.0"
babel-template "^6.24.1"
-babel-plugin-transform-es2015-destructuring@^6.22.0, babel-plugin-transform-es2015-destructuring@^6.23.0:
+babel-plugin-transform-es2015-destructuring@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d"
dependencies:
babel-runtime "^6.22.0"
-babel-plugin-transform-es2015-duplicate-keys@^6.22.0, babel-plugin-transform-es2015-duplicate-keys@^6.24.1:
+babel-plugin-transform-es2015-duplicate-keys@^6.22.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e"
dependencies:
babel-runtime "^6.22.0"
babel-types "^6.24.1"
-babel-plugin-transform-es2015-for-of@^6.22.0, babel-plugin-transform-es2015-for-of@^6.23.0:
+babel-plugin-transform-es2015-for-of@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691"
dependencies:
babel-runtime "^6.22.0"
-babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.24.1:
+babel-plugin-transform-es2015-function-name@^6.22.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b"
dependencies:
@@ -1205,7 +1169,7 @@ babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-e
babel-template "^6.26.0"
babel-types "^6.26.0"
-babel-plugin-transform-es2015-modules-systemjs@^6.23.0, babel-plugin-transform-es2015-modules-systemjs@^6.24.1:
+babel-plugin-transform-es2015-modules-systemjs@^6.23.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23"
dependencies:
@@ -1213,7 +1177,7 @@ babel-plugin-transform-es2015-modules-systemjs@^6.23.0, babel-plugin-transform-e
babel-runtime "^6.22.0"
babel-template "^6.24.1"
-babel-plugin-transform-es2015-modules-umd@^6.23.0, babel-plugin-transform-es2015-modules-umd@^6.24.1:
+babel-plugin-transform-es2015-modules-umd@^6.23.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468"
dependencies:
@@ -1221,14 +1185,14 @@ babel-plugin-transform-es2015-modules-umd@^6.23.0, babel-plugin-transform-es2015
babel-runtime "^6.22.0"
babel-template "^6.24.1"
-babel-plugin-transform-es2015-object-super@^6.22.0, babel-plugin-transform-es2015-object-super@^6.24.1:
+babel-plugin-transform-es2015-object-super@^6.22.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d"
dependencies:
babel-helper-replace-supers "^6.24.1"
babel-runtime "^6.22.0"
-babel-plugin-transform-es2015-parameters@^6.23.0, babel-plugin-transform-es2015-parameters@^6.24.1:
+babel-plugin-transform-es2015-parameters@^6.23.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b"
dependencies:
@@ -1239,7 +1203,7 @@ babel-plugin-transform-es2015-parameters@^6.23.0, babel-plugin-transform-es2015-
babel-traverse "^6.24.1"
babel-types "^6.24.1"
-babel-plugin-transform-es2015-shorthand-properties@^6.22.0, babel-plugin-transform-es2015-shorthand-properties@^6.24.1:
+babel-plugin-transform-es2015-shorthand-properties@^6.22.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0"
dependencies:
@@ -1252,7 +1216,7 @@ babel-plugin-transform-es2015-spread@^6.22.0:
dependencies:
babel-runtime "^6.22.0"
-babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es2015-sticky-regex@^6.24.1:
+babel-plugin-transform-es2015-sticky-regex@^6.22.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc"
dependencies:
@@ -1266,13 +1230,13 @@ babel-plugin-transform-es2015-template-literals@^6.22.0:
dependencies:
babel-runtime "^6.22.0"
-babel-plugin-transform-es2015-typeof-symbol@^6.22.0, babel-plugin-transform-es2015-typeof-symbol@^6.23.0:
+babel-plugin-transform-es2015-typeof-symbol@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372"
dependencies:
babel-runtime "^6.22.0"
-babel-plugin-transform-es2015-unicode-regex@^6.22.0, babel-plugin-transform-es2015-unicode-regex@^6.24.1:
+babel-plugin-transform-es2015-unicode-regex@^6.22.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9"
dependencies:
@@ -1300,14 +1264,7 @@ babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-e
babel-plugin-syntax-exponentiation-operator "^6.8.0"
babel-runtime "^6.22.0"
-babel-plugin-transform-export-extensions@^6.22.0:
- version "6.22.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz#53738b47e75e8218589eea946cbbd39109bbe653"
- dependencies:
- babel-plugin-syntax-export-extensions "^6.8.0"
- babel-runtime "^6.22.0"
-
-babel-plugin-transform-flow-strip-types@^6.22.0, babel-plugin-transform-flow-strip-types@^6.8.0:
+babel-plugin-transform-flow-strip-types@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf"
dependencies:
@@ -1320,7 +1277,7 @@ babel-plugin-transform-jscript@^6.22.0:
dependencies:
babel-runtime "^6.22.0"
-babel-plugin-transform-object-rest-spread@^6.22.0, babel-plugin-transform-object-rest-spread@^6.23.0:
+babel-plugin-transform-object-rest-spread@^6.23.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06"
dependencies:
@@ -1355,7 +1312,7 @@ babel-plugin-transform-react-jsx@^6.24.1:
babel-plugin-syntax-jsx "^6.8.0"
babel-runtime "^6.22.0"
-babel-plugin-transform-regenerator@^6.22.0, babel-plugin-transform-regenerator@^6.24.1:
+babel-plugin-transform-regenerator@^6.22.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f"
dependencies:
@@ -1427,35 +1384,6 @@ babel-preset-env@^1.5.2:
invariant "^2.2.2"
semver "^5.3.0"
-babel-preset-es2015@^6.9.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939"
- dependencies:
- babel-plugin-check-es2015-constants "^6.22.0"
- babel-plugin-transform-es2015-arrow-functions "^6.22.0"
- babel-plugin-transform-es2015-block-scoped-functions "^6.22.0"
- babel-plugin-transform-es2015-block-scoping "^6.24.1"
- babel-plugin-transform-es2015-classes "^6.24.1"
- babel-plugin-transform-es2015-computed-properties "^6.24.1"
- babel-plugin-transform-es2015-destructuring "^6.22.0"
- babel-plugin-transform-es2015-duplicate-keys "^6.24.1"
- babel-plugin-transform-es2015-for-of "^6.22.0"
- babel-plugin-transform-es2015-function-name "^6.24.1"
- babel-plugin-transform-es2015-literals "^6.22.0"
- babel-plugin-transform-es2015-modules-amd "^6.24.1"
- babel-plugin-transform-es2015-modules-commonjs "^6.24.1"
- babel-plugin-transform-es2015-modules-systemjs "^6.24.1"
- babel-plugin-transform-es2015-modules-umd "^6.24.1"
- babel-plugin-transform-es2015-object-super "^6.24.1"
- babel-plugin-transform-es2015-parameters "^6.24.1"
- babel-plugin-transform-es2015-shorthand-properties "^6.24.1"
- babel-plugin-transform-es2015-spread "^6.22.0"
- babel-plugin-transform-es2015-sticky-regex "^6.24.1"
- babel-plugin-transform-es2015-template-literals "^6.22.0"
- babel-plugin-transform-es2015-typeof-symbol "^6.22.0"
- babel-plugin-transform-es2015-unicode-regex "^6.24.1"
- babel-plugin-transform-regenerator "^6.24.1"
-
babel-preset-flow@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d"
@@ -1473,34 +1401,7 @@ babel-preset-react@^6.24.1:
babel-plugin-transform-react-jsx-source "^6.22.0"
babel-preset-flow "^6.23.0"
-babel-preset-stage-1@^6.5.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz#7692cd7dcd6849907e6ae4a0a85589cfb9e2bfb0"
- dependencies:
- babel-plugin-transform-class-constructor-call "^6.24.1"
- babel-plugin-transform-export-extensions "^6.22.0"
- babel-preset-stage-2 "^6.24.1"
-
-babel-preset-stage-2@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1"
- dependencies:
- babel-plugin-syntax-dynamic-import "^6.18.0"
- babel-plugin-transform-class-properties "^6.24.1"
- babel-plugin-transform-decorators "^6.24.1"
- babel-preset-stage-3 "^6.24.1"
-
-babel-preset-stage-3@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395"
- dependencies:
- babel-plugin-syntax-trailing-function-commas "^6.22.0"
- babel-plugin-transform-async-generator-functions "^6.24.1"
- babel-plugin-transform-async-to-generator "^6.24.1"
- babel-plugin-transform-exponentiation-operator "^6.24.1"
- babel-plugin-transform-object-rest-spread "^6.22.0"
-
-babel-register@^6.24.1, babel-register@^6.26.0, babel-register@^6.9.0:
+babel-register@^6.24.1, babel-register@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
dependencies:
@@ -1552,14 +1453,10 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26
lodash "^4.17.4"
to-fast-properties "^1.0.3"
-babylon@^6.15.0, babylon@^6.17.3, babylon@^6.18.0:
+babylon@^6.15.0, babylon@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
-babylon@^7.0.0-beta.30:
- version "7.0.0-beta.47"
- resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.47.tgz#6d1fa44f0abec41ab7c780481e62fd9aafbdea80"
-
balanced-match@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
@@ -1576,18 +1473,6 @@ base64-js@^1.0.2:
version "1.2.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886"
-base@^0.11.1:
- version "0.11.2"
- resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
- dependencies:
- cache-base "^1.0.1"
- class-utils "^0.3.5"
- component-emitter "^1.2.1"
- define-property "^1.0.0"
- isobject "^3.0.1"
- mixin-deep "^1.2.0"
- pascalcase "^0.1.1"
-
bcrypt-pbkdf@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
@@ -1598,7 +1483,7 @@ big.js@^3.1.3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
-bin-links@^1.1.2:
+bin-links@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.2.tgz#fb74bd54bae6b7befc6c6221f25322ac830d9757"
dependencies:
@@ -1612,10 +1497,6 @@ binary-extensions@^1.0.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.10.0.tgz#9aeb9a6c5e88638aad171e167f5900abe24835d0"
-binaryextensions@2:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935"
-
bl@~0.9.4:
version "0.9.5"
resolved "https://registry.yarnpkg.com/bl/-/bl-0.9.5.tgz#c06b797af085ea00bc527afc8efcf11de2232054"
@@ -1674,15 +1555,15 @@ boom@5.x.x:
dependencies:
hoek "4.x.x"
-bootstrap-slider@9.9.0:
- version "9.9.0"
- resolved "https://registry.yarnpkg.com/bootstrap-slider/-/bootstrap-slider-9.9.0.tgz#4e14ecc6401901da1ddf7681aa24e33b00dadce8"
-
bootstrap-slider@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/bootstrap-slider/-/bootstrap-slider-10.0.0.tgz#d4edd3a10af03197d020e3792d32ea6d37cb3b28"
-bootstrap@^3.3.6:
+bootstrap-slider@^9.8.0:
+ version "9.10.0"
+ resolved "https://registry.yarnpkg.com/bootstrap-slider/-/bootstrap-slider-9.10.0.tgz#1103d6bc00cfbfa8cfc9a2599ab518c55643da3f"
+
+bootstrap@^3.3.6, bootstrap@^3.3.7:
version "3.3.7"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-3.3.7.tgz#5a389394549f23330875a3b150656574f8a9eb71"
@@ -1740,10 +1621,6 @@ brace@^0.10.0:
dependencies:
w3c-blob "0.0.1"
-brace@^0.11.1:
- version "0.11.1"
- resolved "https://registry.yarnpkg.com/brace/-/brace-0.11.1.tgz#4896fcc9d544eef45f4bb7660db320d3b379fe58"
-
braces@^1.8.2:
version "1.8.5"
resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
@@ -1752,21 +1629,6 @@ braces@^1.8.2:
preserve "^0.2.0"
repeat-element "^1.1.2"
-braces@^2.3.0, braces@^2.3.1:
- version "2.3.2"
- resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
- dependencies:
- arr-flatten "^1.1.0"
- array-unique "^0.3.2"
- extend-shallow "^2.0.1"
- fill-range "^4.0.0"
- isobject "^3.0.1"
- repeat-element "^1.1.2"
- snapdragon "^0.8.1"
- snapdragon-node "^2.0.1"
- split-string "^3.0.2"
- to-regex "^3.0.1"
-
brcast@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/brcast/-/brcast-2.0.2.tgz#2db16de44140e418dc37fab10beec0369e78dcef"
@@ -1780,15 +1642,6 @@ brfs@^1.3.0, brfs@^1.4.0, brfs@^1.4.3:
static-module "^1.1.0"
through2 "^2.0.0"
-brfs@^1.4.4:
- version "1.6.1"
- resolved "https://registry.yarnpkg.com/brfs/-/brfs-1.6.1.tgz#b78ce2336d818e25eea04a0947cba6d4fb8849c3"
- dependencies:
- quote-stream "^1.0.1"
- resolve "^1.1.5"
- static-module "^2.2.0"
- through2 "^2.0.0"
-
brorand@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
@@ -1930,10 +1783,6 @@ byline@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
-byte-size@^4.0.3:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.3.tgz#b7c095efc68eadf82985fccd9a2df43a74fa2ccd"
-
cacache@^10.0.0, cacache@^10.0.4:
version "10.0.4"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460"
@@ -1970,51 +1819,6 @@ cacache@^10.0.1:
unique-filename "^1.1.0"
y18n "^3.2.1"
-cacache@^11.0.1, cacache@^11.0.2:
- version "11.0.2"
- resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.0.2.tgz#ff30541a05302200108a759e660e30786f788764"
- dependencies:
- bluebird "^3.5.1"
- chownr "^1.0.1"
- figgy-pudding "^3.1.0"
- glob "^7.1.2"
- graceful-fs "^4.1.11"
- lru-cache "^4.1.2"
- mississippi "^3.0.0"
- mkdirp "^0.5.1"
- move-concurrently "^1.0.1"
- promise-inflight "^1.0.1"
- rimraf "^2.6.2"
- ssri "^6.0.0"
- unique-filename "^1.1.0"
- y18n "^4.0.0"
-
-cache-base@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
- dependencies:
- collection-visit "^1.0.0"
- component-emitter "^1.2.1"
- get-value "^2.0.6"
- has-value "^1.0.0"
- isobject "^3.0.1"
- set-value "^2.0.0"
- to-object-path "^0.3.0"
- union-value "^1.0.0"
- unset-value "^1.0.0"
-
-cacheable-request@^2.1.1:
- version "2.1.4"
- resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d"
- dependencies:
- clone-response "1.0.2"
- get-stream "3.0.0"
- http-cache-semantics "3.8.1"
- keyv "3.0.0"
- lowercase-keys "1.0.0"
- normalize-url "2.0.1"
- responselike "1.0.2"
-
call-limit@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.0.tgz#6fd61b03f3da42a2cd0ec2b60f02bd0e71991fea"
@@ -2028,10 +1832,6 @@ call-matcher@^1.0.1:
espurify "^1.6.0"
estraverse "^4.0.0"
-call-me-maybe@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
-
caller-path@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
@@ -2138,14 +1938,6 @@ chalk@^2.1.0:
escape-string-regexp "^1.0.5"
supports-color "^4.0.0"
-chalk@^2.3.0, chalk@^2.4.1:
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
- dependencies:
- ansi-styles "^3.2.1"
- escape-string-regexp "^1.0.5"
- supports-color "^5.3.0"
-
chalk@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
@@ -2191,7 +1983,7 @@ cheerio@^0.22.0:
lodash.reject "^4.4.0"
lodash.some "^4.4.0"
-chokidar@^1.6.1:
+chokidar@^1.6.1, chokidar@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
dependencies:
@@ -2206,24 +1998,6 @@ chokidar@^1.6.1:
optionalDependencies:
fsevents "^1.0.0"
-chokidar@^2.0.2:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.3.tgz#dcbd4f6cbb2a55b4799ba8a840ac527e5f4b1176"
- dependencies:
- anymatch "^2.0.0"
- async-each "^1.0.0"
- braces "^2.3.0"
- glob-parent "^3.1.0"
- inherits "^2.0.1"
- is-binary-path "^1.0.0"
- is-glob "^4.0.0"
- normalize-path "^2.1.1"
- path-is-absolute "^1.0.0"
- readdirp "^2.0.0"
- upath "^1.0.0"
- optionalDependencies:
- fsevents "^1.1.2"
-
chownr@^1.0.1, chownr@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
@@ -2232,11 +2006,9 @@ ci-info@^1.0.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.3.tgz#710193264bb05c77b8c90d02f5aaf22216a667b2"
-cidr-regex@^2.0.8:
- version "2.0.8"
- resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-2.0.8.tgz#c79bae6223d241c0860d93bfde1fb1c1c4fdcab6"
- dependencies:
- ip-regex "^2.1.0"
+cidr-regex@1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-1.0.6.tgz#74abfd619df370b9d54ab14475568e97dd64c0c1"
cint@^8.2.1:
version "8.2.1"
@@ -2259,16 +2031,7 @@ clap@^1.0.9:
dependencies:
chalk "^1.1.3"
-class-utils@^0.3.5:
- version "0.3.6"
- resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
- dependencies:
- arr-union "^3.1.0"
- define-property "^0.2.5"
- isobject "^3.0.0"
- static-extend "^0.1.1"
-
-classnames@2.x, classnames@^2.1.2, classnames@^2.2.3, classnames@^2.2.4, classnames@^2.2.5:
+classnames@^2.2.3, classnames@^2.2.4, classnames@^2.2.5:
version "2.2.5"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
@@ -2280,16 +2043,9 @@ clean-webpack-plugin@^0.1.16:
cli-boxes@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
-
-cli-columns@^3.1.2:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/cli-columns/-/cli-columns-3.1.2.tgz#6732d972979efc2ae444a1f08e08fa139c96a18e"
- dependencies:
- string-width "^2.0.0"
- strip-ansi "^3.0.1"
+ resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
-cli-cursor@^1.0.1, cli-cursor@^1.0.2:
+cli-cursor@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
dependencies:
@@ -2301,11 +2057,7 @@ cli-cursor@^2.1.0:
dependencies:
restore-cursor "^2.0.0"
-cli-spinners@^0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c"
-
-cli-table2@^0.2.0, cli-table2@~0.2.0:
+cli-table2@~0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/cli-table2/-/cli-table2-0.2.0.tgz#2d1ef7f218a0e786e214540562d4bd177fe32d97"
dependencies:
@@ -2320,25 +2072,10 @@ cli-table@^0.3.1:
dependencies:
colors "1.0.3"
-cli-truncate@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
- dependencies:
- slice-ansi "0.0.4"
- string-width "^1.0.1"
-
cli-width@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
-clipboard@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.1.tgz#a12481e1c13d8a50f5f036b0560fe5d16d74e46a"
- dependencies:
- good-listener "^1.2.2"
- select "^1.1.2"
- tiny-emitter "^2.0.0"
-
clite@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/clite/-/clite-0.3.0.tgz#e7fcbc8cc5bd3e7f8b84ed48db12e9474cc73441"
@@ -2370,17 +2107,13 @@ cliui@^3.2.0:
wrap-ansi "^2.0.0"
cliui@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc"
dependencies:
string-width "^2.1.1"
strip-ansi "^4.0.0"
wrap-ansi "^2.0.0"
-clone-buffer@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58"
-
clone-deep@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.3.0.tgz#348c61ae9cdbe0edfe053d91ff4cc521d790ede8"
@@ -2390,24 +2123,6 @@ clone-deep@^0.3.0:
kind-of "^3.2.2"
shallow-clone "^0.1.2"
-clone-response@1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
- dependencies:
- mimic-response "^1.0.0"
-
-clone-stats@^0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1"
-
-clone-stats@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680"
-
-clone@^1.0.0:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
-
clone@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149"
@@ -2416,14 +2131,6 @@ clone@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb"
-cloneable-readable@^1.0.0:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65"
- dependencies:
- inherits "^2.0.1"
- process-nextick-args "^2.0.0"
- readable-stream "^2.3.5"
-
cmd-shim@^2.0.2, cmd-shim@~2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb"
@@ -2445,13 +2152,6 @@ code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
-collection-visit@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
- dependencies:
- map-visit "^1.0.0"
- object-visit "^1.0.0"
-
color-convert@^1.3.0, color-convert@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
@@ -2493,8 +2193,8 @@ colors@1.0.3:
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
colors@^1.1.2:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.0.tgz#5f20c9fef6945cb1134260aab33bfbdc8295e04e"
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.1.tgz#f4a3d302976aaf042356ba1ade3b1a2c62d9d794"
colors@~1.1.2:
version "1.1.2"
@@ -2519,12 +2219,6 @@ combined-stream@~0.0.4:
dependencies:
delayed-stream "0.0.5"
-comma-separated-tokens@^1.0.0:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.5.tgz#b13793131d9ea2d2431cf5b507ddec258f0ce0db"
- dependencies:
- trim "0.0.1"
-
commander@2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
@@ -2547,10 +2241,6 @@ complex.js@2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.4.tgz#d8e7cfb9652d1e853e723386421c1a0ca7a48373"
-component-emitter@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
-
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@@ -2629,7 +2319,7 @@ console-browserify@^1.1.0:
dependencies:
date-now "^0.1.4"
-console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0:
+console-control-strings@^1.0.0, console-control-strings@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
@@ -2649,10 +2339,6 @@ convert-source-map@^1.1.1, convert-source-map@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
-convert-source-map@^1.5.1:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5"
-
cookie-jar@~0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/cookie-jar/-/cookie-jar-0.3.0.tgz#bc9a27d4e2b97e186cd57c9e2063cb99fa68cccc"
@@ -2668,10 +2354,6 @@ copy-concurrently@^1.0.0:
rimraf "^2.5.4"
run-queue "^1.0.0"
-copy-descriptor@^0.1.0:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
-
core-js@^1.0.0:
version "1.2.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
@@ -2680,10 +2362,6 @@ core-js@^2.0.0, core-js@^2.4.0, core-js@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
-core-js@^2.4.1:
- version "2.5.7"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
-
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -2721,7 +2399,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
-create-react-class@^15.5.2, create-react-class@^15.6.0:
+create-react-class@^15.5.2, create-react-class@^15.5.x, create-react-class@^15.6.0:
version "15.6.2"
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.2.tgz#cf1ed15f12aad7f14ef5f2dfe05e6c42f91ef02a"
dependencies:
@@ -2737,16 +2415,6 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0:
shebang-command "^1.2.0"
which "^1.2.9"
-cross-spawn@^6.0.5:
- version "6.0.5"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
- dependencies:
- nice-try "^1.0.4"
- path-key "^2.0.1"
- semver "^5.5.0"
- shebang-command "^1.2.0"
- which "^1.2.9"
-
crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
@@ -2935,7 +2603,7 @@ d3-cloud@^1.2.1:
dependencies:
d3-dispatch "1"
-d3-collection@1, d3-collection@^1.0.4:
+d3-collection@1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.4.tgz#342dfd12837c90974f33f1cc0a785aea570dcdc2"
@@ -3018,10 +2686,6 @@ d3-selection@1, d3-selection@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.1.0.tgz#1998684896488f839ca0372123da34f1d318809c"
-d3-selection@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.0.tgz#d53772382d3dc4f7507bfb28bcd2d6aed2a0ad6d"
-
d3-shape@^1.0.6, d3-shape@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.0.tgz#45d01538f064bafd05ea3d6d2cb748fd8c41f777"
@@ -3046,12 +2710,11 @@ d3-timer@1:
version "1.0.7"
resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.7.tgz#df9650ca587f6c96607ff4e60cc38229e8dd8531"
-d3-tip@^0.9.1:
- version "0.9.1"
- resolved "https://registry.yarnpkg.com/d3-tip/-/d3-tip-0.9.1.tgz#84e6d331c4e6650d80c5228a07e41820609ab64b"
+d3-tip@^0.6.7:
+ version "0.6.8"
+ resolved "https://registry.yarnpkg.com/d3-tip/-/d3-tip-0.6.8.tgz#e5b4491ae8983fde646ea49008ff542a033c0a2c"
dependencies:
- d3-collection "^1.0.4"
- d3-selection "^1.3.0"
+ d3 "^3.5.5"
d3-transition@1:
version "1.1.0"
@@ -3074,7 +2737,7 @@ d3-zoom@^1.3.0:
d3-selection "1"
d3-transition "1"
-d3@3, d3@^3.5.17, d3@^3.5.6:
+d3@3, d3@^3.5.17, d3@^3.5.5, d3@^3.5.6:
version "3.5.17"
resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8"
@@ -3088,10 +2751,6 @@ damerau-levenshtein@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514"
-dargs@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/dargs/-/dargs-5.1.0.tgz#ec7ea50c78564cd36c9d5ec18f66329fade27829"
-
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@@ -3118,18 +2777,10 @@ datatables.net@1.10.16:
dependencies:
jquery ">=1.7"
-date-fns@^1.27.2:
- version "1.29.0"
- resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6"
-
date-now@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
-dateformat@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
-
debug@2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
@@ -3142,7 +2793,7 @@ debug@3.1.0, debug@^3.1.0:
dependencies:
ms "2.0.0"
-debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.3, debug@^2.6.8:
+debug@^2.1.2, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
@@ -3178,12 +2829,6 @@ decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
-decompress-response@^3.2.0, decompress-response@^3.3.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
- dependencies:
- mimic-response "^1.0.0"
-
deep-eql@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
@@ -3194,10 +2839,6 @@ deep-equal@^1.0.0, deep-equal@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
-deep-extend@^0.5.1:
- version "0.5.1"
- resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.1.tgz#b894a9dd90d3023fbf1c55a394fb858eb2066f1f"
-
deep-extend@~0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
@@ -3229,25 +2870,6 @@ define-properties@^1.1.2:
foreach "^2.0.5"
object-keys "^1.0.8"
-define-property@^0.2.5:
- version "0.2.5"
- resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116"
- dependencies:
- is-descriptor "^0.1.0"
-
-define-property@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6"
- dependencies:
- is-descriptor "^1.0.0"
-
-define-property@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d"
- dependencies:
- is-descriptor "^1.0.2"
- isobject "^3.0.1"
-
defined@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
@@ -3272,10 +2894,6 @@ delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
-delegate@^3.1.2:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
-
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
@@ -3287,10 +2905,6 @@ des.js@^1.0.0:
inherits "^2.0.1"
minimalistic-assert "^1.0.0"
-detect-conflict@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/detect-conflict/-/detect-conflict-1.0.1.tgz#088657a66a961c05019db7c4230883b1c6b4176e"
-
detect-indent@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
@@ -3301,10 +2915,6 @@ detect-indent@~5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
-detect-libc@^1.0.2:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
-
detect-newline@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
@@ -3320,9 +2930,9 @@ diff@3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
-diff@^3.1.0, diff@^3.3.1, diff@^3.5.0:
- version "3.5.0"
- resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
+diff@^3.1.0:
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75"
diffie-hellman@^5.0.0:
version "5.0.2"
@@ -3332,12 +2942,9 @@ diffie-hellman@^5.0.0:
miller-rabin "^4.0.0"
randombytes "^2.0.0"
-dir-glob@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034"
- dependencies:
- arrify "^1.0.1"
- path-type "^3.0.0"
+disposables@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/disposables/-/disposables-1.0.2.tgz#36c6a674475f55a2d6913567a601444e487b4b6e"
distributions@^1.0.0:
version "1.0.0"
@@ -3345,6 +2952,15 @@ distributions@^1.0.0:
dependencies:
mathfn "^1.0.0"
+dnd-core@^2.6.0:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/dnd-core/-/dnd-core-2.6.0.tgz#12bad66d58742c6e5f7cf2943fb6859440f809c4"
+ dependencies:
+ asap "^2.0.6"
+ invariant "^2.0.0"
+ lodash "^4.2.0"
+ redux "^3.7.1"
+
doctrine@1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
@@ -3428,7 +3044,7 @@ dotenv@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef"
-duplexer2@^0.1.4, duplexer2@~0.1.4:
+duplexer2@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
dependencies:
@@ -3476,26 +3092,14 @@ ecc-jsbn@~0.1.1:
dependencies:
jsbn "~0.1.0"
-editions@^1.3.3:
- version "1.3.4"
- resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b"
-
editor@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742"
-ejs@^2.5.9:
- version "2.6.1"
- resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
-
electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.18:
version "1.3.24"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz#9b7b88bb05ceb9fa016a177833cc2dde388f21b6"
-elegant-spinner@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
-
elliptic@^6.0.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df"
@@ -3541,22 +3145,10 @@ enhanced-resolve@^3.4.0:
object-assign "^4.0.1"
tapable "^0.2.7"
-enhanced-resolve@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz#e34a6eaa790f62fccd71d93959f56b2b432db10a"
- dependencies:
- graceful-fs "^4.1.2"
- memory-fs "^0.4.0"
- tapable "^1.0.0"
-
entities@^1.1.1, entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
-envinfo@^5.7.0:
- version "5.9.0"
- resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.9.0.tgz#1e681b7400c384c679ffc886b6e3f811d7e687b5"
-
enzyme@^2.0.0:
version "2.9.1"
resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-2.9.1.tgz#07d5ce691241240fb817bf2c4b18d6e530240df6"
@@ -3594,19 +3186,12 @@ errno@~0.1.7:
dependencies:
prr "~1.0.1"
-error-ex@^1.2.0, error-ex@^1.3.1:
+error-ex@^1.2.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
dependencies:
is-arrayish "^0.2.1"
-error@^7.0.2:
- version "7.0.2"
- resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02"
- dependencies:
- string-template "~0.2.1"
- xtend "~4.0.0"
-
es-abstract@^1.6.1, es-abstract@^1.7.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227"
@@ -3632,15 +3217,7 @@ es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14:
es6-iterator "2"
es6-symbol "~3.1"
-es5-ext@^0.10.35:
- version "0.10.44"
- resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.44.tgz#7a877e994bb190aebd4718aa2d62784a12e2ca20"
- dependencies:
- es6-iterator "~2.0.3"
- es6-symbol "~3.1.1"
- next-tick "1"
-
-es6-iterator@2:
+es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512"
dependencies:
@@ -3648,14 +3225,6 @@ es6-iterator@2:
es5-ext "^0.10.14"
es6-symbol "^3.1"
-es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
- dependencies:
- d "1"
- es5-ext "^0.10.35"
- es6-symbol "^3.1.1"
-
es6-map@^0.1.3:
version "0.1.5"
resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0"
@@ -3707,10 +3276,6 @@ es6-weak-map@^2.0.1:
es6-iterator "^2.0.1"
es6-symbol "^3.1.1"
-es6bindall@^0.0.9:
- version "0.0.9"
- resolved "https://registry.yarnpkg.com/es6bindall/-/es6bindall-0.0.9.tgz#71e00afa69f8dd59ac5ac898a0d31c978df817d5"
-
escape-latex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/escape-latex/-/escape-latex-1.0.0.tgz#74b9e94d8c178645704c33791e95a4155b59718f"
@@ -3741,17 +3306,6 @@ escodegen@^1.6.1:
optionalDependencies:
source-map "~0.5.6"
-escodegen@^1.8.1, escodegen@~1.9.0:
- version "1.9.1"
- resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2"
- dependencies:
- esprima "^3.1.3"
- estraverse "^4.2.0"
- esutils "^2.0.2"
- optionator "^0.8.1"
- optionalDependencies:
- source-map "~0.6.1"
-
escodegen@~0.0.24:
version "0.0.28"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-0.0.28.tgz#0e4ff1715f328775d6cab51ac44a406cd7abffd3"
@@ -3792,6 +3346,12 @@ eslint-config-airbnb@^15.0.1:
dependencies:
eslint-config-airbnb-base "^11.3.0"
+eslint-config-prettier@^2.9.0:
+ version "2.9.0"
+ resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz#5ecd65174d486c22dff389fe036febf502d468a3"
+ dependencies:
+ get-stdin "^5.0.1"
+
eslint-import-resolver-node@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc"
@@ -3833,6 +3393,13 @@ eslint-plugin-jsx-a11y@^5.1.1:
emoji-regex "^6.1.0"
jsx-ast-utils "^1.4.0"
+eslint-plugin-prettier@^2.6.0:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.0.tgz#33e4e228bdb06142d03c560ce04ec23f6c767dd7"
+ dependencies:
+ fast-diff "^1.1.1"
+ jest-docblock "^21.0.0"
+
eslint-plugin-react@^7.0.1:
version "7.4.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz#300a95861b9729c087d362dd64abcc351a74364a"
@@ -3915,7 +3482,7 @@ esprima@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
-esprima@^4.0.0, esprima@~4.0.0:
+esprima@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
@@ -4000,10 +3567,6 @@ execa@^0.7.0:
signal-exit "^3.0.0"
strip-eof "^1.0.0"
-exenv@^1.2.0:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
-
exit-hook@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
@@ -4014,40 +3577,22 @@ expand-brackets@^0.1.4:
dependencies:
is-posix-bracket "^0.1.0"
-expand-brackets@^2.1.4:
- version "2.1.4"
- resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
- dependencies:
- debug "^2.3.3"
- define-property "^0.2.5"
- extend-shallow "^2.0.1"
- posix-character-classes "^0.1.0"
- regex-not "^1.0.0"
- snapdragon "^0.8.1"
- to-regex "^3.0.1"
-
expand-range@^1.8.1:
version "1.8.2"
resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
dependencies:
fill-range "^2.1.0"
-expand-tilde@^2.0.0, expand-tilde@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
- dependencies:
- homedir-polyfill "^1.0.1"
-
expect.js@~0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/expect.js/-/expect.js-0.2.0.tgz#1028533d2c1c363f74a6796ff57ec0520ded2be1"
-exports-loader@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/exports-loader/-/exports-loader-0.7.0.tgz#84881c784dea6036b8e1cd1dac3da9b6409e21a5"
+exports-loader@^0.6.3:
+ version "0.6.4"
+ resolved "https://registry.yarnpkg.com/exports-loader/-/exports-loader-0.6.4.tgz#d70fc6121975b35fc12830cf52754be2740fc886"
dependencies:
- loader-utils "^1.1.0"
- source-map "0.5.0"
+ loader-utils "^1.0.2"
+ source-map "0.5.x"
extend-shallow@^2.0.1:
version "2.0.1"
@@ -4055,13 +3600,6 @@ extend-shallow@^2.0.1:
dependencies:
is-extendable "^0.1.0"
-extend-shallow@^3.0.0, extend-shallow@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8"
- dependencies:
- assign-symbols "^1.0.0"
- is-extendable "^1.0.1"
-
extend@~3.0.0, extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
@@ -4078,36 +3616,15 @@ external-editor@^2.0.4:
iconv-lite "^0.4.17"
tmp "^0.0.33"
-external-editor@^2.1.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5"
- dependencies:
- chardet "^0.4.0"
- iconv-lite "^0.4.17"
- tmp "^0.0.33"
-
extglob@^0.3.1:
version "0.3.2"
resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
dependencies:
is-extglob "^1.0.0"
-extglob@^2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
- dependencies:
- array-unique "^0.3.2"
- define-property "^1.0.0"
- expand-brackets "^2.1.4"
- extend-shallow "^2.0.1"
- fragment-cache "^0.2.1"
- regex-not "^1.0.0"
- snapdragon "^0.8.1"
- to-regex "^3.0.1"
-
-extract-text-webpack-plugin@3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz#5f043eaa02f9750a9258b78c0a6e0dc1408fb2f7"
+extract-text-webpack-plugin@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.0.tgz#90caa7907bc449f335005e3ac7532b41b00de612"
dependencies:
async "^2.4.1"
loader-utils "^1.1.0"
@@ -4131,25 +3648,10 @@ fast-deep-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
-fast-deep-equal@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
-
-fast-diff@^1.0.1:
+fast-diff@^1.0.1, fast-diff@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154"
-fast-glob@^2.0.2:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.2.tgz#71723338ac9b4e0e2fff1d6748a2a13d5ed352bf"
- dependencies:
- "@mrmlnc/readdir-enhanced" "^2.2.1"
- "@nodelib/fs.stat" "^1.0.1"
- glob-parent "^3.1.0"
- is-glob "^4.0.0"
- merge2 "^1.2.1"
- micromatch "^3.1.10"
-
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
@@ -4184,11 +3686,7 @@ fbjs@^0.8.1, fbjs@^0.8.12, fbjs@^0.8.16, fbjs@^0.8.4, fbjs@^0.8.9:
setimmediate "^1.0.5"
ua-parser-js "^0.7.9"
-figgy-pudding@^3.0.0, figgy-pudding@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.1.0.tgz#a77ed2284175976c424b390b298569e9df86dd1e"
-
-figures@^1.3.5, figures@^1.7.0:
+figures@^1.3.5:
version "1.7.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
dependencies:
@@ -4235,15 +3733,6 @@ fill-range@^2.1.0:
repeat-element "^1.1.2"
repeat-string "^1.5.2"
-fill-range@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
- dependencies:
- extend-shallow "^2.0.1"
- is-number "^3.0.0"
- repeat-string "^1.6.1"
- to-regex-range "^2.1.0"
-
filled-array@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/filled-array/-/filled-array-1.1.0.tgz#c3c4f6c663b923459a9aa29912d2d031f1507f84"
@@ -4273,12 +3762,6 @@ find-up@^2.0.0, find-up@^2.1.0:
dependencies:
locate-path "^2.0.0"
-first-chunk-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70"
- dependencies:
- readable-stream "^2.0.2"
-
flat-cache@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481"
@@ -4292,10 +3775,6 @@ flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
-flow-parser@^0.*:
- version "0.73.0"
- resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.73.0.tgz#525ac0776f743e16b6dca1a3dd6c602260b15773"
-
flow-remove-types@^1.1.2:
version "1.2.1"
resolved "https://registry.yarnpkg.com/flow-remove-types/-/flow-remove-types-1.2.1.tgz#58e261bf8b842bd234c86cafb982a1213aff0edb"
@@ -4314,7 +3793,7 @@ for-in@^0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
-for-in@^1.0.1, for-in@^1.0.2:
+for-in@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -4374,16 +3853,16 @@ form-data@~2.3.1:
combined-stream "^1.0.5"
mime-types "^2.1.12"
+formatio@1.2.0, formatio@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb"
+ dependencies:
+ samsam "1.x"
+
fraction.js@4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.4.tgz#04e567110718adf7b52974a10434ab4c67a5183e"
-fragment-cache@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
- dependencies:
- map-cache "^0.2.2"
-
from2@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/from2/-/from2-1.3.0.tgz#88413baaa5f9a597cfde9221d86986cd3c061dfd"
@@ -4391,7 +3870,7 @@ from2@^1.3.0:
inherits "~2.0.1"
readable-stream "~1.1.10"
-from2@^2.1.0, from2@^2.1.1:
+from2@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
dependencies:
@@ -4446,13 +3925,6 @@ fsevents@^1.0.0:
nan "^2.3.0"
node-pre-gyp "^0.6.36"
-fsevents@^1.1.2:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426"
- dependencies:
- nan "^2.9.2"
- node-pre-gyp "^0.10.0"
-
fstream-ignore@^1.0.0, fstream-ignore@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105"
@@ -4493,6 +3965,10 @@ functional-red-black-tree@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
+fuse.js@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.2.0.tgz#f0448e8069855bf2a3e683cdc1d320e7e2a07ef4"
+
gauge@~2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.6.0.tgz#d35301ad18e96902b4751dcbbe40f4218b942a46"
@@ -4607,9 +4083,9 @@ geojson-vt@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-2.4.0.tgz#3c1cf44493f35eb4d2c70c95da6550de66072c05"
-geojson-vt@^3.1.0:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-3.1.2.tgz#ea98849bd7717979db4c86fed8ef4e47475e4bab"
+geojson-vt@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-3.0.0.tgz#a24cae5488ab4897e86ca0e4bf0d9760d628ae0a"
geolib@^2.0.24:
version "2.0.24"
@@ -4627,14 +4103,10 @@ get-stdin@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
-get-stream@3.0.0, get-stream@^3.0.0:
+get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
-get-value@^2.0.3, get-value@^2.0.6:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
-
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
@@ -4647,13 +4119,6 @@ gettext-parser@1.1.0:
dependencies:
encoding "^0.1.11"
-gh-got@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-6.0.0.tgz#d74353004c6ec466647520a10bd46f7299d268d0"
- dependencies:
- got "^7.0.0"
- is-plain-obj "^1.1.0"
-
ghauth@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ghauth/-/ghauth-3.0.0.tgz#8292a24ef47899f180a39c780c4809561294bdbc"
@@ -4688,12 +4153,6 @@ github-commit-stream@0.1.0:
request "~2.22.0"
through "~2.3.4"
-github-username@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/github-username/-/github-username-4.1.0.tgz#cbe280041883206da4212ae9e4b5f169c30bf417"
- dependencies:
- gh-got "^6.0.0"
-
github@0.1.16:
version "0.1.16"
resolved "https://registry.yarnpkg.com/github/-/github-0.1.16.tgz#895d2a85b0feb7980d89ac0ce4f44dcaa03f17b5"
@@ -4746,13 +4205,6 @@ glamorous@^3.13.1:
react-html-attributes "^1.3.0"
svg-tag-names "^1.1.0"
-glob-all@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab"
- dependencies:
- glob "^7.0.5"
- yargs "~1.2.6"
-
glob-base@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
@@ -4766,13 +4218,6 @@ glob-parent@^2.0.0:
dependencies:
is-glob "^2.0.0"
-glob-parent@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
- dependencies:
- is-glob "^3.1.0"
- path-dirname "^1.0.0"
-
glob-to-regexp@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
@@ -4798,7 +4243,7 @@ glob@7.1.1:
once "^1.3.0"
path-is-absolute "^1.0.0"
-glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.0, glob@~7.1.2:
+glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.0, glob@~7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
@@ -4822,24 +4267,6 @@ global-dirs@^0.1.0:
dependencies:
ini "^1.3.4"
-global-modules@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
- dependencies:
- global-prefix "^1.0.1"
- is-windows "^1.0.1"
- resolve-dir "^1.0.0"
-
-global-prefix@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
- dependencies:
- expand-tilde "^2.0.2"
- homedir-polyfill "^1.0.1"
- ini "^1.3.4"
- is-windows "^1.0.1"
- which "^1.2.14"
-
globals@^11.0.1:
version "11.4.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.4.0.tgz#b85c793349561c16076a3c13549238a27945f1bc"
@@ -4859,24 +4286,6 @@ globby@^5.0.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"
-globby@^8.0.0, globby@^8.0.1:
- version "8.0.1"
... 3609 lines suppressed ...