diff --git a/app/controllers/ems_storage_dashboard_controller.rb b/app/controllers/ems_storage_dashboard_controller.rb index 937f7097b79..862d98ff57b 100644 --- a/app/controllers/ems_storage_dashboard_controller.rb +++ b/app/controllers/ems_storage_dashboard_controller.rb @@ -23,6 +23,11 @@ def aggregate_status_data render :json => {:data => aggregate_status(params[:id])} end + def aggregate_event_data + assert_privileges('ems_storage_show') # TODO: might be ems_event_show + render :json => {:data => aggregate_event(params[:id])} + end + private def block_storage_heatmap_data(ems_id) @@ -33,6 +38,10 @@ def aggregate_status(ems_id) EmsStorageDashboardService.new(ems_id, self, EmsStorage).aggregate_status_data end + def aggregate_event(ems_id) + EmsStorageDashboardService.new(ems_id, self, EmsStorage).aggregate_event_data + end + def get_session_data @layout = "ems_storage_dashboard" end diff --git a/app/javascript/components/carbon-charts/stackBarChart.js b/app/javascript/components/carbon-charts/stackBarChart.js index 02a02a4c578..95a8bf192af 100644 --- a/app/javascript/components/carbon-charts/stackBarChart.js +++ b/app/javascript/components/carbon-charts/stackBarChart.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { StackedBarChart } from '@carbon/charts-react'; -const StackBarChartGraph = ({ data, title }) => { +const StackBarChartGraph = ({ data, title, chart_options=null }) => { const options = { title, axes: { @@ -24,7 +24,7 @@ const StackBarChartGraph = ({ data, title }) => { }; return ( - + ); }; diff --git a/app/javascript/components/provider-dashboard-charts/events-bar-chart/index.js b/app/javascript/components/provider-dashboard-charts/events-bar-chart/index.js new file mode 100644 index 00000000000..f49e24ecb47 --- /dev/null +++ b/app/javascript/components/provider-dashboard-charts/events-bar-chart/index.js @@ -0,0 +1,73 @@ +import React, { useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; +import { http } from '../../../http_api'; +import EmptyChart from "../emptyChart"; +import StackBarChartGraph from "../../carbon-charts/stackBarChart"; + +const EventChart = ({ + providerId, apiUrl, dataPoint1, dataPoint2, dataPointAvailable, title, + }) => { + const [data, setCardData] = useState({ loading: true }); + + useEffect(() => { + const url = `/${apiUrl}/${providerId}`; + + http.get(url) + .then((response) => { + setCardData({ + loading: false, + vms: response.data.aggEvents , + }); + }); + }, []); + if (data.loading) return null; + + const chart_options = { + title, + axes: { + left: { + mapsTo: 'value', + stacked: true, + }, + bottom: { + mapsTo: 'key', + scaleType: 'labels', + }, + }, + height: '400px', + tooltip: { + truncation: { + type: 'none', + }, + }, + color: { + pairing: { + option: 2 + }, + scale: { + fixed: "#1A52F3", + not_fixed: "#FF0000" + } + } + }; + + return ( +
+
+

{title}

