diff --git a/web/package.json b/web/package.json
index 693ff843e..ea65bf9d4 100644
--- a/web/package.json
+++ b/web/package.json
@@ -86,8 +86,6 @@
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "4.0.0-alpha.58",
"@material-ui/pickers": "^3.2.10",
- "@mui/icons-material": "^5.4.2",
- "@mui/material": "^5.4.3",
"@projectstorm/react-diagrams": "^6.6.1",
"@simonwep/pickr": "^1.5.1",
"@szhsin/react-menu": "^2.2.0",
diff --git a/web/pgadmin/browser/collection.py b/web/pgadmin/browser/collection.py
index 6040cf651..aff57fcba 100644
--- a/web/pgadmin/browser/collection.py
+++ b/web/pgadmin/browser/collection.py
@@ -236,6 +236,16 @@ class CollectionNodeModule(PgAdminModule, PGChildModule):
else:
return False
+ @property
+ def show_user_defined_database_template(self):
+ """
+ Show/Hide the user defined template in the database server.
+ """
+ if self.pref_show_user_defined_templates:
+ return self.pref_show_user_defined_templates.get()
+ else:
+ return False
+
def register_preferences(self):
"""
register_preferences
@@ -251,6 +261,8 @@ class CollectionNodeModule(PgAdminModule, PGChildModule):
self.pref_show_system_objects = self.browser_preference.preference(
'show_system_objects'
)
+ self.pref_show_user_defined_templates = \
+ self.browser_preference.preference('show_user_defined_templates')
self.pref_show_node = self.browser_preference.register(
'node', 'show_node_' + self.node_type,
self.collection_label, 'node', self.SHOW_ON_BROWSER,
diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py
index 5d3482be4..cb419f9c3 100644
--- a/web/pgadmin/browser/register_browser_preferences.py
+++ b/web/pgadmin/browser/register_browser_preferences.py
@@ -27,6 +27,13 @@ def register_browser_preferences(self):
gettext("Show system objects?"), 'boolean', False,
category_label=PREF_LABEL_DISPLAY
)
+
+ self.show_user_defined_templates = self.preference.register(
+ 'display', 'show_user_defined_templates',
+ gettext("Show user defined templates?"), 'boolean', False,
+ category_label=PREF_LABEL_DISPLAY
+ )
+
if config.SERVER_MODE:
self.hide_shared_server = self.preference.register(
'display', 'hide_shared_server',
diff --git a/web/pgadmin/browser/server_groups/servers/databases/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/__init__.py
index 292d88d17..1552ff25d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/__init__.py
@@ -230,21 +230,29 @@ class DatabaseView(PGChildNodeView):
conn=self.conn,
last_system_oid=last_system_oid,
db_restrictions=db_disp_res,
- show_system_objects=self.blueprint.show_system_objects,
)
status, res = self.conn.execute_dict(SQL, params)
if not status:
return internal_server_error(errormsg=res)
+ result_set = []
for row in res['rows']:
+ row['is_sys_obj'] = (
+ row['did'] <= self._DATABASE_LAST_SYSTEM_OID or
+ self.datistemplate)
+ if self.skip_db(row):
+ continue
+
if self.manager.db == row['name']:
row['canDrop'] = False
else:
row['canDrop'] = True
+ result_set.append(row)
+
return ajax_response(
- response=res['rows'],
+ response=result_set,
status=200
)
@@ -256,6 +264,32 @@ class DatabaseView(PGChildNodeView):
return last_system_oid
+ def get_icon(self, res, connected):
+ if not connected and not res['is_template']:
+ icon = "icon-database-not-connected"
+ elif not connected and res['is_template']:
+ icon = 'icon-database-template-not-connected'
+ elif connected and res['is_template']:
+ icon = 'icon-database-template-connected'
+ else:
+ icon = "pg-icon-database"
+
+ return icon
+
+ def skip_db(self, row):
+
+ if not self.blueprint.show_system_objects \
+ and row['is_sys_obj'] \
+ and row['name'] not in ('postgres', 'edb'):
+ return True
+
+ if not self.blueprint.show_user_defined_database_template \
+ and row['is_template'] and \
+ not row['is_sys_obj'] and \
+ row['name'] not in ('postgres', 'edb'):
+ return True
+ return False
+
def get_nodes(self, gid, sid, is_schema_diff=False):
res = []
last_system_oid = self.retrieve_last_system_oid()
@@ -278,7 +312,6 @@ class DatabaseView(PGChildNodeView):
"/".join([self.template_path, self._NODES_SQL]),
last_system_oid=last_system_oid,
db_restrictions=db_disp_res,
- show_system_objects=self.blueprint.show_system_objects,
)
status, rset = self.conn.execute_dict(SQL, params)
@@ -287,6 +320,12 @@ class DatabaseView(PGChildNodeView):
for row in rset['rows']:
dbname = row['name']
+ row['is_sys_obj'] = (
+ row['did'] <= self._DATABASE_LAST_SYSTEM_OID or
+ self.datistemplate)
+
+ if self.skip_db(row):
+ continue
if self.manager.db == dbname:
connected = True
can_drop = can_dis_conn = False
@@ -295,19 +334,21 @@ class DatabaseView(PGChildNodeView):
connected = conn.connected()
can_drop = can_dis_conn = True
+ icon = self.get_icon(row, connected)
+
res.append(
self.blueprint.generate_browser_node(
row['did'],
sid,
row['name'],
- icon="icon-database-not-connected" if not connected
- else "pg-icon-database",
+ icon=icon,
connected=connected,
tablespace=row['spcname'],
allowConn=row['datallowconn'],
canCreate=row['cancreate'],
canDisconn=can_dis_conn,
canDrop=can_drop,
+ isTemplate=row['is_template'],
inode=True if row['datallowconn'] else False
)
)
@@ -429,8 +470,7 @@ class DatabaseView(PGChildNodeView):
result = res['rows'][0]
result['is_sys_obj'] = (
- result['oid'] <= self._DATABASE_LAST_SYSTEM_OID or
- self.datistemplate)
+ result['oid'] <= self._DATABASE_LAST_SYSTEM_OID)
# Fetching variable for database
SQL = render_template(
"/".join([self.template_path, 'get_variables.sql']),
@@ -650,7 +690,8 @@ class DatabaseView(PGChildNodeView):
allowConn=True,
canCreate=response['cancreate'],
canDisconn=True,
- canDrop=True
+ canDrop=True,
+ isTemplate=response['is_template']
)
)
@@ -829,14 +870,16 @@ class DatabaseView(PGChildNodeView):
can_drop = can_dis_conn = is_can_drop
+ icon = self.get_icon(res,
+ self.conn.connected()
+ if self._db['datallowconn'] else False)
+
return jsonify(
node=self.blueprint.generate_browser_node(
did,
sid,
res['name'],
- icon="pg-icon-{0}".format(self.node_type) if
- self._db['datallowconn'] and self.conn.connected() else
- "icon-database-not-connected",
+ icon=icon,
connected=self.conn.connected() if
self._db['datallowconn'] else False,
tablespace=res['spcname'],
@@ -844,7 +887,8 @@ class DatabaseView(PGChildNodeView):
canCreate=res['cancreate'],
canDisconn=can_dis_conn,
canDrop=can_drop,
- inode=True if res['datallowconn'] else False
+ inode=True if res['datallowconn'] else False,
+ isTemplate=res['is_template'],
)
)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/img/template_database.svg b/web/pgadmin/browser/server_groups/servers/databases/static/img/template_database.svg
new file mode 100644
index 000000000..998c073a4
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/static/img/template_database.svg
@@ -0,0 +1,8 @@
+
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/img/template_database_bad.svg b/web/pgadmin/browser/server_groups/servers/databases/static/img/template_database_bad.svg
new file mode 100644
index 000000000..5bc006a2a
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/static/img/template_database_bad.svg
@@ -0,0 +1,10 @@
+
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
index 4f3e63329..df7656296 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
@@ -187,7 +187,8 @@ define('pgadmin.node.database', [
d.is_connecting = false;
t.unload(i);
t.setInode(i);
- t.addIcon(i, {icon: 'icon-database-not-connected'});
+ var dbIcon = d.isTemplate ? 'icon-database-template-not-connected':'icon-database-not-connected';
+ t.addIcon(i, {icon: dbIcon});
pgBrowser.Events.trigger(
'pgadmin:database:connect:cancelled', i, d, self
);
@@ -237,7 +238,8 @@ define('pgadmin.node.database', [
Notify.success(_.unescape(res.info));
t.removeIcon(i);
data.connected = false;
- data.icon = 'icon-database-not-connected';
+ data.icon = data.isTemplate ? 'icon-database-template-not-connected':'icon-database-not-connected';
+
t.addIcon(i, {icon: data.icon});
t.unload(i);
pgBrowser.Events.trigger('pgadmin:browser:tree:update-tree-state', i);
@@ -294,7 +296,6 @@ define('pgadmin.node.database', [
if(!data || data._type != 'database') {
return false;
}
-
pgBrowser.tree.addIcon(item, {icon: data.icon});
if (!data.connected && data.allowConn && !data.is_connecting) {
data.is_connecting = true;
@@ -386,14 +387,16 @@ define('pgadmin.node.database', [
},
function(fun_error) {
tree.setInode(_item);
- tree.addIcon(_item, {icon: 'icon-database-not-connected'});
+ var dbIcon = data.isTemplate ? 'icon-database-template-not-connected':'icon-database-not-connected';
+ tree.addIcon(_item, {icon: dbIcon});
Notify.pgNotifier(fun_error, xhr, gettext('Connect to database.'));
}
);
} else {
if (!_status) {
tree.setInode(_item);
- tree.addIcon(_item, {icon: 'icon-database-not-connected'});
+ var dbIcon = data.isTemplate ? 'icon-database-template-not-connected':'icon-database-not-connected';
+ tree.addIcon(_item, {icon: dbIcon});
}
Notify.pgNotifier('error', xhr, error, function(msg) {
@@ -422,7 +425,8 @@ define('pgadmin.node.database', [
if (typeof res.data.icon == 'string') {
_tree.removeIcon(_item);
_data.icon = res.data.icon;
- _tree.addIcon(_item, {icon: _data.icon});
+ var dbIcon = _data.isTemplate ? 'icon-database-template-connected':_data.icon;
+ _tree.addIcon(_item, {icon: dbIcon});
}
if(res.data.already_connected) {
res.info = gettext('Database already connected.');
@@ -457,7 +461,8 @@ define('pgadmin.node.database', [
_tree.unload(_item);
_tree.setInode(_item);
_tree.removeIcon(_item);
- _tree.addIcon(_item, {icon: 'icon-database-not-connected'});
+ var dbIcon = data.isTemplate ? 'icon-database-template-not-connected':'icon-database-not-connected';
+ _tree.addIcon(_item, {icon: dbIcon});
obj.trigger('connect:cancelled', obj, _item, _data);
pgBrowser.Events.trigger(
'pgadmin:database:connect:cancelled', _item, _data, obj
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
index 871b9db92..11050b02d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
@@ -52,7 +52,7 @@ export default class DatabaseSchema extends BaseUISchema {
super({
name: undefined,
owner: undefined,
- is_sys_obj: undefined,
+ is_sys_obj: false,
comment: undefined,
encoding: 'UTF8',
template: undefined,
@@ -141,8 +141,8 @@ export default class DatabaseSchema extends BaseUISchema {
min: -1,
},{
id: 'is_template', label: gettext('Template?'),
- editable: false, type: 'switch', group: gettext('Definition'),
- readonly: true, mode: ['properties', 'edit'],
+ type: 'switch', group: gettext('Definition'),
+ mode: ['properties', 'edit'], readonly: function(state) {return (state.is_sys_obj); }
},{
id: 'datallowconn', label: gettext('Allow connections?'),
editable: false, type: 'switch', group: gettext('Definition'),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/css/database.css b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/css/database.css
index 0c9ae10dd..bded90788 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/css/database.css
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/css/database.css
@@ -17,3 +17,24 @@
height: 1.3em;
}
+
+.icon-database-template-connected {
+ background-image: url('{{ url_for('NODE-database.static', filename='img/template_database.svg') }}') !important;
+ border-radius: 10px;
+ background-size: 20px !important;
+ background-repeat: no-repeat;
+ vertical-align: middle;
+ align-content: center;
+ height: 1.3em;
+}
+
+.icon-database-template-not-connected {
+ background-image: url('{{ url_for('NODE-database.static', filename='img/template_database_bad.svg') }}') !important;
+ border-radius: 10px;
+ background-size: 20px !important;
+ background-repeat: no-repeat;
+ vertical-align: middle;
+ align-content: center;
+ height: 1.3em;
+
+}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/properties.sql
index 903cd096e..a8281380d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/properties.sql
@@ -29,7 +29,11 @@ FROM pg_catalog.pg_database db
LEFT OUTER JOIN pg_catalog.pg_shdescription descr ON (
db.oid=descr.objoid AND descr.classoid='pg_database'::regclass
)
-WHERE {% if did %}
+WHERE
+{% if show_user_defined_templates is defined %}
+ db.datistemplate = {{show_user_defined_templates}} AND
+{% endif %}
+{% if did %}
db.oid = {{ did|qtLiteral }}::OID{% else %}{% if name %}
db.datname = {{ name|qtLiteral }}::text{% else %}
db.oid > {{ last_system_oid|qtLiteral }}::OID OR db.datname IN ('postgres', 'edb')
@@ -40,6 +44,8 @@ AND
db.datname in ({{db_restrictions}})
{% endif %}
-AND db.datistemplate in (false, {{show_system_objects}})
+{% if show_user_defined_templates is defined %}
+ AND db.datistemplate = {{show_user_defined_templates}}
+{% endif %}
ORDER BY datname;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/properties.sql
index 1a6b38dba..362a8fbf4 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.2_plus/properties.sql
@@ -36,7 +36,11 @@ FROM pg_catalog.pg_database db
LEFT OUTER JOIN pg_catalog.pg_shdescription descr ON (
db.oid=descr.objoid AND descr.classoid='pg_database'::regclass
)
-WHERE {% if did %}
+WHERE
+{% if show_user_defined_templates is defined %}
+ db.datistemplate = {{show_user_defined_templates}} AND
+{% endif %}
+{% if did %}
db.oid = {{ did|qtLiteral }}::OID{% else %}{% if name %}
db.datname = {{ name|qtLiteral }}::text{% else %}
db.oid > {{ last_system_oid|qtLiteral }}::OID OR db.datname IN ('postgres', 'edb')
@@ -47,6 +51,6 @@ AND
db.datname in ({{db_restrictions}})
{% endif %}
-AND db.datistemplate in (false, {{show_system_objects}})
+
ORDER BY datname;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.3_plus/alter_online.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.3_plus/alter_online.sql
index 40ec137ba..65766d546 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.3_plus/alter_online.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.3_plus/alter_online.sql
@@ -155,3 +155,8 @@
{% endif %}
{% endif %}
+
+{# Change the connection limit #}
+{% if data.is_template is defined %}
+ALTER DATABASE {{ conn|qtIdent(data.name) }} WITH IS_TEMPLATE = {{ data.is_template }};
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/alter_online.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/alter_online.sql
index 9296ee6cb..60cf869b5 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/alter_online.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/alter_online.sql
@@ -136,3 +136,8 @@
{% endif %}
{% endif %}
{% endif %}
+
+{# Change the connection limit #}
+{% data.is_template is defined %}
+ALTER DATABASE {{ conn|qtIdent(data.name) }} WITH IS_TEMPLATE = {{ data.is_template }};
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/nodes.sql
index 328c073ca..350aeaf25 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/nodes.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/nodes.sql
@@ -1,10 +1,15 @@
SELECT
db.oid as did, db.datname as name, ta.spcname as spcname, db.datallowconn,
+ db.datistemplate AS is_template,
pg_catalog.has_database_privilege(db.oid, 'CREATE') as cancreate, datdba as owner
FROM
pg_catalog.pg_database db
LEFT OUTER JOIN pg_catalog.pg_tablespace ta ON db.dattablespace = ta.oid
-WHERE {% if did %}
+WHERE
+{% if show_user_defined_templates is defined %}
+db.datistemplate in (false, {{show_user_defined_templates}}) AND
+{% endif %}
+{% if did %}
db.oid = {{ did|qtLiteral }}::OID{% else %}
db.oid > {{ last_system_oid }}::OID OR db.datname IN ('postgres', 'edb')
{% endif %}
@@ -16,8 +21,6 @@ db.datname in ({{db_restrictions}})
{% if show_system_objects %}
AND db.datistemplate in (false, {{show_system_objects}})
-{% else %}
-AND db.datistemplate in (false)
{% endif %}
ORDER BY datname;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql
index 5eced7dd8..6c4985bb6 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql
@@ -20,7 +20,11 @@ FROM pg_catalog.pg_database db
LEFT OUTER JOIN pg_catalog.pg_shdescription descr ON (
db.oid=descr.objoid AND descr.classoid='pg_database'::regclass
)
-WHERE {% if did %}
+WHERE
+{% if show_user_defined_templates is defined %}
+ db.datistemplate = {{show_user_defined_templates}} AND
+{% endif %}
+{% if did %}
db.oid = {{ did|qtLiteral }}::OID{% else %}{% if name %}
db.datname = {{ name|qtLiteral }}::text{% else %}
db.oid > {{ last_system_oid|qtLiteral }}::OID OR db.datname IN ('postgres', 'edb')
@@ -31,6 +35,5 @@ AND
db.datname in ({{db_restrictions}})
{% endif %}
-AND db.datistemplate in (false, {{show_system_objects}})
ORDER BY datname;
diff --git a/web/pgadmin/dashboard/static/js/Dashboard.jsx b/web/pgadmin/dashboard/static/js/Dashboard.jsx
index cb43f0305..0367015e8 100644
--- a/web/pgadmin/dashboard/static/js/Dashboard.jsx
+++ b/web/pgadmin/dashboard/static/js/Dashboard.jsx
@@ -18,14 +18,14 @@ import Graphs from './Graphs';
import Notify from '../../../static/js/helpers/Notifier';
import { Box, Tab, Tabs } from '@material-ui/core';
import { PgIconButton } from '../../../static/js/components/Buttons';
-import CancelIcon from '@mui/icons-material/Cancel';
-import SquareIcon from '@mui/icons-material/Square';
-import ArrowRightOutlinedIcon from '@mui/icons-material/ArrowRightOutlined';
-import ArrowDropDownOutlinedIcon from '@mui/icons-material/ArrowDropDownOutlined';
+import CancelIcon from '@material-ui/icons/Cancel';
+import StopSharpIcon from '@material-ui/icons/StopSharp';
+import ArrowRightOutlinedIcon from '@material-ui/icons/ArrowRightOutlined';
+import ArrowDropDownOutlinedIcon from '@material-ui/icons/ArrowDropDownOutlined';
import WelcomeDashboard from './WelcomeDashboard';
import ActiveQuery from './ActiveQuery.ui';
import _ from 'lodash';
-import CachedIcon from '@mui/icons-material/Cached';
+import CachedOutlinedIcon from '@material-ui/icons/CachedOutlined';
import EmptyPanelMessage from '../../../static/js/components/EmptyPanelMessage';
import TabPanel from '../../../static/js/components/TabPanel';
@@ -287,7 +287,7 @@ export default function Dashboard({
}
+ icon={}
onClick={() => {
if (!canTakeAction(row, 'cancel'))
return;
@@ -774,7 +774,7 @@ export default function Dashboard({
size="xs"
noBorder
className={classes.refreshButton}
- icon={}
+ icon={}
onClick={(e) => {
e.preventDefault();
setRefresh(!refresh);