mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[Synthetics] Fix Private Locations form validation (#167647)
This commit is contained in:
parent
c7b3888522
commit
338e446f97
2 changed files with 43 additions and 23 deletions
|
@ -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',
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue