@ -14,6 +14,8 @@ import {
Select ,
Switch ,
useStyles2 ,
Badge ,
VerticalGroup ,
} from '@grafana/ui' ;
import { AmRouteReceiver , FormAmRoute } from '../../types/amroutes' ;
import {
@ -56,73 +58,85 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
< FieldArray name = "object_matchers" control = { control } >
{ ( { fields , append , remove } ) = > (
< >
< div > Matching labels < / div >
< div className = { styles . matchersContainer } >
{ fields . map ( ( field , index ) = > {
const localPath = ` object_matchers[ ${ index } ] ` ;
return (
< HorizontalGroup key = { field . id } align = "flex-start" >
< Field
label = "Label"
invalid = { ! ! errors . object_matchers ? . [ index ] ? . name }
error = { errors . object_matchers ? . [ index ] ? . name ? . message }
>
< Input
{ . . . register ( ` ${ localPath } .name ` , { required : 'Field is required' } ) }
defaultValue = { field . name }
placeholder = "label"
/ >
< / Field >
< Field label = { 'Operator' } >
< InputControl
render = { ( { field : { onChange , ref , . . . field } } ) = > (
< Select
{ . . . field }
className = { styles . matchersOperator }
onChange = { ( value ) = > onChange ( value ? . value ) }
options = { matcherFieldOptions }
aria - label = "Operator"
menuShouldPortal
< VerticalGroup justify = "flex-start" spacing = "md" >
< div > Matching labels < / div >
{ fields . length === 0 && (
< Badge
color = "orange"
className = { styles . noMatchersWarning }
icon = "exclamation-triangle"
text = "If no matchers are specified, this notification policy will handle all alert instances."
/ >
) }
{ fields . length > 0 && (
< div className = { styles . matchersContainer } >
{ fields . map ( ( field , index ) = > {
const localPath = ` object_matchers[ ${ index } ] ` ;
return (
< HorizontalGroup key = { field . id } align = "flex-start" >
< Field
label = "Label"
invalid = { ! ! errors . object_matchers ? . [ index ] ? . name }
error = { errors . object_matchers ? . [ index ] ? . name ? . message }
>
< Input
{ . . . register ( ` ${ localPath } .name ` , { required : 'Field is required' } ) }
defaultValue = { field . name }
placeholder = "label"
/ >
< / Field >
< Field label = { 'Operator' } >
< InputControl
render = { ( { field : { onChange , ref , . . . field } } ) = > (
< Select
{ . . . field }
className = { styles . matchersOperator }
onChange = { ( value ) = > onChange ( value ? . value ) }
options = { matcherFieldOptions }
aria - label = "Operator"
menuShouldPortal
/ >
) }
defaultValue = { field . operator }
control = { control }
name = { ` ${ localPath } .operator ` as const }
rules = { { required : { value : true , message : 'Required.' } } }
/ >
) }
defaultValue = { field . operator }
control = { control }
name = { ` ${ localPath } .operator ` as const }
rules = { { required : { value : true , message : 'Required.' } } }
/ >
< / Field >
< Field
label = "Value"
invalid = { ! ! errors . object_matchers ? . [ index ] ? . value }
error = { errors . object_matchers ? . [ index ] ? . value ? . message }
>
< Input
{ . . . register ( ` ${ localPath } .value ` , { required : 'Field is required' } ) }
defaultValue = { field . value }
placeholder = "value"
/ >
< / Field >
< IconButton
className = { styles . removeButton }
tooltip = "Remove matcher"
name = { 'trash-alt' }
onClick = { ( ) = > remove ( index ) }
>
Remove
< / IconButton >
< / HorizontalGroup >
) ;
} ) }
< / div >
< Button
className = { styles . addMatcherBtn }
icon = "plus"
onClick = { ( ) = > append ( emptyArrayFieldMatcher ) }
variant = "secondary"
type = "button"
>
Add matcher
< / Button >
< / Field >
< Field
label = "Value"
invalid = { ! ! errors . object_matchers ? . [ index ] ? . value }
error = { errors . object_matchers ? . [ index ] ? . value ? . message }
>
< Input
{ . . . register ( ` ${ localPath } .value ` , { required : 'Field is required' } ) }
defaultValue = { field . value }
placeholder = "value"
/ >
< / Field >
< IconButton
className = { styles . removeButton }
tooltip = "Remove matcher"
name = { 'trash-alt' }
onClick = { ( ) = > remove ( index ) }
>
Remove
< / IconButton >
< / HorizontalGroup >
) ;
} ) }
< / div >
) }
< Button
className = { styles . addMatcherBtn }
icon = "plus"
onClick = { ( ) = > append ( emptyArrayFieldMatcher ) }
variant = "secondary"
type = "button"
>
Add matcher
< / Button >
< / VerticalGroup >
< / >
) }
< / FieldArray >
@ -376,5 +390,8 @@ const getStyles = (theme: GrafanaTheme2) => {
margin - left : $ { theme . spacing ( 1.5 ) } ;
}
` ,
noMatchersWarning : css `
padding : $ { theme . spacing ( 1 ) } $ { theme . spacing ( 2 ) } ;
` ,
} ;
} ;