-
Notifications
You must be signed in to change notification settings - Fork 235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dashboard (Both design and functionality) #471
Changes from 31 commits
0e4988e
ebac6b1
d10486c
5ffc512
2cd218c
c7dfbce
288a67c
feaa07b
27f3823
0bf3a0c
c48605f
80194bc
63d934d
f8499c1
37df28c
8706c6c
6c28f76
c81f450
41c6afd
0a5a94e
216807a
46b1e09
422e886
5b9405a
28e6c66
08b4090
640a9d3
10d1bfa
7a88df1
8aaeda7
b239062
815402a
ef40924
dc03332
2da10bb
74d8b3a
0387266
3de7f30
9df8d9d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
.overlay { | ||
opacity: 0; | ||
z-index: -2; | ||
height: 290px; | ||
width: 240px; | ||
background: rgb(34,47,62,0.9); | ||
border-radius: 30px; | ||
position: relative; | ||
top: -310px; | ||
transition: all .4s ease; | ||
} | ||
|
||
.card { | ||
transition: all .4s ease; | ||
} | ||
|
||
.card:hover + .overlay, .overlay:hover { | ||
opacity: 1; | ||
z-index: 1; | ||
transition: all .4s ease; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
body { | ||
background: #F3F5F7; | ||
} | ||
|
||
.insert-layer-title { | ||
position: relative; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import React from 'react'; | ||
import '../css/dash_style.css'; | ||
|
||
class Card extends React.Component { | ||
render() { | ||
return( | ||
<div style={{display: 'inline-block'}}> | ||
<div className="card" style={{ | ||
background: '#fff', | ||
height: 290, | ||
width: 240, | ||
borderRadius: 30, | ||
display: 'inline-block', | ||
margin: 20, | ||
boxShadow: '0 2px 6px rgba(112,112,112,0.2)' | ||
}}> | ||
<img style={{marginTop: '4.5em'}} src="static/img/thumb.png" height="60%;" /> | ||
</div> | ||
<div className="overlay"> | ||
<br /> | ||
<div className="social" style={{marginTop: '5em'}}> | ||
<div style={{ | ||
margin: 10, | ||
display: 'inline-block', | ||
color: '#fff', | ||
fontFamily: '"Proxima Nova",sans-serif', | ||
width: 10, | ||
height: 10, | ||
border: '3px solid #fff', | ||
padding: 20, | ||
borderRadius: '50%' | ||
}}> | ||
<a href={"/load?id=" + this.props.ModelID} style={{textDecoration: 'none', color: '#fff'}}> | ||
<p style={{marginTop: '-8px', marginLeft: '-6px'}}> | ||
<span className="glyphicon glyphicon-pencil" aria-hidden="true"></span> | ||
</p> | ||
</a> | ||
</div> | ||
<div style={{margin: 10, | ||
display: 'inline-block', | ||
color: '#fff', | ||
fontFamily: '"Proxima Nova",sans-serif', | ||
width: 10, | ||
height: 10, | ||
border: '3px solid #fff', | ||
padding: 20, | ||
borderRadius: '50%' | ||
}}> | ||
<a onClick={ | ||
() => this.props.ModelFunction(this.props.ModelID) | ||
} style={{ | ||
textDecoration: 'none', | ||
color: '#fff', | ||
cursor: 'pointer' | ||
}}> | ||
<p style={{ | ||
marginTop: '-8px', | ||
marginLeft: '-7px' | ||
}}> | ||
<span className="glyphicon glyphicon-trash" aria-hidden="true"></span> | ||
</p> | ||
</a> | ||
</div> | ||
</div> | ||
</div> | ||
<h3 style={{marginTop: '-12em'}}>{this.props.ModelName}</h3> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
Card.propTypes = { | ||
ModelName: React.PropTypes.string, | ||
ModelID: React.PropTypes.number, | ||
ModelFunction: React.PropTypes.func | ||
}; | ||
|
||
|
||
export default Card; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,6 +85,7 @@ class Content extends React.Component { | |
this.openModal = this.openModal.bind(this); | ||
this.closeModal = this.closeModal.bind(this); | ||
this.saveDb = this.saveDb.bind(this); | ||
this.saveModel = this.saveModel.bind(this); | ||
this.loadDb = this.loadDb.bind(this); | ||
this.infoModal = this.infoModal.bind(this); | ||
this.faqModal = this.faqModal.bind(this); | ||
|
@@ -979,6 +980,34 @@ class Content extends React.Component { | |
layer.info.phase = 0; | ||
this.setState({ net }); | ||
} | ||
saveModel(){ | ||
let modelData = this.state.net; | ||
this.setState({ load: true }); | ||
$.ajax({ | ||
url: '/saveModel', | ||
dataType: 'json', | ||
type: 'POST', | ||
data: { | ||
net: JSON.stringify(modelData), | ||
net_name: this.state.net_name, | ||
user_id: this.getUserId(), | ||
nextLayerId: this.state.nextLayerId | ||
}, | ||
success : function (response) { | ||
if (response.result == 'success') { | ||
this.modalContent = "Successfully Saved!"; | ||
this.openModal(); | ||
} | ||
else if (response.result == 'error') { | ||
this.addError(response.error); | ||
} | ||
this.setState({ load: false }); | ||
}.bind(this), | ||
error() { | ||
this.setState({ load: false }); | ||
} | ||
}); | ||
} | ||
saveDb(){ | ||
let netData = this.state.net; | ||
this.setState({ load: true }); | ||
|
@@ -1055,7 +1084,7 @@ class Content extends React.Component { | |
// Note: this needs to be improved when handling conflict resolution to avoid | ||
// inconsistent states of model | ||
let nextLayerId = this.state.nextLayerId; | ||
|
||
let is_shared = false; | ||
this.setState({ load: true }); | ||
|
||
this.dismissAllErrors(); | ||
|
@@ -1072,6 +1101,10 @@ class Content extends React.Component { | |
// while loading a model ensure paramete intialisation | ||
// for UI show/hide is not executed, it leads to inconsistent | ||
// data which cannot be used further | ||
if (response.public_sharing == true) { | ||
is_shared = true; | ||
} | ||
//console.log(response); | ||
nextLayerId = response.next_layer_id; | ||
this.initialiseImportedNet(response.net,response.net_name); | ||
if (Object.keys(response.net).length){ | ||
|
@@ -1083,15 +1116,18 @@ class Content extends React.Component { | |
} | ||
this.setState({ | ||
load: false, | ||
isShared: true, | ||
isShared: is_shared, | ||
nextLayerId: parseInt(nextLayerId) | ||
}, function() { | ||
//console.log("Shared value: " + this.state.isShared); | ||
}); | ||
}.bind(this), | ||
error() { | ||
this.setState({ load: false }); | ||
} | ||
}); | ||
} | ||
|
||
infoModal() { | ||
this.modalHeader = "About" | ||
this.modalContent = `Fabrik is an online collaborative platform to build and visualize deep\ | ||
|
@@ -1113,7 +1149,7 @@ class Content extends React.Component { | |
<a target="_blank" href="https://github.com/Cloud-CV/Fabrik/blob/master/docs/source/tested_models.md"> here</a>. | ||
<br /> | ||
<b>Q:</b> What do the Train/Test buttons mean?<br /> | ||
<b>A:</b> They are two different modes of your model: | ||
<b>A:</b> They are two different modes of your model: | ||
Train and Test - respectively for training your model with data and testing how and if it works.<br /> | ||
<b>Q:</b> What does the import fuction do?<br /> | ||
<b>A:</b> It allows you to import your previously created models in Caffe (.protoxt files), | ||
|
@@ -1127,7 +1163,7 @@ class Content extends React.Component { | |
<b>A:</b> Please see the instructions listed | ||
<a target="_blank" href="https://github.com/Cloud-CV/Fabrik/blob/master/README.md"> here</a> | ||
<br /><br /> | ||
|
||
<b>If you have anymore questions, please visit Fabrik's Github page available | ||
<a target="_blank" href="https://github.com/Cloud-CV/Fabrik"> here</a> for more information.</b> | ||
</p>); | ||
|
@@ -1282,6 +1318,7 @@ class Content extends React.Component { | |
this.addNewLayer(layer); | ||
} | ||
} | ||
|
||
render() { | ||
let loader = null; | ||
if (this.state.load) { | ||
|
@@ -1299,9 +1336,11 @@ class Content extends React.Component { | |
<div id="sidebar-scroll" className="col-md-12"> | ||
<h5 className="sidebar-heading">ACTIONS</h5> | ||
<TopBar | ||
isPublicSharing={this.state.isShared} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is one flag variable in state of content.js where I maintain the type of model as isShared or not, can't we use that here because defining a new one causes necessity to maintain consistency in both. If not possible then please rename this variable name in props There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven’t defined this, this was already in the existing code. isShared is the flag variable which is there in content.js file right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn’t exactly understand, could you please elaborate? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is one boolean flag in content.js state variable if you are passing it down as props use the same name and don't define new ones if possible |
||
exportNet={this.exportNet} | ||
importNet={this.importNet} | ||
saveDb={this.saveDb} | ||
saveModel={this.saveModel} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change the method name to update model (if I understand the functionality correctly There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have explained this function above, please have a look at it, it’s not just updating the already existing model, it updates the model only if it already exists else it saves the model. |
||
zooModal={this.zooModal} | ||
textboxModal={this.textboxModal} | ||
urlModal={this.urlModal} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import React from 'react'; | ||
import Modal from 'react-modal'; | ||
import Card from './card'; | ||
|
||
const infoStyle = { | ||
content : { | ||
top : '50%', | ||
left : '55%', | ||
right : '60%', | ||
bottom : 'auto', | ||
marginRight : '-50%', | ||
transform : 'translate(-50%, -50%)', | ||
borderRadius : '8px' | ||
}, | ||
overlay: { | ||
zIndex : 100 | ||
} | ||
}; | ||
|
||
class Dashboard extends React.Component{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't add two different components in same files |
||
constructor(props) { | ||
super(props); | ||
this.state = {modalIsOpen: false} | ||
this.getModelData = this.getModelData.bind(this); | ||
this.deleteModel = this.deleteModel.bind(this); | ||
this.openModal = this.openModal.bind(this); | ||
this.closeModal = this.closeModal.bind(this); | ||
this.modalContent = null; | ||
this.modalHeader = null; | ||
} | ||
|
||
getModelData(){ | ||
var userid = localStorage.getItem("userID"); | ||
$.ajax({ | ||
url: '/getModel', | ||
dataType: 'json', | ||
type: 'POST', | ||
data: {userID: userid}, | ||
success : function (response) { | ||
if (response.result == 'success') { | ||
var obj = JSON.stringify(response.data); | ||
localStorage.setItem("obj",obj); | ||
return obj; | ||
} | ||
else if (response.result == 'error') { | ||
if (localStorage.hasOwnProperty('obj')) { | ||
localStorage.removeItem("obj"); | ||
} | ||
} | ||
return response.data; | ||
}.bind(this), | ||
error() { | ||
} | ||
}); | ||
} | ||
|
||
deleteModel(model_id){ | ||
var userid = localStorage.getItem("userID"); | ||
$.ajax({ | ||
url: '/deleteModel', | ||
type: 'POST', | ||
dataType: 'json', | ||
data: {userID: userid, modelid: model_id}, | ||
success : function (response) { | ||
|
||
if (response.result == 'success') { | ||
this.modalContent = response.data; | ||
this.openModal(); | ||
} | ||
else if (response.result == 'error') { | ||
} | ||
}.bind(this), | ||
error() { | ||
} | ||
}); | ||
} | ||
|
||
openModal() { | ||
this.setState({ modalIsOpen: true }); | ||
} | ||
|
||
closeModal() { | ||
this.setState({ modalIsOpen: false }); | ||
location.reload(true); | ||
} | ||
|
||
componentDidMount() { | ||
this.getModelData(); | ||
} | ||
|
||
render() { | ||
if (localStorage.hasOwnProperty('userID')) { | ||
if (!localStorage.hasOwnProperty('obj')) { | ||
elements=<div><p style={{fontStyle: 'italic', marginTop: '2em'}}>No models found</p></div>; | ||
} | ||
else { | ||
var data_array = JSON.parse(localStorage.getItem("obj")); | ||
var len = Object.keys(data_array).length/2; | ||
var elements=[]; | ||
for (var i = 1; i < len+1; i++) { | ||
elements.push(<Card ModelFunction={ this.deleteModel } ModelName={ data_array["Model"+i+"_Name"] } ModelID={ data_array["Model"+i+"_ID"] } />) | ||
} | ||
} | ||
return ( | ||
<center> | ||
<div className="cont" style={{width: '80%', marginTop: '2em', display: 'inline-block'}}> | ||
<h1 style={{color: '#455062', fontSize: '2em', textAlign: 'left', fontWeight: 'bolder'}}>DASHBOARD</h1> | ||
<br /> | ||
<p style={{textAlign: 'left'}}> | ||
<a href="#" style={{ | ||
textDecoration: 'none', | ||
color: '#fff', | ||
fontWeight: 'bold', | ||
background: '#222f3e', | ||
fontSize: '0.7em', | ||
padding: 15, | ||
paddingRight: 20, | ||
paddingLeft: 20, | ||
borderRadius: 200 | ||
}}> | ||
<span className="glyphicon glyphicon-plus" aria-hidden="true"></span> CREATE NEW MODEL</a> | ||
</p> | ||
<br /> | ||
<div className="all-cards" style={{marginLeft: '-2.6em', display: 'inline-block'}}> | ||
{elements} | ||
</div> | ||
</div> | ||
<Modal | ||
isOpen={this.state.modalIsOpen} | ||
onRequestClose={this.closeModal} | ||
style={infoStyle} | ||
contentLabel="Modal"> | ||
<button type="button" style={{padding: 5+'px'}} className="close" onClick={this.closeModal}>×</button> | ||
<h4>{ this.modalHeader }</h4> | ||
{ this.modalContent } | ||
</Modal> | ||
</center> | ||
); | ||
} | ||
else { | ||
window.open("#","_self"); | ||
return null; | ||
} | ||
} | ||
} | ||
|
||
export default Dashboard; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I understand this method performs update on already existing model so please rename it to update model
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method doesn’t update on already existing model, it saves the model data on clicking the save button but if the model already exists in the database then it updates the model.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if you are doing this then why do we have older method still present?
Why can't your remove that or add the code in same method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can’t remover the older method as there is a difference between the 2 methods the older one is saving the model with shared properties while the new method is saving the model with not shared properties, if you still want me to combine the two, I’ll try to do it.