diff --git a/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts b/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts index fb1b68caec4..8c9d3e7b3f3 100644 --- a/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts +++ b/superset-frontend/cypress-base/cypress/integration/explore/control.test.ts @@ -177,8 +177,7 @@ describe('Time range filter', () => { ...FORM_DATA_DEFAULTS, metrics: [NUM_METRIC], viz_type: 'line', - time_range: - 'DATETRUNC(DATEADD(DATETIME("TODAY"), -1, MONTH), MONTH) : LASTDAY(DATEADD(DATETIME("TODAY"), -1, MONTH), MONTH)', + time_range: 'previous calendar month', }; cy.visitChartByParams(JSON.stringify(formData)); diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterControl.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterControl.tsx index bc0af3c108d..5bf3d8f6898 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterControl.tsx +++ b/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterControl.tsx @@ -183,15 +183,25 @@ export default function DateFilterControl(props: DateFilterLabelProps) { const [evalResponse, setEvalResponse] = useState(value); useEffect(() => { - fetchTimeRange(value, endpoints).then(({ value, error }) => { - if (error) { - setEvalResponse(error || ''); - setValidTimeRange(false); - } else { - setActualTimeRange(value || ''); - setValidTimeRange(true); - } - }); + const valueToLower = value.toLowerCase(); + if ( + valueToLower.startsWith('last') || + valueToLower.startsWith('next') || + valueToLower.startsWith('previous') + ) { + setActualTimeRange(value); + setValidTimeRange(true); + } else { + fetchTimeRange(value, endpoints).then(({ value, error }) => { + if (error) { + setEvalResponse(error || ''); + setValidTimeRange(false); + } else { + setActualTimeRange(value || ''); + setValidTimeRange(true); + } + }); + } }, [value]); useEffect(() => { diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/types.ts b/superset-frontend/src/explore/components/controls/DateFilterControl/types.ts index 7e43615729a..5b264b99ef8 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl/types.ts +++ b/superset-frontend/src/explore/components/controls/DateFilterControl/types.ts @@ -77,12 +77,9 @@ export type CommonRangeType = | 'Last quarter' | 'Last year'; -export const PreviousCalendarWeek = - 'DATETRUNC(DATEADD(DATETIME("TODAY"), -1, WEEK), WEEK) : LASTDAY(DATEADD(DATETIME("TODAY"), -1, WEEK), WEEK)'; -export const PreviousCalendarMonth = - 'DATETRUNC(DATEADD(DATETIME("TODAY"), -1, MONTH), MONTH) : LASTDAY(DATEADD(DATETIME("TODAY"), -1, MONTH), MONTH)'; -export const PreviousCalendarYear = - 'DATETRUNC(DATEADD(DATETIME("TODAY"), -1, YEAR), YEAR) : LASTDAY(DATEADD(DATETIME("TODAY"), -1, YEAR), YEAR)'; +export const PreviousCalendarWeek = 'previous calendar week'; +export const PreviousCalendarMonth = 'previous calendar month'; +export const PreviousCalendarYear = 'previous calendar year'; export type CalendarRangeType = | typeof PreviousCalendarWeek | typeof PreviousCalendarMonth diff --git a/superset/utils/core.py b/superset/utils/core.py index a353fa86f08..3723a4c80d8 100644 --- a/superset/utils/core.py +++ b/superset/utils/core.py @@ -1497,6 +1497,25 @@ def get_since_until( if time_range and time_range.startswith("Next") and separator not in time_range: time_range = _relative_start + separator + time_range + if ( + time_range + and time_range.startswith("previous calendar week") + and separator not in time_range + ): + time_range = "DATETRUNC(DATEADD(DATETIME('today'), -1, WEEK), WEEK) : LASTDAY(DATEADD(DATETIME('today'), -1, WEEK), WEEK)" # pylint: disable=line-too-long + if ( + time_range + and time_range.startswith("previous calendar month") + and separator not in time_range + ): + time_range = "DATETRUNC(DATEADD(DATETIME('today'), -1, MONTH), MONTH) : LASTDAY(DATEADD(DATETIME('today'), -1, MONTH), MONTH)" # pylint: disable=line-too-long + if ( + time_range + and time_range.startswith("previous calendar year") + and separator not in time_range + ): + time_range = "DATETRUNC(DATEADD(DATETIME('today'), -1, YEAR), YEAR) : LASTDAY(DATEADD(DATETIME('today'), -1, YEAR), YEAR)" # pylint: disable=line-too-long + if time_range and separator in time_range: time_range_lookup = [ ( diff --git a/tests/utils_tests.py b/tests/utils_tests.py index bed3fa02a12..98f70ba95d0 100644 --- a/tests/utils_tests.py +++ b/tests/utils_tests.py @@ -761,6 +761,18 @@ class TestUtils(SupersetTestCase): expected = datetime(2016, 10, 31, 9, 30, 10), datetime(2016, 11, 7, 9, 30, 10) self.assertEqual(result, expected) + result = get_since_until("previous calendar week") + expected = datetime(2016, 10, 31, 0, 0, 0), datetime(2016, 11, 6, 0, 0, 0) + self.assertEqual(result, expected) + + result = get_since_until("previous calendar month") + expected = datetime(2016, 10, 1, 0, 0, 0), datetime(2016, 10, 31, 0, 0, 0) + self.assertEqual(result, expected) + + result = get_since_until("previous calendar year") + expected = datetime(2015, 1, 1, 0, 0, 0), datetime(2015, 12, 31, 0, 0, 0) + self.assertEqual(result, expected) + with self.assertRaises(ValueError): get_since_until(time_range="tomorrow : yesterday")