diff --git a/web/pgadmin/browser/templates/browser/js/browser.js b/web/pgadmin/browser/templates/browser/js/browser.js index 575ffeb7a..9f3d248cc 100644 --- a/web/pgadmin/browser/templates/browser/js/browser.js +++ b/web/pgadmin/browser/templates/browser/js/browser.js @@ -128,16 +128,7 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) { }, // We also support showing dashboards, HTML file, external URL frames: { - // Dashboard - 'dashboard': new pgAdmin.Browser.Frame({ - name: 'dashboard', - title: '{{ _('Dashboard') }}', - icon: 'fa fa-tachometer', - width: 500, - isCloseable: false, - isPrivate: true, - url: 'about:blank' // http://www.pgadmin.org' - })/* Add hooked-in frames by extensions */{% for panel_item in current_app.panels %}{% if panel_item.isIframe %}, + /* Add hooked-in frames by extensions */{% for panel_item in current_app.panels %}{% if panel_item.isIframe %} '{{ panel_item.name }}' : new pgAdmin.Browser.Frame({ name: '{{ panel_item.name }}', title: '{{ panel_item.title }}', @@ -148,7 +139,7 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) { isCloseable: {% if panel_item.isCloseable %}true{% else %}false{% endif %}, isPrivate: {% if panel_item.isPrivate %}true{% else %}false{% endif %}, url: '{{ panel_item.content }}' - }){% endif %}{% endfor %} + }),{% endif %}{% endfor %} }, /* Menus */ // pgAdmin.Browser.MenuItem.add_menus(...) will register all the menus diff --git a/web/pgadmin/dashboard/__init__.py b/web/pgadmin/dashboard/__init__.py new file mode 100644 index 000000000..c18b92098 --- /dev/null +++ b/web/pgadmin/dashboard/__init__.py @@ -0,0 +1,100 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +"""A blueprint module implementing the dashboard frame.""" +MODULE_NAME = 'dashboard' + +from config import PG_DEFAULT_DRIVER +from flask import render_template, url_for, Response +from flask.ext.babel import gettext +from flask.ext.security import login_required +from pgadmin.utils import PgAdminModule +from pgadmin.utils.ajax import precondition_required +from pgadmin.utils.driver import get_driver +from pgadmin.utils.menu import Panel + + +class DashboardModule(PgAdminModule): + def __init__(self, *args, **kwargs): + super(DashboardModule, self).__init__(*args, **kwargs) + + def get_own_menuitems(self): + return {} + + def get_own_javascripts(self): + return [{ + 'name': 'pgadmin.dashboard', + 'path': url_for('dashboard.index') + 'dashboard', + 'when': None + }] + + def get_panels(self): + return [ + Panel( + name='dashboard', + priority=1, + title=gettext('Dashboard'), + icon='fa fa-tachometer', + content=url_for('dashboard.index'), + isCloseable=False, + isPrivate=True) + ] + + +blueprint = DashboardModule(MODULE_NAME, __name__) + + +def check_precondition(f): + """ + This function will behave as a decorator which will check + database connection before running view, it also adds + manager, conn & template_path properties to self + """ + + @wraps(f) + def wrap(**kwargs): + # Here args[0] will hold self & kwargs will hold gid,sid,did + manager = get_driver(PG_DEFAULT_DRIVER).connection_manager( + kwargs['sid'] + ) + conn = manager.connection(did=kwargs['did'] if 'did' in kwargs and kwargs['did'] != 0 else None) + # If DB not connected then return error to browser + if not conn.connected(): + return precondition_required( + gettext( + "Connection to the server has been lost!" + ) + ) + + return f(obj, **kwargs) + + return wrap + + +@blueprint.route("/dashboard.js") +@login_required +def script(): + """render the required javascript""" + return Response(response=render_template("dashboard/js/dashboard.js", _=gettext), + status=200, + mimetype="application/javascript") + + +@blueprint.route('/') +@blueprint.route('/') +@blueprint.route('//') +@login_required +def index(sid=None, did=None): + # Show the appropriate dashboard based on the identifiers passed to us + if sid is None and did is None: + return render_template('/dashboard/welcome_dashboard.html') + if did is None: + return render_template('/dashboard/server_dashboard.html', sid=sid) + else: + return render_template('/dashboard/database_dashboard.html', sid=sid, did=did) diff --git a/web/pgadmin/dashboard/static/css/dashboard.css b/web/pgadmin/dashboard/static/css/dashboard.css new file mode 100644 index 000000000..e69de29bb diff --git a/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html new file mode 100644 index 000000000..5d3ec30c6 --- /dev/null +++ b/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html @@ -0,0 +1,4 @@ +

