mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-22 08:46:39 -06:00
Port Triggers node to react. Fixes #6672
This commit is contained in:
parent
bb5e2b98e9
commit
351cb3e6ca
@ -1480,8 +1480,7 @@ class FunctionView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
parallel_dict = {'u': 'UNSAFE', 's': 'SAFE', 'r': 'RESTRICTED'}
|
||||
|
||||
# Get Schema Name from its OID.
|
||||
if self.node_type != 'trigger_function':
|
||||
self._get_schema_name_from_oid(data)
|
||||
self._get_schema_name_from_oid(data)
|
||||
|
||||
if fnid is not None:
|
||||
# Edit Mode
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
import TriggerFunctionSchema from './trigger_function.ui';
|
||||
import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../../static/js/node_ajax';
|
||||
import { getNodeListByName, getNodeListById, getNodeAjaxOptions } from '../../../../../../../static/js/node_ajax';
|
||||
import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
|
||||
import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
|
||||
|
||||
@ -91,7 +91,9 @@ define('pgadmin.node.trigger_function', [
|
||||
()=>getNodeVariableSchema(this, treeNodeInfo, itemNodeData, false, false),
|
||||
{
|
||||
role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData),
|
||||
schema: ()=>getNodeListByName('schema', treeNodeInfo, itemNodeData, {cacheLevel: 'database'}),
|
||||
schema: ()=>getNodeListById(pgBrowser.Nodes['schema'], treeNodeInfo, itemNodeData, {
|
||||
cacheLevel: 'database'
|
||||
}),
|
||||
language: ()=>getNodeAjaxOptions('get_languages', this, treeNodeInfo, itemNodeData, {noCache: true}, (res) => {
|
||||
return _.reject(res, function(o) {
|
||||
return o.label == 'sql' || o.label == 'edbspl';
|
||||
@ -101,7 +103,7 @@ define('pgadmin.node.trigger_function', [
|
||||
},
|
||||
{
|
||||
funcowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name,
|
||||
pronamespace: treeNodeInfo.schema ? treeNodeInfo.schema.label : ''
|
||||
pronamespace: treeNodeInfo.schema ? treeNodeInfo.schema._id : null
|
||||
}
|
||||
);
|
||||
},
|
||||
|
@ -6,6 +6,8 @@
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../../../static/js/node_ajax';
|
||||
import TriggerSchema from './trigger.ui';
|
||||
|
||||
define('pgadmin.node.trigger', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
@ -173,6 +175,19 @@ define('pgadmin.node.trigger', [
|
||||
},
|
||||
canDrop: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
|
||||
canDropCascade: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
|
||||
getSchema: function(treeNodeInfo, itemNodeData) {
|
||||
return new TriggerSchema(
|
||||
{
|
||||
triggerFunction: ()=>getNodeAjaxOptions('get_triggerfunctions', this, treeNodeInfo, itemNodeData, {cacheLevel: 'trigger_function'}, (data) => {
|
||||
return _.reject(data, function(option) {
|
||||
return option.label == '';
|
||||
});
|
||||
}),
|
||||
columns: ()=> getNodeListByName('column', treeNodeInfo, itemNodeData, { cacheLevel: 'column'}),
|
||||
nodeInfo: treeNodeInfo
|
||||
},
|
||||
);
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
defaults: {
|
||||
|
@ -0,0 +1,492 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import gettext from 'sources/gettext';
|
||||
import BaseUISchema from 'sources/SchemaView/base_schema.ui';
|
||||
import { isEmptyString } from 'sources/validators';
|
||||
|
||||
export class EventSchema extends BaseUISchema {
|
||||
constructor(fieldOptions={}, initValues) {
|
||||
super({
|
||||
evnt_update: false,
|
||||
evnt_insert: false,
|
||||
evnt_delete: false,
|
||||
evnt_truncate: false,
|
||||
is_row_trigger: false,
|
||||
is_constraint_trigger: false,
|
||||
...initValues,
|
||||
});
|
||||
|
||||
this.fieldOptions = {
|
||||
nodeInfo: null,
|
||||
...fieldOptions,
|
||||
};
|
||||
|
||||
this.nodeInfo = this.fieldOptions.nodeInfo;
|
||||
|
||||
}
|
||||
|
||||
get idAttribute() {
|
||||
return 'oid';
|
||||
}
|
||||
|
||||
inSchemaWithModelCheck(state) {
|
||||
// Check if we are under schema node & in 'create' mode
|
||||
if(this.nodeInfo && 'schema' in this.nodeInfo) {
|
||||
// We will disable control if it's in 'edit' mode
|
||||
return !this.isNew(state);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
get baseFields() {
|
||||
let obj = this;
|
||||
return [{
|
||||
id: 'evnt_insert', label: gettext('INSERT'),
|
||||
type: 'switch', mode: ['create','edit', 'properties'],
|
||||
group: gettext('Events'),
|
||||
disabled: (state) => {
|
||||
var evn_insert = state.evnt_insert;
|
||||
if (!_.isUndefined(evn_insert) && obj.nodeInfo && obj.nodeInfo.server.server_type == 'ppas' && obj.isNew(state))
|
||||
return false;
|
||||
return obj.inSchemaWithModelCheck(state);
|
||||
},
|
||||
},{
|
||||
id: 'evnt_update', label: gettext('UPDATE'),
|
||||
type: 'switch', mode: ['create','edit', 'properties'],
|
||||
group: gettext('Events'),
|
||||
disabled: (state) => {
|
||||
var evn_update = state.evnt_update;
|
||||
if (!_.isUndefined(evn_update) && obj.nodeInfo && obj.nodeInfo.server.server_type == 'ppas' && obj.isNew(state))
|
||||
return false;
|
||||
return obj.inSchemaWithModelCheck(state);
|
||||
},
|
||||
},{
|
||||
id: 'evnt_delete', label: gettext('DELETE'),
|
||||
type: 'switch', mode: ['create','edit', 'properties'],
|
||||
group: gettext('Events'),
|
||||
disabled: (state) => {
|
||||
var evn_delete = state.evnt_delete;
|
||||
if (!_.isUndefined(evn_delete) && obj.nodeInfo && obj.nodeInfo.server.server_type == 'ppas' && obj.isNew(state))
|
||||
return false;
|
||||
return obj.inSchemaWithModelCheck(state);
|
||||
},
|
||||
},{
|
||||
id: 'evnt_truncate', label: gettext('TRUNCATE'),
|
||||
type: 'switch', group: gettext('Events'), deps: ['is_row_trigger', 'is_constraint_trigger'],
|
||||
disabled: (state) => {
|
||||
var is_constraint_trigger = state.is_constraint_trigger,
|
||||
is_row_trigger = state.is_row_trigger,
|
||||
server_type = obj.nodeInfo ? obj.nodeInfo.server.server_type: null;
|
||||
if (is_row_trigger == true){
|
||||
state.evnt_truncate = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (server_type === 'ppas' && !_.isUndefined(is_constraint_trigger) &&
|
||||
!_.isUndefined(is_row_trigger) &&
|
||||
is_constraint_trigger === false && obj.isNew(state))
|
||||
return false;
|
||||
|
||||
return obj.inSchemaWithModelCheck(state);
|
||||
},
|
||||
}];
|
||||
}
|
||||
|
||||
validate(state, setError) {
|
||||
|
||||
if (isEmptyString(state.service)) {
|
||||
let errmsg = null;
|
||||
/* events validation*/
|
||||
if (state.tfunction && !state.evnt_truncate && !state.evnt_delete && !state.evnt_update && !state.evnt_insert) {
|
||||
errmsg = gettext('Specify at least one event.');
|
||||
//setError('evnt_truncate', errmsg);
|
||||
//setError('evnt_delete', errmsg);
|
||||
//setError('evnt_update', errmsg);
|
||||
setError('evnt_insert', errmsg);
|
||||
//setError('evnt_update', errmsg);
|
||||
return true;
|
||||
} else {
|
||||
errmsg = null;
|
||||
//setError('evnt_truncate', errmsg);
|
||||
//setError('evnt_delete', errmsg);
|
||||
//setError('evnt_update', errmsg);
|
||||
setError('evnt_insert', errmsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default class TriggerSchema extends BaseUISchema {
|
||||
constructor(fieldOptions={}, initValues) {
|
||||
super({
|
||||
name: undefined,
|
||||
is_row_trigger: true,
|
||||
fires: 'BEFORE',
|
||||
...initValues
|
||||
});
|
||||
|
||||
this.fieldOptions = {
|
||||
triggerFunction: [],
|
||||
//columns: [],
|
||||
...fieldOptions,
|
||||
};
|
||||
this.nodeInfo = this.fieldOptions.nodeInfo;
|
||||
|
||||
}
|
||||
|
||||
get idAttribute() {
|
||||
return 'oid';
|
||||
}
|
||||
|
||||
inSchema() {
|
||||
// Check if under schema node & in 'create' mode
|
||||
if('catalog' in this.nodeInfo) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inSchemaWithModelCheck(state) {
|
||||
// Check if we are under schema node & in 'create' mode
|
||||
if('schema' in this.nodeInfo) {
|
||||
// We will disable control if it's in 'edit' mode
|
||||
return !this.isNew(state);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
disableTransition(state) {
|
||||
if (!this.isNew())
|
||||
return true;
|
||||
var flag = false,
|
||||
evnt = null,
|
||||
name = state.name,
|
||||
evnt_count = 0;
|
||||
|
||||
// Disable transition tables for view trigger and PG version < 100000
|
||||
if(_.indexOf(Object.keys(this.nodeInfo), 'table') == -1 ||
|
||||
this.nodeInfo.server.version < 100000) return true;
|
||||
|
||||
if (name == 'tgoldtable') evnt = 'evnt_delete';
|
||||
else if (name == 'tgnewtable') evnt = 'evnt_insert';
|
||||
|
||||
if(state.evnt_insert) evnt_count++;
|
||||
if(state.evnt_update) evnt_count++;
|
||||
if(state.evnt_delete) evnt_count++;
|
||||
|
||||
|
||||
// Disable transition tables if
|
||||
// - It is a constraint trigger
|
||||
// - Fires other than AFTER
|
||||
// - More than one events enabled
|
||||
// - Update event with the column list
|
||||
|
||||
// Disable Old transition table if both UPDATE and DELETE events are disabled
|
||||
// Disable New transition table if both UPDATE and INSERT events are disabled
|
||||
if(!state.is_constraint_trigger && state.fires == 'AFTER' &&
|
||||
(state.evnt_update || state[evnt]) && evnt_count == 1) {
|
||||
flag = (state.evnt_update && (_.size(state.columns) >= 1 && state.columns[0] != ''));
|
||||
}
|
||||
|
||||
if(flag && state.name) {
|
||||
state.name = null;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
get baseFields() {
|
||||
let obj = this;
|
||||
return [{
|
||||
id: 'name', label: gettext('Name'), cell: 'text',
|
||||
type: 'text', disabled: obj.inSchema, noEmpty: true
|
||||
},{
|
||||
id: 'oid', label: gettext('OID'), cell: 'text',
|
||||
type: 'int', mode: ['properties'],
|
||||
},{
|
||||
id: 'is_enable_trigger', label: gettext('Trigger enabled?'),
|
||||
mode: ['edit', 'properties'], group: gettext('Definition'),
|
||||
type: 'select',
|
||||
disabled: () => {
|
||||
if('catalog' in obj.nodeInfo || 'view' in obj.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: 'is_row_trigger', label: gettext('Row trigger?'),
|
||||
type: 'switch', group: gettext('Definition'),
|
||||
mode: ['create','edit', 'properties'],
|
||||
deps: ['is_constraint_trigger'],
|
||||
disabled: (state) => {
|
||||
// Disabled if table is a partitioned table.
|
||||
if (!obj.isNew())
|
||||
return true;
|
||||
|
||||
if (obj.nodeInfo.table.is_partitioned && obj.nodeInfo.server.version < 110000)
|
||||
{
|
||||
state.is_row_trigger = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// If constraint trigger is set to True then row trigger will
|
||||
// automatically set to True and becomes disable
|
||||
var is_constraint_trigger = state.is_constraint_trigger;
|
||||
if(!obj.inSchemaWithModelCheck(state)) {
|
||||
if(!_.isUndefined(is_constraint_trigger) &&
|
||||
is_constraint_trigger === true) {
|
||||
// change it's model value
|
||||
state.is_row_trigger = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Check if it is row trigger then enabled it.
|
||||
var is_row_trigger = state.is_row_trigger;
|
||||
if (!_.isUndefined(is_row_trigger) && obj.nodeInfo.server.server_type == 'ppas') {
|
||||
return false;
|
||||
}
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},{
|
||||
id: 'is_constraint_trigger', label: gettext('Constraint trigger?'),
|
||||
type: 'switch',
|
||||
mode: ['create','edit', 'properties'],
|
||||
group: gettext('Definition'),
|
||||
deps: ['tfunction'],
|
||||
disabled: (state) => {
|
||||
// Disabled if table is a partitioned table.
|
||||
var tfunction = state.tfunction;
|
||||
if (( _.has(obj.nodeInfo, 'table') && _.has(obj.nodeInfo.table, 'is_partitioned') &&
|
||||
obj.nodeInfo.table.is_partitioned) || ( _.has(obj.nodeInfo, 'view')) ||
|
||||
(obj.nodeInfo.server.server_type === 'ppas' && !_.isUndefined(tfunction) &&
|
||||
tfunction === 'Inline EDB-SPL')) {
|
||||
state.is_constraint_trigger = false;
|
||||
return true;
|
||||
}
|
||||
return obj.inSchemaWithModelCheck(state);
|
||||
},
|
||||
},{
|
||||
id: 'tgdeferrable', label: gettext('Deferrable?'),
|
||||
type: 'switch', group: gettext('Definition'),
|
||||
mode: ['create','edit', 'properties'],
|
||||
deps: ['is_constraint_trigger'],
|
||||
disabled: (state) => {
|
||||
// If constraint trigger is set to True then only enable it
|
||||
var is_constraint_trigger = state.is_constraint_trigger;
|
||||
if(!obj.inSchemaWithModelCheck(state)) {
|
||||
if(!_.isUndefined(is_constraint_trigger) &&
|
||||
is_constraint_trigger === true) {
|
||||
return false;
|
||||
} else {
|
||||
// If value is already set then reset it to false
|
||||
if(state.tgdeferrable) {
|
||||
state.tgdeferrable = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},{
|
||||
id: 'tginitdeferred', label: gettext('Deferred?'),
|
||||
type: 'switch', group: gettext('Definition'),
|
||||
mode: ['create','edit', 'properties'],
|
||||
deps: ['tgdeferrable', 'is_constraint_trigger'],
|
||||
disabled: (state) => {
|
||||
// If Deferrable is set to True then only enable it
|
||||
var tgdeferrable = state.tgdeferrable;
|
||||
if(!obj.inSchemaWithModelCheck(state)) {
|
||||
if(!_.isUndefined(tgdeferrable) && tgdeferrable) {
|
||||
return false;
|
||||
} else {
|
||||
// If value is already set then reset it to false
|
||||
if(obj.tginitdeferred) {
|
||||
state.tginitdeferred = false;
|
||||
}
|
||||
// If constraint trigger is set then do not disable
|
||||
return state.is_constraint_trigger ? false : true;
|
||||
}
|
||||
} else {
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},{
|
||||
id: 'tfunction', label: gettext('Trigger function'),
|
||||
type: 'select', disabled: obj.inSchemaWithModelCheck,
|
||||
mode: ['create','edit', 'properties'], group: gettext('Definition'),
|
||||
control: 'node-ajax-options', url: 'get_triggerfunctions', url_jump_after_node: 'schema',
|
||||
options: obj.fieldOptions.triggerFunction,
|
||||
cache_node: 'trigger_function',
|
||||
},{
|
||||
id: 'tgargs', label: gettext('Arguments'), cell: 'text',
|
||||
group: gettext('Definition'),
|
||||
type: 'text',mode: ['create','edit', 'properties'], deps: ['tfunction'],
|
||||
disabled: (state) => {
|
||||
// We will disable it when EDB PPAS and trigger function is
|
||||
// set to Inline EDB-SPL
|
||||
var tfunction = state.tfunction,
|
||||
server_type = obj.nodeInfo.server.server_type;
|
||||
if(!obj.inSchemaWithModelCheck(state)) {
|
||||
if(server_type === 'ppas' &&
|
||||
!_.isUndefined(tfunction) &&
|
||||
tfunction === 'Inline EDB-SPL') {
|
||||
// Disable and clear its value
|
||||
state.tgargs = undefined;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},{
|
||||
id: 'fires', label: gettext('Fires'), deps: ['is_constraint_trigger'],
|
||||
mode: ['create','edit', 'properties'], group: gettext('Events'),
|
||||
options: () => {
|
||||
var table_options = [
|
||||
{label: 'BEFORE', value: 'BEFORE'},
|
||||
{label: 'AFTER', value: 'AFTER'}],
|
||||
view_options = [
|
||||
{label: 'BEFORE', value: 'BEFORE'},
|
||||
{label: 'AFTER', value: 'AFTER'},
|
||||
{label: 'INSTEAD OF', value: 'INSTEAD OF'}];
|
||||
// If we are under table then show table specific options
|
||||
if(_.indexOf(Object.keys(obj.nodeInfo), 'table') != -1) {
|
||||
return table_options;
|
||||
} else {
|
||||
return view_options;
|
||||
}
|
||||
},
|
||||
type: 'select', controlProps: { allowClear: false },
|
||||
disabled: (state) => {
|
||||
if (!obj.isNew())
|
||||
return true;
|
||||
// If contraint trigger is set to True then only enable it
|
||||
var is_constraint_trigger = obj.is_constraint_trigger;
|
||||
if(!obj.inSchemaWithModelCheck(state)) {
|
||||
if(!_.isUndefined(is_constraint_trigger) &&
|
||||
is_constraint_trigger === true) {
|
||||
state.fires = 'AFTER';
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Check if it is row trigger then enabled it.
|
||||
var fires_ = state.fires;
|
||||
if (!_.isUndefined(fires_) && obj.nodeInfo.server.server_type == 'ppas') {
|
||||
return false;
|
||||
}
|
||||
// Disable it
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},{
|
||||
type: 'nested-fieldset', mode: ['create','edit', 'properties'],
|
||||
label: gettext('Events'), group: gettext('Events'),
|
||||
schema: new EventSchema({nodeInfo: obj.nodeInfo}),
|
||||
},{
|
||||
id: 'whenclause', label: gettext('When'),
|
||||
type: 'sql',
|
||||
readonly: obj.inSchemaWithModelCheck,
|
||||
mode: ['create', 'edit', 'properties'], visible: true,
|
||||
group: gettext('Events'),
|
||||
},{
|
||||
id: 'columns', label: gettext('Columns'),
|
||||
type: 'select', controlProps: { multiple: true },
|
||||
deps: ['evnt_update'], group: gettext('Events'),
|
||||
options: obj.fieldOptions.columns,
|
||||
disabled: (state) => {
|
||||
if(obj.nodeInfo && 'catalog' in obj.nodeInfo) {
|
||||
return true;
|
||||
}
|
||||
//Disable in edit mode
|
||||
if (!obj.isNew()) {
|
||||
return true;
|
||||
}
|
||||
// Enable column only if update event is set true
|
||||
var isUpdate = state.evnt_update;
|
||||
if(!_.isUndefined(isUpdate) && isUpdate) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},{
|
||||
id: 'tgoldtable', label: gettext('Old table'),
|
||||
type: 'text', group: gettext('Transition'),
|
||||
cell: 'text', mode: ['create', 'edit', 'properties'],
|
||||
deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
|
||||
disabled: obj.disableTransition,
|
||||
},{
|
||||
id: 'tgnewtable', label: gettext('New table'),
|
||||
type: 'text', group: gettext('Transition'),
|
||||
cell: 'string', mode: ['create', 'edit', 'properties'],
|
||||
deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
|
||||
disabled: obj.disableTransition,
|
||||
},{
|
||||
id: 'prosrc', label: gettext('Code'), group: gettext('Code'),
|
||||
type: 'sql', mode: ['create', 'edit'], deps: ['tfunction'],
|
||||
isFullTab: true,
|
||||
visible: true,
|
||||
readonly: (state) => {
|
||||
// We will enable it only when EDB PPAS and trigger function is
|
||||
// set to Inline EDB-SPL
|
||||
var tfunction = state.tfunction,
|
||||
server_type = obj.nodeInfo.server.server_type;
|
||||
|
||||
return (server_type !== 'ppas' ||
|
||||
_.isUndefined(tfunction) ||
|
||||
tfunction !== 'Inline EDB-SPL');
|
||||
},
|
||||
},{
|
||||
id: 'is_sys_trigger', label: gettext('System trigger?'), cell: 'text',
|
||||
type: 'switch', disabled: obj.inSchemaWithModelCheck, mode: ['properties'],
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
disabled: obj.inSchema,
|
||||
}];
|
||||
}
|
||||
|
||||
validate(state, setError) {
|
||||
let errmsg = null;
|
||||
|
||||
if (isEmptyString(state.service)) {
|
||||
|
||||
/* trigger function validation*/
|
||||
if (isEmptyString(state.tfunction)) {
|
||||
errmsg = gettext('Trigger function cannot be empty.');
|
||||
setError('tfunction', errmsg);
|
||||
return true;
|
||||
} else {
|
||||
errmsg = null;
|
||||
setError('tfunction', errmsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -405,6 +405,7 @@ export default class PgaJobScheduleSchema extends BaseUISchema {
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
validate(state, setError) {
|
||||
if (isEmptyString(state.jscstart)) {
|
||||
setError('jscstart', gettext('Please enter the start time.'));
|
||||
|
@ -63,6 +63,7 @@ function SQLTab({active, getSQLValue}) {
|
||||
readOnly: true,
|
||||
}}
|
||||
isAsync={true}
|
||||
readonly={true}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ import {useOnScreen} from 'sources/custom_hooks';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/* React wrapper for CodeMirror */
|
||||
export default function CodeMirror({name, value, options, events, ...props}) {
|
||||
export default function CodeMirror({currObj, name, value, options, events, ...props}) {
|
||||
const taRef = useRef();
|
||||
const cmObj = useRef();
|
||||
const cmWrapper = useRef();
|
||||
@ -24,6 +24,8 @@ export default function CodeMirror({name, value, options, events, ...props}) {
|
||||
cmObj.current = new OrigCodeMirror.fromTextArea(
|
||||
taRef.current, options);
|
||||
|
||||
currObj && currObj(cmObj.current);
|
||||
|
||||
if(cmObj.current) {
|
||||
try {
|
||||
cmWrapper.current = cmObj.current.getWrapperElement();
|
||||
@ -65,6 +67,7 @@ export default function CodeMirror({name, value, options, events, ...props}) {
|
||||
}
|
||||
|
||||
CodeMirror.propTypes = {
|
||||
currObj: PropTypes.func,
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
options: PropTypes.object,
|
||||
|
@ -137,11 +137,19 @@ FormInput.propTypes = {
|
||||
testcid: PropTypes.any,
|
||||
};
|
||||
|
||||
export function InputSQL({value, options, onChange, ...props}) {
|
||||
export function InputSQL({value, options, onChange, readonly, ...props}) {
|
||||
const classes = useStyles();
|
||||
const cmObj = useRef();
|
||||
|
||||
useEffect(()=>{
|
||||
if(cmObj.current) {
|
||||
cmObj.current.setOption('readOnly', readonly);
|
||||
}
|
||||
}, [readonly]);
|
||||
|
||||
return (
|
||||
<CodeMirror
|
||||
currObj={(obj)=>cmObj.current=obj}
|
||||
value={value||''}
|
||||
options={{
|
||||
lineNumbers: true,
|
||||
@ -161,8 +169,8 @@ export function InputSQL({value, options, onChange, ...props}) {
|
||||
InputSQL.propTypes = {
|
||||
value: PropTypes.string,
|
||||
options: PropTypes.object,
|
||||
onChange: PropTypes.func
|
||||
|
||||
onChange: PropTypes.func,
|
||||
readonly: PropTypes.bool
|
||||
};
|
||||
|
||||
export function FormInputSQL({hasError, required, label, className, helpMessage, testcid, value, controlProps, noLabel, ...props}) {
|
||||
|
378
web/regression/javascript/schema_ui_files/trigger.ui.spec.js
Normal file
378
web/regression/javascript/schema_ui_files/trigger.ui.spec.js
Normal file
@ -0,0 +1,378 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import jasmineEnzyme from 'jasmine-enzyme';
|
||||
import React from 'react';
|
||||
import '../helper/enzyme.helper';
|
||||
import { createMount } from '@material-ui/core/test-utils';
|
||||
import pgAdmin from 'sources/pgadmin';
|
||||
import {messages} from '../fake_messages';
|
||||
import SchemaView from '../../../pgadmin/static/js/SchemaView';
|
||||
//import BaseUISchema from 'sources/SchemaView/base_schema.ui';
|
||||
import TriggerSchema, { EventSchema } from '../../../pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.ui';
|
||||
|
||||
describe('TriggerSchema', ()=>{
|
||||
let mount;
|
||||
let schemaObj = new TriggerSchema(
|
||||
{
|
||||
triggerFunction: [],
|
||||
columns: [],
|
||||
nodeInfo: {
|
||||
schema: {},
|
||||
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 90400},
|
||||
table: {is_partitioned: false}
|
||||
}
|
||||
}
|
||||
);
|
||||
let getInitData = ()=>Promise.resolve({});
|
||||
|
||||
/* Use createMount so that material ui components gets the required context */
|
||||
/* https://material-ui.com/guides/testing/#api */
|
||||
beforeAll(()=>{
|
||||
mount = createMount();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
mount.cleanUp();
|
||||
});
|
||||
|
||||
beforeEach(()=>{
|
||||
jasmineEnzyme();
|
||||
/* messages used by validators */
|
||||
pgAdmin.Browser = pgAdmin.Browser || {};
|
||||
pgAdmin.Browser.messages = pgAdmin.Browser.messages || messages;
|
||||
pgAdmin.Browser.utils = pgAdmin.Browser.utils || {};
|
||||
});
|
||||
|
||||
it('create', ()=>{
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={schemaObj}
|
||||
viewHelperProps={{
|
||||
mode: 'create',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('edit', ()=>{
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={schemaObj}
|
||||
getInitData={getInitData}
|
||||
viewHelperProps={{
|
||||
mode: 'edit',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('properties', ()=>{
|
||||
mount(<SchemaView
|
||||
formType='tab'
|
||||
schema={schemaObj}
|
||||
getInitData={getInitData}
|
||||
viewHelperProps={{
|
||||
mode: 'properties',
|
||||
}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('validate', ()=>{
|
||||
let state = {};
|
||||
let setError = jasmine.createSpy('setError');
|
||||
|
||||
state.tfunction = null;
|
||||
schemaObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('tfunction', 'Trigger function cannot be empty.');
|
||||
|
||||
state.tfunction = 'public';
|
||||
schemaObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('tfunction', null);
|
||||
});
|
||||
|
||||
it('catalog create', ()=>{
|
||||
let catalogSchemaObj = new TriggerSchema(
|
||||
{
|
||||
triggerFunction: [],
|
||||
columns: [],
|
||||
nodeInfo: {
|
||||
catalog: {},
|
||||
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 90400},
|
||||
table: {is_partitioned: false}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={catalogSchemaObj}
|
||||
viewHelperProps={{
|
||||
mode: 'create',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('catalog properties', ()=>{
|
||||
let catalogPropertiesSchemaObj = new TriggerSchema(
|
||||
{
|
||||
triggerFunction: [],
|
||||
columns: [],
|
||||
nodeInfo: {
|
||||
catalog: {},
|
||||
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 90400},
|
||||
table: {is_partitioned: false}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
mount(<SchemaView
|
||||
formType='tab'
|
||||
schema={catalogPropertiesSchemaObj}
|
||||
getInitData={getInitData}
|
||||
viewHelperProps={{
|
||||
mode: 'properties',
|
||||
}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('edit disableTransition', ()=>{
|
||||
let editSchemaObj = new TriggerSchema(
|
||||
{
|
||||
triggerFunction: [],
|
||||
columns: [],
|
||||
nodeInfo: {
|
||||
catalog: {},
|
||||
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 100000},
|
||||
table: {is_partitioned: false}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
let initData = ()=>Promise.resolve({
|
||||
tgoldtable: 'tgoldtable',
|
||||
evnt_insert: true,
|
||||
evnt_update: true,
|
||||
evnt_delete: true,
|
||||
is_constraint_trigger: true,
|
||||
name: 'tgoldtable',
|
||||
fires: 'AFTER'
|
||||
});
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={editSchemaObj}
|
||||
getInitData={initData}
|
||||
viewHelperProps={{
|
||||
mode: 'edit',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('edit disableTransition tgnewtable', ()=>{
|
||||
let editSchemaObj = new TriggerSchema(
|
||||
{
|
||||
triggerFunction: [],
|
||||
columns: [],
|
||||
nodeInfo: {
|
||||
catalog: {},
|
||||
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 100000},
|
||||
table: {is_partitioned: false}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
let initData = ()=>Promise.resolve({
|
||||
tgoldtable: 'tgnewtable',
|
||||
evnt_insert: true,
|
||||
evnt_update: true,
|
||||
evnt_delete: true,
|
||||
is_constraint_trigger: false,
|
||||
name: 'tgnewtable',
|
||||
fires: 'AFTER'
|
||||
});
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={editSchemaObj}
|
||||
getInitData={initData}
|
||||
viewHelperProps={{
|
||||
mode: 'edit',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('TriggerEventsSchema', ()=>{
|
||||
let mount;
|
||||
let schemaObj = new EventSchema(
|
||||
{
|
||||
nodeInfo: {
|
||||
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 90400},
|
||||
table: {is_partitioned: false}
|
||||
}
|
||||
}
|
||||
);
|
||||
let getInitData = ()=>Promise.resolve({});
|
||||
|
||||
/* Use createMount so that material ui components gets the required context */
|
||||
/* https://material-ui.com/guides/testing/#api */
|
||||
beforeAll(()=>{
|
||||
mount = createMount();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
mount.cleanUp();
|
||||
});
|
||||
|
||||
beforeEach(()=>{
|
||||
jasmineEnzyme();
|
||||
/* messages used by validators */
|
||||
pgAdmin.Browser = pgAdmin.Browser || {};
|
||||
pgAdmin.Browser.messages = pgAdmin.Browser.messages || messages;
|
||||
pgAdmin.Browser.utils = pgAdmin.Browser.utils || {};
|
||||
});
|
||||
|
||||
it('create', ()=>{
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={schemaObj}
|
||||
viewHelperProps={{
|
||||
mode: 'create',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('properties', ()=>{
|
||||
mount(<SchemaView
|
||||
formType='tab'
|
||||
schema={schemaObj}
|
||||
getInitData={getInitData}
|
||||
viewHelperProps={{
|
||||
mode: 'properties',
|
||||
}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('edit', ()=>{
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={schemaObj}
|
||||
getInitData={getInitData}
|
||||
viewHelperProps={{
|
||||
mode: 'edit',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('validate', ()=>{
|
||||
let state = {};
|
||||
let setError = jasmine.createSpy('setError');
|
||||
|
||||
|
||||
state.tfunction = 'public';
|
||||
state.evnt_truncate = false;
|
||||
state.evnt_delete = false;
|
||||
state.evnt_update = false;
|
||||
state.evnt_insert = false;
|
||||
schemaObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('evnt_insert', 'Specify at least one event.');
|
||||
|
||||
state.tfunction = 'public';
|
||||
state.evnt_insert = true;
|
||||
schemaObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('evnt_insert', null);
|
||||
});
|
||||
|
||||
//spyOn(schemaObj, 'isNew’).and.returnValue(true);
|
||||
|
||||
/*it('evnt_insert disabled', ()=>{
|
||||
let disabled = _.find(schemaObj.fields, (f)=>f.id=='evnt_insert').disabled;
|
||||
disabled({evnt_insert : true});
|
||||
});
|
||||
|
||||
it('evnt_update disabled', ()=>{
|
||||
let disabled = _.find(schemaObj.fields, (f)=>f.id=='evnt_update').disabled;
|
||||
disabled({evnt_update : true});
|
||||
});
|
||||
|
||||
it('evnt_delete disabled', ()=>{
|
||||
let disabled = _.find(schemaObj.fields, (f)=>f.id=='evnt_delete').disabled;
|
||||
disabled({evnt_delete : true});
|
||||
});
|
||||
|
||||
it('evnt_truncate disabled', ()=>{
|
||||
getInitData = ()=>Promise.resolve({is_constraint_trigger: true});
|
||||
let disabled = _.find(schemaObj.fields, (f)=>f.id=='evnt_truncate').disabled;
|
||||
disabled({evnt_truncate : true});
|
||||
});*/
|
||||
|
||||
});
|
Loading…
Reference in New Issue
Block a user