diff --git a/front/src/components/table/Table.tsx b/front/src/components/table/Table.tsx index e2164b0fc9..b2eff0c614 100644 --- a/front/src/components/table/Table.tsx +++ b/front/src/components/table/Table.tsx @@ -87,7 +87,7 @@ const StyledTableScrollableContainer = styled.div` flex: 1; `; -function Table<TData, SortField extends string, FilterProperies>({ +function Table<TData extends { id: string }, SortField, FilterProperies>({ data, columns, viewName, @@ -140,7 +140,7 @@ function Table<TData, SortField extends string, FilterProperies>({ <tr key={row.id} data-testid={`row-id-${row.index}`}> {row.getVisibleCells().map((cell) => { return ( - <td key={cell.id}> + <td key={cell.id + row.original.id}> {flexRender( cell.column.columnDef.cell, cell.getContext(), diff --git a/front/src/components/table/table-header/FilterDropdownButton.tsx b/front/src/components/table/table-header/FilterDropdownButton.tsx index a5025fbe72..420b3af1f8 100644 --- a/front/src/components/table/table-header/FilterDropdownButton.tsx +++ b/front/src/components/table/table-header/FilterDropdownButton.tsx @@ -84,10 +84,11 @@ export function FilterDropdownButton<FilterProperties>({ label: selectedFilter.label, value: value.displayValue, icon: selectedFilter.icon, - where: selectedFilter.whereTemplate( - selectedFilterOperand, - value.value, - ), + where: + selectedFilter.whereTemplate( + selectedFilterOperand, + value.value, + ) || ({} as FilterProperties), searchResultMapper: selectedFilter.searchResultMapper, }); setIsUnfolded(false); diff --git a/front/src/components/table/table-header/SortAndFilterBar.tsx b/front/src/components/table/table-header/SortAndFilterBar.tsx index 447c19b331..0fdb69f571 100644 --- a/front/src/components/table/table-header/SortAndFilterBar.tsx +++ b/front/src/components/table/table-header/SortAndFilterBar.tsx @@ -41,7 +41,7 @@ const StyledCancelButton = styled.button` } `; -function SortAndFilterBar<SortField extends string, FilterProperties>({ +function SortAndFilterBar<SortField, FilterProperties>({ sorts, onRemoveSort, filters, diff --git a/front/src/components/table/table-header/SortDropdownButton.tsx b/front/src/components/table/table-header/SortDropdownButton.tsx index 8e67cf9b07..b6459e40f9 100644 --- a/front/src/components/table/table-header/SortDropdownButton.tsx +++ b/front/src/components/table/table-header/SortDropdownButton.tsx @@ -8,9 +8,9 @@ type OwnProps<SortField> = { availableSorts: SortType<SortField>[]; }; -const options: Array<SelectedSortType<string>['order']> = ['asc', 'desc']; +const options: Array<SelectedSortType<any>['order']> = ['asc', 'desc']; -export function SortDropdownButton<SortField extends string>({ +export function SortDropdownButton<SortField>({ isSortSelected, availableSorts, onSortSelect, diff --git a/front/src/components/table/table-header/TableHeader.tsx b/front/src/components/table/table-header/TableHeader.tsx index 5181dfcf27..74a0829a06 100644 --- a/front/src/components/table/table-header/TableHeader.tsx +++ b/front/src/components/table/table-header/TableHeader.tsx @@ -66,7 +66,7 @@ const StyledFilters = styled.div` margin-right: ${(props) => props.theme.spacing(2)}; `; -function TableHeader<SortField extends string, FilterProperties>({ +function TableHeader<SortField, FilterProperties>({ viewName, viewIcon, availableSorts, @@ -84,37 +84,40 @@ function TableHeader<SortField extends string, FilterProperties>({ >([]); const sortSelect = useCallback( - (sort: SelectedSortType<SortField>) => { - innerSetSorts([sort]); - onSortsUpdate && onSortsUpdate([sort]); - }, - [onSortsUpdate], - ); - - const sortUnselect = useCallback( - (sortId: string) => { - const newSorts = [] as SelectedSortType<SortField>[]; + (newSort: SelectedSortType<SortField>) => { + const newSorts = updateSortOrFilterByKey(sorts, newSort); innerSetSorts(newSorts); onSortsUpdate && onSortsUpdate(newSorts); }, - [onSortsUpdate], + [onSortsUpdate, sorts], + ); + + const sortUnselect = useCallback( + (sortKey: string) => { + const newSorts = sorts.filter((sort) => sort.key !== sortKey); + innerSetSorts(newSorts); + onSortsUpdate && onSortsUpdate(newSorts); + }, + [onSortsUpdate, sorts], ); const filterSelect = useCallback( (filter: SelectedFilterType<FilterProperties>) => { - innerSetFilters([filter]); - onFiltersUpdate && onFiltersUpdate([filter]); + const newFilters = updateSortOrFilterByKey(filters, filter); + + innerSetFilters(newFilters); + onFiltersUpdate && onFiltersUpdate(newFilters); }, - [onFiltersUpdate], + [onFiltersUpdate, filters], ); const filterUnselect = useCallback( (filterId: SelectedFilterType<FilterProperties>['key']) => { - const newFilters = [] as SelectedFilterType<FilterProperties>[]; + const newFilters = filters.filter((filter) => filter.key !== filterId); innerSetFilters(newFilters); onFiltersUpdate && onFiltersUpdate(newFilters); }, - [onFiltersUpdate], + [onFiltersUpdate, filters], ); const filterSearch = useCallback( @@ -161,3 +164,19 @@ function TableHeader<SortField extends string, FilterProperties>({ } export default TableHeader; + +function updateSortOrFilterByKey<SortOrFilter extends { key: string }>( + sorts: Readonly<SortOrFilter[]>, + newSort: SortOrFilter, +): SortOrFilter[] { + const newSorts = [...sorts]; + const existingSortIndex = sorts.findIndex((sort) => sort.key === newSort.key); + + if (existingSortIndex !== -1) { + newSorts[existingSortIndex] = newSort; + } else { + newSorts.push(newSort); + } + + return newSorts; +} diff --git a/front/src/components/table/table-header/__stories__/SortAndFilterBar.stories.tsx b/front/src/components/table/table-header/__stories__/SortAndFilterBar.stories.tsx index 85a279177c..b336fce5a4 100644 --- a/front/src/components/table/table-header/__stories__/SortAndFilterBar.stories.tsx +++ b/front/src/components/table/table-header/__stories__/SortAndFilterBar.stories.tsx @@ -25,12 +25,14 @@ export const RegularSortAndFilterBar = ({ removeFunction }: OwnProps) => { order: 'asc', key: 'test_sort', icon: <FaArrowDown />, + _type: 'default_sort', }, { label: 'Test sort 2', order: 'desc', key: 'test_sort_2', icon: <FaArrowDown />, + _type: 'default_sort', }, ]} onRemoveSort={removeFunction} diff --git a/front/src/components/table/table-header/__stories__/SortDropdownButton.stories.tsx b/front/src/components/table/table-header/__stories__/SortDropdownButton.stories.tsx index b7d9a0ced2..fe3a838460 100644 --- a/front/src/components/table/table-header/__stories__/SortDropdownButton.stories.tsx +++ b/front/src/components/table/table-header/__stories__/SortDropdownButton.stories.tsx @@ -11,6 +11,7 @@ import { } from 'react-icons/fa'; import { SortDropdownButton } from '../SortDropdownButton'; import styled from '@emotion/styled'; +import { Order_By, People_Order_By } from '../../../../generated/graphql'; const component = { title: 'SortDropdownButton', @@ -28,25 +29,31 @@ const availableSorts = [ key: 'fullname', label: 'People', icon: <FaRegUser />, + _type: 'custom_sort', + orderByTemplate: () => ({ email: Order_By.Asc }), }, { key: 'company_name', label: 'Company', icon: <FaRegBuilding />, + _type: 'custom_sort', + orderByTemplate: () => ({ email: Order_By.Asc }), }, { key: 'email', label: 'Email', icon: <FaEnvelope />, + _type: 'default_sort', }, - { key: 'phone', label: 'Phone', icon: <FaPhone /> }, + { key: 'phone', label: 'Phone', icon: <FaPhone />, _type: 'default_sort' }, { key: 'created_at', label: 'Created at', icon: <FaCalendar />, + _type: 'default_sort', }, - { key: 'city', label: 'City', icon: <FaMapPin /> }, -] satisfies SortType[]; + { key: 'city', label: 'City', icon: <FaMapPin />, _type: 'default_sort' }, +] satisfies SortType<People_Order_By>[]; const StyleDiv = styled.div` height: 200px; @@ -57,7 +64,7 @@ export const RegularSortDropdownButton = ({ setSorts }: OwnProps) => { return ( <ThemeProvider theme={lightTheme}> <StyleDiv> - <SortDropdownButton + <SortDropdownButton<People_Order_By> isSortSelected={true} availableSorts={availableSorts} onSortSelect={setSorts} diff --git a/front/src/components/table/table-header/__stories__/TableHeader.stories.tsx b/front/src/components/table/table-header/__stories__/TableHeader.stories.tsx index 48ce03c3c2..ba1ddd5b90 100644 --- a/front/src/components/table/table-header/__stories__/TableHeader.stories.tsx +++ b/front/src/components/table/table-header/__stories__/TableHeader.stories.tsx @@ -12,11 +12,12 @@ const component = { export default component; export const RegularTableHeader = () => { - const availableSorts: Array<SortType> = [ + const availableSorts: Array<SortType<Record<'created_at', 'asc'>>> = [ { key: 'created_at', label: 'Created at', icon: <FaCalendar />, + _type: 'default_sort', }, ]; return ( diff --git a/front/src/components/table/table-header/__tests__/SortDropdownButton.test.tsx b/front/src/components/table/table-header/__tests__/SortDropdownButton.test.tsx index 6633660b60..36bbbfe87e 100644 --- a/front/src/components/table/table-header/__tests__/SortDropdownButton.test.tsx +++ b/front/src/components/table/table-header/__tests__/SortDropdownButton.test.tsx @@ -19,6 +19,7 @@ it('Checks the default top option is Ascending', async () => { key: 'email', icon: <FaEnvelope />, order: 'asc', + _type: 'default_sort', }); }); @@ -45,5 +46,6 @@ it('Checks the selection of Descending', async () => { key: 'email', icon: <FaEnvelope />, order: 'desc', + _type: 'default_sort', }); }); diff --git a/front/src/components/table/table-header/helpers.ts b/front/src/components/table/table-header/helpers.ts new file mode 100644 index 0000000000..66ab073f43 --- /dev/null +++ b/front/src/components/table/table-header/helpers.ts @@ -0,0 +1,33 @@ +import { Order_By } from '../../../generated/graphql'; +import { SelectedFilterType, SelectedSortType } from './interface'; + +export const reduceFiltersToWhere = <T>( + filters: Array<SelectedFilterType<T>>, +): T => { + const where = filters.reduce((acc, filter) => { + const { where } = filter; + return { ...acc, ...where }; + }, {} as T); + return where; +}; + +const mapOrderToOrder_By = (order: string) => { + if (order === 'asc') return Order_By.Asc; + return Order_By.Desc; +}; + +export const defaultOrderByTemplateFactory = + (key: string) => (order: string) => ({ + [key]: order, + }); + +export const reduceSortsToOrderBy = <OrderByTemplate>( + sorts: Array<SelectedSortType<OrderByTemplate>>, +): OrderByTemplate[] => { + const mappedSorts = sorts.map((sort) => { + if (sort._type === 'custom_sort') + return sort.orderByTemplate(mapOrderToOrder_By(sort.order)); + return defaultOrderByTemplateFactory(sort.key as string)(sort.order); + }); + return mappedSorts as OrderByTemplate[]; +}; diff --git a/front/src/components/table/table-header/interface.ts b/front/src/components/table/table-header/interface.ts index 090101f363..6380f30e84 100644 --- a/front/src/components/table/table-header/interface.ts +++ b/front/src/components/table/table-header/interface.ts @@ -2,23 +2,27 @@ import { DocumentNode } from 'graphql'; import { ReactNode } from 'react'; import { Companies_Bool_Exp, + Order_By, People_Bool_Exp, Users_Bool_Exp, } from '../../../generated/graphql'; -import { GraphqlQueryCompany } from '../../../interfaces/company.interface'; -import { - SEARCH_COMPANY_QUERY, - SEARCH_PEOPLE_QUERY, -} from '../../../services/search/search'; -import { GraphqlQueryPerson } from '../../../interfaces/person.interface'; -export type SortType<SortKey = string> = { - label: string; - key: SortKey; - icon?: ReactNode; -}; +export type SortType<OrderByTemplate> = + | { + _type: 'default_sort'; + label: string; + key: keyof OrderByTemplate & string; + icon?: ReactNode; + } + | { + _type: 'custom_sort'; + label: string; + key: string; + icon?: ReactNode; + orderByTemplate: (order: Order_By) => OrderByTemplate; + }; -export type SelectedSortType<SortField = string> = SortType<SortField> & { +export type SelectedSortType<OrderByTemplate> = SortType<OrderByTemplate> & { order: 'asc' | 'desc'; }; @@ -30,7 +34,7 @@ export type FilterType<WhereTemplate, FilterValue = Record<string, any>> = { whereTemplate: ( operand: FilterOperandType, value: FilterValue, - ) => WhereTemplate; + ) => WhereTemplate | undefined; searchQuery: DocumentNode; searchTemplate: ( searchInput: string, @@ -52,25 +56,3 @@ export type SelectedFilterType<WhereTemplate> = FilterType<WhereTemplate> & { operand: FilterOperandType; where: WhereTemplate; }; - -export 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; -} - -export 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; -} diff --git a/front/src/pages/companies/Companies.tsx b/front/src/pages/companies/Companies.tsx index a710d47031..8b33e96203 100644 --- a/front/src/pages/companies/Companies.tsx +++ b/front/src/pages/companies/Companies.tsx @@ -5,12 +5,12 @@ import { useState, useCallback } from 'react'; import { CompaniesSelectedSortType, defaultOrderBy, - reduceSortsToOrderBy, useCompaniesQuery, } from '../../services/companies'; import Table from '../../components/table/Table'; import { mapCompany } from '../../interfaces/company.interface'; import { companiesColumns, sortsAvailable } from './companies-table'; +import { reduceSortsToOrderBy } from '../../components/table/table-header/helpers'; const StyledCompaniesContainer = styled.div` display: flex; diff --git a/front/src/pages/companies/companies-table.tsx b/front/src/pages/companies/companies-table.tsx index 51403cdaa2..7691316c8d 100644 --- a/front/src/pages/companies/companies-table.tsx +++ b/front/src/pages/companies/companies-table.tsx @@ -1,6 +1,6 @@ import { createColumnHelper } from '@tanstack/react-table'; import { Company } from '../../interfaces/company.interface'; -import { OrderByFields, updateCompany } from '../../services/companies'; +import { updateCompany } from '../../services/companies'; import ColumnHead from '../../components/table/ColumnHead'; import Checkbox from '../../components/form/Checkbox'; import CompanyChip from '../../components/chips/CompanyChip'; @@ -17,21 +17,24 @@ import { } from 'react-icons/fa'; import ClickableCell from '../../components/table/ClickableCell'; import PersonChip from '../../components/chips/PersonChip'; -import { SortType } from '../../components/table/table-header/interface'; import EditableChip from '../../components/table/editable-cell/EditableChip'; +import { SortType } from '../../components/table/table-header/interface'; +import { Companies_Order_By } from '../../generated/graphql'; export const sortsAvailable = [ { key: 'name', label: 'Name', icon: undefined, + _type: 'default_sort', }, { key: 'domain_name', label: 'Domain', icon: undefined, + _type: 'default_sort', }, -] satisfies Array<SortType<OrderByFields>>; +] satisfies Array<SortType<Companies_Order_By>>; const columnHelper = createColumnHelper<Company>(); export const companiesColumns = [ diff --git a/front/src/pages/people/People.tsx b/front/src/pages/people/People.tsx index 190b06f843..dc2a47f1c3 100644 --- a/front/src/pages/people/People.tsx +++ b/front/src/pages/people/People.tsx @@ -12,13 +12,15 @@ import { useCallback, useState } from 'react'; import { PeopleSelectedSortType, defaultOrderBy, - reduceFiltersToWhere, - reduceSortsToOrderBy, usePeopleQuery, } 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 { + reduceFiltersToWhere, + reduceSortsToOrderBy, +} from '../../components/table/table-header/helpers'; const StyledPeopleContainer = styled.div` display: flex; diff --git a/front/src/pages/people/__tests__/__snapshots__/people-filter.test.ts.snap b/front/src/pages/people/__tests__/__snapshots__/people-filter.test.ts.snap index d9db6a8323..cd9e9e36f1 100644 --- a/front/src/pages/people/__tests__/__snapshots__/people-filter.test.ts.snap +++ b/front/src/pages/people/__tests__/__snapshots__/people-filter.test.ts.snap @@ -93,3 +93,44 @@ Object { }, } `; + +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%", + }, + }, + ], +} +`; diff --git a/front/src/pages/people/__tests__/people-filter.test.ts b/front/src/pages/people/__tests__/people-filter.test.ts index 74386c5d5e..ffc96b8d4d 100644 --- a/front/src/pages/people/__tests__/people-filter.test.ts +++ b/front/src/pages/people/__tests__/people-filter.test.ts @@ -1,12 +1,37 @@ -import { - assertFilterUseCompanySearch, - assertFilterUsePeopleSearch, -} from '../../../components/table/table-header/interface'; +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 { mockCompanyData } from '../../companies/__stories__/mock-data'; import { defaultData } from '../default-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 = defaultData.find( (user) => user.email === 'john@linkedin.com', ) as GraphqlQueryPerson; @@ -33,5 +58,8 @@ describe('PeopleFilter', () => { } } }); + it(`should render the serch ${filter.key} with the searchValue`, () => { + expect(filter.searchTemplate('Search value')).toMatchSnapshot(); + }); } }); diff --git a/front/src/pages/people/people-table.tsx b/front/src/pages/people/people-table.tsx index 79d177293a..93b1cd9410 100644 --- a/front/src/pages/people/people-table.tsx +++ b/front/src/pages/people/people-table.tsx @@ -17,12 +17,16 @@ import CompanyChip from '../../components/chips/CompanyChip'; import { GraphqlQueryPerson, Person } from '../../interfaces/person.interface'; import PipeChip from '../../components/chips/PipeChip'; import EditableText from '../../components/table/editable-cell/EditableText'; -import { OrderByFields, updatePerson } from '../../services/people'; +import { updatePerson } from '../../services/people'; import { FilterType, SortType, } from '../../components/table/table-header/interface'; -import { People_Bool_Exp } from '../../generated/graphql'; +import { + Order_By, + People_Bool_Exp, + People_Order_By, +} from '../../generated/graphql'; import { SEARCH_COMPANY_QUERY, SEARCH_PEOPLE_QUERY, @@ -36,25 +40,44 @@ export const availableSorts = [ key: 'fullname', label: 'People', icon: <FaRegUser />, + _type: 'custom_sort', + orderByTemplate: (order: Order_By) => ({ + firstname: order, + lastname: order, + }), }, { key: 'company_name', label: 'Company', icon: <FaRegBuilding />, + _type: 'custom_sort', + orderByTemplate: (order: Order_By) => ({ company: { name: order } }), }, { key: 'email', label: 'Email', icon: <FaEnvelope />, + _type: 'default_sort', + }, + { + key: 'phone', + label: 'Phone', + icon: <FaPhone />, + _type: 'default_sort', }, - { key: 'phone', label: 'Phone', icon: <FaPhone /> }, { key: 'created_at', label: 'Created at', icon: <FaCalendar />, + _type: 'default_sort', }, - { key: 'city', label: 'City', icon: <FaMapPin /> }, -] satisfies Array<SortType<OrderByFields>>; + { + key: 'city', + label: 'City', + icon: <FaMapPin />, + _type: 'default_sort', + }, +] satisfies Array<SortType<People_Order_By>>; const fullnameFilter = { key: 'fullname', @@ -80,8 +103,6 @@ const fullnameFilter = { }, }; } - console.error(Error(`Unhandled operand: ${operand.keyWord}`)); - return {}; }, searchQuery: SEARCH_PEOPLE_QUERY, searchTemplate: (searchInput: string) => ({ @@ -116,8 +137,6 @@ const companyFilter = { _not: { company: { name: { _eq: companyName } } }, }; } - console.error(Error(`Unhandled operand: ${operand.keyWord}`)); - return {}; }, searchQuery: SEARCH_COMPANY_QUERY, searchTemplate: (searchInput: string) => ({ @@ -149,8 +168,6 @@ const emailFilter = { _not: { email: { _eq: email } }, }; } - console.error(Error(`Unhandled operand: ${operand.keyWord}`)); - return {}; }, searchQuery: SEARCH_PEOPLE_QUERY, searchTemplate: (searchInput: string) => ({ @@ -182,8 +199,6 @@ const cityFilter = { _not: { city: { _eq: city } }, }; } - console.error(Error(`Unhandled operand: ${operand.keyWord}`)); - return {}; }, searchQuery: SEARCH_PEOPLE_QUERY, searchTemplate: (searchInput: string) => ({ diff --git a/front/src/services/companies/select.test.ts b/front/src/services/companies/select.test.ts index 73eb73630c..ec884969fc 100644 --- a/front/src/services/companies/select.test.ts +++ b/front/src/services/companies/select.test.ts @@ -1,12 +1,18 @@ -import { CompaniesSelectedSortType, reduceSortsToOrderBy } from './select'; +import { reduceSortsToOrderBy } from '../../components/table/table-header/helpers'; +import { CompaniesSelectedSortType } from './select'; describe('reduceSortsToOrderBy', () => { it('should return an array of objects with the id as key and the order as value', () => { const sorts = [ - { key: 'name', label: 'name', order: 'asc' }, - { key: 'domain_name', label: 'domain_name', order: 'desc' }, + { key: 'name', label: 'name', order: 'asc', _type: 'default_sort' }, + { + key: 'domain_name', + label: 'domain_name', + order: 'desc', + _type: 'default_sort', + }, ] satisfies CompaniesSelectedSortType[]; const result = reduceSortsToOrderBy(sorts); - expect(result).toEqual([{ name: 'asc', domain_name: 'desc' }]); + expect(result).toEqual([{ name: 'asc' }, { domain_name: 'desc' }]); }); }); diff --git a/front/src/services/companies/select.ts b/front/src/services/companies/select.ts index 4811862687..3dfc29af92 100644 --- a/front/src/services/companies/select.ts +++ b/front/src/services/companies/select.ts @@ -3,25 +3,7 @@ import { Order_By, Companies_Order_By } from '../../generated/graphql'; import { GraphqlQueryCompany } from '../../interfaces/company.interface'; import { SelectedSortType } from '../../components/table/table-header/interface'; -export type OrderByFields = keyof Companies_Order_By | 'domain_name' | 'name'; - -export type CompaniesSelectedSortType = SelectedSortType<OrderByFields>; - -const mapOrder = (order: 'asc' | 'desc'): Order_By => { - return order === 'asc' ? Order_By.Asc : Order_By.Desc; -}; - -export const reduceSortsToOrderBy = ( - sorts: Array<CompaniesSelectedSortType>, -): Companies_Order_By[] => { - const mappedSorts = sorts.reduce((acc, sort) => { - const id = sort.key; - const order = mapOrder(sort.order); - acc[id] = order; - return acc; - }, {} as Companies_Order_By); - return [mappedSorts]; -}; +export type CompaniesSelectedSortType = SelectedSortType<Companies_Order_By>; export const GET_COMPANIES = gql` query GetCompanies($orderBy: [companies_order_by!]) { diff --git a/front/src/services/people/select.test.ts b/front/src/services/people/select.test.ts index 52ff25b389..47b134f0f3 100644 --- a/front/src/services/people/select.test.ts +++ b/front/src/services/people/select.test.ts @@ -1,12 +1,23 @@ -import { PeopleSelectedSortType, reduceSortsToOrderBy } from './select'; +import { reduceSortsToOrderBy } from '../../components/table/table-header/helpers'; +import { PeopleSelectedSortType } from './select'; describe('reduceSortsToOrderBy', () => { it('should return an array of objects with the id as key and the order as value', () => { const sorts = [ - { key: 'firstname', label: 'firstname', order: 'asc' }, - { key: 'lastname', label: 'lastname', order: 'desc' }, + { + key: 'firstname', + label: 'firstname', + order: 'asc', + _type: 'default_sort', + }, + { + key: 'lastname', + label: 'lastname', + order: 'desc', + _type: 'default_sort', + }, ] satisfies PeopleSelectedSortType[]; const result = reduceSortsToOrderBy(sorts); - expect(result).toEqual([{ firstname: 'asc', lastname: 'desc' }]); + expect(result).toEqual([{ firstname: 'asc' }, { lastname: 'desc' }]); }); }); diff --git a/front/src/services/people/select.ts b/front/src/services/people/select.ts index 728f846519..b51512f782 100644 --- a/front/src/services/people/select.ts +++ b/front/src/services/people/select.ts @@ -5,47 +5,9 @@ import { People_Bool_Exp, People_Order_By, } from '../../generated/graphql'; -import { - SelectedFilterType, - SelectedSortType, -} from '../../components/table/table-header/interface'; +import { SelectedSortType } from '../../components/table/table-header/interface'; -export type OrderByFields = keyof People_Order_By | 'fullname' | 'company_name'; - -export type PeopleSelectedSortType = SelectedSortType<OrderByFields>; - -const mapOrder = (order: 'asc' | 'desc'): Order_By => { - return order === 'asc' ? Order_By.Asc : Order_By.Desc; -}; - -export const reduceFiltersToWhere = <T>( - filters: Array<SelectedFilterType<T>>, -): T => { - const where = filters.reduce((acc, filter) => { - const { where } = filter; - return { ...acc, ...where }; - }, {} as T); - return where; -}; - -export const reduceSortsToOrderBy = ( - sorts: Array<PeopleSelectedSortType>, -): People_Order_By[] => { - const mappedSorts = sorts.reduce((acc, sort) => { - const id = sort.key; - const order = mapOrder(sort.order); - if (id === 'fullname') { - acc['firstname'] = order; - acc['lastname'] = order; - } else if (id === 'company_name') { - acc['company'] = { name: order }; - } else { - acc[id] = order; - } - return acc; - }, {} as People_Order_By); - return [mappedSorts]; -}; +export type PeopleSelectedSortType = SelectedSortType<People_Order_By>; export const GET_PEOPLE = gql` query GetPeople(