ui icon indicating copy to clipboard operation
ui copied to clipboard

How to display data not found or loading in the center of TableBody in Table?

Open alamenai opened this issue 1 year ago • 1 comments
trafficstars

Hi guys,

I have created a DataTable component using Table component. However, I'm struggling to displaying loading state in the center of the TableBody.

Code


"use client"

import { useSelector } from "react-redux"

import { RootState } from "@/redux/store"

import {
  Table,
  TableBody,
  TableCaption,
  TableCell,
  TableFooter,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"

import { Roof } from "../state/slice"

export const DataTable = () => {
  const selectedRoofs: Roof[] = useSelector((state: RootState) => state.customInstallation.selectedRoofs)

  const isLoading: boolean = useSelector((state: RootState) => state.customInstallation.isLoadingImage)

  return (
    <Table className='w-full max-w-5xl mx-auto'>
      <TableHeader>
        <TableRow>
          <TableHead className='text-center'>Dachflächen</TableHead>
          <TableHead className='text-center'>Module</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {isLoading ? (
          <p className='min-h-full bg-red-100'>Laoding...</p>
        ) : (
          selectedRoofs.map((roof) => (
            <TableRow key={roof.roof_id} className='text-center'>
              <TableCell className='font-semibold text-xl'>{roof.roof_id}</TableCell>
              <TableCell className='text-lg'>
                {roof.additionalPanels !== undefined ? roof.additionalPanels : roof.default_additional_panels}
              </TableCell>
            </TableRow>
          ))
        )}
      </TableBody>
    </Table>
  )
}

As you see above the loading appeared in the first cell in the TableRow:

image

alamenai avatar Jan 23 '24 19:01 alamenai

Hi,

You can use <TableRow /> and <TableCell /> components like this:

<TableRow>
  <TableCell
    colSpan={columns.length}
    className='h-24 text-center'
  >
    Loading…
  </TableCell>
</TableRow>

The main idea is that you need to span <TableCell /> across all columns using colSpan={columns.length} prop.

So your final code should look like this:


"use client"

import { useSelector } from "react-redux"

import { RootState } from "@/redux/store"

import {
  Table,
  TableBody,
  TableCaption,
  TableCell,
  TableFooter,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"

import { Roof } from "../state/slice"

export const DataTable = () => {
  const selectedRoofs: Roof[] = useSelector((state: RootState) => state.customInstallation.selectedRoofs)

  const isLoading: boolean = useSelector((state: RootState) => state.customInstallation.isLoadingImage)

  return (
    <Table className='w-full max-w-5xl mx-auto'>
      <TableHeader>
        <TableRow>
          <TableHead className='text-center'>Dachflächen</TableHead>
          <TableHead className='text-center'>Module</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {isLoading ? (
          <TableRow>
            <TableCell
              colSpan={columns.length}
              className='h-24 text-center'
            >
              Loading…
            </TableCell>
          </TableRow>
        ) : (
          selectedRoofs.map((roof) => (
            <TableRow key={roof.roof_id} className='text-center'>
              <TableCell className='font-semibold text-xl'>{roof.roof_id}</TableCell>
              <TableCell className='text-lg'>
                {roof.additionalPanels !== undefined ? roof.additionalPanels : roof.default_additional_panels}
              </TableCell>
            </TableRow>
          ))
        )}
      </TableBody>
    </Table>
  )
}

iTsygancov avatar Jan 24 '24 10:01 iTsygancov

This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.

shadcn avatar Feb 15 '24 23:02 shadcn