Skip to content
Snippets Groups Projects
Commit 65f55902 authored by Anthony's avatar Anthony
Browse files

MigratingAnnotationCreation to MUI5.

It's possible to display the creation annotation window, not validate the creation.
parent 8cedeb3c
No related branches found
No related tags found
1 merge request!10Draft: MigratingAnnotationCreation to MUI5.
Pipeline #1659 failed
......@@ -538,7 +538,7 @@ class AnnotationCreation extends Component {
<Alarm fontSize="small" />
</ToggleButton>
</div>
{/* <HMSInput seconds={tstart} onChange={this.updateTstart} /> */}
<HMSInput seconds={tstart} onChange={this.updateTstart} />
</div>
<div style={{
border: '1px solid rgba(0, 0, 0, 0.12)',
......@@ -580,7 +580,7 @@ class AnnotationCreation extends Component {
<Alarm fontSize="small" />
</ToggleButton>
</div>
{/* <HMSInput seconds={tend} onChange={this.updateTend} /> */}
<HMSInput seconds={tend} onChange={this.updateTend} />
</div>
</div>
</>
......@@ -594,7 +594,7 @@ class AnnotationCreation extends Component {
</Typography>
</Grid>
<Grid item xs={12} style={{ marginBottom: 10 }}>
{/* <ImageFormField value={image} onChange={this.handleImgChange} /> */}
<ImageFormField value={image} onChange={this.handleImgChange} />
</Grid>
</Grid>
</div>
......
......
import React, { Component } from 'react';
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@mui/material/styles';
import { Input } from '@mui/material';
import { Input, styled } from '@mui/material';
import { secondsToHMSarray } from './utils';
/** hh:mm:ss input which behave like a single input for parent */
class HMSInput extends Component {
/** Initialize state structure & bindings */
constructor(props) {
super(props);
const StyledInput = styled(Input)(({ theme }) => ({
height: 'fit-content',
margin: '2px',
'& input[type=number]': {
'-moz-appearance': 'textfield',
},
'& input[type=number]::-webkit-outer-spin-button, & input[type=number]::-webkit-inner-spin-button': {
'-webkit-appearance': 'none',
margin: 0,
},
}));
// eslint-disable-next-line react/destructuring-assignment
const [h, m, s] = secondsToHMSarray(this.props.seconds);
this.state = {
hours: h,
minutes: m,
seconds: s,
};
this.someChange = this.someChange.bind(this);
}
const StyledHMSLabel = styled('span')({
color: 'grey',
});
/** update */
componentDidUpdate(prevProps) {
const { seconds } = this.props;
if (prevProps.seconds === seconds) return;
const [h, m, s] = secondsToHMSarray(seconds);
this.setState({
hours: h,
minutes: m,
seconds: s,
const StyledRoot = styled('div')({
alignItems: 'center',
display: 'flex',
});
}
/** If one value is updated, tell the parent component the total seconds counts */
someChange(ev) {
const { onChange } = this.props;
const { state } = this;
state[ev.target.name] = Number(ev.target.value);
onChange(state.hours * 3600 + state.minutes * 60 + state.seconds);
}
function HMSInput({ seconds, onChange }) {
const [hms, setHms] = useState(secondsToHMSarray(seconds));
useEffect(() => {
setHms(secondsToHMSarray(seconds));
}, [seconds]);
const someChange = (ev) => {
const newState = { ...hms, [ev.target.name]: Number(ev.target.value) };
setHms(newState);
onChange(newState.hours * 3600 + newState.minutes * 60 + newState.seconds);
};
/** Render */
render() {
const { hours, minutes, seconds } = this.state;
const { classes } = this.props;
return (
<div className={classes.root}>
<div className={classes.root}>
<Input
className={classes.input}
<StyledRoot>
<StyledInput
variant="filled"
type="number"
min="0"
pattern
name="hours"
value={hours}
onChange={this.someChange}
value={hms.hours}
onChange={someChange}
inputProps={{ style: { textAlign: 'center' } }}
/>
<span className={classes.hmsLabel}>h</span>
<Input className={classes.input} type="number" min="0" max="59" name="minutes" value={minutes} onChange={this.someChange} inputProps={{ style: { textAlign: 'center' } }} />
<span className={classes.hmsLabel}>m</span>
<Input className={classes.input} type="number" min="0" max="59" name="seconds" value={seconds} onChange={this.someChange} inputProps={{ style: { textAlign: 'center' } }} />
<span className={classes.hmsLabel}>s</span>
</div>
</div>
<StyledHMSLabel>h</StyledHMSLabel>
<StyledInput
type="number"
min="0"
max="59"
name="minutes"
value={hms.minutes}
onChange={someChange}
inputProps={{ style: { textAlign: 'center' } }}
/>
<StyledHMSLabel>m</StyledHMSLabel>
<StyledInput
type="number"
min="0"
max="59"
name="seconds"
value={hms.seconds}
onChange={someChange}
inputProps={{ style: { textAlign: 'center' } }}
/>
<StyledHMSLabel>s</StyledHMSLabel>
</StyledRoot>
);
}
}
/** */
const styles = (theme) => ({
root: {
alignItems: 'center',
display: 'flex',
},
// eslint-disable-next-line sort-keys
flexcol: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
},
hmsLabel: {
color: 'grey',
},
// eslint-disable-next-line sort-keys
input: {
height: 'fit-content',
margin: '2px',
// remove arrow from field for Firefox
'& input[type=number]': {
'-moz-appearance': 'textfield',
},
// remove arrow from field for Chrome, Safari and Opera
'& input[type=number]::-webkit-outer-spin-button': {
'-webkit-appearance': 'none',
margin: 0,
},
'& input[type=number]::-webkit-inner-spin-button': {
'-webkit-appearance': 'none',
margin: 0,
},
},
});
HMSInput.propTypes = {
// eslint-disable-next-line react/forbid-prop-types
classes: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
seconds: PropTypes.number.isRequired,
};
HMSInput.defaultProps = {
};
export default HMSInput;
import React, { Component } from 'react';
import React, { useRef, useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@mui/material/styles';
import { TextField } from '@mui/material';
import { TextField, styled } from '@mui/material';
/** URL input with an <img> preview */
class ImageFormField extends Component {
/** */
constructor(props) {
super(props);
const StyledRoot = styled('div')(({ theme }) => ({
alignItems: 'center',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
}));
this.inputRef = React.createRef();
function ImageFormField({ value: image, onChange }) {
const inputRef = useRef(null);
const [imgIsValid, setImgIsValid] = useState(false);
useEffect(() => {
if (inputRef.current) {
setImgIsValid(image.id && inputRef.current.checkValidity());
} else {
setImgIsValid(!!image.id);
}
}, [image]);
/** Render input field and a preview if the input is valid */
render() {
const { value: image, classes, onChange } = this.props;
const imgIsValid = this.inputRef.current
? (image.id && this.inputRef.current.checkValidity()) : image.id;
const imgUrl = image.id === null ? '' : image.id;
return (
<div className={classes.root}>
<StyledRoot>
<TextField
value={imgUrl}
onChange={(ev) => onChange(ev.target.value)}
......@@ -28,35 +33,18 @@ class ImageFormField extends Component {
label="Image URL"
type="url"
fullWidth
inputRef={this.inputRef}
inputRef={inputRef}
/>
{ imgIsValid
&& <img src={image.id} width="100%" height="auto" alt="loading failed" /> }
</div>
{imgIsValid && <img src={image.id} width="100%" height="auto" alt="loading failed" />}
</StyledRoot>
);
}
}
/** custom css */
const styles = (theme) => ({
root: {
alignItems: 'center',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
},
});
ImageFormField.propTypes = {
// eslint-disable-next-line react/forbid-prop-types
classes: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
value: PropTypes.shape({
id: PropTypes.string,
}).isRequired,
};
ImageFormField.defaultProps = {
};
export default ImageFormField;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment