Refactor Filter type to accept Is, Is Not, Contains, Does not Contain (#128)

* Refactor Filter type to accept Is, Is Not, Contains, Does not Contain

* Remove any and add tests
This commit is contained in:
Charles Bochet
2023-05-18 15:32:57 +02:00
committed by GitHub
parent 4211d5872b
commit 5286dfd695
20 changed files with 241 additions and 336 deletions

View File

@ -3,7 +3,7 @@ import People from '../People';
import { ThemeProvider } from '@emotion/react';
import { lightTheme } from '../../../layout/styles/themes';
import { MockedProvider } from '@apollo/client/testing';
import { mockData } from '../__tests__/__data__/mock-data';
import { mockPeopleData } from '../__tests__/__data__/mock-data';
import { GET_PEOPLE } from '../../../services/api/people';
import { SEARCH_PEOPLE_QUERY } from '../../../services/api/search/search';
@ -25,7 +25,7 @@ const mocks = [
},
result: {
data: {
people: mockData,
people: mockPeopleData,
},
},
},
@ -39,7 +39,7 @@ const mocks = [
},
result: {
data: {
people: mockData,
people: mockPeopleData,
},
},
},

View File

@ -1,6 +1,6 @@
import { GraphqlQueryPerson } from '../../../../interfaces/person.interface';
import { GraphqlQueryPerson } from '../../../../interfaces/entities/person.interface';
export const mockData: Array<GraphqlQueryPerson> = [
export const mockPeopleData: Array<GraphqlQueryPerson> = [
{
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
__typename: 'Person',

View File

@ -1,9 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PeopleFilter should render the filter city 1`] = `
exports[`PeopleFilter should render the filter city which is text search 1`] = `
Object {
"city": Object {
"_eq": "Paris",
"_ilike": "%Paris%",
},
}
`;
exports[`PeopleFilter should render the filter company_name which relation search 1`] = `
Object {
"company": Object {
"name": Object {
"_eq": "test-name",
},
},
}
`;

View File

@ -1,20 +1,18 @@
import { cityFilter } from '../people-filters';
import { cityFilter, companyFilter } from '../people-filters';
describe('PeopleFilter', () => {
it(`should render the filter ${cityFilter.key}`, () => {
it(`should render the filter ${companyFilter.key} which relation search`, () => {
expect(
cityFilter.operands[0].whereTemplate({
companyFilter.operands[0].whereTemplate({
id: 'test-id',
city: 'Paris',
email: 'john@doe.com',
firstname: 'John',
lastname: 'Doe',
phone: '0123456789',
creationDate: new Date(),
pipes: [],
company: null,
__typename: 'people',
name: 'test-name',
domainName: 'test-domain-name',
__typename: 'companies',
}),
).toMatchSnapshot();
});
it(`should render the filter ${cityFilter.key} which is text search`, () => {
expect(cityFilter.operands[0].whereTemplate('Paris')).toMatchSnapshot();
});
});

View File

@ -1,12 +1,6 @@
import { FaEnvelope, FaMapPin, FaUser, FaBuilding } from 'react-icons/fa';
import {
Person,
mapToPerson,
} from '../../interfaces/entities/person.interface';
import {
SEARCH_COMPANY_QUERY,
SEARCH_PEOPLE_QUERY,
} from '../../services/api/search/search';
import { Person } from '../../interfaces/entities/person.interface';
import { SEARCH_COMPANY_QUERY } from '../../services/api/search/search';
import {
Company,
mapToCompany,
@ -17,45 +11,31 @@ export const fullnameFilter = {
key: 'fullname',
label: 'People',
icon: <FaUser />,
searchConfig: {
query: SEARCH_PEOPLE_QUERY,
template: (searchInput: string) => ({
_or: [
{ firstname: { _ilike: `%${searchInput}%` } },
{ lastname: { _ilike: `%${searchInput}%` } },
],
}),
resultMapper: (person) => ({
render: (person) => `${person.firstname} ${person.lastname}`,
value: mapToPerson(person),
}),
},
selectedValueRender: (person) => `${person.firstname} ${person.lastname}`,
operands: [
{
label: 'Equal',
id: 'equal',
whereTemplate: (person) => ({
_and: [
{ firstname: { _eq: `${person.firstname}` } },
{ lastname: { _eq: `${person.lastname}` } },
label: 'Contains',
id: 'like',
whereTemplate: (searchString) => ({
_or: [
{ firstname: { _ilike: `%${searchString}%` } },
{ lastname: { _ilike: `%${searchString}%` } },
],
}),
},
{
label: 'Not equal',
id: 'not-equal',
whereTemplate: (person) => ({
label: 'Does not contain',
id: 'not_like',
whereTemplate: (searchString) => ({
_not: {
_and: [
{ firstname: { _eq: `${person.firstname}` } },
{ lastname: { _eq: `${person.lastname}` } },
{ firstname: { _ilike: `%${searchString}%` } },
{ lastname: { _ilike: `%${searchString}%` } },
],
},
}),
},
],
} satisfies FilterConfigType<Person, Person>;
} satisfies FilterConfigType<Person, string>;
export const companyFilter = {
key: 'company_name',
@ -63,8 +43,8 @@ export const companyFilter = {
icon: <FaBuilding />,
searchConfig: {
query: SEARCH_COMPANY_QUERY,
template: (searchInput: string) => ({
name: { _ilike: `%${searchInput}%` },
template: (searchString: string) => ({
name: { _ilike: `%${searchString}%` },
}),
resultMapper: (data) => ({
value: mapToCompany(data),
@ -74,15 +54,15 @@ export const companyFilter = {
selectedValueRender: (company) => company.name || '',
operands: [
{
label: 'Equal',
id: 'equal',
label: 'Is',
id: 'is',
whereTemplate: (company) => ({
company: { name: { _eq: company.name } },
}),
},
{
label: 'Not equal',
id: 'not-equal',
label: 'Is not',
id: 'is_not',
whereTemplate: (company) => ({
_not: { company: { name: { _eq: company.name } } },
}),
@ -94,71 +74,49 @@ export const emailFilter = {
key: 'email',
label: 'Email',
icon: <FaEnvelope />,
searchConfig: {
query: SEARCH_PEOPLE_QUERY,
template: (searchInput: string) => ({
email: { _ilike: `%${searchInput}%` },
}),
resultMapper: (person) => ({
render: (person) => person.email,
value: mapToPerson(person),
}),
},
operands: [
{
label: 'Equal',
id: 'equal',
whereTemplate: (person) => ({
email: { _eq: person.email },
label: 'Contains',
id: 'like',
whereTemplate: (searchString) => ({
email: { _ilike: `%${searchString}%` },
}),
},
{
label: 'Not equal',
id: 'not-equal',
whereTemplate: (person) => ({
_not: { email: { _eq: person.email } },
label: 'Does not contain',
id: 'not_like',
whereTemplate: (searchString) => ({
_not: { email: { _ilike: `%${searchString}%` } },
}),
},
],
selectedValueRender: (person) => person.email || '',
} satisfies FilterConfigType<Person, Person>;
} satisfies FilterConfigType<Person, string>;
export const cityFilter = {
key: 'city',
label: 'City',
icon: <FaMapPin />,
searchConfig: {
query: SEARCH_PEOPLE_QUERY,
template: (searchInput: string) => ({
city: { _ilike: `%${searchInput}%` },
}),
resultMapper: (person) => ({
render: (person) => person.city,
value: mapToPerson(person),
}),
},
operands: [
{
label: 'Equal',
id: 'equal',
whereTemplate: (person) => ({
city: { _eq: person.city },
label: 'Contains',
id: 'like',
whereTemplate: (searchString) => ({
city: { _ilike: `%${searchString}%` },
}),
},
{
label: 'Not equal',
id: 'not-equal',
whereTemplate: (person) => ({
_not: { city: { _eq: person.city } },
label: 'Does not contain',
id: 'not_like',
whereTemplate: (searchString) => ({
_not: { city: { _ilike: `%${searchString}%` } },
}),
},
],
selectedValueRender: (person) => person.email || '',
} satisfies FilterConfigType<Person, Person>;
} satisfies FilterConfigType<Person, string>;
export const availableFilters = [
fullnameFilter,
companyFilter,
emailFilter,
cityFilter,
] satisfies FilterConfigType<Person, any>[];
] satisfies FilterConfigType<Person>[];