diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 4f1ea73..91a5e59 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,428 +1,444 @@ + - - + + + - - + + + - + + + - + + + - - + + - - + + + - - + + - - + - - - - - + + - + - - + + + + + length console + opt true DEFINITION_ORDER - - - - - - + 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) => ); } handleChange(e) { this.props.onRateChange(e.target.value); } render() { const value = this.props.value; return (
Rate : {this.props.rate} {this.props.unit}
); } } class SelectorInput extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.listoptions = props.options.map((opt) => ); } handleChange(select) { this.props.onChange(select); } render() { const value = this.props.value; return (
{this.props.legend}
); } } class CheckboxInput extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state={checked:this.props.defaults}; } handleChange() { this.setState({checked: !this.state.checked}); this.props.onChange(!this.state.checked); } render() { return (
); } } class ButtonInput extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange() { this.props.onClick(this.props.n); } render() { return ( ); } } +class MenuInput extends React.Component { + constructor(props) { + super(props); + this.state={listoptions:this.makelist(props.options)}; + + } + + makelist(data){ + var listoptions=[]; + for (var i = 0; i < data.length; i++) { + listoptions.push({data[i].name}); + } + return listoptions; + } + + render() { + return ( +
+ +
+ {this.state.listoptions} +
+
+ ); + } +} // Outputs definition // --------------------- // --------------------- 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}
); } // Plugins definition // --------------------- // --------------------- 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 ( -
- {this.props.name} +
+
- - - - +
+
+ +
+ {/**/}
); } makecost(amount,rate) { - var total=(amount-this.props.data.AmountFree)*rate; + if (amount<=this.props.data.AmountFree){ + amount=0; + } + var total=amount*rate; total=tomoney(total); this.props.onCostChange(this.props.n,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]}); } render() { const Cat=this.state.Cat; const Amount = this.state.amount; const Rate=this.state.Rate; const Cost=this.makecost(Cat,Amount,Rate); return ( -
- {this.props.name} - +
+ +
+
- - +
+ +
- + {/**/}
); } makecost(cat,amount,rate) { - var total=cat+(amount-this.props.data.AmountFree)*rate; + if (amount<=this.props.data.AmountFree){ + amount=0; + } + var total=cat+amount*rate; total=tomoney(total); this.props.onCostChange(this.props.n,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]}); } 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.n,total); return total; } } +class NoneSelect extends React.Component { + constructor(props) { + super(props); + + } + + + render() { + const Cost=tomoney(0); + this.props.onCostChange(this.props.n,Cost); + + return (
+ Please select a provider in the list. + +
+ ); + } + +} + // Combine plugins // --------------------- // --------------------- class ProviderPluginsSelector extends React.Component { constructor(props) { super(props); this.handleCostChange = this.handleCostChange.bind(this); this.handleProviderChange = this.handleProviderChange.bind(this); this.handleEnableChange = this.handleEnableChange.bind(this); + this.handleAddPlugin = this.handleAddPlugin.bind(this); this.state={ selected:0, keys:this.ProvidersName(props.data), - enabled :false, + enabled :true, n:1, + cost:0, + prevcost:0, }; } handleCostChange(n,e) { // console.log("here n : "+n+" e = "+ e); if(! this.state.enabled){ e=0; } - this.props.handleCostChange(n,e); + if (this.state.prevcost != e ) { + this.setState({cost: e}); + this.setState({prevcost: e}); + + this.props.handleCostChange(n,e);} } handleProviderChange(e){ const select=this.state.keys.indexOf(e.target.value); this.setState({selected:select}); } handleEnableChange(e){ this.setState({enabled:e}); } + handleAddPlugin(n){ + this.props.handleAddPlugin(n); + } + + makemenu(data,n){ + if (((data.url != '')||(data.url==null))&&(n==0)) { + return (); + } + } + + makeinfo(selected,Cdata){ + if (selected>0){ + return ({this.state.keys[selected]} : {Cdata.name}); + } + } render() { // console.log("n= "+this.props.n) const Cmp=this.cmp2string(this.cmpdata(this.state.selected).style); const Cdata=this.cmpdata(this.state.selected); + const id=this.props.data.name.replace(/\s/g,'')+this.props.n; + const Cost=this.state.cost; + const selected=this.state.selected; + return( + +
- {this.props.data.name} -
- - -
-
-
- +
+
+
+
+ +
+ + {/*
+ +
*/} +
+
+
+ +
+ +
+
+
+ {this.makeinfo(selected,Cdata)} +
+
+ +
+
+ +
+ +
+ +
+
+ {this.makemenu(this.props.data,this.props.n)} +
+
+
+ -
- +
+
+ +
+
+
+ + +
+
+ {this.makemenu(Cdata,0)} +
+
+ +
+ +
+
+
-
); } - cmpdata(select){return this.props.data.data[select];} cmp2string(str){ switch (str) { case "AmountRatesCost" : return AmountRatesCost; case "CategoryCost" : return CategoryCost; case "CategoryAmountRatesCost" : return CategoryAmountRatesCost; + case "NoneSelect":return NoneSelect; } } ProvidersName(main){ var data=main.data; // console.log(data); var providers=[]; for (var i = 0; i < data.length; i++) { providers.push(data[i].provider); } return providers; } } class ManagePlugins extends React.Component{ constructor(props) { super(props); this.handleCostChange = this.handleCostChange.bind(this); this.handleAddPlugin = this.handleAddPlugin.bind(this); + this.handleRemovePlugin = this.handleRemovePlugin.bind(this); this.state={ n:1, 'varsum':{} }; } + handleRemovePlugin(key){ + const n=this.state.n+1; + this.setState({n:n}); + } handleAddPlugin(key){ - console.log("add : "+key); + const n=this.state.n+1; + this.setState({n:n}); } handleCostChange(name,e) { this.state.varsum[name]=e; this.props.handleCostChange(this.props.n,sum(this.state.varsum)); } render() { return( {(index) => } + n={index} handleCostChange={this.handleCostChange} handleAddPlugin={this.handleAddPlugin}/>} );} } class PluginsMain extends React.Component { constructor(props) { super(props); this.handleCostChange = this.handleCostChange.bind(this); this.state={'varsum':{}}; } handleCostChange(name,e) { // console.log("name"+name); this.state.varsum[name]=e; this.props.TotalCost(sum(this.state.varsum)); } render() { return( -
+
{(index) => }
); } } // --------------------- // --------------------- class Main extends React.Component { constructor(props) { super(props); this.handleCostChange = this.handleCostChange.bind(this); this.state={'total':0,'prevtotal':0}; } handleCostChange(total) { // console.log("there total : "+total ) if (this.state.prevtotal != total){ // console.log("updated :"+total); // console.log("prev :"+this.state.prevtotal); this.setState({'total':total}); this.setState({'prevtotal':total}); } } render() { return(
- - - +
+
+ +
+
+
+
+
+ Total Cost +
+
+ +
+
+ +
+
+
+
+ +
+

