Skip to content

Commit

Permalink
Separate cells, headers and table into component files
Browse files Browse the repository at this point in the history
  • Loading branch information
tomtitherington committed Nov 5, 2023
1 parent 1ce8672 commit acbf546
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 138 deletions.
137 changes: 0 additions & 137 deletions frontend/src/features/people/components/Table.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion frontend/src/features/people/components/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default as Table } from './Table';
export { default as Table } from './table';
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Cell } from '@tanstack/react-table';
import { ReactNode } from 'react';

interface EditableCellProps<TData, TValue> {
cell: Cell<TData, TValue>;
value: unknown;
}

const EditableCell = <TData, TValue>({ cell, value }: EditableCellProps<TData, TValue>) => {
return (
<div
className="td p-2 border-r border-crumpet-light-200 text-oxford
text-sm whitespace-nowrap overflow-hidden"
key={cell.id}
style={{
width: cell.column.getSize(),
}}>
{value as ReactNode}
</div>
);
};

export default EditableCell;
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Header, flexRender } from '@tanstack/react-table';

interface PropertyHeaderProps<TData, TValue> {
header: Header<TData, TValue>;
value: string;
}

const PropertyHeader = <TData, TValue>({ header, value }: PropertyHeaderProps<TData, TValue>) => {
return (
<div
className="th flex justify-between items-center p-2 border-r border-crumpet-light-200
text-grey-700 text-left text-sm font-medium whitespace-nowrap overflow-hidden"
key={header.id}
style={{
width: header.getSize(),
position: 'relative',
}}>
{value}
{/* {header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())} */}
<div
{...{
onMouseDown: header.getResizeHandler(),
onTouchStart: header.getResizeHandler(),
}}
className={`resizer h-full w-1 cursor-col-resize select-none hover:bg-crumpet-yellow-500
${header.column.getIsResizing() ? 'bg-crumpet-yellow-500' : ''} `}
style={{
position: 'absolute',
right: 0,
top: 0,
}}
/>
</div>
);
};

export default PropertyHeader;
109 changes: 109 additions & 0 deletions frontend/src/features/people/components/table/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import {
ColumnDef,
createColumnHelper,
flexRender,
getCoreRowModel,
useReactTable,
} from '@tanstack/react-table';
import { HTMLProps, useEffect, useMemo, useRef, useState } from 'react';
import PropertyHeader from './headers/PropertyHeader';
import { MdAdd } from 'react-icons/md';
import EditableCell from './cells/EditableCell';
import { IndeterminateCheckbox } from 'components';

const Table = ({ data, columnJson }: { data: any[]; columnJson: any[] }) => {
// Convert the structure to column definitions for TanStack Table
const createColumns = (columnStructure: any[]): ColumnDef<unknown>[] => {
const columnHelper = createColumnHelper<unknown>();
const userColumns = columnStructure.map(column => {
return columnHelper.accessor(column.accessor, {
header: ({ header }) => <PropertyHeader header={header} value={column.header} />,
cell: info => <EditableCell cell={info.cell} value={info.getValue()} />,
size: column.size,
});
});
return [
{
id: 'select',
header: ({ table }) => (
<div className="flex items-center justify-center p-2 border-r border-crumpet-light-200">
<IndeterminateCheckbox
{...{
checked: table.getIsAllRowsSelected(),
indeterminate: table.getIsSomeRowsSelected(),
onChange: table.getToggleAllRowsSelectedHandler(),
}}
/>
</div>
),
cell: ({ row }) => (
<div className="flex items-center justify-center p-2 border-r border-crumpet-light-200">
<IndeterminateCheckbox
{...{
checked: row.getIsSelected(),
disabled: !row.getCanSelect(),
indeterminate: row.getIsSomeSelected(),
onChange: row.getToggleSelectedHandler(),
}}
/>
</div>
),
size: 48,
maxSize: 48,
minSize: 48,
},
...userColumns,
{
id: 'add_column',
header: ({ table }) => (
<div className="flex items-center p-2">
<MdAdd className="text-center text-base text-grey-700" />{' '}
</div>
),
cell: ({ row }) => <div></div>,
},
];
};

const columns = useMemo(() => createColumns(columnJson), [columnJson]);
const [rowSelection, setRowSelection] = useState({});

const tableInstance = useReactTable({
data,
columns,
state: {
rowSelection,
},
enableRowSelection: true,
onRowSelectionChange: setRowSelection,
columnResizeMode: 'onChange',
getCoreRowModel: getCoreRowModel(),
});

return (
<div className="relative overflow-x-auto">
<div className="thead border-b border-t border-crumpet-light-200">
{tableInstance.getHeaderGroups().map(headerGroup => (
<div className="tr flex" key={headerGroup.id}>
{headerGroup.headers.map(header =>
header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext()),
)}
</div>
))}
</div>
<div className="tbody bg-white">
{tableInstance.getRowModel().rows.map(row => (
<div className="tr flex border-b border-crumpet-light-200" key={row.id}>
{row
.getVisibleCells()
.map(cell => flexRender(cell.column.columnDef.cell, cell.getContext()))}
</div>
))}
</div>
</div>
);
};

export default Table;
14 changes: 14 additions & 0 deletions frontend/src/features/people/pages/People.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useState } from 'react';
import { Table } from '../components';

const People = () => {
Expand All @@ -15,6 +16,19 @@ const People = () => {
// ... more columns
];

// Using state to dynamically manage columns
const [columns, setColumns] = useState(columnJson);

// Handler to add a new column
const handleAddColumn = () => {
// Example of a new column. You might want to make this more dynamic.
const newColumn = {
accessor: `newColumn${columns.length}`, // Ensure the accessor is unique
header: `New Column ${columns.length}`,
};
setColumns(prevColumns => [...prevColumns, newColumn]);
};

return (
<div className="w-full h-full container px-6 py-8">
<span>People</span>
Expand Down

0 comments on commit acbf546

Please sign in to comment.