diff --git a/frontend/app/PrivateRoutes.tsx b/frontend/app/PrivateRoutes.tsx
index b9d2cb247..d256df7f8 100644
--- a/frontend/app/PrivateRoutes.tsx
+++ b/frontend/app/PrivateRoutes.tsx
@@ -1,14 +1,15 @@
import withSiteIdUpdater from 'HOCs/withSiteIdUpdater';
import React, { Suspense, lazy } from 'react';
import { Redirect, Route, Switch } from 'react-router-dom';
-import { observer } from 'mobx-react-lite'
-import { useStore } from "./mstore";
+import { observer } from 'mobx-react-lite';
+import { useStore } from './mstore';
import { GLOBAL_HAS_NO_RECORDINGS } from 'App/constants/storageKeys';
import { OB_DEFAULT_TAB } from 'App/routes';
import { Loader } from 'UI';
import APIClient from './api_client';
import * as routes from './routes';
+import { debounce } from '@/utils';
const components: any = {
SessionPure: lazy(() => import('Components/Session/Session')),
@@ -31,7 +32,7 @@ const components: any = {
SpotsListPure: lazy(() => import('Components/Spots/SpotsList')),
SpotPure: lazy(() => import('Components/Spots/SpotPlayer')),
ScopeSetup: lazy(() => import('Components/ScopeForm')),
- HighlightsPure: lazy(() => import('Components/Highlights/HighlightsList')),
+ HighlightsPure: lazy(() => import('Components/Highlights/HighlightsList'))
};
const enhancedComponents: any = {
@@ -51,7 +52,7 @@ const enhancedComponents: any = {
SpotsList: withSiteIdUpdater(components.SpotsListPure),
Spot: components.SpotPure,
ScopeSetup: components.ScopeSetup,
- Highlights: withSiteIdUpdater(components.HighlightsPure),
+ Highlights: withSiteIdUpdater(components.HighlightsPure)
};
const withSiteId = routes.withSiteId;
@@ -97,9 +98,10 @@ const SPOT_PATH = routes.spot();
const SCOPE_SETUP = routes.scopeSetup();
const HIGHLIGHTS_PATH = routes.highlights();
+let debounceSearch: any = () => {};
function PrivateRoutes() {
- const { projectsStore, userStore, integrationsStore } = useStore();
+ const { projectsStore, userStore, integrationsStore, searchStore } = useStore();
const onboarding = userStore.onboarding;
const scope = userStore.scopeState;
const tenantId = userStore.account.tenantId;
@@ -113,10 +115,20 @@ function PrivateRoutes() {
React.useEffect(() => {
if (siteId && integrationsStore.integrations.siteId !== siteId) {
- integrationsStore.integrations.setSiteId(siteId)
+ integrationsStore.integrations.setSiteId(siteId);
void integrationsStore.integrations.fetchIntegrations(siteId);
}
- }, [siteId])
+ }, [siteId]);
+
+ React.useEffect(() => {
+ debounceSearch = debounce(() => searchStore.fetchSessions(), 500);
+ }, []);
+
+ React.useEffect(() => {
+ if (!searchStore.urlParsed) return;
+ debounceSearch();
+ }, [searchStore.instance.filters, searchStore.instance.eventsOrder]);
+
return (
}>
@@ -153,13 +165,13 @@ function PrivateRoutes() {
case '/integrations/slack':
client.post('integrations/slack/add', {
code: location.search.split('=')[1],
- state: tenantId,
+ state: tenantId
});
break;
case '/integrations/msteams':
client.post('integrations/msteams/add', {
code: location.search.split('=')[1],
- state: tenantId,
+ state: tenantId
});
break;
}
@@ -184,7 +196,7 @@ function PrivateRoutes() {
withSiteId(DASHBOARD_PATH, siteIdList),
withSiteId(DASHBOARD_SELECT_PATH, siteIdList),
withSiteId(DASHBOARD_METRIC_CREATE_PATH, siteIdList),
- withSiteId(DASHBOARD_METRIC_DETAILS_PATH, siteIdList),
+ withSiteId(DASHBOARD_METRIC_DETAILS_PATH, siteIdList)
]}
component={enhancedComponents.Dashboard}
/>
@@ -245,7 +257,7 @@ function PrivateRoutes() {
withSiteId(FFLAG_READ_PATH, siteIdList),
withSiteId(FFLAG_CREATE_PATH, siteIdList),
withSiteId(NOTES_PATH, siteIdList),
- withSiteId(BOOKMARKS_PATH, siteIdList),
+ withSiteId(BOOKMARKS_PATH, siteIdList)
]}
component={enhancedComponents.SessionsOverview}
/>
@@ -264,7 +276,7 @@ function PrivateRoutes() {
{Object.entries(routes.redirects).map(([fr, to]) => (
))}
-
+
diff --git a/frontend/app/components/shared/SessionFilters/SessionFilters.tsx b/frontend/app/components/shared/SessionFilters/SessionFilters.tsx
index 54a03b285..c6a918c0a 100644
--- a/frontend/app/components/shared/SessionFilters/SessionFilters.tsx
+++ b/frontend/app/components/shared/SessionFilters/SessionFilters.tsx
@@ -57,10 +57,6 @@ function SessionFilters() {
}
});
- useEffect(() => {
- debounceFetch();
- }, [appliedFilter.filters]);
-
const onAddFilter = (filter: any) => {
filter.autoOpen = true;
searchStore.addFilter(filter);
@@ -72,13 +68,13 @@ function SessionFilters() {
const onFilterMove = (newFilters: any) => {
searchStore.updateSearch({ ...appliedFilter, filters: newFilters});
- debounceFetch();
+ // debounceFetch();
};
const onRemoveFilter = (filterIndex: any) => {
searchStore.removeFilter(filterIndex);
- debounceFetch();
+ // debounceFetch();
};
const onChangeEventsOrder = (e: any, { value }: any) => {
@@ -86,7 +82,7 @@ function SessionFilters() {
eventsOrder: value,
});
- debounceFetch();
+ // debounceFetch();
};
return (
diff --git a/frontend/app/components/shared/SessionsTabOverview/components/LatestSessionsMessage/LatestSessionsMessage.tsx b/frontend/app/components/shared/SessionsTabOverview/components/LatestSessionsMessage/LatestSessionsMessage.tsx
index 03b55e3b1..666ed39e7 100644
--- a/frontend/app/components/shared/SessionsTabOverview/components/LatestSessionsMessage/LatestSessionsMessage.tsx
+++ b/frontend/app/components/shared/SessionsTabOverview/components/LatestSessionsMessage/LatestSessionsMessage.tsx
@@ -6,9 +6,10 @@ import { observer } from 'mobx-react-lite';
function LatestSessionsMessage() {
const { searchStore } = useStore();
- const count = searchStore.latestList.size;
+ const count = searchStore.latestSessionCount;
const onShowNewSessions = () => {
+ searchStore.updateLatestSessionCount(0);
void searchStore.updateCurrentPage(1, true);
};
diff --git a/frontend/app/components/shared/SessionsTabOverview/components/SessionList/SessionList.tsx b/frontend/app/components/shared/SessionsTabOverview/components/SessionList/SessionList.tsx
index e02cb9246..2d05133b2 100644
--- a/frontend/app/components/shared/SessionsTabOverview/components/SessionList/SessionList.tsx
+++ b/frontend/app/components/shared/SessionsTabOverview/components/SessionList/SessionList.tsx
@@ -47,10 +47,10 @@ function SessionList() {
const hasNoRecordings = !activeSite || !activeSite.recorded;
const metaList = customFieldStore.list;
- // useEffect(() => {
- // if (!searchStore.urlParsed) return;
- // void searchStore.fetchSessions(true, isBookmark);
- // }, [location.pathname]);
+ useEffect(() => {
+ if (!searchStore.urlParsed) return;
+ void searchStore.checkForLatestSessionCount();
+ }, [location.pathname]);
const NO_CONTENT = React.useMemo(() => {
if (isBookmark && !isEnterprise) {
@@ -110,7 +110,7 @@ function SessionList() {
useEffect(() => {
const id = setInterval(() => {
if (!document.hidden) {
- searchStore.checkForLatestSessions();
+ void searchStore.checkForLatestSessionCount();
}
}, AUTO_REFRESH_INTERVAL);
return () => clearInterval(id);
@@ -134,7 +134,7 @@ function SessionList() {
sessionTimeOut = setTimeout(function () {
if (!document.hidden) {
- searchStore.checkForLatestSessions();
+ void searchStore.checkForLatestSessionCount();
}
}, 5000);
};
diff --git a/frontend/app/mstore/searchStore.ts b/frontend/app/mstore/searchStore.ts
index 1e0a00544..f6c1abd49 100644
--- a/frontend/app/mstore/searchStore.ts
+++ b/frontend/app/mstore/searchStore.ts
@@ -5,11 +5,11 @@ import {
filtersMap,
generateFilterOptions,
liveFiltersMap,
- mobileConditionalFiltersMap,
+ mobileConditionalFiltersMap
} from 'Types/filter/newFilter';
import { List } from 'immutable';
import { makeAutoObservable, runInAction } from 'mobx';
-import { searchService } from 'App/services';
+import { searchService, sessionService } from 'App/services';
import Search from 'App/mstore/types/search';
import { checkFilterValue } from 'App/mstore/types/filter';
import FilterItem from 'App/mstore/types/filterItem';
@@ -28,18 +28,18 @@ export const checkValues = (key: any, value: any) => {
};
export const filterMap = ({
- category,
- value,
- key,
- operator,
- sourceOperator,
- source,
- custom,
- isEvent,
- filters,
- sort,
- order,
-}: any) => ({
+ category,
+ value,
+ key,
+ operator,
+ sourceOperator,
+ source,
+ custom,
+ isEvent,
+ filters,
+ sort,
+ order
+ }: any) => ({
value: checkValues(key, value),
custom,
type: category === FilterCategory.METADATA ? FilterKey.METADATA : key,
@@ -47,7 +47,7 @@ export const filterMap = ({
source: category === FilterCategory.METADATA ? key.replace(/^_/, '') : source,
sourceOperator,
isEvent,
- filters: filters ? filters.map(filterMap) : [],
+ filters: filters ? filters.map(filterMap) : []
});
export const TAB_MAP: any = {
@@ -55,7 +55,7 @@ export const TAB_MAP: any = {
sessions: { name: 'Sessions', type: 'sessions' },
bookmarks: { name: 'Bookmarks', type: 'bookmarks' },
notes: { name: 'Notes', type: 'notes' },
- recommendations: { name: 'Recommendations', type: 'recommendations' },
+ recommendations: { name: 'Recommendations', type: 'recommendations' }
};
class SearchStore {
@@ -72,6 +72,7 @@ class SearchStore {
scrollY = 0;
sessions = List();
total: number = 0;
+ latestSessionCount: number = 0;
loadingFilterSearch = false;
isSaving: boolean = false;
activeTags: any[] = [];
@@ -111,9 +112,9 @@ class SearchStore {
this.edit({
filters: savedSearch.filter
? savedSearch.filter.filters.map((i: FilterItem) =>
- new FilterItem().fromJson(i)
- )
- : [],
+ new FilterItem().fromJson(i)
+ )
+ : []
});
this.currentPage = 1;
}
@@ -179,6 +180,10 @@ class SearchStore {
void this.fetchSessions(force);
}
+ updateLatestSessionCount(count: number = 0) {
+ this.latestSessionCount = count;
+ }
+
setActiveTab(tab: string) {
runInAction(() => {
this.activeTab = TAB_MAP[tab];
@@ -228,7 +233,7 @@ class SearchStore {
rangeValue: instance.rangeValue,
startDate: instance.startDate,
endDate: instance.endDate,
- filters: [],
+ filters: []
})
);
@@ -237,78 +242,67 @@ class SearchStore {
void this.fetchSessions(true);
}
- checkForLatestSessionCount() {
- const filter = this.instance.toSearch();
- if (this.latestRequestTime) {
- const period = Period({
- rangeName: CUSTOM_RANGE,
- start: this.latestRequestTime,
- end: Date.now(),
- });
- const newTimestamps: any = period.toJSON();
- filter.startDate = newTimestamps.startDate;
- filter.endDate = newTimestamps.endDate;
- }
- // TODO - dedicated API endpoint to get the count of latest sessions, or show X+ sessions
- delete filter.limit;
- delete filter.page;
- searchService.checkLatestSessions(filter).then((response: any) => {
- console.log('response', response);
- // runInAction(() => {
- // this.latestList = List(response);
- // });
- });
- }
+ async checkForLatestSessionCount(): Promise {
+ try {
+ const filter = this.instance.toSearch();
+
+ // Set time filter if we have the latest request time
+ if (this.latestRequestTime) {
+ const period = Period({
+ rangeName: CUSTOM_RANGE,
+ start: this.latestRequestTime,
+ end: Date.now()
+ });
+ const timeRange: any = period.toJSON();
+ filter.startDate = timeRange.startDate;
+ filter.endDate = timeRange.endDate;
+ }
+
+ // Only need the total count, not actual records
+ filter.limit = 1;
+ filter.page = 1;
+
+ const response = await sessionService.getSessions(filter);
- checkForLatestSessions() {
- const filter = this.instance.toSearch();
- if (this.latestRequestTime) {
- const period = Period({
- rangeName: CUSTOM_RANGE,
- start: this.latestRequestTime,
- end: Date.now(),
- });
- const newTimestamps: any = period.toJSON();
- filter.startDate = newTimestamps.startDate;
- filter.endDate = newTimestamps.endDate;
- }
- // TODO - dedicated API endpoint to get the count of latest sessions, or show X+ sessions
- delete filter.limit;
- delete filter.page;
- searchService.checkLatestSessions(filter).then((response: any) => {
runInAction(() => {
- this.latestList = List(response);
+ if (response?.total && response.total > sessionStore.total) {
+ this.latestSessionCount = response.total - sessionStore.total;
+ } else {
+ this.latestSessionCount = 0;
+ }
});
- });
+ } catch (error) {
+ console.error('Failed to check for latest session count:', error);
+ }
}
addFilter(filter: any) {
const index = filter.isEvent
? -1
: this.instance.filters.findIndex(
- (i: FilterItem) => i.key === filter.key
- );
+ (i: FilterItem) => i.key === filter.key
+ );
filter.value = checkFilterValue(filter.value);
filter.filters = filter.filters
? filter.filters.map((subFilter: any) => ({
- ...subFilter,
- value: checkFilterValue(subFilter.value),
- }))
+ ...subFilter,
+ value: checkFilterValue(subFilter.value)
+ }))
: null;
if (index > -1) {
const oldFilter = new FilterItem(this.instance.filters[index]);
const updatedFilter = {
...oldFilter,
- value: oldFilter.value.concat(filter.value),
+ value: oldFilter.value.concat(filter.value)
};
oldFilter.merge(updatedFilter);
this.updateFilter(index, updatedFilter);
} else {
this.instance.filters.push(filter);
this.instance = new Search({
- ...this.instance.toData(),
+ ...this.instance.toData()
});
}
@@ -346,7 +340,7 @@ class SearchStore {
updateSearch = (search: Partial) => {
this.instance = Object.assign(this.instance, search);
- }
+ };
updateFilter = (index: number, search: Partial) => {
const newFilters = this.instance.filters.map((_filter: any, i: any) => {
@@ -359,7 +353,7 @@ class SearchStore {
this.instance = new Search({
...this.instance.toData(),
- filters: newFilters,
+ filters: newFilters
});
};
@@ -370,7 +364,7 @@ class SearchStore {
this.instance = new Search({
...this.instance.toData(),
- filters: newFilters,
+ filters: newFilters
});
};
@@ -393,7 +387,7 @@ class SearchStore {
const tagFilter = filtersMap[FilterKey.ISSUE];
tagFilter.type = tagFilter.type.toLowerCase();
tagFilter.value = [
- issues_types.find((i: any) => i.type === this.activeTags[0])?.type,
+ issues_types.find((i: any) => i.type === this.activeTags[0])?.type
];
delete tagFilter.operatorOptions;
delete tagFilter.options;
@@ -413,7 +407,7 @@ class SearchStore {
filter.filters.push({
type: FilterKey.DURATION,
value,
- operator: 'is',
+ operator: 'is'
});
}
}
@@ -427,7 +421,7 @@ class SearchStore {
page: this.currentPage,
perPage: this.pageSize,
tab: this.activeTab.type,
- bookmarked: bookmarked ? true : undefined,
+ bookmarked: bookmarked ? true : undefined
},
force
).finally(() => {