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

Add new search bar with WQL #5363

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
e9f5923
feat: add a search bar component
Desvelao Feb 16, 2023
eff5d2b
feat(search-bar): change the AQL implemenation to use the regular exp…
Desvelao Mar 1, 2023
0923569
fix(search-bar): fixes a problem hidding the suggestion popover when …
Desvelao Mar 2, 2023
83c05cf
feat(search-bar): add the ability to update the input of example
Desvelao Mar 3, 2023
0b0b451
feat(search-bar): add initial suggestions to AQL
Desvelao Mar 6, 2023
ab8a555
feat(search-bar): add target and rel attributes to the documentation
Desvelao Mar 7, 2023
8d9f746
feat(search-bar): enhancements in AQL and search bar documentation
Desvelao Mar 7, 2023
9c01c8e
feat(search-bar): Add HAQL
Desvelao Mar 7, 2023
b6f0d6d
feat(search-bar): add test to HAQL and AQL query languages
Desvelao Mar 14, 2023
22676d4
feat(search-bar): Rename HAQL query language to WQL
Desvelao Mar 15, 2023
459a932
feat(search-bar): Add more use cases to the tests of WQL query language
Desvelao Mar 15, 2023
315932a
feat(search-bar): enhance the documenation of query languages
Desvelao Mar 15, 2023
4303a1a
feat(search-bar): Add a popover title to replicate similar UI to the …
Desvelao Mar 15, 2023
5e1485c
feat(search-bar): wrap the user input with group operators when there…
Desvelao Mar 15, 2023
9983153
feat(search-bar): add implicit query mode to WQL
Desvelao Mar 16, 2023
1eaf944
feat(search-bar): set the width of the syntax options popover
Desvelao Mar 23, 2023
d9abea0
feat(search-bar): unify suggestion descriptions in WQL
Desvelao Mar 23, 2023
c221f97
feat(search-bar): add enhancements to WQL
Desvelao Apr 10, 2023
8123d6e
Merge branch '4.5' of https://github.com/wazuh/wazuh-kibana-app into …
Desvelao Apr 10, 2023
cdbbb6d
feat(search-bar): rename previousField and previousOperatorCompare in…
Desvelao Apr 10, 2023
c300fa3
fix(tests): update snapshot
Desvelao Apr 11, 2023
ef85c54
fix(search-bar): fix documentation link for WQL
Desvelao Apr 11, 2023
17053c0
fix(search-bar): remove example usage of SearchBar component in Agents
Desvelao Apr 11, 2023
cfbf19b
fix(search-bar): fix an error using the value suggestions in WQL
Desvelao Apr 12, 2023
b4359ce
Merge branch '4.5' into feat/4312-poc-search-bar-component-multiple-q…
Desvelao Apr 20, 2023
8438cd8
Merge branch '4.5' into feat/4312-poc-search-bar-component-multiple-q…
Desvelao Apr 20, 2023
57d11d6
feat(search-bar): add search function suggestion when the input is empty
Desvelao Apr 25, 2023
ce4bc92
fix(search-bar): ensure the query language output changed to trigger …
Desvelao Apr 25, 2023
b547d98
feat(search-bar): allow the API query output can be redone when the s…
Desvelao Apr 27, 2023
a3c3681
feat(search-bar): enhance the validation of value token in WQL
Desvelao Apr 27, 2023
1b390be
feat(search-bar): enhance search bar and WQL
Desvelao May 12, 2023
06893ad
feat(search-bar): enhace search bar and WQL
Desvelao May 17, 2023
d774a48
fix: enhance search bar and WQL types
Desvelao May 19, 2023
4a7e282
Merge branch '4.5' of https://github.com/wazuh/wazuh-kibana-app into …
Desvelao May 22, 2023
ae5bade
Merge branch '4.6.0' of https://github.com/wazuh/wazuh-kibana-app int…
Desvelao Jun 26, 2023
2503edd
Merge branch '4.6.0' of https://github.com/wazuh/wazuh-kibana-app int…
Desvelao Jul 25, 2023
0cfe1d5
fix: remove exact validation for the token value due to performance p…
Desvelao Aug 1, 2023
3502d0b
fix: fix token value validation
Desvelao Aug 1, 2023
bc26f9a
fix: update the link to the documentation of WQL
Desvelao Aug 2, 2023
cd89aa5
fix(search-bar): use value of value token as the value used to get th…
Desvelao Aug 2, 2023
d961094
fix(search-bar): fix a problem extracting value for value tokens wrap…
Desvelao Aug 3, 2023
579d30f
fix(search-bar): add validation for value token in WQL
Desvelao Aug 4, 2023
f8b0044
fix(search-bar): value token in message related to this is invalid
Desvelao Aug 7, 2023
7bd9b09
Merge branch '4.6.0' into feat/4312-poc-search-bar-component-multiple…
asteriscos Aug 8, 2023
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 @@ -108,6 +108,7 @@ exports[`Table With Search Bar component renders correctly to match the snapshot
anchorPosition="downLeft"
attachToAnchor={true}
closePopover={[Function]}
disableFocusTrap={false}
display="block"
fullWidth={true}
id="popover"
Expand Down
2 changes: 2 additions & 0 deletions plugins/main/public/components/eui-suggest/suggest_input.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class EuiSuggestInput extends Component {
onPopoverFocus,
isPopoverOpen,
onClosePopover,
disableFocusTrap = false,
...rest
} = this.props;

Expand Down Expand Up @@ -108,6 +109,7 @@ export class EuiSuggestInput extends Component {
panelPaddingSize="none"
fullWidth
closePopover={onClosePopover}
disableFocusTrap={disableFocusTrap}
>
<div>{suggestions}</div>
</EuiInputPopover>
Expand Down
201 changes: 201 additions & 0 deletions plugins/main/public/components/search-bar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# Component

The `SearchBar` component is a base component of a search bar.

It is designed to be extensible through the self-contained query language implementations. This means
the behavior of the search bar depends on the business logic of each query language. For example, a
query language can display suggestions according to the user input or prepend some buttons to the search bar.

It is based on a custom `EuiSuggest` component defined in `public/components/eui-suggest/suggest.js`. So the
abilities are restricted by this one.

## Features

- Supports multiple query languages.
- Switch the selected query language.
- Self-contained query language implementation and ability to interact with the search bar component.
- React to external changes to set the new input. This enables to change the input from external components.

# Usage

Basic usage:

```tsx
<SearchBar
// Define the query languages. Required.
// The ID of them should be registered previously. See How to add a new query language documentation.
modes={[
{
id: 'wql',
// specific query language parameters
options: {
// implicit query. Optional
// Set a implicit query that can't be changed by the user.
// Use the UQL (Unified Query Language) syntax.
implicitQuery: {
query: 'id!=000',
conjunction: ';'
},
searchTermFields: ['id', 'ip']
},
suggestions: {
field(currentValue) {
return [
{ label: 'configSum', description: 'Config sum' },
{ label: 'dateAdd', description: 'Date add' },
{ label: 'id', description: 'ID' },
{ label: 'ip', description: 'IP address' },
{ label: 'group', description: 'Group' },
{ label: 'group_config_status', description: 'Synced configuration status' },
{ label: 'lastKeepAline', description: 'Date add' },
{ label: 'manager', description: 'Manager' },
{ label: 'mergedSum', description: 'Merged sum' },
{ label: 'name', description: 'Agent name' },
{ label: 'node_name', description: 'Node name' },
{ label: 'os.platform', description: 'Operating system platform' },
{ label: 'status', description: 'Status' },
{ label: 'version', description: 'Version' },
];
},
value: async (currentValue, { field }) => {
switch (field) {
case 'configSum':
return [
{ label: 'configSum1' },
{ label: 'configSum2' },
];
break;
case 'dateAdd':
return [
{ label: 'dateAdd1' },
{ label: 'dateAdd2' },
];
break;
case 'status':
return UI_ORDER_AGENT_STATUS.map(
(status) => ({
label: status,
}),
);
break;
default:
return [];
break;
}
},
}
},
]}
// Handler fired when the input handler changes. Optional.
onChange={onChange}
// Handler fired when the user press the Enter key or custom implementations. Required.
onSearch={onSearch}
// Used to define the internal input. Optional.
// This could be used to change the input text from the external components.
// Use the UQL (Unified Query Language) syntax.
input=''
// Define the default mode. Optional. If not defined, it will use the first one mode.
defaultMode=''
></SearchBar>
```

# Query languages

The built-in query languages are:

- AQL: API Query Language. Based on https://documentation.wazuh.com/current/user-manual/api/queries.html.

## How to add a new query language

### Definition

The language expects to take the interface:

```ts
type SearchBarQueryLanguage = {
description: string;
documentationLink?: string;
id: string;
label: string;
getConfiguration?: () => any;
run: (input: string | undefined, params: any) => Promise<{
searchBarProps: any,
output: {
language: string,
apiQuery: string,
query: string
}
}>;
transformInput: (unifiedQuery: string, options: {configuration: any, parameters: any}) => string;
};
```

where:

- `description`: is the description of the query language. This is displayed in a query language popover
on the right side of the search bar. Required.
- `documentationLink`: URL to the documentation link. Optional.
- `id`: identification of the query language.
- `label`: name
- `getConfiguration`: method that returns the configuration of the language. This allows custom behavior.
- `run`: method that returns:
- `searchBarProps`: properties to be passed to the search bar component. This allows the
customization the properties that will used by the base search bar component and the output used when searching
- `output`:
- `language`: query language ID
- `apiQuery`: API query.
- `query`: current query in the specified language
- `transformInput`: method that transforms the UQL (Unified Query Language) to the specific query
language. This is used when receives a external input in the Unified Query Language, the returned
value is converted to the specific query language to set the new input text of the search bar
component.

Create a new file located in `public/components/search-bar/query-language` and define the expected interface;

### Register

Go to `public/components/search-bar/query-language/index.ts` and add the new query language:

```ts
import { AQL } from './aql';

// Import the custom query language
import { CustomQL } from './custom';

// [...]

// Register the query languages
export const searchBarQueryLanguages: {
[key: string]: SearchBarQueryLanguage;
} = [
AQL,
CustomQL, // Add the new custom query language
].reduce((accum, item) => {
if (accum[item.id]) {
throw new Error(`Query language with id: ${item.id} already registered.`);
}
return {
...accum,
[item.id]: item,
};
}, {});
```

## Unified Query Language - UQL

This is an unified syntax used by the search bar component that provides a way to communicate
with the different query language implementations.

The input and output parameters of the search bar component must use this syntax.

This is used in:
- input:
- `input` component property
- output:
- `onChange` component handler
- `onSearch` component handler

Its syntax is equal to Wazuh API Query Language
https://wazuh.com/<major_version>.<minor_version>/user-manual/api/queries.html

> The AQL query language is a implementation of this syntax.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`SearchBar component Renders correctly the initial render 1`] = `
<div>
<div>
<div
class="euiSuggestInput"
>
<div
class="euiPopover euiPopover--anchorDownLeft euiPopover--displayBlock euiInputPopover euiInputPopover--fullWidth"
id="popover"
>
<div
class="euiPopover__anchor"
>
<div>
<div
class="euiFormControlLayout euiFormControlLayout--fullWidth euiFormControlLayout--group"
>
<div
class="euiFormControlLayout__childrenWrapper"
>
<input
class="euiFieldText euiFieldText--fullWidth euiFieldText--inGroup"
placeholder="Search"
type="text"
value=""
/>
</div>
<div
class="euiPopover euiPopover--anchorDownCenter euiFormControlLayout__append"
>
<div
class="euiPopover__anchor"
>
<button
class="euiButtonEmpty euiButtonEmpty--primary"
type="button"
>
<span
class="euiButtonContent euiButtonEmpty__content"
>
<span
class="euiButtonEmpty__text"
>
WQL
</span>
</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;
57 changes: 57 additions & 0 deletions plugins/main/public/components/search-bar/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';
import { render } from '@testing-library/react';
import { SearchBar } from './index';

describe('SearchBar component', () => {
const componentProps = {
defaultMode: 'wql',
input: '',
modes: [
{
id: 'aql',
implicitQuery: 'id!=000;',
suggestions: {
field(currentValue) {
return [];
},
value(currentValue, { field }){
return [];
},
},
},
{
id: 'wql',
implicitQuery: {
query: 'id!=000',
conjunction: ';'
},
suggestions: {
field(currentValue) {
return [];
},
value(currentValue, { field }){
return [];
},
},
},
],
/* eslint-disable @typescript-eslint/no-empty-function */
onChange: () => {},
onSearch: () => {}
/* eslint-enable @typescript-eslint/no-empty-function */
};

it('Renders correctly the initial render', async () => {
const wrapper = render(
<SearchBar
{...componentProps}
defaultMode='wql'
/>
);

/* This test causes a warning about act. This is intentional, because the test pretends to get
the first rendering of the component that doesn't have the component properties coming of the
selected query language */
expect(wrapper.container).toMatchSnapshot();
});
});
Loading