mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
- Some UI changes based on review comments. - Fix the numeric type.
This commit is contained in:
committed by
Akshay Joshi
parent
453f26817a
commit
5db72a6916
@@ -9,7 +9,7 @@
|
||||
|
||||
/* The DataGridView component is based on react-table component */
|
||||
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import React, { useCallback, useContext, useMemo, useRef, useState } from 'react';
|
||||
import { Box } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import { PgIconButton } from '../components/Buttons';
|
||||
@@ -85,6 +85,9 @@ const useStyles = makeStyles((theme)=>({
|
||||
padding: theme.spacing(1, 0.5),
|
||||
textAlign: 'left',
|
||||
},
|
||||
btnCell: {
|
||||
padding: theme.spacing(0.5, 0),
|
||||
},
|
||||
resizer: {
|
||||
display: 'inline-block',
|
||||
width: '5px',
|
||||
@@ -146,13 +149,14 @@ function DataTableRow({row, totalRows, isResizing, schema, schemaRef, accessPath
|
||||
const classes = useStyles();
|
||||
const [key, setKey] = useState(false);
|
||||
const depListener = useContext(DepListenerContext);
|
||||
|
||||
/* Memoize the row to avoid unnecessary re-render.
|
||||
* If table data changes, then react-table re-renders the complete tables
|
||||
* We can avoid re-render by if row data is not changed
|
||||
*/
|
||||
|
||||
let depsMap = _.values(row.values, Object.keys(row.values).filter((k)=>!k.startsWith('btn')));
|
||||
useEffect(()=>{
|
||||
const externalDeps = useMemo(()=>{
|
||||
let retVal = [];
|
||||
/* Calculate the fields which depends on the current field
|
||||
deps has info on fields which the current field depends on. */
|
||||
schema.fields.forEach((field)=>{
|
||||
@@ -164,18 +168,25 @@ function DataTableRow({row, totalRows, isResizing, schema, schemaRef, accessPath
|
||||
let source = accessPath.concat(dep);
|
||||
if(_.isArray(dep)) {
|
||||
source = dep;
|
||||
depsMap.push(_.get(schemaRef.current.sessData, source));
|
||||
/* If its an array, then dep is from the top schema */
|
||||
retVal.push(source);
|
||||
}
|
||||
depListener.addDepListener(source, accessPath.concat(field.id), field.depChange);
|
||||
});
|
||||
});
|
||||
return retVal;
|
||||
}, []);
|
||||
|
||||
/* External deps values are from top schema sess data */
|
||||
depsMap = depsMap.concat(externalDeps.map((source)=>_.get(schemaRef.current.top?.sessData, source)));
|
||||
depsMap = depsMap.concat([totalRows, row.isExpanded, key, isResizing]);
|
||||
return useMemo(()=>
|
||||
<div {...row.getRowProps()} className="tr">
|
||||
{row.cells.map((cell, ci) => {
|
||||
let classNames = [classes.tableCell];
|
||||
if(typeof(cell.column.id) == 'string' && cell.column.id.startsWith('btn-')) {
|
||||
classNames.push(classes.btnCell);
|
||||
}
|
||||
if(cell.column.id == 'btn-edit' && row.isExpanded) {
|
||||
classNames.push(classes.expandedIconCell);
|
||||
}
|
||||
@@ -207,14 +218,14 @@ export default function DataGridView({
|
||||
resizable: false,
|
||||
sortable: false,
|
||||
dataType: 'edit',
|
||||
width: 30,
|
||||
width: 26,
|
||||
minWidth: '0',
|
||||
Cell: ({row})=>{
|
||||
let canEditRow = true;
|
||||
if(props.canEditRow) {
|
||||
canEditRow = evalFunc(schemaRef.current, props.canEditRow, row.original || {});
|
||||
}
|
||||
return <PgIconButton data-test="expand-row" title={gettext('Edit row')} icon={<EditRoundedIcon />} className={classes.gridRowButton}
|
||||
return <PgIconButton data-test="expand-row" title={gettext('Edit row')} icon={<EditRoundedIcon fontSize="small" />} className={classes.gridRowButton}
|
||||
onClick={()=>{
|
||||
row.toggleRowExpanded(!row.isExpanded);
|
||||
}} disabled={!canEditRow}
|
||||
@@ -235,7 +246,7 @@ export default function DataGridView({
|
||||
resizable: false,
|
||||
sortable: false,
|
||||
dataType: 'delete',
|
||||
width: 30,
|
||||
width: 26,
|
||||
minWidth: '0',
|
||||
Cell: ({row}) => {
|
||||
let canDeleteRow = true;
|
||||
@@ -244,7 +255,7 @@ export default function DataGridView({
|
||||
}
|
||||
|
||||
return (
|
||||
<PgIconButton data-test="delete-row" title={gettext('Delete row')} icon={<DeleteRoundedIcon />}
|
||||
<PgIconButton data-test="delete-row" title={gettext('Delete row')} icon={<DeleteRoundedIcon fontSize="small" />}
|
||||
onClick={()=>{
|
||||
confirmDeleteRow(()=>{
|
||||
/* Get the changes on dependent fields as well */
|
||||
|
||||
@@ -77,7 +77,7 @@ export function getFieldMetaData(field, schema, value, viewHelperProps) {
|
||||
disabled: false,
|
||||
visible: true,
|
||||
canAdd: true,
|
||||
canEdit: true,
|
||||
canEdit: false,
|
||||
canDelete: true,
|
||||
modeSupported: true,
|
||||
};
|
||||
@@ -112,9 +112,9 @@ export function getFieldMetaData(field, schema, value, viewHelperProps) {
|
||||
retData.disabled = Boolean(evalFunc(schema, disabled, value));
|
||||
|
||||
let {canAdd, canEdit, canDelete } = field;
|
||||
retData.canAdd = _.isUndefined(canAdd) ? true : evalFunc(schema, canAdd, value);
|
||||
retData.canEdit = _.isUndefined(canEdit) ? true : evalFunc(schema, canEdit, value);
|
||||
retData.canDelete = _.isUndefined(canDelete) ? true : evalFunc(schema, canDelete, value);
|
||||
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);
|
||||
|
||||
return retData;
|
||||
}
|
||||
@@ -216,9 +216,9 @@ export default function FormView({
|
||||
depsMap.push(canAdd, canEdit, canDelete, visible);
|
||||
|
||||
tabs[group].push(
|
||||
useMemo(()=><DataGridView key={field.id} value={value[field.id]} viewHelperProps={viewHelperProps} formErr={formErr}
|
||||
<DataGridView 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}/>, depsMap)
|
||||
{...field} canAdd={canAdd} canEdit={canEdit} canDelete={canDelete} visible={visible}/>
|
||||
);
|
||||
} else if(field.type === 'group') {
|
||||
groupLabels[field.id] = field.label;
|
||||
|
||||
@@ -43,6 +43,17 @@ function MappedFormControlBase({type, value, id, onChange, className, visible, i
|
||||
onChange && onChange(value);
|
||||
}, []);
|
||||
|
||||
const onNumChange = useCallback((e) => {
|
||||
let value = e;
|
||||
if(e && e.target) {
|
||||
value = e.target.value;
|
||||
}
|
||||
if(!isNaN(parseFloat(value))) {
|
||||
value = parseFloat(value);
|
||||
}
|
||||
onChange && onChange(value);
|
||||
}, []);
|
||||
|
||||
if(!visible) {
|
||||
return <></>;
|
||||
}
|
||||
@@ -51,6 +62,8 @@ function MappedFormControlBase({type, value, id, onChange, className, visible, i
|
||||
switch (type) {
|
||||
case 'int':
|
||||
return <FormInputText name={name} value={value} onChange={onIntChange} className={className} inputRef={inputRef} {...props}/>;
|
||||
case 'numeric':
|
||||
return <FormInputText name={name} value={value} onChange={onNumChange} className={className} inputRef={inputRef} {...props}/>;
|
||||
case 'text':
|
||||
return <FormInputText name={name} value={value} onChange={onTextChange} className={className} inputRef={inputRef} {...props}/>;
|
||||
case 'multiline':
|
||||
@@ -109,6 +122,28 @@ function MappedCellControlBase({cell, value, id, optionsLoaded, onCellChange, vi
|
||||
onCellChange(value);
|
||||
}, []);
|
||||
|
||||
const onIntChange = useCallback((e) => {
|
||||
let value = e;
|
||||
if(e && e.target) {
|
||||
value = e.target.value;
|
||||
}
|
||||
if(!isNaN(parseInt(value))) {
|
||||
value = parseInt(value);
|
||||
}
|
||||
onChange && onChange(value);
|
||||
}, []);
|
||||
|
||||
const onNumChange = useCallback((e) => {
|
||||
let value = e;
|
||||
if(e && e.target) {
|
||||
value = e.target.value;
|
||||
}
|
||||
if(!isNaN(parseFloat(value))) {
|
||||
value = parseFloat(value);
|
||||
}
|
||||
onChange && onChange(value);
|
||||
}, []);
|
||||
|
||||
/* Some grid cells are based on options selected in other cells.
|
||||
* lets trigger a re-render for the row if optionsLoaded
|
||||
*/
|
||||
@@ -125,7 +160,9 @@ function MappedCellControlBase({cell, value, id, optionsLoaded, onCellChange, vi
|
||||
/* The mapping does not need Form* components as labels are not needed for grid cells */
|
||||
switch(cell) {
|
||||
case 'int':
|
||||
case 'number':
|
||||
return <InputText name={name} value={value} onChange={onIntChange} {...props}/>;
|
||||
case 'numeric':
|
||||
return <InputText name={name} value={value} onChange={onNumChange} {...props}/>;
|
||||
case 'text':
|
||||
return <InputText name={name} value={value} onChange={onTextChange} {...props}/>;
|
||||
case 'password':
|
||||
|
||||
@@ -781,9 +781,6 @@ export function InputColor({value, controlProps, disabled, onChange, currObj}) {
|
||||
|
||||
let btnStyles = {backgroundColor: value};
|
||||
return (
|
||||
// <Button variant="contained" ref={eleRef} className={classes.colorBtn} style={btnStyles} disabled={pickrOptions.disabled}>
|
||||
// {(_.isUndefined(value) || _.isNull(value) || value === '') && <CloseIcon />}
|
||||
// </Button>
|
||||
<PgIconButton ref={eleRef} title={gettext('Select the color')} className={classes.colorBtn} style={btnStyles} disabled={pickrOptions.disabled}
|
||||
icon={(_.isUndefined(value) || _.isNull(value) || value === '') && <CloseIcon />}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user