let modalConsole = function (config) {
config = config || {};
modalConsole.superclass.constructor.call(this, config);
};
Ext.extend(modalConsole, Ext.Component, {
window: null,
dialog: {},
combo: {},
label: null,
config: {},
keys: [],
current: 0,
result: '',
fileName: '',
init: false,
toggle: function(){
if (!this.window) {
this.window = MODx.load({
xtype: 'modalconsole-window',
url: this.config.connectorUrl
});
if (this.window.getHeight() < 200) {
this.window.setHeight(document.body.clientHeight-55);
}
this.window.el.setRight(-this.window.getWidth()).setTop(55).setVisible(true, false);
}
if (!this.window.isVisible) {
this.window.isVisible = true;
this.window.el.addClass('visible').setOpacity(1, {duration: .7, easing: 'easeIn'})
// this.window.editor.getEl().focus(1000);
} else {
this.window.isVisible = false;
this.window.el.removeClass('visible').setOpacity(0.5, {duration: .7, easing: 'easeIn'}).setRight(-this.window.getWidth());
}
},
});
modalConsole = new modalConsole();
/** ************************************************ **/
let modalConsoleWindow = function (config) {
config = config || {};
Ext.applyIf(config, {
renderTo: 'modx-body-tag',
// renderTo: 'modx-content',
title: _('modalconsole'),
id: 'modalconsole-window',
width: 950,
minHeight: 200,
minWidth: 300,
autoScroll: false,
// closeAction: 'hide',
hideMode: 'display',
isVisible: false,
tools: [],
tbar: [{
xtype: 'button',
id: 'modalconsole-open',
cls: 'toolbar-btn',
text: '',
tooltipType: 'title',
tooltip: _('modalconsole_btn_open'),
disabled: false,
handler: function () {
this.openFile();
},
scope: this
}, {
xtype: 'button',
cls: 'toolbar-btn',
id: 'modalconsole-save',
text: '',
tooltipType: 'title',
tooltip: _('modalconsole_btn_save'),
disabled: false,
handler: function () {
this.saveFile();
},
scope: this
}, {
xtype: 'button',
cls: 'toolbar-btn',
id: 'modalconsole-clear',
text: '',
tooltipType: 'title',
tooltip: _('modalconsole_btn_clear'),
handler: function () {
this.clearContent();
},
scope: this
}, {
xtype: 'tbspacer',
width: 10
}, {
xtype: 'button',
cls: 'toolbar-btn',
id: 'modalconsole-collapse',
text: '',
tooltipType: 'title',
tooltip: _('modalconsole_btn_collapse'),
handler: function() {this.collapsePanel();},
scope: this
}, {
xtype: 'tbspacer',
width: 10
}, {
xtype: 'button',
cls: 'toolbar-btn',
id: 'modalconsole-history-prev',
text: '',
tooltipType: 'title',
tooltip: _('modalconsole_btn_history_prev'),
handler: function() {this.historyPrev();},
disabled: true,
scope: this
}, {
xtype: 'button',
cls: 'toolbar-btn',
id: 'modalconsole-history-next',
text: '',
tooltipType: 'title',
tooltip: _('modalconsole_btn_history_next'),
disabled: true,
handler: function() {this.historyNext();},
scope: this
}, {
xtype: 'button',
cls: 'toolbar-btn',
id: 'modalconsole-history-clear',
text: '',
tooltipType: 'title',
tooltip: _('modalconsole_btn_history_clear'),
disabled: !!modalConsole.keys.length,
handler: function() {this.clearHistory();},
scope: this
}, {
xtype: 'xcheckbox',
boxLabel: _('modalconsole_save_code'),
// boxLabel: 'Сохранить код',
cls: 'toolbar-checkbox',
id: 'modalconsole-save-code',
disabled: !modalConsole.config.limit,
checked: this.initSaveCodeState(),
listeners: {
check: function(o, value) {
this.setSaveCodeState(value);
},
scope: this
}
}, '->', {
xtype: 'xcheckbox',
boxLabel: _('modalconsole_format_code'),
cls: 'toolbar-checkbox',
id: 'modalconsole-format-code',
checked: this.initFormatCodeState(),
listeners: {
check: function(o, value) {
this.resultPanel.update(this.formatCode(modalConsole.result));
this.setFormatCodeState(value);
},
scope: this
}
}],
items: [{
xtype: 'panel',
// hideLabel: true,
id: 'modalconsole-console',
height: 400,
autoWidth: true,
// autoHeight: true,
layout: 'border',
items: [{
region: 'center',
id: 'modalconsole-code',
// autoScroll: true,
// unstyled: true,
bodyStyle: 'background-color:#fff;',
items: [{
xtype: Ext.ComponentMgr.types['modx-texteditor'] ? 'modx-texteditor' : 'textarea',
// xtype: 'textarea',
editor: null,
id: 'modalconsole-editor',
mimeType: 'application/x-php',
height: '100%',
value: this.getHistory(),
enableKeyEvents: true,
listeners: {
keydown: function(editor, e) {
if (e.ctrlKey && Ext.EventObject.getKey() == Ext.EventObject.ENTER) {
this.execute();
} else if (Ext.EventObject.getKey() == Ext.EventObject.ESC) {
modalConsole.toggle();
}
},
scope: this
}
}]
//width: 400
}, {
// title: '',
region: 'east',
id: 'modalconsole-result',
width: 100,
split: true,
collapsible: false,
minSize: 5,
maxSize: 0,
bodyStyle: 'background-color:#fafafa;',
listeners:{
"render": {
fn: function(el){
el.getUpdater().on('update',function(result, response) {
try {
var rObject = JSON.parse(response.responseText);
} catch (Error) {
el.update(response.responseText);
console.warn(Error.message);
return;
}
if (rObject.success) {
modalConsole.result = rObject.output;
const output = this.formatCode(modalConsole.result);
el.update(output);
} else {
MODx.msg.alert(_('error'), rObject.message, Ext.emptyFn);
}
// Если код новый
if (rObject.keys > modalConsole.keys) {
Ext.getCmp('modalconsole-history-next').disable();
modalConsole.keys = rObject.keys;
modalConsole.current = rObject.keys.length - 1;
(rObject.keys.length > 0) ? Ext.getCmp('modalconsole-history-clear').enable() : Ext.getCmp('modalconsole-history-clear').disable();
(rObject.keys.length > 1) ? Ext.getCmp('modalconsole-history-prev').enable() : Ext.getCmp('modalconsole-history-prev').disable();
}
this.parseProfile(rObject);
if (el.collapsed) el.toggleCollapse();
}, this);
}
}
,scope: this
}
}],
listeners:{
"beforerender": {
fn: function(el){
//el.setHeight(this.getHeight()-113);
}
}
,scope: this
}
// height: 550,
}],
buttonAlign: "left",
buttons: [{
xtype: 'modalConsole-profile-label',
id: 'modalconsole-result-queries',
tagTitle: 'SQL queries',
profileName: 'Queries',
initValue: '0'
}, {
xtype: 'modalConsole-profile-label',
id: 'modalconsole-result-time',
tagTitle: 'SQL time / PHP time / Total time',
profileName: 'Time',
initValue: '0 s / 0 s / 0 s'
}, {
xtype: 'modalConsole-profile-label',
id: 'modalconsole-result-memory',
tagTitle: 'Current memory / Memory peak',
profileName: 'Memory',
initValue: '0 MB / 0 MB'
}, '->' , {
text: _("modalconsole_close") ? _("modalconsole_close") : 'Close',
cls: 'modalconsole-window-btn',
handler: function () {modalConsole.toggle();},
scope: this
}, {
text: _("modalconsole_btn_execute") ? _("modalconsole_btn_execute") : 'Execute',
cls: 'modalconsole-window-btn modalconsole-exec-btn',
handler: function () {this.execute();},
tooltipType: 'title',
tooltip: '+',
scope: this
}],
keys: [{
key: Ext.EventObject.ESC,
shift: false,
fn: function () {
modalConsole.toggle();
},
scope: this
}],
// onEsc: modalConsole.toggle,
listeners: {
'maximize': function (w) {
w.el.setTop(55);
},
'hide': function () {
modalConsole.toggle();
},
'render': function(w) {
let el = w.el.select('.x-tool-close').first();
el.on('click', function (e) {
modalConsole.toggle();
});
},
'beforerender': function(w) {
this.codePanel = Ext.getCmp('modalconsole-code');
this.editor = Ext.getCmp('modalconsole-editor');
this.resultPanel = Ext.getCmp('modalconsole-result');
},
'resize': function(o,w,h) {
let p = Ext.getCmp('modalconsole-console');
if (p) {
p.setHeight(h-113);
if (this.editor && this.editor.editor) this.editor.editor.resize();
}
}
}
});
modalConsoleWindow.superclass.constructor.call(this, config);
};
Ext.extend(modalConsoleWindow, MODx.Window, {
init: function(response) {
switch (response.keys.length) {
case 0:
Ext.getCmp('modalconsole-history-clear').disable();
case 1:
Ext.getCmp('modalconsole-history-prev').disable();
break;
default:
Ext.getCmp('modalconsole-history-prev').enable();
modalConsole.keys = response.keys;
modalConsole.current = response.keys.length - 1;
}
/*if (response.keys.length <= 1) {
Ext.getCmp('modalconsole-history-prev').disable();
} else {
Ext.getCmp('modalconsole-history-prev').enable();
modalConsole.keys = response.keys;
modalConsole.current = response.keys.length - 1;
}*/
modalConsole.init = true;
},
getHistory: function(key) {
MODx.Ajax.request({
url: modalConsole.config.connectorUrl,
params: {
action: 'gethistory',
key: key = key || ''
},
listeners: {
success: {
fn: function(response) {
if (response.success) {
if (!modalConsole.init) this.init(response);
this.editor.setValue(response.code);
} else {
this.resultPanel.update(response.message);
}
},
scope: this
},
failure: function(response) {console.log(response);}
}
});
return "= modalConsole.keys.length - 1) {
Ext.getCmp('modalconsole-history-next').disable();
}
this.getHistory(modalConsole.keys[modalConsole.current]);
},
clearHistory: function(){
MODx.Ajax.request({
url: modalConsole.config.connectorUrl,
params: {
action: 'clearhistory'
},
listeners: {
success: {
fn: function(response) {
if (response.success) {
Ext.getCmp('modalconsole-history-prev').disable();
Ext.getCmp('modalconsole-history-next').disable();
Ext.getCmp('modalconsole-history-clear').disable();
modalConsole.keys = [];
modalConsole.current = 0;
// this.editor.setValue("' + output + '' : output;
},
openFile: function() {
if (this.dialog) this.dialog.destroy();
this.dialog = MODx.load({
xtype: 'modalconsole-openfile-dialog',
// id: Ext.id(),
listeners: {
success: {
fn: function (response) {
if (response.a.result.success) {
const code = response.a.result.message ? response.a.result.message : '{value}{tag}>'
.replace('{profileName}', this.profileName)
.replace(/{tag}/g, this.tag)
.replace('{class}', this.tagCls)
.replace('{title}', this.tagTitle)
.replace('{value}', value);
return this;
}
});
Ext.reg('modalConsole-profile-label', modalConsole.label);
// Open File Dialog
modalConsole.dialog.OpenFile = function (config) {
config = config || {};
if (!config.id) {
config.id = 'modalconsole-openfile-dialog';
}
Ext.applyIf(config, {
title: _('modalconsole_file'),
width: 400,
modal: true,
url: modalConsole.config.connectorUrl,
action: 'loadfile',
fields: [{
xtype: 'modalconsole-combo-files',
name: 'file',
emptyText: _('modalconsole_select_file'),
anchor: '100%'
}],
keys: [{
key: Ext.EventObject.ENTER, shift: true, fn: function () {
let fileName = Ext.getCmp('modalconsole-combo-files').getValue();
modalConsole.fileName = fileName.replace(/\.php$/i, '');
this.submit()
}, scope: this
}],
buttons: [{
text: _('modalconsole_btn_open'),
id: config.id + '-load-btn',
handler: function () {
let fileName = Ext.getCmp('modalconsole-combo-files').getValue();
modalConsole.fileName = fileName.replace(/\.php$/i, '');
this.submit();
},
scope: this
}, {
text: _('close'),
id: config.id + '-close-btn',
handler: function () {
this.hide();
},
scope: this
}]
});
modalConsole.dialog.OpenFile.superclass.constructor.call(this, config);
};
Ext.extend(modalConsole.dialog.OpenFile, MODx.Window);
Ext.reg('modalconsole-openfile-dialog', modalConsole.dialog.OpenFile);
modalConsole.combo.Files = function(config) {
config = config || {};
Ext.applyIf(config,{
id: 'modalconsole-combo-files',
hideMode: 'offsets',
autoScroll: true,
maxHeight: 200,
displayField: 'filename',
valueField: 'filename',
fields: ['filename'],
hiddenName: 'file',
editable: false,
url: modalConsole.config.connectorUrl,
baseParams: {
action: 'getfiles'
},
store: new Ext.data.JsonStore({
url: modalConsole.config.connectorUrl,
root: 'results',
totalProperty: 'total',
fields: ['filename'],
errorReader: MODx.util.JSONReader,
baseParams: {
action: 'getfiles'
},
remoteSort: config.remoteSort || false,
autoDestroy: true,
listeners: {
'loadexception': {
fn: function(o, trans, resp) {
const status = JSON.parse(resp.responseText);
MODx.msg.alert(_('error'), status.message, Ext.emptyFn);
}}
}
})
});
modalConsole.combo.Files.superclass.constructor.call(this, config);
};
Ext.extend(modalConsole.combo.Files, MODx.combo.ComboBox);
Ext.reg('modalconsole-combo-files', modalConsole.combo.Files);
/** ***************************************************/
Ext.onReady(function() {
let usermenuUl = document.getElementById("modx-user-menu"),
firstLi = usermenuUl.firstChild,
modalconsoleLi = document.createElement("LI"),
title = _('modalconsole_open_console');
modalconsoleLi.id = "modalconsole-li";
modalconsoleLi.innerHTML = "";
usermenuUl.insertBefore(modalconsoleLi, firstLi);
});