update
This commit is contained in:
16
apps/admin.saladeaula.digital/app/components/abbr.tsx
Normal file
16
apps/admin.saladeaula.digital/app/components/abbr.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
type AbbrProps = {
|
||||||
|
children: string
|
||||||
|
maxLen?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Abbr({ children, maxLen = 30, ...props }: AbbrProps) {
|
||||||
|
if (children.length <= maxLen) {
|
||||||
|
return <abbr {...props}>{children}</abbr>
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<abbr title={children} {...props}>
|
||||||
|
{children.substring(0, maxLen).concat('...')}
|
||||||
|
</abbr>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -11,14 +11,15 @@ import { cn } from '@repo/ui/lib/utils'
|
|||||||
interface DataTableColumnHeaderProps<TData, TValue>
|
interface DataTableColumnHeaderProps<TData, TValue>
|
||||||
extends React.HTMLAttributes<HTMLDivElement> {
|
extends React.HTMLAttributes<HTMLDivElement> {
|
||||||
column: Column<TData, TValue>
|
column: Column<TData, TValue>
|
||||||
title: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DataTableColumnHeader<TData, TValue>({
|
export function DataTableColumnHeader<TData, TValue>({
|
||||||
column,
|
column,
|
||||||
title,
|
|
||||||
className
|
className
|
||||||
}: DataTableColumnHeaderProps<TData, TValue>) {
|
}: DataTableColumnHeaderProps<TData, TValue>) {
|
||||||
|
// @ts-ignore
|
||||||
|
const title = column.columnDef?.meta?.title ?? column.id
|
||||||
|
|
||||||
if (!column.getCanSort()) {
|
if (!column.getCanSort()) {
|
||||||
return <div className={cn(className)}>{title}</div>
|
return <div className={cn(className)}>{title}</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,13 @@ import {
|
|||||||
type Table,
|
type Table,
|
||||||
type VisibilityState
|
type VisibilityState
|
||||||
} from '@tanstack/react-table'
|
} from '@tanstack/react-table'
|
||||||
import { createContext, useEffect, useState, type ReactNode } from 'react'
|
import {
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
type ReactNode
|
||||||
|
} from 'react'
|
||||||
import { useSearchParams } from 'react-router'
|
import { useSearchParams } from 'react-router'
|
||||||
|
|
||||||
import { Card, CardContent } from '@repo/ui/components/ui/card'
|
import { Card, CardContent } from '@repo/ui/components/ui/card'
|
||||||
@@ -36,7 +42,17 @@ interface DataTableProps<TData, TValue> {
|
|||||||
hiddenColumn?: string[]
|
hiddenColumn?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TableContext = createContext<{ table: Table<any> } | null>(null)
|
const TableContext = createContext<{ table: Table<any> } | null>(null)
|
||||||
|
|
||||||
|
export function useDataTable<TData>() {
|
||||||
|
const ctx = useContext(TableContext) as { table: Table<TData> } | null
|
||||||
|
|
||||||
|
if (!ctx) {
|
||||||
|
throw new Error('TableContext is null')
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
export function DataTable<TData, TValue>({
|
export function DataTable<TData, TValue>({
|
||||||
children,
|
children,
|
||||||
@@ -68,6 +84,9 @@ export function DataTable<TData, TValue>({
|
|||||||
const newState =
|
const newState =
|
||||||
typeof updater === 'function' ? updater({ pageIndex, pageSize }) : updater
|
typeof updater === 'function' ? updater({ pageIndex, pageSize }) : updater
|
||||||
|
|
||||||
|
onRowSelectionChange?.([])
|
||||||
|
setRowSelection({})
|
||||||
|
|
||||||
setSearchParams((searchParams) => {
|
setSearchParams((searchParams) => {
|
||||||
searchParams.set('p', newState?.pageIndex.toString())
|
searchParams.set('p', newState?.pageIndex.toString())
|
||||||
searchParams.set('perPage', newState?.pageSize.toString())
|
searchParams.set('perPage', newState?.pageSize.toString())
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useContext } from 'react'
|
|
||||||
|
|
||||||
import { type Table } from '@tanstack/react-table'
|
|
||||||
import { Columns2Icon } from 'lucide-react'
|
import { Columns2Icon } from 'lucide-react'
|
||||||
|
|
||||||
import { Button } from '@repo/ui/components/ui/button'
|
import { Button } from '@repo/ui/components/ui/button'
|
||||||
@@ -13,20 +10,14 @@ import {
|
|||||||
DropdownMenuTrigger
|
DropdownMenuTrigger
|
||||||
} from '@repo/ui/components/ui/dropdown-menu'
|
} from '@repo/ui/components/ui/dropdown-menu'
|
||||||
import { cn } from '@repo/ui/lib/utils'
|
import { cn } from '@repo/ui/lib/utils'
|
||||||
import { TableContext } from './data-table'
|
import { useDataTable } from './data-table'
|
||||||
|
|
||||||
export function DataTableViewOptions<TData>({
|
export function DataTableViewOptions<TData>({
|
||||||
className
|
className
|
||||||
}: {
|
}: {
|
||||||
className: string
|
className: string
|
||||||
}) {
|
}) {
|
||||||
const ctx = useContext(TableContext) as { table: Table<TData> } | null
|
const { table } = useDataTable()
|
||||||
|
|
||||||
if (!ctx) {
|
|
||||||
throw new Error('TableContext is null')
|
|
||||||
}
|
|
||||||
|
|
||||||
const { table } = ctx
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
@@ -43,13 +34,16 @@ export function DataTableViewOptions<TData>({
|
|||||||
typeof column.accessorFn !== 'undefined' && column.getCanHide()
|
typeof column.accessorFn !== 'undefined' && column.getCanHide()
|
||||||
)
|
)
|
||||||
.map((column) => {
|
.map((column) => {
|
||||||
|
// @ts-ignore
|
||||||
|
const title = column.columnDef?.meta?.title ?? column.id
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenuCheckboxItem
|
<DropdownMenuCheckboxItem
|
||||||
key={column.id}
|
key={column.id}
|
||||||
checked={column.getIsVisible()}
|
checked={column.getIsVisible()}
|
||||||
onCheckedChange={(value) => column.toggleVisibility(!!value)}
|
onCheckedChange={(value) => column.toggleVisibility(!!value)}
|
||||||
>
|
>
|
||||||
{column.columnDef?.meta?.title ?? column.id}
|
{title}
|
||||||
</DropdownMenuCheckboxItem>
|
</DropdownMenuCheckboxItem>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { Checkbox } from '@repo/ui/components/ui/checkbox'
|
|||||||
import { Progress } from '@repo/ui/components/ui/progress'
|
import { Progress } from '@repo/ui/components/ui/progress'
|
||||||
import { cn, initials } from '@repo/ui/lib/utils'
|
import { cn, initials } from '@repo/ui/lib/utils'
|
||||||
|
|
||||||
|
import { Abbr } from '@/components/abbr'
|
||||||
import { DataTableColumnHeader } from '@/components/data-table/column-header'
|
import { DataTableColumnHeader } from '@/components/data-table/column-header'
|
||||||
import { labels, statuses } from './data'
|
import { labels, statuses } from './data'
|
||||||
|
|
||||||
@@ -46,6 +47,7 @@ export const columns: ColumnDef<Enrollment>[] = [
|
|||||||
(table.getIsSomePageRowsSelected() && 'indeterminate')
|
(table.getIsSomePageRowsSelected() && 'indeterminate')
|
||||||
}
|
}
|
||||||
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
|
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
|
||||||
|
className="cursor-pointer"
|
||||||
aria-label="Selecionar tudo"
|
aria-label="Selecionar tudo"
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
@@ -54,6 +56,7 @@ export const columns: ColumnDef<Enrollment>[] = [
|
|||||||
checked={row.getIsSelected()}
|
checked={row.getIsSelected()}
|
||||||
disabled={!row.getCanSelect()}
|
disabled={!row.getCanSelect()}
|
||||||
onCheckedChange={(value) => row.toggleSelected(!!value)}
|
onCheckedChange={(value) => row.toggleSelected(!!value)}
|
||||||
|
className="cursor-pointer"
|
||||||
aria-label="Selecionar linha"
|
aria-label="Selecionar linha"
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
@@ -72,9 +75,11 @@ export const columns: ColumnDef<Enrollment>[] = [
|
|||||||
</Avatar>
|
</Avatar>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li className="font-bold truncate max-w-62">{user.name}</li>
|
<li className="font-bold">
|
||||||
<li className="text-muted-foreground text-sm truncate max-w-62">
|
<Abbr>{user.name}</Abbr>
|
||||||
{user.email}
|
</li>
|
||||||
|
<li className="text-muted-foreground text-sm">
|
||||||
|
<Abbr>{user.email}</Abbr>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -88,11 +93,7 @@ export const columns: ColumnDef<Enrollment>[] = [
|
|||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const { name } = row.getValue('course') as { name: string }
|
const { name } = row.getValue('course') as { name: string }
|
||||||
|
|
||||||
return (
|
return <Abbr>{name}</Abbr>
|
||||||
<abbr className="truncate max-w-62 block" title={name}>
|
|
||||||
{name}
|
|
||||||
</abbr>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -129,9 +130,7 @@ export const columns: ColumnDef<Enrollment>[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'created_at',
|
accessorKey: 'created_at',
|
||||||
header: ({ column }) => (
|
header: ({ column }) => <DataTableColumnHeader column={column} />,
|
||||||
<DataTableColumnHeader column={column} title="Cadastrado em" />
|
|
||||||
),
|
|
||||||
meta: { title: 'Cadastrado em' },
|
meta: { title: 'Cadastrado em' },
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
enableHiding: true,
|
enableHiding: true,
|
||||||
@@ -139,9 +138,7 @@ export const columns: ColumnDef<Enrollment>[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'started_at',
|
accessorKey: 'started_at',
|
||||||
header: ({ column }) => (
|
header: ({ column }) => <DataTableColumnHeader column={column} />,
|
||||||
<DataTableColumnHeader column={column} title="Iniciado em" />
|
|
||||||
),
|
|
||||||
meta: { title: 'Iniciado em' },
|
meta: { title: 'Iniciado em' },
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
enableHiding: true,
|
enableHiding: true,
|
||||||
@@ -149,9 +146,7 @@ export const columns: ColumnDef<Enrollment>[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'completed_at',
|
accessorKey: 'completed_at',
|
||||||
header: ({ column }) => (
|
header: ({ column }) => <DataTableColumnHeader column={column} />,
|
||||||
<DataTableColumnHeader column={column} title="Concluído em" />
|
|
||||||
),
|
|
||||||
meta: { title: 'Concluído em' },
|
meta: { title: 'Concluído em' },
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
enableHiding: true,
|
enableHiding: true,
|
||||||
@@ -159,9 +154,7 @@ export const columns: ColumnDef<Enrollment>[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'failed_at',
|
accessorKey: 'failed_at',
|
||||||
header: ({ column }) => (
|
header: ({ column }) => <DataTableColumnHeader column={column} />,
|
||||||
<DataTableColumnHeader column={column} title="Reprovado em" />
|
|
||||||
),
|
|
||||||
meta: { title: 'Reprovado em' },
|
meta: { title: 'Reprovado em' },
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
enableHiding: true,
|
enableHiding: true,
|
||||||
@@ -169,9 +162,7 @@ export const columns: ColumnDef<Enrollment>[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'canceled_at',
|
accessorKey: 'canceled_at',
|
||||||
header: ({ column }) => (
|
header: ({ column }) => <DataTableColumnHeader column={column} />,
|
||||||
<DataTableColumnHeader column={column} title="Cancelado em" />
|
|
||||||
),
|
|
||||||
meta: { title: 'Cancelado em' },
|
meta: { title: 'Cancelado em' },
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
enableHiding: true,
|
enableHiding: true,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { type ColumnDef } from '@tanstack/react-table'
|
|||||||
import { ArrowRight } from 'lucide-react'
|
import { ArrowRight } from 'lucide-react'
|
||||||
import { NavLink } from 'react-router'
|
import { NavLink } from 'react-router'
|
||||||
|
|
||||||
|
import { Abbr } from '@/components/abbr'
|
||||||
import { Avatar, AvatarFallback } from '@repo/ui/components/ui/avatar'
|
import { Avatar, AvatarFallback } from '@repo/ui/components/ui/avatar'
|
||||||
import { Button } from '@repo/ui/components/ui/button'
|
import { Button } from '@repo/ui/components/ui/button'
|
||||||
import { Spinner } from '@repo/ui/components/ui/spinner'
|
import { Spinner } from '@repo/ui/components/ui/spinner'
|
||||||
@@ -41,9 +42,11 @@ export const columns: ColumnDef<User>[] = [
|
|||||||
</Avatar>
|
</Avatar>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li className="font-bold truncate max-w-62">{name}</li>
|
<li className="font-bold">
|
||||||
<li className="text-muted-foreground text-sm truncate max-w-92">
|
<Abbr>{name}</Abbr>
|
||||||
{email}
|
</li>
|
||||||
|
<li className="text-muted-foreground text-sm">
|
||||||
|
<Abbr>{email}</Abbr>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user