feat: modules and module-editor pages

This commit is contained in:
2025-10-25 12:11:14 +04:00
parent 57a7ab0871
commit 2bdbebc453
40 changed files with 3485 additions and 38 deletions

View File

@ -0,0 +1,112 @@
import { useMemo } from "react";
import {
IconChevronDown,
IconChevronsDown,
IconChevronsRight,
IconChevronsUp,
IconChevronUp,
} from "@tabler/icons-react";
import { DataTableColumn } from "mantine-datatable";
import { Box, Group, Text, Tooltip } from "@mantine/core";
import useModulesActions from "@/app/modules/hooks/useModulesTableActions";
import UpdateDeleteTableActions from "@/components/ui/BaseTable/components/UpdateDeleteTableActions";
import useIsMobile from "@/hooks/utils/useIsMobile";
import { ModuleWithAttributesSchema } from "@/lib/client";
import { useModulesContext } from "../contexts/ModulesContext";
type Props = {
expandedModuleIds: number[];
setExpandedModuleIds: (ids: number[]) => void;
};
const useModulesTableColumns = ({
expandedModuleIds,
setExpandedModuleIds,
}: Props) => {
const isMobile = useIsMobile();
const { modules, refetchModules } = useModulesContext();
const { onUpdate, onDelete } = useModulesActions({ refetchModules });
const onExpandAllClick = () => {
if (expandedModuleIds.length !== modules.length) {
setExpandedModuleIds(modules.map(c => c.id));
return;
}
setExpandedModuleIds([]);
};
const getExpandAllIcon = () => {
if (expandedModuleIds.length === modules.length)
return <IconChevronsUp />;
if (expandedModuleIds.length === 0) return <IconChevronsDown />;
return <IconChevronsRight />;
};
return useMemo(
() =>
[
{
accessor: "",
title: (
<Group>
<Box
style={{ cursor: "pointer" }}
onClick={onExpandAllClick}>
{getExpandAllIcon()}
</Box>
Модуль
</Group>
),
render: ({ id, label }) => (
<Group
key={id}
wrap={"nowrap"}>
{expandedModuleIds.includes(id) ? (
<IconChevronUp />
) : (
<IconChevronDown />
)}
<Text>{label}</Text>
</Group>
),
},
{
title: "Описание",
accessor: "description",
},
{
title: "Зависит от модулей",
accessor: "dependsOn",
render: module => (
<Text>
{module.dependsOn?.map(m => m.label).join(", ")}
</Text>
),
},
{
accessor: "actions",
title: isMobile ? "" : "Действия",
sortable: false,
textAlign: "center",
width: "0%",
render: module => (
<Tooltip
label={
module.isBuiltIn
? "Нельзя изменять встроенные модули"
: null
}>
<UpdateDeleteTableActions
onDelete={() => onDelete(module)}
onChange={() => onUpdate(module)}
disabled={module.isBuiltIn}
/>
</Tooltip>
),
},
] as DataTableColumn<ModuleWithAttributesSchema>[],
[expandedModuleIds, modules, isMobile]
);
};
export default useModulesTableColumns;