Skip to content

Commit

Permalink
refactor(table): improve DateFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
jlopezcur committed Oct 29, 2024
1 parent 5e72dd8 commit 5f7cef2
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 122 deletions.
3 changes: 3 additions & 0 deletions packages/table/src/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ export type TRowDef = {
evenOddType: 'even' | 'odd';
striped: boolean;
}) => CSSProp);
context?: {
[key: string]: unknown;
};
};

export type TCellDef = {
Expand Down
157 changes: 126 additions & 31 deletions packages/table/src/filters/DateFilter/DateFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,131 @@
import * as React from 'react';

import { DateTimeFloatingPicker } from '@devoinc/genesys-ui-datetime';
import { SelectControl } from '@devoinc/genesys-ui';

import {
AdvancedFilter,
BasicFilter,
DATE_OPTIONS,
FilterContainer,
} from '../common';
import type { TFilter } from '../../declarations';
HFlex,
IconButton,
Menu,
Popover,
} from '@devoinc/genesys-ui';
import { GIExitClose, GIFilter } from '@devoinc/genesys-icons';

import { DATE_OPTIONS, FilterContainer } from '../common';
import type { TFilter, TFilterContext } from '../../declarations';
import type { TDateFilterValue } from './declarations';

export const DateFilter: React.FC<TFilter> = ({ colDef, onChange }) => {
const context = colDef?.context as TFilterContext;
const filterValue = context?.filterValue as TDateFilterValue;
const value = filterValue?.value ?? null;
const secondValue = filterValue?.secondValue ?? null;
const operator = filterValue?.operator ?? 'equals';
return (
<FilterContainer>
<HFlex.Item flex="1 1 auto">
<DateTimeFloatingPicker
label=""
size="sm"
value={value}
onApply={(newValue) => {
onChange(
{
value: newValue,
secondValue,
operator,
},
'date',
);
}}
/>
</HFlex.Item>
{operator === 'between' && (
<HFlex.Item flex="1 1 auto">
<DateTimeFloatingPicker
label=""
size="sm"
aria-label="filter"
placeholder="To..."
value={secondValue}
onApply={(newSecondValue) => {
onChange(
{
value,
secondValue: newSecondValue,
operator,
},
'date',
);
}}
/>
</HFlex.Item>
)}

{(context?.showReset ?? true) &&
(value !== null || operator !== 'equals') && (
<HFlex.Item flex="0 0 auto">
<IconButton
icon={<GIExitClose />}
onClick={() => {
onChange(
{
value: null,
operator: 'equals',
} as TDateFilterValue,
'number',
);
}}
size="sm"
colorScheme="quiet"
/>
</HFlex.Item>
)}

export const DateFilter: React.FC<TFilter> = ({ colDef }) => (
<FilterContainer>
<BasicFilter>
<DateTimeFloatingPicker
size="sm"
onApply={() => undefined}
onCancel={() => undefined}
/>
</BasicFilter>
<AdvancedFilter id={`date-adv-filter-${colDef.id}`}>
<SelectControl
menuAppendToBody
// onChange={(opt: TSelectOption) => setValue(opt.value)}
options={DATE_OPTIONS}
// value={value}
/>
<DateTimeFloatingPicker
onApply={() => undefined}
onCancel={() => undefined}
/>
</AdvancedFilter>
</FilterContainer>
);
{(context?.showAdvancedFilter ?? true) && (
<HFlex.Item flex="0 0 auto">
<Popover id={`text-adv-filter-${colDef.id}`} placement="bottom-start">
{({ toggle, ref, isOpened }) => (
<IconButton
aria-controls={`text-adv-filter-${colDef.id}`}
aria-expanded={isOpened}
aria-haspopup="true"
icon={<GIFilter />}
onClick={toggle}
ref={ref}
state={isOpened ? 'expanded' : undefined}
size="sm"
colorScheme="quiet"
/>
)}
{({ setOpened }) => (
<Popover.Panel maxHeight="34rem" width="28rem">
<Menu>
{DATE_OPTIONS.map((option) => (
<Menu.Item
selectionScheme="single"
onChange={() => {
onChange(
{
value,
secondValue,
operator: option.value,
} as TDateFilterValue,
'date',
);
setOpened(false);
}}
key={option.value}
state={operator === option.value ? 'selected' : 'enabled'}
name="options"
value={option.value}
label={option.label}
/>
))}
</Menu>
</Popover.Panel>
)}
</Popover>
</HFlex.Item>
)}
</FilterContainer>
);
};
12 changes: 12 additions & 0 deletions packages/table/src/filters/DateFilter/declarations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export type TDateFilterValue = {
value: number | Date;
secondValue?: number | Date;
operator:
| 'equals'
| 'notEquals'
| 'greater'
| 'greaterOrEqual'
| 'less'
| 'lessOrEqual'
| 'between';
};
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import * as React from 'react';
import { Meta, StoryObj } from '@storybook/react';

import { InputControl, Menu } from '@devoinc/genesys-ui';
import { Menu } from '@devoinc/genesys-ui';

