fix ui bugs in session tab
This commit is contained in:
parent
923fce97fb
commit
7005c046b8
7 changed files with 148 additions and 19 deletions
|
|
@ -0,0 +1,42 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
import {
|
||||
Link,
|
||||
Icon,
|
||||
} from 'UI';
|
||||
import { session as sessionRoute, liveSession as liveSessionRoute } from 'App/routes';
|
||||
|
||||
const PLAY_ICON_NAMES = {
|
||||
notPlayed: 'play-fill',
|
||||
played: 'play-circle-light',
|
||||
hovered: 'play-hover'
|
||||
}
|
||||
|
||||
const getDefaultIconName = (isViewed) => !isViewed ? PLAY_ICON_NAMES.notPlayed : PLAY_ICON_NAMES.played
|
||||
|
||||
interface Props {
|
||||
isAssist: boolean;
|
||||
viewed: boolean;
|
||||
sessionId: string;
|
||||
}
|
||||
export default function PlayLink(props: Props) {
|
||||
const { isAssist, viewed, sessionId } = props
|
||||
const defaultIconName = getDefaultIconName(viewed)
|
||||
|
||||
const [isHovered, toggleHover] = useState(false)
|
||||
const [iconName, setIconName] = useState(defaultIconName)
|
||||
|
||||
useEffect(() => {
|
||||
if (isHovered) setIconName(PLAY_ICON_NAMES.hovered)
|
||||
else setIconName(getDefaultIconName(viewed))
|
||||
}, [isHovered, viewed])
|
||||
|
||||
return (
|
||||
<Link
|
||||
to={ isAssist ? liveSessionRoute(sessionId) : sessionRoute(sessionId) }
|
||||
onMouseEnter={() => toggleHover(true)}
|
||||
onMouseLeave={() => toggleHover(false)}
|
||||
>
|
||||
<Icon name={iconName} size="42" color={isAssist ? "tealx" : "teal"} />
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { default } from './PlayLink'
|
||||
|
|
@ -15,6 +15,7 @@ import stl from './sessionItem.css';
|
|||
import Counter from './Counter'
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import SessionMetaList from './SessionMetaList';
|
||||
import PlayLink from './PlayLink';
|
||||
import ErrorBars from './ErrorBars';
|
||||
import { assist as assistRoute, liveSession, sessions as sessionsRoute, isRoute } from "App/routes";
|
||||
import { capitalize } from 'App/utils';
|
||||
|
|
@ -76,7 +77,7 @@ export default class SessionItem extends React.PureComponent {
|
|||
});
|
||||
|
||||
return (
|
||||
<div className={ cn(stl.sessionItem, "flex flex-col bg-white p-3 mb-3") } id="session-item" >
|
||||
<div className={ cn(stl.sessionItem, "flex flex-col p-3 mb-3") } id="session-item" >
|
||||
<div className="flex items-start">
|
||||
<div className={ cn('flex items-center w-full')}>
|
||||
<div className="flex items-center pr-2" style={{ width: "30%"}}>
|
||||
|
|
@ -144,9 +145,11 @@ export default class SessionItem extends React.PureComponent {
|
|||
)}
|
||||
</div>
|
||||
)}
|
||||
<Link to={ isAssist ? liveSessionRoute(sessionId) : sessionRoute(sessionId) }>
|
||||
<Icon name={ !viewed && !isAssist ? 'play-fill' : 'play-circle-light' } size="42" color={isAssist ? "tealx" : "teal"} />
|
||||
</Link>
|
||||
<PlayLink
|
||||
isAssist={isAssist}
|
||||
sessionId={sessionId}
|
||||
viewed={viewed}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
@import 'mixins.css';
|
||||
|
||||
.sessionItem {
|
||||
background-color: #fff;
|
||||
@mixin defaultHover;
|
||||
user-select: none;
|
||||
border-radius: 3px;
|
||||
border: solid thin #EEEEEE;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,42 @@
|
|||
import { useState, useRef, useEffect, forwardRef } from 'react';
|
||||
import cn from 'classnames';
|
||||
import { Popup } from 'UI';
|
||||
import styles from './textEllipsis.css';
|
||||
|
||||
/** calculates text width in pixels
|
||||
+ * by creating a hidden element with t
|
||||
+ * ext and counting its width
|
||||
+ * @param text String - text string
|
||||
+ * @param fontProp String - font properties
|
||||
+ * @returns width number
|
||||
+ */
|
||||
function findTextWidth(text, fontProp) {
|
||||
const tag = document.createElement('div')
|
||||
|
||||
tag.style.position = 'absolute'
|
||||
tag.style.left = '-99in'
|
||||
tag.style.whiteSpace = 'nowrap'
|
||||
tag.style.font = fontProp
|
||||
tag.innerHTML = text
|
||||
|
||||
document.body.appendChild(tag)
|
||||
const result = tag.clientWidth
|
||||
document.body.removeChild(tag)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const Trigger = forwardRef(({ textOrChildren, maxWidth, style, className, ...rest }, ref) => (
|
||||
<div
|
||||
className={ cn(styles.textEllipsis, className) }
|
||||
style={{ maxWidth, ...style }}
|
||||
ref={ref}
|
||||
{ ...rest }
|
||||
>
|
||||
{ textOrChildren }
|
||||
</div>
|
||||
))
|
||||
|
||||
const TextEllipsis = ({
|
||||
text,
|
||||
hintText = text,
|
||||
|
|
@ -14,23 +49,51 @@ const TextEllipsis = ({
|
|||
hintProps={},
|
||||
...props
|
||||
}) => {
|
||||
const [showPopup, setShowPopup] = useState(false)
|
||||
const textRef = useRef(null);
|
||||
|
||||
const textOrChildren = text || children;
|
||||
const trigger = (
|
||||
<div
|
||||
className={ cn(styles.textEllipsis, className) }
|
||||
style={{ maxWidth, ...style }}
|
||||
{ ...props }
|
||||
>
|
||||
{ textOrChildren }
|
||||
</div>
|
||||
);
|
||||
if (noHint) return trigger;
|
||||
|
||||
const popupId = (Math.random() + 1).toString(36).substring(7);
|
||||
|
||||
useEffect(() => {
|
||||
const element = textRef.current;
|
||||
|
||||
const fontSize = window.getComputedStyle(element, null).getPropertyValue('font-size');
|
||||
|
||||
const textWidth = findTextWidth(element.innerText, fontSize)
|
||||
console.log(textWidth, element.clientWidth)
|
||||
if (textWidth > element.clientWidth) setShowPopup(true)
|
||||
else setShowPopup(false)
|
||||
}, [textRef.current])
|
||||
|
||||
if (noHint || !showPopup) return (
|
||||
<Trigger
|
||||
className={className}
|
||||
maxWidth={maxWidth}
|
||||
style={style}
|
||||
textOrChildren={textOrChildren}
|
||||
ref={textRef}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
|
||||
return (
|
||||
<Popup
|
||||
trigger={ trigger }
|
||||
content={ <div className="customPopupText" { ...hintProps } >{ hintText || textOrChildren }</div> }
|
||||
{ ...popupProps }
|
||||
/>
|
||||
trigger={
|
||||
<Trigger
|
||||
className={className}
|
||||
maxWidth={maxWidth}
|
||||
style={style}
|
||||
textOrChildren={textOrChildren}
|
||||
id={popupId}
|
||||
ref={textRef}
|
||||
{...props}
|
||||
/>
|
||||
}
|
||||
content={ <div className="customPopupText" { ...hintProps } >{ hintText || textOrChildren }</div> }
|
||||
{ ...popupProps }
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,13 @@ import stl from './timezoneDropdown.css';
|
|||
import { connect } from 'react-redux';
|
||||
import { setTimezone } from 'Duck/sessions';
|
||||
|
||||
const localMachineFormat = new Date().toString().match(/([A-Z]+[\+-][0-9]+)/)[1]
|
||||
const middlePoint = localMachineFormat.length - 2
|
||||
const readableLocalTimezone =
|
||||
`${localMachineFormat.substring(0, 3)} ${localMachineFormat.substring(3, middlePoint)}:${localMachineFormat.substring(middlePoint)}`
|
||||
|
||||
const timezoneOptions = {
|
||||
'local': new Date().toString().match(/([A-Z]+[\+-][0-9]+)/)[1],
|
||||
'local': readableLocalTimezone,
|
||||
'UTC': 'UTC'
|
||||
};
|
||||
|
||||
|
|
|
|||
12
frontend/app/svg/icons/play-hover.svg
Normal file
12
frontend/app/svg/icons/play-hover.svg
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<svg width="42" height="42" viewBox="0 0 42 42" fill="inherit" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1_47)">
|
||||
<path d="M21 0C25.1534 0 29.2135 1.23163 32.667 3.53914C36.1204 5.84665 38.812 9.1264 40.4015 12.9636C41.9909 16.8009 42.4068 21.0233 41.5965 25.0969C40.7862 29.1705 38.7861 32.9123 35.8492 35.8492C32.9123 38.7861 29.1705 40.7862 25.0969 41.5965C21.0233 42.4068 16.8009 41.9909 12.9636 40.4015C9.1264 38.812 5.84665 36.1204 3.53914 32.667C1.23163 29.2135 0 25.1534 0 21C0 15.4305 2.21249 10.089 6.15076 6.15076C10.089 2.21249 15.4305 0 21 0ZM21 1.27615C17.099 1.27615 13.2856 2.43294 10.042 4.60022C6.79845 6.76751 4.27039 9.84795 2.77754 13.452C1.28469 17.0561 0.894093 21.0219 1.65514 24.8479C2.41619 28.674 4.29471 32.1884 7.05313 34.9469C9.81156 37.7053 13.326 39.5838 17.1521 40.3449C20.9781 41.1059 24.9439 40.7153 28.548 39.2225C32.1521 37.7296 35.2325 35.2015 37.3998 31.958C39.5671 28.7144 40.7238 24.901 40.7238 21C40.7238 18.4098 40.2137 15.845 39.2225 13.452C38.2312 11.059 36.7784 8.88466 34.9469 7.05313C33.1153 5.22161 30.941 3.76876 28.548 2.77754C26.155 1.78633 23.5902 1.27615 21 1.27615Z" />
|
||||
<circle cx="21" cy="21" r="20" fill="inherit" />
|
||||
<path d="M29.3192 23.0838C31.1527 21.9531 31.1527 20.1438 29.3192 19.0454L18.6819 12.6565C16.8485 11.5258 15.3462 12.2608 15.3462 14.2719V27.7604C15.3462 29.7312 16.8485 30.4742 18.69 29.3758L29.3192 23.0838Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1_47">
|
||||
<rect width="42" height="42" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
Loading…
Add table
Reference in a new issue