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 */
|
/* 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 { Box } from '@material-ui/core';
|
||||||
import { makeStyles } from '@material-ui/core/styles';
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
import { PgIconButton } from '../components/Buttons';
|
import { PgIconButton } from '../components/Buttons';
|
||||||
@@ -85,6 +85,9 @@ const useStyles = makeStyles((theme)=>({
|
|||||||
padding: theme.spacing(1, 0.5),
|
padding: theme.spacing(1, 0.5),
|
||||||
textAlign: 'left',
|
textAlign: 'left',
|
||||||
},
|
},
|
||||||
|
btnCell: {
|
||||||
|
padding: theme.spacing(0.5, 0),
|
||||||
|
},
|
||||||
resizer: {
|
resizer: {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
width: '5px',
|
width: '5px',
|
||||||
@@ -146,13 +149,14 @@ function DataTableRow({row, totalRows, isResizing, schema, schemaRef, accessPath
|
|||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const [key, setKey] = useState(false);
|
const [key, setKey] = useState(false);
|
||||||
const depListener = useContext(DepListenerContext);
|
const depListener = useContext(DepListenerContext);
|
||||||
|
|
||||||
/* Memoize the row to avoid unnecessary re-render.
|
/* Memoize the row to avoid unnecessary re-render.
|
||||||
* If table data changes, then react-table re-renders the complete tables
|
* If table data changes, then react-table re-renders the complete tables
|
||||||
* We can avoid re-render by if row data is not changed
|
* 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')));
|
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
|
/* Calculate the fields which depends on the current field
|
||||||
deps has info on fields which the current field depends on. */
|
deps has info on fields which the current field depends on. */
|
||||||
schema.fields.forEach((field)=>{
|
schema.fields.forEach((field)=>{
|
||||||
@@ -164,18 +168,25 @@ function DataTableRow({row, totalRows, isResizing, schema, schemaRef, accessPath
|
|||||||
let source = accessPath.concat(dep);
|
let source = accessPath.concat(dep);
|
||||||
if(_.isArray(dep)) {
|
if(_.isArray(dep)) {
|
||||||
source = 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);
|
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]);
|
depsMap = depsMap.concat([totalRows, row.isExpanded, key, isResizing]);
|
||||||
return useMemo(()=>
|
return useMemo(()=>
|
||||||
<div {...row.getRowProps()} className="tr">
|
<div {...row.getRowProps()} className="tr">
|
||||||
{row.cells.map((cell, ci) => {
|
{row.cells.map((cell, ci) => {
|
||||||
let classNames = [classes.tableCell];
|
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) {
|
if(cell.column.id == 'btn-edit' && row.isExpanded) {
|
||||||
classNames.push(classes.expandedIconCell);
|
classNames.push(classes.expandedIconCell);
|
||||||
}
|
}
|
||||||
@@ -207,14 +218,14 @@ export default function DataGridView({
|
|||||||
resizable: false,
|
resizable: false,
|
||||||
sortable: false,
|
sortable: false,
|
||||||
dataType: 'edit',
|
dataType: 'edit',
|
||||||
width: 30,
|
width: 26,
|
||||||
minWidth: '0',
|
minWidth: '0',
|
||||||
Cell: ({row})=>{
|
Cell: ({row})=>{
|
||||||
let canEditRow = true;
|
let canEditRow = true;
|
||||||
if(props.canEditRow) {
|
if(props.canEditRow) {
|
||||||
canEditRow = evalFunc(schemaRef.current, props.canEditRow, row.original || {});
|
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={()=>{
|
onClick={()=>{
|
||||||
row.toggleRowExpanded(!row.isExpanded);
|
row.toggleRowExpanded(!row.isExpanded);
|
||||||
}} disabled={!canEditRow}
|
}} disabled={!canEditRow}
|
||||||
@@ -235,7 +246,7 @@ export default function DataGridView({
|
|||||||
resizable: false,
|
resizable: false,
|
||||||
sortable: false,
|
sortable: false,
|
||||||
dataType: 'delete',
|
dataType: 'delete',
|
||||||
width: 30,
|
width: 26,
|
||||||
minWidth: '0',
|
minWidth: '0',
|
||||||
Cell: ({row}) => {
|
Cell: ({row}) => {
|
||||||
let canDeleteRow = true;
|
let canDeleteRow = true;
|
||||||
@@ -244,7 +255,7 @@ export default function DataGridView({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
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={()=>{
|
onClick={()=>{
|
||||||
confirmDeleteRow(()=>{
|
confirmDeleteRow(()=>{
|
||||||
/* Get the changes on dependent fields as well */
|
/* Get the changes on dependent fields as well */
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export function getFieldMetaData(field, schema, value, viewHelperProps) {
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
visible: true,
|
visible: true,
|
||||||
canAdd: true,
|
canAdd: true,
|
||||||
canEdit: true,
|
canEdit: false,
|
||||||
canDelete: true,
|
canDelete: true,
|
||||||
modeSupported: true,
|
modeSupported: true,
|
||||||
};
|
};
|
||||||
@@ -112,9 +112,9 @@ export function getFieldMetaData(field, schema, value, viewHelperProps) {
|
|||||||
retData.disabled = Boolean(evalFunc(schema, disabled, value));
|
retData.disabled = Boolean(evalFunc(schema, disabled, value));
|
||||||
|
|
||||||
let {canAdd, canEdit, canDelete } = field;
|
let {canAdd, canEdit, canDelete } = field;
|
||||||
retData.canAdd = _.isUndefined(canAdd) ? true : evalFunc(schema, canAdd, value);
|
retData.canAdd = _.isUndefined(canAdd) ? retData.canAdd : evalFunc(schema, canAdd, value);
|
||||||
retData.canEdit = _.isUndefined(canEdit) ? true : evalFunc(schema, canEdit, value);
|
retData.canEdit = _.isUndefined(canEdit) ? retData.canEdit : evalFunc(schema, canEdit, value);
|
||||||
retData.canDelete = _.isUndefined(canDelete) ? true : evalFunc(schema, canDelete, value);
|
retData.canDelete = _.isUndefined(canDelete) ? retData.canDelete : evalFunc(schema, canDelete, value);
|
||||||
|
|
||||||
return retData;
|
return retData;
|
||||||
}
|
}
|
||||||
@@ -216,9 +216,9 @@ export default function FormView({
|
|||||||
depsMap.push(canAdd, canEdit, canDelete, visible);
|
depsMap.push(canAdd, canEdit, canDelete, visible);
|
||||||
|
|
||||||
tabs[group].push(
|
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}
|
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') {
|
} else if(field.type === 'group') {
|
||||||
groupLabels[field.id] = field.label;
|
groupLabels[field.id] = field.label;
|
||||||
|
|||||||
@@ -43,6 +43,17 @@ function MappedFormControlBase({type, value, id, onChange, className, visible, i
|
|||||||
onChange && onChange(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);
|
||||||
|
}, []);
|
||||||
|
|
||||||
if(!visible) {
|
if(!visible) {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
@@ -51,6 +62,8 @@ function MappedFormControlBase({type, value, id, onChange, className, visible, i
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 'int':
|
case 'int':
|
||||||
return <FormInputText name={name} value={value} onChange={onIntChange} className={className} inputRef={inputRef} {...props}/>;
|
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':
|
case 'text':
|
||||||
return <FormInputText name={name} value={value} onChange={onTextChange} className={className} inputRef={inputRef} {...props}/>;
|
return <FormInputText name={name} value={value} onChange={onTextChange} className={className} inputRef={inputRef} {...props}/>;
|
||||||
case 'multiline':
|
case 'multiline':
|
||||||
@@ -109,6 +122,28 @@ function MappedCellControlBase({cell, value, id, optionsLoaded, onCellChange, vi
|
|||||||
onCellChange(value);
|
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.
|
/* Some grid cells are based on options selected in other cells.
|
||||||
* lets trigger a re-render for the row if optionsLoaded
|
* 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 */
|
/* The mapping does not need Form* components as labels are not needed for grid cells */
|
||||||
switch(cell) {
|
switch(cell) {
|
||||||
case 'int':
|
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':
|
case 'text':
|
||||||
return <InputText name={name} value={value} onChange={onTextChange} {...props}/>;
|
return <InputText name={name} value={value} onChange={onTextChange} {...props}/>;
|
||||||
case 'password':
|
case 'password':
|
||||||
|
|||||||
@@ -781,9 +781,6 @@ export function InputColor({value, controlProps, disabled, onChange, currObj}) {
|
|||||||
|
|
||||||
let btnStyles = {backgroundColor: value};
|
let btnStyles = {backgroundColor: value};
|
||||||
return (
|
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}
|
<PgIconButton ref={eleRef} title={gettext('Select the color')} className={classes.colorBtn} style={btnStyles} disabled={pickrOptions.disabled}
|
||||||
icon={(_.isUndefined(value) || _.isNull(value) || value === '') && <CloseIcon />}
|
icon={(_.isUndefined(value) || _.isNull(value) || value === '') && <CloseIcon />}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user