import React from 'react'; import { connect } from 'react-redux'; import cn from 'classnames'; import { Icon } from 'UI'; import { List, AutoSizer, CellMeasurer, CellMeasurerCache } from "react-virtualized"; import { TYPES } from 'Types/session/event'; import { setSelected } from 'Duck/events'; import { setEventFilter } from 'Duck/sessions'; import { show as showTargetDefiner } from 'Duck/components/targetDefiner'; import EventGroupWrapper from './EventGroupWrapper'; import styles from './eventsBlock.module.css'; import EventSearch from './EventSearch/EventSearch'; @connect(state => ({ session: state.getIn([ 'sessions', 'current' ]), filteredEvents: state.getIn([ 'sessions', 'filteredEvents' ]), eventsIndex: state.getIn([ 'sessions', 'eventsIndex' ]), selectedEvents: state.getIn([ 'events', 'selected' ]), targetDefinerDisplayed: state.getIn([ 'components', 'targetDefiner', 'isDisplayed' ]), testsAvaliable: false, }), { showTargetDefiner, setSelected, setEventFilter }) export default class EventsBlock extends React.PureComponent { state = { editingEvent: null, mouseOver: false, query: '' } scroller = React.createRef(); cache = new CellMeasurerCache({ fixedWidth: true, defaultHeight: 300 }); write = ({ target: { value, name } }) => { const { filter } = this.state; this.setState({ query: value }) this.props.setEventFilter({ query: value, filter }) setTimeout(() => { if (!this.scroller.current) return; this.scroller.current.scrollToRow(0); }, 100) } clearSearch = () => { const { filter } = this.state; this.setState({ query: '' }) this.props.setEventFilter({ query: '', filter }) this.scroller.current.forceUpdateGrid(); setTimeout(() => { if (!this.scroller.current) return; this.scroller.current.scrollToRow(0); }, 100) } onSetEventFilter = (e, { name, value }) => { const { query } = this.state; this.setState({ filter: value }) this.props.setEventFilter({ filter: value, query }); } componentDidUpdate(prevProps) { if (prevProps.targetDefinerDisplayed && !this.props.targetDefinerDisplayed) { this.setState({ editingEvent: null }); } if (prevProps.session !== this.props.session) { // Doesn't happen this.cache = new CellMeasurerCache({ fixedWidth: true, defaultHeight: 300 }); } if (prevProps.currentTimeEventIndex !== this.props.currentTimeEventIndex && this.scroller.current !== null) { this.scroller.current.forceUpdateGrid(); if (!this.state.mouseOver) { this.scroller.current.scrollToRow(this.props.currentTimeEventIndex); } } } onCheckboxClick(e, event) { e.stopPropagation(); const { session: { events }, selectedEvents, } = this.props; this.props.player.pause(); let newSelectedSet; const wasSelected = selectedEvents.contains(event); if (wasSelected) { newSelectedSet = selectedEvents.remove(event); } else { newSelectedSet = selectedEvents.add(event); } let selectNextLoad = false; events.reverse().forEach((sessEvent) => { if (sessEvent.type === TYPES.LOCATION) { if (selectNextLoad) { newSelectedSet = newSelectedSet.add(sessEvent); } selectNextLoad = false; } else if (newSelectedSet.contains(sessEvent)) { selectNextLoad = true; } }); this.props.setSelected(newSelectedSet); } onEventClick = (e, event) => this.props.player.jump(event.time) onMouseOver = () => this.setState({ mouseOver: true }) onMouseLeave = () => this.setState({ mouseOver: false }) renderGroup = ({ index, key, style, parent }) => { const { session: { events }, selectedEvents, currentTimeEventIndex, testsAvaliable, playing, eventsIndex, filteredEvents } = this.props; const { query } = this.state; const _events = filteredEvents || events; const isLastEvent = index === _events.size - 1; const isLastInGroup = isLastEvent || _events.get(index + 1).type === TYPES.LOCATION; const event = _events.get(index); const isSelected = selectedEvents.includes(event); const isCurrent = index === currentTimeEventIndex; const isEditing = this.state.editingEvent === event; const heightBug = index === 0 && event.type === TYPES.LOCATION && event.referrer ? { top: 2 } : {} return ( {({measure, registerChild}) => (
)}
); } render() { const { query } = this.state; const { testsAvaliable, session: { events, }, filteredEvents, setActiveTab, } = this.props; const _events = filteredEvents || events; const isEmptySearch = query && (_events.size === 0 || !_events) return ( <>
User Events { events.size }
} />
{isEmptySearch && (
No Matching Results
)} {({ height }) => ( )}
); } }