Skip to content

Commit

Permalink
Add ability to clear all filter fields
Browse files Browse the repository at this point in the history
  • Loading branch information
gnoha committed Jan 9, 2025
1 parent 7e96ed2 commit 39162c7
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 33 deletions.
67 changes: 46 additions & 21 deletions src/components/filterform/FiltersForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { PlusCircle, Trash } from '@phosphor-icons/react'
import s from './FiltersForm.module.css'
import cx from 'classnames'
import { FilterForm, FilterConfig } from '.'
import { validateFilterField } from './validateFilterField'
import {
isEmptyFilter,
isValidFilter,
validateFilterField,
} from './filterHelpers'

type Props = {
filterConfigs: FilterConfig[]
Expand All @@ -21,6 +25,13 @@ export const FiltersForm = ({
onSubmit,
initialValues,
}: Props) => {
const handleSubmit = (values: FilterForm) => {
const nonEmptyFilters = values.filters.filter(
(filter) => !isEmptyFilter(filter)
)
onSubmit({ filters: nonEmptyFilters })
}

return (
<Formik<FilterForm>
initialValues={
Expand All @@ -35,12 +46,26 @@ export const FiltersForm = ({
],
}
}
onReset={(_, formikHelpers) => {
formikHelpers.setFieldValue('filters', [
{
field: filterConfigs[0].field,
type: filterConfigs[0].type,
operator: undefined,
values: undefined,
},
])
}}
validate={(values) => {
if (values.filters.every((filter) => isEmptyFilter(filter))) {
return
}

return values.filters
.map((filter) => validateFilterField(filter))
.flat()
}}
onSubmit={onSubmit}
onSubmit={handleSubmit}
>
{({ isValid }) => (
<Form className={s.j2FilterForm}>
Expand Down Expand Up @@ -69,7 +94,7 @@ type FilterFormFieldsProps = {
}

const FilterFormFields = ({ filterConfigs }: FilterFormFieldsProps) => {
const { values, isValid } = useFormikContext<FilterForm>()
const { values, resetForm } = useFormikContext<FilterForm>()

return (
<div>
Expand All @@ -87,25 +112,18 @@ const FilterFormFields = ({ filterConfigs }: FilterFormFieldsProps) => {
index={index}
className="flex-1"
/>
<Button
icon={<Trash />}
onClick={() => {
if (values.filters.length === 1) {
arrayHelpers.replace(index, {
field: filterConfigs[0].field,
type: filterConfigs[0].type,
operator: undefined,
values: undefined,
})
} else {
arrayHelpers.remove(index)
}
}}
type="text"
/>
{index === 0 && values.filters.length === 1 ? (
<div className="w-8" />
) : (
<Button
icon={<Trash />}
onClick={() => arrayHelpers.remove(index)}
type="text"
/>
)}
</div>
))}
<div>
<div className="flex items-center">
<Button
icon={<PlusCircle />}
onClick={() =>
Expand All @@ -116,10 +134,17 @@ const FilterFormFields = ({ filterConfigs }: FilterFormFieldsProps) => {
values: undefined,
})
}
disabled={!isValid}
disabled={
!values.filters.every((filter) => isValidFilter(filter))
}
>
Add Rule
</Button>
{!values.filters.every((filter) => isEmptyFilter(filter)) && (
<Button type="text" onClick={() => resetForm()}>
Clear All Rules
</Button>
)}
</div>
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Filter } from './types'
import { validateFilterField } from './validateFilterField'
import { Filter } from '../types'
import { isEmptyFilter, validateFilterField } from '../filterHelpers'

describe('validateFilterField', () => {
it('should return operator required error when operator is undefined', () => {
Expand Down Expand Up @@ -79,3 +79,36 @@ describe('validateFilterField', () => {
expect(errors).toEqual([])
})
})

describe('isEmptyFilter', () => {
it('should return true when all fields are empty', () => {
const filter: Filter = {
field: 'test',
type: 'text',
operator: undefined,
values: undefined,
}

expect(isEmptyFilter(filter)).toBe(true)
})

it('should return false if operator is blank', () => {
const filter: Filter = {
field: 'test',
type: 'text',
operator: 'blank',
values: [],
}
expect(isEmptyFilter(filter)).toBe(false)
})

it('should return false if values are not empty', () => {
const filter: Filter = {
field: 'test',
type: 'text',
operator: 'blank',
values: ['test'],
}
expect(isEmptyFilter(filter)).toBe(false)
})
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
import { Filter } from './types'

export const isEmptyFilter = (filter: Filter) => {
if (filter.operator === 'blank' || filter.operator === 'notBlank') {
return false
}

if (
filter.values &&
filter.values.length > 0 &&
filter.values.every(
(value) => value !== '' && value !== undefined && value !== null
)
) {
return false
}

return true
}

export const isValidFilter = (filter: Filter) => {
return validateFilterField(filter).length === 0
}

export const validateFilterField = (
filter: Filter
): { field: string; message: string }[] => {
Expand All @@ -10,16 +32,7 @@ export const validateFilterField = (
return errors
}

if (
!['blank', 'notBlank'].includes(filter.operator) &&
!(
filter.values &&
filter.values.length > 0 &&
filter.values.every(
(value) => value !== '' && value !== undefined && value !== null
)
)
) {
if (isEmptyFilter(filter)) {
errors.push({ field: filter.field, message: 'Value is required' })
}

Expand Down

0 comments on commit 39162c7

Please sign in to comment.