@@ -21,6 +21,12 @@ import { Observable, combineLatest, map, startWith } from 'rxjs';
2121import { CommonModalComponent } from '../../../../../shared-standalone-component-lib/components' ;
2222import { CommonFormHelpersService } from '../../../../../shared/services/common-form-helpers.service' ;
2323import { CommonModalConfig } from '../../../../../shared-standalone-component-lib/components/common-modal/common-modal.types' ;
24+ import {
25+ ExperimentCondition ,
26+ WeightingMethod ,
27+ WEIGHTING_METHOD ,
28+ } from '../../../../../core/experiments/store/experiments.model' ;
29+ import { distributeWeightsEqually , WEIGHT_CONFIG } from '../../../../../core/experiments/condition-helper.service' ;
2430
2531export interface ConditionWeightUpdate {
2632 conditionId : string ;
@@ -52,15 +58,15 @@ export class EditConditionWeightsModalComponent implements OnInit {
5258 conditions : ConditionWeightUpdate [ ] = [ ] ;
5359 weightingMethods = [
5460 {
55- value : 'equal' ,
61+ value : WEIGHTING_METHOD . EQUAL ,
5662 name : this . translate . instant ( 'experiments.edit-condition-weights-modal.equal-assignment-weights.label.text' ) ,
5763 description : this . translate . instant (
5864 'experiments.edit-condition-weights-modal.equal-assignment-weights.description.text'
5965 ) ,
6066 disabled : false ,
6167 } ,
6268 {
63- value : 'custom' ,
69+ value : WEIGHTING_METHOD . CUSTOM ,
6470 name : this . translate . instant ( 'experiments.edit-condition-weights-modal.custom-percentages.label.text' ) ,
6571 description : this . translate . instant (
6672 'experiments.edit-condition-weights-modal.custom-percentages.description.text'
@@ -71,7 +77,10 @@ export class EditConditionWeightsModalComponent implements OnInit {
7177
7278 constructor (
7379 @Inject ( MAT_DIALOG_DATA )
74- public config : CommonModalConfig < { experimentWeightsArray : ConditionWeightUpdate [ ] } > ,
80+ public config : CommonModalConfig < {
81+ experimentWeightsArray : ConditionWeightUpdate [ ] ;
82+ weightingMethod : WeightingMethod ;
83+ } > ,
7584 public dialog : MatDialog ,
7685 private readonly formBuilder : FormBuilder ,
7786 private translate : TranslateService ,
@@ -83,28 +92,25 @@ export class EditConditionWeightsModalComponent implements OnInit {
8392 }
8493
8594 createconditionWeightForm ( ) : void {
86- const { experimentWeightsArray } = this . config . params ;
95+ const { experimentWeightsArray, weightingMethod } = this . config . params ;
8796 this . conditions = experimentWeightsArray ;
8897
89- // Determine initial weighting method based on existing weights
90- const initialWeightingMethod = this . determineInitialWeightingMethod ( experimentWeightsArray ) ;
91-
9298 // Create FormArray for conditions with individual validators
9399 const conditionsFormArray = this . formBuilder . array (
94100 experimentWeightsArray . map ( ( condition ) =>
95101 this . formBuilder . group ( {
96102 conditionCode : [ condition . conditionCode ] ,
97103 assignmentWeight : [
98104 condition . assignmentWeight ,
99- [ Validators . required , Validators . min ( 0 ) , Validators . max ( 100 ) , this . decimalValidator ] ,
105+ [ Validators . required , Validators . min ( 0 ) , Validators . max ( WEIGHT_CONFIG . TOTAL_WEIGHT ) , this . decimalValidator ] ,
100106 ] ,
101107 } )
102108 ) ,
103109 [ this . totalWeightValidator ] // Array-level validator for sum = 100
104110 ) ;
105111
106112 this . conditionWeightForm = this . formBuilder . group ( {
107- weightingMethod : [ initialWeightingMethod , Validators . required ] ,
113+ weightingMethod : [ weightingMethod , Validators . required ] ,
108114 conditions : conditionsFormArray ,
109115 } ) ;
110116
@@ -115,38 +121,13 @@ export class EditConditionWeightsModalComponent implements OnInit {
115121 this . watchWeightingMethodChanges ( ) ;
116122
117123 // Set initial input state based on the determined method
118- if ( initialWeightingMethod === 'equal' ) {
124+ if ( weightingMethod === WEIGHTING_METHOD . EQUAL ) {
119125 this . disableWeightInputs ( ) ;
120126 } else {
121127 this . enableWeightInputs ( ) ;
122128 }
123129 }
124130
125- private determineInitialWeightingMethod ( conditions : ConditionWeightUpdate [ ] ) : string {
126- if ( ! conditions || conditions . length === 0 ) {
127- return 'equal' ;
128- }
129-
130- if ( conditions . length === 1 ) {
131- // Single condition should always be 100%
132- return Math . abs ( conditions [ 0 ] . assignmentWeight - 100 ) < 0.01 ? 'equal' : 'custom' ;
133- }
134-
135- const expectedEqualWeight = 100 / conditions . length ;
136-
137- // Check if all weights are close to the expected equal distribution
138- const areWeightsEquallyDistributed = conditions . every (
139- ( condition ) => Math . abs ( condition . assignmentWeight - expectedEqualWeight ) < 0.01
140- ) ;
141-
142- // Additional check: ensure total is close to 100%
143- const totalWeight = conditions . reduce ( ( sum , condition ) => sum + condition . assignmentWeight , 0 ) ;
144- const isTotalValid = Math . abs ( totalWeight - 100 ) < 0.01 ;
145-
146- // Return 'equal' only if weights are equally distributed AND total is valid
147- return areWeightsEquallyDistributed && isTotalValid ? 'equal' : 'custom' ;
148- }
149-
150131 private setupFormValidation ( ) : void {
151132 this . isPrimaryButtonDisabled$ = combineLatest ( [
152133 this . conditionWeightForm . statusChanges . pipe ( startWith ( this . conditionWeightForm . status ) ) ,
@@ -166,10 +147,10 @@ export class EditConditionWeightsModalComponent implements OnInit {
166147 this . conditionWeightForm . get ( 'weightingMethod' ) ?. valueChanges . subscribe ( ( method ) => {
167148 this . conditionWeightForm . markAsDirty ( ) ;
168149
169- if ( method === 'equal' ) {
170- this . distributeWeightsEqually ( ) ;
150+ if ( method === WEIGHTING_METHOD . EQUAL ) {
151+ this . distributeWeightsEquallyInFormControls ( ) ;
171152 this . disableWeightInputs ( ) ;
172- } else if ( method === 'custom' ) {
153+ } else if ( method === WEIGHTING_METHOD . CUSTOM ) {
173154 this . enableWeightInputs ( ) ;
174155 } else if ( method === null ) {
175156 this . disableWeightInputs ( ) ;
@@ -188,9 +169,9 @@ export class EditConditionWeightsModalComponent implements OnInit {
188169 return { invalidNumber : true } ;
189170 }
190171
191- // Allow up to 2 decimal places
172+ // Allow up to configured decimal places
192173 const decimalPlaces = ( control . value . toString ( ) . split ( '.' ) [ 1 ] || '' ) . length ;
193- if ( decimalPlaces > 2 ) {
174+ if ( decimalPlaces > WEIGHT_CONFIG . DECIMAL_PLACES ) {
194175 return { tooManyDecimals : true } ;
195176 }
196177
@@ -210,13 +191,13 @@ export class EditConditionWeightsModalComponent implements OnInit {
210191 } ,
211192 [ 0 , { } ] as [ number , ValidationErrors ]
212193 ) ;
213- const isValid = Math . abs ( total - 100 ) < 0.01 ;
194+ const isValid = Math . abs ( total - WEIGHT_CONFIG . TOTAL_WEIGHT ) < WEIGHT_CONFIG . VALIDATION_TOLERANCE ;
214195 const totalValidation = isValid
215196 ? { }
216197 : {
217198 totalWeightInvalid : {
218199 actualTotal : Math . round ( total * 100 ) / 100 ,
219- expectedTotal : 100 ,
200+ expectedTotal : WEIGHT_CONFIG . TOTAL_WEIGHT ,
220201 } ,
221202 } ;
222203 const allErrors = {
@@ -241,18 +222,13 @@ export class EditConditionWeightsModalComponent implements OnInit {
241222 } , 0 ) ;
242223 }
243224
244- distributeWeightsEqually ( ) : void {
245- const equalWeight = Math . round ( ( 100 / this . conditions . length ) * 100 ) / 100 ;
246- let remainingWeight = 100 ;
225+ distributeWeightsEquallyInFormControls ( ) : void {
226+ // Use service to calculate equal weights
227+ distributeWeightsEqually ( this . conditions ) ;
247228
229+ // Apply to form controls
248230 this . conditionsFormArray . controls . forEach ( ( control , index ) => {
249- if ( index === this . conditionsFormArray . controls . length - 1 ) {
250- // Last condition gets the remaining weight to ensure total = 100
251- control . get ( 'assignmentWeight' ) ?. setValue ( Math . round ( remainingWeight * 100 ) / 100 ) ;
252- } else {
253- control . get ( 'assignmentWeight' ) ?. setValue ( equalWeight ) ;
254- remainingWeight -= equalWeight ;
255- }
231+ control . get ( 'assignmentWeight' ) ?. setValue ( this . conditions [ index ] . assignmentWeight ) ;
256232 } ) ;
257233 }
258234
0 commit comments