This is an automated email from the ASF dual-hosted git repository. arivero pushed a commit to branch table-time-comparison-offset in repository https://gitbox.apache.org/repos/asf/superset.git
commit 97a8521c7cc35c396a67a544d4e422a27522cba9 Author: lilykuang <[email protected]> AuthorDate: Wed Apr 24 17:55:38 2024 -0700 custom and inherit start date --- .../src/sections/timeComparison.tsx | 4 + .../src/time-comparison/fetchTimeRange.ts | 10 ++- .../components/controls/ComparisonRangeLabel.tsx | 89 +++++++++++++++++----- .../components/controls/TimeOffsetControl.tsx | 20 ++++- 4 files changed, 98 insertions(+), 25 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/sections/timeComparison.tsx b/superset-frontend/packages/superset-ui-chart-controls/src/sections/timeComparison.tsx index 2b77c9c311..152f2d455b 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/sections/timeComparison.tsx +++ b/superset-frontend/packages/superset-ui-chart-controls/src/sections/timeComparison.tsx @@ -49,6 +49,8 @@ export const timeComparisonControls: ControlPanelSectionConfig = { ['2 years ago', t('2 years ago')], ['156 weeks ago', t('156 weeks ago')], ['3 years ago', t('3 years ago')], + ['custom', t('Custom')], + ['inherit', t('Inherit')], ], description: t( 'Overlay one or more timeseries from a ' + @@ -65,6 +67,8 @@ export const timeComparisonControls: ControlPanelSectionConfig = { config: { type: 'TimeOffsetControl', label: t('shift start date'), + visibility: ({ controls }) => + controls?.time_compare.value === 'custom', }, }, ], diff --git a/superset-frontend/packages/superset-ui-core/src/time-comparison/fetchTimeRange.ts b/superset-frontend/packages/superset-ui-core/src/time-comparison/fetchTimeRange.ts index 8dff2d9ac9..8a130e225e 100644 --- a/superset-frontend/packages/superset-ui-core/src/time-comparison/fetchTimeRange.ts +++ b/superset-frontend/packages/superset-ui-core/src/time-comparison/fetchTimeRange.ts @@ -64,10 +64,12 @@ export const fetchTimeRange = async ( let query; let endpoint; if (shifts && !isEmpty(shifts)) { - const timeRanges = shifts?.map(shift => ({ - timeRange, - shift, - })); + const timeRanges = (Array.isArray(shifts) ? shifts : [shifts])?.map( + shift => ({ + timeRange, + shift, + }), + ); query = rison.encode_uri([{ timeRange }, ...timeRanges]); endpoint = `/api/v1/time_range/?q=${query}`; } else { diff --git a/superset-frontend/src/explore/components/controls/ComparisonRangeLabel.tsx b/superset-frontend/src/explore/components/controls/ComparisonRangeLabel.tsx index 616cb1698d..18a2e3186a 100644 --- a/superset-frontend/src/explore/components/controls/ComparisonRangeLabel.tsx +++ b/superset-frontend/src/explore/components/controls/ComparisonRangeLabel.tsx @@ -20,7 +20,7 @@ import React, { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; import { isEmpty, isEqual } from 'lodash'; -import moment from 'moment'; +import moment, { Moment } from 'moment'; import { BinaryAdhocFilter, css, @@ -42,6 +42,52 @@ type ComparisonRangeLabelProps = ControlHeaderProps & { multi?: boolean; }; +const dttmToMoment = (dttm: string): Moment => { + if (dttm === 'now') { + return moment().utc().startOf('second'); + } + if (dttm === 'today' || dttm === 'No filter') { + return moment().utc().startOf('day'); + } + if (dttm === 'Last week') { + return moment().utc().startOf('day').subtract(7, 'day'); + } + if (dttm === 'Last month') { + return moment().utc().startOf('day').subtract(1, 'month'); + } + if (dttm === 'Last quarter') { + return moment().utc().startOf('day').subtract(1, 'quarter'); + } + if (dttm === 'Last year') { + return moment().utc().startOf('day').subtract(1, 'year'); + } + if (dttm === 'previous calendar week') { + return moment().utc().subtract(1, 'weeks').startOf('isoWeek'); + } + if (dttm === 'previous calendar month') { + return moment().utc().subtract(1, 'months').startOf('month'); + } + if (dttm === 'previous calendar year') { + return moment().utc().subtract(1, 'years').startOf('year'); + } + if (dttm.includes('ago')) { + const parts = dttm.split(' '); + const amount = parseInt(parts[0], 10); + const unit = parts[1] as + | 'day' + | 'week' + | 'month' + | 'year' + | 'days' + | 'weeks' + | 'months' + | 'years'; + return moment().utc().subtract(amount, unit); + } + + return moment(dttm); +}; + export const ComparisonRangeLabel = ({ multi = true, }: ComparisonRangeLabelProps) => { @@ -57,6 +103,7 @@ export const ComparisonRangeLabel = ({ const shifts = useSelector<RootState, string[]>( state => state.explore.form_data.time_compare, ); + console.log('lily shifts', shifts); const startDate = useSelector<RootState, string>( state => state.explore.form_data.start_date_offset, ); @@ -65,26 +112,32 @@ export const ComparisonRangeLabel = ({ if (isEmpty(currentTimeRangeFilters) || (isEmpty(shifts) && !startDate)) { setLabels([]); } else if (!isEmpty(shifts) || startDate) { + const isCustom = shifts?.includes('custom'); + const isInherit = shifts?.includes('inherit'); const promises = currentTimeRangeFilters.map(filter => { - const startDateShift = - startDate && - moment((filter as any).comparator.split(' : ')[0]).diff( - moment(startDate), + const customStartDate = isCustom && startDate; + const customShift = + customStartDate && + moment(dttmToMoment((filter as any).comparator.split(' : ')[0])).diff( + moment(customStartDate), + 'days', + ) + 1; + + const inInheritShift = + isInherit && + moment(dttmToMoment((filter as any).comparator.split(' : ')[0])).diff( + moment(dttmToMoment((filter as any).comparator.split(' : ')[1])), 'days', - ); - const newshift = startDateShift - ? [`${startDateShift} days ago`] - : shifts - ? Array.isArray(shifts) - ? shifts - : [shifts] - : undefined; + ) + 1; + let newShifts = shifts; + if (isCustom) { + newShifts = [`${customShift} days ago`]; + } + if (isInherit) { + newShifts = [`${inInheritShift} days ago`]; + } - return fetchTimeRange( - filter.comparator, - filter.subject, - multi ? shifts : newshift, - ); + return fetchTimeRange(filter.comparator, filter.subject, newShifts); }); Promise.all(promises).then(res => { // access the value property inside the res and set the labels with it in the state diff --git a/superset-frontend/src/explore/components/controls/TimeOffsetControl.tsx b/superset-frontend/src/explore/components/controls/TimeOffsetControl.tsx index b3f8892ad1..c0767bf8c4 100644 --- a/superset-frontend/src/explore/components/controls/TimeOffsetControl.tsx +++ b/superset-frontend/src/explore/components/controls/TimeOffsetControl.tsx @@ -64,6 +64,20 @@ const dttmToMoment = (dttm: string): Moment => { if (dttm === 'previous calendar year') { return moment().utc().subtract(1, 'years').startOf('year'); } + if (dttm.includes('ago')) { + const parts = dttm.split(' '); + const amount = parseInt(parts[0], 10); + const unit = parts[1] as + | 'day' + | 'week' + | 'month' + | 'year' + | 'days' + | 'weeks' + | 'months' + | 'years'; + return moment().utc().subtract(amount, unit); + } return moment(dttm); }; @@ -84,11 +98,10 @@ export default function TimeOffsetControls({ ), isTimeRangeEqual, ); + const startDate = currentTimeRangeFilters[0]?.comparator.split(' : ')[0]; - const formatedDate = startDate - ? dttmToMoment(startDate) - : dttmToMoment('now'); + const formatedDate = dttmToMoment(startDate); const disabledDate: RangePickerProps['disabledDate'] = current => current && current >= formatedDate; @@ -106,6 +119,7 @@ export default function TimeOffsetControls({ startDate ? moment(formatedDate).subtract(1, 'day') : undefined } disabledDate={disabledDate} + defaultValue={formatedDate} /> </div> );
