diff --git a/client-reactjs/src/components/application/dashboard/clusterUsage/charts/CurrentClusterUsageCharts.jsx b/client-reactjs/src/components/application/dashboard/clusterUsage/charts/CurrentClusterUsageCharts.jsx index 8f5cea27c..fef8b66d3 100644 --- a/client-reactjs/src/components/application/dashboard/clusterUsage/charts/CurrentClusterUsageCharts.jsx +++ b/client-reactjs/src/components/application/dashboard/clusterUsage/charts/CurrentClusterUsageCharts.jsx @@ -5,6 +5,7 @@ import { Empty, Select } from 'antd'; import { addQueriesToUrl } from '../../../../common/AddQueryToUrl.js'; import { authHeader, handleError } from '../../../../common/AuthHeader.js'; import MeterGauge from './MeterGauge.jsx'; +import '../index.css'; const { Option } = Select; function CurrentClusterUsageCharts({ selectedCluster, setSelectedCluster }) { @@ -28,7 +29,27 @@ function CurrentClusterUsageCharts({ selectedCluster, setSelectedCluster }) { const response = await fetch(`/api/cluster/currentClusterUsage/${clusterId}`, payload); if (!response.ok) handleError(response); const data = await response.json(); - setCurrentUsage(data); + + const groupedUsage = []; + const groupedData = {}; + + data.forEach((d) => { + const key = d.maxUsage + 'x' + d.meanUsage; + if (groupedData[key]) { + const newEngineList = [...groupedData[key].engines, d.name]; + groupedData[key] = { ...groupedData[key], engines: newEngineList }; + } else { + groupedData[key] = { data: { maxUsage: d.maxUsage, meanUsage: d.meanUsage }, engines: [d.name] }; + } + }); + + if (Object.keys(groupedData).length > 0) { + for (const key in groupedData) { + groupedUsage.push({ data: groupedData[key].data, engines: groupedData[key].engines }); + } + } + + setCurrentUsage(groupedUsage); } catch (err) { setCurrentUsage([]); handleError(err); @@ -42,32 +63,45 @@ function CurrentClusterUsageCharts({ selectedCluster, setSelectedCluster }) { }; return ( -
-
Current Storage Usage
- -
+
+
+ {clusters ? ( + + ) : null} +
+
+ {/*
Current Storage Usage
*/} + {currentUsage.length < 1 ? ( - +
+ +
) : ( - currentUsage.map((current) => { - return ; - }) +
+ {currentUsage.map((current) => { + return ( +
+ +
+ ); + })} +
)}
diff --git a/client-reactjs/src/components/application/dashboard/clusterUsage/charts/MeterGauge.jsx b/client-reactjs/src/components/application/dashboard/clusterUsage/charts/MeterGauge.jsx index 2573068a9..7f3fbde8f 100644 --- a/client-reactjs/src/components/application/dashboard/clusterUsage/charts/MeterGauge.jsx +++ b/client-reactjs/src/components/application/dashboard/clusterUsage/charts/MeterGauge.jsx @@ -5,8 +5,6 @@ import { Gauge } from '@ant-design/plots'; import { Popover } from 'antd'; const MeterGauge = ({ data }) => { - // data.maxUsage = Math.floor(Math.random() * 100); - //Gauge color const gaugeColor = (maxUsage) => { if (maxUsage <= 50) { @@ -63,9 +61,13 @@ const MeterGauge = ({ data }) => { offsetY: 36, style: { fontSize: '18px', - color: '#01060d', + color: '#1890ff', + textDecoration: 'underline', + }, + + formatter: () => { + return data.engines.length < 2 ? data.name : [`${data.name} [+ ${data.engines.length - 1} more]`]; }, - formatter: () => data.name, }, }, }; @@ -76,10 +78,21 @@ const MeterGauge = ({ data }) => {
Max : {data.maxUsage} %
Mean: {data.meanUsage} %
+ + {data.engines.length > 1 ? ( + <> +
+ <> + {data.engines.map((engine) => { + return
{engine}
; + })} + + + ) : null}
}> - <> + <> ); }; diff --git a/client-reactjs/src/components/application/dashboard/clusterUsage/charts/StorageUsageHistoryCharts.jsx b/client-reactjs/src/components/application/dashboard/clusterUsage/charts/StorageUsageHistoryCharts.jsx index 2f5194225..67cce7a4b 100644 --- a/client-reactjs/src/components/application/dashboard/clusterUsage/charts/StorageUsageHistoryCharts.jsx +++ b/client-reactjs/src/components/application/dashboard/clusterUsage/charts/StorageUsageHistoryCharts.jsx @@ -40,7 +40,6 @@ function StorageUsageHistoryCharts({ clusterUsageHistory, setViewExpandedGraph, return (
-
Storage Usage History
{groupedClusterUsageHistory.length > 0 ? ( groupedClusterUsageHistory.map((clusterHistory, index) => { @@ -50,14 +49,25 @@ function StorageUsageHistoryCharts({ clusterUsageHistory, setViewExpandedGraph,
- {_.capitalize(clusterHistory.engines[0])} + +
+ {clusterHistory.engines[0].length < 40 + ? clusterHistory.engines[0] + : clusterHistory.engines[0].slice(0, 22) + + ' ... ' + + clusterHistory.engines[0].slice( + clusterHistory.engines[0].length - 3, + clusterHistory.engines[0].length + )} +
+
(
{index === 0 ? null : _.capitalize(item)}
))}> {clusterHistory.engines.length > 1 ? ( -   {`[ + ${clusterHistory.engines.length - 1} more ]`} +   {`[ +${clusterHistory.engines.length - 1} more ]`} ) : null}
diff --git a/client-reactjs/src/components/application/dashboard/clusterUsage/index.css b/client-reactjs/src/components/application/dashboard/clusterUsage/index.css index 4b2564bcc..733d1b0e0 100644 --- a/client-reactjs/src/components/application/dashboard/clusterUsage/index.css +++ b/client-reactjs/src/components/application/dashboard/clusterUsage/index.css @@ -19,7 +19,7 @@ } .storageUsageHistoryCharts__box { - max-width: 400px; + width: 400px; height: 250px; } @@ -32,13 +32,13 @@ } .storageUsageHistoryCharts__engineName { - font-size: 18px; color: #808080; font-weight: 500; margin-top: 15px; display: flex; place-items: center; justify-content: center; + padding: 5px 0px 5px 0px; } .storageUsageHistoryCharts__engineName__additionalText { @@ -55,6 +55,8 @@ display: none; color: #808080; margin-left: 10px; + font-size: 12px; + color: var(--primary); } .storageUsageHistoryCharts__chartAndName:hover .storageUsageHistoryCharts__viewMore { @@ -87,3 +89,61 @@ border: 1px solid #808080; background-color: white; } + +.storageUsageHistoryCharts__engineName_scroll { + color: var(--primary); + text-decoration: underline; +} + +/* ---------------------------------------------------- */ +.currentClusterUsageCharts_container { + display: flex; + flex-direction: column; + width: 100%; +} +.currentClusterUsageCharts_container div:first-child { + text-align: center; +} +.currentClusterUsageCharts_main { + border: 1px solid lightGray; + margin-top: 10px; + text-align: center; + padding-bottom: 15px; + min-height: 82vh; +} + +.currentClusterUsageCharts_title { + padding: 10px; + font-size: 20px; + font-weight: 500; +} + +.currentClusterUsageCharts_clusterSelector { + width: 200px; + justify-content: space-around; +} + +.currentClusterUsageCharts_empty { + margin-top: 25px; + display: flex; + flex-wrap: wrap; + justify-content: center; +} + +.currentClusterUsageCharts_meterGauges_5orLess { + margin-top: 25px; + display: flex; + justify-content: center; + flex-wrap: wrap; +} + +.currentClusterUsageCharts_meterGauges_5orMore { + margin-top: 25px; + display: flex; + justify-content: flex-start; + flex-wrap: wrap; +} + +.currentClusterUsageCharts_meterGaugeBox { + width: 300px; +} diff --git a/client-reactjs/src/components/application/dashboard/clusterUsage/index.js b/client-reactjs/src/components/application/dashboard/clusterUsage/index.js index 329d4ee8d..cb7612da7 100644 --- a/client-reactjs/src/components/application/dashboard/clusterUsage/index.js +++ b/client-reactjs/src/components/application/dashboard/clusterUsage/index.js @@ -78,7 +78,7 @@ function ClusterUsage() { if (selectedCluster && historyDateRange) getClusterUsageHistory(selectedCluster, historyDateRange); }, [selectedCluster, historyDateRange]); - //Get current usage func + //Get usage history func const getClusterUsageHistory = async (clusterId) => { try { const payload = { @@ -137,5 +137,3 @@ function ClusterUsage() { } export default ClusterUsage; - -//TODO When the max date is changed first - sometimes not rendering data diff --git a/client-reactjs/src/components/common/AddQueryToUrl.js b/client-reactjs/src/components/common/AddQueryToUrl.js index a3d43226d..62764fa5c 100644 --- a/client-reactjs/src/components/common/AddQueryToUrl.js +++ b/client-reactjs/src/components/common/AddQueryToUrl.js @@ -1,5 +1,5 @@ // A func that checks if there are existing query params, if so appends to them, if not creates one -const addQueriesToUrl = ({ queryName, queryValue }) => { +export const addQueriesToUrl = ({ queryName, queryValue }) => { //Get current URL and its existing queries const urlParams = new URLSearchParams(window.location.search); @@ -16,7 +16,7 @@ const addQueriesToUrl = ({ queryName, queryValue }) => { }; // Get all params from url -const getQueryParamsFromUrl = () => { +export const getQueryParamsFromUrl = () => { const urlParams = new URLSearchParams(window.location.search); const queryParamsObject = {}; @@ -27,5 +27,3 @@ const getQueryParamsFromUrl = () => { return queryParamsObject; }; - -module.exports = { addQueriesToUrl, getQueryParamsFromUrl }; diff --git a/server/job-scheduler.js b/server/job-scheduler.js index 5a6e4bd27..58526f27e 100644 --- a/server/job-scheduler.js +++ b/server/job-scheduler.js @@ -681,8 +681,8 @@ class JobScheduler { } } // -------------------------------------------------------------------------------------------- - // Job monitoring bree job - createClusterUsageHistoryJob(){ + // Cluster monitoring bree job + async createClusterUsageHistoryJob(){ const uniqueJobName = `Cluster Usage History Tracker`; const job = { interval: 14400000, // 4 hours diff --git a/server/jobs/submitClusterUsageTracker.js b/server/jobs/submitClusterUsageTracker.js index 328b1c52e..828350956 100644 --- a/server/jobs/submitClusterUsageTracker.js +++ b/server/jobs/submitClusterUsageTracker.js @@ -63,9 +63,10 @@ const hpccUtil = require("../utils/hpcc-util"); targetClusterUsage.forEach(target =>{ const newData = { date: currentTimeStamp, - maxUsage: target.max, - meanUsage: target.mean, + maxUsage: target.max.toFixed(2), + meanUsage: target.mean.toFixed(2), }; + if(machines.includes(target.Name)){ storageUsageHistory[target.Name].unshift(newData) }else{ diff --git a/server/routes/hpcc/read.js b/server/routes/hpcc/read.js index 153b497a0..4f82f92f5 100644 --- a/server/routes/hpcc/read.js +++ b/server/routes/hpcc/read.js @@ -316,9 +316,10 @@ router.post( router.get("/getClusters", async (req, res) => { try { const clusters = await Cluster.findAll({ - attributes: { exclude: ["hash", "username"] }, + attributes: { exclude: ["hash", "username", "metaData"] }, order: [["createdAt", "DESC"]], }); + res.send(clusters); } catch (err) { logger.error(err);