[Synthetics] Fix Private Locations form validation (#167647)

This commit is contained in:
Abdul Wahab Zahid 2023-10-02 12:55:35 +02:00 committed by GitHub
parent c7b3888522
commit 338e446f97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 23 deletions

View file

@ -4,7 +4,8 @@
* 2.0; you may not use this file except in compliance with the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License
* 2.0. * 2.0.
*/ */
import React from 'react';
import React, { Ref } from 'react';
import { FormattedMessage } from '@kbn/i18n-react'; import { FormattedMessage } from '@kbn/i18n-react';
import { import {
EuiFieldText, EuiFieldText,
@ -14,6 +15,7 @@ import {
EuiCallOut, EuiCallOut,
EuiCode, EuiCode,
EuiLink, EuiLink,
EuiFieldTextProps,
} from '@elastic/eui'; } from '@elastic/eui';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
@ -21,14 +23,14 @@ import { useFormContext, useFormState } from 'react-hook-form';
import { TagsField } from '../components/tags_field'; import { TagsField } from '../components/tags_field';
import { PrivateLocation } from '../../../../../../common/runtime_types'; import { PrivateLocation } from '../../../../../../common/runtime_types';
import { AgentPolicyNeeded } from './agent_policy_needed'; import { AgentPolicyNeeded } from './agent_policy_needed';
import { PolicyHostsField } from './policy_hosts'; import { PolicyHostsField, AGENT_POLICY_FIELD_NAME } from './policy_hosts';
import { selectAgentPolicies } from '../../../state/private_locations'; import { selectAgentPolicies } from '../../../state/private_locations';
export const LocationForm = ({ privateLocations }: { privateLocations: PrivateLocation[] }) => { export const LocationForm = ({ privateLocations }: { privateLocations: PrivateLocation[] }) => {
const { data } = useSelector(selectAgentPolicies); const { data } = useSelector(selectAgentPolicies);
const { control, register, watch } = useFormContext<PrivateLocation>(); const { control, register, getValues } = useFormContext<PrivateLocation>();
const { errors } = useFormState(); const { errors } = useFormState();
const selectedPolicyId = watch('agentPolicyId'); const selectedPolicyId = getValues(AGENT_POLICY_FIELD_NAME);
const selectedPolicy = data?.find((item) => item.id === selectedPolicyId); const selectedPolicy = data?.find((item) => item.id === selectedPolicyId);
const tagsList = privateLocations.reduce((acc, item) => { const tagsList = privateLocations.reduce((acc, item) => {
@ -46,7 +48,7 @@ export const LocationForm = ({ privateLocations }: { privateLocations: PrivateLo
isInvalid={Boolean(errors?.label)} isInvalid={Boolean(errors?.label)}
error={errors?.label?.message} error={errors?.label?.message}
> >
<EuiFieldText <FieldText
data-test-subj="syntheticsLocationFormFieldText" data-test-subj="syntheticsLocationFormFieldText"
fullWidth fullWidth
aria-label={LOCATION_NAME_LABEL} aria-label={LOCATION_NAME_LABEL}
@ -64,7 +66,7 @@ export const LocationForm = ({ privateLocations }: { privateLocations: PrivateLo
/> />
</EuiFormRow> </EuiFormRow>
<EuiSpacer /> <EuiSpacer />
<PolicyHostsField errors={errors} control={control} privateLocations={privateLocations} /> <PolicyHostsField privateLocations={privateLocations} />
<EuiSpacer /> <EuiSpacer />
<TagsField tagsList={tagsList} control={control} errors={errors} /> <TagsField tagsList={tagsList} control={control} errors={errors} />
<EuiSpacer /> <EuiSpacer />
@ -133,6 +135,12 @@ export const LocationForm = ({ privateLocations }: { privateLocations: PrivateLo
); );
}; };
const FieldText = React.forwardRef<HTMLInputElement, EuiFieldTextProps>(
(props, ref: Ref<HTMLInputElement>) => (
<EuiFieldText data-test-subj="syntheticsFieldTextFieldText" {...props} inputRef={ref} />
)
);
export const AGENT_CALLOUT_TITLE = i18n.translate( export const AGENT_CALLOUT_TITLE = i18n.translate(
'xpack.synthetics.monitorManagement.agentCallout.title', 'xpack.synthetics.monitorManagement.agentCallout.title',
{ {

View file

@ -6,14 +6,14 @@
*/ */
import React from 'react'; import React from 'react';
import { Controller, FieldErrors, Control } from 'react-hook-form'; import { Controller, useFormContext } from 'react-hook-form';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { import {
EuiFlexGroup, EuiFlexGroup,
EuiFlexItem, EuiFlexItem,
EuiFormRow, EuiFormRow,
EuiHealth, EuiHealth,
EuiSuperSelectProps,
EuiSuperSelect, EuiSuperSelect,
EuiText, EuiText,
EuiToolTip, EuiToolTip,
@ -23,16 +23,17 @@ import { i18n } from '@kbn/i18n';
import { PrivateLocation } from '../../../../../../common/runtime_types'; import { PrivateLocation } from '../../../../../../common/runtime_types';
import { selectAgentPolicies } from '../../../state/private_locations'; import { selectAgentPolicies } from '../../../state/private_locations';
export const PolicyHostsField = ({ export const AGENT_POLICY_FIELD_NAME = 'agentPolicyId';
errors,
control, export const PolicyHostsField = ({ privateLocations }: { privateLocations: PrivateLocation[] }) => {
privateLocations,
}: {
errors: FieldErrors;
control: Control<PrivateLocation, any>;
privateLocations: PrivateLocation[];
}) => {
const { data } = useSelector(selectAgentPolicies); const { data } = useSelector(selectAgentPolicies);
const {
control,
formState: { isSubmitted },
trigger,
} = useFormContext<PrivateLocation>();
const { isTouched, error } = control.getFieldState(AGENT_POLICY_FIELD_NAME);
const showFieldInvalid = (isSubmitted || isTouched) && !!error;
const policyHostsOptions = data?.map((item) => { const policyHostsOptions = data?.map((item) => {
const hasLocation = privateLocations.find((location) => location.agentPolicyId === item.id); const hasLocation = privateLocations.find((location) => location.agentPolicyId === item.id);
@ -91,16 +92,16 @@ export const PolicyHostsField = ({
<EuiFormRow <EuiFormRow
fullWidth fullWidth
label={POLICY_HOST_LABEL} label={POLICY_HOST_LABEL}
helpText={!errors?.agentPolicyId ? SELECT_POLICY_HOSTS_HELP_TEXT : undefined} helpText={showFieldInvalid ? SELECT_POLICY_HOSTS_HELP_TEXT : undefined}
isInvalid={!!errors?.agentPolicyId} isInvalid={showFieldInvalid}
error={SELECT_POLICY_HOSTS} error={showFieldInvalid ? SELECT_POLICY_HOSTS : undefined}
> >
<Controller <Controller
name="agentPolicyId" name={AGENT_POLICY_FIELD_NAME}
control={control} control={control}
rules={{ required: true }} rules={{ required: true }}
render={({ field }) => ( render={({ field }) => (
<EuiSuperSelect <SuperSelect
fullWidth fullWidth
aria-label={SELECT_POLICY_HOSTS} aria-label={SELECT_POLICY_HOSTS}
placeholder={SELECT_POLICY_HOSTS} placeholder={SELECT_POLICY_HOSTS}
@ -108,9 +109,12 @@ export const PolicyHostsField = ({
itemLayoutAlign="top" itemLayoutAlign="top"
popoverProps={{ repositionOnScroll: true }} popoverProps={{ repositionOnScroll: true }}
hasDividers hasDividers
isInvalid={!!errors?.agentPolicyId} isInvalid={showFieldInvalid}
options={policyHostsOptions ?? []} options={policyHostsOptions ?? []}
{...field} {...field}
onBlur={async () => {
await trigger();
}}
/> />
)} )}
/> />
@ -136,3 +140,11 @@ const SELECT_POLICY_HOSTS_HELP_TEXT = i18n.translate(
const POLICY_HOST_LABEL = i18n.translate('xpack.synthetics.monitorManagement.policyHost', { const POLICY_HOST_LABEL = i18n.translate('xpack.synthetics.monitorManagement.policyHost', {
defaultMessage: 'Agent policy', defaultMessage: 'Agent policy',
}); });
export const SuperSelect = React.forwardRef<HTMLSelectElement, EuiSuperSelectProps<string>>(
(props, ref) => (
<span ref={ref} tabIndex={-1}>
<EuiSuperSelect data-test-subj="syntheticsAgentPolicySelect" {...props} />
</span>
)
);