change(ui): add state handlers
This commit is contained in:
parent
3d760b4ed0
commit
92a897b9c0
7 changed files with 294 additions and 229 deletions
|
|
@ -7,7 +7,6 @@ import withPermissions from 'HOCs/withPermissions';
|
|||
import { PlayerContext, defaultContextValue } from './playerContext';
|
||||
import { makeAutoObservable } from 'mobx';
|
||||
import { createLiveWebPlayer } from 'Player'
|
||||
|
||||
import PlayerBlockHeader from '../Session_/PlayerBlockHeader';
|
||||
import PlayerBlock from '../Session_/PlayerBlock';
|
||||
import styles from '../Session_/session.module.css';
|
||||
|
|
@ -42,7 +41,7 @@ function LivePlayer({
|
|||
const [fullView, setFullView] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (loadingCredentials || !session.sessionId) { return }
|
||||
if (loadingCredentials || !session.sessionId) return;
|
||||
const sessionWithAgentData = {
|
||||
// @ts-ignore burn immutable
|
||||
...session.toJS(),
|
||||
|
|
@ -89,6 +88,7 @@ function LivePlayer({
|
|||
<PlayerContext.Provider value={contextValue}>
|
||||
{!fullView && (
|
||||
<PlayerBlockHeader
|
||||
// @ts-ignore
|
||||
activeTab={activeTab}
|
||||
setActiveTab={setActiveTab}
|
||||
tabs={TABS}
|
||||
|
|
|
|||
|
|
@ -5,57 +5,67 @@ import usePageTitle from 'App/hooks/usePageTitle';
|
|||
import { fetch as fetchSession } from 'Duck/sessions';
|
||||
import { fetchList as fetchSlackList } from 'Duck/integrations/slack';
|
||||
import { Loader } from 'UI';
|
||||
// import { sessions as sessionsRoute } from 'App/routes';
|
||||
import withPermissions from 'HOCs/withPermissions'
|
||||
import withPermissions from 'HOCs/withPermissions';
|
||||
import LivePlayer from './LivePlayer';
|
||||
|
||||
// const SESSIONS_ROUTE = sessionsRoute();
|
||||
function LiveSession({
|
||||
sessionId,
|
||||
loading,
|
||||
session,
|
||||
fetchSession,
|
||||
fetchSlackList,
|
||||
hasSessionsPath,
|
||||
}) {
|
||||
usePageTitle('OpenReplay Assist');
|
||||
|
||||
function LiveSession({
|
||||
sessionId,
|
||||
loading,
|
||||
// hasErrors,
|
||||
session,
|
||||
fetchSession,
|
||||
fetchSlackList,
|
||||
hasSessionsPath
|
||||
}) {
|
||||
usePageTitle("OpenReplay Assist");
|
||||
useEffect(() => {
|
||||
fetchSlackList();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
fetchSlackList()
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (sessionId != null) {
|
||||
fetchSession(sessionId, true);
|
||||
} else {
|
||||
console.error('No sessionID in route.');
|
||||
}
|
||||
return () => {
|
||||
if (!session.exists()) return;
|
||||
};
|
||||
}, [sessionId, hasSessionsPath]);
|
||||
|
||||
useEffect(() => {
|
||||
if (sessionId != null) {
|
||||
fetchSession(sessionId, true)
|
||||
} else {
|
||||
console.error("No sessionID in route.")
|
||||
}
|
||||
return () => {
|
||||
if (!session.exists()) return;
|
||||
}
|
||||
},[ sessionId, hasSessionsPath ]);
|
||||
|
||||
return (
|
||||
<Loader className="flex-1" loading={ loading }>
|
||||
<LivePlayer />
|
||||
</Loader>
|
||||
);
|
||||
return (
|
||||
<Loader className="flex-1" loading={loading}>
|
||||
<LivePlayer />
|
||||
</Loader>
|
||||
);
|
||||
}
|
||||
|
||||
export default withPermissions(['ASSIST_LIVE'], '', true)(connect((state, props) => {
|
||||
const { match: { params: { sessionId } } } = props;
|
||||
const isAssist = state.getIn(['sessions', 'activeTab']).type === 'live';
|
||||
const hasSessiosPath = state.getIn([ 'sessions', 'sessionPath' ]).pathname.includes('/sessions');
|
||||
return {
|
||||
sessionId,
|
||||
loading: state.getIn([ 'sessions', 'loading' ]),
|
||||
// hasErrors: !!state.getIn([ 'sessions', 'errors' ]),
|
||||
session: state.getIn([ 'sessions', 'current' ]),
|
||||
hasSessionsPath: hasSessiosPath && !isAssist,
|
||||
};
|
||||
}, {
|
||||
fetchSession,
|
||||
fetchSlackList,
|
||||
})(LiveSession));
|
||||
export default withPermissions(
|
||||
['ASSIST_LIVE'],
|
||||
'',
|
||||
true
|
||||
)(
|
||||
connect(
|
||||
(state, props) => {
|
||||
const {
|
||||
match: {
|
||||
params: { sessionId },
|
||||
},
|
||||
} = props;
|
||||
const isAssist = state.getIn(['sessions', 'activeTab']).type === 'live';
|
||||
const hasSessiosPath = state
|
||||
.getIn(['sessions', 'sessionPath'])
|
||||
.pathname.includes('/sessions');
|
||||
return {
|
||||
sessionId,
|
||||
loading: state.getIn(['sessions', 'loading']),
|
||||
session: state.getIn(['sessions', 'current']),
|
||||
hasSessionsPath: hasSessiosPath && !isAssist,
|
||||
};
|
||||
},
|
||||
{
|
||||
fetchSession,
|
||||
fetchSlackList,
|
||||
}
|
||||
)(LiveSession)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ function AssistSessionsModal(props: Props) {
|
|||
<>
|
||||
{list.map((session) => (
|
||||
<React.Fragment key={session.sessionID}>
|
||||
<div className="rounded bg-white mb-2 overflow-hidden border">
|
||||
<div className={cn("rounded bg-white mb-2 overflow-hidden border", session.sessionId === assistTabStore.activeSession.sessionId ? 'cursor-not-allowed' : '')}>
|
||||
<SessionItem
|
||||
key={session.sessionId}
|
||||
session={session}
|
||||
|
|
@ -95,6 +95,8 @@ function AssistSessionsModal(props: Props) {
|
|||
hasUserFilter={hasUserFilter}
|
||||
onUserClick={onUserClick}
|
||||
metaList={metaList}
|
||||
isDisabled={session.sessionId === assistTabStore.activeSession.sessionId}
|
||||
isAdd
|
||||
onClick={() => onSessionAdd(session)}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -134,4 +136,4 @@ export default connect(
|
|||
addFilterByKeyAndValue,
|
||||
updateCurrentPage,
|
||||
}
|
||||
)(AssistSessionsModal);
|
||||
)(observer(AssistSessionsModal));
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ function AssistTabs({ session }: { session: Session }) {
|
|||
if (assistTabStore.sessions.length === 0) {
|
||||
assistTabStore.addSession(session)
|
||||
assistTabStore.setActiveSession(session.sessionId)
|
||||
console.log(assistTabStore.sessions, assistTabStore.activeSession, session.sessionId)
|
||||
}
|
||||
}, [])
|
||||
|
||||
|
|
@ -59,7 +60,7 @@ function AssistTabs({ session }: { session: Session }) {
|
|||
{assistTabStore.sessions.map(session => (
|
||||
<React.Fragment key={session.sessionId}>
|
||||
{assistTabStore.isActive(session.sessionId)
|
||||
? <CurrentTab /> : <ActiveTab />}
|
||||
? <CurrentTab /> : <ActiveTab onClick={() => assistTabStore.setActiveSession(session.sessionId)} />}
|
||||
</React.Fragment>
|
||||
)
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -18,194 +18,243 @@ const ASSIST_LIVE_SESSION = liveSession();
|
|||
const SESSIONS_ROUTE = sessionsRoute();
|
||||
|
||||
interface Props {
|
||||
session: {
|
||||
sessionId: string;
|
||||
userBrowser: string;
|
||||
userOs: string;
|
||||
userId: string;
|
||||
userAnonymousId: string;
|
||||
userDisplayName: string;
|
||||
userCountry: string;
|
||||
startedAt: number;
|
||||
duration: string;
|
||||
eventsCount: number;
|
||||
errorsCount: number;
|
||||
pagesCount: number;
|
||||
viewed: boolean;
|
||||
favorite: boolean;
|
||||
userDeviceType: string;
|
||||
userUuid: string;
|
||||
userNumericHash: number;
|
||||
live: boolean;
|
||||
metadata: Record<string, any>;
|
||||
userSessionsCount: number;
|
||||
issueTypes: [];
|
||||
active: boolean;
|
||||
isCallActive?: boolean;
|
||||
agentIds?: string[];
|
||||
};
|
||||
onUserClick?: (userId: string, userAnonymousId: string) => void;
|
||||
hasUserFilter?: boolean;
|
||||
disableUser?: boolean;
|
||||
metaList?: Array<any>;
|
||||
// showActive?: boolean;
|
||||
lastPlayedSessionId?: string;
|
||||
live?: boolean;
|
||||
onClick?: any;
|
||||
compact?: boolean;
|
||||
session: {
|
||||
sessionId: string;
|
||||
userBrowser: string;
|
||||
userOs: string;
|
||||
userId: string;
|
||||
userAnonymousId: string;
|
||||
userDisplayName: string;
|
||||
userCountry: string;
|
||||
startedAt: number;
|
||||
duration: string;
|
||||
eventsCount: number;
|
||||
errorsCount: number;
|
||||
pagesCount: number;
|
||||
viewed: boolean;
|
||||
favorite: boolean;
|
||||
userDeviceType: string;
|
||||
userUuid: string;
|
||||
userNumericHash: number;
|
||||
live: boolean;
|
||||
metadata: Record<string, any>;
|
||||
userSessionsCount: number;
|
||||
issueTypes: [];
|
||||
active: boolean;
|
||||
isCallActive?: boolean;
|
||||
agentIds?: string[];
|
||||
};
|
||||
onUserClick?: (userId: string, userAnonymousId: string) => void;
|
||||
hasUserFilter?: boolean;
|
||||
disableUser?: boolean;
|
||||
metaList?: Array<any>;
|
||||
// showActive?: boolean;
|
||||
lastPlayedSessionId?: string;
|
||||
live?: boolean;
|
||||
onClick?: any;
|
||||
compact?: boolean;
|
||||
isDisabled?: boolean;
|
||||
isAdd?: boolean;
|
||||
}
|
||||
|
||||
function SessionItem(props: RouteComponentProps & Props) {
|
||||
const { settingsStore } = useStore();
|
||||
const { timezone } = settingsStore.sessionSettings;
|
||||
const { settingsStore } = useStore();
|
||||
const { timezone } = settingsStore.sessionSettings;
|
||||
|
||||
const {
|
||||
session,
|
||||
onUserClick = () => null,
|
||||
hasUserFilter = false,
|
||||
disableUser = false,
|
||||
metaList = [],
|
||||
lastPlayedSessionId,
|
||||
onClick = null,
|
||||
compact = false,
|
||||
} = props;
|
||||
const {
|
||||
session,
|
||||
onUserClick = () => null,
|
||||
hasUserFilter = false,
|
||||
disableUser = false,
|
||||
metaList = [],
|
||||
lastPlayedSessionId,
|
||||
onClick = null,
|
||||
compact = false,
|
||||
} = props;
|
||||
|
||||
const {
|
||||
sessionId,
|
||||
userBrowser,
|
||||
userOs,
|
||||
userId,
|
||||
userAnonymousId,
|
||||
userDisplayName,
|
||||
userCountry,
|
||||
startedAt,
|
||||
duration,
|
||||
eventsCount,
|
||||
viewed,
|
||||
userDeviceType,
|
||||
userNumericHash,
|
||||
live,
|
||||
metadata,
|
||||
issueTypes,
|
||||
active,
|
||||
} = session;
|
||||
const {
|
||||
sessionId,
|
||||
userBrowser,
|
||||
userOs,
|
||||
userId,
|
||||
userAnonymousId,
|
||||
userDisplayName,
|
||||
userCountry,
|
||||
startedAt,
|
||||
duration,
|
||||
eventsCount,
|
||||
viewed,
|
||||
userDeviceType,
|
||||
userNumericHash,
|
||||
live,
|
||||
metadata,
|
||||
issueTypes,
|
||||
active,
|
||||
} = session;
|
||||
|
||||
const location = props.location;
|
||||
const queryParams = Object.fromEntries(new URLSearchParams(location.search));
|
||||
const location = props.location;
|
||||
const queryParams = Object.fromEntries(new URLSearchParams(location.search));
|
||||
|
||||
const formattedDuration = durationFormatted(duration);
|
||||
const hasUserId = userId || userAnonymousId;
|
||||
const isSessions = isRoute(SESSIONS_ROUTE, location.pathname);
|
||||
const isAssist = isRoute(ASSIST_ROUTE, location.pathname) || isRoute(ASSIST_LIVE_SESSION, location.pathname);
|
||||
const isLastPlayed = lastPlayedSessionId === sessionId;
|
||||
const formattedDuration = durationFormatted(duration);
|
||||
const hasUserId = userId || userAnonymousId;
|
||||
const isSessions = isRoute(SESSIONS_ROUTE, location.pathname);
|
||||
const isAssist =
|
||||
isRoute(ASSIST_ROUTE, location.pathname) || isRoute(ASSIST_LIVE_SESSION, location.pathname);
|
||||
const isLastPlayed = lastPlayedSessionId === sessionId;
|
||||
|
||||
const _metaList = Object.keys(metadata)
|
||||
.filter((i) => metaList.includes(i))
|
||||
.map((key) => {
|
||||
const value = metadata[key];
|
||||
return { label: key, value };
|
||||
});
|
||||
const _metaList = Object.keys(metadata)
|
||||
.filter((i) => metaList.includes(i))
|
||||
.map((key) => {
|
||||
const value = metadata[key];
|
||||
return { label: key, value };
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={cn(stl.sessionItem, 'flex flex-col py-2 px-4')} id="session-item" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="flex items-start">
|
||||
<div className={cn('flex items-center w-full')}>
|
||||
{!compact && (
|
||||
<div className="flex items-center pr-2 shrink-0" 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,
|
||||
[stl.userName]: !disableUser && hasUserId,
|
||||
'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>
|
||||
)}
|
||||
<div style={{ width: compact ? '40%' : '20%' }} className="px-2 flex flex-col justify-between">
|
||||
<div>
|
||||
<Tooltip
|
||||
delay={0}
|
||||
title={`${formatTimeOrDate(startedAt, timezone, true)} ${timezone.label}`}
|
||||
className="w-fit !block"
|
||||
>
|
||||
<TextEllipsis text={formatTimeOrDate(startedAt, timezone)} popupProps={{ inverted: true, size: 'tiny' }} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="flex items-center color-gray-medium py-1">
|
||||
{!isAssist && (
|
||||
<>
|
||||
<div className="color-gray-medium">
|
||||
<span className="mr-1">{eventsCount}</span>
|
||||
<span>{eventsCount === 0 || eventsCount > 1 ? 'Events' : 'Event'}</span>
|
||||
</div>
|
||||
<Icon name="circle-fill" size={3} className="mx-4" />
|
||||
</>
|
||||
)}
|
||||
<div>{live ? <Counter startTime={startedAt} /> : formattedDuration}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ width: '30%' }} className="px-2 flex flex-col justify-between">
|
||||
<div style={{ height: '21px' }}>
|
||||
<CountryFlag country={userCountry} style={{ paddingTop: '4px' }} label />
|
||||
</div>
|
||||
<div className="color-gray-medium flex items-center py-1">
|
||||
<span className="capitalize" style={{ maxWidth: '70px' }}>
|
||||
<TextEllipsis text={capitalize(userBrowser)} popupProps={{ inverted: true, size: 'tiny' }} />
|
||||
</span>
|
||||
<Icon name="circle-fill" size={3} className="mx-4" />
|
||||
<span className="capitalize" style={{ maxWidth: '70px' }}>
|
||||
<TextEllipsis text={capitalize(userOs)} popupProps={{ inverted: true, size: 'tiny' }} />
|
||||
</span>
|
||||
<Icon name="circle-fill" size={3} className="mx-4" />
|
||||
<span className="capitalize" style={{ maxWidth: '70px' }}>
|
||||
<TextEllipsis text={capitalize(userDeviceType)} popupProps={{ inverted: true, size: 'tiny' }} />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{isSessions && (
|
||||
<div style={{ width: '10%' }} className="self-center px-2 flex items-center">
|
||||
<ErrorBars count={issueTypes.length} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center">
|
||||
<div className={stl.playLink} id="play-button" data-viewed={viewed}>
|
||||
{live && session.isCallActive && session.agentIds.length > 0 ? (
|
||||
<div className="mr-4">
|
||||
<Label className="bg-gray-lightest p-1 px-2 rounded-lg">
|
||||
<span className="color-gray-medium text-xs" style={{ whiteSpace: 'nowrap' }}>
|
||||
CALL IN PROGRESS
|
||||
</span>
|
||||
</Label>
|
||||
</div>
|
||||
) : null}
|
||||
{isSessions && (
|
||||
<div className="mr-4 flex-shrink-0 w-24">
|
||||
{isLastPlayed && (
|
||||
<Label className="bg-gray-lightest p-1 px-2 rounded-lg">
|
||||
<span className="color-gray-medium text-xs" style={{ whiteSpace: 'nowrap' }}>
|
||||
LAST PLAYED
|
||||
</span>
|
||||
</Label>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<PlayLink isAssist={isAssist} sessionId={sessionId} viewed={viewed} onClick={onClick} queryParams={queryParams} />
|
||||
</div>
|
||||
return (
|
||||
<div
|
||||
className={cn(stl.sessionItem, 'flex flex-col py-2 px-4')}
|
||||
id="session-item"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="flex items-start">
|
||||
<div className={cn('flex items-center w-full')}>
|
||||
{!compact && (
|
||||
<div className="flex items-center pr-2 shrink-0" 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,
|
||||
[stl.userName]: !disableUser && hasUserId,
|
||||
'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 className="mt-4" metaList={_metaList} />}
|
||||
)}
|
||||
<div
|
||||
style={{ width: compact ? '40%' : '20%' }}
|
||||
className="px-2 flex flex-col justify-between"
|
||||
>
|
||||
<div>
|
||||
<Tooltip
|
||||
delay={0}
|
||||
title={`${formatTimeOrDate(startedAt, timezone, true)} ${timezone.label}`}
|
||||
className="w-fit !block"
|
||||
>
|
||||
<TextEllipsis
|
||||
text={formatTimeOrDate(startedAt, timezone)}
|
||||
popupProps={{ inverted: true, size: 'tiny' }}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="flex items-center color-gray-medium py-1">
|
||||
{!isAssist && (
|
||||
<>
|
||||
<div className="color-gray-medium">
|
||||
<span className="mr-1">{eventsCount}</span>
|
||||
<span>{eventsCount === 0 || eventsCount > 1 ? 'Events' : 'Event'}</span>
|
||||
</div>
|
||||
<Icon name="circle-fill" size={3} className="mx-4" />
|
||||
</>
|
||||
)}
|
||||
<div>{live ? <Counter startTime={startedAt} /> : formattedDuration}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ width: '30%' }} className="px-2 flex flex-col justify-between">
|
||||
<div style={{ height: '21px' }}>
|
||||
<CountryFlag country={userCountry} style={{ paddingTop: '4px' }} label />
|
||||
</div>
|
||||
<div className="color-gray-medium flex items-center py-1">
|
||||
<span className="capitalize" style={{ maxWidth: '70px' }}>
|
||||
<TextEllipsis
|
||||
text={capitalize(userBrowser)}
|
||||
popupProps={{ inverted: true, size: 'tiny' }}
|
||||
/>
|
||||
</span>
|
||||
<Icon name="circle-fill" size={3} className="mx-4" />
|
||||
<span className="capitalize" style={{ maxWidth: '70px' }}>
|
||||
<TextEllipsis
|
||||
text={capitalize(userOs)}
|
||||
popupProps={{ inverted: true, size: 'tiny' }}
|
||||
/>
|
||||
</span>
|
||||
<Icon name="circle-fill" size={3} className="mx-4" />
|
||||
<span className="capitalize" style={{ maxWidth: '70px' }}>
|
||||
<TextEllipsis
|
||||
text={capitalize(userDeviceType)}
|
||||
popupProps={{ inverted: true, size: 'tiny' }}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{isSessions && (
|
||||
<div style={{ width: '10%' }} className="self-center px-2 flex items-center">
|
||||
<ErrorBars count={issueTypes.length} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
<div className="flex items-center">
|
||||
<div
|
||||
className={cn(stl.playLink, props.isDisabled ? 'cursor-not-allowed' : 'cursor-pointer')}
|
||||
id="play-button"
|
||||
data-viewed={viewed}
|
||||
>
|
||||
{live && session.isCallActive && session.agentIds.length > 0 ? (
|
||||
<div className="mr-4">
|
||||
<Label className="bg-gray-lightest p-1 px-2 rounded-lg">
|
||||
<span className="color-gray-medium text-xs" style={{ whiteSpace: 'nowrap' }}>
|
||||
CALL IN PROGRESS
|
||||
</span>
|
||||
</Label>
|
||||
</div>
|
||||
) : null}
|
||||
{isSessions && (
|
||||
<div className="mr-4 flex-shrink-0 w-24">
|
||||
{isLastPlayed && (
|
||||
<Label className="bg-gray-lightest p-1 px-2 rounded-lg">
|
||||
<span className="color-gray-medium text-xs" style={{ whiteSpace: 'nowrap' }}>
|
||||
LAST PLAYED
|
||||
</span>
|
||||
</Label>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{props.isAdd ? (
|
||||
<Icon
|
||||
name="plus-circle"
|
||||
size={36}
|
||||
color="teal"
|
||||
onClick={() => (props.isDisabled ? null : props.onClick())}
|
||||
/>
|
||||
) : (
|
||||
<PlayLink
|
||||
isAssist={isAssist}
|
||||
sessionId={sessionId}
|
||||
viewed={viewed}
|
||||
onClick={onClick}
|
||||
queryParams={queryParams}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{_metaList.length > 0 && <SessionMetaList className="mt-4" metaList={_metaList} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withRouter(observer(SessionItem));
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
transition: all 0.2s;
|
||||
cursor: pointer;
|
||||
&[data-viewed=true] {
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ export default class AssistTabStore {
|
|||
return this.activeSession.sessionId === sessionId
|
||||
}
|
||||
|
||||
get activeSessionId() {
|
||||
return this.activeSession?.sessionId || ''
|
||||
}
|
||||
|
||||
setSessions(sessions: TabSessions) {
|
||||
this.sessions = sessions
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue