mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Port Extension node to react. Fixes #6582
This commit is contained in:
committed by
Akshay Joshi
parent
3786954a65
commit
5a27961102
@@ -7,6 +7,10 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
import { getNodeAjaxOptions,getNodeListByName } from '../../../../../../static/js/node_ajax';
|
||||||
|
import ExtensionsSchema from './extension.ui';
|
||||||
|
|
||||||
define('pgadmin.node.extension', [
|
define('pgadmin.node.extension', [
|
||||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||||
'sources/pgadmin', 'pgadmin.browser',
|
'sources/pgadmin', 'pgadmin.browser',
|
||||||
@@ -216,7 +220,6 @@ define('pgadmin.node.extension', [
|
|||||||
var res = [],
|
var res = [],
|
||||||
control = cell || this,
|
control = cell || this,
|
||||||
extension = control.model.get('name');
|
extension = control.model.get('name');
|
||||||
|
|
||||||
_.each(data, function(dt) {
|
_.each(data, function(dt) {
|
||||||
if(dt.name == extension) {
|
if(dt.name == extension) {
|
||||||
if(dt.version && _.isArray(dt.version)) {
|
if(dt.version && _.isArray(dt.version)) {
|
||||||
@@ -258,6 +261,25 @@ define('pgadmin.node.extension', [
|
|||||||
return null;
|
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;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
107
web/regression/javascript/schema_ui_files/extension.ui.spec.js
Normal file
107
web/regression/javascript/schema_ui_files/extension.ui.spec.js
Normal 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.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Reference in New Issue
Block a user