Fix column ordering in unique/primary key constraint properties

The fromRaw formatter for the Columns field in unique constraint and
primary key properties used _.filter(allOptions, ...), which preserved
the order of allOptions (table column position) rather than the
constraint-defined column order from backendVal. Replaced with _.find
mapped over backendVal to preserve the correct constraint column order.

Added unit tests for cell and type formatter functions to verify
column ordering is preserved.
pull/9661/head
balodis 2026-02-23 13:41:38 +02:00 committed by GitHub
parent 93e2f23a48
commit 080fcc1cfb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 102 additions and 6 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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();

View File

@ -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();