complete sorting and filtering datatable and working with local storage for caching data
This commit is contained in:
@@ -1,88 +1,86 @@
|
||||
import DataTable_Paper from "./table/Paper";
|
||||
import {useMaterialReactTable} from "material-react-table";
|
||||
import {FA_DATATABLE_LOCALIZATION} from "./localization/fa/datatable";
|
||||
import { useMaterialReactTable } from "material-react-table";
|
||||
import { FA_DATATABLE_LOCALIZATION } from "./localization/fa/datatable";
|
||||
import useTableSetting from "@/lib/hooks/useTableSetting";
|
||||
import {flattenArrayOfObjects} from "@/core/utils/flattenArrayOfObjects";
|
||||
import { flattenArrayOfObjects } from "@/core/utils/flattenArrayOfObjects";
|
||||
import Toolbar from "@/components/home/Toolbar";
|
||||
import useDataTable from "@/lib/hooks/useDataTable";
|
||||
import {useMemo, useState} from "react";
|
||||
import {toast} from "react-toastify";
|
||||
import AskForKeepSort from "@/core/components/NotificationDesign/AskForKeepSort";
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
const data = [
|
||||
{
|
||||
name: {
|
||||
firstName: 'امین',
|
||||
lastName: 'قاسمپور',
|
||||
firstName: "امین",
|
||||
lastName: "قاسمپور",
|
||||
},
|
||||
address: 'فلان جا',
|
||||
city: 'تهران',
|
||||
state: 'بررسی شده',
|
||||
price: '20',
|
||||
updated_at: '2024/05/02',
|
||||
company: 'همراه اول',
|
||||
area: 'منطقه 5',
|
||||
address: "فلان جا",
|
||||
city: "تهران",
|
||||
state: "بررسی شده",
|
||||
price: "20",
|
||||
updated_at: "2024/05/02",
|
||||
company: "همراه اول",
|
||||
area: "منطقه 5",
|
||||
},
|
||||
{
|
||||
name: {
|
||||
firstName: 'امیر حسین',
|
||||
lastName: 'محمودی',
|
||||
firstName: "امیر حسین",
|
||||
lastName: "محمودی",
|
||||
},
|
||||
address: 'فلان جا',
|
||||
city: 'تهران',
|
||||
state: 'تکمیل شده',
|
||||
price: '27',
|
||||
updated_at: '2024/05/02',
|
||||
company: 'وایتل',
|
||||
area: 'منطقه 27',
|
||||
address: "فلان جا",
|
||||
city: "تهران",
|
||||
state: "تکمیل شده",
|
||||
price: "27",
|
||||
updated_at: "2024/05/02",
|
||||
company: "وایتل",
|
||||
area: "منطقه 27",
|
||||
},
|
||||
{
|
||||
name: {
|
||||
firstName: 'یاسمن',
|
||||
lastName: 'علی اکبری',
|
||||
firstName: "یاسمن",
|
||||
lastName: "علی اکبری",
|
||||
},
|
||||
address: 'فلان جا',
|
||||
city: 'شیراز',
|
||||
state: 'بررسی شده',
|
||||
price: '32',
|
||||
updated_at: '2024/05/02',
|
||||
company: 'ایرانسل',
|
||||
area: 'منطقه 23',
|
||||
address: "فلان جا",
|
||||
city: "شیراز",
|
||||
state: "بررسی شده",
|
||||
price: "32",
|
||||
updated_at: "2024/05/02",
|
||||
company: "ایرانسل",
|
||||
area: "منطقه 23",
|
||||
},
|
||||
{
|
||||
name: {
|
||||
firstName: 'حمیدرضا',
|
||||
lastName: 'رنجبرپور',
|
||||
firstName: "حمیدرضا",
|
||||
lastName: "رنجبرپور",
|
||||
},
|
||||
address: 'فلان جا',
|
||||
city: 'اصفهان',
|
||||
state: 'بررسی شده',
|
||||
price: '45',
|
||||
updated_at: '2024/05/02',
|
||||
company: 'ایرانول',
|
||||
area: 'منطقه 21',
|
||||
address: "فلان جا",
|
||||
city: "اصفهان",
|
||||
state: "بررسی شده",
|
||||
price: "45",
|
||||
updated_at: "2024/05/02",
|
||||
company: "ایرانول",
|
||||
area: "منطقه 21",
|
||||
},
|
||||
{
|
||||
name: {
|
||||
firstName: 'محمد',
|
||||
lastName: 'جلالی',
|
||||
firstName: "محمد",
|
||||
lastName: "جلالی",
|
||||
},
|
||||
address: 'فلان جا',
|
||||
city: 'رشت',
|
||||
state: 'درحال بررسی',
|
||||
price: '8',
|
||||
updated_at: '2024/05/02',
|
||||
company: 'فیلیمو',
|
||||
area: 'منطقه 8',
|
||||
address: "فلان جا",
|
||||
city: "رشت",
|
||||
state: "درحال بررسی",
|
||||
price: "8",
|
||||
updated_at: "2024/05/02",
|
||||
company: "فیلیمو",
|
||||
area: "منطقه 8",
|
||||
},
|
||||
];
|
||||
|
||||
const DataTable_Main = (props) => {
|
||||
const {filterData, sortData, setSortData} = useDataTable();
|
||||
const {table_url, user_id, page_name, table_name, columns, initialStateProps} = props
|
||||
const flatColumns = flattenArrayOfObjects(columns, 'columns')
|
||||
const {settingStore, hideAction, sortAction} = useTableSetting();
|
||||
const [pagination, setPagination] = useState({pageIndex: 0, pageSize: 10});
|
||||
const { filterData, sortData, setSortData } = useDataTable();
|
||||
const { table_url, user_id, page_name, table_name, columns, initialStateProps } = props;
|
||||
const flatColumns = flattenArrayOfObjects(columns, "columns");
|
||||
const { settingStore, hideAction } = useTableSetting();
|
||||
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
|
||||
|
||||
const onColumnVisibilityChange = (event) => {
|
||||
const settingValue = event();
|
||||
@@ -90,78 +88,54 @@ const DataTable_Main = (props) => {
|
||||
};
|
||||
|
||||
const onSortingChange = (event) => {
|
||||
toast.dismiss({containerId: "datatable", id: "sort"});
|
||||
setSortData(event);
|
||||
setTimeout(() => {
|
||||
toast(<AskForKeepSort event={event} user_id={user_id} page_name={page_name} table_name={table_name}
|
||||
columns={columns} flatColumns={flatColumns}/>, {
|
||||
containerId: "datatable",
|
||||
toastId: "sort",
|
||||
className: "filter-toast",
|
||||
position: "bottom-left",
|
||||
draggable: true,
|
||||
autoClose: false,
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
const filters = Object.keys(filterData)
|
||||
.map(key => {
|
||||
const value = filterData[key].value;
|
||||
if (value !== "" &&
|
||||
!(Array.isArray(value) && (value.length === 0 || (value.length === 2 && value[0] === "" && value[1] === "")))) {
|
||||
return filterData[key];
|
||||
}
|
||||
})
|
||||
.filter(Boolean);
|
||||
const storedFilters = settingStore?.[user_id]?.[page_name]?.[table_name]?.filters;
|
||||
const finalFilters = storedFilters || filters;
|
||||
};
|
||||
|
||||
const fetchUrl = useMemo(() => {
|
||||
const params = new URLSearchParams();
|
||||
params.set("start", `${pagination.pageIndex * pagination.pageSize}`);
|
||||
params.set("size", pagination.pageSize);
|
||||
params.set("filters", JSON.stringify(finalFilters ?? []));
|
||||
params.set("sorting", JSON.stringify(settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] ?? []));
|
||||
params.set("filters", JSON.stringify(filterData ?? []));
|
||||
params.set("sorting", JSON.stringify(sortData));
|
||||
return `${table_url}?${params}`;
|
||||
}, [table_url, finalFilters, pagination, columns]);
|
||||
|
||||
}, [table_url, filterData, pagination, columns]);
|
||||
|
||||
const table = useMaterialReactTable({
|
||||
localization: FA_DATATABLE_LOCALIZATION,
|
||||
columns,
|
||||
data: data,
|
||||
initialState: {
|
||||
density: 'compact',
|
||||
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.['hides'],
|
||||
density: "compact",
|
||||
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"],
|
||||
sorting: sortData,
|
||||
...initialStateProps
|
||||
...initialStateProps,
|
||||
},
|
||||
state: {
|
||||
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.['hides'],
|
||||
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"],
|
||||
sorting: sortData,
|
||||
pagination
|
||||
pagination,
|
||||
},
|
||||
muiTableHeadProps: {
|
||||
sx: {
|
||||
borderTop: "1px solid #e1e1e1",
|
||||
borderBottom: "2px solid #e1e1e1",
|
||||
}
|
||||
},
|
||||
},
|
||||
muiTableHeadCellProps: {
|
||||
sx: {
|
||||
color: "primary.main",
|
||||
borderLeft: "1px solid #e1e1e1",
|
||||
"&:first-of-type": {
|
||||
borderLeft: "unset"
|
||||
}
|
||||
borderLeft: "unset",
|
||||
},
|
||||
},
|
||||
},
|
||||
muiTableBodyCellProps: {
|
||||
sx: {
|
||||
borderLeft: "1px solid #e1e1e1",
|
||||
"&:first-of-type": {
|
||||
borderLeft: "unset"
|
||||
}
|
||||
borderLeft: "unset",
|
||||
},
|
||||
},
|
||||
},
|
||||
manualFiltering: true,
|
||||
@@ -170,19 +144,23 @@ const DataTable_Main = (props) => {
|
||||
onPaginationChange: setPagination,
|
||||
onColumnVisibilityChange: onColumnVisibilityChange,
|
||||
onSortingChange: onSortingChange,
|
||||
renderTopToolbarCustomActions: ({table}) => (<>
|
||||
<Toolbar
|
||||
columns={flatColumns}
|
||||
/>
|
||||
</>),
|
||||
...props
|
||||
})
|
||||
renderTopToolbarCustomActions: ({ table }) => (
|
||||
<>
|
||||
<Toolbar columns={flatColumns} />
|
||||
</>
|
||||
),
|
||||
...props,
|
||||
});
|
||||
|
||||
return <DataTable_Paper table={table} columns={flatColumns} user_id={user_id} page_name={page_name}
|
||||
table_name={table_name}/>;
|
||||
return (
|
||||
<DataTable_Paper
|
||||
table={table}
|
||||
columns={flatColumns}
|
||||
user_id={user_id}
|
||||
page_name={page_name}
|
||||
table_name={table_name}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default DataTable_Main;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,11 +4,7 @@ import { useMRT_RowVirtualizer, useMRT_Rows } from "material-react-table";
|
||||
import { memo, useMemo } from "react";
|
||||
import DataTable_TableBodyRow, { Memo_DataTable_TableBodyRow } from "./TableBodyRow";
|
||||
|
||||
const DataTable_TableBody = ({
|
||||
columnVirtualizer,
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_TableBody = ({ columnVirtualizer, table, ...rest }) => {
|
||||
const {
|
||||
getBottomRows,
|
||||
getIsSomeRowsPinned,
|
||||
@@ -35,12 +31,8 @@ const DataTable_TableBody = ({
|
||||
...rest,
|
||||
};
|
||||
|
||||
const tableHeadHeight =
|
||||
((enableStickyHeader || isFullScreen) &&
|
||||
tableHeadRef.current?.clientHeight) ||
|
||||
0;
|
||||
const tableFooterHeight =
|
||||
(enableStickyFooter && tableFooterRef.current?.clientHeight) || 0;
|
||||
const tableHeadHeight = ((enableStickyHeader || isFullScreen) && tableHeadRef.current?.clientHeight) || 0;
|
||||
const tableFooterHeight = (enableStickyFooter && tableFooterRef.current?.clientHeight) || 0;
|
||||
|
||||
const pinnedRowIds = useMemo(() => {
|
||||
if (!rowPinning.bottom?.length && !rowPinning.top?.length) return [];
|
||||
@@ -63,67 +55,63 @@ const DataTable_TableBody = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
{!rowPinningDisplayMode?.includes('sticky') &&
|
||||
getIsSomeRowsPinned('top') && (
|
||||
<TableBody
|
||||
{...tableBodyProps}
|
||||
sx={(theme) => ({
|
||||
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
|
||||
position: 'sticky',
|
||||
top: tableHeadHeight - 1,
|
||||
zIndex: 1,
|
||||
...(parseFromValuesOrFunc(tableBodyProps?.sx, theme)),
|
||||
})}
|
||||
>
|
||||
{getTopRows().map((row, staticRowIndex) => {
|
||||
const props = {
|
||||
...commonRowProps,
|
||||
row,
|
||||
staticRowIndex,
|
||||
};
|
||||
return memoMode === 'rows' ? (
|
||||
<Memo_DataTable_TableBodyRow key={row.id} {...props} />
|
||||
) : (
|
||||
<DataTable_TableBodyRow key={row.id} {...props} />
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
)}
|
||||
{!rowPinningDisplayMode?.includes("sticky") && getIsSomeRowsPinned("top") && (
|
||||
<TableBody
|
||||
{...tableBodyProps}
|
||||
sx={(theme) => ({
|
||||
display: layoutMode?.startsWith("grid") ? "grid" : undefined,
|
||||
position: "sticky",
|
||||
top: tableHeadHeight - 1,
|
||||
zIndex: 1,
|
||||
...parseFromValuesOrFunc(tableBodyProps?.sx, theme),
|
||||
})}
|
||||
>
|
||||
{getTopRows().map((row, staticRowIndex) => {
|
||||
const props = {
|
||||
...commonRowProps,
|
||||
row,
|
||||
staticRowIndex,
|
||||
};
|
||||
return memoMode === "rows" ? (
|
||||
<Memo_DataTable_TableBodyRow key={row.id} {...props} />
|
||||
) : (
|
||||
<DataTable_TableBodyRow key={row.id} {...props} />
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
)}
|
||||
<TableBody
|
||||
{...tableBodyProps}
|
||||
sx={(theme) => ({
|
||||
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
|
||||
height: rowVirtualizer
|
||||
? `${rowVirtualizer.getTotalSize()}px`
|
||||
: undefined,
|
||||
minHeight: !rows.length ? '100px' : undefined,
|
||||
position: 'relative',
|
||||
...(parseFromValuesOrFunc(tableBodyProps?.sx, theme)),
|
||||
display: layoutMode?.startsWith("grid") ? "grid" : undefined,
|
||||
height: rowVirtualizer ? `${rowVirtualizer.getTotalSize()}px` : undefined,
|
||||
minHeight: !rows.length ? "100px" : undefined,
|
||||
position: "relative",
|
||||
...parseFromValuesOrFunc(tableBodyProps?.sx, theme),
|
||||
})}
|
||||
>
|
||||
{tableBodyProps?.children ??
|
||||
(!rows.length ? (
|
||||
<tr
|
||||
style={{
|
||||
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
|
||||
display: layoutMode?.startsWith("grid") ? "grid" : undefined,
|
||||
}}
|
||||
>
|
||||
<td
|
||||
colSpan={table.getVisibleLeafColumns().length}
|
||||
style={{
|
||||
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
|
||||
display: layoutMode?.startsWith("grid") ? "grid" : undefined,
|
||||
}}
|
||||
>
|
||||
{renderEmptyRowsFallback?.({ table }) ?? (
|
||||
<Typography
|
||||
sx={{
|
||||
color: 'text.secondary',
|
||||
fontStyle: 'italic',
|
||||
maxWidth: `min(100vw, ${tablePaperRef.current?.clientWidth ?? 360
|
||||
}px)`,
|
||||
py: '2rem',
|
||||
textAlign: 'center',
|
||||
width: '100%',
|
||||
color: "text.secondary",
|
||||
fontStyle: "italic",
|
||||
maxWidth: `min(100vw, ${tablePaperRef.current?.clientWidth ?? 360}px)`,
|
||||
py: "2rem",
|
||||
textAlign: "center",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{globalFilter || columnFilters.length
|
||||
@@ -155,12 +143,10 @@ const DataTable_TableBody = ({
|
||||
row,
|
||||
rowVirtualizer,
|
||||
staticRowIndex,
|
||||
virtualRow: rowVirtualizer
|
||||
? (rowOrVirtualRow)
|
||||
: undefined,
|
||||
virtualRow: rowVirtualizer ? rowOrVirtualRow : undefined,
|
||||
};
|
||||
const key = `${row.id}-${row.index}`;
|
||||
return memoMode === 'rows' ? (
|
||||
return memoMode === "rows" ? (
|
||||
<Memo_DataTable_TableBodyRow key={key} {...props} />
|
||||
) : (
|
||||
<DataTable_TableBodyRow key={key} {...props} />
|
||||
@@ -169,39 +155,37 @@ const DataTable_TableBody = ({
|
||||
</>
|
||||
))}
|
||||
</TableBody>
|
||||
{!rowPinningDisplayMode?.includes('sticky') &&
|
||||
getIsSomeRowsPinned('bottom') && (
|
||||
<TableBody
|
||||
{...tableBodyProps}
|
||||
sx={(theme) => ({
|
||||
bottom: tableFooterHeight - 1,
|
||||
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
|
||||
position: 'sticky',
|
||||
zIndex: 1,
|
||||
...(parseFromValuesOrFunc(tableBodyProps?.sx, theme)),
|
||||
})}
|
||||
>
|
||||
{getBottomRows().map((row, staticRowIndex) => {
|
||||
const props = {
|
||||
...commonRowProps,
|
||||
row,
|
||||
staticRowIndex,
|
||||
};
|
||||
return memoMode === 'rows' ? (
|
||||
<Memo_DataTable_TableBodyRow key={row.id} {...props} />
|
||||
) : (
|
||||
<DataTable_TableBodyRow key={row.id} {...props} />
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
)}
|
||||
{!rowPinningDisplayMode?.includes("sticky") && getIsSomeRowsPinned("bottom") && (
|
||||
<TableBody
|
||||
{...tableBodyProps}
|
||||
sx={(theme) => ({
|
||||
bottom: tableFooterHeight - 1,
|
||||
display: layoutMode?.startsWith("grid") ? "grid" : undefined,
|
||||
position: "sticky",
|
||||
zIndex: 1,
|
||||
...parseFromValuesOrFunc(tableBodyProps?.sx, theme),
|
||||
})}
|
||||
>
|
||||
{getBottomRows().map((row, staticRowIndex) => {
|
||||
const props = {
|
||||
...commonRowProps,
|
||||
row,
|
||||
staticRowIndex,
|
||||
};
|
||||
return memoMode === "rows" ? (
|
||||
<Memo_DataTable_TableBodyRow key={row.id} {...props} />
|
||||
) : (
|
||||
<DataTable_TableBodyRow key={row.id} {...props} />
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
}
|
||||
export default DataTable_TableBody
|
||||
};
|
||||
export default DataTable_TableBody;
|
||||
|
||||
export const Memo_DataTable_TableBody = memo(
|
||||
DataTable_TableBody,
|
||||
(prev, next) => prev.table.options.data === next.table.options.data,
|
||||
);
|
||||
(prev, next) => prev.table.options.data === next.table.options.data
|
||||
);
|
||||
|
||||
@@ -7,15 +7,7 @@ const { useState, useEffect, useMemo, memo } = require("react");
|
||||
const { default: DataTable_CopyButton } = require("../buttons/CopyButton");
|
||||
const { default: DataTable_TableBodyCellValue } = require("./TableBodyCellValue");
|
||||
|
||||
const DataTable_TableBodyCell = ({
|
||||
cell,
|
||||
numRows,
|
||||
rowRef,
|
||||
staticColumnIndex,
|
||||
staticRowIndex,
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, staticRowIndex, table, ...rest }) => {
|
||||
const theme = useTheme();
|
||||
const {
|
||||
getState,
|
||||
@@ -73,9 +65,7 @@ const DataTable_TableBodyCell = ({
|
||||
if ((!isLoading && !showSkeletons) || skeletonWidth !== 100) return;
|
||||
const size = column.getSize();
|
||||
setSkeletonWidth(
|
||||
columnDefType === 'display'
|
||||
? size / 2
|
||||
: Math.round(Math.random() * (size - size / 3) + size / 3),
|
||||
columnDefType === "display" ? size / 2 : Math.round(Math.random() * (size - size / 3) + size / 3)
|
||||
);
|
||||
}, [isLoading, showSkeletons]);
|
||||
|
||||
@@ -88,77 +78,55 @@ const DataTable_TableBodyCell = ({
|
||||
const isLastColumn = column.getIsLastColumn();
|
||||
const isLastRow = numRows && staticRowIndex === numRows - 1;
|
||||
const isResizingColumn = columnSizingInfo.isResizingColumn === column.id;
|
||||
const showResizeBorder =
|
||||
isResizingColumn && columnResizeMode === 'onChange';
|
||||
const showResizeBorder = isResizingColumn && columnResizeMode === "onChange";
|
||||
|
||||
const borderStyle = showResizeBorder
|
||||
? `2px solid ${draggingBorderColor} !important`
|
||||
: isDraggingColumn || isDraggingRow
|
||||
? `1px dashed ${theme.palette.grey[500]} !important`
|
||||
: isHoveredColumn || isHoveredRow || isResizingColumn
|
||||
? `2px dashed ${draggingBorderColor} !important`
|
||||
: undefined;
|
||||
? `1px dashed ${theme.palette.grey[500]} !important`
|
||||
: isHoveredColumn || isHoveredRow || isResizingColumn
|
||||
? `2px dashed ${draggingBorderColor} !important`
|
||||
: undefined;
|
||||
|
||||
if (showResizeBorder) {
|
||||
return columnResizeDirection === 'ltr'
|
||||
? { borderRight: borderStyle }
|
||||
: { borderLeft: borderStyle };
|
||||
return columnResizeDirection === "ltr" ? { borderRight: borderStyle } : { borderLeft: borderStyle };
|
||||
}
|
||||
|
||||
return borderStyle
|
||||
? {
|
||||
borderBottom:
|
||||
isDraggingRow || isHoveredRow || (isLastRow && !isResizingColumn)
|
||||
? borderStyle
|
||||
: undefined,
|
||||
borderLeft:
|
||||
isDraggingColumn ||
|
||||
isHoveredColumn ||
|
||||
((isDraggingRow || isHoveredRow) && isFirstColumn)
|
||||
? borderStyle
|
||||
: undefined,
|
||||
borderRight:
|
||||
isDraggingColumn ||
|
||||
isHoveredColumn ||
|
||||
((isDraggingRow || isHoveredRow) && isLastColumn)
|
||||
? borderStyle
|
||||
: undefined,
|
||||
borderTop: isDraggingRow || isHoveredRow ? borderStyle : undefined,
|
||||
}
|
||||
borderBottom:
|
||||
isDraggingRow || isHoveredRow || (isLastRow && !isResizingColumn) ? borderStyle : undefined,
|
||||
borderLeft:
|
||||
isDraggingColumn || isHoveredColumn || ((isDraggingRow || isHoveredRow) && isFirstColumn)
|
||||
? borderStyle
|
||||
: undefined,
|
||||
borderRight:
|
||||
isDraggingColumn || isHoveredColumn || ((isDraggingRow || isHoveredRow) && isLastColumn)
|
||||
? borderStyle
|
||||
: undefined,
|
||||
borderTop: isDraggingRow || isHoveredRow ? borderStyle : undefined,
|
||||
}
|
||||
: undefined;
|
||||
}, [
|
||||
columnSizingInfo.isResizingColumn,
|
||||
draggingColumn,
|
||||
draggingRow,
|
||||
hoveredColumn,
|
||||
hoveredRow,
|
||||
staticRowIndex,
|
||||
]);
|
||||
}, [columnSizingInfo.isResizingColumn, draggingColumn, draggingRow, hoveredColumn, hoveredRow, staticRowIndex]);
|
||||
|
||||
const isColumnPinned =
|
||||
enableColumnPinning &&
|
||||
columnDef.columnDefType !== 'group' &&
|
||||
column.getIsPinned();
|
||||
const isColumnPinned = enableColumnPinning && columnDef.columnDefType !== "group" && column.getIsPinned();
|
||||
|
||||
const isEditable = isCellEditable({ cell, table });
|
||||
|
||||
const isEditing =
|
||||
isEditable &&
|
||||
!['custom', 'modal'].includes(editDisplayMode) &&
|
||||
(editDisplayMode === 'table' ||
|
||||
editingRow?.id === row.id ||
|
||||
editingCell?.id === cell.id) &&
|
||||
!["custom", "modal"].includes(editDisplayMode) &&
|
||||
(editDisplayMode === "table" || editingRow?.id === row.id || editingCell?.id === cell.id) &&
|
||||
!row.getIsGrouped();
|
||||
|
||||
const isCreating =
|
||||
isEditable && createDisplayMode === 'row' && creatingRow?.id === row.id;
|
||||
const isCreating = isEditable && createDisplayMode === "row" && creatingRow?.id === row.id;
|
||||
|
||||
const showClickToCopyButton =
|
||||
(parseFromValuesOrFunc(enableClickToCopy, cell) === true ||
|
||||
parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) === true) &&
|
||||
!['context-menu', false].includes(
|
||||
!["context-menu", false].includes(
|
||||
// @ts-ignore
|
||||
parseFromValuesOrFunc(columnDef.enableClickToCopy, cell),
|
||||
parseFromValuesOrFunc(columnDef.enableClickToCopy, cell)
|
||||
);
|
||||
|
||||
const isRightClickable = parseFromValuesOrFunc(enableCellActions, cell);
|
||||
@@ -175,13 +143,11 @@ const DataTable_TableBodyCell = ({
|
||||
|
||||
const handleDragEnter = (e) => {
|
||||
tableCellProps?.onDragEnter?.(e);
|
||||
if (enableGrouping && hoveredColumn?.id === 'drop-zone') {
|
||||
if (enableGrouping && hoveredColumn?.id === "drop-zone") {
|
||||
setHoveredColumn(null);
|
||||
}
|
||||
if (enableColumnOrdering && draggingColumn) {
|
||||
setHoveredColumn(
|
||||
columnDef.enableColumnOrdering !== false ? column : null,
|
||||
);
|
||||
setHoveredColumn(columnDef.enableColumnOrdering !== false ? column : null);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -210,43 +176,39 @@ const DataTable_TableBodyCell = ({
|
||||
onDragEnter={handleDragEnter}
|
||||
onDragOver={handleDragOver}
|
||||
sx={(theme) => ({
|
||||
'&:hover': {
|
||||
"&:hover": {
|
||||
outline:
|
||||
actionCell?.id === cell.id ||
|
||||
(editDisplayMode === 'cell' && isEditable) ||
|
||||
(editDisplayMode === 'table' && (isCreating || isEditing))
|
||||
(editDisplayMode === "cell" && isEditable) ||
|
||||
(editDisplayMode === "table" && (isCreating || isEditing))
|
||||
? `1px solid ${theme.palette.grey[500]}`
|
||||
: undefined,
|
||||
textOverflow: 'clip',
|
||||
textOverflow: "clip",
|
||||
},
|
||||
alignItems: layoutMode?.startsWith('grid') ? 'center' : undefined,
|
||||
alignItems: layoutMode?.startsWith("grid") ? "center" : undefined,
|
||||
cursor: isRightClickable
|
||||
? 'context-menu'
|
||||
: isEditable && editDisplayMode === 'cell'
|
||||
? 'pointer'
|
||||
: 'inherit',
|
||||
outline:
|
||||
actionCell?.id === cell.id
|
||||
? `1px solid ${theme.palette.grey[500]}`
|
||||
: undefined,
|
||||
outlineOffset: '-1px',
|
||||
overflow: 'hidden',
|
||||
? "context-menu"
|
||||
: isEditable && editDisplayMode === "cell"
|
||||
? "pointer"
|
||||
: "inherit",
|
||||
outline: actionCell?.id === cell.id ? `1px solid ${theme.palette.grey[500]}` : undefined,
|
||||
outlineOffset: "-1px",
|
||||
overflow: "hidden",
|
||||
p:
|
||||
density === 'compact'
|
||||
? columnDefType === 'display'
|
||||
? '0 0.5rem'
|
||||
: '0.5rem'
|
||||
: density === 'comfortable'
|
||||
? columnDefType === 'display'
|
||||
? '0.5rem 0.75rem'
|
||||
: '1rem'
|
||||
: columnDefType === 'display'
|
||||
? '1rem 1.25rem'
|
||||
: '1.5rem',
|
||||
density === "compact"
|
||||
? columnDefType === "display"
|
||||
? "0 0.5rem"
|
||||
: "0.5rem"
|
||||
: density === "comfortable"
|
||||
? columnDefType === "display"
|
||||
? "0.5rem 0.75rem"
|
||||
: "1rem"
|
||||
: columnDefType === "display"
|
||||
? "1rem 1.25rem"
|
||||
: "1.5rem",
|
||||
|
||||
textOverflow: columnDefType !== 'display' ? 'ellipsis' : undefined,
|
||||
whiteSpace:
|
||||
row.getIsPinned() || density === 'compact' ? 'nowrap' : 'normal',
|
||||
textOverflow: columnDefType !== "display" ? "ellipsis" : undefined,
|
||||
whiteSpace: row.getIsPinned() || density === "compact" ? "nowrap" : "normal",
|
||||
...getCommonMRTCellStyles({
|
||||
column,
|
||||
table,
|
||||
@@ -261,17 +223,10 @@ const DataTable_TableBodyCell = ({
|
||||
{cell.getIsPlaceholder() ? (
|
||||
columnDef.PlaceholderCell?.({ cell, column, row, table }) ?? null
|
||||
) : showSkeletons !== false && (isLoading || showSkeletons) ? (
|
||||
<Skeleton
|
||||
animation="wave"
|
||||
height={20}
|
||||
width={skeletonWidth}
|
||||
{...skeletonProps}
|
||||
/>
|
||||
) : columnDefType === 'display' &&
|
||||
(['mrt-row-expand', 'mrt-row-numbers', 'mrt-row-select'].includes(
|
||||
column.id,
|
||||
) ||
|
||||
!row.getIsGrouped()) ? (
|
||||
<Skeleton animation="wave" height={20} width={skeletonWidth} {...skeletonProps} />
|
||||
) : columnDefType === "display" &&
|
||||
(["mrt-row-expand", "mrt-row-numbers", "mrt-row-select"].includes(column.id) ||
|
||||
!row.getIsGrouped()) ? (
|
||||
columnDef.Cell?.({
|
||||
cell,
|
||||
column,
|
||||
@@ -289,18 +244,12 @@ const DataTable_TableBodyCell = ({
|
||||
) : (
|
||||
<DataTable_TableBodyCellValue {...cellValueProps} />
|
||||
)}
|
||||
{cell.getIsGrouped() && !columnDef.GroupedCell && (
|
||||
<> ({row.subRows?.length})</>
|
||||
)}
|
||||
{cell.getIsGrouped() && !columnDef.GroupedCell && <> ({row.subRows?.length})</>}
|
||||
</>
|
||||
)}
|
||||
</TableCell>
|
||||
);
|
||||
|
||||
}
|
||||
};
|
||||
export default DataTable_TableBodyCell;
|
||||
|
||||
export const Memo_DataTable_TableBodyCell = memo(
|
||||
DataTable_TableBodyCell,
|
||||
(prev, next) => next.cell === prev.cell,
|
||||
);
|
||||
export const Memo_DataTable_TableBodyCell = memo(DataTable_TableBodyCell, (prev, next) => next.cell === prev.cell);
|
||||
|
||||
@@ -2,111 +2,102 @@ import { Box } from "@mui/material";
|
||||
|
||||
const allowedTypes = ["string", "number"];
|
||||
|
||||
const DataTable_TableBodyCellValue = ({
|
||||
cell,
|
||||
rowRef,
|
||||
staticColumnIndex,
|
||||
staticRowIndex,
|
||||
table,
|
||||
}) => {
|
||||
const {
|
||||
getState,
|
||||
options: {
|
||||
enableFilterMatchHighlighting,
|
||||
mrtTheme: { matchHighlightColor },
|
||||
},
|
||||
} = table;
|
||||
const { column, row } = cell;
|
||||
const { columnDef } = column;
|
||||
const { globalFilter, globalFilterFn } = getState();
|
||||
const filterValue = column.getFilterValue();
|
||||
const DataTable_TableBodyCellValue = ({ cell, rowRef, staticColumnIndex, staticRowIndex, table }) => {
|
||||
const {
|
||||
getState,
|
||||
options: {
|
||||
enableFilterMatchHighlighting,
|
||||
mrtTheme: { matchHighlightColor },
|
||||
},
|
||||
} = table;
|
||||
const { column, row } = cell;
|
||||
const { columnDef } = column;
|
||||
const { globalFilter, globalFilterFn } = getState();
|
||||
const filterValue = column.getFilterValue();
|
||||
|
||||
let renderedCellValue =
|
||||
cell.getIsAggregated() && columnDef.AggregatedCell
|
||||
? columnDef.AggregatedCell({
|
||||
cell,
|
||||
column,
|
||||
row,
|
||||
table,
|
||||
})
|
||||
: row.getIsGrouped() && !cell.getIsGrouped()
|
||||
? null
|
||||
: cell.getIsGrouped() && columnDef.GroupedCell
|
||||
? columnDef.GroupedCell({
|
||||
let renderedCellValue =
|
||||
cell.getIsAggregated() && columnDef.AggregatedCell
|
||||
? columnDef.AggregatedCell({
|
||||
cell,
|
||||
column,
|
||||
row,
|
||||
table,
|
||||
})
|
||||
: row.getIsGrouped() && !cell.getIsGrouped()
|
||||
? null
|
||||
: cell.getIsGrouped() && columnDef.GroupedCell
|
||||
? columnDef.GroupedCell({
|
||||
cell,
|
||||
column,
|
||||
row,
|
||||
table,
|
||||
})
|
||||
: undefined;
|
||||
|
||||
const isGroupedValue = renderedCellValue !== undefined;
|
||||
|
||||
if (!isGroupedValue) {
|
||||
renderedCellValue = cell.renderValue();
|
||||
}
|
||||
|
||||
if (
|
||||
enableFilterMatchHighlighting &&
|
||||
columnDef.enableFilterMatchHighlighting !== false &&
|
||||
String(renderedCellValue) &&
|
||||
allowedTypes.includes(typeof renderedCellValue) &&
|
||||
((filterValue &&
|
||||
allowedTypes.includes(typeof filterValue) &&
|
||||
["autocomplete", "text"].includes(columnDef.filterVariant)) ||
|
||||
(globalFilter && allowedTypes.includes(typeof globalFilter) && column.getCanGlobalFilter()))
|
||||
) {
|
||||
const chunks = highlightWords?.({
|
||||
matchExactly: (filterValue ? columnDef._filterFn : globalFilterFn) !== "fuzzy",
|
||||
query: (filterValue ?? globalFilter ?? "").toString(),
|
||||
text: renderedCellValue?.toString(),
|
||||
});
|
||||
if (chunks?.length > 1 || chunks?.[0]?.match) {
|
||||
renderedCellValue = (
|
||||
<span aria-label={renderedCellValue} role="note">
|
||||
{chunks?.map(({ key, match, text }) => (
|
||||
<Box
|
||||
aria-hidden="true"
|
||||
component="span"
|
||||
key={key}
|
||||
sx={
|
||||
match
|
||||
? {
|
||||
backgroundColor: matchHighlightColor,
|
||||
borderRadius: "2px",
|
||||
color: (theme) =>
|
||||
theme.palette.mode === "dark"
|
||||
? theme.palette.common.white
|
||||
: theme.palette.common.black,
|
||||
padding: "2px 1px",
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{text}
|
||||
</Box>
|
||||
)) ?? renderedCellValue}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (columnDef.Cell && !isGroupedValue) {
|
||||
renderedCellValue = columnDef.Cell({
|
||||
cell,
|
||||
column,
|
||||
renderedCellValue,
|
||||
row,
|
||||
rowRef,
|
||||
staticColumnIndex,
|
||||
staticRowIndex,
|
||||
table,
|
||||
})
|
||||
: undefined;
|
||||
|
||||
const isGroupedValue = renderedCellValue !== undefined;
|
||||
|
||||
if (!isGroupedValue) {
|
||||
renderedCellValue = cell.renderValue();
|
||||
}
|
||||
|
||||
if (
|
||||
enableFilterMatchHighlighting &&
|
||||
columnDef.enableFilterMatchHighlighting !== false &&
|
||||
String(renderedCellValue) &&
|
||||
allowedTypes.includes(typeof renderedCellValue) &&
|
||||
((filterValue &&
|
||||
allowedTypes.includes(typeof filterValue) &&
|
||||
["autocomplete", "text"].includes(columnDef.filterVariant)) ||
|
||||
(globalFilter &&
|
||||
allowedTypes.includes(typeof globalFilter) &&
|
||||
column.getCanGlobalFilter()))
|
||||
) {
|
||||
const chunks = highlightWords?.({
|
||||
matchExactly:
|
||||
(filterValue ? columnDef._filterFn : globalFilterFn) !== "fuzzy",
|
||||
query: (filterValue ?? globalFilter ?? "").toString(),
|
||||
text: renderedCellValue?.toString(),
|
||||
});
|
||||
if (chunks?.length > 1 || chunks?.[0]?.match) {
|
||||
renderedCellValue = (
|
||||
<span aria-label={renderedCellValue} role="note">
|
||||
{chunks?.map(({ key, match, text }) => (
|
||||
<Box
|
||||
aria-hidden="true"
|
||||
component="span"
|
||||
key={key}
|
||||
sx={
|
||||
match
|
||||
? {
|
||||
backgroundColor: matchHighlightColor,
|
||||
borderRadius: "2px",
|
||||
color: (theme) =>
|
||||
theme.palette.mode === "dark"
|
||||
? theme.palette.common.white
|
||||
: theme.palette.common.black,
|
||||
padding: "2px 1px",
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{text}
|
||||
</Box>
|
||||
)) ?? renderedCellValue}
|
||||
</span>
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (columnDef.Cell && !isGroupedValue) {
|
||||
renderedCellValue = columnDef.Cell({
|
||||
cell,
|
||||
column,
|
||||
renderedCellValue,
|
||||
row,
|
||||
rowRef,
|
||||
staticColumnIndex,
|
||||
staticRowIndex,
|
||||
table,
|
||||
});
|
||||
}
|
||||
|
||||
return renderedCellValue;
|
||||
return renderedCellValue;
|
||||
};
|
||||
export default DataTable_TableBodyCellValue;
|
||||
|
||||
@@ -28,11 +28,7 @@ const DataTable_TableBodyRow = ({
|
||||
enableStickyHeader,
|
||||
layoutMode,
|
||||
memoMode,
|
||||
mrtTheme: {
|
||||
baseBackgroundColor,
|
||||
pinnedRowBackgroundColor,
|
||||
selectedRowBackgroundColor,
|
||||
},
|
||||
mrtTheme: { baseBackgroundColor, pinnedRowBackgroundColor, selectedRowBackgroundColor },
|
||||
muiTableBodyRowProps,
|
||||
renderDetailPanel,
|
||||
rowPinningDisplayMode,
|
||||
@@ -40,21 +36,12 @@ const DataTable_TableBodyRow = ({
|
||||
refs: { tableFooterRef, tableHeadRef },
|
||||
setHoveredRow,
|
||||
} = table;
|
||||
const {
|
||||
density,
|
||||
draggingColumn,
|
||||
draggingRow,
|
||||
editingCell,
|
||||
editingRow,
|
||||
hoveredRow,
|
||||
isFullScreen,
|
||||
rowPinning,
|
||||
} = getState();
|
||||
const { density, draggingColumn, draggingRow, editingCell, editingRow, hoveredRow, isFullScreen, rowPinning } =
|
||||
getState();
|
||||
|
||||
const visibleCells = row.getVisibleCells();
|
||||
|
||||
const { virtualColumns, virtualPaddingLeft, virtualPaddingRight } =
|
||||
columnVirtualizer ?? {};
|
||||
const { virtualColumns, virtualPaddingLeft, virtualPaddingRight } = columnVirtualizer ?? {};
|
||||
|
||||
const isRowSelected = getIsRowSelected({ row, table });
|
||||
const isRowPinned = enableRowPinning && row.getIsPinned();
|
||||
@@ -71,30 +58,17 @@ const DataTable_TableBodyRow = ({
|
||||
};
|
||||
|
||||
const [bottomPinnedIndex, topPinnedIndex] = useMemo(() => {
|
||||
if (
|
||||
!enableRowPinning ||
|
||||
!rowPinningDisplayMode?.includes('sticky') ||
|
||||
!pinnedRowIds ||
|
||||
!row.getIsPinned()
|
||||
)
|
||||
if (!enableRowPinning || !rowPinningDisplayMode?.includes("sticky") || !pinnedRowIds || !row.getIsPinned())
|
||||
return [];
|
||||
return [
|
||||
[...pinnedRowIds].reverse().indexOf(row.id),
|
||||
pinnedRowIds.indexOf(row.id),
|
||||
];
|
||||
return [[...pinnedRowIds].reverse().indexOf(row.id), pinnedRowIds.indexOf(row.id)];
|
||||
}, [pinnedRowIds, rowPinning]);
|
||||
|
||||
const tableHeadHeight =
|
||||
((enableStickyHeader || isFullScreen) &&
|
||||
tableHeadRef.current?.clientHeight) ||
|
||||
0;
|
||||
const tableFooterHeight =
|
||||
(enableStickyFooter && tableFooterRef.current?.clientHeight) || 0;
|
||||
const tableHeadHeight = ((enableStickyHeader || isFullScreen) && tableHeadRef.current?.clientHeight) || 0;
|
||||
const tableFooterHeight = (enableStickyFooter && tableFooterRef.current?.clientHeight) || 0;
|
||||
|
||||
const sx = parseFromValuesOrFunc(tableRowProps?.sx, theme);
|
||||
|
||||
const defaultRowHeight =
|
||||
density === 'compact' ? 37 : density === 'comfortable' ? 53 : 69;
|
||||
const defaultRowHeight = density === "compact" ? 37 : density === "comfortable" ? 53 : 69;
|
||||
|
||||
const customRowHeight =
|
||||
// @ts-ignore
|
||||
@@ -117,16 +91,16 @@ const DataTable_TableBodyRow = ({
|
||||
const cellHighlightColor = isRowSelected
|
||||
? selectedRowBackgroundColor
|
||||
: isRowPinned
|
||||
? pinnedRowBackgroundColor
|
||||
: undefined;
|
||||
? pinnedRowBackgroundColor
|
||||
: undefined;
|
||||
|
||||
const cellHighlightColorHover =
|
||||
tableRowProps?.hover !== false
|
||||
? isRowSelected
|
||||
? cellHighlightColor
|
||||
: theme.palette.mode === 'dark'
|
||||
? `${lighten(baseBackgroundColor, 0.3)}`
|
||||
: `${darken(baseBackgroundColor, 0.3)}`
|
||||
: theme.palette.mode === "dark"
|
||||
? `${lighten(baseBackgroundColor, 0.3)}`
|
||||
: `${darken(baseBackgroundColor, 0.3)}`
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
@@ -146,91 +120,81 @@ const DataTable_TableBodyRow = ({
|
||||
selected={isRowSelected}
|
||||
{...tableRowProps}
|
||||
style={{
|
||||
transform: virtualRow
|
||||
? `translateY(${virtualRow.start}px)`
|
||||
: undefined,
|
||||
transform: virtualRow ? `translateY(${virtualRow.start}px)` : undefined,
|
||||
...tableRowProps?.style,
|
||||
}}
|
||||
sx={(theme) => ({
|
||||
'&:hover td:after': cellHighlightColorHover
|
||||
"&:hover td:after": cellHighlightColorHover
|
||||
? {
|
||||
backgroundColor: alpha(cellHighlightColorHover, 0.3),
|
||||
...commonCellBeforeAfterStyles,
|
||||
}
|
||||
backgroundColor: alpha(cellHighlightColorHover, 0.3),
|
||||
...commonCellBeforeAfterStyles,
|
||||
}
|
||||
: undefined,
|
||||
backgroundColor: `${baseBackgroundColor} !important`,
|
||||
bottom:
|
||||
!virtualRow && bottomPinnedIndex !== undefined && isRowPinned
|
||||
? `${bottomPinnedIndex * rowHeight +
|
||||
(enableStickyFooter ? tableFooterHeight - 1 : 0)
|
||||
}px`
|
||||
? `${bottomPinnedIndex * rowHeight + (enableStickyFooter ? tableFooterHeight - 1 : 0)}px`
|
||||
: undefined,
|
||||
boxSizing: 'border-box',
|
||||
display: layoutMode?.startsWith('grid') ? 'flex' : undefined,
|
||||
boxSizing: "border-box",
|
||||
display: layoutMode?.startsWith("grid") ? "flex" : undefined,
|
||||
opacity: isRowPinned ? 0.97 : isDraggingRow || isHoveredRow ? 0.5 : 1,
|
||||
position: virtualRow
|
||||
? 'absolute'
|
||||
: rowPinningDisplayMode?.includes('sticky') && isRowPinned
|
||||
? 'sticky'
|
||||
: 'relative',
|
||||
? "absolute"
|
||||
: rowPinningDisplayMode?.includes("sticky") && isRowPinned
|
||||
? "sticky"
|
||||
: "relative",
|
||||
td: {
|
||||
...getCommonPinnedCellStyles({ table, theme }),
|
||||
},
|
||||
'td:after': cellHighlightColor
|
||||
"td:after": cellHighlightColor
|
||||
? {
|
||||
backgroundColor: cellHighlightColor,
|
||||
...commonCellBeforeAfterStyles,
|
||||
}
|
||||
backgroundColor: cellHighlightColor,
|
||||
...commonCellBeforeAfterStyles,
|
||||
}
|
||||
: undefined,
|
||||
top: virtualRow
|
||||
? 0
|
||||
: topPinnedIndex !== undefined && isRowPinned
|
||||
? `${topPinnedIndex * rowHeight +
|
||||
(enableStickyHeader || isFullScreen ? tableHeadHeight - 1 : 0)
|
||||
? `${
|
||||
topPinnedIndex * rowHeight +
|
||||
(enableStickyHeader || isFullScreen ? tableHeadHeight - 1 : 0)
|
||||
}px`
|
||||
: undefined,
|
||||
transition: virtualRow ? 'none' : 'all 150ms ease-in-out',
|
||||
width: '100%',
|
||||
zIndex:
|
||||
rowPinningDisplayMode?.includes('sticky') && isRowPinned ? 2 : 0,
|
||||
...(sx),
|
||||
: undefined,
|
||||
transition: virtualRow ? "none" : "all 150ms ease-in-out",
|
||||
width: "100%",
|
||||
zIndex: rowPinningDisplayMode?.includes("sticky") && isRowPinned ? 2 : 0,
|
||||
...sx,
|
||||
})}
|
||||
>
|
||||
{virtualPaddingLeft ? (
|
||||
<td style={{ display: 'flex', width: virtualPaddingLeft }} />
|
||||
) : null}
|
||||
{(virtualColumns ?? visibleCells).map(
|
||||
(cellOrVirtualCell, staticColumnIndex) => {
|
||||
let cell = cellOrVirtualCell;
|
||||
if (columnVirtualizer) {
|
||||
staticColumnIndex = (cellOrVirtualCell).index;
|
||||
cell = visibleCells[staticColumnIndex];
|
||||
}
|
||||
const props = {
|
||||
cell,
|
||||
numRows,
|
||||
rowRef,
|
||||
staticColumnIndex,
|
||||
staticRowIndex,
|
||||
table,
|
||||
};
|
||||
return cell ? (
|
||||
memoMode === 'cells' &&
|
||||
cell.column.columnDef.columnDefType === 'data' &&
|
||||
!draggingColumn &&
|
||||
!draggingRow &&
|
||||
editingCell?.id !== cell.id &&
|
||||
editingRow?.id !== row.id ? (
|
||||
<Memo_DataTable_TableBodyCell key={cell.id} {...props} />
|
||||
) : (
|
||||
<DataTable_TableBodyCell key={cell.id} {...props} />
|
||||
)
|
||||
) : null;
|
||||
},
|
||||
)}
|
||||
{virtualPaddingRight ? (
|
||||
<td style={{ display: 'flex', width: virtualPaddingRight }} />
|
||||
) : null}
|
||||
{virtualPaddingLeft ? <td style={{ display: "flex", width: virtualPaddingLeft }} /> : null}
|
||||
{(virtualColumns ?? visibleCells).map((cellOrVirtualCell, staticColumnIndex) => {
|
||||
let cell = cellOrVirtualCell;
|
||||
if (columnVirtualizer) {
|
||||
staticColumnIndex = cellOrVirtualCell.index;
|
||||
cell = visibleCells[staticColumnIndex];
|
||||
}
|
||||
const props = {
|
||||
cell,
|
||||
numRows,
|
||||
rowRef,
|
||||
staticColumnIndex,
|
||||
staticRowIndex,
|
||||
table,
|
||||
};
|
||||
return cell ? (
|
||||
memoMode === "cells" &&
|
||||
cell.column.columnDef.columnDefType === "data" &&
|
||||
!draggingColumn &&
|
||||
!draggingRow &&
|
||||
editingCell?.id !== cell.id &&
|
||||
editingRow?.id !== row.id ? (
|
||||
<Memo_DataTable_TableBodyCell key={cell.id} {...props} />
|
||||
) : (
|
||||
<DataTable_TableBodyCell key={cell.id} {...props} />
|
||||
)
|
||||
) : null;
|
||||
})}
|
||||
{virtualPaddingRight ? <td style={{ display: "flex", width: virtualPaddingRight }} /> : null}
|
||||
</TableRow>
|
||||
{renderDetailPanel && !row.getIsGrouped() && (
|
||||
<DataTable_TableDetailPanel
|
||||
@@ -244,11 +208,10 @@ const DataTable_TableBodyRow = ({
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
export default DataTable_TableBodyRow
|
||||
};
|
||||
export default DataTable_TableBodyRow;
|
||||
|
||||
export const Memo_DataTable_TableBodyRow = memo(
|
||||
DataTable_TableBodyRow,
|
||||
(prev, next) =>
|
||||
prev.row === next.row && prev.staticRowIndex === next.staticRowIndex,
|
||||
);
|
||||
(prev, next) => prev.row === next.row && prev.staticRowIndex === next.staticRowIndex
|
||||
);
|
||||
|
||||
@@ -23,7 +23,6 @@ const DataTable_TableDetailPanel = ({
|
||||
} = table;
|
||||
const { isLoading } = getState();
|
||||
|
||||
|
||||
const tableRowProps = parseFromValuesOrFunc(muiTableBodyRowProps, {
|
||||
isDetailPanel: true,
|
||||
row,
|
||||
@@ -52,16 +51,12 @@ const DataTable_TableDetailPanel = ({
|
||||
}}
|
||||
{...tableRowProps}
|
||||
sx={(theme) => ({
|
||||
display: layoutMode?.startsWith('grid') ? 'flex' : undefined,
|
||||
position: virtualRow ? 'absolute' : undefined,
|
||||
top: virtualRow
|
||||
? `${parentRowRef.current?.getBoundingClientRect()?.height}px`
|
||||
: undefined,
|
||||
transform: virtualRow
|
||||
? `translateY(${virtualRow?.start}px)`
|
||||
: undefined,
|
||||
width: '100%',
|
||||
...(parseFromValuesOrFunc(tableRowProps?.sx, theme)),
|
||||
display: layoutMode?.startsWith("grid") ? "flex" : undefined,
|
||||
position: virtualRow ? "absolute" : undefined,
|
||||
top: virtualRow ? `${parentRowRef.current?.getBoundingClientRect()?.height}px` : undefined,
|
||||
transform: virtualRow ? `translateY(${virtualRow?.start}px)` : undefined,
|
||||
width: "100%",
|
||||
...parseFromValuesOrFunc(tableRowProps?.sx, theme),
|
||||
})}
|
||||
>
|
||||
<TableCell
|
||||
@@ -70,12 +65,12 @@ const DataTable_TableDetailPanel = ({
|
||||
{...tableCellProps}
|
||||
sx={(theme) => ({
|
||||
backgroundColor: virtualRow ? baseBackgroundColor : undefined,
|
||||
borderBottom: !row.getIsExpanded() ? 'none' : undefined,
|
||||
display: layoutMode?.startsWith('grid') ? 'flex' : undefined,
|
||||
py: !!DetailPanel && row.getIsExpanded() ? '1rem' : 0,
|
||||
transition: !virtualRow ? 'all 150ms ease-in-out' : undefined,
|
||||
borderBottom: !row.getIsExpanded() ? "none" : undefined,
|
||||
display: layoutMode?.startsWith("grid") ? "flex" : undefined,
|
||||
py: !!DetailPanel && row.getIsExpanded() ? "1rem" : 0,
|
||||
transition: !virtualRow ? "all 150ms ease-in-out" : undefined,
|
||||
width: `100%`,
|
||||
...(parseFromValuesOrFunc(tableCellProps?.sx, theme)),
|
||||
...parseFromValuesOrFunc(tableCellProps?.sx, theme),
|
||||
})}
|
||||
>
|
||||
{virtualRow ? (
|
||||
@@ -88,6 +83,5 @@ const DataTable_TableDetailPanel = ({
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
|
||||
}
|
||||
export default DataTable_TableDetailPanel
|
||||
};
|
||||
export default DataTable_TableDetailPanel;
|
||||
|
||||
@@ -2,11 +2,7 @@ import { getCommonTooltipProps, parseFromValuesOrFunc } from "@/core/utils/utils
|
||||
import { Button, Tooltip } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
|
||||
const DataTable_CopyButton = ({
|
||||
cell,
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_CopyButton = ({ cell, table, ...rest }) => {
|
||||
const {
|
||||
options: { localization, muiCopyButtonProps },
|
||||
} = table;
|
||||
@@ -40,11 +36,8 @@ const DataTable_CopyButton = ({
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
{...getCommonTooltipProps('top')}
|
||||
title={
|
||||
buttonProps?.title ??
|
||||
(copied ? localization.copiedToClipboard : localization.clickToCopy)
|
||||
}
|
||||
{...getCommonTooltipProps("top")}
|
||||
title={buttonProps?.title ?? (copied ? localization.copiedToClipboard : localization.clickToCopy)}
|
||||
>
|
||||
<Button
|
||||
onClick={(e) => handleCopy(e, cell.getValue())}
|
||||
@@ -53,23 +46,23 @@ const DataTable_CopyButton = ({
|
||||
variant="text"
|
||||
{...buttonProps}
|
||||
sx={(theme) => ({
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: 'inherit',
|
||||
cursor: 'copy',
|
||||
fontFamily: 'inherit',
|
||||
fontSize: 'inherit',
|
||||
letterSpacing: 'inherit',
|
||||
m: '-0.25rem',
|
||||
minWidth: 'unset',
|
||||
backgroundColor: "transparent",
|
||||
border: "none",
|
||||
color: "inherit",
|
||||
cursor: "copy",
|
||||
fontFamily: "inherit",
|
||||
fontSize: "inherit",
|
||||
letterSpacing: "inherit",
|
||||
m: "-0.25rem",
|
||||
minWidth: "unset",
|
||||
py: 0,
|
||||
textAlign: 'inherit',
|
||||
textTransform: 'inherit',
|
||||
...(parseFromValuesOrFunc(buttonProps?.sx, theme)),
|
||||
textAlign: "inherit",
|
||||
textTransform: "inherit",
|
||||
...parseFromValuesOrFunc(buttonProps?.sx, theme),
|
||||
})}
|
||||
title={undefined}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
export default DataTable_CopyButton
|
||||
};
|
||||
export default DataTable_CopyButton;
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import { getCommonTooltipProps, parseFromValuesOrFunc } from "@/core/utils/utils";
|
||||
import { IconButton, Tooltip } from "@mui/material";
|
||||
|
||||
const DataTable_GrabHandleButton = ({
|
||||
location,
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_GrabHandleButton = ({ location, table, ...rest }) => {
|
||||
const {
|
||||
options: {
|
||||
icons: { DragHandleIcon },
|
||||
@@ -14,10 +10,7 @@ const DataTable_GrabHandleButton = ({
|
||||
} = table;
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
{...getCommonTooltipProps('top')}
|
||||
title={rest?.title ?? localization.move}
|
||||
>
|
||||
<Tooltip {...getCommonTooltipProps("top")} title={rest?.title ?? localization.move}>
|
||||
<IconButton
|
||||
aria-label={rest.title ?? localization.move}
|
||||
disableRipple
|
||||
@@ -29,19 +22,19 @@ const DataTable_GrabHandleButton = ({
|
||||
rest?.onClick?.(e);
|
||||
}}
|
||||
sx={(theme) => ({
|
||||
'&:active': {
|
||||
cursor: 'grabbing',
|
||||
"&:active": {
|
||||
cursor: "grabbing",
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: 'transparent',
|
||||
"&:hover": {
|
||||
backgroundColor: "transparent",
|
||||
opacity: 1,
|
||||
},
|
||||
cursor: 'grab',
|
||||
m: '0 -0.1rem',
|
||||
opacity: location === 'row' ? 1 : 0.5,
|
||||
p: '2px',
|
||||
transition: 'all 150ms ease-in-out',
|
||||
...(parseFromValuesOrFunc(rest?.sx, theme)),
|
||||
cursor: "grab",
|
||||
m: "0 -0.1rem",
|
||||
opacity: location === "row" ? 1 : 0.5,
|
||||
p: "2px",
|
||||
transition: "all 150ms ease-in-out",
|
||||
...parseFromValuesOrFunc(rest?.sx, theme),
|
||||
})}
|
||||
title={undefined}
|
||||
>
|
||||
@@ -49,6 +42,5 @@ const DataTable_GrabHandleButton = ({
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
}
|
||||
export default DataTable_GrabHandleButton
|
||||
};
|
||||
export default DataTable_GrabHandleButton;
|
||||
|
||||
@@ -19,23 +19,12 @@ const DataTable_ShowHideColumnsButton = ({ table, ...rest }) => {
|
||||
return (
|
||||
<>
|
||||
<Tooltip title={rest?.title ?? localization.showHideColumns}>
|
||||
<IconButton
|
||||
aria-label={localization.showHideColumns}
|
||||
onClick={handleClick}
|
||||
{...rest}
|
||||
title={undefined}
|
||||
>
|
||||
<IconButton aria-label={localization.showHideColumns} onClick={handleClick} {...rest} title={undefined}>
|
||||
<ViewColumnIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
{anchorEl && (
|
||||
<DataTable_ShowHideColumnsMenu
|
||||
anchorEl={anchorEl}
|
||||
setAnchorEl={setAnchorEl}
|
||||
table={table}
|
||||
/>
|
||||
)}
|
||||
{anchorEl && <DataTable_ShowHideColumnsMenu anchorEl={anchorEl} setAnchorEl={setAnchorEl} table={table} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
export default DataTable_ShowHideColumnsButton
|
||||
};
|
||||
export default DataTable_ShowHideColumnsButton;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const DataTable_ToggleFiltersButton = ({ table, ...rest }) => {
|
||||
return <></>
|
||||
}
|
||||
export default DataTable_ToggleFiltersButton
|
||||
return <></>;
|
||||
};
|
||||
export default DataTable_ToggleFiltersButton;
|
||||
|
||||
@@ -1,70 +1,41 @@
|
||||
'use client'
|
||||
"use client";
|
||||
|
||||
import {Box, Button, Drawer, styled} from "@mui/material";
|
||||
import {Form, Formik} from "formik";
|
||||
import { Box, Button, Drawer, styled } from "@mui/material";
|
||||
import { Form, Formik } from "formik";
|
||||
import useTableSetting from "@/lib/hooks/useTableSetting";
|
||||
import {useEffect, useState} from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import FilterHeader from "@/core/components/DataTable/filter/FilterHeader";
|
||||
import * as Yup from "yup";
|
||||
import FilterBodyField from "@/core/components/DataTable/filter/FilterBodyField";
|
||||
import {toast} from "react-toastify";
|
||||
import useDataTable from "@/lib/hooks/useDataTable";
|
||||
|
||||
const ScrollBox = styled(Box)({
|
||||
flexGrow: 1,
|
||||
overflowY: 'scroll',
|
||||
overflowY: "scroll",
|
||||
maxWidth: "450px",
|
||||
'::-webkit-scrollbar': {
|
||||
width: '5px',
|
||||
"::-webkit-scrollbar": {
|
||||
width: "5px",
|
||||
},
|
||||
'::-webkit-scrollbar-track': {
|
||||
boxShadow: 'inset 0 0 5px #fff',
|
||||
borderRadius: '5px',
|
||||
"::-webkit-scrollbar-track": {
|
||||
boxShadow: "inset 0 0 5px #fff",
|
||||
borderRadius: "5px",
|
||||
},
|
||||
"::-webkit-scrollbar-thumb": {
|
||||
background: "#155175",
|
||||
borderRadius: "0px",
|
||||
},
|
||||
'::-webkit-scrollbar-thumb': {
|
||||
background: '#155175',
|
||||
borderRadius: '0px',
|
||||
}
|
||||
});
|
||||
|
||||
function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, table_name}) {
|
||||
const {settingStore} = useTableSetting();
|
||||
function FilterBody({ columns, drawerState, setDrawerState, user_id, page_name, table_name }) {
|
||||
const { settingStore } = useTableSetting();
|
||||
const [initialValues, setInitialValues] = useState({});
|
||||
const [validationSchema, setValidationSchema] = useState({});
|
||||
const {filterData, setFilterData} = useDataTable();
|
||||
const { filterData, setFilterData } = useDataTable();
|
||||
|
||||
useEffect(() => {
|
||||
const values = columns.reduce((acc, column) => {
|
||||
if (!column.enableColumnFilter) return acc;
|
||||
const filter = settingStore?.[user_id]?.[page_name]?.[table_name]?.['filters']?.find((filter) => filter.id === column.id);
|
||||
if (column.datatype === 'array') {
|
||||
acc[column.id] = {
|
||||
id: column.id,
|
||||
value: filter?.value || [],
|
||||
filterFn: filter?.fn || column._filterFn,
|
||||
datatype: column.datatype
|
||||
};
|
||||
} else if (column._filterFn === "between") {
|
||||
acc[column.id] = {
|
||||
id: column.id,
|
||||
value: filter?.value || ["", ""],
|
||||
filterFn: filter?.fn || column._filterFn,
|
||||
datatype: column.datatype
|
||||
};
|
||||
} else {
|
||||
acc[column.id] = {
|
||||
id: column.id,
|
||||
value: filter?.value || '',
|
||||
filterFn: filter?.fn || column._filterFn,
|
||||
datatype: column.datatype
|
||||
};
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
setInitialValues(Object.keys(filterData).length !== 0 ? filterData : values);
|
||||
setInitialValues(filterData);
|
||||
}, [columns, settingStore, user_id, page_name, table_name, filterData]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const generatedSchema = Yup.object().shape(
|
||||
Object.keys(initialValues).reduce((acc, key) => {
|
||||
@@ -76,7 +47,10 @@ function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, t
|
||||
.test({
|
||||
test(value, ctx) {
|
||||
const [start, end] = value || ["", ""];
|
||||
if (initialValue.datatype === "numeric" && parseInt(end, 10) <= parseInt(start, 10)) {
|
||||
if (
|
||||
initialValue.datatype === "numeric" &&
|
||||
parseInt(end, 10) <= parseInt(start, 10)
|
||||
) {
|
||||
return ctx.createError({
|
||||
message: `مقدار وارده باید بیشتر از (${start}) باشد`,
|
||||
});
|
||||
@@ -97,81 +71,81 @@ function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, t
|
||||
setValidationSchema(generatedSchema);
|
||||
}, [initialValues]);
|
||||
|
||||
|
||||
const handleSubmit = (values, {setSubmitting}) => {
|
||||
toast.dismiss({containerId: "datatable", id: "filter"});
|
||||
const handleSubmit = (values, { setSubmitting }) => {
|
||||
setDrawerState(false);
|
||||
setFilterData(values)
|
||||
setFilterData(values);
|
||||
setSubmitting(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Drawer open={drawerState} onClose={() => setDrawerState(false)}
|
||||
sx={{overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%"}}>
|
||||
<FilterHeader setDrawerState={setDrawerState}/>
|
||||
<Drawer
|
||||
open={drawerState}
|
||||
onClose={() => setDrawerState(false)}
|
||||
sx={{ overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%" }}
|
||||
>
|
||||
<FilterHeader setDrawerState={setDrawerState} />
|
||||
{Object.keys(initialValues).length > 0 && (
|
||||
<ScrollBox>
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleSubmit}
|
||||
validationSchema={validationSchema}
|
||||
>
|
||||
{
|
||||
({
|
||||
values,
|
||||
handleChange,
|
||||
handleBlur,
|
||||
setFieldValue,
|
||||
errors,
|
||||
touched,
|
||||
isSubmitting,
|
||||
isValid,
|
||||
dirty,
|
||||
resetForm
|
||||
}) => (
|
||||
<Form>
|
||||
<Box sx={{px: 1, py: 2}}>
|
||||
{
|
||||
columns.map((column) => (
|
||||
column.enableColumnFilter && (
|
||||
<FilterBodyField
|
||||
key={column.id}
|
||||
column={column}
|
||||
filterParameters={values[column.id]}
|
||||
handleChange={handleChange}
|
||||
handleBlur={handleBlur}
|
||||
setFieldValue={setFieldValue}
|
||||
resetForm={resetForm}
|
||||
errors={errors}
|
||||
touched={touched}
|
||||
/>
|
||||
)
|
||||
))
|
||||
}
|
||||
</Box>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
pb: 2
|
||||
}}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
size="large"
|
||||
disabled={isSubmitting || !isValid || !dirty}
|
||||
sx={{
|
||||
px: 8,
|
||||
boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px",
|
||||
backgroundColor: "#155175", ':hover': {
|
||||
backgroundColor: "#155175",
|
||||
}
|
||||
}}>
|
||||
اعمال فیلتر
|
||||
</Button>
|
||||
</Box>
|
||||
</Form>
|
||||
)}
|
||||
<Formik initialValues={initialValues} onSubmit={handleSubmit} validationSchema={validationSchema}>
|
||||
{({
|
||||
values,
|
||||
handleChange,
|
||||
handleBlur,
|
||||
setFieldValue,
|
||||
errors,
|
||||
touched,
|
||||
isSubmitting,
|
||||
isValid,
|
||||
dirty,
|
||||
resetForm,
|
||||
}) => (
|
||||
<Form>
|
||||
<Box sx={{ px: 1, py: 2 }}>
|
||||
{columns.map(
|
||||
(column) =>
|
||||
column.enableColumnFilter && (
|
||||
<FilterBodyField
|
||||
key={column.id}
|
||||
column={column}
|
||||
filterParameters={values[column.id]}
|
||||
handleChange={handleChange}
|
||||
handleBlur={handleBlur}
|
||||
setFieldValue={setFieldValue}
|
||||
resetForm={resetForm}
|
||||
errors={errors}
|
||||
touched={touched}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
pb: 2,
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
size="large"
|
||||
disabled={isSubmitting || !isValid || !dirty}
|
||||
sx={{
|
||||
px: 8,
|
||||
boxShadow:
|
||||
"rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px",
|
||||
backgroundColor: "#155175",
|
||||
":hover": {
|
||||
backgroundColor: "#155175",
|
||||
},
|
||||
}}
|
||||
>
|
||||
اعمال فیلتر
|
||||
</Button>
|
||||
</Box>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</ScrollBox>
|
||||
)}
|
||||
@@ -179,4 +153,4 @@ function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, t
|
||||
);
|
||||
}
|
||||
|
||||
export default FilterBody;
|
||||
export default FilterBody;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {useState} from "react";
|
||||
import { useState } from "react";
|
||||
import FilterOptionList from "@/core/components/DataTable/filter/FilterOptionList";
|
||||
import CustomSelect from "@/core/components/DataTable/filter/fieldsType/CustomSelect";
|
||||
import CustomTextField from "@/core/components/DataTable/filter/fieldsType/CustomTextField";
|
||||
@@ -14,19 +14,19 @@ const columnFilterModeOptionFa = {
|
||||
lessThan: "کوچکتر",
|
||||
greaterThan: "بزرگتر",
|
||||
fuzzy: "فازی",
|
||||
between: "مابین"
|
||||
between: "مابین",
|
||||
};
|
||||
|
||||
function FilterBodyField({
|
||||
column,
|
||||
filterParameters,
|
||||
handleChange,
|
||||
handleBlur,
|
||||
setFieldValue,
|
||||
errors,
|
||||
touched,
|
||||
resetForm
|
||||
}) {
|
||||
column,
|
||||
filterParameters,
|
||||
handleChange,
|
||||
handleBlur,
|
||||
setFieldValue,
|
||||
errors,
|
||||
touched,
|
||||
resetForm,
|
||||
}) {
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const defaultFilterTranslation = columnFilterModeOptionFa[filterParameters.filterFn] || filterParameters.filterFn;
|
||||
|
||||
@@ -47,7 +47,9 @@ function FilterBodyField({
|
||||
errors={errors}
|
||||
touched={touched}
|
||||
/>
|
||||
) : filterParameters.datatype === "numeric" && filterParameters.filterFn === "equals" && Array.isArray(column.columnSelectOption) ? (
|
||||
) : filterParameters.datatype === "numeric" &&
|
||||
filterParameters.filterFn === "equals" &&
|
||||
Array.isArray(column.columnSelectOption) ? (
|
||||
<CustomSelect
|
||||
column={column}
|
||||
filterParameters={filterParameters}
|
||||
@@ -108,4 +110,4 @@ function FilterBodyField({
|
||||
);
|
||||
}
|
||||
|
||||
export default FilterBodyField;
|
||||
export default FilterBodyField;
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
'use client'
|
||||
import FilterAltIcon from '@mui/icons-material/FilterAlt';
|
||||
import {IconButton, Tooltip} from "@mui/material";
|
||||
"use client";
|
||||
import FilterAltIcon from "@mui/icons-material/FilterAlt";
|
||||
import { IconButton, Tooltip } from "@mui/material";
|
||||
|
||||
function FilterButton({drawerState, setDrawerState}) {
|
||||
function FilterButton({ drawerState, setDrawerState }) {
|
||||
return (
|
||||
<Tooltip title="فیلتر">
|
||||
<IconButton onClick={() => {
|
||||
setDrawerState(!drawerState)
|
||||
}} aria-label="filter table">
|
||||
<FilterAltIcon/>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
setDrawerState(!drawerState);
|
||||
}}
|
||||
aria-label="filter table"
|
||||
>
|
||||
<FilterAltIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
'use client'
|
||||
"use client";
|
||||
|
||||
import {Box, IconButton, Typography} from "@mui/material";
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import FilterAltIcon from '@mui/icons-material/FilterAlt';
|
||||
import { Box, IconButton, Typography } from "@mui/material";
|
||||
import CancelIcon from "@mui/icons-material/Cancel";
|
||||
import FilterAltIcon from "@mui/icons-material/FilterAlt";
|
||||
|
||||
function FilterHeader({setDrawerState}) {
|
||||
function FilterHeader({ setDrawerState }) {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@@ -15,18 +15,20 @@ function FilterHeader({setDrawerState}) {
|
||||
py: 1,
|
||||
backgroundColor: "#155175",
|
||||
boxShadow: "rgba(0, 0, 0, 0.19) 0px 10px 20px, rgba(0, 0, 0, 0.23) 0px 6px 6px",
|
||||
maxWidth: "450px"
|
||||
maxWidth: "450px",
|
||||
}}
|
||||
>
|
||||
<Box sx={{display: "flex", alignItems: "center"}}>
|
||||
<FilterAltIcon sx={{color: "#fff"}}/>
|
||||
<Typography variant="h6" sx={{color: "#fff"}}>فیلتر</Typography>
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
<FilterAltIcon sx={{ color: "#fff" }} />
|
||||
<Typography variant="h6" sx={{ color: "#fff" }}>
|
||||
فیلتر
|
||||
</Typography>
|
||||
</Box>
|
||||
<IconButton sx={{color: "#fff"}} onClick={() => setDrawerState(false)}>
|
||||
<CancelIcon sx={{fontSize: "1em"}}/>
|
||||
<IconButton sx={{ color: "#fff" }} onClick={() => setDrawerState(false)}>
|
||||
<CancelIcon sx={{ fontSize: "1em" }} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default FilterHeader;
|
||||
export default FilterHeader;
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
'use client'
|
||||
"use client";
|
||||
|
||||
import {ListItem, Menu} from "@mui/material";
|
||||
import {useState} from "react";
|
||||
import { ListItem, Menu } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
|
||||
function FilterOptionList({
|
||||
column,
|
||||
filterType,
|
||||
filterOption,
|
||||
anchorEl,
|
||||
columnFilterModeOptionFa,
|
||||
setAnchorEl,
|
||||
setFieldValue
|
||||
}) {
|
||||
column,
|
||||
filterType,
|
||||
filterOption,
|
||||
anchorEl,
|
||||
columnFilterModeOptionFa,
|
||||
setAnchorEl,
|
||||
setFieldValue,
|
||||
}) {
|
||||
const [selectedFilter, setSelectedFilter] = useState(filterType);
|
||||
|
||||
const handleChangeItem = (event, index) => {
|
||||
@@ -19,25 +19,21 @@ function FilterOptionList({
|
||||
setFieldValue(`${column.id}.filterFn`, filterOption[index]);
|
||||
setSelectedFilter(filterOption[index]);
|
||||
setAnchorEl(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloseFilterBox = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu
|
||||
id="simple-menu"
|
||||
anchorEl={anchorEl}
|
||||
keepMounted
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={handleCloseFilterBox}
|
||||
>
|
||||
<Menu id="simple-menu" anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleCloseFilterBox}>
|
||||
{filterOption.map((option, index) => (
|
||||
<ListItem key={index}
|
||||
onClick={(event) => handleChangeItem(event, index)}
|
||||
selected={option === selectedFilter}
|
||||
sx={{cursor: 'pointer', width: "100px", display: "flex", justifyContent: "center"}}>
|
||||
<ListItem
|
||||
key={index}
|
||||
onClick={(event) => handleChangeItem(event, index)}
|
||||
selected={option === selectedFilter}
|
||||
sx={{ cursor: "pointer", width: "100px", display: "flex", justifyContent: "center" }}
|
||||
>
|
||||
{columnFilterModeOptionFa[option]}
|
||||
</ListItem>
|
||||
))}
|
||||
@@ -45,4 +41,4 @@ function FilterOptionList({
|
||||
);
|
||||
}
|
||||
|
||||
export default FilterOptionList;
|
||||
export default FilterOptionList;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import React from "react";
|
||||
import MuiDatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker";
|
||||
import {Typography} from "@mui/material";
|
||||
import { Typography } from "@mui/material";
|
||||
|
||||
function CustomDatePicker({column, filterParameters, defaultFilterTranslation, setFieldValue}) {
|
||||
function CustomDatePicker({ column, filterParameters, defaultFilterTranslation, setFieldValue }) {
|
||||
return (
|
||||
<MuiDatePicker
|
||||
name={`${column.id}.value`}
|
||||
@@ -10,7 +10,7 @@ function CustomDatePicker({column, filterParameters, defaultFilterTranslation, s
|
||||
setFieldValue={setFieldValue}
|
||||
placeholder={column.header}
|
||||
helperText={
|
||||
<Typography variant="button" sx={{color: "#155175"}}>
|
||||
<Typography variant="button" sx={{ color: "#155175" }}>
|
||||
نوع فیلتر: {defaultFilterTranslation} (تاریخ)
|
||||
</Typography>
|
||||
}
|
||||
@@ -18,4 +18,4 @@ function CustomDatePicker({column, filterParameters, defaultFilterTranslation, s
|
||||
);
|
||||
}
|
||||
|
||||
export default CustomDatePicker;
|
||||
export default CustomDatePicker;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
'use client'
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import {Box, Typography} from "@mui/material";
|
||||
import { Box, Typography } from "@mui/material";
|
||||
import MuiDatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker";
|
||||
|
||||
function CustomDatePickerRange({column, filterParameters, defaultFilterTranslation, setFieldValue, errors, touched}) {
|
||||
function CustomDatePickerRange({ column, filterParameters, defaultFilterTranslation, setFieldValue, errors, touched }) {
|
||||
return (
|
||||
<Box sx={{display: "flex", gap: 1}}>
|
||||
<Box sx={{ display: "flex", gap: 1 }}>
|
||||
<MuiDatePicker
|
||||
name={`${column.id}.value[0]`}
|
||||
value={filterParameters.value[0]}
|
||||
@@ -14,7 +14,7 @@ function CustomDatePickerRange({column, filterParameters, defaultFilterTranslati
|
||||
maxDate={filterParameters.value[1]}
|
||||
placeholder={`از تاریخ`}
|
||||
helperText={
|
||||
<Typography variant="button" sx={{color: "#155175"}}>
|
||||
<Typography variant="button" sx={{ color: "#155175" }}>
|
||||
نوع فیلتر: {defaultFilterTranslation} (تاریخ)
|
||||
</Typography>
|
||||
}
|
||||
|
||||
@@ -1,33 +1,31 @@
|
||||
import React from 'react';
|
||||
import {LocalizationProvider, MobileDatePicker} from "@mui/x-date-pickers";
|
||||
import {AdapterDateFnsJalali} from "@mui/x-date-pickers/AdapterDateFnsJalali";
|
||||
import {faIR} from "@mui/x-date-pickers/locales";
|
||||
import {Box, FormHelperText, IconButton, InputAdornment} from "@mui/material";
|
||||
import React from "react";
|
||||
import { LocalizationProvider, MobileDatePicker } from "@mui/x-date-pickers";
|
||||
import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali";
|
||||
import { faIR } from "@mui/x-date-pickers/locales";
|
||||
import { Box, FormHelperText, IconButton, InputAdornment } from "@mui/material";
|
||||
import ClearIcon from "@mui/icons-material/Clear";
|
||||
import moment from "jalali-moment";
|
||||
|
||||
function MuiDatePicker({value, setFieldValue, name, minDate, maxDate, helperText, placeholder, error}) {
|
||||
|
||||
function MuiDatePicker({ value, setFieldValue, name, minDate, maxDate, helperText, placeholder, error }) {
|
||||
// console.log("error", error);
|
||||
//
|
||||
// console.log("helperText", helperText)
|
||||
|
||||
return (
|
||||
<Box sx={{display: "flex", flexDirection: "column", my: 1}}>
|
||||
<LocalizationProvider dateAdapter={AdapterDateFnsJalali}
|
||||
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
|
||||
<Box sx={{ display: "flex", flexDirection: "column", my: 1 }}>
|
||||
<LocalizationProvider
|
||||
dateAdapter={AdapterDateFnsJalali}
|
||||
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
|
||||
>
|
||||
<MobileDatePicker
|
||||
value={value ? new Date(value) : null}
|
||||
sx={{width: "100%"}}
|
||||
sx={{ width: "100%" }}
|
||||
id={name}
|
||||
name={name}
|
||||
aria-describedby="component-helper-text"
|
||||
onChange={(value) => {
|
||||
const date = new Date(value);
|
||||
const formattedDate = moment(date)
|
||||
.locale("en")
|
||||
.format("YYYY-MM-DD");
|
||||
const formattedDate = moment(date).locale("en").format("YYYY-MM-DD");
|
||||
setFieldValue(name, formattedDate);
|
||||
}}
|
||||
minDate={minDate ? new Date(minDate) : null}
|
||||
@@ -47,13 +45,13 @@ function MuiDatePicker({value, setFieldValue, name, minDate, maxDate, helperText
|
||||
}}
|
||||
sx={{
|
||||
color: "#bfbfbf",
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(189, 189, 189, 0.1)',
|
||||
color: "#363434"
|
||||
"&:hover": {
|
||||
backgroundColor: "rgba(189, 189, 189, 0.1)",
|
||||
color: "#363434",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ClearIcon/>
|
||||
<ClearIcon />
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
@@ -61,7 +59,7 @@ function MuiDatePicker({value, setFieldValue, name, minDate, maxDate, helperText
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<FormHelperText id="component-helper-text" sx={{ml: 2, color: error ? '#d32f2f' : "unset"}}>
|
||||
<FormHelperText id="component-helper-text" sx={{ ml: 2, color: error ? "#d32f2f" : "unset" }}>
|
||||
{helperText ? helperText : ""}
|
||||
</FormHelperText>
|
||||
</LocalizationProvider>
|
||||
@@ -69,4 +67,4 @@ function MuiDatePicker({value, setFieldValue, name, minDate, maxDate, helperText
|
||||
);
|
||||
}
|
||||
|
||||
export default MuiDatePicker;
|
||||
export default MuiDatePicker;
|
||||
|
||||
@@ -1,35 +1,32 @@
|
||||
'use client'
|
||||
"use client";
|
||||
|
||||
import {FormControl, FormHelperText, InputLabel, MenuItem, OutlinedInput, Select, Typography} from "@mui/material";
|
||||
import { FormControl, FormHelperText, InputLabel, MenuItem, OutlinedInput, Select, Typography } from "@mui/material";
|
||||
|
||||
function CustomSelect({column, filterParameters, defaultFilterTranslation, setFieldValue}) {
|
||||
function CustomSelect({ column, filterParameters, defaultFilterTranslation, setFieldValue }) {
|
||||
const columnSelectOption = column.columnSelectOption;
|
||||
|
||||
return (
|
||||
<FormControl fullWidth sx={{marginY: 1}}>
|
||||
<FormControl fullWidth sx={{ marginY: 1 }}>
|
||||
<InputLabel id={`label${column.id}`}>{column.header}</InputLabel>
|
||||
<Select
|
||||
labelId={`label${column.id}`}
|
||||
id={column.id}
|
||||
name={`${column.id}.value`}
|
||||
value={filterParameters.value}
|
||||
input={<OutlinedInput label={column.header}/>}
|
||||
input={<OutlinedInput label={column.header} />}
|
||||
onChange={(e) => {
|
||||
setFieldValue(`${column.id}.value`, e.target.value)
|
||||
setFieldValue(`${column.id}.value`, e.target.value);
|
||||
}}
|
||||
>
|
||||
<MenuItem value="">{column.header}</MenuItem>
|
||||
{columnSelectOption.map((option) => (
|
||||
<MenuItem
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
>
|
||||
<MenuItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
<FormHelperText>
|
||||
<Typography variant="button" sx={{color: "#155175"}}>
|
||||
<Typography variant="button" sx={{ color: "#155175" }}>
|
||||
نوع فیلتر: {defaultFilterTranslation}
|
||||
</Typography>
|
||||
</FormHelperText>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'use client'
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Box,
|
||||
@@ -9,49 +9,47 @@ import {
|
||||
MenuItem,
|
||||
OutlinedInput,
|
||||
Select,
|
||||
Typography
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
|
||||
function CustomSelectMultiple({column, filterParameters, defaultFilterTranslation, setFieldValue}) {
|
||||
function CustomSelectMultiple({ column, filterParameters, defaultFilterTranslation, setFieldValue }) {
|
||||
const columnSelectOption = column.columnSelectOption;
|
||||
|
||||
const getLabelForValue = (value) => {
|
||||
const option = columnSelectOption.find(opt => opt.value === value);
|
||||
const option = columnSelectOption.find((opt) => opt.value === value);
|
||||
return option ? option.label : value;
|
||||
};
|
||||
|
||||
return (
|
||||
<FormControl fullWidth sx={{marginY: 1}}>
|
||||
<InputLabel htmlFor="uncontrolled-native"
|
||||
id={`label${column.id}`}>{column.header}</InputLabel>
|
||||
<FormControl fullWidth sx={{ marginY: 1 }}>
|
||||
<InputLabel htmlFor="uncontrolled-native" id={`label${column.id}`}>
|
||||
{column.header}
|
||||
</InputLabel>
|
||||
<Select
|
||||
labelId={`label${column.id}`}
|
||||
id={column.id}
|
||||
value={filterParameters.value}
|
||||
multiple
|
||||
onChange={(e) => {
|
||||
setFieldValue(`${column.id}.value`, e.target.value)
|
||||
setFieldValue(`${column.id}.value`, e.target.value);
|
||||
}}
|
||||
renderValue={(selected) => (
|
||||
<Box sx={{display: 'flex', flexWrap: 'wrap', gap: 0.5}}>
|
||||
<Box sx={{ display: "flex", flexWrap: "wrap", gap: 0.5 }}>
|
||||
{selected.map((value) => (
|
||||
<Chip key={value} label={getLabelForValue(value)}/>
|
||||
<Chip key={value} label={getLabelForValue(value)} />
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
input={<OutlinedInput label={column.header}/>}
|
||||
input={<OutlinedInput label={column.header} />}
|
||||
>
|
||||
{columnSelectOption.map((option) => (
|
||||
<MenuItem
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
>
|
||||
<MenuItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
<FormHelperText>
|
||||
<Typography variant="button" sx={{color: "#155175"}}>
|
||||
<Typography variant="button" sx={{ color: "#155175" }}>
|
||||
نوع فیلتر: {defaultFilterTranslation}
|
||||
</Typography>
|
||||
</FormHelperText>
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import {InputAdornment, TextField, Typography} from "@mui/material";
|
||||
import FilterListIcon from '@mui/icons-material/FilterList';
|
||||
import { InputAdornment, TextField, Typography } from "@mui/material";
|
||||
import FilterListIcon from "@mui/icons-material/FilterList";
|
||||
|
||||
function CustomTextField({
|
||||
column,
|
||||
filterParameters,
|
||||
defaultFilterTranslation,
|
||||
handleOpenFilterBox,
|
||||
handleChange,
|
||||
handleBlur
|
||||
}) {
|
||||
|
||||
column,
|
||||
filterParameters,
|
||||
defaultFilterTranslation,
|
||||
handleOpenFilterBox,
|
||||
handleChange,
|
||||
handleBlur,
|
||||
}) {
|
||||
return (
|
||||
<TextField
|
||||
id={column.id}
|
||||
@@ -19,16 +18,18 @@ function CustomTextField({
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
fullWidth
|
||||
helperText={<Typography variant="button" sx={{color: "#155175"}}>
|
||||
نوع فیلتر: {defaultFilterTranslation}
|
||||
</Typography>}
|
||||
helperText={
|
||||
<Typography variant="button" sx={{ color: "#155175" }}>
|
||||
نوع فیلتر: {defaultFilterTranslation}
|
||||
</Typography>
|
||||
}
|
||||
variant="outlined"
|
||||
size="normal"
|
||||
sx={{marginY: 1}}
|
||||
sx={{ marginY: 1 }}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end" sx={{cursor: "pointer"}} onClick={handleOpenFilterBox}>
|
||||
<FilterListIcon/>
|
||||
<InputAdornment position="end" sx={{ cursor: "pointer" }} onClick={handleOpenFilterBox}>
|
||||
<FilterListIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
@@ -36,4 +37,4 @@ function CustomTextField({
|
||||
);
|
||||
}
|
||||
|
||||
export default CustomTextField;
|
||||
export default CustomTextField;
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import {Box, InputAdornment, TextField, Typography} from "@mui/material";
|
||||
import FilterListIcon from '@mui/icons-material/FilterList';
|
||||
import { Box, InputAdornment, TextField, Typography } from "@mui/material";
|
||||
import FilterListIcon from "@mui/icons-material/FilterList";
|
||||
|
||||
function CustomTextFieldRange({
|
||||
column,
|
||||
filterParameters,
|
||||
defaultFilterTranslation,
|
||||
handleOpenFilterBox,
|
||||
handleChange,
|
||||
handleBlur,
|
||||
errors,
|
||||
touched
|
||||
}) {
|
||||
column,
|
||||
filterParameters,
|
||||
defaultFilterTranslation,
|
||||
handleOpenFilterBox,
|
||||
handleChange,
|
||||
handleBlur,
|
||||
errors,
|
||||
touched,
|
||||
}) {
|
||||
return (
|
||||
<Box sx={{display: "flex"}}>
|
||||
<Box sx={{ display: "flex" }}>
|
||||
<TextField
|
||||
id={`${column.id}.value[0]`}
|
||||
name={`${column.id}.value[0]`}
|
||||
@@ -22,11 +22,14 @@ function CustomTextFieldRange({
|
||||
value={filterParameters.value[0]}
|
||||
fullWidth
|
||||
error={touched?.[`${column.id}`]?.value && Boolean(errors?.[`${column.id}`]?.value)}
|
||||
helperText={<Typography variant="button" sx={{color: "#155175"}}>نوع
|
||||
فیلتر: {defaultFilterTranslation}</Typography>}
|
||||
helperText={
|
||||
<Typography variant="button" sx={{ color: "#155175" }}>
|
||||
نوع فیلتر: {defaultFilterTranslation}
|
||||
</Typography>
|
||||
}
|
||||
variant="outlined"
|
||||
size="normal"
|
||||
sx={{marginY: 1, marginRight: 1}}
|
||||
sx={{ marginY: 1, marginRight: 1 }}
|
||||
/>
|
||||
<TextField
|
||||
id={`${column.id}.value[1]`}
|
||||
@@ -40,11 +43,11 @@ function CustomTextFieldRange({
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
size="normal"
|
||||
sx={{marginY: 1}}
|
||||
sx={{ marginY: 1 }}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end" sx={{cursor: "pointer"}} onClick={handleOpenFilterBox}>
|
||||
<FilterListIcon/>
|
||||
<InputAdornment position="end" sx={{ cursor: "pointer" }} onClick={handleOpenFilterBox}>
|
||||
<FilterListIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
@@ -53,4 +56,4 @@ function CustomTextFieldRange({
|
||||
);
|
||||
}
|
||||
|
||||
export default CustomTextFieldRange;
|
||||
export default CustomTextFieldRange;
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
'use client'
|
||||
"use client";
|
||||
|
||||
import {useState} from "react";
|
||||
import { useState } from "react";
|
||||
import FilterButton from "@/core/components/DataTable/filter/FilterButton";
|
||||
import FilterBody from "@/core/components/DataTable/filter/FilterBody";
|
||||
|
||||
function FilterColumn({columns, user_id, page_name, table_name}) {
|
||||
function FilterColumn({ columns, user_id, page_name, table_name }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FilterButton drawerState={open} setDrawerState={setOpen}/>
|
||||
<FilterBody columns={columns} drawerState={open} setDrawerState={setOpen} user_id={user_id}
|
||||
page_name={page_name} table_name={table_name}/>
|
||||
<FilterButton drawerState={open} setDrawerState={setOpen} />
|
||||
<FilterBody
|
||||
columns={columns}
|
||||
drawerState={open}
|
||||
setDrawerState={setOpen}
|
||||
user_id={user_id}
|
||||
page_name={page_name}
|
||||
table_name={table_name}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,26 +1,17 @@
|
||||
import {parseFromValuesOrFunc} from "@/core/utils/utils";
|
||||
import {TableHead} from "@mui/material";
|
||||
import { parseFromValuesOrFunc } from "@/core/utils/utils";
|
||||
import { TableHead } from "@mui/material";
|
||||
import DataTable_TableHeadRow from "./TableHeadRow";
|
||||
|
||||
const DataTable_TableHead = ({
|
||||
columnVirtualizer,
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_TableHead = ({ columnVirtualizer, table, ...rest }) => {
|
||||
const {
|
||||
getState,
|
||||
options: {
|
||||
enableStickyHeader,
|
||||
layoutMode,
|
||||
muiTableHeadProps,
|
||||
positionToolbarAlertBanner,
|
||||
},
|
||||
refs: {tableHeadRef},
|
||||
options: { enableStickyHeader, layoutMode, muiTableHeadProps, positionToolbarAlertBanner },
|
||||
refs: { tableHeadRef },
|
||||
} = table;
|
||||
const {isFullScreen, showAlertBanner} = getState();
|
||||
const { isFullScreen, showAlertBanner } = getState();
|
||||
|
||||
const tableHeadProps = {
|
||||
...parseFromValuesOrFunc(muiTableHeadProps, {table}),
|
||||
...parseFromValuesOrFunc(muiTableHeadProps, { table }),
|
||||
...rest,
|
||||
};
|
||||
|
||||
@@ -37,28 +28,24 @@ const DataTable_TableHead = ({
|
||||
}
|
||||
}}
|
||||
sx={(theme) => ({
|
||||
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
|
||||
display: layoutMode?.startsWith("grid") ? "grid" : undefined,
|
||||
opacity: 0.97,
|
||||
position: stickyHeader ? 'sticky' : 'relative',
|
||||
top: stickyHeader && layoutMode?.startsWith('grid') ? 0 : undefined,
|
||||
position: stickyHeader ? "sticky" : "relative",
|
||||
top: stickyHeader && layoutMode?.startsWith("grid") ? 0 : undefined,
|
||||
zIndex: stickyHeader ? 2 : undefined,
|
||||
...(parseFromValuesOrFunc(tableHeadProps?.sx, theme)),
|
||||
...parseFromValuesOrFunc(tableHeadProps?.sx, theme),
|
||||
})}
|
||||
>
|
||||
{table
|
||||
.getHeaderGroups()
|
||||
.map((headerGroup, index) => (
|
||||
<DataTable_TableHeadRow
|
||||
columnVirtualizer={columnVirtualizer}
|
||||
headerGroup={headerGroup}
|
||||
key={headerGroup.id}
|
||||
table={table}
|
||||
index={index}
|
||||
/>
|
||||
))
|
||||
}
|
||||
{table.getHeaderGroups().map((headerGroup, index) => (
|
||||
<DataTable_TableHeadRow
|
||||
columnVirtualizer={columnVirtualizer}
|
||||
headerGroup={headerGroup}
|
||||
key={headerGroup.id}
|
||||
table={table}
|
||||
index={index}
|
||||
/>
|
||||
))}
|
||||
</TableHead>
|
||||
);
|
||||
|
||||
}
|
||||
export default DataTable_TableHead
|
||||
};
|
||||
export default DataTable_TableHead;
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
import {getCommonMRTCellStyles, parseFromValuesOrFunc} from "@/core/utils/utils";
|
||||
import {useTheme} from "@emotion/react";
|
||||
import {Box, TableCell} from "@mui/material";
|
||||
import {MRT_TableHeadCellSortLabel} from "material-react-table";
|
||||
import {useMemo} from "react";
|
||||
import { getCommonMRTCellStyles, parseFromValuesOrFunc } from "@/core/utils/utils";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { Box, TableCell } from "@mui/material";
|
||||
import { MRT_TableHeadCellSortLabel } from "material-react-table";
|
||||
import { useMemo } from "react";
|
||||
|
||||
const DataTable_TableHeadCell = ({
|
||||
columnVirtualizer,
|
||||
header,
|
||||
staticColumnIndex,
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_TableHeadCell = ({ columnVirtualizer, header, staticColumnIndex, table, ...rest }) => {
|
||||
const theme = useTheme();
|
||||
const {
|
||||
getState,
|
||||
@@ -24,26 +18,19 @@ const DataTable_TableHeadCell = ({
|
||||
enableGrouping,
|
||||
enableMultiSort,
|
||||
layoutMode,
|
||||
mrtTheme: {draggingBorderColor},
|
||||
mrtTheme: { draggingBorderColor },
|
||||
muiTableHeadCellProps,
|
||||
},
|
||||
refs: {tableHeadCellRefs},
|
||||
refs: { tableHeadCellRefs },
|
||||
setHoveredColumn,
|
||||
} = table;
|
||||
const {
|
||||
columnSizingInfo,
|
||||
density,
|
||||
draggingColumn,
|
||||
grouping,
|
||||
hoveredColumn,
|
||||
showColumnFilters,
|
||||
} = getState();
|
||||
const {column} = header;
|
||||
const {columnDef} = column;
|
||||
const {columnDefType} = columnDef;
|
||||
const { columnSizingInfo, density, draggingColumn, grouping, hoveredColumn, showColumnFilters } = getState();
|
||||
const { column } = header;
|
||||
const { columnDef } = column;
|
||||
const { columnDefType } = columnDef;
|
||||
|
||||
const tableCellProps = {
|
||||
...parseFromValuesOrFunc(muiTableHeadCellProps, {column, table}),
|
||||
...parseFromValuesOrFunc(muiTableHeadCellProps, { column, table }),
|
||||
...parseFromValuesOrFunc(columnDef.muiTableHeadCellProps, {
|
||||
column,
|
||||
table,
|
||||
@@ -51,23 +38,17 @@ const DataTable_TableHeadCell = ({
|
||||
...rest,
|
||||
};
|
||||
|
||||
const isColumnPinned =
|
||||
enableColumnPinning &&
|
||||
columnDef.columnDefType !== 'group' &&
|
||||
column.getIsPinned();
|
||||
const isColumnPinned = enableColumnPinning && columnDef.columnDefType !== "group" && column.getIsPinned();
|
||||
|
||||
const showColumnActions =
|
||||
(enableColumnActions || columnDef.enableColumnActions) &&
|
||||
columnDef.enableColumnActions !== false;
|
||||
(enableColumnActions || columnDef.enableColumnActions) && columnDef.enableColumnActions !== false;
|
||||
|
||||
const showDragHandle =
|
||||
enableColumnDragging !== false &&
|
||||
columnDef.enableColumnDragging !== false &&
|
||||
(enableColumnDragging ||
|
||||
(enableColumnOrdering && columnDef.enableColumnOrdering !== false) ||
|
||||
(enableGrouping &&
|
||||
columnDef.enableGrouping !== false &&
|
||||
!grouping.includes(column.id)));
|
||||
(enableGrouping && columnDef.enableGrouping !== false && !grouping.includes(column.id)));
|
||||
|
||||
const headerPL = useMemo(() => {
|
||||
let pl = 0;
|
||||
@@ -80,41 +61,37 @@ const DataTable_TableHeadCell = ({
|
||||
const draggingBorders = useMemo(() => {
|
||||
const showResizeBorder =
|
||||
columnSizingInfo.isResizingColumn === column.id &&
|
||||
columnResizeMode === 'onChange' &&
|
||||
columnResizeMode === "onChange" &&
|
||||
!header.subHeaders.length;
|
||||
|
||||
const borderStyle = showResizeBorder
|
||||
? `2px solid ${draggingBorderColor} !important`
|
||||
: draggingColumn?.id === column.id
|
||||
? `1px dashed ${theme.palette.grey[500]}`
|
||||
: hoveredColumn?.id === column.id
|
||||
? `2px dashed ${draggingBorderColor}`
|
||||
: undefined;
|
||||
? `1px dashed ${theme.palette.grey[500]}`
|
||||
: hoveredColumn?.id === column.id
|
||||
? `2px dashed ${draggingBorderColor}`
|
||||
: undefined;
|
||||
|
||||
if (showResizeBorder) {
|
||||
return columnResizeDirection === 'ltr'
|
||||
? {borderRight: borderStyle}
|
||||
: {borderLeft: borderStyle};
|
||||
return columnResizeDirection === "ltr" ? { borderRight: borderStyle } : { borderLeft: borderStyle };
|
||||
}
|
||||
const draggingBorders = borderStyle
|
||||
? {
|
||||
borderLeft: borderStyle,
|
||||
borderRight: borderStyle,
|
||||
borderTop: borderStyle,
|
||||
}
|
||||
borderLeft: borderStyle,
|
||||
borderRight: borderStyle,
|
||||
borderTop: borderStyle,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
return draggingBorders;
|
||||
}, [draggingColumn, hoveredColumn, columnSizingInfo.isResizingColumn]);
|
||||
|
||||
const handleDragEnter = (_e) => {
|
||||
if (enableGrouping && hoveredColumn?.id === 'drop-zone') {
|
||||
if (enableGrouping && hoveredColumn?.id === "drop-zone") {
|
||||
setHoveredColumn(null);
|
||||
}
|
||||
if (enableColumnOrdering && draggingColumn && columnDefType !== 'group') {
|
||||
setHoveredColumn(
|
||||
columnDef.enableColumnOrdering !== false ? column : null,
|
||||
);
|
||||
if (enableColumnOrdering && draggingColumn && columnDefType !== "group") {
|
||||
setHoveredColumn(columnDef.enableColumnOrdering !== false ? column : null);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -124,7 +101,6 @@ const DataTable_TableHeadCell = ({
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const HeaderElement =
|
||||
parseFromValuesOrFunc(columnDef.Header, {
|
||||
column,
|
||||
@@ -132,12 +108,9 @@ const DataTable_TableHeadCell = ({
|
||||
table,
|
||||
}) ?? columnDef.header;
|
||||
|
||||
|
||||
const columnRelativeDepth = header.depth - column.depth;
|
||||
|
||||
if (
|
||||
columnRelativeDepth > 1
|
||||
) {
|
||||
if (columnRelativeDepth > 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -149,13 +122,7 @@ const DataTable_TableHeadCell = ({
|
||||
|
||||
return (
|
||||
<TableCell
|
||||
align={
|
||||
columnDefType === 'group'
|
||||
? 'center'
|
||||
: theme.direction === 'rtl'
|
||||
? 'right'
|
||||
: 'left'
|
||||
}
|
||||
align={columnDefType === "group" ? "center" : theme.direction === "rtl" ? "right" : "left"}
|
||||
colSpan={header.colSpan}
|
||||
rowSpan={rowSpan}
|
||||
data-index={staticColumnIndex}
|
||||
@@ -165,123 +132,107 @@ const DataTable_TableHeadCell = ({
|
||||
ref={(node) => {
|
||||
if (node) {
|
||||
tableHeadCellRefs.current[column.id] = node;
|
||||
if (columnDefType !== 'group') {
|
||||
if (columnDefType !== "group") {
|
||||
columnVirtualizer?.measureElement?.(node);
|
||||
}
|
||||
}
|
||||
}}
|
||||
{...tableCellProps}
|
||||
sx={(theme) => ({
|
||||
'& :hover': {
|
||||
'.MuiButtonBase-root': {
|
||||
opacity: 1,
|
||||
},
|
||||
"& :hover": {
|
||||
".MuiButtonBase-root": {
|
||||
opacity: 1,
|
||||
},
|
||||
flexDirection: layoutMode?.startsWith('grid') ? 'column' : undefined,
|
||||
fontWeight: 'bold',
|
||||
overflow: 'visible',
|
||||
p:
|
||||
density === 'compact'
|
||||
? '0.5rem'
|
||||
: density === 'comfortable'
|
||||
? columnDefType === 'display'
|
||||
? '0.75rem'
|
||||
: '1rem'
|
||||
: columnDefType === 'display'
|
||||
? '1rem 1.25rem'
|
||||
: '1.5rem',
|
||||
pb:
|
||||
columnDefType === 'display'
|
||||
? 0
|
||||
: showColumnFilters || density === 'compact'
|
||||
? '0.4rem'
|
||||
: '0.6rem',
|
||||
pt:
|
||||
columnDefType === 'group' || density === 'compact'
|
||||
? '0.25rem'
|
||||
: density === 'comfortable'
|
||||
? '.75rem'
|
||||
: '1.25rem',
|
||||
userSelect: enableMultiSort && column.getCanSort() ? 'none' : undefined,
|
||||
verticalAlign: 'middle',
|
||||
...getCommonMRTCellStyles({
|
||||
column,
|
||||
header,
|
||||
table,
|
||||
tableCellProps,
|
||||
theme,
|
||||
}),
|
||||
...draggingBorders,
|
||||
}
|
||||
)}
|
||||
},
|
||||
flexDirection: layoutMode?.startsWith("grid") ? "column" : undefined,
|
||||
fontWeight: "bold",
|
||||
overflow: "visible",
|
||||
p:
|
||||
density === "compact"
|
||||
? "0.5rem"
|
||||
: density === "comfortable"
|
||||
? columnDefType === "display"
|
||||
? "0.75rem"
|
||||
: "1rem"
|
||||
: columnDefType === "display"
|
||||
? "1rem 1.25rem"
|
||||
: "1.5rem",
|
||||
pb: columnDefType === "display" ? 0 : showColumnFilters || density === "compact" ? "0.4rem" : "0.6rem",
|
||||
pt:
|
||||
columnDefType === "group" || density === "compact"
|
||||
? "0.25rem"
|
||||
: density === "comfortable"
|
||||
? ".75rem"
|
||||
: "1.25rem",
|
||||
userSelect: enableMultiSort && column.getCanSort() ? "none" : undefined,
|
||||
verticalAlign: "middle",
|
||||
...getCommonMRTCellStyles({
|
||||
column,
|
||||
header,
|
||||
table,
|
||||
tableCellProps,
|
||||
theme,
|
||||
}),
|
||||
...draggingBorders,
|
||||
})}
|
||||
>
|
||||
{tableCellProps.children ?? (
|
||||
<Box
|
||||
className="Mui-TableHeadCell-Content"
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
flexDirection:
|
||||
tableCellProps?.align === 'right' ? 'row-reverse' : 'row',
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
flexDirection: tableCellProps?.align === "right" ? "row-reverse" : "row",
|
||||
justifyContent:
|
||||
columnDefType === 'group' ||
|
||||
tableCellProps?.align === 'center'
|
||||
? 'center'
|
||||
columnDefType === "group" || tableCellProps?.align === "center"
|
||||
? "center"
|
||||
: column.getCanResize()
|
||||
? 'space-between'
|
||||
: 'flex-start',
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
? "space-between"
|
||||
: "flex-start",
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
className="Mui-TableHeadCell-Content-Labels"
|
||||
onClick={column.getToggleSortingHandler()}
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
cursor:
|
||||
column.getCanSort() && columnDefType !== 'group'
|
||||
? 'pointer'
|
||||
: undefined,
|
||||
display: 'flex',
|
||||
flexDirection:
|
||||
tableCellProps?.align === 'right' ? 'row-reverse' : 'row',
|
||||
overflow: columnDefType === 'data' ? 'hidden' : undefined,
|
||||
pl:
|
||||
tableCellProps?.align === 'center'
|
||||
? `${headerPL}rem`
|
||||
: undefined,
|
||||
alignItems: "center",
|
||||
cursor: column.getCanSort() && columnDefType !== "group" ? "pointer" : undefined,
|
||||
display: "flex",
|
||||
flexDirection: tableCellProps?.align === "right" ? "row-reverse" : "row",
|
||||
overflow: columnDefType === "data" ? "hidden" : undefined,
|
||||
pl: tableCellProps?.align === "center" ? `${headerPL}rem` : undefined,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
className="Mui-TableHeadCell-Content-Wrapper"
|
||||
sx={{
|
||||
'&:hover': {
|
||||
textOverflow: 'clip',
|
||||
"&:hover": {
|
||||
textOverflow: "clip",
|
||||
},
|
||||
minWidth: `${Math.min(columnDef.header?.length ?? 0, 4)}ch`,
|
||||
overflow: columnDefType === 'data' ? 'hidden' : undefined,
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: columnDefType === "data" ? "hidden" : undefined,
|
||||
textOverflow: "ellipsis",
|
||||
color: "#fff",
|
||||
fontSize: "14px",
|
||||
fontWeight: "500",
|
||||
whiteSpace:
|
||||
(columnDef.header?.length ?? 0) < 20
|
||||
? 'nowrap'
|
||||
: 'normal',
|
||||
whiteSpace: (columnDef.header?.length ?? 0) < 20 ? "nowrap" : "normal",
|
||||
}}
|
||||
>
|
||||
{HeaderElement}
|
||||
</Box>
|
||||
{(column.getCanSort() && columnDefType !== 'group') && (
|
||||
<MRT_TableHeadCellSortLabel sx={{width: 20, color: "#fff"}} header={header}
|
||||
table={table}/>
|
||||
{column.getCanSort() && columnDefType !== "group" && (
|
||||
<MRT_TableHeadCellSortLabel
|
||||
sx={{ width: 20, color: "#fff" }}
|
||||
header={header}
|
||||
table={table}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
</TableCell>
|
||||
);
|
||||
|
||||
}
|
||||
export default DataTable_TableHeadCell;
|
||||
};
|
||||
export default DataTable_TableHeadCell;
|
||||
|
||||
@@ -1,25 +1,20 @@
|
||||
import {parseFromValuesOrFunc} from "@/core/utils/utils";
|
||||
import {TableRow} from "@mui/material";
|
||||
import { parseFromValuesOrFunc } from "@/core/utils/utils";
|
||||
import { TableRow } from "@mui/material";
|
||||
import DataTable_TableHeadCell from "./TableHeadCell";
|
||||
|
||||
const DataTable_TableHeadRow = ({
|
||||
columnVirtualizer,
|
||||
headerGroup,
|
||||
table,
|
||||
index, // Add index prop
|
||||
...rest
|
||||
}) => {
|
||||
columnVirtualizer,
|
||||
headerGroup,
|
||||
table,
|
||||
index, // Add index prop
|
||||
...rest
|
||||
}) => {
|
||||
const {
|
||||
options: {
|
||||
enableStickyHeader,
|
||||
layoutMode,
|
||||
muiTableHeadRowProps,
|
||||
},
|
||||
options: { enableStickyHeader, layoutMode, muiTableHeadRowProps },
|
||||
} = table;
|
||||
const {virtualColumns, virtualPaddingLeft, virtualPaddingRight} =
|
||||
columnVirtualizer ?? {};
|
||||
const { virtualColumns, virtualPaddingLeft, virtualPaddingRight } = columnVirtualizer ?? {};
|
||||
|
||||
const backgroundColor = index % 2 === 0 ? '#015688' : '#ff5c0f';
|
||||
const backgroundColor = index % 2 === 0 ? "#015688" : "#ff5c0f";
|
||||
|
||||
const tableRowProps = {
|
||||
...parseFromValuesOrFunc(muiTableHeadRowProps, {
|
||||
@@ -27,20 +22,23 @@ const DataTable_TableHeadRow = ({
|
||||
table,
|
||||
}),
|
||||
...rest,
|
||||
sx: (theme) => ({ // Access theme from the sx function
|
||||
sx: (theme) => ({
|
||||
// Access theme from the sx function
|
||||
...(parseFromValuesOrFunc(muiTableHeadRowProps?.sx, theme) || {}),
|
||||
backgroundColor, // Apply background color
|
||||
display: layoutMode?.startsWith('grid') ? 'flex' : undefined,
|
||||
position: enableStickyHeader && layoutMode === 'semantic' ? 'sticky' : 'relative',
|
||||
display: layoutMode?.startsWith("grid") ? "flex" : undefined,
|
||||
position: enableStickyHeader && layoutMode === "semantic" ? "sticky" : "relative",
|
||||
top: 0,
|
||||
}),
|
||||
};
|
||||
|
||||
return (
|
||||
<TableRow {...tableRowProps}>
|
||||
{virtualPaddingLeft && <th style={{display: 'flex', width: virtualPaddingLeft}}/>}
|
||||
{virtualPaddingLeft && <th style={{ display: "flex", width: virtualPaddingLeft }} />}
|
||||
{(virtualColumns ?? headerGroup.headers).map((headerOrVirtualHeader, staticColumnIndex) => {
|
||||
const header = columnVirtualizer ? headerGroup.headers[headerOrVirtualHeader.index] : headerOrVirtualHeader;
|
||||
const header = columnVirtualizer
|
||||
? headerGroup.headers[headerOrVirtualHeader.index]
|
||||
: headerOrVirtualHeader;
|
||||
|
||||
return header ? (
|
||||
<DataTable_TableHeadCell
|
||||
@@ -52,9 +50,9 @@ const DataTable_TableHeadRow = ({
|
||||
/>
|
||||
) : null;
|
||||
})}
|
||||
{virtualPaddingRight && <th style={{display: 'flex', width: virtualPaddingRight}}/>}
|
||||
{virtualPaddingRight && <th style={{ display: "flex", width: virtualPaddingRight }} />}
|
||||
</TableRow>
|
||||
);
|
||||
};
|
||||
|
||||
export default DataTable_TableHeadRow;
|
||||
export default DataTable_TableHeadRow;
|
||||
|
||||
@@ -3,10 +3,15 @@ import DataTableProvider from "@/lib/contexts/DataTable";
|
||||
|
||||
const DataTable = (props) => {
|
||||
return (
|
||||
<DataTableProvider>
|
||||
<DataTable_Main {...props}/>
|
||||
<DataTableProvider
|
||||
user_id={props.user_id}
|
||||
page_name={props.page_name}
|
||||
table_name={props.table_name}
|
||||
columns={props.columns}
|
||||
>
|
||||
<DataTable_Main {...props} />
|
||||
</DataTableProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default DataTable;
|
||||
export default DataTable;
|
||||
|
||||
@@ -67,8 +67,7 @@ export const FA_DATATABLE_LOCALIZATION = {
|
||||
rowsPerPage: "ردیف در هر صفحه",
|
||||
save: "ذخیره",
|
||||
search: "جستجو",
|
||||
selectedCountOfRowCountRowsSelected:
|
||||
"{selectedCount} از {rowCount} ردیف انتخاب شده",
|
||||
selectedCountOfRowCountRowsSelected: "{selectedCount} از {rowCount} ردیف انتخاب شده",
|
||||
select: "انتخاب",
|
||||
showAll: "نمایش همه",
|
||||
showAllColumns: "نمایش همه ستونها",
|
||||
@@ -89,4 +88,4 @@ export const FA_DATATABLE_LOCALIZATION = {
|
||||
unpin: "رها کردن",
|
||||
unpinAll: "رها کردن همه",
|
||||
unsorted: "بدون مرتب سازی",
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import { Box, IconButton, ListItemIcon, MenuItem } from "@mui/material";
|
||||
|
||||
const DataTable_ActionMenuItem = ({
|
||||
icon,
|
||||
label,
|
||||
onOpenSubMenu,
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_ActionMenuItem = ({ icon, label, onOpenSubMenu, table, ...rest }) => {
|
||||
const {
|
||||
options: {
|
||||
icons: { ArrowRightIcon },
|
||||
@@ -16,35 +10,29 @@ const DataTable_ActionMenuItem = ({
|
||||
return (
|
||||
<MenuItem
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
minWidth: '120px',
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
minWidth: "120px",
|
||||
my: 0,
|
||||
py: '6px',
|
||||
py: "6px",
|
||||
}}
|
||||
{...rest}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
}}
|
||||
>
|
||||
<ListItemIcon>{icon}</ListItemIcon>
|
||||
{label}
|
||||
</Box>
|
||||
{onOpenSubMenu && (
|
||||
<IconButton
|
||||
onClick={onOpenSubMenu}
|
||||
onMouseEnter={onOpenSubMenu}
|
||||
size="small"
|
||||
sx={{ p: 0 }}
|
||||
>
|
||||
<IconButton onClick={onOpenSubMenu} onMouseEnter={onOpenSubMenu} size="small" sx={{ p: 0 }}>
|
||||
<ArrowRightIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
}
|
||||
export default DataTable_ActionMenuItem
|
||||
};
|
||||
export default DataTable_ActionMenuItem;
|
||||
|
||||
@@ -2,10 +2,7 @@ import { parseFromValuesOrFunc } from "@/core/utils/utils";
|
||||
import { Menu } from "@mui/material";
|
||||
import DataTable_ActionMenuItem from "./ActionMenuItem";
|
||||
|
||||
const DataTable_CellActionMenu = ({
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_CellActionMenu = ({ table, ...rest }) => {
|
||||
const {
|
||||
getState,
|
||||
options: {
|
||||
@@ -32,12 +29,11 @@ const DataTable_CellActionMenu = ({
|
||||
};
|
||||
|
||||
const internalMenuItems = [
|
||||
(parseFromValuesOrFunc(enableClickToCopy, cell) === 'context-menu' ||
|
||||
parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) ===
|
||||
'context-menu') && (
|
||||
(parseFromValuesOrFunc(enableClickToCopy, cell) === "context-menu" ||
|
||||
parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) === "context-menu") && (
|
||||
<DataTable_ActionMenuItem
|
||||
icon={<ContentCopy />}
|
||||
key={'mrt-copy'}
|
||||
key={"mrt-copy"}
|
||||
label={localization.copy}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
@@ -47,10 +43,10 @@ const DataTable_CellActionMenu = ({
|
||||
table={table}
|
||||
/>
|
||||
),
|
||||
parseFromValuesOrFunc(enableEditing, row) && editDisplayMode === 'cell' && (
|
||||
parseFromValuesOrFunc(enableEditing, row) && editDisplayMode === "cell" && (
|
||||
<DataTable_ActionMenuItem
|
||||
icon={<EditIcon />}
|
||||
key={'mrt-edit'}
|
||||
key={"mrt-edit"}
|
||||
label={localization.edit}
|
||||
onClick={() => {
|
||||
openEditingCell({ cell, table });
|
||||
@@ -71,14 +67,13 @@ const DataTable_CellActionMenu = ({
|
||||
};
|
||||
|
||||
const menuItems =
|
||||
columnDef.renderCellActionMenuItems?.(renderActionProps) ??
|
||||
renderCellActionMenuItems?.(renderActionProps);
|
||||
columnDef.renderCellActionMenuItems?.(renderActionProps) ?? renderCellActionMenuItems?.(renderActionProps);
|
||||
|
||||
return (
|
||||
(!!menuItems?.length || !!internalMenuItems?.length) && (
|
||||
<Menu
|
||||
MenuListProps={{
|
||||
dense: density === 'compact',
|
||||
dense: density === "compact",
|
||||
sx: {
|
||||
backgroundColor: menuBackgroundColor,
|
||||
},
|
||||
@@ -95,6 +90,5 @@ const DataTable_CellActionMenu = ({
|
||||
</Menu>
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
export default DataTable_CellActionMenu
|
||||
};
|
||||
export default DataTable_CellActionMenu;
|
||||
|
||||
@@ -2,11 +2,7 @@ import { Box, Button, Divider, Menu } from "@mui/material";
|
||||
import { useMemo, useState } from "react";
|
||||
import DataTable_ShowHideColumnsMenuItems from "./ShowHideColumnsMenuItems";
|
||||
|
||||
const DataTable_ShowHideColumnsMenu = ({ anchorEl,
|
||||
setAnchorEl,
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_ShowHideColumnsMenu = ({ anchorEl, setAnchorEl, table, ...rest }) => {
|
||||
const {
|
||||
getAllColumns,
|
||||
getAllLeafColumns,
|
||||
@@ -36,14 +32,11 @@ const DataTable_ShowHideColumnsMenu = ({ anchorEl,
|
||||
|
||||
const allColumns = useMemo(() => {
|
||||
const columns = getAllColumns();
|
||||
if (
|
||||
columnOrder.length > 0 &&
|
||||
!columns.some((col) => col.columnDef.columnDefType === 'group')
|
||||
) {
|
||||
if (columnOrder.length > 0 && !columns.some((col) => col.columnDef.columnDefType === "group")) {
|
||||
return [
|
||||
...getLeftLeafColumns(),
|
||||
...Array.from(new Set(columnOrder)).map((colId) =>
|
||||
getCenterLeafColumns().find((col) => col?.id === colId),
|
||||
getCenterLeafColumns().find((col) => col?.id === colId)
|
||||
),
|
||||
...getRightLeafColumns(),
|
||||
].filter(Boolean);
|
||||
@@ -58,16 +51,14 @@ const DataTable_ShowHideColumnsMenu = ({ anchorEl,
|
||||
getRightLeafColumns(),
|
||||
]);
|
||||
|
||||
const isNestedColumns = allColumns.some(
|
||||
(col) => col.columnDef.columnDefType === 'group',
|
||||
);
|
||||
const isNestedColumns = allColumns.some((col) => col.columnDef.columnDefType === "group");
|
||||
|
||||
const [hoveredColumn, setHoveredColumn] = useState(null);
|
||||
|
||||
return (
|
||||
<Menu
|
||||
MenuListProps={{
|
||||
dense: density === 'compact',
|
||||
dense: density === "compact",
|
||||
sx: {
|
||||
backgroundColor: menuBackgroundColor,
|
||||
},
|
||||
@@ -80,44 +71,29 @@ const DataTable_ShowHideColumnsMenu = ({ anchorEl,
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
p: '0.5rem',
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
p: "0.5rem",
|
||||
pt: 0,
|
||||
}}
|
||||
>
|
||||
{enableHiding && (
|
||||
<Button
|
||||
disabled={!getIsSomeColumnsVisible()}
|
||||
onClick={() => handleToggleAllColumns(false)}
|
||||
>
|
||||
<Button disabled={!getIsSomeColumnsVisible()} onClick={() => handleToggleAllColumns(false)}>
|
||||
{localization.hideAll}
|
||||
</Button>
|
||||
)}
|
||||
{enableColumnOrdering && (
|
||||
<Button
|
||||
onClick={() =>
|
||||
table.setColumnOrder(
|
||||
getDefaultColumnOrderIds(table.options, true),
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button onClick={() => table.setColumnOrder(getDefaultColumnOrderIds(table.options, true))}>
|
||||
{localization.resetOrder}
|
||||
</Button>
|
||||
)}
|
||||
{enableColumnPinning && (
|
||||
<Button
|
||||
disabled={!getIsSomeColumnsPinned()}
|
||||
onClick={() => table.resetColumnPinning(true)}
|
||||
>
|
||||
<Button disabled={!getIsSomeColumnsPinned()} onClick={() => table.resetColumnPinning(true)}>
|
||||
{localization.unpinAll}
|
||||
</Button>
|
||||
)}
|
||||
{enableHiding && (
|
||||
<Button
|
||||
disabled={getIsAllColumnsVisible()}
|
||||
onClick={() => handleToggleAllColumns(true)}
|
||||
>
|
||||
<Button disabled={getIsAllColumnsVisible()} onClick={() => handleToggleAllColumns(true)}>
|
||||
{localization.showAll}
|
||||
</Button>
|
||||
)}
|
||||
@@ -136,5 +112,5 @@ const DataTable_ShowHideColumnsMenu = ({ anchorEl,
|
||||
))}
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
export default DataTable_ShowHideColumnsMenu
|
||||
};
|
||||
export default DataTable_ShowHideColumnsMenu;
|
||||
|
||||
@@ -30,7 +30,7 @@ const DataTable_ShowHideColumnsMenuItems = ({
|
||||
const switchChecked = column.getIsVisible();
|
||||
|
||||
const handleToggleColumnHidden = (column) => {
|
||||
if (columnDefType === 'group') {
|
||||
if (columnDefType === "group") {
|
||||
column?.columns?.forEach?.((childColumn) => {
|
||||
childColumn.toggleVisibility(!switchChecked);
|
||||
});
|
||||
@@ -78,29 +78,29 @@ const DataTable_ShowHideColumnsMenuItems = ({
|
||||
ref={menuItemRef}
|
||||
{...rest}
|
||||
sx={(theme) => ({
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
my: 0,
|
||||
opacity: isDragging ? 0.5 : 1,
|
||||
outline: isDragging
|
||||
? `2px dashed ${theme.palette.grey[500]}`
|
||||
: hoveredColumn?.id === column.id
|
||||
? `2px dashed ${draggingBorderColor}`
|
||||
: 'none',
|
||||
outlineOffset: '-2px',
|
||||
? `2px dashed ${draggingBorderColor}`
|
||||
: "none",
|
||||
outlineOffset: "-2px",
|
||||
pl: `${(column.depth + 0.5) * 2}rem`,
|
||||
py: '6px',
|
||||
...(parseFromValuesOrFunc(rest?.sx, theme)),
|
||||
py: "6px",
|
||||
...parseFromValuesOrFunc(rest?.sx, theme),
|
||||
})}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexWrap: 'nowrap',
|
||||
gap: '8px',
|
||||
display: "flex",
|
||||
flexWrap: "nowrap",
|
||||
gap: "8px",
|
||||
}}
|
||||
>
|
||||
{columnDefType !== 'group' &&
|
||||
{columnDefType !== "group" &&
|
||||
enableColumnOrdering &&
|
||||
!isNestedColumns &&
|
||||
(columnDef.enableColumnOrdering !== false ? (
|
||||
@@ -110,7 +110,7 @@ const DataTable_ShowHideColumnsMenuItems = ({
|
||||
table={table}
|
||||
/>
|
||||
) : (
|
||||
<Box sx={{ width: '28px' }} />
|
||||
<Box sx={{ width: "28px" }} />
|
||||
))}
|
||||
{enableHiding ? (
|
||||
<FormControlLabel
|
||||
@@ -119,15 +119,12 @@ const DataTable_ShowHideColumnsMenuItems = ({
|
||||
typography: {
|
||||
sx: {
|
||||
mb: 0,
|
||||
opacity: columnDefType !== 'display' ? 1 : 0.5,
|
||||
opacity: columnDefType !== "display" ? 1 : 0.5,
|
||||
},
|
||||
},
|
||||
}}
|
||||
control={
|
||||
<Tooltip
|
||||
{...getCommonTooltipProps()}
|
||||
title={localization.toggleVisibility}
|
||||
>
|
||||
<Tooltip {...getCommonTooltipProps()} title={localization.toggleVisibility}>
|
||||
<Switch />
|
||||
</Tooltip>
|
||||
}
|
||||
@@ -136,9 +133,7 @@ const DataTable_ShowHideColumnsMenuItems = ({
|
||||
onChange={() => handleToggleColumnHidden(column)}
|
||||
/>
|
||||
) : (
|
||||
<Typography sx={{ alignSelf: 'center' }}>
|
||||
{columnDef.header}
|
||||
</Typography>
|
||||
<Typography sx={{ alignSelf: "center" }}>{columnDef.header}</Typography>
|
||||
)}
|
||||
</Box>
|
||||
</MenuItem>
|
||||
@@ -155,6 +150,5 @@ const DataTable_ShowHideColumnsMenuItems = ({
|
||||
))}
|
||||
</>
|
||||
);
|
||||
|
||||
}
|
||||
export default DataTable_ShowHideColumnsMenuItems;
|
||||
};
|
||||
export default DataTable_ShowHideColumnsMenuItems;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
"use client"
|
||||
import {IconButton, Tooltip} from '@mui/material';
|
||||
import RestartAltIcon from '@mui/icons-material/RestartAlt';
|
||||
"use client";
|
||||
import { IconButton, Tooltip } from "@mui/material";
|
||||
import RestartAltIcon from "@mui/icons-material/RestartAlt";
|
||||
import useTableSetting from "@/lib/hooks/useTableSetting";
|
||||
import {useState} from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
function RefactorTable() {
|
||||
const {refactorAction} = useTableSetting();
|
||||
const { refactorAction } = useTableSetting();
|
||||
const [userId, setUserId] = useState(0);
|
||||
const [pageName, setPageName] = useState('testPage');
|
||||
const [tableName, setTableName] = useState('testTable');
|
||||
const [pageName, setPageName] = useState("testPage");
|
||||
const [tableName, setTableName] = useState("testTable");
|
||||
|
||||
const refactor = () => {
|
||||
refactorAction(userId, pageName, tableName);
|
||||
@@ -17,12 +17,10 @@ function RefactorTable() {
|
||||
return (
|
||||
<Tooltip title="بازنشانی اطلاعات">
|
||||
<IconButton onClick={refactor} aria-label="refactor table">
|
||||
<RestartAltIcon/>
|
||||
<RestartAltIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
export default RefactorTable;
|
||||
|
||||
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
import {parseFromValuesOrFunc} from "@/core/utils/utils";
|
||||
import {Paper} from "@mui/material";
|
||||
import { parseFromValuesOrFunc } from "@/core/utils/utils";
|
||||
import { Paper } from "@mui/material";
|
||||
import DataTable_BottomToolbar from "../toolbar/BottomToolbar";
|
||||
import DataTable_TopToolbar from "../toolbar/TopToolbar";
|
||||
import DataTable_TableContainer from "./TableContainer";
|
||||
|
||||
const DataTable_Paper = ({table, ...rest}) => {
|
||||
const DataTable_Paper = ({ table, ...rest }) => {
|
||||
const {
|
||||
getState,
|
||||
options: {
|
||||
enableBottomToolbar,
|
||||
enableTopToolbar,
|
||||
mrtTheme: {baseBackgroundColor},
|
||||
mrtTheme: { baseBackgroundColor },
|
||||
muiTablePaperProps,
|
||||
renderBottomToolbar,
|
||||
renderTopToolbar,
|
||||
},
|
||||
refs: {tablePaperRef},
|
||||
refs: { tablePaperRef },
|
||||
} = table;
|
||||
|
||||
const {isFullScreen} = getState();
|
||||
const { isFullScreen } = getState();
|
||||
|
||||
const paperProps = {
|
||||
...parseFromValuesOrFunc(muiTablePaperProps, {table}),
|
||||
...parseFromValuesOrFunc(muiTablePaperProps, { table }),
|
||||
...rest,
|
||||
};
|
||||
|
||||
@@ -39,42 +39,44 @@ const DataTable_Paper = ({table, ...rest}) => {
|
||||
style={{
|
||||
...(isFullScreen
|
||||
? {
|
||||
bottom: 0,
|
||||
height: '100dvh',
|
||||
left: 0,
|
||||
margin: 0,
|
||||
maxHeight: '100dvh',
|
||||
maxWidth: '100dvw',
|
||||
padding: 0,
|
||||
position: 'fixed',
|
||||
right: 0,
|
||||
top: 0,
|
||||
width: '100dvw',
|
||||
zIndex: 999,
|
||||
}
|
||||
bottom: 0,
|
||||
height: "100dvh",
|
||||
left: 0,
|
||||
margin: 0,
|
||||
maxHeight: "100dvh",
|
||||
maxWidth: "100dvw",
|
||||
padding: 0,
|
||||
position: "fixed",
|
||||
right: 0,
|
||||
top: 0,
|
||||
width: "100dvw",
|
||||
zIndex: 999,
|
||||
}
|
||||
: {}),
|
||||
...paperProps?.style,
|
||||
}}
|
||||
sx={(theme) => ({
|
||||
backgroundColor: baseBackgroundColor,
|
||||
backgroundImage: 'unset',
|
||||
overflow: 'hidden',
|
||||
transition: 'all 100ms ease-in-out',
|
||||
...(parseFromValuesOrFunc(paperProps?.sx, theme)),
|
||||
backgroundImage: "unset",
|
||||
overflow: "hidden",
|
||||
transition: "all 100ms ease-in-out",
|
||||
...parseFromValuesOrFunc(paperProps?.sx, theme),
|
||||
})}
|
||||
>
|
||||
{enableTopToolbar &&
|
||||
(parseFromValuesOrFunc(renderTopToolbar, {table}) ?? (
|
||||
<DataTable_TopToolbar table={table} columns={paperProps.columns} table_url={paperProps.table_url}
|
||||
user_id={paperProps.user_id}
|
||||
page_name={paperProps.page_name}
|
||||
table_name={paperProps.table_name}/>
|
||||
(parseFromValuesOrFunc(renderTopToolbar, { table }) ?? (
|
||||
<DataTable_TopToolbar
|
||||
table={table}
|
||||
columns={paperProps.columns}
|
||||
table_url={paperProps.table_url}
|
||||
user_id={paperProps.user_id}
|
||||
page_name={paperProps.page_name}
|
||||
table_name={paperProps.table_name}
|
||||
/>
|
||||
))}
|
||||
<DataTable_TableContainer table={table}/>
|
||||
<DataTable_TableContainer table={table} />
|
||||
{enableBottomToolbar &&
|
||||
(parseFromValuesOrFunc(renderBottomToolbar, {table}) ?? (
|
||||
<DataTable_BottomToolbar table={table}/>
|
||||
))}
|
||||
(parseFromValuesOrFunc(renderBottomToolbar, { table }) ?? <DataTable_BottomToolbar table={table} />)}
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,10 +5,7 @@ import { useMemo } from "react";
|
||||
import DataTable_TableBody, { Memo_DataTable_TableBody } from "../body/TableBody";
|
||||
import DataTable_TableHead from "../head/TableHead";
|
||||
|
||||
const DataTable_Table = ({
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_Table = ({ table, ...rest }) => {
|
||||
const {
|
||||
getFlatHeaders,
|
||||
getState,
|
||||
@@ -23,8 +20,7 @@ const DataTable_Table = ({
|
||||
renderCaption,
|
||||
},
|
||||
} = table;
|
||||
const { columnSizing, columnSizingInfo, columnVisibility, isFullScreen } =
|
||||
getState();
|
||||
const { columnSizing, columnSizingInfo, columnVisibility, isFullScreen } = getState();
|
||||
|
||||
const tableProps = {
|
||||
...parseFromValuesOrFunc(muiTableProps, { table }),
|
||||
@@ -58,14 +54,14 @@ const DataTable_Table = ({
|
||||
{...tableProps}
|
||||
style={{ ...columnSizeVars, ...tableProps?.style }}
|
||||
sx={(theme) => ({
|
||||
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
|
||||
position: 'relative',
|
||||
...(parseFromValuesOrFunc(tableProps?.sx, theme)),
|
||||
display: layoutMode?.startsWith("grid") ? "grid" : undefined,
|
||||
position: "relative",
|
||||
...parseFromValuesOrFunc(tableProps?.sx, theme),
|
||||
})}
|
||||
>
|
||||
{!!Caption && <caption>{Caption}</caption>}
|
||||
{enableTableHead && <DataTable_TableHead {...commonTableGroupProps} />}
|
||||
{memoMode === 'table-body' || columnSizingInfo.isResizingColumn ? (
|
||||
{memoMode === "table-body" || columnSizingInfo.isResizingColumn ? (
|
||||
<Memo_DataTable_TableBody {...commonTableGroupProps} />
|
||||
) : (
|
||||
<DataTable_TableBody {...commonTableGroupProps} />
|
||||
@@ -73,5 +69,5 @@ const DataTable_Table = ({
|
||||
{/* {enableTableFooter && <MRT_TableFooter {...commonTableGroupProps} />} */}
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
export default DataTable_Table
|
||||
};
|
||||
export default DataTable_Table;
|
||||
|
||||
@@ -5,31 +5,17 @@ import DataTable_CellActionMenu from "../menus/CellActionMenu";
|
||||
import DataTable_Table from "./Table";
|
||||
import DataTable_TableLoadingOverlay from "./TableLoadingOverlay";
|
||||
|
||||
const useIsomorphicLayoutEffect =
|
||||
typeof window !== 'undefined' ? useLayoutEffect : useEffect;
|
||||
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
||||
|
||||
const DataTable_TableContainer = ({
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_TableContainer = ({ table, ...rest }) => {
|
||||
const {
|
||||
getState,
|
||||
options: {
|
||||
enableCellActions,
|
||||
enableStickyHeader,
|
||||
muiTableContainerProps,
|
||||
},
|
||||
options: { enableCellActions, enableStickyHeader, muiTableContainerProps },
|
||||
refs: { bottomToolbarRef, tableContainerRef, topToolbarRef },
|
||||
} = table;
|
||||
const {
|
||||
actionCell,
|
||||
isFullScreen,
|
||||
isLoading,
|
||||
showLoadingOverlay,
|
||||
} = getState();
|
||||
const { actionCell, isFullScreen, isLoading, showLoadingOverlay } = getState();
|
||||
|
||||
const loading =
|
||||
showLoadingOverlay !== false && (isLoading || showLoadingOverlay);
|
||||
const loading = showLoadingOverlay !== false && (isLoading || showLoadingOverlay);
|
||||
|
||||
const [totalToolbarHeight, setTotalToolbarHeight] = useState(0);
|
||||
|
||||
@@ -41,15 +27,9 @@ const DataTable_TableContainer = ({
|
||||
};
|
||||
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
const topToolbarHeight =
|
||||
typeof document !== 'undefined'
|
||||
? topToolbarRef.current?.offsetHeight ?? 0
|
||||
: 0;
|
||||
const topToolbarHeight = typeof document !== "undefined" ? topToolbarRef.current?.offsetHeight ?? 0 : 0;
|
||||
|
||||
const bottomToolbarHeight =
|
||||
typeof document !== 'undefined'
|
||||
? bottomToolbarRef?.current?.offsetHeight ?? 0
|
||||
: 0;
|
||||
const bottomToolbarHeight = typeof document !== "undefined" ? bottomToolbarRef?.current?.offsetHeight ?? 0 : 0;
|
||||
|
||||
setTotalToolbarHeight(topToolbarHeight + bottomToolbarHeight);
|
||||
});
|
||||
@@ -57,7 +37,7 @@ const DataTable_TableContainer = ({
|
||||
return (
|
||||
<TableContainer
|
||||
aria-busy={loading}
|
||||
aria-describedby={loading ? 'mrt-progress' : undefined}
|
||||
aria-describedby={loading ? "mrt-progress" : undefined}
|
||||
{...tableContainerProps}
|
||||
ref={(node) => {
|
||||
if (node) {
|
||||
@@ -69,19 +49,17 @@ const DataTable_TableContainer = ({
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
maxHeight: isFullScreen
|
||||
? `calc(100vh - ${totalToolbarHeight}px)`
|
||||
: undefined,
|
||||
maxHeight: isFullScreen ? `calc(100vh - ${totalToolbarHeight}px)` : undefined,
|
||||
...tableContainerProps?.style,
|
||||
}}
|
||||
sx={(theme) => ({
|
||||
maxHeight: enableStickyHeader
|
||||
? `clamp(350px, calc(100vh - ${totalToolbarHeight}px), 9999px)`
|
||||
: undefined,
|
||||
maxWidth: '100%',
|
||||
overflow: 'auto',
|
||||
position: 'relative',
|
||||
...(parseFromValuesOrFunc(tableContainerProps?.sx, theme)),
|
||||
maxWidth: "100%",
|
||||
overflow: "auto",
|
||||
position: "relative",
|
||||
...parseFromValuesOrFunc(tableContainerProps?.sx, theme),
|
||||
})}
|
||||
>
|
||||
{loading ? <DataTable_TableLoadingOverlay table={table} /> : null}
|
||||
@@ -89,6 +67,5 @@ const DataTable_TableContainer = ({
|
||||
{enableCellActions && actionCell && <DataTable_CellActionMenu table={table} />}
|
||||
</TableContainer>
|
||||
);
|
||||
|
||||
}
|
||||
export default DataTable_TableContainer
|
||||
};
|
||||
export default DataTable_TableContainer;
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { Box, CircularProgress } from "@mui/material";
|
||||
|
||||
const DataTable_TableLoadingOverlay = ({
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_TableLoadingOverlay = ({ table, ...rest }) => {
|
||||
const {
|
||||
options: {
|
||||
localization,
|
||||
@@ -20,17 +17,17 @@ const DataTable_TableLoadingOverlay = ({
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
alignItems: "center",
|
||||
backgroundColor: alpha(baseBackgroundColor, 0.5),
|
||||
bottom: 0,
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
left: 0,
|
||||
maxHeight: '100vh',
|
||||
position: 'absolute',
|
||||
maxHeight: "100vh",
|
||||
position: "absolute",
|
||||
right: 0,
|
||||
top: 0,
|
||||
width: '100%',
|
||||
width: "100%",
|
||||
zIndex: 3,
|
||||
}}
|
||||
>
|
||||
@@ -43,6 +40,5 @@ const DataTable_TableLoadingOverlay = ({
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
|
||||
}
|
||||
export default DataTable_TableLoadingOverlay
|
||||
};
|
||||
export default DataTable_TableLoadingOverlay;
|
||||
|
||||
@@ -3,23 +3,15 @@ import { Box, alpha, useMediaQuery } from "@mui/material";
|
||||
import DataTable_LinearProgressBar from "./LinearProgressBar";
|
||||
import DataTable_TablePagination from "./TablePagination";
|
||||
|
||||
const DataTable_BottomToolbar = ({
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_BottomToolbar = ({ table, ...rest }) => {
|
||||
const {
|
||||
getState,
|
||||
options: {
|
||||
enablePagination,
|
||||
muiBottomToolbarProps,
|
||||
positionPagination,
|
||||
renderBottomToolbarCustomActions,
|
||||
},
|
||||
options: { enablePagination, muiBottomToolbarProps, positionPagination, renderBottomToolbarCustomActions },
|
||||
refs: { bottomToolbarRef },
|
||||
} = table;
|
||||
const { isFullScreen } = getState();
|
||||
|
||||
const isMobile = useMediaQuery('(max-width:720px)');
|
||||
const isMobile = useMediaQuery("(max-width:720px)");
|
||||
const toolbarProps = {
|
||||
...parseFromValuesOrFunc(muiBottomToolbarProps, { table }),
|
||||
...rest,
|
||||
@@ -40,49 +32,41 @@ const DataTable_BottomToolbar = ({
|
||||
}}
|
||||
sx={(theme) => ({
|
||||
...getCommonToolbarStyles({ table, theme }),
|
||||
bottom: isFullScreen ? '0' : undefined,
|
||||
boxShadow: `0 1px 2px -1px ${alpha(
|
||||
theme.palette.grey[700],
|
||||
0.5,
|
||||
)} inset`,
|
||||
bottom: isFullScreen ? "0" : undefined,
|
||||
boxShadow: `0 1px 2px -1px ${alpha(theme.palette.grey[700], 0.5)} inset`,
|
||||
left: 0,
|
||||
position: isFullScreen ? 'fixed' : 'relative',
|
||||
position: isFullScreen ? "fixed" : "relative",
|
||||
right: 0,
|
||||
...(parseFromValuesOrFunc(toolbarProps?.sx, theme)),
|
||||
...parseFromValuesOrFunc(toolbarProps?.sx, theme),
|
||||
})}
|
||||
>
|
||||
<DataTable_LinearProgressBar isTopToolbar={false} table={table} />
|
||||
<Box
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
boxSizing: 'border-box',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
p: '0.5rem',
|
||||
width: '100%',
|
||||
alignItems: "center",
|
||||
boxSizing: "border-box",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
p: "0.5rem",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{renderBottomToolbarCustomActions ? (
|
||||
renderBottomToolbarCustomActions({ table })
|
||||
) : (
|
||||
<span />
|
||||
)}
|
||||
{renderBottomToolbarCustomActions ? renderBottomToolbarCustomActions({ table }) : <span />}
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
position: stackAlertBanner ? 'relative' : 'absolute',
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
position: stackAlertBanner ? "relative" : "absolute",
|
||||
right: 0,
|
||||
top: 0,
|
||||
}}
|
||||
>
|
||||
{enablePagination &&
|
||||
['both', 'bottom'].includes(positionPagination ?? '') && (
|
||||
<DataTable_TablePagination position="bottom" table={table} />
|
||||
)}
|
||||
{enablePagination && ["both", "bottom"].includes(positionPagination ?? "") && (
|
||||
<DataTable_TablePagination position="bottom" table={table} />
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
export default DataTable_BottomToolbar
|
||||
};
|
||||
export default DataTable_BottomToolbar;
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import { parseFromValuesOrFunc } from "@/core/utils/utils";
|
||||
import { Collapse, LinearProgress } from "@mui/material";
|
||||
|
||||
const DataTable_LinearProgressBar = ({
|
||||
isTopToolbar,
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_LinearProgressBar = ({ isTopToolbar, table, ...rest }) => {
|
||||
const {
|
||||
getState,
|
||||
options: { muiLinearProgressProps },
|
||||
@@ -26,19 +22,19 @@ const DataTable_LinearProgressBar = ({
|
||||
mountOnEnter
|
||||
sx={{
|
||||
bottom: isTopToolbar ? 0 : undefined,
|
||||
position: 'absolute',
|
||||
position: "absolute",
|
||||
top: !isTopToolbar ? 0 : undefined,
|
||||
width: '100%',
|
||||
width: "100%",
|
||||
}}
|
||||
unmountOnExit
|
||||
>
|
||||
<LinearProgress
|
||||
aria-busy="true"
|
||||
aria-label="Loading"
|
||||
sx={{ position: 'relative' }}
|
||||
sx={{ position: "relative" }}
|
||||
{...linearProgressProps}
|
||||
/>
|
||||
</Collapse>
|
||||
);
|
||||
}
|
||||
export default DataTable_LinearProgressBar
|
||||
};
|
||||
export default DataTable_LinearProgressBar;
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
import { flipIconStyles, getCommonTooltipProps, parseFromValuesOrFunc } from "@/core/utils/utils";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { Box, IconButton, InputLabel, MenuItem, Pagination, PaginationItem, Select, Tooltip, Typography, useMediaQuery } from "@mui/material";
|
||||
import {
|
||||
Box,
|
||||
IconButton,
|
||||
InputLabel,
|
||||
MenuItem,
|
||||
Pagination,
|
||||
PaginationItem,
|
||||
Select,
|
||||
Tooltip,
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
} from "@mui/material";
|
||||
|
||||
const defaultRowsPerPage = [5, 10, 15, 20, 25, 30, 50, 100];
|
||||
|
||||
const DataTable_TablePagination = ({
|
||||
position = 'bottom',
|
||||
table,
|
||||
...rest
|
||||
}) => {
|
||||
const DataTable_TablePagination = ({ position = "bottom", table, ...rest }) => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery('(max-width: 720px)');
|
||||
const isMobile = useMediaQuery("(max-width: 720px)");
|
||||
|
||||
const {
|
||||
getState,
|
||||
@@ -64,26 +71,21 @@ const DataTable_TablePagination = ({
|
||||
<Box
|
||||
className="MuiTablePagination-root"
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
gap: '8px',
|
||||
justifyContent: { md: 'space-between', sm: 'center' },
|
||||
justifySelf: 'flex-end',
|
||||
mt:
|
||||
position === 'top' &&
|
||||
enableToolbarInternalActions &&
|
||||
!showGlobalFilter
|
||||
? '3rem'
|
||||
: undefined,
|
||||
position: 'relative',
|
||||
px: '8px',
|
||||
py: '12px',
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
gap: "8px",
|
||||
justifyContent: { md: "space-between", sm: "center" },
|
||||
justifySelf: "flex-end",
|
||||
mt: position === "top" && enableToolbarInternalActions && !showGlobalFilter ? "3rem" : undefined,
|
||||
position: "relative",
|
||||
px: "8px",
|
||||
py: "12px",
|
||||
zIndex: 2,
|
||||
}}
|
||||
>
|
||||
{showRowsPerPage && (
|
||||
<Box sx={{ alignItems: 'center', display: 'flex', gap: '8px' }}>
|
||||
<Box sx={{ alignItems: "center", display: "flex", gap: "8px" }}>
|
||||
<InputLabel htmlFor="mrt-rows-per-page" sx={{ mb: 0 }}>
|
||||
{localization.rowsPerPage}
|
||||
</InputLabel>
|
||||
@@ -92,22 +94,19 @@ const DataTable_TablePagination = ({
|
||||
disableUnderline
|
||||
disabled={disabled}
|
||||
inputProps={{
|
||||
'aria-label': localization.rowsPerPage,
|
||||
id: 'mrt-rows-per-page',
|
||||
"aria-label": localization.rowsPerPage,
|
||||
id: "mrt-rows-per-page",
|
||||
}}
|
||||
label={localization.rowsPerPage}
|
||||
onChange={(event) =>
|
||||
table.setPageSize(+(event.target.value))
|
||||
}
|
||||
onChange={(event) => table.setPageSize(+event.target.value)}
|
||||
sx={{ mb: 0 }}
|
||||
value={pageSize}
|
||||
variant="standard"
|
||||
{...SelectProps}
|
||||
>
|
||||
{rowsPerPageOptions.map((option) => {
|
||||
const value = typeof option !== 'number' ? option.value : option;
|
||||
const label =
|
||||
typeof option !== 'number' ? option.label : `${option}`;
|
||||
const value = typeof option !== "number" ? option.value : option;
|
||||
const label = typeof option !== "number" ? option.label : `${option}`;
|
||||
return (
|
||||
SelectProps?.children ??
|
||||
(SelectProps?.native ? (
|
||||
@@ -124,7 +123,7 @@ const DataTable_TablePagination = ({
|
||||
</Select>
|
||||
</Box>
|
||||
)}
|
||||
{paginationDisplayMode === 'pages' ? (
|
||||
{paginationDisplayMode === "pages" ? (
|
||||
<Pagination
|
||||
count={numberOfPages}
|
||||
disabled={disabled}
|
||||
@@ -145,16 +144,18 @@ const DataTable_TablePagination = ({
|
||||
showLastButton={showLastButton}
|
||||
{...restPaginationProps}
|
||||
/>
|
||||
) : paginationDisplayMode === 'default' ? (
|
||||
) : paginationDisplayMode === "default" ? (
|
||||
<>
|
||||
<Typography
|
||||
align="center"
|
||||
component="span"
|
||||
sx={{ m: '0 4px', minWidth: '8ch' }}
|
||||
sx={{ m: "0 4px", minWidth: "8ch" }}
|
||||
variant="body2"
|
||||
>{`${lastRowIndex === 0 ? 0 : (firstRowIndex + 1).toLocaleString()
|
||||
}-${lastRowIndex.toLocaleString()} ${localization.of
|
||||
} ${totalRowCount.toLocaleString()}`}</Typography>
|
||||
>{`${
|
||||
lastRowIndex === 0 ? 0 : (firstRowIndex + 1).toLocaleString()
|
||||
}-${lastRowIndex.toLocaleString()} ${
|
||||
localization.of
|
||||
} ${totalRowCount.toLocaleString()}`}</Typography>
|
||||
<Box gap="xs">
|
||||
{showFirstButton && (
|
||||
<Tooltip {...tooltipProps} title={localization.goToFirstPage}>
|
||||
@@ -213,5 +214,5 @@ const DataTable_TablePagination = ({
|
||||
) : null}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
export default DataTable_TablePagination
|
||||
};
|
||||
export default DataTable_TablePagination;
|
||||
|
||||
@@ -16,32 +16,29 @@ const DataTable_ToolbarInternalButtons = ({ table, ...rest }) => {
|
||||
},
|
||||
} = table;
|
||||
|
||||
|
||||
return (
|
||||
<Box
|
||||
{...rest}
|
||||
sx={(theme) => ({
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
zIndex: 3,
|
||||
...(parseFromValuesOrFunc(rest?.sx, theme)),
|
||||
...parseFromValuesOrFunc(rest?.sx, theme),
|
||||
})}
|
||||
>
|
||||
{renderToolbarInternalActions?.({
|
||||
table,
|
||||
}) ?? (
|
||||
<>
|
||||
{enableFilters &&
|
||||
enableColumnFilters &&
|
||||
columnFilterDisplayMode !== 'popover' && (
|
||||
<DataTable_ToggleFiltersButton table={table} />
|
||||
)}
|
||||
{(enableHiding || enableColumnOrdering || enableColumnPinning) && (
|
||||
<DataTable_ShowHideColumnsButton table={table} />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<>
|
||||
{enableFilters && enableColumnFilters && columnFilterDisplayMode !== "popover" && (
|
||||
<DataTable_ToggleFiltersButton table={table} />
|
||||
)}
|
||||
{(enableHiding || enableColumnOrdering || enableColumnPinning) && (
|
||||
<DataTable_ShowHideColumnsButton table={table} />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
export default DataTable_ToolbarInternalButtons
|
||||
};
|
||||
export default DataTable_ToolbarInternalButtons;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import {getCommonToolbarStyles, parseFromValuesOrFunc} from "@/core/utils/utils";
|
||||
import {Box, useMediaQuery} from "@mui/material";
|
||||
import { getCommonToolbarStyles, parseFromValuesOrFunc } from "@/core/utils/utils";
|
||||
import { Box, useMediaQuery } from "@mui/material";
|
||||
import DataTable_LinearProgressBar from "./LinearProgressBar";
|
||||
import DataTable_TablePagination from "./TablePagination";
|
||||
import DataTable_ToolbarInternalButtons from "./ToolbarInternalButtons";
|
||||
import FilterColumn from "@/core/components/DataTable/filter";
|
||||
import RefactorTable from "@/core/components/DataTable/refactor/RefactorTable";
|
||||
|
||||
const DataTable_TopToolbar = ({table, columns, table_url, user_id, page_name, table_name}) => {
|
||||
const DataTable_TopToolbar = ({ table, columns, table_url, user_id, page_name, table_name }) => {
|
||||
const {
|
||||
getState,
|
||||
options: {
|
||||
@@ -16,19 +16,16 @@ const DataTable_TopToolbar = ({table, columns, table_url, user_id, page_name, ta
|
||||
positionPagination,
|
||||
renderTopToolbarCustomActions,
|
||||
},
|
||||
refs: {topToolbarRef},
|
||||
refs: { topToolbarRef },
|
||||
} = table;
|
||||
const {isFullScreen, showGlobalFilter} = getState();
|
||||
const { isFullScreen, showGlobalFilter } = getState();
|
||||
|
||||
const isMobile = useMediaQuery('(max-width:720px)');
|
||||
const isTablet = useMediaQuery('(max-width:1024px)');
|
||||
const isMobile = useMediaQuery("(max-width:720px)");
|
||||
const isTablet = useMediaQuery("(max-width:1024px)");
|
||||
|
||||
const toolbarProps = parseFromValuesOrFunc(muiTopToolbarProps, {table});
|
||||
const toolbarProps = parseFromValuesOrFunc(muiTopToolbarProps, { table });
|
||||
|
||||
const stackAlertBanner =
|
||||
isMobile ||
|
||||
!!renderTopToolbarCustomActions ||
|
||||
(showGlobalFilter && isTablet);
|
||||
const stackAlertBanner = isMobile || !!renderTopToolbarCustomActions || (showGlobalFilter && isTablet);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@@ -41,51 +38,55 @@ const DataTable_TopToolbar = ({table, columns, table_url, user_id, page_name, ta
|
||||
}
|
||||
}}
|
||||
sx={(theme) => ({
|
||||
...getCommonToolbarStyles({table, theme}),
|
||||
position: isFullScreen ? 'sticky' : 'relative',
|
||||
top: isFullScreen ? '0' : undefined,
|
||||
...(parseFromValuesOrFunc(toolbarProps?.sx, theme)),
|
||||
...getCommonToolbarStyles({ table, theme }),
|
||||
position: isFullScreen ? "sticky" : "relative",
|
||||
top: isFullScreen ? "0" : undefined,
|
||||
...parseFromValuesOrFunc(toolbarProps?.sx, theme),
|
||||
})}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
alignItems: 'flex-start',
|
||||
boxSizing: 'border-box',
|
||||
display: 'flex',
|
||||
gap: '0.5rem',
|
||||
justifyContent: 'space-between',
|
||||
p: '0.5rem',
|
||||
position: stackAlertBanner ? 'relative' : 'absolute',
|
||||
alignItems: "flex-start",
|
||||
boxSizing: "border-box",
|
||||
display: "flex",
|
||||
gap: "0.5rem",
|
||||
justifyContent: "space-between",
|
||||
p: "0.5rem",
|
||||
position: stackAlertBanner ? "relative" : "absolute",
|
||||
right: 0,
|
||||
top: 0,
|
||||
width: '100%',
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{renderTopToolbarCustomActions?.({table}) ?? <span/>}
|
||||
{renderTopToolbarCustomActions?.({ table }) ?? <span />}
|
||||
{enableToolbarInternalActions && (
|
||||
<Box
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap-reverse',
|
||||
gap: '0.5rem',
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
flexWrap: "wrap-reverse",
|
||||
gap: "0.5rem",
|
||||
justifyContent: "flex-end",
|
||||
}}
|
||||
>
|
||||
<RefactorTable/>
|
||||
<FilterColumn columns={columns} table_url={table_url} user_id={user_id} page_name={page_name}
|
||||
table_name={table_name}/>
|
||||
<DataTable_ToolbarInternalButtons table={table}/>
|
||||
<RefactorTable />
|
||||
<FilterColumn
|
||||
columns={columns}
|
||||
table_url={table_url}
|
||||
user_id={user_id}
|
||||
page_name={page_name}
|
||||
table_name={table_name}
|
||||
/>
|
||||
<DataTable_ToolbarInternalButtons table={table} />
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
{enablePagination &&
|
||||
['both', 'top'].includes(positionPagination ?? '') && (
|
||||
<DataTable_TablePagination position="top" table={table}/>
|
||||
)}
|
||||
<DataTable_LinearProgressBar isTopToolbar table={table}/>
|
||||
{enablePagination && ["both", "top"].includes(positionPagination ?? "") && (
|
||||
<DataTable_TablePagination position="top" table={table} />
|
||||
)}
|
||||
<DataTable_LinearProgressBar isTopToolbar table={table} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default DataTable_TopToolbar
|
||||
export default DataTable_TopToolbar;
|
||||
|
||||
Reference in New Issue
Block a user