codekingpro/portable-devtools
114k
1/////////////////////////////////////////////////////////////2//3// pgAdmin 4 - PostgreSQL Tools4//5// Copyright (C) 2013 - 2024, The pgAdmin Development Team6// This software is released under the PostgreSQL Licence7//8//////////////////////////////////////////////////////////////9 10import React, { useContext, useEffect } from 'react';11import _ from 'lodash';12import PropTypes from 'prop-types';13 14import { MappedFormControl } from './MappedControl';15import { SCHEMA_STATE_ACTIONS, StateUtilsContext } from '.';16import { evalFunc } from 'sources/utils';17import CustomPropTypes from '../custom_prop_types';18import { DepListenerContext } from './DepListener';19import { getFieldMetaData } from './FormView';20import FieldSet from '../components/FieldSet';21import { Grid } from '@mui/material';22 23export default function FieldSetView({24 value, schema={}, viewHelperProps, accessPath, dataDispatch, controlClassName, isDataGridForm=false, label, visible}) {25 const depListener = useContext(DepListenerContext);26 const stateUtils = useContext(StateUtilsContext);27 28 useEffect(()=>{29 /* Calculate the fields which depends on the current field */30 if(!isDataGridForm && depListener) {31 schema.fields.forEach((field)=>{32 /* Self change is also dep change */33 if(field.depChange || field.deferredDepChange) {34 depListener.addDepListener(accessPath.concat(field.id), accessPath.concat(field.id), field.depChange, field.deferredDepChange);35 }36 (evalFunc(null, field.deps) || []).forEach((dep)=>{37 let source = accessPath.concat(dep);38 if(_.isArray(dep)) {39 source = dep;40 }41 if(field.depChange) {42 depListener.addDepListener(source, accessPath.concat(field.id), field.depChange);43 }44 });45 });46 }47 }, []);48 49 let viewFields = [];50 let inlineComponents = [];51 52 /* Prepare the array of components based on the types */53 for(const field of schema.fields) {54 let {visible, disabled, readonly, modeSupported} =55 getFieldMetaData(field, schema, value, viewHelperProps);56 57 if(modeSupported) {58 /* Its a form control */59 const hasError = field.id == stateUtils?.formErr.name;60 /* When there is a change, the dependent values can change61 * lets pass the new changes to dependent and get the new values62 * from there as well.63 */64 const currentControl = <MappedFormControl65 state={value}66 key={field.id}67 viewHelperProps={viewHelperProps}68 name={field.id}69 value={value[field.id]}70 {...field}71 readonly={readonly}72 disabled={disabled}73 visible={visible}74 onChange={(changeValue)=>{75 /* Get the changes on dependent fields as well */76 dataDispatch({77 type: SCHEMA_STATE_ACTIONS.SET_VALUE,78 path: accessPath.concat(field.id),79 value: changeValue,80 });81 }}82 hasError={hasError}83 className={controlClassName}84 memoDeps={[85 value[field.id],86 readonly,87 disabled,88 visible,89 hasError,90 controlClassName,91 ...(evalFunc(null, field.deps) || []).map((dep)=>value[dep]),92 ]}93 />;94 95 if(field.inlineNext) {96 inlineComponents.push(React.cloneElement(currentControl, {97 withContainer: false, controlGridBasis: 398 }));99 } else if(inlineComponents?.length > 0) {100 inlineComponents.push(React.cloneElement(currentControl, {101 withContainer: false, controlGridBasis: 3102 }));103 viewFields.push(104 <Grid container spacing={0} key={`ic-${inlineComponents[0].key}`} className={controlClassName} rowGap="8px">105 {inlineComponents}106 </Grid>107 );108 inlineComponents = [];109 } else {110 viewFields.push(currentControl);111 }112 }113 }114 if(inlineComponents?.length > 0) {115 viewFields.push(116 <Grid container spacing={0} key={`ic-${inlineComponents[0].key}`} className={controlClassName} rowGap="8px">117 {inlineComponents}118 </Grid>119 );120 }121 122 if(!visible) {123 return <></>;124 }125 126 return (127 <FieldSet title={label} className={controlClassName}>128 {viewFields}129 </FieldSet>130 );131}132 133FieldSetView.propTypes = {134 value: PropTypes.any,135 schema: CustomPropTypes.schemaUI.isRequired,136 viewHelperProps: PropTypes.object,137 isDataGridForm: PropTypes.bool,138 accessPath: PropTypes.array.isRequired,139 dataDispatch: PropTypes.func,140 controlClassName: CustomPropTypes.className,141 label: PropTypes.string,142 visible: PropTypes.oneOfType([143 PropTypes.bool, PropTypes.func,144 ]),145};146 