Refactor/remove react table (#642)
* Refactored tables without tan stack * Fixed checkbox behavior with multiple handlers on click * Fixed hotkeys scope * Fix debounce in editable cells * Lowered coverage --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -4,8 +4,9 @@ import { IconList } from '@tabler/icons-react';
|
||||
import {
|
||||
CompaniesSelectedSortType,
|
||||
defaultOrderBy,
|
||||
useCompaniesQuery,
|
||||
} from '@/companies/services';
|
||||
import { companyColumns } from '@/companies/table/components/companyColumns';
|
||||
import { CompanyEntityTableData } from '@/companies/table/components/CompanyEntityTableData';
|
||||
import { reduceSortsToOrderBy } from '@/lib/filters-and-sorts/helpers';
|
||||
import { filtersScopedState } from '@/lib/filters-and-sorts/states/filtersScopedState';
|
||||
import { turnFilterIntoWhereClause } from '@/lib/filters-and-sorts/utils/turnFilterIntoWhereClause';
|
||||
@ -15,7 +16,6 @@ import { HooksEntityTable } from '@/ui/components/table/HooksEntityTable';
|
||||
import { TableContext } from '@/ui/tables/states/TableContext';
|
||||
import { CompanyOrderByWithRelationInput } from '~/generated/graphql';
|
||||
|
||||
import { useCompaniesColumns } from './companies-columns';
|
||||
import { companiesFilters } from './companies-filters';
|
||||
import { availableSorts } from './companies-sorts';
|
||||
|
||||
@ -30,27 +30,18 @@ export function CompanyTable() {
|
||||
const filters = useRecoilScopedValue(filtersScopedState, TableContext);
|
||||
|
||||
const whereFilters = useMemo(() => {
|
||||
if (!filters.length) return undefined;
|
||||
|
||||
return { AND: filters.map(turnFilterIntoWhereClause) };
|
||||
}, [filters]) as any;
|
||||
|
||||
const companiesColumns = useCompaniesColumns();
|
||||
|
||||
const { data } = useCompaniesQuery(orderBy, whereFilters);
|
||||
|
||||
const companies = data?.companies ?? [];
|
||||
|
||||
return (
|
||||
<>
|
||||
<CompanyEntityTableData orderBy={orderBy} whereFilters={whereFilters} />
|
||||
<HooksEntityTable
|
||||
numberOfColumns={companiesColumns.length}
|
||||
numberOfRows={companies.length}
|
||||
availableTableFilters={companiesFilters}
|
||||
numberOfColumns={companyColumns.length}
|
||||
availableFilters={companiesFilters}
|
||||
/>
|
||||
<EntityTable
|
||||
data={companies}
|
||||
columns={companiesColumns}
|
||||
columns={companyColumns}
|
||||
viewName="All Companies"
|
||||
viewIcon={<IconList size={16} />}
|
||||
availableSorts={availableSorts}
|
||||
|
||||
@ -1,28 +1,21 @@
|
||||
import { IconList } from '@tabler/icons-react';
|
||||
|
||||
import { companyColumns } from '@/companies/table/components/companyColumns';
|
||||
import { EntityTable } from '@/ui/components/table/EntityTable';
|
||||
import { HooksEntityTable } from '@/ui/components/table/HooksEntityTable';
|
||||
import { mockedCompaniesData } from '~/testing/mock-data/companies';
|
||||
|
||||
import { useCompaniesColumns } from './companies-columns';
|
||||
import { companiesFilters } from './companies-filters';
|
||||
import { availableSorts } from './companies-sorts';
|
||||
|
||||
export function CompanyTableMockMode() {
|
||||
const companiesColumns = useCompaniesColumns();
|
||||
|
||||
const companies = mockedCompaniesData;
|
||||
|
||||
return (
|
||||
<>
|
||||
<HooksEntityTable
|
||||
numberOfColumns={companiesColumns.length}
|
||||
numberOfRows={companies.length}
|
||||
availableTableFilters={companiesFilters}
|
||||
numberOfColumns={companyColumns.length}
|
||||
availableFilters={companiesFilters}
|
||||
/>
|
||||
<EntityTable
|
||||
data={companies}
|
||||
columns={companiesColumns}
|
||||
columns={companyColumns}
|
||||
viewName="All Companies"
|
||||
viewIcon={<IconList size={16} />}
|
||||
availableSorts={availableSorts}
|
||||
|
||||
@ -31,12 +31,6 @@ export const SortByName: Story = {
|
||||
|
||||
expect(await canvas.findByText('Airbnb')).toBeInTheDocument();
|
||||
|
||||
expect(
|
||||
(await canvas.findAllByRole('checkbox')).map((item) => {
|
||||
return item.getAttribute('id');
|
||||
})[1],
|
||||
).toStrictEqual('checkbox-selected-89bb825c-171e-4bcc-9cf7-43448d6fb278');
|
||||
|
||||
const cancelButton = canvas.getByText('Cancel');
|
||||
await userEvent.click(cancelButton);
|
||||
|
||||
|
||||
@ -1,150 +0,0 @@
|
||||
import { useMemo } from 'react';
|
||||
import { createColumnHelper } from '@tanstack/react-table';
|
||||
|
||||
import { CompanyAccountOwnerCell } from '@/companies/components/CompanyAccountOwnerCell';
|
||||
import { CompanyEditableNameChipCell } from '@/companies/components/CompanyEditableNameCell';
|
||||
import { EditableCellDate } from '@/ui/components/editable-cell/types/EditableCellDate';
|
||||
import { EditableCellText } from '@/ui/components/editable-cell/types/EditableCellText';
|
||||
import { ColumnHead } from '@/ui/components/table/ColumnHead';
|
||||
import {
|
||||
IconBuildingSkyscraper,
|
||||
IconCalendarEvent,
|
||||
IconLink,
|
||||
IconMap,
|
||||
IconUser,
|
||||
IconUsers,
|
||||
} from '@/ui/icons/index';
|
||||
import { getCheckBoxColumn } from '@/ui/tables/utils/getCheckBoxColumn';
|
||||
import {
|
||||
GetCompaniesQuery,
|
||||
useUpdateCompanyMutation,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
const columnHelper = createColumnHelper<GetCompaniesQuery['companies'][0]>();
|
||||
|
||||
export const useCompaniesColumns = () => {
|
||||
const [updateCompany] = useUpdateCompanyMutation();
|
||||
return useMemo(() => {
|
||||
return [
|
||||
getCheckBoxColumn(),
|
||||
columnHelper.accessor('name', {
|
||||
header: () => (
|
||||
<ColumnHead
|
||||
viewName="Name"
|
||||
viewIcon={<IconBuildingSkyscraper size={16} />}
|
||||
/>
|
||||
),
|
||||
cell: (props) => (
|
||||
<CompanyEditableNameChipCell company={props.row.original} />
|
||||
),
|
||||
size: 180,
|
||||
}),
|
||||
columnHelper.accessor('domainName', {
|
||||
header: () => (
|
||||
<ColumnHead viewName="URL" viewIcon={<IconLink size={16} />} />
|
||||
),
|
||||
cell: (props) => (
|
||||
<EditableCellText
|
||||
value={props.row.original.domainName || ''}
|
||||
placeholder="Domain name"
|
||||
onChange={(value) => {
|
||||
const company = { ...props.row.original };
|
||||
company.domainName = value;
|
||||
updateCompany({
|
||||
variables: {
|
||||
...company,
|
||||
accountOwnerId: company.accountOwner?.id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
),
|
||||
size: 100,
|
||||
}),
|
||||
columnHelper.accessor('employees', {
|
||||
header: () => (
|
||||
<ColumnHead viewName="Employees" viewIcon={<IconUsers size={16} />} />
|
||||
),
|
||||
cell: (props) => (
|
||||
<EditableCellText
|
||||
value={props.row.original.employees?.toString() || ''}
|
||||
placeholder="Employees"
|
||||
onChange={(value) => {
|
||||
const company = { ...props.row.original };
|
||||
|
||||
updateCompany({
|
||||
variables: {
|
||||
...company,
|
||||
employees: value === '' ? null : Number(value),
|
||||
accountOwnerId: company.accountOwner?.id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
),
|
||||
size: 150,
|
||||
}),
|
||||
columnHelper.accessor('address', {
|
||||
header: () => (
|
||||
<ColumnHead viewName="Address" viewIcon={<IconMap size={16} />} />
|
||||
),
|
||||
cell: (props) => (
|
||||
<EditableCellText
|
||||
value={props.row.original.address || ''}
|
||||
placeholder="Address"
|
||||
onChange={(value) => {
|
||||
const company = { ...props.row.original };
|
||||
company.address = value;
|
||||
updateCompany({
|
||||
variables: {
|
||||
...company,
|
||||
accountOwnerId: company.accountOwner?.id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
),
|
||||
size: 170,
|
||||
}),
|
||||
columnHelper.accessor('createdAt', {
|
||||
header: () => (
|
||||
<ColumnHead
|
||||
viewName="Creation"
|
||||
viewIcon={<IconCalendarEvent size={16} />}
|
||||
/>
|
||||
),
|
||||
cell: (props) => (
|
||||
<EditableCellDate
|
||||
value={
|
||||
props.row.original.createdAt
|
||||
? new Date(props.row.original.createdAt)
|
||||
: new Date()
|
||||
}
|
||||
onChange={(value: Date) => {
|
||||
const company = { ...props.row.original };
|
||||
company.createdAt = value.toISOString();
|
||||
updateCompany({
|
||||
variables: {
|
||||
...company,
|
||||
accountOwnerId: company.accountOwner?.id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
),
|
||||
size: 150,
|
||||
}),
|
||||
columnHelper.accessor('accountOwner', {
|
||||
header: () => (
|
||||
<ColumnHead
|
||||
viewName="Account owner"
|
||||
viewIcon={<IconUser size={16} />}
|
||||
/>
|
||||
),
|
||||
cell: (props) => (
|
||||
<CompanyAccountOwnerCell company={props.row.original} />
|
||||
),
|
||||
}),
|
||||
];
|
||||
}, [updateCompany]);
|
||||
};
|
||||
@ -13,30 +13,25 @@ export const availableSorts = [
|
||||
key: 'name',
|
||||
label: 'Name',
|
||||
icon: <IconBuildingSkyscraper size={16} />,
|
||||
_type: 'default_sort',
|
||||
},
|
||||
{
|
||||
key: 'employees',
|
||||
label: 'Employees',
|
||||
icon: <IconUsers size={16} />,
|
||||
_type: 'default_sort',
|
||||
},
|
||||
{
|
||||
key: 'domainName',
|
||||
label: 'Url',
|
||||
icon: <IconLink size={16} />,
|
||||
_type: 'default_sort',
|
||||
},
|
||||
{
|
||||
key: 'address',
|
||||
label: 'Address',
|
||||
icon: <IconMap size={16} />,
|
||||
_type: 'default_sort',
|
||||
},
|
||||
{
|
||||
key: 'createdAt',
|
||||
label: 'Creation',
|
||||
icon: <IconCalendarEvent size={16} />,
|
||||
_type: 'default_sort',
|
||||
},
|
||||
] satisfies Array<SortType<Companies_Order_By>>;
|
||||
|
||||
Reference in New Issue
Block a user