mantine-datatable
mantine-datatable copied to clipboard
Action button clicked but nested expanded
is there away to stop the expanded row in nested when the button is clicked ??
this is the ui image result
https://prnt.sc/8CE7RfhWFjJy
i want to make behavior when the button clicked the nested not going to expanded
here is my code
import { DataTable, DataTableSortStatus } from 'mantine-datatable';
import { useEffect, useState } from 'react';
import sortBy from 'lodash/sortBy';
import dynamic from 'next/dynamic';
import { useDispatch } from 'react-redux';
import { setPageTitle } from '../../store/themeConfigSlice';
import { useSession } from 'next-auth/react';
import { useTranslation } from 'react-i18next';
import Tippy from '@tippyjs/react';
import IconPencil from '@/components/Icon/IconPencil';
import IconTrashLines from '@/components/Icon/IconTrashLines';
import clsx from 'clsx';
import { Box } from '@mantine/core';
import { IconChevronRight } from '@tabler/icons-react';
const ReactApexChart = dynamic(() => import('react-apexcharts'), { ssr: false });
const Basic = () => {
const dispatch = useDispatch();
const { t } = useTranslation();
useEffect(() => {
dispatch(setPageTitle('Advanced Table'));
});
const { data: session } = useSession(); // Get the session from next-auth
const [product, setProduct] = useState([]);
const [isMounted, setIsMounted] = useState(false);
const [page, setPage] = useState(1);
const PAGE_SIZES = [10, 20, 30, 50, 100];
const [pageSize, setPageSize] = useState(PAGE_SIZES[0]);
const [sortStatus, setSortStatus] = useState < DataTableSortStatus > ({
columnAccessor: 'name',
direction: 'asc',
});
const [expandedProductIds, setExpandedProductIds] = useState < string[] > ([]);
const [expandedVariantIds, setExpandedVariantIds] = useState < string[] > ([]);
const [expandedStockIds, setExpandedStockIds] = useState < string[] > ([]);
const getDataProduct = async () => {
if (!session) return; // Ensure session is available
try {
const response = await fetch('/api/products/all', {
headers: {
Authorization: `Bearer ${session.accessToken}`, // Use token from session
},
});
const data = await response.json();
setProduct(data.data);
setIsMounted(true);
if (data.success) {
console.log('Products fetched successfully:', data.data);
} else {
console.error(data.message);
}
} catch (error) {
console.error('Error fetching products:', error);
}
};
useEffect(() => {
getDataProduct();
}, [session]);
useEffect(() => {
setPage(1);
}, [pageSize]);
useEffect(() => {
const data = sortBy(product, sortStatus.columnAccessor);
setProduct(sortStatus.direction === 'desc' ? data.reverse() : data);
setPage(1);
}, [sortStatus]);
return (
<div>
<div className="panel mt-6">
<h5 className="mb-5 text-lg font-semibold dark:text-white-light">Product Data</h5>
<div className="datatables">
{isMounted && (
<DataTable
withTableBorder
withColumnBorders
highlightOnHover
records={product}
columns={[
{
accessor: 'name',
title: `${t('product_name')}`,
sortable: true,
render: ({ id, name }) => (
<Box component="span" ml={5} className="flex items-center gap-x-2">
<IconChevronRight
className={clsx(
'w-4 h-4 cursor-pointer transition-transform duration-200',
expandedProductIds.includes(id) && 'rotate-90'
)}
/>
<span className="font-semibold">{name}</span>
</Box>
),
},
{
accessor: 'image',
title: 'Image',
render: ({ image }) => (
<div className="flex items-center gap-2">
<img src={`${image}`} alt="user-profile" className="w-36 h-36" />
</div>
),
},
{
accessor: 'product_parent_sku',
title: `${t('product_parent_sku')}`,
sortable: true,
render: ({ product_parent_sku }) => <div className="font-semibold">{product_parent_sku}</div>,
},
{
accessor: 'category',
title: `${t('category')}`,
sortable: true,
render: ({ category }) => <div className="font-semibold">{category[0].name}</div>,
},
{
accessor: 'action',
title: 'Action',
titleClassName: '!text-center',
render: () => (
<div className="mx-auto flex w-max items-center gap-2">
<Tippy content="Edit">
<button type="button">
<IconPencil className="text-success" />
</button>
</Tippy>
<Tippy content="Delete">
<button type="button">
<IconTrashLines className="text-danger" />
</button>
</Tippy>
</div>
),
},
]}
rowExpansion={{
allowMultiple: true,
expanded: { recordIds: expandedProductIds, onRecordIdsChange: setExpandedProductIds },
content: (product) => (
<DataTable
noHeader
withColumnBorders
columns={[
{
accessor: 'name',
noWrap: true,
render: ({ id, name }) => (
<Box component="span" ml={5} className="flex items-center gap-x-2">
<IconChevronRight
className={clsx(
'w-4 h-4 cursor-pointer transition-transform duration-200',
expandedVariantIds.includes(id) && 'rotate-90'
)}
/>
<span className="font-semibold">{name}</span>
</Box>
),
},
]}
records={product.record.variants}
rowExpansion={{
allowMultiple: true,
expanded: { recordIds: expandedVariantIds, onRecordIdsChange: setExpandedVariantIds },
content: (variant) => (
variant.record.VariantItem.length > 0 ? (
<DataTable
noHeader
withColumnBorders
columns={[
{
accessor: 'name',
render: ({ id, name }) => (
<Box component="span" ml={10} className="flex items-center gap-x-2">
<IconChevronRight
className={clsx(
'w-4 h-4 cursor-pointer transition-transform duration-200',
expandedStockIds.includes(id) && 'rotate-90'
)}
/>
<span className="font-semibold">{name}</span>
</Box>
),
},
]}
records={variant.record.VariantItem}
rowExpansion={{
allowMultiple: true,
expanded: { recordIds: expandedStockIds, onRecordIdsChange: setExpandedStockIds },
content: (variantItem) => (
<DataTable
noHeader
withColumnBorders
columns={[
{
accessor: 'price_sale',
title: 'Sale Price',
render: ({ price_sale }) => <span>{price_sale}</span>,
},
{
accessor: 'quantity',
title: 'Quantity',
render: ({ quantity }) => <span>{quantity}</span>,
},
]}
records={variantItem.record.stocks}
/>
),
}}
/>
) : (
<DataTable
noHeader
withColumnBorders
columns={[
{
accessor: 'price_sale',
title: 'Sale Price',
render: ({ price_sale }) => <span>{price_sale}</span>,
},
{
accessor: 'quantity',
title: 'Quantity',
render: ({ quantity }) => <span>{quantity}</span>,
},
]}
records={variant.record.stocks}
/>
)
),
}}
/>
),
}}
totalRecords={product.length}
recordsPerPage={pageSize}
page={page}
onPageChange={(p) => setPage(p)}
recordsPerPageOptions={PAGE_SIZES}
onRecordsPerPageChange={setPageSize}
sortStatus={sortStatus}
onSortStatusChange={setSortStatus}
minHeight={200}
paginationText={({ from, to, totalRecords }) => `Showing ${from} to ${to} of ${totalRecords} entries`}
/>
)}
</div>
</div>
</div>
);
};
export default Basic;
Solution is documented here: https://icflorescu.github.io/mantine-datatable/examples/links-or-buttons-inside-clickable-rows-or-cells/
Solution is documented here: https://icflorescu.github.io/mantine-datatable/examples/links-or-buttons-inside-clickable-rows-or-cells/
Thanks sir just ill try it. Just realize theres a method in doc 🤣