Adding support for Horizon FM CSV Reports

The Horizon interface has been enhanced with the addition of an
"Export" action (Button) on the Fault Management pages. This
feature allows for the comprehensive exportation of all
properties retrieved from the API, formatted as a CSV file.

Controllers have been integrated into the three Angular modules
of Fault Management (alarms, events, and event_suppression) to
facilitate data retrieval from the API, conversion to CSV format,
and subsequent download of the CSV file.

Test Plan:
 - PASS Runtime test on Standalone SX env:
   * Login as an admin user.
   * Download CSV reports for active alarms, events, and
     event-suppression.
   * Assess and confirm the CSV file contents.
   * Logout
   * Login with a user account with read-only permissions.
   * Download CSV reports for active alarms, events, and
     event-suppression.
   * Assess and confirm the CSV file contents

 - PASS Runtime test on DC env:
   * Login as an admin user.
   * Download CSV reports for active alarms, events, and
     event-suppression.
   * Assess and confirm the CSV file contents.
   * Logout
   * Login with a user account with read-only permissions.
   * Download CSV reports for active alarms, events, and
     event-suppression.
   * Assess and confirm the CSV file contents

Story: 2011009
Task: 49421

Change-Id: Id9e9b8971a31db8e8d1c8959af7769706fb492f5
Signed-off-by: Jorge Saffe <jorge.saffe@windriver.com>
This commit is contained in:
Jorge Saffe 2024-01-17 13:49:21 -05:00
parent de5edc47ce
commit 834c72fdb8
9 changed files with 302 additions and 7 deletions

View File

