Stability and bug fixes in schemaview react framework.

This commit is contained in:
Aditya Toshniwal 2021-08-12 12:39:23 +05:30 committed by Akshay Joshi
parent e3992527fb
commit bb5e2b98e9
5 changed files with 76 additions and 58 deletions

View File

@ -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||<>&nbsp;</>,
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,

View File

@ -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 <Tab key={tabName} label={tabName} />;
})}
</Tabs>
</Box>
{Object.keys(tabs).map((tabName, i)=>{
{Object.keys(finalTabs).map((tabName, i)=>{
return (
<TabPanel key={tabName} value={tabValue} index={i} classNameRoot={clsx(tabsClassname[tabName], isNested ? classes.nestedTabPanel : null)}
className={fullTabs.indexOf(tabName) == -1 ? classes.nestedControl : null}>
{tabs[tabName]}
{finalTabs[tabName]}
</TabPanel>
);
})}
@ -364,9 +367,9 @@ export default function FormView({
return (
<>
<Box height="100%" display="flex" flexDirection="column" className={className} ref={formRef}>
{Object.keys(tabs).map((tabName)=>{
{Object.keys(finalTabs).map((tabName)=>{
return (
<>{tabs[tabName]}</>
<>{finalTabs[tabName]}</>
);
})}
</Box>

View File

@ -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)) {

View File

@ -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(
<DataGridView
key={field.id}
viewHelperProps={viewHelperProps}
name={field.id}
value={origData[field.id]}
schema={field.schema}
accessPath={[field.id]}
formErr={{}}
controlClassName={classes.controlRow}
canAdd={false}
canEdit={false}
canDelete={false}
visible={visible}
/>
);
} else {
tabs[group].push(
<MappedFormControl
key={field.id}
@ -781,7 +794,7 @@ function SchemaPropertiesView({
value={origData[field.id]}
readonly={readonly}
disabled={disabled}
visible={_visible}
visible={visible}
{...field}
className={classes.controlRow}
/>

View File

@ -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 (
<Box className={containerClassName}>
@ -67,6 +67,7 @@ export default function DataGridViewWithHeaderForm(props) {
}}
hasSQL={false}
isTabView={false}
resetKey={headerFormResetKey}
/>
<Box display="flex">
<DefaultButton className={classes.addBtn} onClick={onAddClick} disabled={isAddDisabled}>Add</DefaultButton>