Skip to content

Commit

Permalink
Tornjak dashboard UI- Front End[Part 1] (#76)
Browse files Browse the repository at this point in the history
* tornjak dashboard design details

* fix rendering bugs

* fix navbar render bog on resize

* taking care of initial review nits

* removing title component

* readding title component

* dashboard data management

* cluster edit update

* expire time date reformat

* no data to show display for banner

* fixing ===

* material Ui version update

* merging changes from dashboard data management pr

* nits from review

* remove Dashboard folder

* renaming as dashboard lowercase

* cluster create form cluster types bug fix

* manager mode cluster create type bug fix

* expanded view tables for dashboard

* expanded view refactor tables dashboard

* removing unused variables and functions

* merging from dashboard frontend bug fixing pr

* removing agent update gitignore

* remove agent file

* nits in spiffe-entry-interface

Signed-off-by: Mohammed Abdi <mohammed.munir.abdi@ibm.com>
  • Loading branch information
mamy-CS authored and lumjjb committed Aug 9, 2021
1 parent c28690c commit 518d30e
Show file tree
Hide file tree
Showing 26 changed files with 3,240 additions and 128 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ agentlocaldb
bin/
ui/
ui-agent/
/agent
agent
Binary file removed agent
Binary file not shown.
2,061 changes: 2,009 additions & 52 deletions tornjak-frontend/package-lock.json

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions tornjak-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@carbon/charts": "^0.41.80",
"@carbon/charts-react": "^0.41.80",
"@carbon/themes": "^10.38.0",
"@material-ui/core": "^4.12.2",
"@material-ui/data-grid": "^4.0.0-alpha.33",
"@material-ui/icons": "^4.11.2",
"@material-ui/styles": "^4.11.4",
"axios": "^0.21.1",
"bootstrap": "^4.5.3",
"carbon-components": "^10.36.0",
"carbon-components-react": "^7.30.0",
"carbon-icons": "^7.0.7",
"d3": "^5.16.0",
"dotenv": "^8.2.0",
"node-sass": "^6.0.1",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-redux": "^7.2.2",
"react-router-dom": "^5.2.0",
"react-scripts": "^4.0.3",
"recharts": "^2.0.9",
"redux": "^4.0.5",
"redux-devtools-extension": "^2.13.9",
"redux-thunk": "^2.3.0",
Expand Down
1 change: 1 addition & 0 deletions tornjak-frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@
height: 30px;
position: fixed;
bottom: 0;
z-index: 2;
}
8 changes: 5 additions & 3 deletions tornjak-frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,24 @@ import EntryList from "./components/entry-list";
import EntryCreate from "./components/entry-create";
import ServerManagement from "./components/server-management";
import TornjakServerInfo from "./components/tornjak-server-info";
import { Provider } from 'react-redux'; //enables all components to have acces to everything inside our react app
import TornjakDashBoard from "./components/dashboard/tornjak-dashboard";
import { Provider } from 'react-redux'; //enables all components to have access to everything inside our react app
import store from 'redux/store';
import IsManager from './components/is_manager';
import './App.css';

function App() {
return (
<Provider store={store}>
<Router>
{/* <div className="container"> */}
<div>
<div className="nav-comp">
<NavigationBar />
</div>
<br />
<div className="rest-body">
<SelectServer />
<br />
{IsManager && <br />}
<Route path="/" exact component={AgentList} />
<Route path="/clusters" exact component={ClusterList} />
<Route path="/agents" exact component={AgentList} />
Expand All @@ -36,6 +37,7 @@ function App() {
<Route path="/agent/createjointoken" exact component={CreateJoinToken} />
<Route path="/cluster/clustermanagement" exact component={ClusterManagement} />
<Route path="/tornjak/serverinfo" exact component={TornjakServerInfo} />
<Route path="/tornjak/dashboard" exact component={TornjakDashBoard} />
<Route path="/server/manage" exact component={ServerManagement} />
<br /><br /><br />
<svg className="endbanneroutput">
Expand Down
43 changes: 43 additions & 0 deletions tornjak-frontend/src/charts/PieChart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from "react";
import { PieChart } from "@carbon/charts-react";
import "@carbon/charts/styles.css";
import { connect } from 'react-redux';
class PieChart1 extends React.Component {
constructor(props) {
super(props);
this.state = {
options: {
resizable: true,
height: "300px",
legend: {
alignment: "center"
},
pie: {
alignment: "center"
}
}
};
}

render() {
const { data } = this.props;
return (
<div>
<div>
</div>
<PieChart
data={data}
options={this.state.options}
/>
</div>
);
}
}

const mapStateToProps = state => ({
})

export default connect(
mapStateToProps,
{}
)(PieChart1);
7 changes: 5 additions & 2 deletions tornjak-frontend/src/components/agent-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { Component } from 'react';
import { connect } from 'react-redux';
import IsManager from './is_manager';
import Table from "tables/agents-list-table";
import { selectors, workloadSelectors} from '../data/data';
import { selectors, workloadSelectors, clusterType } from '../data/data';
import TornjakApi from './tornjak-api-helpers';
import {
serverSelectedFunc,
Expand All @@ -13,6 +13,7 @@ import {
tornjakMessageFunc,
workloadSelectorInfoFunc,
agentworkloadSelectorInfoFunc,
clusterTypeInfoFunc,
} from 'redux/actions';

const Agent = props => (
Expand Down Expand Up @@ -44,12 +45,14 @@ class AgentList extends Component {
}

componentDidMount() {
this.props.clusterTypeInfoFunc(clusterType); //set cluster type info
this.props.selectorInfoFunc(selectors); //set selector info
this.props.workloadSelectorInfoFunc(workloadSelectors); //set workload selector info
if (IsManager) {
if (this.props.globalServerSelected !== "") {
this.TornjakApi.populateAgentsUpdate(this.props.globalServerSelected, this.props.agentsListUpdateFunc, this.props.tornjakMessageFunc)
this.TornjakApi.refreshSelectorsState(this.props.globalServerSelected, this.props.agentworkloadSelectorInfoFunc);
this.TornjakApi.populateTornjakServerInfo(this.props.globalServerSelected, this.props.tornjakServerInfoUpdateFunc, this.props.tornjakMessageFunc);
}
} else {
this.TornjakApi.refreshLocalSelectorsState(this.props.agentworkloadSelectorInfoFunc);
Expand Down Expand Up @@ -118,5 +121,5 @@ const mapStateToProps = (state) => ({

export default connect(
mapStateToProps,
{ serverSelectedFunc, agentsListUpdateFunc, tornjakServerInfoUpdateFunc, serverInfoUpdateFunc, selectorInfoFunc, tornjakMessageFunc, workloadSelectorInfoFunc, agentworkloadSelectorInfoFunc }
{ serverSelectedFunc, agentsListUpdateFunc, tornjakServerInfoUpdateFunc, serverInfoUpdateFunc, selectorInfoFunc, tornjakMessageFunc, workloadSelectorInfoFunc, agentworkloadSelectorInfoFunc, clusterTypeInfoFunc }
)(AgentList)
4 changes: 2 additions & 2 deletions tornjak-frontend/src/components/cluster-create.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,10 @@ class ClusterCreate extends Component {
</div>
<div>
{this.state.statusOK === "OK" &&
<p className="success-message">--ENTRY SUCCESSFULLY CREATED--</p>
<p className="success-message">--CLUSTER SUCCESSFULLY CREATED--</p>
}
{(this.state.statusOK === "ERROR") &&
<p className="failed-message">--ENTRY CREATION FAILED--</p>
<p className="failed-message">--CLUSTER CREATION FAILED--</p>
}
</div>
<div className="alert-primary" role="alert">
Expand Down
13 changes: 10 additions & 3 deletions tornjak-frontend/src/components/cluster-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class ClusterEdit extends Component {
this.setState({ selectedServer: this.props.globalServerSelected });
}
}
if (prevProps.globalServerInfo !== this.props.globalServerInfo) {
if (prevProps.globalClustersList !== this.props.globalClustersList) {
this.prepareClusterNameList();
}
if (prevProps.globalAgentsList !== this.props.globalAgentsList) {
Expand Down Expand Up @@ -256,6 +256,13 @@ class ClusterEdit extends Component {
statusOK: "ERROR"
})
)
if (IsManager) {
if (this.props.globalServerSelected !== "" && (this.props.globalErrorMessage === "OK" || this.props.globalErrorMessage === "")) {
this.TornjakApi.populateClustersUpdate(this.props.globalServerSelected, this.props.clustersListUpdateFunc, this.props.tornjakMessageFunc);
}
} else {
this.TornjakApi.populateLocalClustersUpdate(this.props.clustersListUpdateFunc, this.props.tornjakMessageFunc);
}
}
render() {
const ClusterNames = this.state.clusterNameList, ClusterType = this.props.clusterTypeList;
Expand Down Expand Up @@ -370,10 +377,10 @@ class ClusterEdit extends Component {
</div>
<div>
{this.state.statusOK === "OK" &&
<p className="success-message">--ENTRY SUCCESSFULLY CREATED--</p>
<p className="success-message">--CLUSTER SUCCESSFULLY EDITED--</p>
}
{(this.state.statusOK === "ERROR") &&
<p className="failed-message">--ENTRY CREATION FAILED--</p>
<p className="failed-message">--CLUSTER EDIT FAILED--</p>
}
</div>
<div className="alert-primary" role="alert">
Expand Down
10 changes: 3 additions & 7 deletions tornjak-frontend/src/components/cluster-management.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Tabs, Tab } from 'carbon-components-react';
import ClusterCreate from './cluster-create';
import ClusterEdit from './cluster-edit';
import { connect } from 'react-redux';
import { clusterType } from '../data/data';
import IsManager from './is_manager';
import TornjakApi from './tornjak-api-helpers';
import './style.css';
Expand Down Expand Up @@ -32,7 +31,6 @@ class ClusterManagement extends Component {
}

componentDidMount() {
this.props.clusterTypeInfoFunc(clusterType); //set cluster type info
if (IsManager) {
if (this.props.globalServerSelected !== "" && (this.props.globalErrorMessage === "OK" || this.props.globalErrorMessage === "")) {
this.TornjakApi.populateAgentsUpdate(this.props.globalServerSelected, this.props.agentsListUpdateFunc, this.props.tornjakMessageFunc);
Expand Down Expand Up @@ -67,12 +65,10 @@ class ClusterManagement extends Component {

prepareClusterTypeList() {
let localClusterTypeList = [];
if (this.props.globalServerInfo.length === 0) {
return
}
//user prefered option
// user prefered option
localClusterTypeList[0] = this.state.clusterTypeManualEntryOption;
//agents
// cluster type list
console.log("this.props.globalClusterTypeInfo", this.props.globalClusterTypeInfo)
for (let i = 0; i < this.props.globalClusterTypeInfo.length; i++) {
localClusterTypeList[i + 1] = this.props.globalClusterTypeInfo[i];
}
Expand Down
101 changes: 101 additions & 0 deletions tornjak-frontend/src/components/dashboard/agents-dashboard-table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react';
import { connect } from 'react-redux';
import { withStyles } from '@material-ui/core/styles';
import renderCellExpand from './render-cell-expand';
import Table1 from './table/dashboard-table';
import SpiffeEntryInterface from '../spiffe-entry-interface';

const columns = [
{ field: "spiffeid", headerName: "Name", flex: 1, renderCell: renderCellExpand },
{ field: "numEntries", headerName: "Number of Entries", width: 200 },
{ field: "status", headerName: "Status", width: 120 },
{ field: "platformType", headerName: "Platform Type", width: 170 },
{ field: "clusterName", headerName: "Cluster Name", width: 190 }
];

const styles = theme => ({
seeMore: {
marginTop: theme.spacing(3),
},
});

class AgentDashboardTable extends React.Component {
constructor(props) {
super(props);
this.SpiffeEntryInterface = new SpiffeEntryInterface()
}

numberEntries(spiffeid) {
if (typeof this.props.globalEntries.globalEntriesList !== 'undefined') {
var entriesList = this.props.globalEntries.globalEntriesList.filter(entry => {
return (typeof entry !== 'undefined') && (this.SpiffeEntryInterface.getEntryParentid(entry) === spiffeid)
});
if (typeof entriesList === 'undefined') {
return 0
} else {
return entriesList.length
}
} else {
return 0
}
}

agent(entry) {
var thisSpiffeid = this.SpiffeEntryInterface.getAgentSpiffeid(entry);
// get status
var status = this.SpiffeEntryInterface.getAgentStatusString(entry);
// get tornjak metadata
var metadata_entry = this.SpiffeEntryInterface.getAgentMetadata(thisSpiffeid, this.props.globalAgents.globalAgentsWorkLoadAttestorInfo);
var plugin = "None"
var cluster = "None"
if (typeof metadata_entry["plugin"] !== 'undefined' && metadata_entry["plugin"].length !== 0) {
plugin = metadata_entry["plugin"]
}
if (typeof metadata_entry["cluster"] !== 'undefined' && metadata_entry["cluster"].length !== 0) {
cluster = metadata_entry["cluster"]
}
return {
id: thisSpiffeid,
spiffeid: thisSpiffeid,
numEntries: this.numberEntries(thisSpiffeid),
status: status,
platformType: plugin,
clusterName: cluster,
}
}

agentList() {
if (typeof this.props.globalAgents.globalAgentsList !== undefined) {
return this.props.globalAgents.globalAgentsList.map(currentAgent => {
return this.agent(currentAgent);
})
} else {
return []
}
}

render() {
const { numRows, tableType } = this.props;
var data = this.agentList();
return (
<div>
<Table1
title={"Agents"}
numRows={numRows}
tableType={tableType}
columns={columns}
data={data}/>
</div>
);
}

}

const mapStateToProps = (state) => ({
globalAgents: state.agents,
globalEntries: state.entries,
})

export default withStyles(styles)(
connect(mapStateToProps, {})(AgentDashboardTable)
)
Loading

0 comments on commit 518d30e

Please sign in to comment.