Skip to content

Commit

Permalink
add sorting and filtering to commit tables @client
Browse files Browse the repository at this point in the history
  • Loading branch information
SantiagoJavierRubio committed Nov 30, 2023
1 parent aa42253 commit 8e6beae
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 5 deletions.
14 changes: 14 additions & 0 deletions apps/client/src/hooks/useDebounce.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useState, useEffect } from 'react'

export default function useDebounce<T>(value: T, delay: number) {
const [debouncedValue, setDebouncedValue] = useState<T>(value)
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value)
}, delay)
return () => {
clearTimeout(handler)
}
}, [value, delay])
return debouncedValue
}
58 changes: 53 additions & 5 deletions apps/client/src/pages/Home/CommitTable/CommitTable.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,73 @@
/* eslint-disable no-console */
import { ChangeEvent, useState } from 'react'
import { CommitListElement } from 'types'
import { createColumnHelper, useReactTable, getCoreRowModel, flexRender, getPaginationRowModel } from '@tanstack/react-table'
import {
createColumnHelper,
useReactTable,
getCoreRowModel,
flexRender,
getPaginationRowModel,
getSortedRowModel,
getFilteredRowModel,
type SortingState
} from '@tanstack/react-table'

import useDebounce from '@/hooks/useDebounce'

const columnHelper = createColumnHelper<CommitListElement>()
const columns = [
columnHelper.accessor('sha', { header: () => <span>Id</span>, cell: props => <span>{props.getValue().substring(0, 7)}</span> }),
columnHelper.accessor('commit.author.email', { id: 'author', header: () => <span>Author</span>, cell: props => <span>{props.row.original.commit.author.name}</span> }),
columnHelper.display({ id: 'message', header: () => <span>Message</span>, cell: props => <span>{props.row.original.commit.message}</span> }),
columnHelper.group({
id: 'author',
columns: [
columnHelper.display({ id: 'avatar', cell: props => <img src={props.row.original.author.avatar_url} alt={`${props.row.original.commit.author.name}'s avatar`} className='aspect-square rounded-full w-6'/> }),
columnHelper.accessor('commit.author.name', { id: 'name', header: () => <span>Author</span>, cell: props => <span>{props.getValue()}</span> }),
columnHelper.accessor('commit.author.email', { id: 'email', header: () => null, cell: () => null })
]
}),
columnHelper.accessor('commit.message', { id: 'message', enableSorting: false, header: () => <span>Message</span>, cell: props => <span>{props.row.original.commit.message}</span> }),
columnHelper.accessor('commit.author.date', { id: 'date', header: () => <span>Date</span>, cell: props => <span>{new Date(props.getValue()).toLocaleDateString()}</span> })
]
export default function CommitTable({ commits }: { commits: CommitListElement[] }) {
const table = useReactTable({ data: commits, columns, getCoreRowModel: getCoreRowModel(), getPaginationRowModel: getPaginationRowModel() })
const [sorting, setSorting] = useState<SortingState>([])
const [filtering, setFiltering] = useState<string>('')

const filter = useDebounce(filtering, 250)

const table = useReactTable({
data: commits,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
state: {
sorting,
globalFilter: filter
},
onSortingChange: setSorting,
onGlobalFilterChange: setFiltering
})

const handleSortInput = (e: ChangeEvent<HTMLInputElement>) => {
setFiltering(e.target.value)
}

return (
<>
<input type="text" name="filter" onChange={handleSortInput} value={filtering} />
<p>{table.getState().pagination.pageIndex + 1} of {table.getPageCount()}</p>
<table>
<thead>
{table.getHeaderGroups().map(hGroup => (
<tr key={hGroup.id}>
{hGroup.headers.map(header => (
<th key={header.id}>
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
{header.isPlaceholder ? null : (
<div className={header.column.getCanSort() ? 'cursor-pointer select-none' : 'cursor-default'} onClick={header.column.getToggleSortingHandler()}>
{flexRender(header.column.columnDef.header, header.getContext())}
</div>
)}
</th>
))}
</tr>
Expand Down

0 comments on commit 8e6beae

Please sign in to comment.