ui: remove search field, show filters picker by default for assist
This commit is contained in:
parent
b941ea2cd8
commit
da632304a1
5 changed files with 304 additions and 312 deletions
|
|
@ -6,7 +6,6 @@ import AssistSearchField from './AssistSearchField';
|
|||
function AssistView() {
|
||||
return (
|
||||
<div className="w-full mx-auto" style={{ maxWidth: '1360px'}}>
|
||||
<AssistSearchField />
|
||||
<LiveSessionSearch />
|
||||
<div className="my-4" />
|
||||
<LiveSessionList />
|
||||
|
|
|
|||
|
|
@ -1,223 +1,240 @@
|
|||
import {Space} from 'antd';
|
||||
import {List} from 'immutable';
|
||||
import {GripHorizontal} from 'lucide-react';
|
||||
import {observer} from 'mobx-react-lite';
|
||||
import React, {useEffect} from 'react';
|
||||
import { Space } from 'antd';
|
||||
import { List } from 'immutable';
|
||||
import { GripHorizontal } from 'lucide-react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Button, Card } from 'antd';
|
||||
import { Icon } from 'UI';
|
||||
|
||||
import FilterItem from '../FilterItem';
|
||||
import EventsOrder from "Shared/Filters/FilterList/EventsOrder";
|
||||
import EventsOrder from 'Shared/Filters/FilterList/EventsOrder';
|
||||
import FilterSelection from '../FilterSelection/FilterSelection';
|
||||
|
||||
interface Props {
|
||||
filter?: any; // event/filter
|
||||
onUpdateFilter: (filterIndex: any, filter: any) => void;
|
||||
onFilterMove?: (filters: any) => void;
|
||||
onRemoveFilter: (filterIndex: any) => void;
|
||||
onChangeEventsOrder: (e: any, {name, value}: any) => void;
|
||||
hideEventsOrder?: boolean;
|
||||
observeChanges?: () => void;
|
||||
saveRequestPayloads?: boolean;
|
||||
supportsEmpty?: boolean;
|
||||
readonly?: boolean;
|
||||
excludeFilterKeys?: Array<string>;
|
||||
isConditional?: boolean;
|
||||
actions?: React.ReactNode[];
|
||||
filter?: any; // event/filter
|
||||
onUpdateFilter: (filterIndex: any, filter: any) => void;
|
||||
onFilterMove?: (filters: any) => void;
|
||||
onRemoveFilter: (filterIndex: any) => void;
|
||||
onChangeEventsOrder: (e: any, { name, value }: any) => void;
|
||||
hideEventsOrder?: boolean;
|
||||
observeChanges?: () => void;
|
||||
saveRequestPayloads?: boolean;
|
||||
supportsEmpty?: boolean;
|
||||
readonly?: boolean;
|
||||
excludeFilterKeys?: Array<string>;
|
||||
isConditional?: boolean;
|
||||
actions?: React.ReactNode[];
|
||||
onlyFilters?: boolean;
|
||||
onAddFilter: (filter: any) => void;
|
||||
}
|
||||
|
||||
function FilterList(props: Props) {
|
||||
const {
|
||||
observeChanges = () => {
|
||||
},
|
||||
filter,
|
||||
hideEventsOrder = false,
|
||||
saveRequestPayloads,
|
||||
supportsEmpty = true,
|
||||
excludeFilterKeys = [],
|
||||
isConditional,
|
||||
actions = []
|
||||
} = props;
|
||||
const {
|
||||
observeChanges = () => {},
|
||||
filter,
|
||||
hideEventsOrder = false,
|
||||
saveRequestPayloads,
|
||||
supportsEmpty = true,
|
||||
excludeFilterKeys = [],
|
||||
isConditional,
|
||||
actions = [],
|
||||
onAddFilter,
|
||||
onlyFilters,
|
||||
} = props;
|
||||
|
||||
const filters = filter.filters;
|
||||
const hasEvents = filters.filter((i: any) => i.isEvent).length > 0;
|
||||
const hasFilters = filters.filter((i: any) => !i.isEvent).length > 0;
|
||||
const filters = filter.filters;
|
||||
const hasEvents = filters.filter((i: any) => i.isEvent).length > 0;
|
||||
const hasFilters = filters.filter((i: any) => !i.isEvent).length > 0;
|
||||
|
||||
let rowIndex = 0;
|
||||
const cannotDeleteFilter = hasEvents && !supportsEmpty;
|
||||
let rowIndex = 0;
|
||||
const cannotDeleteFilter = hasEvents && !supportsEmpty;
|
||||
|
||||
useEffect(observeChanges, [filters]);
|
||||
useEffect(observeChanges, [filters]);
|
||||
|
||||
const onRemoveFilter = (filterIndex: any) => {
|
||||
props.onRemoveFilter(filterIndex);
|
||||
};
|
||||
const onRemoveFilter = (filterIndex: any) => {
|
||||
props.onRemoveFilter(filterIndex);
|
||||
};
|
||||
|
||||
const [hoveredItem, setHoveredItem] = React.useState<Record<string, any>>({
|
||||
i: null,
|
||||
position: null,
|
||||
});
|
||||
const [draggedInd, setDraggedItem] = React.useState<number | null>(null);
|
||||
const [hoveredItem, setHoveredItem] = React.useState<Record<string, any>>({
|
||||
i: null,
|
||||
position: null,
|
||||
});
|
||||
const [draggedInd, setDraggedItem] = React.useState<number | null>(null);
|
||||
|
||||
const handleDragOverEv = (event: Record<string, any>, i: number) => {
|
||||
event.preventDefault();
|
||||
const target = event.currentTarget.getBoundingClientRect();
|
||||
const hoverMiddleY = (target.bottom - target.top) / 2;
|
||||
const hoverClientY = event.clientY - target.top;
|
||||
const handleDragOverEv = (event: Record<string, any>, i: number) => {
|
||||
event.preventDefault();
|
||||
const target = event.currentTarget.getBoundingClientRect();
|
||||
const hoverMiddleY = (target.bottom - target.top) / 2;
|
||||
const hoverClientY = event.clientY - target.top;
|
||||
|
||||
const position = hoverClientY < hoverMiddleY ? 'top' : 'bottom';
|
||||
setHoveredItem({position, i});
|
||||
};
|
||||
const position = hoverClientY < hoverMiddleY ? 'top' : 'bottom';
|
||||
setHoveredItem({ position, i });
|
||||
};
|
||||
|
||||
const calculateNewPosition = React.useCallback(
|
||||
(draggedInd: number, hoveredIndex: number, hoveredPosition: string) => {
|
||||
if (hoveredPosition === 'bottom') {
|
||||
hoveredIndex++;
|
||||
}
|
||||
return draggedInd < hoveredIndex ? hoveredIndex - 1 : hoveredIndex;
|
||||
},
|
||||
[]
|
||||
);
|
||||
const calculateNewPosition = React.useCallback(
|
||||
(draggedInd: number, hoveredIndex: number, hoveredPosition: string) => {
|
||||
if (hoveredPosition === 'bottom') {
|
||||
hoveredIndex++;
|
||||
}
|
||||
return draggedInd < hoveredIndex ? hoveredIndex - 1 : hoveredIndex;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const handleDragStart = React.useCallback((
|
||||
ev: Record<string, any>,
|
||||
index: number,
|
||||
elId: string
|
||||
) => {
|
||||
ev.dataTransfer.setData("text/plain", index.toString());
|
||||
setDraggedItem(index);
|
||||
const el = document.getElementById(elId);
|
||||
if (el) {
|
||||
ev.dataTransfer.setDragImage(el, 0, 0);
|
||||
}
|
||||
}, [])
|
||||
const handleDragStart = React.useCallback(
|
||||
(ev: Record<string, any>, index: number, elId: string) => {
|
||||
ev.dataTransfer.setData('text/plain', index.toString());
|
||||
setDraggedItem(index);
|
||||
const el = document.getElementById(elId);
|
||||
if (el) {
|
||||
ev.dataTransfer.setDragImage(el, 0, 0);
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const handleDrop = React.useCallback(
|
||||
(event: Record<string, any>) => {
|
||||
event.preventDefault();
|
||||
if (draggedInd === null) return;
|
||||
const newItems = filters.toArray();
|
||||
const newPosition = calculateNewPosition(
|
||||
draggedInd,
|
||||
hoveredItem.i,
|
||||
hoveredItem.position
|
||||
);
|
||||
const handleDrop = React.useCallback(
|
||||
(event: Record<string, any>) => {
|
||||
event.preventDefault();
|
||||
if (draggedInd === null) return;
|
||||
const newItems = filters.toArray();
|
||||
const newPosition = calculateNewPosition(
|
||||
draggedInd,
|
||||
hoveredItem.i,
|
||||
hoveredItem.position
|
||||
);
|
||||
|
||||
const reorderedItem = newItems.splice(draggedInd, 1)[0];
|
||||
newItems.splice(newPosition, 0, reorderedItem);
|
||||
const reorderedItem = newItems.splice(draggedInd, 1)[0];
|
||||
newItems.splice(newPosition, 0, reorderedItem);
|
||||
|
||||
props.onFilterMove?.(List(newItems));
|
||||
setHoveredItem({i: null, position: null});
|
||||
setDraggedItem(null);
|
||||
},
|
||||
[draggedInd, hoveredItem, filters, props.onFilterMove]
|
||||
);
|
||||
props.onFilterMove?.(List(newItems));
|
||||
setHoveredItem({ i: null, position: null });
|
||||
setDraggedItem(null);
|
||||
},
|
||||
[draggedInd, hoveredItem, filters, props.onFilterMove]
|
||||
);
|
||||
|
||||
const eventsNum = filters.filter((i: any) => i.isEvent).size
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
{hasEvents && (
|
||||
<>
|
||||
<div className="flex items-center mb-2">
|
||||
<div className="text-sm color-gray-medium mr-auto">
|
||||
{filter.eventsHeader || 'EVENTS'}
|
||||
</div>
|
||||
const eventsNum = filters.filter((i: any) => i.isEvent).size;
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
{onlyFilters ? null : (<Card size={'small'}>
|
||||
<div className="flex items-center mb-2">
|
||||
<div className="font-semibold">
|
||||
{filter.eventsHeader || 'Events'}
|
||||
</div>
|
||||
|
||||
<Space>
|
||||
{!hideEventsOrder && <EventsOrder filter={filter}
|
||||
onChange={props.onChangeEventsOrder}/>}
|
||||
{actions && actions.map((action, index) => (
|
||||
<div key={index}>{action}</div>
|
||||
))}
|
||||
</Space>
|
||||
<Space>
|
||||
{!hideEventsOrder && (
|
||||
<EventsOrder
|
||||
filter={filter}
|
||||
onChange={props.onChangeEventsOrder}
|
||||
/>
|
||||
)}
|
||||
{actions &&
|
||||
actions.map((action, index) => <div key={index}>{action}</div>)}
|
||||
</Space>
|
||||
</div>
|
||||
<div className={'flex flex-col'}>
|
||||
{filters.map((filter: any, filterIndex: number) =>
|
||||
filter.isEvent ? (
|
||||
<div
|
||||
style={{
|
||||
pointerEvents: 'unset',
|
||||
paddingTop:
|
||||
hoveredItem.i === filterIndex &&
|
||||
hoveredItem.position === 'top'
|
||||
? '1.5rem'
|
||||
: '0.5rem',
|
||||
paddingBottom:
|
||||
hoveredItem.i === filterIndex &&
|
||||
hoveredItem.position === 'bottom'
|
||||
? '1.5rem'
|
||||
: '0.5rem',
|
||||
marginLeft: '-1.25rem',
|
||||
width: 'calc(100% + 2.5rem)',
|
||||
}}
|
||||
className={
|
||||
'hover:bg-active-blue px-5 gap-2 items-center flex'
|
||||
}
|
||||
id={`${filter.key}-${filterIndex}`}
|
||||
onDragOver={(e) => handleDragOverEv(e, filterIndex)}
|
||||
onDrop={(e) => handleDrop(e)}
|
||||
key={`${filter.key}-${filterIndex}`}
|
||||
>
|
||||
{!!props.onFilterMove && eventsNum > 1 ? (
|
||||
<div
|
||||
className={'p-2 cursor-grab'}
|
||||
draggable={!!props.onFilterMove}
|
||||
onDragStart={(e) =>
|
||||
handleDragStart(
|
||||
e,
|
||||
filterIndex,
|
||||
`${filter.key}-${filterIndex}`
|
||||
)
|
||||
}
|
||||
>
|
||||
<GripHorizontal size={16} />
|
||||
</div>
|
||||
<div className={'flex flex-col'}>
|
||||
{filters.map((filter: any, filterIndex: number) =>
|
||||
filter.isEvent ? (
|
||||
<div
|
||||
style={{
|
||||
pointerEvents: 'unset',
|
||||
paddingTop:
|
||||
hoveredItem.i === filterIndex &&
|
||||
hoveredItem.position === 'top'
|
||||
? '1.5rem'
|
||||
: '0.5rem',
|
||||
paddingBottom:
|
||||
hoveredItem.i === filterIndex &&
|
||||
hoveredItem.position === 'bottom'
|
||||
? '1.5rem'
|
||||
: '0.5rem',
|
||||
marginLeft: '-1.25rem',
|
||||
width: 'calc(100% + 2.5rem)',
|
||||
}}
|
||||
className={
|
||||
'hover:bg-active-blue px-5 gap-2 items-center flex'
|
||||
}
|
||||
id={`${filter.key}-${filterIndex}`}
|
||||
onDragOver={(e) => handleDragOverEv(e, filterIndex)}
|
||||
onDrop={(e) => handleDrop(e)}
|
||||
key={`${filter.key}-${filterIndex}`}
|
||||
>
|
||||
{!!props.onFilterMove && eventsNum > 1 ? (
|
||||
<div
|
||||
className={'p-2 cursor-grab'}
|
||||
draggable={!!props.onFilterMove}
|
||||
onDragStart={(e) =>
|
||||
handleDragStart(
|
||||
e,
|
||||
filterIndex,
|
||||
`${filter.key}-${filterIndex}`
|
||||
)
|
||||
}
|
||||
>
|
||||
<GripHorizontal size={16}/>
|
||||
</div>
|
||||
) : null}
|
||||
<FilterItem
|
||||
filterIndex={rowIndex++}
|
||||
filter={filter}
|
||||
onUpdate={(filter) =>
|
||||
props.onUpdateFilter(filterIndex, filter)
|
||||
}
|
||||
onRemoveFilter={() => onRemoveFilter(filterIndex)}
|
||||
saveRequestPayloads={saveRequestPayloads}
|
||||
disableDelete={cannotDeleteFilter}
|
||||
excludeFilterKeys={excludeFilterKeys}
|
||||
readonly={props.readonly}
|
||||
isConditional={isConditional}
|
||||
/>
|
||||
</div>
|
||||
) : null
|
||||
)}
|
||||
</div>
|
||||
<div className="mb-2"/>
|
||||
</>
|
||||
) : null}
|
||||
<FilterItem
|
||||
filterIndex={rowIndex++}
|
||||
filter={filter}
|
||||
onUpdate={(filter) =>
|
||||
props.onUpdateFilter(filterIndex, filter)
|
||||
}
|
||||
onRemoveFilter={() => onRemoveFilter(filterIndex)}
|
||||
saveRequestPayloads={saveRequestPayloads}
|
||||
disableDelete={cannotDeleteFilter}
|
||||
excludeFilterKeys={excludeFilterKeys}
|
||||
readonly={props.readonly}
|
||||
isConditional={isConditional}
|
||||
/>
|
||||
</div>
|
||||
) : null
|
||||
)}
|
||||
</div>
|
||||
<div className="mb-2" />
|
||||
</Card>)}
|
||||
|
||||
{hasFilters && (
|
||||
<>
|
||||
{hasEvents && <div className="border-t -mx-5 mb-4"/>}
|
||||
<div className="mb-2 text-sm color-gray-medium mr-auto">FILTERS</div>
|
||||
{filters.map((filter: any, filterIndex: any) =>
|
||||
!filter.isEvent ? (
|
||||
<div className={'py-2 hover:bg-active-blue px-5'} style={{
|
||||
marginLeft: '-1.25rem',
|
||||
width: 'calc(100% + 2.5rem)',
|
||||
}}>
|
||||
<FilterItem
|
||||
key={filterIndex}
|
||||
readonly={props.readonly}
|
||||
isFilter={true}
|
||||
filterIndex={filterIndex}
|
||||
filter={filter}
|
||||
onUpdate={(filter) => props.onUpdateFilter(filterIndex, filter)}
|
||||
onRemoveFilter={() => onRemoveFilter(filterIndex)}
|
||||
excludeFilterKeys={excludeFilterKeys}
|
||||
isConditional={isConditional}
|
||||
/>
|
||||
</div>
|
||||
) : null
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<Card size={'small'}>
|
||||
<div className={'flex items-center gap-2 mb-2'}>
|
||||
<div className="font-semibold">Filters</div>
|
||||
<FilterSelection filter={undefined} onFilterClick={onAddFilter}>
|
||||
<Button
|
||||
icon={<Icon name={'filter'} />}
|
||||
type="default"
|
||||
size={'small'}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
</FilterSelection>
|
||||
</div>
|
||||
);
|
||||
{filters.map((filter: any, filterIndex: any) =>
|
||||
!filter.isEvent ? (
|
||||
<div
|
||||
className={'py-2 hover:bg-active-blue px-5'}
|
||||
style={{
|
||||
marginLeft: '-1.25rem',
|
||||
width: 'calc(100% + 2.5rem)',
|
||||
}}
|
||||
>
|
||||
<FilterItem
|
||||
key={filterIndex}
|
||||
readonly={props.readonly}
|
||||
isFilter={true}
|
||||
filterIndex={filterIndex}
|
||||
filter={filter}
|
||||
onUpdate={(filter) => props.onUpdateFilter(filterIndex, filter)}
|
||||
onRemoveFilter={() => onRemoveFilter(filterIndex)}
|
||||
excludeFilterKeys={excludeFilterKeys}
|
||||
isConditional={isConditional}
|
||||
/>
|
||||
</div>
|
||||
) : null
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(FilterList);
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ function LiveSessionSearch() {
|
|||
const { projectsStore, searchStoreLive, sessionStore } = useStore();
|
||||
const saveRequestPayloads = projectsStore.active?.saveRequestPayloads;
|
||||
const appliedFilter = searchStoreLive.instance;
|
||||
const hasEvents = appliedFilter.filters.filter(i => i.isEvent).length > 0;
|
||||
const hasFilters = appliedFilter.filters.filter(i => !i.isEvent).length > 0;
|
||||
const hasEvents = appliedFilter.filters.filter((i) => i.isEvent).length > 0;
|
||||
const hasFilters = appliedFilter.filters.filter((i) => !i.isEvent).length > 0;
|
||||
|
||||
useEffect(() => {
|
||||
void searchStoreLive.fetchSessions();
|
||||
|
|
@ -31,7 +31,7 @@ function LiveSessionSearch() {
|
|||
});
|
||||
|
||||
searchStoreLive.edit({
|
||||
filters: newFilters
|
||||
filters: newFilters,
|
||||
});
|
||||
|
||||
void searchStoreLive.fetchSessions();
|
||||
|
|
@ -39,45 +39,23 @@ function LiveSessionSearch() {
|
|||
|
||||
const onChangeEventsOrder = (e: any, { name, value }: any) => {
|
||||
searchStoreLive.edit({
|
||||
eventsOrder: value
|
||||
eventsOrder: value,
|
||||
});
|
||||
|
||||
void searchStoreLive.fetchSessions();
|
||||
};
|
||||
|
||||
return (hasEvents || hasFilters) ? (
|
||||
<div className="border bg-white rounded mt-4">
|
||||
<div className="p-5">
|
||||
<FilterList
|
||||
filter={appliedFilter}
|
||||
onUpdateFilter={onUpdateFilter}
|
||||
onRemoveFilter={onRemoveFilter}
|
||||
onChangeEventsOrder={onChangeEventsOrder}
|
||||
saveRequestPayloads={saveRequestPayloads}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="border-t px-5 py-1 flex items-center -mx-2">
|
||||
<div>
|
||||
<FilterSelection
|
||||
filter={undefined}
|
||||
onFilterClick={onAddFilter}
|
||||
>
|
||||
{/* <IconButton primaryText label="ADD STEP" icon="plus" /> */}
|
||||
<Button
|
||||
variant="text-primary"
|
||||
className="mr-2"
|
||||
// onClick={() => setshowModal(true)}
|
||||
icon="plus">
|
||||
ADD STEP
|
||||
</Button>
|
||||
</FilterSelection>
|
||||
</div>
|
||||
<div className="ml-auto flex items-center">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : <></>;
|
||||
return (
|
||||
<FilterList
|
||||
filter={appliedFilter}
|
||||
onAddFilter={onAddFilter}
|
||||
onUpdateFilter={onUpdateFilter}
|
||||
onRemoveFilter={onRemoveFilter}
|
||||
onChangeEventsOrder={onChangeEventsOrder}
|
||||
saveRequestPayloads={saveRequestPayloads}
|
||||
onlyFilters={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(LiveSessionSearch);
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ interface Props {
|
|||
export default function MetaItem(props: Props) {
|
||||
const { className = '', label, value } = props
|
||||
return (
|
||||
<div className={cn("flex items-center rounded", className)}>
|
||||
<span className="rounded-tl rounded-bl bg-gray-light-shade px-2 color-gray-medium capitalize" style={{ maxWidth: "150px"}}>
|
||||
<div className={cn("flex items-center rounded border border-gray-light-shade", className)}>
|
||||
<span className="rounded-tl rounded-bl bg-gray-light-shade px-2" style={{ maxWidth: "150px"}}>
|
||||
<TextEllipsis text={label} className="p-0" popupProps={{ size: 'small', disabled: true }} />
|
||||
</span>
|
||||
<span className="rounded-tr rounded-br bg-gray-lightest px-2 color-gray-dark" style={{ maxWidth: "150px"}}>
|
||||
<span className="rounded-tr rounded-br bg-white px-2" style={{ maxWidth: "150px"}}>
|
||||
<TextEllipsis text={value} className="p-0" popupProps={{ size: 'small', disabled: true }} />
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,14 +13,7 @@ import {
|
|||
sessions as sessionsRoute,
|
||||
} from 'App/routes';
|
||||
import { capitalize } from 'App/utils';
|
||||
import {
|
||||
Avatar,
|
||||
CountryFlag,
|
||||
Icon,
|
||||
Label,
|
||||
TextEllipsis,
|
||||
Tooltip,
|
||||
} from 'UI';
|
||||
import { Avatar, CountryFlag, Icon, Label, TextEllipsis, Tooltip } from 'UI';
|
||||
|
||||
import Counter from './Counter';
|
||||
import ErrorBars from './ErrorBars';
|
||||
|
|
@ -83,7 +76,7 @@ const PREFETCH_STATE = {
|
|||
none: 0,
|
||||
loading: 1,
|
||||
fetched: 2,
|
||||
}
|
||||
};
|
||||
|
||||
function SessionItem(props: RouteComponentProps & Props) {
|
||||
const { settingsStore, sessionStore } = useStore();
|
||||
|
|
@ -130,32 +123,32 @@ function SessionItem(props: RouteComponentProps & Props) {
|
|||
|
||||
const location = props.location;
|
||||
const queryParams = Object.fromEntries(new URLSearchParams(location.search));
|
||||
const isMobile = platform !== 'web'
|
||||
const isMobile = platform !== 'web';
|
||||
const formattedDuration = durationFormatted(duration);
|
||||
const hasUserId = userId || userAnonymousId;
|
||||
const isSessions = isRoute(SESSIONS_ROUTE, location.pathname);
|
||||
const isAssist =
|
||||
(!ignoreAssist &&
|
||||
(isRoute(ASSIST_ROUTE, location.pathname) ||
|
||||
isRoute(ASSIST_LIVE_SESSION, location.pathname) ||
|
||||
location.pathname.includes('multiview'))) ||
|
||||
(isRoute(ASSIST_ROUTE, location.pathname) ||
|
||||
isRoute(ASSIST_LIVE_SESSION, location.pathname) ||
|
||||
location.pathname.includes('multiview'))) ||
|
||||
props.live;
|
||||
|
||||
const isLastPlayed = lastPlayedSessionId === sessionId;
|
||||
|
||||
const _metaList = Object.keys(metadata)
|
||||
.map((key) => {
|
||||
const value = metadata[key];
|
||||
return { label: key, value };
|
||||
});
|
||||
const _metaList = Object.keys(metadata).map((key) => {
|
||||
const value = metadata[key];
|
||||
return { label: key, value };
|
||||
});
|
||||
|
||||
const handleHover = async () => {
|
||||
if (
|
||||
prefetchState !== PREFETCH_STATE.none
|
||||
|| props.live
|
||||
|| isAssist
|
||||
|| isMobile
|
||||
) return;
|
||||
prefetchState !== PREFETCH_STATE.none ||
|
||||
props.live ||
|
||||
isAssist ||
|
||||
isMobile
|
||||
)
|
||||
return;
|
||||
|
||||
setPrefetched(PREFETCH_STATE.loading);
|
||||
try {
|
||||
|
|
@ -167,10 +160,10 @@ function SessionItem(props: RouteComponentProps & Props) {
|
|||
};
|
||||
const populateData = () => {
|
||||
if (
|
||||
props.live
|
||||
|| isAssist
|
||||
|| prefetchState === PREFETCH_STATE.none
|
||||
|| isMobile
|
||||
props.live ||
|
||||
isAssist ||
|
||||
prefetchState === PREFETCH_STATE.none ||
|
||||
isMobile
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -193,38 +186,46 @@ function SessionItem(props: RouteComponentProps & Props) {
|
|||
<div className={cn('flex items-center w-full')}>
|
||||
{!compact && (
|
||||
<div
|
||||
className="flex items-center pr-2 shrink-0"
|
||||
className={'flex flex-col shrink-0 pr-2 gap-2'}
|
||||
style={{ width: '40%' }}
|
||||
>
|
||||
<div>
|
||||
<Avatar
|
||||
isActive={active}
|
||||
seed={userNumericHash}
|
||||
isAssist={isAssist}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col overflow-hidden color-gray-medium ml-3 justify-between items-center shrink-0">
|
||||
<div
|
||||
className={cn('text-lg', {
|
||||
'color-teal cursor-pointer':
|
||||
!disableUser && hasUserId && !props.isDisabled,
|
||||
[stl.userName]:
|
||||
!disableUser && hasUserId && !props.isDisabled,
|
||||
'color-gray-medium': disableUser || !hasUserId,
|
||||
})}
|
||||
onClick={() =>
|
||||
!disableUser && !hasUserFilter && hasUserId
|
||||
? onUserClick(userId, userAnonymousId)
|
||||
: null
|
||||
}
|
||||
>
|
||||
<TextEllipsis
|
||||
text={userDisplayName}
|
||||
maxWidth="200px"
|
||||
popupProps={{ inverted: true, size: 'tiny' }}
|
||||
<div className="flex items-center pr-2 shrink-0">
|
||||
<div>
|
||||
<Avatar
|
||||
width={'24px'}
|
||||
height={'24px'}
|
||||
iconSize={12}
|
||||
isActive={active}
|
||||
seed={userNumericHash}
|
||||
isAssist={isAssist}
|
||||
/>
|
||||
</div>
|
||||
<div className="overflow-hidden color-gray-medium ml-3 justify-between items-center shrink-0">
|
||||
<div
|
||||
className={cn('text-lg', {
|
||||
'color-teal cursor-pointer':
|
||||
!disableUser && hasUserId && !props.isDisabled,
|
||||
[stl.userName]:
|
||||
!disableUser && hasUserId && !props.isDisabled,
|
||||
'color-gray-medium': disableUser || !hasUserId,
|
||||
})}
|
||||
onClick={() =>
|
||||
!disableUser && !hasUserFilter && hasUserId
|
||||
? onUserClick(userId, userAnonymousId)
|
||||
: null
|
||||
}
|
||||
>
|
||||
<TextEllipsis
|
||||
text={userDisplayName}
|
||||
maxWidth="200px"
|
||||
popupProps={{ inverted: true, size: 'tiny' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{_metaList.length > 0 && (
|
||||
<SessionMetaList metaList={_metaList} />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
|
|
@ -264,11 +265,11 @@ function SessionItem(props: RouteComponentProps & Props) {
|
|||
text={formatTimeOrDate(
|
||||
startedAt,
|
||||
shownTimezone === 'user' && userTimezone
|
||||
? {
|
||||
label: userTimezone.split('+').join(' +'),
|
||||
value: userTimezone.split(':')[0],
|
||||
}
|
||||
: timezone
|
||||
? {
|
||||
label: userTimezone.split('+').join(' +'),
|
||||
value: userTimezone.split(':')[0],
|
||||
}
|
||||
: timezone
|
||||
)}
|
||||
popupProps={{ inverted: true, size: 'tiny' }}
|
||||
/>
|
||||
|
|
@ -281,8 +282,8 @@ function SessionItem(props: RouteComponentProps & Props) {
|
|||
<span className="mr-1">{eventsCount}</span>
|
||||
<span>
|
||||
{eventsCount === 0 || eventsCount > 1
|
||||
? 'Events'
|
||||
: 'Event'}
|
||||
? 'Events'
|
||||
: 'Event'}
|
||||
</span>
|
||||
</div>
|
||||
<Icon name="circle-fill" size={3} className="mx-4" />
|
||||
|
|
@ -292,8 +293,8 @@ function SessionItem(props: RouteComponentProps & Props) {
|
|||
{live || props.live ? (
|
||||
<Counter startTime={startedAt} />
|
||||
) : (
|
||||
formattedDuration
|
||||
)}
|
||||
formattedDuration
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -394,22 +395,19 @@ function SessionItem(props: RouteComponentProps & Props) {
|
|||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<PlayLink
|
||||
isAssist={isAssist}
|
||||
sessionId={sessionId}
|
||||
viewed={viewed}
|
||||
onClick={onClick}
|
||||
queryParams={queryParams}
|
||||
query={query}
|
||||
beforeOpen={props.live || isAssist ? undefined : populateData}
|
||||
/>
|
||||
)}
|
||||
<PlayLink
|
||||
isAssist={isAssist}
|
||||
sessionId={sessionId}
|
||||
viewed={viewed}
|
||||
onClick={onClick}
|
||||
queryParams={queryParams}
|
||||
query={query}
|
||||
beforeOpen={props.live || isAssist ? undefined : populateData}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{_metaList.length > 0 && (
|
||||
<SessionMetaList className="mt-4" metaList={_metaList} />
|
||||
)}
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue