mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-22 08:46:39 -06:00
Fixed following issues after React Porting:
1. Unique constraint should not allow changing values for deferrable, deferred, included columns. 2. Primary keys should not allow changing values for deferrable, deferred, included columns. 3. Foreign keys should not allow changing match type. The referenced table name is empty. 4. Exclude - Column/Expression has incorrect values. 5. Save should not be enabled when Custom auto-vacuum is enabled but none of the parameters are edited. Fixes #6777
This commit is contained in:
parent
15a494c189
commit
9179b7464b
@ -154,12 +154,12 @@ export default class ColumnSchema extends BaseUISchema {
|
||||
id: 'name', label: gettext('Name'), cell: 'text',
|
||||
type: 'text', readonly: obj.inSchemaWithColumnCheck,
|
||||
editable: this.editableCheckForTable, noEmpty: true,
|
||||
minWidth: 115,
|
||||
width: 115,
|
||||
},{
|
||||
// Need to show this field only when creating new table
|
||||
// [in SubNode control]
|
||||
id: 'is_primary_key', label: gettext('Primary key?'),
|
||||
cell: 'switch', type: 'switch', minWidth: 100, deps:['name'],
|
||||
cell: 'switch', type: 'switch', width: 100, disableResizing: true, deps:['name'],
|
||||
visible: ()=>{
|
||||
return obj.top?.nodeInfo && _.isUndefined(
|
||||
obj.top.nodeInfo['table'] || obj.top.nodeInfo['view'] ||
|
||||
@ -226,7 +226,7 @@ export default class ColumnSchema extends BaseUISchema {
|
||||
type: 'text', disabled: this.inCatalog, mode: ['properties'],
|
||||
},{
|
||||
id: 'cltype', label: gettext('Data type'),
|
||||
readonly: obj.inSchemaWithColumnCheck, minWidth: 150,
|
||||
readonly: obj.inSchemaWithColumnCheck, width: 150,
|
||||
group: gettext('Definition'), noEmpty: true,
|
||||
editable: this.editableCheckForTable,
|
||||
options: this.cltypeOptions, optionsLoaded: (options)=>{obj.datatypes = options;},
|
||||
@ -276,7 +276,7 @@ export default class ColumnSchema extends BaseUISchema {
|
||||
},
|
||||
},{
|
||||
id: 'attlen', label: gettext('Length/Precision'), cell: 'int',
|
||||
deps: ['cltype'], type: 'int', group: gettext('Definition'), width: 120, minWidth: 120,
|
||||
deps: ['cltype'], type: 'int', group: gettext('Definition'), width: 120, disableResizing: true,
|
||||
depChange: (state)=>{
|
||||
let range = this.attlenRange(state);
|
||||
if(range) {
|
||||
@ -300,7 +300,7 @@ export default class ColumnSchema extends BaseUISchema {
|
||||
return Boolean(obj.attlenRange(state));
|
||||
},
|
||||
},{
|
||||
id: 'attprecision', label: gettext('Scale'), cell: 'int', minWidth: 60,
|
||||
id: 'attprecision', label: gettext('Scale'), cell: 'int', width: 60, disableResizing: true,
|
||||
deps: ['cltype'], type: 'int', group: gettext('Definition'),
|
||||
depChange: (state)=>{
|
||||
let range = this.attprecisionRange(state);
|
||||
@ -386,7 +386,7 @@ export default class ColumnSchema extends BaseUISchema {
|
||||
},
|
||||
},{
|
||||
id: 'attnotnull', label: gettext('Not NULL?'), cell: 'switch',
|
||||
type: 'switch', minWidth: 80,
|
||||
type: 'switch', width: 80, disableResizing: true,
|
||||
group: gettext('Constraints'), editable: this.editableCheckForTable,
|
||||
deps: ['colconstype'],
|
||||
readonly: (state) => {
|
||||
|
@ -128,7 +128,8 @@ class ExclusionColumnSchema extends BaseUISchema {
|
||||
get baseFields() {
|
||||
let obj = this;
|
||||
return [{
|
||||
id: 'is_exp', label: '', type:'', editable: false, minWidth: 20,
|
||||
id: 'is_exp', label: '', type:'', editable: false, width: 20,
|
||||
disableResizing: true,
|
||||
controlProps: {
|
||||
formatter: {
|
||||
fromRaw: function (rawValue) {
|
||||
@ -138,11 +139,11 @@ class ExclusionColumnSchema extends BaseUISchema {
|
||||
}, visible: false,
|
||||
},{
|
||||
id: 'column', label: gettext('Col/Exp'), type:'', editable: false,
|
||||
cell:'', minWidth: 125,
|
||||
cell:'', width: 125,
|
||||
},{
|
||||
id: 'oper_class', label: gettext('Operator class'), cell:'select',
|
||||
options: this.operClassOptions,
|
||||
minWidth: 185,
|
||||
width: 185,
|
||||
editable: obj.isEditable,
|
||||
controlProps: {
|
||||
allowClear: true, placeholder: gettext('Select the operator class'),
|
||||
@ -153,7 +154,7 @@ class ExclusionColumnSchema extends BaseUISchema {
|
||||
{label: 'ASC', value: true},
|
||||
{label: 'DESC', value: false},
|
||||
],
|
||||
editable: obj.isEditable, minWidth: 110,
|
||||
editable: obj.isEditable, width: 110, disableResizing: true,
|
||||
controlProps: {
|
||||
allowClear: false,
|
||||
},
|
||||
@ -163,10 +164,10 @@ class ExclusionColumnSchema extends BaseUISchema {
|
||||
{label: 'FIRST', value: true},
|
||||
{label: 'LAST', value: false},
|
||||
], controlProps: {allowClear: false},
|
||||
editable: obj.isEditable, minWidth: 110,
|
||||
editable: obj.isEditable, width: 110, disableResizing: true,
|
||||
},{
|
||||
id: 'operator', label: gettext('Operator'), type: 'select',
|
||||
minWidth: 95,
|
||||
width: 95,
|
||||
editable: function() {
|
||||
return obj.isNewExCons;
|
||||
},
|
||||
@ -353,20 +354,11 @@ export default class ExclusionConstraintSchema extends BaseUISchema {
|
||||
controlProps: {
|
||||
formatter: {
|
||||
fromRaw: (rawValue)=>{
|
||||
var cols = [],
|
||||
remoteCols = [];
|
||||
if (rawValue?.length > 0) {
|
||||
rawValue.forEach((col)=>{
|
||||
cols.push(col.local_column);
|
||||
remoteCols.push(col.referenced);
|
||||
});
|
||||
return '('+cols.join(', ')+') -> ('+ remoteCols.join(', ')+')';
|
||||
}
|
||||
return '';
|
||||
return _.map(rawValue || [], 'column').join(', ');
|
||||
},
|
||||
}
|
||||
},
|
||||
minWidth: 245,
|
||||
width: 245,
|
||||
}),
|
||||
deps: ()=>{
|
||||
let ret = [];
|
||||
|
@ -282,14 +282,20 @@ export default class ForeignKeySchema extends BaseUISchema {
|
||||
readonly: this.isReadonly,
|
||||
},{
|
||||
id: 'references_table_name', label: gettext('Referenced Table'),
|
||||
type: 'text', group: gettext('Columns'), editable: false, visible:false,
|
||||
cell: '', deps: ['columns'],
|
||||
depChange: (state)=>{
|
||||
if(state.columns?.length > 0) {
|
||||
return {references_table_name: _.join(_.map(state.columns, 'references_table_name'), ',')};
|
||||
type: 'text', group: gettext('Columns'), editable: false, visible:false, deps: ['columns'],
|
||||
cell: (state)=>({
|
||||
cell: '',
|
||||
controlProps: {
|
||||
formatter: {
|
||||
fromRaw: ()=>{
|
||||
if(state.columns?.length > 0) {
|
||||
return _.join(_.map(state.columns, 'references_table_name'), ',');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
return {references_table_name: undefined};
|
||||
}
|
||||
}),
|
||||
},{
|
||||
id: 'columns', label: gettext('Columns'),
|
||||
group: gettext('Columns'), type: 'collection',
|
||||
|
@ -156,8 +156,8 @@ export default class PrimaryKeySchema extends BaseUISchema {
|
||||
return false;
|
||||
},
|
||||
deps: ['index'],
|
||||
readonly: function() {
|
||||
if(!obj.isNew()) {
|
||||
readonly: function(state) {
|
||||
if(!obj.isNew(state)) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
@ -223,8 +223,8 @@ export default class PrimaryKeySchema extends BaseUISchema {
|
||||
},{
|
||||
id: 'condeferrable', label: gettext('Deferrable?'),
|
||||
type: 'switch', group: gettext('Definition'), deps: ['index'],
|
||||
readonly: function() {
|
||||
if(!obj.isNew()) {
|
||||
readonly: function(state) {
|
||||
if(!obj.isNew(state)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -244,18 +244,20 @@ export default class PrimaryKeySchema extends BaseUISchema {
|
||||
id: 'condeferred', label: gettext('Deferred?'),
|
||||
type: 'switch', group: gettext('Definition'),
|
||||
deps: ['condeferrable'],
|
||||
readonly: function() {
|
||||
if(!obj.isNew()) {
|
||||
readonly: function(state) {
|
||||
if(!obj.isNew(state)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
disabled: function(state) {
|
||||
// Disable if index is selected.
|
||||
return !(_.isUndefined(state.index) || state.index == '');
|
||||
return !(_.isUndefined(state.index) || state.index == '') || !state.condeferrable;
|
||||
},
|
||||
depChange: (state)=>{
|
||||
if(_.isUndefined(state.index) || state.index == '') {
|
||||
if(!state.condeferrable) {
|
||||
return {condeferred: false};
|
||||
} else if(_.isUndefined(state.index) || state.index == '') {
|
||||
return {};
|
||||
} else {
|
||||
return {condeferred: false};
|
||||
|
@ -158,8 +158,8 @@ export default class UniqueConstraintSchema extends BaseUISchema {
|
||||
return false;
|
||||
},
|
||||
deps: ['index'],
|
||||
readonly: function() {
|
||||
if(!obj.isNew()) {
|
||||
readonly: function(state) {
|
||||
if(!obj.isNew(state)) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
@ -225,8 +225,8 @@ export default class UniqueConstraintSchema extends BaseUISchema {
|
||||
},{
|
||||
id: 'condeferrable', label: gettext('Deferrable?'),
|
||||
type: 'switch', group: gettext('Definition'), deps: ['index'],
|
||||
readonly: function() {
|
||||
if(!obj.isNew()) {
|
||||
readonly: function(state) {
|
||||
if(!obj.isNew(state)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -246,18 +246,20 @@ export default class UniqueConstraintSchema extends BaseUISchema {
|
||||
id: 'condeferred', label: gettext('Deferred?'),
|
||||
type: 'switch', group: gettext('Definition'),
|
||||
deps: ['condeferrable'],
|
||||
readonly: function() {
|
||||
if(!obj.isNew()) {
|
||||
readonly: function(state) {
|
||||
if(!obj.isNew(state)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
disabled: function(state) {
|
||||
// Disable if index is selected.
|
||||
return !(_.isUndefined(state.index) || state.index == '');
|
||||
return !(_.isUndefined(state.index) || state.index == '') || !state.condeferrable;
|
||||
},
|
||||
depChange: (state)=>{
|
||||
if(_.isUndefined(state.index) || state.index == '') {
|
||||
if(!state.condeferrable) {
|
||||
return {condeferred: false};
|
||||
} else if(_.isUndefined(state.index) || state.index == '') {
|
||||
return {};
|
||||
} else {
|
||||
return {condeferred: false};
|
||||
|
@ -64,7 +64,7 @@ export default class VacuumSettingsSchema extends BaseUISchema {
|
||||
var obj = this;
|
||||
return [{
|
||||
id: 'autovacuum_custom', label: gettext('Custom auto-vacuum?'),
|
||||
group: gettext('Table'), mode: ['edit', 'create'],
|
||||
group: gettext('Table'), mode: ['edit', 'create'], skipChange: true,
|
||||
type: 'switch', disabled: function(state) {
|
||||
if(state.is_partitioned) {
|
||||
return true;
|
||||
|
@ -134,7 +134,7 @@ function DataTableHeader({headerGroups}) {
|
||||
: ''}
|
||||
</span>
|
||||
</div>
|
||||
{column.resizable &&
|
||||
{!column.disableResizing &&
|
||||
<div
|
||||
{...column.getResizerProps()}
|
||||
className={classes.resizer}
|
||||
@ -328,16 +328,26 @@ export default function DataGridView({
|
||||
}
|
||||
return 0;
|
||||
}).map((field)=>{
|
||||
let widthParms = {};
|
||||
if(field.width) {
|
||||
widthParms.width = field.width;
|
||||
widthParms.minWidth = field.width;
|
||||
}
|
||||
if(field.minWidth) {
|
||||
widthParms.minWidth = field.minWidth;
|
||||
}
|
||||
if(field.maxWidth) {
|
||||
widthParms.maxWidth = field.maxWidth;
|
||||
}
|
||||
widthParms.disableResizing = Boolean(field.disableResizing);
|
||||
|
||||
let colInfo = {
|
||||
Header: field.label||<> </>,
|
||||
accessor: field.id,
|
||||
field: field,
|
||||
resizable: true,
|
||||
disableResizing: false,
|
||||
sortable: true,
|
||||
...(field.minWidth ? {minWidth: field.minWidth} : {}),
|
||||
...(field.width ? {width: field.width} : {}),
|
||||
...(field.maxWidth ? {maxWidth: field.maxWidth} : {}),
|
||||
...(field.disableResizing ? {disableResizing: field.disableResizing} : {}),
|
||||
...widthParms,
|
||||
Cell: ({value, row, ...other}) => {
|
||||
/* Make sure to take the latest field info from schema */
|
||||
field = _.find(schemaRef.current.fields, (f)=>f.id==field.id) || field;
|
||||
|
@ -125,11 +125,11 @@ export function getFieldMetaData(field, schema, value, viewHelperProps, onlyMode
|
||||
|
||||
let {canAdd, canEdit, canDelete, canAddRow } = field;
|
||||
retData.canAdd = _.isUndefined(canAdd) ? retData.canAdd : evalFunc(schema, canAdd, value);
|
||||
retData.canAdd = !disabled && retData.canAdd;
|
||||
retData.canAdd = !retData.disabled && retData.canAdd;
|
||||
retData.canEdit = _.isUndefined(canEdit) ? retData.canEdit : evalFunc(schema, canEdit, value);
|
||||
retData.canEdit = !disabled && retData.canEdit;
|
||||
retData.canEdit = !retData.disabled && retData.canEdit;
|
||||
retData.canDelete = _.isUndefined(canDelete) ? retData.canDelete : evalFunc(schema, canDelete, value);
|
||||
retData.canDelete = !disabled && retData.canDelete;
|
||||
retData.canDelete = !retData.disabled && retData.canDelete;
|
||||
retData.canAddRow = _.isUndefined(canAddRow) ? retData.canAddRow : evalFunc(schema, canAddRow, value);
|
||||
return retData;
|
||||
}
|
||||
|
@ -138,7 +138,10 @@ function getChangedData(topSchema, viewHelperProps, sessData, stringify=false) {
|
||||
/* At this point the schema assignments like top may not have been done
|
||||
So, only check the mode by passing true to getFieldMetaData */
|
||||
let {modeSupported} = getFieldMetaData(field, schema, {}, viewHelperProps, true);
|
||||
if(!modeSupported) {
|
||||
|
||||
/* If skipChange is true, then field will not be considered for changed data,
|
||||
No change in other behaviour */
|
||||
if(!modeSupported || field.skipChange) {
|
||||
return;
|
||||
}
|
||||
if(typeof(field.type) == 'string' && field.type.startsWith('nested-')) {
|
||||
|
@ -511,7 +511,7 @@ export function InputToggle({cid, value, onChange, options, disabled, readonly,
|
||||
{
|
||||
(options||[]).map((option)=>{
|
||||
const isSelected = option.value === value;
|
||||
const isDisabled = disabled || option.disabled || (readonly && isSelected);
|
||||
const isDisabled = disabled || option.disabled || (readonly && !isSelected);
|
||||
return (
|
||||
<ToggleButton key={option.label} value={option.value} component={isSelected ? PrimaryButton : DefaultButton}
|
||||
disabled={isDisabled} aria-label={option.label}>
|
||||
|
@ -239,9 +239,10 @@ describe('ExclusionConstraintSchema', ()=>{
|
||||
it('columns formatter', ()=>{
|
||||
let formatter = _.find(schemaObj.fields, (f)=>f.id=='columns').cell().controlProps.formatter;
|
||||
expect(formatter.fromRaw([{
|
||||
local_column: 'lid',
|
||||
referenced: 'rid',
|
||||
}])).toBe('(lid) -> (rid)');
|
||||
column: 'lid',
|
||||
},{
|
||||
column: 'rid',
|
||||
}])).toBe('lid, rid');
|
||||
|
||||
expect(formatter.fromRaw([])).toBe('');
|
||||
});
|
||||
|
@ -165,6 +165,7 @@ describe('PrimaryKeySchema', ()=>{
|
||||
});
|
||||
|
||||
state.index = undefined;
|
||||
state.condeferrable = true;
|
||||
expect(getFieldDepChange(schemaObj, 'spcname')(state)).toEqual({});
|
||||
expect(getFieldDepChange(schemaObj, 'include')(state)).toEqual({});
|
||||
expect(getFieldDepChange(schemaObj, 'fillfactor')(state)).toEqual({});
|
||||
|
@ -164,6 +164,7 @@ describe('UniqueConstraintSchema', ()=>{
|
||||
});
|
||||
|
||||
state.index = undefined;
|
||||
state.condeferrable = true;
|
||||
expect(getFieldDepChange(schemaObj, 'spcname')(state)).toEqual({});
|
||||
expect(getFieldDepChange(schemaObj, 'include')(state)).toEqual({});
|
||||
expect(getFieldDepChange(schemaObj, 'fillfactor')(state)).toEqual({});
|
||||
|
Loading…
Reference in New Issue
Block a user