Port Extension node to react. Fixes #6582

pull/58/head
Yogesh Mahajan 2021-07-06 14:37:51 +05:30 committed by Akshay Joshi
parent 3786954a65
commit 5a27961102
3 changed files with 304 additions and 1 deletions

View File

@ -7,6 +7,10 @@
//
//////////////////////////////////////////////////////////////
import { getNodeAjaxOptions,getNodeListByName } from '../../../../../../static/js/node_ajax';
import ExtensionsSchema from './extension.ui';
define('pgadmin.node.extension', [
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
'sources/pgadmin', 'pgadmin.browser',
@ -216,7 +220,6 @@ define('pgadmin.node.extension', [
var res = [],
control = cell || this,
extension = control.model.get('name');
_.each(data, function(dt) {
if(dt.name == extension) {
if(dt.version && _.isArray(dt.version)) {
@ -258,6 +261,25 @@ define('pgadmin.node.extension', [
return null;
},
}),
getSchema: (treeNodeInfo, itemNodeData)=>{
let nodeObj = pgAdmin.Browser.Nodes['extension'];
let schema = new ExtensionsSchema(
{
extensionsList:()=>getNodeAjaxOptions('avails', nodeObj, treeNodeInfo, itemNodeData, { cacheLevel: 'server'},
(data)=>{
let res = [];
if (data && _.isArray(data)) {
_.each(data, function(d) {
res.push({label: d.name, value: d.name, data:d});
});
}
return res;
}),
schemaList:()=>getNodeListByName('schema', treeNodeInfo, itemNodeData)
}
);
return schema;
}
});
}

View File

@ -0,0 +1,174 @@
/////////////////////////////////////////////////////////////
//
// 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 default class ExtensionsSchema extends BaseUISchema {
constructor(fieldOptions = {}) {
super({
name: null,
oid: undefined,
version: '',
schema: '',
relocatable: false,
is_sys_obj: false,
comment: null,
});
fieldOptions = {
extensionsList: [],
schemaList: [],
...fieldOptions,
};
this.extensionsList = fieldOptions.extensionsList;
this.schemaList = fieldOptions.schemaList;
}
get idAttribute() {
return 'oid';
}
get baseFields() {
let obj = this;
return [
{
id: 'name', label: gettext('Name'),
mode: ['properties', 'create', 'edit'],
editable: false,
readonly: function (state) {
return !obj.isNew(state);
},
type: (state) => {
return {
type: 'select',
options: obj.extensionsList,
optionsLoaded: (options) => { obj.extensionData = options; },
controlProps: {
allowClear: false,
filter: (options) => {
let res = [];
if (state && obj.isNew(state)) {
options.forEach((option) => {
if (option.data['installed_version'] === null) {
res.push({ label: option.label, value: option.value });
}
});
} else {
res = options;
}
return res;
}
}
};
},
depChange: (state) => {
let extensionData = obj.extensionData;
if (state && obj.isNew(state)) {
extensionData.forEach((option) => {
if (state.name == option.data['name']) {
let dt = option.data;
state.version = '';
state.relocatable = (
(!_.isNull(dt.relocatable[0]) &&
!_.isUndefined(dt.relocatable[0])) ? dt.relocatable[0] : ''
);
}
});
}
}
},
{
id: 'oid', label: gettext('OID'), type: 'text',
mode: ['properties'],
},
{
id: 'schema', label: gettext('Schema'), type: 'select',
mode: ['properties', 'create', 'edit'], group: gettext('Definition'),
first_empty: true, deps: ['name'],
controlProps: { allowClear: false }, editable: false,
options: this.schemaList,
disabled: function (state) {
/*
* enable or disable schema field if model's relocatable
* attribute is True or False
*/
return (!state.relocatable);
},
},
{
id: 'relocatable', label: gettext('Relocatable?'), cell: 'switch',
group: gettext('Definition'), type: 'switch', mode: ['properties'],
deps: ['name'],
},
{
id: 'version', label: gettext('Version'),
mode: ['properties', 'create', 'edit'], group: gettext('Definition'),
first_empty: true,
deps: ['name'],
type: (state) => {
return {
type: 'select',
options: this.extensionsList,
controlProps: {
allowClear: false,
filter: (options) => {
let res = [];
if (state) {
if (state.name) {
options.forEach((option) => {
if (state.name == option.data['name']) {
let dt = option.data;
if (dt.version && _.isArray(dt.version)) {
_.each(dt.version, function (v) {
res.push({ label: v, value: v });
});
}
}
});
}
} else {
options.forEach((option) => {
let dt = option.data;
if (dt.version && _.isArray(dt.version)) {
_.each(dt.version, function (v) {
res.push({ label: v, value: v });
});
}
});
}
return res;
}
}
};
},
}, {
id: 'is_sys_obj', label: gettext('System extension?'),
cell: 'boolean', type: 'switch', mode: ['properties'],
}, {
id: 'comment', label: gettext('Comment'), cell: 'string',
type: 'multiline', readonly: true,
},
];
}
validate(state, setError) {
let errmsg = null;
if (isEmptyString(state.name)) {
errmsg = gettext('Name cannot be empty.');
setError('name', errmsg);
return true;
} else {
errmsg = null;
setError('name', errmsg);
}
return false;
}
}

View File

@ -0,0 +1,107 @@
/////////////////////////////////////////////////////////////
//
// 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 ExtensionsSchema from '../../../pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.ui';
describe('ExtensionSchema', ()=>{
let mount;
let schemaObj = new ExtensionsSchema(
{
extensionsList: ()=>[],
schemaList: ()=>[],
}
);
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: '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('validate', ()=>{
let state = {};
let setError = jasmine.createSpy('setError');
state.name = null;
schemaObj.validate(state, setError);
expect(setError).toHaveBeenCalledWith('name', 'Name cannot be empty.');
});
});