Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding support to filter events by new group levels #4217

Merged
merged 1 commit into from Jul 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -21,6 +21,12 @@ ManageIQ.angular.app.controller('timelineOptionsController', ['$http', 'miqServi
vm.availableCategories = categories;
};

vm.clearLevelsIfNotSelected = function() {
if (vm.reportModel.tl_categories.length === 0) {
vm.reportModel.tl_levels = undefined;
}
};

vm.eventTypeUpdated = function() {
vm.reportModel.tl_categories = [];
};
Expand Down Expand Up @@ -72,13 +78,6 @@ ManageIQ.angular.app.controller('timelineOptionsController', ['$http', 'miqServi
}
ManageIQ.calendar.calDateFrom = startDay.toDate();
ManageIQ.calendar.calDateTo = endDay.toDate();
if (vm.reportModel.tl_show === 'timeline') {
if (vm.reportModel.showDetailedEvents) {
vm.reportModel.tl_fl_typ = 'detail';
} else {
vm.reportModel.tl_fl_typ = 'critical';
}
}
miqService.sparkleOn();
miqService.miqAsyncAjaxButton(url, miqService.serializeModel(vm.reportModel));
};
Expand Down
49 changes: 48 additions & 1 deletion app/assets/javascripts/miq_timeline.js
Expand Up @@ -62,6 +62,50 @@
});
}

function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

function selectSevereer(severityX, severityY) {
var weight = {
detail: 0,
warning: 1,
critical: 2
};
return (weight[severityX] > weight[severityY] ? severityX : severityY);
}

function eventColor(eventData) {
var colors = {
detail: '#00659C',
critical: '#C00019',
warning: '#E17B1C'
};

if (eventData.hasOwnProperty('events')) {
var severity = 'detail';
var eventList = eventData.events;
for (var i = 0; i < eventList.length; i++) {
severity = selectSevereer(eventList[i].data.group_level.value, severity);
}
return colors[severity];
}
return colors[eventData.data.group_level.value];
}

function createTimelineLegend(eventData) {
var legendHTML = '';
for (var property in eventData) {
var value = eventData[property].value;
if (property === "group_level") {
var color = eventColor({data: eventData});
value = "<text style='color:" + color + "'>" + capitalize(value) + "</text>";
}
legendHTML += "<b>" + eventData[property].text + ":</b>&nbsp;" + value + "<br/>";
}
return legendHTML;
}

