diff --git a/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx b/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx index c7549855a..1c34a2304 100644 --- a/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx +++ b/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx @@ -72,6 +72,7 @@ function WidgetChart(props: Props) { useEffect(() => { return () => { + dashboardStore.setComparisonPeriod(null, _metric.metricId); dashboardStore.resetDrillDownFilter(); }; }, []); @@ -164,11 +165,11 @@ function WidgetChart(props: Props) { !isSaved ? drillDownPeriod : period ); }; - const loadComparisonData = () => { - if (!inView) return; - if (!dashboardStore.comparisonPeriod) return setCompData(null); - const timestamps = dashboardStore.comparisonPeriod.toTimestamps(); + const loadComparisonData = () => { + if (!dashboardStore.comparisonPeriods[_metric.metricId]) return setCompData(null); + + const timestamps = dashboardStore.comparisonPeriods[_metric.metricId].toTimestamps(); // TODO: remove after backend adds support for more view types const payload = { ...params, @@ -180,19 +181,15 @@ function WidgetChart(props: Props) { _metric, payload, isSaved, - dashboardStore.comparisonPeriod, + dashboardStore.comparisonPeriods[_metric.metricId], true ); }; useEffect(() => { - if (!dashboardStore.comparisonPeriod) { - setCompData(null); - return; - } + if (!inView || !props.isPreview) return; loadComparisonData(); - }, [dashboardStore.comparisonPeriod]); + }, [dashboardStore.comparisonPeriods[_metric.metricId], _metric.metricId, inView, props.isPreview]); useEffect(() => { - dashboardStore.setComparisonPeriod(null) setCompData(null); _metric.updateKey('page', 1); _metric.updateKey() @@ -282,6 +279,7 @@ function WidgetChart(props: Props) { chartData.namesMap = Array.isArray(chartData.namesMap) ? chartData.namesMap.map((n) => (enabledRows.includes(n) ? n : null)) : chartData.namesMap; + if (viewType === 'lineChart') { return (
diff --git a/frontend/app/components/Dashboard/components/WidgetDateRange/WidgetDateRange.tsx b/frontend/app/components/Dashboard/components/WidgetDateRange/WidgetDateRange.tsx index a3cc7023a..882983ae6 100644 --- a/frontend/app/components/Dashboard/components/WidgetDateRange/WidgetDateRange.tsx +++ b/frontend/app/components/Dashboard/components/WidgetDateRange/WidgetDateRange.tsx @@ -4,21 +4,26 @@ import { useStore } from 'App/mstore'; import { observer } from 'mobx-react-lite'; import { Space } from 'antd'; import RangeGranularity from "./RangeGranularity"; +import { + CUSTOM_RANGE, + DATE_RANGE_COMPARISON_OPTIONS, +} from 'App/dateRange'; +import Period from 'Types/app/period'; function WidgetDateRange({ - viewType = undefined, label = 'Time Range', hasGranularSettings = false, hasGranularity = false, hasComparison = false, + presetComparison = null, }: any) { - const { dashboardStore } = useStore(); + const { dashboardStore, metricStore } = useStore(); const density = dashboardStore.selectedDensity const onDensityChange = (density: number) => { dashboardStore.setDensity(density); } const period = dashboardStore.drillDownPeriod; - const compPeriod = dashboardStore.comparisonPeriod; + const compPeriod = dashboardStore.comparisonPeriods[metricStore.instance.metricId]; const drillDownFilter = dashboardStore.drillDownFilter; const onChangePeriod = (period: any) => { @@ -31,8 +36,7 @@ function WidgetDateRange({ }; const onChangeComparison = (period: any) => { - console.log(period) - dashboardStore.setComparisonPeriod(period); + dashboardStore.setComparisonPeriod(period, metricStore.instance.metricId); if (!period) return; const periodTimestamps = period.toTimestamps(); const compFilter = dashboardStore.cloneCompFilter(); @@ -42,6 +46,45 @@ function WidgetDateRange({ }); } + React.useEffect(() => { + if (presetComparison) { + const option = DATE_RANGE_COMPARISON_OPTIONS.find((option: any) => option.value === presetComparison[0]); + if (option) { + // @ts-ignore + const newPeriod = new Period({ + start: period.start, + end: period.end, + substract: option.value, + }); + setTimeout(() => { + onChangeComparison(newPeriod); + }, 1) + } else { + const day = 86400000; + const originalPeriodLength = Math.ceil( + (period.end - period.start) / day + ); + const start = presetComparison[0]; + const end = presetComparison[1] + originalPeriodLength * day; + + // @ts-ignore + const compRange = new Period({ + start, + end, + rangeName: CUSTOM_RANGE, + }); + setTimeout(() => { + onChangeComparison(compRange); + }, 1) + } + } + }, [presetComparison]) + + const updateInstComparison = (range: [start: string, end?: string] | null) => { + metricStore.instance.setComparisonRange(range); + metricStore.instance.updateKey('hasChanged', true) + } + return ( {label && {label}} @@ -70,6 +113,7 @@ function WidgetDateRange({ isAnt={true} useButtonStyle={true} comparison={true} + updateInstComparison={updateInstComparison} /> : null} diff --git a/frontend/app/components/Dashboard/components/WidgetPreview/WidgetPreview.tsx b/frontend/app/components/Dashboard/components/WidgetPreview/WidgetPreview.tsx index 4b481a9a7..14b43a187 100644 --- a/frontend/app/components/Dashboard/components/WidgetPreview/WidgetPreview.tsx +++ b/frontend/app/components/Dashboard/components/WidgetPreview/WidgetPreview.tsx @@ -22,6 +22,8 @@ function WidgetPreview(props: Props) { const hasGranularSettings = [TIMESERIES, FUNNEL].includes(metric.metricType) const hasGranularity = ['lineChart', 'barChart', 'areaChart'].includes(metric.viewType); const hasComparison = metric.metricType === FUNNEL || ['lineChart', 'barChart', 'table', 'progressChart'].includes(metric.viewType); + // [rangeStart, rangeEnd] or [period_name] -- have to check options + const presetComparison = metric.compareTo; return ( <>
diff --git a/frontend/app/components/shared/SelectDateRange/SelectDateRange.tsx b/frontend/app/components/shared/SelectDateRange/SelectDateRange.tsx index cb42f510e..8329b3c43 100644 --- a/frontend/app/components/shared/SelectDateRange/SelectDateRange.tsx +++ b/frontend/app/components/shared/SelectDateRange/SelectDateRange.tsx @@ -27,6 +27,7 @@ interface Props { compPeriod?: any | null; onChangeComparison?: (data: any) => void; comparison?: boolean; + updateInstComparison?: (range: [start: string, end?: string] | null) => void; [x: string]: any; } @@ -58,12 +59,16 @@ function SelectDateRange(props: Props) { return; } if (props.comparison && props.onChangeComparison) { - if (!value) return props.onChangeComparison(null); + if (!value) { + props.updateInstComparison?.(null) + return props.onChangeComparison(null); + } const newPeriod = new Period({ start: props.period.start, end: props.period.end, substract: value, }); + props.updateInstComparison?.([value]) props.onChangeComparison(newPeriod); return; } else { @@ -85,6 +90,7 @@ function SelectDateRange(props: Props) { end, rangeName: CUSTOM_RANGE, }); + props.updateInstComparison?.([start.toString(), end.toString()]) props.onChangeComparison(compRange); } else { const range = new Period({ diff --git a/frontend/app/components/shared/SessionFilters/SessionFilters.tsx b/frontend/app/components/shared/SessionFilters/SessionFilters.tsx index d09ec6333..7e3a4caca 100644 --- a/frontend/app/components/shared/SessionFilters/SessionFilters.tsx +++ b/frontend/app/components/shared/SessionFilters/SessionFilters.tsx @@ -21,12 +21,13 @@ function SessionFilters() { const metaLoading = customFieldStore.isLoading; const saveRequestPayloads = projectsStore.instance?.saveRequestPayloads ?? false; + const activeProject = projectsStore.active useEffect(() => { - if (searchStore.instance.filters.length === 0) { + if (searchStore.instance.filters.length === 0 && activeProject?.platform !== 'web') { searchStore.addFilterByKeyAndValue(FilterKey.LOCATION, '', 'isAny') } - }, []) + }, [projectsStore.activeSiteId, activeProject]) useSessionSearchQueryHandler({ appliedFilter, diff --git a/frontend/app/mstore/dashboardStore.ts b/frontend/app/mstore/dashboardStore.ts index 4c2edc59f..fab11f75d 100644 --- a/frontend/app/mstore/dashboardStore.ts +++ b/frontend/app/mstore/dashboardStore.ts @@ -25,7 +25,7 @@ export default class DashboardStore { comparisonFilter: Filter = new Filter(); drillDownPeriod: Record = Period({ rangeName: LAST_7_DAYS }); selectedDensity: number = 7 // depends on default drilldown, 7 points here!!!; - comparisonPeriod: Record | null = null + comparisonPeriods: Record = {} startTimestamp: number = 0; endTimestamp: number = 0; pendingRequests: number = 0; @@ -415,11 +415,11 @@ export default class DashboardStore { }); } - setComparisonPeriod(period: any) { + setComparisonPeriod(period: any, metricId: string) { if (!period) { - return this.comparisonPeriod = null + return this.comparisonPeriods[metricId] = null } - this.comparisonPeriod = Period({ + this.comparisonPeriods[metricId] = Period({ start: period.start, end: period.end, rangeName: period.rangeName, diff --git a/frontend/app/mstore/types/widget.ts b/frontend/app/mstore/types/widget.ts index 6a2cf667f..82a3fedf5 100644 --- a/frontend/app/mstore/types/widget.ts +++ b/frontend/app/mstore/types/widget.ts @@ -90,6 +90,7 @@ export default class Widget { startPoint: FilterItem = new FilterItem(filtersMap[FilterKey.LOCATION]); excludes: FilterItem[] = []; hideExcess?: boolean = false; + compareTo: [startDate?: string, endDate?: string] | null = null period: Record = Period({rangeName: LAST_24_HOURS}); // temp value in detail view hasChanged: boolean = false; @@ -102,7 +103,7 @@ export default class Widget { total: 0, values: [], chart: [], - namesMap: {}, + namesMap: [], avg: 0, percentiles: [] }; @@ -153,6 +154,7 @@ export default class Widget { this.metricFormat = json.metricFormat; this.viewType = json.viewType; this.name = json.name; + this.compareTo = json.compareTo || null; this.series = json.series && json.series.length > 0 ? json.series.map((series: any) => new FilterSeries().fromJson(series, this.metricType === HEATMAP)) @@ -227,6 +229,7 @@ export default class Widget { sessionId: this.data.sessionId, page: this.page, limit: this.limit, + compareTo: this.compareTo, config: { ...this.config, col: @@ -415,6 +418,10 @@ export default class Widget { } } + setComparisonRange(range: [start: string, end?: string] | null) { + this.compareTo = range; + } + fetchIssue(funnelId: any, issueId: any, params: any): Promise { return new Promise((resolve, reject) => {