mirror of
https://github.com/apache/superset.git
synced 2024-09-17 11:09:47 -04:00
1. fix check filters change logic (#4339)
2. should show chart after loading completed
This commit is contained in:
parent
ad212272d1
commit
e965f95477
@ -207,7 +207,7 @@ class Chart extends React.PureComponent {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
{!this.props.chartAlert &&
|
{!isLoading && !this.props.chartAlert &&
|
||||||
<ChartBody
|
<ChartBody
|
||||||
containerId={this.containerId}
|
containerId={this.containerId}
|
||||||
vizType={this.props.vizType}
|
vizType={this.props.vizType}
|
||||||
|
@ -19,6 +19,7 @@ export default function Loading(props) {
|
|||||||
height: props.size,
|
height: props.size,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
margin: 0,
|
margin: 0,
|
||||||
|
position: 'absolute',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -93,12 +93,21 @@ class Dashboard extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
if (!areObjectsEqual(prevProps.filters, this.props.filters) && this.props.refresh) {
|
if (this.props.refresh) {
|
||||||
const currentFilterKeys = Object.keys(this.props.filters);
|
let changedFilterKey;
|
||||||
if (currentFilterKeys.length) {
|
const prevFiltersKeySet = new Set(Object.keys(prevProps.filters));
|
||||||
currentFilterKeys.forEach(key => (this.refreshExcept(key)));
|
Object.keys(this.props.filters).some((key) => {
|
||||||
} else {
|
prevFiltersKeySet.delete(key);
|
||||||
this.refreshExcept();
|
if (prevProps.filters[key] === undefined ||
|
||||||
|
!areObjectsEqual(prevProps.filters[key], this.props.filters[key])) {
|
||||||
|
changedFilterKey = key;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
// has changed filter or removed a filter?
|
||||||
|
if (!!changedFilterKey || prevFiltersKeySet.size) {
|
||||||
|
this.refreshExcept(changedFilterKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ import sinon from 'sinon';
|
|||||||
|
|
||||||
import { chart as initChart } from '../../../javascripts/chart/chartReducer';
|
import { chart as initChart } from '../../../javascripts/chart/chartReducer';
|
||||||
import Chart from '../../../javascripts/chart/Chart';
|
import Chart from '../../../javascripts/chart/Chart';
|
||||||
|
import ChartBody from '../../../javascripts/chart/ChartBody';
|
||||||
|
import Loading from '../../../javascripts/components/Loading';
|
||||||
|
|
||||||
describe('Chart', () => {
|
describe('Chart', () => {
|
||||||
const chart = {
|
const chart = {
|
||||||
@ -30,15 +32,20 @@ describe('Chart', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('renderViz', () => {
|
|
||||||
let wrapper;
|
let wrapper;
|
||||||
let stub;
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = shallow(
|
wrapper = shallow(
|
||||||
<Chart {...mockedProps} />,
|
<Chart {...mockedProps} />,
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
describe('renderViz', () => {
|
||||||
|
let stub;
|
||||||
|
beforeEach(() => {
|
||||||
stub = sinon.stub(wrapper.instance(), 'renderViz');
|
stub = sinon.stub(wrapper.instance(), 'renderViz');
|
||||||
});
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
stub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
it('should not call when loading', () => {
|
it('should not call when loading', () => {
|
||||||
const prevProp = wrapper.props();
|
const prevProp = wrapper.props();
|
||||||
@ -68,4 +75,11 @@ describe('Chart', () => {
|
|||||||
expect(stub.callCount).to.equals(1);
|
expect(stub.callCount).to.equals(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('render', () => {
|
||||||
|
it('should render ChartBody after loading is completed', () => {
|
||||||
|
expect(wrapper.find(Loading)).to.have.length(1);
|
||||||
|
expect(wrapper.find(ChartBody)).to.have.length(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -26,7 +26,7 @@ describe('Dashboard', () => {
|
|||||||
it('should render', () => {
|
it('should render', () => {
|
||||||
const wrapper = shallow(<Dashboard {...mockedProps} />);
|
const wrapper = shallow(<Dashboard {...mockedProps} />);
|
||||||
expect(wrapper.find('#dashboard-container')).to.have.length(1);
|
expect(wrapper.find('#dashboard-container')).to.have.length(1);
|
||||||
expect(wrapper.instance().getAllSlices()).to.have.length(2);
|
expect(wrapper.instance().getAllSlices()).to.have.length(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle metadata default_filters', () => {
|
it('should handle metadata default_filters', () => {
|
||||||
@ -51,10 +51,8 @@ describe('Dashboard', () => {
|
|||||||
it('should carry updated filter', () => {
|
it('should carry updated filter', () => {
|
||||||
wrapper.setProps({
|
wrapper.setProps({
|
||||||
filters: {
|
filters: {
|
||||||
256: {
|
256: { region: [] },
|
||||||
region: [],
|
257: { country_name: ['France'] },
|
||||||
country_name: ['France'],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const extraFilters = wrapper.instance().getFormDataExtra(selectedSlice).extra_filters;
|
const extraFilters = wrapper.instance().getFormDataExtra(selectedSlice).extra_filters;
|
||||||
@ -74,7 +72,7 @@ describe('Dashboard', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not refresh filter slice', () => {
|
it('should not refresh filter slice', () => {
|
||||||
const filterKey = Object.keys(defaultFilters)[0];
|
const filterKey = Object.keys(defaultFilters)[1];
|
||||||
wrapper.instance().refreshExcept(filterKey);
|
wrapper.instance().refreshExcept(filterKey);
|
||||||
expect(spy.callCount).to.equal(1);
|
expect(spy.callCount).to.equal(1);
|
||||||
expect(spy.getCall(0).args[0].length).to.equal(1);
|
expect(spy.getCall(0).args[0].length).to.equal(1);
|
||||||
@ -83,7 +81,102 @@ describe('Dashboard', () => {
|
|||||||
it('should refresh all slices', () => {
|
it('should refresh all slices', () => {
|
||||||
wrapper.instance().refreshExcept();
|
wrapper.instance().refreshExcept();
|
||||||
expect(spy.callCount).to.equal(1);
|
expect(spy.callCount).to.equal(1);
|
||||||
expect(spy.getCall(0).args[0].length).to.equal(2);
|
expect(spy.getCall(0).args[0].length).to.equal(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('componentDidUpdate', () => {
|
||||||
|
let wrapper;
|
||||||
|
let refreshExceptSpy;
|
||||||
|
let fetchSlicesStub;
|
||||||
|
let prevProp;
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(<Dashboard {...mockedProps} />);
|
||||||
|
prevProp = wrapper.instance().props;
|
||||||
|
refreshExceptSpy = sinon.spy(wrapper.instance(), 'refreshExcept');
|
||||||
|
fetchSlicesStub = sinon.stub(wrapper.instance(), 'fetchSlices');
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
fetchSlicesStub.restore();
|
||||||
|
refreshExceptSpy.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('should check if filter has change', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
refreshExceptSpy.reset();
|
||||||
|
});
|
||||||
|
it('no change', () => {
|
||||||
|
wrapper.setProps({
|
||||||
|
refresh: true,
|
||||||
|
filters: {
|
||||||
|
256: { region: [] },
|
||||||
|
257: { country_name: ['United States'] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
wrapper.instance().componentDidUpdate(prevProp);
|
||||||
|
expect(refreshExceptSpy.callCount).to.equal(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('remove filter', () => {
|
||||||
|
wrapper.setProps({
|
||||||
|
refresh: true,
|
||||||
|
filters: {
|
||||||
|
256: { region: [] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
wrapper.instance().componentDidUpdate(prevProp);
|
||||||
|
expect(refreshExceptSpy.callCount).to.equal(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('change filter', () => {
|
||||||
|
wrapper.setProps({
|
||||||
|
refresh: true,
|
||||||
|
filters: {
|
||||||
|
256: { region: [] },
|
||||||
|
257: { country_name: ['Canada'] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
wrapper.instance().componentDidUpdate(prevProp);
|
||||||
|
expect(refreshExceptSpy.callCount).to.equal(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add filter', () => {
|
||||||
|
wrapper.setProps({
|
||||||
|
refresh: true,
|
||||||
|
filters: {
|
||||||
|
256: { region: [] },
|
||||||
|
257: { country_name: ['Canada'] },
|
||||||
|
258: { another_filter: ['new'] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
wrapper.instance().componentDidUpdate(prevProp);
|
||||||
|
expect(refreshExceptSpy.callCount).to.equal(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should refresh if refresh flag is true', () => {
|
||||||
|
wrapper.setProps({
|
||||||
|
refresh: true,
|
||||||
|
filters: {
|
||||||
|
256: { region: ['Asian'] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
wrapper.instance().componentDidUpdate(prevProp);
|
||||||
|
const fetchArgs = fetchSlicesStub.lastCall.args[0];
|
||||||
|
expect(fetchArgs).to.have.length(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not refresh filter_immune_slices', () => {
|
||||||
|
wrapper.setProps({
|
||||||
|
refresh: true,
|
||||||
|
filters: {
|
||||||
|
256: { region: [] },
|
||||||
|
257: { country_name: ['Canada'] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
wrapper.instance().componentDidUpdate(prevProp);
|
||||||
|
const fetchArgs = fetchSlicesStub.lastCall.args[0];
|
||||||
|
expect(fetchArgs).to.have.length(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import { getInitialState } from '../../../javascripts/dashboard/reducers';
|
import { getInitialState } from '../../../javascripts/dashboard/reducers';
|
||||||
|
|
||||||
export const defaultFilters = {
|
export const defaultFilters = {
|
||||||
256: {
|
256: { region: [] },
|
||||||
region: [],
|
257: { country_name: ['United States'] },
|
||||||
country_name: ['United States'],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
export const regionFilter = {
|
export const regionFilter = {
|
||||||
datasource: null,
|
datasource: null,
|
||||||
@ -39,6 +37,35 @@ export const regionFilter = {
|
|||||||
slice_name: 'Region Filters',
|
slice_name: 'Region Filters',
|
||||||
slice_url: '/superset/explore/table/2/?form_data=%7B%22slice_id%22%3A%20256%7D',
|
slice_url: '/superset/explore/table/2/?form_data=%7B%22slice_id%22%3A%20256%7D',
|
||||||
};
|
};
|
||||||
|
export const countryFilter = {
|
||||||
|
datasource: null,
|
||||||
|
description: null,
|
||||||
|
description_markeddown: '',
|
||||||
|
edit_url: '/slicemodelview/edit/257',
|
||||||
|
form_data: {
|
||||||
|
datasource: '2__table',
|
||||||
|
date_filter: false,
|
||||||
|
filters: [],
|
||||||
|
granularity_sqla: null,
|
||||||
|
groupby: ['country_name'],
|
||||||
|
having: '',
|
||||||
|
instant_filtering: true,
|
||||||
|
metric: 'sum__SP_POP_TOTL',
|
||||||
|
show_druid_time_granularity: false,
|
||||||
|
show_druid_time_origin: false,
|
||||||
|
show_sqla_time_column: false,
|
||||||
|
show_sqla_time_granularity: false,
|
||||||
|
since: '100 years ago',
|
||||||
|
slice_id: 257,
|
||||||
|
time_grain_sqla: null,
|
||||||
|
until: 'now',
|
||||||
|
viz_type: 'filter_box',
|
||||||
|
where: '',
|
||||||
|
},
|
||||||
|
slice_id: 257,
|
||||||
|
slice_name: 'Country Filters',
|
||||||
|
slice_url: '/superset/explore/table/2/?form_data=%7B%22slice_id%22%3A%20257%7D',
|
||||||
|
};
|
||||||
export const slice = {
|
export const slice = {
|
||||||
datasource: null,
|
datasource: null,
|
||||||
description: null,
|
description: null,
|
||||||
@ -100,7 +127,7 @@ const mockDashboardData = {
|
|||||||
id: 2,
|
id: 2,
|
||||||
metadata: {
|
metadata: {
|
||||||
default_filters: JSON.stringify(defaultFilters),
|
default_filters: JSON.stringify(defaultFilters),
|
||||||
filter_immune_slices: [],
|
filter_immune_slices: [256],
|
||||||
timed_refresh_immune_slices: [],
|
timed_refresh_immune_slices: [],
|
||||||
filter_immune_slice_fields: {},
|
filter_immune_slice_fields: {},
|
||||||
expanded_slices: {},
|
expanded_slices: {},
|
||||||
@ -122,7 +149,7 @@ const mockDashboardData = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
slug: 'births',
|
slug: 'births',
|
||||||
slices: [regionFilter, slice],
|
slices: [regionFilter, slice, countryFilter],
|
||||||
standalone_mode: false,
|
standalone_mode: false,
|
||||||
};
|
};
|
||||||
export const { dashboard, charts } = getInitialState({
|
export const { dashboard, charts } = getInitialState({
|
||||||
|
@ -11,8 +11,10 @@ describe('Dashboard reducers', () => {
|
|||||||
type: actions.REMOVE_SLICE,
|
type: actions.REMOVE_SLICE,
|
||||||
slice: initState.dashboard.slices[1],
|
slice: initState.dashboard.slices[1],
|
||||||
};
|
};
|
||||||
|
expect(initState.dashboard.slices).to.have.length(3);
|
||||||
|
|
||||||
const { dashboard, filters, refresh } = reducers(initState, action);
|
const { dashboard, filters, refresh } = reducers(initState, action);
|
||||||
expect(dashboard.slices).to.have.length(1);
|
expect(dashboard.slices).to.have.length(2);
|
||||||
expect(filters).to.deep.equal(defaultFilters);
|
expect(filters).to.deep.equal(defaultFilters);
|
||||||
expect(refresh).to.equal(false);
|
expect(refresh).to.equal(false);
|
||||||
});
|
});
|
||||||
@ -22,9 +24,12 @@ describe('Dashboard reducers', () => {
|
|||||||
type: actions.REMOVE_SLICE,
|
type: actions.REMOVE_SLICE,
|
||||||
slice: initState.dashboard.slices[0],
|
slice: initState.dashboard.slices[0],
|
||||||
};
|
};
|
||||||
|
const initFilters = Object.keys(initState.filters);
|
||||||
|
expect(initFilters).to.have.length(2);
|
||||||
|
|
||||||
const { dashboard, filters, refresh } = reducers(initState, action);
|
const { dashboard, filters, refresh } = reducers(initState, action);
|
||||||
expect(dashboard.slices).to.have.length(1);
|
expect(dashboard.slices).to.have.length(2);
|
||||||
expect(filters).to.deep.equal({});
|
expect(Object.keys(filters)).to.have.length(1);
|
||||||
expect(refresh).to.equal(true);
|
expect(refresh).to.equal(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -200,6 +200,7 @@ div.widget {
|
|||||||
.stack-trace-container,
|
.stack-trace-container,
|
||||||
.slice_container {
|
.slice_container {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user