Auto-open publish history drawer

This commit is contained in:
Thomas Nordquist
2019-07-17 17:25:12 +02:00
parent ae915a158b
commit af4cfec451
4 changed files with 46 additions and 50 deletions

View File

@@ -1,4 +1,4 @@
import * as React from 'react' import React, { useCallback, useState, useEffect, memo } from 'react'
import { Badge, Typography } from '@material-ui/core' import { Badge, Typography } from '@material-ui/core'
import { selectTextWithCtrlA } from '../../utils/handleTextSelectWithCtrlA' import { selectTextWithCtrlA } from '../../utils/handleTextSelectWithCtrlA'
import { Theme, withStyles, emphasize } from '@material-ui/core/styles' import { Theme, withStyles, emphasize } from '@material-ui/core/styles'
@@ -15,51 +15,49 @@ interface Props {
onClick?: (index: number, element: EventTarget) => void onClick?: (index: number, element: EventTarget) => void
classes: any classes: any
contentTypeIndicator?: JSX.Element contentTypeIndicator?: JSX.Element
autoOpen?: boolean
theme: Theme theme: Theme
children: any
} }
interface State { function HistoryDrawer(props: Props) {
collapsed: boolean const handleCtrlA = selectTextWithCtrlA({ targetSelector: 'pre' })
} const [expanded, setExpanded] = useState<boolean | undefined>(undefined)
class HistoryDrawer extends React.Component<Props, State> { const toggle = useCallback(() => {
private handleCtrlA = selectTextWithCtrlA({ targetSelector: 'pre' }) setExpanded(!expanded)
}, [expanded])
constructor(props: any) { useEffect(() => {
super(props) if (props.autoOpen && expanded === undefined && props.items.length > 0) {
this.state = { setExpanded(true)
collapsed: true,
}
} }
}, [props.autoOpen, expanded, props.items])
private toggle = () => { const createSelectionHandler = (index: number) => (event: React.MouseEvent) => {
this.setState({ collapsed: !this.state.collapsed }) props.onClick && props.onClick(index, event.target)
}
private createSelectionHandler = (index: number) => (event: React.MouseEvent) => {
this.props.onClick && this.props.onClick(index, event.target)
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
} }
public renderHistory() { function renderHistory() {
const style = (element: HistoryItem) => ({ const style = (element: HistoryItem) => ({
backgroundColor: element.selected backgroundColor: element.selected
? emphasize(this.props.theme.palette.background.default, 0.2) ? emphasize(props.theme.palette.background.default, 0.2)
: emphasize(this.props.theme.palette.background.default, 0.07), : emphasize(props.theme.palette.background.default, 0.07),
margin: '8px', margin: '8px',
padding: '8px 8px 0 8px', padding: '8px 8px 0 8px',
cursor: this.props.onClick ? 'pointer' : 'inherit', cursor: props.onClick ? 'pointer' : 'inherit',
}) })
const messageStyle: React.CSSProperties = { textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden' } const messageStyle: React.CSSProperties = { textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden' }
const elements = this.props.items.map((element, index) => ( const elements = props.items.map((element, index) => (
<div <div
key={element.key} key={element.key}
style={style(element)} style={style(element)}
onClick={this.createSelectionHandler(index)} onClick={createSelectionHandler(index)}
tabIndex={0} tabIndex={0}
onKeyDown={this.handleCtrlA} onKeyDown={handleCtrlA}
> >
<div> <div>
<i>{element.title}</i> <i>{element.title}</i>
@@ -72,36 +70,39 @@ class HistoryDrawer extends React.Component<Props, State> {
</div> </div>
)) ))
const visible = this.props.items.length > 0 && this.state.collapsed const visible = props.items.length > 0 && !expanded
return ( return (
<div className={this.props.classes.main}> <div className={props.classes.main}>
<div style={{ backgroundColor: emphasize(this.props.theme.palette.background.default, 0.07) }}> <div
<Typography component={'span'} onClick={this.toggle} style={{ cursor: 'pointer', display: 'flex' }}> style={{
backgroundColor: emphasize(props.theme.palette.background.default, 0.07),
borderBottom: expanded ? `1px solid ${emphasize(props.theme.palette.background.default, 0.2)}` : undefined,
}}
>
<Typography component={'span'} onClick={toggle} style={{ cursor: 'pointer', display: 'flex' }}>
<span style={{ flexGrow: 1 }}> <span style={{ flexGrow: 1 }}>
<Badge <Badge
classes={{ badge: this.props.classes.badge }} classes={{ badge: props.classes.badge }}
invisible={!visible} invisible={!visible}
badgeContent={this.props.items.length} badgeContent={props.items.length}
color="primary" color="primary"
> >
{this.state.collapsed ? ' History' : ' History'} {expanded ? ' History' : ' History'}
</Badge> </Badge>
</span> </span>
<span>{this.props.contentTypeIndicator}</span> <span>{props.contentTypeIndicator}</span>
</Typography> </Typography>
</div> </div>
<div style={{ maxHeight: '230px', overflowY: 'scroll' }}> <div style={{ maxHeight: '230px', overflowY: 'scroll' }}>
{this.state.collapsed ? null : this.props.children} {expanded ? props.children : null}
{this.state.collapsed ? null : elements} {expanded ? elements : null}
</div> </div>
</div> </div>
) )
} }
public render() { return <div style={{ display: 'block', width: '100%' }}>{renderHistory()}</div>
return <div style={{ display: 'block', width: '100%' }}>{this.renderHistory()}</div>
}
} }
const styles = (theme: Theme) => ({ const styles = (theme: Theme) => ({
@@ -112,4 +113,4 @@ const styles = (theme: Theme) => ({
badge: { right: '-25px' }, badge: { right: '-25px' },
}) })
export default withStyles(styles, { withTheme: true })(HistoryDrawer) export default withStyles(styles, { withTheme: true })(memo(HistoryDrawer))

View File

@@ -70,7 +70,7 @@ function Publish(props: Props) {
return useMemo( return useMemo(
() => ( () => (
<div style={{ flexGrow: 1, marginLeft: '8px' }} onKeyDown={handleSubmit}> <div style={{ flexGrow: 1 }} onKeyDown={handleSubmit}>
<TopicInput /> <TopicInput />
<div style={{ width: '100%', display: 'block' }}> <div style={{ width: '100%', display: 'block' }}>
<EditorMode <EditorMode

View File

@@ -24,7 +24,7 @@ function PublishHistory(props: { history: Array<Message>; actions: typeof publis
value: message.payload || '', value: message.payload || '',
})) }))
return <History items={items} onClick={didSelectHistoryEntry} /> return <History autoOpen={true} items={items} onClick={didSelectHistoryEntry} />
}, [props.history]) }, [props.history])
} }

View File

@@ -6,7 +6,7 @@ import { Base64Message } from '../../../../../backend/src/Model/Base64Message'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { default as ReactResizeDetector } from 'react-resize-detector' import { default as ReactResizeDetector } from 'react-resize-detector'
import { ValueRendererDisplayMode } from '../../../reducers/Settings' import { ValueRendererDisplayMode } from '../../../reducers/Settings'
import { Typography } from '@material-ui/core' import { Typography, Fade, Grow } from '@material-ui/core'
interface Props { interface Props {
message: q.Message message: q.Message
@@ -67,19 +67,14 @@ class ValueRenderer extends React.Component<Props, State> {
return return
} }
const value = this.convertMessage(message.value) const value = this.convertMessage(message.value)
if (!compare) { const compareStr = compare && compare.value ? this.convertMessage(compare.value) : undefined
return this.renderDiff(value, value)
}
if (!compare.value) {
return
}
const compareStr = this.convertMessage(compare.value)
return ( return (
<div> <div>
{this.renderDiff(value, value)} {this.renderDiff(value, value)}
{this.renderDiff(compareStr, compareStr, 'selected')} <Fade in={Boolean(compareStr)} timeout={400}>
<div>{Boolean(compareStr) ? this.renderDiff(compareStr, compareStr, 'selected') : null}</div>
</Fade>
</div> </div>
) )
} }