import {
type TContextOptions,
type TFilterContext,
filterDataByText,
filterDataByFilterStruct,
useFilterStruct,
updateColDefsWithFilterStruct,
Expand All @@ -27,16 +26,76 @@ export default meta;
type Story = StoryObj<typeof BasicTable>;

const data = [
{ text: 'Christine Jimenez', num: 60, bool: false, option: 'A' },
{ text: 'Ina Osborne', num: 20, bool: true, option: 'B' },
{ text: 'Jimmy Hogan', num: 20, bool: true, option: 'C' },
{ text: 'Myra Bell', num: 57, bool: true, option: 'C' },
{ text: 'Jane Padilla', num: 46, bool: false, option: 'B' },
{ text: 'Isabelle Gardner', num: 31, bool: true, option: 'A' },
{ text: 'Sean Parsons', num: 31, bool: true, option: 'A' },
{ text: 'Alvin Castro', num: 55, bool: false, option: 'B' },
{ text: 'Lawrence Holland', num: 56, bool: false, option: 'B' },
{ text: 'Brandon Robertson', num: 41, bool: true, option: 'C' },
{
text: 'Christine Jimenez',
num: 60,
date: new Date(2024, 9, 1, 0, 0, 0),
bool: false,
option: 'A',
},
{
text: 'Ina Osborne',
num: 20,
date: new Date(2024, 9, 2, 0, 0, 0),
bool: true,
option: 'B',
},
{
text: 'Jimmy Hogan',
num: 20,
date: new Date(2024, 9, 3, 0, 0, 0),
bool: true,
option: 'C',
},
{
text: 'Myra Bell',
num: 57,
date: new Date(2024, 9, 4, 0, 0, 0),
bool: true,
option: 'C',
},
{
text: 'Jane Padilla',
num: 46,
date: new Date(2024, 9, 5, 0, 0, 0),
bool: false,
option: 'B',
},
{
text: 'Isabelle Gardner',
num: 31,
date: new Date(2024, 9, 6, 0, 0, 0),
bool: true,
option: 'A',
},
{
text: 'Sean Parsons',
num: 31,
date: new Date(2024, 9, 7, 0, 0, 0),
bool: true,
option: 'A',
},
{
text: 'Alvin Castro',
num: 55,
date: new Date(2024, 9, 8, 0, 0, 0),
bool: false,
option: 'B',
},
{
text: 'Lawrence Holland',
num: 56,
date: new Date(2024, 9, 9, 0, 0, 0),
bool: false,
option: 'B',
},
{
text: 'Brandon Robertson',
num: 41,
date: new Date(2024, 9, 10, 0, 0, 0),
bool: true,
option: 'C',
},
];

const colDefs = [
Expand All @@ -55,6 +114,15 @@ const colDefs = [
showReset: true,
} as TFilterContext,
},
{
id: 'date',
headerName: 'Date',
preset: 'date',
context: {
showAdvancedFilter: true,
showReset: true,
} as TFilterContext,
},
{
id: 'bool',
headerName: 'Boolean',
Expand Down Expand Up @@ -193,73 +261,3 @@ const FilterAndBulkActionsTable = () => {
export const FiltersAndBulkActions: Story = {
render: () => <FilterAndBulkActionsTable />,
};

const GlobalTextFilterTable = () => {

const colDefs = [
{
id: 'text',
headerName: 'Text',
preset: 'text',
},
{
id: 'num',
headerName: 'Number',
preset: 'number',
context: {
showAdvancedFilter: true,
showReset: true,
} as TFilterContext,
},
{
id: 'bool',
headerName: 'Boolean',
preset: 'boolean',
},
{
id: 'option',
headerName: 'Options',
preset: 'options',
context: {
options: {
A: { label: 'Option A' },
B: { label: 'Option B' },
C: { label: 'Option C' },
},
} as TContextOptions,
},
];

const [ textFilter, setTextFilter ] = React.useState(undefined);
const { filterStruct, onFilter } = useFilterStruct();
const dataFiltered = [...data]
.filter(filterDataByText(textFilter, colDefs))
.filter(filterDataByFilterStruct(filterStruct));

return (
<>
<InputControl
aria-label="Contains text..."
placeholder="Contains text..."
type="search"
value={ textFilter }
onChange={(ev) => {
setTextFilter(ev.target.value);
}}
/>
<BasicTable
showFilters
onFilter={(curColDef, value, type) => {
onFilter(curColDef.id, value, type);
}}
colDefs={updateColDefsWithFilterStruct(colDefs, filterStruct)}
data={dataFiltered}
/>
</>
);
};

export const GlobalTextFilter: Story = {
render: () => <GlobalTextFilterTable />,
};

1 change: 1 addition & 0 deletions packages/table/src/filters/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './BooleanFilter';
export * from './DateFilter';
export * from './TextFilter';
export * from './NumberFilter';
export * from './OptionsFilter';
Loading

0 comments on commit 5f7cef2

Please sign in to comment.