1
+ import { AdapterFormDefinition } from "@communitiesuk/model" ;
2
+
3
+ export function sortConditionsBySourceFieldOrder ( data : AdapterFormDefinition ) : AdapterFormDefinition {
4
+ const sortedData = { ...data } ;
5
+
6
+ sortedData . pages = data . pages . map ( page => {
7
+ if ( ! page . next || page . next . length === 0 ) {
8
+ return page ;
9
+ }
10
+
11
+ // Find the source page that these conditions reference
12
+ const sourcePagePath = getConditionSourcePage ( page . next , data ) ;
13
+ if ( ! sourcePagePath ) {
14
+ return page ; // No conditions to sort
15
+ }
16
+
17
+ const sourcePage = data . pages . find ( p => p . path === sourcePagePath ) ;
18
+ if ( ! sourcePage ) {
19
+ return page ;
20
+ }
21
+
22
+ // Get the order of options from the source field (checkboxes, etc.)
23
+ const fieldOptionOrder = getFieldOptionOrder ( sourcePage , data ) ;
24
+
25
+ // Sort conditions based on the order of options in the source field
26
+ const sortedNext = [ ...page . next ] . sort ( ( a , b ) => {
27
+ // Non-conditional links first
28
+ if ( ! a . condition && ! b . condition ) return 0 ;
29
+ if ( ! a . condition ) return - 1 ;
30
+ if ( ! b . condition ) return 1 ;
31
+
32
+ // Get the option values these conditions check for
33
+ const aOptionValue = getConditionOptionValue ( a . condition , data ) ;
34
+ const bOptionValue = getConditionOptionValue ( b . condition , data ) ;
35
+
36
+ // Sort by the order they appear in the source field
37
+ const aIndex = fieldOptionOrder . indexOf ( aOptionValue ) ;
38
+ const bIndex = fieldOptionOrder . indexOf ( bOptionValue ) ;
39
+
40
+ // If both found, sort by their field order
41
+ if ( aIndex !== - 1 && bIndex !== - 1 ) {
42
+ return aIndex - bIndex ;
43
+ }
44
+
45
+ // Fallback to alphabetical for any not found
46
+ return a . path . localeCompare ( b . path ) ;
47
+ } ) ;
48
+
49
+ return {
50
+ ...page ,
51
+ next : sortedNext
52
+ } ;
53
+ } ) ;
54
+
55
+ return sortedData ;
56
+ }
57
+
58
+ function getConditionSourcePage ( nextLinks : any [ ] , data : AdapterFormDefinition ) : string | null {
59
+ // Find the first conditional link and determine what page it's checking
60
+ const conditionalLink = nextLinks . find ( link => link . condition ) ;
61
+ if ( ! conditionalLink ) return null ;
62
+
63
+ const condition = data . conditions ?. find ( c => c . name === conditionalLink . condition ) ;
64
+ if ( ! condition ?. value ?. conditions ?. [ 0 ] ?. field ?. name ) return null ;
65
+
66
+ // Extract page path from field name (e.g., "FabDefault.ZRERCV" -> page with component "ZRERCV")
67
+ const fieldName = condition . value . conditions [ 0 ] . field . name ;
68
+ const componentName = fieldName . includes ( '.' ) ?
69
+ fieldName . split ( '.' ) . pop ( ) : fieldName ;
70
+
71
+ // Find the page that contains this component
72
+ return data . pages . find ( page =>
73
+ page . components ?. some ( component => component . name === componentName )
74
+ ) ?. path || null ;
75
+ }
76
+
77
+ function getFieldOptionOrder ( page : any , data : AdapterFormDefinition ) : string [ ] {
78
+ // Find the checkboxes field (or other multi-select field)
79
+ const checkboxField = page . components ?. find ( component =>
80
+ component . type === 'CheckboxesField' ||
81
+ component . type === 'RadiosField'
82
+ ) ;
83
+
84
+ if ( ! checkboxField ) return [ ] ;
85
+
86
+ // If it uses a list reference, get the list
87
+ if ( checkboxField . values ?. type === 'listRef' ) {
88
+ const listName = checkboxField . values . list || checkboxField . list ;
89
+ const list = data . lists ?. find ( l => l . name === listName ) ;
90
+ return list ?. items ?. map ( item => item . value ) || [ ] ;
91
+ }
92
+
93
+ // If it has inline items
94
+ return checkboxField . items ?. map ( item => item . value ) || [ ] ;
95
+ }
96
+
97
+ function getConditionOptionValue ( conditionName : string , data : AdapterFormDefinition ) : string {
98
+ const condition = data . conditions ?. find ( c => c . name === conditionName ) ;
99
+ return condition ?. value ?. conditions ?. [ 0 ] ?. value ?. value || '' ;
100
+ }
0 commit comments