This service has been developed by ... 2018

+

Icons are from the Noun Project (Book by Randi NI, Storage by I Pitu, Database by Novalyi, data cloud by Vectors Market)

+
+
+
+
); } } // --------------------- // --------------------- -ReactDOM.render(
,document.getElementById('root')); \ No newline at end of file +ReactDOM.render(
,document.getElementById('root')); + diff --git a/js/data.js b/js/data.js index 4b16c17..c76808e 100644 --- a/js/data.js +++ b/js/data.js @@ -1,283 +1,332 @@ // Providers // ---------------------------------------------------- // ---------------------------------------------------- // Storage const NasEpfl = { style: "AmountRatesCost", provider : "EPFL-VPSI", name:'NAS', - url : '', + url : [ + {name:'VPSI-Website',url:'https://support.epfl.ch/help/epfl?id=epfl_service_status&service=49a363acdb34c700ef64731b8c96191f'} + ], 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 : "CHF / TB" }; + const SwitchEpfl = { style : 'CategoryCost', provider : "Switch-EPFL", name:'Online Storage', - url : '', + url : [ + {name:'Switch Website',url:'https://drive.switch.ch/'} + ], CatName:'Options', Cat:{ 'Cloud Based max 50GB':0, }, CatUnit:'CHF', }; const GoogleDriveEdu = { style : 'CategoryCost', provider : "Google Drive Educ", name:'Online Storage', - url : '', + url : [ + {name :'Google Education Page',url:'https://edu.google.com/?modal_active=none'} + ], CatName:'Options', Cat:{ 'Cloud Based illimited':0, }, CatUnit:'CHF', }; // ELN const SLIMSEpfl = { style:'CategoryAmountRatesCost', provider : "EPFL-LSIS", name:'SLIMS', - url : '', + url : [ + {name:'SLIMS on LSIS Website',url:'https://lsis.epfl.ch/page-140284-en.html'}, + {name:'SLIMS Cost on LSIS Website',url:'https://lsis.epfl.ch/cms/site/lsis/lang/en/lims'}, + {name: 'Genohm (SLIMS Company)',url:'https://www.genohm.com/'} + ], 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 : "CHF / TB" }; // Database const MysqlEpfl = { style : 'CategoryCost', provider : "EPFL-VPSI", name:'MySql', - url : '', + url : [ + {name:'EPFL VPSI ',url:'https://support.epfl.ch/epfl?id=epfl_service_status&service=eb026fa0db34c700ef64731b8c96198e'} + ], CatName:'Options', Cat:{ 'MySQL max 2GB':0, }, CatUnit:'CHF', }; // Repository const Zenodo = { style : 'CategoryCost', provider : "Zenodo-CERN", name:'Zenodo', - url : '', + url : [ + {name:'Zenodo Website',url:'https://www.zenodo.org/'}, + {name:'About Zenodo',url:'http://about.zenodo.org/'}, + ], CatName:'Options', Cat:{ 'Max 50GB per dataset':0, }, CatUnit:'CHF', }; const C4science = { style : 'CategoryCost', provider : "EPFL-SCITAS", name:'C4Science', - url : '', + url : [ + {name:'C4Science Website',url:'https://www.c4science.ch/'} + ], CatName:'Options', Cat:{ 'Free for text file':0, }, CatUnit:'CHF', }; const Github = { style: "AmountRatesCost", provider : "GitHub", name:'GitHub', - url : '', + url : [ + {name:'Github Website Pricing',url:'https://github.com/pricing'} + ], AmountName: "Number of user", AmountUnit: "User(s)", AmountMin : 1, AmountMax : 100, AmountStep : 1, AmountFree:0, AmountFreeCumulative:false, RateVar : true, RateName:'Plan', Rates:{ 'OpenSource project':0, 'Developer (for one user)':81.6, 'Team (min 5 users)':104.9, 'Business Cloud':244.7 }, RateUnit:'CHF / Users', }; const Bitbucket= { style: "AmountRatesCost", provider : "Bitbucket", name:'BitBucket', - url : '', + url : [ + {name:'Bitbucket Website Pricing',url:'https://bitbucket.org/product/pricing'} + ], AmountName: "Number of user", AmountUnit: "User(s)", AmountMin : 1, AmountMax : 100, AmountStep : 1, AmountFree:0, AmountFreeCumulative:false, RateVar : true, RateName:'Plan', Rates:{ 'Free (up to 5 users)':0, 'Standard for growing teams (min 5 users)':24, 'Premium for large teams (min 5 users)':60, }, RateUnit:'CHF / Users', }; const Gitlab= { style: "AmountRatesCost", provider : "Gitlab", name:'Gitlab', - url : '', + url : [ + {name:'Gitlab Website Pricing',url:'https://about.gitlab.com/pricing/'} + ], AmountName: "Number of user", AmountUnit: "User(s)", AmountMin : 1, AmountMax : 100, AmountStep : 1, AmountFree:0, AmountFreeCumulative:false, RateVar : true, RateName:'Plan', Rates:{ 'Core Self Hosted':0, 'Free Cloud Based' : 0, 'Starter Self Hosted':48, 'Bronze Cloud based':48, 'Premium Self Hosted':228, 'Silver Cloud Based':228 }, RateUnit:'CHF / Users', }; const Figshare = { style : 'CategoryCost', provider : "FigShare", name:'Figshare', - url : '', + url : [ + {name:'Figshare website',url:'https://figshare.com/'}, + {name:'Figshare Pricing',url:'https://www.g2crowd.com/products/figshare/pricing'} + ], CatName:'Options', Cat:{ 'Free 1GB':0, '10GB':96, '15GB':132, '20GB':180 }, CatUnit:'CHF', }; const Dryad = { style : 'CategoryAmountRatesCost', provider : "Dyrad", name:'Dyrad', - url : '', + url : [ + {name:'Dyrad Website Pricing',url:'https://datadryad.org/pages/payment'} +], CatName:'Options', Cat:{ 'up to 20GB if DPC covered':0, 'up to 20GB if no DPC covered':120 }, CatUnit:'CHF', AmountName: "Extra - Storage", AmountUnit: "GB", AmountMin : 0, AmountMax : 100, AmountStep : 10, AmountFree:0, AmountFreeCumulative:false, RateVar : true, RateName: 'ELN Storage', Rates : { 'Extra Storage': 50, }, RateUnit : "CHF / GB" }; // Categories definition // ---------------------------------------------------- // ---------------------------------------------------- +const NoneSelected={ + style: 'NoneSelect', + provider:'Select a provider', + name:'', + url:'', + +}; + const storage={ name : 'Active Storage', - icon : '', - url : '', + icon : 'storage.png', + url : [ + {name:'EPFL RDM',url:'https://researchdata.epfl.ch/work-with-data/storage/'} + ], intro :'', - data :[NasEpfl, + data :[NoneSelected, + NasEpfl, SwitchEpfl, GoogleDriveEdu + ] }; const ELN={ name : 'Electronic LabBook', - icon : '', - url : '', + icon : 'eln.png', + url : [ + {name: 'EPFL RDM',url:'https://researchdata.epfl.ch/work-with-data/active-data-management/'} + ], intro :'', - data :[SLIMSEpfl, + data :[NoneSelected, + SLIMSEpfl, ] }; const database={ name : 'Database', - icon : '', + icon : 'database.png', url : '', intro :'', - data :[MysqlEpfl, + data :[NoneSelected, + MysqlEpfl, ] }; const repository={ name : 'Repository', - icon : '', - url : '', + icon : 'repos.png', + url : [ + {name:'EPFL RDM WebPage',url:'https://researchdata.epfl.ch/publish-preserve/'} + ], intro :'', - data :[Zenodo, + data :[ + NoneSelected, + Zenodo, C4science, Github, Bitbucket, Gitlab, Figshare, Dryad, ] }; // Combine Categories // ---------------------------------------------------- // ---------------------------------------------------- const maincat={ data:[storage,ELN,database,repository] };