[Dashboard] Keeping refresh frequency value in Dashboard (#5741)

* Keeping refresh frequency value in Dashboard

* fix eslint

* Fix arrow function

* Update ut

* start refresh when load dashboard
This commit is contained in:
Yongjie Zhao 2019-03-23 05:29:18 +08:00 committed by Grace Guo
parent 4631b7b791
commit 33d67dad79
10 changed files with 48 additions and 13 deletions

View File

@ -24,6 +24,7 @@ import RefreshIntervalModal from '../../../../src/dashboard/components/RefreshIn
describe('RefreshIntervalModal', () => {
const mockedProps = {
triggerNode: <i className="fa fa-edit" />,
refreshFrequency: 10,
};
it('is valid', () => {
expect(
@ -34,4 +35,8 @@ describe('RefreshIntervalModal', () => {
const wrapper = mount(<RefreshIntervalModal {...mockedProps} />);
expect(wrapper.find('.fa-edit')).toHaveLength(1);
});
it('should render a interval seconds', () => {
const wrapper = mount(<RefreshIntervalModal {...mockedProps} />);
expect(wrapper.prop('refreshFrequency')).toEqual(10);
});
});

View File

@ -123,6 +123,11 @@ export function onSave() {
return { type: ON_SAVE };
}
export const SET_REFRESH_FREQUENCY = 'SET_REFRESH_FREQUENCY';
export function setRefreshFrequency(refreshFrequency) {
return { type: SET_REFRESH_FREQUENCY, refreshFrequency };
}
export function saveDashboardRequestSuccess() {
return dispatch => {
dispatch(onSave());

View File

@ -77,6 +77,8 @@ const propTypes = {
redoLength: PropTypes.number.isRequired,
setMaxUndoHistoryExceeded: PropTypes.func.isRequired,
maxUndoHistoryToast: PropTypes.func.isRequired,
refreshFrequency: PropTypes.number.isRequired,
setRefreshFrequency: PropTypes.func.isRequired,
};
class Header extends React.PureComponent {
@ -100,6 +102,11 @@ class Header extends React.PureComponent {
this.overwriteDashboard = this.overwriteDashboard.bind(this);
}
componentDidMount() {
const refreshFrequency = this.props.refreshFrequency;
this.props.startPeriodicRender(refreshFrequency * 1000);
}
componentWillReceiveProps(nextProps) {
if (
UNDO_LIMIT - nextProps.undoLength <= 0 &&
@ -234,6 +241,8 @@ class Header extends React.PureComponent {
dashboardInfo,
hasUnsavedChanges,
isLoading,
refreshFrequency,
setRefreshFrequency,
} = this.props;
const userCanEdit = dashboardInfo.dash_edit_perm;
@ -346,6 +355,8 @@ class Header extends React.PureComponent {
onChange={onChange}
forceRefreshAllCharts={this.forceRefresh}
startPeriodicRender={this.startPeriodicRender}
refreshFrequency={refreshFrequency}
setRefreshFrequency={setRefreshFrequency}
updateCss={updateCss}
editMode={editMode}
hasUnsavedChanges={hasUnsavedChanges}

View File

@ -40,6 +40,8 @@ const propTypes = {
onChange: PropTypes.func.isRequired,
updateCss: PropTypes.func.isRequired,
forceRefreshAllCharts: PropTypes.func.isRequired,
refreshFrequency: PropTypes.number.isRequired,
setRefreshFrequency: PropTypes.func.isRequired,
startPeriodicRender: PropTypes.func.isRequired,
editMode: PropTypes.bool.isRequired,
userCanEdit: PropTypes.bool.isRequired,
@ -66,6 +68,7 @@ class HeaderActionsDropdown extends React.PureComponent {
};
this.changeCss = this.changeCss.bind(this);
this.changeRefreshInterval = this.changeRefreshInterval.bind(this);
}
componentWillMount() {
@ -95,12 +98,17 @@ class HeaderActionsDropdown extends React.PureComponent {
this.props.updateCss(css);
}
changeRefreshInterval(refreshInterval) {
this.props.setRefreshFrequency(refreshInterval);
this.props.startPeriodicRender(refreshInterval * 1000);
}
render() {
const {
dashboardTitle,
dashboardId,
startPeriodicRender,
forceRefreshAllCharts,
refreshFrequency,
editMode,
css,
hasUnsavedChanges,
@ -135,6 +143,7 @@ class HeaderActionsDropdown extends React.PureComponent {
layout={layout}
filters={filters}
expandedSlices={expandedSlices}
refreshFrequency={refreshFrequency}
css={css}
onSave={onSave}
isMenuItem
@ -160,9 +169,8 @@ class HeaderActionsDropdown extends React.PureComponent {
{t('Force refresh dashboard')}
</MenuItem>
<RefreshIntervalModal
onChange={refreshInterval =>
startPeriodicRender(refreshInterval * 1000)
}
refreshFrequency={refreshFrequency}
onChange={this.changeRefreshInterval}
triggerNode={<span>{t('Set auto-refresh interval')}</span>}
/>
{editMode && (

View File

@ -25,13 +25,8 @@ import ModalTrigger from '../../components/ModalTrigger';
const propTypes = {
triggerNode: PropTypes.node.isRequired,
initialRefreshFrequency: PropTypes.number,
onChange: PropTypes.func,
};
const defaultProps = {
initialRefreshFrequency: 0,
onChange: () => {},
refreshFrequency: PropTypes.number.isRequired,
onChange: PropTypes.func.isRequired,
};
const options = [
@ -51,7 +46,7 @@ class RefreshIntervalModal extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
refreshFrequency: props.initialRefreshFrequency,
refreshFrequency: props.refreshFrequency,
};
}
render() {
@ -81,6 +76,5 @@ class RefreshIntervalModal extends React.PureComponent {
}
}
RefreshIntervalModal.propTypes = propTypes;
RefreshIntervalModal.defaultProps = defaultProps;
export default RefreshIntervalModal;

View File

@ -41,6 +41,7 @@ const propTypes = {
onSave: PropTypes.func.isRequired,
isMenuItem: PropTypes.bool,
canOverwrite: PropTypes.bool.isRequired,
refreshFrequency: PropTypes.number.isRequired,
};
const defaultProps = {
@ -95,6 +96,7 @@ class SaveModal extends React.PureComponent {
expandedSlices,
filters,
dashboardId,
refreshFrequency,
} = this.props;
const data = {
@ -105,6 +107,7 @@ class SaveModal extends React.PureComponent {
saveType === SAVE_TYPE_NEWDASHBOARD ? newDashName : dashboardTitle,
default_filters: safeStringify(filters),
duplicate_slices: this.state.duplicateSlices,
refresh_frequency: refreshFrequency,
};
if (saveType === SAVE_TYPE_NEWDASHBOARD && !newDashName) {

View File

@ -34,6 +34,7 @@ import {
saveDashboardRequest,
setMaxUndoHistoryExceeded,
maxUndoHistoryToast,
setRefreshFrequency,
} from '../actions/dashboardState';
import {
@ -68,6 +69,7 @@ function mapStateToProps({
(undoableLayout.present[DASHBOARD_HEADER_ID] || {}).meta || {}
).text,
expandedSlices: dashboardState.expandedSlices,
refreshFrequency: dashboardState.refreshFrequency,
css: dashboardState.css,
charts,
userId: dashboardInfo.userId,
@ -101,6 +103,7 @@ function mapDispatchToProps(dispatch) {
setMaxUndoHistoryExceeded,
maxUndoHistoryToast,
logEvent,
setRefreshFrequency,
},
dispatch,
);

View File

@ -30,6 +30,7 @@ import {
TOGGLE_EXPAND_SLICE,
TOGGLE_FAVE_STAR,
UPDATE_CSS,
SET_REFRESH_FREQUENCY,
} from '../actions/dashboardState';
export default function dashboardStateReducer(state = {}, action) {
@ -147,6 +148,9 @@ export default function dashboardStateReducer(state = {}, action) {
const { hasUnsavedChanges } = action.payload;
return { ...state, hasUnsavedChanges };
},
[SET_REFRESH_FREQUENCY]() {
return { ...state, refreshFrequency: action.refreshFrequency };
},
};
if (action.type in actionHandlers) {

View File

@ -186,6 +186,7 @@ export default function(bootstrapData) {
refresh: false,
filters,
expandedSlices: dashboard.metadata.expanded_slices || {},
refreshFrequency: dashboard.metadata.refresh_frequency || 0,
css: dashboard.css || '',
editMode: dashboard.dash_edit_perm && editMode,
showBuilderPane: dashboard.dash_edit_perm && editMode,

View File

@ -1735,6 +1735,7 @@ class Superset(BaseSupersetView):
if 'filter_immune_slice_fields' not in md:
md['filter_immune_slice_fields'] = {}
md['expanded_slices'] = data['expanded_slices']
md['refresh_frequency'] = data.get('refresh_frequency', 0)
default_filters_data = json.loads(data.get('default_filters', '{}'))
applicable_filters = \
{key: v for key, v in default_filters_data.items()