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