Server Dashboard

+ +Server ID: {{ sid }}
+Database ID: {{ did }} \ No newline at end of file diff --git a/web/pgadmin/dashboard/templates/dashboard/js/dashboard.js b/web/pgadmin/dashboard/templates/dashboard/js/dashboard.js new file mode 100644 index 000000000..d51e6f394 --- /dev/null +++ b/web/pgadmin/dashboard/templates/dashboard/js/dashboard.js @@ -0,0 +1,84 @@ +define(['jquery', 'pgadmin', 'underscore', 'wcdocker', 'pgadmin.browser', 'bootstrap'], + function($, pgAdmin, _) { + + var wcDocker = window.wcDocker, + pgBrowser = pgAdmin.Browser; + + /* Return back, this has been called more than once */ + if (pgAdmin.Dashboard) + return; + + pgAdmin.Dashboard = { + init: function() { + if (this.initialized) + return; + + this.initialized = true; + + // Bind the Dashboard object with the 'object_selected' function + var selected = this.object_selected.bind(this); + + // Listen for selection of any of object + pgBrowser.Events.on('pgadmin-browser:tree:selected', selected); + }, + + object_selected: function(item, itemData, node) { + var treeHierarchy = node.getTreeNodeHierarchy(item) + if (itemData && itemData._type) + { + switch(itemData._type) { + case ('server-group'): + url = '{{ url_for('dashboard.index') }}'; + break; + + case ('server'): + case ('coll-database'): + case ('coll-role'): + case ('role'): + case ('coll-tablespace'): + case ('tablespace'): + url = '{{ url_for('dashboard.index') }}' + + treeHierarchy.server._id; + break; + + default: + url = '{{ url_for('dashboard.index') }}' + + treeHierarchy.server._id + + '/' + treeHierarchy.database._id; + break; + } + } + + var dashboardPanel = pgBrowser.frames['dashboard'].panel; + if (dashboardPanel) { + var frame = $(dashboardPanel).data('embeddedFrame'); + + if (frame) { + // Avoid unnecessary reloads + if (_.isUndefined(treeHierarchy.server) || _.isUndefined(treeHierarchy.server._id)) + sid = -1 + else + sid = treeHierarchy.server._id + + if (_.isUndefined(treeHierarchy.database) || _.isUndefined(treeHierarchy.database._id)) + did = -1 + else + did = treeHierarchy.database._id + + if (sid != $(dashboardPanel).data('sid') || + did != $(dashboardPanel).data('did')) { + frame.openURL(url); + + // Cache the current IDs for next time + $(dashboardPanel).data('sid', sid) + $(dashboardPanel).data('did', did) + } + } + } + } + }; + + return pgAdmin.Dashboard; +}); + + diff --git a/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html new file mode 100644 index 000000000..0f7ce31b6 --- /dev/null +++ b/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html @@ -0,0 +1,3 @@ +

Server Dashboard

+ +Server ID: {{ sid }}
diff --git a/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html new file mode 100644 index 000000000..e94f3f656 --- /dev/null +++ b/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html @@ -0,0 +1 @@ +

Welcome Dashboard

\ No newline at end of file