diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index c627478..e95c6af 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,300 +1,381 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
+
+
+
+ console
+
+
+
+
+
-
+
+
+
true
DEFINITION_ORDER
-
-
+
+
-
+
+
+
+
-
+
-
+
1535982823834
1535982823834
+
-
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
-
-
+
-
-
-
-
+
-
-
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
\ No newline at end of file
diff --git a/index.html b/index.html
index d7da9f1..2c659ad 100644
--- a/index.html
+++ b/index.html
@@ -1,64 +1,36 @@
Cost Calculator (alpha)
-
-
-
-
+
-
\ No newline at end of file
diff --git a/js/costcalc_main.js b/js/costcalc_main.js
index 428c29c..faadf97 100644
--- a/js/costcalc_main.js
+++ b/js/costcalc_main.js
@@ -1,248 +1,302 @@
'use strict';
function tonumeric (value) {
return parseFloat(
value.toString().replace(/[^0-9\.]+/g, '')
);
}
function tomoney(numeric) {
if (typeof numeric == 'string') {
numeric = parseFloat(numeric);
}
return numeric.toFixed(0).replace(/(\d)(?=(\d{3})+\.)/g, '$1,') + ' CHF';
}
function sum(obj) {
const val=Object.values(obj);
var total = 0;
for (var i = 0; i < val.length; i++) {
total = total + tonumeric(val[i]);
}
return total;
}
class AmountInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.props.onAmountChange(e.target.value);
}
render() {
const value = this.props.value;
return (
Amount : {value} {this.props.unit}
);
}
}
class RatesInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.listoptions = props.options.map((opt) =>
{opt});
}
handleChange(e) {
this.props.onRateChange(e.target.value);
}
render() {
const value = this.props.value;
return (
Rate : {this.props.rate} {this.props.unit}
);
}
}
class CostOutput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange() {
this.props.onCostChange(this.props.display);
}
render() {
return (
);
}
}
+function Textoutput(props){
+ return(
+
+ {props.text}
+
+ );
+}
class AmountRatesCost extends React.Component {
constructor(props) {
super(props);
this.state={amount : 1, SelectRate : 0 , Rate : this.props.data.Rates[Object.keys(this.props.data.Rates)[0]]};
this.handleAmountChange = this.handleAmountChange.bind(this);
this.handleRateChange = this.handleRateChange.bind(this);
}
handleAmountChange(amount) {
this.setState({amount: amount});
}
handleRateChange(select) {
this.setState({SelectRate: select});
this.setState({Rate: this.props.data.Rates[select]});
}
render() {
const Amount = this.state.amount;
const Rate=this.state.Rate;
const Cost=this.makecost(Amount,Rate);
return (
);
}
makecost(amount,rate) {
var total=amount*rate;
total=tomoney(total);
this.props.onCostChange(this.props.name,total);
return total;
}
}
class CategoryAmountRatesCost extends React.Component {
constructor(props) {
super(props);
this.state={SelectCat : 0, Cat : this.props.data.Cat[Object.keys(this.props.data.Cat)[0]],
amount : 1, SelectRate : 0 , Rate : this.props.data.Rates[Object.keys(this.props.data.Rates)[0]]};
this.handleCatChange = this.handleCatChange.bind(this);
this.handleAmountChange = this.handleAmountChange.bind(this);
this.handleRateChange = this.handleRateChange.bind(this);
// this.handleCostChange = this.handleCostChange.bind(this);
}
handleAmountChange(amount) {
this.setState({amount: amount});
}
handleRateChange(select) {
this.setState({SelectRate: select});
this.setState({Rate: this.props.data.Rates[select]});
}
handleCatChange(select) {
this.setState({SelectCat: select});
this.setState({Cat: this.props.data.Cat[select]});
}
// handleCostChange(total) {
// this.props.onCostChange(this.props.name,total);
// }
render() {
const Cat=this.state.Cat;
const Amount = this.state.amount;
const Rate=this.state.Rate;
const Cost=this.makecost(Cat,Amount,Rate);
return (
);
}
makecost(cat,amount,rate) {
var total=cat+amount*rate;
total=tomoney(total);
this.props.onCostChange(this.props.name,total);
return total;
}
}
+class CategoryCost extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state={SelectCat : 0, Cat : this.props.data.Cat[Object.keys(this.props.data.Cat)[0]]};
+ this.handleCatChange = this.handleCatChange.bind(this);
+
+ }
+
+
+ handleCatChange(select) {
+ this.setState({SelectCat: select});
+ this.setState({Cat: this.props.data.Cat[select]});
+ }
+ // handleCostChange(total) {
+ // this.props.onCostChange(this.props.name,total);
+ // }
+ render() {
+ const Cat=this.state.Cat;
+
+ const Cost=this.makecost(Cat);
+
+ return (
+
+
{this.props.name}
+
+
+
+
+ );
+ }
+ makecost(cat) {
+ var total=cat;
+ total=tomoney(total);
+ this.props.onCostChange(this.props.name,total);
+ return total;
+ }
+}
+
class PluginsMain extends React.Component {
constructor(props) {
super(props);
this.handleCostChange = this.handleCostChange.bind(this);
this.state={'varsum':{}};
}
handleCostChange(name,e) {
// this.props.costs{name:e};
this.state.varsum[name]=e;
this.props.TotalCost(sum(this.state.varsum));
}
render() {
return(
+
);
}
}
class Main extends React.Component {
constructor(props) {
super(props);
this.handleCostChange = this.handleCostChange.bind(this);
this.state={'total':0,'prevtotal':0};
}
handleCostChange(total) {
if (this.state.prevtotal != total){
// console.log("updated :"+total)
this.setState({'total':total});
this.setState({'prevtotal':total});
}
}
render() {
return(
);
}
}
ReactDOM.render(,document.getElementById('root'));
\ No newline at end of file
diff --git a/js/data.js b/js/data.js
new file mode 100644
index 0000000..db2e4d0
--- /dev/null
+++ b/js/data.js
@@ -0,0 +1,84 @@
+const NasEpfl = {
+ style: "AmountRatesCost",
+ provider : "EPFL-VPSI",
+ AmountName: "Amount",
+ AmountUnit: "TB",
+ AmountMin : 1,
+ AmountMax : 100,
+ AmountStep : 1,
+ AmountFree:1,
+ AmountFreeCumulative:false,
+ RateVar : true,
+ RateName : 'Performance',
+ Rates : {
+ 'Collaborative': 165,
+ 'On-line archive': 110,
+ 'Raw': 55
+ },
+ RateUnit : "TB / CHF"
+};
+
+const SLIMSEpfl = {
+ style:'CategoryAmountRatesCost',
+ provider : "EPFL-LSIS",
+ CatName:'PI Status',
+ Cat:{
+ 'Full Professor':3000,
+ 'Associate Professor':2000,
+ 'Tenure Track Assistant Professor or Core Facility':1000
+ },
+ CatUnit:'CHF',
+ AmountName: "Storage",
+ AmountUnit: "TB",
+ AmountMin : 1,
+ AmountMax : 100,
+ AmountStep : 1,
+ AmountFree:0,
+ AmountFreeCumulative:false,
+ RateVar : true,
+ RateName: 'ELN Storage',
+ Rates : {
+ 'Stored on EPFL Server': 300,
+ },
+ RateUnit : "TB / CHF"
+};
+
+const MysqlEpfl = {
+ style : 'CategoryCost',
+ provider : "EPFL-VPSI",
+ CatName:'Options',
+ Cat:{
+ 'MySQL max 2GB':0,
+ },
+ CatUnit:'CHF',
+};
+
+const Zenodo = {
+ style : 'CategoryCost',
+ provider : "Zenodo-CERN",
+ CatName:'Options',
+ Cat:{
+ 'Max 50GB per dataset':0,
+ },
+ CatUnit:'CHF',
+};
+
+const C4science = {
+ style : 'CategoryCost',
+ provider : "EPFL-SCITAS",
+ CatName:'Options',
+ Cat:{
+ 'Free for text file':0,
+ },
+ CatUnit:'CHF',
+};
+
+const Github = {
+ style : 'CategoryCost',
+ provider : "GitHub",
+ CatName:'Options',
+ Cat:{
+ 'Free for text file':0,
+ },
+ CatUnit:'CHF',
+};
\ No newline at end of file