/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2024, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import React, { useCallback, useMemo } from 'react';
import _ from 'lodash';
import {
FormInputText, FormInputSelect, FormInputSwitch, FormInputCheckbox, FormInputColor,
FormInputFileSelect, FormInputToggle, InputSwitch, FormInputSQL, InputSQL, FormNote, FormInputDateTimePicker, PlainString,
InputSelect, InputText, InputCheckbox, InputDateTimePicker, InputFileSelect, FormInputKeyboardShortcut, FormInputQueryThreshold, FormInputSelectThemes, InputRadio, FormButton, InputTree
} from '../components/FormComponents';
import Privilege from '../components/Privilege';
import { evalFunc } from 'sources/utils';
import PropTypes from 'prop-types';
import CustomPropTypes from '../custom_prop_types';
import { SelectRefresh } from '../components/SelectRefresh';
/* Control mapping for form view */
function MappedFormControlBase({ type, value, id, onChange, className, visible, inputRef, noLabel, onClick, withContainer, controlGridBasis, ...props }) {
const name = id;
const onTextChange = useCallback((e) => {
let val = e;
if(e?.target) {
val = e.target.value;
}
onChange && onChange(val);
}, []);
const onSqlChange = useCallback((changedValue) => {
onChange && onChange(changedValue);
}, []);
const onTreeSelection = useCallback((selectedValues)=> {
onChange && onChange(selectedValues);
}, []);
if (!visible) {
return <>>;
}
/* The mapping uses Form* components as it comes with labels */
switch (type) {
case 'int':
return ;
case 'numeric':
return ;
case 'tel':
return ;
case 'text':
return ;
case 'multiline':
return ;
case 'password':
return ;
case 'select':
return ;
case 'select-refresh':
return ;
case 'switch':
return onTextChange(e.target.checked, e.target.name)} className={className}
withContainer={withContainer} controlGridBasis={controlGridBasis}
{...props} />;
case 'checkbox':
return onTextChange(e.target.checked, e.target.name)} className={className}
{...props} />;
case 'toggle':
return ;
case 'color':
return ;
case 'file':
return ;
case 'sql':
return ;
case 'note':
return ;
case 'datetimepicker':
return ;
case 'keyboardShortcut':
return ;
case 'threshold':
return ;
case 'theme':
return ;
case 'button':
return ;
case 'tree':
return ;
default:
return ;
}
}
MappedFormControlBase.propTypes = {
type: PropTypes.oneOfType([
PropTypes.string, PropTypes.func,
]).isRequired,
value: PropTypes.any,
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
onChange: PropTypes.func,
className: PropTypes.oneOfType([
PropTypes.string, PropTypes.object,
]),
visible: PropTypes.bool,
inputRef: CustomPropTypes.ref,
noLabel: PropTypes.bool,
onClick: PropTypes.func,
withContainer: PropTypes.bool,
controlGridBasis: PropTypes.number,
treeData: PropTypes.oneOfType([PropTypes.array, PropTypes.instanceOf(Promise), PropTypes.func]),
};
/* Control mapping for grid cell view */
function MappedCellControlBase({ cell, value, id, optionsLoaded, onCellChange, visible, reRenderRow, inputRef, ...props }) {
const name = id;
const onTextChange = useCallback((e) => {
let val = e;
if (e?.target) {
val = e.target.value;
}
onCellChange && onCellChange(val);
}, []);
const onRadioChange = useCallback((e) => {
let val =e;
if(e?.target) {
val = e.target.checked;
}
onCellChange && onCellChange(val);
});
const onSqlChange = useCallback((val) => {
onCellChange && onCellChange(val);
}, []);
/* Some grid cells are based on options selected in other cells.
* lets trigger a re-render for the row if optionsLoaded
*/
const optionsLoadedRerender = useCallback((res) => {
/* optionsLoaded is called when select options are fetched */
optionsLoaded && optionsLoaded(res);
reRenderRow && reRenderRow();
}, []);
if (!visible) {
return <>>;
}
/* The mapping does not need Form* components as labels are not needed for grid cells */
switch(cell) {
case 'int':
return ;
case 'numeric':
return ;
case 'text':
return ;
case 'password':
return ;
case 'select':
return ;
case 'switch':
return onTextChange(e.target.checked, e.target.name)} {...props} />;
case 'checkbox':
return onTextChange(e.target.checked, e.target.name)} {...props} />;
case 'privilege':
return ;
case 'datetimepicker':
return ;
case 'sql':
return ;
case 'file':
return ;
case 'keyCode':
return ;
case 'radio':
return ;
default:
return ;
}
}
MappedCellControlBase.propTypes = {
cell: PropTypes.oneOfType([
PropTypes.string, PropTypes.func,
]).isRequired,
value: PropTypes.any,
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
onChange: PropTypes.func,
reRenderRow: PropTypes.func,
optionsLoaded: PropTypes.func,
onCellChange: PropTypes.func,
visible: PropTypes.bool,
disabled: PropTypes.bool,
inputRef: CustomPropTypes.ref,
};
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',
'withContainer', 'controlGridBasis', 'hasCheckbox', 'treeData', 'title'
];
const ALLOWED_PROPS_FIELD_FORM = [
'type', 'onChange', 'state', 'noLabel', 'text','onClick'
];
const ALLOWED_PROPS_FIELD_CELL = [
'cell', 'onCellChange', 'row', 'reRenderRow', 'validate', 'disabled', 'readonly', 'radioType', 'hideBrowseButton', 'hidden'
];
export const MappedFormControl = ({memoDeps, ...props}) => {
let newProps = { ...props };
let typeProps = evalFunc(null, newProps.type, newProps.state);
if (typeof (typeProps) === 'object') {
newProps = {
...newProps,
...typeProps,
};
} else {
newProps.type = typeProps;
}
let origOnClick = newProps.onClick;
newProps.onClick = ()=>{
origOnClick?.();
/* Consider on click as change for button.
Just increase state val by 1 to inform the deps and self depChange */
newProps.onChange?.((newProps.state[props.id]||0)+1);
};
/* Filter out garbage props if any using ALLOWED_PROPS_FIELD */
return useMemo(()=>, memoDeps??[]);
};
MappedFormControl.propTypes = {
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
};
export const MappedCellControl = (props) => {
let newProps = { ...props };
let cellProps = evalFunc(null, newProps.cell, newProps.row);
if (typeof (cellProps) === 'object') {
newProps = {
...newProps,
...cellProps,
};
} else {
newProps.cell = cellProps;
}
/* Filter out garbage props if any using ALLOWED_PROPS_FIELD */
return ;
};