\n
\n {\n Array.apply(null, new Array(4)).map((v, i) => {\n let fraction = valueList[i];\n\n return
\n {\n Array.apply(null, new Array(10)).map((v, j) => {\n const top = height - (tickOverallHeight * j) - tickHeight;\n const bottom = tickOverallHeight * j + tickGap / 2;\n\n return
\n }\n )\n }\n {\n Array.apply(null, new Array(10)).map((v, j) => {\n const x = fraction <= 0 ? 0 : fraction >= 10 ? 1 : fraction / 10;\n const top = height - (tickOverallHeight * j) - (tickHeight * x);\n const bottom = tickOverallHeight * j + tickGap / 2;\n\n if (valueList[i] <= 100) {\n fraction -= 10;\n }\n\n return
100\n ? '#d31822'\n : '#6ED59F'\n }}\n />\n }\n )\n }\n
\n }\n )\n }\n
\n
\n }\n}\n\nexport default GraphicBar;\n","import React, {Component} from 'react';\nimport {connect} from 'react-redux';\nimport {updateProps} from '../store/actions/currentadvice';\nimport * as selectors from '../store/selectors';\nimport * as constants from '../store/constants';\nimport {showHelp} from '../store/actions/app';\nimport InputRange from '../components/inputrange';\nimport GraphicBar from '../components/graphicbar';\nimport { METRIC } from '../store/constants';\n\nfunction calcDensityValue(units, densityLimits, value) {\n if (units === METRIC) {\n if (value >= (densityLimits.min * 1000) && value <= densityLimits.max * 1000) {\n return value / 1000;\n }\n return value;\n }\n return value;\n}\n\nfunction isValidProductProps(sum, densityLimits, targetDensityValue) {\n return (sum === 0 || sum === 100) &&\n (\n targetDensityValue === 0 ||\n (targetDensityValue >= densityLimits.min && targetDensityValue <= densityLimits.max)\n );\n}\n\nclass ProductProps extends Component {\n\n state = {sum: 0, errorSum: false};\n\n componentWillReceiveProps(props) {\n this.calcSum(props.properties);\n }\n\n shouldComponentUpdate(nextProps, nextState) {\n const {isValid, properties, densityLimits, units} = nextProps;\n const {sum} = nextState;\n const targetDensityValue = calcDensityValue(units, densityLimits, properties.adviceDensity);\n\n if(isValid !== isValidProductProps(sum, densityLimits, targetDensityValue)) {\n this.props.updateProps(\n null,\n null,\n isValidProductProps(sum, densityLimits, targetDensityValue)\n );\n }\n\n return true;\n }\n\n componentDidMount() {\n this.calcSum(this.props.properties);\n }\n\n calcSum(props) {\n let sum = 0;\n ['granuleSizeMinus2', 'granuleSizeB23',\n 'granuleSizeB34', 'granuleSize4']\n .forEach((i)=> sum+=Number(props[i]));\n let sumError = true;\n let statusSum = 'error';\n if(sum===0 || sum===100) {\n sumError = false;\n statusSum = '';\n }\n statusSum = (sum===100) ? 'success' : statusSum;\n this.setState({sumError, sum, statusSum});\n }\n\n handleChange(f,v) {\n const { properties, densityLimits, units } = this.props;\n const { sum } = this.state;\n const targetDensityValue = calcDensityValue(\n units,\n densityLimits,\n (f === 'adviceDensity') ? v : properties.adviceDensity);\n\n this.props.updateProps(f, v, isValidProductProps(sum, densityLimits, targetDensityValue));\n }\n\n render() {\n const {\n densityLimits,\n properties,\n t,\n showHelp,\n toggleHideAdviceBar,\n icons\n } = this.props;\n const {sum, statusSum} = this.state;\n\n return
\n
\n
\n
\n
this.handleChange('adviceDensity', v)}\n modifyBeforeUpdate={(value) => {\n const { densityLimits, units } = this.props;\n return calcDensityValue(units, densityLimits, value);\n }}\n toggleHideAdviceBar={toggleHideAdviceBar}\n />\n \n {t('page_title_density_and_fractioning_density_value_question')}\n
\n \n
\n
\n
\n
\n {t('page_title_density_and_fractioning_label_distribution')}\n
\n
\n {\n sum === 100\n ? `${100}%`\n : sum <= 100\n ? `${100 - sum}% ${t('page_title_density_and_fractioning_sum_left')}`\n : `${sum}% ${t('page_title_density_and_fractioning_sum_extra')}`\n }\n
\n
\n
\n
\n \n
\n
100 ? \"sum-error\" : \"\"}`}\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginTop: -5,\n marginBottom: 40\n }}\n >\n
\n this.handleChange('granuleSizeMinus2', v)}\n toggleHideAdviceBar={toggleHideAdviceBar}\n />\n
\n
\n this.handleChange('granuleSizeB23', v)}\n toggleHideAdviceBar={toggleHideAdviceBar}\n />\n
\n
\n this.handleChange('granuleSizeB34', v)}\n toggleHideAdviceBar={toggleHideAdviceBar}\n />\n
\n
\n 4.75 mm'}\n maxLength={4}\n min={0}\n max={100}\n canBeZero={true}\n help={'%'}\n errorMsg={''}\n defaultValue={properties.granuleSize4}\n onChange={(v)=> this.handleChange('granuleSize4', v)}\n toggleHideAdviceBar={toggleHideAdviceBar}\n />\n
\n
\n
\n
\n
;\n }\n}\n\nconst mapStateToProps = (state) => {\n return {\n properties: selectors.getCurrentProperties(state),\n densityLimits: selectors.getDensityLimits(state),\n t: selectors.getTranslations(state),\n units: selectors.getCurrentUnits(state),\n icons: selectors.getIcons(state),\n isValid: selectors.getCurrentIsValid(state),\n };\n};\n\nconst actions = {\n updateProps,\n showHelp,\n};\n\nProductProps = connect(mapStateToProps, actions)(ProductProps);\n\nexport default ProductProps;\n","import React, {Component} from 'react';\nimport {connect} from 'react-redux';\n\nimport FertilizerProps from './fertilizerprops';\nimport ProductProps from './productprops';\nimport Advicebar from '../components/advicebar';\nimport { validFertilizerProps } from '../store/actions/currentadvice';\nimport * as selectors from '../store/selectors';\nimport {showModal} from '../store/actions/app';\n\nclass ProductDetails extends Component {\n state = {\n stage: 1,\n multipleShapesMsgShown: false\n };\n\n onSubmit() {\n let {match, history, UsesFractioning} = this.props;\n const { stage, multipleShapesMsgShown} = this.state;\n if(stage === 1 && this.hasMultipleShapes() && !multipleShapesMsgShown) {\n this.props.showModal({\n title: \"attention-shapes-title\",\n text: \"attention-shapes-message\"\n }); \n this.setState((curState) => {\n return {\n ...curState,\n multipleShapesMsgShown: true\n }\n })\n }\n \n if(stage === 1 && UsesFractioning) {\n this.setState((curState) => {\n return {\n ...curState,\n stage: 2, \n multipleShapesMsgShown: false\n }\n })\n } else {\n this.props.validFertilizerProps();\n history.push(`/${match.params.brand}/advice/4/`);\n }\n }\n\n hasMultipleShapes() {\n const {shapeId} = this.props; \n return (shapeId && shapeId.length > 1);\n }\n\n isValid() {\n const {isValid, shapeId} = this.props;\n\n if(this.state.stage === 1) {\n return (shapeId && shapeId.length > 0);\n }\n return isValid;\n }\n\n onBack() {\n this.setState((curState) => {\n return {\n ...curState,\n stage: 1\n }\n });\n }\n\n render() {\n const { stage } = this.state;\n const { t, toggleHideAdviceBar, adviceBarHidden } = this.props;\n\n return
\n }\n}\n\nconst mapStateToProps = (state) => {\n const machineId = selectors.getCurrentMachineId(state);\n const machines = selectors.getMachines(state);\n\n return {\n shapeId: selectors.getCurrentShapeId(state),\n t: selectors.getTranslations(state),\n isValid: selectors.getCurrentIsValid(state),\n UsesFractioning: machines[machineId].UsesFractioning,\n };\n};\n\nconst actions = {\n validFertilizerProps,\n showModal,\n};\n\nProductDetails = connect(mapStateToProps, actions)(ProductDetails);\n\nexport default ProductDetails;\n","import React, { Component } from 'react';\r\nimport icons from './img/icons';\r\n\r\nimport './scss/combobox.scss';\r\n\r\nexport class ComboBox extends Component\r\n{\r\n state = {\r\n collapsed: true\r\n }\r\n\r\n render() {\r\n let {options, value, onChange} = this.props;\r\n\r\n return
\r\n
this.setState({collapsed: false})}>\r\n

\r\n
\r\n
{ value.Label }\r\n

\r\n
\r\n
\r\n\r\n { (!this.state.collapsed) &&\r\n
\r\n
this.setState({collapsed: true})}>
\r\n
\r\n {\r\n options.map(o => \r\n
\r\n {\r\n onChange(o);\r\n this.setState({collapsed: true})\r\n }}>{o.Label}
\r\n )\r\n }\r\n
\r\n
\r\n }\r\n
\r\n }\r\n}","import React, { Component } from 'react';\n\nimport {ComboBox} from './combobox';\n\nimport './scss/tableapplications.scss';\n\n\nclass TableApplications extends Component {\n state = {\n orderBy: null\n }\n\n /*\n * Returns an average number from the fractioning/distribution. The number will reach from 0(small granules) to 300(big granules).\n * Returns -1 if the fractioning wasn't properly formatted.\n */\n getAverageFractioningNumber(fractioning)\n {\n var splitted = fractioning.split(\"-\").map(Number);\n\n if(splitted.length < 4)\n return -1;\n\n\n return splitted[1] + splitted[2] * 2 + splitted[3] * 3;\n }\n\n getOptions(t, usesFractioning, isFiltered) {\n if(usesFractioning && isFiltered)\n {\n return [{Key: \"BestMatch\", Label: t(\"fertiliser_list_match_label\")}, \n {Key: \"Shape\", Label: t(\"title_shapes\")}, \n {Key: \"Distribution\", Label: t(\"page_title_density_and_fractioning_label_distribution\")}, \n {Key: \"Density\", Label: t(\"advice_density\")}, \n {Key: \"Name\", Label: t(\"results-overall-product-title\")}];\n }\n else if(usesFractioning)\n { \n return [{Key: \"Shape\", Label: t(\"title_shapes\")}, \n {Key: \"Distribution\", Label: t(\"page_title_density_and_fractioning_label_distribution\")}, \n {Key: \"Density\", Label: t(\"advice_density\")}, \n {Key: \"Name\", Label: t(\"results-overall-product-title\")}];\n }\n else\n {\n return [{Key: \"Name\", Label: t(\"results-overall-product-title\")}];\n }\n }\n\n compareStrings(stringA, stringB) { \n var upperA = stringA.toUpperCase();\n var upperB = stringB.toUpperCase();\n if(upperA > upperB)\n return 1; \n if(upperB > upperA)\n return -1; \n return 0;\n }\n\n getSortCompareFunction(orderByKey) { \n switch (orderByKey) { \n case \"BestMatch\":\n return (a, b) => b.MatchScore - a.MatchScore;\n\n case \"Density\":\n return (a, b) => a.Density - b.Density;\n\n case \"Distribution\":\n return (a, b) => \n {\n var fA = this.getAverageFractioningNumber(a.Fractioning);\n var fB = this.getAverageFractioningNumber(b.Fractioning);\n return fA - fB;\n };\n\n case \"Shape\":\n return (a, b) => this.compareStrings(a.Shape, b.Shape);\n\n case \"Name\":\n return (a, b) => this.compareStrings(a.Name, b.Name);\n\n //should never trigger.\n default:\n return (a, b) => 0;\n }\n }\n\n render() {\n const { activeApplication, active, list, t, UsesFractioning } = this.props;\n const isFiltered = list.filter(a => a.MatchScore > 0).length > 0;\n\n var options = this.getOptions(t, UsesFractioning, isFiltered);\n if(!this.state.orderBy || !options.some(o => o.Key === this.state.orderBy.Key))\n {\n this.setState({...this.state, orderBy: options[0]});\n return null;\n }\n\n const compareFunction = this.getSortCompareFunction(this.state.orderBy.Key);\n //...list because javascript sucks. Protects the list of mutilation.\n const orderedList = [...list].sort(compareFunction);\n\n return
\n
\n {`${t('fertilizer_list_results_label')} (${list.length})`}\n
\n \n
this.setState({...this.state, orderBy: v})} />\n\n \n {\n orderedList.map((ele, i) => {\n // let classes = (active === ele.Id) ? ' tableapplications__row--active' : '';\n // classes = (ele.IsBestMatch) ? (classes + ' bestMatch') : classes;\n // background: url(../img/icons/ico_best_match.png) no-repeat;\n // background-size: cover;\n // width: 25px;\n // height: 22px;\n const isActive = (active === ele.Id);\n\n return
\n \n {\n i !== 0 &&
\n }\n
activeApplication(ele.FertilizerId)}\n >\n \n
\n

\n
\n
\n
\n
\n {ele.Name}\n
\n
\n
{ele.Producer}
\n
{ele.Shape}
\n {/*
{ele.Producer}
*/}\n {\n UsesFractioning &&\n
\n
\n {ele.Fractioning}\n
\n
\n {`${ele.Density} ${t('unit_density')}`}\n
\n
\n }\n
\n
\n {\n (ele.MatchScore > 0) &&
\n
\n
\n ★★★★★\n
\n
\n ★★★★★\n
\n
\n
\n }\n
\n
\n
\n
\n
;\n })\n }\n
\n ;\n }\n}\n\nexport default TableApplications;\n","import React, {Component} from 'react';\nimport PropTypes from 'prop-types';\nimport {connect} from 'react-redux';\n\nimport {fetchApplications, activeApplication, isFineDosage,\n activeShapeAll} from '../store/actions/currentadvice';\nimport {showModal} from '../store/actions/app';\nimport * as selectors from '../store/selectors';\n\nimport Modal from '../components/modal';\nimport Advicebar from '../components/advicebar';\nimport TableApplications from '../components/tableapplications';\nimport localIcons from '../components/img/icons'\n\nimport './scss/applications.scss';\n\nclass ApplicationVaneset extends Component { \n intervalTimer = {};\n updates = 0;\n state = {\n isExpanded: false,\n height: 0,\n updates: 0\n };\n\n \n constructor(props) {\n super(props);\n this.state.isExpanded = props.expanded;\n this.contentRef = React.createRef();\n }\n\n updateHeight() {\n if(this.contentRef.current)\n {\n let height = this.contentRef.current.getBoundingClientRect().height;\n if(height !== this.state.height)\n {\n this.setState({\n ...this.state,\n height: height\n })\n }\n }\n this.updates = this.updates + 1;\n if(this.updates > 15)\n clearInterval(this.intervalTimer);\n }\n\n componentDidMount() {\n this.updateHeight();\n\n this.intervalTimer = setInterval(() => this.updateHeight(), 500);\n }\n\n componentWillUnmount() {\n clearInterval(this.intervalTimer);\n }\n\n render() {\n let {vaneset, t, UsesFractioning, activeApplication} = this.props;\n let isPS = vaneset.Name === ''\n return
\n { !isPS && \n
{\n this.setState({\n ...this.state,\n isExpanded: !this.state.isExpanded\n })}}>\n \n
\n

\n
\n
\n
{vaneset.Name}
\n {\n vaneset.PartNumbers !== undefined && vaneset.PartNumbers !== null && vaneset.PartNumbers.map((partNumber) => { \n return
\n {t('fertilizer_list_part_number')} {partNumber}
\n })\n }\n

\n
\n
}\n\n
\n
\n
activeApplication(vaneset.Id, id)}\n t={t}\n />\n \n
\n
\n }\n}\n\nApplicationVaneset.propTypes = {\n vaneset: PropTypes.object,\n expanded: PropTypes.bool,\n UsesFractioning: PropTypes.bool,\n activeApplication: PropTypes.func,\n t: PropTypes.func,\n};\n \nApplicationVaneset.defaultProps = {\n vaneset: null,\n expanded: false,\n UsesFractioning: true,\n activeApplication: null,\n t: null,\n};\n\n\nclass Applications extends Component {\n\n state = {\n vaneSetsOpened: null,\n stickyOffSet: null,\n };\n\n componentDidMount() {\n this.fetchApplications();\n window.addEventListener('scroll', this.handleScroll)\n }\n\n componentWillReceiveProps(props) {\n let {fineDosage, widerSearchCriteriaUsed, applications, vanesetId,\n applicationId} = props;\n let {match, history} = this.props;\n if(this.props.fineDosage===null && fineDosage!==null) {\n history.push(`/${match.params.brand}/advice/5/`);\n }\n if (widerSearchCriteriaUsed === true\n && this.props.widerSearchCriteriaUsed === false\n && applications.length > 0) {\n this.props.showModal({\n title: 'popup_title_attention',\n text: 'popup_message_attention'\n })\n }\n if(!(applicationId===this.props.applicationId && vanesetId===this.props.vanesetId) && applicationId!==null ) {\n setTimeout(()=> this.onSumbit(), 1);\n }\n }\n\n componentWillUnmount() {\n window.removeEventListener('scroll', this.handleScroll);\n }\n\n fetchApplications() {\n let {applications} = this.props;\n if(applications===null) {\n this.props.fetchApplications();\n }\n }\n fetchApplicationsAll = () => {\n this.props.activeShapeAll(this.props.shapes.map(item => item.Id));\n this.props.fetchApplications();\n };\n \n goBack = () => {\n const {match, history} = this.props;\n history.push(`/${match.params.brand}/advice/3/`);\n };\n\n activeApplication(vanesetId, id) {\n if(id===this.props.applicationId && vanesetId === this.props.vanesetId) {\n this.onSumbit();\n } else {\n this.props.activeApplication(vanesetId, id);\n }\n }\n\n handleScroll = () => {\n this.refs.stickyBar &&\n this.setState({\n ...this.state,\n stickyOffSet: this.refs.stickyBar.getBoundingClientRect().top\n })\n };\n\n toggleVan(id) {\n this.setState((state) => {\n return {\n ...state,\n vaneSetsOpened: id\n };\n });\n }\n\n onSumbit() {\n let {match, history, fineDosage} = this.props;\n if(fineDosage===null) {\n this.props.isFineDosage();\n } else {\n history.push(`/${match.params.brand}/advice/5/`);\n }\n }\n\n getSelectedVaneSetId(){\n const { vanesetId } = this.props;\n\n return this.state.vaneSetsOpened ||\n vanesetId ||\n null;\n }\n\n render() {\n\n let {t, showModal, applicationId, UsesFractioning} = this.props;\n let applications = (this.props.applications) ? this.props.applications : [];\n\n if(this.props.loading) {\n return null;\n }\n\n return
\n
\n
\n\n { (applications.length===0) &&\n
\n {t('fertilizer_list_nothing_found')}
\n \n \n }\n \n
\n {t('fertilizer_list_header_text')}\n
\n\n
\n {\n applications.sort((a, b) => b.Applications.length - a.Applications.length).map((ite, i) => {\n const isSelected = (ite.Id === this.getSelectedVaneSetId() || (!this.getSelectedVaneSetId() && i === 0));\n\n return
this.activeApplication(vid, id)}\n UsesFractioning={UsesFractioning}>\n {ite.Name}\n \n })\n }\n
\n
\n
this.onSumbit()} nextEnabled={(applicationId!==null)} />\n \n/*\n return
\n
\n
\n\n
\n {t('fertilizer_list_header_text')}\n
\n
\n { (applications.length===0) &&\n
\n {t('fertilizer_list_nothing_found')}
\n \n \n }\n\n
\n
\n
\n
\n {\n applications.map((ite, i) => {\n const isSelected = (ite.Id === this.getSelectedVaneSetId() || (!this.getSelectedVaneSetId() && i === 0));\n\n return
\n {\n (ite.Name !== '') &&
this.toggleVan(ite.Id)}\n\n \n ga-on=\"click\"\n ga-event-category=\"Vanes\"\n ga-event-action=\"switch\"\n ga-event-label={ite.Id}\n >\n

\n
\n }\n
\n })\n }\n
\n
\n
\n
\n {\n applications.map((ite, i) => {\n return (ite.Id === this.getSelectedVaneSetId() || (!this.getSelectedVaneSetId() && i === 0)) &&\n
this.activeApplication(ite.Id, id)}\n active={applicationId}\n list={ite.Applications}\n t={t}\n />\n })\n }\n \n
\n
this.onSumbit()} nextEnabled={(applicationId!==null)} />\n */\n }\n}\n\nconst mapStateToProps = (state) => {\n let machineId = selectors.getCurrentMachineId(state),\n machines = selectors.getMachines(state);\n return {\n applications: selectors.getCurrentApplications(state),\n applicationId: selectors.getCurrentApplicationId(state),\n vanesetId: selectors.getCurrentVanesetId(state),\n t: selectors.getTranslations(state),\n loading: selectors.isLoading(state),\n fineDosage: selectors.getFineDosage(state),\n UsesFractioning: machines[machineId].UsesFractioning,\n widerSearchCriteriaUsed: state.currentAdvice.widerSearchCriteriaUsed,\n shapes: selectors.getShapes(state),\n };\n}\nconst actions = {\n fetchApplications,\n activeApplication,\n showModal,\n activeShapeAll,\n isFineDosage\n};\n\nApplications = connect(mapStateToProps, actions)(Applications);\n\nexport default Applications;","import React from 'react';\n\nimport './scss/adviceresultitem.scss';\n\nconst AdviceResultItem = ({header, value, units, ico, isImageValueType, isValueCondensed = true}) => {\n return
\n
\n

\n
\n
\n\n
\n\n {\n isImageValueType\n ?

\n :
\n \n {value}\n \n \n {units}\n \n
\n }\n
\n
\n}\n\nexport default AdviceResultItem;\n","import React from 'react';\nimport icons from './img/icons';\nimport './scss/buttonscontrol.scss';\nimport AdviceResultItem from './adviceresultitem';\n\n\nconst ButtonsControl = ({\n header,\n title = \"\",\n value,\n units,\n onIncrease,\n ico,\n onDecrease,\n decreaseDisabled,\n increaseDisabled,\n reset,\n}) =>\n
\n
\n
\n
\n
\n
{reset && reset()}}\n >\n

\n
\n
\n
\n\nexport default ButtonsControl;\n","import React from 'react';\nimport OptionSelector from './optionselector';\n\nconst ApplicationTypeOptionSelector = ({applicationType, t, onChange}) => {\n return
;\n}\n\nexport default ApplicationTypeOptionSelector;\n","import React, {Component} from 'react';\r\nimport PropTypes from 'prop-types';\r\n\r\nimport localIcons from './img/icons'\r\n\r\nimport './scss/expendablecard.scss';\r\n\r\n\r\nclass ExpendableCard extends Component {\r\n intervalTimer = {};\r\n updates = 0;\r\n state = {\r\n isExpanded: false,\r\n height: 0,\r\n updates: 0\r\n };\r\n\r\n \r\n constructor(props) {\r\n super(props);\r\n this.state.isExpanded = props.expanded;\r\n this.contentRef = React.createRef();\r\n }\r\n\r\n updateHeight() {\r\n if(this.contentRef.current)\r\n {\r\n let height = this.contentRef.current.getBoundingClientRect().height;\r\n if(height !== this.state.height)\r\n {\r\n this.setState({\r\n ...this.state,\r\n height: height\r\n })\r\n }\r\n }\r\n this.updates = this.updates + 1;\r\n if(this.updates > 15)\r\n clearInterval(this.intervalTimer);\r\n }\r\n\r\n componentDidMount() {\r\n this.updateHeight();\r\n\r\n this.intervalTimer = setInterval(() => this.updateHeight(), 500);\r\n }\r\n\r\n componentWillUnmount() {\r\n clearInterval(this.intervalTimer);\r\n }\r\n\r\n\r\n render() {\r\n return
\r\n
{\r\n this.setState({\r\n ...this.state,\r\n isExpanded: !this.state.isExpanded\r\n })}\r\n }>\r\n
{this.props.header}
\r\n

\r\n
\r\n\r\n
\r\n
\r\n {this.props.children}\r\n
\r\n
\r\n
\r\n }\r\n}\r\n\r\nExpendableCard.propTypes = {\r\n gaLabel: PropTypes.string,\r\n header: PropTypes.string,\r\n expanded: PropTypes.bool,\r\n};\r\n \r\nExpendableCard.defaultProps = {\r\n gaLabel: \"\",\r\n header: \"None\",\r\n expanded: false,\r\n};\r\n\r\n\r\nexport default ExpendableCard;","import React, { Component } from 'react';\n\nimport Graphicbar from './graphicbar';\n\nimport './scss/resultoverall.scss';\nimport ButtonsControl from './buttonscontrol';\nimport * as selectors from '../store/selectors';\nimport { setTablePosition, setApplicationType } from '../store/actions/currentadvice';\nimport { connect } from 'react-redux';\nimport ApplicationTypeOptionSelector from './applicationtypeoptionselector';\nimport AdviceResultItem from './adviceresultitem';\n\nimport ExpendableCard from './expandableCard';\n\nclass ResultOverall extends Component {\n state = {\n isOverallExpanded: false\n };\n\n constructor(props) {\n super(props);\n const {x, y} = props.tablePos;\n this.props.setTablePosition(x, y);\n }\n\n componentWillReceiveProps(props) {\n if(props.table !== this.props.table) {\n const {x, y} = props.tablePos;\n this.props.setTablePosition(x, y);\n }\n };\n\n increaseX() {\n const { table, tablePos,setTablePosition } = this.props;\n let {x, y} = tablePos;\n\n if(x < table[y].length - 1 && table[y][x + 1] !== null) {\n x++;\n setTablePosition(x, y);\n }\n }\n\n decreaseX = () => {\n let { table, tablePos, setTablePosition } = this.props;\n let {x, y} = tablePos;\n\n if(x > 0 && table[y][x - 1] !== null) {\n x--;\n setTablePosition(x, y);\n }\n };\n\n increaseY = () => {\n let {table, tablePos,setTablePosition} = this.props;\n let {x, y} = tablePos;\n\n if(y < table.length - 1 && table[y + 1][x] !== null) {\n y++;\n setTablePosition(x, y);\n }\n };\n\n decreaseY() {\n let {table, tablePos, setTablePosition} = this.props;\n let {x, y} = tablePos;\n\n if(y > 0 && table[y - 1][x] !== null) {\n y--;\n setTablePosition(x, y);\n }\n }\n\n onChangeAppType(type) {\n const { setApplicationType } = this.props;\n setApplicationType(type);\n }\n\n resetXY(target) {\n const {tablePos, setTablePosition, baseTablePos} = this.props;\n let { x,y } = tablePos;\n if(target) {\n target === \"x\"\n ? setTablePosition(baseTablePos.x, y)\n : setTablePosition(x, baseTablePos.y);\n } else {\n setTablePosition(x, y);\n }\n }\n\n render() {\n let {\n t, machine, result, currentAdvice, table,\n tablePos, icons\n } = this.props;\n const {Images} = result;\n const {applicationType} = currentAdvice;\n const {x,y} = tablePos;\n\n let distribution = \"0-0-0-0\"\n if(result.FertiliserDistribution) \n distribution = result.FertiliserDistribution.split(\"-\");\n\n return
\n
\n \n
\n

\n
\n
\n {t('results-overall-machine-title')}\n
\n
\n {machine.Name}\n
\n
\n
\n
\n \n
\n
\n
\n

\n
\n
\n {t('results-overall-product-title')}\n
\n \n {\n result.FertiliserProducer &&\n
\n {result.FertiliserProducer}\n
\n }\n
\n {result.FertiliserName}\n
\n
\n {`${t(result.FertiliserShape)}`}\n
\n {\n (machine.UsesFractioning) &&\n
\n {`${result.FertiliserDensity} ${t('unit_density')}`}\n
\n }\n
\n
\n
\n
\n {\n (machine.UsesFractioning) &&\n
\n
\n \n
\n
\n {result.FertiliserDistribution}\n
\n
\n }\n
\n \n {!machine.HasSpout &&\n
\n {//\n }\n {result.Vanes}
\n
\n \n }\n
\n \n {\n (table && table[y][x]) &&\n \n
\n this.decreaseY()}\n increaseDisabled={(y >= table.length - 1 || table[y + 1][x] === null)}\n decreaseDisabled={(y <= 0 || table[y - 1][x] === null)}\n reset={() => this.resetXY(\"y\")}\n />\n\n
\n
\n this.increaseX()}\n onDecrease={() => this.decreaseX()}\n increaseDisabled={(x >= table[y].length - 1 || table[y][x + 1] === null)}\n decreaseDisabled={(x <= 0 || table[y][x - 1] == null)}\n reset={() => this.resetXY(\"x\")}\n />\n
\n
\n }\n {\n !machine.HasSpout &&\n \n
\n
\n {t('results-overall-application-type-title')}\n
\n {\n !machine.HasSpout &&\n
\n
this.onChangeAppType(v)}\n />\n \n }\n
\n
\n }\n \n
\n }\n}\n\nconst mapStateToProps = (state) => {\n return {\n table: selectors.getCurrentTable(state),\n baseTablePos: selectors.getBaseTablePos(state),\n tablePos: selectors.getCurrentTablePos(state),\n };\n};\n\nconst actions = {\n setTablePosition,\n setApplicationType,\n};\n\nResultOverall = connect(mapStateToProps, actions)(ResultOverall);\n\nexport default ResultOverall;\n","import * as constants from '../constants';\nimport * as Api from '../../api';\nimport * as selectors from '../../store/selectors';\nimport {trackError, preloadStarted, preloadFinished} from './app';\n\n\nconst fetchVideosStarted = () => ({\n type: constants.FETCH_VIDEOS_STARTED,\n});\n\nconst fetchVideosSuccess = (videos) => ({\n type: constants.FETCH_VIDEOS_SUCCESS,\n payload: videos\n});\n\nexport const fetchVideos = () => (dispatch, getState) => {\n dispatch(preloadStarted());\n dispatch(fetchVideosStarted());\n let lang = selectors.getCurrentLanguageCode(getState()),\n units = selectors.getCurrentUnits(getState()),\n brand = selectors.getBrand(getState());\n return Api.getVideos(lang, brand, units)\n .then((r) => {\n dispatch(preloadFinished());\n return dispatch(fetchVideosSuccess(r));\n })\n .catch(err => dispatch(trackError(err)));\n};\n","import React, { Component } from 'react';\nimport Modal from './modal';\nimport * as selectors from '../store/selectors';\nimport { connect } from 'react-redux';\nimport PropTypes from 'prop-types';\n\nimport ReactPlayer from 'react-player';\n\nclass VideoPlayerModal extends Component {\n render() {\n const { onClose, t, url, title } = this.props;\n\n return (\n
\n \n
\n {t(title)}\n
\n
\n \n
\n \n );\n }\n}\n\nVideoPlayerModal.propTypes = {\n url: PropTypes.string,\n onClose: PropTypes.func,\n};\n\nconst mapStateToProps = (state) => ({\n t: selectors.getTranslations(state),\n});\n\nVideoPlayerModal = connect(mapStateToProps)(VideoPlayerModal);\n\nexport default VideoPlayerModal;\n","import React, { Component } from 'react';\nimport * as selectors from '../store/selectors';\nimport { fetchVideos } from '../store/actions/videos';\nimport { connect } from 'react-redux';\nimport PropTypes from 'prop-types';\nimport ReactPlayer from 'react-player';\nimport { fetchSpreaderVideos } from '../store/actions/spreadervideos';\nimport VideoPlayerModal from './videoplayermodal';\nimport './scss/videolist.scss';\nimport { secondsToHms } from '../utils';\nimport icons from './img/icons';\n\nclass VideoItem extends Component {\n state = {\n duration: 0\n };\n\n render() {\n const {id, onClick, url, thumb, desc, width, height, t} = this.props;\n\n return
onClick && onClick(id, url)}\n \n ga-on=\"click\"\n ga-event-category=\"Video\"\n ga-event-action=\"play\"\n ga-event-label={id}\n style={{\n /* for thumbnails...*/ \n\n position: \"relative\"\n }}\n >\n
\n

\n
\n {\n (this.state.duration > 0) &&\n
\n {secondsToHms(this.state.duration)}\n
\n }\n\n

\n \n \n
\n {t(desc)}\n
\n
\n }\n}\n\nVideoItem.propTypes = {\n id: PropTypes.string,\n url: PropTypes.string,\n desc: PropTypes.string,\n thumbnail: PropTypes.string,\n width: PropTypes.string,\n height: PropTypes.any,\n onClick: PropTypes.func,\n t: PropTypes.any,\n};\n\nclass VideoList extends Component {\n state = {\n isModalOpen: false,\n selectedVideoUrl: null\n };\n\n componentDidMount() {\n if(this.props.spreaderId) {\n this.props.fetchSpreaderVideos(this.props.spreaderId);\n } else {\n this.props.fetchVideos();\n }\n }\n\n componentWillReceiveProps(nextProps) {\n if(nextProps.videos === null && this.props.videos !== null) {\n if(this.props.spreaderId) {\n this.props.fetchSpreaderVideos(this.props.spreaderId);\n } else {\n this.props.fetchVideos();\n }\n }\n }\n\n onCloseModal() {\n this.setState({\n isModalOpen: false,\n selectedVideoUrl: null\n })\n }\n\n render() {\n const {t} = this.props;\n const {isModalOpen, selectedVideoUrl, title} = this.state;\n const videos = this.props.spreaderId\n ? this.props.spreaderVideos\n : this.props.videos;\n\n let visible = videos && videos.length > 0;\n\n return
\n
\n {t('app_instructional_videos')}\n
\n
\n {\n isModalOpen &&
\n }\n {\n videos && videos.map((item, index) => {\n return
\n {\n this.setState({\n isModalOpen: true,\n selectedVideoUrl: url,\n title: item.Title,\n })\n }}\n />\n
\n })\n }\n
\n
;\n }\n}\n\nVideoList.propTypes = {\n spreaderId: PropTypes.string\n};\n\nconst mapStateToProps = (state) => {\n return {\n t: selectors.getTranslations(state),\n videos: selectors.getVideos(state),\n spreaderVideos: selectors.getSpreaderVideos(state),\n };\n};\n\nconst actions = {\n fetchVideos,\n fetchSpreaderVideos\n};\n\nVideoList = connect(mapStateToProps, actions)(VideoList);\nexport default VideoList;\n","import * as constants from '../constants';\nimport * as Api from '../../api';\nimport * as selectors from '../../store/selectors';\nimport {trackError, preloadStarted, preloadFinished} from './app';\n\n\nconst fetchSpreaderVideosStarted = () => ({\n type: constants.FETCH_SPREADERVIDEOS_STARTED,\n});\nconst fetchSpreaderVideosSuccess = (spreaderVideos) => ({\n type: constants.FETCH_SPREADERVIDEOS_SUCCESS,\n payload: spreaderVideos\n});\nexport const fetchSpreaderVideos = (spreaderId) => (dispatch, getState) => {\n dispatch(preloadStarted());\n dispatch(fetchSpreaderVideosStarted());\n const lang = selectors.getCurrentLanguageCode(getState());\n return Api.getSpreaderVideos(spreaderId, lang)\n .then((r) => {\n dispatch(preloadFinished());\n return dispatch(fetchSpreaderVideosSuccess(r));\n })\n .catch(err => dispatch(trackError(err)));\n};\n\n","import React, {Component} from 'react';\nimport {connect} from 'react-redux';\n\nimport * as selectors from '../store/selectors';\n\nimport './scss/resultadvice.scss';\nimport AdviceResultItem from './adviceresultitem';\n\nimport ExpendableCard from './expandableCard';\nimport VideoList from './videolist';\n\nclass ResultAdvice extends Component {\n\n getInclination() {\n const { result, currentAdvice} = this.props;\n const { applicationType } = currentAdvice;\n\n if(result.Inclinations && result.Inclinations.length > 0)\n {\n var filtered = result.Inclinations.filter(inc => inc.TopDressMethod === applicationType);\n if(filtered.length === 1)\n return filtered[0].Inclination;\n }\n\n return result.Inclination;\n }\n\n render() {\n const { table, t, machine, result, kitUsed, tablePos} = this.props;\n\n return
\n
\n \n
\n {\n (machine.HasTiming) &&\n
\n }\n {\n !machine.HasSpout &&\n
\n }\n
\n
\n {\n !machine.HasSpout &&\n
\n }\n {\n !machine.HasSpout &&\n
\n }\n {\n !machine.HasSpout &&\n
\n }\n
\n {\n (result.Images.TransmissionValue) &&\n
\n }\n
\n \n \n \n
\n }\n}\nconst mapStateToProps = (state) => {\n return {\n t: selectors.getTranslations(state),\n table: selectors.getCurrentTable(state),\n tablePos: selectors.getCurrentTablePos(state),\n settings: selectors.getCurrentField(state),\n appType: selectors.getCurrentAppType(state),\n result: selectors.getCurrentResult(state),\n kitUsed: selectors.isCurrentKitUsed(state),\n currentAdvice: selectors.getCurrentAdvice(state),\n };\n};\n\nconst actions = {\n};\n\nResultAdvice = connect(mapStateToProps, actions)(ResultAdvice);\n\nexport default ResultAdvice;\n","import React, {Component} from 'react';\r\nimport {connect} from 'react-redux';\r\n\r\nimport ExpendableCard from './expandableCard';\r\nimport AdviceResultItem from './adviceresultitem';\r\n\r\nimport * as selectors from '../store/selectors';\r\n\r\nimport './scss/resultboundary.scss';\r\n\r\n\r\nclass ResultBoundary extends Component {\r\n\r\n static YIELD = \"Yield\";\r\n static ECO = \"Eco\";\r\n static H2O = \"H2O\";\r\n\r\n state = {\r\n boxStrategy: ResultBoundary.YIELD,\r\n plateStrategy: ResultBoundary.ECO\r\n }\r\n\r\n \r\n constructor(props) {\r\n super(props);\r\n this.contentRef = React.createRef();\r\n }\r\n\r\n\r\n setBoxStrategy(boxStrategy) {\r\n this.setState({boxStrategy});\r\n }\r\n\r\n setPlateStrategy(plateStrategy) {\r\n this.setState({plateStrategy});\r\n }\r\n\r\n isBoxStrategy(strategy)\r\n {\r\n return this.state.boxStrategy === strategy;\r\n }\r\n \r\n isPlateStrategy(strategy)\r\n {\r\n return this.state.plateStrategy === strategy;\r\n }\r\n\r\n hasTrimflow(result, machine){\r\n return machine.HasTrimFlow && (result.YieldTrimFlowSetting || result.EcoTrimFlowSetting || result.H2OTrimFlowSetting);\r\n }\r\n\r\n hasPlate(result, machine){\r\n return machine.HasBorderSpreadingPlate && (result.EcoBorderPlateSetting || result.H2OBorderPlateSetting);\r\n }\r\n\r\n getContentWidth() {\r\n if(this.contentRef.current)\r\n return this.contentRef.current.getBoundingClientRect().width;\r\n\r\n return 0;\r\n }\r\n\r\n getTiming(timing, offset) {\r\n var char = timing.charCodeAt(0);\r\n char = char + parseInt(offset, 0);\r\n return String.fromCharCode(char);\r\n }\r\n\r\n getCurrentBoxPosition(strategy) {\r\n return (this.getPosition(strategy) - this.getPosition(this.state.boxStrategy));\r\n }\r\n\r\n getCurrentPlatePosition(strategy) {\r\n return (this.getPosition(strategy) - this.getPosition(this.state.plateStrategy));\r\n }\r\n\r\n getPosition(strategy) {\r\n switch(strategy) {\r\n case ResultBoundary.YIELD:\r\n return 0;\r\n \r\n case ResultBoundary.ECO:\r\n return 1;\r\n\r\n case ResultBoundary.H2O:\r\n return 2;\r\n\r\n default:\r\n return 0;\r\n }\r\n }\r\n\r\n render() {\r\n let {result, machine, t, icons, table, tablePos} = this.props;\r\n\r\n var timing = table[tablePos.y][tablePos.x].Timing;\r\n\r\n return
\r\n {(this.hasTrimflow(result, machine)) &&\r\n
\r\n \r\n
\r\n {(result.YieldTrimFlowSetting) &&
{this.setBoxStrategy(ResultBoundary.YIELD)}}\r\n \r\n ga-on=\"click\"\r\n ga-event-category=\"toBorder\"\r\n ga-event-action=\"pickStrategy\"\r\n ga-event-label=\"yield\">\r\n

\r\n
{t(\"results-boundary-yield\")}\r\n
}\r\n {(result.EcoTrimFlowSetting) &&
{this.setBoxStrategy(ResultBoundary.ECO)}}\r\n \r\n ga-on=\"click\"\r\n ga-event-category=\"toBorder\"\r\n ga-event-action=\"pickBorderStrategy\"\r\n ga-event-label=\"eco\">\r\n

\r\n
{t(\"results-boundary-eco\")}\r\n
}\r\n {(result.H2OTrimFlowSetting) &&
{this.setBoxStrategy(ResultBoundary.H2O)}}\r\n \r\n ga-on=\"click\"\r\n ga-event-category=\"toBorder\"\r\n ga-event-action=\"pickBorderStrategy\"\r\n ga-event-label=\"h2o\">\r\n

\r\n
{t(\"results-boundary-h2o\")}\r\n
}\r\n
\r\n\r\n
\r\n
\r\n \r\n {(result.YieldTrimFlowSetting) && \r\n
\r\n } \r\n {(result.EcoTrimFlowSetting) && \r\n
\r\n }\r\n\r\n \r\n {(result.H2OTrimFlowSetting) && \r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n } \r\n
\r\n
\r\n
\r\n \r\n }\r\n \r\n {(this.hasPlate(result, machine)) && /* BORDER SPREADING PLATE FROM HERE ON */\r\n
\r\n \r\n
\r\n {(result.EcoBorderPlateSetting) &&
{this.setPlateStrategy(ResultBoundary.ECO)}}\r\n \r\n ga-on=\"click\"\r\n ga-event-category=\"fromBorder\"\r\n ga-event-action=\"pickBorderStrategy\"\r\n ga-event-label=\"eco\">\r\n

\r\n
{t(\"results-boundary-eco\")}\r\n
}\r\n {(result.H2OBorderPlateSetting) &&
{this.setPlateStrategy(ResultBoundary.H2O)}}\r\n \r\n ga-on=\"click\"\r\n ga-event-category=\"fromBorder\"\r\n ga-event-action=\"pickBorderStrategy\"\r\n ga-event-label=\"h2o\">\r\n

\r\n
{t(\"results-boundary-h2o\")}\r\n
}\r\n
\r\n\r\n
\r\n
\r\n \r\n {(result.EcoBorderPlateSetting) && \r\n
\r\n\r\n }\r\n\r\n {(result.H2OBorderPlateSetting) && \r\n
\r\n }\r\n
\r\n
\r\n
\r\n \r\n }\r\n
\r\n }\r\n}\r\n\r\nconst mapStateToProps = (state) => {\r\nreturn {\r\n t: selectors.getTranslations(state),\r\n table: selectors.getCurrentTable(state),\r\n tablePos: selectors.getCurrentTablePos(state),\r\n icons: selectors.getIcons(state),\r\n};\r\n};\r\n\r\nconst actions = {\r\n};\r\n \r\nResultBoundary = connect(mapStateToProps, actions)(ResultBoundary);\r\n\r\nexport default ResultBoundary;","import React, {Component} from 'react';\nimport PropTypes from 'prop-types';\n\nimport icons from './img/icons';\n\n/*\niconName: an exported field name of the img icons import\n\nUsage examples:\n\n
\n
\n \n \n*/\nclass IconButton extends Component {\n render() {\n const {iconName, title, width, textColor, bgColor, onClick, disabled,\n gaCategory, gaAction, gaLabel} = this.props;\n const buttonHeight = 30;\n\n return !disabled && onClick && onClick()}\n >\n {\n iconName &&
\n

\n
\n }\n {\n title &&
\n {title}\n
\n }\n
;\n }\n}\n\nIconButton.propTypes = {\n iconName: PropTypes.string,\n title: PropTypes.string,\n width: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.number\n ]),\n onClick: PropTypes.func,\n\n gaCategory: PropTypes.string,\n gaAction: PropTypes.string,\n gaLabel: PropTypes.string,\n};\n\nIconButton.defaultProps = {\n iconName: \"\",\n title: \"\",\n width: \"auto\",\n\n gaCategory: \"Undefined\",\n gaAction: \"Undefined\",\n gaLabel: \"Undefined\",\n};\n\n\nexport default IconButton;\n","import React from 'react';\nimport Modal from './modal';\n\n\nconst InputModal = (\n {\n t,\n onSubmit,\n onChange,\n onClose,\n placeholder,\n }\n ) => {\n\n return (\n \n \n \n )\n};\n\nexport default InputModal;\n","import React, {Component} from 'react';\nimport {connect} from 'react-redux';\n\nimport {showHelp} from '../store/actions/app';\nimport {\n fetchPdf,\n fetchResult,\n newAdvice,\n updateFieldWithoutReset,\n useKit\n} from '../store/actions/currentadvice';\nimport * as selectors from '../store/selectors';\nimport * as constants from '../store/constants';\n\nimport Modal from '../components/modal';\nimport ResultOverall from '../components/resultoverall';\nimport ResultAdvice from '../components/resultadvice';\nimport ResultBoundary from '../components/resultboundary';\n\nimport './scss/results.scss';\nimport Advicebar from '../components/advicebar';\nimport IconButton from '../components/iconbutton';\nimport localIcons from '../components/img/icons';\nimport {favouriteStoreAdvice} from '../store/actions/history';\nimport InputModal from '../components/inputmodal';\nimport favourites from '../store/reducers/favourites';\n\n const objectKeysToEmailQueryParams = (obj) =>\n Object.entries(obj).reduce((acc, [key, value], index) =>\n (value)\n ? `${acc}${index !== 0 ? '&' : ''}${key}=${value}`\n : acc\n , '');\n\nclass Results extends Component {\n state = {\n kind:null,\n isSaveAdviceModalOpen: false,\n isSaved: false,\n saveAdviceTitle: ''\n };\n\n componentDidMount() {\n const {fineDosage} = this.props;\n if(fineDosage===false) {\n this.fetchResult();\n }\n }\n\n componentWillReceiveProps(props) {\n if(props.pdfUrl!==null && this.props.pdfUrl===null) {\n setTimeout(()=> {\n if(this.state.kind==='download') {\n if(props.platform === constants.PLATFORM_DESKTOP) {\n window.open(props.pdfUrl, '_blank');\n } else {\n window.location.href = props.pdfUrl;\n }\n } else {\n this.sendEmail();\n }\n this.setState({kind: null});\n });\n }\n if(props.kitUsed !== null && this.props.kitUsed === null) {\n this.fetchResult();\n }\n }\n\n fetchResult = () => {\n const {result} = this.props;\n if(!result) {\n this.props.fetchResult();\n } else {\n const {x,y} = this.props.tablePos;\n this.setState({x,y});\n }\n };\n\n fetchPdfUrl = () => {\n const { pdfUrl, fetchPdf } = this.props;\n if(pdfUrl===null) {\n this.setState({kind:'email'}, ()=>\n fetchPdf());\n } else {\n this.sendEmail();\n }\n };\n\n saveFavorite = () => {\n const { application } = this.props;\n this.setState({\n ...this.state,\n isSaveAdviceModalOpen: true,\n saveAdviceTitle: application.Name\n })\n };\n\n getDirectUrl = () => {\n const {machine, fertiliserId} = this.props;\n const {\n WorkingWidth, ApplicationRate, applicationType, validField, shapeId,\n granuleSizeMinus2, granuleSizeB23, granuleSizeB34, granuleSize4, adviceDensity, \n fineDosage, kitUsed, applicationId, vanesetId, DrivingSpeed\n } = this.props.currentAdvice;\n const urlBase = window.location.href.split('advice/5')[0];\n\n const url = `${urlBase}shared?${objectKeysToEmailQueryParams({\n machine: machine.Id,\n fertilizer: fertiliserId,\n DrivingSpeed: DrivingSpeed,\n WorkingWidth: WorkingWidth,\n ApplicationRate: ApplicationRate,\n applicationType: applicationType,\n validField,\n shapeId: shapeId.join('-'),\n distribution: `${granuleSizeMinus2}-${granuleSizeB23}-${granuleSizeB34}-${granuleSize4}`,\n density: adviceDensity ? adviceDensity : '0',\n fineDosage: fineDosage ? 'true' : 'false',\n kitUsed,\n applicationId,\n vanes: vanesetId\n })}`;\n\n return url;\n }\n\n sendEmail = () => {\n const {t} = this.props;\n\n const url = this.getDirectUrl();\n \n const body = `${t('email_body')}%0D%0A %0D%0A ${encodeURIComponent(url)}`;\n \n const composed_mail = `mailto:?subject=${t('email_subject')}&body=${body}`;\n window.location.href = composed_mail;\n };\n\n downloadPdf = ( )=> {\n const {pdfUrl, fetchPdf, platform} = this.props;\n if(pdfUrl===null) {\n this.setState({kind: 'download'}, () =>\n fetchPdf());\n } else {\n if (platform === constants.PLATFORM_DESKTOP) {\n window.open(pdfUrl, '_blank');\n } else {\n window.location.href = pdfUrl;\n }\n }\n };\n\n goBack = () => {\n const {match, history} = this.props;\n history.push(`/${match.params.brand}/advice/2/`);\n };\n\n goToPreviousStep = () => {\n const {match, history} = this.props;\n history.push(`/${match.params.brand}/advice/4/`);\n };\n\n updateSpeedAndFetch = () => {\n const {updateFieldWithoutReset, adviceDrivingSpeed} = this.props;\n updateFieldWithoutReset('DrivingSpeed', adviceDrivingSpeed);\n this.fetchResult();\n };\n\n onSubmitSaveFavorite = () => {\n this.props.favouriteStoreAdvice(this.state.saveAdviceTitle);\n this.setState({ isSaveAdviceModalOpen: false, isSaved: true });\n };\n\n handleSaveTitleChange = event => {\n event.preventDefault();\n this.setState({\n ...this.state,\n saveAdviceTitle: event.target.value\n })\n };\n \n historyContainsAdvice = () => {\n const {adviceHistory, currentAdvice} = this.props;\n if(!adviceHistory)\n return false;\n\n let matched = adviceHistory.filter((ite)=> ite.fertiliserId === currentAdvice.fertiliserId && ite.vanesetId === currentAdvice.vanesetId)\n return (matched.length===1);\n };\n\n render() {\n const {\n result, t, showHelp, kitUsed, fineDosage,\n machine, application, advicePossible, warningTranslationKey,\n adviceDrivingSpeed, useKit, currentAdvice, icons\n } = this.props;\n const { isSaveAdviceModalOpen } = this.state;\n \n const isSaved = this.state.isSaved || this.historyContainsAdvice();\n\n if (fineDosage === true && kitUsed === null) {\n return useKit(false)}>\n {t('popup_title_attention')}
\n {t('popup_message_fineapplication')}
\n \n \n \n }\n\n if (advicePossible === false) {\n if (warningTranslationKey && warningTranslationKey === 'ADVICE_SPEED_OUT_OF_RANGE') {\n return \n {t('popup_title_attention')}
\n {t('advice_speed_out_of_range')}
\n \n \n \n }\n return \n {t('popup_title_error')}
\n {t('advice_no_options')}
\n \n \n }\n\n if(!result) {\n return null;\n }\n\n var shareData = {\n url: this.getDirectUrl(),\n title: t('page_title_advice'),\n text: t('email_body')\n };\n\n var canShare = window.navigator.share;\n\n return \n {\n isSaveAdviceModalOpen &&\n
this.setState({ isSaveAdviceModalOpen: false })}\n onChange={this.handleSaveTitleChange}\n onSubmit={this.onSubmitSaveFavorite}\n t={t}\n />\n }\n \n < {t('button_back')}\n \n \n \n \n {\n !canShare && \n \n }\n {\n canShare && \n navigator.share(shareData)}\n />\n }\n \n
\n \n {\n (result.Warning) && \n

\n
\n
\n {`${t('results-attention-title')}:`}\n
\n
\n {result.Warning}\n
\n
\n
\n }\n \n \n \n ;\n }\n}\n\nconst mapStateToProps = (state) => {\n const isHistory = selectors.isHistoryAdvice(state);\n const machines = selectors.getMachines(state);\n const machineId = selectors.getCurrentMachineId(state);\n let machine = machines[machineId];\n \n /*machine = selectors.getCurrentHistoryMachine(state);*/\n\n let units = selectors.getCurrentUnits(state);\n return {\n field: selectors.getCurrentField(state),\n units,\n lang: selectors.getCurrentLanguageCode(state),\n result: selectors.getCurrentResult(state),\n adviceHistory: selectors.getFavourites(state, units),\n spreaderVideos: selectors.getSpreaderVideos(state),\n t: selectors.getTranslations(state),\n icons: selectors.getIcons(state),\n tablePos: selectors.getCurrentTablePos(state),\n pdfUrl: selectors.getCurrentPdf(state),\n machine,\n application: selectors.getCurrentApplication(state),\n fineDosage: selectors.getFineDosage(state),\n kitUsed: selectors.isCurrentKitUsed(state),\n isHistory,\n platform: selectors.getPlatform(state),\n advicePossible: state.currentAdvice.advicePossible,\n warningTranslationKey: state.currentAdvice.warningTranslationKey,\n adviceDrivingSpeed: state.currentAdvice.adviceDrivingSpeed,\n currentAdvice: state.currentAdvice,\n fertiliserId: selectors.getCurrentFertilizerId(state),\n }\n};\n\nconst actions = {\n fetchResult,\n showHelp,\n useKit,\n fetchPdf,\n newAdvice,\n updateFieldWithoutReset,\n favouriteStoreAdvice,\n};\n\nResults = connect(mapStateToProps, actions)(Results);\n\n\nexport default Results;\n","import * as constants from '../constants';\nimport * as selectors from '../selectors';\n\nexport const favouriteStoreAdvice = (name) => (dispatch, getState) => {\n let advice = selectors.getCurrentAdvice(getState());\n let machineId = selectors.getCurrentMachineId(getState());\n const machine = selectors.getMachine(getState(), machineId);\n let units = selectors.getCurrentUnits(getState());\n \n return dispatch({\n type: constants.FAVOURITE_STORE_ADVICE,\n payload: {advice: { ...advice, name }, machine, units}\n });\n};\n\nexport const favouriteLoadAdvice = (id) => (dispatch, getState) => {\n let units = selectors.getCurrentUnits(getState());\n\n let advice = selectors.getFavouriteAdvice(getState(), id, units);\n const machine = selectors.getMachine(getState(), advice.machine);\n\n if(!machine) {\n dispatch({\n type: constants.FETCH_MACHINE_SUCCESS,\n payload: advice.machineHistory\n });\n }\n\n return dispatch({\n type: constants.FAVOURITE_LOAD_ADVICE,\n payload: advice\n });\n};\n\nexport const favouriteRemoveAdvice = (id) => (dispatch) => {\n return dispatch({\n type: constants.FAVOURITE_REMOVE_ADVICE,\n payload: id\n });\n};\n","import React, {Component} from 'react';\nimport {connect} from 'react-redux';\nimport {Switch, Route} from 'react-router';\n\nimport {getCurrentStep} from '../store/selectors';\n\nimport MachinesList from './machineslist';\nimport FieldSettings from './fieldsettings';\nimport ProductDetails from './productdetails';\nimport Applications from './applications';\nimport Results from './results';\n\n\nimport './scss/advice.scss';\n\n\nclass Advice extends Component {\n state = {\n adviceBarHidden: false,\n };\n\n componentWillReceiveProps(props) {\n this.validateUrl(props);\n }\n\n componentWillMount() {\n this.validateUrl(this.props);\n }\n\n validateUrl(props) {\n let {currentStep, match} = props;\n if(match.params.step > currentStep) {\n this.redirectTo(currentStep);\n }\n }\n\n redirectTo(step) {\n let {match, history} = this.props;\n history.push(`/${match.params.brand}/advice/${step}/`);\n\n }\n\n componentDidUpdate(prevProps) {\n if(this.props.location !== prevProps.location) {\n this.onRouteChanged(this.props.location);\n }\n }\n\n toggleHideAdviceBar = (state) =>\n this.setState({\n ...state,\n adviceBarHidden: state\n });\n\n onRouteChanged() {\n const selectedVaneSetNode = document.querySelector('.selected_vaneset_node');\n const selectedApplicationNode = document.querySelector('.selected_application_node');\n\n if(selectedVaneSetNode) {\n selectedVaneSetNode.scrollIntoView({inline: \"center\"});\n }\n\n if(selectedApplicationNode) {\n selectedApplicationNode.scrollIntoView({\n behavior: 'smooth',\n block: 'center',\n });\n }\n }\n\n render() {\n const {match, currentStep} = this.props;\n return \n
\n {(currentStep > 1) &&\n \n \n }\n />\n }\n {(currentStep > 2) &&\n \n \n }\n />\n }\n {(currentStep > 3) &&\n \n \n }\n />\n }\n {(currentStep > 4) && }\n \n \n }\n />\n \n
;\n }\n}\n\n\nconst mapStateToProps = (state) => {\n return {\n currentStep: getCurrentStep(state)\n };\n};\nconst actions = {};\n\nAdvice = connect(mapStateToProps, actions)(Advice);\n\nexport default Advice;\n","import React, { Component } from 'react';\n\nimport './scss/headerimage.scss';\n\n\nclass HeaderImage extends Component {\n\n render() {\n let {title, brand, t} = this.props;\n let path = `${window['DATA'].api_url}/Images/Website/Banners/`;\n\n return \n }\n}\n\nexport default HeaderImage;\n","import React, {Component} from 'react';\nimport {connect} from 'react-redux';\n\nimport * as utils from '../utils';\nimport * as selectors from '../store/selectors';\nimport {fetchAutosetapp} from '../store/actions/autosetapp';\n\nimport HeaderImage from '../components/headerimage';\n\nimport './scss/autosetapp.scss';\n\n\nclass Autosetapp extends Component {\n\n componentDidMount() {\n if(this.props.autosetapp===null) {\n this.props.fetchAutosetapp();\n }\n utils.bodyClassList().add('whiteBackground');\n }\n componentWillUnmount() {\n utils.bodyClassList().remove('whiteBackground');\n }\n\n formatDate(dt) {\n return utils.formatDate(dt);\n }\n\n render() {\n let {t, autosetapp, match} = this.props;\n\n if(autosetapp===null){\n return null;\n }\n\n return \n
\n
\n
\n
\n\n

\n\n
\n
\n
\n
\n
\n
\n
{t('version_title_autosetapp')}
\n
\n - {t('current_version_title_autosetapp')}\n {autosetapp.DBVersion}\n
\n - {t('created_title_autosetapp')}\n {this.formatDate(autosetapp.DateCreated)}\n
\n
\n
\n
\n\n {/*second button*/}\n
\n
\n
\n
\n
\n }\n}\n\nconst mapStateToProps = (state) => {\n return {\n t: selectors.getTranslations(state),\n autosetapp: selectors.getAutosetapp(state),\n };\n}\nconst actions = {\n fetchAutosetapp\n};\nAutosetapp = connect(mapStateToProps, actions)(Autosetapp);\nexport default Autosetapp;\n","import * as constants from '../constants';\nimport * as Api from '../../api';\nimport {trackError, preloadStarted, preloadFinished} from './app';\n\n\nconst fetchAutosetappStarted = () => ({\n type: constants.FETCH_AUTOSETAPP_STARTED,\n});\nconst fetchAutosetappSuccess = (r) => ({\n type: constants.FETCH_AUTOSETAPP_SUCCESS,\n payload: {autosetapp: r}\n});\nexport const fetchAutosetapp = () => (dispatch, getState) => {\n dispatch(preloadStarted());\n dispatch(fetchAutosetappStarted());\n return Api.getAutosetapp()\n .then((r) => {\n dispatch(preloadFinished());\n return dispatch(fetchAutosetappSuccess(r));\n })\n .catch(err => dispatch(trackError(err))\n );\n};\n","import React, {Component} from 'react';\nimport {connect} from 'react-redux';\n\nimport * as selectors from '../store/selectors';\nimport {fetchOtherapps} from '../store/actions/otherapps';\n\nimport HeaderImage from '../components/headerimage';\n\nimport './scss/otherapps.scss';\n\n\nclass OtherApps extends Component {\n\n componentDidMount() {\n let {apps, fetchOtherapps} = this.props;\n if(apps===null) {\n fetchOtherapps();\n }\n }\n\n render() {\n let {t, apps, match} = this.props;\n\n if(apps===null){\n return null;\n }\n\n return \n }\n}\n\nconst mapStateToProps = (state) => {\n return {\n t: selectors.getTranslations(state),\n apps: selectors.getOtherapps(state)\n };\n}\nconst actions = {\n fetchOtherapps\n};\nOtherApps = connect(mapStateToProps, actions)(OtherApps);\nexport default OtherApps;\n","import * as constants from '../constants';\nimport * as Api from '../../api';\nimport * as selectors from '../../store/selectors';\nimport {trackError, preloadStarted, preloadFinished} from './app';\n\n\nconst fetchOtherappsStarted = () => ({\n type: constants.FETCH_OTHERAPPS_STARTED,\n});\nconst fetchOtherappsSuccess = (apps) => ({\n type: constants.FETCH_OTHERAPPS_SUCCESS,\n payload: apps\n});\nexport const fetchOtherapps = () => (dispatch, getState) => {\n dispatch(preloadStarted());\n dispatch(fetchOtherappsStarted());\n let lang = selectors.getCurrentLanguageCode(getState());\n let brand = selectors.getBrand(getState());\n let plataform = selectors.getPlatform(getState());\n return Api.getOtherApps(lang, brand, plataform)\n .then((r) => {\n dispatch(preloadFinished());\n return dispatch(fetchOtherappsSuccess(r));\n })\n .catch(err => dispatch(trackError(err)));\n}\n\n","import React, {Component} from 'react';\nimport {connect} from 'react-redux';\n\nimport * as selectors from '../store/selectors';\nimport * as utils from '../utils';\n\nimport './scss/about.scss';\n\nimport HeaderImage from '../components/headerimage';\n\nclass About extends Component {\n\n componentDidMount() {\n utils.bodyClassList().add('whiteBackground');\n }\n\n componentWillUnmount() {\n utils.bodyClassList().remove('whiteBackground');\n }\n\n render() {\n const {t, match, apiVersion, dbVersion, platform, webview, browser} = this.props;\n\n return \n
\n \n
\n
{t('about_version_header')}
\n {`${t('about_front_version')} (0.2.0)`}\n {`${t('about_db_version')} (${dbVersion})`}\n {`${t('about_api_version')} (${apiVersion})`}\n \n
{t('about_important_header')}
\n
\n
\n ;\n }\n}\n\nconst mapStateToProps = (state) => {\n return {\n t: selectors.getTranslations(state),\n apiVersion: selectors.getApiVersion(state),\n dbVersion: selectors.getApiDatabaseVersion(state),\n };\n};\nconst actions = {};\nAbout = connect(mapStateToProps, actions)(About);\nexport default About;\n","import React, { Component } from 'react';\nimport * as utils from '../utils';\nimport './scss/tablehistory.scss';\nimport * as selectors from '../store/selectors';\nimport { connect } from 'react-redux';\nimport { favouriteRemoveAdvice } from '../store/actions/history';\nimport icons from './img/icons';\nimport Modal from './modal';\n\n\nclass HistoryCard extends Component {\n state = {isModalOpen: false};\n\n formatDate(dt) {\n let date = utils.formatDate(dt);\n let hour = utils.formatHour(dt);\n return date + ' ' + hour;\n }\n\n getApplication(applications, id) {\n const numberId = typeof id === 'string' ? parseInt(id, 10) : id;\n for(let i in applications) {\n let r = applications[i].Applications.filter((app) => app.Id === numberId);\n if(r.length>0) {\n return r[0];\n }\n }\n }\n\n getShape(applications, id) {\n const numberId = typeof id === 'string' ? parseInt(id, 10) : id;\n for(let i in applications) {\n let r = applications[i].Applications.filter((app) => app.Id === numberId);\n if(r.length>0) {\n return r[0].Shape\n }\n }\n }\n\n render() {\n const {t, ele, loadAdvice, index} = this.props;\n const {isModalOpen} = this.state;\n const workingWidth = ele.workingWidth ? ele.workingWidth : ele.WorkingWidth;\n const drivingSpeed = ele.drivingSpeed ? ele.drivingSpeed : ele.DrivingSpeed;\n return \n {\n isModalOpen &&
{\n this.setState({ isModalOpen: false });\n }}\n >\n \n
\n
\n {t('delete-advice-title')}\n
\n
\n {t('delete-advice-are-you-sure')}\n
\n
\n
\n \n \n
\n
\n \n }\n
loadAdvice(ele.id)}\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n width: \"100%\",\n height: \"100%\"\n }}\n >\n

