mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-22 08:46:39 -06:00
Port Types node to react. Fixes #6602
This commit is contained in:
parent
af0a24a5bc
commit
1e07ef13cf
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,7 @@ import { getFieldMetaData } from './FormView';
|
||||
import FieldSet from '../components/FieldSet';
|
||||
|
||||
export default function FieldSetView({
|
||||
value, formErr, schema={}, viewHelperProps, accessPath, dataDispatch, controlClassName, isDataGridForm=false, label}) {
|
||||
value, formErr, schema={}, viewHelperProps, accessPath, dataDispatch, controlClassName, isDataGridForm=false, label, visible}) {
|
||||
const depListener = useContext(DepListenerContext);
|
||||
|
||||
useEffect(()=>{
|
||||
@ -91,6 +91,10 @@ export default function FieldSetView({
|
||||
}
|
||||
});
|
||||
|
||||
if(!visible) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<FieldSet title={label} className={controlClassName}>
|
||||
{viewFields}
|
||||
@ -108,4 +112,7 @@ FieldSetView.propTypes = {
|
||||
dataDispatch: PropTypes.func,
|
||||
controlClassName: CustomPropTypes.className,
|
||||
label: PropTypes.string,
|
||||
visible: PropTypes.oneOfType([
|
||||
PropTypes.bool, PropTypes.func,
|
||||
]),
|
||||
};
|
||||
|
@ -122,7 +122,7 @@ export function getFieldMetaData(field, schema, value, viewHelperProps) {
|
||||
/* The first component of schema view form */
|
||||
export default function FormView({
|
||||
value, formErr, schema={}, viewHelperProps, isNested=false, accessPath, dataDispatch, hasSQLTab,
|
||||
getSQLValue, onTabChange, firstEleRef, className, isDataGridForm=false}) {
|
||||
getSQLValue, onTabChange, firstEleRef, className, isDataGridForm=false, visible}) {
|
||||
let defaultTab = 'General';
|
||||
let tabs = {};
|
||||
let tabsClassname = {};
|
||||
@ -190,7 +190,8 @@ export default function FormView({
|
||||
}
|
||||
tabs[group].push(
|
||||
<FormView key={`nested${tabs[group].length}`} value={value} viewHelperProps={viewHelperProps} formErr={formErr}
|
||||
schema={field.schema} accessPath={accessPath} dataDispatch={dataDispatch} isNested={true} isDataGridForm={isDataGridForm} {...field}/>
|
||||
schema={field.schema} accessPath={accessPath} dataDispatch={dataDispatch} isNested={true} isDataGridForm={isDataGridForm}
|
||||
{...field} visible={visible}/>
|
||||
);
|
||||
} else if(field.type === 'nested-fieldset') {
|
||||
/* Pass on the top schema */
|
||||
@ -203,7 +204,7 @@ export default function FormView({
|
||||
<FieldSetView key={`nested${tabs[group].length}`} value={value} viewHelperProps={viewHelperProps} formErr={formErr}
|
||||
schema={field.schema} accessPath={accessPath} dataDispatch={dataDispatch} isNested={true} isDataGridForm={isDataGridForm}
|
||||
controlClassName={classes.controlRow}
|
||||
{...field} />
|
||||
{...field} visible={visible}/>
|
||||
);
|
||||
} else if(field.type === 'collection') {
|
||||
/* If its a collection, let data grid view handle it */
|
||||
@ -305,6 +306,11 @@ export default function FormView({
|
||||
onTabChange && onTabChange(tabValue, Object.keys(tabs)[tabValue], sqlTabActive);
|
||||
}, [tabValue]);
|
||||
|
||||
/* check whether form is kept hidden by visible prop */
|
||||
if(!_.isUndefined(visible) && !visible) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box height="100%" display="flex" flexDirection="column" className={className} ref={formRef}>
|
||||
@ -343,6 +349,9 @@ FormView.propTypes = {
|
||||
viewHelperProps: PropTypes.object,
|
||||
isNested: PropTypes.bool,
|
||||
isDataGridForm: PropTypes.bool,
|
||||
visible: PropTypes.oneOfType([
|
||||
PropTypes.bool, PropTypes.func,
|
||||
]),
|
||||
accessPath: PropTypes.array.isRequired,
|
||||
dataDispatch: PropTypes.func,
|
||||
hasSQLTab: PropTypes.bool,
|
||||
|
@ -15,6 +15,7 @@ define('pgadmin.browser.messages',['sources/pgadmin'], function(pgAdmin) {
|
||||
|
||||
pgBrowser.messages = {
|
||||
'CANNOT_BE_EMPTY': '\'%s\' cannot be empty.',
|
||||
'MUST_BE_INT': '\'%s\' must be an integer.'
|
||||
};
|
||||
return pgBrowser;
|
||||
});
|
||||
|
457
web/regression/javascript/schema_ui_files/type.ui.spec.js
Normal file
457
web/regression/javascript/schema_ui_files/type.ui.spec.js
Normal file
@ -0,0 +1,457 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 pgAdmin from 'sources/pgadmin';
|
||||
import {messages} from '../fake_messages';
|
||||
import { createMount } from '@material-ui/core/test-utils';
|
||||
import SchemaView from '../../../pgadmin/static/js/SchemaView';
|
||||
import * as nodeAjax from '../../../pgadmin/browser/static/js/node_ajax';
|
||||
import gettext from 'sources/gettext';
|
||||
import { integerValidator } from 'sources/validators';
|
||||
import { getNodePrivilegeRoleSchema } from '../../../pgadmin/browser/server_groups/servers/static/js/privilege.ui';
|
||||
|
||||
import TypeSchema, { EnumerationSchema, getCompositeSchema, getExternalSchema, getRangeSchema, getDataTypeSchema } from '../../../pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.ui';
|
||||
|
||||
describe('TypeSchema', ()=>{
|
||||
|
||||
let mount;
|
||||
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 || {};
|
||||
pgAdmin.Browser.utils.support_ssh_tunnel = true;
|
||||
});
|
||||
|
||||
describe('composite schema describe', () => {
|
||||
|
||||
let compositeCollObj = getCompositeSchema({}, {server: {user: {name: 'postgres'}}}, {});
|
||||
let types = [{ label: '', value: ''}, { label: 'lb1', value: 'numeric[]', length: true, min_val: 10, max_val: 100, precision: true, is_collatable: true}];
|
||||
let collations = [{ label: '', value: ''}, { label: 'lb1', value: 'numeric[]'}];
|
||||
|
||||
it('composite collection', ()=>{
|
||||
|
||||
spyOn(nodeAjax, 'getNodeAjaxOptions').and.returnValue([]);
|
||||
spyOn(compositeCollObj.fieldOptions, 'types').and.returnValue(types);
|
||||
spyOn(compositeCollObj.fieldOptions, 'collations').and.returnValue(collations);
|
||||
|
||||
spyOn(compositeCollObj, 'type_options').and.returnValue(compositeCollObj.fieldOptions.types());
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={compositeCollObj}
|
||||
viewHelperProps={{
|
||||
mode: 'create',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={compositeCollObj}
|
||||
viewHelperProps={{
|
||||
mode: 'edit',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
getInitData={getInitData}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('composite validate', () => {
|
||||
let state = { typtype: 'b' }; //validating for ExternalSchema which is distinguish as r
|
||||
let setError = jasmine.createSpy('setError');
|
||||
|
||||
compositeCollObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('member_name', 'Please specify the value for member name.');
|
||||
|
||||
state.member_name = 'demo_member';
|
||||
compositeCollObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('type', 'Please specify the type.');
|
||||
|
||||
state.type = 'char';
|
||||
state.min_val = 10;
|
||||
state.max_val = 100;
|
||||
state.is_tlength = true;
|
||||
state.tlength = 9;
|
||||
compositeCollObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('tlength', gettext('Length/Precision should not be less than %s.', state.min_val));
|
||||
|
||||
state.tlength = 200;
|
||||
compositeCollObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('tlength', gettext('Length/Precision should not be greater than %s.', state.max_val));
|
||||
|
||||
state.tlength = 'ert';
|
||||
compositeCollObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('tlength', integerValidator('Length/Precision', state.tlength));
|
||||
|
||||
state.tlength = 90;
|
||||
state.is_precision = true;
|
||||
state.precision = 'ert';
|
||||
compositeCollObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('precision', integerValidator('Scale', state.precision));
|
||||
|
||||
state.precision = 9;
|
||||
compositeCollObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('tlength editable', ()=>{
|
||||
compositeCollObj.type_options = types;
|
||||
let editable = _.find(compositeCollObj.fields, (f)=>f.id=='tlength').editable;
|
||||
let status = editable({type: 'numeric[]'});
|
||||
expect(status).toBe(true);
|
||||
});
|
||||
|
||||
it('precision editable', ()=>{
|
||||
compositeCollObj.type_options = types;
|
||||
let editable = _.find(compositeCollObj.fields, (f)=>f.id=='precision').editable;
|
||||
let status = editable({type: 'numeric[]'});
|
||||
expect(status).toBe(true);
|
||||
});
|
||||
|
||||
it('collation editable', ()=>{
|
||||
compositeCollObj.type_options = types;
|
||||
let editable = _.find(compositeCollObj.fields, (f)=>f.id=='collation').editable;
|
||||
let status = editable({type: 'numeric[]'});
|
||||
expect(status).toBe(true);
|
||||
});
|
||||
|
||||
it('setTypeOptions', ()=>{
|
||||
compositeCollObj.setTypeOptions(types);
|
||||
});
|
||||
});
|
||||
|
||||
describe('enumeration schema describe', () => {
|
||||
|
||||
it('enumeration collection', ()=>{
|
||||
|
||||
let enumerationCollObj = new EnumerationSchema(
|
||||
()=>[],
|
||||
()=>[]
|
||||
);
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={enumerationCollObj}
|
||||
viewHelperProps={{
|
||||
mode: 'create',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={enumerationCollObj}
|
||||
viewHelperProps={{
|
||||
mode: 'edit',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
getInitData={getInitData}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
});
|
||||
|
||||
describe('external schema describe', () => {
|
||||
|
||||
let externalCollObj = getExternalSchema({}, {server: {user: {name: 'postgres'}}}, {});
|
||||
|
||||
it('external collection', ()=>{
|
||||
|
||||
spyOn(nodeAjax, 'getNodeAjaxOptions').and.returnValue([]);
|
||||
spyOn(externalCollObj.fieldOptions, 'externalFunctionsList').and.returnValue([{ label: '', value: ''}, { label: 'lb1', cbtype: 'typmodin', value: 'val1'}, { label: 'lb2', cbtype: 'all', value: 'val2'}]);
|
||||
spyOn(externalCollObj.fieldOptions, 'types').and.returnValue([{ label: '', value: ''}]);
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={externalCollObj}
|
||||
viewHelperProps={{
|
||||
mode: 'create',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={externalCollObj}
|
||||
viewHelperProps={{
|
||||
mode: 'edit',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
getInitData={getInitData}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('external validate', () => {
|
||||
let state = { typtype: 'b' }; //validating for ExternalSchema which is distinguish as r
|
||||
let setError = jasmine.createSpy('setError');
|
||||
|
||||
externalCollObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('typinput', 'Input function cannot be empty');
|
||||
|
||||
state.typinput = 'demo_input';
|
||||
externalCollObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('typoutput', 'Output function cannot be empty');
|
||||
});
|
||||
});
|
||||
|
||||
describe('range schema describe', () => {
|
||||
|
||||
let rangeCollObj = getRangeSchema({}, {server: {user: {name: 'postgres'}}}, {});
|
||||
|
||||
it('range collection', ()=>{
|
||||
|
||||
spyOn(nodeAjax, 'getNodeAjaxOptions').and.returnValue([]);
|
||||
spyOn(rangeCollObj.fieldOptions, 'getSubOpClass').and.returnValue([{ label: '', value: ''}, { label: 'lb1', value: 'val1'}]);
|
||||
spyOn(rangeCollObj.fieldOptions, 'getCanonicalFunctions').and.returnValue([{ label: '', value: ''}, { label: 'lb1', value: 'val1'}]);
|
||||
spyOn(rangeCollObj.fieldOptions, 'getSubDiffFunctions').and.returnValue([{ label: '', value: ''}, { label: 'lb1', value: 'val1'}]);
|
||||
spyOn(rangeCollObj.fieldOptions, 'typnameList').and.returnValue([{ label: '', value: ''}, { label: 'lb1', value: 'val1'}]);
|
||||
spyOn(rangeCollObj.fieldOptions, 'collationsList').and.returnValue([{ label: '', value: ''}, { label: 'lb1', value: 'val1'}]);
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={rangeCollObj}
|
||||
viewHelperProps={{
|
||||
mode: 'create',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={rangeCollObj}
|
||||
viewHelperProps={{
|
||||
mode: 'edit',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
getInitData={getInitData}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('range validate', () => {
|
||||
let state = { typtype: 'r' }; //validating for RangeSchema which is distinguish as r
|
||||
let setError = jasmine.createSpy('setError');
|
||||
|
||||
rangeCollObj.validate(state, setError);
|
||||
expect(setError).toHaveBeenCalledWith('typname', 'Subtype cannot be empty');
|
||||
});
|
||||
});
|
||||
|
||||
describe('data type schema describe', () => {
|
||||
|
||||
let dataTypeObj = getDataTypeSchema({}, {server: {user: {name: 'postgres'}}}, {});
|
||||
let types = [{ label: '', value: ''}, { label: 'lb1', value: 'numeric', length: true, min_val: 10, max_val: 100, precision: true}];
|
||||
|
||||
it('data type collection', ()=>{
|
||||
|
||||
spyOn(nodeAjax, 'getNodeAjaxOptions').and.returnValue([]);
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={dataTypeObj}
|
||||
viewHelperProps={{
|
||||
mode: 'create',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={dataTypeObj}
|
||||
viewHelperProps={{
|
||||
mode: 'edit',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
getInitData={getInitData}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('tlength editable', ()=>{
|
||||
dataTypeObj.type_options = types;
|
||||
let editable = _.find(dataTypeObj.fields, (f)=>f.id=='tlength').editable;
|
||||
let status = editable({type: 'numeric', type_options: types});
|
||||
expect(status).toBe(true);
|
||||
});
|
||||
|
||||
it('tlength disabled', ()=>{
|
||||
dataTypeObj.type_options = types;
|
||||
let disabled = _.find(dataTypeObj.fields, (f)=>f.id=='tlength').disabled;
|
||||
let status = disabled({type: 'numeric', type_options: types});
|
||||
expect(status).toBe(false);
|
||||
});
|
||||
|
||||
it('precision editable', ()=>{
|
||||
dataTypeObj.type_options = types;
|
||||
let editable = _.find(dataTypeObj.fields, (f)=>f.id=='precision').editable;
|
||||
let status = editable({type: 'numeric', type_options: types});
|
||||
expect(status).toBe(true);
|
||||
});
|
||||
|
||||
it('precision disabled', ()=>{
|
||||
dataTypeObj.type_options = types;
|
||||
let disabled = _.find(dataTypeObj.fields, (f)=>f.id=='precision').disabled;
|
||||
let status = disabled({type: 'numeric', type_options: types});
|
||||
expect(status).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
let typeSchemaObj = new TypeSchema(
|
||||
(privileges)=>getNodePrivilegeRoleSchema({}, {server: {user: {name: 'postgres'}}}, {}, privileges),
|
||||
()=>getCompositeSchema({}, {server: {user: {name: 'postgres'}}}, {}),
|
||||
()=>getRangeSchema({}, {server: {user: {name: 'postgres'}}}, {}),
|
||||
()=>getExternalSchema({}, {server: {user: {name: 'postgres'}}}, {}),
|
||||
()=>getDataTypeSchema({}, {server: {user: {name: 'postgres'}}}, {}),
|
||||
{
|
||||
roles: ()=>[],
|
||||
schemas: ()=>[{ label: 'pg_demo', value: 'pg_demo'}],
|
||||
server_info: [],
|
||||
node_info: {'schema': []}
|
||||
},
|
||||
{
|
||||
typowner: 'postgres',
|
||||
schema: 'public',
|
||||
typtype: 'c'
|
||||
}
|
||||
);
|
||||
|
||||
it('create', ()=>{
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={typeSchemaObj}
|
||||
viewHelperProps={{
|
||||
mode: 'create',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('edit', ()=>{
|
||||
mount(<SchemaView
|
||||
formType='dialog'
|
||||
schema={typeSchemaObj}
|
||||
viewHelperProps={{
|
||||
mode: 'edit',
|
||||
}}
|
||||
onSave={()=>{}}
|
||||
getInitData={getInitData}
|
||||
onClose={()=>{}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
onDataChange={()=>{}}
|
||||
confirmOnCloseReset={false}
|
||||
hasSQL={false}
|
||||
disableSqlHelp={false}
|
||||
/>);
|
||||
});
|
||||
|
||||
it('properties', ()=>{
|
||||
mount(<SchemaView
|
||||
formType='tab'
|
||||
schema={typeSchemaObj}
|
||||
getInitData={getInitData}
|
||||
viewHelperProps={{
|
||||
mode: 'properties',
|
||||
}}
|
||||
onHelp={()=>{}}
|
||||
onEdit={()=>{}}
|
||||
/>);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user