/*
* Copyright 2024 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.
*/
/**
* This tool is a tool to run solr queries
*/
Ext.define('Ametys.plugins.cms.solrtool.SolrQueryTool', {
extend: 'Ametys.tool.Tool',
/**
* @private
* @property {Ametys.form.field.SolrCode} scriptEditor The codemirror editor for Solr
*/
/**
* @private
* @property {Ext.Component} results The panel containing the results
*/
defaultSolrCore: 'default',
createPanel: function()
{
this.queryEditor = Ext.create('Ametys.form.field.Code', {
mode: {name: "javascript", jsonld: true},
stateful: true,
stateId: this.getId() + "$code",
cmParams: {
foldcode: true,
foldGutter: true,
lineWrapping:true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
}
})
this.leftPanel = Ext.create("Ext.panel.Panel", {
stateful: true,
stateId: this.getId() + "$leftPanel",
layout: 'fit',
split: true,
minWidth:100,
flex:0.5,
items: [ this.queryEditor ],
dockedItems: this._createTopToolBar()
})
this.results = Ext.create("Ext.Component", {
stateId: this.self.getName() + "$results",
stateful: true,
scrollable: true,
html: "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_RESULT_DEFAULT_LABEL}}",
minWidth:100,
flex:0.5,
split: true
})
return Ext.create("Ext.container.Container", {
stateful: true,
stateId: this.self.getName() + "$container",
layout: {
type: 'hbox',
align: 'stretch'
},
cls: 'uitool-solr-query',
items: [ this.leftPanel, this.results ]
})
},
/**
* @protected
* Get the top panel for choosing solr code and actions
* @return {Ext.toolbar.Toolbar} the top toolbar
*/
_createTopToolBar: function ()
{
return Ext.create({
dock: 'top',
xtype: 'toolbar',
layout: {
type: 'hbox',
align: 'stretch'
},
cls: 'top',
items: [
this._getSolrCoresComboBox(),
{
xtype: 'tbspacer',
flex: 0.0001
},
{
// Format
xtype: 'button',
iconCls: 'ametysicon-code-misc-lang-script',
tooltip: "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_PRETTIFY_LABEL}}",
handler: this._formatCode,
scope: this,
cls: 'a-btn-light',
}
]
});
},
/**
* @private
* Get configuration for sorl cores combo box
* @return {Object} the configuration object
*/
_getSolrCoresComboBox: function ()
{
this._coreStore = Ext.create('Ext.data.Store', {
proxy: {
type: 'ametys',
role: 'org.ametys.cms.solr.SolrQueryHandler',
methodName: 'getSolrCoreNames',
methodArguments: [],
},
fields: ['name'],
autoLoad: true,
listeners: {
load: {fn: this._onLoadCores, scope: this},
}
});
this.solrCoreCombo = Ext.create("Ext.form.ComboBox", {
xtype: 'combobox',
itemId: 'cores-combo',
cls: 'ametys',
forceSelection: true,
editable: false,
queryMode: 'local',
allowBlank:false,
store: this._coreStore,
hidden:false,
valueField: 'name',
displayField: 'name',
labelSeparator: '',
fieldLabel: "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_SOLR_CORE_LABEL}}",
maxWidth: 200,
labelWidth:40,
labelAlign: "left",
flex:1
})
return this.solrCoreCombo
},
/**
* Listener called after load form display core combo box
* @param {Object} store The store
* @param {Object[]} data The data
* @private
*/
_onLoadCores: function(store, data)
{
this.solrCoreCombo.setValue(this.defaultSolrCore);
},
/**
* Get the name of current solr core
* @return {String} the current solr core's name
*/
getCurrentSolrCoreName: function ()
{
return this.solrCoreCombo.getValue();
},
getMBSelectionInteraction: function()
{
return Ametys.tool.Tool.MB_TYPE_NOSELECTION;
},
getType: function()
{
return Ametys.tool.Tool.SOLR_QUERY;
},
/**
* Handles the response
* @param {String} result The result of the Solr Query.
*/
updateResult: function(result)
{
var id = Ext.id();
var html = "<div id='" + id + "'>";
if (!Ext.isEmpty(result.result))
{
html += Ext.JSON.prettyEncode( Ext.JSON.decode(result.result || null)); // Encode/decode to ensure the json object reflect the sent one (e.g. eliminate "undefined" values)
}
if (Ext.isEmpty(result.result) && Ext.isEmpty(result.errorMessage))
{
html += "<div class='no-result'>{{i18n plugin.core-ui:PLUGINS_CORE_UI_TOOLS_SCRIPT_RESULTS_NO_RESULT}}</div>";
}
if (!Ext.isEmpty(result.errorMessage))
{
html += '<div class="fatalerror">' + result.errorMessage;
if (!Ext.isEmpty(result.errorStackTrace))
{
html += "<br/><a href='javascript:void(0)' onclick='this.nextSibling.style.display = (this.nextSibling.style.display == \"none\" ? \"\" : \"none\")'>{{i18n plugin.core-ui:PLUGINS_CORE_UI_TOOLS_SCRIPT_ERROR_DETAILS}}</a>"
+ "<div class='stacktrace' style='display: none'>" + Ext.String.stacktraceJavaToHTML(result.errorStackTrace) + "</div>"
}
html += '</div>';
}
html += '</div>';
this.results.update(html);
},
/**
* @private
* Format the code in the editor
*/
_formatCode: function ()
{
if (this.queryEditor.getValue())
{
try
{
var resultAsPrettyJson = this._formatJsonCode();
this.queryEditor.setValue(resultAsPrettyJson);
}
catch (e)
{
Ametys.log.ErrorDialog.display({
title: "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_PRETTIFY_ERROR_LABEL}}",
text: "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_PRETTIFY_ERROR_DESC}} : <br/>" + e.message,
category: this.self.getName()
});
}
}
},
/**
* @private
* Format the code in the editor
*/
getQuery: function ()
{
var value = this.queryEditor.getValue();
if (value)
{
try
{
this._formatJsonCode();
return this.queryEditor.getValue();
}
catch (e)
{
var result = {}
result.errorMessage = "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_MALFORMED_QUERY_ERROR_DESC}} : <br/>" + e.message;
this.updateResult(result);
return null;
}
}
else
{
var result = {}
result.errorMessage = "{{i18n PLUGINS_CMS_SOLR_QUERY_TOOL_NO_QUERY_ERROR_DESC}}";
this.updateResult(result);
return null;
}
},
_formatJsonCode: function()
{
return JSON.stringify(JSON.parse(this.queryEditor.getValue()), undefined, 4);
}
})