1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/web/ synced 2025-03-09 00:00:01 +01:00

Merge commit 'a1ac2c4aa66055501966111a8af67e8ffbef8a91' into additional-widgets

This commit is contained in:
Ricardo Hernandez-Montoya 2017-04-21 13:02:35 +02:00
commit 9fb8734b05
5 changed files with 136 additions and 52 deletions

24
docker-compose.yml Normal file
View file

@ -0,0 +1,24 @@
version: "2"
services:
frontend:
image: nginx:stable
volumes:
- ./nginx:/etc/nginx/conf.d/
- ./build:/www
links:
- backend
ports:
- "80:80"
- "443:443"
backend:
image: villasweb-backend
links:
- database
database:
image: mongo:latest
volumes:
- /opt/database:/data/db

32
nginx/villas.conf Normal file
View file

@ -0,0 +1,32 @@
server {
listen 80 default_server;
server_name VILLASweb;
# backend location
location /api/ {
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# rewrite url to exclude /api on context broker side
rewrite ^/api/?(.*) /api/v1/$1 break;
proxy_pass http://backend:4000/;
}
# frontend location
location / {
root /www;
}
# error pages
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
error_page 500 502 503 504 50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

View file

@ -43,21 +43,30 @@ class NewProjectDialog extends Component {
}
resetState() {
this.setState({ name: '', simulation: this.props.simulations[0]._id });
this.setState({
name: '',
simulation: this.props.simulations[0] != null ? this.props.simulations[0]._id : ''
});
}
validateForm(target) {
// check all controls
var name = true;
var simulation = true;
if (this.state.name === '') {
name = false;
}
this.valid = name;
if (this.state.simulation === '') {
simulation = false;
}
this.valid = name && simulation;
// return state to control
if (target === 'name') return name ? "success" : "error";
else if (target === 'simulation') return simulation ? "success" : "error";
}
render() {
@ -69,7 +78,7 @@ class NewProjectDialog extends Component {
<FormControl type="text" placeholder="Enter name" value={this.state.name} onChange={(e) => this.handleChange(e)} />
<FormControl.Feedback />
</FormGroup>
<FormGroup controlId="simulation">
<FormGroup controlId="simulation" validationState={this.validateForm('simulation')}>
<ControlLabel>Simulation</ControlLabel>
<FormControl componentClass="select" placeholder="Select simulation" value={this.state.simulation} onChange={(e) => this.handleChange(e)}>
{this.props.simulations.map(simulation => (

View file

@ -72,28 +72,39 @@ class NewSimulationModelDialog extends Component {
}
resetState() {
this.setState({ name: '', simulator: this.props.simulators[0]._id, length: '1', mapping: [ { name: 'Signal', type: 'Type' } ] });
this.setState({
name: '',
simulator: this.props.simulators[0] != null ? this.props.simulators[0]._id : '',
length: '1',
mapping: [ { name: 'Signal', type: 'Type' } ]
});
}
validateForm(target) {
// check all controls
var name = true;
var length = true;
var simulator = true;
if (this.state.name === '') {
name = false;
}
if (this.state.simulator === '') {
simulator = false;
}
// test if simulatorid is a number (in a string, not type of number)
if (!/^\d+$/.test(this.state.length)) {
length = false;
}
this.valid = name && length;
this.valid = name && length && simulator;
// return state to control
if (target === 'name') return name ? "success" : "error";
else if (target === 'length') return length ? "success" : "error";
else if (target === 'simulator') return simulator ? "success" : "error";
}
render() {

View file

@ -15,7 +15,7 @@ import AppDispatcher from '../app-dispatcher';
import ProjectStore from '../stores/project-store';
import VisualizationStore from '../stores/visualization-store';
import Table from '../components/table';
import CustomTable from '../components/table';
import TableColumn from '../components/table-column';
import NewVisualzationDialog from '../components/dialog/new-visualization';
import EditVisualizationDialog from '../components/dialog/edit-visualization';
@ -25,66 +25,77 @@ class Visualizations extends Component {
return [ ProjectStore, VisualizationStore ];
}
static calculateState(prevState) {
static calculateState(prevState, props) {
let currentProjects = ProjectStore.getState();
let currentVisualizations = VisualizationStore.getState();
if (prevState) {
var projectUpdate = prevState.project;
// Compare content of the visualizations array, reload projects if changed
if (JSON.stringify(prevState.visualizations) !== JSON.stringify(currentVisualizations)) {
Visualizations.loadProjects();
}
// Compare content of the projects array, update visualizations if changed
if (JSON.stringify(prevState.projects) !== JSON.stringify(currentProjects)) {
projectUpdate = Visualizations.findProjectInState(currentProjects, props.params.project);
Visualizations.loadVisualizations(projectUpdate.visualizations);
}
return {
projects: ProjectStore.getState(),
visualizations: VisualizationStore.getState(),
projects: currentProjects,
visualizations: currentVisualizations,
newModal: prevState.newModal,
deleteModal: prevState.deleteModal,
editModal: prevState.editModal,
modalData: prevState.modalData,
project: prevState.project,
reload: prevState.reload
project: projectUpdate
};
} else {
let initialProject = Visualizations.findProjectInState(currentProjects, props.params.project);
// If projects have been loaded already but visualizations not (redirect from Projects page)
if (initialProject && (!currentVisualizations || currentVisualizations.length === 0)) {
Visualizations.loadVisualizations(initialProject.visualizations);
}
return {
projects: ProjectStore.getState(),
visualizations: VisualizationStore.getState(),
projects: currentProjects,
visualizations: currentVisualizations,
newModal: false,
deleteModal: false,
editModal: false,
modalData: {},
project: {},
reload: false
project: initialProject || {}
};
}
}
componentWillMount() {
static findProjectInState(projects, projectId) {
return projects.find((project) => project._id === projectId);
}
static loadProjects() {
AppDispatcher.dispatch({
type: 'projects/start-load'
});
}
componentDidUpdate() {
if (this.state.project._id !== this.props.params.project /*|| this.state.reload*/) {
this.reloadProject();
if (this.state.reload) {
this.setState({ reload: false });
}
}
static loadVisualizations(visualizations) {
AppDispatcher.dispatch({
type: 'visualizations/start-load',
data: visualizations
});
}
reloadProject() {
// select project by param id
this.state.projects.forEach((project) => {
if (project._id === this.props.params.project) {
// JSON.parse(JSON.stringify(obj)) = deep clone to make also copy of widget objects inside
this.setState({ project: JSON.parse(JSON.stringify(project)) });
// load visualizations
AppDispatcher.dispatch({
type: 'visualizations/start-load',
data: project.visualizations
});
}
});
componentWillMount() {
Visualizations.loadProjects();
}
closeNewModal(data) {
@ -98,7 +109,7 @@ class Visualizations extends Component {
});
}
this.setState({ newModal: false, reload: data != null });
this.setState({ newModal: false });
}
confirmDeleteModal() {
@ -106,7 +117,7 @@ class Visualizations extends Component {
AppDispatcher.dispatch({
type: 'visualizations/start-remove',
data: this.state.modalVisualization
data: this.state.modalData
});
}
@ -124,25 +135,22 @@ class Visualizations extends Component {
render() {
// get visualizations for this project
var visualizations = [];
if (this.state.visualizations && this.state.project.visualizations) {
this.state.visualizations.forEach((visualization) => {
this.state.project.visualizations.forEach((id) => {
if (visualization._id === id) {
visualizations.push(visualization);
}
});
});
visualizations = this.state.visualizations.filter(
(visualization) => this.state.project.visualizations.includes(visualization._id)
).sort(
(visA, visB) => visA.name.localeCompare(visB.name)
);
}
return (
<div className='section'>
<h1>{this.state.project.name}</h1>
<Table data={visualizations}>
<CustomTable data={visualizations}>
<TableColumn title='Name' dataKey='name' link='/visualizations/' linkKey='_id' />
<TableColumn width='70' editButton deleteButton onEdit={index => this.setState({ editModal: true, modalData: this.state.visualizations[index] })} onDelete={index => this.setState({ deleteModal: true, modalData: this.state.visualizations[index] })} />
</Table>
<TableColumn width='70' editButton deleteButton onEdit={(index) => this.setState({ editModal: true, modalData: visualizations[index] })} onDelete={(index) => this.setState({ deleteModal: true, modalData: visualizations[index] })} />
</CustomTable>
<Button onClick={() => this.setState({ newModal: true })}><Glyphicon glyph="plus" /> Visualization</Button>
@ -169,4 +177,4 @@ class Visualizations extends Component {
}
}
export default Container.create(Visualizations);
export default Container.create(Visualizations, {withProps: true});