ManageIQ.Timeline = {
load: function (json, start, end) {
var data = [],
Expand All @@ -80,10 +124,12 @@
if (json[x].data !== undefined && json[x].data.length > 0) {
var timelinedata = json[x].data[0];
for (var y in timelinedata) {
var eventData = timelinedata[y].event;
data[x].data.push({});
data[x].data[y].data = eventData;
data[x].data[y].date = new Date(timelinedata[y].start);
data[x].data[y].details = {};
data[x].data[y].details.event = timelinedata[y].description;
data[x].data[y].details.event = createTimelineLegend(eventData);
}
data[x].display = true;
}
Expand All @@ -93,6 +139,7 @@
.minScale(1)
.maxScale(timeSpanMilliseconds / one_hour)
.eventGrouping(360000).labelWidth(170)
.eventColor(eventColor)
.eventPopover(handlePopover).eventClick(eventClick);

if(!dataHasName) {
Expand Down
3 changes: 0 additions & 3 deletions app/controllers/application_controller/timelines.rb
Expand Up @@ -61,7 +61,6 @@ def tl_build_init_options(refresh = nil)

if @tl_options.policy_events?
@tl_options.policy.result ||= "both"

@tl_options.policy.categories ||= []
if @tl_options.policy.categories.blank?
@tl_options.policy.categories.push("VM Operation")
Expand All @@ -72,8 +71,6 @@ def tl_build_init_options(refresh = nil)
end
end
end
elsif @tl_options.management.level.nil?
@tl_options.management.level = "critical"
end
end

Expand Down
25 changes: 19 additions & 6 deletions app/controllers/application_controller/timelines/options.rb
Expand Up @@ -30,18 +30,21 @@ def update_start_end(sdate, edate)
end

ManagementEventsOptions = Struct.new(
:level,
:levels,
:categories,
) do
def update_from_params(params)
self.level = params[:tl_fl_typ] == "critical" ? :critical : :detail
self.levels = params[:tl_levels]&.map(&:to_sym) || group_levels
self.categories = {}
if params[:tl_categories]
params[:tl_categories].each do |category|
event_group = event_groups[events[category]].clone
next unless event_group.keys.include_any?(levels)
categories[events[category]] = {:display_name => category}
categories[events[category]][:event_groups] = level == :critical ?
event_groups[events[category]][level] :
event_groups[events[category]][level] + event_groups[events[category]][:critical]
unless levels.include_all?(event_group.keys)
event_group.delete_if { |key, _v| !levels.include?(key) }
end
categories[events[category]][:event_groups] = event_group.values.flatten
end
end
end
Expand All @@ -62,12 +65,22 @@ def event_set
end

def drop_cache
@events = @event_groups = nil
@events = @event_groups = @lvl_text_value = nil
end

def event_groups
@event_groups ||= EmsEvent.event_groups
end

def levels_text_and_value
@lvl_text_value ||= group_levels.map { |level| [level.to_s.titleize, level] }
end

private

def group_levels
EmsEvent::GROUP_LEVELS
end
end

PolicyEventsOptions = Struct.new(
Expand Down
21 changes: 15 additions & 6 deletions app/views/layouts/_tl_options.html.haml
Expand Up @@ -29,6 +29,21 @@
= select_tag("tl_category_management",
options_for_select(@tl_options.management.events.keys.sort, nil),
'ng-model' => 'vm.reportModel.tl_categories',
'ng-change' => 'vm.clearLevelsIfNotSelected()',
'title' => _('No category selected'),
"selectpicker-for-select-tag" => '',
'data-live-search' => 'true',
'data-actions-box' => 'true',
'data-select-all-text' => _('Select All'),
'data-deselect-all-text' => _('Deselect All'),
'multiple' => '',
:class => 'selectpicker category-selector')
%span{'ng-if' => 'vm.reportModel.tl_show === "timeline"'}
= select_tag("tl_levels_management",
options_for_select(@tl_options.management.levels_text_and_value.sort, nil),
'ng-model' => 'vm.reportModel.tl_levels',
'title' => _('No severity selected'),
'ng-disabled' => 'vm.reportModel.tl_categories.length === 0',
"selectpicker-for-select-tag" => '',
'data-live-search' => 'true',
'data-actions-box' => 'true',
Expand All @@ -47,12 +62,6 @@
'data-deselect-all-text' => _('Deselect All'),
'multiple' => '',
:class => 'selectpicker category-selector')
%span{'ng-if' => 'vm.reportModel.tl_show === "timeline"', 'class' => 'timeline-option'}
%label
%input{:type => 'checkbox',
:name => 'showDetailedEvents',
'ng-model' => 'vm.reportModel.showDetailedEvents'}
= _("Show Detailed Events")
%span{'ng-if' => 'vm.reportModel.tl_show !== "timeline"', 'class' => 'timeline-option'}
%label.radio
%input{"ng-model" => "vm.reportModel.tl_result", :type => "radio", :value => "success"}
Expand Down
17 changes: 10 additions & 7 deletions lib/report_formatter/timeline.rb
Expand Up @@ -155,17 +155,20 @@ def tl_event(row, col)
:ems_container => ems_container,
:time_zone => tz}
tl_message = TimelineMessage.new(row, rec, flags, mri.db)
e_text = ''
event_data = {}
col_order.each_with_index do |co, co_idx|
val = tl_message.message_html(co)
e_text += "<b>#{headers[co_idx]}:</b>&nbsp;#{val}<br/>" unless val.to_s.empty? || co == "id"
value = tl_message.message_html(co)
next if value.to_s.empty? || co == "id"
event_data[co] = {
:value => value,
:text => headers[co_idx]
}
end
e_text = e_text.chomp('<br/>')

# Add the event to the timeline
@events_data.push("start" => format_timezone(row[col], tz, 'view'),
"title" => e_title.length < 20 ? e_title : e_title[0...17] + "...",
"description" => e_text)
@events_data.push("start" => format_timezone(row[col], tz, 'view'),
"title" => e_title.length < 20 ? e_title : e_title[0...17] + "...",
"event" => event_data)
end
end
end
21 changes: 17 additions & 4 deletions spec/controllers/application_controller/timelines_spec.rb
Expand Up @@ -38,11 +38,11 @@
expect(options.policy[:categories]).to include('VM Operation')
end

it "unchecking Detailed events checkbox of Timelines options should remove them from list of events" do
it "selecting critical option of the selectpicker in the timeline should append them to events filter list" do
controller.instance_variable_set(:@_params,
:id => @ems.id,
:tl_show => "timeline",
:tl_fl_typ => "critical",
:tl_levels => ["critical"],
:tl_categories => ["Power Activity"])
expect(controller).to receive(:render)
controller.send(:tl_chooser)
Expand All @@ -51,17 +51,30 @@
expect(options.management[:categories][:power][:event_groups]).to_not include('PowerOffVM_Task')
end

it "checking Detailed events checkbox of Timelines options should append them to list of events" do
it "selecting details option of the selectpicker in the timeline should append them to events filter list" do
controller.instance_variable_set(:@_params,
:id => @ems.id,
:tl_show => "timeline",
:tl_fl_typ => "detail",
:tl_levels => ["detail"],
:tl_categories => ["Power Activity"])
expect(controller).to receive(:render)
controller.send(:tl_chooser)
options = assigns(:tl_options)
expect(options.management[:categories][:power][:event_groups]).to include('PowerOffVM_Task')
expect(options.management[:categories][:power][:event_groups]).to_not include('AUTO_FAILED_SUSPEND_VM')
end

it "selecting two options of the selectpicker in the timeline should append both to events filter list" do
controller.instance_variable_set(:@_params,
:id => @ems.id,
:tl_show => "timeline",
:tl_levels => %w(critical detail),
:tl_categories => ["Power Activity"])
expect(controller).to receive(:render)
controller.send(:tl_chooser)
options = assigns(:tl_options)
expect(options.management[:categories][:power][:event_groups]).to include('AUTO_FAILED_SUSPEND_VM')
expect(options.management[:categories][:power][:event_groups]).to include('PowerOffVM_Task')
end
end
end
Expand Down
7 changes: 3 additions & 4 deletions spec/lib/report_formater/timeline_spec.rb
Expand Up @@ -208,9 +208,8 @@ def stub_ems_event(event_type)
@report.rpt_options = nil
allow_any_instance_of(Ruport::Controller::Options).to receive(:mri).and_return(@report)
events = ReportFormatter::ReportTimeline.new.build_document_body
expect(JSON.parse(events)[0]["data"][0][0]["description"]).to include("Source Instance Location:")
expect(JSON.parse(events)[0]["data"][0][0]["description"]).to_not include("Source Instance:")
expect(JSON.parse(events)[0]["data"][0][0]["description"]).to_not include("Destination Instance:")
expect(JSON.parse(events)[0]["data"][0][0]["description"]).to_not include("Destination Instance Location:")
json = JSON.parse(events)[0]["data"][0][0]["event"]
expect(json["vm_location"]["text"]).to eq("Source Instance Location")
expect(json["vm_location"]["value"]).to eq("foo")
end
end