mirror of
https://github.com/apache/superset.git
synced 2024-09-12 08:39:45 -04:00
fix(dashboard): Refresh Native Filters when Dashboard refreshes (#15890)
* Implement onRefresh action * Update tests * Clean up * Fix type * Add effect dependency
This commit is contained in:
parent
62550db385
commit
1297fd9169
@ -275,6 +275,32 @@ export function fetchCharts(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const refreshCharts = (chartList, force, interval, dashboardId, dispatch) =>
|
||||||
|
new Promise(resolve => {
|
||||||
|
dispatch(fetchCharts(chartList, force, interval, dashboardId));
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ON_REFRESH_SUCCESS = 'ON_REFRESH_SUCCESS';
|
||||||
|
export function onRefreshSuccess() {
|
||||||
|
return { type: ON_REFRESH_SUCCESS };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ON_REFRESH = 'ON_REFRESH';
|
||||||
|
export function onRefresh(
|
||||||
|
chartList = [],
|
||||||
|
force = false,
|
||||||
|
interval = 0,
|
||||||
|
dashboardId,
|
||||||
|
) {
|
||||||
|
return dispatch => {
|
||||||
|
dispatch({ type: ON_REFRESH });
|
||||||
|
refreshCharts(chartList, force, interval, dashboardId, dispatch).then(() =>
|
||||||
|
dispatch({ type: ON_REFRESH_SUCCESS }),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export const SHOW_BUILDER_PANE = 'SHOW_BUILDER_PANE';
|
export const SHOW_BUILDER_PANE = 'SHOW_BUILDER_PANE';
|
||||||
export function showBuilderPane() {
|
export function showBuilderPane() {
|
||||||
return { type: SHOW_BUILDER_PANE };
|
return { type: SHOW_BUILDER_PANE };
|
||||||
|
@ -378,6 +378,7 @@ export const hydrateDashboard = (dashboardData, chartData) => (
|
|||||||
hasUnsavedChanges: false,
|
hasUnsavedChanges: false,
|
||||||
maxUndoHistoryExceeded: false,
|
maxUndoHistoryExceeded: false,
|
||||||
lastModifiedTime: dashboardData.changed_on,
|
lastModifiedTime: dashboardData.changed_on,
|
||||||
|
isRefreshing: false,
|
||||||
activeTabs: [],
|
activeTabs: [],
|
||||||
},
|
},
|
||||||
dashboardLayout,
|
dashboardLayout,
|
||||||
|
@ -54,6 +54,7 @@ const createProps = () => ({
|
|||||||
onChange: jest.fn(),
|
onChange: jest.fn(),
|
||||||
fetchFaveStar: jest.fn(),
|
fetchFaveStar: jest.fn(),
|
||||||
fetchCharts: jest.fn(),
|
fetchCharts: jest.fn(),
|
||||||
|
onRefresh: jest.fn(),
|
||||||
saveFaveStar: jest.fn(),
|
saveFaveStar: jest.fn(),
|
||||||
savePublished: jest.fn(),
|
savePublished: jest.fn(),
|
||||||
isPublished: false,
|
isPublished: false,
|
||||||
@ -301,5 +302,5 @@ test('should refresh the charts', async () => {
|
|||||||
render(setup(mockedProps));
|
render(setup(mockedProps));
|
||||||
await openActionsDropdown();
|
await openActionsDropdown();
|
||||||
userEvent.click(screen.getByText('Refresh dashboard'));
|
userEvent.click(screen.getByText('Refresh dashboard'));
|
||||||
expect(mockedProps.fetchCharts).toHaveBeenCalledTimes(1);
|
expect(mockedProps.onRefresh).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
@ -82,6 +82,7 @@ const propTypes = {
|
|||||||
lastModifiedTime: PropTypes.number.isRequired,
|
lastModifiedTime: PropTypes.number.isRequired,
|
||||||
|
|
||||||
// redux
|
// redux
|
||||||
|
onRefresh: PropTypes.func.isRequired,
|
||||||
onUndo: PropTypes.func.isRequired,
|
onUndo: PropTypes.func.isRequired,
|
||||||
onRedo: PropTypes.func.isRequired,
|
onRedo: PropTypes.func.isRequired,
|
||||||
undoLength: PropTypes.number.isRequired,
|
undoLength: PropTypes.number.isRequired,
|
||||||
@ -216,8 +217,7 @@ class Header extends React.PureComponent {
|
|||||||
interval: 0,
|
interval: 0,
|
||||||
chartCount: chartList.length,
|
chartCount: chartList.length,
|
||||||
});
|
});
|
||||||
|
return this.props.onRefresh(
|
||||||
return this.props.fetchCharts(
|
|
||||||
chartList,
|
chartList,
|
||||||
true,
|
true,
|
||||||
0,
|
0,
|
||||||
|
@ -87,6 +87,7 @@ export interface HeaderProps {
|
|||||||
lastModifiedTime: number;
|
lastModifiedTime: number;
|
||||||
onUndo: () => void;
|
onUndo: () => void;
|
||||||
onRedo: () => void;
|
onRedo: () => void;
|
||||||
|
onRefresh: () => void;
|
||||||
undoLength: number;
|
undoLength: number;
|
||||||
redoLength: number;
|
redoLength: number;
|
||||||
setMaxUndoHistoryExceeded: () => void;
|
setMaxUndoHistoryExceeded: () => void;
|
||||||
|
@ -28,7 +28,7 @@ import {
|
|||||||
JsonObject,
|
JsonObject,
|
||||||
getChartMetadataRegistry,
|
getChartMetadataRegistry,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { areObjectsEqual } from 'src/reduxUtils';
|
import { areObjectsEqual } from 'src/reduxUtils';
|
||||||
import { getChartDataRequest } from 'src/chart/chartAction';
|
import { getChartDataRequest } from 'src/chart/chartAction';
|
||||||
import Loading from 'src/components/Loading';
|
import Loading from 'src/components/Loading';
|
||||||
@ -36,6 +36,7 @@ import BasicErrorAlert from 'src/components/ErrorMessage/BasicErrorAlert';
|
|||||||
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
|
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
|
||||||
import { waitForAsyncData } from 'src/middleware/asyncEvent';
|
import { waitForAsyncData } from 'src/middleware/asyncEvent';
|
||||||
import { ClientErrorObject } from 'src/utils/getClientErrorObject';
|
import { ClientErrorObject } from 'src/utils/getClientErrorObject';
|
||||||
|
import { RootState } from 'src/dashboard/types';
|
||||||
import { dispatchFocusAction } from './utils';
|
import { dispatchFocusAction } from './utils';
|
||||||
import { FilterProps } from './types';
|
import { FilterProps } from './types';
|
||||||
import { getFormData } from '../../utils';
|
import { getFormData } from '../../utils';
|
||||||
@ -62,6 +63,9 @@ const FilterValue: React.FC<FilterProps> = ({
|
|||||||
const { id, targets, filterType, adhoc_filters, time_range } = filter;
|
const { id, targets, filterType, adhoc_filters, time_range } = filter;
|
||||||
const metadata = getChartMetadataRegistry().get(filterType);
|
const metadata = getChartMetadataRegistry().get(filterType);
|
||||||
const cascadingFilters = useCascadingFilters(id, dataMaskSelected);
|
const cascadingFilters = useCascadingFilters(id, dataMaskSelected);
|
||||||
|
const isDashboardRefreshing = useSelector<RootState, boolean>(
|
||||||
|
state => state.dashboardState.isRefreshing,
|
||||||
|
);
|
||||||
const [state, setState] = useState<ChartDataResponseResult[]>([]);
|
const [state, setState] = useState<ChartDataResponseResult[]>([]);
|
||||||
const [error, setError] = useState<string>('');
|
const [error, setError] = useState<string>('');
|
||||||
const [formData, setFormData] = useState<Partial<QueryFormData>>({
|
const [formData, setFormData] = useState<Partial<QueryFormData>>({
|
||||||
@ -78,7 +82,7 @@ const FilterValue: React.FC<FilterProps> = ({
|
|||||||
const { name: groupby } = column;
|
const { name: groupby } = column;
|
||||||
const hasDataSource = !!datasetId;
|
const hasDataSource = !!datasetId;
|
||||||
const [isLoading, setIsLoading] = useState<boolean>(hasDataSource);
|
const [isLoading, setIsLoading] = useState<boolean>(hasDataSource);
|
||||||
const [isRefreshing, setIsRefreshing] = useState(true);
|
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -102,8 +106,10 @@ const FilterValue: React.FC<FilterProps> = ({
|
|||||||
});
|
});
|
||||||
const filterOwnState = filter.dataMask?.ownState || {};
|
const filterOwnState = filter.dataMask?.ownState || {};
|
||||||
if (
|
if (
|
||||||
!areObjectsEqual(formData, newFormData) ||
|
!isRefreshing &&
|
||||||
!areObjectsEqual(ownState, filterOwnState)
|
(!areObjectsEqual(formData, newFormData) ||
|
||||||
|
!areObjectsEqual(ownState, filterOwnState) ||
|
||||||
|
isDashboardRefreshing)
|
||||||
) {
|
) {
|
||||||
setFormData(newFormData);
|
setFormData(newFormData);
|
||||||
setOwnState(filterOwnState);
|
setOwnState(filterOwnState);
|
||||||
@ -165,6 +171,8 @@ const FilterValue: React.FC<FilterProps> = ({
|
|||||||
groupby,
|
groupby,
|
||||||
JSON.stringify(filter),
|
JSON.stringify(filter),
|
||||||
hasDataSource,
|
hasDataSource,
|
||||||
|
isRefreshing,
|
||||||
|
isDashboardRefreshing,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -39,6 +39,7 @@ import {
|
|||||||
setMaxUndoHistoryExceeded,
|
setMaxUndoHistoryExceeded,
|
||||||
maxUndoHistoryToast,
|
maxUndoHistoryToast,
|
||||||
setRefreshFrequency,
|
setRefreshFrequency,
|
||||||
|
onRefresh,
|
||||||
} from '../actions/dashboardState';
|
} from '../actions/dashboardState';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -120,6 +121,7 @@ function mapDispatchToProps(dispatch) {
|
|||||||
maxUndoHistoryToast,
|
maxUndoHistoryToast,
|
||||||
logEvent,
|
logEvent,
|
||||||
setRefreshFrequency,
|
setRefreshFrequency,
|
||||||
|
onRefresh,
|
||||||
dashboardInfoChanged,
|
dashboardInfoChanged,
|
||||||
dashboardTitleChanged,
|
dashboardTitleChanged,
|
||||||
updateDataMask,
|
updateDataMask,
|
||||||
|
@ -32,6 +32,8 @@ import {
|
|||||||
TOGGLE_PUBLISHED,
|
TOGGLE_PUBLISHED,
|
||||||
UPDATE_CSS,
|
UPDATE_CSS,
|
||||||
SET_REFRESH_FREQUENCY,
|
SET_REFRESH_FREQUENCY,
|
||||||
|
ON_REFRESH,
|
||||||
|
ON_REFRESH_SUCCESS,
|
||||||
SET_DIRECT_PATH,
|
SET_DIRECT_PATH,
|
||||||
SET_FOCUSED_FILTER_FIELD,
|
SET_FOCUSED_FILTER_FIELD,
|
||||||
UNSET_FOCUSED_FILTER_FIELD,
|
UNSET_FOCUSED_FILTER_FIELD,
|
||||||
@ -128,6 +130,18 @@ export default function dashboardStateReducer(state = {}, action) {
|
|||||||
hasUnsavedChanges: action.isPersistent,
|
hasUnsavedChanges: action.isPersistent,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
[ON_REFRESH]() {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isRefreshing: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
[ON_REFRESH_SUCCESS]() {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isRefreshing: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
[SET_DIRECT_PATH]() {
|
[SET_DIRECT_PATH]() {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
@ -60,6 +60,7 @@ export type DashboardState = {
|
|||||||
directPathToChild: string[];
|
directPathToChild: string[];
|
||||||
activeTabs: ActiveTabs;
|
activeTabs: ActiveTabs;
|
||||||
fullSizeChartId: number | null;
|
fullSizeChartId: number | null;
|
||||||
|
isRefreshing: boolean;
|
||||||
};
|
};
|
||||||
export type DashboardInfo = {
|
export type DashboardInfo = {
|
||||||
common: {
|
common: {
|
||||||
|
Loading…
Reference in New Issue
Block a user