mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Properly refresh the parent node when renaming children. Fixes #2355
This commit is contained in:
parent
9e98ded06c
commit
0bc9997a95
@ -605,17 +605,44 @@ class DatabaseView(PGChildNodeView):
|
|||||||
# used for offline updates
|
# used for offline updates
|
||||||
self.manager.release(conn_id="db_offline_update")
|
self.manager.release(conn_id="db_offline_update")
|
||||||
|
|
||||||
|
# Fetch the new data again after update for proper node
|
||||||
|
# generation
|
||||||
|
status, rset = self.conn.execute_dict(
|
||||||
|
render_template(
|
||||||
|
"/".join([self.template_path, 'nodes.sql']),
|
||||||
|
did=did, conn=self.conn, last_system_oid=0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=rset)
|
||||||
|
|
||||||
|
if len(rset['rows']) == 0:
|
||||||
|
return gone(
|
||||||
|
_("Could not find the database on the server.")
|
||||||
|
)
|
||||||
|
|
||||||
|
res = rset['rows'][0]
|
||||||
|
|
||||||
|
canDrop = canDisConn = True
|
||||||
|
if self.manager.db == res['name']:
|
||||||
|
canDrop = canDisConn = False
|
||||||
|
|
||||||
return jsonify(
|
return jsonify(
|
||||||
node=self.blueprint.generate_browser_node(
|
node=self.blueprint.generate_browser_node(
|
||||||
did,
|
did,
|
||||||
sid,
|
sid,
|
||||||
data['name'],
|
res['name'],
|
||||||
"pg-icon-{0}".format(self.node_type) if
|
icon="pg-icon-{0}".format(self.node_type) if
|
||||||
self._db['datallowconn'] else
|
self._db['datallowconn'] and self.conn.connected() else
|
||||||
"icon-database-not-connected",
|
"icon-database-not-connected",
|
||||||
connected=self.conn.connected() if
|
connected=self.conn.connected() if
|
||||||
self._db['datallowconn'] else False,
|
self._db['datallowconn'] else False,
|
||||||
allowConn=self._db['datallowconn']
|
tablespace=res['spcname'],
|
||||||
|
allowConn=res['datallowconn'],
|
||||||
|
canCreate=res['cancreate'],
|
||||||
|
canDisconn=canDisConn,
|
||||||
|
canDrop=canDrop,
|
||||||
|
inode=True if res['datallowconn'] else False
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1107,7 +1107,8 @@ function(
|
|||||||
}
|
}
|
||||||
}.bind(ctx),
|
}.bind(ctx),
|
||||||
deleteNode = function() {
|
deleteNode = function() {
|
||||||
var pI = this.pI,
|
var self = this,
|
||||||
|
pI = this.pI,
|
||||||
findParent = function() {
|
findParent = function() {
|
||||||
if (pI.length) {
|
if (pI.length) {
|
||||||
pI.pop();
|
pI.pop();
|
||||||
@ -1128,35 +1129,134 @@ function(
|
|||||||
}
|
}
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
|
var _item_parent = (this.i
|
||||||
|
&& this.t.hasParent(this.i)
|
||||||
|
&& this.t.parent(this.i)) || null,
|
||||||
|
_item_grand_parent = _item_parent ?
|
||||||
|
(this.t.hasParent(_item_parent)
|
||||||
|
&& this.t.parent(_item_parent))
|
||||||
|
: null;
|
||||||
|
|
||||||
// Remove the current node first.
|
// Remove the current node first.
|
||||||
if (
|
if (
|
||||||
this.i && this.d && this.old._id == this.d._id &&
|
this.i && this.d && this.old._id == this.d._id &&
|
||||||
this.old._type == this.d._type
|
this.old._type == this.d._type
|
||||||
) {
|
) {
|
||||||
this.t.remove(this.i);
|
var _parent = this.t.parent(this.i) || null;
|
||||||
|
|
||||||
// Find the parent
|
// If there is no parent then just update the node
|
||||||
findParent();
|
if(_parent.length == 0 && ctx.op == 'UPDATE') {
|
||||||
var _parentData = this.d;
|
updateNode();
|
||||||
// Find the grand-parent, or the collection node of parent.
|
} else {
|
||||||
findParent();
|
var postRemove = function() {
|
||||||
|
// If item has parent but no grand parent
|
||||||
|
if (_item_parent && !_item_grand_parent) {
|
||||||
|
var parent = null;
|
||||||
|
// We need to search in all parent siblings (eg: server groups)
|
||||||
|
parents = this.t.siblings(this.i) || [];
|
||||||
|
parents.push(this.i[0])
|
||||||
|
_.each(parents, function (p) {
|
||||||
|
var d = self.t.itemData($(p));
|
||||||
|
// If new server group found then assign it parent
|
||||||
|
if(d._id == self.new._pid) {
|
||||||
|
parent = p;
|
||||||
|
self.pI.push({coll: true, item: parent, d: d});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (this.i) {
|
if (parent) {
|
||||||
this.load = true;
|
this.load = true;
|
||||||
|
|
||||||
this.success = function() {
|
this.success = function() {
|
||||||
addItemNode();
|
addItemNode();
|
||||||
|
}.bind(this);
|
||||||
|
// We can refresh the collection node, but - let's not bother about
|
||||||
|
// it right now.
|
||||||
|
this.notFound = errorOut;
|
||||||
|
|
||||||
|
var _d = {_id: this.new._pid, _type: self.d._type}
|
||||||
|
parent = $(parent),
|
||||||
|
loaded = this.t.wasLoad(parent),
|
||||||
|
onLoad = function() {
|
||||||
|
self.i = parent;
|
||||||
|
self.d = self.d;
|
||||||
|
self.pI.push({coll: false, item: parent, d: self.d});
|
||||||
|
self.success();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!loaded && self.load) {
|
||||||
|
self.t.open(parent, {
|
||||||
|
success: onLoad,
|
||||||
|
unanimated: true,
|
||||||
|
fail: function() {
|
||||||
|
var fail = self && self.o && self.o.fail;
|
||||||
|
|
||||||
|
if (
|
||||||
|
fail && typeof(fail) == 'function'
|
||||||
|
) {
|
||||||
|
fail.apply(self.t, []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
onLoad();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// This is for rest of the nodes
|
||||||
|
var _parentData = this.d;
|
||||||
|
// Find the grand-parent, or the collection node of parent.
|
||||||
|
findParent();
|
||||||
|
|
||||||
|
if (this.i) {
|
||||||
|
this.load = true;
|
||||||
|
|
||||||
|
this.success = function() {
|
||||||
|
addItemNode();
|
||||||
|
}.bind(this);
|
||||||
|
// We can refresh the collection node, but - let's not bother about
|
||||||
|
// it right now.
|
||||||
|
this.notFound = errorOut;
|
||||||
|
|
||||||
|
// Find the new parent
|
||||||
|
this.b._findTreeChildNode(
|
||||||
|
this.i, {_id: this.new._pid, _type: _parentData._type}, this
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
addItemNode();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
// We can refresh the collection node, but - let's not bother about
|
|
||||||
// it right now.
|
|
||||||
this.notFound = errorOut;
|
|
||||||
|
|
||||||
// Find the new parent
|
// If there is a parent then we can remove the node
|
||||||
this.b._findTreeChildNode(
|
this.t.remove(this.i, {
|
||||||
this.i, {_id: this.new._pid, _type: _parentData._type}, this
|
success: function() {
|
||||||
);
|
// Find the parent
|
||||||
}
|
findParent();
|
||||||
return;
|
// If server group have no children then close it and set inode
|
||||||
|
// and unload it so it can fetch new data on next expand
|
||||||
|
if (_item_parent && !_item_grand_parent && _parent
|
||||||
|
&& self.t.children(_parent).length == 0) {
|
||||||
|
self.t.setInode(_parent, {
|
||||||
|
success: function() {
|
||||||
|
self.t.unload(_parent, {success: function() {
|
||||||
|
setTimeout(postRemove);
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setTimeout(postRemove);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
errorOut();
|
errorOut();
|
||||||
|
|
||||||
@ -1221,22 +1321,17 @@ function(
|
|||||||
node_data._id = _id = this.new._id;
|
node_data._id = _id = this.new._id;
|
||||||
}
|
}
|
||||||
if (this.new._id == _id) {
|
if (this.new._id == _id) {
|
||||||
// Found the currect
|
// Found the current
|
||||||
_.extend(this.d, this.new._id);
|
_.extend(this.d, {
|
||||||
|
'_id': this.new._id,
|
||||||
|
'_label': this.new._label,
|
||||||
|
'label': this.new.label
|
||||||
|
});
|
||||||
this.t.setLabel(ctx.i, {label: this.new.label});
|
this.t.setLabel(ctx.i, {label: this.new.label});
|
||||||
this.t.addIcon(ctx.i, {icon: this.new.icon});
|
this.t.addIcon(ctx.i, {icon: this.new.icon});
|
||||||
this.t.setId(ctx.id, {id: this.new.id});
|
this.t.setId(ctx.i, {id: this.new.id});
|
||||||
|
this.t.openPath(this.i);
|
||||||
// if label is different then we need to
|
this.t.deselect(this.i);
|
||||||
// refresh parent so that node get properly
|
|
||||||
// placed in tree
|
|
||||||
if(this.d.label != this.new.label) {
|
|
||||||
var p = this.t.parent(this.i);
|
|
||||||
pgAdmin.Browser.onRefreshTreeNode(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.t.openPath(self.i);
|
|
||||||
self.t.deselect(self.i);
|
|
||||||
|
|
||||||
// select tree item after few milliseconds
|
// select tree item after few milliseconds
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
@ -1306,7 +1401,7 @@ function(
|
|||||||
d = ctx.t.itemData(i);
|
d = ctx.t.itemData(i);
|
||||||
if (
|
if (
|
||||||
pgAdmin.natural_sort(
|
pgAdmin.natural_sort(
|
||||||
d._label, _data._label
|
d._label, _new._label
|
||||||
) == 1
|
) == 1
|
||||||
)
|
)
|
||||||
return true;
|
return true;
|
||||||
@ -1325,7 +1420,7 @@ function(
|
|||||||
d = ctx.t.itemData(i);
|
d = ctx.t.itemData(i);
|
||||||
if (
|
if (
|
||||||
pgAdmin.natural_sort(
|
pgAdmin.natural_sort(
|
||||||
d._label, _data._label
|
d._label, _new._label
|
||||||
) != -1
|
) != -1
|
||||||
)
|
)
|
||||||
return true;
|
return true;
|
||||||
@ -1333,14 +1428,14 @@ function(
|
|||||||
d = ctx.t.itemData(i);
|
d = ctx.t.itemData(i);
|
||||||
if (
|
if (
|
||||||
pgAdmin.natural_sort(
|
pgAdmin.natural_sort(
|
||||||
d._label, _data._label
|
d._label, _new._label
|
||||||
) != 1
|
) != 1
|
||||||
)
|
)
|
||||||
return true;
|
return true;
|
||||||
m = s + Math.round((e - s) / 2);
|
m = s + Math.round((e - s) / 2);
|
||||||
i = items.eq(m);
|
i = items.eq(m);
|
||||||
d = ctx.t.itemData(i);
|
d = ctx.t.itemData(i);
|
||||||
var res = pgAdmin.natural_sort(d._label, _data._label);
|
var res = pgAdmin.natural_sort(d._label, _new._label);
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -1359,6 +1454,9 @@ function(
|
|||||||
ctx.t.before(i, {
|
ctx.t.before(i, {
|
||||||
itemData: _new,
|
itemData: _new,
|
||||||
success: function() {
|
success: function() {
|
||||||
|
var new_item = $(arguments[1].items[0]);
|
||||||
|
ctx.t.openPath(new_item);
|
||||||
|
ctx.t.select(new_item);
|
||||||
if (
|
if (
|
||||||
ctx.o && ctx.o.success && typeof(ctx.o.success) == 'function'
|
ctx.o && ctx.o.success && typeof(ctx.o.success) == 'function'
|
||||||
) {
|
) {
|
||||||
@ -1378,6 +1476,9 @@ function(
|
|||||||
ctx.t.append(ctx.i, {
|
ctx.t.append(ctx.i, {
|
||||||
itemData: _new,
|
itemData: _new,
|
||||||
success: function() {
|
success: function() {
|
||||||
|
var new_item = $(arguments[1].items[0]);
|
||||||
|
ctx.t.openPath(new_item);
|
||||||
|
ctx.t.select(new_item);
|
||||||
if (
|
if (
|
||||||
ctx.o && ctx.o.success && typeof(ctx.o.success) == 'function'
|
ctx.o && ctx.o.success && typeof(ctx.o.success) == 'function'
|
||||||
) {
|
) {
|
||||||
@ -1435,7 +1536,17 @@ function(
|
|||||||
ctx.pI.push(_old);
|
ctx.pI.push(_old);
|
||||||
_new._label = _new.label;
|
_new._label = _new.label;
|
||||||
_new.label = _.escape(_new.label);
|
_new.label = _.escape(_new.label);
|
||||||
if (_old._pid != _new._pid) {
|
|
||||||
|
// We need to check if this is collection node and have
|
||||||
|
// children count, if yes then add count with label too
|
||||||
|
if(ctx.b.Nodes[_new._type].is_collection) {
|
||||||
|
if ('collection_count' in _old && _old['collection_count'] > 0) {
|
||||||
|
_new.label = _.escape(_new._label) +
|
||||||
|
' <span>(' + _old['collection_count'] + ')</span>'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_old._pid != _new._pid || _old._label != _new._label) {
|
||||||
ctx.op = 'RECREATE';
|
ctx.op = 'RECREATE';
|
||||||
traversePath();
|
traversePath();
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user