Skip to content

Commit

Permalink
Euify and Reactify Query Bar Component (#23704)
Browse files Browse the repository at this point in the history
Implements query bar portion of https://elastic.github.io/eui/#/layout/header. Filter bar will come in another PR.

Fixes #14086

Re-implements our query bar component in React using some EUI components. Existing typeahead and suggestion styles were copied over 1:1 for now after talking with Dave about it. In this PR I focused on reaching feature parity with the existing query bar. Some additional work would be needed before we could move this into EUI as a generic component that could be consumed by other plugins.

Still needs some new tests and I suspect some old tests will need to be updated, but other than that this PR is functionally complete and ready for reviews.
  • Loading branch information
Bargs authored Oct 23, 2018
1 parent 836b1a1 commit b99c516
Show file tree
Hide file tree
Showing 59 changed files with 2,700 additions and 1,416 deletions.
5 changes: 2 additions & 3 deletions src/core_plugins/kibana/public/dashboard/dashboard_app.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@
<query-bar
query="model.query"
app-name="'dashboard'"
on-submit="updateQueryAndFetch($query)"
on-submit="updateQueryAndFetch"
index-patterns="indexPatterns"
>
</query-bar>
></query-bar>
</div>
</div>
</kbn-top-nav>
Expand Down
1 change: 0 additions & 1 deletion src/core_plugins/kibana/public/dashboard/dashboard_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ const app = uiModules.get('app/dashboard', [
'react',
'kibana/courier',
'kibana/config',
'kibana/typeahead',
]);

app.directive('dashboardViewportProvider', function (reactDirective) {
Expand Down
5 changes: 2 additions & 3 deletions src/core_plugins/kibana/public/discover/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,10 @@ <h1 tabindex="0" id="kui_local_breadcrumb" class="kuiLocalBreadcrumb">
<div data-transclude-slot="bottomRow" class="fullWidth">
<query-bar
query="state.query"
on-submit="updateQueryAndFetch"
app-name="'discover'"
on-submit="updateQueryAndFetch($query)"
index-patterns="[indexPattern]"
>
</query-bar>
></query-bar>
</div>
</div>
</kbn-top-nav>
Expand Down
2 changes: 2 additions & 0 deletions src/core_plugins/kibana/public/index.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@import 'ui/public/styles/styling_constants';

@import 'ui/public/query_bar/index';

// Context styles
@import './context/index';

Expand Down
5 changes: 2 additions & 3 deletions src/core_plugins/kibana/public/visualize/editor/editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@
<query-bar
query="state.query"
app-name="'visualize'"
on-submit="updateQueryAndFetch($query)"
on-submit="updateQueryAndFetch"
disable-auto-focus="true"
index-patterns="[indexPattern]"
>
</query-bar>
></query-bar>
</div>
</div>
</div>
Expand Down
11 changes: 8 additions & 3 deletions src/ui/public/autocomplete_providers/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export type AutocompleteProvider = (
get(configKey: string): any;
};
indexPatterns: StaticIndexPattern[];
boolFilter: any;
boolFilter?: any;
}
) => GetSuggestions;

Expand All @@ -40,10 +40,15 @@ export type GetSuggestions = (
}
) => Promise<AutocompleteSuggestion[]>;

export type AutocompleteSuggestionType = 'field' | 'value' | 'operator' | 'conjunction';
export type AutocompleteSuggestionType =
| 'field'
| 'value'
| 'operator'
| 'conjunction'
| 'recentSearch';