\n
\n
\n
\n {this.formatDate(ele.id)}\n
\n
{\n e.preventDefault();\n e.stopPropagation();\n this.setState({isModalOpen: true});\n }}\n >\n

\n
\n
\n
\n
\n {ele.name || ele.machineHistory.Name}\n
\n
\n
{ele.result.FertiliserName}
\n
\n {ele.result.FertiliserShape}\n
\n
\n {\n [\n `${workingWidth} ${t('unit_distance')}`, \n `${drivingSpeed} ${t('unit_speed')}`,\n `${ele.result.FertiliserDensity} ${t('unit_density')}`\n ].join(', ')\n }\n
\n
\n
\n
\n
\n
;\n }\n}\n\nconst mapStateToProps = (state) => {\n return {\n t: selectors.getTranslations(state),\n };\n};\n\nconst actions = {\n favouriteRemoveAdvice\n};\n\nHistoryCard = connect(mapStateToProps, actions)(HistoryCard);\n\nclass TableHistory extends Component {\n render() {\n let {t, items, loadAdvice} = this.props;\n return \n { (items.length > 0) &&
\n
\n {\n items.sort((a, b) => b.id - a.id).map((ele, i) =>\n
\n \n
\n )}\n
\n
}\n { (items.length === 0) &&\n
\n {t('history_not_stored')}\n
}\n
\n }\n}\n\nexport default TableHistory;\n","import React, {Component} from 'react';\nimport {connect} from 'react-redux';\n\nimport * as utils from '../utils';\nimport * as selectors from '../store/selectors';\nimport {favouriteLoadAdvice} from '../store/actions/history';\nimport {newAdvice} from '../store/actions/currentadvice';\nimport {showModal, showHelp} from '../store/actions/app';\nimport './scss/home.scss';\n\nimport TableHistory from '../components/tablehistory';\nimport VideoList from '../components/videolist';\nimport icons from '../components/img/icons';\n\n\nclass Home extends Component {\n\n loadAdvice(id) {\n const {match, history, favouriteLoadAdvice} = this.props;\n favouriteLoadAdvice(id);\n history.push(`/${match.params.brand}/advice/5/`);\n }\n\n newAdvice() {\n const {match, history, newAdvice} = this.props;\n newAdvice();\n history.push(`/${match.params.brand}/advice/2/`);\n }\n\n formatDate(dt) {\n const date = utils.formatDate(dt);\n const hour = utils.formatHour(dt);\n return date + ' ' + hour;\n }\n\n render() {\n const {t, items, match, showHelp, legalLinks} = this.props;\n const {brand} = match.params;\n const title = t('app_title').replace('[Brand.Name]', brand);\n const path = `${window['DATA'].api_url}/2011/v1/NA/Images/Banners/`;\n\n return \n
\n
\n
\n
\n
\n {title}\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
this.loadAdvice(id)}/>\n \n \n
\n
\n
\n }\n}\n\nconst mapStateToProps = (state) => {\n let units = selectors.getCurrentUnits(state);\n\n return {\n t: selectors.getTranslations(state),\n items: selectors.getFavourites(state, units),\n brand: selectors.getBrand(state),\n legalLinks: selectors.getLegalLinks(state)\n };\n}\nconst actions = {\n favouriteLoadAdvice,\n newAdvice,\n showModal,\n showHelp\n};\nHome = connect(mapStateToProps, actions)(Home);\nexport default Home;\n","export default __webpack_public_path__ + \"static/media/facebook_button.c5908aec.png\";","export default __webpack_public_path__ + \"static/media/twitter_button.abdf9c8a.png\";","export default __webpack_public_path__ + \"static/media/youtube_button.aadee1b8.png\";","export default __webpack_public_path__ + \"static/media/instagram_button.28c77ba1.svg\";","import React, { Component } from 'react';\nimport {connect} from 'react-redux';\n\nimport * as utils from '../utils';\nimport * as selectors from '../store/selectors';\nimport {fetchRessellers} from '../store/actions/ressellers';\n\nimport HeaderImage from '../components/headerimage';\nimport faceImg from './img/facebook_button.png';\nimport twitImg from './img/twitter_button.png';\nimport youtbImg from './img/youtube_button.png';\nimport instagramImg from './img/instagram_button.svg';\n\nimport './scss/contact.scss';\n\n\nclass Contact extends Component {\n\n componentDidMount() {\n if(this.props.ressellers===null) {\n this.props.fetchRessellers();\n }\n utils.bodyClassList().add('whiteBackground');\n }\n componentWillUnmount() {\n utils.bodyClassList().remove('whiteBackground');\n }\n\n componentWillReceiveProps(props) {\n if(props.ressellers===null && this.props.ressellers!==null) {\n this.props.fetchRessellers();\n }\n }\n\n render () {\n let {t, match, ressellers} = this.props;\n\n if(ressellers===null){\n return null;\n }\n\n return \n
\n
\n
\n { ressellers.map((ite, i)=>\n
\n
{ite.Company}
\n
\n
\n { (ite.Phone) && - \n {t('contact_telephone')}\n {ite.Phone}\n
}\n { (ite.Email) && - \n {t('contact_email')}\n {ite.Email}\n
}\n { (ite.Web) && - \n {t('contact_web')}\n {ite.Web}\n
}\n
\n
)}\n
\n
\n {(ressellers[0].Facebook || ressellers[0].Twitter || ressellers[0].Youtube) &&\n
{t('social_media')}
}\n { (ressellers[0].Facebook) &&
\n
\n }\n { (ressellers[0].Twitter) &&
\n
\n }\n { (ressellers[0].Youtube) &&
\n
\n }\n { (ressellers[0].Instagram) &&
\n
\n }\n
\n
\n
\n }\n}\n\nconst mapStateToProps = (state) => {\n return {\n t: selectors.getTranslations(state),\n ressellers: selectors.getRessellers(state)\n };\n}\nconst actions = {\n fetchRessellers\n}\nContact = connect(mapStateToProps, actions)(Contact);\nexport default Contact;\n","import * as constants from '../constants';\nimport * as Api from '../../api';\nimport * as selectors from '../../store/selectors';\nimport {trackError, preloadStarted, preloadFinished} from './app';\n\n\nconst fetchRessellersStarted = () => ({\n type: constants.FETCH_RESSELLERS_STARTED,\n});\nconst fetchRessellersSuccess = (ressellers) => ({\n type: constants.FETCH_RESSELLERS_SUCCESS,\n payload: ressellers\n});\nexport const fetchRessellers = () => (dispatch, getState) => {\n dispatch(preloadStarted());\n dispatch(fetchRessellersStarted());\n let lang = selectors.getCurrentLanguageCode(getState()),\n units = selectors.getCurrentUnits(getState()),\n brand = selectors.getBrand(getState());\n return Api.getRessellers(lang, brand, units)\n .then((r) => {\n dispatch(preloadFinished());\n return dispatch(fetchRessellersSuccess(r));\n })\n .catch(err => dispatch(trackError(err)));\n}\n\n","import React, {Component} from 'react';\nimport {connect} from 'react-redux';\n\nimport {fetchSharedResult} from '../store/actions/currentadvice';\n\n\nclass SharedAdvice extends Component {\n componentDidMount() {\n const {history} = this.props;\n const params = Object.fromEntries(new URLSearchParams(history.location.search));\n if(params)\n this.fetchResult(params); \n }\n\n componentWillUnmount() {\n }\n\n redirectTo(step) {\n let {match, history} = this.props;\n history.push(`/${match.params.brand}/advice/${step}/`);\n\n }\n componentWillReceiveProps(nextProps, nextContext) {\n if(nextProps.result) {\n this.redirectTo(5);\n }\n } \n\n fetchResult = (data) => {\n this.props.fetchSharedResult(data);\n };\n\n render() {\n\n if(!this.props.result)\n return \n\n return \n }\n}\n\nconst mapStateToProps = (state) => {\n return {\n result: state.currentAdvice.result,\n };\n};\n\nconst actions = {\n fetchSharedResult\n};\n\nSharedAdvice = connect(mapStateToProps, actions)(SharedAdvice);\n\nexport default SharedAdvice;\n","import React from 'react';\n\nimport './scss/preloading.scss';\n\nconst Preloading = () =>\n \n \n
\n\nexport default Preloading;\n","import React, {Component} from 'react';\n\nimport './scss/disclaimer.scss';\n\n\nclass Disclaimer extends Component {\n\n state = {bottomReached: false, windowHeight:null};\n\n componentDidMount() {\n let {scrollHeight} = this.refs.scrolling;\n let {height} = this.refs.scrolling.getBoundingClientRect();\n if(scrollHeight<=height) {\n this.setState({bottomReached: true})\n } else {\n this.refs.scrolling.addEventListener('scroll', this.trackScrolling);\n }\n document.getElementsByTagName(\"body\")[0].classList.add('hideScroll');\n this.setState({ windowHeight: window.innerHeight })\n }\n componentWillUnmount() {\n this.refs.scrolling.removeEventListener('scroll', this.trackScrolling);\n document.getElementsByTagName(\"body\")[0].classList.remove('hideScroll');\n }\n\n trackScrolling = (e) => {\n let {scrollHeight, scrollTop} = e.target;\n let {height} = e.target.getBoundingClientRect();\n let scrollable = scrollHeight-height;\n if(scrollable-10\n \n \n
{t('disclaimer_title')}
\n
\n
\n
\n \n }\n}\n\nexport default Disclaimer;\n","export default __webpack_public_path__ + \"static/media/vicon-slogan.266f7750.png\";","import React, {Component} from 'react';\nimport {NavLink} from 'react-router-dom';\nimport * as constants from '../store/constants';\n\nimport './scss/menu.scss';\n\nimport sVicon from './img/vicon-slogan.png';\nimport sKverneland from './img/kverneland-slogan.png';\n\nconst slogans = {kverneland: sKverneland, vicon:sVicon};\n\nexport default class Menu extends Component {\n\n state = {menuVisible: false}\n\n toggleMenu() {\n let {menuVisible} = this.state;\n this.setState({menuVisible:!menuVisible});\n }\n\n closeMenu() {\n this.setState({menuVisible:false});\n }\n\n render() {\n let {brand, t, showHelp, platform} = this.props;\n let {menuVisible} = this.state;\n\n return