diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.ui.js index 6b4f6f0d168..6d903f20dbe 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.ui.js @@ -125,9 +125,10 @@ export default class PrimaryKeySchema extends BaseUISchema { multiple: true, formatter: { fromRaw: (backendVal, allOptions)=>{ - /* remove the column key and pass as array */ - let optValues = (backendVal||[]).map((singleVal)=>singleVal.column); - return _.filter(allOptions, (opt)=>optValues.indexOf(opt.value)>-1); + /* remove the column key and pass as array preserving constraint column order */ + return (backendVal||[]).map((singleVal)=> + _.find(allOptions, (opt)=>opt.value === singleVal.column) + ).filter(Boolean); }, toRaw: (value)=>{ /* take the array and convert to column key collection */ diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.ui.js index f5c7bf1d3ed..86d68cc2f22 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.ui.js @@ -125,9 +125,10 @@ export default class UniqueConstraintSchema extends BaseUISchema { multiple: true, formatter: { fromRaw: (backendVal, allOptions) => { - /* remove the column key and pass as array */ - let optValues = (backendVal||[]).map((singleVal) => singleVal.column); - return _.filter(allOptions, (opt) => optValues.indexOf(opt.value)>-1); + /* remove the column key and pass as array preserving constraint column order */ + return (backendVal||[]).map((singleVal) => + _.find(allOptions, (opt) => opt.value === singleVal.column) + ).filter(Boolean); }, toRaw: (value)=>{ /* take the array and convert to column key collection */ diff --git a/web/regression/javascript/schema_ui_files/primary_key.ui.spec.js b/web/regression/javascript/schema_ui_files/primary_key.ui.spec.js index 86357a7a359..aaa2081c275 100644 --- a/web/regression/javascript/schema_ui_files/primary_key.ui.spec.js +++ b/web/regression/javascript/schema_ui_files/primary_key.ui.spec.js @@ -138,6 +138,53 @@ describe('PrimaryKeySchema', ()=>{ }); + it('columns cell formatter', ()=>{ + let cellFormatter = _.find(schemaObj.fields, (f)=>f.id=='columns').cell().controlProps.formatter; + expect(cellFormatter.fromRaw([{ + column: 'user_id', + },{ + column: 'client_order_id', + }])).toBe('user_id,client_order_id'); + + expect(cellFormatter.fromRaw([])).toBe(''); + }); + + it('columns type formatter preserves constraint column order', ()=>{ + let typeFormatter = _.find(schemaObj.fields, (f)=>f.id=='columns').type().controlProps.formatter; + + /* allOptions are in table column position order (alphabetical here) */ + let allOptions = [ + {value: 'alpha', label: 'alpha'}, + {value: 'beta', label: 'beta'}, + {value: 'gamma', label: 'gamma'}, + ]; + + /* backendVal comes from the constraint definition in a different order */ + let backendVal = [{column: 'gamma'}, {column: 'alpha'}]; + + let result = typeFormatter.fromRaw(backendVal, allOptions); + + /* result must preserve backendVal order, not allOptions order */ + expect(result).toEqual([ + {value: 'gamma', label: 'gamma'}, + {value: 'alpha', label: 'alpha'}, + ]); + + /* empty and null values should be handled gracefully */ + expect(typeFormatter.fromRaw([], allOptions)).toEqual([]); + expect(typeFormatter.fromRaw(null, allOptions)).toEqual([]); + }); + + it('columns type formatter toRaw', ()=>{ + let typeFormatter = _.find(schemaObj.fields, (f)=>f.id=='columns').type().controlProps.formatter; + expect(typeFormatter.toRaw([{value: 'user_id'}, {value: 'client_order_id'}])).toEqual([ + {column: 'user_id'}, + {column: 'client_order_id'}, + ]); + expect(typeFormatter.toRaw([])).toEqual([]); + expect(typeFormatter.toRaw(null)).toEqual([]); + }); + it('validate', ()=>{ let state = {}; let setError = jest.fn(); diff --git a/web/regression/javascript/schema_ui_files/unique_constraint.ui.spec.js b/web/regression/javascript/schema_ui_files/unique_constraint.ui.spec.js index 12dd8db606f..6bb414efc93 100644 --- a/web/regression/javascript/schema_ui_files/unique_constraint.ui.spec.js +++ b/web/regression/javascript/schema_ui_files/unique_constraint.ui.spec.js @@ -137,6 +137,53 @@ describe('UniqueConstraintSchema', ()=>{ }); + it('columns cell formatter', ()=>{ + let cellFormatter = _.find(schemaObj.fields, (f)=>f.id=='columns').cell().controlProps.formatter; + expect(cellFormatter.fromRaw([{ + column: 'user_id', + },{ + column: 'client_order_id', + }])).toBe('user_id,client_order_id'); + + expect(cellFormatter.fromRaw([])).toBe(''); + }); + + it('columns type formatter preserves constraint column order', ()=>{ + let typeFormatter = _.find(schemaObj.fields, (f)=>f.id=='columns').type().controlProps.formatter; + + /* allOptions are in table column position order (alphabetical here) */ + let allOptions = [ + {value: 'alpha', label: 'alpha'}, + {value: 'beta', label: 'beta'}, + {value: 'gamma', label: 'gamma'}, + ]; + + /* backendVal comes from the constraint definition in a different order */ + let backendVal = [{column: 'gamma'}, {column: 'alpha'}]; + + let result = typeFormatter.fromRaw(backendVal, allOptions); + + /* result must preserve backendVal order, not allOptions order */ + expect(result).toEqual([ + {value: 'gamma', label: 'gamma'}, + {value: 'alpha', label: 'alpha'}, + ]); + + /* empty and null values should be handled gracefully */ + expect(typeFormatter.fromRaw([], allOptions)).toEqual([]); + expect(typeFormatter.fromRaw(null, allOptions)).toEqual([]); + }); + + it('columns type formatter toRaw', ()=>{ + let typeFormatter = _.find(schemaObj.fields, (f)=>f.id=='columns').type().controlProps.formatter; + expect(typeFormatter.toRaw([{value: 'user_id'}, {value: 'client_order_id'}])).toEqual([ + {column: 'user_id'}, + {column: 'client_order_id'}, + ]); + expect(typeFormatter.toRaw([])).toEqual([]); + expect(typeFormatter.toRaw(null)).toEqual([]); + }); + it('validate', ()=>{ let state = {}; let setError = jest.fn();