Refactor Filters and Search (#119)
This commit is contained in:
@ -25,7 +25,10 @@ import {
|
||||
Companies_Bool_Exp,
|
||||
Companies_Order_By,
|
||||
} from '../../generated/graphql';
|
||||
import { SelectedFilterType } from '../../components/table/table-header/interface';
|
||||
import {
|
||||
FilterConfigType,
|
||||
SelectedFilterType,
|
||||
} from '../../components/table/table-header/interface';
|
||||
import { useSearch } from '../../services/search/search';
|
||||
import ActionBar from '../../components/table/action-bar/ActionBar';
|
||||
|
||||
@ -47,7 +50,7 @@ function Companies() {
|
||||
}, []);
|
||||
|
||||
const updateFilters = useCallback(
|
||||
(filters: Array<SelectedFilterType<Companies_Bool_Exp>>) => {
|
||||
(filters: Array<SelectedFilterType<Company>>) => {
|
||||
setWhere(reduceFiltersToWhere(filters));
|
||||
},
|
||||
[],
|
||||
@ -108,7 +111,7 @@ function Companies() {
|
||||
viewName="All Companies"
|
||||
viewIcon={<FaList />}
|
||||
availableSorts={availableSorts}
|
||||
availableFilters={availableFilters}
|
||||
availableFilters={availableFilters as Array<FilterConfigType>}
|
||||
filterSearchResults={filterSearchResults}
|
||||
onSortsUpdate={updateSorts}
|
||||
onFiltersUpdate={updateFilters}
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CompaniesFilter should render the filter company_name 1`] = `
|
||||
Object {
|
||||
"name": Object {
|
||||
"_eq": "Airbnb",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`CompaniesFilter should render the filter company_name 2`] = `
|
||||
Object {
|
||||
"_not": Object {
|
||||
"name": Object {
|
||||
"_eq": "Airbnb",
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`CompaniesFilter should render the filter domainName 1`] = `
|
||||
Object {
|
||||
"domain_name": Object {
|
||||
"_eq": "airbnb.com",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`CompaniesFilter should render the filter domainName 2`] = `
|
||||
Object {
|
||||
"_not": Object {
|
||||
"domain_name": Object {
|
||||
"_eq": "airbnb.com",
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`CompaniesFilter should render the serch company_name with the searchValue 1`] = `
|
||||
Object {
|
||||
"name": Object {
|
||||
"_ilike": "%Search value%",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`CompaniesFilter should render the serch domainName with the searchValue 1`] = `
|
||||
Object {
|
||||
"domain_name": Object {
|
||||
"_ilike": "%Search value%",
|
||||
},
|
||||
}
|
||||
`;
|
||||
@ -1,62 +0,0 @@
|
||||
import { FilterType } from '../../../components/table/table-header/interface';
|
||||
import { Companies_Bool_Exp } from '../../../generated/graphql';
|
||||
import { GraphqlQueryCompany } from '../../../interfaces/company.interface';
|
||||
import { GraphqlQueryPerson } from '../../../interfaces/person.interface';
|
||||
import {
|
||||
SEARCH_COMPANY_QUERY,
|
||||
SEARCH_PEOPLE_QUERY,
|
||||
} from '../../../services/search/search';
|
||||
import { mockData } from './__data__/mock-data';
|
||||
import { availableFilters } from '../companies-table';
|
||||
|
||||
function assertFilterUseCompanySearch<FilterValue>(
|
||||
filter: FilterType<Companies_Bool_Exp>,
|
||||
): filter is FilterType<Companies_Bool_Exp> & {
|
||||
searchResultMapper: (data: GraphqlQueryCompany) => {
|
||||
displayValue: string;
|
||||
value: FilterValue;
|
||||
};
|
||||
} {
|
||||
return filter.searchQuery === SEARCH_COMPANY_QUERY;
|
||||
}
|
||||
|
||||
function assertFilterUsePeopleSearch<FilterValue>(
|
||||
filter: FilterType<Companies_Bool_Exp>,
|
||||
): filter is FilterType<Companies_Bool_Exp> & {
|
||||
searchResultMapper: (data: GraphqlQueryPerson) => {
|
||||
displayValue: string;
|
||||
value: FilterValue;
|
||||
};
|
||||
} {
|
||||
return filter.searchQuery === SEARCH_PEOPLE_QUERY;
|
||||
}
|
||||
|
||||
const AirbnbCompany = mockData.find(
|
||||
(user) => user.name === 'Airbnb',
|
||||
) as GraphqlQueryCompany;
|
||||
|
||||
describe('CompaniesFilter', () => {
|
||||
for (const filter of availableFilters) {
|
||||
it(`should render the filter ${filter.key}`, () => {
|
||||
if (assertFilterUseCompanySearch(filter)) {
|
||||
const filterSelectedValue = filter.searchResultMapper(mockData[0]);
|
||||
for (const operand of filter.operands) {
|
||||
expect(
|
||||
filter.whereTemplate(operand, filterSelectedValue.value),
|
||||
).toMatchSnapshot();
|
||||
}
|
||||
}
|
||||
if (assertFilterUsePeopleSearch(filter)) {
|
||||
const filterSelectedValue = filter.searchResultMapper(AirbnbCompany);
|
||||
for (const operand of filter.operands) {
|
||||
expect(
|
||||
filter.whereTemplate(operand, filterSelectedValue.value),
|
||||
).toMatchSnapshot();
|
||||
}
|
||||
}
|
||||
});
|
||||
it(`should render the serch ${filter.key} with the searchValue`, () => {
|
||||
expect(filter.searchTemplate('Search value')).toMatchSnapshot();
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -1,8 +1,5 @@
|
||||
import { CellContext, createColumnHelper } from '@tanstack/react-table';
|
||||
import {
|
||||
Company,
|
||||
GraphqlQueryCompany,
|
||||
} from '../../interfaces/company.interface';
|
||||
import { Company, mapCompany } from '../../interfaces/company.interface';
|
||||
import { updateCompany } from '../../services/companies';
|
||||
import ColumnHead from '../../components/table/ColumnHead';
|
||||
import CompanyChip from '../../components/chips/CompanyChip';
|
||||
@ -15,28 +12,24 @@ import {
|
||||
FaRegUser,
|
||||
FaUsers,
|
||||
FaBuilding,
|
||||
FaUser,
|
||||
} from 'react-icons/fa';
|
||||
import PersonChip, {
|
||||
PersonChipPropsType,
|
||||
} from '../../components/chips/PersonChip';
|
||||
import EditableChip from '../../components/table/editable-cell/EditableChip';
|
||||
import {
|
||||
FilterType,
|
||||
FilterConfigType,
|
||||
SearchConfigType,
|
||||
SortType,
|
||||
} from '../../components/table/table-header/interface';
|
||||
import {
|
||||
Companies_Bool_Exp,
|
||||
Companies_Order_By,
|
||||
Users_Bool_Exp,
|
||||
} from '../../generated/graphql';
|
||||
import { Companies_Order_By } from '../../generated/graphql';
|
||||
import {
|
||||
SEARCH_COMPANY_QUERY,
|
||||
SEARCH_USER_QUERY,
|
||||
} from '../../services/search/search';
|
||||
import EditableDate from '../../components/table/editable-cell/EditableDate';
|
||||
import EditableRelation from '../../components/table/editable-cell/EditableRelation';
|
||||
import { GraphqlQueryUser, PartialUser } from '../../interfaces/user.interface';
|
||||
import { User, mapUser } from '../../interfaces/user.interface';
|
||||
import { useMemo } from 'react';
|
||||
import { SelectAllCheckbox } from '../../components/table/SelectAllCheckbox';
|
||||
import Checkbox from '../../components/form/Checkbox';
|
||||
@ -79,63 +72,67 @@ export const availableFilters = [
|
||||
key: 'company_name',
|
||||
label: 'Company',
|
||||
icon: <FaBuilding />,
|
||||
whereTemplate: (operand, { companyName }) => {
|
||||
if (operand.keyWord === 'equal') {
|
||||
return {
|
||||
name: { _eq: companyName },
|
||||
};
|
||||
}
|
||||
|
||||
if (operand.keyWord === 'not_equal') {
|
||||
return {
|
||||
_not: { name: { _eq: companyName } },
|
||||
};
|
||||
}
|
||||
searchConfig: {
|
||||
query: SEARCH_COMPANY_QUERY,
|
||||
template: (searchInput) => ({
|
||||
name: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
resultMapper: (company) => ({
|
||||
render: (company) => company.name,
|
||||
value: mapCompany(company),
|
||||
}),
|
||||
},
|
||||
searchQuery: SEARCH_COMPANY_QUERY,
|
||||
searchTemplate: (searchInput: string) => ({
|
||||
name: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
searchResultMapper: (company: GraphqlQueryCompany) => ({
|
||||
displayValue: company.name,
|
||||
value: { companyName: company.name },
|
||||
}),
|
||||
selectedValueRender: (company) => company.name,
|
||||
operands: [
|
||||
{ label: 'Equal', id: 'equal', keyWord: 'equal' },
|
||||
{ label: 'Not equal', id: 'not-equal', keyWord: 'not_equal' },
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
whereTemplate: (company) => ({
|
||||
name: { _eq: company.name },
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
whereTemplate: (company) => ({
|
||||
_not: { name: { _eq: company.name } },
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
} as FilterConfigType<Company, Company>,
|
||||
{
|
||||
key: 'domainName',
|
||||
key: 'company_domain_name',
|
||||
label: 'Url',
|
||||
icon: <FaLink />,
|
||||
whereTemplate: (operand, { domainName }) => {
|
||||
if (operand.keyWord === 'equal') {
|
||||
return {
|
||||
domain_name: { _eq: domainName },
|
||||
};
|
||||
}
|
||||
|
||||
if (operand.keyWord === 'not_equal') {
|
||||
return {
|
||||
_not: { domain_name: { _eq: domainName } },
|
||||
};
|
||||
}
|
||||
searchConfig: {
|
||||
query: SEARCH_COMPANY_QUERY,
|
||||
template: (searchInput) => ({
|
||||
name: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
resultMapper: (company) => ({
|
||||
render: (company) => company.domain_name,
|
||||
value: mapCompany(company),
|
||||
}),
|
||||
},
|
||||
searchQuery: SEARCH_COMPANY_QUERY,
|
||||
searchTemplate: (searchInput: string) => ({
|
||||
domain_name: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
searchResultMapper: (company: GraphqlQueryCompany) => ({
|
||||
displayValue: company.domain_name,
|
||||
value: { domainName: company.domain_name },
|
||||
}),
|
||||
selectedValueRender: (company) => company.domain_name,
|
||||
operands: [
|
||||
{ label: 'Equal', id: 'equal', keyWord: 'equal' },
|
||||
{ label: 'Not equal', id: 'not-equal', keyWord: 'not_equal' },
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
whereTemplate: (company) => ({
|
||||
domain_name: { _eq: company.domain_name },
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
whereTemplate: (company) => ({
|
||||
_not: { domain_name: { _eq: company.domain_name } },
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
] satisfies Array<FilterType<Companies_Bool_Exp>>;
|
||||
} as FilterConfigType<Company, Company>,
|
||||
];
|
||||
|
||||
const columnHelper = createColumnHelper<Company>();
|
||||
|
||||
@ -239,18 +236,18 @@ export const useCompaniesColumns = () => {
|
||||
<ColumnHead viewName="Account Owner" viewIcon={<FaRegUser />} />
|
||||
),
|
||||
cell: (props) => (
|
||||
<EditableRelation<PartialUser, PersonChipPropsType>
|
||||
<EditableRelation<User, PersonChipPropsType>
|
||||
relation={props.row.original.accountOwner}
|
||||
searchPlaceholder="Account Owner"
|
||||
ChipComponent={PersonChip}
|
||||
chipComponentPropsMapper={(
|
||||
accountOwner: PartialUser,
|
||||
accountOwner: User,
|
||||
): PersonChipPropsType => {
|
||||
return {
|
||||
name: accountOwner.displayName,
|
||||
};
|
||||
}}
|
||||
changeHandler={(relation: PartialUser) => {
|
||||
changeHandler={(relation: User) => {
|
||||
const company = props.row.original;
|
||||
if (company.accountOwner) {
|
||||
company.accountOwner.id = relation.id;
|
||||
@ -263,28 +260,17 @@ export const useCompaniesColumns = () => {
|
||||
}
|
||||
updateCompany(company);
|
||||
}}
|
||||
searchFilter={
|
||||
searchConfig={
|
||||
{
|
||||
key: 'account_owner_name',
|
||||
label: 'Account Owner',
|
||||
icon: <FaUser />,
|
||||
whereTemplate: () => {
|
||||
return {};
|
||||
},
|
||||
searchQuery: SEARCH_USER_QUERY,
|
||||
searchTemplate: (searchInput: string) => ({
|
||||
query: SEARCH_USER_QUERY,
|
||||
template: (searchInput: string) => ({
|
||||
displayName: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
searchResultMapper: (accountOwner: GraphqlQueryUser) => ({
|
||||
displayValue: accountOwner.displayName,
|
||||
value: {
|
||||
id: accountOwner.id,
|
||||
email: accountOwner.email,
|
||||
displayName: accountOwner.displayName,
|
||||
},
|
||||
resultMapper: (accountOwner) => ({
|
||||
render: (accountOwner) => accountOwner.displayName,
|
||||
value: mapUser(accountOwner),
|
||||
}),
|
||||
operands: [],
|
||||
} satisfies FilterType<Users_Bool_Exp>
|
||||
} satisfies SearchConfigType<User>
|
||||
}
|
||||
/>
|
||||
),
|
||||
|
||||
@ -19,7 +19,10 @@ import {
|
||||
} from '../../services/people';
|
||||
import { useSearch } from '../../services/search/search';
|
||||
import { People_Bool_Exp } from '../../generated/graphql';
|
||||
import { SelectedFilterType } from '../../components/table/table-header/interface';
|
||||
import {
|
||||
FilterConfigType,
|
||||
SelectedFilterType,
|
||||
} from '../../components/table/table-header/interface';
|
||||
import {
|
||||
reduceFiltersToWhere,
|
||||
reduceSortsToOrderBy,
|
||||
@ -44,7 +47,7 @@ function People() {
|
||||
}, []);
|
||||
|
||||
const updateFilters = useCallback(
|
||||
(filters: Array<SelectedFilterType<People_Bool_Exp>>) => {
|
||||
(filters: Array<SelectedFilterType<Person>>) => {
|
||||
setWhere(reduceFiltersToWhere(filters));
|
||||
},
|
||||
[],
|
||||
@ -106,7 +109,7 @@ function People() {
|
||||
viewName="All People"
|
||||
viewIcon={<FaList />}
|
||||
availableSorts={availableSorts}
|
||||
availableFilters={availableFilters}
|
||||
availableFilters={availableFilters as Array<FilterConfigType>}
|
||||
filterSearchResults={filterSearchResults}
|
||||
onSortsUpdate={updateSorts}
|
||||
onFiltersUpdate={updateFilters}
|
||||
|
||||
@ -7,130 +7,3 @@ Object {
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the filter city 2`] = `
|
||||
Object {
|
||||
"_not": Object {
|
||||
"city": Object {
|
||||
"_eq": "Paris",
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the filter company_name 1`] = `
|
||||
Object {
|
||||
"company": Object {
|
||||
"name": Object {
|
||||
"_eq": "Airbnb",
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the filter company_name 2`] = `
|
||||
Object {
|
||||
"_not": Object {
|
||||
"company": Object {
|
||||
"name": Object {
|
||||
"_eq": "Airbnb",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the filter email 1`] = `
|
||||
Object {
|
||||
"email": Object {
|
||||
"_eq": "john@linkedin.com",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the filter email 2`] = `
|
||||
Object {
|
||||
"_not": Object {
|
||||
"email": Object {
|
||||
"_eq": "john@linkedin.com",
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the filter fullname 1`] = `
|
||||
Object {
|
||||
"_and": Array [
|
||||
Object {
|
||||
"firstname": Object {
|
||||
"_eq": "John",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"lastname": Object {
|
||||
"_eq": "Doe",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the filter fullname 2`] = `
|
||||
Object {
|
||||
"_not": Object {
|
||||
"_and": Array [
|
||||
Object {
|
||||
"firstname": Object {
|
||||
"_eq": "John",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"lastname": Object {
|
||||
"_eq": "Doe",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the serch city with the searchValue 1`] = `
|
||||
Object {
|
||||
"city": Object {
|
||||
"_ilike": "%Search value%",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the serch company_name with the searchValue 1`] = `
|
||||
Object {
|
||||
"name": Object {
|
||||
"_ilike": "%Search value%",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the serch email with the searchValue 1`] = `
|
||||
Object {
|
||||
"email": Object {
|
||||
"_ilike": "%Search value%",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the serch fullname with the searchValue 1`] = `
|
||||
Object {
|
||||
"_or": Array [
|
||||
Object {
|
||||
"firstname": Object {
|
||||
"_ilike": "%Search value%",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"lastname": Object {
|
||||
"_ilike": "%Search value%",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
@ -1,65 +1,19 @@
|
||||
import { FilterType } from '../../../components/table/table-header/interface';
|
||||
import { People_Bool_Exp } from '../../../generated/graphql';
|
||||
import { GraphqlQueryCompany } from '../../../interfaces/company.interface';
|
||||
import { GraphqlQueryPerson } from '../../../interfaces/person.interface';
|
||||
import {
|
||||
SEARCH_COMPANY_QUERY,
|
||||
SEARCH_PEOPLE_QUERY,
|
||||
} from '../../../services/search/search';
|
||||
import { mockData as mockCompanyData } from '../../companies/__tests__/__data__/mock-data';
|
||||
import { mockData as mockPeopleData } from './__data__/mock-data';
|
||||
import { availableFilters } from '../people-table';
|
||||
|
||||
function assertFilterUseCompanySearch<FilterValue>(
|
||||
filter: FilterType<People_Bool_Exp>,
|
||||
): filter is FilterType<People_Bool_Exp> & {
|
||||
searchResultMapper: (data: GraphqlQueryCompany) => {
|
||||
displayValue: string;
|
||||
value: FilterValue;
|
||||
};
|
||||
} {
|
||||
return filter.searchQuery === SEARCH_COMPANY_QUERY;
|
||||
}
|
||||
|
||||
function assertFilterUsePeopleSearch<FilterValue>(
|
||||
filter: FilterType<People_Bool_Exp>,
|
||||
): filter is FilterType<People_Bool_Exp> & {
|
||||
searchResultMapper: (data: GraphqlQueryPerson) => {
|
||||
displayValue: string;
|
||||
value: FilterValue;
|
||||
};
|
||||
} {
|
||||
return filter.searchQuery === SEARCH_PEOPLE_QUERY;
|
||||
}
|
||||
|
||||
const JohnDoeUser = mockPeopleData.find(
|
||||
(user) => user.email === 'john@linkedin.com',
|
||||
) as GraphqlQueryPerson;
|
||||
import { cityFilter } from '../people-table';
|
||||
|
||||
describe('PeopleFilter', () => {
|
||||
for (const filter of availableFilters) {
|
||||
it(`should render the filter ${filter.key}`, () => {
|
||||
if (assertFilterUseCompanySearch(filter)) {
|
||||
const filterSelectedValue = filter.searchResultMapper(
|
||||
mockCompanyData[0],
|
||||
);
|
||||
for (const operand of filter.operands) {
|
||||
expect(
|
||||
filter.whereTemplate(operand, filterSelectedValue.value),
|
||||
).toMatchSnapshot();
|
||||
}
|
||||
}
|
||||
if (assertFilterUsePeopleSearch(filter)) {
|
||||
const filterSelectedValue = filter.searchResultMapper(JohnDoeUser);
|
||||
for (const operand of filter.operands) {
|
||||
expect(
|
||||
filter.whereTemplate(operand, filterSelectedValue.value),
|
||||
).toMatchSnapshot();
|
||||
}
|
||||
}
|
||||
});
|
||||
it(`should render the serch ${filter.key} with the searchValue`, () => {
|
||||
expect(filter.searchTemplate('Search value')).toMatchSnapshot();
|
||||
});
|
||||
}
|
||||
it(`should render the filter ${cityFilter.key}`, () => {
|
||||
expect(
|
||||
cityFilter.operands[0].whereTemplate({
|
||||
id: 'test-id',
|
||||
city: 'Paris',
|
||||
email: 'john@doe.com',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
phone: '0123456789',
|
||||
creationDate: new Date(),
|
||||
pipe: null,
|
||||
company: null,
|
||||
}),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@ -14,25 +14,19 @@ import Checkbox from '../../components/form/Checkbox';
|
||||
import CompanyChip, {
|
||||
CompanyChipPropsType,
|
||||
} from '../../components/chips/CompanyChip';
|
||||
import { GraphqlQueryPerson, Person } from '../../interfaces/person.interface';
|
||||
import { Person, mapPerson } from '../../interfaces/person.interface';
|
||||
import EditableText from '../../components/table/editable-cell/EditableText';
|
||||
import {
|
||||
FilterType,
|
||||
FilterConfigType,
|
||||
SearchConfigType,
|
||||
SortType,
|
||||
} from '../../components/table/table-header/interface';
|
||||
import {
|
||||
Order_By,
|
||||
People_Bool_Exp,
|
||||
People_Order_By,
|
||||
} from '../../generated/graphql';
|
||||
import { Order_By, People_Order_By } from '../../generated/graphql';
|
||||
import {
|
||||
SEARCH_COMPANY_QUERY,
|
||||
SEARCH_PEOPLE_QUERY,
|
||||
} from '../../services/search/search';
|
||||
import {
|
||||
GraphqlQueryCompany,
|
||||
PartialCompany,
|
||||
} from '../../interfaces/company.interface';
|
||||
import { Company, mapCompany } from '../../interfaces/company.interface';
|
||||
import EditablePhone from '../../components/table/editable-cell/EditablePhone';
|
||||
import EditableFullName from '../../components/table/editable-cell/EditableFullName';
|
||||
import EditableDate from '../../components/table/editable-cell/EditableDate';
|
||||
@ -85,163 +79,155 @@ export const availableSorts = [
|
||||
},
|
||||
] satisfies Array<SortType<People_Order_By>>;
|
||||
|
||||
const fullnameFilter = {
|
||||
export const fullnameFilter = {
|
||||
key: 'fullname',
|
||||
label: 'People',
|
||||
icon: <FaUser />,
|
||||
whereTemplate: (operand, { firstname, lastname }) => {
|
||||
if (operand.keyWord === 'equal') {
|
||||
return {
|
||||
searchConfig: {
|
||||
query: SEARCH_PEOPLE_QUERY,
|
||||
template: (searchInput: string) => ({
|
||||
_or: [
|
||||
{ firstname: { _ilike: `%${searchInput}%` } },
|
||||
{ lastname: { _ilike: `%${searchInput}%` } },
|
||||
],
|
||||
}),
|
||||
resultMapper: (person) => ({
|
||||
render: (person) => `${person.firstname} ${person.lastname}`,
|
||||
value: mapPerson(person),
|
||||
}),
|
||||
},
|
||||
selectedValueRender: (person) => `${person.firstname} ${person.lastname}`,
|
||||
operands: [
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
whereTemplate: (person) => ({
|
||||
_and: [
|
||||
{ firstname: { _eq: `${firstname}` } },
|
||||
{ lastname: { _eq: `${lastname}` } },
|
||||
{ firstname: { _eq: `${person.firstname}` } },
|
||||
{ lastname: { _eq: `${person.lastname}` } },
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
if (operand.keyWord === 'not_equal') {
|
||||
return {
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
whereTemplate: (person) => ({
|
||||
_not: {
|
||||
_and: [
|
||||
{ firstname: { _eq: `${firstname}` } },
|
||||
{ lastname: { _eq: `${lastname}` } },
|
||||
{ firstname: { _eq: `${person.firstname}` } },
|
||||
{ lastname: { _eq: `${person.lastname}` } },
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
searchQuery: SEARCH_PEOPLE_QUERY,
|
||||
searchTemplate: (searchInput: string) => ({
|
||||
_or: [
|
||||
{ firstname: { _ilike: `%${searchInput}%` } },
|
||||
{ lastname: { _ilike: `%${searchInput}%` } },
|
||||
],
|
||||
}),
|
||||
searchResultMapper: (person: GraphqlQueryPerson) => ({
|
||||
displayValue: `${person.firstname} ${person.lastname}`,
|
||||
value: { firstname: person.firstname, lastname: person.lastname },
|
||||
}),
|
||||
operands: [
|
||||
{ label: 'Equal', id: 'equal', keyWord: 'equal' },
|
||||
{ label: 'Not equal', id: 'not-equal', keyWord: 'not_equal' },
|
||||
}),
|
||||
},
|
||||
],
|
||||
} satisfies FilterType<People_Bool_Exp>;
|
||||
} satisfies FilterConfigType<Person, Person>;
|
||||
|
||||
const companyFilter = {
|
||||
export const companyFilter = {
|
||||
key: 'company_name',
|
||||
label: 'Company',
|
||||
icon: <FaBuilding />,
|
||||
whereTemplate: (operand, { companyName }) => {
|
||||
if (operand.keyWord === 'equal') {
|
||||
return {
|
||||
company: { name: { _eq: companyName } },
|
||||
};
|
||||
}
|
||||
|
||||
if (operand.keyWord === 'not_equal') {
|
||||
return {
|
||||
_not: { company: { name: { _eq: companyName } } },
|
||||
};
|
||||
}
|
||||
searchConfig: {
|
||||
query: SEARCH_COMPANY_QUERY,
|
||||
template: (searchInput: string) => ({
|
||||
name: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
resultMapper: (data) => ({
|
||||
value: mapCompany(data),
|
||||
render: (company) => company.name,
|
||||
}),
|
||||
},
|
||||
searchQuery: SEARCH_COMPANY_QUERY,
|
||||
searchTemplate: (searchInput: string) => ({
|
||||
name: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
searchResultMapper: (company: GraphqlQueryCompany) => ({
|
||||
displayValue: company.name,
|
||||
value: { companyName: company.name },
|
||||
}),
|
||||
selectedValueRender: (company) => company.name,
|
||||
operands: [
|
||||
{ label: 'Equal', id: 'equal', keyWord: 'equal' },
|
||||
{ label: 'Not equal', id: 'not-equal', keyWord: 'not_equal' },
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
whereTemplate: (company) => ({
|
||||
company: { name: { _eq: company.name } },
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
whereTemplate: (company) => ({
|
||||
_not: { company: { name: { _eq: company.name } } },
|
||||
}),
|
||||
},
|
||||
],
|
||||
} satisfies FilterType<People_Bool_Exp>;
|
||||
} satisfies FilterConfigType<Person, Company>;
|
||||
|
||||
const emailFilter = {
|
||||
export const emailFilter = {
|
||||
key: 'email',
|
||||
label: 'Email',
|
||||
icon: <FaEnvelope />,
|
||||
whereTemplate: (operand, { email }) => {
|
||||
if (operand.keyWord === 'equal') {
|
||||
return {
|
||||
email: { _eq: email },
|
||||
};
|
||||
}
|
||||
|
||||
if (operand.keyWord === 'not_equal') {
|
||||
return {
|
||||
_not: { email: { _eq: email } },
|
||||
};
|
||||
}
|
||||
searchConfig: {
|
||||
query: SEARCH_PEOPLE_QUERY,
|
||||
template: (searchInput: string) => ({
|
||||
email: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
resultMapper: (person) => ({
|
||||
render: (person) => person.email,
|
||||
value: mapPerson(person),
|
||||
}),
|
||||
},
|
||||
searchQuery: SEARCH_PEOPLE_QUERY,
|
||||
searchTemplate: (searchInput: string) => ({
|
||||
email: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
searchResultMapper: (person: GraphqlQueryPerson) => ({
|
||||
displayValue: person.email,
|
||||
value: { email: person.email },
|
||||
}),
|
||||
operands: [
|
||||
{ label: 'Equal', id: 'equal', keyWord: 'equal' },
|
||||
{ label: 'Not equal', id: 'not-equal', keyWord: 'not_equal' },
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
whereTemplate: (person) => ({
|
||||
email: { _eq: person.email },
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
whereTemplate: (person) => ({
|
||||
_not: { email: { _eq: person.email } },
|
||||
}),
|
||||
},
|
||||
],
|
||||
} satisfies FilterType<People_Bool_Exp>;
|
||||
selectedValueRender: (person) => person.email,
|
||||
} satisfies FilterConfigType<Person, Person>;
|
||||
|
||||
const cityFilter = {
|
||||
export const cityFilter = {
|
||||
key: 'city',
|
||||
label: 'City',
|
||||
icon: <FaMapPin />,
|
||||
whereTemplate: (operand, { city }) => {
|
||||
if (operand.keyWord === 'equal') {
|
||||
return {
|
||||
city: { _eq: city },
|
||||
};
|
||||
}
|
||||
|
||||
if (operand.keyWord === 'not_equal') {
|
||||
return {
|
||||
_not: { city: { _eq: city } },
|
||||
};
|
||||
}
|
||||
searchConfig: {
|
||||
query: SEARCH_PEOPLE_QUERY,
|
||||
template: (searchInput: string) => ({
|
||||
city: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
resultMapper: (person) => ({
|
||||
render: (person) => person.city,
|
||||
value: mapPerson(person),
|
||||
}),
|
||||
},
|
||||
searchQuery: SEARCH_PEOPLE_QUERY,
|
||||
searchTemplate: (searchInput: string) => ({
|
||||
city: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
searchResultMapper: (person: GraphqlQueryPerson) => ({
|
||||
displayValue: person.city,
|
||||
value: { city: person.city },
|
||||
}),
|
||||
operands: [
|
||||
{ label: 'Equal', id: 'equal', keyWord: 'equal' },
|
||||
{ label: 'Not equal', id: 'not-equal', keyWord: 'not_equal' },
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
whereTemplate: (person) => ({
|
||||
city: { _eq: person.city },
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
whereTemplate: (person) => ({
|
||||
_not: { city: { _eq: person.city } },
|
||||
}),
|
||||
},
|
||||
],
|
||||
} satisfies FilterType<People_Bool_Exp>;
|
||||
selectedValueRender: (person) => person.email,
|
||||
} satisfies FilterConfigType<Person, Person>;
|
||||
|
||||
export const availableFilters = [
|
||||
fullnameFilter,
|
||||
companyFilter,
|
||||
emailFilter,
|
||||
cityFilter,
|
||||
// {
|
||||
// key: 'phone',
|
||||
// label: 'Phone',
|
||||
// icon: faPhone,
|
||||
// whereTemplate: () => ({ phone: { _ilike: '%value%' } }),
|
||||
// searchQuery: GET_PEOPLE,
|
||||
// searchTemplate: { phone: { _ilike: '%value%' } },
|
||||
// },
|
||||
// {
|
||||
// key: 'created_at',
|
||||
// label: 'Created at',
|
||||
// icon: faCalendar,
|
||||
// whereTemplate: () => ({ created_at: { _eq: '%value%' } }),
|
||||
// searchQuery: GET_PEOPLE,
|
||||
// searchTemplate: { created_at: { _eq: '%value%' } },
|
||||
// },
|
||||
] satisfies FilterType<People_Bool_Exp>[];
|
||||
];
|
||||
|
||||
const columnHelper = createColumnHelper<Person>();
|
||||
|
||||
@ -300,53 +286,36 @@ export const usePeopleColumns = () => {
|
||||
<ColumnHead viewName="Company" viewIcon={<FaRegBuilding />} />
|
||||
),
|
||||
cell: (props) => (
|
||||
<EditableRelation<PartialCompany, CompanyChipPropsType>
|
||||
<EditableRelation<Company, CompanyChipPropsType>
|
||||
relation={props.row.original.company}
|
||||
searchPlaceholder="Company"
|
||||
ChipComponent={CompanyChip}
|
||||
chipComponentPropsMapper={(
|
||||
company: PartialCompany,
|
||||
): CompanyChipPropsType => {
|
||||
chipComponentPropsMapper={(company): CompanyChipPropsType => {
|
||||
return {
|
||||
name: company.name,
|
||||
picture: `https://www.google.com/s2/favicons?domain=${company.domain_name}&sz=256`,
|
||||
};
|
||||
}}
|
||||
changeHandler={(relation: PartialCompany) => {
|
||||
changeHandler={(relation) => {
|
||||
const person = props.row.original;
|
||||
if (person.company) {
|
||||
person.company.id = relation.id;
|
||||
} else {
|
||||
person.company = {
|
||||
id: relation.id,
|
||||
name: relation.name,
|
||||
domain_name: relation.domain_name,
|
||||
};
|
||||
person.company = relation;
|
||||
}
|
||||
updatePerson(person);
|
||||
}}
|
||||
searchFilter={
|
||||
searchConfig={
|
||||
{
|
||||
key: 'company_name',
|
||||
label: 'Company',
|
||||
icon: <FaBuilding />,
|
||||
whereTemplate: () => {
|
||||
return {};
|
||||
},
|
||||
searchQuery: SEARCH_COMPANY_QUERY,
|
||||
searchTemplate: (searchInput: string) => ({
|
||||
query: SEARCH_COMPANY_QUERY,
|
||||
template: (searchInput: string) => ({
|
||||
name: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
searchResultMapper: (company: GraphqlQueryCompany) => ({
|
||||
displayValue: company.name,
|
||||
value: {
|
||||
id: company.id,
|
||||
name: company.name,
|
||||
domain_name: company.domain_name,
|
||||
},
|
||||
resultMapper: (company) => ({
|
||||
render: (company) => company.name,
|
||||
value: mapCompany(company),
|
||||
}),
|
||||
operands: [],
|
||||
} satisfies FilterType<People_Bool_Exp>
|
||||
} satisfies SearchConfigType<Company>
|
||||
}
|
||||
/>
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user