forked from community/device-mgt-core
Add lifecycle Graph See merge request entgra/carbon-device-mgt!894.x.x
commit
3cb9fd3a43
@ -0,0 +1,7 @@
|
||||
.srd-diagram{
|
||||
height: 100%;
|
||||
min-height: 300px;
|
||||
background-color: #3c3c3c !important;
|
||||
background-image: linear-gradient(0deg, transparent 24%, rgba(255, 255, 255, 0.05) 25%, rgba(255, 255, 255, 0.05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, 0.05) 75%, rgba(255, 255, 255, 0.05) 76%, transparent 77%, transparent), linear-gradient(90deg, transparent 24%, rgba(255, 255, 255, 0.05) 25%, rgba(255, 255, 255, 0.05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, 0.05) 75%, rgba(255, 255, 255, 0.05) 76%, transparent 77%, transparent);
|
||||
background-size: 50px 50px;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
import React from "react";
|
||||
import LifeCycleGraph from "./LifeCycleGraph";
|
||||
import {connect} from "react-redux";
|
||||
import {getLifecycle, openReleasesModal} from "../../../js/actions";
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
getLifecycle: () => dispatch(getLifecycle())
|
||||
});
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
lifecycle: state.lifecycle
|
||||
};
|
||||
};
|
||||
|
||||
class ConnectedLifeCycle extends React.Component {
|
||||
componentDidMount() {
|
||||
this.props.getLifecycle();
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log();
|
||||
const lifecycle = this.props.lifecycle;
|
||||
if(lifecycle != null){
|
||||
return (
|
||||
<LifeCycleGraph currentStatus={this.props.currentStatus} lifecycle={this.props.lifecycle}/>
|
||||
);
|
||||
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const LifeCycle = connect(mapStateToProps, mapDispatchToProps)(ConnectedLifeCycle);
|
||||
|
||||
export default LifeCycle;
|
@ -0,0 +1,90 @@
|
||||
import React from "react";
|
||||
import * as SRD from "storm-react-diagrams";
|
||||
import "storm-react-diagrams/dist/style.min.css";
|
||||
import "./LifeCycle.css";
|
||||
import {distributeElements} from "../../../js/utils/dagre-utils.ts";
|
||||
|
||||
const inPortName = "IN";
|
||||
const outPortName = "OUT";
|
||||
|
||||
class LifeCycleGraph extends React.Component {
|
||||
render() {
|
||||
|
||||
const lifecycle = this.props.lifecycle;
|
||||
const nodes = [];
|
||||
const links = [];
|
||||
|
||||
const engine = new SRD.DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
const model = new SRD.DiagramModel();
|
||||
const nextStates = lifecycle[this.props.currentStatus].proceedingStates;
|
||||
|
||||
|
||||
Object.keys(lifecycle).forEach((stateName) => {
|
||||
let color = "rgb(83, 92, 104)";
|
||||
if (stateName === this.props.currentStatus) {
|
||||
color = "rgb(192,255,0)";
|
||||
}else if(nextStates.includes(stateName)){
|
||||
color = "rgb(0,192,255)";
|
||||
}
|
||||
const node = createNode(stateName, color);
|
||||
// node.addPort()
|
||||
nodes.push(node);
|
||||
lifecycle[stateName].node = node;
|
||||
});
|
||||
|
||||
Object.keys(lifecycle).forEach((stateName) => {
|
||||
const state = lifecycle[stateName];
|
||||
//todo: remove checking property
|
||||
if (state.hasOwnProperty("proceedingStates")) {
|
||||
|
||||
state.proceedingStates.forEach((proceedingState) => {
|
||||
links.push(connectNodes(state.node, lifecycle[proceedingState].node));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
nodes.forEach((node) => {
|
||||
model.addNode(node);
|
||||
});
|
||||
links.forEach((link) => {
|
||||
model.addLink(link);
|
||||
});
|
||||
|
||||
|
||||
let distributedModel = getDistributedModel(engine, model);
|
||||
engine.setDiagramModel(distributedModel);
|
||||
|
||||
return (
|
||||
<div style={{height: 900}}>
|
||||
<SRD.DiagramWidget diagramEngine={engine} maxNumberPointsPerLink={10} smartRouting={true}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getDistributedModel(engine, model) {
|
||||
const serialized = model.serializeDiagram();
|
||||
const distributedSerializedDiagram = distributeElements(serialized);
|
||||
|
||||
//deserialize the model
|
||||
let deSerializedModel = new SRD.DiagramModel();
|
||||
deSerializedModel.deSerializeDiagram(distributedSerializedDiagram, engine);
|
||||
return deSerializedModel;
|
||||
}
|
||||
|
||||
function createNode(name, color) {
|
||||
const node = new SRD.DefaultNodeModel(name, color);
|
||||
node.addPort(new SRD.DefaultPortModel(true, inPortName, " "));
|
||||
node.addPort(new SRD.DefaultPortModel(false, outPortName, " "));
|
||||
return node;
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
|
||||
function connectNodes(nodeFrom, nodeTo) {
|
||||
return nodeFrom.getPort(outPortName).link(nodeTo.getPort(inPortName));
|
||||
}
|
||||
|
||||
export default LifeCycleGraph;
|
@ -1,16 +1,12 @@
|
||||
import keyMirror from 'keymirror';
|
||||
|
||||
// export const LOGIN = "LOGIN";
|
||||
// export const GET_APPS = "GET_APPS";
|
||||
// export const OPEN_RELEASES_MODAL = "OPEN_RELEASES_MODAL";
|
||||
// export const CLOSE_RELEASES_MODAL = "CLOSE_RELEASES_MODAL";
|
||||
|
||||
const ActionTypes = keyMirror({
|
||||
LOGIN: null,
|
||||
GET_APPS: null,
|
||||
OPEN_RELEASES_MODAL: null,
|
||||
CLOSE_RELEASES_MODAL: null,
|
||||
GET_RELEASE: null
|
||||
GET_RELEASE: null,
|
||||
GET_LIFECYCLE: null
|
||||
|
||||
});
|
||||
|
||||
|
@ -0,0 +1,56 @@
|
||||
import * as dagre from "dagre";
|
||||
import * as _ from "lodash";
|
||||
|
||||
const size = {
|
||||
width: 60,
|
||||
height: 60
|
||||
};
|
||||
|
||||
export function distributeElements(model) {
|
||||
let clonedModel = _.cloneDeep(model);
|
||||
let nodes = distributeGraph(clonedModel);
|
||||
nodes.forEach(node => {
|
||||
let modelNode = clonedModel.nodes.find(item => item.id === node.id);
|
||||
modelNode.x = node.x - node.width / 2;
|
||||
modelNode.y = node.y - node.height / 2;
|
||||
});
|
||||
return clonedModel;
|
||||
}
|
||||
|
||||
function distributeGraph(model) {
|
||||
let nodes = mapElements(model);
|
||||
let edges = mapEdges(model);
|
||||
let graph = new dagre.graphlib.Graph();
|
||||
graph.setGraph({});
|
||||
graph.setDefaultEdgeLabel(() => ({}));
|
||||
//add elements to dagre graph
|
||||
nodes.forEach(node => {
|
||||
graph.setNode(node.id, node.metadata);
|
||||
});
|
||||
edges.forEach(edge => {
|
||||
if (edge.from && edge.to) {
|
||||
graph.setEdge(edge.from, edge.to);
|
||||
}
|
||||
});
|
||||
//auto-distribute
|
||||
dagre.layout(graph);
|
||||
return graph.nodes().map(node => graph.node(node));
|
||||
}
|
||||
|
||||
function mapElements(model) {
|
||||
// dagre compatible format
|
||||
return model.nodes.map(node => ({ id: node.id, metadata: { ...size, id: node.id } }));
|
||||
}
|
||||
|
||||
function mapEdges(model) {
|
||||
// returns links which connects nodes
|
||||
// we check are there both from and to nodes in the model. Sometimes links can be detached
|
||||
return model.links
|
||||
.map(link => ({
|
||||
from: link.source,
|
||||
to: link.target
|
||||
}))
|
||||
.filter(
|
||||
item => model.nodes.find(node => node.id === item.from) && model.nodes.find(node => node.id === item.to)
|
||||
);
|
||||
}
|
Loading…
Reference in new issue