mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Re-organise node structure and loading to make things somewhat more
simple. This also adds the ability to display servers on the treeview.
This commit is contained in:
15
web/pgadmin/browser/server_groups/__init__.py
Normal file
15
web/pgadmin/browser/server_groups/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2015, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
# Node meta data
|
||||
NODE_TYPE = 'server-group'
|
||||
NODE_PATH = '/browser/nodes/' + NODE_TYPE
|
||||
|
||||
# Define the child node list
|
||||
sub_nodes = [ ]
|
||||
68
web/pgadmin/browser/server_groups/hooks.py
Normal file
68
web/pgadmin/browser/server_groups/hooks.py
Normal file
@@ -0,0 +1,68 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2015, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
"""Integration hooks for server groups."""
|
||||
|
||||
from flask import render_template, url_for
|
||||
from flask.ext.babel import gettext
|
||||
from flask.ext.security import current_user
|
||||
|
||||
from pgadmin.browser.utils import register_modules
|
||||
from pgadmin.settings.settings_model import db, ServerGroup
|
||||
|
||||
from pgadmin.browser import all_nodes
|
||||
from . import NODE_TYPE, sub_nodes
|
||||
|
||||
def register_submodules(app):
|
||||
"""Register any child node blueprints"""
|
||||
register_modules(app, __file__, all_nodes, sub_nodes, 'pgadmin.browser.server_groups')
|
||||
|
||||
def get_nodes():
|
||||
"""Return a JSON document listing the server groups for the user"""
|
||||
groups = ServerGroup.query.filter_by(user_id=current_user.id)
|
||||
|
||||
value = ''
|
||||
for group in groups:
|
||||
value += '{"id":"%s/%d","label":"%s","icon":"icon-%s","inode":true,"_type":"%s"},' % (NODE_TYPE, group.id, group.name, NODE_TYPE, NODE_TYPE)
|
||||
value = value[:-1]
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def get_file_menu_items():
|
||||
"""Return a (set) of dicts of file menu items, with name, priority, URL,
|
||||
target and onclick code."""
|
||||
return [
|
||||
{'name': 'mnu_add_server_group', 'label': gettext('Add a server group...'), 'priority': 10, 'url': '#', 'onclick': 'add_server_group()'},
|
||||
{'name': 'mnu_delete_server_group', 'label': gettext('Delete server group'), 'priority': 20, 'url': '#', 'onclick': 'delete_server_group()'},
|
||||
{'name': 'mnu_rename_server_group', 'label': gettext('Rename server group...'), 'priority': 30, 'url': '#', 'onclick': 'rename_server_group()'}
|
||||
]
|
||||
|
||||
|
||||
def get_context_menu_items():
|
||||
"""Return a (set) of dicts of content menu items with name, node type, label, priority and JS"""
|
||||
return [
|
||||
{'name': 'delete_server_group', 'type': NODE_TYPE, 'label': gettext('Delete server group'), 'priority': 10, 'onclick': 'delete_server_group(item);'},
|
||||
{'name': 'rename_server_group', 'type': NODE_TYPE, 'label': gettext('Rename server group...'), 'priority': 20, 'onclick': 'rename_server_group(item);'}
|
||||
]
|
||||
|
||||
|
||||
def get_script_snippets():
|
||||
"""Return the script snippets needed to handle treeview node operations."""
|
||||
return render_template('server_groups/server_groups.js')
|
||||
|
||||
|
||||
def get_css_snippets():
|
||||
"""Return the CSS needed to display the treeview node image."""
|
||||
css = ".icon-server-group {\n"
|
||||
css += " background: url('%s') 0 0 no-repeat !important;\n" % \
|
||||
url_for('NODE-%s.static' % NODE_TYPE, filename='img/server-group.png')
|
||||
css += "}\n"
|
||||
|
||||
return css
|
||||
16
web/pgadmin/browser/server_groups/servers/__init__.py
Normal file
16
web/pgadmin/browser/server_groups/servers/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2015, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
# Node meta data
|
||||
NODE_TYPE = 'server'
|
||||
NODE_PATH = '/browser/nodes/' + NODE_TYPE
|
||||
|
||||
# Define the child node list
|
||||
sub_nodes = [ ]
|
||||
|
||||
61
web/pgadmin/browser/server_groups/servers/hooks.py
Normal file
61
web/pgadmin/browser/server_groups/servers/hooks.py
Normal file
@@ -0,0 +1,61 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2015, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
"""Integration hooks for servers."""
|
||||
|
||||
from flask import render_template, url_for
|
||||
from flask.ext.babel import gettext
|
||||
from flask.ext.security import current_user
|
||||
|
||||
from pgadmin.settings.settings_model import db, Server
|
||||
from . import NODE_TYPE
|
||||
|
||||
def get_nodes(server_group):
|
||||
"""Return a JSON document listing the server groups for the user"""
|
||||
servers = Server.query.filter_by(user_id=current_user.id, servergroup_id=server_group)
|
||||
|
||||
value = ''
|
||||
for server in servers:
|
||||
value += '{"id":"%s/%d","label":"%s","icon":"icon-%s","inode":true,"_type":"%s"},' % (NODE_TYPE, server.id, server.name, NODE_TYPE, NODE_TYPE)
|
||||
value = value[:-1]
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def get_file_menu_items():
|
||||
"""Return a (set) of dicts of file menu items, with name, priority, URL,
|
||||
target and onclick code."""
|
||||
return [
|
||||
{'name': 'mnu_add_server', 'label': gettext('Add a server...'), 'priority': 50, 'url': '#', 'onclick': 'add_server()'},
|
||||
{'name': 'mnu_delete_server', 'label': gettext('Delete server'), 'priority': 60, 'url': '#', 'onclick': 'delete_server()'},
|
||||
{'name': 'mnu_rename_server', 'label': gettext('Rename server...'), 'priority': 70, 'url': '#', 'onclick': 'rename_server()'}
|
||||
]
|
||||
|
||||
|
||||
def get_context_menu_items():
|
||||
"""Return a (set) of dicts of content menu items with name, node type, label, priority and JS"""
|
||||
return [
|
||||
{'name': 'delete_server', 'type': NODE_TYPE, 'label': gettext('Delete server'), 'priority': 50, 'onclick': 'delete_server(item);'},
|
||||
{'name': 'rename_server', 'type': NODE_TYPE, 'label': gettext('Rename server...'), 'priority': 60, 'onclick': 'rename_server(item);'}
|
||||
]
|
||||
|
||||
|
||||
def get_script_snippets():
|
||||
"""Return the script snippets needed to handle treeview node operations."""
|
||||
return render_template('servers/servers.js')
|
||||
|
||||
|
||||
def get_css_snippets():
|
||||
"""Return the CSS needed to display the treeview node image."""
|
||||
css = ".icon-server {\n"
|
||||
css += " background: url('%s') 0 0 no-repeat !important;\n" % \
|
||||
url_for('NODE-%s.static' % NODE_TYPE, filename='img/server.png')
|
||||
css += "}\n"
|
||||
|
||||
return css
|
||||
BIN
web/pgadmin/browser/server_groups/servers/static/img/server.png
Normal file
BIN
web/pgadmin/browser/server_groups/servers/static/img/server.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 553 B |
@@ -0,0 +1,82 @@
|
||||
// Add a server
|
||||
function add_server() {
|
||||
var alert = alertify.prompt(
|
||||
'{{ _('Add a server') }}',
|
||||
'{{ _('Enter a name for the new server') }}',
|
||||
'',
|
||||
function(evt, value) {
|
||||
$.post("{{ url_for('NODE-server.add') }}", { name: value })
|
||||
.done(function(data) {
|
||||
if (data.success == 0) {
|
||||
report_error(data.errormsg, data.info);
|
||||
} else {
|
||||
var item = {
|
||||
id: data.data.id,
|
||||
label: data.data.name,
|
||||
inode: true,
|
||||
open: false,
|
||||
icon: 'icon-server'
|
||||
}
|
||||
|
||||
tree.append(null, {
|
||||
itemData: item
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
null
|
||||
);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
// Delete a server
|
||||
function delete_server(item) {
|
||||
alertify.confirm(
|
||||
'{{ _('Delete server?') }}',
|
||||
'{{ _('Are you sure you wish to delete the server "{0}"?') }}'.replace('{0}', tree.getLabel(item)),
|
||||
function() {
|
||||
var id = tree.getId(item)
|
||||
$.post("{{ url_for('NODE-server.delete') }}", { id: id })
|
||||
.done(function(data) {
|
||||
if (data.success == 0) {
|
||||
report_error(data.errormsg, data.info);
|
||||
} else {
|
||||
var next = tree.next(item);
|
||||
var prev = tree.prev(item);
|
||||
tree.remove(item);
|
||||
if (next.length) {
|
||||
tree.select(next);
|
||||
} else if (prev.length) {
|
||||
tree.select(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
// Rename a server
|
||||
function rename_server(item) {
|
||||
alertify.prompt(
|
||||
'{{ _('Rename server') }}',
|
||||
'{{ _('Enter a new name for the server') }}',
|
||||
tree.getLabel(item),
|
||||
function(evt, value) {
|
||||
var id = tree.getId(item)
|
||||
$.post("{{ url_for('NODE-server.rename') }}", { id: id, name: value })
|
||||
.done(function(data) {
|
||||
if (data.success == 0) {
|
||||
report_error(data.errormsg, data.info);
|
||||
} else {
|
||||
tree.setLabel(item, { label: value });
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
null
|
||||
)
|
||||
}
|
||||
117
web/pgadmin/browser/server_groups/servers/views.py
Normal file
117
web/pgadmin/browser/server_groups/servers/views.py
Normal file
@@ -0,0 +1,117 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2015, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
"""Defines views for management of servers"""
|
||||
|
||||
from flask import Blueprint, Response, current_app, request
|
||||
from flask.ext.babel import gettext
|
||||
from flask.ext.security import current_user, login_required
|
||||
|
||||
from . import NODE_TYPE, NODE_PATH
|
||||
from pgadmin.utils.ajax import make_json_response
|
||||
from pgadmin.settings.settings_model import db, ServerGroup
|
||||
import config
|
||||
|
||||
# Initialise the module
|
||||
blueprint = Blueprint("NODE-" + NODE_TYPE, __name__, static_folder='static', static_url_path='', template_folder='templates', url_prefix=NODE_PATH)
|
||||
|
||||
@blueprint.route('/add/', methods=['POST'])
|
||||
@login_required
|
||||
def add():
|
||||
"""Add a server node to the settings database"""
|
||||
success = 1
|
||||
errormsg = ''
|
||||
data = { }
|
||||
|
||||
if request.form['name'] != '':
|
||||
server = Server(user_id=current_user.id, name=request.form['name'])
|
||||
|
||||
try:
|
||||
db.session.add(server)
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
success = 0
|
||||
errormsg = e.message
|
||||
|
||||
else:
|
||||
success = 0
|
||||
errormsg = gettext('No server name was specified')
|
||||
|
||||
if success == 1:
|
||||
data['id'] = server.id
|
||||
data['name'] = server.name
|
||||
|
||||
return make_json_response(success=success,
|
||||
errormsg=errormsg,
|
||||
info=traceback.format_exc(),
|
||||
result=request.form,
|
||||
data=data)
|
||||
|
||||
@blueprint.route('/delete/', methods=['POST'])
|
||||
@login_required
|
||||
def delete():
|
||||
"""Delete a server node in the settings database"""
|
||||
success = 1
|
||||
errormsg = ''
|
||||
|
||||
if request.form['id'] != '':
|
||||
# There can be only one record at most
|
||||
servergroup = Server.query.filter_by(user_id=current_user.id, id=int(request.form['id'])).first()
|
||||
|
||||
if server is None:
|
||||
success = 0
|
||||
errormsg = gettext('The specified server could not be found.')
|
||||
else:
|
||||
try:
|
||||
db.session.delete(server)
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
success = 0
|
||||
errormsg = e.message
|
||||
|
||||
else:
|
||||
success = 0
|
||||
errormsg = gettext('No server was specified.')
|
||||
|
||||
return make_json_response(success=success,
|
||||
errormsg=errormsg,
|
||||
info=traceback.format_exc(),
|
||||
result=request.form)
|
||||
|
||||
@blueprint.route('/rename/', methods=['POST'])
|
||||
@login_required
|
||||
def rename():
|
||||
"""Rename a server node in the settings database"""
|
||||
success = 1
|
||||
errormsg = ''
|
||||
|
||||
if request.form['id'] != '':
|
||||
# There can be only one record at most
|
||||
servergroup = Server.query.filter_by(user_id=current_user.id, id=int(request.form['id'])).first()
|
||||
|
||||
if server is None:
|
||||
success = 0
|
||||
errormsg = gettext('The specified server could not be found.')
|
||||
else:
|
||||
try:
|
||||
server.name = request.form['name']
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
success = 0
|
||||
errormsg = e.message
|
||||
|
||||
else:
|
||||
success = 0
|
||||
errormsg = gettext('No server was specified.')
|
||||
|
||||
return make_json_response(success=success,
|
||||
errormsg=errormsg,
|
||||
info=traceback.format_exc(),
|
||||
result=request.form)
|
||||
|
||||
BIN
web/pgadmin/browser/server_groups/static/img/server-group.png
Normal file
BIN
web/pgadmin/browser/server_groups/static/img/server-group.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 504 B |
@@ -0,0 +1,82 @@
|
||||
// Add a server group
|
||||
function add_server_group() {
|
||||
var alert = alertify.prompt(
|
||||
'{{ _('Add a server group') }}',
|
||||
'{{ _('Enter a name for the new server group') }}',
|
||||
'',
|
||||
function(evt, value) {
|
||||
$.post("{{ url_for('NODE-server-group.add') }}", { name: value })
|
||||
.done(function(data) {
|
||||
if (data.success == 0) {
|
||||
report_error(data.errormsg, data.info);
|
||||
} else {
|
||||
var item = {
|
||||
id: data.data.id,
|
||||
label: data.data.name,
|
||||
inode: true,
|
||||
open: false,
|
||||
icon: 'icon-server-group'
|
||||
}
|
||||
|
||||
tree.append(null, {
|
||||
itemData: item
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
null
|
||||
);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
// Delete a server group
|
||||
function delete_server_group(item) {
|
||||
alertify.confirm(
|
||||
'{{ _('Delete server group?') }}',
|
||||
'{{ _('Are you sure you wish to delete the server group "{0}"?') }}'.replace('{0}', tree.getLabel(item)),
|
||||
function() {
|
||||
var id = tree.getId(item)
|
||||
$.post("{{ url_for('NODE-server-group.delete') }}", { id: id })
|
||||
.done(function(data) {
|
||||
if (data.success == 0) {
|
||||
report_error(data.errormsg, data.info);
|
||||
} else {
|
||||
var next = tree.next(item);
|
||||
var prev = tree.prev(item);
|
||||
tree.remove(item);
|
||||
if (next.length) {
|
||||
tree.select(next);
|
||||
} else if (prev.length) {
|
||||
tree.select(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
// Rename a server group
|
||||
function rename_server_group(item) {
|
||||
alertify.prompt(
|
||||
'{{ _('Rename server group') }}',
|
||||
'{{ _('Enter a new name for the server group') }}',
|
||||
tree.getLabel(item),
|
||||
function(evt, value) {
|
||||
var id = tree.getId(item)
|
||||
$.post("{{ url_for('NODE-server-group.rename') }}", { id: id, name: value })
|
||||
.done(function(data) {
|
||||
if (data.success == 0) {
|
||||
report_error(data.errormsg, data.info);
|
||||
} else {
|
||||
tree.setLabel(item, { label: value });
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
null
|
||||
)
|
||||
}
|
||||
139
web/pgadmin/browser/server_groups/views.py
Normal file
139
web/pgadmin/browser/server_groups/views.py
Normal file
@@ -0,0 +1,139 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2015, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
"""Defines views for management of server groups"""
|
||||
|
||||
from flask import Blueprint, Response, current_app, request
|
||||
from flask.ext.babel import gettext
|
||||
from flask.ext.security import current_user, login_required
|
||||
|
||||
from . import NODE_TYPE, NODE_PATH, sub_nodes
|
||||
from pgadmin.utils.ajax import make_json_response
|
||||
from pgadmin.settings.settings_model import db, ServerGroup
|
||||
import config
|
||||
|
||||
# Initialise the module
|
||||
blueprint = Blueprint("NODE-" + NODE_TYPE, __name__, static_folder='static', static_url_path='', template_folder='templates', url_prefix=NODE_PATH)
|
||||
|
||||
@blueprint.route("/<server_group>")
|
||||
@login_required
|
||||
def get_nodes(server_group):
|
||||
"""Build a list of treeview nodes from the child nodes."""
|
||||
value = '['
|
||||
|
||||
for node in sub_nodes:
|
||||
if 'hooks' in dir(node) and 'get_nodes' in dir(node.hooks):
|
||||
value += node.hooks.get_nodes(server_group) + ','
|
||||
|
||||
if value[-1:] == ',':
|
||||
value = value[:-1]
|
||||
|
||||
value += ']'
|
||||
|
||||
resp = Response(response=value,
|
||||
status=200,
|
||||
mimetype="text/json")
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
@blueprint.route('/add/', methods=['POST'])
|
||||
@login_required
|
||||
def add():
|
||||
"""Add a server group node to the settings database"""
|
||||
success = 1
|
||||
errormsg = ''
|
||||
data = { }
|
||||
|
||||
if request.form['name'] != '':
|
||||
servergroup = ServerGroup(user_id=current_user.id, name=request.form['name'])
|
||||
|
||||
try:
|
||||
db.session.add(servergroup)
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
success = 0
|
||||
errormsg = e.message
|
||||
|
||||
else:
|
||||
success = 0
|
||||
errormsg = gettext('No server group name was specified')
|
||||
|
||||
if success == 1:
|
||||
data['id'] = servergroup.id
|
||||
data['name'] = servergroup.name
|
||||
|
||||
return make_json_response(success=success,
|
||||
errormsg=errormsg,
|
||||
info=traceback.format_exc(),
|
||||
result=request.form,
|
||||
data=data)
|
||||
|
||||
@blueprint.route('/delete/', methods=['POST'])
|
||||
@login_required
|
||||
def delete():
|
||||
"""Delete a server group node in the settings database"""
|
||||
success = 1
|
||||
errormsg = ''
|
||||
|
||||
if request.form['id'] != '':
|
||||
# There can be only one record at most
|
||||
servergroup = ServerGroup.query.filter_by(user_id=current_user.id, id=int(request.form['id'])).first()
|
||||
|
||||
if servergroup is None:
|
||||
success = 0
|
||||
errormsg = gettext('The specified server group could not be found.')
|
||||
else:
|
||||
try:
|
||||
db.session.delete(servergroup)
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
success = 0
|
||||
errormsg = e.message
|
||||
|
||||
else:
|
||||
success = 0
|
||||
errormsg = gettext('No server group was specified.')
|
||||
|
||||
return make_json_response(success=success,
|
||||
errormsg=errormsg,
|
||||
info=traceback.format_exc(),
|
||||
result=request.form)
|
||||
|
||||
@blueprint.route('/rename/', methods=['POST'])
|
||||
@login_required
|
||||
def rename():
|
||||
"""Rename a server group node in the settings database"""
|
||||
success = 1
|
||||
errormsg = ''
|
||||
|
||||
if request.form['id'] != '':
|
||||
# There can be only one record at most
|
||||
servergroup = ServerGroup.query.filter_by(user_id=current_user.id, id=int(request.form['id'])).first()
|
||||
|
||||
if servergroup is None:
|
||||
success = 0
|
||||
errormsg = gettext('The specified server group could not be found.')
|
||||
else:
|
||||
try:
|
||||
servergroup.name = request.form['name']
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
success = 0
|
||||
errormsg = e.message
|
||||
|
||||
else:
|
||||
success = 0
|
||||
errormsg = gettext('No server group was specified.')
|
||||
|
||||
return make_json_response(success=success,
|
||||
errormsg=errormsg,
|
||||
info=traceback.format_exc(),
|
||||
result=request.form)
|
||||
|
||||
Reference in New Issue
Block a user