add columns
This commit is contained in:
@@ -26,9 +26,9 @@ export function DataTableColumnHeader<TData, TValue>({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="link"
|
||||||
size="sm"
|
size="sm"
|
||||||
className={cn('-ml-3 cursor-pointer', className)}
|
className={cn('-ml-3 cursor-pointer text-inherit h-auto', className)}
|
||||||
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
|
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
|
||||||
>
|
>
|
||||||
<span>{title}</span>
|
<span>{title}</span>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
useContext,
|
useContext,
|
||||||
useEffect,
|
useEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
type ReactNode
|
type ReactNode
|
||||||
} from 'react'
|
} from 'react'
|
||||||
@@ -43,7 +44,7 @@ interface DataTableProps<TData, TValue> {
|
|||||||
sort: SortingState
|
sort: SortingState
|
||||||
pageSize: number
|
pageSize: number
|
||||||
rowCount: number
|
rowCount: number
|
||||||
columnInvisibilityInit?: string[]
|
columnVisibilityInit?: VisibilityState
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TableContextProps<TData> {
|
interface TableContextProps<TData> {
|
||||||
@@ -71,21 +72,33 @@ export function DataTable<TData, TValue>({
|
|||||||
pageSize,
|
pageSize,
|
||||||
rowCount,
|
rowCount,
|
||||||
setSelectedRows,
|
setSelectedRows,
|
||||||
columnInvisibilityInit = []
|
columnVisibilityInit = {}
|
||||||
}: DataTableProps<TData, TValue>) {
|
}: DataTableProps<TData, TValue>) {
|
||||||
const [dataTable, setDataTable] = useState<TData[]>(data)
|
const [dataTable, setDataTable] = useState<TData[]>(data)
|
||||||
const columnInvisibility = useMemo<VisibilityState>(
|
|
||||||
() =>
|
|
||||||
Object.fromEntries(
|
|
||||||
columnInvisibilityInit.map((column) => [column, false])
|
|
||||||
),
|
|
||||||
[columnInvisibilityInit]
|
|
||||||
)
|
|
||||||
const [searchParams, setSearchParams] = useSearchParams()
|
const [searchParams, setSearchParams] = useSearchParams()
|
||||||
const [columnVisibility, setColumnVisibility] =
|
|
||||||
useState<VisibilityState>(columnInvisibility)
|
|
||||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({})
|
const [rowSelection, setRowSelection] = useState<RowSelectionState>({})
|
||||||
|
|
||||||
|
const columnVisibilityInit_ = useMemo<VisibilityState>(() => {
|
||||||
|
const columns = searchParams.get('columns')
|
||||||
|
|
||||||
|
if (columns === null) {
|
||||||
|
return columnVisibilityInit
|
||||||
|
}
|
||||||
|
|
||||||
|
const columnVisibility = columns ? columns.split(',') : []
|
||||||
|
return Object.keys(columnVisibilityInit).reduce<VisibilityState>(
|
||||||
|
(acc, col) => ({
|
||||||
|
...acc,
|
||||||
|
[col]: columnVisibility.includes(col)
|
||||||
|
}),
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const [columnVisibility, setColumnVisibility_] = useState<VisibilityState>(
|
||||||
|
columnVisibilityInit_
|
||||||
|
)
|
||||||
|
|
||||||
const sorting = useMemo(() => {
|
const sorting = useMemo(() => {
|
||||||
const sortParam = searchParams.get('sort')
|
const sortParam = searchParams.get('sort')
|
||||||
|
|
||||||
@@ -110,6 +123,7 @@ export function DataTable<TData, TValue>({
|
|||||||
setSearchParams((prev) => {
|
setSearchParams((prev) => {
|
||||||
prev.set('p', newState?.pageIndex.toString())
|
prev.set('p', newState?.pageIndex.toString())
|
||||||
prev.set('perPage', newState?.pageSize.toString())
|
prev.set('perPage', newState?.pageSize.toString())
|
||||||
|
|
||||||
return prev
|
return prev
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -130,60 +144,67 @@ export function DataTable<TData, TValue>({
|
|||||||
} else {
|
} else {
|
||||||
prev.delete('sort')
|
prev.delete('sort')
|
||||||
}
|
}
|
||||||
|
|
||||||
return prev
|
return prev
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
[sorting, setSearchParams]
|
[sorting, setSearchParams]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const setColumnVisibility = useCallback(
|
||||||
|
(updater: any) => {
|
||||||
|
const newColumnVisibility =
|
||||||
|
typeof updater === 'function' ? updater(columnVisibility) : updater
|
||||||
|
|
||||||
|
setColumnVisibility_(newColumnVisibility)
|
||||||
|
|
||||||
|
setSearchParams((prev) => {
|
||||||
|
const columns = Object.entries(newColumnVisibility)
|
||||||
|
.filter(([_, visible]) => visible)
|
||||||
|
.map(([col, _]) => col)
|
||||||
|
|
||||||
|
if (columns.length > 0) {
|
||||||
|
prev.set('columns', columns.join(','))
|
||||||
|
} else {
|
||||||
|
prev.set('columns', '')
|
||||||
|
}
|
||||||
|
|
||||||
|
return prev
|
||||||
|
})
|
||||||
|
},
|
||||||
|
[setSearchParams, setColumnVisibility_]
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDataTable(data)
|
setDataTable(data)
|
||||||
}, [data])
|
}, [data])
|
||||||
|
|
||||||
const tableConfig = useMemo(
|
const getRowId = useCallback((row: any) => row.id, [])
|
||||||
() => ({
|
const removeRow = useCallback((rowId: string) => {
|
||||||
data: dataTable,
|
setDataTable((rows) => rows.filter((row: any) => row.id !== rowId))
|
||||||
columns,
|
}, [])
|
||||||
rowCount,
|
|
||||||
state: {
|
const table = useReactTable({
|
||||||
sorting,
|
data: dataTable,
|
||||||
rowSelection,
|
columns,
|
||||||
columnVisibility,
|
rowCount,
|
||||||
pagination: {
|
state: {
|
||||||
pageIndex,
|
|
||||||
pageSize
|
|
||||||
}
|
|
||||||
},
|
|
||||||
manualSorting: true,
|
|
||||||
manualPagination: true,
|
|
||||||
enableRowSelection: true,
|
|
||||||
getRowId: (row: any) => row.id,
|
|
||||||
getCoreRowModel: getCoreRowModel(),
|
|
||||||
onRowSelectionChange: setRowSelection,
|
|
||||||
onSortingChange: setSorting,
|
|
||||||
onColumnVisibilityChange: setColumnVisibility,
|
|
||||||
onPaginationChange: setPagination,
|
|
||||||
meta: {
|
|
||||||
removeRow: (rowId: string) => {
|
|
||||||
setDataTable((rows) => rows.filter((row: any) => row?.id !== rowId))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
[
|
|
||||||
dataTable,
|
|
||||||
columns,
|
|
||||||
rowCount,
|
|
||||||
sorting,
|
sorting,
|
||||||
rowSelection,
|
rowSelection,
|
||||||
columnVisibility,
|
columnVisibility,
|
||||||
setColumnVisibility,
|
pagination: { pageIndex, pageSize }
|
||||||
pageIndex,
|
},
|
||||||
pageSize,
|
manualSorting: true,
|
||||||
setSorting,
|
manualPagination: true,
|
||||||
setPagination
|
enableRowSelection: true,
|
||||||
]
|
getRowId,
|
||||||
)
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
onRowSelectionChange: setRowSelection,
|
||||||
const table = useReactTable(tableConfig)
|
onSortingChange: setSorting,
|
||||||
|
onColumnVisibilityChange: setColumnVisibility,
|
||||||
|
onPaginationChange: setPagination,
|
||||||
|
meta: { removeRow }
|
||||||
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!setSelectedRows) return
|
if (!setSelectedRows) return
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export function DataTableViewOptions<TData>({
|
|||||||
<DropdownMenuCheckboxItem
|
<DropdownMenuCheckboxItem
|
||||||
key={column.id}
|
key={column.id}
|
||||||
checked={column.getIsVisible()}
|
checked={column.getIsVisible()}
|
||||||
|
onSelect={(e) => e.preventDefault()}
|
||||||
onCheckedChange={(value) => column.toggleVisibility(!!value)}
|
onCheckedChange={(value) => column.toggleVisibility(!!value)}
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { isbot } from 'isbot'
|
import { isbot } from 'isbot'
|
||||||
import { renderToReadableStream } from 'react-dom/server'
|
import { renderToReadableStream } from 'react-dom/server'
|
||||||
import type { AppLoadContext, EntryContext } from 'react-router'
|
import type { AppLoadContext, EntryContext } from 'react-router'
|
||||||
import { ServerRouter } from 'react-router'
|
import { ServerRouter, type HandleErrorFunction } from 'react-router'
|
||||||
|
|
||||||
export default async function handleRequest(
|
export default async function handleRequest(
|
||||||
request: Request,
|
request: Request,
|
||||||
@@ -44,3 +44,10 @@ export default async function handleRequest(
|
|||||||
|
|
||||||
// https://reactrouter.com/how-to/suspense#timeouts
|
// https://reactrouter.com/how-to/suspense#timeouts
|
||||||
export const streamTimeout = 7_000
|
export const streamTimeout = 7_000
|
||||||
|
|
||||||
|
// https://reactrouter.com/how-to/error-reporting
|
||||||
|
export const handleError: HandleErrorFunction = (error, { request }) => {
|
||||||
|
if (!request.signal.aborted) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -107,12 +107,13 @@ export default function Route({ loaderData: { data } }) {
|
|||||||
pageSize={hitsPerPage}
|
pageSize={hitsPerPage}
|
||||||
setSelectedRows={setSelectedRows}
|
setSelectedRows={setSelectedRows}
|
||||||
rowCount={totalHits}
|
rowCount={totalHits}
|
||||||
hiddenColumn={[
|
columnVisibilityInit={{
|
||||||
'completed_at',
|
created_at: true,
|
||||||
'started_at',
|
completed_at: false,
|
||||||
'failed_at',
|
started_at: false,
|
||||||
'canceled_at'
|
failed_at: false,
|
||||||
]}
|
canceled_at: false
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex gap-2.5 mb-2.5">
|
<div className="flex gap-2.5 mb-2.5">
|
||||||
{selectedRows.length ? (
|
{selectedRows.length ? (
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ export async function action({ params, request, context }: Route.ActionArgs) {
|
|||||||
return { ok: true }
|
return { ok: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Route() {
|
export default function Route({}: Route.ComponentProps) {
|
||||||
const fetcher = useFetcher()
|
const fetcher = useFetcher()
|
||||||
const { activeWorkspace } = useWorksapce()
|
const { activeWorkspace } = useWorksapce()
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
@@ -143,7 +143,7 @@ export default function Route() {
|
|||||||
case 'UserConflictError':
|
case 'UserConflictError':
|
||||||
toast.error('O colaborador já foi vinculado anteriormente')
|
toast.error('O colaborador já foi vinculado anteriormente')
|
||||||
}
|
}
|
||||||
}, [fetcher.data])
|
}, [fetcher.data, reset])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (givenEmail) {
|
if (givenEmail) {
|
||||||
|
|||||||
Reference in New Issue
Block a user