0

I have a Mantine React Table containing some loaded in data and I am trying to apply dynamic routing to the first column of the data, such that every value links to a different URL. Basically to '/test/{value}', where value are the values inside the first column. I would like to use the useRouter hook from nextJS to achieve this.

A snippet of my code detailing the Mantine React Table:

const RepoTable = () => {
  const tableContainerRef = useRef<HTMLDivElement>(null); //we can get access to the underlying TableContainer element and react to its scroll events
  const rowVirtualizerInstanceRef =
    useRef<MRT_Virtualizer<HTMLDivElement, HTMLTableRowElement>>(null); //we can get access to the underlying Virtualizer instance and call its scrollToIndex method

  const [columnFilters, setColumnFilters] = useState<MRT_ColumnFiltersState>(
    PerformSearchFunction()
  );
  const [globalFilter, setGlobalFilter] = useState<string>();
  const [sorting, setSorting] = useState<MRT_SortingState>([]);
  const [expanded, setExpanded] = useState<MRT_ExpandedState>({});

  useEffect(() => {
    console.log(expanded);
  }, [expanded]);

  const { data, fetchNextPage, isError, isFetching, isLoading } = useRepository(
    20,
    columnFilters,
    globalFilter!,
    sorting
  );

  //we must flatten the array of arrays from the useInfiniteQuery hook
  const flatData = useMemo(
    () => data?.pages?.flatMap((page) => page.data) ?? [],
    [data]
  );

  const columns = useMemo<MRT_ColumnDef<Repository>[]>(
    () => [
      {
        accessorKey: "PONUM",
        header: "PO Number",
      },
      {
        accessorKey: "DocTotalOrder",
        header: "Total PO Cost",
      }
    ],
    []
  );

  const handleColumnFiltersChange = (
    updater: MRT_Updater<MRT_ColumnFiltersState>
  ) => {
    setColumnFilters((prevState) =>
      updater instanceof Function ? updater(prevState) : updater
    );
    table.toggleAllRowsExpanded(columnFilters.length != 0);
  };

  const table = useMantineReactTable({
    columns,
    data: flatData,
    enableColumnFilterModes: true,
    enablePagination: false,
    enableRowNumbers: true,
    enableColumnResizing: true,
    enablePinning: true,
    // enableColumnVirtualization: true,
    // enableRowVirtualization: true, //optional, but recommended if it is likely going to be more than 100 rows
    manualFiltering: true,
    manualSorting: true,
    initialState: { showColumnFilters: true },
    mantineTableContainerProps: {
      ref: tableContainerRef, //get access to the table container element
      sx: { maxHeight: "700px" }, //give the table a max height
      onScroll: (
        event: UIEvent<HTMLDivElement> //add an event listener to the table container element
      ) => fetchMoreOnBottomReached(event.target as HTMLDivElement),
    },
    mantineToolbarAlertBannerProps: {
      color: "red",
      children: "Error loading data",
    },
    onColumnFiltersChange: handleColumnFiltersChange,
    onGlobalFilterChange: setGlobalFilter,
    onSortingChange: setSorting,
    renderBottomToolbarCustomActions: () => (
      <Text>
        Fetched {totalFetched} of {totalCount} total rows.
      </Text>
    ),
    state: {
      columnFilters,
      globalFilter,
      isLoading: isLoading,
      showAlertBanner: isError,
      showProgressBars: isFetching,
      sorting,
    },
    rowVirtualizerInstanceRef, //get access to the virtualizer instance
    // rowVirtualizerProps: { overscan: 5 }, //optionally customize the row virtualizer
    // columnVirtualizerProps: { overscan: 5 },
  });

  return (
    <MantineReactTable table={table} />
    // <></>
  );
};

Here I would like to apply dynamic routing to the column PONUM. I have no idea how to do this, however. The data is loaded in using a REST API that is connected to my backend using FastAPI. flatData is essentially an array containing all the data, so an array of arrays.

The way Mantine Table React takes the data makes it hard for me to consider how I would be able to apply dynamic routing, I am open to any suggestions!

1 Answers1

0

you'll need to wrap the cell content of the "PO Number" column with a link that navigates to the desired route.

Here's a step-by-step guide on how to do this:

1: Import the useRouter hook from Next.js at the top of your component file

2: Inside your RepoTable component, initialize the useRouter hook like this

const router = useRouter();

3: Modify your columns definition to include a custom cell renderer for the "PO Number" column:

    const columns = useMemo<MRT_ColumnDef<Repository>[]>(
  () => [
    {
      accessorKey: 'PONUM',
      header: 'PO Number',
      cellRenderer: (rowData) => {
        const poNumber = rowData.PONUM; // Assuming this is how you access the PO number in your data
        const url = `/test/${poNumber}`;
        
        return (
          <a
            href={url}
            onClick={(e) => {
              e.preventDefault();
              router.push(url);
            }}
          >
            {poNumber}
          </a>
        );
      },
    },
    {
      accessorKey: 'DocTotalOrder',
      header: 'Total PO Cost',
    },
  ],
  [router]
);