@@ -1003,6 +1003,168 @@ describe('OpenAPI Conditional Lookup field (e2e)', () => {
10031003 } ) ;
10041004 } ) ;
10051005
1006+ describe ( 'self-table field-reference lookups projecting alternate fields' , ( ) => {
1007+ let table : ITableFullVo ;
1008+ let titleId : string ;
1009+ let nameId : string ;
1010+ let nameMirrorId : string ;
1011+ let title2Id : string ;
1012+ let matchingLookupField : IFieldVo ;
1013+ let rowAliceId : string ;
1014+ let rowBobId : string ;
1015+ let rowCharlieId : string ;
1016+ let rowDaveId : string ;
1017+
1018+ beforeAll ( async ( ) => {
1019+ table = await createTable ( baseId , {
1020+ name : 'ConditionalLookup_Self_AltProjection' ,
1021+ fields : [
1022+ { name : 'Title' , type : FieldType . SingleLineText } as IFieldRo ,
1023+ { name : 'Name' , type : FieldType . SingleLineText } as IFieldRo ,
1024+ { name : 'NameMirror' , type : FieldType . SingleLineText } as IFieldRo ,
1025+ { name : 'Title2' , type : FieldType . SingleLineText } as IFieldRo ,
1026+ ] ,
1027+ records : [
1028+ { fields : { Title : 'T1' , Name : 'Alice' , NameMirror : 'Alice' , Title2 : 'T1-alt' } } ,
1029+ { fields : { Title : 'T2' , Name : 'Bob' , NameMirror : 'Alice' , Title2 : 'T2-alt' } } ,
1030+ { fields : { Title : 'T3' , Name : 'Charlie' , NameMirror : 'Charlie' , Title2 : 'T3-alt' } } ,
1031+ { fields : { Title : 'T4' , Name : 'Dave' , Title2 : 'T4-alt' } } ,
1032+ ] ,
1033+ } ) ;
1034+
1035+ titleId = table . fields . find ( ( f ) => f . name === 'Title' ) ! . id ;
1036+ nameId = table . fields . find ( ( f ) => f . name === 'Name' ) ! . id ;
1037+ nameMirrorId = table . fields . find ( ( f ) => f . name === 'NameMirror' ) ! . id ;
1038+ title2Id = table . fields . find ( ( f ) => f . name === 'Title2' ) ! . id ;
1039+
1040+ rowAliceId = table . records [ 0 ] . id ;
1041+ rowBobId = table . records [ 1 ] . id ;
1042+ rowCharlieId = table . records [ 2 ] . id ;
1043+ rowDaveId = table . records [ 3 ] . id ;
1044+
1045+ const filter : IFilter = {
1046+ conjunction : 'and' ,
1047+ filterSet : [
1048+ {
1049+ fieldId : nameMirrorId ,
1050+ operator : 'is' ,
1051+ value : { type : 'field' , fieldId : nameId } ,
1052+ } ,
1053+ ] ,
1054+ } ;
1055+
1056+ matchingLookupField = await createField ( table . id , {
1057+ name : 'Matching Title2 Values' ,
1058+ type : FieldType . SingleLineText ,
1059+ isLookup : true ,
1060+ isConditionalLookup : true ,
1061+ lookupOptions : {
1062+ foreignTableId : table . id ,
1063+ lookupFieldId : title2Id ,
1064+ filter,
1065+ } as ILookupOptionsRo ,
1066+ } as IFieldRo ) ;
1067+ } ) ;
1068+
1069+ afterAll ( async ( ) => {
1070+ await permanentDeleteTable ( baseId , table . id ) ;
1071+ } ) ;
1072+
1073+ it ( 'should project the requested field from matching self-table rows' , async ( ) => {
1074+ const records = await getRecords ( table . id , { fieldKeyType : FieldKeyType . Id } ) ;
1075+ const rowAlice = records . records . find ( ( r ) => r . id === rowAliceId ) ! ;
1076+ const rowBob = records . records . find ( ( r ) => r . id === rowBobId ) ! ;
1077+ const rowCharlie = records . records . find ( ( r ) => r . id === rowCharlieId ) ! ;
1078+ const rowDave = records . records . find ( ( r ) => r . id === rowDaveId ) ! ;
1079+
1080+ expect ( rowAlice . fields [ matchingLookupField . id ] ) . toEqual ( [ 'T1-alt' ] ) ;
1081+ expect ( rowBob . fields [ matchingLookupField . id ] ) . toEqual ( [ 'T1-alt' ] ) ;
1082+ expect ( rowCharlie . fields [ matchingLookupField . id ] ) . toEqual ( [ 'T3-alt' ] ) ;
1083+ expect ( rowDave . fields [ matchingLookupField . id ] ?? [ ] ) . toEqual ( [ ] ) ;
1084+ } ) ;
1085+ } ) ;
1086+
1087+ describe ( 'self-table field-reference lookups selecting alternate titles' , ( ) => {
1088+ let table : ITableFullVo ;
1089+ let titleId : string ;
1090+ let nameId : string ;
1091+ let name2Id : string ;
1092+ let title2Id : string ;
1093+ let lookupAltTitleField : IFieldVo ;
1094+ let row1Id : string ;
1095+ let row2Id : string ;
1096+ let row3Id : string ;
1097+ let row4Id : string ;
1098+
1099+ beforeAll ( async ( ) => {
1100+ table = await createTable ( baseId , {
1101+ name : 'ConditionalLookup_Self_Title2' ,
1102+ fields : [
1103+ { name : 'Title' , type : FieldType . SingleLineText } as IFieldRo ,
1104+ { name : 'Name' , type : FieldType . SingleLineText } as IFieldRo ,
1105+ { name : 'Name2' , type : FieldType . SingleLineText } as IFieldRo ,
1106+ { name : 'Title2' , type : FieldType . SingleLineText } as IFieldRo ,
1107+ ] ,
1108+ records : [
1109+ { fields : { Title : '00001' , Name : '张三' , Name2 : '张三' , Title2 : '00001' } } ,
1110+ { fields : { Title : '00002' , Name : '李四' , Name2 : null , Title2 : null } } ,
1111+ { fields : { Title : '00003' , Name : '王五' , Name2 : '李四' , Title2 : '00002' } } ,
1112+ { fields : { Title : '00004' , Name : '赵六' , Name2 : '你好' , Title2 : null } } ,
1113+ ] ,
1114+ } ) ;
1115+
1116+ titleId = table . fields . find ( ( f ) => f . name === 'Title' ) ! . id ;
1117+ nameId = table . fields . find ( ( f ) => f . name === 'Name' ) ! . id ;
1118+ name2Id = table . fields . find ( ( f ) => f . name === 'Name2' ) ! . id ;
1119+ title2Id = table . fields . find ( ( f ) => f . name === 'Title2' ) ! . id ;
1120+
1121+ row1Id = table . records [ 0 ] . id ;
1122+ row2Id = table . records [ 1 ] . id ;
1123+ row3Id = table . records [ 2 ] . id ;
1124+ row4Id = table . records [ 3 ] . id ;
1125+
1126+ const filter : IFilter = {
1127+ conjunction : 'and' ,
1128+ filterSet : [
1129+ {
1130+ fieldId : name2Id ,
1131+ operator : 'is' ,
1132+ value : { type : 'field' , fieldId : nameId } ,
1133+ } ,
1134+ ] ,
1135+ } ;
1136+
1137+ lookupAltTitleField = await createField ( table . id , {
1138+ name : 'Title2 via matching Name2' ,
1139+ type : FieldType . SingleLineText ,
1140+ isLookup : true ,
1141+ isConditionalLookup : true ,
1142+ lookupOptions : {
1143+ foreignTableId : table . id ,
1144+ lookupFieldId : title2Id ,
1145+ filter,
1146+ } as ILookupOptionsRo ,
1147+ } as IFieldRo ) ;
1148+ } ) ;
1149+
1150+ afterAll ( async ( ) => {
1151+ await permanentDeleteTable ( baseId , table . id ) ;
1152+ } ) ;
1153+
1154+ it ( 'should return Title2 from foreign rows where host Name2 matches foreign Name' , async ( ) => {
1155+ const records = await getRecords ( table . id , { fieldKeyType : FieldKeyType . Id } ) ;
1156+ const row1 = records . records . find ( ( r ) => r . id === row1Id ) ! ;
1157+ const row2 = records . records . find ( ( r ) => r . id === row2Id ) ! ;
1158+ const row3 = records . records . find ( ( r ) => r . id === row3Id ) ! ;
1159+ const row4 = records . records . find ( ( r ) => r . id === row4Id ) ! ;
1160+
1161+ expect ( row1 . fields [ lookupAltTitleField . id ] ) . toEqual ( [ '00001' ] ) ;
1162+ expect ( row2 . fields [ lookupAltTitleField . id ] ?? [ ] ) . toEqual ( [ ] ) ;
1163+ expect ( row3 . fields [ lookupAltTitleField . id ] ?? [ ] ) . toEqual ( [ ] ) ;
1164+ expect ( row4 . fields [ lookupAltTitleField . id ] ?? [ ] ) . toEqual ( [ ] ) ;
1165+ } ) ;
1166+ } ) ;
1167+
10061168 describe ( 'boolean field reference filters' , ( ) => {
10071169 let foreign : ITableFullVo ;
10081170 let host : ITableFullVo ;
0 commit comments