/**
* This file is part of VILLASweb.
*
* VILLASweb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VILLASweb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VILLASweb. If not, see .
******************************************************************************/
import React, { Component } from 'react';
import { Container } from 'flux/utils';
import { Button } from 'react-bootstrap';
import FileSaver from 'file-saver';
import _ from 'lodash';
import moment from 'moment'
import AppDispatcher from '../common/app-dispatcher';
import InfrastructureComponentStore from './ic-store';
import Icon from '../common/icon';
import Table from '../common/table';
import TableColumn from '../common/table-column';
import NewICDialog from './new-ic';
import EditICDialog from './edit-ic';
import ImportICDialog from './import-ic';
import ICAction from './ic-action';
import DeleteDialog from '../common/dialogs/delete-dialog';
class InfrastructureComponents extends Component {
static getStores() {
return [ InfrastructureComponentStore ];
}
static statePrio(state) {
switch (state) {
case 'running':
case 'starting':
return 1;
case 'paused':
case 'pausing':
case 'resuming':
return 2;
case 'idle':
return 3;
case 'shutdown':
return 4;
case 'error':
return 10;
default:
return 99;
}
}
static calculateState() {
const ics = InfrastructureComponentStore.getState().sort((a, b) => {
if (a.state !== b.state) {
return InfrastructureComponents.statePrio(a.state) > InfrastructureComponents.statePrio(b.state);
}
else if (a.name !== b.name) {
return a.name < b.name;
}
else {
return a.stateUpdatedAt < b.stateUpdatedAt;
}
});
return {
sessionToken: localStorage.getItem("token"),
ics: ics,
modalIC: {},
deleteModal: false,
selectedICs: [],
currentUser: JSON.parse(localStorage.getItem("currentUser"))
};
}
componentDidMount() {
AppDispatcher.dispatch({
type: 'ics/start-load',
token: this.state.sessionToken,
});
// Start timer for periodic refresh
this.timer = window.setInterval(() => this.refresh(), 10000);
}
componentWillUnmount() {
window.clearInterval(this.timer);
}
refresh() {
if (this.state.editModal || this.state.deleteModal){
// do nothing since a dialog is open at the moment
}
else {
AppDispatcher.dispatch({
type: 'ics/start-load',
token: this.state.sessionToken,
});
}
}
closeNewModal(data) {
this.setState({ newModal : false });
if (data) {
AppDispatcher.dispatch({
type: 'ics/start-add',
data,
token: this.state.sessionToken,
});
}
}
closeEditModal(data) {
this.setState({ editModal : false });
if (data) {
//let ic = this.state.ics[this.state.modalIndex];
//ic = data;
//this.setState({ ic: ic });
AppDispatcher.dispatch({
type: 'ics/start-edit',
data: data,
token: this.state.sessionToken,
});
}
}
closeDeleteModal(confirmDelete){
this.setState({ deleteModal: false });
if (confirmDelete === false) {
return;
}
AppDispatcher.dispatch({
type: 'ics/start-remove',
data: this.state.modalIC,
token: this.state.sessionToken,
});
}
exportIC(index) {
// filter properties
let ic = Object.assign({}, this.state.ics[index]);
delete ic.id;
// show save dialog
const blob = new Blob([JSON.stringify(ic, null, 2)], { type: 'application/json' });
FileSaver.saveAs(blob, 'ic - ' + (_.get(ic, 'properties.name') || _.get(ic, 'rawProperties.name') || 'undefined') + '.json');
}
closeImportModal(data) {
this.setState({ importModal: false });
if (data) {
AppDispatcher.dispatch({
type: 'ics/start-add',
data,
token: this.state.sessionToken,
});
}
}
onICChecked(index, event) {
const selectedICs = Object.assign([], this.state.selectedICs);
for (let key in selectedICs) {
if (selectedICs[key] === index) {
// update existing entry
if (event.target.checked) {
return;
}
selectedICs.splice(key, 1);
this.setState({ selectedICs: selectedICs });
return;
}
}
// add new entry
if (event.target.checked === false) {
return;
}
selectedICs.push(index);
this.setState({ selectedICs: selectedICs });
}
runAction = action => {
for (let index of this.state.selectedICs) {
AppDispatcher.dispatch({
type: 'ics/start-action',
ic: this.state.ics[index],
data: action.data,
token: this.state.sessionToken,
});
}
}
static isICOutdated(component) {
if (!component.stateUpdatedAt)
return true;
const fiveMinutes = 5 * 60 * 1000;
return Date.now() - new Date(component.stateUpdatedAt) > fiveMinutes;
}
stateLabelStyle(state, component){
var style = [ 'badge' ];
if (InfrastructureComponents.isICOutdated(component) && state !== 'shutdown') {
style.push('badge-outdated');
}
switch (state) {
case 'error':
style.push('badge-danger');
break;
case 'idle':
style.push('badge-primary');
break;
case 'starting':
style.push('badge-info');
break;
case 'running':
style.push('badge-success');
break;
case 'pausing':
style.push('badge-info');
break;
case 'paused':
style.push('badge-info');
break;
case 'resuming':
style.push('badge-warning');
break;
case 'stopping':
style.push('badge-warning');
break;
case 'resetting':
style.push('badge-warning');
break;
case 'shuttingdown':
style.push('badge-warning');
break;
case 'shutdown':
style.push('badge-warning');
break;
default:
style.push('badge-default');
/* Possible states of ICs
* 'error': ['resetting', 'error'],
'idle': ['resetting', 'error', 'idle', 'starting', 'shuttingdown'],
'starting': ['resetting', 'error', 'running'],
'running': ['resetting', 'error', 'pausing', 'stopping'],
'pausing': ['resetting', 'error', 'paused'],
'paused': ['resetting', 'error', 'resuming', 'stopping'],
'resuming': ['resetting', 'error', 'running'],
'stopping': ['resetting', 'error', 'idle'],
'resetting': ['resetting', 'error', 'idle'],
'shuttingdown': ['shutdown', 'error'],
'shutdown': ['starting', 'error']
* */
}
return style.join(' ')
}
stateUpdateModifier(updatedAt) {
let dateFormat = 'ddd, DD MMM YYYY HH:mm:ss';
let dateTime = moment.utc(updatedAt, dateFormat);
return dateTime.toLocaleString('de-DE');
}
render() {
const buttonStyle = {
marginLeft: '10px'
};
return (
Infrastructure Components
this.onICChecked(index, event)} width='30' />
this.stateLabelStyle(state, component)} />
{/* */}
this.stateUpdateModifier(stateUpdateAt)} />
{this.state.currentUser.role === "Admin" ?
this.setState({ editModal: true, modalIC: this.state.ics[index], modalIndex: index })}
onExport={index => this.exportIC(index)}
onDelete={index => this.setState({ deleteModal: true, modalIC: this.state.ics[index], modalIndex: index })}
/>
:
this.exportIC(index)}
/>
}
{this.state.currentUser.role === "Admin" ?
:
}
{this.state.currentUser.role === "Admin" ?
:
}
this.closeNewModal(data)} />
this.closeEditModal(data)} ic={this.state.modalIC} />
this.closeImportModal(data)} />
this.closeDeleteModal(e)} />
);
}
}
let fluxContainerConverter = require('../common/FluxContainerConverter');
export default Container.create(fluxContainerConverter.convert(InfrastructureComponents));