Auto-open publish history drawer
This commit is contained in:
@@ -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))
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user