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

[EuiInMemoryTable] Allow search prop changes to update internal query state #3371

Merged
merged 11 commits into from
Apr 29, 2020
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