fix(ui): sessions list sidemenu fix, reload properly, sessions tags filter issue
This commit is contained in:
parent
44d0bb1369
commit
beb3eeac0c
11 changed files with 113 additions and 202 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import withPageTitle from 'HOCs/withPageTitle';
|
import withPageTitle from 'HOCs/withPageTitle';
|
||||||
import NoSessionsMessage from 'Shared/NoSessionsMessage';
|
import NoSessionsMessage from 'Shared/NoSessionsMessage';
|
||||||
import MainSearchBar from 'Shared/MainSearchBar';
|
import MainSearchBar from 'Shared/MainSearchBar';
|
||||||
|
|
@ -8,9 +8,10 @@ import FFlagsList from 'Components/FFlags';
|
||||||
import NewFFlag from 'Components/FFlags/NewFFlag';
|
import NewFFlag from 'Components/FFlags/NewFFlag';
|
||||||
import { Switch, Route } from 'react-router';
|
import { Switch, Route } from 'react-router';
|
||||||
import { sessions, fflags, withSiteId, newFFlag, fflag, notes, fflagRead, bookmarks } from 'App/routes';
|
import { sessions, fflags, withSiteId, newFFlag, fflag, notes, fflagRead, bookmarks } from 'App/routes';
|
||||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
import { withRouter, RouteComponentProps, useLocation } from 'react-router-dom';
|
||||||
import FlagView from 'Components/FFlags/FlagView/FlagView';
|
import FlagView from 'Components/FFlags/FlagView/FlagView';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
|
import { useStore } from '@/mstore';
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
interface IProps extends RouteComponentProps {
|
interface IProps extends RouteComponentProps {
|
||||||
|
|
@ -23,7 +24,16 @@ interface IProps extends RouteComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
function Overview({ match: { params } }: IProps) {
|
function Overview({ match: { params } }: IProps) {
|
||||||
|
const { searchStore } = useStore();
|
||||||
const { siteId, fflagId } = params;
|
const { siteId, fflagId } = params;
|
||||||
|
const location = useLocation();
|
||||||
|
const tab = location.pathname.split('/')[2];
|
||||||
|
searchStore.setActiveTab(tab);
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// // const tab = location.pathname.split('/')[2];
|
||||||
|
// searchStore.setActiveTab(tab);
|
||||||
|
// }, [tab]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<Switch>
|
||||||
|
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { SideMenuitem } from 'UI';
|
|
||||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
|
||||||
import { sessions, fflags, withSiteId, notes, bookmarks } from 'App/routes';
|
|
||||||
import { useStore } from 'App/mstore';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
activeTab: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TabToUrlMap = {
|
|
||||||
all: sessions() as '/sessions',
|
|
||||||
bookmark: bookmarks() as '/bookmarks',
|
|
||||||
notes: notes() as '/notes',
|
|
||||||
flags: fflags() as '/feature-flags'
|
|
||||||
};
|
|
||||||
|
|
||||||
function OverviewMenu(props: Props & RouteComponentProps) {
|
|
||||||
// @ts-ignore
|
|
||||||
const { history, match: { params: { siteId } }, location } = props;
|
|
||||||
const { searchStore, userStore } = useStore();
|
|
||||||
const isEnterprise = userStore.isEnterprise;
|
|
||||||
const activeTab = searchStore.activeTab.type;
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const currentLocation = location.pathname;
|
|
||||||
const tab = Object.keys(TabToUrlMap).find((tab: keyof typeof TabToUrlMap) => currentLocation.includes(TabToUrlMap[tab]));
|
|
||||||
if (tab && tab !== activeTab) {
|
|
||||||
searchStore.setActiveTab({ type: tab });
|
|
||||||
}
|
|
||||||
}, [location.pathname]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={'flex flex-col gap-2 w-full'}>
|
|
||||||
<div className="w-full">
|
|
||||||
<SideMenuitem
|
|
||||||
active={activeTab === 'all'}
|
|
||||||
id="menu-sessions"
|
|
||||||
title="Sessions"
|
|
||||||
iconName="play-circle-bold"
|
|
||||||
onClick={() => {
|
|
||||||
searchStore.setActiveTab({ type: 'all' });
|
|
||||||
!location.pathname.includes(sessions()) && history.push(withSiteId(sessions(), siteId));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="w-full">
|
|
||||||
<SideMenuitem
|
|
||||||
active={activeTab === 'bookmark'}
|
|
||||||
id="menu-bookmarks"
|
|
||||||
title={`${isEnterprise ? 'Vault' : 'Bookmarks'}`}
|
|
||||||
iconName={isEnterprise ? 'safe' : 'star'}
|
|
||||||
onClick={() => {
|
|
||||||
// props.setActiveTab({ type: 'bookmark' });
|
|
||||||
!location.pathname.includes(bookmarks()) && history.push(withSiteId(bookmarks(), siteId));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="w-full">
|
|
||||||
<SideMenuitem
|
|
||||||
active={activeTab === 'notes'}
|
|
||||||
id="menu-notes"
|
|
||||||
title="Notes"
|
|
||||||
iconName="stickies"
|
|
||||||
onClick={() => {
|
|
||||||
searchStore.setActiveTab({ type: 'notes' });
|
|
||||||
!location.pathname.includes(notes()) && history.push(withSiteId(notes(), siteId));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="w-full">
|
|
||||||
<SideMenuitem
|
|
||||||
active={activeTab === 'flags'}
|
|
||||||
id="menu-flags"
|
|
||||||
title="Feature Flags"
|
|
||||||
iconName="toggles"
|
|
||||||
onClick={() => {
|
|
||||||
searchStore.setActiveTab({ type: 'flags' });
|
|
||||||
!location.pathname.includes(fflags()) && history.push(withSiteId(fflags(), siteId));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default withRouter(OverviewMenu);
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export { default } from './OverviewMenu';
|
|
||||||
|
|
@ -47,7 +47,7 @@ function SessionSearch(props: Props) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
debounceFetch = debounce(() => searchStore.fetchSessions(), 500);
|
debounceFetch = debounce(() => searchStore.fetchSessions(), 500);
|
||||||
void searchStore.fetchSessions(true)
|
// void searchStore.fetchSessions(true)
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onAddFilter = (filter: any) => {
|
const onAddFilter = (filter: any) => {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ function SessionsTabOverview() {
|
||||||
const [query, setQuery] = React.useState('');
|
const [query, setQuery] = React.useState('');
|
||||||
const { aiFiltersStore, searchStore } = useStore();
|
const { aiFiltersStore, searchStore } = useStore();
|
||||||
const appliedFilter = searchStore.instance;
|
const appliedFilter = searchStore.instance;
|
||||||
const activeTab = searchStore.activeTab.type;
|
const isNotesRoute = searchStore.activeTab.type === 'notes';
|
||||||
|
|
||||||
const handleKeyDown = (event: any) => {
|
const handleKeyDown = (event: any) => {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
|
|
@ -38,7 +38,7 @@ function SessionsTabOverview() {
|
||||||
<SessionHeader />
|
<SessionHeader />
|
||||||
<div className="border-b" />
|
<div className="border-b" />
|
||||||
<LatestSessionsMessage />
|
<LatestSessionsMessage />
|
||||||
{activeTab !== 'notes' ? (
|
{!isNotesRoute ? (
|
||||||
<SessionList />
|
<SessionList />
|
||||||
) : (
|
) : (
|
||||||
<NotesList />
|
<NotesList />
|
||||||
|
|
|
||||||
|
|
@ -20,16 +20,16 @@ function SessionHeader() {
|
||||||
if (activeTab.type === 'notes') {
|
if (activeTab.type === 'notes') {
|
||||||
return 'Notes';
|
return 'Notes';
|
||||||
}
|
}
|
||||||
if (activeTab.type === 'bookmark') {
|
if (activeTab.type === 'bookmarks') {
|
||||||
return isEnterprise ? 'Vault' : 'Bookmarks';
|
return isEnterprise ? 'Vault' : 'Bookmarks';
|
||||||
}
|
}
|
||||||
return 'Sessions';
|
return 'Sessions';
|
||||||
}, [activeTab]);
|
}, [activeTab.type, isEnterprise]);
|
||||||
|
|
||||||
const onDateChange = (e: any) => {
|
const onDateChange = (e: any) => {
|
||||||
const dateValues = e.toJSON();
|
const dateValues = e.toJSON();
|
||||||
searchStore.edit(dateValues);
|
searchStore.edit(dateValues);
|
||||||
searchStore.fetchSessions();
|
void searchStore.fetchSessions(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -37,7 +37,7 @@ function SessionHeader() {
|
||||||
<h2 className="text-2xl capitalize mr-4">{title}</h2>
|
<h2 className="text-2xl capitalize mr-4">{title}</h2>
|
||||||
{activeTab.type !== 'notes' ? (
|
{activeTab.type !== 'notes' ? (
|
||||||
<div className="flex items-center w-full justify-end">
|
<div className="flex items-center w-full justify-end">
|
||||||
{activeTab.type !== 'bookmark' && (
|
{activeTab.type !== 'bookmarks' && (
|
||||||
<>
|
<>
|
||||||
<SessionTags />
|
<SessionTags />
|
||||||
<div className="mr-auto" />
|
<div className="mr-auto" />
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
|
||||||
import { FilterKey } from 'Types/filter/filterType';
|
import { FilterKey } from 'Types/filter/filterType';
|
||||||
import SessionItem from 'Shared/SessionItem';
|
import SessionItem from 'Shared/SessionItem';
|
||||||
import { NoContent, Loader, Pagination, Button } from 'UI';
|
import { NoContent, Loader, Pagination, Button } from 'UI';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { useLocation, withRouter } from 'react-router-dom';
|
||||||
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
||||||
import { numberWithCommas } from 'App/utils';
|
import { numberWithCommas } from 'App/utils';
|
||||||
import SessionDateRange from './SessionDateRange';
|
import SessionDateRange from './SessionDateRange';
|
||||||
|
|
@ -23,6 +23,10 @@ let sessionStatusTimeOut: any = null;
|
||||||
const STATUS_FREQUENCY = 5000;
|
const STATUS_FREQUENCY = 5000;
|
||||||
|
|
||||||
function SessionList() {
|
function SessionList() {
|
||||||
|
const location = useLocation(); // Get the current URL location
|
||||||
|
const isSessionsRoute = location.pathname.includes('/sessions');
|
||||||
|
const isBookmark = location.pathname.includes('/bookmarks');
|
||||||
|
|
||||||
const { projectsStore, sessionStore, customFieldStore, userStore } = useStore();
|
const { projectsStore, sessionStore, customFieldStore, userStore } = useStore();
|
||||||
const isEnterprise = userStore.isEnterprise;
|
const isEnterprise = userStore.isEnterprise;
|
||||||
const isLoggedIn = userStore.isLoggedIn;
|
const isLoggedIn = userStore.isLoggedIn;
|
||||||
|
|
@ -39,12 +43,17 @@ function SessionList() {
|
||||||
const _filterKeys = filters.map((i: any) => i.key);
|
const _filterKeys = filters.map((i: any) => i.key);
|
||||||
const hasUserFilter =
|
const hasUserFilter =
|
||||||
_filterKeys.includes(FilterKey.USERID) || _filterKeys.includes(FilterKey.USERANONYMOUSID);
|
_filterKeys.includes(FilterKey.USERID) || _filterKeys.includes(FilterKey.USERANONYMOUSID);
|
||||||
const isBookmark = activeTab.type === 'bookmark';
|
// const isBookmark = activeTab.type === 'bookmark';
|
||||||
const isVault = isBookmark && isEnterprise;
|
const isVault = isBookmark && isEnterprise;
|
||||||
const activeSite = projectsStore.active;
|
const activeSite = projectsStore.active;
|
||||||
const hasNoRecordings = !activeSite || !activeSite.recorded;
|
const hasNoRecordings = !activeSite || !activeSite.recorded;
|
||||||
const metaList = customFieldStore.list;
|
const metaList = customFieldStore.list;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
void searchStore.fetchSessions(true, isBookmark);
|
||||||
|
}, [location.pathname]);
|
||||||
|
|
||||||
|
|
||||||
const NO_CONTENT = React.useMemo(() => {
|
const NO_CONTENT = React.useMemo(() => {
|
||||||
if (isBookmark && !isEnterprise) {
|
if (isBookmark && !isEnterprise) {
|
||||||
return {
|
return {
|
||||||
|
|
@ -61,7 +70,7 @@ function SessionList() {
|
||||||
icon: ICONS.NO_SESSIONS,
|
icon: ICONS.NO_SESSIONS,
|
||||||
message: <SessionDateRange />
|
message: <SessionDateRange />
|
||||||
};
|
};
|
||||||
}, [isBookmark, isVault, activeTab]);
|
}, [isBookmark, isVault, activeTab, location.pathname]);
|
||||||
const [statusData, setStatusData] = React.useState<SessionStatus>({ status: 0, count: 0 });
|
const [statusData, setStatusData] = React.useState<SessionStatus>({ status: 0, count: 0 });
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -101,11 +110,11 @@ function SessionList() {
|
||||||
}
|
}
|
||||||
}, [statusData, siteId]);
|
}, [statusData, siteId]);
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (siteId) {
|
// if (siteId) {
|
||||||
void searchStore.fetchSessions();
|
// void searchStore.fetchSessions();
|
||||||
}
|
// }
|
||||||
}, [siteId])
|
// }, [siteId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const id = setInterval(() => {
|
const id = setInterval(() => {
|
||||||
|
|
@ -121,11 +130,11 @@ function SessionList() {
|
||||||
const { scrollY } = searchStore;
|
const { scrollY } = searchStore;
|
||||||
window.scrollTo(0, scrollY);
|
window.scrollTo(0, scrollY);
|
||||||
|
|
||||||
if (total === 0 && !loading && !hasNoRecordings) {
|
// if (total === 0 && !loading && !hasNoRecordings) {
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
void searchStore.fetchSessions();
|
// void searchStore.fetchSessions();
|
||||||
}, 100);
|
// }, 100);
|
||||||
}
|
// }
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
searchStore.setScrollPosition(window.scrollY);
|
searchStore.setScrollPosition(window.scrollY);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
import { issues_types, types } from 'Types/session/issue';
|
import { issues_types, types } from 'Types/session/issue';
|
||||||
import { Segmented } from 'antd';
|
import { Segmented } from 'antd';
|
||||||
import cn from 'classnames';
|
|
||||||
import { Angry, CircleAlert, Skull, WifiOff } from 'lucide-react';
|
import { Angry, CircleAlert, Skull, WifiOff } from 'lucide-react';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
import React, { memo } from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { useStore } from 'App/mstore';
|
import { useStore } from 'App/mstore';
|
||||||
import { Icon } from 'UI';
|
|
||||||
|
|
||||||
interface Tag {
|
interface Tag {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -15,7 +12,6 @@ interface Tag {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StateProps {
|
interface StateProps {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = StateProps;
|
type Props = StateProps;
|
||||||
|
|
@ -25,94 +21,37 @@ const tagIcons = {
|
||||||
[types.JS_EXCEPTION]: <CircleAlert size={14} />,
|
[types.JS_EXCEPTION]: <CircleAlert size={14} />,
|
||||||
[types.BAD_REQUEST]: <WifiOff size={14} />,
|
[types.BAD_REQUEST]: <WifiOff size={14} />,
|
||||||
[types.CLICK_RAGE]: <Angry size={14} />,
|
[types.CLICK_RAGE]: <Angry size={14} />,
|
||||||
[types.CRASH]: <Skull size={14} />,
|
[types.CRASH]: <Skull size={14} />
|
||||||
} as Record<string, any>;
|
} as Record<string, any>;
|
||||||
|
|
||||||
const SessionTags: React.FC<Props> = () => {
|
const SessionTags: React.FC<Props> = () => {
|
||||||
const { projectsStore, sessionStore, searchStore } = useStore();
|
const { projectsStore, sessionStore, searchStore } = useStore();
|
||||||
const total = sessionStore.total;
|
const total = sessionStore.total;
|
||||||
const platform = projectsStore.active?.platform || '';
|
const platform = projectsStore.active?.platform || '';
|
||||||
const disable = searchStore.activeTab.type === 'all' && total === 0;
|
const activeTab = searchStore.activeTags;
|
||||||
const activeTab = searchStore.activeTab;
|
|
||||||
const tags = issues_types.filter(
|
|
||||||
(tag) =>
|
|
||||||
tag.type !== 'mouse_thrashing' &&
|
|
||||||
(platform === 'web'
|
|
||||||
? tag.type !== types.TAP_RAGE
|
|
||||||
: tag.type !== types.CLICK_RAGE)
|
|
||||||
);
|
|
||||||
|
|
||||||
const options = tags.map((tag, i) => ({
|
return total === 0 && (activeTab.length === 0 || activeTab[0] === 'all') ? null : (
|
||||||
label: (
|
|
||||||
<div className={'flex items-center gap-2'}>
|
|
||||||
{tag.icon ? (
|
|
||||||
tagIcons[tag.type] ? (
|
|
||||||
tagIcons[tag.type]
|
|
||||||
) : (
|
|
||||||
<Icon
|
|
||||||
name={tag.icon}
|
|
||||||
color={activeTab.type === tag.type ? 'main' : undefined}
|
|
||||||
size="14"
|
|
||||||
className={cn('group-hover:fill-teal')}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
) : null}
|
|
||||||
<div className={activeTab.type === tag.type ? 'text-main' : ''}>
|
|
||||||
{tag.name}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: tag.type,
|
|
||||||
disabled: disable && tag.type !== 'all',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const onPick = (tabValue: string) => {
|
|
||||||
const tab = tags.find((t) => t.type === tabValue);
|
|
||||||
if (tab) {
|
|
||||||
searchStore.setActiveTab(tab);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Segmented
|
<Segmented
|
||||||
options={options}
|
options={issues_types
|
||||||
value={activeTab.type}
|
.filter(
|
||||||
onChange={onPick}
|
(tag) =>
|
||||||
|
tag.type !== 'mouse_thrashing' &&
|
||||||
|
(platform === 'web'
|
||||||
|
? tag.type !== types.TAP_RAGE
|
||||||
|
: tag.type !== types.CLICK_RAGE)
|
||||||
|
)
|
||||||
|
.map((tag: any) => ({
|
||||||
|
value: tag.type,
|
||||||
|
icon: tagIcons[tag.type],
|
||||||
|
label: tag.name
|
||||||
|
}))}
|
||||||
|
value={activeTab[0]}
|
||||||
|
onChange={(value: any) => searchStore.toggleTag(value)}
|
||||||
size={'small'}
|
size={'small'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Separate the TagItem into its own memoized component.
|
|
||||||
export const TagItem: React.FC<{
|
|
||||||
isActive: boolean;
|
|
||||||
onClick: () => void;
|
|
||||||
label: string;
|
|
||||||
icon?: string;
|
|
||||||
disabled: boolean;
|
|
||||||
}> = memo(({ isActive, onClick, label, icon, disabled }) => (
|
|
||||||
<button
|
|
||||||
onClick={onClick}
|
|
||||||
className={cn(
|
|
||||||
'transition group rounded ml-2 px-2 py-1 flex items-center uppercase text-sm hover:bg-active-blue hover:text-teal',
|
|
||||||
{
|
|
||||||
'bg-active-blue text-teal': isActive,
|
|
||||||
disabled: disabled
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
style={{ height: '36px' }}
|
|
||||||
>
|
|
||||||
{icon && (
|
|
||||||
<Icon
|
|
||||||
name={icon}
|
|
||||||
color={isActive ? 'teal' : 'gray-medium'}
|
|
||||||
size="14"
|
|
||||||
className={cn('group-hover:fill-teal mr-2')}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<span className="leading-none font-medium">{label}</span>
|
|
||||||
</button>
|
|
||||||
));
|
|
||||||
|
|
||||||
export default observer(SessionTags);
|
export default observer(SessionTags);
|
||||||
|
|
|
||||||
|
|
@ -139,12 +139,12 @@ function SideMenu(props: Props) {
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const currentLocation = location.pathname;
|
const currentLocation = location.pathname;
|
||||||
const tab = Object.keys(TabToUrlMap).find((tab: keyof typeof TabToUrlMap) =>
|
// const tab = Object.keys(TabToUrlMap).find((tab: keyof typeof TabToUrlMap) =>
|
||||||
currentLocation.includes(TabToUrlMap[tab])
|
// currentLocation.includes(TabToUrlMap[tab])
|
||||||
);
|
// );
|
||||||
if (tab && tab !== searchStore.activeTab && siteId) {
|
// if (tab && tab !== searchStore.activeTab && siteId) {
|
||||||
searchStore.setActiveTab({ type: tab });
|
// searchStore.setActiveTab({ type: tab });
|
||||||
}
|
// }
|
||||||
}, [location.pathname]);
|
}, [location.pathname]);
|
||||||
|
|
||||||
const menuRoutes: any = {
|
const menuRoutes: any = {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import Filter, { checkFilterValue, IFilter } from 'App/mstore/types/filter';
|
||||||
import FilterItem from 'App/mstore/types/filterItem';
|
import FilterItem from 'App/mstore/types/filterItem';
|
||||||
import { sessionStore } from 'App/mstore';
|
import { sessionStore } from 'App/mstore';
|
||||||
import SavedSearch, { ISavedSearch } from 'App/mstore/types/savedSearch';
|
import SavedSearch, { ISavedSearch } from 'App/mstore/types/savedSearch';
|
||||||
|
import { iTag } from '@/services/NotesService';
|
||||||
|
import { issues_types } from 'Types/session/issue';
|
||||||
|
|
||||||
const PER_PAGE = 10;
|
const PER_PAGE = 10;
|
||||||
|
|
||||||
|
|
@ -48,6 +50,14 @@ export const filterMap = ({
|
||||||
filters: filters ? filters.map(filterMap) : []
|
filters: filters ? filters.map(filterMap) : []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const TAB_MAP: any = {
|
||||||
|
all: { name: 'All', type: 'all' },
|
||||||
|
sessions: { name: 'Sessions', type: 'sessions' },
|
||||||
|
bookmarks: { name: 'Bookmarks', type: 'bookmarks' },
|
||||||
|
notes: { name: 'Notes', type: 'notes' },
|
||||||
|
recommendations: { name: 'Recommendations', type: 'recommendations' }
|
||||||
|
};
|
||||||
|
|
||||||
class SearchStore {
|
class SearchStore {
|
||||||
filterList = generateFilterOptions(filtersMap);
|
filterList = generateFilterOptions(filtersMap);
|
||||||
filterListLive = generateFilterOptions(liveFiltersMap);
|
filterListLive = generateFilterOptions(liveFiltersMap);
|
||||||
|
|
@ -68,6 +78,7 @@ class SearchStore {
|
||||||
total: number = 0;
|
total: number = 0;
|
||||||
loadingFilterSearch = false;
|
loadingFilterSearch = false;
|
||||||
isSaving: boolean = false;
|
isSaving: boolean = false;
|
||||||
|
activeTags: any[] = [];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
|
|
@ -79,7 +90,7 @@ class SearchStore {
|
||||||
// filters: savedSearch.filter.filters
|
// filters: savedSearch.filter.filters
|
||||||
// });
|
// });
|
||||||
console.log('savedSearch.filter.filters', savedSearch.filter.filters);
|
console.log('savedSearch.filter.filters', savedSearch.filter.filters);
|
||||||
this.edit({ filters: savedSearch.filter ? savedSearch.filter.filters.map((i: FilterItem) => new FilterItem().fromJson(i)) : []});
|
this.edit({ filters: savedSearch.filter ? savedSearch.filter.filters.map((i: FilterItem) => new FilterItem().fromJson(i)) : [] });
|
||||||
// this.edit({ filters: savedSearch.filter ? savedSearch.filter.filters : [] });
|
// this.edit({ filters: savedSearch.filter ? savedSearch.filter.filters : [] });
|
||||||
this.currentPage = 1;
|
this.currentPage = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -131,12 +142,23 @@ class SearchStore {
|
||||||
void this.fetchSessions();
|
void this.fetchSessions();
|
||||||
}
|
}
|
||||||
|
|
||||||
setActiveTab(tab: any) {
|
setActiveTab(tab: string) {
|
||||||
this.activeTab = tab;
|
this.activeTab = TAB_MAP[tab];
|
||||||
|
// this.activeTab = tab;
|
||||||
this.currentPage = 1;
|
this.currentPage = 1;
|
||||||
// this.fetchSessions();
|
// this.fetchSessions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleTag(tag?: iTag) {
|
||||||
|
if (!tag) {
|
||||||
|
this.activeTags = [];
|
||||||
|
void this.fetchSessions(true);
|
||||||
|
} else {
|
||||||
|
this.activeTags = [tag];
|
||||||
|
void this.fetchSessions(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async removeSavedSearch(id: string): Promise<void> {
|
async removeSavedSearch(id: string): Promise<void> {
|
||||||
await searchService.deleteSavedSearch(id);
|
await searchService.deleteSavedSearch(id);
|
||||||
this.savedSearch = new SavedSearch({});
|
this.savedSearch = new SavedSearch({});
|
||||||
|
|
@ -174,6 +196,7 @@ class SearchStore {
|
||||||
|
|
||||||
this.savedSearch = new SavedSearch({});
|
this.savedSearch = new SavedSearch({});
|
||||||
sessionStore.clearList();
|
sessionStore.clearList();
|
||||||
|
void this.fetchSessions(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkForLatestSessions() {
|
checkForLatestSessions() {
|
||||||
|
|
@ -274,13 +297,26 @@ class SearchStore {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchSessions(force: boolean = false): Promise<void> {
|
async fetchSessions(force: boolean = false, bookmarked: boolean = false): Promise<void> {
|
||||||
|
const filter = this.instance.toSearch();
|
||||||
|
|
||||||
|
if (this.activeTags[0] && this.activeTags[0] !== 'all') {
|
||||||
|
const tagFilter = filtersMap[FilterKey.ISSUE];
|
||||||
|
tagFilter.value = [issues_types.find((i: any) => i.type === this.activeTags[0])?.type];
|
||||||
|
delete tagFilter.operatorOptions;
|
||||||
|
delete tagFilter.options;
|
||||||
|
delete tagFilter.placeholder;
|
||||||
|
delete tagFilter.label;
|
||||||
|
delete tagFilter.icon;
|
||||||
|
filter.filters = filter.filters.concat(tagFilter);
|
||||||
|
}
|
||||||
|
|
||||||
await sessionStore.fetchSessions({
|
await sessionStore.fetchSessions({
|
||||||
...this.instance.toSearch(),
|
...filter,
|
||||||
page: this.currentPage,
|
page: this.currentPage,
|
||||||
perPage: this.pageSize,
|
perPage: this.pageSize,
|
||||||
tab: this.activeTab.type,
|
tab: this.activeTab.type,
|
||||||
bookmarked: this.activeTab.type === 'bookmark' ? true : undefined
|
bookmarked: bookmarked ? true : undefined
|
||||||
}, force);
|
}, force);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -431,3 +431,8 @@ p {
|
||||||
.ant-segmented-group{
|
.ant-segmented-group{
|
||||||
gap:0.25rem;
|
gap:0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-segmented-item-label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue