Commit e818d0a0 authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Optimized the GUI keeping state of invisible components.

parent 7c666fef
......@@ -31,8 +31,8 @@ import {help as uploadHelp, default as Uploads} from './uploads/Uploads'
import ResolvePID from './entry/ResolvePID'
import DatasetPage from './DatasetPage'
import { capitalize } from '../utils'
import { makeStyles } from '@material-ui/core/styles'
import { amber } from '@material-ui/core/colors'
import KeepState from './KeepState'
export class VersionMismatch extends Error {
constructor(msg) {
......@@ -471,6 +471,7 @@ export default class App extends React.Component {
'metainfo': {
exact: true,
path: '/metainfo',
singleton: true,
render: props => <MetaInfoBrowser {...props} />
},
'metainfoEntry': {
......@@ -481,21 +482,13 @@ export default class App extends React.Component {
}
renderChildren(routeKey, props) {
// const { match, ...rest } = props
return (
<div>
{Object.keys(this.routes)
.filter(route => this.routes[route].singleton || route === routeKey)
.map(route => (
<div
key={route.key ? route.key(props) : route}
style={{display: routeKey === route ? 'block' : 'none'}}
>
{this.routes[route].render(props)}
</div>
))}
</div>
<React.Fragment>
{Object.keys(this.routes).map(route => <KeepState key={route}
visible={routeKey === route}
render={(props) => this.routes[route].render(props)}
{...props} />)}
</React.Fragment>
)
}
......
......@@ -40,7 +40,7 @@ class DatasetPage extends React.Component {
dataset: {}
}
componentDidMount() {
update() {
const {datasetId, raiseError, api} = this.props
api.search({
owner: 'all',
......@@ -56,6 +56,16 @@ class DatasetPage extends React.Component {
})
}
componentDidMount() {
this.update()
}
componentDidUpdate(prevProps) {
if (prevProps.api !== this.props.api || prevProps.datasetId !== this.props.datasetId) {
this.update()
}
}
render() {
const { classes, datasetId } = this.props
const { dataset } = this.state
......
import React from 'react'
import PropTypes, { instanceOf } from 'prop-types'
/**
* This is a kinda-HOC that allows to keep a component alive while not being visible.
*/
export default class KeepState extends React.Component {
static propTypes = {
visible: PropTypes.bool,
render: PropTypes.func.isRequired
}
state = {
props: null
}
update() {
const { visible, render, ...props } = this.props
if (this.props.visible) {
this.setState({props: props})
}
}
componentDidMount() {
this.update()
}
componentDidUpdate(prevProps) {
if (prevProps.visible !== this.props.visible && this.props.visible) {
this.update()
}
}
render() {
const { visible, render, ...other } = this.props
const props = visible ? other : this.state.props
if (props) {
return <div style={{display: visible ? 'block' : 'none'}}>
{render(props)}
</div>
} else {
return ''
}
}
}
\ No newline at end of file
......@@ -63,16 +63,19 @@ class ArchiveEntryView extends React.Component {
bottom: 32,
position: 'fixed !important'
}
});
})
static defaultState = {
data: null,
metaInfo: null,
showMetaInfo: false,
doesNotExist: false
}
state = {...ArchiveEntryView.defaultState}
constructor(props) {
super(props)
this.state = {
data: null,
metaInfo: null,
showMetaInfo: false,
doesNotExist: false
}
this.unmounted = false
}
......@@ -87,9 +90,16 @@ class ArchiveEntryView extends React.Component {
componentDidUpdate(prevProps) {
if (prevProps.api !== this.props.api || prevProps.info !== this.props.info) {
this.updateArchive()
this.setState(ArchiveEntryView.defaultState)
this.updateMetaInfo()
}
if (prevProps.api !== this.props.api ||
prevProps.uploadId !== this.props.uploadId ||
prevProps.calcId !== this.props.calcId) {
this.setState({...ArchiveEntryView.defaultState})
this.updateArchive()
}
}
updateMetaInfo() {
......
......@@ -32,20 +32,22 @@ class ArchiveLogView extends React.Component {
}
});
constructor(props) {
super(props)
this.state = {
static defaultState = {
data: null,
doesNotExist: false
}
}
state = {...ArchiveLogView.defaultState}
componentDidMount() {
this.update()
}
componentDidUpdate(prevProps) {
if (prevProps.api !== this.props.api) {
if (prevProps.api !== this.props.api ||
prevProps.uploadId !== this.props.uploadId ||
prevProps.calcId !== this.props.calcId) {
this.setState({...ArchiveLogView.defaultState})
this.update()
}
}
......
......@@ -7,6 +7,7 @@ import RepoEntryView from './RepoEntryView'
import { withApi, DoesNotExist } from '../api'
import { compose } from 'recompose'
import qs from 'qs'
import KeepState from '../KeepState'
class EntryPage extends React.Component {
static styles = theme => ({
......@@ -28,27 +29,32 @@ class EntryPage extends React.Component {
query: PropTypes.bool
}
state = {
static defaultState = {
viewIndex: 0,
calcId: null,
uploadId: null
}
state = {...EntryPage.defaultState}
componentDidMount() {
this.update()
}
componentDidUpdate(prevProps) {
if (prevProps.query !== this.props.query
|| prevProps.location !== this.props.location
|| prevProps.location.key !== this.props.location.key
|| prevProps.uploadId !== this.props.uploadId
|| prevProps.calcId !== this.props.calcId
|| prevProps.query !== this.props.query
|| prevProps.api !== this.props.api) {
this.setState({...EntryPage.defaultState})
this.update()
}
}
update() {
console.log('update entry page')
const { calcId, uploadId, query, location } = this.props
if (query) {
let queryParams = null
......@@ -58,14 +64,14 @@ class EntryPage extends React.Component {
this.props.api.search({...queryParams}).then(data => {
if (data.results && data.results.length > 0) {
const { calc_id, upload_id } = data.results[0]
this.setState({uploadId: upload_id, calcId: calc_id})
this.setState({uploadId: upload_id, calcId: calc_id, viewIndex: 0})
} else {
this.props.raiseError(new DoesNotExist())
}
}).catch(this.props.raiseError)
} else {
if (calcId && uploadId) {
this.setState({calcId: calcId, uploadId: uploadId})
this.setState({calcId: calcId, uploadId: uploadId, viewIndex: 0})
} else {
// this should be unreachable
this.props.raiseError(new DoesNotExist())
......@@ -95,15 +101,9 @@ class EntryPage extends React.Component {
</Tabs>
<div className={classes.content}>
<div style={viewIndex !== 0 ? {display: 'none'} : {}} >
<RepoEntryView {...calcProps} />
</div>
<div style={viewIndex !== 1 ? {display: 'none'} : {}} >
<ArchiveEntryView {...calcProps} />
</div>
<div style={viewIndex !== 2 ? {display: 'none'} : {}} >
<ArchiveLogView {...calcProps} />
</div>
<KeepState visible={viewIndex === 0} render={props => <RepoEntryView {...props} />} {...calcProps} />
<KeepState visible={viewIndex === 1} render={props => <ArchiveEntryView {...props} />} {...calcProps} />
<KeepState visible={viewIndex === 2} render={props => <ArchiveLogView {...props} />} {...calcProps} />
</div>
</div>
)
......
......@@ -23,19 +23,24 @@ class RawFiles extends React.Component {
}
})
state = {
static defaultState = {
selectedFiles: [],
uploadDirectory: null,
files: null,
doesNotExist: false
}
state = {...RawFiles.defaultState}
componentDidMount() {
this.update()
}
componentDidUpdate(prevProps) {
if (prevProps.api !== this.props.api) {
if (prevProps.api !== this.props.api ||
prevProps.data.uploadId !== this.props.data.uploadId ||
prevProps.data.calcId !== this.props.data.calcId) {
this.setState({...RawFiles.defaultState})
this.update()
}
}
......
......@@ -45,17 +45,23 @@ class RepoEntryView extends React.Component {
domain: PropTypes.object.isRequired
}
state = {
static defaultState = {
calcData: null,
doesNotExist: false
}
state = {...RepoEntryView.defaultState}
componentDidMount() {
this.update()
}
componentDidUpdate(prevProps) {
if (prevProps.api !== this.props.api) {
if (prevProps.api !== this.props.api ||
prevProps.uploadId !== this.props.uploadId ||
prevProps.calcId !== this.props.calcId
) {
this.setState({...RepoEntryView.defaultState})
this.update()
}
}
......
......@@ -5,7 +5,7 @@ import { compose } from 'recompose'
import { withApi } from '../api'
import { withRouter } from 'react-router'
class ResovlePID extends React.Component {
class ResolvePID extends React.Component {
static styles = theme => ({
root: {
padding: theme.spacing.unit * 3
......@@ -20,11 +20,13 @@ class ResovlePID extends React.Component {
raiseError: PropTypes.func.isRequired
}
state = {
static defaultState = {
doesNotExist: false
}
componentDidMount() {
state = {...ResolvePID.defaultState}
update() {
const { pid, api, history } = this.props
api.resolvePid(pid).then(entry => {
history.push(`/entry/id/${entry.upload_id}/${entry.calc_id}`)
......@@ -38,6 +40,17 @@ class ResovlePID extends React.Component {
})
}
componentDidMount() {
this.update()
}
componentDidUpdate(prevProps) {
if (prevProps.pid !== this.props.pid || prevProps.api !== this.props.api) {
this.setState({...ResolvePID.defaultState})
this.update()
}
}
render() {
const { classes, api } = this.props
const { doesNotExist } = this.state
......@@ -62,4 +75,4 @@ class ResovlePID extends React.Component {
}
}
export default compose(withRouter, withApi(false), withStyles(ResovlePID.styles))(ResovlePID)
export default compose(withRouter, withApi(false), withStyles(ResolvePID.styles))(ResolvePID)
......@@ -66,7 +66,6 @@ class QuantityHistogram extends React.Component {
const selected = this.props.value
const width = this.container.current.offsetWidth
console.log('B ' + width)
const height = Object.keys(this.props.data).length * 32
const data = Object.keys(this.props.data)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment