Fixed an issue where shared server entries not getting deleted from SQLite database if the user gets deleted. Fixes #6143

This commit is contained in:
Nikhil Mohite
2021-02-04 11:31:39 +05:30
committed by Akshay Joshi
parent 6683522491
commit 02c3863e8c
5 changed files with 752 additions and 345 deletions
@@ -100,352 +100,353 @@ export default function newConnectionDialogModel(response, sgid, sid, handler, c
server_name: server_name,
database_name: database_name,
},
schema: [{
id: 'server',
name: 'server',
label: gettext('Server'),
type: 'text',
editable: true,
disabled: false,
select2: {
allowClear: false,
width: 'style',
templateResult: formatNode,
templateSelection: formatNode,
},
events: {
'focus select': 'clearInvalid',
'keydown :input': 'processTab',
'select2:select': 'onSelect',
'select2:selecting': 'beforeSelect',
'select2:clear': 'onChange',
},
transform: function(data) {
let group_template_options = [];
for (let key in data) {
if (data.hasOwnProperty(key)) {
group_template_options.push({'group': key, 'optval': data[key]});
}
}
return group_template_options;
},
control: Backform.Select2Control.extend({
template: _.template([
'<% if(label == false) {} else {%>',
' <label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<% }%>',
'<div class="<%=controlsClassName%>">',
' <select class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>"',
' name="<%=name%>" value="<%-value%>" <%=disabled ? "disabled" : ""%>',
' <%=required ? "required" : ""%><%= select2.multiple ? " multiple>" : ">" %>',
' <%=select2.first_empty ? " <option></option>" : ""%>',
' <% for (var i=0; i < options.length; i++) {%>',
' <% if (options[i].group) { %>',
' <% var group = options[i].group; %>',
' <% if (options[i].optval) { %> <% var option_length = options[i].optval.length; %>',
' <optgroup label="<%=group%>">',
' <% for (var subindex=0; subindex < option_length; subindex++) {%>',
' <% var option = options[i].optval[subindex]; %>',
' <option ',
' <% if (option.image) { %> data-image=<%=option.image%> <%}%>',
' <% if (option.connected) { %> data-connected=connected <%}%>',
' value=<%- formatter.fromRaw(option.value) %>',
' <% if (option.selected) {%>selected="selected"<%} else {%>',
' <% if (!select2.multiple && option.value === rawValue) {%>selected="selected"<%}%>',
' <% if (select2.multiple && rawValue && rawValue.indexOf(option.value) != -1){%>selected="selected" data-index="rawValue.indexOf(option.value)"<%}%>',
' <%}%>',
' <%= disabled ? "disabled" : ""%>><%-option.label%></option>',
' <%}%>',
' </optgroup>',
' <%}%>',
' <%} else {%>',
' <% var option = options[i]; %>',
' <option ',
' <% if (option.image) { %> data-image=<%=option.image%> <%}%>',
' <% if (option.connected) { %> data-connected=connected <%}%>',
' value=<%- formatter.fromRaw(option.value) %>',
' <% if (option.selected) {%>selected="selected"<%} else {%>',
' <% if (!select2.multiple && option.value === rawValue) {%>selected="selected"<%}%>',
' <% if (select2.multiple && rawValue && rawValue.indexOf(option.value) != -1){%>selected="selected" data-index="rawValue.indexOf(option.value)"<%}%>',
' <%}%>',
' <%= disabled ? "disabled" : ""%>><%-option.label%></option>',
' <%}%>',
' <%}%>',
' </select>',
' <% if (helpMessage && helpMessage.length) { %>',
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
' <% } %>',
'</div>',
].join('\n')),
beforeSelect: function() {
var selVal = arguments[0].params.args.data.id;
if(this.field.get('connect') && this.$el.find('option[value="'+selVal+'"]').attr('data-connected') !== 'connected') {
this.field.get('connect').apply(this, [selVal, this.changeIcon.bind(this)]);
} else {
$(this.$sel).trigger('change');
setTimeout(function(){ this.onChange.apply(this); }.bind(this), 200);
}
schema: [
{
id: 'server',
name: 'server',
label: gettext('Server'),
type: 'text',
editable: true,
disabled: false,
select2: {
allowClear: false,
width: 'style',
templateResult: formatNode,
templateSelection: formatNode,
},
changeIcon: function(data) {
let span = this.$el.find('.select2-selection .select2-selection__rendered span.wcTabIcon'),
selSpan = this.$el.find('option:selected');
if (span.hasClass('icon-server-not-connected') || span.hasClass('icon-shared-server-not-connected')) {
let icon = (data.icon) ? data.icon : 'icon-pg';
span.removeClass('icon-server-not-connected');
span.addClass(icon);
span.attr('data-connected', 'connected');
selSpan.data().image = icon;
selSpan.attr('data-connected', 'connected');
alertify.connectServer().destroy();
this.onChange.apply(this);
}
else if (span.hasClass('icon-database-not-connected')) {
let icon = (data.icon) ? data.icon : 'pg-icon-database';
span.removeClass('icon-database-not-connected');
span.addClass(icon);
span.attr('data-connected', 'connected');
selSpan.removeClass('icon-database-not-connected');
selSpan.data().image = icon;
selSpan.attr('data-connected', 'connected');
alertify.connectServer().destroy();
this.onChange.apply(this);
}
events: {
'focus select': 'clearInvalid',
'keydown :input': 'processTab',
'select2:select': 'onSelect',
'select2:selecting': 'beforeSelect',
'select2:clear': 'onChange',
},
connect: function(self) {
let local_self = self;
if(alertify.connectServer) {
delete alertify.connectServer;
transform: function(data) {
let group_template_options = [];
for (let key in data) {
if (data.hasOwnProperty(key)) {
group_template_options.push({'group': key, 'optval': data[key]});
}
}
return group_template_options;
},
control: Backform.Select2Control.extend({
template: _.template([
'<% if(label == false) {} else {%>',
' <label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<% }%>',
'<div class="<%=controlsClassName%>">',
' <select class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>"',
' name="<%=name%>" value="<%-value%>" <%=disabled ? "disabled" : ""%>',
' <%=required ? "required" : ""%><%= select2.multiple ? " multiple>" : ">" %>',
' <%=select2.first_empty ? " <option></option>" : ""%>',
' <% for (var i=0; i < options.length; i++) {%>',
' <% if (options[i].group) { %>',
' <% var group = options[i].group; %>',
' <% if (options[i].optval) { %> <% var option_length = options[i].optval.length; %>',
' <optgroup label="<%=group%>">',
' <% for (var subindex=0; subindex < option_length; subindex++) {%>',
' <% var option = options[i].optval[subindex]; %>',
' <option ',
' <% if (option.image) { %> data-image=<%=option.image%> <%}%>',
' <% if (option.connected) { %> data-connected=connected <%}%>',
' value=<%- formatter.fromRaw(option.value) %>',
' <% if (option.selected) {%>selected="selected"<%} else {%>',
' <% if (!select2.multiple && option.value === rawValue) {%>selected="selected"<%}%>',
' <% if (select2.multiple && rawValue && rawValue.indexOf(option.value) != -1){%>selected="selected" data-index="rawValue.indexOf(option.value)"<%}%>',
' <%}%>',
' <%= disabled ? "disabled" : ""%>><%-option.label%></option>',
' <%}%>',
' </optgroup>',
' <%}%>',
' <%} else {%>',
' <% var option = options[i]; %>',
' <option ',
' <% if (option.image) { %> data-image=<%=option.image%> <%}%>',
' <% if (option.connected) { %> data-connected=connected <%}%>',
' value=<%- formatter.fromRaw(option.value) %>',
' <% if (option.selected) {%>selected="selected"<%} else {%>',
' <% if (!select2.multiple && option.value === rawValue) {%>selected="selected"<%}%>',
' <% if (select2.multiple && rawValue && rawValue.indexOf(option.value) != -1){%>selected="selected" data-index="rawValue.indexOf(option.value)"<%}%>',
' <%}%>',
' <%= disabled ? "disabled" : ""%>><%-option.label%></option>',
' <%}%>',
' <%}%>',
' </select>',
' <% if (helpMessage && helpMessage.length) { %>',
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
' <% } %>',
'</div>',
].join('\n')),
beforeSelect: function() {
var selVal = arguments[0].params.args.data.id;
alertify.dialog('connectServer', function factory() {
return {
main: function(
title, message, server_id, submit_password=true, connect_server=null,
) {
this.set('title', title);
this.message = message;
this.server_id = server_id;
this.submit_password = submit_password;
this.connect_server = connect_server;
},
setup:function() {
return {
buttons:[{
text: gettext('Cancel'), className: 'btn btn-secondary fa fa-times pg-alertify-button',
key: 27,
},{
text: gettext('OK'), key: 13, className: 'btn btn-primary fa fa-check pg-alertify-button',
}],
focus: {element: '#password', select: true},
options: {
modal: 0, resizable: false, maximizable: false, pinnable: false,
},
};
},
build:function() {
},
prepare:function() {
this.setContent(this.message);
},
callback: function(closeEvent) {
var loadingDiv = $('#show_filter_progress');
if (closeEvent.button.text == gettext('OK')) {
if(this.submit_password) {
var _url = url_for('sqleditor.connect_server', {'sid': this.server_id});
if(this.field.get('connect') && this.$el.find('option[value="'+selVal+'"]').attr('data-connected') !== 'connected') {
this.field.get('connect').apply(this, [selVal, this.changeIcon.bind(this)]);
} else {
$(this.$sel).trigger('change');
setTimeout(function(){ this.onChange.apply(this); }.bind(this), 200);
}
},
changeIcon: function(data) {
let span = this.$el.find('.select2-selection .select2-selection__rendered span.wcTabIcon'),
selSpan = this.$el.find('option:selected');
loadingDiv.removeClass('d-none');
$.ajax({
type: 'POST',
timeout: 30000,
url: _url,
data: $('#frmPassword').serialize(),
})
.done(function(res) {
if (span.hasClass('icon-server-not-connected') || span.hasClass('icon-shared-server-not-connected')) {
let icon = (data.icon) ? data.icon : 'icon-pg';
span.removeClass('icon-server-not-connected');
span.addClass(icon);
span.attr('data-connected', 'connected');
local_self.model.attributes.database = null;
local_self.changeIcon(res.data);
local_self.model.attributes.user = null;
local_self.model.attributes.role = null;
Backform.Select2Control.prototype.onChange.apply(local_self, arguments);
Object.keys(response.server_list).forEach(key => {
response.server_list[key].forEach(option => {
if (option.value == local_self.getValueFromDOM()) {
response.server_name = option.label;
}
});
});
selSpan.data().image = icon;
selSpan.attr('data-connected', 'connected');
alertify.connectServer().destroy();
this.onChange.apply(this);
}
else if (span.hasClass('icon-database-not-connected')) {
let icon = (data.icon) ? data.icon : 'pg-icon-database';
loadingDiv.addClass('d-none');
alertify.connectServer().destroy();
span.removeClass('icon-database-not-connected');
span.addClass(icon);
span.attr('data-connected', 'connected');
selSpan.removeClass('icon-database-not-connected');
selSpan.data().image = icon;
selSpan.attr('data-connected', 'connected');
alertify.connectServer().destroy();
this.onChange.apply(this);
}
},
connect: function(self) {
let local_self = self;
if(alertify.connectServer) {
delete alertify.connectServer;
}
alertify.dialog('connectServer', function factory() {
return {
main: function(
title, message, server_id, submit_password=true, connect_server=null,
) {
this.set('title', title);
this.message = message;
this.server_id = server_id;
this.submit_password = submit_password;
this.connect_server = connect_server;
},
setup:function() {
return {
buttons:[{
text: gettext('Cancel'), className: 'btn btn-secondary fa fa-times pg-alertify-button',
key: 27,
},{
text: gettext('OK'), key: 13, className: 'btn btn-primary fa fa-check pg-alertify-button',
}],
focus: {element: '#password', select: true},
options: {
modal: 0, resizable: false, maximizable: false, pinnable: false,
},
};
},
build:function() {
},
prepare:function() {
this.setContent(this.message);
},
callback: function(closeEvent) {
var loadingDiv = $('#show_filter_progress');
if (closeEvent.button.text == gettext('OK')) {
if(this.submit_password) {
var _url = url_for('sqleditor.connect_server', {'sid': this.server_id});
loadingDiv.removeClass('d-none');
$.ajax({
type: 'POST',
timeout: 30000,
url: _url,
data: $('#frmPassword').serialize(),
})
.fail(function(xhr) {
loadingDiv.addClass('d-none');
alertify.connectServer().destroy();
alertify.connectServer('Connect to server', xhr.responseJSON.result, local_self.getValueFromDOM());
});
} else {
if(Object.keys(this.connect_server).length > 0) {
this.connect_server['password'] = $('#password').val();
this.connect_server['is_selected'] = false;
handler.gridView.on_change_connection(this.connect_server, conn_self, false);
loadingDiv = $('#fetching_data');
loadingDiv.addClass('d-none');
.done(function(res) {
local_self.model.attributes.database = null;
local_self.changeIcon(res.data);
local_self.model.attributes.user = null;
local_self.model.attributes.role = null;
Backform.Select2Control.prototype.onChange.apply(local_self, arguments);
Object.keys(response.server_list).forEach(key => {
response.server_list[key].forEach(option => {
if (option.value == local_self.getValueFromDOM()) {
response.server_name = option.label;
}
});
});
loadingDiv.addClass('d-none');
alertify.connectServer().destroy();
})
.fail(function(xhr) {
loadingDiv.addClass('d-none');
alertify.connectServer().destroy();
alertify.connectServer('Connect to server', xhr.responseJSON.result, local_self.getValueFromDOM());
});
} else {
response.password = $('#password').val();
loadingDiv.addClass('d-none');
if(Object.keys(this.connect_server).length > 0) {
this.connect_server['password'] = $('#password').val();
this.connect_server['is_selected'] = false;
handler.gridView.on_change_connection(this.connect_server, conn_self, false);
loadingDiv = $('#fetching_data');
loadingDiv.addClass('d-none');
} else {
response.password = $('#password').val();
loadingDiv.addClass('d-none');
}
}
} else {
local_self.model.attributes.database = null;
local_self.model.attributes.user = null;
local_self.model.attributes.role = null;
Backform.Select2Control.prototype.onChange.apply(local_self, arguments);
loadingDiv.addClass('d-none');
alertify.connectServer().destroy();
}
} else {
local_self.model.attributes.database = null;
local_self.model.attributes.user = null;
local_self.model.attributes.role = null;
Backform.Select2Control.prototype.onChange.apply(local_self, arguments);
loadingDiv.addClass('d-none');
alertify.connectServer().destroy();
}
closeEvent.close = true;
},
};
});
},
render: function() {
let self = this;
self.connect(self);
Object.keys(response.server_list).forEach(key => {
response.server_list[key].forEach(option => {
if (option.value == parseInt(sid)) {
response.server_name = option.label;
}
closeEvent.close = true;
},
};
});
});
var transform = self.field.get('transform') || self.defaults.transform;
if (transform && _.isFunction(transform)) {
self.field.set('options', transform.bind(self, response.server_list));
} else {
self.field.set('options', response.server_list);
}
return Backform.Select2Control.prototype.render.apply(self, arguments);
},
onChange: function() {
this.model.attributes.database = null;
this.model.attributes.user = null;
let self = this;
self.connect(self);
let url = url_for('sqleditor.connect_server', {
'sid': self.getValueFromDOM(),
'usr': self.model.attributes.user,
});
var loadingDiv = $('#show_filter_progress');
loadingDiv.removeClass('d-none');
$.ajax({
url: url,
type: 'POST',
headers: {
'Cache-Control' : 'no-cache',
},
}).done(function () {
Backform.Select2Control.prototype.onChange.apply(self, arguments);
},
render: function() {
let self = this;
self.connect(self);
Object.keys(response.server_list).forEach(key => {
response.server_list[key].forEach(option => {
if (option.value == self.getValueFromDOM()) {
if (option.value == parseInt(sid)) {
response.server_name = option.label;
}
});
});
loadingDiv.addClass('d-none');
}).fail(function(xhr){
loadingDiv.addClass('d-none');
alertify.connectServer('Connect to server', xhr.responseJSON.result, self.getValueFromDOM());
});
var transform = self.field.get('transform') || self.defaults.transform;
if (transform && _.isFunction(transform)) {
self.field.set('options', transform.bind(self, response.server_list));
} else {
self.field.set('options', response.server_list);
}
return Backform.Select2Control.prototype.render.apply(self, arguments);
},
onChange: function() {
this.model.attributes.database = null;
this.model.attributes.user = null;
let self = this;
self.connect(self);
let url = url_for('sqleditor.connect_server', {
'sid': self.getValueFromDOM(),
'usr': self.model.attributes.user,
});
var loadingDiv = $('#show_filter_progress');
loadingDiv.removeClass('d-none');
$.ajax({
url: url,
type: 'POST',
headers: {
'Cache-Control' : 'no-cache',
},
}).done(function () {
Backform.Select2Control.prototype.onChange.apply(self, arguments);
Object.keys(response.server_list).forEach(key => {
response.server_list[key].forEach(option => {
if (option.value == self.getValueFromDOM()) {
response.server_name = option.label;
}
});
});
loadingDiv.addClass('d-none');
}).fail(function(xhr){
loadingDiv.addClass('d-none');
alertify.connectServer('Connect to server', xhr.responseJSON.result, self.getValueFromDOM());
});
},
}),
},
{
id: 'database',
name: 'database',
label: gettext('Database'),
type: 'text',
editable: true,
disabled: function(m) {
let self_local = this;
if (!_.isUndefined(m.get('server')) && !_.isNull(m.get('server'))
&& m.get('server') !== '') {
setTimeout(function() {
if(self_local.options.length) {
m.set('database', self_local.options[0].value);
}
}, 10);
return false;
}
return true;
},
}),
},
{
id: 'database',
name: 'database',
label: gettext('Database'),
type: 'text',
editable: true,
disabled: function(m) {
let self_local = this;
if (!_.isUndefined(m.get('server')) && !_.isNull(m.get('server'))
deps: ['server'],
url: 'sqleditor.get_new_connection_database',
select2: {
allowClear: false,
width: '100%',
first_empty: true,
select_first: false,
},
extraClasses:['new-connection-dialog-style'],
control: NewConnectionSelect2Control,
transform: function(data) {
response.database_list = data;
return data;
},
},
{
id: 'user',
name: 'user',
label: gettext('User'),
type: 'text',
editable: true,
deps: ['server'],
select2: {
allowClear: false,
width: '100%',
},
control: NewConnectionSelect2Control,
url: 'sqleditor.get_new_connection_user',
disabled: function(m) {
let self_local = this;
if (!_.isUndefined(m.get('server')) && !_.isNull(m.get('server'))
&& m.get('server') !== '') {
setTimeout(function() {
if(self_local.options.length) {
m.set('database', self_local.options[0].value);
}
}, 10);
return false;
}
return true;
setTimeout(function() {
if(self_local.options.length) {
m.set('user', self_local.options[0].value);
}
}, 10);
return false;
}
return true;
},
},{
id: 'role',
name: 'role',
label: gettext('Role'),
type: 'text',
editable: true,
deps: ['server'],
select2: {
allowClear: false,
width: '100%',
first_empty: true,
},
control: NewConnectionSelect2Control,
url: 'sqleditor.get_new_connection_role',
disabled: false,
},
deps: ['server'],
url: 'sqleditor.get_new_connection_database',
select2: {
allowClear: false,
width: '100%',
first_empty: true,
select_first: false,
},
extraClasses:['new-connection-dialog-style'],
control: NewConnectionSelect2Control,
transform: function(data) {
response.database_list = data;
return data;
},
},
{
id: 'user',
name: 'user',
label: gettext('User'),
type: 'text',
editable: true,
deps: ['server'],
select2: {
allowClear: false,
width: '100%',
},
control: NewConnectionSelect2Control,
url: 'sqleditor.get_new_connection_user',
disabled: function(m) {
let self_local = this;
if (!_.isUndefined(m.get('server')) && !_.isNull(m.get('server'))
&& m.get('server') !== '') {
setTimeout(function() {
if(self_local.options.length) {
m.set('user', self_local.options[0].value);
}
}, 10);
return false;
}
return true;
},
},{
id: 'role',
name: 'role',
label: gettext('Role'),
type: 'text',
editable: true,
deps: ['server'],
select2: {
allowClear: false,
width: '100%',
first_empty: true,
},
control: NewConnectionSelect2Control,
url: 'sqleditor.get_new_connection_role',
disabled: false,
},
],
validate: function() {
let msg = null;