Skip to content

Commit

Permalink
entity form validation
Browse files Browse the repository at this point in the history
  • Loading branch information
nreese committed Aug 29, 2023
1 parent 5ccc20b commit d14f6b1
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ function getGeoFields(fields: DataViewField[]) {

interface Props {
data: DataPublicPluginStart;
getValidationError: (key: string) => string | null;
ruleParams: GeoContainmentAlertParams;
setDataViewId: (id: string) => void;
setDataViewTitle: (title: string) => void;
Expand Down Expand Up @@ -86,6 +87,44 @@ export const EntityForm = (props: Props) => {
};
}, [props.ruleParams.indexId]);

function getDataViewError() {
const validationError = props.getValidationError('index');
if (validationError) {
return validationError;
}

if (dataView && dateFields.length === 0) {
return i18n.translate('xpack.stackAlerts.geoContainment.noDateFieldInIndexPattern.message', {
defaultMessage:
'Data view does not contain date fields.',
});
}

if (dataView && geoFields.length === 0) {
return i18n.translate('xpack.stackAlerts.geoContainment.noGeoFieldInIndexPattern.message', {
defaultMessage:
'Data view does not contain geospatial fields. Must have one of type: {geoFieldTypes}.',
values: {
geoFieldTypes: ENTITY_GEO_FIELD_TYPES.join(', '),
},
});
}

if (dataViewNotFound) {
return i18n.translate('xpack.stackAlerts.geoContainment.dataViewNotFound', {
defaultMessage: `Unable to find data view '{id}'`,
values: { id: props.ruleParams.indexId },
});
}

return null;
}

const dataViewError = getDataViewError();
const dateFieldError = props.getValidationError('dateField');
const geoFieldError = props.getValidationError('geoField');
const entityFieldError = props.getValidationError('entity');

return (
<EuiPanel>
<EuiTitle size="xs">
Expand All @@ -101,24 +140,39 @@ export const EntityForm = (props: Props) => {

<EuiSkeletonText lines={3} size="s" isLoading={isLoading}>
<EuiFormRow
error={dataViewError}
isInvalid={Boolean(dataViewError)}
label={i18n.translate('xpack.stackAlerts.geoContainment.dataViewLabel', {
defaultMessage: 'Data view',
})}
>
<DataViewSelect
dataViewId={props.ruleParams.indexId}
data={props.data}
isInvalid={false}
isInvalid={Boolean(dataViewError)}
onChange={(dataView: DataView) => {
props.setDataViewId(dataView.id);
props.setDataViewTitle(dataView.title);

const dateFields = getDateFields(dataView.fields);
props.setDateField(dateFields.length ? dateFields[0].name : '');
if (dateFields.length) {
props.setDateField(dateFields[0].name);
} else if ('dateField' in props.ruleParams) {
props.setDateField('');
}

// do not attempt to auto select entity field
// there can be many matches so auto selecting the correct field is improbable
props.setEntityField('');
if ('entity' in props.ruleParams) {
props.setEntityField('');
}

const geoFields = getGeoFields(dataView.fields);
props.setGeoField(geoFields.length ? geoFields[0].name : '');
if (geoFields.length) {
props.setGeoField(geoFields[0].name);
} else if ('geoField' in props.ruleParams) {
props.setGeoField('');
}
}}
unifiedSearch={props.unifiedSearch}
/>
Expand All @@ -127,13 +181,16 @@ export const EntityForm = (props: Props) => {
{props.ruleParams.indexId &&
<>
<EuiFormRow
error={dateFieldError}
isInvalid={Boolean(dateFieldError)}
label={
i18n.translate('xpack.stackAlerts.geoContainment.timeFieldLabel', {
defaultMessage: 'Time',
})
}
>
<SingleFieldSelect
isInvalid={Boolean(dateFieldError)}
placeholder={i18n.translate('xpack.stackAlerts.geoContainment.selectTimeLabel', {
defaultMessage: 'Select time field',
})}
Expand All @@ -148,11 +205,14 @@ export const EntityForm = (props: Props) => {
</EuiFormRow>

<EuiFormRow
error={geoFieldError}
isInvalid={Boolean(geoFieldError)}
label={i18n.translate('xpack.stackAlerts.geoContainment.geofieldLabel', {
defaultMessage: 'Location',
})}
>
<SingleFieldSelect
isInvalid={Boolean(geoFieldError)}
placeholder={i18n.translate('xpack.stackAlerts.geoContainment.selectGeoLabel', {
defaultMessage: 'Select location field',
})}
Expand All @@ -167,11 +227,14 @@ export const EntityForm = (props: Props) => {
</EuiFormRow>

<EuiFormRow
error={entityFieldError}
isInvalid={Boolean(entityFieldError)}
label={i18n.translate('xpack.stackAlerts.geoContainment.entityfieldLabel', {
defaultMessage: 'Entity',
})}
>
<SingleFieldSelect
isInvalid={Boolean(entityFieldError)}
placeholder={i18n.translate(
'xpack.stackAlerts.geoContainment.topHitsSplitFieldSelectPlaceholder',
{
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,18 @@ import { EntityForm } from './entity_form';
export const GeoContainmentRuleTypeExpression: React.FunctionComponent<
RuleTypeParamsExpressionProps<GeoContainmentAlertParams>
> = (props) => {
console.log('props', props);

function getValidationError(key: string) {
return props.errors[key]?.length > 0 && key in props.ruleParams
? props.errors[key][0]
: null;
}

return (
<>
<EntityForm
data={props.data}
getValidationError={getValidationError}
ruleParams={props.ruleParams}
setDataViewId={(id: string) => props.setRuleParams('indexId', id)}
setDataViewTitle={(title: string) => props.setRuleParams('index', title)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ function fieldsToOptions(fields?: DataViewField[]): Array<EuiComboBoxOptionOptio
}

interface Props {
isInvalid: boolean;
placeholder: string;
value: string | null; // data view field name
onChange: (fieldName?: string) => void;
fields: DataViewField[];
}

export function SingleFieldSelect({ placeholder, value, onChange, fields }: Props) {
export function SingleFieldSelect({ isInvalid, placeholder, value, onChange, fields }: Props) {
function renderOption(
option: EuiComboBoxOptionOption<DataViewField>,
searchValue: string,
Expand Down Expand Up @@ -71,6 +72,7 @@ export function SingleFieldSelect({ placeholder, value, onChange, fields }: Prop

return (
<EuiComboBox
isInvalid={isInvalid}
singleSelection={true}
options={fieldsToOptions(fields)}
selectedOptions={selectedOptions}
Expand Down

0 comments on commit d14f6b1

Please sign in to comment.