Skip to content

Commit

Permalink
[EuiInMemoryTable] Allow search prop changes to update internal que…
Browse files Browse the repository at this point in the history
…ry state (#3371)

* fixed EuiInMemoryTable does not update its internal query state after changes to `search` prop

* added cl

* fixes

* fix

* Check query changes instead of search object changes

* Fixed query not updated if string is empty

* Updated search state value on query change

* external state docs

* CL

Co-authored-by: Greg Thompson <thompson.glowe@gmail.com>
  • Loading branch information
ashikmeerankutty and thompsongl authored Apr 29, 2020
1 parent 90263db commit a6eb423
Show file tree
Hide file tree
Showing 8 changed files with 348 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Added `iconProps` prop to `EuiCollapsibleNavGroup` to extend the props passed to the rendered `EuiIcon` ([#3365](https://github.com/elastic/eui/pull/3365))
- Added `closeButtonProps` to `EuiCollapsibleNav` ([#3398](https://github.com/elastic/eui/pull/3398))
- Added `buffer` prop to `EuiPopover` for altering minimum distance to container edges ([#3398](https://github.com/elastic/eui/pull/3398))
- Allowed `search` prop changes to update `EuiInMemoryTable` internal query state ([#3371](https://github.com/elastic/eui/pull/3371))

**Bug Fixes**

Expand Down
19 changes: 0 additions & 19 deletions src-docs/src/views/tables/in_memory/in_memory_search.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,25 +85,6 @@ export const Table = () => {
return <EuiHealth color={color}>{label}</EuiHealth>;
},
},
{
field: 'nationality',
name: 'Nationality',
render: countryCode => {
const country = store.getCountry(countryCode);
return `${country.flag} ${country.name}`;
},
},
{
field: 'online',
name: 'Online',
dataType: 'boolean',
render: online => {
const color = online ? 'success' : 'danger';
const label = online ? 'Online' : 'Offline';
return <EuiHealth color={color}>{label}</EuiHealth>;
},
sortable: true,
},
];

const search = {
Expand Down
276 changes: 276 additions & 0 deletions src-docs/src/views/tables/in_memory/in_memory_search_external.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
import React, { Fragment, useState } from 'react';
import { formatDate } from '../../../../../src/services/format';
import { createDataStore } from '../data_store';
import {
EuiInMemoryTable,
EuiLink,
EuiHealth,
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiCheckableCard,
} from '../../../../../src/components';

/*
Example user object:
{
id: '1',
firstName: 'john',
lastName: 'doe',
github: 'johndoe',
dateOfBirth: Date.now(),
nationality: 'NL',
online: true
}
Example country object:
{
code: 'NL',
name: 'Netherlands',
flag: '🇳🇱'
}
*/

const initialState = {
eu: false,
na: false,
oc: false,
as: false,
af: false,
sa: false,
};

const store = createDataStore();

export const Table = () => {
const [query, setQuery] = useState('');
const [state, setState] = useState(initialState);

const columns = [
{
field: 'firstName',
name: 'First Name',
sortable: true,
truncateText: true,
},
{
field: 'lastName',
name: 'Last Name',
truncateText: true,
},
{
field: 'github',
name: 'Github',
render: username => (
<EuiLink href={`https://github.com/${username}`} target="_blank">
{username}
</EuiLink>
),
},
{
field: 'dateOfBirth',
name: 'Date of Birth',
dataType: 'date',
render: date => formatDate(date, 'dobLong'),
sortable: true,
},
{
field: 'nationality',
name: 'Nationality',
render: countryCode => {
const country = store.getCountry(countryCode);
return `${country.flag} ${country.name}`;
},
},
{
field: 'online',
name: 'Online',
dataType: 'boolean',
render: online => {
const color = online ? 'success' : 'danger';
const label = online ? 'Online' : 'Offline';
return <EuiHealth color={color}>{label}</EuiHealth>;
},
},
];

const handleOnChange = search => {
setState(initialState);
setQuery(search.queryText);
return true;
};

const handleCheckbox = e => {
switch (e.target.id) {
case 'eu': {
const isChecked = !state.eu;
setQuery(
isChecked ? 'nationality:(NL or CZ or NO or IT or GB or GR)' : ''
);
setState({
...initialState,
eu: isChecked,
});
break;
}
case 'na': {
const isChecked = !state.na;
setQuery(isChecked ? 'nationality:(US or CA or MX or HT)' : '');
setState({
...initialState,
na: isChecked,
});
break;
}
case 'oc': {
const isChecked = !state.oc;
setQuery(isChecked ? 'nationality:(AU or FJ)' : '');
setState({
...initialState,
oc: isChecked,
});
break;
}
case 'as': {
const isChecked = !state.as;
setQuery(isChecked ? 'nationality:(IL or LB)' : '');
setState({
...initialState,
as: isChecked,
});
break;
}
case 'af': {
const isChecked = !state.af;
setQuery(isChecked ? 'nationality:(ZA or CG)' : '');
setState({
...initialState,
af: isChecked,
});
break;
}
case 'sa': {
const isChecked = !state.sa;
setQuery(isChecked ? 'nationality:(CL)' : '');
setState({
...initialState,
sa: isChecked,
});
break;
}
default:
}
};

const search = {
query,
onChange: handleOnChange,
box: {
schema: true,
},
filters: [
{
type: 'is',
field: 'online',
name: 'Online',
negatedName: 'Offline',
},
{
type: 'field_value_selection',
field: 'nationality',
name: 'Nationality',
multiSelect: 'or',
options: store.countries.map(country => ({
value: country.code,
name: country.name,
view: `${country.flag} ${country.name}`,
})),
},
],
};

return (
<Fragment>
<EuiFlexGroup>
<EuiFlexItem grow={1}>
<div>
<EuiCheckableCard
id="af"
label="Africa"
checkableType="radio"
value="Africa"
checked={state.af}
onChange={handleCheckbox}
/>
</div>
<EuiSpacer size="s" />
<div>
<EuiCheckableCard
id="as"
label="Asia"
checkableType="radio"
value="Asia"
checked={state.as}
onChange={handleCheckbox}
/>
</div>
<EuiSpacer size="s" />
<div>
<EuiCheckableCard
id="eu"
label="Europe"
checkableType="radio"
value="Europe"
checked={state.eu}
onChange={handleCheckbox}
/>
</div>
<EuiSpacer size="s" />
<div>
<EuiCheckableCard
id="na"
label="North America"
checkableType="radio"
value="North America"
checked={state.na}
onChange={handleCheckbox}
/>
</div>
<EuiSpacer size="s" />
<div>
<EuiCheckableCard
id="oc"
label="Oceania"
checkableType="radio"
value="Oceania"
checked={state.oc}
onChange={handleCheckbox}
/>
</div>
<EuiSpacer size="s" />
<div>
<EuiCheckableCard
id="sa"
label="South America"
checkableType="radio"
value="South America"
checked={state.sa}
onChange={handleCheckbox}
/>
</div>
</EuiFlexItem>
<EuiFlexItem grow={2}>
<EuiInMemoryTable
items={store.users}
columns={columns}
search={search}
pagination={true}
sorting={true}
/>
</EuiFlexItem>
</EuiFlexGroup>
</Fragment>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import { GuideSectionTypes } from '../../../components';
import { renderToHtml } from '../../../services';

import { Table } from './in_memory_search_external';
import { propsInfo } from './props_info';

const source = require('!!raw-loader!./in_memory_search_external');
const html = renderToHtml(Table);

export const searchExternalSection = {
title: 'In-memory table with search and external state',
source: [
{
type: GuideSectionTypes.JS,
code: source,
},
{
type: GuideSectionTypes.HTML,
code: html,
},
],
text: (
<div>
<p>
The example shows how to configure <strong>EuiInMemoryTable</strong>{' '}
when both external and internal search/filter states are in use.
</p>
</div>
),
props: propsInfo,
demo: <Table />,
};
1 change: 1 addition & 0 deletions src-docs/src/views/tables/in_memory/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export { section } from './in_memory_section';
export { selectionSection } from './in_memory_selection_section';
export { searchSection } from './in_memory_search_section';
export { searchExternalSection } from './in_memory_search_external_section';
export { searchCallbackSection } from './in_memory_search_callback_section';
export { customSortingSection } from './in_memory_custom_sorting_section';
2 changes: 2 additions & 0 deletions src-docs/src/views/tables/tables_in_memory_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
section as inMemorySection,
selectionSection as inMemorySelectionSection,
searchSection as inMemorySearchSection,
searchExternalSection as inMemorySearchExternalSection,
searchCallbackSection as inMemorySearchCallbackSection,
customSortingSection as inMemoryCustomSortingSection,
} from './in_memory';
Expand All @@ -13,6 +14,7 @@ export const TableInMemoryExample = {
inMemorySelectionSection,
inMemorySearchSection,
inMemorySearchCallbackSection,
inMemorySearchExternalSection,
inMemoryCustomSortingSection,
],
};
Loading

0 comments on commit a6eb423

Please sign in to comment.