From bb5e2b98e9c9fe58c37e4dd367e531a464397038 Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Thu, 12 Aug 2021 12:39:23 +0530 Subject: [PATCH] Stability and bug fixes in schemaview react framework. --- .../static/js/SchemaView/DataGridView.jsx | 18 +++--- web/pgadmin/static/js/SchemaView/FormView.jsx | 35 ++++++----- .../static/js/SchemaView/base_schema.ui.js | 5 ++ web/pgadmin/static/js/SchemaView/index.jsx | 59 +++++++++++-------- .../js/helpers/DataGridViewWithHeaderForm.jsx | 17 +++--- 5 files changed, 76 insertions(+), 58 deletions(-) diff --git a/web/pgadmin/static/js/SchemaView/DataGridView.jsx b/web/pgadmin/static/js/SchemaView/DataGridView.jsx index 6d3c1893d..90f582b15 100644 --- a/web/pgadmin/static/js/SchemaView/DataGridView.jsx +++ b/web/pgadmin/static/js/SchemaView/DataGridView.jsx @@ -179,19 +179,19 @@ function DataTableRow({row, totalRows, isResizing, schema, schemaRef, accessPath schema.fields.forEach((field)=>{ /* Self change is also dep change */ if(field.depChange) { - depListener.addDepListener(accessPath.concat(field.id), accessPath.concat(field.id), field.depChange); + depListener?.addDepListener(accessPath.concat(field.id), accessPath.concat(field.id), field.depChange); } (evalFunc(null, field.deps) || []).forEach((dep)=>{ let source = accessPath.concat(dep); if(_.isArray(dep)) { source = dep; } - depListener.addDepListener(source, accessPath.concat(field.id), field.depChange); + depListener?.addDepListener(source, accessPath.concat(field.id), field.depChange); }); }); return ()=>{ /* Cleanup the listeners when unmounting */ - depListener.removeDepListener(accessPath); + depListener?.removeDepListener(accessPath); }; }, []); @@ -324,7 +324,7 @@ export default function DataGridView({ return 0; }).map((field)=>{ let colInfo = { - Header: field.label, + Header: field.label||<> , accessor: field.id, field: field, resizable: true, @@ -386,12 +386,8 @@ export default function DataGridView({ ); const onAddClick = useCallback(()=>{ - if(props.canAddRow) { - let state = schemaRef.current.top ? schemaRef.current.top.sessData : schemaRef.current.sessData; - let canAddRow = evalFunc(schemaRef.current, props.canAddRow, state || {}); - if(!canAddRow) { - return; - } + if(!props.canAddRow) { + return; } let newRow = schemaRef.current.getNewData(); @@ -490,7 +486,7 @@ DataGridView.propTypes = { formErr: PropTypes.object, schema: CustomPropTypes.schemaUI, accessPath: PropTypes.array.isRequired, - dataDispatch: PropTypes.func.isRequired, + dataDispatch: PropTypes.func, containerClassName: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), fixedRows: PropTypes.oneOfType([PropTypes.array, PropTypes.instanceOf(Promise), PropTypes.func]), columns: PropTypes.array, diff --git a/web/pgadmin/static/js/SchemaView/FormView.jsx b/web/pgadmin/static/js/SchemaView/FormView.jsx index d00ac6240..56c748a4c 100644 --- a/web/pgadmin/static/js/SchemaView/FormView.jsx +++ b/web/pgadmin/static/js/SchemaView/FormView.jsx @@ -80,6 +80,7 @@ export function getFieldMetaData(field, schema, value, viewHelperProps, onlyMode canEdit: false, canDelete: true, modeSupported: true, + canAddRow: true, }; if(field.mode) { @@ -115,11 +116,11 @@ export function getFieldMetaData(field, schema, value, viewHelperProps, onlyMode retData.disabled = Boolean(evalFunc(schema, disabled, value)); - let {canAdd, canEdit, canDelete } = field; + let {canAdd, canEdit, canDelete, canAddRow } = field; retData.canAdd = _.isUndefined(canAdd) ? retData.canAdd : evalFunc(schema, canAdd, value); retData.canEdit = _.isUndefined(canEdit) ? retData.canEdit : evalFunc(schema, canEdit, value); retData.canDelete = _.isUndefined(canDelete) ? retData.canDelete : evalFunc(schema, canDelete, value); - + retData.canAddRow = _.isUndefined(canAddRow) ? retData.canAddRow : evalFunc(schema, canAddRow, value); return retData; } @@ -137,6 +138,7 @@ export default function FormView({ const onScreenTracker = useRef(false); const depListener = useContext(DepListenerContext); let groupLabels = {}; + const schemaRef = useRef(schema); let isOnScreen = useOnScreen(formRef); if(isOnScreen) { @@ -153,7 +155,7 @@ export default function FormView({ useEffect(()=>{ /* Calculate the fields which depends on the current field */ if(!isDataGridForm) { - schema.fields.forEach((field)=>{ + schemaRef.current.fields.forEach((field)=>{ /* Self change is also dep change */ if(field.depChange || field.deferredDepChange) { depListener.addDepListener(accessPath.concat(field.id), accessPath.concat(field.id), field.depChange, field.deferredDepChange); @@ -178,8 +180,8 @@ export default function FormView({ let fullTabs = []; /* Prepare the array of components based on the types */ - schema.fields.forEach((field)=>{ - let {visible, disabled, readonly, canAdd, canEdit, canDelete, modeSupported} = + schemaRef.current.fields.forEach((field)=>{ + let {visible, disabled, readonly, canAdd, canEdit, canDelete, canAddRow, modeSupported} = getFieldMetaData(field, schema, value, viewHelperProps); if(modeSupported) { @@ -192,7 +194,7 @@ export default function FormView({ if(field.type === 'nested-tab') { /* Pass on the top schema */ if(isNested) { - field.schema.top = schema.top; + field.schema.top = schemaRef.current.top; } else { field.schema.top = schema; } @@ -204,7 +206,7 @@ export default function FormView({ } else if(field.type === 'nested-fieldset') { /* Pass on the top schema */ if(isNested) { - field.schema.top = schema.top; + field.schema.top = schemaRef.current.top; } else { field.schema.top = schema; } @@ -219,9 +221,9 @@ export default function FormView({ let depsMap = [value[field.id]]; /* Pass on the top schema */ if(isNested) { - field.schema.top = schema.top; + field.schema.top = schemaRef.current.top; } else { - field.schema.top = schema; + field.schema.top = schemaRef.current; } depsMap.push(canAdd, canEdit, canDelete, visible); @@ -235,7 +237,7 @@ export default function FormView({ key: field.id, value: value[field.id], viewHelperProps: viewHelperProps, formErr: formErr, schema: field.schema, accessPath: accessPath.concat(field.id), dataDispatch: dataDispatch, containerClassName: classes.controlRow, ...field, canAdd: canAdd, canEdit: canEdit, canDelete: canDelete, - visible: visible, + visible: visible, canAddRow: canAddRow, }; if(CustomControl) { @@ -246,7 +248,7 @@ export default function FormView({ } else if(field.type === 'group') { groupLabels[field.id] = field.label; if(!visible) { - schema.filterGroups.push(field.label); + schemaRef.current.filterGroups.push(field.label); } } else { /* Its a form control */ @@ -330,6 +332,7 @@ export default function FormView({ return <>; } + let finalTabs = _.pickBy(tabs, (v, tabName)=>schemaRef.current.filterGroups.indexOf(tabName) <= -1); if(isTabView) { return ( <> @@ -345,16 +348,16 @@ export default function FormView({ scrollButtons="auto" action={(ref)=>ref && ref.updateIndicator()} > - {Object.keys(tabs).map((tabName)=>{ + {Object.keys(finalTabs).map((tabName)=>{ return ; })} - {Object.keys(tabs).map((tabName, i)=>{ + {Object.keys(finalTabs).map((tabName, i)=>{ return ( - {tabs[tabName]} + {finalTabs[tabName]} ); })} @@ -364,9 +367,9 @@ export default function FormView({ return ( <> - {Object.keys(tabs).map((tabName)=>{ + {Object.keys(finalTabs).map((tabName)=>{ return ( - <>{tabs[tabName]} + <>{finalTabs[tabName]} ); })} diff --git a/web/pgadmin/static/js/SchemaView/base_schema.ui.js b/web/pgadmin/static/js/SchemaView/base_schema.ui.js index ebff0853e..591b0e627 100644 --- a/web/pgadmin/static/js/SchemaView/base_schema.ui.js +++ b/web/pgadmin/static/js/SchemaView/base_schema.ui.js @@ -86,6 +86,11 @@ export default class BaseUISchema { }); } + initialise() { + /* Called when initial data loaded */ + return; + } + /* Check if current data is new or existing */ isNew(state) { if(_.isUndefined(state)) { diff --git a/web/pgadmin/static/js/SchemaView/index.jsx b/web/pgadmin/static/js/SchemaView/index.jsx index c033a882f..48d0bcb78 100644 --- a/web/pgadmin/static/js/SchemaView/index.jsx +++ b/web/pgadmin/static/js/SchemaView/index.jsx @@ -30,12 +30,12 @@ import gettext from 'sources/gettext'; import BaseUISchema from 'sources/SchemaView/base_schema.ui'; import FormView, { getFieldMetaData } from './FormView'; import { pgAlertify } from '../helpers/legacyConnector'; -import { evalFunc } from 'sources/utils'; import PropTypes from 'prop-types'; import CustomPropTypes from '../custom_prop_types'; import { parseApiError } from '../api_instance'; import DepListener, {DepListenerContext} from './DepListener'; import FieldSetView from './FieldSetView'; +import DataGridView from './DataGridView'; const useDialogStyles = makeStyles((theme)=>({ root: { @@ -475,6 +475,7 @@ function SchemaDialogView({ data = data || {}; /* Set the origData to incoming data, useful for comparing and reset */ schema.origData = prepareData(data || {}); + schema.initialise(data); sessDispatch({ type: SCHEMA_STATE_ACTIONS.INIT, payload: schema.origData, @@ -498,6 +499,15 @@ function SchemaDialogView({ return ()=>clearTimeout(focusTimeout); }, []); + useEffect(()=>{ + /* If reset key changes, reset the form */ + sessDispatch({ + type: SCHEMA_STATE_ACTIONS.INIT, + payload: schema.origData, + }); + return true; + }, [props.resetKey]); + const onResetClick = ()=>{ const resetIt = ()=>{ sessDispatch({ @@ -689,6 +699,7 @@ SchemaDialogView.propTypes = { disableSqlHelp: PropTypes.bool, disableDialogHelp: PropTypes.bool, showFooter: PropTypes.bool, + resetKey: PropTypes.any, }; const usePropsStyles = makeStyles((theme)=>({ @@ -735,29 +746,13 @@ function SchemaPropertiesView({ }, [getInitData]); /* A simple loop to get all the controls for the fields */ - schema.fields.forEach((f)=>{ - let {visible, disabled, group, readonly, ...field} = f; + schema.fields.forEach((field)=>{ + let {group} = field; + let {visible, disabled, readonly, modeSupported} = getFieldMetaData(field, schema, origData, viewHelperProps); group = group || defaultTab; - let verInLimit = (_.isUndefined(viewHelperProps.serverInfo) ? true : - ((_.isUndefined(field.server_type) ? true : - (viewHelperProps.serverInfo.type in field.server_type)) && - (_.isUndefined(field.min_version) ? true : - (viewHelperProps.serverInfo.version >= field.min_version)) && - (_.isUndefined(field.max_version) ? true : - (viewHelperProps.serverInfo.version <= field.max_version)))); - - let _visible = true; - if(field.mode) { - _visible = (field.mode.indexOf(viewHelperProps.mode) > -1); - } - if(_visible && visible) { - _visible = evalFunc(schema, visible, origData); - } - - disabled = evalFunc(schema, disabled, origData); readonly = true; - if(_visible && verInLimit) { + if(visible && modeSupported) { if(!tabs[group]) tabs[group] = []; if(field && field.type === 'nested-fieldset') { tabs[group].push( @@ -769,9 +764,27 @@ function SchemaPropertiesView({ accessPath={[]} formErr={{}} controlClassName={classes.controlRow} + visible={visible} {...field} /> ); - }else{ + } else if(field.type === 'collection') { + tabs[group].push( + + ); + } else { tabs[group].push( diff --git a/web/pgadmin/static/js/helpers/DataGridViewWithHeaderForm.jsx b/web/pgadmin/static/js/helpers/DataGridViewWithHeaderForm.jsx index c1cd045e9..07435be4f 100644 --- a/web/pgadmin/static/js/helpers/DataGridViewWithHeaderForm.jsx +++ b/web/pgadmin/static/js/helpers/DataGridViewWithHeaderForm.jsx @@ -6,6 +6,7 @@ import { DefaultButton } from '../components/Buttons'; import { evalFunc } from '../utils'; import PropTypes from 'prop-types'; import CustomPropTypes from '../custom_prop_types'; +import _ from 'lodash'; const useStyles = makeStyles((theme)=>({ formBorder: { @@ -26,14 +27,10 @@ export default function DataGridViewWithHeaderForm(props) { const headerFormData = useRef({}); const schemaRef = useRef(otherProps.schema); const [isAddDisabled, setAddDisabled] = useState(true); - + const [headerFormResetKey, setHeaderFormResetKey] = useState(0); const onAddClick = useCallback(()=>{ - if(otherProps.canAddRow) { - let state = schemaRef.current.top ? schemaRef.current.top.sessData : schemaRef.current.sessData; - let canAddRow = evalFunc(schemaRef.current, otherProps.canAddRow, state || {}); - if(!canAddRow) { - return; - } + if(!otherProps.canAddRow) { + return; } let newRow = headerSchema.getNewData(headerFormData.current); @@ -42,13 +39,16 @@ export default function DataGridViewWithHeaderForm(props) { path: otherProps.accessPath, value: newRow, }); + setHeaderFormResetKey((preVal)=>preVal+1); }, []); useEffect(()=>{ headerSchema.top = schemaRef.current.top; }, []); - let state = schemaRef.current.top ? schemaRef.current.top.origData : schemaRef.current.origData; + let state = schemaRef.current.top ? _.get(schemaRef.current.top.sessData, _.slice(otherProps.accessPath, 0, -1)) + : _.get(schemaRef.current.sessData); + headerVisible = headerVisible && evalFunc(null, headerVisible, state); return ( @@ -67,6 +67,7 @@ export default function DataGridViewWithHeaderForm(props) { }} hasSQL={false} isTabView={false} + resetKey={headerFormResetKey} /> Add