feat(widget-sessions): improve session filtering logic
- Refactored session filtering logic to handle nested filters properly. - Enhanced `fetchSessions` to ensure null checks and avoid errors. - Updated `loadData` to handle `USER_PATH` and `HEATMAP` metric types. - Improved UI consistency by adjusting spacing and formatting. - Replaced redundant code with cleaner, more maintainable patterns. This change improves the reliability and readability of the session filtering and loading logic in the WidgetSessions component.
This commit is contained in:
parent
dcd19e3c83
commit
3f1f6c03f2
1 changed files with 353 additions and 334 deletions
|
|
@ -1,33 +1,33 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { NoContent, Loader, Pagination } from 'UI';
|
||||
import { Button, Tag, Tooltip, Dropdown, message } from 'antd';
|
||||
import { UndoOutlined, DownOutlined } from '@ant-design/icons';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {NoContent, Loader, Pagination} from 'UI';
|
||||
import {Button, Tag, Tooltip, Dropdown, message} from 'antd';
|
||||
import {UndoOutlined, DownOutlined} from '@ant-design/icons';
|
||||
import cn from 'classnames';
|
||||
import { useStore } from 'App/mstore';
|
||||
import {useStore} from 'App/mstore';
|
||||
import SessionItem from 'Shared/SessionItem';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { DateTime } from 'luxon';
|
||||
import { debounce, numberWithCommas } from 'App/utils';
|
||||
import {observer} from 'mobx-react-lite';
|
||||
import {DateTime} from 'luxon';
|
||||
import {debounce, numberWithCommas} from 'App/utils';
|
||||
import useIsMounted from 'App/hooks/useIsMounted';
|
||||
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
||||
import { HEATMAP, USER_PATH, FUNNEL } from 'App/constants/card';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import AnimatedSVG, {ICONS} from 'Shared/AnimatedSVG/AnimatedSVG';
|
||||
import {HEATMAP, USER_PATH, FUNNEL} from 'App/constants/card';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function WidgetSessions(props: Props) {
|
||||
const { t } = useTranslation();
|
||||
const {t} = useTranslation();
|
||||
const listRef = React.useRef<HTMLDivElement>(null);
|
||||
const { className = '' } = props;
|
||||
const {className = ''} = props;
|
||||
const [activeSeries, setActiveSeries] = useState('all');
|
||||
const [data, setData] = useState<any>([]);
|
||||
const isMounted = useIsMounted();
|
||||
const [loading, setLoading] = useState(false);
|
||||
// all filtering done through series now
|
||||
const filteredSessions = getListSessionsBySeries(data, 'all');
|
||||
const { dashboardStore, metricStore, sessionStore, customFieldStore } =
|
||||
const {dashboardStore, metricStore, sessionStore, customFieldStore} =
|
||||
useStore();
|
||||
const focusedSeries = metricStore.focusedSeriesName;
|
||||
const filter = dashboardStore.drillDownFilter;
|
||||
|
|
@ -39,7 +39,7 @@ function WidgetSessions(props: Props) {
|
|||
'LLL dd, yyyy HH:mm',
|
||||
);
|
||||
const [seriesOptions, setSeriesOptions] = useState([
|
||||
{ label: t('All'), value: 'all' },
|
||||
{label: t('All'), value: 'all'},
|
||||
]);
|
||||
const hasFilters =
|
||||
filter.filters.length > 0 ||
|
||||
|
|
@ -61,13 +61,12 @@ function WidgetSessions(props: Props) {
|
|||
label: item.name,
|
||||
value: item.seriesId ?? item.name,
|
||||
}));
|
||||
setSeriesOptions([{ label: t('All'), value: 'all' }, ...seriesOptions]);
|
||||
setSeriesOptions([{label: t('All'), value: 'all'}, ...seriesOptions]);
|
||||
}, [widget.series.length]);
|
||||
|
||||
const fetchSessions = (metricId: any, filter: any) => {
|
||||
if (!isMounted()) return;
|
||||
setLoading(true);
|
||||
delete filter.eventsOrderSupport;
|
||||
|
||||
if (widget.metricType === FUNNEL) {
|
||||
if (filter.series[0].filter.filters.length === 0) {
|
||||
setLoading(false);
|
||||
|
|
@ -75,14 +74,34 @@ function WidgetSessions(props: Props) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
setLoading(true);
|
||||
const filterCopy = {...filter};
|
||||
delete filterCopy.eventsOrderSupport;
|
||||
|
||||
try {
|
||||
// Handle filters properly with null checks
|
||||
if (filterCopy.filters && filterCopy.filters.length > 0) {
|
||||
// Ensure the nested path exists before pushing
|
||||
if (filterCopy.series?.[0]?.filter) {
|
||||
if (!filterCopy.series[0].filter.filters) {
|
||||
filterCopy.series[0].filter.filters = [];
|
||||
}
|
||||
filterCopy.series[0].filter.filters.push(...filterCopy.filters);
|
||||
}
|
||||
filterCopy.filters = [];
|
||||
}
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
}
|
||||
widget
|
||||
.fetchSessions(metricId, filter)
|
||||
.fetchSessions(metricId, filterCopy)
|
||||
.then((res: any) => {
|
||||
setData(res);
|
||||
if (metricStore.drillDown) {
|
||||
setTimeout(() => {
|
||||
message.info(t('Sessions Refreshed!'));
|
||||
listRef.current?.scrollIntoView({ behavior: 'smooth' });
|
||||
listRef.current?.scrollIntoView({behavior: 'smooth'});
|
||||
metricStore.setDrillDown(false);
|
||||
}, 0);
|
||||
}
|
||||
|
|
@ -93,7 +112,7 @@ function WidgetSessions(props: Props) {
|
|||
};
|
||||
const fetchClickmapSessions = (customFilters: Record<string, any>) => {
|
||||
sessionStore.getSessions(customFilters).then((data) => {
|
||||
setData([{ ...data, seriesId: 1, seriesName: 'Clicks' }]);
|
||||
setData([{...data, seriesId: 1, seriesName: 'Clicks'}]);
|
||||
});
|
||||
};
|
||||
const debounceRequest: any = React.useCallback(
|
||||
|
|
@ -235,7 +254,7 @@ function WidgetSessions(props: Props) {
|
|||
{hasFilters && (
|
||||
<Tooltip title={t('Clear Drilldown')} placement="top">
|
||||
<Button type="text" size="small" onClick={clearFilters}>
|
||||
<UndoOutlined />
|
||||
<UndoOutlined/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
|
@ -271,7 +290,7 @@ function WidgetSessions(props: Props) {
|
|||
<Button type="text" size="small">
|
||||
{seriesOptions.find((option) => option.value === activeSeries)
|
||||
?.label || t('Select Series')}
|
||||
<DownOutlined />
|
||||
<DownOutlined/>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
|
@ -284,8 +303,8 @@ function WidgetSessions(props: Props) {
|
|||
<NoContent
|
||||
title={
|
||||
<div className="flex items-center justify-center flex-col">
|
||||
<AnimatedSVG name={ICONS.NO_SESSIONS} size={60} />
|
||||
<div className="mt-4" />
|
||||
<AnimatedSVG name={ICONS.NO_SESSIONS} size={60}/>
|
||||
<div className="mt-4"/>
|
||||
<div className="text-center">
|
||||
{t('No relevant sessions found for the selected time period')}
|
||||
</div>
|
||||
|
|
@ -300,7 +319,7 @@ function WidgetSessions(props: Props) {
|
|||
session={session}
|
||||
metaList={metaList}
|
||||
/>
|
||||
<div className="border-b" />
|
||||
<div className="border-b"/>
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
|
|
@ -364,7 +383,7 @@ const getListSessionsBySeries = (data: any, seriesId: any) => {
|
|||
}
|
||||
return arr;
|
||||
},
|
||||
{ sessions: [] },
|
||||
{sessions: []},
|
||||
);
|
||||
arr.total =
|
||||
seriesId === 'all'
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue