Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove field type filtering from IndexPatternSelect #97035

Merged
merged 9 commits into from
Apr 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
export declare type IndexPatternSelectProps = Required<Omit<EuiComboBoxProps<any>, 'isLoading' | 'onSearchChange' | 'options' | 'selectedOptions' | 'onChange'>, 'placeholder'> & {
onChange: (indexPatternId?: string) => void;
indexPatternId: string;
fieldTypes?: string[];
onNoIndexPatterns?: () => void;
};
```
1 change: 0 additions & 1 deletion src/plugins/data/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1558,7 +1558,6 @@ export type IndexPatternsContract = PublicMethodsOf<IndexPatternsService>;
export type IndexPatternSelectProps = Required<Omit<EuiComboBoxProps<any>, 'isLoading' | 'onSearchChange' | 'options' | 'selectedOptions' | 'onChange'>, 'placeholder'> & {
onChange: (indexPatternId?: string) => void;
indexPatternId: string;
fieldTypes?: string[];
onNoIndexPatterns?: () => void;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export type IndexPatternSelectProps = Required<
> & {
onChange: (indexPatternId?: string) => void;
indexPatternId: string;
fieldTypes?: string[];
onNoIndexPatterns?: () => void;
};

Expand Down Expand Up @@ -102,49 +101,18 @@ export default class IndexPatternSelect extends Component<IndexPatternSelectInte
};

debouncedFetch = _.debounce(async (searchValue: string) => {
const isCurrentSearch = () => {
return this.isMounted && searchValue === this.state.searchValue;
};

const idsAndTitles = await this.props.indexPatternService.getIdsWithTitle();
if (!isCurrentSearch()) {
if (!this.isMounted || searchValue !== this.state.searchValue) {
return;
}

const options = [];
for (let i = 0; i < idsAndTitles.length; i++) {
if (!idsAndTitles[i].title.toLowerCase().includes(searchValue.toLowerCase())) {
// index pattern excluded due to title not matching search
continue;
}

if (this.props.fieldTypes) {
try {
const indexPattern = await this.props.indexPatternService.get(idsAndTitles[i].id);
if (!isCurrentSearch()) {
return;
}
const hasRequiredFieldTypes = indexPattern.fields.some((field) => {
return this.props.fieldTypes!.includes(field.type);
});
if (!hasRequiredFieldTypes) {
continue;
}
} catch (err) {
// could not load index pattern, exclude it from list.
continue;
}
}

options.push({
label: idsAndTitles[i].title,
value: idsAndTitles[i].id,
});

// Loading each index pattern object requires a network call so just find small number of matching index patterns
// Users can use 'searchValue' to further refine the list and locate their index pattern.
if (options.length > 15) {
break;
if (idsAndTitles[i].title.toLowerCase().includes(searchValue.toLowerCase())) {
options.push({
label: idsAndTitles[i].title,
value: idsAndTitles[i].id,
});
}
}

Expand Down Expand Up @@ -174,7 +142,6 @@ export default class IndexPatternSelect extends Component<IndexPatternSelectInte

render() {
const {
fieldTypes,
onChange,
indexPatternId,
placeholder,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ test('should render', async () => {

test('should render no index pattern warning when there are no matching index patterns', async () => {
const component = shallow(<GeoIndexPatternSelect onChange={() => {}} value={'indexPatternId'} />);
component.setState({ noGeoIndexPatternsExist: true });
component.setState({ noIndexPatternsExist: true });
expect(component).toMatchSnapshot();
});
41 changes: 26 additions & 15 deletions x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ interface Props {
}

interface State {
noGeoIndexPatternsExist: boolean;
doesIndexPatternHaveGeoField: boolean;
noIndexPatternsExist: boolean;
}

export class GeoIndexPatternSelect extends Component<Props, State> {
private _isMounted: boolean = false;

state = {
noGeoIndexPatternsExist: false,
doesIndexPatternHaveGeoField: false,
noIndexPatternsExist: false,
};

componentWillUnmount() {
Expand All @@ -57,24 +59,31 @@ export class GeoIndexPatternSelect extends Component<Props, State> {
// method may be called again before 'get' returns
// ignore response when fetched index pattern does not match active index pattern
if (this._isMounted && indexPattern.id === indexPatternId) {
this.setState({
doesIndexPatternHaveGeoField: indexPattern.fields.some((field) => {
return this.props?.isGeoPointsOnly
? (ES_GEO_FIELD_TYPE.GEO_POINT as string) === field.type
: ES_GEO_FIELD_TYPES.includes(field.type);
}),
});
this.props.onChange(indexPattern);
}
};

_onNoIndexPatterns = () => {
this.setState({ noGeoIndexPatternsExist: true });
this.setState({ noIndexPatternsExist: true });
};

_renderNoIndexPatternWarning() {
if (!this.state.noGeoIndexPatternsExist) {
if (!this.state.noIndexPatternsExist) {
return null;
}

return (
<>
<EuiCallOut
title={i18n.translate('xpack.maps.noIndexPattern.messageTitle', {
defaultMessage: `Couldn't find any index patterns with geospatial fields`,
defaultMessage: `Couldn't find any index patterns`,
})}
color="warning"
>
Expand All @@ -86,18 +95,14 @@ export class GeoIndexPatternSelect extends Component<Props, State> {
<EuiLink href={getHttp().basePath.prepend(`/app/management/kibana/indexPatterns`)}>
<FormattedMessage
id="xpack.maps.noIndexPattern.doThisLinkTextDescription"
defaultMessage="create an index pattern"
defaultMessage="Create an index pattern."
/>
</EuiLink>
<FormattedMessage
id="xpack.maps.noIndexPattern.doThisSuffixDescription"
defaultMessage=" with geospatial fields."
/>
</p>
<p>
<FormattedMessage
id="xpack.maps.noIndexPattern.hintDescription"
defaultMessage="Don't have any geospatial data sets? "
defaultMessage="Don't have any data? "
/>
<EuiLink href={getHttp().basePath.prepend('/app/home#/tutorial_directory/sampleData')}>
<FormattedMessage
Expand All @@ -114,6 +119,12 @@ export class GeoIndexPatternSelect extends Component<Props, State> {

render() {
const IndexPatternSelect = getIndexPatternSelectComponent();
const isIndexPatternInvalid = !!this.props.value && !this.state.doesIndexPatternHaveGeoField;
const error = isIndexPatternInvalid
? i18n.translate('xpack.maps.noGeoFieldInIndexPattern.message', {
defaultMessage: 'Index pattern does not contain any geospatial fields',
})
: '';
return (
<>
{this._renderNoIndexPatternWarning()}
Expand All @@ -122,17 +133,17 @@ export class GeoIndexPatternSelect extends Component<Props, State> {
label={i18n.translate('xpack.maps.indexPatternSelectLabel', {
defaultMessage: 'Index pattern',
})}
isInvalid={isIndexPatternInvalid}
error={error}
>
<IndexPatternSelect
isDisabled={this.state.noGeoIndexPatternsExist}
isInvalid={isIndexPatternInvalid}
isDisabled={this.state.noIndexPatternsExist}
indexPatternId={this.props.value ? this.props.value : ''}
onChange={this._onIndexPatternSelect}
placeholder={i18n.translate('xpack.maps.indexPatternSelectPlaceholder', {
defaultMessage: 'Select index pattern',
})}
fieldTypes={
this.props?.isGeoPointsOnly ? [ES_GEO_FIELD_TYPE.GEO_POINT] : ES_GEO_FIELD_TYPES
}
onNoIndexPatterns={this._onNoIndexPatterns}
isClearable={false}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export function SingleFieldSelect({
options={fieldsToOptions(fields, isFieldDisabled)}
selectedOptions={selectedOptions}
onChange={onSelection}
isDisabled={!fields}
isDisabled={!fields || fields.length === 0}
renderOption={renderOption}
{...rest}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@ interface Props {
}

interface State {
noGeoIndexPatternsExist: boolean;
doesIndexPatternHaveGeoField: boolean;
noIndexPatternsExist: boolean;
}

export class GeoIndexPatternSelect extends Component<Props, State> {
private _isMounted: boolean = false;

state = {
noGeoIndexPatternsExist: false,
doesIndexPatternHaveGeoField: false,
noIndexPatternsExist: false,
};

componentWillUnmount() {
Expand All @@ -56,24 +58,29 @@ export class GeoIndexPatternSelect extends Component<Props, State> {
// method may be called again before 'get' returns
// ignore response when fetched index pattern does not match active index pattern
if (this._isMounted && indexPattern.id === indexPatternId) {
this.setState({
doesIndexPatternHaveGeoField: indexPattern.fields.some((field) => {
return this.props.includedGeoTypes.includes(field.type);
}),
});
this.props.onChange(indexPattern);
}
};

_onNoIndexPatterns = () => {
this.setState({ noGeoIndexPatternsExist: true });
this.setState({ noIndexPatternsExist: true });
};

_renderNoIndexPatternWarning() {
if (!this.state.noGeoIndexPatternsExist) {
if (!this.state.noIndexPatternsExist) {
return null;
}

return (
<>
<EuiCallOut
title={i18n.translate('xpack.stackAlerts.geoContainment.noIndexPattern.messageTitle', {
defaultMessage: `Couldn't find any index patterns with geospatial fields`,
defaultMessage: `Couldn't find any index patterns`,
})}
color="warning"
>
Expand All @@ -87,18 +94,14 @@ export class GeoIndexPatternSelect extends Component<Props, State> {
>
<FormattedMessage
id="xpack.stackAlerts.geoContainment.noIndexPattern.doThisLinkTextDescription"
defaultMessage="create an index pattern"
defaultMessage="Create an index pattern."
/>
</EuiLink>
<FormattedMessage
id="xpack.stackAlerts.geoContainment.noIndexPattern.doThisSuffixDescription"
defaultMessage=" with geospatial fields."
/>
</p>
<p>
<FormattedMessage
id="xpack.stackAlerts.geoContainment.noIndexPattern.hintDescription"
defaultMessage="Don't have any geospatial data sets? "
defaultMessage="Don't have any data? "
/>
<EuiLink
href={this.props.http.basePath.prepend('/app/home#/tutorial_directory/sampleData')}
Expand All @@ -117,6 +120,12 @@ export class GeoIndexPatternSelect extends Component<Props, State> {

render() {
const IndexPatternSelectComponent = this.props.IndexPatternSelectComponent;
const isIndexPatternInvalid = !!this.props.value && !this.state.doesIndexPatternHaveGeoField;
const error = isIndexPatternInvalid
? i18n.translate('xpack.stackAlerts.geoContainment.noGeoFieldInIndexPattern.message', {
defaultMessage: 'Index pattern does not contain any geospatial fields',
})
: '';
return (
<>
{this._renderNoIndexPatternWarning()}
Expand All @@ -125,10 +134,13 @@ export class GeoIndexPatternSelect extends Component<Props, State> {
label={i18n.translate('xpack.stackAlerts.geoContainment.indexPatternSelectLabel', {
defaultMessage: 'Index pattern',
})}
isInvalid={isIndexPatternInvalid}
error={error}
>
{IndexPatternSelectComponent ? (
<IndexPatternSelectComponent
isDisabled={this.state.noGeoIndexPatternsExist}
isInvalid={isIndexPatternInvalid}
isDisabled={this.state.noIndexPatternsExist}
indexPatternId={this.props.value}
onChange={this._onIndexPatternSelect}
placeholder={i18n.translate(
Expand Down
Loading