2017-11-08 19:51:55 +02:00
|
|
|
const React = require('react');
|
|
|
|
const { connect } = require('react-redux');
|
|
|
|
const { _ } = require('lib/locale.js');
|
2017-12-01 23:55:02 +02:00
|
|
|
const moment = require('moment');
|
2017-11-08 19:51:55 +02:00
|
|
|
const { themeStyle } = require('../theme.js');
|
2017-11-28 20:02:54 +02:00
|
|
|
const { time } = require('lib/time-utils.js');
|
2017-11-28 00:50:46 +02:00
|
|
|
const Datetime = require('react-datetime');
|
2019-06-08 00:33:06 +02:00
|
|
|
const CreatableSelect = require('react-select/lib/Creatable').default;
|
|
|
|
const makeAnimated = require('react-select/lib/animated').default;
|
2017-11-08 19:51:55 +02:00
|
|
|
|
|
|
|
class PromptDialog extends React.Component {
|
|
|
|
|
2019-06-08 00:33:06 +02:00
|
|
|
constructor() {
|
|
|
|
super();
|
|
|
|
|
|
|
|
this.answerInput_ = React.createRef();
|
|
|
|
}
|
|
|
|
|
2017-11-08 19:51:55 +02:00
|
|
|
componentWillMount() {
|
|
|
|
this.setState({
|
|
|
|
visible: false,
|
2019-02-24 20:04:25 +02:00
|
|
|
answer: this.props.defaultValue ? this.props.defaultValue : '',
|
2017-11-08 19:51:55 +02:00
|
|
|
});
|
|
|
|
this.focusInput_ = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillReceiveProps(newProps) {
|
2017-11-30 01:03:10 +02:00
|
|
|
if ('visible' in newProps && newProps.visible !== this.props.visible) {
|
2017-11-08 19:51:55 +02:00
|
|
|
this.setState({ visible: newProps.visible });
|
|
|
|
if (newProps.visible) this.focusInput_ = true;
|
|
|
|
}
|
2017-11-12 01:13:14 +02:00
|
|
|
|
2017-11-30 01:03:10 +02:00
|
|
|
if ('defaultValue' in newProps && newProps.defaultValue !== this.props.defaultValue) {
|
2019-02-24 20:04:25 +02:00
|
|
|
this.setState({ answer: newProps.defaultValue });
|
2017-11-12 01:13:14 +02:00
|
|
|
}
|
2017-11-08 19:51:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
componentDidUpdate() {
|
2019-06-08 00:33:06 +02:00
|
|
|
if (this.focusInput_ && this.answerInput_.current) this.answerInput_.current.focus();
|
2017-11-08 19:51:55 +02:00
|
|
|
this.focusInput_ = false;
|
|
|
|
}
|
|
|
|
|
2017-11-30 01:03:10 +02:00
|
|
|
styles(themeId, width, height, visible) {
|
|
|
|
const styleKey = themeId + '_' + width + '_' + height + '_' + visible;
|
|
|
|
if (styleKey === this.styleKey_) return this.styles_;
|
|
|
|
|
|
|
|
const theme = themeStyle(themeId);
|
2017-11-08 19:51:55 +02:00
|
|
|
|
2017-11-30 01:03:10 +02:00
|
|
|
this.styleKey_ = styleKey;
|
|
|
|
|
|
|
|
this.styles_ = {};
|
|
|
|
|
2018-01-09 22:06:47 +02:00
|
|
|
const paddingTop = 20;
|
|
|
|
|
2017-11-30 01:03:10 +02:00
|
|
|
this.styles_.modalLayer = {
|
2017-11-08 19:51:55 +02:00
|
|
|
zIndex: 9999,
|
|
|
|
position: 'absolute',
|
|
|
|
top: 0,
|
|
|
|
left: 0,
|
2017-11-30 01:03:10 +02:00
|
|
|
width: width,
|
2018-01-09 22:06:47 +02:00
|
|
|
height: height - paddingTop,
|
2017-11-08 19:51:55 +02:00
|
|
|
backgroundColor: 'rgba(0,0,0,0.6)',
|
2017-11-30 01:03:10 +02:00
|
|
|
display: visible ? 'flex' : 'none',
|
2019-06-08 00:33:06 +02:00
|
|
|
alignItems: 'flex-start',
|
|
|
|
justifyContent: 'center',
|
|
|
|
paddingTop: paddingTop + 'px',
|
2017-11-08 19:51:55 +02:00
|
|
|
};
|
|
|
|
|
2017-11-30 01:03:10 +02:00
|
|
|
this.styles_.promptDialog = {
|
2018-11-08 00:37:13 +02:00
|
|
|
backgroundColor: theme.backgroundColor,
|
2017-11-10 22:34:36 +02:00
|
|
|
padding: 16,
|
2017-11-08 19:51:55 +02:00
|
|
|
display: 'inline-block',
|
2019-06-08 00:33:06 +02:00
|
|
|
maxWidth: width * 0.5,
|
2017-11-08 19:51:55 +02:00
|
|
|
boxShadow: '6px 6px 20px rgba(0,0,0,0.5)',
|
|
|
|
};
|
|
|
|
|
2017-11-30 01:03:10 +02:00
|
|
|
this.styles_.button = {
|
2017-11-08 19:51:55 +02:00
|
|
|
minWidth: theme.buttonMinWidth,
|
|
|
|
minHeight: theme.buttonMinHeight,
|
|
|
|
marginLeft: 5,
|
2018-11-08 00:37:13 +02:00
|
|
|
color: theme.color,
|
|
|
|
backgroundColor: theme.backgroundColor,
|
|
|
|
border: '1px solid',
|
|
|
|
borderColor: theme.dividerColor,
|
2017-11-08 19:51:55 +02:00
|
|
|
};
|
|
|
|
|
2017-11-30 01:03:10 +02:00
|
|
|
this.styles_.label = {
|
2017-11-10 22:34:36 +02:00
|
|
|
marginRight: 5,
|
|
|
|
fontSize: theme.fontSize,
|
|
|
|
color: theme.color,
|
|
|
|
fontFamily: theme.fontFamily,
|
2019-06-08 00:33:06 +02:00
|
|
|
verticalAlign: 'middle',
|
2017-11-10 22:34:36 +02:00
|
|
|
};
|
|
|
|
|
2017-11-30 01:03:10 +02:00
|
|
|
this.styles_.input = {
|
|
|
|
width: 0.5 * width,
|
2017-11-08 19:51:55 +02:00
|
|
|
maxWidth: 400,
|
2018-11-08 00:37:13 +02:00
|
|
|
color: theme.color,
|
|
|
|
backgroundColor: theme.backgroundColor,
|
|
|
|
border: '1px solid',
|
|
|
|
borderColor: theme.dividerColor,
|
2017-11-08 19:51:55 +02:00
|
|
|
};
|
|
|
|
|
2019-06-08 00:33:06 +02:00
|
|
|
this.styles_.tagList = {
|
|
|
|
control: (provided) => (Object.assign(provided, {
|
|
|
|
minWidth: width * 0.2,
|
|
|
|
maxWidth: width * 0.5,
|
|
|
|
})),
|
|
|
|
input: (provided) => (Object.assign(provided, {
|
|
|
|
minWidth: '20px',
|
|
|
|
color: theme.color,
|
|
|
|
})),
|
|
|
|
menu: (provided) => (Object.assign(provided, {
|
|
|
|
color: theme.color,
|
|
|
|
fontFamily: theme.fontFamily,
|
|
|
|
backgroundColor: theme.backgroundColor,
|
|
|
|
})),
|
|
|
|
multiValueLabel: (provided) => (Object.assign(provided, {
|
|
|
|
fontFamily: theme.fontFamily,
|
|
|
|
})),
|
|
|
|
multiValueRemove: (provided) => (Object.assign(provided, {
|
|
|
|
color: theme.color,
|
|
|
|
})),
|
|
|
|
};
|
|
|
|
|
|
|
|
this.styles_.tagListTheme = (tagTheme) => (Object.assign(tagTheme, {
|
|
|
|
borderRadius: 2,
|
|
|
|
colors: Object.assign(tagTheme.colors, {
|
|
|
|
primary: theme.raisedBackgroundColor,
|
|
|
|
primary25: theme.raisedBackgroundColor,
|
|
|
|
neutral0: theme.backgroundColor,
|
|
|
|
neutral10: theme.raisedBackgroundColor,
|
|
|
|
neutral80: theme.color,
|
|
|
|
danger: theme.backgroundColor,
|
|
|
|
dangerLight: theme.colorError2,
|
|
|
|
}),
|
|
|
|
}));
|
|
|
|
|
2017-11-30 01:03:10 +02:00
|
|
|
this.styles_.desc = Object.assign({}, theme.textStyle, {
|
2017-11-12 01:13:14 +02:00
|
|
|
marginTop: 10,
|
|
|
|
});
|
|
|
|
|
2017-11-30 01:03:10 +02:00
|
|
|
return this.styles_;
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const style = this.props.style;
|
|
|
|
const theme = themeStyle(this.props.theme);
|
|
|
|
const buttonTypes = this.props.buttons ? this.props.buttons : ['ok', 'cancel'];
|
|
|
|
|
|
|
|
const styles = this.styles(this.props.theme, style.width, style.height, this.state.visible);
|
|
|
|
|
2017-11-28 00:50:46 +02:00
|
|
|
const onClose = (accept, buttonType) => {
|
2017-12-01 23:55:02 +02:00
|
|
|
if (this.props.onClose) {
|
|
|
|
let outputAnswer = this.state.answer;
|
|
|
|
if (this.props.inputType === 'datetime') {
|
2018-09-16 20:37:31 +02:00
|
|
|
// outputAnswer = anythingToDate(outputAnswer);
|
|
|
|
outputAnswer = time.anythingToDateTime(outputAnswer);
|
2017-12-01 23:55:02 +02:00
|
|
|
}
|
|
|
|
this.props.onClose(accept ? outputAnswer : null, buttonType);
|
|
|
|
}
|
2017-11-08 19:51:55 +02:00
|
|
|
this.setState({ visible: false, answer: '' });
|
|
|
|
}
|
|
|
|
|
|
|
|
const onChange = (event) => {
|
|
|
|
this.setState({ answer: event.target.value });
|
|
|
|
}
|
|
|
|
|
2018-09-16 20:37:31 +02:00
|
|
|
// const anythingToDate = (o) => {
|
|
|
|
// if (o && o.toDate) return o.toDate();
|
|
|
|
// if (!o) return null;
|
|
|
|
// let m = moment(o, time.dateTimeFormat());
|
|
|
|
// if (m.isValid()) return m.toDate();
|
|
|
|
// m = moment(o, time.dateFormat());
|
|
|
|
// return m.isValid() ? m.toDate() : null;
|
|
|
|
// }
|
2017-12-01 23:55:02 +02:00
|
|
|
|
2017-11-28 00:50:46 +02:00
|
|
|
const onDateTimeChange = (momentObject) => {
|
2017-12-01 23:55:02 +02:00
|
|
|
this.setState({ answer: momentObject });
|
2017-11-28 00:50:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-08 00:33:06 +02:00
|
|
|
const onTagsChange = (newTags) => {
|
|
|
|
this.setState({ answer: newTags });
|
|
|
|
this.focusInput_ = true;
|
|
|
|
}
|
|
|
|
|
2017-11-08 19:51:55 +02:00
|
|
|
const onKeyDown = (event) => {
|
2019-06-08 00:33:06 +02:00
|
|
|
if (event.key === 'Enter' && this.props.inputType !== 'tags') {
|
2019-02-24 20:04:25 +02:00
|
|
|
onClose(true);
|
2017-11-08 19:51:55 +02:00
|
|
|
} else if (event.key === 'Escape') {
|
2017-11-08 23:22:24 +02:00
|
|
|
onClose(false);
|
2017-11-08 19:51:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-30 01:03:10 +02:00
|
|
|
const descComp = this.props.description ? <div style={styles.desc}>{this.props.description}</div> : null;
|
2017-11-12 01:13:14 +02:00
|
|
|
|
2017-11-28 00:50:46 +02:00
|
|
|
let inputComp = null;
|
|
|
|
|
|
|
|
if (this.props.inputType === 'datetime') {
|
|
|
|
inputComp = <Datetime
|
|
|
|
value={this.state.answer}
|
2018-11-08 00:37:13 +02:00
|
|
|
inputProps={{style: styles.input}}
|
2017-11-28 20:02:54 +02:00
|
|
|
dateFormat={time.dateFormat()}
|
|
|
|
timeFormat={time.timeFormat()}
|
2017-11-28 00:50:46 +02:00
|
|
|
onChange={(momentObject) => onDateTimeChange(momentObject)}
|
|
|
|
/>
|
2019-06-08 00:33:06 +02:00
|
|
|
} else if (this.props.inputType === 'tags') {
|
|
|
|
inputComp = <CreatableSelect
|
|
|
|
styles={styles.tagList}
|
|
|
|
theme={styles.tagListTheme}
|
|
|
|
ref={this.answerInput_}
|
|
|
|
value={this.state.answer}
|
|
|
|
placeholder={this.props.label ? this.props.label.replace(':', '') : ''}
|
|
|
|
components={makeAnimated()}
|
|
|
|
isMulti={true}
|
|
|
|
isClearable={false}
|
|
|
|
backspaceRemovesValue={true}
|
|
|
|
options={this.props.autocomplete}
|
|
|
|
onChange={onTagsChange}
|
|
|
|
onKeyDown={(event) => onKeyDown(event)}
|
|
|
|
/>
|
2017-11-28 00:50:46 +02:00
|
|
|
} else {
|
|
|
|
inputComp = <input
|
2017-11-30 01:03:10 +02:00
|
|
|
style={styles.input}
|
2019-06-08 00:33:06 +02:00
|
|
|
ref={this.answerInput_}
|
2017-11-28 00:50:46 +02:00
|
|
|
value={this.state.answer}
|
|
|
|
type="text"
|
|
|
|
onChange={(event) => onChange(event)}
|
|
|
|
onKeyDown={(event) => onKeyDown(event)}
|
|
|
|
/>
|
|
|
|
}
|
|
|
|
|
|
|
|
const buttonComps = [];
|
2017-11-30 01:03:10 +02:00
|
|
|
if (buttonTypes.indexOf('ok') >= 0) buttonComps.push(<button key="ok" style={styles.button} onClick={() => onClose(true, 'ok')}>{_('OK')}</button>);
|
|
|
|
if (buttonTypes.indexOf('cancel') >= 0) buttonComps.push(<button key="cancel" style={styles.button} onClick={() => onClose(false, 'cancel')}>{_('Cancel')}</button>);
|
|
|
|
if (buttonTypes.indexOf('clear') >= 0) buttonComps.push(<button key="clear" style={styles.button} onClick={() => onClose(false, 'clear')}>{_('Clear')}</button>);
|
2017-11-28 00:50:46 +02:00
|
|
|
|
2017-11-08 19:51:55 +02:00
|
|
|
return (
|
2017-11-30 01:03:10 +02:00
|
|
|
<div style={styles.modalLayer}>
|
|
|
|
<div style={styles.promptDialog}>
|
|
|
|
<label style={styles.label}>{this.props.label ? this.props.label : ''}</label>
|
2018-11-08 00:37:13 +02:00
|
|
|
<div style={{display: 'inline-block', color: 'black', backgroundColor: theme.backgroundColor}}>
|
2017-11-28 00:50:46 +02:00
|
|
|
{inputComp}
|
2017-11-12 01:13:14 +02:00
|
|
|
{descComp}
|
|
|
|
</div>
|
2017-11-08 19:51:55 +02:00
|
|
|
<div style={{ textAlign: 'right', marginTop: 10 }}>
|
2017-11-28 00:50:46 +02:00
|
|
|
{buttonComps}
|
2017-11-08 19:51:55 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-11-08 00:37:13 +02:00
|
|
|
module.exports = { PromptDialog };
|