change(ui): duck/customMetrics cleanup and upgrades

This commit is contained in:
Shekar Siri 2024-09-17 15:04:26 +05:30
parent 2c12aa5239
commit 6c56567580
14 changed files with 218 additions and 262 deletions

View file

@ -10,14 +10,13 @@ import {
GLOBAL_DESTINATION_PATH,
IFRAME,
JWT_PARAM,
SPOT_ONBOARDING,
SPOT_ONBOARDING
} from 'App/constants/storageKeys';
import Layout from 'App/layout/Layout';
import { withStore } from 'App/mstore';
import { useStore, withStore } from 'App/mstore';
import { checkParam, handleSpotJWT, isTokenExpired } from 'App/utils';
import { ModalProvider } from 'Components/Modal';
import { ModalProvider as NewModalProvider } from 'Components/ModalContext';
import { fetchListActive as fetchMetadata } from 'Duck/customField';
import { setSessionPath } from 'Duck/sessions';
import { fetchList as fetchSiteList } from 'Duck/site';
import { init as initSite } from 'Duck/site';
@ -43,7 +42,6 @@ interface RouterProps
};
mstore: any;
setJwt: (params: { jwt: string; spotJwt: string | null }) => any;
fetchMetadata: (siteId: string) => void;
initSite: (site: any) => void;
scopeSetup: boolean;
localSpotJwt: string | null;
@ -62,8 +60,9 @@ const Router: React.FC<RouterProps> = (props) => {
setSessionPath,
scopeSetup,
localSpotJwt,
logout,
logout
} = props;
const { customFieldStore } = useStore();
const params = new URLSearchParams(location.search);
const spotCb = params.get('spotCallback');
@ -175,12 +174,16 @@ const Router: React.FC<RouterProps> = (props) => {
}, [isSpotCb, isLoggedIn, localSpotJwt, isSignup]);
useEffect(() => {
if (siteId && siteId !== lastFetchedSiteIdRef.current) {
const activeSite = sites.find((s) => s.id == siteId);
props.initSite(activeSite);
props.fetchMetadata(siteId);
lastFetchedSiteIdRef.current = siteId;
}
const fetchData = async () => {
if (siteId && siteId !== lastFetchedSiteIdRef.current) {
const activeSite = sites.find((s) => s.id == siteId);
props.initSite(activeSite);
lastFetchedSiteIdRef.current = activeSite.id;
await customFieldStore.fetchListActive(siteId + '');
}
};
fetchData();
}, [siteId]);
const lastFetchedSiteIdRef = useRef<any>(null);
@ -232,7 +235,7 @@ const mapStateToProps = (state: Map<string, any>) => {
const userInfoLoading = state.getIn([
'user',
'fetchUserInfoRequest',
'loading',
'loading'
]);
const sitesLoading = state.getIn(['site', 'fetchListRequest', 'loading']);
const scopeSetup = getScope(state) === 0;
@ -256,7 +259,7 @@ const mapStateToProps = (state: Map<string, any>) => {
tenants: state.getIn(['user', 'tenants']),
isEnterprise:
state.getIn(['user', 'account', 'edition']) === 'ee' ||
state.getIn(['user', 'authDetails', 'edition']) === 'ee',
state.getIn(['user', 'authDetails', 'edition']) === 'ee'
};
};
@ -265,9 +268,8 @@ const mapDispatchToProps = {
setSessionPath,
fetchSiteList,
setJwt,
fetchMetadata,
initSite,
logout,
logout
};
const connector = connect(mapStateToProps, mapDispatchToProps);

View file

@ -1,92 +0,0 @@
import React from 'react';
import { connect } from 'react-redux';
import { setSiteId } from 'Duck/site';
import { withRouter } from 'react-router-dom';
import { hasSiteId, siteChangeAvailable } from 'App/routes';
import { Icon } from 'UI';
import { pushNewSite } from 'Duck/user';
import { init } from 'Duck/site';
import styles from './siteDropdown.module.css';
import cn from 'classnames';
import { clearSearch } from 'Duck/search';
import { clearSearch as clearSearchLive } from 'Duck/liveSearch';
import { fetchListActive as fetchIntegrationVariables } from 'Duck/customField';
import { withStore } from 'App/mstore';
import NewProjectButton from './NewProjectButton';
@withStore
@withRouter
@connect(
(state) => ({
sites: state.getIn(['site', 'list']),
siteId: state.getIn(['site', 'siteId']),
account: state.getIn(['user', 'account']),
}),
{
setSiteId,
pushNewSite,
init,
clearSearch,
clearSearchLive,
fetchIntegrationVariables,
}
)
export default class SiteDropdown extends React.PureComponent {
state = { showProductModal: false };
closeModal = (e, newSite) => {
this.setState({ showProductModal: false });
};
newSite = () => {
this.props.init({});
this.setState({ showProductModal: true });
};
switchSite = (siteId) => {
const { mstore, location } = this.props;
this.props.setSiteId(siteId);
this.props.fetchIntegrationVariables();
this.props.clearSearch(location.pathname.includes('/sessions'));
this.props.clearSearchLive();
mstore.initClient();
};
render() {
const {
sites,
siteId,
account,
location: { pathname },
} = this.props;
const isAdmin = account.admin || account.superAdmin;
const activeSite = sites.find((s) => s.id == siteId);
const disabled = !siteChangeAvailable(pathname);
const showCurrent = hasSiteId(pathname) || siteChangeAvailable(pathname);
return (
<div style={{ width: '180px'}}>
<div className={styles.wrapper}>
<div className={cn(styles.currentSite)}>
{showCurrent && activeSite ? activeSite.host : 'All Projects'}
</div>
<Icon className={styles.dropdownIcon} color="gray-dark" name="chevron-down" size="16" />
<div className={styles.menu}>
<ul data-can-disable={disabled}>
{isAdmin && <NewProjectButton onClick={this.newSite} isAdmin={isAdmin} />}
<div className="border-b border-dashed my-1" />
{sites.map((site) => (
<li key={site.id} onClick={() => this.switchSite(site.id)}>
<Icon name={site.platform === 'web' ? 'browser/browser' : 'mobile'} size="16" />
<span className="ml-3">{site.host}</span>
</li>
))}
</ul>
</div>
</div>
</div>
);
}
}

View file

@ -0,0 +1,72 @@
import React, { useEffect } from 'react';
import { Button, TagBadge } from 'UI';
import { connect } from 'react-redux';
import CustomFieldForm from '../../../Client/CustomFields/CustomFieldForm';
import { confirm } from 'UI';
import { useModal } from 'App/components/Modal';
import { toast } from 'react-toastify';
import { useStore } from 'App/mstore';
interface MetadataListProps {
site: { id: string };
}
const MetadataList: React.FC<MetadataListProps> = (props) => {
const { site } = props;
const { customFieldStore } = useStore();
const fields = customFieldStore.list;
const { showModal, hideModal } = useModal();
useEffect(() => {
customFieldStore.fetchList(site.id);
}, [site.id]);
const save = (field: any) => {
customFieldStore.save(site.id, field).then((response) => {
if (!response || !response.errors || response.errors.size === 0) {
hideModal();
toast.success('Metadata added successfully!');
} else {
toast.error(response.errors[0]);
}
});
};
const openModal = () => {
showModal(<CustomFieldForm siteId={site.id} onClose={hideModal} onSave={save} />, { right: true });
};
const removeMetadata = async (field: { index: number }) => {
if (
await confirm({
header: 'Metadata',
confirmation: 'Are you sure you want to remove?'
})
) {
customFieldStore.remove(site.id, field.index + '');
}
};
return (
<div className="py-2 flex">
<Button variant="outline" onClick={() => openModal()}>
Add Metadata
</Button>
<div className="flex ml-2">
{fields.map((f, index) => (
<TagBadge key={index} text={f.key} onRemove={() => removeMetadata(f)} outline />
))}
</div>
</div>
);
};
export default connect(
(state: any) => ({
site: state.getIn(['site', 'instance']),
fields: state.getIn(['customFields', 'list']).sortBy((i: any) => i.index),
field: state.getIn(['customFields', 'instance']),
loading: state.getIn(['customFields', 'fetchRequest', 'loading'])
})
)(MetadataList);

View file

@ -11,8 +11,8 @@ import Tabs from 'Components/Session/Tabs';
import { PlayerContext } from 'App/components/Session/playerContext';
import { observer } from 'mobx-react-lite';
import stl from '../ReplayPlayer/playerBlockHeader.module.css';
import { fetchListActive as fetchMetadata } from 'Duck/customField';
import { IFRAME } from 'App/constants/storageKeys';
import { useStore } from 'App/mstore';
const SESSIONS_ROUTE = sessionsRoute();
@ -23,6 +23,7 @@ function PlayerBlockHeader(props: any) {
const playerState = store?.get?.() || { width: 0, height: 0, showEvents: false };
const { width = 0, height = 0, showEvents = false } = playerState;
const { customFieldStore } = useStore();
const {
session,
@ -32,15 +33,13 @@ function PlayerBlockHeader(props: any) {
setActiveTab,
activeTab,
history,
sessionPath,
fetchMetadata,
} = props;
React.useEffect(() => {
const iframe = localStorage.getItem(IFRAME) || false;
setHideBack(!!iframe && iframe === 'true');
if (metaList.size === 0) fetchMetadata();
if (metaList.size === 0) customFieldStore.fetchList();
}, []);
const backHandler = () => {
@ -116,7 +115,6 @@ const PlayerHeaderCont = connect(
{
toggleFavorite,
setSessionPath,
fetchMetadata,
}
)(observer(PlayerBlockHeader));

View file

@ -16,7 +16,6 @@ import Tabs from 'Components/Session/Tabs';
import { PlayerContext } from 'App/components/Session/playerContext';
import { observer } from 'mobx-react-lite';
import stl from './playerBlockHeader.module.css';
import { fetchListActive as fetchMetadata } from 'Duck/customField';
import { IFRAME } from 'App/constants/storageKeys';
const SESSIONS_ROUTE = sessionsRoute();
@ -25,7 +24,7 @@ const SESSIONS_ROUTE = sessionsRoute();
function PlayerBlockHeader(props: any) {
const [hideBack, setHideBack] = React.useState(false);
const { player, store } = React.useContext(PlayerContext);
const { uxtestingStore } = useStore()
const { uxtestingStore, customFieldStore } = useStore()
const playerState = store?.get?.() || { width: 0, height: 0, showEvents: false }
const { width = 0, height = 0, showEvents = false } = playerState
@ -39,14 +38,13 @@ function PlayerBlockHeader(props: any) {
activeTab,
history,
sessionPath,
fetchMetadata,
} = props;
React.useEffect(() => {
const iframe = localStorage.getItem(IFRAME) || false;
setHideBack(!!iframe && iframe === 'true');
if (metaList.size === 0) fetchMetadata();
if (metaList.size === 0) customFieldStore.fetchList();
}, []);
const backHandler = () => {
@ -146,7 +144,6 @@ const PlayerHeaderCont = connect(
{
toggleFavorite,
setSessionPath,
fetchMetadata,
}
)(observer(PlayerBlockHeader));

View file

@ -11,7 +11,6 @@ import { KEYS } from 'Types/filter/customFilter';
import { capitalize } from 'App/utils';
import { useStore } from 'App/mstore';
import { observer } from 'mobx-react-lite';
import { fetchList as fetchMeta } from 'Duck/customField';
import AssistSearchField from 'App/components/Assist/AssistSearchField';
import LiveSessionSearch from 'Shared/LiveSessionSearch';
import cn from 'classnames';
@ -19,7 +18,9 @@ import Session from 'App/mstore/types/session';
const PER_PAGE = 10;
interface OwnProps {}
interface OwnProps {
}
interface ConnectProps {
loading: boolean;
metaListLoading: boolean;
@ -34,30 +35,30 @@ interface ConnectProps {
updateCurrentPage: (page: number) => void;
applyFilter: (filter: any) => void;
onAdd: () => void;
fetchMeta: () => void;
}
type Props = OwnProps & ConnectProps;
function AssistSessionsModal(props: Props) {
const { assistMultiviewStore } = useStore();
const { loading, list, metaList = [], filter, currentPage, total, onAdd, fetchMeta } = props;
const { assistMultiviewStore, customFieldStore } = useStore();
const { loading, list, filter, currentPage, total, onAdd } = props;
const onUserClick = () => false;
const { filters } = filter;
const hasUserFilter = filters.map((i: any) => i.key).includes(KEYS.USERID);
const metaList = customFieldStore.list;
const sortOptions = metaList
.map((i: any) => ({
label: capitalize(i),
value: i,
}))
.toJS();
value: i
}));
React.useEffect(() => {
if (total === 0) {
reloadSessions();
}
fetchMeta();
// fetchMeta();
customFieldStore.fetchList();
}, []);
const reloadSessions = () => props.applyFilter({ ...filter });
const onSortChange = ({ value }: any) => {
@ -109,37 +110,37 @@ function AssistSessionsModal(props: Props) {
<LiveSessionSearch />
<div className="my-4" />
<Loader loading={loading}>
<div className={'overflow-y-scroll'} style={{ maxHeight: '85vh'}}>
{list.map((session) => (
<React.Fragment key={session.sessionId}>
<div
className={cn(
'rounded bg-white mb-2 overflow-hidden border',
assistMultiviewStore.sessions.findIndex(
(s: Record<string, any>) => s.sessionId === session.sessionId
) !== -1
? 'cursor-not-allowed opacity-60'
: ''
)}
>
<SessionItem
key={session.sessionId}
session={session}
live
hasUserFilter={hasUserFilter}
onUserClick={onUserClick}
metaList={metaList}
isDisabled={
<div className={'overflow-y-scroll'} style={{ maxHeight: '85vh' }}>
{list.map((session) => (
<React.Fragment key={session.sessionId}>
<div
className={cn(
'rounded bg-white mb-2 overflow-hidden border',
assistMultiviewStore.sessions.findIndex(
(s: Record<string, any>) => s.sessionId === session.sessionId
) !== -1
}
isAdd
onClick={() => onSessionAdd(session)}
/>
</div>
</React.Fragment>
))}
? 'cursor-not-allowed opacity-60'
: ''
)}
>
<SessionItem
key={session.sessionId}
session={session}
live
hasUserFilter={hasUserFilter}
onUserClick={onUserClick}
metaList={metaList}
isDisabled={
assistMultiviewStore.sessions.findIndex(
(s: Record<string, any>) => s.sessionId === session.sessionId
) !== -1
}
isAdd
onClick={() => onSessionAdd(session)}
/>
</div>
</React.Fragment>
))}
</div>
</Loader>
@ -166,12 +167,11 @@ export default connect(
total: state.getIn(['liveSearch', 'total']),
currentPage: state.getIn(['liveSearch', 'currentPage']),
metaList: state.getIn(['customFields', 'list']).map((i: any) => i.key),
sort: state.getIn(['liveSearch', 'sort']),
sort: state.getIn(['liveSearch', 'sort'])
}),
{
applyFilter,
addFilterByKeyAndValue,
updateCurrentPage,
fetchMeta,
updateCurrentPage
}
)(observer(AssistSessionsModal));

View file

@ -8,11 +8,10 @@ import React from 'react';
import { connect } from 'react-redux';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { withStore } from 'App/mstore';
import { useStore, withStore } from 'App/mstore';
import { hasSiteId, siteChangeAvailable } from 'App/routes';
import NewSiteForm from 'Components/Client/Sites/NewSiteForm';
import { useModal } from 'Components/Modal';
import { fetchListActive as fetchMetadata } from 'Duck/customField';
import { clearSearch as clearSearchLive } from 'Duck/liveSearch';
import { clearSearch } from 'Duck/search';
import { setSiteId } from 'Duck/site';
@ -31,7 +30,6 @@ interface Props extends RouteComponentProps {
sites: Site[];
siteId: string;
setSiteId: (siteId: string) => void;
fetchMetadata: () => void;
clearSearch: (isSession: boolean) => void;
clearSearchLive: () => void;
initProject: (data: any) => void;
@ -46,10 +44,11 @@ function ProjectDropdown(props: Props) {
const showCurrent =
hasSiteId(location.pathname) || siteChangeAvailable(location.pathname);
const { showModal, hideModal } = useModal();
const { customFieldStore } = useStore();
const handleSiteChange = (newSiteId: string) => {
const handleSiteChange = async (newSiteId: string) => {
props.setSiteId(newSiteId); // Fixed: should set the new siteId, not the existing one
props.fetchMetadata();
await customFieldStore.fetchList(newSiteId)
props.clearSearch(location.pathname.includes('/sessions'));
props.clearSearchLive();
@ -151,7 +150,6 @@ const mapStateToProps = (state: any) => ({
export default withRouter(
connect(mapStateToProps, {
setSiteId,
fetchMetadata,
clearSearch,
clearSearchLive,
initProject,

View file

@ -13,7 +13,6 @@ import {
checkForLatestSessions
} from 'Duck/search';
import { numberWithCommas } from 'App/utils';
import { fetchListActive as fetchMetadata } from 'Duck/customField';
import { toggleFavorite } from 'Duck/sessions';
import SessionDateRange from './SessionDateRange';
import RecordingStatus from 'Shared/SessionsTabOverview/components/RecordingStatus';
@ -51,7 +50,6 @@ interface Props extends RouteComponentProps {
updateCurrentPage: (page: number) => void;
setScrollPosition: (scrollPosition: number) => void;
fetchSessions: (filters: any, force: boolean) => void;
fetchMetadata: () => void;
updateProjectRecordingStatus: (siteId: string, status: boolean) => void;
activeTab: any;
isEnterprise?: boolean;
@ -87,6 +85,7 @@ function SessionList(props: Props) {
const activeSite: any = sites.find((s: any) => s.id === siteId);
const hasNoRecordings = !activeSite || !activeSite.recorded;
const NO_CONTENT = React.useMemo(() => {
if (isBookmark && !isEnterprise) {
setNoContentType(NoContentType.Bookmarked);
@ -165,7 +164,6 @@ function SessionList(props: Props) {
props.fetchSessions(null, true);
}, 300);
}
// props.fetchMetadata();
return () => {
props.setScrollPosition(window.scrollY);
@ -304,7 +302,6 @@ export default connect(
addFilterByKeyAndValue,
setScrollPosition,
fetchSessions,
fetchMetadata,
checkForLatestSessions,
toggleFavorite,
updateProjectRecordingStatus

View file

@ -4,7 +4,6 @@ import SideMenu from 'App/layout/SideMenu';
import TopHeader from 'App/layout/TopHeader';
import { useStore } from 'App/mstore';
import { observer } from 'mobx-react-lite';
import { fetchListActive as fetchMetadata } from 'Duck/customField';
import { init as initSite } from 'Duck/site';
import { connect } from 'react-redux';
@ -15,7 +14,6 @@ interface Props {
children: React.ReactNode;
hideHeader?: boolean;
siteId?: string;
fetchMetadata: (siteId: string) => void;
initSite: (site: any) => void;
sites: any[];
}
@ -25,18 +23,6 @@ function Layout(props: Props) {
const isPlayer = /\/(session|assist|view-spot)\//.test(window.location.pathname);
const { settingsStore } = useStore();
// const lastFetchedSiteIdRef = React.useRef<string | null>(null);
//
// useEffect(() => {
// if (!siteId || siteId === lastFetchedSiteIdRef.current) return;
//
// const activeSite = props.sites.find((s) => s.id == siteId);
// props.initSite(activeSite);
// props.fetchMetadata(siteId);
//
// lastFetchedSiteIdRef.current = siteId;
// }, [siteId]);
return (
<AntLayout style={{ minHeight: '100vh' }}>
{!hideHeader && (
@ -69,4 +55,4 @@ function Layout(props: Props) {
export default connect((state: any) => ({
siteId: state.getIn(['site', 'siteId']),
sites: state.getIn(['site', 'list'])
}), { fetchMetadata, initSite })(observer(Layout));
}), { initSite })(observer(Layout));

View file

@ -9,14 +9,12 @@ import { INDEXES } from 'App/constants/zindex';
import { connect } from 'react-redux';
import { logout } from 'Duck/user';
import { init as initSite } from 'Duck/site';
import { fetchListActive as fetchMetadata } from 'Duck/customField';
const { Header } = Layout;
interface Props {
account: any;
siteId: string;
fetchMetadata: (siteId: string) => void;
initSite: (site: any) => void;
}
@ -49,7 +47,7 @@ function TopHeader(props: Props) {
alignItems: 'center',
height: '60px'
}}
className='justify-between'
className="justify-between"
>
<Space>
<div
@ -57,14 +55,14 @@ function TopHeader(props: Props) {
settingsStore.updateMenuCollapsed(!settingsStore.menuCollapsed);
}}
style={{ paddingTop: '4px' }}
className='cursor-pointer'
className="cursor-pointer"
>
<Tooltip title={settingsStore.menuCollapsed ? 'Show Menu' : 'Hide Menu'} mouseEnterDelay={1}>
<Icon name={settingsStore.menuCollapsed ? 'side_menu_closed' : 'side_menu_open'} size={20} />
</Tooltip>
</div>
<div className='flex items-center'>
<div className="flex items-center">
<Logo siteId={siteId} />
</div>
</Space>
@ -81,8 +79,7 @@ const mapStateToProps = (state: any) => ({
const mapDispatchToProps = {
onLogoutClick: logout,
initSite,
fetchMetadata
initSite
};
export default connect(

View file

@ -15,8 +15,10 @@ import customFields from 'Components/Client/CustomFields';
class CustomFieldStore {
isLoading: boolean = false;
isAllLoading: boolean = false;
isSaving: boolean = false;
list: CustomField[] = [];
allList: CustomField[] = [];
instance: CustomField = new CustomField();
sources: CustomField[] = [];
fetchedMetadata: boolean = false;
@ -43,7 +45,7 @@ class CustomFieldStore {
async fetchListActive(siteId?: string): Promise<any> {
this.isLoading = true;
try {
const response = await customFieldService.get(siteId);
const response = await customFieldService.fetchList(siteId);
clearMetaFilters();
response.forEach((item: any) => {
addElementToFiltersMap(FilterCategory.METADATA, '_' + item.key);

View file

@ -1,29 +1,29 @@
import BaseService from './BaseService';
export default class CustomFieldService extends BaseService {
async fetchList(siteId: string): Promise<any> {
return this.client.get(siteId ? `/${siteId}/metadata` : '/metadata')
async fetchList(projectId?: string): Promise<any> {
return this.client.get(projectId ? `/${projectId}/metadata` : '/metadata')
.then(r => r.json()).then(j => j.data);
}
async get(siteId?: string): Promise<any> {
const url = siteId ? `/${siteId}/metadata` : '/metadata';
async get(projectId?: string): Promise<any> {
const url = projectId ? `/${projectId}/metadata` : '/PROJECT_ID/metadata';
return this.client.get(url)
.then(r => r.json()).then(j => j.data);
}
async create(siteId: string, customField: any): Promise<any> {
return this.client.post(`/${siteId}/metadata`, customField)
async create(projectId: string, customField: any): Promise<any> {
return this.client.post(`/${projectId}/metadata`, customField)
.then(r => r.json()).then(j => j.data);
}
async update(siteId: string, instance: any): Promise<any> {
return this.client.put(`/${siteId}/metadata/${instance.index}`, instance)
async update(projectId: string, instance: any): Promise<any> {
return this.client.put(`/${projectId}/metadata/${instance.index}`, instance)
.then(r => r.json()).then(j => j.data);
}
async delete(siteId: string, index: string): Promise<any> {
return this.client.delete(`/${siteId}/metadata/${index}`)
async delete(projectId: string, index: string): Promise<any> {
return this.client.delete(`/${projectId}/metadata/${index}`)
.then(r => r.json()).then(j => j.data);
}
}

View file

@ -108,7 +108,6 @@ export default Record({
key: '',
operator: 'is',
label: '',
icon: '',
type: '',
value: [""],
custom: '',

View file

@ -109,68 +109,68 @@ export default Record({
}
});
export const preloadedFilters = [];
// export const preloadedFilters = [];
export const defaultFilters = [
{
category: 'Interactions',
type: 'default',
keys: [
{ label: 'Click', key: KEYS.CLICK, type: KEYS.CLICK, filterKey: KEYS.CLICK, icon: 'filters/click', isFilter: false },
{ label: 'DOM Complete', key: KEYS.DOM_COMPLETE, type: KEYS.DOM_COMPLETE, filterKey: KEYS.DOM_COMPLETE, icon: 'filters/click', isFilter: false },
{ label: 'Largest Contentful Paint Time', key: KEYS.LARGEST_CONTENTFUL_PAINT_TIME, type: KEYS.LARGEST_CONTENTFUL_PAINT_TIME, filterKey: KEYS.LARGEST_CONTENTFUL_PAINT_TIME, icon: 'filters/click', isFilter: false },
{ label: 'Time Between Events', key: KEYS.TIME_BETWEEN_EVENTS, type: KEYS.TIME_BETWEEN_EVENTS, filterKey: KEYS.TIME_BETWEEN_EVENTS, icon: 'filters/click', isFilter: false },
{ label: 'Avg CPU Load', key: KEYS.AVG_CPU_LOAD, type: KEYS.AVG_CPU_LOAD, filterKey: KEYS.AVG_CPU_LOAD, icon: 'filters/click', isFilter: false },
{ label: 'Memory Usage', key: KEYS.AVG_MEMORY_USAGE, type: KEYS.AVG_MEMORY_USAGE, filterKey: KEYS.AVG_MEMORY_USAGE, icon: 'filters/click', isFilter: false },
{ label: 'Input', key: KEYS.INPUT, type: KEYS.INPUT, filterKey: KEYS.INPUT, icon: 'event/input', isFilter: false },
{ label: 'Path', key: KEYS.LOCATION, type: KEYS.LOCATION, filterKey: KEYS.LOCATION, icon: 'event/link', isFilter: false },
// { label: 'View', key: KEYS.VIEW, type: KEYS.VIEW, filterKey: KEYS.VIEW, icon: 'event/view', isFilter: false }
]
},
{
category: 'Gear',
type: 'default',
keys: [
{ label: 'OS', key: KEYS.USER_OS, type: KEYS.USER_OS, filterKey: KEYS.USER_OS, icon: 'os', isFilter: true },
{ label: 'Browser', key: KEYS.USER_BROWSER, type: KEYS.USER_BROWSER, filterKey: KEYS.USER_BROWSER, icon: 'window', isFilter: true },
{ label: 'Device', key: KEYS.USER_DEVICE, type: KEYS.USER_DEVICE, filterKey: KEYS.USER_DEVICE, icon: 'device', isFilter: true },
{ label: 'Rev ID', key: KEYS.REVID, type: KEYS.REVID, filterKey: KEYS.REVID, icon: 'filters/rev-id', isFilter: true },
{ label: 'Platform', key: KEYS.PLATFORM, type: KEYS.PLATFORM, filterKey: KEYS.PLATFORM, icon: 'filters/platform', isFilter: true },
]
},
{
category: 'Recording Attributes',
type: 'default',
keys: [
{ label: 'Referrer', key: KEYS.REFERRER, type: KEYS.REFERRER, filterKey: KEYS.REFERRER, icon: 'chat-square-quote', isFilter: true },
{ label: 'Duration', key: KEYS.DURATION, type: KEYS.DURATION, filterKey: KEYS.DURATION, icon: 'clock', isFilter: true },
{ label: 'Country', key: KEYS.USER_COUNTRY, type: KEYS.USER_COUNTRY, filterKey: KEYS.USER_COUNTRY, icon: 'map-marker-alt', isFilter: true },
]
},
{
category: 'Javascript',
type: 'default',
keys: [
{ label: 'Errors', key: KEYS.ERROR, type: KEYS.ERROR, filterKey: KEYS.ERROR, icon: 'exclamation-circle', isFilter: false },
{ label: 'Issues', key: KEYS.ISSUES, type: KEYS.ISSUES, filterKey: KEYS.ISSUES, icon: 'exclamation-circle', isFilter: true },
{ label: 'UTM Source', key: KEYS.UTM_SOURCE, type: KEYS.UTM_SOURCE, filterKey: KEYS.UTM_SOURCE, icon: 'exclamation-circle', isFilter: true },
{ label: 'UTM Medium', key: KEYS.UTM_MEDIUM, type: KEYS.UTM_MEDIUM, filterKey: KEYS.UTM_MEDIUM, icon: 'exclamation-circle', isFilter: true },
{ label: 'UTM Campaign', key: KEYS.UTM_CAMPAIGN, type: KEYS.UTM_CAMPAIGN, filterKey: KEYS.UTM_CAMPAIGN, icon: 'exclamation-circle', isFilter: true },
{ label: 'Fetch Requests', key: KEYS.FETCH, type: KEYS.FETCH, filterKey: KEYS.FETCH, icon: 'fetch', isFilter: false },
{ label: 'GraphQL Queries', key: KEYS.GRAPHQL, type: KEYS.GRAPHQL, filterKey: KEYS.GRAPHQL, icon: 'vendors/graphql', isFilter: false },
{ label: 'Store Actions', key: KEYS.STATEACTION, type: KEYS.STATEACTION, filterKey: KEYS.STATEACTION, icon: 'store', isFilter: false },
{ label: 'Custom Events', key: KEYS.CUSTOM, type: KEYS.CUSTOM, filterKey: KEYS.CUSTOM, icon: 'filters/file-code', isFilter: false },
]
},
{
category: 'User',
type: 'default',
keys: [
{ label: 'User ID', key: KEYS.USERID, type: KEYS.USERID, filterKey: KEYS.USERID, icon: 'filters/user-alt', isFilter: true },
{ label: 'Anonymous ID', key: KEYS.USERANONYMOUSID, type: KEYS.USERANONYMOUSID, filterKey: KEYS.USERANONYMOUSID, icon: 'filters/userid', isFilter: true },
]
}
];
// export const defaultFilters = [
// {
// category: 'Interactions',
// type: 'default',
// keys: [
// { label: 'Click', key: KEYS.CLICK, type: KEYS.CLICK, filterKey: KEYS.CLICK, icon: 'filters/click', isFilter: false },
// { label: 'DOM Complete', key: KEYS.DOM_COMPLETE, type: KEYS.DOM_COMPLETE, filterKey: KEYS.DOM_COMPLETE, icon: 'filters/click', isFilter: false },
// { label: 'Largest Contentful Paint Time', key: KEYS.LARGEST_CONTENTFUL_PAINT_TIME, type: KEYS.LARGEST_CONTENTFUL_PAINT_TIME, filterKey: KEYS.LARGEST_CONTENTFUL_PAINT_TIME, icon: 'filters/click', isFilter: false },
// { label: 'Time Between Events', key: KEYS.TIME_BETWEEN_EVENTS, type: KEYS.TIME_BETWEEN_EVENTS, filterKey: KEYS.TIME_BETWEEN_EVENTS, icon: 'filters/click', isFilter: false },
// { label: 'Avg CPU Load', key: KEYS.AVG_CPU_LOAD, type: KEYS.AVG_CPU_LOAD, filterKey: KEYS.AVG_CPU_LOAD, icon: 'filters/click', isFilter: false },
// { label: 'Memory Usage', key: KEYS.AVG_MEMORY_USAGE, type: KEYS.AVG_MEMORY_USAGE, filterKey: KEYS.AVG_MEMORY_USAGE, icon: 'filters/click', isFilter: false },
// { label: 'Input', key: KEYS.INPUT, type: KEYS.INPUT, filterKey: KEYS.INPUT, icon: 'event/input', isFilter: false },
// { label: 'Path', key: KEYS.LOCATION, type: KEYS.LOCATION, filterKey: KEYS.LOCATION, icon: 'event/link', isFilter: false },
// // { label: 'View', key: KEYS.VIEW, type: KEYS.VIEW, filterKey: KEYS.VIEW, icon: 'event/view', isFilter: false }
// ]
// },
// {
// category: 'Gear',
// type: 'default',
// keys: [
// { label: 'OS', key: KEYS.USER_OS, type: KEYS.USER_OS, filterKey: KEYS.USER_OS, icon: 'os', isFilter: true },
// { label: 'Browser', key: KEYS.USER_BROWSER, type: KEYS.USER_BROWSER, filterKey: KEYS.USER_BROWSER, icon: 'window', isFilter: true },
// { label: 'Device', key: KEYS.USER_DEVICE, type: KEYS.USER_DEVICE, filterKey: KEYS.USER_DEVICE, icon: 'device', isFilter: true },
// { label: 'Rev ID', key: KEYS.REVID, type: KEYS.REVID, filterKey: KEYS.REVID, icon: 'filters/rev-id', isFilter: true },
// { label: 'Platform', key: KEYS.PLATFORM, type: KEYS.PLATFORM, filterKey: KEYS.PLATFORM, icon: 'filters/platform', isFilter: true },
// ]
// },
// {
// category: 'Recording Attributes',
// type: 'default',
// keys: [
// { label: 'Referrer', key: KEYS.REFERRER, type: KEYS.REFERRER, filterKey: KEYS.REFERRER, icon: 'chat-square-quote', isFilter: true },
// { label: 'Duration', key: KEYS.DURATION, type: KEYS.DURATION, filterKey: KEYS.DURATION, icon: 'clock', isFilter: true },
// { label: 'Country', key: KEYS.USER_COUNTRY, type: KEYS.USER_COUNTRY, filterKey: KEYS.USER_COUNTRY, icon: 'map-marker-alt', isFilter: true },
// ]
// },
// {
// category: 'Javascript',
// type: 'default',
// keys: [
// { label: 'Errors', key: KEYS.ERROR, type: KEYS.ERROR, filterKey: KEYS.ERROR, icon: 'exclamation-circle', isFilter: false },
// { label: 'Issues', key: KEYS.ISSUES, type: KEYS.ISSUES, filterKey: KEYS.ISSUES, icon: 'exclamation-circle', isFilter: true },
// { label: 'UTM Source', key: KEYS.UTM_SOURCE, type: KEYS.UTM_SOURCE, filterKey: KEYS.UTM_SOURCE, icon: 'exclamation-circle', isFilter: true },
// { label: 'UTM Medium', key: KEYS.UTM_MEDIUM, type: KEYS.UTM_MEDIUM, filterKey: KEYS.UTM_MEDIUM, icon: 'exclamation-circle', isFilter: true },
// { label: 'UTM Campaign', key: KEYS.UTM_CAMPAIGN, type: KEYS.UTM_CAMPAIGN, filterKey: KEYS.UTM_CAMPAIGN, icon: 'exclamation-circle', isFilter: true },
// { label: 'Fetch Requests', key: KEYS.FETCH, type: KEYS.FETCH, filterKey: KEYS.FETCH, icon: 'fetch', isFilter: false },
// { label: 'GraphQL Queries', key: KEYS.GRAPHQL, type: KEYS.GRAPHQL, filterKey: KEYS.GRAPHQL, icon: 'vendors/graphql', isFilter: false },
// { label: 'Store Actions', key: KEYS.STATEACTION, type: KEYS.STATEACTION, filterKey: KEYS.STATEACTION, icon: 'store', isFilter: false },
// { label: 'Custom Events', key: KEYS.CUSTOM, type: KEYS.CUSTOM, filterKey: KEYS.CUSTOM, icon: 'filters/file-code', isFilter: false },
// ]
// },
// {
// category: 'User',
// type: 'default',
// keys: [
// { label: 'User ID', key: KEYS.USERID, type: KEYS.USERID, filterKey: KEYS.USERID, icon: 'filters/user-alt', isFilter: true },
// { label: 'Anonymous ID', key: KEYS.USERANONYMOUSID, type: KEYS.USERANONYMOUSID, filterKey: KEYS.USERANONYMOUSID, icon: 'filters/userid', isFilter: true },
// ]
// }
// ];
export const getEventIcon = (filter) => {
let { type, key, source } = filter;