Improvement in the look and feel of the whole application

Changed the SCSS/CSS for the below third party libraries to adopt the
new look 'n' feel:
- wcDocker
- Alertify dialogs, and notifications
- AciTree
- Bootstrap Navbar
- Bootstrap Tabs
- Bootstrap Drop-Down menu
- Backgrid
- Select2

Adopated the new the look 'n' feel for the dialogs, wizard, properties,
tab panels, tabs, fieldset, subnode control, spinner control, HTML
table, and other form controls.

- Font is changed to Roboto
- Using SCSS variables to define the look 'n' feel
- Designer background images for the Login, and Forget password pages in
  'web' mode
- Improved the look 'n' feel for the key selection in the preferences
  dialog
- Table classes consistency changes across the application
- File Open and Save dialog list view changes

Author(s): Aditya Toshniwal & Khushboo Vashi
This commit is contained in:
Ashesh Vashi
2018-12-21 17:14:55 +05:30
parent a000dc6f60
commit 5799ac14ba
135 changed files with 5030 additions and 3878 deletions

View File

@@ -97,7 +97,7 @@
"underscore": "^1.8.3",
"underscore.string": "^3.3.4",
"watchify": "~3.9.0",
"webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#5fbdf05a6757464d2fa2c2b017322c97688b2105",
"webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#25f6fda624c5469340da0c111a18545a4455973a",
"wkx": "^0.4.5"
},
"scripts": {

View File

@@ -203,7 +203,7 @@ define('pgadmin.node.fts_configuration', [
' </div>',
' <div class="col-6" header="token"></div>',
' <div class="col-2">',
' <button class="btn btn-sm-sq btn-default add fa fa-plus" <%=canAdd ? "" : "disabled=\'disabled\'"%> ></button>',
' <button class="btn btn-sm-sq btn-secondary add fa fa-plus" <%=canAdd ? "" : "disabled=\'disabled\'"%> ></button>',
' </div>',
' </div>',
' </div>',

View File

@@ -104,9 +104,7 @@ class FunctionModule(SchemaChildModule):
"""
Returns a snippet of css
"""
snippets = [
render_template("function/css/function.css")
]
snippets = []
snippets.extend(
super(SchemaChildModule, self).csssnippets
)

View File

@@ -1,3 +0,0 @@
.functions_code {
height: 130px !important;
}

View File

@@ -389,15 +389,12 @@ define('pgadmin.node.exclusion_constraint', [
generateHeader: function(data) {
var header = [
'<div class="subnode-header-form">',
' <div class="container-fluid">',
' <div>',
' <div class="row">',
' <div class="col-4">',
' <label class="control-label"><%-column_label%></label>',
' </div>',
' <div class="col-4" header="column"></div>',
' <div class="col-4">',
' <button class="btn btn-sm-sq btn-default add fa fa-plus" <%=canAdd ? "" : "disabled=\'disabled\'"%> ></button>',
' </div>',
' </div>',
' </div>',
'</div>'].join('\n');
@@ -441,11 +438,15 @@ define('pgadmin.node.exclusion_constraint', [
showGridControl: function(data) {
var self = this,
titleTmpl = _.template('<div class=\'subnode-header\'></div>'),
titleTmpl = _.template([
'<div class="subnode-header">',
' <label class="control-label pg-el-sm-10"><%-label%></label>',
' <button class="btn btn-sm-sq btn-secondary add fa fa-plus" <%=canAdd ? "" : "disabled=\'disabled\'"%> title="' + _('Add new row') + '"></button>',
'</div>'].join('\n')),
$gridBody =
$('<div class=\'pgadmin-control-group backgrid form-group col-12 object subnode\'></div>').append(
// Append titleTmpl only if create/edit mode
data.mode !== 'properties' ? titleTmpl({label: data.label}) : ''
data.mode !== 'properties' ? titleTmpl({label: data.label, canAdd: data.canAdd}) : ''
);
$gridBody.append(self.generateHeader(data));
@@ -469,7 +470,7 @@ define('pgadmin.node.exclusion_constraint', [
var grid = self.grid = new Backgrid.Grid({
columns: gridColumns,
collection: self.collection,
className: 'backgrid table-bordered',
className: 'backgrid table-bordered table-noouter-border table-hover',
});
self.$grid = grid.render().$el;
@@ -489,6 +490,7 @@ define('pgadmin.node.exclusion_constraint', [
$gridBody.find('.subnode-header-form').removeClass('subnode-header-form');
// Render node grid
self.$gridBody = $gridBody;
return $gridBody;
},
@@ -522,7 +524,7 @@ define('pgadmin.node.exclusion_constraint', [
inSelected = true;
}
self.$header.find('button.add').prop('disabled', inSelected);
self.$gridBody.find('button.add').prop('disabled', inSelected);
},
addColumns: function(ev) {

View File

@@ -302,15 +302,12 @@ define('pgadmin.node.foreign_key', [
generateHeader: function(data) {
var header = [
'<div class="subnode-header-form">',
' <div class="container-fluid">',
' <div>',
' <div class="row">',
' <div class="col-md-4">',
' <label class="control-label"><%-column_label%></label>',
' </div>',
' <div class="col-md-6" header="local_column"></div>',
' <div class="col-md-2">',
' <button class="btn btn-sm-sq btn-default add fa fa-plus" <%=canAdd ? "" : "disabled=\'disabled\'"%> ></button>',
' </div>',
' </div>',
' <div class="row">',
' <div class="col-md-4">',
@@ -370,13 +367,14 @@ define('pgadmin.node.foreign_key', [
var self = this,
titleTmpl = _.template([
'<div class=\'subnode-header\'>',
'<label class=\'control-label\'><%-label%></label>',
'<div class="subnode-header">',
' <label class="control-label pg-el-sm-10"><%-label%></label>',
' <button class="btn btn-sm-sq btn-secondary add fa fa-plus" <%=canAdd ? "" : "disabled=\'disabled\'"%> title="' + _('Add new row') + '"></button>',
'</div>'].join('\n')),
$gridBody =
$('<div class=\'pgadmin-control-group backgrid form-group col-12 object subnode\'></div>').append(
// Append titleTmpl only if create/edit mode
data.mode !== 'properties' ? titleTmpl({label: data.label}) : ''
data.mode !== 'properties' ? titleTmpl({label: data.label, canAdd: data.canAdd}) : ''
);
// Clean up existing grid if any (in case of re-render)
@@ -401,7 +399,7 @@ define('pgadmin.node.foreign_key', [
var grid = self.grid = new Backgrid.Grid({
columns: gridSchema.columns,
collection: self.collection,
className: 'backgrid table-bordered',
className: 'backgrid table-bordered table-noouter-border table-hover',
});
self.$grid = grid.render().$el;
@@ -430,6 +428,7 @@ define('pgadmin.node.foreign_key', [
$gridBody.find('.subnode-header-form').removeClass('subnode-header-form');
// Render node grid
self.$gridBody = $gridBody;
return $gridBody;
},
@@ -463,7 +462,7 @@ define('pgadmin.node.foreign_key', [
inSelected = true;
}
self.$header.find('button.add').prop('disabled', inSelected);
self.$gridBody.find('button.add').prop('disabled', inSelected);
},
addColumns: function(ev) {

View File

@@ -0,0 +1,7 @@
.sql_field_height_140 {
height: 140px;
}
.sql_field_height_280 {
height: 280px;
}

View File

@@ -7,11 +7,3 @@
vertical-align: middle;
height: 1.3em;
}
.sql_field_height_140 {
height: 140px;
}
.sql_field_height_280 {
height: 280px;
}

View File

@@ -0,0 +1,7 @@
.sql_field_height_140 {
height: 140px;
}
.sql_field_width_full {
width: 100%;
}

View File

@@ -7,7 +7,3 @@
vertical-align: middle;
height: 1.3em;
}
.sql_field_width_full {
width: 100%;
}

View File

@@ -6,7 +6,3 @@
vertical-align: middle;
height: 1.3em;
}
.sql_field_height_140 {
height: 140px;
}

View File

@@ -345,8 +345,7 @@ define('pgadmin.node.pga_schedule', [
);
this.$el.prepend(
'<div class="set-group c ' +
Backform.helpMessageClassName + '">' +
'<div class="set-group">' +
gettext('Schedules are specified using a <b>cron-style</b> format.<br/><ul><li>For each selected time or date element, the schedule will execute.<br/>e.g. To execute at 5 minutes past every hour, simply select 05 in the Minutes list box.<br/></li><li>Values from more than one field may be specified in order to further control the schedule.<br/>e.g. To execute at 12:05 and 14:05 every Monday and Thursday, you would click minute 05, hours 12 and 14, and weekdays Monday and Thursday.</li><li>For additional flexibility, the Month Days check list includes an extra Last Day option. This matches the last day of the month, whether it happens to be the 28th, 29th, 30th or 31st.</li></ul>') +
'</div>'
);

View File

@@ -0,0 +1,3 @@
div[role=tabpanel] > .pgadmin-control-group.form-group.c.jscexceptions {
min-height: 400px;
}

View File

@@ -15,16 +15,3 @@
vertical-align: middle;
height: 1.3em;
}
.pg-el-container[el=sm] .pga-round-border {
border: 1px solid darkgray;
border-radius: 12px;
}
.pg-el-container[el=sm] .pga-round-border {
margin: 5px;
}
div[role=tabpanel] > .pgadmin-control-group.form-group.c.jscexceptions {
min-height: 400px;
}

View File

@@ -6,3 +6,7 @@
vertical-align: middle;
height: 1.3em;
}
.change_password {
padding-left: 7px;
}

View File

@@ -422,11 +422,11 @@ define('pgadmin.node.server', [
setup:function() {
return {
buttons: [{
text: gettext('Ok'), key: 13, className: 'btn btn-primary',
attrs: {name:'submit'},
},{
text: gettext('Cancel'), key: 27,
className: 'btn btn-danger', attrs: {name: 'cancel'},
className: 'btn btn-secondary fa fa-times pg-alertify-button', attrs: {name: 'cancel'},
},{
text: gettext('OK'), key: 13, className: 'btn btn-primary fa fa-check pg-alertify-button',
attrs: {name:'submit'},
}],
// Set options for dialog
options: {
@@ -451,7 +451,7 @@ define('pgadmin.node.server', [
prepare: function() {
var self = this;
// Disable Ok button until user provides input
this.__internal.buttons[0].element.disabled = true;
this.__internal.buttons[1].element.disabled = true;
var $container = $('<div class=\'change_password\'></div>'),
newpasswordmodel = new newPasswordModel(
@@ -479,9 +479,9 @@ define('pgadmin.node.server', [
(_.isUndefined(password) || _.isNull(password) || password == '')) ||
_.isUndefined(newPassword) || _.isNull(newPassword) || newPassword == '' ||
_.isUndefined(confirmPassword) || _.isNull(confirmPassword) || confirmPassword == '') {
self.__internal.buttons[0].element.disabled = true;
self.__internal.buttons[1].element.disabled = true;
} else if (newPassword != confirmPassword) {
self.__internal.buttons[0].element.disabled = true;
self.__internal.buttons[1].element.disabled = true;
this.errorTimeout && clearTimeout(this.errorTimeout);
this.errorTimeout = setTimeout(function() {
@@ -489,7 +489,7 @@ define('pgadmin.node.server', [
} ,400);
}else {
that.errorModel.clear();
self.__internal.buttons[0].element.disabled = false;
self.__internal.buttons[1].element.disabled = false;
}
});
},
@@ -1191,10 +1191,10 @@ define('pgadmin.node.server', [
setup:function() {
return {
buttons:[{
text: gettext('OK'), key: 13, className: 'btn btn-primary',
},{
text: gettext('Cancel'), className: 'btn btn-danger',
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: {

View File

@@ -328,7 +328,7 @@ define([
titleTmpl = _.template([
'<div class=\'subnode-header\'>',
'<label class=\'control-label\'><%-label%></label>',
'<button class=\'btn btn-sm-sq btn-default add fa fa-plus\' title=\'' + _('Add new row') + '\' <%=canAdd ? \'\' : \'disabled="disabled"\'%>></button>',
'<button class=\'btn btn-sm-sq btn-secondary add fa fa-plus\' title=\'' + _('Add new row') + '\' <%=canAdd ? \'\' : \'disabled="disabled"\'%>></button>',
'</div>'].join('\n')),
$gridBody =
$('<div class=\'pgadmin-control-group backgrid form-group col-12 object subnode\'></div>').append(
@@ -385,7 +385,7 @@ define([
columns: gridSchema.columns,
collection: self.collection,
row: VariableRow,
className: 'backgrid table-bordered',
className: 'backgrid table presentation table-bordered table-noouter-border table-hover',
});
self.$grid = grid.render().$el;

View File

@@ -180,13 +180,14 @@ define('pgadmin.node.tablespace', [
setup:function() {
return {
buttons: [{
text: '', key: 112, className: 'btn btn-default pull-left fa fa-lg fa-question',
text: '', key: 112,
className: 'btn btn-secondary pull-left fa fa-question pg-alertify-icon-button',
attrs:{name:'dialog_help', type:'button', label: gettext('Users'),
url: url_for('help.static', {'filename': 'move_objects.html'})},
},{
text: gettext('OK'), key: 13, className: 'btn btn-primary fa fa-lg fa-save pg-alertify-button',
text: gettext('Cancel'), key: 27, className: 'btn btn-secondary fa fa-lg fa-times pg-alertify-button',
},{
text: gettext('Cancel'), key: 27, className: 'btn btn-danger fa fa-lg fa-times pg-alertify-button',
text: gettext('OK'), key: 13, className: 'btn btn-primary fa fa-lg fa-save pg-alertify-button',
}],
// Set options for dialog
options: {
@@ -214,7 +215,7 @@ define('pgadmin.node.tablespace', [
var self = this,
$container = $('<div class=\'move_objects\'></div>');
//Disbale Okay button
this.__internal.buttons[1].element.disabled = true;
this.__internal.buttons[2].element.disabled = true;
// Find current/selected node
var t = pgBrowser.tree,
i = t.selected(),
@@ -248,9 +249,9 @@ define('pgadmin.node.tablespace', [
this.view.model.on('change', function() {
if (!_.isUndefined(this.get('tblspc')) && this.get('tblspc') !== '') {
this.errorModel.clear();
self.__internal.buttons[1].element.disabled = false;
self.__internal.buttons[2].element.disabled = false;
} else {
self.__internal.buttons[1].element.disabled = true;
self.__internal.buttons[2].element.disabled = true;
this.errorModel.set('tblspc', gettext('Please select tablespace'));
}
});

View File

@@ -15,7 +15,3 @@
vertical-align: middle;
height: 1.3em;
}
.change_password {
padding-left: 7px;
}

View File

@@ -40,23 +40,10 @@
padding-left: 20px;
}
.aciTree .aciTreeLi div.aciTreeLine {
display: table !important;
}
.pg-login-icon {
font-size: 16px;
}
.CodeMirror {
font-size: 1em;
}
#pg-spinner .pg-sp-content {
position: absolute;
width: 100%;
top: 40%;
}
.pgadmin_header_logo {
cursor: default;
}

View File

@@ -11,7 +11,6 @@
}
.wizard_dlg {
float: left;
height: 100%;
width: 100%;
}
@@ -21,12 +20,6 @@
height: 100%;
}
.wizard-content {
position: relative;
padding: 0;
height: calc(100% - 120px);
}
.wizard-right-panel {
overflow-y: auto;
height: 100%;
@@ -52,8 +45,7 @@
}
.wizard-right-panel_content {
height: calc(100% - 86px);
padding: 0;
padding: 0.5rem 0rem;
}
/* Wizard Footer CSS */
@@ -62,15 +54,6 @@
}
/* Wizard Button CSS */
.pgadmin-wizard .wizard-buttons {
float: right;
}
.pgadmin-wizard .wizard-buttons button {
float: left;
font-size: 14px;
margin: 3px 5px 0 0 !important;
}
.pgadmin-wizard .wizard-buttons button.wizard-next i.fa {
padding-left: 5px;
@@ -108,7 +91,7 @@ div.wizard-header.wizard-badge > div > div.col-sm-2 > button.ajs-maximized.ajs-m
/* Wizard Status bar CSS */
.pgadmin-wizard .wizard-description {
padding: 1.0em 0.1em;
padding: 0.5rem 0rem;
}
/* In wizard select2 dropdown doesn't

View File

@@ -117,7 +117,7 @@ define('pgadmin.browser', [
showTitle: true,
isCloseable: false,
isPrivate: true,
icon: 'fa fa-binoculars',
icon: '',
content: '<div id="tree" class="aciTree"></div>',
onCreate: function(panel) {
toolBar.initializeToolbar(panel, wcDocker);
@@ -127,7 +127,7 @@ define('pgadmin.browser', [
'properties': new pgAdmin.Browser.Panel({
name: 'properties',
title: gettext('Properties'),
icon: 'fa fa-cogs',
icon: '',
width: 500,
isCloseable: false,
isPrivate: true,
@@ -142,18 +142,18 @@ define('pgadmin.browser', [
'statistics': new pgAdmin.Browser.Panel({
name: 'statistics',
title: gettext('Statistics'),
icon: 'fa fa-line-chart',
icon: '',
width: 500,
isCloseable: false,
isPrivate: true,
content: '<div><div class="alert alert-info pg-panel-message pg-panel-statistics-message">' + select_object_msg + '</div><div class="pg-panel-statistics-container d-none"></div></div>',
content: '<div class="negative-space p-2"><div class="alert alert-info pg-panel-message pg-panel-statistics-message">' + select_object_msg + '</div><div class="pg-panel-statistics-container d-none"></div></div>',
events: panelEvents,
}),
// Reversed engineered SQL for the object
'sql': new pgAdmin.Browser.Panel({
name: 'sql',
title: gettext('SQL'),
icon: 'fa fa-file-text-o',
icon: '',
width: 500,
isCloseable: false,
isPrivate: true,
@@ -163,22 +163,22 @@ define('pgadmin.browser', [
'dependencies': new pgAdmin.Browser.Panel({
name: 'dependencies',
title: gettext('Dependencies'),
icon: 'fa fa-hand-o-up',
icon: '',
width: 500,
isCloseable: false,
isPrivate: true,
content: '<div><div class="alert alert-info pg-panel-message pg-panel-depends-message">' + select_object_msg + '</div><div class="pg-panel-depends-container d-none"></div></div>',
content: '<div class="negative-space p-2"><div class="alert alert-info pg-panel-message pg-panel-depends-message">' + select_object_msg + '</div><div class="pg-panel-depends-container d-none"></div></div>',
events: panelEvents,
}),
// Dependents of the object
'dependents': new pgAdmin.Browser.Panel({
name: 'dependents',
title: gettext('Dependents'),
icon: 'fa fa-hand-o-down',
icon: '',
width: 500,
isCloseable: false,
isPrivate: true,
content: '<div><div class="alert alert-info pg-panel-message pg-panel-depends-message">' + select_object_msg + '</div><div class="pg-panel-depends-container d-none"></div></div>',
content: '<div class="negative-space p-2"><div class="alert alert-info pg-panel-message pg-panel-depends-message">' + select_object_msg + '</div><div class="pg-panel-depends-container d-none"></div></div>',
events: panelEvents,
}),
},
@@ -320,13 +320,14 @@ define('pgadmin.browser', [
// Create a dummy 'no object seleted' menu
var create_submenu = pgAdmin.Browser.MenuGroup(
obj.menu_categories['create'], [{
$el: $('<li><a class="dropdown-item text-white disabled" href="#">' + gettext('No object selected') + '</a></li>'),
$el: $('<li><a class="dropdown-item disabled" href="#">' + gettext('No object selected') + '</a></li>'),
priority: 1,
category: 'create',
update: function() {},
}], false);
$obj_mnu.append(create_submenu.$el);
}
pgAdmin.Browser.SubmenuEvents($obj_mnu);
},
save_current_layout: function(obj) {
if(obj.docker) {
@@ -354,7 +355,10 @@ define('pgadmin.browser', [
'#dockerContainer', {
allowContextMenu: true,
allowCollapse: false,
themePath: '../static/css',
loadingClass: 'pg-sp-icon',
themePath: url_for('static', {
'filename': 'css',
}),
theme: 'webcabin.overrides.css',
});
if (obj.docker) {

View File

@@ -66,7 +66,7 @@ define([
j = panel.$container.find('.obj_properties').first(),
view = j.data('obj-view'),
content = $('<div></div>')
.addClass('pg-prop-content col-12'),
.addClass('pg-prop-content col-12 has-pg-prop-btn-group'),
node = pgBrowser.Nodes[that.node],
// This will be the URL, used for object manipulation.
urlBase = this.generate_url(item, 'properties', data),
@@ -169,9 +169,10 @@ define([
}
// Initialize a new Grid instance
that.grid = new Backgrid.Grid({
emptyText: 'No data found',
columns: gridSchema.columns,
collection: collection,
className: 'backgrid table-bordered',
className: 'backgrid table presentation table-bordered table-noouter-border table-hover',
});
var gridView = {
@@ -216,7 +217,7 @@ define([
label: '',
type: 'delete',
tooltip: gettext('Delete/Drop'),
extraClasses: ['btn-default', 'delete_multiple'],
extraClasses: ['btn-secondary m-1', 'delete_multiple'],
icon: 'fa fa-lg fa-trash-o',
disabled: (_.isFunction(that.canDrop)) ? !(that.canDrop.apply(self, [data, item])) : (!that.canDrop),
register: function(btn) {
@@ -230,8 +231,8 @@ define([
label: '',
type: 'delete',
tooltip: gettext('Drop Cascade'),
extraClasses: ['btn-default', 'delete_multiple_cascade'],
icon: '',
extraClasses: ['btn-secondary m-1', 'delete_multiple_cascade'],
icon: 'icon-delete_multiple_cascade',
disabled: (_.isFunction(that.canDropCascade)) ? !(that.canDropCascade.apply(self, [data, item])) : (!that.canDropCascade),
register: function(btn) {
btn.on('click',() => {
@@ -240,10 +241,11 @@ define([
},
});
createButtons(buttons, 'header', 'pg-prop-btn-group-above bg-gray-lighter border-gray-light');
createButtons(buttons, 'header', 'pg-prop-btn-group-above');
// Render subNode grid
content.append(that.grid.render().$el);
content.append('<div class="pg-prop-coll-container"></div>');
content.find('.pg-prop-coll-container').append(that.grid.render().$el);
j.append(content);
// Fetch Data

View File

@@ -41,7 +41,6 @@ _.extend(pgBrowser.keyboardNavigation, {
this.keyboardShortcut.help_shortcut],
}, // Main menu
'bindRightPanel': {'shortcuts': [this.keyboardShortcut.tabbed_panel_backward, this.keyboardShortcut.tabbed_panel_forward]}, // Main window panels
'bindSubMenuClose': {'shortcuts': ['esc','enter']},
'bindLeftTree': {'shortcuts': this.keyboardShortcut.left_tree_shortcut}, // Main menu,
'bindSubMenuQueryTool': {'shortcuts': this.keyboardShortcut.sub_menu_query_tool}, // Sub menu - Open Query Tool,
'bindSubMenuViewData': {'shortcuts': this.keyboardShortcut.sub_menu_view_data}, // Sub menu - Open View Data,
@@ -166,6 +165,7 @@ _.extend(pgBrowser.keyboardNavigation, {
let currMenu = currLi.closest('.dropdown-menu');
if(currMenu.closest('.dropdown-submenu').length > 0) {
currMenu.removeClass('show');
currMenu.closest('.dropdown-submenu').removeClass('dropdown-submenu-visible');
currLi = currMenu.closest('.dropdown-submenu');
currLi.find('.dropdown-item').trigger('focus');
}
@@ -189,6 +189,7 @@ _.extend(pgBrowser.keyboardNavigation, {
/*open submenu if any*/
if(currLi.hasClass('dropdown-submenu')){
currLi.addClass('dropdown-submenu-visible');
currLi.find('.dropdown-menu').addClass('show');
currLi = currLi.find('.dropdown-menu .dropdown-item').first().trigger('focus');
}
@@ -200,8 +201,9 @@ _.extend(pgBrowser.keyboardNavigation, {
keyboardFunc._stopEventPropagation(event);
let currLi = $(event.target).closest('li');
/*close all the submenus on movement*/
$(event.target).closest('.dropdown-menu').find('.show').removeClass('show');
let dropMenu = $(event.target).closest('.dropdown-menu');
dropMenu.find('.show').removeClass('show');
dropMenu.find('.dropdown-submenu').removeClass('dropdown-submenu-visible');
if(combo === 'up') {
currLi = currLi.prev();
}
@@ -222,12 +224,6 @@ _.extend(pgBrowser.keyboardNavigation, {
currLi.find('.dropdown-item').trigger('focus');
}
},
bindSubMenuClose: function() {
if($(event.target).hasClass('dropdown-item')
&& $(event.target).closest('.dropdown-submenu').length > 0) {
$(event.target).closest('.dropdown').find('.dropdown-submenu .dropdown-menu').removeClass('show');
}
},
bindLeftTree: function() {
const tree = this.getTreeDetails();

View File

@@ -169,9 +169,9 @@ define([
'<li class="dropdown-submenu">',
' <a href="#" class="dropdown-item">',
' <% if (icon) { %><i class="<%= icon %>"></i><% } %>',
' <span class="text-white"><%= label %></span>',
' <span><%= label %></span>',
' </a>',
' <ul class="dropdown-menu bg-dark">',
' <ul class="dropdown-menu">',
' </ul>',
'</li>',
'<% if (below) { %><li class="dropdown-divider"></li><% } %>',
@@ -338,6 +338,30 @@ define([
return (len > 0);
};
pgAdmin.Browser.SubmenuEvents = function($mnu) {
let subMenuClose = function(event) {
let $dropDown = $(event.currentTarget).closest('.dropdown');
$dropDown.find('.dropdown-submenu .dropdown-menu').removeClass('show');
$dropDown.find('.dropdown-submenu').removeClass('dropdown-submenu-visible');
};
let $navlink = $mnu.siblings('.nav-link');
$navlink.off('click', subMenuClose).on('click', subMenuClose);
$mnu.parent('.dropdown').off('show.bs.dropdown',subMenuClose)
.on('show.bs.dropdown',subMenuClose);
$mnu.find('.dropdown-item').off('mouseover').on('mouseover', (event)=> {
let $dropSubMenu = $(event.currentTarget).closest('.dropdown-menu').find('.dropdown-submenu');
/* Close all other submenus if any */
$dropSubMenu.find('.dropdown-menu').removeClass('show');
$dropSubMenu.removeClass('dropdown-submenu-visible');
/* Open the current submenu if any */
if($(event.currentTarget).parent().hasClass('dropdown-submenu')){
$(event.currentTarget).parent().find('.dropdown-menu').addClass('show');
$(event.currentTarget).parent().addClass('dropdown-submenu-visible');
}
});
};
// MENU PUBLIC CLASS DEFINITION
// ==============================

View File

@@ -314,7 +314,7 @@ define('pgadmin.browser.node', [
var onSessionInvalid = function(msg) {
var alertMessage = '\
<div class="media error-in-footer bg-danger-lighter border-danger-light text-danger text-14">\
<div class="media error-in-footer bg-danger-light border-danger text-danger text-14">\
<div class="media-body media-middle">\
<div class="alert-icon error-icon">\
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>\
@@ -1121,6 +1121,7 @@ define('pgadmin.browser.node', [
that.footer = $('<div></div>').addClass(
'pg-prop-footer'
).appendTo(j);
// Create a view to show the properties in fieldsets
view = that.getView(item, 'properties', content, data, 'fieldset', undefined, j);
if (view) {
@@ -1132,11 +1133,11 @@ define('pgadmin.browser.node', [
var buttons = [];
buttons.push({
label: '',
label: gettext('Edit'),
type: 'edit',
tooltip: gettext('Edit'),
extraClasses: ['btn-default'],
icon: 'fa fa-lg fa-pencil-square-o',
extraClasses: ['btn', 'btn-primary', 'pull-right', 'm-1'],
icon: 'fa fa-sm fa-pencil',
disabled: !that.canEdit,
register: function(btn) {
btn.on('click',() => {
@@ -1149,7 +1150,7 @@ define('pgadmin.browser.node', [
label: '',
type: 'help',
tooltip: gettext('SQL help for this object type.'),
extraClasses: ['btn-default', 'pull-right'],
extraClasses: ['btn-secondary', 'btn-secondary', 'm-1'],
icon: 'fa fa-lg fa-info',
disabled: (that.sqlAlterHelp == '' && that.sqlCreateHelp == '') ? true : false,
register: function(btn) {
@@ -1159,7 +1160,7 @@ define('pgadmin.browser.node', [
},
});
createButtons(buttons, 'header', 'pg-prop-btn-group-above bg-gray-lighter border-gray-light');
createButtons(buttons, 'header', 'pg-prop-btn-group-above');
}
j.append(content);
}.bind(panel),
@@ -1354,7 +1355,7 @@ define('pgadmin.browser.node', [
label: '',
type: 'help',
tooltip: gettext('SQL help for this object type.'),
extraClasses: ['btn-default', 'pull-left'],
extraClasses: ['btn-secondary', 'pull-left', 'mx-1'],
icon: 'fa fa-lg fa-info',
disabled: (that.sqlAlterHelp == '' && that.sqlCreateHelp == '') ? true : false,
register: function(btn) {
@@ -1366,7 +1367,7 @@ define('pgadmin.browser.node', [
label: '',
type: 'help',
tooltip: gettext('Help for this dialog.'),
extraClasses: ['btn-default', 'pull-left'],
extraClasses: ['btn-secondary', 'pull-left', 'mx-1'],
icon: 'fa fa-lg fa-question',
disabled: (that.dialogHelp == '') ? true : false,
register: function(btn) {
@@ -1374,25 +1375,12 @@ define('pgadmin.browser.node', [
onDialogHelp();
});
},
}, {
label: gettext('Save'),
type: 'save',
tooltip: gettext('Save this object.'),
extraClasses: ['btn-primary'],
icon: 'fa fa-lg fa-save',
disabled: true,
register: function(btn) {
// Save the changes
btn.on('click',() => {
onSave.call(this, view, btn);
});
},
}, {
label: gettext('Cancel'),
type: 'cancel',
tooltip: gettext('Cancel changes to this object.'),
extraClasses: ['btn-danger'],
icon: 'fa fa-lg fa-close',
extraClasses: ['btn-secondary', 'mx-1'],
icon: 'fa fa-close pg-alertify-button',
disabled: false,
register: function(btn) {
btn.on('click',() => {
@@ -1405,8 +1393,8 @@ define('pgadmin.browser.node', [
label: gettext('Reset'),
type: 'reset',
tooltip: gettext('Reset the fields on this dialog.'),
extraClasses: ['btn-warning'],
icon: 'fa fa-lg fa-recycle',
extraClasses: ['btn-secondary', 'mx-1'],
icon: 'fa fa-recycle pg-alertify-button',
disabled: true,
register: function(btn) {
btn.on('click',() => {
@@ -1415,7 +1403,20 @@ define('pgadmin.browser.node', [
}, 0);
});
},
}], 'footer', 'pg-prop-btn-group-below bg-gray-lighter border-gray-light');
}, {
label: gettext('Save'),
type: 'save',
tooltip: gettext('Save this object.'),
extraClasses: ['btn-primary', 'mx-1'],
icon: 'fa fa-save pg-alertify-button',
disabled: true,
register: function(btn) {
// Save the changes
btn.on('click',() => {
onSave.call(this, view, btn);
});
},
}], 'footer', 'pg-prop-btn-group-below');
}
// Create status bar.

View File

@@ -21,7 +21,7 @@ define([
let $rendered = decorated.call(this);
let $selectAll = $([
'<button class="btn btn-default btn-sm" type="button"',
'<button class="btn btn-secondary btn-sm" type="button"',
' style="width: 49%;margin: 0 0.5%;">',
'<i class="fa fa-check-square-o"></i>',
'<span style="padding: 0px 5px;">',
@@ -30,7 +30,7 @@ define([
].join(''));
let $unselectAll = $([
'<button class="btn btn-default btn-sm" type="button"',
'<button class="btn btn-secondary btn-sm" type="button"',
' style="width: 49%;margin: 0 0.5%;">',
'<i class="fa fa-square-o"></i><span style="padding: 0px 5px;">',
gettext('Unselect All'),

View File

@@ -141,15 +141,22 @@ define(
var w = p.width();
p.pgResizeTimeout = null;
if (w <= 480) {
/** Calculations based on https://getbootstrap.com/docs/4.1/layout/grid/#grid-options **/
if (w < 576) {
w = 'xs';
} else if (w < 600) {
}
if (w >= 576) {
w = 'sm';
} else if (w < 768) {
}
if (w >= 768) {
w = 'md';
} else {
}
if (w >= 992) {
w = 'lg';
}
if (w >=1200) {
w = 'xl';
}
p.pgElContainer.attr('el', w);
},

View File

@@ -13,7 +13,6 @@ let _defaultToolBarButtons = [
text: '',
toggled: false,
toggleClass: '',
parentClass: 'pg-toolbar-btn',
enabled: false,
},
{
@@ -22,7 +21,6 @@ let _defaultToolBarButtons = [
text: '',
toggled: false,
toggleClass: '',
parentClass: 'pg-toolbar-btn',
enabled: false,
},
{
@@ -31,7 +29,6 @@ let _defaultToolBarButtons = [
text: '',
toggled: false,
toggleClass: '',
parentClass: 'pg-toolbar-btn',
enabled: false,
},
];

View File

@@ -68,13 +68,13 @@ define([
' <div class="pgadmin-wizard" style="height: <%= this.options.height %>px;' +
' width: <%= this.options.width %>px">' +
' <div class="wizard-header wizard-badge">' +
' <div class="row">' +
' <div class="col-sm-10">' +
' <div class="d-flex">' +
' <div>' +
' <h3><span id="main-title"><%= this.options.title %></span> -' +
' <span id="step-title"><%= page_title %></span></h3>' +
' </div>' +
' <% if (this.options.show_header_cancel_btn) { %>' +
' <div class="col-sm-2">' +
' <div class="ml-auto">' +
' <button class="ajs-close wizard-cancel-event pull-right"' +
' title="' + gettext('Close') + '></button>' +
' <% if (this.options.show_header_maximize_btn) { %>' +
@@ -85,7 +85,7 @@ define([
' <% } %>' +
' </div>' +
' </div>' +
' <div class="wizard-content col-sm-12">' +
' <div class="wizard-content row m-0">' +
' <% if (this.options.show_left_panel) { %>' +
' <div class="col-sm-3 wizard-left-panel">' +
' <img src="<%= this.options.image %>"' +
@@ -101,12 +101,13 @@ define([
' <div class="wizard-progress-bar"><% if (show_progress_bar) { %>' +
' <p class="alert alert-info col-sm-12"><%= show_progress_bar %></p><% } %>' +
' </div>' +
' <div class="wizard-right-panel_content col-12">' +
' <div class="wizard-right-panel_content">' +
' </div>' +
' </div>' +
' </div>' +
' <div class="col-sm-12 pg-prop-status-bar" style="visibility:hidden">' +
' <div class="media error-in-footer bg-danger-lighter border-danger-light text-danger text-14">' +
' <div class="wizard-footer pg-prop-footer">' +
' <div class="pg-prop-status-bar" style="visibility:hidden">' +
' <div class="media error-in-footer bg-danger-light border-danger text-danger text-14">' +
' <div class="media-body media-middle">' +
' <div class="alert-icon error-icon">' +
' <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>' +
@@ -119,28 +120,25 @@ define([
' </div>' +
' </div>' +
' </div>' +
' <div class="footer col-sm-12">' +
' <div class="row">' +
' <div class="col-sm-4 wizard-buttons pull-left">' +
' <div class="wizard-buttons d-flex">' +
' <div>' +
' <button title = "' + gettext('Help for this dialog.') + '"' +
' class="btn btn-default pull-left wizard-help" <%=this.options.wizard_help ? "" : "disabled" %>>' +
' class="btn btn-secondary pull-left wizard-help" <%=this.options.wizard_help ? "" : "disabled" %>>' +
' <span class="fa fa-lg fa-question"></span></button>' +
' </div>' +
' <div class="col-sm-8">' +
' <div class="wizard-buttons">' +
' <button class="btn btn-primary wizard-back" <%=this.options.disable_prev ? "disabled" : ""%>>' +
' <div class="ml-auto">' +
' <button class="btn btn-secondary wizard-cancel" <%=this.options.disable_cancel ? "disabled" : ""%>>' +
' <i class="fa fa-lg fa-close"></i>' + gettext('Cancel') + '</button>' +
' <button class="btn btn-secondary wizard-back" <%=this.options.disable_prev ? "disabled" : ""%>>' +
' <i class="fa fa-backward"></i>' + gettext('Back') + '</button>' +
' <button class="btn btn-primary wizard-next" <%=this.options.disable_next ? "disabled" : ""%>>' +
' <button class="btn btn-secondary wizard-next" <%=this.options.disable_next ? "disabled" : ""%>>' +
' ' + gettext('Next') +
' <i class="fa fa-forward"></i></button>' +
' <button class="btn btn-danger wizard-cancel" <%=this.options.disable_cancel ? "disabled" : ""%>>' +
' <i class="fa fa-lg fa-close"></i>' + gettext('Cancel') + '</button>' +
' <button class="btn btn-primary wizard-finish" <%=this.options.disable_finish ? "disabled" : ""%>>' +
' ' + gettext('Finish') + '</button>' +
' </div>' +
' </div>' +
' </div>' +
' </div>' +
' </div>'),
events: {
'click button.wizard-next': 'nextPage',

View File

@@ -22,38 +22,27 @@ samp,
margin-bottom: 3px;
}
#pg-spinner {
.pg-sp-container {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background: $color-bg-inverse;
opacity: 0.6;
min-width: 100%;
min-height: 100%;
background: $loading-bg;
z-index: 1056;
}
#pg-spinner .pg-sp-icon {
font-size: 50px;
.pg-sp-content {
position: absolute;
width: 100%;
top: 40%;
}
}
.pg-sp-icon {
background: $loader-icon center center no-repeat;
height: 75px;
width: 100%;
text-align: center;
color: $color-gray-light;
}
#pg-spinner .pg-sp-text {
.pg-sp-text {
font-size: 20px;
text-align: center;
color: $color-fg-inverse;
}
.pg-toolbar-btn:hover {
border: none;
background-color: $color-bg !important;
}
.pg-toolbar-btn {
width: 25px !important;
height: 23px !important;
background-color: $color-bg !important;
font-size: 14px !important;
color: $color-gray-darker !important;
border: none;
color: $loading-fg;
}

View File

@@ -1,27 +1,42 @@
.wizard-header {
padding: 6px 10px!important;
min-height: 35px;
max-height: 35px;
border-bottom: 2px solid $color-gray-light;
min-height: $title-height;
max-height: $title-height;
background-color: $color-primary;
font-size: $font-size-base;
font-weight: bold;
color: $color-fg-inverse;
font-size: 14px;
font-weight: bold;
border-radius: 0;
color: $color-primary-fg;
overflow: hidden;
white-space: nowrap;
border-radius: 0rem;
border-top-left-radius: $panel-border-radius;
border-top-right-radius: $panel-border-radius;
border-bottom: none;
}
.pgadmin-wizard .footer {
background-color: $color-gray-lighter;
border-width: 2px 0px 0px 0px;
border-style: solid;
border-color: $color-gray-dark;
.wizard-content {
position: absolute;
overflow: auto;
top: $title-height;
bottom: $footer-height-calc; //similar to alertify footer
left: 0;
right: 0;
}
.pgadmin-wizard .wizard-buttons {
border-top: $panel-border;
padding: $footer-padding
}
/* match the alertify footer */
.pgadmin-wizard .wizard-footer {
min-height: $footer-min-height;
border: none;
position: absolute;
left: 0;
right: 0;
bottom: 0;
margin: 0;
padding: 0;
}
/* Error message css */

View File

@@ -4,7 +4,7 @@
background-size: 20px !important;
align-content: center;
vertical-align: middle;
height: 20px;
height: 15px;
}
.pgadmin-node-select option[node="{{node_type}}"] {

View File

@@ -90,18 +90,19 @@ window.onload = function(e){
{% endblock %}
{% block body %}
<div id="pg-spinner">
<div id="pg-spinner" class="pg-sp-container">
<div class="pg-sp-content">
<div class="row"><div class="col-12 pg-sp-icon fa fa-spinner fa-pulse"></div></div>
<div class="row"><div class="col-12 pg-sp-icon"></div></div>
<div class="row"><div class="col-12 pg-sp-text">{{ _('Loading {0} v{1}...').format(config.APP_NAME, config.APP_VERSION) }}</div></div>
</div>
</div>
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark pg-navbar">
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary pg-navbar">
<a class="navbar-brand pgadmin_header_logo" onClick="return false;" href="{{ '#' }}"
title="{{ config.APP_NAME }} {{ _('logo') }}">
<i class="app-icon {{ config.APP_ICON }}"></i>
<span>&nbsp;{{ config.APP_NAME }}</span>
</a>
<div class="pg-navbar-brand-arrow"></div>
<button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#navbar-menu" aria-controls="navbar-menu">
<span class="sr-only">{{ _('Toggle navigation') }}</span>
<span class="navbar-toggler-icon"></span>
@@ -141,7 +142,7 @@ window.onload = function(e){
</li>
</ul>
{% if config.SERVER_MODE %}
<ul class="navbar-nav mx-2">
<ul class="navbar-nav">
<li class="nav-item active dropdown">
<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown"
role="button" aria-expanded="false" id="navbar-user"></a>

View File

@@ -53,7 +53,7 @@ class DashboardModule(PgAdminModule):
name='dashboard',
priority=1,
title=gettext('Dashboard'),
icon='fa fa-tachometer',
icon='',
content='',
isCloseable=True,
isPrivate=False,

View File

@@ -1,12 +1,3 @@
.dashboard-container {
padding-top: 15px;
padding-bottom: 15px;
}
.dashboard-row {
margin-bottom: 15px;
}
.dashboard-link {
text-align: center;
}
@@ -15,8 +6,8 @@
cursor: pointer;
}
.dashboard-tab-panel > li > a {
padding: 0px 15px !important;
.dashboard-tab-container {
padding: 0px;
}
.dashboard-tab {
@@ -109,3 +100,11 @@
.dashboard-hidden {
display: none;
}
div#dashboard-activity div.tab-content > div.tab-pane table.backgrid.table-bordered {
border: none;
}
div#dashboard-activity div.tab-content > div.tab-pane table.backgrid.table-bordered tr > td:first-child {
border-left: none !important;
}

View File

@@ -2,8 +2,7 @@ define('pgadmin.dashboard', [
'sources/url_for', 'sources/gettext', 'require', 'jquery', 'underscore',
'sources/pgadmin', 'backbone', 'backgrid', './charting',
'pgadmin.alertifyjs', 'pgadmin.backform',
'sources/nodes/dashboard', 'backgrid.filter',
'pgadmin.browser', 'bootstrap', 'wcdocker',
'sources/nodes/dashboard', 'pgadmin.browser', 'bootstrap', 'wcdocker',
], function(
url_for, gettext, r, $, _, pgAdmin, Backbone, Backgrid, charting,
Alertify, Backform, NodesDashboard
@@ -39,7 +38,7 @@ define('pgadmin.dashboard', [
);
} else {
this.$el.html(
'<i class=\'fa fa-times-circle\' data-toggle=\'tooltip\' ' +
'<i class=\'fa fa-times-circle text-danger\' data-toggle=\'tooltip\' ' +
'title=\'' + gettext('Terminate the session') +
'\'></i>'
);
@@ -590,9 +589,10 @@ define('pgadmin.dashboard', [
// Set up the grid
var grid = new Backgrid.Grid({
emptyText: 'No data found',
columns: columns,
collection: data,
className: 'backgrid table-bordered presentation table backgrid-striped',
className: 'backgrid presentation table table-bordered table-noouter-border table-hover',
});
// Render the grid
@@ -605,17 +605,7 @@ define('pgadmin.dashboard', [
collection: data,
});
// Render the filter
$('#' + container.id + '_filter').before(filter.render().el);
// Add some space to the filter and move it to the right
$(filter.el).css({
float: 'right',
margin: '5px',
'margin-right': '2px',
'margin-top': '3px',
});
filter.setCustomSearchBox($('#txtGridSearch'));
// Stash objects for future use
$(container).data('data', data);
$(container).data('grid', grid);
@@ -850,6 +840,13 @@ define('pgadmin.dashboard', [
var div_server_prepared = $dashboardContainer.find('#server_prepared').get(0);
var div_server_config = $dashboardContainer.find('#server_config').get(0);
var tab_grid_map = {
'tab_server_activity': div_server_activity,
'tab_server_locks': div_server_locks,
'tab_server_prepared': div_server_prepared,
'tab_server_config': div_server_config,
};
// Display server activity
if (self.preferences.show_activity) {
var server_activity_columns = [{
@@ -1099,45 +1096,17 @@ define('pgadmin.dashboard', [
// (Re)render the appropriate tab
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
switch ($(e.target).attr('aria-controls')) {
case 'tab_server_activity':
pgAdmin.Dashboard.render_grid_data(div_server_activity);
break;
let prevGrid = tab_grid_map[$(e.relatedTarget).attr('aria-controls')];
$(prevGrid).data('filtertext', $('#txtGridSearch').val());
case 'tab_server_locks':
pgAdmin.Dashboard.render_grid_data(div_server_locks);
break;
case 'tab_server_prepared':
pgAdmin.Dashboard.render_grid_data(div_server_prepared);
break;
case 'tab_server_config':
pgAdmin.Dashboard.render_grid_data(div_server_config);
break;
}
let currGrid = tab_grid_map[$(e.target).attr('aria-controls')];
$('#txtGridSearch').val($(currGrid).data('filtertext'));
pgAdmin.Dashboard.render_grid_data(currGrid);
});
$('button').off('click').on('click', (e) => {
let $this = $(e.currentTarget);
let targetID = $this.length ? $this[0].id : undefined;
switch (targetID) {
case 'btn_server_activity_refresh':
pgAdmin.Dashboard.render_grid_data(div_server_activity);
break;
case 'btn_server_locks_refresh':
pgAdmin.Dashboard.render_grid_data(div_server_locks);
break;
case 'btn_server_prepared_refresh':
pgAdmin.Dashboard.render_grid_data(div_server_prepared);
break;
case 'btn_server_config_refresh':
pgAdmin.Dashboard.render_grid_data(div_server_config);
break;
}
$('#btn_refresh').off('click').on('click', () => {
let currGrid = tab_grid_map[$('#dashboard-activity .nav-tabs .active').attr('aria-controls')];
pgAdmin.Dashboard.render_grid_data(currGrid);
});
}
},
@@ -1147,6 +1116,12 @@ define('pgadmin.dashboard', [
var div_database_locks = document.getElementById('database_locks');
var div_database_prepared = document.getElementById('database_prepared');
var tab_grid_map = {
'tab_database_activity': div_database_activity,
'tab_database_locks': div_database_locks,
'tab_database_prepared': div_database_prepared,
};
// Display server activity
if (self.preferences.show_activity) {
var database_activity_columns = [{
@@ -1348,39 +1323,18 @@ define('pgadmin.dashboard', [
pgAdmin.Dashboard.render_grid_data(div_database_activity);
// (Re)render the appropriate tab
$('a[data-toggle="tab"]').off('shown.bs.tab').on('shown.bs.tab', function(e) {
switch ($(e.target).attr('aria-controls')) {
case 'tab_database_activity':
pgAdmin.Dashboard.render_grid_data(div_database_activity);
break;
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
let prevGrid = tab_grid_map[$(e.relatedTarget).attr('aria-controls')];
$(prevGrid).data('filtertext', $('#txtGridSearch').val());
case 'tab_database_locks':
pgAdmin.Dashboard.render_grid_data(div_database_locks);
break;
case 'tab_database_prepared':
pgAdmin.Dashboard.render_grid_data(div_database_prepared);
break;
}
let currGrid = tab_grid_map[$(e.target).attr('aria-controls')];
$('#txtGridSearch').val($(currGrid).data('filtertext'));
pgAdmin.Dashboard.render_grid_data(currGrid);
});
// Handle button clicks
$('button').off('click').on('click', (e) => {
let $this = $(e.currentTarget);
let targetID = $this.length ? $this[0].id : undefined;
switch (targetID) {
case 'btn_database_activity_refresh':
pgAdmin.Dashboard.render_grid_data(div_database_activity);
break;
case 'btn_database_locks_refresh':
pgAdmin.Dashboard.render_grid_data(div_database_locks);
break;
case 'btn_database_prepared_refresh':
pgAdmin.Dashboard.render_grid_data(div_database_prepared);
break;
}
$('#btn_refresh').off('click').on('click', () => {
let currGrid = tab_grid_map[$('#dashboard-activity .nav-tabs .active').attr('aria-controls')];
pgAdmin.Dashboard.render_grid_data(currGrid);
});
}
},

View File

@@ -1,11 +1,19 @@
.dashboard-icon {
color: $color-fg;
color: $color-primary;
}
.dashboard-tab-container {
border-left: 1px solid $color-gray-lighter;
border-right: 1px solid $color-gray-lighter;
border-bottom: 1px solid $color-gray-lighter;
.dashboard-container {
padding-top: $grid-gutter-width/2;
padding-bottom: $grid-gutter-width/2;
min-height: 100%;
}
.dashboard-graph-body {
padding: 0.25rem 0.5rem;
}
.dashboard-row {
margin-bottom: $grid-gutter-width/2;
}
.dashboard-tab-btn-group {
@@ -27,25 +35,9 @@
padding-bottom: 40px;
}
.dashboard-tab-container .sub-node-form {
padding: 0px 0px 0px 1px;
background-color: $color-gray-lighter;
}
.dashboard-tab-container .subnode-dialog .nav > li > a {
font-weight: bold;
}
.dashboard-tab-container .subnode-dialog .nav-tabs > li.active > a,
.dashboard-tab-container .subnode-dialog .nav-tabs > li.active > a:hover {
border-top: 1px solid $color-gray-lighter;
border-left: 1px solid $color-gray-lighter;
border-right: 1px solid $color-gray-lighter;
margin-bottom: -1px;
z-index: 10;
}
.dashboard-tab-container .backgrid .editor {
background-color: $color-gray-lighter !important;
border-bottom-color: $color-gray-lighter;
.grid-container {
width: 100%;
overflow: auto;
border-radius: $card-border-radius;
border: $panel-border;
}

View File

@@ -1,115 +1,114 @@
<div class="container-fluid">
<div class="dashboard-container">
<div class="container-fluid dashboard-container negative-space">
<div id="dashboard-graphs" class="dashboard-hidden">
<div class="row">
<div class="col-6">
<div class="obj_properties">
<legend class="badge">{{ _('Database sessions') }}</legend>
</div>
</div>
<div class="col-6">
<div class="obj_properties">
<legend class="badge">{{ _('Transactions per second') }}</legend>
</div>
</div>
</div>
<div class="row dashboard-row">
<div class="col-6">
<div class="col-md-6 col-12">
<div class="card">
<div class="card-header">
{{ _('Dashboard sessions') }}
</div>
<div class="card-body dashboard-graph-body">
<div id="graph-sessions" class="graph-container"></div>
</div>
<div class="col-6">
</div>
</div>
<div class="col-md-6 col-12">
<div class="card">
<div class="card-header">
{{ _('Transactions per second') }}
</div>
<div class="card-body dashboard-graph-body">
<div id="graph-tps" class="graph-container"></div>
</div>
</div>
<div class="row">
<div class="col-4">
<div class="obj_properties">
<legend class="badge">{{ _('Tuples in') }}</legend>
</div>
</div>
<div class="col-4">
<div class="obj_properties">
<legend class="badge">{{ _('Tuples out') }}</legend>
</div>
</div>
<div class="col-4">
<div class="obj_properties">
<legend class="badge">{{ _('Block I/O') }}</legend>
</div>
</div>
</div>
<div class="row dashboard-row">
<div class="col-4">
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
{{ _('Tuples in') }}
</div>
<div class="card-body dashboard-graph-body">
<div id="graph-ti" class="graph-container"></div>
</div>
<div class="col-4">
</div>
</div>
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
{{ _('Tuples out') }}
</div>
<div class="card-body dashboard-graph-body">
<div id="graph-to" class="graph-container"></div>
</div>
<div class="col-4">
</div>
</div>
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
{{ _('Block I/O') }}
</div>
<div class="card-body dashboard-graph-body">
<div id="graph-bio" class="graph-container"></div>
</div>
</div>
</div>
<div id="dashboard-activity" class="dashboard-hidden">
</div>
</div>
<div id="dashboard-activity" class="card dashboard-row dashboard-hidden">
<div class="card-header">
{{ _('Server activity') }}
</div>
<div class="card-body">
<div class="row">
<div class="col-12">
<div class="obj_properties">
<legend class="badge">{{ _('Database activity') }}</legend>
</div>
</div>
</div>
<div class="row dashboard-row">
<div class="col-12">
<div class="dashboard-tab-container">
<!-- Nav tabs -->
<ul class="nav nav-tabs dashboard-tab-panel" role="tablist">
<li role="presentation" class="nav-item dashboard-tab"><a href="#tab_panel_database_activity"
class="nav-link active"
aria-controls="tab_database_activity"
<div class="col-md-9 col-12 pr-0">
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active show" href="#tab_panel_database_activity" aria-controls="tab_database_activity"
role="tab" data-toggle="tab">{{ _('Sessions') }}</a>
</li>
<li role="presentation" class="nav-item dashboard-tab"><a href="#tab_panel_database_locks"
class="nav-link"
aria-controls="tab_database_locks" role="tab"
data-toggle="tab">{{ _('Locks') }}</a></li>
<li role="presentation" class="nav-item dashboard-tab"><a href="#tab_panel_database_prepared"
class="nav-link"
aria-controls="tab_database_prepared" role="tab"
data-toggle="tab">{{ _('Prepared Transactions') }}</a></li>
<li class="nav-item">
<a class="nav-link" href="#tab_panel_database_locks" aria-controls="tab_database_locks"
role="tab" data-toggle="tab">{{ _('Locks') }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#tab_panel_database_prepared" aria-controls="tab_database_prepared"
role="tab" data-toggle="tab">{{ _('Prepared Transactions') }}</a>
</li>
</ul>
</div>
<div class="col-md-3 col-12 pl-0 text-right">
<div class="navtab-inline-controls">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text fa fa-search" id="labelSearch"></span>
</div>
<input type="search" class="form-control" id="txtGridSearch" placeholder="Search" aria-label="Search" aria-describedby="labelSearch">
</div>
<button id="btn_refresh" type="button" class="btn btn-secondary btn-navtab-inline" title="{{ _('Refresh') }}">
<span class="fa fa-refresh"></span>
</button>
</div>
</div>
</div>
<!-- Nav tabs -->
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="tab_panel_database_activity">
<div class="dashboard-tab-btn-group pg-prop-btn-group-above">
<button id="btn_database_activity_refresh" type="button" class="btn btn-default" title="{{ _('Refresh') }}"> <span class="fa fa-lg fa-refresh"></span></button>
<div id="database_activity_filter"></div>
</div>
<div role="tabpanel" class="tab-pane negative-space p-2 active show" id="tab_panel_database_activity">
<div id="database_activity" class="grid-container"></div>
</div>
<div role="tabpanel" class="tab-pane" id="tab_panel_database_locks">
<div class="dashboard-tab-btn-group pg-prop-btn-group-above">
<button id="btn_database_locks_refresh" type="button" class="btn btn-default" title="{{ _('Refresh') }}"> <span class="fa fa-lg fa-refresh"></span></button>
<div id="database_locks_filter"></div>
</div>
<div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_database_locks">
<div id="database_locks" class="grid-container"></div>
</div>
<div role="tabpanel" class="tab-pane" id="tab_panel_database_prepared">
<div class="dashboard-tab-btn-group pg-prop-btn-group-above">
<button id="btn_database_prepared_refresh" type="button" class="btn btn-default" title="{{ _('Refresh') }}"> <span class="fa fa-lg fa-refresh"></span></button>
<div id="database_prepared_filter"></div>
</div>
<div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_database_prepared">
<div id="database_prepared" class="grid-container"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="dashboard-none-show" class="alert alert-info pg-panel-message dashboard-hidden" role="alert">
{{ _('All Dashboard elements are currently disabled.') }}
</div>
</div>
</div>

View File

@@ -1,126 +1,121 @@
<div class="container-fluid">
<div class="dashboard-container">
<div class="container-fluid dashboard-container negative-space">
<div id="dashboard-graphs" class="dashboard-hidden">
<div class="row">
<div class="col-6">
<div class="obj_properties">
<legend class="badge">{{ _('Server sessions') }}</legend>
</div>
</div>
<div class="col-6">
<div class="obj_properties">
<legend class="badge">{{ _('Transactions per second') }}</legend>
</div>
</div>
</div>
<div class="row dashboard-row">
<div class="col-6">
<div class="col-md-6 col-12">
<div class="card">
<div class="card-header">
{{ _('Server sessions') }}
</div>
<div class="card-body dashboard-graph-body">
<div id="graph-sessions" class="graph-container"></div>
</div>
<div class="col-6">
</div>
</div>
<div class="col-md-6 col-12">
<div class="card">
<div class="card-header">
{{ _('Transactions per second') }}
</div>
<div class="card-body dashboard-graph-body">
<div id="graph-tps" class="graph-container"></div>
</div>
</div>
<div class="row">
<div class="col-4">
<div class="obj_properties">
<legend class="badge">{{ _('Tuples in') }}</legend>
</div>
</div>
<div class="col-4">
<div class="obj_properties">
<legend class="badge">{{ _('Tuples out') }}</legend>
</div>
</div>
<div class="col-4">
<div class="obj_properties">
<legend class="badge">{{ _('Block I/O') }}</legend>
</div>
</div>
</div>
<div class="row dashboard-row">
<div class="col-4">
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
{{ _('Tuples in') }}
</div>
<div class="card-body dashboard-graph-body">
<div id="graph-ti" class="graph-container"></div>
</div>
<div class="col-4">
</div>
</div>
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
{{ _('Tuples out') }}
</div>
<div class="card-body dashboard-graph-body">
<div id="graph-to" class="graph-container"></div>
</div>
<div class="col-4">
</div>
</div>
<div class="col-md-4 col-12">
<div class="card">
<div class="card-header">
{{ _('Block I/O') }}
</div>
<div class="card-body dashboard-graph-body">
<div id="graph-bio" class="graph-container"></div>
</div>
</div>
</div>
<div id="dashboard-activity" class="dashboard-hidden">
</div>
</div>
<div id="dashboard-activity" class="card dashboard-row dashboard-hidden">
<div class="card-header">
{{ _('Server activity') }}
</div>
<div class="card-body">
<div class="row">
<div class="col-12">
<div class="obj_properties">
<legend class="badge">{{ _('Server activity') }}</legend>
</div>
</div>
</div>
<div class="row dashboard-row">
<div class="col-12">
<div class="dashboard-tab-container">
<!-- Nav tabs -->
<ul class="nav nav-tabs dashboard-tab-panel" role="tablist">
<li role="presentation" class="nav-item dashboard-tab"><a href="#tab_panel_server_activity"
class="nav-link active"
aria-controls="tab_server_activity"
role="tab" data-toggle="tab">{{ _('Sessions') }}</a>
<div class="col-md-9 col-12 pr-0">
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active show" href="#tab_panel_server_activity" aria-controls="tab_server_activity"
role="tab" data-toggle="tab">{{_('Sessions') }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#tab_panel_server_locks" aria-controls="tab_server_locks"
role="tab" data-toggle="tab">{{ _('Locks') }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#tab_panel_server_prepared" aria-controls="tab_server_prepared"
role="tab" data-toggle="tab">{{ _('Prepared Transactions') }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#tab_panel_server_config" aria-controls="tab_server_config"
role="tab" data-toggle="tab">{{ _('Configuration') }}</a>
</li>
<li role="presentation" class="nav-item dashboard-tab"><a href="#tab_panel_server_locks"
class="nav-link"
aria-controls="tab_server_locks" role="tab"
data-toggle="tab">{{ _('Locks') }}</a></li>
<li role="presentation" class="nav-item dashboard-tab"><a href="#tab_panel_server_prepared"
class="nav-link"
aria-controls="tab_server_prepared" role="tab"
data-toggle="tab">{{ _('Prepared Transactions') }}</a></li>
<li role="presentation" class="nav-item dashboard-tab"><a href="#tab_panel_server_config"
class="nav-link"
aria-controls="tab_server_config" role="tab"
data-toggle="tab">{{ _('Configuration') }}</a></li>
</ul>
</div>
<div class="col-md-3 col-12 pl-0 text-right">
<div class="navtab-inline-controls">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text fa fa-search" id="labelSearch"></span>
</div>
<input type="search" class="form-control" id="txtGridSearch" placeholder="Search" aria-label="Search" aria-describedby="labelSearch">
</div>
<button id="btn_refresh" type="button" class="btn btn-secondary btn-navtab-inline" title="{{ _('Refresh') }}">
<span class="fa fa-refresh"></span>
</button>
</div>
</div>
</div>
<!-- Nav tabs -->
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="tab_panel_server_activity">
<div class="dashboard-tab-btn-group pg-prop-btn-group-above">
<button id="btn_server_activity_refresh" type="button" class="btn btn-default" title="{{ _('Refresh') }}"> <span class="fa fa-lg fa-refresh"></span></button>
<div id="server_activity_filter"></div>
</div>
<div role="tabpanel" class="tab-pane negative-space p-2 active show" id="tab_panel_server_activity">
<div id="server_activity" class="grid-container"></div>
</div>
<div role="tabpanel" class="tab-pane" id="tab_panel_server_locks">
<div class="dashboard-tab-btn-group pg-prop-btn-group-above">
<button id="btn_server_locks_refresh" type="button" class="btn btn-default" title="{{ _('Refresh') }}"> <span class="fa fa-lg fa-refresh"></span></button>
<div id="server_locks_filter"></div>
</div>
<div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_locks">
<div id="server_locks" class="grid-container"></div>
</div>
<div role="tabpanel" class="tab-pane" id="tab_panel_server_prepared">
<div class="dashboard-tab-btn-group pg-prop-btn-group-above">
<button id="btn_server_prepared_refresh" type="button" class="btn btn-default" title="{{ _('Refresh') }}"> <span class="fa fa-lg fa-refresh"></span></button>
<div id="server_prepared_filter"></div>
</div>
<div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_prepared">
<div id="server_prepared" class="grid-container"></div>
</div>
<div role="tabpanel" class="tab-pane" id="tab_panel_server_config">
<div class="dashboard-tab-btn-group pg-prop-btn-group-above">
<button id="btn_server_config_refresh" type="button" class="btn btn-default" title="{{ _('Refresh') }}"> <span class="fa fa-lg fa-refresh"></span></button>
<div id="server_config_filter"></div>
</div>
<div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_config">
<div id="server_config" class="grid-container"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="dashboard-none-show" class="alert alert-info pg-panel-message dashboard-hidden" role="alert">
{{ _('All Dashboard elements are currently disabled.') }}
</div>
</div>
</div>

View File

@@ -1,12 +1,10 @@
<div class="container-fluid">
<div class="container-fluid negative-space">
<div class="dashboard-container">
<div class="row mb-2">
<div class="col-12">
<div class="obj_properties">
<legend class="badge">{{ _('Welcome') }}</legend>
</div>
<div class="card bg-light">
<div class="card-body">
<div class="card">
<div class="card-header">{{ _('Welcome') }}</div>
<div class="card-body p-2">
<img src="{{ url_for('dashboard.static', filename='img/welcome_logo.png') }}"
alt="{{ config.APP_NAME }} {{ _('logo') }}">
<h4>{{ _('Feature rich') }} | {{ _('Maximises PostgreSQL') }} | {{ _('Open Source') }} </h4>
@@ -19,20 +17,18 @@
</div>
<div class="row mb-2">
<div class="col-12">
<div class="obj_properties">
<legend class="badge">{{ _('Quick Links') }}</legend>
</div>
<div class="card bg-light">
<div class="card-body">
<div class="card ">
<div class="card-header">{{ _('Quick Links') }}</div>
<div class="card-body p-2">
<div class="row">
<div class="col-6 dashboard-link">
<a onclick="pgAdmin.Dashboard.add_new_server()">
<a href="#" onclick="pgAdmin.Dashboard.add_new_server()">
<span class="fa fa-4x dashboard-icon fa-server" aria-hidden="true"></span><br/>
{{ _('Add New Server') }}
</a>
</div>
<div class="col-6 dashboard-link">
<a onclick="pgAdmin.Preferences.show()">
<a href="#" onclick="pgAdmin.Preferences.show()">
<span id="mnu_preferences" class="fa fa-4x dashboard-icon fa-cogs"
aria-hidden="true"></span><br/>
{{ _('Configure pgAdmin') }}
@@ -45,11 +41,9 @@
</div>
<div class="row mb-2">
<div class="col-12">
<div class="obj_properties">
<legend class="badge">{{ _('Getting Started') }}</legend>
</div>
<div class="card bg-light">
<div class="card-body">
<div class="card ">
<div class="card-header">{{ _('Getting Started') }}</div>
<div class="card-body p-2">
<div class="row">
<div class="col-3 dashboard-link">
<a href="http://www.postgresql.org/docs" target="_blank">

View File

@@ -69,15 +69,14 @@ class BrowserToolBarFeatureTest(BaseFeatureTest):
retry_count = 0
while retry_count < 5:
try:
self.page.find_by_xpath(
"//*[contains(@class,'pg-toolbar-btn') and "
"contains(@title, 'Query Tool')]").click()
self.page.find_by_css_selector(
".wcFrameButton[title='Query Tool']").click()
break
except StaleElementReferenceException:
retry_count += 1
time.sleep(0.5)
self.page.find_by_xpath("//*[contains(@class,'wcTabIcon fa fa-bolt')]")
self.page.find_by_css_selector(".wcPanelTab .wcTabIcon.fa.fa-bolt")
def test_view_data_tool_button(self):
self.page.select_tree_item(self.test_db)
@@ -89,28 +88,26 @@ class BrowserToolBarFeatureTest(BaseFeatureTest):
retry_count = 0
while retry_count < 5:
try:
self.page.find_by_xpath(
"//*[contains(@class,'pg-toolbar-btn') and "
"contains(@title, 'View Data')]").click()
self.page.find_by_css_selector(
".wcFrameButton[title='View Data']").click()
break
except StaleElementReferenceException:
retry_count += 1
time.sleep(0.5)
self.page.find_by_xpath("//*[contains(@class,'wcTabIcon fa fa-bolt')]")
self.page.find_by_css_selector(".wcPanelTab .wcTabIcon.fa.fa-bolt")
def test_filtered_rows_tool_button(self):
retry_count = 0
while retry_count < 5:
try:
self.page.find_by_xpath(
"//*[contains(@class,'pg-toolbar-btn') and "
"contains(@title, 'Filtered Rows')]").click()
self.page.find_by_css_selector(
".wcFrameButton[title='Filtered Rows']").click()
break
except StaleElementReferenceException:
retry_count += 1
time.sleep(0.5)
self.page.find_by_xpath("//*[contains(@class, 'ajs-header') and "
"contains(., 'Data Filter')]")
self.page.find_by_css_selector(
".alertify .ajs-header[data-title='Data Filter']")
self.page.click_modal('Cancel')

View File

@@ -66,29 +66,19 @@ class CheckFileManagerFeatureTest(BaseFeatureTest):
def _create_new_file(self):
self.page.find_by_id("btn-save").click()
self.page.wait_for_query_tool_loading_indicator_to_disappear()
self.wait.until(EC.presence_of_element_located(
(
By.XPATH,
"//*[contains(string(), 'Show hidden files and folders? ')]"
)
))
self.page.find_by_css_selector('.change_file_types')
# Set the XSS value in input
self.page.find_by_id("file-input-path").clear()
self.page.find_by_id("file-input-path").send_keys(
self.XSS_FILE
)
# Save the file
self.page.click_modal('Save')
self.page.click_modal('Create')
self.page.wait_for_query_tool_loading_indicator_to_disappear()
def _open_file_manager_and_check_xss_file(self):
self.page.find_by_id("btn-load-file").click()
self.wait.until(EC.presence_of_element_located(
(
By.XPATH,
"//*[contains(string(), 'Show hidden files and folders? ')]"
)
))
self.page.find_by_css_selector('.change_file_types')
self.page.find_by_id("file-input-path").clear()
self.page.find_by_id("file-input-path").send_keys(
'/tmp/'
@@ -124,12 +114,7 @@ class CheckFileManagerFeatureTest(BaseFeatureTest):
def _check_file_sorting(self):
self.page.find_by_id("btn-load-file").click()
self.wait.until(
EC.element_to_be_clickable((
By.CSS_SELECTOR,
"#contents th[data-column='0']")
)
)
self.page.find_by_css_selector("#contents th[data-column='0']")
# Added time.sleep so that the element to be clicked.
time.sleep(0.05)

View File

@@ -116,10 +116,7 @@ class KeyboardShortcutFeatureTest(BaseFeatureTest):
field.send_keys(key)
# save and close the preference dialog.
self.page.find_by_xpath(
"//*[contains(@class,'pg-alertify-button') and "
"contains(.,'OK')]"
).click()
self.page.click_modal('Save')
self.page.wait_for_element_to_disappear(
lambda driver: driver.find_element_by_css_selector(".ajs-modal")

View File

@@ -109,10 +109,7 @@ class PGDataypeFeatureTest(BaseFeatureTest):
switch_btn.click()
# save and close the preference dialog.
self.page.find_by_xpath(
"//*[contains(@class,'pg-alertify-button') and "
"contains(.,'OK')]"
).click()
self.page.click_modal('Save')
self.page.wait_for_element_to_disappear(
lambda driver: driver.find_element_by_css_selector(".ajs-modal")

View File

@@ -50,6 +50,8 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self.page.toggle_open_server(self.server['name'])
self.page.toggle_open_tree_item('Databases')
self.page.toggle_open_tree_item('pg_utility_test_db')
# Backup
self.driver.find_element_by_link_text("Tools").click()
self.page.find_by_partial_link_text("Backup...").click()
@@ -65,18 +67,16 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self.page.find_by_xpath("//button[contains(@class,'fa-save') "
"and contains(.,'Backup')]").click()
self.page.wait_for_element_to_disappear(
lambda driver: driver.find_element_by_css_selector(".ajs-modal")
)
self.page.find_by_css_selector('.ajs-bg-bgprocess')
status = self.page.find_by_css_selector(
".pg-bg-bgprocess .bg-success").text
".pg-bg-status .bg-success-light .pg-bg-status-text").text
self.assertEquals(status, "Successfully completed.")
self.page.find_by_css_selector(
".pg-bg-bgprocess .pg-bg-click > span").click()
command = self.page.find_by_css_selector("p.bg-detailed-desc").text
".pg-bg-more-details").click()
command = self.page.find_by_css_selector(
".bg-process-details .bg-detailed-desc").text
self.assertIn(self.server['name'], str(command))
self.assertIn("from database 'pg_utility_test_db'", str(command))
@@ -94,6 +94,7 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self.page.find_by_xpath("//div[contains(@class,'wcFloatingFocus')"
"]//div[contains(@class,'fa-close')]").click()
# Restore
self.driver.find_element_by_link_text("Tools").click()
self.page.find_by_partial_link_text("Restore...").click()
@@ -108,17 +109,16 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self.page.find_by_xpath("//button[contains(@class,'fa-upload')"
" and contains(.,'Restore')]").click()
self.page.wait_for_element_to_disappear(
lambda driver: driver.find_element_by_css_selector(".ajs-modal")
)
self.page.find_by_css_selector('.ajs-bg-bgprocess')
status = self.page.find_by_css_selector(
".pg-bg-bgprocess .bg-success").text
".pg-bg-status .bg-success-light .pg-bg-status-text").text
self.assertEquals(status, "Successfully completed.")
self.page.find_by_css_selector(
".pg-bg-bgprocess .pg-bg-click > span").click()
command = self.page.find_by_css_selector("p.bg-detailed-desc").text
".pg-bg-more-details").click()
command = self.page.find_by_css_selector(
".bg-process-details .bg-detailed-desc").text
self.assertIn(self.server['name'], str(command))
if os.name is not 'nt':

View File

@@ -56,12 +56,8 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
def runTest(self):
self._open_maintenance_dialogue()
self.page.find_by_css_selector(
"button.fa-save.btn-primary.pg-alertify-button"). \
click()
self.page.wait_for_element_to_disappear(
lambda driver: driver.find_element_by_css_selector(".ajs-modal")
)
self.page.click_modal('OK')
self.page.find_by_css_selector('.ajs-bg-bgprocess')
self._verify_command()
def _open_maintenance_dialogue(self):
@@ -80,11 +76,11 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
def _verify_command(self):
status = self.page.find_by_css_selector(
".pg-bg-bgprocess .bg-success").text
".pg-bg-status .bg-success-light .pg-bg-status-text").text
self.assertEquals(status, "Successfully completed.")
self.page.find_by_css_selector(
".pg-bg-bgprocess .pg-bg-click > span").click()
command = self.page.find_by_css_selector("p.bg-detailed-desc").text
self.page.find_by_css_selector(".pg-bg-more-details").click()
command = self.page.find_by_css_selector(
".bg-process-details .bg-detailed-desc").text
if self.test_level == 'database':
self.assertEquals(command, "VACUUM "
"(VERBOSE)\nRunning Query:"

View File

@@ -110,10 +110,10 @@ class QueryToolJourneyTest(BaseFeatureTest):
self.page.click_element(newly_selected_history_entry)
selected_history_detail_pane = self.page.find_by_id("query_detail")
self.assertIn("SELECT * FROM table_that_doesnt_exist",
selected_history_detail_pane.text)
selected_history_detail_pane.get_attribute('innerHTML'))
self.page.click_tab("Query Editor")
self.__clear_query_tool()
self.page.click_element(editor_input)
self.page.fill_codemirror_area_with("SELECT * FROM hats")
@@ -135,6 +135,7 @@ class QueryToolJourneyTest(BaseFeatureTest):
self._assert_clickable(query_we_need_to_scroll_to)
self.page.click_tab("Query Editor")
self.__clear_query_tool()
self.page.click_element(editor_input)
self.page.fill_codemirror_area_with("SELECT * FROM hats")

View File

@@ -110,24 +110,26 @@ class QueryToolFeatureTest(BaseFeatureTest):
# this will set focus to correct iframe.
self.page.fill_codemirror_area_with('')
query_op = self.page.find_by_id("btn-query-dropdown")
query_op.click()
ActionChains(self.driver).move_to_element(
query_op.find_element_by_xpath(
"//li[contains(.,'Explain Options')]")).perform()
self.page.driver.execute_script(
"arguments[0].scrollIntoView()",
self.page.find_by_xpath(
"//span[normalize-space(text())='Verbose']"))
explain_op = self.page.find_by_id("btn-explain-options-dropdown")
explain_op.click()
# disable Explain options and auto rollback only if they are enabled.
for op in ('explain-verbose', 'explain-costs',
'explain-buffers', 'explain-timing', 'auto-rollback'):
'explain-buffers', 'explain-timing'):
btn = self.page.find_by_id("btn-{}".format(op))
check = btn.find_element_by_tag_name('i')
if 'visibility-hidden' not in check.get_attribute('class'):
btn.click()
query_op = self.page.find_by_id("btn-query-dropdown")
query_op.click()
# disable auto rollback only if they are enabled
btn = self.page.find_by_id("btn-auto-rollback")
check = btn.find_element_by_tag_name('i')
if 'visibility-hidden' not in check.get_attribute('class'):
btn.click()
# enable autocommit only if it's disabled
btn = self.page.find_by_id("btn-auto-commit")
check = btn.find_element_by_tag_name('i')
@@ -135,7 +137,7 @@ class QueryToolFeatureTest(BaseFeatureTest):
btn.click()
# close menu
self.page.find_by_xpath("//li[contains(.,'Explain Options')]").click()
query_op.click()
def _locate_database_tree_node(self):
self.page.toggle_open_tree_item(self.server['name'])
@@ -249,20 +251,15 @@ SELECT generate_series(1, 1000) as id order by id desc"""
wait = WebDriverWait(self.page.driver, 10)
self.page.fill_codemirror_area_with(query)
query_op = self.page.find_by_id("btn-query-dropdown")
query_op.click()
ActionChains(self.driver).move_to_element(
query_op.find_element_by_xpath(
"//li[contains(.,'Explain Options')]")).perform()
self.page.driver.execute_script(
"arguments[0].scrollIntoView()",
self.page.find_by_xpath(
"//span[normalize-space(text())='Verbose']"))
explain_op = self.page.find_by_id("btn-explain-options-dropdown")
explain_op.click()
self.page.find_by_id("btn-explain-verbose").click()
# disable Explain options and auto rollback only if they are enabled.
for op in ('explain-verbose', 'explain-costs'):
self.page.find_by_id("btn-{}".format(op)).click()
self.page.find_by_id("btn-explain-costs").click()
explain_op.click()
self.page.find_by_id("btn-explain").click()
@@ -288,21 +285,14 @@ SELECT generate_series(1, 1000) as id order by id desc"""
self.page.fill_codemirror_area_with(query)
query_op = self.page.find_by_id("btn-query-dropdown")
query_op.click()
explain_op = self.page.find_by_id("btn-explain-options-dropdown")
explain_op.click()
ActionChains(self.driver).move_to_element(
query_op.find_element_by_xpath(
"//li[contains(.,'Explain Options')]")).perform()
# disable Explain options and auto rollback only if they are enabled.
for op in ('explain-buffers', 'explain-timing'):
self.page.find_by_id("btn-{}".format(op)).click()
self.page.driver.execute_script(
"arguments[0].scrollIntoView()",
self.page.find_by_xpath(
"//span[normalize-space(text())='Verbose']"))
self.page.find_by_id("btn-explain-buffers").click()
self.page.find_by_id("btn-explain-timing").click()
explain_op.click()
self.page.find_by_id("btn-explain-analyze").click()
@@ -334,15 +324,12 @@ CREATE TABLE public.{}();""".format(table_name)
self.page.fill_codemirror_area_with(query)
self.page.find_by_id("btn-query-dropdown").click()
query_op = self.page.find_by_id("btn-query-dropdown")
query_op.click()
self.page.find_by_id("btn-auto-commit").click()
# Close the Explain Options drop down, getting error while clicking
# flash button on jenkins windows platform
self.page.find_by_xpath("//li[contains(.,'Explain Options')]").click()
wait.until(EC.invisibility_of_element_located(
(By.XPATH, "//li[contains(.,'Explain Options')]")))
query_op.click()
self.page.find_by_id("btn-flash").click()
@@ -406,18 +393,12 @@ END;"""
wait = WebDriverWait(self.page.driver, 10)
btn_query_dropdown = wait.until(EC.presence_of_element_located(
(By.ID, "btn-query-dropdown")))
btn_query_dropdown.click()
query_op = self.page.find_by_id("btn-query-dropdown")
query_op.click()
self.page.find_by_id("btn-auto-commit").click()
# Close the Explain Options drop down, getting error while clicking
# flash button on jenkins windows platform
self.page.find_by_xpath("//li[contains(.,'Explain Options')]").click()
wait.until(EC.invisibility_of_element_located(
(By.XPATH, "//li[contains(.,'Explain Options')]")))
query_op.click()
self.page.find_by_id("btn-flash").click()
@@ -498,17 +479,15 @@ END;"""
self.page.fill_codemirror_area_with(query)
self.page.find_by_id("btn-query-dropdown").click()
query_op = self.page.find_by_id("btn-query-dropdown")
query_op.click()
self.page.find_by_id("btn-auto-rollback").click()
self.page.find_by_id("btn-auto-commit").click()
# Close the Explain Options drop down, getting error while clicking
# flash button on jenkins windows platform
self.page.find_by_xpath("//li[contains(.,'Explain Options')]").click()
wait.until(EC.invisibility_of_element_located(
(By.XPATH, "//li[contains(.,'Explain Options')]")))
query_op.click()
self.page.find_by_id("btn-flash").click()
self.page.wait_for_query_tool_loading_indicator_to_disappear()
@@ -605,7 +584,8 @@ SELECT 1, pg_sleep(300)"""
self.page.fill_codemirror_area_with(query)
self.page.find_by_id("btn-query-dropdown").click()
query_op = self.page.find_by_id("btn-query-dropdown")
query_op.click()
auto_rollback_btn = self.page.find_by_id("btn-auto-rollback")
@@ -633,12 +613,7 @@ SELECT 1, pg_sleep(300)"""
auto_commit_check.get_attribute('class')):
auto_commit_btn.click()
# Close the Explain Options drop down, getting error while clicking
# flash button on jenkins windows platform
wait = WebDriverWait(self.page.driver, 10)
self.page.find_by_xpath("//li[contains(.,'Explain Options')]").click()
wait.until(EC.invisibility_of_element_located(
(By.XPATH, "//li[contains(.,'Explain Options')]")))
query_op.click()
self.page.find_by_id("btn-flash").click()
@@ -737,14 +712,16 @@ SELECT 1, pg_sleep(300)"""
self._clear_query_tool()
self.page.fill_codemirror_area_with("SELECT count(*) FROM pg_class;")
query_op = self.page.find_by_id("btn-query-dropdown")
query_op.click()
ActionChains(self.driver).move_to_element(
query_op.find_element_by_xpath(
"//li[contains(.,'Explain Options')]")).perform()
self.page.find_by_id("btn-explain-verbose").click()
self.page.find_by_id("btn-explain-costs").click()
explain_op = self.page.find_by_id("btn-explain-options-dropdown")
explain_op.click()
# disable Explain options and auto rollback only if they are enabled.
for op in ('explain-verbose', 'explain-costs', 'explain-analyze'):
self.page.find_by_id("btn-{}".format(op)).click()
explain_op.click()
self.page.find_by_id("btn-explain-analyze").click()
self.page.wait_for_query_tool_loading_indicator_to_disappear()

View File

@@ -169,7 +169,7 @@ CREATE TABLE public.defaults_{0}
(By.XPATH, xpath)), CheckForViewDataTest.TIMEOUT_STRING
)
cell_el = self.page.find_by_xpath(xpath)
self.page.driver.execute_script("arguments[0].scrollIntoView()",
self.page.driver.execute_script("arguments[0].scrollIntoView(false)",
cell_el)
ActionChains(self.driver).move_to_element(cell_el).double_click(
cell_el
@@ -189,10 +189,8 @@ CREATE TABLE public.defaults_{0}
ActionChains(self.driver).send_keys(value).perform()
# Click on editor's Save button
self.page.find_by_xpath(
"//*[contains(@class, 'pg_text_editor')]"
"//button[contains(@class, 'fa-save')]"
).click()
self.page.find_by_css_selector(
'.pg_text_editor button[data-label="Save"]').click()
else:
# Boolean editor test for to True click
if data[1] == 'true':
@@ -306,8 +304,8 @@ CREATE TABLE public.defaults_{0}
# row 2(being primary keys) won't match
# see if cell values matched to actual value
element = result_row.find_element_by_class_name("r" + str(idx))
self.page.driver.execute_script("arguments[0].scrollIntoView()",
element)
self.page.driver.execute_script(
"arguments[0].scrollIntoView(false)", element)
if (idx != 1 and not is_new_row) or is_new_row:
self.assertEquals(element.text, config_data[str(idx)][1])
@@ -316,5 +314,5 @@ CREATE TABLE public.defaults_{0}
# to reset position so other assertions can succeed
for idx in range(len(config_data.keys()), 1, -1):
element = result_row.find_element_by_class_name("r" + str(idx))
self.page.driver.execute_script("arguments[0].scrollIntoView()",
element)
self.page.driver.execute_script(
"arguments[0].scrollIntoView(false)", element)

View File

@@ -1,6 +1,3 @@
.ajs-bg-bgprocess.ajs-visible {
padding: 0px !important;
}
.ajs-bg-bgprocess .col-xs-12 {
padding-right: 5px;
@@ -25,17 +22,9 @@
}
ol.pg-bg-process-logs {
padding: 5px 10px 5px 60px;
height: 100%;
overflow: auto;
width: 100%;
font-style: italic;
font-size: small;
}
.pg-bg-res-out, .pg-bg-res-err {
padding-left: 10px;
white-space: pre-wrap;
}
.pg-panel-content .bg-process-stats p{

View File

@@ -24,6 +24,27 @@ define('misc.bgprocess', [
_.extend(
BGProcess.prototype, {
success_status_tpl: _.template(`
<div class="d-flex px-2 py-1 bg-success-light border border-success rounded">
<div class="pr-2">
<i class="fa fa-check fa-lg text-success pg-bg-status-icon" aria-hidden="true"></i>
</div>
<div class="text-body mx-auto pg-bg-status-text"><%-status_text%></div>
</div>`),
failed_status_tpl: _.template(`
<div class="d-flex px-2 py-1 bg-danger-light border border-danger rounded">
<div class="pr-2">
<i class="fa fa-close fa-lg text-danger pg-bg-status-icon" aria-hidden="true"></i>
</div>
<div class="text-body mx-auto pg-bg-status-text"><%-status_text%></div>
</div>`),
other_status_tpl: _.template(`
<div class="d-flex px-2 py-1 bg-primary-light border border-primary rounded">
<div class="pr-2">
<i class="fa fa-info fa-lg text-primary pg-bg-status-icon" aria-hidden="true"></i>
</div>
<div class="text-body mx-auto pg-bg-status-text"><%-status_text%></div>
</div>`),
initialize: function(info, notify) {
_.extend(this, {
details: false,
@@ -179,21 +200,21 @@ define('misc.bgprocess', [
}
if (self.stime) {
self.curr_status = gettext('Started');
self.curr_status = self.other_status_tpl({status_text:gettext('Started')});
if (self.execution_time >= 2) {
self.curr_status = gettext['Running...'];
self.curr_status = self.other_status_tpl({status_text:gettext('Running...')});
}
if (!_.isNull(self.exit_code)) {
if (self.state === 3) {
self.curr_status = gettext('Terminated by user.');
self.curr_status = self.failed_status_tpl({status_text:gettext('Terminated by user.')});
} else if (self.exit_code == 0) {
self.curr_status = gettext('Successfully completed.');
self.curr_status = self.success_status_tpl({status_text:gettext('Successfully completed.')});
} else {
self.curr_status = S(
gettext('Failed (exit code: %s).')
).sprintf(String(self.exit_code)).value();
self.curr_status = self.failed_status_tpl(
{status_text:S(gettext('Failed (exit code: %s).')).sprintf(String(self.exit_code)).value()}
);
}
}
@@ -255,55 +276,34 @@ define('misc.bgprocess', [
if (self.notify && !self.details) {
if (!self.notifier) {
var header = $('<div></div>', {
class: 'pg-bg-notify-header',
}).append($('<span></span>').text(_.unescape(self.desc))),
content = $('<div class="pg-bg-bgprocess"></div>').append(
header
).append(
$('<div></div>', {
class: 'pg-bg-notify-body',
}).append(
$('<div></div>', {
class: 'pg-bg-start',
}).append(
$('<div></div>', {
class: 'row align-items-center',
}).append(
$('<div></div>', {
class: 'col-9',
}).text(self.stime.toString())
).append(
$('<div></div>', {
class: 'col-3',
}).append(
$('<button></button>', {
type: 'button',
class: 'btn btn-danger btn-sm float-right bg-process-stop',
}).text('Stop Process')
)
)
).append(
$('<div class="pg-bg-etime"></div>')
)
)
),
for_details = $('<div></div>', {
class: 'text-center pg-bg-click',
}).append(
$('<span></span>').text(gettext('Click here for details.'))
).appendTo(content),
close_me = $(
'<div class="bg-close"><i class="fa fa-close"></i></div>'
).appendTo(header);
let content = $(`
<div class="card">
<div class="card-header bg-primary d-flex">
<div>${_.unescape(self.desc)}</div>
<div class="ml-auto">
<button class="btn btn-sm-sq btn-primary pg-bg-close"><i class="fa fa-lg fa-close"></i></button>
</div>
</div>
<div class="card-body px-2">
<div class="py-1">${self.stime.toString()}</div>
<div class="d-flex py-1">
<div class="my-auto mr-2">
<span class="fa fa-clock-o fa-2x"></span>
</div>
<div class="pg-bg-etime my-auto mr-2"></div>
<div class="ml-auto">
<button class="btn btn-secondary pg-bg-more-details"><span class="fa fa-info-circle"></span>&nbsp;${gettext('More details...')}</button>
<button class="btn btn-danger bg-process-stop"><span class="fa fa-times-circle"></span>&nbsp;${gettext('Stop Process')}</button>
</div>
</div>
<div class="pg-bg-status py-1">
</div>
</div>
</div>
`);
$('<div></div>', {
class: 'pg-bg-status ' + ((self.exit_code === 0) ?
'bg-success' : (self.exit_code == 1) ?
'bg-failed' : ''),
}).appendTo(content);
$('<div></div>').appendTo(content);
let for_details = content.find('.pg-bg-more-details');
let close_me = content.find('.pg-bg-close');
self.container = content;
self.notifier = Alertify.notify(
@@ -330,7 +330,7 @@ define('misc.bgprocess', [
// Do not close the notifier, when clicked on the container, which
// is a default behaviour.
content.on('click', function(ev) {
self.container.on('click', function(ev) {
ev = ev || window.event;
ev.cancelBubble = true;
ev.stopPropagation();
@@ -341,6 +341,7 @@ define('misc.bgprocess', [
// On Click event to stop the process.
content.find('.bg-process-stop').off('click').on('click', self.stop_process.bind(this));
}
// TODO:: Formatted execution time
self.container.find('.pg-bg-etime').empty().append(
$('<span></span>').text(
@@ -349,24 +350,15 @@ define('misc.bgprocess', [
).append(
$('<span></span>').text(' ' + gettext('seconds'))
);
var $status_bar = $(self.container.find('.pg-bg-status'));
$status_bar.empty().append(
self.curr_status
);
var $status_bar = $(self.container.find('.pg-bg-status'));
$status_bar.html(self.curr_status);
// Enable/Disable stop process button
var $btn_stop_process = $(self.container.find('.bg-process-stop'));
if (isNaN(parseInt(self.exit_code))) {
$btn_stop_process.attr('disabled', false);
} else {
$btn_stop_process.attr('disabled', true);
if (self.exit_code === 0 && self.state != 3) {
$status_bar.addClass('bg-success');
$status_bar.removeClass('bg-failed');
} else {
$status_bar.addClass('bg-failed');
$status_bar.removeClass('bg-success');
}
}
} else {
self.show_detailed_view.apply(self);
@@ -388,7 +380,6 @@ define('misc.bgprocess', [
}
var container = panel.$container,
status_class = '',
$logs = container.find('.bg-process-watcher'),
$header = container.find('.bg-process-details'),
$footer = container.find('.bg-process-footer'),
@@ -399,11 +390,6 @@ define('misc.bgprocess', [
$btn_stop_process.attr('disabled', false);
} else {
$btn_stop_process.attr('disabled', true);
if (self.exit_code === 0 && self.state != 3) {
status_class = 'bg-bgprocess-success';
} else {
status_class = 'bg-bgprocess-failed';
}
}
// On Click event to stop the process.
@@ -425,9 +411,7 @@ define('misc.bgprocess', [
);
// set status
$footer.find('.bg-process-status p').removeClass().addClass(
status_class
).html(self.curr_status);
$footer.find('.bg-process-status').html(self.curr_status);
// set bgprocess execution time
$footer.find('.bg-process-exec-time p').empty().append(
@@ -606,34 +590,33 @@ define('misc.bgprocess', [
isCloseable: true,
isPrivate: true,
content: '<div class="bg-process-details">' +
'<p class="bg-detailed-desc"></p>' +
'<div class="bg-process-stats" style="padding-bottom: 5px">' +
'<div class="row align-items-center">' +
'<div class="col-9">' +
'<span><b>' + gettext('Start time') + ': </b>' +
'<span class="bgprocess-start-time"></span>' +
'</span>' +
'<div class="bg-detailed-desc"></div>' +
'<div class="bg-process-stats d-flex py-1">' +
'<div class="my-auto mr-2">' +
'<span class="fa fa-clock-o fa-2x"></span>' +
'</div>' +
'<div class="col-3">' +
'<button type="button" class="btn btn-danger btn-sm float-right bg-process-stop">' +
gettext('Stop Process') + '</button>' +
'<div class="pg-bg-etime my-auto mr-2">'+
'<span>' + gettext('Start time') + ': <span class="bgprocess-start-time"></span>' +
'</span>'+
'</div>' +
'<div class="ml-auto">' +
'<button type="button" class="btn btn-danger bg-process-stop"><span class="fa fa-times-circle"></span>&nbsp;' + gettext('Stop Process') + '</button>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="bg-process-watcher">' +
'</div>' +
'<div class="bg-process-footer row">' +
'<div class="bg-process-status col-6">' +
'<span><b>' + gettext('Status') + ':</b></span><p></p>' +
'<div class="bg-process-footer p-2 d-flex">' +
'<div class="bg-process-status flex-grow-1">' +
'</div>' +
'<div class="bg-process-exec-time col-6">' +
'<div class="exec-div pull-right">' +
'<span><b>' + gettext('Execution time') + ':</b></span><p></p>' +
'<div class="bg-process-exec-time ml-4 my-auto">' +
'<div class="exec-div">' +
'<span>' + gettext('Execution time') + ':</span><p></p>' +
'</div>' +
'</div>' +
'</div>',
onCreate: function(myPanel, $container) {
$container.addClass('pg-no-overflow');
$container.addClass('pg-no-overflow p-2');
},
});
p.load(pgBrowser.docker);

View File

@@ -1,8 +1,32 @@
$bgproc-container-pad: 2px;
.ajs-bg-bgprocess.ajs-visible {
border: none;
padding: 0px !important;
text-align: left;
color: $color-fg-theme;
.card {
border:none;
& .card-header {
border: $border-width solid $color-primary;
background: $color-primary;
color: $color-primary-fg;
}
& .card-body {
padding: 5px;
border: $border-width solid $card-border-color;
border-bottom-left-radius: $card-border-radius;
border-bottom-right-radius: $card-border-radius;
}
}
}
.ajs-bg-bgprocess > .pg-bg-bgprocess {
background-color: $color-primary;
color: $color-fg-inverse;
color: $color-primary-fg;
padding: $bgproc-container-pad;
text-align: left;
font-size: 0.9em;
@@ -25,22 +49,6 @@ $bgproc-container-pad: 2px;
padding: 5px 0px;
}
.pg-bg-etime {
width: 100%;
display: block;
font-size: 95%;
padding: 5px;
font-weight: bold;
color: $color-fg;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25em;
background-color: $color-gray-lighter;
margin-top: 10px;
margin-bottom: 5px;
}
.pg-bg-click {
color: $color-gray-lighter;
text-decoration: underline;
@@ -52,6 +60,15 @@ $bgproc-container-pad: 2px;
color: $color-gray-dark;
}
.pg-bg-res-out, .pg-bg-res-err {
white-space: pre-wrap;
}
.pg-bg-res-err {
color: $color-danger;
}
.ajs-bg-bgprocess > .pg-bg-bgprocess > .pg-bg-status.bg-success,
.bg-process-status .bg-bgprocess-success {
color: $color-success-light;
@@ -71,41 +88,27 @@ $bgproc-container-pad: 2px;
.pg-panel-content div.bg-process-watcher {
height: 100%;
padding: 0px 0px 0px 0px;
WebkitTransition: all 1s;
transition: all 1s;
background-color: $color-primary-lighter;
}
.pg-bg-res-out {
color: $color-primary;
.pg-bg-process-logs {
border: $border-width solid $input-border-color;
border-radius: $input-border-radius;
padding-inline-start: 1rem;
}
.pg-bg-res-err {
color: rgba($color-danger, 0.81);
.pg-bg-cmd {
border: $border-width solid $input-border-color;
border-radius: $input-border-radius;
background: $input-disabled-bg;
}
.pg-panel-content .bg-process-details {
padding: 10px 15px;
min-height: 70px;
color: $color-fg;
background-color: $color-gray-lighter;
}
.pg-panel-content .bg-process-footer {
border-top: 1px solid $color-gray-light;
padding: 10px 25px;
position: absolute;
bottom: 0;
background-color: $color-gray-lighter;
right: 0px;
left: 0px;
}
.pg-panel-content .bg-process-footer b, .bg-process-stats span b {
color: $color-gray-dark;
}
.pg-bg-bgprocess .bg-close {
display: inline-block;
position: relative;

View File

@@ -73,6 +73,7 @@ define('misc.depends', [
var $container = panel[0].layout().scene().find('.pg-panel-content'),
$gridContainer = $container.find('.pg-panel-depends-container'),
grid = new Backgrid.Grid({
emptyText: 'No data found',
columns: [{
name: 'type',
label: gettext('Type'),
@@ -103,7 +104,7 @@ define('misc.depends', [
],
collection: collection,
className: 'backgrid presentation table backgrid-striped table-bordered table-hover',
className: 'backgrid table presentation table-bordered table-noouter-border table-hover',
});
// Condition is used to save grid object to change the label of the header.

View File

@@ -1,30 +1,6 @@
/*
* CSS for Storage Manager Dialog
*/
.file_manager #uploader {
padding: 2px 4px;
border-width: 1px;
height: auto;
min-height:30px;
max-height: 80px;
overflow: hidden;
border-bottom: 1px;
}
#uploader .input-path {
font-size: 14px;
margin: 0;
padding: 0;
display: block;
float: left;
text-align: left;
line-height:1.6em;
width: calc(100% - 72px);
text-overflow: ellipsis;
overflow: hidden;
}
.uploadresponse {
display: none;
}
@@ -47,12 +23,10 @@
.fileinfo #contents li p > span.less_text,
.fileinfo table#contents tr td:first-child p span.less_text {
width: 100%;
display: inline-block;
text-overflow: ellipsis;
overflow: hidden;
text-align: center;
white-space: nowrap;
padding: 0 10px;
}
.fileinfo table#contents tr td p {
@@ -108,7 +82,6 @@ x:-o-prefocus, .file-input-container {top:16px;width:198px;}
/** Input file Replacement - end */
.file_listing #contents.grid {
padding: 25px;
text-align: left;
}
@@ -168,6 +141,11 @@ button.list span {
position: relative;
}
#dropzone-container {
min-height: 100%;
}
#dropzone-container h2 {
font-size: 20px;
margin-top: 0;
@@ -186,97 +164,6 @@ button.list span {
width: 100% !important;
}
.storage_dialog {
height: 100%;
width: 100%;
}
.storage_content {
height: 100%;
width: 100%;
}
.file_manager {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.file_manager .fileinfo {
height: calc(100% - 90px);
overflow: hidden;
position: relative;
}
.file_manager .fileinfo #contents{
padding: 5px;
text-align: left;
display: inline-block;
height: 100%;
width: 100%;
overflow: hidden;
}
.file_manager .fileinfo #contents thead tr{
position: relative;
display: block;
width: 100%;
}
.file_manager .fileinfo #contents thead tr th:nth-child(1),
.file_manager .fileinfo #contents tbody tr td:nth-child(1) {
position: relative;
width: 100%;
min-width: 100%;
max-width: 100%;
}
.file_manager .fileinfo #contents thead tr th:nth-child(2) {
width: 152px;
min-width: 152px;
max-width: 152px;
padding-left: 10px;
}
.file_manager .fileinfo #contents tbody tr td:nth-child(2) {
width: 150px;
min-width: 150px;
max-width: 150px;
}
.file_manager .fileinfo #contents thead tr th:nth-child(3) {
width: 197px;
min-width: 197px;
max-width: 197px;
padding-left: 10px;
}
.file_manager .fileinfo #contents tbody tr td:nth-child(3) {
width: 177px;
min-width: 177px;
max-width: 177px;
}
.file_manager .fileinfo #contents tbody {
display: block;
overflow: auto;
width: 100%;
height: calc(100% - 30px);
}
.file_manager .fileinfo #contents tbody tr{
/*display: table;*/
max-width: 100%;
width: 100%;
cursor: pointer;
}
.file_manager .upload_file #dropzone-container {
height: 100%;
}
.file_manager .upload_file #multiple-uploads .dz-message {
text-align: center;
}
@@ -313,12 +200,6 @@ button.list span {
width: 150px;
}
.allowed_file_types .change_file_types {
position: absolute;
top: 4px;
right: 0;
}
.allowed_file_types .change_file_types select {
width: 75px;
margin-left: 10px;
@@ -326,10 +207,6 @@ button.list span {
height: 22px;
}
.allowed_file_types .change_file_types label {
float: right;
}
.upload_file .file_upload_main .show_error p.size {
text-align: center;
}
@@ -442,10 +319,18 @@ div.change_file_types span {
}
/* Overriding the css for the dropzone */
.dropzone {
text-align: center;
}
.dropzone .dz-preview .dz-progress {
height: initial;
}
.dropzone.dz-clickable {
cursor: move;
}
.dropzone .dz-preview .dz-progress .dz-upload {
bottom: initial;
}

View File

@@ -12,15 +12,14 @@ module.exports = Alertify.dialog('createModeDlg', function() {
setup: function() {
return {
buttons: [{
text: gettext('Cancel'),
key: 27,
className: 'btn btn-secondary fa fa-times file_manager_create_cancel pg-alertify-button',
},{
text: gettext('Create'),
key: 13,
className: 'btn btn-primary fa fa-file file_manager_create file_manager_ok pg-alertify-button disabled',
},
{
text: gettext('Cancel'),
key: 27,
className: 'btn btn-danger fa fa-times file_manager_create_cancel pg-alertify-button',
},
],
focus: {
element: 0,

View File

@@ -18,11 +18,6 @@ module.exports = Alertify.dialog('fileSelectionDlg', function() {
self.dialog_type = params['dialog_type'];
this.set('title', params['dialog_title']);
if (_.isUndefined(params['btn_primary'])) {
params['btn_primary'] = 'Select';
}
this.set('label', params['btn_primary']);
this.params = JSON.stringify(params);
this.elements.dialog.style.minWidth = '630px';
@@ -74,21 +69,19 @@ module.exports = Alertify.dialog('fileSelectionDlg', function() {
$($(self.elements.footer).find('.file_manager_ok')).trigger('click');
});
}, 200);
self.__internal.buttons[0].element.disabled = true;
self.__internal.buttons[1].element.disabled = true;
},
setup: function() {
return {
buttons: [{
text: gettext('Cancel'),
key: 27,
className: 'btn btn-secondary fa fa-times pg-alertify-button',
},{
text: gettext('Select'),
key: 13,
className: 'btn btn-primary fa fa-file file_manager_ok pg-alertify-button disabled',
},
{
text: gettext('Cancel'),
key: 27,
className: 'btn btn-danger fa fa-times pg-alertify-button',
},
],
}],
focus: {
element: 0,
},

View File

@@ -576,7 +576,7 @@ define([
result += '</ul>';
} else {
result += '<table id="contents" class="list tablesorter">';
result += '<table id="contents" class="table table-bordered table-noouter-border table-hover tablesorter">';
result += '<thead><tr><th>';
result += '<span>' + lg.name + '</span></th>';
result += '<th><span>' + lg.size + '</span></th><th>';
@@ -589,7 +589,7 @@ define([
var path = _.escape((data[key]).Path),
props = (data[key]).Properties,
cap_classes = '',
cap, class_type;
cap, class_type, icon_type;
for (cap in capabilities) {
if (has_capability(data[key], capabilities[cap])) {
@@ -601,11 +601,14 @@ define([
bindToolbar(data[key]);
if ((data[key]).file_type == 'dir') {
class_type = 'fa fa-folder-open tbl_folder';
class_type = 'tbl_folder';
icon_type = 'fa fa-folder-open';
} else if ((data[key]).file_type == 'drive') {
class_type = 'fa fa-hdd-o tbl_drive';
class_type = 'tbl_drive';
icon_type = 'fa fa-hdd-o';
} else {
class_type = 'fa fa-file-text tbl_file';
class_type = 'tbl_file';
icon_type = 'fa fa-file-text';
}
result += '<tr class="' + cap_classes + '">';
@@ -617,16 +620,21 @@ define([
fm_filename = _.escape(fm_filename);
result += '<td title="' + path + '" class="' + class_type + '">';
let data_protected = '';
if ((data[key]).Protected == 1) {
result +=
'<i class="fa fa-lock tbl_lock_icon" data-protected="protected"></i>';
data_protected = '<i class="fa fa-lock tbl_lock_icon" data-protected="protected"></i>';
}
if (!has_capability(data[key], 'rename')) {
result += data_protected;
result += '<span title="' + (data[key]).Filename + '">' +
fm_filename + '</span></td>';
} else {
result += '<p><input type="text" class="fm_file_rename"/><span class="less_text" title="' +
fm_filename + '">' + fm_filename + '</span></p></td>';
result += '<p><input type="text" class="fm_file_rename"/>'+
'<span class="'+icon_type+'"></span>' +
data_protected +
'<span class="less_text ml-2" title="' + fm_filename + '">' + fm_filename + '</span>' +
'</p></td>';
}
if (props.Size && props.Size != '') {
result += '<td><span title="' + props.Size + '">' +
@@ -1104,20 +1112,15 @@ define([
selected = false,
have_all_types = false;
select_box = '<div class=\'change_file_types\'>' +
gettext('Show hidden files and folders') +
'? <input type=\'checkbox\' id=\'show_hidden\' onclick=\'pgAdmin.FileUtils.handleClick(this)\' tabindex=\'11\'>' +
'<span></span>' +
'<select name=\'type\' tabindex=\'12\'>';
let fileFormats = '';
while (i < types_len) {
t = allowed_types[i];
if (!selected && (types_len == 1 || t != '*')) {
select_box += '<option value=' + t + ' selected>' + t + '</option>';
fileFormats += '<option value=' + t + ' selected>' + t + '</option>';
selected = true;
have_all_types = (have_all_types || (t == '*'));
} else {
select_box += '<option value="' + t + '">' +
fileFormats += '<option value="' + t + '">' +
(t == '*' ? gettext('All Files') : t) + '</option>';
have_all_types = (have_all_types || (t == '*'));
}
@@ -1125,9 +1128,18 @@ define([
}
if (!have_all_types) {
select_box += '<option value="*">' + gettext('All Files') + '</option>';
fileFormats += '<option value="*">' + gettext('All Files') + '</option>';
}
select_box += '</select><label>' + gettext('Format') + ': </label></div>';
select_box = `<div class='change_file_types d-flex align-items-center p-1'>
<div>
${gettext('Show hidden files and folders')} ?
<input type='checkbox' id='show_hidden' onclick='pgAdmin.FileUtils.handleClick(this)' tabindex='11'>
</div>
<div class="ml-auto">
<label>${gettext('Format')}</label>
<select name='type' tabindex='12'>${fileFormats}</select>
<div>`;
}
$('.allowed_file_types').html(select_box);
@@ -1399,10 +1411,12 @@ define([
$('#uploader .upload').off().on('click', function() {
// we create prompt
var msg = '<div id="dropzone-container">' +
'<button class="fa fa-times dz_cross_btn" tabindex="7"></button>' +
'<div id="multiple-uploads" class="dropzone"></div>' +
'<div class="prompt-info">' + lg.file_size_limit +
var msg = '<div id="dropzone-container" class="d-flex flex-column flex-grow-1">' +
'<button class="fa fa-times fa-lg dz_cross_btn ml-auto" tabindex="7"></button>' +
'<div id="multiple-uploads" class="dropzone flex-grow-1 d-flex p-1">'+
'<div class="dz-default dz-message d-none"></div>'+
'</div>' +
'<div class="prompt-info">Drop files here to upload. ' + lg.file_size_limit +
config.upload.fileSizeLimit + ' ' + lg.mb + '.</div>',
path = $('.currentpath').val(),
filesizelimit = config.upload.fileSizeLimit,
@@ -1419,10 +1433,10 @@ define([
acceptFiles = null;
}
$('.file_manager .upload_file').toggle();
$('.file_manager .upload_file').toggleClass('d-none');
$('.file_manager .file_listing').toggleClass('d-none');
$('.file_manager .upload_file').html(msg);
//var previewTemplate = '<div id="dropzone-container">';
var previewTemplate = '<div class="file_upload_main dz-preview dz-file-preview">' +
'<div class="show_error">' +
'<p class="size dz-size" data-dz-size></p>' +
@@ -1454,7 +1468,8 @@ define([
autoProcessQueue: true,
init: function() {
$('.dz_cross_btn').off().on('click', function() {
$('.file_manager .upload_file').toggle();
$('.file_manager .upload_file').toggleClass('d-none');
$('.file_manager .file_listing').toggleClass('d-none');
});
},
sending: function(file, xhr, formData) {
@@ -1594,10 +1609,12 @@ define([
// template to create new folder in table view
folder_div = $(
'<tr class=\'cap_download cap_delete cap_select_file cap_select_folder cap_rename cap_create cap_upload\'>' +
'<td title=\'\' class=\'fa fa-folder-open tbl_folder\'>' +
'<p><input type=\'text\' class=\'fm_file_rename\'><span>' +
lg.new_folder + '</span></p>' +
'</td><td><span title=\'\'></span></td>' +
'<td title=\'\' class=\' tbl_folder\'>' +
'<input type=\'text\' class=\'fm_file_rename\'>'+
'<span class="fa fa-folder-open"></span>' +
'<span>' + lg.new_folder + '</span>' +
'</td>'+
'<td><span title=\'\'></span></td>' +
'<td></td>' +
'</tr>'
);

View File

@@ -3,12 +3,15 @@
color: $color-gray;
}
.file_listing #contents.grid li.selected {
border: 1px solid $color-primary-lighter;
.file_listing {
min-width: 100%;
}
.file_listing #contents.grid li.selected, .fileinfo #contents tbody tr.selected {
background: $color-primary-lighter !important;
.file_listing #contents.grid li:hover,
.file_listing #contents.grid li.selected {
cursor: pointer;
border: $table-hover-border;
background: $table-hover-bg-color;
}
.fileinfo table#contents tr td p {
@@ -25,10 +28,6 @@
color: $color-gray;
}
.file_manager button {
background-color: $color-gray-light;
}
.newfile {
position: absolute;
top:0;
@@ -87,40 +86,23 @@
width: 100%;
}
.file_listing #contents.list th {
font-weight: bold;
cursor: pointer;
color: $color-fg-inverse;
}
.file_listing #contents.list td.tbl_folder:first-child:before {
margin-right: 5px;
color: $color-warning;
}
.file_listing #contents.list td.tbl_drive:first-child:before {
color: $color-gray-light;
margin-right: 5px;
}
.file_listing #contents.list tbody tr:nth-child(even):hover {
background-color: $color-gray-lighter !important;
}
.file_listing #contents.grid li:hover {
border: 1px solid $color-gray-lighter;
background-color: $color-gray-lighter;
cursor: pointer;
height: 80px;
}
.btn-group.filemanager-btn-group .btn:not(:first-child):not(:last-child),
.btn-group.filemanager-path-group .btn:not(:first-child):not(:last-child) {
border-left: 1px solid $color-gray-light;
}
.file_manager {
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
}
.file_manager #uploader {
border-bottom: $panel-border;
}
.file_manager #uploader .filemanager-path-group {
padding: 0;
display: block;
@@ -149,65 +131,21 @@
overflow: hidden;
}
.file_manager .fileinfo #contents tbody tr:nth-child(even) {
background: $color-gray-lighter;
}
.file_manager .fileinfo #contents thead tr th:not(:first-child) {
border-left: 1px solid $color-bg;
}
.file_manager .upload_file {
display: none;
z-index: 1;
margin-bottom: auto;
top: 0;
margin-top: 0;
height: calc(100% - 5px);
width: 100%;
border: none;
position: absolute;
bottom: 0;
background-color: $color-bg-inverse;
padding: 0px;
padding-top: 22px;
padding-left: 10px;
}
.file_manager .upload_file #multiple-uploads {
height: calc(100% - 20px);
background: $color-bg-inverse;
color: $color-fg-inverse;
padding: 0px !important;
overflow: auto;
width: 100%;
.file_manager .upload_file #dropzone-container {
background: $color-gray-light;
}
.fileinfo .prompt-info {
text-align: center;
color: $color-fg-inverse;
color: $color-fg-theme;
}
.fileinfo .file_listing {
display: block;
height: calc(100% - 35px);
border: 1px solid $color-gray-lighter;
border-bottom: none;
font-size: 12px;
.allowed_file_types {
border-top: $panel-border;
}
.fileinfo .allowed_file_types {
display: block;
height: 25px;
position: absolute;
right: 0;
border-top: 1px solid $color-gray-lighter;
padding-top: 4px;
bottom: 4px;
width: 100%;
background: $color-bg;
white-space: nowrap;
.upload_file{
min-width: 100%;
}
.upload_file .file_upload_main {
@@ -242,7 +180,7 @@
}
.file_upload_main .dz-progress .dz-upload {
background: $color-primary-lighter !important;
background: $color-primary-light !important;
text-align: center;
}
@@ -268,6 +206,10 @@
border: 1px solid $color-fg;
}
.dropzone .dz-message {
color: $color-gray;
}
.fileinfo .fm_dimmer {
height: calc(100% - 32px);
display: none;
@@ -282,14 +224,10 @@
.fileinfo .delete_item, .fileinfo .replace_file {
display: none;
padding: 15px 15px;
opacity: 0.8;
color: $color-fg-inverse;
border: 1px solid $color-gray-light;
border-left: 0;
border-right: 0;
background: $color-bg-inverse;
box-shadow: 1px 0px 3px 1px $color-bg;
font-weight: bold;
background: $color-bg-theme;
position: absolute;
top: 0;
left: 0;
@@ -307,17 +245,15 @@
}
.upload_file .dz_cross_btn {
color: $color-fg-inverse;
font-size: x-large;
right: -4px;
color: $color-fg-theme;
right: 0px;
position: absolute;
top: -1px;
background: transparent;
border: none;
}
.file_manager .fileinfo #contents .fm_lock_icon {
color: $color-danger-lighter;
color: $color-danger;
position: absolute;
top: 6px;
right: 0;
@@ -326,16 +262,16 @@
}
.file_manager .fileinfo #contents .fa-lock.tbl_lock_icon {
color: $color-danger-lighter;
position: absolute;
left: 19px;
top: 5px;
color: $color-danger;
position: relative;
left: -5px;
top: -5px;
font-size: 10px;
}
.file_manager button.ON {
background: $color-gray-lighter;
border: 1px inset $color-gray-lighter;
background: $color-primary;
color: $color-primary-fg;
}
.fileinfo .is_file_replace {
@@ -346,17 +282,16 @@
.file_selection_ctrl button.select_item {
display: inline;
background: $color-gray;
background: -webkit-linear-gradient( $color-gray, $color-gray);
background: -o-linear-gradient( $color-gray, $color-gray-light);
background: -moz-linear-gradient( $color-gray, $color-gray-light);
background: linear-gradient( $color-gray, $color-gray-light);
color: $color-fg-inverse;
background: $color-bg-theme;
padding: 9px 0px 9px 0px;
margin-left: 0px;
margin-right: -7px;
margin-top: -4px;
min-width: 30px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.cap_select_file {
cursor: pointer;
}

View File

@@ -2,55 +2,65 @@
<head>
</head>
<body>
<div class="file_manager container-fluid">
<div id="uploader" class="row">
<div class="col-sm-7">
<div class="file_manager d-flex flex-column">
<div id="uploader" class="p-1">
<div class="d-flex">
<div class="flex-grow-1 mr-1">
<div class="input-group" role="group">
<div class="input-group-prepend">
<button name="home" type="button" value="Home" title="{{ _('Home') }}" class="btn fa fa-home home"
<button name="home" type="button" value="Home" title="{{ _('Home') }}" class="btn btn-secondary bg-gray-lighter home"
tabindex="1">
<span class="fa fa-home fa-lg"></span>
</button>
<button name="level-up" type="button" title="{{ _('Back') }}" value="LevelUp" class="btn fa fa-level-up level-up"
<button name="level-up" type="button" title="{{ _('Back') }}" value="LevelUp" class="btn btn-secondary bg-gray-lighter fa fa-level-up level-up"
disabled tabindex="2">
</button>
</div>
<input id="file-input-path" class="form-control input-path" title="" type="text" tabindex="3" autofocus/>
<input id="file-input-path" class="form-control input-path text-truncate" title="" type="text" tabindex="3" autofocus/>
</div>
</div>
<div class="col-sm-5">
<div class="uploadresponse"></div>
</div>
<div>
<input class="mode" name="mode" type="hidden" value="add"/>
<input class="currentpath" name="currentpath" type="hidden"/>
<div class="btn-group" role="group">
<button type="button" title="{{ _('Refresh') }}" class="btn fa fa-refresh refresh"
tabindex="4"></button>
<button type="button" title="{{ _('Download File') }}" class="btn fa fa-download download"
disabled>
<button type="button" title="{{ _('Refresh') }}" class="btn btn-sm refresh"
tabindex="4">
<span class="fa fa-refresh fa-lg"></span>
</button>
<button name="delete" type="button" title="{{ _('Delete File/Folder') }}" class="btn fa fa-trash delete"
<button type="button" title="{{ _('Download File') }}" class="btn btn-sm download"
disabled>
<span class="fa fa-download fa-lg"></span>
</button>
<button name="rename" type="button" title="{{ _('Rename File/Folder') }}" class="btn fa fa-pencil-square-o rename"
<button name="delete" type="button" title="{{ _('Delete File/Folder') }}" class="btn btn-sm delete"
disabled>
<span class="fa fa-trash fa-lg"></span>
</button>
<button name="rename" type="button" title="{{ _('Rename File/Folder') }}" class="btn btn-sm rename"
tabindex="5">
<span class="fa fa-pencil-square-o fa-lg"></span>
</button>
<button name="newfolder" type="button" title="{{ _('Create new folder') }}" value="New Folder"
class="btn fa fa-folder-open create" tabindex="8">
class="btn btn-sm create" tabindex="8">
<span class="fa fa-folder-open fa-lg"></span>
</button>
<button class="ON fa fa-th btn grid" type="button" title="{{ _('View as grid') }}" tabindex="9">
<div class="btn-group" role="group">
<button class="ON btn btn-secondary btn-sm grid" type="button" title="{{ _('View as grid') }}" tabindex="9">
<span class="fa fa-th fa-lg"></span>
</button>
<button type="button" class="btn fa fa-list list" title="{{ _('View as table') }}" tabindex="10">
<button type="button" class="btn btn-secondary btn-sm list" title="{{ _('View as table') }}" tabindex="10">
<span class="fa fa-list fa-lg"></span>
</button>
</div>
</div>
</div>
<div class="fileinfo">
</div>
<div class="fileinfo flex-grow-1 d-flex">
<span class="activity">
<img src="{{ url_for('static', filename='js/generated/img/load-root.gif') }}"
alt="{{ _('Loading...') }}">
</span>
<div class="file_listing"></div>
<div class="upload_file dropzone"></div>
<div class="allowed_file_types"></div>
<div class="upload_file d-none"></div>
<div class='fm_dimmer'></div>
<div class='delete_item'>
<span>{{ _('Are you sure you want to delete this item?') }}</span>
@@ -67,6 +77,7 @@
</span>
</div>
</div>
<div class="allowed_file_types"></div>
<script>
require(['sources/generated/file_utils'], function() {
pgAdmin.FileUtils.init();

View File

@@ -86,7 +86,7 @@ define('misc.statistics', [
includeDate: false, includeTime: true, includeMilli: true
}) */
},
GRID_CLASSES = 'backgrid presentation table backgrid-striped table-bordered table-hover',
GRID_CLASSES = 'backgrid presentation table table-bordered table-noouter-border table-hover',
wcDocker = window.wcDocker;
_.extend(
@@ -257,6 +257,7 @@ define('misc.statistics', [
}
self.grid = new Backgrid.Grid({
emptyText: 'No data found',
columns: self.columns,
collection: self.collection,
className: GRID_CLASSES,

View File

@@ -1,8 +1,6 @@
.preferences_dialog {
height: 100%;
width: 100%;
padding-top: 34px;
padding-bottom: 39px;
}
.preferences_content {
@@ -32,16 +30,4 @@ div.pgadmin-preference-body div.ajs-content {
font-weight: normal !important;
}
.preferences_content input[type="checkbox"]:focus {
outline: 5px auto -webkit-focus-ring-color;
}
.preferences_content .pgadmin-controls input[type="checkbox"] {
margin-left: -20px !important;
}
.preferences_content .pgadmin-controls .shift,
.preferences_content .pgadmin-controls .control,
.preferences_content .pgadmin-controls .alt {
margin-left: 15px !important;
}

View File

@@ -30,7 +30,7 @@ define('pgadmin.preferences', [
controls = [], // Keep tracking of all the backform controls
// created by the dialog.
// Dialog containter
$container = $('<div class=\'preferences_dialog\'></div>');
$container = $('<div class=\'preferences_dialog d-flex flex-row\'></div>');
/*
@@ -94,6 +94,7 @@ define('pgadmin.preferences', [
* Clear the existing html in the preferences content
*/
var content = $container.find('.preferences_content');
/*
* We should clean up the existing controls.
*/
@@ -306,6 +307,14 @@ define('pgadmin.preferences', [
/*
* Clear the existing html in the preferences content
*/
// Keyboard short cuts and nodes wiull have striped divs
if (d.label.toLowerCase() == 'keyboard shortcuts' || d.label.toLowerCase() == 'nodes')
$container.find('.preferences_content').addClass('striped-divs');
else
$container.find('.preferences_content').removeClass('striped-divs');
$container.find('.preferences_content');
renderPreferencePanel(d.preferences);
return true;
@@ -363,9 +372,9 @@ define('pgadmin.preferences', [
dialogContentCleanup();
$container.append(
'<div class=\'pg-el-xs-3 preferences_tree aciTree\'></div>'
'<div class=\'pg-el-3 preferences_tree aciTree\'></div>'
).append(
'<div class=\'pg-el-xs-9 preferences_content\'>' +
'<div class=\'pg-el-9 preferences_content\'>' +
gettext('Category is not selected.') +
'</div>'
);
@@ -397,7 +406,7 @@ define('pgadmin.preferences', [
buttons: [{
text: '',
key: 112,
className: 'btn btn-default pull-left fa fa-lg fa-question',
className: 'btn btn-secondary pull-left fa fa-question pg-alertify-icon-button',
attrs: {
name: 'dialog_help',
type: 'button',
@@ -408,14 +417,14 @@ define('pgadmin.preferences', [
}
),
},
}, {
text: gettext('OK'),
key: 13,
className: 'btn btn-primary fa fa-lg fa-save pg-alertify-button',
}, {
text: gettext('Cancel'),
key: 27,
className: 'btn btn-danger fa fa-lg fa-times pg-alertify-button',
className: 'btn btn-secondary fa fa-lg fa-times pg-alertify-button',
}, {
text: gettext('Save'),
key: 13,
className: 'btn btn-primary fa fa-lg fa-save pg-alertify-button',
}],
focus: {
element: 0,
@@ -438,7 +447,7 @@ define('pgadmin.preferences', [
return;
}
if (e.button.text == gettext('OK')) {
if (e.button.text == gettext('Save')) {
preferences.updateAll();
/* Find the modules changed */
@@ -460,7 +469,7 @@ define('pgadmin.preferences', [
},
hooks: {
onshow: function() {
$(this.elements.body).addClass('pgadmin-preference-body');
// $(this.elements.body).addClass('pgadmin-preference-body');
},
},
};

View File

@@ -6,3 +6,19 @@
border-right: 2px solid $color-gray-light;
background-image: $color-gray-lighter;
}
.preferences_content {
&.striped-divs > {
div.pgadmin-control-group:nth-of-type(odd) {
background: $color-gray-light;
padding-top: 6px;
}
div.pgadmin-control-group:nth-of-type(even) {
background: $color-bg-theme;
}
}
}
.btn-checkbox {
padding: $btn-checkbox-padding;
}

View File

@@ -1,11 +1,84 @@
@font-face {
font-family: "Open Sans";
src: url("~top/static/fonts/OpenSans-Regular.ttf");
src: url("~top/static/fonts/OpenSans-Regular.ttf") format("truetype");
speak: none;
font-style: normal;
font-weight: normal;
font-style: normal; }
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
@font-face {
font-family: "Open Sans Semibold";
src: url("~top/static/fonts/OpenSans-SemiBold.ttf") format("truetype");
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
@font-face {
font-family: "Open Sans Bold";
src: url("~top/static/fonts/OpenSans-Bold.ttf") format("truetype");
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
@font-face {
font-family: "Source Code Pro";
src: url("~top/static/fonts/SourceCodePro-Regular.ttf");
src: url("~top/static/fonts/SourceCodePro-Regular.ttf") format("truetype");
speak: none;
font-style: normal;
font-weight: normal;
font-style: normal; }
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
@font-face {
font-family: "Roboto";
src: url("~top/static/fonts/Roboto-Regular.ttf") format("truetype");
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
@font-face {
font-family: "Roboto Medium";
src: url("~top/static/fonts/Roboto-Medium.ttf") format("truetype");
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
@font-face {
font-family: "Roboto Bold";
src: url("~top/static/fonts/Roboto-Bold.ttf") format("truetype");
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 67 24" style="enable-background:new 0 0 67 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#333333;stroke-width:4;stroke-miterlimit:10;}
</style>
<title>collapse</title>
<g id="Layer_3">
<polyline class="st0" points="8,4 16,12 8,20 "/>
</g>
<g id="Layer_3_1_">
<polyline class="st0" points="63,8.8 55,16.8 47,8.8 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 634 B

View File

@@ -0,0 +1,283 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 350 350" style="enable-background:new 0 0 350 350;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.3;}
.st1{fill:#C2D2DE;}
.st2{fill:#336791;stroke:#C2D2DE;stroke-width:0.5;stroke-miterlimit:10;}
.st3{fill:none;stroke:#C2D2DE;stroke-width:0.5;stroke-miterlimit:10;}
</style>
<title>forgot_password</title>
<g class="st0">
<path class="st1" d="M164.8,295.6L164.8,295.6L164.8,295.6z"/>
<path class="st1" d="M189.1,86.3c0.3-2.9,0.4-5.7,0.5-8.6s0.1-5.7,0.1-8.5s-0.2-5.7-0.4-8.5c-0.1-1.7-0.3-3.5-0.5-5.2
s-0.4-3.4-0.6-5.1l0,0c-0.3,2.8-0.7,5.5-1,8.2s-0.4,5.6-0.6,8.5s-0.1,5.7,0,8.5s0.2,5.7,0.4,8.6c0.2,2.4,0.4,4.7,0.7,7l0.8,0.1
C188.8,89.7,189,88,189.1,86.3z"/>
<path class="st1" d="M188.1,44.7C188.1,44.7,188.2,44.7,188.1,44.7C188.2,44.6,188.2,44.6,188.1,44.7c0.7-3.4,1-6.8,1-10.2
c0-1.7-0.1-3.3-0.3-4.9s-0.5-3.3-0.8-5l0,0c-0.3,1.6-0.5,3.2-0.7,4.8c-0.1,0.8-0.2,1.6-0.2,2.4c0,0.8-0.1,1.8-0.1,2.7
c0,3.4,0.3,6.8,0.9,10.2C188,44.7,188,44.7,188.1,44.7L188.1,44.7z"/>
<path class="st1" d="M186.5,242.8c0,2.8-0.1,5.6-0.1,8.4c0,3.1,0.1,6.2,0.4,9.3c0.1,1.5,0.3,3.1,0.5,4.6s0.5,2.8,0.7,4.3l0,0
c0.2-1.3,0.4-2.5,0.6-3.8s0.4-2.7,0.5-4.1c0.3-2.8,0.4-5.6,0.5-8.4s0-5.6,0-8.4c0-1.4,0-2.8,0-4.2s0-2.8,0-4.2c0-0.2,0-0.4,0-0.6
h-3C186.6,238.2,186.6,240.5,186.5,242.8z"/>
<path class="st1" d="M188.5,286c-0.1-0.9-0.2-1.8-0.3-2.7s-0.1-2-0.1-3l0,0c0,1,0,1.9-0.1,2.9s-0.2,1.8-0.3,2.8
c-0.1,0.5-0.1,1-0.2,1.4s-0.1,1-0.1,1.4c-0.1,1-0.2,2-0.2,3c-0.1,1.9,0,3.9,0.2,5.8s0.4,3.9,0.7,5.8l0,0c0,0.1,0,0.2,0,0.3l0,0
c0-0.1,0-0.2,0-0.3l0,0c0.3-1.9,0.5-3.8,0.7-5.7s0.2-4,0.2-6c0-1-0.1-1.9-0.2-2.9S188.6,286.9,188.5,286z"/>
<path class="st1" d="M245.8,336.1L245.8,336.1c0.2,0.7,0.5,1.4,0.9,2s1,1.2,1.6,1.6l0,0c-0.2-0.7-0.5-1.4-0.9-2
C246.9,337.1,246.4,336.6,245.8,336.1z"/>
<path class="st1" d="M146,139.1c-1.1-0.9-2.1-1.8-3.2-2.7c-1.1-0.9-2.1-1.8-3.2-2.6c-2.2-1.8-4.5-3.5-6.8-5.1c-1.4-1-2.9-2-4.3-2.9
c-0.7-0.5-1.5-0.9-2.2-1.4l-2.2-1.3l0,0c0.6,0.6,1.1,1.2,1.7,1.8s1.2,1.2,1.9,1.9c1.2,1.2,2.5,2.3,3.7,3.5c2.6,2.4,5.3,4.6,8.1,6.8
c1.5,1.2,3,2.3,4.6,3.5c0.8,0.6,1.5,1.1,2.3,1.6c0.4,0.3,0.9,0.6,1.3,0.9v-2.5C147,140,146.5,139.5,146,139.1z"/>
<path class="st1" d="M108.9,112.7c0.9,0.7,1.9,1.3,2.8,2s1.9,1.3,2.9,1.9s2,1.3,3,1.9s1.9,1.2,2.9,1.8l0,0
c-0.8-0.8-1.6-1.5-2.4-2.3s-1.7-1.7-2.6-2.5c-1.7-1.6-3.3-3.2-5.1-4.7c-1.8-1.5-3.8-3-5.8-4.3c-1.9-1.3-3.9-2.4-5.9-3.5l0,0
c1.5,1.7,3,3.3,4.6,4.9C105.2,109.7,107,111.2,108.9,112.7z"/>
<path class="st1" d="M83.7,92.2c0.9,0.7,1.9,1.3,2.9,1.9s2,1.2,3,1.8l0,0c-0.8-0.9-1.6-1.7-2.4-2.6c-0.8-0.8-1.6-1.6-2.5-2.4
c-1.8-1.4-3.7-2.6-5.8-3.6l0,0C80.3,89.2,81.9,90.8,83.7,92.2z"/>
<path class="st1" d="M239.7,215.5c1,1,1.9,2.1,2.9,3.1c2,1.9,4,3.8,6.1,5.7c1,0.9,2.1,1.8,3.1,2.7s2.2,1.7,3.3,2.6
c2.2,1.7,4.4,3.4,6.5,5.1c2,1.6,4,3.1,6,4.7s4.2,3.4,6.5,4.9s4.2,2.8,6.4,4.1c1.1,0.6,2.2,1.3,3.3,1.9s2.1,1.1,3.2,1.7l0,0
c-0.5-0.6-1.1-1.3-1.6-1.9s-1.2-1.4-1.9-2c-1.3-1.4-2.6-2.7-3.9-4c-2.7-2.6-5.6-5.1-8.6-7.4c-1-0.8-2-1.5-3-2.3l-3.3-2.6l-6.5-5.2
c-1.2-0.9-2.4-1.9-3.6-2.8s-2.2-1.6-3.3-2.4c-2.3-1.6-4.6-3.1-6.9-4.6c-1.5-0.9-3-1.8-4.5-2.7L239.7,215.5L239.7,215.5z"/>
<path class="st1" d="M237.7,147.7c2.4-1.4,4.9-2.8,7.2-4.4c1.2-0.8,2.4-1.5,3.5-2.3s2.2-1.7,3.3-2.6l0.6-0.5c0.1,0,0.1-0.1,0.2-0.1
c0.2-0.2,0.4-0.4,0.6-0.6l0,0c-0.3,0.1-0.5,0.2-0.8,0.2c-0.2,0-0.3,0.1-0.5,0.1c-0.7,0.2-1.3,0.4-2,0.7c-1.4,0.5-2.7,1-4,1.6
c-0.6,0.3-1.2,0.6-1.8,0.9l-0.9,0.4l-1.1,0.5c-1.3,0.6-2.5,1.3-3.8,1.9s-2.4,1.3-3.6,2s-2.4,1.5-3.6,2.2c-1,0.6-1.9,1.2-2.8,1.8
c1.1,0.3,2.3,0.7,3.3,1.2C233.6,149.9,235.7,148.9,237.7,147.7z"/>
<path class="st1" d="M266.9,128.5c-0.9,0.8-1.8,1.6-2.6,2.5l0,0c2.4-0.4,4.7-1.3,6.8-2.4c1-0.6,2-1.3,2.9-2.1
c0.4-0.3,0.9-0.7,1.3-1.1s0.7-0.7,1.1-1.1l0,0c-0.5,0.1-0.9,0.2-1.4,0.3c-0.2,0-0.5,0.1-0.7,0.2l-0.9,0.3c-1.2,0.4-2.4,0.9-3.5,1.4
C268.8,127,267.8,127.7,266.9,128.5z"/>
<path class="st1" d="M292.2,113.1c-0.9,0.5-1.8,1.1-2.6,1.7s-1.9,1.3-2.8,2.1c-1.7,1.3-3.3,2.7-4.8,4.2l0,0c2-0.5,4-1.1,6-1.8
c1-0.4,2.1-0.8,3.1-1.3s2-0.9,3-1.4s1.8-1.1,2.7-1.6c1-0.6,2-1.3,2.9-2.1c1.6-1.3,3.2-2.7,4.6-4.2l0,0c-2,0.4-4,1-5.9,1.6
c-1.1,0.4-2.2,0.8-3.2,1.3S293.2,112.6,292.2,113.1z"/>
<path class="st1" d="M79.1,236.3c2.5-1.3,5-2.7,7.5-4.1s4.9-2.8,7.4-4.1c4.9-2.7,9.8-5.5,14.7-8.2c1.2-0.7,2.5-1.4,3.7-2.1
s2.4-1.4,3.6-2.2c2.4-1.5,4.7-3.1,7-4.8c1.6-1.2,3.2-2.3,4.7-3.5l0,0c-2.6,1-5.2,2-7.8,3.1c-2.6,1.1-5.1,2.3-7.7,3.6
s-5,2.7-7.5,4.1l-7.4,4.1c-4.9,2.8-9.8,5.6-14.7,8.3c-2.5,1.4-5,2.8-7.4,4.3s-4.7,3-7,4.6c-0.8,0.6-1.7,1.2-2.5,1.8
c-0.4,0.3-0.8,0.6-1.1,0.9c-0.4,0.2-0.7,0.5-1,0.8c-0.1,0.1,0,0.3,0.2,0.2s0.5-0.2,0.7-0.2c0.3-0.1,0.6-0.2,0.9-0.3
c0.7-0.2,1.3-0.5,2-0.8c1.3-0.6,2.6-1.1,3.8-1.7C74,238.8,76.6,237.6,79.1,236.3z"/>
<path class="st1" d="M55,247.9L55,247.9c-2.1,0.8-4.1,1.6-6.1,2.6c-1,0.5-2,1-3,1.5c-0.5,0.3-1,0.6-1.4,0.9s-1,0.6-1.5,0.9
c-0.3,0.2-0.4,0.6-0.2,0.9l0,0c0.2,0.3,0.6,0.4,0.9,0.2c0.4-0.3,0.9-0.5,1.4-0.7s1-0.5,1.5-0.8c1-0.5,1.9-1.1,2.9-1.7
C51.3,250.6,53.2,249.3,55,247.9L55,247.9z"/>
<path class="st1" d="M226.5,128.1c1.8-2.2,3.6-4.4,5.3-6.7l5.3-6.6c1.4-1.8,2.8-3.6,4.2-5.4s2.7-3.6,4-5.4s2.5-3.7,3.7-5.5
s2.3-3.7,3.4-5.6l0,0l0,0c-1,0.9-2,1.8-2.9,2.8s-1.9,2-2.9,3c-1.9,2-3.8,4.1-5.6,6.3c-1.8,2.2-3.5,4.4-5.3,6.6l-5.2,6.7
c-2.8,3.6-5.7,7.2-8.3,10.9c-0.4,0.6-0.8,1.2-1.2,1.8v3.5C222.9,132.4,224.7,130.2,226.5,128.1z"/>
<path class="st1" d="M264.7,79.4c1-1.3,1.9-2.7,2.8-4.2c0.8-1.4,1.5-2.8,2.2-4.3l0,0l0,0c-1.2,0.9-2.3,1.9-3.4,2.9
c-1.2,1.1-2.3,2.3-3.4,3.5c-1.1,1.3-2,2.7-2.9,4.2c-0.8,1.5-1.6,3-2.2,4.5l0,0C260.4,84.1,262.7,81.9,264.7,79.4z"/>
<path class="st1" d="M276.6,63c1-0.9,1.9-1.9,2.8-2.9c0.9-1.1,1.7-2.2,2.4-3.4c0.7-1.2,1.3-2.4,1.9-3.6l0,0c-1,0.9-2.1,1.7-3,2.7
c-1,1-1.9,2-2.8,3.2c-0.8,1.1-1.5,2.2-2.2,3.4s-1.4,2.4-2.1,3.6l0,0C274.6,64.9,275.6,64,276.6,63z"/>
<path class="st1" d="M138.8,236c-1.9,2.1-3.8,4.2-5.6,6.3c-1.8,2.2-3.6,4.4-5.3,6.6l-5.3,6.6c-1.8,2.2-3.5,4.4-5.3,6.6l-5.2,6.6
c-3.6,4.5-7.2,8.9-10.5,13.6c-1.4,2-2.7,4-4,6.1c-0.7,1.1-1.3,2.1-1.9,3.2s-1.1,1.9-1.6,2.9l0,0l1.2-1.1c0.5-0.5,1.1-1,1.6-1.5
c1-1,2-2,3-3c2-2,3.9-4.1,5.7-6.3s3.7-4.5,5.4-6.8s3.4-4.5,5.1-6.7c2.6-3.3,5.1-6.6,7.7-10c1.7-2.1,3.3-4.3,5-6.4
c1.8-2.3,3.6-4.6,5.3-6.9s3.3-4.6,4.9-6.9c0.7-1.1,1.4-2.2,2.1-3.3c-0.6-0.1-1.1-0.2-1.7-0.4C139.3,235.5,139,235.7,138.8,236z"/>
<path class="st1" d="M217.4,109.2L217.4,109.2c0-0.2,0.1-0.5,0.2-0.7l0,0l-0.3,0.5c-0.3,0.4-0.5,0.8-0.8,1.2
c0.1,0.3,0.3,0.5,0.4,0.8c0-0.1,0-0.2,0.1-0.2"/>
<path class="st1" d="M221.9,98.7c0.1-0.2,0.3-0.4,0.4-0.6l0.4-0.8c0.3-0.6,0.6-1.2,0.9-1.9l1.9-3.8c1.3-2.5,2.5-5.1,3.6-7.6
c2.3-5.1,4.7-10.3,7-15.4c1.2-2.6,2.3-5.1,3.5-7.7c0.6-1.3,1.2-2.5,1.8-3.8s1.2-2.5,1.8-3.8s1.2-2.6,1.7-3.9s1.2-2.7,1.8-4
c0.2-0.6,0.5-1.2,0.7-1.8s0.4-1.3,0.6-2c0.4-1.3,0.7-2.5,1-3.8c0.2-0.7,0.3-1.4,0.5-2.1v-0.1c0-0.2,0.1-0.5,0.2-0.7l0,0
c-0.1,0.2-0.3,0.4-0.4,0.6l-0.1,0.1c-1.2,1.8-2.5,3.7-3.6,5.6c-0.6,1-1.1,2-1.6,3c-0.2,0.5-0.4,1-0.7,1.5s-0.4,1-0.7,1.6
c-1.7,3.7-3.1,7.5-4.7,11.3s-3.1,7.4-4.6,11.2c-2.1,4.9-4.1,9.7-6.2,14.6c-1,2.4-2,4.9-2.9,7.3c-0.5,1.2-0.9,2.4-1.4,3.6
c-0.2,0.6-0.4,1.2-0.7,1.8c-0.1,0.3-0.2,0.6-0.3,0.9C221.9,98.2,221.9,98.4,221.9,98.7L221.9,98.7
C221.8,98.7,221.9,98.8,221.9,98.7z"/>
<path class="st1" d="M255.3,24.4c0.6-1.4,1-2.9,1.1-4.4c0-0.1,0-0.2,0-0.3l0,0c-0.4,0.5-0.9,1.1-1.3,1.7c-0.5,0.7-0.9,1.4-1.2,2.1
c-0.6,1.4-0.9,3-1,4.5l0,0C253.8,26.9,254.6,25.7,255.3,24.4z"/>
<path class="st1" d="M155.2,246.7c-1.2,2.5-2.4,5.1-3.5,7.7c-1.1,2.6-2.3,5.2-3.4,7.8s-2.2,5.1-3.3,7.6s-2.3,5.2-3.4,7.9
s-2,5.1-2.9,7.7c-0.4,1.3-0.9,2.6-1.3,4c-0.2,0.6-0.4,1.3-0.6,1.9s-0.4,1.3-0.5,1.9c-0.1,0.2,0,0.4,0.2,0.5s0.4,0,0.5-0.2l0,0
c0.4-0.5,0.6-1,1-1.5s0.7-1.2,1.1-1.9c0.7-1.2,1.4-2.4,2.1-3.6c1.3-2.5,2.6-5,3.8-7.5s2.3-5.1,3.4-7.7s2.3-5.2,3.4-7.8
s2.2-5.1,3.3-7.6s2.3-5.2,3.3-7.9c1.5-3.9,2.8-7.9,3.9-12h-1.2C159.1,239.4,157,243,155.2,246.7z"/>
<path class="st1" d="M133.7,300.2c-0.7,1-1.3,1.9-1.9,2.9c-0.5,0.9-1,1.9-1.5,2.9c-0.5,1.1-0.9,2.2-1.2,3.3c-0.3,1-0.6,2.1-0.9,3.2
c0,0,0.1,0.1,0.1,0c0.6-0.9,1.2-1.8,1.8-2.8s1.1-2,1.6-3.1c0.4-1,0.8-2,1.1-3.1C133.1,302.4,133.4,301.3,133.7,300.2L133.7,300.2z"
/>
<path class="st1" d="M173.5,244c-0.4,2.2-0.9,4.5-1.3,6.7s-0.8,4.5-1.1,6.8c-0.3,2.3-0.6,4.6-0.9,6.9c-0.1,1.1-0.2,2.2-0.3,3.3
s-0.1,2.1-0.2,3.2c0,0.1,0.1,0.3,0.3,0.3l0,0c0.1,0,0.2-0.1,0.3-0.2l0,0c0.5-1.2,0.9-2.5,1.3-3.7s0.9-2.7,1.2-4
c0.8-2.7,1.5-5.4,2.1-8.1s1.2-5.5,1.8-8.3s1.2-5.5,1.7-8.3c0.2-0.9,0.4-1.8,0.5-2.7h-3.8C174.5,238.6,174,241.3,173.5,244z"/>
<path class="st1" d="M168.4,278.1c-1.2,2.9-2.2,5.8-2.8,8.8c-0.3,1.5-0.5,3.1-0.7,4.6c-0.1,1.5-0.2,3-0.3,4.5
c0,0.1,0.1,0.1,0.1,0.1c0.1,0,0.2-0.1,0.2-0.1c0.6-1.4,1-2.8,1.5-4.2c0.5-1.5,0.9-3,1.2-4.6c0.3-1.5,0.4-3.1,0.6-4.6
S168.4,279.6,168.4,278.1L168.4,278.1z M164.8,295.6L164.8,295.6z"/>
<path class="st1" d="M160.4,318L160.4,318z"/>
<path class="st1" d="M162.9,305.3L162.9,305.3c-1,2-1.7,4-2.1,6.2c-0.2,1.2-0.4,2.3-0.4,3.5c-0.1,1.1-0.1,2.2-0.1,3.3l0,0l0.1-0.3
c0.9-2,1.6-4,2.1-6.1C162.9,309.7,163,307.5,162.9,305.3L162.9,305.3z"/>
<path class="st1" d="M207.6,97.2c0.6-3.3,1.1-6.6,1.7-9.9c0.3-1.6,0.6-3.2,0.9-4.9s0.5-3.3,0.8-5c0.2-1.2,0.4-2.4,0.6-3.6
s0.2-2.3,0.3-3.5c0.1-2.2,0.2-4.5,0.3-6.7c0-0.1,0-0.1-0.1-0.1l0,0c-0.1,0-0.2,0-0.2,0.1c-1,2.5-2,5.1-2.9,7.7
c-0.2,0.6-0.4,1.3-0.6,1.9s-0.4,1.4-0.6,2.1s-0.3,1.2-0.5,1.9s-0.4,1.4-0.6,2.2c-0.7,2.8-1.3,5.6-1.9,8.3s-1.3,5.5-1.9,8.2
c0,0.1-0.1,0.2-0.1,0.3c1.5,0.9,3,1.9,4.4,3C207.3,98.5,207.4,97.9,207.6,97.2z"/>
<path class="st1" d="M213.4,56.2c0.3-1.1,0.6-2.2,0.9-3.4s0.7-2.4,1-3.6c0.5-2.3,0.8-4.7,0.9-7.1l0,0c-0.4,1-0.7,2-1,3
s-0.6,2-0.8,3.1c-0.4,2.1-0.6,4.2-0.9,6.3l0,0L213.4,56.2L213.4,56.2z"/>
<path class="st1" d="M217.5,35.6c0.8-1.4,1.4-3,1.8-4.6c0.3-1.7,0.4-3.5,0.2-5.2l0,0c-0.8,1.4-1.4,3-1.8,4.6
c-0.2,0.8-0.3,1.7-0.3,2.5C217.4,33.8,217.5,34.7,217.5,35.6L217.5,35.6z"/>
<path class="st1" d="M146.7,82c0.2,0.7,0.4,1.4,0.7,2c0.5,1.4,1.1,2.7,1.7,4.1c0.6,1.2,1.4,2.4,2.1,3.7s1.5,2.4,2.3,3.6l0,0
c-0.4-1.3-0.9-2.6-1.3-3.9s-1-2.7-1.6-4.1c-0.6-1.3-1.3-2.6-2.1-3.9c-0.4-0.6-0.8-1.2-1.2-1.8l-0.5-0.8c-0.1-0.1-0.1-0.3-0.3-0.3
l0,0c-0.1,0-0.1,0.1-0.1,0.1c0,0.1,0,0.2,0.1,0.3C146.5,81.4,146.6,81.7,146.7,82z"/>
<path class="st1" d="M127.3,45.1c0.5,1.3,1.1,2.5,1.7,3.8s1.2,2.5,1.8,3.7c1.3,2.5,2.5,5,3.7,7.5c0.6,1.2,1.2,2.5,1.9,3.8
c0.6,1.2,1.3,2.4,2,3.7c1.4,2.3,2.8,4.6,4.3,6.9c1.1,1.7,2.2,3.5,3.2,5.2l0,0c-0.4-1.3-0.9-2.5-1.3-3.8s-0.8-2.5-1.2-3.8
c-0.9-2.6-1.7-5.1-2.7-7.6c-1.1-2.7-2.3-5.3-3.5-7.9l-1.7-3.8c-0.6-1.3-1.1-2.6-1.7-3.8c-0.7-1.5-1.4-3-2.1-4.4s-1.5-2.9-2.4-4.4
s-1.7-2.8-2.7-4.2s-1.8-2.5-2.8-3.8c-0.1-0.1-0.1-0.1-0.2-0.1c-0.2,0-0.4,0.2-0.3,0.4v0.1c0.5,2.1,1,4.1,1.7,6.1
C125.5,40.8,126.3,43,127.3,45.1z"/>
<path class="st1" d="M257,312.3c-0.2-0.6-0.4-1.3-0.6-1.9c-0.4-1.3-0.9-2.6-1.4-3.9c-0.9-2.6-1.9-5.2-3-7.7
c-0.6-1.4-1.2-2.8-1.8-4.2c-0.6-1.3-1.2-2.6-1.8-3.9c-1.2-2.5-2.4-5-3.7-7.5c-2.5-5-5-10-7.5-15.1c-1.2-2.6-2.5-5.1-3.7-7.7
c-0.6-1.3-1.2-2.5-1.8-3.8s-1.3-2.5-1.9-3.7c-1.1-2.2-2.4-4.3-3.6-6.4c-0.6-1-1.3-2.1-1.9-3.1s-1.2-2.1-1.9-3.1l0,0
c0.5,1.3,0.9,2.6,1.4,3.9s0.9,2.6,1.4,3.9c1,2.6,2.1,5.2,3.2,7.8s2.4,5.2,3.6,7.7s2.4,5.1,3.6,7.7c2.4,5.1,4.7,10.2,7,15.4
c1.2,2.5,2.4,5.1,3.6,7.6s2.5,5.1,3.9,7.6c1.2,2.1,2.4,4.2,3.7,6.3c0.6,1,1.3,2.1,2,3.1l0.9,1.4c0.2,0.2,0.3,0.5,0.5,0.7
c0.1,0.2,0.2,0.3,0.3,0.5c0,0.1,0.2,0,0.2-0.1c0-0.2-0.1-0.5-0.2-0.7C257.2,312.9,257.1,312.6,257,312.3z"/>
<path class="st1" d="M264.3,326.4c-1-1.9-2.2-3.7-3.5-5.3l0,0c0.5,2.1,1.1,4.1,1.9,6.1c0.4,1,0.9,1.9,1.5,2.8
c0.5,0.9,1.1,1.7,1.7,2.5l0,0c0,0.1,0.1,0.1,0.2,0.1s0.2-0.1,0.2-0.3l0,0c-0.2-1-0.5-1.9-0.9-2.8
C265.2,328.4,264.8,327.4,264.3,326.4z"/>
<path class="st1" d="M147.1,115.8c-2.7-3.5-5.5-7-8.2-10.5c-1.3-1.7-2.5-3.4-3.9-5s-2.6-3.2-4-4.8s-2.7-3-4.2-4.4s-2.9-2.8-4.3-4.2
h-0.1c-0.1,0-0.2,0.2-0.2,0.3c1.3,2.4,2.7,4.7,4.1,6.9s3,4.6,4.7,6.8s3.6,4.6,5.5,6.8l5.2,6.5c2.1,2.6,4.1,5.2,6.2,7.9
c0.2-1.4,0.5-2.8,0.9-4.2L147.1,115.8z"/>
<path class="st1" d="M113.4,76.5c1.2,1.3,2.4,2.6,3.7,3.8l0,0c-0.9-1.5-1.8-3-2.8-4.5s-2-2.9-3-4.4s-2.3-2.8-3.5-4.2
c-1.2-1.3-2.4-2.5-3.8-3.7l0,0c1.7,3.2,3.6,6.1,5.9,8.9C111,73.9,112.2,75.2,113.4,76.5z"/>
<path class="st1" d="M234,232.6l0.5,0.6c1.8,2.2,3.6,4.5,5.4,6.7c2.5,3.1,5,6.1,7.5,9.2c2.6,3.1,5,6.3,7.6,9.5
c1.3,1.7,2.6,3.4,3.9,5s2.9,3.5,4.5,5.1s3,3.2,4.5,4.7c0.8,0.8,1.6,1.6,2.4,2.3s1.5,1.4,2.3,2.1l0,0c-0.6-1.1-1.2-2.3-1.9-3.4
s-1.4-2.4-2.2-3.6c-1.5-2.4-3-4.7-4.7-7s-3.5-4.7-5.4-7s-3.4-4.4-5.2-6.6l-2.6-3.3c-1.7-2.2-3.4-4.5-5.1-6.7s-3.4-4.6-5.1-6.8
c-1.1-1.4-2.1-2.8-3.2-4.2C236.3,230.6,235.2,231.7,234,232.6z"/>
<path class="st1" d="M286.8,293.7c-2-2.5-4.3-4.7-6.9-6.4l0,0c0.5,1.4,1.2,2.7,1.9,4.1c0.8,1.4,1.6,2.7,2.6,4c1,1.2,2,2.3,3.2,3.3
c1.1,1,2.2,1.9,3.4,2.7l0,0l0.1,0.1l0,0c-0.6-1.3-1.2-2.6-1.8-3.9C288.5,296.2,287.7,294.9,286.8,293.7z"/>
<path class="st1" d="M293.5,196.8L293.5,196.8L293.5,196.8z"/>
<path class="st1" d="M261,187.3c-5.5-1.2-11.1-2.4-16.6-3.7c-1.4-0.3-2.8-0.6-4.2-0.9l-0.4-0.1v3.9c1.3,0.3,3.1,0,4.4,0.4
s3.2,0,4.6,0.1"/>
<path class="st1" d="M310.3,199.2c-0.8-0.2-1.6-0.3-2.4-0.4c-0.8-0.1-1.5-0.2-2.3-0.2c-0.4,0-0.9,0-1.3,0c-1.1,0-2.1,0.1-3.2,0.2
l0,0c1.3,0.8,2.6,1.4,3.9,2c1.4,0.7,2.9,1.2,4.5,1.5c0.8,0.2,1.6,0.3,2.4,0.4c0.8,0.1,1.5,0.1,2.3,0.2c1.4,0,2.8,0,4.2-0.1l0,0
c-1.2-0.7-2.4-1.3-3.6-1.9C313.3,200.1,311.8,199.6,310.3,199.2z"/>
<path class="st1" d="M123.3,156.3c-5.5-1.3-11-2.7-16.5-4l-8.1-2c-2.7-0.7-5.5-1.2-8.3-1.8c-2.4-0.4-4.8-0.8-7.2-1.1
s-4.7-0.5-7-0.6l0,0c5.1,2.1,10.3,3.8,15.6,5.2c1.4,0.4,2.7,0.7,4.1,1s2.7,0.6,4.1,0.9l8.2,1.8l16.6,3.6l4.6,1
c0.2-0.9,0.5-1.7,0.9-2.5L123.3,156.3z"/>
<path class="st1" d="M59.2,143c2.1,0.9,4.4,1.6,6.6,2c1.2,0.2,2.4,0.4,3.6,0.6s2.4,0.4,3.6,0.5l0,0c-1.1-0.4-2.3-0.7-3.4-1.1
s-2.3-0.7-3.5-1s-2.4-0.6-3.6-0.8C61.5,143.1,60.4,143,59.2,143L59.2,143C59.2,142.9,59.2,142.9,59.2,143L59.2,143L59.2,143
L59.2,143L59.2,143z"/>
<path class="st1" d="M52.3,140.9c-0.6-0.2-1.1-0.4-1.7-0.5c-1.1-0.3-2.2-0.6-3.4-0.8s-2.4-0.3-3.5-0.4l0,0c-0.1,0-0.1,0.1-0.1,0.2
c0,0.1,0.1,0.1,0.1,0.1c1.4,0.6,2.8,1.1,4.2,1.5c0.7,0.2,1.5,0.4,2.2,0.5s1.4,0.2,2.1,0.3c1.7,0.3,3.3,0.5,5,0.7l0,0
c-1.1-0.4-2.2-0.8-3.4-1.1C53.4,141.2,52.9,141.1,52.3,140.9z"/>
<path class="st1" d="M240.5,165.1L240.5,165.1L240.5,165.1l0.2-0.1L240.5,165.1L240.5,165.1c-0.3-0.1-0.5-0.1-0.8-0.1v0.4
C240,165.3,240.2,165.2,240.5,165.1z"/>
<path class="st1" d="M314.4,152.9h-0.2c-1.9-0.1-3.8-0.2-5.7-0.2c-0.8,0-1.6,0-2.4,0.1c-0.3,0-0.6,0.1-0.9,0.1l-1,0.1l-2.2,0.2
c-1.5,0.2-3,0.3-4.6,0.6c-2.8,0.4-5.5,1-8.2,1.5l-4.1,0.8c-1.4,0.3-2.8,0.5-4.2,0.7l-8.4,1.4c-2.8,0.5-5.5,0.9-8.3,1.5
s-5.5,1.1-8.2,1.8c-1.3,0.3-2.7,0.7-4,1s-2.7,0.7-4.1,1.1l-0.4,0.1c-0.3,0.1-0.2,0.5,0.1,0.4c0.6,0,1.2,0,1.8,0l2.2-0.1
c1.4-0.1,2.7-0.1,4.1-0.2c2.8-0.2,5.5-0.4,8.3-0.8c1.5-0.2,3-0.4,4.5-0.6l4.2-0.6l8.4-1.2l3.9-0.6c2.4-0.3,4.7-0.6,7.1-0.9
c2.6-0.3,5.3-0.6,7.9-1.1c1.2-0.2,2.4-0.5,3.6-0.8l1.8-0.4c0.6-0.1,1.2-0.3,1.8-0.4s1.2-0.4,1.8-0.6s1.2-0.4,1.7-0.6l3.5-1.3h0.2
c0.4-0.1,0.7-0.3,1-0.4s0.1-0.6-0.2-0.6S314.7,152.9,314.4,152.9z"/>
<path class="st1" d="M108.3,186.1h0.8c0.6,0,1.2,0,1.7,0c1.2,0,2.5-0.2,3.7-0.4s2.3-0.5,3.5-0.8c1.1-0.3,2.2-0.7,3.3-1l0,0h-1.6
c-1.7,0-3.5,0.1-5.2,0.3c-1.2,0.2-2.5,0.4-3.7,0.8c-0.6,0.1-1.1,0.3-1.7,0.5l-0.7,0.2c-0.2,0.1-0.4,0.1-0.6,0.2l-0.5,0.2l0,0h0.5
C108,186.1,108.1,186.1,108.3,186.1z"/>
<path class="st1" d="M45.2,197.3c2.8-0.1,5.6-0.2,8.4-0.5c1.6-0.2,3.1-0.4,4.7-0.6c1.4-0.2,2.8-0.5,4.1-0.7c2.7-0.5,5.5-1,8.2-1.5
c2.3-0.4,4.5-0.9,6.8-1.4s4.5-1.1,6.7-1.7s4.4-1.2,6.6-1.8s4.2-1.1,6.2-1.6l0,0c-2.6,0.2-5.2,0.4-7.8,0.5s-5.5,0.2-8.3,0.4
s-5.6,0.5-8.4,0.8s-5.8,0.8-8.8,1.1c-2.3,0.3-4.5,0.6-6.8,1s-4.6,0.9-6.8,1.4s-4.5,1.1-6.7,1.8c-1.1,0.3-2.1,0.7-3.2,1l-1.6,0.6
c-0.5,0.2-1,0.4-1.5,0.6c-0.1,0-0.1,0.1-0.1,0.2L37,197l0,0c0.6,0,1.2,0.1,1.8,0.1s1.4,0.1,2.2,0.1
C42.5,197.3,43.9,197.3,45.2,197.3z"/>
<path class="st1" d="M127.3,193.3c-2.7,0.9-5.4,1.8-8.1,2.7c-5.3,1.8-10.7,3.6-16,5.4c-2.7,0.9-5.4,1.8-8.1,2.7s-5.4,1.8-8.1,2.8
c-3.2,1.2-6.3,2.4-9.4,3.8c-1.4,0.6-2.9,1.3-4.3,2s-2.9,1.4-4.2,2.3l0,0v0.1c2.7-0.4,5.3-0.9,7.9-1.5c2.7-0.6,5.4-1.3,8.1-2.1
s5.4-1.8,8.1-2.7l8.1-2.8l8-2.8l7.9-2.8c2.7-0.9,5.4-1.9,8.1-2.8l3.5-1.2v-3.7L127.3,193.3z"/>
<path class="st1" d="M50.5,222.8c0.8-0.3,1.6-0.7,2.4-1s1.6-0.8,2.3-1.1s1.5-0.8,2.2-1.2l2.3-1.2l0,0c-0.8,0.1-1.6,0.3-2.5,0.5
l-2.5,0.4c-0.8,0.1-1.6,0.3-2.5,0.5s-1.7,0.4-2.5,0.6c-1.7,0.5-3.3,1.2-4.9,2c-1.5,0.8-2.9,1.6-4.3,2.5l0,0
c1.6-0.2,3.3-0.4,4.9-0.7C47.2,223.8,48.9,223.3,50.5,222.8z"/>
<path class="st1" d="M32.6,227.4L32.6,227.4c-2.9,0.3-5.8,0.8-8.6,1.7c-1.4,0.5-2.9,1.1-4.2,1.8c-1.3,0.6-2.5,1.3-3.8,2.1l0,0
c-0.2,0.1-0.1,0.5,0.1,0.4c1.4-0.1,2.8-0.4,4.2-0.6c1.5-0.3,2.9-0.7,4.3-1.1c1.4-0.5,2.8-1.1,4.2-1.8c1.3-0.6,2.5-1.4,3.7-2.1l0,0
C32.8,227.6,32.7,227.4,32.6,227.4z"/>
<path class="st1" d="M241.1,157.5c2.7-0.8,5.4-1.8,8.1-2.7l7.9-2.8c2.7-0.9,5.4-1.9,8.1-2.8c2.7-0.9,5.4-1.8,8.1-2.8s5.2-2,7.8-3
s5.2-2.1,7.7-3.4l1.1-0.6l0,0l0,0c-2.7,0.5-5.3,1.1-8,1.9l-1.9,0.6l-2,0.6c-1.4,0.4-2.7,0.8-4.1,1.2c-2.7,0.9-5.4,1.8-8.1,2.7
l-8.1,2.8c-2.6,0.9-5.3,1.8-8,2.7s-5.4,1.8-8,2.7c-1.4,0.5-2.7,1-4,1.6l-0.3,0.1c0.4,0.6,0.8,1.3,1.1,2
C239.3,158,240.2,157.8,241.1,157.5z"/>
<path class="st1" d="M303.3,134c-1.6,0.7-3.2,1.6-4.8,2.4l0,0c3.5-0.5,7-1.3,10.3-2.4c1.7-0.6,3.4-1.3,5-2s3-1.5,4.4-2.3l0,0h-0.1
c-3.3,0.5-6.6,1.2-9.8,2.3C306.5,132.6,304.9,133.3,303.3,134z"/>
<path class="st1" d="M318,129.7L318,129.7L318,129.7z"/>
<path class="st1" d="M334,124.3l-1.5,0.1c-0.2,0-0.5,0-0.7,0.1l-0.2,0.1c-0.2,0.1-0.3,0.1-0.5,0.1c-1.1,0.3-2.3,0.6-3.4,1
c-2.1,0.8-4.1,1.7-6.1,2.8l0,0c1.6-0.2,3.1-0.5,4.7-0.9s3.2-1,4.7-1.7l0.7-0.3c0.4-0.1,0.7-0.3,1.1-0.5
C333.3,124.8,333.6,124.5,334,124.3L334,124.3z"/>
<path class="st1" d="M219.6,149.2L219.6,149.2h2.3l1.4-0.9c0.6-0.4,1.2-0.8,1.8-1.2c2.3-1.6,4.6-3.2,6.8-4.9
c1.2-0.9,2.4-1.9,3.6-2.9c0.5-0.4,1-0.9,1.5-1.3l1.7-1.4c1.1-0.9,2.2-1.8,3.3-2.7l3.4-2.7l3.4-2.7c1.1-0.9,2.1-1.8,3.2-2.7
c2.2-1.8,4.5-3.6,6.7-5.4c4.3-3.6,8.3-7.6,12-11.7c0.4-0.4,0.8-0.8,1.1-1.2s0.6-0.8,0.9-1.2l0,0c-0.5,0.3-1.1,0.6-1.6,0.8
s-1.1,0.7-1.7,1c-1.2,0.7-2.3,1.4-3.5,2.2c-2.3,1.5-4.6,3.1-6.8,4.8c-1.2,0.9-2.5,1.9-3.7,2.8s-2.2,1.8-3.3,2.8l-3.3,2.8l-3.2,2.7
l-6.6,5.5c-1.1,0.9-2.2,1.8-3.3,2.7c-0.5,0.4-1,0.9-1.6,1.3s-1.1,0.9-1.7,1.4c-1.1,0.9-2.2,1.8-3.2,2.8s-2.1,1.9-3.1,2.9s-2,2-3,3
c-0.7,0.6-1.3,1.4-1.9,2.1v1.6L219.6,149.2z"/>
<path class="st1" d="M278.4,101.5L278.4,101.5c3.2-1.6,6.2-3.5,9-5.6c1.4-1.1,2.8-2.3,4-3.6c1.2-1.3,2.4-2.6,3.5-4
c0.3-0.3,0.5-0.7,0.8-1l0,0l-1,0.4l-1.2,0.6c-0.8,0.5-1.6,0.9-2.5,1.4c-1.7,1-3.3,2.2-4.8,3.4c-0.7,0.6-1.4,1.3-2.1,1.9
s-1.4,1.4-2,2.1C280.8,98.4,279.6,99.9,278.4,101.5z"/>
<path class="st1" d="M295,88.2L295,88.2L295,88.2z"/>
<path class="st1" d="M305.8,80c1.2-1.1,2.3-2.4,3.1-3.8l0,0h-0.1l0,0c-0.7,0.3-1.4,0.6-2,0.9c-0.8,0.4-1.5,0.9-2.2,1.4
c-0.6,0.5-1.2,1.1-1.7,1.8c-0.6,0.7-1.1,1.4-1.5,2.1l0,0C302.9,81.9,304.4,81,305.8,80z"/>
<path class="st1" d="M123.3,227.3c-2.2,1.8-4.3,3.5-6.5,5.3c-4.4,3.6-8.8,7.2-13.2,10.8l-6.7,5.6c-1.1,0.9-2.2,1.8-3.2,2.7
l-3.4,2.7L88,256c-0.9,0.7-1.8,1.3-2.7,1.9c-1.9,1.4-3.6,2.9-5.3,4.5c-1.6,1.5-3.2,3.1-4.7,4.8c-0.7,0.8-1.4,1.6-2.2,2.4L72,271
l-0.5,0.6c-0.1,0.1-0.2,0.3-0.4,0.4c-0.3,0.3,0,1,0.5,0.9c0.3-0.1,0.5-0.2,0.7-0.4l0.9-0.5l1.8-1.1c1.2-0.7,2.3-1.4,3.4-2.1
s2.3-1.5,3.5-2.3s2.5-1.8,3.7-2.8s2.1-1.7,3.1-2.7c0.5-0.5,0.9-0.9,1.4-1.4l1.6-1.5c2.1-1.9,4.3-3.7,6.4-5.5
c4.4-3.6,8.8-7.2,13.1-10.8c2.2-1.8,4.4-3.6,6.6-5.4l6.4-5.4c1.8-1.6,3.7-3.1,5.6-4.6c-0.5-1.2-0.8-2.4-0.9-3.7L123.3,227.3z"/>
<path class="st1" d="M66.1,276.8c-2.4,1-4.6,2.3-6.7,3.9c-1,0.8-1.9,1.7-2.8,2.7c-0.8,0.9-1.6,1.9-2.3,2.9
c-0.1,0.1,0.1,0.2,0.2,0.2l0,0c2.3-1,4.5-2.3,6.5-3.9c1-0.8,1.9-1.8,2.7-2.8C64.6,278.9,65.4,277.9,66.1,276.8L66.1,276.8z"/>
<path class="st1" d="M123.1,172.2c-2.8,0-5.6,0-8.4,0s-5.6-0.1-8.4-0.1h-4.6c-1.3,0-2.5,0-3.8,0.1c-2.8,0.1-5.7,0.3-8.6,0.6
c-1.4,0.1-2.8,0.3-4.2,0.4s-2.6,0.3-3.9,0.5l-2,0.4l0,0l1.9,0.4c0.6,0.1,1.3,0.2,1.9,0.3c1.3,0.2,2.7,0.3,4.1,0.5s2.8,0.3,4.2,0.4
s2.9,0.2,4.3,0.3s2.8,0.1,4.2,0.1s2.8,0,4.2,0c2.8,0,5.6,0,8.4-0.1l8.4-0.1c2.6,0,5.3,0,7.9-0.1v-3.6
C126.9,172.2,125,172.2,123.1,172.2z"/>
<path class="st1" d="M46,173.8c0,0-0.1,0-0.1,0.1v0.1c0,0,0,0,0,0.1s0,0,0,0.1c0,0,0,0,0,0.1l0.1,0.1c2.1,0.4,4.3,0.7,6.4,0.8
c2.3,0.2,4.6,0.3,6.9,0.2c2.2-0.1,4.5-0.3,6.7-0.5s4.4-0.5,6.6-0.8l0,0c-2.2-0.3-4.3-0.5-6.5-0.7s-4.5-0.4-6.7-0.5
c-0.6,0-1.1,0-1.7,0c-1.7,0-3.4,0.1-5.2,0.2C50.4,173.1,48.2,173.4,46,173.8z"/>
<path class="st1" d="M242.4,175.8c2.3-0.1,4.5-0.2,6.8-0.6c1.1-0.1,2.1-0.3,3.2-0.5s2.1-0.4,3.1-0.6l0,0c-1-0.2-2-0.4-3-0.6
s-2.1-0.4-3.2-0.5c-2.3-0.3-4.6-0.6-6.9-0.6H242c-0.7,0-1.5,0.1-2.2,0.1v3.3C240.6,175.7,241.5,175.8,242.4,175.8z"/>
<path class="st1" d="M328.1,173.1l-1.7-0.4c-0.4-0.1-0.8-0.2-1.2-0.2c-0.2,0-0.3,0-0.5,0h-0.2c-4.8-0.7-9.7-1-14.5-1h-2
c-2.8,0-5.7,0-8.5,0.1s-5.7,0.1-8.5,0.1c-2,0-4,0-6,0.1s-4,0.3-6,0.5c-4,0.4-8,1-12,1.8l0,0c5.5,1.1,11.1,1.8,16.6,2.2
c1.4,0.1,2.8,0.1,4.2,0.2s2.8,0,4.2,0c2.9,0,5.7,0,8.5,0.1l6.1,0.1c2,0,4.1,0.1,6.1,0c3.9-0.1,7.8-0.4,11.7-0.9h0.2
c0.1,0,0.3,0,0.4,0c0.4,0,0.8-0.1,1.1-0.2l1.9-0.5l1.6-0.4c0.6-0.1,1.1-0.3,1.7-0.4l0,0c-0.5-0.1-1-0.3-1.6-0.4
S328.7,173.3,328.1,173.1z"/>
<path class="st1" d="M292.3,222.1c-1.4-1-2.8-1.9-4.3-2.6c-1.5-0.7-3.1-1.3-4.7-1.7s-3.2-0.7-4.9-0.9l0,0c2.3,2.2,4.9,4.1,7.7,5.5
c0.8,0.4,1.6,0.7,2.4,1s1.6,0.5,2.4,0.8s1.4,0.4,2.2,0.5s1.5,0.2,2.3,0.3l0.5,0.1l0,0c-0.5-0.5-1-1-1.6-1.5
S292.9,222.6,292.3,222.1z"/>
<path class="st1" d="M312.9,231.8c-1.3-0.9-2.6-1.7-4-2.4c-1.5-0.7-3-1.2-4.5-1.6c-1.4-0.4-2.9-0.8-4.3-1.1H300
c-0.1,0-0.1,0-0.2,0.1s-0.1,0.3,0,0.4l0,0c1.2,0.9,2.4,1.8,3.6,2.6c1.3,0.9,2.6,1.7,4,2.4c1.5,0.7,3,1.3,4.6,1.7
c1.4,0.4,2.9,0.6,4.4,0.8l0,0c-0.5-0.5-1-1-1.6-1.5S313.5,232.2,312.9,231.8z"/>
<path class="st1" d="M75.9,123.7c1.2,0.7,2.5,1.3,3.8,1.9s2.5,1.2,3.8,1.8l7.6,3.5l7.6,3.5c2.6,1.2,5.1,2.4,7.7,3.6s5.3,2.5,8,3.6
s5.2,2.1,7.8,3c3.4,1.3,6.9,2.4,10.3,3.6l0,0c-4.7-3-9.4-5.8-14.2-8.5c-2.5-1.4-5-2.6-7.5-3.9s-5.2-2.5-7.7-3.7
c-5-2.4-10.1-4.8-15.1-7.3c-2.5-1.2-5-2.5-7.6-3.6s-5.4-2.3-8.1-3.2c-3.3-1.2-6.7-2.2-10.1-3l0,0c2.1,1.6,4.2,3.1,6.5,4.5
C71,121,73.4,122.4,75.9,123.7z"/>
<path class="st1" d="M42.6,106.8c0.6,0.4,1.2,0.7,1.9,1.1s1.4,0.7,2.2,1.1c1.4,0.6,2.8,1,4.3,1.5s2.8,0.9,4.2,1.4l0,0
c-1.2-0.8-2.4-1.6-3.6-2.3s-2.6-1.6-3.9-2.3c-0.6-0.4-1.3-0.7-2-0.9c-0.7-0.3-1.4-0.6-2.2-0.8c-1.3-0.5-2.6-0.8-4-1.1l0,0
c-0.1,0-0.2,0.1-0.1,0.2C40.4,105.2,41.5,106,42.6,106.8z"/>
<path class="st1" d="M170.6,83.9L170.6,83.9c0,0.1,0,0.1,0,0.2V83.9z"/>
<path class="st1" d="M153.6,14.6c0.2,1.4,0.4,2.8,0.6,4.1c0.5,2.8,1,5.6,1.6,8.3c1.3,5.5,2.5,11.1,3.7,16.6l1.9,8.3
c0.6,2.8,1.3,5.6,1.9,8.4s1.2,5.5,1.8,8.2s1.3,5.5,2,8.2c0.6,2.2,1.2,4.4,1.9,6.7s1.4,4.3,2.2,6.4l0,0c-0.1-2-0.4-4-0.6-5.9
c-0.7-5.6-1.8-11.1-3.1-16.5c-0.7-2.7-1.3-5.4-1.9-8.2s-1.3-5.6-1.9-8.4c-1.2-5.5-2.5-11.1-3.8-16.6c-0.6-2.8-1.2-5.5-1.9-8.3
s-1.3-5.5-2.1-8.2c-0.4-1.2-0.7-2.4-1.1-3.6c-0.2-0.6-0.4-1.2-0.6-1.7s-0.4-1.2-0.6-1.8c0-0.1-0.2-0.2-0.3-0.2h-0.1
c-0.2,0-0.3,0.2-0.2,0.4c0.1,0.6,0.1,1.2,0.2,1.8L153.6,14.6z"/>
<path class="st1" d="M204.9,240.2c0.2,0.5,0.4,0.9,0.6,1.4l0,0c-0.1-1.9-0.3-3.8-0.5-5.7h-1.6C203.8,237.3,204.3,238.7,204.9,240.2
z"/>
<path class="st1" d="M222.4,311.2c-0.2-1.4-0.5-2.7-0.8-4c-0.6-2.7-1.2-5.5-1.9-8.2s-1.2-5.5-1.9-8.3c-1.2-5.5-2.4-11-3.6-16.5
c-1.2-5.5-2.7-11-4.5-16.3c-0.5-1.5-1.1-3-1.7-4.5l0,0c0.2,2.7,0.5,5.4,0.8,8.1s0.9,5.6,1.4,8.4s1.2,5.6,1.9,8.4s1.3,5.5,1.9,8.2
s1.2,5.5,1.9,8.2s1.2,5.5,1.8,8.3s1.2,5.4,1.9,8.1s1.6,5.2,2.5,7.8c0.5,1.5,1,2.9,1.6,4.4h0.1c-0.2-2.6-0.5-5.3-0.8-7.9
C222.8,314,222.6,312.6,222.4,311.2z"/>
<path class="st1" d="M226.3,331.9c-0.2-0.7-0.4-1.5-0.6-2.2c-0.2-0.6-0.5-1.3-0.8-1.9l0,0c0,1.4,0.1,2.9,0.4,4.2
c0.3,1.3,0.8,2.5,1.4,3.7l0,0c0-0.6,0-1.1-0.1-1.7C226.5,333.3,226.4,332.6,226.3,331.9z"/>
</g>
<g id="Icons">
<path class="st2" d="M239.6,213.2v6.5c0,8.3-6.8,15.1-15.1,15.1l0,0h-80.7c-8.3,0-15.1-6.8-15.1-15.1v-56.4
c0-8.3,6.8-15.1,15.1-15.1h80.7c8.3,0,15.1,6.8,15.1,15.1l0,0v23.5"/>
<line class="st3" x1="140.6" y1="205" x2="140.6" y2="179.6"/>
<path class="st3" d="M140.6,168c0-5.2,4.2-9.4,9.4-9.4"/>
<path class="st2" d="M209.9,148.2v-21.3c0-14.2-11.5-25.8-25.8-25.8s-25.8,11.5-25.8,25.8l0,0v21.3 M147.4,148.2v-21.3
c0-20.3,16.5-36.8,36.8-36.8s36.8,16.5,36.8,36.8l0,0v21.3"/>
</g>
<path class="st2" d="M188.3,187H291c0.6,0,1,0.4,1,1v24.3c0,0.6-0.4,1-1,1H188.3c-0.6,0-1-0.4-1-1V188
C187.3,187.4,187.7,187,188.3,187z"/>
<path class="st1" d="M211.2,203.5l-0.1-0.5c-0.1-1.3,0.4-2.6,1.3-3.6c0.8-0.7,1.3-1.7,1.4-2.8c0-1-0.7-1.7-1.9-1.8
c-0.7,0-1.5,0.2-2.1,0.6l-0.5-1.3c0.9-0.6,1.9-0.8,2.9-0.8c2.4,0,3.4,1.5,3.4,3c0,1.4-0.8,2.4-1.8,3.6c-0.8,0.8-1.2,1.9-1.2,3v0.5
L211.2,203.5z M210.8,206.4c0-0.7,0.5-1.3,1.1-1.3h0.1c0.7,0,1.3,0.5,1.3,1.2s-0.5,1.3-1.2,1.3S210.8,207.1,210.8,206.4L210.8,206.4
z"/>
<path class="st1" d="M222,203.5V203c-0.1-1.3,0.4-2.6,1.3-3.6c0.8-0.7,1.3-1.7,1.4-2.8c0-1-0.7-1.7-2-1.8c-0.7,0-1.5,0.2-2.1,0.6
l-0.5-1.3c0.9-0.6,1.9-0.8,2.9-0.8c2.4,0,3.4,1.5,3.4,3c0,1.4-0.8,2.4-1.8,3.6c-0.8,0.8-1.2,1.9-1.2,3v0.5L222,203.5z M221.5,206.4
c0-0.7,0.5-1.3,1.1-1.3h0.1c0.7,0,1.3,0.5,1.3,1.2s-0.5,1.3-1.2,1.3S221.6,207.1,221.5,206.4L221.5,206.4z"/>
<path class="st1" d="M232.9,203.5V203c-0.1-1.3,0.4-2.6,1.3-3.6c0.8-0.7,1.3-1.7,1.4-2.8c0-1-0.6-1.7-2-1.8c-0.7,0-1.5,0.2-2.1,0.6
l-0.5-1.3c0.9-0.6,1.9-0.8,2.9-0.8c2.4,0,3.4,1.5,3.4,3c0,1.4-0.8,2.4-1.8,3.6c-0.8,0.8-1.2,1.9-1.2,3v0.5L232.9,203.5z
M232.4,206.4c0-0.7,0.5-1.3,1.1-1.3h0.1c0.7,0,1.3,0.5,1.3,1.2s-0.5,1.3-1.2,1.3C233,207.7,232.4,207.1,232.4,206.4L232.4,206.4z"
/>
<path class="st1" d="M243.7,203.5V203c-0.1-1.3,0.4-2.6,1.3-3.6c0.8-0.7,1.3-1.7,1.4-2.8c0-1-0.7-1.7-2-1.8c-0.7,0-1.5,0.2-2.1,0.6
l-0.5-1.3c0.9-0.6,1.9-0.8,2.9-0.8c2.4,0,3.4,1.5,3.4,3c0,1.4-0.8,2.4-1.8,3.6c-0.8,0.8-1.2,1.9-1.2,3v0.5L243.7,203.5z
M243.2,206.4c0-0.7,0.5-1.3,1.1-1.3h0.1c0.7,0,1.3,0.5,1.3,1.2s-0.5,1.3-1.2,1.3C243.9,207.7,243.3,207.1,243.2,206.4L243.2,206.4z
"/>
<path class="st1" d="M254.5,203.5V203c-0.1-1.3,0.4-2.6,1.3-3.6c0.8-0.7,1.3-1.7,1.4-2.8c0-1-0.6-1.7-2-1.8c-0.7,0-1.5,0.2-2.1,0.6
l-0.5-1.3c0.9-0.6,1.9-0.8,2.9-0.8c2.4,0,3.4,1.5,3.4,3c0,1.4-0.8,2.4-1.8,3.6c-0.8,0.8-1.2,1.9-1.2,3v0.5L254.5,203.5z M254,206.4
c0-0.7,0.5-1.3,1.1-1.3h0.1c0.7,0,1.3,0.5,1.3,1.2s-0.5,1.3-1.2,1.3C254.7,207.7,254.1,207.1,254,206.4L254,206.4z"/>
<path class="st1" d="M265.3,203.5V203c-0.1-1.3,0.4-2.6,1.3-3.6c0.8-0.7,1.3-1.7,1.4-2.8c0-1-0.6-1.7-2-1.8c-0.7,0-1.5,0.2-2.1,0.6
l-0.5-1.3c0.9-0.6,1.9-0.8,2.9-0.8c2.4,0,3.4,1.5,3.4,3c0,1.4-0.8,2.4-1.8,3.6c-0.8,0.8-1.2,1.9-1.2,3v0.5L265.3,203.5z
M264.9,206.4c0-0.7,0.5-1.3,1.1-1.3h0.1c0.7,0,1.3,0.5,1.3,1.2s-0.5,1.3-1.2,1.3C265.5,207.7,264.9,207.1,264.9,206.4L264.9,206.4z
"/>
<path class="st1" d="M276.2,203.5V203c-0.1-1.3,0.4-2.6,1.3-3.6c0.8-0.7,1.3-1.7,1.4-2.8c0-1-0.6-1.7-2-1.8c-0.7,0-1.5,0.2-2.1,0.6
l-0.5-1.3c0.9-0.6,1.9-0.8,2.9-0.8c2.4,0,3.4,1.5,3.4,3c0,1.4-0.8,2.4-1.8,3.6c-0.8,0.8-1.2,1.9-1.2,3v0.5L276.2,203.5z
M275.8,206.4c0-0.7,0.5-1.3,1.1-1.3h0.1c0.7,0,1.3,0.5,1.3,1.2s-0.5,1.3-1.2,1.3C276.4,207.7,275.8,207.1,275.8,206.4L275.8,206.4z
"/>
<path class="st1" d="M199.8,203.5V203c-0.1-1.3,0.4-2.6,1.3-3.6c0.8-0.7,1.3-1.7,1.4-2.8c0-1-0.7-1.7-2-1.8c-0.7,0-1.5,0.2-2.1,0.6
l-0.5-1.3c0.9-0.6,1.9-0.8,2.9-0.8c2.4,0,3.4,1.5,3.4,3c0,1.4-0.8,2.4-1.8,3.6c-0.8,0.8-1.2,1.9-1.2,3v0.5L199.8,203.5z
M199.3,206.4c-0.1-0.7,0.4-1.3,1.1-1.3c0.7-0.1,1.3,0.4,1.3,1.1c0,0.1,0,0.1,0,0.2c0.1,0.7-0.4,1.3-1.1,1.3
c-0.7,0.1-1.3-0.4-1.3-1.1C199.3,206.5,199.3,206.5,199.3,206.4z"/>
</svg>

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 109 KiB

View File

@@ -2,8 +2,8 @@ define([
'sources/gettext', 'alertify', 'jquery',
], function(gettext, alertify, $) {
alertify.defaults.transition = 'zoom';
alertify.defaults.theme.ok = 'btn btn-primary';
alertify.defaults.theme.cancel = 'btn btn-danger';
alertify.defaults.theme.ok = 'btn btn-primary fa fa-lg fa-check pg-alertify-button';
alertify.defaults.theme.cancel = 'btn btn-secondary fa fa-lg fa-times pg-alertify-button';
alertify.defaults.theme.input = 'form-control';
alertify.defaults.closable = false;
alertify.pgIframeDialog || alertify.dialog('pgIframeDialog', function() {
@@ -196,15 +196,22 @@ define([
this.pgResizeTimeout = null;
if (w <= 480) {
/** Calculations based on https://getbootstrap.com/docs/4.1/layout/grid/#grid-options **/
if (w < 576) {
w = 'xs';
} else if (w < 600) {
}
if (w >= 576) {
w = 'sm';
} else if (w < 768) {
}
if (w >= 768) {
w = 'md';
} else {
}
if (w >= 992) {
w = 'lg';
}
if (w >=1200) {
w = 'xl';
}
$el.attr('el', w);
}.bind(self),
@@ -376,49 +383,50 @@ define([
_.extend(alertify, {
success: function(message, timeout, callback) {
var alertMessage = '\
<div class="media text-success text-14">\
<div class="media-body media-middle">\
<div class="alert-icon success-icon">\
<i class="fa fa-check" aria-hidden="true"></i>\
</div>\
<div class="alert-text">' + message + '</div>\
</div>\
</div>';
var alertMessage =
`<div class="d-flex px-3 py-2">
<div class="pr-2">
<i class="fa fa-check text-success" aria-hidden="true"></i>
</div>
<div class="text-body">${message}</div>
</div>`;
return alertify.orig_success(alertMessage, timeout, callback);
},
error: function(message, timeout, callback) {
var alertMessage = '\
<div class="media text-danger text-14">\
<div class="media-body media-middle">\
<div class="alert-icon error-icon">\
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>\
</div>\
<div class="alert-text">' + message + '</div>\
</div>\
</div>';
var alertMessage =
`<div class="d-flex px-3 py-2">
<div class="pr-2">
<i class="fa fa-exclamation-triangle text-danger" aria-hidden="true"></i>
</div>
<div class="text-body">${message}</div>
</div>`;
return alertify.orig_error(alertMessage, timeout, callback);
},
info: function(message, timeout) {
var alertMessage = '\
<div class="media alert-info font-blue text-14">\
<div class="media-body media-middle">\
<div class="alert-icon info-icon">\
<i class="fa fa-info" aria-hidden="true"></i>\
</div>\
<div class="alert-text">' + message + '</div>\
</div>\
</div>';
var alertMessage =
`<div class="d-flex px-3 py-2">
<div class="mr-3">
<i class="fa fa-info text-primary" aria-hidden="true"></i>
</div>
<div class="text-body">${message}</div>
</div>`;
var alert = alertify.notify(alertMessage, timeout);
return alert;
},
});
// Confirm dialogue: Set title attribute
alertify.confirm().set({onshow:function() {
alertify.confirm().set({
onshow:function() {
$(this.elements.commands.close).attr('title', gettext('Close'));
$(this.elements.commands.maximize).attr('title', gettext('Maximize'));
}});
},
reverseButtons: true,
});
alertify.prompt().set({
reverseButtons: true,
});
return alertify;
});

View File

@@ -22,12 +22,13 @@ define([
// HTML markup global class names. More can be added by individual controls
// using _.extend. Look at RadioControl as an example.
_.extend(Backform, {
controlLabelClassName: 'control-label pg-el-sm-3 pg-el-xs-12',
controlsClassName: 'pgadmin-controls pg-el-sm-9 pg-el-xs-12',
groupClassName: 'pgadmin-control-group form-group pg-el-xs-12',
setGroupClassName: 'set-group pg-el-xs-12',
tabClassName: 'backform-tab pg-el-xs-12',
setGroupContentClassName: 'fieldset-content pg-el-xs-12',
controlLabelClassName: 'control-label pg-el-sm-3 pg-el-12',
controlsClassName: 'pgadmin-controls pg-el-sm-9 pg-el-12',
controlContainerClassName: 'pgadmin-controls pg-el-sm-9 pg-el-12',
groupClassName: 'pgadmin-control-group form-group row pg-el-12',
setGroupClassName: 'set-group pg-el-12',
tabClassName: 'backform-tab pg-el-12',
setGroupContentClassName: 'fieldset-content pg-el-12',
hiddenClassName: 'd-none',
});
@@ -402,7 +403,7 @@ define([
'[type="radio"]'
).append(
$('<div></div>').addClass(
'pgadmin-control-error-message pg-el-xs-offset-4 pg-el-xs-8 pg-el-xs-8 help-block'
'pgadmin-control-error-message pg-el-offset-4 pg-el-8 pg-el-8 help-block'
).text(error));
});
},
@@ -481,7 +482,7 @@ define([
tagName: 'div',
legend: true,
className: function() {
return 'pg-el-sm-12 pg-el-md-12 pg-el-lg-12 pg-el-xs-12';
return 'pg-el-sm-12 pg-el-md-12 pg-el-lg-12 pg-el-12';
},
tabPanelClassName: function() {
return Backform.tabClassName;
@@ -513,7 +514,7 @@ define([
'<%=label%></a></li>',
].join(' ')),
'panel': _.template(
'<div role="tabpanel" tabindex="-1" class="tab-pane <%=label%> pg-el-sm-12 pg-el-md-12 pg-el-lg-12 pg-el-xs-12 fade" id="<%=cId%>" aria-labelledby="<%=hId%>"></div>'
'<div role="tabpanel" tabindex="-1" class="tab-pane <%=label%> pg-el-sm-12 pg-el-md-12 pg-el-lg-12 pg-el-12 fade" id="<%=cId%>" aria-labelledby="<%=hId%>"></div>'
),
},
render: function() {
@@ -539,7 +540,7 @@ define([
var tabHead = $('<ul class="nav nav-tabs" role="tablist"></ul>')
.appendTo(this.$el);
var tabContent = $('<div class="tab-content pg-el-sm-12 pg-el-md-12 pg-el-lg-12 pg-el-xs-12"></div>')
var tabContent = $('<div class="tab-content pg-el-sm-12 pg-el-md-12 pg-el-lg-12 pg-el-12"></div>')
.appendTo(this.$el);
_.each(this.schema, function(o) {
@@ -628,7 +629,7 @@ define([
Backform.Fieldset = Backform.Dialog.extend({
className: function() {
return 'set-group pg-el-xs-12';
return 'set-group pg-el-12';
},
tabPanelClassName: function() {
return Backform.tabClassName;
@@ -640,7 +641,7 @@ define([
'header': _.template([
'<fieldset class="<%=fieldsetClass%>" <%=disabled ? "disabled" : ""%>>',
' <% if (legend != false) { %>',
' <legend class="<%=legendClass%>" <%=collapse ? "data-toggle=\'collapse\'" : ""%> data-target="#<%=cId%>"><%=collapse ? "<span class=\'caret\'></span>" : "" %><%=label%></legend>',
' <div><legend class="<%=legendClass%>" <%=collapse ? "data-toggle=\'collapse\'" : ""%> data-target="#<%=cId%>"><%=collapse ? "<span class=\'caret\'></span>" : "" %><%=label%></legend></div>',
' <% } %>',
'</fieldset>',
].join('\n')),
@@ -991,10 +992,10 @@ define([
gridHeader = _.template([
'<div class="subnode-header">',
' <label class="control-label pg-el-sm-10"><%-label%></label>',
' <button class="btn btn-sm-sq btn-default add fa fa-plus" <%=canAdd ? "" : "disabled=\'disabled\'"%> title="' + _('Add new row') + '"><%-add_label%></button>',
' <button class="btn btn-sm-sq btn-secondary add fa fa-plus" <%=canAdd ? "" : "disabled=\'disabled\'"%> title="' + _('Add new row') + '"><%-add_label%></button>',
'</div>',
].join('\n')),
gridBody = $('<div class="pgadmin-control-group backgrid form-group pg-el-xs-12 object subnode"></div>').append(
gridBody = $('<div class="pgadmin-control-group backgrid form-group pg-el-12 object subnode "></div>').append(
gridHeader(data)
);
@@ -1073,7 +1074,7 @@ define([
self.grid = new Backgrid.Grid({
columns: gridSchema.columns,
collection: collection,
className: 'backgrid table-bordered',
className: 'backgrid table presentation table-bordered table-noouter-border table-hover',
});
// Render subNode grid
@@ -1169,7 +1170,7 @@ define([
self.$el.addClass('subnode-error').append(
$('<div></div>').addClass(
'pgadmin-control-error-message pg-el-xs-offset-4 pg-el-xs-8 help-block'
'pgadmin-control-error-message pg-el-offset-4 pg-el-8 help-block'
).text(error)
);
});
@@ -1235,7 +1236,7 @@ define([
if (self.field.get('showError')) {
self.$el.addClass('subnode-error').append(
$('<div></div>').addClass('pgadmin-control-error-message pg-el-xs-offset-4 pg-el-xs-8 help-block').text(error)
$('<div></div>').addClass('pgadmin-control-error-message pg-el-offset-4 pg-el-8 help-block').text(error)
);
}
},
@@ -1259,10 +1260,10 @@ define([
var self = this,
gridHeader = ['<div class=\'subnode-header\'>',
' <label class=\'control-label pg-el-sm-10\'>' + data.label + '</label>',
' <button class=\'btn btn-sm-sq btn-default add fa fa-plus\' title=\'' + _('Add new row') + '\'></button>',
' <button class=\'btn btn-sm-sq btn-secondary add fa fa-plus\' title=\'' + _('Add new row') + '\'></button>',
'</div>',
].join('\n'),
gridBody = $('<div class=\'pgadmin-control-group backgrid form-group pg-el-xs-12 object subnode\'></div>').append(gridHeader);
gridBody = $('<div class=\'pgadmin-control-group backgrid form-group pg-el-12 object subnode\'></div>').append(gridHeader);
var subnode = data.subnode.schema ? data.subnode : data.subnode.prototype,
gridSchema = Backform.generateGridColumnsFromModel(
@@ -1353,7 +1354,7 @@ define([
columns: gridSchema.columns,
collection: collection,
row: this.row,
className: 'backgrid table-bordered',
className: 'backgrid table presentation table-bordered table-noouter-border table-hover',
});
// Render subNode grid
@@ -1968,6 +1969,7 @@ define([
);
this.dialog = opts.dialog;
this.tabIndex = opts.tabIndex;
this.contentClass = opts.field.get('contentClass')?opts.field.get('contentClass'):'';
// Listen to the dependent fields in the model for any change
var deps = this.field.get('deps');
@@ -2014,7 +2016,6 @@ define([
},
fieldsetClass: 'inline-fieldset',
legendClass: '',
contentClass: '',
collapse: false,
});
@@ -2046,7 +2047,7 @@ define([
'header': _.template([
'<fieldset class="<%=fieldsetClass%>" <%=disabled ? "disabled" : ""%>>',
' <% if (legend != false) { %>',
' <legend class="<%=legendClass%>" <%=collapse ? "data-toggle=\'collapse\'" : ""%> data-target="#<%=cId%>"><%=collapse ? "<span class=\'caret\'></span>" : "" %></legend>',
' <div><legend class="<%=legendClass%>" <%=collapse ? "data-toggle=\'collapse\'" : ""%> data-target="#<%=cId%>"><%=collapse ? "<span class=\'caret\'></span>" : "" %></legend></div>',
' <% } %>',
'</fieldset>',
].join('\n')),
@@ -2251,7 +2252,7 @@ define([
noteClass: 'backform_control_notes',
},
template: _.template([
'<div class="<%=noteClass%> pg-el-xs-12 <%=extraClasses.join(\' \')%>">',
'<div class="<%=noteClass%> pg-el-12 <%=extraClasses.join(\' \')%>">',
'<label class="control-label"><%=label%>:</label>',
'<span><%=text%></span></div>',
].join('\n')),
@@ -2725,7 +2726,7 @@ define([
},
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<div class="<%=Backform.controlsClassName%>">',
'<div class="<%=Backform.controlsClassName%> d-flex flex-row">',
'</div>',
].join('\n')),
@@ -2771,7 +2772,7 @@ define([
_.extend({}, {
id: fld['name'],
name: fld['name'],
control: fld['type'],
control: fld['type'] == 'checkbox' ? 'checkboxWithBox' : fld['type'],
label: fld['label'],
})
),
@@ -2790,13 +2791,13 @@ define([
cntr.$el.find('label.control-label').remove();
}
if (fld['name'] == 'alt_option') {
$container.append($('<div class="pg-el-sm-3 pg-el-xs-12"></div>').append(cntr.$el));
if (fld['name'] == 'alt') {
$container.append($('<div class="pg-el-sm-3 pg-el-12"></div>').append(cntr.$el));
} else {
$container.append($('<div class="pg-el-sm-2 pg-el-xs-12"></div>').append(cntr.$el));
$container.append($('<div class="pg-el-sm-2 pg-el-12"></div>').append(cntr.$el));
}
} else {
$container.append($('<div class="pg-el-sm-5 pg-el-xs-12"></div>').append(cntr.$el));
$container.append($('<div class="pg-el-sm-5 pg-el-12"></div>').append(cntr.$el));
}
// We will keep track of all the controls rendered at the
@@ -2814,5 +2815,26 @@ define([
},
});
Backform.CheckboxWithBoxControl = Backform.CheckboxControl.extend({
events: _.extend({}, Backform.CheckboxControl.prototype.events, {
'click button': 'onButtonClick',
}),
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=controlLabel%></label>',
'<div class="<%=Backform.controlContainerClassName%>">',
' <button class="btn btn-secondary btn-checkbox">',
' <input type="<%=type%>" class="<%=extraClasses.join(\' \')%>" id="<%=id%>" name="<%=name%>" <%=value ? "checked=\'checked\'" : ""%> <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> />',
' <%=label%>',
' </button>',
'</div>',
].join('\n')),
onButtonClick: function(e) {
if (e.target.nodeName !== 'BUTTON')
return;
var $el = this.$el.find('input[type=checkbox]');
$el.prop('checked', !$el.prop('checked'));
},
});
return Backform;
});

View File

@@ -1,6 +1,6 @@
define([
'sources/gettext', 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify',
'moment', 'bignumber', 'bootstrap.datetimepicker', 'bootstrap.switch',
'moment', 'bignumber', 'bootstrap.datetimepicker', 'bootstrap.switch', 'backgrid.filter',
], function(
gettext, _, $, Backbone, Backform, Backgrid, Alertify, moment, BigNumber
) {
@@ -236,7 +236,7 @@ define([
var $dialog = this.$dialog = $(this.modalTemplate({
title: '',
})),
tr = $('<tr>'),
tr = $('<tr class="nohover editor-row">'),
td = $('<td>', {
class: 'editable sortable renderable',
style: 'height: auto',
@@ -790,8 +790,7 @@ define([
},
render: function() {
this.$el.empty();
//this.$el.html("<i class='fa fa-plus-circle'></i>");
this.$el.html('<label><a><span style=\'font-weight:normal;\'>Array Values</a></span></label> <button class=\'btn-sm btn-default add\'>Add</button>');
this.$el.html('<label><a><span style=\'font-weight:normal;\'>Array Values</a></span></label> <button class=\'btn-sm btn-secondary add\'>Add</button>');
this.delegateEvents();
return this;
},
@@ -1611,6 +1610,32 @@ define([
remove: Backgrid.Extension.DependentCell.prototype.remove,
});
/* Custom search box was added to give user defined text box for search
* instead of backgrid rendered textbox
*/
Backgrid.Extension.ClientSideFilter = Backgrid.Extension.ClientSideFilter.extend({
$customSearchBox: null,
searchBox: function() {
if(this.$customSearchBox) {
return this.$customSearchBox;
} else {
return this.$el.find('input[type=search]');
}
},
setCustomSearchBox: function($el) {
this.$customSearchBox = $el;
this.$customSearchBox.attr('type','search');
this.$customSearchBox.on('keydown', this.search.bind(this));
},
unsetCustomSearchBox: function() {
this.$customSearchBox.off('keydown', this.search.bind(this));
this.$customSearchBox = null;
},
});
Backgrid.BooleanCellFormatter = _.extend(Backgrid.CellFormatter.prototype, {
fromRaw: function (rawValue) {
if (_.isUndefined(rawValue) || _.isNull(rawValue)) {

View File

@@ -39,11 +39,15 @@
button_type = editable ? 'btn-danger' : 'btn-primary';
if (editable) {
$('<button class=\'btn btn-primary fa fa-lg fa-save long_text_editor pg-alertify-button\'>Save</button>')
$('<button class=\'btn btn-primary long_text_editor\' data-label="Save">'+
'<span class="fa fa-save pg-alertify-button"></span>&nbsp;Save'+
'</button>')
.appendTo($buttons);
}
$('<button class=\'btn ' + button_type + ' fa fa-lg fa-times long_text_editor pg-alertify-button\'>' + label + '</button>')
$('<button class=\'btn ' + button_type + ' long_text_editor pg-alertify-button\' data-label="'+label+'">' +
'<span class="fa fa-save pg-alertify-button"></span>&nbsp;'+ label +
'</button>')
.appendTo($buttons);
return $buttons;
}

View File

@@ -56,7 +56,7 @@ let FilterDialog = {
buttons: [{
text: '',
key: 112,
className: 'btn btn-default pull-left fa fa-lg fa-question',
className: 'btn btn-secondary pull-left fa fa-question pg-alertify-icon-button',
attrs: {
name: 'dialog_help',
type: 'button',
@@ -65,15 +65,15 @@ let FilterDialog = {
'filename': 'editgrid.html',
}),
},
}, {
text: gettext('OK'),
className: 'btn btn-primary pg-alertify-button',
'data-btn-name': 'ok',
}, {
text: gettext('Cancel'),
key: 27,
className: 'btn btn-danger pg-alertify-button',
className: 'btn btn-secondary fa fa-times pg-alertify-button',
'data-btn-name': 'cancel',
}, {
text: gettext('OK'),
className: 'btn btn-primary fa fa-check pg-alertify-button',
'data-btn-name': 'ok',
}],
// Set options for dialog
options: {
@@ -109,11 +109,11 @@ let FilterDialog = {
let self = this;
$container.html('');
// Disable Ok button
this.__internal.buttons[1].element.disabled = true;
this.__internal.buttons[2].element.disabled = true;
// Status bar
this.statusBar = $('<div class=\'pg-prop-status-bar pg-el-xs-12 d-none\'>' +
' <div class=\'media error-in-footer bg-danger-lighter border-danger-light text-danger text-14\'>' +
' <div class=\'media error-in-footer bg-danger-light border-danger text-danger text-14\'>' +
' <div class=\'media-body media-middle\'>' +
' <div class=\'alert-icon error-icon\'>' +
' <i class=\'fa fa-exclamation-triangle\' aria-hidden=\'true\'></i>' +
@@ -128,12 +128,13 @@ let FilterDialog = {
// To show progress on filter Saving/Updating on AJAX
this.showFilterProgress = $(
'<div id="show_filter_progress" class="wcLoadingIconContainer busy-fetching d-none">' +
'<div class="wcLoadingBackground"></div>' +
'<span class="wcLoadingIcon fa fa-spinner fa-pulse"></span>' +
'<span class="busy-text wcLoadingLabel">' + gettext('Loading data...') + '</span>' +
'</div>').appendTo($container);
`<div id="show_filter_progress" class="pg-sp-container sql-editor-busy-fetching d-none">
<div class="pg-sp-content">
<div class="row"><div class="col-12 pg-sp-icon sql-editor-busy-icon"></div></div>
<div class="row"><div class="col-12 pg-sp-text sql-editor-busy-text">${gettext('Loading data...')}</div></div>
</div>
</div>`
).appendTo($container);
$(
self.showFilterProgress[0]
).removeClass('d-none');
@@ -162,14 +163,14 @@ let FilterDialog = {
self.statusBar.removeClass('d-none');
$(self.statusBar.find('.alert-text')).html(msg);
// Disable Okay button
self.__internal.buttons[1].element.disabled = true;
self.__internal.buttons[2].element.disabled = true;
});
view.listenTo(view.model, 'pgadmin-session:valid', function() {
self.statusBar.addClass('d-none');
$(self.statusBar.find('.alert-text')).html('');
// Enable Okay button
self.__internal.buttons[1].element.disabled = false;
self.__internal.buttons[2].element.disabled = false;
});
});

View File

@@ -76,14 +76,13 @@ function updateUIPreferences(sqlEditor) {
.attr('title',
shortcut_title('Execute/Refresh',preferences.execute_query));
$el.find('#btn-flash-menu span')
.text(shortcut_title('Execute/Refresh',preferences.execute_query));
$el.find('#btn-explain')
.attr('title',
shortcut_title('Explain',preferences.explain_query));
$el.find('#btn-explain span')
.text(shortcut_title('Explain',preferences.explain_query));
$el.find('#btn-explain-analyze span')
.text(shortcut_title('Explain Analyze',preferences.explain_analyze_query));
$el.find('#btn-explain-analyze')
.attr('title',
shortcut_title('Explain Analyze',preferences.explain_analyze_query));
$el.find('#btn-download')
.attr('title',
@@ -144,7 +143,6 @@ function updateUIPreferences(sqlEditor) {
$conn_status.popover();
$conn_status.removeClass('connection-status-hide');
$el.find('.editor-title').addClass('editor-title-connection');
// To set initial connection
SqlEditorUtils.fetchConnectionStatus(sqlEditor.handler, $conn_status, $status_el);
@@ -157,7 +155,6 @@ function updateUIPreferences(sqlEditor) {
}
else {
$el.find('#btn-conn-status').addClass('connection-status-hide');
$el.find('.editor-title').removeClass('editor-title-connection');
}
/* Code Mirror Preferences */

View File

@@ -1,23 +1,31 @@
.aciTree .aciTreeLi {
display: grid !important;
}
.aciTree .aciTreeText {
font-family: $font-family-primary;
font-size: 12px;
}
.aciTree .aciTreeLine.aciTreeHover .aciTreeItem {
background-color: $color-primary-lighter;
.aciTree.aciTreeFocus .aciTreeFocus > .aciTreeLine {
background-color: $color-primary-light;
border-right: $active-border;
}
.aciTree .aciTreeSelected > .aciTreeLine {
background-color: $color-primary-light;
border-color: $color-primary-light;
}
.aciTree .aciTreeLine.aciTreeHover .aciTreeText {
color: $color-fg;
}
.aciTree.aciTreeFocus .aciTreeFocus > .aciTreeLine .aciTreeItem {
background-color: $color-primary-lighter;
}
.aciTree.aciTreeFocus .aciTreeFocus > .aciTreeLine .aciTreeText {
color: $color-fg;
border-right: $active-border;
border-left: none !important;
border-top: none !important;
border-bottom: none !important;
-webkit-border-radius: none !important;
-moz-border-radius: none !important;
border-radius: none !important;
}
.aciTree .aciTreeSelected > .aciTreeLine .aciTreeItem {
background-color: $color-primary-lighter;
border-color: $color-primary-light;
background-color: $color-primary-light;
border: 1px solid transparent;
-webkit-border-radius: none !important;
-moz-border-radius: none !important;
border-radius: none !important;
}
.aciTree .aciTreeItem {
white-space: nowrap !important;
@@ -25,3 +33,44 @@
.aciTree.aciTreeLoad {
background: none;
}
.aciTree .aciTreeLine.aciTreeHover {
background-color: $color-gray-light;
-webkit-border-radius: none !important;
-moz-border-radius: none !important;
border-radius: none !important;
}
.aciTree .aciTreeLine.aciTreeHover .aciTreeItem {
background-color: $color-gray-light;
border: 1px solid transparent;
-webkit-border-radius: none !important;
-moz-border-radius: none !important;
border-radius: none !important;
}
.aciTree.aciTreeFocus .aciTreeSelected >.aciTreeLine .aciTreeItem {
background-color: $color-primary-light;
}
.aciTree.aciTreeFocus .aciTreeFocus >.aciTreeLine .aciTreeItem,
.aciTree.aciTreeFocus .aciTreeSelected.aciTreeFocus >.aciTreeLine .aciTreeItem {
border: 1px solid transparent;
}
.aciTree .aciTreeButton {
background: none;
}
.aciTree .aciTreePush {
width: 30px;
background: url(../img/collapse_expand.svg) 12px 7px no-repeat;
}
.aciTree .aciTreeEntry,
.aciTree .aciTreeBranch,
.aciTree[dir=rtl] .aciTreeBranch {
overflow:hidden;
background: none !important;
}
.aciTree .aciTreeInode >.aciTreeLine .aciTreePush,
.aciTree .aciTreeInode >.aciTreeLine .aciTreePush.aciTreeHover {
background-position: 6px 6px !important;
}
.aciTree .aciTreeOpen >.aciTreeLine .aciTreePush,
.aciTree .aciTreeOpen >.aciTreeLine .aciTreePush.aciTreeHover {
background-position: -14px 5px !important;
}

View File

@@ -1,7 +1,7 @@
.alert-icon {
display: flex;
align-items: center;
color: $color-fg-inverse;
color: $alert-icon-color;
padding: 15px 15px 15px 17px;
width: 50px;
min-height: 50px;
@@ -46,8 +46,8 @@
}
.alert-info {
border-color: $color-primary-light;
background-color: $color-primary-lighter;
border-color: $color-primary;
background-color: $color-primary-light;
color : $color-primary;
background-image: none;
}
@@ -117,7 +117,8 @@
}
.error-in-footer {
border-radius: 4px;
border-radius: 5px;
border: 1px solid transparent;
.alert-text {
border-color: $color-danger-light;
@@ -125,7 +126,8 @@
}
.success-in-footer {
border-radius: 4px;
border-radius: 5px;
border: 1px solid transparent;
.alert-text {
border-color: $color-success-light;

View File

@@ -2,49 +2,80 @@
.alertify {
.ajs-header {
padding: 6px 10px !important;
min-height: 35px;
max-height: 35px;
border-bottom: 2px solid $color-gray-lighter;
//margin is calculated with -$alertify-borderremove-margin, adjust the header
min-height: $title-height + $alertify-borderremove-margin !important;
max-height: $title-height + $alertify-borderremove-margin !important;
background-color: $color-primary;
font-size: $font-size-base;
font-weight: bold;
color: $color-fg-inverse;
font-size: 14px;
font-weight: bold;
border-radius: 0;
color: $color-primary-fg;
overflow: hidden;
white-space: nowrap;
border-radius: 0rem;
border-top-left-radius: $panel-border-radius;
border-top-right-radius: $panel-border-radius;
border-bottom: none;
margin: -24px - $alertify-borderremove-margin; //-24px is default by alertify
margin-bottom: 0px;
&:hover {
background-color: $color-primary;
}
}
/* Overrides alertify js headers hovering behaviour*/
.ajs-header:hover {
background-color: $color-primary;
&.ajs-resizable,
&.ajs-maximized {
& .ajs-body {
& .ajs-content {
top: $title-height;
}
&.pgadmin_grant_wizard_body {
border-top-left-radius: $panel-border-radius;
border-top-right-radius: $panel-border-radius;
& .ajs-content {
top: 0;
border-radius: inherit;
}
}
}
& .ajs-header{
//default is 0, to override the borders
margin: -$alertify-borderremove-margin;
}
& .ajs-handle {
z-index: 5;
}
}
.ajs-body .ajs-content {
top: $title-height;
}
/* Removes padding from alertify footer */
.ajs-footer {
padding: 0;
min-height: 35px;
min-height: $footer-min-height;
border-top: $panel-border;
& .ajs-buttons {
border: none;
border-radius: 0rem;
border-bottom-left-radius: $panel-border-radius;
border-bottom-right-radius: $panel-border-radius;
padding: $footer-padding;
&.ajs-auxiliary .ajs-button,
&.ajs-primary .ajs-button {
margin: 0px 2px;
}
/* Restyling alertify buttons */
.ajs-footer .ajs-buttons {
background-color: $color-gray-light;
border-width: 2px 0px 0px 0px;
border-style: solid;
border-color: $color-gray-dark;
& .ajs-button {
font-family: $font-family-primary;
font-size: $font-size-base;
-webkit-font-smoothing: auto;
min-width: 0;
min-height: 0;
}
.ajs-footer .ajs-buttons.ajs-auxiliary .ajs-button,
.ajs-footer .ajs-buttons.ajs-primary .ajs-button {
margin-left: 2px;
margin-right: 2px;
margin-top: 2px;
margin-bottom: 0px;
}
.ajs-footer .ajs-buttons .ajs-button {
min-width: 40px;
min-height: 30px;
}
.ajs-commands {
@@ -73,18 +104,14 @@
/* Restyling alertify dialogue panel boundaries */
.ajs-dialog {
border: 3px solid $color-gray-lighter;
border-radius: 0;
border: $panel-border;
border-radius: $panel-border-radius;
box-shadow: $dialog-box-shadow;
}
.ajs-content {
padding-left: 0 !important;
padding-right: 0 !important;
}
.ajs-handle {
right: -4px;
bottom: -4px;
}
}
.alertify.ajs-maximized .ajs-commands,
@@ -100,12 +127,11 @@
.ajs-pin, .ajs-maximize, .ajs-close {
width: 20px;
height: 20px;
border: 2px solid $color-gray-light !important;
background-color: $color-gray-lighter !important;
border: $input-btn-border-width solid $btn-secondary-border !important;
background-color: $color-secondary !important;
font-size: 12px;
border-radius: 5px 5px 5px 5px;
border-radius: $btn-border-radius;
position: relative;
//float: right;
cursor: pointer;
text-align: center;
overflow: hidden;
@@ -113,7 +139,7 @@
}
.ajs-pin:hover, .ajs-maximize:hover, .ajs-close:hover {
border: 2px solid $color-gray-lighter !important;
background-color: $btn-secondary-hover-bg !important;
}
.alertify.ajs-modeless.ajs-pinnable .ajs-commands button.ajs-pin {
@@ -141,18 +167,26 @@
}
.alertify-notifier .ajs-message {
border-radius: 4px;
border-radius: $card-border-radius;
width: 100%;
}
button.pg-alertify-button {
font-family: $font-family-primary;
font-size: 14px;
-webkit-font-smoothing: auto;
}
.fa.pg-alertify-button:before {
font: normal normal normal 18px/1 FontAwesome;
.pg-alertify-button:before {
font-size: $font-size-base;
@at-root .ajs-button#{&} {
font-family: $font-family-icon;
margin-right: 5px;
}
}
.pg-alertify-icon-button {
//refered - $input-btn-padding-y, $input-btn-padding-x
padding: 0.275rem $input-btn-padding-x;
&:before {
font-size: 1.3em !important;
line-height: 1.3;
font-family: $font-family-icon;
}
}
.ajs-text-smoothing {
@@ -161,20 +195,20 @@ button.pg-alertify-button {
}
.ajs-message.ajs-error.ajs-visible {
@extend .bg-danger-lighter;
@extend .border-danger;
background: $color-danger-light;
border: $border-width solid $color-danger;
@extend .ajs-text-smoothing;
}
.ajs-message.ajs-success.ajs-visible {
@extend .bg-success-lighter;
@extend .border-success;
background: $color-success-light;
border: $border-width solid $color-success;
@extend .ajs-text-smoothing;
}
.ajs-message.ajs-visible {
@extend .bg-primary-lighter;
@extend .border-primary;
background: $color-primary-light;
border: $border-width solid $color-primary;
@extend .ajs-text-smoothing;
}

View File

@@ -60,3 +60,11 @@
div.backform_control_notes label.control-label {
min-width: 0px;
}
.subnode-header label {
max-width: 90% !important;
}
.set-group {
margin-bottom: $form-group-margin-bottom;
}

View File

@@ -1,14 +1,29 @@
.backgrid > th, .backgrid > td {
padding: 2px;
.backgrid th, .backgrid td {
font-weight: normal!important;
text-align: left;
}
.subnode > table.backgrid > thead > tr > th:first-child{
border-left-color: $color-primary;
}
.backgrid.backgrid-striped tbody {
& tr:nth-child(even) {
background: $table-bg;
.subnode > table.backgrid > thead > tr > th:last-child{
border-right-color: $color-primary;
& td.editor {
background: $table-bg;
outline: none;
}
}
& tr:nth-child(odd) {
background: $table-bg;
& td.editor {
background: $table-bg;
outline: none;
}
}
}
.backgrid tbody tr.empty td {
display: table-cell;
font-style: normal;
color: $text-muted;
}
.backgrid .textarea-cell {
@@ -52,52 +67,21 @@
-moz-appearance: none;
}
.subnode > table.backgrid{
width: 100%;
margin: 0px;
padding: 0;
margin-bottom: 15px;
.backgrid {
border-radius: inherit;
}
.backgrid > thead th{
background-color: $color-primary;
}
.backgrid > thead > th, .backgrid > tbody > td {
line-height: 18px;
}
.backgrid > thead > th {
letter-spacing:0.5px
}
.backgrid > tbody > td {
padding-top: 0px;
padding-bottom: 0px;
padding-left: 2px;
padding-right: 2px;
}
.backgrid > thead th a {
color: $color-fg-inverse;
font-size: 12px;
}
.backgrid > th.object {
width: 30px;
}
.backgrid.presentation {
background-color: $color-gray-lighter;
}
.backgrid.presentation td.renderable {
padding: 6px 3px 3px 3px;
font-size: 12px;
.backgrid thead td,
.backgrid thead th{
background: $color-bg-theme;
background-color: $color-bg-theme !important;
text-align: left;
}
.backgrid:not(.presentation) td.renderable:not(.editable):not(.delete-cell) {
background-color: $color-gray-lighter;
// if transparent border then setting color will help
border-bottom-color: $color-gray-lighter;
}
.backgrid tr.header td.renderable:not(.editable):not(.delete-cell) {
@@ -109,27 +93,8 @@
white-space: pre-wrap;
}
table.backgrid tr.new {
background-color: rgba($color-primary, 0.1) !important;
box-sizing: border-box;
outline: 1px solid rgba($color-primary, 0.8);
outline-offset: -1px;
}
.pg-panel-depends-container >table.backgrid.table-bordered {
border: 0px;
}
.alertify_tools_dialog_backgrid_properties {
top: 43px !important;
}
.pg-panel-statistics-container >table.backgrid.table-bordered {
border: 0px;
}
table.backgrid {
overflow: auto;
position: initial;
}
.backgrid td.editor input[type=password] {
@@ -162,13 +127,6 @@ table.backgrid {
user-select: text;
}
.backgrid tr th button {
background: none;
border: none;
color: $color-fg-inverse;
padding: 0;
}
/* Latest backgrid adds column name like `label` to td element, override color*/
.backgrid td.label {
color: $color-gray-dark;
@@ -179,3 +137,148 @@ table.backgrid {
span.form-control:disabled {
@extend .form-control:disabled
}
.subnode {
border: $panel-border;
background: $color-bg-theme;
}
.subnode-noouter-border {
border: none !important;
}
.subnode > table.backgrid > thead > tr > th:last-child {
border-right-color: $color-primary;
}
.subnode > table.backgrid {
width: 100%;
margin: 0px;
padding: 0;
}
.subnode-header button {
border-left: 1px solid $border-color;
border-bottom-width: 0px !important;
border-top-width: 0px !important;
border-right-width: 0px !important;
border-radius: 0px !important;
text-align: center !important;
padding: 8px 8px !important;
min-height: 31px !important;
margin: 0px !important;
}
.subnode-header .control-label {
min-height: 31px;
font-weight: bold;
}
.subnode-footer {
text-align: right;
border-color: $color-gray-light;
border-style: inset inset inset solid;
border-width: 2px 1px 0;
margin-top: -10px;
}
.subnode-footer .ajs-button {
margin: 2px 2px 0;
}
/* Sub-Node */
.edit-cell, .delete-cell {
text-align:center !important;
width:25px;
height:29px !important;
}
.subnode-header {
background-color: $color-bg-theme;
color: $color-fg-theme;
border-bottom: $panel-border;
}
.subnode-header > button.add {
float: right;
margin-right: 3px;
margin-bottom: 3px;
margin-top: 5px;
}
.subnode-dialog {
bottom: 0;
left: 0;
overflow-x: auto;
overflow-y: auto;
right: 0;
height: auto;
margin-top: 0px;
}
.subnode-body {
height: auto;
overflow: inherit;
background-color: $color-bg;
border: 1px solid $border-color;
border-radius: $panel-border-radius;
}
.subnode-footer {
height: 38px;
margin: 0px, 15px;
min-height: 40px;
vertical-align: bottom;
}
.sub-node-form {
height: auto;
padding-left: 0rem !important;
padding-right: 0rem !important;
}
.sub-node-form > ul.tab-content{
background-color: $color-bg;
padding-left: 15px;
left: 1px;
}
.subnode-header-form {
background-color: $color-gray-lighter;
padding: 7px;
border-bottom: $panel-border;
}
.subnode-header-form button.add {
float: right;
margin-right: 0px;
}
.subnode-error .help-block {
color: $color-danger;
}
table.backgrid {
overflow: auto;
}
.backgrid tbody {
& td.editor {
background-color: $color-gray-light !important;
border-bottom-color: $color-gray-light !important;
outline: none !important;
}
tr.editor-row {
& > td {
padding: 15px !important;
background-color: $color-gray-light !important;
border-top: none !important;
border-bottom-color: $color-gray-light !important;
}
}
}
table tr th button {
font-weight: bold;
}

View File

@@ -1,10 +1,3 @@
.dropdown-menu > .dropdown-item > span {
padding-left: 3px;
}
.dropdown-menu > .dropdown-item > .has-icon {
padding-left: 0px;
}
/* Ensure simple forms don't hit the top of the screen */
body {
font-family: $font-family-primary;
@@ -15,37 +8,40 @@ body {
vertical-align: middle;
}
/* Use the full width of the screen */
.container {
width: 100% !important;
}
/* iFrames should have no border */
iframe {
border-width: 0;
}
/* Padding for the treeview */
.browser-browser-pane {
padding-left: 0;
}
/* Disabled menu items */
.mnu-disabled {
color: $color-gray !important;
}
.dropdown-divider {
margin: 0px;
.dropdown-menu {
box-shadow: $dropdown-box-shadow;
}
.dropdown-toggle::after {
font-family: $font-family-icon;
content: "\f078";
font-size: 0.6rem;
vertical-align: 2px;
margin-left: 0rem;
border: none;
width: auto;
}
/*
* Bootstrap 3 remove submenus as they don't work overly well on Mobile. The
* following CSS adds them back in - for our purposes they actually work fine
@@ -55,43 +51,53 @@ iframe {
position: relative;
}
.dropdown-submenu>.dropdown-menu {
-moz-border-radius: 0 6px 6px 6px;
-webkit-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
-moz-border-radius: $dropdown-border-radius;
-webkit-border-radius:$dropdown-border-radius;
border-radius: $dropdown-border-radius;
left: 100%;
margin-left: -1px;
top: 2px;
top: $dropdown-submenu-top;
}
.dropdown-submenu:hover>.dropdown-menu {
display: block;
.dropdown-submenu .dropdown-menu.show {
background-color: $dropdown-bg;
}
.dropdown-submenu>a:after {
border-color: transparent;
border-left-color: $color-gray-light;
border-style: solid;
border-width: 5px 0 5px 5px;
content: " ";
display: block;
font-family: $font-family-icon;
content: "\f054";
float: right;
height: 0;
margin-right: -10px;
margin-top: 5px;
width: 0;
font-size: 0.6rem;
line-height: 2;
}
.dropdown-submenu:hover>a:after {
border-left-color: $color-bg;
border-left-color: $dropdown-link-hover-color;
}
.dropdown-submenu.pull-left {
float: none;
}
.dropdown-submenu.pull-left>.dropdown-menu {
-moz-border-radius: 6px 0 6px 6px;
-webkit-border-radius: 6px 0 6px 6px;
border-radius: 6px 0 6px 6px;
-moz-border-radius: $dropdown-border-radius;
-webkit-border-radius: $dropdown-border-radius;
border-radius: $dropdown-border-radius;
left: -100%;
margin-left: 10px;
}
.dropdown-submenu-visible>.dropdown-item {
background-color: $dropdown-link-hover-bg;
color: $dropdown-link-hover-color;
}
/** Overriding secondary button of bootstrap **/
/* Used Bootstrap 4 Mixin button-variant
* Refer file : bootstrap/scss/mixins/_buttons.scss
*/
.btn-secondary {
@include button-variant($color-secondary, $btn-secondary-border, $btn-secondary-hover-bg);
}
.form-group fieldset {
background-color: $color-gray-lighter;
border-color: $color-gray-lighter;
@@ -134,16 +140,77 @@ iframe {
padding: 5px 25px 5px 5px;
vertical-align: middle;
}
.form-control {
color: $color-gray-dark;
padding: 3px 6px;
}
.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control {
color: $color-gray-dark;
color: $text-muted;
}
.card-header {
padding: $card-header-padding;
font-weight: bold;
}
.table {
margin-bottom: 0rem;
}
.table-bordered {
border: $panel-border;
& thead {
& th, & td {
border-bottom: none;
}
& tr {
font-weight: bold !important;
// for first row, remove top border
&:first-of-type{
& td, & th {
border-top: none !important;
}
}
}
}
& tbody {
& tr {
& th, & td {
border-top: $panel-border;
border-bottom: none;
}
}
}
& thead, & tbody {
& tr {
& td, & th {
&:first-of-type {
border-left: none;
}
&:last-of-type {
border-right: none;
}
}
}
}
}
.table.table-hover {
& > tbody {
& > tr:not(.nohover):not(.empty):hover, tr.selected {
background-color: $table-hover-bg-color;
& > td {
border-top: $table-hover-border;
border-bottom: $table-hover-border;
}
}
& > tr.nohover {
background-color: transparent;
}
}
}
/* Override default bootstrap popover fonts & size */
.popover-content {
@@ -151,11 +218,6 @@ iframe {
font-size: 13px;
}
.navbar .dropdown-menu {
padding-top: 0;
}
/* Remove default left padding from checkbox for bootstrap-switch */
.checkbox {
@@ -178,52 +240,32 @@ iframe {
width: 0px;
}
/* Center align the switch in backgrid */
td.switch-cell > div.bootstrap-switch {
display: block;
margin: auto;
}
.dropdown-menu > hr {
margin-bottom: 0;
margin-top: 0;
}
.dropdown-menu > li > a > i {
margin-left: -17px;
width: 13px;
}
.dropdown-menu > li > a > span {
cursor: pointer;
padding-left: 3px;
}
.dropdown-menu > li > a > .has-icon {
padding-left: 0px;
}
.dropdown-menu > li > a:not(.disabled):hover, .dropdown-menu > li > a:not(.disabled):focus {
background: $color-gray-dark none;
color: $color-fg-inverse;
}
.nav {
&.nav-tabs {
height: $title-height;
border-top-left-radius: inherit;
border-top-right-radius: inherit;
.navbar-nav .nav-item .dropdown-menu {
@extend .bg-dark;
margin-top: -0.2rem;
& .dropdown-item {
@extend .text-white;
&.disabled {
@extend .text-muted;
& .nav-link {
border: none !important;
padding: $tabs-padding;
color: $color-fg-theme;
font-weight: bold;
&.active {
border-bottom: $active-border !important;
}
}
}
}
/* If Bootstrap tab is already active then don't show pointer cursor */
.nav-tabs > .nav-item > .nav-link.active {
color: $color-fg;
background-color: $color-fg-inverse;
cursor: default;
.navbar-nav .nav-item > .dropdown-menu {
top: $navbar-dropdown-top;
}
.bootstrap-datetimepicker-widget td, .bootstrap-datetimepicker-widget th {
@@ -233,6 +275,14 @@ td.switch-cell > div.bootstrap-switch {
.navbar-brand {
color: $color-brand !important;
background: $color-brand-bg !important;
margin-right: 0rem;
padding-left: 0.5rem !important;
padding-right: 1rem !important;
min-height: $title-height;
padding: 0rem;
display: flex;
align-items: center !important;
}
.navbar-brand:hover {
@@ -259,13 +309,5 @@ td.switch-cell > div.bootstrap-switch {
}
.bootstrap-datetimepicker-widget thead th {
background-color: $color-fg-inverse;
}
.nav-tabs {
background-color: $color-gray-lighter;
}
.nav-tabs > .nav-item > .nav-link:hover:not(.active) {
background-color: $color-gray-white;
background-color: $color-bg;
}

View File

@@ -7,6 +7,10 @@
background-color: $color-gray-lighter !important;
}
.CodeMirror {
font-size: 1em;
}
/* Ensure the codemirror editor displays full height gutters when resized */
.CodeMirror, .CodeMirror-gutter {
height: 100% !important;
@@ -28,10 +32,6 @@
border-right: 1px solid $color-gray-lighter;
}
.CodeMirror-linenumber {
font-size: $font-size-base;
}
/* class to disable Codemirror editor */
.cm_disabled {
background: $input-disabled-bg;
@@ -51,7 +51,7 @@
/* Codemirror buttons */
.CodeMirror-dialog button {
font-family: $font-family-primary;
color: $color-fg-inverse;
color: $color-primary-fg;
font-size: 70%;
background-image: -webkit-linear-gradient(top, $color-primary-light 0%, $color-primary 100%);
background-image: -o-linear-gradient(top, $color-primary-light 0%, $color-primary 100%);
@@ -64,27 +64,81 @@
border-radius: 4px;
}
#history-detail-query .CodeMirror {
border: 1px solid $color-gray-light;
background-color: $color-gray-lighter;
width: 100%;
padding-left: 5px;
position: absolute;
}
.CodeMirror-gutters {
z-index: 2;
}
.sql_textarea {
height: 100%;
}
.sql_textarea .CodeMirror-scroll {
z-index: 0;
background-color: $sql-gutters-bg;
border-right: none;
}
/* workaround for codemirrors 'readOnly' option which is set to true instead of 'noCursor' */
.hide-cursor-workaround .CodeMirror-cursors {
display: none;
}
.CodeMirror-foldmarker {
color: $color-primary;
text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
line-height: .3;
cursor: pointer;
}
.CodeMirror-linenumber {
color: $color-fg-theme;
}
.debugger-container .breakpoints {
width: 0.9em;
}
.CodeMirror, .CodeMirror-gutters {
min-height: 100%;
}
.CodeMirror-foldgutter {
width: .9em;
}
.CodeMirror-foldgutter-open,
.CodeMirror-foldgutter-folded {
cursor: pointer;
}
.CodeMirror-foldgutter-open:after {
content: "\25BC";
}
.CodeMirror-foldgutter-folded:after {
content: "\25B6";
}
.CodeMirror-foldmarker {
color: $color-editor-foldmarker;
text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
font-family: $font-family-primary;
line-height: .3;
cursor: pointer;
}
.CodeMirror-hints {
position: absolute;
z-index: 10;
overflow: hidden;
list-style: none;
margin: 0;
padding: 2px;
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
border-radius: 3px;
border: 1px solid $border-color;
background: $color-bg-theme;
font-size: 90%;
font-family: $font-family-editor;
max-height: 20em;
overflow-y: auto;
}

View File

@@ -0,0 +1,56 @@
/* The Bootstrap default grid layout is based on @media - window size
* But in pgadmin4, we need to resize/make responsive elements based on panel size
* which can be changed by wcDocker. Below code will generate pg-el-* classes
* using the bootstrap grid classes generator. Based on el attribute of pg-el-container div,
* the classes will apply.el attribute is set in /pgadmin4/web/pgadmin/browser/static/js/panel.js
*
* Code reused and customized from : bootstrap/scss/mixins/_grid-framework.scss
*/
@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {
// Common properties for all breakpoints
%grid-column {
position: relative;
width: 100%;
padding-right: ($gutter / 2);
padding-left: ($gutter / 2);
}
@each $breakpoint in map-keys($breakpoints) {
$infix: breakpoint-infix($breakpoint, $breakpoints);
// Allow columns to stretch full width below their breakpoints
@for $i from 1 through $columns {
.pg-el#{$infix}-#{$i} {
@extend %grid-column;
}
}
.pg-el-container[el=xs]
.pg-el#{$infix},
.pg-el-container[el=xs]
.pg-el#{$infix}-auto {
@extend %grid-column;
}
// Provide basic `.pg-el-{bp}` classes for equal-width flexbox columns
.pg-el-container[el=xs]
.pg-el#{$infix} {
flex-basis: 0;
flex-grow: 1;
max-width: 100%;
}
@for $i from 1 through $columns {
.pg-el-container[el=lg],
.pg-el-container[el=md],
.pg-el-container[el=sm]
.pg-el#{$infix}-#{$i} {
@include make-col($i, $columns);
}
}
}
}
@include make-grid-columns();

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
.select2-container--default .select2-results__option--highlighted[aria-selected] {
background-color: $color-primary-lighter;
background-color: $color-primary-light;
color: $color-gray-dark;
}
@@ -15,8 +15,19 @@
width: 100% !important;
}
.select2-container .select2-selection--single .select2-selection__rendered{
padding-left: 5px;
.select2-container .select2-selection--single {
height: unset;
min-height: 28px;
& .select2-selection__rendered{
line-height: inherit;
padding: $input-padding-y $input-padding-x;
padding-right: 1.5rem;
}
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
top: 0px;
height: 100%;
}
@@ -36,7 +47,6 @@
.select2-results span.wcTabIcon {
padding-left: 20px;
background-position: 0px 2px;
}
.select2-selection {
@@ -49,11 +59,17 @@
.select2-container--default.select2-container--disabled .select2-selection--multiple {
background-color: $input-disabled-bg !important;
opacity: 1;
color: $text-muted;
}
.select2-container--default.select2-container--disabled .select2-selection--single {
background-color: $input-disabled-bg !important;
opacity: 1;
color: $text-muted;
}
.select2-container--default.select2-container--disabled .select2-selection__rendered {
color: $text-muted;
}
.select2-select-all-adapter-container {

View File

@@ -1,368 +0,0 @@
.wcDocker {
background-color: $color-bg;
}
.wcPanelBackground {
background-color: $color-bg;
}
.wcPanelBackground .wcCenter {
background-color: $color-gray-lighter;
}
.wcFrameFlasher {
background-color: $color-danger;
}
.wcFrameShadower {
background-color: $color-gray-light;
}
.wcFrameTitle {
font-size: 13px;
padding-left: 8px;
vertical-align: middle;
text-align: left;
border-bottom: 1px none;
height: 100%;
padding-top: 10px;
background-color: $color-gray-lighter;
}
.wcFrameCenter {
top: 35px;
}
.wcFrameButton {
width: 20px;
height: 20px;
border: 2px solid $color-gray;
background-color: $color-gray-lighter;
font-size: 12px;
border-radius: 5px 5px 5px 5px;
margin-right: 2px;
}
.wcFrameButton.disabled {
pointer-events: none;
opacity: 0.4;
}
.wcFrameMiniButton {
width: 8px;
}
.wcFrameButton.wcFrameButtonLeft {
right: 10px;
}
.wcFrameButton.wcFrameButtonRight {
right: 10px;
}
.wcFrameButton:hover {
border: 2px solid $color-gray-light;
}
.wcFrameButton:active {
border: 2px solid $color-gray-lighter;
}
.wcFrameButtonToggled, .wcFrameButtonToggled:hover {
border-style: inset;
}
.wcLayoutGrid, .wcLayoutGrid tr, .wcLayoutGrid td {
border: 1px solid $color-gray;
}
.wcLayoutGridAlternate tr:nth-child(even), .wcLayoutGridAltColor {
background-color: rgba($color-danger-light, 0.2) !important;
}
.wcFrameEdge {
border: 1px solid $color-gray-lighter;
background-color: $color-gray-lighter;
}
.wcFrame > .wcFrameEdgeV ~ .wcFrameEdgeV {
box-shadow: 3px 6px 3px 1px $color-gray !important;
}
.wcFrame > .wcFrameEdge ~ .wcFrameEdgeV {
box-shadow: 1px 0px 0px 0px $color-gray;
}
.wcFrame > .wcFrameEdgeH ~ .wcFrameEdgeH {
box-shadow: 2px 3px 3px 2px $color-gray !important;
}
.wcFrame > .wcFrameEdgeH {
box-shadow: 1px 0px 0px 0px $color-gray;
}
.wcFrameEdgeH {
height: 6px;
}
.wcFrameEdgeV {
width: 6px;
}
.wcFrameCornerNW,
.wcFrameCornerNE {
height: 6px;
width: 6px;
}
.wcSplitterBar {
border: 1px solid $color-gray;
background-color: $color-gray-light;
}
.wcSplitterBarV {
border-left: 3px solid $color-gray-light;
height: 100% !important;
}
.wcSplitterBarH {
border-top: 3px solid $color-gray-light;
width: 100% !important;
}
.wcPanelTab {
color: $color-primary;
background-color: $color-gray-lighter;
border: 0px;
border-radius: 4px 4px 0px 0px;
border-bottom: 0px;
margin-right: 1px;
margin-top: 10px;
font-size: 13px;
padding-left: 8px;
padding-right: 8px;
padding-top: 4px;
padding-bottom: 4px;
}
.wcPanelTab:hover {
background-color: $color-gray-white;
padding-bottom: 10px;
}
.wcPanelTabActive {
background-color: $color-bg;
color: $color-fg;
margin-top: 5px;
line-height: 30px;
font-weight: normal;
}
.wcFloating .wcPanelTabActive {
background-color: $color-primary;
margin-top: -2px;
font-weight: bold;
color: $color-fg-inverse;
}
.wcFloating .wcPanelTabActive:hover {
background-color: $color-primary-light;
}
.wcGhost {
background-color: $color-primary-light;
border-radius: 6px;
}
.wcMenuList, .context-menu-list {
border: 1px solid $color-gray-lighter;
z-index: 999 !important;
background: $color-gray-lighter;
}
.wcMenuItem, .context-menu-item {
background-color: $color-gray-lighter;
}
.wcMenuItemHover, .wcMenuItem:hover, .context-menu-item.hover, .context-menu-item:hover {
background-color: $color-primary !important;
}
.wcMenuItem.disabled, .context-menu-item.disabled {
color: $color-gray-dark;
background-color: $color-gray;
}
.wcMenuSeparator, .context-menu-separator {
border: 2px solid $color-gray-light;
background-color: $color-gray-lighter;
}
.wcInput, input {
background-color: transparent;
}
.wcSelect, select {
background-color: transparent;
}
.wcLayout, .wcLayout tr, .wcLayout td {
vertical-align: top;
}
.wcPanelTab > div > .wcTabIcon {
display: inline-block;
text-align: center;
padding-left: 20px;
margin-top: -5px;
margin-right: 5px;
}
.wcPanelTab > div .wcTabIcon.fa {
padding-left: 0px !important;
color: $color-fg;
}
.wcTabIcon.fa {
margin-right: 5px;
}
.wcFrameTitleBar {
background-color: $color-gray-lighter;
height: 35px;
border-bottom: $color-gray;
}
.wcFloating .wcFrameTitleBar {
border-bottom: 2px solid $color-gray;
background-color: $color-primary;
}
.wcFloating .wcFrameTitleBar > div .wcTabIcon.fa {
color: $color-fg-inverse;
}
.wcFrame .wcFrameTitleBar a:hover {
color: $color-primary-dark;
}
.wcFrameButtonBar {
top: 5px;
right: 5px;
}
.context-menu-list {
font-family: $font-family-primary;
font-size: 13px;
}
.context-menu-icon:before {
color: $color-gray-darker;
font-size: 13px;
}
.context-menu-icon-fa:before {
font-family: 'FontAwesome'
}
.context-menu-item {
display:block;
font-family: $font-family-primary;
font-size: 13px;
font-weight: normal;
}
.context-menu-list {
padding: 2px 0;
width: initial !important;
}
.context-menu-list > .context-menu-item {
display:block !important;
}
.context-menu-list > .context-menu-separator {
margin: 0;
border: 1px solid $color-bg;
}
.context-menu-icon-wcTabIcon {
text-align: left;
padding: 3px 28px;
height: auto;
background-position: 5px 50%;
}
ul.dropdown-menu > li.menu-item > a > i.wcTabIcon {
width: 14px;
}
.wcFrameButton .fa.fa-close,
.wcFrameButton .fa.fa-filter,
.wcFrameButton .fa.fa-table,
.wcFrameButton .fa.fa-bolt {
margin-top: 3.5px;
padding-left: 1px;
}
span.fa.fa-arrow-left, .fa-arrow-right {
margin-top: 4px;
width: 14px;
}
.wcMenuSubMenu {
visibility: hidden;
}
i.wcTabIcon {
min-width: 20px;
}
.wcLoadingBackground {
background: $color-bg-inverse;
opacity: 0.6 !important;
}
.wcLoadingIcon.fa-spinner {
position: absolute;
top: 34%;
left: 48%;
font-size: 50px;
color: $color-gray-light;
height: 49px !important;
}
.wcLoadingLabel {
top: 40%;
left: 0;
color: $color-fg-inverse;
width: 100%;
font-size: 20px;
position: absolute;
text-align: center;
}
.wcPanelTab > div {
display: inline-block;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
max-width: 125px;
}
.wcPanelTabActive > div {
width: auto !important;
max-width: 100%;
}
.wcFrameTitleBar.wcTabTop .wcFrameButtonBar {
right: 30px !important;
}
.wcFloating .wcPanelTab .wcTabIcon {
display: block;
float: left;
margin-top: 8px;
border-radius: 2px;
padding: 0px 13px 5px 5px;
background-color: $color-bg;
background-size: 18px !important;
height: 18px;
}

View File

@@ -0,0 +1,250 @@
.wcDocker {
background-color: $color-bg-theme;
}
.wcModalBlocker {
background-color: $color-bg-theme;
}
.wcPanelBackground {
background-color: $color-bg-theme;
}
.wcPanelBackground .wcCenter {
background-color: $color-bg-theme;
}
.wcFrameFlasher {
background-color: $color-bg-theme;
}
.wcFrameShadower {
background-color: $color-bg-theme;
}
.wcFrameTitleBar {
height: $title-height;
background-color: $color-bg-theme;
border-bottom: $panel-border;
}
.wcFrameButton {
width: 25px;
height: 20px;
display: flex;
border-radius: $btn-border-radius;
margin: auto;
}
/* darken % taken from bootstrap - button_variant */
.wcFrameButton:hover, .wcFrameButtonHover {
background-color: $btn-secondary-hover-bg;
}
.wcFrameButton.disabled {
pointer-events: none;
color: $color-gray;
}
.wcFrameButton .fa {
margin: auto;
}
.wcFrameButtonBar {
height: $title-height;
background-color: $color-bg-theme;
border-bottom: $panel-border;
padding: 0rem 0.25rem;
display: -webkit-flex; /* Safari */
-webkit-flex-direction: row-reverse; /* Safari 6.1+ */
display: flex;
flex-direction: row-reverse;
}
.wcLayoutGrid, .wcLayoutGrid tr, .wcLayoutGrid td {
border: 1px solid $panel-border-color;
}
.wcFrameCenter {
top: $title-height;
}
.wcLayoutGrid, .wcLayoutGrid tr, .wcLayoutGrid td {
border: 1px solid $panel-border-color;
}
.wcPanelTab, .wcFrameTitle{
color: $color-fg-theme;
padding: $tabs-padding;
margin: 0px;
font-weight: bold;
}
.wcFloating {
box-shadow: $box-shadow;
z-index: 1050 !important;
}
.wcFloating .wcPanelTabActive {
border-bottom: none;
color: $color-fg-theme;
font-weight: bold;
}
.wcFloating .wcPanelTabActive:hover {
background-color: $color-primary-light;
}
.wcFloating .wcFrameTitleBar {
height: $title-height;
background-color: $color-bg-theme;
border-bottom: $panel-border;
}
.wcTabIcon {
background-position: center;
padding: 0px 10px;
&.fa{
padding: 0rem 0.25rem 0rem 0rem
}
}
.wcFloating .wcPanelTab .wcTabIcon {
color: $color-primary;
padding: 0px 10px;
}
.wcPanelTabActive {
border-bottom: $active-border;
color: $color-primary;
}
.wcFrameEdge {
background-color: $panel-border-color;
border: none;
}
.wcFrameEdgeH {
height: $panel-border-width;
}
.wcFrameEdgeV {
width: $panel-border-width;
}
.wcFrameCornerNW,
.wcFrameCornerNE,
.wcFrameCornerSW,
.wcFrameCornerSE {
height: $panel-border-width;
width: $panel-border-width;
}
.wcSplitterBar {
background-color: $panel-border-color;
border: none;
}
.wcSplitterBarV {
width: $panel-border-width;
}
.wcSplitterBarH {
height: $panel-border-width;
}
.wcSplitterBarV.wcSplitterBarStatic {
width: 0px;
}
.wcSplitterBarH.wcSplitterBarStatic {
height: 0px;
}
.wcGhost {
background-color: $color-primary-light;
border-radius: 6px;
}
.wcMenuList, .context-menu-list {
border: 1px solid $dropdown-border-color;
z-index: 999 !important;
background-color: $dropdown-bg;
box-shadow: $dropdown-box-shadow;
border-radius: $dropdown-border-radius;
}
.wcMenuItem, .context-menu-item {
color: $dropdown-link-color;
background-color: $dropdown-bg;
}
.wcMenuItemHover, .wcMenuItem:hover, .context-menu-item:not(.context-menu-not-selectable).hover, .context-menu-item:not(.context-menu-not-selectable):hover {
color: $dropdown-link-hover-color;
background-color: $dropdown-link-hover-bg !important;
}
.wcMenuItem.disabled, .context-menu-item.disabled {
color: $text-muted;
background-color: $dropdown-bg;
}
.wcMenuSeparator, .context-menu-separator {
border: 0.5px solid $dropdown-border-color;
}
.wcLoadingBackground {
background: $loading-bg;
}
.wcLoadingLabel {
top: 50%;
left: 0;
color: $loading-fg;
width: 100%;
font-size: 20px;
position: absolute;
text-align: center;
}
.wcLoadingIcon.pg-sp-icon {
left: 0;
top: calc(50% - 75px);
}
.wcPanelTab > div {
// display: inline-block;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
max-width: 125px;
}
.wcPanelTabActive > div {
width: auto !important;
max-width: 100%;
}
.context-menu-item.context-menu-disabled {
color: $text-muted;
background-color: $dropdown-bg;
}
.context-menu-submenu::after {
font-family: 'FontAwesome';
content: "\f054" !important;
right: 15px;
top: unset;
font-size: 0.6rem;
line-height: 2;
border-style: none;
}
.wcMenuSubMenu::before{
content: none;
}

View File

@@ -1,19 +1,16 @@
$font-size-base: 0.875rem;
$navbar-padding-y: 0 rem;
$form-group-margin-bottom: 0.5rem;
$btn-active-box-shadow: none;
@import './resources/pgadmin.resources.scss';
$theme-colors: (
"primary": $color-primary,
"danger": $color-danger,
"success": $color-success,
"warning": $color-warning,
"dark": #000
);
@import "node_modules/bootstrap/scss/bootstrap";
@import 'webcabin.overrides';
@import 'webcabin.pgadmin';
@import 'bootstrap.overrides';
@import 'backgrid.overrides';
@import 'aci_tree.overrides';
@@ -22,4 +19,5 @@ $theme-colors: (
@import 'alert';
@import 'alertify.overrides';
@import 'backform.overrides';
@import 'pgadmin.grid';
@import 'pgadmin.style';

View File

@@ -7,10 +7,6 @@
.bg-primary {
background-color: $color-primary;
&-lighter {
background-color: $color-primary-lighter;
}
&-light{
background-color: $color-primary-light;
}
@@ -18,71 +14,31 @@
&-dark{
background-color: $color-primary-dark;
}
&-darker{
background-color: $color-primary-darker;
}
}
.bg-danger {
background-color: $color-danger;
&-lighter {
background-color: $color-danger-lighter;
}
&-light {
background-color: $color-danger-light;
}
&-dark{
background-color: $color-danger-dark;
}
&-darker{
background-color: $color-danger-darker;
}
}
.bg-success {
background-color: $color-success;
&-lighter {
background-color: $color-success-lighter;
}
&-light {
background-color: $color-success-light;
}
&-dark{
background-color: $color-success-dark;
}
&-darker{
background-color: $color-success-darker;
}
}
.bg-warning {
background-color: $color-warning;
&-lighter {
background-color: $color-warning-lighter;
}
&-light {
background-color: $color-warning-light;
}
&-dark{
background-color: $color-warning-dark;
}
&-darker{
background-color: $color-warning-darker;
}
}
@@ -110,10 +66,6 @@
.border-primary {
border-color: $color-primary;
&-lighter {
border-color: $color-primary-lighter;
}
&-light {
border-color: $color-primary-light;
}
@@ -121,50 +73,22 @@
&-dark {
border-color: $color-primary-dark;
}
&-darker {
border-color: $color-primary-darker;
}
}
.border-danger {
border-color: $color-danger;
&-lighter{
border-color: $color-danger-lighter;
}
&-light {
border-color: $color-danger-light;
}
&-dark {
border-color: $color-danger-dark;
}
&-darker {
border-color: $color-danger-darker;
}
}
.border-success {
border-color: $color-success-light;
&-lighter {
border-color: $color-success-lighter;
}
&-light {
border-color: $color-success-light;
}
&-dark {
border-color: $color-success-dark;
}
&-darker {
border-color: $color-success-darker;
}
}
.border-gray {
@@ -185,19 +109,9 @@
&-darker {
border: 2px solid $color-gray-darker;
}
&-white {
border: 2px solid $color-gray-white;
}
}
/* Typography */
.text-fg-inverse {
color: $color-fg-inverse;
}
.text-gray {
color: $color-gray;
@@ -241,3 +155,7 @@
font-family: $font-family-primary;
font-size: 11px;
}
.text-semibold {
font-family: $font-family-semibold;
}

View File

@@ -1,59 +1,186 @@
/** Dividing a pixel var with 1px or rem var with 1rem removes the unit px/rem **/
$enable-flex: true !default;
$color-bg: #fff !default;
$color-fg: #000 !default;
$white: #fff;
$black: #000;
$color-bg-inverse: $color-fg;
$color-fg-inverse: $color-bg;
$color-bg: $white !default;
$color-fg: #222222 !default;
$color-primary: #2c76b4 !default;
$color-primary-fg: #fff !default;
$color-bg-theme: $white !default;
$color-fg-theme: #222222 !default;
$color-danger: #d63a35 !default;
$color-danger-fg: #fff !default;
$color-primary: #326690 !default;
$color-primary-fg: $white !default;
$color-primary-light: #d6effc;
$color-primary-dark: #295c85;
$color-success: #3a773a !default;
$color-success-fg: $color-fg !default;
$color-secondary: $white !default;
$color-danger: #e53935 !default;
$color-danger-fg: $white !default;
$color-danger-light: #FBE1E1;
$color-success: #43a047 !default;
$color-success-fg: $black !default;
$color-success-light: #DDF1DE;
$color-warning: #eea236 !default;
$color-warning-fg: $color-fg !default;
$color-warning-fg: $black !default;
$color-warning-light: #fce5c5;
$color-gray-darker: #5b6d7c;
$color-gray-dark: #848ea0;
$color-gray: #bac1cd;
$color-gray-light: #ebeef3;
$color-gray-lighter: #f3f5f9;
$color-brand: $white !default;
$color-brand-bg: #222222;
$color-brand: #009dcf !default;
$color-editor-bg: $color-bg !default;
$color-editor-keyword: #908 !default;
$color-editor-number: #964 !default;
$color-editor-foldmarker: #0000FF !default;
$color-editor-activeline: #50B0F0 !default;
$gray-base: #000 !default;
$color-gray-darker: #333333;
$color-gray-dark: #555555;
$color-gray: #888888;
$color-gray-light: #cccccc;
$color-gray-lighter: #e8e8e8;
$color-gray-white: #f9f9f9;
$color-primary-light: lighten($color-primary, 25%);
$color-primary-lighter: lighten($color-primary, 50%);
$color-primary-dark: darken($color-primary, 10%);
$color-primary-darker: darken($color-primary, 25%);
$color-danger-light: lighten($color-danger, 25%);
$color-danger-lighter: lighten($color-danger, 40%);
$color-danger-dark: darken($color-danger, 10%);
$color-danger-darker: darken($color-danger, 25%);
$color-success-light: lighten($color-success, 30%);
$color-success-lighter: lighten($color-success, 50%);
$color-success-dark: darken($color-success, 10%);
$color-success-darker: darken($color-success, 25%);
$color-warning-light: lighten($color-warning, 25%);
$color-warning-lighter: lighten($color-warning, 40%);
$color-warning-dark: darken($color-warning, 25%);
$color-warning-darker: darken($color-warning, 40%);
/* Typography */
$font-family-primary: "Open Sans" !default;
$font-family-primary: "Roboto" !default;
$font-family-semibold: "Roboto Medium" !default;
$font-family-editor: 'Source Code Pro' !default;
$font-family-icon: 'FontAwesome' !default;
$border-width: 1px;
$border-color: rgba($color-gray, 0.5);
$border-color-dark: $color-gray;
$box-shadow: 0 0.5rem 3rem $color-gray-dark;
/** Bootstrap Variable Changes **/
$gray-600: $color-gray-dark;
$gray-900: $color-fg-theme;
$body-color: $color-fg-theme;
$font-size-base: 0.815rem;
$grid-gutter-width: 15px;
$border-radius: 0.25rem; //no change
$text-color: $color-fg-theme;
$text-muted: $color-gray-dark;
$navbar-dark-color: #fff;
$navbar-dark-hover-color: #fff;
$navbar-dark-active-color: #fff;
$navbar-dark-disabled-color: $color-gray;
$navbar-toggler-padding-y: 0.25rem; //no-change
$form-group-margin-bottom: 0.5rem;
$btn-active-box-shadow: none;
$dropdown-link-hover-color: $white;
$dropdown-link-hover-bg: $color-primary;
$dropdown-border-color: $border-color;
$dropdown-box-shadow: 0 0.125rem 0.5rem rgba($color-gray-dark, .175);
$dropdown-divider-bg: $dropdown-border-color;
$dropdown-padding-y: 0.25rem;
$dropdown-item-padding-x: 1rem;
$dropdown-spacer: .125rem; //no-change
$nav-divider-margin-y: .25rem;
$input-btn-focus-width: 0.1rem;
$btn-disabled-opacity: 0.5;
$btn-transition: color .05s ease-in-out, background-color .05s ease-in-out, border-color .05s ease-in-out, box-shadow .05s ease-in-out;
$card-spacer-y: 0rem;
$card-spacer-x: 0rem;
$card-border-radius: $border-radius;
$card-border-color: $border-color;
$card-cap-bg: $color-bg-theme;
$card-bg: $color-bg-theme;
$navbar-brand-padding-y: 0rem;
$nav-tabs-border-color: $border-color;
$nav-tabs-border-width: 1px;
$nav-tabs-border-radius: 0px;
$nav-tabs-link-hover-border-color: none;
$nav-tabs-link-active-color: $color-primary;
$nav-tabs-link-active-bg: none;
$nav-tabs-link-active-border-color: none;
$table-cell-padding: 0.25rem;
$table-hover-bg: none; //we will use our own classes
$table-active-bg: $color-primary-light;
$table-border-width: $border-width !default;
$table-border-color: $border-color !default;
$table-head-bg: $color-primary !default;
$table-head-color: $color-primary-fg !default;
$input-bg: $white; //no change
$input-color: $color-fg-theme;
$input-border-color: $border-color;
$input-border-radius: $border-radius; //no change
$input-disabled-bg: $color-gray-lighter;
$input-btn-border-width: $border-width; //no change
$input-border-width: $input-btn-border-width; //no change
$input-btn-padding-y: .375rem; //no change
$input-btn-padding-x: .75rem; //no change
$btn-border-radius: $border-radius; //no change
/***************/
$active-border: 3px solid $color-primary;
$panel-border-width: $border-width;
$panel-border-color: $border-color;
$panel-border-radius: $border-radius;
$panel-border: $panel-border-width solid $panel-border-color !important;
$panel-border-dark: $panel-border-width solid $border-color-dark !important;
$tabs-padding: 5px 10px 2px;
$title-height: 37px * $font-size-base/1rem;
$footer-padding: 0.5rem;
$footer-min-height: 2.18rem;
$footer-height-calc: $footer-min-height+$footer-padding*2;
$navbar-font-size: 0.875rem;
$navbar-user-font-size: 0.815rem;
$navbar-dropdown-top: 100%;
$dropdown-submenu-top: -$dropdown-spacer;
$table-bg: $color-bg-theme;
$table-bg-selected: $color-primary-light;
$table-hover-border-color: #4fc2f8;
$table-hover-border: $panel-border-width solid #4fc2f8 !important;
$table-hover-bg-color: $color-primary-light;
$datagrid-bg: $color-gray-light;
$sql-title-padding: 3px;
$sql-title-bg: $color-gray-darker;
$sql-title-fg: $white;
$sql-gutters-bg: $color-gray-light;
$sql-history-detail-bg: $color-gray-lighter;
$sql-history-success-bg: $color-primary-light;
$sql-history-success-fg: $color-primary;
$sql-history-error-bg: $color-danger-light;
$sql-history-error-fg: $color-danger;
$negative-bg: $color-gray-light;
$dialog-box-shadow: $box-shadow;
$alert-icon-color: $white;
$alertify-borderremove-margin: $panel-border-width;
$btn-secondary-border: $color-gray;
$btn-secondary-hover-bg: $color-gray-light;
$card-header-padding : 0.25rem 0.5rem;
$no-border-radius: 0px !important;
$btn-checkbox-padding: 0.3rem 0.8rem;
$security-text-color: $white;
$security-btn-color: #038bba;
$loading-bg : rgba($black,0.6);
$loading-fg : $white;
$loader-icon : url("data:image/svg+xml;charset=UTF-8,%3c?xml version='1.0' encoding='utf-8'?%3e%3csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 38 38' style='enable-background:new 0 0 38 38;' xml:space='preserve'%3e%3cstyle type='text/css'%3e .st0%7bfill:none;stroke:%23ebeef3;stroke-width:2;%7d .st1%7bfill:none;stroke:%23326690;stroke-width:2;%7d %3c/style%3e%3cg%3e%3cg transform='translate(1 1)'%3e%3ccircle class='st0' cx='18' cy='18' r='18'/%3e%3cpath class='st1' d='M36,18c0-9.9-8.1-18-18-18 '%3e%3canimateTransform accumulate='none' additive='replace' attributeName='transform' calcMode='linear' dur='0.7s' fill='remove' from='0 18 18' repeatCount='indefinite' restart='always' to='360 18 18' type='rotate'%3e%3c/animateTransform%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/svg%3e ");

View File

@@ -0,0 +1,645 @@
/*
Backform
http://github.com/amiliaapp/backform
Copyright (c) 2014 Amilia Inc.
Written by Martin Drapeau
Licensed under the MIT @license
*/
(function(root, factory) {
// Set up Backform appropriately for the environment. Start with AMD.
if (typeof define === 'function' && define.amd) {
define(['underscore', 'jquery', 'backbone'], function(_, $, Backbone) {
// Export global even in AMD case in case this script is loaded with
// others that may still expect a global Backform.
return factory(root, _, $, Backbone);
});
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
} else if (typeof exports !== 'undefined') {
var _ = require('underscore');
factory(root, _, (root.jQuery || root.$ || root.Zepto || root.ender), root.Backbone);
// Finally, as a browser global.
} else {
factory(root, root._, (root.jQuery || root.Zepto || root.ender || root.$), root.Backbone);
}
} (this, function(root, _, $, Backbone) {
// Backform namespace and global options
Backform = root.Backform = {
// HTML markup global class names. More can be added by individual controls
// using _.extend. Look at RadioControl as an example.
formClassName: "backform form-inline",
groupClassName: "form-group row",
controlLabelClassName: "col-sm-2 col-form-label",
controlContainerClassName: "col-sm-10",
controlsClassName: "col-sm-8",
controlClassName: "form-control",
controlFormInlineClassName: "form-inline",
helpClassName: "form-text",
errorClassName: "has-error",
helpMessageClassName: "form-text text-muted",
hiddenClassName: "d-none",
requiredInputClassName: undefined,
// https://github.com/wyuenho/backgrid/blob/master/lib/backgrid.js
resolveNameToClass: function(name, suffix) {
if (_.isString(name)) {
var key = _.map(name.split('-'), function(e) {
return e.slice(0, 1).toUpperCase() + e.slice(1);
}).join('') + suffix;
var klass = Backform[key];
if (_.isUndefined(klass)) {
throw new ReferenceError("Class '" + key + "' not found");
}
return klass;
}
return name;
}
};
// Backform Form view
// A collection of field models.
var Form = Backform.Form = Backbone.View.extend({
fields: undefined,
errorModel: undefined,
tagName: "form",
className: function() {
return Backform.formClassName;
},
initialize: function(options) {
if (!(options.fields instanceof Backbone.Collection))
options.fields = new Fields(options.fields || this.fields);
this.fields = options.fields;
this.model.errorModel = options.errorModel || this.model.errorModel || new Backbone.Model();
this.controls = [];
},
cleanup: function() {
_.each(this.controls, function(c) {
c.remove();
});
this.controls.length = 0;
},
remove: function() {
/* First do the clean up */
this.cleanup();
Backbone.View.prototype.remove.apply(this, arguments);
},
render: function() {
this.cleanup();
this.$el.empty();
var form = this,
$form = this.$el,
model = this.model,
controls = this.controls;
this.fields.each(function(field) {
var control = new (field.get("control"))({
field: field,
model: model
});
$form.append(control.render().$el);
controls.push(control);
});
return this;
}
});
// Converting data to/from Model/DOM.
// Stolen directly from Backgrid's CellFormatter.
// Source: http://backgridjs.com/ref/formatter.html
/**
Just a convenient class for interested parties to subclass.
The default Cell classes don't require the formatter to be a subclass of
Formatter as long as the fromRaw(rawData) and toRaw(formattedData) methods
are defined.
@abstract
@class Backform.ControlFormatter
@constructor
*/
var ControlFormatter = Backform.ControlFormatter = function() {};
_.extend(ControlFormatter.prototype, {
/**
Takes a raw value from a model and returns an optionally formatted string
for display. The default implementation simply returns the supplied value
as is without any type conversion.
@member Backform.ControlFormatter
@param {*} rawData
@param {Backbone.Model} model Used for more complicated formatting
@return {*}
*/
fromRaw: function (rawData, model) {
return rawData;
},
/**
Takes a formatted string, usually from user input, and returns a
appropriately typed value for persistence in the model.
If the user input is invalid or unable to be converted to a raw value
suitable for persistence in the model, toRaw must return `undefined`.
@member Backform.ControlFormatter
@param {string} formattedData
@param {Backbone.Model} model Used for more complicated formatting
@return {*|undefined}
*/
toRaw: function (formattedData, model) {
return formattedData;
}
});
// Store value in DOM as stringified JSON.
var JSONFormatter = Backform.JSONFormatter = function() {};
_.extend(JSONFormatter.prototype, {
fromRaw: function(rawData, model) {
return JSON.stringify(rawData);
},
toRaw: function(formattedData, model) {
return JSON.parse(formattedData);
}
});
// Field model and collection
//
// A field maps a model attriute to a control for rendering and capturing
// user input.
var Field = Backform.Field = Backbone.Model.extend({
defaults: {
// Name of the model attribute
// - It accepts "." nested path (e.g. x.y.z)
name: "",
// Placeholder for the input
placeholder: "",
// Disable the input control
// (Optional - true/false/function returning boolean)
// (Default Value: false)
disabled: false,
// Visible
// (Optional - true/false/function returning boolean)
// (Default Value: true)
visible: true,
// Value Required (validation)
// (Optional - true/false/function returning boolean)
// (Default Value: true)
required: false,
// Default value for the field
// (Optional)
value: undefined,
// Control or class name for the control representing this field
control: undefined,
formatter: undefined
},
initialize: function(attributes, options) {
var control = Backform.resolveNameToClass(this.get("control"), "Control");
this.set({control: control}, {silent: true});
}
});
var Fields = Backform.Fields = Backbone.Collection.extend({
model: Field
});
// Base Control class
var Control = Backform.Control = Backbone.View.extend({
// Additional field defaults
defaults: {},
className: function() {
return Backform.groupClassName;
},
events: {
'keydown :input': 'processTab'
},
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<div class="<%=Backform.controlContainerClassName%>">',
' <span readonly class="<%=Backform.controlClassName%>" value="<%=value%>">',
'</div>'
].join("\n")),
initialize: function(options) {
// Back-reference to the field
this.field = options.field;
var formatter = Backform.resolveNameToClass(this.field.get("formatter") || this.formatter, "Formatter");
if (!_.isFunction(formatter.fromRaw) && !_.isFunction(formatter.toRaw)) {
formatter = new formatter();
}
this.formatter = formatter;
var attrArr = this.field.get('name').split('.');
var name = attrArr.shift();
// Listen to the field in the model for any change
this.listenTo(this.model, "change:" + name, this.render);
// Listen for the field in the error model for any change
if (this.model.errorModel instanceof Backbone.Model)
this.listenTo(this.model.errorModel, "change:" + name, this.updateInvalid);
},
formatter: ControlFormatter,
getValueFromDOM: function() {
return this.formatter.toRaw(this.$el.find(".uneditable-input").text(), this.model);
},
onChange: function(e) {
var model = this.model,
$el = $(e.target),
attrArr = this.field.get("name").split('.'),
name = attrArr.shift(),
path = attrArr.join('.'),
value = this.getValueFromDOM(),
changes = {};
if (this.model.errorModel instanceof Backbone.Model) {
if (_.isEmpty(path)) {
this.model.errorModel.unset(name);
} else {
var nestedError = this.model.errorModel.get(name);
if (nestedError) {
this.keyPathSetter(nestedError, path, null);
this.model.errorModel.set(name, nestedError);
}
}
}
changes[name] = _.isEmpty(path) ? value : _.clone(model.get(name)) || {};
if (!_.isEmpty(path)) this.keyPathSetter(changes[name], path, value);
this.stopListening(this.model, "change:" + name, this.render);
model.set(changes);
this.listenTo(this.model, "change:" + name, this.render);
},
render: function() {
var field = _.defaults(this.field.toJSON(), this.defaults),
attributes = this.model.toJSON(),
attrArr = field.name.split('.'),
name = attrArr.shift(),
path = attrArr.join('.'),
rawValue = this.keyPathAccessor(attributes[name], path),
data = _.extend(field, {
rawValue: rawValue,
value: this.formatter.fromRaw(rawValue, this.model),
attributes: attributes,
formatter: this.formatter
}),
evalF = function(f, m) {
return (_.isFunction(f) ? !!f(m) : !!f);
};
// Evaluate the disabled, visible, and required option
_.extend(data, {
disabled: evalF(data.disabled, this.model),
visible: evalF(data.visible, this.model),
required: evalF(data.required, this.model)
});
// Clean up first
this.$el.removeClass(Backform.hiddenClassName);
if (!data.visible)
this.$el.addClass(Backform.hiddenClassName);
if(Backform.requiredInputClassName) {
this.$el.removeClass(Backform.requiredInputClassName);
}
if (data.required) {
this.$el.addClass(Backform.requiredInputClassName);
}
this.$el.html(this.template(data)).addClass(field.name);
this.updateInvalid();
return this;
},
clearInvalid: function() {
this.$el.removeClass(Backform.errorClassName)
.find("." + Backform.helpClassName + ".error").remove();
return this;
},
updateInvalid: function() {
var self = this;
var errorModel = this.model.errorModel;
if (!(errorModel instanceof Backbone.Model)) return this;
this.clearInvalid();
this.$el.find(':input').not('button').each(function(ix, el) {
var attrArr = $(el).attr('name').split('.'),
name = attrArr.shift(),
path = attrArr.join('.'),
error = self.keyPathAccessor(errorModel.toJSON(), $(el).attr('name'));
if (_.isEmpty(error)) return;
self.$el.addClass(Backform.errorClassName);
if (ix === 0) {
self.$el
.find("." + Backform.controlsClassName)
.append('<span class="' + Backform.helpClassName + ' error">' + (_.isArray(error) ? error.join(", ") : error) + '</span>');
}
});
return this;
},
keyPathAccessor: function(obj, path) {
var res = obj;
path = path.split('.');
for (var i = 0; i < path.length; i++) {
if (_.isNull(res)) return null;
if (_.isEmpty(path[i])) continue;
if (!_.isUndefined(res[path[i]])) res = res[path[i]];
}
return _.isObject(res) && !_.isArray(res) ? null : res;
},
keyPathSetter: function(obj, path, value) {
path = path.split('.');
while (path.length > 1) {
if (!obj[path[0]]) obj[path[0]] = {};
obj = obj[path.shift()];
}
return obj[path.shift()] = value;
},
processTab: function(e) {
if (e.which == 9) {
var $target = $(e.currentTarget);
setTimeout(function() {
var $nextFocus;
if (e.shiftKey) {
$nextFocus = !!$target.prevAll(':input:visible').length ?
$target.prevAll(':input:visible').first() :
$target.closest('.control-group:visible').prev('.control-group:visible').find(':input:visible');
} else {
$nextFocus = !!$target.nextAll(':input:visible').length ?
$target.nextAll(':input:visible').first() :
$target.closest('.control-group:visible').next('.control-group:visible').find(':input:visible');
}
if ($nextFocus.length) $nextFocus.first().focus();
}, 0);
}
}
});
// Built-in controls
var UneditableInputControl = Backform.UneditableInputControl = Control;
var HelpControl = Backform.HelpControl = Control.extend({
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>">&nbsp;</label>',
'<div class="<%=Backform.controlsClassName%>">',
' <span class="<%=Backform.helpMessageClassName%> help-block"><%=label%></span>',
'</div>'
].join("\n"))
});
var SpacerControl = Backform.SpacerControl = Control.extend({
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>">&nbsp;</label>',
'<div class="<%=Backform.controlsClassName%>"></div>'
].join("\n"))
});
var TextareaControl = Backform.TextareaControl = Control.extend({
defaults: {
label: "",
maxlength: 4000,
extraClasses: [],
helpMessage: null
},
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<div class="<%=Backform.controlContainerClassName%>">',
' <textarea class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>" name="<%=name%>" maxlength="<%=maxlength%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%>><%-value%></textarea>',
' <% if (helpMessage && helpMessage.length) { %>',
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
' <% } %>',
'</div>'
].join("\n")),
events: _.extend({}, Control.prototype.events, {
"change textarea": "onChange",
"focus textarea": "clearInvalid"
}),
getValueFromDOM: function() {
return this.formatter.toRaw(this.$el.find("textarea").val(), this.model);
}
});
var SelectControl = Backform.SelectControl = Control.extend({
defaults: {
label: "",
options: [], // List of options as [{label:<label>, value:<value>}, ...]
extraClasses: []
},
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<div class="<%=Backform.controlContainerClassName%>">',
' <select class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>" name="<%=name%>" value="<%-value%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> >',
' <% for (var i=0; i < options.length; i++) { %>',
' <% var option = options[i]; %>',
' <option value="<%-formatter.fromRaw(option.value)%>" <%=option.value === rawValue ? "selected=\'selected\'" : ""%> <%=option.disabled ? "disabled=\'disabled\'" : ""%>><%-option.label%></option>',
' <% } %>',
' </select>',
'</div>'
].join("\n")),
events: _.extend({}, Control.prototype.events, {
"change select": "onChange",
"focus select": "clearInvalid"
}),
formatter: JSONFormatter,
getValueFromDOM: function() {
return this.formatter.toRaw(this.$el.find("select").val(), this.model);
}
});
// Note: Value here is null or an array. Since jQuery val() returns either.
var MultiSelectControl = Backform.MultiSelectControl = SelectControl.extend({
defaults: {
label: "",
options: [], // List of options as [{label:<label>, value:<value>}, ...]
extraClasses: [],
height: '78px'
},
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<div class="<%=Backform.controlsClassName%>">',
' <select multiple="multiple" class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>" name="<%=name%>" value="<%-JSON.stringify(value)%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> style="height:<%=height%>">',
' <% for (var i=0; i < options.length; i++) { %>',
' <% var option = options[i]; %>',
' <option value="<%-option.value%>" <%=value != null && _.indexOf(value, option.value) != -1 ? "selected=\'selected\'" : ""%> <%=option.disabled ? "disabled=\'disabled\'" : ""%>><%-option.label%></option>',
' <% } %>',
' </select>',
'</div>'
].join("\n")),
events: _.extend({}, Control.prototype.events, {
"change select": "onChange",
"dblclick select": "onDoubleClick",
"focus select": "clearInvalid"
}),
formatter: {
fromRaw: function(rawData, model) {
return rawData;
},
toRaw: function(formattedData, model) {
return typeof formattedData == "object" ? formattedData : JSON.parse(formattedData);
}
},
onDoubleClick: function(e) {
this.model.trigger('doubleclick', e);
}
});
var InputControl = Backform.InputControl = Control.extend({
defaults: {
type: "text",
label: "",
maxlength: 255,
extraClasses: [],
helpMessage: null,
},
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<div class="<%=Backform.controlContainerClassName%>">',
' <input type="<%=type%>" class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>" name="<%=name%>" maxlength="<%=maxlength%>" value="<%-value%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> />',
' <% if (helpMessage && helpMessage.length) { %>',
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
' <% } %>',
'</div>'
].join("\n")),
events: _.extend({}, Control.prototype.events, {
"change input": "onChange",
"focus input": "clearInvalid"
}),
getValueFromDOM: function() {
return this.formatter.toRaw(this.$el.find("input").val(), this.model);
}
});
var BooleanControl = Backform.BooleanControl = InputControl.extend({
defaults: {
type: "checkbox",
label: "",
controlLabel: '&nbsp;',
extraClasses: [],
id: _.uniqueId('bf_')
},
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=controlLabel%></label>',
'<div class="<%=Backform.controlContainerClassName%>">',
' <div class="form-check">',
' <input type="<%=type%>" class="form-check-input <%=extraClasses.join(\' \')%>" id="<%=id%>" name="<%=name%>" <%=value ? "checked=\'checked\'" : ""%> <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> />',
' <label class="form-check-label" for="<%=id%>"><%=label%></label>',
' </div>',
'</div>'
].join("\n")),
getValueFromDOM: function() {
return this.formatter.toRaw(this.$el.find("input").is(":checked"), this.model);
}
});
var CheckboxControl = Backform.CheckboxControl = BooleanControl;
var RadioControl = Backform.RadioControl = InputControl.extend({
defaults: {
type: "radio",
label: "",
options: [],
extraClasses: [],
helpMessage: null
},
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
'<div class="<%=Backform.controlContainerClassName%> form-check-inline">',
' <% for (var i=0; i < options.length; i++) { %>',
' <% var option = options[i]; %>',
' <% var id = _.uniqueId("bf_"); %>',
' <div class="form-check">',
' <input type="<%=type%>" class="<%=extraClasses.join(\' \')%>" id="<%=id%>" name="<%=name%>" value="<%-formatter.fromRaw(option.value)%>" <%=rawValue == option.value ? "checked=\'checked\'" : ""%> <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> />',
' <label class="form-check-label" for="<%=id%>"><%-option.label%></label>',
' </div>',
' <% } %>',
' <% if (helpMessage && helpMessage.length) { %>',
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
' <% } %>',
'</div>'
].join("\n")),
formatter: JSONFormatter,
getValueFromDOM: function() {
return this.formatter.toRaw(this.$el.find("input:checked").val(), this.model);
},
bootstrap2: function() {
Backform.radioControlsClassName = "controls";
Backform.radioLabelClassName = "radio inline";
}
});
_.extend(Backform, {
radioControlsClassName: "checkbox",
radioLabelClassName: "checkbox-inline"
});
// Requires the Bootstrap Datepicker to work.
var DatepickerControl = Backform.DatepickerControl = InputControl.extend({
defaults: {
type: "text",
label: "",
options: {},
extraClasses: [],
maxlength: 255,
helpMessage: null
},
events: _.extend({}, Control.prototype.events, {
"blur input": "onChange",
"change input": "onChange",
"changeDate input": "onChange",
"focus input": "clearInvalid"
}),
render: function() {
InputControl.prototype.render.apply(this, arguments);
this.$el.find("input").datepicker(this.field.get("options"));
return this;
}
});
var ButtonControl = Backform.ButtonControl = Control.extend({
defaults: {
type: "submit",
label: "Submit",
status: undefined, // error or success
message: undefined,
extraClasses: []
},
template: _.template([
'<label class="<%=Backform.controlLabelClassName%>">&nbsp;</label>',
'<div class="<%=Backform.controlsClassName%>">',
' <button type="<%=type%>" name="<%=name%>" class="btn <%=extraClasses.join(\' \')%>" <%=disabled ? "disabled" : ""%> ><%=label%></button>',
' <% var cls = ""; if (status == "error") cls = Backform.buttonStatusErrorClassName; if (status == "success") cls = Backform.buttonStatusSuccessClassname; %>',
' <span class="status <%=cls%>"><%=message%></span>',
'</div>'
].join("\n")),
initialize: function() {
Control.prototype.initialize.apply(this, arguments);
this.listenTo(this.field, "change:status", this.render);
this.listenTo(this.field, "change:message", this.render);
},
bootstrap2: function() {
Backform.buttonStatusErrorClassName = "text-error";
Backform.buttonStatusSuccessClassname = "text-success";
}
});
_.extend(Backform, {
buttonStatusErrorClassName: "text-danger",
buttonStatusSuccessClassname: "text-success"
});
return Backform;
}));

View File

@@ -1,16 +1,29 @@
{% extends "security/panel.html" %}
{% block panel_title %}{{ _('%(appname)s Password Change', appname=config.APP_NAME) }}{% endblock %}
{% block panel_body %}
{% if config.SERVER_MODE %}
<form action="{{ url_for('browser.change_password') }}" method="POST" name="change_password_form">
{% extends "base.html" %}
{% from "security/fields.html" import render_field_with_errors %}
{% block body %}
<div class="container-fluid change_pass">
{% include "security/messages.html" %}
<div class="row align-items-center h-100">
<div class="col-md-4"></div>
<div class="col-md-4">
<div class="panel-header h4"><i class="app-icon pg-icon-blue"></i> {{ _('%(appname)s', appname=config.APP_NAME) }}</div>
<div class="panel-body">
<div class="d-block text-color pb-3 h5">{{ _('Password Change', appname=config.APP_NAME) }}</div>
{% if config.SERVER_MODE %}
<form action="{{ url_for('browser.change_password') }}" method="POST" name="change_password_form">
{{ change_password_form.hidden_tag() }}
<fieldset>
{{ render_field_with_errors(change_password_form.password, "password") }}
{{ render_field_with_errors(change_password_form.new_password, "password") }}
{{ render_field_with_errors(change_password_form.new_password_confirm, "password") }}
<input class="btn btn-lg btn-primary btn-block" type="submit" value="{{ _('Change Password') }}"
<input class="btn btn-primary btn-block btn-change-pass" type="submit" value="{{ _('Change Password') }}"
title="{{ _('Change Password') }}">
</fieldset>
</form>
{% endif %}
</form>
{% endif %}
</div>
</div>
<div class="col-md-4"></div>
</div>
</div>
{% endblock %}

View File

@@ -1,5 +1,10 @@
{% extends "security/panel.html" %}
{% block panel_title %}{{ _('Recover %(appname)s Password', appname=config.APP_NAME) }}{% endblock %}
{% block panel_image %}
<div class="p-5">
<img src="{{ url_for('static', filename='img/forgot_password.svg') }}" alt="{{ _('Forgot Password') }}">
</div>
{% endblock %}
{% block panel_title %}{{ _('Recover Password', appname=config.APP_NAME) }}{% endblock %}
{% block panel_body %}
{% if config.SERVER_MODE %}
<p>{{ _('Enter the email address for the user account you wish to recover the password for:') }}</p>
@@ -7,7 +12,7 @@
{{ forgot_password_form.hidden_tag() }}
<fieldset>
{{ render_field_with_errors(forgot_password_form.email, "text") }}
<input class="btn btn-lg btn-primary btn-block" type="submit" value="{{ _('Recover Password') }}"
<input class="btn btn-primary btn-block btn-login" type="submit" value="{{ _('Recover Password') }}"
title="{{ _('Recover Password') }}">
</fieldset>
</form>

View File

@@ -1,5 +1,10 @@
{% extends "security/panel.html" %}
{% block panel_title %}{{ _('%(appname)s Login', appname=config.APP_NAME) }}{% endblock %}
{% block panel_image %}
<div class="pr-4">
<img src="{{ url_for('static', filename='img/login.svg') }}" alt="{{ _('Login') }}">
</div>
{% endblock %}
{% block panel_title %}{{ _('Login') }}{% endblock %}
{% block panel_body %}
{% if config.SERVER_MODE %}
<form action="{{ url_for_security('login') }}" method="POST" name="login_user_form">
@@ -7,10 +12,10 @@
{% set user_language = request.cookies.get('PGADMIN_LANGUAGE') or 'en' %}
{{ render_field_with_errors(login_user_form.email, "text") }}
{{ render_field_with_errors(login_user_form.password, "password") }}
<button class="btn btn-lg btn-primary btn-block" type="submit" value="{{ _('Login') }}">{{ _('Login') }}</button>
<button class="btn btn-primary btn-block btn-login" type="submit" value="{{ _('Login') }}">{{ _('Login') }}</button>
<div class="form-group row mb-3 c user-language">
<label class="help-block col-sm-3">{{ _("Language") }}</label>
<div class="col-sm-9">
<div class="col-8"><span class="help-block">{{ _('<a href="%(url)s" class="text-white">Forgotten your password</a>?', url=url_for('browser.forgot_password')) }}</span></div>
<div class="col-4">
<select class="form-control" name="language" value="{{user_language}}">
{% for key, lang in config.LANGUAGES.items() %}
<option value="{{key}}" {% if user_language == key %}selected{% endif %}>{{lang}}</option>
@@ -19,8 +24,5 @@
</div>
</div>
</form>
<div>
<span class="help-block">{{ _('Forgotten your <a href="%(url)s">password</a>?', url=url_for('browser.forgot_password')) }}</span>
</div>
{% endif %}
{% endblock %}

View File

@@ -1,23 +1,18 @@
{% extends "base.html" %}
{% from "security/fields.html" import render_field_with_errors %}
{% block body %}
<div class="container-fluid" style="position:relative;z-index:1;">
<div class="container-fluid h-100 login_page">
{% include "security/messages.html" %}
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-4">
<div class="card">
<div class="card-header bg-primary text-white">
<span class="panel-title h5">{% block panel_title %}{% endblock %}</span>
</div>
<div class="card-body">
<div class="row h-100 align-items-center justify-content-center">
<div class="col-md-6">{% block panel_image %}{% endblock %}</div>
<div class="col-md-3">
<div class="panel-header text-color h4"><i class="app-icon pg-icon"></i> {{ _('%(appname)s', appname=config.APP_NAME) }}</div>
<div class="panel-body">
<div class="d-block text-color pb-3 h5">{% block panel_title %}{% endblock %}</div>
{% block panel_body %}
{% endblock %}
</div>
</div>
</div>
<div class="col-md-4"></div>
</div>
</div>
{% include 'security/watermark.html' %}
{% endblock %}

View File

@@ -194,11 +194,11 @@ class BackupMessage(IProcessDesc):
# It should never reach here.
res += "Backup"
res += '</div><div>'
res += '</div><div class="py-1">'
res += _("Running command:")
res += '</b><br><span class="pg-bg-cmd enable-selection">'
res += '<div class="pg-bg-cmd enable-selection p-1">'
res += html.safe_str(cmd + self.cmd)
res += '</span></div>'
res += '</div></div>'
return res

Some files were not shown because too many files have changed in this diff Show More