From d0c0967b6fc760753c183d6cd14cd60d80ef0d88 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Wed, 4 Aug 2021 15:48:20 -0400 Subject: [PATCH 01/18] dashboard details metadata and routing --- tornjak-frontend/package-lock.json | 6 +- tornjak-frontend/package.json | 2 +- .../dashboard/agents-dashboard-table.js | 51 ++++++-- .../dashboard/clusters-dashboard-table.js | 27 +++- .../dashboard/entries-dashboard-table.js | 42 +++++-- .../dashboard/table/dashboard-table.js | 35 +++++- .../components/dashboard/tornjak-dashboard.js | 116 +++++++++++++++++- tornjak-frontend/src/components/style.css | 20 +++ tornjak-frontend/src/redux/actions/index.js | 14 ++- tornjak-frontend/src/redux/actions/types.js | 1 + .../src/redux/reducers/tornjakReducer.js | 7 ++ 11 files changed, 286 insertions(+), 35 deletions(-) diff --git a/tornjak-frontend/package-lock.json b/tornjak-frontend/package-lock.json index 2ed61a4f..f88ed991 100644 --- a/tornjak-frontend/package-lock.json +++ b/tornjak-frontend/package-lock.json @@ -2800,9 +2800,9 @@ } }, "@material-ui/core": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.2.tgz", - "integrity": "sha512-Q1npB8V73IC+eV2X6as+g71MpEGQwqKHUI2iujY62npk35V8nMx/bUXAHjv5kKG1BZ8s8XUWoG6s/VkjYPjjQA==", + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.3.tgz", + "integrity": "sha512-sdpgI/PL56QVsEJldwEe4FFaFTLUqN+rd7sSZiRCdx2E/C7z5yK0y/khAWVBH24tXwto7I1hCzNWfJGZIYJKnw==", "requires": { "@babel/runtime": "^7.4.4", "@material-ui/styles": "^4.11.4", diff --git a/tornjak-frontend/package.json b/tornjak-frontend/package.json index c4b6356a..27bb2876 100644 --- a/tornjak-frontend/package.json +++ b/tornjak-frontend/package.json @@ -6,7 +6,7 @@ "@carbon/charts": "^0.41.80", "@carbon/charts-react": "^0.41.80", "@carbon/themes": "^10.38.0", - "@material-ui/core": "^4.12.2", + "@material-ui/core": "^4.12.3", "@material-ui/data-grid": "^4.0.0-alpha.33", "@material-ui/icons": "^4.11.2", "@material-ui/styles": "^4.11.4", diff --git a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js index f05c0340..6856e4c5 100644 --- a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js @@ -7,10 +7,10 @@ import SpiffeHelper from '../spiffe-helper'; const columns = [ { field: "spiffeid", headerName: "Name", flex: 1, renderCell: renderCellExpand }, + { field: "clusterName", headerName: "Cluster Name", width: 190 }, { 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 => ({ @@ -22,6 +22,8 @@ const styles = theme => ({ class AgentDashboardTable extends React.Component { constructor(props) { super(props); + this.state = { + }; this.SpiffeHelper = new SpiffeHelper() } @@ -31,13 +33,13 @@ class AgentDashboardTable extends React.Component { // Also check for parent IDs associated with the agent let agentEntries = agentEntriesDict[spiffeid]; if (agentEntries !== undefined) { - for (let j=0; j < agentEntries.length; j++) { - validIds.add(this.SpiffeHelper.getEntrySpiffeid(agentEntries[j])); + for (let j = 0; j < agentEntries.length; j++) { + validIds.add(this.SpiffeHelper.getEntrySpiffeid(agentEntries[j])); } } if (typeof this.props.globalEntries.globalEntriesList !== 'undefined') { - var entriesList = this.props.globalEntries.globalEntriesList.filter(entry=> { + var entriesList = this.props.globalEntries.globalEntriesList.filter(entry => { return (typeof entry !== 'undefined') && validIds.has(this.SpiffeHelper.getEntryParentid(entry)); }); @@ -77,8 +79,8 @@ class AgentDashboardTable extends React.Component { agentList() { if ((typeof this.props.globalEntries.globalEntriesList === 'undefined') || - (typeof this.props.globalAgents.globalAgentsList === 'undefined')) { - return []; + (typeof this.props.globalAgents.globalAgentsList === 'undefined')) { + return []; } let agentEntriesDict = this.SpiffeHelper.getAgentsEntries(this.props.globalAgents.globalAgentsList, this.props.globalEntries.globalEntriesList) @@ -87,16 +89,46 @@ class AgentDashboardTable extends React.Component { }) } + selectedData() { + var data = this.agentList(), filteredData = [], selectedDataKey = [], selectedData = this.props.selectedData, clickedDashboardTable = this.props.globalClickedDashboardTable; + if (selectedData === undefined) + return data; + if (clickedDashboardTable === "clustersdetails") { + for (let i = 0; i < selectedData.length; i++) { + selectedDataKey[i] = selectedData[i].name; + } + for (let i = 0; i < data.length; i++) { + for (let j = 0; j < selectedDataKey.length; j++) { + if (data[i].clusterName === selectedDataKey[j]) { + filteredData.push(data[i]); + } + } + } + } else if (clickedDashboardTable === "entriesdetails") { + for (let i = 0; i < selectedData.length; i++) { + selectedDataKey[i] = selectedData[i].value.parentId; + } + for (let i = 0; i < data.length; i++) { + for (let j = 0; j < selectedDataKey.length; j++) { + if (data[i].id === selectedDataKey[j]) { + filteredData.push(data[i]); + } + } + } + } + return filteredData; + } + render() { const { numRows } = this.props; - var data = this.agentList(); + var data = this.selectedData(); return (
- + data={data} />
); } @@ -106,6 +138,7 @@ class AgentDashboardTable extends React.Component { const mapStateToProps = (state) => ({ globalAgents: state.agents, globalEntries: state.entries, + globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable, }) export default withStyles(styles)( diff --git a/tornjak-frontend/src/components/dashboard/clusters-dashboard-table.js b/tornjak-frontend/src/components/dashboard/clusters-dashboard-table.js index a57bdcee..d5acff44 100644 --- a/tornjak-frontend/src/components/dashboard/clusters-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/clusters-dashboard-table.js @@ -7,8 +7,8 @@ import SpiffeHelper from '../spiffe-helper'; const columns = [ { field: "name", headerName: "Name", width: 200 }, { field: "created", headerName: "Created", width: 300 }, - { field: "numNodes", headerName: "Number Of Nodes", width: 300}, - { field: "numEntries", headerName: "Number of Entries", width: 200} + { field: "numNodes", headerName: "Number Of Nodes", width: 300 }, + { field: "numEntries", headerName: "Number of Entries", width: 200 } ]; const styles = theme => ({ @@ -62,16 +62,33 @@ class ClusterDashboardTable extends React.Component { } } + selectedData() { + var data = this.clusterList(), filteredData = [], selectedDataKey = [], selectedData = this.props.selectedData; + if (selectedData === undefined) + return data; + for (let i = 0; i < selectedData.length; i++) { + selectedDataKey[i] = selectedData[i].value.clusterName; + } + for (let i = 0; i < data.length; i++) { + for (let j = 0; j < selectedDataKey.length; j++) { + if ((data[i].clusterName === selectedDataKey[j]) || (data[i].name === selectedDataKey[j])) { + filteredData.push(data[i]); + } + } + } + return filteredData; + } + render() { const { numRows } = this.props; - var data = this.clusterList(); + var data = this.selectedData(); return (
- + data={data} />
); } diff --git a/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js b/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js index 4b5827fc..a272bfbc 100644 --- a/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js @@ -6,16 +6,16 @@ import TableDashboard from './table/dashboard-table'; import SpiffeHelper from '../spiffe-helper' const columns = [ - { field: "id", headerName: "ID", width: 200, renderCell: renderCellExpand}, - { field: "spiffeid", headerName: "Name", width: 300, renderCell: renderCellExpand}, - { field: "parentId", headerName: "Parent ID", width: 250, renderCell: renderCellExpand}, - { field: "adminFlag", headerName: "Admin Flag", width: 150}, - { field: "entryExpireTime", headerName: "Entry Expire Time", width: 190}, - { field: "platformType", headerName: "Platform Type", width: 170}, - { field: "clusterName", headerName: "Cluster Name", width: 190} + { field: "id", headerName: "ID", width: 170, renderCell: renderCellExpand }, + { field: "spiffeid", headerName: "Name", width: 170, renderCell: renderCellExpand }, + { field: "parentId", headerName: "Parent ID", width: 170, renderCell: renderCellExpand }, + { field: "clusterName", headerName: "Cluster Name", width: 170 }, + { field: "entryExpireTime", headerName: "Entry Expire Time", width: 190 }, + { field: "platformType", headerName: "Platform Type", width: 170 }, + { field: "adminFlag", headerName: "Admin Flag", width: 150 }, ]; -const styles = ( theme => ({ +const styles = (theme => ({ seeMore: { marginTop: theme.spacing(3), }, @@ -45,7 +45,7 @@ class EntriesDashBoardTable extends React.Component { var expTime = "No Expiry Time" if (typeof entry.expires_at !== 'undefined') { var d = new Date(this.SpiffeHelper.getEntryExpiryMillisecondsFromEpoch(entry)) - expTime = d.toLocaleDateString("en-US", {month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: false}) + expTime = d.toLocaleDateString("en-US", { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: false }) } return { id: entry.id, @@ -68,16 +68,33 @@ class EntriesDashBoardTable extends React.Component { } } + selectedData() { + var data = this.entryList(), filteredData = [], selectedDataKey = [], selectedData = this.props.selectedData, clickedDashboardTable = this.props.globalClickedDashboardTable; + if (selectedData === undefined) + return data; + for (let i = 0; i < selectedData.length; i++) { + selectedDataKey[i] = selectedData[i].name; + } + for (let i = 0; i < data.length; i++) { + for (let j = 0; j < selectedDataKey.length; j++) { + if ((data[i].clusterName === selectedDataKey[j]) || (data[i].parentId === selectedDataKey[j])) { + filteredData.push(data[i]); + } + } + } + return filteredData; + } + render() { const { numRows } = this.props; - var data = this.entryList(); + var data = this.selectedData(); return (
- + data={data} />
); } @@ -86,6 +103,7 @@ class EntriesDashBoardTable extends React.Component { const mapStateToProps = state => ({ globalAgents: state.agents, globalEntriesList: state.entries, + globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable, }) export default withStyles(styles)( diff --git a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js index dddee02b..0ebc1f82 100644 --- a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js @@ -1,18 +1,27 @@ import React from "react"; import { connect } from 'react-redux'; -import { DataGrid, GridToolbar } from "@material-ui/data-grid"; +import { DataGrid, GridToolbar, GridLinkOperator } from "@material-ui/data-grid"; import Title from '../title'; import { Button, } from '@material-ui/core'; import { clickedDashboardTabelFunc, + selectedDashboardTableData } from 'redux/actions'; + class TableDashboard extends React.Component { constructor(props) { super(props); this.state = { + selectedRows: [] }; + this.prepareSelectedRowsData = this.prepareSelectedRowsData.bind(this); + } + + prepareSelectedRowsData() { + var selectedRows = Array.from(this.state.selectedRows, ([name, value]) => ({ name, value })); + this.props.selectedDashboardTableData(selectedRows) } render() { @@ -28,6 +37,18 @@ class TableDashboard extends React.Component { {title} +
{ + this.setState({ selectedRows: selectedRows.api.current.getSelectedRows() }) + //console.log(selectedRows.api.current.getSelectedRows()) + }} components={{ Toolbar: GridToolbar, }} + // filterModel={{ + // linkOperator: GridLinkOperator, + // }} />
@@ -46,10 +74,11 @@ class TableDashboard extends React.Component { } const mapStateToProps = state => ({ - globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable + globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable, + globalSelectedDashboardData: state.tornjak.globalSelectedDashboardData }) export default connect( mapStateToProps, - { clickedDashboardTabelFunc } + { clickedDashboardTabelFunc, selectedDashboardTableData } )(TableDashboard); diff --git a/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js b/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js index 2db47e87..e150a807 100644 --- a/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js +++ b/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js @@ -124,6 +124,7 @@ const styles = theme => ({ container: { //container for root paddingTop: theme.spacing(4), paddingBottom: theme.spacing(4), + marginLeft: 0 }, paper: { //container for all grids padding: theme.spacing(2), @@ -348,6 +349,118 @@ class TornjakDashboard extends React.Component { } + {(this.props.globalClickedDashboardTable === "clustersdetails") && +
+ + + +

Cluster Name : {this.props.globalSelectedDashboardData[0].value.name}

+

Metadata

+
+

Created : {this.props.globalSelectedDashboardData[0].value.created}

+

Number of Nodes : {this.props.globalSelectedDashboardData[0].value.numNodes}

+

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

+
+
+
+ + {/* Agents Table */} + + + + + + + + {/* Entries Table */} + + + + + + +
+ } + {(this.props.globalClickedDashboardTable === "agentsdetails") && +
+ + + +

Agent Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

+

Metadata

+
+

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

+

Status : {this.props.globalSelectedDashboardData[0].value.status}

+

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

+

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

+
+
+
+ + {/* Clusters Table */} + + + + + + + + {/* Entries Table */} + + + + + + +
+ } + {(this.props.globalClickedDashboardTable === "entriesdetails") && +
+ + + +

Entry ID : {this.props.globalSelectedDashboardData[0].value.id}

+

Metadata

+
+

Entry Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

+

Parent ID : {this.props.globalSelectedDashboardData[0].value.parentId}

+

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

+

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

+

Is Admin : {this.props.globalSelectedDashboardData[0].value.adminFlag.toString().toUpperCase()}

+

Entry Expire Time: {this.props.globalSelectedDashboardData[0].value.entryExpireTime}

+
+
+
+ + {/* Clusters Table */} + + + + + + + + {/* Agents Table */} + + + + + + +
+ } ) @@ -361,7 +474,8 @@ const mapStateToProps = (state) => ({ globalErrorMessage: state.tornjak.globalErrorMessage, globalAgents: state.agents, globalEntries: state.entries.globalEntriesList, - globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable + globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable, + globalSelectedDashboardData: state.tornjak.globalSelectedDashboardData }) export default withStyles(styles)(connect( diff --git a/tornjak-frontend/src/components/style.css b/tornjak-frontend/src/components/style.css index 306accd0..74637fa5 100644 --- a/tornjak-frontend/src/components/style.css +++ b/tornjak-frontend/src/components/style.css @@ -161,4 +161,24 @@ .no-data { margin-top: 120px; margin-left: 200px; + } + + .details-title { + font-size:x-large; + color: rgb(89, 103, 185) + } + + .metadata-tag { + font-weight: bold; + font-size:large; + margin-top: 10px; + } + + .dashboard-detals-line { + margin-left: 0; + width: 1200px; + } + + .metadata-details { + font-size:large; } \ No newline at end of file diff --git a/tornjak-frontend/src/redux/actions/index.js b/tornjak-frontend/src/redux/actions/index.js index 0be771d5..7a5650c1 100644 --- a/tornjak-frontend/src/redux/actions/index.js +++ b/tornjak-frontend/src/redux/actions/index.js @@ -11,7 +11,8 @@ import { GLOBAL_AGENTS_WORKLOADATTESTOR_INFO, GLOBAL_CLUSTERS_LIST, GLOBAL_CLUSTER_TYPE_INFO, - GLOBAL_CLICKED_DASHBOARD_TABLE + GLOBAL_CLICKED_DASHBOARD_TABLE, + GLOBAL_SELECTED_DASHBOARD_DATA } from './types'; // Expected input - List of clusters with their info @@ -238,3 +239,14 @@ export function clickedDashboardTabelFunc(globalClickedDashboardTable) { }); } } + +// Expected input - clicked dashboard row data from specific dashboard table +// selectedDashboardTableData returns the selected dashboard tabel data +export function selectedDashboardTableData(globalSelectedDashboardData) { + return dispatch => { + dispatch({ + type: GLOBAL_SELECTED_DASHBOARD_DATA, + payload: globalSelectedDashboardData + }); + } +} diff --git a/tornjak-frontend/src/redux/actions/types.js b/tornjak-frontend/src/redux/actions/types.js index 624f4765..a9fec5d9 100644 --- a/tornjak-frontend/src/redux/actions/types.js +++ b/tornjak-frontend/src/redux/actions/types.js @@ -1,6 +1,7 @@ //tornjak export const GLOBAL_MESSAGE = 'GLOBAL_MESSAGE'; export const GLOBAL_CLICKED_DASHBOARD_TABLE = 'GLOBAL_CLICKED_DASHBOARD_TABLE'; +export const GLOBAL_SELECTED_DASHBOARD_DATA = 'GLOBAL_SELECTED_DASHBOARD_DATA'; //servers export const GLOBAL_SERVER_SELECTED = 'GLOBAL_SERVER_SELECTED'; diff --git a/tornjak-frontend/src/redux/reducers/tornjakReducer.js b/tornjak-frontend/src/redux/reducers/tornjakReducer.js index 8c72afe6..6f6eab3d 100644 --- a/tornjak-frontend/src/redux/reducers/tornjakReducer.js +++ b/tornjak-frontend/src/redux/reducers/tornjakReducer.js @@ -1,11 +1,13 @@ import { GLOBAL_MESSAGE, GLOBAL_CLICKED_DASHBOARD_TABLE, + GLOBAL_SELECTED_DASHBOARD_DATA, } from '../actions/types'; const initialState = { globalErrorMessage: "", globalClickedDashboardTable: "", + globalSelectedDashboardData: [], }; export default function tornjakReducer(state = initialState, action) { @@ -20,6 +22,11 @@ export default function tornjakReducer(state = initialState, action) { ...state, globalClickedDashboardTable: action.payload }; + case GLOBAL_SELECTED_DASHBOARD_DATA: + return { + ...state, + globalSelectedDashboardData: action.payload + }; default: return state; } From 0d90680f3ba4751f2a3ebef749374dac539329ce Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Wed, 4 Aug 2021 15:55:33 -0400 Subject: [PATCH 02/18] removing unused import --- .../src/components/dashboard/table/dashboard-table.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js index 0ebc1f82..080dd166 100644 --- a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js @@ -1,6 +1,6 @@ import React from "react"; import { connect } from 'react-redux'; -import { DataGrid, GridToolbar, GridLinkOperator } from "@material-ui/data-grid"; +import { DataGrid, GridToolbar } from "@material-ui/data-grid"; import Title from '../title'; import { Button, From a61fc58aba17c7a60306195271c10da62bdc1e73 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Wed, 4 Aug 2021 16:04:07 -0400 Subject: [PATCH 03/18] removing unused declared variable --- .../src/components/dashboard/entries-dashboard-table.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js b/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js index a272bfbc..1ea8db25 100644 --- a/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js @@ -69,7 +69,7 @@ class EntriesDashBoardTable extends React.Component { } selectedData() { - var data = this.entryList(), filteredData = [], selectedDataKey = [], selectedData = this.props.selectedData, clickedDashboardTable = this.props.globalClickedDashboardTable; + var data = this.entryList(), filteredData = [], selectedDataKey = [], selectedData = this.props.selectedData; if (selectedData === undefined) return data; for (let i = 0; i < selectedData.length; i++) { From 103d0ff5e9f830982d764437378017e8f1652ea8 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Thu, 5 Aug 2021 11:59:38 -0400 Subject: [PATCH 04/18] make details page seperate component --- .../components/dashboard/dashboard-details.js | 169 ++++++++++++++++++ .../components/dashboard/tornjak-dashboard.js | 114 +----------- 2 files changed, 171 insertions(+), 112 deletions(-) create mode 100644 tornjak-frontend/src/components/dashboard/dashboard-details.js diff --git a/tornjak-frontend/src/components/dashboard/dashboard-details.js b/tornjak-frontend/src/components/dashboard/dashboard-details.js new file mode 100644 index 00000000..83021cf6 --- /dev/null +++ b/tornjak-frontend/src/components/dashboard/dashboard-details.js @@ -0,0 +1,169 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import { withStyles } from '@material-ui/core/styles'; +// Components +import { + Container, + Grid, + Paper, + } from '@material-ui/core'; + // Tables +import ClustersTable from './clusters-dashboard-table'; +import AgentsTable from './agents-dashboard-table'; +import EntriesTable from './entries-dashboard-table'; + +const styles = theme => ({ + seeMore: { + marginTop: theme.spacing(3), + }, + container: { //container for root + paddingTop: theme.spacing(4), + paddingBottom: theme.spacing(4), + marginLeft: 0 + }, + paper: { //container for all grids + padding: theme.spacing(2), + display: 'flex', + overflow: 'auto', + flexDirection: 'column', + marginBottom: 20 + }, +}); + +class DashboardDetails extends React.Component { + constructor(props) { + super(props); + this.state = { + }; + } + + render() { + const { classes } = this.props; + return ( +
+ {(this.props.globalClickedDashboardTable === "clustersdetails") && +
+ + + +

Cluster Name : {this.props.globalSelectedDashboardData[0].value.name}

+

Metadata

+
+

Created : {this.props.globalSelectedDashboardData[0].value.created}

+

Number of Nodes : {this.props.globalSelectedDashboardData[0].value.numNodes}

+

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

+
+
+
+ + {/* Agents Table */} + + + + + + + + {/* Entries Table */} + + + + + + +
+ } + {(this.props.globalClickedDashboardTable === "agentsdetails") && +
+ + + +

Agent Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

+

Metadata

+
+

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

+

Status : {this.props.globalSelectedDashboardData[0].value.status}

+

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

+

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

+
+
+
+ + {/* Clusters Table */} + + + + + + + + {/* Entries Table */} + + + + + + +
+ } + {(this.props.globalClickedDashboardTable === "entriesdetails") && +
+ + + +

Entry ID : {this.props.globalSelectedDashboardData[0].value.id}

+

Metadata

+
+

Entry Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

+

Parent ID : {this.props.globalSelectedDashboardData[0].value.parentId}

+

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

+

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

+

Is Admin : {this.props.globalSelectedDashboardData[0].value.adminFlag.toString().toUpperCase()}

+

Entry Expire Time: {this.props.globalSelectedDashboardData[0].value.entryExpireTime}

+
+
+
+ + {/* Clusters Table */} + + + + + + + + {/* Agents Table */} + + + + + + +
+ } +
+ ); + } + +} + +const mapStateToProps = (state) => ({ + globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable, + globalSelectedDashboardData: state.tornjak.globalSelectedDashboardData +}) + +export default withStyles(styles)( + connect(mapStateToProps, {})(DashboardDetails) +) \ No newline at end of file diff --git a/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js b/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js index e150a807..eaa5cfdf 100644 --- a/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js +++ b/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js @@ -49,6 +49,7 @@ import { clickedDashboardTabelFunc, } from 'redux/actions'; import SpiffeHelper from '../spiffe-helper'; +import DashboardDetails from './dashboard-details'; const drawerWidth = 240; const drawerHeight = '100%'; @@ -349,118 +350,7 @@ class TornjakDashboard extends React.Component { } - {(this.props.globalClickedDashboardTable === "clustersdetails") && -
- - - -

Cluster Name : {this.props.globalSelectedDashboardData[0].value.name}

-

Metadata

-
-

Created : {this.props.globalSelectedDashboardData[0].value.created}

-

Number of Nodes : {this.props.globalSelectedDashboardData[0].value.numNodes}

-

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

-
-
-
- - {/* Agents Table */} - - - - - - - - {/* Entries Table */} - - - - - - -
- } - {(this.props.globalClickedDashboardTable === "agentsdetails") && -
- - - -

Agent Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

-

Metadata

-
-

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

-

Status : {this.props.globalSelectedDashboardData[0].value.status}

-

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

-

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

-
-
-
- - {/* Clusters Table */} - - - - - - - - {/* Entries Table */} - - - - - - -
- } - {(this.props.globalClickedDashboardTable === "entriesdetails") && -
- - - -

Entry ID : {this.props.globalSelectedDashboardData[0].value.id}

-

Metadata

-
-

Entry Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

-

Parent ID : {this.props.globalSelectedDashboardData[0].value.parentId}

-

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

-

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

-

Is Admin : {this.props.globalSelectedDashboardData[0].value.adminFlag.toString().toUpperCase()}

-

Entry Expire Time: {this.props.globalSelectedDashboardData[0].value.entryExpireTime}

-
-
-
- - {/* Clusters Table */} - - - - - - - - {/* Agents Table */} - - - - - - -
- } + ) From e1da96de9e2587e2f513b4541a24eea45392257e Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Thu, 5 Aug 2021 17:37:45 -0400 Subject: [PATCH 05/18] details page with unique links --- tornjak-frontend/src/App.js | 2 + .../components/dashboard/dashboard-details.js | 258 ++++++++++-------- .../components/dashboard/dashboard-drawer.js | 236 ++++++++++++++++ .../dashboard/table/dashboard-table.js | 29 +- .../components/dashboard/tornjak-dashboard.js | 157 +---------- tornjak-frontend/src/components/navbar.js | 20 +- 6 files changed, 412 insertions(+), 290 deletions(-) create mode 100644 tornjak-frontend/src/components/dashboard/dashboard-drawer.js diff --git a/tornjak-frontend/src/App.js b/tornjak-frontend/src/App.js index 012da190..adf82754 100644 --- a/tornjak-frontend/src/App.js +++ b/tornjak-frontend/src/App.js @@ -16,6 +16,7 @@ import { Provider } from 'react-redux'; //enables all components to have access import store from 'redux/store'; import IsManager from './components/is_manager'; import './App.css'; +import dashboardDetails from 'components/dashboard/dashboard-details'; function App() { return ( @@ -38,6 +39,7 @@ function App() { +


diff --git a/tornjak-frontend/src/components/dashboard/dashboard-details.js b/tornjak-frontend/src/components/dashboard/dashboard-details.js index 83021cf6..8c1c0b92 100644 --- a/tornjak-frontend/src/components/dashboard/dashboard-details.js +++ b/tornjak-frontend/src/components/dashboard/dashboard-details.js @@ -6,28 +6,37 @@ import { Container, Grid, Paper, - } from '@material-ui/core'; - // Tables +} from '@material-ui/core'; +// Tables import ClustersTable from './clusters-dashboard-table'; import AgentsTable from './agents-dashboard-table'; import EntriesTable from './entries-dashboard-table'; +import DashboardDrawer from './dashboard-drawer'; +const drawerWidth = 240; +const drawerHeight = '100%'; const styles = theme => ({ - seeMore: { - marginTop: theme.spacing(3), + root: { + marginTop: -25, + marginLeft: -20, + display: 'flex', + }, + appBarSpacer: theme.mixins.toolbar, + content: { + flexGrow: 1, }, container: { //container for root paddingTop: theme.spacing(4), paddingBottom: theme.spacing(4), marginLeft: 0 - }, - paper: { //container for all grids + }, + paper: { //container for all grids padding: theme.spacing(2), display: 'flex', overflow: 'auto', flexDirection: 'column', marginBottom: 20 - }, + }, }); class DashboardDetails extends React.Component { @@ -36,123 +45,130 @@ class DashboardDetails extends React.Component { this.state = { }; } - render() { const { classes } = this.props; return ( -
- {(this.props.globalClickedDashboardTable === "clustersdetails") && -
- - - -

Cluster Name : {this.props.globalSelectedDashboardData[0].value.name}

-

Metadata

-
-

Created : {this.props.globalSelectedDashboardData[0].value.created}

-

Number of Nodes : {this.props.globalSelectedDashboardData[0].value.numNodes}

-

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

-
-
-
- - {/* Agents Table */} - - - - - - - - {/* Entries Table */} - - - - - - -
- } - {(this.props.globalClickedDashboardTable === "agentsdetails") && -
- - - -

Agent Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

-

Metadata

-
-

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

-

Status : {this.props.globalSelectedDashboardData[0].value.status}

-

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

-

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

-
-
-
- - {/* Clusters Table */} - - - - - - - - {/* Entries Table */} - - - - - - -
- } - {(this.props.globalClickedDashboardTable === "entriesdetails") && -
- - - -

Entry ID : {this.props.globalSelectedDashboardData[0].value.id}

-

Metadata

-
-

Entry Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

-

Parent ID : {this.props.globalSelectedDashboardData[0].value.parentId}

-

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

-

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

-

Is Admin : {this.props.globalSelectedDashboardData[0].value.adminFlag.toString().toUpperCase()}

-

Entry Expire Time: {this.props.globalSelectedDashboardData[0].value.entryExpireTime}

-
-
-
- - {/* Clusters Table */} - - - - - - - - {/* Agents Table */} - - - - - - -
- } +
+ +
+
+ {(this.props.globalSelectedDashboardData.length !== 0) && +
+ {(this.props.globalClickedDashboardTable === "clustersdetails") && +
+ + + +

Cluster Name : {this.props.globalSelectedDashboardData[0].value.name}

+

Metadata

+
+

Created : {this.props.globalSelectedDashboardData[0].value.created}

+

Number of Nodes : {this.props.globalSelectedDashboardData[0].value.numNodes}

+

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

+
+
+
+ + {/* Agents Table */} + + + + + + + + {/* Entries Table */} + + + + + + +
+ } + {(this.props.globalClickedDashboardTable === "agentsdetails") && +
+ + + +

Agent Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

+

Metadata

+
+

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

+

Status : {this.props.globalSelectedDashboardData[0].value.status}

+

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

+

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

+
+
+
+ + {/* Clusters Table */} + + + + + + + + {/* Entries Table */} + + + + + + +
+ } + {(this.props.globalClickedDashboardTable === "entriesdetails") && +
+ + + +

Entry ID : {this.props.globalSelectedDashboardData[0].value.id}

+

Metadata

+
+

Entry Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

+

Parent ID : {this.props.globalSelectedDashboardData[0].value.parentId}

+

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

+

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

+

Is Admin : {this.props.globalSelectedDashboardData[0].value.adminFlag.toString().toUpperCase()}

+

Entry Expire Time: {this.props.globalSelectedDashboardData[0].value.entryExpireTime}

+
+
+
+ + {/* Clusters Table */} + + + + + + + + {/* Agents Table */} + + + + + + +
+ } +
+ } +
); } diff --git a/tornjak-frontend/src/components/dashboard/dashboard-drawer.js b/tornjak-frontend/src/components/dashboard/dashboard-drawer.js new file mode 100644 index 00000000..b1d017af --- /dev/null +++ b/tornjak-frontend/src/components/dashboard/dashboard-drawer.js @@ -0,0 +1,236 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import clsx from 'clsx'; +import { withStyles } from '@material-ui/core/styles'; +// Components +import { + CssBaseline, + Drawer, + AppBar, + Toolbar, + List, + Typography, + Divider, + IconButton, + ListItem, + ListItemIcon, + ListItemText, + ListSubheader, +} from '@material-ui/core'; +// Icons +import MenuIcon from '@material-ui/icons/Menu'; +import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'; +import DashboardIcon from '@material-ui/icons/Dashboard'; +import PeopleIcon from '@material-ui/icons/People'; +import BarChartIcon from '@material-ui/icons/BarChart'; +import LayersIcon from '@material-ui/icons/Layers'; +import { + clickedDashboardTabelFunc, +} from 'redux/actions'; +const drawerWidth = 240; +const drawerHeight = '100%'; + +const styles = theme => ({ + root: { + marginTop: -25, + marginLeft: -20, + display: 'flex', + }, + toolbar: { + paddingRight: 24, // keep right padding when drawer closed + }, + toolbarIcon: { //drawer icon close + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-end', + padding: '0 8px', + ...theme.mixins.toolbar, + }, + appBar: { //appbar + backgroundColor: 'grey', + marginTop: 52, + zIndex: 2, + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + }, + appBarShift: { //appbar on shift/ open + marginLeft: drawerWidth, + width: `calc(100% - ${drawerWidth}px)`, + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + menuButton: { //menu button next to Tornjak Dashboard title on view + marginRight: 35, + }, + menuButtonHidden: { //menu button next to Tornjak Dashboard title on hidden + display: 'none', + }, + title: { + flexGrow: 1, + }, + drawerPaper: { //dashboard side drawer on open + position: 'relative', + whiteSpace: 'nowrap', + zIndex: 1, + width: drawerWidth, + height: drawerHeight, + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + drawerPaperClose: { //dashboard side drawer on close + overflowX: 'hidden', + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + width: theme.spacing(7), + [theme.breakpoints.up('sm')]: { + width: theme.spacing(9), + }, + }, + appBarSpacer: theme.mixins.toolbar, + content: { + flexGrow: 1, + }, + container: { //container for root + paddingTop: theme.spacing(4), + paddingBottom: theme.spacing(4), + marginLeft: 0 + }, + paper: { //container for all grids + padding: theme.spacing(2), + display: 'flex', + overflow: 'auto', + flexDirection: 'column', + marginBottom: 20 + }, + fixedHeight: { + height: 370, //height of piechart container + }, +}); + +class DashboardDrawer extends React.Component { + constructor(props) { + super(props); + const { classes } = this.props; + this.state = { + open: true, + }; + this.handleDrawerOpen = () => this.setState({ open: true }) + this.handleDrawerClose = () => this.setState({ open: false }) + this.fixedHeightPaper = clsx(classes.paper, classes.fixedHeight) + } + + render() { + const { classes } = this.props; + return ( +
+ + + + + + + + Tornjak Dashboard + + + + +
+ + + +
+ + +
+ { + this.props.clickedDashboardTabelFunc("dashboard"); + const path = "/tornjak/dashboard"; + if (location.href !== location.origin + path) + location.href = path; + }}> + + + + + + Details + { + this.props.clickedDashboardTabelFunc("clusters"); + const path = "/tornjak/dashboard"; + if (location.href !== location.origin + path) + location.href = path; + }}> + + + + + + { + this.props.clickedDashboardTabelFunc("agents"); + const path = "/tornjak/dashboard"; + if (location.href !== location.origin + path) + location.href = path; + }}> + + + + + + { + this.props.clickedDashboardTabelFunc("entries"); + const path = "/tornjak/dashboard"; + console.log("location.href", location) + if (location.href !== location.origin + path) + location.href = path; + }}> + + + + + +
+
+ +
+
+ ); + } + +} + +const mapStateToProps = (state) => ({ + globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable, +}) + +export default withStyles(styles)( + connect(mapStateToProps, { clickedDashboardTabelFunc })(DashboardDrawer) +) diff --git a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js index 080dd166..fe66949e 100644 --- a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js @@ -9,21 +9,26 @@ import { clickedDashboardTabelFunc, selectedDashboardTableData } from 'redux/actions'; +import DashboardDetails from '../dashboard-details'; class TableDashboard extends React.Component { constructor(props) { super(props); this.state = { - selectedRows: [] + selectedRows: [], + detailsLink: "" }; - this.prepareSelectedRowsData = this.prepareSelectedRowsData.bind(this); + this.detailsLink = this.detailsLink.bind(this); } - prepareSelectedRowsData() { - var selectedRows = Array.from(this.state.selectedRows, ([name, value]) => ({ name, value })); - this.props.selectedDashboardTableData(selectedRows) + detailsLink() { + const { title } = this.props; + if (this.state.selectedRows.length !== 0) { + var detailsLink = "/tornjak/dashboard/details/" + title.toLowerCase() + "/" + this.state.selectedRows[0].name; + console.log(detailsLink) + } + return detailsLink; } - render() { const { numRows, data, columns, title } = this.props; return ( @@ -38,13 +43,16 @@ class TableDashboard extends React.Component {
diff --git a/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js b/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js index eaa5cfdf..43f0ab00 100644 --- a/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js +++ b/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js @@ -4,29 +4,10 @@ import clsx from 'clsx'; import { withStyles } from '@material-ui/core/styles'; // Components import { - CssBaseline, - Drawer, - AppBar, - Toolbar, - List, - Typography, - Divider, - IconButton, Container, Grid, Paper, - ListItem, - ListItemIcon, - ListItemText, - ListSubheader, } from '@material-ui/core'; -// Icons -import MenuIcon from '@material-ui/icons/Menu'; -import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'; -import DashboardIcon from '@material-ui/icons/Dashboard'; -import PeopleIcon from '@material-ui/icons/People'; -import BarChartIcon from '@material-ui/icons/BarChart'; -import LayersIcon from '@material-ui/icons/Layers'; // Pie Charts import AgentsPieChart from './agents-pie-chart'; import ClustersPieChart from './clusters-pie-chart'; @@ -49,10 +30,7 @@ import { clickedDashboardTabelFunc, } from 'redux/actions'; import SpiffeHelper from '../spiffe-helper'; -import DashboardDetails from './dashboard-details'; - -const drawerWidth = 240; -const drawerHeight = '100%'; +import DashboardDrawer from './dashboard-drawer'; const styles = theme => ({ root: { @@ -60,64 +38,6 @@ const styles = theme => ({ marginLeft: -20, display: 'flex', }, - toolbar: { - paddingRight: 24, // keep right padding when drawer closed - }, - toolbarIcon: { //drawer icon close - display: 'flex', - alignItems: 'center', - justifyContent: 'flex-end', - padding: '0 8px', - ...theme.mixins.toolbar, - }, - appBar: { //appbar - backgroundColor: 'grey', - marginTop: 52, - zIndex: 2, - transition: theme.transitions.create(['width', 'margin'], { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.leavingScreen, - }), - }, - appBarShift: { //appbar on shift/ open - marginLeft: drawerWidth, - width: `calc(100% - ${drawerWidth}px)`, - transition: theme.transitions.create(['width', 'margin'], { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen, - }), - }, - menuButton: { //menu button next to Tornjak Dashboard title on view - marginRight: 35, - }, - menuButtonHidden: { //menu button next to Tornjak Dashboard title on hidden - display: 'none', - }, - title: { - flexGrow: 1, - }, - drawerPaper: { //dashboard side drawer on open - position: 'relative', - whiteSpace: 'nowrap', - zIndex: 1, - width: drawerWidth, - height: drawerHeight, - transition: theme.transitions.create('width', { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen, - }), - }, - drawerPaperClose: { //dashboard side drawer on close - overflowX: 'hidden', - transition: theme.transitions.create('width', { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.leavingScreen, - }), - width: theme.spacing(7), - [theme.breakpoints.up('sm')]: { - width: theme.spacing(9), - }, - }, appBarSpacer: theme.mixins.toolbar, content: { flexGrow: 1, @@ -145,11 +65,7 @@ class TornjakDashboard extends React.Component { super(props); const { classes } = this.props; this.state = { - open: true, - clickedDashboardList: "" }; - this.handleDrawerOpen = () => this.setState({ open: true }) - this.handleDrawerClose = () => this.setState({ open: false }) this.fixedHeightPaper = clsx(classes.paper, classes.fixedHeight) this.TornjakApi = new TornjakApi(); this.SpiffeHelper = new SpiffeHelper(); @@ -207,75 +123,7 @@ class TornjakDashboard extends React.Component { const { classes } = this.props; return (
- - - - - - - - Tornjak Dashboard - - - - -
- - - -
- - -
- { this.props.clickedDashboardTabelFunc("dashboard"); }}> - - - - - - Details - { this.props.clickedDashboardTabelFunc("clusters"); }}> - - - - - - { this.props.clickedDashboardTabelFunc("agents"); }}> - - - - - - { this.props.clickedDashboardTabelFunc("entries"); }}> - - - - - -
-
- -
+
{(this.props.globalClickedDashboardTable === "" || this.props.globalClickedDashboardTable === "dashboard") && @@ -350,7 +198,6 @@ class TornjakDashboard extends React.Component { } -
) diff --git a/tornjak-frontend/src/components/navbar.js b/tornjak-frontend/src/components/navbar.js index d8b40633..1bac31a3 100644 --- a/tornjak-frontend/src/components/navbar.js +++ b/tornjak-frontend/src/components/navbar.js @@ -1,10 +1,14 @@ import React, { Component } from 'react'; +import { connect } from 'react-redux'; import IsManager from './is_manager'; import 'carbon-components/css/carbon-components.min.css'; import './style.css'; import tornjak_logo from "res/tornjak_logo.png"; +import { + clickedDashboardTabelFunc, +} from 'redux/actions'; -export default class NavigationBar extends Component { +class NavigationBar extends Component { constructor(props) { super(props); this.state = {}; @@ -45,7 +49,11 @@ export default class NavigationBar extends Component { Tornjak ServerInfo {IsManager && managerNavs} @@ -60,3 +68,11 @@ export default class NavigationBar extends Component { ); } } + +const mapStateToProps = (state) => ({ +}) + +export default connect( + mapStateToProps, + { clickedDashboardTabelFunc } +)(NavigationBar) \ No newline at end of file From 2f88f32008eca816b71a0f72c14b96c7c4be93d4 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Thu, 5 Aug 2021 17:47:13 -0400 Subject: [PATCH 06/18] adding window.location instead of location --- .../components/dashboard/dashboard-drawer.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tornjak-frontend/src/components/dashboard/dashboard-drawer.js b/tornjak-frontend/src/components/dashboard/dashboard-drawer.js index b1d017af..2ade98ba 100644 --- a/tornjak-frontend/src/components/dashboard/dashboard-drawer.js +++ b/tornjak-frontend/src/components/dashboard/dashboard-drawer.js @@ -168,8 +168,8 @@ class DashboardDrawer extends React.Component { onClick={() => { this.props.clickedDashboardTabelFunc("dashboard"); const path = "/tornjak/dashboard"; - if (location.href !== location.origin + path) - location.href = path; + if (window.location.href !== window.location.origin + path) + window.location.href = path; }}> @@ -182,8 +182,8 @@ class DashboardDrawer extends React.Component { onClick={() => { this.props.clickedDashboardTabelFunc("clusters"); const path = "/tornjak/dashboard"; - if (location.href !== location.origin + path) - location.href = path; + if (window.location.href !== window.location.origin + path) + window.location.href = path; }}> @@ -195,8 +195,8 @@ class DashboardDrawer extends React.Component { onClick={() => { this.props.clickedDashboardTabelFunc("agents"); const path = "/tornjak/dashboard"; - if (location.href !== location.origin + path) - location.href = path; + if (window.location.href !== window.location.origin + path) + window.location.href = path; }}> @@ -208,9 +208,8 @@ class DashboardDrawer extends React.Component { onClick={() => { this.props.clickedDashboardTabelFunc("entries"); const path = "/tornjak/dashboard"; - console.log("location.href", location) - if (location.href !== location.origin + path) - location.href = path; + if (window.location.href !== window.location.origin + path) + window.location.href = path; }}> From 2217cf3e701ae4e4aeb7615ebf6fe6ac128a7c52 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Fri, 6 Aug 2021 18:33:34 -0400 Subject: [PATCH 07/18] remove already declared variable --- tornjak-frontend/src/components/dashboard/dashboard-details.js | 2 -- .../src/components/dashboard/table/dashboard-table.js | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tornjak-frontend/src/components/dashboard/dashboard-details.js b/tornjak-frontend/src/components/dashboard/dashboard-details.js index 8c1c0b92..afa8bb33 100644 --- a/tornjak-frontend/src/components/dashboard/dashboard-details.js +++ b/tornjak-frontend/src/components/dashboard/dashboard-details.js @@ -13,8 +13,6 @@ import AgentsTable from './agents-dashboard-table'; import EntriesTable from './entries-dashboard-table'; import DashboardDrawer from './dashboard-drawer'; -const drawerWidth = 240; -const drawerHeight = '100%'; const styles = theme => ({ root: { marginTop: -25, diff --git a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js index fe66949e..3cc10a7a 100644 --- a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js @@ -65,7 +65,7 @@ class TableDashboard extends React.Component { autoHeight={true} checkboxSelection onRowSelected={(selectedRows) => { - var selectedRows = Array.from(selectedRows.api.current.getSelectedRows(), ([name, value]) => ({ name, value })); + selectedRows = Array.from(selectedRows.api.current.getSelectedRows(), ([name, value]) => ({ name, value })); this.setState({ selectedRows: selectedRows }) }} components={{ From 687801f053fcb3748d7096dd712412ebc51027f8 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Mon, 9 Aug 2021 10:18:18 -1000 Subject: [PATCH 08/18] when clicking tornjak dashboard button change props to dashboard --- tornjak-frontend/package.json | 2 ++ .../components/dashboard/table/dashboard-table.js | 14 ++++++++------ tornjak-frontend/src/components/navbar.js | 13 +++++++++---- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/tornjak-frontend/package.json b/tornjak-frontend/package.json index 27bb2876..fd902d8b 100644 --- a/tornjak-frontend/package.json +++ b/tornjak-frontend/package.json @@ -9,6 +9,7 @@ "@material-ui/core": "^4.12.3", "@material-ui/data-grid": "^4.0.0-alpha.33", "@material-ui/icons": "^4.11.2", + "@material-ui/lab": "^4.0.0-alpha.60", "@material-ui/styles": "^4.11.4", "axios": "^0.21.1", "bootstrap": "^4.5.3", @@ -19,6 +20,7 @@ "dotenv": "^8.2.0", "node-sass": "^6.0.1", "react": "^16.6.3", + "react-alert": "^7.0.3", "react-dom": "^16.6.3", "react-redux": "^7.2.2", "react-router-dom": "^5.2.0", diff --git a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js index 3cc10a7a..e6274e9b 100644 --- a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js @@ -25,7 +25,6 @@ class TableDashboard extends React.Component { const { title } = this.props; if (this.state.selectedRows.length !== 0) { var detailsLink = "/tornjak/dashboard/details/" + title.toLowerCase() + "/" + this.state.selectedRows[0].name; - console.log(detailsLink) } return detailsLink; } @@ -49,10 +48,14 @@ class TableDashboard extends React.Component { size="small" variant="outlined" onClick={() => { - this.props.clickedDashboardTabelFunc(title.toLowerCase() + "details") - this.props.selectedDashboardTableData(this.state.selectedRows) - this.detailsLink(); - + if (this.state.selectedRows.length === 0) { + window.alert("Please Select a Row to See Details."); + } else { + this.props.clickedDashboardTabelFunc(title.toLowerCase() + "details") + this.props.selectedDashboardTableData(this.state.selectedRows) + this.detailsLink(); + + } }} > Selected Details @@ -63,7 +66,6 @@ class TableDashboard extends React.Component { columns={columns} pageSize={numRows} autoHeight={true} - checkboxSelection onRowSelected={(selectedRows) => { selectedRows = Array.from(selectedRows.api.current.getSelectedRows(), ([name, value]) => ({ name, value })); this.setState({ selectedRows: selectedRows }) diff --git a/tornjak-frontend/src/components/navbar.js b/tornjak-frontend/src/components/navbar.js index 1bac31a3..7d6fd9ed 100644 --- a/tornjak-frontend/src/components/navbar.js +++ b/tornjak-frontend/src/components/navbar.js @@ -49,11 +49,15 @@ class NavigationBar extends Component { Tornjak ServerInfo
- Tornjak Dashboard + onClick={() => { + if (this.props.globalClickedDashboardTable !== "dashboard") { + this.props.clickedDashboardTabelFunc("dashboard") + } + }} + >Tornjak Dashboard
{IsManager && managerNavs} @@ -70,6 +74,7 @@ class NavigationBar extends Component { } const mapStateToProps = (state) => ({ + globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable, }) export default connect( From ae155d5075122c2d5b819491ecca6bc63d60b0b5 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Wed, 11 Aug 2021 08:48:07 -1000 Subject: [PATCH 09/18] initial nits from review --- tornjak-frontend/src/App.js | 4 +-- .../dashboard/agents-dashboard-table.js | 3 +- .../components/dashboard/dashboard-drawer.js | 28 ++++++++----------- .../dashboard/table/dashboard-table.js | 14 +++------- .../src/components/tornjak-helper.js | 13 +++++++++ 5 files changed, 33 insertions(+), 29 deletions(-) create mode 100644 tornjak-frontend/src/components/tornjak-helper.js diff --git a/tornjak-frontend/src/App.js b/tornjak-frontend/src/App.js index adf82754..8690f99b 100644 --- a/tornjak-frontend/src/App.js +++ b/tornjak-frontend/src/App.js @@ -16,7 +16,7 @@ import { Provider } from 'react-redux'; //enables all components to have access import store from 'redux/store'; import IsManager from './components/is_manager'; import './App.css'; -import dashboardDetails from 'components/dashboard/dashboard-details'; +import DashboardDetails from 'components/dashboard/dashboard-details'; function App() { return ( @@ -39,7 +39,7 @@ function App() { - +


diff --git a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js index 6856e4c5..a37231f7 100644 --- a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js @@ -90,7 +90,8 @@ class AgentDashboardTable extends React.Component { } selectedData() { - var data = this.agentList(), filteredData = [], selectedDataKey = [], selectedData = this.props.selectedData, clickedDashboardTable = this.props.globalClickedDashboardTable; + var data = this.agentList() , selectedData = this.props.selectedData, clickedDashboardTable = this.props.globalClickedDashboardTable; + var filteredData = [], selectedDataKey = []; if (selectedData === undefined) return data; if (clickedDashboardTable === "clustersdetails") { diff --git a/tornjak-frontend/src/components/dashboard/dashboard-drawer.js b/tornjak-frontend/src/components/dashboard/dashboard-drawer.js index 2ade98ba..f8986842 100644 --- a/tornjak-frontend/src/components/dashboard/dashboard-drawer.js +++ b/tornjak-frontend/src/components/dashboard/dashboard-drawer.js @@ -125,6 +125,14 @@ class DashboardDrawer extends React.Component { this.handleDrawerOpen = () => this.setState({ open: true }) this.handleDrawerClose = () => this.setState({ open: false }) this.fixedHeightPaper = clsx(classes.paper, classes.fixedHeight) + this.assignDashboardPath = this.assignDashboardPath.bind(this); + } + + assignDashboardPath(entity) { + this.props.clickedDashboardTabelFunc(entity); + const path = "/tornjak/dashboard"; + if (window.location.href !== window.location.origin + path) + window.location.href = path; } render() { @@ -166,10 +174,7 @@ class DashboardDrawer extends React.Component { { - this.props.clickedDashboardTabelFunc("dashboard"); - const path = "/tornjak/dashboard"; - if (window.location.href !== window.location.origin + path) - window.location.href = path; + this.assignDashboardPath("dashboard"); }}> @@ -180,10 +185,7 @@ class DashboardDrawer extends React.Component { { - this.props.clickedDashboardTabelFunc("clusters"); - const path = "/tornjak/dashboard"; - if (window.location.href !== window.location.origin + path) - window.location.href = path; + this.assignDashboardPath("clusters"); }}> @@ -193,10 +195,7 @@ class DashboardDrawer extends React.Component { { - this.props.clickedDashboardTabelFunc("agents"); - const path = "/tornjak/dashboard"; - if (window.location.href !== window.location.origin + path) - window.location.href = path; + this.assignDashboardPath("agents"); }}> @@ -206,10 +205,7 @@ class DashboardDrawer extends React.Component { { - this.props.clickedDashboardTabelFunc("entries"); - const path = "/tornjak/dashboard"; - if (window.location.href !== window.location.origin + path) - window.location.href = path; + this.assignDashboardPath("entries"); }}> diff --git a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js index e6274e9b..fbeb5c67 100644 --- a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js @@ -10,6 +10,7 @@ import { selectedDashboardTableData } from 'redux/actions'; import DashboardDetails from '../dashboard-details'; +import TornjakHelper from 'components/tornjak-helper'; class TableDashboard extends React.Component { constructor(props) { @@ -18,16 +19,9 @@ class TableDashboard extends React.Component { selectedRows: [], detailsLink: "" }; - this.detailsLink = this.detailsLink.bind(this); + this.TornjakHelper = new TornjakHelper(); } - detailsLink() { - const { title } = this.props; - if (this.state.selectedRows.length !== 0) { - var detailsLink = "/tornjak/dashboard/details/" + title.toLowerCase() + "/" + this.state.selectedRows[0].name; - } - return detailsLink; - } render() { const { numRows, data, columns, title } = this.props; return ( @@ -42,7 +36,7 @@ class TableDashboard extends React.Component { } }} diff --git a/tornjak-frontend/src/components/tornjak-helper.js b/tornjak-frontend/src/components/tornjak-helper.js new file mode 100644 index 00000000..8129ddeb --- /dev/null +++ b/tornjak-frontend/src/components/tornjak-helper.js @@ -0,0 +1,13 @@ +import { Component } from 'react'; + +class TornjakHelper extends Component { + detailsLink(selectedRows, title, ) { + const dashboardDetailsLink = "/tornjak/dashboard/details/"; + if (selectedRows.length !== 0) { + var detailsLink = dashboardDetailsLink + title.toLowerCase() + "/" + selectedRows[0].name; + } + return detailsLink; + } + +} + export default TornjakHelper; \ No newline at end of file From 337f76b40ab24afa654213daff505e88278b7192 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Wed, 11 Aug 2021 11:08:39 -1000 Subject: [PATCH 10/18] additional nits dashboard details css --- .../components/dashboard/dashboard-details.js | 73 ++++++++++++------- tornjak-frontend/src/components/style.css | 20 ----- 2 files changed, 45 insertions(+), 48 deletions(-) diff --git a/tornjak-frontend/src/components/dashboard/dashboard-details.js b/tornjak-frontend/src/components/dashboard/dashboard-details.js index afa8bb33..b3b236c7 100644 --- a/tornjak-frontend/src/components/dashboard/dashboard-details.js +++ b/tornjak-frontend/src/components/dashboard/dashboard-details.js @@ -35,6 +35,23 @@ const styles = theme => ({ flexDirection: 'column', marginBottom: 20 }, + detailsTitle: { + fontSize: 20, + color: 'rgb(89, 103, 185)' + }, + metadataTag: { + fontWeight: 'bold', + fontSize: 17, + marginTop: 10, + }, + + dashboardDetalsLine: { + marginLeft: 0, + width: 1200, + }, + metadataDetails: { + fontSize: 17, + } }); class DashboardDetails extends React.Component { @@ -53,16 +70,16 @@ class DashboardDetails extends React.Component { {(this.props.globalSelectedDashboardData.length !== 0) &&
{(this.props.globalClickedDashboardTable === "clustersdetails") && -
+
-

Cluster Name : {this.props.globalSelectedDashboardData[0].value.name}

-

Metadata

-
-

Created : {this.props.globalSelectedDashboardData[0].value.created}

-

Number of Nodes : {this.props.globalSelectedDashboardData[0].value.numNodes}

-

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

+

Cluster Name : {this.props.globalSelectedDashboardData[0].value.name}

+

Metadata

+
+

Created : {this.props.globalSelectedDashboardData[0].value.created}

+

Number of Nodes : {this.props.globalSelectedDashboardData[0].value.numNodes}

+

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

@@ -86,20 +103,20 @@ class DashboardDetails extends React.Component { -
+
// End clustersdetails } {(this.props.globalClickedDashboardTable === "agentsdetails") && -
+
-

Agent Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

-

Metadata

-
-

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

-

Status : {this.props.globalSelectedDashboardData[0].value.status}

-

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

-

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

+

Agent Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

+

Metadata

+
+

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

+

Status : {this.props.globalSelectedDashboardData[0].value.status}

+

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

+

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

@@ -123,22 +140,22 @@ class DashboardDetails extends React.Component { -
+
// End agentsdetails } {(this.props.globalClickedDashboardTable === "entriesdetails") && -
+
-

Entry ID : {this.props.globalSelectedDashboardData[0].value.id}

-

Metadata

-
-

Entry Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

-

Parent ID : {this.props.globalSelectedDashboardData[0].value.parentId}

-

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

-

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

-

Is Admin : {this.props.globalSelectedDashboardData[0].value.adminFlag.toString().toUpperCase()}

-

Entry Expire Time: {this.props.globalSelectedDashboardData[0].value.entryExpireTime}

+

Entry ID : {this.props.globalSelectedDashboardData[0].value.id}

+

Metadata

+
+

Entry Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

+

Parent ID : {this.props.globalSelectedDashboardData[0].value.parentId}

+

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

+

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

+

Is Admin : {this.props.globalSelectedDashboardData[0].value.adminFlag.toString().toUpperCase()}

+

Entry Expire Time: {this.props.globalSelectedDashboardData[0].value.entryExpireTime}

@@ -162,7 +179,7 @@ class DashboardDetails extends React.Component { -
+
// End entriesdetails }
} diff --git a/tornjak-frontend/src/components/style.css b/tornjak-frontend/src/components/style.css index 74637fa5..306accd0 100644 --- a/tornjak-frontend/src/components/style.css +++ b/tornjak-frontend/src/components/style.css @@ -161,24 +161,4 @@ .no-data { margin-top: 120px; margin-left: 200px; - } - - .details-title { - font-size:x-large; - color: rgb(89, 103, 185) - } - - .metadata-tag { - font-weight: bold; - font-size:large; - margin-top: 10px; - } - - .dashboard-detals-line { - margin-left: 0; - width: 1200px; - } - - .metadata-details { - font-size:large; } \ No newline at end of file From f2a029fee5dceae2768817314cfde04d7dde2fc8 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Thu, 12 Aug 2021 04:42:33 -1000 Subject: [PATCH 11/18] passing selected data as props - not working --- .../components/dashboard/dashboard-details.js | 49 ++++++++++--------- .../dashboard/table/dashboard-table.js | 3 +- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/tornjak-frontend/src/components/dashboard/dashboard-details.js b/tornjak-frontend/src/components/dashboard/dashboard-details.js index b3b236c7..37080020 100644 --- a/tornjak-frontend/src/components/dashboard/dashboard-details.js +++ b/tornjak-frontend/src/components/dashboard/dashboard-details.js @@ -61,25 +61,26 @@ class DashboardDetails extends React.Component { }; } render() { - const { classes } = this.props; + const { classes, selectedData } = this.props; + console.log("selectedData", selectedData) return (
- {(this.props.globalSelectedDashboardData.length !== 0) && + {(selectedData.length !== 0) &&
{(this.props.globalClickedDashboardTable === "clustersdetails") &&
-

Cluster Name : {this.props.globalSelectedDashboardData[0].value.name}

+

Cluster Name : {selectedData[0].value.name}

Metadata


-

Created : {this.props.globalSelectedDashboardData[0].value.created}

-

Number of Nodes : {this.props.globalSelectedDashboardData[0].value.numNodes}

-

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

+

Created : {selectedData[0].value.created}

+

Number of Nodes : {selectedData[0].value.numNodes}

+

Number of Entries: {selectedData[0].value.numEntries}

@@ -89,7 +90,7 @@ class DashboardDetails extends React.Component { + selectedData={selectedData} /> @@ -99,7 +100,7 @@ class DashboardDetails extends React.Component { + selectedData={selectedData} /> @@ -110,13 +111,13 @@ class DashboardDetails extends React.Component { -

Agent Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

+

Agent Name : {selectedData[0].value.spiffeid}

Metadata


-

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

-

Status : {this.props.globalSelectedDashboardData[0].value.status}

-

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

-

Number of Entries: {this.props.globalSelectedDashboardData[0].value.numEntries}

+

Belongs to Cluster : {selectedData[0].value.clusterName}

+

Status : {selectedData[0].value.status}

+

Platform Type : {selectedData[0].value.platformType}

+

Number of Entries: {selectedData[0].value.numEntries}

@@ -126,7 +127,7 @@ class DashboardDetails extends React.Component { + selectedData={selectedData} /> @@ -136,7 +137,7 @@ class DashboardDetails extends React.Component { + selectedData={selectedData} /> @@ -147,15 +148,15 @@ class DashboardDetails extends React.Component { -

Entry ID : {this.props.globalSelectedDashboardData[0].value.id}

+

Entry ID : {selectedData[0].value.id}

Metadata


-

Entry Name : {this.props.globalSelectedDashboardData[0].value.spiffeid}

-

Parent ID : {this.props.globalSelectedDashboardData[0].value.parentId}

-

Belongs to Cluster : {this.props.globalSelectedDashboardData[0].value.clusterName}

-

Platform Type : {this.props.globalSelectedDashboardData[0].value.platformType}

-

Is Admin : {this.props.globalSelectedDashboardData[0].value.adminFlag.toString().toUpperCase()}

-

Entry Expire Time: {this.props.globalSelectedDashboardData[0].value.entryExpireTime}

+

Entry Name : {selectedData[0].value.spiffeid}

+

Parent ID : {selectedData[0].value.parentId}

+

Belongs to Cluster : {selectedData[0].value.clusterName}

+

Platform Type : {selectedData[0].value.platformType}

+

Is Admin : {selectedData[0].value.adminFlag.toString().toUpperCase()}

+

Entry Expire Time: {selectedData[0].value.entryExpireTime}

@@ -165,7 +166,7 @@ class DashboardDetails extends React.Component { + selectedData={selectedData} /> @@ -175,7 +176,7 @@ class DashboardDetails extends React.Component { + selectedData={selectedData} /> diff --git a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js index fbeb5c67..62e8403b 100644 --- a/tornjak-frontend/src/components/dashboard/table/dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/table/dashboard-table.js @@ -48,7 +48,8 @@ class TableDashboard extends React.Component { this.props.clickedDashboardTabelFunc(title.toLowerCase() + "details") this.props.selectedDashboardTableData(this.state.selectedRows) this.TornjakHelper.detailsLink(this.state.selectedRows, title); - + } }} > From 62fbb488cb0df4181f330fff80d3f66ce0717783 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Thu, 12 Aug 2021 18:05:46 -1000 Subject: [PATCH 12/18] refactor details page to use props for selcted data instead of redux --- tornjak-frontend/src/App.js | 91 ++++--- .../dashboard/agents-dashboard-table.js | 90 ++----- .../dashboard/clusters-dashboard-table.js | 55 +---- .../components/dashboard/dashboard-details.js | 34 ++- .../dashboard/entries-dashboard-table.js | 56 +---- .../dashboard/table/dashboard-table.js | 13 +- .../components/dashboard/tornjak-dashboard.js | 1 - .../src/components/spiffe-helper.js | 227 ++++++++++++++---- .../src/components/tornjak-helper.js | 48 +++- tornjak-frontend/src/index.js | 6 +- tornjak-frontend/src/redux/actions/index.js | 12 - tornjak-frontend/src/redux/actions/types.js | 1 - .../src/redux/reducers/tornjakReducer.js | 7 - 13 files changed, 342 insertions(+), 299 deletions(-) diff --git a/tornjak-frontend/src/App.js b/tornjak-frontend/src/App.js index 8690f99b..259b10e8 100644 --- a/tornjak-frontend/src/App.js +++ b/tornjak-frontend/src/App.js @@ -1,5 +1,6 @@ import React from 'react'; import "bootstrap/dist/css/bootstrap.min.css"; +import { connect } from 'react-redux'; import { BrowserRouter as Router, Route } from "react-router-dom"; import NavigationBar from "./components/navbar"; import SelectServer from "./components/select-server"; @@ -17,39 +18,65 @@ import store from 'redux/store'; import IsManager from './components/is_manager'; import './App.css'; import DashboardDetails from 'components/dashboard/dashboard-details'; +import TornjakHelper from 'components/tornjak-helper'; -function App() { - return ( - - -
-
- +class App extends React.Component { + constructor(props) { + super(props); + this.TornjakHelper = new TornjakHelper(); + this.state = { + entity: "", + id: "" + }; + } + render() { + return ( + + +
+
+ +
+
+ +
+ {IsManager &&
} + + + + + + + + + + ( + + )} + /> + +


+ + + +
-
- -
- {IsManager &&
} - - - - - - - - - - - -


- - - -
-
- - - ); + + + ); + } } -export default App; +const mapStateToProps = (state) => ({ + globalClustersList: state.clusters.globalClustersList, + globalAgentsList: state.agents.globalAgentsList, + globalEntriesList: state.entries.globalEntriesList, + globalAgentsWorkLoadAttestorInfo: state.agents.globalAgentsWorkLoadAttestorInfo, +}) + +export default connect( + mapStateToProps, + {} +)(App) diff --git a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js index a37231f7..3f468cff 100644 --- a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js @@ -27,56 +27,6 @@ class AgentDashboardTable extends React.Component { this.SpiffeHelper = new SpiffeHelper() } - numberEntries(spiffeid, agentEntriesDict) { - var validIds = new Set([spiffeid]); - - // Also check for parent IDs associated with the agent - let agentEntries = agentEntriesDict[spiffeid]; - if (agentEntries !== undefined) { - for (let j = 0; j < agentEntries.length; j++) { - validIds.add(this.SpiffeHelper.getEntrySpiffeid(agentEntries[j])); - } - } - - if (typeof this.props.globalEntries.globalEntriesList !== 'undefined') { - var entriesList = this.props.globalEntries.globalEntriesList.filter(entry => { - return (typeof entry !== 'undefined') && validIds.has(this.SpiffeHelper.getEntryParentid(entry)); - }); - - if (typeof entriesList === 'undefined') { - return 0 - } else { - return entriesList.length - } - } else { - return 0 - } - } - - getChildEntries(agent, agentEntriesDict) { - var thisSpiffeid = this.SpiffeHelper.getAgentSpiffeid(agent); - // get status - var status = this.SpiffeHelper.getAgentStatusString(agent); - // get tornjak metadata - var metadata_entry = this.SpiffeHelper.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, agentEntriesDict), - status: status, - platformType: plugin, - clusterName: cluster, - } - } - agentList() { if ((typeof this.props.globalEntries.globalEntriesList === 'undefined') || (typeof this.props.globalAgents.globalAgentsList === 'undefined')) { @@ -85,44 +35,40 @@ class AgentDashboardTable extends React.Component { let agentEntriesDict = this.SpiffeHelper.getAgentsEntries(this.props.globalAgents.globalAgentsList, this.props.globalEntries.globalEntriesList) return this.props.globalAgents.globalAgentsList.map(currentAgent => { - return this.getChildEntries(currentAgent, agentEntriesDict); + return this.SpiffeHelper.getChildEntries(currentAgent, agentEntriesDict, this.props.globalEntries.globalEntriesList, this.props.globalAgents.globalAgentsWorkLoadAttestorInfo) }) } selectedData() { - var data = this.agentList() , selectedData = this.props.selectedData, clickedDashboardTable = this.props.globalClickedDashboardTable; + var data = this.agentList(), selectedData = this.props.selectedData, clickedDashboardTable = this.props.globalClickedDashboardTable; var filteredData = [], selectedDataKey = []; - if (selectedData === undefined) - return data; - if (clickedDashboardTable === "clustersdetails") { - for (let i = 0; i < selectedData.length; i++) { - selectedDataKey[i] = selectedData[i].name; - } - for (let i = 0; i < data.length; i++) { - for (let j = 0; j < selectedDataKey.length; j++) { - if (data[i].clusterName === selectedDataKey[j]) { + if (selectedData !== undefined) { + if (clickedDashboardTable === "clustersdetails") { + selectedDataKey = selectedData.name; + for (let i = 0; i < data.length; i++) { + if (data[i].clusterName === selectedDataKey) { filteredData.push(data[i]); } } - } - } else if (clickedDashboardTable === "entriesdetails") { - for (let i = 0; i < selectedData.length; i++) { - selectedDataKey[i] = selectedData[i].value.parentId; - } - for (let i = 0; i < data.length; i++) { - for (let j = 0; j < selectedDataKey.length; j++) { - if (data[i].id === selectedDataKey[j]) { + } else if (clickedDashboardTable === "entriesdetails") { + selectedDataKey = selectedData.parentId; + for (let i = 0; i < data.length; i++) { + if (data[i].id === selectedDataKey) { filteredData.push(data[i]); } } } + return filteredData; } - return filteredData; } render() { - const { numRows } = this.props; - var data = this.selectedData(); + const { numRows, selectedData } = this.props; + if (selectedData === undefined) { + var data = this.agentList(); + } else { + var data = this.selectedData(); + } return (
{ - return spiffeid === (this.SpiffeHelper.getEntryParentid(entry)) - }) - return entriesList.length - } else { - return 0 - } - } - - numberClusterEntries(entry) { - var entriesPerAgent = entry.agentsList.map(currentAgent => { - return this.numberAgentEntries(currentAgent); - }) - var sum = entriesPerAgent.reduce((acc, curVal) => { - return acc + curVal; - }, 0) - return sum - } - - cluster(entry) { - return { - id: entry.name, - name: entry.name, - created: entry.creationTime, - numNodes: entry.agentsList.length, - numEntries: this.numberClusterEntries(entry), - } - } - clusterList() { if (typeof this.props.globalClustersList !== 'undefined') { - return this.props.globalClustersList.map(a => this.cluster(a)) + return this.props.globalClustersList.map(a => this.SpiffeHelper.cluster(a, this.props.globalEntries.globalEntriesList)) } else { return [] } @@ -64,24 +33,24 @@ class ClusterDashboardTable extends React.Component { selectedData() { var data = this.clusterList(), filteredData = [], selectedDataKey = [], selectedData = this.props.selectedData; - if (selectedData === undefined) - return data; - for (let i = 0; i < selectedData.length; i++) { - selectedDataKey[i] = selectedData[i].value.clusterName; - } - for (let i = 0; i < data.length; i++) { - for (let j = 0; j < selectedDataKey.length; j++) { - if ((data[i].clusterName === selectedDataKey[j]) || (data[i].name === selectedDataKey[j])) { + if (selectedData !== undefined) { + selectedDataKey = selectedData.clusterName; + for (let i = 0; i < data.length; i++) { + if ((data[i].clusterName === selectedDataKey) || (data[i].name === selectedDataKey)) { filteredData.push(data[i]); } } + return filteredData; } - return filteredData; } render() { - const { numRows } = this.props; - var data = this.selectedData(); + const { numRows, selectedData } = this.props; + if (selectedData === undefined) { + var data = this.clusterList(); + } else { + var data = this.selectedData(); + } return (
@@ -75,12 +74,12 @@ class DashboardDetails extends React.Component { -

Cluster Name : {selectedData[0].value.name}

+

Cluster Name : {selectedData.name}

Metadata


-

Created : {selectedData[0].value.created}

-

Number of Nodes : {selectedData[0].value.numNodes}

-

Number of Entries: {selectedData[0].value.numEntries}

+

Created : {selectedData.created}

+

Number of Nodes : {selectedData.numNodes}

+

Number of Entries: {selectedData.numEntries}

@@ -111,13 +110,13 @@ class DashboardDetails extends React.Component { -

Agent Name : {selectedData[0].value.spiffeid}

+

Agent Name : {selectedData.spiffeid}

Metadata


-

Belongs to Cluster : {selectedData[0].value.clusterName}

-

Status : {selectedData[0].value.status}

-

Platform Type : {selectedData[0].value.platformType}

-

Number of Entries: {selectedData[0].value.numEntries}

+

Belongs to Cluster : {selectedData.clusterName}

+

Status : {selectedData.status}

+

Platform Type : {selectedData.platformType}

+

Number of Entries: {selectedData.numEntries}

@@ -148,15 +147,15 @@ class DashboardDetails extends React.Component { -

Entry ID : {selectedData[0].value.id}

+

Entry ID : {selectedData.id}

Metadata


-

Entry Name : {selectedData[0].value.spiffeid}

-

Parent ID : {selectedData[0].value.parentId}

-

Belongs to Cluster : {selectedData[0].value.clusterName}

-

Platform Type : {selectedData[0].value.platformType}

-

Is Admin : {selectedData[0].value.adminFlag.toString().toUpperCase()}

-

Entry Expire Time: {selectedData[0].value.entryExpireTime}

+

Entry Name : {selectedData.spiffeid}

+

Parent ID : {selectedData.parentId}

+

Belongs to Cluster : {selectedData.clusterName}

+

Platform Type : {selectedData.platformType}

+

Is Admin : {selectedData.adminFlag.toString().toUpperCase()}

+

Entry Expire Time: {selectedData.entryExpireTime}

@@ -193,7 +192,6 @@ class DashboardDetails extends React.Component { const mapStateToProps = (state) => ({ globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable, - globalSelectedDashboardData: state.tornjak.globalSelectedDashboardData }) export default withStyles(styles)( diff --git a/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js b/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js index 1ea8db25..b9296555 100644 --- a/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js @@ -27,41 +27,10 @@ class EntriesDashBoardTable extends React.Component { this.SpiffeHelper = new SpiffeHelper(); } - workloadEntry(entry) { - var thisSpiffeId = this.SpiffeHelper.getEntrySpiffeid(entry) - var thisParentId = this.SpiffeHelper.getEntryParentid(entry) - // get tornjak metadata - var metadata_entry = this.SpiffeHelper.getAgentMetadata(thisParentId, this.props.globalAgents.globalAgentsWorkLoadAttestorInfo); - var plugin = "None" - var cluster = "None" - if (metadata_entry["plugin"].length !== 0) { - plugin = metadata_entry["plugin"] - } - if (metadata_entry["cluster"].length !== 0) { - cluster = metadata_entry["cluster"] - } - // get spire data - var admin = this.SpiffeHelper.getEntryAdminFlag(entry) - var expTime = "No Expiry Time" - if (typeof entry.expires_at !== 'undefined') { - var d = new Date(this.SpiffeHelper.getEntryExpiryMillisecondsFromEpoch(entry)) - expTime = d.toLocaleDateString("en-US", { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: false }) - } - return { - id: entry.id, - spiffeid: thisSpiffeId, - parentId: thisParentId, - adminFlag: admin, - entryExpireTime: expTime, - platformType: plugin, - clusterName: cluster, - } - } - entryList() { if (typeof this.props.globalEntriesList !== 'undefined' && typeof this.props.globalEntriesList.globalEntriesList !== 'undefined') { return this.props.globalEntriesList.globalEntriesList.map(currentEntry => { - return this.workloadEntry(currentEntry); + return this.SpiffeHelper.workloadEntry(currentEntry, this.props.globalAgents.globalAgentsWorkLoadAttestorInfo); }) } else { return [] @@ -69,25 +38,24 @@ class EntriesDashBoardTable extends React.Component { } selectedData() { - var data = this.entryList(), filteredData = [], selectedDataKey = [], selectedData = this.props.selectedData; - if (selectedData === undefined) - return data; - for (let i = 0; i < selectedData.length; i++) { - selectedDataKey[i] = selectedData[i].name; - } - for (let i = 0; i < data.length; i++) { - for (let j = 0; j < selectedDataKey.length; j++) { - if ((data[i].clusterName === selectedDataKey[j]) || (data[i].parentId === selectedDataKey[j])) { + var data = this.entryList(), filteredData = [], selectedData = this.props.selectedData; + if (selectedData !== undefined) { + for (let i = 0; i < data.length; i++) { + if ((data[i].clusterName === selectedData.name) || (data[i].parentId === selectedData.spiffeid)) { filteredData.push(data[i]); } } + return filteredData; } - return filteredData; } render() { - const { numRows } = this.props; - var data = this.selectedData(); + const { numRows, selectedData } = this.props; + if (selectedData === undefined) { + var data = this.entryList(); + } else { + var data = this.selectedData(); + } return (
} }} > @@ -62,8 +55,7 @@ class TableDashboard extends React.Component { pageSize={numRows} autoHeight={true} onRowSelected={(selectedRows) => { - selectedRows = Array.from(selectedRows.api.current.getSelectedRows(), ([name, value]) => ({ name, value })); - this.setState({ selectedRows: selectedRows }) + this.setState({ selectedRows: selectedRows.data }) }} components={{ Toolbar: GridToolbar, @@ -77,10 +69,9 @@ class TableDashboard extends React.Component { const mapStateToProps = state => ({ globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable, - globalSelectedDashboardData: state.tornjak.globalSelectedDashboardData }) export default connect( mapStateToProps, - { clickedDashboardTabelFunc, selectedDashboardTableData } + { clickedDashboardTabelFunc } )(TableDashboard); diff --git a/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js b/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js index 43f0ab00..1414ee15 100644 --- a/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js +++ b/tornjak-frontend/src/components/dashboard/tornjak-dashboard.js @@ -212,7 +212,6 @@ const mapStateToProps = (state) => ({ globalAgents: state.agents, globalEntries: state.entries.globalEntriesList, globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable, - globalSelectedDashboardData: state.tornjak.globalSelectedDashboardData }) export default withStyles(styles)(connect( diff --git a/tornjak-frontend/src/components/spiffe-helper.js b/tornjak-frontend/src/components/spiffe-helper.js index 48b1c2b3..31ed2587 100644 --- a/tornjak-frontend/src/components/spiffe-helper.js +++ b/tornjak-frontend/src/components/spiffe-helper.js @@ -21,8 +21,8 @@ class SpiffeHelper extends Component { getEntryAdminFlag(entry) { return typeof entry !== 'undefined' && - typeof entry.admin !== 'undefined' && - entry.admin; + typeof entry.admin !== 'undefined' && + entry.admin; } // check if format strictly adhered to @@ -30,7 +30,7 @@ class SpiffeHelper extends Component { if (typeof trust_domain === 'undefined' || typeof path === 'undefined') { return false } else if (trust_domain.length === 0 || path.length === 0) { - return false + return false } else if (trust_domain.charAt(0) === '/') { return false } else if (trust_domain.slice(-1) === "/" && path.charAt(0) !== "/") { @@ -83,20 +83,20 @@ class SpiffeHelper extends Component { return metadata[0] } } - return {"plugin":"", "cluster":""} + return { "plugin": "", "cluster": "" } } // getAgentEntries provides an agent and a list of entries and returns // the list of entries which are associated with this agent - getAgentEntries (agent, entries) { - let nodeEntries = entries.filter(e => e.parent_id.path === "/spire/server") - let agentSelectors = new Set(agent.selectors.map(formatSelectors)) - let isAssocWithAgent = e => { - let entrySelectors = new Set(e.selectors.map(formatSelectors)) - return isSuperset(agentSelectors, entrySelectors) - } + getAgentEntries(agent, entries) { + let nodeEntries = entries.filter(e => e.parent_id.path === "/spire/server") + let agentSelectors = new Set(agent.selectors.map(formatSelectors)) + let isAssocWithAgent = e => { + let entrySelectors = new Set(e.selectors.map(formatSelectors)) + return isSuperset(agentSelectors, entrySelectors) + } - return nodeEntries.filter(isAssocWithAgent) + return nodeEntries.filter(isAssocWithAgent) } // getAgentEntries provides list of agents and a list of entries @@ -114,64 +114,189 @@ class SpiffeHelper extends Component { // since the association with entries and agent selectors are likely to be // n:1, this would reduce the total cost. This may be useful when // performance is impacted. - getAgentsEntries (agents, entries) { - let nodeEntries = entries.filter(e => e.parent_id.path === "/spire/server"); - var lambdas = []; - var agentEntriesDict = {}; - - for (let i=0; i < agents.length; i++) { - let agent = agents[i]; - let agentId = this.getAgentSpiffeid(agent); - agentEntriesDict[agentId] = []; - - let agentSelectors = new Set(agent.selectors.map(formatSelectors)); - let isAssocWithAgent = e => { - let entrySelectors = new Set(e.selectors.map(formatSelectors)) - if (isSuperset(agentSelectors, entrySelectors)) { - agentEntriesDict[agentId].push(e); - } - }; - lambdas.push(isAssocWithAgent); - } + getAgentsEntries(agents, entries) { + let nodeEntries = entries.filter(e => e.parent_id.path === "/spire/server"); + var lambdas = []; + var agentEntriesDict = {}; + + for (let i = 0; i < agents.length; i++) { + let agent = agents[i]; + let agentId = this.getAgentSpiffeid(agent); + agentEntriesDict[agentId] = []; - for (let i=0; i < nodeEntries.length; i++) { - for (let j=0; j < lambdas.length; j++) { - lambdas[j](nodeEntries[i]) - } + let agentSelectors = new Set(agent.selectors.map(formatSelectors)); + let isAssocWithAgent = e => { + let entrySelectors = new Set(e.selectors.map(formatSelectors)) + if (isSuperset(agentSelectors, entrySelectors)) { + agentEntriesDict[agentId].push(e); + } + }; + lambdas.push(isAssocWithAgent); + } + + for (let i = 0; i < nodeEntries.length; i++) { + for (let j = 0; j < lambdas.length; j++) { + lambdas[j](nodeEntries[i]) } + } - return agentEntriesDict + return agentEntriesDict } // getCanonicalAgentSpiffeid takes in a agent entry, and returns the first // agent ID that is found associated with it. getCanonicalAgentSpiffeid(entry, agents) { - let entrySelectors = new Set(entry.selectors.map(formatSelectors)); - let isAssocWithEntry = a => { - let agentSelectors = new Set(a.selectors.map(formatSelectors)); - return isSuperset(agentSelectors, entrySelectors); + let entrySelectors = new Set(entry.selectors.map(formatSelectors)); + let isAssocWithEntry = a => { + let agentSelectors = new Set(a.selectors.map(formatSelectors)); + return isSuperset(agentSelectors, entrySelectors); + } + + let filteredAgents = agents.filter(isAssocWithEntry); + if (filteredAgents.length > 0) { + return this.getAgentSpiffeid(filteredAgents[0]); + } + return ""; + } + + // numberAgentEntries takes in spiffe id of an agent and entries list + // returns number of entries for an agent + numberAgentEntries(spiffeid, globalEntries) { + if (typeof globalEntries !== 'undefined') { + var entriesList = globalEntries.filter(entry => { + return spiffeid === (this.getEntryParentid(entry)) + }) + return entriesList.length + } else { + return 0 + } + } + + // numberClusterEntries takes in an entry cluster metadata and list of entries + // returns number of entries in a cluster + numberClusterEntries(entry, globalEntries) { + var entriesPerAgent = entry.agentsList.map(currentAgent => { + return this.numberAgentEntries(currentAgent, globalEntries); + }) + var sum = entriesPerAgent.reduce((acc, curVal) => { + return acc + curVal; + }, 0) + return sum + } + + // cluster takes in an entry cluster metadata and list of entries + // returns cluster metadata info for dashboard table + cluster(entry, globalEntries) { + return { + id: entry.name, + name: entry.name, + created: entry.creationTime, + numNodes: entry.agentsList.length, + numEntries: this.numberClusterEntries(entry, globalEntries), + } + } + + // numberEntries takes in spiffe id of an agent, avialble agents' spiffeids and list of entries + // returns cluster metadata info for dashboard table + numberEntries(spiffeid, agentEntriesDict, globalEntries) { + var validIds = new Set([spiffeid]); + + // Also check for parent IDs associated with the agent + let agentEntries = agentEntriesDict[spiffeid]; + if (agentEntries !== undefined) { + for (let j = 0; j < agentEntries.length; j++) { + validIds.add(this.SpiffeHelper.getEntrySpiffeid(agentEntries[j])); } + } + + if (typeof globalEntries !== 'undefined') { + var entriesList = globalEntries.filter(entry => { + return (typeof entry !== 'undefined') && validIds.has(this.getEntryParentid(entry)); + }); - let filteredAgents = agents.filter(isAssocWithEntry); - if (filteredAgents.length > 0) { - return this.getAgentSpiffeid(filteredAgents[0]); + if (typeof entriesList === 'undefined') { + return 0 + } else { + return entriesList.length } - return ""; + } else { + return 0 + } + } + + // getChildEntries takes in an agent metadata, avialble agents' spiffeids, list of entries and workload attestor info for specified agents + // returns agent metadata info for dashboard table + getChildEntries(agent, agentEntriesDict, globalEntries, WorkLoadAttestorInfo) { + var thisSpiffeid = this.getAgentSpiffeid(agent); + // get status + var status = this.getAgentStatusString(agent); + // get tornjak metadata + var metadata_entry = this.getAgentMetadata(thisSpiffeid, WorkLoadAttestorInfo); + 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, agentEntriesDict, globalEntries), + status: status, + platformType: plugin, + clusterName: cluster, + } } + + // workloadEntry takes in an entry metadata and workload attestor info for specified agents + // returns entry metadata info for dashboard table + workloadEntry(entry, WorkLoadAttestorInfo) { + var thisSpiffeId = this.getEntrySpiffeid(entry) + var thisParentId = this.getEntryParentid(entry) + // get tornjak metadata + var metadata_entry = this.getAgentMetadata(thisParentId, WorkLoadAttestorInfo); + var plugin = "None" + var cluster = "None" + if (metadata_entry["plugin"].length !== 0) { + plugin = metadata_entry["plugin"] + } + if (metadata_entry["cluster"].length !== 0) { + cluster = metadata_entry["cluster"] + } + // get spire data + var admin = this.getEntryAdminFlag(entry) + var expTime = "No Expiry Time" + if (typeof entry.expires_at !== 'undefined') { + var d = new Date(this.getEntryExpiryMillisecondsFromEpoch(entry)) + expTime = d.toLocaleDateString("en-US", { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: false }) + } + return { + id: entry.id, + spiffeid: thisSpiffeId, + parentId: thisParentId, + adminFlag: admin, + entryExpireTime: expTime, + platformType: plugin, + clusterName: cluster, + } + } + } function isSuperset(set, subset) { - for (let elem of subset) { - if (!set.has(elem)) { - return false - } + for (let elem of subset) { + if (!set.has(elem)) { + return false } - return true + } + return true } -function formatSelectors (s) { - return s.type + ":" + s.value; +function formatSelectors(s) { + return s.type + ":" + s.value; } diff --git a/tornjak-frontend/src/components/tornjak-helper.js b/tornjak-frontend/src/components/tornjak-helper.js index 8129ddeb..1e5030b9 100644 --- a/tornjak-frontend/src/components/tornjak-helper.js +++ b/tornjak-frontend/src/components/tornjak-helper.js @@ -1,13 +1,49 @@ import { Component } from 'react'; +import SpiffeHelper from './spiffe-helper'; class TornjakHelper extends Component { - detailsLink(selectedRows, title, ) { - const dashboardDetailsLink = "/tornjak/dashboard/details/"; - if (selectedRows.length !== 0) { - var detailsLink = dashboardDetailsLink + title.toLowerCase() + "/" + selectedRows[0].name; + constructor(props) { + super(props); + this.SpiffeHelper = new SpiffeHelper(); + this.state = { + }; + } + + detailsLink(selectedRows, entity,) { + const dashboardDetailsLink = "/tornjak/dashboard/details/"; + if (selectedRows.length !== 0) { + var detailsLink = dashboardDetailsLink + entity.toLowerCase() + "/" + encodeURIComponent(selectedRows.id); //encode URL since spiffeid contains special characters + } + return detailsLink; + } + + detailsDataParse(urlParams, props) { + let selectedData = [{}], id = decodeURIComponent(urlParams.id); + const { globalClustersList, globalAgentsList, globalEntriesList, globalAgentsWorkLoadAttestorInfo } = props; + if (urlParams.entity === "clusters") { + for (let i = 0; i < globalClustersList.length; i++) { + if (globalClustersList[i].name === id) { + selectedData = this.SpiffeHelper.cluster(globalClustersList[i], globalEntriesList) + } + } + } else if (urlParams.entity === "agents") { + for (let i = 0; i < globalAgentsList.length; i++) { + let agentId = "spiffe://" + globalAgentsList[i].id.trust_domain + globalAgentsList[i].id.path; + if (agentId === id) { + let agentEntriesDict = this.SpiffeHelper.getAgentsEntries(globalAgentsList, globalEntriesList) + selectedData = this.SpiffeHelper.getChildEntries(globalAgentsList[i], agentEntriesDict, globalEntriesList, globalAgentsWorkLoadAttestorInfo) } - return detailsLink; } + } else if (urlParams.entity === "entries") { + for (let i = 0; i < globalEntriesList.length; i++) { + if (globalEntriesList[i].id === id) { + selectedData = this.SpiffeHelper.workloadEntry(globalEntriesList[i], globalAgentsWorkLoadAttestorInfo) + } + } + } + return selectedData; + } } - export default TornjakHelper; \ No newline at end of file + +export default TornjakHelper; \ No newline at end of file diff --git a/tornjak-frontend/src/index.js b/tornjak-frontend/src/index.js index ef2edf8e..780bc9b2 100644 --- a/tornjak-frontend/src/index.js +++ b/tornjak-frontend/src/index.js @@ -3,10 +3,14 @@ import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; +import { Provider } from 'react-redux'; +import store from './redux/store'; ReactDOM.render( - + + + , document.getElementById('root') ); diff --git a/tornjak-frontend/src/redux/actions/index.js b/tornjak-frontend/src/redux/actions/index.js index 7a5650c1..d479f4b5 100644 --- a/tornjak-frontend/src/redux/actions/index.js +++ b/tornjak-frontend/src/redux/actions/index.js @@ -12,7 +12,6 @@ import { GLOBAL_CLUSTERS_LIST, GLOBAL_CLUSTER_TYPE_INFO, GLOBAL_CLICKED_DASHBOARD_TABLE, - GLOBAL_SELECTED_DASHBOARD_DATA } from './types'; // Expected input - List of clusters with their info @@ -239,14 +238,3 @@ export function clickedDashboardTabelFunc(globalClickedDashboardTable) { }); } } - -// Expected input - clicked dashboard row data from specific dashboard table -// selectedDashboardTableData returns the selected dashboard tabel data -export function selectedDashboardTableData(globalSelectedDashboardData) { - return dispatch => { - dispatch({ - type: GLOBAL_SELECTED_DASHBOARD_DATA, - payload: globalSelectedDashboardData - }); - } -} diff --git a/tornjak-frontend/src/redux/actions/types.js b/tornjak-frontend/src/redux/actions/types.js index a9fec5d9..624f4765 100644 --- a/tornjak-frontend/src/redux/actions/types.js +++ b/tornjak-frontend/src/redux/actions/types.js @@ -1,7 +1,6 @@ //tornjak export const GLOBAL_MESSAGE = 'GLOBAL_MESSAGE'; export const GLOBAL_CLICKED_DASHBOARD_TABLE = 'GLOBAL_CLICKED_DASHBOARD_TABLE'; -export const GLOBAL_SELECTED_DASHBOARD_DATA = 'GLOBAL_SELECTED_DASHBOARD_DATA'; //servers export const GLOBAL_SERVER_SELECTED = 'GLOBAL_SERVER_SELECTED'; diff --git a/tornjak-frontend/src/redux/reducers/tornjakReducer.js b/tornjak-frontend/src/redux/reducers/tornjakReducer.js index 6f6eab3d..8c72afe6 100644 --- a/tornjak-frontend/src/redux/reducers/tornjakReducer.js +++ b/tornjak-frontend/src/redux/reducers/tornjakReducer.js @@ -1,13 +1,11 @@ import { GLOBAL_MESSAGE, GLOBAL_CLICKED_DASHBOARD_TABLE, - GLOBAL_SELECTED_DASHBOARD_DATA, } from '../actions/types'; const initialState = { globalErrorMessage: "", globalClickedDashboardTable: "", - globalSelectedDashboardData: [], }; export default function tornjakReducer(state = initialState, action) { @@ -22,11 +20,6 @@ export default function tornjakReducer(state = initialState, action) { ...state, globalClickedDashboardTable: action.payload }; - case GLOBAL_SELECTED_DASHBOARD_DATA: - return { - ...state, - globalSelectedDashboardData: action.payload - }; default: return state; } From ef1e65e4ad1d2a4d2ee900aa715a1c4deb19c30c Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Thu, 12 Aug 2021 18:27:37 -1000 Subject: [PATCH 13/18] removing double declaration --- .../src/components/dashboard/agents-dashboard-table.js | 5 +++-- .../src/components/dashboard/clusters-dashboard-table.js | 5 +++-- .../src/components/dashboard/entries-dashboard-table.js | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js index 3f468cff..69a11751 100644 --- a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js @@ -64,10 +64,11 @@ class AgentDashboardTable extends React.Component { render() { const { numRows, selectedData } = this.props; + var data = []; if (selectedData === undefined) { - var data = this.agentList(); + data = this.agentList(); } else { - var data = this.selectedData(); + data = this.selectedData(); } return (
diff --git a/tornjak-frontend/src/components/dashboard/clusters-dashboard-table.js b/tornjak-frontend/src/components/dashboard/clusters-dashboard-table.js index 32bc9688..97febc02 100644 --- a/tornjak-frontend/src/components/dashboard/clusters-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/clusters-dashboard-table.js @@ -46,10 +46,11 @@ class ClusterDashboardTable extends React.Component { render() { const { numRows, selectedData } = this.props; + var data = []; if (selectedData === undefined) { - var data = this.clusterList(); + data = this.clusterList(); } else { - var data = this.selectedData(); + data = this.selectedData(); } return (
diff --git a/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js b/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js index b9296555..5d07c395 100644 --- a/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js @@ -51,10 +51,11 @@ class EntriesDashBoardTable extends React.Component { render() { const { numRows, selectedData } = this.props; + var data = []; if (selectedData === undefined) { - var data = this.entryList(); + data = this.entryList(); } else { - var data = this.selectedData(); + data = this.selectedData(); } return (
From 929ac109cfe44055731d53d2a948c16ba64dfa02 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Tue, 17 Aug 2021 05:12:03 -1000 Subject: [PATCH 14/18] handling getEntrySpiffeid of undefined error in spiffehelper --- tornjak-frontend/src/components/spiffe-helper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tornjak-frontend/src/components/spiffe-helper.js b/tornjak-frontend/src/components/spiffe-helper.js index 31ed2587..296b97e0 100644 --- a/tornjak-frontend/src/components/spiffe-helper.js +++ b/tornjak-frontend/src/components/spiffe-helper.js @@ -205,7 +205,7 @@ class SpiffeHelper extends Component { let agentEntries = agentEntriesDict[spiffeid]; if (agentEntries !== undefined) { for (let j = 0; j < agentEntries.length; j++) { - validIds.add(this.SpiffeHelper.getEntrySpiffeid(agentEntries[j])); + validIds.add(this.getEntrySpiffeid(agentEntries[j])); } } From 7fd6a30f6a429137609365d8507976ee9c55c0c6 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Tue, 17 Aug 2021 07:03:42 -1000 Subject: [PATCH 15/18] refactor selecteddata --- .../dashboard/agents-dashboard-table.js | 40 ++++++------------- .../dashboard/clusters-dashboard-table.js | 32 ++++++--------- .../components/dashboard/dashboard-details.js | 36 ++++++++++++++--- .../dashboard/entries-dashboard-table.js | 39 +++++++++--------- .../src/components/tornjak-helper.js | 6 ++- 5 files changed, 78 insertions(+), 75 deletions(-) diff --git a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js index 69a11751..fb13bbab 100644 --- a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js @@ -28,48 +28,32 @@ class AgentDashboardTable extends React.Component { } agentList() { + var filteredData = [], selectedDataKey = this.props.selectedDataKey; + let agentsList = []; if ((typeof this.props.globalEntries.globalEntriesList === 'undefined') || (typeof this.props.globalAgents.globalAgentsList === 'undefined')) { return []; } - let agentEntriesDict = this.SpiffeHelper.getAgentsEntries(this.props.globalAgents.globalAgentsList, this.props.globalEntries.globalEntriesList) - return this.props.globalAgents.globalAgentsList.map(currentAgent => { + agentsList = this.props.globalAgents.globalAgentsList.map(currentAgent => { return this.SpiffeHelper.getChildEntries(currentAgent, agentEntriesDict, this.props.globalEntries.globalEntriesList, this.props.globalAgents.globalAgentsWorkLoadAttestorInfo) }) - } - - selectedData() { - var data = this.agentList(), selectedData = this.props.selectedData, clickedDashboardTable = this.props.globalClickedDashboardTable; - var filteredData = [], selectedDataKey = []; - if (selectedData !== undefined) { - if (clickedDashboardTable === "clustersdetails") { - selectedDataKey = selectedData.name; - for (let i = 0; i < data.length; i++) { - if (data[i].clusterName === selectedDataKey) { - filteredData.push(data[i]); - } - } - } else if (clickedDashboardTable === "entriesdetails") { - selectedDataKey = selectedData.parentId; - for (let i = 0; i < data.length; i++) { - if (data[i].id === selectedDataKey) { - filteredData.push(data[i]); - } + + //For details page filtering data + if (selectedDataKey !== undefined) { + for (let i = 0; i < agentsList.length; i++) { + if ((agentsList[i].clusterName === selectedDataKey["agentsFilter"]) || (agentsList[i].id === selectedDataKey["agentsFilter"])) { + filteredData.push(agentsList[i]); } } return filteredData; } + return agentsList; } render() { - const { numRows, selectedData } = this.props; - var data = []; - if (selectedData === undefined) { - data = this.agentList(); - } else { - data = this.selectedData(); - } + const { numRows } = this.props; + var data = this.agentList(); return (
this.SpiffeHelper.cluster(a, this.props.globalEntries.globalEntriesList)) - } else { - return [] + var filteredData = [], selectedDataKey = this.props.selectedDataKey; + let clustersList = []; + if (typeof this.props.globalClustersList === 'undefined') { + return []; } - } + clustersList = this.props.globalClustersList.map(a => this.SpiffeHelper.cluster(a, this.props.globalEntries.globalEntriesList)); - selectedData() { - var data = this.clusterList(), filteredData = [], selectedDataKey = [], selectedData = this.props.selectedData; - if (selectedData !== undefined) { - selectedDataKey = selectedData.clusterName; - for (let i = 0; i < data.length; i++) { - if ((data[i].clusterName === selectedDataKey) || (data[i].name === selectedDataKey)) { - filteredData.push(data[i]); + //For details page filtering data + if (selectedDataKey !== undefined) { + for (let i = 0; i < clustersList.length; i++) { + if ((clustersList[i].clusterName === selectedDataKey["clustersFilter"]) || (clustersList[i].name === selectedDataKey["clustersFilter"])) { + filteredData.push(clustersList[i]); } } return filteredData; } + return clustersList; } render() { - const { numRows, selectedData } = this.props; - var data = []; - if (selectedData === undefined) { - data = this.clusterList(); - } else { - data = this.selectedData(); - } + const { numRows } = this.props; + var data = this.clusterList(); return (
+ selectedDataKey={this.selectedDataKey()} /> @@ -99,7 +123,7 @@ class DashboardDetails extends React.Component { + selectedDataKey={this.selectedDataKey()} /> @@ -126,7 +150,7 @@ class DashboardDetails extends React.Component { + selectedDataKey={this.selectedDataKey()} /> @@ -136,7 +160,7 @@ class DashboardDetails extends React.Component { + selectedDataKey={this.selectedDataKey()} /> @@ -165,7 +189,7 @@ class DashboardDetails extends React.Component { + selectedDataKey={this.selectedDataKey()} /> @@ -175,7 +199,7 @@ class DashboardDetails extends React.Component { + selectedDataKey={this.selectedDataKey()} /> diff --git a/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js b/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js index 5d07c395..c9c51f15 100644 --- a/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/entries-dashboard-table.js @@ -28,35 +28,32 @@ class EntriesDashBoardTable extends React.Component { } entryList() { - if (typeof this.props.globalEntriesList !== 'undefined' && typeof this.props.globalEntriesList.globalEntriesList !== 'undefined') { - return this.props.globalEntriesList.globalEntriesList.map(currentEntry => { - return this.SpiffeHelper.workloadEntry(currentEntry, this.props.globalAgents.globalAgentsWorkLoadAttestorInfo); - }) - } else { - return [] + var filteredData = [], selectedDataKey = this.props.selectedDataKey; + let entriesList = []; + if ((typeof this.props.globalEntries.globalEntriesList === 'undefined') || + (typeof this.props.globalAgents.globalAgentsList === 'undefined')) { + return []; } - } - selectedData() { - var data = this.entryList(), filteredData = [], selectedData = this.props.selectedData; - if (selectedData !== undefined) { - for (let i = 0; i < data.length; i++) { - if ((data[i].clusterName === selectedData.name) || (data[i].parentId === selectedData.spiffeid)) { - filteredData.push(data[i]); + entriesList = this.props.globalEntries.globalEntriesList.map(currentEntry => { + return this.SpiffeHelper.workloadEntry(currentEntry, this.props.globalAgents.globalAgentsWorkLoadAttestorInfo); + }) + + //For details page filtering data + if (selectedDataKey !== undefined) { + for (let i = 0; i < entriesList.length; i++) { + if ((entriesList[i].clusterName === selectedDataKey["entriesFilter"]) || (entriesList[i].parentId === selectedDataKey["entriesFilter"])) { + filteredData.push(entriesList[i]); } } return filteredData; } + return entriesList; } render() { - const { numRows, selectedData } = this.props; - var data = []; - if (selectedData === undefined) { - data = this.entryList(); - } else { - data = this.selectedData(); - } + const { numRows } = this.props; + var data = this.entryList(); return (
({ globalAgents: state.agents, - globalEntriesList: state.entries, + globalEntries: state.entries, globalClickedDashboardTable: state.tornjak.globalClickedDashboardTable, }) diff --git a/tornjak-frontend/src/components/tornjak-helper.js b/tornjak-frontend/src/components/tornjak-helper.js index 1e5030b9..4fb6d319 100644 --- a/tornjak-frontend/src/components/tornjak-helper.js +++ b/tornjak-frontend/src/components/tornjak-helper.js @@ -8,7 +8,9 @@ class TornjakHelper extends Component { this.state = { }; } - + + // detailsLink takes in selectedRows/ specified data and entity + // returns a specfic routing link/ URL for an entity detailsLink(selectedRows, entity,) { const dashboardDetailsLink = "/tornjak/dashboard/details/"; if (selectedRows.length !== 0) { @@ -17,6 +19,8 @@ class TornjakHelper extends Component { return detailsLink; } + // detailsDataParse takes in url parameters for a specific url and properties of a class + // returns a parsed and filtered data for the specifed entity from the url parameteres detailsDataParse(urlParams, props) { let selectedData = [{}], id = decodeURIComponent(urlParams.id); const { globalClustersList, globalAgentsList, globalEntriesList, globalAgentsWorkLoadAttestorInfo } = props; From 83a102365b7f00309278433ce1b5383f5694d058 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Tue, 17 Aug 2021 07:38:17 -1000 Subject: [PATCH 16/18] nit: encapsulate dashboard details render in separate class --- tornjak-frontend/src/App.js | 102 +++++++----------- .../dashboard/dashboard-details-render.js | 31 ++++++ 2 files changed, 70 insertions(+), 63 deletions(-) create mode 100644 tornjak-frontend/src/components/dashboard/dashboard-details-render.js diff --git a/tornjak-frontend/src/App.js b/tornjak-frontend/src/App.js index 259b10e8..b29329d1 100644 --- a/tornjak-frontend/src/App.js +++ b/tornjak-frontend/src/App.js @@ -1,7 +1,9 @@ import React from 'react'; import "bootstrap/dist/css/bootstrap.min.css"; -import { connect } from 'react-redux'; +import store from 'redux/store'; +import IsManager from './components/is_manager'; import { BrowserRouter as Router, Route } from "react-router-dom"; +import { Provider } from 'react-redux'; //enables all components to have access to everything inside our react app import NavigationBar from "./components/navbar"; import SelectServer from "./components/select-server"; import ClusterList from "./components/cluster-list"; @@ -13,70 +15,44 @@ import EntryCreate from "./components/entry-create"; import ServerManagement from "./components/server-management"; import TornjakServerInfo from "./components/tornjak-server-info"; 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 DashboardDetailsRender from 'components/dashboard/dashboard-details-render'; import './App.css'; -import DashboardDetails from 'components/dashboard/dashboard-details'; -import TornjakHelper from 'components/tornjak-helper'; -class App extends React.Component { - constructor(props) { - super(props); - this.TornjakHelper = new TornjakHelper(); - this.state = { - entity: "", - id: "" - }; - } - render() { - return ( - - -
-
- -
-
- -
- {IsManager &&
} - - - - - - - - - - ( - - )} - /> - -


- - - -
+function App() { + return ( + + +
+
+
- - - ); - } +
+ +
+ {IsManager &&
} + + + + + + + + + + ()} + /> + +


+ + + +
+
+
+
+ ); } -const mapStateToProps = (state) => ({ - globalClustersList: state.clusters.globalClustersList, - globalAgentsList: state.agents.globalAgentsList, - globalEntriesList: state.entries.globalEntriesList, - globalAgentsWorkLoadAttestorInfo: state.agents.globalAgentsWorkLoadAttestorInfo, -}) - -export default connect( - mapStateToProps, - {} -)(App) +export default App; diff --git a/tornjak-frontend/src/components/dashboard/dashboard-details-render.js b/tornjak-frontend/src/components/dashboard/dashboard-details-render.js new file mode 100644 index 00000000..8e90513f --- /dev/null +++ b/tornjak-frontend/src/components/dashboard/dashboard-details-render.js @@ -0,0 +1,31 @@ +import React from 'react'; +import { Component } from 'react'; +import { connect } from 'react-redux'; +import DashboardDetails from './dashboard-details'; +import TornjakHelper from '../tornjak-helper'; + +class DashboardDetailsRender extends Component { + constructor(props) { + super(props); + this.TornjakHelper = new TornjakHelper(); + this.state = {}; + } + render() { + const { params } = this.props; + return ( + + ); +} +} + +const mapStateToProps = (state) => ({ + globalClustersList: state.clusters.globalClustersList, + globalAgentsList: state.agents.globalAgentsList, + globalEntriesList: state.entries.globalEntriesList, + globalAgentsWorkLoadAttestorInfo: state.agents.globalAgentsWorkLoadAttestorInfo, +}) + +export default connect( + mapStateToProps, + {} +)(DashboardDetailsRender) From e245ee114bea9a30fc5a07d316183c3e6a561106 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Thu, 19 Aug 2021 08:04:48 -1000 Subject: [PATCH 17/18] refresh redux state during link share --- .../dashboard/agents-dashboard-table.js | 2 +- .../dashboard/dashboard-details-render.js | 54 +++++++++++++++++-- .../components/dashboard/dashboard-details.js | 2 +- tornjak-frontend/src/components/entry-list.js | 2 + 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js index fb13bbab..8a0c6d1c 100644 --- a/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js +++ b/tornjak-frontend/src/components/dashboard/agents-dashboard-table.js @@ -34,7 +34,7 @@ class AgentDashboardTable extends React.Component { (typeof this.props.globalAgents.globalAgentsList === 'undefined')) { return []; } - let agentEntriesDict = this.SpiffeHelper.getAgentsEntries(this.props.globalAgents.globalAgentsList, this.props.globalEntries.globalEntriesList) + let agentEntriesDict = this.SpiffeHelper.getAgentsEntries(this.props.globalAgents.globalAgentsList, this.props.globalEntries.globalEntriesList); agentsList = this.props.globalAgents.globalAgentsList.map(currentAgent => { return this.SpiffeHelper.getChildEntries(currentAgent, agentEntriesDict, this.props.globalEntries.globalEntriesList, this.props.globalAgents.globalAgentsWorkLoadAttestorInfo) }) diff --git a/tornjak-frontend/src/components/dashboard/dashboard-details-render.js b/tornjak-frontend/src/components/dashboard/dashboard-details-render.js index 8e90513f..d54d9df4 100644 --- a/tornjak-frontend/src/components/dashboard/dashboard-details-render.js +++ b/tornjak-frontend/src/components/dashboard/dashboard-details-render.js @@ -1,24 +1,72 @@ import React from 'react'; import { Component } from 'react'; import { connect } from 'react-redux'; +import IsManager from '../is_manager'; import DashboardDetails from './dashboard-details'; import TornjakHelper from '../tornjak-helper'; +import TornjakApi from '../tornjak-api-helpers'; +import { + serverSelectedFunc, + clustersListUpdateFunc, + agentsListUpdateFunc, + entriesListUpdateFunc, + tornjakServerInfoUpdateFunc, + serverInfoUpdateFunc, + selectorInfoFunc, + tornjakMessageFunc, + workloadSelectorInfoFunc, + agentworkloadSelectorInfoFunc, + clusterTypeInfoFunc, + clickedDashboardTabelFunc, +} from 'redux/actions'; class DashboardDetailsRender extends Component { constructor(props) { super(props); + this.TornjakApi = new TornjakApi(); this.TornjakHelper = new TornjakHelper(); this.state = {}; } + + componentDidMount() { + const { params } = this.props; + if(this.props.globalTornjakServerInfo === "" || this.props.globalServerInfo === undefined) { + if (IsManager) { + if (this.props.globalServerSelected !== "") { + this.props.clickedDashboardTabelFunc(params.entity+"details"); + this.TornjakApi.populateClustersUpdate(this.props.globalServerSelected, this.props.clustersListUpdateFunc, this.props.tornjakMessageFunc); + this.TornjakApi.populateAgentsUpdate(this.props.globalServerSelected, this.props.agentsListUpdateFunc, this.props.tornjakMessageFunc); + this.TornjakApi.populateEntriesUpdate(this.props.globalServerSelected, this.props.entriesListUpdateFunc, this.props.tornjakMessageFunc); + this.TornjakApi.refreshSelectorsState(this.props.globalServerSelected, this.props.agentworkloadSelectorInfoFunc); + this.TornjakApi.populateTornjakAgentInfo(this.props.globalServerSelected, this.props.agentworkloadSelectorInfoFunc, ""); + this.TornjakApi.populateTornjakServerInfo(this.props.globalServerSelected, this.props.tornjakServerInfoUpdateFunc, this.props.tornjakMessageFunc); + } + } else { + this.props.clickedDashboardTabelFunc(params.entity+"details"); + this.TornjakApi.refreshLocalSelectorsState(this.props.agentworkloadSelectorInfoFunc); + this.TornjakApi.populateLocalClustersUpdate(this.props.clustersListUpdateFunc, this.props.tornjakMessageFunc); + this.TornjakApi.populateLocalAgentsUpdate(this.props.agentsListUpdateFunc, this.props.tornjakMessageFunc); + this.TornjakApi.populateLocalEntriesUpdate(this.props.entriesListUpdateFunc, this.props.tornjakMessageFunc); + this.TornjakApi.populateLocalTornjakAgentInfo(this.props.agentworkloadSelectorInfoFunc, ""); + this.TornjakApi.populateLocalTornjakServerInfo(this.props.tornjakServerInfoUpdateFunc, this.props.tornjakMessageFunc); + if (this.props.globalTornjakServerInfo !== "") { + this.TornjakApi.populateServerInfo(this.props.globalTornjakServerInfo, this.props.serverInfoUpdateFunc); + } + } + } + } + render() { const { params } = this.props; return ( - + ); -} + } } const mapStateToProps = (state) => ({ + globalServerInfo: state.servers.globalServerInfo, + globalTornjakServerInfo: state.servers.globalTornjakServerInfo, globalClustersList: state.clusters.globalClustersList, globalAgentsList: state.agents.globalAgentsList, globalEntriesList: state.entries.globalEntriesList, @@ -27,5 +75,5 @@ const mapStateToProps = (state) => ({ export default connect( mapStateToProps, - {} + { serverSelectedFunc, clustersListUpdateFunc, agentsListUpdateFunc, entriesListUpdateFunc, tornjakServerInfoUpdateFunc, serverInfoUpdateFunc, selectorInfoFunc, tornjakMessageFunc, workloadSelectorInfoFunc, agentworkloadSelectorInfoFunc, clusterTypeInfoFunc, clickedDashboardTabelFunc } )(DashboardDetailsRender) diff --git a/tornjak-frontend/src/components/dashboard/dashboard-details.js b/tornjak-frontend/src/components/dashboard/dashboard-details.js index 82640fd5..53ca4fdd 100644 --- a/tornjak-frontend/src/components/dashboard/dashboard-details.js +++ b/tornjak-frontend/src/components/dashboard/dashboard-details.js @@ -91,7 +91,7 @@ class DashboardDetails extends React.Component {
- {(selectedData.length !== 0) && + {(selectedData.length !== 0) && (!selectedData[0]) &&
{(this.props.globalClickedDashboardTable === "clustersdetails") &&
diff --git a/tornjak-frontend/src/components/entry-list.js b/tornjak-frontend/src/components/entry-list.js index 71206f1b..8d675ac1 100644 --- a/tornjak-frontend/src/components/entry-list.js +++ b/tornjak-frontend/src/components/entry-list.js @@ -53,6 +53,8 @@ class EntryList extends Component { if(prevProps.globalServerSelected !== this.props.globalServerSelected){ this.TornjakApi.populateEntriesUpdate(this.props.globalServerSelected, this.props.entriesListUpdateFunc, this.props.tornjakMessageFunc) } + } else { + this.TornjakApi.populateLocalEntriesUpdate(this.props.entriesListUpdateFunc, this.props.tornjakMessageFunc) } } From 48f6fe27ba1a817d20dfc96d711fcb761c1ad1a8 Mon Sep 17 00:00:00 2001 From: Mohammed Abdi Date: Thu, 19 Aug 2021 08:13:02 -1000 Subject: [PATCH 18/18] add checks --- .../dashboard/dashboard-details-render.js | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tornjak-frontend/src/components/dashboard/dashboard-details-render.js b/tornjak-frontend/src/components/dashboard/dashboard-details-render.js index d54d9df4..2c9a6b9c 100644 --- a/tornjak-frontend/src/components/dashboard/dashboard-details-render.js +++ b/tornjak-frontend/src/components/dashboard/dashboard-details-render.js @@ -6,18 +6,18 @@ import DashboardDetails from './dashboard-details'; import TornjakHelper from '../tornjak-helper'; import TornjakApi from '../tornjak-api-helpers'; import { - serverSelectedFunc, - clustersListUpdateFunc, - agentsListUpdateFunc, - entriesListUpdateFunc, - tornjakServerInfoUpdateFunc, - serverInfoUpdateFunc, - selectorInfoFunc, - tornjakMessageFunc, - workloadSelectorInfoFunc, - agentworkloadSelectorInfoFunc, - clusterTypeInfoFunc, - clickedDashboardTabelFunc, + serverSelectedFunc, + clustersListUpdateFunc, + agentsListUpdateFunc, + entriesListUpdateFunc, + tornjakServerInfoUpdateFunc, + serverInfoUpdateFunc, + selectorInfoFunc, + tornjakMessageFunc, + workloadSelectorInfoFunc, + agentworkloadSelectorInfoFunc, + clusterTypeInfoFunc, + clickedDashboardTabelFunc, } from 'redux/actions'; class DashboardDetailsRender extends Component { @@ -30,10 +30,10 @@ class DashboardDetailsRender extends Component { componentDidMount() { const { params } = this.props; - if(this.props.globalTornjakServerInfo === "" || this.props.globalServerInfo === undefined) { + if (this.props.globalTornjakServerInfo === "" || this.props.globalServerInfo === undefined) { if (IsManager) { if (this.props.globalServerSelected !== "") { - this.props.clickedDashboardTabelFunc(params.entity+"details"); + this.props.clickedDashboardTabelFunc(params.entity + "details"); this.TornjakApi.populateClustersUpdate(this.props.globalServerSelected, this.props.clustersListUpdateFunc, this.props.tornjakMessageFunc); this.TornjakApi.populateAgentsUpdate(this.props.globalServerSelected, this.props.agentsListUpdateFunc, this.props.tornjakMessageFunc); this.TornjakApi.populateEntriesUpdate(this.props.globalServerSelected, this.props.entriesListUpdateFunc, this.props.tornjakMessageFunc); @@ -42,7 +42,7 @@ class DashboardDetailsRender extends Component { this.TornjakApi.populateTornjakServerInfo(this.props.globalServerSelected, this.props.tornjakServerInfoUpdateFunc, this.props.tornjakMessageFunc); } } else { - this.props.clickedDashboardTabelFunc(params.entity+"details"); + this.props.clickedDashboardTabelFunc(params.entity + "details"); this.TornjakApi.refreshLocalSelectorsState(this.props.agentworkloadSelectorInfoFunc); this.TornjakApi.populateLocalClustersUpdate(this.props.clustersListUpdateFunc, this.props.tornjakMessageFunc); this.TornjakApi.populateLocalAgentsUpdate(this.props.agentsListUpdateFunc, this.props.tornjakMessageFunc);