diff --git a/superset-frontend/src/dashboard/components/Header/Header.test.tsx b/superset-frontend/src/dashboard/components/Header/Header.test.tsx index 2eb73091bcd82..4f8bf64f68cdb 100644 --- a/superset-frontend/src/dashboard/components/Header/Header.test.tsx +++ b/superset-frontend/src/dashboard/components/Header/Header.test.tsx @@ -37,7 +37,12 @@ const createProps = () => ({ userId: '1', metadata: {}, common: { - conf: {}, + conf: { + DASHBOARD_AUTO_REFRESH_INTERVALS: [ + [0, "Don't refresh"], + [10, '10 seconds'], + ], + }, }, }, user: { diff --git a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx index eb3c6aeb4e973..36a3e2cb2c380 100644 --- a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx +++ b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx @@ -38,7 +38,12 @@ const createProps = () => ({ userId: '1', metadata: {}, common: { - conf: {}, + conf: { + DASHBOARD_AUTO_REFRESH_INTERVALS: [ + [0, "Don't refresh"], + [10, '10 seconds'], + ], + }, }, }, dashboardTitle: 'Title', diff --git a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx index 3d25b049fba5b..eb20c57019519 100644 --- a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx +++ b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/index.jsx @@ -239,6 +239,9 @@ class HeaderActionsDropdown extends React.PureComponent { hash: window.location.hash, }); + const refreshIntervalOptions = + dashboardInfo.common?.conf?.DASHBOARD_AUTO_REFRESH_INTERVALS; + return ( <Menu selectable={false} data-test="header-actions-menu" {...rest}> {!editMode && ( @@ -386,6 +389,7 @@ class HeaderActionsDropdown extends React.PureComponent { refreshWarning={refreshWarning} onChange={this.changeRefreshInterval} editMode={editMode} + refreshIntervalOptions={refreshIntervalOptions} triggerNode={<span>{t('Set auto-refresh interval')}</span>} /> </Menu.Item> diff --git a/superset-frontend/src/dashboard/components/Header/index.jsx b/superset-frontend/src/dashboard/components/Header/index.jsx index 178f6da6eeb43..1a831b4822589 100644 --- a/superset-frontend/src/dashboard/components/Header/index.jsx +++ b/superset-frontend/src/dashboard/components/Header/index.jsx @@ -54,7 +54,6 @@ import { import setPeriodicRunner, { stopPeriodicRender, } from 'src/dashboard/util/setPeriodicRunner'; -import { options as PeriodicRefreshOptions } from 'src/dashboard/components/RefreshIntervalModal'; import { FILTER_BOX_MIGRATION_STATES } from 'src/explore/constants'; import { PageHeaderWithActions } from 'src/components/PageHeaderWithActions'; import { DashboardEmbedModal } from '../DashboardEmbedControls'; @@ -289,12 +288,17 @@ class Header extends React.PureComponent { startPeriodicRender(interval) { let intervalMessage; + if (interval) { - const predefinedValue = PeriodicRefreshOptions.find( - option => option.value === interval / 1000, + const { dashboardInfo } = this.props; + const periodicRefreshOptions = + dashboardInfo.common?.conf?.DASHBOARD_AUTO_REFRESH_INTERVALS; + const predefinedValue = periodicRefreshOptions.find( + option => Number(option[0]) === interval / 1000, ); + if (predefinedValue) { - intervalMessage = predefinedValue.label; + intervalMessage = t(predefinedValue[1]); } else { intervalMessage = moment.duration(interval, 'millisecond').humanize(); } diff --git a/superset-frontend/src/dashboard/components/RefreshIntervalModal.test.tsx b/superset-frontend/src/dashboard/components/RefreshIntervalModal.test.tsx index 9151275e800de..aad254d9ceb4c 100644 --- a/superset-frontend/src/dashboard/components/RefreshIntervalModal.test.tsx +++ b/superset-frontend/src/dashboard/components/RefreshIntervalModal.test.tsx @@ -41,6 +41,7 @@ describe('RefreshIntervalModal - Enzyme', () => { refreshFrequency: 10, onChange: jest.fn(), editMode: true, + refreshIntervalOptions: [], }; it('should show warning message', () => { const props = { @@ -78,7 +79,20 @@ const createProps = () => ({ userId: '1', metadata: {}, common: { - conf: {}, + conf: { + DASHBOARD_AUTO_REFRESH_INTERVALS: [ + [0, "Don't refresh"], + [10, '10 seconds'], + [30, '30 seconds'], + [60, '1 minute'], + [300, '5 minutes'], + [1800, '30 minutes'], + [3600, '1 hour'], + [21600, '6 hours'], + [43200, '12 hours'], + [86400, '24 hours'], + ], + }, }, }, dashboardTitle: 'Title', @@ -133,6 +147,7 @@ const defaultRefreshIntervalModalProps = { onChange: jest.fn(), editMode: true, addSuccessToast: jest.fn(), + refreshIntervalOptions: [], }; describe('RefreshIntervalModal - RTL', () => { diff --git a/superset-frontend/src/dashboard/components/RefreshIntervalModal.tsx b/superset-frontend/src/dashboard/components/RefreshIntervalModal.tsx index 98b763ed859b5..6299b09c539a6 100644 --- a/superset-frontend/src/dashboard/components/RefreshIntervalModal.tsx +++ b/superset-frontend/src/dashboard/components/RefreshIntervalModal.tsx @@ -26,19 +26,6 @@ import ModalTrigger, { ModalTriggerRef } from 'src/components/ModalTrigger'; import { FormLabel } from 'src/components/Form'; import { propertyComparator } from 'src/components/Select/utils'; -export const options = [ - [0, t("Don't refresh")], - [10, t('10 seconds')], - [30, t('30 seconds')], - [60, t('1 minute')], - [300, t('5 minutes')], - [1800, t('30 minutes')], - [3600, t('1 hour')], - [21600, t('6 hours')], - [43200, t('12 hours')], - [86400, t('24 hours')], -].map(o => ({ value: o[0] as number, label: o[1] })); - const StyledModalTrigger = styled(ModalTrigger)` .ant-modal-body { overflow: visible; @@ -57,6 +44,7 @@ type RefreshIntervalModalProps = { editMode: boolean; refreshLimit?: number; refreshWarning: string | null; + refreshIntervalOptions: [number, string][]; }; type RefreshIntervalModalState = { @@ -99,13 +87,19 @@ class RefreshIntervalModal extends React.PureComponent< } handleFrequencyChange(value: number) { + const { refreshIntervalOptions } = this.props; this.setState({ - refreshFrequency: value || options[0].value, + refreshFrequency: value || refreshIntervalOptions[0][0], }); } render() { - const { refreshLimit = 0, refreshWarning, editMode } = this.props; + const { + refreshLimit = 0, + refreshWarning, + editMode, + refreshIntervalOptions, + } = this.props; const { refreshFrequency = 0 } = this.state; const showRefreshWarning = !!refreshFrequency && !!refreshWarning && refreshFrequency < refreshLimit; @@ -120,7 +114,10 @@ class RefreshIntervalModal extends React.PureComponent< <FormLabel>{t('Refresh frequency')}</FormLabel> <Select ariaLabel={t('Refresh interval')} - options={options} + options={refreshIntervalOptions.map(option => ({ + value: option[0], + label: t(option[1]), + }))} value={refreshFrequency} onChange={this.handleFrequencyChange} sortComparator={propertyComparator('value')} diff --git a/superset/config.py b/superset/config.py index 64dc3baa125b5..cb63b519bac9c 100644 --- a/superset/config.py +++ b/superset/config.py @@ -761,6 +761,19 @@ def _try_json_readsha(filepath: str, length: int) -> Optional[str]: # Force refresh while auto-refresh in dashboard DASHBOARD_AUTO_REFRESH_MODE: Literal["fetch", "force"] = "force" +# Dashboard auto refresh intervals +DASHBOARD_AUTO_REFRESH_INTERVALS = [ + [0, "Don't refresh"], + [10, "10 seconds"], + [30, "30 seconds"], + [60, "1 minute"], + [300, "5 minutes"], + [1800, "30 minutes"], + [3600, "1 hour"], + [21600, "6 hours"], + [43200, "12 hours"], + [86400, "24 hours"], +] # Default celery config is to use SQLA as a broker, in a production setting # you'll want to use a proper broker as specified here: diff --git a/superset/views/base.py b/superset/views/base.py index cf7868eaf1c04..602e5fc31a75b 100644 --- a/superset/views/base.py +++ b/superset/views/base.py @@ -103,6 +103,7 @@ "SQLALCHEMY_DISPLAY_TEXT", "GLOBAL_ASYNC_QUERIES_WEBSOCKET_URL", "DASHBOARD_AUTO_REFRESH_MODE", + "DASHBOARD_AUTO_REFRESH_INTERVALS", "DASHBOARD_VIRTUALIZATION", "SCHEDULED_QUERIES", "EXCEL_EXTENSIONS",