diff --git a/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py b/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py index 75b42220b..ac50ea13e 100644 --- a/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py +++ b/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py @@ -61,7 +61,7 @@ class CheckForXssFeatureTest(BaseFeatureTest): # Query tool self._check_xss_in_query_tool() - self._close_query_tool() + self.page.close_query_tool() def after(self): time.sleep(1) @@ -123,7 +123,6 @@ class CheckForXssFeatureTest(BaseFeatureTest): "Properties tab (Backform Control)" ) - def _check_xss_in_sql_tab(self): self.page.click_tab("SQL") # Fetch the inner html & check for escaped characters @@ -173,19 +172,6 @@ class CheckForXssFeatureTest(BaseFeatureTest): "Query tool (SlickGrid)" ) - def _close_query_tool(self): - self.page.driver.switch_to_default_content() - self.page.click_element( - self.page.find_by_xpath("//*[@id='dockerContainer']/div/div[3]/div/div[2]/div[1]") - ) - time.sleep(0.5) - self.page.driver.switch_to.frame(self.page.driver.find_element_by_tag_name('iframe')) - time.sleep(1) - self.page.click_element(self.page.find_by_xpath("//button[contains(.,'Yes')]")) - time.sleep(0.5) - self.page.driver.switch_to_default_content() - - def _check_escaped_characters(self, source_code, string_to_find, source): # For XSS we need to search against element's html code if source_code.find(string_to_find) == -1: diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js index 2ea37fcc7..0584df5a9 100644 --- a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js +++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js @@ -253,11 +253,11 @@ define([ var data_store = self.handler.data_store; if(data_store && (_.size(data_store.added) || _.size(data_store.updated))) { - msg = gettext("The data has been modified, but not saved. Are you sure you wish to discard the changes?"); + msg = gettext("The data has changed. Do you want to save changes?"); notify = true; } } else if(self.handler.is_query_tool && self.handler.is_query_changed) { - msg = gettext("The query has been modified, but not saved. Are you sure you wish to discard the changes?"); + msg = gettext("The text has changed. Do you want to save changes?"); notify = true; } if(notify) {return self.user_confirmation(p, msg);} @@ -407,23 +407,60 @@ define([ user_confirmation: function(panel, msg) { // If there is anything to save then prompt user var that = this; - alertify.confirm(gettext("Unsaved changes"), msg, - function() { - // Do nothing as user do not want to save, just continue - window.onbeforeunload = null; - panel.off(wcDocker.EVENT.CLOSING); - // remove col_size object on panel close - if (!_.isUndefined(that.handler.col_size)) { - delete that.handler.col_size; + + alertify.confirmSave || alertify.dialog('confirmSave', function() { + return { + main: function(title, message) { + var content = '
' + + gettext('The text has changed. Do you want to save changes?') + + '
'; + this.setHeader(title); + this.setContent(message); + }, + setup: function () { + return { + buttons: [ + { + text: gettext('Save'), + className: 'btn btn-primary', + },{ + text: gettext('Don\'t save'), + className: 'btn btn-danger', + },{ + text: gettext('Cancel'), + key: 27, // ESC + invokeOnClose: true, + className: 'btn btn-warning', + } + ], + focus: { + element: 0, + select: false + }, + options: { + maximizable: false, + resizable: false + } + }; + }, + callback: function (closeEvent) { + switch (closeEvent.index) { + case 0: // Save + that.handler.close_on_save = true; + that.handler._save(that, that.handler); + break; + case 1: // Don't Save + that.handler.close_on_save = false; + that.handler.close(); + break; + case 2: //Cancel + //Do nothing. + break; + } } - window.top.pgAdmin.Browser.docker.removePanel(panel); - }, - function() { - // Stop, User wants to save - // false value will prevent from panel to close - return true; - } - ).set('labels', {ok:'Yes', cancel:'No'}); + }; + }); + alertify.confirmSave(gettext("Save changes?"), msg); return false; }, @@ -1015,6 +1052,7 @@ define([ this._stopEventPropogation(ev); this._closeDropDown(ev); + self.handler.close_on_save = false; // Trigger the save signal to the SqlEditorController class self.handler.trigger( 'pgadmin-sqleditor:button:save', @@ -1030,6 +1068,7 @@ define([ this._stopEventPropogation(ev); this._closeDropDown(ev); + self.handler.close_on_save = false; // Trigger the save signal to the SqlEditorController class self.handler.trigger( 'pgadmin-sqleditor:button:save', @@ -1497,6 +1536,7 @@ define([ self.is_new_browser_tab = is_new_browser_tab; self.has_more_rows = false; self.fetching_rows = false; + self.close_on_save = false; // We do not allow to call the start multiple times. if (self.gridView) @@ -2363,6 +2403,11 @@ define([ self.trigger('pgadmin-sqleditor:loading-icon:hide'); grid.invalidate(); + var alertifyWrapper = new AlertifyWrapper(); + alertifyWrapper.success(gettext("Data saved successfully.")); + if (self.close_on_save) { + self.close(); + } }, error: function(e) { if (e.readyState == 0) { @@ -2557,6 +2602,9 @@ define([ self.is_query_changed = false; } self.trigger('pgadmin-sqleditor:loading-icon:hide'); + if (self.close_on_save) { + self.close() + } }, error: function(e) { self.trigger('pgadmin-sqleditor:loading-icon:hide'); @@ -3663,6 +3711,20 @@ define([ ); } }); + }, + close: function() { + var self= this; + _.each(window.top.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(panel) { + if(panel.isVisible()) { + window.onbeforeunload = null; + panel.off(wcDocker.EVENT.CLOSING); + // remove col_size object on panel close + if (!_.isUndefined(self.col_size)) { + delete self.col_size; + } + window.top.pgAdmin.Browser.docker.removePanel(panel); + } + }); } } ); diff --git a/web/regression/feature_utils/pgadmin_page.py b/web/regression/feature_utils/pgadmin_page.py index b675c1a35..890724367 100644 --- a/web/regression/feature_utils/pgadmin_page.py +++ b/web/regression/feature_utils/pgadmin_page.py @@ -96,7 +96,7 @@ class PgadminPage: self.find_by_xpath("//li[contains(@class, 'context-menu-item')]/span[contains(text(), 'Remove Panel')]").click() self.driver.switch_to.frame(self.driver.find_elements_by_tag_name("iframe")[0]) time.sleep(.5) - self.click_element(self.find_by_xpath('//button[contains(@class, "ajs-button") and contains(.,"Yes")]')) + self.click_element(self.find_by_xpath('//button[contains(@class, "ajs-button") and contains(.,"Don\'t save")]')) self.driver.switch_to.default_content() def close_data_grid(self):