Skip to content

Commit a1802a4

Browse files
committed
chore: fix deprecation warnings and refactor react reporter to use hooks
1 parent 34588e9 commit a1802a4

File tree

12 files changed

+475
-653
lines changed

12 files changed

+475
-653
lines changed

packages/reporter/src/attempts/attempts.tsx

+19-32
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import cs from 'classnames'
22
import { observer } from 'mobx-react'
3-
import React, { Component } from 'react'
3+
import React from 'react'
44

55
import type { TestState } from '@packages/types'
66
import Agents from '../agents/agents'
@@ -52,7 +52,7 @@ function renderAttemptContent (model: AttemptModel, studioActive: boolean) {
5252
<Sessions model={model.sessions} />
5353
<Agents model={model} />
5454
<Routes model={model} />
55-
<div ref='commands' className='runnable-commands-region'>
55+
<div className='runnable-commands-region'>
5656
{model.hasCommands ? <Hooks model={model} /> : <NoCommands />}
5757
</div>
5858
{model.state === 'failed' && (
@@ -71,37 +71,24 @@ interface AttemptProps {
7171
studioActive: boolean
7272
}
7373

74-
@observer
75-
class Attempt extends Component<AttemptProps> {
76-
componentDidUpdate () {
77-
this.props.scrollIntoView()
78-
}
79-
80-
render () {
81-
const { model, studioActive } = this.props
82-
83-
// HACK: causes component update when command log is added
84-
model.commands.length
85-
86-
return (
87-
<li
88-
key={model.id}
89-
className={cs('attempt-item', `attempt-state-${model.state}`)}
90-
ref="container"
74+
const Attempt: React.FC<AttemptProps> = observer(({ model, scrollIntoView, studioActive }) => {
75+
return (
76+
<li
77+
key={model.id}
78+
className={cs('attempt-item', `attempt-state-${model.state}`)}
79+
>
80+
<Collapsible
81+
header={<AttemptHeader index={model.id} state={model.state} />}
82+
hideExpander
83+
headerClass='attempt-name'
84+
contentClass='attempt-content'
85+
isOpen={model.isOpen}
9186
>
92-
<Collapsible
93-
header={<AttemptHeader index={model.id} state={model.state} />}
94-
hideExpander
95-
headerClass='attempt-name'
96-
contentClass='attempt-content'
97-
isOpen={model.isOpen}
98-
>
99-
{renderAttemptContent(model, studioActive)}
100-
</Collapsible>
101-
</li>
102-
)
103-
}
104-
}
87+
{renderAttemptContent(model, studioActive)}
88+
</Collapsible>
89+
</li>
90+
)
91+
})
10592

10693
const Attempts = observer(({ test, scrollIntoView, studioActive }: {test: TestModel, scrollIntoView: Function, studioActive: boolean}) => {
10794
return (<ul className={cs('attempts', {
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,65 @@
11
import cs from 'classnames'
2-
import React, { Component, CSSProperties, MouseEvent, ReactNode, RefObject } from 'react'
2+
import React, { CSSProperties, MouseEvent, ReactNode, RefObject, useState } from 'react'
33

44
import { onEnterOrSpace } from '../lib/util'
55

66
import ChevronIcon from '@packages/frontend-shared/src/assets/icons/chevron-down-small_x8.svg'
77

8-
interface Props {
8+
interface CollapsibleProps {
99
isOpen?: boolean
1010
headerClass?: string
1111
headerStyle?: CSSProperties
1212
header?: ReactNode
1313
headerExtras?: ReactNode
1414
containerRef?: RefObject<HTMLDivElement>
1515
contentClass?: string
16-
hideExpander: boolean
16+
hideExpander?: boolean
17+
children: React.ReactNode
1718
}
1819

19-
interface State {
20-
isOpen: boolean
21-
}
22-
23-
class Collapsible extends Component<Props, State> {
24-
static defaultProps = {
25-
isOpen: false,
26-
headerClass: '',
27-
headerStyle: {},
28-
contentClass: '',
29-
hideExpander: false,
30-
}
31-
32-
constructor (props: Props) {
33-
super(props)
20+
const Collapsible: React.FC<CollapsibleProps> = ({ isOpen: isOpenAsProp = false, header, headerClass = '', headerStyle = {}, headerExtras, contentClass = '', hideExpander = false, containerRef = null, toggleOpen = () => undefined, children }) => {
21+
const [isOpen, setIsOpen] = useState(isOpenAsProp)
3422

35-
this.state = { isOpen: props.isOpen || false }
23+
const _onClick = (e: MouseEvent) => {
24+
e.stopPropagation()
25+
setIsOpen(!isOpen)
3626
}
3727

38-
componentDidUpdate (prevProps: Props) {
39-
if (this.props.isOpen != null && this.props.isOpen !== prevProps.isOpen) {
40-
this.setState({ isOpen: this.props.isOpen })
41-
}
28+
const _onKeyPress = () => {
29+
setIsOpen(!isOpen)
4230
}
4331

44-
render () {
45-
return (
46-
<div className={cs('collapsible', { 'is-open': this.state.isOpen })} ref={this.props.containerRef}>
47-
<div className={cs('collapsible-header-wrapper', this.props.headerClass)}>
32+
return (
33+
<div className={cs('collapsible', { 'is-open': isOpen })} ref={containerRef}>
34+
<div className={cs('collapsible-header-wrapper', headerClass)}>
35+
<div
36+
aria-expanded={isOpen}
37+
className='collapsible-header'
38+
onClick={_onClick}
39+
onKeyUp={onEnterOrSpace(_onKeyPress)}
40+
role='button'
41+
tabIndex={0}
42+
>
4843
<div
49-
aria-expanded={this.state.isOpen}
50-
className='collapsible-header'
51-
onClick={this._onClick}
52-
onKeyPress={onEnterOrSpace(this._onKeyPress)}
53-
role='button'
54-
tabIndex={0}
44+
className='collapsible-header-inner'
45+
style={headerStyle}
46+
tabIndex={-1}
5547
>
56-
<div
57-
className='collapsible-header-inner'
58-
style={this.props.headerStyle}
59-
tabIndex={-1}
60-
>
61-
{!this.props.hideExpander && <ChevronIcon className='collapsible-indicator' />}
62-
<span className='collapsible-header-text'>
63-
{this.props.header}
64-
</span>
65-
</div>
48+
{!hideExpander && <ChevronIcon className='collapsible-indicator' />}
49+
<span className='collapsible-header-text'>
50+
{header}
51+
</span>
6652
</div>
67-
{this.props.headerExtras}
6853
</div>
69-
{this.state.isOpen && (
70-
<div className={cs('collapsible-content', this.props.contentClass)}>
71-
{this.props.children}
72-
</div>
73-
)}
54+
{headerExtras}
7455
</div>
75-
)
76-
}
77-
78-
_toggleOpen = () => {
79-
this.setState({ isOpen: !this.state.isOpen })
80-
}
81-
82-
_onClick = (e: MouseEvent) => {
83-
e.stopPropagation()
84-
this._toggleOpen()
85-
}
86-
87-
_onKeyPress = () => {
88-
this._toggleOpen()
89-
}
56+
{isOpen && (
57+
<div className={cs('collapsible-content', contentClass)}>
58+
{children}
59+
</div>
60+
)}
61+
</div>
62+
)
9063
}
9164

9265
export default Collapsible

0 commit comments

Comments
 (0)