From a08714cd6548e5463c0b4f79fde8566407f5389c Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Mon, 10 Jul 2023 17:42:20 +0530 Subject: [PATCH] Allow two controls to be inline in SchemaView. --- .../static/js/SchemaView/FieldSetView.jsx | 90 +++++++++------ web/pgadmin/static/js/SchemaView/FormView.jsx | 106 +++++++++++------- .../static/js/SchemaView/MappedControl.jsx | 3 +- .../static/js/components/FormComponents.jsx | 42 +++++-- .../tools/backup/static/js/backup.ui.js | 1 + 5 files changed, 162 insertions(+), 80 deletions(-) diff --git a/web/pgadmin/static/js/SchemaView/FieldSetView.jsx b/web/pgadmin/static/js/SchemaView/FieldSetView.jsx index 79928b1b1..ddb9d76d5 100644 --- a/web/pgadmin/static/js/SchemaView/FieldSetView.jsx +++ b/web/pgadmin/static/js/SchemaView/FieldSetView.jsx @@ -18,6 +18,7 @@ import CustomPropTypes from '../custom_prop_types'; import { DepListenerContext } from './DepListener'; import { getFieldMetaData } from './FormView'; import FieldSet from '../components/FieldSet'; +import { Box } from '@material-ui/core'; export default function FieldSetView({ value, schema={}, viewHelperProps, accessPath, dataDispatch, controlClassName, isDataGridForm=false, label, visible}) { @@ -46,6 +47,8 @@ export default function FieldSetView({ }, []); let viewFields = []; + let inlineComponents = []; + /* Prepare the array of components based on the types */ for(const field of schema.fields) { let {visible, disabled, readonly, modeSupported} = @@ -58,40 +61,63 @@ export default function FieldSetView({ * lets pass the new changes to dependent and get the new values * from there as well. */ - viewFields.push( - { - /* Get the changes on dependent fields as well */ - dataDispatch({ - type: SCHEMA_STATE_ACTIONS.SET_VALUE, - path: accessPath.concat(field.id), - value: changeValue, - }); - }} - hasError={hasError} - className={controlClassName} - memoDeps={[ - value[field.id], - readonly, - disabled, - visible, - hasError, - controlClassName, - ...(evalFunc(null, field.deps) || []).map((dep)=>value[dep]), - ]} - /> - ); + const currentControl = { + /* Get the changes on dependent fields as well */ + dataDispatch({ + type: SCHEMA_STATE_ACTIONS.SET_VALUE, + path: accessPath.concat(field.id), + value: changeValue, + }); + }} + hasError={hasError} + className={controlClassName} + memoDeps={[ + value[field.id], + readonly, + disabled, + visible, + hasError, + controlClassName, + ...(evalFunc(null, field.deps) || []).map((dep)=>value[dep]), + ]} + />; + + if(field.inlineNext) { + inlineComponents.push(React.cloneElement(currentControl, { + withContainer: false, controlGridBasis: 3 + })); + } else if(inlineComponents?.length > 0) { + inlineComponents.push(React.cloneElement(currentControl, { + withContainer: false, controlGridBasis: 3 + })); + viewFields.push( + + {inlineComponents} + + ); + inlineComponents = []; + } else { + viewFields.push(currentControl); + } } } + if(inlineComponents?.length > 0) { + viewFields.push( + + {inlineComponents} + + ); + } if(!visible) { return <>; diff --git a/web/pgadmin/static/js/SchemaView/FormView.jsx b/web/pgadmin/static/js/SchemaView/FormView.jsx index b06eb07ed..d97ca4eff 100644 --- a/web/pgadmin/static/js/SchemaView/FormView.jsx +++ b/web/pgadmin/static/js/SchemaView/FormView.jsx @@ -212,6 +212,8 @@ export default function FormView({ }, [stateUtils.formResetKey]); let fullTabs = []; + let inlineComponents = []; + let inlineCompGroup = null; /* Prepare the array of components based on the types */ for(const field of schemaRef.current.fields) { @@ -304,49 +306,75 @@ export default function FormView({ firstEleID.current = field.id; } - tabs[group].push( - { - if(firstEleRef && firstEleID.current === field.id) { - firstEleRef.current = ele; - } - }} - state={value} - key={id} - viewHelperProps={viewHelperProps} - name={id} - value={value[id]} - {...field} - id={id} - readonly={readonly} - disabled={disabled} - visible={visible} - onChange={(changeValue)=>{ - /* Get the changes on dependent fields as well */ - dataDispatch({ - type: SCHEMA_STATE_ACTIONS.SET_VALUE, - path: accessPath.concat(id), - value: changeValue, - }); - }} - hasError={hasError} - className={classes.controlRow} - noLabel={field.isFullTab} - memoDeps={[ - value[id], - readonly, - disabled, - visible, - hasError, - classes.controlRow, - ...(evalFunc(null, field.deps) || []).map((dep)=>value[dep]), - ]} - /> - ); + const currentControl = { + if(firstEleRef && firstEleID.current === field.id) { + firstEleRef.current = ele; + } + }} + state={value} + key={id} + viewHelperProps={viewHelperProps} + name={id} + value={value[id]} + {...field} + id={id} + readonly={readonly} + disabled={disabled} + visible={visible} + onChange={(changeValue)=>{ + /* Get the changes on dependent fields as well */ + dataDispatch({ + type: SCHEMA_STATE_ACTIONS.SET_VALUE, + path: accessPath.concat(id), + value: changeValue, + }); + }} + hasError={hasError} + className={classes.controlRow} + noLabel={field.isFullTab} + memoDeps={[ + value[id], + readonly, + disabled, + visible, + hasError, + classes.controlRow, + ...(evalFunc(null, field.deps) || []).map((dep)=>value[dep]), + ]} + />; + + if(field.inlineNext) { + inlineComponents.push(React.cloneElement(currentControl, { + withContainer: false, controlGridBasis: 3 + })); + inlineCompGroup = group; + } else if(inlineComponents?.length > 0) { + inlineComponents.push(React.cloneElement(currentControl, { + withContainer: false, controlGridBasis: 3 + })); + tabs[group].push( + + {inlineComponents} + + ); + inlineComponents = []; + inlineCompGroup = null; + } else { + tabs[group].push(currentControl); + } } } } + if(inlineComponents?.length > 0) { + tabs[inlineCompGroup].push( + + {inlineComponents} + + ); + } + let finalTabs = _.pickBy(tabs, (v, tabName)=>schemaRef.current.filterGroups.indexOf(tabName) <= -1); /* Add the SQL tab if required */ diff --git a/web/pgadmin/static/js/SchemaView/MappedControl.jsx b/web/pgadmin/static/js/SchemaView/MappedControl.jsx index 6daba238f..52bf1d289 100644 --- a/web/pgadmin/static/js/SchemaView/MappedControl.jsx +++ b/web/pgadmin/static/js/SchemaView/MappedControl.jsx @@ -201,7 +201,8 @@ const ALLOWED_PROPS_FIELD_COMMON = [ 'mode', 'value', 'readonly', 'disabled', 'hasError', 'id', 'label', 'options', 'optionsLoaded', 'controlProps', 'schema', 'inputRef', 'visible', 'autoFocus', 'helpMessage', 'className', 'optionsReloadBasis', - 'orientation', 'isvalidate', 'fields', 'radioType', 'hideBrowseButton', 'btnName', 'hidden' + 'orientation', 'isvalidate', 'fields', 'radioType', 'hideBrowseButton', 'btnName', 'hidden', + 'withContainer', 'controlGridBasis', ]; const ALLOWED_PROPS_FIELD_FORM = [ diff --git a/web/pgadmin/static/js/components/FormComponents.jsx b/web/pgadmin/static/js/components/FormComponents.jsx index e44a805aa..f42104a7f 100644 --- a/web/pgadmin/static/js/components/FormComponents.jsx +++ b/web/pgadmin/static/js/components/FormComponents.jsx @@ -125,19 +125,37 @@ FormIcon.propTypes = { }; /* Wrapper on any form component to add label, error indicator and help message */ -export function FormInput({ children, error, className, label, helpMessage, required, testcid }) { +export function FormInput({ children, error, className, label, helpMessage, required, testcid, withContainer=true, labelGridBasis=3, controlGridBasis=9 }) { const classes = useStyles(); const cid = testcid || _.uniqueId('c'); const helpid = `h${cid}`; + if(!withContainer) { + return ( + <> + + + {label} + + + + + + {React.cloneElement(children, { cid, helpid })} + + {HTMLReactParse(helpMessage || '')} + + + ); + } return ( - + {label} - + {React.cloneElement(children, { cid, helpid })} @@ -154,6 +172,9 @@ FormInput.propTypes = { helpMessage: PropTypes.string, required: PropTypes.bool, testcid: PropTypes.any, + withContainer: PropTypes.bool, + labelGridBasis: PropTypes.number, + controlGridBasis: PropTypes.number, }; export function InputSQL({ value, options, onChange, className, controlProps, inputRef, ...props }) { @@ -512,10 +533,10 @@ InputSwitch.propTypes = { controlProps: PropTypes.object, }; -export function FormInputSwitch({ hasError, required, label, className, helpMessage, testcid, ...props }) { - +export function FormInputSwitch({ hasError, required, label, className, helpMessage, testcid, withContainer, controlGridBasis, ...props }) { return ( - + ); @@ -527,6 +548,8 @@ FormInputSwitch.propTypes = { className: CustomPropTypes.className, helpMessage: PropTypes.string, testcid: PropTypes.string, + withContainer: PropTypes.bool, + controlGridBasis: PropTypes.number, }; export function InputCheckbox({ cid, helpid, value, onChange, controlProps, readonly, ...props }) { @@ -1019,10 +1042,11 @@ InputColor.propTypes = { }; export function FormInputColor({ - hasError, required, className, label, helpMessage, testcid, ...props }) { + hasError, required, className, label, helpMessage, testcid, withContainer, controlGridBasis, ...props }) { return ( - + ); @@ -1034,6 +1058,8 @@ FormInputColor.propTypes = { label: PropTypes.string, helpMessage: PropTypes.string, testcid: PropTypes.string, + withContainer: PropTypes.bool, + controlGridBasis: PropTypes.number, }; export function PlainString({ controlProps, value }) { diff --git a/web/pgadmin/tools/backup/static/js/backup.ui.js b/web/pgadmin/tools/backup/static/js/backup.ui.js index 364d4356a..4da07ef62 100644 --- a/web/pgadmin/tools/backup/static/js/backup.ui.js +++ b/web/pgadmin/tools/backup/static/js/backup.ui.js @@ -40,6 +40,7 @@ export class SectionSchema extends BaseUISchema { state.only_tablespaces || state.only_roles; }, + inlineNext: true, }, { id: 'data', label: gettext('Data'),