From e25a7f58990e58ef905c9d49ad23338206c48e5b Mon Sep 17 00:00:00 2001 From: Peter Donker Date: Tue, 29 Mar 2022 22:58:01 +0200 Subject: [PATCH] Fixes relative path issues in loading monaco editor --- .../scripts/ConfigConsole.js | 570 +++---- .../Dnn.SqlConsole/scripts/SqlConsole.js | 1512 +++++++++-------- 2 files changed, 1043 insertions(+), 1039 deletions(-) diff --git a/Dnn.AdminExperience/Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.ConfigConsole/scripts/ConfigConsole.js b/Dnn.AdminExperience/Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.ConfigConsole/scripts/ConfigConsole.js index 60bf95c83d7..5e24e930989 100644 --- a/Dnn.AdminExperience/Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.ConfigConsole/scripts/ConfigConsole.js +++ b/Dnn.AdminExperience/Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.ConfigConsole/scripts/ConfigConsole.js @@ -7,314 +7,316 @@ 'use strict'; define(['jquery', - 'knockout', - 'knockout.mapping', - 'jquery-ui.min', - 'main/config', - 'jquery.easydropdown.min', - 'dnn.jquery', - 'main/koBindingHandlers/jScrollPane'], - function ($, ko, koMapping, jqueryUI, cf) { - var config = cf.init(); - - var utility, $panel, viewModel, monacoConfigFilesEditor, configFilesEditor, configFilesModel, configFilesContent, monacoMergeScriptsEditor, mergeScriptsEditor, mergeScriptsModel, mergeScriptsContent, curConfigName; - - var requestService = function (type, method, params, callback, failure) { - utility.sf.moduleRoot = "personaBar"; - utility.sf.controller = "ConfigConsole"; - - utility.sf[type].call(utility.sf, method, params, callback, failure); + 'knockout', + 'knockout.mapping', + 'jquery-ui.min', + 'main/config', + 'jquery.easydropdown.min', + 'dnn.jquery', + 'main/koBindingHandlers/jScrollPane'], + function ($, ko, koMapping, jqueryUI, cf) { + var config = cf.init(); + + var utility, $panel, viewModel, monacoConfigFilesEditor, configFilesEditor, configFilesModel, configFilesContent, monacoMergeScriptsEditor, mergeScriptsEditor, mergeScriptsModel, mergeScriptsContent, curConfigName; + + var requestService = function (type, method, params, callback, failure) { + utility.sf.moduleRoot = "personaBar"; + utility.sf.controller = "ConfigConsole"; + + utility.sf[type].call(utility.sf, method, params, callback, failure); + } + + var getConfigs = function () { + requestService('get', 'GetConfigFilesList', {}, function (data) { + // add the caption as first option + data.Results.unshift(viewModel.resx.plConfigHelp); + + viewModel.configs(data.Results); + + $('.configConsolePanel select').easyDropDown({ wrapperClass: 'pb-dropdown', cutOff: 10, inFocus: true }); + }, function () { + // failed + utility.notifyError('Failed...'); + }); + } + + var getConfigFile = function () { + if (curConfigName === viewModel.resx.plConfigHelp) { + // it's the caption, so empty the editor + configFilesContent.setValue(''); + } else { + requestService('get', 'GetConfigFile', { 'fileName': curConfigName }, function (data) { + if (curConfigName.endsWith("config")) { + configFilesEditor.setModelLanguage(configFilesModel, "xml"); + } + else if (curConfigName.endsWith("txt")) { + configFilesEditor.setModelLanguage(configFilesModel, "plain/text"); + } + configFilesContent.setValue(data.FileContent); + }, function () { + // failed + utility.notifyError('Failed...'); + }); + } + } + + var saveConfigFile = function () { + utility.confirm( + utility.resx.ConfigConsole.SaveConfirm, + utility.resx.ConfigConsole.SaveButton, + utility.resx.ConfigConsole.CancelButton, + function () { + validate({ + 'fileName': curConfigName, + 'fileContent': configFilesContent.getValue() + }); } - - var getConfigs = function () { - requestService('get', 'GetConfigFilesList', {}, function (data) { - // add the caption as first option - data.Results.unshift(viewModel.resx.plConfigHelp); - - viewModel.configs(data.Results); - - $('.configConsolePanel select').easyDropDown({ wrapperClass: 'pb-dropdown', cutOff: 10, inFocus: true }); - }, function () { - // failed - utility.notifyError('Failed...'); - }); + ); + } + + var validate = function (configFile) { + var callback = function (data) { + if (data && data.ValidationErrors && data.ValidationErrors.length) { + confirmValidationErrors(data.ValidationErrors, configFile); + } else { + update(configFile); } + }; - var getConfigFile = function () { - if (curConfigName === viewModel.resx.plConfigHelp) { - // it's the caption, so empty the editor - configFilesContent.setValue(''); - } else { - requestService('get', 'GetConfigFile', { 'fileName': curConfigName }, function (data) { - if (curConfigName.endsWith("config")) { - configFilesEditor.setModelLanguage(configFilesModel, "xml"); - } - else if (curConfigName.endsWith("txt")) { - configFilesEditor.setModelLanguage(configFilesModel, "plain/text"); - } - configFilesContent.setValue(data.FileContent); - }, function () { - // failed - utility.notifyError('Failed...'); - }); - } - } + requestService('post', 'ValidateConfigFile', configFile, callback, fail); + } - var saveConfigFile = function () { - utility.confirm( - utility.resx.ConfigConsole.SaveConfirm, - utility.resx.ConfigConsole.SaveButton, - utility.resx.ConfigConsole.CancelButton, - function () { - validate({ - 'fileName': curConfigName, - 'fileContent': configFilesContent.getValue() - }); - } - ); - } + var confirmValidationErrors = function (validationErrors, configFile) { + const BR = '
'; + const TOP = 5; - var validate = function(configFile) { - var callback = function(data) { - if (data && data.ValidationErrors && data.ValidationErrors.length) { - confirmValidationErrors(data.ValidationErrors, configFile); - } else { - update(configFile); - } - }; + var question = utility.resx.ConfigConsole.ValidationErrorsConfirm.replace('{0}', BR); - requestService('post', 'ValidateConfigFile', configFile, callback, fail); - } + // remove duplicates and take top N + var errors = validationErrors + .filter((value, index, self) => self.indexOf(value) === index) + .slice(0, TOP) + .concat(validationErrors.length > TOP ? ['...'] : []); - var confirmValidationErrors = function(validationErrors, configFile) { - const BR = '
'; - const TOP = 5; - - var question = utility.resx.ConfigConsole.ValidationErrorsConfirm.replace('{0}', BR); - - // remove duplicates and take top N - var errors = validationErrors - .filter((value, index, self) => self.indexOf(value) === index) - .slice(0, TOP) - .concat(validationErrors.length > TOP ? ['...'] : []); - - utility.confirm( - question + BR + BR + errors.join(BR), - utility.resx.ConfigConsole.SaveButton, - utility.resx.ConfigConsole.CancelButton, - function () { - update(configFile); - } - ); + utility.confirm( + question + BR + BR + errors.join(BR), + utility.resx.ConfigConsole.SaveButton, + utility.resx.ConfigConsole.CancelButton, + function () { + update(configFile); } - - var update = function(configFile) { - requestService('post', 'UpdateConfigFile', configFile, succeed, fail); + ); + } + + var update = function (configFile) { + requestService('post', 'UpdateConfigFile', configFile, succeed, fail); + } + + var succeed = () => { + utility.notify(utility.resx.ConfigConsole.Success); + } + + var fail = () => { + utility.notifyError(utility.resx.ConfigConsole.ERROR_ConfigurationFormat); + } + + var mergeConfigFile = function () { + var confirmText = utility.resx.ConfigConsole.MergeConfirm; + if (curConfigName != null && curConfigName == 'web.config') { + confirmText = utility.resx.ConfigConsole.SaveWarning; + } + utility.confirm(confirmText, utility.resx.ConfigConsole.SaveButton, utility.resx.ConfigConsole.CancelButton, function () { + requestService('post', 'MergeConfigFile', { 'fileName': '', 'fileContent': mergeScriptsContent.getValue() }, function (data) { + utility.notify(utility.resx.ConfigConsole.Success); + }, function () { + // failed + utility.notifyError(utility.resx.ConfigConsole.ERROR_Merge); + }); + }); + } + + var initViewModel = function () { + viewModel = { + resx: utility.resx.ConfigConsole, + configxml: ko.observable(''), + mergexml: ko.observable(''), + saveConfig: saveConfigFile, + mergeConfig: mergeConfigFile, + configs: ko.observableArray([]), + config: ko.observable('') + }; + } + + var configSelectionChanged = function (data) { + if (data != null && data != curConfigName) { + curConfigName = data; + getConfigFile(); + } + } + + var initUpload = function () { + var $uploadContainer = $panel.find('.fileupload-wrapper'); + var $uploadControl = $uploadContainer.find('input'); + + if (typeof FileReader === "undefined") { + $uploadContainer.hide(); + return; + } + + $uploadControl.on('change', function (e) { + var file = $uploadControl[0].files[0]; + var textType = /text|xml.*/; + + if (file.type.match(textType) || file.name.toLowerCase().split('.').pop() === 'config') { + var reader = new FileReader(); + + reader.onload = function (e) { + mergeScriptsContent.setValue(reader.result); + } + + reader.readAsText(file); + } else { + utility.notifyError('File not supported'); } + }); + } - var succeed = () => { - utility.notify(utility.resx.ConfigConsole.Success); - } - - var fail = () => { - utility.notifyError(utility.resx.ConfigConsole.ERROR_ConfigurationFormat); - } - - var mergeConfigFile = function () { - var confirmText = utility.resx.ConfigConsole.MergeConfirm; - if (curConfigName != null && curConfigName == 'web.config') { - confirmText = utility.resx.ConfigConsole.SaveWarning; - } - utility.confirm(confirmText, utility.resx.ConfigConsole.SaveButton, utility.resx.ConfigConsole.CancelButton, function () { - requestService('post', 'MergeConfigFile', { 'fileName': '', 'fileContent': mergeScriptsContent.getValue() }, function (data) { - utility.notify(utility.resx.ConfigConsole.Success); - }, function () { - // failed - utility.notifyError(utility.resx.ConfigConsole.ERROR_Merge); - }); - }); - } - - var initViewModel = function () { - viewModel = { - resx: utility.resx.ConfigConsole, - configxml: ko.observable(''), - mergexml: ko.observable(''), - saveConfig: saveConfigFile, - mergeConfig: mergeConfigFile, - configs: ko.observableArray([]), - config: ko.observable('') - }; - } - - var configSelectionChanged = function (data) { - if (data != null && data != curConfigName) { - curConfigName = data; - getConfigFile(); - } - } - - var initUpload = function () { - var $uploadContainer = $panel.find('.fileupload-wrapper'); - var $uploadControl = $uploadContainer.find('input'); - - if (typeof FileReader === "undefined") { - $uploadContainer.hide(); - return; - } - - $uploadControl.on('change', function (e) { - var file = $uploadControl[0].files[0]; - var textType = /text|xml.*/; - - if (file.type.match(textType) || file.name.toLowerCase().split('.').pop() === 'config') { - var reader = new FileReader(); + var init = function (wrapper, util, params, callback) { + utility = util; + $panel = wrapper; - reader.onload = function (e) { - mergeScriptsContent.setValue(reader.result); - } + initViewModel(); - reader.readAsText(file); - } else { - utility.notifyError('File not supported'); - } - }); - } + ko.applyBindings(viewModel, $panel[0]); - var init = function (wrapper, util, params, callback) { - utility = util; - $panel = wrapper; + curConfigName = config.portalId; - initViewModel(); + getConfigs(); - ko.applyBindings(viewModel, $panel[0]); + initConfigConsole(); - curConfigName = config.portalId; + initUpload(); - getConfigs(); + $('.configConsolePanel .body').dnnTabs({ selected: 0, activate: initTabsClickEvent() }); + setEditorHeight(); - initConfigConsole(); + if (typeof callback === 'function') { + callback(); + } + }; - initUpload(); + var initTabsClickEvent = function () { + const tabs = document.querySelectorAll('.configConsolePanel .tabs-nav li'); + tabs.forEach(tab => { + tab.addEventListener('click', setEditorHeight); + }); + } - $('.configConsolePanel .body').dnnTabs({ selected: 0, activate: initTabsClickEvent() }); - setEditorHeight(); + var setEditorHeight = function () { + setTimeout(() => { + var panelHeight = $('#ConfigConsole-panel').height(); + if (panelHeight > 400) { - if (typeof callback === 'function') { - callback(); - } - }; + if (document.querySelector('#configConsole-files').style.display !== 'none') { + $('#monaco-editor-config-files').height(panelHeight - 400); + } - var initTabsClickEvent = function() { - const tabs = document.querySelectorAll('.configConsolePanel .tabs-nav li'); - tabs.forEach(tab => { - tab.addEventListener('click', setEditorHeight); - }); + if (document.querySelector('#configConsole-merge').style.display !== 'none') { + $('#monaco-editor-merge-scripts').height(panelHeight - 400); + } } - - var setEditorHeight = function() { - setTimeout(() => { - var panelHeight = $('#ConfigConsole-panel').height(); - if (panelHeight > 400) { - - if(document.querySelector('#configConsole-files').style.display !== 'none') { - $('#monaco-editor-config-files').height(panelHeight - 400); - } - - if(document.querySelector('#configConsole-merge').style.display !== 'none') { - $('#monaco-editor-merge-scripts').height(panelHeight - 400); - } - } - }, 300); - } - - var initConfigConsole = function() { - var monacoEditorLoaderScript = document.createElement('script'); - monacoEditorLoaderScript.type = 'text/javascript'; - monacoEditorLoaderScript.src = '/Resources/Shared/components/MonacoEditor/loader.js'; - document.body.appendChild(monacoEditorLoaderScript); - - require.config({ paths: { 'vs': '/Resources/Shared/components/MonacoEditor' }}); - require(['vs/editor/editor.main'], function(monaco) { - - self.MonacoEnvironment = { - getWorkerUrl: function (moduleId, label) { - if (label === 'typescript' || label === 'javascript') { - return `data:text/javascript;charset=utf-8,${encodeURIComponent(` + }, 300); + } + + var initConfigConsole = function () { + let siteRoot = dnn.getVar("sf_siteRoot"); + if (!siteRoot) siteRoot = '/'; + var monacoEditorLoaderScript = document.createElement('script'); + monacoEditorLoaderScript.type = 'text/javascript'; + monacoEditorLoaderScript.src = siteRoot + 'Resources/Shared/components/MonacoEditor/loader.js'; + document.body.appendChild(monacoEditorLoaderScript); + + require.config({ paths: { 'vs': siteRoot + 'Resources/Shared/components/MonacoEditor' } }); + require(['vs/editor/editor.main'], function (monaco) { + + self.MonacoEnvironment = { + getWorkerUrl: function (moduleId, label) { + if (label === 'typescript' || label === 'javascript') { + return `data:text/javascript;charset=utf-8,${encodeURIComponent(` importScripts('${process.env.ASSET_PATH}/typescript.worker.js');` - )}`; - } - - return `data:text/javascript;charset=utf-8,${encodeURIComponent(` - importScripts('${process.env.ASSET_PATH}/editor.worker.js');` - )}`; - } - } - - configFilesEditor = monaco.editor; - mergeScriptsEditor = monaco.editor; - - configFilesContent = configFilesEditor.createModel("", "xml"); - mergeScriptsContent = mergeScriptsEditor.createModel("", "xml"); - - initMonacoEditors(); - - configFilesModel = monacoConfigFilesEditor.getModel(); - mergeScriptsModel = monacoMergeScriptsEditor.getModel(); - - viewModel.config.subscribe(configSelectionChanged); - }); - - } - - var initMonacoEditors = function() { - var theme = "vs-light"; - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - theme = "vs-dark"; + )}`; } - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { - theme = e.matches ? "vs-dark" : "vs-light"; - }); - - monacoConfigFilesEditor = configFilesEditor.create(document.getElementById("monaco-editor-config-files"), { - model: configFilesContent, - language: "xml", - wordWrap: 'wordWrapColumn', - wordWrapColumn: 80, - wordWrapMinified: true, - wrappingIndent: "indent", - lineNumbers: "on", - roundedSelection: false, - scrollBeyondLastLine: false, - readOnly: false, - theme: theme, - automaticLayout: true - }); - - monacoMergeScriptsEditor = mergeScriptsEditor.create(document.getElementById("monaco-editor-merge-scripts"), { - model: mergeScriptsContent, - language: "xml", - wordWrap: 'wordWrapColumn', - wordWrapColumn: 80, - wordWrapMinified: true, - wrappingIndent: "indent", - lineNumbers: "on", - roundedSelection: false, - scrollBeyondLastLine: false, - readOnly: false, - theme: theme, - automaticLayout: true - }); - } - var load = function (params, callback) { - if (typeof callback === 'function') { - callback(); - } - }; + return `data:text/javascript;charset=utf-8,${encodeURIComponent(` + importScripts('${process.env.ASSET_PATH}/editor.worker.js');` + )}`; + } + } - return { - init: init, - load: load - }; - }); + configFilesEditor = monaco.editor; + mergeScriptsEditor = monaco.editor; + + configFilesContent = configFilesEditor.createModel("", "xml"); + mergeScriptsContent = mergeScriptsEditor.createModel("", "xml"); + + initMonacoEditors(); + + configFilesModel = monacoConfigFilesEditor.getModel(); + mergeScriptsModel = monacoMergeScriptsEditor.getModel(); + + viewModel.config.subscribe(configSelectionChanged); + }); + + } + + var initMonacoEditors = function () { + var theme = "vs-light"; + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + theme = "vs-dark"; + } + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { + theme = e.matches ? "vs-dark" : "vs-light"; + }); + + monacoConfigFilesEditor = configFilesEditor.create(document.getElementById("monaco-editor-config-files"), { + model: configFilesContent, + language: "xml", + wordWrap: 'wordWrapColumn', + wordWrapColumn: 80, + wordWrapMinified: true, + wrappingIndent: "indent", + lineNumbers: "on", + roundedSelection: false, + scrollBeyondLastLine: false, + readOnly: false, + theme: theme, + automaticLayout: true + }); + + monacoMergeScriptsEditor = mergeScriptsEditor.create(document.getElementById("monaco-editor-merge-scripts"), { + model: mergeScriptsContent, + language: "xml", + wordWrap: 'wordWrapColumn', + wordWrapColumn: 80, + wordWrapMinified: true, + wrappingIndent: "indent", + lineNumbers: "on", + roundedSelection: false, + scrollBeyondLastLine: false, + readOnly: false, + theme: theme, + automaticLayout: true + }); + } + + var load = function (params, callback) { + if (typeof callback === 'function') { + callback(); + } + }; + + return { + init: init, + load: load + }; + }); diff --git a/Dnn.AdminExperience/Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.SqlConsole/scripts/SqlConsole.js b/Dnn.AdminExperience/Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.SqlConsole/scripts/SqlConsole.js index 3995f2cd3e8..e6fddc34116 100644 --- a/Dnn.AdminExperience/Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.SqlConsole/scripts/SqlConsole.js +++ b/Dnn.AdminExperience/Dnn.PersonaBar.Extensions/admin/personaBar/Dnn.SqlConsole/scripts/SqlConsole.js @@ -5,803 +5,805 @@ * Module responsible to Sql Console */ define(['jquery', - 'knockout', - 'knockout.mapping', - './sort', - './exportData', - './clipboard.min', - './html2canvas', - './FileSaver.min', - 'dnn.jquery', - 'main/koBindingHandlers/jScrollPane'], - function ($, ko, koMapping, sort, exportData, Clipboard) { - 'use strict'; - - var utility, resx, $panel, viewModel, sqlConsole, sqlContent, jsPdf; - - var pagesCount = 7; - - var requestService = function (type, method, params, callback, error) { - utility.sf.moduleRoot = "personaBar"; - utility.sf.controller = "SqlConsole"; - - utility.sf[type].call(utility.sf, method, params, callback, error); - } - - var getSavedQueries = function (selectedId) { - requestService('get', 'GetSavedQueries', {}, function (data) { - viewModel.connections(data.connections); - viewModel.connection(data.connections[0]); - - var newQuery = { - id: -1, - name: resx.NewQuery, - connection: viewModel.connection(), - query: '' - }; - - viewModel.savedQueries.removeAll(); - viewModel.savedQueries.push(newQuery); - for (var i = 0; i < data.queries.length; i++) { - viewModel.savedQueries.push(data.queries[i]); - } - - viewModel.selectedQuery(selectedId); + 'knockout', + 'knockout.mapping', + './sort', + './exportData', + './clipboard.min', + './html2canvas', + './FileSaver.min', + 'dnn.jquery', + 'main/koBindingHandlers/jScrollPane'], + function ($, ko, koMapping, sort, exportData, Clipboard) { + 'use strict'; + + var utility, resx, $panel, viewModel, sqlConsole, sqlContent, jsPdf; + + var pagesCount = 7; + + var requestService = function (type, method, params, callback, error) { + utility.sf.moduleRoot = "personaBar"; + utility.sf.controller = "SqlConsole"; + + utility.sf[type].call(utility.sf, method, params, callback, error); + } + + var getSavedQueries = function (selectedId) { + requestService('get', 'GetSavedQueries', {}, function (data) { + viewModel.connections(data.connections); + viewModel.connection(data.connections[0]); + + var newQuery = { + id: -1, + name: resx.NewQuery, + connection: viewModel.connection(), + query: '' + }; - if (!viewModel.name()) { - viewModel.name(newQuery.name); - } - }); + viewModel.savedQueries.removeAll(); + viewModel.savedQueries.push(newQuery); + for (var i = 0; i < data.queries.length; i++) { + viewModel.savedQueries.push(data.queries[i]); } - var initUpload = function () { - var $uploadContainer = $panel.find('.fileupload-wrapper'); - var $uploadControl = $uploadContainer.find('input'); - - if (typeof FileReader === "undefined") { - $uploadContainer.hide(); - return; - } - - $uploadControl.on('change', function (e) { - var file = $uploadControl[0].files[0]; - var textType = /text.*/; - if (file.type.match(textType) || file.name.toLowerCase().split('.').pop() === 'sql') { - var reader = new FileReader(); - - reader.onload = function (e) { - viewModel.query(reader.result); - } + viewModel.selectedQuery(selectedId); - reader.readAsText(file); - } else { - utility.notifyError('File not supported'); - } - - $uploadControl.val(''); - }); + if (!viewModel.name()) { + viewModel.name(newQuery.name); } - - var changeTab = function (data) { - var index = data.index; - - $panel.find('.tables-container > div').hide(); - $panel.find('.tables-container > div#result' + index).show(); - var $tableContainer = $panel.find('.tables-container > div#result' + index).find('> div.table-container'); - if ($tableContainer.data('jsp')) { - $tableContainer.data('jsp').destroy(); - $tableContainer = $panel.find('.tables-container > div#result' + index).find('> div.table-container'); - } - $tableContainer.jScrollPane(); - - $panel.find('.result-tabs ul li').removeClass('selected').eq(index).addClass('selected'); + }); + } + + var initUpload = function () { + var $uploadContainer = $panel.find('.fileupload-wrapper'); + var $uploadControl = $uploadContainer.find('input'); + + if (typeof FileReader === "undefined") { + $uploadContainer.hide(); + return; + } + + $uploadControl.on('change', function (e) { + var file = $uploadControl[0].files[0]; + var textType = /text.*/; + if (file.type.match(textType) || file.name.toLowerCase().split('.').pop() === 'sql') { + var reader = new FileReader(); + + reader.onload = function (e) { + viewModel.query(reader.result); + } + + reader.readAsText(file); + } else { + utility.notifyError('File not supported'); } - var scrollPaneInitialised = function (table, e) { - var $table = $panel.find('.tables-container > div#result' + table.index).find('table'); - if (!$table.attr('width') || $table.attr('width') === '0') { - $table.attr('width', $table.width()); - } + $uploadControl.val(''); + }); + } + + var changeTab = function (data) { + var index = data.index; + + $panel.find('.tables-container > div').hide(); + $panel.find('.tables-container > div#result' + index).show(); + var $tableContainer = $panel.find('.tables-container > div#result' + index).find('> div.table-container'); + if ($tableContainer.data('jsp')) { + $tableContainer.data('jsp').destroy(); + $tableContainer = $panel.find('.tables-container > div#result' + index).find('> div.table-container'); + } + $tableContainer.jScrollPane(); + + $panel.find('.result-tabs ul li').removeClass('selected').eq(index).addClass('selected'); + } + + var scrollPaneInitialised = function (table, e) { + var $table = $panel.find('.tables-container > div#result' + table.index).find('table'); + if (!$table.attr('width') || $table.attr('width') === '0') { + $table.attr('width', $table.width()); + } + } + + var savedQueryChanged = function (val) { + var id = viewModel.selectedQuery(); + var query; + var savedQueries = viewModel.savedQueries(); + for (var i = 0; i < savedQueries.length; i++) { + if (savedQueries[i].id === id) { + query = savedQueries[i]; + break; } - - var savedQueryChanged = function (val) { - var id = viewModel.selectedQuery(); - var query; - var savedQueries = viewModel.savedQueries(); - for (var i = 0; i < savedQueries.length; i++) { - if (savedQueries[i].id === id) { - query = savedQueries[i]; - break; - } - } - - if (!query || !query.name) { - return; - } - - viewModel.query(query.query || ''); - viewModel.name(query.name); - viewModel.connection(query.connection); - viewModel.id(query.id || -1); + } + + if (!query || !query.name) { + return; + } + + viewModel.query(query.query || ''); + viewModel.name(query.name); + viewModel.connection(query.connection); + viewModel.id(query.id || -1); + } + + var startSaveQuery = function () { + viewModel.query(sqlContent.getValue()); + + if (!viewModel.query()) { + return; + } + + viewModel.saving(true); + + if (viewModel.id() <= 0) { + viewModel.name(''); + } + + $('#query-name').focus(); + } + + var saveQuery = function () { + viewModel.query(sqlContent.getValue()); + + if (!viewModel.query()) { + return; + } + + if (!viewModel.name()) { + utility.notify(resx.EmptyName); + return; + } + + var query = { + id: viewModel.id(), + name: viewModel.name(), + query: viewModel.query(), + connection: viewModel.connection() + } + + viewModel.loading(true); + + requestService('post', 'SaveQuery', query, function (data) { + getSavedQueries(data.id); + viewModel.saving(false); + viewModel.loading(false); + }); + } + + var cancelSave = function () { + viewModel.saving(false); + } + + var deleteQuery = function () { + var confirmText = resx.DeleteConfirm; + var deleteText = resx.Delete; + var cancelText = resx.Cancel; + + utility.confirm(confirmText, deleteText, cancelText, function () { + viewModel.loading(true); + requestService('post', 'DeleteQuery', { id: viewModel.id() }, function () { + getSavedQueries(); + viewModel.loading(false); + }); + }); + } + + var clone = function (data) { + var cloneData = {}; + for (var name in data) { + if (data.hasOwnProperty(name)) { + cloneData[name] = data[name]; } + } - var startSaveQuery = function() { - viewModel.query(sqlContent.getValue()); - - if (!viewModel.query()) { - return; - } - - viewModel.saving(true); + return cloneData; + } - if (viewModel.id() <= 0) { - viewModel.name(''); - } - - $('#query-name').focus(); + var encode = function (item) { + for (var name in item) { + if (item.hasOwnProperty(name) && item[name]) { + item[name] = $('
').text(item[name]).html(); } + } - var saveQuery = function () { - viewModel.query(sqlContent.getValue()); - - if (!viewModel.query()) { - return; - } - - if (!viewModel.name()) { - utility.notify(resx.EmptyName); - return; - } + return item; + }; - var query = { - id: viewModel.id(), - name: viewModel.name(), - query: viewModel.query(), - connection: viewModel.connection() - } + var matchKeyword = function (data, keyword) { + if (!keyword) { + return true; + } - viewModel.loading(true); + var keywords = keyword.toLowerCase().split(' '); - requestService('post', 'SaveQuery', query, function (data) { - getSavedQueries(data.id); - viewModel.saving(false); - viewModel.loading(false); - }); + var allEmptyKey = true; + for (var i = 0; i < keywords.length; i++) { + var key = keywords[i].trim(); + if (key) { + allEmptyKey = false; + break; } - - var cancelSave = function () { - viewModel.saving(false); + } + + if (allEmptyKey) { + return true; + } + + var matched = false; + for (var name in data) { + if (data.hasOwnProperty(name) && data[name]) { + for (var i = 0; i < keywords.length; i++) { + var key = keywords[i].trim(); + if (key) { + var regexVal = key.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'); + var regex = new RegExp('(' + regexVal + ')', 'gi'); + if (regex.test(data[name].toString())) { + data[name] = data[name].toString().replace(regex, '$1'); + matched = true; + } + } + } } - - var deleteQuery = function() { - var confirmText = resx.DeleteConfirm; - var deleteText = resx.Delete; - var cancelText = resx.Cancel; - - utility.confirm(confirmText, deleteText, cancelText, function () { - viewModel.loading(true); - requestService('post', 'DeleteQuery', { id: viewModel.id() }, function () { - getSavedQueries(); - viewModel.loading(false); - }); - }); + } + + return matched; + } + + var normalizeType = function (value) { + if (value === "" || value === null || typeof value === "undefined") { + return ""; + } + var type = typeof value; + switch (type) { + case 'boolean': + return value; + case 'number': + return value; + case 'string': + var lcValue = value.toLowerCase(); + if (isFinite(lcValue)) { + return parseFloat(lcValue); + } else if (lcValue == "true") { + return true; + } else if (lcValue == "false") { + return false; + } + return lcValue; + default: + return value; + + } + }; + + var createDataTable = function (data) { + var table = { header: [], rows: ko.observableArray(data) }; + //try to find headers + var row = data[0]; + for (var name in row) { + if (row.hasOwnProperty(name)) { + table.header.push(name); } - - var clone = function (data) { - var cloneData = {}; - for (var name in data) { - if (data.hasOwnProperty(name)) { - cloneData[name] = data[name]; - } - } - - return cloneData; + } + + table.sortColumn = ko.observable(table.header[0]); + table.sortType = ko.observable(0); + + table.keywords = ko.observable(''); + table.keywords.subscribe(function () { + table.currentPage(1); + }); + table.keywords.extend({ rateLimit: 200 }); + + //try to get page info + table.pageSizes = ko.observableArray([ + { name: resx.AllEntries, value: 0 }, + { name: resx.PageSize.replace('{0}', 10), value: 10 }, + { name: resx.PageSize.replace('{0}', 25), value: 25 }, + { name: resx.PageSize.replace('{0}', 50), value: 50 }, + { name: resx.PageSize.replace('{0}', 100), value: 100 } + ]); + + table.pageSize = ko.observable(10); + table.showPageSizesList = ko.observable(false); + + table.pageSizesLabel = ko.computed(function () { + var sizes = table.pageSizes(); + for (var i = 0; i < sizes.length; i++) { + if (sizes[i].value === table.pageSize()) { + return sizes[i].name; + } } - var encode = function (item) { - for (var name in item) { - if (item.hasOwnProperty(name) && item[name]) { - item[name] = $('
').text(item[name]).html(); - } - } - - return item; - }; - - var matchKeyword = function (data, keyword) { - if (!keyword) { - return true; - } - - var keywords = keyword.toLowerCase().split(' '); - - var allEmptyKey = true; - for (var i = 0; i < keywords.length; i++) { - var key = keywords[i].trim(); - if (key) { - allEmptyKey = false; - break; - } - } - - if (allEmptyKey) { - return true; - } - - var matched = false; - for (var name in data) { - if (data.hasOwnProperty(name) && data[name]) { - for (var i = 0; i < keywords.length; i++) { - var key = keywords[i].trim(); - if (key) { - var regexVal = key.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'); - var regex = new RegExp('(' + regexVal + ')', 'gi'); - if (regex.test(data[name].toString())) { - data[name] = data[name].toString().replace(regex, '$1'); - matched = true; - } - } - } - } - } - - return matched; + return ''; + }); + + table.changePageSize = function () { + table.pageSize(this.value); + table.currentPage(1); + + var $currentTable = $('.tables-container > div:visible').find('div.table-container'); + $currentTable.data('jsp').destroy(); + + $currentTable = $('.tables-container > div:visible').find('div.table-container'); + $currentTable.jScrollPane(); + + table.showPageSizesList(false); + } + + table.currentPage = ko.observable(1); + table.currentPage.subscribe(function () { + setTimeout(function () { + var $currentTable = $('.tables-container > div:visible').find('div.table-container'); + if ($currentTable.data('jsp')) { + $currentTable.data('jsp').destroy(); + } + }, 0); + setTimeout(function () { + var $currentTable = $('.tables-container > div:visible').find('div.table-container'); + + if (!$currentTable.data('jsp')) { + $currentTable.jScrollPane(); + } + }, 10); + + }); + + table.startIndex = ko.computed(function () { + return (table.currentPage() - 1) * table.pageSize(); + }); + + table.filterData = ko.computed(function () { + var filterData = ko.observableArray(); + var source = table.rows(); + for (var i = 0; i < source.length; i++) { + var keywords = table.keywords(); + var item = encode(clone(source[i])); + if (matchKeyword(item, keywords)) { + filterData.push(item); + } } - var normalizeType = function (value) { - if(value === "" || value === null || typeof value === "undefined") { - return ""; - } - var type = typeof value; - switch(type) { - case 'boolean': - return value; - case 'number': - return value; - case 'string': - var lcValue = value.toLowerCase(); - if(isFinite(lcValue)) { - return parseFloat(lcValue); - } else if(lcValue == "true") { - return true; - } else if(lcValue == "false") { - return false; - } - return lcValue; - default: - return value; - - } - }; - - var createDataTable = function (data) { - var table = { header: [], rows: ko.observableArray(data) }; - //try to find headers - var row = data[0]; - for (var name in row) { - if (row.hasOwnProperty(name)) { - table.header.push(name); - } - } - - table.sortColumn = ko.observable(table.header[0]); - table.sortType = ko.observable(0); - - table.keywords = ko.observable(''); - table.keywords.subscribe(function () { - table.currentPage(1); - }); - table.keywords.extend({ rateLimit: 200 }); - - //try to get page info - table.pageSizes = ko.observableArray([ - { name: resx.AllEntries, value: 0 }, - { name: resx.PageSize.replace('{0}', 10), value: 10 }, - { name: resx.PageSize.replace('{0}', 25), value: 25 }, - { name: resx.PageSize.replace('{0}', 50), value: 50 }, - { name: resx.PageSize.replace('{0}', 100), value: 100 } - ]); - - table.pageSize = ko.observable(10); - table.showPageSizesList = ko.observable(false); - - table.pageSizesLabel = ko.computed(function () { - var sizes = table.pageSizes(); - for (var i = 0; i < sizes.length; i++) { - if (sizes[i].value === table.pageSize()) { - return sizes[i].name; - } - } - - return ''; - }); - - table.changePageSize = function () { - table.pageSize(this.value); - table.currentPage(1); - - var $currentTable = $('.tables-container > div:visible').find('div.table-container'); - $currentTable.data('jsp').destroy(); - - $currentTable = $('.tables-container > div:visible').find('div.table-container'); - $currentTable.jScrollPane(); - - table.showPageSizesList(false); - } - - table.currentPage = ko.observable(1); - table.currentPage.subscribe(function () { - setTimeout(function () { - var $currentTable = $('.tables-container > div:visible').find('div.table-container'); - if ($currentTable.data('jsp')) { - $currentTable.data('jsp').destroy(); - } - }, 0); - setTimeout(function () { - var $currentTable = $('.tables-container > div:visible').find('div.table-container'); - - if (!$currentTable.data('jsp')) { - $currentTable.jScrollPane(); - } - }, 10); - - }); - - table.startIndex = ko.computed(function () { - return (table.currentPage() - 1) * table.pageSize(); - }); - - table.filterData = ko.computed(function () { - var filterData = ko.observableArray(); - var source = table.rows(); - for (var i = 0; i < source.length; i++) { - var keywords = table.keywords(); - var item = encode(clone(source[i])); - if (matchKeyword(item, keywords)) { - filterData.push(item); - } - } - - var sortType = table.sortType(); - if (sortType !== 0) { - filterData.sort(function (left, right) { - var sortColumn = table.sortColumn(); - var leftData = normalizeType(left[sortColumn]); - var rightData = normalizeType(right[sortColumn]); - - if (leftData === rightData) { - return 0; - } else if (leftData === "" || leftData < rightData) { - return sortType === 1 ? -1 : 1; - } else if (leftData > rightData || rightData === "") { - return sortType === 1 ? 1 : -1; - } - }); - } - - return filterData(); - }); - - table.endIndex = ko.computed(function () { - var endIndex = table.startIndex() + table.pageSize(); - - if (table.pageSize() === 0 || endIndex > table.filterData().length) { - endIndex = table.filterData().length; - } - return endIndex; - }); - - table.totalPages = ko.computed(function () { - if (table.pageSize() === 0) { - return 0; - } - var totalPages = parseInt(table.filterData().length / table.pageSize()); - if (table.filterData().length % table.pageSize() !== 0) { - totalPages++; - } - return totalPages; - }); - - table.statistics = ko.computed(function () { - var args = [table.startIndex() + 1, table.endIndex(), table.filterData().length]; - return viewModel.resx.PageInfo.replace(/\{(\d+)\}/gi, function (i) { var index = parseInt(arguments[1]); return args[index]; }); - }); - - table.pagesNumber = ko.computed(function () { - var pages = []; - var totalPages = table.totalPages(); - if (totalPages <= pagesCount) { - for (var i = 1; i <= totalPages; i++) { - pages.push(i); - } - } else { - var currentPage = table.currentPage(); - var split = parseInt(pagesCount / 2); - var start = currentPage > split ? currentPage - split : 1; - var end = totalPages - currentPage < split ? totalPages : start + pagesCount - 1; - - if (end - start !== pagesCount - 1) { - start = end - pagesCount + 1; - } - - for (var i = start; i <= end; i++) { - pages.push(i); - } - } - - return pages; - }); - - table.prev = function (e) { - if (table.currentPage() > 1) { - table.currentPage(table.currentPage() - 1); - } - } - - table.next = function (e) { - if (table.currentPage() < table.totalPages()) { - table.currentPage(table.currentPage() + 1); - } - } - - table.changePage = function (page, e) { - table.currentPage(page); - }; - - table.pageData = ko.computed(function () { - var data = []; - var filterData = table.filterData(); - for (var i = table.startIndex() ; i < table.endIndex() ; i++) { - data.push(filterData[i]); - } - return data; - }); - - table.hasData = ko.computed(function() { - return table.pageData().length > 0 || table.keywords().length > 0; - }); - - var exportFile = function (name, data) { - var blob = new Blob([data], { - type: "application/vnd.ms-excel;charset=utf-8" - }); - saveAs(blob, name); - } - - var exportExcel = function () { - viewModel.loading(true); - var pageSize = table.pageSize(); - var currentPage = table.currentPage(); - table.currentPage(1); - table.pageSize(table.filterData().length); - - exportFile(table.title + '.xls', exportData.excel($('#result' + table.index + ' table')[0])); - - table.pageSize(pageSize); - table.currentPage(currentPage); - table.showExportList(false); - viewModel.loading(false); - } - - var exportCsv = function () { - viewModel.loading(true); - var pageSize = table.pageSize(); - var currentPage = table.currentPage(); - table.currentPage(1); - table.pageSize(table.filterData().length); - - exportFile(table.title + '.csv', exportData.csv($('#result' + table.index + ' table')[0])); - - table.pageSize(pageSize); - table.currentPage(currentPage); - table.showExportList(false); - viewModel.loading(false); - } - - var exportPdf = function () { - viewModel.loading(true); - var pageSize = table.pageSize(); - var currentPage = table.currentPage(); - table.currentPage(1); - table.pageSize(table.filterData().length); - var selector = '#result' + table.index + ' .table-container'; - var $container = $(selector); - - if ($container.data('jsp')) { - $container.data('jsp').destroy(); - $container = $(selector); - } - - var $table = $container.find('table'); - var $line = $('
').css({ - height: '1px', - width: $table.outerWidth(), - opacity: 0 - }); - $('.sqlconsolePanel .results-container').after($line); - - html2canvas($table[0], { - onrendered: function (canvas) { - table.pageSize(pageSize); - table.currentPage(currentPage); - table.showExportList(false); - viewModel.loading(false); - - var $wrapper = $('
'); - $wrapper.width(canvas.width).height(canvas.height); - $wrapper.append(canvas); - $(document.body).append($wrapper); - - var generatePdf = function() { - var layout = canvas.height > canvas.width ? 'p' : 'l'; - var pdf = new jsPdf(layout, 'pt', [canvas.width, canvas.height]); - pdf.addHTML($wrapper[0], function () { - pdf.save(table.title + '.pdf'); - $wrapper.remove(); - $line.remove(); - - if (!$container.data('jsp')) { - $container.jScrollPane(); - } - }); - } - - if (typeof jsPdf === "undefined") { - require(['main/../modules/dnn.sqlconsole/scripts/jspdf'], function(pdf) { - jsPdf = pdf; - generatePdf(); - }); - } else { - generatePdf(); - } - } - }); - } - - var exportClipboard = function () { - viewModel.loading(true); - var pageSize = table.pageSize(); - var currentPage = table.currentPage(); - table.currentPage(1); - table.pageSize(table.filterData().length); - - var $download = $('').appendTo(document.body); - $download.click(function(e) { - e.preventDefault(); - }); - - var clipboard = new Clipboard($download[0], { - text: function(trigger) { - return exportData.csv($('#result' + table.index + ' table')[0], '\t'); - } - }); - - clipboard.on('success', function(e) { - clipboard.destroy(); - $download.remove(); - - utility.notify(resx.ExportClipboardSuccessful); - - table.pageSize(pageSize); - table.currentPage(currentPage); - table.showExportList(false); - viewModel.loading(false); - }); - - clipboard.on('error', function (e) { - e.clearSelection(); - - clipboard.destroy(); - $download.remove(); - - utility.notify(resx.ExportClipboardFailed); - - table.pageSize(pageSize); - table.currentPage(currentPage); - table.showExportList(false); - viewModel.loading(false); - }); - - $download[0].click(); - } - - var getExportMethods = function () { - return [ - { - name: resx.ExportExcel, - onExport: exportExcel - }, - { - name: resx.ExportCSV, - onExport: exportCsv - }, { - name: resx.ExportPDF, - onExport: exportPdf - }, { - name: resx.ExportClipboard, - onExport: exportClipboard - }]; - } - - table.showExportList = ko.observable(false); - table.exportMethods = getExportMethods(); - - return table; - } - - var renderData = function (data) { - viewModel.tables.removeAll(); - for (var i = 0; i < data.length; i++) { - var table = createDataTable(data[i]); - if (table != null) { - table.title = resx.QueryTabTitle.replace('{0}', (i + 1)); - table.index = i; - viewModel.tables.push(table); - } - } + var sortType = table.sortType(); + if (sortType !== 0) { + filterData.sort(function (left, right) { + var sortColumn = table.sortColumn(); + var leftData = normalizeType(left[sortColumn]); + var rightData = normalizeType(right[sortColumn]); + + if (leftData === rightData) { + return 0; + } else if (leftData === "" || leftData < rightData) { + return sortType === 1 ? -1 : 1; + } else if (leftData > rightData || rightData === "") { + return sortType === 1 ? 1 : -1; + } + }); } - var runQuery = function () { - var newQuery = sqlContent.getValue(); - viewModel.query(newQuery); - - if (!viewModel.query()) { - return; - } + return filterData(); + }); - var params = { - connection: viewModel.connection(), - query: viewModel.query() - } - viewModel.tables.removeAll(); - viewModel.loading(true); - - requestService('post', 'RunQuery', params, function (data) { - if (data.Data) { - renderData(data.Data); - - var $animateControl = $('div.CodeMirror'); - if ($animateControl.height() > 100) { - $animateControl.animate({ height: '-=250' }, 'fast').on('click.sqlconsole', function() { - $animateControl.animate({ height: '+=250' }, 'fast'); - $animateControl.off('click.sqlconsole'); - }); - } - } else { - utility.notify(resx.QuerySuccessful); - } + table.endIndex = ko.computed(function () { + var endIndex = table.startIndex() + table.pageSize(); - viewModel.loading(false); - }, function (xhr) { - var message = resx.QueryFailed; - if (xhr.responseText) { - var response = eval('(' + xhr.responseText + ')'); - if (response['Error'] || response['Message']) { - message = response['Error'] || response['Message']; - } - } - viewModel.loading(false); - utility.notifyError(htmlDecode(message), { clickToClose: true}); - }); + if (table.pageSize() === 0 || endIndex > table.filterData().length) { + endIndex = table.filterData().length; } - function htmlDecode(textToDecode) { - return $('
').text(textToDecode).html(); + return endIndex; + }); + + table.totalPages = ko.computed(function () { + if (table.pageSize() === 0) { + return 0; } - var queryChanged = function (data) { - sqlContent.setValue(data); + var totalPages = parseInt(table.filterData().length / table.pageSize()); + if (table.filterData().length % table.pageSize() !== 0) { + totalPages++; } - - var initViewModel = function () { - viewModel = { - resx: utility.resx.SqlConsole, - savedQueries: ko.observableArray([]), - selectedQuery: ko.observable(), - connections: ko.observableArray([]), - id: ko.observable(0), - name: ko.observable(''), - connection: ko.observable(''), - query: ko.observable(''), - loading: ko.observable(false), - runQuery: runQuery, - tables: ko.observableArray([]), - changeTab: changeTab, - scrollPaneInitialised: scrollPaneInitialised, - saving: ko.observable(false), - startSaveQuery: startSaveQuery, - saveQuery: saveQuery, - deleteQuery: deleteQuery, - cancelSave: cancelSave, - savedQueryChanged: savedQueryChanged, - }; - - viewModel.selectedQuery.subscribe(savedQueryChanged); + return totalPages; + }); + + table.statistics = ko.computed(function () { + var args = [table.startIndex() + 1, table.endIndex(), table.filterData().length]; + return viewModel.resx.PageInfo.replace(/\{(\d+)\}/gi, function (i) { var index = parseInt(arguments[1]); return args[index]; }); + }); + + table.pagesNumber = ko.computed(function () { + var pages = []; + var totalPages = table.totalPages(); + if (totalPages <= pagesCount) { + for (var i = 1; i <= totalPages; i++) { + pages.push(i); + } + } else { + var currentPage = table.currentPage(); + var split = parseInt(pagesCount / 2); + var start = currentPage > split ? currentPage - split : 1; + var end = totalPages - currentPage < split ? totalPages : start + pagesCount - 1; + + if (end - start !== pagesCount - 1) { + start = end - pagesCount + 1; + } + + for (var i = start; i <= end; i++) { + pages.push(i); + } } + return pages; + }); - var init = function (wrapper, util, params, callback) { - utility = util; - resx = utility.resx.SqlConsole; - $panel = wrapper; - - initViewModel(); - - viewModel.query.subscribe(queryChanged); - - ko.applyBindings(viewModel, $panel[0]); + table.prev = function (e) { + if (table.currentPage() > 1) { + table.currentPage(table.currentPage() - 1); + } + } - getSavedQueries(-1); - initUpload(); + table.next = function (e) { + if (table.currentPage() < table.totalPages()) { + table.currentPage(table.currentPage() + 1); + } + } - initSqlConsole(); + table.changePage = function (page, e) { + table.currentPage(page); + }; - if (typeof callback === 'function') { - callback(); - } - }; + table.pageData = ko.computed(function () { + var data = []; + var filterData = table.filterData(); + for (var i = table.startIndex(); i < table.endIndex(); i++) { + data.push(filterData[i]); + } + return data; + }); + + table.hasData = ko.computed(function () { + return table.pageData().length > 0 || table.keywords().length > 0; + }); + + var exportFile = function (name, data) { + var blob = new Blob([data], { + type: "application/vnd.ms-excel;charset=utf-8" + }); + saveAs(blob, name); + } + + var exportExcel = function () { + viewModel.loading(true); + var pageSize = table.pageSize(); + var currentPage = table.currentPage(); + table.currentPage(1); + table.pageSize(table.filterData().length); + + exportFile(table.title + '.xls', exportData.excel($('#result' + table.index + ' table')[0])); + + table.pageSize(pageSize); + table.currentPage(currentPage); + table.showExportList(false); + viewModel.loading(false); + } + + var exportCsv = function () { + viewModel.loading(true); + var pageSize = table.pageSize(); + var currentPage = table.currentPage(); + table.currentPage(1); + table.pageSize(table.filterData().length); + + exportFile(table.title + '.csv', exportData.csv($('#result' + table.index + ' table')[0])); + + table.pageSize(pageSize); + table.currentPage(currentPage); + table.showExportList(false); + viewModel.loading(false); + } + + var exportPdf = function () { + viewModel.loading(true); + var pageSize = table.pageSize(); + var currentPage = table.currentPage(); + table.currentPage(1); + table.pageSize(table.filterData().length); + var selector = '#result' + table.index + ' .table-container'; + var $container = $(selector); + + if ($container.data('jsp')) { + $container.data('jsp').destroy(); + $container = $(selector); + } - var initSqlConsole = function() { - var monacoEditorLoaderScript = document.createElement('script'); - monacoEditorLoaderScript.type = 'text/javascript'; - monacoEditorLoaderScript.src = '/Resources/Shared/components/MonacoEditor/loader.js'; - document.body.appendChild(monacoEditorLoaderScript); - - require.config({ paths: { 'vs': '/Resources/Shared/components/MonacoEditor' }}); - require(['vs/editor/editor.main'], function(monaco) { - - self.MonacoEnvironment = { - getWorkerUrl: function (moduleId, label) { - if (label === 'typescript' || label === 'javascript') { - return `data:text/javascript;charset=utf-8,${encodeURIComponent(` - importScripts('${process.env.ASSET_PATH}/typescript.worker.js');` - )}`; - } - - return `data:text/javascript;charset=utf-8,${encodeURIComponent(` - importScripts('${process.env.ASSET_PATH}/editor.worker.js');` - )}`; - } + var $table = $container.find('table'); + var $line = $('
').css({ + height: '1px', + width: $table.outerWidth(), + opacity: 0 + }); + $('.sqlconsolePanel .results-container').after($line); + + html2canvas($table[0], { + onrendered: function (canvas) { + table.pageSize(pageSize); + table.currentPage(currentPage); + table.showExportList(false); + viewModel.loading(false); + + var $wrapper = $('
'); + $wrapper.width(canvas.width).height(canvas.height); + $wrapper.append(canvas); + $(document.body).append($wrapper); + + var generatePdf = function () { + var layout = canvas.height > canvas.width ? 'p' : 'l'; + var pdf = new jsPdf(layout, 'pt', [canvas.width, canvas.height]); + pdf.addHTML($wrapper[0], function () { + pdf.save(table.title + '.pdf'); + $wrapper.remove(); + $line.remove(); + + if (!$container.data('jsp')) { + $container.jScrollPane(); } - - sqlConsole = monaco.editor; - sqlContent = sqlConsole.createModel("", "sql"); - initMonacoEditor(); + }); + } + + if (typeof jsPdf === "undefined") { + require(['main/../modules/dnn.sqlconsole/scripts/jspdf'], function (pdf) { + jsPdf = pdf; + generatePdf(); + }); + } else { + generatePdf(); + } + } + }); + } + + var exportClipboard = function () { + viewModel.loading(true); + var pageSize = table.pageSize(); + var currentPage = table.currentPage(); + table.currentPage(1); + table.pageSize(table.filterData().length); + + var $download = $('').appendTo(document.body); + $download.click(function (e) { + e.preventDefault(); + }); + + var clipboard = new Clipboard($download[0], { + text: function (trigger) { + return exportData.csv($('#result' + table.index + ' table')[0], '\t'); + } + }); + + clipboard.on('success', function (e) { + clipboard.destroy(); + $download.remove(); + + utility.notify(resx.ExportClipboardSuccessful); + + table.pageSize(pageSize); + table.currentPage(currentPage); + table.showExportList(false); + viewModel.loading(false); + }); + + clipboard.on('error', function (e) { + e.clearSelection(); + + clipboard.destroy(); + $download.remove(); + + utility.notify(resx.ExportClipboardFailed); + + table.pageSize(pageSize); + table.currentPage(currentPage); + table.showExportList(false); + viewModel.loading(false); + }); + + $download[0].click(); + } + + var getExportMethods = function () { + return [ + { + name: resx.ExportExcel, + onExport: exportExcel + }, + { + name: resx.ExportCSV, + onExport: exportCsv + }, { + name: resx.ExportPDF, + onExport: exportPdf + }, { + name: resx.ExportClipboard, + onExport: exportClipboard + }]; + } + + table.showExportList = ko.observable(false); + table.exportMethods = getExportMethods(); + + return table; + } + + var renderData = function (data) { + viewModel.tables.removeAll(); + for (var i = 0; i < data.length; i++) { + var table = createDataTable(data[i]); + if (table != null) { + table.title = resx.QueryTabTitle.replace('{0}', (i + 1)); + table.index = i; + viewModel.tables.push(table); + } + } + } + + var runQuery = function () { + var newQuery = sqlContent.getValue(); + viewModel.query(newQuery); + + if (!viewModel.query()) { + return; + } + + var params = { + connection: viewModel.connection(), + query: viewModel.query() + } + viewModel.tables.removeAll(); + viewModel.loading(true); + + requestService('post', 'RunQuery', params, function (data) { + if (data.Data) { + renderData(data.Data); + + var $animateControl = $('div.CodeMirror'); + if ($animateControl.height() > 100) { + $animateControl.animate({ height: '-=250' }, 'fast').on('click.sqlconsole', function () { + $animateControl.animate({ height: '+=250' }, 'fast'); + $animateControl.off('click.sqlconsole'); }); - + } + } else { + utility.notify(resx.QuerySuccessful); } - var initMonacoEditor = function() { - var theme = "vs-light"; - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - theme = "vs-dark"; + viewModel.loading(false); + }, function (xhr) { + var message = resx.QueryFailed; + if (xhr.responseText) { + var response = eval('(' + xhr.responseText + ')'); + if (response['Error'] || response['Message']) { + message = response['Error'] || response['Message']; + } + } + viewModel.loading(false); + utility.notifyError(htmlDecode(message), { clickToClose: true }); + }); + } + function htmlDecode(textToDecode) { + return $('
').text(textToDecode).html(); + } + var queryChanged = function (data) { + sqlContent.setValue(data); + } + + var initViewModel = function () { + viewModel = { + resx: utility.resx.SqlConsole, + savedQueries: ko.observableArray([]), + selectedQuery: ko.observable(), + connections: ko.observableArray([]), + id: ko.observable(0), + name: ko.observable(''), + connection: ko.observable(''), + query: ko.observable(''), + loading: ko.observable(false), + runQuery: runQuery, + tables: ko.observableArray([]), + changeTab: changeTab, + scrollPaneInitialised: scrollPaneInitialised, + saving: ko.observable(false), + startSaveQuery: startSaveQuery, + saveQuery: saveQuery, + deleteQuery: deleteQuery, + cancelSave: cancelSave, + savedQueryChanged: savedQueryChanged, + }; + + viewModel.selectedQuery.subscribe(savedQueryChanged); + } + + + var init = function (wrapper, util, params, callback) { + utility = util; + resx = utility.resx.SqlConsole; + $panel = wrapper; + + initViewModel(); + + viewModel.query.subscribe(queryChanged); + + ko.applyBindings(viewModel, $panel[0]); + + getSavedQueries(-1); + initUpload(); + + initSqlConsole(); + + if (typeof callback === 'function') { + callback(); + } + }; + + var initSqlConsole = function () { + let siteRoot = dnn ? dnn.getVar("sf_siteRoot") : '/'; + if (!siteRoot) siteRoot = '/'; + var monacoEditorLoaderScript = document.createElement('script'); + monacoEditorLoaderScript.type = 'text/javascript'; + monacoEditorLoaderScript.src = siteRoot + 'Resources/Shared/components/MonacoEditor/loader.js'; + document.body.appendChild(monacoEditorLoaderScript); + + require.config({ paths: { 'vs': siteRoot + 'Resources/Shared/components/MonacoEditor' } }); + require(['vs/editor/editor.main'], function (monaco) { + + self.MonacoEnvironment = { + getWorkerUrl: function (moduleId, label) { + if (label === 'typescript' || label === 'javascript') { + return `data:text/javascript;charset=utf-8,${encodeURIComponent(` + importScripts('${process.env.ASSET_PATH}/typescript.worker.js');` + )}`; } - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { - theme = e.matches ? "vs-dark" : "vs-light"; - }); - var monacoEditor = sqlConsole.create(document.getElementById("monaco-editor"), { - model: sqlContent, - language: "sql", - wordWrap: 'wordWrapColumn', - wordWrapColumn: 80, - wordWrapMinified: true, - wrappingIndent: "indent", - lineNumbers: "on", - roundedSelection: false, - scrollBeyondLastLine: false, - readOnly: false, - theme: theme, - automaticLayout: true - }); + return `data:text/javascript;charset=utf-8,${encodeURIComponent(` + importScripts('${process.env.ASSET_PATH}/editor.worker.js');` + )}`; + } } - var load = function (params, callback) { - if (typeof callback === 'function') { - callback(); - } - }; - - return { - init: init, - load: load - }; - }); + sqlConsole = monaco.editor; + sqlContent = sqlConsole.createModel("", "sql"); + initMonacoEditor(); + }); + + } + + var initMonacoEditor = function () { + var theme = "vs-light"; + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + theme = "vs-dark"; + } + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { + theme = e.matches ? "vs-dark" : "vs-light"; + }); + + var monacoEditor = sqlConsole.create(document.getElementById("monaco-editor"), { + model: sqlContent, + language: "sql", + wordWrap: 'wordWrapColumn', + wordWrapColumn: 80, + wordWrapMinified: true, + wrappingIndent: "indent", + lineNumbers: "on", + roundedSelection: false, + scrollBeyondLastLine: false, + readOnly: false, + theme: theme, + automaticLayout: true + }); + } + + var load = function (params, callback) { + if (typeof callback === 'function') { + callback(); + } + }; + + return { + init: init, + load: load + }; + });