/*
* Copyright 2023 Anyware Services
*
* 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.
*/
/**
* <p>This tool displays a tree of statistics
* @private
*/
Ext.define('Ametys.plugins.admin.jvmstatus.StatisticsTool', {
extend: 'Ametys.tool.Tool',
/**
* @private
* @property {Ext.tree.Panel} _tree The statistics tree
*/
getMBSelectionInteraction: function()
{
return Ametys.tool.Tool.MB_TYPE_NOSELECTION;
},
createPanel: function ()
{
this._tree = this._createStatisticsTreePanel();
return this._tree;
},
/**
* Get the tree of the tool
* @return {Ext.tree.Panel} The main tree component of the tool
*/
getTree: function()
{
return this._tree;
},
setParams: function (params)
{
this.callParent(arguments);
this.showOutOfDate();
},
refresh: function ()
{
this.showRefreshing("{{i18n PLUGINS_ADMIN_STATISTICS_TOOL_LOADING}}");
this._tree.getStore().load({node: this._tree.getRootNode(), callback: Ext.bind(function() { this.showRefreshed(); this._tree.getRootNode().expand(); }, this)});
},
/**
* @private
* Draw the tree panel for the statistics
*/
_createStatisticsTreePanel: function()
{
function renderer(value)
{
if (value === null) return '';
if (Ext.isArray(value)) return value.map(renderer).join(', ');
if (Ext.isNumber(value)) return value.toLocaleString();
if (Ext.isBoolean(value)) return '<span class="a-grid-glyph ' + (value === true ? "ametysicon-check34" : "ametysicon-sign-raw-cross") + '" title="' + value + '"></span>';
return "\"" + value + "\"";
}
return Ext.create('Ext.tree.Panel', {
cls:'statistics-tree',
border: false,
scrollable: true,
rootVisible: false,
columns: [{
xtype: 'treecolumn',
text: "{{i18n PLUGINS_ADMIN_STATISTICS_TOOL_COL_NAME}}",
dataIndex: 'label',
width: 300,
sortable: true
}, {
text: "{{i18n PLUGINS_ADMIN_STATISTICS_TOOL_COL_VALUE}}",
dataIndex: 'value',
flex: 1,
sortable: true,
renderer: renderer
}],
// Filter box
dockedItems: [{
dock: 'top',
xtype: 'toolbar',
layout: {
type: 'hbox',
align: 'stretch'
},
border: false,
defaults : {
cls: 'ametys',
labelWidth: 55,
labelSeparator: ''
},
items: [{
// Search input
xtype: 'textfield',
itemId: 'search-filter-input',
cls: 'ametys',
flex: 1,
maxWidth: 300,
emptyText: "{{i18n PLUGINS_ADMIN_STATISTICS_TOOL_FILTER_EMPTYTEXT}}",
enableKeyEvents: true,
msgTarget: 'qtip',
listeners: {change: Ext.Function.createBuffered(this._filterByTitle, 300, this)}
}, {
// Clear filter
tooltip: "{{i18n PLUGINS_ADMIN_STATISTICS_TOOL_FILTER_CLEAR}}",
handler: Ext.bind (this._clearFilter, this),
iconCls: 'a-btn-glyph ametysicon-eraser11 size-16',
cls: 'a-btn-light'
}]
}],
store: Ext.create('Ext.data.TreeStore', {
root: {
text: 'root',
type: 'root',
id: 'root',
expanded: false
},
autoLoad: false,
proxy: {
type: 'ametys',
role: 'org.ametys.runtime.plugins.admin.statistics.StatisticsProviderExtensionPoint',
methodName: 'getStatisticsTree',
methodArguments: [],
reader: {
type: 'json',
rootProperty: 'children'
}
},
sorters: [ { property: 'title', direction: "ASC" }]
})
});
},
/**
* @private
* Filters queries by input field value.
* @param {Ext.form.Field} field The field
*/
_filterByTitle: function (field)
{
var currentSelection = this.getContentPanel().getSelection();
var value = Ext.String.trim(field.getValue());
this.getContentPanel().getStore().clearFilter();
if (value)
{
this._regexFilter = new RegExp(value, 'i');
this.getContentPanel().getStore().filterBy(Ext.bind(this._filterByTextAndChildren, this));
}
if (currentSelection.length > 0)
{
var me = this;
Ext.Array.each(currentSelection, function (sel) {
if (me.getContentPanel().getStore().findExact(me.getContentPanel().getStore().getModel().idProperty, sel.getId()) == -1)
{
// The current selection is not visible, clear the selection
me.getContentPanel().getSelectionModel().deselect([sel]);
}
});
var selection = this.getContentPanel().getSelection();
if (selection.length > 0)
{
this.getContentPanel().ensureVisible(selection[0].getPath());
}
}
},
/**
* @private
* Filter function that check if a node in the tree should be visible or not.
* @param {Ext.data.Model} record The record to check.
* @return {boolean} True if the record should be visible.
*/
_filterByTextAndChildren: function (record)
{
var isVisible = this._regexFilter == null || this._regexFilter.test(record.data.label);
if (!isVisible)
{
// if the record does not match, we check if any child is visible. If at least one is, this record should not be hidden.
// This is efficient because the data is in the store, and is not loaded in the view.
for (var i = 0; !isVisible && i < record.childNodes.length; i++) {
isVisible = this._filterByTextAndChildren(record.childNodes[i]);
}
}
if (isVisible)
{
this.getContentPanel().expandNode(record);
}
return isVisible;
},
/**
* Clear the current filter
*/
_clearFilter: function()
{
this.getContentPanel().down("#search-filter-input").reset();
}
});