@ -0,0 +1,93 @@
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
/**
* Copyright (c) 2024 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
(function() {
'use strict';
angular
.module('horizon.dashboard.fault_management.active_alarms')
.controller('ActiveAlarmsController', ['horizon.dashboard.fault_management.active_alarms.service', '$scope', ActiveAlarmsController]);
var fieldMappings = {
'alarm_id': 'Alarm ID',
'reason_text': 'Reason Text',
'entity_instance_id': 'Entity Instance ID',
'severity': 'Severity',
'timestamp': 'Timestamp',
};
function ActiveAlarmsController(activeAlarmsService, $scope) {
$scope.downloadAlarmsData = function() {
activeAlarmsService.getPromise().then(function(response) {
var csvData = convertToCSV(response.data.items, fieldMappings);
triggerDownload(csvData, 'active-alarms-data.csv');
});
};
function convertToCSV(objArray, fieldMappings) {
var array = objArray;
var str = '';
var row = '';
// Header
for (var index in objArray[0]) {
if (fieldMappings[index]) {
row += '"' + fieldMappings[index].replace(/"/g, '""') + '",';
}
}
row = row.slice(0, -1);
str += row + '\r\n';
// Data
for (var i = 0; i < array.length; i++) {
var line = '';
for (var index in array[i]) {
if (fieldMappings[index]) {
var data = array[i][index];
if (data && typeof data === 'string') {
// Escape double quotes and replace internal line breaks
data = data.replace(/"/g, '""').replace(/(\r\n|\n|\r)/gm, " ");
}
line += '"' + data + '",';
}
}
line = line.slice(0, -1);
str += line + '\r\n';
}
return str;
}
function triggerDownload(csvData, filename) {
var blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });
var link = document.createElement("a");
if (link.download !== undefined) {
var url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", filename);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
})();

View File

@ -12,7 +12,7 @@
* under the License.
*/
/**
* Copyright (c) 2019 Wind River Systems, Inc.
* Copyright (c) 2019-2024 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
@ -181,6 +181,7 @@
$provide.constant('horizon.dashboard.fault_management.active_alarms.basePath', path);
$routeProvider.when('/admin/active_alarms', {
templateUrl: path + 'panel.html',
controller: 'ActiveAlarmsController',
resolve: {
searchResults: ['horizon.dashboard.fault_management.active_alarms.service', function (searchService) {
return searchService.getSuppressionList();

View File

@ -1,6 +1,11 @@
<hz-resource-panel resource-type-name="OS::StarlingX::ActiveAlarms">
<hz-resource-table resource-type-name="OS::StarlingX::ActiveAlarms"
<hz-resource-table resource-type-name="OS::StarlingX::ActiveAlarms"
track-by="trackBy">
</hz-resource-table>
<div ng-click="downloadAlarmsData()" class="download-icon" title="Download Active Alarms Data">
<span class="fa fa-download" aria-hidden="true"></span> Export CSV Report
</div>
</hz-resource-panel>

View File

@ -0,0 +1,94 @@
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
/**
* Copyright (c) 2024 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
(function() {
'use strict';
angular
.module('horizon.dashboard.fault_management.events')
.controller('EventsController', ['horizon.dashboard.fault_management.events.service', '$scope', EventsController]);
var fieldMappings = {
'timestamp': 'Timestamp',
'state': 'State',
'event_log_id': 'Event ID',
'reason_text': 'Reason Text',
'entity_instance_id': 'Entity Instance ID',
'severity': 'Severity',
};
function EventsController(eventsService, $scope) {
$scope.downloadEventData = function() {
eventsService.getPromise().then(function(response) {
var csvData = convertToCSV(response.data.items, fieldMappings);
triggerDownload(csvData, 'events-data.csv');
});
};
function convertToCSV(objArray, fieldMappings) {
var array = objArray;
var str = '';
var row = '';
// Header
for (var index in objArray[0]) {
if (fieldMappings[index]) {
row += '"' + fieldMappings[index].replace(/"/g, '""') + '",';
}
}
row = row.slice(0, -1);
str += row + '\r\n';
// Data
for (var i = 0; i < array.length; i++) {
var line = '';
for (var index in array[i]) {
if (fieldMappings[index]) {
var data = array[i][index];
if (data && typeof data === 'string') {
// Escape double quotes and replace internal line breaks
data = data.replace(/"/g, '""').replace(/(\r\n|\n|\r)/gm, " ");
}
line += '"' + data + '",';
}
}
line = line.slice(0, -1);
str += line + '\r\n';
}
return str;
}
function triggerDownload(csvData, filename) {
var blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });
var link = document.createElement("a");
if (link.download !== undefined) {
var url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", filename);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
})();

View File

@ -12,7 +12,7 @@
* under the License.
*/
/**
* Copyright (c) 2019 Wind River Systems, Inc.
* Copyright (c) 2019-2024 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
@ -195,6 +195,7 @@
$routeProvider.when('/admin/events', {
templateUrl: path + 'panel.html',
controller: 'EventsController',
resolve: {
searchResults: ['horizon.dashboard.fault_management.events.service', function (searchService) {
return searchService.getSuppressionList();

View File

@ -1,6 +1,11 @@
<hz-resource-panel resource-type-name="OS::StarlingX::Events">
<hz-resource-table resource-type-name="OS::StarlingX::Events"
<hz-resource-table resource-type-name="OS::StarlingX::Events"
track-by="trackBy">
</hz-resource-table>
<div ng-click="downloadEventData()" class="download-icon" title="Download Event Data">
<span class="fa fa-download" aria-hidden="true"></span> Export CSV Report
</div>
</hz-resource-panel>

View File

@ -0,0 +1,91 @@
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
/**
* Copyright (c) 2024 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
(function() {
'use strict';
angular
.module('horizon.dashboard.fault_management.events_suppression')
.controller('EventsSuppressionController', ['horizon.dashboard.fault_management.events_suppression.service', '$scope', EventsSuppressionController]);
var fieldMappings = {
'alarm_id': 'Event ID',
'description': 'Description',
'suppression_status': 'Status'
};
function EventsSuppressionController(eventsSuppressionService, $scope) {
$scope.downloadEventsSuppressionData = function() {
eventsSuppressionService.getPromise().then(function(response) {
var csvData = convertToCSV(response.data.items, fieldMappings);
triggerDownload(csvData, 'events-suppression-data.csv');
});
};
function convertToCSV(objArray, fieldMappings) {
var array = objArray;
var str = '';
var row = '';
// Header
for (var index in objArray[0]) {
if (fieldMappings[index]) {
row += '"' + fieldMappings[index].replace(/"/g, '""') + '",';
}
}
row = row.slice(0, -1);
str += row + '\r\n';
// Data
for (var i = 0; i < array.length; i++) {
var line = '';
for (var index in array[i]) {
if (fieldMappings[index]) {
var data = array[i][index];
if (data && typeof data === 'string') {
// Escape double quotes and replace internal line breaks
data = data.replace(/"/g, '""').replace(/(\r\n|\n|\r)/gm, " ");
}
line += '"' + data + '",';
}
}
line = line.slice(0, -1);
str += line + '\r\n';
}
return str;
}
function triggerDownload(csvData, filename) {
var blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });
var link = document.createElement("a");
if (link.download !== undefined) {
var url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", filename);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
})();

View File

@ -12,7 +12,7 @@
* under the License.
*/
/**
* Copyright (c) 2019 Wind River Systems, Inc.
* Copyright (c) 2019-2024 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
@ -130,7 +130,8 @@
var path = $windowProvider.$get().STATIC_URL + 'dashboard/fault_management/events_suppression/';
$provide.constant('horizon.dashboard.fault_management.events_suppression.basePath', path);
$routeProvider.when('/admin/events_suppression', {
templateUrl: path + 'panel.html'
templateUrl: path + 'panel.html',
controller: 'EventsSuppressionController',
});
}
})();

View File

@ -2,5 +2,9 @@
<hz-resource-table resource-type-name="OS::StarlingX::EventsSuppression"
track-by="trackBy">
</hz-resource-table>
</hz-resource-panel>
<div ng-click="downloadEventsSuppressionData()" class="download-icon" title="Download Events Suppression Data">
<span class="fa fa-download" aria-hidden="true"></span> Export CSV Report
</div>
</hz-resource-panel>