Port FTS Configurations node to react. Fixes #6638

This commit is contained in:
Akshay Joshi 2021-08-23 19:09:59 +05:30
parent 42eac6f846
commit 4bfffa3806
5 changed files with 331 additions and 502 deletions

View File

@ -7,6 +7,9 @@
//
//////////////////////////////////////////////////////////////
import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../../../../../static/js/node_ajax';
import FTSConfigurationSchema from './fts_configuration.ui';
define('pgadmin.node.fts_configuration', [
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.backgrid',
@ -17,398 +20,6 @@ define('pgadmin.node.fts_configuration', [
schemaChild, schemaChildTreeNode
) {
// Model for tokens control
var TokenModel = pgAdmin.Browser.Node.Model.extend({
idAttribute: 'token',
defaults: {
token: undefined,
dictname: undefined,
},
keys: ['token'],
// Define the schema for the token/dictionary list
schema: [{
id: 'token', label: gettext('Token'), type:'text', group: null,
cellHeaderClasses:'width_percent_50',
editable: false, cell: 'string', url: 'tokens',
},{
id: 'dictname', label: gettext('Dictionaries'), type: 'text', group:null,
cellHeaderClasses:'width_percent_50', editable: true,
cell:Backgrid.Extension.MultiSelectAjaxCell, url: 'dictionaries',
cache_level:'fts_configuration', cache_node:'fts_configuration',
}],
// Validation for token and dictionary list
validate: function() {
// Clear any existing errors.
var msg;
this.errorModel.clear();
var token = this.get('token');
var dictionary = this.get('dictname');
if (_.isNull(token) ||
_.isUndefined(token) ||
String(token).replace(/^\s+|\s+$/g, '') == '') {
msg = gettext('Token cannot be empty.');
this.errorModel.set('token',msg);
return msg;
}
if (_.isNull(dictionary) ||
_.isUndefined(dictionary) ||
String(dictionary).replace(/^\s+|\s+$/g, '') == '') {
msg = gettext('Dictionary name cannot be empty.');
this.errorModel.set('dictname',msg);
return msg;
}
return null;
},
});
// Customized control for token control
var TokenControl = Backform.TokenControl =
Backform.UniqueColCollectionControl.extend({
initialize: function() {
Backform.UniqueColCollectionControl.prototype.initialize.apply(
this, arguments
);
var self = this,
headerSchema = [{
id: 'token', label:'', type:'text', url: 'tokens',
node:'fts_configuration', canAdd: true, 'url_with_id': true,
// Defining control for tokens dropdown control in header
control: Backform.NodeAjaxOptionsControl.extend({
formatter: Backform.NodeAjaxOptionsControl.prototype.formatter,
initialize: function() {
Backform.NodeAjaxOptionsControl.prototype.initialize.apply(
this,
arguments
);
var _self = this,
url = _self.field.get('url') || _self.defaults.url,
m = _self.model.top || _self.model;
/* Fetch the tokens/dict list from '_self' node.
* Here '_self' refers to unique collection control where
* '_self' refers to nodeAjaxOptions control for dictionary
*/
if (url) {
var node = this.field.get('schema_node'),
node_info = this.field.get('node_info'),
full_url = node.generate_url.apply(
node, [
null, url, this.field.get('node_data'),
this.field.get('url_with_id') || false,
node_info,
]),
cache_level = this.field.get('cache_level') || node.type,
cache_node = this.field.get('cache_node');
cache_node = (cache_node &&
pgAdmin.Browser.Nodes[cache_node])
|| node;
// Clear the cache to get the latest dictionaries and parsers.
cache_node.clear_cache(this);
/*
* We needs to check, if we have already cached data
* for this url. If yes - use it, and do not bother about
* fetching it again.
*/
var data = cache_node.cache(url, node_info, cache_level);
// Fetch token/dictionary list
if (this.field.get('version_compatible') &&
(_.isUndefined(data) || _.isNull(data))) {
m.trigger('pgadmin:view:fetching', m, _self.field);
$.ajax({
async: false,
url: full_url,
})
.done(function(res) {
/*
* We will cache this data for short period of time for
* avoiding same calls.
*/
data = cache_node.cache(url,
node_info,
cache_level,
res.data
);
})
.fail(function() {
m.trigger('pgadmin:view:fetch:error', m, _self.field);
});
m.trigger('pgadmin:view:fetched', m, _self.field);
}
// It is feasible that the data may not have been fetched.
data = (data && data.data) || [];
/*
* Transform the data
*/
var transform = (this.field.get('transform')
|| _self.defaults.transform);
if (transform && _.isFunction(transform)) {
_self.field.set('options', transform.bind(_self, data));
} else {
_self.field.set('options', data);
}
}
},
}),
// Select2 control for adding new tokens
select2: {
allowClear: true, width: 'style',
placeholder: gettext('Select token'),
},
first_empty: true,
disabled: function() {
return _.isUndefined(self.model.get('oid'));
},
}],
headerDefaults = {token: null},
// Grid columns backgrid
gridCols = ['token', 'dictname'];
// Creating model for header control which is used to add new tokens
self.headerData = new (Backbone.Model.extend({
defaults: headerDefaults,
schema: headerSchema,
}))({});
// Creating view from header schema in tokens control
var headerGroups = Backform.generateViewSchema(
self.field.get('node_info'), self.headerData, 'create',
self.field.get('schema_node'), self.field.get('node_data')
),
fields = [];
_.each(headerGroups, function(o) {
fields = fields.concat(o.fields);
});
self.headerFields = new Backform.Fields(fields);
// creating grid using grid columns
self.gridSchema = Backform.generateGridColumnsFromModel(
self.field.get('node_info'), self.field.get('model'),
'edit', gridCols, self.field.get('schema_node')
);
// Providing behaviour control functions to header and grid control
self.controls = [];
self.listenTo(self.headerData, 'change', self.headerDataChanged);
self.listenTo(self.headerData, 'select2', self.headerDataChanged);
self.listenTo(self.collection, 'add', self.onAddorRemoveTokens);
self.listenTo(self.collection, 'remove', self.onAddorRemoveTokens);
},
// Template for creating header view
generateHeader: function(data) {
var header = [
'<div class="subnode-header-form">',
' <div class="container-fluid">',
' <div class="row">',
' <div class="col-3">',
' <label class="control-label"><%-token_label%></label>',
' </div>',
' <div class="col-6" header="token"></div>',
' <div class="col-2">',
' <button class="btn btn-sm-sq btn-primary-icon add fa fa-plus" <%=canAdd ? "" : "disabled=\'disabled\'"%> ><span class="sr-only">' + gettext('Add Token') + '</span></button>',
' </div>',
' </div>',
' </div>',
'</div>'].join('\n');
_.extend(data, {
token_label: gettext('Tokens'),
});
var self = this,
headerTmpl = _.template(header),
$header = $(headerTmpl(data)),
controls = this.controls;
self.headerFields.each(function(field) {
var control = new (field.get('control'))({
field: field,
model: self.headerData,
});
$header.find('div[header="' + field.get('name') + '"]').append(
control.render().$el
);
control.$el.find('.control-label').remove();
controls.push(control);
});
// We should not show add button in properties mode
if (data.mode == 'properties') {
$header.find('button.add').remove();
}
// Disable add button in token control in create mode
if(data.mode == 'create') {
$header.find('button.add').attr('disabled', true);
}
self.$header = $header;
return $header;
},
// Providing event handler for add button in header
events: _.extend(
{}, Backform.UniqueColCollectionControl.prototype.events,
{'click button.add': 'addTokens'}
),
// Show token/dictionary grid
showGridControl: function(data) {
var self = this,
titleTmpl = _.template('<div class=\'subnode-header\'></div>'),
$gridBody = $('<div></div>', {
class:'pgadmin-control-group backgrid form-group col-12 object subnode',
}).append(
titleTmpl({label: data.label})
);
$gridBody.append(self.generateHeader(data));
var gridColumns = _.clone(this.gridSchema.columns);
// Insert Delete Cell into Grid
if (data.disabled == false && data.canDelete) {
gridColumns.unshift({
name: 'pg-backform-delete', label: '',
cell: Backgrid.Extension.DeleteCell,
editable: false, cell_priority: -1,
});
}
if (self.grid) {
self.grid.remove();
self.grid = null;
}
// Initialize a new Grid instance
var grid = self.grid = new Backgrid.Grid({
columns: gridColumns,
collection: self.collection,
className: 'backgrid table-bordered',
});
self.$grid = grid.render().$el;
$gridBody.append(self.$grid);
// Find selected dictionaries in grid and show it all together
setTimeout(function() {
self.headerData.set({
'token': self.$header.find(
'div[header="token"] select'
).val(),
}, {silent:true}
);
}, 10);
// Render node grid
return $gridBody;
},
// When user change the header control to add a new token
headerDataChanged: function() {
var self = this,
data = this.headerData.toJSON(),
inSelected = (_.isEmpty(data) || _.isUndefined(data));
if (!self.$header) {
return;
}
self.$header.find('button.add').prop('disabled', inSelected);
},
// Get called when user click on add button header
addTokens: function(ev) {
ev.preventDefault();
var self = this,
token = self.headerData.get('token');
if (token && token != '') {
var coll = self.model.get(self.field.get('name')),
m = new (self.field.get('model'))(
self.headerData.toJSON(), {
silent: true, top: self.model.top,
collection: coll, handler: coll,
}),
checkVars = ['token'],
idx = -1;
// Find if token exists in grid
self.collection.each(function(local_model) {
_.each(checkVars, function(v) {
var val = local_model.get(v);
if(val == token) {
idx = coll.indexOf(local_model);
}
});
});
// remove 'm' if duplicate value found.
if (idx == -1) {
coll.add(m);
idx = coll.indexOf(m);
}
self.$grid.find('.new').removeClass('new');
var newRow = self.grid.body.rows[idx].$el;
newRow.addClass('new');
$(newRow).pgMakeVisible('backform-tab');
}
return false;
},
// When user delete token/dictionary entry from grid
onAddorRemoveTokens: function() {
var self = this;
/*
* Wait for collection to be updated before checking for the button to
* be enabled, or not.
*/
setTimeout(function() {
self.collection.trigger('pgadmin:tokens:updated', self.collection);
self.headerDataChanged();
}, 10);
},
// When control is about to destroy
remove: function() {
/*
* Stop listening the events registered by this control.
*/
this.stopListening(this.headerData, 'change', this.headerDataChanged);
this.listenTo(this.headerData, 'select2', this.headerDataChanged);
this.listenTo(this.collection, 'remove', this.onAddorRemoveTokens);
// Remove header controls.
_.each(this.controls, function(control) {
control.remove();
});
TokenControl.__super__.remove.apply(this, arguments);
// Remove the header model
delete (this.headerData);
},
});
// Extend the collection class for FTS Configuration
if (!pgBrowser.Nodes['coll-fts_configuration']) {
pgAdmin.Browser.Nodes['coll-fts_configuration'] =
@ -463,19 +74,30 @@ define('pgadmin.node.fts_configuration', [
}]);
},
getSchema: function(treeNodeInfo, itemNodeData) {
return new FTSConfigurationSchema(
{
role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData),
schema: ()=>getNodeListById(pgBrowser.Nodes['schema'], treeNodeInfo, itemNodeData),
parsers: ()=>getNodeAjaxOptions('parsers', this, treeNodeInfo, itemNodeData),
copyConfig: ()=>getNodeAjaxOptions('copyConfig', this, treeNodeInfo, itemNodeData),
tokens: ()=>getNodeAjaxOptions('tokens', this, treeNodeInfo, itemNodeData, {urlWithId: true}),
dictionaries: ()=>getNodeAjaxOptions('dictionaries', this, treeNodeInfo, itemNodeData, {
cacheLevel: 'fts_configuration',
cacheNode: 'fts_configuration'
}),
},
{
owner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name,
schema: itemNodeData._id,
}
);
},
// Defining model for FTS Configuration node
model: pgAdmin.Browser.Node.Model.extend({
idAttribute: 'oid',
defaults: {
name: undefined, // FTS Configuration name
owner: undefined, // FTS Configuration owner
is_sys_obj: undefined, // Is system object
description: undefined, // Comment on FTS Configuration
schema: undefined, // Schema name FTS Configuration belongs to
prsname: undefined, // FTS parser list for FTS Configuration node
copy_config: undefined, // FTS configuration list to copy from
tokens: undefined, // token/dictionary pair list for node
},
initialize: function(attrs, opts) {
var isNew = (_.size(attrs) === 0);
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
@ -492,106 +114,10 @@ define('pgadmin.node.fts_configuration', [
schema: [{
id: 'name', label: gettext('Name'), cell: 'string',
type: 'text', cellHeaderClasses: 'width_percent_50',
},{
id: 'oid', label: gettext('OID'), cell: 'string',
editable: false, type: 'text', mode:['properties'],
},{
id: 'owner', label: gettext('Owner'), cell: 'string',
type: 'text', mode: ['properties', 'edit','create'], node: 'role',
control: Backform.NodeListByNameControl, select2: { allowClear: false },
},{
id: 'schema', label: gettext('Schema'), cell: 'string',
type: 'text', mode: ['create','edit'], node: 'schema',
control: 'node-list-by-id', cache_node: 'database',
cache_level: 'database',
},{
id: 'is_sys_obj', label: gettext('System FTS configuration?'),
cell:'boolean', type: 'switch', mode: ['properties'],
},{
}, {
id: 'description', label: gettext('Comment'), cell: 'string',
type: 'multiline', cellHeaderClasses: 'width_percent_50',
},{
id: 'prsname', label: gettext('Parser'),type: 'text',
url: 'parsers', first_empty: true,
group: gettext('Definition'), control: 'node-ajax-options',
deps: ['copy_config'],
//disable parser when user select copy_config manually and vica-versa
disabled: function(m) {
var copy_config = m.get('copy_config');
return (_.isNull(copy_config) ||
_.isUndefined(copy_config) ||
copy_config === '') ? false : true;
},
readonly: function(m) {return !m.isNew();},
},{
id: 'copy_config', label: gettext('Copy config'),type: 'text',
mode: ['create'], group: gettext('Definition'),
control: 'node-ajax-options', url: 'copyConfig', deps: ['prsname'],
//disable copy_config when user select parser manually and vica-versa
disabled: function(m) {
var parser = m.get('prsname');
return (_.isNull(parser) ||
_.isUndefined(parser) ||
parser === '') ? false : true;
},
readonly: function(m) {return !m.isNew();},
},{
id: 'tokens', label: gettext('Tokens'), type: 'collection',
group: gettext('Tokens'), control: TokenControl,
model: TokenModel, columns: ['token', 'dictionary'],
uniqueCol : ['token'], mode: ['create','edit'],
canAdd: true, canEdit: false, canDelete: true,
}],
/*
* Triggers control specific error messages for name,
* copy_config/parser and schema, if any one of them is not specified
* while creating new fts configuration
*/
validate: function() {
var msg;
var name = this.get('name');
var parser = this.get('prsname');
var copy_config_or_parser = !(parser === '' ||
_.isUndefined(parser) ||
_.isNull(parser)) ?
this.get('prsname') : this.get('copy_config');
var schema = this.get('schema');
// Clear the existing error model
this.errorModel.clear();
this.trigger('on-status-clear');
// Validate the name
if (_.isUndefined(name) ||
_.isNull(name) ||
String(name).replace(/^\s+|\s+$/g, '') == '') {
msg = gettext('Name must be specified.');
this.errorModel.set('name', msg);
return msg;
}
// Validate parser or copy_config
else if (_.isUndefined(copy_config_or_parser) ||
_.isNull(copy_config_or_parser) ||
String(copy_config_or_parser).replace(/^\s+|\s+$/g, '') == '') {
msg = gettext('Select parser or configuration to copy.');
this.errorModel.set('parser', msg);
return msg;
}
// Validate schema
else if (_.isUndefined(schema) ||
_.isNull(schema) ||
String(schema).replace(/^\s+|\s+$/g, '') == '') {
msg = gettext('Schema must be selected.');
this.errorModel.set('schema', msg);
return msg;
}
return null;
},
}),
});
}

View File

@ -0,0 +1,182 @@
/////////////////////////////////////////////////////////////
//
// 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 DataGridViewWithHeaderForm from 'sources/helpers/DataGridViewWithHeaderForm';
import { isEmptyString } from '../../../../../../../../static/js/validators';
class TokenHeaderSchema extends BaseUISchema {
constructor(tokenOptions) {
super({
token: undefined,
});
this.tokenOptions = tokenOptions;
this.isNewFTSConf = true;
}
addDisabled() {
return this.isNewFTSConf;
}
getNewData(data) {
return {
token: data.token,
dictname: [],
};
}
get baseFields() {
let obj = this;
return [{
id: 'token', label: gettext('Tokens'), type:'select', editable: false,
options: this.tokenOptions, disabled: function() { return obj.isNewFTSConf; }
}];
}
}
class TokenSchema extends BaseUISchema {
constructor(dictOptions) {
super({
token: undefined,
dictname: undefined,
});
this.dictOptions = dictOptions;
}
get baseFields() {
return [
{
id: 'token', label: gettext('Token'), type:'text',
editable: false, cell: '', minWidth: 150, noEmpty: true,
}, {
id: 'dictname', label: gettext('Dictionaries'),
editable: true, controlProps: {multiple: true}, cell:'select',
options: this.dictOptions, minWidth: 260, noEmpty: true,
}
];
}
}
export default class FTSConfigurationSchema extends BaseUISchema {
constructor(fieldOptions={}, initValues) {
super({
name: undefined, // FTS Configuration name
owner: undefined, // FTS Configuration owner
is_sys_obj: undefined, // Is system object
description: undefined, // Comment on FTS Configuration
schema: undefined, // Schema name FTS Configuration belongs to
prsname: undefined, // FTS parser list for FTS Configuration node
copy_config: undefined, // FTS configuration list to copy from
tokens: undefined, // token/dictionary pair list for node
...initValues
});
this.fieldOptions = {
role: [],
schema: [],
parsers: [],
copyConfig: [],
tokens: [],
dictionaries: [],
...fieldOptions,
};
this.tokHeaderSchema = new TokenHeaderSchema(this.fieldOptions.tokens);
this.tokColumnSchema = new TokenSchema(this.fieldOptions.dictionaries);
}
get idAttribute() {
return 'oid';
}
initialise(data) {
this.tokHeaderSchema.isNewFTSConf = this.isNew(data);
}
get baseFields() {
let obj = this;
return [
{
id: 'name', label: gettext('Name'), cell: 'text', type: 'text',
noEmpty: true,
}, {
id: 'oid', label: gettext('OID'), cell: 'text',
editable: false, type: 'text', mode:['properties'],
}, {
id: 'owner', label: gettext('Owner'), cell: 'text',
editable: false, type: 'select', options: this.fieldOptions.role,
mode: ['properties', 'edit','create'], noEmpty: true,
}, {
id: 'schema', label: gettext('Schema'),
editable: false, type: 'select', options: this.fieldOptions.schema,
mode: ['create', 'edit'], noEmpty: true,
}, {
id: 'is_sys_obj', label: gettext('System FTS configuration?'),
cell:'boolean', type: 'switch', mode: ['properties'],
}, {
id: 'description', label: gettext('Comment'), cell: 'text',
type: 'multiline',
}, {
id: 'prsname', label: gettext('Parser'),
editable: false, type: 'select', group: gettext('Definition'),
deps: ['copy_config'],
options: this.fieldOptions.parsers,
//disable parser when user select copy_config manually and vica-versa
disabled: function(state) {
var copy_config = state.copy_config;
return (_.isNull(copy_config) ||
_.isUndefined(copy_config) ||
copy_config === '') ? false : true;
},
readonly: function(state) { return !obj.isNew(state); },
}, {
id: 'copy_config', label: gettext('Copy config'),
editable: false, type: 'select', group: gettext('Definition'),
mode: ['create'], deps: ['prsname'],
options: this.fieldOptions.copyConfig,
//disable copy_config when user select parser manually and vica-versa
disabled: function(state) {
var parser = state.prsname;
return (_.isNull(parser) ||
_.isUndefined(parser) ||
parser === '') ? false : true;
},
readonly: function(state) { return !obj.isNew(state); },
}, {
id: 'tokens', label: '', type: 'collection',
group: gettext('Tokens'), mode: ['create','edit'],
editable: false, schema: this.tokColumnSchema,
headerSchema: this.tokHeaderSchema,
headerVisible: function() { return true;},
CustomControl: DataGridViewWithHeaderForm,
uniqueCol : ['token'],
canAdd: true, canEdit: false, canDelete: true,
}
];
}
validate(state, setError) {
let errmsg = null,
parser = state.prsname,
config = state.copy_config;
let copy_config_or_parser = !(parser === '' || _.isUndefined(parser)
|| _.isNull(parser)) ? parser : config;
if(isEmptyString(copy_config_or_parser)) {
errmsg = gettext('Select parser or configuration to copy.');
setError('prsname', errmsg);
return true;
} else {
setError('prsname', null);
}
}
}

View File

@ -24,7 +24,7 @@ import {FormFooterMessage, MESSAGE_TYPE } from 'sources/components/FormComponent
import Theme from 'sources/Theme';
import { PrimaryButton, DefaultButton, PgIconButton } from 'sources/components/Buttons';
import Loader from 'sources/components/Loader';
import { minMaxValidator, numberValidator, integerValidator, emptyValidator, checkUniqueCol } from '../validators';
import { minMaxValidator, numberValidator, integerValidator, emptyValidator, checkUniqueCol, isEmptyString} from '../validators';
import { MappedFormControl } from './MappedControl';
import gettext from 'sources/gettext';
import BaseUISchema from 'sources/SchemaView/base_schema.ui';
@ -225,7 +225,7 @@ function validateSchema(schema, sessData, setError) {
if(dupInd > 0) {
let uniqueColNames = _.filter(field.schema.fields, (uf)=>field.uniqueCol.indexOf(uf.id) > -1)
.map((uf)=>uf.label).join(', ');
if (_.isUndefined(field.label) || _.isNull(field.label)) {
if (isEmptyString(field.label)) {
setError(field.uniqueCol[0], gettext('%s must be unique.', uniqueColNames));
} else {
setError(field.uniqueCol[0], gettext('%s in %s must be unique.', uniqueColNames, field.label));

View File

@ -53,7 +53,7 @@ export default function DataGridViewWithHeaderForm(props) {
return (
<Box className={containerClassName}>
<Box className={classes.formBorder}>
<DataGridHeader label={props.label} />
{props.label && <DataGridHeader label={props.label} />}
{headerVisible && <Box className={classes.form}>
<SchemaView
formType={'dialog'}

View File

@ -0,0 +1,121 @@
/////////////////////////////////////////////////////////////
//
// 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 FTSConfigurationSchema from '../../../pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.ui';
describe('FTSConfigurationSchema', ()=>{
let mount;
let schemaObj = new FTSConfigurationSchema(
{
role: ()=>[],
schema: ()=>[],
parsers: ()=>[],
copyConfig: ()=>[],
tokens: ()=>[],
dictionaries: ()=>[],
},
{
owner: 'postgres',
schema: 'public',
}
);
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}
disableDialogHelp={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}
disableDialogHelp={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.prsname = '';
state.copy_config = '';
schemaObj.validate(state, setError);
expect(setError).toHaveBeenCalledWith('prsname', 'Select parser or configuration to copy.');
state.prsname = 'default';
schemaObj.validate(state, setError);
expect(setError).toHaveBeenCalledWith('prsname', null);
});
});