mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-12-25 08:21:04 -06:00
Added support to enable/disable rules. Fixes #6794
This commit is contained in:
parent
2aac87569b
commit
173cb60691
BIN
docs/en_US/images/rule_definition_enabled.png
Normal file
BIN
docs/en_US/images/rule_definition_enabled.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
@ -13,6 +13,7 @@ New features
|
||||
| `Issue #6081 <https://redmine.postgresql.org/issues/6081>`_ - Added support for advanced table fields like the foreign key, primary key in the ERD tool.
|
||||
| `Issue #6529 <https://redmine.postgresql.org/issues/6529>`_ - Added index creation when generating SQL in the ERD tool.
|
||||
| `Issue #6657 <https://redmine.postgresql.org/issues/6657>`_ - Added support for authentication via the webserver (REMOTE_USER).
|
||||
| `Issue #6794 <https://redmine.postgresql.org/issues/6794>`_ - Added support to enable/disable rules.
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
@ -37,6 +37,13 @@ Use the fields in the *Definition* tab to write parameters:
|
||||
executed instead of the original command; if Do Instead specifies *No*, the
|
||||
rule will be invoked in addition to the original command.
|
||||
|
||||
.. image:: images/rule_definition_enabled.png
|
||||
:alt: Trigger enabled in dialog tab
|
||||
:align: center
|
||||
|
||||
* *Rule enabled* field is available in rule dialog once the rule is created.
|
||||
You can select one of the four options available.
|
||||
|
||||
Click the *Condition* tab to continue.
|
||||
|
||||
.. image:: images/rule_condition.png
|
||||
|
@ -177,7 +177,7 @@ class ServerGroupView(NodeView):
|
||||
# if server group id is 1 we won't delete it.
|
||||
sg = groups.first()
|
||||
|
||||
shared_servers = Server.query.filter_by(servergroup_id=sg.id,
|
||||
shared_servers = Server.query.filter_by(servergroup_id=gid,
|
||||
shared=True).all()
|
||||
if shared_servers:
|
||||
return make_json_response(
|
||||
|
@ -249,7 +249,8 @@ class RuleView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
rset['rows'][0]['oid'],
|
||||
tid,
|
||||
rset['rows'][0]['name'],
|
||||
icon="icon-rule"
|
||||
icon="icon-rule" if
|
||||
rset['rows'][0]['is_enable_rule'] == 'D' else "icon-rule-bad"
|
||||
)
|
||||
|
||||
return make_json_response(
|
||||
@ -276,7 +277,9 @@ class RuleView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
row['oid'],
|
||||
tid,
|
||||
row['name'],
|
||||
icon="icon-rule"
|
||||
icon="icon-rule-bad"
|
||||
if 'is_enable_rule' in row and
|
||||
row['is_enable_rule'] == 'D' else "icon-rule"
|
||||
))
|
||||
|
||||
return make_json_response(
|
||||
@ -385,7 +388,10 @@ class RuleView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
rid,
|
||||
tid,
|
||||
name,
|
||||
icon="icon-%s" % self.node_type
|
||||
icon="icon-%s-bad" % self.node_type
|
||||
if 'is_enable_rule' in data and
|
||||
data['is_enable_rule'] == 'D'
|
||||
else "icon-%s" % self.node_type
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
|
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.4.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 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FEE07B;stroke:#DDA91D;stroke-width:0.75;stroke-linecap:round;stroke-linejoin:round;}
|
||||
.st1{fill:none;stroke:#DDA91D;stroke-width:0.75;stroke-linecap:round;stroke-linejoin:round;}
|
||||
.st2{fill:#D0021B;}
|
||||
</style>
|
||||
<g>
|
||||
<g id="_8">
|
||||
<rect x="2.4" y="5" class="st0" width="11.1" height="6"/>
|
||||
<line class="st1" x1="10.9" y1="5.4" x2="10.9" y2="8.9"/>
|
||||
<line class="st1" x1="6.9" y1="5.4" x2="6.9" y2="8.9"/>
|
||||
<line class="st1" x1="8.9" y1="5.4" x2="8.9" y2="7.9"/>
|
||||
<line class="st1" x1="4.9" y1="5.4" x2="4.9" y2="7.9"/>
|
||||
</g>
|
||||
<path class="st2" d="M14,5.1l1-1c0.3-0.3,0.3-0.8,0-1.1s-0.8-0.3-1.1,0l-1,1l-1-1c-0.3-0.3-0.8-0.3-1.1,0s-0.3,0.8,0,1.1l1,1l-1,1
|
||||
c-0.3,0.3-0.3,0.8,0,1.1c0.1,0.1,0.3,0.2,0.5,0.2s0.6-0.1,0.7-0.3l1-1l1,1c0.1,0.1,0.3,0.2,0.5,0.2s0.4,0,0.5-0.2
|
||||
c0.3-0.3,0.3-0.8,0-1.1L14,5.1z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -12,8 +12,8 @@ import RuleSchema from './rule.ui';
|
||||
define('pgadmin.node.rule', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
|
||||
'pgadmin.node.schema.dir/schema_child_tree_node',
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform, SchemaChildTreeNode) {
|
||||
'pgadmin.node.schema.dir/schema_child_tree_node', 'pgadmin.alertifyjs',
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform, SchemaChildTreeNode, alertify) {
|
||||
|
||||
/**
|
||||
Create and add a rule collection into nodes
|
||||
@ -112,8 +112,93 @@ define('pgadmin.node.rule', [
|
||||
icon: 'wcTabIcon icon-rule', data: {action: 'create', check: true},
|
||||
enable: 'canCreate',
|
||||
},
|
||||
{
|
||||
name: 'enable_rule', node: 'rule', module: this,
|
||||
applies: ['object', 'context'], callback: 'enable_rule',
|
||||
category: 'connect', priority: 3, label: gettext('Enable rule'),
|
||||
icon: 'fa fa-check', enable: 'canCreate_with_rule_enable',
|
||||
},{
|
||||
name: 'disable_rule', node: 'rule', module: this,
|
||||
applies: ['object', 'context'], callback: 'disable_rule',
|
||||
category: 'drop', priority: 3, label: gettext('Disable rule'),
|
||||
icon: 'fa fa-times', enable: 'canCreate_with_rule_disable'
|
||||
}
|
||||
]);
|
||||
},
|
||||
callbacks: {
|
||||
/* Enable rule */
|
||||
enable_rule: function(args) {
|
||||
var input = args || {},
|
||||
obj = this,
|
||||
t = pgBrowser.tree,
|
||||
i = input.item || t.selected(),
|
||||
d = i ? t.itemData(i) : undefined;
|
||||
|
||||
if (!d)
|
||||
return false;
|
||||
|
||||
var data = d;
|
||||
$.ajax({
|
||||
url: obj.generate_url(i, 'obj' , d, true),
|
||||
type:'PUT',
|
||||
data: {'is_enable_rule' : 'O'},
|
||||
dataType: 'json',
|
||||
})
|
||||
.done(function() {
|
||||
alertify.success('Rule updated.');
|
||||
t.removeIcon(i);
|
||||
data.icon = 'icon-rule';
|
||||
t.addIcon(i, {icon: data.icon});
|
||||
t.unload(i);
|
||||
t.setInode(false);
|
||||
t.deselect(i);
|
||||
// Fetch updated data from server
|
||||
setTimeout(function() {
|
||||
t.select(i);
|
||||
}, 10);
|
||||
})
|
||||
.fail(function(xhr, status, error) {
|
||||
alertify.pgRespErrorNotify(xhr, error);
|
||||
t.unload(i);
|
||||
});
|
||||
},
|
||||
/* Disable rule */
|
||||
disable_rule: function(args) {
|
||||
var input = args || {},
|
||||
obj = this,
|
||||
t = pgBrowser.tree,
|
||||
i = input.item || t.selected(),
|
||||
d = i ? t.itemData(i) : undefined;
|
||||
|
||||
if (!d)
|
||||
return false;
|
||||
|
||||
var data = d;
|
||||
$.ajax({
|
||||
url: obj.generate_url(i, 'obj' , d, true),
|
||||
type:'PUT',
|
||||
data: {'is_enable_rule' : 'D'},
|
||||
dataType: 'json',
|
||||
})
|
||||
.done(function() {
|
||||
alertify.success('Rule updated');
|
||||
t.removeIcon(i);
|
||||
data.icon = 'icon-rule-bad';
|
||||
t.addIcon(i, {icon: data.icon});
|
||||
t.unload(i);
|
||||
t.setInode(false);
|
||||
t.deselect(i);
|
||||
// Fetch updated data from server
|
||||
setTimeout(function() {
|
||||
t.select(i);
|
||||
}, 10);
|
||||
})
|
||||
.fail(function(xhr, status, error) {
|
||||
alertify.pgRespErrorNotify(xhr, error, gettext('Disable rule failed'));
|
||||
t.unload(i);
|
||||
});
|
||||
},
|
||||
},
|
||||
getSchema: function(treeNodeInfo, itemNodeData) {
|
||||
return new RuleSchema(
|
||||
{
|
||||
@ -216,6 +301,26 @@ define('pgadmin.node.rule', [
|
||||
|
||||
},
|
||||
|
||||
canCreate_with_rule_enable: function(itemData, item, data) {
|
||||
var treeData = pgBrowser.tree.getTreeNodeHierarchy(item);
|
||||
if ('view' in treeData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return itemData.icon === 'icon-rule-bad' &&
|
||||
this.canCreate.apply(this,[itemData, item, data]);
|
||||
},
|
||||
// Check to whether rule is enable ?
|
||||
canCreate_with_rule_disable: function(itemData, item, data) {
|
||||
var treeData = pgBrowser.tree.getTreeNodeHierarchy(item);
|
||||
if ('view' in treeData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return itemData.icon === 'icon-rule' &&
|
||||
this.canCreate.apply(itemData, item, data);
|
||||
},
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,24 @@ export default class RuleSchema extends BaseUISchema {
|
||||
state.view = obj.fieldOptions.nodeData.label;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'is_enable_rule', label: gettext('Rule enabled?'),
|
||||
mode: ['edit', 'properties'], group: gettext('Definition'),
|
||||
type: 'select',
|
||||
disabled: () => {
|
||||
if('catalog' in obj.fieldOptions.nodeInfo || 'view' in obj.fieldOptions.nodeInfo) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
options: [
|
||||
{label: gettext('Enable'), value: 'O'},
|
||||
{label: gettext('Enable Replica'), value: 'R'},
|
||||
{label: gettext('Enable Always'), value: 'A'},
|
||||
{label: gettext('Disable'), value: 'D'},
|
||||
],
|
||||
controlProps: { allowClear: false },
|
||||
},
|
||||
{
|
||||
id: 'event', label: gettext('Event'), control: 'select2',
|
||||
group: gettext('Definition'), type: 'select',
|
||||
@ -94,10 +112,6 @@ export default class RuleSchema extends BaseUISchema {
|
||||
id: 'system_rule', label: gettext('System rule?'),
|
||||
type: 'switch', mode: ['properties'],
|
||||
},
|
||||
{
|
||||
id: 'enabled', label: gettext('Enabled?'),
|
||||
type: 'switch', mode: ['properties'],
|
||||
},
|
||||
{
|
||||
id: 'comment', label: gettext('Comment'), cell: 'text', type: 'multiline',
|
||||
},
|
||||
|
@ -7,3 +7,14 @@
|
||||
vertical-align: middle;
|
||||
height: 1.3em;
|
||||
}
|
||||
|
||||
|
||||
.icon-rule-bad{
|
||||
background-image: url('{{ url_for('NODE-rule.static', filename='img/rule-bad.svg') }}') !important;
|
||||
border-radius: 10px;
|
||||
background-size: 20px !important;
|
||||
background-repeat: no-repeat;
|
||||
align-content: center;
|
||||
vertical-align: middle;
|
||||
height: 1.3em;
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
SELECT
|
||||
rw.oid AS oid,
|
||||
rw.rulename AS name
|
||||
rw.rulename AS name,
|
||||
CASE WHEN rw.ev_enabled != 'D' THEN True ELSE False END AS enabled,
|
||||
rw.ev_enabled AS is_enable_rule
|
||||
|
||||
FROM
|
||||
pg_catalog.pg_rewrite rw
|
||||
WHERE
|
||||
|
@ -12,6 +12,7 @@ SELECT
|
||||
{# ===== Check whether it is system rule or not ===== #}
|
||||
CASE WHEN rw.rulename = '_RETURN' THEN True ELSE False END AS system_rule,
|
||||
CASE WHEN rw.ev_enabled != 'D' THEN True ELSE False END AS enabled,
|
||||
rw.ev_enabled AS is_enable_rule,
|
||||
pg_catalog.pg_get_ruledef(rw.oid) AS definition
|
||||
FROM
|
||||
pg_catalog.pg_rewrite rw
|
||||
|
@ -35,3 +35,13 @@ CREATE OR REPLACE RULE {{ conn|qtIdent(rule_name) }} AS
|
||||
{% set old_comment = o_data.comment|default('', true) %}
|
||||
{% if (data.comment is defined and (data.comment != old_comment)) %}
|
||||
COMMENT ON RULE {{ conn|qtIdent(rule_name) }} ON {{ conn|qtIdent(o_data.schema, o_data.view) }} IS {{ data.comment|qtLiteral }};{% endif %}
|
||||
|
||||
{% if data.enabled is defined and o_data.enabled != data.enabled %}
|
||||
ALTER TABLE {{ conn|qtIdent(o_data.schema, o_data.view) }} {% if (data.enabled in ['false', False]) %}DISABLE{% endif %}{% if (data.enabled in ['true', True]) %}ENABLE{% endif %} RULE {{ conn|qtIdent(o_data.name) }};
|
||||
{% endif %}
|
||||
|
||||
{% if data.is_enable_rule is defined and o_data.is_enable_rule != data.is_enable_rule %}
|
||||
{% set enable_map = {'R':'ENABLE REPLICA', 'A':'ENABLE ALWAYS', 'O':'ENABLE', 'D':'DISABLE'} %}
|
||||
ALTER TABLE {{ conn|qtIdent(o_data.schema, o_data.view) }}
|
||||
{{ enable_map[data.is_enable_rule] }} RULE {{ conn|qtIdent(o_data.name) }};
|
||||
{% endif %}
|
||||
|
Loading…
Reference in New Issue
Block a user