mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Allow to create sub-menu/menu-group by specify the same category in
multiple menu-items (not just the 'create' menu-group). Moved all the main menu/context menu generation implementation in the 'menu' javascript menu. In this implementation, if more than one menu-items specify same type of categories, they will be created withing that group, otherwise - it will be created separately (unless 'single' property of that category is set to true). We can also provide icon, priority, separator(s) above/below it for the individual sub-menu too using pgAdmin.Browser.add_menu_category function(...).
This commit is contained in:
@@ -4,7 +4,9 @@ function(_, pgAdmin, $) {
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
pgAdmin.Browser = pgAdmin.Browser || {};
|
pgAdmin.Browser = pgAdmin.Browser || {};
|
||||||
pgAdmin.Browser.MenuItem = function(opts) {
|
|
||||||
|
// Individual menu-item class
|
||||||
|
var MenuItem = pgAdmin.Browser.MenuItem = function(opts) {
|
||||||
var menu_opts = [
|
var menu_opts = [
|
||||||
'name', 'label', 'priority', 'module', 'callback', 'data', 'enable',
|
'name', 'label', 'priority', 'module', 'callback', 'data', 'enable',
|
||||||
'category', 'target', 'url', 'icon'
|
'category', 'target', 'url', 'icon'
|
||||||
@@ -18,7 +20,32 @@ function(_, pgAdmin, $) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
_.extend(pgAdmin.Browser.MenuItem.prototype, {
|
_.extend(pgAdmin.Browser.MenuItem.prototype, {
|
||||||
|
/*
|
||||||
|
* Keeps track of the jQuery object representing this menu-item. This will
|
||||||
|
* be used by the update function to enable/disable the individual item.
|
||||||
|
*/
|
||||||
|
$el: null,
|
||||||
|
/*
|
||||||
|
* Generate the UI for this menu-item. enable/disable, based on the
|
||||||
|
* currently selected object.
|
||||||
|
*/
|
||||||
generate: function(node, item) {
|
generate: function(node, item) {
|
||||||
|
this.create_el(node, item);
|
||||||
|
|
||||||
|
this.context = {
|
||||||
|
name: this.label,
|
||||||
|
icon: this.icon || this.module && (this.module.type),
|
||||||
|
disabled: this.is_disabled,
|
||||||
|
callback: this.context_menu_callback.bind(this, item)
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.$el;
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the jquery element for the menu-item.
|
||||||
|
*/
|
||||||
|
create_el: function(node, item) {
|
||||||
var url = $('<a></a>', {
|
var url = $('<a></a>', {
|
||||||
'id': this.name,
|
'id': this.name,
|
||||||
'href': this.url,
|
'href': this.url,
|
||||||
@@ -29,15 +56,68 @@ function(_, pgAdmin, $) {
|
|||||||
cb: this.callback,
|
cb: this.callback,
|
||||||
data: this.data
|
data: this.data
|
||||||
}).addClass('menu-link');
|
}).addClass('menu-link');
|
||||||
|
|
||||||
if (this.icon) {
|
if (this.icon) {
|
||||||
url.append($('<i></i>', {'class': this.icon}));
|
url.append($('<i></i>', {'class': this.icon}));
|
||||||
}
|
}
|
||||||
url.append($('<span></span>').text(' ' + this.label));
|
url.append($('<span></span>').text(' ' + this.label));
|
||||||
|
|
||||||
return $('<li/>')
|
this.is_disabled = this.disabled(node, item);
|
||||||
.addClass('menu-item' + (this.disabled(node, item) ? ' disabled' : ''))
|
this.$el = $('<li/>')
|
||||||
|
.addClass('menu-item' + (this.is_disabled ? ' disabled' : ''))
|
||||||
.append(url);
|
.append(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Updates the enable/disable state of the menu-item based on the current
|
||||||
|
* selection using the disabled function. This also creates a object
|
||||||
|
* for this menu, which can be used in the context-menu.
|
||||||
|
*/
|
||||||
|
update: function(node, item) {
|
||||||
|
|
||||||
|
if (!this.$el.hasClass('disabled')) {
|
||||||
|
this.$el.addClass('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.is_disabled = this.disabled(node, item);
|
||||||
|
if (!this.is_disabled) {
|
||||||
|
this.$el.removeClass('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context = {
|
||||||
|
name: this.label,
|
||||||
|
icon: this.icon || (this.module && this.module.type),
|
||||||
|
disabled: this.is_disabled,
|
||||||
|
callback: this.context_menu_callback.bind(this, item)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This will be called when context-menu is clicked.
|
||||||
|
*/
|
||||||
|
context_menu_callback: function(item) {
|
||||||
|
var o = this, cb;
|
||||||
|
|
||||||
|
if (o.module['callbacks'] && (
|
||||||
|
o.callback in o.module['callbacks']
|
||||||
|
)) {
|
||||||
|
cb = o.module['callbacks'][o.callback];
|
||||||
|
} else if (o.callback in o.module) {
|
||||||
|
cb = o.module[o.callback];
|
||||||
|
}
|
||||||
|
if (cb) {
|
||||||
|
cb.apply(o.module, [o.data, item]);
|
||||||
|
} else {
|
||||||
|
pgAdmin.Browser.report_error(
|
||||||
|
S('Developer Warning: Callback - "%s" not found!').
|
||||||
|
sprintf(o.cb).value()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks this menu enable/disable state based on the selection.
|
||||||
|
*/
|
||||||
disabled: function(node, item) {
|
disabled: function(node, item) {
|
||||||
if (this.enable == undefined)
|
if (this.enable == undefined)
|
||||||
return false;
|
return false;
|
||||||
@@ -51,6 +131,179 @@ function(_, pgAdmin, $) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This a class for creating a menu group, mainly used by the submenu
|
||||||
|
* creation logic.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 1. Options to render the submenu DOM Element.
|
||||||
|
* i.e. label, icon, above (separator), below (separator)
|
||||||
|
* 2. List of menu-items comes under this submenu.
|
||||||
|
* 3. Did we rendered separator after the menu-item/submenu?
|
||||||
|
* 4. A unique-id for this menu-item.
|
||||||
|
*
|
||||||
|
* Returns a object, similar to the menu-item, which has his own jQuery
|
||||||
|
* Element, context menu representing object, etc.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
pgAdmin.Browser.MenuGroup = function(opts, items, prev, ctx) {
|
||||||
|
var template = _.template([
|
||||||
|
'<% if (above) { %><hr><% } %>',
|
||||||
|
'<li class="menu-item dropdown dropdown-submenu">',
|
||||||
|
' <a href="#" class="dropdown-toggle" data-toggle="dropdown">',
|
||||||
|
' <% if (icon) { %><i class="<%= icon %>"></i><% } %>',
|
||||||
|
' <span><%= label %></span>',
|
||||||
|
' </a>',
|
||||||
|
' <ul class="dropdown-menu navbar-inverse">',
|
||||||
|
' </ul>',
|
||||||
|
'</li>',
|
||||||
|
'<% if (below) { %><hr><% } %>',].join('\n')),
|
||||||
|
data = {
|
||||||
|
'label': opts.label,
|
||||||
|
'icon': opts.icon,
|
||||||
|
'above': opts.above && !prev,
|
||||||
|
'below': opts.below,
|
||||||
|
}, m,
|
||||||
|
$el = $(template(data)),
|
||||||
|
$menu = $el.find('.dropdown-menu'),
|
||||||
|
submenus = {},
|
||||||
|
ctxId = 1;
|
||||||
|
|
||||||
|
ctx = _.uniqueId(ctx + '_sub_');
|
||||||
|
|
||||||
|
// Sort by alphanumeric ordered first
|
||||||
|
items.sort(function(a, b) {return a.label.localeCompare(b.label);});
|
||||||
|
// Sort by priority
|
||||||
|
items.sort(function(a, b) {return a.priority - b.priority;});
|
||||||
|
|
||||||
|
for (var idx in items) {
|
||||||
|
m = items[idx];
|
||||||
|
$menu.append(m.$el);
|
||||||
|
if (!m.is_disabled) {
|
||||||
|
submenus[ctx + ctxId] = m.context
|
||||||
|
}
|
||||||
|
ctxId++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var is_disabled = (_.size(submenus) == 0);
|
||||||
|
|
||||||
|
return {
|
||||||
|
$el: $el,
|
||||||
|
priority: opts.priority || 10,
|
||||||
|
label: opts.label,
|
||||||
|
above: data['above'],
|
||||||
|
below: opts.below,
|
||||||
|
is_disabled: is_disabled,
|
||||||
|
context: {
|
||||||
|
name: opts.label,
|
||||||
|
icon: opts.icon,
|
||||||
|
items: submenus,
|
||||||
|
disabled: is_disabled
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A function to generate menus (submenus) based on the categories.
|
||||||
|
* Attach the current selected browser tree node to each of the generated
|
||||||
|
* menu-items.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 1. jQuery Element on which you may want to created the menus
|
||||||
|
* 2. list of menu-items
|
||||||
|
* 3. categories - metadata information about the categories, based on which
|
||||||
|
* the submenu (menu-group) will be created (if any).
|
||||||
|
* 4. d - Data object for the selected browser tree item.
|
||||||
|
* 5. item - The selected browser tree item
|
||||||
|
* 6. menu_items - A empty object on which the context menu for the given
|
||||||
|
* list of menu-items.
|
||||||
|
*
|
||||||
|
* Returns if any menu generated for the given input.
|
||||||
|
*/
|
||||||
|
pgAdmin.Browser.MenuCreator = function($mnu, menus, categories, d, item, menu_items) {
|
||||||
|
var groups = {'common': []},
|
||||||
|
common, idx = 0, j, item,
|
||||||
|
ctxId = _.uniqueId('ctx_'),
|
||||||
|
update_menuitem = function(m) {
|
||||||
|
if (m instanceof MenuItem) {
|
||||||
|
if (m.$el) {
|
||||||
|
m.$el.remove();
|
||||||
|
delete m.$el;
|
||||||
|
}
|
||||||
|
m.generate(d, item);
|
||||||
|
var group = groups[m.category || 'common'] =
|
||||||
|
groups[m.category || 'common'] || [];
|
||||||
|
group.push(m);
|
||||||
|
} else {
|
||||||
|
for (var key in m) {
|
||||||
|
update_menuitem(m[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, ctxIdx = 1;
|
||||||
|
|
||||||
|
for (idx in menus) {
|
||||||
|
update_menuitem(menus[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not all menu creator requires the context menu structure.
|
||||||
|
menu_items = menu_items || {};
|
||||||
|
|
||||||
|
common = groups['common'];
|
||||||
|
delete groups['common'];
|
||||||
|
|
||||||
|
var prev = true;
|
||||||
|
|
||||||
|
for (name in groups) {
|
||||||
|
var g = groups[name],
|
||||||
|
c = categories[name] || {'label': name, single: false},
|
||||||
|
menu_group = pgAdmin.Browser.MenuGroup(c, g, prev, ctxId);
|
||||||
|
|
||||||
|
if (g.length <= 1 && !c.single) {
|
||||||
|
prev = false;
|
||||||
|
for (idx in g) {
|
||||||
|
common.push(g[idx]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prev = g.below;
|
||||||
|
common.push(menu_group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The menus will be created based on the priority given.
|
||||||
|
// Menu with lowest value has the highest priority. If the priority is
|
||||||
|
// same, then - it will be ordered by label.
|
||||||
|
// Sort by alphanumeric ordered first
|
||||||
|
common.sort(function(a, b) {return a.label.localeCompare(b.label);});
|
||||||
|
// Sort by priority
|
||||||
|
common.sort(function(a, b) {return a.priority - b.priority;});
|
||||||
|
var len = _.size(common);
|
||||||
|
|
||||||
|
for (idx in common) {
|
||||||
|
item = common[idx];
|
||||||
|
|
||||||
|
item.priority = (item.priority || 10);
|
||||||
|
$mnu.append(item.$el);
|
||||||
|
var prefix = ctxId + '_' + item.priority + '_' + ctxIdx;
|
||||||
|
|
||||||
|
if (ctxIdx != 1 && item.above && !item.is_disabled) {
|
||||||
|
// For creatign the seprator any string will do.
|
||||||
|
menu_items[prefix + '_ma'] = '----';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item.is_disabled) {
|
||||||
|
menu_items[prefix + '_ms'] = item.context;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxId != len && item.below && !item.is_disabled) {
|
||||||
|
menu_items[prefix + '_mz'] = '----';
|
||||||
|
}
|
||||||
|
ctxIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (len > 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// MENU PUBLIC CLASS DEFINITION
|
// MENU PUBLIC CLASS DEFINITION
|
||||||
// ==============================
|
// ==============================
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
height: 1.3em;
|
height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pgadmin-node-select option[node="{{node_type}}"] {
|
.pgadmin-node-select option[node="{{node_type}}"] {
|
||||||
|
|||||||
@@ -44,22 +44,9 @@ try {
|
|||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">{{ _('Edit') }} <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">{{ _('Edit') }} <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu navbar-inverse" role="menu"></ul>
|
<ul class="dropdown-menu navbar-inverse" role="menu"></ul>
|
||||||
</li>
|
</li>
|
||||||
<li id="mnu_obj" class="dropdown hide">
|
<li id="mnu_obj" class="dropdown ">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">{{ _('Object') }} <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">{{ _('Object') }} <span class="caret"></span></a>
|
||||||
<ul id="mnu_dropdown_obj" class="dropdown-menu navbar-inverse" role="menu">
|
<ul class="dropdown-menu navbar-inverse" role="menu"></ul>
|
||||||
<li id="mnu_create_dropdown_obj" class="menu-item dropdown dropdown-submenu">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
|
||||||
<i class="fa fa-magic"></i>
|
|
||||||
<span>{{ _('Create') }}</span>
|
|
||||||
</a>
|
|
||||||
<ul id="mnu_create_obj" class="dropdown-menu navbar-inverse">
|
|
||||||
<li class="menu-item">
|
|
||||||
<a href="#">Link 1</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<hr/>
|
|
||||||
</ul>
|
|
||||||
</li>
|
</li>
|
||||||
<li id="mnu_management" class="dropdown hide">
|
<li id="mnu_management" class="dropdown hide">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">{{ _('Management') }} <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">{{ _('Management') }} <span class="caret"></span></a>
|
||||||
|
|||||||
@@ -160,6 +160,18 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) {
|
|||||||
// Help menus
|
// Help menus
|
||||||
help: {}
|
help: {}
|
||||||
},
|
},
|
||||||
|
menu_categories: {
|
||||||
|
/* name, label (pair) */
|
||||||
|
'create': {
|
||||||
|
label: '{{ _('Create')|safe }}',
|
||||||
|
priority: 1,
|
||||||
|
/* separator above this menu */
|
||||||
|
above: false,
|
||||||
|
below: true,
|
||||||
|
icon: 'fa fa-magic',
|
||||||
|
single: true
|
||||||
|
}
|
||||||
|
},
|
||||||
// A callback to load/fetch a script when a certain node is loaded
|
// A callback to load/fetch a script when a certain node is loaded
|
||||||
register_script: function(n, m, p) {
|
register_script: function(n, m, p) {
|
||||||
var scripts = this.scripts;
|
var scripts = this.scripts;
|
||||||
@@ -189,16 +201,22 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) {
|
|||||||
// menu navigation bar
|
// menu navigation bar
|
||||||
navbar = $('#navbar-menu > ul').first(),
|
navbar = $('#navbar-menu > ul').first(),
|
||||||
// Drop down menu for objects
|
// Drop down menu for objects
|
||||||
obj_mnu = navbar.find('li#mnu_obj > ul#mnu_dropdown_obj').first(),
|
$obj_mnu = navbar.find('li#mnu_obj > ul.dropdown-menu').first(),
|
||||||
// Drop down menu for create object
|
|
||||||
create_mnu = navbar.find("#mnu_create_obj").empty(),
|
|
||||||
// data for current selected object
|
// data for current selected object
|
||||||
d = this.tree.itemData(item);
|
d = obj.tree.itemData(item),
|
||||||
|
update_menuitem = function(m) {
|
||||||
|
if (m instanceof pgAdmin.Browser.MenuItem) {
|
||||||
|
m.update(d, item);
|
||||||
|
} else {
|
||||||
|
for (var key in m) {
|
||||||
|
update_menuitem(m[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// All menus from the object menus (except the create drop-down
|
// All menus from the object menus (except the create drop-down
|
||||||
// menu) needs to be removed.
|
// menu) needs to be removed.
|
||||||
obj_mnu.children("li:not(:first-child)").remove();
|
$obj_mnu.empty();
|
||||||
// Create a dummy 'no object seleted' menu
|
|
||||||
create_mnu.html('<li class="menu-item disabled"><a href="#">{{ _('No object selected') }}</a></li>\n');
|
|
||||||
|
|
||||||
// All menus (except for the object menus) are already present.
|
// All menus (except for the object menus) are already present.
|
||||||
// They will just require to check, wheather they are
|
// They will just require to check, wheather they are
|
||||||
@@ -209,40 +227,28 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) {
|
|||||||
{m: 'management', id: '#mnu_management'},
|
{m: 'management', id: '#mnu_management'},
|
||||||
{m: 'tools', id: '#mnu_tools'},
|
{m: 'tools', id: '#mnu_tools'},
|
||||||
{m: 'help', id:'#mnu_help'}], function(o) {
|
{m: 'help', id:'#mnu_help'}], function(o) {
|
||||||
j = navbar.children(o.id).children('.dropdown-menu').first();
|
_.each(
|
||||||
_.each(obj.menus[o.m],
|
obj.menus[o.m],
|
||||||
function(v, k) {
|
function(m, k) {
|
||||||
// Remove disabled class in any case first.
|
update_menuitem(m);
|
||||||
e = j.find('#' + k).closest('.menu-item').removeClass('disabled');
|
|
||||||
if (v.disabled(d, item)) {
|
|
||||||
// Make this menu disabled
|
|
||||||
e.addClass('disabled');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create the object menu dynamically
|
// Create the object menu dynamically
|
||||||
if (item && this.menus['object'] && this.menus['object'][d._type]) {
|
if (item && obj.menus['object'] && obj.menus['object'][d._type]) {
|
||||||
var create_items = [];
|
pgAdmin.Browser.MenuCreator(
|
||||||
// The menus will be created based on the priority given.
|
$obj_mnu, obj.menus['object'][d._type], obj.menu_categories, d, item
|
||||||
// Menu with lowest value has the highest priority.
|
)
|
||||||
_.each(_.sortBy(
|
|
||||||
this.menus['object'][d._type],
|
|
||||||
function(o) { return o.priority; }),
|
|
||||||
function(m) {
|
|
||||||
if (m.category && m.category == 'create') {
|
|
||||||
create_items.push(m.generate(d, item));
|
|
||||||
} else {
|
} else {
|
||||||
obj_mnu.append(m.generate(d, item));
|
// Create a dummy 'no object seleted' menu
|
||||||
}
|
create_submenu = pgAdmin.Browser.MenuGroup(
|
||||||
});
|
obj.menu_categories['create'], [{
|
||||||
// Create menus goes seperately
|
$el: $('<li class="menu-item disabled"><a href="#">{{ _("No object selected") }}</a></li>'),
|
||||||
if (create_items.length > 0) {
|
priority: 1,
|
||||||
create_mnu.empty();
|
category: 'create',
|
||||||
_.each(create_items, function(c) {
|
update: function() {}
|
||||||
create_mnu.append(c);
|
}], false);
|
||||||
});
|
$obj_mnu.append(create_submenu.$el);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
init: function() {
|
init: function() {
|
||||||
@@ -347,66 +353,22 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) {
|
|||||||
// Build the treeview context menu
|
// Build the treeview context menu
|
||||||
$('#tree').contextMenu({
|
$('#tree').contextMenu({
|
||||||
selector: '.aciTreeLine',
|
selector: '.aciTreeLine',
|
||||||
|
autoHide: false,
|
||||||
build: function(element) {
|
build: function(element) {
|
||||||
var item = obj.tree.itemFrom(element),
|
var item = obj.tree.itemFrom(element),
|
||||||
menu = { },
|
|
||||||
createMenu = { },
|
|
||||||
d = obj.tree.itemData(item),
|
d = obj.tree.itemData(item),
|
||||||
menus = obj.menus['context'][d._type],
|
menus = obj.menus['context'][d._type],
|
||||||
cb = function(name) {
|
$div = $('<div></div>'),
|
||||||
var o = undefined;
|
context_menu = {};
|
||||||
|
|
||||||
_.each(menus, function(m) {
|
pgAdmin.Browser.MenuCreator(
|
||||||
if (name == (m.module.type + '_' + m.name)) {
|
$div, menus, obj.menu_categories, d, item, context_menu
|
||||||
o = m;
|
);
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (o) {
|
return {
|
||||||
var cb;
|
autoHide: false,
|
||||||
if (o.module['callbacks'] && (
|
items: context_menu
|
||||||
o.callback in o.module['callbacks'])) {
|
|
||||||
cb = o.module['callbacks'][o.callback];
|
|
||||||
} else if (o.callback in o.module) {
|
|
||||||
cb = o.module[o.callback];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cb) {
|
|
||||||
cb.apply(o.module, [o.data, item]);
|
|
||||||
} else {
|
|
||||||
pgAdmin.Browser.report_error(
|
|
||||||
S('Developer Warning: Callback - "%s" not found!').
|
|
||||||
sprintf(o.cb).value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_.each(
|
|
||||||
_.sortBy(menus, function(m) { return m.priority; }),
|
|
||||||
function(m) {
|
|
||||||
if (m.category == 'create' && !m.disabled(d, item)) {
|
|
||||||
createMenu[m.module.type + '_' + m.name] = { name: m.label, icon: m.icon || m.module.type };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (_.size(createMenu)) {
|
|
||||||
menu["create"] = { name: "{{ _('Create') }}", icon: 'fa fa-magic' };
|
|
||||||
menu["create"]["items"] = createMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
_.each(
|
|
||||||
_.sortBy(menus, function(m) { return m.priority; }),
|
|
||||||
function(m) {
|
|
||||||
if (m.category != 'create' && !m.disabled(d, item)) {
|
|
||||||
menu[m.module.type + '_' + m.name] = { name: m.label, icon: m.icon };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return _.size(menu) ? {
|
|
||||||
autoHide: true,
|
|
||||||
items: menu,
|
|
||||||
callback: cb
|
|
||||||
} : {};
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -529,6 +491,7 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) {
|
|||||||
{% endif %}{% if item.url %}url: "{{ item.url }}",
|
{% endif %}{% if item.url %}url: "{{ item.url }}",
|
||||||
{% endif %}{% if item.target %}target: "{{ item.target }}",
|
{% endif %}{% if item.target %}target: "{{ item.target }}",
|
||||||
{% endif %}{% if item.callback %}callback: "{{ item.callback }}",
|
{% endif %}{% if item.callback %}callback: "{{ item.callback }}",
|
||||||
|
{% endif %}{% if item.category %}category: "{{ item.category }}",
|
||||||
{% endif %}{% if item.icon %}icon: '{{ item.icon }}',
|
{% endif %}{% if item.icon %}icon: '{{ item.icon }}',
|
||||||
{% endif %}{% if item.data %}data: {{ item.data }},
|
{% endif %}{% if item.data %}data: {{ item.data }},
|
||||||
{% endif %}label: '{{ item.label }}', applies: ['{{ key.lower() }}'],
|
{% endif %}label: '{{ item.label }}', applies: ['{{ key.lower() }}'],
|
||||||
@@ -577,6 +540,18 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) {
|
|||||||
'{{ _('Error loading script - ') }}' + path);
|
'{{ _('Error loading script - ') }}' + path);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
add_menu_category: function(
|
||||||
|
id, label, priority, icon, above_separator, below_separator, single
|
||||||
|
) {
|
||||||
|
this.menu_categories[id] = {
|
||||||
|
label: label,
|
||||||
|
priority: priority,
|
||||||
|
icon: icon,
|
||||||
|
above: (above_separator === true),
|
||||||
|
below: (below_separator === true),
|
||||||
|
single: single
|
||||||
|
}
|
||||||
|
},
|
||||||
// Add menus of module/extension at appropriate menu
|
// Add menus of module/extension at appropriate menu
|
||||||
add_menus: function(menus) {
|
add_menus: function(menus) {
|
||||||
var pgMenu = this.menus;
|
var pgMenu = this.menus;
|
||||||
@@ -591,7 +566,10 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) {
|
|||||||
pgMenu[a] = pgMenu[a] || {};
|
pgMenu[a] = pgMenu[a] || {};
|
||||||
if (_.isString(m.node)) {
|
if (_.isString(m.node)) {
|
||||||
menus = pgMenu[a][m.node] = pgMenu[a][m.node] || {};
|
menus = pgMenu[a][m.node] = pgMenu[a][m.node] || {};
|
||||||
} else {
|
} else if (_.isString(m.category)) {
|
||||||
|
menus = pgMenu[a][m.category] = pgMenu[a][m.category] || {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
menus = pgMenu[a];
|
menus = pgMenu[a];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,6 +601,7 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) {
|
|||||||
},
|
},
|
||||||
// Create the menus
|
// Create the menus
|
||||||
create_menus: function() {
|
create_menus: function() {
|
||||||
|
|
||||||
/* Create menus */
|
/* Create menus */
|
||||||
var navbar = $('#navbar-menu > ul').first();
|
var navbar = $('#navbar-menu > ul').first();
|
||||||
var obj = this;
|
var obj = this;
|
||||||
@@ -632,17 +611,21 @@ function(require, $, _, S, Bootstrap, pgAdmin, alertify, CodeMirror) {
|
|||||||
{menu: 'edit', id: '#mnu_edit'},
|
{menu: 'edit', id: '#mnu_edit'},
|
||||||
{menu: 'management', id: '#mnu_management'},
|
{menu: 'management', id: '#mnu_management'},
|
||||||
{menu: 'tools', id: '#mnu_tools'},
|
{menu: 'tools', id: '#mnu_tools'},
|
||||||
{menu: 'help', id:'#mnu_help'}], function(o) {
|
{menu: 'help', id:'#mnu_help'}],
|
||||||
var j = navbar.children(o.id).children('.dropdown-menu').first().empty();
|
function(o) {
|
||||||
_.each(
|
var $mnu = navbar.children(o.id).first(),
|
||||||
_.sortBy(obj.menus[o.menu],
|
$dropdown = $mnu.children('.dropdown-menu').first();
|
||||||
function(v, k) { return v.priority; }),
|
$dropdown.empty();
|
||||||
function(v) {
|
var menus = {};
|
||||||
j.closest('.dropdown').removeClass('hide');
|
|
||||||
j.append(v.generate());
|
if (pgAdmin.Browser.MenuCreator(
|
||||||
|
$dropdown, obj.menus[o.menu], obj.menu_categories
|
||||||
|
)) {
|
||||||
|
$mnu.removeClass('hide');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
navbar.children('#mnu_obj').removeClass('hide');
|
navbar.children('#mnu_obj').removeClass('hide');
|
||||||
});
|
|
||||||
obj.enable_disable_menus();
|
obj.enable_disable_menus();
|
||||||
},
|
},
|
||||||
messages: {
|
messages: {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ function($, _, S, pgAdmin, Backbone, Alertify, Backform) {
|
|||||||
pgAdmin.Browser.add_menus([{
|
pgAdmin.Browser.add_menus([{
|
||||||
name: 'refresh', node: this.type, module: this,
|
name: 'refresh', node: this.type, module: this,
|
||||||
applies: ['object', 'context'], callback: 'refresh',
|
applies: ['object', 'context'], callback: 'refresh',
|
||||||
priority: 1, label: '{{ _("Refresh...") }}',
|
priority: 2, label: '{{ _("Refresh...") }}',
|
||||||
icon: 'fa fa-refresh'
|
icon: 'fa fa-refresh'
|
||||||
}]);
|
}]);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"""Browser integration functions for the Test module."""
|
"""Browser integration functions for the Test module."""
|
||||||
MODULE_NAME = 'test'
|
MODULE_NAME = 'test'
|
||||||
from flask.ext.security import login_required
|
from flask.ext.security import login_required
|
||||||
from flask import render_template, url_for, current_app
|
from flask import url_for, current_app
|
||||||
from flask.ext.babel import gettext
|
from flask.ext.babel import gettext
|
||||||
from pgadmin.utils import PgAdminModule
|
from pgadmin.utils import PgAdminModule
|
||||||
from pgadmin.utils.menu import MenuItem
|
from pgadmin.utils.menu import MenuItem
|
||||||
@@ -22,32 +22,37 @@ class TestModule(PgAdminModule):
|
|||||||
return {'file_items': [
|
return {'file_items': [
|
||||||
MenuItem(name='mnu_generate_test_html',
|
MenuItem(name='mnu_generate_test_html',
|
||||||
label=gettext('Generated Test HTML'),
|
label=gettext('Generated Test HTML'),
|
||||||
priority=100,
|
priority=2,
|
||||||
url=url_for('test.generated')),
|
url=url_for('test.generated')),
|
||||||
MenuItem(name='mnu_test_alert',
|
MenuItem(name='mnu_test_alert',
|
||||||
label=gettext('Test Alert'),
|
label=gettext('Test Alert'),
|
||||||
priority=200,
|
priority=200,
|
||||||
module='pgAdmin.Test',
|
module='pgAdmin.Test',
|
||||||
|
category=gettext('alertify'),
|
||||||
callback='test_alert'),
|
callback='test_alert'),
|
||||||
MenuItem(name='mnu_test_confirm',
|
MenuItem(name='mnu_test_confirm',
|
||||||
label=gettext('Test Confirm'),
|
label=gettext('Test Confirm'),
|
||||||
priority=300,
|
priority=300,
|
||||||
module='pgAdmin.Test',
|
module='pgAdmin.Test',
|
||||||
|
category=gettext('alertify'),
|
||||||
callback='test_confirm'),
|
callback='test_confirm'),
|
||||||
MenuItem(name='mnu_test_dialog',
|
MenuItem(name='mnu_test_dialog',
|
||||||
label=gettext('Test Dialog'),
|
label=gettext('Test Dialog'),
|
||||||
priority=400,
|
priority=400,
|
||||||
module='pgAdmin.Test',
|
module='pgAdmin.Test',
|
||||||
|
category=gettext('alertify'),
|
||||||
callback='test_dialog'),
|
callback='test_dialog'),
|
||||||
MenuItem(name='mnu_test_prompt',
|
MenuItem(name='mnu_test_prompt',
|
||||||
label=gettext('Test Prompt'),
|
label=gettext('Test Prompt'),
|
||||||
priority=500,
|
priority=500,
|
||||||
module='pgAdmin.Test',
|
module='pgAdmin.Test',
|
||||||
|
category=gettext('alertify'),
|
||||||
callback='test_prompt'),
|
callback='test_prompt'),
|
||||||
MenuItem(name='mnu_test_notifier',
|
MenuItem(name='mnu_test_notifier',
|
||||||
label=gettext('Test Notifier'),
|
label=gettext('Test Notifier'),
|
||||||
priority=600,
|
priority=600,
|
||||||
module='pgAdmin.Test',
|
module='pgAdmin.Test',
|
||||||
|
category=gettext('alertify'),
|
||||||
callback='test_notifier'),
|
callback='test_notifier'),
|
||||||
MenuItem(name='mnu_test_disabled',
|
MenuItem(name='mnu_test_disabled',
|
||||||
label=gettext('Test Disabled'),
|
label=gettext('Test Disabled'),
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ define(
|
|||||||
function($, alertify, pgAdmin, pgServer, ServerGroup) {
|
function($, alertify, pgAdmin, pgServer, ServerGroup) {
|
||||||
pgAdmin = pgAdmin || window.pgAdmin || {};
|
pgAdmin = pgAdmin || window.pgAdmin || {};
|
||||||
|
|
||||||
|
if (pgAdmin.Test)
|
||||||
|
return pgAdmin.Test;
|
||||||
|
|
||||||
pgAdmin.Test = {
|
pgAdmin.Test = {
|
||||||
test_alert: function() {
|
test_alert: function() {
|
||||||
alertify.alert(
|
alertify.alert(
|
||||||
@@ -66,8 +69,17 @@ define(
|
|||||||
|
|
||||||
alertify.myAlert('Dialog Test 2',
|
alertify.myAlert('Dialog Test 2',
|
||||||
'This is another test dialog from Alertify!', 'This is dialog 2');
|
'This is another test dialog from Alertify!', 'This is dialog 2');
|
||||||
}
|
},
|
||||||
};
|
init: function() {
|
||||||
|
if (this.initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.initialized = true;
|
||||||
|
|
||||||
|
// Add the alertify category
|
||||||
|
pgAdmin.Browser.add_menu_category(
|
||||||
|
'alertify', 'Alertify', 3, 'fa fa-film', true, true
|
||||||
|
);
|
||||||
|
|
||||||
pgServer.on(
|
pgServer.on(
|
||||||
'server-connected', function() {
|
'server-connected', function() {
|
||||||
@@ -80,5 +92,8 @@ define(
|
|||||||
console.log('I know that the server-group has been expanded!');
|
console.log('I know that the server-group has been expanded!');
|
||||||
}, pgAdmin.Test);
|
}, pgAdmin.Test);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return pgAdmin.Test;
|
return pgAdmin.Test;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user