wazuh-kibana-app/public/kibana-integrations/kibana-visualization.js

147 lines
7.0 KiB
JavaScript
Raw Normal View History

/*
* Wazuh app - Custom visualization directive
* Copyright (C) 2018 Wazuh, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Find more information about this on the LICENSE file.
*/
2018-09-03 09:46:55 +00:00
import $ from 'jquery';
import { uiModules } from 'ui/modules';
import { getVisualizeLoader } from './loader';
2018-09-03 09:46:55 +00:00
import { timefilter } from 'ui/timefilter';
2018-07-24 08:49:44 +00:00
const app = uiModules.get('apps/webinar_app', []);
2018-09-03 09:46:55 +00:00
app.directive('kbnVis', function () {
2018-07-24 08:49:44 +00:00
return {
restrict: 'E',
scope: {
visID: '=visId',
specificTimeRange: '=specificTimeRange'
},
2018-09-03 09:46:55 +00:00
controller($scope, $rootScope, wzsavedVisualizations, errorHandler, rawVisualizations, loadedVisualizations, tabVisualizations, discoverPendingUpdates, visHandlers) {
2018-07-24 08:49:44 +00:00
let implicitFilter = '';
let rawFilters = [];
let rendered = false;
let visualization = null;
let visHandler = null;
let renderInProgress = false;
const setSearchSource = discoverList => {
try {
if ($scope.visID !== 'Wazuh-App-Overview-General-Agents-status' && !$scope.visID.includes('Cluster')) {
visualization.searchSource
.setField('query',{ language: discoverList[0].language || 'lucene', query: implicitFilter })
.setField('filter', discoverList.length > 1 ? [...discoverList[1], ...rawFilters] : rawFilters);
} else {
// Checks for cluster.name or cluster.node filter existence
const monitoringFilter = discoverList[1].filter(item => item && item.meta && item.meta.key && (item.meta.key.includes('cluster.name') || item.meta.key.includes('cluster.node')));
// Applying specific filter to cluster monitoring vis
if (Array.isArray(monitoringFilter) && monitoringFilter.length) {
visualization.searchSource.setField('filter',monitoringFilter);
}
2018-07-24 08:49:44 +00:00
}
} catch (error) {
errorHandler.handle(error,'Visualize - setSearchSource');
2018-07-24 08:49:44 +00:00
}
2018-07-24 08:49:44 +00:00
};
const myRender = async raw => {
try {
if(!loader) {
loader = await getVisualizeLoader()
}
const discoverList = discoverPendingUpdates.getList();
if (raw && discoverList.length) { // There are pending updates from the discover (which is the one who owns the true app state)
2018-07-24 08:49:44 +00:00
if(!visualization && !rendered && !renderInProgress) { // There's no visualization object -> create it with proper filters
renderInProgress = true;
2018-07-24 08:49:44 +00:00
const rawVis = raw.filter(item => item && item.id === $scope.visID);
visualization = await wzsavedVisualizations.get($scope.visID,rawVis[0]);
rawFilters = visualization.searchSource.getField('filter');
2018-07-24 08:49:44 +00:00
// Other case, use the pending one, if it is empty, it won't matter
implicitFilter = discoverList ? discoverList[0].query : '';
2018-07-24 08:49:44 +00:00
setSearchSource(discoverList);
visHandler = loader.embedVisualizationWithSavedObject($(`[vis-id="'${$scope.visID}'"]`)[0], visualization, { });
visHandler.update({
timeRange: timefilter.getTime(),
})
2018-07-24 08:49:44 +00:00
visHandlers.addItem(visHandler);
visHandler.addRenderCompleteListener(renderComplete);
} else if (rendered) { // There's a visualization object -> just update its filters
2018-07-24 08:49:44 +00:00
// Use the pending one, if it is empty, it won't matter
implicitFilter = discoverList ? discoverList[0].query : '';
visHandler.update({
timeRange: timefilter.getTime(),
})
2018-07-24 08:49:44 +00:00
setSearchSource(discoverList);
}
2018-01-16 23:17:48 +00:00
}
2018-07-24 08:49:44 +00:00
} catch (error) {
if(error && error.message && error.message.includes('not locate that index-pattern-field')){
errorHandler.handle(`${error.message}, please restart Kibana and refresh this page once done`,'Visualize');
} else {
errorHandler.handle(error,'Visualize');
}
2018-07-24 08:49:44 +00:00
}
2018-07-24 08:49:44 +00:00
return;
};
2018-05-15 14:46:52 +00:00
2018-07-24 08:49:44 +00:00
// Listen for changes
const updateVisWatcher = $rootScope.$on('updateVis', () => {
if(!$rootScope.$$phase) $rootScope.$digest();
const rawVis = rawVisualizations.getList();
if(Array.isArray(rawVis) && rawVis.length){
myRender(rawVis);
}
});
2018-05-15 12:01:26 +00:00
$scope.$on('$destroy',() => {
2018-08-27 14:40:49 +00:00
updateVisWatcher();
try { visualization.destroy(); } catch (error) {} // eslint-disable-line
try { visHandler.destroy(); } catch (error) {} // eslint-disable-line
});
2018-05-15 12:01:26 +00:00
2018-07-24 08:49:44 +00:00
const renderComplete = () => {
rendered = true;
loadedVisualizations.addItem(true);
const currentCompleted = Math.round((loadedVisualizations.getList().length / tabVisualizations.getItem(tabVisualizations.getTab())) * 100);
$rootScope.loadingStatus = `Rendering visualizations... ${currentCompleted > 100 ? 100 : currentCompleted} %`;
if (currentCompleted >= 100) {
2018-07-24 08:49:44 +00:00
if ($scope.visID !== 'Wazuh-App-Overview-General-Agents-status') {
const thereIsData = visHandlers.hasData();
2018-07-24 08:49:44 +00:00
$rootScope.rendered = thereIsData;
if(!thereIsData) $rootScope.resultState = 'none';
else $rootScope.resultState = 'ready';
2018-09-03 09:46:55 +00:00
}
2018-07-24 08:49:44 +00:00
// Forcing a digest cycle
if(!$rootScope.$$phase) $rootScope.$digest();
}
else if ($scope.visID !== 'Wazuh-App-Overview-General-Agents-status') $rootScope.rendered = false;
};
2018-07-24 08:49:44 +00:00
// Initializing the visualization
let loader = null;
}
2018-07-24 08:49:44 +00:00
};
2018-09-03 09:46:55 +00:00
});