fix ui: reformat old files (saas consistency)
This commit is contained in:
parent
2e65173e9a
commit
a32155efc3
4 changed files with 1150 additions and 932 deletions
|
|
@ -7,43 +7,50 @@ import { connect } from 'react-redux';
|
|||
import { useParams } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
|
||||
|
||||
import { useStore } from 'App/mstore';
|
||||
import { Note } from 'App/services/NotesService';
|
||||
import { closeBottomBlock, toggleFullscreen } from 'Duck/components/player';
|
||||
import { fetchList } from 'Duck/integrations';
|
||||
import { Loader, Modal } from 'UI';
|
||||
|
||||
|
||||
|
||||
import ReadNote from '../Session_/Player/Controls/components/ReadNote';
|
||||
import PlayerBlockHeader from './Player/ReplayPlayer/PlayerBlockHeader';
|
||||
import PlayerContent from './Player/ReplayPlayer/PlayerContent';
|
||||
import { IPlayerContext, PlayerContext, defaultContextValue } from './playerContext';
|
||||
|
||||
import {
|
||||
IPlayerContext,
|
||||
PlayerContext,
|
||||
defaultContextValue,
|
||||
} from './playerContext';
|
||||
|
||||
const TABS = {
|
||||
EVENTS: 'Activity',
|
||||
CLICKMAP: 'Click map',
|
||||
INSPECTOR: 'Tag'
|
||||
INSPECTOR: 'Tag',
|
||||
};
|
||||
|
||||
const UXTTABS = {
|
||||
EVENTS: TABS.EVENTS
|
||||
EVENTS: TABS.EVENTS,
|
||||
};
|
||||
|
||||
let playerInst: IPlayerContext['player'] | undefined;
|
||||
|
||||
function WebPlayer(props: any) {
|
||||
const { session, toggleFullscreen, closeBottomBlock, fullscreen, fetchList, startedAt } = props;
|
||||
const {
|
||||
session,
|
||||
toggleFullscreen,
|
||||
closeBottomBlock,
|
||||
fullscreen,
|
||||
fetchList,
|
||||
startedAt,
|
||||
} = props;
|
||||
const { notesStore, sessionStore, uxtestingStore } = useStore();
|
||||
const [activeTab, setActiveTab] = useState('');
|
||||
const [noteItem, setNoteItem] = useState<Note | undefined>(undefined);
|
||||
const [visuallyAdjusted, setAdjusted] = useState(false);
|
||||
const [windowActive, setWindowActive] = useState(!document.hidden);
|
||||
// @ts-ignore
|
||||
const [contextValue, setContextValue] = useState<IPlayerContext>(defaultContextValue);
|
||||
const [contextValue, setContextValue] =
|
||||
useState<IPlayerContext>(defaultContextValue);
|
||||
const params: { sessionId: string } = useParams();
|
||||
const [fullView, setFullView] = useState(false);
|
||||
|
||||
|
|
@ -54,15 +61,17 @@ function WebPlayer(props: any) {
|
|||
setWindowActive(true);
|
||||
document.removeEventListener('visibilitychange', handleActivation);
|
||||
}
|
||||
}
|
||||
};
|
||||
document.addEventListener('visibilitychange', handleActivation);
|
||||
}
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
playerInst = undefined;
|
||||
if (!session.sessionId || contextValue.player !== undefined) return;
|
||||
const mobData = sessionStore.prefetchedMobUrls[session.sessionId] as Record<string, any> | undefined;
|
||||
const mobData = sessionStore.prefetchedMobUrls[session.sessionId] as
|
||||
| Record<string, any>
|
||||
| undefined;
|
||||
const usePrefetched = props.prefetched && mobData?.data;
|
||||
fetchList('issues');
|
||||
sessionStore.setUserTimezone(session.timezone);
|
||||
|
|
@ -70,11 +79,11 @@ function WebPlayer(props: any) {
|
|||
session,
|
||||
(state) => makeAutoObservable(state),
|
||||
toast,
|
||||
props.prefetched,
|
||||
props.prefetched
|
||||
);
|
||||
if (usePrefetched) {
|
||||
if (mobData?.data) {
|
||||
WebPlayerInst.preloadFirstFile(mobData?.data)
|
||||
WebPlayerInst.preloadFirstFile(mobData?.data);
|
||||
}
|
||||
}
|
||||
setContextValue({ player: WebPlayerInst, store: PlayerStore });
|
||||
|
|
@ -96,17 +105,26 @@ function WebPlayer(props: any) {
|
|||
|
||||
useEffect(() => {
|
||||
if (!props.prefetched && session.domURL.length > 0) {
|
||||
playerInst?.reinit(session)
|
||||
playerInst?.reinit(session);
|
||||
}
|
||||
}, [session.domURL.length, props.prefetched])
|
||||
}, [session.domURL.length, props.prefetched]);
|
||||
|
||||
const { firstVisualEvent: visualOffset, messagesProcessed, tabStates, ready } = contextValue.store?.get() || {};
|
||||
const cssLoading = ready && tabStates ? Object.values(tabStates).some(
|
||||
({ cssLoading }) => cssLoading
|
||||
) : true
|
||||
const {
|
||||
firstVisualEvent: visualOffset,
|
||||
messagesProcessed,
|
||||
tabStates,
|
||||
ready,
|
||||
} = contextValue.store?.get() || {};
|
||||
const cssLoading =
|
||||
ready && tabStates
|
||||
? Object.values(tabStates).some(({ cssLoading }) => cssLoading)
|
||||
: true;
|
||||
|
||||
React.useEffect(() => {
|
||||
if (messagesProcessed && (session.events.length > 0 || session.errors.length > 0)) {
|
||||
if (
|
||||
messagesProcessed &&
|
||||
(session.events.length > 0 || session.errors.length > 0)
|
||||
) {
|
||||
contextValue.player?.updateLists?.(session);
|
||||
}
|
||||
}, [session.events, session.errors, contextValue.player, messagesProcessed]);
|
||||
|
|
@ -119,7 +137,8 @@ function WebPlayer(props: any) {
|
|||
|
||||
if (jumpToTime || shouldAdjustOffset) {
|
||||
if (jumpToTime > visualOffset) {
|
||||
const diff = startedAt < jumpToTime ? jumpToTime - startedAt : jumpToTime
|
||||
const diff =
|
||||
startedAt < jumpToTime ? jumpToTime - startedAt : jumpToTime;
|
||||
contextValue.player.jump(Math.max(diff, 0));
|
||||
} else {
|
||||
contextValue.player.jump(visualOffset);
|
||||
|
|
@ -136,7 +155,7 @@ function WebPlayer(props: any) {
|
|||
} else if (ready) {
|
||||
contextValue.player?.play();
|
||||
}
|
||||
}, [cssLoading, ready, noteItem])
|
||||
}, [cssLoading, ready, noteItem]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (activeTab === 'Click map') {
|
||||
|
|
@ -168,7 +187,7 @@ function WebPlayer(props: any) {
|
|||
};
|
||||
|
||||
useEffect(() => {
|
||||
const isFullView = new URLSearchParams(location.search).get('fullview')
|
||||
const isFullView = new URLSearchParams(location.search).get('fullview');
|
||||
setFullView(isFullView === 'true');
|
||||
}, [session.sessionId]);
|
||||
|
||||
|
|
@ -181,7 +200,7 @@ function WebPlayer(props: any) {
|
|||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
height: 75
|
||||
height: 75,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
|
@ -207,12 +226,21 @@ function WebPlayer(props: any) {
|
|||
/>
|
||||
) : (
|
||||
<Loader
|
||||
style={{ position: 'fixed', top: '0%', left: '50%', transform: 'translateX(-50%)' }}
|
||||
style={{
|
||||
position: 'fixed',
|
||||
top: '0%',
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Modal open={noteItem !== undefined} onClose={onNoteClose}>
|
||||
{noteItem !== undefined ? (
|
||||
<ReadNote note={noteItem} onClose={onNoteClose} notFound={!noteItem} />
|
||||
<ReadNote
|
||||
note={noteItem}
|
||||
onClose={onNoteClose}
|
||||
notFound={!noteItem}
|
||||
/>
|
||||
) : null}
|
||||
</Modal>
|
||||
</PlayerContext.Provider>
|
||||
|
|
@ -229,11 +257,11 @@ export default connect(
|
|||
fullscreen: state.getIn(['components', 'player', 'fullscreen']),
|
||||
showEvents: state.get('showEvents'),
|
||||
members: state.getIn(['members', 'list']),
|
||||
startedAt: state.getIn(['sessions', 'current']).startedAt || 0
|
||||
startedAt: state.getIn(['sessions', 'current']).startedAt || 0,
|
||||
}),
|
||||
{
|
||||
toggleFullscreen,
|
||||
closeBottomBlock,
|
||||
fetchList
|
||||
fetchList,
|
||||
}
|
||||
)(withLocationHandlers()(observer(WebPlayer)));
|
||||
|
|
|
|||
|
|
@ -1,22 +1,30 @@
|
|||
import { List, Map } from 'immutable';
|
||||
import { fetchListType, fetchType, saveType, removeType, editType } from './funcTools/crud';
|
||||
import { createRequestReducer, ROOT_KEY } from './funcTools/request';
|
||||
import { array, success, mergeReducers } from './funcTools/tools';
|
||||
import Period, { CUSTOM_RANGE } from 'Types/app/period';
|
||||
import Filter from 'Types/filter';
|
||||
import SavedFilter from 'Types/filter/savedFilter';
|
||||
import { errors as errorsRoute, isRoute } from 'App/routes';
|
||||
import { fetchList as fetchSessionList, fetchAutoplayList } from './sessions';
|
||||
import { fetchList as fetchErrorsList } from './errors';
|
||||
import { FilterCategory, FilterKey } from 'Types/filter/filterType';
|
||||
import {
|
||||
filtersMap,
|
||||
liveFiltersMap,
|
||||
conditionalFiltersMap,
|
||||
generateFilterOptions,
|
||||
mobileConditionalFiltersMap,
|
||||
} from "Types/filter/newFilter";
|
||||
conditionalFiltersMap,
|
||||
filtersMap,
|
||||
generateFilterOptions,
|
||||
liveFiltersMap,
|
||||
mobileConditionalFiltersMap,
|
||||
} from 'Types/filter/newFilter';
|
||||
import SavedFilter from 'Types/filter/savedFilter';
|
||||
import { List, Map } from 'immutable';
|
||||
|
||||
import { DURATION_FILTER } from 'App/constants/storageKeys';
|
||||
import Period, { CUSTOM_RANGE } from 'Types/app/period';
|
||||
import { errors as errorsRoute, isRoute } from 'App/routes';
|
||||
|
||||
import { fetchList as fetchErrorsList } from './errors';
|
||||
import {
|
||||
editType,
|
||||
fetchListType,
|
||||
fetchType,
|
||||
removeType,
|
||||
saveType,
|
||||
} from './funcTools/crud';
|
||||
import { ROOT_KEY, createRequestReducer } from './funcTools/request';
|
||||
import { array, mergeReducers, success } from './funcTools/tools';
|
||||
import { fetchAutoplayList, fetchList as fetchSessionList } from './sessions';
|
||||
|
||||
const ERRORS_ROUTE = errorsRoute();
|
||||
|
||||
|
|
@ -41,182 +49,216 @@ const SET_SCROLL_POSITION = `${name}/SET_SCROLL_POSITION`;
|
|||
|
||||
const REFRESH_FILTER_OPTIONS = 'filters/REFRESH_FILTER_OPTIONS';
|
||||
const CHECK_LATEST = fetchListType(`${name}/CHECK_LATEST`);
|
||||
const UPDATE_LATEST_REQUEST_TIME = 'filters/UPDATE_LATEST_REQUEST_TIME'
|
||||
const UPDATE_LATEST_REQUEST_TIME = 'filters/UPDATE_LATEST_REQUEST_TIME';
|
||||
|
||||
const initialState = Map({
|
||||
filterList: generateFilterOptions(filtersMap),
|
||||
filterListLive: generateFilterOptions(liveFiltersMap),
|
||||
filterListConditional: generateFilterOptions(conditionalFiltersMap),
|
||||
filterListMobileConditional: generateFilterOptions(mobileConditionalFiltersMap),
|
||||
list: List(),
|
||||
latestRequestTime: null,
|
||||
latestList: List(),
|
||||
alertMetricId: null,
|
||||
instance: new Filter({ filters: [] }),
|
||||
savedSearch: new SavedFilter({}),
|
||||
filterSearchList: {},
|
||||
currentPage: 1,
|
||||
pageSize: PER_PAGE,
|
||||
activeTab: { name: 'All', type: 'all' },
|
||||
scrollY: 0,
|
||||
filterList: generateFilterOptions(filtersMap),
|
||||
filterListLive: generateFilterOptions(liveFiltersMap),
|
||||
filterListConditional: generateFilterOptions(conditionalFiltersMap),
|
||||
filterListMobileConditional: generateFilterOptions(
|
||||
mobileConditionalFiltersMap
|
||||
),
|
||||
list: List(),
|
||||
latestRequestTime: null,
|
||||
latestList: List(),
|
||||
alertMetricId: null,
|
||||
instance: new Filter({ filters: [] }),
|
||||
savedSearch: new SavedFilter({}),
|
||||
filterSearchList: {},
|
||||
currentPage: 1,
|
||||
pageSize: PER_PAGE,
|
||||
activeTab: { name: 'All', type: 'all' },
|
||||
scrollY: 0,
|
||||
});
|
||||
|
||||
// Metric - Series - [] - filters
|
||||
function reducer(state = initialState, action = {}) {
|
||||
switch (action.type) {
|
||||
case REFRESH_FILTER_OPTIONS:
|
||||
return state
|
||||
.set('filterList', generateFilterOptions(filtersMap))
|
||||
.set('filterListLive', generateFilterOptions(liveFiltersMap))
|
||||
.set('filterListConditional', generateFilterOptions(conditionalFiltersMap))
|
||||
.set('filterListMobileConditional', generateFilterOptions(mobileConditionalFiltersMap))
|
||||
case EDIT:
|
||||
return state.mergeIn(['instance'], action.instance).set('currentPage', 1);
|
||||
case APPLY:
|
||||
if (action.fromUrl) {
|
||||
return state.set('instance', Filter(action.filter)).set('currentPage', 1)
|
||||
} else {
|
||||
return action.filter ? state.mergeIn(['instance'], action.filter).set('currentPage', 1) : state.mergeIn(['instance'], action.filter)
|
||||
}
|
||||
case success(FETCH):
|
||||
return state.set('instance', action.data);
|
||||
case success(FETCH_LIST):
|
||||
const { data } = action;
|
||||
return state.set(
|
||||
'list',
|
||||
List(data.map(SavedFilter)).sortBy((i) => i.searchId)
|
||||
);
|
||||
case UPDATE_LATEST_REQUEST_TIME:
|
||||
return state.set('latestRequestTime', Date.now()).set('latestList', [])
|
||||
case success(CHECK_LATEST):
|
||||
return state.set('latestList', action.data)
|
||||
case success(FETCH_FILTER_SEARCH):
|
||||
const groupedList = action.data.reduce((acc, item) => {
|
||||
const { projectId, type, value } = item;
|
||||
const key = type;
|
||||
if (!acc[key]) {
|
||||
acc[key] = [];
|
||||
}
|
||||
acc[key].push({ projectId, value });
|
||||
return acc;
|
||||
}, {});
|
||||
return state.set('filterSearchList', groupedList);
|
||||
case APPLY_SAVED_SEARCH:
|
||||
return state.set('savedSearch', action.filter);
|
||||
case CLEAR_SEARCH:
|
||||
return state.set('savedSearch', new SavedFilter({}));
|
||||
case EDIT_SAVED_SEARCH:
|
||||
return state.mergeIn(['savedSearch'], action.instance);
|
||||
case UPDATE_CURRENT_PAGE:
|
||||
return state.set('currentPage', action.page);
|
||||
case SET_ACTIVE_TAB:
|
||||
return state.set('activeTab', action.tab).set('currentPage', 1);
|
||||
case SET_SCROLL_POSITION:
|
||||
return state.set('scrollY', action.scrollPosition);
|
||||
}
|
||||
return state;
|
||||
switch (action.type) {
|
||||
case REFRESH_FILTER_OPTIONS:
|
||||
return state
|
||||
.set('filterList', generateFilterOptions(filtersMap))
|
||||
.set('filterListLive', generateFilterOptions(liveFiltersMap))
|
||||
.set(
|
||||
'filterListConditional',
|
||||
generateFilterOptions(conditionalFiltersMap)
|
||||
)
|
||||
.set(
|
||||
'filterListMobileConditional',
|
||||
generateFilterOptions(mobileConditionalFiltersMap)
|
||||
);
|
||||
case EDIT:
|
||||
return state.mergeIn(['instance'], action.instance).set('currentPage', 1);
|
||||
case APPLY:
|
||||
if (action.fromUrl) {
|
||||
return state
|
||||
.set('instance', Filter(action.filter))
|
||||
.set('currentPage', 1);
|
||||
} else {
|
||||
return action.filter
|
||||
? state.mergeIn(['instance'], action.filter).set('currentPage', 1)
|
||||
: state.mergeIn(['instance'], action.filter);
|
||||
}
|
||||
case success(FETCH):
|
||||
return state.set('instance', action.data);
|
||||
case success(FETCH_LIST):
|
||||
const { data } = action;
|
||||
return state.set(
|
||||
'list',
|
||||
List(data.map(SavedFilter)).sortBy((i) => i.searchId)
|
||||
);
|
||||
case UPDATE_LATEST_REQUEST_TIME:
|
||||
return state.set('latestRequestTime', Date.now()).set('latestList', []);
|
||||
case success(CHECK_LATEST):
|
||||
return state.set('latestList', action.data);
|
||||
case success(FETCH_FILTER_SEARCH):
|
||||
const groupedList = action.data.reduce((acc, item) => {
|
||||
const { projectId, type, value } = item;
|
||||
const key = type;
|
||||
if (!acc[key]) {
|
||||
acc[key] = [];
|
||||
}
|
||||
acc[key].push({ projectId, value });
|
||||
return acc;
|
||||
}, {});
|
||||
return state.set('filterSearchList', groupedList);
|
||||
case APPLY_SAVED_SEARCH:
|
||||
return state.set('savedSearch', action.filter);
|
||||
case CLEAR_SEARCH:
|
||||
return state.set('savedSearch', new SavedFilter({}));
|
||||
case EDIT_SAVED_SEARCH:
|
||||
return state.mergeIn(['savedSearch'], action.instance);
|
||||
case UPDATE_CURRENT_PAGE:
|
||||
return state.set('currentPage', action.page);
|
||||
case SET_ACTIVE_TAB:
|
||||
return state.set('activeTab', action.tab).set('currentPage', 1);
|
||||
case SET_SCROLL_POSITION:
|
||||
return state.set('scrollY', action.scrollPosition);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
export default mergeReducers(
|
||||
reducer,
|
||||
createRequestReducer({
|
||||
[ROOT_KEY]: FETCH_LIST,
|
||||
fetch: FETCH,
|
||||
fetchFilterSearch: FETCH_FILTER_SEARCH,
|
||||
})
|
||||
reducer,
|
||||
createRequestReducer({
|
||||
[ROOT_KEY]: FETCH_LIST,
|
||||
fetch: FETCH,
|
||||
fetchFilterSearch: FETCH_FILTER_SEARCH,
|
||||
})
|
||||
);
|
||||
|
||||
const checkValues = (key, value) => {
|
||||
if (key === FilterKey.DURATION) {
|
||||
return value[0] === '' || value[0] === null ? [0, value[1]] : value;
|
||||
}
|
||||
return value.filter((i) => i !== '' && i !== null);
|
||||
if (key === FilterKey.DURATION) {
|
||||
return value[0] === '' || value[0] === null ? [0, value[1]] : value;
|
||||
}
|
||||
return value.filter((i) => i !== '' && i !== null);
|
||||
};
|
||||
|
||||
export const checkFilterValue = (value) => {
|
||||
return Array.isArray(value) ? (value.length === 0 ? [''] : value) : [value];
|
||||
return Array.isArray(value) ? (value.length === 0 ? [''] : value) : [value];
|
||||
};
|
||||
|
||||
export const filterMap = ({ category, value, key, operator, sourceOperator, source, custom, isEvent, filters, sort, order }) => ({
|
||||
value: checkValues(key, value),
|
||||
custom,
|
||||
type: category === FilterCategory.METADATA ? FilterKey.METADATA : key,
|
||||
operator,
|
||||
source: category === FilterCategory.METADATA ? key.replace(/^_/, '') : source,
|
||||
sourceOperator,
|
||||
isEvent,
|
||||
filters: filters ? filters.map(filterMap) : [],
|
||||
export const filterMap = ({
|
||||
category,
|
||||
value,
|
||||
key,
|
||||
operator,
|
||||
sourceOperator,
|
||||
source,
|
||||
custom,
|
||||
isEvent,
|
||||
filters,
|
||||
sort,
|
||||
order,
|
||||
}) => ({
|
||||
value: checkValues(key, value),
|
||||
custom,
|
||||
type: category === FilterCategory.METADATA ? FilterKey.METADATA : key,
|
||||
operator,
|
||||
source: category === FilterCategory.METADATA ? key.replace(/^_/, '') : source,
|
||||
sourceOperator,
|
||||
isEvent,
|
||||
filters: filters ? filters.map(filterMap) : [],
|
||||
});
|
||||
|
||||
|
||||
const getFilters = (state) => {
|
||||
const filter = state.getIn(['search', 'instance']).toData();
|
||||
const activeTab = state.getIn(['search', 'activeTab']);
|
||||
if (activeTab.type !== 'all' && activeTab.type !== 'bookmark' && activeTab.type !== 'vault') {
|
||||
const tmpFilter = filtersMap[FilterKey.ISSUE];
|
||||
tmpFilter.value = [activeTab.type];
|
||||
filter.filters = filter.filters.concat(tmpFilter);
|
||||
const filter = state.getIn(['search', 'instance']).toData();
|
||||
const activeTab = state.getIn(['search', 'activeTab']);
|
||||
if (
|
||||
activeTab.type !== 'all' &&
|
||||
activeTab.type !== 'bookmark' &&
|
||||
activeTab.type !== 'vault'
|
||||
) {
|
||||
const tmpFilter = filtersMap[FilterKey.ISSUE];
|
||||
tmpFilter.value = [activeTab.type];
|
||||
filter.filters = filter.filters.concat(tmpFilter);
|
||||
}
|
||||
|
||||
if (activeTab.type === 'bookmark' || activeTab.type === 'vault') {
|
||||
filter.bookmarked = true;
|
||||
}
|
||||
|
||||
filter.filters = filter.filters.map(filterMap);
|
||||
|
||||
// duration filter from local storage
|
||||
if (!filter.filters.find((f) => f.type === FilterKey.DURATION)) {
|
||||
const durationFilter = JSON.parse(
|
||||
localStorage.getItem(DURATION_FILTER) || '{"count": 0}'
|
||||
);
|
||||
let durationValue = parseInt(durationFilter.count);
|
||||
if (durationValue > 0) {
|
||||
const value = [0];
|
||||
durationValue =
|
||||
durationFilter.countType === 'min'
|
||||
? durationValue * 60 * 1000
|
||||
: durationValue * 1000;
|
||||
if (durationFilter.operator === '<') {
|
||||
value[0] = durationValue;
|
||||
} else if (durationFilter.operator === '>') {
|
||||
value[1] = durationValue;
|
||||
}
|
||||
|
||||
filter.filters = filter.filters.concat({
|
||||
type: FilterKey.DURATION,
|
||||
operator: 'is',
|
||||
value,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (activeTab.type === 'bookmark' || activeTab.type === 'vault') {
|
||||
filter.bookmarked = true;
|
||||
}
|
||||
|
||||
filter.filters = filter.filters.map(filterMap);
|
||||
|
||||
// duration filter from local storage
|
||||
if (!filter.filters.find((f) => f.type === FilterKey.DURATION)) {
|
||||
const durationFilter = JSON.parse(localStorage.getItem(DURATION_FILTER) || '{"count": 0}');
|
||||
let durationValue = parseInt(durationFilter.count);
|
||||
if (durationValue > 0) {
|
||||
const value = [0];
|
||||
durationValue = durationFilter.countType === 'min' ? durationValue * 60 * 1000 : durationValue * 1000;
|
||||
if (durationFilter.operator === '<') {
|
||||
value[0] = durationValue;
|
||||
} else if (durationFilter.operator === '>') {
|
||||
value[1] = durationValue;
|
||||
}
|
||||
|
||||
filter.filters = filter.filters.concat({
|
||||
type: FilterKey.DURATION,
|
||||
operator: 'is',
|
||||
value,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
return filter;
|
||||
};
|
||||
|
||||
export const reduceThenFetchResource =
|
||||
(actionCreator) =>
|
||||
(...args) =>
|
||||
(dispatch, getState) => {
|
||||
dispatch(actionCreator(...args));
|
||||
const activeTab = getState().getIn(['search', 'activeTab']);
|
||||
if (['notes', 'flags'].includes(activeTab.type)) return;
|
||||
|
||||
const filter = getFilters(getState());
|
||||
filter.limit = PER_PAGE;
|
||||
filter.page = getState().getIn(['search', 'currentPage']);
|
||||
(actionCreator) =>
|
||||
(...args) =>
|
||||
(dispatch, getState) => {
|
||||
dispatch(actionCreator(...args));
|
||||
const activeTab = getState().getIn(['search', 'activeTab']);
|
||||
if (['notes', 'flags'].includes(activeTab.type)) return;
|
||||
|
||||
const forceFetch = filter.filters.length === 0 || args[1] === true;
|
||||
const filter = getFilters(getState());
|
||||
filter.limit = PER_PAGE;
|
||||
filter.page = getState().getIn(['search', 'currentPage']);
|
||||
|
||||
// reset the timestamps to latest
|
||||
if (filter.rangeValue !== CUSTOM_RANGE) {
|
||||
const period = new Period({ rangeName: filter.rangeValue })
|
||||
const newTimestamps = period.toJSON();
|
||||
filter.startDate = newTimestamps.startDate
|
||||
filter.endDate = newTimestamps.endDate
|
||||
}
|
||||
const forceFetch = filter.filters.length === 0 || args[1] === true;
|
||||
|
||||
dispatch(updateLatestRequestTime())
|
||||
return isRoute(ERRORS_ROUTE, window.location.pathname) ? dispatch(fetchErrorsList(filter)) : dispatch(fetchSessionList(filter, forceFetch));
|
||||
};
|
||||
// reset the timestamps to latest
|
||||
if (filter.rangeValue !== CUSTOM_RANGE) {
|
||||
const period = new Period({ rangeName: filter.rangeValue });
|
||||
const newTimestamps = period.toJSON();
|
||||
filter.startDate = newTimestamps.startDate;
|
||||
filter.endDate = newTimestamps.endDate;
|
||||
}
|
||||
|
||||
dispatch(updateLatestRequestTime());
|
||||
return isRoute(ERRORS_ROUTE, window.location.pathname)
|
||||
? dispatch(fetchErrorsList(filter))
|
||||
: dispatch(fetchSessionList(filter, forceFetch));
|
||||
};
|
||||
|
||||
export const edit = reduceThenFetchResource((instance) => ({
|
||||
type: EDIT,
|
||||
instance,
|
||||
type: EDIT,
|
||||
instance,
|
||||
}));
|
||||
|
||||
export const editDefault = (instance) => ({
|
||||
|
|
@ -225,69 +267,73 @@ export const editDefault = (instance) => ({
|
|||
});
|
||||
|
||||
export const setActiveTab = reduceThenFetchResource((tab) => ({
|
||||
type: SET_ACTIVE_TAB,
|
||||
tab,
|
||||
type: SET_ACTIVE_TAB,
|
||||
tab,
|
||||
}));
|
||||
|
||||
export const remove = (id) => (dispatch, getState) => {
|
||||
return dispatch({
|
||||
types: REMOVE.array,
|
||||
call: (client) => client.delete(`/saved_search/${id}`),
|
||||
id,
|
||||
}).then(() => {
|
||||
dispatch(applySavedSearch(new SavedFilter({})));
|
||||
dispatch(fetchList());
|
||||
});
|
||||
return dispatch({
|
||||
types: REMOVE.array,
|
||||
call: (client) => client.delete(`/saved_search/${id}`),
|
||||
id,
|
||||
}).then(() => {
|
||||
dispatch(applySavedSearch(new SavedFilter({})));
|
||||
dispatch(fetchList());
|
||||
});
|
||||
};
|
||||
|
||||
// export const remove = createRemove(name, (id) => `/saved_search/${id}`);
|
||||
|
||||
export const applyFilter = reduceThenFetchResource((filter, force = false) => ({
|
||||
type: APPLY,
|
||||
filter,
|
||||
force,
|
||||
type: APPLY,
|
||||
filter,
|
||||
force,
|
||||
}));
|
||||
|
||||
export const updateFilter = (filter, force = false, resetPage = true) => ({
|
||||
type: APPLY,
|
||||
filter,
|
||||
force,
|
||||
resetPage,
|
||||
type: APPLY,
|
||||
filter,
|
||||
force,
|
||||
resetPage,
|
||||
});
|
||||
|
||||
export const updateCurrentPage = reduceThenFetchResource((page) => ({
|
||||
type: UPDATE_CURRENT_PAGE,
|
||||
page,
|
||||
type: UPDATE_CURRENT_PAGE,
|
||||
page,
|
||||
}));
|
||||
|
||||
export const applySavedSearch = (filter) => (dispatch, getState) => {
|
||||
dispatch(edit({ filters: filter ? filter.filter.filters : [] }));
|
||||
return dispatch({
|
||||
type: APPLY_SAVED_SEARCH,
|
||||
filter,
|
||||
});
|
||||
dispatch(edit({ filters: filter ? filter.filter.filters : [] }));
|
||||
return dispatch({
|
||||
type: APPLY_SAVED_SEARCH,
|
||||
filter,
|
||||
});
|
||||
};
|
||||
|
||||
export const fetchSessions = (filter, force = false) => (dispatch, getState) => {
|
||||
export const fetchSessions =
|
||||
(filter, force = false) =>
|
||||
(dispatch, getState) => {
|
||||
const _filter = filter ? filter : getState().getIn(['search', 'instance']);
|
||||
return dispatch(applyFilter(_filter, force));
|
||||
};
|
||||
};
|
||||
|
||||
export const updateSeries = (index, series) => ({
|
||||
type: UPDATE,
|
||||
index,
|
||||
series,
|
||||
type: UPDATE,
|
||||
index,
|
||||
series,
|
||||
});
|
||||
|
||||
export function fetch(id) {
|
||||
return {
|
||||
id,
|
||||
types: array(FETCH),
|
||||
call: (c) => c.get(`/errors/${id}`),
|
||||
};
|
||||
return {
|
||||
id,
|
||||
types: array(FETCH),
|
||||
call: (c) => c.get(`/errors/${id}`),
|
||||
};
|
||||
}
|
||||
|
||||
export const save = (id, rename = false) => (dispatch, getState) => {
|
||||
export const save =
|
||||
(id, rename = false) =>
|
||||
(dispatch, getState) => {
|
||||
const filter = getState().getIn(['search', 'instance']).toData();
|
||||
// filter.filters = filter.filters.map(filterMap);
|
||||
const isNew = !id;
|
||||
|
|
@ -296,68 +342,72 @@ export const save = (id, rename = false) => (dispatch, getState) => {
|
|||
const newInstance = rename ? instance : { ...instance, filter };
|
||||
newInstance.filter.filters = newInstance.filter.filters.map(filterMap);
|
||||
return dispatch({
|
||||
types: SAVE.array,
|
||||
call: (client) => client.post(isNew ? '/saved_search' : `/saved_search/${id}`, newInstance),
|
||||
types: SAVE.array,
|
||||
call: (client) =>
|
||||
client.post(
|
||||
isNew ? '/saved_search' : `/saved_search/${id}`,
|
||||
newInstance
|
||||
),
|
||||
}).then(() => {
|
||||
dispatch(fetchList()).then(() => {
|
||||
if (isNew) {
|
||||
const lastSavedSearch = getState().getIn(['search', 'list']).last();
|
||||
dispatch(applySavedSearch(lastSavedSearch));
|
||||
}
|
||||
});
|
||||
dispatch(fetchList()).then(() => {
|
||||
if (isNew) {
|
||||
const lastSavedSearch = getState().getIn(['search', 'list']).last();
|
||||
dispatch(applySavedSearch(lastSavedSearch));
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function fetchList() {
|
||||
return {
|
||||
types: array(FETCH_LIST),
|
||||
call: (client) => client.get(`/saved_search`),
|
||||
};
|
||||
return {
|
||||
types: array(FETCH_LIST),
|
||||
call: (client) => client.get(`/saved_search`),
|
||||
};
|
||||
}
|
||||
|
||||
export function setAlertMetricId(id) {
|
||||
return {
|
||||
type: SET_ALERT_METRIC_ID,
|
||||
id,
|
||||
};
|
||||
return {
|
||||
type: SET_ALERT_METRIC_ID,
|
||||
id,
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchFilterSearch(params) {
|
||||
return {
|
||||
types: FETCH_FILTER_SEARCH.array,
|
||||
call: (client) => client.get('/events/search', params),
|
||||
params,
|
||||
};
|
||||
return {
|
||||
types: FETCH_FILTER_SEARCH.array,
|
||||
call: (client) => client.get('/events/search', params),
|
||||
params,
|
||||
};
|
||||
}
|
||||
|
||||
export const clearSearch = () => (dispatch, getState) => {
|
||||
const instance = getState().getIn(['search', 'instance']);
|
||||
dispatch(
|
||||
edit(
|
||||
new Filter({
|
||||
rangeValue: instance.rangeValue,
|
||||
startDate: instance.startDate,
|
||||
endDate: instance.endDate,
|
||||
filters: [],
|
||||
})
|
||||
)
|
||||
);
|
||||
return dispatch({
|
||||
type: CLEAR_SEARCH,
|
||||
});
|
||||
const instance = getState().getIn(['search', 'instance']);
|
||||
dispatch(
|
||||
edit(
|
||||
new Filter({
|
||||
rangeValue: instance.rangeValue,
|
||||
startDate: instance.startDate,
|
||||
endDate: instance.endDate,
|
||||
filters: [],
|
||||
})
|
||||
)
|
||||
);
|
||||
return dispatch({
|
||||
type: CLEAR_SEARCH,
|
||||
});
|
||||
};
|
||||
|
||||
export const hasFilterApplied = (filters, filter) => {
|
||||
return !filter.isEvent && filters.some((f) => f.key === filter.key);
|
||||
return !filter.isEvent && filters.some((f) => f.key === filter.key);
|
||||
};
|
||||
|
||||
export const getAppliedFilterIndex = (filters, filterToFind) => {
|
||||
if (!filterToFind.isEvent) {
|
||||
return filters.findIndex((filter) => filter.key === filterToFind.key);
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
if (!filterToFind.isEvent) {
|
||||
return filters.findIndex((filter) => filter.key === filterToFind.key);
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
export const addFilter = (filter) => (dispatch, getState) => {
|
||||
const instance = getState().getIn(['search', 'instance']);
|
||||
const filters = instance.get('filters');
|
||||
|
|
@ -388,67 +438,77 @@ export const addFilter = (filter) => (dispatch, getState) => {
|
|||
};
|
||||
|
||||
export const addFilterByKeyAndValue =
|
||||
(key, value, operator = undefined, sourceOperator = undefined, source = undefined) =>
|
||||
(dispatch, getState) => {
|
||||
let defaultFilter = {...filtersMap[key]};
|
||||
defaultFilter.value = value;
|
||||
if (operator) {
|
||||
defaultFilter.operator = operator;
|
||||
}
|
||||
if (defaultFilter.hasSource && source && sourceOperator) {
|
||||
defaultFilter.sourceOperator = sourceOperator;
|
||||
defaultFilter.source = source;
|
||||
}
|
||||
(
|
||||
key,
|
||||
value,
|
||||
operator = undefined,
|
||||
sourceOperator = undefined,
|
||||
source = undefined
|
||||
) =>
|
||||
(dispatch, getState) => {
|
||||
let defaultFilter = { ...filtersMap[key] };
|
||||
defaultFilter.value = value;
|
||||
if (operator) {
|
||||
defaultFilter.operator = operator;
|
||||
}
|
||||
if (defaultFilter.hasSource && source && sourceOperator) {
|
||||
defaultFilter.sourceOperator = sourceOperator;
|
||||
defaultFilter.source = source;
|
||||
}
|
||||
|
||||
dispatch(addFilter(defaultFilter));
|
||||
};
|
||||
dispatch(addFilter(defaultFilter));
|
||||
};
|
||||
|
||||
export const editSavedSearch = (instance) => {
|
||||
return {
|
||||
type: EDIT_SAVED_SEARCH,
|
||||
instance,
|
||||
};
|
||||
return {
|
||||
type: EDIT_SAVED_SEARCH,
|
||||
instance,
|
||||
};
|
||||
};
|
||||
|
||||
export const refreshFilterOptions = () => {
|
||||
return {
|
||||
type: REFRESH_FILTER_OPTIONS,
|
||||
};
|
||||
return {
|
||||
type: REFRESH_FILTER_OPTIONS,
|
||||
};
|
||||
};
|
||||
|
||||
export const setScrollPosition = (scrollPosition) => {
|
||||
return {
|
||||
type: SET_SCROLL_POSITION,
|
||||
scrollPosition,
|
||||
};
|
||||
return {
|
||||
type: SET_SCROLL_POSITION,
|
||||
scrollPosition,
|
||||
};
|
||||
};
|
||||
|
||||
export const updateLatestRequestTime = () => {
|
||||
return {
|
||||
type: UPDATE_LATEST_REQUEST_TIME
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: UPDATE_LATEST_REQUEST_TIME,
|
||||
};
|
||||
};
|
||||
|
||||
export const checkForLatestSessions = () => (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const filter = getFilters(state);
|
||||
const latestRequestTime = state.getIn(['search', 'latestRequestTime'])
|
||||
if (!!latestRequestTime) {
|
||||
const period = new Period({ rangeName: CUSTOM_RANGE, start: latestRequestTime, end: Date.now() })
|
||||
const newTimestamps = period.toJSON();
|
||||
filter.startDate = newTimestamps.startDate
|
||||
filter.endDate = newTimestamps.endDate
|
||||
}
|
||||
|
||||
return dispatch({
|
||||
types: array(CHECK_LATEST),
|
||||
call: (client) => client.post(`/sessions/search/ids`, filter),
|
||||
const state = getState();
|
||||
const filter = getFilters(state);
|
||||
const latestRequestTime = state.getIn(['search', 'latestRequestTime']);
|
||||
if (!!latestRequestTime) {
|
||||
const period = new Period({
|
||||
rangeName: CUSTOM_RANGE,
|
||||
start: latestRequestTime,
|
||||
end: Date.now(),
|
||||
});
|
||||
}
|
||||
const newTimestamps = period.toJSON();
|
||||
filter.startDate = newTimestamps.startDate;
|
||||
filter.endDate = newTimestamps.endDate;
|
||||
}
|
||||
|
||||
return dispatch({
|
||||
types: array(CHECK_LATEST),
|
||||
call: (client) => client.post(`/sessions/search/ids`, filter),
|
||||
});
|
||||
};
|
||||
|
||||
export const fetchAutoplaySessions = (page) => (dispatch, getState) => {
|
||||
const filter = getFilters(getState());
|
||||
filter.page = page;
|
||||
filter.limit = PER_PAGE;
|
||||
return dispatch(fetchAutoplayList(filter));
|
||||
}
|
||||
const filter = getFilters(getState());
|
||||
filter.page = page;
|
||||
filter.limit = PER_PAGE;
|
||||
return dispatch(fetchAutoplayList(filter));
|
||||
};
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,16 +1,24 @@
|
|||
import { makeAutoObservable, observable, action } from 'mobx';
|
||||
import { sessionService } from 'App/services';
|
||||
import { filterMap } from 'Duck/search';
|
||||
import Session from 'Types/session';
|
||||
import Record, { LAST_7_DAYS } from 'Types/app/period';
|
||||
import Watchdog from "Types/watchdog";
|
||||
import Session from 'Types/session';
|
||||
import ErrorStack from 'Types/session/errorStack';
|
||||
import { Location, InjectedEvent } from 'Types/session/event'
|
||||
import { getDateRangeFromValue } from "App/dateRange";
|
||||
import { getRE, setSessionFilter, getSessionFilter, compareJsonObjects, cleanSessionFilters } from 'App/utils';
|
||||
import store from 'App/store'
|
||||
import { Note } from "App/services/NotesService";
|
||||
import { loadFile } from "../player/web/network/loadFiles";
|
||||
import { InjectedEvent, Location } from 'Types/session/event';
|
||||
import Watchdog from 'Types/watchdog';
|
||||
import { action, makeAutoObservable, observable } from 'mobx';
|
||||
|
||||
import { getDateRangeFromValue } from 'App/dateRange';
|
||||
import { sessionService } from 'App/services';
|
||||
import { Note } from 'App/services/NotesService';
|
||||
import store from 'App/store';
|
||||
import {
|
||||
cleanSessionFilters,
|
||||
compareJsonObjects,
|
||||
getRE,
|
||||
getSessionFilter,
|
||||
setSessionFilter,
|
||||
} from 'App/utils';
|
||||
import { filterMap } from 'Duck/search';
|
||||
|
||||
import { loadFile } from '../player/web/network/loadFiles';
|
||||
|
||||
class UserFilter {
|
||||
endDate: number = new Date().getTime();
|
||||
|
|
@ -71,7 +79,12 @@ class DevTools {
|
|||
|
||||
constructor() {
|
||||
this.network = { index: 0, filter: '', activeTab: 'ALL', isError: false };
|
||||
this.stackEvent = { index: 0, filter: '', activeTab: 'ALL', isError: false };
|
||||
this.stackEvent = {
|
||||
index: 0,
|
||||
filter: '',
|
||||
activeTab: 'ALL',
|
||||
isError: false,
|
||||
};
|
||||
this.console = { index: 0, filter: '', activeTab: 'ALL', isError: false };
|
||||
makeAutoObservable(this, {
|
||||
update: action,
|
||||
|
|
@ -96,37 +109,44 @@ export default class SessionStore {
|
|||
userFilter: UserFilter = new UserFilter();
|
||||
devTools: DevTools = new DevTools();
|
||||
|
||||
list: Session[] = []
|
||||
sessionIds: string[] = []
|
||||
current = new Session()
|
||||
total = 0
|
||||
keyMap = {}
|
||||
wdTypeCount = {}
|
||||
favoriteList: Session[] = []
|
||||
activeTab = Watchdog({ name: 'All', type: 'all' })
|
||||
timezone = 'local'
|
||||
errorStack: ErrorStack[] = []
|
||||
eventsIndex = []
|
||||
sourcemapUploaded = true
|
||||
filteredEvents: InjectedEvent[] | null = null
|
||||
eventsQuery = ''
|
||||
showChatWindow = false
|
||||
liveSessions: Session[] = []
|
||||
visitedEvents = []
|
||||
insights: any[] = []
|
||||
insightFilters = defaultDateFilters
|
||||
host = ''
|
||||
funnelPage = {}
|
||||
list: Session[] = [];
|
||||
sessionIds: string[] = [];
|
||||
current = new Session();
|
||||
total = 0;
|
||||
keyMap = {};
|
||||
wdTypeCount = {};
|
||||
favoriteList: Session[] = [];
|
||||
activeTab = Watchdog({ name: 'All', type: 'all' });
|
||||
timezone = 'local';
|
||||
errorStack: ErrorStack[] = [];
|
||||
eventsIndex = [];
|
||||
sourcemapUploaded = true;
|
||||
filteredEvents: InjectedEvent[] | null = null;
|
||||
eventsQuery = '';
|
||||
showChatWindow = false;
|
||||
liveSessions: Session[] = [];
|
||||
visitedEvents = [];
|
||||
insights: any[] = [];
|
||||
insightFilters = defaultDateFilters;
|
||||
host = '';
|
||||
funnelPage = {};
|
||||
/** @Deprecated */
|
||||
timelinePointer = {}
|
||||
sessionPath = {}
|
||||
lastPlayedSessionId: string
|
||||
timeLineTooltip = { time: 0, offset: 0, isVisible: false, localTime: '', userTime: '' }
|
||||
createNoteTooltip = { time: 0, isVisible: false, isEdit: false, note: null }
|
||||
previousId = ''
|
||||
nextId = ''
|
||||
userTimezone = ''
|
||||
prefetchedMobUrls: Record<string, { data: Uint8Array, entryNum: number }> = {}
|
||||
timelinePointer = {};
|
||||
sessionPath = {};
|
||||
lastPlayedSessionId: string;
|
||||
timeLineTooltip = {
|
||||
time: 0,
|
||||
offset: 0,
|
||||
isVisible: false,
|
||||
localTime: '',
|
||||
userTime: '',
|
||||
};
|
||||
createNoteTooltip = { time: 0, isVisible: false, isEdit: false, note: null };
|
||||
previousId = '';
|
||||
nextId = '';
|
||||
userTimezone = '';
|
||||
prefetchedMobUrls: Record<string, { data: Uint8Array; entryNum: number }> =
|
||||
{};
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this, {
|
||||
|
|
@ -144,25 +164,32 @@ export default class SessionStore {
|
|||
}
|
||||
|
||||
async getFirstMob(sessionId: string) {
|
||||
const { domURL } = await sessionService.getFirstMobUrl(sessionId)
|
||||
await loadFile(
|
||||
domURL[0],
|
||||
(data) => this.setPrefetchedMobUrl(sessionId, data)
|
||||
)
|
||||
const { domURL } = await sessionService.getFirstMobUrl(sessionId);
|
||||
await loadFile(domURL[0], (data) =>
|
||||
this.setPrefetchedMobUrl(sessionId, data)
|
||||
);
|
||||
}
|
||||
|
||||
setPrefetchedMobUrl(sessionId: string, fileData: Uint8Array) {
|
||||
const keys = Object.keys(this.prefetchedMobUrls)
|
||||
const toLimit = 10 - keys.length
|
||||
const keys = Object.keys(this.prefetchedMobUrls);
|
||||
const toLimit = 10 - keys.length;
|
||||
if (toLimit < 0) {
|
||||
const oldest = keys.sort(
|
||||
(a, b) => this.prefetchedMobUrls[a].entryNum - this.prefetchedMobUrls[b].entryNum
|
||||
)[0]
|
||||
delete this.prefetchedMobUrls[oldest]
|
||||
(a, b) =>
|
||||
this.prefetchedMobUrls[a].entryNum -
|
||||
this.prefetchedMobUrls[b].entryNum
|
||||
)[0];
|
||||
delete this.prefetchedMobUrls[oldest];
|
||||
}
|
||||
const nextEntryNum = keys.length > 0
|
||||
? Math.max(...keys.map(key => this.prefetchedMobUrls[key].entryNum)) + 1 : 0
|
||||
this.prefetchedMobUrls[sessionId] = { data: fileData, entryNum: nextEntryNum }
|
||||
const nextEntryNum =
|
||||
keys.length > 0
|
||||
? Math.max(...keys.map((key) => this.prefetchedMobUrls[key].entryNum)) +
|
||||
1
|
||||
: 0;
|
||||
this.prefetchedMobUrls[sessionId] = {
|
||||
data: fileData,
|
||||
entryNum: nextEntryNum,
|
||||
};
|
||||
}
|
||||
|
||||
getSessions(filter: any): Promise<any> {
|
||||
|
|
@ -171,7 +198,9 @@ export default class SessionStore {
|
|||
.getSessions(filter.toJson?.() || filter)
|
||||
.then((response: any) => {
|
||||
resolve({
|
||||
sessions: response.sessions.map((session: any) => new Session(session)),
|
||||
sessions: response.sessions.map(
|
||||
(session: any) => new Session(session)
|
||||
),
|
||||
total: response.total,
|
||||
});
|
||||
})
|
||||
|
|
@ -184,9 +213,11 @@ export default class SessionStore {
|
|||
async fetchLiveSessions(params = {}) {
|
||||
try {
|
||||
const data = await sessionService.getLiveSessions(params);
|
||||
this.liveSessions = data.map(session => new Session({ ...session, live: true }));
|
||||
this.liveSessions = data.map(
|
||||
(session) => new Session({ ...session, live: true })
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -200,22 +231,22 @@ export default class SessionStore {
|
|||
}
|
||||
setSessionFilter(cleanSessionFilters(params));
|
||||
const data = await sessionService.getSessions(params);
|
||||
const list = data.sessions.map(s => new Session(s))
|
||||
const list = data.sessions.map((s) => new Session(s));
|
||||
|
||||
this.list = list;
|
||||
this.total = data.total;
|
||||
this.sessionIds = data.sessions.map(s => s.sessionId);
|
||||
this.favoriteList = list.filter(s => s.favorite);
|
||||
this.sessionIds = data.sessions.map((s) => s.sessionId);
|
||||
this.favoriteList = list.filter((s) => s.favorite);
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async fetchSessionInfo(sessionId: string, isLive = false) {
|
||||
try {
|
||||
const { events } = store.getState().getIn(['filters', 'appliedFilter']);
|
||||
const data = await sessionService.getSessionInfo(sessionId, isLive)
|
||||
const session = new Session(data)
|
||||
const data = await sessionService.getSessionInfo(sessionId, isLive);
|
||||
const session = new Session(data);
|
||||
|
||||
const matching: number[] = [];
|
||||
const visitedEvents: Location[] = [];
|
||||
|
|
@ -228,7 +259,6 @@ export default class SessionStore {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
(events as {}[]).forEach(({ key, operator, value }: any) => {
|
||||
session.events.forEach((e, index) => {
|
||||
if (key === e.type) {
|
||||
|
|
@ -243,16 +273,16 @@ export default class SessionStore {
|
|||
});
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async fetchErrorStack(sessionId: string, errorId: string) {
|
||||
try {
|
||||
const data = await sessionService.getErrorStack(sessionId, errorId);
|
||||
this.errorStack = data.trace.map(es => new ErrorStack(es))
|
||||
this.errorStack = data.trace.map((es) => new ErrorStack(es));
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -260,68 +290,74 @@ export default class SessionStore {
|
|||
try {
|
||||
setSessionFilter(cleanSessionFilters(params));
|
||||
const data = await sessionService.getAutoplayList(params);
|
||||
const list = [...this.sessionIds, ...data.map(s => s.sessionId)]
|
||||
const list = [...this.sessionIds, ...data.map((s) => s.sessionId)];
|
||||
this.sessionIds = list.filter((id, ind) => list.indexOf(id) === ind);
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
setAutoplayValues() {
|
||||
const currentId = this.current.sessionId
|
||||
const currentIndex = this.sessionIds.indexOf(currentId)
|
||||
const currentId = this.current.sessionId;
|
||||
const currentIndex = this.sessionIds.indexOf(currentId);
|
||||
|
||||
this.previousId = this.sessionIds[currentIndex - 1]
|
||||
this.nextId = this.sessionIds[currentIndex + 1]
|
||||
this.previousId = this.sessionIds[currentIndex - 1];
|
||||
this.nextId = this.sessionIds[currentIndex + 1];
|
||||
}
|
||||
|
||||
setEventQuery(filter: { query: string }) {
|
||||
const events = this.current.events
|
||||
const events = this.current.events;
|
||||
const query = filter.query;
|
||||
const searchRe = getRE(query, 'i')
|
||||
const searchRe = getRE(query, 'i');
|
||||
|
||||
const filteredEvents = query ? events.filter(
|
||||
(e) => searchRe.test(e.url)
|
||||
|| searchRe.test(e.value)
|
||||
|| searchRe.test(e.label)
|
||||
|| searchRe.test(e.type)
|
||||
|| (e.type === 'LOCATION' && searchRe.test('visited'))
|
||||
) : null;
|
||||
const filteredEvents = query
|
||||
? events.filter(
|
||||
(e) =>
|
||||
searchRe.test(e.url) ||
|
||||
searchRe.test(e.value) ||
|
||||
searchRe.test(e.label) ||
|
||||
searchRe.test(e.type) ||
|
||||
(e.type === 'LOCATION' && searchRe.test('visited'))
|
||||
)
|
||||
: null;
|
||||
|
||||
this.filteredEvents = filteredEvents
|
||||
this.eventsQuery = query
|
||||
this.filteredEvents = filteredEvents;
|
||||
this.eventsQuery = query;
|
||||
}
|
||||
|
||||
async toggleFavorite(id: string) {
|
||||
try {
|
||||
const r = await sessionService.toggleFavorite(id)
|
||||
const r = await sessionService.toggleFavorite(id);
|
||||
if (r.success) {
|
||||
const list = this.list;
|
||||
const current = this.current;
|
||||
const sessionIdx = list.findIndex(({ sessionId }) => sessionId === id);
|
||||
const session = list[sessionIdx]
|
||||
const wasInFavorite = this.favoriteList.findIndex(({ sessionId }) => sessionId === id) > -1;
|
||||
const session = list[sessionIdx];
|
||||
const wasInFavorite =
|
||||
this.favoriteList.findIndex(({ sessionId }) => sessionId === id) > -1;
|
||||
|
||||
if (session && !wasInFavorite) {
|
||||
session.favorite = true
|
||||
this.list[sessionIdx] = session
|
||||
session.favorite = true;
|
||||
this.list[sessionIdx] = session;
|
||||
}
|
||||
if (current.sessionId === id) {
|
||||
this.current.favorite = !wasInFavorite
|
||||
this.current.favorite = !wasInFavorite;
|
||||
}
|
||||
|
||||
if (session) {
|
||||
if (wasInFavorite) {
|
||||
this.favoriteList = this.favoriteList.filter(({ sessionId }) => sessionId !== id)
|
||||
this.favoriteList = this.favoriteList.filter(
|
||||
({ sessionId }) => sessionId !== id
|
||||
);
|
||||
} else {
|
||||
this.favoriteList.push(session)
|
||||
this.favoriteList.push(session);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error(r)
|
||||
console.error(r);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -333,18 +369,20 @@ export default class SessionStore {
|
|||
return sign * diff;
|
||||
};
|
||||
|
||||
this.list = this.list.sort(comparator)
|
||||
this.favoriteList = this.favoriteList.sort(comparator)
|
||||
this.list = this.list.sort(comparator);
|
||||
this.favoriteList = this.favoriteList.sort(comparator);
|
||||
return;
|
||||
}
|
||||
|
||||
setActiveTab(tab: { type: string }) {
|
||||
const list = tab.type === 'all'
|
||||
? this.list : this.list.filter(s => s.issueTypes.includes(tab.type))
|
||||
const list =
|
||||
tab.type === 'all'
|
||||
? this.list
|
||||
: this.list.filter((s) => s.issueTypes.includes(tab.type));
|
||||
|
||||
// @ts-ignore
|
||||
this.activeTab = tab
|
||||
this.sessionIds = list.map(s => s.sessionId)
|
||||
this.activeTab = tab;
|
||||
this.sessionIds = list.map((s) => s.sessionId);
|
||||
}
|
||||
|
||||
setTimezone(tz: string) {
|
||||
|
|
@ -352,80 +390,85 @@ export default class SessionStore {
|
|||
}
|
||||
|
||||
toggleChatWindow(isActive: boolean) {
|
||||
this.showChatWindow = isActive
|
||||
this.showChatWindow = isActive;
|
||||
}
|
||||
|
||||
async fetchInsights(filters = {}) {
|
||||
try {
|
||||
const data = await sessionService.getClickMap(filters)
|
||||
const data = await sessionService.getClickMap(filters);
|
||||
|
||||
this.insights = data
|
||||
this.insights = data;
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
setFunnelPage(page = {}) {
|
||||
this.funnelPage = page || false
|
||||
this.funnelPage = page || false;
|
||||
}
|
||||
|
||||
/* @deprecated */
|
||||
setTimelinePointer(pointer: {}) {
|
||||
this.timelinePointer = pointer
|
||||
this.timelinePointer = pointer;
|
||||
}
|
||||
|
||||
setTimelineTooltip(tp: { time: number, offset: number, isVisible: boolean, localTime: string, userTime?: string }) {
|
||||
this.timeLineTooltip = tp
|
||||
setTimelineTooltip(tp: {
|
||||
time: number;
|
||||
offset: number;
|
||||
isVisible: boolean;
|
||||
localTime: string;
|
||||
userTime?: string;
|
||||
}) {
|
||||
this.timeLineTooltip = tp;
|
||||
}
|
||||
|
||||
filterOutNote(noteId: string) {
|
||||
const current = this.current
|
||||
const current = this.current;
|
||||
|
||||
current.notesWithEvents = current.notesWithEvents.filter(n => {
|
||||
current.notesWithEvents = current.notesWithEvents.filter((n) => {
|
||||
if ('noteId' in item) {
|
||||
return item.noteId !== noteId
|
||||
return item.noteId !== noteId;
|
||||
}
|
||||
return true
|
||||
})
|
||||
return true;
|
||||
});
|
||||
|
||||
this.current = current
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
addNote(note: Note) {
|
||||
const current = this.current
|
||||
const current = this.current;
|
||||
|
||||
current.notesWithEvents.push(note)
|
||||
current.notesWithEvents.sort((a,b) => {
|
||||
const aTs = a.time || a.timestamp
|
||||
const bTs = b.time || b.timestamp
|
||||
current.notesWithEvents.push(note);
|
||||
current.notesWithEvents.sort((a, b) => {
|
||||
const aTs = a.time || a.timestamp;
|
||||
const bTs = b.time || b.timestamp;
|
||||
|
||||
return aTs - bTs
|
||||
})
|
||||
return aTs - bTs;
|
||||
});
|
||||
|
||||
this.current = current
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
updateNote(note: Note) {
|
||||
const noteIndex = this.current.notesWithEvents.findIndex(item => {
|
||||
if ('noteId' in item) {
|
||||
return item.noteId === note.noteId
|
||||
}
|
||||
return false
|
||||
})
|
||||
const noteIndex = this.current.notesWithEvents.findIndex((item) => {
|
||||
if ('noteId' in item) {
|
||||
return item.noteId === note.noteId;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
this.current.notesWithEvents[noteIndex] = note
|
||||
this.current.notesWithEvents[noteIndex] = note;
|
||||
}
|
||||
|
||||
setSessionPath(path = {}) {
|
||||
this.sessionPath = path
|
||||
this.sessionPath = path;
|
||||
}
|
||||
|
||||
setLastPlayed(sessionId: string) {
|
||||
const list = this.list
|
||||
const sIndex = list.findIndex((s) => s.sessionId === sessionId)
|
||||
const list = this.list;
|
||||
const sIndex = list.findIndex((s) => s.sessionId === sessionId);
|
||||
if (sIndex !== -1) {
|
||||
this.list[sIndex].viewed = true
|
||||
this.list[sIndex].viewed = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue