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