diff --git a/src/components/tools/Background.jsx b/src/components/tools/Background.jsx index 3d46d7c4..4919e2ac 100644 --- a/src/components/tools/Background.jsx +++ b/src/components/tools/Background.jsx @@ -1,15 +1,14 @@ -import '../../less/toolSketch.less'; - import React from 'react'; import { pure } from 'recompose'; +import {Container, Header, Image} from "semantic-ui-react"; export default pure( ({image}) => { return (
-

Background

-
- -
+
Background
+ + +
); } ); diff --git a/src/components/tools/Parameters.jsx b/src/components/tools/Parameters.jsx index fa54d737..e30043cb 100644 --- a/src/components/tools/Parameters.jsx +++ b/src/components/tools/Parameters.jsx @@ -1,95 +1,97 @@ -/* eslint-disable react/no-multi-comp */ import React from 'react'; import {pure} from 'recompose'; import PropTypes from 'prop-types'; import {inputType} from '../../inputType'; -import '../../less/toolParameters.less'; -import '../../less/input-range.less'; - import ParameterSlider from '../../core/parameterSlider'; +import {Button, Grid, Input} from "semantic-ui-react"; -const renderParam = (param, handleChange) => { - if (!param.inputType) { - return (); - } +class Parameters extends React.Component { - switch (param.inputType) { - case inputType.NUMBER: - return renderNumber(param, handleChange); - case inputType.RADIO_SELECT: - return renderRadioSelect(param, handleChange); - case inputType.SLIDER: - return (); + constructor(props) { + super(props); } - return null; -}; - -const renderNumber = (param, handleChange) => { - return ( - {param.label} - - - - ); -}; - + renderParam = param => { + if (!param.inputType) { + return ( + + ); + } -const renderRadioOption = (param, option, handleChange) => { - return (); -}; + switch (param.inputType) { + case inputType.NUMBER: + return this.renderNumber(param); + case inputType.RADIO_SELECT: + return this.renderRadioSelect(param); + case inputType.SLIDER: + return (); + } -const renderRadioSelect = (param) => { - const options = param - .options - .map(option => { - return renderRadioOption(param, option); + return null; + }; + + renderNumber = param => { + return ( + + {param.label} + + + + + ); + }; + + + renderRadioOption = (param, option) => { + return ( + + ); + }; + + renderRadioSelect = (param) => { + const options = param + .options + .map(option => { + return this.renderRadioOption(param, option); + }); + + return ( + + {param.label} + {options} + + ); + }; + + render() { + const sortedParameters = this.props.parameters.sort((a, b) => { + if (a.order > b.order) { + return 1; + } + return -1; }); - return ( - {param.label} - {options} - ); -}; + const params = sortedParameters.map(param => { + return this.renderParam(param, this.props.handleChange); + }); -const Parameters = ({parameters, handleChange, handleReset}) => { - const sortedParameters = parameters.sort((a, b) => { - if (a.order > b.order) { - return 1; - } - return -1; - }); - - const params = sortedParameters.map(param => { - return renderParam(param, handleChange); - }); - - return ( -
-
- - - {params} - -
-
- -
-
    -
  • - -
  • -
-
-
- ); -}; + return ( + + + + + + + {params} + + + ); + }; +} Parameters.propTypes = { handleChange: PropTypes.func.isRequired, diff --git a/src/containers/Navbar.jsx b/src/containers/Navbar.jsx index 9142aed8..17c5a2bf 100644 --- a/src/containers/Navbar.jsx +++ b/src/containers/Navbar.jsx @@ -1,12 +1,20 @@ -import '../less/navbar.less'; - -import PropTypes from 'prop-types'; import React from 'react'; - -import Icon from '../components/primitive/Icon'; -import {Link} from 'react-router'; +import PropTypes from 'prop-types'; +import {Dropdown, Icon, Menu} from "semantic-ui-react"; +import {Link, withRouter} from 'react-router'; import {connect} from 'react-redux'; -import {withRouter} from 'react-router'; + +const styles = { + navBar: { + borderRadius: 0, + padding: '0 101.5px 0 101.5px', + position: 'fixed', + top: 0, + left: 0, + right: 0, + zIndex: 1200 + } +}; class NavBar extends React.Component { @@ -36,21 +44,24 @@ class NavBar extends React.Component { } let navElement = ( - + {l.icon}{l.name} - + ); if (l.path) { navElement = ( - + {l.icon}{l.name} ); if (l.path.includes('http')) { navElement = ( - + {l.icon}{l.name} ); @@ -58,10 +69,12 @@ class NavBar extends React.Component { } return ( -
  • + //
  • +
    {navElement} {l.sub &&
      {this.renderLinks(l.sub, recursionDepth + 1)}
    } -
  • + + // ); }); } @@ -71,9 +84,9 @@ class NavBar extends React.Component { renderRoleSpecificItems = roles => { if (roles.includes('ROLE_ADMIN')) { return ( -
  • - -
  • + this.historyPushTo('/admin')}> + Admin + ); } @@ -84,35 +97,27 @@ class NavBar extends React.Component { const {roles, name} = this.props.user; if (userIsLoggedIn) { return ( -
  • - - {name} - -
      + + {this.renderRoleSpecificItems(roles)} -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    -
  • + this.historyPushTo('/credentials')}> + Change password + + this.historyPushTo('/profile')}> + Profile + + this.historyPushTo('/logout')}> + Logout + + + ); } + return ( -
  • - this.historyPushTo('/login')}> - Login - -
  • + this.historyPushTo('/login')}> + Login + ); } @@ -129,23 +134,14 @@ class NavBar extends React.Component { const userIsLoggedIn = this.props.session.apiKey; return ( -
    -
    - - - -
    -
    + + {this.renderLinks(standardLinks)} + {userIsLoggedIn && this.renderLinks(standardLinksAuthenticationRequired.concat(this.props.links))} + {!userIsLoggedIn && this.props.info && this.renderInfo(this.props.info)} + + {this.renderUserNavigation(userIsLoggedIn)} + + ); } } diff --git a/src/core/parameterSlider/SliderParameter.js b/src/core/parameterSlider/SliderParameter.js new file mode 100644 index 00000000..f8188815 --- /dev/null +++ b/src/core/parameterSlider/SliderParameter.js @@ -0,0 +1,163 @@ +import uuidv4 from 'uuid/v4'; + +class SliderParameter { + _decimals = 0; + _id = uuidv4(); + _label = ''; + _max = 10; + _min = 10; + _name = ''; + _order = 0; + _stepSize = 0.001; + _type = 'string'; + _validMax; + _validMin; + _value = 0; + + static fromObject(obj) { + const parameter = new SliderParameter(); + parameter.decimals = obj.decimals; + parameter.id = obj.id; + parameter.label = obj.label; + parameter.max = obj.max; + parameter.min = obj.min; + parameter.name = obj.name; + parameter.order = obj.order; + parameter.stepSize = obj.stepSize; + parameter.type = obj.type; + parameter.validMax = obj.validMax; + parameter.validMin = obj.validMin; + parameter.value = obj.value; + + return parameter; + } + + constructor() { + } + + get decimals() { + return this._decimals; + } + + set decimals(value) { + this._decimals = value ? parseInt(value, 10) : 0; + } + + get id() { + return this._id; + } + + set id(value) { + this._id = value ? value : uuidv4(); + } + + get label() { + return this._label; + } + + set label(value) { + this._label = value ? value : ''; + } + + get max() { + return this._max; + } + + set max(value) { + this._max = value ? this.parse(value) : 0; + } + + get min() { + return this._min; + } + + set min(value) { + this._min = value ? this.parse(value) : 0; + } + + get name() { + return this._name; + } + + set name(value) { + this._name = value ? value : ''; + } + + get order() { + return this._order; + } + + set order(value) { + this._order = value ? value : 0; + } + + get stepSize() { + return this._stepSize; + } + + set stepSize(value) { + this._stepSize = value ? this.parse(value) : 1; + } + + get type() { + return this._type; + } + + set type(value) { + this._type = value ? value : 'string'; + } + + get validMax() { + return this._validMax; + } + + set validMax(value) { + this._validMax = value ? value : null; + } + + get validMin() { + return this._validMin; + } + + set validMin(value) { + this._validMin = value ? value : null; + } + + get value() { + return this._value; + } + + set value(value) { + this._value = value ? this.parse(value) : null; + } + + get toObject() { + return ({ + decimals: this.decimals, + id: this.id, + label: this.label, + max: this.max, + min: this.min, + name: this.name, + order: this.order, + stepSize: this.stepSize, + type: this.type, + validMax: this.validMax, + validMin: this.validMin, + value: this.value + }); + } + + parse(value) { + if (this.type === 'integer') { + return parseInt(value, 10); + } + if (this.type === 'float') { + return parseFloat(value); + } + + return value; + } +} + +export default SliderParameter; diff --git a/src/core/parameterSlider/index.js b/src/core/parameterSlider/index.js index 8a63d13a..5bdbeb62 100644 --- a/src/core/parameterSlider/index.js +++ b/src/core/parameterSlider/index.js @@ -1,93 +1,103 @@ import React from 'react'; import PropTypes from 'prop-types'; -import HtmlLabel from '../../components/primitive/HtmlLabel'; +import {Grid, Input} from "semantic-ui-react"; + +import Slider from 'rc-slider'; +import SliderParameter from "./SliderParameter"; + +const styles = { + extraMini: { + width: '100px' + } +}; class ParameterSlider extends React.Component { constructor(props) { super(props); this.state = { - param: props.param, - localChange: false + param: props.param.toObject }; } componentWillReceiveProps(nextProps) { - const param = { - ...nextProps.param, - value: Number(nextProps.param.value).toFixed(nextProps.param.decimals) - }; - this.setState({ ...this.state, - param, - localChange: false + param: nextProps.param.toObject }); } handleLocalChange = ({target}) => { const {value, name} = target; + const param = SliderParameter.fromObject(this.state.param); - let param; - if (name.endsWith('value')) { - param = {...this.state.param, value}; - } + param[name] = value; - if (name.endsWith('min')) { - param = {...this.state.param, min: value}; - } + this.setState({ + param: param.toObject + }); + }; - if (name.endsWith('max')) { - param = {...this.state.param, max: value}; - } + handleSlider = value => { + const param = SliderParameter.fromObject(this.state.param); + param.value = value; - this.setState({param, localChange: false}); + return this.setState({ + param: param + }); }; + handleChange = () => this.props.handleChange(SliderParameter.fromObject(this.state.param)); + render() { - const {handleChange} = this.props; const {param} = this.state; - // Should do some refactoring - if (!param.label && param.name) { - param.label = param.name; - } - - let disable = false; - if (param.disable) { - disable = param.disable; - } - return ( - - - - - - - - - - - - - + + {param.name} + + + + + + + + + + + + + + + + + + - - + + ); } } @@ -97,4 +107,4 @@ ParameterSlider.propTypes = { handleChange: PropTypes.func.isRequired }; -export default ParameterSlider; +export default ParameterSlider; \ No newline at end of file diff --git a/src/dashboard/container/Dashboard.jsx b/src/dashboard/container/Dashboard.jsx index e71ce4a4..32ef239a 100644 --- a/src/dashboard/container/Dashboard.jsx +++ b/src/dashboard/container/Dashboard.jsx @@ -1,7 +1,4 @@ -import '../../less/dashboard.less'; - import ConfiguredRadium from 'ConfiguredRadium'; - import React from 'react'; import PropTypes from 'prop-types'; @@ -10,59 +7,38 @@ import {loadInstances} from '../actions/queries'; import {getTool, getTools} from '../selectors/tool'; import {getActiveToolSlug, getPublic} from '../selectors/ui'; -import Button from '../../components/primitive/Button'; import {Formatter} from '../../core'; -import Icon from '../../components/primitive/Icon'; -import Input from '../../components/primitive/Input'; -import Menu from '../../components/primitive/Menu'; import Navbar from '../../containers/Navbar'; -import Table from '../../components/primitive/table/Table'; -import Td from '../../components/primitive/table/Td'; -import Tr from '../../components/primitive/table/Tr'; import {connect} from 'react-redux'; -import styleGlobals from 'styleGlobals'; import {includes} from 'lodash'; import {withRouter} from 'react-router'; +import {Button, Container, Grid, Header, Icon, Menu, Popup, Table} from "semantic-ui-react"; const styles = { - menu: { - width: - 2 * styleGlobals.dimensions.gridColumn + - styleGlobals.dimensions.gridGutter, - marginRight: styleGlobals.dimensions.gridGutter + actionWrapper: { + position: 'absolute', + right: 10, }, - - linkActive: { - textDecoration: 'underline' + wrapper: { + padding: '0 40px 0 40px', + width: '1280px' }, - - lastTd: { - position: 'relative', - width: 0, - padding: 0 + columnPadding: { + padding: '12px' }, - - actionWrapper: { - position: 'absolute', - right: 0, - width: 500 + columnContainer: { + background: '#fff', + boxShadow: '0 1px 2px 0 rgba(34, 36, 38, 0.15)', + border: '1px solid rgba(34, 36, 38, 0.15)', + borderRadius: '.28571429rem', + height: '100%', }, - - actionContent: { - paddingLeft: 50, - paddingTop: styleGlobals.dimensions.spacing.small, - paddingRight: styleGlobals.dimensions.spacing.small, - paddingBottom: styleGlobals.dimensions.spacing.small - 1, - background: - 'linear-gradient(to right, transparent, ' + - styleGlobals.colors.background + - ' 50px)', - float: 'right' + menu: { + width: '100%' }, - - action: { - marginLeft: styleGlobals.dimensions.spacing.large + grid: { + marginTop: '25px' } }; @@ -78,7 +54,7 @@ class Dashboard extends React.Component { { name: 'Datasets', path: 'https://kb.inowas.hydro.tu-dresden.de', - icon: + icon: } ], hoveredInstance: null @@ -117,73 +93,76 @@ class Dashboard extends React.Component { }; renderTableRows(basePath, subPath, instances) { - // eslint-disable-next-line no-shadow const {publicInstances, cloneToolInstance, deleteToolInstance} = this.props; const {push} = this.props.router; return instances.map((i, index) => { return ( - - this.setState({hoveredInstance: index})} - onMouseLeave={() => - this.setState({hoveredInstance: null})} + onMouseEnter={() => this.setState({hoveredInstance: index})} + onMouseLeave={() => this.setState({hoveredInstance: null})} > - + {index + 1} - - + + - - + + {i.tool} - - + + {Formatter.dateToDatetime(new Date(i.created_at))} - - + + {i.user_name} - - + + {(() => { if (this.state.hoveredInstance === index) { return ( -
    -
    - {!i.fake && - } - {!i.fake && - !publicInstances && - } -
    -
    + + {!i.fake && + cloneToolInstance(i.id)} + icon + > + + + } + content='Clone' + /> + } + {!i.fake && + !publicInstances && + deleteToolInstance(i.id)} + icon + > + + + } + content='Delete' + /> + } + ); } - return null; })()} - - +
    + ); }); } @@ -192,68 +171,66 @@ class Dashboard extends React.Component { // eslint-disable-next-line no-shadow const {activeTool, setPublic, publicInstances} = this.props; const {push} = this.props.router; + return ( -
    -

    - Instances of {activeTool.slug} -

    -
    -
    - -
    -
      -
    • - -
    • -
    -
      -
    • + > + + Add new + + + + -
    • -
    • + -
    • -
    -
    - - - - - - - - - - - - - {this.renderTableRows( - activeTool.path, - activeTool.subPath, - activeTool.instances - )} - -
    No.NameToolDate createdCreated by -
    -
    + + + + + + + + + No. + Name + Tool + Date created + Created by + + + + + {this.renderTableRows( + activeTool.path, + activeTool.subPath, + activeTool.instances + )} + +
    +
    +
    + ); } @@ -264,7 +241,7 @@ class Dashboard extends React.Component { const menuItems = [ { name: 'Tools', - icon: , + icon: , items: tools.filter(t => includes(roles, t.role)) .map(t => { return { @@ -277,18 +254,34 @@ class Dashboard extends React.Component { ]; return ( -
    + -
    - {' '} - {this.renderDataTable()} -
    -
    + + + + {menuItems.map((category, key) => +
    + {category.name} + {category.items.map((item, key) => + + {item.name} + + )} +
    + )} +
    +
    + + + {this.renderDataTable()} + + +
    + ); } } diff --git a/src/less/button.less b/src/less/button.less index 3524f038..e69de29b 100644 --- a/src/less/button.less +++ b/src/less/button.less @@ -1,43 +0,0 @@ -@import "variables.less"; - -.button { - padding: @spacing-small @spacing-regular; - border: 0; - border-radius: @border-radius; - background-color: @background-dark; - color: @color-dark; - cursor: pointer; - text-decoration: none; - - &.icon-inside { - padding: @spacing-small; - } - - &:hover, - &:focus { - background-color: darken(@background-dark, 15%); - } - -} - -.button.is-disabled { - background-color: @background-dark; -} - -.button-accent { - background-color: @accent; - - &:hover, - &:focus { - background-color: darken(@accent, 15%); - } -} - -.button-primary { - background-color: @primary; - - &:hover, - &:focus { - background-color: darken(@primary, 15%); - } -} diff --git a/src/less/footer.less b/src/less/footer.less index 47efa8f1..bdad7fb7 100644 --- a/src/less/footer.less +++ b/src/less/footer.less @@ -6,7 +6,6 @@ margin-top: @grid-gutter; padding-top: @spacing-large; padding-bottom: @spacing-large; - z-index: 1; .content { overflow: visible; diff --git a/src/less/icon.less b/src/less/icon.less index 32cd4b51..baeb9c35 100644 --- a/src/less/icon.less +++ b/src/less/icon.less @@ -6,8 +6,6 @@ vertical-align: middle; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - height: 1.25em; - width: 1.25em; display: inline-block; vertical-align: baseline; diff --git a/src/less/input.less b/src/less/input.less index d4074f6a..e69de29b 100644 --- a/src/less/input.less +++ b/src/less/input.less @@ -1,40 +0,0 @@ -.input-max, -.input { - background-color: @grey-bright; - border: 0; - padding: @spacing-small @spacing-regular; - border-radius: @border-radius; -} -.input:out-of-range{ - //background-color: @warning-red; -} -.input-max:hover, -.input-max:focus, -.input:hover, -.input:focus { - box-shadow: @box-shadow-accent; -} - -.input-max:disabled{ - visibility: hidden; -} - -.input-xs { - padding: 0; -} - -.input-on-focus { - border: 0; - background: transparent; - padding: @spacing-small @spacing-regular; -} - -.input-on-focus:focus { - background-color: @grey-bright; - border-radius: @border-radius; -} - -// TODO do it better ;-) -.form-group label, .form-group input, .form-group select, .form-group textarea { - width:100%; -} diff --git a/src/less/popup.less b/src/less/popup.less index e487de17..e69de29b 100644 --- a/src/less/popup.less +++ b/src/less/popup.less @@ -1,19 +0,0 @@ -@import 'variables.less'; - -.popup { - position: fixed; - z-index: 1100; - left: 0; - top: 0; - right: 0; - bottom: 0; - background-color: fade(@grey-dark, 70%); - - .content { - width: 3 * @grid-column + 2 * @grid-gutter; - - .header { - text-align: right; - } - } -} diff --git a/src/less/select.less b/src/less/select.less index 1b7141f7..e69de29b 100644 --- a/src/less/select.less +++ b/src/less/select.less @@ -1,17 +0,0 @@ -@import "variables.less"; - -.select { - background: @grey-bright; - border-radius: @border-radius; - border: 0; - padding: @spacing-small @spacing-regular; - - &.block { - width: 100%; - } - - option { - border: 0; - background: @grey-semi-bright; - } -} diff --git a/src/less/table.less b/src/less/table.less index 8bf0d4ba..9d2e9a77 100644 --- a/src/less/table.less +++ b/src/less/table.less @@ -1,67 +1,9 @@ @import "variables.less"; .table { - width: 100%; - max-width: 100%; - border-spacing: 0; - border-collapse: collapse; - - thead tr { - border-bottom: 1px solid @grey-dark; - display: table; - table-layout: fixed; - } - - tbody tr { - border-bottom: 1px solid @grey-semi-bright; - display: table; - table-layout: fixed; - } - - tbody tr.error-row { - background-color: @warning-red; - } - - thead { - flex: 0 0 auto; - width: 100%; - tr { - width: calc(100% - 0.9em); /* 0.9em approximates scrollbar width */ - display: table; - } - } - - tbody { - display: block; - flex: 1 1 auto; - overflow-y: scroll; - - tr { - width: 100%; - } - - tr.selected-row { - } - } - - td, - th { - padding: @spacing-small; - vertical-align: top; - text-align: left; - } - - th { - font-weight: 700; - } - - td { - font-weight: 300; - } - .sort { cursor: pointer; - cursor: hand; + } .sort-order { display:none; diff --git a/src/t01/components/chart.jsx b/src/t01/components/chart.jsx index 9b1ef51a..917f3cef 100644 --- a/src/t01/components/chart.jsx +++ b/src/t01/components/chart.jsx @@ -2,12 +2,28 @@ import React from 'react'; import PropTypes from 'prop-types'; import {pure} from 'recompose'; -import '../../less/toolDiagram.less'; - import {CartesianGrid, Legend, ResponsiveContainer, Scatter, ScatterChart, Tooltip, XAxis, YAxis} from 'recharts'; +import {Grid, Header} from "semantic-ui-react"; const cbPalette = ['#999999', '#E69F00', '#56B4E9', '#009E73', '#F0E442', '#0072B2', '#D55E00', '#CC79A7']; +const styles = { + diagram: { + position: 'relative' + }, + diagramXLabels: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center' + }, + diagramYLabels: { + position: 'absolute', + bottom: '170px', + left: '5px', + transform: 'rotate(-90deg)' + } +}; + const Chart = ({data}) => { const scatterLines = data.map(row => { if (row.selected) { @@ -31,10 +47,10 @@ const Chart = ({data}) => { return (
    -

    Infiltration capacity decline

    -
    -
    -
    +
    Infiltration capacity decline
    + + +
    @@ -46,11 +62,11 @@ const Chart = ({data}) => { {scatterLines} -
    V50/V50o
    -
    Specific volume (L/m2)
    +
    V50/V50o
    +
    Specific volume (L/m2)
    -
    -
    + +
    ); }; diff --git a/src/t01/components/info.jsx b/src/t01/components/info.jsx index 1464ce13..57885e91 100644 --- a/src/t01/components/info.jsx +++ b/src/t01/components/info.jsx @@ -39,7 +39,7 @@ const Info = ({data}) => { return (
    -
    Infiltration capacity reduction
    +
    Infiltration capacity reduction
    @@ -56,7 +56,7 @@ const Info = ({data}) => {
    -
    Proportion of infiltration capacity phases
    +
    Proportion of infiltration capacity phases
    diff --git a/src/t01/components/parameters.jsx b/src/t01/components/parameters.jsx index 81532d89..53ab1323 100644 --- a/src/t01/components/parameters.jsx +++ b/src/t01/components/parameters.jsx @@ -3,8 +3,6 @@ import React from 'react'; import {pure} from 'recompose'; import PropTypes from 'prop-types'; -import '../../less/toolParameters.less'; -import '../../less/input-range.less'; import {Button, Header} from 'semantic-ui-react'; import DataTable from './dataTable'; @@ -15,30 +13,29 @@ class Parameters extends React.Component { render() { return ( -
    -
    -
    Selected - -
    - r.selected === true)} - color={'red'} - icon={'trash'} - filter={false} - /> +
    +
    + Selected + +
    + r.selected === true)} + color={'red'} + icon={'trash'} + filter={false} + /> -
    - Data -
    - r.selected === false)} - color={'grey'} - icon={'add'} - filter={['hlr', 'hlc', 'time', 'k', 'climate', 'scale']} - /> -
    +
    + Data +
    + r.selected === false)} + color={'grey'} + icon={'add'} + filter={['hlr', 'hlc', 'time', 'k', 'climate', 'scale']} + />
    ); } diff --git a/src/t01/containers/main.js b/src/t01/containers/main.js index 3898fa88..273ed4ac 100644 --- a/src/t01/containers/main.js +++ b/src/t01/containers/main.js @@ -1,24 +1,25 @@ import React from 'react'; -import '../../less/4TileTool.less'; -import styleGlobals from 'styleGlobals'; import image from '../images/T01.png'; import {Background, Chart, Parameters, Info} from '../components'; -import Icon from '../../components/primitive/Icon'; import Navbar from '../../containers/Navbar'; import PapaParse from 'papaparse'; import csvFile from '../data/2018-10-25-mar-in-scales.csv'; +import {Container, Divider, Grid, Header, Icon} from "semantic-ui-react"; const styles = { - heading: { - borderBottom: '1px solid ' + styleGlobals.colors.graySemilight, - fontWeight: 300, - fontSize: 16, - textAlign: 'left', - paddingBottom: 10 + container: { + padding: '0 40px 0 40px', + width: '1280px' + }, + columnContainer: { + background: '#fff', + boxShadow: '0 0 2px 0 rgba(76, 76, 76, 0.3)', + height: '100%', + padding: '12px' } }; @@ -39,7 +40,7 @@ class T01 extends React.Component { const parsedFile = PapaParse.parse(csvFile, {header: true, dynamicTyping: true, skipEmptyLines: true}); return parsedFile.data.map((row, key) => { row.x = row.x.split(';').map(v => parseInt(v, 10)); - row.y = row.y.split(';').map(v => parseFloat(v, 10)); + row.y = row.y.split(';').map(v => parseFloat(v)); key < 3 ? row.selected = true : row.selected = false; return row; }); @@ -64,31 +65,41 @@ class T01 extends React.Component { render() { const {data} = this.state; return ( -
    + -

    T01. SAT basin infiltration capacity reduction database

    -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    +
    T01. SAT basin infiltration capacity reduction database
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); } } diff --git a/src/t02/components/chart.jsx b/src/t02/components/chart.jsx index 1666bc1b..20dbb736 100644 --- a/src/t02/components/chart.jsx +++ b/src/t02/components/chart.jsx @@ -3,8 +3,6 @@ import PropTypes from 'prop-types'; import {mounding} from 'gwflowjs'; import {pure} from 'recompose'; -import '../../less/toolDiagram.less'; - import { CartesianGrid, Line, @@ -14,6 +12,36 @@ import { XAxis, YAxis, } from 'recharts'; +import {Grid, Header} from "semantic-ui-react"; + +const styles = { + diagram: { + position: 'relative' + }, + diagramLabelsRight: { + position: 'absolute', + top: '20px', + right: '50px' + }, + diagramXLabels: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center' + }, + diagramYLabels: { + position: 'absolute', + bottom: '170px', + left: '5px', + transform: 'rotate(-90deg)' + }, + diagramLabel: { + textAlign: 'center', + background: '#EFF3F6', + opacity: 0.9, + padding: '5px', + margin: '5px' + } +}; const calculateDiagramData = (variable, w, L, W, hi, Sy, K, t, min, max, stepSize) => { const data = []; @@ -86,10 +114,10 @@ const Chart = ({settings, w, L, W, hi, Sy, K, t}) => { return (
    -

    Calculation

    -
    -
    -
    +
    Calculation
    + + +
    { dot={false}/> -
    +

    h - hi (m)

    -
    -
    -

    - hmax - = - {hMax.toFixed(2)} - m -

    +
    +
    + hmax={hMax.toFixed(2)}m
    -

    {xLabel}

    +

    {xLabel}

    -
    -
    + +
    ); }; diff --git a/src/t02/components/settings.jsx b/src/t02/components/settings.jsx index eb974d3a..05c05442 100644 --- a/src/t02/components/settings.jsx +++ b/src/t02/components/settings.jsx @@ -2,37 +2,38 @@ import React from 'react'; import {pure} from 'recompose'; import PropTypes from 'prop-types'; import {mounding} from 'gwflowjs'; +import {Form, Grid, Header, Radio} from "semantic-ui-react"; const Settings = ({settings, handleChange, w, L, W, hi, Sy, K, t}) => { const hhi = mounding.calculateHi(0, 0, w, L, W, hi, Sy, K, t); const hMax = (hhi + hi); return ( -
    -

    Settings

    -
    -

    Please select the axis for the calculation of groundwater mounding:

    -
    -
    -
    -
    - + +
    Settings
    +
    + +
    Please select the axis for the calculation of groundwater + mounding:
    +
    + +
    + + - -
    -
    - + + - -
    -
    -
    -
    -

    - The resulting groundwater mound is {hhi.toFixed(2)}m - and the groundwater level will rise up to {hMax.toFixed(2)}m.

    -
    -
    + + + + + The resulting groundwater mound is {hhi.toFixed(2)}m + and the groundwater level will rise up to {hMax.toFixed(2)}m. + +
    ); }; diff --git a/src/t02/containers/main.js b/src/t02/containers/main.js index 44b86abc..bdb22732 100644 --- a/src/t02/containers/main.js +++ b/src/t02/containers/main.js @@ -4,34 +4,31 @@ import {connect} from 'react-redux'; import {withRouter} from 'react-router'; import uuid from 'uuid'; -import '../../less/4TileTool.less'; -import styleGlobals from 'styleGlobals'; import image from '../images/T02.png'; import {Background, Chart, Parameters, Settings} from '../components'; -import {WebData, LayoutComponents} from '../../core'; +import {WebData} from '../../core'; -import Icon from '../../components/primitive/Icon'; import Navbar from '../../containers/Navbar'; -import Accordion from '../../components/primitive/Accordion'; -import AccordionItem from '../../components/primitive/AccordionItem'; -import Input from '../../components/primitive/Input'; -import Select from '../../components/primitive/Select'; -import Button from '../../components/primitive/Button'; import {Modifier as Dashboard} from '../../dashboard'; import {each} from 'lodash'; import {getInitialState} from '../reducers/main'; import applyParameterUpdate from '../../core/simpleTools/parameterUpdate'; import {isReadOnly} from '../../core/helpers'; +import {Accordion, Icon, Container, Divider, Grid, Header, Input, Form} from "semantic-ui-react"; +import SliderParameter from "../../core/parameterSlider/SliderParameter"; const styles = { - heading: { - borderBottom: '1px solid ' + styleGlobals.colors.graySemilight, - fontWeight: 300, - fontSize: 16, - textAlign: 'left', - paddingBottom: 10 + container: { + padding: '0 40px 0 40px', + width: '1280px' + }, + columnContainer: { + background: '#fff', + boxShadow: '0 0 2px 0 rgba(76, 76, 76, 0.3)', + height: '100%', + padding: '12px' } }; @@ -39,12 +36,12 @@ const buildPayload = (data) => { return { settings: data.settings, parameters: data.parameters.map(v => { - return { + SliderParameter.fromObject({ id: v.id, max: v.max, min: v.min, value: v.value, - }; + }).toObject; }) }; }; @@ -57,13 +54,15 @@ const navigation = [{ class T02 extends React.Component { + // TODO: get data from saved instance constructor() { super(); this.state = getInitialState(); + this.state.activeIndex = 0; } componentWillReceiveProps(newProps) { - this.setState(function(prevState) { + this.setState(function (prevState) { return { ...prevState, ...newProps.toolInstance, @@ -113,47 +112,32 @@ class T02 extends React.Component { }); } - handleInputChange = name => { - return value => { - this.setState(prevState => { - return { - ...prevState, - [ name ]: value - }; - }); + handleInputChange = (e, {name, value}) => this.setState(prevState => { + return { + ...prevState, + [name]: value }; - }; + }); - handleSelectChange = name => { - return data => { - this.handleInputChange(name)(data ? data.value : undefined); - }; - }; - - handleChange = (e) => { - if (e.target.name === 'variable') { - this.updateSettings(e.target.value); - } - - if (e.target.name.startsWith('parameter')) { - const param = e.target.name.split('_'); - - const parameter = {}; - parameter.id = param[1]; - parameter[param[2]] = e.target.value; - - this.updateParameter(parameter); - } + handleChange = parameter => { + this.updateParameter(parameter.toObject); }; handleReset = () => { this.setState(getInitialState()); }; + handleClickAccordion = (e, titleProps) => { + const {index} = titleProps; + const {activeIndex} = this.state; + const newIndex = activeIndex === index ? -1 : index; + + this.setState({activeIndex: newIndex}) + }; + render() { - const {settings, parameters, name, description} = this.state; - const {getToolInstanceStatus, updateToolInstanceStatus, createToolInstanceStatus, toolInstance} = this.props; - const {id} = this.props.params; + const {activeIndex, settings, parameters} = this.state; + const {getToolInstanceStatus, toolInstance} = this.props; const readOnly = isReadOnly(toolInstance.permissions); const chartParams = {settings}; @@ -161,92 +145,99 @@ class T02 extends React.Component { chartParams[v.id] = v.value; }); - const heading = ( -
    -
    - -
    -
    - - - -
    -
    - ); - return ( -
    + -

    - T02. Groundwater mounding (Hantush) -

    +
    T02. Groundwater mounding (Hantush)
    + -
    -
    - - - - - - - -
    -
    -
    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    - -
    - -
    -
    + + + + + + + + + + } + type="text" + disabled={readOnly} + name="name" + value={this.state.name} + onChange={this.handleInputChange} + placeholder="Name" + /> + + + + + + + +
    + + + +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + SliderParameter.fromObject(p))} + handleChange={this.handleChange} + handleReset={this.handleReset} + /> + + + +
    -
    + ); } } @@ -268,7 +259,7 @@ const mapDispatchToProps = (dispatch, props) => { for (const key in actions) { if (actions.hasOwnProperty(key)) { // eslint-disable-next-line no-loop-func - wrappedActions[key] = function() { + wrappedActions[key] = function () { const args = Array.prototype.slice.call(arguments); dispatch(actions[key](tool, ...args)); }; diff --git a/src/t02/reducers/main.js b/src/t02/reducers/main.js index 198129a8..3f2e5f93 100644 --- a/src/t02/reducers/main.js +++ b/src/t02/reducers/main.js @@ -18,6 +18,7 @@ export const getInitialState = () => { max: 10, value: 0.045, stepSize: 0.001, + type: 'float', decimals: 3 }, { order: 1, @@ -28,6 +29,7 @@ export const getInitialState = () => { max: 1000, value: 40, stepSize: 1, + type: 'float', decimals: 0 }, { order: 2, @@ -38,6 +40,7 @@ export const getInitialState = () => { max: 100, value: 20, stepSize: 1, + type: 'float', decimals: 0 }, { order: 3, @@ -48,6 +51,7 @@ export const getInitialState = () => { max: 100, value: 35, stepSize: 1, + type: 'float', decimals: 0 }, { order: 4, @@ -59,6 +63,7 @@ export const getInitialState = () => { validMax: (x) => x <= 0.5, value: 0.085, stepSize: 0.001, + type: 'float', decimals: 3 }, { order: 5, @@ -70,6 +75,7 @@ export const getInitialState = () => { validMax: x => x <= 100000, value: 1.83, stepSize: 0.01, + type: 'float', decimals: 2 }, { order: 6, @@ -80,6 +86,7 @@ export const getInitialState = () => { max: 100, value: 1.5, stepSize: 0.1, + type: 'float', decimals: 1 }] }; diff --git a/src/t03/components/optimization/OptimizationObjectives.jsx b/src/t03/components/optimization/OptimizationObjectives.jsx index b74ee8fb..dfbf13a6 100644 --- a/src/t03/components/optimization/OptimizationObjectives.jsx +++ b/src/t03/components/optimization/OptimizationObjectives.jsx @@ -155,225 +155,223 @@ class OptimizationObjectivesComponent extends React.Component { ]; return ( - - - - - {this.state.selectedObjective && - + } + + + + {!this.state.selectedObjective ? + : + - } - - - - {!this.state.selectedObjective ? - : - - } - - - - - {(!this.state.selectedObjective && (!this.state.objectives || this.state.objectives.length < 1)) && - -

    No optimization objectives

    -
    - } - {(!this.state.selectedObjective && this.state.objectives && this.state.objectives.length >= 1) && - - - - Name - Type - - - - - { - this.state.objectives.map((objective) => - - - this.onClickObjective(objective)}> - {objective.name} - - - {objective.type} - - - - - ) - } - -
    - } - {this.state.selectedObjective && -
    + } + + + + + {(!this.state.selectedObjective && (!this.state.objectives || this.state.objectives.length < 1)) && + +

    No optimization objectives

    +
    + } + {(!this.state.selectedObjective && this.state.objectives && this.state.objectives.length >= 1) && + + + + Name + Type + + + + + { + this.state.objectives.map((objective) => + + + this.onClickObjective(objective)}> + {objective.name} + + + {objective.type} + + + + + ) + } + +
    + } + {this.state.selectedObjective && + + + + + + + + + + - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + {this.state.selectedObjective.type !== 'distance' && +
    + + + + `${this.formatTimestamp(value)}`} /> - - - {this.state.selectedObjective.type !== 'distance' && -
    - - - - `${this.formatTimestamp(value)}`} - /> - - - - - - - - -
    - } - {this.state.selectedObjective.type === 'distance' && + + -

    Distance

    + - - - - - - - - - - +
    - } - +
    + } + {this.state.selectedObjective.type === 'distance' && + +

    Distance

    + + + + + + + + + + + + +
    } -
    -
    -
    -
    + + } + + + ); } }