export interface AutocompleteSuggestion {
description: string;
description?: string;
end: number;
start: number;
text: string;
Expand Down
2 changes: 1 addition & 1 deletion src/ui/public/autoload/modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ import '../style_compile';
import '../timefilter';
import '../timepicker';
import '../tooltip';
import '../typeahead';
import '../url';
import '../validate_date_interval';
import '../watch_multi';
import '../courier/saved_object/ui/saved_object_save_as_checkbox';
import '../react_components';
import '../i18n';
import '../query_bar/directive';
10 changes: 3 additions & 7 deletions src/ui/public/directives/__tests__/parse_query.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,23 @@ import ngMock from 'ng_mock';

let $rootScope;
let $compile;
let Private;
let config;
let $elemScope;
let $elem;

let cycleIndex = 0;
const markup = '<input ng-model="mockModel" parse-query input-focus type="text">';
let fromUser;
import { toUser } from '../../parse_query/lib/to_user';
import '../../parse_query';
import { ParseQueryLibFromUserProvider } from '../../parse_query/lib/from_user';
import '../../parse_query/index';
import { fromUser } from '../../parse_query/lib/from_user';

const init = function () {
// Load the application
ngMock.module('kibana');

// Create the scope
ngMock.inject(function ($injector, _$rootScope_, _$compile_, _$timeout_, _Private_, _config_) {
ngMock.inject(function ($injector, _$rootScope_, _$compile_, _$timeout_, _config_) {
$compile = _$compile_;
Private = _Private_;
config = _config_;

// Give us a scope
Expand Down Expand Up @@ -77,7 +74,6 @@ describe('parse-query directive', function () {
describe('user input parser', function () {

beforeEach(function () {
fromUser = Private(ParseQueryLibFromUserProvider);
config.set('query:queryString:options', {});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,15 @@ export const documentationLinks = {
installation: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/filebeat-installation.html`,
configuration: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/filebeat-configuration.html`,
elasticsearchOutput: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/elasticsearch-output.html`,
elasticsearchOutputAnchorParameters:
`${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/elasticsearch-output.html#_parameters`,
elasticsearchOutputAnchorParameters: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/elasticsearch-output.html#_parameters`,
startup: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/filebeat-starting.html`,
exportedFields: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/exported-fields.html`
exportedFields: `${ELASTIC_WEBSITE_URL}guide/en/beats/filebeat/${DOC_LINK_VERSION}/exported-fields.html`,
},
metricbeat: {
base: `${ELASTIC_WEBSITE_URL}guide/en/beats/metricbeat/${DOC_LINK_VERSION}`
base: `${ELASTIC_WEBSITE_URL}guide/en/beats/metricbeat/${DOC_LINK_VERSION}`,
},
logstash: {
base: `${ELASTIC_WEBSITE_URL}guide/en/logstash/${DOC_LINK_VERSION}`
base: `${ELASTIC_WEBSITE_URL}guide/en/logstash/${DOC_LINK_VERSION}`,
},
aggs: {
date_histogram: `${ELASTIC_DOCS}search-aggregations-bucket-datehistogram-aggregation.html`,
Expand Down Expand Up @@ -78,19 +77,18 @@ export const documentationLinks = {
painless: `${ELASTIC_DOCS}modules-scripting-painless.html`,
painlessApi: `${ELASTIC_DOCS}modules-scripting-painless.html#painless-api`,
painlessSyntax: `${ELASTIC_DOCS}modules-scripting-painless-syntax.html`,
luceneExpressions: `${ELASTIC_DOCS}modules-scripting-expression.html`
luceneExpressions: `${ELASTIC_DOCS}modules-scripting-expression.html`,
},
indexPatterns: {
loadingData: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/tutorial-load-dataset.html`,
introduction: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/index-patterns.html`,
},
query: {
luceneQuerySyntax:
`${ELASTIC_DOCS}query-dsl-query-string-query.html#query-string-syntax`,
luceneQuerySyntax: `${ELASTIC_DOCS}query-dsl-query-string-query.html#query-string-syntax`,
queryDsl: `${ELASTIC_DOCS}query-dsl.html`,
kueryQuerySyntax: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/kuery-query.html`,
},
date: {
dateMath: `${ELASTIC_DOCS}common-options.html#date-math`
dateMath: `${ELASTIC_DOCS}common-options.html#date-math`,
},
};
29 changes: 29 additions & 0 deletions src/ui/public/index_patterns/static_utils/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { StaticIndexPattern } from 'ui/index_patterns';

interface SavedObject {
attributes: {
fields: string;
title: string;
};
}

export function getFromLegacyIndexPattern(indexPatterns: any[]): StaticIndexPattern[];
4 changes: 1 addition & 3 deletions src/ui/public/index_patterns/static_utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@

import { KBN_FIELD_TYPES } from '../../../../utils/kbn_field_types';

const filterableTypes = KBN_FIELD_TYPES.filter(type => type.filterable).map(
type => type.name
);
const filterableTypes = KBN_FIELD_TYPES.filter(type => type.filterable).map(type => type.name);

export function isFilterable(field) {
return filterableTypes.includes(field.type);
Expand Down
27 changes: 27 additions & 0 deletions src/ui/public/metadata.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

declare class Metadata {
public branch: string;
public version: string;
}

declare const metadata: Metadata;

export { metadata };
23 changes: 23 additions & 0 deletions src/ui/public/parse_query/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import './parse_query';

export * from './lib/from_user';
export * from './lib/to_user';
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,29 @@

import _ from 'lodash';

export function ParseQueryLibFromUserProvider() {
/**
* Take userInput from the user and make it into a query object
* @returns {object}
* @param userInput
*/

/**
* Take userInput from the user and make it into a query object
* @param {userInput} user's query input
* @returns {object}
*/
return function (userInput) {
const matchAll = '';
export function fromUser(userInput: object | string) {
const matchAll = '';

if (_.isObject(userInput)) {
// If we get an empty object, treat it as a *
if (!Object.keys(userInput).length) {
return matchAll;
}
return userInput;
if (_.isObject(userInput)) {
// If we get an empty object, treat it as a *
if (!Object.keys(userInput).length) {
return matchAll;
}
return userInput;
}

// Nope, not an object.
userInput = (userInput || '').trim();
if (userInput.length === 0) return matchAll;
userInput = userInput || '';
if (typeof userInput === 'string') {
userInput = userInput.trim();
if (userInput.length === 0) {
return matchAll;
}

if (userInput[0] === '{') {
try {
Expand All @@ -50,6 +52,5 @@ export function ParseQueryLibFromUserProvider() {
} else {
return userInput;
}
};
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,34 @@
* under the License.
*/

import _ from 'lodash';
import angular from 'angular';

/**
* Take text from the model and present it to the user as a string
* @param {text} model value
* @returns {string}
*/
export function toUser(text) {
if (text == null) return '';
if (_.isObject(text)) {
if (text.match_all) return '';
if (text.query_string) return toUser(text.query_string.query);
export function toUser(text: ToUserQuery | string): string {
if (text == null) {
return '';
}
if (typeof text === 'object') {
if (text.match_all) {
return '';
}
if (text.query_string) {
return toUser(text.query_string.query);
}
return angular.toJson(text);
}
return '' + text;
}

interface ToUserQuery {
match_all: object;
query_string: ToUserQueryString;
}

interface ToUserQueryString {
query: string;
}
5 changes: 2 additions & 3 deletions src/ui/public/parse_query/parse_query.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@
*/

import { toUser } from './lib/to_user';
import { ParseQueryLibFromUserProvider } from './lib/from_user';
import { fromUser } from './lib/from_user';

import { uiModules } from '../modules';
uiModules
.get('kibana')
.directive('parseQuery', function (Private) {
const fromUser = Private(ParseQueryLibFromUserProvider);
.directive('parseQuery', function () {

return {
restrict: 'A',
Expand Down
Loading

0 comments on commit b99c516

Please sign in to comment.