diff --git a/.idea/webServers.xml b/.idea/webServers.xml
index f312376..5dd1bf4 100644
--- a/.idea/webServers.xml
+++ b/.idea/webServers.xml
@@ -1,18 +1,18 @@
-
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index a458a33..8f590ad 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,604 +1,646 @@
-
-
+
-
-
-
-
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
-
-
+
+
tip
tooltip
url
icon
props.data.
data
ButtonInput
TxtInput
numeric
here
if
UserCost
>
upd
rawexport
randomint
console
Url
Icon
Data
UserCostSelect
>
<
-
-
+
+
true
true
true
true
DEFINITION_ORDER
-
+
+
-
-
+
1535982823834
1535982823834
-
+
+
-
+
-
+
-
-
+
+
-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
\ No newline at end of file
diff --git a/js/costcalc_main.jsx b/js/costcalc_main.jsx
index c389ae0..8439a00 100644
--- a/js/costcalc_main.jsx
+++ b/js/costcalc_main.jsx
@@ -1,1320 +1,1327 @@
"use strict";
// Functions Tools
// ---------------------
// ---------------------
+
+// Function loop for ReactJS object
function Repeat(props) {
let items = [];
for (let i = 0; i < props.numTimes; i++) {
items.push(props.children(i));
}
return
{items}
;
}
+//Convert a str value to numeric
function tonumeric (value) {
return parseFloat(
value.toString().replace(/[^0-9\.]+/g, '')
);
}
+//Convert a numeric to moeney
function tomoney(numeric) {
if (typeof numeric == 'string') {
numeric = parseFloat(numeric);
}
return numeric.toFixed(0).replace(/(\d)(?=(\d{3})+\.)/g, '$1,') + ' '+MainData.Currency;
}
-
+//Return sum of an array
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;
}
+//Compare two objects return true if similar
Object.compare = function (obj1, obj2) {
//Loop through properties in object 1
for (var p in obj1) {
//Check property exists on both objects
if (obj1.hasOwnProperty(p) !== obj2.hasOwnProperty(p)) return false;
switch (typeof (obj1[p])) {
//Deep compare objects
case 'object':
if (!Object.compare(obj1[p], obj2[p])) return false;
break;
//Compare function code
case 'function':
if (typeof (obj2[p]) == 'undefined' || (p != 'compare' && obj1[p].toString() != obj2[p].toString())) return false;
break;
//Compare values
default:
if (obj1[p] != obj2[p]) return false;
}
}
//Check object 2 for any extra properties
for (var p in obj2) {
if (typeof (obj1[p]) == 'undefined') return false;
}
return true;
};
+
+//Return a random int
function randomint(not){
var rnd;
do {
rnd=Math.floor(Math.random() * 100);
var cont=false;
for (let i = 0; i < not.length ; i++) {
if (not[i]===rnd){
cont=true;
}
}
} while(cont);
return rnd;
}
// Inputs Definition
// ---------------------
// ---------------------
class AmountInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.props.onChange(e.target.value);
}
render() {
const value = this.props.value;
return (
{this.props.name}
Amount : {value} {this.props.unit}
);
}
}
class SelectorInput extends React.Component {
constructor(props) {
super(props);
// this.state={listoptions:this.makelist(props.options)};
this.handleChange = this.handleChange.bind(this);
}
rate(i){
return i;
}
makelist(data){
var listoptions=[];
for (var i = 0; i < data.length; i++) {
listoptions.push({data[i]} );
}
return listoptions;
}
handleChange(select) {
this.props.onChange(select.target.value);
}
makerate(){
if (this.props.rate!=null){
return( Rate : {this.props.rate} {this.props.unit} );}
}
maketitle(title){
const maxstr=20
if (title.length>maxstr){
title=title.substr(0,maxstr)+"...";
}
return title;
}
render() {
return (
{this.props.name}
{this.makerate()}
)
}
}
class MakeknowmoreInput extends React.Component {
constructor(props) {
super(props);
this.state={btnsize:20}
}
render() {
const data = this.props.data;
if (((data.Url !== '') )) {
// if (data.Url.length==1){
// return(
// } url={data.Url[0].Url}
// id="btn-plugin-knowmore"
// class="btn-primary btn-sm" tips={"Know more about " + data.Name}/>
// );
// }else {
return (} options={data.Url}
id="btn-plugin-knowmore"
class="btn-primary btn-sm" tips={"Know more about " + data.Name}/>);
//}
}
else{
return null
}
}
}
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 (
{this.props.name}
);
}
}
class ButtonHrefInput extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
{this.props.name}
);
}
}
class ButtonInputWpop extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state={target:"Modal"+this.props.idp};
}
handleChange() {
const out={n:this.props.n,target:this.state.target};
this.props.onClick(out);
}
render() {
return (
{this.props.name}
Are you sure you want to suppress this line ?
×
You are removing a item. Please confirm you want to suppress : {this.props.info}
Cancel
Yes I want to remove it
);
}
}
class ButtonInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange() {
this.props.onClick(this.props.n);
}
render() {
return (
{this.props.name}
);
}
}
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 (
);
}
}
class TxtInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.props.onChange(e.target.value);
}
render() {
return (
{this.props.name}
);
}
}
// 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.handleAmountChange = this.handleAmountChange.bind(this);
this.handleRateChange = this.handleRateChange.bind(this);
this.state={
Amount : 1,
SelectRate : 0 ,
Rate : this.props.data.Rates[Object.keys(this.props.data.Rates)[0]]
};
this.make_export();
}
handleAmountChange(amount) {
this.setState({Amount: amount});
}
handleRateChange(select) {
this.setState({SelectRate: select});
this.setState({Rate: this.props.data.Rates[Object.keys(this.props.data.Rates)[select]]});
}
make_export(){
this.export=[
{Name:"Amount",Value:this.state.Amount+" "+this.props.data.AmountUnit},
{Name:this.props.data.RateName,Value:Object.keys(this.props.data.Rates)[this.state.SelectRate]}
];
this.props.export(this.export);
}
componentDidUpdate(){
this.makecost(this.state.Amount,this.state.Rate);
this.make_export();
}
render() {
return (
);
}
makecost(amount,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.handleCatChange = this.handleCatChange.bind(this);
this.handleAmountChange = this.handleAmountChange.bind(this);
this.handleRateChange = this.handleRateChange.bind(this);
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.make_export();
}
handleAmountChange(amount) {
this.setState({Amount: amount});
}
handleRateChange(select) {
this.setState({SelectRate: select});
this.setState({Rate: this.props.data.Rates[Object.keys(this.props.data.Rates)[select]]});
}
handleCatChange(select) {
this.setState({SelectCat: select});
this.setState({Cat: this.props.data.Cat[Object.keys(this.props.data.Cat)[select]]});
}
make_export(){
this.export=[
{Name:this.props.data.CatName,Value:Object.keys(this.props.data.Cat)[this.state.SelectCat]},
{Name:"Amount",Value:this.state.Amount+" "+this.props.data.AmountUnit},
{Name:this.props.data.RateName,Value:Object.keys(this.props.data.Rates)[this.state.SelectRate]}
];
this.props.export(this.export);
}
componentDidUpdate(){
this.makecost(this.state.Cat,this.state.Amount,this.state.Rate);
this.make_export();
}
render() {
return (
);
}
makecost(cat,amount,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.handleCatChange = this.handleCatChange.bind(this);
this.state={SelectCat : 0,
Cat : this.props.data.Cat[Object.keys(this.props.data.Cat)[0]]
};
this.make_export();
}
handleCatChange(select) {
this.setState({SelectCat: select});
this.setState({Cat: this.props.data.Cat[Object.keys(this.props.data.Cat)[select]]});
}
make_export(){
this.export=[
{Name:this.props.data.CatName,Value:Object.keys(this.props.data.Cat)[this.state.SelectCat]},
];
this.props.export(this.export);
}
componentDidUpdate(){
this.makecost(this.state.Cat);
this.make_export();
}
render() {
return (
);
}
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);
this.export=[]
}
render() {
const Cost=tomoney(0);
this.props.onCostChange(this.props.n,Cost);
this.props.export(this.export);
return (
Please select a provider in the list.
);
}
}
class UserCost extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleProviderChange = this.handleProviderChange.bind(this);
this.handleServiceChange = this.handleServiceChange.bind(this);
this.state={total:0,
CostError:false,
ProviderError:true,
ServiceError:true,
};
this.export=[]
}
handleChange(value){
if (isNaN(value)||value===''){
this.setState({CostError: true});
value=0;
}else{
this.setState({CostError: false});
}
this.setState({total:value});
this.props.onCostChange(this.props.n,tomoney(value));
}
handleProviderChange(txt){
this.props.handleProviderChange(txt);
if(txt ===''){
this.setState({ProviderError: true});
}
else {
this.setState({ProviderError: false});
}
}
handleServiceChange(txt){
this.props.handleServiceChange(txt);
if(txt ===''){
this.setState({ServiceError: true});
}
else {
this.setState({ServiceError: false});
}
}
classtxt(error){
if(error){
return "is-invalid";
}
else {
return "is-valid";
}
}
render() {
this.props.export(this.export);
return (
);
}
}
// Combine plugins
// ---------------------
// ---------------------
class ProviderPluginsSelector extends React.Component {
constructor(props) {
super(props);
this.handleCostChange = this.handleCostChange.bind(this);
this.handleProviderChange = this.handleProviderChange.bind(this);
this.handleCommentChange = this.handleCommentChange.bind(this);
this.handleAddPlugin = this.handleAddPlugin.bind(this);
this.handleRmvPlugin = this.handleRmvPlugin.bind(this);
this.handleProviderChangetxt = this.handleProviderChangetxt.bind(this);
this.handleServiceChangetxt = this.handleServiceChangetxt.bind(this);
this.make_exportcmp = this.make_exportcmp.bind(this);
this.make_export = this.make_export.bind(this);
this.state={
selected:0,
keys:this.ProvidersName(props.data),
n:1,
cost:0,
comments:"",
Provider:"",
Name:"",
manualname:false,
show_plus:false,
exportcmp:"",
};
}
handleCostChange(n,e) {
if (this.state.cost !== e ) {
this.setState({cost: e});
this.props.handleCostChange(n,e);
}
}
handleProviderChange(select){
this.setState({selected:select});
if (select>0){
this.setState({show_plus:true});
}else {
this.setState({show_plus:false});
}
this.state.Provider=this.props.data.Data[select].Provider;
this.state.Name=this.props.data.Data[select].Name;
this.props.handleCostChange(this.props.n,this.state.cost);
}
componentDidUpdate(){
this.props.handleCostChange(this.props.n,this.state.cost);
this.make_export();
}
make_exportcmp(data){
this.state.exportcmp=data
}
make_export(){
const out={
Category:this.props.data.Name,
Provider:this.state.Provider,
Name:this.state.Name,
Comments:this.state.comments,
ExportCmp:this.state.exportcmp,
Cost:this.state.cost,
};
this.props.export(out,this.props.n)
}
handleCommentChange(com){
this.setState({comments:com});
}
handleAddPlugin(n){
this.props.handleAddPlugin(n);
}
handleRmvPlugin(n){
this.props.handleRmvPlugin(n);
}
handleProviderChangetxt(txt){
this.setState({Provider:txt});
// this.props.handleCostChange(this.props.n,this.state.cost);//provoke export update on the parent
}
handleServiceChangetxt(txt){
this.setState({Name:txt});
// this.props.handleCostChange(this.props.n,this.state.cost);//provoke export update on the parent
}
render() {
const selected=this.state.selected;
this.state.manualname=false;
this.state.keys=this.ProvidersName(this.props.data);
const Cmp=this.cmp2string(this.cmpdata(selected).Style);
const Cdata=this.cmpdata(selected);
const id=this.props.data.Name.replace(/\s/g,'')+this.props.n;
return(
);
}
cmpdata(select){
let out=this.props.data.Data[select];
if (this.state.manualname){
out.Name=this.state.Name;
if ( this.state.Provider ==='') {
this.state.keys[select] = 'Please provide a Provider';
}else {
this.state.keys[select]=this.state.Provider;
}
}
return out;
}
cmp2string(str){
switch (str) {
case "AmountRatesCost" : return AmountRatesCost;
case "CategoryCost" : return CategoryCost;
case "CategoryAmountRatesCost" : return CategoryAmountRatesCost;
case "NoneSelect":return NoneSelect;
case "UserCost":{this.state.manualname=true; return UserCost;}
}
}
ProvidersName(main){
const data = main.Data;
var providers=[];
for (var i = 0; i < data.length; i++) {
providers.push(data[i].Provider);
}
return providers;
}
}
class ModuleHeader extends React.Component{
constructor(props) {
super(props);
this.handleAddPlugin = this.handleAddPlugin.bind(this);
this.handleRmvPlugin = this.handleRmvPlugin.bind(this);
}
handleAddPlugin(n){
this.props.handleAddPlugin(n);
}
handleRmvPlugin(n){
this.props.handleRmvPlugin(n);
}
render() {
let minus='';
let plus='';
if (this.props.show_minus){
minus= }
onClick={this.handleRmvPlugin} n={this.props.n} tips={"Remove this line"}
idp={this.props.id} info={this.props.data.Name}/>;
}
if (this.props.show_plus){
plus= }
onClick={this.handleAddPlugin} n={this.props.n} tips={"Add a new "+this.props.data.Name}/>
}
return(
{this.props.n+1}. {this.props.data.Name}
{this.makeinfo(this.props.keys,this.props.selected,this.props.Cdata)}
{this.props.comments}
);
}
makeinfo(keys,selected,Cdata){
let name=Cdata.Name;
if ( name ===''&&keys[selected]===''){
name='Please provide a Provider';
return ({name} );
}else if(keys[selected]==='None'){
return ({name} );
}else{
return ({keys[selected]} : {name} );
}
}
}
class ManagePlugins extends React.Component{
constructor(props) {
super(props);
this.handleCostChange = this.handleCostChange.bind(this);
this.handleAddPlugin = this.handleAddPlugin.bind(this);
this.handleRmvPlugin = this.handleRmvPlugin.bind(this);
this.make_exportplug=this.make_exportplug.bind(this);
this.make_export = this.make_export.bind(this);
this.state={
displayed:[],
varsum:{},
plugins:[],
export:[],
};
this.state.displayed.push(randomint(this.state.displayed));
}
handleRmvPlugin(n){
$('#'+n.target).modal('hide');
var tmp=this.state.displayed;
tmp.splice(n.n,1);
this.setState({displayed:tmp});
this.handleCostChange(n.n,0);
}
handleAddPlugin(n){
var tmp=this.state.displayed;
tmp.splice(n+1,0,randomint(this.state.displayed));
this.setState({displayed:tmp});
}
handleCostChange(n,cost) {
this.state.varsum[n]=cost;
this.props.handleCostChange(this.props.n,sum(this.state.varsum));
}
make_exportplug(data,n) {
this.state.export[n] = data;
this.make_export()
}
make_export(){
// var out=[];
// for (var i = 0; i < this.state.export.length; i++) {
// if((this.state.export[i]!==null)&&
// (typeof this.state.export[i].data !== 'undefined')&&(typeof this.state.export[i].state !== 'undefined')){
// out.push({data:this.state.export[i].data,state:this.state.export[i].state});
// }}
//
// this.props.export(out,this.props.n)
if (this.state.export.length === this.give_n()) {
this.props.export(this.state.export, this.props.n)
}
}
give_id(index){
return this.state.displayed[index]
}
give_n(){
const disp=this.state.displayed;
return disp.length
}
componentDidUpdate(){
this.make_export();
}
render() {
let show_minus = false;
if (this.give_n()>1) {
show_minus=true;
}
this.make_export();
return(
);}
}
class PluginsMain extends React.Component {
constructor(props) {
super(props);
this.handleCostChange = this.handleCostChange.bind(this);
this.make_exportplug=this.make_exportplug.bind(this);
this.make_export = this.make_export.bind(this);
this.state={
varsum:{},
export:[]
};
}
handleCostChange(name,e) {
this.state.varsum[name]=e;
this.props.TotalCost(sum(this.state.varsum));
}
make_exportplug(data,n) {
this.state.export[n] = data;
this.make_export()
}
make_export(){
if (this.state.export.length === this.props.data.length) {
this.props.export(this.state.export);
}
}
render() {
return(
Line controls
Category
Provider information
Cost
{(index) => }
);
}
}
// MAIN
// ---------------------
// ---------------------
class Main extends React.Component {
constructor(props) {
super(props);
this.handleCostChange = this.handleCostChange.bind(this);
this.make_exportmain = this.make_exportmain.bind(this);
this.state= {
total: 0,
export: [],
exportmain:[],
};
this.init=true;
}
handleCostChange(total) {
if (this.state.total !== total){
this.setState({total:total});
}
}
make_exportmain(idata) {
const tmp=JSON.parse(JSON.stringify(idata));
let disp=false;
if(!this.init){
if(!Object.compare(tmp,this.state.exportmain.data)){
disp=true;
}
}
if((this.init)||(disp)){
this.setState({exportmain: {data: tmp, total: tomoney(this.state.total)}});
this.init=false;
}
}
render() {
return(
{this.page_head()}
{this.final_cost()}
{this.howto()}
{this.page_foot()}
);
}
howto(){
return(
HOWTO
Categories
This tool is divided by categories (for example Activate storage). Click
on the category name, and it will expand.
Providers
Providers can be chosen from the Select a provider box . You can then tune your setting for this provider to fit your needs.
If the provider you want is not registered, you can add it manually with Provide your own provider and then enter your provider/service and cost.
Add or Remove Line
If you want to add a new provider use the }
tips={"Add a new category"} onClick={this.fctnull}/> button.
You can also remove a provider with }
tips={"Remove this line"} onClick={this.fctnull}/> button.
To know more about
Some extra information about the category or the provider can be obtained with the }
tips={"Know more"} onClick={this.fctnull}/> button.
Comments your input
Comments are for your own usage, you can use for remembering what each section is and for a nice export.
Export
You can export your work into different format :
HTML : This format can be used in any wordprocessing software (such as Microsoft Word or Libreoffice).
HTML Source code and Markdown formats are also possible.
Click on the in order to copy your work into your clipboard. A simple Paste will transfer your work into any software.
);
}
final_cost(){
return(
{/*
*/}
Total Cost
);
}
page_head(){
return(
-
Cost Calculator for Data Management
+ EPFL Library Cost Calculator for Data Management
Welcome to our cost calculator this tool will help researcher/professor to have an
estimate of the cost of managing, storing and publishing data.
Many providers are included in the service and you will be able to calculate a cost
based on your needs. Total cost is calculated dynamically based on your inputs.
We hope you will enjoy this tool and it will be useful for you.
);
}
move2howto(){
$('html,body').animate({
scrollTop: $("#howto").offset().top},
'slow');
}
page_foot(){
return(
);
}
fctnull(){}
}
//Main Declaration
// ---------------------
// ---------------------
ReactDOM.render( ,document.getElementById('root'));
$(function () {
$('[data-toggle="tooltip"]').tooltip()
});
diff --git a/js/data.js b/js/data.js
index 9668513..6759c98 100644
--- a/js/data.js
+++ b/js/data.js
@@ -1,347 +1,348 @@
// Providers
// ----------------------------------------------------
// ----------------------------------------------------
// Storage
const NasEpfl = {
Style: "AmountRatesCost",
Provider : "EPFL-VPSI",
Name:'NAS',
Url : [
{Name:'VPSI-Website',Url:'https://support.epfl.ch/help/epfl?id=epfl_service_status&service=49a363acdb34c700ef64731b8c96191f'},
{Name:'SV-IT Storage Website',Url:'https://sv-it.epfl.ch/stockage'}
],
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 : [
{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 : [
{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-SV-IT",
Name:'SLIMS',
Url : [
{Name:'SLIMS on SV-IT Website',Url:'https://sv-it.epfl.ch/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': 165,
},
RateUnit : "CHF / TB"
};
// Database
const MysqlEpfl = {
Style : 'CategoryCost',
Provider : "EPFL-VPSI",
Name:'MySql',
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 : [
{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 : [
{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 : [
{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 : [
{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 : [
{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 : [
{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 : "Dryad",
Name:'Dyrad',
Url : [
{Name:'Dryad 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"
};
// System variable definition
// ----------------------------------------------------
// ----------------------------------------------------
const NoneSelected={
Style: 'NoneSelect',
Provider:'None',
Name:'Select a Provider',
Url:'',
};
const UserCostSelect={
Style : 'UserCost',
Provider:'Provide your own provider',
Name:'',
Url:'',
};
// Categories definition
// ----------------------------------------------------
// ----------------------------------------------------
const storage={
Name : 'Active Storage',
Icon : 'storage.png',
Url : [
{Name:'EPFL RDM',Url:'https://researchData.epfl.ch/work-with-Data/storage/'}
],
Intro :'',
Data :[NoneSelected,
NasEpfl,
SwitchEpfl,
GoogleDriveEdu,
UserCostSelect,
]
};
const ELN={
Name : 'Electronic LabBook',
Icon : 'eln.png',
Url : [
{Name: 'EPFL RDM',Url:'https://researchData.epfl.ch/work-with-Data/active-Data-management/'}
],
Intro :'',
Data :[NoneSelected,
SLIMSEpfl,
UserCostSelect,
]
};
const Database={
Name : 'Database',
Icon : 'database.png',
Url : '',
Intro :'',
Data :[NoneSelected,
MysqlEpfl,
UserCostSelect,
]
};
const repository={
Name : 'Repository',
Icon : 'repos.png',
Url : [
{Name:'EPFL RDM WebPage',Url:'https://researchData.epfl.ch/publish-preserve/'}
],
Intro :'',
Data :[
NoneSelected,
Zenodo,
C4science,
Github,
Bitbucket,
Gitlab,
Figshare,
Dryad,
UserCostSelect,
]
};
// Combine Categories
// ----------------------------------------------------
// ----------------------------------------------------
const MainData={
Currency:'CHF',
+ Updated:'29/11/2018',
Data:[storage,ELN,Database,repository]
};