mirror of
https://github.com/apache/superset.git
synced 2026-04-20 16:44:46 +00:00
[Feature] Dashboard scoped filter (#8590)
* [WIP][dashboard scoped filter] part 1: scope selector modal (#8557) * filter scope selector modal * add single-field-edit in multi-edit mode switch * fix code review comments (round 1) * refactory after design review * fix a few props initial value * [WIP][dashboard scoped filter] part 2: add algorithm to convert checked ids to scope object (#8564) * convert ids to scope object * use lodash helpers to make code readable * [WIP][dashboard scoped filter] part 3: merge filter scope settings into dashboard redux state (#8522) * merge filter scope settings into dashboard redux state * fix/add unit tests * minor bug fixes * fix save filter Scopes behavior * resolve review comments * fix save filter scope settings * minor comments * [dashboard scoped filter] Improve scrollbar inside modal (#8553) * improve scroll inside modal * make left pane and right pane scroll separately * fix review comments * force show filter_box as unchecked (#8587)
This commit is contained in:
@@ -39,6 +39,7 @@ import {
|
||||
} from '../../../../src/dashboard/actions/dashboardLayout';
|
||||
|
||||
import { setUnsavedChanges } from '../../../../src/dashboard/actions/dashboardState';
|
||||
import * as dashboardFilters from '../../../../src/dashboard/actions/dashboardFilters';
|
||||
import {
|
||||
addWarningToast,
|
||||
ADD_TOAST,
|
||||
@@ -80,6 +81,12 @@ describe('dashboardLayout actions', () => {
|
||||
|
||||
return { getState, dispatch, state };
|
||||
}
|
||||
beforeEach(() => {
|
||||
sinon.spy(dashboardFilters, 'updateLayoutComponents');
|
||||
});
|
||||
afterEach(() => {
|
||||
dashboardFilters.updateLayoutComponents.restore();
|
||||
});
|
||||
|
||||
describe('updateComponents', () => {
|
||||
it('should dispatch an updateLayout action', () => {
|
||||
@@ -92,6 +99,9 @@ describe('dashboardLayout actions', () => {
|
||||
type: UPDATE_COMPONENTS,
|
||||
payload: { nextComponents },
|
||||
});
|
||||
|
||||
// update component should not trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(0);
|
||||
});
|
||||
|
||||
it('should dispatch a setUnsavedChanges action if hasUnsavedChanges=false', () => {
|
||||
@@ -101,8 +111,10 @@ describe('dashboardLayout actions', () => {
|
||||
const nextComponents = { 1: {} };
|
||||
const thunk = updateComponents(nextComponents);
|
||||
thunk(dispatch, getState);
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(1).args[0]).toEqual(setUnsavedChanges(true));
|
||||
|
||||
// update component should not trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -111,11 +123,13 @@ describe('dashboardLayout actions', () => {
|
||||
const { getState, dispatch } = setup();
|
||||
const thunk = deleteComponent('id', 'parentId');
|
||||
thunk(dispatch, getState);
|
||||
expect(dispatch.callCount).toBe(1);
|
||||
expect(dispatch.getCall(0).args[0]).toEqual({
|
||||
type: DELETE_COMPONENT,
|
||||
payload: { id: 'id', parentId: 'parentId' },
|
||||
});
|
||||
|
||||
// delete components should trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(1);
|
||||
});
|
||||
|
||||
it('should dispatch a setUnsavedChanges action if hasUnsavedChanges=false', () => {
|
||||
@@ -124,8 +138,10 @@ describe('dashboardLayout actions', () => {
|
||||
});
|
||||
const thunk = deleteComponent('id', 'parentId');
|
||||
thunk(dispatch, getState);
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(1).args[0]).toEqual(setUnsavedChanges(true));
|
||||
expect(dispatch.getCall(2).args[0]).toEqual(setUnsavedChanges(true));
|
||||
|
||||
// delete components should trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -149,7 +165,8 @@ describe('dashboardLayout actions', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
// update dashboard title should not trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -159,11 +176,13 @@ describe('dashboardLayout actions', () => {
|
||||
const dropResult = {};
|
||||
const thunk = createTopLevelTabs(dropResult);
|
||||
thunk(dispatch, getState);
|
||||
expect(dispatch.callCount).toBe(1);
|
||||
expect(dispatch.getCall(0).args[0]).toEqual({
|
||||
type: CREATE_TOP_LEVEL_TABS,
|
||||
payload: { dropResult },
|
||||
});
|
||||
|
||||
// create top level tabs should trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(1);
|
||||
});
|
||||
|
||||
it('should dispatch a setUnsavedChanges action if hasUnsavedChanges=false', () => {
|
||||
@@ -173,8 +192,10 @@ describe('dashboardLayout actions', () => {
|
||||
const dropResult = {};
|
||||
const thunk = createTopLevelTabs(dropResult);
|
||||
thunk(dispatch, getState);
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(1).args[0]).toEqual(setUnsavedChanges(true));
|
||||
expect(dispatch.getCall(2).args[0]).toEqual(setUnsavedChanges(true));
|
||||
|
||||
// create top level tabs should trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -184,11 +205,13 @@ describe('dashboardLayout actions', () => {
|
||||
const dropResult = {};
|
||||
const thunk = deleteTopLevelTabs(dropResult);
|
||||
thunk(dispatch, getState);
|
||||
expect(dispatch.callCount).toBe(1);
|
||||
expect(dispatch.getCall(0).args[0]).toEqual({
|
||||
type: DELETE_TOP_LEVEL_TABS,
|
||||
payload: {},
|
||||
});
|
||||
|
||||
// delete top level tabs should trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(1);
|
||||
});
|
||||
|
||||
it('should dispatch a setUnsavedChanges action if hasUnsavedChanges=false', () => {
|
||||
@@ -198,8 +221,10 @@ describe('dashboardLayout actions', () => {
|
||||
const dropResult = {};
|
||||
const thunk = deleteTopLevelTabs(dropResult);
|
||||
thunk(dispatch, getState);
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(1).args[0]).toEqual(setUnsavedChanges(true));
|
||||
expect(dispatch.getCall(2).args[0]).toEqual(setUnsavedChanges(true));
|
||||
|
||||
// delete top level tabs should trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -261,6 +286,9 @@ describe('dashboardLayout actions', () => {
|
||||
thunk2(dispatch, getState);
|
||||
|
||||
expect(dispatch.callCount).toBe(3);
|
||||
|
||||
// resize components should not trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -286,7 +314,8 @@ describe('dashboardLayout actions', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
// create components should trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(1);
|
||||
});
|
||||
|
||||
it('should move a component if the component is not new', () => {
|
||||
@@ -315,7 +344,8 @@ describe('dashboardLayout actions', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
// create components should trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(1);
|
||||
});
|
||||
|
||||
it('should dispatch a toast if the drop overflows the destination', () => {
|
||||
@@ -379,9 +409,6 @@ describe('dashboardLayout actions', () => {
|
||||
parentId: 'parentId',
|
||||
},
|
||||
});
|
||||
|
||||
// move thunk, delete thunk, delete result actions
|
||||
expect(dispatch.callCount).toBe(3);
|
||||
});
|
||||
|
||||
it('should create top-level tabs if dropped on root', () => {
|
||||
@@ -404,8 +431,6 @@ describe('dashboardLayout actions', () => {
|
||||
dropResult,
|
||||
},
|
||||
});
|
||||
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
});
|
||||
|
||||
it('should dispatch a toast if drop top-level tab into nested tab', () => {
|
||||
@@ -497,8 +522,10 @@ describe('dashboardLayout actions', () => {
|
||||
const thunk = redoLayoutAction();
|
||||
thunk(dispatch, getState);
|
||||
|
||||
expect(dispatch.callCount).toBe(1);
|
||||
expect(dispatch.getCall(0).args[0]).toEqual(UndoActionCreators.redo());
|
||||
|
||||
// redo/undo should trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(1);
|
||||
});
|
||||
|
||||
it('should dispatch a setUnsavedChanges(true) action if hasUnsavedChanges=false', () => {
|
||||
@@ -507,9 +534,10 @@ describe('dashboardLayout actions', () => {
|
||||
});
|
||||
const thunk = redoLayoutAction();
|
||||
thunk(dispatch, getState);
|
||||
expect(dispatch.getCall(2).args[0]).toEqual(setUnsavedChanges(true));
|
||||
|
||||
expect(dispatch.callCount).toBe(2);
|
||||
expect(dispatch.getCall(1).args[0]).toEqual(setUnsavedChanges(true));
|
||||
// redo/undo should trigger action for dashboardFilters
|
||||
expect(dashboardFilters.updateLayoutComponents.callCount).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user