Skip to content

Commit

Permalink
fix(table): modify reducer to cache initial search value
Browse files Browse the repository at this point in the history
  • Loading branch information
tay1orjones committed Jul 28, 2020
1 parent 7c6f8a7 commit 92369c1
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 156 deletions.
8 changes: 8 additions & 0 deletions src/components/Table/StatefulTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const StatefulTable = ({ data: initialData, expandedData, ...other }) => {
view,
view: {
table: { filteredData, selectedIds, sort },
toolbar: { initialDefaultSearch },
},
} = state;

Expand Down Expand Up @@ -203,6 +204,13 @@ const StatefulTable = ({ data: initialData, expandedData, ...other }) => {
options={options}
view={{
...view,
toolbar: {
...view.toolbar,
search: {
...view.toolbar.search,
defaultValue: initialDefaultSearch,
},
},
pagination: {
...view.pagination,
totalItems: filteredData.length,
Expand Down
8 changes: 1 addition & 7 deletions src/components/Table/Table.story.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -1031,13 +1031,7 @@ storiesOf('Watson IoT/Table', module)
style={{ maxWidth: '300px' }}
columns={tableColumns.slice(0, 2)}
data={tableData}
actions={{
toolbar: {
onApplySearch: newValue => {
setDefaultValue(newValue);
},
},
}}
actions={actions}
options={{ hasSearch: true, hasPagination: true, hasRowSelection: 'single' }}
view={{
toolbar: {
Expand Down
255 changes: 107 additions & 148 deletions src/components/Table/TableToolbar/TableToolbar.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { Column20, Filter20, Download20, Edit20 } from '@carbon/icons-react';
import { DataTable, Button, Tooltip } from 'carbon-components-react';
Expand Down Expand Up @@ -143,154 +143,113 @@ const TableToolbar = ({
totalItemsCount,
rowEditBarButtons,
},
}) => {
const [currentSearchValue, setCurrentSearchValue] = useState(search.defaultValue || '');
}) => (
<CarbonTableToolbar className={classnames(`${iotPrefix}--table-toolbar`, className)}>
<TableBatchActions
className={`${iotPrefix}--table-batch-actions`}
onCancel={onCancelBatchAction}
shouldShowBatchActions={hasRowSelection === 'multi' && totalSelected > 0}
totalSelected={totalSelected}
translateWithId={(...args) => tableTranslateWithId(i18n, ...args)}
>
{batchActions.map(({ id, labelText, ...others }) => (
<TableBatchAction key={id} onClick={() => onApplyBatchAction(id)} {...others}>
{labelText}
</TableBatchAction>
))}
</TableBatchActions>
{secondaryTitle ? (
// eslint-disable-next-line jsx-a11y/label-has-associated-control, jsx-a11y/label-has-for
<label className={`${iotPrefix}--table-toolbar-secondary-title`}>{secondaryTitle}</label>
) : null}
{// Deprecated in favor of secondaryTitle for a more general use-case
hasRowCountInHeader ? (
// eslint-disable-next-line jsx-a11y/label-has-associated-control, jsx-a11y/label-has-for
<label className={`${iotPrefix}--table-toolbar-secondary-title`}>
{i18n.rowCountInHeader(totalItemsCount)}
</label>
) : null}
{tooltip && (
<div className={`${iotPrefix}--table-tooltip-container`}>
<Tooltip
triggerId={`card-tooltip-trigger-${tableId}`}
tooltipId={`card-tooltip-${tableId}`}
triggerText=""
>
{tooltip}
</Tooltip>
</div>
)}
{activeBar === 'rowEdit' ? (
<div className={`${iotPrefix}--table-row-edit-actions`}>{rowEditBarButtons}</div>
) : (
<TableToolbarContent className={`${iotPrefix}--table-toolbar-content`}>
{hasSearch ? (
<TableToolbarSearch
{...search}
key={`table-toolbar-search${search.defaultValue}${search.value}`}
defaultValue={search.defaultValue || search.value}
className="table-toolbar-search"
translateWithId={(...args) => tableTranslateWithId(i18n, ...args)}
id={`${tableId}-toolbar-search`}
onChange={(event, defaultValue) => {
// https://github.com/carbon-design-system/carbon/issues/6157
onApplySearch(event?.target?.value || defaultValue);
}}
disabled={isDisabled}
/>
) : null}
{totalFilters > 0 ? (
<Button kind="secondary" onClick={onClearAllFilters} disabled={isDisabled}>
{i18n.clearAllFilters}
</Button>
) : null}
{onDownloadCSV ? (
<TableToolbarSVGButton
onClick={onDownloadCSV}
description={i18n.downloadIconDescription}
testId="download-button"
renderIcon={Download20}
disabled={isDisabled}
/>
) : null}
{hasColumnSelection ? (
<TableToolbarSVGButton
isActive={activeBar === 'column'}
onClick={onToggleColumnSelection}
description={i18n.columnSelectionButtonAria}
testId="column-selection-button"
renderIcon={Column20}
disabled={isDisabled}
/>
) : null}
{hasFilter ? (
<TableToolbarSVGButton
isActive={activeBar === 'filter'}
onClick={onToggleFilter}
description={i18n.filterButtonAria}
testId="filter-button"
renderIcon={Filter20}
disabled={isDisabled}
/>
) : null}
{hasRowEdit ? (
<TableToolbarSVGButton
isActive={activeBar === 'rowEdit'}
description={i18n.editButtonAria}
onClick={onShowRowEdit}
testId="row-edit-button"
renderIcon={Edit20}
disabled={isDisabled}
/>
) : null}

console.log(`defaultValue: ${search.defaultValue}`);
console.log(`currentSearchValue: ${currentSearchValue}`);
console.log(
((search.defaultValue || search.defaultValue === '') &&
search.defaultValue !== currentSearchValue) ||
((search.value || search.value === '') && search.value !== currentSearchValue)
? `${tableId}-toolbar-search${search.defaultValue || 'emptyDefault'}${search.value ||
'emptyDefault'}`
: `${tableId}-toolbar-search`
);
console.log(`--------------------------------------------------`);
return (
<CarbonTableToolbar className={classnames(`${iotPrefix}--table-toolbar`, className)}>
<TableBatchActions
className={`${iotPrefix}--table-batch-actions`}
onCancel={onCancelBatchAction}
shouldShowBatchActions={hasRowSelection === 'multi' && totalSelected > 0}
totalSelected={totalSelected}
translateWithId={(...args) => tableTranslateWithId(i18n, ...args)}
>
{batchActions.map(({ id, labelText, ...others }) => (
<TableBatchAction key={id} onClick={() => onApplyBatchAction(id)} {...others}>
{labelText}
</TableBatchAction>
))}
</TableBatchActions>
{secondaryTitle ? (
// eslint-disable-next-line jsx-a11y/label-has-associated-control, jsx-a11y/label-has-for
<label className={`${iotPrefix}--table-toolbar-secondary-title`}>{secondaryTitle}</label>
) : null}
{// Deprecated in favor of secondaryTitle for a more general use-case
hasRowCountInHeader ? (
// eslint-disable-next-line jsx-a11y/label-has-associated-control, jsx-a11y/label-has-for
<label className={`${iotPrefix}--table-toolbar-secondary-title`}>
{i18n.rowCountInHeader(totalItemsCount)}
</label>
) : null}
{tooltip && (
<div className={`${iotPrefix}--table-tooltip-container`}>
<Tooltip
triggerId={`card-tooltip-trigger-${tableId}`}
tooltipId={`card-tooltip-${tableId}`}
triggerText=""
>
{tooltip}
</Tooltip>
</div>
)}
{activeBar === 'rowEdit' ? (
<div className={`${iotPrefix}--table-row-edit-actions`}>{rowEditBarButtons}</div>
) : (
<TableToolbarContent className={`${iotPrefix}--table-toolbar-content`}>
{hasSearch ? (
<TableToolbarSearch
{...search}
// defaultValue is updated when onApplySearch is called. If the defaultValue does
// not match the currentSearchValue, we can infer that a new defaultValue has been
// set externally and we should render a new instance of the component.
// https://github.com/IBM/carbon-addons-iot-react/issues/1386
key={
((search.defaultValue || search.defaultValue === '') &&
search.defaultValue !== currentSearchValue) ||
((search.value || search.value === '') && search.value !== currentSearchValue)
? `${tableId}-toolbar-search${search.defaultValue ||
'emptyDefault'}${search.value ?? 'emptyDefault'}`
: `${tableId}-toolbar-search`
}
// key={`${tableId}-toolbar-search${
// (search.defaultValue || search.defaultValue === '') &&
// search.defaultValue !== currentSearchValue
// ? search.defaultValue
// : ''
// }${
// (search.value || search.value === '') && search.value !== currentSearchValue
// ? search.value
// : ''
// }`}
defaultValue={search.defaultValue ?? search.value}
className="table-toolbar-search"
translateWithId={(...args) => tableTranslateWithId(i18n, ...args)}
id={`${tableId}-toolbar-search`}
onChange={(
event,
defaultValue // https://github.com/carbon-design-system/carbon/issues/6157
) => {
const newSearchValue =
defaultValue || (event.currentTarget ? event.currentTarget.value : '');
setCurrentSearchValue(newSearchValue);
onApplySearch(newSearchValue);
}}
disabled={isDisabled}
/>
) : null}
{totalFilters > 0 ? (
<Button kind="secondary" onClick={onClearAllFilters} disabled={isDisabled}>
{i18n.clearAllFilters}
</Button>
) : null}
{onDownloadCSV ? (
<TableToolbarSVGButton
onClick={onDownloadCSV}
description={i18n.downloadIconDescription}
testId="download-button"
renderIcon={Download20}
disabled={isDisabled}
/>
) : null}
{hasColumnSelection ? (
<TableToolbarSVGButton
isActive={activeBar === 'column'}
onClick={onToggleColumnSelection}
description={i18n.columnSelectionButtonAria}
testId="column-selection-button"
renderIcon={Column20}
disabled={isDisabled}
/>
) : null}
{hasFilter ? (
<TableToolbarSVGButton
isActive={activeBar === 'filter'}
onClick={onToggleFilter}
description={i18n.filterButtonAria}
testId="filter-button"
renderIcon={Filter20}
disabled={isDisabled}
/>
) : null}
{hasRowEdit ? (
<TableToolbarSVGButton
isActive={activeBar === 'rowEdit'}
description={i18n.editButtonAria}
onClick={onShowRowEdit}
testId="row-edit-button"
renderIcon={Edit20}
disabled={isDisabled}
/>
) : null}

{// Default card header actions should be to the right of the table-specific actions
customToolbarContent || null}
</TableToolbarContent>
)}
</CarbonTableToolbar>
);
};
{// Default card header actions should be to the right of the table-specific actions
customToolbarContent || null}
</TableToolbarContent>
)}
</CarbonTableToolbar>
);

TableToolbar.propTypes = propTypes;
TableToolbar.defaultProps = defaultProps;
Expand Down
10 changes: 9 additions & 1 deletion src/components/Table/tableReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,12 @@ export const tableReducer = (state = {}, action) => {
const { pageSize, pageSizes } = get(view, 'pagination') || {};
const toolbar = get(view, 'toolbar') || {};
const paginationFromState = get(state, 'view.pagination');
const initialDefaultSearch =
get(view, 'toolbar.search.defaultValue') || get(view, 'toolbar.search.value');
// update the column ordering if I'm passed new columns
const ordering = get(view, 'table.ordering') || get(state, 'view.table.ordering');
// update the search if a new one is passed
const searchFromState = get(state, 'view.toolbar.search');
const pagination = get(state, 'view.pagination')
? {
totalItems: { $set: totalItems || updatedData.length },
Expand All @@ -296,13 +300,17 @@ export const tableReducer = (state = {}, action) => {
},
view: {
pagination,
toolbar: {
initialDefaultSearch: { $set: initialDefaultSearch },
search: { $set: searchFromState },
},
table: {
ordering: { $set: ordering },
filteredData: {
$set: filterSearchAndSort(
updatedData,
get(state, 'view.table.sort'),
get(state, 'view.toolbar.search'),
searchFromState,
get(state, 'view.filters'),
get(state, 'columns')
),
Expand Down

0 comments on commit 92369c1

Please sign in to comment.