11import { Rule , RuleVerb } from "../../spec/authoringTypes" ;
22const verbs : RuleVerb [ ] = [ "switch_profile" , "press" , "regress" , "apply_policy" ] ;
33
4- export default function RuleForm ( { value : rule , onChange } : { value : Rule ; onChange : ( r : Rule ) => void } ) {
5- function setArg ( key : string , val : unknown ) {
6- const args : Record < string , unknown > = { ...( rule . then . args ?? { } ) } ;
7- if ( val === undefined || val === "" ) {
8- delete args [ key ] ;
9- } else {
10- args [ key ] = val ;
11- }
12- onChange ( { ...rule , then : { ...rule . then , args } } ) ;
4+ export default function RuleForm ( { value, onChange } : { value : Rule ; onChange : ( r : Rule ) => void } ) {
5+ function setArg ( k : string , v : any ) {
6+ const args = { ...( value . then . args ?? { } ) , [ k ] : v } ;
7+ onChange ( { ...value , then : { ...value . then , args } } ) ;
138 }
149 return (
1510 < div className = "space-y-2 text-sm" >
1611 < label className = "block" >
1712 < span className = "block" > Rule ID</ span >
1813 < input
1914 className = "w-full border rounded px-2 py-1"
20- value = { rule . id }
21- onChange = { ( e ) => onChange ( { ...rule , id : e . target . value } ) }
15+ value = { value . id }
16+ onChange = { ( e ) => onChange ( { ...value , id : e . target . value } ) }
2217 />
2318 </ label >
2419 < label className = "block" >
2520 < span className = "block" > When (expression)</ span >
2621 < input
2722 className = "w-full border rounded px-2 py-1"
28- value = { rule . when }
29- onChange = { ( e ) => onChange ( { ...rule , when : e . target . value } ) }
23+ value = { value . when }
24+ onChange = { ( e ) => onChange ( { ...value , when : e . target . value } ) }
3025 />
3126 </ label >
3227 < label className = "block" >
3328 < span className = "block" > Then (verb)</ span >
3429 < select
3530 className = "w-full border rounded px-2 py-1"
36- value = { rule . then . verb }
37- onChange = { ( e ) => onChange ( { ...rule , then : { ...rule . then , verb : e . target . value as RuleVerb } } ) }
31+ value = { value . then . verb }
32+ onChange = { ( e ) => onChange ( { ...value , then : { ...value . then , verb : e . target . value as any } } ) }
3833 >
3934 { verbs . map ( ( v ) => (
4035 < option key = { v } value = { v } >
@@ -48,26 +43,16 @@ export default function RuleForm({ value: rule, onChange }: { value: Rule; onCha
4843 < span className = "block" > Arg: target/policy</ span >
4944 < input
5045 className = "w-full border rounded px-2 py-1"
51- value = { String ( ( rule . then . args ?? { } ) . target ?? ( rule . then . args ?? { } ) . policy ?? "" ) }
46+ value = { String ( ( value . then . args ?? { } ) . target ?? ( value . then . args ?? { } ) . policy ?? "" ) }
5247 onChange = { ( e ) => setArg ( "target" , e . target . value ) }
5348 />
5449 </ label >
5550 < label className = "block" >
5651 < span className = "block" > Arg: delta/factor</ span >
5752 < input
5853 className = "w-full border rounded px-2 py-1"
59- value = { String ( ( rule . then . args ?? { } ) . delta ?? ( rule . then . args ?? { } ) . factor ?? "" ) }
60- onChange = { ( e ) => {
61- const raw = e . target . value ;
62- const num = Number ( raw ) ;
63- if ( raw . trim ( ) === "" ) {
64- setArg ( "delta" , undefined ) ;
65- } else if ( Number . isFinite ( num ) ) {
66- setArg ( "delta" , num ) ;
67- } else {
68- setArg ( "delta" , raw ) ;
69- }
70- } }
54+ value = { String ( ( value . then . args ?? { } ) . delta ?? ( value . then . args ?? { } ) . factor ?? "" ) }
55+ onChange = { ( e ) => setArg ( "delta" , Number ( e . target . value ) || e . target . value ) }
7156 />
7257 </ label >
7358 </ div >
@@ -77,16 +62,16 @@ export default function RuleForm({ value: rule, onChange }: { value: Rule; onCha
7762 < input
7863 type = "number"
7964 className = "w-full border rounded px-2 py-1"
80- value = { rule . cooldown ?? "" }
81- onChange = { ( e ) => onChange ( { ...rule , cooldown : n ( e . target . value ) } ) }
65+ value = { value . cooldown ?? "" }
66+ onChange = { ( e ) => onChange ( { ...value , cooldown : n ( e . target . value ) } ) }
8267 />
8368 </ label >
8469 < label className = "block" >
8570 < span className = "block" > Scope</ span >
8671 < select
8772 className = "w-full border rounded px-2 py-1"
88- value = { rule . scope ?? "" }
89- onChange = { ( e ) => onChange ( { ...rule , scope : ( e . target . value as Rule [ "scope" ] ) || undefined } ) }
73+ value = { value . scope ?? "" }
74+ onChange = { ( e ) => onChange ( { ...value , scope : ( e . target . value as any ) || undefined } ) }
9075 >
9176 < option value = "" > —</ option >
9277 < option > roll</ option >
@@ -98,8 +83,8 @@ export default function RuleForm({ value: rule, onChange }: { value: Rule; onCha
9883 < span className = "block" > Guards (csv)</ span >
9984 < input
10085 className = "w-full border rounded px-2 py-1"
101- value = { ( rule . guards ?? [ ] ) . join ( "," ) }
102- onChange = { ( e ) => onChange ( { ...rule , guards : csv ( e . target . value ) } ) }
86+ value = { ( value . guards ?? [ ] ) . join ( "," ) }
87+ onChange = { ( e ) => onChange ( { ...value , guards : csv ( e . target . value ) } ) }
10388 />
10489 </ label >
10590 </ div >
@@ -111,8 +96,5 @@ function n(v: string) {
11196 return Number . isFinite ( x ) ? x : undefined ;
11297}
11398function csv ( v : string ) {
114- return v
115- . split ( "," )
116- . map ( ( s ) => s . trim ( ) )
117- . filter ( Boolean ) ;
99+ return v . split ( "," ) . map ( ( s ) => s . trim ( ) ) . filter ( Boolean ) ;
118100}
0 commit comments