1
0
Fork 0

Added handling of pattern/recipe (restore) defaults

This commit is contained in:
Joost De Cock 2019-10-03 12:32:50 +02:00
parent eb2dcf9568
commit 70d10e5946
14 changed files with 402 additions and 315 deletions

View file

@ -19,14 +19,14 @@ const Bool = props => {
<FormControlLabel <FormControlLabel
control={<Radio color="primary" />} control={<Radio color="primary" />}
value="false" value="false"
checked={value === 'false' || value === false ? true : false} checked={value === 'true' || value === true || value === 1 ? false : true}
label={props.labels[0]} label={props.labels[0]}
className="po-list-item" className="po-list-item"
/> />
<FormControlLabel <FormControlLabel
control={<Radio color="primary" />} control={<Radio color="primary" />}
value="true" value="true"
checked={value === 'true' || value === true ? true : false} checked={value === 'true' || value === true || value === 1 ? true : false}
label={props.labels[1]} label={props.labels[1]}
className="po-list-item" className="po-list-item"
/> />

View file

@ -1,54 +1,59 @@
import React, { useState } from "react"; import React, { useState } from 'react'
import PropTypes from "prop-types"; import PropTypes from 'prop-types'
import FormFieldList from "../../.form/FormFieldList"; import FormFieldList from '../../.form/FormFieldList'
import OptionPreamble from "../OptionPreamble"; import OptionPreamble from '../OptionPreamble'
import { injectIntl } from "react-intl"; import { injectIntl } from 'react-intl'
import { languages } from "@freesewing/i18n"; import { languages } from '@freesewing/i18n'
const DraftSettingLanguage = props => { const DraftSettingLanguage = props => {
const [value, setValue] = useState( const [value, setValue] = useState(props.value === null ? props.intl.locale : props.value)
props.value === null ? props.intl.locale : props.value const [expanded, setExpanded] = useState(false)
);
const [expanded, setExpanded] = useState(false);
const update = (name, newValue, evt) => { const update = (name, newValue, evt) => {
props.updateValue(props.name, newValue); props.updateValue(props.name, newValue)
setValue(newValue); setValue(newValue)
}; }
const reset = () => { const reset = () => {
setValue(props.intl.locale); setValue(props.dflt || props.intl.locale)
props.updateValue(props.name, props.intl.locale); props.updateValue(props.name, props.dflt || props.intl.locale)
}; }
const toggleExpanded = () => setExpanded(!expanded); const patternReset = () => {
setValue(props.intl.locale)
props.updateValue(props.name, props.intl.locale)
}
const toggleExpanded = () => setExpanded(!expanded)
const option = ( const option = (
<FormFieldList <FormFieldList
name={props.name} name={props.name}
value={value} value={value}
dflt={props.intl.locale} dflt={props.dflt}
patternDflt={props.intl.locale}
onChange={update} onChange={update}
label={"po-list-" + props.name} label={'po-list-' + props.name}
updateValue={update} updateValue={update}
list={languages} list={languages}
/> />
); )
return ( return (
<li> <li>
<OptionPreamble <OptionPreamble
dflt={props.intl.locale} dflt={props.dflt}
patternDflt={props.intl.locale}
value={value} value={value}
desc={props.desc} desc={props.desc}
title={props.title} title={props.title}
id={"po-list-" + props.name} id={'po-list-' + props.name}
displayValue={languages[value]} displayValue={languages[value]}
reset={reset} reset={reset}
patternReset={patternReset}
toggleExpanded={toggleExpanded} toggleExpanded={toggleExpanded}
expanded={expanded} expanded={expanded}
showHelp={() => showHelp={() =>
props.raiseEvent("showHelp", { props.raiseEvent('showHelp', {
type: "draftSetting", type: 'draftSetting',
value: props.name value: props.name
}) })
} }
@ -56,8 +61,8 @@ const DraftSettingLanguage = props => {
noDocs={props.noDocs} noDocs={props.noDocs}
/> />
</li> </li>
); )
}; }
DraftSettingLanguage.propTypes = { DraftSettingLanguage.propTypes = {
raiseEvent: PropTypes.func.isRequired, raiseEvent: PropTypes.func.isRequired,
@ -65,6 +70,6 @@ DraftSettingLanguage.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
title: PropTypes.node.isRequired, title: PropTypes.node.isRequired,
desc: PropTypes.node.isRequired desc: PropTypes.node.isRequired
}; }
export default injectIntl(DraftSettingLanguage); export default injectIntl(DraftSettingLanguage)

View file

@ -1,37 +1,40 @@
import React, { useState } from "react"; import React, { useState } from 'react'
import PropTypes from "prop-types"; import PropTypes from 'prop-types'
import FormFieldSlider from "../../.form/FormFieldSlider"; import FormFieldSlider from '../../.form/FormFieldSlider'
import formatMm from "@freesewing/utils/formatMm"; import formatMm from '@freesewing/utils/formatMm'
import roundMm from "@freesewing/utils/roundMm"; import roundMm from '@freesewing/utils/roundMm'
import sliderStep from "@freesewing/utils/sliderStep"; import sliderStep from '@freesewing/utils/sliderStep'
import OptionPreamble from "../OptionPreamble"; import OptionPreamble from '../OptionPreamble'
const DraftSettingMargin = props => { const DraftSettingMargin = props => {
const [value, setValue] = useState( const [value, setValue] = useState(props.value === null ? props.dflt : props.value)
props.value === null ? props.dflt : props.value const [expanded, setExpanded] = useState(false)
);
const [expanded, setExpanded] = useState(false);
const update = (name, newValue, evt) => { const update = (name, newValue, evt) => {
newValue = roundMm(newValue); newValue = roundMm(newValue)
// Sometimes, when sliding, the rapid succession of updates // Sometimes, when sliding, the rapid succession of updates
// causes a weird timing issue to result in a value that is NaN. // causes a weird timing issue to result in a value that is NaN.
// If that's the case, just ignore this update and keep the // If that's the case, just ignore this update and keep the
// previous one instead // previous one instead
if (!isNaN(newValue)) { if (!isNaN(newValue)) {
setValue(newValue); setValue(newValue)
if (evt.type !== "mousemove") props.updateValue("margin", newValue); if (evt.type !== 'mousemove') props.updateValue('margin', newValue)
} else { } else {
props.updateValue("margin", value); props.updateValue('margin', value)
} }
}; }
const reset = () => { const reset = () => {
setValue(props.dflt); setValue(props.dflt)
props.updateValue("margin", props.dflt); props.updateValue('margin', props.dflt)
}; }
const toggleExpanded = () => setExpanded(!expanded); const patternReset = () => {
setValue(props.patternDflt)
props.updateValue('margin', props.patternDflt)
}
const toggleExpanded = () => setExpanded(!expanded)
let option = ( let option = (
<FormFieldSlider <FormFieldSlider
@ -44,12 +47,13 @@ const DraftSettingMargin = props => {
max={25.4} max={25.4}
step={sliderStep[props.units]} step={sliderStep[props.units]}
/> />
); )
return ( return (
<li> <li>
<OptionPreamble <OptionPreamble
dflt={props.dflt} dflt={props.dflt}
patternDflt={props.patternDflt}
value={value} value={value}
desc={props.desc} desc={props.desc}
title={props.title} title={props.title}
@ -57,31 +61,32 @@ const DraftSettingMargin = props => {
displayValue={formatMm(value, props.units)} displayValue={formatMm(value, props.units)}
displayFormat="html" displayFormat="html"
reset={reset} reset={reset}
patternReset={patternReset}
toggleExpanded={toggleExpanded} toggleExpanded={toggleExpanded}
expanded={expanded} expanded={expanded}
showHelp={() => showHelp={() =>
props.raiseEvent("showHelp", { props.raiseEvent('showHelp', {
type: "draftSetting", type: 'draftSetting',
value: "margin" value: 'margin'
}) })
} }
option={option} option={option}
noDocs={props.noDocs} noDocs={props.noDocs}
/> />
</li> </li>
); )
}; }
DraftSettingMargin.propTypes = { DraftSettingMargin.propTypes = {
raiseEvent: PropTypes.func.isRequired, raiseEvent: PropTypes.func.isRequired,
updateValue: PropTypes.func.isRequired, updateValue: PropTypes.func.isRequired,
title: PropTypes.node.isRequired, title: PropTypes.node.isRequired,
desc: PropTypes.node.isRequired, desc: PropTypes.node.isRequired,
units: PropTypes.oneOf(["metric", "imperial"]).isRequired units: PropTypes.oneOf(['metric', 'imperial']).isRequired
}; }
DraftSettingMargin.defaultProps = { DraftSettingMargin.defaultProps = {
// FIXME // FIXME
}; }
export default DraftSettingMargin; export default DraftSettingMargin

View file

@ -1,53 +1,65 @@
import React, { useState } from "react"; import React, { useState } from 'react'
import FormFieldChecks from "../../.form/FormFieldChecks"; import FormFieldChecks from '../../.form/FormFieldChecks'
import FormFieldList from "../../.form/FormFieldList"; import FormFieldList from '../../.form/FormFieldList'
import OptionPreamble from "../OptionPreamble"; import OptionPreamble from '../OptionPreamble'
const DraftSettingOnly = props => { const DraftSettingOnly = props => {
const [value, setValue] = useState( const [value, setValue] = useState(
props.value === null ? "dflt" : props.value === false ? "dflt" : "custom" props.value === null ? 'dflt' : props.value === false ? 'dflt' : 'custom'
); )
const [parts, setParts] = useState( const [parts, setParts] = useState(value === 'custom' ? props.value : props.customDflt)
value === "custom" ? props.value : props.customDflt const [expanded, setExpanded] = useState(false)
);
const [expanded, setExpanded] = useState(false);
const update = (name, newValue, evt) => { const update = (name, newValue, evt) => {
setValue(newValue); setValue(newValue)
if (newValue === "dflt") props.updateValue("only", false); if (newValue === 'dflt') props.updateValue('only', false)
else props.updateValue("only", parts); else props.updateValue('only', parts)
}; }
let onlyDfltToggle = 'dflt'
if (props.dflt === 'custom' || Array.isArray(props.dflt)) onlyDfltToggle = 'custom'
const reset = () => { const reset = () => {
setValue("dflt"); setValue(onlyDfltToggle)
setParts([]); if (onlyDfltToggle === 'dflt') {
props.updateValue("only", false); setParts([])
}; props.updateValue('only', false)
} else {
setParts(props.dflt)
props.updateValue('only', props.dflt)
}
}
const patternReset = () => {
setValue('dflt')
setParts([])
props.updateValue('only', false)
}
const updateCustom = (name, newValue, evt) => { const updateCustom = (name, newValue, evt) => {
props.updateValue("only", newValue); props.updateValue('only', newValue)
setParts(newValue); setParts(newValue)
}; }
const toggleExpanded = () => setExpanded(!expanded); const toggleExpanded = () => setExpanded(!expanded)
const list = { const list = {
dflt: props.labels.dflt, dflt: props.labels.dflt,
custom: props.labels.custom custom: props.labels.custom
}; }
let option = ( let option = (
<FormFieldList <FormFieldList
name="only" name="only"
value={value} value={value}
dflt={props.dflt} dflt={props.dflt}
patternDflt={props.dflt}
onChange={update} onChange={update}
label="po-list-only" label="po-list-only"
updateValue={update} updateValue={update}
list={list} list={list}
/> />
); )
if (value === "custom") if (value === 'custom')
option = ( option = (
<React.Fragment> <React.Fragment>
{option} {option}
@ -62,31 +74,34 @@ const DraftSettingOnly = props => {
list={list} list={list}
/> />
</React.Fragment> </React.Fragment>
); )
return ( return (
<li> <li>
<OptionPreamble <OptionPreamble
dflt="dflt" dflt={onlyDfltToggle}
patternDflt="dflt"
sameButDifferent={props.dflt !== props.value}
value={value} value={value}
desc={props.desc} desc={props.desc}
title={props.title} title={props.title}
id="po-list-only" id="po-list-only"
displayValue={props.labels[value]} displayValue={props.labels[value]}
reset={reset} reset={reset}
patternReset={patternReset}
toggleExpanded={toggleExpanded} toggleExpanded={toggleExpanded}
expanded={expanded} expanded={expanded}
showHelp={() => showHelp={() =>
props.raiseEvent("showHelp", { props.raiseEvent('showHelp', {
type: "draftSetting", type: 'draftSetting',
value: "only" value: 'only'
}) })
} }
option={option} option={option}
noDocs={props.noDocs} noDocs={props.noDocs}
/> />
</li> </li>
); )
}; }
export default DraftSettingOnly; export default DraftSettingOnly

View file

@ -1,89 +1,92 @@
import React, { useState } from "react"; import React, { useState } from 'react'
import PropTypes from "prop-types"; import PropTypes from 'prop-types'
import FormFieldList from "../../.form/FormFieldList"; import FormFieldList from '../../.form/FormFieldList'
import FormFieldSlider from "../../.form/FormFieldSlider"; import FormFieldSlider from '../../.form/FormFieldSlider'
import formatMm from "@freesewing/utils/formatMm"; import formatMm from '@freesewing/utils/formatMm'
import roundMm from "@freesewing/utils/roundMm"; import roundMm from '@freesewing/utils/roundMm'
import defaultSa from "@freesewing/utils/defaultSa"; import defaultSa from '@freesewing/utils/defaultSa'
import sliderStep from "@freesewing/utils/sliderStep"; import sliderStep from '@freesewing/utils/sliderStep'
import OptionPreamble from "../OptionPreamble"; import OptionPreamble from '../OptionPreamble'
const DraftSettingSa = props => { const DraftSettingSa = props => {
const [value, setValue] = useState( const [value, setValue] = useState(
props.value === defaultSa[props.units] props.value === defaultSa[props.units] ? 'dflt' : props.value === 0 ? 'none' : 'custom'
? "dflt" )
: props.value === 0
? "none"
: "custom"
);
const [saValue, setSaValue] = useState( const [saValue, setSaValue] = useState(
props.value === null ? defaultSa[props.units] : props.value props.value === null ? defaultSa[props.units] : props.value
); )
const [customValue, setCustomValue] = useState( const [customValue, setCustomValue] = useState(value === 'custom' ? props.value : 10)
value === "custom" ? props.value : 10 const [expanded, setExpanded] = useState(false)
);
const [expanded, setExpanded] = useState(false);
const update = (name, newValue, evt) => { const update = (name, newValue, evt) => {
switch (newValue) { switch (newValue) {
case "none": case 'none':
props.updateValue("sa", 0); props.updateValue('sa', 0)
setValue(newValue); setValue(newValue)
setSaValue(0); setSaValue(0)
break; break
case "dflt": case 'dflt':
props.updateValue("sa", defaultSa[props.units]); props.updateValue('sa', defaultSa[props.units])
setValue(newValue); setValue(newValue)
setSaValue(defaultSa[props.units]); setSaValue(defaultSa[props.units])
break; break
default: default:
props.updateValue("sa", customValue); props.updateValue('sa', customValue)
setValue(newValue); setValue(newValue)
setSaValue(customValue); setSaValue(customValue)
break; break
} }
}; }
let saDfltToggle = 'dflt'
if (props.dflt === 0) saDfltToggle = 'none'
if (props.dflt !== 10) saDfltToggle = 'custom'
const reset = () => { const reset = () => {
setValue("dflt"); setValue(saDfltToggle)
setSaValue(defaultSa[props.units]); setSaValue(props.dflt)
props.updateValue("sa", defaultSa[props.units]); props.updateValue('sa', props.dflt)
}; }
const toggleExpanded = () => setExpanded(!expanded); const patternReset = () => {
setValue('dflt')
setSaValue(defaultSa[props.units])
props.updateValue('sa', defaultSa[props.units])
}
const toggleExpanded = () => setExpanded(!expanded)
const updateCustom = (name, newValue, evt) => { const updateCustom = (name, newValue, evt) => {
newValue = roundMm(newValue); newValue = roundMm(newValue)
// Sometimes, when sliding, the rapid succession of updates // Sometimes, when sliding, the rapid succession of updates
// causes a weird timing issue to result in a value that is NaN. // causes a weird timing issue to result in a value that is NaN.
// If that's the case, just ignore this update and keep the // If that's the case, just ignore this update and keep the
// previous one instead // previous one instead
if (!isNaN(newValue)) { if (!isNaN(newValue)) {
setSaValue(newValue); setSaValue(newValue)
setCustomValue(newValue); setCustomValue(newValue)
if (evt.type !== "mousemove") props.updateValue("sa", newValue); if (evt.type !== 'mousemove') props.updateValue('sa', newValue)
} else { } else {
props.updateValue("sa", customValue); props.updateValue('sa', customValue)
} }
}; }
const list = { const list = {
none: props.labels.none, none: props.labels.none,
dflt: props.labels.dflt, dflt: props.labels.dflt,
custom: props.labels.custom custom: props.labels.custom
}; }
let option = ( let option = (
<FormFieldList <FormFieldList
name="sa" name="sa"
value={value} value={value}
dflt={"dflt"} dflt={'dflt'}
onChange={update} onChange={update}
label="po-bool-sa" label="po-bool-sa"
updateValue={update} updateValue={update}
list={list} list={list}
/> />
); )
if (value === "custom") if (value === 'custom')
option = ( option = (
<React.Fragment> <React.Fragment>
{option} {option}
@ -98,12 +101,13 @@ const DraftSettingSa = props => {
step={sliderStep[props.units]} step={sliderStep[props.units]}
/> />
</React.Fragment> </React.Fragment>
); )
return ( return (
<li> <li>
<OptionPreamble <OptionPreamble
dflt={"dflt"} dflt={saDfltToggle}
patternDflt={'dflt'}
sameButDifferent={props.dflt !== props.value}
value={value} value={value}
desc={props.desc} desc={props.desc}
title={props.title} title={props.title}
@ -111,31 +115,32 @@ const DraftSettingSa = props => {
displayValue={formatMm(saValue, props.units)} displayValue={formatMm(saValue, props.units)}
displayFormat="html" displayFormat="html"
reset={reset} reset={reset}
patternReset={patternReset}
toggleExpanded={toggleExpanded} toggleExpanded={toggleExpanded}
expanded={expanded} expanded={expanded}
showHelp={() => showHelp={() =>
props.raiseEvent("showHelp", { props.raiseEvent('showHelp', {
type: "draftSetting", type: 'draftSetting',
value: "sa" value: 'sa'
}) })
} }
option={option} option={option}
noDocs={props.noDocs} noDocs={props.noDocs}
/> />
</li> </li>
); )
}; }
DraftSettingSa.propTypes = { DraftSettingSa.propTypes = {
updateValue: PropTypes.func.isRequired, updateValue: PropTypes.func.isRequired,
title: PropTypes.node.isRequired, title: PropTypes.node.isRequired,
desc: PropTypes.node.isRequired, desc: PropTypes.node.isRequired,
units: PropTypes.oneOf(["metric", "imperial"]).isRequired, units: PropTypes.oneOf(['metric', 'imperial']).isRequired,
labels: PropTypes.object labels: PropTypes.object
}; }
DraftSettingSa.defaultProps = { DraftSettingSa.defaultProps = {
// FIXME // FIXME
}; }
export default DraftSettingSa; export default DraftSettingSa

View file

@ -1,22 +1,27 @@
import React, { useState } from "react"; import React, { useState } from 'react'
import FormFieldList from "../../.form/FormFieldList"; import FormFieldList from '../../.form/FormFieldList'
import OptionPreamble from "../OptionPreamble"; import OptionPreamble from '../OptionPreamble'
const DraftSettingUnits = props => { const DraftSettingUnits = props => {
const [value, setValue] = useState(props.dflt); const [value, setValue] = useState(props.dflt)
const [expanded, setExpanded] = useState(false); const [expanded, setExpanded] = useState(false)
const update = (name, newValue, evt) => { const update = (name, newValue, evt) => {
props.updateValue(props.name, newValue); props.updateValue(props.name, newValue)
setValue(newValue); setValue(newValue)
}; }
const reset = () => { const reset = () => {
setValue(props.dflt); setValue(props.dflt)
props.updateValue(props.name, props.dflt); props.updateValue(props.name, props.dflt)
}; }
const toggleExpanded = () => setExpanded(!expanded); const patternReset = () => {
setValue(props.patternDflt)
props.updateValue(props.name, props.patternDflt)
}
const toggleExpanded = () => setExpanded(!expanded)
let option = ( let option = (
<FormFieldList <FormFieldList
@ -28,31 +33,33 @@ const DraftSettingUnits = props => {
updateValue={update} updateValue={update}
list={props.list} list={props.list}
/> />
); )
return ( return (
<li> <li>
<OptionPreamble <OptionPreamble
dflt={props.dflt} dflt={props.dflt}
patternDflt={props.patternDflt}
value={value} value={value}
desc={props.desc} desc={props.desc}
title={props.title} title={props.title}
id="po-list-units" id="po-list-units"
displayValue={props.list[value]} displayValue={props.list[value]}
reset={reset} reset={reset}
patternReset={patternReset}
toggleExpanded={toggleExpanded} toggleExpanded={toggleExpanded}
expanded={expanded} expanded={expanded}
showHelp={() => showHelp={() =>
props.raiseEvent("showHelp", { props.raiseEvent('showHelp', {
type: "draftSetting", type: 'draftSetting',
value: "units" value: 'units'
}) })
} }
option={option} option={option}
noDocs={props.noDocs} noDocs={props.noDocs}
/> />
</li> </li>
); )
}; }
export default DraftSettingUnits; export default DraftSettingUnits

View file

@ -20,9 +20,8 @@ const DraftSettings = props => {
else shown.splice(index, 1) else shown.splice(index, 1)
setExpanded(shown) setExpanded(shown)
} }
const getDefault = setting => { const getDefault = (setting, recipe = false) => {
if (props.recipe && typeof props.recipe.settings[setting] !== 'undefined') if (recipe && typeof recipe.settings[setting] !== 'undefined') return recipe.settings[setting]
return props.recipe.settings[setting]
switch (setting) { switch (setting) {
case 'sa': case 'sa':
return 10 return 10
@ -68,7 +67,8 @@ const DraftSettings = props => {
name: setting, name: setting,
labels: labels[setting], labels: labels[setting],
noDocs: props.noDocs, noDocs: props.noDocs,
dflt: getDefault(setting) dflt: getDefault(setting, props.recipe),
patternDflt: getDefault(setting)
} }
childProps.title = <FormattedMessage id={'settings.' + setting + '.title'} /> childProps.title = <FormattedMessage id={'settings.' + setting + '.title'} />
childProps.desc = <FormattedMessage id={'settings.' + setting + '.description'} /> childProps.desc = <FormattedMessage id={'settings.' + setting + '.description'} />

View file

@ -20,6 +20,7 @@ const OptionGroup = props => {
let extraProps = { let extraProps = {
name, name,
dflt: optionDefault(name, props.config.options[name], props.recipe), dflt: optionDefault(name, props.config.options[name], props.recipe),
patternDflt: optionDefault(name, props.config.options[name]),
units: props.units, units: props.units,
updateValue: props.updateValue, updateValue: props.updateValue,
raiseEvent: props.raiseEvent, raiseEvent: props.raiseEvent,

View file

@ -1,74 +1,90 @@
import React from "react"; import React from 'react'
import PropTypes from "prop-types"; import PropTypes from 'prop-types'
import IconButton from "@material-ui/core/IconButton"; import IconButton from '@material-ui/core/IconButton'
import RightIcon from "@material-ui/icons/KeyboardArrowRight"; import RightIcon from '@material-ui/icons/KeyboardArrowRight'
import ResetIcon from "@material-ui/icons/SettingsBackupRestore"; import ResetIcon from '@material-ui/icons/SettingsBackupRestore'
import HelpIcon from "@material-ui/icons/Help"; import HelpIcon from '@material-ui/icons/Help'
import { injectIntl } from "react-intl"; import { injectIntl } from 'react-intl'
const OptionPreamble = props => { const OptionPreamble = props => {
const styles = { const styles = {
container: { container: {
display: "flex", display: 'flex',
flexDirection: "row", flexDirection: 'row',
alignItems: "center" alignItems: 'center'
}, },
left: { left: {
flexGrow: 1, flexGrow: 1,
margin: "0 0.5rem" margin: '0 0.5rem'
}, },
right: { right: {
margin: "0 5px 0 0 ", margin: '0 5px 0 0 ',
textAlign: "right" textAlign: 'right'
} }
}; }
const resetLabel = props.intl.formatMessage({ const resetLabel = props.intl.formatMessage({
id: "app.restoreDefaults", id: 'app.restoreDefaults',
defaultMessage: " ♻️ " defaultMessage: ' ♻️ '
}); })
const resetPatternLabel = props.intl.formatMessage({
id: 'app.restorePatternDefaults',
defaultMessage: ' ♻️ '
})
const resetRecipeLabel = props.intl.formatMessage({
id: 'app.restoreRecipeDefaults',
defaultMessage: ' ♻️ '
})
const docsLabel = props.intl.formatMessage({ const docsLabel = props.intl.formatMessage({
id: "app.docs", id: 'app.docs',
defaultMessage: " 🤔 " defaultMessage: ' 🤔 '
}); })
let displayClass = props.value === props.dflt ? "dflt" : "custom"; let recipe = false
let displayValue = <span className={displayClass}>{props.displayValue}</span>; if (props.dflt !== props.patternDflt) recipe = true
if (props.displayFormat === "html") let displayClass = props.value === props.dflt ? 'dflt' : 'custom'
if (recipe && props.value === props.patternDflt) displayClass = 'p-dflt'
else if (recipe && props.sameButDifferent) displayClass = 'custom'
let displayValue = <span className={displayClass}>{props.displayValue}</span>
if (props.displayFormat === 'html')
displayValue = ( displayValue = (
<span <span className={displayClass} dangerouslySetInnerHTML={{ __html: props.displayValue }} />
className={displayClass} )
dangerouslySetInnerHTML={{ __html: props.displayValue }}
/>
);
return ( return (
<React.Fragment> <React.Fragment>
<div onClick={props.toggleExpanded} style={styles.container}> <div onClick={props.toggleExpanded} style={styles.container}>
<div style={styles.left}> <div style={styles.left}>
<RightIcon <RightIcon className={'icon-col-exp ' + (props.expanded ? 'expanded' : 'collapsed')} />
className={
"icon-col-exp " + (props.expanded ? "expanded" : "collapsed")
}
/>
{props.title} {props.title}
</div> </div>
<div style={styles.right}>{displayValue}</div> <div style={styles.right}>{displayValue}</div>
</div> </div>
<div <div className={props.expanded ? 'col-exp expanded' : 'col-exp collapsed'}>
className={props.expanded ? "col-exp expanded" : "col-exp collapsed"}
>
<div style={styles.container}> <div style={styles.container}>
<div style={styles.left}> <div style={styles.left}>
<p>{props.desc}</p> <p>{props.desc}</p>
</div> </div>
<div style={styles.right}> <div style={styles.right}>
{recipe ? (
<IconButton
title={resetPatternLabel}
aria-label={resetPatternLabel}
color="primary"
disabled={props.value === props.patternDflt ? true : false}
onClick={props.patternReset}
className="mini-icon-btn pattern"
>
<ResetIcon />
</IconButton>
) : null}
<IconButton <IconButton
title={resetLabel} title={recipe ? resetRecipeLabel : resetLabel}
aria-label={resetLabel} aria-label={recipe ? resetRecipeLabel : resetLabel}
color="primary" color="primary"
disabled={props.value === props.dflt ? true : false} disabled={props.value === props.dflt && !props.sameButDifferent ? true : false}
onClick={props.reset} onClick={props.reset}
className="mini-icon-btn" className={'mini-icon-btn' + (recipe ? ' recipe' : '')}
> >
<ResetIcon /> <ResetIcon />
</IconButton> </IconButton>
@ -88,8 +104,8 @@ const OptionPreamble = props => {
{props.option} {props.option}
</div> </div>
</React.Fragment> </React.Fragment>
); )
}; }
OptionPreamble.propTypes = { OptionPreamble.propTypes = {
dflt: PropTypes.oneOfType([ dflt: PropTypes.oneOfType([
@ -108,10 +124,10 @@ OptionPreamble.propTypes = {
showHelp: PropTypes.func.isRequired, showHelp: PropTypes.func.isRequired,
expanded: PropTypes.bool, expanded: PropTypes.bool,
displayFormat: PropTypes.string displayFormat: PropTypes.string
}; }
OptionPreamble.defaultProps = { OptionPreamble.defaultProps = {
displayFormat: "node" displayFormat: 'node'
}; }
export default injectIntl(OptionPreamble); export default injectIntl(OptionPreamble)

View file

@ -1,25 +1,28 @@
import React, { useState } from "react"; import React, { useState } from 'react'
import PropTypes from "prop-types"; import PropTypes from 'prop-types'
import FormFieldBool from "../../.form/FormFieldBool"; import FormFieldBool from '../../.form/FormFieldBool'
import OptionPreamble from "../OptionPreamble"; import OptionPreamble from '../OptionPreamble'
const PatternOptionBool = props => { const PatternOptionBool = props => {
const [value, setValue] = useState( const [value, setValue] = useState(props.value === null ? props.dflt : props.value)
props.value === null ? props.dflt : props.value const [expanded, setExpanded] = useState(false)
);
const [expanded, setExpanded] = useState(false);
const update = (name, newValue, evt) => { const update = (name, newValue, evt) => {
props.updateValue(props.name, newValue); props.updateValue(props.name, newValue)
setValue(newValue); setValue(newValue)
}; }
const reset = () => { const reset = () => {
setValue(props.dflt); setValue(props.dflt)
props.updateValue(props.name, props.dflt); props.updateValue(props.name, props.dflt)
}; }
const toggleExpanded = () => setExpanded(!expanded); const patternReset = () => {
setValue(props.patternDflt)
props.updateValue(props.name, props.patternDflt)
}
const toggleExpanded = () => setExpanded(!expanded)
let option = ( let option = (
<FormFieldBool <FormFieldBool
@ -27,26 +30,28 @@ const PatternOptionBool = props => {
value={value} value={value}
dflt={props.dflt} dflt={props.dflt}
onChange={update} onChange={update}
label={"po-bool-" + props.name} label={'po-bool-' + props.name}
updateValue={update} updateValue={update}
labels={props.labels} labels={props.labels}
/> />
); )
return ( return (
<li> <li>
<OptionPreamble <OptionPreamble
dflt={props.dflt} dflt={props.dflt}
patternDflt={props.patternDflt}
value={value} value={value}
desc={props.desc} desc={props.desc}
title={props.title} title={props.title}
id={"po-list-" + props.name} id={'po-list-' + props.name}
displayValue={value ? props.labels[1] : props.labels[0]} displayValue={value ? props.labels[1] : props.labels[0]}
toggleExpanded={toggleExpanded} toggleExpanded={toggleExpanded}
expanded={expanded} expanded={expanded}
reset={reset} reset={reset}
patternReset={patternReset}
showHelp={() => showHelp={() =>
props.raiseEvent("showHelp", { props.raiseEvent('showHelp', {
type: "draftSetting", type: 'draftSetting',
value: props.name value: props.name
}) })
} }
@ -54,8 +59,8 @@ const PatternOptionBool = props => {
noDocs={props.noDocs} noDocs={props.noDocs}
/> />
</li> </li>
); )
}; }
PatternOptionBool.propTypes = { PatternOptionBool.propTypes = {
raiseEvent: PropTypes.func.isRequired, raiseEvent: PropTypes.func.isRequired,
@ -69,6 +74,6 @@ PatternOptionBool.propTypes = {
title: PropTypes.node.isRequired, title: PropTypes.node.isRequired,
desc: PropTypes.node.isRequired, desc: PropTypes.node.isRequired,
labels: PropTypes.array.isRequired labels: PropTypes.array.isRequired
}; }
export default PatternOptionBool; export default PatternOptionBool

View file

@ -1,43 +1,49 @@
import React, { useState } from "react"; import React, { useState } from 'react'
import PropTypes from "prop-types"; import PropTypes from 'prop-types'
import FormFieldList from "../../.form/FormFieldList"; import FormFieldList from '../../.form/FormFieldList'
import OptionPreamble from "../OptionPreamble"; import OptionPreamble from '../OptionPreamble'
const PatternOptionList = props => { const PatternOptionList = props => {
const [value, setValue] = useState(props.dflt); const [value, setValue] = useState(props.dflt)
const [expanded, setExpanded] = useState(false); const [expanded, setExpanded] = useState(false)
const update = (name, newValue, evt) => { const update = (name, newValue, evt) => {
props.updateValue(props.name, newValue); props.updateValue(props.name, newValue)
setValue(newValue); setValue(newValue)
}; }
const reset = () => { const reset = () => {
setValue(props.dflt); setValue(props.dflt)
props.updateValue(props.name, props.dflt); props.updateValue(props.name, props.dflt)
}; }
const toggleExpanded = () => setExpanded(!expanded); const patternReset = () => {
setValue(props.patternDflt)
props.updateValue(props.name, props.patternDflt)
}
const toggleExpanded = () => setExpanded(!expanded)
// Add translations // Add translations
let stringKey = `options.${props.pattern}.${props.name}.options.`; let stringKey = `options.${props.pattern}.${props.name}.options.`
let list = {}; let list = {}
for (let item of props.list) for (let item of props.list)
list[item] = props.intl.formatMessage({ list[item] = props.intl.formatMessage({
id: stringKey + item, id: stringKey + item,
defaultMessage: item defaultMessage: item
}); })
let option = ( let option = (
<FormFieldList <FormFieldList
name={props.name} name={props.name}
value={value} value={value}
dflt={props.dflt} dflt={props.dflt}
patternDflt={props.patternDflt}
onChange={update} onChange={update}
label={"po-list-" + props.name} label={'po-list-' + props.name}
updateValue={update} updateValue={update}
list={list} list={list}
/> />
); )
return ( return (
<li> <li>
<OptionPreamble <OptionPreamble
@ -45,14 +51,15 @@ const PatternOptionList = props => {
value={value} value={value}
desc={props.desc} desc={props.desc}
title={props.title} title={props.title}
id={"po-list-" + props.name} id={'po-list-' + props.name}
displayValue={list[value]} displayValue={list[value]}
reset={reset} reset={reset}
patternReset={patternReset}
toggleExpanded={toggleExpanded} toggleExpanded={toggleExpanded}
expanded={expanded} expanded={expanded}
showHelp={() => showHelp={() =>
props.raiseEvent("showHelp", { props.raiseEvent('showHelp', {
type: "patternOption", type: 'patternOption',
value: props.name value: props.name
}) })
} }
@ -60,19 +67,16 @@ const PatternOptionList = props => {
noDocs={props.noDocs} noDocs={props.noDocs}
/> />
</li> </li>
); )
}; }
PatternOptionList.propTypes = { PatternOptionList.propTypes = {
updateValue: PropTypes.func.isRequired, updateValue: PropTypes.func.isRequired,
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
dflt: PropTypes.oneOfType([ dflt: PropTypes.oneOfType([PropTypes.number.isRequired, PropTypes.string.isRequired]),
PropTypes.number.isRequired,
PropTypes.string.isRequired
]),
title: PropTypes.node.isRequired, title: PropTypes.node.isRequired,
desc: PropTypes.node.isRequired, desc: PropTypes.node.isRequired,
list: PropTypes.array.isRequired list: PropTypes.array.isRequired
}; }
export default PatternOptionList; export default PatternOptionList

View file

@ -1,46 +1,49 @@
import React, { useState } from "react"; import React, { useState } from 'react'
import PropTypes from "prop-types"; import PropTypes from 'prop-types'
import FormFieldSlider from "../../.form/FormFieldSlider"; import FormFieldSlider from '../../.form/FormFieldSlider'
import OptionPreamble from "../OptionPreamble"; import OptionPreamble from '../OptionPreamble'
const PatternOptionPctDegCount = props => { const PatternOptionPctDegCount = props => {
let factor = 1; let factor = 1
if (props.type === "pct") factor = 100; if (props.type === 'pct') factor = 100
const round = val => Math.round(val * 10) / 10; const round = val => Math.round(val * 10) / 10
const [value, setValue] = useState( const [value, setValue] = useState(
props.value === null ? props.dflt : round(props.value * factor) props.value === null ? props.dflt : round(props.value * factor)
); )
const [previousValue, setPreviousValue] = useState( const [previousValue, setPreviousValue] = useState(
props.value === null ? props.dflt : round(props.value * factor) props.value === null ? props.dflt : round(props.value * factor)
); )
const [expanded, setExpanded] = useState(false); const [expanded, setExpanded] = useState(false)
const update = (name, newValue, evt) => { const update = (name, newValue, evt) => {
newValue = round(newValue); newValue = round(newValue)
// Sometimes, when sliding, the rapid succession of updates // Sometimes, when sliding, the rapid succession of updates
// causes a weird timing issue to result in a value that is NaN. // causes a weird timing issue to result in a value that is NaN.
// If that's the case, just ignore this update and keep the // If that's the case, just ignore this update and keep the
// previous one instead // previous one instead
if (!isNaN(newValue)) { if (!isNaN(newValue)) {
setValue(newValue); setValue(newValue)
if (evt.type !== "mousemove") if (evt.type !== 'mousemove') props.updateValue(props.name, newValue / factor)
props.updateValue(props.name, newValue / factor);
} else { } else {
if (evt.type !== "mousemove") if (evt.type !== 'mousemove') props.updateValue(props.name, value / factor)
props.updateValue(props.name, value / factor);
} }
}; }
const reset = () => { const reset = () => {
setValue(props.dflt); setValue(props.dflt)
props.updateValue(props.name, props.dflt / factor); props.updateValue(props.name, props.dflt / factor)
}; }
const toggleExpanded = () => setExpanded(!expanded); const patternReset = () => {
setValue(props.patternDflt)
props.updateValue(props.name, props.patternDflt / factor)
}
let unit = ""; const toggleExpanded = () => setExpanded(!expanded)
if (props.type === "pct") unit = "%";
if (props.type === "deg") unit = "°"; let unit = ''
if (props.type === 'pct') unit = '%'
if (props.type === 'deg') unit = '°'
let option = ( let option = (
<FormFieldSlider <FormFieldSlider
@ -48,28 +51,30 @@ const PatternOptionPctDegCount = props => {
value={value} value={value}
min={props.min} min={props.min}
max={props.max} max={props.max}
step={props.type === "count" ? 1 : props.step} step={props.type === 'count' ? 1 : props.step}
onChange={update} onChange={update}
label={"po-" + props.type + "-" + props.name} label={'po-' + props.type + '-' + props.name}
updateValue={update} updateValue={update}
/> />
); )
return ( return (
<li> <li>
<OptionPreamble <OptionPreamble
dflt={props.dflt} dflt={props.dflt}
patternDflt={props.patternDflt}
value={value} value={value}
desc={props.desc} desc={props.desc}
title={props.title} title={props.title}
id={"po-" + props.type + "-" + props.name} id={'po-' + props.type + '-' + props.name}
displayValue={value + unit} displayValue={value + unit}
reset={reset} reset={reset}
patternReset={patternReset}
toggleExpanded={toggleExpanded} toggleExpanded={toggleExpanded}
expanded={expanded} expanded={expanded}
showHelp={() => showHelp={() =>
props.raiseEvent("showHelp", { props.raiseEvent('showHelp', {
type: "patternOption", type: 'patternOption',
value: props.name value: props.name
}) })
} }
@ -77,8 +82,8 @@ const PatternOptionPctDegCount = props => {
noDocs={props.noDocs} noDocs={props.noDocs}
/> />
</li> </li>
); )
}; }
PatternOptionPctDegCount.propTypes = { PatternOptionPctDegCount.propTypes = {
min: PropTypes.number, min: PropTypes.number,
@ -89,14 +94,14 @@ PatternOptionPctDegCount.propTypes = {
dflt: PropTypes.number.isRequired, dflt: PropTypes.number.isRequired,
title: PropTypes.node.isRequired, title: PropTypes.node.isRequired,
desc: PropTypes.node.isRequired, desc: PropTypes.node.isRequired,
type: PropTypes.oneOf(["pct", "deg", "count"]) type: PropTypes.oneOf(['pct', 'deg', 'count'])
}; }
PatternOptionPctDegCount.defaultProps = { PatternOptionPctDegCount.defaultProps = {
min: 0, min: 0,
max: 100, max: 100,
step: 0.1, step: 0.1,
type: "pct" type: 'pct'
}; }
export default PatternOptionPctDegCount; export default PatternOptionPctDegCount

View file

@ -6,7 +6,6 @@ import DraftSettings from './DraftSettings'
const DraftConfigurator = props => { const DraftConfigurator = props => {
const [expanded, setExpanded] = useState([]) const [expanded, setExpanded] = useState([])
return ( return (
<ul className="config l1"> <ul className="config l1">
<li> <li>

View file

@ -76,6 +76,7 @@ ul.config.l4 > li > div { padding-left: 2.5rem; }
span.dflt, span.dflt,
span.p-dflt,
span.custom { span.custom {
padding: 2px 4px; padding: 2px 4px;
border-radius: 4px; border-radius: 4px;
@ -86,6 +87,12 @@ span.custom {
.theme-wrapper.dark span.custom { .theme-wrapper.dark span.custom {
color: $oc-yellow-8; color: $oc-yellow-8;
} }
.theme-wrapper.light span.p-dflt {
background: $oc-green-2;
}
.theme-wrapper.dark span.p-dflt {
color: $oc-green-6;
}
.theme-wrapper.light div.col-exp.expanded { .theme-wrapper.light div.col-exp.expanded {
border-left: 4px solid $fc-text-light; border-left: 4px solid $fc-text-light;
} }
@ -107,3 +114,16 @@ button.mini-icon-btn {
margin: 0; margin: 0;
padding: 2px; padding: 2px;
} }
.theme-wrapper.light button.mini-icon-btn.recipe:enabled {
color: $oc-blue-7;
}
.theme-wrapper.light button.mini-icon-btn.pattern:enabled {
color: $oc-green-8;
}
.theme-wrapper.dark button.mini-icon-btn.recipe:enabled {
color: $oc-blue-5;
}
.theme-wrapper.dark button.mini-icon-btn.pattern:enabled {
color: $oc-green-6;
}