+
+
+ {(data.vms.length > 0) ? + : } +
+
+ ); +}; + +EventChart.propTypes = { + providerId: PropTypes.string.isRequired, + apiUrl: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, +}; + +export default EventChart; diff --git a/app/javascript/components/provider-dashboard-charts/heat-map-chart/HeatMapChartGraph.js b/app/javascript/components/provider-dashboard-charts/heat-map-chart/HeatMapChartGraph.js index 2652650f514..2ee8f7bcb00 100644 --- a/app/javascript/components/provider-dashboard-charts/heat-map-chart/HeatMapChartGraph.js +++ b/app/javascript/components/provider-dashboard-charts/heat-map-chart/HeatMapChartGraph.js @@ -74,7 +74,6 @@ const HeatMapChartGraph = ({ }, experimental: true, height: '400px', - width: '280px', tooltip: { customHTML: heatmapCpuTooltip(data), truncation: { @@ -108,7 +107,6 @@ const HeatMapChartGraph = ({ }, }, height: '400px', - width: '280px', tooltip: { customHTML: heatmapMemoryTooltip(data), truncation: { diff --git a/app/javascript/packs/component-definitions-common.js b/app/javascript/packs/component-definitions-common.js index d5fa9aacda5..9cea536a99e 100644 --- a/app/javascript/packs/component-definitions-common.js +++ b/app/javascript/packs/component-definitions-common.js @@ -35,6 +35,7 @@ import CopyDashboardForm from '../components/copy-dashboard-form/copy-dashboard- import DashboardWidget from '../components/dashboard-widgets/dashboard-charts'; import Datastore from '../components/data-tables/datastore'; import DbList from '../components/data-tables/db-list'; +import EventChart from "../components/provider-dashboard-charts/events-bar-chart"; import FlavorForm from '../components/flavor-form'; import FilterDropdown from '../components/filter-dropdown'; import FirmwareRegistryForm from '../components/firmware-registry/firmware-registry-form'; @@ -168,6 +169,7 @@ ManageIQ.component.addReact('CopyDashboardForm', CopyDashboardForm); ManageIQ.component.addReact('DashboardWidget', DashboardWidget); ManageIQ.component.addReact('Datastore', Datastore); ManageIQ.component.addReact('DbList', DbList); +ManageIQ.component.addReact('EventChart', EventChart); ManageIQ.component.addReact('FirmwareRegistryForm', FirmwareRegistryForm); ManageIQ.component.addReact('FlavorForm', FlavorForm); ManageIQ.component.addReact('FilterDropdown', FilterDropdown); diff --git a/app/services/ems_storage_dashboard_service.rb b/app/services/ems_storage_dashboard_service.rb index e9d446be93d..bcc16efd5c2 100644 --- a/app/services/ems_storage_dashboard_service.rb +++ b/app/services/ems_storage_dashboard_service.rb @@ -11,6 +11,12 @@ def aggregate_status_data }.compact end + def aggregate_event_data + { + :aggEvents => agg_events + }.compact + end + def aggregate_status { :quadicon => @controller.instance_exec(@ems, &EmsStorageDashboardService.quadicon_calc), @@ -71,7 +77,6 @@ def get_physical_storages_ids def heatmaps resource_usage = [] - @ems.physical_storages.each do |system| system.storage_resources.each do |resource| resource_usage << { @@ -90,4 +95,36 @@ def heatmaps :title => 'Used capacity [%]' } end + + def agg_events + event_hash = {} + event_list = [] + events = EmsEvent.where("ems_id=#{@ems_id}") + + events.each do |event| + unless event_hash[event.physical_storage_name] + event_hash[event.physical_storage_name] = {:fixed => 0, :not_fixed => 0} + end + if event.event_type == "autosde_critical_alert_fixed" + event_hash[event.physical_storage_name][:fixed] = event_hash[event.physical_storage_name][:fixed] + 1 + else + event_hash[event.physical_storage_name][:not_fixed] = event_hash[event.physical_storage_name][:not_fixed] + 1 + end + end + + event_hash.each_pair do |key, value| + event_list << { + :group => "fixed", + :key => key, + :value => value[:fixed] + } + event_list << { + :group => "not_fixed", + :key => key, + :value => value[:not_fixed] + } + end + + event_list.to_a + end end diff --git a/app/views/ems_storage/_show_block_storage_dashboard.html.haml b/app/views/ems_storage/_show_block_storage_dashboard.html.haml index b2d548eaf27..2e0d922d046 100644 --- a/app/views/ems_storage/_show_block_storage_dashboard.html.haml +++ b/app/views/ems_storage/_show_block_storage_dashboard.html.haml @@ -4,8 +4,11 @@ = react 'AggregateStatusCard', {:providerId => @record.id.to_s, :providerType => 'ems_storage'} .row.row-tile-pf .col-xs-12.col-sm-12.col-md-6 - = react('HeatChart', :providerId => @record.id.to_s, - :apiUrl => 'ems_storage_dashboard/resources_capacity_data', :dataPoint1 => 'resourceUsage', :dataPointAvailable => false, :title => _('Used capacity [%]')) + = react('HeatChart', :providerId => @record.id.to_s, :apiUrl => 'ems_storage_dashboard/resources_capacity_data', + :dataPoint1 => 'resourceUsage', :dataPointAvailable => false, :title => _('Used Capacity [%]')) + .col-xs-12.col-sm-12.col-md-6 + = react('EventChart', :providerId => @record.id.to_s, :apiUrl => 'ems_storage_dashboard/aggregate_event_data', + :title => 'Fixed vs Not-Fixed Events By Storage-System') :javascript ManageIQ.angular.app.value('providerId', '#{@record.id}'); diff --git a/config/routes.rb b/config/routes.rb index 0e5e75b330e..588833cc959 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -119,6 +119,7 @@ show aggregate_status_data resources_capacity_data + aggregate_event_data ] }, @@ -134,6 +135,7 @@ tagging_edit download_private_key ownership + ) + compare_get, :post => %w(