Feature/user management

This commit is contained in:
AmirHossein Mahmoodi
2025-05-10 05:31:24 +00:00
parent bc59952f7b
commit f07d27b273
101 changed files with 7136 additions and 14 deletions

View File

@@ -0,0 +1,102 @@
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,
table_name,
columns,
user_id,
page_name,
mutate,
need_filter,
table_url,
table_title,
setFilterData,
...rest
}) => {
const {
getState,
options: {
enableBottomToolbar,
enableTopToolbar,
mrtTheme: { baseBackgroundColor },
muiTablePaperProps,
renderBottomToolbar,
renderTopToolbar,
},
refs: { tablePaperRef },
} = table;
const { isFullScreen } = getState();
const paperProps = {
...parseFromValuesOrFunc(muiTablePaperProps, { table }),
...rest,
};
return (
<Paper
elevation={0}
{...paperProps}
ref={(ref) => {
tablePaperRef.current = ref;
if (paperProps?.ref) {
//@ts-ignore
paperProps.ref.current = ref;
}
}}
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,
}
: {}),
...paperProps?.style,
}}
sx={(theme) => ({
backgroundColor: baseBackgroundColor,
backgroundImage: "unset",
overflow: "hidden",
transition: "all 100ms ease-in-out",
...parseFromValuesOrFunc(paperProps?.sx, theme),
})}
>
{enableTopToolbar &&
(parseFromValuesOrFunc(renderTopToolbar, { table }) ?? (
<DataTable_TopToolbar
need_filter={need_filter}
table={table}
mutate={mutate}
columns={columns}
table_url={table_url}
user_id={user_id}
page_name={page_name}
table_name={table_name}
table_title={table_title}
setFilterData={setFilterData}
{...paperProps}
/>
))}
<DataTable_TableContainer table={table} />
{enableBottomToolbar &&
(parseFromValuesOrFunc(renderBottomToolbar, { table }) ?? (
<DataTable_BottomToolbar table={table} />
))}
</Paper>
);
};
export default DataTable_Paper;

View File

@@ -0,0 +1,76 @@
import { parseCSSVarId, parseFromValuesOrFunc } from "@/core/utils/utils";
import { Table } from "@mui/material";
import { useMRT_ColumnVirtualizer } from "material-react-table";
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 {
getFlatHeaders,
getState,
options: {
columns,
enableStickyHeader,
enableTableFooter,
enableTableHead,
layoutMode,
memoMode,
muiTableProps,
renderCaption,
},
} = table;
const { columnSizing, columnSizingInfo, columnVisibility, isFullScreen } =
getState();
const tableProps = {
...parseFromValuesOrFunc(muiTableProps, { table }),
...rest,
};
const Caption = parseFromValuesOrFunc(renderCaption, { table });
const columnSizeVars = useMemo(() => {
const headers = getFlatHeaders();
const colSizes = {};
for (let i = 0; i < headers.length; i++) {
const header = headers[i];
const colSize = header.getSize();
colSizes[`--header-${parseCSSVarId(header.id)}-size`] = colSize;
colSizes[`--col-${parseCSSVarId(header.column.id)}-size`] = colSize;
}
return colSizes;
}, [columns, columnSizing, columnSizingInfo, columnVisibility]);
const columnVirtualizer = useMRT_ColumnVirtualizer(table);
const commonTableGroupProps = {
columnVirtualizer,
table,
};
return (
<Table
stickyHeader={enableStickyHeader || isFullScreen}
{...tableProps}
style={{ ...columnSizeVars, ...tableProps?.style }}
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 ? (
<Memo_DataTable_TableBody {...commonTableGroupProps} />
) : (
<DataTable_TableBody {...commonTableGroupProps} />
)}
{/* {enableTableFooter && <MRT_TableFooter {...commonTableGroupProps} />} */}
</Table>
);
};
export default DataTable_Table;

View File

@@ -0,0 +1,84 @@
import { parseFromValuesOrFunc } from "@/core/utils/utils";
import { TableContainer } from "@mui/material";
import { useEffect, useLayoutEffect, useState } from "react";
import DataTable_CellActionMenu from "../menus/CellActionMenu";
import DataTable_Table from "./Table";
import DataTable_TableLoadingOverlay from "./TableLoadingOverlay";
const useIsomorphicLayoutEffect =
typeof window !== "undefined" ? useLayoutEffect : useEffect;
const DataTable_TableContainer = ({ table, ...rest }) => {
const {
getState,
options: { enableCellActions, enableStickyHeader, muiTableContainerProps },
refs: { bottomToolbarRef, tableContainerRef, topToolbarRef },
} = table;
const { actionCell, isFullScreen, isLoading, showLoadingOverlay } =
getState();
const loading =
showLoadingOverlay !== false && (isLoading || showLoadingOverlay);
const [totalToolbarHeight, setTotalToolbarHeight] = useState(0);
const tableContainerProps = {
...parseFromValuesOrFunc(muiTableContainerProps, {
table,
}),
...rest,
};
useIsomorphicLayoutEffect(() => {
const topToolbarHeight =
typeof document !== "undefined"
? (topToolbarRef.current?.offsetHeight ?? 0)
: 0;
const bottomToolbarHeight =
typeof document !== "undefined"
? (bottomToolbarRef?.current?.offsetHeight ?? 0)
: 0;
setTotalToolbarHeight(topToolbarHeight + bottomToolbarHeight);
});
return (
<TableContainer
aria-busy={loading}
aria-describedby={loading ? "mrt-progress" : undefined}
{...tableContainerProps}
ref={(node) => {
if (node) {
tableContainerRef.current = node;
if (tableContainerProps?.ref) {
//@ts-ignore
tableContainerProps.ref.current = node;
}
}
}}
style={{
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),
})}
>
{loading ? <DataTable_TableLoadingOverlay table={table} /> : null}
<DataTable_Table table={table} />
{enableCellActions && actionCell && (
<DataTable_CellActionMenu table={table} />
)}
</TableContainer>
);
};
export default DataTable_TableContainer;

View File

@@ -0,0 +1,44 @@
import { Box, CircularProgress } from "@mui/material";
const DataTable_TableLoadingOverlay = ({ table, ...rest }) => {
const {
options: {
localization,
mrtTheme: { baseBackgroundColor },
muiCircularProgressProps,
},
} = table;
const circularProgressProps = {
...parseFromValuesOrFunc(muiCircularProgressProps, { table }),
...rest,
};
return (
<Box
sx={{
alignItems: "center",
backgroundColor: alpha(baseBackgroundColor, 0.5),
bottom: 0,
display: "flex",
justifyContent: "center",
left: 0,
maxHeight: "100vh",
position: "absolute",
right: 0,
top: 0,
width: "100%",
zIndex: 3,
}}
>
{circularProgressProps?.Component ?? (
<CircularProgress
aria-label={localization.noRecordsToDisplay}
id="mrt-progress"
{...circularProgressProps}
/>
)}
</Box>
);
};
export default DataTable_TableLoadingOverlay;